The existing Noise texture was originally designed for textures where values in the range 0-1 are useful.
For 3D space used in geometry and volumes it is useful to have signed noise.
After exploring adding a signed noise output to the existing Noise Texture I created the following patches.
D12820: Nodes: Add Vector Distortion node (WIP)
D15947: Nodes: Add Signed output value to the Noise Texture node
D15944: Nodes: Add Signed Noise node
Separate sockets:
Enum (current patch):
I'm currently in favour of D15944 and adding the function as a simple node.
Distortion using just the Signed Noise patch.
The advantage of exposing the base noise function is that it allows users to create their own noise based node groups. It decouples the function from the existing Noise texture and only exposes the noise function for a simple UI.
It is possible to use the existing noise texture for this but it needs the correct values setting plus additional nodes. The underlying code is less efficient.
/* Distortion. */
BLI_INLINE float3 perlin_distortion(float3 position, float strength)
{
return float3(perlin_signed(position + random_float3_offset(0.0f)) * strength,
perlin_signed(position + random_float3_offset(1.0f)) * strength,
perlin_signed(position + random_float3_offset(2.0f)) * strength);
}
/* Positive fractal perlin noise. */
template<typename T> float perlin_fractal_template(T position, float octaves, float roughness)
{
float fscale = 1.0f;
float amp = 1.0f;
float maxamp = 0.0f;
float sum = 0.0f;
octaves = CLAMPIS(octaves, 0.0f, 15.0f);
int n = static_cast<int>(octaves);
for (int i = 0; i <= n; i++) {
float t = perlin(fscale * position);
sum += t * amp;
maxamp += amp;
amp *= CLAMPIS(roughness, 0.0f, 1.0f);
fscale *= 2.0f;
}
float rmd = octaves - std::floor(octaves);
if (rmd == 0.0f) {
return sum / maxamp;
}
float t = perlin(fscale * position);
float sum2 = sum + t * amp;
sum /= maxamp;
sum2 /= maxamp + amp;
return (1.0f - rmd) * sum + rmd * sum2;
}vs
/* Perlin signed noise */ r_value = noise::perlin_signed(position);




