平民程序 - linghuye's blog

天下风云出我辈,一入江湖岁月催。皇图霸业谈笑中,不胜人生一场醉。提剑跨骑挥鬼雨,白骨如山鸟惊飞。尘事如潮人如水,只笑江湖几人回。

随笔 - 221, 文章 - 0, 评论 - 680, 引用 - 0
数据加载中……

解决颠倒成像过程中遇到的几个问题

如何上下颠倒一个场景的成像?
我的第一个念头是想把镜头上下颠倒(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

posted on 2009-06-30 21:19 linghuye 阅读(2103) 评论(3)  编辑 收藏 引用 所属分类: 3D图形学研究

评论

# re: 解决颠倒成像过程中遇到的几个问题  回复  更多评论   

用glPixelZoom好像就可以了吧?红宝书上有的。。。
2009-07-16 22:24 | simbaforrest

# re: 解决颠倒成像过程中遇到的几个问题[未登录]  回复  更多评论   

Nope,glPixelZoom是作用于OpenGL图像数据管道的,对glDrawPixels,glBitmap有作用,对渲染成像管道是没有作用的.
2009-07-17 13:41 | linghuye

# re: 解决颠倒成像过程中遇到的几个问题  回复  更多评论   

改变 三角形的顶点顺序,渲染出来的图像不会是 反的么???

实作后,果然画面正确地上下颠倒了. 这时你用的是 逆时针,顺时针后,渲染的还是 正确的?
2010-08-11 17:00 | yilog
只有注册用户登录后才能发表评论。