Difference between revisions of "Face Culling"

From OpenGL.org
Jump to: navigation, search
m (How does face culling work? Why doesn't it use the surface normal?)
(Tessellation: Clarification on patch winding.)
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
== How does face culling work? Why doesn't it use the surface normal? ==
+
{{pipeline float}}
  
OpenGL face culling calculates the signed area of the filled primitive in window coordinate space. The signed area is positive when the window coordinates are in a counter-clockwise order and negative when clockwise. An app can use {{apifunc|glFrontFace|()}} to specify the ordering, counter-clockwise or clockwise, to be interpreted as a front-facing or back-facing primitive. An application can specify culling either front or back faces by calling {{apifunc|glCullFace|()}}. Finally, face culling must be enabled with a call to {{apifunc|glEnable|(GL_CULL_FACE)}}; .
+
[[Primitive|Triangle primitives]] after all transformation steps have a particular facing. This is defined by the order of the three vertices that make up the triangle, as well as their apparent order on-screen. Triangles can be discarded based on their apparent facing, a process known as '''Face Culling'''.
  
OpenGL uses your primitive's window space projection to determine face culling for two reasons. To create interesting lighting effects, it's often desirable to specify normals that aren't orthogonal to the surface being approximated. If these normals were used for face culling, it might cause some primitives to be culled erroneously. Also, a dot-product culling scheme could require a matrix inversion, which isn't always possible (i.e., in the case where the matrix is singular), whereas the signed area in DC space is always defined.
+
== Winding order ==
  
However, some OpenGL implementations support the GL_EXT_cull_vertex extension. If this extension is present, an application may specify a homogeneous eye position in object space. Vertices are flagged as culled, based on the dot product of the current normal with a vector from the vertex to the eye. If all vertices of a primitive are culled, the primitive isn't rendered. In many circumstances, using this extension results in faster rendering, because it culls faces at an earlier stage of the rendering pipeline.
+
When the user issues a [[Drawing Command]], the vertices processed by the [[Rendering Pipeline]] are processed in the order provided by [[Vertex Specification]]. The [[Geometry Shader]] can alter the order, but even then, the vertices created by each GS invocation are ordered relative to the other vertices. The [[Tessellation Evaluation Shader]] can directly control the order of the vertices in the tessellated patch [[#Tessellation|using special options]].
 +
 
 +
When vertices are broken down into [[Primitive]]s during [[Primitive Assembly]], the order of the vertices relative to the others in the primitive is noted. The order of the vertices in a triangle, when combined with their visual orientation, can be used to determine whether the triangle is being seen from the "front" or the "back" side.
 +
 
 +
This is determined by the winding order of the triangle. Given an ordering of the triangle's three vertices, a triangle can appear to have a clockwise winding or counter-clockwise winding. Clockwise means that the three vertices, in order, rotate clockwise around the triangle's center. Counter-clockwise means that the three vertices, in order, rotate counter-clockwise around the triangle's center.
 +
 
 +
[[File:Winding order.png]]
 +
 
 +
Which side is considered the "front" side is controlled by this function:
 +
 
 +
{{funcdef|void {{apifunc|glFrontFace}}(GLenum {{param|mode}});}}
 +
 
 +
This is global state. {{param|mode}} may be {{enum|GL_CW}} or {{enum|GL_CCW}}, which mean clockwise or counter-clockwise is front, respectively. On a freshly created [[OpenGL Context]], the default front face is {{enum|GL_CCW}}.
 +
 
 +
The [[Fragment Shader]] gets a built-in input value saying whether the fragment was generated by the triangle's front face (this will always be true for non-triangular primitives).
 +
 
 +
=== Tessellation ===
 +
{{main|Tessellation Winding Order}}
 +
 
 +
The winding order of the abstract patch vertices generated during [[Tessellation]] is controlled by the [[Tessellation Evaluation Shader]]. It is a layout option specified by the TES, rather than a runtime value. The winding order is specified in terms of the direction: {{code|cw}} and {{code|ccw}}. Which is considered "front" is still defined by {{apifunc|glFrontFace}}.
 +
 
 +
Note that the final winding order of any generated triangles is determined by the positions output from the TES (or a subsequent [[Geometry Shader]]. So even though the winding order specification in the TES is a fixed value for the shader, this does not mean that all triangles generated will have that winding after the TES generates positions for them. The specified order is only for the abstract patch; the TES decides what that means in the generated objects.
 +
 
 +
== Culling ==
 +
 
 +
The primary use of setting the front facing of a triangle is to allow the culling of the front or back facing triangles.
 +
 
 +
Consider a cube; this is made of 12 triangles, but 6 of them will be facing in the opposite direction from the other 6. Unless the cube is transparent, 6 of the triangles will always be covered up by the other 6. Indeed, depending on the projection, more than 6 triangles could be covered (imagine a cube that is very close to the camera, since the front face is huge).
 +
 
 +
Face culling allows non-visible triangles of closed surfaces to be culled before expensive [[Rasterization]] and [[Fragment Shader]] operations.
 +
 
 +
To activate face culling, {{enum|GL_CULL_FACE}} must first be enabled with {{apifunc|glEnable}}. By default, face culling is disabled. To select which side will be culled, use the following function:
 +
 
 +
{{funcdef|void {{apifunc|glCullFace}}(GLenum {{param|mode}});}}
 +
 
 +
{{param|mode}} can be set to {{enum|GL_FRONT}}, {{enum|GL_BACK}}, or {{enum|GL_FRONT_AND_BACK}}. The latter will cull all triangles. This is different from {{apifunc|glEnable|(GL_RASTERIZER_DISCARD)}}, as the latter will shut off ''all'' [[Primitive]]s, while culling both faces will only cull triangles (since only they have faces).
 +
 
 +
By default, {{enum|GL_BACK}} is the face to be culled.

Latest revision as of 01:04, 4 February 2015

Triangle primitives after all transformation steps have a particular facing. This is defined by the order of the three vertices that make up the triangle, as well as their apparent order on-screen. Triangles can be discarded based on their apparent facing, a process known as Face Culling.

Winding order

When the user issues a Drawing Command, the vertices processed by the Rendering Pipeline are processed in the order provided by Vertex Specification. The Geometry Shader can alter the order, but even then, the vertices created by each GS invocation are ordered relative to the other vertices. The Tessellation Evaluation Shader can directly control the order of the vertices in the tessellated patch using special options.

When vertices are broken down into Primitives during Primitive Assembly, the order of the vertices relative to the others in the primitive is noted. The order of the vertices in a triangle, when combined with their visual orientation, can be used to determine whether the triangle is being seen from the "front" or the "back" side.

This is determined by the winding order of the triangle. Given an ordering of the triangle's three vertices, a triangle can appear to have a clockwise winding or counter-clockwise winding. Clockwise means that the three vertices, in order, rotate clockwise around the triangle's center. Counter-clockwise means that the three vertices, in order, rotate counter-clockwise around the triangle's center.

File:Winding order.png

Which side is considered the "front" side is controlled by this function:

void glFrontFace(GLenum mode​);

This is global state. mode​ may be GL_CW or GL_CCW, which mean clockwise or counter-clockwise is front, respectively. On a freshly created OpenGL Context, the default front face is GL_CCW.

The Fragment Shader gets a built-in input value saying whether the fragment was generated by the triangle's front face (this will always be true for non-triangular primitives).

Tessellation

The winding order of the abstract patch vertices generated during Tessellation is controlled by the Tessellation Evaluation Shader. It is a layout option specified by the TES, rather than a runtime value. The winding order is specified in terms of the direction: cw​ and ccw​. Which is considered "front" is still defined by glFrontFace.

Note that the final winding order of any generated triangles is determined by the positions output from the TES (or a subsequent Geometry Shader. So even though the winding order specification in the TES is a fixed value for the shader, this does not mean that all triangles generated will have that winding after the TES generates positions for them. The specified order is only for the abstract patch; the TES decides what that means in the generated objects.

Culling

The primary use of setting the front facing of a triangle is to allow the culling of the front or back facing triangles.

Consider a cube; this is made of 12 triangles, but 6 of them will be facing in the opposite direction from the other 6. Unless the cube is transparent, 6 of the triangles will always be covered up by the other 6. Indeed, depending on the projection, more than 6 triangles could be covered (imagine a cube that is very close to the camera, since the front face is huge).

Face culling allows non-visible triangles of closed surfaces to be culled before expensive Rasterization and Fragment Shader operations.

To activate face culling, GL_CULL_FACE must first be enabled with glEnable. By default, face culling is disabled. To select which side will be culled, use the following function:

void glCullFace(GLenum mode​);

mode​ can be set to GL_FRONT, GL_BACK, or GL_FRONT_AND_BACK. The latter will cull all triangles. This is different from glEnable(GL_RASTERIZER_DISCARD), as the latter will shut off all Primitives, while culling both faces will only cull triangles (since only they have faces).

By default, GL_BACK is the face to be culled.