115 lines
4.0 KiB
Plaintext
115 lines
4.0 KiB
Plaintext
Shader "IndianOcean/DarknessOverlay"
|
|
{
|
|
// 黑暗遮罩 Shader v2 —— 乘法混合版(纯黑暗 + 光源,不含回声)
|
|
// 回声描边已独立到 SpriteEchoOutline shader,由 EchoSystem 全局参数驱动。
|
|
//
|
|
// 乘法混合:finalColor = srcColor * dstColor
|
|
// 黑暗区域:sceneColor * 0 = 纯黑(精灵完全看不见)
|
|
// 光照区域:sceneColor * 1 = 原色(完全可见)
|
|
Properties
|
|
{
|
|
_DarknessColor ("黑暗底色(夜间微光色调)", Color) = (0.01, 0.01, 0.02, 1)
|
|
_MinBrightness ("最小亮度(0=纯黑不可见, 0.05=微光)", Range(0, 0.3)) = 0.0
|
|
_LightSoftness ("光线柔和度(边缘渐变宽度)", Range(0.01, 1.0)) = 0.35
|
|
}
|
|
SubShader
|
|
{
|
|
Tags
|
|
{
|
|
"RenderType" = "Transparent"
|
|
"Queue" = "Transparent+100"
|
|
"RenderPipeline" = "UniversalPipeline"
|
|
}
|
|
Blend DstColor Zero
|
|
ZWrite Off
|
|
ZTest Always
|
|
Cull Off
|
|
|
|
Pass
|
|
{
|
|
Name "DarknessOverlay"
|
|
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;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct Varyings
|
|
{
|
|
float4 positionCS : SV_POSITION;
|
|
float2 uv : TEXCOORD0;
|
|
float3 worldPos : TEXCOORD1;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
CBUFFER_START(UnityPerMaterial)
|
|
float4 _DarknessColor;
|
|
float _MinBrightness;
|
|
float _LightSoftness;
|
|
CBUFFER_END
|
|
|
|
// 光源数据数组:xy = 世界坐标 XZ, z = 半径, w = 强度(0~1)
|
|
float4 _LightData[64];
|
|
int _LightCount;
|
|
|
|
Varyings vert(Attributes input)
|
|
{
|
|
Varyings output;
|
|
UNITY_SETUP_INSTANCE_ID(input);
|
|
UNITY_TRANSFER_INSTANCE_ID(input, output);
|
|
|
|
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
|
|
output.uv = input.uv;
|
|
output.worldPos = TransformObjectToWorld(input.positionOS.xyz);
|
|
return output;
|
|
}
|
|
|
|
half4 frag(Varyings input) : SV_Target
|
|
{
|
|
// 2.5D 俯视角:用世界坐标的 XZ 平面计算距离
|
|
float2 worldPos = input.worldPos.xz;
|
|
float lightAmount = 0.0;
|
|
|
|
// 常规光源
|
|
for (int i = 0; i < _LightCount; i++)
|
|
{
|
|
float2 lightPos = _LightData[i].xy;
|
|
float radius = _LightData[i].z;
|
|
float intensity= _LightData[i].w;
|
|
|
|
float dist = distance(worldPos, lightPos);
|
|
float innerRadius = radius * (1.0 - _LightSoftness);
|
|
float light = 1.0 - smoothstep(innerRadius, radius, dist);
|
|
light *= intensity;
|
|
lightAmount = max(lightAmount, light);
|
|
}
|
|
|
|
// 最小亮度:全黑区域是否允许微微看到东西
|
|
lightAmount = max(lightAmount, _MinBrightness);
|
|
|
|
// 从黑暗底色插值到白色
|
|
float3 maskColor = lerp(_DarknessColor.rgb, float3(1.0, 1.0, 1.0), lightAmount);
|
|
|
|
// 编辑器开关开启时(MinBrightness >= 0.99),输出纯白色
|
|
// 这样乘法混合不会改变原场景颜色
|
|
if (_MinBrightness >= 0.99)
|
|
{
|
|
return half4(1.0, 1.0, 1.0, 1.0);
|
|
}
|
|
|
|
return half4(maskColor, 1.0);
|
|
}
|
|
ENDHLSL
|
|
}
|
|
}
|
|
FallBack Off
|
|
}
|