【发布时间】:2022-04-03 17:42:50
【问题描述】:
我想在按下按钮时使纹理对象显示为灰度,然后在再次单击按钮后保留其原始颜色。我该怎么办?
【问题讨论】:
-
可能有点矫枉过正,但you could use a 3D Lookup Table.
我想在按下按钮时使纹理对象显示为灰度,然后在再次单击按钮后保留其原始颜色。我该怎么办?
【问题讨论】:
有几种方法可以解决这个问题。可能最简单的方法是准备纹理的第二个灰度版本。单击按钮时,您只需交换纹理。
另一种选择是使用简单的后处理效果,如下面的live demo。但是,这将改变整个场景的视觉外观,而不仅仅是单个对象。如果您只想操作某些对象,则需要像 OutlineEffect 这样的更高级的后处理。
还可以增强现有材质,以便您可以统一控制最终颜色到灰度值的转换。制服将是一个简单的整数值,表示开/关。
// -
【讨论】:
如果您有分离的纹理图像,您还可以获取画布纹理并将新画布重新计算为单色,然后以编程方式替换模型纹理:
// _c 是存储为画布的原始纹理 var _canvas = document.createElement('canvas'); var _ctx = _canvas.getContext("2d"); _ctx.canvas.width = _c.width; _ctx.canvas.height = _c.height;
_ctx.drawImage(_c, 0, 0);
let imgData = _ctx.getImageData(0, 0, _c.width, _c.height);
// sandbox here, averange color is not true monochromatic, but its good enough for me https://en.wikipedia.org/wiki/Grayscale
for (let i = 0; i < imgData.data.length; i += 4) {
let avg = (imgData.data[i + 0] + imgData.data[i + 1] + imgData.data[i + 2])/3;
imgData.data[i + 0] = Math.min(avg+150,255);
imgData.data[i + 1] = Math.min(avg+150,255);
imgData.data[i + 2] = Math.min(avg+150,255);
imgData.data[i + 3] = 255;
}
_ctx.putImageData(imgData, 0, 0);
c.material.roughnessMap = new THREE.CanvasTexture(_canvas); c.material.roughnessMap.flipY = false; // 在某些情况下,例如 GLTF 模型,您需要取消翻转纹理
【讨论】: