Three.js深度冲突(模型闪烁)与解决方案

news/2024/11/8 2:39:31/

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);

look

两个矩形Mesh拉开距离

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

mesh2.position.z = 1;

 

间隙很小,深度冲突

当两个面间隙很小,也可能出现深度冲突。从纯理论的角度,你能分清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);

 


http://www.ppmy.cn/news/87579.html

相关文章

【使用教程】NIMC2000控制器EtherCAT通讯下SDO位置清零

NIMC2000控制器是一种高性能的运动控制器,可通过EtherCAT通讯进行控制。在使用过程中,有时需要将位置清零,这可以通过SDO命令实现。 首先,需要确保NIMC2000控制器已经通过EtherCAT连接到了主机。然后,使用SDO命令将位…

Student实体类实现HashSet集合,唯一性

Student类如下所示: package com.test.Test07;import java.util.Objects;public class Student {private int age;private String name;public int getAge() {return age;}public void setAge(int age) {this.age age;}public String getName() {return name;}pub…

澳洲学生用ChatGPT代写?澳洲多所高校使用全新反击工具检测

朋友们听句劝 ChatGPT可太危险了 ChatGPT有多火?据2月1日瑞银发布的一项研究报告显示,仅仅发布两个月,ChatGPT月活跃用户已达1亿,这是历史上增长速度最快的应用。要知道达成1亿用户的时间,Instagram用了2.5年&#xf…

Java并发体系-锁与同步-[2]

可见性设计的硬件 从硬件的级别来考虑一下可见性的问题 **1、第一个可见性的场景:**每个处理器都有自己的寄存器(register),所以多个处理器各自运行一个线程的时候,可能导致某个变量给放到寄存器里去,接着…

redis缓存数据库的使用

一,什么是redis ?为什么要用它? 简单介绍: Redis是开源的key-value缓存框架,由c语言编写,也是一款高性能的框架提供多种语言的API 。 SET 每秒11万次 取get每秒81000次。 数据完全存储在内存空间中&…

基于html+css的图片展示92

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

Python基础-数据类型转换

数据类型之间的转换 将自身的数据类型变成新的数据类型,并且拥有新的数据类型的所有功能的过程即为类型转换为方便更好的帮助处理业务,将类型变更为更适合业务场景的类型 字符串与数字之间的转换 转换要求 字符串转换为数字,需要确保字符串中没有任何的字母或者符合数字转换…

实测「360智脑」的真正实力:能否领跑国内百“模”大战?

ChatGPT 的发布,无疑掀起了一股“AI 技术”新浪潮。百度文心一言、华为盘古、商汤日日新、阿里通义千问、讯飞星火等众多大模型的接连问世,使得国内的“百模之战”进入了前所未有的白热化阶段。无论是各大互联网巨头,还是清华、复旦等知名高校…