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

Revision 3306, 7.2 KB checked in by mattausch, 15 years ago (diff)

found error with border

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        // compute minimal convergence for savetly reasons, write it out
169        const float convergence = ComputeConvergenceHalfRes(ssaoTex, IN.texCoord, res * 0.5f);
170        OUT.illum_col.y = convergence;
171
172        const float2 xyStep = float2(1.0f / res.x, 0);
173
174        // filter reaches size 1 pixel when sample size reaches threshold
175        // afterwards we do not use the filter anymore
176
177        // filter up to a certain convergance value and leave out background (sky) by checking depth
178        if ((convergence < SSAO_CONVERGENCE_THRESHOLD) && (depth < DEPTH_THRESHOLD))
179        {
180                // the filtered ssao value
181                OUT.illum_col.x = FilterXY(IN.texCoord, ssaoTex, colorsTex, bl, br, tl, tr, xyStep, convergence);
182        }
183
184        return OUT;
185}
186
187/** Function combining image and indirect illumination buffer using a
188    depth and convergence aware discontinuity filter.
189*/
190pixel CombineSsao(fragment IN,
191                                  uniform sampler2D colorsTex,
192                                  uniform sampler2D ssaoTex,
193                                  uniform float3 bl,
194                                  uniform float3 br,
195                                  uniform float3 tl,
196                                  uniform float3 tr,
197                                  uniform float2 res
198                                  )
199{
200        pixel OUT;
201
202        float4 col = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0));
203        float4 ao = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
204
205        const float depth = col.w;
206        // just take unfiltered convergence in current pixel
207        const float convergence = ao.y;
208
209        const float2 xyStep = float2(0, 1.0f / res.y);
210       
211        // filter reaches size 1 pixel when sample size reaches threshold
212        // afterwards we do not use the filter anymore
213
214        // filter up to a certain convergance value and leave out background (sky) by checking depth
215        if ((convergence < SSAO_CONVERGENCE_THRESHOLD) && (depth < DEPTH_THRESHOLD))
216        {
217                // the filtered ssao value
218                ao.x = FilterXY(IN.texCoord, ssaoTex, colorsTex, bl, br, tl, tr, xyStep, convergence);
219        }
220
221        // just apply ssao if we are not in the sky
222        if (depth < DEPTH_THRESHOLD)
223        {
224                //OUT.illum_col.xyz = col.xyz * max(2e-2f, 1.0f - ao.x);
225                OUT.illum_col.xyz = max(2e-2f, 1.0f - ao.x);
226        }
227        else
228        {
229                OUT.illum_col.xyz = col.xyz;
230        }
231
232        OUT.illum_col.w = col.w;
233
234        return OUT;
235}
Note: See TracBrowser for help on using the repository browser.