]> git.tdb.fi Git - libs/gl.git/commitdiff
Add a new, better structured Phong shader
authorMikko Rasa <tdb@tdb.fi>
Thu, 4 Jun 2020 21:04:53 +0000 (00:04 +0300)
committerMikko Rasa <tdb@tdb.fi>
Thu, 11 Jun 2020 15:38:43 +0000 (18:38 +0300)
shaderlib/common.glsl [new file with mode: 0644]
shaderlib/msp_interface.glsl
shaderlib/phong.glsl [new file with mode: 0644]
shaderlib/shadow.glsl [new file with mode: 0644]
shaderlib/singlepass.glsl

diff --git a/shaderlib/common.glsl b/shaderlib/common.glsl
new file mode 100644 (file)
index 0000000..7222b00
--- /dev/null
@@ -0,0 +1,94 @@
+import msp_interface;
+import shadow;
+
+const bool use_normal_map = false;
+
+#pragma MSP stage(vertex)
+vec4 get_vertex_position()
+{
+       return vertex;
+}
+
+vec3 get_vertex_normal()
+{
+       return normal;
+}
+
+vec4 transform_position(vec4 pos)
+{
+       return eye_obj_matrix*pos;
+}
+
+vec3 transform_normal(vec3 nor)
+{
+       return eye_obj_normal_matrix*nor;
+}
+
+void standard_transform()
+{
+       out vec4 eye_vertex = transform_position(get_vertex_position());
+       gl_Position = projection_matrix*eye_vertex;
+
+       out vec3 eye_normal = transform_normal(get_vertex_normal());
+       vec3 eye_tangent = transform_normal(tangent);
+       vec3 eye_binormal = transform_normal(binormal);
+       out mat3 eye_tbn_matrix = mat3(eye_tangent, eye_binormal, eye_normal);
+
+       out vec3 eye_look_dir = normalize(eye_vertex.xyz);
+       out vec3 tbn_look_dir = eye_look_dir*eye_tbn_matrix;
+
+       out vec3 eye_light_dir = normalize(light_sources[0].position.xyz-eye_vertex.xyz*light_sources[0].position.w);
+       out vec3 tbn_light_dir = eye_light_dir*eye_tbn_matrix;
+
+       out vec3 eye_halfway_dir = normalize(eye_light_dir-eye_look_dir);
+       out vec3 tbn_halfway_dir = eye_halfway_dir*eye_tbn_matrix;
+
+       out vec3 tbn_zenith_dir = eye_zenith_dir*eye_tbn_matrix;
+       out vec3 shadow_coord = (shd_eye_matrix*eye_vertex).xyz;
+       out float fog_coord = eye_vertex.z;
+
+       for(int i=0; i<max_clip_planes; ++i)
+               gl_ClipDistance[i] = dot(eye_vertex, clip_planes[i].equation);
+
+       shadow_transform(eye_vertex);
+}
+
+void custom_transform()
+{
+}
+
+void main()
+{
+       standard_transform();
+       custom_transform();
+       passthrough;
+}
+
+#pragma MSP stage(fragment)
+vec3 get_normal_sample()
+{
+       if(use_normal_map)
+               return texture(normal_map, texcoord.xy).xyz*2.0-1.0;
+       else
+               return vec3(0.0, 0.0, 1.0);
+}
+
+vec4 get_environment_sample(vec3 direction)
+{
+       return texture(environment, direction);
+}
+
+vec3 get_reflection(vec3 normal, vec3 look)
+{
+       vec3 reflect_dir = reflect(look, normal);
+       if(use_normal_map)
+               reflect_dir = eye_tbn_matrix*reflect_dir;
+
+       return get_environment_sample(env_eye_matrix*reflect_dir).rgb;
+}
+
+vec3 apply_fog(vec3 color)
+{
+       float fog_value = exp(fog_coord*fog_density);
+       return mix(fog_color, color, fog_value);
+}
index 6a8ee8d8f63713260ff05b98879b8e7f30644505..b1b887ea68a92b3f11a308d0895e503473cf8f61 100644 (file)
@@ -50,7 +50,7 @@ uniform sampler2D shininess_map;
 uniform sampler2D emission_map;
 uniform sampler2D normal_map;
 
