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

Revision 3314, 7.3 KB checked in by mattausch, 15 years ago (diff)

reverted to old sampling scheme

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{
62        float2 aoSample = tex2Dlod(ssaoTex, sampleTexCoord);
63               
64        // check spatial discontinuity
65        // note: using the depth from the color texture is not 100% correct as depth was
66        // not scaled with the interpolated view vector depth yet ...
67        float3 samplePos = ReconstructSamplePos(colorsTex, sampleTexCoord.xy, bl, br, tl, tr);
68        //samplePos = ReconstructSamplePos(ssaoTex, sampleTexCoord.xy, bl, br, tl, tr);
69
70        //float len = min(SqrLen(centerPos - samplePos), 1e2f);
71        float len = distance(centerPos, samplePos);
72        float spatialFactor = 1.0f / max(len, 1e-3f);
73
74        float convergenceFactor = aoSample.y + 1.0f;
75
76        // combine the weights
77        //float w = convergenceFactor * convergenceFactor * spatialFactor;
78        float w = convergenceFactor * spatialFactor;
79        //float w = spatialFactor;
80        float average = aoSample.x * w;
81
82        return float2(average, w);
83}
84
85
86/** Filter taking into account depth, normal discontinuities
87   and ssao convergence of a sample (the higher the more reliably
88   has the sample a correct ssao value)
89*/
90float FilterXY(float2 texCoord,
91                           uniform sampler2D ssaoTex,
92                           uniform sampler2D colorsTex,
93                           float3 bl,
94                           float3 br,
95                           float3 tl,
96                           float3 tr,
97                           float2 xyStep,
98                           float convergence)
99{
100        float2 result = float2(0.0f, 0.0f);
101       
102        const float3 centerPos = ReconstructSamplePos(colorsTex, texCoord, bl, br, tl, tr);
103
104        const float scale = saturate((SSAO_CONVERGENCE_THRESHOLD - convergence) / SSAO_CONVERGENCE_THRESHOLD);
105        //const int radius = SSAO_FILTER_RADIUS * saturate((SSAO_CONVERGENCE_THRESHOLD - convergence) / SSAO_CONVERGENCE_THRESHOLD);
106       
107        //for (int i = -radius; i <= radius; ++ i)
108        for (int i = -SSAO_FILTER_RADIUS; i <= SSAO_FILTER_RADIUS; ++ i)
109        {
110                float4 sampleTexCoord = float4(texCoord + i * xyStep * scale, .0f, .0f);
111                result += FilterSample(sampleTexCoord, ssaoTex, colorsTex, centerPos, bl, br, tl, tr);
112        }
113
114        result.x /= max(result.y, 1e-6f);
115
116        return saturate(result.x);
117}
118
119
120/** In between step that only filters in one direction
121*/
122pixel FilterSsaoHalfRes(fragment IN,
123                                                uniform sampler2D colorsTex,
124                                                uniform sampler2D ssaoTex,
125                                                uniform float3 bl,
126                                                uniform float3 br,
127                                                uniform float3 tl,
128                                                uniform float3 tr,
129                                                uniform float2 res
130                                                 )
131{
132        pixel OUT;
133
134        const float depth = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0)).w;
135
136        OUT.illum_col = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
137        // compute minimal convergence for savetly reasons, write it out
138        const float convergence = ComputeConvergenceHalfRes(ssaoTex, IN.texCoord, res * 0.5f);
139        OUT.illum_col.y = convergence;
140
141        const float2 xyStep = float2(1.0f / res.x, 0);
142
143        // filter reaches size 1 pixel when sample size reaches threshold
144        // afterwards we do not use the filter anymore
145
146        // filter up to a certain convergance value and leave out background (sky) by checking depth
147        if ((convergence < SSAO_CONVERGENCE_THRESHOLD) && (depth < DEPTH_THRESHOLD))
148        {
149                // the filtered ssao value
150                OUT.illum_col.x = FilterXY(IN.texCoord, ssaoTex, colorsTex, bl, br, tl, tr, xyStep, convergence);
151        }
152
153        return OUT;
154}
155
156/** In between step that only filters in one direction
157*/
158pixel FilterSsaoFullRes(fragment IN,
159                                                uniform sampler2D colorsTex,
160                                                uniform sampler2D ssaoTex,
161                                                uniform float3 bl,
162                                                uniform float3 br,
163                                                uniform float3 tl,
164                                                uniform float3 tr,
165                                                uniform float2 res
166                                                )
167{
168        pixel OUT;
169
170        const float depth = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0)).w;
171
172        OUT.illum_col = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
173        // just take unfiltered convergence in current pixel
174        const float convergence = OUT.illum_col.y;
175
176        // filter reaches size 1 pixel when sample size reaches threshold
177        // afterwards we do not use the filter anymore
178
179        float2 xyStep = float2(1.0f / res.x, 0);
180
181        // filter up to a certain convergance value and leave out background (sky) by checking depth
182        if ((convergence < SSAO_CONVERGENCE_THRESHOLD) && (depth < DEPTH_THRESHOLD))
183        {
184                // the filtered ssao value
185                OUT.illum_col.x = FilterXY(IN.texCoord, ssaoTex, colorsTex, bl, br, tl, tr, xyStep, convergence);
186        }
187
188        return OUT;
189}
190
191
192/** Function combining image and indirect illumination buffer using a
193    depth and convergence aware discontinuity filter.
194*/
195pixel CombineSsao(fragment IN,
196                                  uniform sampler2D colorsTex,
197                                  uniform sampler2D ssaoTex,
198                                  uniform float3 bl,
199                                  uniform float3 br,
200                                  uniform float3 tl,
201                                  uniform float3 tr,
202                                  uniform float2 res
203                                  )
204{
205        pixel OUT;
206
207        float4 col = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0));
208        float4 ao = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
209
210        const float depth = col.w;
211        // just take unfiltered convergence in current pixel
212        const float convergence = ao.y;
213
214        const float2 xyStep = float2(0, 1.0f / res.y);
215       
216        // filter reaches size 1 pixel when sample size reaches threshold
217        // afterwards we do not use the filter anymore
218
219        // filter up to a certain convergance value and leave out background (sky) by checking depth
220        if ((convergence < SSAO_CONVERGENCE_THRESHOLD) && (depth < DEPTH_THRESHOLD))
221        {
222                // the filtered ssao value
223                ao.x = FilterXY(IN.texCoord, ssaoTex, colorsTex, bl, br, tl, tr, xyStep, convergence);
224        }
225
226        // just apply ssao if we are not in the sky
227        if (depth < DEPTH_THRESHOLD)
228        {
229                //OUT.illum_col.xyz = col.xyz * max(2e-2f, 1.0f - ao.x);
230                OUT.illum_col.xyz = max(1e-3f, 1.0f - ao.x);
231        }
232        else
233        {
234                OUT.illum_col.xyz = col.xyz;
235        }
236
237        OUT.illum_col.w = col.w;
238
239        return OUT;
240}
Note: See TracBrowser for help on using the repository browser.