diff options
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.glsl | 203 |
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 | |||
10 | uniform sampler2DRect depthMap; | ||
11 | uniform sampler2DRect normalMap; | ||
12 | uniform sampler2DRectShadow shadowMap0; | ||
13 | uniform sampler2DRectShadow shadowMap1; | ||
14 | uniform sampler2DRectShadow shadowMap2; | ||
15 | uniform sampler2DRectShadow shadowMap3; | ||
16 | uniform sampler2DRectShadow shadowMap4; | ||
17 | uniform sampler2DRectShadow shadowMap5; | ||
18 | uniform sampler2D noiseMap; | ||
19 | |||
20 | uniform sampler2D lightFunc; | ||
21 | |||
22 | |||
23 | // Inputs | ||
24 | uniform mat4 shadow_matrix[6]; | ||
25 | uniform vec4 shadow_clip; | ||
26 | uniform float ssao_radius; | ||
27 | uniform float ssao_max_radius; | ||
28 | uniform float ssao_factor; | ||
29 | uniform float ssao_factor_inv; | ||
30 | |||
31 | varying vec2 vary_fragcoord; | ||
32 | varying vec4 vary_light; | ||
33 | |||
34 | uniform mat4 inv_proj; | ||
35 | uniform vec2 screen_res; | ||
36 | |||
37 | uniform float shadow_bias; | ||
38 | uniform float shadow_offset; | ||
39 | |||
40 | vec4 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) | ||
54 | float 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 | |||
103 | void 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 | } | ||