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

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

updated shader programs

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                //float shadowTerm = CalcShadowTerm(IN, shadowMap, sampleWidth, lightSpacePos.xy, lightSpacePos.z, samples, noiseTex);
190
191                diffuse *= shadowTerm;
192        }
193
194        // light ambient term
195        const float4 ambient = glstate.light[0].ambient;
196        // compute shading
197        OUT.color = useShading ? (ambient + diffuse) * color : color;
198        // store scaled view vector from now on so wie don't have to normalize later (e.g., for ssao)
199        OUT.color.w = color.w / lenView;
200
201        return OUT;
202}
203
204#if 0
205/** This shader computes the reprojection and stores reprojected color / depth values
206        as well as a boolean that
207*/
208pixel Reproject(fragment IN,
209                                uniform sampler2D colors,
210                                uniform sampler2D normals)
211{
212        float4 norm = tex2Dlod(normals, float4(IN.texCoord, 0 ,0));
213        const float3 normal = normalize(norm.xyz);
214
215        /// reconstruct position from the eye space depth
216        float3 viewDir = IN.view;
217        const float eyeDepth = tex2Dlod(colors, float4(IN.texCoord, 0, 0)).w;
218        const float3 eyeSpacePos = -viewDir * eyeDepth;
219        const float4 worldPos = float4(eyePos + eyeSpacePos, 1.0f);
220
221
222        ////////////////
223        //-- calculcate the current projected posiion (also used for next frame)
224       
225        float4 currentPos = mul(modelViewProj, worldPos);
226       
227        const float w = SAMPLE_RADIUS / currentPos.w;
228        currentPos /= currentPos.w;
229       
230        const float precisionScale = 1e-3f;
231        const float currentDepth = currentPos.z * precisionScale;
232
233        const float2 ao = ssao(IN, colors, noiseTex, samples, normal,
234                                   eyeSpacePos, w, bl, br, tl, tr, normalize(viewDir));
235
236
237        /////////////////
238        //-- compute temporally smoothing
239
240
241        // reproject new frame into old one
242       
243        // calculate projected depth
244        float4 projPos = mul(oldModelViewProj, worldPos);
245        projPos /= projPos.w;
246       
247        // the current depth projected into the old frame
248        const float projDepth = projPos.z * precisionScale;
249        // fit from unit cube into 0 .. 1
250        const float2 tex = projPos.xy * 0.5f + 0.5f;
251        // retrieve the sample from the last frame
252        float4 oldCol = tex2D(oldTex, tex);
253
254        const float oldDepth = oldCol.z;
255        //const float depthDif = 1.0f - projDepth / oldDepth;
256        const float depthDif = projDepth - oldDepth;
257
258        //const float oldNumSamples = oldCol.y;
259        const float oldWeight = clamp(oldCol.y, 0, temporalCoherence);
260
261        float newWeight;
262
263        // the number of valid samples in this frame
264        //const float newNumSamples = ao.y;
265
266        if ((temporalCoherence > 0)
267                && (tex.x >= 0.0f) && (tex.x < 1.0f)
268                && (tex.y >= 0.0f) && (tex.y < 1.0f)
269                && (abs(depthDif) < MIN_DEPTH_DIFF)
270                && (abs(oldCol.x - ao.x) < 0.1f)
271                // if visibility changed in the surrounding area we have to recompute
272                //&& (oldNumSamples > 0.8f * newNumSamples)
273                )
274        {
275                // increase the weight for convergence
276                newWeight = oldWeight + 1.0f;
277                OUT.illum_col.x = (ao.x + oldCol.x * oldWeight) / newWeight;
278                //if (!(oldNumSamples > ao.y - 1.5f)) newWeight = 0;
279        }
280        else
281        {       
282                OUT.illum_col.x = ao.x;
283                newWeight = .0f;
284        }
285
286        OUT.illum_col.y = newWeight;
287        OUT.illum_col.z = currentDepth;
288
289        return OUT;
290}
291
292#endif
Note: See TracBrowser for help on using the repository browser.