Browse Source

Allow custom forward base, lighting and alpha pass names by defining metadata in the render path, and allowing the forwardlights command to specify the pass name to use.

Lasse Öörni 12 years ago
parent
commit
7ba580852d

+ 2 - 2
Bin/CoreData/RenderPaths/Deferred.xml

@@ -3,7 +3,7 @@
     <rendertarget name="normal" rtsizedivisor="1 1" format="rgba" />
     <rendertarget name="normal" rtsizedivisor="1 1" format="rgba" />
     <rendertarget name="depth" rtsizedivisor="1 1" format="lineardepth" />
     <rendertarget name="depth" rtsizedivisor="1 1" format="lineardepth" />
     <command type="clear" color="fog" depth="1.0" stencil="0" />
     <command type="clear" color="fog" depth="1.0" stencil="0" />
-    <command type="scenepass" pass="deferred" marktostencil="true" vertexlights="true">
+    <command type="scenepass" pass="deferred" marktostencil="true" vertexlights="true" metadata="gbuffer">
         <output index="0" name="viewport" />
         <output index="0" name="viewport" />
         <output index="1" name="albedo" />
         <output index="1" name="albedo" />
         <output index="2" name="normal" />
         <output index="2" name="normal" />
@@ -15,6 +15,6 @@
         <texture unit="depth" name="depth" />
         <texture unit="depth" name="depth" />
     </command>
     </command>
     <command type="scenepass" pass="prealpha" />
     <command type="scenepass" pass="prealpha" />
-    <command type="scenepass" pass="alpha" usescissor="true" vertexlights="true" sort="backtofront" />
+    <command type="scenepass" pass="alpha" usescissor="true" vertexlights="true" sort="backtofront" metadata="alpha" />
     <command type="scenepass" pass="postalpha" sort="backtofront" />
     <command type="scenepass" pass="postalpha" sort="backtofront" />
 </renderpath>
 </renderpath>

+ 3 - 3
Bin/CoreData/RenderPaths/Forward.xml

@@ -1,8 +1,8 @@
 <renderpath>
 <renderpath>
     <command type="clear" color="fog" depth="1.0" stencil="0" />
     <command type="clear" color="fog" depth="1.0" stencil="0" />
-    <command type="scenepass" pass="base" vertexlights="true" />
-    <command type="forwardlights" />
+    <command type="scenepass" pass="base" vertexlights="true" metadata="base" />
+    <command type="forwardlights" pass="light" />
     <command type="scenepass" pass="prealpha" />
     <command type="scenepass" pass="prealpha" />
-    <command type="scenepass" pass="alpha" usescissor="true" vertexlights="true" sort="backtofront" />
+    <command type="scenepass" pass="alpha" usescissor="true" vertexlights="true" sort="backtofront" metadata="alpha" />
     <command type="scenepass" pass="postalpha" sort="backtofront" />
     <command type="scenepass" pass="postalpha" sort="backtofront" />
 </renderpath>
 </renderpath>

+ 3 - 3
Bin/CoreData/RenderPaths/ForwardDepth.xml

@@ -3,9 +3,9 @@
     <command type="clear" color="1 1 1 1" depth="1.0" output="depth" />
     <command type="clear" color="1 1 1 1" depth="1.0" output="depth" />
     <command type="scenepass" pass="depth" output="depth" />
     <command type="scenepass" pass="depth" output="depth" />
     <command type="clear" color="fog" depth="1.0" stencil="0" />
     <command type="clear" color="fog" depth="1.0" stencil="0" />
-    <command type="scenepass" pass="base" vertexlights="true" />
-    <command type="forwardlights" />
+    <command type="scenepass" pass="base" vertexlights="true" metadata="base" />
+    <command type="forwardlights" pass="light" />
     <command type="scenepass" pass="prealpha" />
     <command type="scenepass" pass="prealpha" />
