diff --git a/src/math/noise.js b/src/math/noise.js index 85cbdb066c..c5fa491730 100644 --- a/src/math/noise.js +++ b/src/math/noise.js @@ -397,6 +397,22 @@ function noise(p5, fn){ } }; + /** + * @private + * Returns the current number of octaves used by noise(). + */ + fn._getNoiseOctaves = function() { + return perlin_octaves; + }; + + /** + * @private + * Returns the current falloff factor used by noise(). + */ + fn._getNoiseAmpFalloff = function() { + return perlin_amp_falloff; + }; + /** * Sets the seed value for the noise() function. * diff --git a/src/strands/strands_api.js b/src/strands/strands_api.js index 3ee5f15666..7e649d0731 100644 --- a/src/strands/strands_api.js +++ b/src/strands/strands_api.js @@ -104,6 +104,20 @@ export function initGlobalStrandsAPI(p5, fn, strandsContext) { } // Add GLSL noise. TODO: Replace this with a backend-agnostic implementation const originalNoise = fn.noise; + const originalNoiseDetail = fn.noiseDetail; + + strandsContext._noiseOctaves = null; + strandsContext._noiseAmpFalloff = null; + + fn.noiseDetail = function (lod, falloff) { + if (!strandsContext.active) { + return originalNoiseDetail.apply(this, arguments); + } + + strandsContext._noiseOctaves = lod; + strandsContext._noiseAmpFalloff = falloff; + }; + fn.noise = function (...args) { if (!strandsContext.active) { return originalNoise.apply(this, args); // fallback to regular p5.js noise @@ -131,9 +145,20 @@ export function initGlobalStrandsAPI(p5, fn, strandsContext) { `It looks like you've called noise() with ${args.length} arguments. It only supports 1D to 3D input.` ); } + + const octaves = strandsContext._noiseOctaves !== null + ? strandsContext._noiseOctaves + : fn._getNoiseOctaves(); + const falloff = strandsContext._noiseAmpFalloff !== null + ? strandsContext._noiseAmpFalloff + : fn._getNoiseAmpFalloff(); + + nodeArgs.push(octaves); + nodeArgs.push(falloff); + const { id, dimension } = build.functionCallNode(strandsContext, 'noise', nodeArgs, { overloads: [{ - params: [DataType.float3], + params: [DataType.float3, DataType.int1, DataType.float1], returnType: DataType.float1, }] }); diff --git a/src/webgl/shaders/functions/noise3DGLSL.glsl b/src/webgl/shaders/functions/noise3DGLSL.glsl index 58dea1129f..e0bca75aa7 100644 --- a/src/webgl/shaders/functions/noise3DGLSL.glsl +++ b/src/webgl/shaders/functions/noise3DGLSL.glsl @@ -93,15 +93,16 @@ float baseNoise(vec3 v) dot(p2,x2), dot(p3,x3) ) ); } -float noise(vec3 st) { +float noise(vec3 st, int octaves, float ampFalloff) { float result = 0.0; float amplitude = 1.0; float frequency = 1.0; - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 8; i++) { + if (i >= octaves) break; result += amplitude * baseNoise(st * frequency); frequency *= 2.0; - amplitude *= 0.5; + amplitude *= ampFalloff; } return result;