javascript - Three.js 网络摄像头作为背景

标签 javascript three.js

我正在尝试获取 Threejs 场景背景的摄像机视频。下面是代码。目前背景网格是空白的。不确定为什么会发生这种情况。

我按照以下链接将图像替换为相机视频。

http://jeremy.assenat.free.fr/Lab/threejsbg/

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


})();

最佳答案

如果您希望视频在背景中保持静态,我不会将视频作为纹理传输到 3D 场景中。相反,我会将其留在 Canvas 后面的 div 中。 Canvas 可以设置为透明,因此只有网格会被渲染,但背景保持清晰。

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>

关于javascript - Three.js 网络摄像头作为背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41829246/

相关文章:

javascript - Prototype JS 吞下 dom :loaded, 和 ajax 回调中的错误?

javascript - 使用套接字时返回 promise

javascript - Three.js - 全景应用到reactjs中

javascript - 在三个js中突出显示距鼠标指针最近的边缘

javascript - 在React中动态添加输入标签,显示一会儿然后消失

javascript - 'inspectedWindow' 的替代方案(不适用于 chrome devtools)

javascript - CSS 过滤器转换

javascript - Three.js - 在动画期间获取当前骨骼骨骼位置

three.js - 如何旋转对象以查看三个js中的鼠标点?

three.js - bullet/ammo.js 中的刚体(形状)来自 three.js 中的网格