|
|
看了一篇关于体积雾的文章。介绍说可以用D3DFMT_G16R16格式的纹理来进行雾厚度的计算。过程是这样的:
将D3DFMT_G16R16格式的纹理作为RenderTarget,将Fog Volume渲染两次,第一次设置CULLMODD=CCW,colorwriteenable=GREEN将前向面的深度值渲染到G通道中,第二次设置CULLMODD=CW,colorwriteenable=RED将后向面的深度值写到R通道中。两次渲染时都设置alphablendenable = true;alphatestenable = false;srcblend = one;destblend = one;这样就能对深度值进行累加。
shader代码如下:
void VS_depthOutput( in float3 vLocalPos : POSITION,
out float4 oScreenPos : POSITION,
out float2 oTexDepth : TEXCOORD0 )
{
oScreenPos = mul( float4(vLocalPos,1.0f), matWorldViewProj );
oTexDepth.x = oScreenPos.w * ScaleAndOffset.x + ScaleAndOffset.y;
oTexDepth.y = 0.0f;
}
float4 PS_depthOutput( float2 vTexDepth : TEXCOORD0 ) : COLOR
{
// Return the depth value.
return vTexDepth.xxxx;
}
之后,应用这个纹理绘制一个屏幕对齐的四边形,在PixelShader中对这个纹理进行采样,将G,R通道的值相减得到雾的厚度。shader代码如下:
float4 ComputeFogValuePS( float2 vTexCoord : TEXCOORD0 ) : COLOR
{
float2 Sums = tex2D( SumTex, vTexCoord );
float4 Color;
Color.rgb = FogColorAndDensity.rgb;//set fog color
float thickness = (Sums.g - Sums.r)*f_scale;//f_scale???
Color.a = thickness ;//set alpha to the thickness of fog
return Color;
}
现在问题就是,1)这个D3DFMT_G16R16格式纹理是如何累加深度值的?我每次算出的深度都是一个[0,1]范围的浮点值,DX是把[0,1]映射成[0,255],然后加到纹理数据里面吗?
2)在pixelshader中对其采样时又是如何把16为颜色值转变成浮点值的呢?
比如说16位色的范围是[0,256*256-1],它在采样时是映射成[0.0f,1.0f]吗?如果是这样的话,我只累加一两次的话,得到的值将非常小了,但实际情况又不像。
有哪位用过D3DFMT_G16R16格式纹理的吗?
|
|