1
0

BeforeLightTargetOverlay.cs 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. using System.Numerics;
  2. using Robust.Client.Graphics;
  3. using Robust.Shared.Enums;
  4. namespace Content.Client.Light;
  5. /// <summary>
  6. /// Handles an enlarged lighting target so content can use large blur radii.
  7. /// </summary>
  8. public sealed class BeforeLightTargetOverlay : Overlay
  9. {
  10. public override OverlaySpace Space => OverlaySpace.BeforeLighting;
  11. [Dependency] private readonly IClyde _clyde = default!;
  12. public IRenderTexture EnlargedLightTarget = default!;
  13. public Box2Rotated EnlargedBounds;
  14. /// <summary>
  15. /// In metres
  16. /// </summary>
  17. private float _skirting = 2f;
  18. public const int ContentZIndex = -10;
  19. public BeforeLightTargetOverlay()
  20. {
  21. IoCManager.InjectDependencies(this);
  22. ZIndex = ContentZIndex;
  23. }
  24. protected override void Draw(in OverlayDrawArgs args)
  25. {
  26. // Code is weird but I don't think engine should be enlarging the lighting render target arbitrarily either, maybe via cvar?
  27. // The problem is the blur has no knowledge of pixels outside the viewport so with a large enough blur radius you get sampling issues.
  28. var size = args.Viewport.LightRenderTarget.Size + (int) (_skirting * EyeManager.PixelsPerMeter);
  29. EnlargedBounds = args.WorldBounds.Enlarged(_skirting / 2f);
  30. // This just exists to copy the lightrendertarget and write back to it.
  31. if (EnlargedLightTarget?.Size != size)
  32. {
  33. EnlargedLightTarget = _clyde
  34. .CreateRenderTarget(size, new RenderTargetFormatParameters(RenderTargetColorFormat.Rgba8Srgb), name: "enlarged-light-copy");
  35. }
  36. args.WorldHandle.RenderInRenderTarget(EnlargedLightTarget,
  37. () =>
  38. {
  39. }, _clyde.GetClearColor(args.MapUid));
  40. }
  41. }