float Script : STANDARDSGLOBAL < string UIWidget = "none"; string ScriptClass = "scene"; string ScriptOrder = "standard"; string ScriptOutput = "color"; // We just call a script in the main technique. string Script = "Technique=water;"; > = 0.8; // Params bool bReset : FXCOMPOSER_RESETPULSE < string UIName="Reset"; >; bool Painting < string UIName="Splash with Mouse?"; > = true; float iterationsPerFrame < string UIName = "Iterations Per Frame"; string UIWidget = "slider"; float UIMin = 0; float UIMax = 100; float UIStep = 1; > = 10; float BrushSize < string UIWidget = "slider"; float UIMin = 0.001; float UIMax = 0.15; float UIStep = 0.001; string UIName = "Brush size"; > = 0.1f; float4 ClearColor : DIFFUSE = {0.0, 0.0, 0.0, 0.0}; float4 PaintColor : DIFFUSE = {0.5, 0.5, 0.5, 0.0}; float4 MouseL : LEFTMOUSEDOWN < string UIWidget="None"; >; float3 MousePos : MOUSEPOSITION < string UIWidget="None"; >; float Timer : TIME < string UIWidget = "None"; >; float Damping < string UIWidget = "slider"; string UIName = "Damping"; float UIMin = 0.0; float UIMax = 1.0; float UIStep = 0.001; > = 0.99f; float Brightness < string UIWidget = "slider"; string UIName = "Brightness"; float UIMin = 0.0; float UIMax = 10.0; float UIStep = 0.001; > = 1.0f; float NormalScale < string UIWidget = "slider"; string UIName = "Normal scale"; float UIMin = 0.0; float UIMax = 1.0; float UIStep = 0.001; > = 0.1f; float Refraction < string UIWidget = "slider"; string UIName = "Refraction strengh"; float UIMin = 0.0; float UIMax = 1.0; float UIStep = 0.001; > = 0.01f; //////////////////////////////////////////////////// /// Textures /////////////////////////////////////// //////////////////////////////////////////////////// #define WIDTH 256 #define HEIGHT 256 float2 viewport : VIEWPORTPIXELSIZE ; float2 texelSize = 1.0f / float2(WIDTH, HEIGHT); //static float2 texelSize = 1.0f / viewport; //#define TEX_FORMAT "A32B32G32R32F" #define TEX_FORMAT "A16B16G16R16F" //#define TEX_FORMAT "R32F" texture PaintTex : RENDERCOLORTARGET < float2 Dimensions = { WIDTH, HEIGHT }; // float2 ViewportRatio = { 1.0, 1.0 }; string Format = "a8b8g8r8"; string UIWidget = "None"; int MipLevels = 1; >; // We need 3 heightfield textures - current, previous, and one to render to texture HeightTex0 : RENDERCOLORTARGET < float2 Dimensions = { WIDTH, HEIGHT }; // float2 ViewportRatio = { 1.0, 1.0 }; string Format = TEX_FORMAT; string UIWidget = "None"; int MipLevels = 1; >; texture HeightTex1 : RENDERCOLORTARGET < float2 Dimensions = { WIDTH, HEIGHT }; // float2 ViewportRatio = { 1.0, 1.0 }; string Format = TEX_FORMAT; string UIWidget = "None"; int MipLevels = 1; >; texture HeightTex2 : RENDERCOLORTARGET < float2 Dimensions = { WIDTH, HEIGHT }; // float2 ViewportRatio = { 1.0, 1.0 }; string Format = TEX_FORMAT; string UIWidget = "None"; int MipLevels = 1; >; texture NormalMapTex : RENDERCOLORTARGET < float2 Dimensions = { WIDTH, HEIGHT }; // float2 ViewportRatio = { 1.0, 1.0 }; string Format = TEX_FORMAT; string UIWidget = "None"; int MipLevels = 1; >; texture DepthStencilTarget : RENDERDEPTHSTENCILTARGET < float2 Dimensions = { WIDTH, HEIGHT }; // float2 ViewportRatio = { 1.0, 1.0 }; string format = "D24S8"; string UIWidget = "None"; >; sampler PaintSamp = sampler_state { texture = ; AddressU = CLAMP; AddressV = CLAMP; MipFilter = None; MinFilter = POINT; MagFilter = POINT; }; sampler HeightSamp0 = sampler_state { texture = ; AddressU = CLAMP; AddressV = CLAMP; MipFilter = None; MinFilter = POINT; MagFilter = POINT; }; sampler HeightSamp1 = sampler_state { texture = ; AddressU = CLAMP; AddressV = CLAMP; MipFilter = None; MinFilter = POINT; MagFilter = POINT; }; sampler HeightSamp2 = sampler_state { texture = ; AddressU = CLAMP; AddressV = CLAMP; MipFilter = None; MinFilter = POINT; MagFilter = POINT; }; sampler NormalMapSamp = sampler_state { texture = ; AddressU = CLAMP; AddressV = CLAMP; MipFilter = None; MinFilter = POINT; MagFilter = POINT; }; texture SeedTexture < string ResourceName = "Height_seed.png"; string TextureType = "2D"; string UIName = "Seed Image"; >; sampler2D SeedSampler = sampler_state { Texture = ; MinFilter = Linear; MagFilter = Linear; MipFilter = None; AddressU = CLAMP; AddressV = CLAMP; }; texture ImageTexture < string ResourceName = "nvlogo.png"; string TextureType = "2D"; string UIName = "Background Image"; >; sampler2D ImageSampler = sampler_state { Texture = ; MinFilter = Linear; MagFilter = Linear; MipFilter = Linear; AddressU = Wrap; AddressV = Wrap; }; // Shaders #if 1 #define float4 half4 #define float3 half3 #define float2 half2 #define float half #endif float4 sumNeighborsWrap(sampler2D tex, float2 coords) { float4 sum; sum = tex2D(tex, coords + float2(texelSize.x, 0)); sum += tex2D(tex, coords + float2(-texelSize.x, 0)); sum += tex2D(tex, coords + float2(0, texelSize.y)); sum += tex2D(tex, coords + float2(0, -texelSize.y)); return sum; } // perform water simulation float4 simulate_PS(QuadVertexOutput IN, uniform sampler2D currentHeightTex, uniform sampler2D prevHeightTex ) : COLOR { float4 h_curr = tex2D(currentHeightTex, IN.UV.xy); float4 h_new = sumNeighborsWrap(prevHeightTex, IN.UV.xy) / 2.0 - h_curr; h_new *= Damping; return h_new; } // simulate and add seed float4 simulate_seed_PS(QuadVertexOutput IN, uniform sampler2D tex_curr, uniform sampler2D tex_prev ) : COLOR { return simulate_PS(IN, tex_curr, tex_prev) + tex2D(PaintSamp, IN.UV.xy); } // paint brush stroke float4 strokePS(QuadVertexOutput IN) : COLOR { float r = length(IN.UV.xy - 0.5*MousePos.xy); // float i = r < BrushSize; float i = smoothstep(BrushSize, 0.0, r); i *= MouseL.z * Painting; return PaintColor * i; } // add paint texture to buffer float4 addSeedPS(QuadVertexOutput IN, uniform sampler2D tex ) : COLOR { return tex2D(tex, IN.UV.xy) + tex2D(PaintSamp, IN.UV.xy); } // calculate normal from heightfield float4 calcNormalPS(QuadVertexOutput IN, uniform sampler2D heightTex ) : COLOR { float3 n; n.y = tex2D(heightTex, IN.UV.xy + float2(-texelSize.x, 0.0)).x - tex2D(heightTex, IN.UV.xy + float2(texelSize.x, 0.0)).x; n.x = tex2D(heightTex, IN.UV.xy + float2(0.0, -texelSize.x)).x - tex2D(heightTex, IN.UV.xy + float2(0.0, texelSize.y)).x; n.z = NormalScale; n = normalize(n); return float4(n, 1.0); } // display heightfield float4 displayHeightPS(QuadVertexOutput IN, uniform sampler2D tex ) : COLOR { // return abs(tex2D(tex, IN.UV.xy)) * Brightness; return (tex2D(tex, IN.UV.xy)*0.5+0.5) * Brightness; } // display heightfield with shading effects float4 displayShadedPS(QuadVertexOutput IN, uniform sampler2D heightTex, uniform sampler2D normalTex, uniform sampler2D imageTex ) : COLOR { float3 L = { 0.577, 0.577, 0.577 }; // float3 L = { 0.0, 0.0, 1.0 }; float3 H = L; float3 diffColor = { 1.0, 1.0, 1.0 }; float3 specColor = { 1.0, 1.0, 1.0 }; float shininess = 10.0; float3 N = tex2D(normalTex, IN.UV.xy); float3 diff = max(0, dot(N, L)) * diffColor; float3 spec = pow(max(0, dot(N, H)), shininess) * specColor; float3 image = tex2D(imageTex, IN.UV.xy + N.xy*Refraction); // return float4(diff + spec, 1.0); // return float4(spec, 1.0); return float4(image*diff + spec, 1.0); } // Technique technique water < string Script = "LoopByCount=bReset;" "Pass=reset;" "Pass=reset1;" "LoopEnd=;" "Pass=paint;" // "Pass=seed;" "LoopByCount=iterationsPerFrame;" "Pass=simulate0;" "Pass=copy0;" "Pass=simulate1;" "Pass=copy1;" "LoopEnd=;" "Pass=calcNormal;" "Pass=display;"; > { pass simulate0 < string Script = "RenderColorTarget0=HeightTex2;" "RenderDepthStencilTarget=DepthStencilTarget;" "Draw=Buffer;"; > { VertexShader = compile vs_1_1 ScreenQuadVS(); PixelShader = compile ps_2_a simulate_PS(HeightSamp0, HeightSamp1); AlphaBlendEnable = false; ZEnable = false; ZFunc = always; } pass copy0 < string Script = "RenderColorTarget0=HeightTex0;" "RenderDepthStencilTarget=DepthStencilTarget;" "Draw=Buffer;"; > { VertexShader = compile vs_1_1 ScreenQuadVS(); PixelShader = compile ps_2_a TexQuadPS(HeightSamp2); AlphaBlendEnable = false; ZEnable = false; } pass simulate1 < string Script = "RenderColorTarget0=HeightTex2;" "RenderDepthStencilTarget=DepthStencilTarget;" "Draw=Buffer;"; > { VertexShader = compile vs_1_1 ScreenQuadVS(); // PixelShader = compile ps_2_a simulate_PS(HeightSamp1, HeightSamp0); PixelShader = compile ps_2_a simulate_seed_PS(HeightSamp1, HeightSamp0); AlphaBlendEnable = false; ZEnable = false; } pass copy1 < string Script = "RenderColorTarget0=HeightTex1;" "RenderDepthStencilTarget=DepthStencilTarget;" "Draw=Buffer;"; > { VertexShader = compile vs_1_1 ScreenQuadVS(); PixelShader = compile ps_2_a TexQuadPS(HeightSamp2); AlphaBlendEnable = false; ZEnable = false; } pass calcNormal < string Script = "RenderColorTarget0=NormalMapTex;" "RenderDepthStencilTarget=DepthStencilTarget;" "Draw=Buffer;"; > { VertexShader = compile vs_1_1 ScreenQuadVS(); PixelShader = compile ps_2_a calcNormalPS(HeightSamp0); AlphaBlendEnable = false; ZEnable = false; } pass display < string Script = "RenderColorTarget0=;" "RenderDepthStencilTarget=;" "Draw=Buffer;"; > { VertexShader = compile vs_1_1 ScreenQuadVS(); // PixelShader = compile ps_2_a TexQuadPS(HeightSamp0); // PixelShader = compile ps_2_a displayHeightPS(HeightSamp0); // PixelShader = compile ps_2_a displayHeightPS(NormalMapSamp); PixelShader = compile ps_2_a displayShadedPS(HeightSamp0, NormalMapSamp, ImageSampler); AlphaBlendEnable = false; ZEnable = false; } pass paint < string Script = "RenderColorTarget0=PaintTex;" "RenderDepthStencilTarget=DepthStencilTarget;" // "LoopByCount=bReset;" "ClearSetColor=ClearColor;" "Clear=Color0;" // "LoopEnd=;" "Draw=Buffer;"; > { VertexShader = compile vs_1_1 ScreenQuadVS(); PixelShader = compile ps_2_0 strokePS(); AlphaBlendEnable = true; SrcBlend = One; DestBlend = One; ZEnable = false; } pass seed < string Script = "RenderColorTarget0=HeightTex0;" "RenderDepthStencilTarget=DepthStencilTarget;" "LoopByCount=bReset;" "ClearSetColor=ClearColor;" "Clear=Color0;" "LoopEnd=;" "Draw=Buffer;"; > { VertexShader = compile vs_1_1 ScreenQuadVS(); PixelShader = compile ps_2_0 addSeedPS(HeightSamp1); AlphaBlendEnable = false; ZEnable = false; } pass reset < string Script = "RenderColorTarget0=HeightTex0;" "RenderDepthStencilTarget=DepthStencilTarget;" "Draw=Buffer;"; > { VertexShader = compile vs_1_1 ScreenQuadVS(); PixelShader = compile ps_2_a TexQuadPS(SeedSampler); AlphaBlendEnable = false; ZEnable = false; } pass reset1 < string Script = "RenderColorTarget0=HeightTex1;" "RenderDepthStencilTarget=DepthStencilTarget;" "Draw=Buffer;"; > { VertexShader = compile vs_1_1 ScreenQuadVS(); PixelShader = compile ps_2_a TexQuadPS(SeedSampler); AlphaBlendEnable = false; ZEnable = false; } } ]]>; \ 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 /// ]]>