]> git.tdb.fi Git - libs/gl.git/blob - shaderlib/singlepass.glsl
Add a builtin module for standard shaders
[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_sky_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_reflection = false;
67 const bool use_environment_map = false;
68 uniform samplerCube environment;
69 uniform EnvMap
70 {
71         mat3 env_eye_matrix;
72 };
73
74 const int max_clip_planes = 0;
75 uniform Clipping
76 {
77         ClipPlane clip_planes[max_clip_planes];
78 };
79
80 ////// vertex
81 in vec4 vertex;
82 in vec4 texcoord;
83 in vec4 color;
84 in vec3 normal;
85 in vec3 tangent;
86 in vec3 binormal;
87
88 vec4 get_vertex_position()
89 {
90         return vertex;
91 }
92
93 vec3 get_vertex_normal()
94 {
95         return normal;
96 }
97
98 void singlepass_transform_and_lighting()
99 {
100         out vec4 eye_vertex = eye_obj_matrix*get_vertex_position();
101         gl_Position = projection_matrix*eye_vertex;
102
103         out vec3 eye_normal = eye_obj_normal_matrix*get_vertex_normal();
104         vec3 eye_tangent = eye_obj_normal_matrix*tangent;
105         vec3 eye_binormal = eye_obj_normal_matrix*binormal;
106         out mat3 eye_tbn_matrix = mat3(eye_tangent, eye_binormal, eye_normal);
107
108         out vec3 incident_dir = normalize(eye_vertex.xyz);
109         if(use_normal_map)
110                 incident_dir = incident_dir*eye_tbn_matrix;
111
112         vec3 ldir = normalize(light_sources[0].position.xyz-eye_vertex.xyz*light_sources[0].position.w);
113         if(use_normal_map)
114                 ldir = ldir*eye_tbn_matrix;
115         out vec3 light_dir = ldir;
116
117         out vec3 tbn_sky_dir = eye_sky_dir*eye_tbn_matrix;
118         out vec3 shadow_coord = (shd_eye_matrix*eye_vertex).xyz;
119         out float fog_coord = eye_vertex.z;
120
121         for(int i=0; i<max_clip_planes; ++i)
122                 gl_ClipDistance[i] = dot(eye_vertex, clip_planes[i].equation);
123 }
124
125 void main()
126 {
127         singlepass_transform_and_lighting();
128         passthrough;
129 }
130
131 ////// fragment
132 out vec4 frag_color;
133
134 vec4 get_diffuse_sample()
135 {
136         return texture(diffuse_map, texcoord.xy);
137 }
138
139 vec3 get_normal_sample()
140 {
141         return texture(normal_map, texcoord.xy).xyz*2.0-1.0;
142 }
143
144 vec3 normal;
145 vec4 diffuse_sample;
146
147 vec3 singlepass_lighting()
148 {
149         float shadow_sample = texture(shadow, shadow_coord);
150         float shadow_intensity = mix(1.0, shadow_sample, shadow_darkness);
151
152         vec3 ambient_light = ambient_color.rgb;
153         if(use_sky)
154         {
155                 vec3 sky_dir;
156                 if(use_normal_map)
157                         sky_dir = tbn_sky_dir;
158                 else
159                         sky_dir = eye_sky_dir;
160                 float skylight_intensity = dot(normal, sky_dir)*0.5+0.5;
161                 ambient_light += skylight_intensity*sky_color.rgb;
162         }
163
164         vec3 n_light_dir = normalize(light_dir);
165         float diffuse_intensity = max(dot(normal, n_light_dir), 0.0);
166         if(use_shadow_map)
167                 diffuse_intensity *= shadow_intensity;
168         vec3 diffuse_light = diffuse_intensity*light_sources[0].diffuse.rgb;
169
170         vec3 half_vec = normalize(light_dir-incident_dir);
171         float specular_intensity = pow(max(dot(half_vec, normal), 0.0), material.shininess);
172         if(use_shadow_map)
173                 specular_intensity *= shadow_intensity;
174         vec3 specular_light = specular_intensity*light_sources[0].specular.rgb;
175
176         vec3 result = material.ambient.rgb*ambient_light+material.diffuse.rgb*diffuse_light;
177         if(use_diffuse_map)
178                 result *= diffuse_sample.rgb;
179         if(use_specular)
180                 result += material.specular.rgb*specular_light;
181
182         return result;
183 }
184
185 float singlepass_transparency()
186 {
187         float alpha = material.diffuse.a;
188         if(use_diffuse_map)
189                 alpha *= diffuse_sample.a;
190         return alpha;
191 }
192
193 vec3 singlepass_reflection()
194 {
195         vec3 reflect_dir = reflect(incident_dir, normal);
196         if(use_normal_map)
197                 reflect_dir = eye_tbn_matrix*reflect_dir;
198         vec3 result = vec3(0.0);
199
200         if(use_environment_map)
201                 result += texture(environment, env_eye_matrix*reflect_dir).rgb*reflectivity;
202
203         if(use_sky && use_specular)
204         {
205                 float reflect_altitude = clamp(dot(reflect_dir, eye_sky_dir)-horizon_limit, -1.0, 0.0);
206                 float sky_specular_intensity = pow((1.0-reflect_altitude*reflect_altitude), material.shininess/2.0);
207                 result += sky_specular_intensity*sky_color.rgb;
208         }
209
210         return result;
211 }
212
213 vec4 singlepass_color()
214 {
215         vec4 result = vec4(1.0);
216         if(use_vertex_color)
217                 result *= color;
218         if(use_diffuse_map)
219                 result *= get_diffuse_sample();
220         return result;
221 }
222
223 void main()
224 {
225         if(use_normal_map)
226                 normal = get_normal_sample();
227         else
228                 normal = normalize(eye_normal);
229
230         diffuse_sample = get_diffuse_sample();
231
232         vec4 final_color;
233         if(use_lighting)
234                 final_color = vec4(singlepass_lighting(), singlepass_transparency());
235         else
236                 final_color = singlepass_color();
237
238         if(use_reflection)
239                 final_color += vec4(singlepass_reflection(), 0.0);
240         if(use_fog)
241         {
242                 float fog_value = exp(fog_coord*fog_density);
243                 final_color = vec4(mix(fog_color.rgb, final_color.rgb, fog_value), final_color.a);
244         }
245
246         frag_color = final_color;
247 }