游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2775|回复: 4

询问一个关于ShadowMap Demo的Shader的问题。

[复制链接]

16

主题

88

帖子

102

积分

注册会员

Rank: 2

积分
102
发表于 2009-12-17 23:08:00 | 显示全部楼层 |阅读模式
[em5]
下面的代码来自最新版DX SDK的Sample。ShadowMap。一个问题关于将RenderTarget坐标变换到纹理坐标:

  1. //-----------------------------------------------------------------------------
  2. // Pixel Shader: PixScene
  3. // Desc: Process pixel (do per-pixel lighting) for enabled scene
  4. //-----------------------------------------------------------------------------
  5. float4 PixScene( float2 Tex : TEXCOORD0,
  6.                  float4 vPos : TEXCOORD1,
  7.                  float3 vNormal : TEXCOORD2,
  8.                  float4 vPosLight : TEXCOORD3 ) : COLOR
  9. {
  10.     float4 Diffuse;

  11.     // vLight is the unit vector from the light to this pixel
  12.     float3 vLight = normalize( float3( vPos - g_vLightPos ) );

  13.     // Compute diffuse from the light
  14.     if( dot( vLight, g_vLightDir ) > g_fCosTheta ) // Light must face the pixel (within Theta)
  15.     {
  16.         // Pixel is in lit area. Find out if it's
  17.         // in shadow using 2x2 percentage closest filtering

  18.         //transform from RT space to texture space.
  19.         float2 ShadowTexC = 0.5 * vPosLight.xy / vPosLight.w + float2( 0.5, 0.5 );
  20.         ShadowTexC.y = 1.0f - ShadowTexC.y;

  21.         // transform to texel space
  22.         float2 texelpos = SMAP_SIZE * ShadowTexC;
  23.         
  24.         // Determine the lerp amounts           
  25.         float2 lerps = frac( texelpos );

  26.         //read in bilerp stamp, doing the shadow checks
  27.         float sourcevals[4];
  28.         sourcevals[0] = (tex2D( g_samShadow, ShadowTexC ) + SHADOW_EPSILON < vPosLight.z / vPosLight.w)? 0.0f: 1.0f;  
  29.         sourcevals[1] = (tex2D( g_samShadow, ShadowTexC + float2(1.0/SMAP_SIZE, 0) ) + SHADOW_EPSILON < vPosLight.z / vPosLight.w)? 0.0f: 1.0f;  
  30.         sourcevals[2] = (tex2D( g_samShadow, ShadowTexC + float2(0, 1.0/SMAP_SIZE) ) + SHADOW_EPSILON < vPosLight.z / vPosLight.w)? 0.0f: 1.0f;  
  31.         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;  
  32.         
  33.         // lerp between the shadow values to calculate our light amount
  34.         float LightAmount = lerp( lerp( sourcevals[0], sourcevals[1], lerps.x ),
  35.                                   lerp( sourcevals[2], sourcevals[3], lerps.x ),
  36.                                   lerps.y );
  37.         // Light it
  38.         Diffuse = ( saturate( dot( -vLight, normalize( vNormal ) ) ) * LightAmount * ( 1 - g_vLightAmbient ) + g_vLightAmbient )
  39.                   * g_vMaterial;
  40.     }
  41.     else
  42.     {
  43.         Diffuse = g_vLightAmbient * g_vMaterial;
  44.     }

  45.     return tex2D( g_samScene, Tex ) * Diffuse;
  46. }
复制代码



问题主要在这里:

  1.         //transform from RT space to texture space.
  2.         float2 ShadowTexC = 0.5 * vPosLight.xy / vPosLight.w + float2( 0.5, 0.5 );
  3.         ShadowTexC.y = 1.0f - ShadowTexC.y;
复制代码

这是什么样的算法啊?如何从RenderTarget空间变换到纹理空间啊?为什么y轴需要取1.0与之的差啊?
[em20]

16

主题

88

帖子

102

积分

注册会员

Rank: 2

积分
102
 楼主| 发表于 2009-12-17 23:08:00 | 显示全部楼层

Re:询问一个关于ShadowMap Demo的Shader的问题。

看来论坛的脚本有点问题。

34

主题

629

帖子

629

积分

高级会员

Rank: 4

积分
629
发表于 2009-12-18 15:44:00 | 显示全部楼层

Re:询问一个关于ShadowMap Demo的Shader的问题。

RT spaceY轴向上,texture spaceY轴向下

42

主题

140

帖子

158

积分

注册会员

Rank: 2

积分
158
发表于 2009-12-18 16:52:00 | 显示全部楼层

Re:询问一个关于ShadowMap Demo的Shader的问题。

就是把[-1, +1]的齐次裁剪空间转换到纹理坐标的[0,1]。

16

主题

88

帖子

102

积分

注册会员

Rank: 2

积分
102
 楼主| 发表于 2009-12-23 21:42:00 | 显示全部楼层

Re:询问一个关于ShadowMap Demo的Shader的问题。

谢谢。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-17 01:09

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表