【Three.js】遮挡剔除

这篇具有很好参考价值的文章主要介绍了【Three.js】遮挡剔除。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景

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

效果

【Three.js】遮挡剔除,前端,web,three.js,javascript,前端
【Three.js】遮挡剔除,前端,web,three.js,javascript,前端

例子

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的例子。文章来源地址https://www.toymoban.com/news/detail-637619.html

到了这里,关于【Three.js】遮挡剔除的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WEB 3D技术 three.js 3D贺卡(1) 搭建基本项目环境

    好 今天 我也是在网上学的 带着大家一起来做个3D贺卡 首先 我们要创建一个vue3的项目、 先创建一个文件夹 装我们的项目 终端执行 vue create 项目名称 例如 我的名字想叫 greetingCards 就是 因为这个名录 里面是全部都小写的 然后 下面选择 vue3 然后按下回车 等待项目创建完成

    2024年01月19日
    浏览(53)
  • WEB 3D技术 three.js 3D贺卡(3) 点光源灯光动画效果

    经过 上文 WEB 3D技术 three.js 3D贺卡(2) 加入天空与水面效果 我们将水面 和 天空的效果搭建了一下 那么 我们将四周 点光源的效果做一下 首先 我们将 renderer.toneMappingExposure 的值 改为 0.1 让效果看着明显一点 这样 整个界面就会暗下来 然后 我们在任意位置 加入代码 创建一个点

    2024年01月19日
    浏览(53)
  • 如何用Three.js + Blender打造一个web 3D展览馆

    作者:vivo 互联网前端团队- Wei Xing  运营活动新玩法层出不穷,web 3D炙手可热,本文将一步步带大家了解如何利用Three.js和Blender来打造一个沉浸式web 3D展览馆。 3D展览馆是什么,先来预览下效果: 看起来像个3D冒险类手游,用户可以操纵屏幕中央的虚拟摇杆,以第一人称视角

    2024年02月16日
    浏览(55)
  • WEB 3D技术 three.js 3D贺卡(2) 加入天空与水面效果

    上文 WEB 3D技术 three.js 3D贺卡(1) 搭建基本项目环境 我们简单搭了一个贺卡雏形 然后 我们要引入一个hdr的一个天空的效果 所以 我们需要在代码中导入 RGBELoader 这里 大家可以选择下载我的hdr资源 WEB 3D技术 three.js 3D贺卡 天空 hdr资源 下载好之后呢 我们在外面套一个 xhdr 文件夹

    2024年01月18日
    浏览(63)
  • Three.js--》前端开发者掌握3d技术不再是梦,初识threejs

            这十年来 web 得到了快速的发展,随着 webgl 的普及,网页的表现能力越来越强大,网页上已经开始可以做出很多复杂的动画和精美的效果,还可以通过 webgl 在网页中绘制高性能的3d图形,别的不说,凡是入门程序员都离不开github这个网站,细心的人都会发现,gi

    2024年02月01日
    浏览(62)
  • web3d-three.js场景设计器-天空包围盒-TWEEN.js

    THREE.JS 实现场景天空包围盒,为了让场景背景更具体,而不是呆板的纯色,可以给厂家添加围绕的包围盒。 这里使用球体来实现,球体中央则是场景 给球体添加天空的渐变色 加入场景 代码如下 function createSky( hemiLight) {   const vertexShader = `varying vec3 vWorldPosition;     void main

    2024年01月23日
    浏览(46)
  • WEB 3D技术 three.js draco解压器 解决 压缩后的gltf/glb报错 Error: THREE.GLTFLoader: No DRACOLoader instance pravid

    通常 我们 glb/gltf里面都是非常大的场景 有些工具 它会因为过大做了压缩 导致 我们开始是用不了的 我们可以官网搜索 draco 如下图选择 这是个解压工具 用在我们各种的3D建模软件中 大部分是通用的 我们先在代码中导入工具 我们在项目根目录中 找到 node_modules下的 three 然后

    2024年04月16日
    浏览(45)
  • web3d-three.js场景设计器-sprite广告牌

    three.js使用Sprite精灵实现文字或者图片广告牌 1.将文字绘制到Canvas,调整对应宽高。 2.作为Cavans材质绑定到Sprite 3.加载到场景调整适当的scale function createLabel({ text, fontSize, textColor, color, imageUrl }) {     return new Promise((resolve, reject) = {         let canvas = document.createElement(\\\'canvas\\\')

    2024年02月02日
    浏览(52)
  • Web3D开发经验分享:基于Three.js的Web3D建模案例

    个人主页: 左本Web3D,更多案例预览请点击==》 在线案例 个人简介:专注Web3D使用ThreeJS实现3D效果技巧和学习案例 💕 💕积跬步以至千里,致敬每个爱学习的你。喜欢的话请三连,有问题请私信或者加微信         随着互联网的快速发展,Web3D技术也越来越成熟,越来越

    2024年02月13日
    浏览(49)
  • web 3d场景构建+three.js+室内围墙,仓库,楼梯,货架模型等,第一人称进入场景案例

      翻到了之前的一个案例,基于three.js做的仓库布局模拟,地图元素除了大模型外,其他都是通过JSON数据解析动态生成的,例如墙体,柱子门口,地标等,集成了第一人称的插件可以第一人称进入场景有需要的可以下载看看,对想入门的朋友应该有一些参考价值。 /**    *创

    2024年02月10日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包