为什么着色器不适用于特定模型
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;
}
作为黑客帝国的粉丝和三个新手。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;
}