3D加载程序的性能优化

通过使用数组实现连续内存,从而提高程序加载速度,

在绘制几十万个三角形的时候让它的帧数也保持在60帧

 

效果:


 

代码:

<!doctype html>
<html>
	<head>
		<meta charset="utf-8"/>
		<title>Cube</title>
		<style>body{background:#CCCCCC;margin:0;padding:0;}</style>
		<script src="js/three.js"></script>
		<!--<script src="js/three.min.js"></script>-->
	</head>
	<body>
		<script>
			var width = window.innerWidth*98/100;
			var height = window.innerHeight*98/100;
			
			var scene = new THREE.Scene();
			scene.fog = new THREE.Fog(0xcccccc, 2000, 3500);	//雾效(0xcccccc:颜色;2000:近平面;3500:远平面)近平面要大于camera的近平面,远平面要小于camera的远平面
			
			var camera = new THREE.PerspectiveCamera(27, width/height, 1,3500);
			camera.position.z = 2750;	//
			
			scene.add(new THREE.AmbientLight(0x444444));	//添加环境光
			
			var light1 = new THREE.DirectionalLight(0xffffff, 0.5);
			light1.position.set(1, 1, 1);
			scene.add(light1);
			
			var light2 = new THREE.DirectionalLight(0xffffff, 1.5);
			light2.position.set(0, -1, 0);
			scene.add(light2);
			
			var triangles = 160000;
			
			var geometry = new THREE.BufferGeometry();
			geometry.attributes = {
				index:{
					itemSize:1,
					array:new Uint16Array(triangles * 3),		//根据指定长度创建一个无符号的16位整形数组
					numItems:triangles * 3
				},
				position:{
					itemSize:3,
					array:new Float32Array(triangles * 3 * 3),	//一个三角形有三个顶点,一个顶点有x,y,z三个值
					numItems:triangles * 3 * 3
				},
				normal:{
					itemSize:3,
					array:new Float32Array(triangles * 3 * 3),
					numItems:triangles * 3 * 3
				},
				color:{
					itemSize:3,
					array:new Float32Array(triangles * 3 * 3),
					numItems:triangles * 3 * 3
				}
			}
			
			var flag = 65535/3;		//16位的整形最大能表示65535
			
			var indexes = geometry.attributes.index.array;
			for(var i=0; i<indexes.length; i++){
				indexes[i] = i % (flag*3);
			}
			
			geometry.offsets = [];
			var offsets = triangles/flag;
			for(var i=0; i<offsets; i++){
				//console.log(i);
				var offset = {
					start: i*flag*3,
					index: i*flag*3,
					count: Math.min(triangles-(i*flag),flag)*3
				};
				geometry.offsets.push(offset);
			}
			
			var positions = geometry.attributes.position.array;
			var normals = geometry.attributes.normal.array;
			var colors = geometry.attributes.color.array;
			
			var A = new THREE.Vector3();
			var B = new THREE.Vector3();
			var C = new THREE.Vector3();
			
			var CB = new THREE.Vector3();
			var AB = new THREE.Vector3();
			
			var color = new THREE.Color();
			
			var l = 600;	//立方体的边长
			var o = 12;		//三角形大小
			console.log(positions.length);
			for(var i=0; i<positions.length; i+=9){
				var x = Math.random()*l - l/2;
				var y = Math.random()*l - l/2;
				var z = Math.random()*l - l/2;
				
				var Ax = x + (Math.random()*o - o/2);
				var Ay = y + (Math.random()*o - o/2);
				var Az = z + (Math.random()*o - o/2);
				
				var Bx = x + (Math.random()*o - o/2);
				var By = y + (Math.random()*o - o/2);
				var Bz = z + (Math.random()*o - o/2);
				
				var Cx = x + (Math.random()*o - o/2);
				var Cy = y + (Math.random()*o - o/2);
				var Cz = z + (Math.random()*o - o/2);
				
				positions[i] = Ax;
				positions[i+1] = Ay;
				positions[i+2] = Az;
				
				positions[i+3] = Bx;
				positions[i+4] = By;
				positions[i+5] = Bz;
				
				positions[i+6] = Cx;
				positions[i+7] = Cy;
				positions[i+8] = Cz;
				
				A.set(Ax, Ay, Az);
				B.set(Bx, By, Bz);
				C.set(Cx, Cy, Cz);
				
				CB.subVectors(C, B);
				AB.subVectors(A, B);
				CB.cross(AB);
				
				CB.normalize();		//规范化(将法向量的长度规范为1)
				
				var Nx = CB*x;
				var Ny = CB*y;
				var Nz = CB*z;
				
				normals[i] = Nx;
				normals[i + 1] = Ny;
				normals[i + 2] = Nz;
				
				normals[i + 3] = Nx;
				normals[i + 4] = Ny;
				normals[i + 5] = Nz;
				
				normals[i + 6] = Nx;
				normals[i + 7] = Ny;
				normals[i + 8] = Nz;
				
				//颜色用R,G,B来表示,R/G/B每个分量的取值范围是0~1
				var r = x/l + 0.5;
				var g = y/l + 0.5;
				var b = z/l + 0.5;
				//console.log("r: " + r + "\tg: " + g + "\tb: " + b);
				color.setRGB(r, g, b);
				
				color[i] = color.r;
				color[i + 1] = color.g;
				color[i + 2] = color.b
				
				color[i + 3] = color.r;
				color[i + 4] = color.g;
				color[i + 5] = color.b;
				
				color[i + 6] = color.r;
				color[i + 7] = color.g;
				color[i + 8] = color.b;
			}
			
			//geometry.computeBoundingSphere();	//计算边界椭圆
			
			//var material = new THREE.MeshPhongMaterial({color:0xffffff,side:THREE.DoubleSide,vertexColors:THREE.VertexColors});
			var material = new THREE.MeshPhongMaterial( {
				color: 0xaaaaaa, ambient: 0xaaaaaa, specular: 0xffffff, shininess: 250,
				side: THREE.DoubleSide, vertexColors: THREE.VertexColors
			} );
			var mesh = new THREE.Mesh(geometry, material);
			scene.add(mesh);
			
			var renderer = new THREE.WebGLRenderer();
			//renderer = new THREE.WebGLRenderer( { antialias: false, clearColor: 0x333333, clearAlpha: 1, alpha: false } );
			renderer.setSize(width, height);
			renderer.setClearColor(scene.fog.color, 1);
			//renderer.gammaInput = true;
			//renderer.gammaOutput = true;
			//renderer.physicallyBasedShading = true;
			document.body.appendChild(renderer.domElement);
			
			function render(){
				mesh.rotation.x += 0.005;
				mesh.rotation.y += 0.005;
				renderer.render(scene, camera);
				requestAnimationFrame(render);
			}
			render();
		</script>
	</body>
</html>

 附注:

笔者当前使用的three.js版本是r56

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值