惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
Microsoft Security Blog
Microsoft Security Blog
Recent Announcements
Recent Announcements
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Last Week in AI
Last Week in AI
罗磊的独立博客
腾讯CDC
云风的 BLOG
云风的 BLOG
月光博客
月光博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
宝玉的分享
宝玉的分享
U
Unit 42
I
InfoQ
D
DataBreaches.Net
Blog — PlanetScale
Blog — PlanetScale
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
V
V2EX
美团技术团队
IT之家
IT之家
Stack Overflow Blog
Stack Overflow Blog
F
Fortinet All Blogs
GbyAI
GbyAI
S
SegmentFault 最新的问题

博客园 - ITman彪叔

赋能UE运行态编辑平台: 网络图片下载的插件改造与复盘 召回率暴涨!“层级化分片”与“降噪”拯救 RAG 系统 基于FastMCP打通业务系统与AI:构建智能协作新范式 在 Dify 中通过 MCP 集成本地 FastMCP 服务避坑指南 从分形到森林——使用 Three.js 创建逼真的 3D 树木 UE5 小部件 组合框(键)ComboBox (Key) Tesseract OCR 页面分割模式解析 Java MQTT 主流开发方案对比 Java Modbus主流开发方案对比 Java OPC UA 开发方案全对比:开源、商业、集成与官方标准 Nodejs打包 Webpack 中 __dirname 的正确配置与行为解析 强制 pnpm 使用 IPv4 而不是 IPv6 的终极解决方案指南 uniapp 微信小程序 调试 UE Websocket 通信 UE Geometry_Script 程序化建模 UE MultiLineTraceByChannel函数返回只有一个对象的问题 UE Spline 样条网格体组件添加碰撞 Three光源Target位置改变光照方向不变的问题及解决方法 UE5 射线检测排除隐藏的Actor UE5打包SDK未正确安装的问题 判断两个矩形是否相交(Rect Intersection) 电力布局三维编辑器功能设计 UE4 WebUI使用指南2-通信
Threejs 视频融合
ITman彪叔 · 2026-04-05 · via 博客园 - ITman彪叔

楔子

这个是一个公众号读者加了微信咨询,其实这种视频融合技术很多年前就做过。

比如做cesium的,也有很多文章介绍视频融合。 不过我看大部分视频的融合的技术,是用一个长方形面片,然后把视频纹理渲染到这个面片上,然后叠加到场景中,记得好多年前一个同事就是用这种思路实现的。这种方式的优点在于实现思路简单,资源消耗小。 缺点是只能从视频投射的角度去看,从其他角度就会露馅。

要实现真正的视频融合,需要使用投影纹理映射。

投影纹理映射Texture Projection

投影纹理映射的原来就是类似于用的投影仪,把图像投影到三维空间的物体表面。下面是找的一张图片资源:

在projector location 放一个投影机,就可以把图像投射到房间中墙上。 有关思路参考:

https://tympanus.net/codrops/2020/01/07/playing-with-texture-projection-in-three-js/

视频纹理

图片纹理大家都比较属性,视频纹理就是把视频作为纹理的输入源,由于视频需要实时更新,所以需要实时上传视频内容。 这一块的内容可以参考Three的VedioTexture,在three中,首先通过flv.js 播放视频,然后把视频元素vedio给到VedioTexture既可实现视频纹理。

实现思路

主要实现思路如下,在真实摄像机所在位置和朝向,模拟一个透视摄像头(Perspective Camera),该摄像头的投影区间是 是 xy 从左到右 从上到下-1 到1, 可以把区间转换成uv空间,如下:

vec2 projectUv = (vProjTexCoords.xy / vProjTexCoords.w) * 0.5 + 0.5;

如果projectUv在0~1区局,则可以获取视频上对应的像素值,如果不在该区间,用模型本身的贴图颜色。

bool inTexture = (max(projectUv.x, projectUv.y) <= 1.0 && min(projectUv.x, projectUv.y) >= 0.0);
if (inTexture) {
   // 确保采样的视频纹理有效
      vec4 projectionColor = texture(projectionTexture, projectUv);
      // 应用投影颜色
      diffuseColor.rgb = projectionColor.rgb;
}

深度问题

上面的思路有一个缺陷,就是没有考虑深度遮挡的问题,比如两个物体A和B,从摄像头所在位置和朝向看过去,A在前面,B在后面,这个时候B是被A遮挡了,基于这个道理,视频不应该投影到B物体的表面上。 如何解决这个问题?

如果熟悉阴影的原理,其实就比较好解决。 解决办法就是从摄像头的位置和朝向用深度材质渲染一遍场景,获得一张深度图,然后在实际渲染的时候,比较当前片元离摄像头深度和深度图保存深度,如果大于,则是被遮挡的,代码逻辑如下:

// 计算当前片段在投影空间中的标准化设备坐标深度
float currentDepthNDC = (vProjTexCoords.z / vProjTexCoords.w) * 0.5 + 0.5;
// 转换为线性深度用于比较
float currentLinearDepth = linearizeDepth(currentDepthNDC);
// 从深度图中采样深度值
vec4 depthSample = texture(depthTexture, projectUv);
float storedDepth = unpackDepth(depthSample);
// 转换存储的深度为线性深度
float storedLinearDepth = linearizeDepth(storedDepth);
// 添加一个与深度相关的偏差以避免z-fighting
float bias = 0.01 * currentLinearDepth; // 深度越大,偏差越小
// 只有当当前片段是最接近投影相机的表面时,才应用投影
if (currentLinearDepth < storedLinearDepth + bias) {
  
}

注意由于精度问题,需要设置一个偏移值bias。

最终投影的效果如下:

多视频融合

前面介绍的是一个摄像头的情况,如果是多个摄像头的情况,就要复杂一些,不过基本原来是一样的。 就是要增加多个透视投影Camera的逻辑和多个视频纹理。 此处不再详述。

总结

本文简述了视频融合的基本原理 ,有兴趣的可以讨论。最后,关注公号“ITMan彪叔” 可以添加作者微信进行交流,及时收到更多有价值的文章。