Divide any geometry into more triangles

Is there an built-in way to do this? For example, say I have a BoxGeometry and instead of each face having two triangles, I want it to have 8 triangles instead. I tried using Subdivision Modifier but it wont handle a box geometry properly.

How did you try? How did it fail? A JSFiddle that demonstrates the problem would be nice.

The included one is a catmull clark implementation i guess, it will smooth/round the surface. What do you want to archive with the subdivision? Which requirements for the topology?

Also notice you can define the number of segments for the box geometry
https://threejs.org/docs/#api/en/geometries/BoxBufferGeometry

Hi.

I don’t know if this function can help.

I had the same problem and in order to divide a big triangle in small ones I aided this function:

function splitTriangle(trianglePositionArray, trianglesize) {
		let triangles = [];
		const size = 1 / trianglesize;
		const triangleVectorSideArray = [
			trianglePositionArray[3] - trianglePositionArray[0],
			trianglePositionArray[4] - trianglePositionArray[1],
			trianglePositionArray[5] - trianglePositionArray[2],
			
			trianglePositionArray[6] - trianglePositionArray[0],
			trianglePositionArray[7] - trianglePositionArray[1],
			trianglePositionArray[8] - trianglePositionArray[2],
			
			trianglePositionArray[3] - trianglePositionArray[6],
			trianglePositionArray[4] - trianglePositionArray[7],
			trianglePositionArray[5] - trianglePositionArray[8]
		];
		
		// order triangle sides by length ascendant
		const triangleSideLengthArray = [
			[ Math.sqrt( 
				(triangleVectorSideArray[0]*triangleVectorSideArray[0]) + 
				(triangleVectorSideArray[1]*triangleVectorSideArray[1]) +
				(triangleVectorSideArray[2]*triangleVectorSideArray[2])
			), "v0v1" , 0, [0,1,2] ],
			[ Math.sqrt( 
				(triangleVectorSideArray[3]*triangleVectorSideArray[3]) + 
				(triangleVectorSideArray[4]*triangleVectorSideArray[4]) +
				(triangleVectorSideArray[5]*triangleVectorSideArray[5])
			), "v0v2", 1, [0,2,1] ],
			[ Math.sqrt( 
				(triangleVectorSideArray[6]*triangleVectorSideArray[6]) + 
				(triangleVectorSideArray[7]*triangleVectorSideArray[7]) +
				(triangleVectorSideArray[8]*triangleVectorSideArray[8])
			), "v1v2", 2, [1,2,0] ]
		].sort(function(a, b) {
			return a[0] - b[0];
		});
		
		
		// We compute the base side divs: (longuest side)
		const triangleLongSideDivs = Math.round(0.5 + triangleSideLengthArray[2][0] / trianglesize);
		
		
		// if longuest side is less than trianglesize then return triangle
		if(triangleLongSideDivs === 1) {
			return [trianglePositionArray];
		}
		
		// We compute number of divs for non base triangle sides and take the sortest one (this will be invariable)
		const triangleShortSideDivs = Math.round(0.5 + triangleSideLengthArray[1][0] / trianglesize);
		
		const startBaseIndex = triangleSideLengthArray[2][3][0];
		const endBaseIndex = triangleSideLengthArray[2][3][1];
		let topIndex = triangleSideLengthArray[2][3][2];
		
		const deltaShort1 = [ // for start base
			(trianglePositionArray[topIndex*3] - trianglePositionArray[startBaseIndex*3]) / triangleShortSideDivs,
			(trianglePositionArray[topIndex*3+1] - trianglePositionArray[startBaseIndex*3+1]) / triangleShortSideDivs,
			(trianglePositionArray[topIndex*3+2] - trianglePositionArray[startBaseIndex*3+2]) / triangleShortSideDivs
		];
		
		const deltaShort2 = [ // for start base
			(trianglePositionArray[topIndex*3] - trianglePositionArray[endBaseIndex*3]) / triangleShortSideDivs,
			(trianglePositionArray[topIndex*3+1] - trianglePositionArray[endBaseIndex*3+1]) / triangleShortSideDivs,
			(trianglePositionArray[topIndex*3+2] - trianglePositionArray[endBaseIndex*3+2]) / triangleShortSideDivs
		];
		
		// We take the array of positions
		let positions = [];
		let baseLengths = [];
		const startIndex = triangleSideLengthArray[2][3][0]; //(biggest side index0)
		const endIndex = triangleSideLengthArray[2][3][1]; //(biggest side index1)
		for (let i=0; i<triangleShortSideDivs; i++) {
			// get horizonal start  and end index
			let startVertex = [ 
				trianglePositionArray[startIndex*3] + i * deltaShort1[0],
				trianglePositionArray[startIndex*3+1] + i * deltaShort1[1],
				trianglePositionArray[startIndex*3+2] + i * deltaShort1[2]
			];
			let endVertex = [ 
				trianglePositionArray[endIndex*3] + i * deltaShort2[0],
				trianglePositionArray[endIndex*3+1] + i * deltaShort2[1],
				trianglePositionArray[endIndex*3+2] + i * deltaShort2[2]
			];
			let baseVector = [
				endVertex[0] - startVertex[0],
				endVertex[1] - startVertex[1],
				endVertex[2] - startVertex[2]
			];
			let baseSize = Math.sqrt(baseVector[0]*baseVector[0] + baseVector[1]*baseVector[1] + baseVector[2]*baseVector[2]);
			let baseDivs = Math.round(0.5 + baseSize / trianglesize) + 1;
			let deltaBase = [ baseVector[0]/baseDivs, baseVector[1]/baseDivs, baseVector[2]/baseDivs ];
			
			baseLengths[i] = [startVertex, endVertex, baseVector, deltaBase, baseSize, baseDivs];
			
			positions[i] = [];
			for (let j=0; j<baseDivs; j++) {
				positions[i].push(
					startVertex[0] + j * deltaBase[0],
					startVertex[1] + j * deltaBase[1],
					startVertex[2] + j * deltaBase[2]
				);
			}
			positions[i].push( endVertex[0], endVertex[1], endVertex[2]);
		}
		// add top vertex
		topIndex = triangleSideLengthArray[2][3][2];
		positions[triangleShortSideDivs] = [
			trianglePositionArray[topIndex*3], trianglePositionArray[topIndex*3+1],trianglePositionArray[topIndex*3+2] 
		];
		// We take triangles:
		
		for (let i=0; i<triangleShortSideDivs; i++) {
			let baseDivs = positions[i].length / 3 - 1; //(max lower index)
			let upperDivs = positions[i+1].length / 3 - 1; //(max upper index)
			for (let j=0; j<baseDivs; j++) {
				let baseIndex = j;
				let upperIndex = j;
				if (upperIndex > upperDivs) {
					upperIndex = upperDivs;
				}
				// lower triangles:
				triangles.push([
					positions[i][baseIndex*3], positions[i][baseIndex*3+1], positions[i][baseIndex*3+2],
					positions[i][(baseIndex+1)*3], positions[i][(baseIndex+1)*3+1], positions[i][(baseIndex+1)*3+2],
					positions[i+1][upperIndex*3], positions[i+1][upperIndex*3+1], positions[i+1][upperIndex*3+2]
				]);
				//upper triangles:
				if (upperIndex < upperDivs) {
					triangles.push([
						positions[i+1][upperIndex*3], positions[i+1][upperIndex*3+1], positions[i+1][upperIndex*3+2],
						positions[i+1][(upperIndex+1)*3], positions[i+1][(upperIndex+1)*3+1], positions[i+1][(upperIndex+1)*3+2],
						positions[i][baseIndex*3], positions[i][baseIndex*3+1], positions[i][baseIndex*3+2]
					]);
				}
			}
		}
		return triangles;
	}

Best regards

The thing is that a box geometry is defined with duplicated vertices to get the correct normals, so it is in fact equivalent to six planes merged into one geometry. Therefore, subdividing the planes will not alter their looks when using common mesh shading.

If you, on the other hand, define your own cubes that reuse the same 8 vertices for all triangles, and define the vertex normals to point in the corresponding 3D diagonal directions, shaders that use vertex normals will interpolate them all over the surface, typically making the surfaces look rounded. Depending on how subdivision handles normals, you may observe some changes.

A shader that outlines polygons will show the subdivisions no matter what you do with the normals.