Add shader source!
Some checks failed
CI / Linux (push) Has been cancelled

This commit is contained in:
Ethan Lee 2024-11-19 12:00:36 -05:00
parent 64c4850afd
commit 01f2eb5307
31 changed files with 1679 additions and 0 deletions

View file

@ -0,0 +1,21 @@
sampler TextureSampler : register(s0);
sampler LightSampler : register(s1);
float4 BasicString(float2 texCoord : TEXCOORD0, float4 color : COLOR0) : COLOR0
{
float4 colorGround = tex2D(TextureSampler, texCoord);
float4 colorShadow = tex2D(LightSampler, texCoord);
colorShadow.a = 0; // Sets the shadow's alpha to 0, making it invisible instead of black.
float4 resultColor = colorGround * colorShadow + colorShadow * colorGround;
return resultColor;
}
technique Basic
{
pass Pass0
{
PixelShader = compile ps_2_0 BasicString();
}
}

View file

@ -0,0 +1,29 @@
sampler ScreenSampler : register(s0);
sampler MaskSampler : register(s1);
// here we do the real work.
float4 PixelShaderFunction(float2 inCoord: TEXCOORD0) : COLOR
{
// we retrieve the color in the original texture at
// the current coordinate remember that this function
// is run on every pixel in our texture.
float4 color = tex2D(ScreenSampler, inCoord);
// Since we are using a black and white mask the black
// area will have a value of 0 and the white areas will
// have a value of 255. Hence the black areas will subtract
// nothing from our original color, and the white areas of
// our mask will subtract all color from the color.
color.rgba = color.rgba - tex2D(MaskSampler, inCoord).r;
// return the new color of the pixel.
return color;
}
technique
{
pass P0
{
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}

View file

@ -0,0 +1,73 @@
// Effect applies normalmapped lighting to a 2D sprite.
float4 LightIntensity = 1.0;
int NumberOfLights;
float3 LightPosition[5]; // Max number of lights.
float LightSize[5];
float4 AmbientColor = 1;
sampler TextureSampler : register(s0);
sampler NormalSampler : register(s1);
float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
//texCoord coordinates are returned between values 0 to 1.
// Look up the texture and normalmap values.
float4 tex = tex2D(TextureSampler, texCoord);
if (NumberOfLights > 0)
{
float3 normal = tex2D(NormalSampler, texCoord);
float3 pixelPosition = float3(1320 * texCoord.x, 720 * texCoord.y, 0);
float lightAmount = 0;
for (int i = 0; i < NumberOfLights; i++)
{
float internalAmount = max(dot(normal, normalize(LightPosition[i] - pixelPosition)), 0);
if (internalAmount > lightAmount)
lightAmount = internalAmount;
}
color.rgb *= 0 + lightAmount * LightIntensity;
}
return tex * color;
}
float4 AmbientNormalCombination(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
//texCoord coordinates are returned between values 0 to 1.
float4 tex = tex2D(TextureSampler, texCoord);
if (NumberOfLights > 0)
{
float3 normal = tex2D(NormalSampler, texCoord);
float3 pixelPosition = float3(1320 * texCoord.x, 720 * texCoord.y, 0);
float lightAmount = 0;
for (int i = 0; i < NumberOfLights; i++)
{
float internalAmount = max(dot(normal, normalize(LightPosition[i] - pixelPosition)), 0);
if (internalAmount > lightAmount)
lightAmount = internalAmount;
}
if ((lightAmount < 1 && lightAmount > 0.7f)) // Change this second value to shrink the circle.
color = (color * (1 - AmbientColor.a)) + ((AmbientColor + (lightAmount * LightIntensity)) * AmbientColor.a);
else
color.rgb *= 0 + lightAmount * LightIntensity * 2;
}
return tex * color;
}
technique AmbientNormalmap
{
pass Pass1
{
//PixelShader = compile ps_2_0 main();
PixelShader = compile ps_2_0 AmbientNormalCombination();
}
}

View file

@ -0,0 +1,23 @@
sampler TextureSampler : register(s1);
sampler LightSampler : register(s0);
float4 MaskShade(float2 texCoord : TEXCOORD0, float4 color : COLOR0) : COLOR0
{
float4 colorGround = tex2D(TextureSampler, texCoord);
float4 colorShadow = tex2D(LightSampler, texCoord);
float4 resultColor = 0;
if (colorShadow.r == 0 && colorShadow.g == 0 && colorShadow.b == 0)
resultColor = colorGround;
return resultColor;
}
technique Basic
{
pass Pass0
{
PixelShader = compile ps_2_0 MaskShade();
}
}

View file

@ -0,0 +1,29 @@
float BlurDistance = 0.003f;
sampler TextureSampler : register(s0);
float4 BlurShader(float2 Tex:TEXCOORD0) : COLOR0
{
float4 Color;
// Get the texel from ColorMapSampler using a modified texture coordinate. This
// gets the texels at the neighbour texels and adds it to Color.
Color = tex2D( TextureSampler, float2(Tex.x+BlurDistance, Tex.y+BlurDistance));
Color += tex2D( TextureSampler, float2(Tex.x-BlurDistance, Tex.y-BlurDistance));
Color += tex2D( TextureSampler, float2(Tex.x+BlurDistance, Tex.y-BlurDistance));
Color += tex2D( TextureSampler, float2(Tex.x-BlurDistance, Tex.y+BlurDistance));
// We need to devide the color with the amount of times we added
// a color to it, in this case 4, to get the avg. color
Color = Color / 4;
// returned the blurred color
return Color;
}
technique Technique1
{
pass Pass1
{
PixelShader = compile ps_2_0 BlurShader();
}
}

View file

@ -0,0 +1,18 @@
uniform extern float BloomThreshold;
float2 halfPixel;
sampler TextureSampler : register(s0);
float4 BrightPassPS(float2 texCoord : TEXCOORD0) : COLOR0
{
texCoord -= halfPixel;
// Look up the original image color.
float4 c = tex2D(TextureSampler, texCoord);
// Adjust it to keep only values brighter than the specified threshold.
return saturate((c - BloomThreshold) / (1 - BloomThreshold));
}
technique BloomExtract
{
pass P0
{
PixelShader = compile ps_2_0 BrightPassPS();
}
}

