为什么着色器不适用于特定模型

Why is shader not working on specific models

作为黑客帝国的粉丝和三个新手。js/r3f/react/shader,我决定用类似矩阵的着色器来试用它们。

我浏览了文档并找到了一些示例代码并设法将它们组合起来,这就是我得到的:https://codesandbox.io/s/react-fox-matrix-shader-test-g3i4n?file=/src/App.js

import React, { Suspense, useRef } from "react";
import { Canvas, useLoader, useFrame, useThree } from "@react-three/fiber";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import fragmentShader from "./fragment.js";
import vertexShader from "./vertex.js";
import * as THREE from "three";
import { OrbitControls } from "@react-three/drei";

const clock = new THREE.Clock();

const uniforms = {
  u_resolution: { value: { x: window.innerWidth, y: window.innerHeight } },
  u_time: { value: 0.0 }
};

const matrixMaterial = new THREE.ShaderMaterial({
  vertexShader: vertexShader,
  fragmentShader: fragmentShader,
  uniforms
});

const Model = () => {
  const group = useRef();
  const gltf = useLoader(GLTFLoader, "models/scene.gltf"); //Modify to arwing.glb and shader is not working
  const model = gltf.scene;

  model.traverse((m) => {
    if (m instanceof THREE.Mesh) {
      m.material = matrixMaterial;
      m.material.side = THREE.DoubleSide;
    }
  });

  useFrame(() => {
    matrixMaterial.uniforms.u_time.value = clock.getElapsedTime();
    group.current.rotation.y += 0.004;
  });

  return <primitive ref={group} object={model} />;
};

export default function App() {
  const canvasRef = useRef();
  return (
    <>
      <Canvas
        ref={canvasRef}
        style={{ background: "white" }}
        onCreated={({ camera }) => {
          camera.position.set(0, 20, 30);
        }}
      >
        <directionalLight />
        <Suspense fallback={null}>
          <Model />
        </Suspense>
        <OrbitControls />
      </Canvas>
    </>
  );
}

const vertexShader = `
    varying vec2 vUv;

    void main()
    {
        vUv = uv;
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
`;

export default vertexShader;

然而,如果您在 l24 上切换模型,则并非所有模型都能正常工作。可能是什么原因?我相信我缺少一些关于图形或 gltf/glb

的背景知识

如有任何关于如何调试此类问题的建议,我们将不胜感激。

加载 arwing 模型并将着色器更改为只输出一种颜色有效,所以在我看来模型没有设置 UV 坐标。

您将不得不使用某种 3d 编辑程序来为模型添加适当的 UV 坐标。

我不知道这是否有帮助,但有时一个网格可以有多个 material。

fox 例如,如果你想让一个盒子的每一面都有不同的纹理,你最多可以有 6 materials 用于 1 个网格。

我会检查 material 是否是数组的一个实例,并会为每个 material

应用着色器
if (m.material instanceof Array) {
    for (let i = 0; i < m.material.length; i ++) {
        m.material[i] = matrixMaterial;
        m.material[i].side = THREE.DoubleSide;
    }
} else {
    m.material = matrixMaterial;
    m.material.side = THREE.DoubleSide;
}