0

I would like to do something pretty simple with three.js. I would like to create a cube on a "ground": the cube will emit blue light and I would like to see the reflection on the ground.

I searched and find the meshLambertMaterial in the Three.js documentation, and it includes emissivity and reflectivity properties.

So, I made my code like this:

import * as THREE from '../lib/three.module.js';
// Set up
const scene = new THREE.Scene();

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);

const camera = new THREE.PerspectiveCamera(100, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, -7, 4);
camera.rotation.x = Math.PI / 2;

// Ground
const ground = new THREE.PlaneGeometry(5, 5, 5);
const material = new THREE.MeshLambertMaterial({
  color: 'white',
  reflectivity: 1,
});
const mesh = new THREE.Mesh(ground, material);
scene.add(mesh);

// Modelling
const geometry = new THREE.Geometry();

geometry.vertices.push(
  new THREE.Vector3(0, 0, 0),
  new THREE.Vector3(1, 0, 0),
  new THREE.Vector3(1, 1, 0),
  new THREE.Vector3(0, 1, 0),
  new THREE.Vector3(0, 0, 1),
  new THREE.Vector3(1, 0, 1),
  new THREE.Vector3(1, 1, 1),
  new THREE.Vector3(0, 1, 1),
);

console.log(geometry.vertices);

geometry.faces.push(
  // front
  new THREE.Face3(0, 1, 5),
  new THREE.Face3(0, 5, 4),
  // right
  new THREE.Face3(1, 2, 6),
  new THREE.Face3(1, 6, 5),
  // back
  new THREE.Face3(2, 3, 7),
  new THREE.Face3(2, 7, 6),
  // left
  new THREE.Face3(0, 4, 7),
  new THREE.Face3(0, 7, 3),
  // top
  new THREE.Face3(4, 5, 6),
  new THREE.Face3(4, 6, 7),
  // bottom
  new THREE.Face3(0, 3, 2),
  new THREE.Face3(0, 2, 1),
);

const material2 = new THREE.MeshLambertMaterial({
  emissive: new THREE.Color(0.2, 0.3, 0.3),
  emissiveIntensity: 1,
});
const cube = new THREE.Mesh(geometry, material2);
cube.position.x = -0.5;
cube.position.z = 0;
// Add the cube to the scene
scene.add(cube);
renderer.render(scene, camera);

function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();

The cube emits blue light as planned, but the ground doesn't reflect anything even if it's reflectivity is equal to 1 and he even didn't appear on the screen.

Can someone please help me to understand what can I do for my idea to work? I search in the net but all the "solution" I found was using camera mirror tricks and I don't want that.

Thanks.

Eccsx
  • 185
  • 2
  • 13

1 Answers1

0

The effect you're trying to achieve requires a lot more work. The material's reflectivity attribute only works to reflect environment maps. If you want to reflect dynamic objects that you've added to the scene, you'll have to render how they look in the reflection first, and THEN you can render what the scene looks like from the camera's point of view. The examples section has two approaches you can use:

  • The mirror example requires you use a Reflector object and add it to the scene. Then it takes care of the rendering automatically for you.
  • The dynamic cubemap example uses a CubeCamera to
    1. Render the scene from the mirror's point-of-view.
    2. Apply the render result to the reflective objects.
    3. Render the scene from the camera's point-of-view.

From your description, it looks like you should to use example #1, plus it's simpler to implement. But it's up to you to decide.

M -
  • 26,908
  • 11
  • 49
  • 81