PDA

View Full Version : The w coordinate

HalcyonBlaze
02-04-2003, 10:02 PM
Hey everyone,

I do not understand what other uses the w coordinate has other than scaling and providing an easy way for the programmer to represent points and vectors. I saw the NVIDIA demo to teach it, but it seems like it is just scaling the triangle around. In 2D space, the w coordinate seems to be a z coordinate. But it only seems like a scaling value in 3D space.

- Halcyon

cass
02-04-2003, 10:41 PM
Since I wrote that demo, I guess I could field questions on it. http://www.opengl.org/discussion_boards/ubb/smile.gif

At it's simplest, you can think of w as an easy way to scale coordinates. This does make for a convenient representation of points at infinity -- just set w=0.

But what about when w is negative? Consider when you have the triangle on the screen and you negate every component of, say the red vertex. So

Before: r = (rx, ry, rz, rw)
After: r = (-rx, -ry, -rz, -rw)

(You can do this by hitting the 'r' key when the demo first comes up.)

If you think of w as simply a scale factor, then why is the triangle it renders different?

If you look at the 2DH view (by hitting the 'h' key) you will see why the triangle is different. If the -w portions of the triangle were rendered (hardware generally only renders the +w portions) you would see the triangle go off to infinity on one side of the screen and return from infinity back to the red vertex on the other side of the screen.

This is a helpful visualization of what Blinn calls the Moebius space.

There's an interesting optimization of shadow volume rendering that you can do with these "external" triangles. A triangle is called external, if one or more of its vertices have w<0.

Anyone want to guess what the optimization for using external triangles in shadow volume rendering is? http://www.opengl.org/discussion_boards/ubb/smile.gif

Cass

Zeno
02-04-2003, 11:21 PM
Anyone want to guess what the optimization for using external triangles in shadow volume rendering is?

I'll take a stab at it, but you have to promise not to pick on me too bad if I'm wrong http://www.opengl.org/discussion_boards/ubb/wink.gif. If you had an object that you knew was going to cast a shadow over the majority of your on-screen scene, you could flip the 'w' coordinate of any vertices that would normally be extruded away from the light and make an inverse shadow volume. This inverse shadow volume would cover fewer pixels than the regular volume and save you some fill. You'd have to adjust the stencil testing a bit, but otherwise it should work as usual.

Is that close?

-- Zeno

pkaler
02-04-2003, 11:36 PM
Originally posted by cass:

This is a helpful visualization of what Blinn calls the Moebius space.

My projective geometry is not as good as I'd like it to be. Does anyone have any good references (book, website, papers)? I guess a book that assumes first year calculus and linear algebra would probably be the best.

Quick search of library catologue:
Modern projective geometry / by Claude-Alain Faure and Alfred Frölicher. Kluwer Academic Publishers, 2000

Affine and projective geometry / M.K. Bennett. Published New York : Wiley & Sons, c1995.

knackered
02-05-2003, 01:26 AM
Originally posted by Zeno:
I'll take a stab at it, but you have to promise not to pick on me too bad if I'm wrong http://www.opengl.org/discussion_boards/ubb/wink.gif. If you had an object that you knew was going to cast a shadow over the majority of your on-screen scene, you could flip the 'w' coordinate of any vertices that would normally be extruded away from the light and make an inverse shadow volume. This inverse shadow volume would cover fewer pixels than the regular volume and save you some fill. You'd have to adjust the stencil testing a bit, but otherwise it should work as usual.

Is that close?

-- Zeno

I don't get it. What are you talking about?

Jan
02-05-2003, 02:17 AM
Just a guess.
Does it have to with "infinite shadow volumes" ? By setting w = 0 one wouldn´t have to scale the vertices "by hand", and could therefore save some calculations ?

Jan.

boyd
02-05-2003, 02:29 AM
Another guess (for infinite shadow volumes):
Instead of extruding to infinity one might extrude to the (point) light source visiting infinity on the way? This would make it
easier to close the shadow volume.

-boyd

Tom Nuydens
02-05-2003, 02:50 AM
It allows you to draw your shadow volumes as triangles instead of quads. As boyd suggested, you can "extrude" towards the light instead of towards infinity, and because you "go around past infinity", the results will still look the same.

