【Three.js】遮挡剔除

news2025/3/1 9:16:09

背景

考虑到场景中模型顶点过多会让fps过低,所以想把相机看不到的模型从场景中移除,来提高渲染性能,但是后续测试结果让我恍然大悟。虽然场景中的顶点数降低了很多,但是每次渲染检查遮挡的过程本身就是一个消耗性能的行为,有点适得其反了。虽然并没有解决问题,但是在此做一下探索记录。

效果

在这里插入图片描述
在这里插入图片描述

例子

index.html

<!DOCTYPE html>
<html lang="en">
	<head>
		<title>three.js webgl - geometry hierarchy</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<style>
			body {
				background:#fff;
				padding:0;
				margin:0;
				font-weight: bold;
				overflow:hidden;
			}
		</style>
	</head>
	<body>
		<!-- r58 -->
		<script src="./three.js"></script>

		<script type="module">
    	import Stats from '../jsm/libs/stats.module.js'
			var container, stats, occlusionStats;

			var camera, scene, renderer;

			var geometry;

			var mouseX = 0, mouseY = 0;
			
			var debugMode = 0;

			var windowHalfX = window.innerWidth / 2;
			var windowHalfY = window.innerHeight / 2;

			document.addEventListener( 'mousemove', onDocumentMouseMove, false );
			document.addEventListener( 'click', onDocumentClick, false );

			init();
			animate();

			function init() {

				container = document.createElement( 'div' );
				document.body.appendChild( container );

				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 10, 10000 );
				camera.position.z = 500;

				scene = new THREE.Scene();
				scene.fog = new THREE.Fog( 0xffffff, 1, 10000 );

				var geometry = new THREE.CubeGeometry( 100, 100, 100 );
				var material = new THREE.MeshNormalMaterial();
				
				for ( var gz = -10; gz < 10 ; gz++ ) {
					
					if ( gz % 3 === 0 ) continue;

					for ( var gx = -10; gx < 10 ; gx++ ) {
						
						if ( gx % 3 === 0 ) continue;
						
						var height = Math.random() * 10;
						
						for ( var gy = 0; gy < height ; gy++ ) {
							
							var mesh = new THREE.Mesh( geometry, material );
							
							mesh.occluder = true;
							mesh.occludable = THREE.EdgeOccludable;

							mesh.position.x = gx * 100;
							mesh.position.y = gy * 100;
							mesh.position.z = gz * 100;

							mesh.matrixAutoUpdate = false;
							mesh.updateMatrix();

							scene.add( mesh );

						}
						
					}
					
				}

				renderer = new THREE.WebGLRenderer();
				renderer.setSize( window.innerWidth, window.innerHeight );
				renderer.sortObjects = true;
				renderer.occlusionCulling = true;

				container.appendChild( renderer.domElement );

				stats = new Stats();
				stats.domElement.style.position = 'absolute';
				stats.domElement.style.top = '0px';
				stats.domElement.style.zIndex = 100;
				container.appendChild( stats.domElement );

				window.addEventListener( 'resize', onWindowResize, false );
				
				occlusionStats = document.createElement('DIV');
				occlusionStats.style.position = 'absolute';
				occlusionStats.style.top = '200px';
				occlusionStats.style.zIndex = 100;
				occlusionStats.style.whiteSpace = 'pre';
				occlusionStats.style.fontFamily = 'monospace';
				container.appendChild( occlusionStats );
				
				var instruction = document.createElement('P');
				instruction.textContent = 'Click to cycle through debug views';
				instruction.style.position = 'absolute';
				instruction.style.bottom = '10px';
				instruction.style.zIndex = 100;
				instruction.style.fontFamily = 'sans-serif';
				container.appendChild( instruction );
			}

			function onWindowResize() {

				windowHalfX = window.innerWidth / 2;
				windowHalfY = window.innerHeight / 2;

				camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();

				renderer.setSize( window.innerWidth, window.innerHeight );

			}

			function onDocumentMouseMove(event) {

				mouseX = event.clientX / window.innerWidth;
				mouseY = event.clientY / window.innerHeight;

			}
			
			function onDocumentClick(event) {
				
				debugMode++;
				
				if ( debugMode & 1 ) {
					
					if ( ! scene.overrideMaterial ) {

						scene.overrideMaterial = new THREE.MeshBasicMaterial({wireframe:true, color:0xff00ff});

					}
					
				}
				else if ( scene.overrideMaterial ) {

					scene.overrideMaterial = null;

				}

				if ( debugMode & 2 ) {

					if ( ! window.threejsOcclusionOverlayCanvas ) {
						var overlayCanvas = document.createElement('CANVAS');
						overlayCanvas.style.position = 'absolute';
						overlayCanvas.style.top = '0';
						overlayCanvas.style.left = '0';
						overlayCanvas.style.bottom = '0';
						overlayCanvas.style.right = '0';
						overlayCanvas.style.width = '100%';
						overlayCanvas.style.height = '100%';
						container.appendChild(overlayCanvas);
						window.threejsOcclusionOverlayCanvas = overlayCanvas;
					}
					
				}
				else if ( window.threejsOcclusionOverlayCanvas ) {
					window.threejsOcclusionOverlayCanvas.parentNode.removeChild(window.threejsOcclusionOverlayCanvas);
					window.threejsOcclusionOverlayCanvas = null;
				}

			}

			function animate() {

				requestAnimationFrame( animate );

				render();
				stats.update();

			}

			function render() {
				
				camera.position.x = Math.cos(mouseX * Math.PI) * 2000;
				camera.position.y = mouseY * 1000;
				camera.position.z = Math.sin(mouseX * Math.PI) * 2000;

				camera.lookAt( scene.position );

				renderer.render( scene, camera );

				var occlusionStatsText = '';

//				console.log(renderer.info);

				for ( var stat in renderer.info.occlusion ) {
					
					occlusionStatsText += stat + ": " + renderer.info.occlusion[ stat ] + "\n";
				}
				if ( occlusionStats.textContent !== occlusionStatsText ) {
					
					occlusionStats.textContent = occlusionStatsText;
					
				}

			}

		</script>

	</body>
