jax 0.0.0.4 → 0.0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +14 -0
- data/Rakefile +4 -0
- data/builtin/shaders/depthmap/fragment.ejs +4 -2
- data/builtin/shaders/depthmap/material.js +5 -0
- data/builtin/shaders/depthmap/vertex.ejs +4 -1
- data/builtin/shaders/functions/noise.ejs +523 -0
- data/builtin/shaders/lighting/common.ejs +1 -1
- data/builtin/shaders/normal_map/common.ejs +1 -1
- data/builtin/shaders/{paraboloid-depthmap → paraboloid}/common.ejs +2 -2
- data/builtin/shaders/{paraboloid-depthmap → paraboloid}/fragment.ejs +3 -3
- data/builtin/shaders/paraboloid/manifest.yml +5 -0
- data/builtin/shaders/{paraboloid-depthmap → paraboloid}/material.js +4 -4
- data/builtin/shaders/{paraboloid-depthmap → paraboloid}/vertex.ejs +1 -0
- data/builtin/shaders/shadow_map/common.ejs +1 -1
- data/builtin/shaders/shadow_map/fragment.ejs +1 -1
- data/lib/jax.rb +4 -0
- data/lib/jax/application.rb +4 -5
- data/lib/jax/generators/app/templates/public/javascripts/jax.js +190 -6
- data/lib/jax/generators/material/USAGE +1 -1
- data/lib/jax/generators/shader/templates/common.ejs.tt +1 -1
- data/lib/jax/generators/shader/templates/spec.js.tt +4 -0
- data/lib/jax/packager/sprockets_template.rb +4 -0
- data/lib/jax/resource_compiler.rb +1 -1
- data/lib/jax/shader.rb +19 -7
- data/lib/jax/version.rb +1 -1
- data/spec/example_app/app/controllers/noise_controller.js +18 -0
- data/spec/example_app/app/helpers/noise_helper.js +3 -0
- data/spec/example_app/app/resources/materials/blob.yml +28 -0
- data/spec/example_app/app/shaders/blob/common.ejs +18 -0
- data/spec/example_app/app/shaders/blob/fragment.ejs +8 -0
- data/spec/example_app/app/shaders/blob/manifest.yml +15 -0
- data/spec/example_app/app/shaders/blob/material.js +48 -0
- data/spec/example_app/app/shaders/blob/vertex.ejs +13 -0
- data/spec/example_app/app/views/noise/index.js +4 -0
- data/spec/example_app/config/routes.rb +1 -0
- data/spec/example_app/spec/javascripts/controllers/noise_controller_spec.js +11 -0
- data/spec/example_app/spec/javascripts/helpers/noise_helper_spec.js +12 -0
- data/spec/example_app/spec/javascripts/shaders/blob_spec.js +30 -0
- data/spec/example_app/spec/javascripts/support/spec_layout.html.erb +2 -1
- data/spec/javascripts/shaders/core_materials_spec.js +1 -0
- data/spec/javascripts/shaders/{dual_paraboloid_spec.js → paraboloid_spec.js} +2 -2
- data/src/constants.yml +1 -0
- data/src/constants.yml.erb +1 -0
- data/src/jax.js +14 -1
- data/src/jax/noise.js +193 -0
- data/src/jax/webgl/material.js +3 -2
- data/src/jax/webgl/scene/light_source.js +3 -2
- metadata +41 -12
- data/spec/javascripts/Player.js +0 -58
data/CHANGELOG
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
* 0.0.0.5 *
|
2
|
+
|
3
|
+
* Jax now checks JS version against gem version and reports on mismatches
|
4
|
+
|
5
|
+
* Perlin noise functions added -- just do this in your shader:
|
6
|
+
//= require "functions/noise"
|
7
|
+
|
8
|
+
* Split 'paraboloid-depthmap' shader into 2 separate shaders: 'paraboloid' and 'depthmap'
|
9
|
+
This makes it possible to reuse paraboloids for environment mapping.
|
10
|
+
|
11
|
+
* Shader dependencies are now loaded via Jax.shader_load_paths, which can be multiple
|
12
|
+
different directories (e.g. Jax builtin + app/shaders)
|
13
|
+
|
14
|
+
* Added CHANGELOG. :)
|
data/Rakefile
CHANGED
@@ -49,6 +49,10 @@ end
|
|
49
49
|
|
50
50
|
desc "compile Jax"
|
51
51
|
task :compile do
|
52
|
+
# generate constants file
|
53
|
+
erb = ERB.new(File.read(File.join(File.dirname(__FILE__), "src/constants.yml.erb")))
|
54
|
+
File.open(File.join(File.dirname(__FILE__), "src/constants.yml"), "w") { |f| f.puts erb.result(binding) }
|
55
|
+
|
52
56
|
secretary = Sprockets::Secretary.new(
|
53
57
|
:root => File.dirname(__FILE__),
|
54
58
|
:asset_root => "public",
|
@@ -0,0 +1,523 @@
|
|
1
|
+
/*
|
2
|
+
* 2D, 3D and 4D Perlin noise, classic and simplex, in a GLSL fragment shader.
|
3
|
+
*
|
4
|
+
* Classic noise is implemented by the functions:
|
5
|
+
* float noise(vec2 P)
|
6
|
+
* float noise(vec3 P)
|
7
|
+
* float noise(vec4 P)
|
8
|
+
*
|
9
|
+
* Simplex noise is implemented by the functions:
|
10
|
+
* float snoise(vec2 P)
|
11
|
+
* float snoise(vec3 P)
|
12
|
+
* float snoise(vec4 P)
|
13
|
+
*
|
14
|
+
* Author: Stefan Gustavson ITN-LiTH (stegu@itn.liu.se) 2004-12-05
|
15
|
+
* You may use, modify and redistribute this code free of charge,
|
16
|
+
* provided that my name and this notice appears intact.
|
17
|
+
*/
|
18
|
+
|
19
|
+
/*
|
20
|
+
* NOTE: there is a formal problem with the dependent texture lookups.
|
21
|
+
* A texture coordinate of exactly 1.0 will wrap to 0.0, so strictly speaking,
|
22
|
+
* an error occurs every 256 units of the texture domain, and the same gradient
|
23
|
+
* is used for two adjacent noise cells. One solution is to set the texture
|
24
|
+
* wrap mode to "CLAMP" and do the wrapping explicitly in GLSL with the "mod"
|
25
|
+
* operator. This could also give you noise with repetition intervals other
|
26
|
+
* than 256 without any extra cost.
|
27
|
+
* This error is not even noticeable to the eye even if you isolate the exact
|
28
|
+
* position in the domain where it occurs and know exactly what to look for.
|
29
|
+
* The noise pattern is still visually correct, so I left the bug in there.
|
30
|
+
*
|
31
|
+
* The value of classic 4D noise goes above 1.0 and below -1.0 at some
|
32
|
+
* points. Not much and only very sparsely, but it happens.
|
33
|
+
*/
|
34
|
+
|
35
|
+
|
36
|
+
/*
|
37
|
+
* "permTexture" is a 256x256 texture that is used for both the permutations
|
38
|
+
* and the 2D and 3D gradient lookup. For details, see the main C program.
|
39
|
+
* "simplexTexture" is a small look-up table to determine a simplex traversal
|
40
|
+
* order for 3D and 4D simplex noise. Details are in the C program.
|
41
|
+
* "gradTexture" is a 256x256 texture with 4D gradients, similar to
|
42
|
+
* "permTexture" but with the permutation index in the alpha component
|
43
|
+
* replaced by the w component of the 4D gradient.
|
44
|
+
* 2D classic noise uses only permTexture.
|
45
|
+
* 2D simplex noise uses permTexture and simplexTexture.
|
46
|
+
* 3D classic noise uses only permTexture.
|
47
|
+
* 3D simplex noise uses permTexture and simplexTexture.
|
48
|
+
* 4D classic noise uses permTexture and gradTexture.
|
49
|
+
* 4D simplex noise uses all three textures.
|
50
|
+
*/
|
51
|
+
uniform sampler2D permTexture;
|
52
|
+
// sampler1D not supported in WebGL
|
53
|
+
//uniform sampler1D simplexTexture;
|
54
|
+
uniform sampler2D simplexTexture;
|
55
|
+
uniform sampler2D gradTexture;
|
56
|
+
uniform float time; // Used for texture animation
|
57
|
+
|
58
|
+
/*
|
59
|
+
* Both 2D and 3D texture coordinates are defined, for testing purposes.
|
60
|
+
*/
|
61
|
+
//varying vec2 v_texCoord2D;
|
62
|
+
//varying vec3 v_texCoord3D;
|
63
|
+
//varying vec4 v_color;
|
64
|
+
|
65
|
+
/*
|
66
|
+
* To create offsets of one texel and one half texel in the
|
67
|
+
* texture lookup, we need to know the texture image size.
|
68
|
+
*/
|
69
|
+
#define ONE 0.00390625
|
70
|
+
#define ONEHALF 0.001953125
|
71
|
+
// The numbers above are 1/256 and 0.5/256, change accordingly
|
72
|
+
// if you change the code to use another texture size.
|
73
|
+
|
74
|
+
|
75
|
+
/*
|
76
|
+
* The interpolation function. This could be a 1D texture lookup
|
77
|
+
* to get some more speed, but it's not the main part of the algorithm.
|
78
|
+
*/
|
79
|
+
float fade(float t) {
|
80
|
+
// return t*t*(3.0-2.0*t); // Old fade, yields discontinuous second derivative
|
81
|
+
return t*t*t*(t*(t*6.0-15.0)+10.0); // Improved fade, yields C2-continuous noise
|
82
|
+
}
|
83
|
+
|
84
|
+
|
85
|
+
/*
|
86
|
+
* 2D classic Perlin noise. Fast, but less useful than 3D noise.
|
87
|
+
*/
|
88
|
+
float noise(vec2 P)
|
89
|
+
{
|
90
|
+
vec2 Pi = ONE*floor(P)+ONEHALF; // Integer part, scaled and offset for texture lookup
|
91
|
+
vec2 Pf = fract(P); // Fractional part for interpolation
|
92
|
+
|
93
|
+
// Noise contribution from lower left corner
|
94
|
+
vec2 grad00 = texture2D(permTexture, Pi).rg * 4.0 - 1.0;
|
95
|
+
float n00 = dot(grad00, Pf);
|
96
|
+
|
97
|
+
// Noise contribution from lower right corner
|
98
|
+
vec2 grad10 = texture2D(permTexture, Pi + vec2(ONE, 0.0)).rg * 4.0 - 1.0;
|
99
|
+
float n10 = dot(grad10, Pf - vec2(1.0, 0.0));
|
100
|
+
|
101
|
+
// Noise contribution from upper left corner
|
102
|
+
vec2 grad01 = texture2D(permTexture, Pi + vec2(0.0, ONE)).rg * 4.0 - 1.0;
|
103
|
+
float n01 = dot(grad01, Pf - vec2(0.0, 1.0));
|
104
|
+
|
105
|
+
// Noise contribution from upper right corner
|
106
|
+
vec2 grad11 = texture2D(permTexture, Pi + vec2(ONE, ONE)).rg * 4.0 - 1.0;
|
107
|
+
float n11 = dot(grad11, Pf - vec2(1.0, 1.0));
|
108
|
+
|
109
|
+
// Blend contributions along x
|
110
|
+
vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade(Pf.x));
|
111
|
+
|
112
|
+
// Blend contributions along y
|
113
|
+
float n_xy = mix(n_x.x, n_x.y, fade(Pf.y));
|
114
|
+
|
115
|
+
// We're done, return the final noise value.
|
116
|
+
return n_xy;
|
117
|
+
}
|
118
|
+
|
119
|
+
|
120
|
+
/*
|
121
|
+
* 3D classic noise. Slower, but a lot more useful than 2D noise.
|
122
|
+
*/
|
123
|
+
float noise(vec3 P)
|
124
|
+
{
|
125
|
+
vec3 Pi = ONE*floor(P)+ONEHALF; // Integer part, scaled so +1 moves one texel
|
126
|
+
// and offset 1/2 texel to sample texel centers
|
127
|
+
vec3 Pf = fract(P); // Fractional part for interpolation
|
128
|
+
|
129
|
+
// Noise contributions from (x=0, y=0), z=0 and z=1
|
130
|
+
float perm00 = texture2D(permTexture, Pi.xy).a ;
|
131
|
+
vec3 grad000 = texture2D(permTexture, vec2(perm00, Pi.z)).rgb * 4.0 - 1.0;
|
132
|
+
float n000 = dot(grad000, Pf);
|
133
|
+
vec3 grad001 = texture2D(permTexture, vec2(perm00, Pi.z + ONE)).rgb * 4.0 - 1.0;
|
134
|
+
float n001 = dot(grad001, Pf - vec3(0.0, 0.0, 1.0));
|
135
|
+
|
136
|
+
// Noise contributions from (x=0, y=1), z=0 and z=1
|
137
|
+
float perm01 = texture2D(permTexture, Pi.xy + vec2(0.0, ONE)).a ;
|
138
|
+
vec3 grad010 = texture2D(permTexture, vec2(perm01, Pi.z)).rgb * 4.0 - 1.0;
|
139
|
+
float n010 = dot(grad010, Pf - vec3(0.0, 1.0, 0.0));
|
140
|
+
vec3 grad011 = texture2D(permTexture, vec2(perm01, Pi.z + ONE)).rgb * 4.0 - 1.0;
|
141
|
+
float n011 = dot(grad011, Pf - vec3(0.0, 1.0, 1.0));
|
142
|
+
|
143
|
+
// Noise contributions from (x=1, y=0), z=0 and z=1
|
144
|
+
float perm10 = texture2D(permTexture, Pi.xy + vec2(ONE, 0.0)).a ;
|
145
|
+
vec3 grad100 = texture2D(permTexture, vec2(perm10, Pi.z)).rgb * 4.0 - 1.0;
|
146
|
+
float n100 = dot(grad100, Pf - vec3(1.0, 0.0, 0.0));
|
147
|
+
vec3 grad101 = texture2D(permTexture, vec2(perm10, Pi.z + ONE)).rgb * 4.0 - 1.0;
|
148
|
+
float n101 = dot(grad101, Pf - vec3(1.0, 0.0, 1.0));
|
149
|
+
|
150
|
+
// Noise contributions from (x=1, y=1), z=0 and z=1
|
151
|
+
float perm11 = texture2D(permTexture, Pi.xy + vec2(ONE, ONE)).a ;
|
152
|
+
vec3 grad110 = texture2D(permTexture, vec2(perm11, Pi.z)).rgb * 4.0 - 1.0;
|
153
|
+
float n110 = dot(grad110, Pf - vec3(1.0, 1.0, 0.0));
|
154
|
+
vec3 grad111 = texture2D(permTexture, vec2(perm11, Pi.z + ONE)).rgb * 4.0 - 1.0;
|
155
|
+
float n111 = dot(grad111, Pf - vec3(1.0, 1.0, 1.0));
|
156
|
+
|
157
|
+
// Blend contributions along x
|
158
|
+
vec4 n_x = mix(vec4(n000, n001, n010, n011),
|
159
|
+
vec4(n100, n101, n110, n111), fade(Pf.x));
|
160
|
+
|
161
|
+
// Blend contributions along y
|
162
|
+
vec2 n_xy = mix(n_x.xy, n_x.zw, fade(Pf.y));
|
163
|
+
|
164
|
+
// Blend contributions along z
|
165
|
+
float n_xyz = mix(n_xy.x, n_xy.y, fade(Pf.z));
|
166
|
+
|
167
|
+
// We're done, return the final noise value.
|
168
|
+
return n_xyz;
|
169
|
+
}
|
170
|
+
|
171
|
+
|
172
|
+
/*
|
173
|
+
* 4D classic noise. Slow, but very useful. 4D simplex noise is a lot faster.
|
174
|
+
*
|
175
|
+
* This function performs 8 texture lookups and 16 dependent texture lookups,
|
176
|
+
* 16 dot products, 4 mix operations and a lot of additions and multiplications.
|
177
|
+
* Needless to say, it's not super fast. But it's not dead slow either.
|
178
|
+
*/
|
179
|
+
float noise(vec4 P)
|
180
|
+
{
|
181
|
+
vec4 Pi = ONE*floor(P)+ONEHALF; // Integer part, scaled so +1 moves one texel
|
182
|
+
// and offset 1/2 texel to sample texel centers
|
183
|
+
vec4 Pf = fract(P); // Fractional part for interpolation
|
184
|
+
|
185
|
+
// "n0000" is the noise contribution from (x=0, y=0, z=0, w=0), and so on
|
186
|
+
float perm00xy = texture2D(permTexture, Pi.xy).a ;
|
187
|
+
float perm00zw = texture2D(permTexture, Pi.zw).a ;
|
188
|
+
vec4 grad0000 = texture2D(gradTexture, vec2(perm00xy, perm00zw)).rgba * 4.0 -1.0;
|
189
|
+
float n0000 = dot(grad0000, Pf);
|
190
|
+
|
191
|
+
float perm01zw = texture2D(permTexture, Pi.zw + vec2(0.0, ONE)).a ;
|
192
|
+
vec4 grad0001 = texture2D(gradTexture, vec2(perm00xy, perm01zw)).rgba * 4.0 - 1.0;
|
193
|
+
float n0001 = dot(grad0001, Pf - vec4(0.0, 0.0, 0.0, 1.0));
|
194
|
+
|
195
|
+
float perm10zw = texture2D(permTexture, Pi.zw + vec2(ONE, 0.0)).a ;
|
196
|
+
vec4 grad0010 = texture2D(gradTexture, vec2(perm00xy, perm10zw)).rgba * 4.0 - 1.0;
|
197
|
+
float n0010 = dot(grad0010, Pf - vec4(0.0, 0.0, 1.0, 0.0));
|
198
|
+
|
199
|
+
float perm11zw = texture2D(permTexture, Pi.zw + vec2(ONE, ONE)).a ;
|
200
|
+
vec4 grad0011 = texture2D(gradTexture, vec2(perm00xy, perm11zw)).rgba * 4.0 - 1.0;
|
201
|
+
float n0011 = dot(grad0011, Pf - vec4(0.0, 0.0, 1.0, 1.0));
|
202
|
+
|
203
|
+
float perm01xy = texture2D(permTexture, Pi.xy + vec2(0.0, ONE)).a ;
|
204
|
+
vec4 grad0100 = texture2D(gradTexture, vec2(perm01xy, perm00zw)).rgba * 4.0 - 1.0;
|
205
|
+
float n0100 = dot(grad0100, Pf - vec4(0.0, 1.0, 0.0, 0.0));
|
206
|
+
|
207
|
+
vec4 grad0101 = texture2D(gradTexture, vec2(perm01xy, perm01zw)).rgba * 4.0 - 1.0;
|
208
|
+
float n0101 = dot(grad0101, Pf - vec4(0.0, 1.0, 0.0, 1.0));
|
209
|
+
|
210
|
+
vec4 grad0110 = texture2D(gradTexture, vec2(perm01xy, perm10zw)).rgba * 4.0 - 1.0;
|
211
|
+
float n0110 = dot(grad0110, Pf - vec4(0.0, 1.0, 1.0, 0.0));
|
212
|
+
|
213
|
+
vec4 grad0111 = texture2D(gradTexture, vec2(perm01xy, perm11zw)).rgba * 4.0 - 1.0;
|
214
|
+
float n0111 = dot(grad0111, Pf - vec4(0.0, 1.0, 1.0, 1.0));
|
215
|
+
|
216
|
+
float perm10xy = texture2D(permTexture, Pi.xy + vec2(ONE, 0.0)).a ;
|
217
|
+
vec4 grad1000 = texture2D(gradTexture, vec2(perm10xy, perm00zw)).rgba * 4.0 - 1.0;
|
218
|
+
float n1000 = dot(grad1000, Pf - vec4(1.0, 0.0, 0.0, 0.0));
|
219
|
+
|
220
|
+
vec4 grad1001 = texture2D(gradTexture, vec2(perm10xy, perm01zw)).rgba * 4.0 - 1.0;
|
221
|
+
float n1001 = dot(grad1001, Pf - vec4(1.0, 0.0, 0.0, 1.0));
|
222
|
+
|
223
|
+
vec4 grad1010 = texture2D(gradTexture, vec2(perm10xy, perm10zw)).rgba * 4.0 - 1.0;
|
224
|
+
float n1010 = dot(grad1010, Pf - vec4(1.0, 0.0, 1.0, 0.0));
|
225
|
+
|
226
|
+
vec4 grad1011 = texture2D(gradTexture, vec2(perm10xy, perm11zw)).rgba * 4.0 - 1.0;
|
227
|
+
float n1011 = dot(grad1011, Pf - vec4(1.0, 0.0, 1.0, 1.0));
|
228
|
+
|
229
|
+
float perm11xy = texture2D(permTexture, Pi.xy + vec2(ONE, ONE)).a ;
|
230
|
+
vec4 grad1100 = texture2D(gradTexture, vec2(perm11xy, perm00zw)).rgba * 4.0 - 1.0;
|
231
|
+
float n1100 = dot(grad1100, Pf - vec4(1.0, 1.0, 0.0, 0.0));
|
232
|
+
|
233
|
+
vec4 grad1101 = texture2D(gradTexture, vec2(perm11xy, perm01zw)).rgba * 4.0 - 1.0;
|
234
|
+
float n1101 = dot(grad1101, Pf - vec4(1.0, 1.0, 0.0, 1.0));
|
235
|
+
|
236
|
+
vec4 grad1110 = texture2D(gradTexture, vec2(perm11xy, perm10zw)).rgba * 4.0 - 1.0;
|
237
|
+
float n1110 = dot(grad1110, Pf - vec4(1.0, 1.0, 1.0, 0.0));
|
238
|
+
|
239
|
+
vec4 grad1111 = texture2D(gradTexture, vec2(perm11xy, perm11zw)).rgba * 4.0 - 1.0;
|
240
|
+
float n1111 = dot(grad1111, Pf - vec4(1.0, 1.0, 1.0, 1.0));
|
241
|
+
|
242
|
+
// Blend contributions along x
|
243
|
+
float fadex = fade(Pf.x);
|
244
|
+
vec4 n_x0 = mix(vec4(n0000, n0001, n0010, n0011),
|
245
|
+
vec4(n1000, n1001, n1010, n1011), fadex);
|
246
|
+
vec4 n_x1 = mix(vec4(n0100, n0101, n0110, n0111),
|
247
|
+
vec4(n1100, n1101, n1110, n1111), fadex);
|
248
|
+
|
249
|
+
// Blend contributions along y
|
250
|
+
vec4 n_xy = mix(n_x0, n_x1, fade(Pf.y));
|
251
|
+
|
252
|
+
// Blend contributions along z
|
253
|
+
vec2 n_xyz = mix(n_xy.xy, n_xy.zw, fade(Pf.z));
|
254
|
+
|
255
|
+
// Blend contributions along w
|
256
|
+
float n_xyzw = mix(n_xyz.x, n_xyz.y, fade(Pf.w));
|
257
|
+
|
258
|
+
// We're done, return the final noise value.
|
259
|
+
return n_xyzw;
|
260
|
+
}
|
261
|
+
|
262
|
+
|
263
|
+
/*
|
264
|
+
* 2D simplex noise. Somewhat slower but much better looking than classic noise.
|
265
|
+
*/
|
266
|
+
float snoise(vec2 P) {
|
267
|
+
|
268
|
+
// Skew and unskew factors are a bit hairy for 2D, so define them as constants
|
269
|
+
// This is (sqrt(3.0)-1.0)/2.0
|
270
|
+
#define F2 0.366025403784
|
271
|
+
// This is (3.0-sqrt(3.0))/6.0
|
272
|
+
#define G2 0.211324865405
|
273
|
+
|
274
|
+
// Skew the (x,y) space to determine which cell of 2 simplices we're in
|
275
|
+
float s = (P.x + P.y) * F2; // Hairy factor for 2D skewing
|
276
|
+
vec2 Pi = floor(P + s);
|
277
|
+
float t = (Pi.x + Pi.y) * G2; // Hairy factor for unskewing
|
278
|
+
vec2 P0 = Pi - t; // Unskew the cell origin back to (x,y) space
|
279
|
+
Pi = Pi * ONE + ONEHALF; // Integer part, scaled and offset for texture lookup
|
280
|
+
|
281
|
+
vec2 Pf0 = P - P0; // The x,y distances from the cell origin
|
282
|
+
|
283
|
+
// For the 2D case, the simplex shape is an equilateral triangle.
|
284
|
+
// Find out whether we are above or below the x=y diagonal to
|
285
|
+
// determine which of the two triangles we're in.
|
286
|
+
vec2 o1;
|
287
|
+
if(Pf0.x > Pf0.y) o1 = vec2(1.0, 0.0); // +x, +y traversal order
|
288
|
+
else o1 = vec2(0.0, 1.0); // +y, +x traversal order
|
289
|
+
|
290
|
+
// Noise contribution from simplex origin
|
291
|
+
vec2 grad0 = texture2D(permTexture, Pi).rg * 4.0 - 1.0;
|
292
|
+
float t0 = 0.5 - dot(Pf0, Pf0);
|
293
|
+
float n0;
|
294
|
+
if (t0 < 0.0) n0 = 0.0;
|
295
|
+
else {
|
296
|
+
t0 *= t0;
|
297
|
+
n0 = t0 * t0 * dot(grad0, Pf0);
|
298
|
+
}
|
299
|
+
|
300
|
+
// Noise contribution from middle corner
|
301
|
+
vec2 Pf1 = Pf0 - o1 + G2;
|
302
|
+
vec2 grad1 = texture2D(permTexture, Pi + o1*ONE).rg * 4.0 - 1.0;
|
303
|
+
float t1 = 0.5 - dot(Pf1, Pf1);
|
304
|
+
float n1;
|
305
|
+
if (t1 < 0.0) n1 = 0.0;
|
306
|
+
else {
|
307
|
+
t1 *= t1;
|
308
|
+
n1 = t1 * t1 * dot(grad1, Pf1);
|
309
|
+
}
|
310
|
+
|
311
|
+
// Noise contribution from last corner
|
312
|
+
vec2 Pf2 = Pf0 - vec2(1.0-2.0*G2);
|
313
|
+
vec2 grad2 = texture2D(permTexture, Pi + vec2(ONE, ONE)).rg * 4.0 - 1.0;
|
314
|
+
float t2 = 0.5 - dot(Pf2, Pf2);
|
315
|
+
float n2;
|
316
|
+
if(t2 < 0.0) n2 = 0.0;
|
317
|
+
else {
|
318
|
+
t2 *= t2;
|
319
|
+
n2 = t2 * t2 * dot(grad2, Pf2);
|
320
|
+
}
|
321
|
+
|
322
|
+
// Sum up and scale the result to cover the range [-1,1]
|
323
|
+
return 70.0 * (n0 + n1 + n2);
|
324
|
+
}
|
325
|
+
|
326
|
+
|
327
|
+
/*
|
328
|
+
* 3D simplex noise. Comparable in speed to classic noise, better looking.
|
329
|
+
*/
|
330
|
+
float snoise(vec3 P) {
|
331
|
+
|
332
|
+
// The skewing and unskewing factors are much simpler for the 3D case
|
333
|
+
#define F3 0.333333333333
|
334
|
+
#define G3 0.166666666667
|
335
|
+
|
336
|
+
// Skew the (x,y,z) space to determine which cell of 6 simplices we're in
|
337
|
+
float s = (P.x + P.y + P.z) * F3; // Factor for 3D skewing
|
338
|
+
vec3 Pi = floor(P + s);
|
339
|
+
float t = (Pi.x + Pi.y + Pi.z) * G3;
|
340
|
+
vec3 P0 = Pi - t; // Unskew the cell origin back to (x,y,z) space
|
341
|
+
Pi = Pi * ONE + ONEHALF; // Integer part, scaled and offset for texture lookup
|
342
|
+
|
343
|
+
vec3 Pf0 = P - P0; // The x,y distances from the cell origin
|
344
|
+
|
345
|
+
// For the 3D case, the simplex shape is a slightly irregular tetrahedron.
|
346
|
+
// To find out which of the six possible tetrahedra we're in, we need to
|
347
|
+
// determine the magnitude ordering of x, y and z components of Pf0.
|
348
|
+
// The method below is explained briefly in the C code. It uses a small
|
349
|
+
// 1D texture as a lookup table. The table is designed to work for both
|
350
|
+
// 3D and 4D noise, so only 8 (only 6, actually) of the 64 indices are
|
351
|
+
// used here.
|
352
|
+
float c1 = (Pf0.x > Pf0.y) ? 0.5078125 : 0.0078125; // 1/2 + 1/128
|
353
|
+
float c2 = (Pf0.x > Pf0.z) ? 0.25 : 0.0;
|
354
|
+
float c3 = (Pf0.y > Pf0.z) ? 0.125 : 0.0;
|
355
|
+
float sindex = c1 + c2 + c3;
|
356
|
+
vec3 offsets = texture2D(simplexTexture, vec2(sindex, 0.0)).rgb;
|
357
|
+
// vec3 offsets = texture1D(simplexTexture, sindex).rgb;
|
358
|
+
vec3 o1 = step(0.375, offsets);
|
359
|
+
vec3 o2 = step(0.125, offsets);
|
360
|
+
|
361
|
+
// Noise contribution from simplex origin
|
362
|
+
float perm0 = texture2D(permTexture, Pi.xy).a;
|
363
|
+
vec3 grad0 = texture2D(permTexture, vec2(perm0, Pi.z)).rgb * 4.0 - 1.0;
|
364
|
+
float t0 = 0.6 - dot(Pf0, Pf0);
|
365
|
+
float n0;
|
366
|
+
if (t0 < 0.0) n0 = 0.0;
|
367
|
+
else {
|
368
|
+
t0 *= t0;
|
369
|
+
n0 = t0 * t0 * dot(grad0, Pf0);
|
370
|
+
}
|
371
|
+
|
372
|
+
// Noise contribution from second corner
|
373
|
+
vec3 Pf1 = Pf0 - o1 + G3;
|
374
|
+
float perm1 = texture2D(permTexture, Pi.xy + o1.xy*ONE).a;
|
375
|
+
vec3 grad1 = texture2D(permTexture, vec2(perm1, Pi.z + o1.z*ONE)).rgb * 4.0 - 1.0;
|
376
|
+
float t1 = 0.6 - dot(Pf1, Pf1);
|
377
|
+
float n1;
|
378
|
+
if (t1 < 0.0) n1 = 0.0;
|
379
|
+
else {
|
380
|
+
t1 *= t1;
|
381
|
+
n1 = t1 * t1 * dot(grad1, Pf1);
|
382
|
+
}
|
383
|
+
|
384
|
+
// Noise contribution from third corner
|
385
|
+
vec3 Pf2 = Pf0 - o2 + 2.0 * G3;
|
386
|
+
float perm2 = texture2D(permTexture, Pi.xy + o2.xy*ONE).a;
|
387
|
+
vec3 grad2 = texture2D(permTexture, vec2(perm2, Pi.z + o2.z*ONE)).rgb * 4.0 - 1.0;
|
388
|
+
float t2 = 0.6 - dot(Pf2, Pf2);
|
389
|
+
float n2;
|
390
|
+
if (t2 < 0.0) n2 = 0.0;
|
391
|
+
else {
|
392
|
+
t2 *= t2;
|
393
|
+
n2 = t2 * t2 * dot(grad2, Pf2);
|
394
|
+
}
|
395
|
+
|
396
|
+
// Noise contribution from last corner
|
397
|
+
vec3 Pf3 = Pf0 - vec3(1.0-3.0*G3);
|
398
|
+
float perm3 = texture2D(permTexture, Pi.xy + vec2(ONE, ONE)).a;
|
399
|
+
vec3 grad3 = texture2D(permTexture, vec2(perm3, Pi.z + ONE)).rgb * 4.0 - 1.0;
|
400
|
+
float t3 = 0.6 - dot(Pf3, Pf3);
|
401
|
+
float n3;
|
402
|
+
if(t3 < 0.0) n3 = 0.0;
|
403
|
+
else {
|
404
|
+
t3 *= t3;
|
405
|
+
n3 = t3 * t3 * dot(grad3, Pf3);
|
406
|
+
}
|
407
|
+
|
408
|
+
// Sum up and scale the result to cover the range [-1,1]
|
409
|
+
return 32.0 * (n0 + n1 + n2 + n3);
|
410
|
+
}
|
411
|
+
|
412
|
+
|
413
|
+
/*
|
414
|
+
* 4D simplex noise. A lot faster than classic 4D noise, and better looking.
|
415
|
+
*/
|
416
|
+
|
417
|
+
float snoise(vec4 P) {
|
418
|
+
|
419
|
+
// The skewing and unskewing factors are hairy again for the 4D case
|
420
|
+
// This is (sqrt(5.0)-1.0)/4.0
|
421
|
+
#define F4 0.309016994375
|
422
|
+
// This is (5.0-sqrt(5.0))/20.0
|
423
|
+
#define G4 0.138196601125
|
424
|
+
|
425
|
+
// Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in
|
426
|
+
float s = (P.x + P.y + P.z + P.w) * F4; // Factor for 4D skewing
|
427
|
+
vec4 Pi = floor(P + s);
|
428
|
+
float t = (Pi.x + Pi.y + Pi.z + Pi.w) * G4;
|
429
|
+
vec4 P0 = Pi - t; // Unskew the cell origin back to (x,y,z,w) space
|
430
|
+
Pi = Pi * ONE + ONEHALF; // Integer part, scaled and offset for texture lookup
|
431
|
+
|
432
|
+
vec4 Pf0 = P - P0; // The x,y distances from the cell origin
|
433
|
+
|
434
|
+
// For the 4D case, the simplex is a 4D shape I won't even try to describe.
|
435
|
+
// To find out which of the 24 possible simplices we're in, we need to
|
436
|
+
// determine the magnitude ordering of x, y, z and w components of Pf0.
|
437
|
+
// The method below is presented without explanation. It uses a small 1D
|
438
|
+
// texture as a lookup table. The table is designed to work for both
|
439
|
+
// 3D and 4D noise and contains 64 indices, of which only 24 are actually
|
440
|
+
// used. An extension to 5D would require a larger texture here.
|
441
|
+
float c1 = (Pf0.x > Pf0.y) ? 0.5078125 : 0.0078125; // 1/2 + 1/128
|
442
|
+
float c2 = (Pf0.x > Pf0.z) ? 0.25 : 0.0;
|
443
|
+
float c3 = (Pf0.y > Pf0.z) ? 0.125 : 0.0;
|
444
|
+
float c4 = (Pf0.x > Pf0.w) ? 0.0625 : 0.0;
|
445
|
+
float c5 = (Pf0.y > Pf0.w) ? 0.03125 : 0.0;
|
446
|
+
float c6 = (Pf0.z > Pf0.w) ? 0.015625 : 0.0;
|
447
|
+
float sindex = c1 + c2 + c3 + c4 + c5 + c6;
|
448
|
+
vec4 offsets = texture2D(simplexTexture, vec2(sindex, 0.0)).rgba;
|
449
|
+
// vec4 offsets = texture1D(simplexTexture, sindex).rgba;
|
450
|
+
vec4 o1 = step(0.625, offsets);
|
451
|
+
vec4 o2 = step(0.375, offsets);
|
452
|
+
vec4 o3 = step(0.125, offsets);
|
453
|
+
|
454
|
+
// Noise contribution from simplex origin
|
455
|
+
float perm0xy = texture2D(permTexture, Pi.xy).a;
|
456
|
+
float perm0zw = texture2D(permTexture, Pi.zw).a;
|
457
|
+
vec4 grad0 = texture2D(gradTexture, vec2(perm0xy, perm0zw)).rgba * 4.0 - 1.0;
|
458
|
+
float t0 = 0.6 - dot(Pf0, Pf0);
|
459
|
+
float n0;
|
460
|
+
if (t0 < 0.0) n0 = 0.0;
|
461
|
+
else {
|
462
|
+
t0 *= t0;
|
463
|
+
n0 = t0 * t0 * dot(grad0, Pf0);
|
464
|
+
}
|
465
|
+
|
466
|
+
// Noise contribution from second corner
|
467
|
+
vec4 Pf1 = Pf0 - o1 + G4;
|
468
|
+
o1 = o1 * ONE;
|
469
|
+
float perm1xy = texture2D(permTexture, Pi.xy + o1.xy).a;
|
470
|
+
float perm1zw = texture2D(permTexture, Pi.zw + o1.zw).a;
|
471
|
+
vec4 grad1 = texture2D(gradTexture, vec2(perm1xy, perm1zw)).rgba * 4.0 - 1.0;
|
472
|
+
float t1 = 0.6 - dot(Pf1, Pf1);
|
473
|
+
float n1;
|
474
|
+
if (t1 < 0.0) n1 = 0.0;
|
475
|
+
else {
|
476
|
+
t1 *= t1;
|
477
|
+
n1 = t1 * t1 * dot(grad1, Pf1);
|
478
|
+
}
|
479
|
+
|
480
|
+
// Noise contribution from third corner
|
481
|
+
vec4 Pf2 = Pf0 - o2 + 2.0 * G4;
|
482
|
+
o2 = o2 * ONE;
|
483
|
+
float perm2xy = texture2D(permTexture, Pi.xy + o2.xy).a;
|
484
|
+
float perm2zw = texture2D(permTexture, Pi.zw + o2.zw).a;
|
485
|
+
vec4 grad2 = texture2D(gradTexture, vec2(perm2xy, perm2zw)).rgba * 4.0 - 1.0;
|
486
|
+
float t2 = 0.6 - dot(Pf2, Pf2);
|
487
|
+
float n2;
|
488
|
+
if (t2 < 0.0) n2 = 0.0;
|
489
|
+
else {
|
490
|
+
t2 *= t2;
|
491
|
+
n2 = t2 * t2 * dot(grad2, Pf2);
|
492
|
+
}
|
493
|
+
|
494
|
+
// Noise contribution from fourth corner
|
495
|
+
vec4 Pf3 = Pf0 - o3 + 3.0 * G4;
|
496
|
+
o3 = o3 * ONE;
|
497
|
+
float perm3xy = texture2D(permTexture, Pi.xy + o3.xy).a;
|
498
|
+
float perm3zw = texture2D(permTexture, Pi.zw + o3.zw).a;
|
499
|
+
vec4 grad3 = texture2D(gradTexture, vec2(perm3xy, perm3zw)).rgba * 4.0 - 1.0;
|
500
|
+
float t3 = 0.6 - dot(Pf3, Pf3);
|
501
|
+
float n3;
|
502
|
+
if (t3 < 0.0) n3 = 0.0;
|
503
|
+
else {
|
504
|
+
t3 *= t3;
|
505
|
+
n3 = t3 * t3 * dot(grad3, Pf3);
|
506
|
+
}
|
507
|
+
|
508
|
+
// Noise contribution from last corner
|
509
|
+
vec4 Pf4 = Pf0 - vec4(1.0-4.0*G4);
|
510
|
+
float perm4xy = texture2D(permTexture, Pi.xy + vec2(ONE, ONE)).a;
|
511
|
+
float perm4zw = texture2D(permTexture, Pi.zw + vec2(ONE, ONE)).a;
|
512
|
+
vec4 grad4 = texture2D(gradTexture, vec2(perm4xy, perm4zw)).rgba * 4.0 - 1.0;
|
513
|
+
float t4 = 0.6 - dot(Pf4, Pf4);
|
514
|
+
float n4;
|
515
|
+
if(t4 < 0.0) n4 = 0.0;
|
516
|
+
else {
|
517
|
+
t4 *= t4;
|
518
|
+
n4 = t4 * t4 * dot(grad4, Pf4);
|
519
|
+
}
|
520
|
+
|
521
|
+
// Sum up and scale the result to cover the range [-1,1]
|
522
|
+
return 27.0 * (n0 + n1 + n2 + n3 + n4);
|
523
|
+
}
|