-    <command type="scenepass" pass="alpha" usescissor="true" vertexlights="true" sort="backtofront" />
+    <command type="scenepass" pass="alpha" usescissor="true" vertexlights="true" sort="backtofront" metadata="alpha" />
     <command type="scenepass" pass="postalpha" sort="backtofront" />
     <command type="scenepass" pass="postalpha" sort="backtofront" />
 </renderpath>
 </renderpath>

+ 2 - 2
Bin/CoreData/RenderPaths/Prepass.xml

@@ -3,7 +3,7 @@
     <rendertarget name="normal" rtsizedivisor="1 1" format="rgba" />
     <rendertarget name="normal" rtsizedivisor="1 1" format="rgba" />
     <rendertarget name="depth" rtsizedivisor="1 1"  format="lineardepth" />
     <rendertarget name="depth" rtsizedivisor="1 1"  format="lineardepth" />
     <command type="clear" color="fog" depth="1.0" stencil="0" />
     <command type="clear" color="fog" depth="1.0" stencil="0" />
-    <command type="scenepass" pass="prepass" marktostencil="true">
+    <command type="scenepass" pass="prepass" marktostencil="true" metadata="gbuffer">
         <output index="0" name="normal" />
         <output index="0" name="normal" />
         <output index="1" name="depth" />
         <output index="1" name="depth" />
     </command>
     </command>
@@ -16,6 +16,6 @@
         <texture unit="light" name="light" />
         <texture unit="light" name="light" />
     </command>
     </command>
     <command type="scenepass" pass="prealpha"/>
     <command type="scenepass" pass="prealpha"/>
-    <command type="scenepass" pass="alpha" usescissor="true" vertexlights="true" sort="backtofront" />
+    <command type="scenepass" pass="alpha" usescissor="true" vertexlights="true" sort="backtofront" metadata="alpha" />
     <command type="scenepass" pass="postalpha" sort="backtofront" />
     <command type="scenepass" pass="postalpha" sort="backtofront" />
 </renderpath>
 </renderpath>

+ 11 - 9
Docs/Reference.dox

@@ -851,7 +851,7 @@ The available commands are:
 - clear: Clear any of color, depth and stencil. Color clear can optionally use the fog color from the Zone visible at the far clip distance.
 - clear: Clear any of color, depth and stencil. Color clear can optionally use the fog color from the Zone visible at the far clip distance.
 - scenepass: Render scene objects whose \ref Materials "material technique" contains the specified pass. Will either be front-to-back ordered with state sorting, or back-to-front ordered with no state sorting. For deferred rendering, object lightmasks can be optionally marked to the stencil buffer. Vertex lights can optionally be handled during a pass, if it has the necessary shader combinations. Textures global to the pass can be bound to free texture units; these can either be the viewport, a named rendertarget, or a 2D texture resource identified with its pathname.
 - scenepass: Render scene objects whose \ref Materials "material technique" contains the specified pass. Will either be front-to-back ordered with state sorting, or back-to-front ordered with no state sorting. For deferred rendering, object lightmasks can be optionally marked to the stencil buffer. Vertex lights can optionally be handled during a pass, if it has the necessary shader combinations. Textures global to the pass can be bound to free texture units; these can either be the viewport, a named rendertarget, or a 2D texture resource identified with its pathname.
 - quad: Render a viewport-sized quad using the specified shaders. Textures can be bound and additionally Vector4 shader parameters can be specified.
 - quad: Render a viewport-sized quad using the specified shaders. Textures can be bound and additionally Vector4 shader parameters can be specified.
