【Games101】从作业3代码看软光栅渲染流程及透视投影矫正等问题

作业3陆陆续续的做了一周,在透视投影矫正、interpolated_shadingcoords等地方卡了很久,不理解。参考网上一些博客文章,总结自己在做作业3的过程中的一些收获。
参考的一些博文:
Games101:作业3(管线分析、深度插值、libpng warning、双线性插值等)
矫正透视投影插值及属性插值详解

软光栅渲染流程

从Games101 shadeing部分介绍了图形渲染管线:
graphics pipeline
那么如何用代码去实现这样一个图形渲染管线,作业3的代码中实现了一个基本的软光栅渲染器,我们从作业框架的代码中,总结软光栅渲染器渲染一个模型的流程:

  1. 读取模型坐标,通过模型矩阵、视图矩阵,转换为视图空间下的坐标。(main函数)
  2. 进行投影变换转换为投影空间下坐标。
  3. 进行视口变换,转换为屏幕空间下坐标。
  4. 在屏幕空间下,进行逐像素的着色:
    1. 判断像素是否着色
    2. 对像素进行插值,深度插值、颜色插值、法线插值等,这时因为是在屏幕空间上,经过了透视投影后物体发生了非线性变换,所以需要进行透视投影矫正插值(可参考)。
    3. 获取了像素的深度、颜色、法线等信息后,根据不同的着色模型(phong、texture、bump、dispacement、pbr等等),计算出该像素的颜色,赋值给该像素即可。注意这里不同的着色模型计算,是发生在视图空间的,也就是说我们要把当前着色像素点对应到视图空间中的某个点,在视图空间下计算该像素的颜色。(这也就是作业框架中出现的shading_coordinates)

问题

透视投影矫正

参考Games101:作业3(管线分析、深度插值、libpng warning、双线性插值等)_games101作业3_Q_pril的博客-CSDN博客


推导:
假设二维空间中小三角形三个顶点的深度值分别为图片[2]-【Games101】从作业3代码看软光栅渲染流程及透视投影矫正等问题-五八三,其内部一点的重心坐标为图片[2]-【Games101】从作业3代码看软光栅渲染流程及透视投影矫正等问题-五八三,对应深度值为图片[2]-【Games101】从作业3代码看软光栅渲染流程及透视投影矫正等问题-五八三;而三维空间三个顶点的深度值分别为图片[2]-【Games101】从作业3代码看软光栅渲染流程及透视投影矫正等问题-五八三重心坐标为图片[2]-【Games101】从作业3代码看软光栅渲染流程及透视投影矫正等问题-五八三,对应深度值为图片[2]-【Games101】从作业3代码看软光栅渲染流程及透视投影矫正等问题-五八三,可得出:
图片[3]-【Games101】从作业3代码看软光栅渲染流程及透视投影矫正等问题-五八三
联立①⑤:
图片[4]-【Games101】从作业3代码看软光栅渲染流程及透视投影矫正等问题-五八三
可知⑥+⑦+⑧ = 1,将各式右边相加,得:
图片[5]-【Games101】从作业3代码看软光栅渲染流程及透视投影矫正等问题-五八三
**这就是透视投影矫正的公式,**通过二维空间中一点的重心坐标图片[6]-【Games101】从作业3代码看软光栅渲染流程及透视投影矫正等问题-五八三,以及三维空间中三个点的Z值,可得到该点在三维空间中的Z值。
同理,对于任意的属性值图片[7]-【Games101】从作业3代码看软光栅渲染流程及透视投影矫正等问题-五八三,在三维空间中有:
图片[8]-【Games101】从作业3代码看软光栅渲染流程及透视投影矫正等问题-五八三
深度值也是一个属性,这里的图片[9]-【Games101】从作业3代码看软光栅渲染流程及透视投影矫正等问题-五八三与①式中的图片[9]-【Games101】从作业3代码看软光栅渲染流程及透视投影矫正等问题-五八三是相同的,所以有:
图片[10]-【Games101】从作业3代码看软光栅渲染流程及透视投影矫正等问题-五八三
图片[11]-【Games101】从作业3代码看软光栅渲染流程及透视投影矫正等问题-五八三
也就是说对于任意的属性,我们都可以通过⑩式来求得。

公式⑨、⑩都很重要

对于作业框架代码,z值就是通过⑨式求值,zp是⑩式。

auto[alpha, beta, gamma] = computeBarycentric2D(i+0.5, j+0.5, t.v);
float Z = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
float zp = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
zp *= Z;

这里刚开始不理解,z值就是视图空间(未发生透视变换)的深度值,为什么还要在带入⑩式求出zp,其实我们用⑩式来计算深度插值,求出的结果就是⑨式,zzp是相等的。

interpolated_shadingcoords

注意这里不同的着色模型计算,是发生在视图空间的,也就是说我们要把当前着色像素点对应到视图空间中的某个点,在视图空间下计算该像素的颜色。(这也就是作业框架中出现的shading_coordinates)
参考:
games论坛中关于interpolated_shadingcoords的解释

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYpj7n4v' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片