From 3a4bbcb28903edc911e188a8ada90524e2ced0e4 Mon Sep 17 00:00:00 2001 From: Red <96445749+TheShuEd@users.noreply.github.com> Date: Wed, 18 Jun 2025 21:46:58 +0300 Subject: [PATCH] Area of influence depends on followers MobState (#1439) * simple anti-religion zone shader * observers refactor --- .../Religion/CP14ReligionVisionOverlay.cs | 75 ++++++++++++----- .../_CP14/Religion/CP14ReligionSystem.cs | 53 ++++++++---- .../CP14ReligionObserverComponent.cs | 5 +- .../Prototypes/CP14ReligionPrototype.cs | 5 +- .../CP14SharedReligionGodSystem.Altars.cs | 44 ---------- .../CP14SharedReligionGodSystem.Followers.cs | 24 ++++-- ...CP14SharedReligionGodSystem.Observation.cs | 38 ++------- .../_CP14/Entities/Mobs/NPC/Flem.yml | 2 +- .../Entities/Mobs/Player/Patrons/gods.yml | 1 + .../Specific/Religion/primordial.yml | 8 +- .../Textures/_CP14/Shaders/religion.swsl | 80 ++++++++++++------- 11 files changed, 179 insertions(+), 156 deletions(-) diff --git a/Content.Client/_CP14/Religion/CP14ReligionVisionOverlay.cs b/Content.Client/_CP14/Religion/CP14ReligionVisionOverlay.cs index 6c837e0713..ab043c58d0 100644 --- a/Content.Client/_CP14/Religion/CP14ReligionVisionOverlay.cs +++ b/Content.Client/_CP14/Religion/CP14ReligionVisionOverlay.cs @@ -25,12 +25,15 @@ public sealed class CP14ReligionVisionOverlay : Overlay public override bool RequestScreenTexture => true; public override OverlaySpace Space => OverlaySpace.WorldSpace; - private readonly ProtoId? _religion = null; + private readonly ProtoId? _religion; private readonly ShaderInstance _religionShader; private readonly Vector2[] _positions = new Vector2[MaxCount]; private readonly float[] _radii = new float[MaxCount]; - private int _count = 0; + private int _count; + private readonly Vector2[] _antiPositions = new Vector2[MaxCount]; + private readonly float[] _antiRadii = new float[MaxCount]; + private int _antiCount; public CP14ReligionVisionOverlay() { @@ -49,20 +52,21 @@ public sealed class CP14ReligionVisionOverlay : Overlay if (args.Viewport.Eye == null) return false; - _count = 0; - var clusters = new List(); + var antiClusters = new List(); var religionQuery = _entManager.AllEntityQueryEnumerator(); - while (religionQuery.MoveNext(out var uid, out var rel, out var xform)) + while (religionQuery.MoveNext(out var uid, out var observer, out var xform)) { if (_religion is null) continue; - var observation = rel.Observation; - if (!observation.ContainsKey(_religion.Value)) + if (observer.Religion is null) continue; - if (!rel.Active || xform.MapID != args.MapId) + if (observer.Radius <= 0f) + continue; + + if (!observer.Active || xform.MapID != args.MapId) continue; var mapPos = _transform.GetWorldPosition(uid); @@ -72,23 +76,40 @@ public sealed class CP14ReligionVisionOverlay : Overlay var tempCoords = args.Viewport.WorldToLocal(mapPos); tempCoords.Y = args.Viewport.Size.Y - tempCoords.Y; // Local space to fragment space. - // try find cluster to merge with - bool merged = false; - foreach (var cluster in clusters) + if (observer.Religion.Value == _religion.Value) { - if ((cluster.Position - tempCoords).Length() < 150f) + // try find cluster to merge with + bool merged = false; + foreach (var cluster in clusters) { - cluster.Add(tempCoords, rel.Observation[_religion.Value]); - merged = true; - break; + if ((cluster.Position - tempCoords).Length() < 150f) + { + cluster.Add(tempCoords, observer.Radius); + merged = true; + break; + } } + + if (!merged && clusters.Count < MaxCount) + clusters.Add(new Cluster(tempCoords, observer.Radius)); } + else + { + // try find cluster to merge with + bool merged = false; + foreach (var antiCluster in antiClusters) + { + if ((antiCluster.Position - tempCoords).Length() < 150f) + { + antiCluster.Add(tempCoords, observer.Radius); + merged = true; + break; + } + } - if (!merged) - clusters.Add(new Cluster(tempCoords, rel.Observation[_religion.Value])); - - if (clusters.Count >= MaxCount) - break; + if (!merged && antiClusters.Count < MaxCount) + antiClusters.Add(new Cluster(tempCoords, observer.Radius)); + } } _count = 0; @@ -99,6 +120,14 @@ public sealed class CP14ReligionVisionOverlay : Overlay _count++; } + _antiCount = 0; + foreach (var antiCluster in antiClusters) + { + _antiPositions[_antiCount] = antiCluster.Position; + _antiRadii[_antiCount] = antiCluster.Radius; + _antiCount++; + } + return true; } @@ -112,9 +141,15 @@ public sealed class CP14ReligionVisionOverlay : Overlay _religionShader?.SetParameter("shaderColor", visionComponent.ShaderColor); _religionShader?.SetParameter("renderScale", args.Viewport.RenderScale * args.Viewport.Eye.Scale); + _religionShader?.SetParameter("count", _count); _religionShader?.SetParameter("position", _positions); _religionShader?.SetParameter("radius", _radii); + + _religionShader?.SetParameter("anticount", _antiCount); + _religionShader?.SetParameter("antiposition", _antiPositions); + _religionShader?.SetParameter("antiradius", _antiRadii); + _religionShader?.SetParameter("SCREEN_TEXTURE", ScreenTexture); var worldHandle = args.WorldHandle; diff --git a/Content.Server/_CP14/Religion/CP14ReligionSystem.cs b/Content.Server/_CP14/Religion/CP14ReligionSystem.cs index ac9cdd5eaa..7a0e95c5b0 100644 --- a/Content.Server/_CP14/Religion/CP14ReligionSystem.cs +++ b/Content.Server/_CP14/Religion/CP14ReligionSystem.cs @@ -86,7 +86,12 @@ public sealed partial class CP14ReligionGodSystem : CP14SharedReligionGodSystem foreach (var god in GetGods(follower.Religion.Value)) { - _magicEnergy.TransferEnergy((uid, energy), god.Owner, follower.EnergyToGodTransfer, out _, out _, safe: true); + _magicEnergy.TransferEnergy((uid, energy), + god.Owner, + follower.EnergyToGodTransfer, + out _, + out _, + safe: true); } } } @@ -111,7 +116,12 @@ public sealed partial class CP14ReligionGodSystem : CP14SharedReligionGodSystem Timer.Spawn(333, () => { - _chatSys.TrySendInGameICMessage(speaker, message, type, ChatTransmitRange.Normal, nameOverride: MetaData(ent).EntityName, ignoreActionBlocker: true); + _chatSys.TrySendInGameICMessage(speaker, + message, + type, + ChatTransmitRange.Normal, + nameOverride: MetaData(ent).EntityName, + ignoreActionBlocker: true); }); } @@ -126,14 +136,14 @@ public sealed partial class CP14ReligionGodSystem : CP14SharedReligionGodSystem private void OnObserverInit(Entity ent, ref ComponentInit args) { - foreach (var (religion, _) in ent.Comp.Observation) - { - var gods = GetGods(religion); + if (ent.Comp.Religion is null) + return; - foreach (var god in gods) - { - UpdatePvsOverrides(god); - } + var gods = GetGods(ent.Comp.Religion.Value); + + foreach (var god in gods) + { + UpdatePvsOverrides(god); } } @@ -163,7 +173,9 @@ public sealed partial class CP14ReligionGodSystem : CP14SharedReligionGodSystem return; var wrappedMessage = - Loc.GetString("cp14-altar-wrapped-message", ("name", MetaData(args.Source).EntityName), ("msg", args.Message)); + Loc.GetString("cp14-altar-wrapped-message", + ("name", MetaData(args.Source).EntityName), + ("msg", args.Message)); SendMessageToGods(ent.Comp.Religion.Value, wrappedMessage, args.Source); } @@ -181,7 +193,14 @@ public sealed partial class CP14ReligionGodSystem : CP14SharedReligionGodSystem channels.Add(godActor.PlayerSession.Channel); } - _chat.ChatMessageToMany(ChatChannel.Notifications, msg, msg, source, false, true, channels, colorOverride: Color.Aqua); + _chat.ChatMessageToMany(ChatChannel.Notifications, + msg, + msg, + source, + false, + true, + channels, + colorOverride: Color.Aqua); } public FixedPoint2 GetFollowerPercentage(Entity god) @@ -221,10 +240,10 @@ public sealed partial class CP14ReligionGodSystem : CP14SharedReligionGodSystem var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var observer)) { - if (!observer.Observation.ContainsKey(ent.Comp.Religion.Value)) + if (!observer.Active) continue; - if (observer.Observation[ent.Comp.Religion.Value] <= ObservationOverrideRadius) + if (observer.Radius <= ObservationOverrideRadius) continue; ent.Comp.PvsOverridedObservers.Add(uid); @@ -240,9 +259,9 @@ public sealed partial class CP14ReligionGodSystem : CP14SharedReligionGodSystem if (ent.Comp.Session is null) return; - foreach (var altar in ent.Comp.PvsOverridedObservers) + foreach (var observer in ent.Comp.PvsOverridedObservers) { - _pvs.RemoveSessionOverride(altar, ent.Comp.Session); + _pvs.RemoveSessionOverride(observer, ent.Comp.Session); } ent.Comp.Session = null; @@ -259,10 +278,10 @@ public sealed partial class CP14ReligionGodSystem : CP14SharedReligionGodSystem } } -public sealed class CP14SpokeAttemptEvent(string message, InGameICChatType type, ICommonSession? player) : CancellableEntityEventArgs +public sealed class CP14SpokeAttemptEvent(string message, InGameICChatType type, ICommonSession? player) + : CancellableEntityEventArgs { public string Message = message; public InGameICChatType Type = type; public ICommonSession? Player = player; } - diff --git a/Content.Shared/_CP14/Religion/Components/CP14ReligionObserverComponent.cs b/Content.Shared/_CP14/Religion/Components/CP14ReligionObserverComponent.cs index 5d9b31e6c5..a1e0b0e478 100644 --- a/Content.Shared/_CP14/Religion/Components/CP14ReligionObserverComponent.cs +++ b/Content.Shared/_CP14/Religion/Components/CP14ReligionObserverComponent.cs @@ -12,7 +12,10 @@ namespace Content.Shared._CP14.Religion.Components; public sealed partial class CP14ReligionObserverComponent : Component { [DataField, AutoNetworkedField] - public Dictionary, float> Observation = new(); //DAMNATION + public ProtoId? Religion; + + [DataField, AutoNetworkedField] + public float Radius = 5f; [DataField, AutoNetworkedField] public bool Active = true; diff --git a/Content.Shared/_CP14/Religion/Prototypes/CP14ReligionPrototype.cs b/Content.Shared/_CP14/Religion/Prototypes/CP14ReligionPrototype.cs index 01639cb564..3284e2936e 100644 --- a/Content.Shared/_CP14/Religion/Prototypes/CP14ReligionPrototype.cs +++ b/Content.Shared/_CP14/Religion/Prototypes/CP14ReligionPrototype.cs @@ -11,8 +11,5 @@ public sealed partial class CP14ReligionPrototype : IPrototype [IdDataField] public string ID { get; } = default!; [DataField] - public float FollowerObservationRadius = 8f; - - [DataField] - public float AltarObservationRadius = 25f; + public float FollowerObservationRadius = 10f; } diff --git a/Content.Shared/_CP14/Religion/Systems/CP14SharedReligionGodSystem.Altars.cs b/Content.Shared/_CP14/Religion/Systems/CP14SharedReligionGodSystem.Altars.cs index e9e29777d9..73e28913a6 100644 --- a/Content.Shared/_CP14/Religion/Systems/CP14SharedReligionGodSystem.Altars.cs +++ b/Content.Shared/_CP14/Religion/Systems/CP14SharedReligionGodSystem.Altars.cs @@ -48,50 +48,6 @@ public abstract partial class CP14SharedReligionGodSystem }, }); } - - public bool TryConvertAltar(EntityUid target, ProtoId religion) - { - if (!_proto.TryIndex(religion, out var indexedReligion)) - return false; - - EnsureComp(target, out var altar); - - if (!altar.CanBeConverted) - return false; - - var oldReligion = altar.Religion; - altar.Religion = religion; - Dirty(target, altar); - - EditObservation(target, religion, indexedReligion.AltarObservationRadius); - - var ev = new CP14ReligionChangedEvent(oldReligion, religion); - RaiseLocalEvent(target, ev); - - return true; - } - - public void DeconvertAltar(EntityUid target) - { - if (!TryComp(target, out var altar)) - return; - - if (altar.Religion is null) - return; - - if (!_proto.TryIndex(altar.Religion, out var indexedReligion)) - return; - - EditObservation(target, altar.Religion.Value, -indexedReligion.AltarObservationRadius); - - var oldReligion = altar.Religion; - altar.Religion = null; - - var ev = new CP14ReligionChangedEvent(oldReligion, null); - RaiseLocalEvent(target, ev); - - Dirty(target, altar); - } } [Serializable, NetSerializable] diff --git a/Content.Shared/_CP14/Religion/Systems/CP14SharedReligionGodSystem.Followers.cs b/Content.Shared/_CP14/Religion/Systems/CP14SharedReligionGodSystem.Followers.cs index 4ad072f40e..05c3480a95 100644 --- a/Content.Shared/_CP14/Religion/Systems/CP14SharedReligionGodSystem.Followers.cs +++ b/Content.Shared/_CP14/Religion/Systems/CP14SharedReligionGodSystem.Followers.cs @@ -40,16 +40,30 @@ public abstract partial class CP14SharedReligionGodSystem if (ent.Comp.Religion is null) return; + EnsureComp(ent, out var observer); + + if (!_proto.TryIndex(observer.Religion, out var indexedReligion)) + return; + + var baseObservation = indexedReligion.FollowerObservationRadius; switch (args.NewMobState) { + case MobState.Alive: + observer.Radius = baseObservation; + break; + case MobState.Critical: SendMessageToGods(ent.Comp.Religion.Value, Loc.GetString("cp14-critical-follower-message", ("name", MetaData(ent).EntityName)), ent); + observer.Radius = baseObservation * 0.25f; break; case MobState.Dead: SendMessageToGods(ent.Comp.Religion.Value, Loc.GetString("cp14-dead-follower-message", ("name", MetaData(ent).EntityName)), ent); + observer.Radius = 0f; break; } + + Dirty(ent.Owner, observer); } private void OnGetAltVerbs(EntityUid uid, CP14ReligionFollowerComponent component, GetVerbsEvent args) @@ -152,12 +166,14 @@ public abstract partial class CP14SharedReligionGodSystem return false; EnsureComp(pending, out var follower); + EnsureComp(pending, out var observer); + observer.Religion = indexedReligion; + observer.Radius = indexedReligion.FollowerObservationRadius; var oldReligion = follower.Religion; follower.Religion = pending.Comp.Religion; Dirty(pending, follower); - - EditObservation(pending, pending.Comp.Religion.Value, indexedReligion.FollowerObservationRadius); + Dirty(pending, observer); var ev = new CP14ReligionChangedEvent(oldReligion, pending.Comp.Religion); RaiseLocalEvent(pending, ev); @@ -178,11 +194,9 @@ public abstract partial class CP14SharedReligionGodSystem if (follower.Religion is null) return; - if (!_proto.TryIndex(follower.Religion, out var indexedReligion)) - return; + RemCompDeferred(target); SendMessageToGods(follower.Religion.Value, Loc.GetString("cp14-remove-follower-message", ("name", MetaData(target).EntityName)), target); - EditObservation(target, follower.Religion.Value, -indexedReligion.FollowerObservationRadius); var oldReligion = follower.Religion; follower.Religion = null; diff --git a/Content.Shared/_CP14/Religion/Systems/CP14SharedReligionGodSystem.Observation.cs b/Content.Shared/_CP14/Religion/Systems/CP14SharedReligionGodSystem.Observation.cs index dc5a3f5174..0209c74378 100644 --- a/Content.Shared/_CP14/Religion/Systems/CP14SharedReligionGodSystem.Observation.cs +++ b/Content.Shared/_CP14/Religion/Systems/CP14SharedReligionGodSystem.Observation.cs @@ -28,28 +28,6 @@ public abstract partial class CP14SharedReligionGodSystem args.Visibility &= ~MenuVisibility.NoFov; } - public void EditObservation(EntityUid target, ProtoId religion, float range) - { - EnsureComp(target, out var observer); - - if (observer.Observation.ContainsKey(religion)) - { - var newRange = Math.Clamp(observer.Observation[religion] + range, 0, float.MaxValue); - - if (newRange <= 0) - observer.Observation.Remove(religion); - else - observer.Observation[religion] = newRange; - } - else - { - // Otherwise, add a new observation for the religion. - observer.Observation.Add(religion, range); - } - - Dirty(target, observer); - } - public bool InVision(EntityUid target, Entity user) { var position = Transform(target).Coordinates; @@ -62,29 +40,27 @@ public abstract partial class CP14SharedReligionGodSystem if (!HasComp(user)) return true; + if (user.Comp.Religion is null) + return true; + var userXform = Transform(user); var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var observer, out var xform)) { - if (!observer.Active) + if (!observer.Active || observer.Religion is null || observer.Radius <= 0f) continue; if (xform.MapID != userXform.MapID) continue; - if (user.Comp.Religion is null) + if (observer.Religion.Value != user.Comp.Religion.Value) continue; - if (!observer.Observation.ContainsKey(user.Comp.Religion.Value)) - continue; - - var obsPos = _transform.GetWorldPosition(uid); var targetPos = coords.Position; - if (Vector2.Distance(obsPos, targetPos) <= observer.Observation[user.Comp.Religion.Value]) + if (Vector2.Distance(obsPos, targetPos) <= observer.Radius) { - // If the observer is within range of the target, they can see it. - return true; + return observer.Religion.Value == user.Comp.Religion.Value; } } diff --git a/Resources/Prototypes/_CP14/Entities/Mobs/NPC/Flem.yml b/Resources/Prototypes/_CP14/Entities/Mobs/NPC/Flem.yml index bd111c5a59..aeba888e70 100644 --- a/Resources/Prototypes/_CP14/Entities/Mobs/NPC/Flem.yml +++ b/Resources/Prototypes/_CP14/Entities/Mobs/NPC/Flem.yml @@ -97,4 +97,4 @@ - type: Tag tags: - FootstepSound - - CP14Mosquito + - CP14Mosquito \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Entities/Mobs/Player/Patrons/gods.yml b/Resources/Prototypes/_CP14/Entities/Mobs/Player/Patrons/gods.yml index bf39fe58c6..4ea2ea3b26 100644 --- a/Resources/Prototypes/_CP14/Entities/Mobs/Player/Patrons/gods.yml +++ b/Resources/Prototypes/_CP14/Entities/Mobs/Player/Patrons/gods.yml @@ -12,6 +12,7 @@ sprite: _CP14/Mobs/Demigods/temp_icons.rsi color: "#ffffff99" - type: PointLight + energy: 2 radius: 10 softness: 1 castShadows: false diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Specific/Religion/primordial.yml b/Resources/Prototypes/_CP14/Entities/Structures/Specific/Religion/primordial.yml index 0d7619dd74..f5bfc80f38 100644 --- a/Resources/Prototypes/_CP14/Entities/Structures/Specific/Religion/primordial.yml +++ b/Resources/Prototypes/_CP14/Entities/Structures/Specific/Religion/primordial.yml @@ -13,8 +13,8 @@ - type: CP14ReligionAltar religion: Lumera - type: CP14ReligionObserver - observation: - Lumera: 10 + religion: Lumera + radius: 15 - type: SpawnPoint job_id: CP14GodLumera @@ -31,7 +31,7 @@ # - type: CP14ReligionAltar # religion: Merkas # - type: CP14ReligionObserver -# observation: -# Merkas: 10 +# religion: Merkas +# radius: 10 # - type: SpawnPoint # job_id: CP14GodMerkas \ No newline at end of file diff --git a/Resources/Textures/_CP14/Shaders/religion.swsl b/Resources/Textures/_CP14/Shaders/religion.swsl index 0168f11ba7..325e7a9bf8 100644 --- a/Resources/Textures/_CP14/Shaders/religion.swsl +++ b/Resources/Textures/_CP14/Shaders/religion.swsl @@ -1,11 +1,17 @@ uniform sampler2D SCREEN_TEXTURE; + uniform lowp int count; uniform highp vec2[64] position; uniform highp float[64] radius; + +uniform lowp int anticount; +uniform highp vec2[64] antiposition; +uniform highp float[64] antiradius; + uniform highp vec2 renderScale; uniform highp vec3 shaderColor; -const highp float radiusFalloff = 60.0; +const highp float radiusFalloff = 20.0; const highp float noiseScale = 6; const highp float timeScale = 0.1; @@ -34,51 +40,67 @@ highp vec3 gradientColor(highp float t) { } } -void fragment() { - highp vec2 fragPos = FRAGCOORD.xy; +highp float calculateVisibilityAtPoint(highp vec2 fragPos) { highp float visibility = 0.0; - highp float edgeHighlight = 0.0; highp float scale = renderScale.x; + // Видимость (раскрытие) + for (lowp int i = 0; i < 64 && i < count; i++) { + highp float scaledRadius = radius[i] * 33.0 * scale; + highp float dist = length(fragPos - position[i]); + + highp float fade = smoothstep(scaledRadius - radiusFalloff * scale, scaledRadius, dist); + visibility = max(visibility, 1.0 - fade); + } + + // Антивидимость (перекрытие) + for (lowp int i = 0; i < 64 && i < anticount; i++) { + highp float scaledRadius = antiradius[i] * 33.0 * scale; + highp float dist = length(fragPos - antiposition[i]); + + highp float fade = smoothstep(scaledRadius - radiusFalloff * scale, scaledRadius, dist); + highp float antiVis = 1.0 - fade; + + // Учитываем антивидимость как маску + visibility = min(visibility, fade); // fade → 1 в центре антизоны (нулевая видимость) + } + + return visibility; +} + +highp float calculateEdgeHighlight(highp float visibility) { + if (visibility >= 0.99 || visibility <= 0.0) + return 0.0; + + return visibility; +} + + +void fragment() { + highp vec2 fragPos = FRAGCOORD.xy; highp vec2 uv = fragPos * SCREEN_PIXEL_SIZE; highp float t = TIME * timeScale; highp vec2 noiseUV = uv * noiseScale + vec2(t); + // Цветовая маска (по шуму) highp float n = noise(noiseUV); highp vec3 colorOverlay = gradientColor(n); + // Искажение позиции для эффекта "миража" highp float nX = noise(noiseUV + vec2(3.1, 7.7)); highp float nY = noise(noiseUV + vec2(9.3, 2.4)); - highp vec2 distortion = vec2(nX - 0.5, nY - 0.5) * 15.0 * scale; + highp vec2 distortion = vec2(nX - 0.5, nY - 0.5) * 15.0 * renderScale.x; - for (lowp int i = 0; i < 64 && i < count; i++) { - highp float scaledRadius = radius[i] * 33.0 * scale; - highp float dist = length((fragPos + distortion) - position[i]); - - highp float fade = smoothstep(scaledRadius - radiusFalloff * scale, scaledRadius, dist); - visibility = max(visibility, 1.0 - fade); - - // Узкая кромка по расстоянию до радиуса - highp float offset = -60; - highp float edgeWidth = 8.0 * scale; // ширина кромки в пикселях - highp float edgeDist = abs(dist - (scaledRadius + offset)) * (1 / scale); - highp float edge = smoothstep(edgeWidth, 0.0, edgeDist); - edgeHighlight = max(edgeHighlight, edge); - } + highp float visibility = calculateVisibilityAtPoint(fragPos + distortion); + highp float edgeHighlight = calculateEdgeHighlight(visibility); - - highp vec4 baseColor = zTextureSpec(SCREEN_TEXTURE, fragPos * SCREEN_PIXEL_SIZE); + highp vec4 baseColor = zTextureSpec(SCREEN_TEXTURE, uv); highp vec3 finalColor = mix(colorOverlay, baseColor.rgb, visibility); - // Наложим бордовую кромку - finalColor = mix( - finalColor, - shaderColor, - edgeHighlight * step(0.5, 1.0 - visibility) - ); + finalColor = mix(finalColor, shaderColor, edgeHighlight); - highp float minAlpha = 1; - COLOR = vec4(finalColor, mix(minAlpha, 1.0, visibility)); + highp float minAlpha = 1.0; + COLOR = vec4(finalColor, mix(minAlpha, 1.0, edgeHighlight)); }