news 2026/6/23 15:31:35

【URP】Unity[视差遮挡贴图]原理剖析实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【URP】Unity[视差遮挡贴图]原理剖析实践

视差遮挡贴图(Parallax Occlusion Mapping, POM)介绍

视差遮挡贴图是视差贴图技术的高阶实现,通过‌光线步进(Raymarching)算法‌精确计算视线与高度图的交点,模拟复杂表面(如砖墙、岩石)的几何遮挡效果。相比标准视差贴图,POM能更真实地表现深度变化和自阴影,适用于高精度材质表现。

核心原理

‌分层深度检测‌将视线方向在切线空间分解为多层(通常8-15层),逐层采样高度图,通过二分法逼*视线与表面的交点。

‌动态采样优化‌根据视角与法线的夹角动态调整采样层数(**行视角增加层数,垂直视角减少层数),*衡精度与性能。

‌遮挡关系重建‌通过交点处的UV偏移修正纹理采样位置,模拟凹凸表面的光线遮挡效果。

Unity URP 实现示例与原理详解

代码关键点解析

‌动态采样层数‌

通过lerp(_MaxSamples, _MinSamples, saturate(dot(float3(0,0,1), viewDirTS)))实现视角自适应分层,优化性能。

‌光线步进循环‌

循环比较当前层高度与采样深度,找到首个交点区间,避免全精度遍历。

‌二分法优化‌

在初步交点区间内使用lerp插值计算精确UV,减少采样次数。

ParallaxOcclusionMapping.shader

Shader "Universal Render Pipeline/POM"

{

Properties

{

_MainTex("Albedo", 2D) = "white" {}

_NormalMap("Normal Map", 2D) = "bump" {}

_HeightMap("Height Map", 2D) = "white" {}

_ParallaxScale("Height Scale", Range(0, 0.1)) = 0.05

_MinSamples("Min Samples", Int) = 8

_MaxSamples("Max Samples", Int) = 15

}

SubShader

{

Tags { "RenderPipeline"="UniversalPipeline" }

HLSLINCLUDE

#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);

TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap);

TEXTURE2D(_HeightMap); SAMPLER(sampler_HeightMap);

float _ParallaxScale;

int _MinSamples, _MaxSamples;

float2 ParallaxOcclusionMapping(float3 viewDirTS, float2 uv)

{

// 动态计算采样层数

int numSamples = (int)lerp(_MaxSamples, _MinSamples, saturate(dot(float3(0,0,1), viewDirTS)));

float layerHeight = 1.0 / numSamples;

float2 deltaUV = _ParallaxScale * viewDirTS.xy / viewDirTS.z / numSamples;

// 光线步进初始化

float currentLayerHeight = 0;

float2 currentUV = uv;

float currentDepth = 1 - SAMPLE_TEXTURE2D(_HeightMap, sampler_HeightMap, currentUV).r;

// 分层检测

[loop]

for (int i = 0; i < 15; ++i) {

if (currentLayerHeight >= currentDepth) break;

currentUV -= deltaUV;

currentDepth = 1 - SAMPLE_TEXTURE2D(_HeightMap, sampler_HeightMap, currentUV).r;

currentLayerHeight += layerHeight;

}

// 二分法精确交点

float2 prevUV = currentUV + deltaUV;

float prevDepth = currentDepth - layerHeight;

float weight = (currentLayerHeight - currentDepth) / (prevDepth - currentDepth);

return lerp(currentUV, prevUV, weight);

}

ENDHLSL

Pass

{

HLSLPROGRAM

#pragma vertex vert

#pragma fragment frag

struct Attributes

{

float4 positionOS : POSITION;

float2 uv : TEXCOORD0;

float3 normalOS : NORMAL;

float4 tangentOS : TANGENT;

};

struct Varyings

{

float4 positionCS : SV_POSITION;

float2 uv : TEXCOORD0;

float3 viewDirTS : TEXCOORD1;

};

Varyings vert(Attributes IN)

{

Varyings OUT;

VertexPositionInputs posInput = GetVertexPositionInputs(IN.positionOS.xyz);

OUT.positionCS = posInput.positionCS;

// 转换视角方向到切线空间

VertexNormalInputs normInput = GetVertexNormalInputs(IN.normalOS, IN.tangentOS);

float3 viewDirWS = GetWorldSpaceViewDir(posInput.positionWS);

OUT.viewDirTS = TransformWorldToTangent(viewDirWS,

normInput.tangentWS, normInput.bitangentWS, normInput.normalWS);

OUT.uv = IN.uv;

return OUT;

}

half4 frag(Varyings IN) : SV_Target

{

// 计算POM偏移后的UV

float2 pomUV = ParallaxOcclusionMapping(normalize(IN.viewDirTS), IN.uv);

// 采样最终纹理

half4 albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, pomUV);

half3 normalTS = UnpackNormal(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, pomUV));

return half4(albedo.rgb, 1);

}

