Possible to reflect specular highlights?

I am trying to set up reflective planar surfaces in my scene via the standard 2-pass stencil buffer technique and am having problems figuring out how one would set things up to get correct specular highlights in the reflection.

It would seem to me that during the first pass (to draw the reflected objects) no matter if you leave the eyepoint and reflect the objects and lights, or if you leave the objects and lights and reflect the eyepoint, that you are going to get an incorrect specular highlight (note, your diffuse lighting will look fine in either case).

I have checked various sources (eg Tim Hall’s and Mark Kilgard’s newsgroup posts) but they never mention specular highlights specifically. Also, none of the code examples I can find ever use specular lighting.

Can it not be done without using vertex/fragment shaders?? Or am I missing something?

You need to reflect the light sources that illuminate the reflected scene when rendering that scene.

The highlights will not match the original scene exactly because of the different viewpoint, but this will be a correct rendering.

Originally posted by PickleWorld:
…during the first pass (to draw the reflected objects) no matter if you leave the eyepoint and reflect the objects and lights, or if you leave the objects and lights and reflect the eyepoint, that you are going to get an incorrect specular highlight
I fail to see how specular highlights can be wrong if you mirror objects and lights properly ?
Anyw screenshots or details about your so called incorrect speculars ?

I do not have any screen shots, I have just been thinking about it in my head (and drawing little 2D diagrams). Basically I want to know if it can be done before committing to any implementation (as I want to know if I will need vertex/fragment shaders to do my own lighting calculations).

Let me break down what I am thinking, basically you have two options to render a planar reflection…

Option 1) First pass: you can invert the objects and lights around the X-Z plane (or whichever plane) and render the reflection from the regular eyepoint. Second Pass: You render the scene normally. I have no doubt this gives perfectly reflected objects and diffuse lighting.

Option 2) First pass: you can invert the eyepoint around the X-Z plane and render the reflection from this viewpoint. Second Pass: you then return the eye back and render the scene normally. Again, this will give perfectly reflected objects and diffuse lighting.

However, it is the specular highlights I am worried about. Consider the following scene:

We have a light directly above a sphere which sits just above a mirror (on the X-Z plane). Our viewpoint is back and above the sphere looking down on it at a 45 degree angle. In the reflection you should not see any specular highlight as the light is directly above the sphere (but you will see a specular highlight on the sphere itself)

Now consider an image rendered with the first option above. During the first pass we keep our eyepoint fixed above and back looking down at a 45 degree angle and we then add an inverted sphere below the mirror and a light directly below it. When OpenGl renders this, will you not get an incorrect specular highlight (or at least part of one) on the side of the reflected sphere?

Then, is the same not conversely true for option 2 except we are moving the eyepoint instead (all the same angles, just objects in different spots).

While I freely admit I could be wrong, my thinking is that in either case (option 1 or 2) you are changing the angle of incidence for the specular lighting calculation. In option 1 you move the light but not the eye, in option 2 you move the eye but not the light (note, diffuse lighting will look fine as this angle is irrelevant).

Or like I said, am I wrong? Maybe my drawings are just not doing the angles justice. It could very well be that while the angle does change that due to laws of reflections (ie physics) that no specular highlight will appear unless it should be there.

I am just looking for a “yes/no, can it be done” type answer and was hoping someone that had implemented it would be able to tell me.

Option 1 and option 2 are mathematically equivalent. Furthermore, in OpenGL they’re also equivalent in code since the view matrix and model matrix are concatenated into the modelview matrix.

You don’t need any custom shaders, if you just reflect the modelview matrix in your reflection plane everything will just work.

/A.B.

For the positions of specular highlights to be correct, you’ll have to preserve the relationship between the eye vector and the rest of the scene.
With option #1, that would mean reflecting the eye vector too, along with the objects and lights in the scene (I’m not talking about the viewpoint, which should of course remain in the original position if you want to see the scene reflected; I’m only talking about the eye vector used in specular calculations).
With option #2, where you reflect the viewpoint and leave the rest of the scene untouched, you should have an eye vector that points to the original viewpoint, not the reflected one.
AFAIK, this means that you’ll be forced to use shaders, because I don’t think that the fixed function pipeline allows you to specify an eye vector to be used in specular lighting that is different from the one pointing to the viewpoint.
Luca

