From 2c113ed6421ee6e256377bfa0938b5465bd07a93 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Wed, 9 Dec 2020 12:44:53 -0800 Subject: [PATCH] palette crush effect --- Effects/FXB/PaletteCrushEffect.fxb | 3 ++ Effects/HLSL/PaletteCrushEffect.fx | 66 ++++++++++++++++++++++++++++++ Effects/PaletteCrushEffect.cs | 51 +++++++++++++++++++++++ Kav.Core.csproj | 3 ++ Kav.Framework.csproj | 3 ++ Renderer.cs | 4 +- Resources.cs | 13 ++++++ 7 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 Effects/FXB/PaletteCrushEffect.fxb create mode 100644 Effects/HLSL/PaletteCrushEffect.fx create mode 100644 Effects/PaletteCrushEffect.cs diff --git a/Effects/FXB/PaletteCrushEffect.fxb b/Effects/FXB/PaletteCrushEffect.fxb new file mode 100644 index 0000000..dfb94e4 --- /dev/null +++ b/Effects/FXB/PaletteCrushEffect.fxb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:601be54d2ff0278fd16cffd6954d26694c370f7356a715498d94932fe77e3a2f +size 1432 diff --git a/Effects/HLSL/PaletteCrushEffect.fx b/Effects/HLSL/PaletteCrushEffect.fx new file mode 100644 index 0000000..6126199 --- /dev/null +++ b/Effects/HLSL/PaletteCrushEffect.fx @@ -0,0 +1,66 @@ +#include "Macros.fxh" + +#define FLT_MAX 3.402823466e+38 + +DECLARE_TEXTURE(Texture, 0); +DECLARE_TEXTURE(Palette, 1); + +BEGIN_CONSTANTS + + int PaletteWidth _ps(c0) _cb(c0); + +END_CONSTANTS + +struct VertexInput +{ + float4 Position : POSITION; + float2 TexCoord : TEXCOORD; +}; + +struct PixelInput +{ + float4 Position : SV_POSITION; + float2 TexCoord : TEXCOORD0; +}; + +PixelInput main_vs(VertexInput input) +{ + PixelInput output; + + output.Position = input.Position; + output.TexCoord = input.TexCoord; + + return output; +} + +float4 main_ps(PixelInput input) : SV_TARGET0 +{ + float4 sampled = SAMPLE_TEXTURE(Texture, input.TexCoord); + + float3 sampled_color = sampled.rgb; + + float3 closest_color = float3(0, 0, 0); + float closest_dist = FLT_MAX; + + for (int i = 0; i < PaletteWidth; i++) + { + float3 palette_color = SAMPLE_TEXTURE(Palette, float2(i / (float)PaletteWidth, 0)); + float dist = distance(palette_color, sampled_color); + if (dist < closest_dist) + { + closest_dist = dist; + closest_color = palette_color; + } + } + + return float4(closest_color, sampled.a); +} + +Technique PaletteCrush +{ + Pass + { + VertexShader = compile vs_3_0 main_vs(); + PixelShader = compile ps_3_0 main_ps(); + } +} diff --git a/Effects/PaletteCrushEffect.cs b/Effects/PaletteCrushEffect.cs new file mode 100644 index 0000000..0f3a854 --- /dev/null +++ b/Effects/PaletteCrushEffect.cs @@ -0,0 +1,51 @@ +using Microsoft.Xna.Framework.Graphics; + +namespace Kav +{ + public class PaletteCrushEffect : Effect + { + EffectParameter textureParam; + EffectParameter paletteParam; + EffectParameter paletteWidthParam; + + Texture2D texture; + Texture2D palette; + + int paletteWidth; + + public Texture2D Texture + { + get { return texture; } + set + { + texture = value; + textureParam.SetValue(texture); + } + } + + public Texture2D Palette + { + get { return palette; } + set + { + palette = value; + paletteWidth = palette.Width; + paletteParam.SetValue(palette); + paletteWidthParam.SetValue(paletteWidth); + } + } + + public PaletteCrushEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.PaletteCrushEffect) + { + CacheEffectParameters(); + } + + void CacheEffectParameters() + { + textureParam = Parameters["Texture"]; + paletteParam = Parameters["Palette"]; + + paletteWidthParam = Parameters["PaletteWidth"]; + } + } +} diff --git a/Kav.Core.csproj b/Kav.Core.csproj index 7ed1272..541feb0 100644 --- a/Kav.Core.csproj +++ b/Kav.Core.csproj @@ -58,6 +58,9 @@ Kav.Resources.DiffuseLitSpriteEffect.fxb + + Kav.Resources.PaletteCrushEffect.fxb + Kav.Resources.UnitCube.glb diff --git a/Kav.Framework.csproj b/Kav.Framework.csproj index 90aacaa..1cf665d 100644 --- a/Kav.Framework.csproj +++ b/Kav.Framework.csproj @@ -58,6 +58,9 @@ Kav.Resources.DiffuseLitSpriteEffect.fxb + + Kav.Resources.PaletteCrushEffect.fxb + Kav.Resources.UnitCube.glb diff --git a/Renderer.cs b/Renderer.cs index 9c97fef..59da550 100644 --- a/Renderer.cs +++ b/Renderer.cs @@ -26,7 +26,7 @@ namespace Kav private Effect ToneMapEffect { get; } private SkyboxEffect SkyboxEffect { get; } private DiffuseLitSpriteEffect DiffuseLitSpriteEffect { get; } - + private Kav.Model UnitCube { get; } public Renderer( @@ -180,7 +180,7 @@ namespace Kav } } - private IEnumerable<(MeshSprite, Matrix)> BillboardTransforms( + private static IEnumerable<(MeshSprite, Matrix)> BillboardTransforms( PerspectiveCamera camera, IEnumerable<(MeshSprite, SpriteBillboardConstraint, Matrix)> meshSpriteBillboardTransforms ) { diff --git a/Resources.cs b/Resources.cs index da6c5e8..ae53a3d 100644 --- a/Resources.cs +++ b/Resources.cs @@ -171,6 +171,18 @@ namespace Kav } } + public static byte[] PaletteCrushEffect + { + get + { + if (paletteCrushEffect == null) + { + paletteCrushEffect = GetResource("PaletteCrushEffect.fxb"); + } + return paletteCrushEffect; + } + } + public static byte[] UnitCubeModel { get @@ -197,6 +209,7 @@ namespace Kav private static byte[] linearDepthEffectInstanced; private static byte[] skyboxEffect; private static byte[] diffuseLitSpriteEffect; + private static byte[] paletteCrushEffect; private static byte[] unitCubeModel;