Bladeren bron

multi color marching cube with example

Hyuntak Cha 6 jaren geleden
bovenliggende
commit
951b658722
2 gewijzigde bestanden met toevoegingen van 250 en 68 verwijderingen
  1. 227 64
      examples/js/MarchingCubes.js
  2. 23 4
      examples/webgl_marchingcubes.html

+ 227 - 64
examples/js/MarchingCubes.js

@@ -1,6 +1,7 @@
 /**
  * @author alteredq / http://alteredqualia.com/
  * @author mrdoob / http://mrdoob.com
+ * @author chaht01 / http://hyuntak.com
  * Port of http://webglsamples.org/blob/blob.html
  */
 
@@ -14,6 +15,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 	var vlist = new Float32Array( 12 * 3 );
 	var nlist = new Float32Array( 12 * 3 );
+	var clist = new Float32Array( 12 * 3 );
 
 	this.enableUvs = enableUvs !== undefined ? enableUvs : false;
 	this.enableColors = enableColors !== undefined ? enableColors : false;
@@ -45,6 +47,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 		this.field = new Float32Array( this.size3 );
 		this.normal_cache = new Float32Array( this.size3 * 3 );
+		this.palette = new Float32Array( this.size3 * 4 );
 
 		// immediate render mode simulator
 
@@ -83,7 +86,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 	}
 
