From a0abc41253a1b153ef137dfc8652ccdcc7bfee33 Mon Sep 17 00:00:00 2001 From: Harsh Date: Sun, 19 Oct 2025 01:40:20 +0530 Subject: [PATCH 1/2] Add methods to retrieve noise parameters for WebGL shaders --- src/math/noise.js | 16 ++++++++++++++++ src/strands/strands_api.js | 14 ++++++++++++++ src/webgl/shaders/functions/noise3DGLSL.glsl | 5 +++-- 3 files changed, 33 insertions(+), 2 deletions(-) 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 8c85488eea..c3e69e943e 100644 --- a/src/strands/strands_api.js +++ b/src/strands/strands_api.js @@ -121,6 +121,20 @@ export function initGlobalStrandsAPI(p5, fn, strandsContext) { return originalNoise.apply(this, args); // fallback to regular p5.js noise } + const hasNoiseUniforms = strandsContext.uniforms.some(u => u.name === 'uNoiseOctaves'); + if (!hasNoiseUniforms) { + strandsContext.uniforms.push({ + name: 'uNoiseOctaves', + typeInfo: DataType.int1, + defaultValue: () => p5._getNoiseOctaves() + }); + strandsContext.uniforms.push({ + name: 'uNoiseAmpFalloff', + typeInfo: DataType.float1, + defaultValue: () => p5._getNoiseAmpFalloff() + }); + } + strandsContext.vertexDeclarations.add(noiseGLSL); strandsContext.fragmentDeclarations.add(noiseGLSL); // Handle noise(x, y) as noise(vec2) diff --git a/src/webgl/shaders/functions/noise3DGLSL.glsl b/src/webgl/shaders/functions/noise3DGLSL.glsl index 58dea1129f..27d6ca37c5 100644 --- a/src/webgl/shaders/functions/noise3DGLSL.glsl +++ b/src/webgl/shaders/functions/noise3DGLSL.glsl @@ -98,10 +98,11 @@ float noise(vec3 st) { float amplitude = 1.0; float frequency = 1.0; - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 8; i++) { + if (i >= uNoiseOctaves) break; result += amplitude * baseNoise(st * frequency); frequency *= 2.0; - amplitude *= 0.5; + amplitude *= uNoiseAmpFalloff; } return result; From eb3448cb8c62b56b8bc977faf38fadcff95de37f Mon Sep 17 00:00:00 2001 From: Harsh Date: Sun, 19 Oct 2025 16:13:13 +0530 Subject: [PATCH 2/2] add suggested changes --- src/strands/strands_api.js | 44 ++++++++++++-------- src/webgl/shaders/functions/noise3DGLSL.glsl | 6 +-- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/strands/strands_api.js b/src/strands/strands_api.js index c3e69e943e..6420af4a08 100644 --- a/src/strands/strands_api.js +++ b/src/strands/strands_api.js @@ -116,28 +116,28 @@ export function initGlobalStrandsAPI(p5, fn, strandsContext) { // Add GLSL noise. TODO: Replace this with a backend-agnostic implementation const originalNoise = fn.noise; - fn.noise = function (...args) { + const originalNoiseDetail = fn.noiseDetail; + + strandsContext._noiseOctaves = null; + strandsContext._noiseAmpFalloff = null; + + fn.noiseDetail = function (lod, falloff) { if (!strandsContext.active) { - return originalNoise.apply(this, args); // fallback to regular p5.js noise + return originalNoiseDetail.apply(this, arguments); } - const hasNoiseUniforms = strandsContext.uniforms.some(u => u.name === 'uNoiseOctaves'); - if (!hasNoiseUniforms) { - strandsContext.uniforms.push({ - name: 'uNoiseOctaves', - typeInfo: DataType.int1, - defaultValue: () => p5._getNoiseOctaves() - }); - strandsContext.uniforms.push({ - name: 'uNoiseAmpFalloff', - typeInfo: DataType.float1, - defaultValue: () => p5._getNoiseAmpFalloff() - }); + strandsContext._noiseOctaves = lod; + strandsContext._noiseAmpFalloff = falloff; + }; + + fn.noise = function (...args) { + if (!strandsContext.active) { + return originalNoise.apply(this, args); } strandsContext.vertexDeclarations.add(noiseGLSL); strandsContext.fragmentDeclarations.add(noiseGLSL); - // Handle noise(x, y) as noise(vec2) + let nodeArgs; if (args.length === 3) { nodeArgs = [fn.vec3(args[0], args[1], args[2])]; @@ -147,10 +147,20 @@ export function initGlobalStrandsAPI(p5, fn, strandsContext) { nodeArgs = args; } + const octaves = strandsContext._noiseOctaves !== null + ? strandsContext._noiseOctaves + : p5._getNoiseOctaves(); + const falloff = strandsContext._noiseAmpFalloff !== null + ? strandsContext._noiseAmpFalloff + : p5._getNoiseAmpFalloff(); + + nodeArgs.push(octaves); + nodeArgs.push(falloff); + const { id, dimension } = build.functionCallNode(strandsContext, 'noise', nodeArgs, { overloads: [{ - params: [DataType.float3], - returnType: DataType.float1, + params: [DataType.float3, DataType.int1, DataType.float1], + returnType: DataType.float1 }] }); return createStrandsNode(id, dimension, strandsContext); diff --git a/src/webgl/shaders/functions/noise3DGLSL.glsl b/src/webgl/shaders/functions/noise3DGLSL.glsl index 27d6ca37c5..e0bca75aa7 100644 --- a/src/webgl/shaders/functions/noise3DGLSL.glsl +++ b/src/webgl/shaders/functions/noise3DGLSL.glsl @@ -93,16 +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 < 8; i++) { - if (i >= uNoiseOctaves) break; + if (i >= octaves) break; result += amplitude * baseNoise(st * frequency); frequency *= 2.0; - amplitude *= uNoiseAmpFalloff; + amplitude *= ampFalloff; } return result;