Is the scissor test any different from (accordingly) adjusting the viewport and projection matrix? As far as I know all it does is 'clip' the area that is rendered to (like a viewport - with clipping enabled), but without scaling in screen space. But I might be missing something. Is scissoring redundant?

Thanks,

Nick

TheNut
—
2006-07-21T10:58:45Z —
#2

The scissor test is a fragment operation whereas clipping is a vertex operation. Each has their benefit, but scissor tests are more often used for GUI intensive applications and clipping is usually for geometry intensive applications.

Using scissors is also far more simple than resizing the viewport and adjusting the projection matrix =) But yes, I believe you could achieve the same affect with that approach so long as you don't clear any buffers in the process.

The scissor test is a fragment operation whereas clipping is a vertex operation.

Conceptually, yes, but guard-band clipping is pretty much a raster operation as well. So in practice the difference should be quite small. It might even be handled by the same hardware components (actually that's my question). :ninja:

Using scissors is also far more simple than resizing the viewport and adjusting the projection matrix =)

That's relative. But yeah I have the feeling they just added the scissoring concept to the API to make it a little easier to render to an area without scaling. Or it might just be a historical thing, when 3D geometry clipping was handled on the CPU but the graphics chip featured 'accelerated' 2D clipping (so you didn't have to implement a complex clipper in software just for some simple GUI work).

Anyway, I'd just like to know whether the two are in fact entirely redundant, or whether there is something that can't be done without having both? Or in other words, if an API didn't have scissoring, would it still be fully functional?

But yes, I believe you could achieve the same affect with that approach so long as you don't clear any buffers in the process.

Direct3D allows to clear just regions. For OpenGL it appears that setting the scissor rectangle is the only way to control clearing of smaller areas? But that's more of a legacy API limitation than a technical limitation...

Thanks!

SigKILL
—
2006-07-21T14:00:44Z —
#4

The difference is that glScissor test specifies what pixels to be changed when rendering, while glViewport changes how gl should map from device coordinates to window coordinates. So if you want to render to a subsection to the window you should use glScissor() (and enable GL_SCISSOR_TEST), and then set glViewport() if required.

The difference is that glScissor test specifies what pixels to be changed when rendering, while glViewport changes how gl should map from device coordinates to window coordinates. So if you want to render to a subsection to the window you should use glScissor() (and enable GL_SCISSOR_TEST), and then set glViewport() if required.

Then what's the difference with setting the viewport to the rectangle you want to render to and adjusting the projection matrix to undo the scaling done by the viewport (and leaving clipping enabled)? For example, if we'd like to render to the left half of the screen only, we could set the viewport to that half, and adjust the projection matrix so x-coordinates are multiplied by 2 and translated right by 1.

I just tried this with a Direct3D 'spinning cube' application and it works without trouble.

Interesting. If my assumption is correct then scissoring would be technically redundant in both APIs...

My guess is that it is. But since pixels have to be clipped to the visible window area anyway (so-called 'pixel ownership test'), adding scissor capability is trivially easy for API implementors. It probably just exists to provide a somewhat simpler interface for updating a portion of the screen. It might also be a historical artifact as you mentioned.

Nick
—
2006-07-21T20:02:50Z —
#9

While experimenting with viewports and scissor rectangles I bumped into something odd. I have no idea how to disable clipping in Direct3D! I tried SetRenderState(D3DRS_CLIPPING, FALSE), but the geometry still gets clipped to the viewport. :blink: Shouldn't it allow to render geometry outside the viewport? If not, what does D3DRS_CLIPPING really do?

Nick
—
2006-07-21T20:59:07Z —
#10

It looks like D3DRS_CLIPPING is from the times when clipping was typically done in software. Nowadays its implicitely always enabled. So rendering outside the viewport is impossible, and the render state doesn't do anything. Can anyone confirm this? :unsure:

Goz
—
2006-07-22T07:44:55Z —
#11

The scaling is the difference. I was trying, once, to implement scissoring using the viewport trick but it wasn't accurate enough for me. I seem to recall, at the time, being told by an nVidia man that vewport clipping used the scissor rectangle!

I was trying, once, to implement scissoring using the viewport trick but it wasn't accurate enough for me.

What do you mean by not accurate enough? Both the viewport and scissor rectangle are defined in integer coordinates, and the floating-point components of the projection matrix should be accurate enough to compensate the scaling.

I seem to recall, at the time, being told by an nVidia man that vewport clipping used the scissor rectangle!

Yes, that's starting to sound logical to me. By using the half-space rasterization algorithm, clipping or scissoring is just a matter of adding extra planes. So it's all a raster operation and it can be done with the same hardware. Anyway, this also confirms that scissoring is technically redundant and was just added for convenience. Unless there are indeed precision problems...

It can't under all circumstances ... this was the exact problem i had.

Floating point accuracy is your enemy here. You may be able to use ir for certain things but i was trying to save fill rate in a DX8 app by scissoring the geometry to the light's bounds (A Doom 3 style light renderer). You need to apply the same projection matrix to both (and hence GL or DX9 scissoring is so much better here) to make sure the same Z values are generated for triangles with the same 3D coordinates. Otherwise Z-fighting ensues. Now if we were using fixed point ...

Floating point accuracy is your enemy here. You may be able to use ir for certain things but i was trying to save fill rate in a DX8 app by scissoring the geometry to the light's bounds (A Doom 3 style light renderer). You need to apply the same projection matrix to both (and hence GL or DX9 scissoring is so much better here) to make sure the same Z values are generated for triangles with the same 3D coordinates. Otherwise Z-fighting ensues. Now if we were using fixed point ...

Oh, I think I got it now. :o If a polygon is clipped in 3D its gradients (most notably z-gradient) might be very slightly different from the same unclipped polygon, causing z-fighting problems when doing multipass.

That can indeed only be solved with a raster based scissor operation...

Thanks a lot for the information! :worthy:

Nick
—
2006-07-25T12:45:03Z —
#15

Actually, the problem you experienced isn't from 3D clipping like I said above but indeed from floating-point imprecision of the projection matrix alone. All modern hardware uses guard band clipping, which is already a raster based clipping technique. It's just the scaling done by the viewport and the correction of the projection matrix that can't be without (tiny) floating-point imprecisions. So the polygons of multiple passes don't match entirely perfectly and cause the z-fighting. :ninja:

Actually, the problem you experienced isn't from 3D clipping like I said above but indeed from floating-point imprecision of the projection matrix alone. All modern hardware uses guard band clipping, which is already a raster based clipping technique. It's just the scaling done by the viewport and the correction of the projection matrix that can't be without (tiny) floating-point imprecisions. So the polygons of multiple passes don't match entirely perfectly and cause the z-fighting. :ninja:

Yup thats the one. Glad my terrible explanation made some sense to ya

Its a fairly common matrix case Projection x Viewport produces a different results to Projection x InverseViewportScale x SmallViewport. That extra matrix multiply adds in the, often tiny but significant, error.