PDA

View Full Version : Bump mapping technique repository



Freelancer
12-22-2003, 04:55 AM
Hi everyone!

The main idea of engine I'm crafting is: create several execution paths for (almost) any hadware. So, I've got several bump mapping paths:

1) NVidia Vertex Program path (works, cool result!).
2) NVidia Register combiners (? but also works).
3) Fixed function (TexEnv, everyone knows... nice result).
4) !!!MISSING!!!SOS!!! ARB vertex program path! can't find any example of bump maps through ARB vp1.0 !

So.... if anyone has the code - please post!
Or - send: kh_dmitry2001@mail.ru

Thanx everyone!

[This message has been edited by Freelancer (edited 12-22-2003).]

Ostsol
12-22-2003, 08:20 AM
A while ago I wrote a little bump mapping demo that used ARB_vertex_program and ARB_fragment_program. . . I lost the source code, but still have the demo itself and its shader programs.



!!ARBvp1.0

PARAM mvp[4] = {state.matrix.mvp};
PARAM light1pos = state.light[1].position;
PARAM light2pos = state.light[2].position;
#PARAM light2pos = {-2.5, 2.5, -2.5, 1.0};
PARAM one = {1.0, 1.0, 1.0, 1.0};
PARAM lightradius = {0.125, 0.125, 0.125, 1.0};

ATTRIB normal = vertex.normal;
ATTRIB binormal = vertex.attrib[9];
ATTRIB tangent = vertex.attrib[10];

TEMP light1vector, light1ts;
TEMP light2vector, light2ts;
TEMP temp;

# Light 1
SUB light1vector, light1pos, vertex.position;

DP3 light1ts.x, light1vector, tangent;
DP3 light1ts.y, light1vector, binormal;
DP3 light1ts.z, light1vector, normal;
MOV light1ts.w, one;

DP3 temp, light1ts, light1ts;
RSQ temp, temp.x;
MUL light1ts, light1ts, temp;

MOV result.texcoord[1], light1ts;
MUL result.texcoord[2], light1vector, lightradius;

# Light 2
SUB light2vector, light2pos, vertex.position;

DP3 light2ts.x, light2vector, tangent;
DP3 light2ts.y, light2vector, binormal;
DP3 light2ts.z, light2vector, normal;
MOV light2ts.w, one;

DP3 temp, light2ts, light2ts;
RSQ temp, temp.x;
MUL light2ts, light2ts, temp;

MOV result.texcoord[3], light2ts;
MUL result.texcoord[4], light2vector, lightradius;

# Output everything else
MOV result.color, vertex.color;

DP4 result.position.x, mvp[0], vertex.position;
DP4 result.position.y, mvp[1], vertex.position;
DP4 result.position.z, mvp[2], vertex.position;
DP4 result.position.w, mvp[3], vertex.position;

MOV result.texcoord[0], vertex.texcoord[0];

END



!!ARBfp1.0

OUTPUT final = result.color;
TEMP base, normal, temp, bump, total;
TEMP light1, atten1;
TEMP light2, atten2;

PARAM light0colour = state.light[0].ambient;
#PARAM light1colour = state.light[1].diffuse;
PARAM light1colour = {0.0, 1.0, 0.0, 1.0};
#PARAM light2colour = state.light[2].diffuse;
PARAM light2colour = {1.0, 0.0, 0.0, 1.0};

TEX base, fragment.texcoord[0], texture[1], 2D;
TEX normal, fragment.texcoord[0], texture[0], 2D;

# remove scale and bias from the normal map
SUB normal, normal, 0.5;
MUL normal, normal, 2.0;

# normalize the normal map
DP3 temp, normal, normal;
RSQ temp, temp.r;
MUL normal, normal, temp;


# normalize the light1 vector
DP3 temp, fragment.texcoord[1], fragment.texcoord[1];
RSQ temp, temp.x;
MUL light1, fragment.texcoord[1], temp;

# N.L
DP3 bump, normal, light1;

# calculate and add attenuation
DP3_SAT atten1, fragment.texcoord[2], fragment.texcoord[2];
SUB atten1, 1.0, atten1;
MUL bump, bump, atten1;

# add colour
MUL total, bump, light1colour;


# normalize the light2 vector
DP3 temp, fragment.texcoord[3], fragment.texcoord[3];
RSQ temp, temp.x;
MUL light2, fragment.texcoord[3], temp;

# N.L
DP3 bump, normal, light2;

# calculate and add attenuation
DP3_SAT atten2, fragment.texcoord[4], fragment.texcoord[4];
SUB atten2, 1.0, atten2;
MUL bump, bump, atten2;

# add colour and add to the total
MAD_SAT total, bump, light2colour, total;

# add ambient lighting
ADD_SAT total, total, light0colour;

MUL_SAT total, base, total;

MOV final, total;

#MOV final, bump;

END

Freelancer
12-24-2003, 03:56 AM
Grand Thanx!

Freelancer
12-24-2003, 04:17 AM
....but.... without fragment programs?
For GeForce1/2/3 ?

Just Vertex_Program + setup?

