|
34 | 34 |
|
35 | 35 | // light |
36 | 36 |
|
37 | | - const hemiLight = new THREE.HemisphereLight( 0x888888, 0x000000, 1 ); |
| 37 | + const hemiLight = new THREE.HemisphereLight( 0x888888, 0x444444, 1 ); |
38 | 38 | scene.add( hemiLight ); |
39 | 39 |
|
40 | 40 | const dirLight = new THREE.DirectionalLight( 0xffffff, 0.75 ); |
41 | 41 | dirLight.position.set( 1.5, 3, 2.5 ); |
42 | 42 | scene.add( dirLight ); |
43 | 43 |
|
| 44 | + const dirLight2 = new THREE.DirectionalLight( 0xffffff, 0.5 ); |
| 45 | + dirLight2.position.set( - 1.5, - 3, - 2.5 ); |
| 46 | + scene.add( dirLight2 ); |
| 47 | + |
44 | 48 | const loader = new VOXLoader(); |
45 | 49 | loader.load( 'models/vox/monu10.vox', function ( chunks ) { |
46 | 50 |
|
47 | | - const geometry = new THREE.BoxBufferGeometry( 1, 1, 1 ); |
48 | | - const material = new THREE.MeshStandardMaterial(); |
49 | | - |
50 | | - const color = new THREE.Color(); |
51 | | - const matrix = new THREE.Matrix4(); |
52 | | - |
53 | 51 | for ( let i = 0; i < chunks.length; i ++ ) { |
54 | 52 |
|
55 | 53 | const chunk = chunks[ i ]; |
56 | 54 |
|
57 | | - const size = chunk.size; |
58 | | - const data = chunk.data; |
59 | | - const palette = chunk.palette; |
| 55 | + const geometry = buildGeometry( chunk ); |
| 56 | + const material = new THREE.MeshStandardMaterial( { |
| 57 | + vertexColors: geometry.hasAttribute( 'color' ) |
| 58 | + } ); |
60 | 59 |
|
61 | | - // displayPalette( palette ); |
62 | | - |
63 | | - const mesh = new THREE.InstancedMesh( geometry, material, data.length / 4 ); |
| 60 | + const mesh = new THREE.Mesh( geometry, material ); |
64 | 61 | mesh.scale.setScalar( 0.0015 ); |
65 | 62 | scene.add( mesh ); |
66 | 63 |
|
67 | | - for ( let j = 0, k = 0; j < data.length; j += 4, k ++ ) { |
68 | | - |
69 | | - const x = data[ j + 0 ] - size.x / 2; |
70 | | - const y = data[ j + 1 ] - size.y / 2; |
71 | | - const z = data[ j + 2 ] - size.z / 2; |
72 | | - const c = data[ j + 3 ]; |
73 | | - |
74 | | - const hex = palette[ c ]; |
75 | | - const r = ( hex >> 0 & 0xff ) / 0xff; |
76 | | - const g = ( hex >> 8 & 0xff ) / 0xff; |
77 | | - const b = ( hex >> 16 & 0xff ) / 0xff; |
78 | | - |
79 | | - mesh.setColorAt( k, color.setRGB( r, g, b ) ); |
80 | | - mesh.setMatrixAt( k, matrix.setPosition( x, z, - y ) ); |
81 | | - |
82 | | - } |
83 | | - |
84 | 64 | } |
85 | 65 |
|
86 | 66 | } ); |
|
90 | 70 | renderer = new THREE.WebGLRenderer(); |
91 | 71 | renderer.setPixelRatio( window.devicePixelRatio ); |
92 | 72 | renderer.setSize( window.innerWidth, window.innerHeight ); |
93 | | - |
94 | | - const container = document.createElement( 'div' ); |
95 | | - document.body.appendChild( container ); |
96 | | - container.appendChild( renderer.domElement ); |
| 73 | + document.body.appendChild( renderer.domElement ); |
97 | 74 |
|
98 | 75 | // controls |
99 | 76 |
|
|
107 | 84 |
|
108 | 85 | } |
109 | 86 |
|
| 87 | + function buildGeometry( chunk ) { |
| 88 | + |
| 89 | + const data = chunk.data; |
| 90 | + const size = chunk.size; |
| 91 | + const palette = chunk.palette; |
| 92 | + |
| 93 | + // displayPalette( palette ); |
| 94 | + |
| 95 | + const vertices = []; |
| 96 | + const colors = []; |
| 97 | + |
| 98 | + const nx = [ 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1 ]; |
| 99 | + const px = [ 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0 ]; |
| 100 | + const py = [ 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1 ]; |
| 101 | + const ny = [ 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0 ]; |
| 102 | + const nz = [ 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0 ]; |
| 103 | + const pz = [ 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1 ]; |
| 104 | + |
| 105 | + function add( tile, x, y, z, r, g, b ) { |
| 106 | + |
| 107 | + x -= size.x / 2; |
| 108 | + y -= size.z / 2; |
| 109 | + z += size.y / 2; |
| 110 | + |
| 111 | + for ( let i = 0; i < 18; i += 3 ) { |
| 112 | + |
| 113 | + vertices.push( tile[ i + 0 ] + x, tile[ i + 1 ] + y, tile[ i + 2 ] + z ); |
| 114 | + colors.push( r, g, b ); |
| 115 | + |
| 116 | + } |
| 117 | + |
| 118 | + } |
| 119 | + |
| 120 | + // Store data in a volume for sampling |
| 121 | + |
| 122 | + const offsety = size.x; |
| 123 | + const offsetz = size.x * size.y; |
| 124 | + |
| 125 | + const array = new Uint8Array( size.x * size.y * size.z ); |
| 126 | + |
| 127 | + for ( let j = 0; j < data.length; j += 4 ) { |
| 128 | + |
| 129 | + const x = data[ j + 0 ]; |
| 130 | + const y = data[ j + 1 ]; |
| 131 | + const z = data[ j + 2 ]; |
| 132 | + |
| 133 | + const index = x + ( y * offsety ) + ( z * offsetz ); |
| 134 | + |
| 135 | + array[ index ] = 255; |
| 136 | + |
| 137 | + } |
| 138 | + |
| 139 | + // Construct geometry |
| 140 | + |
| 141 | + let hasColors = false; |
| 142 | + |
| 143 | + for ( let j = 0; j < data.length; j += 4 ) { |
| 144 | + |
| 145 | + const x = data[ j + 0 ]; |
| 146 | + const y = data[ j + 1 ]; |
| 147 | + const z = data[ j + 2 ]; |
| 148 | + const c = data[ j + 3 ]; |
| 149 | + |
| 150 | + const hex = palette[ c ]; |
| 151 | + const r = ( hex >> 0 & 0xff ) / 0xff; |
| 152 | + const g = ( hex >> 8 & 0xff ) / 0xff; |
| 153 | + const b = ( hex >> 16 & 0xff ) / 0xff; |
| 154 | + |
| 155 | + if ( r > 0 || g > 0 || b > 0 ) hasColors = true; |
| 156 | + |
| 157 | + const index = x + ( y * offsety ) + ( z * offsetz ); |
| 158 | + |
| 159 | + if ( array[ index + 1 ] === 0 || x === size.x - 1 ) add( px, x, z, - y, r, g, b ); |
| 160 | + if ( array[ index - 1 ] === 0 || x === 0 ) add( nx, x, z, - y, r, g, b ); |
| 161 | + if ( array[ index + offsety ] === 0 || y === size.y - 1 ) add( ny, x, z, - y, r, g, b ); |
| 162 | + if ( array[ index - offsety ] === 0 || y === 0 ) add( py, x, z, - y, r, g, b ); |
| 163 | + if ( array[ index + offsetz ] === 0 || z === size.z - 1 ) add( pz, x, z, - y, r, g, b ); |
| 164 | + if ( array[ index - offsetz ] === 0 || z === 0 ) add( nz, x, z, - y, r, g, b ); |
| 165 | + |
| 166 | + } |
| 167 | + |
| 168 | + const geometry = new THREE.BufferGeometry(); |
| 169 | + geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); |
| 170 | + geometry.computeVertexNormals(); |
| 171 | + |
| 172 | + if ( hasColors ) geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) ); |
| 173 | + |
| 174 | + return geometry; |
| 175 | + |
| 176 | + } |
| 177 | + |
110 | 178 | /* |
111 | 179 | function displayPalette( palette ) { |
112 | 180 |
|
|
0 commit comments