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

Revision 3341, 8.0 KB checked in by mattausch, 15 years ago (diff)

nix geht

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
197        return OUT;
198}
199
200
201/** Function combining image and indirect illumination buffer using a
202    depth and convergence aware discontinuity filter.
203*/
204pixel CombineSsao(fragment IN,
205                                  uniform sampler2D colorsTex,
206                                  uniform sampler2D ssaoTex,
207                                  uniform float3 bl,
208                                  uniform float3 br,
209                                  uniform float3 tl,
210                                  uniform float3 tr,
211                                  uniform float2 res,
212                                  uniform float maxConvergence,
213                                  uniform float spatialWeight
214                                  )
215{
216        pixel OUT;
217
218        float4 col = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0));
219        float4 ao = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
220
221        const float depth = col.w;
222        // just take unfiltered convergence in current pixel
223        const float convergence = ao.y;
224
225        const float2 xyStep = float2(.0f, 1.0f / res.y);
226       
227        // filter reaches size 1 pixel when sample size reaches threshold
228        // afterwards we do not use the filter anymore
229
230        // filter up to a certain convergance value and leave out background (sky) by checking depth
231        if ((convergence < SSAO_CONVERGENCE_THRESHOLD) && (depth < DEPTH_THRESHOLD))
232        {
233                // the filtered ssao value
234                ao.x = FilterXY(IN.texCoord, ssaoTex, colorsTex, bl, br, tl, tr, xyStep, convergence, maxConvergence, spatialWeight);
235        }
236
237        //const float minAO = 2e-2f;
238        const float minAO = 1e-3f;
239
240        // just apply ssao if we are not in the sky
241        if (depth < DEPTH_THRESHOLD)
242        {
243                OUT.illum_col.xyz = col.xyz * max(minAO, 1.0f - ao.x);
244                //OUT.illum_col.xyz = max(minAO, 1.0f - ao.x);
245        }
246        else
247        {
248                OUT.illum_col.xyz = col.xyz;
249        }
250
251        OUT.illum_col.xyz = float3(ao.w * 5e-1f, 0, 0);
252        //OUT.illum_col.xyz = float3(ao.z * 1e-1f);
253        OUT.illum_col.xyz = float3(ao.y * 1e-1f);//, 0, 0);
254        //OUT.illum_col.xyz = ao.xyz;
255
256        OUT.illum_col.w = col.w;
257
258        return OUT;
259}
Note: See TracBrowser for help on using the repository browser.