2014-01-29 06:13:40 +00:00
|
|
|
Note that the GPL covers only the arrangement in this file. The actual code
|
|
|
|
is covered by the MIT licence (see LICENCE.txt below).
|
|
|
|
|
|
|
|
This file is just all the shader code presented by Stefan Gustavson
|
|
|
|
collected into one file and split into useable sections with redundant
|
|
|
|
code removed.
|
|
|
|
|
|
|
|
--
|
|
|
|
|
|
|
|
sgustavson.glsl
|
|
|
|
|
|
|
|
GLSL noise functions
|
|
|
|
|
|
|
|
Copyright (C) 2014 Bill Currie <bill@taniwha.org>
|
|
|
|
|
|
|
|
Author: Bill Currie <bill@taniwha.org>
|
|
|
|
Date: 2014/01/29
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to:
|
|
|
|
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
59 Temple Place - Suite 330
|
|
|
|
Boston, MA 02111-1307, USA
|
|
|
|
|
|
|
|
-- LICENCE.txt
|
|
|
|
|
|
|
|
Copyright (C) 2011 by Stefan Gustavson
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
|
|
|
|
-- Math.permute
|
|
|
|
|
|
|
|
vec4 permute(vec4 x)
|
|
|
|
{
|
|
|
|
return mod(((x*34.0)+1.0)*x, 289.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
-- Math.InvSqrt
|
|
|
|
|
|
|
|
vec4 taylorInvSqrt(vec4 r)
|
|
|
|
{
|
|
|
|
return 1.79284291400159 - 0.85373472095314 * r;
|
|
|
|
}
|
|
|
|
|
|
|
|
-- Noise.simplex
|
|
|
|
|
|
|
|
// Description : Array and textureless GLSL 3D simplex noise function.
|
|
|
|
// Author : Ian McEwan, Ashima Arts.
|
|
|
|
// Maintainer : ijm
|
|
|
|
// Lastmod : 20110409 (stegu)
|
|
|
|
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
|
|
|
|
// Distributed under the MIT License. See LICENSE file.
|
|
|
|
|
|
|
|
float snoise(vec3 v)
|
|
|
|
{
|
|
|
|
const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;
|
|
|
|
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
|
|
|
|
|
|
|
|
// First corner
|
|
|
|
vec3 i = floor(v + dot(v, C.yyy) );
|
|
|
|
vec3 x0 = v - i + dot(i, C.xxx) ;
|
|
|
|
|
|
|
|
// Other corners
|
|
|
|
vec3 g = step(x0.yzx, x0.xyz);
|
|
|
|
vec3 l = 1.0 - g;
|
|
|
|
vec3 i1 = min( g.xyz, l.zxy );
|
|
|
|
vec3 i2 = max( g.xyz, l.zxy );
|
|
|
|
|
|
|
|
// x0 = x0 - 0. + 0.0 * C
|
|
|
|
vec3 x1 = x0 - i1 + 1.0 * C.xxx;
|
|
|
|
vec3 x2 = x0 - i2 + 2.0 * C.xxx;
|
|
|
|
vec3 x3 = x0 - 1. + 3.0 * C.xxx;
|
|
|
|
|
|
|
|
// Permutations
|
|
|
|
i = mod(i, 289.0 );
|
|
|
|
vec4 p = permute( permute( permute(
|
|
|
|
i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
|
|
|
|
+ i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
|
|
|
|
+ i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
|
|
|
|
|
|
|
|
// Gradients
|
|
|
|
// ( N*N points uniformly over a square, mapped onto an octahedron.)
|
|
|
|
float n_ = 1.0/7.0; // N=7
|
|
|
|
vec3 ns = n_ * D.wyz - D.xzx;
|
|
|
|
|
|
|
|
vec4 j = p - 49.0 * floor(p * ns.z *ns.z); // mod(p,N*N)
|
|
|
|
|
|
|
|
vec4 x_ = floor(j * ns.z);
|
|
|
|
vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)
|
|
|
|
|
|
|
|
vec4 x = x_ *ns.x + ns.yyyy;
|
|
|
|
vec4 y = y_ *ns.x + ns.yyyy;
|
|
|
|
vec4 h = 1.0 - abs(x) - abs(y);
|
|
|
|
|
|
|
|
vec4 b0 = vec4( x.xy, y.xy );
|
|
|
|
vec4 b1 = vec4( x.zw, y.zw );
|
|
|
|
|
|
|
|
//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
|
|
|
|
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
|
|
|
|
vec4 s0 = floor(b0)*2.0 + 1.0;
|
|
|
|
vec4 s1 = floor(b1)*2.0 + 1.0;
|
|
|
|
vec4 sh = -step(h, vec4(0.0));
|
|
|
|
|
|
|
|
vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
|
|
|
|
vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
|
|
|
|
|
|
|
|
vec3 p0 = vec3(a0.xy,h.x);
|
|
|
|
vec3 p1 = vec3(a0.zw,h.y);
|
|
|
|
vec3 p2 = vec3(a1.xy,h.z);
|
|
|
|
vec3 p3 = vec3(a1.zw,h.w);
|
|
|
|
|
|
|
|
//Normalise gradients
|
|
|
|
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
|
|
|
|
p0 *= norm.x;
|
|
|
|
p1 *= norm.y;
|
|
|
|
p2 *= norm.z;
|
|
|
|
p3 *= norm.w;
|
|
|
|
|
|
|
|
// Mix final noise value
|
|
|
|
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
|
|
|
|
m = m * m;
|
|
|
|
return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
|
|
|
|
dot(p2,x2), dot(p3,x3) ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
-- Vertex.simplex
|
|
|
|
|
|
|
|
uniform float time;
|
|
|
|
varying vec3 vTexCoord3D;
|
|
|
|
|
|
|
|
void main(void) {
|
|
|
|
vTexCoord3D = gl_Vertex.xyz * 4.0 + vec3(0.0, 0.0, time);
|
|
|
|
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
|
|
|
}
|
|
|
|
|
|
|
|
-- Fragment.simplex
|
|
|
|
|
|
|
|
varying vec3 vTexCoord3D;
|
|
|
|
void main( void )
|
|
|
|
{
|
|
|
|
float n = snoise(vTexCoord3D);
|
|
|
|
|
|
|
|
gl_FragColor = vec4(0.5 + 0.6 * vec3(n, n, n), 1.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
-- Vertex.flame
|
|
|
|
|
|
|
|
uniform float time;
|
|
|
|
varying vec3 vTexCoord3D;
|
|
|
|
|
|
|
|
void main(void) {
|
|
|
|
vTexCoord3D = gl_Vertex.xyz * 2.0 + vec3(0.0, 0.0, -time);
|
|
|
|
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
|
|
|
}
|
|
|
|
|
2014-01-29 06:36:16 +00:00
|
|
|
-- Fragment.flame
|
2014-01-29 06:13:40 +00:00
|
|
|
|
|
|
|
varying vec3 vTexCoord3D;
|
|
|
|
void main( void )
|
|
|
|
{
|
|
|
|
float n = abs(snoise(vTexCoord3D));
|
|
|
|
n += 0.5 * abs(snoise(vTexCoord3D * 2.0));
|
|
|
|
n += 0.25 * abs(snoise(vTexCoord3D * 4.0));
|
|
|
|
n += 0.125 * abs(snoise(vTexCoord3D * 8.0));
|
|
|
|
|
|
|
|
gl_FragColor = vec4(vec3(1.5-n, 1.0-n, 0.5-n), 1.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
-- Noise.flow
|
|
|
|
|
|
|
|
// GLSL implementation of 2D "flow noise" as presented
|
|
|
|
// by Ken Perlin and Fabrice Neyret at Siggraph 2001.
|
|
|
|
// (2D simplex noise with analytic derivatives and
|
|
|
|
// in-plane rotation of generating gradients,
|
|
|
|
// in a fractal sum where higher frequencies are
|
|
|
|
// displaced (advected) by lower frequencies in the
|
|
|
|
// direction of their gradient. For details, please
|
|
|
|
// refer to the 2001 paper "Flow Noise" by Perlin and Neyret.)
|
|
|
|
//
|
|
|
|
// Author: Stefan Gustavson (stefan.gustavson@liu.se)
|
|
|
|
// Distributed under the terms of the MIT license.
|
|
|
|
// See LICENSE file for details.
|
|
|
|
//
|
|
|
|
|
|
|
|
// Helper constants
|
|
|
|
#define F2 0.366025403
|
|
|
|
#define G2 0.211324865
|
|
|
|
#define K 0.0243902439 // 1/41
|
|
|
|
|
|
|
|
// Gradient mapping with an extra rotation.
|
|
|
|
vec2 grad2(vec2 p, float rot) {
|
|
|
|
#if 1
|
|
|
|
// Map from a line to a diamond such that a shift maps to a rotation.
|
|
|
|
float u = permute(permute(p.x) + p.y) * K + rot; // Rotate by shift
|
|
|
|
u = 4.0 * fract(u) - 2.0;
|
|
|
|
return vec2(abs(u)-1.0, abs(abs(u+1.0)-2.0)-1.0);
|
|
|
|
#else
|
|
|
|
#define TWOPI 6.28318530718
|
|
|
|
// For more isotropic gradients, sin/cos can be used instead.
|
|
|
|
float u = permute(permute(p.x) + p.y) * K + rot; // Rotate by shift
|
|
|
|
u = fract(u) * TWOPI;
|
|
|
|
return vec2(cos(u), sin(u));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
float srdnoise(in vec2 P, in float rot, out vec2 grad) {
|
|
|
|
|
|
|
|
// Transform input point to the skewed simplex grid
|
|
|
|
vec2 Ps = P + dot(P, vec2(F2));
|
|
|
|
|
|
|
|
// Round down to simplex origin
|
|
|
|
vec2 Pi = floor(Ps);
|
|
|
|
|
|
|
|
// Transform simplex origin back to (x,y) system
|
|
|
|
vec2 P0 = Pi - dot(Pi, vec2(G2));
|
|
|
|
|
|
|
|
// Find (x,y) offsets from simplex origin to first corner
|
|
|
|
vec2 v0 = P - P0;
|
|
|
|
|
|
|
|
// Pick (+x, +y) or (+y, +x) increment sequence
|
|
|
|
vec2 i1 = (v0.x > v0.y) ? vec2(1.0, 0.0) : vec2 (0.0, 1.0);
|
|
|
|
|
|
|
|
// Determine the offsets for the other two corners
|
|
|
|
vec2 v1 = v0 - i1 + G2;
|
|
|
|
vec2 v2 = v0 - 1.0 + 2.0 * G2;
|
|
|
|
|
|
|
|
// Wrap coordinates at 289 to avoid float precision problems
|
|
|
|
Pi = mod(Pi, 289.0);
|
|
|
|
|
|
|
|
// Calculate the circularly symmetric part of each noise wiggle
|
|
|
|
vec3 t = max(0.5 - vec3(dot(v0,v0), dot(v1,v1), dot(v2,v2)), 0.0);
|
|
|
|
vec3 t2 = t*t;
|
|
|
|
vec3 t4 = t2*t2;
|
|
|
|
|
|
|
|
// Calculate the gradients for the three corners
|
|
|
|
vec2 g0 = grad2(Pi, rot);
|
|
|
|
vec2 g1 = grad2(Pi + i1, rot);
|
|
|
|
vec2 g2 = grad2(Pi + 1.0, rot);
|
|
|
|
|
|
|
|
// Compute noise contributions from each corner
|
|
|
|
vec3 gv = vec3(dot(g0,v0), dot(g1,v1), dot(g2,v2)); // ramp: g dot v
|
|
|
|
vec3 n = t4 * gv; // Circular kernel times linear ramp
|
|
|
|
|
|
|
|
// Compute partial derivatives in x and y
|
|
|
|
vec3 temp = t2 * t * gv;
|
|
|
|
vec3 gradx = temp * vec3(v0.x, v1.x, v2.x);
|
|
|
|
vec3 grady = temp * vec3(v0.y, v1.y, v2.y);
|
|
|
|
grad.x = -8.0 * (gradx.x + gradx.y + gradx.z);
|
|
|
|
grad.y = -8.0 * (grady.x + grady.y + grady.z);
|
|
|
|
grad.x += dot(t4, vec3(g0.x, g1.x, g2.x));
|
|
|
|
grad.y += dot(t4, vec3(g0.y, g1.y, g2.y));
|
|
|
|
grad *= 40.0;
|
|
|
|
|
|
|
|
// Add contributions from the three corners and return
|
|
|
|
return 40.0 * (n.x + n.y + n.z);
|
|
|
|
}
|
|
|
|
|
|
|
|
-- Vertex.flow
|
|
|
|
|
|
|
|
varying vec2 vTexCoord2D;
|
|
|
|
|
|
|
|
void main(void) {
|
|
|
|
vTexCoord2D = gl_Vertex.xy * 8.0;
|
|
|
|
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
|
|
|
}
|
|
|
|
|
|
|
|
-- Fragment.flow
|
|
|
|
|
|
|
|
varying vec3 vTexCoord3D;
|
|
|
|
uniform float time;
|
|
|
|
|
|
|
|
void main(void) {
|
|
|
|
vec2 g1, g2;
|
|
|
|
vec2 p = vTexCoord2D;
|
|
|
|
float n1 = srdnoise(p*0.5, 0.2*time, g1);
|
|
|
|
float n2 = srdnoise(p*2.0 + g1*0.5, 0.51*time, g2);
|
|
|
|
float n3 = srdnoise(p*4.0 + g1*0.5 + g2*0.25, 0.77*time, g2);
|
|
|
|
gl_FragColor = vec4(vec3(0.4, 0.5, 0.6) + vec3(n1+0.75*n2+0.5*n3), 1.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
-- Noise.spots
|
|
|
|
|
|
|
|
// Cellular noise ("Worley noise") in 3D in GLSL.
|
|
|
|
// Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved.
|
|
|
|
// This code is released under the conditions of the MIT license.
|
|
|
|
// See LICENSE file for details.
|
|
|
|
|
|
|
|
// Cellular noise, returning F1 and F2 in a vec2.
|
|
|
|
// Speeded up by using 2x2x2 search window instead of 3x3x3,
|
|
|
|
// at the expense of some pattern artifacts.
|
|
|
|
// F2 is often wrong and has sharp discontinuities.
|
|
|
|
// If you need a good F2, use the slower 3x3x3 version.
|
|
|
|
vec2 cellular2x2x2(vec3 P)
|
|
|
|
{
|
|
|
|
#define K 0.142857142857 // 1/7
|
|
|
|
#define Ko 0.428571428571 // 1/2-K/2
|
|
|
|
#define K2 0.020408163265306 // 1/(7*7)
|
|
|
|
#define Kz 0.166666666667 // 1/6
|
|
|
|
#define Kzo 0.416666666667 // 1/2-1/6*2
|
|
|
|
#define jitter 0.8 // smaller jitter gives less errors in F2
|
|
|
|
vec3 Pi = mod(floor(P), 289.0);
|
|
|
|
vec3 Pf = fract(P);
|
|
|
|
vec4 Pfx = Pf.x + vec4(0.0, -1.0, 0.0, -1.0);
|
|
|
|
vec4 Pfy = Pf.y + vec4(0.0, 0.0, -1.0, -1.0);
|
|
|
|
vec4 p = permute(Pi.x + vec4(0.0, 1.0, 0.0, 1.0));
|
|
|
|
p = permute(p + Pi.y + vec4(0.0, 0.0, 1.0, 1.0));
|
|
|
|
vec4 p1 = permute(p + Pi.z); // z+0
|
|
|
|
vec4 p2 = permute(p + Pi.z + vec4(1.0)); // z+1
|
|
|
|
vec4 ox1 = fract(p1*K) - Ko;
|
|
|
|
vec4 oy1 = mod(floor(p1*K), 7.0)*K - Ko;
|
|
|
|
vec4 oz1 = floor(p1*K2)*Kz - Kzo; // p1 < 289 guaranteed
|
|
|
|
vec4 ox2 = fract(p2*K) - Ko;
|
|
|
|
vec4 oy2 = mod(floor(p2*K), 7.0)*K - Ko;
|
|
|
|
vec4 oz2 = floor(p2*K2)*Kz - Kzo;
|
|
|
|
vec4 dx1 = Pfx + jitter*ox1;
|
|
|
|
vec4 dy1 = Pfy + jitter*oy1;
|
|
|
|
vec4 dz1 = Pf.z + jitter*oz1;
|
|
|
|
vec4 dx2 = Pfx + jitter*ox2;
|
|
|
|
vec4 dy2 = Pfy + jitter*oy2;
|
|
|
|
vec4 dz2 = Pf.z - 1.0 + jitter*oz2;
|
|
|
|
vec4 d1 = dx1 * dx1 + dy1 * dy1 + dz1 * dz1; // z+0
|
|
|
|
vec4 d2 = dx2 * dx2 + dy2 * dy2 + dz2 * dz2; // z+1
|
|
|
|
|
|
|
|
// Sort out the two smallest distances (F1, F2)
|
|
|
|
#if 1
|
|
|
|
// Cheat and sort out only F1
|
|
|
|
d1 = min(d1, d2);
|
|
|
|
d1.xy = min(d1.xy, d1.wz);
|
|
|
|
d1.x = min(d1.x, d1.y);
|
|
|
|
return sqrt(d1.xx);
|
|
|
|
#else
|
|
|
|
// Do it right and sort out both F1 and F2
|
|
|
|
vec4 d = min(d1,d2); // F1 is now in d
|
|
|
|
d2 = max(d1,d2); // Make sure we keep all candidates for F2
|
|
|
|
d.xy = (d.x < d.y) ? d.xy : d.yx; // Swap smallest to d.x
|
|
|
|
d.xz = (d.x < d.z) ? d.xz : d.zx;
|
|
|
|
d.xw = (d.x < d.w) ? d.xw : d.wx; // F1 is now in d.x
|
|
|
|
d.yzw = min(d.yzw, d2.yzw); // F2 now not in d2.yzw
|
|
|
|
d.y = min(d.y, d.z); // nor in d.z
|
|
|
|
d.y = min(d.y, d.w); // nor in d.w
|
|
|
|
d.y = min(d.y, d2.x); // F2 is now in d.y
|
|
|
|
return sqrt(d.xy); // F1 and F2
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
-- Vertex.spots
|
|
|
|
|
|
|
|
uniform float time;
|
|
|
|
|
|
|
|
varying vec3 vTexCoord3D;
|
|
|
|
|
|
|
|
void main(void) {
|
|
|
|
vTexCoord3D = gl_Vertex.xyz * 4.0 - vec3(0.0, 0.0, time);
|
|
|
|
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
|
|
|
}
|
|
|
|
|
2014-01-29 06:36:16 +00:00
|
|
|
-- Fragment.spots
|
2014-01-29 06:13:40 +00:00
|
|
|
|
|
|
|
varying vec3 vTexCoord3D;
|
|
|
|
|
|
|
|
void main(void) {
|
|
|
|
vec2 F = cellular2x2x2(vTexCoord3D);
|
|
|
|
float s = fwidth(F.x);
|
|
|
|
float n1 = smoothstep(0.4-s, 0.4+s, F.x);
|
|
|
|
float n2 = smoothstep(0.5-s, 0.5+s, F.x);
|
|
|
|
gl_FragColor = vec4(n1, n2, n2, 1.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
-- Noise.tile
|
|
|
|
|
|
|
|
// Cellular noise ("Worley noise") in 3D in GLSL.
|
|
|
|
// Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved.
|
|
|
|
// This code is released under the conditions of the MIT license.
|
|
|
|
// See LICENSE file for details.
|
|
|
|
|
|
|
|
// Cellular noise, returning F1 and F2 in a vec2.
|
|
|
|
// 3x3x3 search region for good F2 everywhere, but a lot
|
|
|
|
// slower than the 2x2x2 version.
|
|
|
|
// The code below is a bit scary even to its author,
|
|
|
|
// but it has at least half decent performance on a
|
|
|
|
// modern GPU. In any case, it beats any software
|
|
|
|
// implementation of Worley noise hands down.
|
|
|
|
|
|
|
|
vec2 cellular(vec3 P)
|
|
|
|
{
|
|
|
|
#define K 0.142857142857 // 1/7
|
|
|
|
#define Ko 0.428571428571 // 1/2-K/2
|
|
|
|
#define K2 0.020408163265306 // 1/(7*7)
|
|
|
|
#define Kz 0.166666666667 // 1/6
|
|
|
|
#define Kzo 0.416666666667 // 1/2-1/6*2
|
|
|
|
#define jitter 1.0 // smaller jitter gives more regular pattern
|
|
|
|
|
|
|
|
vec3 Pi = mod(floor(P), 289.0);
|
|
|
|
vec3 Pf = fract(P) - 0.5;
|
|
|
|
|
|
|
|
vec3 Pfx = Pf.x + vec3(1.0, 0.0, -1.0);
|
|
|
|
vec3 Pfy = Pf.y + vec3(1.0, 0.0, -1.0);
|
|
|
|
vec3 Pfz = Pf.z + vec3(1.0, 0.0, -1.0);
|
|
|
|
|
|
|
|
vec3 p = permute(Pi.x + vec3(-1.0, 0.0, 1.0));
|
|
|
|
vec3 p1 = permute(p + Pi.y - 1.0);
|
|
|
|
vec3 p2 = permute(p + Pi.y);
|
|
|
|
vec3 p3 = permute(p + Pi.y + 1.0);
|
|
|
|
|
|
|
|
vec3 p11 = permute(p1 + Pi.z - 1.0);
|
|
|
|
vec3 p12 = permute(p1 + Pi.z);
|
|
|
|
vec3 p13 = permute(p1 + Pi.z + 1.0);
|
|
|
|
|
|
|
|
vec3 p21 = permute(p2 + Pi.z - 1.0);
|
|
|
|
vec3 p22 = permute(p2 + Pi.z);
|
|
|
|
vec3 p23 = permute(p2 + Pi.z + 1.0);
|
|
|
|
|
|
|
|
vec3 p31 = permute(p3 + Pi.z - 1.0);
|
|
|
|
vec3 p32 = permute(p3 + Pi.z);
|
|
|
|
vec3 p33 = permute(p3 + Pi.z + 1.0);
|
|
|
|
|
|
|
|
vec3 ox11 = fract(p11*K) - Ko;
|
|
|
|
vec3 oy11 = mod(floor(p11*K), 7.0)*K - Ko;
|
|
|
|
vec3 oz11 = floor(p11*K2)*Kz - Kzo; // p11 < 289 guaranteed
|
|
|
|
|
|
|
|
vec3 ox12 = fract(p12*K) - Ko;
|
|
|
|
vec3 oy12 = mod(floor(p12*K), 7.0)*K - Ko;
|
|
|
|
vec3 oz12 = floor(p12*K2)*Kz - Kzo;
|
|
|
|
|
|
|
|
vec3 ox13 = fract(p13*K) - Ko;
|
|
|
|
vec3 oy13 = mod(floor(p13*K), 7.0)*K - Ko;
|
|
|
|
vec3 oz13 = floor(p13*K2)*Kz - Kzo;
|
|
|
|
|
|
|
|
vec3 ox21 = fract(p21*K) - Ko;
|
|
|
|
vec3 oy21 = mod(floor(p21*K), 7.0)*K - Ko;
|
|
|
|
vec3 oz21 = floor(p21*K2)*Kz - Kzo;
|
|
|
|
|
|
|
|
vec3 ox22 = fract(p22*K) - Ko;
|
|
|
|
vec3 oy22 = mod(floor(p22*K), 7.0)*K - Ko;
|
|
|
|
vec3 oz22 = floor(p22*K2)*Kz - Kzo;
|
|
|
|
|
|
|
|
vec3 ox23 = fract(p23*K) - Ko;
|
|
|
|
vec3 oy23 = mod(floor(p23*K), 7.0)*K - Ko;
|
|
|
|
vec3 oz23 = floor(p23*K2)*Kz - Kzo;
|
|
|
|
|
|
|
|
vec3 ox31 = fract(p31*K) - Ko;
|
|
|
|
vec3 oy31 = mod(floor(p31*K), 7.0)*K - Ko;
|
|
|
|
vec3 oz31 = floor(p31*K2)*Kz - Kzo;
|
|
|
|
|
|
|
|
vec3 ox32 = fract(p32*K) - Ko;
|
|
|
|
vec3 oy32 = mod(floor(p32*K), 7.0)*K - Ko;
|
|
|
|
vec3 oz32 = floor(p32*K2)*Kz - Kzo;
|
|
|
|
|
|
|
|
vec3 ox33 = fract(p33*K) - Ko;
|
|
|
|
vec3 oy33 = mod(floor(p33*K), 7.0)*K - Ko;
|
|
|
|
vec3 oz33 = floor(p33*K2)*Kz - Kzo;
|
|
|
|
|
|
|
|
vec3 dx11 = Pfx + jitter*ox11;
|
|
|
|
vec3 dy11 = Pfy.x + jitter*oy11;
|
|
|
|
vec3 dz11 = Pfz.x + jitter*oz11;
|
|
|
|
|
|
|
|
vec3 dx12 = Pfx + jitter*ox12;
|
|
|
|
vec3 dy12 = Pfy.x + jitter*oy12;
|
|
|
|
vec3 dz12 = Pfz.y + jitter*oz12;
|
|
|
|
|
|
|
|
vec3 dx13 = Pfx + jitter*ox13;
|
|
|
|
vec3 dy13 = Pfy.x + jitter*oy13;
|
|
|
|
vec3 dz13 = Pfz.z + jitter*oz13;
|
|
|
|
|
|
|
|
vec3 dx21 = Pfx + jitter*ox21;
|
|
|
|
vec3 dy21 = Pfy.y + jitter*oy21;
|
|
|
|
vec3 dz21 = Pfz.x + jitter*oz21;
|
|
|
|
|
|
|
|
vec3 dx22 = Pfx + jitter*ox22;
|
|
|
|
vec3 dy22 = Pfy.y + jitter*oy22;
|
|
|
|
vec3 dz22 = Pfz.y + jitter*oz22;
|
|
|
|
|
|
|
|
vec3 dx23 = Pfx + jitter*ox23;
|
|
|
|
vec3 dy23 = Pfy.y + jitter*oy23;
|
|
|
|
vec3 dz23 = Pfz.z + jitter*oz23;
|
|
|
|
|
|
|
|
vec3 dx31 = Pfx + jitter*ox31;
|
|
|
|
vec3 dy31 = Pfy.z + jitter*oy31;
|
|
|
|
vec3 dz31 = Pfz.x + jitter*oz31;
|
|
|
|
|
|
|
|
vec3 dx32 = Pfx + jitter*ox32;
|
|
|
|
vec3 dy32 = Pfy.z + jitter*oy32;
|
|
|
|
vec3 dz32 = Pfz.y + jitter*oz32;
|
|
|
|
|
|
|
|
vec3 dx33 = Pfx + jitter*ox33;
|
|
|
|
vec3 dy33 = Pfy.z + jitter*oy33;
|
|
|
|
vec3 dz33 = Pfz.z + jitter*oz33;
|
|
|
|
|
|
|
|
vec3 d11 = dx11 * dx11 + dy11 * dy11 + dz11 * dz11;
|
|
|
|
vec3 d12 = dx12 * dx12 + dy12 * dy12 + dz12 * dz12;
|
|
|
|
vec3 d13 = dx13 * dx13 + dy13 * dy13 + dz13 * dz13;
|
|
|
|
vec3 d21 = dx21 * dx21 + dy21 * dy21 + dz21 * dz21;
|
|
|
|
vec3 d22 = dx22 * dx22 + dy22 * dy22 + dz22 * dz22;
|
|
|
|
vec3 d23 = dx23 * dx23 + dy23 * dy23 + dz23 * dz23;
|
|
|
|
vec3 d31 = dx31 * dx31 + dy31 * dy31 + dz31 * dz31;
|
|
|
|
vec3 d32 = dx32 * dx32 + dy32 * dy32 + dz32 * dz32;
|
|
|
|
vec3 d33 = dx33 * dx33 + dy33 * dy33 + dz33 * dz33;
|
|
|
|
|
|
|
|
// Sort out the two smallest distances (F1, F2)
|
|
|
|
#if 0
|
|
|
|
// Cheat and sort out only F1
|
|
|
|
vec3 d1 = min(min(d11,d12), d13);
|
|
|
|
vec3 d2 = min(min(d21,d22), d23);
|
|
|
|
vec3 d3 = min(min(d31,d32), d33);
|
|
|
|
vec3 d = min(min(d1,d2), d3);
|
|
|
|
d.x = min(min(d.x,d.y),d.z);
|
|
|
|
return sqrt(d.xx); // F1 duplicated, no F2 computed
|
|
|
|
#else
|
|
|
|
// Do it right and sort out both F1 and F2
|
|
|
|
vec3 d1a = min(d11, d12);
|
|
|
|
d12 = max(d11, d12);
|
|
|
|
d11 = min(d1a, d13); // Smallest now not in d12 or d13
|
|
|
|
d13 = max(d1a, d13);
|
|
|
|
d12 = min(d12, d13); // 2nd smallest now not in d13
|
|
|
|
vec3 d2a = min(d21, d22);
|
|
|
|
d22 = max(d21, d22);
|
|
|
|
d21 = min(d2a, d23); // Smallest now not in d22 or d23
|
|
|
|
d23 = max(d2a, d23);
|
|
|
|
d22 = min(d22, d23); // 2nd smallest now not in d23
|
|
|
|
vec3 d3a = min(d31, d32);
|
|
|
|
d32 = max(d31, d32);
|
|
|
|
d31 = min(d3a, d33); // Smallest now not in d32 or d33
|
|
|
|
d33 = max(d3a, d33);
|
|
|
|
d32 = min(d32, d33); // 2nd smallest now not in d33
|
|
|
|
vec3 da = min(d11, d21);
|
|
|
|
d21 = max(d11, d21);
|
|
|
|
d11 = min(da, d31); // Smallest now in d11
|
|
|
|
d31 = max(da, d31); // 2nd smallest now not in d31
|
|
|
|
d11.xy = (d11.x < d11.y) ? d11.xy : d11.yx;
|
|
|
|
d11.xz = (d11.x < d11.z) ? d11.xz : d11.zx; // d11.x now smallest
|
|
|
|
d12 = min(d12, d21); // 2nd smallest now not in d21
|
|
|
|
d12 = min(d12, d22); // nor in d22
|
|
|
|
d12 = min(d12, d31); // nor in d31
|
|
|
|
d12 = min(d12, d32); // nor in d32
|
|
|
|
d11.yz = min(d11.yz,d12.xy); // nor in d12.yz
|
|
|
|
d11.y = min(d11.y,d12.z); // Only two more to go
|
|
|
|
d11.y = min(d11.y,d11.z); // Done! (Phew!)
|
|
|
|
return sqrt(d11.xy); // F1, F2
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
-- Vertex.tile
|
|
|
|
|
|
|
|
uniform float time;
|
|
|
|
|
|
|
|
varying vec3 vTexCoord3D;
|
|
|
|
|
|
|
|
void main(void) {
|
|
|
|
vTexCoord3D = gl_Vertex.xyz * 4.0
|
|
|
|
+ 0.2 * vec3(snoise(gl_Vertex.xyz + vec3(0.0, 0.0, time)),
|
|
|
|
snoise(gl_Vertex.xyz + vec3(43.0, 17.0, time)),
|
|
|
|
snoise(gl_Vertex.xyz + vec3(0.0, -43.0, time-17.0)));
|
|
|
|
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
|
|
|
}
|
|
|
|
|
2014-01-29 06:36:16 +00:00
|
|
|
-- Fragment.tile
|
2014-01-29 06:13:40 +00:00
|
|
|
|
|
|
|
varying vec3 vTexCoord3D;
|
|
|
|
|
|
|
|
void main(void) {
|
|
|
|
vec2 F = cellular(vTexCoord3D.xyz);
|
|
|
|
float n = 0.1+F.y-F.x;
|
|
|
|
gl_FragColor = vec4(n*0.6, n*1.1, n*0.5, 1.0);
|
|
|
|
}
|