【问题标题】:Video texture playing but showing black视频纹理播放但显示黑色
【发布时间】:2016-07-28 23:53:45
【问题描述】:

我正在尝试创建视频纹理。我的代码会将视频添加到我的场景中,但是我的立方体只是黑色的。视频在某处,因为我可以听到浏览器中播放的音频。我是three.js的新手,所以我不确定我做错了什么。我有一个相机和三个灯。我可以看到场景中的其他对象并且它们的纹理是可见的。我的代码改编自here。这是我的 HTML 代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <script src="libraries/three.js"></script>
    <script src="libraries/OBJLoader2.js"></script>
    <script src="libraries/OrbitControls.js"></script>
    <script src="libraries/MtlLoader.js"></script>
    <script src="libraries/DDSLoader.js"></script>
</head>

<body>
<script src="libraries/main.js"></script>
</body>
</html>

这是我的 main.js 代码:

//global variables
var renderer;
var scene;
var camera;
var cameraControl;
var loader;
var updateFcts  = [];

function createRenderer() {
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x000000, 1.0);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
}

function createCamera() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth /window.innerHeight, 0.1, 1000);
camera.position.x = 0;
camera.position.y = 100;
camera.position.z = 450;
camera.lookAt(scene.position);
cameraControl = new THREE.OrbitControls(camera);
}

var THREEx = THREEx || {}
THREEx.VideoTexture = function(url){
var video   = document.createElement('video');
video.width = 320;
video.height    = 240;
video.autoplay  = true;
video.loop  = true;
video.src   = url;
this.video  = video;
var texture = new THREE.Texture( video );
this.texture    = texture;
this.update = function(){
    if( video.readyState !== video.HAVE_ENOUGH_DATA )   return;
    texture.needsUpdate = true;     
}
  this.destroy  = function(){
    video.pause()
  }
}

function createVideo() {
var videoTexture= new THREEx.VideoTexture('models/textures/video.mp4')
var video   = videoTexture.video;
updateFcts.push(function(delta, now){
    videoTexture.update(delta, now)
});
var geometry    = new THREE.CubeGeometry(10,50,10);
var material    = new THREE.MeshBasicMaterial({
    map : videoTexture.texture,
    side: THREE.DoubleSide
});
var mesh    = new THREE.Mesh( geometry, material );
scene.add( mesh );
updateFcts.push(function(delta, now){
    mesh.rotation.x += 1 * delta;
    mesh.rotation.y += 2 * delta;       
});
}

function createLight() {
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(10, 40, 20);
spotLight.shadowCameraNear = 20;
spotLight.shadowCameraFar = 50;
spotLight.castShadow = true;
scene.add(spotLight);
var ambient = new THREE.AmbientLight( 0x444444 );
ambient.castShadow = true;
scene.add( ambient );
var directionalLight = new THREE.DirectionalLight( 0xffeedd );
directionalLight.position.set( 0, 0.5, 0.5 ).normalize();
scene.add( directionalLight );
}

function init() {
scene = new THREE.Scene();
createRenderer();
createCamera();
createLight();
createVideo();
document.body.appendChild(renderer.domElement);
render();
}

 function render() {
cameraControl.update();
renderer.render(scene, camera);
requestAnimationFrame(render);
}

init();

