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

Revision 3345, 10.3 KB checked in by mattausch, 15 years ago (diff)

trying to reduce render targets but something srange

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