= 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 ***/ ]]>