支付宝那些以假乱真的渲染效果,是怎么来的?

简介: AR技术在增强现实方向上的不断努力,目的都是为了让虚拟模型能够更好地与现实环境融为一体,真假分不清楚,达到真实感渲染的体验,从而创造出更好的场景,本文就围绕这种虚拟与真实环境结合的环境纹理渲染技术实现探索来开展。

小叽导读:AR技术在增强现实方向上的不断努力,目的都是为了让虚拟模型能够更好地与现实环境融为一体,真假分不清楚,达到真实感渲染的体验,从而创造出更好的场景,本文就围绕这种虚拟与真实环境结合的环境纹理渲染技术实现探索来开展。


背景

先来看两个AR效果,真实地面打开效果:

640 (10).gif

地面被挖开效果:

640 (9).gif

可以看到真实世界的"地面"作用了虚拟模型的动画效果慢慢打开或铲开,进而再做出虚拟模型的一系列动画渲染效果,给用户一种真实的地面被打开或挖开的效果。那么如何实现这种酷炫的渲染效果呢?

实战初探分步走

第一步:制作简单模型

为了实现这种与地面融合的渲染效果,我们制作一个简单的模型及动画:一个立方体从地面钻出,然后顶部屏幕从中间慢慢左右打开。

使用Maya简单制作一个模型,这里用最普通的立方体模型,让它的最顶端的平面节点位于水平面之下(模型坐标系),同时紧贴在其上增加两个半平面节点用于左右打开效果的动画实现,为了效果看起来不是那么挫(实际最终效果还是很挫,我不是一个合格的UED),在两个半平面节点与立方体顶端平面之间增加一个视频节点,这样当"地面"打开时,从地面钻出个箱子,有个视频在箱子上面播放。

image.png

image.png

第二步:节点纹理与实景纹理绑定

模型资源已经准备好了,所以为了能与实景融合,我们将相机实时采集的图像每一帧不断的渲染至"模型的平面"(模型节点)所在的纹理上,也就是之前模型制作时的用于左右分开的模型节点上,OpenGL部分核心代码如下:

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _dstTexture, 0);

_dstTexture为获取到的用于左右分开动画的节点目标纹理,我们将相机帧渲染至此纹理,至此,我们可以看到这样的效果:

640 (8).gif

整个场景都被渲染上来了,我们最终想要的,仅仅是此时该平面真正占据的实景部分,即立方体顶部平面所占据的一小块实景部分,那么意味着,我们需要对纹理进行“裁剪处理”。

第三步:对实景纹理进行裁剪

如何进行准确的裁剪?并且随着模型的旋转、平移、缩放都能够不断更新且准确地裁剪到对应的纹理区域?

那么我们首先想到的是模型的顶部平面在未结合环境纹理是怎么被渲染到屏幕的?

首先模型通过mesh文件提取出模型顶点信息,渲染管线会在所有顶点着色器运行后,将我们所有可见的顶点都变为标准化设备坐标。也就是说,每个顶点的x,y,z坐标都应该在-1.0到1.0之间,超出这个坐标范围的顶点都将不可见,顶点坐标经过不同的坐标系变换类似流水线的方式拿到标准化设备坐标,即经过如下不同的坐标系空间:

  • 局部空间(Local Space,或者称为物体空间(Object Space))
  • 世界空间(World Space)
  • 观察空间(View Space,或者称为视觉空间(Eye Space))
  • 裁剪空间(Clip Space)
  • 屏幕空间(Screen Space)

这些就是我们将所有顶点转换为片段之前,顶点需要处于的不同的状态,即大家熟知的MVP。

如下图的变换过程:

image.png

局部坐标是对象相对于局部原点的坐标,也是对象开始的坐标。即该例中立方体的上平面在局部坐标中的位置。

将局部坐标转换为世界坐标,世界坐标是作为一个更大空间范围的坐标系统。这些坐标是相对于世界的原点的。

接下来我们将世界坐标转换为观察坐标,观察坐标是指以摄像机或观察者的角度观察的坐标

