PDA

View Full Version : How to use a height map

ei05tbe
08-18-2010, 04:25 AM
I got the normal mapping working. I wonder how to use a normal map. Not in code but in words. I guess you read the values from the texture like when are doing normal mapping. When you got the rgb value what do you do then? I guess you normalize it like the normal?

(normalize(texture2D(normalMap, gl_TexCoord[0].st).xyz * 2.0 - 1.0));

When you got you vector what do you do then. I guess you move the vertex position but in what direction? Just the direction of the vector, or do any other calculations have to be done?

nickels
08-18-2010, 07:25 AM
I don't entirely understand your question, but maybe:

1) Read the heightmap value (probably a grayscale value).
2) Scale the heightmap to [-1,1] : h = 2*h - 1.0;
3) Scale by some real world amount h = wscale*h;
4) Apply a perturbation to the vertex in the vertical direction:
vec4 v = vertex + vec4(0.0, 1.0, 0.0)*h;

Or, conceivably you could deform in the normal direction:
vec4 v = vertex + normal*h;
but probably not in the case of a 'height' map.

Not sure if that was your question, but cheers!

Aleksandar
08-18-2010, 10:58 AM
When you got you vector what do you do then. I guess you move the vertex position but in what direction? Just the direction of the vector, or do any other calculations have to be done?
Normal mapping has nothing in common with vertex movements. You have probably misused the term. A normal map enables more detailed appearance of the low detailed models by using normals from the high detailed one.

So, how to use your normal map? In the fragment shader, instead of reading interpolated value of the normal passed from the vertex shader, or calculate it by some means, you should read the value from the texture that represents normals. Very simple, very fast, but also very effective trick to display your models as very high detailed ones.

ei05tbe
08-18-2010, 11:41 AM
Thanks! You understood my question.

ei05tbe
08-18-2010, 11:47 AM
Thanks. but I think I got the normal mapping working.
http://forumbilder.se/images/c38201084417P3f0b.jpg (http://forumbilder.se)
I have a height map texture that I am currently not using. I wont to use that for bumb mapping but don't know how to do it.
Thank you all!

nickels
08-18-2010, 11:49 AM
Ah, that clarifies things.

You map the rgb values to perturbations in the normal from the geometry normal.
Red = perturbation in tangent direction
Green = perturbation in bitangent direction
Blue = regular geometry normal direction

So, for instance, forgetting tangent, bitangent, if the rgb value is all blue you get back your regular geometry normal.

So what are the tangent and bitangent? Two vectors that span the tangent plane to your model at the point you are shading (hence orthogonal to the normal).
You choose these two vectors so that tangent = direction in x,y,z that a change in u texture spaces gives, bitangent same, but for v. The formulas are out there...
in the end:

newNormal = r*tangent + g*bitangent + b*geomNormal.
newNormal.normalize(); // interpolation can mess this up

nickels
08-18-2010, 11:52 AM
Thanks. but I think I got the normal mapping working.
I have a height map texture that I am currently not using. I wont to use that for bumb mapping but don't know how to do it.
Thank you all!

Ahh, the plot thickens!!

Easiest way to convert a height map to a normal map is to use the gimp nvidia normal map filter:

ei05tbe
08-18-2010, 12:30 PM
Hehehe, I don't know if you understand what I wont do do? Let us forget about normal mapping(I guess normal mapping and bump mapping can be combined in the same shader)? :)
I tried this code but nothing happens except for the normalmapping :)

1 #extension GL_ARB_draw_buffers : enable
2
3 varying vec3 tangent;
4 varying vec3 position;
5 varying vec3 normal;
6 uniform sampler2D tex1;
7 uniform sampler2D normalMap;
8 uniform sampler2D bumpMap;
9
10 void main(void) {
11
12 vec3 binormal = cross(normal,tangent);
13 mat3 tbn = mat3(tangent,binormal,normal);
14
15 //Move thr normal from the texture to world coordinates.
16 vec3 worldSpaceNormal = tbn * (normalize(texture2D(normalMap, gl_TexCoord[0].st).xyz * 2.0 - 1.0));
17
18 vec4 height = (normalize(texture2D(bumpMap, gl_TexCoord[0].st).xyz * 2.0 - 1.0),0.0);
19 height *= 500.0;
20 vec4 newPosition = vec4(position.xyz,0.0) + vec4(0.0,1.0,0.0,0.0)* height;
21
22 gl_FragData[0] = vec4(newPosition.xyz, 0.0);
23 gl_FragData[1] = vec4(normalize(worldSpaceNormal),0.0);
24 gl_FragData[2] = texture2D(tex1, gl_TexCoord[0].st);
25 }

So what do do whit the bumpMap? I already have it and don't have to create it. Thank you for your time.

Edit: The scaling with 500 was just to try if anything works.:)

nickels
08-18-2010, 01:00 PM
The plot gets even thicker yet :) !

Typically you would apply the displacment of the height map in the vertex shader. That way when the triangles are rasterized you would see the effect.

But a high res displacement texture won't do much for you with a low res mesh.

I think what you might be after is parallax mapping, which produces height effects at the fragment level: Parallax mapping (http://en.wikipedia.org/wiki/Parallax_mapping)
Haven't implemented it myself, but it seems like an ultra cool effect!