</html>

three.js

rendererocclusionCulling 属性在r58版本有,最新版的该属性被移除了,移除原因我想也是我开头说的原因吧,有兴趣的同学可以深入研究一下。

webgl实现

https://tsherif.github.io/webgl2examples/occlusion.html这个是webgl的例子。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/862131.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ae 效果:CC Sphere

透视/CC Sphere Perspective/CC Sphere CC Sphere&#xff08;CC 球体&#xff09;效果可将图层映射到受光照的球体上。支持 Alpha 通道&#xff0c;球体可呈镂空状且能显示和调整内壁。 要注意&#xff0c;虽然本效果可生成一个非常生动的 3D 球体外观&#xff0c;但仍然是一个…

还在纠结QLC?Solidigm 61.44TB SSD交出了一份漂亮答卷

说起SSD&#xff0c;你最关心的是哪方面&#xff1f;容量大小&#xff1f;价格高低&#xff1f;性能快慢&#xff1f;寿命长短&#xff1f; 相信很多用户&#xff0c;尤其是懂技术、有追求的用户&#xff0c;还会非常在意NAND闪存颗粒的类型&#xff1a; SLC早已几乎销声匿迹&a…

为什么重写equals方法时必须重写hashcode方法

与 equals的区别 如果两个引用类型变量使用运算符&#xff0c;那么比较的是地址&#xff0c;它们分别指向的是否是同一地址的对象&#xff0c;结果一定是false&#xff0c;因为两个对象地址必然不同。 不能实现比较对象的值是否相同。 所有对象都有equals方法&#xff0c;默认…

车载Tbox-CAN终端数据采集实现方案

因工作关系有机会与一家做汽车数据采集公司的Tbox终端产品做数据对接。 这个产品通过can口与汽车总线交换数据&#xff0c;再将采集的数据打包通过4G以tcp报文发送到云端。云端通过解析、格式转换后保存到数据库。 本文介绍用nodejs实现tcp报文的解析&#xff0c;报文描述如下…

推荐 4 个 yyds 的 GitHub 项目

本期推荐开源项目目录&#xff1a; 1. 开源的 Markdown 编辑器 2. MetaGPT 3. SuperAGI 4. 一个舒适的笔记平台 01 开源的 Markdown 编辑器 Cherry 是腾讯开源的 Markdown 编辑器&#xff0c;基于 Javascript具有轻量简洁、易于扩展等特点&#xff0c; 它可以运行在浏览器或服…

SAP Fiori 问题收集

事务代码篇 启动工作台&#xff1a;/N/UI2/FLP 错误日志&#xff1a; /n/IWFND/ERROR_LOG 服务清单&#xff1a; /n/IWFND/MAINT_SERVICE 创建语义对象&#xff1a;/N/UI2/SEMOBJ 创建目录&#xff1a;/N/UI2/FLPD_CONF&#xff08;cross-client&#xff09;或 /N/UI2…

Vc - Qt - 绘制绿色矩形

要在Qt中绘制一个绿色矩形&#xff0c;您需要创建一个自定义的QWidget或QGraphicsView类&#xff0c;在其绘制事件中使用QPainter来绘制形状。 以下是一个简单的示例&#xff0c;演示如何在QWidget中绘制一个绿色矩形&#xff1a; #include <QWidget> #include <QPain…

