绘制整个立方体的面,而不是构成面的三角形 -three.js [英] Paint cube faces as a whole, not the triangles that make up the face - three.js

查看:9
本文介绍了绘制整个立方体的面,而不是构成面的三角形 -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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