• Games101--Assignment2


    Update(2020/7/9)

    1. 之前得到了倒置三角形,正置需要修改近平面为负值,因为框架中使用的是左手系。

    2. void rst::rasterizer::rasterize_triangle(const Triangle& t) 中包围盒上边界计算书写错误,应该为MAX而非MIN。

    修改后的投影矩阵:

    Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio, float zNear, float zFar)
    {
        // TODO: Use the same projection matrix from the previous assignments
        Eigen::Matrix4f projection = Eigen::Matrix4f::Identity();
        float n=zNear,f=zFar;
        float t=-n*tan(eye_fov/2.0);//Use -n because the left-hand coordinate used in the framework 
        // float t=fabs(n)*tan(eye_fov/2.0); //即为倒置三角形
        float r=t*aspect_ratio;
        float b=-t,l=-r;
        projection<<(2.0*n)/(r-l),0,(r+l)/(l-r),0,
        0,(2.0*n)/(t-b),(t+b)/(b-t),0,
        0,0,(n+f)/(n-f),(2.0*n*f)/(f-n),
        0,0,1,0;
        
        return projection;
    }
    

    要求

    Gams101的Assignment2的要求如下:

    修改函数rasterize_triangle(const Triangle& t)。
    该函数的内部工作流程如下:

    1. 创建三角形的2 维bounding box。
    2. 遍历此bounding box 内的所有像素(使用其整数索引)。然后,使用像素中
      心的屏幕空间坐标来检查中心点是否在三角形内。
    3. 如果在内部,则将其位置处的插值深度值(interpolated depth value) 与深度
      缓冲区(depth buffer) 中的相应值进行比较。
    4. 如果当前点更靠近相机,请设置像素颜色并更新深度缓冲区(depth buffer)。

    需要修改的函数如下:
    • rasterize_triangle(): 执行三角形栅格化算法
    • static bool insideTriangle(): 测试点是否在三角形内。

    判断点是否在三角形内,只要用叉积来判断方向即可。

    static bool insideTriangle(float x, float y, const Vector3f* _v)
    {   
        // TODO : Implement this function to check if the point (x, y) is inside the triangle represented by _v[0], _v[1], _v[2]
        float a=_v[0].x(),b=_v[0].y(),c=_v[1].x(),d=_v[1].y(),e=_v[2].x(),f=_v[2].y();
        float t1=(c-a)*(y-b)-(d-b)*(x-a);
        float t2=(e-c)*(y-d)-(f-d)*(x-c);
        float t3=(a-e)*(y-f)-(b-f)*(x-e);
        bool x1=true?t1>0.0:false,x2=true?t2>0.0:false,x3=true?t3>0.0:false;
        bool ret=false;
        if((x1 &x2&x3) || (!x1)&(!x2)&(!x3)) ret=true;
        return ret;
    }
    

    rasterize_triangle(),使用MSAA,用的是4x4的supersampling。

    //Screen space rasterization
    void rst::rasterizer::rasterize_triangle(const Triangle& t) {
        auto v = t.toVector4();
        
        // TODO : Find out the bounding box of current triangle.
        // iterate through the pixel and find if the current pixel is inside the triangle
        int left=MIN(v[0].x(),MIN(v[1].x(),v[2].x()))-1;
        int right=MAX(v[0].x(),MAX(v[1].x(),v[2].x()))+1;
        int bottom=MIN(v[0].y(),MIN(v[1].y(),v[2].y()))-1;
        int top=MAX(v[0].y(),MAX(v[1].y(),v[2].y()))+1;
        //修正top计算书写错误,应该取最大值 
        bool MSAA=true;
        //4x4 SuperSampling
        float dir[16][2]={
            {0.125,0.125},
            {0.125,0.375},
            {0.125,0.625},
            {0.125,0.875},
            {0.375,0.125},
            {0.375,0.375},
            {0.375,0.625},
            {0.375,0.875},
            {0.625,0.125},
            {0.625,0.375},
            {0.625,0.625},
            {0.625,0.875},
            {0.875,0.125},
            {0.875,0.375},
            {0.875,0.625},
            {0.875,0.875},
        };
        if(MSAA){
    
        for(int x=left;x<=right;x++){
            for(int y=bottom;y<=top;y++){
                float min_dep=0x7f7ffff;
                int count=0;
                for(int i=0;i<16;i++){
                    if(insideTriangle(x+dir[i][0],y+dir[i][1],t.v)){
                        count++;
                        std::tuple<float, float, float> alpha= computeBarycentric2D(x, y, t.v);
                        float w_reciprocal = 1.0/(std::get<0>(alpha) / v[0].w() + std::get<1>(alpha) / v[1].w() + std::get<2>(alpha) / v[2].w());
                        float z_interpolated = std::get<0>(alpha)* v[0].z() / v[0].w() + std::get<1>(alpha) * v[1].z() / v[1].w() + std::get<2>(alpha) * v[2].z() / v[2].w();
                        z_interpolated *= w_reciprocal;
                        min_dep=MIN(min_dep,z_interpolated);
                    }
                }
                if(count==0)continue;
                if(min_dep < depth_buf[get_index(x,y)]){
                    depth_buf[get_index(x,y)]=min_dep;
                    set_pixel(Vector3f(x,y,min_dep),t.getColor()*count/16.0);
                }
            }
        }
    
        }
        else
        {
            for(int x=left;x<=right;x++){
                for(int y=bottom;y<=top;y++){
                    if(insideTriangle(x,y,t.v)){
                        std::tuple<float, float, float> alpha= computeBarycentric2D(x, y, t.v);
                        float w_reciprocal = 1.0/(std::get<0>(alpha) / v[0].w() + std::get<1>(alpha) / v[1].w() + std::get<2>(alpha) / v[2].w());
                        float z_interpolated = std::get<0>(alpha)* v[0].z() / v[0].w() + std::get<1>(alpha) * v[1].z() / v[1].w() + std::get<2>(alpha) * v[2].z() / v[2].w();
                        z_interpolated *= w_reciprocal;
                        if(z_interpolated<depth_buf[get_index(x,y)]){
                            depth_buf[get_index(x,y)]=z_interpolated;
                            set_pixel(Vector3f(x,y,z_interpolated),t.getColor());
                        }
                    }
                }   
            }
        }
        // If so, use the following code to get the interpolated z value.
        //auto tpp = computeBarycentric2D(x, y, t.v);
        //float alpha, beta, gamma;
        //std::tie(alpha, beta, gamma)=tpp;
        //float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
        //float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
        //z_interpolated *= w_reciprocal;
    
        // TODO : set the current pixel (use the set_pixel function) to the color of the triangle (use getColor function) if it should be painted.
    }
    

    如果不用MSAA,则代码如下:

    //Screen space rasterization
    void rst::rasterizer::rasterize_triangle(const Triangle& t) {
        auto v = t.toVector4();
        
        // TODO : Find out the bounding box of current triangle.
        // iterate through the pixel and find if the current pixel is inside the triangle
        int left=MIN(v[0].x(),MIN(v[1].x(),v[2].x()))-1;
        int right=MAX(v[0].x(),MAX(v[1].x(),v[2].x()))+1;
        int bottom=MIN(v[0].y(),MIN(v[1].y(),v[2].y()))-1;
        int top=MAX(v[0].y(),MIN(v[1].y(),v[2].y()))+1;
        for(int x=left;x<=right;x++)
        {
            for(int y=bottom;y<=top;y++)
            {
               if(insideTriangle(x,y,t.v))
               {
                   std::tuple<float, float, float> alpha= computeBarycentric2D(x, y, t.v);
                   float w_reciprocal = 1.0/(std::get<0>(alpha) / v[0].w() + std::get<1>(alpha) / v[1].w() + std::get<2>(alpha) / v[2].w());
                    float z_interpolated = std::get<0>(alpha)* v[0].z() / v[0].w() + std::get<1>(alpha) * v[1].z() / v[1].w() + std::get<2>(alpha) * v[2].z() / v[2].w();
                    z_interpolated *= w_reciprocal;
                    if(z_interpolated<depth_buf[get_index(x,y)])
                    {
                        depth_buf[get_index(x,y)]=z_interpolated;
                        set_pixel(Vector3f(x,y,z_interpolated),t.getColor());
                    }
                }
            }   
        }
        // If so, use the following code to get the interpolated z value.
        //auto tpp = computeBarycentric2D(x, y, t.v);
        //float alpha, beta, gamma;
        //std::tie(alpha, beta, gamma)=tpp;
        //float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
        //float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
        //z_interpolated *= w_reciprocal;
    
        // TODO : set the current pixel (use the set_pixel function) to the color of the triangle (use getColor function) if it should be painted.
    }
    

    结果

    两者对比结果如下:

    without_MSAA with_MSAA
  • 相关阅读:
    centos6 Cacti部署文档
    nginx 3.nginx+fastcgi
    nginx 2.基本配置
    nginx 1.安装
    mongodb入门教程二
    mongodb入门教程
    一款jQuery立体感动态下拉导航菜单特效
    一款jQuery仿海尔官网全屏焦点图特效代码
    一款非常炫酷的jQuery动态随机背景滚动特效
    一款jquery编写图文下拉二级导航菜单特效
  • 原文地址:https://www.cnblogs.com/FlyerBird/p/13245962.html
Copyright © 2020-2023  润新知