Perspective divide and viewport transform

RoOoBo

Regular
Would make sense to perform the perspective divide and viewport transform in the vertex shader? As they are both just per vertex operations.

And how would affect that to frustum clipping?
 
RoOoBo said:
Would make sense to perform the perspective divide and viewport transform in the vertex shader? As they are both just per vertex operations.

And how would affect that to frustum clipping?

crucially.

order of operations is:
1. projection transform (i.e. perspective or parallel)
2. view port clipping
3. w division
--- here vertices are already in normal device coordinates (NDC)
4. viewport transform
--- here vertices are in screen space
5. viewport clipping
 
What I'm asking is if it would make sense or be useful to avoid clipping in clip space (after projection transform) and go directly to screen space. The output from the vertex shader (vertex position) would be in screen space coordinates rather than in clip coordinates as is currently defined in OpenGL and D3D. And what kind of problems would you face using that approach.

From what I know what you show is just the 'official' geometry 3D pipeline part but there are other ways to do the same delaying clipping up to rasterization. For example this: http://www.cs.unc.edu/~olano/papers/2dh-tri/.

Of course the method discussed in the paper wouldn't work in screen space (rasterizes vertices in 2D homogeneous coordinates).
 
What I'm asking is if it would make sense or be useful to avoid clipping in clip space (after projection transform) and go directly to screen space. The output from the vertex shader (vertex position) would be in screen space coordinates rather than in clip coordinates as is currently defined in OpenGL and D3D. And what kind of problems would you face using that approach.

ok. see below.

RoOoBo said:
From what I know what you show is just the 'official' geometry 3D pipeline part

not exactly. note that the last step i've listed is 'viewport clipping', whereas in the 'classic' rasterizer implementations this step is absent, actually substituted for another thing - viewport (or screen) guarbanding. a rasterizer's guardband is most informally described as a margin around the actual viewport/screen, which the vertices falling into do not need clipping. now, this is from the user's parspective. from the rasterizer's perspective this guarbanding can be implemented just as well through rectangle clipping of the screen space coordinates. and if the domain of this rectangle clipper is of large enough (tm) magnitude then one could completely bypass the frustum clipping and rely completely on this viewport clipping, with no impact on the visualized output. [ed] with one pre-condition, though: all coorinates of the screen-space vertices should be indeed 'screen-space', i.e. all vertex data of coordinate nature (e.g. position, color, tex.mapping) should have undergone the porjection transform, followed by the w-division.

so, to answer your original question, there would be no implications on the produced output if there's a good enough viewport rectangle clipper. YET there's one performance implication: vertices wich would otherwise be rejected by the frustum clipper would now undergo W-division, just to be rejected later on by the viewport clipper.
 
The reason not to do it is simple enough. You do the homogenous divide after doing near clip plane clipping. You don't want to be dividing by 0.
 
Colourless said:
The reason not to do it is simple enough. You do the homogenous divide after doing near clip plane clipping. You don't want to be dividing by 0.

*slaps forehead*

gotta get some rest.
 
Colourless said:
The reason not to do it is simple enough. You do the homogenous divide after doing near clip plane clipping. You don't want to be dividing by 0.

That makes sense, you would lose that triangle if you divide by zero. And the programmer should have know that vertices in the eye plane weren't allowed.
 
Colourless said:
The reason not to do it is simple enough. You do the homogenous divide after doing near clip plane clipping. You don't want to be dividing by 0.

Whats wrong with dividing by 0? Perfectly acceptable floating point number is produced (+ or -Infinity).

Some hardware (at least NVIDIA) does indeed clip post-perspective. i.e on exit from the vertex shader it does the homogenous divide and then clips. On Xbox this is explicitly controlable and you can write screen space vertex shader (very handy for distortion type effects), doesn't make no difference to the clipping.
 
DeanoC said:
Colourless said:
The reason not to do it is simple enough. You do the homogenous divide after doing near clip plane clipping. You don't want to be dividing by 0.

Whats wrong with dividing by 0? Perfectly acceptable floating point number is produced (+ or -Infinity).

Some hardware (at least NVIDIA) does indeed clip post-perspective. i.e on exit from the vertex shader it does the homogenous divide and then clips. On Xbox this is explicitly controlable and you can write screen space vertex shader (very handy for distortion type effects), doesn't make no difference to the clipping.

