canvas
materials / video / webcam
What this shows
Click the canvas to stream the webcam onto 128 planes arranged on a sphere around the camera, then drag to look around.
Side by side with the three.js r186 original: webgl_materials_video_webcam.html
Differences from three.js
- Both sides request the camera on the first click on their own canvas instead of at page load, so the side-by-side page never prompts on its own; each side opens its own stream.
- EASEL caches each video frame at 128x128 and samples it nearest-neighbor with affine warping, so the webcam image is much blockier than the filtered three.js texture.
- EASEL re-reads the video only when texture.update() runs, so the port calls it once per frame, where three.js refreshes the VideoTexture on its own.
- Before a stream arrives, three.js samples an empty texture and draws the planes black on the black background, while EASEL draws them in the material's white base colour until the first video frame is cached.
Loading scene…Key API excerpt
Key API excerpt
import * as EASEL from "@xsyetopz/easel";
const texture = new EASEL.VideoTexture(video);
texture.colorSpace = EASEL.SRGBColorSpace;
const geometry = new EASEL.PlaneGeometry(16, 9);
geometry.scale(0.5, 0.5, 0.5);
const material = new EASEL.BasicMaterial({ map: texture, vertexColors: false });
for (let i = 1; i <= 128; i++) {
const phi = Math.acos(-1 + (2 * i) / 128);
const theta = Math.sqrt(128 * Math.PI) * phi;
const mesh = new EASEL.Mesh(geometry, material);
mesh.position.setFromSphericalCoords(32, phi, theta);
mesh.lookAt(camera.position);
scene.add(mesh);
}
canvas.addEventListener("click", async () => {
video.srcObject = await navigator.mediaDevices.getUserMedia({ video: true });
video.play();
});
texture.update();
renderer.prepare(scene, camera);
renderer.render(scene, camera);