【问题标题】:Add video player to a GLB model with controls使用控件将视频播放器添加到 GLB 模型
【发布时间】:2021-06-11 18:47:56
【问题描述】:

我正在尝试使用 Three.JS 在 GLB 模型网格中添加视频播放器。虽然这可以使用 VideoTexture 完成,但我正在尝试添加视频播放器默认拥有的所有控件。

这是使用 VideoTexture 的代码 sn-p:

let video = document.createElement( 'video' );
video.loop = true;
video.crossOrigin = 'anonymous';
video.muted = "muted";
video.load(); 
video.src = videoD;
video.controls = true

let texture = new THREE.VideoTexture( video );
texture.minFilter = THREE.NearestFilter;
texture.magFilter = THREE.LinearFilter;
texture.format = THREE.RGBFormat;
let material   = new THREE.MeshBasicMaterial( { map : texture } );

// and then use this material as the material for the glb child mesh

上述方法的问题是我无法添加控件。我目前正在使用反应,所以另一种方式 是使用 HTML 组件并尝试加载它来代替网格,这是使用 react refs 的方法


<>
  <primitive ref={stall_ref} object={glb.scene} />
    <Html>
      <ReactPlayer ref={react_player_ref} id="widget2" url='https://www.youtube.com/watch?v=ysz5S6PUM-U' />
    </Html>
</>

然后使用这个 ref 修改视频播放器位置

// I'm actually not sure what I'm doing here

react_player_ref.current.position.copy(meshChild.position)
react_player_ref.current.quaternion.copy(meshChild.quaternion)
react_player_ref.current.matrix.copy(meshChild.matrix)
react_player_ref.current.matrixWorld.copy(meshChild.matrixWorld)
react_player_ref.current.scale.copy(meshChild.scale)
react_player_ref.current.rotation.set(meshChild.rotation)

【问题讨论】:

    标签: reactjs three.js react-three-fiber


    【解决方案1】:

    我认为你最好的选择可能是用一堆平面自己构建一个 UI,并使用 raycastinglibraries such as this 来注册点击。

    由于您的threeJS 视频纹理使用视频dom 元素,它应该可以使用JavaScript 轻松控制。

    const DemoScene = () => {
      const ref = useRef()
    
      useEffect(() => {
        // ...
    
        // setup UI planes
        const geometry = new THREE.PlaneGeometry(5, 20, 32)
        const material = new THREE.MeshBasicMaterial({
          color: 0xffff00,
          side: THREE.DoubleSide
        })
        const playUIPlane = new THREE.Mesh(geometry, material)
        scene.add(playUIPlane)
    
        // ...
    
        // setup raycasting, see documentation…
        const raycaster = new THREE.Raycaster()
        raycaster.setFromCamera(pointer, camera)
        const intersects = raycaster.intersectObjects(scene.children)
    
        // ...
    
        // check if/which UI has been intersected
        const video = ref.current
        const { object } = intersects[0]
    
        if (object === playUIPlane) video.play()
        if (object === pauseUIPlane) video.pause()
        if (object === incVolumeUIPlane) video.volume += 0.2
    
        // ...
      }, [ref])
    
      return (
        <>
          <video ref={ref} width="320" height="240" controls loop>
            <source src="movie.mp4" type="video/mp4" />
            Your browser does not support the video tag.
          </video>
          <canvas />
        </>
      )
    }
    

    【讨论】:

    • 嘿,谢谢!,虽然我想这不能解决将视频播放器准确定位在网格位置的问题,但您的回答基本上只会帮助视频控制,比如说飞机是根据那架飞机上的事件制造然后控制的,对吗?
    • 您可以group 多个几何体(glb 模型和平面)并同时对所有几何体应用变换。
    • 也可以在 3D 建模程序中导出 glb 之前添加平面,然后在 loader.load() 函数中访问单独的网格:const mesh = gltf.scene.children[ 3 ];
    • 嘿,抱歉,您能举个例子来支持一下吗?视频播放器既不是网格也不是模型,它是一个 HTML 元素,您将如何对 html 元素应用转换以使其与网格完全对齐
    • 查看video texture。它使用 html 视频元素。您可以将视频纹理添加到基本材质,即const texture = new THREE.VideoTexture(videoElem),然后是const material = new THREE.MeshBasicMaterial({ map: texture })。将此材料提供给任何网格(例如平面几何),您将在 3D 空间like so 中播放视频。但是,这不附带视频控件。有关如何向场景添加控件的可能解决方案,请参阅我的原始帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    • 2019-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多