|
以下代码Copy自《GPU Gems I》第11章:
- float3 offset_lookup(sampler2D map,
- float4 loc,
- float2 offset)
- {
- return tex2Dproj(map, float4(loc.xy + offset * texmapscale * loc.w,
- loc.z, loc.w));
- }
- We can implement the 16-sample version in a fragment program as follows:
- float sum = 0;
- float x, y;
- for (y = -1.5; y <= 1.5; y += 1.0)
- for (x = -1.5; x <= 1.5; x += 1.0)
- sum += offset_lookup(shadowmap, shadowCoord, float2(x, y));
- shadowCoeff = sum / 16.0;
复制代码
以下代码来自DX的DEMO-ShadowMap:
- // 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;
复制代码
我的问题是在做tex2D或者tex2DProj的时候,通过这样多次采样取平均值的方式,它是如何处理纹理边缘的像素的呢?比如说左上角的像素,那么取四周的四个像素或者16个像素,其中的一部分岂不是在纹理外面?
另外一个问题是GPU Gems上面11章的另外一段代码
- offset = (float)(frac(position.xy * 0.5) > 0.25); // mod
- offset.y += offset.x; // y ^= x in floating point
复制代码
第一行到底执行的是什么样的一个运算呢?
完整代码
- Figure 11-4 The Sampling Pattern Used for the Four-Sample Version of the Shader
- We can implement the four-sample version as follows:
- offset = (float)(frac(position.xy * 0.5) > 0.25); // mod
- offset.y += offset.x; // y ^= x in floating point
- if (offset.y > 1.1)
- offset.y = 0;
- shadowCoeff = (offset_lookup(shadowmap, sCoord, offset +
- float2(-1.5, 0.5)) +
- offset_lookup(shadowmap, sCoord, offset +
- float2(0.5, 0.5)) +
- offset_lookup(shadowmap, sCoord, offset +
- float2(-1.5, -1.5)) +
- offset_lookup(shadowmap, sCoord, offset +
- float2(0.5, -1.5)) ) * 0.25;
复制代码
谢谢大家。
[em3] [em2] |
|