@module lightning @vs vs in vec4 coord; out vec2 texUV; void main() { gl_Position = vec4(coord.xy, 0.0, 1.0); texUV = coord.zw; } @end @fs fs uniform uniforms { float iTime; }; in vec2 texUV; out vec4 fragColor; vec4 permute(vec4 t) { return t * (t * 34.0 + 133.0); } // Gradient set is a normalized expanded rhombic dodecahedron vec3 grad(float hash) { // Random vertex of a cube, +/- 1 each vec3 cube = mod(floor(hash / vec3(1.0, 2.0, 4.0)), 2.0) * 2.0 - 1.0; // Random edge of the three edges connected to that vertex // Also a cuboctahedral vertex // And corresponds to the face of its dual, the rhombic dodecahedron vec3 cuboct = cube; int selected_edge =int(hash / 16.0) ; if(selected_edge == 0) cuboct.x = 0.0; if(selected_edge == 1) cuboct.y = 0.0; if(selected_edge == 2) cuboct.z = 0.0; // In a funky way, pick one of the four points on the rhombic face float type = mod(floor(hash / 8.0), 2.0); vec3 rhomb = (1.0 - type) * cube + type * (cuboct + cross(cube, cuboct)); // Expand it so that the new edges are the same length // as the existing ones vec3 grad = cuboct * 1.22474487139 + rhomb; // To make all gradients the same length, we only need to shorten the // second type of vector. We also put in the whole noise scale constant. // The compiler should reduce it into the existing floats. I think. grad *= (1.0 - 0.042942436724648037 * type) * 3.5946317686139184; return grad; } // BCC lattice split up into 2 cube lattices vec4 bccNoiseDerivativesPart(vec3 X) { vec3 b = floor(X); vec4 i4 = vec4(X - b, 2.5); // Pick between each pair of oppposite corners in the cube. vec3 v1 = b + floor(dot(i4, vec4(.25))); vec3 v2 = b + vec3(1, 0, 0) + vec3(-1, 1, 1) * floor(dot(i4, vec4(-.25, .25, .25, .35))); vec3 v3 = b + vec3(0, 1, 0) + vec3(1, -1, 1) * floor(dot(i4, vec4(.25, -.25, .25, .35))); vec3 v4 = b + vec3(0, 0, 1) + vec3(1, 1, -1) * floor(dot(i4, vec4(.25, .25, -.25, .35))); // Gradient hashes for the four vertices in this half-lattice. vec4 hashes = permute(mod(vec4(v1.x, v2.x, v3.x, v4.x), 289.0)); hashes = permute(mod(hashes + vec4(v1.y, v2.y, v3.y, v4.y), 289.0)); hashes = mod(permute(mod(hashes + vec4(v1.z, v2.z, v3.z, v4.z), 289.0)), 48.0); // Gradient extrapolations & kernel function vec3 d1 = X - v1; vec3 d2 = X - v2; vec3 d3 = X - v3; vec3 d4 = X - v4; vec4 a = max(0.75 - vec4(dot(d1, d1), dot(d2, d2), dot(d3, d3), dot(d4, d4)), 0.0); vec4 aa = a * a; vec4 aaaa = aa * aa; vec3 g1 = grad(hashes.x); vec3 g2 = grad(hashes.y); vec3 g3 = grad(hashes.z); vec3 g4 = grad(hashes.w); vec4 extrapolations = vec4(dot(d1, g1), dot(d2, g2), dot(d3, g3), dot(d4, g4)); // Derivatives of the noise vec3 derivative = -8.0 * mat4x3(d1, d2, d3, d4) * (aa * a * extrapolations) + mat4x3(g1, g2, g3, g4) * aaaa; // Return it all as a vec4 return vec4(derivative, dot(aaaa, extrapolations)); } // Gives X and Y a triangular alignment, and lets Z move up the main diagonal. // Might be good for terrain, or a time varying X/Y plane. Z repeats. vec4 bccNoiseDerivatives_XYBeforeZ(vec3 X) { // Not a skew transform. mat3 orthonormalMap = mat3( 0.788675134594813, -0.211324865405187, -0.577350269189626, -0.211324865405187, 0.788675134594813, -0.577350269189626, 0.577350269189626, 0.577350269189626, 0.577350269189626); X = orthonormalMap * X; vec4 result = bccNoiseDerivativesPart(X) + bccNoiseDerivativesPart(X + 144.5); return vec4(result.xyz * orthonormalMap, result.w); } void main() { vec2 uv = texUV; vec2 p = uv; uv = uv * 2. -1.; float tickle = 0.001*1000*iTime; vec3 offset = vec3(cos(tickle), sin(tickle), 0.0); vec3 p3 = vec3(p, 0.0) + offset; vec3 noise_input = vec3(p3*25.0+12.0); //float intensity = noise(noise_input); float intensity = 0.0; intensity += bccNoiseDerivatives_XYBeforeZ(noise_input).w*0.4; intensity += bccNoiseDerivatives_XYBeforeZ(noise_input*0.55).w*0.7; intensity += bccNoiseDerivatives_XYBeforeZ(noise_input*0.44).w*0.8; float t = clamp((uv.x * -uv.x * 0.16) + 0.15, 0., 1.); //fragColor.rgb = vec3(t); float dist = length(uv); float y = abs(dist - 0.5 - intensity * 0.1); float g = pow(y, 0.2); vec3 col = vec3(1.50, 1.48, 1.78); col = col * -g + col; col = col * col; col = col * col; fragColor.rgb = col; fragColor.a = (col.r + col.g + col.b)/3.0; } @end @program program vs fs