Skip to content

在Three.js的世界中,颜色的准确性对于创建逼真的3D场景至关重要。纹理的.encoding属性和渲染器的.outputEncoding(或新版本中的.outputColorSpace)是确保颜色正确显示的关键因素。让我们深入了解这些概念,并探索如何通过调整它们来避免颜色偏差。

纹理的.encoding属性

纹理的.encoding属性决定了纹理数据的颜色空间编码方式。Three.js提供了两种主要的颜色空间编码:

  • THREE.LinearEncoding:线性颜色空间,这是默认值。
  • THREE.sRGBEncoding:sRGB颜色空间,更接近人眼对颜色的感知。

示例代码:设置纹理的.encoding

javascript
const texture = new THREE.TextureLoader().load('path/to/your/texture.jpg');
texture.encoding = THREE.LinearEncoding; // 默认值
console.log('texture.encoding', texture.encoding); // THREE.LinearEncoding

// 修改为sRGB颜色空间
texture.encoding = THREE.sRGBEncoding;
console.log('texture.encoding', texture.encoding); // THREE.sRGBEncoding

渲染器的.outputEncoding

渲染器的.outputEncoding属性(在新版本中为.outputColorSpace)决定了渲染器输出颜色的方式。默认情况下,它与纹理对象的.encoding属性值相同,都是THREE.LinearEncoding

示例代码:设置渲染器的.outputEncoding

javascript
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 设置渲染器输出颜色空间为sRGB
renderer.outputEncoding = THREE.sRGBEncoding;

GLTF模型的纹理编码

当Three.js加载GLTF模型时,模型中的纹理默认使用THREE.sRGBEncoding。这意味着,如果你的渲染器也设置为sRGB颜色空间,通常不需要额外调整。

示例代码:检查GLTF模型纹理的.encoding

javascript
gltf.scene.traverse(function (obj) {
    if (obj.isMesh && obj.material.map) {
        console.log('.encoding', obj.material.map.encoding); // 通常为3001 (THREE.sRGBEncoding)
    }
});

完整的示例代码

让我们将这些概念整合到一个完整的示例中,展示如何在Three.js中加载GLTF模型,并确保颜色正确显示。

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Three.js Texture Encoding Example</title>
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
</head>
<body>
    <script type="importmap">
    {
      "imports": {
        "three": "https://threejs.org/build/three.module.js",
        "three/addons/": "https://threejs.org/examples/jsm/"
      }
    }
    </script>
    <script type="module">
      import * as THREE from 'three';
      import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

      const scene = new THREE.Scene();
      const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
      const renderer = new THREE.WebGLRenderer();
      renderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(renderer.domElement);

      const loader = new GLTFLoader();

      loader.load('path/to/your/model.gltf', function (gltf) {
          scene.add(gltf.scene);

          // 确保渲染器输出颜色空间与模型纹理匹配
          renderer.outputColorSpace = THREE.SRGBColorSpace;

          camera.position.set(0, 0, 5);
          render();
      });

      function render() {
          requestAnimationFrame(render);
          renderer.render(scene, camera);
      }
    </script>
</body>
</html>

Theme by threelab