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

Three.js添加灯光后地面纹理出现波纹,如何消除?

Three.js地面纹理波纹问题的成因与解决方法

成因

这种波纹本质是纹理采样精度与实时灯光计算的叠加误差:

  • 地面作为大平面,纹理通常会重复平铺,当PointLight这类灯光进行光照计算时,GPU需要对纹理像素进行多采样来计算漫反射、衰减等效果,大平面上的采样坐标微小误差会被放大,形成周期性的波纹(类似摩尔纹)。
  • 相机移动时,纹理的mipmap采样层级、采样位置会动态变化,误差的表现形式也跟着改变,所以波纹会动态跳动。
  • 移除灯光后,仅做基础纹理采样,没有光照计算的叠加误差,波纹自然消失;而灯光参数(强度、距离、角度)只影响光照的强弱范围,无法解决采样精度的核心问题。

解决方法

  • 优化纹理过滤配置:开启mipmap并使用线性过滤,减少采样跳变带来的误差。示例代码:
    const groundTexture = new THREE.TextureLoader().load('your-ground-texture.png');
    groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
    groundTexture.repeat.set(8, 8); // 根据场景需求调整平铺次数
    groundTexture.minFilter = THREE.LinearMipmapLinearFilter;
    groundTexture.magFilter = THREE.LinearFilter;
    groundTexture.generateMipmaps = true; // 确保生成多级纹理
    
  • 给纹理加微小随机偏移:打破纹理采样的规律对齐,缓解波纹的周期性。比如:
    groundTexture.offset.set(Math.random() * 0.001, Math.random() * 0.001);
    
  • 增加地面几何体细分:给PlaneGeometry增加更多细分段数,让光照计算的顶点分布更均匀,避免大平面上的误差集中。示例:
    const groundGeo = new THREE.PlaneGeometry(200, 200, 64, 64); // 最后两个参数是细分数量
    
  • 自定义Shader优化采样精度:如果使用ShaderMaterial,在片元着色器中使用更高精度的纹理坐标计算,比如加入微小的扰动,或者用highp精度修饰变量:
    highp vec2 uv = vUv + vec2(sin(vUv.x * 0.1) * 0.0005, cos(vUv.y * 0.1) * 0.0005);
    vec4 texColor = texture2D(groundTexture, uv);
    
  • 烘焙光照到纹理:如果场景是静态的,提前用Blender等工具把PointLight的光照效果烘焙到地面纹理上,运行时无需实时计算灯光,彻底避免这类问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 08:25:01