#include 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.1,0.1,0.1,0.0}; float ClearDepth = 1.0; /////////////////////////////////////////////////////////// /////////////////////////////////////// Textures ////////// /////////////////////////////////////////////////////////// DECLARE_QUAD_TEX(SceneTexture,SceneSampler,"A8R8G8B8") DECLARE_QUAD_TEX(DTex0,DSamp0,"A8R8G8B8") DECLARE_QUAD_DEPTH_BUFFER(DepthBuffer,"D24S8") /////////////////////////////////////////////////////////// /////////////////////////////////////// Tweakables //////// /////////////////////////////////////////////////////////// // #define SHIFT_MAX 0.01f #define SHIFT_MAX 0.10f #define SHIFT_MIN (-SHIFT_MAX) #define ROT_MAX 10.0f #define ROT_MIN (-ROT_MAX) float OffCx < string UIWidget = "slider"; string UIName = "Cyan X Offset"; float UIMin = SHIFT_MIN; float UIMax = SHIFT_MAX; float UIStep = 0.001f; > = 0.002f; float OffCy < string UIWidget = "slider"; string UIName = "Cyan Y Offset"; float UIMin = SHIFT_MIN; float UIMax = SHIFT_MAX; float UIStep = 0.001f; > = 0.0f; float OffCr < string UIWidget = "slider"; string UIName = "Cyan Rotation"; float UIMin = ROT_MIN; float UIMax = ROT_MAX; float UIStep = 0.01; > = 0.0f; float OffMx < string UIWidget = "slider"; string UIName = "Magenta X Offset"; float UIMin = SHIFT_MIN; float UIMax = SHIFT_MAX; float UIStep = 0.001f; > = 0.0f; float OffMy < string UIWidget = "slider"; string UIName = "Magenta Y Offset"; float UIMin = SHIFT_MIN; float UIMax = SHIFT_MAX; float UIStep = 0.001f; > = 0.001f; float OffMr < string UIWidget = "slider"; string UIName = "Magenta Rotation"; float UIMin = ROT_MIN; float UIMax = ROT_MAX; float UIStep = 0.01f; > = 0.0f; float OffYx < string UIWidget = "slider"; string UIName = "Yellow X Offset"; float UIMin = SHIFT_MIN; float UIMax = SHIFT_MAX; float UIStep = 0.001f; > = -0.003f; float OffYy < string UIWidget = "slider"; string UIName = "Yellow Y Offset"; float UIMin = SHIFT_MIN; float UIMax = SHIFT_MAX; float UIStep = 0.001f; > = -0.001f; float OffYr < string UIWidget = "slider"; string UIName = "Yellow Rotation"; float UIMin = ROT_MIN; float UIMax = ROT_MAX; float UIStep = 0.01f; > = 0.0f; float OffKx < string UIWidget = "slider"; string UIName = "Black (K) X Offset"; float UIMin = SHIFT_MIN; float UIMax = SHIFT_MAX; float UIStep = 0.001f; > = 0.0f; float OffKy < string UIWidget = "slider"; string UIName = "Black (K) Y Offset"; float UIMin = SHIFT_MIN; float UIMax = SHIFT_MAX; float UIStep = 0.001f; > = -0.015f; float OffKr < string UIWidget = "slider"; string UIName = "Black (K) Rotation"; float UIMin = ROT_MIN; float UIMax = ROT_MAX; float UIStep = 0.01f; > = 0.0f; static QUAD_REAL2 COffset = QUAD_REAL2(OffCx,OffCy); static QUAD_REAL2 MOffset = QUAD_REAL2(OffMx,OffMy); static QUAD_REAL2 YOffset = QUAD_REAL2(OffYx,OffYy); static QUAD_REAL2 KOffset = QUAD_REAL2(OffKx,OffKy); static QUAD_REAL2 CRot = QUAD_REAL2(cos(radians(OffCr)),sin(radians(OffCr))); static QUAD_REAL2 MRot = QUAD_REAL2(cos(radians(OffMr)),sin(radians(OffMr))); static QUAD_REAL2 YRot = QUAD_REAL2(cos(radians(OffYr)),sin(radians(OffYr))); static QUAD_REAL2 KRot = QUAD_REAL2(cos(radians(OffKr)),sin(radians(OffKr))); ////////////////////////////////////////////////////// ////////////////////////////////// vertex shader ///// ////////////////////////////////////////////////////// struct SplitVertexOutput { QUAD_REAL4 Position : POSITION; QUAD_REAL2 UV0 : TEXCOORD0; QUAD_REAL2 UV1 : TEXCOORD1; QUAD_REAL2 UV2 : TEXCOORD2; QUAD_REAL2 UV3 : TEXCOORD3; }; // utility const QUAD_REAL2 CenterPt = QUAD_REAL2(0.5,0.5); QUAD_REAL2 misalign(QUAD_REAL2 Orig,QUAD_REAL2 Off, QUAD_REAL2 Rot) { QUAD_REAL2 m = Orig + Off - CenterPt; QUAD_REAL2 tilt = QUAD_REAL2(m.x*Rot.x - m.y*Rot.y, m.y*Rot.x + m.x*Rot.y); return (tilt+CenterPt); } SplitVertexOutput SplitVS( QUAD_REAL3 Position : POSITION, QUAD_REAL3 TexCoord : TEXCOORD0 ) { SplitVertexOutput OUT = (SplitVertexOutput)0; OUT.Position = QUAD_REAL4(Position, 1); #ifdef NO_TEXEL_OFFSET QUAD_REAL2 base = TexCoord.xy; #else /* NO_TEXEL_OFFSET */ QUAD_REAL2 off = QUAD_REAL2(QuadTexOffset/(QuadScreenSize.x),QuadTexOffset/(QuadScreenSize.y)); QUAD_REAL2 base = QUAD_REAL2(TexCoord.xy+off); #endif /* NO_TEXEL_OFFSET */ OUT.UV0 = misalign(base,COffset,CRot); OUT.UV1 = misalign(base,MOffset,MRot); OUT.UV2 = misalign(base,YOffset,YRot); OUT.UV3 = misalign(base,KOffset,KRot); return OUT; } ////////////////////////////////////////////////////// /////////////////////////////////// pixel shader ///// ////////////////////////////////////////////////////// QUAD_REAL4 SeparatePS(QuadVertexOutput IN) : COLOR { CREAL3 rgb = tex2D(SceneSampler, IN.UV).xyz; CREAL4 cmyk = rgb2cmyk(rgb); return QUAD_REAL4(cmyk); } QUAD_REAL4 SplitPS(SplitVertexOutput IN) : COLOR { CREAL c = tex2D(DSamp0, IN.UV0).x; CREAL m = tex2D(DSamp0, IN.UV1).y; CREAL y = tex2D(DSamp0, IN.UV2).z; CREAL k = tex2D(DSamp0, IN.UV3).w; CREAL4 cmyk = CREAL4(c,m,y,k); CREAL3 rgb = cmyk2rgb(cmyk); return QUAD_REAL4(rgb.xyz,1); } ///////////////////////////////////////////////// //////////////////////////////////////////////////////////// /////////////////////////////////////// techniques ///////// //////////////////////////////////////////////////////////// technique Main < string ScriptClass = "scene"; string ScriptOrder = "postprocess"; string ScriptOutput = "color"; string Script = "RenderColorTarget0=SceneTexture;" "RenderDepthStencilTarget=DepthBuffer;" "ClearSetColor=ClearColor;" "ClearSetDepth=ClearDepth;" "Clear=Color;" "Clear=Depth;" "ScriptExternal=color;" "Pass=Convert;" "Pass=Split;"; > { pass Convert < string Script = "RenderColorTarget0=DTex0;" "Draw=Buffer;"; > { VertexShader = compile vs_2_0 ScreenQuadVS(); ZEnable = false; AlphaBlendEnable = false; PixelShader = compile ps_2_a SeparatePS(); } pass Split < string Script = "RenderColorTarget0=;" "RenderDepthStencilTarget=;" "Draw=Buffer;"; > { VertexShader = compile vs_2_0 SplitVS(); ZEnable = false; AlphaBlendEnable = false; PixelShader = compile ps_2_a SplitPS(); } } ]]>; \ 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 ***/ ]]>