/* * lighting.frag * * Lighting calculations * * (c) 2007-2008 Thomas White * * thrust3d - a silly game * */ varying vec3 pos; varying vec3 normal; varying vec3 light0vc; varying vec3 light0half; varying vec3 light1vc; varying vec3 light2vc; varying vec3 light2hvc; uniform sampler2D texture; uniform sampler2D normalmap; uniform bool has_normals; uniform bool fill_light_enabled; uniform bool texture_enabled; uniform bool texture_emits; uniform float alpha; varying vec3 col_ambi_diff; varying vec3 col_emit; void main() { vec3 ambi; vec3 emit; vec3 diff = vec3(0.0, 0.0, 0.0); vec3 spec = vec3(0.0, 0.0, 0.0); vec3 norm = normal; if ( has_normals ) { norm += (texture2D(normalmap, gl_TexCoord[0].st).rgb - vec3(0.5, 0.5, 0.5)) / 2.0; } norm = normalize(norm); /* Ambient */ ambi = col_ambi_diff * gl_LightModel.ambient.rgb; /* Emission */ emit = col_emit; /* Fill-in light (light 2) */ if ( fill_light_enabled ) { float ndothv; ndothv = max(dot(norm, normalize(light2hvc)), 0.0); diff += col_ambi_diff * gl_LightSource[2].diffuse.rgb * max(dot(vec3(light1vc), norm), 0.0); spec += gl_LightSource[2].specular.rgb * pow(ndothv, 80.0); } else { /* Spotlight (light 0) - positional, spotlight */ float falloff, spot; float spec_fac; vec3 L, E, R; falloff = 1.0 / ( gl_LightSource[0].constantAttenuation + gl_LightSource[0].linearAttenuation * length(light0vc) + gl_LightSource[0].quadraticAttenuation * pow(length(light0vc), 2.0) ); spot = max(dot(normalize(-light0vc), gl_LightSource[0].spotDirection), 0.0); spot = pow(spot, gl_LightSource[0].spotExponent); L = normalize(gl_LightSource[0].position.xyz - pos); E = normalize(-pos); R = normalize(-reflect(L, norm)); spec_fac = max(0.0, dot(R, E)); diff += col_ambi_diff * gl_LightSource[0].diffuse.rgb * spot * falloff * max(dot(normalize(light0vc).xyz, norm), 0.0); spec += vec3(1.0, 1.0, 1.0) * gl_LightSource[0].specular.rgb * spot * falloff * pow(spec_fac, 80.0); /* Background glow (light 1) - diffuse only, directional */ diff += col_ambi_diff * gl_LightSource[1].diffuse.rgb * max(dot(vec3(light1vc), norm), 0.0); } if ( texture_enabled ) { vec3 tex = texture2D(texture, gl_TexCoord[0].st).rgb; if ( texture_emits ) { gl_FragColor = vec4(tex.r, tex.g, tex.b, alpha); } else { gl_FragColor = vec4(min(tex.r * (ambi.r + diff.r) + spec.r, 1.0), min(tex.g * (ambi.g + diff.g) + spec.g, 1.0), min(tex.b * (ambi.b + diff.b) + spec.b, 1.0), alpha); } } else { gl_FragColor = vec4(min(emit.r + ambi.r + diff.r + spec.r, 1.0), min(emit.g + ambi.g + diff.g + spec.g, 1.0), min(emit.b + ambi.b + diff.b + spec.b, 1.0), alpha); } }