Log In  

Cart #portalsaurus-1 | 2021-10-01 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA

Cart #portalsaurus-0 | 2021-07-25 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA


Recently I decided to dig into portal renderers and start to build my own, inspired by this excellent write-up of BUILD. This is currently work in progress, no guarantee it will turn into a full game but thought it was interesting enough to share.

I used a lot of stuff from other projects

From Caped Feline Arena

  • Player movement
  • Floor and sky casting
  • Palette functions

From Cab Ride

  • Palette

I also revisited Lodev's raycasting articles, specifically the code to render sprites without fisheye distortion as they behave similarly to the ends of the walls.

Implementation Notes


  • New features including
  • Variable height sectors!
  • Distance based lighting!
  • Large performance gains!
  • Island sectors!
  • This is all thanks for being a bit smarter about how many walls to cast each ray for
  • After flooding portals, the walls of each sector are grouped into subgroups (referred to in BUILD terminology as 'bunches')
  • The bunches are ordered near-far (thanks to traversing the portal graph)
  • Island sectors get inserted before other bunches an enclosing sector (this would cause glitches with concave sectors, out of scope for now)
  • Walls within a bunch are ordered near-far, and projected into screen space, where they are further chopped down, grouped by walls that touch at one end
  • Portals take account of differences in sector height - this allows for doorways/overhangs
  • A very simple buffer keeps track of which x coordinates have had a wall drawn, to prevent overdraw of walls
  • Rays are cast for the walls nearest bunch (from the lowest to highest x coordinate). If a hit is recorded, the 'x buffer' is updated, so no further drawing happens - that coordinate is now occluded
  • Palette is set for each vertical slice of wall, based on distance from the camera

Original post:

  • At the moment it relies on casting a ray for every column of the screen to determine which walls to draw
  • One wall per column at the moment
  • Casting a ray traverses a subset of potentially visible walls
  • Potentially visible walls are calculated by traversing the portals in the world structure, starting with the 'sector' the player/camera currently occupies
  • World is represented by sectors, which hold references to a set of walls that border the sector
  • A portal is a wall shared by two sectors
  • Traversing the world tests which walls of a sector are in front of the camera, if any wall is a portal, it is currently discarded and the connected sector is visited, up to a hard limit of 10
  • The current sector of the player/camera (or starting sector for rendering) is determined by casting a ray to the left and the number of intersections with walls is counted. Even means outside the sector (and connected sectors are tested), odd means within the sector. A short description of this is found in the 'Inside a concave polygon' of the BUILD write-up
  • The world is created when the cart starts and builds a model of how sectors are connected to each other
  • tline() is used for floor and sky
  • No collision detection currently


  • Arrow keys - move around
  • X - toggle map view (off by default)
  • C/Z - strafe

Next up??? Maybe?

  • More performance
  • Sector based floor textures
  • Collision detection
  • / 'Island' sectors for columns
  • Basic level editor
P#95261 2021-07-25 07:30 ( Edited 2021-10-01 14:19)

how do you plan to have rooms with different floor/ceiling?
do you have the (convex) polygon that is making up a room?

P#95291 2021-07-25 20:29

@freds72 - not 100% sure yet about different floor and ceiling heights (making all of this up as I go along/read). Next bit I'm reading up on is occlusion arrays which will help with this. I'm expecting I will have to ditch the 'raycaster' bit of this soon as I think it will make this difficult.

re: Convex polgons - not yet. Concave sectors give odd results, I think due to the order of checking a ray colliding with walls.

P#95295 2021-07-25 22:01

thanks - I meant different textures ;)

P#95308 2021-07-26 07:45

haha, not sure about that yet! :) Just used a looping area of the map to get something on the screen.

P#95317 2021-07-26 21:36

minor fix to correct texture alignement with vertical subpixel grid - much pleasing to the eye :]

Cart #zizebebano-0 | 2021-11-10 | Code ▽ | Embed ▽ | No License

P#99675 2021-11-06 08:21 ( Edited 2021-11-10 20:10)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2023-12-02 14:39:32 | 0.019s | Q:23