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

Revision 3160, 9.0 KB checked in by mattausch, 16 years ago (diff)

working quite well, put filter size adaptation factor from 10 to 5, still
small popping artifact when switching from no filter to filter for convergence 100.
problems with balconies, transition between low convergence regions and high convergence

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};
17
18
19float2 myreflect(float2 pt, float2 n)
20{
21        // distance to plane
22        float d = dot(n, pt);
23        // reflect around plane
24        float2 rpt = pt - d * 2.0f * n;
25
26        return rpt;
27}
28
29
30/** function for standard deferred shading
31*/
32float4 shade(fragment IN,
33                         uniform float4 color,
34                         uniform float3 normal,
35                         float3 lightDir)
36{
37        // diffuse intensity
38        const float angle = saturate(dot(normal, lightDir));
39       
40        float4 lightDiffuse = glstate.light[0].diffuse;
41        float4 diffuse = angle * lightDiffuse;
42
43        // global ambient
44        const float4 ambient = glstate.light[0].ambient;
45       
46        float4 outColor;
47
48        // hack: prevent shading the sky
49        if (color.w > 1e19f) outColor = color;
50        else outColor = (ambient + diffuse) * color;
51
52        return outColor;
53}
54
55
56
57/** The mrt shader for standard rendering
58*/
59pixel main(fragment IN,
60                   uniform sampler2D colors,
61                   uniform sampler2D normals,
62                   uniform float3 lightDir
63                   )
64{
65        pixel OUT;
66
67        float4 norm = tex2D(normals, IN.texCoord);
68        float4 color = tex2Dlod(colors, float4(IN.texCoord, 0, 0));
69       
70        float3 normal = normalize(norm.xyz);
71        float4 col = shade(IN, color, normal, lightDir);
72       
73        OUT.color = col;
74        // store scaled view vector so wie don't have to normalize for e.g., ssao
75        OUT.color.w = color.w;// / length(IN.view);
76        //OUT.color = color;
77        return OUT;
78}
79
80
81float CalcShadowTerm(fragment IN,
82                                         uniform sampler2D shadowMap,
83                                         uniform float scale,
84                                         uniform float2 lightSpacePos,
85                                         uniform float depth,
86                                         uniform float2 samples[NUM_PCF_TABS],
87                                         uniform float weights[NUM_PCF_TABS],
88                                         uniform sampler2D noiseTexture
89                                         )
90{
91        //float shadowDepth = tex2D(shadowMap, lightSpacePos).x;
92        //return step(depth, shadowDepth);
93
94        float total_d = .0f;
95        float total_w = .0f;
96
97        for (int i = 0; i < NUM_PCF_TABS; ++ i)
98        {
99                const float2 offset = samples[i];
100                const float w = weights[i];
101
102#if 1
103                ////////////////////
104                //-- add random noise: reflect around random normal vector (warning: slow!)
105
106                float2 mynoise = tex2D(noiseTexture, IN.texCoord).xy;
107                const float2 offsetTransformed = myreflect(offset, mynoise);
108#else
109                const float2 offsetTransformed = offset;
110#endif
111                // weight with projected coordinate to reach similar kernel size for near and far
112                float2 texcoord = lightSpacePos + offsetTransformed * scale;
113
114                float shadowDepth = tex2D(shadowMap, texcoord).x;
115
116                total_d += w * step(depth, shadowDepth);
117                total_w += w;
118        }
119
120        total_d /= (float)total_w;
121
122        return total_d;
123}
124
125
126inline float3 Interpol(float2 w, float3 bl, float3 br, float3 tl, float3 tr)
127{
128        float3 x1 = lerp(bl, tl, w.y);
129        float3 x2 = lerp(br, tr, w.y);
130        float3 v  = lerp(x1, x2, w.x);
131
132        return v;
133}
134
135
136pixel main_shadow(fragment IN,
137                                  uniform sampler2D colors,
138                                  uniform sampler2D positions,
139                                  uniform sampler2D normals,               
140                                  uniform sampler2D shadowMap,
141                                  uniform float4x4 shadowMatrix,
142                                  uniform float sampleWidth,
143                                  uniform sampler2D noiseTex,
144                                  uniform float2 samples[NUM_PCF_TABS],
145                                  uniform float weights[NUM_PCF_TABS],
146                                  uniform float3 lightDir,
147                                  uniform float3 eyePos,
148                                  uniform float3 bl,
149                                  uniform float3 br,
150                                  uniform float3 tl,
151                                  uniform float3 tr
152                                  )
153{
154        pixel OUT;
155
156        float4 norm = tex2D(normals, IN.texCoord.xy);
157        const float3 normal = normalize(norm.xyz);
158
159        float4 color = tex2Dlod(colors, float4(IN.texCoord, 0, 0));
160
161        /// reconstruct position from the eye space depth
162        float3 viewDir = IN.view;
163        const float lenView = length(viewDir);
164        viewDir /= lenView;
165
166        const float eyeDepth = tex2Dlod(colors, float4(IN.texCoord, 0, 0)).w;
167
168        const float4 worldPos = float4(eyePos - viewDir * eyeDepth, 1);
169       
170        // diffuse intensity
171        const float angle = saturate(dot(normal, lightDir));
172        const float4 lightDiffuse = glstate.light[0].diffuse;
173       
174        float4 diffuse = lightDiffuse * angle;
175
176        // hack: prevent shadowing the sky     
177        const bool useShading = (color.w < 1e19f);
178
179        // calc diffuse illumination + shadow term
180        if (useShading &&
181                (angle > 1e-3f) // shadow only if diffuse color has some minimum intensity
182                )
183        {
184                float4 lightSpacePos = mul(shadowMatrix, worldPos);
185                lightSpacePos /= lightSpacePos.w;
186
187                float shadowTerm = CalcShadowTerm(IN, shadowMap, sampleWidth, lightSpacePos.xy, lightSpacePos.z, samples, weights, noiseTex);
188       
189                diffuse *= shadowTerm;
190        }
191
192        // light ambient term
193        const float4 ambient = glstate.light[0].ambient;
194        // compute shading
195        OUT.color = useShading ? (ambient + diffuse) * color : color;
196        // store scaled view vector from now on so wie don't have to normalize later (e.g., for ssao)
197        //OUT.color.w = color.w / lenView;
198
199        return OUT;
200}
201
202
203float4 Output(fragment IN, uniform sampler2D colors): COLOR
204{   
205        return tex2Dlod(colors, float4(IN.texCoord, 0, 0));
206}
207
208
209float4 ScaleDepth(fragment IN,
210                                  uniform sampler2D colors): COLOR
211{   
212        float4 color = tex2Dlod(colors, float4(IN.texCoord, 0, 0));
213        // store scaled view vector so wie don't have to normalize for e.g., ssao
214        color.w /= length(IN.view);
215       
216        return color;
217}
218
219
220
221inline float SqrLen(float3 v)
222{
223        return v.x * v.x + v.y * v.y + v.z * v.z;
224}
225
226
227
228/** This shader computes the reprojection and checks
229        if the reprojected pixel from last frame is still
230        valid in the current frame
231        */
232inline float PixelValid(sampler2D diffVals,
233                                                sampler2D oldTex,
234                                                float4 color,
235                                                float2 texCoord,
236                                                float3 viewDir,
237                                                float3 oldEyePos,
238                                                float4x4 modelViewProj,
239                                                float4x4 oldModelViewProj,
240                                                float3 oldbl,
241                                                float3 oldbr,
242                                                float3 oldtl,
243                                                float3 oldtr
244                                                )
245{
246        // reconstruct position from the eye space depth
247        const float eyeSpaceDepth = color.w;
248        const float4 worldPos = float4(-viewDir * eyeSpaceDepth, 1.0f);
249
250        float3 diffVec = tex2Dlod(diffVals, float4(texCoord, 0, 0)).xyz;
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 <= 1e-2))
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
310float4 PrepareSsao(fragment IN,
311                                   uniform sampler2D colorsTex,
312                                   uniform sampler2D oldTex,
313                                   uniform float4x4 modelViewProj,
314                                   uniform float4x4 oldModelViewProj,
315                                   uniform float3 oldbl,
316                                   uniform float3 oldbr,
317                                   uniform float3 oldtl,
318                                   uniform float3 oldtr,
319                                   uniform float3 oldEyePos,
320                                   uniform sampler2D diffVals
321                                   ): COLOR
322{   
323        //const float3 normal = normalize(tex2Dlod(normals, float4(IN.texCoord, 0 ,0)).xyz);
324        const float3 viewDir = IN.view;
325        float4 color = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0));
326
327        // store scaled view vector so wie don't have to normalize for e.g., ssao
328        color.w /= length(IN.view);
329        //color.w = 1;
330
331        // do reprojection and filter out the pixels that are not save
332        float pValid = PixelValid(diffVals,
333                oldTex,
334                color,
335                IN.texCoord,
336                viewDir,
337                oldEyePos,
338                modelViewProj,
339                oldModelViewProj,
340                oldbl, oldbr, oldtl, oldtr
341                );
342
343        color.x = pValid;
344        return color;
345}
346
347
348float4 DownSample(fragment IN,
349                                  uniform sampler2D colors,
350                                  uniform float2 downSampleOffs[NUM_DOWNSAMPLES]): COLOR
351{   
352        // let bilinear filtering do its work
353        float4 color = tex2Dlod(colors, float4(IN.texCoord, 0, 0));
354        return color;
355}
Note: See TracBrowser for help on using the repository browser.