= 0.8; // version # /////////////// #define SPEC_EXPON 64.0 #define TOX_TABLE_SIZE 256 #define TOX_FORMAT "g16r16" /************* "UN-TWEAKABLES," TRACKED BY CPU APPLICATION **************/ float4x4 WorldITXf : WorldInverseTranspose ; float4x4 WvpXf : WorldViewProjection ; float4x4 WorldXf : World ; float4x4 ViewIXf : ViewInverse ; float2 ScreenSize : VIEWPORTPIXELSIZE ; /////////////////////////////////////////////////////////////// /// TWEAKABLES //////////////////////////////////////////////// /////////////////////////////////////////////////////////////// ////////////////////////////////////////////// light float3 LightDir : DIRECTION < string UIName = "Direction"; string Object = "DirectionalLight"; string Space = "World"; > = {-1.0f, -1.0f, -0.2f}; float3 LightColor : SPECULAR < string UIName = "Lamp"; string UIWidget = "Color"; > = {1.0f, 1.0f, 1.0f}; ////////////////////////////////////////////// ambient light float3 AmbiLightColor : Ambient < string UIName = "Ambient"; string UIWidget = "Color"; > = {0.07f, 0.07f, 0.07f}; ////////////////////////////////////////////// surface float3 SurfColor : Diffuse < string UIName = "Surface"; string UIWidget = "Color"; > = {1.0f, 1.0f, 1.0f}; float Kd < string UIWidget = "slider"; float UIMin = 0.0; float UIMax = 1.5; float UIStep = 0.01; string UIName = "Diffuse"; > = 0.6; float Ks < string UIWidget = "slider"; float UIMin = 0.0; float UIMax = 1.5; float UIStep = 0.01; string UIName = "Specular"; > = 1.0; float Bumpy = 1.0; float URep < string UIWidget = "slider"; float UIMin = 1.0; float UIMax = 40.0; float UIStep = 1.0; string UIName = "U Repeat"; > = 1.0; float VRep < string UIWidget = "slider"; float UIMin = 1.0; float UIMax = 40.0; float UIStep = 1.0; string UIName = "V Repeat"; > = 1.0; //////////////////////////////////////////////////////// /// TEXTURES /////////////////////////////////////////// //////////////////////////////////////////////////////// #ifdef DO_COLORTEX texture ColorTexture : DIFFUSE < string ResourceName = "default_color.dds"; string TextureType = "2D"; >; sampler2D ColorSampler = sampler_state { Texture = ; MinFilter = Linear; MagFilter = Linear; MipFilter = Linear; }; #endif /* !DO_COLORTEX */ texture NormalTexture : NORMAL < string ResourceName = "default_bump_normal.dds"; string TextureType = "2D"; >; sampler2D NormalSampler = sampler_state { Texture = ; MinFilter = Linear; MagFilter = Linear; MipFilter = Linear; }; //////////////////////////////////////////////////////// float spec_func(float s, float NaH, float NaNa) { float toksvig = sqrt(NaNa)/(sqrt(NaNa)+s*(1-sqrt(NaNa))); return (1.0+toksvig*s)/(1.0+s)*pow(NaH/sqrt(NaNa), toksvig*s); } float4 make_specular_tex(float2 Pos : POSITION, float2 Size : PSIZE) : COLOR { float f = spec_func(SPEC_EXPON,Pos.x,Pos.y); return float4(f.xxx,0.0); } texture SpecTex < string function = "make_specular_tex"; int width = TOX_TABLE_SIZE; int height = TOX_TABLE_SIZE; string UIWidget = "None"; string format = (TOX_FORMAT); >; sampler SpecSampler = sampler_state { texture = ; AddressU = CLAMP; AddressV = CLAMP; MIPFILTER = NONE; MINFILTER = ANISOTROPIC; MAGFILTER = ANISOTROPIC; }; ////////////// /*********************************************************/ /************* DATA STRUCTS ******************************/ /*********************************************************/ /* data from application vertex buffer */ struct appdata { float3 Position : POSITION; float4 UV : TEXCOORD0; float4 Normal : NORMAL; float4 Tangent : TANGENT0; float4 Binormal : BINORMAL0; }; struct vertexOutput { float4 HPosition : POSITION; float2 UV : TEXCOORD0; float3 WorldNormal : TEXCOORD1; float3 WorldView : TEXCOORD2; float3 WorldTangent : TEXCOORD3; float3 WorldBinorm : TEXCOORD4; }; /*********************************************************/ /*********** vertex shader *******************************/ /*********************************************************/ vertexOutput basicVS(appdata IN) { vertexOutput OUT; OUT.WorldNormal = normalize(mul(IN.Normal,WorldITXf).xyz); OUT.WorldTangent = normalize(mul(IN.Tangent,WorldITXf).xyz); OUT.WorldBinorm = normalize(mul(IN.Binormal,WorldITXf).xyz); float4 Po = float4(IN.Position.xyz,1.0); // object coordinates float3 Pw = mul(Po,WorldXf).xyz; // world coordinates OUT.UV = (float2(URep,VRep) * IN.UV.xy); OUT.WorldView = normalize(ViewIXf[3].xyz - Pw); // obj coords OUT.HPosition = mul(Po,WvpXf); // screen clipspace coords return OUT; } /*********************************************************/ /*********** pixel shader ********************************/ /*********************************************************/ float4 toksvigPS(vertexOutput IN) : COLOR { float3 Nn = /*normalize*/(IN.WorldNormal); float3 Tn = /*normalize*/(IN.WorldTangent); float3 Bn = /*normalize*/(IN.WorldBinorm); float3 bumps = 2.0 * (tex2D(NormalSampler,IN.UV).xyz-(0.5).xxx); float3 Na = bumps.x * Tn + bumps.y * Bn + bumps.z * Nn; float3 Vn = normalize(IN.WorldView); float3 Ln = /*normalize*/(-LightDir); // normalize() required? FXComposer should provide pre-norm'd value float3 Hn = normalize(Vn + Ln); float NaH = dot(Hn,Na); float NaNa = dot(Na,Na); //float2 texelAdjust = (0.5/TOX_TABLE_SIZE).xx; //float s = tex2D(SpecSampler,float2(NaH,NaNa)+texelAdjust).x; float s = tex2D(SpecSampler,float2(NaH,NaNa)).x; Nn = normalize(Na); float ldn = dot(Ln,Nn); ldn = max(ldn,0); float3 diffContrib = ldn * LightColor; float3 specContrib = ((s * Ks) * LightColor); // add, incorporating ambient light term #ifdef DO_COLORTEX float3 colorTex = SurfColor * tex2D(ColorSampler,IN.UV).xyz; #define SURF_COLOR colorTex #else /* !DO_COLORTEX */ #define SURF_COLOR SurfColor #endif /* !DO_COLORTEX */ float3 result = SURF_COLOR*(Kd*diffContrib+AmbiLightColor) + specContrib; return float4(result.xyz,1.0); } float4 nonToksvigPS(vertexOutput IN) : COLOR { float3 Nn = normalize(IN.WorldNormal); float3 Tn = normalize(IN.WorldTangent); float3 Bn = normalize(IN.WorldBinorm); float3 bumps = (Bumpy*2.0) * (tex2D(NormalSampler,IN.UV).xyz-(0.5).xxx); Nn = (bumps.x*Tn + bumps.y*Bn + bumps.z*Nn); Nn = normalize(Nn); float3 Vn = normalize(IN.WorldView); float3 Ln = normalize(-LightDir); // normalize() required? float3 Hn = normalize(Vn + Ln); float hdn = dot(Hn,Nn); float ldn = dot(Ln,Nn); float4 litVec = lit(ldn,hdn,SPEC_EXPON); float3 diffContrib = litVec.y * LightColor; float3 specContrib = ((litVec.z * Ks) * LightColor); // add, incorporating ambient light term #ifdef DO_COLORTEX float3 colorTex = SurfColor * tex2D(ColorSampler,IN.UV).xyz; #define SURF_COLOR colorTex #else /* !DO_COLORTEX */ #define SURF_COLOR SurfColor #endif /* !DO_COLORTEX */ float3 result = SURF_COLOR*(Kd*diffContrib+AmbiLightColor) + specContrib; return float4(result.xyz,1.0); } //////////////////////////////////////////////////////////////////// /// TECHNIQUES ///////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// technique Toksvig < string Script = "Pass=p0;"; > { pass p0 < string Script = "Draw=geometry;"; > { VertexShader = compile vs_2_0 basicVS(); ZEnable = true; ZWriteEnable = true; CullMode = None; PixelShader = compile ps_2_a toksvigPS(); } } technique Non_Toksvig < string Script = "Pass=p0;"; > { pass p0 < string Script = "Draw=geometry;"; > { VertexShader = compile vs_2_0 basicVS(); ZEnable = true; ZWriteEnable = true; CullMode = None; PixelShader = compile ps_2_a nonToksvigPS(); } } /***************************** eof ***/ ]]>