Files
gold_dolphin/unity/Assets/Light/shaders/DarknessOverlay.shader
2026-06-27 03:35:52 +08:00

107 lines
3.7 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/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);
return half4(maskColor, 1.0);
}
ENDHLSL
}
}
FallBack Off
}