varying vec3 r; varying vec4 c; #vertex uniform vec3 eye; uniform vec3 center; uniform float factor; uniform sampler2D spikemap; float sample(in vec3 v) { vec3 r = v; vec3 a = abs(r); float m = max(a.x, max(a.y, a.z)); vec2 o; r /= m; if (m == a.x) { r = r.yzx; o.x = 0.125; } else if (m == a.y) { r = r.xzy; o.x = 0.375; } else `o.x = 0.625; o.y = (r.z >= 0.0) ? 0.25 : 0.75; return texture2D(spikemap, o + r.xy * vec2(0.123076923076923, 0.246153846153846)).r; } vec3 trans(in vec3 v, in float e) { vec3 d = v - center; float r = length(d); return center + normalize(d) * mix(r, mix(r, 2.0, factor), e); } vec3 spike(in vec3 v) { return trans(normalize(v), sample(v)); } void main() { vec4 p; vec3 n, t, b; float e; n = gl_Vertex.xyz; e = sample(n); p = vec4(trans(n, e), 1.0); t = vec3(n.y, -n.x, 0.0); t = 0.000621698996452716 * normalize(t - n * dot(n, t)); // ^^^ = 1 / (2 * pi * TEXSIZE) b = cross(n, t); n = normalize(cross(spike(n + t) - spike(n - t), spike(n + b) - spike(n - b))); r = reflect(normalize(eye - p.xyz), n); c = abs(dot(normalize(gl_LightSource[0].position.xyz - vec3(gl_ModelViewMatrix * p)), normalize(gl_NormalMatrix * n))) * vec4(0.2, 0.0, 0.0, 0.0) + vec4(0.3, 0.0, 0.0, 1.0); e = 1.0 - e; c *= 1.0 - e * e; gl_Position = gl_ModelViewProjectionMatrix * p; } #fragment uniform samplerCube cubemap; void main() { gl_FragColor = c + textureCube(cubemap, r); }