From dcd3e8d4445459aebfa41e0790bf4192810a4924 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Tue, 27 Jul 2021 14:09:48 +0100 Subject: [PATCH] Ignore terrain slopes when calculating model shadows. This is less realistic, but better matches the original game and is the only practical way to reduce visual issues caused by long shadows being cast over multiple cells. --- OpenRA.Game/Graphics/ModelRenderer.cs | 8 ++++++-- OpenRA.Mods.Common/Graphics/ModelRenderable.cs | 6 +----- OpenRA.Mods.Common/Graphics/UIModelRenderable.cs | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/OpenRA.Game/Graphics/ModelRenderer.cs b/OpenRA.Game/Graphics/ModelRenderer.cs index 2767eaa544..8bc7ae8e65 100644 --- a/OpenRA.Game/Graphics/ModelRenderer.cs +++ b/OpenRA.Game/Graphics/ModelRenderer.cs @@ -42,6 +42,7 @@ namespace OpenRA.Graphics static readonly float[] ZVector = new float[] { 0, 0, 1, 1 }; static readonly float[] FlipMtx = Util.ScaleMatrix(1, -1, 1); static readonly float[] ShadowScaleFlipMtx = Util.ScaleMatrix(2, -2, 2); + static readonly float[] GroundNormal = { 0, 0, 1, 1 }; readonly Renderer renderer; readonly IShader shader; @@ -80,7 +81,7 @@ namespace OpenRA.Graphics public ModelRenderProxy RenderAsync( WorldRenderer wr, IEnumerable models, in WRot camera, float scale, - float[] groundNormal, in WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor, + in WRot groundOrientation, in WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor, PaletteReference color, PaletteReference normals, PaletteReference shadowPalette) { if (!isInFrame) @@ -92,7 +93,10 @@ namespace OpenRA.Graphics // Correct for bogus light source definition var lightYaw = Util.MakeFloatMatrix(new WRot(WAngle.Zero, WAngle.Zero, -lightSource.Yaw).AsMatrix()); var lightPitch = Util.MakeFloatMatrix(new WRot(WAngle.Zero, -lightSource.Pitch, WAngle.Zero).AsMatrix()); - var shadowTransform = Util.MatrixMultiply(lightPitch, lightYaw); + var ground = Util.MakeFloatMatrix(groundOrientation.AsMatrix()); + var shadowTransform = Util.MatrixMultiply(Util.MatrixMultiply(lightPitch, lightYaw), Util.MatrixInverse(ground)); + + var groundNormal = Util.MatrixVectorMultiply(ground, GroundNormal); var invShadowTransform = Util.MatrixInverse(shadowTransform); var cameraTransform = Util.MakeFloatMatrix(camera.AsMatrix()); diff --git a/OpenRA.Mods.Common/Graphics/ModelRenderable.cs b/OpenRA.Mods.Common/Graphics/ModelRenderable.cs index b6614abb8d..1f152c46c4 100644 --- a/OpenRA.Mods.Common/Graphics/ModelRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/ModelRenderable.cs @@ -116,8 +116,6 @@ namespace OpenRA.Mods.Common.Graphics palette, normalsPalette, shadowPalette, alpha, newTint, newTintModifiers); } - // This will need generalizing once we support TS/RA2 terrain - static readonly float[] GroundNormal = new float[] { 0, 0, 1, 1 }; public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return new FinalizedModelRenderable(wr, this); @@ -135,10 +133,8 @@ namespace OpenRA.Mods.Common.Graphics var map = wr.World.Map; var groundOrientation = map.TerrainOrientation(map.CellContaining(model.pos)); - var groundNormal = OpenRA.Graphics.Util.MatrixVectorMultiply(OpenRA.Graphics.Util.MakeFloatMatrix(groundOrientation.AsMatrix()), GroundNormal); - renderProxy = Game.Renderer.WorldModelRenderer.RenderAsync( - wr, draw, model.camera, model.scale, groundNormal, model.lightSource, + wr, draw, model.camera, model.scale, groundOrientation, model.lightSource, model.lightAmbientColor, model.lightDiffuseColor, model.palette, model.normalsPalette, model.shadowPalette); } diff --git a/OpenRA.Mods.Common/Graphics/UIModelRenderable.cs b/OpenRA.Mods.Common/Graphics/UIModelRenderable.cs index e05097aca1..aa839928ff 100644 --- a/OpenRA.Mods.Common/Graphics/UIModelRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/UIModelRenderable.cs @@ -68,7 +68,6 @@ namespace OpenRA.Mods.Common.Graphics public IRenderable OffsetBy(in WVec vec) { return this; } public IRenderable AsDecoration() { return this; } - static readonly float[] GroundNormal = { 0, 0, 1, 1 }; public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return new FinalizedUIModelRenderable(wr, this); @@ -85,7 +84,7 @@ namespace OpenRA.Mods.Common.Graphics var draw = model.models.Where(v => v.IsVisible); renderProxy = Game.Renderer.WorldModelRenderer.RenderAsync( - wr, draw, model.camera, model.scale, GroundNormal, model.lightSource, + wr, draw, model.camera, model.scale, WRot.None, model.lightSource, model.lightAmbientColor, model.lightDiffuseColor, model.palette, model.normalsPalette, model.shadowPalette); }