Voxel Landscape

new graphics/music demos - bitshifters, 0xc0de, The Master + others
Post Reply
User avatar
ChrisB
Posts: 547
Joined: Wed Oct 05, 2011 10:37 pm
Location: Surrey
Contact:

Voxel Landscape

Post by ChrisB »

Don't know if this counts as a demo - it's certainly not a game. This is just something I have been playing with based on this website : https://github.com/s-macke/VoxelSpace/t ... me-ov-file

After interest at ABUG I've modified it a bit and added movement controls. Unlike the version at ABUG this runs on an unexpanded BBC B. The frame rate is ... poor ... and you'd be better running it at 2-5 times speed in an emulator but it's interesting that it's even possible.

There isn't much error checking so putting yourself in the "wrong" place causes graphical corruption. Loading a new landscape will reset your position.
vox.ssd
(91.75 KiB) Downloaded 41 times
voxel.png
voxel.png (6.18 KiB) Viewed 1419 times
Technically the screen display is a slightly reduced mode 8 with double buffering. The landscape is 8k of data (64x128 pixels) and it's averaged every other horizontal position to reduce the calculations required. Colour is simply based on landscape "height" - I did try a colour map but it didn't look good and I might try again with the NULA. Lots of pre-calculated tables wherever possible and a fast multiply (1408 multiplies for the initial frame) and vertical line draw routine. Even with all that the code is only around 3.8K.

I had thought I might try and split the calculations across a second processor to give a more useable frame rate (possibly 5 fps with a following wind?).

Edit: Second processor versions attached here. See below for descriptions.
Edit 2:Updated Nula version to use compression to allow more maps on disk. Maps I-L are alternate colour versions of A-D.
vox_spLo.ssd
(108.5 KiB) Not downloaded yet
vox_spHi.ssd
(196.25 KiB) Not downloaded yet
vox_Nula.ssd
(180 KiB) Downloaded 1 time
nulavoxel.png
Last edited by ChrisB on Wed May 08, 2024 8:37 am, edited 2 times in total.
Castle Defender, Untitled Dungeon Game, Night Ninja, Wordle, Waffle, Acorn Island, Beebchase, Ghostbusters
User avatar
colinhoad
Posts: 228
Joined: Fri Mar 15, 2019 2:25 pm
Location: London, UK
Contact:

Re: Voxel Landscape

Post by colinhoad »

Tremendous! Thanks ever so much for sharing this, Chris :D
User avatar
NickLuvsRetro
Posts: 285
Joined: Sat Jul 17, 2021 4:18 pm
Contact:

Re: Voxel Landscape

Post by NickLuvsRetro »

I had the great pleasure to be able to see this in person. One of those things I assumed "could not be done". How nice to be proven wrong. :D

Amazing work Chris!
User avatar
hoglet
Posts: 12662
Joined: Sat Oct 13, 2012 7:21 pm
Location: Bristol
Contact:

Re: Voxel Landscape

Post by hoglet »

This is fantastic indeed.

I must dig out Revaldino/Ed's Beeb816 upgrade and try this at 14MHz!

Dave
User avatar
ChrisB
Posts: 547
Joined: Wed Oct 05, 2011 10:37 pm
Location: Surrey
Contact:

Re: Voxel Landscape

Post by ChrisB »

Code uploaded to git - A little rough in places.

https://github.com/ChrisB73/BBCVoxelLandscape/tree/main

(This is where someone comes along and says "but of you do this it's twice as fast"... ;) )
Castle Defender, Untitled Dungeon Game, Night Ninja, Wordle, Waffle, Acorn Island, Beebchase, Ghostbusters
User avatar
trixster
Posts: 1173
Joined: Wed May 06, 2015 12:45 pm
Location: York
Contact:

Re: Voxel Landscape

Post by trixster »

This is bloody great, thanks for sharing!
tnash
Posts: 161
Joined: Mon May 02, 2022 9:56 am
Contact:

Re: Voxel Landscape

Post by tnash »

This is super. And even at 5fps it might be suitable for some purposes where moving fast isn't important... eg Lords Of Midnight or Sentinel?