-uniform sampler2DShadow shadow;
+uniform sampler2DShadow shadow_map;
 uniform ShadowMap
 {
        float shadow_darkness;
diff --git a/shaderlib/phong.glsl b/shaderlib/phong.glsl
new file mode 100644 (file)
index 0000000..e3b97f5
--- /dev/null
@@ -0,0 +1,120 @@
+import msp_interface;
+import common;
+import shadow;
+
+const bool use_diffuse_map = false;
+const bool use_specular = false;
+const bool use_specular_map = false;
+const bool use_shininess_map = false;
+const bool use_emission = false;
+const bool use_emission_map = false;
+const bool use_reflectivity = false;
+const bool use_reflectivity_map = false;
+const bool use_sky = false;
+const bool use_fog = false;
+
+#pragma MSP stage(fragment)
+vec4 get_diffuse_color()
+{
+       if(use_diffuse_map)
+               return texture(diffuse_map, texcoord.xy);
+       else
+               return basic_material.diffuse;
+}
+
+vec3 get_specular_color()
+{
+       if(use_specular_map)
+               return texture(specular_map, texcoord.xy).rgb;
+       else
+               return basic_material.specular.rgb;
+}
+
+float get_shininess_value()
+{
+       if(use_shininess_map)
+               return texture(shininess_map, texcoord.xy).r*255.0;
+       else
+               return basic_material.shininess;
+}
+
+vec3 get_emission_color()
+{
+       if(use_emission_map)
+               return texture(emission_map, texcoord.xy).rgb;
+       else
+               return basic_material.emission.rgb;
+}
+
+float get_reflectivity_value()
+{
+       if(use_reflectivity_map)
+               return texture(reflectivity_map, texcoord.xy).r;
+       else
+               return basic_material.reflectivity;
+}
+
+vec3 phong_ambient(vec3 surface_diffuse)
+{
+       return ambient_color.rgb*surface_diffuse;
+}
+
+vec3 phong_one_light(vec3 light, vec3 normal, vec3 look, vec3 light_color, vec3 surface_diffuse, vec3 surface_specular, float shininess)
+{
+       float diffuse_intensity = max(dot(light, normal), 0.0);
+       vec3 color = light_color*surface_diffuse*diffuse_intensity;
+       if(use_specular)
+       {
+               /* The light vector points towards the light, so reflected will point
+               towards the surface - but so does the look vector. */
+               vec3 reflected = reflect(light, normal);
+               float specular_intensity = pow(max(dot(reflected, look), 0.0), shininess);
+               color += light_color*surface_specular*specular_intensity;
+       }
+       return color;
+}
+
+vec3 phong_lighting(vec3 normal, vec3 look, vec3 surface_diffuse, vec3 surface_specular, float shininess)
+{
+       vec3 light;
+       if(use_normal_map)
+               light = normalize(tbn_light_dir);
+       else
+               light = normalize(eye_light_dir);
+
+       vec3 color = phong_ambient(surface_diffuse);
+       float shadow = get_shadow_factor(0);
+       color += phong_one_light(light, normal, look, light_sources[0].diffuse.rgb, surface_diffuse, surface_specular, shininess)*shadow;
+
+       if(use_emission)
+               color += get_emission_color();
+
+       if(use_reflectivity)
+               color += get_reflection(normal, look)*get_reflectivity_value();
+
+       return color;
+}
+
+void main()
+{
+       vec3 normal;
+       vec3 look;
+       if(use_normal_map)
+       {
+               normal = get_normal_sample();
+               look = normalize(tbn_look_dir);
+       }
+       else
+       {
+               normal = normalize(eye_normal);
+               look = normalize(eye_look_dir);
+       }
+
+       vec4 surface_diffuse = get_diffuse_color();
+       vec3 surface_specular = get_specular_color();
+       float shininess = get_shininess_value();
+
+       vec3 lit_color = phong_lighting(normal, look, surface_diffuse.rgb, surface_specular, shininess);
+
+       frag_color = vec4(lit_color, surface_diffuse.a);
+}
diff --git a/shaderlib/shadow.glsl b/shaderlib/shadow.glsl
new file mode 100644 (file)
index 0000000..0a20b3a
--- /dev/null
@@ -0,0 +1,21 @@
+import msp_interface;
+
+const bool use_shadow_map = false;
+
+#pragma MSP stage(vertex)
+void shadow_transform(vec4 eye_vertex)
+{
+       out vec3 shadow_coord = (shd_eye_matrix*eye_vertex).xyz;
+}
+
+#pragma MSP stage(fragment)
+float get_shadow_factor(int index)
+{
+       if(use_shadow_map)
+       {
+               float shadow_sample = texture(shadow_map, shadow_coord);
+               return mix(1.0, shadow_sample, shadow_darkness);
+       }
+       else
+               return 1.0;
+}
index ff421ea0287ccfabeacdf651eae590b719c573ac..2de3f6121c71255f4e4bb04a496951cc454bffe3 100644 (file)
@@ -1,3 +1,4 @@
+// Deprecated; use phong.glsl instead.
 import msp_interface;
 
 const bool use_vertex_color = false;
@@ -79,7 +80,7 @@ vec4 diffuse_sample;
 
 vec3 singlepass_lighting()
 {
-       float shadow_sample = texture(shadow, shadow_coord);
+       float shadow_sample = texture(shadow_map, shadow_coord);
        float shadow_intensity = mix(1.0, shadow_sample, shadow_darkness);
 
        vec3 ambient_light = ambient_color.rgb;