ENDHLSL

}

}

}

技术对比与性能建议

特性 标准视差贴图 陡峭视差贴图 POM

‌采样次数‌ 单次 5-15次 8-15次+二分法

‌陡峭表面精度‌ 低 中 高

‌适用*台‌ 移动端 PC/主机 高端PC

‌推荐参数‌ Scale=0.02 Scale=0.05 Scale=0.03-0.07

实际应用中需注意:

高度图建议使用法线贴图的Alpha通道节省资源

过高的_ParallaxScale可能导致边缘拉伸,建议不超过0.1

移动端可减少_MaxSamples至8层以降低开销

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/22 4:26:39

计算机Java毕设实战-基于springboot的汽车租赁买卖管理系统的设计与实现入库录入、租赁登记、租赁状态查询【完整源码+LW+部署说明+演示视频,全bao一条龙等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/6/23 9:40:32

华为OD机考双机位C卷 - 编程能力提升计划 (Java Python JS C/C++ GO )

最新华为上机考试 真题目录:点击查看目录 华为OD面试真题精选:点击立即查看 华为OD机考双机位C卷 题目描述 为了提升软件编码能力,小王制定了刷题计划,他选了题库中的n道题,编号从0到n-1,并计划在m天内按照题目编号顺序刷完所有的题目(注意,小王不能用多天完成同一…

作者头像 李华
网站建设 2026/6/23 5:23:46

ORACLE检查并创建表空间和表分区

为确保系统在高并发、大数据量环境下的稳定高效运行&#xff0c;要求建立完善的表空间与表分区管理机制&#xff0c;具体包括&#xff1a;定期检查表空间使用率&#xff0c;及时发现并处理空间不足风险&#xff1b;建立分区自动创建与维护流程&#xff0c;防止因分区缺失导致的…

作者头像 李华
网站建设 2026/6/22 10:23:42

港媒盛赞“香港媳妇”徐冬冬!婚照惊艳全网,港圈作品圈粉无数

12月18日&#xff0c;徐冬冬与尹子维的婚纱照强势空降热搜&#xff0c;甜酷兼具的造型让网友直呼美貌惊艳&#xff0c;气质独一份。从戏里媚骨天成的“大嫂”到戏外被港媒追捧的“香港媳妇”&#xff0c;这位东北大妞不仅用八年分合的爱情故事打动人心&#xff0c;更在港娱圈深…

作者头像 李华
网站建设 2026/6/22 13:05:05

Redis高级特性与生产环境部署

Redis高级特性与生产环境部署实践一、Redis核心数据类型深度解析1.1 哈希&#xff08;Hash&#xff09;类型详解1.1.1 哈希数据结构# 哈希结构示意图 key: "user:1001" value: {"name": "张三","age": 25,"city": "北京…

作者头像 李华
网站建设 2026/6/17 13:34:33

java计算机毕业设计网咖会员管理系统 电竞馆会员计费与点餐一体化平台 网吧会员上机充值及订单管理系统

计算机毕业设计网咖会员管理系统67kvh9&#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。疫情后电竞消费井喷&#xff0c;传统网吧前台手工登记、纸质充值券、Excel对账的模式已无法…

作者头像 李华