【问题标题】:Why is shader not working on specific models为什么着色器不适用于特定模型
【发布时间】:2022-01-25 10:26:25
【问题描述】:

作为 Matrix 粉丝和 three.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;

可能是什么原因?我相信我缺少一些关于图形或 gltf/glb 的背景知识

感谢任何有关如何调试此类问题的建议。

【问题讨论】:

  • @Rabbid76 感谢您的提醒!我已经在帖子中添加了代码,希望它能澄清问题。
  • 有什么问题?代码框链接对我来说似乎很好用。我看到模型上的矩阵纹理。
  • @2pha 如果将 l24 上的模型源修改为“models/arwing.glb”,着色器将无法工作,只会显示黑色外观。

标签: three.js shader react-three-fiber


【解决方案1】:

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

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

我会检查材质是否是数组的实例,并为每个材质应用着色器

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

【讨论】:

    【解决方案2】:

    加载 arwing 模型并更改着色器以仅输出颜色作品,因此在我看来该模型没有设置 UV 坐标。

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

    【讨论】:

    • 感谢您指出要走的路,因为作为图形新手,我对 UV 坐标一无所知。非常感谢。如果我解决了问题,我会回到这个问题
    猜你喜欢
    • 1970-01-01
    • 2019-11-16
    • 1970-01-01
    • 2018-01-06
    • 2022-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多