移位贴图 Displacement Mapping

说明:该技术需要VS3.0的支持!!!

一,移位贴图类似于地形渲染。不过由于移位纹理可以做成动态的,因此,该技术可以用来模拟波涛滚滚,起伏不平的海面。

二,类似于法线贴图,移位贴图的每一个纹素中存储了一个向量,这个向量代表了对应顶点的位移。

注意,此处的纹素并不是与像素一一对应,而是与顶点一一对应,因此,纹理的纹素个数与网格的顶点个数是相等的。

在VS阶段,获取每个顶点对应的纹素中的位移向量,(注意,直到3.0版本的vs才支持纹理数据的获取,之前的版本只有ps才能获取纹理数据),施加到局部坐标系下的顶点上,然后进行世界视点投影变换即可。

三,纹理过滤的实现。

之所以补充这一点,是因为某些版本的显卡vs支持的纹理格式有限,而这些种类的纹理格式并不支持纹理过滤,因此我们需要在vs中手动进行纹理过滤。纹理过滤的基本思路如下:

假设点P(x,z)对应的纹理坐标是(117.76,34.13),但是纹素的坐标只能是整数类型的,那么P点对应的应该是哪一个纹素呢?(117,34)?还是(118,35)?实际上,我们需要对如下的四个点:(117,34) (117,35)  (118,34) (118,35)进行采样,并对四个样本值进行加权平均,最终得到的值便是过滤后的纹理值。具体算法实现如下:

// Transform to texel space
    float2 texelpos = DMAP_SIZE * texC0;
       
    // Determine the lerp amounts.          
    float2 lerps = frac(texelpos);
   
 float dmap0[4];
 dmap0[0] = tex2Dlod(DMapS0, float4(texC0, 0.0f, 0.0f)).r;
 dmap0[1] = tex2Dlod(DMapS0, float4(texC0, 0.0f, 0.0f)+float4(DMAP_DX, 0.0f, 0.0f, 0.0f)).r;
 dmap0[2] = tex2Dlod(DMapS0, float4(texC0, 0.0f, 0.0f)+float4(0.0f, DMAP_DX, 0.0f, 0.0f)).r;
 dmap0[3] = tex2Dlod(DMapS0, float4(texC0, 0.0f, 0.0f)+float4(DMAP_DX, DMAP_DX, 0.0f, 0.0f)).r;
 
 // Filter displacement map:
 float h0 = lerp( lerp( dmap0[0], dmap0[1], lerps.x ),
                     lerp( dmap0[2], dmap0[3], lerps.x ),
                     lerps.y );

猜你喜欢

转载自blog.csdn.net/huazai434/article/details/5650629
今日推荐