source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/combineSsaoSep.cg @ 3372

Revision 3372, 8.8 KB checked in by mattausch, 15 years ago (diff)

reverted but now a good version

RevLine 
[3302]1#include "../shaderenv.h"
2#include "common.h"
3
4
[3372]5/********************************************************/
6/*         Filter for combining ssao with image         */
7/********************************************************/
[3302]8
9
10struct fragment
11{
12        float2 texCoord: TEXCOORD0;
13        float3 view: TEXCOORD1;
14};
15
16
17struct pixel
18{
19        float4 illum_col: COLOR0;
20};
21
22
[3305]23float ComputeConvergenceHalfRes(uniform sampler2D ssaoTex,
24                                                                float2 texCoord,
25                                                                float2 halfres)
26{
27    // the following has to be done for half resolution ssao:
28        // get the minimum convergence by exactly sampling the 4 surrounding
29        // texels in the old texture, otherwise flickering because convergence
30        // will be interpolated when upsampling and filter size does not match!
31
32        float4 texelCenterConv;
33        const float xoffs = .5f / halfres.x; const float yoffs = .5f / halfres.y;
34
35        // get position exactly between old texel centers
36        float2 center;
37        center.x = (floor(texCoord.x * halfres.x - .5f) + 1.0f) / halfres.x;
38        center.y = (floor(texCoord.y * halfres.y - .5f) + 1.0f) / halfres.y;
39
40        texelCenterConv.x = tex2Dlod(ssaoTex, float4(center + float2( xoffs,  yoffs), 0, 0)).y;
41        texelCenterConv.y = tex2Dlod(ssaoTex, float4(center + float2( xoffs, -yoffs), 0, 0)).y;
42        texelCenterConv.z = tex2Dlod(ssaoTex, float4(center + float2(-xoffs, -yoffs), 0, 0)).y;
43        texelCenterConv.w = tex2Dlod(ssaoTex, float4(center + float2(-xoffs,  yoffs), 0, 0)).y;
44
45        const float m1 = min(texelCenterConv.x, texelCenterConv.y);
46        const float m2 = min(texelCenterConv.z, texelCenterConv.w);
47
48        const float minConvergence = min(m1, m2);
49        return minConvergence;
50}
51
52
[3302]53float2 FilterSample(float4 sampleTexCoord,
54                                        uniform sampler2D ssaoTex,
55                                        uniform sampler2D colorsTex,
56                                        float3 centerPos,
57                                        float3 bl,
58                                        float3 br,
59                                        float3 tl,
[3316]60                                        float3 tr,
[3319]61                                        float maxConvergence,
62                                        float spatialWeight)
[3302]63{
64        float2 aoSample = tex2Dlod(ssaoTex, sampleTexCoord);
65               
66        // check spatial discontinuity
67        // note: using the depth from the color texture is not 100% correct as depth was
68        // not scaled with the interpolated view vector depth yet ...
69        float3 samplePos = ReconstructSamplePos(colorsTex, sampleTexCoord.xy, bl, br, tl, tr);
70        //samplePos = ReconstructSamplePos(ssaoTex, sampleTexCoord.xy, bl, br, tl, tr);
71
[3314]72        //float len = min(SqrLen(centerPos - samplePos), 1e2f);
73        float len = distance(centerPos, samplePos);
[3319]74        //float spatialFactor = 1.0f / max(len, 1e-3f);
75        float spatialFactor = 1.0f / max(spatialWeight + len, 1e-3f);
[3302]76
[3316]77        float convergenceFactor = min(aoSample.y + 1.0f, maxConvergence);
[3319]78        //convergenceFactor *= convergenceFactor;
[3302]79
80        // combine the weights
[3319]81        //float w = convergenceFactor * exp(1.0f + spatialFactor);
[3314]82        float w = convergenceFactor * spatialFactor;
83        //float w = spatialFactor;
[3302]84        float average = aoSample.x * w;
85
86        return float2(average, w);
87}
88
89
90/** Filter taking into account depth, normal discontinuities
91   and ssao convergence of a sample (the higher the more reliably
92   has the sample a correct ssao value)
93*/
94float FilterXY(float2 texCoord,
95                           uniform sampler2D ssaoTex,
96                           uniform sampler2D colorsTex,
97                           float3 bl,
98                           float3 br,
99                           float3 tl,
100                           float3 tr,
[3304]101                           float2 xyStep,
[3316]102                           float convergence,
[3319]103                           float maxConvergence,
104                           float spatialWeight
[3316]105                           )
[3302]106{
[3362]107        //return tex2Dlod(ssaoTex, float4(texCoord, .0f, .0f)).x;
108        float2 result = float2(.0f);
[3302]109       
110        const float3 centerPos = ReconstructSamplePos(colorsTex, texCoord, bl, br, tl, tr);
111
[3363]112#if 1
[3362]113        //const float scale = saturate((SSAO_CONVERGENCE_THRESHOLD - convergence + 100) / SSAO_CONVERGENCE_THRESHOLD);
[3339]114        const float scale = saturate((SSAO_CONVERGENCE_THRESHOLD - convergence) / SSAO_CONVERGENCE_THRESHOLD);
[3304]115       
[3363]116        for (int i = -SSAO_FILTER_RADIUS; i <= SSAO_FILTER_RADIUS; ++ i)
[3302]117        {
[3339]118                const float4 sampleTexCoord = float4(texCoord + i * xyStep * scale, .0f, .0f);
[3319]119                result += FilterSample(sampleTexCoord, ssaoTex, colorsTex, centerPos, bl, br, tl, tr, maxConvergence, spatialWeight);
[3302]120        }
[3362]121#else
[3302]122
[3363]123        const float radius = SSAO_FILTER_RADIUS * saturate((SSAO_CONVERGENCE_THRESHOLD - convergence + 100) / SSAO_CONVERGENCE_THRESHOLD);
[3362]124
125        for (int i = -radius; i <= radius; ++ i)
126        {
127                const float4 sampleTexCoord = float4(texCoord + i * xyStep, .0f, .0f);
128                result += FilterSample(sampleTexCoord, ssaoTex, colorsTex, centerPos, bl, br, tl, tr, maxConvergence, spatialWeight);
129        }
130
131#endif
[3302]132        result.x /= max(result.y, 1e-6f);
133        return saturate(result.x);
134}
135
[3314]136
[3302]137/** In between step that only filters in one direction
138*/
[3314]139pixel FilterSsaoHalfRes(fragment IN,
[3302]140                                                uniform sampler2D colorsTex,
141                                                uniform sampler2D ssaoTex,
142                                                uniform float3 bl,
143                                                uniform float3 br,
144                                                uniform float3 tl,
145                                                uniform float3 tr,
[3362]146                                                uniform float2 res,
147                                                uniform float maxConvergence,
148                                                uniform float spatialWeight
149
[3314]150                                                 )
[3302]151{
152        pixel OUT;
153
154        const float depth = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0)).w;
155
[3303]156        OUT.illum_col = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
[3314]157        // compute minimal convergence for savetly reasons, write it out
158        const float convergence = ComputeConvergenceHalfRes(ssaoTex, IN.texCoord, res * 0.5f);
159        OUT.illum_col.y = convergence;
[3302]160
[3314]161        const float2 xyStep = float2(1.0f / res.x, 0);
162
[3302]163        // filter reaches size 1 pixel when sample size reaches threshold
164        // afterwards we do not use the filter anymore
165
166        // filter up to a certain convergance value and leave out background (sky) by checking depth
[3362]167        if ((!USE_OPTIMIZATION || (convergence < SSAO_CONVERGENCE_THRESHOLD)) &&
168                (depth < DEPTH_THRESHOLD))
[3302]169        {
170                // the filtered ssao value
[3362]171                OUT.illum_col.x = FilterXY(IN.texCoord, ssaoTex, colorsTex,
172                                               bl, br, tl, tr, xyStep,
173                                                                   convergence, maxConvergence, spatialWeight);
[3302]174        }
175
176        return OUT;
177}
178
[3305]179/** In between step that only filters in one direction
180*/
[3314]181pixel FilterSsaoFullRes(fragment IN,
[3305]182                                                uniform sampler2D colorsTex,
183                                                uniform sampler2D ssaoTex,
184                                                uniform float3 bl,
185                                                uniform float3 br,
186                                                uniform float3 tl,
187                                                uniform float3 tr,
[3316]188                                                uniform float2 res,
[3319]189                                                uniform float maxConvergence,
190                                                uniform float spatialWeight
[3314]191                                                )
[3305]192{
193        pixel OUT;
[3302]194
[3305]195        const float depth = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0)).w;
196
197        OUT.illum_col = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
[3314]198        // just take unfiltered convergence in current pixel
199        const float convergence = OUT.illum_col.y;
[3305]200
201        // filter reaches size 1 pixel when sample size reaches threshold
202        // afterwards we do not use the filter anymore
203
[3362]204        float2 xyStep = float2(1.0f / res.x, .0f);
[3314]205
[3305]206        // filter up to a certain convergance value and leave out background (sky) by checking depth
[3363]207        if ((!USE_OPTIMIZATION || convergence < SSAO_CONVERGENCE_THRESHOLD) &&
208                (depth < DEPTH_THRESHOLD))
[3305]209        {
210                // the filtered ssao value
[3362]211                OUT.illum_col.x = FilterXY(IN.texCoord, ssaoTex, colorsTex,
212                                               bl, br, tl, tr, xyStep,
213                                                                   convergence, maxConvergence, spatialWeight);
[3305]214        }
215
216        return OUT;
217}
218
[3314]219
[3302]220/** Function combining image and indirect illumination buffer using a
221    depth and convergence aware discontinuity filter.
222*/
[3305]223pixel CombineSsao(fragment IN,
224                                  uniform sampler2D colorsTex,
225                                  uniform sampler2D ssaoTex,
226                                  uniform float3 bl,
227                                  uniform float3 br,
228                                  uniform float3 tl,
229                                  uniform float3 tr,
[3316]230                                  uniform float2 res,
[3319]231                                  uniform float maxConvergence,
232                                  uniform float spatialWeight
[3305]233                                  )
[3302]234{
235        pixel OUT;
236
[3364]237        float4 col = tex2Dlod(colorsTex, float4(IN.texCoord, .0f, .0f));
238        float4 ao = tex2Dlod(ssaoTex, float4(IN.texCoord, .0f, .0f));
[3302]239
240        const float depth = col.w;
241        // just take unfiltered convergence in current pixel
242        const float convergence = ao.y;
243
[3326]244        const float2 xyStep = float2(.0f, 1.0f / res.y);
[3305]245       
[3302]246        // filter reaches size 1 pixel when sample size reaches threshold
247        // afterwards we do not use the filter anymore
248
249        // filter up to a certain convergance value and leave out background (sky) by checking depth
[3362]250        if ((!USE_OPTIMIZATION || (convergence < SSAO_CONVERGENCE_THRESHOLD))
251                && (depth < DEPTH_THRESHOLD))
[3302]252        {
253                // the filtered ssao value
[3364]254                ao.x = FilterXY(IN.texCoord, ssaoTex, colorsTex,
[3369]255                                    bl, br, tl, tr,
256                                                xyStep, convergence, maxConvergence, spatialWeight);
[3302]257        }
258
[3319]259        const float minAO = 1e-3f;
260
[3302]261        // just apply ssao if we are not in the sky
[3304]262        if (depth < DEPTH_THRESHOLD)
[3302]263        {
[3353]264                //OUT.illum_col.xyz = col.xyz * max(minAO, 1.0f - ao.x);
265                OUT.illum_col.xyz = max(minAO, 1.0f - ao.x);
[3328]266                //OUT.illum_col.xyz = max(minAO, 1.0f - ao.x);
[3302]267        }
268        else
269        {
270                OUT.illum_col.xyz = col.xyz;
271        }
272
[3361]273        //OUT.illum_col.xyz = float3(ao.x * 1e1f, col.yz);
274
[3343]275        //OUT.illum_col.xyz = float3(ao.w * 5e-1f, 0, 0);
[3354]276        //OUT.illum_col.xyz = float3(ao.z * 1e-3f);
[3365]277       
278        //OUT.illum_col.xyz = float3(ao.y * 5e-4f);
279        //OUT.illum_col.xyz = float3(ao.y);
[3327]280        //OUT.illum_col.xyz = ao.xyz;
[3326]281
[3302]282        OUT.illum_col.w = col.w;
283
284        return OUT;
285}
Note: See TracBrowser for help on using the repository browser.