首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在aframe/3 js中渲染成本较低的球体?

如何在aframe/3 js中渲染成本较低的球体?
EN

Stack Overflow用户
提问于 2020-05-29 20:16:19
回答 1查看 190关注 0票数 1

我有一个虚拟现实的应用程序,呈现了很多领域。内置的aframe <a-sphere>元素使用三角形呈现球体,因此我的场景中有大量的三角形。这正在扼杀表演,把帧率降到青少年的水平。是否有一个更有效的球体,像我可以使用的物体?这些球体真的不需要做什么特别的事情,我愿意牺牲它们的外观,以便能够在不扼杀性能的情况下渲染更多的球体。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-29 21:24:54

您可以求助于InstancedMesh,它使用GPU实例在一个绘图调用中呈现重复的几何图形。

检查下面的演示。呈现1000个元素通常需要1000个单独的绘图,大大降低了性能。但是,有了实例,您可以在相同的通行证中呈现它们。

代码语言:javascript
复制
var camera, scene, renderer, stats;

			var mesh;
			var amount = parseInt( window.location.search.substr( 1 ) ) || 10;
			var count = Math.pow( amount, 3 );
			var dummy = new THREE.Object3D();

			init();
			animate();

			function init() {

				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 100 );
				camera.position.set( amount * 0.9, amount * 0.9, amount * 0.9 );
				camera.lookAt( 0, 0, 0 );

				scene = new THREE.Scene();

				var loader = new THREE.BufferGeometryLoader();
				loader.load( 'https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/json/suzanne_buffergeometry.json', function ( geometry ) {

					geometry.computeVertexNormals();
					geometry.scale( 0.5, 0.5, 0.5 );

					var material = new THREE.MeshNormalMaterial();
					// check overdraw
					// var material = new THREE.MeshBasicMaterial( { color: 0xff0000, opacity: 0.1, transparent: true } );

					mesh = new THREE.InstancedMesh( geometry, material, count );
					mesh.instanceMatrix.setUsage( THREE.DynamicDrawUsage ); // will be updated every frame
					scene.add( mesh );

					//

					var gui = new dat.GUI();
					gui.add( mesh, 'count', 0, count );

				} );

				//

				renderer = new THREE.WebGLRenderer( { antialias: true } );
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( window.innerWidth, window.innerHeight );
				document.body.appendChild( renderer.domElement );

				//

				stats = new Stats();
				document.body.appendChild( stats.dom );

				//

				window.addEventListener( 'resize', onWindowResize, false );

			}

			function onWindowResize() {

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

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

			}

			//

			function animate() {

				requestAnimationFrame( animate );

				render();

				stats.update();

			}

			function render() {

				if ( mesh ) {

					var time = Date.now() * 0.001;

					mesh.rotation.x = Math.sin( time / 4 );
					mesh.rotation.y = Math.sin( time / 2 );

					var i = 0;
					var offset = ( amount - 1 ) / 2;

					for ( var x = 0; x < amount; x ++ ) {

						for ( var y = 0; y < amount; y ++ ) {

							for ( var z = 0; z < amount; z ++ ) {

								dummy.position.set( offset - x, offset - y, offset - z );
								dummy.rotation.y = ( Math.sin( x / 4 + time ) + Math.sin( y / 4 + time ) + Math.sin( z / 4 + time ) );
								dummy.rotation.z = dummy.rotation.y * 2;

								dummy.updateMatrix();

								mesh.setMatrixAt( i ++, dummy.matrix );

							}

						}

					}

					mesh.instanceMatrix.needsUpdate = true;

				}

				renderer.render( scene, camera );

			}
代码语言:javascript
复制
html, body {margin: 0; padding: 0;overflow: hidden;}
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
	<head>
		<title>three.js webgl - instancing - dynamic</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<script src="https://cdn.jsdelivr.net/npm/three@0.117.1/build/three.min.js"></script>
		<script src="https://cdn.jsdelivr.net/npm/stats.js@0.17.0/build/stats.min.js"></script>
		<script src="https://cdn.jsdelivr.net/npm/three@0.117.1/examples/js/libs/dat.gui.min.js"></script>
	</head>
	<body>

	</body>
</html>

单击此处查看演示源代码

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62093987

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档