Design time again!
I'm currently dealing with transparent objects. This is the flow I wanted :
1) When the GBuffer scheme handler inspects an objects (to auto-create the GBuffer writing pass) it also checks if a pass is transparent.
2) An additional technique will be created called "NoGBuffer" (or something similar) - all the passes that can't get written to the GBuffer get copied to this technique.
3) After rendering the lights, an additional render_scene directive will be dispatched with the NoGBuffer material scheme, so all transparent passes within the GBuffer render queue range will render themselves normally now.
4) After that, the post-GBuffer render queue range objects get rendered normally.
This is how the compositor would look :
Code: Select all
compositor DeferredShading/ShowLit
{
technique
{
//Reference the main Gbuffer texture
texture_ref mrt_output DeferredShading/GBuffer mrt_output
target_output
{
input none
pass clear
{
}
// render skies and other pre-gbuffer objects
pass render_scene
{
first_render_queue 1
last_render_queue 9
}
//Render the lights and their meshes
pass render_custom DeferredLight
{
input 0 mrt_output 0
input 1 mrt_output 1
}
//Render the passes that did not get written to the GBuffer
pass render_scene
{
material_scheme NoGBuffer
first_render_queue 10
last_render_queue 79
}
// Render the post-gbuffer objects
pass render_scene
{
//This value is synchronized with the code
first_render_queue 80
}
}
}
}
Why did I choose this approach?
The alternative was to change the visibility mask or render queue of the transparent passes. The problem is, visibility masks and render queues are properties of MovableObjects and not passes. I need to potentially be able to split an object's rendering into two different parts. This is a pretty big change in ogre that I don't want to do. (And don't think is right)
Why can't I do this right now
The compositor script I wrote there is illegal. The problem? the "material_scheme" directive belongs in the target scope, and not in the pass scope. This means that I can't have different material schemes in different render_scene passes.
Why not split the passes into different target operations?
There can only be one target_output pass in a composition technique.
Solution
In my opinion, the "material_scheme" directive belongs in the pass scope, and not in the target scope. The directive is usually applied to render_scene passes, and if someone puts render_scene and render_quad directives in the same target operation, do they expect that the quad's material will be affected by the material scheme? I don't think so.
The downsides of the solution are that they break backwards compatibility and might cause script duplication (if you really want the same custom scheme for multiple passes).
A possibility to solve these downsides is to allow the directive at both scopes, but I really don't like that option. I think that material_scheme really belongs in the pass scope.
[EDIT]
My solution isn't currently possible either. Technique resolution (which is where missing techniques are handled) happens during updateRenderQueue, which means that you cannot resolve techniques based on the scheme that will be active during their render queue.
I'm going to have to find a different solution, or change more stuff in Ogre. Ideas?
[EDIT2]
As a temporary solution, I am now rendering everything into an A8R8G8B8 buffer, allowing me to have multiple target passes before outputting the entire thing to a texture. This does introduce an additional full screen quad rendering, and costs another full-screen 32 bit texture, but I didn't have to change anything in ogre. Not happy with this, but I can't think of a better solution right now.