游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2555|回复: 2

关于ShadowMap反走样Shader的一个问题。

[复制链接]

16

主题

88

帖子

102

积分

注册会员

Rank: 2

积分
102
发表于 2010-8-4 23:03:00 | 显示全部楼层 |阅读模式
以下代码Copy自《GPU Gems I》第11章:

  1. float3 offset_lookup(sampler2D map,
  2.                      float4 loc,
  3.                      float2 offset)
  4. {
  5. return tex2Dproj(map, float4(loc.xy + offset * texmapscale * loc.w,
  6.                                loc.z, loc.w));
  7. }
  8. We can implement the 16-sample version in a fragment program as follows:

  9. float sum = 0;
  10. float x, y;

  11. for (y = -1.5; y <= 1.5; y += 1.0)
  12.   for (x = -1.5; x <= 1.5; x += 1.0)
  13.     sum += offset_lookup(shadowmap, shadowCoord, float2(x, y));

  14. shadowCoeff = sum / 16.0;

复制代码


以下代码来自DX的DEMO-ShadowMap:

  1. // Pixel is in lit area. Find out if it's
  2.         // in shadow using 2x2 percentage closest filtering

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

  6.         // transform to texel space
  7.         float2 texelpos = SMAP_SIZE * ShadowTexC;
  8.         
  9.         // Determine the lerp amounts           
  10.         float2 lerps = frac( texelpos );

  11.         //read in bilerp stamp, doing the shadow checks
  12.         float sourcevals[4];
  13.         sourcevals[0] = (tex2D( g_samShadow, ShadowTexC ) + SHADOW_EPSILON < vPosLight.z / vPosLight.w)? 0.0f: 1.0f;  
  14.         sourcevals[1] = (tex2D( g_samShadow, ShadowTexC + float2(1.0/SMAP_SIZE, 0) ) + SHADOW_EPSILON < vPosLight.z / vPosLight.w)? 0.0f: 1.0f;  
  15.         sourcevals[2] = (tex2D( g_samShadow, ShadowTexC + float2(0, 1.0/SMAP_SIZE) ) + SHADOW_EPSILON < vPosLight.z / vPosLight.w)? 0.0f: 1.0f;  
  16.         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;  
  17.         
  18.         // lerp between the shadow values to calculate our light amount
  19.         float LightAmount = lerp( lerp( sourcevals[0], sourcevals[1], lerps.x ),
  20.                                   lerp( sourcevals[2], sourcevals[3], lerps.x ),
  21.                                   lerps.y );
  22.         // Light it
  23.         Diffuse = ( saturate( dot( -vLight, normalize( vNormal ) ) ) * LightAmount * ( 1 - g_vLightAmbient ) + g_vLightAmbient )
  24.                   * g_vMaterial;
复制代码


我的问题是在做tex2D或者tex2DProj的时候,通过这样多次采样取平均值的方式,它是如何处理纹理边缘的像素的呢?比如说左上角的像素,那么取四周的四个像素或者16个像素,其中的一部分岂不是在纹理外面?

另外一个问题是GPU Gems上面11章的另外一段代码

  1. offset = (float)(frac(position.xy * 0.5) > 0.25);  // mod
  2. offset.y += offset.x;  // y ^= x in floating point
复制代码

第一行到底执行的是什么样的一个运算呢?
完整代码

  1. Figure 11-4 The Sampling Pattern Used for the Four-Sample Version of the Shader

  2. We can implement the four-sample version as follows:

  3. offset = (float)(frac(position.xy * 0.5) > 0.25);  // mod
  4. offset.y += offset.x;  // y ^= x in floating point

  5.    if (offset.y > 1.1)
  6.   offset.y = 0;
  7. shadowCoeff = (offset_lookup(shadowmap, sCoord, offset +
  8.                              float2(-1.5, 0.5)) +
  9.                offset_lookup(shadowmap, sCoord, offset +
  10.                              float2(0.5, 0.5)) +
  11.                offset_lookup(shadowmap, sCoord, offset +
  12.                              float2(-1.5, -1.5)) +
  13.                offset_lookup(shadowmap, sCoord, offset +
  14.                              float2(0.5, -1.5)) ) * 0.25;
复制代码


谢谢大家。
[em3] [em2]

227

主题

1794

帖子

1866

积分

金牌会员

Rank: 6Rank: 6

积分
1866
发表于 2010-8-5 10:27:00 | 显示全部楼层

Re:关于ShadowMap反走样Shader的一个问题。

边缘?这和你怎么设置纹理坐标越位有关

16

主题

88

帖子

102

积分

注册会员

Rank: 2

积分
102
 楼主| 发表于 2010-8-6 17:40:00 | 显示全部楼层

Re: Re:关于ShadowMap反走样Shader的一个问题。

oz01: Re:关于ShadowMap反走样Shader的一个问题。

边缘?这和你怎么设置纹理坐标越位有关


越位?
你说的是纹理寻址模式吗?Texture Addressing Modes >>><<??

Texture Addressing Modes (Direct3D 9)
Your Direct3D application can assign texture coordinates to any vertex of any primitive. For details, see Texture Coordinates (Direct3D 9). Typically, the u- and v-texture coordinates that you assign to a vertex are in the range of 0.0 to 1.0 inclusive. However, by assigning texture coordinates outside that range, you can create certain special texturing effects.

You control what Direct3D does with texture coordinates that are outside the [0.0, 1.0] range by setting the texture addressing mode. For instance, you can have your application set the texture addressing mode so that a texture is tiled across a primitive.

Direct3D enables applications to perform texture wrapping. It is important to note that setting the texture addressing mode to D3DTADDRESS_WRAP is not the same as performing texture wrapping. Setting the texture addressing mode to D3DTADDRESS_WRAP results in multiple copies of the source texture being applied to the current primitive, and enabling texture wrapping changes how the system rasterizes textured polygons. For details, see Texture Wrapping (Direct3D 9).

Enabling texture wrapping effectively makes texture coordinates outside the [0.0, 1.0] range invalid, and the behavior for rasterizing such delinquent texture coordinates is undefined in this case. When texture wrapping is enabled, texture addressing modes are not used. Take care that your application does not specify texture coordinates lower than 0.0 or higher than 1.0 when texture wrapping is enabled.

Setting the Addressing Mode
You can set texture addressing modes for individual texture stages by calling the IDirect3DDevice9::SetSamplerState method. Specify the desired texture stage identifier in the Sampler parameter. Set the Type parameter to D3DSAMP_ADDRESSU, D3DSAMP_ADDRESSV, or D3DSAMP_ADDRESSW values to update the u-, v-, or w-addressing modes individually. The Value parameter determines which mode is being set. This can be any member of the D3DTEXTUREADDRESS enumerated type. To retrieve the current texture address mode for a texture stage, call IDirect3DDevice9::GetSamplerState, using the D3DSAMP_ADDRESSU, D3DSAMP_ADDRESSV, or D3DSAMP_ADDRESSW members of the D3DSAMPLERSTATETYPE enumeration to identify the address mode about which you want information.

Device Limitations
Although the system generally allows texture coordinates outside the range of 0.0 and 1.0, inclusive, hardware limitations often affect how far outside that range texture coordinates can be. A rendering device communicates this limit in the MaxTextureRepeat member of the D3DCAPS9 structure when you retrieve device capabilities. The value in this member describes the full range of texture coordinates allowed by the device. For instance, if this value is 128, then the input texture coordinates must be kept in the range -128.0 to +128.0. Passing vertices with texture coordinates outside this range is invalid. The same restriction applies to the texture coordinates generated as a result of automatic texture coordinate generation and texture coordinate transformations.

The interpretation of MaxTextureRepeat is also affected by the D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE capability bit. When this bit is set, the value in the MaxTextureRepeat member is used precisely as described. However, when D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE is not set, texture repeating limitations depend on the size of the texture indexed by the texture coordinates. In this case, MaxTextureRepeat must be scaled by the current texture size at the largest level of detail to compute the valid texture coordinate range. For example, given a texture dimension of 32 and MaxTextureRepeat of 512, the actual valid texture coordinate range is 512/32 = 16, so the texture coordinates for this device must be within the range of -16.0 to +16.0.

Additional information about the texture addressing modes is contained in the following topics.

Wrap Texture Address Mode (Direct3D 9)
Mirror Texture Address Mode (Direct3D 9)
Clamp Texture Address Mode (Direct3D 9)
Border Color Texture Address Mode (Direct3D 9)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-6-8 05:58

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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