【问题标题】:How do I make a textured mesh object grayscale in three.js?如何在three.js中制作纹理网格对象灰度?
【发布时间】:2022-04-03 17:42:50
【问题描述】:

我想在按下按钮时使纹理对象显示为灰度,然后在再次单击按钮后保留其原始颜色。我该怎么办?

【问题讨论】:

标签: canvas three.js


【解决方案1】:

有几种方法可以解决这个问题。可能最简单的方法是准备纹理的第二个灰度版本。单击按钮时,您只需交换纹理。

另一种选择是使用简单的后处理效果,如下面的live demo。但是,这将改变整个场景的视觉外观,而不仅仅是单个对象。如果您只想操作某些对象,则需要像 OutlineEffect 这样的更高级的后处理。

还可以增强现有材质,以便您可以统一控制最终颜色到灰度值的转换。制服将是一个简单的整数值,表示开/关。

// -

【讨论】:

    【解决方案2】:

    如果您有分离的纹理图像,您还可以获取画布纹理并将新画布重新计算为单色,然后以编程方式替换模型纹理:

    // _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 模型,您需要取消翻转纹理

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-12
      相关资源
      最近更新 更多