Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance Worley noise with solid cells option #2119

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions documents/Specification/MaterialX.Specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

<a id="node-worleynoise3d"> </a>

* **`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.

<a id="node-unifiednoise2d"> </a>
Expand Down
141 changes: 106 additions & 35 deletions libraries/stdlib/genglsl/lib/mx_noise.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -437,16 +437,32 @@ 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);

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
Expand All @@ -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
Expand All @@ -474,65 +484,91 @@ 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)
{
sqdist.y = dist;
}
}
}
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)
{
Expand All @@ -545,48 +581,67 @@ 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)
{
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)
{
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)
{
Expand All @@ -595,28 +650,39 @@ 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)
{
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)
{
Expand All @@ -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;
}
}
4 changes: 2 additions & 2 deletions libraries/stdlib/genglsl/mx_worleynoise2d_float.glsl
Original file line number Diff line number Diff line change
@@ -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);
}
4 changes: 2 additions & 2 deletions libraries/stdlib/genglsl/mx_worleynoise2d_vector2.glsl
Original file line number Diff line number Diff line change
@@ -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);
}
4 changes: 2 additions & 2 deletions libraries/stdlib/genglsl/mx_worleynoise2d_vector3.glsl
Original file line number Diff line number Diff line change
@@ -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);
}
4 changes: 2 additions & 2 deletions libraries/stdlib/genglsl/mx_worleynoise3d_float.glsl
Original file line number Diff line number Diff line change
@@ -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);
}
4 changes: 2 additions & 2 deletions libraries/stdlib/genglsl/mx_worleynoise3d_vector2.glsl
Original file line number Diff line number Diff line change
@@ -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);
}
4 changes: 2 additions & 2 deletions libraries/stdlib/genglsl/mx_worleynoise3d_vector3.glsl
Original file line number Diff line number Diff line change
@@ -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);
}
6 changes: 6 additions & 0 deletions libraries/stdlib/stdlib_defs.mtlx
Original file line number Diff line number Diff line change
Expand Up @@ -1002,16 +1002,19 @@
<nodedef name="ND_worleynoise2d_float" node="worleynoise2d" nodegroup="procedural2d">
<input name="texcoord" type="vector2" defaultgeomprop="UV0" />
<input name="jitter" type="float" value="1.0" />
<input name="style" uiname="Cell Style" type="integer" value="0" enum="Distance,Solid" enumvalues="0,1" />
<output name="out" type="float" default="0.0" />
</nodedef>
<nodedef name="ND_worleynoise2d_vector2" node="worleynoise2d" nodegroup="procedural2d">
<input name="texcoord" type="vector2" defaultgeomprop="UV0" />
<input name="jitter" type="float" value="1.0" />
<input name="style" uiname="Cell Style" type="integer" value="0" enum="Distance,Solid" enumvalues="0,1" />
<output name="out" type="vector2" default="0.0, 0.0" />
</nodedef>
<nodedef name="ND_worleynoise2d_vector3" node="worleynoise2d" nodegroup="procedural2d">
<input name="texcoord" type="vector2" defaultgeomprop="UV0" />
<input name="jitter" type="float" value="1.0" />
<input name="style" uiname="Cell Style" type="integer" value="0" enum="Distance,Solid" enumvalues="0,1" />
<output name="out" type="vector3" default="0.0, 0.0, 0.0" />
</nodedef>

Expand All @@ -1022,16 +1025,19 @@
<nodedef name="ND_worleynoise3d_float" node="worleynoise3d" nodegroup="procedural3d">
<input name="position" type="vector3" defaultgeomprop="Pobject" />
<input name="jitter" type="float" value="1.0" />
<input name="style" uiname="Cell Style" type="integer" value="0" enum="Distance,Solid" enumvalues="0,1" />
<output name="out" type="float" default="0.0" />
</nodedef>
<nodedef name="ND_worleynoise3d_vector2" node="worleynoise3d" nodegroup="procedural3d">
<input name="position" type="vector3" defaultgeomprop="Pobject" />
<input name="jitter" type="float" value="1.0" />
<input name="style" uiname="Cell Style" type="integer" value="0" enum="Distance,Solid" enumvalues="0,1" />
<output name="out" type="vector2" default="0.0, 0.0" />
</nodedef>
<nodedef name="ND_worleynoise3d_vector3" node="worleynoise3d" nodegroup="procedural3d">
<input name="position" type="vector3" defaultgeomprop="Pobject" />
<input name="jitter" type="float" value="1.0" />
<input name="style" uiname="Cell Style" type="integer" value="0" enum="Distance,Solid" enumvalues="0,1" />
<output name="out" type="vector3" default="0.0, 0.0, 0.0" />
</nodedef>

Expand Down