source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg @ 3168

Revision 3168, 9.1 KB checked in by mattausch, 16 years ago (diff)

removed bug (second aa output), normsl normalization now during mrt output

Line 
1#include "../shaderenv.h"
2
3
4struct fragment
5{
6         // normalized screen position
7        float4 pos: WPOS;
8        float2 texCoord: TEXCOORD0;
9        float3 view: TEXCOORD1;
10};
11
12
13struct pixel
14{
15        float4 color: COLOR0;
16        float3 normal: COLOR1;
17        float3 diffVal: COLOR2;
18};
19
20
21float2 myreflect(float2 pt, float2 n)
22{
23        // distance to plane
24        float d = dot(n, pt);
25        // reflect around plane
26        float2 rpt = pt - d * 2.0f * n;
27
28        return rpt;
29}
30
31
32/** function for standard deferred shading
33*/
34float4 shade(fragment IN,
35                         uniform float4 color,
36                         uniform float3 normal,
37                         float3 lightDir)
38{
39        // diffuse intensity
40        const float angle = saturate(dot(normal, lightDir));
41       
42        float4 lightDiffuse = glstate.light[0].diffuse;
43        float4 diffuse = angle * lightDiffuse;
44
45        // global ambient
46        const float4 ambient = glstate.light[0].ambient;
47       
48        float4 outColor;
49
50        // hack: prevent shading the sky
51        if (color.w > 1e19f) outColor = color;
52        else outColor = (ambient + diffuse) * color;
53
54        return outColor;
55}
56
57
58
59/** The mrt shader for standard rendering
60*/
61pixel main(fragment IN,
62                   uniform sampler2D colors,
63                   uniform sampler2D normals,
64                   uniform float3 lightDir
65                   )
66{
67        pixel OUT;
68
69        float4 norm = tex2D(normals, IN.texCoord);
70        float4 color = tex2Dlod(colors, float4(IN.texCoord, 0, 0));
71       
72        float3 normal = normalize(norm.xyz);
73        float4 col = shade(IN, color, normal, lightDir);
74       
75        OUT.color = col;
76        // store scaled view vector so wie don't have to normalize for e.g., ssao
77        OUT.color.w = color.w;// / length(IN.view);
78        //OUT.color = color;
79        return OUT;
80}
81
82
83float CalcShadowTerm(fragment IN,
84                                         uniform sampler2D shadowMap,
85                                         uniform float scale,
86                                         uniform float2 lightSpacePos,
87                                         uniform float depth,
88                                         uniform float2 samples[NUM_PCF_TABS],
89                                         uniform float weights[NUM_PCF_TABS],
90                                         uniform sampler2D noiseTexture
91                                         )
92{
93        //float shadowDepth = tex2D(shadowMap, lightSpacePos).x;
94        //return step(depth, shadowDepth);
95
96        float total_d = .0f;
97        float total_w = .0f;
98
99        for (int i = 0; i < NUM_PCF_TABS; ++ i)
100        {
101                const float2 offset = samples[i];
102                const float w = weights[i];
103
104#if 1
105                ////////////////////
106                //-- add random noise: reflect around random normal vector (warning: slow!)
107
108                float2 mynoise = tex2D(noiseTexture, IN.texCoord).xy;
109                const float2 offsetTransformed = myreflect(offset, mynoise);
110#else
111                const float2 offsetTransformed = offset;
112#endif
113                // weight with projected coordinate to reach similar kernel size for near and far
114                float2 texcoord = lightSpacePos + offsetTransformed * scale;
115
116                float shadowDepth = tex2D(shadowMap, texcoord).x;
117
118                total_d += w * step(depth, shadowDepth);
119                total_w += w;
120        }
121
122        total_d /= (float)total_w;
123
124        return total_d;
125}
126
127
128inline float3 Interpol(float2 w, float3 bl, float3 br, float3 tl, float3 tr)
129{
130        float3 x1 = lerp(bl, tl, w.y);
131        float3 x2 = lerp(br, tr, w.y);
132        float3 v  = lerp(x1, x2, w.x);
133
134        return v;
135}
136
137
138pixel main_shadow(fragment IN,
139                                  uniform sampler2D colors,
140                                  uniform sampler2D positions,
141                                  uniform sampler2D normals,               
142                                  uniform sampler2D shadowMap,
143                                  uniform float4x4 shadowMatrix,
144                                  uniform float sampleWidth,
145                                  uniform sampler2D noiseTex,
146                                  uniform float2 samples[NUM_PCF_TABS],
147                                  uniform float weights[NUM_PCF_TABS],
148                                  uniform float3 lightDir,
149                                  uniform float3 eyePos,
150                                  uniform float3 bl,
151                                  uniform float3 br,
152                                  uniform float3 tl,
153                                  uniform float3 tr
154                                  )
155{
156        pixel OUT;
157
158        const float3 normal = tex2D(normals, IN.texCoord.xy);
159
160        float4 color = tex2Dlod(colors, float4(IN.texCoord, 0, 0));
161
162        /// reconstruct position from the eye space depth
163        float3 viewDir = IN.view;
164        const float lenView = length(viewDir);
165        viewDir /= lenView;
166
167        const float eyeDepth = tex2Dlod(colors, float4(IN.texCoord, 0, 0)).w;
168
169        const float4 worldPos = float4(eyePos - viewDir * eyeDepth, 1);
170       
171        // diffuse intensity
172        const float angle = saturate(dot(normal, lightDir));
173        const float4 lightDiffuse = glstate.light[0].diffuse;
174       
175        float4 diffuse = lightDiffuse * angle;
176
177        // hack: prevent shadowing the sky     
178        const bool useShading = (color.w < 1e19f);
179
180        // calc diffuse illumination + shadow term
181        if (useShading &&
182                (angle > 1e-3f) // shadow only if diffuse color has some minimum intensity
183                )
184        {
185                float4 lightSpacePos = mul(shadowMatrix, worldPos);
186                lightSpacePos /= lightSpacePos.w;
187
188                float shadowTerm = CalcShadowTerm(IN, shadowMap, sampleWidth, lightSpacePos.xy, lightSpacePos.z, samples, weights, noiseTex);
189       
190                diffuse *= shadowTerm;
191        }
192
193        // light ambient term
194        const float4 ambient = glstate.light[0].ambient;
195        // compute shading
196        OUT.color = useShading ? (ambient + diffuse) * color : color;
197        // store scaled view vector from now on so wie don't have to normalize later (e.g., for ssao)
198        //OUT.color.w = color.w / lenView;
199
200        return OUT;
201}
202
203
204float4 Output(fragment IN, uniform sampler2D colors): COLOR
205{   
206        return tex2Dlod(colors, float4(IN.texCoord, 0, 0));
207}
208
209
210float4 ScaleDepth(fragment IN,
211                                  uniform sampler2D colors): COLOR
212{   
213        float4 color = tex2Dlod(colors, float4(IN.texCoord, 0, 0));
214        // store scaled view vector so wie don't have to normalize for e.g., ssao
215        color.w /= length(IN.view);
216       
217        return color;
218}
219
220
221
222inline float SqrLen(float3 v)
223{
224        return v.x * v.x + v.y * v.y + v.z * v.z;
225}
226
227
228
229/** This shader computes the reprojection and checks
230        if the reprojected pixel from last frame is still
231        valid in the current frame
232        */
233inline float PixelValid(sampler2D oldTex,
234                                                float4 color,
235                                                float3 diffVec,
236                                                float2 texCoord,
237                                                float3 viewDir,
238                                                float3 oldEyePos,
239                                                float4x4 modelViewProj,
240                                                float4x4 oldModelViewProj,
241                                                float3 oldbl,
242                                                float3 oldbr,
243                                                float3 oldtl,
244                                                float3 oldtr
245                                                )
246{
247        // reconstruct position from the eye space depth
248        const float eyeSpaceDepth = color.w;
249        const float4 worldPos = float4(-viewDir * eyeSpaceDepth, 1.0f);
250
251       
252
253        ////////////////
254        //-- calculcate the current projected posiion (also used for next frame)
255       
256        float4 projPos = mul(modelViewProj, worldPos);
257        const float invw = 1.0f / projPos.w;
258        projPos *= invw;
259
260        // compute position from old frame for dynamic objects + translational portion
261        const float3 translatedPos = diffVec - oldEyePos + worldPos.xyz;
262
263
264        /////////////////
265        //-- reproject into old frame and calculate texture position of sample in old frame
266
267        // note: the old model view matrix only holds the view orientation part
268        float4 backProjPos = mul(oldModelViewProj, float4(translatedPos, 1.0f));
269        backProjPos /= backProjPos.w;
270       
271        // fit from unit cube into 0 .. 1
272        const float2 oldTexCoords = backProjPos.xy * 0.5f + 0.5f;
273        //const float2 oldTexCoords = texCoord;
274        // retrieve the sample from the last frame
275        const float4 oldPixel = tex2Dlod(oldTex, float4(oldTexCoords, .0f, .0f));
276
277        // calculate eye space position of sample in old frame
278        const float oldEyeSpaceDepth = oldPixel.w;
279
280        // vector from eye pos to old sample
281        const float3 oldViewDir = Interpol(oldTexCoords, oldbl, oldbr, oldtl, oldtr);
282        const float invLen = 1.0f / length(oldViewDir);
283        const float projectedEyeSpaceDepth = invLen * length(translatedPos);
284       
285        const float depthDif = abs(1.0f - oldEyeSpaceDepth / projectedEyeSpaceDepth);
286
287        const float squaredLen = SqrLen(diffVec);
288       
289        // test if this pixel was not valid in the old frame
290        float validPixel;
291
292        if ((((squaredLen <= DYNAMIC_OBJECTS_THRESHOLD) && (oldPixel.z <= DYNAMIC_OBJECTS_THRESHOLD)) ||
293                (depthDif <= MIN_DEPTH_DIFF))
294                && (oldTexCoords.x >= 0.0f) && (oldTexCoords.x < 1.0f)
295                && (oldTexCoords.y >= 0.0f) && (oldTexCoords.y < 1.0f)
296                )
297        {
298                validPixel = 0.0f;
299        }
300        else
301        {       
302                validPixel = 10.5f;
303        }
304
305        //return depthDif;
306        return validPixel;
307}
308
309
310pixel PrepareSsao(fragment IN,
311                                   uniform sampler2D colorsTex,
312                                   uniform sampler2D normalsTex,
313                                   uniform sampler2D diffVals,
314                                   uniform sampler2D oldTex,
315                                   uniform float4x4 modelViewProj,
316                                   uniform float4x4 oldModelViewProj,
317                                   uniform float3 oldbl,
318                                   uniform float3 oldbr,
319                                   uniform float3 oldtl,
320                                   uniform float3 oldtr,
321                                   uniform float3 oldEyePos
322                                   )
323{   
324        pixel pix;
325
326        const float3 normal = normalize(tex2Dlod(normalsTex, float4(IN.texCoord, 0 ,0)).xyz);
327        const float3 difVec = tex2Dlod(diffVals, float4(IN.texCoord, 0 ,0)).xyz;
328
329        const float3 viewDir = IN.view;
330        float4 color = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0));
331
332        // store scaled view vector so wie don't have to normalize for e.g., ssao
333        color.w /= length(IN.view);
334        //color.w = 1;
335
336        // do reprojection and filter out the pixels that are not save
337        float pValid = PixelValid(
338                oldTex,
339                color,
340                difVec.xyz,
341                IN.texCoord,
342                viewDir,
343                oldEyePos,
344                modelViewProj,
345                oldModelViewProj,
346                oldbl, oldbr, oldtl, oldtr
347                );
348
349        pix.color = color;
350        pix.color.x = pValid;
351
352        pix.normal = normal;
353        pix.diffVal = difVec;
354
355        return pix;
356}
357
358
359float4 DownSample(fragment IN,
360                                  uniform sampler2D colors,
361                                  uniform float2 downSampleOffs[NUM_DOWNSAMPLES]): COLOR
362{   
363        // let bilinear filtering do its work
364        float4 color = tex2Dlod(colors, float4(IN.texCoord, 0, 0));
365        return color;
366}
Note: See TracBrowser for help on using the repository browser.