source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg @ 2830

Revision 2830, 4.8 KB checked in by mattausch, 16 years ago (diff)
Line 
1////////////////////
2// Screen Spaced Ambient Occlusion shader
3// mainly based on Kustls shader
4
5#define NUM_SAMPLES 8
6//#define SAMPLE_INTENSITY 0.5f
7//#define SAMPLE_INTENSITY 1.1f
8#define SAMPLE_INTENSITY 0.7f
9#define AREA_SIZE 5e-1f
10
11
12struct fragment
13{
14  float4 pos: WPOS; // normalized screen position
15  float4 texCoord: TEXCOORD0;
16};
17
18
19struct pixel
20{
21  float4 color: COLOR0;
22};
23
24
25float2 reflect(float2 pt, float2 n)
26{
27  // distance to plane
28  float d = dot(n, pt);
29  // reflect around plane
30  float2 rpt = pt - d * 2.0f * n;
31 
32  //return pt;
33  return rpt;
34}
35
36
37float2 rotate(float2 pt, float2 n)
38{
39  float2 ptTransformed;
40  ptTransformed.x = n.r * pt.x - n.g * pt.y;
41  ptTransformed.y = n.g * pt.x + n.r * pt.y;
42
43  return ptTransformed;
44}
45
46
47//based on kustls shader       
48float ssao(fragment IN,
49           uniform sampler2D positions,
50           uniform sampler2D noiseTexture,
51           uniform float2 samples[NUM_SAMPLES],
52           uniform float3 currentNormal
53           )
54{
55  // the current world position
56  float4 centerPosition = tex2D(positions, IN.texCoord.xy);
57  // the w coordinate from the persp. projection
58  float w = centerPosition.w;
59
60  // Check in a circular area around the current position.
61  // Shoot vectors to the positions there, and check the angle to these positions.
62  // Summing up these angles gives an estimation of the occlusion at the current position.
63 
64  float total_ao = 0.0;
65
66  const float areaSize = 5e-1f;
67  //const float areaSize = 3e-1f;
68  //const float sampleIntensity = 0.2f;
69 
70  for (int i = 0; i < NUM_SAMPLES; i ++) {
71    float2 offset = samples[i];
72   
73    //sample noisetex; r stores costheta, g stores sintheta
74    float2 noise = tex2D(noiseTexture, IN.texCoord.xy * 7.0f).xy * 2.0f - 1.0f;
75       
76    // rotation
77    //float2 offsetTransformed = offset;
78    float2 offsetTransformed = rotate(offset, noise);
79    //float2 offsetTransformed = reflect(offset, noise);
80               
81    // weight with projected coordinate to reach similar kernel size for near and far
82    float2 texcoord = IN.texCoord.xy + offsetTransformed * AREA_SIZE * w;
83   
84    float3 sample_position = tex2D(positions, texcoord).xyz;
85   
86    float3 vector_to_sample = sample_position - centerPosition.xyz;
87    float length_to_sample = length(vector_to_sample);
88    float3 direction_to_sample = vector_to_sample / length_to_sample;
89   
90    // Angle between current normal and direction to sample controls AO intensity.
91    float cos_angle = dot(direction_to_sample, currentNormal);
92    cos_angle = max(cos_angle, 0.0f);
93    // take quadratic influence to sharpen contrast
94    //cos_angle *= cos_angle;
95
96    // distance between current position and sample position controls AO intensity.
97    //const float maxdist = 2e-1f;
98    //const float maxdist = 5e-1f;
99    const float distanceScale = 1e-6f;
100    //float distance_intensity = maxdist - length_to_sample;
101    float distance_intensity = (SAMPLE_INTENSITY * distanceScale) / (distanceScale + length_to_sample * length_to_sample);
102    //distance_intensity = max(distance_intensity, 0.0f);
103    // quadratic influence
104    //distance_intensity *= distance_intensity;
105   
106    total_ao += cos_angle * distance_intensity;
107  }
108       
109  return (1.0f - total_ao);
110}
111
112
113float4 shade(fragment IN,
114             uniform sampler2D colors,
115             uniform sampler2D positions,
116             uniform float3 normal,
117             uniform float amb)
118{
119  float4 lightDir = float4(0.8f, -1.0f, 0.7f, 0.0f);
120  float4 lightDir2 = float4(-0.5f, 0.5f, 0.4f, 0.0f);
121 
122  float4 color = tex2D(colors, IN.texCoord.xy);
123 
124  float4 position = tex2D(positions, IN.texCoord.xy);
125
126  float4 ambient = 0.3f;
127
128  // float3 L = normalize(lightPosition - position);
129  float3 light = normalize(lightDir.xyz);
130  float3 light2 = normalize(lightDir2.xyz);
131 
132  float diffuseLight = max(dot(normal, light), 0.0f);
133  float diffuseLight2 = max(dot(normal, light2), 0.0f);
134
135  float diffuse = diffuseLight + diffuseLight2;
136
137  return (ambient + diffuse) * color * (1.0f - amb) + amb * color;
138}
139
140
141pixel main_ssao(fragment IN,
142               uniform sampler2D colors,
143               uniform sampler2D positions,
144               uniform sampler2D normals,
145               uniform sampler2D noiseTexture,
146               uniform float2 samples[NUM_SAMPLES])
147{
148  pixel OUT;
149
150  float4 normal = tex2D(normals, IN.texCoord.xy);
151  float amb = normal.w;
152
153  // expand normal
154  normal = normalize(normal * 2.0f - 1.0f);
155
156  float4 col = shade(IN, colors, positions, normal, amb);
157  float ao = ssao(IN, positions, noiseTexture, samples, normal);
158 
159   //OUT.color = ao;
160   OUT.color = ao * col;
161
162  return OUT;
163}
164
165
166pixel main(fragment IN,
167           uniform sampler2D colors,
168           uniform sampler2D positions,
169           uniform sampler2D normals)
170{
171  pixel OUT;
172 
173  float4 normal = tex2D(normals, IN.texCoord.xy);
174  float amb = normal.w;
175
176  // expand normal
177  normal = normalize(normal * 2.0f - 1.0f);
178 
179  float4 col = shade(IN, colors, positions, normal.xyz, amb);
180  OUT.color = col;
181
182  return OUT;
183}
Note: See TracBrowser for help on using the repository browser.