为什么 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 />
</>
);
}
在 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 />
</>
);
}