source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ambient_occlusion.fx @ 2810

Revision 2810, 4.8 KB checked in by mattausch, 16 years ago (diff)
Line 
1//=======================================================================================
2string description = "Screenspace Ambient Occlusion";
3//=======================================================================================
4
5
6//=======================================================================================
7
8
9#define SAMPLES                         24
10
11static const float2 samples[SAMPLES] =
12        {
13                {-0.326212f, -0.405805f},
14                {-0.840144f, -0.07358f},
15                {-0.695914f, 0.457137f},
16                {-0.203345f, 0.620716},
17                {0.96234f, -0.194983f},
18                {0.473434f, -0.480026f},
19                {0.519456, 0.767022f},
20                {0.185461f, -0.893124f},
21                {0.507431f, 0.064425f},
22                {0.89642f, 0.412458f},
23                {-0.32194f, -0.932615f},
24                {-0.791559f, -0.597705f},
25                {0.326212f, 0.405805f},
26                {0.840144f, 0.07358f},
27                {0.695914f, -0.457137f},
28                {0.203345f, -0.620716},
29                {-0.96234f, 0.194983f},
30                {-0.473434f, 0.480026f},
31                {-0.519456, -0.767022f},
32                {-0.185461f, 0.893124f},
33                {-0.507431f, -0.064425f},
34                {-0.89642f, -0.412458f},
35                {0.32194f, 0.932615f},
36                {0.791559f, 0.597705f}
37        };
38       
39       
40//=======================================================================================
41
42
43float4x4 WorldViewProj                  : WorldViewProjection;
44float4x4 WorldView                              : WorldView;
45
46float4x4 CameraViewProjection;
47
48shared float3 WorldCenterPosition;              // Center positions around this point (usually eye point).
49shared float WorldScale;                                // Scale positions to maintain precision.
50
51float AreaSize = 1.0;
52float SampleIntensity = 0.1;
53
54
55//=======================================================================================
56
57
58shared texture positions;
59shared texture diffuse;
60shared texture normals;
61
62sampler PositionsSampler = sampler_state
63{
64    texture = <positions>;
65    AddressU  = CLAMP;       
66    AddressV  = CLAMP;
67    AddressW  = CLAMP;
68    MINFILTER = POINT;
69    MAGFILTER = POINT;
70    MIPFILTER = NONE;
71};
72
73sampler DiffuseSampler = sampler_state
74{
75    texture = <diffuse>;
76    AddressU  = CLAMP;       
77    AddressV  = CLAMP;
78    AddressW  = CLAMP;
79    MINFILTER = POINT;
80    MAGFILTER = POINT;
81    MIPFILTER = NONE;
82};
83
84sampler NormalsSampler = sampler_state
85{
86    texture = <normals>;
87    AddressU  = CLAMP;       
88    AddressV  = CLAMP;
89    AddressW  = CLAMP;
90    MINFILTER = POINT;
91    MAGFILTER = POINT;
92    MIPFILTER = NONE;
93};
94
95
96//=======================================================================================
97
98
99struct VertexInput {
100        float4 position                 : POSITION;
101        float2 texcoord                 : TEXCOORD0;
102};
103
104struct VertexOutput {
105        float4 position                 : POSITION;
106        float2 texcoord                 : TEXCOORD0;
107};
108
109struct PixelOutput {
110        float4 color                    : COLOR0;
111};
112
113
114//=======================================================================================
115
116
117VertexOutput vs_render(VertexInput IN)
118{
119        VertexOutput OUT;
120
121        OUT.position = float4(IN.position.xyz, 1.0);
122        OUT.texcoord = IN.texcoord;
123       
124        return OUT;
125}
126
127
128//=======================================================================================
129
130
131PixelOutput ps_render(VertexOutput IN)
132{
133        PixelOutput OUT;
134
135        float4 positions = tex2D(PositionsSampler, IN.texcoord);
136        float4 normals = tex2D(NormalsSampler, IN.texcoord);
137       
138        float3 current_position = positions.xyz;
139        float3 current_normal = normals.xyz * 2.0 - 1.0;
140       
141        // Get postprojection Z value to adjust AO area size.
142        float3 worldposition = (positions.xyz / WorldScale) + WorldCenterPosition;
143        float4 projected_position = mul(float4(worldposition.xyz, 1.0), CameraViewProjection);
144        projected_position.xyz /= projected_position.w;
145       
146
147        // Check in a circular area around the current position.
148        // Shoot vectors to the positions there, and check the angle to these positions.
149        // Summing up these angles gives an estimation of the occlusion at the current position.
150
151        float total_ao = 0.0;
152
153        for (float sample = 0.0; sample < SAMPLES; sample++)
154        {
155                float2 offset = samples[sample];
156                float2 texcoord = IN.texcoord + offset * AreaSize * (1.0 - projected_position.z);
157               
158                float3 sample_position = tex2D(PositionsSampler, texcoord).xyz;
159               
160                float3 vector_to_sample = sample_position - current_position;
161                float length_to_sample = length(vector_to_sample);
162                float3 direction_to_sample = vector_to_sample / length_to_sample;
163                length_to_sample /= WorldScale;
164               
165                // Angle between current normal and direction to sample controls AO intensity.
166                float angle = dot(direction_to_sample, current_normal);
167                angle = max(angle, 0.0);
168               
169                // Distance between current position and sample position controls AO intensity.
170                float distance_intensity = 1.0 - length_to_sample * 2.0;
171                distance_intensity = max(distance_intensity, 0.0);
172               
173                total_ao += angle * SampleIntensity * distance_intensity;
174        }
175       
176       
177        OUT.color = float4(0.0, 0.0, 0.0, total_ao);
178       
179        return OUT;
180}
181
182
183//=======================================================================================
184
185
186technique render
187{
188        pass p0
189        {
190                VertexShader = compile vs_3_0 vs_render();
191                PixelShader = compile ps_3_0 ps_render();       
192        }
193}
Note: See TracBrowser for help on using the repository browser.