35

I was studying the rendering pipeline and when I got to the clipping stage it was explained that from the view (eye or camera) space we have to pass to the clip space, also called normalized device space (NDC), that is a cubic space from -1 to 1.

However, now I don't understand when the passage from this space to the screen coordinates space happens:

  1. Right after clipping and before rasterization?

  2. After rasterization and before scissor and z-test?

  3. At the end just before writing on the frame buffer?

nbro
  • 12,226
  • 19
  • 85
  • 163
StrG30
  • 630
  • 1
  • 8
  • 18

5 Answers5

54

No, clip space and NDC space are not the same thing.

Clip space is actually one step away from NDC, all coordinates are divided by Clip.W to produce NDC. Anything outside of the range [-1,1] in resulting NDC space corresponds to a point that is outside of the clipping volume. There is a reason the coordinate space before NDC is called clip space ;)

Strictly speaking, however, NDC space is not necessarily cubic. It is true that NDC space is a cube in OpenGL, but in Direct3D it is not. In D3D the Z coordinate in NDC space ranges from 0.0 to 1.0, while it ranges from -1.0 to 1.0 in GL. X and Y behave the same in GL and D3D (that is, they range from -1.0 to 1.0). NDC is a standard coordinate space, but it has different representation in different APIs.

Lastly, NDC space to screen space (AKA window space) occurs during rasterization and is defined by your viewport and depth range. Fragment locations really would not make sense in any other coordinate space, and this is what rasterization produces: fragments.


Update:

Introduced in OpenGL 4.5, the extension GL_ARB_clip_control allows you to adopt D3D's NDC convention in GL.

Traditional OpenGL behavior is:

glClipControl (GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE);

Direct3D behavior can be achieved through:

