为什么 EffectsComposer 在默认情况下无意中使自定义 shaderMaterial 更亮?

Why does EffectsComposer unintentionally make a custom shaderMaterial brighter by default?

在 Three.js 中,似乎如果您添加一个空的 EffectsComposer,您的 shaderMaterials 会无意中变得更亮并且看起来过时了。

https://codesandbox.io/s/effects-composer-shader-conflict-mysyn

似乎添加作曲家也可以启用颜色 space 转换。要解决这些问题,您必须做几件事:

  • 将纹理的 encoding 属性 设置为 sRGBEncoding
  • 使用three.js函数mapTexelToLinear()将纹素转换为线性颜色space
  • 为了保持一致性,将 #include <encodings_fragment> 着色器块添加到您的代码中(不是解决问题所必需的,但如果您不使用 post 处理但更改渲染器的输出编码则很重要)。
  • 将纹理分配给 ShaderMaterial.map,以便渲染器可以使用正确的代码配置 mapTexelToLinear()
import './styles.css';
import { TextureLoader, ShaderMaterial, sRGBEncoding } from 'three';
import { useMemo } from 'react';
import { EffectComposer } from '@react-three/postprocessing';

export default function App() {
  const texture = new TextureLoader().load('crate.gif');
  texture.encoding = sRGBEncoding;

  const shaderMaterial = useMemo(
    () =>
      new ShaderMaterial({
        fragmentShader: `
        uniform sampler2D u_Txt1;
        varying vec2 vUv;
        void main() {
          gl_FragColor = mapTexelToLinear( texture2D(u_Txt1, vUv) );
          #include <encodings_fragment>
        }`,
        uniforms: {
          u_Txt1: { value: texture }
        },
        vertexShader: `#include <common>
        varying vec2 vUv;
        void main () {
          vUv = uv;
          gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
        }`
      }),
    [texture]
  );
  shaderMaterial.map = texture;

  return (
    <>
      <mesh name="screen" scale={[10, 10, 1]} material={shaderMaterial}>
        {/* <meshBasicMaterial map={texture} color={0xffffff} /> */}
        <planeBufferGeometry args={[1, 1]} />
      </mesh>
      <EffectComposer />
    </>
  );
}