使用自定义着色器为图像组件创建悬停状态时,如何使用 react-three-fiber 解决 React 中的着色器错误?

问题描述 投票:0回答:1

我正在尝试使用带有

react-three-fiber
的着色器创建具有悬停状态的图像组件。

着色器最初由 TheFrost 创建,可以在 https://codepen.io/frost084/full/OKZNRm.

不幸的是,我遇到了一个我不明白的错误。 错误:

REE.WebGLProgram: Shader Error 0 - VALIDATE_STATUS false

RAGMENT

Program Info Log: Fragment shader is not compiled.

ERROR: 0:106: 'texture' : function name expected
ERROR: 0:106: '=' : dimension mismatch
ERROR: 0:106: '=' : cannot convert from 'const mediump float' to 'highp 4-component vector of float'
ERROR: 0:111: 'texture' : function name expected
ERROR: 0:111: '=' : dimension mismatch
ERROR: 0:111: 'assign' : cannot convert from 'const mediump float' to 'highp 4-component vector of float'
ERROR: 0:113: 'texture' : function name expected
ERROR: 0:113: 'r' :  field selection requires structure, vector, or interface block on left hand side
ERROR: 0:114: 'texture' : function name expected
ERROR: 0:114: 'g' :  field selection requires structure, vector, or interface block on left hand side

 101:         float zoomLevel = .2;
  102:         float hoverLevel = exponentialInOut(min(1., (distance(vec2(.5), uv) * hover) + hover));
  103:         uv *= 1. - zoomLevel * hoverLevel;
  104:         uv += zoomLevel / 2. * hoverLevel;
  105:         uv = clamp(uv, 0., 1.);
> 106:         vec4 color = texture2D(texture, uv);
  107:         if(hoverLevel > 0.) {
  108:           hoverLevel = 1.-abs(hoverLevel-.5)*2.;
  109:           //Pixel displace
  110:           uv.y += color.r * hoverLevel * .05;
  111:           color = texture2D(texture, uv);
  112:           // RGBshift
o

Image组件代码:

import { useState, useMemo } from 'react';
import { TextureLoader } from 'three';
import { Canvas } from '@react-three/fiber';
import { useSpring, animated, config } from '@react-spring/three';

import { HoverImageShader } from 'shader/HoverImageShader';

const AnimatedImage = ({ src, width = '100%', height = '100%' }) => {
  const [hovered, setHover] = useState(false);

  const imgTexture = useMemo(() => {
    const loader = new TextureLoader();
    return loader.load(src);
  }, [src]);

  const { hoverValue } = useSpring({
    hoverValue: hovered ? 1 : 0,
    config: config.molasses,
  });

  return (
    <Canvas
      pixelratio={window.devicePixelRatio || 1}
      style={{ background: 'pink', width, height }}
      camera={{ fov: 75, position: [0, 0, 7] }}
    >
      <animated.mesh
        onPointerOver={() => setHover(true)}
        onPointerOut={() => setHover(false)}
      >
        <planeBufferGeometry attach='geometry' args={[10.7, 10.7]} />
        <animated.shaderMaterial
          attach='material'
          transparent
          args={[HoverImageShader]}
          uniforms-texture-value={imgTexture}
          uniforms-hover-value={hoverValue}
        />
      </animated.mesh>
    </Canvas>
  );
};

export default AnimatedImage;

除了错误我的网站工作正常,只有图像没有呈现。我已经确认图像已成功通过道具。但是,图像未在画布上呈现。画布正确呈现粉红色背景。

如何解决这个着色器错误?

javascript reactjs three.js glsl react-three-fiber
1个回答
1
投票

texture sampler uniform的名称不能是

texture
,因为
texture
是GLSL ES 3.00中内置函数的名称。我建议使用
tDiffuse
,因为它在threejs中很常见。

统一变量的更改设置:

uniforms-texture-value={imgTexture}

uniforms-tDiffuse-value={imgTexture}

更改片段着色器:

precision highp float; 

uniform sampler2D tDiffuse;
uniform float imageAspectRatio;
uniform float aspectRatio;
uniform float opacity;
uniform float hover;
varying vec2 vUv;

float exponentialInOut(float t) {
    return t == 0.0 || t == 1.0 
    ? t 
    : t < 0.5
        ? +0.5 * pow(2.0, (20.0 * t) - 10.0)
        : -0.5 * pow(2.0, 10.0 - (t * 20.0)) + 1.0;
} 

void main() {
    vec2 uv = vUv;

    // fix aspectRatio
    float u = imageAspectRatio/aspectRatio;
    if(imageAspectRatio > aspectRatio) {
    u = 1. / u;
    }

    uv.y *= u;
    uv.y -= (u)/2.-.5;

    // hover effect
    float zoomLevel = .2;
    float hoverLevel = exponentialInOut(min(1., (distance(vec2(.5), uv) * hover) + hover));
    uv *= 1. - zoomLevel * hoverLevel;
    uv += zoomLevel / 2. * hoverLevel;
    uv = clamp(uv, 0., 1.);
    vec4 color = texture2D(tDiffuse, uv);
    if(hoverLevel > 0.) {
    hoverLevel = 1.-abs(hoverLevel-.5)*2.;
    //Pixel displace
    uv.y += color.r * hoverLevel * .05;
    color = texture2D(tDiffuse, uv);
    // RGBshift
    color.r = texture2D(tDiffuse, uv+(hoverLevel)*0.01).r;
    color.g = texture2D(tDiffuse, uv-(hoverLevel)*0.01).g;
    }

    gl_FragColor = mix(vec4(1.,1.,1.,opacity), color, opacity);
}
© www.soinside.com 2019 - 2024. All rights reserved.