ok, i have this relief shader that has been editted here and there by many different people, and now i need some more help to add to it again!
here is a screenshot of it working in DBP:
but as you can see, the trees and (if you look carefully) the grass has some serious smoothing issues that i believe to be caused by the shader because using the SET OBJECT SMOOTHING command does nothing to these objects what so ever (yet works on non-shadered objects)
i've been fiddling around with the shader code a little, but im not experienced enough to really know how to fix the problem... i assume this can be done?
here's the shader:
///Tweakables///
float tile
<
string UIName = "Tile Factor";
//string UIWidget = "slider";
//float UIMin = 1.0;
//float UIStep = 1.0;
//float UIMax = 32.0;
> = 1;
float depth
<
string UIName = "Depth Factor";
string UIWidget = "slider";
float UIMin = 0.0f;
float UIStep = 0.01f;
float UIMax = 0.25f;
> = 0.1;
float3 ambient
<
string UIName = "Ambient";
string UIWidget = "color";
> = {0.2,0.2,0.2};
float3 diffuse
<
string UIName = "Diffuse";
string UIWidget = "color";
> = {1,1,1};
float3 specular
<
string UIName = "Specular";
string UIWidget = "color";
> = {0.9,0.9,0.9};
float shine
<
string UIName = "Shine";
//string UIWidget = "slider";
//float UIMin = 8.0f;
//float UIStep = 8;
//float UIMax = 256.0f;
> = 10.0;
float3 lightpos : POSITION
<
string UIName="Light Position";
> = { -150.0, 200.0, -125.0 };
///Un-tweakables///
float4x4 modelviewproj : WorldViewProjection;
float4x4 modelview : WorldView;
float4x4 modelinv : WorldInverse;
float4x4 view : View;
///Textures///
texture texmap : DIFFUSE
<
string name = "rockwall.jpg";
string TextureType = "2D";
>;
texture reliefmap : NORMAL
<
string name = "rockwall.tga";
string TextureType = "2D";
>;
sampler2D texmap_sampler = sampler_state
{
Texture = <texmap>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
};
sampler2D reliefmap_sampler = sampler_state
{
Texture = <reliefmap>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
};
struct a2v
{
float4 pos : POSITION;
float4 color : COLOR0;
float3 normal : NORMAL;
float2 txcoord : TEXCOORD0;
float3 tangent : TANGENT0;
float3 binormal : BINORMAL0;
};
struct v2f
{
float4 hpos : POSITION;
float4 color : COLOR0;
float2 txcoord : TEXCOORD0;
float3 vpos : TEXCOORD1;
float3 tangent : TEXCOORD2;
float3 binormal : TEXCOORD3;
float3 normal : TEXCOORD4;
float4 lightpos : TEXCOORD5;
};
v2f view_space(a2v IN)
{
v2f OUT;
// vertex position in object space
float4 pos=float4(IN.pos.x,IN.pos.y,IN.pos.z,1.0);
// compute modelview rotation only part
float3x3 modelviewrot;
modelviewrot[0]=modelview[0].xyz;
modelviewrot[1]=modelview[1].xyz;
modelviewrot[2]=modelview[2].xyz;
// vertex position in clip space
OUT.hpos=mul(pos,modelviewproj);
// vertex position in view space (with model transformations)
OUT.vpos=mul(pos,modelview).xyz;
// light position in view space
float4 lp=float4(lightpos.x,lightpos.y,lightpos.z,1);
OUT.lightpos=mul(lp,view);
// tangent space vectors in view space (with model transformations)
OUT.tangent=mul(IN.tangent,modelviewrot);
OUT.binormal=mul(IN.binormal,modelviewrot);
OUT.normal=mul(IN.normal,modelviewrot);
// copy color and texture coordinates
OUT.color=IN.color;
OUT.txcoord=IN.txcoord.xy;
return OUT;
}
float ray_intersect_rm(
in sampler2D reliefmap,
in float2 dp,
in float2 ds)
{
const int linear_search_steps=15;
const int binary_search_steps=5;
float depth_step=1.0/linear_search_steps;
// current size of search window
float size=depth_step;
// current depth position
float depth=0.0;
// best match found (starts with last position 1.0)
float best_depth=1.0;
// search front to back for first point inside object
for( int i=0;i<linear_search_steps-1;i++ )
{
depth+=size;
float4 t=tex2D(reliefmap,dp+ds*depth);
if (best_depth>0.996) // if no depth found yet
if (depth>=t.w)
best_depth=depth; // store best depth
}
depth=best_depth;
// recurse around first point (depth) for closest match
for( int i=0;i<binary_search_steps;i++ )
{
size*=0.5;
float4 t=tex2D(reliefmap,dp+ds*depth);
if (depth>=t.w)
{
best_depth=depth;
depth-=2*size;
}
depth+=size;
}
return best_depth;
}
float4 relief_map(
v2f IN,
uniform sampler2D texmap,
uniform sampler2D reliefmap) : COLOR
{
float4 t,c;
float3 p,v,l,s;
float2 dp,ds,uv;
float d,a;
// ray intersect in view direction
p = IN.vpos;
v = normalize(p);
a = dot(IN.normal,-v);
s = normalize(float3(dot(v,IN.tangent),dot(v,IN.binormal),a));
s *= depth/a;
ds = s.xy;
dp = IN.txcoord*tile;
d = ray_intersect_rm(reliefmap,dp,ds);
// get rm and color texture points
uv=dp+ds*d;
t=tex2D(reliefmap,uv);
c=tex2D(texmap,uv);
// expand normal from normal map in local polygon space
t.xy=t.xy*2.0-1.0;
t.z=sqrt(1.0-dot(t.xy,t.xy));
t.xyz=normalize(t.x*IN.tangent-t.y*IN.binormal+t.z*IN.normal);
// compute light direction
p += v*d*a;
l=normalize(p-IN.lightpos.xyz);
// compute diffuse and specular terms
float att=saturate(dot(-l,IN.normal.xyz));
float diff=saturate(dot(-l,t.xyz));
float spec=saturate(dot(normalize(-l-v),t.xyz));
// compute final color
float4 finalcolor;
finalcolor.xyz=ambient*c+att*(c*diffuse*diff+specular.xyz*pow(spec,shine));
finalcolor.w=c.w;
return finalcolor;
}
technique relief_mapping
{
pass p0
{
//CullMode = CCW;
Zenable = true;
ZWriteEnable = true;
CullMode = None;
//NormalizeNormals = true;
VertexShader = compile vs_1_1 view_space();
PixelShader = compile ps_2_a relief_map(texmap_sampler,reliefmap_sampler);
}
}
[if you're having trouble seeing the smoothing issues, they are best found on the roots of the trees. ew!]