How easy would it be to rotate left and right?
User avatar
Cybershark
Posts: 736
Joined: Wed Jun 14, 2006 11:16 pm
Contact:

Re: Voxel Landscape

Post by Cybershark »

Astonishing! Really enjoyed scooting around at 5x emulator speed and, with less distance displayed, it actually runs ok in real time :D
User avatar
ChrisB
Posts: 547
Joined: Wed Oct 05, 2011 10:37 pm
Location: Surrey
Contact:

Re: Voxel Landscape

Post by ChrisB »

tnash wrote: Sun Apr 21, 2024 11:53 am How easy would it be to rotate left and right?
If you mean 90 degrees - reasonably simple - although you might want to change the way the map is stored. 45 degrees would be a simple step up from that. Other angles are of course doable - just more maths.
Castle Defender, Untitled Dungeon Game, Night Ninja, Wordle, Waffle, Acorn Island, Beebchase, Ghostbusters
User avatar
lovebug
Posts: 1739
Joined: Sun Jan 31, 2021 5:07 pm
Location: Magrathea
Contact:

Re: Voxel Landscape

Post by lovebug »

very cool
Image Image Image Image
User avatar
ChrisB
Posts: 547
Joined: Wed Oct 05, 2011 10:37 pm
Location: Surrey
Contact:

Re: Voxel Landscape

Post by ChrisB »

Whilst working on a tube version I noticed a logic error in the redraw. So a slight update here which allows the screen to redraw properly when the landscape goes of the top of the screen. You can now practice your low flying skills ;)
vox.ssd
(91.75 KiB) Downloaded 18 times
Castle Defender, Untitled Dungeon Game, Night Ninja, Wordle, Waffle, Acorn Island, Beebchase, Ghostbusters
User avatar
colinhoad
Posts: 228
Joined: Fri Mar 15, 2019 2:25 pm
Location: London, UK
Contact:

Re: Voxel Landscape

Post by colinhoad »

I've made a video looking at Chris' excellent demo here as part of my "Bits & Bytes" series:

https://youtu.be/MRsxcKTHQFk
tomhelm
Posts: 20
Joined: Fri Jan 19, 2024 5:18 pm
Contact:

Re: Voxel Landscape

Post by tomhelm »

This is amazing, I’m shocked by the speed you’ve achieved. Last year I took an old landscape rendering program from a type-in program created by David Lawrence in the Acorn User magazine. With optimisation and converting to 6502, I got this sort of image:
landscape.png
As you can see from the timer, it is very slow in comparison to what you’ve done. I’m still relying on BASIC’s built-in triangle drawing but it would take a miracle to get it down to similar speeds.

Thanks for sharing the code, I did spot a couple of potential speed-ups in relation to the line drawing code. Given that each byte in the screen memory represents two neighbouring pixels, I noticed that your drawing code is always masked e.g.

Code: Select all

lda (plotposition),y:and #%01010101:ora maskedcolour:sta (plotposition),Y:iny
If we could avoid masking some of the time, that would get down to

Code: Select all

sta (plotposition),Y:iny
A reduction from 18 cycles to 8 cycles, so very tempting if it works from a good proportion of lines drawn. We can’t just rely on ordering of drawing from right to left to not mask the right pixels and mask the left because of the drawing order in layers from front to back.
Illustration1.png
In the diagram above, I show two possible scenarios. First to explain the colours. The bottom layer of green and red is the previous layer drawn, so the heights will be in the buffer. The blue and yellow are the current layer being drawn, so would want to make as fast as possible.

In the left hand case, we can draw the yellow first without masking because when the blue is drawn, it will fill up the left pixels, so can be done without masking. In the right hand case however, we can see that drawing the yellow without masking would mess up the already drawn green pixels where they overlap.

Optimisation opportunity #1
The answer would be to compare the height of the left and right columns from the height buffer. Then call an unbuffered version of the line drawing routine for the one which starts highest and the buffered version for the lower one.

