Hacker News new | past | comments | ask | show | jobs | submit login
Pico3D: Open World 3D Game Engine for the PicoSystem (RP2040 Microcontroller) (github.com/bernhardstrobl)
265 points by bstrobl on April 16, 2023 | hide | past | favorite | 39 comments



Very impressive, and very fun :)

I wish I had the time to do this, but it looks like it would be relatively simple to modify render_rasterize.cpp [0] to do perspective-correct texture mapping [1]. I also wonder if going for a scanline approach [2] would be faster than iterating over the whole screen calculating barycentric coordinates?

[0] https://github.com/bernhardstrobl/Pico3D/blob/main/engine/re...

[1] https://gabrielgambetta.com/computer-graphics-from-scratch/1...

[2] https://gabrielgambetta.com/computer-graphics-from-scratch/0...


I used some of your pages for my thesis so thanks for that :)! It is likely that a scanline rasterizer is more performant, but some of the triangles are really small on a 120x120px display, so just the sorting of up to 1500 triangles for each scanline may have its own drawbacks if many are tiny. One of the other reasons (aside from needed implementation time) for the current approach is also the hope that future microcontrollers might simply have more cores to throw at the problem so rendering could be parallized a lot faster simply by splitting rendering areas. Definitely plenty of room for improvement everywhere but time is sadly always a factor, hence why I hope others may be able to help ^^.


Currently writing my own software rasterizer, some interesting stuff I came across:

Fine grained visibility determination (span, coverage buffers, etc) https://www.flipcode.com/harmless/issue01.htm

Tom Forsyth, How To Draw Ugly Lines Fast https://cohost.org/tomforsyth/post/648716-how-to-draw-ugly-l...

Ned Greene, Hierarchical Polygon Tiling with Coverage Masks https://www.cs.princeton.edu/courses/archive/spring01/cs598b...

This UC Davis lecture video explains rasterization rules really well: https://youtu.be/z3fWd7G3mrU


Oh, that's very nice, we've come full circle :)

What do you mean by "sorting 1500 triangles"? You mean sorting their vertices? I believe you already do that in a couple of places; since you're using a depth buffer, I don't think you need to sort them back-to-front, so I'm not sure what you mean.

True that a 120x120 display is tiny, but that also means that you can get away with two static arrays of 120 elements for the left and right sides of the triangle, no need to do any allocation or use tons of memory.


By scanline rasterizer I assumed a system similar to the original Quake scene rasterizer best described in Michael Abrash's Graphics Programming Black Book.

The method allows saving substantially on any overdraw since fillrate is really the primary bottleneck here.

I did a quick check on your page and it seems the implementation describes a per triangle setup vs the more complicated solution by Carmack and his team? Could still work well for larger triangles, maybe with a check on triangle size to avoid really small ones.

Quake did after all utilize 3 different rasterizers to optimize performance depending on use case.


>we've come full circle

Triangle, surely...


There's also RP2040 Doom which managed to get doom running on the RP2040, complete with sound, music and networking over I2C. The VGA signal is generated by a PIO state machine on the RP2040.

https://kilograham.github.io/rp2040-doom/


Neat, I love these tiny rendering projects!

The original Nintendo DS also had two ARM cores (33MHz and 66MHz IIRC). People made some amazing things, including a Portal clone:

https://www.gamebrew.org/wiki/Aperture_Science_DS


To be fair, it also had lots of dedicated 2D and 3D graphics hardware.


There's also a handful 3D tech demos for the GBA. That one's only got 2D hardware and a single 16MHz ARM7TDMI.

https://www.youtube.com/watch?v=UFmhpZ4A1mQ


Beyond the tech demos There are dozens published 3D games.

The most impressive is the GBA port of Driv3r. More or less stripped down Grand Theft Auto 3 style sandbox game, squashed down onto the GBA.

Driv3r Video: https://www.youtube.com/watch?v=xXq3jH8TQNo&t=32s

History/showcase of various 3d GBA games: https://www.youtube.com/watch?v=79fgH08z6xs


The cores were also ARM7 and ARM9, respectively.

IIRC, the ARM7 one was essentially identical to the ARM7 used in the GBA, and was used for the GBA backwards compatibility mode on the original DS/lite.


The Portal clone is definitely dope. Thanks for pointing it out!


The PicoSystem itself can be purchased from its creator, pimoroni: https://shop.pimoroni.com/products/picosystem


As an aside, if you haven’t yet found this wonderful if tiny retro gaming experience, the InfoNES emulator project ported to PicoSystem is definitely worth hitting up:

https://github.com/fhoedemakers/PicoSystem_InfoNes

It’s still in early stages, no sound and no save points, but thoroughly cute and addictive nonetheless!


I wonder what's with safety of such enclosures made of pcbs? For instance is it going to have unpleasant chemicals transferring on the fingers and then to the body when someone touches eyes or mouth?


As a user can confirm siblings comment. The way it's designed your fingers don't really come into contacting the faceplate, and even then it's not raw but painted. Certainly, I have not felt anything coming off of it and I've used it rather a lot.


The only part of the enclosure that is exposed PCB is the front plate, the rest is machined anodised aluminium - it feels great.

All of our products meet the REACH and RoHS requiements for restricted and hazardous materials.

TL;DR It's fine.


Intended use of PCBs is to provide a rigid platform supporting electronic components and so would you not agree that regulation is written with that in mind, as the bar for chemical safety would be set higher if the product was intended to be touched (even accidentally), rather than being hidden inside an enclosure away from direct contact?

