157 lines
5.8 KiB
Plaintext
157 lines
5.8 KiB
Plaintext
Shader "IndianOcean/AbyssBuilding"
|
||
{
|
||
// 深渊边缘建筑 Shader v2
|
||
//
|
||
// 改进(vs v1):
|
||
// 1. 世界坐标 Y 替代 UV.y —— 所有建筑在同一世界高度被吞,不受尺寸/Pivot/动画影响
|
||
// 2. 颜色和 Alpha 一起渐变 —— 黑暗"侵蚀"进去,而不是硬切
|
||
// 3. 噪声扰动吞没线 —— 边缘破碎,不是直线
|
||
// 4. 边缘侵蚀发光 —— 过渡带泛幽光,和 AbyssEdgeGlow 衔接
|
||
//
|
||
// Queue = Transparent(在 DarknessOverlay 之前渲染)
|
||
// DarknessOverlay 乘法遮罩控制最终可见性
|
||
//
|
||
// 搭配:
|
||
// - AbyssEdgeGlow(Queue +200)放地图断层处
|
||
// - AbyssGlowParticle(Queue +200)在深渊里撒粒子
|
||
// - 建筑用此 shader,底部延伸到 _CutoffY 以下
|
||
Properties
|
||
{
|
||
_MainTex ("精灵贴图", 2D) = "white" {}
|
||
_Color ("色调", Color) = (1,1,1,1)
|
||
_CutoffY ("深渊吞没线(世界 Y)", Float) = 0.0
|
||
_Feather ("吞没渐变宽度(世界单位)", Float) = 1.5
|
||
_NoiseScale ("噪声缩放(越大越细碎)", Float) = 3.0
|
||
_NoiseAmount ("噪声强度 (0=直线 1=强烈破碎)", Range(0,1)) = 0.3
|
||
_EdgeColor ("边缘侵蚀色", Color) = (0.15, 0.5, 0.8, 1.0)
|
||
_EdgeIntensity ("边缘亮度", Range(0, 5)) = 1.5
|
||
}
|
||
SubShader
|
||
{
|
||
Tags
|
||
{
|
||
"RenderType" = "Transparent"
|
||
"Queue" = "Transparent"
|
||
"RenderPipeline" = "UniversalPipeline"
|
||
"CanUseSpriteAtlas" = "true"
|
||
}
|
||
Cull Off
|
||
ZWrite Off
|
||
Blend SrcAlpha OneMinusSrcAlpha
|
||
|
||
Pass
|
||
{
|
||
Name "AbyssBuilding"
|
||
HLSLPROGRAM
|
||
#pragma vertex vert
|
||
#pragma fragment frag
|
||
#pragma multi_compile_instancing
|
||
|
||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||
|
||
struct Attributes
|
||
{
|
||
float4 positionOS : POSITION;
|
||
float2 uv : TEXCOORD0;
|
||
float4 color : COLOR;
|
||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||
};
|
||
|
||
struct Varyings
|
||
{
|
||
float4 positionCS : SV_POSITION;
|
||
float2 uv : TEXCOORD0;
|
||
float4 color : COLOR;
|
||
float3 positionWS : TEXCOORD1;
|
||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||
};
|
||
|
||
CBUFFER_START(UnityPerMaterial)
|
||
float4 _MainTex_ST;
|
||
float4 _Color;
|
||
float _CutoffY;
|
||
float _Feather;
|
||
float _NoiseScale;
|
||
float _NoiseAmount;
|
||
float4 _EdgeColor;
|
||
float _EdgeIntensity;
|
||
CBUFFER_END
|
||
|
||
TEXTURE2D(_MainTex);
|
||
SAMPLER(sampler_MainTex);
|
||
|
||
// ---- 简单 2D Value Noise(世界空间一致)----
|
||
float hash21(float2 p)
|
||
{
|
||
p = frac(p * float2(123.34, 456.21));
|
||
p += dot(p, p + 34.345);
|
||
return frac(p.x * p.y);
|
||
}
|
||
|
||
float noise2D(float2 p)
|
||
{
|
||
float2 i = floor(p);
|
||
float2 f = frac(p);
|
||
float a = hash21(i);
|
||
float b = hash21(i + float2(1, 0));
|
||
float c = hash21(i + float2(0, 1));
|
||
float d = hash21(i + float2(1, 1));
|
||
float2 u = f * f * (3.0 - 2.0 * f);
|
||
return lerp(lerp(a, b, u.x), lerp(c, d, u.x), u.y);
|
||
}
|
||
|
||
Varyings vert(Attributes input)
|
||
{
|
||
Varyings output;
|
||
UNITY_SETUP_INSTANCE_ID(input);
|
||
UNITY_TRANSFER_INSTANCE_ID(input, output);
|
||
output.positionWS = TransformObjectToWorld(input.positionOS.xyz);
|
||
output.positionCS = TransformWorldToHClip(output.positionWS);
|
||
output.uv = input.uv;
|
||
output.color = input.color;
|
||
return output;
|
||
}
|
||
|
||
half4 frag(Varyings input) : SV_Target
|
||
{
|
||
half4 tex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv);
|
||
half3 albedo = tex.rgb * input.color.rgb * _Color.rgb;
|
||
half alpha = tex.a * input.color.a * _Color.a;
|
||
|
||
// ---- 世界坐标 Y 做吞没线 ----
|
||
float worldY = input.positionWS.y;
|
||
|
||
// 噪声扰动吞没线高度(基于世界 XZ,跨建筑一致)
|
||
float n = noise2D(input.positionWS.xz * _NoiseScale);
|
||
float noisyCutoff = _CutoffY + (n - 0.5) * _NoiseAmount * _Feather * 2.0;
|
||
|
||
// fade: 0 = 完全被吞, 1 = 完全可见
|
||
float fade = smoothstep(
|
||
noisyCutoff - _Feather,
|
||
noisyCutoff + _Feather,
|
||
worldY
|
||
);
|
||
|
||
// ---- 颜色和 Alpha 一起渐变 ----
|
||
// 黑暗"吃进去"而不是硬切
|
||
half3 finalColor = albedo * fade;
|
||
half finalAlpha = alpha * fade;
|
||
|
||
// ---- 边缘侵蚀发光 ----
|
||
// 在过渡带(fade ≈ 0.1~0.4)泛光,模拟深渊腐蚀边缘
|
||
float edge = smoothstep(0.0, 0.12, fade) * (1.0 - smoothstep(0.12, 0.45, fade));
|
||
finalColor += _EdgeColor.rgb * edge * _EdgeIntensity;
|
||
// 边缘也补一点 Alpha,让发光看得见
|
||
finalAlpha += edge * _EdgeIntensity * 0.3;
|
||
|
||
// 丢弃几乎全透明的像素
|
||
clip(finalAlpha - 0.001);
|
||
|
||
return half4(finalColor, finalAlpha);
|
||
}
|
||
ENDHLSL
|
||
}
|
||
}
|
||
FallBack Off
|
||
}
|