软件光栅化渲染器(六)

透视矫正

加入了透视矫正, 像素的覆盖遵循了左上的原则。
对1/Z进行插值,将结果在除以1/Z得到正确的插值。

//透视矫正纹理
    void FillBottomTriangleByTexCorrect(const Triangle &t)
    {
        Vertex3D bottom, left, right;
        if (t.vertex[0].newPos.y == t.vertex[1].newPos.y)
        {
            bottom = t.vertex[2];
            left = t.vertex[0];
            right = t.vertex[1];
        }
        else if (t.vertex[1].newPos.y == t.vertex[2].newPos.y)
        {
            bottom = t.vertex[0];
            left = t.vertex[1];
            right = t.vertex[2];
        }
        else
        {
            bottom = t.vertex[1];
            left = t.vertex[0];
            right = t.vertex[2];;
        }
        if (left.newPos.x > right.newPos.x)
        {
            Swap(left, right);
        }
        float leftDxDivDy = (bottom.newPos.x - left.newPos.x) / ((float)bottom.newPos.y - (float)left.newPos.y);
        float rightDxDivDy = ((float)right.newPos.x - (float)bottom.newPos.x) / ((float)right.newPos.y - (float)bottom.newPos.y);
        float xleft = (float)left.newPos.x;
        float xRight = (float)right.newPos.x;
        int y = left.newPos.y;

        //1/Z
        float leftDxDivDyReciprocalZ = ((1 / bottom.newPos.z) - (1 / left.newPos.z)) / (bottom.newPos.y - left.newPos.y);
        float rightDxDivDyReciprocalZ = ((1 / right.newPos.z) - (1 / bottom.newPos.z)) / (right.newPos.y - bottom.newPos.y);
        float xLeftReciprocalZ = 1 / left.newPos.z;
        float xRightReciprocalZ = 1 / right.newPos.z;

        //U
        float leftDxDivDyColorU = (bottom.uv.x / bottom.newPos.z - left.uv.x / left.newPos.z) / (bottom.newPos.y - left.newPos.y);
        float rightDxDivDyColorU = (right.uv.x / right.newPos.z - bottom.uv.x / bottom.newPos.z) / (right.newPos.y - bottom.newPos.y);
        float xLeftColorU = left.uv.x / left.newPos.z;
        float xRightColorU = right.uv.x / right.newPos.z;
        //V
        float leftDxDivDyColorV = (bottom.uv.y / bottom.newPos.z - left.uv.y / left.newPos.z) / (bottom.newPos.y - left.newPos.y);
        float rightDxDivDyColorV = (right.uv.y / right.newPos.z - bottom.uv.y / bottom.newPos.z) / (right.newPos.y - bottom.newPos.y);
        float xLeftColorV = left.uv.y / left.newPos.z;
        float xRightColorV = right.uv.y / right.newPos.z;

        while (y < bottom.newPos.y)
        {
            float dxReciprocalZ = (xRightReciprocalZ - xLeftReciprocalZ) / (xRight - xleft);
            float reciprocalZ = xLeftReciprocalZ;

            float dxColorU = (xRightColorU - xLeftColorU) / (xRight - xleft);
            float ColorStarU = xLeftColorU;

            float dxColorV = (xRightColorV - xLeftColorV) / (xRight - xleft);
            float ColorStarV = xLeftColorV;
            for (int i = (int)(xleft); i < (int)(xRight); i++)
            {
                float u = (ColorStarU / reciprocalZ) * (t.texWidth-1);
                float v = (ColorStarV / reciprocalZ) * (t.texHeight-1);
                if (u < 0 || v < 0 || u >= t.texWidth || v >= t.texHeight)
                {
                    int haa = 0;
                }
                UINT color = t.texBuffer[(UINT)u + (UINT)v * (UINT)t.texWidth];
                DrawPoint(i, y, color);
                ColorStarU += dxColorU;
                ColorStarV += dxColorV;
                reciprocalZ += dxReciprocalZ;
            }
            y++;
            xleft += leftDxDivDy;
            xRight += rightDxDivDy;

            xLeftReciprocalZ += leftDxDivDyReciprocalZ;
            xRightReciprocalZ += rightDxDivDyReciprocalZ;

            xLeftColorU += leftDxDivDyColorU;
            xRightColorU += rightDxDivDyColorU;

            xLeftColorV += leftDxDivDyColorV;
            xRightColorV += rightDxDivDyColorV;
        }
    }

发现了个新问题,背面剔除貌似有问题。
这里写图片描述
Github项目地址

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值