Three.js中文网 Three.js中文网
首页
免费视频
系统课 (opens new window)
  • Three.js基础课程
  • Vue3+Threejs 3D可视化
  • Threejs进阶课程
  • 展厅3D预览漫游
  • Threejs Shader
  • Blender建模基础
  • Three.js基础课程(旧版本) (opens new window)
  • 文章
WebGPU教程
  • WebGL教程
  • WebGL教程(旧版本) (opens new window)
3D案例
  • 本站部署(打开快) (opens new window)
  • 原英文官网文档 (opens new window)
首页
免费视频
系统课 (opens new window)
  • Three.js基础课程
  • Vue3+Threejs 3D可视化
  • Threejs进阶课程
  • 展厅3D预览漫游
  • Threejs Shader
  • Blender建模基础
  • Three.js基础课程(旧版本) (opens new window)
  • 文章
WebGPU教程
  • WebGL教程
  • WebGL教程(旧版本) (opens new window)
3D案例
  • 本站部署(打开快) (opens new window)
  • 原英文官网文档 (opens new window)
Web3D系统课程视频
  • 0.学前说明

  • 1.Three.js快速入门

  • 2.几何体BufferGeometry

  • 3.模型对象、材质

  • 4.层级模型

  • 5.顶点UV坐标、纹理贴图

  • 6.加载外部三维模型(gltf)

  • 7.PBR材质与纹理贴图

  • 8.渲染器和前端UI界面

    • 1. three.js Canvas画布布局
    • 2. UI交互界面与Canvas画布叠加
    • 3. UI交互按钮与3D场景交互
    • 4. Three.js背景透明度
    • 5. Three.js渲染结果保存为图片
    • 6. 深度冲突(模型闪烁)
      • 7. 模型加载进度条
    • 9.生成曲线、几何体

    • 10.相机基础

    • 11.光源和阴影

    • 12.精灵模型Sprite

    • 13.后处理EffectComposer

    • 14.射线拾取模型

    • 15.场景标注标签信息

    • 16.关键帧动画

    • 17.动画库tween.js

    • Three.js教程
    • 8.渲染器和前端UI界面
    郭隆邦
    2023-01-29
    目录

    6. 深度冲突(模型闪烁)

    # 深度冲突(模型闪烁)

    本节课通过一个比较简单的案例,来给大家展示一下,实际开发的过程中,你可能会遇到的模型闪烁问题。

    对于模型闪烁的原因简单地说就是深度冲突,对应的英文关键词是Z-fighting。

    # Mesh面重合渲染测试

    下面代码创建两个重合的矩形平面Mesh,通过浏览器预览,当你旋转三维场景的时候,你会发现模型渲染的时候产生闪烁。

    这种现象,主要是两个Mesh重合,电脑GPU分不清谁在前谁在后,这种现象,可以称为深度冲突Z-fighting。

    // 两个矩形平面Mesh重合,产生闪烁
    // 闪烁原因:两个矩形面位置重合,GPU无法分清谁在前谁在后
    const geometry = new THREE.PlaneGeometry(250, 250);
    const material = new THREE.MeshLambertMaterial({
        color: 0x00ffff,
        side: THREE.DoubleSide,
    });
    const mesh = new THREE.Mesh(geometry, material);
    
    
    const geometry2 = new THREE.PlaneGeometry(300, 300); 
    const material2 = new THREE.MeshLambertMaterial({
        color: 0xff6666,
        side: THREE.DoubleSide,
    });
    const mesh2 = new THREE.Mesh(geometry2, material2);
    

    # 两个矩形Mesh拉开距离

    适当偏移,解决深度冲突,偏移尺寸相对模型尺寸比较小,视觉上两个平面近似还是重合效果。

    mesh2.position.z = 1;
    

    # 建模注意

    上面代码测试提醒我们,在三维软件中建模的的时候,尽量避免两个Mesh完全重合,可以考虑适当偏移一定的距离。

    # 间隙很小,深度冲突

    当两个面间隙很小,也可能出现深度冲突。从纯理论的角度,你能分清0和0.0000...0000001的大小,但是实际上,电脑GPU精度是有限的。

    // 当两个面间隙很小,也可能出现深度冲突。
    mesh2.position.z = 0.0000000000000000000001;
    

    # 透视投影相机对距离影响(深度冲突)

    第1步:设置两个Mesh平面的距离相差0.1,课件中案例源码你可以看到,没有深度冲突导致的模型闪烁问题

    mesh2.position.z = 0;
    mesh2.position.z = 0.1;
    camera.position.set(292, 223, 185);
    

    第2步:改变相机.position属性,你会发现当相机距离三维模型较远的时候,两个面也可能出现深度冲突,当然你也可以通过相机控件OrbitControls缩放功能,改变相机与模型的距离,进行观察。

    camera.position.set(292*5, 223*5, 185*5)
    

    透视投影相机的投影规律是远小近大,和人眼观察世界一样,模型距离相机越远,模型渲染的效果越小,两个mesh之间的间距同样也会变小。当两个Mesh和相机距离远到一定程度,两个模型的距离也会无限接近0。

    # webgl渲染器设置对数深度缓冲区

    两个矩形平面距离比较近,相差0.1

    mesh2.position.z = 0;
    mesh2.position.z = 0.1;
    camera.position.set(292*5, 223*5, 185*5);
    

    当一个三维场景中有一些面距离比较近,有深度冲突,你可以尝试设置webgl渲染器设置对数深度缓冲区logarithmicDepthBuffer: true来优化或解决。logarithmicDepthBuffer: true作用简单来说,就是两个面间距比较小的时候,让threejs更容易区分两个面,谁在前,谁在后。

    // WebGL渲染器设置
    const renderer = new THREE.WebGLRenderer({
        // 设置对数深度缓冲区,优化深度冲突问题
        logarithmicDepthBuffer: true
    });
    

    有一点要注意,当两个面间隙过小,或者重合,你设置webgl渲染器对数深度缓冲区也是无效的。

    mesh2.position.z = 0;
    //当两个面重合,logarithmicDepthBuffer: true无效
    mesh2.position.z = 0;
    //当两个面间隙过小,logarithmicDepthBuffer: true无效
    mesh2.position.z = 0.00001;
    camera.position.set(292*5, 223*5, 185*5);
    
    5. Three.js渲染结果保存为图片
    7. 模型加载进度条

    ← 5. Three.js渲染结果保存为图片 7. 模型加载进度条→

    Theme by Vdoing | Copyright © 2016-2025 豫ICP备16004767号-2
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式