Background utilizing the webcam in three.js

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();


})();

Answer №1

To achieve a static video background, it is not advisable to transfer the video as a texture into the 3D scene. Instead, consider leaving it in a div positioned behind the canvas element. By setting the canvas to be transparent, only the meshes will be rendered while keeping the background clear.

var renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setClearAlpha(0.0);
.parent {
  position: relative;
  width: 1024px;
  height: 768px;
}
#monitor, #mainCanvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
#monitor {
  transform: scaleX(-1);
}
<div class="parent">
  <div id="monitor"></div>
  <div id="mainCanvas"></div>
</div>

Answer №2

It appears that the code currently lacks any functionality to render onto the texture while the video is being played. To resolve this, consider incorporating:

videoImageContext.drawImage(video, 0, 0);
videoTexture.needsUpdate = true;

within your rendering loop.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Despite the use of v-if and v-else directives in Vue 2, a specific component properties are not being updated while the others are updating

Vue2 is not updating one specific component (<Button>) inside v-if and v-else, while the rest of the content is updated. I have recently discovered a solution to make this code function, but I am still unsure about Vue2 re-rendering behavior. I worr ...

Different techniques for retrieving elements generated by ng-repeat from their containing parent

Let's keep it simple - imagine we have a directive called headSlides. This directive's template includes an image that is being repeated using ng-repeat: <img class="bg" ng-repeat="image in images" ng-src="{{image.src}}"> I need to access ...

Guide to creating and importing a JSON file in Wordpress

I'm looking to save a list in a JSON file within the Wordpress functions.php file. Can you guide me on how to achieve this? function ScheduleDeletion(){ ?> <script type="text/javascript"> var day = (new Date).get ...

Executing a jQuery function automatically & Invoking a jQuery function using the onClick attribute in an HTML element

Having some issues with jQuery and could use some assistance... Currently, I am trying to have a jQuery function automatically execute when the page loads, as well as when a button is clicked. [Previous Issue] Previously, the jQuery function would automa ...

Gallery Pagination using JQuery is not working properly

I am experimenting with the jquery easy paginate plugin on a separate page of my Blogspot. The images are displaying properly, but the pagination and CSS are not showing up. I need to adjust my CSS to make this jQuery pagination work correctly. Can someone ...

Steps to create a dropdown select option using an AJAX call: When the data is fetched, it generates an array

How can I dynamically populate a dropdown with data from an array using jQuery and AJAX? <html> <script> $(document).ready(function() { $("#class_name").change(function(){ var class_id=$("#class_name").val(); ...

List with pulldown options

I am trying to implement a drop-down list with bullets using Angular 2, JavaScript, and CSS. Although I have managed to create the drop-down list, I am facing difficulty in adding bullets to the list items. Unfortunately, I have found that jQuery and Boot ...

Displaying a real-time clock synchronized with the server using Javascript and

I am facing an issue with server time. I want a timer on my website that counts every second, but I need it to be based on the server time rather than the client's time. However, my current script only works with client time: <script> setInter ...

I'm trying to implement a command in my bot that displays the number of Discord members, but I keep encountering an error

I've encountered an issue with the discord.js v13 member count command. Despite seeking help in various Discord servers, I haven't received any assistance. If anyone could offer their expertise, it would be greatly appreciated. const Discord = re ...

Issues with voice state updates in JavaScript

I am currently working on setting up a discord bot to send notifications when someone joins a voice chat. While coding in Atom, I encountered the following error: TypeError: Cannot read property 'send' of undefined at Client.client.on (C:\U ...

What is the best way to add a blob to the document object model (

I am a beginner when it comes to working with blobs, and I am looking for some guidance to avoid wasting hours on unsuccessful brute-force attempts. I have been using the PHP code below (sourced from here) to retrieve the base64-encoded image from my data ...

Changing the color of a face in Three.js

I've been trying to change the color of a face, but I'm having trouble. When I use wireframe, it looks like it's working fine. However, when I don't use it, the face doesn't seem to render properly. var geo = new THREE.Geometry(); ...

A guide on implementing lazy loading for components and templates

I have successfully implemented lazy loading for components and templates individually, but I am struggling to combine the two. Here's an example of how I lazy load a component: // In my main.js file const router = new VueRouter({ routes: [ ...

The contents of the image are currently unable to be viewed

I have a Blob of an image that I am trying to display in the browser. However, when I use the code below to open the image, it shows some Mandarin scripts on the window. Here is the code snippet: var url="http://....link..../downloadFile?fdsFileId="+file ...

Differences between using ng-pattern and scripting for validation

My goal is to validate a date in the format YYYY/MM/DD using a regular expression ng-pattern. When I use the code below in the UI, it works perfectly fine. <input type="text" class="k-fill" ng-pattern="/((^[1]{1}[9]{1}[9]{1}\d{1})|([2-9]{1}\d ...

Is it possible to capture and generate an AxiosPromise inside a function?

I am looking to make a change in a function that currently returns an AxiosPromise. Here is the existing code: example(){ return api.get(url); } The api.get call returns an object of type AxiosPromise<any>. I would like to modify this function so ...

Clone the children of an li element using jQuery, modify the text within a child tag, and then add it to

I have some awesome CSS that I want to recycle within a <ul>. My plan is to duplicate an existing <li> (to leverage the CSS), modify a <p> element, and then add it at the end of the <ul>. I believe I can achieve this by locating... ...

Save the information fetched using the 'fetch' method into a different .js document when working with React

Here is the code I am working on: const fetchData = () => fetch("https://api.myjson.com/bins/mp441") .then(response => response.json()) .then(obj => data = obj); const RECORD_NOS = Object.keys(data).length - 1; export { fetchData, ...

Automatically fill in a custom entity using JavaScript even when the GUID of the parent entity is unknown within Dynamics 365

Recently delving into client-side scripting, I have been tirelessly searching through Google and various communities for answers without success. Allow me to present my issue for a clearer understanding of the predicament. I have established two custom en ...

Error in Angular2: The provided parameters do not match any of the available function signatures

I have implemented logic in the code snippet below to dynamically adjust rows and columns based on my specific business requirements. However, when I include this code in my Angular2 TypeScript file, I encounter an error stating that the supplied paramet ...