For simplicity's sake, I'll assume that all W coordinates are normally 1. To extrude an edge AB towards infinity, you would normally render this quad:

glVertex4f(Bx, By, Bz, 1);
glVertex4f(Ax, Ay, Az, 1);
glVertex4f(Ax-Lx, Ay-Ly, Az-Lz, 0);
glVertex4f(Bx-Lx, By-Ly, Bz-Lz, 0);

You can use this triangle instead:

glVertex4f(Bx, By, Bz, 1);
glVertex4f(Ax, Ay, Az, 1);
glVertex4f(-Lx, -Ly, -Lz, -1);

I don't know how much this would save you out there in the real world, but it's definitely a Cunning Trick.

-- Tom

knackered
02-05-2003, 04:07 AM
Ahh! That is a very nice trick.
So, do I recall it being mentioned that most drivers ignore 'external' triangles? Does that mean they ignore triangles containing verts with a negative W?
Basically, is this 'trick' portable to other chipsets/drivers? Is it in the gl spec to deal with them correctly?

PH
02-05-2003, 04:41 AM
This is very interesting. It seems to work on the 9700. If I remember correctly, a line with differing signs for its endpoints ( wc clip coordinate ), would require performing two clipping operations. According to the GL spec, only the wc > 0 is required to be generated ( for this case with *differing* signs ), so is it correct that it might not work ?

Tom Nuydens
02-05-2003, 05:09 AM
Well, here's the relevant bit from the spec:

Section 2.11: "Clipping" (page 43):
A line segment or polygon whose vertices have Wc values of differing signs
may generate multiple connected components after clipping. GL implementations
are not required to handle this situation. That is, only the portion of the primitive
that lies in the region of Wc > 0 need be produced by clipping.

It seems that implementations are allowed to discard the Wc < 0 part, but not required to do so. If they generate both parts, of course, the trick will not work.

I don't know if any such implementations exist, though. I've tested it on different GeForces and on the GDI Generic renderer, all of which work fine. It didn't work on Parhelia, but not because of different clipping behaviour, by the looks of it.

-- Tom

castano
02-05-2003, 05:27 AM
I belive that current hardware perform rasterization in homogeneous coordinates, so rasterization of external triangles should be handled correctly.

cass
02-05-2003, 07:00 AM
Well done! One gold star for boyd (for having the right idea), and two for Tom (for understanding and clarifying details)! http://www.opengl.org/discussion_boards/ubb/smile.gif

As was pointed out, it is not illegal for an OpenGL implementation to rasterize both parts of an external triangle, which would be problematic. In reality, I don't know of any implementations that actually rasterize wc<0. They're required to rasterize wc>0 though.

But wait! There are more gold stars to give out. http://www.opengl.org/discussion_boards/ubb/smile.gif Round 2 questions:

When can't you use this technique? Why?

Thanks-
Cass

PH
02-05-2003, 07:09 AM
I want a gold star too http://www.opengl.org/discussion_boards/ubb/smile.gif. I'll have a shot, you can't use it with directional lights. Why ? All points would project to a single point and therefor not rendered...

PH
02-05-2003, 07:10 AM
I think... http://www.opengl.org/discussion_boards/ubb/smile.gif

Edit: That should have been "all triangles project to a single point"

[This message has been edited by PH (edited 02-05-2003).]

castano
02-05-2003, 07:12 AM
Do the shadow volume caps match correctly with the edges of the external triangles? In theory they should, but since the computations are quite different maybe they do not match correctly producings seams (as with the t-juncs).

Tom Nuydens
02-05-2003, 07:23 AM
An obvious answer would be "when you're using finite shadow volumes", but I think PH's answer might be closer to what you had in mind http://www.opengl.org/discussion_boards/ubb/smile.gif

Castano: as far as I can tell from my (admittedly rather simple) test app, the two approaches lead to 100% identical output.

-- Tom

castano
02-05-2003, 07:23 AM
PH, directional lights would work fine. It's just the previous method. The w component of the directional light is 0, so you only negate the light direction, and in fact that's what you usually do with Cass and Kilgard's method.