-	function VIntX( q, offset, isol, x, y, z, valp1, valp2 ) {
+	function VIntX( q, offset, isol, x, y, z, valp1, valp2, c_valp1, c_valp2 ) {
 
 		var mu = ( isol - valp1 ) / ( valp2 - valp1 ),
 			nc = scope.normal_cache;
@@ -96,9 +99,13 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 		nlist[ offset + 1 ] = lerp( nc[ q + 1 ], nc[ q + 4 ], mu );
 		nlist[ offset + 2 ] = lerp( nc[ q + 2 ], nc[ q + 5 ], mu );
 
+		clist[ offset + 0 ] = lerp( c_valp1[ 0 ], c_valp2[ 0 ], mu );
+		clist[ offset + 1 ] = lerp( c_valp1[ 1 ], c_valp2[ 1 ], mu );
+		clist[ offset + 2 ] = lerp( c_valp1[ 2 ], c_valp2[ 2 ], mu );
+
 	}
 
-	function VIntY( q, offset, isol, x, y, z, valp1, valp2 ) {
+	function VIntY( q, offset, isol, x, y, z, valp1, valp2, c_valp1, c_valp2 ) {
 
 		var mu = ( isol - valp1 ) / ( valp2 - valp1 ),
 			nc = scope.normal_cache;
@@ -113,9 +120,13 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 		nlist[ offset + 1 ] = lerp( nc[ q + 1 ], nc[ q2 + 1 ], mu );
 		nlist[ offset + 2 ] = lerp( nc[ q + 2 ], nc[ q2 + 2 ], mu );
 
+		clist[ offset + 0 ] = lerp( c_valp1[ 0 ], c_valp2[ 0 ], mu );
+		clist[ offset + 1 ] = lerp( c_valp1[ 1 ], c_valp2[ 1 ], mu );
+		clist[ offset + 2 ] = lerp( c_valp1[ 2 ], c_valp2[ 2 ], mu );
+
 	}
 
-	function VIntZ( q, offset, isol, x, y, z, valp1, valp2 ) {
+	function VIntZ( q, offset, isol, x, y, z, valp1, valp2, c_valp1, c_valp2 ) {
 
 		var mu = ( isol - valp1 ) / ( valp2 - valp1 ),
 			nc = scope.normal_cache;
@@ -130,6 +141,10 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 		nlist[ offset + 1 ] = lerp( nc[ q + 1 ], nc[ q2 + 1 ], mu );
 		nlist[ offset + 2 ] = lerp( nc[ q + 2 ], nc[ q2 + 2 ], mu );
 
+		clist[ offset + 0 ] = lerp( c_valp1[ 0 ], c_valp2[ 0 ], mu );
+		clist[ offset + 1 ] = lerp( c_valp1[ 1 ], c_valp2[ 1 ], mu );
+		clist[ offset + 2 ] = lerp( c_valp1[ 2 ], c_valp2[ 2 ], mu );
+
 	}
 
 	function compNorm( q ) {
@@ -139,8 +154,10 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 		if ( scope.normal_cache[ q3 ] === 0.0 ) {
 
 			scope.normal_cache[ q3 + 0 ] = scope.field[ q - 1 ] - scope.field[ q + 1 ];
-			scope.normal_cache[ q3 + 1 ] = scope.field[ q - scope.yd ] - scope.field[ q + scope.yd ];
-			scope.normal_cache[ q3 + 2 ] = scope.field[ q - scope.zd ] - scope.field[ q + scope.zd ];
+			scope.normal_cache[ q3 + 1 ] =
+				scope.field[ q - scope.yd ] - scope.field[ q + scope.yd ];
+			scope.normal_cache[ q3 + 2 ] =
+				scope.field[ q - scope.zd ] - scope.field[ q + scope.zd ];
 
 		}
 
@@ -170,6 +187,31 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 			field6 = scope.field[ qyz ],
 			field7 = scope.field[ q1yz ];
 
+		var c_field0 = scope.palette
+				.slice( q * 4, q * 4 + 3 )
+				.map( v => v / scope.palette[ q * 4 + 3 ] ), // slicing (r, g, b) part
+			c_field1 = scope.palette
+				.slice( q1 * 4, q1 * 4 + 3 )
+				.map( v => v / scope.palette[ q1 * 4 + 3 ] ),
+			c_field2 = scope.palette
+				.slice( qy * 4, qy * 4 + 3 )
+				.map( v => v / scope.palette[ qy * 4 + 3 ] ),
+			c_field3 = scope.palette
+				.slice( q1y * 4, q1y * 4 + 3 )
+				.map( v => v / scope.palette[ q1y * 4 + 3 ] ),
+			c_field4 = scope.palette
+				.slice( qz * 4, qz * 4 + 3 )
+				.map( v => v / scope.palette[ qz * 4 + 3 ] ),
+			c_field5 = scope.palette
+				.slice( q1z * 4, q1z * 4 + 3 )
+				.map( v => v / scope.palette[ q1z * 4 + 3 ] ),
+			c_field6 = scope.palette
+				.slice( qyz * 4, qyz * 4 + 3 )
+				.map( v => v / scope.palette[ qyz * 4 + 3 ] ),
+			c_field7 = scope.palette
+				.slice( q1yz * 4, q1yz * 4 + 3 )
+				.map( v => v / scope.palette[ q1yz * 4 + 3 ] );
+
 		if ( field0 < isol ) cubeindex |= 1;
 		if ( field1 < isol ) cubeindex |= 2;
 		if ( field2 < isol ) cubeindex |= 8;
@@ -195,7 +237,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( q );
 			compNorm( q1 );
-			VIntX( q * 3, 0, isol, fx, fy, fz, field0, field1 );
+			VIntX( q * 3, 0, isol, fx, fy, fz, field0, field1, c_field0, c_field1 );
 
 		}
 
@@ -203,7 +245,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( q1 );
 			compNorm( q1y );
-			VIntY( q1 * 3, 3, isol, fx2, fy, fz, field1, field3 );
+			VIntY( q1 * 3, 3, isol, fx2, fy, fz, field1, field3, c_field1, c_field3 );
 
 		}
 
@@ -211,7 +253,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( qy );
 			compNorm( q1y );
-			VIntX( qy * 3, 6, isol, fx, fy2, fz, field2, field3 );
+			VIntX( qy * 3, 6, isol, fx, fy2, fz, field2, field3, c_field2, c_field3 );
 
 		}
 
@@ -219,7 +261,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( q );
 			compNorm( qy );
-			VIntY( q * 3, 9, isol, fx, fy, fz, field0, field2 );
+			VIntY( q * 3, 9, isol, fx, fy, fz, field0, field2, c_field0, c_field2 );
 
 		}
 
@@ -229,7 +271,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( qz );
 			compNorm( q1z );
-			VIntX( qz * 3, 12, isol, fx, fy, fz2, field4, field5 );
+			VIntX( qz * 3, 12, isol, fx, fy, fz2, field4, field5, c_field4, c_field5 );
 
 		}
 
@@ -237,7 +279,18 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( q1z );
 			compNorm( q1yz );
