在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>