castano
02-05-2003, 07:29 AM
Well Tom, I cannot test it right now. I've an exam tomorrow morning and should be studying instead playing with homogeneous coordinates :-P

So, I was just guessing. I though about t-juncs, because when you are extruding a cap triangle with w=0 you place it on infinity, and when you use an external triangle, you have an edge that goes through infinity and commes back to the opposite vertex. So, you really have a t-junc. However, I don't know if that produces artifacts or not...

cass
02-05-2003, 07:39 AM
You guys are sniffing in the right direction, but nobody's nailed it with authority yet.

Gorg
02-05-2003, 07:56 AM
Ok, this might show that I don't get it http://www.opengl.org/discussion_boards/ubb/wink.gif

If the eye is inside the shadow volume, would that mean the the rendered volume would be behind you and hence not shadow anything?

PH
02-05-2003, 08:04 AM
Using w = -1 represent a fixed point that would project to the same point as w = 1 but directional lights have no position, only direction. So you wouldn't be able to specify a directional light in the first place. Is this correct ?

Edit: That would mean that the vertices that are to be projected ( silhouette ) cannot be specified for directional lights, as they are specified as directions.

[This message has been edited by PH (edited 02-05-2003).]

castano
02-05-2003, 08:19 AM
PH, you don't just set w=-1 instead of that you negate all the components. Take the demo, set blue vertex w coordinate to 0 and press 'b'.

PH
02-05-2003, 08:22 AM
What demo ? Blue vertex ?

HalcyonBlaze
02-05-2003, 08:29 AM
Look at the homepage of this site. In the news there is a title about understanding the w coordinate. Clicking on it takes you to the NVIDIA site where you can download the demo.

- Halcyon

Tom Nuydens
02-05-2003, 08:30 AM
PH, I simplified the code snippets above by assuming that all W's were 1. If you don't make this assumption, then the regular case becomes:

glVertex4f(Bx, By, Bz, Bw);
glVertex4f(Ax, Ay, Az, Aw);
glVertex4f(Ax*Lw - Lx*Aw, Ay*Lw - Ly*Aw, Az*Lw - Lz*Aw, 0);
glVertex4f(Bx*Lw - Lx*Bw, By*Lw - Ly*Bw, Bz*Lw - Lz*Bw, 0);

Using external triangles, you'd change the last two vertices to:

glVertex4f(-Lx, -Ly, -Lz, -Lw);

For a directional light, Lw = 0. If you assume that your vertices all have W=1 and your light either has W=1 or W=0, then substituting Lw=0 into the two code snippets above will show that they end up exactly the same. Hence, directional lights should work fine.

What happens, however, if not all vertices have W=1, or if Lw is neither 0 nor 1? Are the two approaches still equivalent in that case? I'm not sure, but I am sure that my head hurts now http://www.opengl.org/discussion_boards/ubb/wink.gif

-- Tom

P.S.: The demo is here: http://developer.nvidia.com/view.asp?IO=understanding_w

bakery2k
02-05-2003, 08:30 AM
With this approach, a triangle is drawn from the two points with positive w, away to infinity. The triangle is drawn to infinity on the side of (0, 0, 0, 0) where the triangle crosses w=0.
For example, if the x-coordinates on the line where the triangle intersects the plane w=0 are all negative, the triangle will be drawn with the "infinite part" to the left of the line between the other 2 vertices in the window.

Imagine the light source lies on an edge which you wish to project. With the original infinite shadow volumes approach, this would produce a single (infinitely long) line due to all 4 points of the "extruded edge quad" being colinear.

With this approach however, one side of the line (in window coordinates) is filled, but we do not know which side this will be, as the triangle passes through w=0 at exactly (0, 0, 0, 0).

Cass' app confirms this. If the situation is set up so that a triangle passes through (0, 0, 0, 0), one side or the other is drawn arbitrarily.

Is this right?

PH
02-05-2003, 08:38 AM
Originally posted by Tom Nuydens:

For a directional light, Lw = 0. If you assume that your vertices all have W=1 and your light either has W=1 or W=0, then substituting Lw=0 into the two code snippets above will show that they end up exactly the same. Hence, directional lights should work fine.

