跳到主要内容

视差映射

视差映射利用高度贴图,让平面看起来具有深度。法线贴图只改变表面的受光方式,视差映射还会在相机移动时改变看到的纹理位置,让砖缝看起来真正凹入,而不只是阴影变化。

它是标准材质上的逐像素效果,通过指定 heightMap 启用。与法线映射相同,它需要切线坐标系,带 UV 的网格会自动获得。

实时示例​

  • 视差映射:在砖房的平墙和球体上比较不同模式。
视差映射
  • 视差地形:从不同距离和角度观察同一种地面材质。
视差地形

两种模式​

StandardMaterial#parallaxMode 选择高度贴图的解释方式。

模式说明
PARALLAX_OFFSET默认模式。只采样高度贴图一次来偏移 UV,开销很低,足以表现浅层起伏。
PARALLAX_OCCLUSION沿视线在高度场中步进,直到进入表面以下。能将深层起伏表现为真实深度,但采样次数更多。
material.parallaxMode = pc.PARALLAX_OCCLUSION;
material.heightMapFactor = 0.5;
material.update();

两种模式中,heightMapFactor 都用于缩放深度。实用范围约为 0 到 2;超过后,起伏深度会超出该技术可逼真模拟的程度,沿表面观察时纹理会明显拉伸。

零高度​

StandardMaterial#heightMapBase 指定高度贴图中哪个值位于原始几何体表面。高于它的起伏看起来凸出,低于它的则凹入。两种模式以相同方式读取贴图,因此切换模式不会改变表面位置。

默认值 0.5 以中灰为起伏基准,适合同时包含凸起和凹陷细节的贴图。纯深度贴图(白色地面、深色裂缝)应将基准设为 1,使地面保持原位,只有裂缝下陷。纯高度贴图则应设为 0。

material.heightMapBase = 1; // white is the surface, darker is carved in
material.update();

采样预算​

在遮蔽模式中,StandardMaterial#parallaxSamples 限定沿视线步进时高度贴图采样次数的上限,默认 16。

这是上限,而非固定次数。射线覆盖的纹理范围越小,采样越少;正面观察、起伏较浅或表面较远时均如此。射线覆盖范围小于一个纹素时,就没有可位移的内容,效果会完全淡出,因此远处表面不产生这项开销。

仅前向通道进行这些采样,阴影和深度通道不受影响。

自阴影​

StandardMaterial#parallaxShadowSamples 让起伏产生自阴影:着色器从视线命中点向光源方向在高度场中步进,使凸起砖块压暗旁边的砂浆。默认值为 0,表示禁用。

material.parallaxMode = pc.PARALLAX_OCCLUSION;
material.parallaxShadowSamples = 8;
material.update();

阴影是柔和的。步进不会在第一个遮挡处停止,而是测量光路被阻挡的程度,并按距离加权,使阴影在接近投影物处清晰、远处柔化。更多采样带来更平滑结果,而非更早退出,因此指定采样数的开销固定。可从约 8 次开始;低于 4 次会产生条带。

备注

自阴影仅适用于平行光,且需要 PARALLAX_OCCLUSION。无需启用灯光投影,因为它是表面属性,而非灯光属性。

只有光线斜着横跨高度贴图纹理走向时才明显。因此入射方向与高度同样重要;顺着纹理走向照射几乎不产生自阴影。降低光源角度也不一定增强它:光线越低,越多表面完全背光,而不接收直接光的表面也就没有可继续遮蔽的光。

限制​

视差映射通过移动纹理查询位置模拟深度,像素本身不移动,这决定了技术边界。

  • **轮廓不变。**起伏只在网格轮廓内部可见,因此凹凸表面仍有平直边缘。
  • **深度缓冲区仍将表面视为平面。**投射到表面的阴影、SSAO 和深度预通道均将其视为平面,不会随起伏变化。自阴影为平行光弥补了这一点。
  • **掠射角下纹理会滑动。**查询偏移等于起伏深度乘以视角正切,因此浅角度下,相机的微小移动会导致纹理大幅移动,看起来像表面漂浮。降低 heightMapFactor 是最直接的补救方法。

如果起伏必须改变轮廓,或需要被阴影和深度效果识别,应改为对几何体进行位移。