diff --git a/OpenRA.Mods.Cnc/Activities/Teleport.cs b/OpenRA.Mods.Cnc/Activities/Teleport.cs index 9884860110..e431525b90 100644 --- a/OpenRA.Mods.Cnc/Activities/Teleport.cs +++ b/OpenRA.Mods.Cnc/Activities/Teleport.cs @@ -101,7 +101,7 @@ namespace OpenRA.Mods.Cnc.Activities // Trigger screen desaturate effect if (screenFlash) - foreach (var a in self.World.ActorsWithTrait()) + foreach (var a in self.World.ActorsWithTrait()) a.Trait.Enable(); if (teleporter != null && self != teleporter && !teleporter.Disposed) diff --git a/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs b/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs index 6629e347ab..8a3ef651c0 100644 --- a/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs +++ b/OpenRA.Mods.Cnc/Traits/ConyardChronoReturn.cs @@ -213,7 +213,7 @@ namespace OpenRA.Mods.Cnc.Traits TriggerVortex(); // Trigger screen desaturate effect - foreach (var cpa in self.World.ActorsWithTrait()) + foreach (var cpa in self.World.ActorsWithTrait()) cpa.Trait.Enable(); Game.Sound.Play(SoundType.World, info.ChronoshiftSound, self.CenterPosition); diff --git a/OpenRA.Mods.Cnc/Traits/PaletteEffects/ChronoshiftPaletteEffect.cs b/OpenRA.Mods.Cnc/Traits/PaletteEffects/ChronoshiftPostProcessEffect.cs similarity index 55% rename from OpenRA.Mods.Cnc/Traits/PaletteEffects/ChronoshiftPaletteEffect.cs rename to OpenRA.Mods.Cnc/Traits/PaletteEffects/ChronoshiftPostProcessEffect.cs index 6e8dd5a71e..3632485642 100644 --- a/OpenRA.Mods.Cnc/Traits/PaletteEffects/ChronoshiftPaletteEffect.cs +++ b/OpenRA.Mods.Cnc/Traits/PaletteEffects/ChronoshiftPostProcessEffect.cs @@ -9,29 +9,29 @@ */ #endregion -using System.Collections.Generic; using OpenRA.Graphics; -using OpenRA.Primitives; +using OpenRA.Mods.Common.Traits; using OpenRA.Traits; namespace OpenRA.Mods.Cnc.Traits { [TraitLocation(SystemActors.World | SystemActors.EditorWorld)] [Desc("Apply palette full screen rotations during chronoshifts. Add this to the world actor.")] - public class ChronoshiftPaletteEffectInfo : TraitInfo + public class ChronoshiftPostProcessEffectInfo : TraitInfo { [Desc("Measured in ticks.")] public readonly int ChronoEffectLength = 60; - public override object Create(ActorInitializer init) { return new ChronoshiftPaletteEffect(this); } + public override object Create(ActorInitializer init) { return new ChronoshiftPostProcessEffect(this); } } - public class ChronoshiftPaletteEffect : IPaletteModifier, ITick + public class ChronoshiftPostProcessEffect : RenderPostProcessPassBase, ITick { - readonly ChronoshiftPaletteEffectInfo info; + readonly ChronoshiftPostProcessEffectInfo info; int remainingFrames; - public ChronoshiftPaletteEffect(ChronoshiftPaletteEffectInfo info) + public ChronoshiftPostProcessEffect(ChronoshiftPostProcessEffectInfo info) + : base("chronoshift", PostProcessPassType.AfterWorld) { this.info = info; } @@ -47,23 +47,10 @@ namespace OpenRA.Mods.Cnc.Traits remainingFrames--; } - void IPaletteModifier.AdjustPalette(IReadOnlyDictionary palettes) + protected override bool Enabled => remainingFrames > 0; + protected override void PrepareRender(WorldRenderer wr, IShader shader) { - if (remainingFrames == 0) - return; - - var frac = (float)remainingFrames / info.ChronoEffectLength; - - foreach (var pal in palettes) - { - for (var x = 0; x < Palette.Size; x++) - { - var orig = pal.Value.GetColor(x); - var lum = (int)(255 * orig.GetBrightness()); - var desat = Color.FromArgb(orig.A, lum, lum, lum); - pal.Value.SetColor(x, Exts.ColorLerp(frac, orig, desat)); - } - } + shader.SetVec("Blend", (float)remainingFrames / info.ChronoEffectLength); } } } diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/20230801/ReplacePaletteModifiers.cs b/OpenRA.Mods.Common/UpdateRules/Rules/20230801/ReplacePaletteModifiers.cs index bc43165c6f..cf05ddb40d 100644 --- a/OpenRA.Mods.Common/UpdateRules/Rules/20230801/ReplacePaletteModifiers.cs +++ b/OpenRA.Mods.Common/UpdateRules/Rules/20230801/ReplacePaletteModifiers.cs @@ -18,11 +18,13 @@ namespace OpenRA.Mods.Common.UpdateRules.Rules public override string Name => "Replace palette modifiers with post-processing shaders."; public override string Description => - "MenuPaletteEffect is renamed to MenuPostProcessEffect."; + "MenuPaletteEffect is renamed to MenuPostProcessEffect.\n" + + "ChronoshiftPaletteEffect is renamed to ChronoshiftPostProcessEffect."; public override IEnumerable UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode) { actorNode.RenameChildrenMatching("MenuPaletteEffect", "MenuPostProcessEffect"); + actorNode.RenameChildrenMatching("ChronoshiftPaletteEffect", "ChronoshiftPostProcessEffect"); yield break; } diff --git a/glsl/postprocess_chronoshift.frag b/glsl/postprocess_chronoshift.frag new file mode 100644 index 0000000000..88f7636ff1 --- /dev/null +++ b/glsl/postprocess_chronoshift.frag @@ -0,0 +1,31 @@ +#version {VERSION} +#ifdef GL_ES +precision mediump float; +#endif + +uniform float Blend; +uniform sampler2D WorldTexture; + +#if __VERSION__ == 120 +uniform vec2 WorldTextureSize; +#else +out vec4 fragColor; +#endif + +void main() +{ +#if __VERSION__ == 120 + vec4 c = texture2D(WorldTexture, gl_FragCoord.xy / WorldTextureSize); +#else + vec4 c = texture(WorldTexture, gl_FragCoord.xy / textureSize(WorldTexture, 0)); +#endif + + float lum = 0.5 * (min(c.r, min(c.g, c.b)) + max(c.r, max(c.g, c.b))); + c = vec4(lum, lum, lum, c.a) * Blend + c * (1.0 - Blend); + + #if __VERSION__ == 120 + gl_FragColor = c; + #else + fragColor = c; + #endif +} diff --git a/mods/ra/maps/mousetrap/rules.yaml b/mods/ra/maps/mousetrap/rules.yaml index 9ce276bb1b..f76ef1f055 100644 --- a/mods/ra/maps/mousetrap/rules.yaml +++ b/mods/ra/maps/mousetrap/rules.yaml @@ -22,7 +22,7 @@ World: ClearNoSmudges: 100 ^Palettes: - -ChronoshiftPaletteEffect: + -ChronoshiftPostProcessEffect: # Used in ChronoEffect. 1TNK: diff --git a/mods/ra/rules/palettes.yaml b/mods/ra/rules/palettes.yaml index a8405ba29e..b870083bf6 100644 --- a/mods/ra/rules/palettes.yaml +++ b/mods/ra/rules/palettes.yaml @@ -99,7 +99,7 @@ RotationBase: 32 LightPaletteRotator: ExcludePalettes: terrain, effect, desert - ChronoshiftPaletteEffect: + ChronoshiftPostProcessEffect: FlashPaletteEffect@NUKE: Type: Nuke IndexedPalette@CIV2: