大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE稳定放心使用
看了好几篇关于投影矩阵的文章,在z坐标的推导上,没有提到为什么z’和1/z成线性关系,而是通过结论中的投影矩阵,即已知z’= (zA + B)/w,并且x和x’,y和y’关系式中分母都有-z,所以w为-z,然后(-n,-f)映射到(-1,1),求出A、B,得到z’和z的关系。
这是用结论去反推过程,过程再得到结论,这样的逻辑我觉得不对,我认为,应该是先得到x,y,z各自的关系式,才去构造出投影矩阵。
推导x,y坐标
向量投影到近平面,然后映射到NDC,就可以得到,在此不赘述。
(下文Ze同Z,都是投影前向量坐标(观察空间坐标))
式1.1
式1.2
重点讨论如何推导z坐标
z坐标的转换关系,并不是投影得到的,而是根据我们的需要:
1、表示物体原有的前后关系。
2、映射到标准设备坐标,从(-n,-f)映射到(-1,1)(使用右手坐标系)。
3、近处精度更大;因为精度有限,当场景中有许多物体时,按照重要程度来说,首先保证近处物体前后关系是正确;所以要让近处物体的z坐标有更大的表示范围。
关键在于3,在这篇文章(https://learnopengl-cn.github.io/04%20Advanced%20OpenGL/01%20Depth%20testing/#_3)中的深度精度部分有提到,如何让近处有更大表示范围,文章中是映射到(0,1),映射到(-1, 1)也是一样的道理。
这里我认为,不只是z’ = A*1/z + B可以达到我们的需求,z’ = A*1/z² + B也可以,还可以构造很多关系式都可以达到我们的需求,但是我们的最终目标是构造一个投影矩阵,投影矩阵*向量/齐次坐标=映射后的向量。
整理式1.1,式1.2
式2.1
式2.2
整理后,式2.1、式2.2分母都有Ze,因此选择z'(NDC) = A*1/z(观察空间) + B,即可以和x,y的关系式对应起来,又满足我们的需求
(2019.08.15补充:使用1/z还有一个重要的原因在于,光栅化时,需要进行透视校正插值,因为z'(NDC)与1/z(观察空间)是线性关系(证明:https://www.cnblogs.com/cys12345/archive/2009/03/16/1413821.html或《3D游戏与计算机图形学中的数学方法》 第3版,第5.4章节),所以z'(NDC) = A*1/z(观察空间) + B,另外,如果z'(NDC)直接保存为z(观察空间) ,等到进行透视校正插值,再进行转换,这样做是不好的,因为透视校正插值是逐片元操作,就要重复非常多次的运算,直接保存为A*1/z(观察空间) + B,是逐顶点操作,运算次数就少很多)
z'(NDC) = A*1/z + B,(-n, -f)映射到(-1,1)
式2.3
式2.1,式2.2,式2.3就可以整理出投影矩阵(负号提取到分母)
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/185886.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...