Skip to content

Commit

Permalink
implement support for boom transfer heights colormaps
Browse files Browse the repository at this point in the history
  • Loading branch information
nstlaurent committed Jan 8, 2024
1 parent ce3675e commit 632a0fb
Show file tree
Hide file tree
Showing 19 changed files with 186 additions and 90 deletions.
10 changes: 9 additions & 1 deletion Core/Layer/Worlds/WorldLayer.Render.Hud.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using Helion.Geometry.Vectors;
using Helion.Graphics;
using Helion.Graphics.Geometry;
using Helion.Graphics.Palettes;
using Helion.Render;
using Helion.Render.Common;
using Helion.Render.Common.Context;
using Helion.Render.Common.Enums;
Expand Down Expand Up @@ -347,7 +349,13 @@ private void DrawHudWeapon(IHudRenderContext hud, FrameState frameState, int yOf
lightLevel = GLHelper.DoomLightLevelToColor(lightLevel, extraLight);
}

Color lightLevelColor = ((byte)lightLevel, (byte)lightLevel, (byte)lightLevel);
var camera = World.GetCameraPlayer().GetCamera(m_lastTickInfo.Fraction);
var colorMix = Renderer.GetColorMix(Player, camera);

Color lightLevelColor = ((byte)(Math.Min(lightLevel * colorMix.X, 255)),
(byte)(Math.Min(lightLevel * colorMix.Y, 255)),
(byte)(Math.Min(lightLevel * colorMix.Z, 255)));

string sprite = GetHudWeaponSpriteString(frameState, flash);

if (!hud.Textures.TryGet(sprite, out var handle, ResourceNamespace.Sprites))
Expand Down
3 changes: 3 additions & 0 deletions Core/Models/SectorModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ public class SectorModel
public int? TransferFloorLight;
public int? TransferCeilingLight;
public int? TransferHeights;
public string? TransferHeightsColormapUpper;
public string? TransferHeightsColormapMiddle;
public string? TransferHeightsColormapLower;
public double? Friction;
public SectorEffect? SectorEffect;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class EntityProgram : RenderProgram
private readonly int m_extraLightLocation;
private readonly int m_viewRightNormalLocation;
private readonly int m_distanceOffsetLocation;
private readonly int m_colorMixLocation;

public EntityProgram() : base("Entity")
{
Expand All @@ -32,6 +33,7 @@ public EntityProgram() : base("Entity")
m_extraLightLocation = Uniforms.GetLocation("extraLight");
m_viewRightNormalLocation = Uniforms.GetLocation("viewRightNormal");
//m_distanceOffsetLocation = Uniforms.GetLocation("distanceOffset");
m_colorMixLocation = Uniforms.GetLocation("colorMix");
}

public void BoundTexture(TextureUnit unit) => Uniforms.Set(unit, m_boundTextureLocation);
Expand All @@ -44,6 +46,7 @@ public EntityProgram() : base("Entity")
public void TimeFrac(float frac) => Uniforms.Set(frac, m_timeFracLocation);
public void ViewRightNormal(Vec2F viewRightNormal) => Uniforms.Set(viewRightNormal, m_viewRightNormalLocation);
public void DistanceOffset(float distance) => Uniforms.Set(distance, m_distanceOffsetLocation);
public void ColorMix(Vec3F color) => Uniforms.Set(color, m_colorMixLocation);

