|
[em5]
下面的代码来自最新版DX SDK的Sample。ShadowMap。一个问题关于将RenderTarget坐标变换到纹理坐标:
- //-----------------------------------------------------------------------------
- // Pixel Shader: PixScene
- // Desc: Process pixel (do per-pixel lighting) for enabled scene
- //-----------------------------------------------------------------------------
- float4 PixScene( float2 Tex : TEXCOORD0,
- float4 vPos : TEXCOORD1,
- float3 vNormal : TEXCOORD2,
- float4 vPosLight : TEXCOORD3 ) : COLOR
- {
- float4 Diffuse;
- // vLight is the unit vector from the light to this pixel
- float3 vLight = normalize( float3( vPos - g_vLightPos ) );
- // Compute diffuse from the light
- if( dot( vLight, g_vLightDir ) > g_fCosTheta ) // Light must face the pixel (within Theta)
- {
- // Pixel is in lit area. Find out if it's
- // in shadow using 2x2 percentage closest filtering
- //transform from RT space to texture space.
- float2 ShadowTexC = 0.5 * vPosLight.xy / vPosLight.w + float2( 0.5, 0.5 );
- ShadowTexC.y = 1.0f - ShadowTexC.y;
- // transform to texel space
- float2 texelpos = SMAP_SIZE * ShadowTexC;
-
- // Determine the lerp amounts
- float2 lerps = frac( texelpos );
- //read in bilerp stamp, doing the shadow checks
- float sourcevals[4];
- sourcevals[0] = (tex2D( g_samShadow, ShadowTexC ) + SHADOW_EPSILON < vPosLight.z / vPosLight.w)? 0.0f: 1.0f;
- sourcevals[1] = (tex2D( g_samShadow, ShadowTexC + float2(1.0/SMAP_SIZE, 0) ) + SHADOW_EPSILON < vPosLight.z / vPosLight.w)? 0.0f: 1.0f;
- sourcevals[2] = (tex2D( g_samShadow, ShadowTexC + float2(0, 1.0/SMAP_SIZE) ) + SHADOW_EPSILON < vPosLight.z / vPosLight.w)? 0.0f: 1.0f;
- sourcevals[3] = (tex2D( g_samShadow, ShadowTexC + float2(1.0/SMAP_SIZE, 1.0/SMAP_SIZE) ) + SHADOW_EPSILON < vPosLight.z / vPosLight.w)? 0.0f: 1.0f;
-
- // lerp between the shadow values to calculate our light amount
- float LightAmount = lerp( lerp( sourcevals[0], sourcevals[1], lerps.x ),
- lerp( sourcevals[2], sourcevals[3], lerps.x ),
- lerps.y );
- // Light it
- Diffuse = ( saturate( dot( -vLight, normalize( vNormal ) ) ) * LightAmount * ( 1 - g_vLightAmbient ) + g_vLightAmbient )
- * g_vMaterial;
- }
- else
- {
- Diffuse = g_vLightAmbient * g_vMaterial;
- }
- return tex2D( g_samScene, Tex ) * Diffuse;
- }
复制代码
问题主要在这里:
- //transform from RT space to texture space.
- float2 ShadowTexC = 0.5 * vPosLight.xy / vPosLight.w + float2( 0.5, 0.5 );
- ShadowTexC.y = 1.0f - ShadowTexC.y;
复制代码
这是什么样的算法啊?如何从RenderTarget空间变换到纹理空间啊?为什么y轴需要取1.0与之的差啊?
[em20] |
|