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

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