Wrapping-Up New Renderer

Hey Folks! Hope everyone had a good weekend. I finally got with the times and started The Witcher 3, and it's pretty good so far. I don't know if I'm drawn in as much as some folks I've heard talk about it, but maybe my taste is changing. Still, I'm really digging the attention to detail and immersion.

Back on the space prototype, I think I've just about finished working out the remaining kinks in the new renderer. I figured out the problem with my shader's lighting stage, which mostly had to do with bad normal map color channel info being passed into the lighting calculation.

First, I had to take the normal map's color info (values ranging from 0 to +1) and convert them into direction (-1 to +1) with a simple arithmetic operation. I also had to make sure I was only dealing with RGB channels for the normal map's data, instead of an RGBA value. The normal map has no A (alpha) channel, and I think the extra channel was affecting later attempts to normalize the vector (make sure it is always less than or equal to one unit long).

Also, I ended up forcing the blue channel (which is largely unused) to be 1, since some areas had 0, and combined with flat areas of the normal map (R = 0 and G = 0) caused an error when the vector was normalized. I.e. black spots.

And lastly, I forced the final color output of that shader stage to have an alpha of 100%. This might have been redundant, but it seemed like the only logical value for this shader, since it represents the color information of the entire scene.

The result is what you see in today's screenshot: crew rendered on top of floor, with edges transparent, and highlights and shadows matching light position in the scene. I see one slight glitch in the shoulder/foot overlap on the right side, but it's otherwise looking pretty good!

Also, as an experiment, I increased the scene from 360p to 720p, and I still see 66fps with 400 blocks, 50 lights, and this animated crew mesh. I think we're going to see a decent improvement in performance once this replaces the prototype's default lighting/rendering system.

And that's probably where tomorrow will start. Now that I've got this test scene working, I need to start porting this over to the main prototype. That means a few things:

  • Change the code to spawn new custom lights instead of Unity lights.
  • Change the code to use new shadow blocker squares instead of arbitrary polygon meshes defined inside each item. Probably by defining which tiles the item shadows, similar to other per-tile stats.
  • Add rendering-specific layers to the prototype, and adjust items to use the correct ones.
  • Add new renderer script to game's main scene camera.
  • Add necessary shaders, materials, render textures, and other pieces for handling the render pipeline.
  • Fix any issues resulting from the switch over. E.g. mouse click coordinates, UI overlay, rendering high-Z cut-out objects like overhead conduits, etc.

It'll probably be an involved refactor. I'm guessing at least a day or two to get visible results. But, you know what they say about the best laid plans :)


ra1's picture

Are you planning on clipping lighting as doors open/close or walls are removed/added? Also, have you tested performance with multiple moving lights?

dcfedor's picture

I do plan to refresh light zones whenever doors open or blockers are removed. As for multiple moving lights, I suspect we can manage a handful without too much of a penalty, but probably not tens of them.

That said, this is with a fairly light optimization pass so far. It's possible there's more performance to be squeezed out of it with a concerted effort.

The real test, though, is putting it in situ to see how a full ship tilemap and light load works. I'm optimistic based on my testing, but one never knows until they try!

Dan Fedor - Founder, Blue Bottle Games