|
@@ -6,12 +6,12 @@
|
|
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
|
|
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
|
|
<style>
|
|
<style>
|
|
body {
|
|
body {
|
|
- color: #808080;
|
|
|
|
|
|
+ color: #cccccc;
|
|
font-family:Monospace;
|
|
font-family:Monospace;
|
|
font-size:13px;
|
|
font-size:13px;
|
|
text-align:center;
|
|
text-align:center;
|
|
|
|
|
|
- background-color: #fff;
|
|
|
|
|
|
+ background-color: #050505;
|
|
margin: 0px;
|
|
margin: 0px;
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
}
|
|
}
|
|
@@ -56,12 +56,29 @@
|
|
|
|
|
|
container = document.getElementById( 'container' );
|
|
container = document.getElementById( 'container' );
|
|
|
|
|
|
- camera = new THREE.PerspectiveCamera( 20, window.innerWidth / window.innerHeight, 1, 10000 );
|
|
|
|
- camera.position.z = 1800;
|
|
|
|
|
|
+ //
|
|
|
|
+
|
|
|
|
+ camera = new THREE.PerspectiveCamera( 27, window.innerWidth / window.innerHeight, 1, 3500 );
|
|
|
|
+ camera.position.z = 2750;
|
|
|
|
|
|
scene = new THREE.Scene();
|
|
scene = new THREE.Scene();
|
|
|
|
+ scene.fog = new THREE.Fog( 0x050505, 2000, 3500 );
|
|
|
|
+
|
|
|
|
+ //
|
|
|
|
|
|
- var triangles = 10000;
|
|
|
|
|
|
+ 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 = 250000;
|
|
|
|
|
|
var geometry = new THREE.BufferGeometry();
|
|
var geometry = new THREE.BufferGeometry();
|
|
geometry.attributes = {
|
|
geometry.attributes = {
|
|
@@ -74,58 +91,177 @@
|
|
itemSize: 3,
|
|
itemSize: 3,
|
|
array: new Float32Array( triangles * 3 * 3 ),
|
|
array: new Float32Array( triangles * 3 * 3 ),
|
|
numItems: triangles * 3 * 3
|
|
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
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // break geometry into
|
|
|
|
+ // chunks of 20,000 triangles (3 unique vertices per triangle)
|
|
|
|
+ // for indices to fit into 16 bit integer number
|
|
|
|
+
|
|
|
|
+ var chunkSize = 20000;
|
|
|
|
+
|
|
var indices = geometry.attributes.index.array;
|
|
var indices = geometry.attributes.index.array;
|
|
|
|
|
|
for ( var i = 0; i < indices.length; i ++ ) {
|
|
for ( var i = 0; i < indices.length; i ++ ) {
|
|
|
|
|
|
- indices[ i ] = i;
|
|
|
|
|
|
+ indices[ i ] = i % ( 3 * chunkSize );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
var positions = geometry.attributes.position.array;
|
|
var positions = geometry.attributes.position.array;
|
|
|
|
+ var normals = geometry.attributes.normal.array;
|
|
|
|
+ var colors = geometry.attributes.color.array;
|
|
|
|
+
|
|
|
|
+ var color = new THREE.Color();
|
|
|
|
+
|
|
|
|
+ var n = 800, n2 = n/2; // triangles spread in the cube
|
|
|
|
+ var d = 12, d2 = d/2; // individual triangle size
|
|
|
|
+
|
|
|
|
+ var pA = new THREE.Vector3();
|
|
|
|
+ var pB = new THREE.Vector3();
|
|
|
|
+ var pC = new THREE.Vector3();
|
|
|
|
+
|
|
|
|
+ var cb = new THREE.Vector3();
|
|
|
|
+ var ab = new THREE.Vector3();
|
|
|
|
|
|
for ( var i = 0; i < positions.length; i += 9 ) {
|
|
for ( var i = 0; i < positions.length; i += 9 ) {
|
|
|
|
|
|
- var x = Math.random() * 400 - 200;
|
|
|
|
- var y = Math.random() * 400 - 200;
|
|
|
|
- var z = Math.random() * 400 - 200;
|
|
|
|
|
|
+ // positions
|
|
|
|
+
|
|
|
|
+ var x = Math.random() * n - n2;
|
|
|
|
+ var y = Math.random() * n - n2;
|
|
|
|
+ var z = Math.random() * n - n2;
|
|
|
|
+
|
|
|
|
+ var ax = x + Math.random() * d - d2;
|
|
|
|
+ var ay = y + Math.random() * d - d2;
|
|
|
|
+ var az = z + Math.random() * d - d2;
|
|
|
|
+
|
|
|
|
+ var bx = x + Math.random() * d - d2;
|
|
|
|
+ var by = y + Math.random() * d - d2;
|
|
|
|
+ var bz = z + Math.random() * d - d2;
|
|
|
|
+
|
|
|
|
+ var cx = x + Math.random() * d - d2;
|
|
|
|
+ var cy = y + Math.random() * d - d2;
|
|
|
|
+ var cz = z + Math.random() * d - d2;
|
|
|
|
+
|
|
|
|
+ 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 ] = x + Math.random() * 40 - 20;
|
|
|
|
- positions[ i + 1 ] = y + Math.random() * 40 - 20;
|
|
|
|
- positions[ i + 2 ] = z + Math.random() * 40 - 20;
|
|
|
|
|
|
+ positions[ i + 6 ] = cx;
|
|
|
|
+ positions[ i + 7 ] = cy;
|
|
|
|
+ positions[ i + 8 ] = cz;
|
|
|
|
|
|
- positions[ i + 3 ] = x + Math.random() * 40 - 20;
|
|
|
|
- positions[ i + 4 ] = y + Math.random() * 40 - 20;
|
|
|
|
- positions[ i + 5 ] = z + Math.random() * 40 - 20;
|
|
|
|
|
|
+ // flat face normals
|
|
|
|
|
|
- positions[ i + 6 ] = x + Math.random() * 40 - 20;
|
|
|
|
- positions[ i + 7 ] = y + Math.random() * 40 - 20;
|
|
|
|
- positions[ i + 8 ] = z + Math.random() * 40 - 20;
|
|
|
|
|
|
+ pA.set( ax, ay, az );
|
|
|
|
+ pB.set( bx, by, bz );
|
|
|
|
+ pC.set( cx, cy, cz );
|
|
|
|
+
|
|
|
|
+ cb.sub( pC, pB );
|
|
|
|
+ ab.sub( pA, pB );
|
|
|
|
+ cb.crossSelf( ab );
|
|
|
|
+
|
|
|
|
+ cb.normalize();
|
|
|
|
+
|
|
|
|
+ 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;
|
|
|
|
+
|
|
|
|
+ // colors
|
|
|
|
+
|
|
|
|
+ var vx = ( x / n ) + 0.5;
|
|
|
|
+ var vy = ( y / n ) + 0.5;
|
|
|
|
+ var vz = ( z / n ) + 0.5;
|
|
|
|
+
|
|
|
|
+ //color.setHSV( 0.5 + 0.5 * vx, 0.25 + 0.75 * vy, 0.25 + 0.75 * vz );
|
|
|
|
+ color.setRGB( vx, vy, vz );
|
|
|
|
+
|
|
|
|
+ colors[ i ] = color.r;
|
|
|
|
+ colors[ i + 1 ] = color.g;
|
|
|
|
+ colors[ i + 2 ] = color.b;
|
|
|
|
+
|
|
|
|
+ colors[ i + 3 ] = color.r;
|
|
|
|
+ colors[ i + 4 ] = color.g;
|
|
|
|
+ colors[ i + 5 ] = color.b;
|
|
|
|
+
|
|
|
|
+ colors[ i + 6 ] = color.r;
|
|
|
|
+ colors[ i + 7 ] = color.g;
|
|
|
|
+ colors[ i + 8 ] = color.b;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- geometry.offsets = [{
|
|
|
|
- start: 0,
|
|
|
|
- count: triangles * 3,
|
|
|
|
- index: 0
|
|
|
|
- }]
|
|
|
|
|
|
+ geometry.offsets = [];
|
|
|
|
+
|
|
|
|
+ var start = 0;
|
|
|
|
+ var index = 0;
|
|
|
|
+ var left = triangles * 3;
|
|
|
|
+
|
|
|
|
+ for ( ;; ) {
|
|
|
|
+
|
|
|
|
+ var count = Math.min( chunkSize * 3, left );
|
|
|
|
+
|
|
|
|
+ var chunk = { start: start, count: count, index: index };
|
|
|
|
+
|
|
|
|
+ geometry.offsets.push( chunk );
|
|
|
|
+
|
|
|
|
+ start += count;
|
|
|
|
+ index += chunkSize * 3;
|
|
|
|
+
|
|
|
|
+ left -= count;
|
|
|
|
+
|
|
|
|
+ if ( left <= 0 ) break;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
geometry.computeBoundingSphere();
|
|
geometry.computeBoundingSphere();
|
|
- geometry.computeVertexNormals();
|
|
|
|
|
|
|
|
- var material = new THREE.MeshNormalMaterial( { side: THREE.DoubleSide } );
|
|
|
|
|
|
+ var material = new THREE.MeshPhongMaterial( { color: 0xaaaaaa, ambient: 0xaaaaaa, specular: 0xffffff, shininess: 250,
|
|
|
|
+ side: THREE.DoubleSide, perPixel: true, vertexColors: THREE.VertexColors } );
|
|
|
|
|
|
mesh = new THREE.Mesh( geometry, material );
|
|
mesh = new THREE.Mesh( geometry, material );
|
|
scene.add( mesh );
|
|
scene.add( mesh );
|
|
|
|
|
|
- renderer = new THREE.WebGLRenderer( { antialias: false } );
|
|
|
|
|
|
+ //
|
|
|
|
+
|
|
|
|
+ renderer = new THREE.WebGLRenderer( { antialias: false, clearColor: 0x333333, clearAlpha: 1, alpha: false } );
|
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
|
|
|
+ renderer.setClearColor( scene.fog.color, 1 );
|
|
|
|
+
|
|
|
|
+ renderer.gammaInput = true;
|
|
|
|
+ renderer.gammaOutput = true;
|
|
|
|
+ renderer.physicallyBasedShading = true;
|
|
|
|
|
|
container.appendChild( renderer.domElement );
|
|
container.appendChild( renderer.domElement );
|
|
|
|
|
|
|
|
+ //
|
|
|
|
+
|
|
stats = new Stats();
|
|
stats = new Stats();
|
|
stats.domElement.style.position = 'absolute';
|
|
stats.domElement.style.position = 'absolute';
|
|
stats.domElement.style.top = '0px';
|
|
stats.domElement.style.top = '0px';
|
|
@@ -162,8 +298,10 @@
|
|
|
|
|
|
function render() {
|
|
function render() {
|
|
|
|
|
|
- mesh.rotation.x += 0.01;
|
|
|
|
- mesh.rotation.y += 0.02;
|
|
|
|
|
|
+ var time = Date.now() * 0.001;
|
|
|
|
+
|
|
|
|
+ mesh.rotation.x = time * 0.25;
|
|
|
|
+ mesh.rotation.y = time * 0.5;
|
|
|
|
|
|
renderer.render( scene, camera );
|
|
renderer.render( scene, camera );
|
|
|
|
|