The Quest for More Colors

Some of you may have seen my other post on making a 3D renderer from scratch, and the experienced devs seemed politely suggestive that I stick to the native fillTriangle functions. Here I reveal my hand…

I’d like to make a game that actively uses more than 16 colors by changing palettes on the fly.

This initial demonstration is just a small performance test and proof of concept that shows palettes can be swapped pretty quickly on the fly to allow for an arbitrary number of colors to be displayed in a single project.

My eventual goal…

  1. Take a dynamically generated image with as many as 16,777,216 unique colors - the standard limitation for colors represented by rgb hex values, which Makecode uses for its palette colors
  2. Plot the color of each pixel in a 3-dimensional plot by its r, g, and b values
  3. Use some algorithm like median cut or octrees to intelligently pick 15 colors (+ transparent, which can be used to mimic black) to represent that frame.
  4. Employ a technique like Floyd-Steinberg dithering to shade the image appropriately with those 16 colors.

If this is done every frame, the color palette will adapt to whichever 15 colors + black will best represent the image on any given frame. This is similar to the technique used to generate old .gifs


The images I will be processing are renderings from my 3d engine. Rather than drawing directly to the screen, I plan on drawing to a color buffer that holds information for the actual colors I’d like at each pixel, were Makecode Arcade not limited to 16 colors. The colors will be based on lightning and rotation of the triangles in my scene, and to start, I’d like to attach hex color values to the vertices on my 3d models rather than assigning a palette index to the faces like many other 3D implementations in Arcade have done up to this point.

This will absolutely not be performant, especially on hardware. I’m curious to see how many fps (frames-per-sometimes) my laptop will be able to eventually manage. If you wanted it to be even remotely performant, you’re probably better off manually setting or calculating the color palette on boot up and just using a dithering algorithm, though I doubt even that will be feasible for realtime.

Thank you for reading, and wish me luck! I will update as I make progress. First step will be coding the dithering algorithm with a static color palette, though I need to make progress on my 3D engine before I can appropriately test it.

22 Likes

Wow… Have fun tackling that. I hope you succeed!

1 Like

This looks so cool!!

1 Like

HOLY-
I can tell your going to be one of the big users after you stay for awhile!

4 Likes

this could revolutionize makecode if it can be an extension and works with 20+fps on hardware

Let’s just say there’s a reason PCs use graphics cards… lol

I have no hopes of the finalized product running fast - but I would still like to make it and then potentially discuss some compromises that could be made to still maintain some performance.

Any techniques I use, I don’t think would work as an extension in the way that you hope. I can’t magically make extra colors appear in the pixel art palette or show more than 16 on the screen at a time, for example. I will just be intelligently swapping palette colors on the fly, which you can already do yourself with one of the available palette extensions.

I hope to combine this with retro shading techniques like dithering to further mimic the appearance of more than 16 colors. This you can also already do with your pixel art - it just takes skill. I’ll be doing it programatically and on 3d models. I would not hold out for an extension from me, but I would encourage you to do your own research! Most of the things I’m doing I learned from books at the library or youtube. If you want some direction on where to start, I’ll happily share advice.

3 Likes

i think your biggest issue on hardware is going to be memory rather than computational performance. the reason we do 4 bits per pixel is 100% because of memory; packing and unpacking bytes every time we change a pixel is pretty significantly slower than just using one byte per pixel.

but the memory saving makes it worth it. each screen is 160*120 pixels which comes out to roughly 10kb per screen. we have two screens in memory at given time (i.e. we double buffer the screen) so that’s 20kb total. the processor in the meowbit, the STM32F401RET6, has a whopping 96kb of RAM, so that’s not much left over for the user program!

2 Likes

Hey did you know you can do this?

3 Likes

uhhm… When can we get ‘official’ new colors? @richard

pls, pls, pls, pls, pls, pls, pls, pls, pls, pls, pls, pls!

1 Like

It won’t happen, makecode has a 4 by 4-bit screen, 4*4=16, therefore makecode can only handle 16 colors, and of course one of those colors must be transparent.

3 Likes

thats really cool omg :open_mouth:

its so bright lol >0<

thanks for letting me know!

1 Like

welcome :slight_smile:

Is there code for that cat? Or is it a demo of what it could look like?