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

Revision 3361, 8.1 KB checked in by mattausch, 15 years ago (diff)
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        float2 result = float2(0.0f, 0.0f);
108       
109        const float3 centerPos = ReconstructSamplePos(colorsTex, texCoord, bl, br, tl, tr);
110
111        const float scale = saturate((SSAO_CONVERGENCE_THRESHOLD - convergence) / SSAO_CONVERGENCE_THRESHOLD);
112        //const int radius = SSAO_FILTER_RADIUS * saturate((SSAO_CONVERGENCE_THRESHOLD - convergence) / SSAO_CONVERGENCE_THRESHOLD);
113       
114        //for (int i = -radius; i <= radius; ++ i)
115        for (int i = -SSAO_FILTER_RADIUS; i <= SSAO_FILTER_RADIUS; ++ i)
116        {
117                const float4 sampleTexCoord = float4(texCoord + i * xyStep * scale, .0f, .0f);
118                result += FilterSample(sampleTexCoord, ssaoTex, colorsTex, centerPos, bl, br, tl, tr, maxConvergence, spatialWeight);
119        }
120
121        result.x /= max(result.y, 1e-6f);
122        return saturate(result.x);
123}
124
125
126/** In between step that only filters in one direction
127*/
128pixel FilterSsaoHalfRes(fragment IN,
129                                                uniform sampler2D colorsTex,
130                                                uniform sampler2D ssaoTex,
131                                                uniform float3 bl,
132                                                uniform float3 br,
133                                                uniform float3 tl,
134                                                uniform float3 tr,
135                                                uniform float2 res
136                                                 )
137{
138        pixel OUT;
139
140        const float depth = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0)).w;
141
142        OUT.illum_col = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
143        // compute minimal convergence for savetly reasons, write it out
144        const float convergence = ComputeConvergenceHalfRes(ssaoTex, IN.texCoord, res * 0.5f);
145        OUT.illum_col.y = convergence;
146
147        const float2 xyStep = float2(1.0f / res.x, 0);
148
149        // filter reaches size 1 pixel when sample size reaches threshold
150        // afterwards we do not use the filter anymore
151
152        // filter up to a certain convergance value and leave out background (sky) by checking depth
153        if ((convergence < SSAO_CONVERGENCE_THRESHOLD) && (depth < DEPTH_THRESHOLD))
154        {
155                // the filtered ssao value
156                OUT.illum_col.x = FilterXY(IN.texCoord, ssaoTex, colorsTex, bl, br, tl, tr, xyStep, convergence, maxConvergence, spatialWeight);
157        }
158
159        return OUT;
160}
161
162/** In between step that only filters in one direction
163*/
164pixel FilterSsaoFullRes(fragment IN,
165                                                uniform sampler2D colorsTex,
166                                                uniform sampler2D ssaoTex,
167                                                uniform float3 bl,
168                                                uniform float3 br,
169                                                uniform float3 tl,
170                                                uniform float3 tr,
171                                                uniform float2 res,
172                                                uniform float maxConvergence,
173                                                uniform float spatialWeight
174                                                )
175{
176        pixel OUT;
177
178        const float depth = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0)).w;
179
180        OUT.illum_col = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
181        // just take unfiltered convergence in current pixel
182        const float convergence = OUT.illum_col.y;
183
184        // filter reaches size 1 pixel when sample size reaches threshold
185        // afterwards we do not use the filter anymore
186
187        float2 xyStep = float2(1.0f / res.x, 0);
188
189        // filter up to a certain convergance value and leave out background (sky) by checking depth
190        if ((convergence < SSAO_CONVERGENCE_THRESHOLD) && (depth < DEPTH_THRESHOLD))
191        {
192                // the filtered ssao value
193                OUT.illum_col.x = FilterXY(IN.texCoord, ssaoTex, colorsTex, bl, br, tl, tr, xyStep, convergence, maxConvergence, spatialWeight);
194        }
195
196        return OUT;
197}
198
199
200/** Function combining image and indirect illumination buffer using a
201    depth and convergence aware discontinuity filter.
202*/
203pixel CombineSsao(fragment IN,
204                                  uniform sampler2D colorsTex,
205                                  uniform sampler2D ssaoTex,
206                                  uniform float3 bl,
207                                  uniform float3 br,
208                                  uniform float3 tl,
209                                  uniform float3 tr,
210                                  uniform float2 res,
211                                  uniform float maxConvergence,
212                                  uniform float spatialWeight
213                                  )
214{
215        pixel OUT;
216
217        float4 col = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0));
218        float4 ao = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
219
220        const float depth = col.w;
221        // just take unfiltered convergence in current pixel
222        const float convergence = ao.y;
223
224        const float2 xyStep = float2(.0f, 1.0f / res.y);
225       
226        // filter reaches size 1 pixel when sample size reaches threshold
227        // afterwards we do not use the filter anymore
228
229        // filter up to a certain convergance value and leave out background (sky) by checking depth
230        if ((convergence < SSAO_CONVERGENCE_THRESHOLD) && (depth < DEPTH_THRESHOLD))
231        {
232                // the filtered ssao value
233                ao.x = FilterXY(IN.texCoord, ssaoTex, colorsTex, bl, br, tl, tr, xyStep, convergence, maxConvergence, spatialWeight);
234        }
235
236        const float minAO = 1e-3f;
237
238        // just apply ssao if we are not in the sky
239        if (depth < DEPTH_THRESHOLD)
240        {
241                //OUT.illum_col.xyz = col.xyz * max(minAO, 1.0f - ao.x);
242                OUT.illum_col.xyz = max(minAO, 1.0f - ao.x);
243                //OUT.illum_col.xyz = max(minAO, 1.0f - ao.x);
244        }
245        else
246        {
247                OUT.illum_col.xyz = col.xyz;
248        }
249
250        //OUT.illum_col.xyz = float3(ao.x * 1e1f, col.yz);
251
252        //OUT.illum_col.xyz = float3(ao.w * 5e-1f, 0, 0);
253        //OUT.illum_col.xyz = float3(ao.z * 1e-3f);
254        //OUT.illum_col.xyz = float3(ao.y * 1e-3f);
255        //OUT.illum_col.xyz = ao.xyz;
256
257        OUT.illum_col.w = col.w;
258
259        return OUT;
260}
Note: See TracBrowser for help on using the repository browser.