First step was reading my codebase and understanding it again. To do this, I followed through my DogFight and SpaceFlight python modules, and drilled down into the how the Scene works, with n cameras and lights and render channels and Scene vizCallbacks etc. Very happy once I'd figured it out, to remember that I had come a long way. With hindsight and a fresh perspective, I jumped in and fixed a few long-standing bugs.
Then to test out my knowledge of the renderer, I launched in and implemented both depth-of-field scene blurring and materials that reflect the dynamic skybox, and got these new features done in a single night. That was an awesome feeling, I was really happy to get 2 huge features working in such a short amount of time. It required no new architecture work, just straight implementation using existing paradigms. I'm so happy right now that the rendering engine I made last year is so flexible and that I had come so far already.
I wrote up a how-to on how to add new Post-Processing stages.
How to add a Post-Processing stage==================================Each CameraScene owns a "post" render channel strip.Currently each Camera Scene has the same python code and same post setup.1. Add a Render Channel to CameraScene.post render channel strip. e.g. rcs.add( Stingray.RenderChannel(), "DepthOfField", 9.5 )2. Need a list of Draw Commands to render your effect. Do this via XML, and load in python - see Scripts/Postself.dofCommands = path = "data/depthOfField.xml"d = Stingray.root().open( path )for name in d.children().keys():dc = Stingray.DrawCommandClassFactory( path + "/" + name, None )self.dofCommands.append(dc)self.postChannelStrip.strip.addDrawCommand( "DepthOfField", dc )3. The SinglePassFilter DrawCommand takes 4 source textures and a destination texture in XML, e.g.
SinglePassFilter [DrawCommand] TransferFilter4. Create custom shaders for the steps.Pixel Shader Post Processing Constants//from ShaderConstants::setStandardPostProcessConstants()float4x4 view : register(c0);float4x4 proj : register(c4);float4x4 viewProj : register(c8);float4x4 invViewProj : register(c12);float4x4 invView : register(c16);float4 user1 : register(c20); //user constant 1float4 user2 : register(c21); //user constant 2float4 user3 : register(c22); //user constant 3float4 user4 : register(c23); //user constant 4float4 lut : register(c24);5. Assign python control over shader constantsIn PyStingray/ShaderConstants.pyregister( "dof", "nearZ", "shaders2/post/dof_lens.pso", 20, "near Z for depth of field camera lens" )
Then based on the scene knowledge, I added something I always wanted to, image-based procedural world maps. This is really cool, I now have a 2Kx2K image, where each pixel creates a 250m. x 250m. tile of world, such as city pieces, water pieces, suburbs, forest, etc. This image is procedural, using the Python Imaging Library, I have a layer-based procedural image compositing system. In the end, I'm going to use this to generate planets, and allow players to build hand-made cities and do terraforming.
Got to go now, will post screenshots up later but I need to finish optimising the world tile streaming, currently it's pretty jerky when moving around.