Normal map from height map
NickName:Deniz Cetinalp Ask DateTime:2014-09-26T02:24:59

Normal map from height map

I am trying to create a normal map from a height map in HLSL. I followed this https://stackoverflow.com/a/5284527/451136 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.

Copyright Notice:Content Author:「Deniz Cetinalp」,Reproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/26045527/normal-map-from-height-map

More about “Normal map from height map” related questions

Normal map from height map artifact

I'm baking normal map on the fragment shader from a height map. The height map looks great and looks smooth. However, when I generate the normal map I get very weird result. Here are two rendered ...

Show Detail

How do I create an Object-Space normal map from a height map?

I'm able to convert my existing height-map into a normal map by sampling the surrounding pixels, like in this question Generating a normal map from a height map? except I'm doing it on CPU. I have a

Show Detail

Generating a normal map from a height map in compute shader?

The problem is that when I tried converting height map to normal map. The results are wrong. For some reason there is 3 light sources that is emitting from top (green), right (red), and left (blue)...

Show Detail

Normal map from height map

I am trying to create a normal map from a height map in HLSL. I followed this https://stackoverflow.com/a/5284527/451136 which is for GLSL. Here is how I translated GLSL to HLSL: GLSL: uniform

Show Detail

What is the purpose of a height map when you already have a normal map?

In 3D graphics, many textures have normal- and height maps to create an illusion of 3D features on a flat surface. Looking at the implementation of height maps, I see that it basically just affects...

Show Detail

Generating a normal map from a height map?

I'm working on procedurally generating patches of dirt using randomized fractals for a video game. I've already generated a height map using the midpoint displacement algorithm and saved it to a te...

Show Detail

convert a normal map to height map with imagemagick: how to recreate/integrate following algorithm

I'm trying to convert a tangent space normal map to a height/displacement map. For sure this will be not 100% accurate speaking in terms of "exact height" for each pixel. But the relative height from

Show Detail

OpenGL: Which shaders for normal map (bump map)?

I could not find a way to generate a normal/bump map in PyOpenGL. Specifically I want a map which I can read with glReadPixels(). I do not know how to get a map of the form: (width, height, normal...

Show Detail

which coordinate system the normal vector calculated from height map in?

I have read a lot of material about heightmap and normal map, and have many questions: We can generate a normal map from heightmap: If we have in the S and T direction: S(i,j)= <1,0,aH(i+1,j)...

Show Detail

Normal map generation - shaders and FBO

I want to generate a normal map from a heightmap. I know it's a pretty 'overasked question', but I haven't found any good topics about this. The normal map should be about 6-8x larger than the orig...

Show Detail