-- forwardlights: Render per-pixel forward lighting for opaque objects. Shadow maps are also rendered as necessary.
+- forwardlights: Render per-pixel forward lighting for opaque objects with the specified pass name. Shadow maps are also rendered as necessary.
 - lightvolumes: Render deferred light volumes using the specified shaders. G-buffer textures can be bound as necessary.
 - lightvolumes: Render deferred light volumes using the specified shaders. G-buffer textures can be bound as necessary.
 
 
 A render path can be loaded from a main XML file by calling \ref RenderPath::Load "Load()", after which other XML files (for example one for each post-processing effect) can be appended to it by calling \ref RenderPath::Append "Append()". Rendertargets and commands can be enabled or disabled by calling \ref RenderPath::SetEnabled "SetEnabled()" to switch eg. a post-processing effect on or off. To aid in this, both can be identified by tag names, for example the bloom effect uses the tag "Bloom" for all of its rendertargets and commands.
 A render path can be loaded from a main XML file by calling \ref RenderPath::Load "Load()", after which other XML files (for example one for each post-processing effect) can be appended to it by calling \ref RenderPath::Append "Append()". Rendertargets and commands can be enabled or disabled by calling \ref RenderPath::SetEnabled "SetEnabled()" to switch eg. a post-processing effect on or off. To aid in this, both can be identified by tag names, for example the bloom effect uses the tag "Bloom" for all of its rendertargets and commands.
@@ -865,7 +865,7 @@ The render path XML definition looks like this:
     <rendertarget name="RTName" tag="TagName" enabled="true|false" size="x y"|sizedivisor="x y"|rtsizedivisor="x y"
     <rendertarget name="RTName" tag="TagName" enabled="true|false" size="x y"|sizedivisor="x y"|rtsizedivisor="x y"
         format="rgb|rgba|r32f|rgba16|rgba16f|rgba32f|rg16|rg16f|rg32f|lineardepth" filter="true|false" srgb="true|false" />
         format="rgb|rgba|r32f|rgba16|rgba16f|rgba32f|rg16|rg16f|rg32f|lineardepth" filter="true|false" srgb="true|false" />
     <command type="clear" tag="TagName" enabled="true|false" clearcolor="r g b a|fog" cleardepth="x" clearstencil="y" output="viewport|RTName" />
     <command type="clear" tag="TagName" enabled="true|false" clearcolor="r g b a|fog" cleardepth="x" clearstencil="y" output="viewport|RTName" />
-    <command type="scenepass" pass="PassName" sort="fronttoback|backtofront" marktostencil="true|false" usescissor="true|false" vertexlights="true|false">
+    <command type="scenepass" pass="PassName" sort="fronttoback|backtofront" marktostencil="true|false" usescissor="true|false" vertexlights="true|false" metadata="base|alpha|gbuffer" >
         <output index="0" name="RTName1" />
         <output index="0" name="RTName1" />
         <output index="1" name="RTName2" />
         <output index="1" name="RTName2" />
         <output index="2" name="RTName3" />
         <output index="2" name="RTName3" />
@@ -875,7 +875,7 @@ The render path XML definition looks like this:
         <texture unit="unit" name="viewport|RTName|TextureName" />
         <texture unit="unit" name="viewport|RTName|TextureName" />
         <shaderparameter name="ParameterName" value="x y z w" />
         <shaderparameter name="ParameterName" value="x y z w" />
     </command>
     </command>
-    <command type="forwardlights" uselitbase="true|false" output="viewport|RTName" />
+    <command type="forwardlights" pass="PassName" uselitbase="true|false" output="viewport|RTName" />
     <command type="lightvolumes"  vs="VertexShaderName" ps="PixelShaderName" output="viewport|RTName" />
     <command type="lightvolumes"  vs="VertexShaderName" ps="PixelShaderName" output="viewport|RTName" />
         <texture unit="unit" name="viewport|RTName|TextureName" />
         <texture unit="unit" name="viewport|RTName|TextureName" />
     </command>
     </command>
