A tiny software raymarcher that attempts to render "n-dimension" manofold insertions as an image appearing to be a non-euclidean 3-dimensional space. Written for the uqcs hackathon 2020. This repo is a mirror of:
https://github.com/ailrst/blackpink
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2.4 KiB
2.4 KiB
title | author |
---|---|
BlackPink (Manifold Raymarching Rendering Engine) | _"A Blazing 100x100px at 10FPS"_ |
Objective
Can we use raymarching to render primitive objects inside an arbitrary manifold in real time?
"Non-euclidean rendering" in the most generalised form possible.
Raymarching
- an approximate and fast form of 'raytracing'
- good for primitives (spheres, boxes et cetera.)
- still very expensive
Manifolds
Only one of us does galaxy brain maths.
Tech Stack Requirements
- Fast, compiled code
- We are relatively familiar with it (that disqualifies any modern or "good" language, and C++)
- Need n-dimensional vectors
- Need to draw pixels on a window
- not Java
C and libSDL2
Its fast (to run) and we "know" it. C is a nice language if only for the simplicity of its mental model.
libSDL2 is what the big kids like Valve use.
- nicely handles threading, drawing, timers, and gets out of the way.
Richal spent 10 hours writing a vector library from scratch.
N-dimentional determinants and cross products sound simple.
At one point we were leaking memory at approximately 150Mb per second.
12 Hours later, we could render
- circles
- boxes, and
- straight lines
from one angle, and move them around the scene
- as long as we got lucky with whatever the 4th dimension was doing.
Plus some post-processing and lighting.
Results
A 3D renderer where all the maths is done in n-dimensions.
video
Takeaways 1
- sticking raymarching vectors to manifolds in 4 dimensions is possible but has a lot of edge cases
Takeaways 2
- having RAII would be really nice when writing a vector library
if (1 || keyboardstate[SDL_SCANCODE_UP]) {
struct ray cameraray = {.pos = copy_vec(camera->pos), .dir = camera->y};
manifoldturn(&cameraray, camera->x, 0);
free_vec(cameraray.pos);
cameraray.pos = copy_vec(camera->pos);
manifoldturn(&cameraray, camera->y, 0);
free_vec(cameraray.pos);
cameraray.pos = camera->pos;
manifoldstep(&cameraray, dist);
free_vec(cameraray.pos);
}