在 Threejs 中使用toneMapping时如何避免背景图像从白色变成灰色?

dc0*_*c09 5 javascript three.js

我使用类中的以下代码来初始化渲染器:

// setup renderer
        this.renderer = new THREE.WebGLRenderer( { antialias: true });
        this.renderer.setClearColor (0xffffff, 1); // set background color
        this.renderer.outputEncoding = THREE.sRGBEncoding;
        this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
        this.renderer.toneMappingExposure = 1;
        this.renderer.physicallyCorrectLights = true;
Run Code Online (Sandbox Code Playgroud)

以下代码添加白色图像作为场景的背景:

var texture11 = new THREE.TextureLoader().load("https://www.publicdomainpictures.net/pictures/30000/velka/plain-white-background.jpg");
        
        this.scene.background = texture11 ;
Run Code Online (Sandbox Code Playgroud)

使用 时toneMapping,白色图像在场景中被渲染为灰色,如下场景:

在此输入图像描述

如何让它渲染成原来的颜色?

Mug*_*n87 2

默认情况下,纹理背景响应色调映射,如果不对着色器代码进行猴子修补,则无法防止这种情况发生。

Scene.background您可以创建自己的自定义天空盒和禁用色调映射,而不是使用。查看这段代码:

let camera, scene, renderer;

init();
animate();

function init() {

  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
  camera.position.z = 1;

  scene = new THREE.Scene();

  const loader = new THREE.CubeTextureLoader();
  loader.setPath('https://threejs.org/examples/textures/cube/Bridge2/');

  const cubeMap = loader.load(['posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg']);
  cubeMap.encoding = THREE.sRGBEncoding;

  //scene.background = cubeMap;

  const skybox = new THREE.Mesh(
    new THREE.BoxBufferGeometry(10, 10, 10),
    new THREE.ShaderMaterial({
      uniforms: THREE.UniformsUtils.clone(THREE.ShaderLib.cube.uniforms),
      vertexShader: THREE.ShaderLib.cube.vertexShader,
      fragmentShader: THREE.ShaderLib.cube.fragmentShader,
      depthTest: false,
      depthWrite: false,
      side: THREE.BackSide,
      toneMapped: false
    })
  );

  skybox.material.uniforms.envMap.value = cubeMap;

  Object.defineProperty(skybox.material, 'envMap', {

    get: function() {

      return this.uniforms.envMap.value;

    }

  });

  scene.add(skybox);

  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.outputEncoding = THREE.sRGBEncoding;
  renderer.toneMapping = THREE.ACESFilmicToneMapping;
  renderer.toneMappingExposure = 2;
  document.body.appendChild(renderer.domElement);

}

function animate() {

  requestAnimationFrame(animate);
  renderer.render(scene, camera);

}
Run Code Online (Sandbox Code Playgroud)
body {
      margin: 0;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdn.jsdelivr.net/npm/three@0.124/build/three.js"></script>
Run Code Online (Sandbox Code Playgroud)