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

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

updated shader programs

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                ////////////////////
[3084]91                // add random noiseTex: reflect around random normal vector (warning: slow!)
[2903]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
[3103]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,
[3084]153                   uniform sampler2D noiseTex,
[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 bl,
161                   uniform float3 br,
162                   uniform float3 tl,
163                   uniform float3 tr
[2882]164                   )
165{
166        pixel2 OUT;
167
[3016]168        float4 norm = tex2Dlod(normals, float4(IN.texCoord, 0 ,0));
[2975]169        float3 normal = normalize(norm.xyz);   
[2882]170
[3017]171       
[3006]172        /////////////
173        //-- reconstruct position from the eye space depth
174
[3009]175        float3 viewDir = IN.view;
[3016]176        const float eyeDepth = tex2Dlod(colors, float4(IN.texCoord, 0, 0)).w;
[3000]177       
[3094]178        const float4 eyeSpacePos = float4(-viewDir * eyeDepth, 1.0f);
[3014]179
[3017]180        // calculcate the current projected depth for next frame
[3094]181        float4 currentPos = mul(modelViewProj, eyeSpacePos);
[3034]182
[3017]183        const float w = SAMPLE_RADIUS / currentPos.w;
184        currentPos /= currentPos.w;
[3034]185       
[3084]186        const float currentDepth = currentPos.z * PRECISION_SCALE;
[3003]187
[3006]188        ///////////
189        //-- compute color bleeding + ao
[2882]190
[3084]191        GiStruct gi = globIllum(IN, colors, noiseTex, samples, normal, eyeSpacePos, w, bl, br, tl, tr, normalize(IN.view));
[2882]192       
193
194        /////////////////
195        //-- compute temporally smoothing
196
[3017]197        // reprojection new frame into old one
[3006]198        // calculate projected depth
[3094]199        float4 projPos = mul(oldModelViewProj, eyeSpacePos);
[3006]200        projPos /= projPos.w;
[2882]201
[3006]202        // the current depth projected into the old frame
[3084]203        const float projDepth = projPos.z * PRECISION_SCALE;
[3006]204
205        // fit from unit cube into 0 .. 1
[3017]206        float2 tex = projPos.xy * 0.5f + 0.5f;
[3006]207
208        // retrieve the sample from the last frame
[3034]209        float3 oldSsao = tex2D(oldSsaoTex, tex).xyz;
210        float3 oldIllum = tex2D(oldIllumTex, tex).xyz;
[2882]211
[3017]212        const float oldDepth = oldSsao.z;
213        //const float depthDif = 1.0f - projDepth / oldDepth;
214        const float depthDif = projDepth - oldDepth;
[2882]215
[3019]216        // the weights that indicate the state of convergence
217        const float oldWeight = clamp(oldSsao.y, .0f, temporalCoherence);
[2897]218        float newWeight;
[2882]219
[3006]220        //const float oldNumSamples = oldSsao.y;
[3017]221       
[3084]222        if ((temporalCoherence > 1e-6f) &&
[2897]223                (tex.x >= 0.0f) && (tex.x < 1.0f) &&
[2882]224                (tex.y >= 0.0f) && (tex.y < 1.0f) &&
[3009]225                (abs(depthDif) < MIN_DEPTH_DIFF)
[2975]226                // check if something changed in the surrounding area
[2999]227                //&& (oldNumSamples > 0.2 * gi.ao.y)
[2904]228                )
[2882]229        {
[2897]230                newWeight = oldWeight + 1;
231
[3019]232                float4 tmp = float4(gi.ao.x, gi.illum);
233                float4 oldTmp = float4(oldSsao.x, oldIllum);
234
235                float4 interpol = (tmp + oldTmp * oldWeight) / newWeight;
236
237                OUT.ssao_col.x = interpol.x;
238                OUT.illum_col.xyz = interpol.yzw;
[2882]239        }
240        else
241        {
[2897]242                newWeight = 0;
243
[3017]244                OUT.ssao_col.x = gi.ao.x;
[2904]245                OUT.illum_col.xyz = gi.illum;
[2882]246        }
247
[3017]248        OUT.ssao_col.y = newWeight;
249        OUT.ssao_col.z = currentDepth;
[2882]250
251        return OUT;
252}
253
254
[2880]255pixel combine(fragment IN,
[3104]256                          uniform sampler2D colorsTex,
[2880]257                          uniform sampler2D ssaoTex,
258                          uniform sampler2D illumTex
[2975]259                          )
[2880]260{
261        pixel OUT;
262
[3104]263        float4 col = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0));
[3019]264        float ao = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0)).x;
[3016]265
[3019]266        float3 illum = tex2Dlod(illumTex, float4(IN.texCoord, 0, 0)).xyz;
267
268        OUT.illum_col.xyz = (col.xyz + illum) * ao;
269        //OUT.illum_col.xyz = col.xyz * ao;
270
[2884]271        OUT.illum_col.w = col.w;
[2880]272
273        return OUT;
274}
Note: See TracBrowser for help on using the repository browser.