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

Revision 3136, 7.5 KB checked in by mattausch, 16 years ago (diff)

fixed antialiasing, but ssao not working at that point (depth)

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        //OUT.color.xyz = normal * 0.5f + 0.5f;
75        // store scaled view vector so wie don't have to normalize for e.g., ssao
76        OUT.color.w = color.w;// / length(IN.view);
77       
78        return OUT;
79}
80
81
82float CalcShadowTerm(fragment IN,
83                                         uniform sampler2D shadowMap,
84                                         uniform float scale,
85                                         uniform float2 lightSpacePos,
86                                         uniform float depth,
87                                         uniform float2 samples[NUM_PCF_TABS],
88                                         uniform float weights[NUM_PCF_TABS],
89                                         uniform sampler2D noiseTexture
90                                         )
91{
92        //float shadowDepth = tex2D(shadowMap, lightSpacePos).x;
93        //return step(depth, shadowDepth);
94
95        float total_d = .0f;
96        float total_w = .0f;
97
98        for (int i = 0; i < NUM_PCF_TABS; ++ i)
99        {
100                const float2 offset = samples[i];
101                const float w = weights[i];
102
103#if 1
104                ////////////////////
105                //-- add random noise: reflect around random normal vector (warning: slow!)
106
107                float2 mynoise = tex2D(noiseTexture, IN.texCoord).xy;
108                const float2 offsetTransformed = myreflect(offset, mynoise);
109#else
110                const float2 offsetTransformed = offset;
111#endif
112                // weight with projected coordinate to reach similar kernel size for near and far
113                float2 texcoord = lightSpacePos + offsetTransformed * scale;
114
115                float shadowDepth = tex2D(shadowMap, texcoord).x;
116
117                total_d += w * step(depth, shadowDepth);
118                total_w += w;
119        }
120
121        total_d /= (float)total_w;
122
123        return total_d;
124}
125
126
127inline float3 Interpol(float2 w, float3 bl, float3 br, float3 tl, float3 tr)
128{
129        float3 x1 = lerp(bl, tl, w.y);
130        float3 x2 = lerp(br, tr, w.y);
131        float3 v  = lerp(x1, x2, w.x);
132
133        return v;
134}
135
136
137pixel main_shadow(fragment IN,
138                                  uniform sampler2D colors,
139                                  uniform sampler2D positions,
140                                  uniform sampler2D normals,               
141                                  uniform sampler2D shadowMap,
142                                  uniform float4x4 shadowMatrix,
143                                  uniform float sampleWidth,
144                                  uniform sampler2D noiseTex,
145                                  uniform float2 samples[NUM_PCF_TABS],
146                                  uniform float weights[NUM_PCF_TABS],
147                                  uniform float3 lightDir,
148                                  uniform float3 eyePos,
149                                  uniform float3 bl,
150                                  uniform float3 br,
151                                  uniform float3 tl,
152                                  uniform float3 tr
153                                  )
154{
155        pixel OUT;
156
157        float4 norm = tex2D(normals, IN.texCoord.xy);
158        const float3 normal = normalize(norm.xyz);
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#if 0
204/** This shader computes the reprojection and stores reprojected color / depth values
205        as well as a boolean that
206*/
207pixel Reproject(fragment IN,
208                                uniform sampler2D colors,
209                                uniform sampler2D normals)
210{
211        float4 norm = tex2Dlod(normals, float4(IN.texCoord, 0 ,0));
212        const float3 normal = normalize(norm.xyz);
213
214        /// reconstruct position from the eye space depth
215        float3 viewDir = IN.view;
216        const float eyeDepth = tex2Dlod(colors, float4(IN.texCoord, 0, 0)).w;
217        const float3 eyeSpacePos = -viewDir * eyeDepth;
218        const float4 worldPos = float4(eyePos + eyeSpacePos, 1.0f);
219
220
221        ////////////////
222        //-- calculcate the current projected posiion (also used for next frame)
223       
224        float4 currentPos = mul(modelViewProj, worldPos);
225       
226        const float w = SAMPLE_RADIUS / currentPos.w;
227        currentPos /= currentPos.w;
228       
229        const float precisionScale = 1e-3f;
230        const float currentDepth = currentPos.z * precisionScale;
231
232        const float2 ao = ssao(IN, colors, noiseTex, samples, normal,
233                                   eyeSpacePos, w, bl, br, tl, tr, normalize(viewDir));
234
235
236        /////////////////
237        //-- compute temporally smoothing
238
239
240        // reproject new frame into old one
241       
242        // calculate projected depth
243        float4 projPos = mul(oldModelViewProj, worldPos);
244        projPos /= projPos.w;
245       
246        // the current depth projected into the old frame
247        const float projDepth = projPos.z * precisionScale;
248        // fit from unit cube into 0 .. 1
249        const float2 tex = projPos.xy * 0.5f + 0.5f;
250        // retrieve the sample from the last frame
251        float4 oldCol = tex2D(oldTex, tex);
252
253        const float oldDepth = oldCol.z;
254        //const float depthDif = 1.0f - projDepth / oldDepth;
255        const float depthDif = projDepth - oldDepth;
256
257        //const float oldNumSamples = oldCol.y;
258        const float oldWeight = clamp(oldCol.y, 0, temporalCoherence);
259
260        float newWeight;
261
262        // the number of valid samples in this frame
263        //const float newNumSamples = ao.y;
264
265        if ((temporalCoherence > 0)
266                && (tex.x >= 0.0f) && (tex.x < 1.0f)
267                && (tex.y >= 0.0f) && (tex.y < 1.0f)
268                && (abs(depthDif) < MIN_DEPTH_DIFF)
269                && (abs(oldCol.x - ao.x) < 0.1f)
270                // if visibility changed in the surrounding area we have to recompute
271                //&& (oldNumSamples > 0.8f * newNumSamples)
272                )
273        {
274                // increase the weight for convergence
275                newWeight = oldWeight + 1.0f;
276                OUT.illum_col.x = (ao.x + oldCol.x * oldWeight) / newWeight;
277                //if (!(oldNumSamples > ao.y - 1.5f)) newWeight = 0;
278        }
279        else
280        {       
281                OUT.illum_col.x = ao.x;
282                newWeight = .0f;
283        }
284
285        OUT.illum_col.y = newWeight;
286        OUT.illum_col.z = currentDepth;
287
288        return OUT;
289}
290
291#endif
292
293
294float4 Output(fragment IN, uniform sampler2D colors): COLOR
295{   
296        // let bilinear filtering do its work
297        return tex2Dlod(colors, float4(IN.texCoord, 0, 0));
298}
Note: See TracBrowser for help on using the repository browser.