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

Line 
1#include "../shaderenv.h"
2#include "common.h"
3
4
5/********************************************************/
6/*         Filter for combining ssao with image         */
7/********************************************************/
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
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
53float2 FilterSample(float4 sampleTexCoord,
54                                        uniform sampler2D ssaoTex,
55                                        uniform sampler2D colorsTex,
56                                        float3 centerPos,
57                                        float3 bl,
58                                        float3 br,
59                                        float3 tl,
60                                        float3 tr,
61                                        float maxConvergence,
62                                        float spatialWeight)
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
72        //float len = min(SqrLen(centerPos - samplePos), 1e2f);
73        float len = distance(centerPos, samplePos);
74        //float spatialFactor = 1.0f / max(len, 1e-3f);
75        float spatialFactor = 1.0f / max(spatialWeight + len, 1e-3f);
76
77        float convergenceFactor = min(aoSample.y + 1.0f, maxConvergence);
78        //convergenceFactor *= convergenceFactor;
79
80        // combine the weights
81        //float w = convergenceFactor * exp(1.0f + spatialFactor);
82        float w = convergenceFactor * spatialFactor;
83        //float w = spatialFactor;
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,
101                           float2 xyStep,
102                           float convergence,
103                           float maxConvergence,
104                           float spatialWeight
105                           )
106{
107        //return tex2Dlod(ssaoTex, float4(texCoord, .0f, .0f)).x;
108        float2 result = float2(.0f);
109       
110        const float3 centerPos = ReconstructSamplePos(colorsTex, texCoord, bl, br, tl, tr);
111
112#if 1
113        //const float scale = saturate((SSAO_CONVERGENCE_THRESHOLD - convergence + 100) / SSAO_CONVERGENCE_THRESHOLD);
114        const float scale = saturate((SSAO_CONVERGENCE_THRESHOLD - convergence) / SSAO_CONVERGENCE_THRESHOLD);
115       
116        for (int i = -SSAO_FILTER_RADIUS; i <= SSAO_FILTER_RADIUS; ++ i)
117        {
118                const float4 sampleTexCoord = float4(texCoord + i * xyStep * scale, .0f, .0f);
119                result += FilterSample(sampleTexCoord, ssaoTex, colorsTex, centerPos, bl, br, tl, tr, maxConvergence, spatialWeight);
120        }
121#else
122
123        const float radius = SSAO_FILTER_RADIUS * saturate((SSAO_CONVERGENCE_THRESHOLD - convergence + 100) / SSAO_CONVERGENCE_THRESHOLD);
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
132        result.x /= max(result.y, 1e-6f);
133        return saturate(result.x);
134}
135
136
137/** In between step that only filters in one direction
138*/
139pixel FilterSsaoHalfRes(fragment IN,
140                                                uniform sampler2D colorsTex,
141                                                uniform sampler2D ssaoTex,
142                                                uniform float3 bl,
143                                                uniform float3 br,
144                                                uniform float3 tl,
145                                                uniform float3 tr,
146                                                uniform float2 res,
147                                                uniform float maxConvergence,
148                                                uniform float spatialWeight
149
150                                                 )
151{
152        pixel OUT;
153
154        const float depth = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0)).w;
155
156        OUT.illum_col = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
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;
160
161        const float2 xyStep = float2(1.0f / res.x, 0);
162
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
167        if ((!USE_OPTIMIZATION || (convergence < SSAO_CONVERGENCE_THRESHOLD)) &&
168                (depth < DEPTH_THRESHOLD))
169        {
170                // the filtered ssao value
171                OUT.illum_col.x = FilterXY(IN.texCoord, ssaoTex, colorsTex,
172                                               bl, br, tl, tr, xyStep,
173                                                                   convergence, maxConvergence, spatialWeight);
174        }
175
176        return OUT;
177}
178
179/** In between step that only filters in one direction
180*/
181pixel FilterSsaoFullRes(fragment IN,
182                                                uniform sampler2D colorsTex,
183                                                uniform sampler2D ssaoTex,
184                                                uniform float3 bl,
185                                                uniform float3 br,
186                                                uniform float3 tl,
187                                                uniform float3 tr,
188                                                uniform float2 res,
189                                                uniform float maxConvergence,
190                                                uniform float spatialWeight
191                                                )
192{
193        pixel OUT;
194
195        const float depth = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0)).w;
196
197        OUT.illum_col = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
198        // just take unfiltered convergence in current pixel
199        const float convergence = OUT.illum_col.y;
200
201        // filter reaches size 1 pixel when sample size reaches threshold
202        // afterwards we do not use the filter anymore
203
204        float2 xyStep = float2(1.0f / res.x, .0f);
205
206        // filter up to a certain convergance value and leave out background (sky) by checking depth
207        if ((!USE_OPTIMIZATION || convergence < SSAO_CONVERGENCE_THRESHOLD) &&
208                (depth < DEPTH_THRESHOLD))
209        {
210                // the filtered ssao value
211                OUT.illum_col.x = FilterXY(IN.texCoord, ssaoTex, colorsTex,
212                                               bl, br, tl, tr, xyStep,
213                                                                   convergence, maxConvergence, spatialWeight);
214        }
215
216        return OUT;
217}
218
219
220/** Function combining image and indirect illumination buffer using a
221    depth and convergence aware discontinuity filter.
222*/
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,
230                                  uniform float2 res,
231                                  uniform float maxConvergence,
232                                  uniform float spatialWeight
233                                  )
234{
235        pixel OUT;
236
237        float4 col = tex2Dlod(colorsTex, float4(IN.texCoord, .0f, .0f));
238        float4 ao = tex2Dlod(ssaoTex, float4(IN.texCoord, .0f, .0f));
239
240        const float depth = col.w;
241        // just take unfiltered convergence in current pixel
242        const float convergence = ao.y;
243
244        const float2 xyStep = float2(.0f, 1.0f / res.y);
245       
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
250        if ((!USE_OPTIMIZATION || (convergence < SSAO_CONVERGENCE_THRESHOLD))
251                && (depth < DEPTH_THRESHOLD))
252        {
253                // the filtered ssao value
254                ao.x = FilterXY(IN.texCoord, ssaoTex, colorsTex,
255                                    bl, br, tl, tr,
256                                                xyStep, convergence, maxConvergence, spatialWeight);
257        }
258
259        const float minAO = 1e-3f;
260
261        // just apply ssao if we are not in the sky
262        if (depth < DEPTH_THRESHOLD)
263        {
264                //OUT.illum_col.xyz = col.xyz * max(minAO, 1.0f - ao.x);
265                OUT.illum_col.xyz = max(minAO, 1.0f - ao.x);
266                //OUT.illum_col.xyz = max(minAO, 1.0f - ao.x);
267        }
268        else
269        {
270                OUT.illum_col.xyz = col.xyz;
271        }
272
273        //OUT.illum_col.xyz = float3(ao.x * 1e1f, col.yz);
274
275        //OUT.illum_col.xyz = float3(ao.w * 5e-1f, 0, 0);
276        //OUT.illum_col.xyz = float3(ao.z * 1e-3f);
277       
278        //OUT.illum_col.xyz = float3(ao.y * 5e-4f);
279        //OUT.illum_col.xyz = float3(ao.y);
280        //OUT.illum_col.xyz = ao.xyz;
281
282        OUT.illum_col.w = col.w;
283
284        return OUT;
285}
Note: See TracBrowser for help on using the repository browser.