Optimisation opportunity #2
Then another step in complexity but also performance could come from noting that where the current layer has an overlap between the left and right pixels, we can draw them both with one byte by combining the colours with appropriate masks. That would mean for part of the drawing we just have the 8 cycle code instead of using the 8 cycle for one side plus the 18 cycle masked drawing on the other. The code would take another step in complexity in managing the different combinations.
Illustration2.png
Now I’ve added dashed lines for each scenario. Above the lines, we can draw everything with a single 8 cycle call per screen row, using the combined colours. That would overdraw on one side but with no consequence as that side will eventually be drawn properly as we go further up the screen. Below the line would need to use the masked drawing as before.

All good fun, thanks for the inspiration to look into this topic. I won’t try to implement these for now in case you are planning some changes but would be happy to try if you didn’t want to.
User avatar
ChrisB
Posts: 547
Joined: Wed Oct 05, 2011 10:37 pm
Location: Surrey
Contact:

Re: Voxel Landscape

Post by ChrisB »

I did think a little about the line drawing. Originally this was Mode 2 and I was filling in double pixel rows - obviously that took a while - and lots of memory. I then moved to Mode 8 again with double pixels - but moved back to single pixels. Hence we're now a simplistic masked version. Yes - you could probably be clever with the drawing and I was thinking about something along these lines.

However - A lot of the lines are quite short - so there would be a lot of setup for not a lot of gain here. Secondly the actual line drawing time seems low in comparison to the calculation time. If you look at the initial landscape plot where it isn't plotting to the back buffer you can see that the sky fills in in 2 or three vsync frames - and given this is using the same masked line plot - just with no calculation - I don't think that the line draw is taking that much time.

This is something that's concerning me as I try to look at a Tube version - Will the I/O processor have "enough" to do - or will it be waiting for the second processor to send it data? If so - can I do some of the calculation on the I/O processor - and does that "some" need to vary based on the speed of the second processor (3/4/unrestricted MHz)? :?:
Castle Defender, Untitled Dungeon Game, Night Ninja, Wordle, Waffle, Acorn Island, Beebchase, Ghostbusters
User avatar
cola5pandex
Posts: 55
Joined: Wed Apr 17, 2024 7:56 am
Location: West Midlands UK
Contact:

Re: Voxel Landscape

Post by cola5pandex »

This is impressive. =D> Maybe it is too intensive to pad out into a full game as is but full screen, real-time isn't everything. I can imagine the basic technique having some kind of use in a Beeb game. Perhaps in some kind of small viewport, in conjunction with something less intensive. Maybe some kind of cityscape rather than landscape where the degrees of movement might seem more natural (because city blocks have a lot of right angles).

This may just be the beginning of something really different. And we like different.
User avatar
cola5pandex
Posts: 55
Joined: Wed Apr 17, 2024 7:56 am
Location: West Midlands UK
Contact:

Re: Voxel Landscape

Post by cola5pandex »

colinhoad wrote: Tue Apr 23, 2024 8:37 am I've made a video looking at Chris' excellent demo here as part of my "Bits & Bytes" series:

https://youtu.be/MRsxcKTHQFk
And this is the video that led me to this post. Good stuff Colin. =D>
User avatar
haerfest
Posts: 37
Joined: Fri Dec 17, 2021 10:28 am
Location: Assen, NL
Contact:

Re: Voxel Landscape

Post by haerfest »

Read about it here, then saw the video, very impressive! =D>
User avatar
tricky
Posts: 7693
Joined: Tue Jun 21, 2011 9:25 am
Contact:

Re: Voxel Landscape

Post by tricky »

Would there be enough saving to do an on rails shooter/bomber.
Stay in the canyon or the radar will alert the enemy - remember I have no game play skills :)
So, a bit of side to side and up and down.
Would that allow for any other optimisations?
I've fancied doing a copro something with lines so that all the setup and picking the best routine would be on the copro and just the core loops of each line drawing on the beeb.
paulb
Posts: 1767
Joined: Mon Jan 20, 2014 9:02 pm
Contact:

Re: Voxel Landscape

Post by paulb »