Most interesting. I didn't know that... but Nvidia hardware is (or was, GFFX might be different) known to not really like clipping planes at all. This could probably be called a 'peculiarity' of their architechture.

But anyway, the thing about clipping post divide is that perspective correction will break... interpolating from +/- infinity after a divide by 0... umm, yeah... just how exactly do you do that.

Ok, it's not 'impossible' to do. You can use a number that is just really huge, and it would produce somewhat correct results. So in effect divide by zero just becomes divide by the smallest positive floating point value. This may cause some problems, but it shouldn't be too obvious.

Of course if you do it this way, you don't even need to implement a near clipping plane. You can use your per-pixel depth compare to clip pixels that are too close for triangles that are potentially clipping. Could this be what nvidia is doing.... hey, I wouldn't want to speculate, but it really wouldn't surprise me.

But anyway, conventional thinking has divide by w after clipping so you wont have to worry about divide by 0 issues, valid floating point number or not :)
 
DeanoC said:
Whats wrong with dividing by 0? Perfectly acceptable floating point number is produced (+ or -Infinity).

Some hardware (at least NVIDIA) does indeed clip post-perspective. i.e on exit from the vertex shader it does the homogenous divide and then clips. On Xbox this is explicitly controlable and you can write screen space vertex shader (very handy for distortion type effects), doesn't make no difference to the clipping.

In fact I knew that it was being done that way in the XBOX, and that was the reason I was asking. However as I theorically shouldn't know about that ...

The problem with a vertex in infinity is how the hell you interpolate. And if you divide by 0 you are losing all the info in that vertex. You no longer have the two edges that come from that vertex. So I don't really see how you could draw such a triangle.

Using 2DH rasterization (as described on the paper I listed and some other paper from McCool) you wouldn't have the problem as you don't have to divide by w.

Another thing about NVidia is that Akeley (from NVidia) said in his 2001 Stanford's Real-Time Graphics Architecture course that modern GPUs (or perhaps he was just meaning NVidia) were not doing geometric clipping anymore and were using rasterization in homogeneous coordinates. However using screen space coordinates could break such method and produce errors (wrapping vertices through infinite).

I have the feeling that ATI is not using that approach (2DH rasterization) though, I wonder if there is somekind of synthetic benchmark that could test what clipping method is used.
 
Colourless said:
Most interesting. I didn't know that... but Nvidia hardware is (or was, GFFX might be different) known to not really like clipping planes at all. This could probably be called a 'peculiarity' of their architechture.

Of course if you do it this way, you don't even need to implement a near clipping plane. You can use your per-pixel depth compare to clip pixels that are too close for triangles that are potentially clipping. Could this be what nvidia is doing.... hey, I wouldn't want to speculate, but it really wouldn't surprise me.

For user clip planes I think they just use normal interpolation between the triangle vertices (interpolation of the distance to the clip plane). So they are checking in every pixel if the pixel is inside or outside the clipping plane. May be that is the reason of the slow down, or because it needs additional interpolated values and there is a limited number of interpolators in the hardware. Of course the other reason could just be that with geometric clipping you don't have to rasterize all those pixels.

That is the method used in 2DH rasterization. And the CLPx registers introduced with NV_vertex_program2 seem to point to that method as the clip registers are just the signed distance to the clip planes (or whatever you want to code in your shader for clipping).
 
back afresh.

RoOoBo said:
Colourless said:
Most interesting. I didn't know that... but Nvidia hardware is (or was, GFFX might be different) known to not really like clipping planes at all. This could probably be called a 'peculiarity' of their architechture.

Of course if you do it this way, you don't even need to implement a near clipping plane. You can use your per-pixel depth compare to clip pixels that are too close for triangles that are potentially clipping. Could this be what nvidia is doing.... hey, I wouldn't want to speculate, but it really wouldn't surprise me.

For user clip planes I think they just use normal interpolation between the triangle vertices (interpolation of the distance to the clip plane). So they are checking in every pixel if the pixel is inside or outside the clipping plane. May be that is the reason of the slow down, or because it needs additional interpolated values and there is a limited number of interpolators in the hardware. Of course the other reason could just be that with geometric clipping you don't have to rasterize all those pixels.

