vid3d-projection
v0.2.3
Published
Spatial video projection utility for Three.js and Cesium
Maintainers
Readme
vid3d-projection
vid3d-projection 是一个面向 Three.js 和 Cesium.js 的三维视频投影工具库,支持把视频内容投射融合到 3D 模型或地理场景中。
在线演示
点击图片查看在线示例:
Three.js 视频融合
Cesium.js 视频融合
Three.js 电影院
本地运行示例
git clone https://github.com/hh-hang/vid3d-projection.git
cd vid3d-projection
npm install
npm run dev浏览器打开:http://localhost:5173
安装
npm install vid3d-projection导入方式
推荐按子路径导入:
import { createThreeVideoProjector } from "vid3d-projection/three";
import { createCesiumVideoProjector } from "vid3d-projection/cesium";也可以从根入口导入:
import {
createThreeVideoProjector,
createCesiumVideoProjector,
} from "vid3d-projection";快速开始
Three.js
import * as THREE from "three";
import { createThreeVideoProjector } from "vid3d-projection/three";
// 准备视频源
const video = document.createElement("video");
video.src = "/video/monitorTest.mp4";
video.loop = true;
video.muted = true;
video.playsInline = true;
await video.play();
// 由 video 生成可用于着色器采样的纹理
const videoTexture = new THREE.VideoTexture(video);
// 创建投影器(核心参数:相机位置、视锥参数、朝向)
const projector = await createThreeVideoProjector({
scene, // Three 场景
renderer, // Three 渲染器
videoTexture, // 投影视频纹理
projCamPosition: [2, 2, 2], // 投影相机位置 [x, y, z]
projCamParams: { fov: 30, aspect: 1, near: 0.1, far: 50 }, // 投影视锥参数
orientationParams: { azimuthDeg: 180, elevationDeg: -10, rollDeg: 0 }, // 方位/俯仰/横滚(度)
intensity: 1.0, // 投影强度(对应 uniforms.intensity)
opacity: 1.0, // 全局透明度(0~1)
projBias: 0.0001, // 深度偏移,减轻自遮挡/闪烁
edgeFeather: 0.05, // 投影边缘羽化
cropRect: [0, 0, 1, 1], // 裁剪区域 [x0, y0, x1, y1]
quadCorners: [
[0, 0],
[1, 0],
[1, 1],
[0, 1],
], // 四角透视校正(顺序:左下、右下、右上、左上)
isShowHelper: true, // 显示投影相机辅助线
});
// 添加需要被投影的目标 mesh
projector.addTargetMesh(meshA);
projector.addTargetMesh(meshB);
// 渲染循环中调用 update
renderer.setAnimationLoop(() => {
projector.update();
renderer.render(scene, camera);
});
// 释放资源(卸载页面或销毁场景时)
projector.dispose();Cesium.js
import * as Cesium from "cesium";
import { createCesiumVideoProjector } from "vid3d-projection/cesium";
// 初始化 Cesium Viewer
const viewer = new Cesium.Viewer("cesiumContainer");
// 准备视频源
const video = document.createElement("video");
video.src = "/video/monitorTest2.mp4";
video.loop = true;
video.muted = true;
video.playsInline = true;
await video.play();
// 创建投影器
const projector = createCesiumVideoProjector(viewer, {
projCamPosition: [116.3974, 39.9093, 100], // [经度, 纬度, 高度]
projCamParams: { fov: 36, aspect: 1, near: 0.1, far: 120 }, // 投影视锥参数
orientationParams: { azimuthDeg: 47, elevationDeg: -22.6, rollDeg: 0 }, // 方位/俯仰/横滚(度)
source: video, // 投影源
intensity: 1, // 投影强度
opacity: 1, // 投影透明度
projBias: 0.0001, // 深度偏移
edgeFeather: 0.05, // 边缘羽化
cropRect: [0, 0, 1, 1], // 裁剪区域
quadCorners: [
[0, 0],
[1, 0],
[1, 1],
[0, 1],
], // 四角透视校正
isShowHelper: false, // 是否显示视锥辅助线
});
// 释放资源
projector.destroy();说明:
createCesiumVideoProjector(viewer, opts)会把投影器作为 primitive 加入viewer.scene.primitives。- 不需要手动调用
projector.update(),Cesium 渲染流程会自动调用。
API
Three API
createThreeVideoProjector(opts: ThreeProjectorToolOptions): Promise<ThreeProjectorTool>
ThreeProjectorToolOptions 参数表:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| scene | THREE.Scene | 是 | - | Three 场景实例。 |
| renderer | THREE.WebGLRenderer | 是 | - | Three 渲染器实例。 |
| videoTexture | THREE.VideoTexture | 是 | - | 投影的视频纹理。 |
| projCamPosition | [number, number, number] | 否 | [0, 0, 0] | 投影相机位置 [x, y, z]。 |
| projCamParams.fov | number | 否 | 30 | 投影相机 FOV(度)。 |
| projCamParams.aspect | number | 否 | 1 | 投影相机宽高比。 |
| projCamParams.near | number | 否 | 0.1 | 投影相机近裁剪面。 |
| projCamParams.far | number | 否 | 50 | 投影相机远裁剪面。 |
| orientationParams.azimuthDeg | number | 否 | 0 | 方位角(度)。 |
| orientationParams.elevationDeg | number | 否 | 0 | 俯仰角(度)。 |
| orientationParams.rollDeg | number | 否 | 0 | 横滚角(度)。 |
| depthSize | number | 否 | 1024 | 深度贴图分辨率(宽高相同)。 |
| intensity | number | 否 | 1 | 初始投影强度(对应 uniforms.intensity)。 |
| opacity | number | 否 | 1 | 初始透明度,内部会限制到 0~1。 |
| projBias | number | 否 | 0.0001 | 深度偏移,减少投影穿插/闪烁。 |
| edgeFeather | number | 否 | 0.05 | 边缘羽化强度。 |
| cropRect | [number, number, number, number] | 否 | [0, 0, 1, 1] | UV 裁剪 [x0, y0, x1, y1]。 |
| quadCorners | [[number, number], [number, number], [number, number], [number, number]] | 否 | [[0,0],[1,0],[1,1],[0,1]] | 四角透视校正,顺序:左下、右下、右上、左上。 |
| isShowHelper | boolean | 否 | true | 是否显示 CameraHelper。 |
ThreeProjectorTool 方法表:
| 方法 | 签名 | 说明 |
| --- | --- | --- |
| addTargetMesh | (mesh: THREE.Mesh) => void | 把目标网格加入投影列表,并创建 overlay/depth 代理。 |
| removeTargetMesh | (mesh: THREE.Mesh) => void | 从投影列表移除目标网格及其内部代理对象。 |
| update | () => void | 更新深度贴图、投影矩阵和 overlay 变换;建议在渲染循环中调用。 |
| dispose | () => void | 清理内部资源(材质、RT、辅助对象等)。 |
ThreeProjectorTool 属性表:
| 属性 | 类型 | 可写 | 说明 |
| --- | --- | --- | --- |
| azimuthDeg | number | 是 | 方位角(度),写入后立即更新投影方向。 |
| elevationDeg | number | 是 | 俯仰角(度)。 |
| rollDeg | number | 是 | 横滚角(度)。 |
| opacity | number | 是 | 透明度,范围会被限制为 0~1。 |
| cropRect | [number, number, number, number] | 是 | UV 裁剪区域。 |
| quadCorners | [[number, number], [number, number], [number, number], [number, number]] | 是(Setter) | 四角透视校正写入入口。 |
| uniforms | any | 否 | 着色器 uniforms(如 intensity/projBias/edgeFeather)。 |
| overlays | THREE.Mesh[] | 否 | 内部投影 overlay 列表。 |
| targetMeshes | THREE.Mesh[] | 否 | 当前目标 mesh 列表。 |
| projCam | THREE.PerspectiveCamera | 否 | 投影相机实例。 |
| camHelper | THREE.CameraHelper \| null | 否 | 相机辅助线实例。 |
| orientationParams | { azimuthDeg: number; elevationDeg: number; rollDeg: number } | 否 | 当前朝向参数快照。 |
Cesium API
createCesiumVideoProjector(viewer: Cesium.Viewer, opts: CesiumProjectorOptions): CesiumProjectorTool
CesiumProjectorOptions 参数表:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| viewer | Cesium.Viewer | 是(函数第 1 参) | - | Cesium Viewer。 |
| projCamPosition | [number, number, number] | 否 | [0, 0, 0] | 投影相机地理坐标 [lon, lat, height]。 |
| projCamParams.fov | number | 否 | 30 | 投影视锥 FOV(度)。 |
| projCamParams.aspect | number | 否 | 1 | 投影视锥宽高比。未传时会回落到视口比例。 |
| projCamParams.near | number | 否 | 0.1 | 近裁剪面。 |
| projCamParams.far | number | 否 | 50 | 远裁剪面,同时用于计算视点距离。 |
| orientationParams.azimuthDeg | number | 否 | 0 | 方位角(度)。 |
| orientationParams.elevationDeg | number | 否 | 0 | 俯仰角(度)。 |
| orientationParams.rollDeg | number | 否 | 0 | 横滚角(度)。 |
| source | HTMLVideoElement \| HTMLImageElement \| HTMLCanvasElement \| ImageData | 否 | - | 投影纹理源,可运行时切换。 |
| intensity | number | 否 | 1 | 投影强度。 |
| opacity | number | 否 | 1 | 投影透明度,内部限制到 0~1。 |
| projBias | number | 否 | 0.0001 | 深度偏移。 |
| edgeFeather | number | 否 | 0.05 | 边缘羽化。 |
| isShowHelper | boolean | 否 | true | 是否显示视锥辅助线。 |
| cropRect | [number, number, number, number] | 否 | [0, 0, 1, 1] | UV 裁剪区域。 |
| quadCorners | [[number, number], [number, number], [number, number], [number, number]] | 否 | [[0,0],[1,0],[1,1],[0,1]] | 四角透视校正,顺序:左下、右下、右上、左上。 |
| videoPlay | boolean | 否 | - | 预留字段(当前核心流程未使用)。 |
| texture | any | 否 | - | 预留字段(当前核心流程未使用)。 |
CesiumProjectorTool 方法表:
| 方法 | 签名 | 说明 |
| --- | --- | --- |
| update | (frameState: any) => void | Cesium primitive 生命周期调用,手动调用通常不需要。 |
| destroy | () => void | 销毁后处理、纹理、阴影图与辅助对象。 |
| isDestroyed | () => boolean | 返回是否已销毁。 |
CesiumProjectorTool 属性表:
| 属性 | 类型 | 可写 | 说明 |
| --- | --- | --- | --- |
| azimuthDeg | number | 是 | 方位角(度),变更后会重建投影资源。 |
| elevationDeg | number | 是 | 俯仰角(度),变更后会重建。 |
| rollDeg | number | 是 | 横滚角(度),变更后会重建。 |
| opacity | number | 是 | 投影透明度。 |
| intensity | number | 是 | 投影强度。 |
| edgeFeather | number | 是 | 边缘羽化强度。 |
| projBias | number | 是 | 深度偏移。 |
| aspect | number | 是 | 宽高比,变更后会重建。 |
| fov | number | 是 | FOV(度),变更后会重建。 |
| isShowHelper | boolean | 是 | 控制视锥辅助线显隐。 |
| cameraPosition | [number, number, number] | 是 | 地理位置 [lon, lat, height],变更后会重建。 |
| far | number | 是 | 远裁剪面,变更后会重建。 |
| near | number | 是 | 近裁剪面,变更后会重建。 |
| cropRect | [number, number, number, number] | 是 | UV 裁剪区域。 |
| quadCorners | [[number, number], [number, number], [number, number], [number, number]] | 是(Setter) | 四角透视校正写入入口。 |
| source | TextureSource | 是(Setter) | 投影源切换入口(video/image/canvas/imageData)。 |



