varying vec3 n, l, h; varying vec2 t[2]; varying float z; #vertex uniform vec2 offs; uniform vec3 spk[9]; uniform float zatt; const vec2 dx = vec2(0.00390625, 0.0); const vec2 dy = vec2(0.0, 0.00390625); vec3 smpl(in vec2 v) { float r, h = 0.0; int i; for (i = 0; i < 9; ++i) { r = min(length(v - spk[i].xy), 1.0); h += (1.0 - r * r * (3.0 - 2.0 * r)) * spk[i].z; } return vec3(v, h); } void main() { // compute vertex position vec4 v = vec4(smpl(gl_Vertex.xy), 1.0) + vec4(offs, 0.0, 0.0); // generate texture coordinates t[0] = 0.07 * v.xy; t[1] = 0.84 * v.xy; // transform vertex v = gl_ModelViewMatrix * v; gl_Position = gl_ProjectionMatrix * v; // compute depth z = 1.0 - (v.z + zatt) * (1.0 / zatt); z = 1.0 - z * z; // compute vertex normal n = normalize(gl_NormalMatrix * cross(smpl(gl_Vertex.xy + dx) - smpl(gl_Vertex.xy - dx), smpl(gl_Vertex.xy + dy) - smpl(gl_Vertex.xy - dy))); // light direction, half vector l = normalize(vec3(gl_LightSource[0].position) - v.xyz); h = normalize(gl_LightSource[0].halfVector.xyz); // the rest gl_FrontColor = gl_Color; } #fragment uniform sampler2D tex; vec3 ns(in vec2 c) { return texture2D(tex, c).xyz - vec3(0.5, 0.5, 0.5); } void main() { float d; vec3 nn; vec4 col = gl_Color * gl_LightModel.ambient; // lighting nn = normalize(n + ns(t[0]) + 0.5 * ns(t[1])); d = dot(nn, normalize(l)); if (d > 0.0) { col += gl_Color * d; col += gl_FrontMaterial.specular * pow(max(dot(nn, normalize(h)), 0.000001), gl_FrontMaterial.shininess); } gl_FragColor = z * col; }