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

Revision 3305, 7.1 KB checked in by mattausch, 15 years ago (diff)

removed filter radius

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