quite a viable approach you've described. re your last note in the above paragraph, to clip a pixel they would need just its positional data, so it's not exactly full-blown rasterization. plus, they don't need to do that for all scene triangles' coverage either, just for those triangles which intersect a given clip plane; triangles which are completely off the plane can be rejected altogether.
 
I'll add this, you don't even need to check per pixel. You could discard per scanline too. If the beginning and the end are clipped, then the entire scan line can be clipped too.
 
RoOoBo said:
However as I theorically shouldn't know about that ...

If you shouldn't know about that - that means you haven't sign an NDA.
So there's nothing stopping you from talking about that ;)
 
Colourless said:
I'll add this, you don't even need to check per pixel. You could discard per scanline too. If the beginning and the end are clipped, then the entire scan line can be clipped too.

I think rasterizers don't work any more by scanlines but by 2^n x 2^n blocks. But of course you could use the same approach, check the corners of the block for clipping before producing any new fragment inside the block.
 
There is an interesting discussion on the implementation of "user" clip planes (i.e. clipping in addition to the standard {near, far, top, left, etc} planes) on the DirectX developer mailing list. It was quite amusing to see the standpoints of the developer relations reps from ATI and NVidia. :)
 
Simon F said:
There is an interesting discussion on the implementation of "user" clip planes (i.e. clipping in addition to the standard {near, far, top, left, etc} planes) on the DirectX developer mailing list. It was quite amusing to see the standpoints of the developer relations reps from ATI and NVidia. :)

would you quote some by your discretion for the not subscribed/unsubscribed among us?
 
darkblu said:
Simon F said:
There is an interesting discussion on the implementation of "user" clip planes (i.e. clipping in addition to the standard {near, far, top, left, etc} planes) on the DirectX developer mailing list. It was quite amusing to see the standpoints of the developer relations reps from ATI and NVidia. :)

would you quote some by your discretion for the not subscribed/unsubscribed among us?
Gosh it was a few weeks ago and I don't really have time to dig it up. (You might be able to find it on google.)
IIRC, in summary someone asked if the user clip planes still cost texture slots on NV hardware and how to control it in the API. I think that an ATI rep then said that there was no way to control that in the API anyway and that this way of doing clipping was bad.

An NV employee responded saying that was a over-broad generalisation and that there were some advantages of texkill (?) based clipping - although he said something that probably wasn't correct.

It was just the polite debate that I found amusing.
 
Simon F said:
IIRC, in summary someone asked if the user clip planes still cost texture slots on NV hardware and how to control it in the API. I think that an ATI rep then said that there was no way to control that in the API anyway and that this way of doing clipping was bad.

An NV employee responded saying that was a over-broad generalisation and that there were some advantages of texkill (?) based clipping - although he said something that probably wasn't correct.

It was just the polite debate that I found amusing.

http://discuss.microsoft.com/SCRIPTS/WA-MSD.EXE?A2=ind0306D&L=DIRECTXDEV&P=R1696&I=-3

I'm still reading the thread though. This reminds me that I had should joined or should be reading the DXDEV list long ago. Not that I'm a 3D programmer but sometimes they seem to give interesting GPU architectural tips there.

Amazingly just before start reading the thread I was thinking that you could emulate the GFFX interpolated clip planes method with pixel shaders and kill using some 'free' interpolators (texture coords) ...

Of course that would produces more overhead that rejecting at fragment generation.
 
Now I see what you mean ;)


Huddy(ATI) said:
It's a good way (and may very well be the best way) to emulate clip planes if your graphics card does not have direct hardware support for clip planes - but it's a rotten technique to use on more advanced hardware.

Everitt(NVIDIA) said:
Before we make broad generalizations about what constitutes a "rotten technique", consider your intended use. If you need depth invariance and texture coordinate interpolation invariance, and your hardware doesn't support invariant user clip planes, then you may well need to use "texkill" clipping.

What I get at the end of the discussion is that NVidia doesn't support hardware geometry user clipping (I mean generating new vertices), and more likely frustrum clipping either (other than may be full primitive reject) as they could use the same hardware for both (just iterate for the additional user planes).

But ATI (and PowerVR) may support geometric clipping.
 
Back
Top