Ah ok. Well, I'm not 100% clear on all of this yet.

cass
02-05-2003, 08:57 AM
You're getting colder.

Hint: water-tight rasterization

This is fun. http://www.opengl.org/discussion_boards/ubb/smile.gif

Cass

HalcyonBlaze
02-05-2003, 09:43 AM
Ok, this is totally a very randomn guess. I'm just starting to understand the w-coordinate and i can't apply it to explain my guess.

Anyways, along the lines of what castano said...Is the w-coordinate going to create a t-junc and create cracks in the rendering of the shadow? Or maybe it's if you use it on higher order curves? Ok the reason i'm spitting this out is because I'm reading the article on NVIDIA's site about the GF3 architecture. There was a part where they were talking about higher order surfaces and they mentioned Water-tight Tesselation and had a bullet under it saying that you would get crack free rendering.

So, don't ask me to explain myself..because i can't http://www.opengl.org/discussion_boards/ubb/biggrin.gif.

- Halcyon

Edit: Cass, I was just looking over some of the articles you wrote for NVIDIA. I have one thing to say: ... ... ... ... WOW!!!!!! They are really good and informative but not like a billion pages long with size 8 font! Can I ask you how you learnt all the stuff you have up there? I'm just getting into lighting and what not with OpenGL...and I am obviously a beginner!

[This message has been edited by HalcyonBlaze (edited 02-05-2003).]

PH
02-05-2003, 09:58 AM
Originally posted by castano:
PH, you don't just set w=-1 instead of that you negate all the components. Take the demo, set blue vertex w coordinate to 0 and press 'b'.

Yes, you're right. I simply had w = -1 and thought that was it. I modified Cass' shadow volume demo and indeed both local and infinite lights work.

I'm completely blank.

Cass, next hint http://www.opengl.org/discussion_boards/ubb/smile.gif ?

castano
02-05-2003, 09:59 AM
With 'watertight rasterization' he means: "no double hitting of pixels or missed pixels along shared edges of rasterized triangles"

However, I don't know for sure how the rasterization rules work in this case...

PH
02-05-2003, 10:29 AM
Originally posted by cass:

Hint: water-tight rasterization

I think it is related to the nudge with infinite far plane. Your demo produces artifacts when using a nudge != 1. This nudge = 1 - 1.0 / (1<<23) never seems to work on Radeons ( I use 0.995 normally ). Infinite lights seem to work with the nudge...

cass
02-05-2003, 10:50 AM
Ok, several people have hit on the key point. The problem is a T-junction cracking problem at infinity. External triangles pass *through* infinity rather than stopping at infinity, so it's not possible to render the infinite caps without T-junctions along the silhouette.

Still this does not answer the question:
When can't you use this approach?

Or, if you prefer:
When can you use this approach?

We've identified the problem, but what we really need to know is when it is and isn't safe to use this technique.

Thanks -
Cass

cass
02-05-2003, 10:58 AM
Edit: Cass, I was just looking over some of the articles you wrote for NVIDIA. I have one thing to say: ... ... ... ... WOW!!!!!! They are really good and informative but not like a billion pages long with size 8 font! Can I ask you how you learnt all the stuff you have up there? I'm just getting into lighting and what not with OpenGL...and I am obviously a beginner!
[/B]

Thanks, Halcyon. I've had lots of good "teachers" at NVIDIA. There is information everywhere, and all the important topics show up in various forms over and over. Eventually the fundamentals sink in, and all we're left with is homoegeneous coordinates to keep us feeling like newbies. http://www.opengl.org/discussion_boards/ubb/smile.gif

Cass

PH
02-05-2003, 11:07 AM
Well, it should be safe to use with the zpass approach ( with the "infinite" far plane ) but that answer almost seems too obvious.

Edit: I see Tom already mentioned this...

[This message has been edited by PH (edited 02-05-2003).]

Liquid
02-05-2003, 11:09 AM
You can use this approach when your inside a shadow-volume, because then you don't have to render the caps but could use the z-pass method.
Am I right?

castano
02-05-2003, 11:12 AM
You can use this approach when you don't need to cap the shadow volumes, that is:
- the shadow volume doesn't intersect the near plane.
- the caps are outside the view frustum.

