Heuristic42
Blog
Opengl
Meta
Rendering
1
comment
Jan 25 at 16:20
Matrices
[deleted]
–
anonymous
created
Jan 17 at 21:12
Embedding GDB pretty printers, just like natvis
Pretty printers are awesome, but the setup can be a real pain. …
–
pknowles
comment
Jan 14 at 15:46
Matrices
[deleted]
–
anonymous
comment
Jan 13 at 16:05
Making a real EMF Reader
All good/my bad. A half implemented feature that I really shoul…
–
pknowles
comment
Jan 13 at 16:03
Making a real EMF Reader
I don't have a circuit diagram sorry. The LEDs are all on separ…
–
pknowles
comment
Jan 9 at 8:07
Making a real EMF Reader
а есть подробные схемы что к чему подключать и куда припаивать…
–
anonymous
comment
Jan 5 at 2:00
Matrices
[deleted]
–
anonymous
comment
Dec 15 '24
Matrices
[deleted]
–
anonymous
comment
Nov 27 '24
DerBard: Custom Split Mechanical Keyboard Prototype
hello
–
anonymous
comment
Nov 19 '24
Matrices
[deleted]
–
anonymous
created
Oct 20 '24
Iterators: pointers vs cursors
You're already doing both of these by hand. This post emphaisze…
–
pknowles
comment
Oct 10 '24
Matrices
[deleted]
–
anonymous
comment
Oct 4 '24
Matrices
[deleted]
–
anonymous
comment
Sep 30 '24
Matrices
[deleted]
–
anonymous
comment
Sep 23 '24
Matrices
[deleted]
–
anonymous
comment
Sep 21 '24
Contributing
I kind of predicted what was bound to happen when my favourite …
–
anonymous
comment
Sep 7 '24
Route contention when running docker and a VPN
Thank you for this. Between this and the overwriting of iptabl…
–
anonymous
comment
Sep 6 '24
Making a real EMF Reader
Sorry for the random quoted text comments. I am one of those p…
–
anonymous
comment
Sep 6 '24
Making a real EMF Reader
[deleted]
–
anonymous
comment
Sep 6 '24
Making a real EMF Reader
[deleted]
–
anonymous
comment
Aug 20 '24
Matrices
[deleted]
–
anonymous
comment
Aug 11 '24
Matrices
[deleted]
–
anonymous
edited
Jun 8 '24
Rethinking writing files with memory mapping and C++
This post introduces the motivation behind the [decodless C++ o…
–
admin
created
Jun 8 '24
Rethinking writing files with memory mapping and C++
This post introduces the motivation behind the [decodless C++ o…
–
pknowles
…
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