@@ -884,14 +884,16 @@ The render path XML definition looks like this:
 
 
 Note the special "lineardepth" format available for rendertargets. This is intended for storing scene depth in deferred rendering. It will be D3DFMT_R32F on Direct3D9, but RGBA on OpenGL, due to the limitation of all color buffers having to be the same format. The file Samplers.frag in Bin/CoreData/Shaders/GLSL provides functions to encode and decode linear depth to RGB.
 Note the special "lineardepth" format available for rendertargets. This is intended for storing scene depth in deferred rendering. It will be D3DFMT_R32F on Direct3D9, but RGBA on OpenGL, due to the limitation of all color buffers having to be the same format. The file Samplers.frag in Bin/CoreData/Shaders/GLSL provides functions to encode and decode linear depth to RGB.
 
 
-\section RenderPaths_HardCodedPasses Hardcoded scene passes
+\section RenderPaths_ForwardLighting Forward lighting special considerations
 
 
-Otherwise fully customized scene render passes can be specified, but there are a few exceptions related to forward per-pixel lighting.
-
-- The "light" and "litbase" passes will be automatically rendered by the forwardlights command, interleaved with shadow map rendering as necessary.
-- The "litalpha" pass for transparent objects is automatically merged with the "alpha" pass, if it exists in the render path definition. The idea is that all transparent objects are sorted back to front, and their base passes (the actual "alpha" pass) are rendered first, followed by their additive pixel-lit passes. The "usescissor" flag in the scenepass command should be set to true, so that scissor rectangles limit the effect of lights on transparent objects.
-- The forwardlights command can optionally disable the "litbase" pass optimization without having to touch the material techniques, if a separate opaque ambient-only base pass is needed. By default the optimization is enabled.
+Otherwise fully customized scene render passes can be specified, but there are a few things to remember related to forward lighting:
 
 
+- The opaque base pass must be tagged with metadata "base". When forward lighting logic does the lit base pass optimization, it will search for a pass with the word "lit" prepended, ie. if your custom opaque base pass is
+  called "custombase", the corresponding lit base pass would be "litcustombase".
+- The transparent base pass must be tagged with metadata "alpha". For lit transparent objects, the forward lighting logic will look for a pass with the word "lit" prepended, ie. if the custom alpha base pass is called "customalpha", the corresponding lit pass is "litcustomalpha". The lit drawcalls will be interleaved with the transparent base pass, and the scenepass command should have back-to-front sorting enabled.
+- If forward and deferred lighting are mixed, the G-buffer writing pass must be tagged with metadata "gbuffer" to prevent geometry being double-lit also with forward lights.
+- Remember to mark the lighting mode (per-vertex / per-pixel) into the techniques which define custom passes, as the lighting mode can be guessed automatically only for the known default passes.
+- The forwardlights command can optionally disable the lit base pass optimization without having to touch the material techniques, if a separate opaque ambient-only base pass is needed. By default the optimization is enabled.
 
 
 \page Lights Lights and shadows
 \page Lights Lights and shadows
 
 

+ 2 - 1
Docs/ScriptAPI.dox

@@ -1778,7 +1778,8 @@ Properties:<br>
 - String tag
 - String tag
 - RenderCommandType type
 - RenderCommandType type
 - RenderCommandSortMode sortMode
 - RenderCommandSortMode sortMode
-- StringHash pass
+- String pass
+- String metadata
 - uint clearFlags
 - uint clearFlags
 - Color clearColor
 - Color clearColor
 - float clearDepth
 - float clearDepth

+ 2 - 1
Engine/Engine/GraphicsAPI.cpp

@@ -313,7 +313,8 @@ static void RegisterRenderPath(asIScriptEngine* engine)
     engine->RegisterObjectProperty("RenderPathCommand", "String tag", offsetof(RenderPathCommand, tag_));
     engine->RegisterObjectProperty("RenderPathCommand", "String tag", offsetof(RenderPathCommand, tag_));
     engine->RegisterObjectProperty("RenderPathCommand", "RenderCommandType type", offsetof(RenderPathCommand, type_));
     engine->RegisterObjectProperty("RenderPathCommand", "RenderCommandType type", offsetof(RenderPathCommand, type_));
     engine->RegisterObjectProperty("RenderPathCommand", "RenderCommandSortMode sortMode", offsetof(RenderPathCommand, sortMode_));
     engine->RegisterObjectProperty("RenderPathCommand", "RenderCommandSortMode sortMode", offsetof(RenderPathCommand, sortMode_));