在将坐标处理到观察空间之后,我们需要将其投影到裁剪坐标。裁剪坐标是处理-1.0到1.0范围内并判断哪些顶点将会出现在屏幕上。

最后,我们需要将裁剪坐标转换为屏幕坐标,我们将这一过程称为视口变换(Viewport Transform)。视口变换将位于-1.0到1.0范围的坐标转换到由glViewport函数所定义的坐标范围内。最后转换的坐标将会送到光栅器,由光栅器将其转化为片段。

矩阵公式为:

image.png

顶点着色器的输出需要所有的顶点都在裁剪空间内,然后OpenGL在裁剪空间中执行透视划分从而将它们转换到标准化设备坐标,在这个过程中将位置向量的x,y,z分量分别除以向量的齐次w分量;透视划分是将4维裁剪空间坐标转换为3维标准化设备坐标。这一步会在每一个顶点着色器运行的最后被自动执行。OpenGL会使用glViewPort内部的参数来将标准化设备坐标映射到屏幕坐标,每个坐标都关联了一个屏幕上的点。

image.png

顶点坐标信息通过以上的MVP变换最终被赋予顶点着色器中的gl_Position且OpenGL将会自动进行透视划分和裁剪。

通过以上过程,我们已经知道了箱子的顶部平面是经过 MVP矩阵变换+透视划分的顶点着色器处理送给光栅化处理的了,那么我们可以将相同的处理作用给环境纹理,从而确定了我们纹理应该裁剪得到哪一部分环境纹理。但这里有一个问题,我们通过MVP矩阵变换+透视划分拿到的坐标区域是OpenGL坐标系下的,而纹理映射是UV坐标下的。

20180919172334.png

OpenGL坐标系是从(-1,-1)到(1,1)而UV坐标是(0,0)到(1,1)

image.png

所以我们需要对结果坐标position从OpenGL变换至UV坐标系下:

x = position.x/2.0 + 0.5, 
y = position.y/2.0 + 0.5

至此,我们通过最初的顶点信息经过

  • MVP矩阵变换
  • 透视划分
  • OpenGL至UV坐标系变换

拿到了需要裁剪的纹理坐标。

通过以上处理最终作用到纹理坐标v_texCoord上,看下效果:

640 (7).gif

目前环境纹理渲染效果已经在支付宝10.1.35版本的星宝中使用(星宝入口:支付宝首页搜索“AR星宝”生活号→进入“AR星宝”),效果如下:


640 (6).gif

遇到的问题

在实际的应用中,我们绑定了环境纹理后,便不希望随着模型节点的RT(旋转、移动)再去更新节点的环境纹理,即不希望环境纹理有更新,从而才能产生真实的“地面被挖开”等效果。我们通过记下需要停止更新时刻的MVP,后续都使用该MVP去计算纹理裁剪坐标即可。

但是在设计节点动画时,设计师为了酷炫的动画效果,会针对要绑定环境纹理的节点做一系列骨骼动画的处理,当我们对有骨骼动画的节点做环境纹理处理的时候,遇到环境纹理还是会不断更新的问题,细究原因,骨骼动画即是对顶点坐标在MVP处理之前有一系列M的动画矩阵运算达到动画效果,那么,我们要么去缓存下每个顶点在骨骼动画前的信息,面对上万的顶点信息,这不太现实,于是,我们做一个取舍,不管有没有骨骼动画,在停止更新时都使用未经过处理(骨骼动画)的position,这样就避免了骨骼动画对于环境纹理的影响。

扩展

这种将现实世界环境纹理与虚拟物体结合起来渲染的技术目前应用的场景也较多,比如虚拟球体的环境镜面反射效果,通过将环境纹理映射到球体表面:

image.png

image.png

包括WWDC2018苹果结合ARKit2.0做的环境纹理(Environment Texturing),现实世界环境被渲染在立方体贴图中,可被用于作为渲染引擎中的反射探针(Reflection Probe)。此反射探针可应用环境纹理在虚拟物体上,这将大大提升了会反射的物体的视觉效果。

image.png

image.png

image.png

