float Script : STANDARDSGLOBAL <
string UIWidget = "none";
string ScriptClass = "scene";
string ScriptOrder = "postprocess";
string ScriptOutput = "color";
string Script = "Technique=Main;";
> = 0.8; // version #
float4 ClearColor <
string UIWidget = "color";
string UIName = "background";
> = {0,0,0,0.0};
float ClearDepth = 1.0;
#ifdef HAS_FP16
#define FAR 1000.0f
#else
#define FAR 1.0f
#endif
float4 ShadowClearColor <
string UIWidget = "none";
> = {FAR,FAR,FAR,0.0};
/************* "UN-TWEAKABLES," TRACKED BY CPU APPLICATION **************/
float4x4 WorldITXf : WorldInverseTranspose ;
float4x4 WorldViewProjXf : WorldViewProjection ;
float4x4 WorldXf : World ;
float4x4 ViewIXf : ViewInverse ;
float4x4 WorldViewITXf : WorldViewInverseTranspose ;
float4x4 WorldViewXf : WorldView ;
float4x4 ViewXf : View ;
float4x4 ViewITXf : ViewInverseTranspose ;
float4x4 LampViewXf : View <
//string UIWidget="None";
string frustum = "light0";
>;
float4x4 LampProjXf : Projection <
//string UIWidget="None";
string frustum = "light0";
>;
///////////////////////////////////////////////////////////////
/// TWEAKABLES ////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
////////////////////////////////////////////// spot light
float3 SpotLightPos : POSITION <
string UIName = "Light Posistion";
string Object = "SpotLight";
string Space = "World";
> = {-1.0f, 1.0f, 0.0f};
float3 SpotLightColor : Diffuse <
string UIName = "Lamp";
string Object = "SpotLight";
string UIWidget = "Color";
> = {0.8f, 1.0f, 0.4f};
float SpotLightIntensity <
string UIName = "Light Intensity";
string UIWidget = "slider";
float UIMin = 0.0;
float UIMax = 2;
float UIStep = 0.1;
> = 1;
float SpotLightCone <
string UIWidget = "slider";
float UIMin = 0.0;
float UIMax = 90.5;
float UIStep = 0.1;
string UIName = "Cone Angle";
> = 45.0f;
////////////////////////////////////////////// ambient light
float3 AmbiLightColor : Ambient
<
string UIName = "Ambient";
> = {0.07f, 0.07f, 0.07f};
/////////////// Shadow and Aiming Parameters
float ShadBias <
string UIWidget = "slider";
float UIMin = 0.0;
float UIMax = 0.3;
float UIStep = 0.0001;
string UIName = "Shadow Bias";
> = 0.01;
////////////////////////////////////////////// surface
float3 SurfColor : Diffuse
<
string UIName = "Surface";
string UIWidget = "Color";
> = {1.0f, 0.7f, 0.3f};
float Kd
<
string UIWidget = "slider";
float UIMin = 0.0;
float UIMax = 1.5;
float UIStep = 0.01;
string UIName = "Diffuse";
> = 1.0;
float Ks
<
string UIWidget = "slider";
float UIMin = 0.0;
float UIMax = 1.5;
float UIStep = 0.01;
string UIName = "Specular";
> = 1.0;
float SpecExpon : SpecularPower
<
string UIWidget = "slider";
float UIMin = 1.0;
float UIMax = 128.0;
float UIStep = 1.0;
string UIName = "Specular power";
> = 12.0;
float PCFSize <
string UIWidget = "slider";
float UIMin = 0.001;
float UIMax = 0.1;
float UIStep = 0.001;
string UIName = "PCF Filter Width";
> = 0.01;
////////////////////////////////////////////////////////
/// TEXTURES ///////////////////////////////////////////
////////////////////////////////////////////////////////
#define SHADOW_SIZE 1024
//#ifdef HAS_FP16
//#define SHADOW_FMT "a16b16g16r16f"
#define SHADOW_FMT "r32f"
//#else /* !HAS_FP16 */
//#define SHADOW_FMT "a8b8g8r8"
//#endif /* !HAS_FP16 */
texture ShadMap : RENDERCOLORTARGET <
float2 Dimensions = { SHADOW_SIZE, SHADOW_SIZE };
string Format = (SHADOW_FMT) ;
string UIWidget = "None";
>;
sampler ShadSampler = sampler_state {
texture = ;
AddressU = CLAMP;
AddressV = CLAMP;
MipFilter = NONE;
MinFilter = POINT;
MagFilter = POINT;
};
texture ShadDepthTarget : RENDERDEPTHSTENCILTARGET <
float2 Dimensions = { SHADOW_SIZE, SHADOW_SIZE };
string format = "D24S8";
string UIWidget = "None";
>;
/////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
/// SHADER CODE BEGINS /////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
/* data from application vertex buffer */
struct ShadowAppData {
float3 Position : POSITION;
float4 UV : TEXCOORD0;
float4 Normal : NORMAL;
};
// Connector from vertex to pixel shader
struct ShadowVertexOutput {
float4 HPosition : POSITION;
float2 UV : TEXCOORD0;
float3 LightVec : TEXCOORD1;
float3 WNormal : TEXCOORD2;
float3 WView : TEXCOORD3;
float4 LP : TEXCOORD4; // current position in light-projection space
};
// Connector from vertex to pixel shader
struct JustShadowVertexOutput {
float4 HPosition : POSITION;
float4 LP : TEXCOORD0; // current position in light-projection space
};
////////////////////////////////////////////////////////////////////////////////
/// Vertex Shaders /////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
JustShadowVertexOutput shadVS(ShadowAppData IN,
uniform float4x4 ShadowViewProjXf // typically created from aimShadowProjXf()
) {
JustShadowVertexOutput OUT = (JustShadowVertexOutput)0;
float4 Po = float4(IN.Position.xyz,(float)1.0); // object coordinates
float4 Pw = mul(Po,WorldXf); // "P" in world coordinates
float4 Pl = mul(Pw,ShadowViewProjXf); // "P" in light coords
OUT.LP = Pl; // view coords (also lightspace projection coords in this case)
OUT.HPosition = Pl; // screen clipspace coords
return OUT;
}
// from scene camera POV
ShadowVertexOutput mainCamVS(ShadowAppData IN,
uniform float4x4 ShadowViewProjXf)
{
ShadowVertexOutput OUT = (ShadowVertexOutput)0;
OUT.WNormal = mul(IN.Normal,WorldITXf).xyz; // world coords
float4 Po = float4(IN.Position.xyz,(float)1.0); // "P" in object coordinates
float4 Pw = mul(Po,WorldXf); // "P" in world coordinates
float4 Pl = mul(Pw,ShadowViewProjXf); // "P" in light coords
OUT.LP = Pl; // ...for pixel-shader shadow calcs
OUT.WView = normalize(ViewIXf[3].xyz - Pw.xyz); // world coords
OUT.HPosition = mul(Po,WorldViewProjXf); // screen clipspace coords
OUT.UV = IN.UV.xy; // pass-thru
OUT.LightVec = SpotLightPos - Pw.xyz; // world coords
return OUT;
}
/*********************************************************/
/*********** pixel shader ********************************/
/*********************************************************/
float4 shadPS(JustShadowVertexOutput IN) : COLOR
{
return float4(IN.LP.zzz,1);
}
//
// Utility function for pixel shaders to use this shadow map
//
float shadow_calc(float4 LP, // current shaded point in light-projected coordinates
uniform sampler ShadowMapSampler, // obvious
uniform float ShadowBiasing
) {
float totalShad=0;
int i, j;
float offSize = PCFSize / (float)PCF_SAMPS;
for (i = -PCFH; i<= PCFH; i += 1) {
for (j = -PCFH; j<= PCFH; j += 1) {
float2 offset = float2(offSize*i,offSize*j);
float2 nuv = float2(.5,-.5)*(LP.xy+offset)/LP.w + float2(.5,.5);
float shadMapDepth = tex2D(ShadowMapSampler,nuv).x;
float depth = LP.z - ShadowBiasing;
float shad = 1-(shadMapDepth {
pass MakeShadow <
string Script = "RenderColorTarget0=ShadMap;"
"RenderDepthStencilTarget=ShadDepthTarget;"
"RenderPort=light0;"
"ClearSetColor=ShadowClearColor;"
"ClearSetDepth=ClearDepth;"
"Clear=Color;"
"Clear=Depth;"
"Draw=geometry;";
> {
VertexShader = compile vs_3_0 shadVS(mul(LampViewXf,LampProjXf));
ZEnable = true;
ZWriteEnable = true;
ZFunc = LessEqual;
CullMode = None;
PixelShader = compile ps_3_0 shadPS();
}
pass UseShadow <
string Script = "RenderColorTarget0=;"
"RenderDepthStencilTarget=;"
"RenderPort=;"
"ClearSetColor=ClearColor;"
"ClearSetDepth=ClearDepth;"
"Clear=Color;"
"Clear=Depth;"
"Draw=geometry;";
> {
VertexShader = compile vs_3_0 mainCamVS(mul(LampViewXf,LampProjXf));
ZEnable = true;
ZWriteEnable = true;
ZFunc = LessEqual;
CullMode = None;
PixelShader = compile ps_3_0 useShadowPS(cos(radians(SpotLightCone)));
}
}
/***************************** 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 ///
]]>