Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharlie Jolly <charlie>2021-10-18 12:12:22 +0300
committerCharlie Jolly <mistajolly@gmail.com>2021-10-18 16:24:14 +0300
commit729b2d026d1379de92908b16e7492a509721c796 (patch)
tree7cd9396e59006f9bbd5135e6c4556df25040bae5 /source/blender/blenlib
parentde6bf5d4d2f1f832f8305c519fc88d8896ea9a0b (diff)
Geometry Nodes: Add shader Musgrave texture node
Port shader node musgrave texture Differential Revision: https://developer.blender.org/D12701
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r--source/blender/blenlib/BLI_noise.hh99
-rw-r--r--source/blender/blenlib/intern/noise.cc718
2 files changed, 817 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_noise.hh b/source/blender/blenlib/BLI_noise.hh
index 93980e3569e..a7af69f42a9 100644
--- a/source/blender/blenlib/BLI_noise.hh
+++ b/source/blender/blenlib/BLI_noise.hh
@@ -113,6 +113,105 @@ float3 perlin_float3_fractal_distorted(float4 position,
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Musgrave Multi Fractal
+ * \{ */
+
+float musgrave_ridged_multi_fractal(const float co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset,
+ const float gain);
+float musgrave_ridged_multi_fractal(const float2 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset,
+ const float gain);
+float musgrave_ridged_multi_fractal(const float3 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset,
+ const float gain);
+float musgrave_ridged_multi_fractal(const float4 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset,
+ const float gain);
+
+float musgrave_hybrid_multi_fractal(const float co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset,
+ const float gain);
+float musgrave_hybrid_multi_fractal(const float2 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset,
+ const float gain);
+float musgrave_hybrid_multi_fractal(const float3 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset,
+ const float gain);
+float musgrave_hybrid_multi_fractal(const float4 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset,
+ const float gain);
+
+float musgrave_fBm(const float co, const float H, const float lacunarity, const float octaves);
+float musgrave_fBm(const float2 co, const float H, const float lacunarity, const float octaves);
+float musgrave_fBm(const float3 co, const float H, const float lacunarity, const float octaves);
+float musgrave_fBm(const float4 co, const float H, const float lacunarity, const float octaves);
+
+float musgrave_multi_fractal(const float co,
+ const float H,
+ const float lacunarity,
+ const float octaves);
+float musgrave_multi_fractal(const float2 co,
+ const float H,
+ const float lacunarity,
+ const float octaves);
+float musgrave_multi_fractal(const float3 co,
+ const float H,
+ const float lacunarity,
+ const float octaves);
+float musgrave_multi_fractal(const float4 co,
+ const float H,
+ const float lacunarity,
+ const float octaves);
+
+float musgrave_hetero_terrain(const float co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset);
+float musgrave_hetero_terrain(const float2 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset);
+float musgrave_hetero_terrain(const float3 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset);
+float musgrave_hetero_terrain(const float4 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset);
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Voronoi Noise
* \{ */
diff --git a/source/blender/blenlib/intern/noise.cc b/source/blender/blenlib/intern/noise.cc
index a6c3377b71f..812e6ddd181 100644
--- a/source/blender/blenlib/intern/noise.cc
+++ b/source/blender/blenlib/intern/noise.cc
@@ -756,6 +756,724 @@ float3 perlin_float3_fractal_distorted(float4 position,
perlin_fractal(position + random_float4_offset(5.0f), octaves, roughness));
}
+/* --------------
+ * Musgrave Noise
+ * --------------
+ */
+
+/* 1D Musgrave fBm
+ *
+ * H: fractal increment parameter
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ *
+ * from "Texturing and Modelling: A procedural approach"
+ */
+
+float musgrave_fBm(const float co, const float H, const float lacunarity, const float octaves)
+{
+ float p = co;
+ float value = 0.0f;
+ float pwr = 1.0f;
+ const float pwHL = powf(lacunarity, -H);
+
+ for (int i = 0; i < (int)octaves; i++) {
+ value += perlin_signed(p) * pwr;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ float rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ value += rmd * perlin_signed(p) * pwr;
+ }
+
+ return value;
+}
+
+/* 1D Musgrave Multifractal
+ *
+ * H: highest fractal dimension
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ */
+
+float musgrave_multi_fractal(const float co,
+ const float H,
+ const float lacunarity,
+ const float octaves)
+{
+ float p = co;
+ float value = 1.0f;
+ float pwr = 1.0f;
+ const float pwHL = powf(lacunarity, -H);
+
+ for (int i = 0; i < (int)octaves; i++) {
+ value *= (pwr * perlin_signed(p) + 1.0f);
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ const float rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ value *= (rmd * pwr * perlin_signed(p) + 1.0f); /* correct? */
+ }
+
+ return value;
+}
+
+/* 1D Musgrave Heterogeneous Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float musgrave_hetero_terrain(
+ const float co, const float H, const float lacunarity, const float octaves, const float offset)
+{
+ float p = co;
+ const float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL;
+
+ /* first unscaled octave of function; later octaves are scaled */
+ float value = offset + perlin_signed(p);
+ p *= lacunarity;
+
+ for (int i = 1; i < (int)octaves; i++) {
+ float increment = (perlin_signed(p) + offset) * pwr * value;
+ value += increment;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ const float rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ float increment = (perlin_signed(p) + offset) * pwr * value;
+ value += rmd * increment;
+ }
+
+ return value;
+}
+
+/* 1D Hybrid Additive/Multiplicative Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float musgrave_hybrid_multi_fractal(const float co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset,
+ const float gain)
+{
+ float p = co;
+ const float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL;
+
+ float value = perlin_signed(p) + offset;
+ float weight = gain * value;
+ p *= lacunarity;
+
+ for (int i = 1; (weight > 0.001f) && (i < (int)octaves); i++) {
+ if (weight > 1.0f) {
+ weight = 1.0f;
+ }
+
+ float signal = (perlin_signed(p) + offset) * pwr;
+ pwr *= pwHL;
+ value += weight * signal;
+ weight *= gain * signal;
+ p *= lacunarity;
+ }
+
+ const float rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ value += rmd * ((perlin_signed(p) + offset) * pwr);
+ }
+
+ return value;
+}
+
+/* 1D Ridged Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float musgrave_ridged_multi_fractal(const float co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset,
+ const float gain)
+{
+ float p = co;
+ const float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL;
+
+ float signal = offset - fabsf(perlin_signed(p));
+ signal *= signal;
+ float value = signal;
+ float weight = 1.0f;
+
+ for (int i = 1; i < (int)octaves; i++) {
+ p *= lacunarity;
+ weight = CLAMPIS(signal * gain, 0.0f, 1.0f);
+ signal = offset - fabsf(perlin_signed(p));
+ signal *= signal;
+ signal *= weight;
+ value += signal * pwr;
+ pwr *= pwHL;
+ }
+
+ return value;
+}
+
+/* 2D Musgrave fBm
+ *
+ * H: fractal increment parameter
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ *
+ * from "Texturing and Modelling: A procedural approach"
+ */
+
+float musgrave_fBm(const float2 co, const float H, const float lacunarity, const float octaves)
+{
+ float2 p = co;
+ float value = 0.0f;
+ float pwr = 1.0f;
+ const float pwHL = powf(lacunarity, -H);
+
+ for (int i = 0; i < (int)octaves; i++) {
+ value += perlin_signed(p) * pwr;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ const float rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ value += rmd * perlin_signed(p) * pwr;
+ }
+
+ return value;
+}
+
+/* 2D Musgrave Multifractal
+ *
+ * H: highest fractal dimension
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ */
+
+float musgrave_multi_fractal(const float2 co,
+ const float H,
+ const float lacunarity,
+ const float octaves)
+{
+ float2 p = co;
+ float value = 1.0f;
+ float pwr = 1.0f;
+ const float pwHL = powf(lacunarity, -H);
+
+ for (int i = 0; i < (int)octaves; i++) {
+ value *= (pwr * perlin_signed(p) + 1.0f);
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ const float rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ value *= (rmd * pwr * perlin_signed(p) + 1.0f); /* correct? */
+ }
+
+ return value;
+}
+
+/* 2D Musgrave Heterogeneous Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float musgrave_hetero_terrain(const float2 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset)
+{
+ float2 p = co;
+ const float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL;
+
+ /* first unscaled octave of function; later octaves are scaled */
+ float value = offset + perlin_signed(p);
+ p *= lacunarity;
+
+ for (int i = 1; i < (int)octaves; i++) {
+ float increment = (perlin_signed(p) + offset) * pwr * value;
+ value += increment;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ const float rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ float increment = (perlin_signed(p) + offset) * pwr * value;
+ value += rmd * increment;
+ }
+
+ return value;
+}
+
+/* 2D Hybrid Additive/Multiplicative Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float musgrave_hybrid_multi_fractal(const float2 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset,
+ const float gain)
+{
+ float2 p = co;
+ const float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL;
+
+ float value = perlin_signed(p) + offset;
+ float weight = gain * value;
+ p *= lacunarity;
+
+ for (int i = 1; (weight > 0.001f) && (i < (int)octaves); i++) {
+ if (weight > 1.0f) {
+ weight = 1.0f;
+ }
+
+ float signal = (perlin_signed(p) + offset) * pwr;
+ pwr *= pwHL;
+ value += weight * signal;
+ weight *= gain * signal;
+ p *= lacunarity;
+ }
+
+ const float rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ value += rmd * ((perlin_signed(p) + offset) * pwr);
+ }
+
+ return value;
+}
+
+/* 2D Ridged Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float musgrave_ridged_multi_fractal(const float2 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset,
+ const float gain)
+{
+ float2 p = co;
+ const float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL;
+
+ float signal = offset - fabsf(perlin_signed(p));
+ signal *= signal;
+ float value = signal;
+ float weight = 1.0f;
+
+ for (int i = 1; i < (int)octaves; i++) {
+ p *= lacunarity;
+ weight = CLAMPIS(signal * gain, 0.0f, 1.0f);
+ signal = offset - fabsf(perlin_signed(p));
+ signal *= signal;
+ signal *= weight;
+ value += signal * pwr;
+ pwr *= pwHL;
+ }
+
+ return value;
+}
+
+/* 3D Musgrave fBm
+ *
+ * H: fractal increment parameter
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ *
+ * from "Texturing and Modelling: A procedural approach"
+ */
+
+float musgrave_fBm(const float3 co, const float H, const float lacunarity, const float octaves)
+{
+ float3 p = co;
+ float value = 0.0f;
+ float pwr = 1.0f;
+ const float pwHL = powf(lacunarity, -H);
+
+ for (int i = 0; i < (int)octaves; i++) {
+ value += perlin_signed(p) * pwr;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ const float rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ value += rmd * perlin_signed(p) * pwr;
+ }
+
+ return value;
+}
+
+/* 3D Musgrave Multifractal
+ *
+ * H: highest fractal dimension
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ */
+
+float musgrave_multi_fractal(const float3 co,
+ const float H,
+ const float lacunarity,
+ const float octaves)
+{
+ float3 p = co;
+ float value = 1.0f;
+ float pwr = 1.0f;
+ const float pwHL = powf(lacunarity, -H);
+
+ for (int i = 0; i < (int)octaves; i++) {
+ value *= (pwr * perlin_signed(p) + 1.0f);
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ const float rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ value *= (rmd * pwr * perlin_signed(p) + 1.0f); /* correct? */
+ }
+
+ return value;
+}
+
+/* 3D Musgrave Heterogeneous Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float musgrave_hetero_terrain(const float3 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset)
+{
+ float3 p = co;
+ const float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL;
+
+ /* first unscaled octave of function; later octaves are scaled */
+ float value = offset + perlin_signed(p);
+ p *= lacunarity;
+
+ for (int i = 1; i < (int)octaves; i++) {
+ float increment = (perlin_signed(p) + offset) * pwr * value;
+ value += increment;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ const float rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ float increment = (perlin_signed(p) + offset) * pwr * value;
+ value += rmd * increment;
+ }
+
+ return value;
+}
+
+/* 3D Hybrid Additive/Multiplicative Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float musgrave_hybrid_multi_fractal(const float3 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset,
+ const float gain)
+{
+ float3 p = co;
+ const float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL;
+
+ float value = perlin_signed(p) + offset;
+ float weight = gain * value;
+ p *= lacunarity;
+
+ for (int i = 1; (weight > 0.001f) && (i < (int)octaves); i++) {
+ if (weight > 1.0f) {
+ weight = 1.0f;
+ }
+
+ float signal = (perlin_signed(p) + offset) * pwr;
+ pwr *= pwHL;
+ value += weight * signal;
+ weight *= gain * signal;
+ p *= lacunarity;
+ }
+
+ const float rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ value += rmd * ((perlin_signed(p) + offset) * pwr);
+ }
+
+ return value;
+}
+
+/* 3D Ridged Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float musgrave_ridged_multi_fractal(const float3 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset,
+ const float gain)
+{
+ float3 p = co;
+ const float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL;
+
+ float signal = offset - fabsf(perlin_signed(p));
+ signal *= signal;
+ float value = signal;
+ float weight = 1.0f;
+
+ for (int i = 1; i < (int)octaves; i++) {
+ p *= lacunarity;
+ weight = CLAMPIS(signal * gain, 0.0f, 1.0f);
+ signal = offset - fabsf(perlin_signed(p));
+ signal *= signal;
+ signal *= weight;
+ value += signal * pwr;
+ pwr *= pwHL;
+ }
+
+ return value;
+}
+
+/* 4D Musgrave fBm
+ *
+ * H: fractal increment parameter
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ *
+ * from "Texturing and Modelling: A procedural approach"
+ */
+
+float musgrave_fBm(const float4 co, const float H, const float lacunarity, const float octaves)
+{
+ float4 p = co;
+ float value = 0.0f;
+ float pwr = 1.0f;
+ const float pwHL = powf(lacunarity, -H);
+
+ for (int i = 0; i < (int)octaves; i++) {
+ value += perlin_signed(p) * pwr;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ const float rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ value += rmd * perlin_signed(p) * pwr;
+ }
+
+ return value;
+}
+
+/* 4D Musgrave Multifractal
+ *
+ * H: highest fractal dimension
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ */
+
+float musgrave_multi_fractal(const float4 co,
+ const float H,
+ const float lacunarity,
+ const float octaves)
+{
+ float4 p = co;
+ float value = 1.0f;
+ float pwr = 1.0f;
+ const float pwHL = powf(lacunarity, -H);
+
+ for (int i = 0; i < (int)octaves; i++) {
+ value *= (pwr * perlin_signed(p) + 1.0f);
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ const float rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ value *= (rmd * pwr * perlin_signed(p) + 1.0f); /* correct? */
+ }
+
+ return value;
+}
+
+/* 4D Musgrave Heterogeneous Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float musgrave_hetero_terrain(const float4 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset)
+{
+ float4 p = co;
+ const float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL;
+
+ /* first unscaled octave of function; later octaves are scaled */
+ float value = offset + perlin_signed(p);
+ p *= lacunarity;
+
+ for (int i = 1; i < (int)octaves; i++) {
+ float increment = (perlin_signed(p) + offset) * pwr * value;
+ value += increment;
+ pwr *= pwHL;
+ p *= lacunarity;
+ }
+
+ const float rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ float increment = (perlin_signed(p) + offset) * pwr * value;
+ value += rmd * increment;
+ }
+
+ return value;
+}
+
+/* 4D Hybrid Additive/Multiplicative Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float musgrave_hybrid_multi_fractal(const float4 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset,
+ const float gain)
+{
+ float4 p = co;
+ const float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL;
+
+ float value = perlin_signed(p) + offset;
+ float weight = gain * value;
+ p *= lacunarity;
+
+ for (int i = 1; (weight > 0.001f) && (i < (int)octaves); i++) {
+ if (weight > 1.0f) {
+ weight = 1.0f;
+ }
+
+ float signal = (perlin_signed(p) + offset) * pwr;
+ pwr *= pwHL;
+ value += weight * signal;
+ weight *= gain * signal;
+ p *= lacunarity;
+ }
+
+ const float rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ value += rmd * ((perlin_signed(p) + offset) * pwr);
+ }
+
+ return value;
+}
+
+/* 4D Ridged Multifractal Terrain
+ *
+ * H: fractal dimension of the roughest area
+ * lacunarity: gap between successive frequencies
+ * octaves: number of frequencies in the fBm
+ * offset: raises the terrain from `sea level'
+ */
+
+float musgrave_ridged_multi_fractal(const float4 co,
+ const float H,
+ const float lacunarity,
+ const float octaves,
+ const float offset,
+ const float gain)
+{
+ float4 p = co;
+ const float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL;
+
+ float signal = offset - fabsf(perlin_signed(p));
+ signal *= signal;
+ float value = signal;
+ float weight = 1.0f;
+
+ for (int i = 1; i < (int)octaves; i++) {
+ p *= lacunarity;
+ weight = CLAMPIS(signal * gain, 0.0f, 1.0f);
+ signal = offset - fabsf(perlin_signed(p));
+ signal *= signal;
+ signal *= weight;
+ value += signal * pwr;
+ pwr *= pwHL;
+ }
+
+ return value;
+}
+
/*
* Voronoi: Ported from Cycles code.
*