glClipControl (GL_UPPER_LEFT, GL_ZERO_TO_ONE); // Y-axis is inverted in D3D
Andon M. Coleman
  • 39,833
  • 2
  • 72
  • 98
  • 1
    Clip space and NDC are not the same thing otherwise they wouldn't have different names. Clip space is the space points are in after the point transformation by the projection matrix but before the normalisation by w. NDC space is the space points are in after the normalisation by w. http://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/projection-matrix-GPU-rendering-pipeline-clipping – user18490 Apr 07 '15 at 20:53
  • 11
    This answer might be a bit misleading. Clip space and NDC are conceptually the same thing, just represented in different forms - one in homogeneous coordinates and the other in Cartesian. The only thing lost in this conversion is the ability to represent points at infinity. So yes, while they are different things in practice (that is, you have to do an operation to get from one to the other), they effectively represent the same underlying model. – Joseph Mansfield May 23 '16 at 08:53
  • I though it was much simpler than that. It has nothing to do with what I will call the 2d projection space. Instead it is merely the volume which represents the camera's field of view. An object inside the clip space is visible to the camera. An object outside of clip space isn't visible. Nothing to do with the 2d perspective projection. After further reading it appears clip space is the same as NDS. In 2d perspective space you can easily tell if an object is in field of view if it's x and y coordinates are in range of the screen dimensions. So you would use the 2d perspective space 2 times. – marshal craft Aug 28 '16 at 07:23
  • 2
    This is correct, but the thing about clip-space is, it's not normalized :) The `w` coordinate defines the extent of the clip volume in both clip-space and NDC-space, but in NDC-space, `w` is **1.0** and everything has been normalized. In clip-space, each vertex can exist with its own scale defined by a different `w` coordinate; once transformed into NDC-space, all vertices are in agreement and much simpler to work with. – Andon M. Coleman Aug 30 '16 at 01:26
  • 1
    @AndonM.Coleman - Thanks for the very useful comment! I still have a doubt, could you please help? In basically all the sources I found online ([linking one for reference](http://www.songho.ca/opengl/gl_projectionmatrix.html)) the NDC space is shown as a cube. How should I think of the Clip space as? Is it a cube as well, or is it a perspective frustum as the eye space (since inside of it we can represent points at infinity)? And is it correct to think of the operation that goes from clip to to NDC as mapping a ray in the first into a point in the second, or is it 1 to 1? – Matteo Aug 30 '16 at 21:23
  • Yes, by definition clip-space HAS to be a cube, if your range in x/y/z is +/-w, that's a cube. The way it typically works is that a (perspective) projection matrix will define different values for `w` based on the value of `z` -- that's where perspective comes from, but it's not an automatic part of clip-space. After the perspective divide, once everything is in NDC-space, perspective will cause any vertices with differing clip-space `w` coordinates to spread out. Orthographic projection is just as valid in clip-space and does not cause this. – Andon M. Coleman Aug 31 '16 at 02:48
11

Clip space and NDC (normalized device coordinates) are not the same thing, otherwise they wouldn't have different names.

Clip space is where the space points are in after the point transformation by the projection matrix, but before the normalisation by w.

NDC space is the space points are in after the normalisation by w.

http://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/projection-matrix-GPU-rendering-pipeline-clipping

Camera space --> 
x projection matrix ---> 
Clip space (before normalisation) --->
Clipping ---> 
Normalisation by w (x/w, y/w, z/w) --->
NDC space (in the range [-1, 1] in x and y)
nbro
  • 12,226
  • 19
  • 85
  • 163
user18490
  • 3,073
  • 3
  • 24
  • 49
  • 16
    Not to nitpick, but there are plenty of coordinate spaces with multiple names. For example, eye-space, view-space and camera-space are all, unfortunately, the same thing. Window-space and screen-space are two words for the same thing as well. _NDC and clip-space definitely are not two words that mean the same thing, that much is true._ – Andon M. Coleman Aug 31 '15 at 04:37
  • 4
    The step of dividing each component by the `w` component is not called "normalization", it's called *perspective division* and its purpose is to transform vertices from Homogeneous space into Cartesian space (i.e. project them). It's true they end up in normalized device space, but that does not mean the vertices were "normalized". Normalizing a vertex, which is actually represented as a vector, is something very different. – code_dredd Mar 13 '17 at 07:58
1

Apparently, according to Apple, clip space is the same as NDC.

https://developer.apple.com/documentation/metal/hello_triangle

Quote:

"The main task of a vertex function (also known as a vertex shader) is to process incoming vertex data and map each vertex to a position in the viewport. This way, subsequent stages in the pipeline can refer to this viewport position and render pixels to an exact location in the drawable. The vertex function accomplishes this task by translating arbitrary vertex coordinates into normalized device coordinates, also known as clip-space coordinates."

Another quote from comments in sample code:

"The output position of every vertex shader is in clip space (also known as normalized device coordinate space, or NDC)."

Perhaps this is because the tutorial is in 2D? Misleading statements..

Siamaster
  • 892
  • 11
  • 17
  • 1
    From the book "OpenGL SuperBible 6th edition" - Pag. 64: " _Clip Space_ : Positions of vertices after projection into a non-linear homogeneous coordinate. _Normalized Device Coordinate (NDC) Space_ : Vertex coordinates are said to be in NDC after their clip-space coordinates have been divided by their own w component." – Drout Nov 08 '17 at 13:41
  • Yes, for me clip space is before clipping, not after clipping. But in a 2D app or with an orthogonal projection, the result is the same. – Siamaster Nov 08 '17 at 14:20
  • You are in clip space before and after clipping. The idea behind clip coordinates is that all gradients are still linear since there is no perspective applied yet; this simplifies things a lot. If the input to clipper is in clip space, so is the output. You are describing a corner case where w is uniformly 1.0 for all of the vertices. This scenario is easy to detect from the transformation matrix and input vertices (trivial if they are 3 components or less). This doesn't affect the fact that clip results are still in clip coordinates. OK so NDC is identical to clip, great; you can skip a step. – t0rakka Dec 27 '17 at 14:05
0

NDC space is clip space, NDC space to window space is done by hardware, happened after NDC and before rasterization.

There is API to set the width and height, the default value is same size with window size.

// metal
func setViewport(_ viewport: MTLViewport)
// OpenGL
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);

NDC space for OpenGL, xyz range [-1, 1]. For Metal, Z is from 0 to 1

NDC space is usually left hand system.

lbsweek
  • 4,230
  • 37
  • 37
0

You can think the transition from clip space (-1 to +1 on every axis, for anything inside your image) to Screen Coordinates, also called viewport space (0 to ResX in X, 0 to rexY in Y, and 0 to 1 in Z, aka depth), as occurring just before the rasterization, after the vertex processor.

When you write a Vertex shader, you output is the projected position of the vertex in Clip space, but in the Fragment shader, each fragment comes with its own Screen coordinates and depth.

About Clip Space VS NDC

Clip Space is, as the name implies, is a Space, that is, a Reference Frame, a Coordinate System, that is, a particular choice of origin and set of three axis that you use to specify points and vectors.

Its origin is in the middle of the clip volume, its three axis are aligned as specified by the API. For example, the point with Cartesian coordinates (+1,0,0) of this Space appears on the right end of the image, and the point with Cartesian coordinates (-1,0,0) of the left.

NDC (Normalized Device Coordinates) is, as the name implies, a set of coordinates: they are the three Cartesian coordinates of a point in Clip Space. For example, take a point in Clip space of homogeneous coordinates (3,0,0,3), which you can also express as (30,0,0,30), and in many other ways, and which has Cartesian coordinates (1,0,0): its NDC are (1,0,0).