Anyway, that was obvious, so I suppose you are talking about something else, right?

PH
02-05-2003, 12:14 PM
I'm not sure I see why T-juctions are generated. From the shadow volumes demo, it almost seems like the cracks go away as the nugde value approaches 1.0. If that is the case, wouldn't NV_depth_clamp make this approach possible all the time ?

cass
02-05-2003, 12:38 PM
Castano gets the gold star. http://www.opengl.org/discussion_boards/ubb/smile.gif

You can use this approach anytime you don't need to render infinite cap. Since zpass rendering doesn't require caps, that's the important case when you know you can use it.

Paul (PH),

For infinite shadow volumes, you have vertexes at infinity - both to extrude to and to cap with. With the external triangle approach, you extrude *through* not *to* infinity, so your infinite caps don't have actual vertexes to seam up with. It's the same problem as trying to cap an object that intersects the near plane.

Good job, all.

Thanks -
Cass

Gorg
02-05-2003, 12:53 PM
And I get the dirty broken star for the least usefull post of the thread http://www.opengl.org/discussion_boards/ubb/smile.gif

But at least I get it now.

[This message has been edited by Gorg (edited 02-05-2003).]

PH
02-05-2003, 01:03 PM
Originally posted by cass:
For infinite shadow volumes, you have vertexes at infinity - both to extrude to and to cap with. With the external triangle approach, you extrude *through* not *to* infinity, so your infinite caps don't have actual vertexes to seam up with. It's the same problem as trying to cap an object that intersects the near plane.

Ah, of course. Thanks, it's completely clear now http://www.opengl.org/discussion_boards/ubb/smile.gif. For some reason I kept thinking that the caps would be projected through infinity but this is only for rendering the "silhouette quads" as triangles.

castano
02-05-2003, 01:25 PM
Originally posted by cass:

Castano gets the gold star. http://www.opengl.org/discussion_boards/ubb/smile.gif

Thanks! :-)

Your explanation makes more sense though. t-juncs at the infinity are quite hard to visualize. :-)

rgpc
02-05-2003, 05:04 PM
Originally posted by cass:

You can use this approach anytime you don't need to render infinite cap. Since zpass rendering doesn't require caps, that's the important case when you know you can use it.

*Clunk*

