如何为p5.js WEBGL模式下的3D对象设置两种不同均匀纯色
p5.js WEBGL 3D模型上下分纯色实现方案
问题原因
你之前尝试的几类方案无法实现均匀分色是必然的:
- 环境光、自发光材质:属于全局统一着色逻辑,没有空间位置判断能力,只能给整个模型赋单一颜色
- 平行光、点光源:着色亮度由面片法线与光源夹角、光源距离衰减共同计算,不同朝向的面片受光强度天然不一致,必然出现明暗渐变,不可能输出无差别的纯色块
实现思路
放弃光照系统,直接使用自定义着色器,根据模型顶点的Y轴坐标判断所属区域,直接输出对应纯色,完全跳过光照计算,从根源避免色差问题。
完整实现代码
// 上下分色自定义着色器 const splitColorShader = { vertex: ` precision mediump float; attribute vec3 aPosition; uniform mat4 uProjectionMatrix; uniform mat4 uModelViewMatrix; varying float vPosY; void main() { vec4 viewPos = uModelViewMatrix * vec4(aPosition, 1.0); vPosY = viewPos.y; // 把顶点Y坐标传递给片元着色器 gl_Position = uProjectionMatrix * viewPos; } `, fragment: ` precision mediump float; varying float vPosY; uniform vec3 topColor; uniform vec3 bottomColor; void main() { // Y坐标大于0为上半区,小于0为下半区 vec3 fillColor = vPosY > 0.0 ? topColor : bottomColor; gl_FragColor = vec4(fillColor, 1.0); } ` }; let customShader; function setup() { createCanvas(400, 400, WEBGL); customShader = createShader(splitColorShader.vertex, splitColorShader.fragment); } function draw() { background(220); noStroke(); // 启用自定义分色着色器 shader(customShader); // 设置上半部分为蓝色,下半部分为红色,参数为0-1范围的RGB值 customShader.setUniform('topColor', [0, 0, 1]); customShader.setUniform('bottomColor', [1, 0, 0]); // 加Y轴旋转方便观察分色效果,不需要可删除 rotateY(frameCount * 0.01); // 绘制圆环 torus(100, 40); // 绘制完成后重置为默认着色器,避免影响其他图形绘制 resetShader(); }
代码运行需p5.js 1.5.0版本的WEBGL环境支持。
可调参数说明
- 分色边界:修改片元着色器中
vPosY > 0.0的判断阈值,即可调整上下分界的高度位置 - 配色:修改
setUniform传入的RGB值即可自定义上下区域颜色 - 通用性:该方案对p5.js WEBGL模式下所有3D几何体生效,不局限于圆环模型
内容的提问来源于stack exchange,提问作者Drone
相关产品推荐
相关产品推荐

