varianceshadowreceiverfp.cg
资源名称:3dwind2.0.rar [点击查看]
上传用户:xhbjoy
上传日期:2014-10-07
资源大小:38068k
文件大小:4k
源码类别:
游戏引擎
开发平台:
Visual C++
- /////////////////////////////////////////////////////////////////////////////////
- //
- // shadowreceiverfp.cg
- //
- // Hamilton Chong
- // (c) 2006
- //
- // This is an example fragment shader for shadow receiver objects.
- //
- /////////////////////////////////////////////////////////////////////////////////
- sampler2D ShadowMap : TEXUNIT0;
- // Define outputs from vertex shader.
- struct Vertex
- {
- float4 position : POSITION; // fragment position in post projective space
- float4 shadowCoord : TEXCOORD0; // fragment position in shadow map coordinates
- float diffuse : TEXCOORD1; // diffuse shading value
- };
- struct Fragment
- {
- float4 color : COLOR0;
- };
- Fragment main(Vertex In,
- uniform float uSTexWidth,
- uniform float uSTexHeight)
- {
- Fragment Out;
- // compute the shadow coordinates for texture lookup
- // NOTE: texture_viewproj_matrix maps z into [0,1] range, not [-1,1], so
- // have to make sure shadow caster stores depth values with same convention.
- float4 scoord = In.shadowCoord / In.shadowCoord.w;
- // -- Bilinear Filtering of Sample --------------------------------------------
- // One could use scoord.xy to look up the shadow map for depth testing, but
- // we'll be implementing a simple "percentage closest filtering" algorithm instead.
- // This mimics the behavior of turning on bilinear filtering on NVIDIA hardware
- // when also performing shadow comparisons. This causes bilinear filtering of
- // depth tests. Note that this is NOT the same as bilinear filtering the depth
- // values and then doing the depth comparison. The two operations are not
- // commutative. PCF is explicitly about filtering the test values since
- // testing filtered z values is often meaningless.
- // Real percentage closest filtering should sample from the entire footprint
- // on the shadow map, not just seek the closest four sample points. Such
- // an improvement is for future work.
- // NOTE: Assuming OpenGL convention for texture lookups with integers in centers.
- // DX convention is to have integers mark sample corners
- float2 tcoord;
- tcoord.x = (scoord.x * uSTexWidth) - 0.5;
- tcoord.y = (scoord.y * uSTexHeight) - 0.5;
- float x0 = floor(tcoord.x);
- float x1 = ceil(tcoord.x);
- float fracx = frac(tcoord.x);
- float y0 = floor(tcoord.y);
- float y1 = ceil(tcoord.y);
- float fracy = frac(tcoord.y);
- // sample coordinates in [0,1]^2 domain
- float2 t00, t01, t10, t11;
- float invWidth = 1.0 / uSTexWidth;
- float invHeight = 1.0 / uSTexHeight;
- t00 = float2((x0+0.5) * invWidth, (y0+0.5) * invHeight);
- t10 = float2((x1+0.5) * invWidth, (y0+0.5) * invHeight);
- t01 = float2((x0+0.5) * invWidth, (y1+0.5) * invHeight);
- t11 = float2((x1+0.5) * invWidth, (y1+0.5) * invHeight);
- // grab the samples
- float2 z00 = tex2D(ShadowMap, t00).xy;
- float2 z01 = tex2D(ShadowMap, t01).xy;
- float2 z10 = tex2D(ShadowMap, t10).xy;
- float2 z11 = tex2D(ShadowMap, t11).xy;
- // bilinear filter the sample data
- float2 d0 = ((1.0 - fracx) * z00) + (fracx * z10);
- float2 d1 = ((1.0 - fracx) * z01) + (fracx * z11);
- float2 datum = ((1.0 - fracy) * d0) + (fracy * d1);
- // -- Variance Shadow Mapping ---------------------------------------------------
- float zVariance = datum.y - (datum.x * datum.x);
- float zDeviation = scoord.z - datum.x;
- zDeviation = (zDeviation < 0.0) ? 0.0 : zDeviation;
- float visibility = zVariance / (zVariance + (zDeviation * zDeviation));
- float ztest = (scoord.z < datum.x) ? 1.0:0.0; // filtering depth ok, because used only for small variance
- visibility = (zVariance > 0.0) ? visibility : ztest; // if variance too small, we get garbage
- //0.0000001
- // determine that all geometry within pixel border of shadow map (and outside) is lit
- float filterBorder = max(invWidth, invHeight);
- visibility = (all(abs(scoord.xy-0.5)<=0.5-filterBorder)) ? visibility : 1.0;
- // ------------------------------------------------------------------------------
- visibility *= In.diffuse;
- Out.color = float4(visibility, visibility, visibility, 0.0);
- return Out;
- }