From 6039cb14121cd38fb330180fc21d474e1572134b Mon Sep 17 00:00:00 2001 From: Yukti Nandwana Date: Sun, 5 Apr 2026 15:38:49 +0530 Subject: [PATCH 1/2] feat(webgl): add texCoord parameter to getFinalColor hook --- src/webgl/p5.RendererGL.js | 8 ++++---- src/webgl/p5.Shader.js | 2 +- src/webgl/shaders/basic.frag | 5 +++-- src/webgl/shaders/line.frag | 2 +- src/webgl/shaders/normal.frag | 5 +++-- src/webgl/shaders/phong.frag | 2 +- src/webgpu/p5.RendererWebGPU.js | 6 +++--- src/webgpu/shaders/color.js | 2 +- src/webgpu/shaders/line.js | 2 +- src/webgpu/shaders/material.js | 2 +- 10 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index b744baff19..edd4f9969b 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -723,7 +723,7 @@ class RendererGL extends Renderer3D { color.a = components.opacity; return color; }`, - "vec4 getFinalColor": "(vec4 color) { return color; }", + "vec4 getFinalColor": "(vec4 color, vec2 texCoord) { return color; }", "void afterFragment": "() {}", }, } @@ -760,7 +760,7 @@ class RendererGL extends Renderer3D { }, fragment: { "void beforeFragment": "() {}", - "vec4 getFinalColor": "(vec4 color) { return color; }", + "vec4 getFinalColor": "(vec4 color, vec2 texCoord) { return color; }", "void afterFragment": "() {}", }, } @@ -788,7 +788,7 @@ class RendererGL extends Renderer3D { }, fragment: { "void beforeFragment": "() {}", - "vec4 getFinalColor": "(vec4 color) { return color; }", + "vec4 getFinalColor": "(vec4 color, vec2 texCoord) { return color; }", "void afterFragment": "() {}", }, } @@ -820,7 +820,7 @@ class RendererGL extends Renderer3D { fragment: { "void beforeFragment": "() {}", "Inputs getPixelInputs": "(Inputs inputs) { return inputs; }", - "vec4 getFinalColor": "(vec4 color) { return color; }", + "vec4 getFinalColor": "(vec4 color, vec2 texCoord) { return color; }", "bool shouldDiscard": "(bool outside) { return outside; }", "void afterFragment": "() {}", }, diff --git a/src/webgl/p5.Shader.js b/src/webgl/p5.Shader.js index a881825948..753c5180bd 100644 --- a/src/webgl/p5.Shader.js +++ b/src/webgl/p5.Shader.js @@ -172,7 +172,7 @@ class Shader { * color.a = components.opacity; * return color; * } - * vec4 getFinalColor(vec4 color) { return color; } + * vec4 getFinalColor(vec4 color, vec2 texCoord) { return color; } * void afterFragment() {} * ``` * diff --git a/src/webgl/shaders/basic.frag b/src/webgl/shaders/basic.frag index 1406964ca9..b7db52b1ad 100644 --- a/src/webgl/shaders/basic.frag +++ b/src/webgl/shaders/basic.frag @@ -1,7 +1,8 @@ IN vec4 vColor; +IN highp vec2 vVertTexCoord; void main(void) { HOOK_beforeFragment(); - OUT_COLOR = HOOK_getFinalColor(vColor); + OUT_COLOR = HOOK_getFinalColor(vColor, vVertTexCoord); OUT_COLOR.rgb *= OUT_COLOR.a; // Premultiply alpha before rendering HOOK_afterFragment(); -} +} \ No newline at end of file diff --git a/src/webgl/shaders/line.frag b/src/webgl/shaders/line.frag index a0ca059040..b1ed298b0d 100644 --- a/src/webgl/shaders/line.frag +++ b/src/webgl/shaders/line.frag @@ -69,6 +69,6 @@ void main() { discard; } } - OUT_COLOR = HOOK_getFinalColor(vec4(inputs.color.rgb, 1.) * inputs.color.a); + OUT_COLOR = HOOK_getFinalColor(vec4(inputs.color.rgb, 1.) * inputs.color.a, vec2(0.0, 0.0)); HOOK_afterFragment(); } diff --git a/src/webgl/shaders/normal.frag b/src/webgl/shaders/normal.frag index 0cb362265a..fbb9258547 100644 --- a/src/webgl/shaders/normal.frag +++ b/src/webgl/shaders/normal.frag @@ -1,6 +1,7 @@ IN vec3 vVertexNormal; +IN highp vec2 vVertTexCoord; void main(void) { HOOK_beforeFragment(); - OUT_COLOR = HOOK_getFinalColor(vec4(vVertexNormal, 1.0)); + OUT_COLOR = HOOK_getFinalColor(vec4(vVertexNormal, 1.0), vVertTexCoord); HOOK_afterFragment(); -} +} \ No newline at end of file diff --git a/src/webgl/shaders/phong.frag b/src/webgl/shaders/phong.frag index 78cfb76163..47ec519d47 100644 --- a/src/webgl/shaders/phong.frag +++ b/src/webgl/shaders/phong.frag @@ -77,7 +77,7 @@ void main(void) { c.ambient = inputs.ambientLight; c.specular = specular; c.emissive = inputs.emissiveMaterial; - OUT_COLOR = HOOK_getFinalColor(HOOK_combineColors(c)); + OUT_COLOR = HOOK_getFinalColor(HOOK_combineColors(c), vTexCoord); OUT_COLOR.rgb *= OUT_COLOR.a; // Premultiply alpha before rendering HOOK_afterFragment(); } diff --git a/src/webgpu/p5.RendererWebGPU.js b/src/webgpu/p5.RendererWebGPU.js index 2b616e4a63..b52d0dc599 100644 --- a/src/webgpu/p5.RendererWebGPU.js +++ b/src/webgpu/p5.RendererWebGPU.js @@ -2345,7 +2345,7 @@ function rendererWebGPU(p5, fn) { rgb += components.emissive; return vec4(rgb, components.opacity); }`, - "vec4f getFinalColor": "(color: vec4) { return color; }", + "vec4f getFinalColor": "(color: vec4, texCoord: vec2) { return color; }", "void afterFragment": "() {}", }, } @@ -2370,7 +2370,7 @@ function rendererWebGPU(p5, fn) { }, fragment: { "void beforeFragment": "() {}", - "vec4 getFinalColor": "(color: vec4) { return color; }", + "vec4 getFinalColor": "(color: vec4, texCoord: vec2) { return color; }", "void afterFragment": "() {}", }, } @@ -2396,7 +2396,7 @@ function rendererWebGPU(p5, fn) { fragment: { "void beforeFragment": "() {}", "Inputs getPixelInputs": "(inputs: Inputs) { return inputs; }", - "vec4 getFinalColor": "(color: vec4) { return color; }", + "vec4 getFinalColor": "(color: vec4, texCoord: vec2) { return color; }", "bool shouldDiscard": "(outside: bool) { return outside; };", "void afterFragment": "() {}", }, diff --git a/src/webgpu/shaders/color.js b/src/webgpu/shaders/color.js index cea80efc9b..cf4ab00285 100644 --- a/src/webgpu/shaders/color.js +++ b/src/webgpu/shaders/color.js @@ -119,7 +119,7 @@ ${uniforms} @fragment fn main(input: FragmentInput) -> @location(0) vec4 { HOOK_beforeFragment(); - var outColor = HOOK_getFinalColor(input.vColor); + var outColor = HOOK_getFinalColor(input.vColor, input.vVertTexCoord); outColor = vec4(outColor.rgb * outColor.a, outColor.a); HOOK_afterFragment(); return outColor; diff --git a/src/webgpu/shaders/line.js b/src/webgpu/shaders/line.js index a46317cee6..2b58857286 100644 --- a/src/webgpu/shaders/line.js +++ b/src/webgpu/shaders/line.js @@ -362,7 +362,7 @@ fn main(input: StrokeFragmentInput) -> @location(0) vec4 { discard; } } - var col = HOOK_getFinalColor(inputs.color); + var col = HOOK_getFinalColor(inputs.color, vec2(0.0, 0.0)); col = vec4(col.rgb, 1.0) * col.a; HOOK_afterFragment(); return vec4(col); diff --git a/src/webgpu/shaders/material.js b/src/webgpu/shaders/material.js index a740e9d17a..9da60f4628 100644 --- a/src/webgpu/shaders/material.js +++ b/src/webgpu/shaders/material.js @@ -417,7 +417,7 @@ fn main(input: FragmentInput) -> @location(0) vec4 { ); var outColor = HOOK_getFinalColor( - HOOK_combineColors(components) + HOOK_combineColors(components), input.vTexCoord ); outColor = vec4(outColor.rgb * outColor.a, outColor.a); HOOK_afterFragment(); From 31ad84a617f2c6de4cf3fffb3fb98f3a897d09a3 Mon Sep 17 00:00:00 2001 From: Yukti Nandwana Date: Sun, 5 Apr 2026 17:09:45 +0530 Subject: [PATCH 2/2] feat(webgl): add texCoord parameter to getFinalColor hook --- test/unit/visual/cases/webgl.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/unit/visual/cases/webgl.js b/test/unit/visual/cases/webgl.js index 7e1889674e..41420ba3cd 100644 --- a/test/unit/visual/cases/webgl.js +++ b/test/unit/visual/cases/webgl.js @@ -1134,6 +1134,21 @@ visualSuite('WebGL', function() { screenshot(); }); + visualTest('texCoord is available in getFinalColor', (p5, screenshot) => { + p5.createCanvas(50, 50, p5.WEBGL); + const shader = p5.baseColorShader().modify(() => { + getFinalColor((color) => { + color = [texCoord[0], texCoord[1], 0, 1]; + return color; + }); + }); + p5.background(0); + p5.shader(shader); + p5.noStroke(); + p5.plane(50, 50); + screenshot(); +}); + visualSuite('auto-return for shader hooks', () => { visualTest('auto-returns input struct when return is omitted', (p5, screenshot) => { p5.createCanvas(50, 50, p5.WEBGL);