Cesium中实现视差贴图假房间

视差贴图假房间

了解什么什么是视差贴图假房间 (Interior Mapping)之前,我们先看一下游戏中的窗户是怎么实现的。两个典型的例子是 《GTA 4》 和 《蜘蛛侠》。

《GTA 4》 的大部分窗户,实际上都是由一张平面的贴图来实现的,就像是在墙上贴了一张窗户的海报一样,并不能随着视线的变化产生透视的效果

gta4

而反观 《蜘蛛侠》 中大部分窗户是能够随着视线变化而产生透视效果的,仿佛窗户背面真的有一个空间一样。但事实上和 《GTA 4》 类似,这同样是由一个平面来实现的

蜘蛛侠

《蜘蛛侠》 游戏中的窗户正是使用了视差贴图假房间 (Interior Mapping) 这项技术。相比于传统的建模渲染或者贴贴图,Interior Mapping 可以在保持高效率和高质量的同时,将室内的细节和灯光效果呈现得更为逼真。因此,它极大地拓展了虚拟建筑场景的可能性。

实现方式

实现 Interior Mapping 需要一个具有法线方向和切线方向信息的平面,并利用法线和切线计算出副切线(当前也可以创建平面的时候直接计算好)。

平面信息

然后计算出相机看向平面的视线方向 cameraDir,将切线、副切线、法线分别与 cameraDir 点乘,可以求出在表面坐标系下的视线方向。

表面坐标系视线方向

因为以上计算都是基于,表面法线与切线的基本空间单位,也就是建模时物体的尺寸。因此我们需要把获得这个单位矢量坐标去除1,来获得这个坐标下的标准空间尺寸。

表面视线空间

将平面的uv范围从 0 到 1 映射到 -1 到 1 让 0 点在平面中心。并增加 Z 轴为 -1 使得平面位置后移。

平面UV坐标点

由此即可计算视线与构建的 box 空间相交的最短距离 fmin 和 CubeMap 的采样点 boxSampleDir。

1
2
3
4
5
6
7
float min3 (vec3 v) {
return min (min (v.x, v.y), v.z);
}

float fmin = min3(abs(FaceViewSpace) - FaceViewSpace * FaceSpacePos);

vec3 boxSampleDir = viewDir * fmin + FaceSpacePos;

最后根据 boxSampleDir 来采样 CubeMap 即可。

Cesium中实现的效果展示


Cesium中实现视差贴图假房间
https://www.liaomz.top/2024/06/03/cesium-zhong-shi-xian-shi-chai-tie-tu-jia-fang-jian/
作者
发布于
2024年6月3日
许可协议