-
Notifications
You must be signed in to change notification settings - Fork 0
/
wombatSN3D.glsl
127 lines (109 loc) · 5.13 KB
/
wombatSN3D.glsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Author:
// Title:
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
//
// Wombat
// An efficient texture-free GLSL procedural noise library
// Source: https://github.com/BrianSharpe/Wombat
// Derived from: https://github.com/BrianSharpe/GPU-Noise-Lib
//
// I'm not one for copyrights. Use the code however you wish.
// All I ask is that credit be given back to the blog or myself when appropriate.
// And also to let me know if you come up with any changes, improvements, thoughts or interesting uses for this stuff. :)
// Thanks!
//
// Brian Sharpe
// brisharpe CIRCLE_A yahoo DOT com
// http://briansharpe.wordpress.com
// https://github.com/BrianSharpe
//
//
// This is a modified version of Stefan Gustavson's and Ian McEwan's work at http://github.com/ashima/webgl-noise
// Modifications are...
// - faster random number generation
// - analytical final normalization
// - space scaled can have an approx feature size of 1.0
// - filter kernel changed to fix discontinuities at tetrahedron boundaries
//
//
// Simplex Perlin Noise 3D
// Return value range of -1.0->1.0
//
float SimplexPerlin3D( vec3 P )
{
// https://github.com/BrianSharpe/Wombat/blob/master/SimplexPerlin3D.glsl
// simplex math constants
const float SKEWFACTOR = 1.0/3.0;
const float UNSKEWFACTOR = 1.0/6.0;
const float SIMPLEX_CORNER_POS = 0.5;
const float SIMPLEX_TETRAHADRON_HEIGHT = 0.70710678118654752440084436210485; // sqrt( 0.5 )
// establish our grid cell.
P *= SIMPLEX_TETRAHADRON_HEIGHT; // scale space so we can have an approx feature size of 1.0
vec3 Pi = floor( P + dot( P, vec3( SKEWFACTOR) ) );
// Find the vectors to the corners of our simplex tetrahedron
vec3 x0 = P - Pi + dot(Pi, vec3( UNSKEWFACTOR ) );
vec3 g = step(x0.yzx, x0.xyz);
vec3 l = 1.0 - g;
vec3 Pi_1 = min( g.xyz, l.zxy );
vec3 Pi_2 = max( g.xyz, l.zxy );
vec3 x1 = x0 - Pi_1 + UNSKEWFACTOR;
vec3 x2 = x0 - Pi_2 + SKEWFACTOR;
vec3 x3 = x0 - SIMPLEX_CORNER_POS;
// pack them into a parallel-friendly arrangement
vec4 v1234_x = vec4( x0.x, x1.x, x2.x, x3.x );
vec4 v1234_y = vec4( x0.y, x1.y, x2.y, x3.y );
vec4 v1234_z = vec4( x0.z, x1.z, x2.z, x3.z );
// clamp the domain of our grid cell
Pi.xyz = Pi.xyz - floor(Pi.xyz * ( 1.0 / 69.0 )) * 69.0;
vec3 Pi_inc1 = step( Pi, vec3( 69.0 - 1.5 ) ) * ( Pi + 1.0 );
// generate the random vectors
vec4 Pt = vec4( Pi.xy, Pi_inc1.xy ) + vec2( 50.0, 161.0 ).xyxy;
Pt *= Pt;
vec4 V1xy_V2xy = mix( Pt.xyxy, Pt.zwzw, vec4( Pi_1.xy, Pi_2.xy ) );
Pt = vec4( Pt.x, V1xy_V2xy.xz, Pt.z ) * vec4( Pt.y, V1xy_V2xy.yw, Pt.w );
const vec3 SOMELARGEFLOATS = vec3( 635.298681, 682.357502, 668.926525 );
const vec3 ZINC = vec3( 48.500388, 65.294118, 63.934599 );
vec3 lowz_mods = vec3( 1.0 / ( SOMELARGEFLOATS.xyz + Pi.zzz * ZINC.xyz ) );
vec3 highz_mods = vec3( 1.0 / ( SOMELARGEFLOATS.xyz + Pi_inc1.zzz * ZINC.xyz ) );
Pi_1 = ( Pi_1.z < 0.5 ) ? lowz_mods : highz_mods;
Pi_2 = ( Pi_2.z < 0.5 ) ? lowz_mods : highz_mods;
vec4 hash_0 = fract( Pt * vec4( lowz_mods.x, Pi_1.x, Pi_2.x, highz_mods.x ) ) - 0.49999;
vec4 hash_1 = fract( Pt * vec4( lowz_mods.y, Pi_1.y, Pi_2.y, highz_mods.y ) ) - 0.49999;
vec4 hash_2 = fract( Pt * vec4( lowz_mods.z, Pi_1.z, Pi_2.z, highz_mods.z ) ) - 0.49999;
// evaluate gradients
vec4 grad_results = inversesqrt( hash_0 * hash_0 + hash_1 * hash_1 + hash_2 * hash_2 ) * ( hash_0 * v1234_x + hash_1 * v1234_y + hash_2 * v1234_z );
// Normalization factor to scale the final result to a strict 1.0->-1.0 range
// http://briansharpe.wordpress.com/2012/01/13/simplex-noise/#comment-36
const float FINAL_NORMALIZATION = 37.837227241611314102871574478976;
// evaulate the kernel weights ( use (0.5-x*x)^3 instead of (0.6-x*x)^4 to fix discontinuities )
vec4 kernel_weights = v1234_x * v1234_x + v1234_y * v1234_y + v1234_z * v1234_z;
kernel_weights = max(0.5 - kernel_weights, 0.0);
kernel_weights = kernel_weights*kernel_weights*kernel_weights;
// sum with the kernel and return
return dot( kernel_weights, grad_results ) * FINAL_NORMALIZATION;
}
vec3 hsb2rgb(in vec3 c) {
vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0,
0.0, 1.0);
rgb = rgb * rgb * (3.0 - 2.0 * rgb);
return c.z * mix(vec3(1.0), rgb, c.y);
}
void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y;
float noiseScale = 2.5;
float noiseSpeed = 0.25;
float hueFreq = 2.0;
float hueSpeed = 0.4;
float noiseValue = 0.5+0.5*SimplexPerlin3D(vec3(st.x*noiseScale,st.y*noiseScale,u_time*noiseSpeed));
float noiseValue2 = 0.5+0.5*SimplexPerlin3D(vec3(2.0*st.x*noiseScale,2.0*st.y*noiseScale,2.0*u_time*noiseSpeed));
vec3 color = vec3(0.);
color = hsb2rgb(vec3(noiseValue*hueFreq+hueSpeed*u_time,1.0,noiseValue2+0.25));
//color = vec3(noiseValue,noiseValue,noiseValue);
gl_FragColor = vec4(color,1.0);
}