MaterialX icon indicating copy to clipboard operation
MaterialX copied to clipboard

Noise nodes should support periodic pattern repetition

Open rafalSFX opened this issue 3 years ago • 6 comments

This request has already been integrated into the v1.39 specification, but I'm attaching the implementation of the GLSL shader for reference: mx_noise.glsl.txt

This is a request for noise, cellnoise, worleynoise, and fractalnoise for both 2d and 3d versions to gain a new parameter, 'period', of vector2 or vector3 type. The values are integers but MaterialX does not have integer2 nor integer3 types.

Each component of period should have range of [0, INF), 0 being the default value. When period is 0 for every component, we get results that are exactly the same as before.

There is a small issue with fractal3d though: the result will be tileable only if lacunarity is an integer value (it's a float parameter).

And to clarify, the period parameter is the integer distance at which the noise function returns the same value for points or texture coordinates repeated at that step.

rafalSFX avatar Jan 20 '23 15:01 rafalSFX

The current draft of the v1.39 spec @rafalSFX refers to has a single integer "period" input for the various noise functions. This enforces the period to in fact be an integer value, but has the obvious limitation that the same period value would be applied to all channels of a vector2/3/4 type. Would it be preferable to change "period" to be a float or vectorN input, so that each channel could have its own period value? If so, what should implementations do if a non-integer value for a channel of "period" is provided: run it through a floor() so the value is enforced to be integer? Or do we simply let the period take non-integer values and end up with non-tileable results?

dbsmythe avatar Jan 20 '23 23:01 dbsmythe

A few thoughts:

OSL provides periodic versions of noise. For the n-D domain functions, the periods are always n-D as well. It seems like a strange limitation to only allow a single period to apply to all dimensions.

The underlying mathematical implementation of the noise functions is a hermite interpolation of discrete values at integer lattice points, so the period itself needs to be integer valued, or the whole thing doesn't really make sense. The periodicity is achieved in how you look up the values for those lattice points, not by periodically windowing the result of the interpolation (which would be akin to pnoise(x,p) == noise(fmod(x,p)).

If you tried to switch to an fmod-like thing for non-integer period values (I assume that's what Doug means for "end up with non-tileable"), you would have a weird situation where the integer-period results would look very different from almost-integer period, and numerical precision issues on how you compute the period could have very strange artifacts or temporal flipping between the two modes. I wouldn't recommend that. The alternate methods of forcing it to an integer value (by floor, or maybe ceil is better?) would always be tileable, but not with the period you requested, so also a bit weird, and also could still lead to spatial or temporal seams where you suddenly jump to the next higher or lower periodicity at integer boundaries, ick.

The last concern I'll add is that noise is already a little expensive, and I wouldn't want to the implementations to have to add any unnecessary extra per-call tests and branches, for example, an underlying "different code path for exact integer values versus non-integer periods" or even a "single noise function that takes a period, but there is a different behavior if the period is a special value like inf or 0 to indicate the nonperiodic kind" -- better, I think, to have a separate call or node for nonperiodic infinite expanse noise than for the periodic variety, so each one is doing precisely the right thing without needing to adjudicate different underlying algorithms?

lgritz avatar Jan 21 '23 05:01 lgritz

Following up on this earlier request, I would agree with @lgritz's suggestion, where we would add periodic noise nodes that are separate from the existing, non-periodic versions, allowing the code paths for each version to remain as simple as possible.

How does this idea sound to you, @rafalSFX and @dbsmythe?

jstone-lucasfilm avatar Mar 21 '24 23:03 jstone-lucasfilm

Agreed- separate periodic versions of noise nodes would be preferable.

dbsmythe avatar Mar 22 '24 00:03 dbsmythe

No major objections. Sounds like a reasonable approach.

rafalSFX avatar Mar 22 '24 15:03 rafalSFX