Jump to content


Scissor versus viewport & projection


15 replies to this topic

#1 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 21 July 2006 - 09:03 AM

Hi all,

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

#2 TheNut

    Senior Member

  • Moderators
  • 1699 posts
  • LocationThornhill, ON

Posted 21 July 2006 - 10:58 AM

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.
http://www.nutty.ca - Being a nut has its advantages.

#3 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 21 July 2006 - 12:28 PM

TheNut said:

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:

Quote

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?

Quote

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!

#4 SigKILL

    Valued Member

  • Members
  • PipPipPip
  • 200 posts

Posted 21 July 2006 - 02:00 PM

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.

#5 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 21 July 2006 - 02:51 PM

SigKILL said:

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.

#6 Reedbeta

    DevMaster Staff

  • Administrators
  • 5307 posts
  • LocationBellevue, WA

Posted 21 July 2006 - 04:27 PM

Nick said:

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?

OpenGL only clears the pixels in the viewport, so you can clear smaller areas by setting the viewport appropriately.
reedbeta.com - developer blog, OpenGL demos, and other projects

#7 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 21 July 2006 - 06:27 PM

Reedbeta said:

OpenGL only clears the pixels in the viewport, so you can clear smaller areas by setting the viewport appropriately.
Interesting. If my assumption is correct then scissoring would be technically redundant in both APIs...

#8 Reedbeta

    DevMaster Staff

  • Administrators
  • 5307 posts
  • LocationBellevue, WA

Posted 21 July 2006 - 06:34 PM

Nick said:

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.
reedbeta.com - developer blog, OpenGL demos, and other projects

#9 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 21 July 2006 - 08:02 PM

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?

#10 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 21 July 2006 - 08:59 PM

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:

#11 Goz

    Senior Member

  • Members
  • PipPipPipPip
  • 575 posts

Posted 22 July 2006 - 07:44 AM

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!

#12 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 22 July 2006 - 10:04 AM

Goz said:

The scaling is the difference.
But this can be corrected with the projection matrix?

Quote

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.

Quote

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...

Thanks!

#13 Goz

    Senior Member

  • Members
  • PipPipPipPip
  • 575 posts

Posted 25 July 2006 - 08:59 AM

Nick said:

But this can be corrected with the projection matrix?

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 ... ;)

#14 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 25 July 2006 - 12:12 PM

Goz said:

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:

#15 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 25 July 2006 - 12:45 PM

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:

#16 Goz

    Senior Member

  • Members
  • PipPipPipPip
  • 575 posts

Posted 26 July 2006 - 11:12 AM

Nick said:

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.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users