-			VIntY( q1z * 3, 15, isol, fx2, fy, fz2, field5, field7 );
+			VIntY(
+				q1z * 3,
+				15,
+				isol,
+				fx2,
+				fy,
+				fz2,
+				field5,
+				field7,
+				c_field5,
+				c_field7
+			);
 
 		}
 
@@ -245,7 +298,18 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( qyz );
 			compNorm( q1yz );
-			VIntX( qyz * 3, 18, isol, fx, fy2, fz2, field6, field7 );
+			VIntX(
+				qyz * 3,
+				18,
+				isol,
+				fx,
+				fy2,
+				fz2,
+				field6,
+				field7,
+				c_field6,
+				c_field7
+			);
 
 		}
 
@@ -253,17 +317,16 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( qz );
 			compNorm( qyz );
-			VIntY( qz * 3, 21, isol, fx, fy, fz2, field4, field6 );
+			VIntY( qz * 3, 21, isol, fx, fy, fz2, field4, field6, c_field4, c_field6 );
 
 		}
 
 		// vertical lines of the cube
-
 		if ( bits & 256 ) {
 
 			compNorm( q );
 			compNorm( qz );
-			VIntZ( q * 3, 24, isol, fx, fy, fz, field0, field4 );
+			VIntZ( q * 3, 24, isol, fx, fy, fz, field0, field4, c_field0, c_field4 );
 
 		}
 
@@ -271,7 +334,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( q1 );
 			compNorm( q1z );
-			VIntZ( q1 * 3, 27, isol, fx2, fy, fz, field1, field5 );
+			VIntZ( q1 * 3, 27, isol, fx2, fy, fz, field1, field5, c_field1, c_field5 );
 
 		}
 
@@ -279,7 +342,18 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( q1y );
 			compNorm( q1yz );
-			VIntZ( q1y * 3, 30, isol, fx2, fy2, fz, field3, field7 );
+			VIntZ(
+				q1y * 3,
+				30,
+				isol,
+				fx2,
+				fy2,
+				fz,
+				field3,
+				field7,
+				c_field3,
+				c_field7
+			);
 
 		}
 
@@ -287,13 +361,17 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			compNorm( qy );
 			compNorm( qyz );
-			VIntZ( qy * 3, 33, isol, fx, fy2, fz, field2, field6 );
+			VIntZ( qy * 3, 33, isol, fx, fy2, fz, field2, field6, c_field2, c_field6 );
 
 		}
 
 		cubeindex <<= 4; // re-purpose cubeindex into an offset into triTable
 
-		var o1, o2, o3, numtris = 0, i = 0;
+		var o1,
+			o2,
+			o3,
+			numtris = 0,
+			i = 0;
 
 		// here is where triangles are created
 
@@ -303,11 +381,15 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 			o2 = o1 + 1;
 			o3 = o1 + 2;
 
-			posnormtriv( vlist, nlist,
+			posnormtriv(
+				vlist,
+				nlist,
+				clist,
 				3 * THREE.triTable[ o1 ],
 				3 * THREE.triTable[ o2 ],
 				3 * THREE.triTable[ o3 ],
-				renderCallback );
+				renderCallback
+			);
 
 			i += 3;
 			numtris ++;
@@ -322,7 +404,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 	// Immediate render mode simulator
 	/////////////////////////////////////
 
-	function posnormtriv( pos, norm, o1, o2, o3, renderCallback ) {
+	function posnormtriv( pos, norm, colors, o1, o2, o3, renderCallback ) {
 
 		var c = scope.count * 3;
 
@@ -360,7 +442,6 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 			scope.normalArray[ c + 7 ] = ny;
 			scope.normalArray[ c + 8 ] = nz;
 
-
 		} else {
 
 			scope.normalArray[ c + 0 ] = norm[ o1 + 0 ];
@@ -398,17 +479,17 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 		if ( scope.enableColors ) {
 
-			scope.colorArray[ c + 0 ] = pos[ o1 + 0 ];
-			scope.colorArray[ c + 1 ] = pos[ o1 + 1 ];
-			scope.colorArray[ c + 2 ] = pos[ o1 + 2 ];
+			scope.colorArray[ c + 0 ] = colors[ o1 + 0 ];
+			scope.colorArray[ c + 1 ] = colors[ o1 + 1 ];
+			scope.colorArray[ c + 2 ] = colors[ o1 + 2 ];
 
-			scope.colorArray[ c + 3 ] = pos[ o2 + 0 ];
-			scope.colorArray[ c + 4 ] = pos[ o2 + 1 ];
-			scope.colorArray[ c + 5 ] = pos[ o2 + 2 ];
+			scope.colorArray[ c + 3 ] = colors[ o2 + 0 ];
+			scope.colorArray[ c + 4 ] = colors[ o2 + 1 ];
+			scope.colorArray[ c + 5 ] = colors[ o2 + 2 ];
 
-			scope.colorArray[ c + 6 ] = pos[ o3 + 0 ];
-			scope.colorArray[ c + 7 ] = pos[ o3 + 1 ];
-			scope.colorArray[ c + 8 ] = pos[ o3 + 2 ];
+			scope.colorArray[ c + 6 ] = colors[ o3 + 0 ];
+			scope.colorArray[ c + 7 ] = colors[ o3 + 1 ];
+			scope.colorArray[ c + 8 ] = colors[ o3 + 2 ];
 
 		}
 
@@ -484,10 +565,36 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 	// Adds a reciprocal ball (nice and blobby) that, to be fast, fades to zero after
 	// a fixed distance, determined by strength and subtract.
 
-	this.addBall = function ( ballx, bally, ballz, strength, subtract ) {
+	this.addBall = function ( ballx, bally, ballz, strength, subtract, colors ) {
 
 		var sign = Math.sign( strength );
 		strength = Math.abs( strength );
+		var userDefineColor = ! ( colors === undefined || colors === null );
+		console.log( ballx, bally, ballz );
+		var ballColor = new THREE.Color( ballx, bally, ballz );
+		if ( userDefineColor ) {
+
+			try {
+
+				ballColor =
+					colors instanceof THREE.Color
+						? colors
+						: Array.isArray( colors )
+							? new THREE.Color(
+								Math.min( Math.abs( colors[ 0 ] ), 1 ),
+								Math.min( Math.abs( colors[ 1 ] ), 1 ),
+								Math.min( Math.abs( colors[ 2 ] ), 1 )
+						  )
+							: new THREE.Color( colors );
+
+			} catch ( err ) {
+
+				userDefineColor = false;
+				ballColor = new THREE.Color( ballx, bally, ballz );
+
+			}
+
+		}
 
 		// Let's solve the equation to find the radius:
 		// 1.0 / (0.000001 + radius^2) * strength - subtract = 0
@@ -501,19 +608,23 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 			ys = bally * this.size,
 			xs = ballx * this.size;
 
-		var min_z = Math.floor( zs - radius ); if ( min_z < 1 ) min_z = 1;
-		var max_z = Math.floor( zs + radius ); if ( max_z > this.size - 1 ) max_z = this.size - 1;
-		var min_y = Math.floor( ys - radius ); if ( min_y < 1 ) min_y = 1;
-		var max_y = Math.floor( ys + radius ); if ( max_y > this.size - 1 ) max_y = this.size - 1;
-		var min_x = Math.floor( xs - radius ); if ( min_x < 1 ) min_x = 1;
-		var max_x = Math.floor( xs + radius ); if ( max_x > this.size - 1 ) max_x = this.size - 1;
-
+		var min_z = Math.floor( zs - radius );
+		if ( min_z < 1 ) min_z = 1;
+		var max_z = Math.floor( zs + radius );
+		if ( max_z > this.size - 1 ) max_z = this.size - 1;
+		var min_y = Math.floor( ys - radius );
+		if ( min_y < 1 ) min_y = 1;
+		var max_y = Math.floor( ys + radius );
+		if ( max_y > this.size - 1 ) max_y = this.size - 1;
+		var min_x = Math.floor( xs - radius );
+		if ( min_x < 1 ) min_x = 1;
+		var max_x = Math.floor( xs + radius );
+		if ( max_x > this.size - 1 ) max_x = this.size - 1;
 
 		// Don't polygonize in the outer layer because normals aren't
 		// well-defined there.
 
 		var x, y, z, y_offset, z_offset, fx, fy, fz, fz2, fy2, val;
-
 		for ( z = min_z; z < max_z; z ++ ) {
 
 			z_offset = this.size2 * z;
@@ -530,7 +641,22 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 					fx = x / this.size - ballx;
 					val = strength / ( 0.000001 + fx * fx + fy2 + fz2 ) - subtract;
-					if ( val > 0.0 ) this.field[ y_offset + x ] += val * sign;
+					if ( val > 0.0 ) {
+
+						this.field[ y_offset + x ] += val * sign;
+
+						// optimization
+						// http://www.geisswerks.com/ryan/BLOBS/blobs.html
+						const ratio =
+							Math.sqrt( ( x - xs ) * ( x - xs ) + ( y - ys ) * ( y - ys ) + ( z - zs ) * ( z - zs ) ) / radius;
+						const contrib =
+							1 - ratio * ratio * ratio * ( ratio * ( ratio * 6 - 15 ) + 10 );
+						this.palette[ ( y_offset + x ) * 4 + 0 ] += ballColor.r * contrib;
+						this.palette[ ( y_offset + x ) * 4 + 1 ] += ballColor.g * contrib;
+						this.palette[ ( y_offset + x ) * 4 + 2 ] += ballColor.b * contrib;
+						this.palette[ ( y_offset + x ) * 4 + 3 ] += contrib;
+
+					}
 
 				}
 
@@ -542,14 +668,18 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 	this.addPlaneX = function ( strength, subtract ) {
 
-		var x, y, z, xx, val, xdiv, cxy,
-
+		var x,
+			y,
+			z,
+			xx,
+			val,
+			xdiv,
+			cxy,
 			// cache attribute lookups
 			size = this.size,
 			yd = this.yd,
 			zd = this.zd,
 			field = this.field,
-
 			dist = size * Math.sqrt( strength / subtract );
 
 		if ( dist > size ) dist = size;
@@ -582,14 +712,19 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 	this.addPlaneY = function ( strength, subtract ) {
 
-		var x, y, z, yy, val, ydiv, cy, cxy,
-
+		var x,
+			y,
+			z,
+			yy,
+			val,
+			ydiv,
+			cy,
+			cxy,
 			// cache attribute lookups
 			size = this.size,
 			yd = this.yd,
 			zd = this.zd,
 			field = this.field,
-
 			dist = size * Math.sqrt( strength / subtract );
 
 		if ( dist > size ) dist = size;
@@ -608,8 +743,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 					cxy = cy + x;
 
-					for ( z = 0; z < size; z ++ )
-						field[ zd * z + cxy ] += val;
+					for ( z = 0; z < size; z ++ ) field[ zd * z + cxy ] += val;
 
 				}
 
@@ -621,14 +755,19 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 	this.addPlaneZ = function ( strength, subtract ) {
 
-		var x, y, z, zz, val, zdiv, cz, cyz,
-
+		var x,
+			y,
+			z,
+			zz,
+			val,
+			zdiv,
+			cz,
+			cyz,
 			// cache attribute lookups
 			size = this.size,
 			yd = this.yd,
 			zd = this.zd,
 			field = this.field,
-
 			dist = size * Math.sqrt( strength / subtract );
 
 		if ( dist > size ) dist = size;
@@ -646,8 +785,7 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 					cyz = cz + y * yd;
 
-					for ( x = 0; x < size; x ++ )
-						field[ cyz + x ] += val;
+					for ( x = 0; x < size; x ++ ) field[ cyz + x ] += val;
 
 				}
 
@@ -671,6 +809,9 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 			this.normal_cache[ i * 3 ] = 0.0;
 			this.field[ i ] = 0.0;
+			this.palette[ i * 4 ] = this.palette[ i * 4 + 1 ] = this.palette[
+				i * 4 + 2
+			] = this.palette[ i * 4 + 3 ] = 0.0;
 
 		}
 
@@ -713,7 +854,9 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 	this.generateGeometry = function () {
 
-		console.warn( 'THREE.MarchingCubes: generateGeometry() now returns THREE.BufferGeometry' );
+		console.warn(
+			"THREE.MarchingCubes: generateGeometry() now returns THREE.BufferGeometry"
+		);
 		return this.generateBufferGeometry();
 
 	};
@@ -738,10 +881,26 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 		var geo_callback = function ( object ) {
 
-			if ( scope.hasPositions ) posArray = concatenate( posArray, object.positionArray, object.count * 3 );
-			if ( scope.hasNormals ) normArray = concatenate( normArray, object.normalArray, object.count * 3 );
-			if ( scope.hasColors ) colorArray = concatenate( colorArray, object.colorArray, object.count * 3 );
-			if ( scope.hasUvs ) uvArray = concatenate( uvArray, object.uvArray, object.count * 2 );
+			if ( scope.hasPositions )
+				posArray = concatenate(
+					posArray,
+					object.positionArray,
+					object.count * 3
+				);
+			if ( scope.hasNormals )
+				normArray = concatenate(
+					normArray,
+					object.normalArray,
+					object.count * 3
+				);
+			if ( scope.hasColors )
+				colorArray = concatenate(
+					colorArray,
+					object.colorArray,
+					object.count * 3
+				);
+			if ( scope.hasUvs )
+				uvArray = concatenate( uvArray, object.uvArray, object.count * 2 );
 
 			object.count = 0;
 
@@ -749,10 +908,14 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 
 		this.render( geo_callback );
 
-		if ( this.hasPositions ) geo.addAttribute( 'position', new THREE.BufferAttribute( posArray, 3 ) );
-		if ( this.hasNormals ) geo.addAttribute( 'normal', new THREE.BufferAttribute( normArray, 3 ) );
-		if ( this.hasColors ) geo.addAttribute( 'color', new THREE.BufferAttribute( colorArray, 3 ) );
-		if ( this.hasUvs ) geo.addAttribute( 'uv', new THREE.BufferAttribute( uvArray, 2 ) );
+		if ( this.hasPositions )
+			geo.addAttribute( "position", new THREE.BufferAttribute( posArray, 3 ) );
+		if ( this.hasNormals )
+			geo.addAttribute( "normal", new THREE.BufferAttribute( normArray, 3 ) );
+		if ( this.hasColors )
+			geo.addAttribute( "color", new THREE.BufferAttribute( colorArray, 3 ) );
+		if ( this.hasUvs )
+			geo.addAttribute( "uv", new THREE.BufferAttribute( uvArray, 2 ) );
 
 		return geo;
 

+ 23 - 4
examples/webgl_marchingcubes.html

@@ -331,7 +331,11 @@
 				m: new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0xffffff, shininess: 2, vertexColors: THREE.VertexColors } ),
 				h: 0, s: 0, l: 1
 			},
-
+				"multiColors":
+			{
+				m: new THREE.MeshPhongMaterial( { shininess: 2, vertexColors: THREE.VertexColors } ),
+				h: 0, s: 0, l: 1
+			},
 				"plastic":
 			{
 				m: new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x888888, shininess: 250 } ),
@@ -423,7 +427,7 @@
 					m_l.setValue( mat.l );
 
 					effect.enableUvs = ( current_material === "textured" ) ? true : false;
-					effect.enableColors = ( current_material === "colors" ) ? true : false;
+					effect.enableColors = ( current_material === "colors" || current_material === "multiColors" ) ? true : false;
 
 				};
 
