Babylonjs VideoTexture纵横比

问题描述 投票:1回答:1

我在BabylonJS中有一个脚本,可以用视频源创建一个背景层。问题是我无法将其锁定为一定的纵横比。

 const background = new BABYLON.Layer("back", null, scene);
 BABYLON.VideoTexture.CreateFromWebCam(scene, function (videoTexture) {
    background.texture = videoTexture;
    background.texture.level = 0;
    background.texture.wAng = Math.PI;
 }, { maxWidth: window.innerWidth, maxHeight: window.innerHeight});

上面的代码正确地将背景设置为网络摄像头馈送,但随着窗口的缩放而缩放。

调用 background.texture.scale(20); 无效,因为 .canRescale 的纹理返回 false.

尝试重新缩放图层也没有用。

这就是 联系 到操场上。

我觉得解决方法一定很简单,但我还没能谷歌到它。谢谢。

javascript video 3d babylonjs
1个回答
1
投票

我一直在寻找一种类似的方法来设置图像背景,并最终使用了一个固定长宽比的平面和一个正交相机。

(代码使用的是react-babylonjs,但同样的属性在普通的babylonjs中也可以使用)

先做正射影机

<targetCamera
   name="camera1"
   position={new Vector3(0, 0, -2)}
   rotation={new Vector3(toRadians(0), toRadians(0), 0)}
   mode={Camera.ORTHOGRAPHIC_CAMERA}
   ref={scenePlaneCameraRef}
 />

然后做一个尺寸=1的平面

// the real size will be stretched with scale, 
// this works because 1 unit on the orthographic camera is the size of 1 pixel
<plane
  ref={planeRef}
  name="backdropPlane"
  size={1}
  billboardMode={AbstractMesh.BILLBOARDMODE_ALL}
/>

这些都是一些函数,以获得平面应该是的大小。

export function defaultSize(engine) {
  return { width: 0, height: 0 };
}

export function getViewSize(engine) {
  if (!engine) return defaultSize();
  return {
    width: engine.getRenderWidth(),
    height: engine.getRenderHeight(),
  };
}

// this gets the wanted plane size so it fills the screen but keeps the aspect ratio
export function getPlaneSize(engine) {
  const viewSize = getViewSize(engine);

  const viewAspectRatio = viewSize.width / viewSize.height;
  const planeAspectRatio = 16 / 9;

  const viewIsThinner = viewAspectRatio < planeAspectRatio;

  if (viewIsThinner) {
    return {
      width: viewSize.height * planeAspectRatio,
      height: viewSize.height,
    };
  } else {
    return {
      width: viewSize.width,
      height: viewSize.width * (1.0 / planeAspectRatio),
    };
  }
}

export default function fitScenePlaneToScreen(planeMesh, engine) {
  const planeSize = getPlaneSize(engine);
  planeMesh.scaling.y = planeSize.height;
  planeMesh.scaling.x = planeSize.width;
}

然后每当屏幕大小改变时,就调整飞机的大小。

fitScenePlaneToScreen(scenePlane, engine);
engine.onResizeObservable.add(() => {
  fitScenePlaneToScreen(scenePlane, engine);
});

然后将该平面的材质纹理设置为视频纹理。

而作为背景的一种方法是两个场景叠加在一起,其中后面的场景使用正射摄像机

© www.soinside.com 2019 - 2024. All rights reserved.