View file

@ -0,0 +1,34 @@
sampler TextureSampler : register(s0);
// TODO: add effect parameters here.
float4 desiredTint;
float4 ColourSwappedOut1;
float4 ColourSwappedIn1;
float4 ColourSwappedOut2;
float4 ColourSwappedIn2;
float Opacity = 1;
const float colourBuffer = 0.2f;
float4 PixelShaderFunction(float2 texCoord : TEXCOORD0) : COLOR0
{
float4 color = tex2D(TextureSampler, texCoord);
if (color.r == ColourSwappedOut1.r && color.g == ColourSwappedOut1.g && color.b == ColourSwappedOut1.b)
return ColourSwappedIn1 * Opacity;
if (color.r == ColourSwappedOut2.r && color.g == ColourSwappedOut2.g && color.b == ColourSwappedOut2.b)
return ColourSwappedIn2 * Opacity;
return color * desiredTint * Opacity;
}
technique Technique1
{
pass Pass1
{
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}

View file

@ -0,0 +1,99 @@
float2 ScreenLightPos;
float Density = .5f;
float Decay = .95f;
float Weight = 1.0f;
float Exposure = .08f;
sampler DryImage : register(s0)
{
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
AddressU = Wrap;
AddressV = Wrap;
};
float4 PixelShaderFunction(float2 texCoord : TEXCOORD0) : COLOR0
{
float2 deltaTexCoord = (texCoord - ScreenLightPos.xy);
deltaTexCoord *= 1.0f / 50 * Density;
float4 color = tex2D(DryImage, texCoord);
float illuminationDecay = 1.0f;
for (int i = 0; i < 20; i++)
{
texCoord -= deltaTexCoord;
float4 sample = tex2D(DryImage, texCoord);
sample *= illuminationDecay * Weight;
color += sample;
illuminationDecay *= Decay;
}
return color * Exposure;
}
technique Technique1
{
pass Pass1
{
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}
uniform extern float BloomThreshold;
float2 halfPixel;
sampler TextureSampler : register(s0);
float4 BrightPassPS(float2 texCoord : TEXCOORD0) : COLOR0
{
texCoord -= halfPixel;
// Look up the original image color.
float4 c = tex2D(TextureSampler, texCoord);
// Adjust it to keep only values brighter than the specified threshold.
return saturate((c - BloomThreshold) / (1 - BloomThreshold));
}
technique BloomExtract
{
pass P0
{
PixelShader = compile ps_2_0 BrightPassPS();
}
}
sampler2D Scene: register(s0){
AddressU = Mirror;
AddressV = Mirror;
};
texture OrgScene;
sampler2D orgScene = sampler_state
{
Texture = <OrgScene>;
AddressU = CLAMP;
AddressV = CLAMP;
};
float4 BlendPS(float2 texCoord : TEXCOORD0 ) : COLOR0
{
texCoord -= halfPixel;
float4 col = tex2D(orgScene,texCoord) * tex2D(Scene,texCoord);
return col;
}
float4 AditivePS(float2 texCoord : TEXCOORD0 ) : COLOR0
{
texCoord -= halfPixel;
float4 col = tex2D(orgScene,texCoord) + tex2D(Scene,texCoord);
return col;
}
technique Blend
{
pass p0
{
PixelShader = compile ps_2_0 BlendPS();
}
}
technique Aditive
{
pass p0
{
PixelShader = compile ps_2_0 AditivePS();
}
}

View file

@ -0,0 +1,41 @@
#define RADIUS 7
#define KERNEL_SIZE (RADIUS * 2 + 1)
//-----------------------------------------------------------------------------
// Globals.
//-----------------------------------------------------------------------------
float weights[KERNEL_SIZE];
float2 offsets[KERNEL_SIZE];
//-----------------------------------------------------------------------------
// Textures.
//-----------------------------------------------------------------------------
sampler colorMap : register(s0);
//-----------------------------------------------------------------------------
// Pixel Shaders.
//-----------------------------------------------------------------------------
float4 PS_GaussianBlur(float2 texCoord : TEXCOORD) : COLOR0
{
float4 color = float4(0.0f, 0.0f, 0.0f, 0.0f);
for (int i = 0; i < KERNEL_SIZE; ++i)
color += tex2D(colorMap, texCoord + offsets[i]) * weights[i];
return color;
}
//-----------------------------------------------------------------------------
// Techniques.
//-----------------------------------------------------------------------------
technique GaussianBlur
{
pass
{
PixelShader = compile ps_2_0 PS_GaussianBlur();
}
}

View file

@ -0,0 +1,47 @@
#define RADIUS 7
#define KERNEL_SIZE (RADIUS * 2 + 1)
//-----------------------------------------------------------------------------
// Globals.
//-----------------------------------------------------------------------------
float weights[KERNEL_SIZE];
float2 offsets[KERNEL_SIZE];
bool invert = false;
//-----------------------------------------------------------------------------
// Textures.
//-----------------------------------------------------------------------------
sampler colorMap : register(s0);
sampler mask : register(s1);
//-----------------------------------------------------------------------------
// Pixel Shaders.
//-----------------------------------------------------------------------------
float4 PS_GaussianBlur(float2 texCoord : TEXCOORD) : COLOR0
{
float4 maskColor = tex2D(mask, texCoord);
if (invert == true)
maskColor.a = 1 - maskColor.a;
float4 color = float4(0.0f, 0.0f, 0.0f, 0.0f);
for (int i = 0; i < KERNEL_SIZE; ++i)
color += tex2D(colorMap, texCoord + (offsets[i] * maskColor.a)) * weights[i];
return color;
}
//-----------------------------------------------------------------------------
// Techniques.
//-----------------------------------------------------------------------------
technique GaussianBlur
{
pass
{
PixelShader = compile ps_2_0 PS_GaussianBlur();
}
}

View file

@ -0,0 +1,56 @@
// The default numbers represent no change in HSV
float Hue = 0; // 0 to 360. 360 == 0 as hue loops back around.
float Brightness = 0; // -1 to 1
float Contrast = 0; // -1 to 1
float Saturation = 1; // 1 is normal saturation. 0 is no saturation (no colour). < 0 is inverse saturation.
bool UseMask = false;
sampler Samp : register(S0);
sampler Mask : register(s1);
float3x3 QuaternionToMatrix(float4 quat)
{
float3 cross = quat.yzx * quat.zxy;
float3 square= quat.xyz * quat.xyz;
float3 wimag = quat.w * quat.xyz;
square = square.xyz + square.yzx;
float3 diag = 0.5 - square;
float3 a = (cross + wimag);
float3 b = (cross - wimag);
return float3x3(
2.0 * float3(diag.x, b.z, a.y),
2.0 * float3(a.z, diag.y, b.x),
2.0 * float3(b.y, a.x, diag.z));
}
const float3 lumCoeff = float3(0.2125, 0.7154, 0.0721);
float4 mainPS(float2 uv : TEXCOORD) : COLOR
{
float4 outputColor = tex2D(Samp, uv);
float4 maskColor = tex2D(Mask, uv);
if (UseMask == false || maskColor.a >= 1)
{
float3 hsv;
float3 intensity;
float3 root3 = float3(0.57735, 0.57735, 0.57735);
float half_angle = 0.5 * radians(Hue); // Hue is radians of 0 to 360 degree
float4 rot_quat = float4( (root3 * sin(half_angle)), cos(half_angle));
float3x3 rot_Matrix = QuaternionToMatrix(rot_quat);
outputColor.rgb = mul(rot_Matrix, outputColor.rgb);
outputColor.rgb = (outputColor.rgb - 0.5) *(Contrast + 1.0) + 0.5;
outputColor.rgb = outputColor.rgb + Brightness;
intensity = float(dot(outputColor.rgb, lumCoeff));
outputColor.rgb = lerp(intensity, outputColor.rgb, Saturation );
}
return outputColor;
}
technique TransformTexture {
pass p0 {
PixelShader = compile ps_2_0 mainPS();
}
}

View file

@ -0,0 +1,21 @@
sampler TextureSampler : register(s0);
sampler mask : register(s1);
float4 InvertShader(float2 Tex:TEXCOORD0) : COLOR0
{
float4 texColor = tex2D(TextureSampler, Tex);
float4 maskColor = tex2D(mask, Tex);
if (maskColor.a >= 1)
texColor = 1.0f - texColor;
return texColor;
}
technique Technique1
{
pass Pass1
{
PixelShader = compile ps_2_0 InvertShader();
}
}

View file

@ -0,0 +1,59 @@
#include "PPVertexShader.fxh"
#define NUM_SAMPLES 25
float2 lightScreenPosition;
float4x4 matVP;
float2 halfPixel;
float Density = .5f;
float Decay = .95f;
float Weight = 1.0f;
float Exposure = .15f;
sampler2D Scene: register(s0){
AddressU = Clamp;
AddressV = Clamp;
};
float4 lightRayPS( float2 texCoord : TEXCOORD0 ) : COLOR0
{
// Find light pixel position
float2 TexCoord = texCoord - halfPixel;
float2 DeltaTexCoord = (TexCoord - lightScreenPosition);
DeltaTexCoord *= (1.0f / 128 * Density);
//DeltaTexCoord *= (1.0f/ NUM_SAMPLES * Density);
DeltaTexCoord = DeltaTexCoord ;
float3 col = tex2D(Scene,TexCoord);
float IlluminationDecay = 1.0;
float3 Sample;
for( int i = 0; i < NUM_SAMPLES; ++i )
{
TexCoord -= DeltaTexCoord;
Sample = tex2D(Scene, TexCoord);
Sample *= IlluminationDecay * Weight;
col += Sample;
IlluminationDecay *= Decay;
}
return float4(col * Exposure,1);
}
technique LightRayFX
{
pass p0
{
//VertexShader = compile vs_2_0 VertexShaderFunction();
PixelShader = compile ps_2_0 lightRayPS();
}
}

View file

@ -0,0 +1,55 @@
#include "PPVertexShader.fxh"
float2 lightScreenPosition;
float2 screenRes = float2(4,3);
float4x4 matVP;
float2 halfPixel;
float SunSize = 1500;
sampler2D Scene: register(s0){
AddressU = Clamp;
AddressV = Clamp;
};
texture flare;
sampler Flare = sampler_state
{
Texture = (flare);
AddressU = CLAMP;
AddressV = CLAMP;
};
float4 LightSourceMaskPS(float2 texCoord : TEXCOORD0 ) : COLOR0
{
texCoord -= halfPixel;
// Get the scene
float4 col = 0;
// Find the suns position in the world and map it to the screen space.
float2 coord;
float size = SunSize / 1;
float2 center = lightScreenPosition;
coord = .5 - ((texCoord - center) * screenRes) / size * .5f;
col += (pow(tex2D(Flare,coord),2) * 1) * 2;
return col * tex2D(Scene,texCoord);
}
technique LightSourceMask
{
pass p0
{
VertexShader = compile vs_2_0 VertexShaderFunction();
PixelShader = compile ps_2_0 LightSourceMaskPS();
}
}

View file

@ -0,0 +1,51 @@
//sampler TextureSampler : register(s0);
const float4 MaskRect;
float4x4 MatrixTransform;
float2 ViewportDimensions;
struct VS_INPUT
{
float4 Position : POSITION0;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float4 VPos : TEXCOORD0;
float4 color : COLOR0;
};
float4 ConvertToVPos( float4 screenPosition )
{
float2 screenPos = screenPosition.xy / screenPosition.w;
return float4((screenPos.x + 1) * ViewportDimensions.x * 0.5f, ((screenPos.y * -1) + 1) * ViewportDimensions.y * 0.5f, screenPosition.z, screenPosition.w);
}
VS_OUTPUT vs_main(VS_INPUT Input, float4 color: COLOR)
{
VS_OUTPUT Output;
Output.color = color;
Output.Position = mul( Input.Position, MatrixTransform );
Output.VPos = ConvertToVPos(Output.Position);
return( Output );
}
float4 main(VS_OUTPUT output) : COLOR0
{
if (output.VPos.x > MaskRect.x && output.VPos.x < (MaskRect.x + MaskRect.z) &&
output.VPos.y > MaskRect.y && output.VPos.y < (MaskRect.y + MaskRect.w))
return output.color;
else
return 0;
}
technique Mask
{
pass Pass1
{
VertexShader = compile vs_2_0 vs_main();
PixelShader = compile ps_2_0 main();
}
}

View file

@ -0,0 +1,44 @@
// Effect applies normalmapped lighting to a 2D sprite.
float4 LightIntensity = 1;
float4 AmbientColor = 0;
int NumberOfLights;
float3 LightPosition[5]; // Max number of lights.
sampler TextureSampler : register(s0);
sampler NormalSampler : register(s1);
float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
//texCoord coordinates are returned between values 0 to 1.
float4 tex = tex2D(TextureSampler, texCoord);
if (NumberOfLights > 0)
{
float3 normal = tex2D(NormalSampler, texCoord);
float3 pixelPosition = float3(1320 * texCoord.x, 720 * texCoord.y, 0);
float lightAmount = 0;
for (int i = 0; i < NumberOfLights; i++)
{
float internalAmount = max(dot(normal, normalize(LightPosition[i] - pixelPosition)), 0);
if (internalAmount > lightAmount)
lightAmount = internalAmount;
}
if ((lightAmount < 1 && lightAmount > 0.5))
color = (color * (1 - AmbientColor.a)) + ((AmbientColor + (lightAmount * LightIntensity)) * AmbientColor.a);
}
return tex * color;
}
technique Normalmap
{
pass Pass1
{
PixelShader = compile ps_2_0 main();
}
}

View file

@ -0,0 +1,198 @@
/* ********************************************************
* A Simple toon shader based on the work of Petri T. Wilhelmsen
* found on his blog post XNA Shader Programming Tutorial 7, Toon shading
* http://digitalerr0r.wordpress.com/2009/03/22/xna-shader-programming-tutorial-7-toon-shading/.
* Which in turn is based on the shader "post edgeDetect" from nVidias Shader library
* http://developer.download.nvidia.com/shaderlibrary/webpages/shader_library.html
*
* This process will use a Sobell convolution filter to determine contrast across each pixel.
* pixels that have a contrast greater than a given threshold value will be treated
* as an edge pixel and turned black.
*
* Author: John Marquiss
* Email: txg1152@gmail.com
*
* This work by John Marquiss is licensed under a
* Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
* http://creativecommons.org/licenses/by-nc-sa/3.0/
*/
sampler ColorMapSampler : register(s0);
/* Screen size (really texture size) is used to
* scale the outline line thickness nicely around the
* image
*/
float2 ScreenSize = float2(1320.0f, 720.0f);
/* Outline line thickness scale
*/
float Thickness = 1.5f;
/* Edge detection threshold
* Contrast values over the threshold are considered
* edges. That means smaller values for the threshold make the
* image more "edgy" higher values less so.
*/
float Threshold = 0.2f;
/* getGray
* a simple helper function to return a grey scale
* value for a given pixel
*/
float getGray(float4 c)
{
/* The closer a color is to a pure gray
* value the closer its dot product and gray
* will be to 0.
*/
return(dot(c.rgb,((0.33333).xxx)));
}
struct VertexShaderOutput
{
float2 Tex : TEXCOORD0;
};
/* Shade each pixel turning edge pixels black
*/
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
// Get the source pixel color
float4 Color = tex2D(ColorMapSampler, input.Tex);
/* ox is the X offset vector where the offest is based
* on the scaled edge thickness
*/
float2 ox = float2(Thickness/ScreenSize.x,0.0);
/* oy is the Y offset vector where the offest is based
* on the scaled edge thickness
*/
float2 oy = float2(0.0,Thickness/ScreenSize.y);
/* our current xy (uv) texture coordinate
*/
float2 uv = input.Tex.xy;
/* Our kernel filter is a 3x3 matrix in order to process
* it we need to get the 8 neighbor pixles (top left, top, top right,
* left, right, bottom left, bottom, and bottom right) and the
* current pixel. For each of these pixels we then need to get
* its grey scale value using getGray. We will store the gray scale
* values in a 3x3 matrix g:
* g00 g01 g02
* g10 g11 g12
* g20 g21 g22
*/
/* First the bottom row pixels
* bottom left uv - oy - ox, bottom uv - oy and
* bottom right uv - oy + ox
*/
float2 PP = uv - oy;
float4 CC = tex2D(ColorMapSampler, PP-ox); float g00 = getGray(CC);
CC = tex2D(ColorMapSampler, PP); float g01 = getGray(CC);
CC = tex2D(ColorMapSampler, PP+ox); float g02 = getGray(CC);
/* Next get the middle row pixels
* left uv - ox, current uv and right uv + ox
*/
PP = uv;
CC = tex2D(ColorMapSampler, PP-ox); float g10 = getGray(CC);
CC = tex2D(ColorMapSampler, PP); float g11 = getGray(CC);
CC = tex2D(ColorMapSampler, PP+ox); float g12 = getGray(CC);
/* Finally get the top row pixels
* top left uv + oy - ox, top uv + oy and
* top right uv + oy + ox
*/
PP = uv + oy;
CC = tex2D(ColorMapSampler, PP-ox); float g20 = getGray(CC);
CC = tex2D(ColorMapSampler, PP); float g21 = getGray(CC);
CC = tex2D(ColorMapSampler, PP+ox); float g22 = getGray(CC);
/* We will use a Sobell convolution filter
* -1 -2 -1
* 0 0 0
* 1 2 1
*/
float K00 = -1;
float K01 = -2;
float K02 = -1;
float K10 = 0;
float K11 = 0;
float K12 = 0;
float K20 = 1;
float K21 = 2;
float K22 = 1;
/* Calculate sx as the summation
* of g.ij * K.ij
* This will give us horizantal edge detection
*/
float sx = 0;
sx += g00 * K00;
sx += g01 * K01;
sx += g02 * K02;
sx += g10 * K10;
sx += g11 * K11;
sx += g12 * K12;
sx += g20 * K20;
sx += g21 * K21;
sx += g22 * K22;
/* Calculate sy as the summation
* of g.ij * K.ji
* K.ji effectively rotates the kernel filter
* this will give us vertical edge detection
*/
float sy = 0;
sy += g00 * K00;
sy += g01 * K10;
sy += g02 * K20;
sy += g10 * K01;
sy += g11 * K11;
sy += g12 * K21;
sy += g20 * K02;
sy += g21 * K12;
sy += g22 * K22;
/* Now merge the results of the horizantal
* and veritcal edge detection calculations
* together by calculating the distance of the
* vector they form.
*/
float contrast = sqrt(sx*sx + sy*sy);
/* assume no edge (result = 1)
*/
float result = 1;
/* If the length of s.xy has a value
* greater than the threshold then the color change (contrast)
* accoss that pixel is enough that we want to consider
* it an edge. Set result to 0 to black out that pixel.
*/
if (contrast > Threshold)
{
result = 0;
}
/* finally return the original color multiplied
* by the result. For with contrast values over the
* threshold result will be 0 giving us a black edge.
* Make sure we do not clear out the alpha value though
* otherwise our edges will disappear if we use alpha
* blending.
*/
return Color*float4(result.xxx,1);
}
technique PostOutline
{
pass Pass0
{
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}

View file

@ -0,0 +1,20 @@
struct VertexShaderOutput
{
float4 Position : POSITION0;
float2 TexCoord : TexCoord0;
};
struct VertexShaderInput
{
float4 Position : POSITION0;
float2 TexCoord : TexCoord0;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output = (VertexShaderOutput)0;
output.Position = float4(input.Position.xyz,1);
output.TexCoord = input.TexCoord;
return output;
}

View file

@ -0,0 +1,29 @@
float4x4 World;
float4x4 View;
float4x4 Projection;
// TODO: add effect parameters here.
sampler RenderSampler : register(s0);
sampler ParallaxBGSampler : register(s1);
float discrepancy = 0.9f;
float4 ApplyParallax(float2 texCoord : TEXCOORD0, float4 color : COLOR0) : COLOR0
{
float4 parallaxColour = tex2D(ParallaxBGSampler, texCoord);
float4 renderColour = tex2D(RenderSampler, texCoord);
if (renderColour.r > discrepancy && renderColour.g < 1 - discrepancy && renderColour.b > discrepancy)
return parallaxColour;
else
return renderColour;
}
technique Technique1
{
pass Pass1
{
PixelShader = compile ps_2_0 ApplyParallax();
}
}

View file

@ -0,0 +1,13 @@
Believe it or not, Rogue Legacy uses a shader system that is very very old!
Like all XNA games, RL1 uses the Effects Framework, a forgotten DXSDK format.
XNA had a way to compile these via the Content Project, but you can get the same
binaries by using FXC, the old shader compiler from the DirectX SDK (June 2010).
Whether on Windows or not, install the June 2010 DirectX SDK and `buildEffects`
should do what it needs to do. It's not _exactly_ the same since XNA expects a
specific compression on top of the FX output, but FNA is more flexible, so to
accommodate community changes the SDL3 update for RL1 now uses the "fxb" format
directly, to avoid weird content overrides and collisions.
Enjoy!

View file

@ -0,0 +1,38 @@
sampler ScreenS : register(s0);
float wave; // pi/.75 is a good default
float distortion; // 1 is a good default
float2 centerCoord; // 0.5,0.5 is the screen center
float4 RippleEffect(float2 texCoord: TEXCOORD0) : COLOR
{
float2 distance = abs(texCoord - centerCoord);
float scalar = length(distance);
// invert the scale so 1 is centerpoint
scalar = abs(1 - scalar);
// calculate how far to distort for this pixel
float sinoffset = sin(wave / scalar);
sinoffset = clamp(sinoffset, 0, 1);
// calculate which direction to distort
float sinsign = cos(wave / scalar);
// reduce the distortion effect
sinoffset = sinoffset * distortion/32;
// pick a pixel on the screen for this pixel, based on
// the calculated offset and direction
float4 color = tex2D(ScreenS, texCoord+(sinoffset*sinsign));
return color;
}
technique
{
pass P0
{
PixelShader = compile ps_2_0 RippleEffect();
}
}

View file

@ -0,0 +1,38 @@
float2 halfPixel;
sampler2D Scene: register(s0){
AddressU = Mirror;
AddressV = Mirror;
};
texture OrgScene;
sampler2D orgScene = sampler_state
{
Texture = <OrgScene>;
AddressU = CLAMP;
AddressV = CLAMP;
};
float4 BlendPS(float2 texCoord : TEXCOORD0 ) : COLOR0
{
texCoord -= halfPixel;
float4 col = tex2D(orgScene,texCoord) * tex2D(Scene,texCoord);
return col;
}
float4 AditivePS(float2 texCoord : TEXCOORD0 ) : COLOR0
{
texCoord -= halfPixel;
float4 col = tex2D(orgScene,texCoord) + tex2D(Scene,texCoord);
return col;
}
technique Blend
{
pass p0
{
PixelShader = compile ps_2_0 BlendPS();
}
}
technique Aditive
{
pass p0
{
PixelShader = compile ps_2_0 AditivePS();
}
}

View file

@ -0,0 +1,23 @@
// TODO: add effect parameters here.
sampler TextureSampler : register(s0);
sampler ShadowSampler : register(s1);
float ShadowIntensity = 0;
float4 ApplyShadow(float2 texCoord : TEXCOORD0, float4 color : COLOR0) : COLOR0
{
float4 bgColour = tex2D(TextureSampler, texCoord);
float4 shadowColour = tex2D(ShadowSampler, texCoord);
bgColour.a = ShadowIntensity - shadowColour.a; // Change the first value to set shadow amount. Setting to 0 means no shadow.
return bgColour;
}
technique Technique1
{
pass Pass1
{
PixelShader = compile ps_2_0 ApplyShadow();
}
}

View file

@ -0,0 +1,49 @@
// shockwave.fx
sampler samplerState;
float xcenter = 0.5;
float ycenter = 0.5;
float mag = 0;
float width = 0;
float4 Shockwave(float2 texCoord: TEXCOORD) : COLOR0
{
float4 col = 0.0;
float2 tex = texCoord;
float xdif = tex.x - xcenter;
float ydif = tex.y - ycenter;
float d = sqrt(xdif * xdif + ydif * ydif) - width;
float t = abs(d);
if (d < 0.1 && d > -0.2)
{
if (d < 0.0)
{
t = (0.2 - t) / 2.0;
tex.x = tex.x - (xdif * t * mag);
tex.y = tex.y - (ydif * t * mag);
col = tex2D(samplerState, tex);
}
else
{
t = (0.1 - t);
tex.x = tex.x - (xdif * t * mag);
tex.y = tex.y - (ydif * t * mag);
col = tex2D(samplerState, tex);
}
// col.a = t * 12.0;
}
col = tex2D(samplerState, tex);
return col;
}
technique Technique1 {
pass P0{
PixelShader = compile ps_2_0 Shockwave();
}
}

View file

@ -0,0 +1,34 @@
sampler ScreenS : register(s0);
float2 center = (0.5,0.5);
float time;
float2 centerCoord = (0.5, 0.5);
float4 PixelShaderFunction(float2 texCoord: TEXCOORD0) : COLOR
{
float2 distance = abs(texCoord - centerCoord);
float4 outputColor = tex2D(ScreenS, texCoord);
float boop = length(distance);
// boop = abs(1 - boop);
if (boop <= time + 0.025 && boop >= time - 0.025)
{
float ecart = (distance - time); // value between -0.02 & 0.02
float powEcart = 1.0-pow(abs(ecart*40.0),0.4); // value between -1 & 1 (because 0.02 * 50 = 1)
float ecartTime = ecart * powEcart; // value between -0.02 & 0.02
float2 diff = normalize(texCoord - center); // get the direction
float2 newTexCoord = texCoord + (diff * ecartTime);
float4 color = tex2D(ScreenS, newTexCoord);
return color;
}
return outputColor;
}
technique Technique1
{
pass Pass1
{
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}

View file

@ -0,0 +1,193 @@
//-----------------------------------------------------------------------------
// PostprocessEffect.fx
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
// Settings controlling the edge detection filter.
float EdgeWidth = 1;
float EdgeIntensity = 1;
// How sensitive should the edge detection be to tiny variations in the input data?
// Smaller settings will make it pick up more subtle edges, while larger values get
// rid of unwanted noise.
float NormalThreshold = 0.5;
float DepthThreshold = 0.1;
// How dark should the edges get in response to changes in the input data?
float NormalSensitivity = 1;
float DepthSensitivity = 10;
// How should the sketch effect respond to changes of brightness in the input scene?
float SketchThreshold = 0.1;
float SketchBrightness = 0.333;
// Randomly offsets the sketch overlay pattern to create a hand-drawn animation effect.
float2 SketchJitter;
// Pass in the current screen resolution.
float2 ScreenResolution;
// This texture contains the main scene image, which the edge detection
// and/or sketch filter are being applied over the top of.
texture SceneTexture;
sampler SceneSampler : register(s0) = sampler_state
{
Texture = (SceneTexture);
MinFilter = Linear;
MagFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
// This texture contains normals (in the color channels) and depth (in alpha)
// for the main scene image. Differences in the normal and depth data are used
// to detect where the edges of the model are.
texture NormalDepthTexture;
sampler NormalDepthSampler : register(s1) = sampler_state
{
Texture = (NormalDepthTexture);
MinFilter = Linear;
MagFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
// This texture contains an overlay sketch pattern, used to create the hatched
// pencil drawing effect.
texture SketchTexture;
sampler SketchSampler : register(s2) = sampler_state
{
Texture = (SketchTexture);
AddressU = Wrap;
AddressV = Wrap;
};
// Pixel shader applies the edge detection and/or sketch filter postprocessing.
// It is compiled several times using different settings for the uniform boolean
// parameters, producing different optimized versions of the shader depending on
// which combination of processing effects is desired.
float4 PixelShaderFunction(float2 texCoord : TEXCOORD0, uniform bool applyEdgeDetect,
uniform bool applySketch,
uniform bool sketchInColor) : COLOR0
{
// Look up the original color from the main scene.
float3 scene = tex2D(SceneSampler, texCoord);
// Apply the sketch effect?
if (applySketch)
{
// Adjust the scene color to remove very dark values and increase the contrast.
float3 saturatedScene = saturate((scene - SketchThreshold) * 2);
// Look up into the sketch pattern overlay texture.
float3 sketchPattern = tex2D(SketchSampler, texCoord + SketchJitter);
// Convert into negative color space, and combine the scene color with the
// sketch pattern. We need to do this multiply in negative space to get good
// looking results, because pencil sketching works by drawing black ink
// over an initially white page, rather than adding light to an initially
// black background as would be more common in computer graphics.
float3 negativeSketch = (1 - saturatedScene) * (1 - sketchPattern);
// Convert the result into a positive color space greyscale value.
float sketchResult = dot(1 - negativeSketch, SketchBrightness);
// Apply the sketch result to the main scene color.
if (sketchInColor)
scene *= sketchResult;
else
scene = sketchResult;
}
// Apply the edge detection filter?
if (applyEdgeDetect)
{
// Look up four values from the normal/depth texture, offset along the
// four diagonals from the pixel we are currently shading.
float2 edgeOffset = EdgeWidth / ScreenResolution;
float4 n1 = tex2D(NormalDepthSampler, texCoord + float2(-1, -1) * edgeOffset);
float4 n2 = tex2D(NormalDepthSampler, texCoord + float2( 1, 1) * edgeOffset);
float4 n3 = tex2D(NormalDepthSampler, texCoord + float2(-1, 1) * edgeOffset);
float4 n4 = tex2D(NormalDepthSampler, texCoord + float2( 1, -1) * edgeOffset);
// Work out how much the normal and depth values are changing.
float4 diagonalDelta = abs(n1 - n2) + abs(n3 - n4);
float normalDelta = dot(diagonalDelta.xyz, 1);
float depthDelta = diagonalDelta.w;
// Filter out very small changes, in order to produce nice clean results.
normalDelta = saturate((normalDelta - NormalThreshold) * NormalSensitivity);
depthDelta = saturate((depthDelta - DepthThreshold) * DepthSensitivity);
// Does this pixel lie on an edge?
float edgeAmount = saturate(normalDelta + depthDelta) * EdgeIntensity;
// Apply the edge detection result to the main scene color.
scene *= (1 - edgeAmount);
}
return float4(scene, 1);
}
// Compile the pixel shader for doing edge detection without any sketch effect.
technique EdgeDetect
{
pass P0
{
PixelShader = compile ps_2_0 PixelShaderFunction(true, false, false);
}
}
// Compile the pixel shader for doing edge detection with a monochrome sketch effect.
technique EdgeDetectMonoSketch
{
pass P0
{
PixelShader = compile ps_2_0 PixelShaderFunction(true, true, false);
}
}
// Compile the pixel shader for doing edge detection with a colored sketch effect.
technique EdgeDetectColorSketch
{
pass P0
{
PixelShader = compile ps_2_0 PixelShaderFunction(true, true, true);
}
}
// Compile the pixel shader for doing a monochrome sketch effect without edge detection.
technique MonoSketch
{
pass P0
{
PixelShader = compile ps_2_0 PixelShaderFunction(false, true, false);
}
}
// Compile the pixel shader for doing a colored sketch effect without edge detection.
technique ColorSketch
{
pass P0
{
PixelShader = compile ps_2_0 PixelShaderFunction(false, true, true);
}
}

View file

@ -0,0 +1,29 @@
sampler TextureSampler : register(s0);
// TODO: add effect parameters here.
float4 desiredTint;
float4 nonTintedColour;
float4 nonTintedColour2;
const float colourBuffer = 0.2f;
float4 PixelShaderFunction(float2 texCoord : TEXCOORD0) : COLOR0
{
// TODO: add your pixel shader code here.
float4 color = tex2D(TextureSampler, texCoord);
if ( ( (color.r >= nonTintedColour.r - colourBuffer && color.r <= nonTintedColour.r + colourBuffer) && (color.g >= nonTintedColour.g - colourBuffer && color.g <= nonTintedColour.g + colourBuffer) && (color.b >= nonTintedColour.b - colourBuffer && color.b <= nonTintedColour.b + colourBuffer) )
||
( (color.r >= nonTintedColour2.r - colourBuffer && color.r <= nonTintedColour2.r + colourBuffer) && (color.g >= nonTintedColour2.g - colourBuffer && color.g <= nonTintedColour2.g + colourBuffer) && (color.b >= nonTintedColour2.b - colourBuffer && color.b <= nonTintedColour2.b + colourBuffer) ))
return color;
else
return color * desiredTint;
}
technique Technique1
{
pass Pass1
{
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}

View file

@ -0,0 +1,3 @@
for %%I in (*.fx) do (
fxc /T fx_2_0 %%I /Fo %%~nI.fxb
)

View file

@ -0,0 +1,11 @@
#!/bin/bash
set -e
cd "`dirname "$0"`"
FILES=`ls | grep '\.fx$'`
for f in $FILES
do
WINEDEBUG=fixme-all,err-all wine fxc.exe /T fx_2_0 $f /Fo "`basename $f .fx`.fxb"
done

View file

@ -0,0 +1,67 @@
texture SourceTexture;
sampler inputSampler = sampler_state
{
Texture = <SourceTexture>;
MipFilter = Point;
MinFilter = Point;
MagFilter = Point;
AddressU = Clamp;
AddressV = Clamp;
};
float2 TextureDimensions;
struct VS_OUTPUT
{
float4 Pos : POSITION;
float2 Tex : TEXCOORD0;
};
VS_OUTPUT VS(
float3 InPos : POSITION,
float2 InTex : TEXCOORD0)
{
VS_OUTPUT Out = (VS_OUTPUT)0;
// transform the position to the screen
Out.Pos = float4(InPos,1) + float4(-TextureDimensions.x, TextureDimensions.y, 0, 0);
Out.Tex = InTex;
return Out;
}
float4 HorizontalReductionPS(float2 TexCoord : TEXCOORD0) : COLOR0
{
float2 color = tex2D(inputSampler, TexCoord);
float2 colorR = tex2D(inputSampler, TexCoord + float2(TextureDimensions.x,0));
float2 result = min(color,colorR);
return float4(result,0,1);
}
float4 CopyPS(float2 TexCoord : TEXCOORD0) : COLOR0
{
return tex2D(inputSampler, TexCoord);
}
technique HorizontalReduction
{
pass P0
{
VertexShader = compile vs_2_0 VS();
PixelShader = compile ps_2_0 HorizontalReductionPS();
}
}
technique Copy
{
pass P0
{
VertexShader = compile vs_2_0 VS();
PixelShader = compile ps_2_0 CopyPS();
}
}

View file

@ -0,0 +1,234 @@
texture InputTexture;
sampler inputSampler = sampler_state
{
Texture = <InputTexture>;
MipFilter = Point;
MinFilter = Point;
MagFilter = Point;
AddressU = Clamp;
AddressV = Clamp;
};
texture ShadowMapTexture;
sampler shadowMapSampler = sampler_state
{
Texture = <ShadowMapTexture>;
MipFilter = Point;
MinFilter = Point;
MagFilter = Point;
AddressU = Clamp;
AddressV = Clamp;
};
float2 renderTargetSize;
struct VS_OUTPUT
{
float4 Position : POSITION;
float2 TexCoords : TEXCOORD0;
};
VS_OUTPUT FullScreenVS( float3 InPos : POSITION,
float2 InTex : TEXCOORD0)
{
VS_OUTPUT Out = (VS_OUTPUT)0;
// Offset the position by half a pixel to correctly align texels to pixels
Out.Position = float4(InPos,1) + 0.5f* float4(-1.0f/renderTargetSize.x, 1.0f/renderTargetSize.y, 0, 0);
Out.TexCoords = InTex;
return Out;
}
float4 ComputeDistancesPS(float2 TexCoord : TEXCOORD0) : COLOR0
{
float4 color = tex2D(inputSampler, TexCoord);
//compute distance from center
float distance = color.a>0.3f?length(TexCoord - 0.5f):1.0f;
//save it to the Red channel
return float4(distance,0,0,1);
}
float4 DistortPS(float2 TexCoord : TEXCOORD0) : COLOR0
{
//translate u and v into [-1 , 1] domain
float u0 = TexCoord.x * 2 - 1;
float v0 = TexCoord.y * 2 - 1;
//then, as u0 approaches 0 (the center), v should also approach 0
v0 = v0 * abs(u0);
//convert back from [-1,1] domain to [0,1] domain
v0 = (v0 + 1) / 2;
//we now have the coordinates for reading from the initial image
float2 newCoords = float2(TexCoord.x, v0);
//read for both horizontal and vertical direction and store them in separate channels
float horizontal = tex2D(inputSampler, newCoords).r;
float vertical = tex2D(inputSampler, newCoords.yx).r;
return float4(horizontal,vertical ,0,1);
}
float GetShadowDistanceH(float2 TexCoord, float displacementV)
{
float u = TexCoord.x;
float v = TexCoord.y;
u = abs(u-0.5f) * 2;
v = v * 2 - 1;
float v0 = v/u;
v0+=displacementV;
v0 = (v0 + 1) / 2;
float2 newCoords = float2(TexCoord.x,v0);
//horizontal info was stored in the Red component
return tex2D(shadowMapSampler, newCoords).r;
}
float GetShadowDistanceV(float2 TexCoord, float displacementV)
{
float u = TexCoord.y;
float v = TexCoord.x;
u = abs(u-0.5f) * 2;
v = v * 2 - 1;
float v0 = v/u;
v0+=displacementV;
v0 = (v0 + 1) / 2;
float2 newCoords = float2(TexCoord.y,v0);
//vertical info was stored in the Green component
return tex2D(shadowMapSampler, newCoords).g;
}
float4 DrawShadowsPS(float2 TexCoord : TEXCOORD0) : COLOR0
{
// distance of this pixel from the center
float distance = length(TexCoord - 0.5f);
//distance stored in the shadow map
float shadowMapDistance;
//coords in [-1,1]
float nY = 2.0f*( TexCoord.y - 0.5f);
float nX = 2.0f*( TexCoord.x - 0.5f);
//we use these to determine which quadrant we are in
if(abs(nY)<abs(nX))
{
shadowMapDistance = GetShadowDistanceH(TexCoord,0);
}
else
{
shadowMapDistance = GetShadowDistanceV(TexCoord,0);
}
//if distance to this pixel is lower than distance from shadowMap,
//then we are not in shadow
float light = distance < shadowMapDistance ? 1:0;
float4 result = light;
result.b = length(TexCoord - 0.5f);
result.a = 1;
return result;
}
static const float minBlur = 0.0f;
static const float maxBlur = 15.0f; // 5.0f;
static const int g_cKernelSize = 13;
static const float2 OffsetAndWeight[g_cKernelSize] =
{
{ -6, 0.002216 },
{ -5, 0.008764 },
{ -4, 0.026995 },
{ -3, 0.064759 },
{ -2, 0.120985 },
{ -1, 0.176033 },
{ 0, 0.199471 },
{ 1, 0.176033 },
{ 2, 0.120985 },
{ 3, 0.064759 },
{ 4, 0.026995 },
{ 5, 0.008764 },
{ 6, 0.002216 },
};
float4 BlurHorizontallyPS(float2 TexCoord : TEXCOORD0) : COLOR0
{
float sum=0;
float distance = tex2D( inputSampler, TexCoord).b;
for (int i = 0; i < g_cKernelSize; i++)
{
sum += tex2D( inputSampler, TexCoord + OffsetAndWeight[i].x * lerp(minBlur, maxBlur , distance)/renderTargetSize.x * float2(1,0) ).r * OffsetAndWeight[i].y;
}
float4 result = sum;
result.b = distance;
result.a = 1;
return result;
}
float4 BlurVerticallyPS(float2 TexCoord : TEXCOORD0) : COLOR0
{
float sum=0;
float distance = tex2D( inputSampler, TexCoord).b;
for (int i = 0; i < g_cKernelSize; i++)
{
sum += tex2D( inputSampler, TexCoord + OffsetAndWeight[i].x * lerp(minBlur, maxBlur , distance)/renderTargetSize.x * float2(0,1) ).r * OffsetAndWeight[i].y;
}
float d = 2 * length(TexCoord - 0.5f);
float attenuation = pow( saturate(1.0f - d),1.0f);
float4 result = sum * attenuation;
result.a = 1;
return result;
}
technique ComputeDistances
{
pass P0
{
VertexShader = compile vs_2_0 FullScreenVS();
PixelShader = compile ps_2_0 ComputeDistancesPS();
}
}
technique Distort
{
pass P0
{
VertexShader = compile vs_2_0 FullScreenVS();
PixelShader = compile ps_2_0 DistortPS();
}
}
technique DrawShadows
{
pass P0
{
VertexShader = compile vs_2_0 FullScreenVS();
PixelShader = compile ps_2_0 DrawShadowsPS();
}
}
technique BlurHorizontally
{
pass P0
{
VertexShader = compile vs_2_0 FullScreenVS();
PixelShader = compile ps_2_0 BlurHorizontallyPS();
}
}
technique BlurVerticallyAndAttenuate
{
pass P0
{
VertexShader = compile vs_2_0 FullScreenVS();
PixelShader = compile ps_2_0 BlurVerticallyPS();
}
}