Three.js:尝试渲染自定义网格(菱形十二面体)?
Three.js: trying to render a custom mesh (rhombic dodecahedron)?
我想渲染这个:
不幸的是,当我尝试创建自定义网格时,我得到了这个:
我发现了一些旧的 THREE.js 代码来渲染这个实体,但令人失望的是,它只有一半用处,因为它依赖于已弃用的 THREE.Face4()。因此,通过深入研究 Whosebug,我发现了我认为使用 2 THREE.Face3() 的解决方法。正如您在上面看到的,它没有用。这是我的代码。
//'2 Face3' to emulate 'Face4' function, thanks to @Kevin Miller and
@Jonathan at github.com
function drawSquare(x1, y1, x2, y2) {
var square = new THREE.Geometry();
//set 4 points
square.vertices.push( new THREE.Vector3( x1,y2,0) );
square.vertices.push( new THREE.Vector3( x1,y1,0) );
square.vertices.push( new THREE.Vector3( x2,y1,0) );
square.vertices.push( new THREE.Vector3( x2,y2,0) );
//push 1 triangle
square.faces.push( new THREE.Face3( 0,1,2) );
//push another triangle
square.faces.push( new THREE.Face3( 0,3,2) );
//return the square object with BOTH faces
return square;
};
//rhombic dodecahedron geometry, thanks to http://www.sacred-geometry.es
//vertices
var vertices = [ new THREE.Vector3( 2.04772293123743050, -4.09327412386437040, -5.74908146957292670),
new THREE.Vector3( 7.02732984841516030, 1.40331541320251810, -1.62706516545639390),
new THREE.Vector3( 4.22549114271519950, -1.62031854283173550, 5.78962800381778210),
new THREE.Vector3( 0.75411577446253997, 7.11690807989861880, -1.66761169970125600),
new THREE.Vector3(-0.75411577446252998, -7.11690807989862510, 1.66761169970125020),
new THREE.Vector3(-4.22549114271518980, 1.62031854283173260, -5.78962800381778920),
new THREE.Vector3( -2.0477229312374288, 4.09327412386436950, 5.74908146957292670),
new THREE.Vector3(-7.02732984841515230, -1.40331541320252740, 1.62706516545639970),
new THREE.Vector3( 6.27321407395262300, -5.71359266669610030, 0.04054653424485652),
new THREE.Vector3( 2.80183870569996340, 3.02363395603425690, -7.41669316927418000),
new THREE.Vector3( 4.97960691717773150, 5.49658953706689160, 4.12201630411653590),
new THREE.Vector3(-2.80183870569996340, -3.02363395603425690, 7.41669316927418000),
new THREE.Vector3(-4.97960691717773150, -5.49658953706689160, -4.12201630411653590),
new THREE.Vector3(-6.27321407395262480, 5.71359266669610210, -0.04054653424485653) ];
//faces
var faces = [ drawSquare(vertices[8],vertices[0],vertices[9],vertices[1]).faces[0],
drawSquare(vertices[8],vertices[0],vertices[9],vertices[1]).faces[1],
drawSquare(vertices[8],vertices[1],vertices[10],vertices[2]).faces[0],
drawSquare(vertices[8],vertices[1],vertices[10],vertices[2]).faces[1],
drawSquare(vertices[8],vertices[2],vertices[11],vertices[4]).faces[0],
drawSquare(vertices[8],vertices[2],vertices[11],vertices[4]).faces[1],
drawSquare(vertices[8],vertices[4],vertices[12],vertices[0]).faces[0],
drawSquare(vertices[8],vertices[4],vertices[12],vertices[0]).faces[1],
drawSquare(vertices[12],vertices[5],vertices[9],vertices[0]).faces[0],
drawSquare(vertices[12],vertices[5],vertices[9],vertices[0]).faces[1],
drawSquare(vertices[13],vertices[3],vertices[9],vertices[5]).faces[0],
drawSquare(vertices[13],vertices[3],vertices[9],vertices[5]).faces[1],
drawSquare(vertices[10],vertices[1],vertices[9],vertices[3]).faces[0],
drawSquare(vertices[10],vertices[1],vertices[9],vertices[3]).faces[1],
drawSquare(vertices[10],vertices[3],vertices[13],vertices[6]).faces[0],
drawSquare(vertices[10],vertices[3],vertices[13],vertices[6]).faces[1],
drawSquare(vertices[11],vertices[2],vertices[10],vertices[6]).faces[0],
drawSquare(vertices[11],vertices[2],vertices[10],vertices[6]).faces[1],
drawSquare(vertices[11],vertices[7],vertices[12],vertices[4]).faces[0],
drawSquare(vertices[11],vertices[7],vertices[12],vertices[4]).faces[1],
drawSquare(vertices[12],vertices[7],vertices[13],vertices[5]).faces[0],
drawSquare(vertices[12],vertices[7],vertices[13],vertices[5]).faces[1],
drawSquare(vertices[13],vertices[7],vertices[11],vertices[6]).faces[0],
drawSquare(vertices[13],vertices[7],vertices[11],vertices[6]).faces[1] ];
//create the mesh
var rhombic_dodecahedron_geo = new THREE.Geometry();
for(c=0; c<vertices.length; c++) { rhombic_dodecahedron_geo.vertices.push( vertices[c] ) };
for(d=0; d<faces.length; d++) { rhombic_dodecahedron_geo.faces.push( faces[d] ) };
var rhombic_dodecahedron_mat = new THREE.MeshBasicMaterial( {color: 0x4B32AF, wireframe: false} );
rhombic_dodecahedron = new THREE.Mesh(rhombic_dodecahedron_geo, rhombic_dodecahedron_mat);
scene.add(rhombic_dodecahedron);
任何人都可以发现任何错误吗?预先感谢您帮助解决这个令人沮丧的问题。
创建自定义多面体网格要遵循以下模式:
// geometry
var geometry = new THREE.Geometry();
// vertices
geometry.vertices = [
new THREE.Vector3( 2.04772293123743050, -4.09327412386437040, -5.74908146957292670),
new THREE.Vector3( 7.02732984841516030, 1.40331541320251810, -1.62706516545639390),
new THREE.Vector3( 4.22549114271519950, -1.62031854283173550, 5.78962800381778210),
new THREE.Vector3( 0.75411577446253997, 7.11690807989861880, -1.66761169970125600),
new THREE.Vector3(-0.75411577446252998, -7.11690807989862510, 1.66761169970125020),
new THREE.Vector3(-4.22549114271518980, 1.62031854283173260, -5.78962800381778920),
new THREE.Vector3( -2.0477229312374288, 4.09327412386436950, 5.74908146957292670),
new THREE.Vector3(-7.02732984841515230, -1.40331541320252740, 1.62706516545639970),
new THREE.Vector3( 6.27321407395262300, -5.71359266669610030, 0.04054653424485652),
new THREE.Vector3( 2.80183870569996340, 3.02363395603425690, -7.41669316927418000),
new THREE.Vector3( 4.97960691717773150, 5.49658953706689160, 4.12201630411653590),
new THREE.Vector3(-2.80183870569996340, -3.02363395603425690, 7.41669316927418000),
new THREE.Vector3(-4.97960691717773150, -5.49658953706689160, -4.12201630411653590),
new THREE.Vector3(-6.27321407395262480, 5.71359266669610210, -0.04054653424485653)
];
// faces - in counterclockwise winding order - important!
geometry.faces.push(
new THREE.Face3( 8, 0, 9 ), new THREE.Face3( 9, 1, 8 ),
new THREE.Face3( 8, 1, 10 ), new THREE.Face3( 10, 2, 8 ),
new THREE.Face3( 8, 2, 11 ), new THREE.Face3( 11, 4, 8 ),
new THREE.Face3( 8, 4, 12 ), new THREE.Face3( 12, 0, 8 ),
new THREE.Face3( 12, 5, 9 ), new THREE.Face3( 9, 0, 12 ),
new THREE.Face3( 13, 3, 9 ), new THREE.Face3( 9, 5, 13 ),
new THREE.Face3( 10, 1, 9 ), new THREE.Face3( 9, 3, 10 ),
new THREE.Face3( 10, 3, 13 ), new THREE.Face3( 13, 6, 10 ),
new THREE.Face3( 11, 2, 10 ), new THREE.Face3( 10, 6, 11 ),
new THREE.Face3( 11, 7, 12 ), new THREE.Face3( 12, 4, 11 ),
new THREE.Face3( 12, 7, 13 ), new THREE.Face3( 13, 5, 12 ),
new THREE.Face3( 13, 7, 11 ), new THREE.Face3( 11, 6, 13 )
);
// normals ( since they are not specified directly )
geometry.computeFaceNormals();
geometry.computeVertexNormals();
// material - polyhedron requires flat shading
var material = new THREE.MeshLambertMaterial( { color: 0x479100, shading: THREE.FlatShading } );
// mesh
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
请务必为您的场景添加灯光,因为 Lambert
material.
需要它
three.js r.71
扩展 WestLangley 的答案,这是在 threejs 中表示菱形十二面体的简化方法。
菱形十二面体可以通过在正方形的每个面上放置一个四角锥来构造,其中正方形的边长 l
和四角锥的高度 l/2
(来自 here).
下面的代码描述了基于具有
的正方形的菱形十二面体
- 起点在 (0, 0, 0)
- 旋转 (0, 0, 0)
- 顶面:(A、B、C、D)
- 底面:(E, F, G, H)
- 边长:2
您会注意到我的十二面体的面数是 WestLangley 的一半。这是因为所得十二面体的每个面实际上都是上述方形金字塔的两个相邻面的并集。 [编辑:我使用 Face4 生成菱形,但我刚刚发现 Face4 已被弃用,因此我在下面创建的每个菱形都需要用两个三角形替换。如何做到这一点应该很明显。]
(jsfiddle)
var geometry = new THREE.Geometry();
// vertices
geometry.vertices = [
new THREE.Vector3( -1, 1, -1 ), // A (0)
new THREE.Vector3( 1, 1, -1 ), // B (1)
new THREE.Vector3( 1, 1, 1 ), // C (2)
new THREE.Vector3( -1, 1, 1 ), // D (3)
new THREE.Vector3( -1, -1, -1 ), // E (4)
new THREE.Vector3( 1, -1, -1 ), // F (5)
new THREE.Vector3( 1, -1, 1 ), // G (6)
new THREE.Vector3( -1, -1, 1 ), // H (7)
new THREE.Vector3( -2, 0, 0 ), // left (8)
new THREE.Vector3( 2, 0, 0 ), // right (9)
new THREE.Vector3( 0, 2, 0 ), // top (10)
new THREE.Vector3( 0, -2, 0 ), // bottom (11)
new THREE.Vector3( 0, 0, 2 ), // front (12)
new THREE.Vector3( 0, 0, -2 ) // back (13)
];
// faces - in counterclockwise winding order
geometry.faces.push(
new THREE.Face4( 12, 2, 10, 3 ), // (front, C, top, D)
new THREE.Face4( 12, 6, 9, 2 ), // (front, G, right, C)
new THREE.Face4( 12, 7, 11, 6 ), // (front, H, bottom, G)
new THREE.Face4( 12, 3, 8, 7 ), // (front, D, left, H)
new THREE.Face4( 13, 5, 11, 4 ), // (back, F, bottom, E)
new THREE.Face4( 13, 4, 8, 0 ), // (back, E, left, A)
new THREE.Face4( 13, 0, 10, 1 ), // (back, A, top, B)
new THREE.Face4( 13, 1, 9, 5 ), // (back, B, right, F)
new THREE.Face4( 8, 3, 10, 0 ), // (left, D, top, A)
new THREE.Face4( 8, 4, 11, 7 ), // (left, E, bottom, H)
new THREE.Face4( 9, 1, 10, 2 ), // (right, B, top, C)
new THREE.Face4( 9, 6, 11, 5 ) // (right, G, bottom, F)
);
// normals ( since they are not specified directly )
geometry.computeFaceNormals();
geometry.computeVertexNormals();
// material - polyhedron requires flat shading
var material = new THREE.MeshLambertMaterial( { color: 0x479100, shading: THREE.FlatShading } );
// mesh
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
我想渲染这个:
不幸的是,当我尝试创建自定义网格时,我得到了这个:
我发现了一些旧的 THREE.js 代码来渲染这个实体,但令人失望的是,它只有一半用处,因为它依赖于已弃用的 THREE.Face4()。因此,通过深入研究 Whosebug,我发现了我认为使用 2 THREE.Face3() 的解决方法。正如您在上面看到的,它没有用。这是我的代码。
//'2 Face3' to emulate 'Face4' function, thanks to @Kevin Miller and
@Jonathan at github.com
function drawSquare(x1, y1, x2, y2) {
var square = new THREE.Geometry();
//set 4 points
square.vertices.push( new THREE.Vector3( x1,y2,0) );
square.vertices.push( new THREE.Vector3( x1,y1,0) );
square.vertices.push( new THREE.Vector3( x2,y1,0) );
square.vertices.push( new THREE.Vector3( x2,y2,0) );
//push 1 triangle
square.faces.push( new THREE.Face3( 0,1,2) );
//push another triangle
square.faces.push( new THREE.Face3( 0,3,2) );
//return the square object with BOTH faces
return square;
};
//rhombic dodecahedron geometry, thanks to http://www.sacred-geometry.es
//vertices
var vertices = [ new THREE.Vector3( 2.04772293123743050, -4.09327412386437040, -5.74908146957292670),
new THREE.Vector3( 7.02732984841516030, 1.40331541320251810, -1.62706516545639390),
new THREE.Vector3( 4.22549114271519950, -1.62031854283173550, 5.78962800381778210),
new THREE.Vector3( 0.75411577446253997, 7.11690807989861880, -1.66761169970125600),
new THREE.Vector3(-0.75411577446252998, -7.11690807989862510, 1.66761169970125020),
new THREE.Vector3(-4.22549114271518980, 1.62031854283173260, -5.78962800381778920),
new THREE.Vector3( -2.0477229312374288, 4.09327412386436950, 5.74908146957292670),
new THREE.Vector3(-7.02732984841515230, -1.40331541320252740, 1.62706516545639970),
new THREE.Vector3( 6.27321407395262300, -5.71359266669610030, 0.04054653424485652),
new THREE.Vector3( 2.80183870569996340, 3.02363395603425690, -7.41669316927418000),
new THREE.Vector3( 4.97960691717773150, 5.49658953706689160, 4.12201630411653590),
new THREE.Vector3(-2.80183870569996340, -3.02363395603425690, 7.41669316927418000),
new THREE.Vector3(-4.97960691717773150, -5.49658953706689160, -4.12201630411653590),
new THREE.Vector3(-6.27321407395262480, 5.71359266669610210, -0.04054653424485653) ];
//faces
var faces = [ drawSquare(vertices[8],vertices[0],vertices[9],vertices[1]).faces[0],
drawSquare(vertices[8],vertices[0],vertices[9],vertices[1]).faces[1],
drawSquare(vertices[8],vertices[1],vertices[10],vertices[2]).faces[0],
drawSquare(vertices[8],vertices[1],vertices[10],vertices[2]).faces[1],
drawSquare(vertices[8],vertices[2],vertices[11],vertices[4]).faces[0],
drawSquare(vertices[8],vertices[2],vertices[11],vertices[4]).faces[1],
drawSquare(vertices[8],vertices[4],vertices[12],vertices[0]).faces[0],
drawSquare(vertices[8],vertices[4],vertices[12],vertices[0]).faces[1],
drawSquare(vertices[12],vertices[5],vertices[9],vertices[0]).faces[0],
drawSquare(vertices[12],vertices[5],vertices[9],vertices[0]).faces[1],
drawSquare(vertices[13],vertices[3],vertices[9],vertices[5]).faces[0],
drawSquare(vertices[13],vertices[3],vertices[9],vertices[5]).faces[1],
drawSquare(vertices[10],vertices[1],vertices[9],vertices[3]).faces[0],
drawSquare(vertices[10],vertices[1],vertices[9],vertices[3]).faces[1],
drawSquare(vertices[10],vertices[3],vertices[13],vertices[6]).faces[0],
drawSquare(vertices[10],vertices[3],vertices[13],vertices[6]).faces[1],
drawSquare(vertices[11],vertices[2],vertices[10],vertices[6]).faces[0],
drawSquare(vertices[11],vertices[2],vertices[10],vertices[6]).faces[1],
drawSquare(vertices[11],vertices[7],vertices[12],vertices[4]).faces[0],
drawSquare(vertices[11],vertices[7],vertices[12],vertices[4]).faces[1],
drawSquare(vertices[12],vertices[7],vertices[13],vertices[5]).faces[0],
drawSquare(vertices[12],vertices[7],vertices[13],vertices[5]).faces[1],
drawSquare(vertices[13],vertices[7],vertices[11],vertices[6]).faces[0],
drawSquare(vertices[13],vertices[7],vertices[11],vertices[6]).faces[1] ];
//create the mesh
var rhombic_dodecahedron_geo = new THREE.Geometry();
for(c=0; c<vertices.length; c++) { rhombic_dodecahedron_geo.vertices.push( vertices[c] ) };
for(d=0; d<faces.length; d++) { rhombic_dodecahedron_geo.faces.push( faces[d] ) };
var rhombic_dodecahedron_mat = new THREE.MeshBasicMaterial( {color: 0x4B32AF, wireframe: false} );
rhombic_dodecahedron = new THREE.Mesh(rhombic_dodecahedron_geo, rhombic_dodecahedron_mat);
scene.add(rhombic_dodecahedron);
任何人都可以发现任何错误吗?预先感谢您帮助解决这个令人沮丧的问题。
创建自定义多面体网格要遵循以下模式:
// geometry
var geometry = new THREE.Geometry();
// vertices
geometry.vertices = [
new THREE.Vector3( 2.04772293123743050, -4.09327412386437040, -5.74908146957292670),
new THREE.Vector3( 7.02732984841516030, 1.40331541320251810, -1.62706516545639390),
new THREE.Vector3( 4.22549114271519950, -1.62031854283173550, 5.78962800381778210),
new THREE.Vector3( 0.75411577446253997, 7.11690807989861880, -1.66761169970125600),
new THREE.Vector3(-0.75411577446252998, -7.11690807989862510, 1.66761169970125020),
new THREE.Vector3(-4.22549114271518980, 1.62031854283173260, -5.78962800381778920),
new THREE.Vector3( -2.0477229312374288, 4.09327412386436950, 5.74908146957292670),
new THREE.Vector3(-7.02732984841515230, -1.40331541320252740, 1.62706516545639970),
new THREE.Vector3( 6.27321407395262300, -5.71359266669610030, 0.04054653424485652),
new THREE.Vector3( 2.80183870569996340, 3.02363395603425690, -7.41669316927418000),
new THREE.Vector3( 4.97960691717773150, 5.49658953706689160, 4.12201630411653590),
new THREE.Vector3(-2.80183870569996340, -3.02363395603425690, 7.41669316927418000),
new THREE.Vector3(-4.97960691717773150, -5.49658953706689160, -4.12201630411653590),
new THREE.Vector3(-6.27321407395262480, 5.71359266669610210, -0.04054653424485653)
];
// faces - in counterclockwise winding order - important!
geometry.faces.push(
new THREE.Face3( 8, 0, 9 ), new THREE.Face3( 9, 1, 8 ),
new THREE.Face3( 8, 1, 10 ), new THREE.Face3( 10, 2, 8 ),
new THREE.Face3( 8, 2, 11 ), new THREE.Face3( 11, 4, 8 ),
new THREE.Face3( 8, 4, 12 ), new THREE.Face3( 12, 0, 8 ),
new THREE.Face3( 12, 5, 9 ), new THREE.Face3( 9, 0, 12 ),
new THREE.Face3( 13, 3, 9 ), new THREE.Face3( 9, 5, 13 ),
new THREE.Face3( 10, 1, 9 ), new THREE.Face3( 9, 3, 10 ),
new THREE.Face3( 10, 3, 13 ), new THREE.Face3( 13, 6, 10 ),
new THREE.Face3( 11, 2, 10 ), new THREE.Face3( 10, 6, 11 ),
new THREE.Face3( 11, 7, 12 ), new THREE.Face3( 12, 4, 11 ),
new THREE.Face3( 12, 7, 13 ), new THREE.Face3( 13, 5, 12 ),
new THREE.Face3( 13, 7, 11 ), new THREE.Face3( 11, 6, 13 )
);
// normals ( since they are not specified directly )
geometry.computeFaceNormals();
geometry.computeVertexNormals();
// material - polyhedron requires flat shading
var material = new THREE.MeshLambertMaterial( { color: 0x479100, shading: THREE.FlatShading } );
// mesh
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
请务必为您的场景添加灯光,因为 Lambert
material.
three.js r.71
扩展 WestLangley 的答案,这是在 threejs 中表示菱形十二面体的简化方法。
菱形十二面体可以通过在正方形的每个面上放置一个四角锥来构造,其中正方形的边长 l
和四角锥的高度 l/2
(来自 here).
下面的代码描述了基于具有
的正方形的菱形十二面体- 起点在 (0, 0, 0)
- 旋转 (0, 0, 0)
- 顶面:(A、B、C、D)
- 底面:(E, F, G, H)
- 边长:2
您会注意到我的十二面体的面数是 WestLangley 的一半。这是因为所得十二面体的每个面实际上都是上述方形金字塔的两个相邻面的并集。 [编辑:我使用 Face4 生成菱形,但我刚刚发现 Face4 已被弃用,因此我在下面创建的每个菱形都需要用两个三角形替换。如何做到这一点应该很明显。]
(jsfiddle)
var geometry = new THREE.Geometry();
// vertices
geometry.vertices = [
new THREE.Vector3( -1, 1, -1 ), // A (0)
new THREE.Vector3( 1, 1, -1 ), // B (1)
new THREE.Vector3( 1, 1, 1 ), // C (2)
new THREE.Vector3( -1, 1, 1 ), // D (3)
new THREE.Vector3( -1, -1, -1 ), // E (4)
new THREE.Vector3( 1, -1, -1 ), // F (5)
new THREE.Vector3( 1, -1, 1 ), // G (6)
new THREE.Vector3( -1, -1, 1 ), // H (7)
new THREE.Vector3( -2, 0, 0 ), // left (8)
new THREE.Vector3( 2, 0, 0 ), // right (9)
new THREE.Vector3( 0, 2, 0 ), // top (10)
new THREE.Vector3( 0, -2, 0 ), // bottom (11)
new THREE.Vector3( 0, 0, 2 ), // front (12)
new THREE.Vector3( 0, 0, -2 ) // back (13)
];
// faces - in counterclockwise winding order
geometry.faces.push(
new THREE.Face4( 12, 2, 10, 3 ), // (front, C, top, D)
new THREE.Face4( 12, 6, 9, 2 ), // (front, G, right, C)
new THREE.Face4( 12, 7, 11, 6 ), // (front, H, bottom, G)
new THREE.Face4( 12, 3, 8, 7 ), // (front, D, left, H)
new THREE.Face4( 13, 5, 11, 4 ), // (back, F, bottom, E)
new THREE.Face4( 13, 4, 8, 0 ), // (back, E, left, A)
new THREE.Face4( 13, 0, 10, 1 ), // (back, A, top, B)
new THREE.Face4( 13, 1, 9, 5 ), // (back, B, right, F)
new THREE.Face4( 8, 3, 10, 0 ), // (left, D, top, A)
new THREE.Face4( 8, 4, 11, 7 ), // (left, E, bottom, H)
new THREE.Face4( 9, 1, 10, 2 ), // (right, B, top, C)
new THREE.Face4( 9, 6, 11, 5 ) // (right, G, bottom, F)
);
// normals ( since they are not specified directly )
geometry.computeFaceNormals();
geometry.computeVertexNormals();
// material - polyhedron requires flat shading
var material = new THREE.MeshLambertMaterial( { color: 0x479100, shading: THREE.FlatShading } );
// mesh
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );