如何给我的立方体三个3D效果?

时间:2020-01-13 08:23:36

标签: three.js

如何将类似于此图像的3D灯光效果添加到下面的立方体中? enter image description here

如果我将BasicMaterial替换为MeshPhongMaterial或其他材料,则会得到一个黑色立方体。

var camera = null;
var scene = null;
var renderer = null;
var cube = null;
var angle = null;

init();
renderer.render(scene, camera);

function init() {

	camera = new THREE.PerspectiveCamera(1, 1);
	camera.position.z = 200;
    camera.position.set(50, -300, 100);
    camera.lookAt(0, 0, 0);

	// Make a scene
	scene = new THREE.Scene();

	clock = new THREE.Clock();

	//
	renderer = new THREE.WebGLRenderer({
		antialias: true,
		alpha: true
	});
	let container = document.getElementById('container');
	renderer.setSize(container.offsetWidth, container.offsetHeight);
	container.appendChild(renderer.domElement);

	let cube2 = createCube();
	cube2.name = "cube2";
	//       cube2.position = new THREE.Vector3(1, 0)
	scene.add(cube2);

}

function createCube() {

	// GEOMETRY

	// 1. Start with empty geometry
	let geometry = new THREE.Geometry();

	// 2. Add vertices to geometry
	geometry.vertices.push(
		// verts [0-3] are in in +z
		new THREE.Vector3(-1, 1, 1),
		new THREE.Vector3(-1, -1, 1),
		new THREE.Vector3(1, -1, 1),
		new THREE.Vector3(1, 1, 1),
		// verts [4-7] in -z
		new THREE.Vector3(-1, 1, -1),
		new THREE.Vector3(-1, -1, -1),
		new THREE.Vector3(1, -1, -1),
		new THREE.Vector3(1, 1, -1),
	);

	// 3. Connect vertices in desired order to make faces
	let b = 0x1db0ec;
	let y = 0xffef3a;
	let r = 0xea353d;
	let w = 0x00ff00;

	// Set half faces
	geometry.faces.push(new THREE.Face3(0, 1, 2)); // blue
	geometry.faces.push(new THREE.Face3(0, 2, 3)); // yellow
	geometry.faces.push(new THREE.Face3(5, 4, 6)); // white
	geometry.faces.push(new THREE.Face3(6, 4, 7)); // red

	// Set whole faces
	geometry.faces.push(new THREE.Face3(1, 0, 5)); // blue
	geometry.faces.push(new THREE.Face3(5, 0, 4));
	geometry.faces.push(new THREE.Face3(1, 5, 2)); // white
	geometry.faces.push(new THREE.Face3(5, 6, 2));
	geometry.faces.push(new THREE.Face3(2, 6, 3)); // red
	geometry.faces.push(new THREE.Face3(3, 6, 7));
	geometry.faces.push(new THREE.Face3(0, 3, 4)); // yellow
	geometry.faces.push(new THREE.Face3(3, 7, 4));

	// Set faces colors
	geometry.faces[0].color.setHex(b); // Half face
	geometry.faces[1].color.setHex(y);
	geometry.faces[2].color.setHex(w);
	geometry.faces[3].color.setHex(r);
	geometry.faces[4].color.setHex(b); // Whole face
	geometry.faces[5].color.setHex(b);
	geometry.faces[6].color.setHex(w);
	geometry.faces[7].color.setHex(w);
	geometry.faces[8].color.setHex(r);
	geometry.faces[9].color.setHex(r);
	geometry.faces[10].color.setHex(y);
	geometry.faces[11].color.setHex(y);

	// MATERIAL

	// Make a material
	let material = new THREE.MeshBasicMaterial({
		// color: 0x00FF00,
		vertexColors: THREE.FaceColors,
		wireframe: false,
	});

	// MESH

	let cube = new THREE.Mesh(geometry, material);
	return cube;
}
#container {
      width: 20em;
      height: 20em;
    }
<script src="https://threejs.org/build/three.min.js"></script>

        <div id="container"></div>

1 个答案:

答案 0 :(得分:2)

您必须在场景中添加光源。 MeshPhongMaterial使用基于非物理的Blinn-Phong模型来计算反射率。
如果没有光源,则不会反射任何光线,并且该对象将显示为全黑。

例如AmbientLightDirectionalLight

let ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);

let directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(1,1,1);
scene.add(directionalLight);

此外,还需要计算光法向矢量的反射。
例如使用.computeFaceNormals()计算人脸的法线向量:

let material = new THREE.MeshPhongMaterial({
    vertexColors: THREE.FaceColors,
    wireframe: false});

geometry.computeFaceNormals();
let cube = new THREE.Mesh(geometry, material);

查看示例:

var camera = null;
var scene = null;
var renderer = null;
var cube = null;
var angle = null;

init();
renderer.render(scene, camera);

function init() {

  camera = new THREE.PerspectiveCamera(1, 1);
  camera.position.z = 200;
  camera.position.set(50, -300, 100);
  camera.lookAt(0, 0, 0);

  // Make a scene
  scene = new THREE.Scene();

  let ambientLight = new THREE.AmbientLight(0x404040);
  scene.add(ambientLight);

  let directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
  directionalLight.position.set(2,-3,1);
  scene.add(directionalLight);

  clock = new THREE.Clock();

  //
  renderer = new THREE.WebGLRenderer({
  antialias: true,
  alpha: true
  });
  let container = document.getElementById('container');
  renderer.setSize(container.offsetWidth, container.offsetHeight);
  container.appendChild(renderer.domElement);

  let cube2 = createCube();
  cube2.name = "cube2";
  //       cube2.position = new THREE.Vector3(1, 0)
  scene.add(cube2);
}

function createCube() {

  // GEOMETRY

  // 1. Start with empty geometry
  let geometry = new THREE.Geometry();

  // 2. Add vertices to geometry
  geometry.vertices.push(
  // verts [0-3] are in in +z
  new THREE.Vector3(-1, 1, 1),
  new THREE.Vector3(-1, -1, 1),
  new THREE.Vector3(1, -1, 1),
  new THREE.Vector3(1, 1, 1),
  // verts [4-7] in -z
  new THREE.Vector3(-1, 1, -1),
  new THREE.Vector3(-1, -1, -1),
  new THREE.Vector3(1, -1, -1),
  new THREE.Vector3(1, 1, -1),
  );

  // 3. Connect vertices in desired order to make faces
  let b = 0x1db0ec;
  let y = 0xffef3a;
  let r = 0xea353d;
  let w = 0x00ff00;

  // Set half faces
  geometry.faces.push(new THREE.Face3(0, 1, 2)); // blue
  geometry.faces.push(new THREE.Face3(0, 2, 3)); // yellow
  geometry.faces.push(new THREE.Face3(5, 4, 6)); // white
  geometry.faces.push(new THREE.Face3(6, 4, 7)); // red

  // Set whole faces
  geometry.faces.push(new THREE.Face3(1, 0, 5)); // blue
  geometry.faces.push(new THREE.Face3(5, 0, 4));
  geometry.faces.push(new THREE.Face3(1, 5, 2)); // white
  geometry.faces.push(new THREE.Face3(5, 6, 2));
  geometry.faces.push(new THREE.Face3(2, 6, 3)); // red
  geometry.faces.push(new THREE.Face3(3, 6, 7));
  geometry.faces.push(new THREE.Face3(0, 3, 4)); // yellow
  geometry.faces.push(new THREE.Face3(3, 7, 4));

  // Set faces colors
  geometry.faces[0].color.setHex(b); // Half face
  geometry.faces[1].color.setHex(y);
  geometry.faces[2].color.setHex(w);
  geometry.faces[3].color.setHex(r);
  geometry.faces[4].color.setHex(b); // Whole face
  geometry.faces[5].color.setHex(b);
  geometry.faces[6].color.setHex(w);
  geometry.faces[7].color.setHex(w);
  geometry.faces[8].color.setHex(r);
  geometry.faces[9].color.setHex(r);
  geometry.faces[10].color.setHex(y);
  geometry.faces[11].color.setHex(y);

  // MATERIAL

  // Make a material
  let material = new THREE.MeshPhongMaterial({
    vertexColors: THREE.FaceColors,
    wireframe: false});

  // MESH

  geometry.computeFaceNormals()
  let cube = new THREE.Mesh(geometry, material);
  return cube;
}
#container {width: 20em; height: 20em;}
<!--script src="https://threejs.org/build/three.min.js"></script-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
<div id="container"></div>