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

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

fast and cool
not using kernel for high convergence

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,
[3212]67                                   uniform float3 tr,
68                                   float3 viewDir,
69                                   float sampleIntensity
[2990]70                                   )
[2882]71{
[2904]72        GiStruct gi;
73
[2882]74        // Check in a circular area around the current position.
75        // Shoot vectors to the positions there, and check the angle to these positions.
76        // Summing up these angles gives an estimation of the occlusion at the current position.
77
78        // ao is in stored in the w component
[2904]79        float3 total_color = float3(0, 0, 0);
80        float total_ao = 0.0f;
81        float numSamples = 0.0f;
[2882]82
83        ////////////
84        //-- the main sampling loop
85
86        for (int i = 0; i < NUM_SAMPLES; i ++)
87        {
[3019]88                const float2 offset = samples[i];
[2882]89
[2903]90#if 1
91                ////////////////////
[3084]92                // add random noiseTex: reflect around random normal vector (warning: slow!)
[2903]93                float2 mynoise = tex2D(noiseTexture, IN.texCoord.xy).xy;
[2892]94                float2 offsetTransformed = myreflect(offset, mynoise);
[2903]95#else
96                float2 offsetTransformed = offset;
97#endif
[2882]98                // weight with projected coordinate to reach similar kernel size for near and far
[3026]99                float2 texcoord = IN.texCoord.xy + offsetTransformed * scaleFactor;
[2882]100
[2999]101                //if ((texcoord.x <= 1.0f) && (texcoord.x >= 0.0f) && (texcoord.y <= 1.0f) && (texcoord.y >= 0.0f)) ++ numSamples;
[2904]102
[3010]103
[3006]104                //////////
105                //-- reconstruct world space position from sample
106
[3103]107                const float4 sample = tex2Dlod(colors, float4(texcoord, 0, 0));
108                //const float4 sample = tex2D(colors, texcoord);
[3014]109
[2990]110                const float eyeSpaceDepth = sample.w;
[2999]111                float3 rotView = Interpol(texcoord, bl, br, tl, tr);
[2990]112               
[3019]113                const float3 samplePos = - rotView * eyeSpaceDepth;
114                const float3 sampleCol = sample.xyz;
[2990]115
[3017]116                // distance between current position and sample position controls AO intensity.
117
[3019]118                float3 dirSample = samplePos - centerPosition.xyz;
119                const float magSample = length(dirSample);
120                // normalize
121                dirSample /= magSample;
[2882]122
[3006]123                // use angle between current normal and direction to sample controls AO intensity.
[3019]124                float cosAngle = max(dot(dirSample, currentNormal), 0);
[2882]125
[3019]126                const float denom = (DISTANCE_SCALE + magSample * magSample);
[2882]127
[3212]128                float2 intensity = float2(sampleIntensity, ILLUM_INTENSITY);
[3019]129                intensity /= denom;
[3016]130
[3017]131                // if normal perpenticular to view dir, only the samples approx count half
132#if 1
[3019]133                const float viewCorrect = 1.0f + VIEW_CORRECTION_SCALE * dot(viewDir, currentNormal);
[3017]134       
[3019]135                total_ao += cosAngle * intensity.x * viewCorrect;
136                total_color += cosAngle * intensity.y * sampleCol * viewCorrect;
[3017]137#else
[3019]138                total_ao += cos_angle * intensity.x;
139                total_color += cos_angle * intensity.y * sampleCol;
[3017]140#endif
[2882]141        }
142
[2975]143        gi.illum = total_color;
[2904]144        gi.ao = float2(max(0.0f, 1.0f - total_ao), numSamples);
145
146        return gi;
[2882]147}
148
149
[3000]150
[2882]151pixel2 main(fragment IN,
152                   uniform sampler2D colors,
153                   uniform sampler2D normals,
[3084]154                   uniform sampler2D noiseTex,
[2882]155                   uniform float2 samples[NUM_SAMPLES],
156                   uniform sampler2D oldSsaoTex,
157                   uniform sampler2D oldIllumTex,
158                   const uniform float4x4 oldModelViewProj,
[3006]159                   const uniform float4x4 modelViewProj,
[2990]160                   uniform float temporalCoherence,
161                   uniform float3 bl,
162                   uniform float3 br,
163                   uniform float3 tl,
[3212]164                   uniform float3 tr,
165                   uniform float kernelRadius,
166                   uniform float sampleIntensity
[2882]167                   )
168{
169        pixel2 OUT;
170
[3212]171        const float3 normal = tex2Dlod(normals, float4(IN.texCoord, 0 ,0)).xyz;
[2882]172
[3017]173       
[3006]174        /////////////
175        //-- reconstruct position from the eye space depth
176
[3009]177        float3 viewDir = IN.view;
[3016]178        const float eyeDepth = tex2Dlod(colors, float4(IN.texCoord, 0, 0)).w;
[3000]179       
[3094]180        const float4 eyeSpacePos = float4(-viewDir * eyeDepth, 1.0f);
[3014]181
[3017]182        // calculcate the current projected depth for next frame
[3094]183        float4 currentPos = mul(modelViewProj, eyeSpacePos);
[3034]184
[3212]185        const float w = kernelRadius / currentPos.w;
[3017]186        currentPos /= currentPos.w;
[3034]187       
[3230]188        const float currentDepth = currentPos.z;
[3003]189
[3006]190        ///////////
191        //-- compute color bleeding + ao
[2882]192
[3212]193        GiStruct gi = globIllum(IN, colors, noiseTex, samples, normal, eyeSpacePos, w, bl, br, tl, tr, normalize(IN.view), sampleIntensity);
[2882]194       
195
196        /////////////////
197        //-- compute temporally smoothing
198
[3017]199        // reprojection new frame into old one
[3006]200        // calculate projected depth
[3094]201        float4 projPos = mul(oldModelViewProj, eyeSpacePos);
[3006]202        projPos /= projPos.w;
[2882]203
[3006]204        // the current depth projected into the old frame
[3230]205        const float projDepth = projPos.z;
[3006]206
207        // fit from unit cube into 0 .. 1
[3017]208        float2 tex = projPos.xy * 0.5f + 0.5f;
[3006]209
210        // retrieve the sample from the last frame
[3034]211        float3 oldSsao = tex2D(oldSsaoTex, tex).xyz;
212        float3 oldIllum = tex2D(oldIllumTex, tex).xyz;
[2882]213
[3017]214        const float oldDepth = oldSsao.z;
215        //const float depthDif = 1.0f - projDepth / oldDepth;
216        const float depthDif = projDepth - oldDepth;
[2882]217
[3019]218        // the weights that indicate the state of convergence
219        const float oldWeight = clamp(oldSsao.y, .0f, temporalCoherence);
[2897]220        float newWeight;
[2882]221
[3006]222        //const float oldNumSamples = oldSsao.y;
[3017]223       
[3084]224        if ((temporalCoherence > 1e-6f) &&
[2897]225                (tex.x >= 0.0f) && (tex.x < 1.0f) &&
[2882]226                (tex.y >= 0.0f) && (tex.y < 1.0f) &&
[3009]227                (abs(depthDif) < MIN_DEPTH_DIFF)
[2975]228                // check if something changed in the surrounding area
[2999]229                //&& (oldNumSamples > 0.2 * gi.ao.y)
[2904]230                )
[2882]231        {
[2897]232                newWeight = oldWeight + 1;
233
[3019]234                float4 tmp = float4(gi.ao.x, gi.illum);
235                float4 oldTmp = float4(oldSsao.x, oldIllum);
236
237                float4 interpol = (tmp + oldTmp * oldWeight) / newWeight;
238
239                OUT.ssao_col.x = interpol.x;
240                OUT.illum_col.xyz = interpol.yzw;
[2882]241        }
242        else
243        {
[2897]244                newWeight = 0;
245
[3017]246                OUT.ssao_col.x = gi.ao.x;
[2904]247                OUT.illum_col.xyz = gi.illum;
[2882]248        }
249
[3017]250        OUT.ssao_col.y = newWeight;
251        OUT.ssao_col.z = currentDepth;
[2882]252
253        return OUT;
254}
255
256
[2880]257pixel combine(fragment IN,
[3104]258                          uniform sampler2D colorsTex,
[2880]259                          uniform sampler2D ssaoTex,
260                          uniform sampler2D illumTex
[2975]261                          )
[2880]262{
263        pixel OUT;
264
[3104]265        float4 col = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0));
[3019]266        float ao = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0)).x;
[3016]267
[3019]268        float3 illum = tex2Dlod(illumTex, float4(IN.texCoord, 0, 0)).xyz;
269
270        OUT.illum_col.xyz = (col.xyz + illum) * ao;
271        //OUT.illum_col.xyz = col.xyz * ao;
272
[2884]273        OUT.illum_col.w = col.w;
[2880]274
275        return OUT;
276}
Note: See TracBrowser for help on using the repository browser.