protected override string VertexShader() => @"
#version 330
Expand Down Expand Up @@ -167,6 +170,7 @@ void main()
uniform sampler2D boundTexture;
uniform float lightLevelMix;
uniform int extraLight;
uniform vec3 colorMix;
// These two functions are found here:
// https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83
Expand Down Expand Up @@ -207,6 +211,8 @@ void main()
if (fragColor.w <= 0.0)
discard;
fragColor.xyz *= min(colorMix, 1);
// If invulnerable, grayscale everything and crank the brightness.
// Note: The 1.5x is a visual guess to make it look closer to vanilla.
if (hasInvulnerability != 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using GlmSharp;
using Helion.Geometry.Vectors;
using Helion.Graphics.Palettes;
using Helion.Render.OpenGL.Renderers.Legacy.World.Data;
using Helion.Render.OpenGL.Shared;
using Helion.Render.OpenGL.Shared.World.ViewClipping;
Expand Down Expand Up @@ -195,37 +196,19 @@ public unsafe void RenderEntity(Sector viewSector, Entity entity, in Vec3D posit

private void SetUniforms(RenderInfo renderInfo)
{
const int TicksPerFrame = 4;
const int DifferentFrames = 8;

mat4 mvp = Renderer.CalculateMvpMatrix(renderInfo);
mat4 mvpNoPitch = Renderer.CalculateMvpMatrix(renderInfo, true);
float fuzzFrac = (((WorldStatic.World.GameTicker / TicksPerFrame) % DifferentFrames)) + 1;
bool drawInvulnerability = false;
int extraLight = 0;
float mix = 0.0f;

if (renderInfo.ViewerEntity.PlayerObj != null)
{
if (renderInfo.ViewerEntity.PlayerObj.DrawFullBright())
mix = 1.0f;
if (renderInfo.ViewerEntity.PlayerObj.DrawInvulnerableColorMap())
drawInvulnerability = true;

extraLight = renderInfo.ViewerEntity.PlayerObj.GetExtraLightRender();
}

var uniforms = Renderer.GetShaderUniforms(renderInfo);
SetViewDirection(renderInfo.Camera.Direction.XY.Double);
m_program.BoundTexture(TextureUnit.Texture0);
m_program.ExtraLight(extraLight);
m_program.HasInvulnerability(drawInvulnerability);
m_program.LightLevelMix(mix);
m_program.Mvp(mvp);
m_program.MvpNoPitch(mvpNoPitch);
m_program.FuzzFrac(fuzzFrac);
m_program.ExtraLight(uniforms.ExtraLight);
m_program.HasInvulnerability(uniforms.DrawInvulnerability);
m_program.LightLevelMix(uniforms.Mix);
m_program.Mvp(uniforms.Mvp);
m_program.MvpNoPitch(uniforms.MvpNoPitch);
m_program.FuzzFrac(uniforms.TimeFrac);
m_program.TimeFrac(renderInfo.TickFraction);
m_program.ViewRightNormal(m_viewRightNormal);
m_program.DistanceOffset(Renderer.GetDistanceOffset(renderInfo));
m_program.ColorMix(uniforms.ColorMix);
}

public void RenderAlpha(RenderInfo renderInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class FloodFillProgram : RenderProgram
private readonly int m_lightLevelMixLocation;
private readonly int m_extraLightLocation;
private readonly int m_distanceOffsetLocation;
private readonly int m_colorMixLocation;

public FloodFillProgram() : base("Flood fill plane")
{
Expand All @@ -31,6 +32,7 @@ public FloodFillProgram() : base("Flood fill plane")
m_lightLevelMixLocation = Uniforms.GetLocation("lightLevelMix");
m_extraLightLocation = Uniforms.GetLocation("extraLight");
m_distanceOffsetLocation = Uniforms.GetLocation("distanceOffset");
m_colorMixLocation = Uniforms.GetLocation("colorMix");
}

public void BoundTexture(TextureUnit unit) => Uniforms.Set(unit, m_boundTextureLocation);
Expand All @@ -44,6 +46,7 @@ public FloodFillProgram() : base("Flood fill plane")
public void LightLevelMix(float lightLevelMix) => Uniforms.Set(lightLevelMix, m_lightLevelMixLocation);
public void ExtraLight(int extraLight) => Uniforms.Set(extraLight, m_extraLightLocation);
public void DistanceOffset(float distance) => Uniforms.Set(distance, m_distanceOffsetLocation);
public void ColorMix(Vec3F color) => Uniforms.Set(color, m_colorMixLocation);

protected override string VertexShader() => @"
#version 330
Expand Down Expand Up @@ -99,6 +102,7 @@ protected override string FragmentShader() => @"
uniform vec3 camera;
uniform mat4 mvpNoPitch;
uniform int hasInvulnerability;
uniform vec3 colorMix;
${LightLevelFragVariables}
${LightLevelConstants}
Expand All @@ -120,6 +124,8 @@ void main()
fragColor = texture(boundTexture, uv);
fragColor.xyz *= lightLevel;
fragColor.xyz *= min(colorMix, 1);
// If invulnerable, grayscale everything and crank the brightness.
// Note: The 1.5x is a visual guess to make it look closer to vanilla.
if (hasInvulnerability != 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,35 +194,22 @@ private static void OverwriteAndSubUploadVboWithZero(VertexBufferObject<FloodFil

public void Render(RenderInfo renderInfo)
{
mat4 mvp = Renderer.CalculateMvpMatrix(renderInfo);
bool drawInvulnerability = false;
int extraLight = 0;
float mix = 0.0f;

if (renderInfo.ViewerEntity.PlayerObj != null)
{
if (renderInfo.ViewerEntity.PlayerObj.DrawFullBright())
mix = 1.0f;
if (renderInfo.ViewerEntity.PlayerObj.DrawInvulnerableColorMap())
drawInvulnerability = true;

extraLight = renderInfo.ViewerEntity.PlayerObj.GetExtraLightRender();
}

var uniforms = Renderer.GetShaderUniforms(renderInfo);
m_program.Bind();

GL.ActiveTexture(TextureUnit.Texture0);
m_program.BoundTexture(TextureUnit.Texture0);
m_program.SectorLightTexture(TextureUnit.Texture1);
m_program.Camera(renderInfo.Camera.PositionInterpolated);
m_program.Mvp(mvp);
m_program.Mvp(uniforms.Mvp);
m_program.TimeFrac(renderInfo.TickFraction);
m_program.HasInvulnerability(drawInvulnerability);
m_program.MvpNoPitch(Renderer.CalculateMvpMatrix(renderInfo, true));
m_program.HasInvulnerability(uniforms.DrawInvulnerability);
m_program.MvpNoPitch(uniforms.MvpNoPitch);
m_program.TimeFrac(renderInfo.TickFraction);
m_program.LightLevelMix(mix);
m_program.ExtraLight(extraLight);
m_program.DistanceOffset(Renderer.GetDistanceOffset(renderInfo));
m_program.LightLevelMix(uniforms.Mix);
m_program.ExtraLight(uniforms.ExtraLight);
m_program.DistanceOffset(uniforms.DistanceOffset);
m_program.ColorMix(uniforms.ColorMix);

for (int i = 0; i < m_floodFillInfos.Count; i++)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using GlmSharp;
using Helion.Geometry.Vectors;
using Helion.Render.OpenGL.Renderers.Legacy.World.Shader;
using Helion.Render.OpenGL.Shader;
using OpenTK.Graphics.OpenGL;
Expand All @@ -16,6 +17,7 @@ public class InterpolationShader : RenderProgram
private readonly int m_lightLevelMixLocation;
private readonly int m_extraLightLocation;
private readonly int m_distanceOffsetLocation;
private readonly int m_colorMixLocation;

public InterpolationShader() : base("World")
{
Expand All @@ -28,6 +30,7 @@ public InterpolationShader() : base("World")
m_lightLevelMixLocation = Uniforms.GetLocation("lightLevelMix");
m_extraLightLocation = Uniforms.GetLocation("extraLight");
m_distanceOffsetLocation = Uniforms.GetLocation("distanceOffset");
m_colorMixLocation = Uniforms.GetLocation("colorMix");
}

public void BoundTexture(TextureUnit unit) => Uniforms.Set(unit, m_boundTextureLocation);
Expand All @@ -40,6 +43,7 @@ public InterpolationShader() : base("World")
public void LightLevelMix(float lightLevelMix) => Uniforms.Set(lightLevelMix, m_lightLevelMixLocation);
public void ExtraLight(int extraLight) => Uniforms.Set(extraLight, m_extraLightLocation);
public void DistanceOffset(float distance) => Uniforms.Set(distance, m_distanceOffsetLocation);
public void ColorMix(Vec3F color) => Uniforms.Set(color, m_colorMixLocation);

protected override string VertexShader() => @"
#version 330
Expand Down Expand Up @@ -92,6 +96,7 @@ protected override string FragmentShader() => @"
uniform int hasInvulnerability;
uniform sampler2D boundTexture;
uniform vec3 colorMix;
${LightLevelFragVariables}
Expand All @@ -108,6 +113,8 @@ void main() {
if (fragColor.w <= 0.0)
discard;
fragColor.xyz *= min(colorMix, 1);
// If invulnerable, grayscale everything and crank the brightness.
// Note: The 1.5x is a visual guess to make it look closer to vanilla.
if (hasInvulnerability != 0)
Expand Down
38 changes: 4 additions & 34 deletions Core/Render/OpenGL/Renderers/Legacy/World/LegacyWorldRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Helion.Geometry.Boxes;
using Helion.Geometry.Segments;
using Helion.Geometry.Vectors;
using Helion.Graphics.Palettes;
using Helion.Render.OpenGL.Renderers.Legacy.World.Automap;
using Helion.Render.OpenGL.Renderers.Legacy.World.Data;
using Helion.Render.OpenGL.Renderers.Legacy.World.Entities;
Expand Down Expand Up @@ -261,7 +262,7 @@ protected override void PerformRender(IWorld world, RenderInfo renderInfo)
m_geometryRenderer.RenderPortalsAndSkies(renderInfo);
m_entityRenderer.RenderNonAlpha(renderInfo);

var uniforms = GetShaderUniforms(renderInfo);
var uniforms = Renderer.GetShaderUniforms(renderInfo);

m_interpolationProgram.Bind();
GL.ActiveTexture(TextureUnit.Texture0);
Expand Down Expand Up @@ -390,6 +391,7 @@ private void SetInterpolationUniforms(RenderInfo renderInfo, ShaderUniforms unif
m_interpolationProgram.LightLevelMix(uniforms.Mix);
m_interpolationProgram.ExtraLight(uniforms.ExtraLight);
m_interpolationProgram.DistanceOffset(uniforms.DistanceOffset);
m_interpolationProgram.ColorMix(uniforms.ColorMix);
}

private void SetStaticUniforms(RenderInfo renderInfo, ShaderUniforms uniforms)
Expand All @@ -402,39 +404,7 @@ private void SetStaticUniforms(RenderInfo renderInfo, ShaderUniforms uniforms)
m_staticProgram.LightLevelMix(uniforms.Mix);
m_staticProgram.ExtraLight(uniforms.ExtraLight);
m_staticProgram.DistanceOffset(uniforms.DistanceOffset);
}

private ShaderUniforms GetShaderUniforms(RenderInfo renderInfo)
{
// We divide by 4 to make it so the noise changes every four ticks.
// We then mod by 8 so that the number stays small (or else when it
// is multiplied in the shader it will overflow very quickly if we
// don't do this). This could be any number, I just arbitrarily
// chose 8. This means there are 8 different versions that are to
// be rendered if the person stares at an unmoving body long enough.
// Then we add 1 because if the value is 0, then the noise formula
// outputs zero uniformly which makes it look invisible.
const int TicksPerFrame = 4;
const int DifferentFrames = 8;

float timeFrac = ((WorldStatic.World.Gametick / TicksPerFrame) % DifferentFrames) + 1;
bool drawInvulnerability = false;
int extraLight = 0;
float mix = 0.0f;

if (renderInfo.ViewerEntity.PlayerObj != null)
{
if (renderInfo.ViewerEntity.PlayerObj.DrawFullBright())
mix = 1.0f;
if (renderInfo.ViewerEntity.PlayerObj.DrawInvulnerableColorMap())
drawInvulnerability = true;

extraLight = renderInfo.ViewerEntity.PlayerObj.GetExtraLightRender();
}

return new ShaderUniforms(Renderer.CalculateMvpMatrix(renderInfo),
Renderer.CalculateMvpMatrix(renderInfo, true),
timeFrac, drawInvulnerability, mix, extraLight, Renderer.GetDistanceOffset(renderInfo));
m_staticProgram.ColorMix(uniforms.ColorMix);
}

private void ReleaseUnmanagedResources()
Expand Down
5 changes: 4 additions & 1 deletion Core/Render/OpenGL/Renderers/Legacy/World/ShaderUniforms.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using GlmSharp;
using Helion.Geometry.Vectors;

namespace Helion.Render.OpenGL.Renderers.Legacy.World;

Expand All @@ -11,8 +12,9 @@ public readonly struct ShaderUniforms
public readonly bool DrawInvulnerability;
public readonly int ExtraLight;
public readonly float DistanceOffset;
public readonly Vec3F ColorMix;

public ShaderUniforms(mat4 mvp, mat4 mvpNoPitch, float timeFrac, bool drawInvulnerability, float mix, int extraLight, float distanceOffset)
public ShaderUniforms(mat4 mvp, mat4 mvpNoPitch, float timeFrac, bool drawInvulnerability, float mix, int extraLight, float distanceOffset, Vec3F colorMix)
{
Mvp = mvp;
MvpNoPitch = mvpNoPitch;
Expand All @@ -21,5 +23,6 @@ public ShaderUniforms(mat4 mvp, mat4 mvpNoPitch, float timeFrac, bool drawInvuln
DrawInvulnerability = drawInvulnerability;
ExtraLight = extraLight;
DistanceOffset = distanceOffset;
ColorMix = colorMix;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ public void RenderWorldGeometry(RenderInfo renderInfo)
{
m_geometryProgram.Bind();

m_geometryProgram.Mvp(Renderer.CalculateMvpMatrix(renderInfo));
var uniforms = Renderer.GetShaderUniforms(renderInfo);
m_geometryProgram.Mvp(uniforms.Mvp);

m_geometryVbo.UploadIfNeeded();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
using GlmSharp;
using Helion.Geometry.Vectors;
using Helion.Render.OpenGL.Shader;

namespace Helion.Render.OpenGL.Renderers.Legacy.World.Sky.Sphere;

public class SkySphereGeometryShader : RenderProgram
{
private readonly int m_mvpLocation;

public SkySphereGeometryShader() : base("Sky sphere geometry")
{
m_mvpLocation = Uniforms.GetLocation("mvp");
}

public void Mvp(mat4 mat) => Uniforms.Set(mat, "mvp");
Expand Down
Loading

0 comments on commit 632a0fb

Please sign in to comment.