我正在try 使用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

图像组件代码:

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;

除了错误我的网站工作正常,只有图像不被渲染.我已确认图像已成功通过props .但是,该图像不会在画布上渲染.画布以粉色背景正确渲染.

如何解决此着色器错误?

推荐答案

纹理采样器统一的名称不能是texture,因为texture是GLSL ES 3.00中内置函数的名称.我建议使用tDiffuse,因为它在三个EJ中很常见.

更改统一变量的设置:

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

Javascript相关问答推荐

使用CDO时如何将Vue组件存储在html之外?

React对话框模式在用户单击预期按钮之前出现

仅在React和JS中生成深色

用相器进行向内碰撞检测

fetch在本地设置相同来源的cookie,但部署时相同的代码不会设置cookie

如何将拖放功能添加到我已自定义为图像的文件输入HTML标签中?

如何使用Echart 5.5.0创建箱形图

如何修复循环HTML元素附加函数中的问题?

Vega中的模运算符

togglePopover()不打开但不关闭原生HTML popover'

WebRTC关闭navigator. getUserMedia正确

Chromium会将URL与JS一起传递到V8吗?

如何在Vue 3中创建自定义 Select 组件,并将选项作为HTML而不是props 传递?

使用POST请求时,Req.Body为空

将核心模块导入另一个组件模块时存在多个主题

如何在JAVASCRIPT中临时删除eventListener?

TinyMCE 6导致Data:Image对象通过提供的脚本过度上载

是否可以在不更改组件标识的情况下换出Reaction组件定义(以维护状态/引用等)?如果是这样的话,是如何做到的呢?

如何设置时间选取器的起始值,仅当它获得焦点时?

将字体样式应用于material -UI条形图图例