Penny just dropped. Whilst I have no idea how to visualize the previously mentioned junctions at infinity (and I haven't looked at the mentioned demo yet) I have just realised an optimization I can put into the game I've been working on (and it's so obvious I should blush).

My game is based around an "iso" view and I have shadows working nicely but I've just realised that because of the position of the viewer I don't actually need to cap the end of the shadow volumes.

At least I don't think I do - at any rate the volumes are being clipped anyway because I have a frustum that doesn't go *to* infinity but I'm projecting the end points *through* ( http://www.opengl.org/discussion_boards/ubb/smile.gif) infinity. This works (I think) because you never actually see the end of the shadow volumes - or perhaps because you never enter a volume...

So I should be able to use this technique (boy I'll have to have a look at the demo because to me it sounds like w=-1 projects the shadow towards the light (?) which makes little sense to me...).

I'll just have to wait til I get home where I can stuff around with a post WW2 gfx card. http://www.opengl.org/discussion_boards/ubb/wink.gif

V-man
02-05-2003, 06:55 PM
Originally posted by PH:
I'm not sure I see why T-juctions are generated. From the shadow volumes demo, it almost seems like the cracks go away as the nugde value approaches 1.0. If that is the case, wouldn't NV_depth_clamp make this approach possible all the time ?

What? What cracks?

In practical terms, does this translate to a optmization? Is there a big difference between doing a single triangle instead of a quad?

Because to me it seems the major problem with shadow volumes is fillrate. Having a good algorithm to find the silhouette is quite important for this case.

If it's just educational, that's good. Reminds me of an old friend who asked me what would be the result of a triangle's shape if you pulled one of it's vertices to inifinity.
Ah, the good old days!

castano
02-05-2003, 07:20 PM
Originally posted by V-man:

In practical terms, does this translate to a optmization? Is there a big difference between doing a single triangle instead of a quad?

Another benefit is that you don't have to update all the vertices for each light, instead of that you only have to update a single vertex.

Hmm... thinking about that, here is a better idea, setup your static vertex buffer with the following format:

x y z 1
x y z 0

the first vertex should stay as is, while the second one will be transformed depending on the employed method.

If you use the standard method you want to turn it into:

x-Lx y-Ly z-Lz 0

And with the new method it would just be:

-Lx -Ly -Lz -1

You can of course do that with two simple vertex programs, but the 'nice' thing is that you can also do it with two blending matrices, using the 4th coordinate as the blending factor.

In the first case the matrix would be:
[I -L]
[0 0 ]

While on the second it would be:
[0 -L]
[0 -1]

V-man
02-06-2003, 07:34 AM
Here's a quick benchmark on the knight model

A small improvement, as expected and notice the T-J problem.

[This message has been edited by V-man (edited 02-06-2003).]

HalcyonBlaze
02-06-2003, 08:48 AM
The link is broken. I get the geocities "Page cannot be found error".

- Halcyon

cass
02-06-2003, 09:29 AM
This works for me:

Go to:
http://www.geocities.com/vmelkon/images2
Then click on the benchmarkstencilshadow.jpg from there. It's like geocities doesn't allow linking directly to images (perhaps unless they're the referrer).

[This message has been edited by cass (edited 02-06-2003).]

dare
02-06-2003, 02:27 PM
Hi.
I'm little late on discussion, but someone may find this useful, although it's written some time ago, and my question about w=0 is resolved... http://www.geocities.com/darkosos/shadow.htm

rgpc
02-06-2003, 09:26 PM
Originally posted by cass:
It's like geocities doesn't allow linking directly to images (perhaps unless they're the referrer).

Something odd going on there, V-Man has successfully put links to piccies using the same method before... (I recognised Image1 & 2)

The gain in performance isn't anything to write home about (but every little bit does count) but there are lots of artifacts in the inversion method shot...

vincoof
02-07-2003, 03:16 AM
Originally posted by rgpc:
The gain in performance isn't anything to write home about (but every little bit does count) but there are lots of artifacts in the inversion method shot...

I think artefacts are due to capping issues with T-junction. If the shadows were not capped I guess this would look ok.

SirKnight
02-07-2003, 09:29 AM
Well if this way of extruding the edge to create a volume rather than how it's usually done like in the nvidia paper with a quad or two triangles, then how is it really any better if it produces so many artifacts? I mean sure you can use one triangle per edge rather than two but if it causes problems like t-juncs, then I don't see how it gains anything. We still would have to try to fix the t-juncs and by this time we might as well extrude two triangles or a quad like normal. Am I wrong?

-SirKnight

PH
02-07-2003, 09:33 AM
One of Cass' gold star questions was "when is it safe to use ?". The answer was, when you don't need caps. So, if you are already mixing zpass and zfail then this can be used with the zpass. The artifacts only illustrate the case when you *shouldn't* use this approach.

SirKnight
02-07-2003, 10:22 AM
OOohhhhhh. I must have not noticed that part in this thread. I have never messed with the zpass technique yet, I really like zfail. http://www.opengl.org/discussion_boards/ubb/biggrin.gif But once I do implement it, shouldn't take too long now, I'll try this out. Sounds pretty cool if used correctly then.

-SirKnight

SirKnight
02-07-2003, 10:27 AM
One thing that kinda bugs me. Ok lets say I plan on mixing zpass and zfail. How do I know when to switch to zpass rather than zfail? I guess maybe if the "camera" can never go into the shadow that could be one case where I could switch to zpass. But should dynamic shadows or any shadow that the "camera" can walk through always use zfail? I know you could make it do that and there would be no visual problems, only performance in some cases.

-SirKnight

bakery2k
02-07-2003, 10:50 AM
Look here. The bit you want is on page 4.
http://www.gamasutra.com/features/20021011/lengyel_01.htm

SirKnight
02-07-2003, 03:36 PM
Ah, thanks man. I didn't know that article talked about that. It's been a while since I looked at it. http://www.opengl.org/discussion_boards/ubb/smile.gif

-SirKnight