;
float4x4 viMatrix : ViewInverse ;
// Textures //////////////////
texture texmap : Diffuse
<
string ResourceName = "dm1.jpg";
>;
texture dispmap
<
string ResourceName = "dm1.tga";
>;
texture dispindxmap
<
string ResourceName = "displace_indxmap.tga";
>;
sampler2D texmap_sampler = sampler_state
{
Texture = ;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = None;
};
sampler2D dispmap_sampler = sampler_state
{
Texture = ;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = None;
AddressU = Clamp;
AddressV = Clamp;
};
sampler2D dispindxmap_sampler = sampler_state
{
Texture = ;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = None;
AddressU = Clamp;
AddressV = Clamp;
};
// Tweakable parameters ////////////////////////
float tile
<
string UIWidget = "slider";
float UIMin = 1;
float UIMax = .0;
float UIStep = 1;
string UIName = "tile";
> = 10.0;
float4 constants
<
string UIName = "constants";
> = {32,32,0.03125,0.03125};
float depth
<
string UIName = "depth";
> = 3.38478;
float4 base0
<
string UIName = "base0";
> = {-1,-1,0,0};
float4 base1
<
string UIName = "base1";
> = {1,0,0,2};
float4 base2
<
string UIName = "base2";
> = {0,1,0,2};
float4 diffuse
<
string UIName = "diffuse";
string UIWidget = "Color";
> = {1,1,1,1};
float4 specular
<
string UIName = "specular";
string UIWidget = "Color";
> = {0.75,0.75,0.75,100};
float4 lightpos : Position
<
string Object = "PointLight";
string Space = "World";
> = {-1.0f, 1.0f, -1.5f, 1.0f};
float4 lightcolor
<
string UIWidget = "Color";
> = {1.0f, 1.0f, 1.0f, 1.0f};
// structures ///////////////////////////////////
struct a2v
{
float4 pos : POSITION;
};
struct v2f {
float4 hpos : POSITION;
float4 opos : TEXCOORD0;
float4 eyepos : TEXCOORD1;
};
// shaders //////////////////////////////////
v2f displace_map_vert(
a2v IN,
uniform float4x4 WorldViewProj,
uniform float4x4 ViewInv)
{
v2f OUT;
OUT.hpos=mul(IN.pos,WorldViewProj);
OUT.opos=IN.pos;
OUT.eyepos=ViewInv[3];
return OUT;
}
float4 displace_map_frag(
v2f IN,
uniform float depthfactor,
uniform sampler2D texmap,
uniform sampler2D dispmap,
uniform sampler2D dispindxmap) : COLOR
{
float4 t,color;
float3 viewdir,opos,lightdir,halfdir;
float2 uv,uv1,uv2;
float HdotL,NdotL;
// view direction is AB index (uv1)
viewdir=normalize(IN.opos.xyz-IN.eyepos.xyz);
// full computation
// uv1.x=1.0-acos(viewdir.x/sqrt(1.0-viewdir.y*viewdir.y))/3.1415927;
// uv1.y=1.0-acos(viewdir.y)/3.1415927;
// simplified computation
uv1=viewdir.xy*0.5+0.5;
t=tex2D(dispindxmap,uv1);
uv1=t.xy+t.zw*0.005;
// tile position is XY index (uv2)
opos=IN.opos.xyz-base0.xyz;
uv.x=dot(opos,base1.xyz)/base1.w;
uv.y=dot(opos,base2.xyz)/base2.w;
uv2=fmod(uv*tile,1.0);
// compose ABXY index for 4D texture (uv=f(uv1,uv2))
uv=(floor(uv1*constants.xy)+uv2.xy)*constants.zw;
// get pixel normal and depth from displace map
t=tex2D(dispmap,uv);
t.xyz=2.0*t.xyz-1.0;
if (depth<0.01)
t=float4(0.0,0.0,1.0,0.0);
// displace pixel and compute new texture coordinates
opos+=viewdir*t.w*depthfactor;
uv.x=dot(opos,base1.xyz)/base1.w;
uv.y=dot(opos,base2.xyz)/base2.w;
// illuminate for a point light with diffuse and specular
diffuse*=tex2D(texmap,uv*tile);
lightdir=normalize(opos+base0.xyz-lightpos.xyz);
halfdir=normalize(lightdir+viewdir);
HdotL=max(0.0,dot(halfdir,t.xyz));
NdotL=max(0.0,dot(lightdir,t.xyz));
HdotL=HdotL*HdotL; HdotL=HdotL*HdotL; HdotL=HdotL*HdotL;
color.xyz=diffuse.xyz*NdotL+specular.xyz*pow(HdotL,specular.w);
color.w=1.0;
/*
// clamp edges
if (length(uv-clamp(uv,0.0,1.0))>0.0)
color.w=0.0;
*/
return color;
}
//////// techniques ////////////
technique displacemap
{
pass p0
{
Zenable = true;
ZWriteEnable = true;
CullMode = CW;
VertexShader = compile vs_1_1 displace_map_vert(
wvpMatrix,viMatrix);
PixelShader = compile ps_2_0 displace_map_frag(
depth*base1.w/tile,
texmap_sampler,dispmap_sampler,dispindxmap_sampler);
}
}
]]>;
float4x4 wMatrix : World ;
float4x4 viMatrix : WorldViewInverse ;
// textures //////////////////////////////
texture texmap : Diffuse
<
string ResourceName = "dm2.jpg";
>;
texture dispmap
<
string ResourceName = "dm2.tga";
>;
texture dispindxmap
<
string ResourceName = "displace_indxmap.tga";
>;
sampler2D texmap_sampler = sampler_state
{
Texture = ;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = None;
};
sampler2D dispmap_sampler = sampler_state
{
Texture = ;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = None;
AddressU = Clamp;
AddressV = Clamp;
};
sampler2D dispindxmap_sampler = sampler_state
{
Texture = ;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = None
;
AddressU = Clamp;
AddressV = Clamp;
};
// User Tweakables ////////////////////////////////
float tile
<
string UIWidget = "slider";
float UIMin = 1;
float UIMax = 32.0;
float UIStep = 1;
string UIName = "tile";
> = 10.0;
float4 constants
<
string UIName = "constants";
> = {32,32,0.03125,0.03125};
float depth
<
string UIName = "depth";
> = 12.0313;
float4 base0
<
string UIName = "base0";
> = {-1,-1,0,0};
float4 base1
<
string UIName = "base1";
> = {1,0,0,2};
float4 base2
<
string UIName = "base2";
> = {0,1,0,2};
float4 diffuse
<
string UIName = "diffuse";
string UIWidget = "Color";
> = {1,1,1,1};
float4 specular
<
string UIName = "specular";
string UIWidget = "Color";
> = {0.75,0.75,0.75,100};
float4 lightpos : Position
<
string Object = "PointLight";
string Space = "World";
> = {-1.0f, 1.0f, -1.5f, 1.0f};
float4 lightcolor
<
string UIWidget = "Color";
> = {1.0f, 1.0f, 1.0f, 1.0f};
// structs ///////////////////////////
struct a2v
{
float4 pos : POSITION;
};
struct v2f {
float4 hpos : POSITION;
float4 opos : TEXCOORD0;
float4 eyepos : TEXCOORD1;
};
// shaders /////////////////////
v2f displace_map_vert(
a2v IN,
uniform float4x4 WorldViewProj,
uniform float4x4 World,
uniform float4x4 ViewInv)
{
v2f OUT;
OUT.hpos=mul(IN.pos,WorldViewProj);
OUT.opos=mul(IN.pos,World);
OUT.eyepos=ViewInv[3];
return OUT;
}
float4 displace_map_frag(
v2f IN,
uniform float depthfactor,
uniform sampler2D texmap,
uniform sampler2D dispmap,
uniform sampler2D dispindxmap) : COLOR
{
float4 t,color;
float3 viewdir,opos,lightdir,halfdir;
float2 uv,uv1,uv2;
float HdotL,NdotL;
// view direction is AB index (uv1)
viewdir=normalize(IN.opos.xyz-IN.eyepos.xyz);
// full computation (exceeds ps_2_0 limits)
// uv1.x=1.0-acos(viewdir.x/sqrt(1.0-viewdir.y*viewdir.y))/3.1415927;
// uv1.y=1.0-acos(viewdir.y)/3.1415927;
// simplified computation
uv1=viewdir.xy*0.5+0.5;
t=tex2D(dispindxmap,uv1);
uv1=t.xy+t.zw*0.005;
// tile position is XY index (uv2)
opos=IN.opos.xyz-base0.xyz;
uv.x=dot(opos,base1.xyz)/base1.w;
uv.y=dot(opos,base2.xyz)/base2.w;
uv2=fmod(uv*tile,1.0);
// compose ABXY index for 4D texture (uv=f(uv1,uv2))
uv=(floor(uv1*constants.xy)+uv2.xy)*constants.zw;
// get pixel normal and depth from displace map
t=tex2D(dispmap,uv);
t.xyz=2.0*t.xyz-1.0;
if (depth<0.01)
t=float4(0.0,0.0,1.0,0.0);
// displace pixel and compute new texture coordinates
opos+=viewdir*t.w*depthfactor;
uv.x=dot(opos,base1.xyz)/base1.w;
uv.y=dot(opos,base2.xyz)/base2.w;
// illuminate for a point light with diffuse and specular
diffuse*=tex2D(texmap,uv*tile);
lightdir=-normalize(lightpos.xyz-opos-base0.xyz);
halfdir=normalize(lightdir+viewdir);
HdotL=max(0.0,dot(halfdir,t.xyz));
NdotL=max(0.0,dot(lightdir,t.xyz));
color.xyz=diffuse.xyz*NdotL+specular.xyz*pow(HdotL,specular.w);
color.w=1.0;
/*
// clamp edges
if (length(uv-clamp(uv,0.0,1.0))>0.0)
color.w=0.0;
*/
return color;
}
// techniques ////////////////////////////////
technique displacemap2
{
pass p0
{
Zenable = true;
ZWriteEnable = true;
CullMode = CW;
VertexShader = compile vs_1_1 displace_map_vert(
wvpMatrix,wMatrix,viMatrix);
PixelShader = compile ps_2_0 displace_map_frag(
depth*base1.w/tile,
texmap_sampler,dispmap_sampler,dispindxmap_sampler);
}
}
]]>