Изображение, полученное из useLoader @react-three/fiber с использованием shaperMaterial, имеет цвет, отличный от исходного.
Вот моя проблема, мой проект создается из приложения create-react-app, за которым следуют некоторые зависимости @react-three/fiber и glsl, я визуализирую простую planeBufferGeometry и для материала я использую ShaderMaterial
вот код для planeBufferGeometry: (Geometries.jsx)
import React, { useRef } from 'react';
import * as THREE from 'three';
import { useFrame, useLoader } from '@react-three/fiber';
import './PlaneShaderMaterial';
import tiger from './images/tiger.jpg';
export const Plane = () => {
const meshRef = useRef();
const shaderRef = useRef();
useFrame(() => {
if (shaderRef.current) {
shaderRef.current.uTime += 0.05;
}
});
const [img] = useLoader(THREE.TextureLoader, [tiger]);
return (
<mesh ref={meshRef} position={[0, 0, 0]}>
<planeBufferGeometry attach="geometry" args={[1, 1, 10, 10]} />
{/* <meshBasicMaterial side={THREE.DoubleSide} map={img} attach="material" /> */}
<planeShaderMaterial
attach="material"
ref={shaderRef}
side={THREE.DoubleSide}
uTexture={img}
/>
</mesh>
);
};
вот код для шейдерного материала: (PlaneShaderMaterial.jsx)
import * as THREE from 'three';
import { shaderMaterial } from '@react-three/drei';
import { extend } from '@react-three/fiber';
import glsl from 'babel-plugin-glsl/macro';
const uniform = {
uColor: new THREE.Color(1.0, 0.0, 0.0),
uTexture: new THREE.Texture(),
uTime: 0,
distanceFromCenter: 0,
};
const vertexShader = glsl`
precision mediump float;
varying vec2 vUv;
uniform float uTime;
void main() {
vec3 pos = position;
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
`;
const fragmentShader = glsl`
precision mediump float;
uniform vec3 uColor;
varying vec2 vUv;
uniform float uTime;
uniform sampler2D uTexture;
void main() {
vec4 t = texture2D(uTexture, vUv);
gl_FragColor = vec4(t);
}
`;
const PlaneShaderMaterial = shaderMaterial(
// Uniform
uniform,
// vertex shader
vertexShader,
// fragment shader
fragmentShader,
);
вот код в App.jsx:
import React, { Suspense } from 'react';
import './App.css';
import CameraControls from './CameraControls.jsx';
import { Canvas } from '@react-three/fiber';
import { Plane } from './Geometries';
const Scene = () => {
return (
<Canvas
gl={{ antialias: true, alpha: true }}
camera={{
fov: 70,
aspect: window.innerWidth / window.innerHeight,
near: 0.001,
far: 1000,
position: [0, 0, 2],
}}
style={{
display: 'block',
zIndex: '10',
}}
>
<CameraControls />
<Suspense fallback={null}>
<Plane />
</Suspense>
</Canvas>
);
};
function App() {
return (
<div style={{ height: '100vh', width: '100vw' }}>
<Scene />
</div>
);
}
export default App;
Это изображение после рендеринга с помощью useLoader и текстурирования с помощью shaperMaterial:
Но когда я попытался изменить материал на MeshBasicMaterial, цвет был правильным, я думаю, что проблема как-то связана с шейдерным материалом, а не с использованием реактивного волокна useLoader, который предварительно загружает изображение.
Таким образом, визуализированное изображение имеет немного более темный цвет, чем его исходный цвет. Я пытался изменить SRGBEncoding, но это не сработало. Любая идея, как сделать его таким же цветом?
1 ответ
void main() {
float gamma = 2.2;
vec3 texture = texture2D(uTexture, vUv).rgb;
texture = pow(texture, vec3(1.0 / gamma));
gl_FragColor = vec4(texture, 1.0);
}
У меня была такая же проблема. Единственное, что мне помогло, это гамма-коррекция.