244 lines
5.9 KiB
HLSL
244 lines
5.9 KiB
HLSL
//------------------------------------------- Defines -------------------------------------------
|
|
|
|
#define Pi 3.14159265
|
|
|
|
//------------------------------------- Top Level Variables -------------------------------------
|
|
|
|
// Top level variables can and have to be set at runtime
|
|
float4 AmbientColor;
|
|
float AmbientIntensity;
|
|
float4 DiffuseColor;
|
|
texture ScreenTexture;
|
|
texture2D SpotlightTexture;
|
|
|
|
float WorldRotation;
|
|
|
|
int TextureWidth;
|
|
|
|
// Matrices for 3D perspective projection
|
|
float4x4 View, Projection, World, WorldIT;
|
|
|
|
//---------------------------------- Input / Output structures ----------------------------------
|
|
|
|
// Each member of the struct has to be given a "semantic", to indicate what kind of data should go in
|
|
// here and how it should be treated. Read more about the POSITION0 and the many other semantics in
|
|
// the MSDN library
|
|
struct VertexShaderInput
|
|
{
|
|
float4 Position3D : POSITION0;
|
|
float4 Normals3D : NORMAL0;
|
|
};
|
|
|
|
// The output of the vertex shader. After being passed through the interpolator/rasterizer it is also
|
|
// the input of the pixel shader.
|
|
// Note 1: The values that you pass into this struct in the vertex shader are not the same as what
|
|
// you get as input for the pixel shader. A vertex shader has a single vertex as input, the pixel
|
|
// shader has 3 vertices as input, and lets you determine the color of each pixel in the triangle
|
|
// defined by these three vertices. Therefor, all the values in the struct that you get as input for
|
|
// the pixel shaders have been linearly interpolated between there three vertices!
|
|
// Note 2: You cannot use the data with the POSITION0 semantic in the pixel shader.
|
|
struct VertexShaderOutput
|
|
{
|
|
float4 Position2D : POSITION0;
|
|
float4 Normals : TEXCOORD0;
|
|
float4 lightDir : TEXCOORD1;
|
|
float4 lambertLightDir : TEXCOORD2;
|
|
float4 Position : TEXCOORD3;
|
|
};
|
|
|
|
//---------------------------------------- Technique: Simple ----------------------------------------
|
|
|
|
VertexShaderOutput SimpleVertexShader(VertexShaderInput input)
|
|
{
|
|
// Allocate an empty output struct
|
|
VertexShaderOutput output = (VertexShaderOutput)0;
|
|
|
|
input.Position3D.w = 1.0f;
|
|
|
|
// Do the matrix multiplications for perspective projection and the world transform
|
|
float4 worldPosition = mul(input.Position3D, World);
|
|
float4 viewPosition = mul(worldPosition, View);
|
|
output.Position2D = mul(viewPosition, Projection);
|
|
output.Position = mul(viewPosition, Projection);
|
|
output.Normals = mul(input.Normals3D, WorldIT);
|
|
float4 lightPoint = { -3, -2, -2, 0 };
|
|
output.lightDir = normalize(worldPosition - lightPoint);
|
|
output.lambertLightDir = float4(30, 30, 20, 0);
|
|
|
|
return output;
|
|
}
|
|
|
|
float4 SimplePixelShader(VertexShaderOutput input) : COLOR0
|
|
{
|
|
|
|
float4 color = DiffuseColor * 0.2 * max(0, dot(input.Normals, input.lambertLightDir));
|
|
color += AmbientColor * AmbientIntensity;
|
|
|
|
return color;
|
|
}
|
|
|
|
float4 SpotlightPixelShader(VertexShaderOutput input) : COLOR0
|
|
{
|
|
float4 lightDirection = { 1, 1, 1, 0 };
|
|
float theta = 20.0f;
|
|
float phi = 40.0f;
|
|
float4 color;
|
|
float4 lambert = DiffuseColor * 0.2 * max(0, dot(input.Normals, input.lambertLightDir));
|
|
float angle = acos(dot(input.lightDir, normalize(lightDirection)));
|
|
|
|
if (angle > radians(phi))
|
|
color = AmbientColor * AmbientIntensity;
|
|
else if (angle < radians(theta))
|
|
color = lambert;
|
|
else
|
|
color = max(AmbientColor * AmbientIntensity, smoothstep(radians(phi), radians(theta), angle) * lambert);
|
|
|
|
return color;
|
|
}
|
|
|
|
sampler SpotlightTextureSampler :register(s2) = sampler_state
|
|
{
|
|
Texture = <SpotlightTexture>;
|
|
};
|
|
|
|
float4 TexturedSpotlightPixelShader(VertexShaderOutput input) : COLOR0
|
|
{
|
|
float4 color;
|
|
|
|
float2 TextureCoordinates;
|
|
TextureCoordinates.x = input.Position.x / input.Position.w / 2.0f + 0.5f;
|
|
TextureCoordinates.y = -input.Position.y / input.Position.w / 2.0f + 0.5f;
|
|
|
|
float4 lightDirection = { 1, 1, 1, 0 };
|
|
float theta = 20.0f;
|
|
float phi = 40.0f;
|
|
float angle = acos(dot(input.lightDir, normalize(lightDirection)));
|
|
color = AmbientColor * AmbientIntensity + DiffuseColor * 0.2 * max(0, dot(input.Normals, input.lambertLightDir));
|
|
color *= 0.6;
|
|
if (angle < radians(phi))
|
|
color += tex2D(SpotlightTextureSampler, TextureCoordinates);
|
|
|
|
return color;
|
|
}
|
|
|
|
sampler TextureSampler = sampler_state
|
|
{
|
|
Texture = <ScreenTexture>;
|
|
};
|
|
|
|
float4 GrayscalePixelShader(float2 TextureCoordinate : TEXCOORD0) : COLOR0
|
|
{
|
|
// Get the color.
|
|
float4 color = tex2D(TextureSampler, TextureCoordinate);
|
|
|
|
// Turn pixel to grayscale.
|
|
float grayscale = dot(color.rgb, float3(0.3, 0.59, 0.11));
|
|
color.r = grayscale;
|
|
color.g = grayscale;
|
|
color.b = grayscale;
|
|
color.a = 1.0f;
|
|
|
|
// Return the result.
|
|
return color;
|
|
}
|
|
|
|
float Pixels[13] =
|
|
{
|
|
-6,
|
|
-5,
|
|
-4,
|
|
-3,
|
|
-2,
|
|
-1,
|
|
0,
|
|
1,
|
|
2,
|
|
3,
|
|
4,
|
|
5,
|
|
6,
|
|
};
|
|
|
|
float BlurWeights[13] =
|
|
{
|
|
0.002216,
|
|
0.008764,
|
|
0.026995,
|
|
0.064759,
|
|
0.120985,
|
|
0.176033,
|
|
0.199471,
|
|
0.176033,
|
|
0.120985,
|
|
0.064759,
|
|
0.026995,
|
|
0.008764,
|
|
0.002216,
|
|
};
|
|
|
|
|
|
float4 GaussianPixelShader(float2 TextureCoordinate : TEXCOORD0) : COLOR
|
|
{
|
|
// Pixel width
|
|
float pixelWidth = 1.0 / (float)TextureWidth;
|
|
|
|
float4 color = { 0, 0, 0, 1 };
|
|
|
|
float2 blur;
|
|
blur.y = TextureCoordinate.y;
|
|
|
|
for (int i = 0; i < 13; i++)
|
|
{
|
|
blur.x = TextureCoordinate.x + Pixels[i] * (pixelWidth * 2);
|
|
blur.y = TextureCoordinate.y + Pixels[i] * (pixelWidth * 2);
|
|
color += tex2D(TextureSampler, blur.xy) * BlurWeights[i];
|
|
}
|
|
|
|
return color;
|
|
}
|
|
|
|
|
|
technique Simple
|
|
{
|
|
|
|
pass Pass0
|
|
{
|
|
VertexShader = compile vs_2_0 SimpleVertexShader();
|
|
PixelShader = compile ps_2_0 SimplePixelShader();
|
|
}
|
|
}
|
|
|
|
technique Spotlight
|
|
{
|
|
pass Pass0
|
|
{
|
|
VertexShader = compile vs_2_0 SimpleVertexShader();
|
|
PixelShader = compile ps_2_0 SpotlightPixelShader();
|
|
}
|
|
}
|
|
|
|
technique Greyscale
|
|
{
|
|
pass Pass0
|
|
{
|
|
PixelShader = compile ps_2_0 GrayscalePixelShader();
|
|
}
|
|
}
|
|
|
|
technique GaussianBlur
|
|
{
|
|
pass Pass0
|
|
{
|
|
PixelShader = compile ps_2_0 GaussianPixelShader();
|
|
}
|
|
}
|
|
|
|
technique TexturedLight
|
|
{
|
|
pass Pass0
|
|
{
|
|
VertexShader = compile vs_2_0 SimpleVertexShader();
|
|
PixelShader = compile ps_2_0 TexturedSpotlightPixelShader();
|
|
}
|
|
}
|