PDA

View Full Version : cubemap reflection not perspective correct



painterb
11-27-2002, 09:00 AM
From the posts I saw on this forum, I've implemented my own reflection texture-mappping using the GL_TEXTURE_CUBE_MAP_ARB extension. It's working great for me except for one thing: The reflection does not get rendered perspective-correct (regular texture mapping modes are working fine). Is this a limitation of the technique or is there something extra I must do when using a cubemap to render reflections?

I've looked at Nutty's demo and source code where he's doing the same thing, and I see his reflections have the same problem, which leads me to believe it's just a limitation I have to live with. (Thanks Nutty for your demos)

See these images for clarification, which are just simple cubes with 2 tris/face:

Correctly rendered cube with a simple checkerboard pattern http://home.columbus.rr.com/bpainte/cube3.jpg

Incorrectly rendered cube with reflection mapping (nevermind that the reflection does not include the ground in the scene, I'm not dynamically updating the cubemap texture) http://home.columbus.rr.com/bpainte/cube1.jpg

Of course, I'll post code if people feel it will help.

(Edited to add extra info.)
Oh yes, hw is Geforce4 Ti 4200, with 30.72 drivers.

[This message has been edited by painterb (edited 11-27-2002).]

jwatte
11-27-2002, 09:32 AM
That doesn't look like a perspective correction problem; it looks like a cube map image problem. If you use those same images as a sky box, does it look seamless or does it show the same discontinuities at the seams?

painterb
11-27-2002, 10:08 AM
When used as a skybox, the textures look fine together.

Just to be sure we're looking at the same thing, here's one more image ... the flawed areas are highlighted in yellow (it's where the 2 tris of one face meet). This type of distortion doesn't occur on my skybox. http://home.columbus.rr.com/bpainte/cube2.jpg

And, here's a link to Nutty's demo exhibiting the same flaw. (Look for the demo "Dynamic Cubemap Demo") http://romka.demonews.com/opengl/demos/texture_eng.htm

davepermen
11-27-2002, 10:42 AM
tesselate it higher..

you do per vertex generate reflection coords, but per triangle, you will map planar onto the surface.. it looks like you have smooth normals, on wich you reflect at?

at least, its a texcoord problem. nothing else..

bakery2k
11-27-2002, 10:44 AM
How are you computing the texture coordinates to use for the cube mapping? I had this problem once when creating the reflection vectors in a vertex program since I was normalizong them per vertex. Interpolating normalized vectors does not give the correct results.
If you are using REFLECTION_MAP however, it should not be doing this normalisation. Just make sure you have unit normals on your cube.

painterb
11-27-2002, 10:57 AM
Originally posted by davepermen:
tesselate it higher..

I realize this would help. But the problem would still exist, just at a level where it won't be terribly noticable.

And I'm surprised, is this really the only way to solve? Because when applying a texture normally (GL_TEXTURE_2D mode, not CUBE_MAP) say in decal mode, this flaw is not present.

Sorry I left out some useful data ... I am using glTexGen to generate the tex coords:
glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_REFLECTION_M AP_ARB);
glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_REFLECTION_M AP_ARB);
glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_REFLECTION_M AP_ARB);

bakery2k, ok, I will double check to make sure my normals are of unit length.

I admit, I have trouble with the more complex texture-mapping methods, so you guys no doubt are smarter than me, but from what I've read it certainly looks like a perspective-correction issue. I will see if I can put together an executable for you to run.

Thanks all.

ehart
11-27-2002, 11:22 AM
One thing that will help debug this for you is to try outputting those texture coords as colors. This can show you if the coordintes are showing a discontinuity there. I imagine the problem you are having is with the texture matrix.

-Evan

BTW, Go Bucks!

dorbie
11-27-2002, 11:29 AM
Does this help:

glTexGeni(GL_Q,GL_TEXTURE_GEN_MODE,GL_REFLECTION_M AP_ARB);

Just a guess really.

jwatte
11-27-2002, 11:36 AM
Okay, I'm also convinced it's a triangle edge issue now.

I'd bet a donut that Dorbies suggestion is on the right track.

bakery2k
11-27-2002, 11:42 AM
Quote from the OpenGL 1.4 specs:

"Calling TexGen with a coord of Q when pname indicates REFLECTION_MAP generates the error INVALID_ENUM"

That's not it...

painterb
11-27-2002, 11:55 AM
Originally posted by ehart:
BTW, Go Bucks!

http://www.opengl.org/discussion_boards/ubb/smile.gif ... yeah, I about had a heart attack watching that game! Woohoo!

