Hi all,
I've been exploring the subject of brut force ray casting on Oric and, surprisingly, I think I found a way to reach a satisfying level of performance with this approach.
I say "brut force" because the principle is to :
- scan ALL walls of a scene for they part in the field of view,
- compute the distance to the camera for each ray angle in the field of view
- keep a z-buffer with closest distance found to determine which wall is visible on which part of the screen.
To afford such a brutal approach,I first restricted the study to cases with only aligned wall. As in Wolfeinstein, walls can only be aligned with (O,y) or (O,x) axis.
This led to important simplifications in the distance calculation.
It turned out that distance is either:
- (Xcamera-Xwall)/sin(alpha) for (O,y) aligned walls or
- (Ycamera-Ywall)/cos(alpha) for (O,x) aligned walls
In order to avoid the division, I do all computation in logarithmic scale.
For a given wall,I first compute the numerator log2(32*(Xc-Xw)) or log2(32*(yc-yw)) depending on orientation of the wall.
Next, for each ray angle alpha, i pick the denominator in a precalculated look-up table containing log2(32*(1/sin(alpha)) or log2(32*(1/cos(alpha)).
thus, the distance calculation is only one 16 bits addition+ an indirect indexing + one 16 bits comparison to deal with z-buffering. And that's all.
One i have computed the logaritmic z-buffer, I apply the anti fisheye transformation on the result before I exponentiate the whole with a precalculated look-up table .
For better performance, I use the exponentiation look-up table to also performs the Distance to Height transformation.
I can't see how there could be faster way to proceed.
You have to know that in the .tap here, only the rendering part and the arctangent operator are in assembly language .. all the rest is in C language.
So there remains lots of cycle to save that could be used to enhance the rendering and/or add some gameplay.