通过使用数组实现连续内存,从而提高程序加载速度,
在绘制几十万个三角形的时候让它的帧数也保持在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


460

被折叠的 条评论
为什么被折叠?