bakery2k's right ... I already tried that and promptly generated an Opengl error.

Well, I'll keep trying and let you know if I find the solution ... Nutty if you're here, I'd be curious if you noticed this with your demo and what you found. Also, I'm still trying to put an exe together.

Humus
11-27-2002, 12:11 PM
This is normal behaviour. The texture coords are linearly interpolated, which isn't the most optimal or most correct way to interpolate reflection vectors.
From the "issues" section in GL_ARB_texture_cube_map:



The spec just linearly interpolates the reflection vectors computed
per-vertex across polygons. Is there a problem interpolating
reflection vectors in this way?

Probably. The better approach would be to interpolate the eye
vector and normal vector over the polygon and perform the reflection
vector computation on a per-fragment basis. Not doing so is likely
to lead to artifacts because angular changes in the normal vector
result in twice as large a change in the reflection vector as normal
vector changes. The effect is likely to be reflections that become
glancing reflections too fast over the surface of the polygon.

Note that this is an issue for REFLECTION_MAP_ARB, but not
NORMAL_MAP_ARB.


[This message has been edited by Humus (edited 11-27-2002).]

davepermen
11-27-2002, 12:15 PM
its the same "bug" we know from environmental mapping.. its a nonlinear generated mapping coord, but you only generate it at the edges and linear interpolate between.
nuttys demo uses a sphere.. http://www.opengl.org/discussion_boards/ubb/biggrin.gif

