Изображение, полученное из 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);
}

У меня была такая же проблема. Единственное, что мне помогло, это гамма-коррекция.

Другие вопросы по тегам