-    engine->RegisterObjectProperty("RenderPathCommand", "StringHash pass", offsetof(RenderPathCommand, pass_));
+    engine->RegisterObjectProperty("RenderPathCommand", "String pass", offsetof(RenderPathCommand, pass_));
+    engine->RegisterObjectProperty("RenderPathCommand", "String metadata", offsetof(RenderPathCommand, metadata_));
     engine->RegisterObjectProperty("RenderPathCommand", "uint clearFlags", offsetof(RenderPathCommand, clearFlags_));
     engine->RegisterObjectProperty("RenderPathCommand", "uint clearFlags", offsetof(RenderPathCommand, clearFlags_));
     engine->RegisterObjectProperty("RenderPathCommand", "Color clearColor", offsetof(RenderPathCommand, clearColor_));
     engine->RegisterObjectProperty("RenderPathCommand", "Color clearColor", offsetof(RenderPathCommand, clearColor_));
     engine->RegisterObjectProperty("RenderPathCommand", "float clearDepth", offsetof(RenderPathCommand, clearDepth_));
     engine->RegisterObjectProperty("RenderPathCommand", "float clearDepth", offsetof(RenderPathCommand, clearDepth_));

+ 3 - 0
Engine/Graphics/RenderPath.cpp

@@ -92,6 +92,8 @@ void RenderPathCommand::Load(const XMLElement& element)
     tag_ = element.GetAttribute("tag");
     tag_ = element.GetAttribute("tag");
     if (element.HasAttribute("enabled"))
     if (element.HasAttribute("enabled"))
         enabled_ = element.GetBool("enabled");
         enabled_ = element.GetBool("enabled");