how to solve it? move to a flatshaded quad. then it _should_ look less ugly (if it is yet flat shaded, i'm sorry.. it really is ugly http://www.opengl.org/discussion_boards/ubb/biggrin.gif)

the only real solution is calculating the reflection per pixel and then look up. possible on a gf3+, radeon8500+..

you can only correctly map something wich is based on a linear equation. GL_NORMAL_ARB (or whats it called again?), normal texture mapping, projective, eye space coord mapping, object space coord mapping, etc.. but reflections are not linear, like envmaps are not linear.

so interpolate the linear components per vertex, and set up texture_shaders/fragment_shader/ARB_fragment_program to take those inputs and generate a perpixelreflection to look up into the cubemap..

thats the only way.

for hw that can't do this: tesselate.. (think of the sphere of nutty.. http://www.opengl.org/discussion_boards/ubb/biggrin.gif)

painterb
11-27-2002, 12:29 PM
Originally posted by davepermen:
for hw that can't do this: tesselate.. (think of the sphere of nutty.. http://www.opengl.org/discussion_boards/ubb/biggrin.gif)

Nutty's demo has two reflecting cubes which orbit the sphere. It is those two cubes which I was referring to having the error. They pass across the scene quickly, but the error is visible (especially if you get the source and slow them down!)

OK, looks like the easy thing for me to do is to go ahead and add polygons, or just forget it. http://www.opengl.org/discussion_boards/ubb/smile.gif

I'll have to mull over what you said (Humus and davepermen) for a bit. Each side of the cube is flatshaded however (I only submit one normal (perp to the face) to render the 2 tris composing each face).

Thanks to all.

Nutty
11-27-2002, 12:36 PM
(Thanks Nutty for your demos)

No problemo.


And, here's a link to Nutty's demo exhibiting the same flaw. (Look for the demo "Dynamic Cubemap Demo") *edit*

Man I wish he would just link to my site, than hosting them directly.. http://www.opengl.org/discussion_boards/ubb/frown.gif


Nutty if you're here, I'd be curious if you noticed this with your demo and what you found. Also, I'm still trying to put an exe together.

Yeah, Humus and Dave seem to be right. You can either tesselate the faces, which doesn't remove the problem, just makes it alot less visible, or calculate the reflection vector correctly per fragment.

I never noticed it before, cos I always use stuff with pretty good tesselation.

Nutty

Nutty
11-27-2002, 12:37 PM
Nutty's demo has two reflecting cubes which orbit the sphere. It is those two cubes which I was referring to having the error. They pass across the scene quickly, but the error is visible (especially if you get the source and slow them down!)

The cube are just sphere-mapped http://www.opengl.org/discussion_boards/ubb/biggrin.gif

Nutty

Dakeyras
11-27-2002, 04:06 PM
I may be wrong about this, but if I'm not mistaken, while your normals should be normalized, your eye vector ( ie. texcoords ) should not. Leave them at vertex-to-eye length.

It works for me when I'm using the dot_product_reflect_cube_map_eye_from_qs texture shader. I had the same artifact when the eye vectors were normalized. It might not be the case for the non-texture-shader version though.

Edit: fixed UBB code

[This message has been edited by Dakeyras (edited 11-27-2002).]

rgpc
11-27-2002, 05:53 PM
Originally posted by Nutty:
You can either tesselate the faces, which doesn't remove the problem, just makes it alot less visible, or calculate the reflection vector correctly per fragment.


What about a normal map? Would that work?

vincoof
11-28-2002, 02:02 AM
painterb: you can't do anything about the "perspective-correction-like" problem because OpenGL does work linearly. A possible solution would be to work with Q coordinate, but in that case I'm not even sure the Q coordinate would be interpolated either. I'm afraid the only solution is tesselation again and again...

rgpc: of course you can, since normal maps lead to per-fragment computations. But not all hardware can perform it today.

knackered
11-28-2002, 05:38 AM
No, this is not a fundamental problem with cube mapping. The reflection vector is interpolated, but this reflection vector is referencing a spherical lookup table, essentially, so you shouldn't be getting these artifacts.
The only thing I would ask is will you please draw your normal vectors, and print out another screenshot for us....I'll bet your cube has 8 shared vertices, and therefore 8 shared normals - this may explain why it looks messed up, because with a cube you should duplicate the shared vertices because the normals should be drastically different for each face sharing the vertex.
BTW, make sure you load the inverse upperleft 3x3 of the modelview matrix into the texture matrix before rendering.

[This message has been edited by knackered (edited 11-28-2002).]

dorbie
11-28-2002, 06:25 AM
The normals are not shared, if they were there would be no discontinuity in coordinates on the leading edge.

painterb
11-30-2002, 03:47 PM
OK ... after a delay (for the Thanksgiving holiday here in the US) ... I've got a demo prepared to better show off the problem.

Dorbie is correct, the normals are not shared. And I'm pretty sure I do properly load the texture matrix with the 3x3 of the inverse modelview.

Feel free to see the problem yourself by downloading an *.exe at http://home.columbus.rr.com/bpainte
There are two versions to choose, for hi-res (2.4 MB) and lo-res (1.0 MB) textures.

The executable should run, but I honestly don't test Release builds all that often. Let me know if there are problems obviously. The *.exe is large, but it is due mostly to the GUI library I use (wxWindows). I'll work on a pure Win32 demo probably too.

Thanks for looking.
--Brett

tellaman
01-13-2003, 09:42 PM
i guess this is the same problem you get when trying to draw a textured trapezoid
and i guess it's due to linear interpolation of tex coords
and i guess there's no solution to that :>

Humus
01-13-2003, 11:57 PM
Drawing a textured trapezoid and getting nice results is quite easy actually, you just need to properly set the q coord. http://www.r3.nu/~cass/qcoord/

For the cubemap prob, you can always use higher tesselation, or you can just do the math in a fragment program instead.

tellaman
01-14-2003, 12:07 AM
talking about fragment progs, does anybody know when arb frag progs will be implemented on nvidia boards? should we wait for geforce fx or will they be emulated with some sort of sw driver?

Joel
01-14-2003, 12:20 AM
Originally posted by tellaman:
talking about fragment progs, does anybody know when arb frag progs will be implemented on nvidia boards? should we wait for geforce fx or will they be emulated with some sort of sw driver?

ARB_FRAGMENT_PROGRAM will work on hardware on GeforceFX
There is an util at the nvidia site that allows to emulate the functionnalities of the FX
It is damn slow though...

tellaman
01-14-2003, 12:44 AM
but how can i get this emulation to work? i mean i can only see ati extensions in the latest version of mesa glext.h (GL_ATI_fragment_shader instead of some sort of GL_ARB_fragment_shader)
is it me i'm using an outdated header file?

Joel
01-14-2003, 02:18 AM
Originally posted by tellaman:
but how can i get this emulation to work? i mean i can only see ati extensions in the latest version of mesa glext.h (GL_ATI_fragment_shader instead of some sort of GL_ARB_fragment_shader)
is it me i'm using an outdated header file?

ARB_f_p is not part of opengl1.4 so i doubt mesa has integrated it. (easy to check on their site if it does but i'm getting lasy http://www.opengl.org/discussion_boards/ubb/smile.gif)
The emulation has nothing to do with the header. It just allows you to use the extensions of the FX instead of reporting that the extension is not supported.
In fact the emulation is in the drivers (since 40.41 i think) and this app is just an easy way to toggle the abilites of the FX.
If you want to program these effects, there you will need to get these extensions.
As i don't use glext.h i can't tell you, but i'm pretty sure there might be one somewhere that defines the entries of arb_f_p