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