如何上下颠倒一个场景的成像?
我的第一个念头是想把镜头上下颠倒(Up向量取负)即可,后来想想不对,镜头上下颠倒后,世界也左右颠倒了.
然后想可以在投影矩阵上搞鬼,因为经过正常投影矩阵作用后的顶点的y值分布在[-1,1]之间,所以对y取负,就可以使画面颠倒呈现(而且对上层毫无影响).如果使用可编程流水线,只要在VertexShader里将输出的gl_Position的y值取负即可.如果使用固定流水线,需要将正常的投影矩阵左乘(DX是右乘)一个Scale(1.0f, -1.0f, 1.0)矩阵即可,也可以直接将正常投影矩阵的第2行(DX是第2列)取负.
实作后,果然画面正确地上下颠倒了.但是发现,从VS到PS的法线的插值结果不对了,图像化PS中的法线值后呈现的颜色和无颠倒的图像颜色完全不同,似乎前后颠倒了,如下:
void main()
{
gl_Position = ftransform();
gl_Position.y = -gl_Position.y;
// 将顶点法线传入PS
gl_TexCoord[0] = vec4(gl_Normal, 1.0);
}
void main()
{
// 将法线值显示出来
gl_FragData[0] = gl_TexCoord[0];
}
根据Perspective-Correct Interpolation的数学原理,深度值倒数是线性插值的,而从VS到PS的数值是根据深度值倒数做的插值:
研究公式后,觉得y值取负理应不会影响到z值的正确计算,z值不变,整个插值的结果应该是不变的,茫然不知所以.
今天突然想到,y值取负后,所有三角形成像颠倒了,三角形的顶点顺序也逆反了,原来逆时针的变成了顺时针,影响了GL_CULL_FACE,输出的画面会呈现前后颠倒的假象,实作下果然如此,修改了CULL_MODE后,终于得到想要的画面了.
其实,我想说,搞图形学,你不懂数学原理能行吗?
Reference:Mathematics for 3D Game Programming and Computer Graphics