source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/globillum.cg @ 3006

Revision 3006, 7.2 KB checked in by mattausch, 16 years ago (diff)

tried downsampling

Line 
1////////////////////
2// SSAO + color bleeding shader
3// based on shader of Alexander Kusternig
4
5#include "../shaderenv.h"
6
7
8struct fragment
9{
10         // normalized screen position
11        float4 pos: WPOS;
12        float4 texCoord: TEXCOORD0;
13        float3 view: COLOR0;
14};
15
16
17struct pixel2
18{
19        float4 ssao_col: COLOR0;
20        float4 illum_col: COLOR1;
21};
22
23
24struct pixel
25{
26        float4 illum_col: COLOR0;
27};
28
29
30float2 myreflect(float2 pt, float2 n)
31{
32        // distance to plane
33        float d = dot(n, pt);
34        // reflect around plane
35        float2 rpt = pt - d * 2.0f * n;
36        return rpt;
37}
38
39struct GiStruct
40{
41        float3 illum;
42        float2 ao;
43};
44
45
46
47inline float3 Interpol(float2 w, float3 bl, float3 br, float3 tl, float3 tr)
48{
49        float3 x1 = lerp(bl, tl, w.y);
50        float3 x2 = lerp(br, tr, w.y);
51        float3 v = lerp(x1, x2, w.x);
52
53        return v;
54}
55
56
57/** Computes  diffuse reflections + ambient occlusion
58*/
59GiStruct globIllum(fragment IN,
60                                   uniform sampler2D colors,
61                                   uniform sampler2D noiseTexture,
62                                   uniform float2 samples[NUM_SAMPLES],
63                                   uniform float3 currentNormal,
64                                   uniform float3 centerPosition,
65                                   float w,
66                                   uniform float3 eyePos,
67                                   uniform float3 bl,
68                                   uniform float3 br,
69                                   uniform float3 tl,
70                                   uniform float3 tr
71                                   //, uniform float3 viewDir
72                                   )
73{
74        GiStruct gi;
75
76        // Check in a circular area around the current position.
77        // Shoot vectors to the positions there, and check the angle to these positions.
78        // Summing up these angles gives an estimation of the occlusion at the current position.
79
80        // ao is in stored in the w component
81        float3 total_color = float3(0, 0, 0);
82        float total_ao = 0.0f;
83        float numSamples = 0.0f;
84
85        ////////////
86        //-- the main sampling loop
87
88        for (int i = 0; i < NUM_SAMPLES; i ++)
89        {
90                float2 offset = samples[i];
91
92#if 1
93                ////////////////////
94                // add random noise: reflect around random normal vector (warning: slow!)
95                float2 mynoise = tex2D(noiseTexture, IN.texCoord.xy).xy;
96                float2 offsetTransformed = myreflect(offset, mynoise);
97#else
98                float2 offsetTransformed = offset;
99#endif
100                // weight with projected coordinate to reach similar kernel size for near and far
101                float2 texcoord = IN.texCoord.xy + offsetTransformed * AREA_SIZE * w;
102
103                //if ((texcoord.x <= 1.0f) && (texcoord.x >= 0.0f) && (texcoord.y <= 1.0f) && (texcoord.y >= 0.0f)) ++ numSamples;
104
105                //////////
106                //-- reconstruct world space position from sample
107
108                float4 sample = tex2Dlod(colors, float4(texcoord, 0, SSAO_MIPMAP_LEVEL));
109                const float eyeSpaceDepth = sample.w;
110                //float3 rotView = normalize(Interpol(texcoord, bl, br, tl, tr));
111                float3 rotView = Interpol(texcoord, bl, br, tl, tr);
112               
113               
114                const float3 sample_position = eyePos - rotView * eyeSpaceDepth;
115                const float3 sample_color = sample.xyz;
116
117                float3 vector_to_sample = sample_position - centerPosition.xyz;
118                const float length_to_sample = length(vector_to_sample);
119
120                float3 direction_to_sample = vector_to_sample / length_to_sample;
121
122                // use angle between current normal and direction to sample controls AO intensity.
123                float cos_angle = max(dot(direction_to_sample, currentNormal), 0);
124
125                // distance between current position and sample position controls AO intensity.
126                const float distance_intensity =
127                        (SAMPLE_INTENSITY * DISTANCE_SCALE) / (DISTANCE_SCALE + length_to_sample * length_to_sample);
128
129                // if normal perpenticular to view dir, only half of the samples count
130#if 0
131                const float view_correction = 1.0f + VIEW_CORRECTION_SCALE * (1.0f - dot(currentViewDir, currentNormal));
132                total_color.w -= cos_angle * distance_intensity * view_correction;
133                total_color.xyz += cos_angle * distance_intensity * view_correction * sample_color * ILLUM_INTENSITY;
134#endif
135                total_ao += cos_angle * distance_intensity;
136                total_color += cos_angle * distance_intensity * sample_color * ILLUM_INTENSITY;
137        }
138
139        gi.illum = total_color;
140        gi.ao = float2(max(0.0f, 1.0f - total_ao), numSamples);
141
142        //return saturate(total_color);
143        return gi;
144}
145
146
147
148pixel2 main(fragment IN,
149                   uniform sampler2D colors,
150                   uniform sampler2D positions,
151                   uniform sampler2D normals,
152                   uniform sampler2D noiseTexture,
153                   uniform float2 samples[NUM_SAMPLES],
154                   uniform sampler2D oldSsaoTex,
155                   uniform sampler2D oldIllumTex,
156                   const uniform float4x4 oldModelViewProj,
157                   const uniform float4x4 modelViewProj,
158                   uniform float maxDepth,
159                   uniform float temporalCoherence,
160                   uniform float3 eyePos,
161                   uniform float3 bl,
162                   uniform float3 br,
163                   uniform float3 tl,
164                   uniform float3 tr
165                   )
166{
167        pixel2 OUT;
168
169        float4 norm = tex2D(normals, IN.texCoord.xy);
170        float3 normal = normalize(norm.xyz);   
171
172        // the w coordinate from the persp. projection
173        float w = norm.w;
174
175
176        /////////////
177        //-- reconstruct position from the eye space depth
178
179        float3 viewDir = Interpol(IN.texCoord.xy, bl, br, tl, tr);//IN.view;
180        const float eyeDepth = tex2Dlod(colors, float4(IN.texCoord.xy, 0, 0)).w;
181       
182        float3 centerPosition;
183        centerPosition.xyz = eyePos - viewDir * eyeDepth;
184       
185        //const float3 centerPosition = tex2D(positions, IN.texCoord.xy).xyz;
186
187
188        ///////////
189        //-- compute color bleeding + ao
190
191        GiStruct gi = globIllum(IN, colors, noiseTexture, samples, normal, centerPosition, w, eyePos, bl, br, tl, tr);
192       
193
194        /////////////////
195        //-- compute temporally smoothing
196
197        float4 realPos = float4(centerPosition * maxDepth, 1.0f);
198
199
200        // calculcate the current projected depth for next frame
201        float4 currentPos = mul(modelViewProj, realPos);
202        currentPos /= currentPos.w;
203        const float currentDepth = currentPos.z;
204       
205
206        ///////////
207        //-- reprojection new frame into old one
208       
209        // calculate projected depth
210        float4 projPos = mul(oldModelViewProj, realPos);
211        projPos /= projPos.w;
212
213        // the current depth projected into the old frame
214        const float projDepth = projPos.z;
215
216        // fit from unit cube into 0 .. 1
217        float2 tex = (projPos.xy) * 0.5f + 0.5f;
218
219        // retrieve the sample from the last frame
220        float4 oldSsao = tex2D(oldSsaoTex, tex);
221        float4 oldIllum = tex2D(oldIllumTex, tex);
222
223        const float oldDepth = oldSsao.w;
224        const float depthDif = 1.0f - projDepth / oldDepth;
225
226        float oldWeight = clamp(oldSsao.z, 0, temporalCoherence);
227
228        float newWeight;
229
230        //const float oldNumSamples = oldSsao.y;
231        //const float oldAvgDepth = oldSsao.z;
232
233        if (//(temporalCoherence > 0.0f) &&
234                (tex.x >= 0.0f) && (tex.x < 1.0f) &&
235                (tex.y >= 0.0f) && (tex.y < 1.0f) &&
236                (abs(depthDif) < 1e-3f)
237                // check if something changed in the surrounding area
238                //&& (oldNumSamples > 0.2 * gi.ao.y)
239                )
240        {
241                newWeight = oldWeight + 1;
242
243                OUT.ssao_col.xy = (gi.ao + oldSsao.xy * oldWeight) / newWeight;
244                OUT.illum_col.xyz  = (gi.illum + oldIllum.xyz * oldWeight) / newWeight;
245        }
246        else
247        {
248                newWeight = 0;
249
250                OUT.ssao_col.xy = gi.ao.xy;
251                OUT.illum_col.xyz = gi.illum;
252        }
253
254        OUT.ssao_col.z = newWeight;
255        OUT.ssao_col.w = currentDepth;
256
257        return OUT;
258}
259
260
261pixel combine(fragment IN,
262                          uniform sampler2D colors,
263                          uniform sampler2D ssaoTex,
264                          uniform sampler2D illumTex
265                          )
266{
267        pixel OUT;
268
269        float4 col = tex2D(colors, IN.texCoord.xy);
270        float ao = tex2D(ssaoTex, IN.texCoord.xy).x;
271        float4 illum = tex2D(illumTex, IN.texCoord.xy);
272       
273        OUT.illum_col = (col + illum) * ao;
274        OUT.illum_col.w = col.w;
275
276        return OUT;
277}
Note: See TracBrowser for help on using the repository browser.