参考教程
Tutorial 43: Projective Texturing
《GPU Programming And Cg Language Primer 1rd Edition》
学习记录
这篇文章中我们介绍投影纹理映射(Projective Texture Mapping),并且给出一个简单的示例。
投影纹理映射(Projective Texture Mapping)初由Segal在文章“Fast shadows and lighting effects using texture maaping”中提出,用于映射一个纹理到物体上,就像将幻灯片投影到墙上一样。该方法不需要在应用程序中指定顶点纹理坐标,实际上,投影纹理映射中使用的纹理坐标是在顶点着色程序中通过视点矩阵和投 影矩阵计算得到的,通常也被称作投影纹理坐标(coordinates in projective space)。 而我们常用的纹理坐标是在建模软件中通过手工调整纹理和3D模型的对应关系 而产生的。
投影纹理映射的目的是将纹理和三维空间顶点进行对应,这种对应的方法好 比“将纹理当作一张幻灯片,投影到墙上一样”。投影纹理映射真正的流程是“根据投影机(视点相机)的位置、投影角度,物体的坐标,求出每个顶点所对应的纹理坐标,然后依据纹理坐标去查询纹理 值”,也就是说,不是将纹理投影到墙上,而是把墙投影到纹理上。投影纹理坐 标的求得,也与纹理本身没有关系,而是由投影机的位置、角度,以及3D模型 的顶点坐标所决定。
这篇文章中我们使用一个 ProjectionShaderClass
类来实现渲染,这个类和 TextureShaderClass
不同的是它类似 LightShaderClass
,同时在 MatrixBufferType
里多了一个 view
和 projection
矩阵,其声明如下:
1 | class ProjectionShaderClass |
其实现并没有什么多少特殊的地方,所以暂且不提。新增的 ViewPoint
类也只是简单的进行了数据封装,主要来看我们的着色器。
在 VertexShader
中,我们使用新增的 viewMatrix2
和 projectionMatrix2
矩阵变换 viewPosition
并且传递给像素着色器,如下:
1 | ///////////// |
在 PixelShader
中,我们除了计算光照以外,我们将 ViewPosition
变换为 0 到 1 之内,然后使用它作为纹理坐标来渲染纹理:
1 | ////////////////////// |
在 GraphicsClass
中我们初始化相应类的对象,设定观察点以及对应的变换矩阵,部分代码如下:
1 | m_ViewPoint = new ViewPointClass; |
最后,在 Render
里我们使用 ProjectionShaderClass
的对象来进行渲染,它接受多个矩阵参数:
1 | bool GraphicsClass::Render() |
最终效果如下: