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

Procedural Wood #1404

Open
wants to merge 4 commits into
base: adsk_contrib/dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
261 changes: 261 additions & 0 deletions contrib/adsk/libraries/adsklib/adsklib_3dwood_defs.mtlx

Large diffs are not rendered by default.

1,659 changes: 1,659 additions & 0 deletions contrib/adsk/libraries/adsklib/adsklib_3dwood_ng.mtlx

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,11 @@
<implementation name="IM_turbulence2d_float_genglsl" nodedef="ND_turbulence2d_float" file="mx_turbulence2d_float.glsl" function="mx_turbulence2d_float" target="genglsl" />
<implementation name="IM_turbulence3d_float_genglsl" nodedef="ND_turbulence3d_float" file="mx_turbulence3d_float.glsl" function="mx_turbulence3d_float" target="genglsl" />

<!-- 2d hashnoise -->
<implementation name="IM_hashnoise2d_vector3_genglsl" nodedef="ND_wood3d_util_hashnoise2d_vector3" file="mx_hashnoise2d_vector3.glsl" function="mx_hashnoise2d_vector3" target="genglsl" />
<!-- 1d perlin noise -->
<implementation name="IM_noise1d_float_genglsl" nodedef="ND_wood3d_util_noise1d_float" file="mx_noise1d_float.glsl" function="mx_noise1d_float" target="genglsl" />
<!-- 3D wood pore function -->
<implementation name="IM_wood3d_pore_impulse_genglsl" nodedef="ND_wood3d_util_pore_impulse" file="mx_wood_pore_impulse.glsl" function="mx_wood_pore_impulse" target="genglsl" />

</materialx>
12 changes: 12 additions & 0 deletions contrib/adsk/libraries/adsklib/genglsl/mx_hashnoise2d_vector3.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "../../stdlib/genglsl/lib/mx_noise.glsl"
// hash noise is similar to cell noise without floor operation on input.
void mx_hashnoise2d_vector3(vec2 texcoord, out vec3 result)
{
int ix = floatBitsToInt(texcoord.x);
int iy = floatBitsToInt(texcoord.y);
result = vec3(
mx_bits_to_01(mx_hash_int(ix, iy, 0)),
mx_bits_to_01(mx_hash_int(ix, iy, 1)),
mx_bits_to_01(mx_hash_int(ix, iy, 2))
);
}
34 changes: 34 additions & 0 deletions contrib/adsk/libraries/adsklib/genglsl/mx_noise1d_float.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "../../stdlib/genglsl/lib/mx_noise.glsl"
// 1 dimensional gradient function for 1D perlin noise
float mx_gradient_float(uint hash, float x)
{
uint h = hash & 15u;
float g = 1 + (h & 7u);
return mx_negate_if(g, bool(h&8u)) * x;
}

// Scaling factors to normalize the result of gradients above.
// These factors were experimentally calculated to be:
// 1D: 0.2500
// 2D: 0.6616
// 3D: 0.9820
float mx_gradient_scale1d(float v) { return 0.2500 * v; }

// 1D perlin noise
float mx_perlin_noise_float(float p)
{
int X;
float fx = mx_floorfrac(p, X);
float u = mx_fade(fx);
// mix in glsl is equivalent to lerp
float result = mix(
mx_gradient_float(mx_hash_int(X ), fx ),
mx_gradient_float(mx_hash_int(X+1), fx-1.0),
u);
return mx_gradient_scale1d(result);
}
void mx_noise1d_float(float amplitude, float pivot, float p, out float result)
{
float value = mx_perlin_noise_float(p);
result = value * amplitude + pivot;
}
44 changes: 44 additions & 0 deletions contrib/adsk/libraries/adsklib/genglsl/mx_wood_pore_impulse.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "../../stdlib/genglsl/lib/mx_noise.glsl"

// Wyvill kernel with pre-squared input.
float wyvillsq(float rsq)
{
float tmp = 1.0 - rsq;
return rsq >= 1.0 ? 0.0 : tmp * tmp * tmp;
}
// Compute impulse for wood pore effects which can't be done by node graph. This is essentially a re-implementation of the
// weight2DNeighborImpulses function in the 3ds max advance wood source code.
void mx_wood_pore_impulse(vec3 position, float wood_weight, float seed, float pore_cell_dim, float pore_radius, out float weight)
{
weight = 0.0;
if (wood_weight <= 0.0)
{
return;
}
float weighted_pore_radius = pore_radius * wood_weight;

// Determine the boundaries of the pore cells that may affect us, given the pore radius and
// cell dimensions.
float x_left = floor((position.x - weighted_pore_radius) / pore_cell_dim);
float x_right = floor((position.x + weighted_pore_radius) / pore_cell_dim);
float y_left = floor((position.y - weighted_pore_radius) / pore_cell_dim);
float y_right = floor((position.y + weighted_pore_radius) / pore_cell_dim);

// Sum the wyvill impulse from all potentially contributing cells.
float inverse_radius_sq = 1.0 / (weighted_pore_radius * weighted_pore_radius);
for (int j = int(y_left); j <= int(y_right); j++)
{
for (int i = int(x_left); i <= int(x_right); i++)
{
// Determine where the pore is in the cell
vec2 offset = mx_cell_noise_vec3(vec2(i + seed * 37, j)).xy;
vec2 pore_position = (offset + vec2(float(i), float(j))) * pore_cell_dim;

// Compute the distance to the pore and use it for the wyvill impulse.
vec2 diff = pore_position - vec2(position.x,position.y);
float diff_sq = dot(diff, diff);
weight += wyvillsq(diff_sq * inverse_radius_sq);
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,11 @@

<implementation name="IM_turbulence2d_float_genmdl" nodedef="ND_turbulence2d_float" sourcecode="color(0.5, 0.5, 0.5)" target="genmdl" />
<implementation name="IM_turbulence3d_float_genmdl" nodedef="ND_turbulence3d_float" sourcecode="color(0.5, 0.5, 0.5)" target="genmdl" />


<!-- 2d hashnoise -->
<implementation name="IM_wood3d_util_hashnoise2d_vector3_genmdl" nodedef="ND_wood3d_util_hashnoise2d_vector3" sourcecode="color(0.5, 0.5, 0.5)" target="genmdl" />
<!-- 1d perlin noise -->
<implementation name="IM_wood3d_util_noise1d_float_genmdl" nodedef="ND_wood3d_util_noise1d_float" sourcecode="color(0.5, 0.5, 0.5)" target="genmdl" />
<!-- 3D wood pore function -->
<implementation name="IM_wood3d_util_pore_impulse_genmdl" nodedef="ND_wood3d_util_pore_impulse" sourcecode="color(0.5, 0.5, 0.5)" target="genmdl" />
</materialx>
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,12 @@

<implementation name="IM_turbulence2d_float_genosl" nodedef="ND_turbulence2d_float" file="mx_turbulence2d_float.osl" function="mx_turbulence2d_float" target="genosl" />
<implementation name="IM_turbulence3d_float_genosl" nodedef="ND_turbulence3d_float" file="mx_turbulence3d_float.osl" function="mx_turbulence3d_float" target="genosl" />

<!-- 2d hashnoise -->
<implementation name="IM_wood3d_util_hashnoise2d_vector3_genosl" nodedef="ND_wood3d_util_hashnoise2d_vector3" file="mx_hashnoise2d_vector3.osl" function="mx_hashnoise2d_vector3" target="genosl" />
<!-- 1d perlin noise -->
<implementation name="IM_wood3d_util_noise1d_float_genosl" nodedef="ND_wood3d_util_noise1d_float" file="mx_noise1d_float.osl" function="mx_noise1d_float" target="genosl" />
<!-- 3D wood pore function -->
<implementation name="IM_wood3d_util_pore_impulse_genosl" nodedef="ND_wood3d_util_pore_impulse" file="mx_wood_pore_impulse.osl" function="mx_wood_pore_impulse" target="genosl" />

</materialx>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
void mx_hashnoise2d_vector3(vector2 texcoord, output vector3 result)
{
result = noise("hash", texcoord.x, texcoord.y);
}
5 changes: 5 additions & 0 deletions contrib/adsk/libraries/adsklib/genosl/mx_noise1d_float.osl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
void mx_noise2d_float(float amplitude, float pivot, float p, output float result)
{
float value = noise("perlin", p);
result = value * amplitude + pivot;
}
42 changes: 42 additions & 0 deletions contrib/adsk/libraries/adsklib/genosl/mx_wood_pore_impulse.osl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Wyvill kernel with pre-squared input.
float wyvillsq(float rsq)
{
float tmp = 1.0 - rsq;
return rsq >= 1.0 ? 0.0 : tmp * tmp * tmp;
}
// Compute impulse for wood pore effects which can't be done by node graph. This is essentially a re-implementation of the
// weight2DNeighborImpulses function in the 3ds max advance wood source code.
void mx_wood_pore_impulse(vector3 position, float wood_weight, float seed, float pore_cell_dim, float pore_radius, out float weight)
{
weight = 0.0;
if (wood_weight <= 0.0)
{
return;
}
float weighted_pore_radius = pore_radius * wood_weight;

// Determine the boundaries of the pore cells that may affect us, given the pore radius and
// cell dimensions.
float x_left = floor((position.x - weighted_pore_radius) / pore_cell_dim);
float x_right = floor((position.x + weighted_pore_radius) / pore_cell_dim);
float y_left = floor((position.y - weighted_pore_radius) / pore_cell_dim);
float y_right = floor((position.y + weighted_pore_radius) / pore_cell_dim);

// Sum the wyvill impulse from all potentially contributing cells.
float inverse_radius_sq = 1.0 / (weighted_pore_radius * weighted_pore_radius);
for (int j = int(y_left); j <= int(y_right); j++)
{
for (int i = int(x_left); i <= int(x_right); i++)
{
// Determine where the pore is in the cell
vector2 offset = vcellnoise(vector2(i + seed * 37, j)).xy;
vector2 pore_position = (offset + vector2(float(i), float(j))) * pore_cell_dim;

// Compute the distance to the pore and use it for the wyvill impulse.
vector2 diff = pore_position - vector2(position.x,position.y);
float diff_sq = dot(diff, diff);
weight += wyvillsq(diff_sq * inverse_radius_sq);
}
}
}

Loading
Loading