I am struggling to capture the camera video as the background of a threejs scene. The code provided below is not displaying the background mesh properly and I can't figure out why.
My reference for replacing the image with the camera video was the link mentioned below:
(function () {
var video, videoImage, videoImageContext, videoTexture;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
window.URL = window.URL || window.webkitURL;
var camvideo = document.getElementById('monitor');
if (!navigator.getUserMedia)
{
document.getElementById('errorMessage').innerHTML =
'Sorry. <code>navigator.getUserMedia()</code> is not available.';
} else {
navigator.getUserMedia({video: true}, gotStream, noStream);
}
function gotStream(stream)
{
if (window.URL)
{
camvideo.src = window.URL.createObjectURL(stream);
} else // Opera
{
camvideo.src = stream;
}
camvideo.onerror = function (e)
{
stream.stop();
};
stream.onended = noStream;
}
function noStream(e)
{
var msg = 'No camera available.';
if (e.code == 1)
{
msg = 'User denied access to use camera.';
}
document.getElementById('errorMessage').textContent = msg;
}
var color = 0x000000;
// Create your main scene
var scene = new THREE.Scene();
// Create your main camera
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// Create lights
var light = new THREE.PointLight(0xEEEEEE);
light.position.set(20, 0, 20);
scene.add(light);
var lightAmb = new THREE.AmbientLight(0x777777);
scene.add(lightAmb);
// Create your renderer
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
renderer.domElement.className = "mainCanvas"
// Create a cube
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshLambertMaterial({
color: 0xff00ff,
ambient: 0x121212,
emissive: 0x121212
});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// Set up the main camera
camera.position.z = 5;
///////////
// VIDEO //
///////////
video = document.getElementById('monitor');
videoImage = document.getElementById('videoImage');
videoImageContext = videoImage.getContext('2d');
videoImageContext.translate(320, 0);
videoImageContext.scale(-1, 1);
// background color if no video present
videoImageContext.fillStyle = '#000000';
videoImageContext.fillRect(0, 0, videoImage.width, videoImage.height);
videoTexture = new THREE.Texture(videoImage);
videoTexture.minFilter = THREE.LinearFilter;
videoTexture.magFilter = THREE.LinearFilter;
var movieMaterial = new THREE.MeshBasicMaterial({map: videoTexture, overdraw: true, side: THREE.DoubleSide});
// the geometry on which the movie will be displayed;
// movie image will be scaled to fit these dimensions.
var movieGeometry = new THREE.PlaneGeometry(100, 100, 1, 1);
var movieScreen = new THREE.Mesh(movieGeometry, movieMaterial);
movieScreen.position.set(0, 50, 0);
/* scene.add(movieScreen);
camera.position.set(0, 150, 300);
camera.lookAt(movieScreen.position);
*/
// Load the background texture
/* var texture = THREE.ImageUtils.loadTexture('images/checkerboard.jpg');
var backgroundMesh = new THREE.Mesh(
new THREE.PlaneGeometry(2, 2, 0, 0),
new THREE.MeshBasicMaterial({
map: videoTexture
})
);*/
var backgroundMesh = movieScreen;
backgroundMesh.material.depthTest = false;
backgroundMesh.material.depthWrite = false;
// Create your background scene
var backgroundScene = new THREE.Scene();
var backgroundCamera = new THREE.Camera();
backgroundScene.add(backgroundCamera);
backgroundScene.add(backgroundMesh);
// Rendering function
var render = function () {
requestAnimationFrame(render);
// Update the color to set
if (color < 0xdddddd)
color += 0x0000ff;
// Update the cube color
cube.material.color.setHex(color);
// Update the cube rotations
cube.rotation.x += 0.05;
cube.rotation.y += 0.02;
renderer.autoClear = false;
renderer.clear();
renderer.render(backgroundScene, backgroundCamera);
renderer.render(scene, camera);
};
render();
})();