tricky wrote: Thu Apr 25, 2024 4:44 pm Would there be enough saving to do an on rails shooter/bomber.
Would it need to be on rails? Panning across a landscape with a fixed view direction is what Zarch does.
User avatar
tricky
Posts: 7693
Joined: Tue Jun 21, 2011 9:25 am
Contact:

Re: Voxel Landscape

Post by tricky »

I changed my mind as I wrote it, on rails-ish, if you have to go nearly straight forwards and the canyon walls don't allow room to turn around, you have a justification for not turnings arround, but only moving within the screen. It sounded like that was the cheapest maths.

Have you thought of an EOR fill, as used in one of the 3D demos?
User avatar
colinhoad
Posts: 228
Joined: Fri Mar 15, 2019 2:25 pm
Location: London, UK
Contact:

Re: Voxel Landscape

Post by colinhoad »

cola5pandex wrote: Tue Apr 23, 2024 11:04 pm And this is the video that led me to this post. Good stuff Colin. =D>
Thanks a lot! I thought Chris might like to know that this video has - by a sizeable distance - been the most popular video on my channel in its entire history! 8.2k views and still growing... for comparison, my videos tend to average about 300 views *if I'm lucky*! So, there's genuine interest and enthusiasm out there in what Chris has done - and rightly so.
User avatar
cola5pandex
Posts: 55
Joined: Wed Apr 17, 2024 7:56 am
Location: West Midlands UK
Contact:

Re: Voxel Landscape

Post by cola5pandex »

colinhoad wrote: Mon Apr 29, 2024 10:32 am Thanks a lot! I thought Chris might like to know that this video has - by a sizeable distance - been the most popular video on my channel in its entire history! 8.2k views and still growing... for comparison, my videos tend to average about 300 views *if I'm lucky*! So, there's genuine interest and enthusiasm out there in what Chris has done - and rightly so.
Wow :D
User avatar
ChrisB
Posts: 547
Joined: Wed Oct 05, 2011 10:37 pm
Location: Surrey
Contact:

Re: Voxel Landscape

Post by ChrisB »

Having spent far more time on this than originally intended I've been updating for the second processor. Using the Elite trick of redirecting OSWRCH to split the code across both processors I produced a version that was ... slower than the original.

Some code profiling later it seems that I was basing my assumption that the drawing code was slower than the multiply code was based on older multiply code. This lead me to go back to my original mode 2 version that then uses a much simpler line drawing routine. The original version above uses Mode 8 to allow something that was possible on original unexpanded hardware.

I've never done any multiprocessor coding before so I'm sure this is old hat to some people. For the uninitiated there is a FIFO queue in the Tube ULA which is 24 bytes deep. Calling OSWRCH on the parasite side adds a byte to this queue. By intercepting the OSWRCH vector on the host side this can be used to send "instructions" to the IO processor. Because these two operations are independent it becomes a balancing act of keeping the queue populated - but not full because then writes from the parasite processor stall.

Here's a video doing one "pass" of the landscape showing the comparative speeds of the different versions I have:
https://youtu.be/yP3Mv5zT3uw
The versions are:
  • Mode 2 with 16K landscape using sideways RAM (Unreleased). 1.9fps
  • Mode 8 on a standard 32K machine with an 8K landscape with interpolated horizontal values. 2.0fps
  • Mode 2 with 16K "high res" landscape on the second processor. 2.6fps
  • Mode 2 with 8K "low res" landscape on the second processor. 3.0fps
Running the "high res" version on a pitube at maximum speed (albeit an old pi - but still in the 100x faster category) gives around 3.2fps as the maximum achievable speed using this technique. It is notable that depending on how many lines need to be drawn (with - for example - a large mountain in the foreground) that the speed improves on the copro versions.

Obviously you could more calculations on a faster pi - or an arm copro - and simply blit the screen across but we're moving further away from real hardware. With that said I made one more version that uses the NuLA and rather than simple allocating a colour dependent on height performs a texture map. The texture map is a simplistic 16k array with colours byte values in it for easy quick access. This version naughtily overwrites the top part of the language as we now have 32K of data to store + lookup tables and code.

