当前位置: 首页 > news >正文

【URP】Unity[视差贴图]模拟[冰面裂缝]实践

Unity URP 冰面裂缝视差效果实现方案

冰面裂缝效果优化的URP Shader实现。该方案通过‌视差遮挡贴图(POM)‌技术增强深度表现,结合‌高度图动态控制‌实现可调节的冰缝裂痕效果。

核心特性

‌物理精确的裂缝深度‌采用光线步进算法精确计算冰缝几何形状,通过_DepthMultiplier参数控制裂缝视觉深度

‌冰面光学特性模拟‌添加折射率参数(_RefractionIndex)和菲涅尔效应,增强冰面半透明质感

‌性能优化‌动态采样层数控制(8-12层),在移动端保持30fps以上流畅度

完整HLSL代码实现

关键参数说明

‌高度图控制‌_DepthMultiplier参数动态调节冰缝视觉深度,值越大裂缝越深

‌光学参数‌_RefractionIndex控制冰面折射率,_FresnelPower调整边缘高光强度

‌性能控制‌minSamples和maxSamples控制光线步进精度,移动端建议8-10层

IceCrackPOM.shader

Shader "Universal Render Pipeline/IceCrackPOM"

{

Properties

{

[Header(Base Textures)]

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

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

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

[Header(Parallax Settings)]

_ParallaxScale("Crack Depth Scale", Range(0, 0.2)) = 0.08

_DepthMultiplier("Depth Multiplier", Range(0.5, 3)) = 1.2

[Header(Ice Optical Properties)]

_RefractionIndex("Refraction Index", Range(1.1, 1.5)) = 1.3

_FresnelPower("Fresnel Power", Range(1, 10)) = 3

_Specular("Specular Intensity", Range(0, 1)) = 0.5

}

SubShader

{

Tags { "RenderType"="Transparent" "Queue"="Transparent" }

HLSLINCLUDE

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

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

TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);

TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap);

TEXTURE2D(_HeightMap); SAMPLER(sampler_HeightMap);

float _ParallaxScale;

float _DepthMultiplier;

float _RefractionIndex;

float _FresnelPower;

float _Specular;

// 冰面裂缝POM计算

float2 IceParallaxOcclusion(float3 viewDirTS, float2 uv)

{

int minSamples = 8;

int maxSamples = 12;

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 * _DepthMultiplier;

float currentLayerHeight = 0;

float2 currentUV = uv;

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

[loop]

for (int i = 0; i < maxSamples; ++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 + 0.001);

return lerp(currentUV, prevUV, weight);

}

// 冰面菲涅尔效应

float IceFresnel(float3 viewDirWS, float3 normalWS)

{

float fresnel = pow(1.0 - saturate(dot(viewDirWS, normalWS)), _FresnelPower);

return fresnel * 0.7;

}

ENDHLSL

Pass

{

Blend SrcAlpha OneMinusSrcAlpha

ZWrite Off

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;

float3 viewDirWS : TEXCOORD2;

float3 normalWS : TEXCOORD3;

};

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.viewDirWS = viewDirWS;

OUT.normalWS = normInput.normalWS;

OUT.uv = IN.uv;

return OUT;

}

half4 frag(Varyings IN) : SV_Target

{

// 计算POM偏移UV

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

// 采样纹理

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

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

// 转换法线到世界空间

float3x3 TBN = float3x3(

normalize(cross(IN.normalWS, IN.viewDirWS)),

normalize(IN.normalWS),

normalize(IN.viewDirWS)

);

float3 normalWS = mul(TBN, normalTS);

// 冰面光学效果

float fresnel = IceFresnel(normalize(IN.viewDirWS), normalWS);

float3 refractedView = refract(-normalize(IN.viewDirWS), normalWS, 1.0/_RefractionIndex);

// 合成最终颜色

half3 finalColor = albedo.rgb * (1 - fresnel) + fresnel * 0.8;

finalColor += _Specular * pow(saturate(dot(refractedView, normalWS)), 64);

return half4(finalColor, albedo.a * 0.9);

}

