可能你不会那么极端,在Unity嵌套Three.js再嵌套一个游戏引擎,
但是只要你用Threejs ,特别像我一样的新手,你可能会遇到下面这个问题
表面上是renderer.render()方法的问题,实际是shader的问题
Javascript - Threejs - 3d框架
three@v0.113.0:65 Uncaught (in promise) Error: Can not resolve #include <utils>
首先,可以try catch , 稍微定位是不是shader的问题,和打印堆栈
this.loaded = Promise.all(shadersPromises) .then(([vs,fs])=>{ // new material... }) .catch(err=>{ console.error("Water材质编译失败:", err); throw err; //继续抛出,方便调试 })Uncaught (in promise) Error: Can not resolve #include <utils>
报错来自Three.js RawShaderMaterial / ShaderMaterial 的
#include预处理,不是 renderer.render 这一行本身报错。 只是你的this.loadedPromise 内部编译 Shader 失败,抛出错误;Promise 的异常没有被 catch,之后执行到 render 时,错误冒泡,控制台显示栈指向 render 调用处,真正根源:GLSL 着色器的#include <utils>找不到文件片段。
根本原因
#include <utils>是 Three.jsShaderChunk 片段包含语法。
RawShaderMaterial❗不会自动内置 ShaderChunk。ShaderMaterial才会自动解析#include <xxx>,自动加载内置 chunk。
你用的是THREE.RawShaderMaterial:
RawShaderMaterial = 完全原始 GLSL,没有预处理、没有内置 #include 片段,写
#include <utils>直接报无法解析。
this.material = new THREE.RawShaderMaterial({ vertexShader: vs, fragmentShader: fs, // RawShaderMaterial 不处理 #include <utils> })方案 1:改用ShaderMaterial(最简单,推荐)
ShaderMaterial支持#include <utils>,会自动解析 Three 内置的 shader chunk。
⚠️虽然如此:ShaderMaterial 会自动加 attribute、uniform 前缀,你的 shader 语法要适配,不能完全照搬 Raw 的原始 GLSL。
this.material = new THREE.ShaderMaterial({ vertexShader: vertexShaderSource, fragmentShader: fragmentShaderSource, uniforms: { light:{value:this.light}, tiles:{value:this.tiles}, sky:{value:this.textureCube}, water:{value:null}, causticTex:{value:null}, underwater:{value:false} } })方案 2:继续使用 RawShaderMaterial
Raw 模式不支持#include,两个选择:
- 删掉 shader 里面全部
#include <utils>,把需要的代码手动复制粘贴进顶点 / 片元着色器源码; - 手动自己实现 #include 预处理器,加载
utilschunk 文本,做字符串替换(麻烦,不推荐)。
90% 该报错,都是误用 RawShaderMaterial 却写了
#include <xxx>。
为什么报错栈指向renderer.render(this.mesh, cam)?完整链路
loadFile加载 glsl 文本完成 → Promise.all resolve- new RawShaderMaterial(vs,fs) →内部 WebGL 编译 shader,遇到
#include <utils>抛出异常 - 这个错误发生在
this.loaded.then()内部,变成 Promise reject - 代码没有写
.catch(),成为unhandled promise rejection - JS 事件循环不会立刻抛出;等到下一帧,你执行
renderer.render(...)的时候,这个未处理 Promise 错误才打印到控制台。
❗假象:看起来是 render 这一行报错,实际 shader 在更早异步阶段就编译失败。mesh、material 对象虽然创建出来,但是 GPU 着色器编译失败。
============================
最后,勉强算是搞出来了
js 包了3~4层调用,算了,不搞了
===========================
UnityWebGL:::错误1:wasm63 or 32
Building Library\Bee\artifacts\WebGL\build\debug_WebGL_wasm\build.js failed with output:
wasm-ld: error: Assets/Ocean/Plugins/WebGL/ocean.bc: machine type must be wasm32 or wasm64
emcc2: error: '"F:/Program Files (x86)/2021.3.45f2c1/Editor/Data/PlaybackEngines/WebGLSupport/BuildTools/Emscripten/llvm\wasm-ld.exe" @C:\Users\Admin\AppData\Local\Temp\emscripten_1jrpmur_.rsp.utf-8' failed (1)
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
首先要拆解原因:
- 核心原因:.bc 文件的编译目标架构不是 wasm32/wasm64,而是其他(比如 x86、arm 等),Unity 在处理 WASM 相关编译时识别不到合法的机器类型。
- 常见场景:WebGL 构建、使用第三方 WASM 插件、自定义 LLVM 编译的 bc 文件导入 Unity。
步骤 1:安装 LLVM 工具链(必备)
LLVM 是处理 Bitcode/WASM 的核心工具,需安装兼容 WASM 的版本(建议 LLVM 10+):
- Windows:从 LLVM 官网 下载安装包(勾选「Add to PATH」);
- macOS/Linux:通过包管理器安装:
# macOS(Homebrew) brew install llvm # Linux(Ubuntu/Debian) sudo apt install llvm lld - 验证安装:终端执行
llc --version,能看到输出且包含WebAssembly说明支持 WASM。