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

Revision 3216, 5.8 KB checked in by mattausch, 16 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
140        const float convergence = minConvergence;
141        //const float convergence = 0;
142        //const float convergence = ao.y;
143
144        // filter reaches size 1 pixel when sample size reaches threshold
145        // afterwards we do not use the filter anymore
146
147        // filter up to a certain convergance value and leave out background (sky) by checking depth
148        if ((convergence < SSAO_CONVERGENCE_THRESHOLD) && (col.w < 1e10f))
149        {
150                const float distanceScale = 1.0f;
151
152                // descend to zero filter size after reaching thres pixels
153                const float convergenceWeight = SSAO_CONVERGENCE_THRESHOLD / (ssaoFilterRadius - 1.0f);
154                const float convergenceScale = convergenceWeight / (convergence + convergenceWeight);
155                const float scale = ssaoFilterRadius * convergenceScale * distanceScale;
156
157                // the filtered ssao value
158                ao.x = DiscontinuityFilter(IN.texCoord, ao, col, ssaoTex, normalsTex, colorsTex, filterOffs, scale, bl, br, tl, tr);
159        }
160
161        if (col.w < 1e10f)
162                OUT.illum_col.xyz = col.xyz * max(1e-1f, 1.0f - ao.x);
163        else
164                OUT.illum_col.xyz = col.xyz;
165
166        //OUT.illum_col.xyz = float3(ao.x, ao.x, step(thres, convergence));
167        //OUT.illum_col.xyz = float3(0, convergence, 0);
168        //OUT.illum_col.xyz = float3(abs(center.x - IN.texCoord.x) * 16.0f, abs(center.y - IN.texCoord.y) * 12.0f, 0);
169       
170        //OUT.illum_col.xyz = float3(0, clamp(1.0f - ao.y * 1e-3f, 0, 1), 1);
171        //OUT.illum_col.xyz = float3(0, 1.0f - step(0.5f + NUM_SAMPLES, convergence), 1);
172        OUT.illum_col.w = col.w;
173
174        return OUT;
175}
Note: See TracBrowser for help on using the repository browser.