溶解效果 (Dissolve Effect)
使用噪声纹理实现物体消融
📚 原理
溶解效果的核心是使用噪声纹理的灰度值与阈值比较,低于阈值的像素被裁剪。通过动画改变阈值,实现逐渐消失的效果。
💻 代码实现
基础溶解 Shader
// Properties
_DissolveMap("Dissolve Map", 2D) = "white" {}
_DissolveThreshold("Dissolve Threshold", Range(0, 1)) = 0
_EdgeWidth("Edge Width", Range(0, 0.1)) = 0.05
_EdgeColor("Edge Color", Color) = (1, 0.5, 0, 1)
// Fragment Shader
half4 frag(Varyings input) : SV_Target
{
// 采样溶解贴图
float dissolveValue = SAMPLE_TEXTURE2D(_DissolveMap, sampler_DissolveMap, input.uv).r;
// 裁剪低于阈值的像素
clip(dissolveValue - _DissolveThreshold);
// 采样基础颜色
half4 baseColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv);
// 边缘发光
float edge = 1 - smoothstep(0, _EdgeWidth, dissolveValue - _DissolveThreshold);
half3 finalColor = lerp(baseColor.rgb, _EdgeColor.rgb, edge);
return half4(finalColor, baseColor.a);
}
完整 Shader 文件结构
Shader "Custom/Dissolve"
{
Properties
{
_BaseMap("Base Map", 2D) = "white" {}
_BaseColor("Base Color", Color) = (1, 1, 1, 1)
_DissolveMap("Dissolve Map", 2D) = "white" {}
_DissolveThreshold("Threshold", Range(0, 1)) = 0
_EdgeWidth("Edge Width", Range(0, 0.2)) = 0.05
_EdgeColor("Edge Color", Color) = (1, 0.5, 0, 1)
}
SubShader
{
Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" }
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
};
TEXTURE2D(_BaseMap);
SAMPLER(sampler_BaseMap);
TEXTURE2D(_DissolveMap);
SAMPLER(sampler_DissolveMap);
CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
half4 _BaseColor;
float _DissolveThreshold;
float _EdgeWidth;
half4 _EdgeColor;
CBUFFER_END
Varyings vert(Attributes input)
{
Varyings output;
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
return output;
}
half4 frag(Varyings input) : SV_Target
{
float dissolve = SAMPLE_TEXTURE2D(_DissolveMap, sampler_DissolveMap, input.uv).r;
clip(dissolve - _DissolveThreshold);
half4 baseColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv) * _BaseColor;
float edge = 1 - smoothstep(0, _EdgeWidth, dissolve - _DissolveThreshold);
half3 finalColor = lerp(baseColor.rgb, _EdgeColor.rgb, edge);
return half4(finalColor, 1);
}
ENDHLSL
}
}
}
🎮 应用场景
💀 角色死亡
敌人被击败后的消失效果
✨ 传送门
物体进入传送门时的溶解
🔥 燃烧效果
配合橙色边缘模拟燃烧
⚡ 数字化
科幻风格的像素化消失
💡 技巧
多层边缘
// 双色边缘 float edge1 = 1 - smoothstep(0, _EdgeWidth, dissolve - _DissolveThreshold); float edge2 = 1 - smoothstep(0, _EdgeWidth * 2, dissolve - _DissolveThreshold); half3 color = baseColor.rgb; color = lerp(color, _EdgeColor2.rgb, edge2); // 外层 color = lerp(color, _EdgeColor1.rgb, edge1); // 内层
方向性溶解
// 从下往上溶解 float dirDissolve = input.positionOS.y * 0.5 + 0.5; // 归一化高度 float finalDissolve = dissolve * dirDissolve; clip(finalDissolve - _DissolveThreshold);