Use of PCB as a human user interface started in hobbyist world, because it was cheap and easy to create sturdy front panels and was good enough for creating prototypes, but it was never meant for mainstream commercial use in this way - as PCBs even if they meet RoHS, still can contain dangerous chemicals - like flame retardants.


Direct link to gameplay video (spoiler):

https://youtube.com/watch?v=n6bECGQyNuk

It achieves this by using both cores & clocking the RP2040 at 250Mhz (via Picosystem's SDK).

(Well, and probably also being decently coded...)


From personal experience I know a 266 MHz (single core) PC from c. 1997 can run 3D games with somewhat comparable graphics just fine (MechWarrior 2, the PC version of FF7) at low SVGA resolutions (640x480 - 800x600).

The Pico3D is 1/2 the performance (133 MHz if you use only one core for rendering), but 1/8 as many pixels (240x240 display).

Definitely a cool project, but based on specs it's actually not that surprising this is possible.


One key relevant difference between the Picosystem/RP2040 and a '97 PC is available RAM and video RAM, the RP2040 has only 264KB of any fast RAM (excluding external flash which has DMA and XiP but is still comparably slow).

Whereas a '97 PC would be in the many tens of MB or possibly hundreds, and at least a few MB dedicated VRAM on a video card. So not an equivalent comparison really, this is a much more constrained environment.


Did a 1997 pc have 100s of mb?

I seem to recall running Windows 95 on a 200mhz - 300mhz processor with 64mb ram.

It wasnt top of the line but I don't think windows 95 was top of the line either. My ex corporate windows 2000 pc upgrade had 128mb ram. Neither had fancy graphics cards.

Mechwarrior as I recall ran on my 486 with 8mb ram. I'd guess that's in the same ball park of 256k for ram with xip flash. With a lot of hand waving of course. It could certainly run doom.


You can render one line of output and DMA it to the display.

So no need to have a complete framebuffer in the first place. Lack of memory just limits the number of textures you can have.


Another huge difference is that the RP2040 lacks floating point support. At least it has (integer) hardware division, but that's about it.


Floating point doesn't really matter much here. Even at the time, you'd typically use integer fixed point math unless you were micro optimizing for the different execution ports of the CPUs you were targeting and didn't want the float pipes to sit idle.


Very impressive. The linked thesis is a nice overview of the design:

https://lavarails.com/download/open_world_3D_microcontroller...

It describes a lot of previous commercial game devices, but doesn't really discuss current alternatives to the PicoSystem. I wonder if there are more capable open-firmware devices at around the same price?


Nothing I'm aware of has nailed the form-factor/ergonomics and quality of the controls. It's a solid unit and has the feel of a finished product. Alternatives are typically bare circuit boards or lack quality input.

It seems like Pimoroni spent time to get those aspects right, and so while there aren't that many games (yet?) - the good quality ones are a joy to play feel-wise, eg Square Bros (which comes installed on a new unit).

The SDK is well thought-out and simple, and has a unified API - micropython or c/c++.

They are apparently working on a successor that plugs into a TV or monitor via HDMI. IIRC it will use two RP2040's.

EDIT: Yes, two chips:

https://www.tomshardware.com/news/pimoroni-stick-pi-gaming-c...


Huh, I was going to suggest that! There're 80 cents each, so why not? But it seems there's a purpose for it:

> The dual RP2040 chips on the DV Stick will allow it to have one CPU that does the software processing and another that just drives the display. Each of the chips has its own PS RAM chip, which means that there will be more memory than the 264K that comes standard with RP2040 chips / Raspberry Pi Picos.

> "Each of the chips has a PS RAM chip for the frame buffer and, on VSync they swap," Williamson said. "So we have an analog mux that basically swaps the chips between the two so the application processor writes into the frame buffer in one RAM chip then, when VSync occurs in the display, it hands that RAM chip over to the display processor which hands its RAM chip back to the application processor so the display outputs on the screen."

Thanks for the link!


This is so awesome. Well done! I played a little with Pico/RP2040 (as a hobby), and it is so much fun. I wish educational content and institutions would embrace it more quickly.


This is fantastic! I am a huge fan of seeing limited hardware pushed to it's limits (I'm a SEGA Saturn homebrew developer at the moment, but in high school I was huge into GBA, and then eventually DS, programming) and this is the adorable and skill-laden kind of project I love to see on the front page of HN! Great work!


I've heard the sega Saturn is difficult to develop for, compared to the PlayStation. Is that true in your experience?

I would guess judging by the games that the Saturn was more capable with 2D games.


This is really great. I haven’t made much (any) progress, but I would like to do something similar for the Analogue Pocket. Still trying to discern the best use of the FPGA cores for a little 3D world. I’ll take a look and see if there are any nifty tricks here I can leverage.


Impressed with the frame rate and gfx style. I feel like i could enjoy a world/story in that engine.


This is probably the coolest project I've ran on my PicoSystem thus far. Felt nice to dust it off.


Is this any relation to pico8, the fantasy console? If not, can the picosystem run pico8?


No in this case the Pico part comes from its use of the Pi Foundation's Pico microcontroller. There are projects[1] that are working on porting PICO-8 to the Picosystem. Unfortunately it will never be fully compatible with the PICO-8 standards as it isn't powerful enough but some games work.

[1]https://github.com/yocto-8/yocto-8


Mind blowing!


genius work




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: