You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Three.js自定义GLTF模型上应用Ocean海洋着色器

代码存在的核心问题

  • 传入Water构造器的第一个参数要求是BufferGeometry/Geometry类型,你现在传的是完整的Mesh对象waterGeo,会直接导致初始化失败
  • 变量waterGeo没有显式声明,存在作用域污染问题,且如果GLTF模型内有多个Mesh的话,只会保留最后遍历到的Mesh
  • water.rotation.x = - Math.PI / 2 是官方示例给平面海面设置的旋转角度,用在自定义3D模型上会导致模型姿态异常
  • 开头定义的waterMat没有实际使用,可以删除
  • 你贴出的代码片段缺少loader.load回调、以及遍历函数的闭合括号,实际运行会触发语法错误

修正后代码

const loader = new GLTFLoader().setPath( 'models/gltf/DamagedHelmet/glTF/' );
loader.load( 'DamagedHelmet.gltf', function ( gltf ) {
    let targetGeo;
    let meshTransform;
    gltf.scene.traverse( function ( child ) {
        if ( child.isMesh ) {
            targetGeo = child.geometry;
            // 保存原模型的位置/旋转/缩放信息
            meshTransform = child.matrix;
        }
    } );

    // 加载水法线纹理
    const waterNormals = new THREE.TextureLoader().load( 'textures/waternormals.jpg', function ( texture ) {
        texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
    } );

    const water = new Water(
        targetGeo,
        {
            textureWidth: 512,
            textureHeight: 512,
            waterNormals: waterNormals,
            sunDirection: new THREE.Vector3(0, 1, 0).normalize(), // 可根据光照调整阳光方向
            sunColor: 0xffffff,
            waterColor: 0x001e0f,
            distortionScale: 3.7,
            fog: scene.fog !== undefined
        }
    );

    // 继承原模型的变换属性,避免位置偏移
    water.applyMatrix4(meshTransform);
    scene.add(water);
});

额外注意事项

  • 渲染循环中需要添加时间参数更新逻辑,否则波浪动画不会运行:
    function animate() {
      requestAnimationFrame(animate);
      // 同步更新水材质的时间 uniforms
      water.material.uniforms.time.value += 1 / 60;
      renderer.render(scene, camera);
    }
    
  • 如果自定义模型包含多个Mesh,需要给每个Mesh单独创建Water实例,或者提前合并所有Mesh的几何体为单个BufferGeometry再使用
  • 可通过调整distortionScale参数、水法线纹理的重复次数,适配不同尺寸的模型,避免波浪效果失真

内容的提问来源于stack exchange,提问作者Onur Caba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 01:45:04