Something about clipping windows

Have a question, suggestion, or comment about Aleph One's features and functionality (Lua, MML, the engine itself, etc)? Post such topics here.
Post Reply
Qweasy908
Cyborg
Posts: 86
Joined: Jul 18th '18, 22:45

I've tried to make sense how the clipping windows work reading the source code.
My guess is it starts with the player camera as a clipping window that clips all the polygons in the root node and then the clipping windows clip the next room with polygons.

Clipping can be used to find portals?

Everything is in screen space when lines intersect lines.
It uses a raycast to split the polygon walls and make new walls.
I tried this in Unity and making clipped polygons is slow, but that is how I think it works.
The view through portals gets smaller clipping everything.

If everything is in screen space, the walls will need to be clipped so the vertices don't go behind the camera.
Qweasy908
Cyborg
Posts: 86
Joined: Jul 18th '18, 22:45

I don't fully understand clipping windows in Aleph One, but I've come up with something that could work in Unity.

Aleph One is a portal renderer, but has no mention of portals in the source code.

Instead of making walls from clipped polygons, I could get the clipped points and if the clipped points are greater than 2 then the polygon is drawn.
Getting the clipped points is faster.
Then I get a function that takes the view frustum and sector to clip a list of polygons in the sector.
If the polygon has a adjacent sector then put that polygon in a queue and add mathematical planes around the portal to do clipping.
The polygon with a adjacent sector holds the mathematical planes and sector.
Every visible portal has a frustum of mathematical planes to clip it's sector polygons.
If you get too close to a polygon then it is visible and the main camera does the clipping to clip the adjacent sector.
The clipping I'm using is plane line intersection.
Polygons are made of lines and vertices.
For better clipping I use the GPU and the mathematical planes to discard geometry.

When I load a level I put each polygon into a polygon class and render it if its a polygon and if its a portal then get the adjacent sector.
User avatar
LidMop
Spazeroid
Posts: 6
Joined: Jan 2nd '19, 20:18

Clipping windows are subsets of the camera view used to cull some occluded portions of geometry in order to reduce overdraw and support 5D space rendering. They are defined as 4 clip planes that intersect the camera position, left/right/top/bottom. However, top/bottom are used only by the software renderer, and they don't help with rendering 5D space, so let's ignore them.

Each visible polygon (sorted_node_data) is associated with a list of clipping windows (.clipping_windows) that describes sub-FOVs (cones) in which that polygon's surfaces are not occluded by an opaque wall or screen edge. Each window boundary lines up with a boundary of occlusion, which is either a vertex or a (virtual) screen edge. (The "screen" for this purpose is virtual and wider than the actual screen in the OpenGL renderer in order to support three-point perspective.)

In this example, the yellow polygon has 2 clipping windows shown in green, essentially defined as {A, B} and {C, screen_right}.

Image

The renderer (software or OpenGL) essentially draws the geometric intersection of a given entity and the union of its associated clipping windows. The way it achieves this is by drawing the entity once per window, each time clipped to just that window (see the window list loops in RenderRasterizerClass::render_node). This works even for OpenGL alpha-blending cases because windows in a list never overlap horizontally.

The software renderer calculates the clipped result of individual polygonal shapes manually, whereas the OpenGL renderer just throws that work to the GPU by using glClipPlane() (another way would be to use gl_ClipDistance in a vertex shader).

5D space is supported automatically by this per-polygon clipping scheme. In this example, polygons 1 and 2 overlap, but their clipping windows do not, so they aren't drawn over each other.

Image

The really complex part is finding the clipping windows in the first place. The raycasting process in build_render_tree() eventually hits every visible vertex. If a sightline ray hits an opaque vertex (a vertex of an opaque wall) but can continue on into the strict interior of another polygon (i.e. the polygon straddles the ray), that means the vertex is an occlusion boundary (endpoint_clip_data) for that polygon and also for every farther polygon that also straddles the ray. A1 detects this case with the help of decide_where_vertex_leads() and the complicated "split rays around both sides of a vertex" behavior, and it does some bookkeeping to record every such occurance (node_data::clipping_endpoints) within the vistree. After the vistree is complete, build_clipping_windows() is called for every visible polygon in order to collect and sort its associated set of endpoint_clip_data into pairs of left and right clip planes, i.e. clipping windows. (Note: ignore line_clip_data; it's just for top/bottom clip planes.)

(Edit: replaced "vertex" with "opaque vertex")
Qweasy908
Cyborg
Posts: 86
Joined: Jul 18th '18, 22:45

Thanks for sharing how it works, I can study the code better with this.

I've used 2D cross product to find vertices in the cones and line clipping when the cone edge is on a portal line.

To get Aleph One's 5D space working in Unity, I'd have to code it in C# and load map data.
User avatar
LidMop
Spazeroid
Posts: 6
Joined: Jan 2nd '19, 20:18

Correction: I just confirmed that the software renderer relies on clipping windows to correctly render not just 5D space, but more generally any situation where 2 visible polygons overlap in both world xy and screen space, because the software renderer doesn't use depth buffering and polygon sorting ignores height. The OpenGL renderer does use depth buffering, but must still use clipping windows for 5D space.
User avatar
LidMop
Spazeroid
Posts: 6
Joined: Jan 2nd '19, 20:18

the software renderer relies on clipping windows to correctly render not just 5D space, but more generally any situation where 2 visible polygons overlap in both world xy and screen space, because the software renderer doesn't use depth buffering and polygon sorting ignores height.
This isn't quite right either; let me try again.

Currently, polygon sorting is "partial"; it merely performs a topological sort and doesn't bother enforcing that "sibling" polygons (polygons with the same parent polygon in the vistree) be in back-to-front order.
  • Correctly rendering 5D space requires clipping windows + partial sorting (EDIT: or, I think, clipping windows + depth buffering).
  • Correctly rendering normal space requires 1) depth buffering, or 2) full sorting, or 3) clipping windows + partial sorting.
Post Reply