目录
相关文章
|
存储 编译器 C语言
计算机组成与体系结构期末题目解析
计算机组成与体系结构期末题目解析
2727 0
计算机组成与体系结构期末题目解析
|
测试技术 UED 开发者
优秀的developer----自测优势及规范
本文章针对于弹性计算项目,合作方出的自测规范,仅供参考
8903 0
优秀的developer----自测优势及规范
|
开发者
「代码强迫症?」从0到1实现项目代码拼写检查 vscode 插件:project-spell-checker(一)
「代码强迫症?」从0到1实现项目代码拼写检查 vscode 插件:project-spell-checker(一)
631 0
|
存储 网络安全 数据处理
阿里云对象存储OSS计费模式按量付费和包年包月选择攻略
阿里云OSS对象存储计费模式分为按量付费和包年包月,默认开通OSS就是按量付费,购买资源包抵扣OSS费用的方式属于包年包月计费模式
3716 0
阿里云对象存储OSS计费模式按量付费和包年包月选择攻略
|
运维 监控 Linux
BPF及Linux性能调试探索初探
BPF技术从最初的网络数据包过滤发展为强大的系统性能优化工具,无需修改内核代码即可实现实时监控、动态调整和精确分析。本文深入探讨BPF在Linux性能调试中的应用,介绍bpftune和BPF-tools等工具,并通过具体案例展示其优化效果。
746 14
|
存储 安全 网络安全
勒索病毒不再可怕:.baxia病毒解密与预防策略
本文深入分析了.baxia勒索病毒的特点,探讨数据恢复方法及预防措施,旨在帮助个人和企业有效应对这一网络威胁,确保数据安全。文章还提供了技术服务号(sjhf91),为用户提供专业的数据恢复支持。
710 3
|
人工智能 语音技术 UED
仅用4块GPU、不到3天训练出开源版GPT-4o,这是国内团队最新研究
【10月更文挑战第19天】中国科学院计算技术研究所提出了一种名为LLaMA-Omni的新型模型架构,实现与大型语言模型(LLMs)的低延迟、高质量语音交互。该模型集成了预训练的语音编码器、语音适配器、LLM和流式语音解码器,能够在不进行语音转录的情况下直接生成文本和语音响应,显著提升了用户体验。实验结果显示,LLaMA-Omni的响应延迟低至226ms,具有创新性和实用性。
565 1
|
编译器 C语言
C语言:typedef 和 define 有什么区别
在C语言中,`typedef`和`#define`都是用来创建标识符以简化复杂数据类型或常量的使用,但它们之间存在本质的区别。`typedef`用于定义新的数据类型别名,它保留了数据类型的特性但不分配内存。而`#define`是预处理器指令,用于定义宏替换,既可用于定义常量,也可用于简单的文本替换,但在编译前进行,过度使用可能导致代码可读性下降。正确选择使用`typedef`或`#define`可以提高代码质量和可维护性。
|
SQL 人工智能 自然语言处理
通义灵码代码大模型应用实践访谈
2024 年 6 月 26 日,中国信息通信研究院(以下简称“中国信通院”)在可信 AI·南京人工智能产业发展论坛正式发布了代码大模型评估结果。阿里云计算有限公司的通义灵码代码大模型顺利通过评估,获得目前最高等级 4+ 级。该等级代表阿里云通义灵码大模型在通用能力及专用场景能力绝大多部分达到优秀水平,同时具备较为成熟的管理机制。
|
前端开发 JavaScript 测试技术
React 与前端自动化测试也太重要啦!各种测试框架助力确保应用质量,快来开启优质开发之旅!
【8月更文挑战第31天】随着前端技术的发展,React 成为了构建用户界面的热门选择。然而,随着应用复杂性的增加,确保应用质量变得至关重要。本文介绍了前端自动化测试的重要性,并详细综述了常用的测试框架如 Jest、Enzyme 和 Cypress,以及如何通过它们进行高效的 React 组件测试。通过遵循最佳实践,如编写可维护的测试用例、覆盖关键场景、集成 CI/CD 流程和进行性能测试,可以显著提高应用的稳定性和可靠性。
379 0