# Portal Rendering

{ I haven't yet gotten to implementing a portal renderer so it's possible I make a wrong claim here by mistake, but I'll try not to :) ~drummyfish }

Portal rendering is a method of [3D rendering](3d_rendering.md) that treats the rendered environment as spaces (e.g. rooms) connected by portals (doors, windows, ...) which allows fast and simple determination of visibility and therefore fast and simple rendering. It was a quite popular way of 3D rendering for example in the old 1990s 3D [games](game.md) such as [Descent](descent.md) and [Duke Nukem](duke3d.md).

The **basic general idea** is to represent the 3D environment as a set of "rooms" (generally any [subdivision](subdivision.md) unit of space, not just "house rooms" of course) and their connections to other rooms through portals ("holes", shared walls through which one room connects to another); then when rendering we simply draw the room the camera resides in (from the inside) and proceed to draw the rooms that are connected by portals which are now visible on the screen, treating each of those portals as a kind of new smaller screen (i.e. a [clipping](clipping.md) window). Then we go on to [recursively](recursion.md) draw portals in those rooms again etc. until some terminating condition is met (e.g. all screen pixels are covered or we have reached maximum draw depth etc.). A limitation imposed on a room is often that it has to be [convex](convex.md) so that its "from the inside" rendering is simple; non-convex spaces are then simply split into multiple convex ones -- [EZ](ez.md).

Just as similar methods like [raycasting](raycasting.md) and [BSP](bsp.md) rendering, portal rendering can be used in various ways, it is not a simple [algorithm](algorithm.md) but rather a method, approach to rendering. It may also be used just as a "helper" for visibility determination in another method. Notably there is a "full 3D" (*Descent*) and "2D" (*Duke Nukem*), sector based version of portal rendering. They are all based on the same principle but may have different limitations etc.

**Advantages** of portal rendering:

- **It can work without [precomputation](precomputation.md)**, which is a huge plus compared e.g. to [BSP](bsp.md) rendering (though optional precomputations such as [PVS](pvs.md) can of course be always employed). This among others saves time (precomputing can take a while), program complexity and space (no need to store extra precomputed data).
- **The environment can be [dynamic](dynamic.md)** (change on the fly, consider e.g. destructible or animated environment), thanks to not needing precomputed data. This was made advantage of in Build engine games a lot, while in Doom only wall and ceiling height could change on the run.
- **Impossible geometry can be created** -- as we may create any arbitrary spaces that connect to each other, it is possible to for example create a house that's bigger on the inside than on the outside, or a curved tunnel that would in reality intersect itself but doesn't. We can even have **room above room in the 2D version** (though in vanilla version there can't be two VISIBLE rooms above one another).
- **Effect such as mirrors are easy** -- a mirror may be just a portal that connects to the same room in opposite way.
- **There is no [overdraw](overdraw.md)**, a problem that plagues many 3D renderers, so **we don't need [z-buffer](z_buffer.md)** and may probably hack the method to not even [need](dependency.md) a [frame buffer](frame_buffer.md). This is pretty awesome, may reduce memory requirements greatly and allow things such as [frameless rendering](frameless.md). However z-buffer and [double buffering](double_buffering.md) are still mostly used so as to allow additional correct rendering of overlays to the environments, e.g. "2D [sprites](billboard.md)".
- For mentioned reasons the method is relatively simple, efficient and [software rendering](sw_rendering.md) friendly, making it a good candidate for weak computers.
- ...

TODO

## 2D Portal Rendering

TODO