Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: data/branches/Shader_HS18/programs/Example/GLSLES/varianceshadowreceiverfp.glsles @ 12091

Last change on this file since 12091 was 12091, checked in by wiesep, 5 years ago

Updated programs and adjusted Material to work with GLSL>150

File size: 8.3 KB
Line 
1/////////////////////////////////////////////////////////////////////////////////
2//
3// shadowreceiverfp.cg
4//
5// Hamilton Chong
6// (c) 2006
7//
8// This is an example fragment shader for shadow receiver objects. 
9//
10/////////////////////////////////////////////////////////////////////////////////
11
12
13sampler2D ShadowMap : TEXUNIT0;
14
15// Define outputs from vertex shader.
16struct Vertex
17{
18  float4 position       : POSITION;     // fragment position in post projective space
19  float4 shadowCoord    : TEXCOORD0;    // fragment position in shadow map coordinates
20  float  diffuse        : TEXCOORD1;    // diffuse shading value
21};
22
23struct Fragment
24{
25    float4 color  : COLOR0;
26};
27
28Fragment main(Vertex        In,
29              uniform float uSTexWidth,
30              uniform float uSTexHeight)
31{
32    Fragment Out;
33
34    // compute the shadow coordinates for texture lookup
35    // NOTE: texture_viewproj_matrix maps z into [0,1] range, not [-1,1], so
36    //  have to make sure shadow caster stores depth values with same convention.
37    float4 scoord = In.shadowCoord / In.shadowCoord.w;
38
39
40    // -- Bilinear Filtering of Sample --------------------------------------------
41
42    // One could use scoord.xy to look up the shadow map for depth testing, but
43    // we'll be implementing a simple "percentage closest filtering" algorithm instead.
44    // This mimics the behavior of turning on bilinear filtering on NVIDIA hardware
45    // when also performing shadow comparisons.  This causes bilinear filtering of
46    // depth tests.  Note that this is NOT the same as bilinear filtering the depth
47    // values and then doing the depth comparison.  The two operations are not
48    // commutative.  PCF is explicitly about filtering the test values since
49    // testing filtered z values is often meaningless. 
50
51    // Real percentage closest filtering should sample from the entire footprint
52    // on the shadow map, not just seek the closest four sample points.  Such
53    // an improvement is for future work.
54
55   
56    // NOTE: Assuming OpenGL convention for texture lookups with integers in centers.
57    //  DX convention is to have integers mark sample corners
58    float2 tcoord;
59    tcoord.x = (scoord.x * uSTexWidth) - 0.5;
60    tcoord.y = (scoord.y * uSTexHeight) - 0.5;
61    float x0 = floor(tcoord.x);
62    float x1 = ceil(tcoord.x);
63    float fracx = frac(tcoord.x);
64    float y0 = floor(tcoord.y);
65    float y1 = ceil(tcoord.y);
66    float fracy = frac(tcoord.y);
67   
68    // sample coordinates in [0,1]^2 domain
69    float2 t00, t01, t10, t11;
70    float invWidth  = 1.0 / uSTexWidth;
71    float invHeight = 1.0 / uSTexHeight;
72    t00 = float2((x0+0.5) * invWidth, (y0+0.5) * invHeight);
73    t10 = float2((x1+0.5) * invWidth, (y0+0.5) * invHeight);
74    t01 = float2((x0+0.5) * invWidth, (y1+0.5) * invHeight);
75    t11 = float2((x1+0.5) * invWidth, (y1+0.5) * invHeight);
76   
77    // grab the samples
78    float2 z00 = tex2D(ShadowMap, t00).xy;
79    float2 z01 = tex2D(ShadowMap, t01).xy;
80    float2 z10 = tex2D(ShadowMap, t10).xy;
81    float2 z11 = tex2D(ShadowMap, t11).xy;
82
83    // bilinear filter the sample data
84    float2 d0 = ((1.0 - fracx) * z00) + (fracx * z10);
85    float2 d1 = ((1.0 - fracx) * z01) + (fracx * z11);
86    float2 datum = ((1.0 - fracy) * d0) + (fracy * d1);
87
88    // -- Variance Shadow Mapping ---------------------------------------------------
89
90    float zVariance = datum.y - (datum.x * datum.x);
91    float zDeviation = scoord.z - datum.x;
92    zDeviation = (zDeviation < 0.0) ? 0.0 : zDeviation;
93    float visibility = zVariance / (zVariance + (zDeviation * zDeviation));
94    float ztest = (scoord.z < datum.x) ? 1.0:0.0;  // filtering depth ok, because used only for small variance
95    visibility = (zVariance > 0.0) ? visibility : ztest; // if variance too small, we get garbage
96    //0.0000001
97
98    // determine that all geometry within pixel border of shadow map (and outside) is lit
99    float filterBorder = max(invWidth, invHeight);
100    visibility = (all(abs(scoord.xy-0.5)<=0.5-filterBorder)) ? visibility : 1.0;
101
102    // ------------------------------------------------------------------------------
103
104    visibility *= In.diffuse;
105    Out.color = float4(visibility, visibility, visibility, 0.0);
106    return Out;
107}
108/////////////////////////////////////////////////////////////////////////////////
109//
110// shadowreceiverfp.cg
111//
112// Hamilton Chong
113// (c) 2006
114//
115// This is an example fragment shader for shadow receiver objects. 
116//
117/////////////////////////////////////////////////////////////////////////////////
118
119
120sampler2D ShadowMap : TEXUNIT0;
121
122// Define outputs from vertex shader.
123struct Vertex
124{
125  float4 position       : POSITION;     // fragment position in post projective space
126  float4 shadowCoord    : TEXCOORD0;    // fragment position in shadow map coordinates
127  float  diffuse        : TEXCOORD1;    // diffuse shading value
128};
129
130struct Fragment
131{
132    float4 color  : COLOR0;
133};
134
135Fragment main(Vertex        In,
136              uniform float uSTexWidth,
137              uniform float uSTexHeight)
138{
139    Fragment Out;
140
141    // compute the shadow coordinates for texture lookup
142    // NOTE: texture_viewproj_matrix maps z into [0,1] range, not [-1,1], so
143    //  have to make sure shadow caster stores depth values with same convention.
144    float4 scoord = In.shadowCoord / In.shadowCoord.w;
145
146
147    // -- Bilinear Filtering of Sample --------------------------------------------
148
149    // One could use scoord.xy to look up the shadow map for depth testing, but
150    // we'll be implementing a simple "percentage closest filtering" algorithm instead.
151    // This mimics the behavior of turning on bilinear filtering on NVIDIA hardware
152    // when also performing shadow comparisons.  This causes bilinear filtering of
153    // depth tests.  Note that this is NOT the same as bilinear filtering the depth
154    // values and then doing the depth comparison.  The two operations are not
155    // commutative.  PCF is explicitly about filtering the test values since
156    // testing filtered z values is often meaningless. 
157
158    // Real percentage closest filtering should sample from the entire footprint
159    // on the shadow map, not just seek the closest four sample points.  Such
160    // an improvement is for future work.
161
162   
163    // NOTE: Assuming OpenGL convention for texture lookups with integers in centers.
164    //  DX convention is to have integers mark sample corners
165    float2 tcoord;
166    tcoord.x = (scoord.x * uSTexWidth) - 0.5;
167    tcoord.y = (scoord.y * uSTexHeight) - 0.5;
168    float x0 = floor(tcoord.x);
169    float x1 = ceil(tcoord.x);
170    float fracx = frac(tcoord.x);
171    float y0 = floor(tcoord.y);
172    float y1 = ceil(tcoord.y);
173    float fracy = frac(tcoord.y);
174   
175    // sample coordinates in [0,1]^2 domain
176    float2 t00, t01, t10, t11;
177    float invWidth  = 1.0 / uSTexWidth;
178    float invHeight = 1.0 / uSTexHeight;
179    t00 = float2((x0+0.5) * invWidth, (y0+0.5) * invHeight);
180    t10 = float2((x1+0.5) * invWidth, (y0+0.5) * invHeight);
181    t01 = float2((x0+0.5) * invWidth, (y1+0.5) * invHeight);
182    t11 = float2((x1+0.5) * invWidth, (y1+0.5) * invHeight);
183   
184    // grab the samples
185    float2 z00 = tex2D(ShadowMap, t00).xy;
186    float2 z01 = tex2D(ShadowMap, t01).xy;
187    float2 z10 = tex2D(ShadowMap, t10).xy;
188    float2 z11 = tex2D(ShadowMap, t11).xy;
189
190    // bilinear filter the sample data
191    float2 d0 = ((1.0 - fracx) * z00) + (fracx * z10);
192    float2 d1 = ((1.0 - fracx) * z01) + (fracx * z11);
193    float2 datum = ((1.0 - fracy) * d0) + (fracy * d1);
194
195    // -- Variance Shadow Mapping ---------------------------------------------------
196
197    float zVariance = datum.y - (datum.x * datum.x);
198    float zDeviation = scoord.z - datum.x;
199    zDeviation = (zDeviation < 0.0) ? 0.0 : zDeviation;
200    float visibility = zVariance / (zVariance + (zDeviation * zDeviation));
201    float ztest = (scoord.z < datum.x) ? 1.0:0.0;  // filtering depth ok, because used only for small variance
202    visibility = (zVariance > 0.0) ? visibility : ztest; // if variance too small, we get garbage
203    //0.0000001
204
205    // determine that all geometry within pixel border of shadow map (and outside) is lit
206    float filterBorder = max(invWidth, invHeight);
207    visibility = (all(abs(scoord.xy-0.5)<=0.5-filterBorder)) ? visibility : 1.0;
208
209    // ------------------------------------------------------------------------------
210
211    visibility *= In.diffuse;
212    Out.color = float4(visibility, visibility, visibility, 0.0);
213    return Out;
214}
Note: See TracBrowser for help on using the repository browser.