I'll add disk images and another screenshot to the top post and when I've tidied up the code I'll update the GIT repository. There may be further optimisations that could be made but at this stage I'm happy with where this is.
Castle Defender, Untitled Dungeon Game, Night Ninja, Wordle, Waffle, Acorn Island, Beebchase, Ghostbusters
User avatar
BigEd
Posts: 6261
Joined: Sun Jan 24, 2010 10:24 am
Location: West Country
Contact:

Re: Voxel Landscape

Post by BigEd »

Depending on your priorities and values, it might be worth considering using the Tube hardware directly, as Elite does, rather than using OSWRCH. You'll reduce the per-byte overhead a lot, I think.

Also perhaps worth considering is using the second processor the other way around... Keep the main application in the host processor (the i/o processor) and have it send work packages to the second processor and (later) fetch back results. The second processor becomes an accelerator for computations. The idea only works if the problem can be broken down in that kind of way, of course. But perhaps there's some computation in an inner loop which fits the bill - perhaps all the operands are sent over for each packet, or perhaps the second processor holds some, or lots, of state which is made use of for the computation.

(A similar but different idea here is to run the application in the second processor but have it use the host processor to do a fraction of the computation work - may be applicable when the second processor is at most twice as fast as the host, as it was back in the day, but less so if the second processor is very fast indeed.)
ThomasHarte
Posts: 563
Joined: Sat Dec 23, 2000 5:56 pm
Contact:

Re: Voxel Landscape

Post by ThomasHarte »

BigEd wrote: Mon May 06, 2024 12:17 pm Also perhaps worth considering is using the second processor the other way around... Keep the main application in the host processor (the i/o processor) and have it send work packages to the second processor and (later) fetch back results. The second processor becomes an accelerator for computations. The idea only works if the problem can be broken down in that kind of way, of course. But perhaps there's some computation in an inner loop which fits the bill - perhaps all the operands are sent over for each packet, or perhaps the second processor holds some, or lots, of state which is made use of for the computation.
It's easy to make pronouncements from an armchair, but: for voxels perhaps a second processor could calculate the span buffer per column, i.e. post content of the form "for column 0, from bottom to top, it's 11 purple pixels then 5 blue then 19 reds..." and the IO processor could spend its time diffing those with the previous input and plotting the differences?

(Aside: since voxel landscapes are generally calculated front to back for no overdraw whatsoever, colour boundaries come out naturally sorted, making them a rare fully-interactive algorithm where drawing only the differences *might* actually be cheaper than brute-forcing it, subject to endless many other factors)
User avatar
ChrisB
Posts: 547
Joined: Wed Oct 05, 2011 10:37 pm
Location: Surrey
Contact:

Re: Voxel Landscape

Post by ChrisB »

Updated Nula version with more maps on the first post.

I did think about it if might be cheaper (especially when using the original palette - probably not so much for the nula) to combine the line draws. Since it is a simplistic height based colour it is probably likely that two line segments next to each other vertically have the same colour and could be drawn as one line line as opposed to two shorter ones. These could be aggregated until there was a change in colour then the whole line sent over reducing "draw calls" and possibly allowing the line draw to be sped up... Now I've come to write that down it seems feasible....
Castle Defender, Untitled Dungeon Game, Night Ninja, Wordle, Waffle, Acorn Island, Beebchase, Ghostbusters
reenigne
Posts: 15
Joined: Thu May 24, 2018 12:31 pm
Contact:

Re: Voxel Landscape

Post by reenigne »

I'm curious what you need the multiply for. The voxel landscape in Area 5150 is done entirely with table lookups, though that one probably uses quite a bit more memory! For each column, the routine casts out rays at 32 zenith angles. There is a table to convert zenith angle and azimuthal angle (i.e. pan angle + x coordinate) into texture positions relative to the camera position, the texture table itself, and a table to convert altitude (from the texture) and zenith angle into y position on the screen.
Post Reply

Return to “new projects and releases: demoscene”