GLB模型移动旋转后Decal无法正确投影至表面的技术问题
问题解决:Three.js中模型移动/旋转后Decal无法正确投影
根本原因
你推测的方向完全正确——DecalGeometry是基于模型初始原点状态的几何数据生成的,当前代码先创建Decal再对模型应用位置/旋转变换,导致Decal的投影几何已经固定,后续模型的变换只会让Decal跟着父节点平移旋转,但无法重新贴合模型表面。
解决方案
核心逻辑:先完成模型的所有位置、旋转变换,再创建DecalGeometry,让Decal基于模型最终的空间状态计算投影。
修改代码步骤
- 将模型的
position和rotation设置逻辑,移到调用#createDecals之前 - 强制更新模型矩阵,确保变换完全生效后再生成Decal
修改后的关键代码
generate() { return new Promise(async (resolve, reject) => { // 预加载纹理 const metalStrapsTexture = await this.#safeLoadTexture('../models/helmet/helmetFootball_metalStraps_baseColor.png'); const strapTexture = await this.#safeLoadTexture('../models/helmet/helmetFootball_strap_baseColor.png'); loader.load( './models/helmet/helmetFootball.glb', (gltf) => { const model = gltf.scene.children[0]; // 先设置模型的位置和旋转 model.position.set( this.position.x, this.position.y, this.position.z ); model.rotation.set( this.rotation.x, this.rotation.y, this.rotation.z ); // 强制更新矩阵,确保变换立即生效 model.updateMatrix(); model.updateMatrixWorld(true); // 基于模型最终状态创建Decal if (this.logoTexture) { this.#createDecals(model); } model.traverse((node) => { // ... 你的材质处理逻辑 }); resolve(model); }, (progress) => { console.log('Lade: ', (progress.loaded / progress.total * 100) + '%'); }, (error) => { console.error('Fehler beim Laden des Modells:', error); reject(error); } ); }); }
动态变换的额外处理
如果之后需要动态修改模型的位置或旋转,需要:
- 移除场景中旧的Decal Mesh
- 重新调用
#createDecals生成新的DecalGeometry,因为DecalGeometry是静态结构,不会自动跟随模型变换更新
内容的提问来源于stack exchange,提问作者Marco
相关产品推荐
相关产品推荐

