简介:面向虚幻引擎5开发者与视觉美术的视差材质资源,聚焦用高度图与法线贴图模拟表面微小起伏,解决平面纹理缺乏立体深度的问题,适用于游戏场景、建筑可视化与影视级材质练习。包内共478个文件,以384个uasset材质与贴图资产、4个umap关卡为主,辅以udd、ini、dat等配置与数据文件,以及uproject工程入口,解压后约918MB,目录便于直接导入或对照研究。已有1127人学习下载,说明其在UE5材质学习中具备一定参考热度。内容覆盖九宫格与单图版两种视差实现,涉及高度图、视差偏移、视差UV、切线空间、法线混合等核心概念,读者可据此观察节点连接、参数组织与贴图配置,快速理解深度错觉的构建方式,并将其迁移到自己的场景材质中。
1. 一面砖墙省下几十万面:UE5 视差材质到底解决什么问题
做室内场景的人大概都撞过这堵墙:一面清水砖墙,要凑到三十厘米能看清砖缝的凹凸,又要四米外跑满帧。真去雕砖缝,一面墙轻松吃掉几十万面,光照还容易炸;纯法线贴图在掠射角下平得像贴纸。UE5 视差材质堵的就是这个缺口——用一张高度图在像素阶段把 UV 往里推,让平面在视觉上凹下去。虚幻5材质系统里这条路有两个入口:老的 BumpOffset 和 ParallaxOcclusionMapping 函数。这套东西值不值得下,取决于你要的是一套能标定、能降级、能验收的参数流程,还是一堆看着唬人的节点图。
真正让视差材质在项目里站住脚的,不是它能"假凹凸",而是它便宜得离谱:一面 4m×4m 的墙,几何方案是几万面加一张 4K 法线,视差方案是一张高度图加一次额外采样。代价也很明确——它是屏幕空间的假象,不写深度,不参与真实遮挡,视角一斜就露馅。所以整套流程的重心不在节点怎么连,而在"什么时候该用它、参数标到多少、哪里必须退回真几何"。
2. 三条技术路线选型:BumpOffset、POM 与真几何的边界
选型这一步不做,后面参数怎么调都是瞎调。视差在 UE 里有三代做法,代价和正确性差了一个数量级,混着用是最常见的翻车起点。
2.1 BumpOffset:最便宜的那条路,什么时候还该用它
BumpOffset 节点内部做的是一次线性偏移,公式大致是UV - (ViewDir.xy / ViewDir.z) * Height * HeightRatio,只采样一次高度图,不做任何步进搜索。它的输入只有四个:Coordinates、Height、Height Ratio、Reference Plane,输出一组偏移后的 UV,直接喂给 Texture Sample 的 UVs 就行。
代价低到什么程度:一条指令级别的额外开销,移动端、Nanite、VR 全都能跑,材质指令数几乎不变。所以它在两个场景里依然是首选。第一是掠射角为主的大面积地面和走廊——你站在走廊这头看那头的地砖,视角几乎是贴着地面的,POM 在这种情况下步进次数不够就会抖成一锅粥,反而不如 BumpOffset 稳定。第二是移动端和需要大量材质变体的项目,POM 的循环在 ES3.1 上要么不支持,要么得退化成固定次数展开,变体数量直接翻倍。
它的硬伤也很清楚:没有遮挡判定。因为只偏移一次,当高度差超过一个像素覆盖的范围,砖缝的"墙"和"底"会互相穿插,表现为边缘拉丝、纹理游泳。这不是参数没调好,是算法本身只做了一次近似。经验值是 Height Ratio 别超过 0.05,超过这个数拉丝肉眼可见;如果你需要更强的立体感,别硬怼参数,换路线。
还有一点容易忽略:BumpOffset 的偏移是在切线空间里做的,模型的切线必须正确。导入的墙面如果切线是自动生成的、UV 又是镜像平铺,偏移方向会左右反。碰到"左边凹右边凸"的诡异现象,先去看 UV 是不是负值缩放。
2.2 ParallaxOcclusionMapping:逐像素步进的真相
引擎自带的 ParallaxOcclusionMapping 材质函数(在 Engine Content 的 Functions 目录下)本质是一次视线射线步进:在切线空间里沿视线方向按固定步长往前走,每走一步采样一次高度图,比较当前层高和采样到的高度,第一次"穿模"之后再做一次线性插值细化,得到最终 UV。这就是它能产生真实遮挡关系的原因——砖缝的侧壁会盖住后面的砖面,而不是简单平移。
它的输入参数比 BumpOffset 多得多,也是大部分人卡住的地方:
| 参数 | 作用 | 典型取值 | 调错的表现 |
|---|---|---|---|
| Heightmap Texture | 高度图纹理对象 | 单通道灰度图 | 空值直接不偏移 |
| Height Ratio | 整体视差深度 | 0.02~0.12 | 太大撕裂,太小没感觉 |
| Min Steps | 最少步进次数 | 8~16 | 太小近处台阶感明显 |
| Max Steps | 最多步进次数 | 32~64 | 太大指令数暴涨 |
| Step Scale | 步长缩放系数 | 1.0 起调 | 偏离 1 太多会漏采 |
| Height Map Channel | 高度所在通道 | R 或 A | 选错整张图反向 |
| Reference Plane | 参考平面偏移 | 0~1 | 影响凹凸中心位置 |
函数通常吐出两个输出:Parallax UVs 和 Pixel Depth Offset。前者接给所有需要采样表面细节的贴图(BaseColor、Normal、Roughness 都要用同一组偏移 UV,否则颜色和凹凸会错位),后者接材质的 Pixel Depth Offset 引脚,用来把假深度写回深度缓冲。
步进次数是最直接的性能旋钮。Min Steps 决定近处质量,Max Steps 决定极端角度下的上限。常见做法是把 Min Steps 设成 8、Max Steps 设成 32,然后根据项目预算上下浮动。要注意这玩意儿是指令数大户,一个 64 步的 POM 材质在 1080p 全屏铺开,GPU 时间能吃掉几个毫秒,别在地面这种占屏比极高的物体上无脑拉满。
提示:POM 的循环在材质编译器里会被展开,Steps 越大编译时间越长,材质变体多的时候编辑器会明显卡顿。改参数前先想清楚是不是真的需要 64 步。
2.3 三条路线的选型判断表
把三条路线摆在一起看,选择其实不难,难的是团队里没人愿意承认"这面墙该上真几何"。
| 维度 | BumpOffset | POM 函数 | 真几何 + Nanite |
|---|---|---|---|
| 额外采样数 | 1 次 | Steps 次 | 0 |
| 遮挡正确性 | 无 | 有 | 完整 |
| 深度写入 | 无 | 需手动接 PDO | 原生 |
| 移动端可用 | 是 | 受限 | 是 |
| 掠射角稳定性 | 好 | 一般 | 好 |
| 近距特写 | 差 | 好 | 最好 |
| 美术成本 | 低 | 中 | 高 |
我一般按观看距离和视角给规则:主视角距离大于两米、以正视为主的墙面,BumpOffset 够了;玩家能走到一米以内、并且会侧着看的地面、墙裙、石材台面,上 POM;需要凑到二十厘米、必须要有硬边投影和真实轮廓的(家具边缘、雕花、破损砖角),老老实实建模,视差只用来补表面细节。
还有一条容易被忽略的判据:这东西会不会出现在反射里。POM 在屏幕空间反射、平面反射里不会自动跟着凹,你会在湿地面反射里看到一面平墙。这种场景要么上真几何,要么干脆别用视差。
3. 搭一套可复用的视差材质:从高度图规范到参数标定
节点连起来只是开始,真正决定效果好坏的是高度图规范和参数标定。这一章给一套可以直接抄的流程,主材质做一次,后面所有墙面都从材质实例派生。
3.1 高度图的生产规范与打包策略
高度图不是随便拿张灰度图就完事,它的数值分布直接决定视差层高。约定比技术更重要:统一规定 0 为最低、1 为最高,中间调对应实际层高。全项目用同一套约定,否则从不同来源拿的贴图混在一起必然有一半是反的。
在 UE 里导入高度图,有两个设置必须手动改,默认值会毁掉一切:
import unreal # 批量修正高度图的导入设置:关 sRGB、改灰度压缩 def fix_heightmap(asset_path: str): tex = unreal.EditorAssetLibrary.load_asset(asset_path) if not isinstance(tex, unreal.Texture2D): return # 高度是线性数据,必须关掉 sRGB,否则中间调被 gamma 掰弯 tex.set_editor_property("srgb", False) # BC4 单通道压缩,比 BC1/BC3 的块状伪影小得多 tex.set_editor_property("compression_settings", unreal.TextureCompressionSettings.TC_GRAYSCALE) tex.set_editor_property("lod_group", unreal.TextureGroup.TEXTUREGROUP_WORLD) unreal.EditorAssetLibrary.save_loaded_asset(tex) for path in unreal.EditorUtilityLibrary.get_selected_assets(): fix_heightmap(path.get_path_name())这段脚本选中一批高度图后跑一遍,核心是三个属性。srgb必须为 False,因为高度是线性数据,打开 sRGB 会让 0.5 的中间调实际变成 0.21 左右,层高分布整个塌向一侧,表现是"凹凸只往一个方向偏"。compression_settings设成 TC_GRAYSCALE 走 BC4,单通道 8 位,比塞进 RGB 用 BC1 压缩的块状台阶好太多。lod_group设成 World 是为了让贴图流送策略和场景贴图一致,避免远景突然糊掉。
如果你的管线要求把所有贴图打包进一张图的 RGB + A,高度就放 A 通道,压缩用 BC3 或 BC7,此时脚本里的压缩设置要改成对应的 TC_BC7,材质里 Height Map Channel 选 A。打包的代价是 A 通道和 RGB 共享压缩块,高度精度会略降,近距离大层高时能看出台阶。
分辨率上,高度图和法线图保持一致,都跟 BaseColor 同 UV 平铺。别用 2K 高度配 4K 法线,采样位置对不上,凹凸和颜色会错半格。平铺次数超过 4 次的墙面,建议单独做一张只含高度的低分辨率平铺图,避免高度图在远处产生摩尔纹。
3.2 主材质节点连线与参数暴露
主材质的连线顺序很重要,错一步后面全乱。我的固定顺序是:先算视差 UV,再用同一组 UV 采样所有表面贴图,最后把 PDO 单独接到材质输出。
第一段,Heightmap Texture 采样节点,UV 用 TexCoord 乘平铺系数,输出接 ParallaxOcclusionMapping 的 Heightmap Texture 和 UVs。注意这里的高度采样不要加任何偏移,POM 内部会自己算。
第二段,ViewDir 不需要手动接,函数内部用像素的切线空间视线。但如果你要做自定义版本,需要把 Camera Vector 转到切线空间,用 TransformVector(Tangent Space)节点。
第三段,POM 输出的 Parallax UVs 接给 BaseColor、Normal、ORM 三张贴图的 UVs 输入。这一步最容易出错:有人只把 BaseColor 接了偏移 UV,法线还用原始 UV,结果颜色在动、高光不动,看着像贴图在墙上滑。
第四段,PDO 输出接材质的 Pixel Depth Offset 引脚。这个引脚在材质细节面板的"材质"分类下,需要把着色模型设成能写深度的类型才生效。
参数暴露上,把 Height Ratio、Min Steps、Max Steps、Step Scale 都提成材质参数(勾上 Use Custom Primitive Data 更省,但先保证能用)。命名统一加前缀,比如MP_HeightRatio,后面用脚本批量改实例参数时不容易撞名。
如果要做自定义版本(很多人做是因为官方函数不够灵活,想加自适应步长),Custom 节点里可以这么写一个最简步进:
// Custom 节点输入:UV(float2)、HeightTex(Texture2D)、ViewDirTS(float3)、 // HeightRatio(float)、Steps(float) // 注意:Steps 必须是编译期常量,别接动态参数 float2 curUV = UV; float layerStep = 1.0 / Steps; // 视线越斜,单步在 UV 上的投影越长 float2 delta = (ViewDirTS.xy / max(abs(ViewDirTS.z), 0.15)) * HeightRatio * layerStep; float curLayer = 0.0; float curHeight = HeightTex.SampleLevel(HeightTexSampler, curUV, 0).r; [loop] for (int i = 0; i < 64; i++) { if (curLayer >= 1.0 || curHeight <= curLayer) break; curLayer += layerStep; curUV -= delta; curHeight = HeightTex.SampleLevel(HeightTexSampler, curUV, 0).r; } return curUV;ViewDirTS.z加了 0.15 的下限保护,防止视线完全平行表面时 delta 爆炸,这是掠射角撕裂的主要来源之一。SampleLevel显式指定 mip 0,避免循环里自动求导导致 mip 选择抖动。循环上限写死 64,UE 的材质编译器不接受完全动态的循环次数,接一个动态 Steps 进去会编译报错或者退化成常量。
注意:Custom 节点里的 Texture2D 输入,UE 会自动配一个
<参数名>Sampler的采样器,写代码时直接引用这个名字,别自己声明。
3.3 参数标定:Height Ratio 到底给多少
Height Ratio 是这个系统里唯一"没有标准答案"的参数,因为它跟你的贴图内容强相关——同一面墙,如果高度图最高点代表 2 厘米凸起,和代表 8 厘米凸起,比率差四倍。
我用的标定法子是这样:在场景里放一个 1m×1m×1m 的立方体,贴同一套材质,UV 平铺设成 1。然后从正前方平视,慢慢调 Height Ratio,直到立方体的侧面(真实厚度 1m)和墙面视差产生的"假厚度"在视觉上抵消。这个值记为基准值。比如基准值调到 0.08 正好对上 1m 的立方体,那说明这张高度图的满量程对应 8 厘米的真实起伏,接下来所有墙都从这个值出发,按实际砖缝深度微调。
Steps 的标定看的是另一个东西:把相机贴到墙面前 30 厘米,视线压到 15 度左右,慢慢降 Max Steps,直到砖缝侧壁开始出现明显台阶(一层一层的横向条纹),再往上加 8 步。这个值就是你这张图的步进下限。同一张图在 4K 屏上需要更多步,因为一个像素覆盖的世界尺寸更小。
Step Scale 一般不碰,除非你发现视差在深度方向上"分层"了——表现为凹凸之间有一圈圈的环状纹路,那是步长和高度变化率不匹配,把 Step Scale 调到 1.2 左右能缓解。
Reference Plane 影响的是凹凸的"零点"位置。设成 0 时,高度 0 的部分是基准面,整个表面往里凹;设成 1 时反过来,往外凸。做墙面一般设 0.5,让砖面和砖缝各占一半,这样材质在物料边缘不会突然变厚一层。
3.4 用 PDO 把深度"补回来"
不接 PDO 的视差材质,在深度缓冲里依然是平的。后果是三件事:贴花会浮在"凸起"的砖面上但实际画在平面;软阴影和距离场 AO 不认这些凹凸,砖缝里不会变暗;景深和半透明排序按平面算,玩家靠近时会有明显的割裂感。
PDO 的近似公式是Height * HeightRatio,也就是把当前像素的高度值按比率折算成世界单位的深度偏移。POM 函数已经把这个值算好了,直接接过去就行。
代价要说清楚:一旦写了 PDO,材质就进入深度预通道并关闭 Early-Z,overdraw 变成实打实的像素着色开销。墙面这种大面积、深度复杂度高的物体,开了 PDO 之后 GPU 时间会涨。我一般只在"玩家能走到一米内"的墙面上开,远景墙面不开。
还有一条坑:PDO 和 Nanite 网格搭配时行为不一致,下一章细说。
4. 让视差材质在 Nanite、Lumen、移动端上不出戏
本地看着挺好,一进正式场景就出问题,九成是这三样东西在打架。它们各自的渲染路径和视差的"屏幕空间假象"天生不对付。
4.1 Nanite 网格上的视差偏移与深度排序
Nanite 走的是虚拟化几何的软件光栅化路径,和传统网格的深度写入方式不一样。把带 PDO 的视差材质贴到 Nanite 网格上,常见现象是深度排序错乱——墙体自己和自己打架,或者远处物体被墙"咬掉"一块。
原因在于 PDO 修改的是光栅化后的像素深度,而 Nanite 的可见性缓冲和软件光栅有自己的深度处理逻辑,两者叠加时,深度预通道算出来的值和最终着色的值对不上,遮挡剔除阶段就会误判。
解决办法很直接,我的习惯是视差墙面根本不勾 Nanite。墙面本来就不是高面数模型,一个立方体加平铺材质,Nanite 带来的好处趋近于零,反而引入一堆兼容问题。如果项目规范强制全场景 Nanite,那就把视差强度压到 0.03 以下并关掉 PDO,用纯 UV 偏移的 BumpOffset 替代,牺牲立体感换稳定。
还有一个隐蔽的坑:Nanite 的 fallback mesh 在远处会切回传统光栅。如果你在材质里用 Feature Level 或距离判断做了分支,切回的一瞬间参数会跳变,表现为远处墙面"啪"地一下变平。要么保持两套分支参数一致,要么干脆不做距离分支。
4.2 与 Lumen、SSAO、贴花的相互影响
POM 造出来的凹凸是屏幕空间的幻觉,场景的全局光照看到的是那张平面。所以砖缝深处不会因为遮挡而变暗,砖面也不会有来自侧壁的反弹光。结果就是视差看起来"贴"在墙上,而不是墙体的一部分。
常见的补法有三层。第一层,在高度图上烘一张 AO,按高度值乘进 BaseColor 和 Roughness,砖缝压暗。这个最便宜,效果也最直接。第二层,法线贴图别省,视差负责大轮廓、法线负责细节高光,两者叠加才有质感。第三层,如果预算允许,用材质里的 Distance Field AO 或者屏幕空间 AO 反向影响,但别指望它能救回砖缝里的暗部。
贴花的处理稍微麻烦一点。视差墙面上的贴花(比如污渍、涂鸦),如果材质没接 PDO,贴花会按平面投影,落在"凸起"上的部分会悬浮。接了 PDO 之后贴花能正确贴合,但要注意贴花的材质也得支持深度测试。反过来,如果贴花本身带位移,两套 PDO 叠加会互相干扰,这种场景我一般把贴花改成贴图混合进主材质,不做独立贴花。
Lumen 还有一个具体的表现:墙面视差很强的时候,附近的间接光会显得"平",因为 Lumen 的表面缓存采样的是几何法线,不认视差偏移。缓解方式是把法线贴图的强度在视差区域适当加大,让表面缓存捕捉到更多法线变化。
4.3 移动端降级:Feature Level Switch 与材质变体
移动端(ES3.1)对视差的支持是受限的。POM 的循环在移动端着色器里要么不支持动态次数,要么被展开成固定次数后指令数爆炸,直接表现是材质编译报错、模型粉屏,或者帧率腰斩。
正确做法是在材质里用 FeatureLevelSwitch 节点做分支:SM5 及以上走 POM 完整版,ES3.1 走 BumpOffset 简化版。两支的 BaseColor、Normal、Roughness 采样逻辑保持一致,只有 UV 计算不同,这样视觉差异只在立体感上,不会出现颜色对不上。
// Custom 节点内做特性等级判断(伪代码示意) #if ES3_1_PROFILE // 移动端:单次偏移,Height Ratio 压到 0.02 return UV - ViewDirTS.xy * HeightRatio * Height; #else // 桌面端:走完整步进 return ParallaxStep(UV, HeightTex, ViewDirTS, HeightRatio, 32); #endif实际项目里我更推荐用两个独立材质而不是一个材质两分支。原因很实在:FeatureLevelSwitch 会在编译期展开,但材质变体数量是按分支组合算的,一个材质里塞两套逻辑,变体数会翻倍,打包时间和包体都受影响。分开做两个材质,移动端那个只保留必要节点,指令数能压到桌面版的三分之一。
移动端还有个必须注意的点:高度图在移动平台上如果走了 ASTC 压缩,单通道精度的损失比桌面 BC4 更明显,近距离会出现明显的层状台阶。这种情况下把 Height Ratio 再压小,用视觉上的"浅浮雕"换稳定。
提示:移动端做降级时,一定要在真机上验证,不要只看编辑器里的 Mobile Preview。预览器的着色器编译路径和真机不完全一致,PDO 相关的报错经常只在真机上出现。
5. 视差材质避坑清单:五个血泪现场
下面这五条都是从实际项目里攒出来的,按"现象 → 原因 → 解决"写,碰到对应症状直接对号入座。
5.1 掠射角下撕裂、抖动、拉丝
现象:相机贴近墙面、视线几乎平行表面时,砖缝边缘出现锯齿状拉丝,移动相机时纹理像在水里游。
原因:视线方向的 z 分量趋近 0,ViewDir.xy / ViewDir.z这个比值爆炸,单步在 UV 上的投影长度远超一个纹素,步进直接跨过了整个凹凸结构。步数不够时更明显。
解决:在计算 delta 时给 z 加下限钳制(前面代码里的max(abs(z), 0.15)),同时提高 Max Steps 到 48 以上。如果还是抖,说明这张高度图的层高太大,降低 Height Ratio,把立体感交给法线贴图。另外检查贴图的 mip 设置,掠射角下如果 mip 没降下来,高频细节会持续闪烁。
5.2 高度图反相,凹的变凸的
现象:砖缝应该是凹进去的,结果看起来是凸出来的网格线,光照方向也反了。
原因有三种。一是高度图本身的 0/1 约定和材质里的期望相反,导入时没统一;二是材质里 Height Map Channel 选错了通道(比如高度在 A 通道,却选了 R),采样到的是别的数据;三是 UV 用了负值缩放,导致偏移方向整体翻转。
解决:先单独预览高度图,用一张已知方向的测试图(左黑右白)确认数值方向;再检查材质里的通道选择;最后排查 UV 缩放。三处都对还反,就在高度采样后面加一个 OneMinus 节点直接翻转,这是最快的后悔药。
5.3 阴影和物体"浮"在墙上
现象:墙角的箱子在地面上投的阴影是对的,但贴着墙时影子画在砖面上,没有落在砖缝的凹陷里;贴花也像贴在玻璃上。
原因:材质没接 Pixel Depth Offset,深度缓冲里墙还是平的。
解决:把 POM 输出的 PDO 接到材质引脚。接完之后如果出现新的问题(比如半透明物体排序错乱),说明 PDO 的数值符号反了,取负再试。还有一种情况是物体本身也在做视差,两套 PDO 叠加,这就要把其中一方的 PDO 关掉。
5.4 远距离噪点和摩尔纹
现象:站在十米外看墙面,视差区域出现一片闪烁的噪点,相机一动就变。
原因:高度图没有正确生成 mip,或者采样时用了 SampleLevel(0) 强制采样最高精度,远处像素覆盖多个纹素,采样结果在帧间跳变。
解决:循环内采样用SampleLevel显式指定 mip 层级,这个层级根据像素到相机的距离或者 UV 导数算出来;或者在材质里加一层距离衰减,超过一定距离直接把视差偏移量 lerp 到 0,退回普通贴图。后者更粗暴但很有效,我常用。
5.5 材质变体爆炸、编译时间失控
现象:加完视差材质之后,项目编译 shader 的时间从几分钟涨到半小时,打包出来的包体也大了不少。
原因:POM 的步进循环在编译期展开,Steps 越大展开越多;如果再叠加 FeatureLevelSwitch、Quality Switch、多个材质参数组合,变体数呈乘法增长。
解决:把 Steps 固定成两档(低配 16、高配 32),用 Quality Switch 而不是暴露成可变参数;把静态参数(Static Switch)能砍的都砍掉;把视差材质单独做成一个材质函数,只在需要的材质里引用,别全局挂在母材质上。还有一个容易忽略的:Height Map Channel 如果是参数化选择的,也会产生变体,直接写死成常量。
6. 进阶:分层材质里的视差与一套可复用的验收流程
单层视差调通了只是入门,真正吃性能的地方在分层材质——一套墙面材质里混砖、石、木三种表面,每种都要各自的视差。
做法是给每一层单独算视差 UV,用高度图的通道区分层高,然后按混合权重做加权。这里有个原则:只对权重最高的那一层跑完整 POM,其他层用 BumpOffset,最后按权重 lerp。全层全步进是性能杀手,而且视觉上看不出差别。层间混合的边界处,两套视差 UV 差值过大时会出现接缝撕裂,处理办法是在混合区把偏移量整体 lerp 到 0,让过渡区域退回平面。
| 场景类型 | 路线 | Height Ratio | Max Steps | PDO | Nanite |
|---|---|---|---|---|---|
| 远景墙面 | BumpOffset | 0.02 | — | 关 | 可开 |
| 可走近的砖墙 | POM | 0.06 | 32 | 开 | 关 |
| 地面石材 | POM | 0.04 | 24 | 开 | 关 |
| 移动端墙面 | BumpOffset | 0.02 | — | 关 | 关 |
| 家具边缘雕花 | 真几何 | — | — | — | 视情况 |
验收我固定走三个角度:正前方 1 米、侧 30 度 1 米、侧 60 度 3 米。第一个看层高是否自然,第二个看步进台阶有没有露出来,第三个看有没有噪点和 mip 问题。三个角度都过,再放到实际光照环境里看 Lumen 的表现。参数改一次就重跑一遍,别偷懒。
从那以后我每次接手视差材质,都强制先跑一遍这套验收,尤其是侧 60 度那一档——十次翻车有七次是在这个角度暴露的,而玩家在场景里走动时,恰恰最常出现在这个视角。希望帮到你。
本文还有配套的精品资源,点击获取