You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Three.js中vec3颜色属性在片元着色器中会被插值?

问题根源

你看到的渐变是GPU渲染管线的顶点属性插值机制导致的。PlaneGeometry表面上是4个顶点,但它的内部索引结构会把平面拆分成两个三角形(总共6个顶点索引)。你只给了4个颜色值,GPU在渲染三角形时,会自动对三角形内部的每个片元进行顶点颜色的平滑插值计算,所以最终呈现出渐变效果。

两种解决方法

方法1:为每个三角形顶点分配对应颜色

直接扩展你的颜色数组,给PlaneGeometry的6个顶点索引都分配对应的颜色值(每个三角形的三个顶点用同一种颜色)。比如PlaneGeometry的两个三角形顶点顺序通常是0,1,2和0,2,3,你可以把4个颜色扩展成6个:

// 原始4个颜色
const baseColors = [
  new THREE.Color(0xff0000),
  new THREE.Color(0x00ff00),
  new THREE.Color(0x0000ff),
  new THREE.Color(0xffff00)
];
// 扩展为6个,对应两个三角形的顶点
const fullColors = [
  baseColors[0], baseColors[1], baseColors[2],
  baseColors[0], baseColors[2], baseColors[3]
];
// 转换为浮点数组
const colorBuffer = new Float32Array(fullColors.length * 3);
fullColors.forEach((color, i) => color.toArray(colorBuffer, i * 3));
// 为几何体添加属性
geometry.setAttribute('myColor', new THREE.BufferAttribute(colorBuffer, 3));

这样每个三角形的三个顶点颜色完全一致,GPU插值后就会呈现纯色块。

方法2:使用flat限定符关闭插值

在顶点着色器的varying变量前添加flat关键字,强制GPU不对该变量进行插值,每个三角形会使用其第一个顶点的颜色填充整个面片:

顶点着色器:

attribute vec3 myColor;
flat varying vec3 vColor;

void main() {
  vColor = myColor;
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

片元着色器:

flat varying vec3 vColor;

void main() {
  gl_FragColor = vec4(vColor, 1.0);
}

这种方法不需要修改颜色数组,适合想保留原始顶点数量的场景。

内容的提问来源于stack exchange,提问作者Justin Seo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 03:47:16