@@ -528,7 +532,15 @@
 			// fill the field with some metaballs
 
 			var i, ballx, bally, ballz, subtract, strength;
-
+			var rainbow = [
+					new THREE.Color(0xff0000),
+					new THREE.Color(0xff7f00),
+					new THREE.Color(0xffff00),
+					new THREE.Color(0x00ff00),
+					new THREE.Color(0x0000ff),
+					new THREE.Color(0x4b0082),
+					new THREE.Color(0x9400d3)
+				];
 			subtract = 12;
 			strength = 1.2 / ( ( Math.sqrt( numblobs ) - 1 ) / 4 + 1 );
 
@@ -537,9 +549,16 @@
 				ballx = Math.sin( i + 1.26 * time * ( 1.03 + 0.5 * Math.cos( 0.21 * i ) ) ) * 0.27 + 0.5;
 				bally = Math.abs( Math.cos( i + 1.12 * time * Math.cos( 1.22 + 0.1424 * i ) ) ) * 0.77; // dip into the floor
 				ballz = Math.cos( i + 1.32 * time * 0.1 * Math.sin( ( 0.92 + 0.53 * i ) ) ) * 0.27 + 0.5;
+				
+				if (current_material === "multiColors") {
 
-				object.addBall( ballx, bally, ballz, strength, subtract );
+					object.addBall( ballx, bally, ballz, strength, subtract, rainbow[i % 7] );
+					
+							} else {
 
+					object.addBall( ballx, bally, ballz, strength, subtract );
+					
+							}
 			}
 
 			if ( floor ) object.addPlaneY( 2, 12 );