diff --git a/unity/Assets/Light/shaders/AbyssBuilding.shader b/unity/Assets/Light/shaders/AbyssBuilding.shader new file mode 100644 index 0000000..c5817de --- /dev/null +++ b/unity/Assets/Light/shaders/AbyssBuilding.shader @@ -0,0 +1,156 @@ +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 +} diff --git a/unity/Assets/Light/shaders/AbyssBuilding.shader.meta b/unity/Assets/Light/shaders/AbyssBuilding.shader.meta new file mode 100644 index 0000000..63c4db3 --- /dev/null +++ b/unity/Assets/Light/shaders/AbyssBuilding.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: CH8Y5n7/Vn0BksK967jOuQ03oTZ0pHkaGkBawhmQJVNYJSt6fo0VODc= +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity/Assets/Light/shaders/AbyssEdgeGlow.shader b/unity/Assets/Light/shaders/AbyssEdgeGlow.shader new file mode 100644 index 0000000..43eaf36 --- /dev/null +++ b/unity/Assets/Light/shaders/AbyssEdgeGlow.shader @@ -0,0 +1,77 @@ +Shader "IndianOcean/AbyssEdgeGlow" +{ + // 悬崖边缘发光线 Shader + // 加法混合 + Queue 3200(在黑暗遮罩之后渲染) + // UV.y = 1 在顶部(亮),UV.y = 0 在底部(暗) + // 用于 CliffWallBuilder 生成的边缘条带,勾勒地面断开处的轮廓 + Properties + { + _Color ("发光颜色", Color) = (0.2, 0.6, 0.9, 1.0) + _Intensity ("亮度", Range(0.1, 5.0)) = 1.5 + _Gradient ("渐变(越大边缘越硬)", Range(0.1, 3.0)) = 1.0 + } + SubShader + { + Tags + { + "RenderType" = "Transparent" + "Queue" = "Transparent+200" + "RenderPipeline" = "UniversalPipeline" + } + Blend SrcAlpha One + ZWrite Off + ZTest LEqual + Cull Off + + Pass + { + Name "EdgeGlow" + 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; + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + CBUFFER_START(UnityPerMaterial) + float4 _Color; + float _Intensity; + float _Gradient; + CBUFFER_END + + 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; + return output; + } + + half4 frag(Varyings input) : SV_Target + { + // UV.y: 1=顶部(亮), 0=底部(暗) + float glow = pow(input.uv.y, _Gradient); + float3 col = _Color.rgb * _Intensity; + return half4(col, glow); + } + ENDHLSL + } + } + FallBack Off +} diff --git a/unity/Assets/Light/shaders/AbyssEdgeGlow.shader.meta b/unity/Assets/Light/shaders/AbyssEdgeGlow.shader.meta new file mode 100644 index 0000000..d8220a1 --- /dev/null +++ b/unity/Assets/Light/shaders/AbyssEdgeGlow.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: Bi8btyuvWnwuDEqjGGQaRZk43g/rx9FVi+DZcvflp7j5INDN2KO2rmg= +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity/Assets/Light/shaders/AbyssGlowParticle.shader b/unity/Assets/Light/shaders/AbyssGlowParticle.shader new file mode 100644 index 0000000..5c368d1 --- /dev/null +++ b/unity/Assets/Light/shaders/AbyssGlowParticle.shader @@ -0,0 +1,94 @@ +Shader "IndianOcean/AbyssGlowParticle" +{ + // 深渊荧光粒子 Shader + // 加法混合 + Queue 3200(在 DarknessOverlay 的 3100 之后渲染) + // 不受乘法黑暗遮罩影响,在纯黑虚空中也能发光 + // 程序化软圆点,不需要贴图 + // + // 使用方式: + // 1. 创建材质,选此 shader + // 2. 材质赋给 ParticleSystem 的 Renderer > Material + // 3. 粒子贴图留空(程序化圆点),用 Vertex Color 控制颜色/透明度 + Properties + { + _Color ("颜色", Color) = (1.0, 0.85, 0.4, 1.0) + _Softness ("柔和度(边缘渐变宽度)", Range(0.01, 1.0)) = 0.5 + _Intensity ("亮度倍数", Range(0.1, 5.0)) = 1.0 + } + SubShader + { + Tags + { + "RenderType" = "Transparent" + "Queue" = "Transparent+200" + "RenderPipeline" = "UniversalPipeline" + } + // alpha 加法混合:finalColor = src.rgb * src.a + dst.rgb + // 粒子在黑暗遮罩之后渲染,直接往画面上加光 + Blend SrcAlpha One + ZWrite Off + ZTest LEqual + Cull Off + + Pass + { + Name "AbyssGlow" + 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; // 粒子系统顶点色(含生命周期 alpha) + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct Varyings + { + float4 positionCS : SV_POSITION; + float2 uv : TEXCOORD0; + float4 color : COLOR; + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + CBUFFER_START(UnityPerMaterial) + float4 _Color; + float _Softness; + float _Intensity; + CBUFFER_END + + 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.color = input.color; + return output; + } + + half4 frag(Varyings input) : SV_Target + { + // 程序化软圆点:UV 中心 (0.5,0.5) 到边缘的距离 + float2 center = float2(0.5, 0.5); + float dist = distance(input.uv, center); + float softCircle = 1.0 - smoothstep(_Softness * 0.5, 0.5, dist); + softCircle = max(0.0, softCircle); + + // 颜色 = 材质色 × 粒子顶点色 × 亮度 × 软圆形状 + float3 col = _Color.rgb * input.color.rgb * _Intensity; + float alpha = softCircle * input.color.a; + + return half4(col, alpha); + } + ENDHLSL + } + } + FallBack Off +} diff --git a/unity/Assets/Light/shaders/AbyssGlowParticle.shader.meta b/unity/Assets/Light/shaders/AbyssGlowParticle.shader.meta new file mode 100644 index 0000000..5497149 --- /dev/null +++ b/unity/Assets/Light/shaders/AbyssGlowParticle.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: XHwdvCKrAHM5jtQKUz7NX7gNUWP6C/xTlbaNEvJBAkPlInq15kmlkzE= +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity/Assets/Light/shaders/IndianOcean_AbyssBuilding.mat b/unity/Assets/Light/shaders/IndianOcean_AbyssBuilding.mat new file mode 100644 index 0000000..94035e0 --- /dev/null +++ b/unity/Assets/Light/shaders/IndianOcean_AbyssBuilding.mat @@ -0,0 +1,41 @@ +%YAML 1.1 +%TAG !u! tag:yousandi.cn,2023: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: IndianOcean_AbyssBuilding + m_Shader: {fileID: 4800000, guid: 757cdb56f31a23247b9e9c52e37fc9df, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _CutoffY: 0 + - _EdgeIntensity: 1.5 + - _Feather: 1.5 + - _Gradient: 0.1 + - _NoiseAmount: 0.345 + - _NoiseScale: 2 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EdgeColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/unity/Assets/Light/shaders/IndianOcean_AbyssBuilding.mat.meta b/unity/Assets/Light/shaders/IndianOcean_AbyssBuilding.mat.meta new file mode 100644 index 0000000..b29e0a1 --- /dev/null +++ b/unity/Assets/Light/shaders/IndianOcean_AbyssBuilding.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: BygXvHytAHNjY/H6e7FddaEOUe2+LFBn6Hpm/0vRdZba9B/k9Et+ufs= +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity/Assets/Light/shaders/IndianOcean_DarknessOverlay.mat b/unity/Assets/Light/shaders/IndianOcean_DarknessOverlay.mat index 2abee3a..93efba6 100644 --- a/unity/Assets/Light/shaders/IndianOcean_DarknessOverlay.mat +++ b/unity/Assets/Light/shaders/IndianOcean_DarknessOverlay.mat @@ -31,7 +31,7 @@ Material: - _EchoRadius: 39.41617 - _EchoWidth: 2.5 - _LightSoftness: 1 - - _MinBrightness: 0 + - _MinBrightness: 1 m_Colors: - _DarknessColor: {r: 0.01, g: 0.01, b: 0.02, a: 1} - _EchoCenter: {r: -2.4399998, g: -1.5000057, b: 0, a: 0} diff --git a/unity/UserSettings/EditorUserSettings.asset b/unity/UserSettings/EditorUserSettings.asset index 7d46cd5..d131177 100644 --- a/unity/UserSettings/EditorUserSettings.asset +++ b/unity/UserSettings/EditorUserSettings.asset @@ -27,14 +27,14 @@ EditorUserSettings: value: 5a5757560101590a5d0c0e24427b5d44434e4c7a7b7a23677f2b4565b7b5353a flags: 0 RecentlyUsedSceneGuid-7: - value: 5300055151055f5a5e0c0f27477708444515192b287124367c791f30b3b9616d - flags: 0 - RecentlyUsedSceneGuid-8: value: 5a55515156575a0b0f56592346260f444f16197c7e7f24697d2a4a32b1b0353e flags: 0 - RecentlyUsedSceneGuid-9: + RecentlyUsedSceneGuid-8: value: 0209025f575750595c57092149765d444e4e49727e7c7068757b1c65b6e36c3b flags: 0 + RecentlyUsedSceneGuid-9: + value: 5300055151055f5a5e0c0f27477708444515192b287124367c791f30b3b9616d + flags: 0 UnityEditor.ShaderGraph.Blackboard: value: 18135939215a0a5004000b0e15254b524c030a3f2964643d120d1230e9e93a3fd6e826abbd2e2d293c4ead313b08042de6030a0afa240c0d020be94c4ba75e435d8715fa32c70d15d11612dacc11fee5d3c5d1fe9ab1bf968e93e2ffcbc3e7e2f0b3ffe0e8b0be9af8ffaeffff8e85dd8390e3949c8899daa7 flags: 0