投影纹理映射(Projective Texture Mapping)详解

来源:互联网 发布:手机淘宝哪里看好评率 编辑:程序博客网 时间:2024/05/17 07:14
投影纹理映射(Projective Texture Mapping)目的是映射一张纹理到物体上,就像将幻灯片投影到墙上一样。该方法不需要在应用程序中指定顶点纹理坐标,实际上,投影纹理映射中使用的纹理坐标是在顶点着色程序中通过视点矩阵和投影矩阵计算得到的,通常也被称作投影纹理坐标(coordinates in projective space)。而我们常用的纹理坐标是在建模软件中通过手工调整纹理和3D 模型的对应关系而产生的。
投影纹理映射有两大优点:
第一,将纹理与空间顶点进行实时对应,不需要预先在建模软件中生成纹理坐标。很多情况下,我们需要将场景渲染两遍,第一遍是为了获取场景信息,得到的场景信息通常保存为一张纹理(eg.Depth);然后基于上述预计算纹理进行第二次渲染;第二次渲染结果才是最终显示到屏幕上的效果。为了在第二次渲染中使用到预计算的纹理(无预先设置的纹理坐标),需要时时进行纹理计算,这时就可以使用投影纹理映射技术。实际上,这也是投影纹理映射技术的最广泛的应用了。
第二,使用投影纹理映射,可以有效的避免纹理扭曲现象。将一张纹理投影到两个三角面片上,它们的顶点纹理坐标相同,但是由于三角面片形状不同,插值出来的内部点的纹理坐标也会产生不同的梯度(gradient),最后纹理颜色在两个三角面片上的分布也是不一样的。
根据顶点坐标获得纹理坐标的本质是将顶点坐标投影到NDC平面上,此时投影点的平面坐标即为纹理坐标。如果你将当前视点作为投影机,那么在顶点着色程序中通过 POSTION 语义词输出的顶点投影坐标,就是当前视点下的投影纹理坐标没有被归一化的表达形式。

“Projective texture mapping”文章中有一幅比较著名的图片,说明计算纹理投影坐标的过程,如下图所示。


左图是正常的顶点坐标空间转换流程,无非是顶点从模型坐标空间转换到世界坐标空间,然后从世界坐标空间转换到视点空间,再从视点空间转换到裁剪空间,然后投影到视锥近平面,经过这些步骤,一个顶点就确定了在屏幕上的位置。右图是将视点当作投影机,根据模型空间的顶点坐标,求得投影纹理坐标的流程。通过比较,可以发现这两个流程基本一样,唯一的区别在于求取顶点投影坐标后的归一化不一样:计算投影纹理坐标需要将投影顶点坐标归一化到[0,1]空间中,实现这一步,可以在在着色程序中对顶点投影坐标的每个分量先乘以1/2 然后再加上1/2。使用投影纹理坐标之前,别忘了将投影纹理坐标除以最后一个分量w 。到此,你就可以使用所求得的投影纹理坐标的前两个分量去检索纹理图片,从中提取颜色值。

Unity中写段小程序测试下:

[cpp] view plaincopyprint?
  1. Shader "GLSL projectShader" {  
  2.    Properties {  
  3.       _MainTex ("Texture Image", 2D) = "white" {}   
  4.    }  
  5.    SubShader {  
  6.       Pass {      
  7.          GLSLPROGRAM  
  8.          uniform sampler2D _MainTex;      
  9.          uniform vec4 _MainTex_ST;   
  10.          varying vec4 textureCoordinates;   
  11.          #ifdef VERTEX  
  12.          void main()  
  13.          {  
  14.             textureCoordinates = gl_ModelViewProjectionMatrix * gl_Vertex;;  
  15.             gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;  
  16.          }  
  17.          #endif  
  18.          #ifdef FRAGMENT  
  19.           void main()  
  20.          {  
  21.             gl_FragColor = texture2D(_MainTex,(textureCoordinates.xy/textureCoordinates.w*0.5f+0.5f));         
  22.          }  
  23.           #endif  
  24.           ENDGLSL  
  25.       }  
  26.    }  
  27. }  
  28. 就是它了,没有加入任何光照信息,丑了点~~  

参考:

[1] Projective texture mapping, Cass Everitt, cass@nvidia.com 

http://www.nvidia.com/object/Projective_Texture_Mapping.html

[2] http://dev.gameres.com/Program/Visual/3D/ProjectTexture.htm
[3] http://www.bluevoid.com/opengl/sig00/advanced00/notes/node81.html
[4] http://pointer.cnblogs.com/archive/2004/12/30/84367.html

0 0