+    if (element.HasAttribute("metadata"))
+        metadata_ = element.GetAttribute("metadata");
     
     
     switch (type_)
     switch (type_)
     {
     {
@@ -129,6 +131,7 @@ void RenderPathCommand::Load(const XMLElement& element)
         break;
         break;
         
         
     case CMD_FORWARDLIGHTS:
     case CMD_FORWARDLIGHTS:
+        pass_ = element.GetAttribute("pass");
         if (element.HasAttribute("uselitbase"))
         if (element.HasAttribute("uselitbase"))
             useLitBase_ = element.GetBool("uselitbase");
             useLitBase_ = element.GetBool("uselitbase");
         break;
         break;

+ 5 - 3
Engine/Graphics/RenderPath.h

@@ -121,7 +121,7 @@ struct RenderPathCommand
     
     
     /// Return texture resource name.
     /// Return texture resource name.
     const String& GetTextureName(TextureUnit unit) const;
     const String& GetTextureName(TextureUnit unit) const;
-    /// Return shader paramter.
+    /// Return shader parameter.
     const Vector4& GetShaderParameter(const String& name) const;
     const Vector4& GetShaderParameter(const String& name) const;
     /// Return number of output rendertargets.
     /// Return number of output rendertargets.
     unsigned GetNumOutputs() const { return outputNames_.Size(); }
     unsigned GetNumOutputs() const { return outputNames_.Size(); }
@@ -134,8 +134,10 @@ struct RenderPathCommand
     RenderCommandType type_;
     RenderCommandType type_;
     /// Sorting mode.
     /// Sorting mode.
     RenderCommandSortMode sortMode_;
     RenderCommandSortMode sortMode_;
-    /// Scene pass hash.
-    StringHash pass_;
+    /// Scene pass name.
+    String pass_;
+    /// Command/pass metadata.
+    String metadata_;
     /// Clear flags.
     /// Clear flags.
     unsigned clearFlags_;
     unsigned clearFlags_;
     /// Clear color.
     /// Clear color.

+ 36 - 7
Engine/Graphics/View.cpp

@@ -299,6 +299,13 @@ bool View::Define(RenderSurface* renderTarget, Viewport* viewport)
     renderTarget_ = renderTarget;
     renderTarget_ = renderTarget;
     renderPath_ = viewport->GetRenderPath();
     renderPath_ = viewport->GetRenderPath();
     
     
+    gBufferPassName_ = StringHash();
+    basePassName_  = PASS_BASE;
+    alphaPassName_ = PASS_ALPHA;
+    lightPassName_ = PASS_LIGHT;
+    litBasePassName_ = PASS_LITBASE;
+    litAlphaPassName_ = PASS_LITALPHA;
+    
     // Make sure that all necessary batch queues exist
     // Make sure that all necessary batch queues exist
     scenePasses_.Clear();
     scenePasses_.Clear();
     for (unsigned i = 0; i < renderPath_->commands_.Size(); ++i)
     for (unsigned i = 0; i < renderPath_->commands_.Size(); ++i)
@@ -316,6 +323,23 @@ bool View::Define(RenderSurface* renderTarget, Viewport* viewport)
             info.useScissor_ = command.useScissor_;
             info.useScissor_ = command.useScissor_;
             info.vertexLights_ = command.vertexLights_;
             info.vertexLights_ = command.vertexLights_;
             
             
+            // Check scenepass metadata for defining custom passes which interact with lighting
+            if (command.metadata_.Length())
+            {
+                if (!command.metadata_.Compare("gbuffer", false))
+                    gBufferPassName_ = command.pass_;
+                if (!command.metadata_.Compare("base", false))
+                {
+                    basePassName_ = command.pass_;
+                    litBasePassName_ = "lit" + command.pass_;
+                }
+                if (!command.metadata_.Compare("alpha", false))
+                {
+                    alphaPassName_ = command.pass_;
+                    litAlphaPassName_ = "lit" + command.pass_;
+                }
+            }
+            
             HashMap<StringHash, BatchQueue>::Iterator j = batchQueues_.Find(command.pass_);
             HashMap<StringHash, BatchQueue>::Iterator j = batchQueues_.Find(command.pass_);
             if (j == batchQueues_.End())
             if (j == batchQueues_.End())
                 j = batchQueues_.Insert(Pair<StringHash, BatchQueue>(command.pass_, BatchQueue()));
                 j = batchQueues_.Insert(Pair<StringHash, BatchQueue>(command.pass_, BatchQueue()));
@@ -323,6 +347,11 @@ bool View::Define(RenderSurface* renderTarget, Viewport* viewport)
             
             
             scenePasses_.Push(info);
             scenePasses_.Push(info);
         }
         }
+        else if (command.type_ == CMD_FORWARDLIGHTS)
+        {
+            if (!command.pass_.Trimmed().Empty())
+                lightPassName_ = command.pass_;
+        }
     }
     }
     
     
     // Get light volume shaders according to the renderpath, if it needs them
     // Get light volume shaders according to the renderpath, if it needs them
