split library and example + add README
|
@ -11,35 +11,33 @@ find_package(Gint 2.9 REQUIRED)
|
|||
find_package(LibProf 2.4 REQUIRED)
|
||||
find_package(Azur 0.1 REQUIRED)
|
||||
|
||||
if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G)
|
||||
message(SEND_ERROR "Azuray doesn't support fx-9860G")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
set(SOURCES
|
||||
src/azuray.cc
|
||||
src/main.cc
|
||||
src/physics.cc
|
||||
src/shader_floor.cc
|
||||
src/shader_floor.S
|
||||
src/shader_wall.cc
|
||||
src/shader_wall.S
|
||||
src/texture.cc)
|
||||
azuray/azuray.cc
|
||||
azuray/physics.cc
|
||||
azuray/shader_floor.cc
|
||||
azuray/shader_floor.S
|
||||
azuray/shader_wall.cc
|
||||
azuray/shader_wall.S
|
||||
azuray/texture.cc
|
||||
src/main.cc)
|
||||
set(ASSETS
|
||||
assets/map1.txt)
|
||||
set(ASSETS_fx
|
||||
)
|
||||
set(ASSETS_cg
|
||||
assets-cg/tileset.png)
|
||||
assets/map1.txt
|
||||
assets/tileset.png)
|
||||
|
||||
fxconv_declare_converters(converters.py)
|
||||
fxconv_declare_converters(src/converters.py)
|
||||
fxconv_declare_assets(${ASSETS} ${ASSETS_fx} ${ASSETS_cg} WITH_METADATA)
|
||||
|
||||
add_executable(myaddin ${SOURCES} ${ASSETS} ${ASSETS_${FXSDK_PLATFORM}})
|
||||
target_compile_options(myaddin PRIVATE -Wall -Wextra -O3)
|
||||
target_link_libraries(myaddin Azur::Azur -lnum LibProf::LibProf Gint::Gint -lstdc++)
|
||||
target_compile_options(myaddin PRIVATE
|
||||
-Wall -Wextra -O3 -I "${CMAKE_CURRENT_SOURCE_DIR}/azuray")
|
||||
target_link_libraries(myaddin
|
||||
Azur::Azur -lnum LibProf::LibProf Gint::Gint -lstdc++)
|
||||
|
||||
if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G)
|
||||
generate_g1a(TARGET myaddin OUTPUT "Azuray.g1a"
|
||||
NAME "Azuray" ICON assets-fx/icon.png)
|
||||
elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
|
||||
generate_g3a(TARGET myaddin OUTPUT "Azuray.g3a"
|
||||
NAME "Azuray" ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png)
|
||||
endif()
|
||||
generate_g3a(TARGET myaddin OUTPUT "Azuray.g3a"
|
||||
NAME "Azuray" ICONS assets/icon-uns.png assets/icon-sel.png)
|
||||
|
|
21
README.md
|
@ -1,5 +1,22 @@
|
|||
# Azuray: an optimized Azur raycaster
|
||||
|
||||
![](screenshot.jpg)
|
||||
|
||||
This is a raycaster that I let myself get distracted into making while I should have been working on [PythonExtra](https://git.planet-casio.com/Lephenixnoir/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
|
||||
|
||||
|
@ -11,8 +28,8 @@ There are many more things to play with. I don't think performance can be mainta
|
|||
* 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 two sections). This requires multiples passes on the floor 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.
|
||||
* 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](https://mit-license.org/).
|
||||
[MIT](https://mit-license.org/)
|
||||
|
|
Before Width: | Height: | Size: 6.0 KiB |
|
@ -1,4 +0,0 @@
|
|||
*.png:
|
||||
type: bopti-image
|
||||
profile: p8
|
||||
name_regex: (.*)\.png img_\1
|
Before Width: | Height: | Size: 7.3 KiB |
|
@ -1,3 +1,7 @@
|
|||
*.png:
|
||||
type: bopti-image
|
||||
profile: p8
|
||||
name_regex: (.*)\.png img_\1
|
||||
map*.txt:
|
||||
custom-type: map
|
||||
name_regex: map(.*)\.txt map_\1
|
||||
|
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 159 KiB |