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

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

tried out scaling vs reduction of samples

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 = SqrLen(centerPos - samplePos);
72                //len = length(centerPos - samplePos);
73                spatialFactor = 1.0f / max(len, 1e-3f);
74
75                convergenceFactor = aoSample.y + 1.0f;
76
77                //sampleNorm = tex2Dlod(normalsTex, sampleTexCoord).xyz;
78                //normalFactor = max(step(.2f, dot(sampleNorm, centerNormal)), 1e-2f);
79
80                // combine the weights
81                w = convergenceFactor * convergenceFactor * spatialFactor;// * normalFactor;
82               
83                average += aoSample.x * w;
84                total_w += w;
85        }
86
87        average /= max(total_w, 1e-6f);
88
89        return saturate(average);
90}
91
92
93/** Function combining image and indirect illumination buffer using a
94        depth and normal aware discontinuity filter. We assume that
95        we are using half resolution ssao for this version of the combineSsao
96*/
97pixel CombineSsaoHalfRes(fragment IN,
98                                                 uniform sampler2D colorsTex,
99                                                 uniform sampler2D ssaoTex,
100                                                 uniform sampler2D normalsTex,
101                                                 uniform float2 filterOffs[NUM_SSAO_FILTER_SAMPLES],
102                                                 uniform float filterWeights[NUM_SSAO_FILTER_SAMPLES],
103                                                 uniform float ssaoFilterRadius,
104                                                 uniform float4x4 modelViewProj,
105                                                 uniform float3 bl,
106                                                 uniform float3 br,
107                                                 uniform float3 tl,
108                                                 uniform float3 tr,
109                                                 uniform float2 resolution
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) &&
147                (col.w < DEPTH_THRESHOLD))
148        {
149                const float distanceScale = 1.0f;
150
151                // descend to zero filter size after reaching thres pixels
152                const float convergenceWeight = SSAO_CONVERGENCE_THRESHOLD / (ssaoFilterRadius - 1.0f);
153                const float convergenceScale = convergenceWeight / (convergence + convergenceWeight);
154                const float scale = 1;//ssaoFilterRadius * convergenceScale * distanceScale;
155
156                // the filtered ssao value
157                ao.x = DiscontinuityFilter(IN.texCoord, ao, col, ssaoTex, normalsTex, colorsTex, filterOffs, scale, bl, br, tl, tr);
158        }
159
160        // just apply ssao if we are not in the sky
161        if (col.w < DEPTH_THRESHOLD)
162        {
163                OUT.illum_col.xyz = col.xyz * max(2e-2f, 1.0f - ao.x);
164                //OUT.illum_col.xyz = col.xyz * ao.x;
165        }
166        else
167        {
168                OUT.illum_col.xyz = col.xyz;
169        }
170
171        //OUT.illum_col.xyz = float3(abs(ao.y * 1e2f), abs(ao.z * 1e2f), abs(ao.w * 1e2f));
172
173        //if (convergence < (1.0f + NUM_SAMPLES * 10))
174        //      OUT.illum_col.xyz = float3(1 - convergence / (NUM_SAMPLES * 10), convergence / (NUM_SAMPLES * 10), 0);
175       
176        //OUT.illum_col.xyz = float3(ao.z * 1e4f, ao.z * 1e4f, ao.z * 1e4f);
177
178        //OUT.illum_col.xyz = float3(ao.x, ao.x, step(thres, convergence));
179        //OUT.illum_col.xyz = float3(abs(center.x - IN.texCoord.x) * 16.0f, abs(center.y - IN.texCoord.y) * 12.0f, 0);
180        //OUT.illum_col.xyz = float3(0, 1.0f - step(0.5f + NUM_SAMPLES, convergence), 1);
181
182        OUT.illum_col.w = col.w;
183
184        return OUT;
185}
186
187
188/** Function combining image and indirect illumination buffer using a
189        depth and normal aware discontinuity filter.
190*/
191pixel CombineSsaoFullRes(fragment IN,
192                                                 uniform sampler2D colorsTex,
193                                                 uniform sampler2D ssaoTex,
194                                                 uniform sampler2D normalsTex,
195                                                 uniform float2 filterOffs[NUM_SSAO_FILTER_SAMPLES],
196                                                 uniform float filterWeights[NUM_SSAO_FILTER_SAMPLES],
197                                                 uniform float ssaoFilterRadius,
198                                                 uniform float4x4 modelViewProj,
199                                                 uniform float3 bl,
200                                                 uniform float3 br,
201                                                 uniform float3 tl,
202                                                 uniform float3 tr,
203                                                 uniform float2 resolution
204                                                 )
205{
206        pixel OUT;
207
208        float4 col = tex2Dlod(colorsTex, float4(IN.texCoord, 0, 0));
209        float4 ao =  tex2Dlod(ssaoTex, float4(IN.texCoord, 0, 0));
210
211        // just take unfiltered convergence in current pixel
212        const float convergence = ao.y;
213       
214        // filter reaches size 1 pixel when sample size reaches threshold
215        // afterwards we do not use the filter anymore
216
217        // filter up to a certain convergance value and leave out background (sky) by checking depth
218        if ((convergence < SSAO_CONVERGENCE_THRESHOLD) &&
219                (col.w < DEPTH_THRESHOLD))
220        {
221                const float distanceScale = 1.0f;
222
223                // descend to zero filter size after reaching thres pixels
224                const float convergenceWeight = SSAO_CONVERGENCE_THRESHOLD / (ssaoFilterRadius - 1.0f);
225                const float convergenceScale = convergenceWeight / (convergence + convergenceWeight);
226                //const float scale = 1;//ssaoFilterRadius * convergenceScale * distanceScale;
227                const float scale = convergenceScale;
228
229                // the filtered ssao value
230                ao.x = DiscontinuityFilter(IN.texCoord, ao, col, ssaoTex, normalsTex, colorsTex, filterOffs, scale, bl, br, tl, tr);
231        }
232
233        // just apply ssao if we are not in the sky
234        if (col.w < DEPTH_THRESHOLD)
235        {
236                OUT.illum_col.xyz = col.xyz * max(2e-2f, 1.0f - ao.x);
237                //OUT.illum_col.xyz = col.xyz * ao.x;
238        }
239        else
240        {
241                OUT.illum_col.xyz = col.xyz;
242        }
243
244        OUT.illum_col.w = col.w;
245
246        return OUT;
247}
Note: See TracBrowser for help on using the repository browser.