# Where in a typical rendering pipeline does visibility and shading occur?

I am taking a computer graphics course. The book and the lecture notes are vague on the on the order of flow between the different steps in the rendering process. For example, if we have specified a view in a scene, and then want to perform a projection transformation for that given view, then we have to go through a sequence of transformations. In the end we end up with a normalized "viewcube" ready to be mapped 2D after clipping. But why do we end up with a cube (ie 3D thing), when a projection results in projecting the 3D objects to 2D. (depth information is lost?) The other line of reasoning is that all information further needed is stored within the "cube" and that visibility detection and shading is performed with respect to this cube and then we perform rasterezation.

edit: (More explicit question) Is shading and visibility checks performed after projections/normalization and clipping.

-
Could you clarify this somewhat to make it explicit what you want to know? The title of your question doesn't seem to match the questions asked in the main body. Part of the answer is that 'visibility' is not a single operation but can be done in different ways and at different stages. Shading occurs at the rasterisation stage, which typically comes after all the geometric transformations and projections. Remember that lighting angles are all relative and remain essentially unchanged through transformations. – Kylotan Dec 14 '12 at 13:24
Thanks, I tried to make the question more explicit now. The confusion comes from the fact that if we project something in 3D to 2D, then depth information is lost right? So how can we then perform operations like shading and visibility checks that are described using a three-dimensional model. – user29163 Dec 14 '12 at 14:11
Obtaining per-pixel depth information can form part of the projection process, which can yield x and y coordinates for the screen position and a z coordinate for the depth buffer. Shading is a bit different and very dependent on the type of shading you mean, as it can be done in many different ways these days - the end result is done during rasterisation but input variables could be calculated much further up the pipeline. – Kylotan Dec 14 '12 at 15:21
I will note that Frank Luna's books (Introduction to 3D Programming with DirectX) is an excellent resource for questions like these. Much of the information is also quite relevant to OpenGL, though there are some key differences (and the API tutorials obviously don't port over). The gltut website is a great resource for these questions focused on OpenGL. – Sean Middleditch Dec 14 '12 at 18:03

Short answer: visibility determination occurs both before and after the projection to screen space. Shading is generally done afterward.

Visibility determination in a typical rendering engine takes place at several different levels of granularity: object, triangle, and pixel. These occur in different parts of the pipeline.

First, on the CPU, the engine will typically use a scene graph to cull entire objects that it determines are not visible from the current camera position. This involves frustum culling (getting rid of offscreen objects) and occlusion culling (getting rid of objects entirely hidden behind other opaque objects). Both of these act to reduce the number of draw calls sent to the GPU. Each mesh will be either drawn in its entirety if any part of it is visible, or not drawn at all. (By "drawn" here I mean the engine queues up a draw call for it and sends it to the GPU.)

When the GPU processes a mesh, it starts running the vertex shader on each vertex in it. This transforms the vertex into screen space. Note that screen space is still 3D. The XY coordinates of a vertex in screen space determine the pixel coordinates on screen, but the Z depth is also kept so that we can do per-pixel visibility later. If we threw away the Z at this point we wouldn't be able to tell which triangles should appear in front of which other triangles.

Once vertices start coming out of the vertex shader, the GPU assembles them into triangles and any triangles that fall entirely offscreen are thrown out. Triangles are also clipped when necessary. So this is the triangle-level visibility. After this the remaining triangles are passed to the rasterizer, which determines which pixels are covered by a triangle and runs the pixel shader on each of those.

The pixel shader typically does most of the work of calculating lighting and shading. After the pixel shader is done*, the result is stored to the framebuffer. However, it is only stored if the Z depth of the pixel (interpolated from the Z depths of the triangle's vertices) is closer to the camera than the Z depth already stored in the depth buffer at that pixel. So this is per-pixel visibility and is the finest-grained level of visibility determination.

*Footnote: actually, depth testing can often be done before the pixel shader runs, which saves a lot of time by not shading invisible pixels.

-
Fantastic answer, very clear, thank you sir! Consider this thread solved. – user29163 Dec 15 '12 at 9:04