tex2Dproj 和tex2D的区别是什么.只是除以最后一个分量和份量的区别吗

在使用阴影映射(shadow maping)实现阴影时,《》中使用了投影纹理。其中生成投影纹理坐标的纹理矩阵的生成过程由下图所示:
其官方教程的说明如下:
Let's go through the transformations, to clarify what's going on. The vertices start in object coordinates.
Multiply by the light's viewing matrix. This rotates and translates the vertices so that they are in the light's frame of reference.
Scale and bias the results. Following steps 1 to 3, the transformed vertex values range from -1 to 1. However, textures are indexed from 0 to 1, so the results have to be mapped to this range. This is done by multiplying the x, y, and z components of the results by ½ and then adding ½. A single matrix multiplication accomplishes this mapping.
当时看的时候对其中标红的部分感到匪夷所思,因为在我的印象中经过前三步后的将坐标转到的裁剪空间(clip space)貌似不是在(-1,1)的范围(难道我记错了! ),之后我就开始找资料,看看是不是这么一回事(参考我之前的随笔&&)。结论是裁剪空间三个坐标分量的范围都是(-w,w),原来真的是《The Cg Tutorial》中的说法有误!
---------------------------------------------------------
后来看了Cg Toolkit中的Sample 27_projective_texturing后发现,其实它的文中这么写也无可厚非,目的是让人更加容易理解。因为它的源码中是使用了tex2Dproj()这个专用的投影采样函数。那它与我们常用的tex2D()有什么不一样的地方呢?于是我查了工具包中的Reference Manual,其说明如下:
Performs a texture lookup in sampler samp using coordinates s, the coordinates used in the lookup are first projected, that is, divided by the last component of the coordinate vector and them used in the lookup. If an extra coordinate is present it is used to perform a shadow comparison, the value used in the shadow comparison is always the next-to-last component in the coordinate vector.
大意就是在查询纹理的时候对其纹理坐标做了一次投影,即除以了纹理坐标的最后一个分量。上文提到裁剪空间的坐标范围是(-w,w),那么经过一次&Scale and Bias&之后其表述范围就是(0,w),再在tex2Dproj()中纹理坐标投影后不就是(0,1)了吗?此时,我已恍然大悟 。
---------------------------------------------------------
知道原因后,其实直接用tex2D()来实现tex2Dproj()的功能也仅仅是在纹理坐标上手动除以其最后一个分量(这里补充一下:其实tex2D本身就已经有tex2Dproj的功能,完全可以代替tex2Dproj使用!说白了就是有用tex2Dproj的地方都可以用tex2D代替,反之不成立。这是我后来在Cg Reference中发现的,之前没有注意到而已啦),如下:
float4 textureColor = tex2Dproj(projectiveMap,
texCoordProj);
float4 textureColor = tex2D(projectiveMap,
texCoordProj.xy/texCoordProj.w);
想想看,其实也可以在生成Texture Matrix的时候去掉最后一步(Scale and Bias),直接取光源的MVP(ModelView_Projection)矩阵作为投影纹理矩阵,不过相应地也需要在纹理查询时对其纹理坐标进行一次变换,示例代码如下:
float4 textureColor = tex2D(projectiveMap,
texCoordProj.xy/texCoordProj.w*0.5+0.5);
后面的*0.5+0.5算是对之前&偷工减料&的弥补了!
阅读(...) 评论()安全检查中...
请打开浏览器的javascript,然后刷新浏览器
< 浏览器安全检查中...
还剩 5 秒&摘抄&GPU Programming And Cg Language Primer 1rd Edition& 中文
名&GPU编程与CG语言之阳春白雪下里巴人&&
投影纹理映射(
Projective Texture Mapping
&Fast shadows and lighting effects using texture maaping&
中提出,用于映射一个纹理到物体上,就像将幻灯片投影到墙上一样。该方法不需要在应用程序中指定顶点纹理坐标,实际上,投影纹理映射中使用的纹理坐标是在顶点着色程序中通过视点矩阵和投影矩阵计算得到的,通常也被称作投影纹理坐标
(coordinates in projective
。而我们常用的纹理坐标是在建模软件中通过手工调整纹理和
模型的对应关系而产生的。
投影纹理映射的目的是将纹理和三维空间顶点进行对应,这种对应的方法好比
将纹理当作一张幻灯片,投影到墙上一样
投影纹理映射
本章我们针对投影纹理映射的原理和实现方法进行详细的阐述。这一章的地位很高,在一些阴影算法以及体绘制算法中都需要用到投影纹理映射技术。严格的说,只要涉及到
纹理实时和空间顶点对应
,通常都会用到投影纹理映射技术。
投影纹理映射的优点
投影纹理映射有两大优点:其一,将纹理与空间顶点进行实时对应,不需要预先在建模软件中生成纹理坐标;其二,使用投影纹理映射,可以有效的避免纹理扭曲现象。
为了说明第一个优点,先举一个简要的例子:很多情况下,我们需要将场景渲染两遍,第一遍是为了获取场景信息,得到的场景信息通常保存为一张纹理(例如深度图);然后基于&存放场景信息&的纹理进行第二次渲染;第二次渲染结果才是最终显示到屏幕上的效果。为了在第二次渲染中使用到&存放场景信息&的纹理(无预先设置的纹理坐标),需要时时进行纹理计算,这时就可以使用投影纹理映射技术。实际上,这也是投影纹理映射技术的最广泛的应用了。
可能大家对于上一段文字还不能理解得很清楚,不过在第
章的阴影贴图算法以及第
章的体绘制光线投射算法中,大家会明白其含义。一个算法只有理论加实践,才可能真正的被理解,只会照本宣科的朗诵术语,基本上都是鲁迅先生所说的
投影纹理映射的第二个优点是:可以有效的避免纹理扭曲现象。如
所示,将一张纹理投影到两个三角面片上,它们的顶点纹理坐标相同,但是由于三角面片形状不同,插值出来的内部点的纹理坐标也会产生不同的梯度(
),最后纹理颜色在两个三角面片上的分布也是不一样的。
右边所示的是将一张纹理贴到一个正方形上,左边所示的是将同样的纹理贴到一个梯形上,正方形和梯形的顶点纹理坐标相同,但两者的贴图效果是不同的。梯形上的纹理会出现明显的扭曲现象。这是因为几何体的变换,导致插值出来的内部纹理坐标分布不均衡。
齐次纹理坐标(
齐次纹理坐标(
homogeneous texture
coordinates
)的概念对大多数人来说比较陌生,纹理坐标一般是二维的,如果是体纹理,其纹理坐标也只是三维的。齐次纹理坐标的出现是为了和三维顶点的齐次坐标相对应,因为本质上,投影纹理坐标是通过三维顶点的齐次坐标计算得到的。
齐次纹理坐标通常表示为(s,t,r,q
以区别于物体位置齐次坐标(x, y, z, w)
。一维纹理常用s
坐标表示,二维纹理常用(s, t)
坐标表示,目前忽略r
坐标的作用与齐次坐标点中的w
坐标非常类似。值一般为1
原理与实现流程
对投影纹理映射,很多教程上都是这么解释的:纹理好比一张幻灯片,灯光好比投影机,然后将纹理投影到一个物体上,类似于投影机将幻灯片投影到墙上。这个比喻没有太大的问题,也找不到更加形象的比喻了。问题是:这个解释刚好颠倒了算法的实现流程。
投影纹理映射真正的流程是
根据投影机(视点相机)的位置、投影角度,物体的坐标,求出每个顶点所对应的纹理坐标,然后依据纹理坐标去查询纹理值
,也就是说,不是将纹理投影到墙上,而是把墙投影到纹理上。投影纹理坐标的求得,也与纹理本身没有关系,而是由投影机的位置、角度,以及
模型的顶点坐标所决定。所以,我一直觉得
投影纹理映射
这个术语具有很强的误导性,总让人觉得是把纹理投射出去。
根据顶点坐标获得纹理坐标的本质是将顶点坐标投影到
平面上,此时投影点的平面坐标即为纹理坐标。如果你将当前视点作为投影机,那么在顶点着色程序中通过
语义词输出的顶点投影坐标,就是当前视点下的投影纹理坐标没有被归一化的表达形式。
&Projective texture mapping&
文章中有一幅比较著名的图片,说明计算纹理投影坐标的过程,如
左边是正常的顶点坐标空间转换流程,无非是顶点从模型坐标空间转换到世界坐标空间,然后从世界坐标空间转换到视点空间,再从视点空间转换到裁剪空间,然后投影到视锥近平面,经过这些步骤,一个顶点就确定了在屏幕上的位置。图的右边是将视点当作投影机,根据模型空间的顶点坐标,求得投影纹理坐标的流程。通过比较,可以发现这两个流程基本一样,唯一的区别在于求取顶点投影坐标后的归一化不一样:计算投影纹理坐标需要将投影顶点坐标归一化到【0
】空间中,实现这一步,可以在需要左乘矩阵normalMatrix
也可以在着色程序中对顶点投影坐标的每个分量先乘以1/2
然后再加上1/2
&&&&&&&&&& &&&&&&&&&&&&&&
所以求取投影坐标矩阵的公式为:
求得纹理投影矩阵后,便可以使用该矩阵将顶点坐标转换为纹理投影坐标。
使用投影纹理坐标之前,别忘了将投影纹理坐标除以最后一个分量
。到此,你就可以使用所求得的投影纹理坐标的前两个分量去检索纹理图片,从中提取颜色值。还记得Cg
标准函数库中有的纹理映射函数的表达形式为:
tex2DProj(sampler2D
tex, float4
函数的区别就在于:前者会对齐次纹理坐标除以最后一个分量
,然后再进行纹理检索!
注意:上面常被提到的&投影机&只是一种形象化的比喻,本质是视点相机,很多教程上都说&将灯光当作投影机&,这是一种错误的表达(并非是这些教程的作者不懂,而是语言组织上的错误),他们真正的意思是&在当前灯光所在的位置放置一个相机,相机的观察方向和光线投射方向一致&,这个相机就作为投影机使用。在一些阴影算法中,根据光源信息设置投影机,并从投影机的角度渲染出场景信息纹理(如,阴影纹理),然后把这个纹理放到正常的场景渲染相机中使用,这时就需要投影机的矩阵信息来建立投影纹理矩阵了。
附:投影纹理矩阵的计算通常不需要开发人员自己动手,常用的图形API
中都给出了获取各种矩阵(视点矩阵、投影矩阵等)的函数,不过偏移矩阵需要自己设置。在应用程序中获取这些矩阵信息后,再传递到着色程序中使用。
顶点着色程序和片段着色程序如下所示:
投影纹理映射顶点着色程序
void main_v(
&&&&&& float4 position&&&&&&&&&&& &&&&&&&&&&&&& :
&&&&&& float4 normal&&&&&&&&&&&&& &&&&&&&&&&&&& :
&&&&&& out float4 outPos&&&&&&&&&&&&&&&&&&&& &&&&&& :
&&&&&& out float4 outShadowUV &&&&&& :
TEXCOORD0,
&&&&&& uniform float4x4 worldMatrix,
&&&&&& uniform float4x4 worldViewProj,
&&&&&& uniform float4x4 texViewProj //
投影纹理矩阵
&&&&&& outPos = mul(worldViewProj, position);
计算投影纹理坐标
&&&&&& float4 worldPos = mul(worldMatrix,
position);
&&&&&& outShadowUV = mul(texViewProj, worldPos);
投影纹理映射片段着色程序
void main_f(
&&&&&& &&&&&&&&&&&&& float4
shadowUV&&&&&&&&&&&&&&&&&&& : TEXCOORD0,
&&&&&& &&&&&&&&&&&&& out
float4 result&&&&&&&&& &&&&&& &&&&&& :
&&&&&& &&&&&&&&&&&&& uniform
sampler2D projectiveMap& //
用于投影的纹理
&&&&&& shadowUV = shadowUV / shadowUV.w;
&&&&&& float4 mapC
&&&&&& shadowUV.x = (shadowUV.x
+float(1.0))/float(2.0);
&&&&&& shadowUV.y = (shadowUV.y
+float(1.0))/float(2.0);
&&&&&& mapColor = tex2D(projectiveMap,
shadowUV.xy);&&
&&&&&& result = mapC&
本文已收录于以下专栏:
相关文章推荐
投影纹理映射(Projective Texture Mapping)目的是映射一张纹理到物体上,就像将幻灯片投影到墙上一样。该方法不需要在应用程序中指定顶点纹理坐标,实际上,投影纹理映射中使用的纹理坐...
http://blog.csdn.net/xiajun/article/details/7672635
一、纹理投影映射简介
投影纹理映射用于映射一个纹理到物体上,好比...
转载:http://blog.csdn.net/xiajun/article/details/7672635
一、纹理投影映射简介
投影纹理映射用于映射一个纹理到物体上,好比将...
纹理映射技术,是一种将图形绘制(映射)到表面的技术,可以显著地增加所绘制场景的细节和真实感。
纹理实际上是一个二维数组,它的元素是一些颜色值。单个的颜色值被称为纹理元素或纹理...
转载地址&#160;点击打开链接&#160;http://caobeixingqiu./posts/18999.html
1,理论分析圆柱面的纹理映射,可以仿照球面的纹理映射。
只需要定义圆柱面对应的“映射技术”(即OpenCylinderMap)。当然,也可以在OpenCylinder::hit()中计算撞击点时,计...
纹理映射是将纹理空间中的纹理像素映射到屏幕空间中的像素的过程。一张纹理是由一系列的像素组成的(所以叫做texel,翻译为“纹理像素”或“纹理元素”),每个像素基于纹理的宽和高对应一个纹理坐标。这些纹理...
Projective texturing
当人们谈论 纹理的时候 大部分的 是指将纹理坐标应用到 物体表面,投影纹理是指纹理可以投影到物体表面,就好像幻灯片的投影一样。
投影纹理和普通的纹理是一样的 ...
Decals Using Projective Texture Mapping
讲投影纹理的好文章网上是很多的,在此给大家一个参考链接,我就不再呈述了。 此文章的描述很易懂。
投影纹理映射(Pro...
当纹理映射启动后绘图时,你必须为OpenGL ES提供其他数据,即顶点数组中各顶点的 纹理坐标。纹理坐标定义了图像的哪一部分将被映射到多边形。它的工作方式有点奇怪。你有一个正方形或长...
他的最新文章
讲师:刘文志
讲师:陈伟
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)摘抄&GPU Programming And Cg Language Primer 1rd Edition& 中文名&GPU编程与CG语言之阳春白雪下里巴人&&
投影纹理映射( Projective Texture Mapping )最初由 Segal 在文章 &Fast shadows and lighting effects using texture maaping& 中提出,用于映射一个纹理到物体上,就像将幻灯片投影到墙上一样。该方法不需要在应用程序中指定顶点纹理坐标,实际上,投影纹理映射中使用的纹理坐标是在 顶点着色程序中通过视点矩阵和投影矩阵计算得到的,通常也被称作投影纹理坐标 (coordinates in projective space) 。而我们常用的纹理坐标是在建模软件中通过手工调整纹理和 3D 模型的对应关系而产生的。
投影纹理映射的目的是将纹理和三维空间顶点进行对应,这种对应的方法好比 & 将纹理当作一张幻灯片,投影到墙上一样 & 。如 图 35 投影纹理映射 所示。
本章我们针对投影纹理映射的原理和实现方法进行详细的阐述。这一章的地位很高,在一些阴影算法以及体绘制算法中都需要用到投影纹理映射技术。严格的说,只要涉及到 & 纹理实时和空间顶点对应 & ,通常都会用到投影纹理映射技术。
12.1 投影纹理映射的优点
投影纹理映射有两大优点:其一,将纹理与空间顶点进行实时对应,不需要预先在建模软件中生成纹理坐标;其二,使用投影纹理映射,可以有效的避免纹理扭曲现象。
为了说明第一个优点,先举一个简要的例子:很多情况下,我们需要将场景渲染两遍,第一遍是为了获取场景信息,得到的场景信息通常保存为一张纹理(例
如深度图);然后基于&存放场景信息&的纹理进行第二次渲染;第二次渲染结果才是最终显示到屏幕上的效果。为了在第二次渲染中使用到&存放场景信息&的纹
理(无预先设置的纹理坐标),需要时时进行纹理计算,这时就可以使用投影纹理映射技术。实际上,这也是投影纹理映射技术的最广泛的应用了。
& 可能大家对于上一段文字还不能理解得很清楚,不过在第 13 章的阴影贴图算法以及第 15 章的体绘制光线投射算法中,大家会明白其含义。一个算法只有理论加实践,才可能真正的被理解,只会照本宣科的朗诵术语,基本上都是鲁迅先生所说的 & 泥塘 & 似的人。
投影纹理映射的第二个优点是:可以有效的避免纹理扭曲现象。如 图 36
所示,将一张纹理投影到两个三角面片上,它们的顶点纹理坐标相同,但是由于三角面片形状不同,插值出来的内部点的纹理坐标也会产生不同的梯度(
gradient ),最后纹理颜色在两个三角面片上的分布也是不一样的。
图 37 右边所示的是将一张纹理贴到一个正方形上,左边所示的是将同样的纹理贴到一个梯形上,正方形和梯形的顶点纹理坐标相同,但两者的贴图效果是不同的。梯形上的纹理会出现明显的扭曲现象。这是因为几何体的变换,导致插值出来的内部纹理坐标分布不均衡。
12.2 齐次纹理坐标( Homogeneous Texture Coordinates )
齐次纹理坐标( homogeneous texture coordinates
)的概念对大多数人来说比较陌生,纹理坐标一般是二维的,如果是体纹理,其纹理坐标也只是三维的。齐次纹理坐标的出现是为了和三维顶点的齐次坐标相对应,
因为本质上,投影纹理坐标是通过三维顶点的齐次坐标计算得到的。
齐次纹理坐标通常表示为(s,t,r,q ), 以区别于物体位置齐次坐标(x, y, z, w) 。一维纹理常用s 坐标表示,二维纹理常用(s, t) 坐标表示,目前忽略r 坐标,q 坐标的作用与齐次坐标点中的w 坐标非常类似。值一般为1 。
12.3 原理与实现流程
对投影纹理映射,很多教程上都是这么解释的:纹理好比一张幻灯片,灯光好比投影机,然后将纹理投影到一个物体上,类似于投影机将幻灯片投影到墙上。这个比喻没有太大的问题,也找不到更加形象的比喻了。问题是:这个解释刚好颠倒了算法的实现流程。
投影纹理映射真正的流程是 &
根据投影机(视点相机)的位置、投影角度,物体的坐标,求出每个顶点所对应的纹理坐标,然后依据纹理坐标去查询纹理值 &
,也就是说,不是将纹理投影到墙上,而是把墙投影到纹理上。投影纹理坐标的求得,也与纹理本身没有关系,而是由投影机的位置、角度,以及 3D
模型的顶点坐标所决定。所以,我一直觉得 & 投影纹理映射 & 这个术语具有很强的误导性,总让人觉得是把纹理投射出去。
根据顶点坐标获得纹理坐标的本质是将顶点坐标投影到 NDC 平面上,此时投影点的平面坐标即为纹理坐标。如果你将当前视点作为投影机,那么在顶点着色程序中通过 POSTION 语义词输出的顶点投影坐标,就是当前视点下的投影纹理坐标没有被归一化的表达形式。
&Projective texture mapping& 文章中有一幅比较著名的图片,说明计算纹理投影坐标的过程,如 图 38 所示。
左边是正常的顶点坐标空间转换流程,无非是顶点从模型坐标空间转换到世界坐标空间,然后从世界坐标空间转换到视点空间,再从视点空间转换到裁剪空间,然后
投影到视锥近平面,经过这些步骤,一个顶点就确定了在屏幕上的位置。图的右边是将视点当作投影机,根据模型空间的顶点坐标,求得投影纹理坐标的流程。通过
比较,可以发现这两个流程基本一样,唯一的区别在于求取顶点投影坐标后的归一化不一样:计算投影纹理坐标需要将投影顶点坐标归一化到【0 ,1
】空间中,实现这一步,可以在需要左乘矩阵normalMatrix
, 也可以在着色程序中对顶点投影坐标的每个分量先乘以1/2 然后再加上1/2 。
&&&&&&&&&& &&&&&&&&&&&&&&
所以求取投影坐标矩阵的公式为:
求得纹理投影矩阵后,便可以使用该矩阵将顶点坐标转换为纹理投影坐标。
使用投影纹理坐标之前,别忘了将投影纹理坐标除以最后一个分量 q 。到此,你就可以使用所求得的投影纹理坐标的前两个分量去检索纹理图片,从中提取颜色值。还记得Cg 标准函数库中有的纹理映射函数的表达形式为:
tex2DProj(sampler2D tex, float4 szq)
tex2DProj 函数与 tex2D 函数的区别就在于:前者会对齐次纹理坐标除以最后一个分量 q ,然后再进行纹理检索!
注意:上面常被提到的&投影机&只是一种形象化的比喻,本质是视点相机,很多教程上都说&将灯光当作投影机&,这是一种
错误的表达(并非是这些教程的作者不懂,而是语言组织上的错误),他们真正的意思是&在当前灯光所在的位置放置一个相机,相机的观察方向和光线投射方向一
致&,这个相机就作为投影机使用。在一些阴影算法中,根据光源信息设置投影机,并从投影机的角度渲染出场景信息纹理(如,阴影纹理),然后把这个纹理放到
正常的场景渲染相机中使用,这时就需要投影机的矩阵信息来建立投影纹理矩阵了。
附:投影纹理矩阵的计算通常不需要开发人员自己动手,常用的图形API 中都给出了获取各种矩阵(视点矩阵、投影矩阵等)的函数,不过偏移矩阵需要自己设置。在应用程序中获取这些矩阵信息后,再传递到着色程序中使用。
顶点着色程序和片段着色程序如下所示:
代码 16 投影纹理映射顶点着色程序
void main_v(
&&&&&& float4 position&&&&&&&&&&& &&&&&&&&&&&&& : POSITION,
&&&&&& float4 normal&&&&&&&&&&&&& &&&&&&&&&&&&& : NORMAL,
&&&&&& out float4 outPos&&&&&&&&&&&&&&&&&&&& &&&&&& : POSITION,
&&&&&& out float4 outShadowUV &&&&&& : TEXCOORD0,
&&&&&& uniform float4x4 worldMatrix,
&&&&&& uniform float4x4 worldViewProj,
&&&&&& uniform float4x4 texViewProj // 投影纹理矩阵
&&&&&& outPos = mul(worldViewProj, position);
// 计算投影纹理坐标
&&&&&& float4 worldPos = mul(worldMatrix, position);
&&&&&& outShadowUV = mul(texViewProj, worldPos);
代码 17 投影纹理映射片段着色程序
void main_f(
&&&&&& &&&&&&&&&&&&& float4 shadowUV&&&&&&&&&&&&&&&&&&& : TEXCOORD0,
&&&&&& &&&&&&&&&&&&& out float4 result&&&&&&&&& &&&&&& &&&&&& : COLOR,
&&&&&& &&&&&&&&&&&&& uniform sampler2D projectiveMap& // 用于投影的纹理
&&&&&& shadowUV = shadowUV / shadowUV.w;
&&&&&& float4 mapC
&&&&&& // 归一化到 0-1 空间
&&&&&& shadowUV.x = (shadowUV.x +float(1.0))/float(2.0);
&&&&&& shadowUV.y = (shadowUV.y +float(1.0))/float(2.0);
&&&&&& mapColor = tex2D(projectiveMap, shadowUV.xy);&&
&&&&&& result = mapC&
阅读(...) 评论()摘抄&GPU Programming And Cg Language Primer 1rd Edition& 中文
名&GPU编程与CG语言之阳春白雪下里巴人&&
投影纹理映射(
Projective Texture Mapping
&Fast shadows and lighting effects using texture maaping&
中提出,用于映射一个纹理到物体上,就像将幻灯片投影到墙上一样。该方法不需要在应用程序中指定顶点纹理坐标,实际上,投影纹理映射中使用的纹理坐标是在顶点着色程序中通过视点矩阵和投影矩阵计算得到的,通常也被称作投影纹理坐标
(coordinates in projective
。而我们常用的纹理坐标是在建模软件中通过手工调整纹理和
模型的对应关系而产生的。
投影纹理映射的目的是将纹理和三维空间顶点进行对应,这种对应的方法好比
将纹理当作一张幻灯片,投影到墙上一样
投影纹理映射
本章我们针对投影纹理映射的原理和实现方法进行详细的阐述。这一章的地位很高,在一些阴影算法以及体绘制算法中都需要用到投影纹理映射技术。严格的说,只要涉及到
纹理实时和空间顶点对应
,通常都会用到投影纹理映射技术。
投影纹理映射的优点
投影纹理映射有两大优点:其一,将纹理与空间顶点进行实时对应,不需要预先在建模软件中生成纹理坐标;其二,使用投影纹理映射,可以有效的避免纹理扭曲现象。
为了说明第一个优点,先举一个简要的例子:很多情况下,我们需要将场景渲染两遍,第一遍是为了获取场景信息,得到的场景信息通常保存为一张纹理(例如深度图);然后基于&存放场景信息&的纹理进行第二次渲染;第二次渲染结果才是最终显示到屏幕上的效果。为了在第二次渲染中使用到&存放场景信息&的纹理(无预先设置的纹理坐标),需要时时进行纹理计算,这时就可以使用投影纹理映射技术。实际上,这也是投影纹理映射技术的最广泛的应用了。
可能大家对于上一段文字还不能理解得很清楚,不过在第
章的阴影贴图算法以及第
章的体绘制光线投射算法中,大家会明白其含义。一个算法只有理论加实践,才可能真正的被理解,只会照本宣科的朗诵术语,基本上都是鲁迅先生所说的
投影纹理映射的第二个优点是:可以有效的避免纹理扭曲现象。如
所示,将一张纹理投影到两个三角面片上,它们的顶点纹理坐标相同,但是由于三角面片形状不同,插值出来的内部点的纹理坐标也会产生不同的梯度(
),最后纹理颜色在两个三角面片上的分布也是不一样的。
右边所示的是将一张纹理贴到一个正方形上,左边所示的是将同样的纹理贴到一个梯形上,正方形和梯形的顶点纹理坐标相同,但两者的贴图效果是不同的。梯形上的纹理会出现明显的扭曲现象。这是因为几何体的变换,导致插值出来的内部纹理坐标分布不均衡。
齐次纹理坐标(
齐次纹理坐标(
homogeneous texture
coordinates
)的概念对大多数人来说比较陌生,纹理坐标一般是二维的,如果是体纹理,其纹理坐标也只是三维的。齐次纹理坐标的出现是为了和三维顶点的齐次坐标相对应,因为本质上,投影纹理坐标是通过三维顶点的齐次坐标计算得到的。
齐次纹理坐标通常表示为(s,t,r,q
以区别于物体位置齐次坐标(x, y, z, w)
。一维纹理常用s
坐标表示,二维纹理常用(s, t)
坐标表示,目前忽略r
坐标的作用与齐次坐标点中的w
坐标非常类似。值一般为1
原理与实现流程
对投影纹理映射,很多教程上都是这么解释的:纹理好比一张幻灯片,灯光好比投影机,然后将纹理投影到一个物体上,类似于投影机将幻灯片投影到墙上。这个比喻没有太大的问题,也找不到更加形象的比喻了。问题是:这个解释刚好颠倒了算法的实现流程。
投影纹理映射真正的流程是
根据投影机(视点相机)的位置、投影角度,物体的坐标,求出每个顶点所对应的纹理坐标,然后依据纹理坐标去查询纹理值
,也就是说,不是将纹理投影到墙上,而是把墙投影到纹理上。投影纹理坐标的求得,也与纹理本身没有关系,而是由投影机的位置、角度,以及
模型的顶点坐标所决定。所以,我一直觉得
投影纹理映射
这个术语具有很强的误导性,总让人觉得是把纹理投射出去。
根据顶点坐标获得纹理坐标的本质是将顶点坐标投影到
平面上,此时投影点的平面坐标即为纹理坐标。如果你将当前视点作为投影机,那么在顶点着色程序中通过
语义词输出的顶点投影坐标,就是当前视点下的投影纹理坐标没有被归一化的表达形式。
&Projective texture mapping&
文章中有一幅比较著名的图片,说明计算纹理投影坐标的过程,如
左边是正常的顶点坐标空间转换流程,无非是顶点从模型坐标空间转换到世界坐标空间,然后从世界坐标空间转换到视点空间,再从视点空间转换到裁剪空间,然后投影到视锥近平面,经过这些步骤,一个顶点就确定了在屏幕上的位置。图的右边是将视点当作投影机,根据模型空间的顶点坐标,求得投影纹理坐标的流程。通过比较,可以发现这两个流程基本一样,唯一的区别在于求取顶点投影坐标后的归一化不一样:计算投影纹理坐标需要将投影顶点坐标归一化到【0
】空间中,实现这一步,可以在需要左乘矩阵normalMatrix
也可以在着色程序中对顶点投影坐标的每个分量先乘以1/2
然后再加上1/2
&&&&&&&&&& &&&&&&&&&&&&&&
所以求取投影坐标矩阵的公式为:
求得纹理投影矩阵后,便可以使用该矩阵将顶点坐标转换为纹理投影坐标。
使用投影纹理坐标之前,别忘了将投影纹理坐标除以最后一个分量
。到此,你就可以使用所求得的投影纹理坐标的前两个分量去检索纹理图片,从中提取颜色值。还记得Cg
标准函数库中有的纹理映射函数的表达形式为:
tex2DProj(sampler2D
tex, float4
函数的区别就在于:前者会对齐次纹理坐标除以最后一个分量
,然后再进行纹理检索!
注意:上面常被提到的&投影机&只是一种形象化的比喻,本质是视点相机,很多教程上都说&将灯光当作投影机&,这是一种错误的表达(并非是这些教程的作者不懂,而是语言组织上的错误),他们真正的意思是&在当前灯光所在的位置放置一个相机,相机的观察方向和光线投射方向一致&,这个相机就作为投影机使用。在一些阴影算法中,根据光源信息设置投影机,并从投影机的角度渲染出场景信息纹理(如,阴影纹理),然后把这个纹理放到正常的场景渲染相机中使用,这时就需要投影机的矩阵信息来建立投影纹理矩阵了。
附:投影纹理矩阵的计算通常不需要开发人员自己动手,常用的图形API
中都给出了获取各种矩阵(视点矩阵、投影矩阵等)的函数,不过偏移矩阵需要自己设置。在应用程序中获取这些矩阵信息后,再传递到着色程序中使用。
顶点着色程序和片段着色程序如下所示:
投影纹理映射顶点着色程序
void main_v(
&&&&&& float4 position&&&&&&&&&&& &&&&&&&&&&&&& :
&&&&&& float4 normal&&&&&&&&&&&&& &&&&&&&&&&&&& :
&&&&&& out float4 outPos&&&&&&&&&&&&&&&&&&&& &&&&&& :
&&&&&& out float4 outShadowUV &&&&&& :
TEXCOORD0,
&&&&&& uniform float4x4 worldMatrix,
&&&&&& uniform float4x4 worldViewProj,
&&&&&& uniform float4x4 texViewProj //
投影纹理矩阵
&&&&&& outPos = mul(worldViewProj, position);
计算投影纹理坐标
&&&&&& float4 worldPos = mul(worldMatrix,
position);
&&&&&& outShadowUV = mul(texViewProj, worldPos);
投影纹理映射片段着色程序
void main_f(
&&&&&& &&&&&&&&&&&&& float4
shadowUV&&&&&&&&&&&&&&&&&&& : TEXCOORD0,
&&&&&& &&&&&&&&&&&&& out
float4 result&&&&&&&&& &&&&&& &&&&&& :
&&&&&& &&&&&&&&&&&&& uniform
sampler2D projectiveMap& //
用于投影的纹理
&&&&&& shadowUV = shadowUV / shadowUV.w;
&&&&&& float4 mapC
&&&&&& shadowUV.x = (shadowUV.x
+float(1.0))/float(2.0);
&&&&&& shadowUV.y = (shadowUV.y
+float(1.0))/float(2.0);
&&&&&& mapColor = tex2D(projectiveMap,
shadowUV.xy);&&
&&&&&& result = mapC&
本文已收录于以下专栏:
相关文章推荐
投影纹理映射(Projective Texture Mapping)目的是映射一张纹理到物体上,就像将幻灯片投影到墙上一样。该方法不需要在应用程序中指定顶点纹理坐标,实际上,投影纹理映射中使用的纹理坐...
http://blog.csdn.net/xiajun/article/details/7672635
一、纹理投影映射简介
投影纹理映射用于映射一个纹理到物体上,好比...
转载:http://blog.csdn.net/xiajun/article/details/7672635
一、纹理投影映射简介
投影纹理映射用于映射一个纹理到物体上,好比将...
纹理映射技术,是一种将图形绘制(映射)到表面的技术,可以显著地增加所绘制场景的细节和真实感。
纹理实际上是一个二维数组,它的元素是一些颜色值。单个的颜色值被称为纹理元素或纹理...
转载地址&#160;点击打开链接&#160;http://caobeixingqiu./posts/18999.html
1,理论分析圆柱面的纹理映射,可以仿照球面的纹理映射。
只需要定义圆柱面对应的“映射技术”(即OpenCylinderMap)。当然,也可以在OpenCylinder::hit()中计算撞击点时,计...
纹理映射是将纹理空间中的纹理像素映射到屏幕空间中的像素的过程。一张纹理是由一系列的像素组成的(所以叫做texel,翻译为“纹理像素”或“纹理元素”),每个像素基于纹理的宽和高对应一个纹理坐标。这些纹理...
Projective texturing
当人们谈论 纹理的时候 大部分的 是指将纹理坐标应用到 物体表面,投影纹理是指纹理可以投影到物体表面,就好像幻灯片的投影一样。
投影纹理和普通的纹理是一样的 ...
Decals Using Projective Texture Mapping
讲投影纹理的好文章网上是很多的,在此给大家一个参考链接,我就不再呈述了。 此文章的描述很易懂。
投影纹理映射(Pro...
当纹理映射启动后绘图时,你必须为OpenGL ES提供其他数据,即顶点数组中各顶点的 纹理坐标。纹理坐标定义了图像的哪一部分将被映射到多边形。它的工作方式有点奇怪。你有一个正方形或长...
他的最新文章
讲师:刘文志
讲师:陈伟
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 双连通分量 的文章

 

随机推荐