Shader "Custom/URP/GTASAHintMarker" { Properties { [ToggleUI] _Enabled ("Enabled", Float) = 1 [HDR] _HintColor ("Marker Color", Color) = (1, 0.8, 0, 0.5) _FadeStart ("Fade Start Height (World Y)", Float) = 0.0 _FadeEnd ("Fade End Height (World Y)", Float) = 2.0 _HoleRadius ("Hole Radius", Range(0.0, 1.0)) = 0.5 _HoleSmoothness ("Hole Smoothness", Range(0.001, 0.5)) = 0.05 _PulseSpeed ("Pulse Speed", Float) = 6.0 _PulseIntensity ("Pulse Intensity", Range(0, 1)) = 0.3 } SubShader { Tags { "RenderType" = "Transparent" "Queue" = "Transparent+10" "RenderPipeline" = "UniversalPipeline" "IgnoreProjector" = "True" } LOD 100 Pass { Name "Unlit" Tags { "LightMode" = "UniversalForward" } Blend SrcAlpha OneMinusSrcAlpha ZWrite Off Cull Off HLSLPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 3.0 #pragma multi_compile_instancing #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" // CBUFFER необходим для совместимости с SRP Batcher CBUFFER_START(UnityPerMaterial) float4 _HintColor; float _Enabled; float _FadeStart; float _FadeEnd; float _HoleRadius; float _HoleSmoothness; float _PulseSpeed; float _PulseIntensity; CBUFFER_END struct Attributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct Varyings { float4 positionCS : SV_POSITION; float3 positionWS : TEXCOORD0; float3 positionOS : TEXCOORD1; float3 normalOS : NORMAL; UNITY_VERTEX_INPUT_INSTANCE_ID }; Varyings vert(Attributes input) { Varyings output = (Varyings)0; UNITY_SETUP_INSTANCE_ID(input); UNITY_TRANSFER_INSTANCE_ID(input, output); VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz); output.positionCS = vertexInput.positionCS; output.positionWS = vertexInput.positionWS; output.positionOS = input.positionOS.xyz; output.normalOS = input.normalOS; return output; } half4 frag(Varyings input) : SV_Target { UNITY_SETUP_INSTANCE_ID(input); if (_Enabled < 0.5) { discard; } // Отсечение верхней крышки цилиндра/маркера if (input.normalOS.y > 0.5 && input.positionOS.y > 0.0) { discard; } // Вертикальный градиент затухания по высоте float heightRange = max(_FadeEnd - _FadeStart, 0.001); float gradient = saturate((input.positionWS.y - _FadeStart) / heightRange); float alphaFade = 1.0 - gradient; // Маска отверстия в нижней части float distFromCenter = length(input.positionOS.xz); if (input.normalOS.y < -0.5) { float targetRadius = _HoleRadius * 0.5; float holeMask = smoothstep(targetRadius, targetRadius + _HoleSmoothness, distFromCenter); alphaFade *= holeMask; } half4 finalColor = _HintColor; finalColor.a *= alphaFade; // Пульсация прозрачности во времени float pulseWave = sin(_Time.y * _PulseSpeed) * 0.5 + 0.5; float pulse = (1.0 - _PulseIntensity) + pulseWave * _PulseIntensity; finalColor.a *= pulse; return finalColor; } ENDHLSL } } FallBack "Hidden/Universal Render Pipeline/FallbackError" }