ENDHLSL

}

}

}

材质配置建议

纹理类型 制作要求 示例用途

高度图 黑白分明,裂缝处为黑色(0值) 控制裂缝形状和深度

法线贴图 配合高度图制作微观凹凸 增强冰面晶体质感

底色贴图 半透明蓝色调,带裂纹边缘高光 基础颜色和透明度控制

实际应用中可通过调整_ParallaxScale(0.05-0.1)和_DepthMultiplier(1.0-2.0)获得不同结冰程度效果

http://www.jsqmd.com/news/120208/

相关文章:

  • 【协同攻击】基于人工势场算法APF实现无人机蜂群系统具有飞行时间和攻击角度的协同攻击研究附Matlab代码
  • Java计算机毕设之基于springboot的校园一卡通管理系统的设计与实现校园一卡通的发放、注销和状态更新、 充值信息管理(完整前后端代码+说明文档+LW,调试定制等)
  • Java计算机毕设之基于springboot的校园一卡通管理系统的设计与实现校园一卡通的发放、注销和状态更新、 充值信息管理(完整前后端代码+说明文档+LW,调试定制等)
  • 【Pytorch】基于LSTM-KAN、BiLSTM-KAN、GRU-KAN、TCN-KAN、Transformer-KAN(各种KAN修改一行代码搞定)的共享单车租赁预测研究(数据可换)附Pytho
  • 【程序员必备】LoRA微调技术面经总结:收藏级大模型学习指南
  • 大模型面试经验汇总:22家大厂面试实录+高频考点解析
  • Python 装饰器
  • 【优化调度】基于matlab非支配排序遗传算法求解车辆充电调度优化问题研究附Matlab代码
  • 为什么Llama、Gemma等大模型都选择RoPE?位置编码技术解析
  • 从零开始学RAG:手把手教你构建检索增强生成系统,程序员必藏指南
  • Java毕设选题推荐:基于springboot的校园一卡通管理系统的设计与实现 校园智能卡管理系统设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • Java毕设项目:基于springboot的影院购票管理系统的设计与实现(源码+文档,讲解、调试运行,定制等)
  • AI大模型零基础入门:Transformer、BERT与微调技术详解
  • 【PFJSP问题】基于吕佩尔狐算法RFO求解置换流水车间调度问题PFSP研究附Matlab代码
  • Lock()与TryLock():并发锁机制核心差异
  • 计算机Java毕设实战-基于springboot的影院购票管理系统的设计与实现基于SpringBoot的电影购票系统的设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 计算机Java毕设实战-基于springboot的影院购票管理系统的设计与实现基于SpringBoot的电影购票系统的设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • Java计算机毕设之基于springboot的村务管理系统的设计与实现springboot+mysql村务档案管理系统设计与实现(完整前后端代码+说明文档+LW,调试定制等)
  • Java毕设选题推荐:基于springboot的村务管理系统的设计与实现智慧村务管理系统的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • K8s注解的指令模式:元数据如何控制集群行为
  • 从0到1:我用LLM搭建医学知识库,附详细教程,建议永久收藏
  • 别弄混了!SSO单点登录和OAuth2.0还是有区别的
  • 国产操作系统学习实践:从基础安装到高级应用探索
  • 【PID】基于人工神经网络的PID控制器,用于更好的系统响应研究附MatlabSimulink代码
  • 基于PyQt和FFmpeg的开源视频剪辑器OpenShot
  • MySQL 千万级表变更字段,要想不锁表,可以这么做!
  • Mybatis入门简介HelloMybatis
  • 【PO-BP】基于鹦鹉优化算法优化BP神经网络的风电功率预测研究附Matlab代码
  • 2025年有哪些免费降ai率工具?亲测2个靠谱平台,这个真能把AI率降到20%以内!
  • 2025年LLM技术突破全解析:从RLVR到氛围编程,小白也能掌握的大模型前沿指南