Difference between revisions of "Vertex Post-Processing"
(→Clipping: Section on clip planes.) |
(No more stub.) |
||
(8 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | {{pipeline float}} | ||
'''Vertex Post-Processing''' is the stage in the OpenGL Rendering Pipeline where the vertex outputs of the [[Vertex Processing]] undergo a variety of operations. Many of these are setup for [[Primitive Assembly]] and [[Rasterization]] stages. | '''Vertex Post-Processing''' is the stage in the OpenGL Rendering Pipeline where the vertex outputs of the [[Vertex Processing]] undergo a variety of operations. Many of these are setup for [[Primitive Assembly]] and [[Rasterization]] stages. | ||
== Transform Feedback == | == Transform Feedback == | ||
{{main|Transform Feedback}} | {{main|Transform Feedback}} | ||
+ | |||
+ | Transform feedback is a way of recording values output from the [[Vertex Processing]] stage into [[Buffer Object]]s. | ||
== Clipping == | == Clipping == | ||
+ | |||
+ | Primitives generated by previous stages are collected and then clipped to the view volume. Each vertex has a clip-space position (the {{code|gl_Position}} output of the last [[Vertex Processing]] stage). The viewing volume for a vertex is defined by: | ||
+ | |||
+ | <math> | ||
+ | \begin{align} | ||
+ | -w_c & \le x_c & \le w_c \\ | ||
+ | -w_c & \le y_c & \le w_c \\ | ||
+ | -w_c & \le z_c & \le w_c | ||
+ | \end{align} | ||
+ | </math> | ||
+ | |||
+ | This volume can be modified by [[#Depth clamping|depth clamping]] as well as the addition of [[#Clip planes|user-defined clip-planes]]. The total volume that primitives are clipped to, including user-defined clip planes, is the clipping volume. | ||
+ | |||
+ | The way primitives are clipped to this clipping volume depends on the basic [[Primitive]] type: | ||
+ | |||
+ | ; Points | ||
+ | : Points are not really "clipped". If a point is in any way outside of the clipping volume, then the primitive is discarded (ie: not rendered). Points can be bigger than one pixel, but the clipping remains; if the center of the point (the actual {{code|gl_Position}} value) is outside of the clipping range, it is discarded. Yes, this means that point sprites will disappear when the center moves off-screen. | ||
+ | : {{plat note|NVIDIA|These cards will not clip points "properly". That is, they will do what people generally want (only discard the point if it is ''fully'' off-screen), rather than what the OpenGL specification ''requires''. Be advised that other hardware does what OpenGL asks.}} | ||
+ | ; Lines | ||
+ | : If the line is entirely outside of the volume, it is discarded. If the line is partially outside of the volume, then it is clipped; new vertex coordinates are computed for one or both vertices, as appropriate. The end-point of such a clipped vertex is on the boundary of the clipping volume. | ||
+ | ; Triangles | ||
+ | : A triangle is clipped to the viewing volume by generating appropriate triangles who's vertices are on the boundary of the clipping volume. This may generate more than 1 triangle, as appropriate. If a triangle is entirely outside of the viewing volume, it is culled. | ||
+ | |||
+ | When primitives are clipped, new per-vertex outputs must be generated for them. These are generated via linear interpolation (in clip-space) of the output values. Flat-shaded outputs don't get this treatment. | ||
+ | |||
+ | === Depth clamping === | ||
+ | |||
+ | The clipping behavior against the Z position of a vertex (ie: <math>-w_c \le z_c \le w_c</math>) can be turned off by activating depth clamping. This is done with {{apifunc|glEnable|(GL_DEPTH_CLAMP)}}. This will cause the clip-space Z to remain unclipped by the front and rear viewing volume. | ||
+ | |||
+ | {{note|With perspective projections, you still get clipping with the ''sides'' of the viewing volume. Depth clamping turns a frustum into a pyramid. So objects that go behind the camera are still clipped; it's just objects between the projection near-plane and the camera who's clipping is turned off.}} | ||
+ | |||
+ | The Z value computations will proceed as normal through the pipeline. After computing the window-space position, the resulting Z value will be clamped to the {{apifunc|glDepthRange}}. | ||
=== Clip planes === | === Clip planes === | ||
+ | {{missing|section}} | ||
== Perspective divide == | == Perspective divide == | ||
+ | |||
+ | The clip-space positions returned from the clipping stage are transformed into normalized device coordinates (NDC) via this equation: | ||
+ | |||
+ | <math> | ||
+ | \begin{pmatrix} | ||
+ | x_{ndc}\\ | ||
+ | y_{ndc}\\ | ||
+ | z_{ndc} | ||
+ | \end{pmatrix} | ||
+ | = | ||
+ | \begin{pmatrix} | ||
+ | \tfrac{x_c}{w_c}\\ | ||
+ | \tfrac{y_c}{w_c}\\ | ||
+ | \tfrac{z_c}{w_c} | ||
+ | \end{pmatrix} | ||
+ | </math> | ||
== Viewport transform == | == Viewport transform == | ||
− | {{ | + | The viewport transform defines the transformation of vertex positions from NDC space to window space. These are the coordinates that are rasterized to the output image. |
+ | |||
+ | The viewport is defined by a number of viewport parameters. These parameters are set by these functions: | ||
+ | |||
+ | {{funcdef | ||
+ | |void {{apifunc|glViewport}}(GLint {{param|x}}, GLint {{param|y}}, GLsizei {{param|width}}, GLsizei {{param|height}}) | ||
+ | |void {{apifunc|glDepthRange}}(GLdouble {{param|nearVal}}, GLdouble {{param|farVal}}) | ||
+ | |||
+ | |void {{apifunc|glDepthRange|f}}(GLfloat {{param|nearVal}}, GLfloat {{param|farVal}}) | ||
+ | }} | ||
+ | |||
+ | The second two functions set the same parameters, the near and far values of the depth range. | ||
+ | |||
+ | Given the viewport parameters, we compute the window-space coordinates via these equations: | ||
+ | |||
+ | <math> | ||
+ | \begin{pmatrix} | ||
+ | x_w\\ | ||
+ | y_w\\ | ||
+ | z_w | ||
+ | \end{pmatrix} | ||
+ | = | ||
+ | \begin{pmatrix} | ||
+ | \begin{align} | ||
+ | \tfrac{width}{2}x_{ndc} & + x + \tfrac{width}{2}\\ | ||
+ | \tfrac{height}{2}y_{ndc} & + y + \tfrac{height}{2}\\ | ||
+ | \tfrac{farVal - nearVal}{2}z_{ndc} & + \tfrac{farVal + nearVal}{2} | ||
+ | \end{align} | ||
+ | \end{pmatrix} | ||
+ | </math> | ||
+ | |||
+ | Where {{param|x}}, {{param|y}}, {{param|width}}, {{param|height}}, {{param|nearVal}}, and {{param|farVal}} are the viewport parameters. | ||
+ | |||
+ | === Viewport array === | ||
+ | {{infobox feature | ||
+ | | name = Viewport Arrays | ||
+ | | core = 4.1 | ||
+ | | core_extension = {{extref|viewport_array}} | ||
+ | }} | ||
+ | |||
+ | Multiple viewports can be used in OpenGL. The specific [[Geometry Shader#Layered rendering|viewport for a particular primitive can be set by the Geometry Shader]]. If the GS does not specify a viewport, then viewport number 0 is selected. The computation works as above, except where it says "the viewport parameters", it means "the viewport parameters for the primitive's viewport index". | ||
+ | |||
+ | There are sets of viewports, indexed on the half-open range [0, {{enum|GL_MAX_VIEWPORTS}}). Each index has its own depth range and viewport coordinates. The previously defined functions will only set the value for viewport index 0. | ||
+ | |||
+ | To set the viewport parameters for a particular index, use this pair of functions: | ||
+ | |||
+ | {{funcdef | ||
+ | |void {{apifunc|glViewportIndexed|f}}(GLuint {{param|index}}, GLfloat {{param|x}}, GLfloat {{param|y}}, GLfloat {{param|w}}, GLfloat {{param|h}}) | ||
+ | |void {{apifunc|glViewportIndexed|fv}}(GLuint {{param|index}}, const GLfloat *{{param|v}}) | ||
+ | |||
+ | |void {{apifunc|glDepthRangeIndexed}}(GLuint {{param|index}}, GLdouble {{param|nearVal}}, GLdouble {{param|farVal}}) | ||
+ | }} | ||
+ | |||
+ | The {{param|index}} is the viewport index to set the parameters for. {{apifunc|glViewportIndexed|fv}} takes an array of 4 floats, in the same orders as the parameters for {{apifunc|glViewportIndexed|f}}. | ||
+ | |||
+ | Multiple viewport indices can be set with a single function, via these APIs: | ||
+ | |||
+ | {{funcdef | ||
+ | |void {{apifunc|glViewportArray|v}}(GLuint {{param|first}}, GLsizei {{param|count}}, const GLfloat *{{param|v}}) | ||
+ | |void {{apifunc|glDepthRangeArray|v}}(GLuint {{param|first}}, GLsizei {{param|count}}, const GLdouble *{{param|v}}) | ||
+ | }} | ||
+ | |||
+ | The {{param|first}} index is the first viewport index to set. {{param|count}} is the number of viewport indices to be set by the function. {{param|v}} is an array of viewport values, which contains {{param|count}} * 4 or 2 values, depending on the function being called. The values for a single viewport index are in the same order as the arguments in the regular function calls. | ||
+ | |||
+ | == See also == | ||
+ | |||
[[Category:General OpenGL]] | [[Category:General OpenGL]] |
Revision as of 20:07, 9 February 2013
- Vertex Specification
- Vertex Processing
- Vertex Post-Processing
- Primitive Assembly
- Rasterization
- Fragment Shader
- Per-Sample Processing
Vertex Post-Processing is the stage in the OpenGL Rendering Pipeline where the vertex outputs of the Vertex Processing undergo a variety of operations. Many of these are setup for Primitive Assembly and Rasterization stages.
Contents
Transform Feedback
Transform feedback is a way of recording values output from the Vertex Processing stage into Buffer Objects.
Clipping
Primitives generated by previous stages are collected and then clipped to the view volume. Each vertex has a clip-space position (the gl_Position output of the last Vertex Processing stage). The viewing volume for a vertex is defined by:
This volume can be modified by depth clamping as well as the addition of user-defined clip-planes. The total volume that primitives are clipped to, including user-defined clip planes, is the clipping volume.
The way primitives are clipped to this clipping volume depends on the basic Primitive type:
- Points
- Points are not really "clipped". If a point is in any way outside of the clipping volume, then the primitive is discarded (ie: not rendered). Points can be bigger than one pixel, but the clipping remains; if the center of the point (the actual gl_Position value) is outside of the clipping range, it is discarded. Yes, this means that point sprites will disappear when the center moves off-screen.
- Lines
- If the line is entirely outside of the volume, it is discarded. If the line is partially outside of the volume, then it is clipped; new vertex coordinates are computed for one or both vertices, as appropriate. The end-point of such a clipped vertex is on the boundary of the clipping volume.
- Triangles
- A triangle is clipped to the viewing volume by generating appropriate triangles who's vertices are on the boundary of the clipping volume. This may generate more than 1 triangle, as appropriate. If a triangle is entirely outside of the viewing volume, it is culled.
When primitives are clipped, new per-vertex outputs must be generated for them. These are generated via linear interpolation (in clip-space) of the output values. Flat-shaded outputs don't get this treatment.
Depth clamping
The clipping behavior against the Z position of a vertex (ie: ) can be turned off by activating depth clamping. This is done with glEnable(GL_DEPTH_CLAMP). This will cause the clip-space Z to remain unclipped by the front and rear viewing volume.
The Z value computations will proceed as normal through the pipeline. After computing the window-space position, the resulting Z value will be clamped to the glDepthRange.
Clip planes
This section is missing information. Further details can be found on the talk page. |
Perspective divide
The clip-space positions returned from the clipping stage are transformed into normalized device coordinates (NDC) via this equation:
Viewport transform
The viewport transform defines the transformation of vertex positions from NDC space to window space. These are the coordinates that are rasterized to the output image.
The viewport is defined by a number of viewport parameters. These parameters are set by these functions:
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) void glDepthRange(GLdouble nearVal, GLdouble farVal)
void glDepthRangef(GLfloat nearVal, GLfloat farVal)
The second two functions set the same parameters, the near and far values of the depth range.
Given the viewport parameters, we compute the window-space coordinates via these equations:
Where x, y, width, height, nearVal, and farVal are the viewport parameters.
Viewport array
Core in version | 4.5 | |
---|---|---|
Core since version | 4.1 | |
Core ARB extension | ARB_viewport_array |
Multiple viewports can be used in OpenGL. The specific viewport for a particular primitive can be set by the Geometry Shader. If the GS does not specify a viewport, then viewport number 0 is selected. The computation works as above, except where it says "the viewport parameters", it means "the viewport parameters for the primitive's viewport index".
There are sets of viewports, indexed on the half-open range [0, GL_MAX_VIEWPORTS). Each index has its own depth range and viewport coordinates. The previously defined functions will only set the value for viewport index 0.
To set the viewport parameters for a particular index, use this pair of functions:
void glViewportIndexedf(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h) void glViewportIndexedfv(GLuint index, const GLfloat *v)
void glDepthRangeIndexed(GLuint index, GLdouble nearVal, GLdouble farVal)
The index is the viewport index to set the parameters for. glViewportIndexedfv takes an array of 4 floats, in the same orders as the parameters for glViewportIndexedf.
Multiple viewport indices can be set with a single function, via these APIs:
void glViewportArrayv(GLuint first, GLsizei count, const GLfloat *v) void glDepthRangeArrayv(GLuint first, GLsizei count, const GLdouble *v)
The first index is the first viewport index to set. count is the number of viewport indices to be set by the function. v is an array of viewport values, which contains count * 4 or 2 values, depending on the function being called. The values for a single viewport index are in the same order as the arguments in the regular function calls.