Heuristic42
Blog
Opengl
Meta
Rendering
0
comment
Dec 15 at 4:39
Matrices
Hello! Are you looking to elevate your online business with a p…
–
anonymous
comment
Nov 27 at 0:30
DerBard: Custom Split Mechanical Keyboard Prototype
hello
–
anonymous
comment
Nov 19 at 15:47
Matrices
[deleted]
–
anonymous
created
Oct 20 at 20:30
Iterators: pointers vs cursors
You're already doing both of these by hand. This post emphaisze…
–
pknowles
comment
Oct 10 at 10:27
Matrices
[deleted]
–
anonymous
comment
Oct 4 at 19:12
Matrices
[deleted]
–
anonymous
comment
Sep 30 at 18:51
Matrices
[deleted]
–
anonymous
comment
Sep 23 at 16:15
Matrices
[deleted]
–
anonymous
comment
Sep 21 at 6:52
Contributing
I kind of predicted what was bound to happen when my favourite …
–
anonymous
comment
Sep 7 at 1:21
Route contention when running docker and a VPN
Thank you for this. Between this and the overwriting of iptabl…
–
anonymous
comment
Sep 6 at 17:57
Making a real EMF Reader
Sorry for the random quoted text comments. I am one of those p…
–
anonymous
comment
Sep 6 at 17:48
Making a real EMF Reader
["ove! Play a tone with a buzzer and has 5 LEDs to show the “EM…
–
anonymous
comment
Sep 6 at 17:47
Making a real EMF Reader
["easure direction Measure the magnetic fie"](#q107-644-685)
–
anonymous
comment
Aug 20 at 17:01
Matrices
[deleted]
–
anonymous
comment
Aug 11 at 22:32
Matrices
[deleted]
–
anonymous
edited
Jun 8 at 22:29
Rethinking writing files with memory mapping and C++
This post introduces the motivation behind the [decodless C++ o…
–
admin
created
Jun 8 at 22:16
Rethinking writing files with memory mapping and C++
This post introduces the motivation behind the [decodless C++ o…
–
pknowles
comment
Jun 5 at 13:36
Contributing
[deleted]
–
anonymous
comment
Apr 19 at 11:24
Matrices
[deleted]
–
anonymous
comment
Apr 13 at 0:25
Matrices
[deleted]
–
anonymous
comment
Apr 5 at 9:43
Matrices
[deleted]
–
anonymous
comment
Mar 27 at 17:19
Matrices
[deleted]
–
anonymous
comment
Mar 25 at 4:59
Matrices
[deleted]
–
anonymous
comment
Mar 5 at 15:39
Matrices
[deleted]
–
anonymous
…
View All
Log in
Clip Space
leave this field blank to prove your humanity
Slug
*
A URL path component
Parent page
<root>
rendering/:Article2:3D Rendering (Computer Graphics)
--- rendering/cameras/:Article11:Cameras
--- rendering/matrices/:Article12:Matrices
------ rendering/matrices/projection/:Article14:Projection Matrix
--- rendering/vectors/:Article13:Vectors
--- rendering/geometry/:Article62:3D Geometry
------ rendering/geometry/triangle_meshes/:None
--- rendering/shading/:Article64:Shading
------ rendering/shading/transparency/:Article70:Transparency and Alpha Blending
--- rendering/lights/:Article65:Lights
--- rendering/rasterization/:None
------ rendering/rasterization/deepimage/:Article72:Deep Image
--- rendering/shadows/:Article67:Shadows
--- rendering/spaces/:Article68:Vector Spaces
------ rendering/spaces/tangent_space/:Article69:Tangent Space
------ rendering/spaces/clip_space/:Article89:Clip Space
--- rendering/rotations/:None
--- rendering/images/:Article74:<unset>:Images
------ rendering/images/mipmapping/:Article75:<unset>:Mipmapping
--- rendering/materials/:None
opengl/:Article3:OpenGL Tutorials
--- opengl/oit/:Article7:Order Independent Transparency (OIT)
--- opengl/framebuffer/:Article71:The Framebuffer
meta/:Article4:Pages About This Site
--- meta/contribute/:Article5:Contributing
--- meta/bugs/:Article9:Bugs
--- meta/about/:Article10:Why does this website exist?
The parent page this belongs to.
Article title
*
Article revisions must have a non-empty title
Article body
*
Clip space is a linearly dependent vector space between eye space and *normalized device coordinates* (NDC). See [Spaces](/18/rendering/spaces/). It is where the viewing volume is finally defined, by: $$ -w \geq x \geq w $$ $$ -w \geq y \geq w $$ $$ -w \geq z \geq w $$ Geometry is typically clipped to be inside this volume. This is somewhat straight forward for lines and more complex for triangles, which may require multiple triangles to render after clipping. By convention, vectors in clip space are normalized with a [perspective divide](/11/rendering/matrices/projection/#clip-space-and-the-perspective-divide) to take them to NDC. The purpose of this page is to cover some of the maths and geometric oddities when working in clip space. A good presentation of clipping in clip space is at [chaosinmotion.com](https://chaosinmotion.com/2016/05/22/3d-clipping-in-homogeneous-coordinates/comment-page-1/). # Interpolation When working in clip space, vectors can mostly be dealt with the same as 3D but just with another component. For exmaple, the point $p$ at $t$ along a line between two vertices $\mathbf{a}$ and $\mathbf{b}$ in clip space is simply: $$ \mathbf{p} = \mathbf{a} (1 - t) + \mathbf{b} t $$ Computing perspective correct depth $d$ with a perspective divide is then: $$ d = \mathbf{p}_z / \mathbf{p}_w $$ If instead $\mathbf{a}$ and $\mathbf{b}$ were normalized before interpolation, the result would be incorrect. As a general rule, perform the perspective divide at the last moment, right when a 2D screen position or non-linear depth is needed. # Line--Plane Intersections Starting with just the left plane, $-w \geq x$. This inequality defines a deceptively simple plane equation in cartesian coordinates: $$x + w = 0$$ Think of this as a plane in 4D space intersecting the origin and with the normal $(1, 0, 0, 1)$. To find the intersection with a line $\mathbf{o} + \mathbf{d} t$ , plug the line equation into $x - w = 0$ and solve for t: $$(\mathbf{o}_x + \mathbf{d}_x t) - (\mathbf{o}_w + \mathbf{o}_w t) = 0$$ $$t = -\frac{\mathbf{o}_x + \mathbf{o}_w}{\mathbf{d}_w + \mathbf{d}_x}$$ For the positive $x$ clipping plane: $$t = \frac{\mathbf{o}_x - \mathbf{o}_w}{\mathbf{d}_w - \mathbf{d}_x}$$ This can almost be thought of as intersecting with an axis aligned box, plus a linearly dependent $w$. Unfortunately that tantalising simplicity is not so. One surprise is that even in the case $\mathbf{o}_x = 0$ and $\mathbf{d}_x > 0$, $t$ may be negative because $w$ in $x - w = 0$ "out-runs" in the $+t$ direction. For a regular axis aligned intersection this wouldn't happen --- if a line moves in positive $x$; it must hit axis-aligned planes in that direction. ![enter image description here][1] It's easy to see this geometrically when thinking about a perspective frustum. The gradient of the line's direction is simply not low enough to intersect the right hand clipping plane in the positive direction. It still intersects the right hand plane, just at negative $t$. In fact this intersection occurrs outside the viewing volume, which is another surprise. Both left and right clipping planes place lower $t$ bounds on this line and the $x$ axis has no upper bound on $t$. This complicates a general intersection algorithm. # Inside and Outside An easy algorithm to clip a line to a box is to first compute the intersection times $t$ of the axis aligned planes. Then sort them into $t_0$ and $t_1$ for each axis --- there's only two, so it's not much of a sort. Finally $t_0 = \max(t_{x0}, t_{y0}, t_{z0})$ and $t_1 = \min(t_{x1}, t_{y1}, t_{z1})$. This works for a bounding box because the first of two intersections on each axis is always the lower bound of the box and the second is always the upper bound. As described above, the same does not work for clipping against perspective projections. ![perspective clipping][2] As seen in the figure above, intersections on opposing planes may be both lower (in this case, shown in green) or both upper bounds on $t$. What is needed is a test for the side of the plane the line hits. Continuing the example above for a line $\mathbf{o} + \mathbf{d} t$. In the general case, a line hits the front of a plane if its direction vector $\mathbf{d}$ is opposite the plane's normal vector $\mathbf{n}$. The normal vectors for clipping planes are simply: $$(1, 0, 0, 1) \text{left}$$ $$(-1, 0, 0, 1) \text{right}$$ $$(0, 1, 0, 1) \text{bottom}$$ $$(0, -1, 0, 1) \text{top}$$ $$(0, 0, 1, 1) \text{near}$$ $$(0, 0, -1, 1) \text{far}$$ If $\mathbf{d} \cdot (1, 0, 0, 1) < 0$, i.e. $\mathbf{d}_x + \mathbf{d}_w < 0$, then the line will hit the left clipping plane coming from the right hand side, meaning the time of intersection $t$ (see the section above) becomes an upper limit to clip the line's $t_1$ to. If the inequality is false then the line hits the left clipping plane coming from the left and $t$ should instead be a lower limit on the line's $t_0$. For an example of this in use, see [this frustum clipping shadertoy](https://www.shadertoy.com/view/ctV3zc). [1]: https://img.heuristic42.com/img/675ebe68cd3a.svg [2]: https://img.heuristic42.com/img/4ec909adeb9d.svg
Toggle Preview
Edit message
*
A description of the changes made
Discard Draft
Save Draft
leave this field blank to prove your humanity
Flag
the thing you clicked
for moderator attention.
Reason choice:
Spam, promoting, advertising without disclosure
Rude, inappropriate, generally offensive
Too arrogant or demeaning to others
Other
Reason:
The reason for raising the flag
Error