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

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