Three.js - Picking - RayCaster w/Transparency
With orthographic camera
by navinleon
HTML
<canvas id="c"></canvas>
CSS
body {
margin: 0;
}
#c {
width: 100vw;
height: 100vh;
display: block;
}
JavaScript
// Three.js - Picking - RayCaster w/Transparency
// from https://threejsfundamentals.org/threejs/threejs-picking-gpu.html
import * as THREE from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/build/three.module.js';
function main() {
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});
const camera = new THREE.OrthographicCamera(0, 1, 0, 1, -1, 1);
camera.position.z = 1;
const scene = new THREE.Scene();
scene.background = new THREE.Color('white');
const pickingScene = new THREE.Scene();
pickingScene.background = new THREE.Color(0);
// put the camera on a pole (parent it to an object)
// so we can spin the pole to move the camera around the scene
const cameraPole = new THREE.Object3D();
scene.add(cameraPole);
cameraPole.add(camera);
const geometry = new THREE.PlaneBufferGeometry();
function rand(min, max) {
if (max === undefined) {
max = min;
min = 0;
}
return min + (max - min) * Math.random();
}
function randomColor() {
return `hsl(${rand(360) | 0}, ${rand(50, 100) | 0}%, 50%)`;
}
const loader = new THREE.TextureLoader();
const texture = loader.load('https://threejsfundamentals.org/threejs/resources/images/frame.png');
const idToObject = {};
const numObjects = 100;
for (let i = 0; i < numObjects; ++i) {
const id = i + 1;
const material = new THREE.MeshBasicMaterial({
color: randomColor(),
map: texture,
transparent: true,
side: THREE.DoubleSide,
alphaTest: 0.5,
});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
idToObject[id] = cube;
cube.position.set(rand(-500, 500), rand(-500, 500), 0);
cube.rotation.set(0, 0, rand(Math.PI));
cube.scale.set(rand(32, 64), rand(32, 64), 1);
const pickingMaterial = new THREE.MeshPhongMaterial({
emissive: new THREE.Color(id),
color: new THREE.Color(0, 0, 0),
specular: new...