jax 0.0.0.4 → 0.0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
}
|