Add see-through X-ray reveal overlay for players

Add a second, additive HDR emission color (_XRayColor) that reveals a
player through walls as a pulsing energy glow, driven during matches:

- Shader: XRayOverlay pass (ZTest Greater, additive) for occluded parts
  plus a matching additive term in the forward fragment for visible
  parts, so the glow shows everywhere and never double-blends. Exposes
  _XRayColor, _XRayPulseSpeed and _XRayPulseStrength for a breathing pulse.
- Render it after opaques via a RenderObjects feature (custom XRayReveal
  light-mode tag) on both PC and Mobile renderers, so the through-wall
  test is depth-sort independent and no longer drops out at some camera
  angles/distances.
- MeshPainter drives _XRayColor alpha through a framerate-independent
  fade (xrayFadeDuration) rather than a hard toggle.
- Reveal is driven per avatar on every client: all remaining un-found
  hiders glow during the Resolution phase, and a hider whose
  ConcealmentMeter EmbeddedPercent exceeds MatchManager.embeddedRevealPercent
  glows via an owner-authoritative NetworkVariable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 4.8 committed 2026-07-01 12:22:17 +02:00
1 parent d7104f9314
commit c54e0cf502
8 files changed
+338 -13

No files matched your search

+25
View File
@@ -120,6 +120,25 @@ public partial class MeshPainter : MonoBehaviour
set { if (_materialInstance && _materialInstance.HasProperty(ParallaxId)) _materialInstance.SetFloat(ParallaxId, Mathf.Max(0f, value) * ParallaxBase); }
}
/// <summary>Drives the see-through-walls X-ray overlay (see <c>PlayerCamoLit</c>): sets the TARGET for
/// the ALPHA of the authored <c>_XRayColor</c>, so the rgb glow colour set on the material is preserved
/// (target 0 = off/no effect, 1 = full glow). The material alpha eases toward this target over
/// <see cref="xrayFadeDuration"/> seconds in <c>Update</c> (a smooth fade instead of a hard pop); set the
/// duration to 0 for an instant toggle. This is a per-avatar runtime reveal, NOT a painted channel: it
/// neither persists with the painting nor round-trips through the HUD. <see cref="NetworkPlayerSetup"/>
/// raises it for the remaining hiders during the resolution phase and for a hider that buries itself
/// too deep in geometry (over the concealment threshold).</summary>
public bool XRayRevealed
{
get => _xrayTarget > 0f;
set => _xrayTarget = value ? 1f : 0f;
}
[Tooltip("Seconds for the see-through X-ray reveal glow to fade fully in or out when toggled (0 = instant snap).")]
[Min(0f)]
[SerializeField] private float xrayFadeDuration = 0.3f;
private float _xrayTarget; // desired _XRayColor alpha (0/1); the material eases toward it each frame
[Header("Backend")]
[Tooltip("ON = GPU painting (fast), OFF = CPU painting. Can be toggled live in Play mode.")]
public bool useGpu = true;
@@ -361,6 +380,7 @@ public partial class MeshPainter : MonoBehaviour
private static readonly int HalfLambertId = Shader.PropertyToID("_HalfLambert");
private static readonly int HalfLambertBrightnessId = Shader.PropertyToID("_HalfLambertBrightness");
private static readonly int SpecularDampenId = Shader.PropertyToID("_SpecularDampen");
private static readonly int XRayColorId = Shader.PropertyToID("_XRayColor");
private static readonly int BrushColorId = Shader.PropertyToID("_BrushColor");
private static readonly int ColorWriteMaskId = Shader.PropertyToID("_ColorWriteMask");
private static readonly int BrushCenterId = Shader.PropertyToID("_BrushCenter");
@@ -404,6 +424,10 @@ public partial class MeshPainter : MonoBehaviour
if (_materialInstance.HasProperty(BaseColorId)) _materialInstance.SetColor(BaseColorId, Color.white);
else if (_materialInstance.HasProperty(ColorId)) _materialInstance.SetColor(ColorId, Color.white);
// Seed the X-ray reveal target from the authored alpha so the fade baseline matches the material
// (authored 0 = off). NetworkPlayerSetup drives this target at runtime; Update eases the alpha to it.
if (_materialInstance.HasProperty(XRayColorId)) _xrayTarget = _materialInstance.GetColor(XRayColorId).a;
BuildSeedColors();
// Always start fresh from the material seed. Saved paintings are loaded explicitly from the
// HUD library (MeshPainter.Persistence), never auto-loaded on start.
@@ -695,6 +719,7 @@ public partial class MeshPainter : MonoBehaviour
if (useGpu != _gpuActive) SwitchBackend(useGpu);
RefreshEmissionColor(); // live-tunable emission intensity
TickXRayFade(); // ease the see-through X-ray glow toward its on/off target (runs on every avatar)
// Painting disabled by the game mode (e.g. player-control mode): do nothing.
if (!PaintingEnabled)