Files
2026-07-04 01:48:39 +08:00

157 lines
5.8 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Shader "IndianOcean/AbyssBuilding"
{
// 深渊边缘建筑 Shader v2
//
// 改进(vs v1):
// 1. 世界坐标 Y 替代 UV.y —— 所有建筑在同一世界高度被吞,不受尺寸/Pivot/动画影响
// 2. 颜色和 Alpha 一起渐变 —— 黑暗"侵蚀"进去,而不是硬切
// 3. 噪声扰动吞没线 —— 边缘破碎,不是直线
// 4. 边缘侵蚀发光 —— 过渡带泛幽光,和 AbyssEdgeGlow 衔接
//
// Queue = Transparent(在 DarknessOverlay 之前渲染)
// DarknessOverlay 乘法遮罩控制最终可见性
//
// 搭配:
// - AbyssEdgeGlowQueue +200)放地图断层处
// - AbyssGlowParticleQueue +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
}