Three.js 如何制作全斜角立方体?
Three.js how to make a FULLY beveled cube?
我正在尝试制作一个斜角立方体,但我似乎不知道如何制作。我找到了 THREE.ExtrudeGeometry
here,但如果您注意到,在示例编辑器中它只有顶面和底面有斜边,所以我得到的是这样的:
而不是像这样的东西,这就是我想要的:
代码:
var bevelShape = new THREE.Shape();
bevelShape.moveTo(0, unitSize - 0.2);
bevelShape.lineTo(0, unitSize - 0.2);
bevelShape.lineTo(unitSize - 0.2, unitSize - 0.2);
bevelShape.lineTo(unitSize - 0.2, 0);
bevelShape.lineTo(0, 0);
var extrudeSettings = {
steps: 20,
depth: unitSize - 0.2,
bevelEnabled: true,
bevelThickness: 0.1,
bevelSize: 0.1,
bevelOffset: 0,
bevelSegments: 1
};
var blockGeometry = new THREE.ExtrudeGeometry(bevelShape, extrudeSettings);
var blockMaterial = new THREE.MeshStandardMaterial({color: color, roughness: 1, metalness: -1});
var block = new THREE.Mesh(blockGeometry, blockMaterial);
scene.add(block);
我应该怎么做才能做到这一点?
谢谢!
您可以构建自己的几何图形。
或者随意搜索论坛,因为您可以在那里找到许多有用且有趣的东西。
例如:https://discourse.threejs.org/t/faceted-box-geometry/5474
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, 1, 1, 1000);
camera.position.set(15, 10, 20).setLength(130);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setClearColor(0x404040);
//renderer.setPixelRatio(0.5);
var canvas = renderer.domElement;
document.body.appendChild(canvas);
var controls = new THREE.OrbitControls(camera, canvas);
var light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.set(1, 2, 1);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.5));
for (let i = 0; i < 11; i++) {
let r = 10;
let posX = (-5 + i) * 12.5;
let wireGeom = facetedBox(r, r, r, i * 0.5, true);
let wire = new THREE.LineSegments(
wireGeom,
new THREE.LineBasicMaterial({ color: Math.random() * 0x808080 + 0x808080 })
);
wire.position.x = posX;
scene.add(wire);
let geom = facetedBox(r, r, r, i * 0.5, false);
let mesh = new THREE.Mesh(
geom,
new THREE.MeshStandardMaterial({
color: Math.random() * 0x808080 + 0x808080,
flatShading: true
})
);
mesh.position.x = posX;
scene.add(mesh);
}
var clock = new THREE.Clock();
renderer.setAnimationLoop(() => {
if (resize(renderer)) {
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
renderer.render(scene, camera);
});
function resize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
html, body {
height: 100%;
margin: 0;
overflow: hidden;
}
canvas {
width: 100%;
height: 100%;
display; block;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script>
function facetedBox(w, h, d, f, isWireframed){
let hw = w * 0.5, hh = h * 0.5, hd = d * 0.5;
let vertices = [
// px
hw, hh - f, -hd + f, // 0
hw, -hh + f, -hd + f, // 1
hw, -hh + f, hd - f, // 2
hw, hh - f, hd - f, // 3
// pz
hw - f, hh - f, hd, // 4
hw - f, -hh + f, hd, // 5
-hw + f, -hh + f, hd, // 6
-hw + f, hh - f, hd, // 7
// nx
-hw, hh - f, hd - f, // 8
-hw, -hh + f, hd - f, // 9
-hw, -hh + f, -hd + f, // 10
-hw, hh - f, -hd + f, // 11
// nz
-hw + f, hh - f, -hd, // 12
-hw + f, -hh + f, -hd, // 13
hw - f, -hh + f, -hd, // 14
hw - f, hh - f, -hd, // 15
// py
hw - f, hh, -hd + f, // 16
hw - f, hh, hd - f, // 17
-hw + f, hh, hd - f, // 18
-hw + f, hh, -hd + f, // 19
// ny
hw - f, -hh, -hd + f, // 20
hw - f, -hh, hd - f, // 21
-hw + f, -hh, hd - f, // 22
-hw + f, -hh, -hd + f // 23
];
let indices = [
0, 2, 1, 3, 2, 0,
4, 6, 5, 7, 6, 4,
8, 10, 9, 11, 10, 8,
12, 14, 13, 15, 14, 12,
16, 18, 17, 19, 18, 16,
20, 21, 22, 23, 20, 22,
// link the sides
3, 5, 2, 4, 5, 3,
7, 9, 6, 8, 9, 7,
11, 13, 10, 12, 13, 11,
15, 1, 14, 0, 1, 15,
// link the lids
// top
16, 3, 0, 17, 3, 16,
17, 7, 4, 18, 7, 17,
18, 11, 8, 19, 11, 18,
19, 15, 12, 16, 15, 19,
// bottom
1, 21, 20, 2, 21, 1,
5, 22, 21, 6, 22, 5,
9, 23, 22, 10, 23, 9,
13, 20, 23, 14, 20, 13,
// corners
// top
3, 17, 4,
7, 18, 8,
11, 19, 12,
15, 16, 0,
// bottom
2, 5, 21,
6, 9, 22,
10, 13, 23,
14, 1, 20
];
let indicesWire = [
0, 1, 1, 2, 2, 3, 3, 0,
4, 5, 5, 6, 6, 7, 7, 4,
8, 9, 9, 10, 10, 11, 11, 8,
12, 13, 13, 14, 14, 15, 15, 12,
16, 17, 17, 18, 18, 19, 19, 16,
20, 21, 21, 22, 22, 23, 23, 20,
// link the sides
2, 5, 3, 4, //px - pz
6, 9, 7, 8, // pz - nx
10, 13, 11, 12, // nx - nz
15, 0, 14, 1, // nz - px
// link the lids
// top
16, 0, 17, 3, // px
17, 4, 18, 7, // pz
18, 8, 19, 11, // nx
19, 12, 16, 15, // nz
// bottom
20, 1, 21, 2,
21, 5, 22, 6,
22, 9, 23, 10,
23, 13, 20, 14
];
let geom = new THREE.BufferGeometry();
geom.setAttribute("position", new THREE.BufferAttribute(new Float32Array(vertices), 3));
geom.setIndex(isWireframed ? indicesWire : indices);
if (!isWireframed) geom.computeVertexNormals();
return geom;
}
</script>
我正在尝试制作一个斜角立方体,但我似乎不知道如何制作。我找到了 THREE.ExtrudeGeometry
here,但如果您注意到,在示例编辑器中它只有顶面和底面有斜边,所以我得到的是这样的:
而不是像这样的东西,这就是我想要的:
代码:
var bevelShape = new THREE.Shape();
bevelShape.moveTo(0, unitSize - 0.2);
bevelShape.lineTo(0, unitSize - 0.2);
bevelShape.lineTo(unitSize - 0.2, unitSize - 0.2);
bevelShape.lineTo(unitSize - 0.2, 0);
bevelShape.lineTo(0, 0);
var extrudeSettings = {
steps: 20,
depth: unitSize - 0.2,
bevelEnabled: true,
bevelThickness: 0.1,
bevelSize: 0.1,
bevelOffset: 0,
bevelSegments: 1
};
var blockGeometry = new THREE.ExtrudeGeometry(bevelShape, extrudeSettings);
var blockMaterial = new THREE.MeshStandardMaterial({color: color, roughness: 1, metalness: -1});
var block = new THREE.Mesh(blockGeometry, blockMaterial);
scene.add(block);
我应该怎么做才能做到这一点?
谢谢!
您可以构建自己的几何图形。
或者随意搜索论坛,因为您可以在那里找到许多有用且有趣的东西。
例如:https://discourse.threejs.org/t/faceted-box-geometry/5474
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, 1, 1, 1000);
camera.position.set(15, 10, 20).setLength(130);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setClearColor(0x404040);
//renderer.setPixelRatio(0.5);
var canvas = renderer.domElement;
document.body.appendChild(canvas);
var controls = new THREE.OrbitControls(camera, canvas);
var light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.set(1, 2, 1);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.5));
for (let i = 0; i < 11; i++) {
let r = 10;
let posX = (-5 + i) * 12.5;
let wireGeom = facetedBox(r, r, r, i * 0.5, true);
let wire = new THREE.LineSegments(
wireGeom,
new THREE.LineBasicMaterial({ color: Math.random() * 0x808080 + 0x808080 })
);
wire.position.x = posX;
scene.add(wire);
let geom = facetedBox(r, r, r, i * 0.5, false);
let mesh = new THREE.Mesh(
geom,
new THREE.MeshStandardMaterial({
color: Math.random() * 0x808080 + 0x808080,
flatShading: true
})
);
mesh.position.x = posX;
scene.add(mesh);
}
var clock = new THREE.Clock();
renderer.setAnimationLoop(() => {
if (resize(renderer)) {
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
renderer.render(scene, camera);
});
function resize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
html, body {
height: 100%;
margin: 0;
overflow: hidden;
}
canvas {
width: 100%;
height: 100%;
display; block;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script>
function facetedBox(w, h, d, f, isWireframed){
let hw = w * 0.5, hh = h * 0.5, hd = d * 0.5;
let vertices = [
// px
hw, hh - f, -hd + f, // 0
hw, -hh + f, -hd + f, // 1
hw, -hh + f, hd - f, // 2
hw, hh - f, hd - f, // 3
// pz
hw - f, hh - f, hd, // 4
hw - f, -hh + f, hd, // 5
-hw + f, -hh + f, hd, // 6
-hw + f, hh - f, hd, // 7
// nx
-hw, hh - f, hd - f, // 8
-hw, -hh + f, hd - f, // 9
-hw, -hh + f, -hd + f, // 10
-hw, hh - f, -hd + f, // 11
// nz
-hw + f, hh - f, -hd, // 12
-hw + f, -hh + f, -hd, // 13
hw - f, -hh + f, -hd, // 14
hw - f, hh - f, -hd, // 15
// py
hw - f, hh, -hd + f, // 16
hw - f, hh, hd - f, // 17
-hw + f, hh, hd - f, // 18
-hw + f, hh, -hd + f, // 19
// ny
hw - f, -hh, -hd + f, // 20
hw - f, -hh, hd - f, // 21
-hw + f, -hh, hd - f, // 22
-hw + f, -hh, -hd + f // 23
];
let indices = [
0, 2, 1, 3, 2, 0,
4, 6, 5, 7, 6, 4,
8, 10, 9, 11, 10, 8,
12, 14, 13, 15, 14, 12,
16, 18, 17, 19, 18, 16,
20, 21, 22, 23, 20, 22,
// link the sides
3, 5, 2, 4, 5, 3,
7, 9, 6, 8, 9, 7,
11, 13, 10, 12, 13, 11,
15, 1, 14, 0, 1, 15,
// link the lids
// top
16, 3, 0, 17, 3, 16,
17, 7, 4, 18, 7, 17,
18, 11, 8, 19, 11, 18,
19, 15, 12, 16, 15, 19,
// bottom
1, 21, 20, 2, 21, 1,
5, 22, 21, 6, 22, 5,
9, 23, 22, 10, 23, 9,
13, 20, 23, 14, 20, 13,
// corners
// top
3, 17, 4,
7, 18, 8,
11, 19, 12,
15, 16, 0,
// bottom
2, 5, 21,
6, 9, 22,
10, 13, 23,
14, 1, 20
];
let indicesWire = [
0, 1, 1, 2, 2, 3, 3, 0,
4, 5, 5, 6, 6, 7, 7, 4,
8, 9, 9, 10, 10, 11, 11, 8,
12, 13, 13, 14, 14, 15, 15, 12,
16, 17, 17, 18, 18, 19, 19, 16,
20, 21, 21, 22, 22, 23, 23, 20,
// link the sides
2, 5, 3, 4, //px - pz
6, 9, 7, 8, // pz - nx
10, 13, 11, 12, // nx - nz
15, 0, 14, 1, // nz - px
// link the lids
// top
16, 0, 17, 3, // px
17, 4, 18, 7, // pz
18, 8, 19, 11, // nx
19, 12, 16, 15, // nz
// bottom
20, 1, 21, 2,
21, 5, 22, 6,
22, 9, 23, 10,
23, 13, 20, 14
];
let geom = new THREE.BufferGeometry();
geom.setAttribute("position", new THREE.BufferAttribute(new Float32Array(vertices), 3));
geom.setIndex(isWireframed ? indicesWire : indices);
if (!isWireframed) geom.computeVertexNormals();
return geom;
}
</script>