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

Revision 3001, 7.0 KB checked in by mattausch, 16 years ago (diff)

reverted back from trying to use less components in fbo for faster sampling

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 float4 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                // reconstruct world space position from sample
106                float4 sample = tex2Dlod(colors, float4(texcoord, 0, SSAO_MIPMAP_LEVEL));
107                const float eyeSpaceDepth = sample.w;
108                //float3 rotView = normalize(Interpol(texcoord, bl, br, tl, tr));
109                float3 rotView = Interpol(texcoord, bl, br, tl, tr);
110               
111               
112                const float3 sample_position = eyePos - rotView * eyeSpaceDepth;
113                const float3 sample_color = sample.xyz;
114
115                float3 vector_to_sample = sample_position - centerPosition.xyz;
116                const float length_to_sample = length(vector_to_sample);
117
118                float3 direction_to_sample = vector_to_sample / length_to_sample;
119
120                // Angle between current normal and direction to sample controls AO intensity.
121                float cos_angle = max(dot(direction_to_sample, currentNormal), 0);
122
123                // distance between current position and sample position controls AO intensity.
124                const float distance_intensity =
125                        (SAMPLE_INTENSITY * DISTANCE_SCALE) / (DISTANCE_SCALE + length_to_sample * length_to_sample);
126
127                // if normal perpenticular to view dir, only half of the samples count
128#if 0
129                const float view_correction = 1.0f + VIEW_CORRECTION_SCALE * (1.0f - dot(currentViewDir, currentNormal));
130                total_color.w -= cos_angle * distance_intensity * view_correction;
131                total_color.xyz += cos_angle * distance_intensity * view_correction * sample_color * ILLUM_INTENSITY;
132#endif
133                total_ao += cos_angle * distance_intensity;
134                total_color += cos_angle * distance_intensity * sample_color * ILLUM_INTENSITY;
135        }
136
137        gi.illum = total_color;
138        gi.ao = float2(max(0.0f, 1.0f - total_ao), numSamples);
139
140        //return saturate(total_color);
141        return gi;
142}
143
144
145
146pixel2 main(fragment IN,
147                   uniform sampler2D colors,
148                   uniform sampler2D positions,
149                   uniform sampler2D normals,
150                   uniform sampler2D noiseTexture,
151                   uniform float2 samples[NUM_SAMPLES],
152                   uniform sampler2D oldSsaoTex,
153                   uniform sampler2D oldIllumTex,
154                   const uniform float4x4 oldModelViewProj,
155                   uniform float maxDepth,
156                   uniform float temporalCoherence,
157                   uniform float3 eyePos,
158                   uniform float3 bl,
159                   uniform float3 br,
160                   uniform float3 tl,
161                   uniform float3 tr
162                   )
163{
164        pixel2 OUT;
165
166        float4 norm = tex2D(normals, IN.texCoord.xy);
167        float3 normal = normalize(norm.xyz);   
168        // something like a constant ambient term
169        const float amb = norm.w;
170       
171        /// the current view direction
172        //float3 viewDir = normalize(IN.view);
173
174        // the w coordinate from the persp. projection
175        float w = norm.w;
176        // the current world position
177        const float4 centerPosition = tex2D(positions, IN.texCoord.xy);
178
179        /// reconstruct position from the eye space depth
180        /*float3 viewDir = normalize(IN.view);
181        const float eyeDepth = tex2D(colors, IN.texCoord.xy).w;
182       
183        float4 centerPosition;
184        centerPosition.xyz = eyePos - viewDir * eyeDepth;
185
186        centerPosition.w = centerPosition2.w;
187*/
188        // the current color
189        const float4 currentCol = tex2Dlod(colors, float4(IN.texCoord.xy, 0, 0));
190        // the current depth is stored in the w component
191        const float currentDepth = centerPosition.w;
192
193        GiStruct gi = globIllum(IN, colors, noiseTexture, samples, normal, centerPosition, w, eyePos, bl, br, tl, tr);
194       
195
196        /////////////////
197        //-- compute temporally smoothing
198
199        float4 realPos = centerPosition * maxDepth;
200        realPos.w = 1.0f;
201
202        float4 oldPos = mul(oldModelViewProj, realPos);
203
204        const float newDepth = oldPos.z / oldPos.w;
205
206        float2 tex = (oldPos.xy / oldPos.w) * 0.5f + 0.5f;
207
208        float4 oldSsao = tex2D(oldSsaoTex, tex);
209        float4 oldIllum = tex2D(oldIllumTex, tex);
210
211        const float oldDepth = oldSsao.w;
212        const float depthDif = 1.0f - newDepth / oldDepth;
213
214        float oldWeight = clamp(oldSsao.z, 0, temporalCoherence);
215        float newWeight;
216
217        const float oldNumSamples = oldSsao.y;
218        const float oldAvgDepth = oldSsao.z;
219
220        if (//(temporalCoherence > 0.0f) &&
221                (tex.x >= 0.0f) && (tex.x < 1.0f) &&
222                (tex.y >= 0.0f) && (tex.y < 1.0f) &&
223                (abs(depthDif) < 1e-3f)
224                // check if something changed in the surrounding area
225                //&& (oldNumSamples > 0.2 * gi.ao.y)
226                )
227        {
228                newWeight = oldWeight + 1;
229
230                OUT.ssao_col.xy = (gi.ao + oldSsao.xy * oldWeight) / newWeight;
231                OUT.illum_col.xyz  = (gi.illum + oldIllum.xyz * oldWeight) / newWeight;
232        }
233        else
234        {
235                newWeight = 0;
236
237                OUT.ssao_col.xy = gi.ao.xy;
238                OUT.illum_col.xyz = gi.illum;
239        }
240
241        OUT.ssao_col.z = newWeight;
242        OUT.ssao_col.w = currentDepth;
243
244        return OUT;
245}
246
247
248pixel combine(fragment IN,
249                          uniform sampler2D colors,
250                          uniform sampler2D ssaoTex,
251                          uniform sampler2D illumTex
252                          )
253{
254        pixel OUT;
255
256        float4 col = tex2D(colors, IN.texCoord.xy);
257        float ao = tex2D(ssaoTex, IN.texCoord.xy).x;
258        float4 illum = tex2D(illumTex, IN.texCoord.xy);
259       
260        OUT.illum_col = (col + illum) * ao;
261        OUT.illum_col.w = col.w;
262
263        return OUT;
264}
Note: See TracBrowser for help on using the repository browser.