Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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

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

1 Answer

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 />
    </>
  );
}


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...