Skip to content

Instantly share code, notes, and snippets.

@thatcosmonaut
Last active June 24, 2020 04:17
Show Gist options
  • Save thatcosmonaut/14c5d49b45d006b90adc0103014260ad to your computer and use it in GitHub Desktop.
Save thatcosmonaut/14c5d49b45d006b90adc0103014260ad to your computer and use it in GitHub Desktop.
FNA Background Shader Example
#define SV_POSITION POSITION
uniform float time;
struct VertexShaderOutput {
float4 Position : TEXCOORD0;
float4 Color : COLOR0;
float2 TextureCoordinates : TEXCOORD1;
};
static float3 colors[32] = {
float3(0.094, 0.078, 0.145),
float3(0.149, 0.168, 0.266),
float3(0.247, 0.156, 0.196),
float3(0.098, 0.235, 0.243),
float3(0.149, 0.360, 0.258),
float3(0.227, 0.266, 0.400),
float3(0.454, 0.247, 0.223),
float3(0.070, 0.305, 0.537),
float3(0.407, 0.219, 0.423),
float3(0.243, 0.537, 0.282),
float3(0.619, 0.156, 0.207),
float3(0.352, 0.411, 0.533),
float3(0.745, 0.290, 0.184),
float3(0.721, 0.435, 0.313),
float3(0.388, 0.780, 0.301),
float3(0.709, 0.313, 0.533),
float3(0.894, 0.231, 0.266),
float3(0.847, 0.462, 0.266),
float3(0.760, 0.521, 0.411),
float3(1.000, 0.000, 0.266),
float3(0.545, 0.607, 0.705),
float3(0.968, 0.462, 0.133),
float3(0.000, 0.584, 0.913),
float3(0.964, 0.458, 0.478),
float3(0.894, 0.650, 0.447),
float3(0.996, 0.682, 0.203),
float3(0.909, 0.717, 0.588),
float3(0.172, 0.909, 0.960),
float3(0.752, 0.796, 0.862),
float3(0.996, 0.905, 0.380),
float3(0.917, 0.831, 0.666),
float3(1.0, 1.0, 1.0)
};
float3 hsv_to_rgb(float3 HSV) {
float3 RGB = HSV.z;
float var_h = HSV.x * 6;
float var_i = floor(var_h);
float var_1 = HSV.z * (1.0 - HSV.y);
float var_2 = HSV.z * (1.0 - HSV.y * (var_h - var_i));
float var_3 = HSV.z * (1.0 - HSV.y * (1 - (var_h - var_i)));
if (var_i == 0) { RGB = float3(HSV.z, var_3, var_1); }
else if (var_i == 1) { RGB = float3(var_2, HSV.z, var_1); }
else if (var_i == 2) { RGB = float3(var_1, HSV.z, var_3); }
else if (var_i == 3) { RGB = float3(var_1, var_2, HSV.z); }
else if (var_i == 4) { RGB = float3(var_3, var_1, HSV.z); }
else { RGB = float3(HSV.z, var_1, var_2); }
return (RGB);
}
float wrap(float n) {
if (n > 1) {
n = n % 1;
}
else if (n < 0) {
n = (abs(n)) % 1;
}
return n;
}
float posterize(float n, float steps) {
n *= steps;
n = floor(n);
n /= steps;
return n;
}
float4 MainPS(VertexShaderOutput input) : COLOR
{
float x = floor(input.Position.x * (160));
float y = floor(input.Position.y * (120));
float hue = sin(time / 4 + y / 20) * sin(time / 8 + y / 60);
hue = frac(hue);
float saturation = tan(x - y + time);
saturation = clamp(saturation, 1, 1);
float value = (cos(y / 2) + sin(x / 4 + time) + cos(y / 6 + time) + sin(x / 8)) * sin(x / 10 + y / 12) + sin((x / 14 + time) + (y / 16 + time));
value = posterize(value, 1);
if (saturation > 1 && value > 0) {
saturation = 1;
}
float3 hsv = float3(hue, saturation, value);
float3 rgb = hsv_to_rgb(hsv);
if (length(rgb) >= length(float3(1, 1, 1)) || (rgb.r <= 0 && rgb.g <= 0 && rgb.b <= 0)) {
hsv = float3(254.0 / 360, 0.45, 0.14);
}
rgb = hsv_to_rgb(hsv);
float3 closest = float3(0, 0, 0);
float closest_dist = 3.402823466e+38;
for (int color_index = 0; color_index < 32; color_index++) {
float3 palette_color = colors[color_index];
float dist = distance(palette_color, rgb);
if (dist < closest_dist) {
closest = palette_color;
closest_dist = dist;
}
}
return float4(closest, 1.0);
}
technique SpriteDrawing {
pass P0 {
PixelShader = compile ps_3_0 MainPS();
}
};
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace ShaderTest
{
class ShaderTestGame : Game
{
GraphicsDeviceManager graphics;
Effect backgroundEffect;
RenderTarget2D backgroundRenderTarget;
SpriteBatch spriteBatch;
Texture2D whitePixel;
float elapsedTime = 0f;
public ShaderTestGame()
{
graphics = new GraphicsDeviceManager(this);
graphics.PreferredBackBufferWidth = 1280;
graphics.PreferredBackBufferHeight = 720;
graphics.PreferMultiSampling = false;
Content.RootDirectory = "Content";
Window.AllowUserResizing = false;
IsMouseVisible = true;
}
protected override void LoadContent()
{
base.LoadContent();
spriteBatch = new SpriteBatch(GraphicsDevice);
backgroundEffect = new Effect(GraphicsDevice, System.IO.File.ReadAllBytes("ShaderTest/Content/Background.fxo"));
backgroundRenderTarget = new RenderTarget2D(GraphicsDevice, 1280, 720);
whitePixel = new Texture2D(GraphicsDevice, 1, 1);
whitePixel.SetData(new[] { Color.White });
GraphicsDevice.SetRenderTarget(backgroundRenderTarget);
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied);
spriteBatch.Draw(whitePixel, new Rectangle(0, 0, 1280, 720), Color.White);
spriteBatch.End();
GraphicsDevice.SetRenderTarget(null);
}
protected override void UnloadContent()
{
base.UnloadContent();
}
protected override void Update(GameTime gameTime)
{
elapsedTime += (float)gameTime.ElapsedGameTime.TotalSeconds;
backgroundEffect.Parameters["time"].SetValue(elapsedTime);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, null, null, null, backgroundEffect);
spriteBatch.Draw(backgroundRenderTarget, Vector2.Zero, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment