【问题标题】:Using Video as texture with Three.js在 Three.js 中使用视频作为纹理
【发布时间】:2022-04-11 14:21:15
【问题描述】:

我正在尝试创建一个带有 .mp4 视频作为纹理的简单矩形。根据 three.js 文档(http://threejs.org/docs/#Reference/Textures/Texture),这应该是直截了当的。

当我放置视频链接时,我得到的只是一个没有纹理的黑色盒子。我已经通过用 jpg 图像替换视频来测试代码,它工作正常。有人可以解释一下我做错了什么。

我已经看到了通过首先将视频链接到视频元素然后将帧复制到画布上来播放视频的示例。我想尝试一下three.js文档中提到的直接方式。

【问题讨论】:

    标签: three.js


    【解决方案1】:

    将视频视为一系列图像。因此,要在您的 3D 对象上“播放”该视频 - 您必须将该序列的每一帧传递给您的材质,然后更新该材质。

    这里是开始的好地方:https://github.com/mrdoob/three.js/wiki/Updates

    在这里:http://stemkoski.github.io/Three.js/Video.html

    【讨论】:

    • 是的,我理解并且已经使代码以这种方式工作。但是我想通过传递 mp4 文件链接直接实现视频纹理。虽然我还没有看到任何这样做的例子或能够让它自己工作,但根据这里的文档threejs.org/docs/#Reference/Textures/Texture 应该是可能的。可能是我误解了文档,目前唯一的方法是使用视频标签并根据帧更新纹理。
    • 他们是三个.js 文档中的一个错误,让我认为视频可以直接用作纹理。在 irc 上讨论过,您说的似乎是目前唯一可能的解决方案。
    • 牢记 KISS 规则(保持简单愚蠢),每个人都试图保持他的代码尽可能整洁,所以如果有更方便的解决方案来解决您的问题 - 它会在某些情况下使用已经有例子了。
    【解决方案2】:

    第 1 步: 将视频添加到您的 HTML 并“隐藏”它:

    <video id="video" playsinline webkit-playsinline muted loop autoplay width="320" height="240" src="some-video.mp4" style="display: none;"></video>
    

    第 2 步:

    //Get your video element:
    const video = document.getElementById('video');
    
    //Create your video texture:
    const videoTexture = new THREE.VideoTexture(video);
    const videoMaterial =  new THREE.MeshBasicMaterial( {map: videoTexture, side: THREE.FrontSide, toneMapped: false} );
    //Create screen
    const screen = new THREE.PlaneGeometry(1, 1);
    const videoScreen = new THREE.Mesh(screen, videoMaterial);
    scene.add(videoScreen);
    

    【讨论】:

    • 我试过这种方式,但是videScreen只是黑色
    【解决方案3】:

    除了豪斯的回答,我还需要设置videoTexture.needsUpdate = true;videoMaterial.needsUpdate = true;。我也在onloadeddata上播放了视频。

    //Get your video element:
    const video = document.getElementById("video");
    video.onloadeddata = function () {
        video.play();
    };
    
    //Create your video texture:
    const videoTexture = new THREE.VideoTexture(video);
    videoTexture.needsUpdate = true;
    const videoMaterial = new THREE.MeshBasicMaterial({
        map: videoTexture,
        side: THREE.FrontSide,
        toneMapped: false,
    });
    videoMaterial.needsUpdate = true;
    
    //Create screen
    const screen = new THREE.PlaneGeometry(10, 10);
    const videoScreen = new THREE.Mesh(screen, videoMaterial);
    scene.add(videoScreen);
    

    【讨论】:

      猜你喜欢
      • 2014-05-31
      • 2016-10-19
      • 1970-01-01
      • 1970-01-01
      • 2013-04-18
      • 2019-07-31
      • 1970-01-01
      • 1970-01-01
      • 2011-12-16
      相关资源
      最近更新 更多