JanHH
12-25-2003, 06:56 AM
Seems like everyone is posting things about bump mapping at the moment http://www.opengl.org/discussion_boards/ubb/wink.gif.

your paths seem weird to me:

whats the point with 1. and 2.? How can you do bump mapping with vertex programs, but without RC? I think RC and VP are not alternatives, but other parts of the same things, use VP for geometry setup and RC for the dot3 stuff!?


3) Fixed function (TexEnv, everyone knows... nice result).

Do you mean the ARB texture combine mode extension?

My path suggestions would be:

- ARB extensions only
- NV RC
- the ati thing that is equivalent to NV RC (I do not own a radeon)
- fragment prorams (gf fx/radeon and up).

I would do any of them with vp if vp is availabe, otherwise there's a problem anyway (I think) because when not having vp, you cannot use display lists/vbo, and this will slow down everyhing.

Or am I getting something wrong?

The point about your SOS call: I think Vertex Progam are not the right things for bump mapping, they are just a way of doing the geometry transformation (tangent space), the heart of bump mapping is that you need something that can do a dot product for each fragment, and THIS is where the rendering paths should/would be different.

Jan

Ostsol
12-25-2003, 08:37 AM
Yeah, ARB_vertex_program and NV_vertex_program are very close. Also, I think that every card that supports NV_vp also supports ARB_vp (with some limitations, perhaps). As such, the only issue there is what to use for fragment processing. The basic things you have to do are:

1) normalize the light vector,
2) convert the normalmap data from the range [0,1] to [-1,1],
3) take the dot3 product of the normalmap and light vector,
4) and modulate with the material colour or texture.

Attenuation can be done, too, but I'm not all that sure if I did it right in my posted example. . . It looked good at the time, so I kept it. http://www.opengl.org/discussion_boards/ubb/smile.gif Light colour may also be something you want to take into account, but that may be considered extra. The above steps are the basic elements of per-pixel dot3 bumpmapping.

The only difficult part with the fragment processing is in the method and the graphics card's capabilities. If you only have two texture units, for example, you'll need two passes per light using ARB_texture_env_combine (and related extensions) -- one pass if you have more texture units. Using ATI_fragment_shader, ARB_fragment_program, or NV_fragment_program only a single pass is needed, of course. I'm not sure about other NVidia fragment processing extensions, though, since I've never had the oportunity to learn them.

On another note, without vertex programs you can still do bump-mapping, but you must then use immediate mode or standard vertex arrays if you want the object and/or the light to be dynamic (moving). If they're both static, then you can set the appropriate attributes once and then toss the data into whatever static vertex storage method you want (display lists, VBO). Of course, bump mapping is really best and most noticable when the lighting is dynamic.

JanHH
12-25-2003, 10:33 AM
I disagree about the possibility of precomputing everything for static lights, so you can use display lists without having to use VP. Of course you can do so for the diffuse part, but for specular hightlights, you need the half vector, and this is dynamic even with static lights, as the eye position is taken into account, and this of course is dynamic (if not, do not use OpenGL but something like paintshop http://www.opengl.org/discussion_boards/ubb/wink.gif ).

jwatte
12-25-2003, 01:50 PM
You pretty much can't do good specular bump on 2-texture-unit hardware. There just isn't enough math power on the chip; there aren't even dependent reads.

You can do regular specular (using REFLECTION_MAP) in one pass, and bumped diffuse (using object-space normal maps) in one pass. Assuming the lights are infinite. Something like:



Pass 1:
Calculate (ObjNormal DOT LightVector) TIMES DiffuseColor
Pass 2:
Add specular based on REFLECTION_MAP look-up in cube map


I'm not sure you can even get ambient into this situation with regular, plain TexEnv(); you might need a third pass for that (after pass 1).

Freelancer
12-28-2003, 04:57 AM
JanHH - you've posted the thing I wanted, thank you!

But.... again that BUT! http://www.opengl.org/discussion_boards/ubb/smile.gif

Do you (or anyone else) have the vertex programs for lighting (lighting only!).
I think that LIGHTING in OpenGL is a vertex-based thing...

...so the idea is to offload all lighting to the video hardware.

What I need is:

1) direction light
2) point omni light
3) spot light

vertex programs. Diffuse/specular/etc components appreciated....

JanHH
12-28-2003, 05:08 AM
No I do not have any vertex program examples, vp will be one of the next things I'm going to learn. I would suggest with reading the specs of ARB_vertex_program, there are also some examples there, and first try to get the standard geometry transformations done with vp (modelview and projection), so that it looks like before. I am quite sure that once you got that so far and understand how it works, the maths for bump mapping are quite simple (but I am not sure about that, just guessing).

My plan is to rework my terrain engine to do the whole lighting with ARB_texture_env_combine, using one pass for diffuse and one pass for specular (with gloss map). The gloss map has an alpha channel so you later even can add reflections blended by destination alpha (so that it looks like puddles on the street, for example). As the data is inside of display lists, I'm going to use ARB_vertex_program. I am quite sure about getting good results in a two pass process (there is only one light in the scene which is an infinite light, no spot light).

for spoint+point lights I suggest you read ron frazier's papers.

Jan