]> git.tdb.fi Git - libs/gl.git/blob - shaderlib/singlepass.glsl
Rename Lighting::sky_direction to zenith_direction
[libs/gl.git] / shaderlib / singlepass.glsl
1 struct LightSourceParameters
2 {
3         vec4 position;
4         vec4 diffuse;
5         vec4 specular;
6 };
7
8 struct MaterialParameters
9 {
10         vec4 ambient;
11         vec4 diffuse;
12         vec4 specular;
13         float shininess;
14 };
15
16 struct ClipPlane
17 {
18         vec4 equation;
19 };
20
21 uniform mat4 eye_obj_matrix;
22 uniform mat3 eye_obj_normal_matrix;
23 uniform Transform
24 {
25         mat4 projection_matrix;
26 };
27
28 uniform Material
29 {
30         MaterialParameters material;
31         float reflectivity;
32 };
33
34 const bool use_vertex_color = false;
35
36 const bool use_lighting = false;
37 const bool use_specular = false;
38 const bool use_sky = false;
39 const bool use_fog = false;
40 uniform Lighting
41 {
42         // Declared as an array for compatibility reasons
43         LightSourceParameters light_sources[1];
44         vec4 ambient_color;
45         vec4 sky_color;
46         vec3 eye_zenith_dir;
47         float horizon_limit;
48         vec4 fog_color;
49         float fog_density;
50 };
51
52 const bool use_diffuse_map = false;
53 uniform sampler2D diffuse_map;
54
55 const bool use_normal_map = false;
56 uniform sampler2D normal_map;
57
58 const bool use_shadow_map = false;
59 uniform sampler2DShadow shadow;
60 uniform ShadowMap
61 {
62         float shadow_darkness;
63         mat4 shd_eye_matrix;
64 };
65
66 const bool use_environment_map = false;
67 uniform samplerCube environment;
68 uniform EnvMap
69 {
70         mat3 env_eye_matrix;
71 };
72
73 const int max_clip_planes = 0;
74 uniform Clipping
75 {
76         ClipPlane clip_planes[max_clip_planes];
77 };
78
79 ////// vertex
80 layout(location=0) in vec4 vertex;
81 layout(location=8) in vec4 texcoord;
82 layout(location=3) in vec4 color;
83 layout(location=2) in vec3 normal;
84 layout(location=4) in vec3 tangent;
85 layout(location=5) in vec3 binormal;
86
87 vec4 get_vertex_position()
88 {
89         return vertex;
90 }
91
92 vec3 get_vertex_normal()
93 {
94         return normal;
95 }
96
97 void singlepass_transform_and_lighting()
98 {
99         out vec4 eye_vertex = eye_obj_matrix*get_vertex_position();
100         gl_Position = projection_matrix*eye_vertex;
101
102         out vec3 eye_normal = eye_obj_normal_matrix*get_vertex_normal();
103         vec3 eye_tangent = eye_obj_normal_matrix*tangent;
104         vec3 eye_binormal = eye_obj_normal_matrix*binormal;
105         out mat3 eye_tbn_matrix = mat3(eye_tangent, eye_binormal, eye_normal);
106
107         out vec3 incident_dir = normalize(eye_vertex.xyz);
108         if(use_normal_map)
109                 incident_dir = incident_dir*eye_tbn_matrix;
110
111         vec3 ldir = normalize(light_sources[0].position.xyz-eye_vertex.xyz*light_sources[0].position.w);
112         if(use_normal_map)
113                 ldir = ldir*eye_tbn_matrix;
114         out vec3 light_dir = ldir;
115
116         out vec3 tbn_zenith_dir = eye_zenith_dir*eye_tbn_matrix;
117         out vec3 shadow_coord = (shd_eye_matrix*eye_vertex).xyz;
118         out float fog_coord = eye_vertex.z;
119
120         for(int i=0; i<max_clip_planes; ++i)
121                 gl_ClipDistance[i] = dot(eye_vertex, clip_planes[i].equation);
122 }
123
124 void main()
125 {
126         singlepass_transform_and_lighting();
127         passthrough;
128 }
129
130 ////// fragment
131 layout(location=0) out vec4 frag_color;
132
133 vec4 get_diffuse_sample()
134 {
135         return texture(diffuse_map, texcoord.xy);
136 }
137
138 vec3 get_normal_sample()
139 {
140         return texture(normal_map, texcoord.xy).xyz*2.0-1.0;
141 }
142
143 vec4 get_environment_sample(vec3 direction)
144 {
145         return texture(environment, direction);
146 }
147
148 vec3 normal;
149 vec4 diffuse_sample;
150
151 vec3 singlepass_lighting()
152 {
153         float shadow_sample = texture(shadow, shadow_coord);
154         float shadow_intensity = mix(1.0, shadow_sample, shadow_darkness);
155
156         vec3 ambient_light = ambient_color.rgb;
157         if(use_sky)
158         {
159                 vec3 zenith_dir;
160                 if(use_normal_map)
161                         zenith_dir = tbn_zenith_dir;
162                 else
163                         zenith_dir = eye_zenith_dir;
164                 float skylight_intensity = dot(normal, zenith_dir)*0.5+0.5;
165                 ambient_light += skylight_intensity*sky_color.rgb;
166         }
167
168         vec3 n_light_dir = normalize(light_dir);
169         float diffuse_intensity = max(dot(normal, n_light_dir), 0.0);
170         if(use_shadow_map)
171                 diffuse_intensity *= shadow_intensity;
172         vec3 diffuse_light = diffuse_intensity*light_sources[0].diffuse.rgb;
173
174         vec3 half_vec = normalize(light_dir-incident_dir);
175         float specular_intensity = pow(max(dot(half_vec, normal), 0.0), material.shininess);
176         if(use_shadow_map)
177                 specular_intensity *= shadow_intensity;
178         vec3 specular_light = specular_intensity*light_sources[0].specular.rgb;
179
180         vec3 result = material.ambient.rgb*ambient_light+material.diffuse.rgb*diffuse_light;
181         if(use_diffuse_map)
182                 result *= diffuse_sample.rgb;
183         if(use_specular)
184                 result += material.specular.rgb*specular_light;
185
186         return result;
187 }
188
189 float singlepass_transparency()
190 {
191         float alpha = material.diffuse.a;
192         if(use_diffuse_map)
193                 alpha *= diffuse_sample.a;
194         return alpha;
195 }
196
197 vec3 singlepass_reflection()
198 {
199         vec3 reflect_dir = reflect(incident_dir, normal);
200         if(use_normal_map)
201                 reflect_dir = eye_tbn_matrix*reflect_dir;
202
203         return get_environment_sample(env_eye_matrix*reflect_dir).rgb;
204 }
205
206 vec4 singlepass_color()
207 {
208         vec4 result = vec4(1.0);
209         if(use_vertex_color)
210                 result *= color;
211         if(use_diffuse_map)
212                 result *= get_diffuse_sample();
213         return result;
214 }
215
216 void main()
217 {
218         if(use_normal_map)
219                 normal = get_normal_sample();
220         else
221                 normal = normalize(eye_normal);
222
223         diffuse_sample = get_diffuse_sample();
224
225         vec4 final_color;
226         if(use_lighting)
227                 final_color = vec4(singlepass_lighting(), singlepass_transparency());
228         else
229                 final_color = singlepass_color();
230
231         if(use_environment_map)
232                 final_color += vec4(singlepass_reflection(), 0.0);
233         if(use_fog)
234         {
235                 float fog_value = exp(fog_coord*fog_density);
236                 final_color = vec4(mix(fog_color.rgb, final_color.rgb, fog_value), final_color.a);
237         }
238
239         frag_color = final_color;
240 }