I released a new build a few days ago, this time featuring an actual in-game module being rendered by the actual in-game module renderer! There was a lot of behind-the-scenes work involved in this, and I’ve never built anything like it before, so I’m incredibly relieved that it works.
The renderer uses Multiple Render Targets, or MRTs, which are a new feature in flash. They are pri-tee cool. Now when I draw a screen full of modules I can render out an image showing their diffuse colours (what colours are painted on them), an image showing their lower frequency circular harmonic light radiance (how much light hits each pixel from every direction), and an image showing their higher frequency circular harmonic light radiance (more detail for the lower frequency stuff). Here are some pictures!
You can see here that I haven’t actually painted the command module yet – it’s just flat white, so everything you see in game is lighting detail
Radiance low harmonics
I might be using the word “radiance” incorrectly. I’m pretty new to all this!
It’s not really obvious what’s happening here, but trust me it’s cool and useful.
This is where all the lights are added together. Since light brightness isn’t proportional to pixel value, this looks a bit funny until…
This shows the accumulation buffer translated to pixel values, and is what finally appears on screen. Pretty!
So, what’s the point of this? The point is lights. Many, many, many lights. Lights from thrusters, lights from muzzle flashes, lights from explosions, and lights from missiles and torpedoes and laser bolts. With this information stored in buffers already it becomes incredibly efficient to draw lots of little light sources, which should be perfect for a game like this, and would have been impossible with regular forward rendering. I, uh, don’t actually have any of these lights in the game yet, but I expect they’ll look awesome. PEW PEW!
I ran into quite a few issues getting this working, mostly due to a an apparent absence of documentation. I couldn’t find a single article from Adobe about how this works, so had to cobble together an understanding via other people’s source and hours of trial and error. If you’re also looking to use the new flash MRT feature you might find these notes useful:
- MRTs are only available in Context3DProfile.STANDARD, which you pass as a parameter when you requestContext3D
- setRenderToTexture has a new parameter colorOutputIndex, which you set to 0, 1, 2 etc for each of your targets
- Each target used in a single draw must have the same texture format
- Your pixel shader should output to each of the targets, using registers oc0, oc1, oc2 etc to reference them
- Older versions of the AGALMiniAssembler won’t recognise oc0, oc1, oc2 etc. I couldn’t find an official Adobe source for this file but found a more recent version here
- If you render to any other textures later, first call setRenderToTexture with a null target for each colorOutputIndex you are no longer using
I hope this helps someone out there.