GAMES101-作业2

4 篇文章 0 订阅

作业链接放前面

光栅化三角形

void rst::rasterizer::rasterize_triangle(const Triangle& t) {
    auto v = t.toVector4();
    std::vector<float> bb(4,INT_MAX);
    bb[0]=bb[1]=INT_MIN;
    for(int i=0;i<3;i++){
        bb[0]=std::max(float(v[i][0]),float(bb[0]));
        bb[1]=std::max(float(v[i][1]),float(bb[1]));
        bb[2]=std::min(float(v[i][0]),float(bb[2]));
        bb[3]=std::min(float(v[i][1]),float(bb[3]));
    }
    bb[0]=std::ceil(bb[0]);     //max x,means right;
    bb[1]=std::ceil(bb[1]);     //max y,means top;
    bb[2]=std::floor(bb[2]);    //min x,means left; 
    bb[3]=std::floor(bb[3]);    //min y,means bottom;
    
    for(float x=bb[2];x<bb[0];x++){
        for(float y=bb[3];y<bb[1];y++){
            if(insideTriangle(x+0.5,y+0.5,t.v)){
                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;
                if(z_interpolated<depth_buf[get_index(x,y)]){
                    depth_buf[get_index(x,y)]=z_interpolated;
                    set_pixel(Vector3f(x,y,1),t.getColor());
                }
            }
        }
    }
}

SSAA版

//SSAA
void rst::rasterizer::rasterize_triangle(const Triangle& t) {
    auto v = t.toVector4();
    std::vector<float> bb(4,INT_MAX);
    bb[0]=bb[1]=INT_MIN;
    for(int i=0;i<3;i++){
        bb[0]=std::max(float(v[i][0]),float(bb[0]));
        bb[1]=std::max(float(v[i][1]),float(bb[1]));
        bb[2]=std::min(float(v[i][0]),float(bb[2]));
        bb[3]=std::min(float(v[i][1]),float(bb[3]));
    }
    bb[0]=std::ceil(bb[0]);     //max x,means right;
    bb[1]=std::ceil(bb[1]);     //max y,means top;
    bb[2]=std::floor(bb[2]);    //min x,means left; 
    bb[3]=std::floor(bb[3]);    //min y,means bottom;

    for(float x=bb[2];x<bb[0];x++){
        for(float y=bb[3];y<bb[1];y++){
            float cnt=0;
            for(float i=x+0.25;i<x+1;i+=0.5){
                for(float j=y+0.25;j<y+1;j+=0.5){
                    if(insideTriangle(i,j,t.v)){
                        cnt++;
                    }
                }
            }
            if(cnt>0){
                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;
                if(z_interpolated<depth_buf[get_index(x,y)]){
                    depth_buf[get_index(x,y)]=z_interpolated;
                    set_pixel(Vector3f(x,y,1),t.getColor()*cnt/4);
                }
            }
        }
    }
}

首先计算Triangle的boundingbox,这步原理其实很简单,我在boudingbox应该是三维的还是二维的这个问题上纠结了一会,后来发现两个三角形都是在同一个z平面上的,就不用考虑z轴方向了。此处的最大值要向上取整celi,最小值向下取整floor,以求得正确的空间范围。
求完boundingbox后,就要遍历区间内的每一个点,计算是否在三角形内,注意此时要取每个像素的中点判断该像素的位置,

4XSSAA:将每个点分为四个点,分别计算其是否在三角形内,若有n个在,则最后将实际的颜色值设为原来值的n/4,这里会出现黑边,不知是不是插值的方法不正确,求大佬指正。
对每个点调用insideTriangle函数判断其位置是否在三角形内,代码如下

static bool insideTriangle(float x, float y,const Vector3f* _v)
{   
    Eigen::Vector3f p(x,y,1);
    Vector3f edge[3]={_v[1]-_v[0],_v[2]-_v[1],_v[0]-_v[2]};
    int last=0;
    for(int i=0;i<3;i++){
        auto pi=p-_v[i];
        float temp=edge[i][0]*pi[1]-pi[0]*edge[i][1];
        if(last==1&&temp<0){
            return false;
        }else if(last==-1&&temp>0){
            return false;
        }else{
            last= temp>0? 1:-1; 
        }
    }
    

注意,这里将参数中的x,y改为了float,否则无法实现点的细分。
用x,y生成一个点,计算该点与三角形三条边的向量分别叉乘后得到的向量在z轴上是否一致。一致在三角形内,否则在三角形外。

普通
無SSAA

抗锯齿后4XSSAA

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值