three.js网络摄像头作为背景

时间:2017-01-24 13:18:27

标签: 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();


})();

2 个答案:

答案 0 :(得分:0)

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

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>

答案 1 :(得分:0)

在视频播放时似乎没有任何实际绘制到纹理的代码。您可能需要添加类似

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

到你的renderloop。

相关问题