A simple, somewhat reusable, Azur raycaster.
Go to file
Lephenixnoir a2c4fbcfd1
fix angle overflow freeze
Would freeze upon angle reaching about -367.5 or 416.2 likely due to
numerical error. Reported and reproduced by Rainning_Tacos1.
2024-04-30 12:04:54 +02:00
assets split library and example + add README 2024-03-17 23:05:03 +01:00
azuray fix texture size being hardcoded to 16 in one spot 2024-03-17 23:21:13 +01:00
src fix angle overflow freeze 2024-04-30 12:04:54 +02:00
.gitignore initial commit 2024-03-10 00:28:30 +01:00
CMakeLists.txt split library and example + add README 2024-03-17 23:05:03 +01:00
README.md split library and example + add README 2024-03-17 23:05:03 +01:00
screenshot.jpg split library and example + add README 2024-03-17 23:05:03 +01:00

README.md

Azuray: an optimized Azur raycaster

This is a raycaster that I let myself get distracted into making while I should have been working on PythonExtra. It started out pretty simple and remains feature-limited but has quite a number of optimizations that lead to a consistent 35-45 FPS when there isn't a ton of overdraw.

Features:

  • Can specify each wall independently (i.e. wall-based not block-based)
  • Supports flat colored walls, full opaque and partly transparent walls (but abusing transparency drops performance)
  • Kinda fast
  • Zero real world testing (that's a feature right?)

Check src/ for the example code on how to use it, azuray/ for the engine implementation.

In terms of design, this is your standard raycaster. The whole schtick is that walls are made of vertical stripes of constant camera depth. The floor is also made of horizontal stripes of constant camera depth. In both cases this makes the pixel-to-world coordinate change linear, meaning everything is fast.

Fitting this into Azur is trickier than it looks. Azur has horizontal fragments so vertical stripes is basically its nemesis. To avoid having thousands of commands, the wall shader implements its own 0-to-DWIDTH loop that morally replaces Azur's command iteration, which is very beneficial because there's no point spending time sorting thousands of commands for 16-pixel wall segments.

Azur remains quite a lot faster than pure VRAM rendering. The wall shaders I'm providing here are quite polished, with EX-tight inner loops of 5 and 7 cycles per pixel for opaque and transparent image formats.

TODO

Simple things...

  • Change the rendering viewport and horizon height

There are many more things to play with. I don't think performance can be maintained reasonably for all these extensions, but with 2:2 scaling or overclock it might just work out. The following are sorted roughly by increasing cost.

  • Sprites on floor: there will be a performance hit but since the floor shader isn't even written in assembly yet, there is some room.
  • Ceiling: should cost about as much as the floor.
  • Variable-height walls (open-air setting): this is easy technologically since we already have combining textures, but this means rays almost never stop traveling.
  • Variable-height floor: the final model being each cell is a vertical stack of a block, some open space, and a block (so every wall has a lower and an upper half). This requires multiple passes on the floor/ceiling renderer, which might be too slow. The extra complexity on the walls would also be costly. But I'm confident there are compromises on this that work within the raycaster model.

License

MIT