=== added file 'data/shaders/light-cel.frag'
@@ -0,0 +1,60 @@
+varying vec3 vertex_normal;
+varying vec4 vertex_position;
+
+void main(void)
+{
+ const vec4 OutlineColor = vec4(0.0, 0.0, 0.0, 1.0);
+ const vec2 OutlineThickness = vec2(0.1, 0.4);
+ const vec4 BaseColor = vec4(0.0, 0.3, 0.0, 1.0);
+ const vec4 LightColor = vec4(1.0, 1.0, 1.0, 1.0);
+ const vec4 LightSourcePosition = vec4(4.0, 3.0, 1.0, 1.0);
+ const vec4 DiffuseColor = vec4(0.0, 0.6, 0.0, 1.0);
+ const vec4 SpecularColor = vec4(1.0, 1.0, 1.0, 0.7);
+ const float DiffuseThreshold = 0.1;
+ const float SpecularThreshold = 0.5;
+ const float Shininess = 10.0;
+
+ // Initialize the fragment color with an unlit value.
+ vec4 fragColor = BaseColor;
+
+ // Set up factors for computing diffuse illumination
+ vec3 vertex_light = LightSourcePosition.xyz - vertex_position.xyz;
+ vec3 N = normalize(vertex_normal);
+ vec3 L = normalize(vertex_light);
+ float NdotL = dot(N, L);
+ float maxNdotL = max(NdotL, 0.0);
+ float attenuation = length(LightSourcePosition) / length(vertex_light);
+
+ // See if we have a diffuse contribution...
+ // This will only be true if the interpolated normal and the light
+ // are pointing in the "same" direction, and the attenuation due to
+ // distance allows enough light for diffuse reflection.
+ if (attenuation * maxNdotL >= DiffuseThreshold) {
+ fragColor = LightColor * DiffuseColor;
+ }
+
+ // See if this fragment is part of the silhouette
+ // If it is facing away from the viewer enough not to get any
+ // diffuse illumination contribution, then it is close enough
+ // to the silouhette to be painted with the outline color rather
+ // than the unlit color.
+ vec3 V = normalize(-vertex_position.xyz);
+ if (dot(V, N) <
+ mix(OutlineThickness.x, OutlineThickness.y, maxNdotL)) {
+ fragColor = LightColor * OutlineColor;
+ }
+
+ // See if we have a specular contribution...
+ // If the interpolated normal direction and the light direction
+ // are facing the "same" direction, and the attenuated specular
+ // intensity is strong enough, then we have a contribution.
+ vec3 R = reflect(-L, N);
+ float specularIntensity = pow(max(0.0, dot(R, V)), Shininess);
+ if (NdotL > 0.0 && attenuation * specularIntensity > SpecularThreshold) {
+ fragColor = SpecularColor.a * LightColor * SpecularColor +
+ (1.0 - SpecularColor.a) * fragColor;
+ }
+
+ // Emit the final color
+ gl_FragColor = vec4(fragColor.xyz, 1.0);
+}
=== modified file 'src/default-benchmarks.h'
@@ -49,6 +49,7 @@
benchmarks.push_back("shading:shading=gouraud");
benchmarks.push_back("shading:shading=blinn-phong-inf");
benchmarks.push_back("shading:shading=phong");
+ benchmarks.push_back("shading:shading=cel");
benchmarks.push_back("bump:bump-render=high-poly");
benchmarks.push_back("bump:bump-render=normals");
benchmarks.push_back("bump:bump-render=height");
=== modified file 'src/scene-shading.cpp'
@@ -59,7 +59,7 @@
}
options_["shading"] = Scene::Option("shading", "gouraud",
"Which shading method to use",
- "gouraud,blinn-phong-inf,phong");
+ "gouraud,blinn-phong-inf,phong,cel");
options_["num-lights"] = Scene::Option("num-lights", "1",
"The number of lights applied to the scene (phong only)");
options_["model"] = Scene::Option("model", "cat", "Which model to use",
@@ -178,6 +178,12 @@
frg_source.add_const("MaterialDiffuse", materialDiffuse);
vtx_source.append_file(vtx_shader_filename);
}
+ else if (shading == "cel") {
+ vtx_shader_filename = GLMARK_DATA_PATH"/shaders/light-phong.vert";
+ frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-cel.frag";
+ vtx_source.append_file(vtx_shader_filename);
+ frg_source.append_file(frg_shader_filename);
+ }
if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
frg_source.str()))