材质修改

This commit is contained in:
tianmo committed 2026-10-10 20:12:37 +08:00
1 parent 7c1fedab2c
commit 5d58cb3743
12 files changed
+814 -8

No files matched your search

+264
View File
@@ -0,0 +1,264 @@
// UIMask:UI Mask 粒子/特效 shader —— 加色与普通混合共用一个 shader
//
// 混合模式在材质面板上是一个下拉框 "_BlendMode"(加色 Additive / 普通混合 AlphaBlend)。
// 它由 Assets/Shaders/Editor/UIMaskBlendMode.cs([UIMaskBlendMode] 绘制器)映射到真正的 Blend 状态:
// 加色(Additive): _SrcBlend = 5 (SrcAlpha) _DstBlend = 1 (One)
// 普通混合(AlphaBlend):_SrcBlend = 5 (SrcAlpha) _DstBlend = 10 (OneMinusSrcAlpha)
// 渲染面同理:[UIMaskRenderFace] 下拉映射到隐藏属性 _Cull(双面=0,只渲染后面=1,只渲染前面=2)。
// _SrcBlend / _DstBlend / _Cull 是隐藏属性,由下拉框自动写入,不要手动改。
// Blend 是固定功能状态,不参与 shader 变体表,所以切换混合模式不产生额外变体。
// 面向美术:程序/技术类参数一律用 [HideInInspector] 隐藏(混合模式内部值、Stencil 组、
// 顶点 Mask 翻转),需要时由程序控制,材质面板只留艺术参数。
Shader "VFX/VFX" {
Properties {
[UIMaskBlendMode] _BlendMode ("混合模式", Float) = 0
[HideInInspector] _SrcBlend ("Src Blend", Float) = 5
[HideInInspector] _DstBlend ("Dst Blend", Float) = 1
[UIMaskRenderFace] _RenderFace ("渲染面", Float) = 2
[HideInInspector] _Cull ("Cull", Float) = 0
[HDR]_TintColor ("着色", Color) = (0.5,0.5,0.5,0.5)
_GlowScale("发光强度", float) = 1
_AlphaScale("透明度", float) = 1
_MainTex ("主贴图", 2D) = "white" {}
[Toggle] _UseUvAni("启用", Float) = 0
_SpeedU("U 速度", Float) = 0
_SpeedV("V 速度", Float) = 0
[Toggle] _UseUvDistortion("启用", Float) = 0
_UVNoiseTex("噪声贴图", 2D) = "black" {}
_Distortion ("扰动量", Float) = 0
_NoiseScroll ("噪声滚动 (XY 速度 / ZW 强度)", Vector) = (0,0,1,1)
[Toggle] _UseMask("启用", Float) = 0
[Toggle] _UseMaskUvAni("UV 滚动", Float) = 0
_Mask("遮罩贴图", 2D) = "white" {}
[UIMaskChannel] _MaskChannel("通道", Float) = 3
_MaskSpeedU("U 速度", Float) = 0
_MaskSpeedV("V 速度", Float) = 0
[Toggle] _UseDissolve("启用", Float) = 0
_DissolveTex ("溶解贴图", 2D) = "white" {}
[UIMaskChannel] _DissolveChannel("通道", Float) = 3
_Dissolve ("溶解进度", Range(0, 1.01)) = 0
_DissolveWidth ("溶解宽度", Range(0, 1)) = 0
[Toggle] _UseUIMaskClip("启用", Float) = 0
_ClipRect("裁切矩形 (由 Mask / RectMask2D 控制)", Vector) = (-1, -1, 1, 1)
[Toggle] _UseVertexMask("启用", Float) = 0
_VertexOffset ("方向与范围", Vector) = (0,0,1,1)
// 程序专用:顶点 Mask 的翻转,由程序设置
[HideInInspector] _VertexFlipX ("程序专用", Float) = 1
// required for UI.Mask —— 这几个由 Unity 的 Mask / RectMask2D 在运行时写入,不需要美术看到
[HideInInspector] _StencilComp("Stencil Comparison", Float) = 8
[HideInInspector] _Stencil("Stencil ID", Float) = 0
[HideInInspector] _StencilOp("Stencil Operation", Float) = 0
[HideInInspector] _StencilWriteMask("Stencil Write Mask", Float) = 255
[HideInInspector] _StencilReadMask("Stencil Read Mask", Float) = 255
[HideInInspector] _ColorMask("Color Mask", Float) = 15
}
CustomEditor "UIMaskShaderGUI"
Category {
Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" }
Blend [_SrcBlend][_DstBlend]
Cull [_Cull] Lighting Off ZWrite Off
SubShader {
Stencil
{
Ref[_Stencil]
Comp[_StencilComp]
Pass[_StencilOp]
ReadMask[_StencilReadMask]
WriteMask[_StencilWriteMask]
}
ColorMask[_ColorMask]
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
// 全部使用 shader_feature(按材质用到的组合裁剪),不要改成 multi_compile
#pragma shader_feature _USEMASK_ON
#pragma shader_feature _USEMASKUVANI_ON
#pragma shader_feature _USEUVANI_ON
#pragma shader_feature _USEUVDISTORTION_ON
#pragma shader_feature _USEDISSOLVE_ON
#pragma shader_feature _USEUIMASKCLIP_ON
#pragma shader_feature _USEVERTEXMASK_ON
// 不声明 multi_compile_fog:UNITY_FOG_* 宏在无雾关键字时展开为空,
// 原来的"_UseReceiveFog"开关勾了也不会有任何效果,故已移除。
#include "UnityCG.cginc"
#include "UnityUI.cginc"
sampler2D _MainTex;
fixed4 _TintColor;
#if _USEMASK_ON
sampler2D _Mask;
fixed4 _Mask_ST;
float _MaskChannel;
#if _USEMASKUVANI_ON
float _MaskSpeedU;
float _MaskSpeedV;
#endif
#endif
#if _USEUVANI_ON
float _SpeedU;
float _SpeedV;
#endif
#if _USEUVDISTORTION_ON
sampler2D _UVNoiseTex;
fixed4 _UVNoiseTex_ST;
fixed _Distortion;
fixed4 _NoiseScroll;
#endif
#if _USEDISSOLVE_ON
sampler2D _DissolveTex;
fixed4 _DissolveTex_ST;
float _DissolveChannel;
fixed _Dissolve;
fixed _DissolveWidth;
#endif
// 通道选择:0=R 1=G 2=B 3=A。用点乘取通道,避免动态分量索引(SM2.0 不支持)
inline float UIMaskSampleChannel(sampler2D tex, float2 uv, float channel)
{
float4 c = tex2D(tex, uv);
float4 w = 1.0 - saturate(abs(channel - float4(0.0, 1.0, 2.0, 3.0)));
return dot(c, w);
}
#if _USEUIMASKCLIP_ON
fixed4 _ClipRect;
#endif
#if _USEVERTEXMASK_ON
fixed4 _VertexOffset;
fixed _VertexFlipX;
#endif
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
fixed4 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
fixed4 texcoord : TEXCOORD0;
#if _USEMASK_ON
fixed2 texcoordMask : TEXCOORD2;
#endif
#if _USEUVDISTORTION_ON
fixed2 texcoordNoise : TEXCOORD3;
#endif
#if _USEDISSOLVE_ON
fixed2 texcoordDissolve: TEXCOORD4;
#endif
#if _USEUIMASKCLIP_ON
fixed4 worldPosition : TEXCOORD5;
#endif
#if _USEVERTEXMASK_ON
fixed4 vertex2 : TEXCOORD7;
#endif
UNITY_VERTEX_OUTPUT_STEREO
};
fixed4 _MainTex_ST;
fixed _GlowScale;
fixed _AlphaScale;
v2f vert (appdata_t v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.vertex = UnityObjectToClipPos(v.vertex);
o.color = v.color * _TintColor;
o.texcoord.xy = TRANSFORM_TEX(v.texcoord,_MainTex);
o.texcoord.zw = v.texcoord.zw;
#if _USEMASK_ON
o.texcoordMask = TRANSFORM_TEX(v.texcoord,_Mask);
#endif
#if _USEUVDISTORTION_ON
o.texcoordNoise = TRANSFORM_TEX(v.texcoord,_UVNoiseTex);
#endif
#if _USEDISSOLVE_ON
o.texcoordDissolve = TRANSFORM_TEX(v.texcoord,_DissolveTex);
#endif
#if _USEUIMASKCLIP_ON
o.worldPosition = mul(unity_ObjectToWorld, v.vertex);
#endif
#if _USEVERTEXMASK_ON
o.vertex2 = v.vertex;
#endif
return o;
}
fixed4 frag (v2f i) : SV_Target
{
#if _USEUVANI_ON
// 用 _Time.y(float)而不是 _Time.g(fixed):运行久了 fixed 精度不足会出现像素块/卡顿
i.texcoord.xy += _Time.y * float2(_SpeedU, _SpeedV);
#endif
#if _USEUVDISTORTION_ON
float2 noiseScrollXY = _NoiseScroll.xy;
i.texcoordNoise += fixed2(_Time.g * noiseScrollXY);
i.texcoord.xy += tex2D(_UVNoiseTex, i.texcoordNoise).xy*_Distortion*_NoiseScroll.zw;
#endif
fixed4 col = 2.0f * i.color * tex2D(_MainTex, i.texcoord.xy);
col.rgb *= _GlowScale;
col.a = saturate(col.a) * _AlphaScale;
#if _USEMASK_ON
#if _USEMASKUVANI_ON
i.texcoordMask += _Time.y * float2(_MaskSpeedU, _MaskSpeedV);
#endif
col.a = saturate(col.a * UIMaskSampleChannel(_Mask, i.texcoordMask, _MaskChannel));
#endif
#if _USEDISSOLVE_ON
fixed DissolveWithParticle =(_Dissolve*(1-i.texcoord.z)*(1+_DissolveWidth)-_DissolveWidth) ;
fixed dissolveMap = UIMaskSampleChannel(_DissolveTex, i.texcoordDissolve, _DissolveChannel);
fixed dissolveAlpha = saturate(smoothstep( DissolveWithParticle, (DissolveWithParticle+_DissolveWidth), dissolveMap));
col.a *= dissolveAlpha;
#endif
#if _USEUIMASKCLIP_ON
col.a *= UnityGet2DClipping(i.worldPosition.xy, _ClipRect);
#endif
#if _USEVERTEXMASK_ON
col.a *= smoothstep(1, 0, ((i.vertex2.x - _VertexOffset.x) * _VertexOffset.z + (i.vertex2.y - _VertexOffset.y) * _VertexOffset.w) * _VertexFlipX);
#endif
return col;
}
ENDCG
}
}
}
}