小版本更新kubernetes

小版本更新kubernetes 背景 最近一段时间躺平了没有更新我的博客文档。感谢各位小伙伴一直以来的支持。 此脚本基于 https://github.com/cby-chen/Kubernetes/ 仓库内的安装部署文档。此脚本仅会升级k8s相关组件其他组件不进行升级。使用此脚本 务必是使用 该文档进行部署的集…

【Python从小白到高手】---函数基础

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【Python小白从入门到精通】&#x1f388; 本专栏旨在分享学习Python的一点学习心得&#xff0c;欢迎大家在评论区讨论&#x1f48c; 目录…

SpringBoot系列---【SpringBoot在多个profiles环境中自由切换】

SpringBoot在多个profiles环境中自由切换 1.在resource目录下新建dev&#xff0c;prod两个目录&#xff0c;并分别把dev环境的配置文件和prod环境的配置文件放到对应目录下&#xff0c;可以在配置文件中指定激活的配置文件&#xff0c;也可以默认不指定。 2.在pom.xml中最后位置…

【C++类和对象】类有哪些默认成员函数呢?(上)

目录 1. 类的6个默认成员函数 2. 构造函数(*^▽^*) 2.1 概念 2.2 特性 3. 析构函数(*^▽^*) 3.1 概念 3.2 特性 4. 拷贝构造函数(*^▽^*) 4.1 概念 4.2 特性 5. 赋值运算符重载(*^▽^*) 5.1 运算符重载 5.2 赋值运算符重载 ヾ(๑╹◡╹)&#xff89;"人总要为…

uniapp 左右滑动切换页面并切换tab

实现效果如图 要实现底部内部的左右滑动切换带动上方tab栏的切换&#xff0c;并且下方内容要实现纵向滚动 &#xff0c;所以需要swiper&#xff0c;swiper-item,scroll-view组合使用 tab栏部分 <view class"tabs"><view class"tab_item" v-for&…

Nvidia显卡驱动、CUDA、cuDNN、Anaconda及Tensorflow-GPU版本

Nvidia显卡驱动、CUDA、cuDNN、Anaconda及Tensorflow-GPU版本 一、确定版本关系二、安装过程1.安装显卡驱动2、安装CUDA3、安装cudnn4、安装TensorFlow 三、卸载 一、确定版本关系 1、CUDA与显卡驱动 https://www.nvidia.com/Download/index.aspx 2、cuDNN Toolkit与CUDA版本…

【雕爷学编程】Arduino动手做(12)---霍尔磁场传感器模块4

37款传感器与模块的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&#x…

springboot第35集:微服务与flutter安卓App开发

Google Playplay.google.com/apps/publis…[1]应用宝open.qq.com/[2]百度手机助手app.baidu.com/[3]360 手机助手dev.360.cn/[4]vivo 应用商店dev.vivo.com.cn/[5]OPPO 软件商店&#xff08;一加&#xff09;open.oppomobile.com/[6]小米应用商店dev.mi.com/[7]华为应用市场dev…

摆动序列——力扣376

文章目录 题目描述贪心题目描述 贪心 int wiggleMaxLength(vector<int>& nums){int n=nums.

Stable Diffusion基础:ControlNet之人体姿势控制

在AI绘画中精确控制图片是一件比较困难的事情&#xff0c;不过随着 ControlNet 的诞生&#xff0c;这一问题得到了很大的缓解。 今天我就给大家分享一个使用Stable Diffusion WebUI OpenPose ControlNet 复制照片人物姿势的方法&#xff0c;效果可以参考上图。 OpenPose 可以…

将vsCode 打开的多个文件分行(栏)排列,实现全部显示,便于切换文件

目录 1. 前言 2. 设置VsCode 多文件分行(栏)排列显示 1. 前言 主流编程IDE几乎都有排列切换选择所要查看的文件功能&#xff0c;如下为Visual Studio 2022的该功能界面&#xff1a; 图 1 图 2 当在Visual Studio 2022打开很多文件时&#xff0c;可以按照图1、图2所示找到自…

《Linux从练气到飞升》No.11 初识操作系统

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的…

HTML详解连载(1)

这里写目录标题 HTML定义HTML 超文本标记语言标签语法注意拓展 HTML基本骨架解释VS Code 快速生成骨架&#xff1a;标签的关系父子关系&#xff08;嵌套关系&#xff09;兄弟关系&#xff08;并列关系&#xff09; 代码格式注释 标题标签标签名:h1-h6(双标签)经验&#xff1a; …