React项目中使用Three.js加载GLSL着色器报错求助
问题分析
报错信息里的/static/media/vertex.b0f036220a7b64047a36.glsl是文件的打包路径,被直接插入到Three.js生成的着色器代码中,导致语法错误。核心原因是React项目的构建工具(Webpack/Vite)默认未将.glsl文件识别为纯文本资源,而是处理成了资源路径,而非文件内容。
解决方案
一、Create React App(Webpack)环境
CRA默认隐藏Webpack配置,需借助craco修改配置:
- 安装依赖
npm install craco craco-glsl-loader --save-dev
- 项目根目录创建
craco.config.js
const glslLoader = require('craco-glsl-loader'); module.exports = { plugins: [{ plugin: glslLoader }], };
- 修改
package.json的启动脚本
"scripts": { "start": "craco start", "build": "craco build", "test": "craco test" }
二、Vite环境
Vite对自定义资源支持更友好,只需在配置中声明:
- 修改
vite.config.js
import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; export default defineConfig({ plugins: [react()], assetsInclude: ['**/*.glsl'], });
若需更精确控制,可安装raw-loader并配置:
npm install raw-loader --save-dev
export default defineConfig({ plugins: [react()], module: { rules: [ { test: /\.(glsl|vs|fs|vert|frag)$/, use: ['raw-loader'], }, ], }, });
三、无需配置的替代方案
直接将着色器代码写在JS/TS文件中,用模板字符串包裹:
const vertexShader = ` uniform vec2 uFrequency; uniform float uTime; varying vec2 vUv; varying float vElevation; void main() { vec4 modelPosition = modelMatrix * vec4(position, 1.0); float elevation = sin(modelPosition.x * uFrequency.x - uTime*4.0) * 0.01; elevation += sin(modelPosition.y * uFrequency.y - uTime*2.0) * 0.01; modelPosition.z += elevation; vec4 viewPosition = viewMatrix * modelPosition; vec4 projectedPosition = projectionMatrix * viewPosition; gl_Position = projectedPosition; vUv = uv; vElevation = elevation; } `; const fragmentShader = ` uniform vec3 uColor; uniform sampler2D uTexture; varying vec2 vUv; varying float vElevation; void main() { vec4 textureColor = texture2D(uTexture, vUv); textureColor.rgb *= vElevation * 2.0 + 0.85; gl_FragColor = textureColor; } `;
之后直接在ShaderMaterial中使用这两个变量即可。
验证
修改配置后重启开发服务器,确保导入的vertexShader和fragmentShader是字符串形式的着色器代码,而非文件路径,此时ShaderMaterial即可正常编译。
内容的提问来源于stack exchange,提问作者Satya Prakash
相关产品推荐
相关产品推荐

