I am trying to create a normal map from a height map in HLSL. I followed this https://mcmap.net/q/21936/-generating-a-normal-map-from-a-height-map which is for GLSL. Here is how I translated GLSL to HLSL:
GLSL:
uniform sampler2D unit_wave
noperspective in vec2 tex_coord;
const vec2 size = vec2(2.0,0.0);
const ivec3 off = ivec3(-1,0,1);
vec4 wave = texture(unit_wave, tex_coord);
float s11 = wave.x;
float s01 = textureOffset(unit_wave, tex_coord, off.xy).x;
float s21 = textureOffset(unit_wave, tex_coord, off.zy).x;
float s10 = textureOffset(unit_wave, tex_coord, off.yx).x;
float s12 = textureOffset(unit_wave, tex_coord, off.yz).x;
vec3 va = normalize(vec3(size.xy,s21-s01));
vec3 vb = normalize(vec3(size.yx,s12-s10));
vec4 bump = vec4( cross(va,vb), s11 );
HLSL:
sampler2D image : register(s0);
noperspective float2 TEXCOORD;
static const float2 size = (2.0,0.0);
static const int3 off = (-1,0,1);
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 color = tex2D(image, uv);
float s11 = color.x;
float s01 = tex2D(image, uv + off.xy).x;
float s21 = tex2D(image, uv + off.zy).x;
float s10 = tex2D(image, uv + off.yx).x;
float s12 = tex2D(image, uv + off.yz).x;
float3 va = normalize((size.xy,s21-s01));
float3 vb = normalize((size.yx,s12-s10));
float4 bump = (cross(va,vb), s11);
return bump;
}
The output is a black and white image, with the darker pixels being more transparent (since the alpha is the height).
How can I generate a normal map like this http://www.filterforge.com/filters/3051-normal.jpg from a height map?
Edit
I followed the megadan's suggestions , and I also had some synthax errors that I fixed. Here is the working HLSL code:
float Width : register(C0);
float Height : register(C1);
sampler2D image : register(s0);
noperspective float2 TEXCOORD;
static const float2 size = {2.0,0.0};
static const float3 off = {-1.0,0.0,1.0};
static const float2 nTex = {Width, Height};
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 color = tex2D(image, uv.xy);
float2 offxy = {off.x/nTex.x , off.y/nTex.y};
float2 offzy = {off.z/nTex.x , off.y/nTex.y};
float2 offyx = {off.y/nTex.x , off.x/nTex.y};
float2 offyz = {off.y/nTex.x , off.z/nTex.y};
float s11 = color.x;
float s01 = tex2D(image, uv.xy + offxy).x;
float s21 = tex2D(image, uv.xy + offzy).x;
float s10 = tex2D(image, uv.xy + offyx).x;
float s12 = tex2D(image, uv.xy + offyz).x;
float3 va = {size.x, size.y, s21-s01};
float3 vb = {size.y, size.x, s12-s10};
va = normalize(va);
vb = normalize(vb);
float4 bump = {(cross(va,vb)) / 2 + 0.5, 1.0};
return bump;
}
I read that using GetDimensions to automatically get the width and height of the texture is supported on Direct3D 10.1 or higher, so the width and height of the texture must be passed into the shader since I need it to be compatible with Direct3D 9 as well.