source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/combineSsao.cg @ 3204

Revision 3204, 8.2 KB checked in by mattausch, 16 years ago (diff)

debug version showing a visualization of the confidence

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
23/** Filter taking into account depth and normal differences,
24    and convergence of a sample 
25*/
26float DiscontinuityFilter(float2 texCoord,
27                                                  float4 ao,
28                                                  float4 color,
29                                                  uniform sampler2D ssaoTex,
30                                                  uniform sampler2D normalsTex,
31                                                  uniform sampler2D colorsTex,
32                                                  uniform float2 filterOffs[NUM_SSAO_FILTER_SAMPLES],
33                                                  uniform float filterWeights[NUM_SSAO_FILTER_SAMPLES],
34                                                  float scale
35                                                  )
36{
37        float average = .0f;
38        float total_w = .0f;
39
40        const float eyeSpaceDepth = color.w;
41
42        const float3 centerNormal = tex2Dlod(normalsTex, float4(texCoord, 0, 0)).xyz;
43
44        float4 aoSample;
45        float3 sampleNorm;
46        float3 samplePos;
47        float w;
48        float4 sampleTexCoord;
49        float depthFactor;
50        float normalFactor;
51        float convergenceFactor;
52        float sampleDepth;
53
54        for (int i = 0; i < NUM_SSAO_FILTER_SAMPLES; ++ i)
55        {
56                sampleTexCoord = float4(texCoord + filterOffs[i] * scale, 0, 0);
57
58                aoSample = tex2Dlod(ssaoTex, sampleTexCoord);
59                sampleNorm = tex2Dlod(normalsTex, sampleTexCoord).xyz;
60
61                // check depth discontinuity
62                sampleDepth = tex2Dlod(colorsTex, sampleTexCoord).w;
63                //sampleDepth = aoSample.w;
64               
65                //depthFactor = 1.0f / max(abs(eyeSpaceDepth - sampleDepth), 1e-2f);
66                depthFactor = 1.0f - step(1e-2f, abs(1.0f - eyeSpaceDepth / sampleDepth));
67                //normalFactor = max(step(0.6f, dot(sampleNorm, centerNormal)), 1e-3f);
68                normalFactor = max(dot(sampleNorm, centerNormal), 1e-3f);
69                //convergenceFactor = min(100.0f, aoSample.y);
70                convergenceFactor = aoSample.y + 1.0f;
71
72                // combine the weights
73                w = filterWeights[i] * convergenceFactor * depthFactor * normalFactor;
74                //w = normalFactor * convergenceFactor;
75
76                average += aoSample.x * w;
77                total_w += w;
78        }
79
80        average /= max(total_w, 1e-6f);
81
82        return saturate(average);
83}
84
85
86
87/** Filter taking into account depth and normal differences,
88   and convergence of a sample 
89*/
90float DiscontinuityFilter2(float2 texCoord,
91                                                   float4 ao,
92                                                   float4 color,
93                                                   uniform sampler2D ssaoTex,
94                                                   uniform sampler2D normalsTex,
95                                                   uniform sampler2D colorsTex,
96                                                   uniform float2 filterOffs[NUM_SSAO_FILTER_SAMPLES],
97                                                   float scale,
98                                                   float3 bl,
99                                                   float3 br,
100                                                   float3 tl,
101                                                   float3 tr)
102{
103        float average = .0f;
104        float total_w = .0f;
105
106        //const float3 centerPos = ReconstructSamplePos(ssaoTex, texCoord, bl, br, tl, tr);
107        const float3 centerPos = ReconstructSamplePos(colorsTex, texCoord, bl, br, tl, tr);
108        const float3 centerNormal = tex2Dlod(normalsTex, float4(texCoord, 0, 0)).xyz;
109
110        float4 aoSample;
111        float3 sampleNorm;
112        float3 samplePos;
113        float w;
114        float4 sampleTexCoord;
115        float spatialFactor;
116        float normalFactor;
117        float convergenceFactor;
118        float len;
119
120        const float convergenceThresh = 200.0f;
121
122        for (int i = 0; i < NUM_SSAO_FILTER_SAMPLES; ++ i)
123        {
124                sampleTexCoord = float4(texCoord + filterOffs[i] * scale, .0f, .0f);
125
126                aoSample = tex2Dlod(ssaoTex, sampleTexCoord);
127                //sampleNorm = tex2Dlod(normalsTex, sampleTexCoord).xyz;
128
129                // check spatial discontinuity
130                // note: using the depth from the color texture is not 100% correct as depth was
131                // not scaled with the interpolated view vector depth yet ...
132                samplePos = ReconstructSamplePos(colorsTex, sampleTexCoord.xy, bl, br, tl, tr);
133                //samplePos = ReconstructSamplePos(ssaoTex, sampleTexCoord.xy, bl, br, tl, tr);
134
135                len = min(SqrLen(centerPos - samplePos), 1e2f);
136                spatialFactor = 1.0f / max(len, 1e-3f);
137
138                //normalFactor = max(step(.2f, dot(sampleNorm, centerNormal)), 1e-2f);
139                convergenceFactor = aoSample.y + 1.0f;
140               
141                // combine the weights
142                w = convergenceFactor * convergenceFactor * spatialFactor;// * normalFactor;
143               
144                average += aoSample.x * w;
145                total_w += w;
146        }
147
148        average /= max(total_w, 1e-6f);
149
150        return saturate(average);
151}
152
153
154/** Function combining image and indirect illumination buffer using a
155        depth and normal aware discontinuity filter.
156*/
157pixel combine(fragment IN,
158                          uniform sampler2D colorsTex,
159                          uniform sampler2D ssaoTex,
160                          uniform sampler2D normalsTex,
161                          uniform float2 filterOffs[NUM_SSAO_FILTER_SAMPLES],
162                          uniform float filterWeights[NUM_SSAO_FILTER_SAMPLES],
163                          uniform float4x4 modelViewProj,
164                          uniform float3 bl,
165                          uniform float3 br,
166                          uniform float3 tl,
167                          uniform float3 tr
168                          )
169{
170        pixel OUT;
171
172        float4 col = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0));
173        float4 ao =  tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
174
175        // get the minimum convergence by exactly sampling the 4 surrounding
176        // texels in the old texture, otherwise flickering because convergence
177        // will be interpolated when upsampling and filter size does not match!
178        float4 texelCenterConv;
179        //const float w = 512.0f; const float h = 384.0f;
180        //const float w = 128.0f; const float h = 96.0f;
181        const float w = 16.0f; const float h = 12.0f;
182        const float xoffs = .5f / w; const float yoffs = .5f / h;
183
184        // get position exactly between old texel centers
185        float2 center;
186        center.x = (floor(IN.texCoord.x * w - .5f) + 1.0f) / w;
187        center.y = (floor(IN.texCoord.y * h - .5f) + 1.0f) / h;
188//center=IN.texCoord;
189        texelCenterConv.x = tex2Dlod(ssaoTex, float4(center + float2( xoffs,  yoffs), 0, 0)).y;
190        texelCenterConv.y = tex2Dlod(ssaoTex, float4(center + float2( xoffs, -yoffs), 0, 0)).y;
191        texelCenterConv.z = tex2Dlod(ssaoTex, float4(center + float2(-xoffs, -yoffs), 0, 0)).y;
192        texelCenterConv.w = tex2Dlod(ssaoTex, float4(center + float2(-xoffs,  yoffs), 0, 0)).y;
193
194        const float m1 = min(texelCenterConv.x, texelCenterConv.y);
195        const float m2 = min(texelCenterConv.z, texelCenterConv.w);
196
197        const float minConvergence = min(m1, m2);
198
199        const float convergence = minConvergence;
200        //const float convergence = 0;
201        //const float convergence = ao.y;
202
203        // filter reaches size 1 pixel after thres samples:
204        // afterwards we do not use the filter anymore
205        const float thres = 500.0f;
206
207        // filter up to a certain convergance value and leave out background (sky) by checking depth
208        if ((convergence < thres) && (col.w < 1e10f))
209        {
210                const float distanceScale = 1.0f;
211
212                // descend to zero filter size after reaching thres pixels
213                const float convergenceWeight = thres / (SSAO_FILTER_WIDTH - 1.0f);
214                const float convergenceScale = convergenceWeight / (convergence + convergenceWeight);
215                const float scale = SSAO_FILTER_WIDTH * convergenceScale * distanceScale;
216
217                // the filtered ssao value
218                ao.x = DiscontinuityFilter2(IN.texCoord, ao, col, ssaoTex, normalsTex, colorsTex, filterOffs, scale, bl, br, tl, tr);
219        }
220
221        if (col.w < 1e10f)
222                OUT.illum_col.xyz = col.xyz * ao.x;
223        else
224                OUT.illum_col.xyz = col.xyz;
225
226        //OUT.illum_col.xyz = float3(ao.x, ao.x, step(thres, convergence));
227        OUT.illum_col.xyz = float3(0, convergence, 0);
228        //OUT.illum_col.xyz = float3(abs(center.x - IN.texCoord.x) * 16.0f, abs(center.y - IN.texCoord.y) * 12.0f, 0);
229       
230        //OUT.illum_col.xyz = float3(0, clamp(1.0f - ao.y * 1e-3f, 0, 1), 1);
231        //OUT.illum_col.xyz = float3(0, 1.0f - step(0.5f + NUM_SAMPLES, convergence), 1);
232        OUT.illum_col.w = col.w;
233
234        return OUT;
235}
236
237
238
239/** Function combining image and indirect illumination buffer using a
240        depth and normal aware discontinuity filter.
241*/
242pixel SmoothSsao(fragment IN,
243                                 uniform sampler2D ssaoTex)
244{
245        pixel OUT;
246
247        float4 ao = tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
248
249        float4 dummy;
250        const float xoffs = .5f / 1024.0f; const float yoffs = .5f / 768.0f;
251
252        // get positions exactly between old texel centers
253        dummy.x = tex2Dlod(ssaoTex, float4(IN.texCoord + float2(xoffs, 0), 0, 0)).y;
254        dummy.y = tex2Dlod(ssaoTex, float4(IN.texCoord + float2(0, -yoffs), 0, 0)).y;
255        dummy.z = tex2Dlod(ssaoTex, float4(IN.texCoord + float2(-xoffs, 0), 0, 0)).y;
256        dummy.w = tex2Dlod(ssaoTex, float4(IN.texCoord + float2(0, yoffs), 0, 0)).y;
257
258        const float m1 = min(dummy.x, dummy.y);
259        const float m2 = min(dummy.z, dummy.w);
260
261        ao.y = min(ao.y, min(m1, m2));
262
263        return OUT;
264}
Note: See TracBrowser for help on using the repository browser.