【问题讨论】:

    标签: video three.js textures


    【解决方案1】:

    我遇到了类似的问题:将相机源渲染到纹理会导致黑色对象(黑色纹理)。 就我而言,这是由于未设置texture.needsUpdate = true 造成的。 所以我自己的代码是这样的:

    updateTexture = function(videoDomElement){
        var cameraTexture = new THREE.Texture(videoDomElement);
        cameraTexture.needsUpdate = true;
        var material = new THREE.MeshLambertMaterial({map: cameraTexture});
        material.needsUpdate = true;
        existingObject.material = material;
    }
    

    【讨论】:

      【解决方案2】:

      您必须为视频创建一个画布,以便将其用于构建纹理。 您还必须刷新渲染循环中的每一帧。

      var renderer;
      var scene;
      var camera;
      var cameraControl;
      var loader;
      var updateFcts = [];
      var video;
      var videoImageContext;
      var videoTexture;
      
      function createRenderer() {
          renderer = new THREE.WebGLRenderer();
          renderer.setClearColor(0x111111, 1.0);
          renderer.setSize(window.innerWidth, window.innerHeight);
          renderer.shadowMap.enabled = true;
      }
      
      function createCamera() {
          camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
          camera.position.x = 0;
          camera.position.y = 100;
          camera.position.z = 450;
          camera.lookAt(scene.position);
          cameraControl = new THREE.OrbitControls(camera);
      }
      
      var THREEx = THREEx || {}
      THREEx.VideoTexture = function(url) {
          video = document.createElement('video');
      
          video.autoplay = true;
          video.loop = true;
          video.src = url;
          video.load();
          video.play();
      
          videoImage = document.createElement('canvas');
          videoImage.width = 320;
          videoImage.height = 240;
          videoImageContext = videoImage.getContext('2d');
          videoImageContext.fillStyle = '#000000';
          videoImageContext.fillRect(0, 0, videoImage.width, videoImage.height);
      
          this.texture = new THREE.Texture(videoImage);
          this.texture.minFilter = THREE.LinearFilter;
          this.texture.magFilter = THREE.LinearFilter; 
      
          this.destroy = function() {
              video.pause()
          }
      }
      
      function createVideo() {
          videoTexture = new THREEx.VideoTexture('myvideo.mp4')
          updateFcts.push(function(delta, now) {
              videoTexture.update(delta, now)
          });
          var geometry = new THREE.CubeGeometry(10, 50, 10);
          var material = new THREE.MeshBasicMaterial({
              map: videoTexture.texture,
              side: THREE.DoubleSide
          });
          var mesh = new THREE.Mesh(geometry, material);
          scene.add(mesh);
          updateFcts.push(function(delta, now) {
              mesh.rotation.x += 1 * delta;
              mesh.rotation.y += 2 * delta;
          });
      }
      
      function createLight() {
          var spotLight = new THREE.SpotLight(0xffffff);
          spotLight.position.set(10, 40, 20);
          spotLight.shadowCameraNear = 20;
          spotLight.shadowCameraFar = 50;
          spotLight.castShadow = true;
          scene.add(spotLight);
          var ambient = new THREE.AmbientLight(0x444444);
          ambient.castShadow = true;
          scene.add(ambient);
          var directionalLight = new THREE.DirectionalLight(0xffeedd);
          directionalLight.position.set(0, 0.5, 0.5).normalize();
          scene.add(directionalLight);
      }
      
      function init() {
          scene = new THREE.Scene();
          createRenderer();
          createCamera();
          createLight();
          createVideo();
          document.body.appendChild(renderer.domElement);
          render();
      }
      
      function render() {
          cameraControl.update();
          if (video.readyState === video.HAVE_ENOUGH_DATA) {
              videoImageContext.drawImage(video, 0, 0);
              if (videoTexture)
                  videoTexture.texture.needsUpdate = true;
          }
          renderer.render(scene, camera);
          requestAnimationFrame(render);
      }
      
      init();
      

      我已经更改了 THREEx.VideoTexture 函数和渲染循环,并使用 r75 进行了测试,并且可以正常工作!

      【讨论】:

      • 谢谢,我尝试添加画布,但也无法正常工作,但您的代码有帮助!我知道我也必须改变我的渲染功能,所以你帮我解决了这个问题:)
      • 视频不需要画布。这三个.js examples 都没有为视频创建单独的画布
      猜你喜欢
      • 2013-04-21
      • 1970-01-01
      • 2020-11-29
      • 1970-01-01
      • 1970-01-01
      • 2011-01-18
      • 2012-01-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多