aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl')
-rw-r--r--linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl203
1 files changed, 203 insertions, 0 deletions
diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
new file mode 100644
index 0000000..8ced94e
--- /dev/null
+++ b/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
@@ -0,0 +1,203 @@
1/**
2 * @file sunLightF.glsl
3 *
4 * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
5 * $License$
6 */
7
8#extension GL_ARB_texture_rectangle : enable
9
10uniform sampler2DRect depthMap;
11uniform sampler2DRect normalMap;
12uniform sampler2DRectShadow shadowMap0;
13uniform sampler2DRectShadow shadowMap1;
14uniform sampler2DRectShadow shadowMap2;
15uniform sampler2DRectShadow shadowMap3;
16uniform sampler2DRectShadow shadowMap4;
17uniform sampler2DRectShadow shadowMap5;
18uniform sampler2D noiseMap;
19
20uniform sampler2D lightFunc;
21
22
23// Inputs
24uniform mat4 shadow_matrix[6];
25uniform vec4 shadow_clip;
26uniform float ssao_radius;
27uniform float ssao_max_radius;
28uniform float ssao_factor;
29uniform float ssao_factor_inv;
30
31varying vec2 vary_fragcoord;
32varying vec4 vary_light;
33
34uniform mat4 inv_proj;
35uniform vec2 screen_res;
36
37uniform float shadow_bias;
38uniform float shadow_offset;
39
40vec4 getPosition(vec2 pos_screen)
41{
42 float depth = texture2DRect(depthMap, pos_screen.xy).a;
43 vec2 sc = pos_screen.xy*2.0;
44 sc /= screen_res;
45 sc -= vec2(1.0,1.0);
46 vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
47 vec4 pos = inv_proj * ndc;
48 pos /= pos.w;
49 pos.w = 1.0;
50 return pos;
51}
52
53//calculate decreases in ambient lighting when crowded out (SSAO)
54float calcAmbientOcclusion(vec4 pos, vec3 norm)
55{
56 vec2 kern[8];
57 // exponentially (^2) distant occlusion samples spread around origin
58 kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
59 kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
60 kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
61 kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
62 kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
63 kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
64 kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
65 kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
66
67 vec2 pos_screen = vary_fragcoord.xy;
68 vec3 pos_world = pos.xyz;
69 vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
70
71 float angle_hidden = 0.0;
72 int points = 0;
73
74 float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
75
76 // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?)
77 for (int i = 0; i < 8; i++)
78 {
79 vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect);
80 vec3 samppos_world = getPosition(samppos_screen).xyz;
81
82 vec3 diff = pos_world - samppos_world;
83 float dist2 = dot(diff, diff);
84
85 // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
86 // --> solid angle shrinking by the square of distance
87 //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
88 //(k should vary inversely with # of samples, but this is taken care of later)
89
90 //if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces
91 // angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor)
92 angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv);
93
94 // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
95 points = points + int(diff.z > -1.0);
96 }
97
98 angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0);
99
100 return (1.0 - (float(points != 0) * angle_hidden));
101}
102
103void main()
104{
105 vec2 pos_screen = vary_fragcoord.xy;
106
107 //try doing an unproject here
108
109 vec4 pos = getPosition(pos_screen);
110
111 vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0;
112
113 /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
114 {
115 gl_FragColor = vec4(0.0); // doesn't matter
116 return;
117 }*/
118
119 float shadow = 1.0;
120 float dp_directional_light = max(0.0, dot(norm, vary_light.xyz));
121
122 vec4 spos = vec4(pos.xyz + norm.xyz * (-pos.z/64.0*shadow_offset+shadow_bias), 1.0);
123
124 //vec3 debug = vec3(0,0,0);
125
126 if (spos.z > -shadow_clip.w)
127 {
128 if (dp_directional_light == 0.0)
129 {
130 // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup
131 shadow = 0.0;
132 }
133 else
134 {
135 vec4 lpos;
136
137 if (spos.z < -shadow_clip.z)
138 {
139 lpos = shadow_matrix[3]*spos;
140 lpos.xy *= screen_res;
141 shadow = shadow2DRectProj(shadowMap3, lpos).x;
142 shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
143 }
144 else if (spos.z < -shadow_clip.y)
145 {
146 lpos = shadow_matrix[2]*spos;
147 lpos.xy *= screen_res;
148 shadow = shadow2DRectProj(shadowMap2, lpos).x;
149 }
150 else if (spos.z < -shadow_clip.x)
151 {
152 lpos = shadow_matrix[1]*spos;
153 lpos.xy *= screen_res;
154 shadow = shadow2DRectProj(shadowMap1, lpos).x;
155 }
156 else
157 {
158 lpos = shadow_matrix[0]*spos;
159 lpos.xy *= screen_res;
160 shadow = shadow2DRectProj(shadowMap0, lpos).x;
161 }
162
163 // take the most-shadowed value out of these two:
164 // * the blurred sun shadow in the light (shadow) map
165 // * an unblurred dot product between the sun and this norm
166 // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting
167 shadow = min(shadow, dp_directional_light);
168 }
169
170 /*debug.r = lpos.y / (lpos.w*screen_res.y);
171
172 lpos.xy /= lpos.w*32.0;
173 if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1)
174 {
175 debug.gb = vec2(0.5, 0.5);
176 }
177
178 debug += (1.0-shadow)*0.5;*/
179
180 }
181 else
182 {
183 // more distant than the shadow map covers
184 shadow = 1.0;
185 }
186
187 gl_FragColor[0] = shadow;
188 gl_FragColor[1] = calcAmbientOcclusion(pos, norm);
189
190 //spotlight shadow 1
191 vec4 lpos = shadow_matrix[4]*spos;
192 lpos.xy *= screen_res;
193 gl_FragColor[2] = shadow2DRectProj(shadowMap4, lpos).x;
194
195 //spotlight shadow 2
196 lpos = shadow_matrix[5]*spos;
197 lpos.xy *= screen_res;
198 gl_FragColor[3] = shadow2DRectProj(shadowMap5, lpos).x;
199
200 //gl_FragColor.rgb = pos.xyz;
201 //gl_FragColor.b = shadow;
202 //gl_FragColor.rgb = debug;
203}