GAMES101 作业2 给三角形上色和MSAA的实现

主要代码思路来自大佬:https://blog.csdn.net/qq_36242312/article/details/105758619

 

然后有个插值计算,好像下节课才讲。

转发的文章的代码不能直接改true来实现MSAA,因为insideTriangle的参数他写的是int,改成float就可以了。

color那里写成t.getColor() * count / 4.0f + (4 - count) * frame_buf[get_index(x,y)] / 4.0f貌似还可以减黑边

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]
      Eigen::Vector2f p;
      p<<x,y;
      Eigen::Vector2f AB=_v[1].head(2)-_v[0].head(2);
      Eigen::Vector2f BC=_v[2].head(2)-_v[1].head(2);
      Eigen::Vector2f CA=_v[0].head(2)-_v[2].head(2);
      
      Eigen::Vector2f AP=p-_v[0].head(2);
      Eigen::Vector2f BP=p-_v[1].head(2);
      Eigen::Vector2f CP=p-_v[2].head(2);
      
      return AB[0]*AP[1]-AB[1]*AP[0]>0
           &&BC[0]*BP[1]-BC[1]*BP[0]>0
           &&CA[0]*CP[1]-CA[1]*CP[0]>0;
  
}



void rst::rasterizer::rasterize_triangle(const Triangle& t) {
    auto v = t.toVector4();
    float min_x=std::min(v[0][0],std::min(v[1][0],v[2][0]));
    float max_x=std::max(v[0][0],std::max(v[1][0],v[2][0]));
    float min_y=std::min(v[0][1],std::min(v[1][1],v[2][1]));
    float max_y=std::max(v[0][1],std::max(v[1][1],v[2][1]));
    
    min_x=(int)std::floor(min_x);
    max_x=(int)std::ceil(max_x);
    min_y=(int)std::floor(min_y);
    max_y=(int)std::ceil(max_y);
    bool MSAA=true;
    
    if(MSAA)
    {
    	float pos[4][2]=
    	{
    		{0.25,0.25},
    		{0.75,0.25},
    		{0.25,0.75},
    		{0.75,0.75},
    	};
    	for(int x=min_x;x<=max_x;x++)
    	{
    		for(int y=min_y;y<=max_y;y++)
    		{
    			float minDepth=FLT_MAX;
    			int count=0;
    			for(int i=0;i<4;i++)
    			{
    				if(insideTriangle((float)x+pos[i][0],(float)y+pos[i][1],t.v))
    				{
    					auto[alpha, beta, gamma] = computeBarycentric2D((float)x+pos[i][0],(float)y+pos[i][1],t.v);
                        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;
                        minDepth=std::min(minDepth,z_interpolated);
                        count++;
                    }
                }
            if(count!=0)
            {
            	if(depth_buf[get_index(x,y)]>minDepth)
            	{
            		Vector3f color=t.getColor()*(float)count/4.0;
            		Vector3f point;
            		point<<(float)x,(float)y,minDepth;
            		depth_buf[get_index(x,y)]=minDepth;
            		set_pixel(point,color);
            	}
            }
           }
        }
    }
    else
    {
      for(int x=min_x;x<=max_x;x++)
      {
      	for(int y=min_y;y<=max_y;y++)
      	{
      		if(insideTriangle((float)x+0.5,(float)y+0.5,t.v))
    	{
    		auto[alpha, beta, gamma] = computeBarycentric2D((float)x+0.5,(float)y+0.5,t.v);
            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;
        
        if(depth_buf[get_index(x,y)]>z_interpolated)
        {
        	Vector3f color=t.getColor();
        	Vector3f point;
        	point<<(float)x,(float)y,z_interpolated;
        	depth_buf[get_index(x,y)]=z_interpolated;
        	set_pixel(point,color);
        }
        }
        }
       }
   }
    // TODO : Find out the bounding box of current triangle.
    // iterate through the pixel and find if the current pixel is inside the triangle

    // If so, use the following code to get the interpolated z value.
    //auto[alpha, beta, gamma] = computeBarycentric2D(x, y, t.v);
    //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.
}

 

                      left is using MSAA   while right is not

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值