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

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