Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

three.js - Why does EffectsComposer unintentionally make a custom shaderMaterial brighter by default?

In Three.js, it seems that if you add an empty EffectsComposer, your shaderMaterials unintentionally get brighter and look blown out.

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

question from:https://stackoverflow.com/questions/65879643/why-does-effectscomposer-unintentionally-make-a-custom-shadermaterial-brighter-b

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It seems adding a composer also enables color space conversion. To fix the issues, you have to do a couple of things:

  • Set the encoding property of your texture to sRGBEncoding
  • Use the three.js function mapTexelToLinear() to convert texels to linear color space
  • For consistency, add the #include <encodings_fragment> shader chunk to your code (not necessary to fix the issue but important if you use no post processing but change the output encoding of the renderer).
  • Assign the texture to ShaderMaterial.map so the renderer can configure mapTexelToLinear() with the correct code.
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 />
    </>
  );
}


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...