= 0.8;
///////////////////////////////////////////////////////////
/////////////////////////////////////// Tweakables ////////
///////////////////////////////////////////////////////////
float SceneIntensity <
string UIName = "Scene intensity";
string UIWidget = "slider";
float UIMin = 0.0f;
float UIMax = 2.0f;
float UIStep = 0.1f;
> = 0.5f;
float GlowIntensity <
string UIName = "Glow intensity";
string UIWidget = "slider";
float UIMin = 0.0f;
float UIMax = 2.0f;
float UIStep = 0.1f;
> = 0.5f;
float HighlightThreshold <
string UIName = "Highlight threshold";
string UIWidget = "slider";
float UIMin = 0.0f;
float UIMax = 1.0f;
float UIStep = 0.1f;
> = 0.9f;
float HighlightIntensity <
string UIName = "Highlight intensity";
string UIWidget = "slider";
float UIMin = 0.0f;
float UIMax = 10.0f;
float UIStep = 0.1f;
> = 0.5f;
///////////////////////////////////////////////////////////
///////////////////////////// Render-to-Texture Data //////
///////////////////////////////////////////////////////////
float2 WindowSize : VIEWPORTPIXELSIZE < string UIWidget = "none"; >;
float downsampleScale = 0.25;
float BlurWidth <
string UIName = "Blur width";
string UIWidget = "slider";
float UIMin = 0.0f;
float UIMax = 10.0f;
float UIStep = 0.5f;
> = 2.0f;
texture SceneMap : RENDERCOLORTARGET
<
float2 ViewportRatio = { 1.0, 1.0 };
int MIPLEVELS = 1;
string format = "X8R8G8B8";
>;
texture DepthMap : RENDERDEPTHSTENCILTARGET
<
float2 ViewportRatio = { 1.0, 1.0 };
string format = "D24S8";
>;
sampler SceneSampler = sampler_state
{
texture = ;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
MIPFILTER = NONE;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};
texture DownsampleMap : RENDERCOLORTARGET
<
float2 ViewportRatio = { 0.25, 0.25 };
int MIPLEVELS = 1;
string format = "A8R8G8B8";
>;
sampler DownsampleSampler = sampler_state
{
texture = ;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
MIPFILTER = NONE;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};
texture HBlurMap : RENDERCOLORTARGET
<
float2 ViewportRatio = { 0.25, 0.25 };
int MIPLEVELS = 1;
string format = "A8R8G8B8";
>;
sampler HBlurSampler = sampler_state
{
texture = ;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
MIPFILTER = NONE;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};
texture FinalBlurMap : RENDERCOLORTARGET
<
float2 ViewportRatio = { 0.25, 0.25 };
int MIPLEVELS = 1;
string format = "A8R8G8B8";
>;
sampler FinalBlurSampler = sampler_state
{
texture = ;
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;
};
struct VS_OUTPUT_DOWNSAMPLE
{
float4 Position : POSITION;
float2 TexCoord[4]: TEXCOORD0;
};
////////////////////////////////////////////////////////////
////////////////////////////////// vertex shaders //////////
////////////////////////////////////////////////////////////
// generate texture coordinates to sample 4 neighbours
VS_OUTPUT_DOWNSAMPLE VS_Downsample(float4 Position : POSITION,
float2 TexCoord : TEXCOORD0)
{
VS_OUTPUT_DOWNSAMPLE OUT;
float2 texelSize = downsampleScale / WindowSize;
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;
}
// generate texcoords for blur
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 / WindowSize;
float2 s = TexCoord - texelSize*(nsamples-1)*0.5*direction;
for(int i=0; i
{
pass DownSample
<
string Script = "RenderColorTarget0=DownsampleMap;"
"ClearSetColor=ClearColor;"
"Clear=Color;"
"Draw=Buffer;";
>
{
cullmode = none;
ZEnable = false;
ZWriteEnable = false;
VertexShader = compile vs_2_0 VS_Downsample();
PixelShader = compile ps_2_0 PS_Downsample(SceneSampler);
}
pass GlowH
<
string Script = "RenderColorTarget0=HBlurMap;"
"ClearSetColor=ClearColor;"
"Clear=Color;"
"Draw=Buffer;";
>
{
cullmode = none;
ZEnable = false;
ZWriteEnable = false;
VertexShader = compile vs_2_0 VS_Blur(7, float2(1, 0));
// PixelShader = compile ps_2_0 PS_Blur7(SceneSampler, weights7);
PixelShader = compile ps_2_0 PS_Blur7(DownsampleSampler, weights7);
}
pass GlowV
<
string Script = "RenderColorTarget0=FinalBlurMap;"
"ClearSetColor=ClearColor;"
"Clear=color;"
"Draw=Buffer;";
>
{
cullmode = none;
ZEnable = false;
ZWriteEnable = false;
VertexShader = compile vs_2_0 VS_Blur(7, float2(0, 1));
PixelShader = compile ps_2_0 PS_Blur7(HBlurSampler, weights7);
}
pass GlowH_Central
<
string Script = "RenderColorTarget0=HBlurMap;"
"ClearSetColor=ClearColor;"
"Clear=Color;"
"Draw=Buffer;";
>
{
cullmode = none;
ZEnable = false;
ZWriteEnable = false;
VertexShader = compile vs_2_0 VS_Blur(7, float2(1, 0));
PixelShader = compile ps_2_0 PS_Blur7(DownsampleSampler, weights7_Central);
}
pass GlowV_Central
<
string Script = "RenderColorTarget0=FinalBlurMap;"
"ClearSetColor=ClearColor;"
"Clear=Color;"
"Draw=Buffer;";
>
{
cullmode = none;
ZEnable = false;
ZWriteEnable = false;
VertexShader = compile vs_2_0 VS_Blur(7, float2(0, 1));
PixelShader = compile ps_2_0 PS_Blur7(HBlurSampler, weights7_Central);
}
pass FinalComp
<
string Script = "RenderColorTarget=;"
"RenderDepthStencilTarget=;"
"Draw=Buffer;";
>
{
cullmode = none;
ZEnable = false;
ZWriteEnable = false;
VertexShader = compile vs_2_0 VS_Quad();
PixelShader = compile ps_2_0 PS_Comp(SceneSampler, FinalBlurSampler);
}
}
]]>
// Turn this on to get the "dissolve" technique -- a bit slow just now
// #define DISSOLVE
float Script : STANDARDSGLOBAL <
string UIWidget = "none";
string ScriptClass = "scene";
string ScriptOrder = "postprocess";
string ScriptOutput = "color";
string Script = "Technique=Technique?over:base:blend"
#ifdef DISSOLVE
":dissolve"
#endif /* DISSOLVE */
// NO TECHNIQUES FOUND
":average:darken:lighten:multiply:add:subtract:difference:inverseDifference"
":exclusion:screen:colorBurn:colorDodge:overlay:softLight:hardLight";
> = 0.8;
float4 ClearColor : DIFFUSE <
string UIName = "Background";
> = {0.3,0.3,0.3,1.0};
float ClearDepth
<
string UIWidget = "none";
> = 1.0;
// Top-Level Compilation Switches /////////////////////////////////////
// Turn this on to provide "advanced" PS-style blend ranges
// #define BLEND_RANGE
// Turn this on to use grayscale values for the above. Ignored if (!BLEND_RANGE)
// #define BLEND_GRAY
// If (!BLEND_GRAY) use this channel for BLEND_RANGE calculations
// #define BLEND_CHANNEL r
// Define this if you want to build static lookup textures for the blend-range functions
// #define BLEND_TEX
///////////////////////////////////////////////////////////
///////////////////////////// Render-to-Texture Data //////
///////////////////////////////////////////////////////////
DECLARE_QUAD_TEX(SceneTexture,SceneSampler,"A8R8G8B8")
DECLARE_QUAD_DEPTH_BUFFER(DepthBuffer, "D24S8")
/////////////////////////////////////////////////////
//// Textures for Input Images //////////////////////
/////////////////////////////////////////////////////
FILE_TEXTURE_2D(BlendImg,BlendImgSampler,"Blended.dds")
/////////////////////////////////////////////////////
//// Tweakables /////////////////////////////////////
/////////////////////////////////////////////////////
float Opacity <
string UIWidget = "slider";
float uimin = 0.0;
float uimax = 1.0;
float uistep = 0.01;
string UIName = "Blend Opacity";
> = 1.0;
// Blend Ranges for "Advanced Blend"
// (these could be float4's but are individual sliders for FX Composer)
#ifdef BLEND_RANGE
#define LNORM(minv,maxv,p) ((p)-(minv))/((maxv)-(minv))
// #define CLAMP(p) min(1.0,(max(0.0,(p))))
#define CLAMP(p) (((p)<=0.0)?0:(((p)>=1)?1:(p)))
// #define CLAMPRANGE(minv,maxv,p) min(1.0,(max(0.0,LNORM(minv,maxv,p))))
#define CLAMPRANGE(minv,maxv,p) CLAMP((LNORM((minv),(maxv),(p))))
#ifdef BLEND_TEX
///////////////////////////////////////////////////////////
////// procedural textures used for blending //////////////
///////////////////////////////////////////////////////////
#define BASE_LO_MIN 0.0
#define BASE_LO_MAX 0.7
#define BASE_HI_MIN 0.9
#define BASE_HI_MAX 1.0
#define BLEND_LO_MIN 0.0
#define BLEND_LO_MAX 0.3
#define BLEND_HI_MIN 0.8
#define BLEND_HI_MAX 1.0
#define BLEND_TEX_SIZE 256
// texture functions used to fill the volume noise texture
float4 blend_1D(float2 Pos : POSITION) : COLOR
{
float lo, hi;
if (BLEND_LO_MIN == BLEND_LO_MAX) {
lo = (Pos.x >= BLEND_LO_MIN) ? 1 : 0;
} else {
lo = CLAMPRANGE(BLEND_LO_MIN,BLEND_LO_MAX,Pos.x);
}
if (BLEND_HI_MIN == BLEND_HI_MAX) {
hi = (Pos.x <= BLEND_HI_MIN) ? 1 : 0;
} else {
hi = 1 - CLAMPRANGE(BLEND_HI_MIN,BLEND_HI_MAX,Pos.x);
}
float4 blends = 0;
blends.x = lo * hi;
if (BASE_LO_MIN == BASE_LO_MAX) {
lo = (Pos.y >= BASE_LO_MIN) ? 1 : 0;
} else {
lo = CLAMPRANGE(BASE_LO_MIN,BASE_LO_MAX,Pos.y);
}
if (BASE_HI_MIN == BASE_HI_MAX) {
hi = (Pos.y <= BASE_HI_MIN) ? 1 : 0;
} else {
hi = 1 - CLAMPRANGE(BLEND_HI_MIN,BLEND_HI_MAX,Pos.y);
}
blends.y = lo * hi;
return blends;
}
texture BlendTex <
string ResourceType = "2D";
string function = "blend_1D";
string UIWidget = "None";
string Format = "A16B16G16R16F";
float2 Dimensions = { BLEND_TEX_SIZE, BLEND_TEX_SIZE };
>;
sampler BlendSampler = sampler_state
{
texture = ;
AddressU = CLAMP;
AddressV = CLAMP;
MIPFILTER = LINEAR;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};
#else /* ! BLEND_TEX */
float baseLoMin
<
string UIWidget = "slider";
float uimin = 0.0;
float uimax = 1.0;
float uistep = 0.01;
string UIName = "Blend Opacity";
> = 0.0;
float baseLoMax
<
string UIWidget = "slider";
float uimin = 0.0;
float uimax = 1.0;
float uistep = 0.01;
string UIName = "Blend Opacity";
> = 0.1;
float baseHiMin
<
string UIWidget = "slider";
float uimin = 0.0;
float uimax = 1.0;
float uistep = 0.01;
string UIName = "Blend Opacity";
> = 0.9;
float baseHiMax
<
string UIWidget = "slider";
float uimin = 0.0;
float uimax = 1.0;
float uistep = 0.01;
string UIName = "Blend Opacity";
> = 1.0;
float blendLoMin
<
string UIWidget = "slider";
float uimin = 0.0;
float uimax = 1.0;
float uistep = 0.01;
string UIName = "Blend Opacity";
> = 0.0;
float blendLoMax
<
string UIWidget = "slider";
float uimin = 0.0;
float uimax = 1.0;
float uistep = 0.01;
string UIName = "Blend Opacity";
> = 0.1;
float blendHiMin
<
string UIWidget = "slider";
float uimin = 0.0;
float uimax = 1.0;
float uistep = 0.01;
string UIName = "Blend Opacity";
> = 0.9;
float blendHiMax
<
string UIWidget = "slider";
float uimin = 0.0;
float uimax = 1.0;
float uistep = 0.01;
string UIName = "Blend Opacity";
> = 1.0;
#endif /* ! BLEND_TEX */
#endif /* BLEND_RANGE */
// Dissolve-Related tweakable and functions //////
#ifdef DISSOLVE
float Dissolver
<
string UIWidget = "slider";
float uimin = 0.0;
float uimax = 1.0;
float uistep = 0.01;
string UIName = "For Dissolve";
> = 0.5;
////// procedural texture used for dissolve
#define NOISE_SIZE 256
#define NOISE_SCALE 110
// function used to fill the volume noise texture
float4 noise_2d(float2 Pos : POSITION) : COLOR
{
float4 Noise = (float4)0;
for (int i = 1; i < 256; i += i) {
Noise.r += abs(noise(Pos * NOISE_SCALE * i)) / i;
//Noise.g += abs(noise((Pos + 1.2)* NOISE_SCALE * i)) / i;
//Noise.b += abs(noise((Pos + 2.3) * NOISE_SCALE * i)) / i;
//Noise.a += abs(noise((Pos + 3.1) * NOISE_SCALE * i)) / i;
}
return Noise.rrrr;
}
texture NoiseTex <
string ResourceType = "2D";
string function = "noise_2d";
string UIWidget = "None";
float2 Dimensions = { NOISE_SIZE, NOISE_SIZE };
>;
sampler NoiseSampler = sampler_state
{
texture = ;
AddressU = WRAP;
AddressV = WRAP;
MIPFILTER = LINEAR;
MINFILTER = LINEAR;
MAGFILTER = LINEAR;
};
#endif /* DISSOLVE */
/**************************************************************/
/********* utility pixel-shader functions and macros **********/
/**************************************************************/
#define GET_PIX float4 base = tex2D(SceneSampler, IN.UV); \
float4 blend = tex2D(BlendImgSampler, IN.UV)
#ifdef BLEND_GRAY
float grayValue(float3 Color)
{
return dot(Color,float3(0.25,0.65,0.1)); // just made this chroma target up - KB
}
#endif /* BLEND_GRAY */
// assume NON-pre-multiplied RGB...
float4 final_mix(float4 NewColor,float4 Base,float4 Blend)
{
float A2 = Opacity * Blend.a;
#ifdef BLEND_RANGE
#ifdef BLEND_GRAY
float blendV = grayValue(Blend.rgb);
float baseV = grayValue(Base.rgb);
#else /* ! BLEND_GRAY */
float blendV = Blend.BLEND_CHANNEL;
float baseV = Base.BLEND_CHANNEL;
#endif /* !BLEND_GRAY */
#ifdef BLEND_TEX
float2 bv = tex2D(BlendSampler,float2(blendV,baseV)).xy;
// baseV = tex2D(BlendSampler,float2(baseV,0)).y;
A2 *= (bv.x * bv.y);
#else /* !BLEND_TEX */
blendV =
CLAMPRANGE(blendLoMin,blendLoMax,blendV)*
(1-CLAMPRANGE(blendHiMin,blendHiMax,blendV));
baseV =
CLAMPRANGE(baseLoMin,baseLoMax,baseV)*
(1-CLAMPRANGE(baseHiMin,baseHiMax,baseV));
A2 *= (blendV * baseV);
#endif /* !BLEND_TEX */
#endif /*BLEND_RANGE */
float3 mixRGB = A2 * NewColor.rgb;
mixRGB += ((1.0-A2) * Base.rgb);
// float mixA = max(Base.a, A2);
// float mixA = 1 - (1-Base.w)*(1-A2);
return float4(mixRGB,Blend.a); // wrong grrrrr
}
/**************************************/
/********* blend pixel shaders ********/
/**************************************/
float4 overPS(QuadVertexOutput IN) : COLOR {
GET_PIX;
return final_mix(blend,base,blend);
}
float4 basePS(QuadVertexOutput IN) : COLOR {
GET_PIX;
return base;
}
float4 blendPS(QuadVertexOutput IN) : COLOR {
GET_PIX;
return blend;
}
#ifdef DISSOLVE
float4 dissolvePS(QuadVertexOutput IN) : COLOR {
GET_PIX;
float diss = tex2D(NoiseSampler, IN.UV1).x;
float4 newC;
if (diss < Dissolver) {
newC = blend;
} else {
newC = base;
}
return final_mix(newC,base,blend);
}
#endif /* DISSOLVE */
float4 averagePS(QuadVertexOutput IN) : COLOR {
GET_PIX;
return final_mix((blend+base)/2,base,blend);
}
float4 darkenPS(QuadVertexOutput IN) : COLOR {
GET_PIX;
return final_mix(min(base,blend),base,blend);
}
float4 lightenPS(QuadVertexOutput IN) : COLOR {
GET_PIX;
return final_mix(max(base,blend),base,blend);
}
float4 multiplyPS(QuadVertexOutput IN) : COLOR {
GET_PIX;
return final_mix((base*blend),base,blend);
}
float4 addPS(QuadVertexOutput IN) : COLOR {
GET_PIX;
return final_mix((base+blend),base,blend);
}
float4 subtractPS(QuadVertexOutput IN) : COLOR {
GET_PIX;
return final_mix((base*blend),base,blend);
}
float4 differencePS(QuadVertexOutput IN) : COLOR {
GET_PIX;
return final_mix(abs(base*blend),base,blend);
}
float4 inverseDifferencePS(QuadVertexOutput IN) : COLOR {
GET_PIX;
return final_mix(1-abs(1-base-blend),base,blend);
}
float4 exclusionPS(QuadVertexOutput IN) : COLOR {
GET_PIX;
return final_mix(base + blend - (2*base*blend),base,blend);
}
float4 screenPS(QuadVertexOutput IN) : COLOR {
GET_PIX;
return final_mix(1 - (1 - base) * (1 - blend),base,blend);
}
float4 colorBurnPS(QuadVertexOutput IN) : COLOR {
GET_PIX;
return final_mix(1-(1-base)/blend,base,blend);
}
float4 colorDodgePS(QuadVertexOutput IN) : COLOR {
GET_PIX;
return final_mix( base / (1-blend), base,blend);
}
float4 overlayPS(QuadVertexOutput IN) : COLOR {
GET_PIX;
float4 lumCoeff = float4(0.25,0.65,0.1,0);
float L = min(1,max(0,10*(dot(lumCoeff,base)- 0.45)));
float4 result1 = 2 * base * blend;
float4 result2 = 1 - 2*(1-blend)*(1-base);
return final_mix(lerp(result1,result2,L),base,blend);
}
float4 softLightPS(QuadVertexOutput IN) : COLOR {
GET_PIX;
return final_mix(2*base*blend + base*base - 2*base*base*blend,base,blend);
}
float4 hardLightPS(QuadVertexOutput IN) : COLOR {
GET_PIX;
float4 lumCoeff = float4(0.25,0.65,0.1,0);
float L = min(1,max(0,10*(dot(lumCoeff,blend)- 0.45)));
float4 result1 = 2 * base * blend;
float4 result2 = 1 - 2*(1-blend)*(1-base);
return final_mix(lerp(result1,result2,L),base,blend);
}
/*******************************************************************/
/************* TECHNIQUES ******************************************/
/*******************************************************************/
#define DEFSCRIPT "RenderColorTarget0=SceneTexture;RenderDepthStencilTarget=DepthBuffer;ClearSetColor=ClearColor;ClearSetDepth=ClearDepth;Clear=Color;Clear=Depth;ScriptExternal=color;Pass=p0;"
// simplest techniques work in ps_1_1
#define TECH(name,psName) technique name < string Script = (DEFSCRIPT); > {\
pass p0 { \
VertexShader = compile vs_1_1 ScreenQuadVS(); \
ZEnable = false; ZWriteEnable = false; CullMode = None; \
PixelShader = compile ps_1_1 psName (); } }
// most techniques require ps_2 for blending
#define TECH2(name,psName) technique name < string Script = (DEFSCRIPT); > { \
pass p0 { \
VertexShader = compile vs_2_0 ScreenQuadVS(); \
ZEnable = false; ZWriteEnable = false; CullMode = None; \
PixelShader = compile ps_2_0 psName (); } }
TECH2(over,overPS)
TECH(base,basePS)
TECH(blend,blendPS)
#ifdef DISSOLVE
TECH2(dissolve,dissolvePS)
#endif /* DISSOLVE */
TECH2(average,averagePS)
TECH2(darken,darkenPS)
TECH2(lighten,lightenPS)
TECH2(multiply,multiplyPS)
TECH2(add,addPS)
TECH2(subtract,subtractPS)
TECH2(difference,differencePS)
TECH2(inverseDifference,inverseDifferencePS)
TECH2(exclusion,exclusionPS)
TECH2(screen,screenPS)
TECH2(colorBurn,colorBurnPS)
TECH2(colorDodge,colorDodgePS)
TECH2(overlay,overlayPS)
TECH2(softLight,softLightPS)
TECH2(hardLight,hardLightPS)
/***************************** eof ***/
]]>; \
sampler SampName = sampler_state { \
texture = ; \
AddressU = AddrMode; \
AddressV = AddrMode; \
MipFilter = LINEAR; \
MinFilter = LINEAR; \
MagFilter = LINEAR; \
};
//
// Simple 2D File Textures
//
// example usage: FILE_TEXTURE_2D(GlowMap,GlowSampler,"myfile.dds")
//
#define FILE_TEXTURE_2D(TextureName,SamplerName,Diskfile) FILE_TEXTURE_2D_MODAL(TextureName,SamplerName,(Diskfile),WRAP)
//
// Use this variation of DECLARE_QUAD_TEX() if you want a *scaled* render target
//
// example usage: DECLARE_SIZED_QUAD_TEX(GlowMap,GlowSampler,"A8R8G8B8",1.0)
#define DECLARE_SIZED_QUAD_TEX(TexName,SampName,PixFmt,Multiple) texture TexName : RENDERCOLORTARGET < \
float2 ViewPortRatio = {Multiple,Multiple}; \
int MipLevels = 1; \
string Format = PixFmt ; \
string UIWidget = "None"; \
>; \
sampler SampName = sampler_state { \
texture = ; \
AddressU = CLAMP; \
AddressV = CLAMP; \
MipFilter = POINT; \
MinFilter = LINEAR; \
MagFilter = LINEAR; \
};
//
// Use this macro to easily declare typical color render targets
//
// example usage: DECLARE_QUAD_TEX(ObjMap,ObjSampler,"A8R8G8B8")
#define DECLARE_QUAD_TEX(TextureName,SamplerName,PixelFormat) DECLARE_SIZED_QUAD_TEX(TextureName,SamplerName,(PixelFormat),1.0)
//
// Use this macro to easily declare variable-sized depth render targets
//
// example usage: DECLARE_SIZED_QUAD_DEPTH_BUFFER(DepthMap,"D24S8",0.5)
#define DECLARE_SIZED_QUAD_DEPTH_BUFFER(TextureName,PixelFormat,Multiple) texture TextureName : RENDERDEPTHSTENCILTARGET < \
float2 ViewPortRatio = {Multiple,Multiple}; \
string Format = (PixelFormat); \
string UIWidget = "None"; \
>;
//
// Use this macro to easily declare typical depth render targets
//
// example usage: DECLARE_QUAD_DEPTH_BUFFER(DepthMap,"D24S8")
#define DECLARE_QUAD_DEPTH_BUFFER(TexName,PixFmt) DECLARE_SIZED_QUAD_DEPTH_BUFFER(TexName,PixFmt,1.0)
//
// declare exact-sized arbitrary texture
//
// example usage: DECLARE_SIZED_TEX(BlahMap,BlahSampler,"R32F",128,1)
#define DECLARE_SIZED_TEX(Tex,Samp,Fmt,Wd,Ht) texture Tex : RENDERCOLORTARGET < \
float2 Dimensions = { Wd, Ht }; \
string Format = Fmt ; \
string UIWidget = "None"; \
int miplevels=1;\
>; \
sampler Samp = sampler_state { \
texture = ; \
AddressU = CLAMP; \
AddressV = CLAMP; \
MipFilter = NONE; \
MinFilter = LINEAR; \
MagFilter = LINEAR; \
};
//
// declare exact-sized square texture, as for shadow maps
//
// example usage: DECLARE_SQUARE_QUAD_TEX(ShadMap,ShadObjSampler,"A16R16G16B16F",512)
#define DECLARE_SQUARE_QUAD_TEX(TexName,SampName,PixFmt,Size) DECLARE_SIZED_TEX(TexName,SampName,(PixFmt),Size,Size)
//
// likewise for shadow depth targets
//
// example usage: DECLARE_SQUARE_QUAD_DEPTH_BUFFER(ShadDepth,"D24S8",512)
#define DECLARE_SQUARE_QUAD_DEPTH_BUFFER(TextureName,PixelFormat,Size) texture TextureName : RENDERDEPTHSTENCILTARGET < \
float2 Dimensions = { Size, Size }; \
string Format = (PixelFormat) ; \
string UIWidget = "None"; \
>;
////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////// Utility Functions ////////
////////////////////////////////////////////////////////////////////////////
//
// Scale inputs for use with texture-based lookup tables. A value ranging from zero to one needs
// a slight scaling and offset to be sure to point at the centers of the first and last pixels
// of that lookup texture. Pass the integer size of the table in TableSize
// For now we'll assume that all tables are 1D, square, or cube-shaped -- all axes of equal size
//
// Cost of this operation for pixel shaders: two const-register
// entries and a MAD (one cycle)
QUAD_REAL scale_lookup(QUAD_REAL Value,const QUAD_REAL TableSize)
{
QUAD_REAL scale = ((TableSize - 1.0)/TableSize);
QUAD_REAL shift = (0.5 / TableSize);
return (scale*Value + shift);
}
QUAD_REAL2 scale_lookup(QUAD_REAL2 Value,const QUAD_REAL TableSize)
{
QUAD_REAL scale = ((TableSize - 1.0)/TableSize);
QUAD_REAL shift = (0.5 / TableSize);
return (scale.xx*Value + shift.xx);
}
QUAD_REAL3 scale_lookup(QUAD_REAL3 Value,const QUAD_REAL TableSize)
{
QUAD_REAL scale = ((TableSize - 1.0)/TableSize);
QUAD_REAL shift = (0.5 / TableSize);
return (scale.xxx*Value + shift.xxx);
}
// pre-multiply and un-pre-mutliply functions. The precision
// of thse operatoions is often limited to 8-bit so don't
// always count on them!
// The macro value of NV_ALPHA_EPSILON, if defined, is used to
// avoid IEEE "NaN" values that may occur when erroneously
// dividing by a zero alpha (thanks to Pete Warden @ Apple
// Computer for the suggestion in GPU GEMS II)
// multiply color by alpha to turn an un-premultipied
// pixel value into a premultiplied one
QUAD_REAL4 premultiply(QUAD_REAL4 C)
{
return QUAD_REAL4((C.w*C.xyz),C.w);
}
#define NV_ALPHA_EPSILON 0.0001
// given a premultiplied pixel color, try to undo the premultiplication.
// beware of precision errors
QUAD_REAL4 unpremultiply(QUAD_REAL4 C)
{
#ifdef NV_ALPHA_EPSILON
QUAD_REAL a = C.w + NV_ALPHA_EPSILON;
return QUAD_REAL4((C.xyz / a),C.w);
#else /* ! NV_ALPHA_EPSILON */
return QUAD_REAL4((C.xyz / C.w),C.w);
#endif /* ! NV_ALPHA_EPSILON */
}
/////////////////////////////////////////////////////////////////////////////////////
// Structure Declaration ////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
struct QuadVertexOutput {
QUAD_REAL4 Position : POSITION;
QUAD_REAL2 UV : TEXCOORD0;
};
/////////////////////////////////////////////////////////////////////////////////////
// Hidden tweakables declared by this .fxh file /////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
#ifndef NO_TEXEL_OFFSET
#ifdef TWEAKABLE_TEXEL_OFFSET
QUAD_REAL QuadTexOffset = 0.5;
#else /* !TWEAKABLE_TEXEL_OFFSET */
QUAD_REAL QuadTexOffset < string UIWidget="None"; > = 0.5;
#endif /* !TWEAKABLE_TEXEL_OFFSET */
QUAD_REAL2 QuadScreenSize : VIEWPORTPIXELSIZE < string UIWidget="None"; >;
#endif /* NO_TEXEL_OFFSET */
////////////////////////////////////////////////////////////
////////////////////////////////// vertex shaders //////////
////////////////////////////////////////////////////////////
QuadVertexOutput ScreenQuadVS(
QUAD_REAL3 Position : POSITION,
QUAD_REAL3 TexCoord : TEXCOORD0
) {
QuadVertexOutput OUT;
OUT.Position = QUAD_REAL4(Position, 1);
#ifdef NO_TEXEL_OFFSET
OUT.UV = TexCoord.xy;
#else /* NO_TEXEL_OFFSET */
QUAD_REAL2 off = QUAD_REAL2(QuadTexOffset/(QuadScreenSize.x),QuadTexOffset/(QuadScreenSize.y));
OUT.UV = QUAD_REAL2(TexCoord.xy+off);
#endif /* NO_TEXEL_OFFSET */
return OUT;
}
//////////////////////////////////////////////////////
////////////////////////////////// pixel shaders /////
//////////////////////////////////////////////////////
// add glow on top of model
QUAD_REAL4 TexQuadPS(QuadVertexOutput IN,uniform sampler2D InputSampler) : COLOR
{
QUAD_REAL4 texCol = tex2D(InputSampler, IN.UV);
return texCol;
}
QUAD_REAL4 TexQuadBiasPS(QuadVertexOutput IN,uniform sampler2D InputSampler,QUAD_REAL TBias) : COLOR
{
QUAD_REAL4 texCol = tex2Dbias(InputSampler, QUAD_REAL4(IN.UV,0,TBias));
return texCol;
}
//////////////////////////////////////////////////////////////////
/// Macros to define passes within Techniques ////////////////////
//////////////////////////////////////////////////////////////////
// older HLSL syntax
#define TEX_TECH(TechName,SamplerName) technique TechName { \
pass TexturePass { \
VertexShader = compile vs_2_0 ScreenQuadVS(); \
AlphaBlendEnable = false; ZEnable = false; \
PixelShader = compile ps_2_a TexQuadPS(SamplerName); } }
#define TEX_BLEND_TECH(TechName,SamplerName) technique TechName { \
pass TexturePass { \
VertexShader = compile vs_2_0 ScreenQuadVS(); \
ZEnable = false; AlphaBlendEnable = true; \
SrcBlend = SrcAlpha; DestBlend = InvSrcAlpha; \
PixelShader = compile ps_2_a TexQuadPS(SamplerName); } }
// newer HLSL syntax
#define TEX_TECH2(TechName,SamplerName,TargName) technique TechName { \
pass TexturePass < \
string ScriptFunction = "RenderColorTarget0=" (TargName) ";" \
"DrawInternal=Buffer;"; \
> { \
VertexShader = compile vs_2_0 ScreenQuadVS(); \
AlphaBlendEnable = false; ZEnable = false; \
PixelShader = compile ps_2_a TexQuadPS(SamplerName); } }
#define TEX_BLEND_TECH2(TechName,SamplerName) technique TechName { \
pass TexturePass < \
string ScriptFunction = "RenderColorTarget0=" (TargName) ";" \
"DrawInternal=Buffer;"; \
> { \
VertexShader = compile vs_2_0 ScreenQuadVS(); \
ZEnable = false; AlphaBlendEnable = true; \
SrcBlend = SrcAlpha; DestBlend = InvSrcAlpha; \
PixelShader = compile ps_2_a TexQuadPS(SamplerName); } }
#endif /* _QUAD_FXH */
////////////// eof ///
]]>
float Script : STANDARDSGLOBAL <
string UIWidget = "none";
string ScriptClass = "scene";
string ScriptOrder = "preprocess";
string ScriptOutput = "color";
string Script = "Technique=TexBg;";
> = 0.8; // version #
float ClearDepth = 1.0;
///////// Textures ///////////////
texture BgTexture
<
string ResourceName = "Veggie.dds";
string ResourceType = "2D";
string UIName = "Background Texture";
>;
sampler2D BgSampler = sampler_state
{
Texture = ;
MinFilter = Point;
MagFilter = Point;
MipFilter = None;
};
////////////////////////
technique TexBg <
string Script =
"ClearSetDepth=ClearDepth;"
"Clear=Depth;"
"Pass=Bg;"
"ScriptExternal=Scene;";
> {
pass Bg <
string Script = "Draw=Buffer;";
> {
VertexShader = compile vs_1_1 ScreenQuadVS();
AlphaBlendEnable = false;
ZEnable = false;
PixelShader = compile ps_1_1 TexQuadPS(BgSampler);
}
}
/***************************** eof ***/
]]> = 0.8;
/*********** UNTWEAKABLES **************/
float4x4 WorldIT : WorldInverseTranspose < string UIWidget="None"; >;
float4x4 WorldViewProj : WorldViewProjection < string UIWidget="None"; >;
float4x4 World : World < string UIWidget="None"; >;
float4x4 ViewI : ViewInverse < string UIWidget="None"; >;
/************* TWEAKABLES **************/
float3 LightPos : Position <
string Object = "PointLight";
string Space = "World";
> = {-10.0f, 10.0f, -10.0f};
float3 LightColor <
string UIName = "Light Color";
string UIWidget = "Color";
> = {1.0f, 1.0f, 1.0f};
float LightIntensity
<
string UIWidget = "slider";
float UIMin = 1.0;
float UIMax = 1000.0;
float UIStep = 0.2;
string UIName = "Intensity";
> = 1.0;
float3 AmbiColor : Ambient
<
string UIName = "Ambient Light Color";
string UIWidget = "Color";
> = {0.2f, 0.2f, 0.2f};
////
float3 SurfColor : Diffuse
<
string UIName = "Surface Color";
string UIWidget = "Color";
> = {0.9f, 0.5f, 0.9f};
float SpecExpon : SpecularPower
<
string UIWidget = "slider";
float UIMin = 1.0;
float UIMax = 128.0;
float UIStep = 1.0;
string UIName = "specular power";
> = 22.0;
/************* DATA STRUCTS **************/
/* data from application vertex buffer */
struct appdata {
float3 Position : POSITION;
float4 UV : TEXCOORD0;
float4 Normal : NORMAL;
};
/* data passed from vertex shader to pixel shader */
struct vertexOutput {
float4 HPosition : POSITION;
float4 TexCoord0 : TEXCOORD0; // put light distance into "z"
float4 diffCol : COLOR0;
float4 specCol : COLOR1;
};
/*********** vertex shader ******/
vertexOutput plasticQVS(appdata IN)
{
vertexOutput OUT;
float3 Nn = normalize(mul(IN.Normal, WorldIT).xyz);
float4 Po = float4(IN.Position.xyz,1);
float3 Pw = mul(Po, World).xyz;
OUT.HPosition = mul(Po, WorldViewProj);
float3 LightDelta = (LightPos - Pw);
float falloff = LightIntensity / dot(LightDelta,LightDelta);
float3 Ln = normalize(LightDelta);
float ldn = dot(Ln,Nn);
float diffComp = max(0,ldn);
float3 diffContrib = SurfColor * (diffComp * LightColor + AmbiColor);
OUT.diffCol = float4(diffContrib,1);
OUT.TexCoord0 = float4(IN.UV.xy,falloff,1.0);
float3 Vn = normalize(ViewI[3].xyz - Pw);
float3 Hn = normalize(Vn + Ln);
float hdn = pow(max(0,dot(Hn,Nn)),SpecExpon);
OUT.specCol = float4((diffComp * hdn * LightColor).xyz,1);
return OUT;
}
/********* pixel shader ********/
float4 plasticQPS(vertexOutput IN) : COLOR {
return (IN.TexCoord0.z * (IN.diffCol + IN.specCol));
}
/*************/
technique ps11 <
string Script = "Pass=p0;";
> {
pass p0 <
string Script = "Draw=geometry;";
> {
VertexShader = compile vs_1_1 plasticQVS();
ZEnable = true;
ZWriteEnable = true;
CullMode = None;
PixelShader = compile ps_1_1 plasticQPS();
}
}
/***************************** eof ***/
]]>