@@ -686,7 +715,7 @@ void View::GetBatches()
 {
 {
     WorkQueue* queue = GetSubsystem<WorkQueue>();
     WorkQueue* queue = GetSubsystem<WorkQueue>();
     PODVector<Light*> vertexLights;
     PODVector<Light*> vertexLights;
-    BatchQueue* alphaQueue = batchQueues_.Contains(PASS_ALPHA) ? &batchQueues_[PASS_ALPHA] : (BatchQueue*)0;
+    BatchQueue* alphaQueue = batchQueues_.Contains(alphaPassName_) ? &batchQueues_[alphaPassName_] : (BatchQueue*)0;
     
     
     // Check whether to use the lit base pass optimization
     // Check whether to use the lit base pass optimization
     bool useLitBase = true;
     bool useLitBase = true;
@@ -930,7 +959,7 @@ void View::GetBatches()
                         continue;
                         continue;
                     
                     
                     // Skip forward base pass if the corresponding litbase pass already exists
                     // Skip forward base pass if the corresponding litbase pass already exists
-                    if (info.pass_ == PASS_BASE && j < 32 && drawable->HasBasePass(j))
+                    if (info.pass_ == basePassName_ && j < 32 && drawable->HasBasePass(j))
                         continue;
                         continue;
                     
                     
                     if (info.vertexLights_ && !drawableVertexLights.Empty())
                     if (info.vertexLights_ && !drawableVertexLights.Empty())
@@ -1089,7 +1118,7 @@ void View::GetLitBatches(Drawable* drawable, LightBatchQueue& lightQueue, BatchQ
             continue;
             continue;
         
         
         // Do not create pixel lit forward passes for materials that render into the G-buffer
         // Do not create pixel lit forward passes for materials that render into the G-buffer
-        if (deferred_ && (tech->HasPass(PASS_PREPASS) || tech->HasPass(PASS_DEFERRED)))
+        if (gBufferPassName_.Value() && tech->HasPass(gBufferPassName_))
             continue;
             continue;
         
         
         Batch destBatch(srcBatch);
         Batch destBatch(srcBatch);
@@ -1099,22 +1128,22 @@ void View::GetLitBatches(Drawable* drawable, LightBatchQueue& lightQueue, BatchQ
         // Also vertex lighting or ambient gradient require the non-lit base pass, so skip in those cases
         // Also vertex lighting or ambient gradient require the non-lit base pass, so skip in those cases
         if (i < 32 && allowLitBase)
         if (i < 32 && allowLitBase)
         {
         {
-            destBatch.pass_ = tech->GetPass(PASS_LITBASE);
+            destBatch.pass_ = tech->GetPass(litBasePassName_);
             if (destBatch.pass_)
             if (destBatch.pass_)
             {
             {
                 destBatch.isBase_ = true;
                 destBatch.isBase_ = true;
                 drawable->SetBasePass(i);
                 drawable->SetBasePass(i);
             }
             }
             else
             else
-                destBatch.pass_ = tech->GetPass(PASS_LIGHT);
+                destBatch.pass_ = tech->GetPass(lightPassName_);
         }
         }
         else
         else
-            destBatch.pass_ = tech->GetPass(PASS_LIGHT);
+            destBatch.pass_ = tech->GetPass(lightPassName_);
         
         
         // If no lit pass, check for lit alpha
         // If no lit pass, check for lit alpha
         if (!destBatch.pass_)
         if (!destBatch.pass_)
         {
         {
-            destBatch.pass_ = tech->GetPass(PASS_LITALPHA);
+            destBatch.pass_ = tech->GetPass(litAlphaPassName_);
             isLitAlpha = true;
             isLitAlpha = true;
         }
         }
         
         

+ 12 - 0
Engine/Graphics/View.h

@@ -290,6 +290,18 @@ private:
     HashMap<unsigned long long, LightBatchQueue> vertexLightQueues_;
     HashMap<unsigned long long, LightBatchQueue> vertexLightQueues_;
     /// Batch queues.
     /// Batch queues.
     HashMap<StringHash, BatchQueue> batchQueues_;
     HashMap<StringHash, BatchQueue> batchQueues_;
+    /// Hash of the GBuffer pass, or null if none.
+    StringHash gBufferPassName_;
+    /// Hash of the opaque forward base pass.
+    StringHash basePassName_;
+    /// Hash of the alpha pass.
+    StringHash alphaPassName_;
+    /// Hash of the forward light pass.
+    StringHash lightPassName_;
+    /// Hash of the litbase pass.
+    StringHash litBasePassName_;
+    /// Hash of the litalpha pass.
+    StringHash litAlphaPassName_;
 };
 };
 
 
 }
 }