Code:
//===================================================================================
// Sharpen Mod
//
// Made By: Drigien
// Date: Oct 2011
//===================================================================================
float SceneIntensity = 0.95f;
float GlowIntensity = 0.5f;
float HighlightThreshold = 0.8f;
float HighlightIntensity = 0.0f;
float2 vViewportSize;
float downsampleScale = 0.25;
float BlurWidth = 0.125f;
texture SceneMap;
sampler SceneSampler = sampler_state
{
texture = <SceneMap>;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
MIPFILTER = NONE;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};
texture DownsampleMap;
sampler DownsampleSampler = sampler_state
{
texture = <DownsampleMap>;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
MIPFILTER = NONE;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};
texture HBlurMap;
sampler HBlurSampler = sampler_state
{
texture = <HBlurMap>;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
MIPFILTER = NONE;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};
texture FinalBlurMap;
sampler FinalBlurSampler = sampler_state
{
texture = <FinalBlurMap>;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
MIPFILTER = NONE;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};
///////////////////////////////////////////////////////////
/////////////////////////////////// data structures ///////
///////////////////////////////////////////////////////////
struct VS_OUTPUT_BLUR
{
float4 Position : POSITION;
float2 TexCoord[8]: TEXCOORD0;
};
struct VS_OUTPUT
{
float4 Position : POSITION;
float2 TexCoord0 : TEXCOORD0;
float2 TexCoord1 : TEXCOORD1;
float2 TexCoord2 : TEXCOORD2;
};
struct VS_OUTPUT_DOWNSAMPLE
{
float4 Position : POSITION;
float2 TexCoord[4]: TEXCOORD0;
};
////////////////////////////////////////////////////////////
////////////////////////////////// vertex shaders //////////
////////////////////////////////////////////////////////////
VS_OUTPUT_DOWNSAMPLE VS_Downsample(float4 Position : POSITION,
float2 TexCoord : TEXCOORD0)
{
VS_OUTPUT_DOWNSAMPLE OUT;
float2 texelSize = downsampleScale / vViewportSize;
float2 s = TexCoord;
OUT.Position = Position;
OUT.TexCoord[0] = s;
OUT.TexCoord[1] = s + float2(2, 0)*texelSize;
OUT.TexCoord[2] = s + float2(2, 2)*texelSize;
OUT.TexCoord[3] = s + float2(0, 2)*texelSize;
return OUT;
}
VS_OUTPUT_BLUR VS_Blur(float4 Position : POSITION,
float2 TexCoord : TEXCOORD0,
uniform int nsamples,
uniform float2 direction
)
{
VS_OUTPUT_BLUR OUT = (VS_OUTPUT_BLUR)0;
OUT.Position = Position;
float2 texelSize = BlurWidth / vViewportSize;
float2 s = TexCoord - texelSize*(nsamples-1)*0.5*direction;
for(int i=0; i<nsamples; i++) {
OUT.TexCoord[i] = s + texelSize*i*direction;
}
return OUT;
}
VS_OUTPUT VS_Quad(float4 Position : POSITION,
float2 TexCoord : TEXCOORD0)
{
VS_OUTPUT OUT;
float2 texelSize = 1.0 / vViewportSize;
OUT.Position = Position;
// don't want bilinear filtering on original scene:
OUT.TexCoord0 = TexCoord; //+ texelSize*0.5;
OUT.TexCoord1 = TexCoord + texelSize*0.5/downsampleScale;
OUT.TexCoord2 = texelSize;
return OUT;
}
//////////////////////////////////////////////////////
////////////////////////////////// pixel shaders /////
//////////////////////////////////////////////////////
half luminance(half3 c)
{
return dot( c, float3(0.3, 0.59, 0.11) );
}
half highlights(half3 c)
{
return smoothstep(HighlightThreshold, 1.0, luminance(c.rgb));
}
// blur filter weights
const half weights7[7] = {
0.05,
0.1,
0.2,
0.3,
0.2,
0.1,
0.05,
};
half4 PS_Blur7(VS_OUTPUT_BLUR IN,
uniform sampler2D tex,
uniform half weight[7]
) : COLOR
{
half4 c = 0;
// this loop will be unrolled by compiler
for(int i=0; i<7; i++) {
c += tex2D(tex, IN.TexCoord[i]) * weight[i];
}
return c;
}
half4 PS_Downsample(VS_OUTPUT_DOWNSAMPLE IN,
uniform sampler2D tex) : COLOR
{
half4 c;
c = tex2D(tex, IN.TexCoord[0]) * 0.25;
c += tex2D(tex, IN.TexCoord[1]) * 0.25;
c += tex2D(tex, IN.TexCoord[2]) * 0.25;
c += tex2D(tex, IN.TexCoord[3]) * 0.25;
// store hilights in alpha
c.a = highlights(c.rgb);
return c;
}
half4 PS_Comp(VS_OUTPUT IN,
uniform sampler2D sceneSampler,
uniform sampler2D blurredSceneSampler) : COLOR
{
float4 orig = tex2D(sceneSampler, IN.TexCoord0);
float4 blur = tex2D(blurredSceneSampler, IN.TexCoord1);
float2 s = IN.TexCoord2;
float4 x = 0;
float4 y = 0;
float4 xy;
float amount = 3.0f;
//x += tex2D(sceneSampler, IN.TexCoord0 + float2(-s.x, -s.y) );
x += -amount * tex2D(sceneSampler, IN.TexCoord0 + float2( 0.0f,-s.y) );
//x += tex2D(sceneSampler, IN.TexCoord0 + float2( s.x, -s.y) );
x += -amount * tex2D(sceneSampler, IN.TexCoord0 + float2(-s.x, 0.0f) );
x += +(amount*4+1) * tex2D(sceneSampler, IN.TexCoord0 + float2( 0.0f, 0.0f) );
x += -amount * tex2D(sceneSampler, IN.TexCoord0 + float2( s.x, 0.0f) );
//x += tex2D(sceneSampler, IN.TexCoord0 + float2(-s.x, s.y) );
x += -amount * tex2D(sceneSampler, IN.TexCoord0 + float2( 0.0f, s.y) );
//x += tex2D(sceneSampler, IN.TexCoord0 + float2( s.x, s.y) );
return x;
}
////////////////////////////////////////////////////////////
/////////////////////////////////////// techniques /////////
////////////////////////////////////////////////////////////
technique Bloom
{
pass DownSample
{
ZWriteEnable = false;
ZEnable = false;
Lighting = false;
VertexShader = compile vs_2_0 VS_Downsample();
PixelShader = compile ps_2_0 PS_Downsample(SceneSampler);
}
pass GlowH
{
ZWriteEnable = false;
ZEnable = false;
Lighting = false;
ZWriteEnable = false;
VertexShader = compile vs_2_0 VS_Blur(7, float2(1, 0));
PixelShader = compile ps_2_0 PS_Blur7(DownsampleSampler, weights7);
}
pass GlowV
{
ZWriteEnable = false;
ZEnable = false;
Lighting = false;
ZWriteEnable = false;
VertexShader = compile vs_2_0 VS_Blur(7, float2(0, 1));
PixelShader = compile ps_2_0 PS_Blur7(HBlurSampler, weights7);
}
pass FinalComp
{
cullmode = none;
ZEnable = false;
ZWriteEnable = false;
VertexShader = compile vs_2_0 VS_Quad();
PixelShader = compile ps_2_0 PS_Comp(SceneSampler, FinalBlurSampler);
}
}