绘制整个立方体的面,而不是构成面的三角形 -three.js [英] Paint cube faces as a whole, not the triangles that make up the face - three.js
问题描述
尝试用不同的颜色绘制每个立方体的面,我发现了一个
得到构成每张脸的三角形,单独绘制.
为了达到理想的效果,我对上面的代码做了如下修改:
var geometry = new THREE.BoxGeometry(5, 5, 5);for ( var i = 0; i < geometry.faces.length; i += 2 ) {var faceColor = Math.random() * 0xffffff;geometry.faces[i].color.setHex(faceColor);geometry.faces[i+1].color.setHex(faceColor);}var material = new THREE.MeshBasicMaterial({颜色:0xffffff,顶点颜色:THREE.FaceColors});
但这一切似乎有点过头了!
'use strict';var 相机、场景、渲染器、立方体;在里面();使成为();函数初始化(){场景 = 新的 THREE.Scene();camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);//渲染器渲染器 = 新的 THREE.WebGLRenderer({阿尔法:真实});renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);相机.位置.z = 12;//网格 - 立方体var geometry = new THREE.BoxGeometry(5, 5, 5);for (var i = 0; i < geometry.faces.length; i += 2) {var faceColor = Math.random() * 0xffffff;geometry.faces[i].color.setHex(faceColor);geometry.faces[i + 1].color.setHex(faceColor);}var material = new THREE.MeshBasicMaterial({颜色:0xffffff,顶点颜色:THREE.FaceColors});立方体 = 新的 THREE.Mesh(geometry, material);场景.添加(立方体);//光var pointLight = new THREE.PointLight(0xFFFFFF);pointLight.position.x = 10;pointLight.position.y = 50;pointLight.position.z = 130;场景添加(点光源);}函数渲染(){立方体.旋转.x = 16;立方体.旋转.y = 4;立方体.旋转.z -= 5;renderer.render(场景,相机);}
body,帆布 {边距:0;填充:0;}身体 {溢出:隐藏;背景色:#fff;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/86/three.js"></script>
我是否遗漏了 Three.js 上的一些东西来完成整个面部绘画?
如果您切换到 BufferGeometry
,您可以使用 groups
来控制几何体部分的材质.组基于顶点索引,并允许您定义材质索引,该索引将引用材质数组中的材质.
考虑:
//开始,计数,材料索引bufferGeometry.addGroup(12, 6, 2)
这告诉几何体在索引索引 12处开始一组新的三角形,并占6个索引(引用6个顶点).最后一个参数告诉三角形组使用材质索引 2(用于创建网格的材质数组的索引 2).
在下面的示例中,我为立方体的每一面指定了不同的颜色.您可能认为这与设置面部颜色的效果相同,但请注意,这是为每组设置材质,而不仅仅是颜色,这会导致创建一些非常酷的效果.
var 渲染器、场景、相机、控件、统计信息、网格;var WIDTH = window.innerWidth,高度 = window.innerHeight,视场 = 35,近 = 1,远 = 1000;函数 populateScene() {var bg = new THREE.BufferGeometry();bg.addAttribute("position", new THREE.BufferAttribute(new Float32Array([//正面-1, 1, 1,//0-1, -1, 1,//11, 1, 1,//21, -1, 1,//3//对1, 1, 1,//41, -1, 1,//51, 1, -1,//61, -1, -1,//7//背部1, 1, -1,//81, -1, -1,//9-1, 1, -1,//10-1, -1, -1,//11//剩下-1, 1, -1,//12-1, -1, -1,//13-1, 1, 1,//14-1, -1, 1,//15//顶部-1, 1, -1,//16-1, 1, 1,//171, 1, -1,//181, 1, 1,//19//底部-1, -1, 1,//20-1, -1, -1,//211, -1, 1,//221, -1, -1//23]), 3));bg.addAttribute("normal", new THREE.BufferAttribute(new Float32Array([//正面0, 0, 1,//00, 0, 1,//10, 0, 1,//20, 0, 1,//3//对1, 0, 0,//41, 0, 0,//51, 0, 0,//61, 0, 0,//7//背部0, 0, -1,//80, 0, -1,//90, 0, -1,//100, 0, -1,//11//剩下-1, 0, 0,//12-1, 0, 0,//13-1, 0, 0,//14-1, 0, 0,//15//顶部0, 1, 0,//160, 1, 0,//170, 1, 0,//180, 1, 0,//19//底部0, -1, 0,//200, -1, 0,//210, -1, 0,//220, -1, 0//23]), 3));bg.setIndex(new THREE.BufferAttribute(new Uint32Array([//前面 00, 1, 2,3, 2, 1,//右边 64, 5, 6,7, 6, 5,//返回 128, 9, 10,11, 10, 9,//左 1812, 13, 14,15, 14, 13,//前 2416, 17, 18,19, 18, 17,//底部 3020, 21, 22,23、22、21]), 1));bg.clearGroups();//开始,计数,材料索引bg.addGroup(0, 6, 0);bg.addGroup(6, 6, 1);bg.addGroup(12, 6, 2);bg.addGroup(18, 6, 3);bg.addGroup(24, 6, 4);bg.addGroup(30, 6, 5);var 材料 = [new THREE.MeshLambertMaterial({color:"red"}),new THREE.MeshLambertMaterial({color:"green"}),new THREE.MeshLambertMaterial({color:"blue"}),new THREE.MeshLambertMaterial({color:"cyan"}),新的 THREE.MeshLambertMaterial({color:"magenta"}),new THREE.MeshLambertMaterial({color:"yellow"})];mesh = new THREE.Mesh(bg, materials);mesh.scale.set(5, 5, 5);场景.添加(网格);}函数初始化(){document.body.style.backgroundColor = "slateGray";渲染器 = 新的 THREE.WebGLRenderer({抗锯齿:真实,阿尔法:真实});renderer.shadowMap.enabled = true;renderer.shadowMap.type = THREE.PCFSoftShadowMap;document.body.appendChild(renderer.domElement);document.body.style.overflow = "隐藏";document.body.style.margin = "0";document.body.style.padding = "0";场景 = 新的 THREE.Scene();相机 = 新的 THREE.PerspectiveCamera(FOV, WIDTH/HEIGHT, NEAR, FAR);相机.位置.z = 50;场景.添加(相机);控件 = 新的 THREE.TrackballControls(camera, renderer.domElement);control.dynamicDampingFactor = 0.5;control.rotateSpeed = 3;var light = new THREE.PointLight(0xffffff, 1, Infinity);相机.添加(光);统计=新统计();stats.domElement.style.position = '绝对';stats.domElement.style.top = '0';document.body.appendChild(stats.domElement);调整大小();window.onresize = 调整大小;populateScene();动画();}函数调整大小(){WIDTH = window.innerWidth;高度 = window.innerHeight;如果(渲染器&&相机&&控制){renderer.setSize(WIDTH, HEIGHT);camera.aspect = 宽度/高度;相机.updateProjectionMatrix();control.handleResize();}}函数渲染(){renderer.render(场景,相机);}函数动画(){网格.旋转.x += 0.015;网格.旋转.y += 0.017;网格.旋转.z += 0.019;请求动画帧(动画);使成为();控制更新();stats.update();}功能三准备(){在里面();}(功能() {函数添加脚本(网址,回调){回调 = 回调 ||功能() {};var script = document.createElement("script");script.addEventListener("load", callback);script.setAttribute("src", url);document.head.appendChild(script);}addScript("https://threejs.org/build/three.js", function() {addScript("https://threejs.org/examples/js/controls/TrackballControls.js", function() {addScript("https://threejs.org/examples/js/libs/stats.min.js", function() {三就绪();})})})})();
使用基础 BoxBufferGeometry
根据 pailhead 对原始帖子的评论,这里有一个使用未修改的 BoxBufferGeometry
的片段.但正如他们在评论中提到的,您仍然需要知道哪个组对应哪个面孔.
var 渲染器、场景、相机、控件、统计信息、网格;var WIDTH = window.innerWidth,高度 = window.innerHeight,视场 = 35,近 = 1,远 = 1000;函数 populateScene() {var bg = new THREE.BoxBufferGeometry(1, 1, 1);var 材料 = [new THREE.MeshLambertMaterial({color:"red"}),new THREE.MeshLambertMaterial({color:"green"}),new THREE.MeshLambertMaterial({color:"blue"}),new THREE.MeshLambertMaterial({color:"cyan"}),新的 THREE.MeshLambertMaterial({color:"magenta"}),new THREE.MeshLambertMaterial({color:"yellow"})];mesh = new THREE.Mesh(bg, materials);mesh.scale.set(10, 10, 10);场景.添加(网格);}函数初始化(){document.body.style.backgroundColor = "slateGray";渲染器 = 新的 THREE.WebGLRenderer({抗锯齿:真实,阿尔法:真实});renderer.shadowMap.enabled = true;renderer.shadowMap.type = THREE.PCFSoftShadowMap;document.body.appendChild(renderer.domElement);document.body.style.overflow = "隐藏";document.body.style.margin = "0";document.body.style.padding = "0";场景 = 新的 THREE.Scene();相机 = 新的 THREE.PerspectiveCamera(FOV, WIDTH/HEIGHT, NEAR, FAR);相机.位置.z = 50;场景.添加(相机);控件 = 新的 THREE.TrackballControls(camera, renderer.domElement);control.dynamicDampingFactor = 0.5;control.rotateSpeed = 3;var light = new THREE.PointLight(0xffffff, 1, Infinity);相机.添加(光);统计=新统计();stats.domElement.style.position = '绝对';stats.domElement.style.top = '0';document.body.appendChild(stats.domElement);调整大小();window.onresize = 调整大小;populateScene();动画();}函数调整大小(){WIDTH = window.innerWidth;高度 = window.innerHeight;如果(渲染器&&相机&&控制){renderer.setSize(WIDTH, HEIGHT);camera.aspect = 宽度/高度;相机.updateProjectionMatrix();control.handleResize();}}函数渲染(){renderer.render(场景,相机);}函数动画(){网格.旋转.x += 0.015;网格.旋转.y += 0.017;网格.旋转.z += 0.019;请求动画帧(动画);使成为();控制更新();stats.update();}功能三准备(){在里面();}(功能() {函数添加脚本(网址,回调){回调 = 回调 ||功能() {};var script = document.createElement("script");script.addEventListener("load", callback);script.setAttribute("src", url);document.head.appendChild(script);}addScript("https://threejs.org/build/three.js", function() {addScript("https://threejs.org/examples/js/controls/TrackballControls.js", function() {addScript("https://threejs.org/examples/js/libs/stats.min.js", function() {三就绪();})})})})();
Trying to paint each cube face with a different color, I found a thread that presents a way to achieve this:
var geometry = new THREE.BoxGeometry(5, 5, 5);
for (var i = 0; i < geometry.faces.length; i++) {
geometry.faces[i].color.setHex(Math.random() * 0xffffff);
}
var material = new THREE.MeshBasicMaterial({
color: 0xffffff,
vertexColors: THREE.FaceColors
});
But with three.js r86, I get the following result:
Got the triangles that make up each face, painted individually.
To achieve the desirable effect, I used the following adaptation of the above code:
var geometry = new THREE.BoxGeometry(5, 5, 5);
for ( var i = 0; i < geometry.faces.length; i += 2 ) {
var faceColor = Math.random() * 0xffffff;
geometry.faces[i].color.setHex(faceColor);
geometry.faces[i+1].color.setHex(faceColor);
}
var material = new THREE.MeshBasicMaterial({
color: 0xffffff,
vertexColors: THREE.FaceColors
});
But this all seems a bit over worked!
'use strict';
var camera, scene, renderer, cube;
init();
render();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// renderer
renderer = new THREE.WebGLRenderer({
alpha: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.z = 12;
// Mesh - cube
var geometry = new THREE.BoxGeometry(5, 5, 5);
for (var i = 0; i < geometry.faces.length; i += 2) {
var faceColor = Math.random() * 0xffffff;
geometry.faces[i].color.setHex(faceColor);
geometry.faces[i + 1].color.setHex(faceColor);
}
var material = new THREE.MeshBasicMaterial({
color: 0xffffff,
vertexColors: THREE.FaceColors
});
cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// Light
var pointLight = new THREE.PointLight(0xFFFFFF);
pointLight.position.x = 10;
pointLight.position.y = 50;
pointLight.position.z = 130;
scene.add(pointLight);
}
function render() {
cube.rotation.x = 16;
cube.rotation.y = 4;
cube.rotation.z -= 5;
renderer.render(scene, camera);
}
body,
canvas {
margin: 0;
padding: 0;
}
body {
overflow: hidden;
background-color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/86/three.js"></script>
Am I missing something on three.js to accomplish the face painting as a whole ?
If you switch to BufferGeometry
you can use groups
to control the material of sections of your geometry. Groups are based on the vertex indices, and allow you to define a material index, which will reference a material inside an array of materials.
Consider:
// start, count, material index
bufferGeometry.addGroup(12, 6, 2)
This tells the geometry to start a new group of triangles at indices index 12, and accounts for 6 indices (which reference 6 vertices). The final parameter tells the group of triangles to use material index 2 (index 2 of the array of materials you use to create the mesh).
In the example below, I've given each side of a cube a different color. You might think this is the same effect as setting face colors, but note that this is setting a material per group, not just a color, which can lead to creating some really cool effects.
var renderer, scene, camera, controls, stats, mesh;
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight,
FOV = 35,
NEAR = 1,
FAR = 1000;
function populateScene() {
var bg = new THREE.BufferGeometry();
bg.addAttribute("position", new THREE.BufferAttribute(new Float32Array([
// front
-1, 1, 1, // 0
-1, -1, 1, // 1
1, 1, 1, // 2
1, -1, 1, // 3
// right
1, 1, 1, // 4
1, -1, 1, // 5
1, 1, -1, // 6
1, -1, -1, // 7
// back
1, 1, -1, // 8
1, -1, -1, // 9
-1, 1, -1, // 10
-1, -1, -1, // 11
// left
-1, 1, -1, // 12
-1, -1, -1, // 13
-1, 1, 1, // 14
-1, -1, 1, // 15
// top
-1, 1, -1, // 16
-1, 1, 1, // 17
1, 1, -1, // 18
1, 1, 1, // 19
// bottom
-1, -1, 1, // 20
-1, -1, -1, // 21
1, -1, 1, // 22
1, -1, -1 // 23
]), 3));
bg.addAttribute("normal", new THREE.BufferAttribute(new Float32Array([
// front
0, 0, 1, // 0
0, 0, 1, // 1
0, 0, 1, // 2
0, 0, 1, // 3
// right
1, 0, 0, // 4
1, 0, 0, // 5
1, 0, 0, // 6
1, 0, 0, // 7
// back
0, 0, -1, // 8
0, 0, -1, // 9
0, 0, -1, // 10
0, 0, -1, // 11
// left
-1, 0, 0, // 12
-1, 0, 0, // 13
-1, 0, 0, // 14
-1, 0, 0, // 15
// top
0, 1, 0, // 16
0, 1, 0, // 17
0, 1, 0, // 18
0, 1, 0, // 19
// bottom
0, -1, 0, // 20
0, -1, 0, // 21
0, -1, 0, // 22
0, -1, 0 // 23
]), 3));
bg.setIndex(new THREE.BufferAttribute(new Uint32Array([
// front 0
0, 1, 2,
3, 2, 1,
// right 6
4, 5, 6,
7, 6, 5,
// back 12
8, 9, 10,
11, 10, 9,
// left 18
12, 13, 14,
15, 14, 13,
// top 24
16, 17, 18,
19, 18, 17,
// bottom 30
20, 21, 22,
23, 22, 21
]), 1));
bg.clearGroups();
// start, count, material index
bg.addGroup(0, 6, 0);
bg.addGroup(6, 6, 1);
bg.addGroup(12, 6, 2);
bg.addGroup(18, 6, 3);
bg.addGroup(24, 6, 4);
bg.addGroup(30, 6, 5);
var materials = [
new THREE.MeshLambertMaterial({color:"red"}),
new THREE.MeshLambertMaterial({color:"green"}),
new THREE.MeshLambertMaterial({color:"blue"}),
new THREE.MeshLambertMaterial({color:"cyan"}),
new THREE.MeshLambertMaterial({color:"magenta"}),
new THREE.MeshLambertMaterial({color:"yellow"})
];
mesh = new THREE.Mesh(bg, materials);
mesh.scale.set(5, 5, 5);
scene.add(mesh);
}
function init() {
document.body.style.backgroundColor = "slateGray";
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
document.body.appendChild(renderer.domElement);
document.body.style.overflow = "hidden";
document.body.style.margin = "0";
document.body.style.padding = "0";
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR);
camera.position.z = 50;
scene.add(camera);
controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.dynamicDampingFactor = 0.5;
controls.rotateSpeed = 3;
var light = new THREE.PointLight(0xffffff, 1, Infinity);
camera.add(light);
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0';
document.body.appendChild(stats.domElement);
resize();
window.onresize = resize;
populateScene();
animate();
}
function resize() {
WIDTH = window.innerWidth;
HEIGHT = window.innerHeight;
if (renderer && camera && controls) {
renderer.setSize(WIDTH, HEIGHT);
camera.aspect = WIDTH / HEIGHT;
camera.updateProjectionMatrix();
controls.handleResize();
}
}
function render() {
renderer.render(scene, camera);
}
function animate() {
mesh.rotation.x += 0.015;
mesh.rotation.y += 0.017;
mesh.rotation.z += 0.019;
requestAnimationFrame(animate);
render();
controls.update();
stats.update();
}
function threeReady() {
init();
}
(function() {
function addScript(url, callback) {
callback = callback || function() {};
var script = document.createElement("script");
script.addEventListener("load", callback);
script.setAttribute("src", url);
document.head.appendChild(script);
}
addScript("https://threejs.org/build/three.js", function() {
addScript("https://threejs.org/examples/js/controls/TrackballControls.js", function() {
addScript("https://threejs.org/examples/js/libs/stats.min.js", function() {
threeReady();
})
})
})
})();
Edit: Adding a second example using the base BoxBufferGeometry
Based on pailhead's comment to the original post, here's a snippet which uses unmodified BoxBufferGeometry
. But as they mentioned in their comment, you'll still need to know which group corresponds to which face.
var renderer, scene, camera, controls, stats, mesh;
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight,
FOV = 35,
NEAR = 1,
FAR = 1000;
function populateScene() {
var bg = new THREE.BoxBufferGeometry(1, 1, 1);
var materials = [
new THREE.MeshLambertMaterial({color:"red"}),
new THREE.MeshLambertMaterial({color:"green"}),
new THREE.MeshLambertMaterial({color:"blue"}),
new THREE.MeshLambertMaterial({color:"cyan"}),
new THREE.MeshLambertMaterial({color:"magenta"}),
new THREE.MeshLambertMaterial({color:"yellow"})
];
mesh = new THREE.Mesh(bg, materials);
mesh.scale.set(10, 10, 10);
scene.add(mesh);
}
function init() {
document.body.style.backgroundColor = "slateGray";
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
document.body.appendChild(renderer.domElement);
document.body.style.overflow = "hidden";
document.body.style.margin = "0";
document.body.style.padding = "0";
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR);
camera.position.z = 50;
scene.add(camera);
controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.dynamicDampingFactor = 0.5;
controls.rotateSpeed = 3;
var light = new THREE.PointLight(0xffffff, 1, Infinity);
camera.add(light);
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0';
document.body.appendChild(stats.domElement);
resize();
window.onresize = resize;
populateScene();
animate();
}
function resize() {
WIDTH = window.innerWidth;
HEIGHT = window.innerHeight;
if (renderer && camera && controls) {
renderer.setSize(WIDTH, HEIGHT);
camera.aspect = WIDTH / HEIGHT;
camera.updateProjectionMatrix();
controls.handleResize();
}
}
function render() {
renderer.render(scene, camera);
}
function animate() {
mesh.rotation.x += 0.015;
mesh.rotation.y += 0.017;
mesh.rotation.z += 0.019;
requestAnimationFrame(animate);
render();
controls.update();
stats.update();
}
function threeReady() {
init();
}
(function() {
function addScript(url, callback) {
callback = callback || function() {};
var script = document.createElement("script");
script.addEventListener("load", callback);
script.setAttribute("src", url);
document.head.appendChild(script);
}
addScript("https://threejs.org/build/three.js", function() {
addScript("https://threejs.org/examples/js/controls/TrackballControls.js", function() {
addScript("https://threejs.org/examples/js/libs/stats.min.js", function() {
threeReady();
})
})
})
})();
这篇关于绘制整个立方体的面,而不是构成面的三角形 -three.js的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!