大乔炮台shader修复

This commit is contained in:
Game
2026-05-08 18:01:36 +08:00
parent c3586de20e
commit 7dc8346014
4 changed files with 205 additions and 242 deletions
@@ -1,27 +1,5 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1101 &-3783248633044409505
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions: []
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 2396006443845923745}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0.25
m_TransitionOffset: 0
m_ExitTime: 0.875
m_HasExitTime: 1
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!91 &9100000
AnimatorController:
m_ObjectHideFlags: 0
@@ -484,7 +462,6 @@ AnimatorState:
m_CycleOffset: 0
m_Transitions:
- {fileID: 1101597724011292661}
- {fileID: -3783248633044409505}
m_StateMachineBehaviours: []
m_Position: {x: 0, y: 0, z: 0}
m_IKOnFeet: 0
@@ -542,7 +519,7 @@ AnimatorStateMachine:
m_Position: {x: 0, y: 0, z: 0}
- serializedVersion: 1
m_State: {fileID: 2396006443845923745}
m_Position: {x: 160, y: 80, z: 0}
m_Position: {x: 250, y: 30, z: 0}
m_ChildStateMachines: []
m_AnyStateTransitions: []
m_EntryTransitions: []
@@ -31,180 +31,57 @@ Shader "Boke/QianPao/Addmul_Fresnel_Rim" {
[Enum(UnityEngine.Rendering.StencilOp)] _StencilFailOp ("StenciFailOp(模板测试失败时的操作)", Float) = 0
}
//DummyShaderTextExporter
SubShader {
// 针对 URP 和特效 Shader 的标签设置
Tags {
"RenderPipeline" = "UniversalPipeline"
"RenderType" = "Transparent"
"Queue" = "Transparent"
"IgnoreProjector" = "True"
}
LOD 200
SubShader{
Tags { "RenderType"="Opaque" }
LOD 200
Pass {
Name "ForwardLit"
// 绑定材质面板传入的渲染状态
Cull [__CullMode]
ZWrite [__ZWrite]
ZTest [__ZTest]
// 特效常用的透明混合模式 (SrcAlpha OneMinusSrcAlpha)
// 如果你的特效需要叠加高亮,可以改为 Blend SrcAlpha One
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
Stencil {
Ref [_StencilRef]
Comp [_StencilComp]
Pass [_StencilPassOp]
Fail [_StencilFailOp]
}
float4x4 unity_ObjectToWorld;
float4x4 unity_MatrixVP;
float4 _MainTex_ST;
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
// 启用特性变体
#pragma shader_feature_local _MAINTEX_A_ON
#pragma shader_feature_local _RIM_ON
struct Vertex_Stage_Input
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
// 引入 URP 核心库
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Vertex_Stage_Output
{
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
};
// ========== 输入输出结构体 ==========
struct Attributes {
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
float3 normalOS : NORMAL; // 法线信息,用于计算菲涅尔和Rim
float4 color : COLOR; // 顶点色,特效粒子必备
};
Vertex_Stage_Output vert(Vertex_Stage_Input input)
{
Vertex_Stage_Output output;
output.uv = (input.uv.xy * _MainTex_ST.xy) + _MainTex_ST.zw;
output.pos = mul(unity_MatrixVP, mul(unity_ObjectToWorld, input.pos));
return output;
}
struct Varyings {
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
float3 normalWS : NORMAL;
float3 viewDirWS : TEXCOORD1;
float4 color : COLOR;
};
Texture2D<float4> _MainTex;
SamplerState sampler_MainTex;
float4 _Color;
// ========== 纹理与采样器声明 ==========
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D(_Noise); SAMPLER(sampler_Noise);
struct Fragment_Stage_Input
{
float2 uv : TEXCOORD0;
};
// ========== CBUFFER (支持 SRP Batcher 优化) ==========
CBUFFER_START(UnityPerMaterial)
float4 _EmissionColor;
float _AlphaCutoff;
float4 _Color;
float4 _MainTex_ST;
float _qd;
float _opacity;
float _Main_Tex_speed_x;
float _Main_Tex_speed_y;
float4 _Noise_ST;
float _Noise_qd_x;
float _Noise_qd_y;
float _Noise_speed_x;
float _Noise_speed_y;
float4 frag(Fragment_Stage_Input input) : SV_TARGET
{
return _MainTex.Sample(sampler_MainTex, input.uv.xy) * _Color;
}
float4 _Fresnel_Color;
float _Fresnel_qd;
float _Scale;
float _Power;
float3 _RimViewDirOffsetXYZ;
float _RimRange;
float _RimHardness;
CBUFFER_END
// ========== 顶点着色器 ==========
Varyings vert(Attributes input) {
Varyings output;
// 坐标转换
VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
output.positionCS = vertexInput.positionCS;
// 传递世界空间法线与视角方向
output.normalWS = TransformObjectToWorldNormal(input.normalOS);
output.viewDirWS = GetWorldSpaceNormalizeViewDir(vertexInput.positionWS);
// 传递基础 UV 与顶点色
output.uv = input.uv;
output.color = input.color;
return output;
}
// ========== 片元着色器 ==========
half4 frag(Varyings input) : SV_TARGET {
// 标准化法线与视口向量
float3 normalWS = normalize(input.normalWS);
float3 viewDirWS = normalize(input.viewDirWS);
// ---------------- 1. 噪波扭曲计算 (Distortion) ----------------
// 计算噪波 UV 与流速
float2 noiseUV = input.uv * _Noise_ST.xy + _Noise_ST.zw;
noiseUV += float2(_Noise_speed_x, _Noise_speed_y) * _Time.y;
// 采样噪波图 (使用 rg 通道计算偏移方向,减去0.5使偏移居中于 -0.5 到 0.5)
half4 noiseCol = SAMPLE_TEXTURE2D(_Noise, sampler_Noise, noiseUV);
float2 uvOffset = (noiseCol.rg - 0.5) * float2(_Noise_qd_x, _Noise_qd_y);
// ---------------- 2. 主贴图计算 ----------------
// 计算主贴图 UV 与流速,并加上噪波偏移
float2 mainUV = input.uv * _MainTex_ST.xy + _MainTex_ST.zw;
mainUV += float2(_Main_Tex_speed_x, _Main_Tex_speed_y) * _Time.y;
mainUV += uvOffset;
half4 mainCol = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, mainUV);
// 主贴图 Alpha 开关逻辑
half texAlpha = 1.0;
#if defined(_MAINTEX_A_ON)
texAlpha = mainCol.a;
#endif
// 基础颜色融合:贴图色 * 材质色 * 顶点色 * 整体强度
half4 baseColor = mainCol * _Color * input.color * _qd;
// ---------------- 3. 菲涅尔边缘光 (Fresnel) ----------------
float NdotV = saturate(dot(normalWS, viewDirWS));
// 菲涅尔公式:(Scale - NdotV)^Power * 强度
float fresnelFactor = pow(max(0.0, _Scale - NdotV), _Power) * _Fresnel_qd;
half3 fresnelColor = _Fresnel_Color.rgb * fresnelFactor * _Fresnel_Color.a;
// ---------------- 4. 新边缘光 (Rim Light) ----------------
half3 rimColor = half3(0, 0, 0);
#if defined(_RIM_ON)
// 加上视口偏移向量
float3 offsetViewDir = normalize(viewDirWS + _RimViewDirOffsetXYZ);
float rimNdotV = saturate(dot(normalWS, offsetViewDir));
// Rim 公式与硬度计算
float rimFactor = 1.0 - rimNdotV;
rimFactor = pow(rimFactor, _RimHardness) * _RimRange;
// 假设面板中隐藏的 _EmissionColor 是专供 Rim 使用的
rimColor = _EmissionColor.rgb * rimFactor;
#endif
// ---------------- 5. 最终混合与输出 ----------------
// 合并 RGB 通道
half3 finalRGB = baseColor.rgb + fresnelColor + rimColor;
// 计算最终 Alpha:基础色Alpha * 贴图Alpha * 全局不透明度缩放
half finalAlpha = baseColor.a * texAlpha * _opacity;
// 透明度测试 (Alpha Cutoff)
clip(finalAlpha - _AlphaCutoff);
return half4(finalRGB, finalAlpha);
}
ENDHLSL
}
}
// 降级处理
Fallback "Hidden/InternalErrorShader"
ENDHLSL
}
}
Fallback "Hidden/InternalErrorShader"
//CustomEditor "UnityEditor.ShaderGraph.PBRMasterGUI"
}
@@ -4,6 +4,8 @@ Shader "Boke/Addmul_niuqu" {
[HideInInspector] _AlphaCutoff ("Alpha Cutoff ", Range(0, 1)) = 0.5
_Color ("Color", Vector) = (1,1,1,1)
_MainTex ("Main Tex", 2D) = "white" {}
_MainTexRotater ("MainTexRotater", Range(0, 360)) = 0
_MainTexRotateSpeed ("MainTexRotateSpeed", Float) = 0
_Main_Desaturate ("Main_Desaturate", Range(0, 1)) = 0
_qd ("qd", Float) = 0
_opacity ("opacity", Float) = 0
@@ -15,9 +17,13 @@ Shader "Boke/Addmul_niuqu" {
_Noise_speed_x ("Noise_speed_x", Float) = 0
_Noise_speed_y ("Noise_speed_y", Float) = 0
_Mask ("Mask", 2D) = "white" {}
_MaskRotator ("MaskRotator", Range(0, 360)) = 0
_MaskRotateSpeed ("MaskRotateSpeed", Float) = 0
_Mask_speed_x ("Mask_speed_x", Float) = 0
_Mask_speed_y ("Mask_speed_y", Float) = 0
_Mask2 ("Mask2", 2D) = "white" {}
_Mask2Rotator ("Mask2Rotator", Range(0, 360)) = 0
_Mask2RotateSpeed ("Mask2RotateSpeed", Float) = 0
_Mask2_speed_x ("Mask2_speed_x", Float) = 0
_Mask2_speed_y ("Mask2_speed_y", Float) = 0
[Enum(Off,0,Front,1,Back,2)] __CullMode ("CullMode(Back时背面看不见,Off时双面可见)", Float) = 0
@@ -27,14 +33,16 @@ Shader "Boke/Addmul_niuqu" {
[Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp ("StencilComp(模板测试的比较方法)", Float) = 0
[Enum(UnityEngine.Rendering.StencilOp)] _StencilPassOp ("StenciPassOp(模板测试成功时的操作)", Float) = 0
[Enum(UnityEngine.Rendering.StencilOp)] _StencilFailOp ("StenciFailOp(模板测试失败时的操作)", Float) = 0
[Toggle(UNITY_UI_CLIP_RECT)] _UNITY_UI_CLIP_RECT ("启用粒子遮罩", Float) = 0
}
//DummyShaderTextExporter
SubShader
{
// URP 透明特效标签
Tags
{
"RenderType" = "TransparentCutout"
"Queue" = "AlphaTest"
"RenderType" = "Transparent"
"Queue" = "Transparent"
"RenderPipeline" = "UniversalPipeline"
"IgnoreProjector" = "True"
}
@@ -42,13 +50,16 @@ Shader "Boke/Addmul_niuqu" {
Pass
{
Name "Forward"
Name "ForwardUnlit"
Tags { "LightMode" = "UniversalForward" }
Cull [_CullMode]
ZWrite [_ZWrite]
ZTest [_ZTest]
// 渲染状态
Cull [__CullMode]
ZWrite [__ZWrite]
ZTest [__ZTest]
Blend SrcAlpha OneMinusSrcAlpha // 标准透明混合
// 模板测试
Stencil
{
Ref [_StencilRef]
@@ -60,99 +71,197 @@ Shader "Boke/Addmul_niuqu" {
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.5
// 开关:Unity UI 裁剪矩形
#pragma shader_feature_local UNITY_UI_CLIP_RECT
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D(_Noise); SAMPLER(sampler_Noise);
TEXTURE2D(_Mask); SAMPLER(sampler_Mask);
TEXTURE2D(_Mask2); SAMPLER(sampler_Mask2);
// ----------------------------------------------
// 纹理和采样器声明(SRP Batcher 兼容)
// ----------------------------------------------
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D(_Noise); SAMPLER(sampler_Noise);
TEXTURE2D(_Mask); SAMPLER(sampler_Mask);
TEXTURE2D(_Mask2); SAMPLER(sampler_Mask2);
// ----------------------------------------------
// 材质属性缓冲区
// ----------------------------------------------
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
float4 _Color;
float4 _MainTex_ST;
float _MainTexRotater;
float _MainTexRotateSpeed;
float _Main_Desaturate;
float _qd;
float _opacity;
float _Main_Tex_speed_x;
float _Main_Tex_speed_y;
float4 _Noise_ST;
float _Noise_qd_x;
float _Noise_qd_y;
float _Noise_speed_x;
float _Noise_speed_y;
float4 _Mask_ST;
float _MaskRotator;
float _MaskRotateSpeed;
float _Mask_speed_x;
float _Mask_speed_y;
float4 _Mask2_ST;
float _Mask2Rotator;
float _Mask2RotateSpeed;
float _Mask2_speed_x;
float _Mask2_speed_y;
float _AlphaCutoff;
CBUFFER_END
// UI 裁剪矩形(需要时由外部脚本传入)
#ifdef UNITY_UI_CLIP_RECT
float4 _ClipRect;
#endif
// ----------------------------------------------
// 顶点输入结构
// ----------------------------------------------
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
float2 uv : TEXCOORD0;
float4 color : COLOR; // 顶点颜色(可选)
};
// ----------------------------------------------
// 顶点输出结构
// ----------------------------------------------
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uv : TEXCOORD0;
float4 color : COLOR;
#ifdef UNITY_UI_CLIP_RECT
float2 worldPosition : TEXCOORD1;
#endif
};
Varyings vert(Attributes IN)
// ==========================================
// 辅助函数:UV 旋转(绕中心点 0.5,0.5)
// ==========================================
float2 RotateUV(float2 uv, float angleDegrees)
{
Varyings OUT;
OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz);
OUT.uv = IN.uv;
return OUT;
float rad = radians(angleDegrees);
float s, c;
sincos(rad, s, c);
float2 centered = uv - 0.5;
float2 rotated;
rotated.x = centered.x * c - centered.y * s;
rotated.y = centered.x * s + centered.y * c;
return rotated + 0.5;
}
float4 frag(Varyings IN) : SV_Target
// ==========================================
// 顶点着色器
// ==========================================
Varyings vert(Attributes input)
{
Varyings output;
// 标准顶点变换
VertexPositionInputs posInput = GetVertexPositionInputs(input.positionOS.xyz);
output.positionCS = posInput.positionCS;
// 传递 UV(应用主纹理的 Tiling/Offset)
output.uv = TRANSFORM_TEX(input.uv, _MainTex);
// 传递顶点颜色
output.color = input.color;
#ifdef UNITY_UI_CLIP_RECT
// 世界空间位置(用于裁剪矩形)
output.worldPosition = posInput.positionWS.xy;
#endif
return output;
}
// ==========================================
// 片段着色器(实现金粉扭曲特效)
// ==========================================
half4 frag(Varyings input) : SV_Target
{
// ************ 1. 基础 UV 和全局时间 ************
float2 baseUV = input.uv;
float time = _Time.y;
// 1. 主纹理 UV(Tiling/Offset + 滚动)
float2 mainUV = IN.uv * _MainTex_ST.xy + _MainTex_ST.zw;
mainUV += float2(_Main_Tex_speed_x, _Main_Tex_speed_y) * time;
// ************ 2. Noise 纹理采样:用于产生扭曲偏移 ************
// Noise UV 流动
float2 noiseUV = TRANSFORM_TEX(baseUV, _Noise);
noiseUV.x += time * _Noise_speed_x;
noiseUV.y += time * _Noise_speed_y;
half4 noiseTex = SAMPLE_TEXTURE2D(_Noise, sampler_Noise, noiseUV);
// 将 [0,1] 映射到 [-1,1],并乘以强度系数
float2 distortion = float2(
(noiseTex.r - 0.5) * 2.0 * _Noise_qd_x,
(noiseTex.g - 0.5) * 2.0 * _Noise_qd_y
);
// 2. 噪声扭曲 (niuqu)
// 噪声使用自定义平铺值,滚动速度
float2 noiseUV = IN.uv * float2(_Noise_qd_x, _Noise_qd_y)
+ float2(_Noise_speed_x, _Noise_speed_y) * time;
float4 noise = SAMPLE_TEXTURE2D(_Noise, sampler_Noise, noiseUV);
// RG 解码为方向向量 [-1,1]
float2 twistDir = noise.rg * 2.0 - 1.0;
// ************ 3. 主纹理 UV 处理(旋转 + 流动 + 扭曲)************
// 旋转角度随时间变化
float mainRotateAngle = _MainTexRotater + time * _MainTexRotateSpeed;
float2 mainUV = RotateUV(baseUV, mainRotateAngle);
// 流动
mainUV.x += time * _Main_Tex_speed_x;
mainUV.y += time * _Main_Tex_speed_y;
// 叠加扭曲偏移
mainUV += twistDir * _qd;
mainUV += distortion;
// 3. 采样主纹理并调制颜色
float4 mainTex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, mainUV);
float4 color = mainTex * _Color;
// 采样主纹理
half4 mainColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, mainUV);
// 4. 去饱和度
float gray = dot(color.rgb, float3(0.299, 0.587, 0.114));
color.rgb = lerp(color.rgb, gray, _Main_Desaturate);
// ************ 4. 去饱和度处理 ************
half gray = dot(mainColor.rgb, half3(0.299, 0.587, 0.114));
half3 desaturatedColor = lerp(mainColor.rgb, gray, _Main_Desaturate);
// 5. 遮罩1
float2 maskUV = IN.uv + float2(_Mask_speed_x, _Mask_speed_y) * time;
float mask1 = SAMPLE_TEXTURE2D(_Mask, sampler_Mask, maskUV).r;
// ************ 5. Mask(第一层遮罩)处理 ************
// Mask UV:旋转 + 流动
float maskRotateAngle = _MaskRotator + time * _MaskRotateSpeed;
float2 maskUV = RotateUV(baseUV, maskRotateAngle);
maskUV.x += time * _Mask_speed_x;
maskUV.y += time * _Mask_speed_y;
// 采样 Mask(使用 R 通道作为遮罩值)
half maskValue = SAMPLE_TEXTURE2D(_Mask, sampler_Mask, maskUV).r;
// 6. 遮罩2
float2 mask2UV = IN.uv + float2(_Mask2_speed_x, _Mask2_speed_y) * time;
float mask2 = SAMPLE_TEXTURE2D(_Mask2, sampler_Mask2, mask2UV).r;
// ************ 6. Mask2(第二层遮罩)处理 ************
float mask2RotateAngle = _Mask2Rotator + time * _Mask2RotateSpeed;
float2 mask2UV = RotateUV(baseUV, mask2RotateAngle);
mask2UV.x += time * _Mask2_speed_x;
mask2UV.y += time * _Mask2_speed_y;
half mask2Value = SAMPLE_TEXTURE2D(_Mask2, sampler_Mask2, mask2UV).r;
// 7. 最终 Alpha = 贴图Alpha * 整体不透明度 * 遮罩1 * 遮罩2
float finalAlpha = color.a * _opacity * mask1 * mask2;
// ************ 7. 合并遮罩(相乘)************
half finalMask = maskValue * mask2Value;
// 8. Alpha 裁剪
clip(finalAlpha - _AlphaCutoff);
// ************ 8. 最终颜色与透明度 ************
// 颜色:去饱和后的颜色 * 材质主色 * 整体强度 _qd * 顶点颜色
half3 finalColor = desaturatedColor * _Color.rgb * _qd * input.color.rgb;
// 透明度:主纹理 alpha * 材质 alpha * opacity * 遮罩 * 顶点颜色 alpha
half finalAlpha = mainColor.a * _Color.a * _opacity * finalMask * input.color.a;
// 输出颜色,Alpha 固定为 1
return float4(color.rgb, 1.0);
// ************ 9. UI 裁剪矩形(如果启用)************
#ifdef UNITY_UI_CLIP_RECT
float2 inMask = float2(
step(_ClipRect.x, input.worldPosition.x) * step(input.worldPosition.x, _ClipRect.z),
step(_ClipRect.y, input.worldPosition.y) * step(input.worldPosition.y, _ClipRect.w)
);
finalAlpha *= (inMask.x * inMask.y);
#endif
// 返回结果(透明混合由 Blend 指令自动处理)
return half4(finalColor, finalAlpha);
}
ENDHLSL
}
}
Fallback "Hidden/InternalErrorShader"
// 后备 Shader(确保兼容性)
Fallback "Universal Render Pipeline/Unlit"
}
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: db6be42076013d94a942c294928920db
guid: 4603aa59cfe607d45a659911277b6f1d
timeCreated: 1767110572
licenseType: Free
ShaderImporter: