Heuristic42
Blog
Opengl
Rendering
Meta
0
edited
Oct 13 at 8:08
Why std::move and move semantics?
For years C++ destructors felt like an academic solution that d…
–
pknowles
comment
Oct 13 at 6:39
Clip Space
Thanks for the reminder. Please see [https://www.heuristic42.co…
–
pknowles
comment
Oct 11 at 4:27
Contributing
I have bilateral carpel tunnel and my Microsoft 4k has a torn c…
–
anonymous
edited
Oct 6 at 10:28
Pages About This Site
... in an effort to keep presented content and self discussion …
–
admin
created
Oct 6 at 10:20
Privacy and Data Collection
This wiki stores a small amount of personal data to function an…
–
admin
comment
Sep 12 at 19:24
Clip Space
Hello, We ran a 30-second scan of your domain and found: - …
–
anonymous
created
Jul 7 at 11:21
Hello Ray, a Hello World Vulkan Ray Tracing Tutorial
\*WORK IN PROGRESS\* Want to do some quick 3D graphics progr…
–
pknowles
created
Jul 4 at 6:54
Why std::move and move semantics?
A few years ago, I was fortunate enough to have Jon Kalb explai…
–
pknowles
edited
Jul 4 at 5:15
3D Rendering (Computer Graphics)
Rendering in 3D computer graphics is computing a 2D image from …
–
pknowles
edited
Jul 4 at 4:16
Heuristic42, A Graphics Programming Website
#[Blog](/blog/) An unstructured assortment of personal graph…
–
pknowles
edited
Jun 24 at 15:10
RAII++ - the powerful implication of always initializing
If you search, most definitions of RAII refer to using "**scope…
–
pknowles
created
Jun 24 at 15:01
RAII++ - the powerful implication of always initializing
If you search, most definitions of RAII refer to using "**scope…
–
pknowles
comment
Jun 15 at 11:42
Matrices
[deleted]
–
anonymous
comment
Jun 1 at 11:01
Matrices
[deleted]
–
anonymous
comment
May 18 at 22:30
Matrices
[deleted]
–
anonymous
created
Apr 10 at 12:38
test2
;</script>
–
Nia
comment
Feb 8 at 6:26
Matrices
[deleted]
–
anonymous
edited
Feb 3 at 7:54
Embedding GDB pretty printers, just like natvis
Pretty printers are awesome, but the setup can be a real pain. …
–
pknowles
created
Feb 1 at 12:27
Embedding GDB pretty printers, just like natvis
Pretty printers are awesome, but the setup can be a real pain. …
–
pknowles
comment
Jan 26 at 8:20
Matrices
[deleted]
–
anonymous
comment
Jan 15 at 7:46
Matrices
[deleted]
–
anonymous
comment
Jan 14 at 8:05
Making a real EMF Reader
All good/my bad. A half implemented feature that I really shoul…
–
pknowles
comment
Jan 14 at 8:03
Making a real EMF Reader
I don't have a circuit diagram sorry. The LEDs are all on separ…
–
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?
--- meta/privacy/:Article107:Privacy and Data Collection
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