LRoss: Thats exactly what I was thinking.

Brinck: I know they are mathematically equivalent, my point was that I don’t think either works for specular highlights (note, you do get a reflected image with correct diffuse lighting).

Think of another scene with just a unit sphere at the origin and a mirror lying on the XZ plane. When you draw your reflected and regular scenes you are really just drawing a sphere in the same location twice (if you clip correctly you will actually draw 1/2 each time).

However, when you light the sphere during the reflected pass you will have moved either the eye or the light (but not both) and thus you will get a different specular highlight.

I think you must be getting the angles wrong in your diagrams…either method should give you correct results.

Think of it this way:
You have a scene. It is lit correctly.

Now put a wall with a window between you and the scene.Original scene is still lit correctly.

Now put a inverted copy of the scene on your side of the wall. The original scene hasn’t changed, so must still be lit correctly, right?

If we turn the window into a mirror, then reflection method 1 will draw the exact same scene for the reflection as we had originally, so it should be lit the same way. It was lit correctly before, so it must still be correct, right? If not, what would you expect to change if you removed the mirror again?

In your example, you should have some specular highlight on the reflected sphere, since in the reflection the light is below the sphere, not behind it.

edit:
above is referring to the first example with sphere abvove mirror.
In the second example with mirror bisecting sphere, you do get a different highlight in each pass, which is correct…if they were in the same place, the sphere would look the same with or without the mirror, which is obviously wrong if the light isn’t on the plane of the mirror.

3B you have a chicken or the Egg problem going there. If you assume that the reflection is lit correctly when you start, then of course it will be lit correctly when you finish. You have to start with the non-reflected scene.

Back to my unit sphere at the origin, consider…

           p1 (eye and light)
 ***   
*****SC       (normal scene)

–*********SI---- (plane)


*****SR       (reflected scene)
 ***   
           p2 (reflected light)

If we take p1 as our eye location and if we assume we have a single light also located at p1 then on our non-reflected sphere we will get a specular highlight around SC (correct).

So in our reflected scene we want a reflected specular highlight at SR to match. However when we reflect the light around the plane to p2 and then do a standard openGL lighting calculation with the eyepoint still at p1 will we not get an incorrect specular highlight at SI??

In order to produce the correct specular hightlight at SR would we not need to move both the eye and the light to P2 WITHOUT moving the viewpoint?

Hmm, it took all the leading whitespace out of my post. Gonna try the CODE UBB tag.

                p1 (eye and light)
     *** 
    *****SC (normal scene)
   *******
--*********SI---- (plane)
   *******
    *****SR (reflected scene)
     *** 
                p2 (reflected light)

My point was that you get the same results whether the geometry came from a reflection or from independent geometry, and if it’s correct for independent geometry, its correct for the reflection case as well.

SI is the correct place for the highlight, even if its not really obvious…though for complete correctness, there should be a highlight on the original sphere at SI as well, from the reflected light. There isn’t a highlight at SR, since you wouldn’t be able to see it from the point of reflection. Draw out the lines (from eye to mirror, mirror to object, object to light) and it should be obvious that the mirror to object vector wouldn’t give you much of a highlight.

Try it in real life, put a hemisphere on a mirror and move it around and see where the highlights go (or a half cylinder might be easier to get, chop a can in half or whatever).

>> I am just looking for a “yes/no, can it be done” type answer

YES it will work both ways you described.

There isn’t a highlight at SR, since you wouldn’t be able to see it from the point of reflection.
So move the light to where you would be able to see it…

SI is the correct place for the highlight, even if its not really obvious…though for complete correctness, there should be a highlight on the original sphere at SI as well, from the reflected light

Correct, SI would be a specular highlight caused by reflected light rays but while physically correct I am not looking for them in my scene. If you start adding those then, like you said, you have to render both scenes with both lights and things get way more complicated (because you only have 8 lights to work with in OpenGL and I need to be able to render scenes with more than 4 lights). So for my purposes, SI is an incorrect specular highlight.