Heightmap interpretation (in Parallax Mapping)

Started by
1 comment, last by ambershee 14 years, 1 month ago
Hello! I've been writing a simple implementation of parallax mapping, that uses a standard diffuse, specular and normal map, combined with a heightmap. I'm getting some odd distortion and my offset is sometimes off. I believe I may be doing something a wee bit wrong when I'm trying to interpret the values of my heightmap, or otherwise using said values incorrectly. I've cut out the lighting functions, they work nicely. (Notably I'm using DirectX and HLSL)

sampler2D Diffuse;
sampler2D Specular;
sampler2D Normal;
sampler2D Height;

struct PS_Input
{
	float2 TexCoord0 : TEXCOORD0;
	float3 WorldPosition : TEXCOORD1;
	float3 ModelNormal : TEXCOORD2;
	float3 ModelTangent : TEXCOORD3;
};

struct PS_Output
{
	float4 Colour : COLOR0;
};

struct Light
{
	float3 Position;
	float4 Colour;
	float Intensity;
};

float4x4 WorldMatrix;

float3 AmbientLightColour;
Light Lights[2];

float3 CameraPosition;
float SpecularPower;

float TextureDepth;

void main (in PS_Input input, out PS_Output output)
{
	float4 TextureDiffuse = tex2D(Diffuse, input.TexCoord0);
	float4 TextureSpecular = tex2D(Specular, input.TexCoord0);
	float4 TextureHeight = tex2D(Height, input.TexCoord0);
	
	float3 ModelNormal = normalize(input.ModelNormal);
	float3 ModelTangent = normalize(input.ModelTangent);
	float3 ModelBiTangent = cross( ModelNormal, ModelTangent );
	
	float3x3 InvTangentMatrix = float3x3(ModelTangent, ModelBiTangent, ModelNormal);
	
	float3 CameraDirection = normalize(CameraPosition - input.WorldPosition);
	
	float4x4 InvWorldMatrix = transpose(WorldMatrix);
	float3 CameraModelDirection = normalize( mul(CameraDirection, InvWorldMatrix));
	
	float3x3 TangentMatrix = transpose(InvTangentMatrix);
	float2 TextureOffsetDirection = mul(CameraModelDirection, TangentMatrix);
	
	float DepthInfo = TextureDepth * TextureHeight - 0.5f;
	
	float2 OffsetTextureCoord = input.TexCoord0 + DepthInfo * TextureOffsetDirection;
	
	float3 TextureNormal = 2.0f * tex2D(Normal, OffsetTextureCoord) - 1.0f;
	
	float3 WorldNormal = normalize( mul( mul( TextureNormal, InvTangentMatrix), WorldMatrix));
	
	float3 DiffuseColour = calcDiffuse(input.WorldPosition, WorldNormal);
	float3 SpecularColour = calcSpecular(input.WorldPosition, WorldNormal, CameraDirection);
	
	float4 TextureParallax = tex2D(Diffuse, OffsetTextureCoord);
	
	output.Colour.rgb =  TextureDiffuse * AmbientLightColour + TextureDiffuse * DiffuseColour * TextureParallax + TextureDiffuse * TextureSpecular * SpecularColour; //Make a colour specular map!
	output.Colour.a = 1.f;
}
Any suggestions would be much appreciated. I find shaders rather tricky to debug as I've only recently started working on them sans a node editor.
Advertisement
Welcome to parallax mapping, enjoy your stay. :)

It's working as intended. More advanced methods of virtual displacement mapping (such as parallax occlusion mapping, relief mapping or variants thereof) were designed explicitly to combat the 'swimming' artifacts you're seeing here. It's unavoidable except through careful tweaking of parameters, and even then you're just minimizing the visibility of the problems, not making them go away.

Re: shader debugging-- have you looked into something like FX Composer? I can imagine it might be useful, and the integrated performance tools can be quite helpful for optimization once you get the tricks working initially.

EDIT: Well, now that I think about it, you might want to rearrange the
float DepthInfo = TextureDepth * TextureHeight - 0.5f;
to read
float DepthInfo = TextureDepth * (TextureHeight - 0.5f);
It's an order of operations thing.
clb: At the end of 2012, the positions of jupiter, saturn, mercury, and deimos are aligned so as to cause a denormalized flush-to-zero bug when computing earth's gravitational force, slinging it to the sun.
Aha! Good catch - I should have spotted that silly slip earlier. It's one thing to translate a paper into notes, then translate notes into code, but if your notes are wrong, well xD

It's looking pretty sharp, so thank you very much. I've only been working with this for a few weeks, and this is probably the first proper shader I've attempted :)

Thanks again,

Luke

This topic is closed to new replies.

Advertisement