diff --git a/documents/Specification/MaterialX.Specification.md b/documents/Specification/MaterialX.Specification.md index 4ad29dc963..52763fd321 100644 --- a/documents/Specification/MaterialX.Specification.md +++ b/documents/Specification/MaterialX.Specification.md @@ -888,12 +888,14 @@ Standard Noise nodes: * **`worleynoise2d`**: 2D Worley noise using centered jitter, outputting float (distance metric to closest feature), vector2 (distance metrics to closest 2 features) or vector3 (distance metrics to closest 3 features). * `jitter` (float): amount to jitter the cell center position, with smaller values creating a more regular pattern. Default is 1.0. + * `style` (integer): the output style, one of "distance" (distance to the cell center), or "solid" (constant value for each cell). * `texcoord` (vector2): the 2D position at which the noise is evaluated. Default is to use the first set of texture coordinates. * **`worleynoise3d`**: 3D Worley noise using centered jitter, outputting float (distance metric to closest feature), vector2 (distance metrics to closest 2 features) or vector3 (distance metrics to closest 3 features). * `jitter` (float): amount to jitter the cell center position, with smaller values creating a more regular pattern. Default is 1.0. + * `style` (integer): the output style, one of "distance" (distance to the cell center), or "solid" (constant value for each cell). Default is "distance". * `position` (vector3): the 3D position at which the noise is evaluated. Default is to use the current 3D object-space coordinate. diff --git a/libraries/stdlib/genglsl/lib/mx_noise.glsl b/libraries/stdlib/genglsl/lib/mx_noise.glsl index 3212481d1d..b48475bc11 100644 --- a/libraries/stdlib/genglsl/lib/mx_noise.glsl +++ b/libraries/stdlib/genglsl/lib/mx_noise.glsl @@ -437,7 +437,7 @@ vec4 mx_fractal_noise_vec4(vec3 p, int octaves, float lacunarity, float diminish return vec4(c, f); } -float mx_worley_distance(vec2 p, int x, int y, int xoff, int yoff, float jitter, int metric) +vec2 mx_worley_cell_position(int x, int y, int xoff, int yoff, float jitter) { vec3 tmp = mx_cell_noise_vec3(vec2(x+xoff, y+yoff)); vec2 off = vec2(tmp.x, tmp.y); @@ -445,8 +445,24 @@ float mx_worley_distance(vec2 p, int x, int y, int xoff, int yoff, float jitter, off -= 0.5f; off *= jitter; off += 0.5f; + + return vec2(float(x), float(y)) + off; +} + +vec3 mx_worley_cell_position(int x, int y, int z, int xoff, int yoff, int zoff, float jitter) +{ + vec3 off = mx_cell_noise_vec3(vec3(x+xoff, y+yoff, z+zoff)); + + off -= 0.5f; + off *= jitter; + off += 0.5f; + + return vec3(float(x), float(y), float(z)) + off; +} - vec2 cellpos = vec2(float(x), float(y)) + off; +float mx_worley_distance(vec2 p, int x, int y, int xoff, int yoff, float jitter, int metric) +{ + vec2 cellpos = mx_worley_cell_position(x, y, xoff, yoff, jitter); vec2 diff = cellpos - p; if (metric == 2) return abs(diff.x) + abs(diff.y); // Manhattan distance @@ -458,13 +474,7 @@ float mx_worley_distance(vec2 p, int x, int y, int xoff, int yoff, float jitter, float mx_worley_distance(vec3 p, int x, int y, int z, int xoff, int yoff, int zoff, float jitter, int metric) { - vec3 off = mx_cell_noise_vec3(vec3(x+xoff, y+yoff, z+zoff)); - - off -= 0.5f; - off *= jitter; - off += 0.5f; - - vec3 cellpos = vec3(float(x), float(y), float(z)) + off; + vec3 cellpos = mx_worley_cell_position(x, y, z, xoff, yoff, zoff, jitter); vec3 diff = cellpos - p; if (metric == 2) return abs(diff.x) + abs(diff.y) + abs(diff.z); // Manhattan distance @@ -474,38 +484,53 @@ float mx_worley_distance(vec3 p, int x, int y, int z, int xoff, int yoff, int zo return dot(diff, diff); } -float mx_worley_noise_float(vec2 p, float jitter, int metric) +float mx_worley_noise_float(vec2 p, float jitter, int style, int metric) { int X, Y; + float dist; vec2 localpos = vec2(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y)); float sqdist = 1e6f; // Some big number for jitter > 1 (not all GPUs may be IEEE) + vec2 minpos = vec2(0,0); for (int x = -1; x <= 1; ++x) { for (int y = -1; y <= 1; ++y) { float dist = mx_worley_distance(localpos, x, y, X, Y, jitter, metric); - sqdist = min(sqdist, dist); + vec2 cellpos = mx_worley_cell_position(x, y, X, Y, jitter) - localpos; + if(dist < sqdist) + { + sqdist = dist; + minpos = cellpos; + } } } - if (metric == 0) - sqdist = sqrt(sqdist); - return sqdist; + if (style == 1) + return mx_cell_noise_float(minpos + p); + else + { + if (metric == 0) + sqdist = sqrt(sqdist); + return sqdist; + } } -vec2 mx_worley_noise_vec2(vec2 p, float jitter, int metric) +vec2 mx_worley_noise_vec2(vec2 p, float jitter, int style, int metric) { int X, Y; vec2 localpos = vec2(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y)); vec2 sqdist = vec2(1e6f, 1e6f); + vec2 minpos = vec2(0,0); for (int x = -1; x <= 1; ++x) { for (int y = -1; y <= 1; ++y) { float dist = mx_worley_distance(localpos, x, y, X, Y, jitter, metric); + vec2 cellpos = mx_worley_cell_position(x, y, X, Y, jitter) - localpos; if (dist < sqdist.x) { sqdist.y = sqdist.x; sqdist.x = dist; + minpos = cellpos; } else if (dist < sqdist.y) { @@ -513,26 +538,37 @@ vec2 mx_worley_noise_vec2(vec2 p, float jitter, int metric) } } } - if (metric == 0) - sqdist = sqrt(sqdist); - return sqdist; + if (style == 1) + { + vec3 tmp = mx_cell_noise_vec3(minpos + p); + return vec2(tmp.x,tmp.y); + } + else + { + if (metric == 0) + sqdist = sqrt(sqdist); + return sqdist; + } } -vec3 mx_worley_noise_vec3(vec2 p, float jitter, int metric) +vec3 mx_worley_noise_vec3(vec2 p, float jitter, int style, int metric) { int X, Y; vec2 localpos = vec2(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y)); vec3 sqdist = vec3(1e6f, 1e6f, 1e6f); + vec2 minpos = vec2(0,0); for (int x = -1; x <= 1; ++x) { for (int y = -1; y <= 1; ++y) { float dist = mx_worley_distance(localpos, x, y, X, Y, jitter, metric); + vec2 cellpos = mx_worley_cell_position(x, y, X, Y, jitter) - localpos; if (dist < sqdist.x) { sqdist.z = sqdist.y; sqdist.y = sqdist.x; sqdist.x = dist; + minpos = cellpos; } else if (dist < sqdist.y) { @@ -545,16 +581,22 @@ vec3 mx_worley_noise_vec3(vec2 p, float jitter, int metric) } } } - if (metric == 0) - sqdist = sqrt(sqdist); - return sqdist; + if (style == 1) + return mx_cell_noise_vec3(minpos + p); + else + { + if (metric == 0) + sqdist = sqrt(sqdist); + return sqdist; + } } -float mx_worley_noise_float(vec3 p, float jitter, int metric) +float mx_worley_noise_float(vec3 p, float jitter, int style, int metric) { int X, Y, Z; vec3 localpos = vec3(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y), mx_floorfrac(p.z, Z)); float sqdist = 1e6f; + vec3 minpos = vec3(0,0,0); for (int x = -1; x <= 1; ++x) { for (int y = -1; y <= 1; ++y) @@ -562,20 +604,31 @@ float mx_worley_noise_float(vec3 p, float jitter, int metric) for (int z = -1; z <= 1; ++z) { float dist = mx_worley_distance(localpos, x, y, z, X, Y, Z, jitter, metric); - sqdist = min(sqdist, dist); + vec3 cellpos = mx_worley_cell_position(x, y, z, X, Y, Z, jitter) - localpos; + if(dist < sqdist) + { + sqdist = dist; + minpos = cellpos; + } } } } - if (metric == 0) - sqdist = sqrt(sqdist); - return sqdist; + if (style == 1) + return mx_cell_noise_float(minpos + p); + else + { + if (metric == 0) + sqdist = sqrt(sqdist); + return sqdist; + } } -vec2 mx_worley_noise_vec2(vec3 p, float jitter, int metric) +vec2 mx_worley_noise_vec2(vec3 p, float jitter, int style, int metric) { int X, Y, Z; vec3 localpos = vec3(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y), mx_floorfrac(p.z, Z)); vec2 sqdist = vec2(1e6f, 1e6f); + vec3 minpos = vec3(0,0,0); for (int x = -1; x <= 1; ++x) { for (int y = -1; y <= 1; ++y) @@ -583,10 +636,12 @@ vec2 mx_worley_noise_vec2(vec3 p, float jitter, int metric) for (int z = -1; z <= 1; ++z) { float dist = mx_worley_distance(localpos, x, y, z, X, Y, Z, jitter, metric); + vec3 cellpos = mx_worley_cell_position(x, y, z, X, Y, Z, jitter) - localpos; if (dist < sqdist.x) { sqdist.y = sqdist.x; sqdist.x = dist; + minpos = cellpos; } else if (dist < sqdist.y) { @@ -595,16 +650,25 @@ vec2 mx_worley_noise_vec2(vec3 p, float jitter, int metric) } } } - if (metric == 0) - sqdist = sqrt(sqdist); - return sqdist; + if (style == 1) + { + vec3 tmp = mx_cell_noise_vec3(minpos + p); + return vec2(tmp.x,tmp.y); + } + else + { + if (metric == 0) + sqdist = sqrt(sqdist); + return sqdist; + } } -vec3 mx_worley_noise_vec3(vec3 p, float jitter, int metric) +vec3 mx_worley_noise_vec3(vec3 p, float jitter, int style, int metric) { int X, Y, Z; vec3 localpos = vec3(mx_floorfrac(p.x, X), mx_floorfrac(p.y, Y), mx_floorfrac(p.z, Z)); vec3 sqdist = vec3(1e6f, 1e6f, 1e6f); + vec3 minpos = vec3(0,0,0); for (int x = -1; x <= 1; ++x) { for (int y = -1; y <= 1; ++y) @@ -612,11 +676,13 @@ vec3 mx_worley_noise_vec3(vec3 p, float jitter, int metric) for (int z = -1; z <= 1; ++z) { float dist = mx_worley_distance(localpos, x, y, z, X, Y, Z, jitter, metric); + vec3 cellpos = mx_worley_cell_position(x, y, z, X, Y, Z, jitter) - localpos; if (dist < sqdist.x) { sqdist.z = sqdist.y; sqdist.y = sqdist.x; sqdist.x = dist; + minpos = cellpos; } else if (dist < sqdist.y) { @@ -630,7 +696,12 @@ vec3 mx_worley_noise_vec3(vec3 p, float jitter, int metric) } } } - if (metric == 0) - sqdist = sqrt(sqdist); - return sqdist; + if (style == 1) + return mx_cell_noise_vec3(minpos + p); + else + { + if (metric == 0) + sqdist = sqrt(sqdist); + return sqdist; + } } diff --git a/libraries/stdlib/genglsl/mx_worleynoise2d_float.glsl b/libraries/stdlib/genglsl/mx_worleynoise2d_float.glsl index 75368e4f38..a69bc80b0c 100644 --- a/libraries/stdlib/genglsl/mx_worleynoise2d_float.glsl +++ b/libraries/stdlib/genglsl/mx_worleynoise2d_float.glsl @@ -1,6 +1,6 @@ #include "lib/mx_noise.glsl" -void mx_worleynoise2d_float(vec2 texcoord, float jitter, out float result) +void mx_worleynoise2d_float(vec2 texcoord, float jitter, int style, out float result) { - result = mx_worley_noise_float(texcoord, jitter, 0); + result = mx_worley_noise_float(texcoord, jitter, style, 0); } diff --git a/libraries/stdlib/genglsl/mx_worleynoise2d_vector2.glsl b/libraries/stdlib/genglsl/mx_worleynoise2d_vector2.glsl index 1a63c0c220..fca38efbde 100644 --- a/libraries/stdlib/genglsl/mx_worleynoise2d_vector2.glsl +++ b/libraries/stdlib/genglsl/mx_worleynoise2d_vector2.glsl @@ -1,6 +1,6 @@ #include "lib/mx_noise.glsl" -void mx_worleynoise2d_vector2(vec2 texcoord, float jitter, out vec2 result) +void mx_worleynoise2d_vector2(vec2 texcoord, float jitter, int style, out vec2 result) { - result = mx_worley_noise_vec2(texcoord, jitter, 0); + result = mx_worley_noise_vec2(texcoord, jitter, style, 0); } diff --git a/libraries/stdlib/genglsl/mx_worleynoise2d_vector3.glsl b/libraries/stdlib/genglsl/mx_worleynoise2d_vector3.glsl index ee4ce42b58..2aff692834 100644 --- a/libraries/stdlib/genglsl/mx_worleynoise2d_vector3.glsl +++ b/libraries/stdlib/genglsl/mx_worleynoise2d_vector3.glsl @@ -1,6 +1,6 @@ #include "lib/mx_noise.glsl" -void mx_worleynoise2d_vector3(vec2 texcoord, float jitter, out vec3 result) +void mx_worleynoise2d_vector3(vec2 texcoord, float jitter, int style, out vec3 result) { - result = mx_worley_noise_vec3(texcoord, jitter, 0); + result = mx_worley_noise_vec3(texcoord, jitter, style, 0); } diff --git a/libraries/stdlib/genglsl/mx_worleynoise3d_float.glsl b/libraries/stdlib/genglsl/mx_worleynoise3d_float.glsl index 738d2f6a77..ad43dee954 100644 --- a/libraries/stdlib/genglsl/mx_worleynoise3d_float.glsl +++ b/libraries/stdlib/genglsl/mx_worleynoise3d_float.glsl @@ -1,6 +1,6 @@ #include "lib/mx_noise.glsl" -void mx_worleynoise3d_float(vec3 position, float jitter, out float result) +void mx_worleynoise3d_float(vec3 position, float jitter, int style, out float result) { - result = mx_worley_noise_float(position, jitter, 0); + result = mx_worley_noise_float(position, jitter, style, 0); } diff --git a/libraries/stdlib/genglsl/mx_worleynoise3d_vector2.glsl b/libraries/stdlib/genglsl/mx_worleynoise3d_vector2.glsl index 22bfe8d03d..c124d3a3eb 100644 --- a/libraries/stdlib/genglsl/mx_worleynoise3d_vector2.glsl +++ b/libraries/stdlib/genglsl/mx_worleynoise3d_vector2.glsl @@ -1,6 +1,6 @@ #include "lib/mx_noise.glsl" -void mx_worleynoise3d_vector2(vec3 position, float jitter, out vec2 result) +void mx_worleynoise3d_vector2(vec3 position, float jitter, int style, out vec2 result) { - result = mx_worley_noise_vec2(position, jitter, 0); + result = mx_worley_noise_vec2(position, jitter, style, 0); } diff --git a/libraries/stdlib/genglsl/mx_worleynoise3d_vector3.glsl b/libraries/stdlib/genglsl/mx_worleynoise3d_vector3.glsl index ac6f7121c6..b96086269c 100644 --- a/libraries/stdlib/genglsl/mx_worleynoise3d_vector3.glsl +++ b/libraries/stdlib/genglsl/mx_worleynoise3d_vector3.glsl @@ -1,6 +1,6 @@ #include "lib/mx_noise.glsl" -void mx_worleynoise3d_vector3(vec3 position, float jitter, out vec3 result) +void mx_worleynoise3d_vector3(vec3 position, float jitter, int style, out vec3 result) { - result = mx_worley_noise_vec3(position, jitter, 0); + result = mx_worley_noise_vec3(position, jitter, style, 0); } diff --git a/libraries/stdlib/stdlib_defs.mtlx b/libraries/stdlib/stdlib_defs.mtlx index 7e6be9b050..6cebca7faf 100644 --- a/libraries/stdlib/stdlib_defs.mtlx +++ b/libraries/stdlib/stdlib_defs.mtlx @@ -1002,16 +1002,19 @@ + + + @@ -1022,16 +1025,19 @@ + + +