Browse Source

engine:
defines and alters a series of material features for deferred shading in order to define a fully fleshed out multiple render target gbuffer patterned after the general principles outlined http://www.catalinzima.com/xna/tutorials/deferred-rendering-in-xna/creating-the-g-buffer/ (though I cannot stress enough *not* using the identical layout)

script:
removes dead material features (ie: those that never functioned to begin with)

shader:
bool getFlag(float flags, int num) definition for retreiving data from the 3rd (matinfo) gbuffer slot's red channel (more on that shortly)

purpose:
_A)_ Small primer on how material features function:
When a https://github.com/GarageGames/Torque3D/search?utf8=%E2%9C%93&q=_determineFeatures call is executed, certain conditions trigger a given .addFeature(MFT_SOMEFEATURE) call based upon material definition entries, be it a value, a texture reference, or even the presence or lack thereof for another feature. In general terms, the first to be executed is ProcessedShaderMaterial::_determineFeatures followed by ProcessedPrePassMaterial::_determineFeatures. The next commit will provide the bindings there. For now it's enough to understand that one of those two will trigger the shadergen subsystem, when rendering a material, to check it's associated list of features and spit out a shader if one is not already defined, or reference a pre-existing one that includes codelines determined by that list of features.

Relevant execution of this is as follows:
DeclareFeatureType( MFT_DeferredDiffuseMap ); - Name
ImplementFeatureType( MFT_DeferredDiffuseMap, MFG_Texture, 2.0f, false ); - Codeline Insertion Order
FEATUREMGR->registerFeature( MFT_DeferredDiffuseMap, new DeferredDiffuseMapHLSL ); - Hook to class which actually generates code
alternately FEATUREMGR->registerFeature( MFT_Imposter, new NamedFeatureHLSL( "Imposter" ) ); - a simple feature that serves no purpose further than as a test of it's existence (to modify other features for instance)

class DeferredDiffuseMapHLSL : public ShaderFeatureHLSL - Class definition
{
getName -embeded in the proceedural shader as a remline both up top and before actual code insertions
processPix - pixel shader codeline insertions
getOutputTargets - used to determine which buffer is written to (assumes only one. depending on branched logic, older features that may be run for either forward or deferred rendering depending on circumstance may have a logical switch based on additional feature flags. as an example: TerrainBaseMapFeatHLSL::getOutputTargets)
getResources - associated with the Resources struct, closely aligned with the hardware regestry
getBlendOp - used to determine what blend operation to use if a material requires a second pass (defaults to overwriting)
setTexData - ???
processVert - vertex shader codeline insertions
};

_B)_
The resultant Gbuffer layout defined by the previous commit therefore is as follows:
defaultrendertarget (referred to in shaders as out.col or col depending on GFX plugin) contains either lighting and normal data, or color data depending on if it is used in a deferred or forward lit manner (note for forward lit, this data is replaced as a second step with color. why custommaterials have traditionally had problems with lighting)
color1 (referred to in shaders as out.col1 or col1 depending on GFX plugin) RGB color data and an A for blending operations (including transparency)
color2 (referred to in shaders as out.col2 or col2 depending on GFX plugin) contains:
red channel comprising material flags such as metalness, emissive, ect,
green channel for translucency (light shining through, as oposed to see-through transparency), blue for
blue for specular strength (how much light influences net color)
alpha for specular power (generally how reflective/glossy an object is)

long term purpose:
further down the line, these will be used to condition data for use with a PBR subsystem, with further corrections to the underlying mathematics, strength being replaced by roughness, and power by metalness

Azaezel 9 years ago
parent
commit
196b214eae
25 changed files with 1257 additions and 486 deletions
  1. 190 0
      Engine/source/lighting/advanced/glsl/deferredShadingFeaturesGLSL.cpp
  2. 85 0
      Engine/source/lighting/advanced/glsl/deferredShadingFeaturesGLSL.h
  3. 187 0
      Engine/source/lighting/advanced/hlsl/deferredShadingFeaturesHLSL.cpp
  4. 84 0
      Engine/source/lighting/advanced/hlsl/deferredShadingFeaturesHLSL.h
  5. 15 5
      Engine/source/materials/materialFeatureTypes.cpp
  6. 10 2
      Engine/source/materials/materialFeatureTypes.h
  7. 138 46
      Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp
  8. 11 0
      Engine/source/shaderGen/GLSL/shaderFeatureGLSL.h
  9. 4 1
      Engine/source/shaderGen/GLSL/shaderGenGLSL.h
  10. 14 7
      Engine/source/shaderGen/GLSL/shaderGenGLSLInit.cpp
  11. 125 27
      Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp
  12. 11 0
      Engine/source/shaderGen/HLSL/shaderFeatureHLSL.h
  13. 12 0
      Engine/source/shaderGen/HLSL/shaderGenHLSLInit.cpp
  14. 16 2
      Engine/source/shaderGen/shaderFeature.cpp
  15. 4 1
      Engine/source/shaderGen/shaderGenVars.cpp
  16. 3 0
      Engine/source/shaderGen/shaderGenVars.h
  17. 174 85
      Engine/source/terrain/glsl/terrFeatureGLSL.cpp
  18. 17 0
      Engine/source/terrain/glsl/terrFeatureGLSL.h
  19. 102 77
      Engine/source/terrain/hlsl/terrFeatureHLSL.cpp
  20. 17 0
      Engine/source/terrain/hlsl/terrFeatureHLSL.h
  21. 21 9
      Engine/source/terrain/terrCellMaterial.cpp
  22. 5 1
      Engine/source/terrain/terrFeatureTypes.cpp
  23. 6 0
      Engine/source/terrain/terrFeatureTypes.h
  24. 1 0
      Templates/Full/game/shaders/common/terrain/terrain.glsl
  25. 5 223
      Templates/Full/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui

+ 190 - 0
Engine/source/lighting/advanced/glsl/deferredShadingFeaturesGLSL.cpp

@@ -0,0 +1,190 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "platform/platform.h"
+#include "lighting/advanced/glsl/deferredShadingFeaturesGLSL.h"
+
+#include "lighting/advanced/advancedLightBinManager.h"
+#include "shaderGen/langElement.h"
+#include "shaderGen/shaderOp.h"
+#include "shaderGen/conditionerFeature.h"
+#include "renderInstance/renderPrePassMgr.h"
+#include "materials/processedMaterial.h"
+#include "materials/materialFeatureTypes.h"
+
+
+//****************************************************************************
+// Deferred Shading Features
+//****************************************************************************
+
+// Specular Map -> Blue of Material Buffer ( greyscaled )
+// Gloss Map (Alpha Channel of Specular Map) -> Alpha ( Spec Power ) of Material Info Buffer.
+void DeferredSpecMapGLSL::processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+{
+   // Get the texture coord.
+   Var *texCoord = getInTexCoord( "texCoord", "vec2", true, componentList );
+
+   // search for color var
+   Var *material = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
+   MultiLine * meta = new MultiLine;
+   if ( !material )
+   {
+      // create color var
+      material = new Var;
+      material->setType( "vec4" );
+      material->setName( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
+      material->setStructName("OUT");
+   }
+
+   // create texture var
+   Var *specularMap = new Var;
+   specularMap->setType( "sampler2D" );
+   specularMap->setName( "specularMap" );
+   specularMap->uniform = true;
+   specularMap->sampler = true;
+   specularMap->constNum = Var::getTexUnitNum();
+   LangElement *texOp = new GenOp( "tex2D(@, @)", specularMap, texCoord );
+   //matinfo.g slot reserved for AO later
+   meta->addStatement(new GenOp("   @.g = 1.0;\r\n", material));
+   meta->addStatement(new GenOp("   @.b = dot(tex2D(@, @).rgb, vec3(0.3, 0.59, 0.11));\r\n", material, specularMap, texCoord));
+   meta->addStatement(new GenOp("   @.a = tex2D(@, @).a;\r\n", material, specularMap, texCoord));
+   output = meta;
+}
+
+ShaderFeature::Resources DeferredSpecMapGLSL::getResources( const MaterialFeatureData &fd )
+{
+   Resources res; 
+   res.numTex = 1;
+   res.numTexReg = 1;
+
+   return res;
+}
+
+void DeferredSpecMapGLSL::setTexData(   Material::StageData &stageDat,
+                                       const MaterialFeatureData &fd,
+                                       RenderPassData &passData,
+                                       U32 &texIndex )
+{
+   GFXTextureObject *tex = stageDat.getTex( MFT_SpecularMap );
+   if ( tex )
+   {
+      passData.mTexType[ texIndex ] = Material::Standard;
+      passData.mSamplerNames[ texIndex ] = "specularMap";
+      passData.mTexSlot[ texIndex++ ].texObject = tex;
+   }
+}
+
+void DeferredSpecMapGLSL::processVert( Vector<ShaderComponent*> &componentList, 
+                                       const MaterialFeatureData &fd )
+{
+   MultiLine *meta = new MultiLine;
+   getOutTexCoord(   "texCoord", 
+                     "vec2", 
+                     true, 
+                     fd.features[MFT_TexAnim], 
+                     meta, 
+                     componentList );
+   output = meta;
+}
+
+// Material Info Flags -> Red ( Flags ) of Material Info Buffer.
+void DeferredMatInfoFlagsGLSL::processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+{
+	MultiLine *meta = new MultiLine;
+
+   // search for material var
+   Var *material = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
+   if ( !material )
+   {
+      // create material var
+      material = new Var;
+      material->setType( "vec4" );
+      material->setName( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
+      material->setStructName("OUT");
+   }
+
+   Var *matInfoFlags = new Var;
+   matInfoFlags->setType( "float" );
+   matInfoFlags->setName( "matInfoFlags" );
+   matInfoFlags->uniform = true;
+   matInfoFlags->constSortPos = cspPotentialPrimitive;
+
+   meta->addStatement(output = new GenOp("   @.r = @;\r\n", material, matInfoFlags));
+   output = meta;
+}
+
+// Spec Strength -> Blue Channel of Material Info Buffer.
+// Spec Power -> Alpha Channel ( of Material Info Buffer.
+void DeferredSpecVarsGLSL::processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+{
+
+   // search for material var
+   Var *material = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
+   if ( !material )
+   {
+      // create material var
+      material = new Var;
+      material->setType( "vec4" );
+      material->setName( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
+      material->setStructName("OUT");
+   }
+
+   Var *specStrength = new Var;
+   specStrength->setType( "float" );
+   specStrength->setName( "specularStrength" );
+   specStrength->uniform = true;
+   specStrength->constSortPos = cspPotentialPrimitive;
+
+   Var *specPower = new Var;
+   specPower->setType("float");
+   specPower->setName("specularPower");
+   specPower->uniform = true;
+   specPower->constSortPos = cspPotentialPrimitive;
+
+   MultiLine *meta = new MultiLine;
+   //matinfo.g slot reserved for AO later
+   meta->addStatement(new GenOp("   @.g = 1.0;\r\n", material));
+   meta->addStatement(new GenOp("   @.b = @/128;\r\n", material, specStrength));
+   meta->addStatement(new GenOp("   @.a = @/5;\r\n", material, specPower));
+   output = meta;
+}
+
+// Black -> Blue and Alpha of Color Buffer (representing no specular)
+void DeferredEmptySpecGLSL::processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+{    
+   // search for material var
+   Var *material = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
+   if ( !material )
+   {
+      // create material var
+      material = new Var;
+      material->setType( "vec4" );
+      material->setName( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
+      material->setStructName("OUT");
+   }
+
+   MultiLine * meta = new MultiLine;
+   //matinfo.g slot reserved for AO later
+   meta->addStatement(new GenOp("   @.g = 1.0;\r\n", material));
+   meta->addStatement(new GenOp("   @.ba = vec2(0.0);\r\n", material));
+   output = meta;
+}

+ 85 - 0
Engine/source/lighting/advanced/glsl/deferredShadingFeaturesGLSL.h

@@ -0,0 +1,85 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _DEFERREDSHADINGGLSL_H_
+#define _DEFERREDSHADINGGLSL_H_
+
+#include "shaderGen/GLSL/shaderFeatureGLSL.h"
+#include "shaderGen/GLSL/bumpGLSL.h"
+#include "shaderGen/GLSL/pixSpecularGLSL.h"
+
+// Specular Outputs
+class DeferredSpecMapGLSL : public ShaderFeatureGLSL
+{
+public:
+   virtual String getName() { return "Deferred Shading: Specular Map"; }
+
+   virtual void processPix( Vector<ShaderComponent*> &componentList, 
+      const MaterialFeatureData &fd );
+   
+   virtual Resources getResources( const MaterialFeatureData &fd );
+
+   // Sets textures and texture flags for current pass
+   virtual void setTexData( Material::StageData &stageDat,
+                            const MaterialFeatureData &fd,
+                            RenderPassData &passData,
+                            U32 &texIndex );
+   
+   virtual void processVert( Vector<ShaderComponent*> &componentList,
+                             const MaterialFeatureData &fd );
+};
+
+class DeferredMatInfoFlagsGLSL : public ShaderFeatureGLSL
+{
+public:
+   virtual String getName() { return "Deferred Shading: Mat Info Flags"; }
+
+   virtual void processPix( Vector<ShaderComponent*> &componentList, 
+      const MaterialFeatureData &fd );
+   
+   virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const { return ShaderFeature::RenderTarget2; }
+};
+
+class DeferredSpecVarsGLSL : public ShaderFeatureGLSL
+{
+public:
+   virtual String getName() { return "Deferred Shading: Specular Explicit Numbers"; }
+
+   virtual void processPix( Vector<ShaderComponent*> &componentList, 
+      const MaterialFeatureData &fd );
+   
+   virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const { return ShaderFeature::RenderTarget2; }
+};
+
+
+class DeferredEmptySpecGLSL : public ShaderFeatureGLSL
+{
+public:
+   virtual String getName() { return "Deferred Shading: Empty Specular"; }
+
+   virtual void processPix( Vector<ShaderComponent*> &componentList, 
+      const MaterialFeatureData &fd );
+   
+   virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const { return ShaderFeature::RenderTarget2; }
+};
+
+#endif

+ 187 - 0
Engine/source/lighting/advanced/hlsl/deferredShadingFeaturesHLSL.cpp

@@ -0,0 +1,187 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "platform/platform.h"
+#include "lighting/advanced/hlsl/deferredShadingFeaturesHLSL.h"
+
+#include "lighting/advanced/advancedLightBinManager.h"
+#include "shaderGen/langElement.h"
+#include "shaderGen/shaderOp.h"
+#include "shaderGen/conditionerFeature.h"
+#include "renderInstance/renderPrePassMgr.h"
+#include "materials/processedMaterial.h"
+#include "materials/materialFeatureTypes.h"
+
+
+//****************************************************************************
+// Deferred Shading Features
+//****************************************************************************
+
+// Specular Map -> Blue of Material Buffer ( greyscaled )
+// Gloss Map (Alpha Channel of Specular Map) -> Alpha ( Spec Power ) of Material Info Buffer.
+void DeferredSpecMapHLSL::processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+{
+   // Get the texture coord.
+   Var *texCoord = getInTexCoord( "texCoord", "float2", true, componentList );
+
+   // search for color var
+   Var *material = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
+   MultiLine * meta = new MultiLine;
+   if ( !material )
+   {
+      // create color var
+      material = new Var;
+      material->setType( "fragout" );
+      material->setName( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
+      material->setStructName( "OUT" );
+   }
+
+   // create texture var
+   Var *specularMap = new Var;
+   specularMap->setType( "sampler2D" );
+   specularMap->setName( "specularMap" );
+   specularMap->uniform = true;
+   specularMap->sampler = true;
+   specularMap->constNum = Var::getTexUnitNum();
+   LangElement *texOp = new GenOp( "tex2D(@, @)", specularMap, texCoord );
+
+   //matinfo.g slot reserved for AO later
+   meta->addStatement(new GenOp("   @.g = 1.0;\r\n", material));
+   meta->addStatement(new GenOp("   @.b = dot(tex2D(@, @).rgb, float3(0.3, 0.59, 0.11));\r\n", material, specularMap, texCoord));
+   meta->addStatement(new GenOp("   @.a = tex2D(@, @).a;\r\n", material, specularMap, texCoord));
+   output = meta;
+}
+
+ShaderFeature::Resources DeferredSpecMapHLSL::getResources( const MaterialFeatureData &fd )
+{
+   Resources res; 
+   res.numTex = 1;
+   res.numTexReg = 1;
+
+   return res;
+}
+
+void DeferredSpecMapHLSL::setTexData(   Material::StageData &stageDat,
+                                       const MaterialFeatureData &fd,
+                                       RenderPassData &passData,
+                                       U32 &texIndex )
+{
+   GFXTextureObject *tex = stageDat.getTex( MFT_SpecularMap );
+   if ( tex )
+   {
+      passData.mTexType[ texIndex ] = Material::Standard;
+      passData.mSamplerNames[ texIndex ] = "specularMap";
+      passData.mTexSlot[ texIndex++ ].texObject = tex;
+   }
+}
+
+void DeferredSpecMapHLSL::processVert( Vector<ShaderComponent*> &componentList, 
+                                       const MaterialFeatureData &fd )
+{
+   MultiLine *meta = new MultiLine;
+   getOutTexCoord(   "texCoord", 
+                     "float2", 
+                     true, 
+                     fd.features[MFT_TexAnim], 
+                     meta, 
+                     componentList );
+   output = meta;
+}
+
+// Material Info Flags -> Red ( Flags ) of Material Info Buffer.
+void DeferredMatInfoFlagsHLSL::processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+{
+   // search for material var
+   Var *material = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
+   if ( !material )
+   {
+      // create material var
+      material = new Var;
+      material->setType( "fragout" );
+      material->setName( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
+      material->setStructName( "OUT" );
+   }
+
+   Var *matInfoFlags = new Var;
+   matInfoFlags->setType( "float" );
+   matInfoFlags->setName( "matInfoFlags" );
+   matInfoFlags->uniform = true;
+   matInfoFlags->constSortPos = cspPotentialPrimitive;
+
+   output = new GenOp( "   @.r = @;\r\n", material, matInfoFlags );
+}
+
+// Spec Strength -> Blue Channel of Material Info Buffer.
+// Spec Power -> Alpha Channel ( of Material Info Buffer.
+void DeferredSpecVarsHLSL::processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+{
+   // search for material var
+   Var *material = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
+   if ( !material )
+   {
+      // create material var
+      material = new Var;
+      material->setType( "fragout" );
+      material->setName( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
+      material->setStructName( "OUT" );
+   }
+
+   Var *specStrength = new Var;
+   specStrength->setType( "float" );
+   specStrength->setName( "specularStrength" );
+   specStrength->uniform = true;
+   specStrength->constSortPos = cspPotentialPrimitive;
+
+   Var *specPower = new Var;
+   specPower->setType( "float" );
+   specPower->setName( "specularPower" );
+   specPower->uniform = true;
+   specPower->constSortPos = cspPotentialPrimitive;
+
+   MultiLine * meta = new MultiLine;
+   //matinfo.g slot reserved for AO later
+   meta->addStatement(new GenOp("   @.g = 1.0;\r\n", material));
+   meta->addStatement(new GenOp("   @.b = @/128;\r\n", material, specStrength));
+   meta->addStatement(new GenOp("   @.a = @/5;\r\n", material, specPower));
+   output = meta;
+}
+
+// Black -> Blue and Alpha of matinfo Buffer (representing no specular), White->G (representing No AO)
+void DeferredEmptySpecHLSL::processPix( Vector<ShaderComponent*> &componentList, const MaterialFeatureData &fd )
+{
+   // search for material var
+   Var *material = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget2));
+   if (!material)
+   {
+       // create color var
+      material = new Var;
+      material->setType("fragout");
+      material->setName(getOutputTargetVarName(ShaderFeature::RenderTarget2));
+      material->setStructName("OUT");
+   }
+
+   MultiLine * meta = new MultiLine;
+   //matinfo.g slot reserved for AO later
+   meta->addStatement(new GenOp("   @.g = 1.0;\r\n", material));
+   meta->addStatement(new GenOp("   @.ba = 0.0;\r\n", material));
+   output = meta;
+}

+ 84 - 0
Engine/source/lighting/advanced/hlsl/deferredShadingFeaturesHLSL.h

@@ -0,0 +1,84 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _DEFERREDSHADINGHLSL_H_
+#define _DEFERREDSHADINGHLSL_H_
+
+#include "shaderGen/HLSL/shaderFeatureHLSL.h"
+#include "shaderGen/HLSL/bumpHLSL.h"
+#include "shaderGen/HLSL/pixSpecularHLSL.h"
+
+// Specular Outputs
+class DeferredSpecMapHLSL : public ShaderFeatureHLSL
+{
+public:
+   virtual String getName() { return "Deferred Shading: Specular Map"; }
+
+   virtual void processPix( Vector<ShaderComponent*> &componentList, 
+      const MaterialFeatureData &fd );
+   
+   virtual Resources getResources( const MaterialFeatureData &fd );
+
+   // Sets textures and texture flags for current pass
+   virtual void setTexData( Material::StageData &stageDat,
+                            const MaterialFeatureData &fd,
+                            RenderPassData &passData,
+                            U32 &texIndex );
+   
+   virtual void processVert( Vector<ShaderComponent*> &componentList,
+                             const MaterialFeatureData &fd );
+};
+
+class DeferredMatInfoFlagsHLSL : public ShaderFeatureHLSL
+{
+public:
+   virtual String getName() { return "Deferred Shading: Mat Info Flags"; }
+
+   virtual void processPix( Vector<ShaderComponent*> &componentList, 
+      const MaterialFeatureData &fd );
+   
+   virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const { return ShaderFeature::RenderTarget2; }
+};
+
+class DeferredSpecVarsHLSL : public ShaderFeatureHLSL
+{
+public:
+   virtual String getName() { return "Deferred Shading: Specular Explicit Numbers"; }
+
+   virtual void processPix( Vector<ShaderComponent*> &componentList, 
+      const MaterialFeatureData &fd );
+   
+   virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const { return ShaderFeature::RenderTarget2; }
+};
+
+class DeferredEmptySpecHLSL : public ShaderFeatureHLSL
+{
+public:
+   virtual String getName() { return "Deferred Shading: Empty Specular"; }
+
+   virtual void processPix( Vector<ShaderComponent*> &componentList, 
+      const MaterialFeatureData &fd );
+   
+   virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const { return ShaderFeature::RenderTarget2; }
+};
+
+#endif

+ 15 - 5
Engine/source/materials/materialFeatureTypes.cpp

@@ -56,10 +56,9 @@ ImplementFeatureType( MFT_LightMap, MFG_Lighting, 4.0f, true );
 ImplementFeatureType( MFT_ToneMap, MFG_Lighting, 5.0f, true );
 ImplementFeatureType( MFT_ToneMap, MFG_Lighting, 5.0f, true );
 ImplementFeatureType( MFT_VertLitTone, MFG_Lighting, 6.0f, false );
 ImplementFeatureType( MFT_VertLitTone, MFG_Lighting, 6.0f, false );
 ImplementFeatureType( MFT_VertLit, MFG_Lighting, 7.0f, true );
 ImplementFeatureType( MFT_VertLit, MFG_Lighting, 7.0f, true );
-ImplementFeatureType( MFT_EnvMap, MFG_Lighting, 8.0f, true );
-ImplementFeatureType( MFT_CubeMap, MFG_Lighting, 9.0f, true );
-ImplementFeatureType( MFT_PixSpecular, MFG_Lighting, 10.0f, true );
-ImplementFeatureType( MFT_MinnaertShading, MFG_Lighting, 12.0f, true );
+ImplementFeatureType( MFT_PixSpecular, MFG_Lighting, 9.0f, true );
+ImplementFeatureType( MFT_MinnaertShading, MFG_Lighting, 10.0f, true );
+ImplementFeatureType( MFT_CubeMap, MFG_Lighting, 11.0f, true );
 
 
 ImplementFeatureType( MFT_GlowMask, MFG_PostLighting, 1.0f, true );
 ImplementFeatureType( MFT_GlowMask, MFG_PostLighting, 1.0f, true );
 ImplementFeatureType( MFT_Visibility, MFG_PostLighting, 2.0f, true );
 ImplementFeatureType( MFT_Visibility, MFG_PostLighting, 2.0f, true );
@@ -85,6 +84,8 @@ ImplementFeatureType( MFT_NormalsOut, MFG_PreLighting, 1.0f, false );
 
 
 ImplementFeatureType( MFT_LightbufferMRT, MFG_PreLighting, 1.0f, false );
 ImplementFeatureType( MFT_LightbufferMRT, MFG_PreLighting, 1.0f, false );
 ImplementFeatureType( MFT_RenderTarget1_Zero, MFG_PreTexture, 1.0f, false );
 ImplementFeatureType( MFT_RenderTarget1_Zero, MFG_PreTexture, 1.0f, false );
+ImplementFeatureType( MFT_RenderTarget2_Zero, MFG_PreTexture, 1.0f, false );
+ImplementFeatureType( MFT_RenderTarget3_Zero, MFG_PreTexture, 1.0f, false );
 
 
 ImplementFeatureType( MFT_Foliage, MFG_PreTransform, 1.0f, false );
 ImplementFeatureType( MFT_Foliage, MFG_PreTransform, 1.0f, false );
 
 
@@ -92,4 +93,13 @@ ImplementFeatureType( MFT_ParticleNormal, MFG_PreTransform, 2.0f, false );
 
 
 ImplementFeatureType( MFT_ForwardShading, U32(-1), -1, true );
 ImplementFeatureType( MFT_ForwardShading, U32(-1), -1, true );
 
 
-ImplementFeatureType( MFT_ImposterVert, MFG_PreTransform, 1.0, false );
+ImplementFeatureType( MFT_ImposterVert, MFG_PreTransform, 1.0, false );
+
+// Deferred Shading
+ImplementFeatureType( MFT_isDeferred, U32(-1), -1, true );
+ImplementFeatureType( MFT_SkyBox, MFG_Transform, 1.0f, true );
+ImplementFeatureType( MFT_DeferredEmptySpec, MFG_Texture, 8.01f, false );
+
+ImplementFeatureType( MFT_DeferredSpecMap, MFG_Texture, 8.2f, false );
+ImplementFeatureType( MFT_DeferredSpecVars, MFG_Texture, 8.5f, false );
+ImplementFeatureType( MFT_DeferredMatInfoFlags, MFG_Texture, 8.7f, false );

+ 10 - 2
Engine/source/materials/materialFeatureTypes.h

@@ -121,7 +121,6 @@ DeclareFeatureType( MFT_ToneMap );
 DeclareFeatureType( MFT_VertLit );
 DeclareFeatureType( MFT_VertLit );
 DeclareFeatureType( MFT_VertLitTone );
 DeclareFeatureType( MFT_VertLitTone );
 
 
-DeclareFeatureType( MFT_EnvMap );
 DeclareFeatureType( MFT_CubeMap );
 DeclareFeatureType( MFT_CubeMap );
 DeclareFeatureType( MFT_PixSpecular );
 DeclareFeatureType( MFT_PixSpecular );
 DeclareFeatureType( MFT_SpecularMap );
 DeclareFeatureType( MFT_SpecularMap );
@@ -158,8 +157,10 @@ DeclareFeatureType( MFT_InterlacedPrePass );
 /// to the second render-target
 /// to the second render-target
 DeclareFeatureType( MFT_LightbufferMRT );
 DeclareFeatureType( MFT_LightbufferMRT );
 
 
-/// This feature outputs black to RenderTarget1
+/// This feature outputs black to RenderTarget3
 DeclareFeatureType( MFT_RenderTarget1_Zero );
 DeclareFeatureType( MFT_RenderTarget1_Zero );
+DeclareFeatureType( MFT_RenderTarget2_Zero );
+DeclareFeatureType( MFT_RenderTarget3_Zero );
 
 
 DeclareFeatureType( MFT_Foliage );
 DeclareFeatureType( MFT_Foliage );
 
 
@@ -179,4 +180,11 @@ DeclareFeatureType( MFT_ForwardShading );
 DeclareFeatureType( MFT_ImposterVert );
 DeclareFeatureType( MFT_ImposterVert );
 
 
 
 
+// Deferred Shading
+DeclareFeatureType( MFT_isDeferred );
+DeclareFeatureType( MFT_SkyBox );
+DeclareFeatureType( MFT_DeferredSpecMap );
+DeclareFeatureType( MFT_DeferredSpecVars );
+DeclareFeatureType( MFT_DeferredMatInfoFlags );
+DeclareFeatureType( MFT_DeferredEmptySpec );
 #endif // _MATERIALFEATURETYPES_H_
 #endif // _MATERIALFEATURETYPES_H_

+ 138 - 46
Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp

@@ -156,10 +156,10 @@ LangElement *ShaderFeatureGLSL::expandNormalMap(   LangElement *sampleNormalOp,
       }
       }
       else
       else
       {
       {
-      // DXT Swizzle trick
-         meta->addStatement( new GenOp( "   @ = float4( @.ag * 2.0 - 1.0, 0.0, 0.0 ); // DXTnm\r\n", normalDecl, sampleNormalOp ) );
-      meta->addStatement( new GenOp( "   @.z = sqrt( 1.0 - dot( @.xy, @.xy ) );  // DXTnm\r\n", normalVar, normalVar, normalVar ) );      
-   }
+          // DXT Swizzle trick
+          meta->addStatement( new GenOp( "   @ = float4( @.ag * 2.0 - 1.0, 0.0, 0.0 ); // DXTnm\r\n", normalDecl, sampleNormalOp ) );
+          meta->addStatement( new GenOp( "   @.z = sqrt( 1.0 - dot( @.xy, @.xy ) );  // DXTnm\r\n", normalVar, normalVar, normalVar ) );    
+      }
    }
    }
    else
    else
    {
    {
@@ -708,7 +708,7 @@ void ShaderFeatureGLSL::getWsPosition( Vector<ShaderComponent*> &componentList,
 	
 	
    Var *objTrans = getObjTrans( componentList, useInstancing, meta );
    Var *objTrans = getObjTrans( componentList, useInstancing, meta );
 	
 	
-   meta->addStatement( new GenOp( "   @ = tMul( @, float4( @.xyz, 1 ) ).xyz;\r\n", 
+   meta->addStatement( new GenOp( "   @ = tMul( @, vec4( @.xyz, 1 ) ).xyz;\r\n", 
 											wsPosition, objTrans, inPosition ) );
 											wsPosition, objTrans, inPosition ) );
 }
 }
 
 
@@ -847,12 +847,22 @@ void DiffuseMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
    output = meta;
    output = meta;
 }
 }
 
 
+U32 DiffuseMapFeatGLSL::getOutputTargets(const MaterialFeatureData &fd) const
+{
+   return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+}
+
 void DiffuseMapFeatGLSL::processPix(   Vector<ShaderComponent*> &componentList, 
 void DiffuseMapFeatGLSL::processPix(   Vector<ShaderComponent*> &componentList, 
                                        const MaterialFeatureData &fd )
                                        const MaterialFeatureData &fd )
 {
 {
    // grab connector texcoord register
    // grab connector texcoord register
    Var *inTex = getInTexCoord( "texCoord", "vec2", true, componentList );
    Var *inTex = getInTexCoord( "texCoord", "vec2", true, componentList );
 
 
+   //determine output target
+   ShaderFeature::OutputTarget targ = ShaderFeature::DefaultTarget;
+   if (fd.features[MFT_isDeferred])
+      targ = ShaderFeature::RenderTarget1;
+
    // create texture var
    // create texture var
    Var *diffuseMap = new Var;
    Var *diffuseMap = new Var;
    diffuseMap->setType( "sampler2D" );
    diffuseMap->setType( "sampler2D" );
@@ -869,7 +879,6 @@ void DiffuseMapFeatGLSL::processPix(   Vector<ShaderComponent*> &componentList,
 
 
    MultiLine * meta = new MultiLine;
    MultiLine * meta = new MultiLine;
    output = meta;
    output = meta;
-
    if (  fd.features[MFT_CubeMap] )
    if (  fd.features[MFT_CubeMap] )
    {
    {
       meta->addStatement(  new GenOp( "   @ = tex2D(@, @);\r\n", 
       meta->addStatement(  new GenOp( "   @ = tex2D(@, @);\r\n", 
@@ -878,9 +887,8 @@ void DiffuseMapFeatGLSL::processPix(   Vector<ShaderComponent*> &componentList,
                            inTex ) );
                            inTex ) );
       if (!fd.features[MFT_Imposter])
       if (!fd.features[MFT_Imposter])
          meta->addStatement( new GenOp("   @ = toLinear(@);\r\n", diffColor, diffColor) );
          meta->addStatement( new GenOp("   @ = toLinear(@);\r\n", diffColor, diffColor) );
-      
-      meta->addStatement( new GenOp( "   @;\r\n", assignColor( diffColor, Material::Mul ) ) );
-      output = meta;
+
+      meta->addStatement( new GenOp( "   @;\r\n", assignColor( diffColor, Material::Mul, NULL, targ) ) );
    }
    }
    else if(fd.features[MFT_DiffuseMapAtlas])
    else if(fd.features[MFT_DiffuseMapAtlas])
    {   
    {   
@@ -946,8 +954,8 @@ void DiffuseMapFeatGLSL::processPix(   Vector<ShaderComponent*> &componentList,
 #ifdef DEBUG_ATLASED_UV_COORDS
 #ifdef DEBUG_ATLASED_UV_COORDS
       if(!fd.features[MFT_PrePassConditioner])
       if(!fd.features[MFT_PrePassConditioner])
       {
       {
-         meta->addStatement(new GenOp("   @ = float4(@.xy, mipLod / @.w, 1.0);\r\n", new DecOp(diffColor), inTex, atParams));
-         meta->addStatement(new GenOp("   @; return OUT;\r\n", assignColor(diffColor, Material::Mul)));
+         meta->addStatement(new GenOp("   @ = vec4(@.xy, mipLod / @.w, 1.0);\r\n", new DecOp(diffColor), inTex, atParams));
+         meta->addStatement(new GenOp("   @; return OUT;\r\n", assignColor(diffColor, Material::Mul, NULL, targ) ) );
          return;
          return;
       }
       }
 #endif
 #endif
@@ -961,20 +969,20 @@ void DiffuseMapFeatGLSL::processPix(   Vector<ShaderComponent*> &componentList,
       }
       }
       else
       else
       {
       {
-         meta->addStatement(new GenOp( "   @ = tex2D(@, @);\r\n", 
-            new DecOp(diffColor), diffuseMap, inTex));
+         meta->addStatement(new GenOp( "   @ = tex2D(@, @);\r\n",
+            new DecOp(diffColor), diffuseMap, inTex)); 
           if (!fd.features[MFT_Imposter])
           if (!fd.features[MFT_Imposter])
              meta->addStatement(new GenOp("   @ = toLinear(@);\r\n", diffColor, diffColor));
              meta->addStatement(new GenOp("   @ = toLinear(@);\r\n", diffColor, diffColor));
       }
       }
 
 
-      meta->addStatement(new GenOp( "   @;\r\n", assignColor(diffColor, Material::Mul)));
+      meta->addStatement(new GenOp( "   @;\r\n", assignColor(diffColor, Material::Mul, NULL, targ) ) );
    }
    }
    else
    else
    {
    {
       meta->addStatement(new GenOp("@ = tex2D(@, @);\r\n", colorDecl, diffuseMap, inTex));
       meta->addStatement(new GenOp("@ = tex2D(@, @);\r\n", colorDecl, diffuseMap, inTex));
       if (!fd.features[MFT_Imposter])
       if (!fd.features[MFT_Imposter])
          meta->addStatement(new GenOp("   @ = toLinear(@);\r\n", diffColor, diffColor));
          meta->addStatement(new GenOp("   @ = toLinear(@);\r\n", diffColor, diffColor));
-      meta->addStatement(new GenOp("   @;\r\n", assignColor(diffColor, Material::Mul)));
+      meta->addStatement(new GenOp("   @;\r\n", assignColor(diffColor, Material::Mul, NULL, targ)));
    }
    }
 }
 }
 
 
@@ -1089,6 +1097,11 @@ void OverlayTexFeatGLSL::setTexData(   Material::StageData &stageDat,
 // Diffuse color
 // Diffuse color
 //****************************************************************************
 //****************************************************************************
 
 
+U32 DiffuseFeatureGLSL::getOutputTargets(const MaterialFeatureData &fd) const
+{
+   return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+}
+
 void DiffuseFeatureGLSL::processPix(   Vector<ShaderComponent*> &componentList, 
 void DiffuseFeatureGLSL::processPix(   Vector<ShaderComponent*> &componentList, 
                                        const MaterialFeatureData &fd )
                                        const MaterialFeatureData &fd )
 {
 {
@@ -1099,7 +1112,33 @@ void DiffuseFeatureGLSL::processPix(   Vector<ShaderComponent*> &componentList,
    diffuseMaterialColor->constSortPos = cspPotentialPrimitive;
    diffuseMaterialColor->constSortPos = cspPotentialPrimitive;
 
 
    MultiLine* meta = new MultiLine;
    MultiLine* meta = new MultiLine;
-   meta->addStatement( new GenOp( "   @;\r\n", assignColor( diffuseMaterialColor, Material::Mul ) ) );
+   Var *col = (Var*)LangElement::find("col");
+   ShaderFeature::OutputTarget targ = ShaderFeature::DefaultTarget;
+   if (fd.features[MFT_isDeferred])
+   {
+      targ = ShaderFeature::RenderTarget1;
+
+      col = (Var*)LangElement::find("col1");
+      MultiLine * meta = new MultiLine;
+      if (!col)
+      {
+         // create color var
+         col = new Var;
+         col->setType("vec4");
+         col->setName(getOutputTargetVarName(targ));
+         col->setStructName("OUT");
+         meta->addStatement(new GenOp("   @ = vec4(1.0);\r\n", col));
+      }
+   }
+
+   Material::BlendOp op;
+
+   if (fd.features[MFT_DiffuseMap])
+      op = Material::Mul;
+   else
+      op = Material::None;
+
+   meta->addStatement(new GenOp("   @;\r\n", assignColor(diffuseMaterialColor, op, NULL, targ)));
    output = meta;
    output = meta;
 }
 }
 
 
@@ -1231,9 +1270,9 @@ void LightmapFeatGLSL::processPix(  Vector<ShaderComponent*> &componentList,
          // Lightmap has already been included in the advanced light bin, so
          // Lightmap has already been included in the advanced light bin, so
          // no need to do any sampling or anything
          // no need to do any sampling or anything
          if(bPreProcessedLighting)
          if(bPreProcessedLighting)
-            statement = new GenOp( "float4(@, 1.0)", inColor );
+            statement = new GenOp( "vec4(@, 1.0)", inColor );
          else
          else
-            statement = new GenOp( "tex2D(@, @) + float4(@.rgb, 0.0)", lightMap, inTex, inColor );
+            statement = new GenOp( "tex2D(@, @) + vec4(@.rgb, 0.0)", lightMap, inTex, inColor );
       }
       }
    }
    }
    
    
@@ -1245,8 +1284,8 @@ void LightmapFeatGLSL::processPix(  Vector<ShaderComponent*> &componentList,
    MultiLine *meta = new MultiLine;
    MultiLine *meta = new MultiLine;
    if( fd.features[MFT_LightbufferMRT] )
    if( fd.features[MFT_LightbufferMRT] )
    {
    {
-      meta->addStatement( new GenOp( "   @;\r\n", assignColor( statement, Material::None, NULL, ShaderFeature::RenderTarget1 ) ) );
-      meta->addStatement( new GenOp( "   @.a = 0.0001;\r\n", LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget1) ) ) );
+      meta->addStatement( new GenOp( "   @;\r\n", assignColor( statement, Material::None, NULL, ShaderFeature::RenderTarget3 ) ) );
+      meta->addStatement( new GenOp( "   @.a = 0.0001;\r\n", LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget3) ) ) );
    }
    }
    else
    else
       meta->addStatement( new GenOp( "   @;\r\n", assignColor( statement, Material::Mul ) ) );
       meta->addStatement( new GenOp( "   @;\r\n", assignColor( statement, Material::Mul ) ) );
@@ -1278,7 +1317,7 @@ void LightmapFeatGLSL::setTexData(  Material::StageData &stageDat,
 
 
 U32 LightmapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 U32 LightmapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 {
 {
-   return fd.features[MFT_LightbufferMRT] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+   return fd.features[MFT_LightbufferMRT] ? ShaderFeature::RenderTarget3 : ShaderFeature::DefaultTarget;
 }
 }
 
 
 //****************************************************************************
 //****************************************************************************
@@ -1372,8 +1411,8 @@ void TonemapFeatGLSL::processPix(  Vector<ShaderComponent*> &componentList,
    // Assign to proper render target
    // Assign to proper render target
    if( fd.features[MFT_LightbufferMRT] )
    if( fd.features[MFT_LightbufferMRT] )
    {
    {
-      meta->addStatement( new GenOp( "   @;\r\n", assignColor( toneMapColor, Material::None, NULL, ShaderFeature::RenderTarget1 ) ) );
-      meta->addStatement( new GenOp( "   @.a = 0.0001;\r\n", LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget1) ) ) );
+      meta->addStatement( new GenOp( "   @;\r\n", assignColor( toneMapColor, Material::None, NULL, ShaderFeature::RenderTarget3 ) ) );
+      meta->addStatement( new GenOp( "   @.a = 0.0001;\r\n", LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget3) ) ) );
    }
    }
    else
    else
       meta->addStatement( new GenOp( "   @;\r\n", assignColor( toneMapColor, blendOp ) ) );
       meta->addStatement( new GenOp( "   @;\r\n", assignColor( toneMapColor, blendOp ) ) );
@@ -1406,7 +1445,7 @@ void TonemapFeatGLSL::setTexData(  Material::StageData &stageDat,
 
 
 U32 TonemapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 U32 TonemapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 {
 {
-   return fd.features[MFT_LightbufferMRT] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+   return fd.features[MFT_LightbufferMRT] ? ShaderFeature::RenderTarget3 : ShaderFeature::DefaultTarget;
 }
 }
 
 
 //****************************************************************************
 //****************************************************************************
@@ -1512,17 +1551,17 @@ void VertLitGLSL::processPix(   Vector<ShaderComponent*> &componentList,
          // the dynamic light buffer, and it already has the baked-vertex-color 
          // the dynamic light buffer, and it already has the baked-vertex-color 
          // included in it
          // included in it
          if(bPreProcessedLighting)
          if(bPreProcessedLighting)
-            outColor = new GenOp( "float4(@.rgb, 1.0)", rtLightingColor );
+            outColor = new GenOp( "vec4(@.rgb, 1.0)", rtLightingColor );
          else
          else
-            outColor = new GenOp( "float4(@.rgb + @.rgb, 1.0)", rtLightingColor, outColor );
+            outColor = new GenOp( "vec4(@.rgb + @.rgb, 1.0)", rtLightingColor, outColor );
       }
       }
    }
    }
    
    
    // Output the color
    // Output the color
    if ( fd.features[MFT_LightbufferMRT] )
    if ( fd.features[MFT_LightbufferMRT] )
    {
    {
-      meta->addStatement( new GenOp( "   @;\r\n", assignColor( outColor, Material::None, NULL, ShaderFeature::RenderTarget1 ) ) );
-      meta->addStatement( new GenOp( "   @.a = 0.0001;\r\n", LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget1) ) ) );
+      meta->addStatement( new GenOp( "   @;\r\n", assignColor( outColor, Material::None, NULL, ShaderFeature::RenderTarget3 ) ) );
+      meta->addStatement( new GenOp( "   @.a = 0.0001;\r\n", LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget3) ) ) );
    }
    }
    else
    else
       meta->addStatement( new GenOp( "   @;\r\n", assignColor( outColor, blendOp ) ) );
       meta->addStatement( new GenOp( "   @;\r\n", assignColor( outColor, blendOp ) ) );
@@ -1532,7 +1571,7 @@ void VertLitGLSL::processPix(   Vector<ShaderComponent*> &componentList,
 
 
 U32 VertLitGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 U32 VertLitGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 {
 {
-   return fd.features[MFT_LightbufferMRT] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+   return fd.features[MFT_LightbufferMRT] ? ShaderFeature::RenderTarget3 : ShaderFeature::DefaultTarget;
 }
 }
 
 
 //****************************************************************************
 //****************************************************************************
@@ -1571,7 +1610,10 @@ void DetailFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
    // and a simple multiplication with the detail map.
    // and a simple multiplication with the detail map.
 
 
    LangElement *statement = new GenOp( "( tex2D(@, @) * 2.0 ) - 1.0", detailMap, inTex );
    LangElement *statement = new GenOp( "( tex2D(@, @) * 2.0 ) - 1.0", detailMap, inTex );
-   output = new GenOp( "   @;\r\n", assignColor( statement, Material::Add ) );
+   if (  fd.features[MFT_isDeferred])
+      output = new GenOp( "   @;\r\n", assignColor( statement, Material::Add, NULL, ShaderFeature::RenderTarget1 ) );
+   else
+      output = new GenOp( "   @;\r\n", assignColor( statement, Material::Add ) );
 }
 }
 
 
 ShaderFeature::Resources DetailFeatGLSL::getResources( const MaterialFeatureData &fd )
 ShaderFeature::Resources DetailFeatGLSL::getResources( const MaterialFeatureData &fd )
@@ -1630,7 +1672,7 @@ void VertPositionGLSL::processVert( Vector<ShaderComponent*> &componentList,
 	
 	
 	Var *modelview = getModelView( componentList, fd.features[MFT_UseInstancing], meta );
 	Var *modelview = getModelView( componentList, fd.features[MFT_UseInstancing], meta );
    
    
-   meta->addStatement( new GenOp( "   @ = tMul(@, float4(@.xyz,1));\r\n", 
+   meta->addStatement( new GenOp( "   @ = tMul(@, vec4(@.xyz,1));\r\n", 
        outPosition, modelview, inPosition ) );   
        outPosition, modelview, inPosition ) );   
    
    
 	output = meta;
 	output = meta;
@@ -1694,8 +1736,8 @@ void ReflectCubeFeatGLSL::processVert( Vector<ShaderComponent*> &componentList,
    cubeNormal->setName( "cubeNormal" );
    cubeNormal->setName( "cubeNormal" );
     cubeNormal->setType( "vec3" );
     cubeNormal->setType( "vec3" );
    LangElement *cubeNormDecl = new DecOp( cubeNormal );
    LangElement *cubeNormDecl = new DecOp( cubeNormal );
-
-    meta->addStatement( new GenOp( "   @ = ( tMul( (@),  vec4(@, 0) ) ).xyz;\r\n",
+   
+   meta->addStatement( new GenOp( "   @ = ( tMul( (@),  vec4(@, 0) ) ).xyz;\r\n",
                        cubeNormDecl, cubeTrans, inNormal ) );
                        cubeNormDecl, cubeTrans, inNormal ) );
 
 
     meta->addStatement( new GenOp( "   @ = bool(length(@)) ? normalize(@) : @;\r\n",
     meta->addStatement( new GenOp( "   @ = bool(length(@)) ? normalize(@) : @;\r\n",
@@ -1771,9 +1813,14 @@ void ReflectCubeFeatGLSL::processPix(  Vector<ShaderComponent*> &componentList,
    }
    }
    else
    else
    {
    {
-      glossColor = (Var*) LangElement::find( "diffuseColor" );
-      if( !glossColor )
-         glossColor = (Var*) LangElement::find( "bumpNormal" );
+      if (fd.features[MFT_isDeferred])
+         glossColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget1));
+      if (!glossColor)
+         glossColor = (Var*)LangElement::find("specularColor");  
+      if (!glossColor)
+         glossColor = (Var*)LangElement::find("diffuseColor");
+      if (!glossColor)
+         glossColor = (Var*)LangElement::find("bumpNormal");
    }
    }
 
 
    // grab connector texcoord register
    // grab connector texcoord register
@@ -1786,7 +1833,7 @@ void ReflectCubeFeatGLSL::processPix(  Vector<ShaderComponent*> &componentList,
 
 
    // create cubemap var
    // create cubemap var
    Var *cubeMap = new Var;
    Var *cubeMap = new Var;
-   cubeMap->setType( "samplerCUBE" );
+   cubeMap->setType( "samplerCube" );
    cubeMap->setName( "cubeMap" );
    cubeMap->setName( "cubeMap" );
    cubeMap->uniform = true;
    cubeMap->uniform = true;
    cubeMap->sampler = true;
    cubeMap->sampler = true;
@@ -1800,14 +1847,36 @@ void ReflectCubeFeatGLSL::processPix(  Vector<ShaderComponent*> &componentList,
       if ( fd.materialFeatures[MFT_RTLighting] )
       if ( fd.materialFeatures[MFT_RTLighting] )
       attn =(Var*)LangElement::find("d_NL_Att");
       attn =(Var*)LangElement::find("d_NL_Att");
 
 
-   LangElement *texCube = new GenOp( "texCUBE( @, @ )", cubeMap, reflectVec );
+   LangElement *texCube = NULL;
+   Var* matinfo = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
+   //first try and grab the gbuffer
+   if (fd.features[MFT_isDeferred] && matinfo)
+   {
+
+      if (fd.features[MFT_DeferredSpecMap])
+         texCube = new GenOp("textureLod(  @, @, (@.a*5) )", cubeMap, reflectVec, matinfo);
+      else
+         texCube = new GenOp("textureLod(  @, @, (@.a/4) )", cubeMap, reflectVec, matinfo);
+   }
+   else if(glossColor) //failing that, rtry and find color data
+      texCube = new GenOp("textureLod( @, @, @.a*5)", cubeMap, reflectVec, glossColor);
+   else
+      texCube = new GenOp("texture( @, @)", cubeMap, reflectVec);
+      
    LangElement *lerpVal = NULL;
    LangElement *lerpVal = NULL;
    Material::BlendOp blendOp = Material::LerpAlpha;
    Material::BlendOp blendOp = Material::LerpAlpha;
 
 
    // Note that the lerpVal needs to be a float4 so that
    // Note that the lerpVal needs to be a float4 so that
    // it will work with the LerpAlpha blend.
    // it will work with the LerpAlpha blend.
-
-   if ( glossColor )
+   
+   if (matinfo)
+   {
+      if (attn)
+         lerpVal = new GenOp("@ * saturate( @ )", matinfo, attn);
+      else
+         lerpVal = new GenOp("@", matinfo);
+   }
+   else if ( glossColor )
    {
    {
       if ( attn )
       if ( attn )
          lerpVal = new GenOp( "@ * saturate( @ )", glossColor, attn );
          lerpVal = new GenOp( "@ * saturate( @ )", glossColor, attn );
@@ -1821,8 +1890,16 @@ void ReflectCubeFeatGLSL::processPix(  Vector<ShaderComponent*> &componentList,
       else
       else
          blendOp = Material::Mul;
          blendOp = Material::Mul;
    }
    }
-
-   meta->addStatement( new GenOp( "   @;\r\n", assignColor( texCube, blendOp, lerpVal ) ) );         
+   if (fd.features[MFT_isDeferred])
+   {
+      Var* targ = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget1));
+      if (fd.features[MFT_DeferredSpecMap])
+         meta->addStatement(new GenOp("   @.rgb = lerp( @.rgb, (@).rgb, (@.b));\r\n", targ, targ, texCube, lerpVal));
+      else
+         meta->addStatement(new GenOp("   @.rgb = lerp( @.rgb, (@).rgb, (@.b*128/5));\r\n", targ, targ, texCube, lerpVal));
+   }
+   else
+        meta->addStatement( new GenOp( "   @;\r\n", assignColor( texCube, blendOp, lerpVal ) ) );         
    output = meta;
    output = meta;
 }
 }
 
 
@@ -1967,7 +2044,7 @@ void RTLightingFeatGLSL::processVert(  Vector<ShaderComponent*> &componentList,
       Var *objTrans = getObjTrans( componentList, fd.features[MFT_UseInstancing], meta );
       Var *objTrans = getObjTrans( componentList, fd.features[MFT_UseInstancing], meta );
    
    
       // Transform the normal to world space.
       // Transform the normal to world space.
-      meta->addStatement( new GenOp( "   @ = tMul( @, float4( normalize( @ ), 0.0 ) ).xyz;\r\n", outNormal, objTrans, inNormal ) );
+      meta->addStatement( new GenOp( "   @ = tMul( @, vec4( normalize( @ ), 0.0 ) ).xyz;\r\n", outNormal, objTrans, inNormal ) );
    }
    }
 
 
 	addOutWsPosition( componentList, fd.features[MFT_UseInstancing], meta );
 	addOutWsPosition( componentList, fd.features[MFT_UseInstancing], meta );
@@ -2025,7 +2102,7 @@ void RTLightingFeatGLSL::processPix(   Vector<ShaderComponent*> &componentList,
    // feature (this is done for BL terrain lightmaps).
    // feature (this is done for BL terrain lightmaps).
    LangElement *lightMask = LangElement::find( "lightMask" );
    LangElement *lightMask = LangElement::find( "lightMask" );
    if ( !lightMask )
    if ( !lightMask )
-      lightMask = new GenOp( "float4( 1, 1, 1, 1 )" );
+      lightMask = new GenOp( "vec4( 1, 1, 1, 1 )" );
 
 
    // Get all the light constants.
    // Get all the light constants.
    Var *inLightPos  = new Var( "inLightPos", "vec4" );
    Var *inLightPos  = new Var( "inLightPos", "vec4" );
@@ -2080,7 +2157,7 @@ void RTLightingFeatGLSL::processPix(   Vector<ShaderComponent*> &componentList,
       rtShading, specular ) );
       rtShading, specular ) );
 
 
    // Apply the lighting to the diffuse color.
    // Apply the lighting to the diffuse color.
-   LangElement *lighting = new GenOp( "float4( @.rgb + @.rgb, 1 )", rtShading, ambient );
+   LangElement *lighting = new GenOp( "vec4( @.rgb + @.rgb, 1 )", rtShading, ambient );
    meta->addStatement( new GenOp( "   @;\r\n", assignColor( lighting, Material::Mul ) ) );
    meta->addStatement( new GenOp( "   @;\r\n", assignColor( lighting, Material::Mul ) ) );
    output = meta;  
    output = meta;  
 }
 }
@@ -2351,7 +2428,9 @@ void AlphaTestGLSL::processPix(  Vector<ShaderComponent*> &componentList,
    }
    }
 
 
    // If we don't have a color var then we cannot do an alpha test.
    // If we don't have a color var then we cannot do an alpha test.
-   Var *color = (Var*)LangElement::find( "col" );
+   Var *color = (Var*)LangElement::find( "col1" );
+   if ( !color )
+	   color = (Var*)LangElement::find("col");
    if ( !color )
    if ( !color )
    {
    {
       output = NULL;
       output = NULL;
@@ -2718,3 +2797,16 @@ void ImposterVertFeatureGLSL::determineFeature( Material *material,
       outFeatureData->features.addFeature( MFT_ImposterVert );
       outFeatureData->features.addFeature( MFT_ImposterVert );
 }
 }
 
 
+//****************************************************************************
+// Vertex position
+//****************************************************************************
+void DeferredSkyGLSL::processVert( Vector<ShaderComponent*> &componentList, 
+                                    const MaterialFeatureData &fd )
+{
+   Var *outPosition = (Var*)LangElement::find( "gl_Position" );
+   MultiLine *meta = new MultiLine;
+   meta->addStatement( new GenOp( "   @.w = @.z;\r\n", outPosition, outPosition ) );
+
+   output = meta;
+}
+

+ 11 - 0
Engine/source/shaderGen/GLSL/shaderFeatureGLSL.h

@@ -248,6 +248,8 @@ public:
    virtual void processPix( Vector<ShaderComponent*> &componentList, 
    virtual void processPix( Vector<ShaderComponent*> &componentList, 
                             const MaterialFeatureData &fd );
                             const MaterialFeatureData &fd );
 
 
+   virtual U32 getOutputTargets(const MaterialFeatureData &fd) const;
+
    virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
    virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
 
 
    virtual Resources getResources( const MaterialFeatureData &fd );
    virtual Resources getResources( const MaterialFeatureData &fd );
@@ -301,6 +303,8 @@ public:
 
 
    virtual Material::BlendOp getBlendOp(){ return Material::None; }
    virtual Material::BlendOp getBlendOp(){ return Material::None; }
 
 
+   virtual U32 getOutputTargets(const MaterialFeatureData &fd) const;
+
    virtual String getName()
    virtual String getName()
    {
    {
       return "Diffuse Color";
       return "Diffuse Color";
@@ -656,4 +660,11 @@ public:
 };
 };
 
 
 
 
+class DeferredSkyGLSL : public ShaderFeatureGLSL
+{
+public:
+   virtual String getName() { return "Deferred Shading: Sky"; }
+   virtual void processVert( Vector<ShaderComponent*> &componentList,
+                             const MaterialFeatureData &fd );
+};
 #endif // _SHADERGEN_GLSL_SHADERFEATUREGLSL_H_
 #endif // _SHADERGEN_GLSL_SHADERFEATUREGLSL_H_

+ 4 - 1
Engine/source/shaderGen/GLSL/shaderGenGLSL.h

@@ -30,8 +30,11 @@
 
 
 class ShaderGenPrinterGLSL : public ShaderGenPrinter
 class ShaderGenPrinterGLSL : public ShaderGenPrinter
 {
 {
+        bool extraRTs[3];
+ 
 public:
 public:
-
+        ShaderGenPrinterGLSL() { for (int i = 0; i < 3; i++) extraRTs[i] = false; }
+ 
    // ShaderGenPrinter
    // ShaderGenPrinter
    virtual void printShaderHeader(Stream& stream);
    virtual void printShaderHeader(Stream& stream);
    virtual void printMainComment(Stream& stream);
    virtual void printMainComment(Stream& stream);

+ 14 - 7
Engine/source/shaderGen/GLSL/shaderGenGLSLInit.cpp

@@ -34,6 +34,8 @@
 #include "core/module.h"
 #include "core/module.h"
 #include "shaderGen/GLSL/accuFeatureGLSL.h"
 #include "shaderGen/GLSL/accuFeatureGLSL.h"
 
 
+// Deferred Shading
+#include "lighting/advanced/glsl/deferredShadingFeaturesGLSL.h"
 
 
 static ShaderGen::ShaderGenInitDelegate sInitDelegate;
 static ShaderGen::ShaderGenInitDelegate sInitDelegate;
 
 
@@ -66,8 +68,13 @@ void _initShaderGenGLSL( ShaderGen *shaderGen )
    FEATUREMGR->registerFeature( MFT_AccuMap, new AccuTexFeatGLSL );
    FEATUREMGR->registerFeature( MFT_AccuMap, new AccuTexFeatGLSL );
    FEATUREMGR->registerFeature( MFT_GlossMap, new NamedFeatureGLSL( "Gloss Map" ) );
    FEATUREMGR->registerFeature( MFT_GlossMap, new NamedFeatureGLSL( "Gloss Map" ) );
    FEATUREMGR->registerFeature( MFT_IsTranslucent, new NamedFeatureGLSL( "Translucent" ) );
    FEATUREMGR->registerFeature( MFT_IsTranslucent, new NamedFeatureGLSL( "Translucent" ) );
+   FEATUREMGR->registerFeature( MFT_IsTranslucentZWrite, new NamedFeatureGLSL( "Translucent ZWrite" ) );
    FEATUREMGR->registerFeature( MFT_Visibility, new VisibilityFeatGLSL );
    FEATUREMGR->registerFeature( MFT_Visibility, new VisibilityFeatGLSL );
    FEATUREMGR->registerFeature( MFT_Fog, new FogFeatGLSL );
    FEATUREMGR->registerFeature( MFT_Fog, new FogFeatGLSL );
+   FEATUREMGR->registerFeature( MFT_LightbufferMRT, new NamedFeatureGLSL( "Lightbuffer MRT" ) );
+   FEATUREMGR->registerFeature( MFT_RenderTarget1_Zero, new RenderTargetZeroGLSL( ShaderFeature::RenderTarget1 ) );
+   FEATUREMGR->registerFeature( MFT_RenderTarget2_Zero, new RenderTargetZeroGLSL( ShaderFeature::RenderTarget2 ) );
+   FEATUREMGR->registerFeature( MFT_RenderTarget3_Zero, new RenderTargetZeroGLSL( ShaderFeature::RenderTarget3 ) );
    FEATUREMGR->registerFeature( MFT_Imposter, new NamedFeatureGLSL( "Imposter" ) );
    FEATUREMGR->registerFeature( MFT_Imposter, new NamedFeatureGLSL( "Imposter" ) );
 
 
 	FEATUREMGR->registerFeature( MFT_NormalsOut, new NormalsOutFeatGLSL );
 	FEATUREMGR->registerFeature( MFT_NormalsOut, new NormalsOutFeatGLSL );
@@ -80,9 +87,6 @@ void _initShaderGenGLSL( ShaderGen *shaderGen )
    FEATUREMGR->registerFeature( MFT_ParaboloidVertTransform, new ParaboloidVertTransformGLSL );
    FEATUREMGR->registerFeature( MFT_ParaboloidVertTransform, new ParaboloidVertTransformGLSL );
    FEATUREMGR->registerFeature( MFT_IsSinglePassParaboloid, new NamedFeatureGLSL( "Single Pass Paraboloid" ) );
    FEATUREMGR->registerFeature( MFT_IsSinglePassParaboloid, new NamedFeatureGLSL( "Single Pass Paraboloid" ) );
    FEATUREMGR->registerFeature( MFT_UseInstancing, new NamedFeatureGLSL( "Hardware Instancing" ) );
    FEATUREMGR->registerFeature( MFT_UseInstancing, new NamedFeatureGLSL( "Hardware Instancing" ) );
-
-	FEATUREMGR->registerFeature( MFT_RenderTarget1_Zero, new RenderTargetZeroGLSL
-										 ( ShaderFeature::RenderTarget1 ) );
 	
 	
    FEATUREMGR->registerFeature( MFT_DiffuseMapAtlas, new NamedFeatureGLSL( "Diffuse Map Atlas" ) );
    FEATUREMGR->registerFeature( MFT_DiffuseMapAtlas, new NamedFeatureGLSL( "Diffuse Map Atlas" ) );
    FEATUREMGR->registerFeature( MFT_NormalMapAtlas, new NamedFeatureGLSL( "Normal Map Atlas" ) );
    FEATUREMGR->registerFeature( MFT_NormalMapAtlas, new NamedFeatureGLSL( "Normal Map Atlas" ) );
@@ -94,10 +98,13 @@ void _initShaderGenGLSL( ShaderGen *shaderGen )
 
 
    FEATUREMGR->registerFeature( MFT_ImposterVert, new ImposterVertFeatureGLSL );
    FEATUREMGR->registerFeature( MFT_ImposterVert, new ImposterVertFeatureGLSL );
 
 
-   FEATUREMGR->registerFeature( MFT_LightbufferMRT, new NamedFeatureGLSL( "Lightbuffer MRT" ) );
-   //FEATUREMGR->registerFeature( MFT_IsTranslucentZWrite, new NamedFeatureGLSL( "Translucent ZWrite" ) );
-   //FEATUREMGR->registerFeature( MFT_InterlacedPrePass, new NamedFeatureGLSL( "Interlaced Pre Pass" ) );
-
+   // Deferred Shading
+   FEATUREMGR->registerFeature( MFT_isDeferred, new NamedFeatureGLSL( "Deferred Material" ) );
+   FEATUREMGR->registerFeature( MFT_DeferredSpecMap, new DeferredSpecMapGLSL );
+   FEATUREMGR->registerFeature( MFT_DeferredSpecVars, new DeferredSpecVarsGLSL );
+   FEATUREMGR->registerFeature( MFT_DeferredMatInfoFlags, new DeferredMatInfoFlagsGLSL );
+   FEATUREMGR->registerFeature( MFT_DeferredEmptySpec, new DeferredEmptySpecGLSL );
+   FEATUREMGR->registerFeature( MFT_SkyBox, new DeferredSkyGLSL );
 }
 }
 
 
 MODULE_BEGIN( ShaderGenGLSL )
 MODULE_BEGIN( ShaderGenGLSL )

+ 125 - 27
Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp

@@ -845,12 +845,22 @@ void DiffuseMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
    output = meta;
    output = meta;
 }
 }
 
 
+U32 DiffuseMapFeatHLSL::getOutputTargets(const MaterialFeatureData &fd) const
+{
+   return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+}
+
 void DiffuseMapFeatHLSL::processPix(   Vector<ShaderComponent*> &componentList, 
 void DiffuseMapFeatHLSL::processPix(   Vector<ShaderComponent*> &componentList, 
                                        const MaterialFeatureData &fd )
                                        const MaterialFeatureData &fd )
 {
 {
    // grab connector texcoord register
    // grab connector texcoord register
    Var *inTex = getInTexCoord( "texCoord", "float2", true, componentList );
    Var *inTex = getInTexCoord( "texCoord", "float2", true, componentList );
 
 
+   //determine output target
+   ShaderFeature::OutputTarget targ = ShaderFeature::DefaultTarget;
+   if (fd.features[MFT_isDeferred])
+      targ = ShaderFeature::RenderTarget1;
+
    // create texture var
    // create texture var
    Var *diffuseMap = new Var;
    Var *diffuseMap = new Var;
    diffuseMap->setType( "sampler2D" );
    diffuseMap->setType( "sampler2D" );
@@ -877,7 +887,7 @@ void DiffuseMapFeatHLSL::processPix(   Vector<ShaderComponent*> &componentList,
       if (!fd.features[MFT_Imposter])
       if (!fd.features[MFT_Imposter])
          meta->addStatement(new GenOp("   @ = toLinear(@);\r\n", diffColor, diffColor));
          meta->addStatement(new GenOp("   @ = toLinear(@);\r\n", diffColor, diffColor));
       
       
-      meta->addStatement( new GenOp( "   @;\r\n", assignColor( diffColor, Material::Mul ) ) );
+      meta->addStatement(new GenOp("   @;\r\n", assignColor(diffColor, Material::Mul, NULL, targ)));
    }
    }
    else if(fd.features[MFT_DiffuseMapAtlas])
    else if(fd.features[MFT_DiffuseMapAtlas])
    {   
    {   
@@ -944,7 +954,7 @@ void DiffuseMapFeatHLSL::processPix(   Vector<ShaderComponent*> &componentList,
       if(!fd.features[MFT_PrePassConditioner])
       if(!fd.features[MFT_PrePassConditioner])
       {
       {
          meta->addStatement(new GenOp("   @ = float4(@.xy, mipLod / @.w, 1.0);\r\n", new DecOp(diffColor), inTex, atParams));
          meta->addStatement(new GenOp("   @ = float4(@.xy, mipLod / @.w, 1.0);\r\n", new DecOp(diffColor), inTex, atParams));
-         meta->addStatement(new GenOp("   @; return OUT;\r\n", assignColor(diffColor, Material::Mul)));
+         meta->addStatement(new GenOp("   @; return OUT;\r\n", assignColor(diffColor, Material::Mul, NULL, targ) ) );
          return;
          return;
       }
       }
 #endif
 #endif
@@ -962,15 +972,15 @@ void DiffuseMapFeatHLSL::processPix(   Vector<ShaderComponent*> &componentList,
       if (!fd.features[MFT_Imposter])
       if (!fd.features[MFT_Imposter])
          meta->addStatement(new GenOp("   @ = toLinear(@);\r\n", diffColor, diffColor));
          meta->addStatement(new GenOp("   @ = toLinear(@);\r\n", diffColor, diffColor));
 
 
-      meta->addStatement(new GenOp( "   @;\r\n", assignColor(diffColor, Material::Mul)));
+      meta->addStatement(new GenOp("   @;\r\n", assignColor(diffColor, Material::Mul, NULL, targ) ) );
    }
    }
    else
    else
    {
    {
       meta->addStatement(new GenOp("@ = tex2D(@, @);\r\n", colorDecl, diffuseMap, inTex));
       meta->addStatement(new GenOp("@ = tex2D(@, @);\r\n", colorDecl, diffuseMap, inTex));
       if (!fd.features[MFT_Imposter])
       if (!fd.features[MFT_Imposter])
          meta->addStatement(new GenOp("   @ = toLinear(@);\r\n", diffColor, diffColor));
          meta->addStatement(new GenOp("   @ = toLinear(@);\r\n", diffColor, diffColor));
-      meta->addStatement(new GenOp("   @;\r\n", assignColor(diffColor, Material::Mul)));
-   }
+      meta->addStatement(new GenOp("   @;\r\n", assignColor(diffColor, Material::Mul, NULL, targ)));
+   }   
 }
 }
 
 
 ShaderFeature::Resources DiffuseMapFeatHLSL::getResources( const MaterialFeatureData &fd )
 ShaderFeature::Resources DiffuseMapFeatHLSL::getResources( const MaterialFeatureData &fd )
@@ -1087,6 +1097,11 @@ void OverlayTexFeatHLSL::setTexData(   Material::StageData &stageDat,
 // Diffuse color
 // Diffuse color
 //****************************************************************************
 //****************************************************************************
 
 
+U32 DiffuseFeatureHLSL::getOutputTargets(const MaterialFeatureData &fd) const
+{
+   return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+}
+
 void DiffuseFeatureHLSL::processPix(   Vector<ShaderComponent*> &componentList, 
 void DiffuseFeatureHLSL::processPix(   Vector<ShaderComponent*> &componentList, 
                                        const MaterialFeatureData &fd )
                                        const MaterialFeatureData &fd )
 {
 {
@@ -1096,8 +1111,34 @@ void DiffuseFeatureHLSL::processPix(   Vector<ShaderComponent*> &componentList,
    diffuseMaterialColor->uniform = true;
    diffuseMaterialColor->uniform = true;
    diffuseMaterialColor->constSortPos = cspPotentialPrimitive;
    diffuseMaterialColor->constSortPos = cspPotentialPrimitive;
 
 
-   MultiLine * meta = new MultiLine;
-   meta->addStatement( new GenOp( "   @;\r\n", assignColor( diffuseMaterialColor, Material::Mul ) ) );
+   MultiLine* meta = new MultiLine;
+   Var *col = (Var*)LangElement::find("col");
+   ShaderFeature::OutputTarget targ = ShaderFeature::DefaultTarget;
+   if (fd.features[MFT_isDeferred])
+   {
+      targ = ShaderFeature::RenderTarget1;
+
+      col = (Var*)LangElement::find("col1");
+      MultiLine * meta = new MultiLine;
+      if (!col)
+      {
+         // create color var
+         col = new Var;
+         col->setType("fragout");
+         col->setName(getOutputTargetVarName(targ));
+         col->setStructName("OUT");
+         meta->addStatement(new GenOp("   @ = float4(1.0);\r\n", col));
+      }
+   }
+
+   Material::BlendOp op;
+   
+   if (fd.features[MFT_DiffuseMap])
+      op = Material::Mul;
+   else
+      op = Material::None;
+
+   meta->addStatement( new GenOp( "   @;\r\n", assignColor( diffuseMaterialColor, op, NULL, targ ) ) );
    output = meta;
    output = meta;
 }
 }
 
 
@@ -1243,8 +1284,8 @@ void LightmapFeatHLSL::processPix(  Vector<ShaderComponent*> &componentList,
    MultiLine *meta = new MultiLine;
    MultiLine *meta = new MultiLine;
    if( fd.features[MFT_LightbufferMRT] )
    if( fd.features[MFT_LightbufferMRT] )
    {
    {
-      meta->addStatement( new GenOp( "   @;\r\n", assignColor( statement, Material::None, NULL, ShaderFeature::RenderTarget1 ) ) );
-      meta->addStatement( new GenOp( "   @.a = 0.0001;\r\n", LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget1) ) ) );
+      meta->addStatement( new GenOp( "   @;\r\n", assignColor( statement, Material::None, NULL, ShaderFeature::RenderTarget3 ) ) );
+      meta->addStatement( new GenOp( "   @.a = 0.0001;\r\n", LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget3) ) ) );
    }
    }
    else
    else
       meta->addStatement( new GenOp( "   @;\r\n", assignColor( statement, Material::Mul ) ) );
       meta->addStatement( new GenOp( "   @;\r\n", assignColor( statement, Material::Mul ) ) );
@@ -1276,7 +1317,7 @@ void LightmapFeatHLSL::setTexData(  Material::StageData &stageDat,
 
 
 U32 LightmapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 U32 LightmapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 {
 {
-   return fd.features[MFT_LightbufferMRT] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+   return fd.features[MFT_LightbufferMRT] ? ShaderFeature::RenderTarget3 : ShaderFeature::DefaultTarget;
 }
 }
 
 
 //****************************************************************************
 //****************************************************************************
@@ -1370,8 +1411,8 @@ void TonemapFeatHLSL::processPix(  Vector<ShaderComponent*> &componentList,
    // Assign to proper render target
    // Assign to proper render target
    if( fd.features[MFT_LightbufferMRT] )
    if( fd.features[MFT_LightbufferMRT] )
    {
    {
-      meta->addStatement( new GenOp( "   @;\r\n", assignColor( toneMapColor, Material::None, NULL, ShaderFeature::RenderTarget1 ) ) );
-      meta->addStatement( new GenOp( "   @.a = 0.0001;\r\n", LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget1) ) ) );
+      meta->addStatement( new GenOp( "   @;\r\n", assignColor( toneMapColor, Material::None, NULL, ShaderFeature::RenderTarget3 ) ) );
+      meta->addStatement( new GenOp( "   @.a = 0.0001;\r\n", LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget3) ) ) );
    }
    }
    else
    else
       meta->addStatement( new GenOp( "   @;\r\n", assignColor( toneMapColor, blendOp ) ) );
       meta->addStatement( new GenOp( "   @;\r\n", assignColor( toneMapColor, blendOp ) ) );
@@ -1404,7 +1445,7 @@ void TonemapFeatHLSL::setTexData(  Material::StageData &stageDat,
 
 
 U32 TonemapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 U32 TonemapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 {
 {
-   return fd.features[MFT_LightbufferMRT] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+   return fd.features[MFT_LightbufferMRT] ? ShaderFeature::RenderTarget3 : ShaderFeature::DefaultTarget;
 }
 }
 
 
 //****************************************************************************
 //****************************************************************************
@@ -1519,8 +1560,8 @@ void VertLitHLSL::processPix(   Vector<ShaderComponent*> &componentList,
    // Output the color
    // Output the color
    if ( fd.features[MFT_LightbufferMRT] )
    if ( fd.features[MFT_LightbufferMRT] )
    {
    {
-      meta->addStatement( new GenOp( "   @;\r\n", assignColor( outColor, Material::None, NULL, ShaderFeature::RenderTarget1 ) ) );
-      meta->addStatement( new GenOp( "   @.a = 0.0001;\r\n", LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget1) ) ) );
+      meta->addStatement( new GenOp( "   @;\r\n", assignColor( outColor, Material::None, NULL, ShaderFeature::RenderTarget3 ) ) );
+      meta->addStatement( new GenOp( "   @.a = 0.0001;\r\n", LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget3) ) ) );
    }
    }
    else
    else
       meta->addStatement( new GenOp( "   @;\r\n", assignColor( outColor, blendOp ) ) );
       meta->addStatement( new GenOp( "   @;\r\n", assignColor( outColor, blendOp ) ) );
@@ -1530,7 +1571,7 @@ void VertLitHLSL::processPix(   Vector<ShaderComponent*> &componentList,
 
 
 U32 VertLitHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 U32 VertLitHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 {
 {
-   return fd.features[MFT_LightbufferMRT] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+   return fd.features[MFT_LightbufferMRT] ? ShaderFeature::RenderTarget3 : ShaderFeature::DefaultTarget;
 }
 }
 
 
 //****************************************************************************
 //****************************************************************************
@@ -1569,7 +1610,10 @@ void DetailFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
    // and a simple multiplication with the detail map.
    // and a simple multiplication with the detail map.
 
 
    LangElement *statement = new GenOp( "( tex2D(@, @) * 2.0 ) - 1.0", detailMap, inTex );
    LangElement *statement = new GenOp( "( tex2D(@, @) * 2.0 ) - 1.0", detailMap, inTex );
-   output = new GenOp( "   @;\r\n", assignColor( statement, Material::Add ) );
+   if (  fd.features[MFT_isDeferred])
+      output = new GenOp( "   @;\r\n", assignColor( statement, Material::Add, NULL, ShaderFeature::RenderTarget1 ) );
+   else
+      output = new GenOp( "   @;\r\n", assignColor( statement, Material::Add ) );
 }
 }
 
 
 ShaderFeature::Resources DetailFeatHLSL::getResources( const MaterialFeatureData &fd )
 ShaderFeature::Resources DetailFeatHLSL::getResources( const MaterialFeatureData &fd )
@@ -1694,7 +1738,7 @@ void ReflectCubeFeatHLSL::processVert( Vector<ShaderComponent*> &componentList,
     cubeNormal->setType( "float3" );
     cubeNormal->setType( "float3" );
     LangElement *cubeNormDecl = new DecOp( cubeNormal );
     LangElement *cubeNormDecl = new DecOp( cubeNormal );
 
 
-    meta->addStatement( new GenOp( "   @ = normalize( mul(@, float4(normalize(@),0.0)).xyz );\r\n",
+    meta->addStatement( new GenOp( "   @ = normalize( mul(@, float4(normalize(@),0.0)).xyz );\r\n", 
                         cubeNormDecl, cubeTrans, inNormal ) );
                         cubeNormDecl, cubeTrans, inNormal ) );
 
 
     // grab the eye position
     // grab the eye position
@@ -1767,9 +1811,14 @@ void ReflectCubeFeatHLSL::processPix(  Vector<ShaderComponent*> &componentList,
    }
    }
    else
    else
    {
    {
-      glossColor = (Var*) LangElement::find( "diffuseColor" );
-      if( !glossColor )
-         glossColor = (Var*) LangElement::find( "bumpNormal" );
+      if (fd.features[MFT_isDeferred])
+         glossColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget1));
+      if (!glossColor)
+         glossColor = (Var*)LangElement::find("specularColor");
+      if (!glossColor)
+         glossColor = (Var*)LangElement::find("diffuseColor");
+      if (!glossColor)
+         glossColor = (Var*)LangElement::find("bumpNormal");
    }
    }
 
 
    // grab connector texcoord register
    // grab connector texcoord register
@@ -1795,15 +1844,41 @@ void ReflectCubeFeatHLSL::processPix(  Vector<ShaderComponent*> &componentList,
    //else 
    //else 
       if ( fd.materialFeatures[MFT_RTLighting] )
       if ( fd.materialFeatures[MFT_RTLighting] )
       attn =(Var*)LangElement::find("d_NL_Att");
       attn =(Var*)LangElement::find("d_NL_Att");
+      
+   LangElement *texCube = NULL;
+   Var* matinfo = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
+   //first try and grab the gbuffer
+   if (fd.features[MFT_isDeferred] && matinfo)
+   {
+       // Cube LOD level = (1.0 - Roughness) * 8
+       // mip_levle =  min((1.0 - u_glossiness)*11.0 + 1.0, 8.0)
+       //LangElement *texCube = new GenOp( "texCUBElod( @, float4(@, min((1.0 - (@ / 128.0)) * 11.0 + 1.0, 8.0)) )", cubeMap, reflectVec, specPower );
+
+      if (fd.features[MFT_DeferredSpecMap])
+         texCube = new GenOp("texCUBElod( @, float4(@, (@.a*5)) )", cubeMap, reflectVec, matinfo);
+      else
+         texCube = new GenOp("texCUBElod( @, float4(@, (@.a/4)) )", cubeMap, reflectVec, matinfo);
+   }
+   else
+      if (glossColor) //failing that, rtry and find color data
+         texCube = new GenOp("texCUBElod( @, float4(@, @.a*5))", cubeMap, reflectVec, glossColor);
+      else //failing *that*, just draw the cubemap
+         texCube = new GenOp("texCUBE( @, @)", cubeMap, reflectVec);
 
 
-   LangElement *texCube = new GenOp( "texCUBE( @, @ )", cubeMap, reflectVec );
    LangElement *lerpVal = NULL;
    LangElement *lerpVal = NULL;
    Material::BlendOp blendOp = Material::LerpAlpha;
    Material::BlendOp blendOp = Material::LerpAlpha;
 
 
    // Note that the lerpVal needs to be a float4 so that
    // Note that the lerpVal needs to be a float4 so that
    // it will work with the LerpAlpha blend.
    // it will work with the LerpAlpha blend.
 
 
-   if ( glossColor )
+   if (matinfo)
+   {
+      if (attn)
+         lerpVal = new GenOp("@ * saturate( @ )", matinfo, attn);
+      else
+         lerpVal = new GenOp("@", matinfo);
+   }
+   else if ( glossColor )
    {
    {
       if ( attn )
       if ( attn )
          lerpVal = new GenOp( "@ * saturate( @ )", glossColor, attn );
          lerpVal = new GenOp( "@ * saturate( @ )", glossColor, attn );
@@ -1817,8 +1892,16 @@ void ReflectCubeFeatHLSL::processPix(  Vector<ShaderComponent*> &componentList,
       else
       else
          blendOp = Material::Mul;
          blendOp = Material::Mul;
    }
    }
-
-   meta->addStatement( new GenOp( "   @;\r\n", assignColor( texCube, blendOp, lerpVal ) ) );         
+   if (fd.features[MFT_isDeferred])
+   {
+      Var* targ = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget1));
+      if (fd.features[MFT_DeferredSpecMap])
+         meta->addStatement(new GenOp("   @.rgb = lerp( @.rgb, (@).rgb, (@.b));\r\n", targ, targ, texCube, lerpVal));
+      else
+         meta->addStatement(new GenOp("   @.rgb = lerp( @.rgb, (@).rgb, (@.b*128/5));\r\n", targ, targ, texCube, lerpVal));
+   }
+   else
+       meta->addStatement( new GenOp( "   @;\r\n", assignColor( texCube, blendOp, lerpVal ) ) );         
    output = meta;
    output = meta;
 }
 }
 
 
@@ -1865,9 +1948,9 @@ void ReflectCubeFeatHLSL::setTexData(  Material::StageData &stageDat,
          {
          {
             passData.mSamplerNames[ texIndex ] = "bumpMap";
             passData.mSamplerNames[ texIndex ] = "bumpMap";
             passData.mTexSlot[ texIndex++ ].texObject = tex;
             passData.mTexSlot[ texIndex++ ].texObject = tex;
+         }
       }
       }
    }
    }
-   }
    
    
    if( stageDat.getCubemap() )
    if( stageDat.getCubemap() )
    {
    {
@@ -2347,7 +2430,9 @@ void AlphaTestHLSL::processPix(  Vector<ShaderComponent*> &componentList,
    }
    }
 
 
    // If we don't have a color var then we cannot do an alpha test.
    // If we don't have a color var then we cannot do an alpha test.
-   Var *color = (Var*)LangElement::find( "col" );
+   Var *color = (Var*)LangElement::find( "col1" );
+   if (!color)
+	   color = (Var*)LangElement::find("col");
    if ( !color )
    if ( !color )
    {
    {
       output = NULL;
       output = NULL;
@@ -2714,3 +2799,16 @@ void ImposterVertFeatureHLSL::determineFeature( Material *material,
       outFeatureData->features.addFeature( MFT_ImposterVert );
       outFeatureData->features.addFeature( MFT_ImposterVert );
 }
 }
 
 
+
+//****************************************************************************
+// Vertex position
+//****************************************************************************
+void DeferredSkyHLSL::processVert( Vector<ShaderComponent*> &componentList, 
+                                    const MaterialFeatureData &fd )
+{
+   Var *outPosition = (Var*)LangElement::find( "hpos" );
+   MultiLine *meta = new MultiLine;
+   meta->addStatement( new GenOp( "   @.w = @.z;\r\n", outPosition, outPosition ) );
+
+   output = meta;
+}

+ 11 - 0
Engine/source/shaderGen/HLSL/shaderFeatureHLSL.h

@@ -248,6 +248,8 @@ public:
    virtual void processPix( Vector<ShaderComponent*> &componentList, 
    virtual void processPix( Vector<ShaderComponent*> &componentList, 
                             const MaterialFeatureData &fd );
                             const MaterialFeatureData &fd );
 
 
+   virtual U32 getOutputTargets(const MaterialFeatureData &fd) const;
+
    virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
    virtual Material::BlendOp getBlendOp(){ return Material::LerpAlpha; }
 
 
    virtual Resources getResources( const MaterialFeatureData &fd );
    virtual Resources getResources( const MaterialFeatureData &fd );
@@ -301,6 +303,7 @@ public:
 
 
    virtual Material::BlendOp getBlendOp(){ return Material::None; }
    virtual Material::BlendOp getBlendOp(){ return Material::None; }
 
 
+   virtual U32 getOutputTargets(const MaterialFeatureData &fd) const;
    virtual String getName()
    virtual String getName()
    {
    {
       return "Diffuse Color";
       return "Diffuse Color";
@@ -656,4 +659,12 @@ public:
 };
 };
 
 
 
 
+class DeferredSkyHLSL : public ShaderFeatureHLSL
+{
+public:
+   virtual String getName() { return "Deferred Shading: Sky"; }
+   virtual void processVert( Vector<ShaderComponent*> &componentList,
+                             const MaterialFeatureData &fd );
+};
+
 #endif // _SHADERGEN_HLSL_SHADERFEATUREHLSL_H_
 #endif // _SHADERGEN_HLSL_SHADERFEATUREHLSL_H_

+ 12 - 0
Engine/source/shaderGen/HLSL/shaderGenHLSLInit.cpp

@@ -32,6 +32,8 @@
 #include "shaderGen/HLSL/paraboloidHLSL.h"
 #include "shaderGen/HLSL/paraboloidHLSL.h"
 #include "materials/materialFeatureTypes.h"
 #include "materials/materialFeatureTypes.h"
 #include "core/module.h"
 #include "core/module.h"
+// Deferred Shading
+#include "lighting/advanced/hlsl/deferredShadingFeaturesHLSL.h"
 #include "shaderGen/HLSL/accuFeatureHLSL.h"
 #include "shaderGen/HLSL/accuFeatureHLSL.h"
 
 
 static ShaderGen::ShaderGenInitDelegate sInitDelegate;
 static ShaderGen::ShaderGenInitDelegate sInitDelegate;
@@ -70,6 +72,8 @@ void _initShaderGenHLSL( ShaderGen *shaderGen )
    FEATUREMGR->registerFeature( MFT_GlossMap, new NamedFeatureHLSL( "Gloss Map" ) );
    FEATUREMGR->registerFeature( MFT_GlossMap, new NamedFeatureHLSL( "Gloss Map" ) );
    FEATUREMGR->registerFeature( MFT_LightbufferMRT, new NamedFeatureHLSL( "Lightbuffer MRT" ) );
    FEATUREMGR->registerFeature( MFT_LightbufferMRT, new NamedFeatureHLSL( "Lightbuffer MRT" ) );
    FEATUREMGR->registerFeature( MFT_RenderTarget1_Zero, new RenderTargetZeroHLSL( ShaderFeature::RenderTarget1 ) );
    FEATUREMGR->registerFeature( MFT_RenderTarget1_Zero, new RenderTargetZeroHLSL( ShaderFeature::RenderTarget1 ) );
+   FEATUREMGR->registerFeature( MFT_RenderTarget2_Zero, new RenderTargetZeroHLSL( ShaderFeature::RenderTarget2 ) );
+   FEATUREMGR->registerFeature( MFT_RenderTarget3_Zero, new RenderTargetZeroHLSL( ShaderFeature::RenderTarget3 ) );
    FEATUREMGR->registerFeature( MFT_Imposter, new NamedFeatureHLSL( "Imposter" ) );
    FEATUREMGR->registerFeature( MFT_Imposter, new NamedFeatureHLSL( "Imposter" ) );
 
 
    FEATUREMGR->registerFeature( MFT_DiffuseMapAtlas, new NamedFeatureHLSL( "Diffuse Map Atlas" ) );
    FEATUREMGR->registerFeature( MFT_DiffuseMapAtlas, new NamedFeatureHLSL( "Diffuse Map Atlas" ) );
@@ -95,6 +99,14 @@ void _initShaderGenHLSL( ShaderGen *shaderGen )
    FEATUREMGR->registerFeature( MFT_ForwardShading, new NamedFeatureHLSL( "Forward Shaded Material" ) );
    FEATUREMGR->registerFeature( MFT_ForwardShading, new NamedFeatureHLSL( "Forward Shaded Material" ) );
 
 
    FEATUREMGR->registerFeature( MFT_ImposterVert, new ImposterVertFeatureHLSL );
    FEATUREMGR->registerFeature( MFT_ImposterVert, new ImposterVertFeatureHLSL );
+
+   // Deferred Shading
+   FEATUREMGR->registerFeature( MFT_isDeferred, new NamedFeatureHLSL( "Deferred Material" ) );
+   FEATUREMGR->registerFeature( MFT_DeferredSpecMap, new DeferredSpecMapHLSL );
+   FEATUREMGR->registerFeature( MFT_DeferredSpecVars, new DeferredSpecVarsHLSL );
+   FEATUREMGR->registerFeature( MFT_DeferredMatInfoFlags, new DeferredMatInfoFlagsHLSL );
+   FEATUREMGR->registerFeature( MFT_DeferredEmptySpec, new DeferredEmptySpecHLSL );
+   FEATUREMGR->registerFeature( MFT_SkyBox, new DeferredSkyHLSL );
 }
 }
 
 
 MODULE_BEGIN( ShaderGenHLSL )
 MODULE_BEGIN( ShaderGenHLSL )

+ 16 - 2
Engine/source/shaderGen/shaderFeature.cpp

@@ -47,10 +47,24 @@ ShaderFeature::Resources ShaderFeature::getResources( const MaterialFeatureData
 const char* ShaderFeature::getOutputTargetVarName( OutputTarget target ) const
 const char* ShaderFeature::getOutputTargetVarName( OutputTarget target ) const
 {
 {
    const char* targName = "col";
    const char* targName = "col";
-   if ( target != DefaultTarget )
+
+   switch(target)
    {
    {
+      case DefaultTarget:
+         targName = "col";
+         break;
+
+      case RenderTarget1:
       targName = "col1";
       targName = "col1";
-      AssertFatal(target == RenderTarget1, "yeah Pat is lame and didn't want to do bit math stuff, TODO");
+         break;
+
+      case RenderTarget2:
+         targName = "col2";
+         break;
+
+      case RenderTarget3:
+         targName = "col3";
+         break;
    }
    }
 
 
    return targName;
    return targName;

+ 4 - 1
Engine/source/shaderGen/shaderGenVars.cpp

@@ -80,4 +80,7 @@ const String ShaderGenVars::cubeMap("$cubeMap");
 const String ShaderGenVars::dLightMap("$dlightMap");
 const String ShaderGenVars::dLightMap("$dlightMap");
 const String ShaderGenVars::dLightMapSec("$dlightMapSec");
 const String ShaderGenVars::dLightMapSec("$dlightMapSec");
 const String ShaderGenVars::dLightMask("$dlightMask");
 const String ShaderGenVars::dLightMask("$dlightMask");
-const String ShaderGenVars::toneMap("$toneMap");
+const String ShaderGenVars::toneMap("$toneMap");
+
+// Deferred shading
+const String ShaderGenVars::matInfoFlags("$matInfoFlags");

+ 3 - 0
Engine/source/shaderGen/shaderGenVars.h

@@ -94,6 +94,9 @@ struct ShaderGenVars
    const static String dLightMapSec;
    const static String dLightMapSec;
    const static String dLightMask;
    const static String dLightMask;
    const static String toneMap;
    const static String toneMap;
+
+   // Deferred Shading
+   const static String matInfoFlags;
 };
 };
 
 
 #endif
 #endif

+ 174 - 85
Engine/source/terrain/glsl/terrFeatureGLSL.cpp

@@ -26,6 +26,7 @@
 #include "terrain/terrFeatureTypes.h"
 #include "terrain/terrFeatureTypes.h"
 #include "materials/materialFeatureTypes.h"
 #include "materials/materialFeatureTypes.h"
 #include "materials/materialFeatureData.h"
 #include "materials/materialFeatureData.h"
+#include "materials/processedMaterial.h"
 #include "gfx/gfxDevice.h"
 #include "gfx/gfxDevice.h"
 #include "shaderGen/langElement.h"
 #include "shaderGen/langElement.h"
 #include "shaderGen/shaderOp.h"
 #include "shaderGen/shaderOp.h"
@@ -48,6 +49,10 @@ namespace
       FEATUREMGR->registerFeature( MFT_TerrainLightMap, new TerrainLightMapFeatGLSL );
       FEATUREMGR->registerFeature( MFT_TerrainLightMap, new TerrainLightMapFeatGLSL );
       FEATUREMGR->registerFeature( MFT_TerrainSideProject, new NamedFeatureGLSL( "Terrain Side Projection" ) );
       FEATUREMGR->registerFeature( MFT_TerrainSideProject, new NamedFeatureGLSL( "Terrain Side Projection" ) );
       FEATUREMGR->registerFeature( MFT_TerrainAdditive, new TerrainAdditiveFeatGLSL );     
       FEATUREMGR->registerFeature( MFT_TerrainAdditive, new TerrainAdditiveFeatGLSL );     
+      FEATUREMGR->registerFeature( MFT_DeferredTerrainBaseMap, new TerrainBaseMapFeatGLSL );
+      FEATUREMGR->registerFeature( MFT_DeferredTerrainMacroMap, new TerrainMacroMapFeatGLSL );
+      FEATUREMGR->registerFeature( MFT_DeferredTerrainDetailMap, new TerrainDetailMapFeatGLSL ); 
+      FEATUREMGR->registerFeature( MFT_DeferredTerrainBlankInfoMap, new TerrainBlankInfoMapFeatGLSL );
    }
    }
 
 
 };
 };
@@ -250,10 +255,6 @@ void TerrainBaseMapFeatGLSL::processPix(  Vector<ShaderComponent*> &componentLis
    // grab connector texcoord register
    // grab connector texcoord register
    Var *texCoord = getInTexCoord( "texCoord", "vec3", true, componentList );
    Var *texCoord = getInTexCoord( "texCoord", "vec3", true, componentList );
 
 
-   // We do nothing more if this is a prepass.
-   if ( fd.features.hasFeature( MFT_PrePassConditioner ) )
-      return;
-
    // create texture var
    // create texture var
    Var *diffuseMap = new Var;
    Var *diffuseMap = new Var;
    diffuseMap->setType( "sampler2D" );
    diffuseMap->setType( "sampler2D" );
@@ -269,7 +270,14 @@ void TerrainBaseMapFeatGLSL::processPix(  Vector<ShaderComponent*> &componentLis
    baseColor->setName( "baseColor" );
    baseColor->setName( "baseColor" );
    meta->addStatement( new GenOp( "   @ = tex2D( @, @.xy );\r\n", new DecOp( baseColor ), diffuseMap, texCoord ) );
    meta->addStatement( new GenOp( "   @ = tex2D( @, @.xy );\r\n", new DecOp( baseColor ), diffuseMap, texCoord ) );
    meta->addStatement(new GenOp("   @ = toLinear(@);\r\n", baseColor, baseColor));
    meta->addStatement(new GenOp("   @ = toLinear(@);\r\n", baseColor, baseColor));
-   meta->addStatement( new GenOp( "   @;\r\n", assignColor( baseColor, Material::Mul ) ) );
+
+  ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
+
+   if(fd.features.hasFeature(MFT_isDeferred))
+   {
+      target= ShaderFeature::RenderTarget1;
+   }
+   meta->addStatement( new GenOp( "   @;\r\n", assignColor( baseColor, Material::Mul,NULL,target ) ) );
 
 
    output = meta;
    output = meta;
 }
 }
@@ -278,14 +286,16 @@ ShaderFeature::Resources TerrainBaseMapFeatGLSL::getResources( const MaterialFea
 {
 {
    Resources res; 
    Resources res; 
    res.numTexReg = 1;
    res.numTexReg = 1;
-
-   // We only sample from the base map during a diffuse pass.
-   if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
       res.numTex = 1;
       res.numTex = 1;
 
 
    return res;
    return res;
 }
 }
 
 
+U32 TerrainBaseMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
+{
+   return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+}
+
 TerrainDetailMapFeatGLSL::TerrainDetailMapFeatGLSL()
 TerrainDetailMapFeatGLSL::TerrainDetailMapFeatGLSL()
    :  mTorqueDep( "shaders/common/gl/torque.glsl" ),
    :  mTorqueDep( "shaders/common/gl/torque.glsl" ),
       mTerrainDep( "shaders/common/terrain/terrain.glsl" )
       mTerrainDep( "shaders/common/terrain/terrain.glsl" )
@@ -386,6 +396,9 @@ void TerrainDetailMapFeatGLSL::processPix(   Vector<ShaderComponent*> &component
    const U32 detailIndex = getProcessIndex();
    const U32 detailIndex = getProcessIndex();
    Var *inTex = getVertTexCoord( "texCoord" );
    Var *inTex = getVertTexCoord( "texCoord" );
 
 
+   // new terrain
+   bool hasNormal = fd.features.hasFeature(MFT_TerrainNormalMap, detailIndex);
+
    MultiLine *meta = new MultiLine;
    MultiLine *meta = new MultiLine;
 
 
    // We need the negative tangent space view vector
    // We need the negative tangent space view vector
@@ -454,6 +467,100 @@ void TerrainDetailMapFeatGLSL::processPix(   Vector<ShaderComponent*> &component
    meta->addStatement( new GenOp( "   @ = calcBlend( @.x, @.xy, @, @ );\r\n", 
    meta->addStatement( new GenOp( "   @ = calcBlend( @.x, @.xy, @, @ );\r\n", 
                                     new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) );
                                     new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) );
 
 
+   // New terrain
+
+   Var *lerpBlend = (Var*)LangElement::find("lerpBlend");
+   if (!lerpBlend)
+   {
+	   lerpBlend = new Var;
+	   lerpBlend->setType("float");
+	   lerpBlend->setName("lerpBlend");
+	   lerpBlend->uniform = true;
+	   lerpBlend->constSortPos = cspPrimitive;
+   }
+
+
+   Var *blendDepth = (Var*)LangElement::find(String::ToString("blendDepth%d", detailIndex));
+   if (!blendDepth)
+   {
+	   blendDepth = new Var;
+	   blendDepth->setType("float");
+	   blendDepth->setName(String::ToString("blendDepth%d", detailIndex));
+	   blendDepth->uniform = true;
+	   blendDepth->constSortPos = cspPrimitive;
+   }
+
+   Var *baseColor = (Var*)LangElement::find("baseColor");
+   ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
+
+   if(fd.features.hasFeature( MFT_DeferredTerrainDetailMap ))
+      target= ShaderFeature::RenderTarget1;
+
+   Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
+
+   if (!outColor)
+   {
+	   // create color var
+	   outColor = new Var;
+	   outColor->setType("float4");
+	   outColor->setName("col");
+       outColor->setStructName("OUT");
+	   meta->addStatement(new GenOp("   @;\r\n", outColor));
+   }
+
+   Var *detailColor = (Var*)LangElement::find("detailColor");
+   if (!detailColor)
+   {
+	   detailColor = new Var;
+	   detailColor->setType("float4");
+	   detailColor->setName("detailColor");
+	   meta->addStatement(new GenOp("   @;\r\n", new DecOp(detailColor)));
+   }
+
+   // Get the detail texture.
+   Var *detailMap = new Var;
+   detailMap->setType("sampler2D");
+   detailMap->setName(String::ToString("detailMap%d", detailIndex));
+   detailMap->uniform = true;
+   detailMap->sampler = true;
+   detailMap->constNum = Var::getTexUnitNum();     // used as texture unit num here
+
+   // Get the normal map texture.
+   Var *normalMap = _getNormalMapTex();
+
+   // Issue happens somewhere here -----
+
+   // Sample the normal map.
+   //
+   // We take two normal samples and lerp between them for
+   // side projection layers... else a single sample.
+   LangElement *texOp;
+
+   // Note that we're doing the standard greyscale detail 
+   // map technique here which can darken and lighten the 
+   // diffuse texture.
+   //
+   // We take two color samples and lerp between them for
+   // side projection layers... else a single sample.
+   //
+   if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex))
+   {
+	   meta->addStatement(new GenOp("   @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n",
+		   detailColor, detailMap, inDet, detailMap, inDet, inTex));
+
+	   texOp = new GenOp("lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z )",
+		   normalMap, inDet, normalMap, inDet, inTex);
+   }
+   else
+   {
+	   meta->addStatement(new GenOp("   @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
+		   detailColor, detailMap, inDet));
+
+	   texOp = new GenOp("tex2D(@, @.xy)", normalMap, inDet);
+   }
+
+   // New terrain
+
    // Get a var and accumulate the blend amount.
    // Get a var and accumulate the blend amount.
    Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
    Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
    if ( !blendTotal )
    if ( !blendTotal )
@@ -487,46 +594,6 @@ void TerrainDetailMapFeatGLSL::processPix(   Vector<ShaderComponent*> &component
       }
       }
    }
    }
 
 
-   // If this is a prepass then we skip color.
-   if ( fd.features.hasFeature( MFT_PrePassConditioner ) )
-   {
-      // Check to see if we have a gbuffer normal.
-      Var *gbNormal = (Var*)LangElement::find( "gbNormal" );
-
-      // If we have a gbuffer normal and we don't have a
-      // normal map feature then we need to lerp in a 
-      // default normal else the normals below this layer
-      // will show thru.
-      if (  gbNormal && 
-            !fd.features.hasFeature( MFT_TerrainNormalMap, detailIndex ) )
-      {
-         Var *viewToTangent = getInViewToTangent( componentList );
-
-         meta->addStatement( new GenOp( "   @ = lerp( @, tGetMatrix3Row(@, 2), min( @, @.w ) );\r\n", 
-            gbNormal, gbNormal, viewToTangent, detailBlend, inDet ) );
-      }
-
-      output = meta;
-      return;
-   }
-
-   Var *detailColor = (Var*)LangElement::find( "detailColor" ); 
-   if ( !detailColor )
-   {
-      detailColor = new Var;
-      detailColor->setType( "vec4" );
-      detailColor->setName( "detailColor" );
-      meta->addStatement( new GenOp( "   @;\r\n", new DecOp( detailColor ) ) );
-   }
-
-   // Get the detail texture.
-   Var *detailMap = new Var;
-   detailMap->setType( "sampler2D" );
-   detailMap->setName( String::ToString( "detailMap%d", detailIndex ) );
-   detailMap->uniform = true;
-   detailMap->sampler = true;
-   detailMap->constNum = Var::getTexUnitNum();     // used as texture unit num here
-
    // If we're using SM 3.0 then take advantage of 
    // If we're using SM 3.0 then take advantage of 
    // dynamic branching to skip layers per-pixel.
    // dynamic branching to skip layers per-pixel.
    
    
@@ -557,9 +624,6 @@ void TerrainDetailMapFeatGLSL::processPix(   Vector<ShaderComponent*> &component
    meta->addStatement( new GenOp( "      @ *= @.y * @.w;\r\n",
    meta->addStatement( new GenOp( "      @ *= @.y * @.w;\r\n",
                                     detailColor, detailInfo, inDet ) );
                                     detailColor, detailInfo, inDet ) );
 
 
-   Var *baseColor = (Var*)LangElement::find( "baseColor" );
-   Var *outColor = (Var*)LangElement::find( "col" );
-
    meta->addStatement( new GenOp( "      @ = lerp( @, @ + @, @ );\r\n",
    meta->addStatement( new GenOp( "      @ = lerp( @, @ + @, @ );\r\n",
                                     outColor, outColor, baseColor, detailColor, detailBlend ) );
                                     outColor, outColor, baseColor, detailColor, detailBlend ) );
 
 
@@ -585,9 +649,7 @@ ShaderFeature::Resources TerrainDetailMapFeatGLSL::getResources( const MaterialF
          res.numTexReg += 4;
          res.numTexReg += 4;
    }
    }
 
 
-   // If this isn't the prepass then we sample 
-   // from the detail texture for diffuse coloring.
-   if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
+   // sample from the detail texture for diffuse coloring.
       res.numTex += 1;
       res.numTex += 1;
 
 
    // If we have parallax for this layer then we'll also
    // If we have parallax for this layer then we'll also
@@ -602,6 +664,11 @@ ShaderFeature::Resources TerrainDetailMapFeatGLSL::getResources( const MaterialF
    return res;
    return res;
 }
 }
 
 
+U32 TerrainDetailMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
+{
+   return fd.features[MFT_DeferredTerrainDetailMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+}
+
 
 
 TerrainMacroMapFeatGLSL::TerrainMacroMapFeatGLSL()
 TerrainMacroMapFeatGLSL::TerrainMacroMapFeatGLSL()
    :  mTorqueDep( "shaders/common/gl/torque.glsl" ),
    :  mTorqueDep( "shaders/common/gl/torque.glsl" ),
@@ -759,29 +826,6 @@ void TerrainMacroMapFeatGLSL::processPix(   Vector<ShaderComponent*> &componentL
    // Add to the blend total.
    // Add to the blend total.
    meta->addStatement( new GenOp( "   @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend ) );
    meta->addStatement( new GenOp( "   @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend ) );
 
 
-   // If this is a prepass then we skip color.
-   if ( fd.features.hasFeature( MFT_PrePassConditioner ) )
-   {
-      // Check to see if we have a gbuffer normal.
-      Var *gbNormal = (Var*)LangElement::find( "gbNormal" );
-
-      // If we have a gbuffer normal and we don't have a
-      // normal map feature then we need to lerp in a 
-      // default normal else the normals below this layer
-      // will show thru.
-      if (  gbNormal && 
-            !fd.features.hasFeature( MFT_TerrainNormalMap, detailIndex ) )
-      {
-         Var *viewToTangent = getInViewToTangent( componentList );
-
-         meta->addStatement( new GenOp( "   @ = lerp( @, tGetMatrix3Row(@, 2), min( @, @.w ) );\r\n", 
-            gbNormal, gbNormal, viewToTangent, detailBlend, inDet ) );
-      }
-
-      output = meta;
-      return;
-   }
-
    Var *detailColor = (Var*)LangElement::find( "macroColor" ); 
    Var *detailColor = (Var*)LangElement::find( "macroColor" ); 
    if ( !detailColor )
    if ( !detailColor )
    {
    {
@@ -826,8 +870,12 @@ void TerrainMacroMapFeatGLSL::processPix(   Vector<ShaderComponent*> &componentL
 
 
    meta->addStatement( new GenOp( "      @ *= @.y * @.w;\r\n",
    meta->addStatement( new GenOp( "      @ *= @.y * @.w;\r\n",
                                     detailColor, detailInfo, inDet ) );
                                     detailColor, detailInfo, inDet ) );
+   ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
 
 
-   Var *outColor = (Var*)LangElement::find( "col" );
+   if(fd.features.hasFeature(MFT_DeferredTerrainMacroMap))
+      target= ShaderFeature::RenderTarget1;
+
+   Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
 
 
    meta->addStatement( new GenOp( "      @ = lerp( @, @ + @, @ );\r\n",
    meta->addStatement( new GenOp( "      @ = lerp( @, @ + @, @ );\r\n",
                                     outColor, outColor, outColor, detailColor, detailBlend ) );
                                     outColor, outColor, outColor, detailColor, detailBlend ) );
@@ -850,9 +898,6 @@ ShaderFeature::Resources TerrainMacroMapFeatGLSL::getResources( const MaterialFe
          res.numTex += 1;
          res.numTex += 1;
    }
    }
 
 
-   // If this isn't the prepass then we sample 
-   // from the detail texture for diffuse coloring.
-   if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
       res.numTex += 1;
       res.numTex += 1;
 
 
    // Finally we always send the detail texture 
    // Finally we always send the detail texture 
@@ -862,6 +907,11 @@ ShaderFeature::Resources TerrainMacroMapFeatGLSL::getResources( const MaterialFe
    return res;
    return res;
 }
 }
 
 
+U32 TerrainMacroMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
+{
+   return fd.features[MFT_DeferredTerrainMacroMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+}
+
 void TerrainNormalMapFeatGLSL::processVert(  Vector<ShaderComponent*> &componentList, 
 void TerrainNormalMapFeatGLSL::processVert(  Vector<ShaderComponent*> &componentList, 
                                              const MaterialFeatureData &fd )
                                              const MaterialFeatureData &fd )
 {
 {
@@ -881,9 +931,6 @@ void TerrainNormalMapFeatGLSL::processVert(  Vector<ShaderComponent*> &component
 void TerrainNormalMapFeatGLSL::processPix(   Vector<ShaderComponent*> &componentList, 
 void TerrainNormalMapFeatGLSL::processPix(   Vector<ShaderComponent*> &componentList, 
                                              const MaterialFeatureData &fd )
                                              const MaterialFeatureData &fd )
 {
 {
-   // We only need to process normals during the prepass.
-   if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
-      return;
 
 
    MultiLine *meta = new MultiLine;
    MultiLine *meta = new MultiLine;
 
 
@@ -1023,7 +1070,12 @@ ShaderFeature::Resources TerrainLightMapFeatGLSL::getResources( const MaterialFe
 void TerrainAdditiveFeatGLSL::processPix( Vector<ShaderComponent*> &componentList, 
 void TerrainAdditiveFeatGLSL::processPix( Vector<ShaderComponent*> &componentList, 
                                           const MaterialFeatureData &fd )
                                           const MaterialFeatureData &fd )
 {
 {
-   Var *color = (Var*) LangElement::find( "col" );
+   Var *color = NULL;
+   if (fd.features[MFT_DeferredTerrainDetailMap])
+       color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget1) );
+   else
+       color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::DefaultTarget) );
+
    Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
    Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
    if ( !color || !blendTotal )
    if ( !color || !blendTotal )
       return;
       return;
@@ -1035,3 +1087,40 @@ void TerrainAdditiveFeatGLSL::processPix( Vector<ShaderComponent*> &componentLis
 
 
    output = meta;
    output = meta;
 }
 }
+
+//standard matInfo map contains data of the form .r = bitflags, .g = (will contain AO), 
+//.b = specular strength, a= spec power. 
+//here, it's merely a cutout for now, so that lightmapping (target3) doesn't get mangled.
+//we'll most likely revisit that later. possibly several ways...
+
+U32 TerrainBlankInfoMapFeatGLSL::getOutputTargets(const MaterialFeatureData &fd) const
+{
+   return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget2 : ShaderFeature::RenderTarget1;
+}
+
+void TerrainBlankInfoMapFeatGLSL::processPix(Vector<ShaderComponent*> &componentList,
+   const MaterialFeatureData &fd)
+{
+   // search for material var
+   Var *material;
+   OutputTarget targ = RenderTarget1;
+   if (fd.features[MFT_isDeferred])
+   {
+      targ = RenderTarget2;
+   }
+   material = (Var*)LangElement::find(getOutputTargetVarName(targ));
+
+   MultiLine * meta = new MultiLine;
+   if (!material)
+   {
+      // create color var
+      material = new Var;
+      material->setType("vec4");
+      material->setName(getOutputTargetVarName(targ));
+      material->setStructName("OUT");
+   }
+
+   meta->addStatement(new GenOp("   @ = float4(0.0,0.0,0.0,0.0001);\r\n", material));
+
+   output = meta;
+}

+ 17 - 0
Engine/source/terrain/glsl/terrFeatureGLSL.h

@@ -67,6 +67,8 @@ public:
    virtual Resources getResources( const MaterialFeatureData &fd );
    virtual Resources getResources( const MaterialFeatureData &fd );
 
 
    virtual String getName() { return "Terrain Base Texture"; }
    virtual String getName() { return "Terrain Base Texture"; }
+
+   virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
 };
 };
 
 
 
 
@@ -90,6 +92,8 @@ public:
    virtual Resources getResources( const MaterialFeatureData &fd );
    virtual Resources getResources( const MaterialFeatureData &fd );
 
 
    virtual String getName() { return "Terrain Detail Texture"; }
    virtual String getName() { return "Terrain Detail Texture"; }
+
+   virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
 };
 };
 
 
 
 
@@ -113,6 +117,8 @@ public:
    virtual Resources getResources( const MaterialFeatureData &fd );
    virtual Resources getResources( const MaterialFeatureData &fd );
 
 
    virtual String getName() { return "Terrain Macro Texture"; }
    virtual String getName() { return "Terrain Macro Texture"; }
+
+   virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
 };
 };
 
 
 
 
@@ -154,4 +160,15 @@ public:
    virtual String getName() { return "Terrain Additive"; }
    virtual String getName() { return "Terrain Additive"; }
 };
 };
 
 
+class TerrainBlankInfoMapFeatGLSL : public ShaderFeatureGLSL
+{
+public:
+
+   virtual void processPix(Vector<ShaderComponent*> &componentList,
+      const MaterialFeatureData &fd);
+
+   virtual U32 getOutputTargets(const MaterialFeatureData &fd) const;
+   virtual String getName() { return "Blank Matinfo map"; }
+};
+
 #endif // _TERRFEATUREGLSL_H_
 #endif // _TERRFEATUREGLSL_H_

+ 102 - 77
Engine/source/terrain/hlsl/terrFeatureHLSL.cpp

@@ -26,6 +26,7 @@
 #include "terrain/terrFeatureTypes.h"
 #include "terrain/terrFeatureTypes.h"
 #include "materials/materialFeatureTypes.h"
 #include "materials/materialFeatureTypes.h"
 #include "materials/materialFeatureData.h"
 #include "materials/materialFeatureData.h"
+#include "materials/processedMaterial.h"
 #include "gfx/gfxDevice.h"
 #include "gfx/gfxDevice.h"
 #include "shaderGen/langElement.h"
 #include "shaderGen/langElement.h"
 #include "shaderGen/shaderOp.h"
 #include "shaderGen/shaderOp.h"
@@ -47,9 +48,12 @@ namespace
       FEATUREMGR->registerFeature( MFT_TerrainMacroMap, new TerrainMacroMapFeatHLSL );
       FEATUREMGR->registerFeature( MFT_TerrainMacroMap, new TerrainMacroMapFeatHLSL );
       FEATUREMGR->registerFeature( MFT_TerrainLightMap, new TerrainLightMapFeatHLSL );
       FEATUREMGR->registerFeature( MFT_TerrainLightMap, new TerrainLightMapFeatHLSL );
       FEATUREMGR->registerFeature( MFT_TerrainSideProject, new NamedFeatureHLSL( "Terrain Side Projection" ) );
       FEATUREMGR->registerFeature( MFT_TerrainSideProject, new NamedFeatureHLSL( "Terrain Side Projection" ) );
-      FEATUREMGR->registerFeature( MFT_TerrainAdditive, new TerrainAdditiveFeatHLSL );
+      FEATUREMGR->registerFeature( MFT_TerrainAdditive, new TerrainAdditiveFeatHLSL );     
+      FEATUREMGR->registerFeature( MFT_DeferredTerrainBaseMap, new TerrainBaseMapFeatHLSL );
+      FEATUREMGR->registerFeature( MFT_DeferredTerrainMacroMap, new TerrainMacroMapFeatHLSL );
+      FEATUREMGR->registerFeature( MFT_DeferredTerrainDetailMap, new TerrainDetailMapFeatHLSL );
+      FEATUREMGR->registerFeature( MFT_DeferredTerrainBlankInfoMap, new TerrainBlankInfoMapFeatHLSL );
    }
    }
-
 };
 };
 
 
 MODULE_BEGIN( TerrainFeatHLSL )
 MODULE_BEGIN( TerrainFeatHLSL )
@@ -250,10 +254,6 @@ void TerrainBaseMapFeatHLSL::processPix(  Vector<ShaderComponent*> &componentLis
    // grab connector texcoord register
    // grab connector texcoord register
    Var *texCoord = getInTexCoord( "texCoord", "float3", true, componentList );
    Var *texCoord = getInTexCoord( "texCoord", "float3", true, componentList );
 
 
-   // We do nothing more if this is a prepass.
-   if ( fd.features.hasFeature( MFT_PrePassConditioner ) )
-      return;
-
    // create texture var
    // create texture var
    Var *diffuseMap = new Var;
    Var *diffuseMap = new Var;
    diffuseMap->setType( "sampler2D" );
    diffuseMap->setType( "sampler2D" );
@@ -269,8 +269,15 @@ void TerrainBaseMapFeatHLSL::processPix(  Vector<ShaderComponent*> &componentLis
    baseColor->setName( "baseColor" );
    baseColor->setName( "baseColor" );
    meta->addStatement( new GenOp( "   @ = tex2D( @, @.xy );\r\n", new DecOp( baseColor ), diffuseMap, texCoord ) );
    meta->addStatement( new GenOp( "   @ = tex2D( @, @.xy );\r\n", new DecOp( baseColor ), diffuseMap, texCoord ) );
    meta->addStatement(new GenOp("   @ = toLinear(@);\r\n", baseColor, baseColor));
    meta->addStatement(new GenOp("   @ = toLinear(@);\r\n", baseColor, baseColor));
-   meta->addStatement( new GenOp( "   @;\r\n", assignColor( baseColor, Material::Mul ) ) );
 
 
+  ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
+
+  if (fd.features.hasFeature(MFT_isDeferred))
+   {
+      target= ShaderFeature::RenderTarget1;
+   }
+
+   meta->addStatement( new GenOp( "   @;\r\n", assignColor( baseColor, Material::Mul,NULL,target ) ) );
    output = meta;
    output = meta;
 }
 }
 
 
@@ -278,14 +285,16 @@ ShaderFeature::Resources TerrainBaseMapFeatHLSL::getResources( const MaterialFea
 {
 {
    Resources res; 
    Resources res; 
    res.numTexReg = 1;
    res.numTexReg = 1;
-
-   // We only sample from the base map during a diffuse pass.
-   if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
       res.numTex = 1;
       res.numTex = 1;
 
 
    return res;
    return res;
 }
 }
 
 
+U32 TerrainBaseMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
+{
+   return fd.features[MFT_DeferredTerrainBaseMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+}
+
 TerrainDetailMapFeatHLSL::TerrainDetailMapFeatHLSL()
 TerrainDetailMapFeatHLSL::TerrainDetailMapFeatHLSL()
    :  mTorqueDep( "shaders/common/torque.hlsl" ),
    :  mTorqueDep( "shaders/common/torque.hlsl" ),
       mTerrainDep( "shaders/common/terrain/terrain.hlsl" )
       mTerrainDep( "shaders/common/terrain/terrain.hlsl" )
@@ -477,7 +486,7 @@ void TerrainDetailMapFeatHLSL::processPix(   Vector<ShaderComponent*> &component
       // Call the library function to do the rest.
       // Call the library function to do the rest.
       if(fd.features.hasFeature( MFT_IsDXTnm, detailIndex ) )
       if(fd.features.hasFeature( MFT_IsDXTnm, detailIndex ) )
       {
       {
-         meta->addStatement( new GenOp( "   @.xy += parallaxOffsetDxtnm( @, @.xy, @, @.z * @ );\r\n", 
+         meta->addStatement( new GenOp( "   @.xy += parallaxOffsetDxtnm( @, @.xy, @, @.z * @ );\r\n",
             inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend ) );
             inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend ) );
       }
       }
       else
       else
@@ -487,29 +496,6 @@ void TerrainDetailMapFeatHLSL::processPix(   Vector<ShaderComponent*> &component
       }
       }
    }
    }
 
 
-   // If this is a prepass then we skip color.
-   if ( fd.features.hasFeature( MFT_PrePassConditioner ) )
-   {
-      // Check to see if we have a gbuffer normal.
-      Var *gbNormal = (Var*)LangElement::find( "gbNormal" );
-
-      // If we have a gbuffer normal and we don't have a
-      // normal map feature then we need to lerp in a 
-      // default normal else the normals below this layer
-      // will show thru.
-      if (  gbNormal && 
-            !fd.features.hasFeature( MFT_TerrainNormalMap, detailIndex ) )
-      {
-         Var *viewToTangent = getInViewToTangent( componentList );
-
-         meta->addStatement( new GenOp( "   @ = lerp( @, @[2], min( @, @.w ) );\r\n", 
-            gbNormal, gbNormal, viewToTangent, detailBlend, inDet ) );
-      }
-
-      output = meta;
-      return;
-   }
-
    Var *detailColor = (Var*)LangElement::find( "detailColor" ); 
    Var *detailColor = (Var*)LangElement::find( "detailColor" ); 
    if ( !detailColor )
    if ( !detailColor )
    {
    {
@@ -543,21 +529,35 @@ void TerrainDetailMapFeatHLSL::processPix(   Vector<ShaderComponent*> &component
    // We take two color samples and lerp between them for
    // We take two color samples and lerp between them for
    // side projection layers... else a single sample.
    // side projection layers... else a single sample.
    //
    //
+
+   //Sampled detail texture that is not expanded
+   Var *detailTex = new Var;
+   detailTex->setType("float4");
+   detailTex->setName("detailTex");
+   meta->addStatement( new GenOp( "   @;\r\n", new DecOp( detailTex ) ) );   
+
    if ( fd.features.hasFeature( MFT_TerrainSideProject, detailIndex ) )
    if ( fd.features.hasFeature( MFT_TerrainSideProject, detailIndex ) )
    {
    {
-      meta->addStatement( new GenOp( "      @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n", 
-                                                detailColor, detailMap, inDet, detailMap, inDet, inTex ) );
+      meta->addStatement( new GenOp("      @ =  lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z);\r\n",detailTex,detailMap,inDet,detailMap,inDet,inTex));
+      meta->addStatement( new GenOp( "      @ = ( @ * 2.0 ) - 1.0;\r\n", detailColor, detailTex) );
    }
    }
    else
    else
    {
    {
-      meta->addStatement( new GenOp( "      @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n", 
-                                       detailColor, detailMap, inDet ) );
+      meta->addStatement( new GenOp("      @ = tex2D(@,@.xy);\r\n",detailTex,detailMap,inDet));
+      meta->addStatement( new GenOp( "      @ = ( @ * 2.0 ) - 1.0;\r\n", 
+                                       detailColor, detailTex) );
    }
    }
 
 
    meta->addStatement( new GenOp( "      @ *= @.y * @.w;\r\n",
    meta->addStatement( new GenOp( "      @ *= @.y * @.w;\r\n",
                                     detailColor, detailInfo, inDet ) );
                                     detailColor, detailInfo, inDet ) );
 
 
-   Var *outColor = (Var*)LangElement::find( "col" );
+   Var *baseColor = (Var*)LangElement::find( "baseColor" );
+   ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
+
+   if(fd.features.hasFeature( MFT_DeferredTerrainDetailMap ))
+      target= ShaderFeature::RenderTarget1;
+
+   Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
 
 
    meta->addStatement( new GenOp( "      @ += @ * @;\r\n",
    meta->addStatement( new GenOp( "      @ += @ * @;\r\n",
                                     outColor, detailColor, detailBlend));
                                     outColor, detailColor, detailBlend));
@@ -584,9 +584,7 @@ ShaderFeature::Resources TerrainDetailMapFeatHLSL::getResources( const MaterialF
          res.numTexReg += 4;
          res.numTexReg += 4;
    }
    }
 
 
-   // If this isn't the prepass then we sample 
-   // from the detail texture for diffuse coloring.
-   if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
+   // sample from the detail texture for diffuse coloring.
       res.numTex += 1;
       res.numTex += 1;
 
 
    // If we have parallax for this layer then we'll also
    // If we have parallax for this layer then we'll also
@@ -601,6 +599,11 @@ ShaderFeature::Resources TerrainDetailMapFeatHLSL::getResources( const MaterialF
    return res;
    return res;
 }
 }
 
 
+U32 TerrainDetailMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
+{
+   return fd.features[MFT_DeferredTerrainDetailMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+}
+
 
 
 TerrainMacroMapFeatHLSL::TerrainMacroMapFeatHLSL()
 TerrainMacroMapFeatHLSL::TerrainMacroMapFeatHLSL()
    :  mTorqueDep( "shaders/common/torque.hlsl" ),
    :  mTorqueDep( "shaders/common/torque.hlsl" ),
@@ -758,29 +761,6 @@ void TerrainMacroMapFeatHLSL::processPix(   Vector<ShaderComponent*> &componentL
    // Add to the blend total.
    // Add to the blend total.
    meta->addStatement( new GenOp( "   @ += @;\r\n", blendTotal, detailBlend ) );
    meta->addStatement( new GenOp( "   @ += @;\r\n", blendTotal, detailBlend ) );
 
 
-   // If this is a prepass then we skip color.
-   if ( fd.features.hasFeature( MFT_PrePassConditioner ) )
-   {
-      // Check to see if we have a gbuffer normal.
-      Var *gbNormal = (Var*)LangElement::find( "gbNormal" );
-
-      // If we have a gbuffer normal and we don't have a
-      // normal map feature then we need to lerp in a 
-      // default normal else the normals below this layer
-      // will show thru.
-      if (  gbNormal && 
-            !fd.features.hasFeature( MFT_TerrainNormalMap, detailIndex ) )
-      {
-         Var *viewToTangent = getInViewToTangent( componentList );
-
-         meta->addStatement( new GenOp( "   @ = lerp( @, @[2], min( @, @.w ) );\r\n", 
-            gbNormal, gbNormal, viewToTangent, detailBlend, inDet ) );
-      }
-
-      output = meta;
-      return;
-   }
-
    Var *detailColor = (Var*)LangElement::find( "macroColor" ); 
    Var *detailColor = (Var*)LangElement::find( "macroColor" ); 
    if ( !detailColor )
    if ( !detailColor )
    {
    {
@@ -826,8 +806,14 @@ void TerrainMacroMapFeatHLSL::processPix(   Vector<ShaderComponent*> &componentL
    meta->addStatement( new GenOp( "      @ *= @.y * @.w;\r\n",
    meta->addStatement( new GenOp( "      @ *= @.y * @.w;\r\n",
                                     detailColor, detailInfo, inDet ) );
                                     detailColor, detailInfo, inDet ) );
 
 
-   //Var *baseColor = (Var*)LangElement::find( "baseColor" );
-   Var *outColor = (Var*)LangElement::find( "col" );
+   Var *baseColor = (Var*)LangElement::find( "baseColor" );
+
+   ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
+
+   if(fd.features.hasFeature(MFT_DeferredTerrainMacroMap))
+      target= ShaderFeature::RenderTarget1;
+
+   Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
 
 
    meta->addStatement(new GenOp("      @ += @ * @;\r\n",
    meta->addStatement(new GenOp("      @ += @ * @;\r\n",
                                     outColor, detailColor, detailBlend));
                                     outColor, detailColor, detailBlend));
@@ -837,8 +823,6 @@ void TerrainMacroMapFeatHLSL::processPix(   Vector<ShaderComponent*> &componentL
    output = meta;
    output = meta;
 }
 }
 
 
-
-
 ShaderFeature::Resources TerrainMacroMapFeatHLSL::getResources( const MaterialFeatureData &fd )
 ShaderFeature::Resources TerrainMacroMapFeatHLSL::getResources( const MaterialFeatureData &fd )
 {
 {
    Resources res;
    Resources res;
@@ -850,9 +834,6 @@ ShaderFeature::Resources TerrainMacroMapFeatHLSL::getResources( const MaterialFe
       res.numTex += 1;
       res.numTex += 1;
    }
    }
 
 
-   // If this isn't the prepass then we sample 
-   // from the detail texture for diffuse coloring.
-   if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
       res.numTex += 1;
       res.numTex += 1;
 
 
    // Finally we always send the detail texture 
    // Finally we always send the detail texture 
@@ -862,6 +843,11 @@ ShaderFeature::Resources TerrainMacroMapFeatHLSL::getResources( const MaterialFe
    return res;
    return res;
 }
 }
 
 
+U32 TerrainMacroMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
+{
+   return fd.features[MFT_DeferredTerrainMacroMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+}
+
 void TerrainNormalMapFeatHLSL::processVert(  Vector<ShaderComponent*> &componentList, 
 void TerrainNormalMapFeatHLSL::processVert(  Vector<ShaderComponent*> &componentList, 
                                              const MaterialFeatureData &fd )
                                              const MaterialFeatureData &fd )
 {
 {
@@ -881,9 +867,6 @@ void TerrainNormalMapFeatHLSL::processVert(  Vector<ShaderComponent*> &component
 void TerrainNormalMapFeatHLSL::processPix(   Vector<ShaderComponent*> &componentList, 
 void TerrainNormalMapFeatHLSL::processPix(   Vector<ShaderComponent*> &componentList, 
                                              const MaterialFeatureData &fd )
                                              const MaterialFeatureData &fd )
 {
 {
-   // We only need to process normals during the prepass.
-   if ( !fd.features.hasFeature( MFT_PrePassConditioner ) )
-      return;
 
 
    MultiLine *meta = new MultiLine;
    MultiLine *meta = new MultiLine;
 
 
@@ -1019,11 +1002,15 @@ ShaderFeature::Resources TerrainLightMapFeatHLSL::getResources( const MaterialFe
    return res;
    return res;
 }
 }
 
 
-
 void TerrainAdditiveFeatHLSL::processPix( Vector<ShaderComponent*> &componentList, 
 void TerrainAdditiveFeatHLSL::processPix( Vector<ShaderComponent*> &componentList, 
                                           const MaterialFeatureData &fd )
                                           const MaterialFeatureData &fd )
 {
 {
-   Var *color = (Var*) LangElement::find( "col" );
+   Var *color = NULL;
+   if (fd.features[MFT_DeferredTerrainDetailMap])
+       color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget1) );
+   else
+       color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::DefaultTarget) );
+
    Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
    Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
    if ( !color || !blendTotal )
    if ( !color || !blendTotal )
       return;
       return;
@@ -1033,5 +1020,43 @@ void TerrainAdditiveFeatHLSL::processPix( Vector<ShaderComponent*> &componentLis
    meta->addStatement( new GenOp( "   clip( @ - 0.0001 );\r\n", blendTotal ) );
    meta->addStatement( new GenOp( "   clip( @ - 0.0001 );\r\n", blendTotal ) );
    meta->addStatement( new GenOp( "   @.a = @;\r\n", color, blendTotal ) );
    meta->addStatement( new GenOp( "   @.a = @;\r\n", color, blendTotal ) );
 
 
+
+   output = meta;
+}
+
+//standard matInfo map contains data of the form .r = bitflags, .g = (will contain AO), 
+//.b = specular strength, a= spec power. 
+//here, it's merely a cutout for now, so that lightmapping (target3) doesn't get mangled.
+//we'll most likely revisit that later. possibly several ways...
+
+U32 TerrainBlankInfoMapFeatHLSL::getOutputTargets(const MaterialFeatureData &fd) const
+{
+   return fd.features[MFT_DeferredTerrainBaseMap] ? ShaderFeature::RenderTarget2 : ShaderFeature::RenderTarget1;
+}
+
+void TerrainBlankInfoMapFeatHLSL::processPix(Vector<ShaderComponent*> &componentList,
+   const MaterialFeatureData &fd)
+{
+   // search for material var
+   Var *material;
+   OutputTarget targ = RenderTarget1;
+   if (fd.features[MFT_isDeferred])
+   {
+      targ = RenderTarget2;
+   }
+   material = (Var*)LangElement::find(getOutputTargetVarName(targ));
+
+   MultiLine * meta = new MultiLine;
+   if (!material)
+   {
+      // create color var
+      material = new Var;
+      material->setType("fragout");
+      material->setName(getOutputTargetVarName(targ));
+      material->setStructName("OUT");
+   }
+
+   meta->addStatement(new GenOp("   @ = float4(0.0,0.0,0.0,0.0001);\r\n", material));
+
    output = meta;
    output = meta;
 }
 }

+ 17 - 0
Engine/source/terrain/hlsl/terrFeatureHLSL.h

@@ -68,6 +68,8 @@ public:
    virtual Resources getResources( const MaterialFeatureData &fd );
    virtual Resources getResources( const MaterialFeatureData &fd );
 
 
    virtual String getName() { return "Terrain Base Texture"; }
    virtual String getName() { return "Terrain Base Texture"; }
+
+   virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
 };
 };
 
 
 
 
@@ -91,6 +93,8 @@ public:
    virtual Resources getResources( const MaterialFeatureData &fd );
    virtual Resources getResources( const MaterialFeatureData &fd );
 
 
    virtual String getName() { return "Terrain Detail Texture"; }
    virtual String getName() { return "Terrain Detail Texture"; }
+
+   virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
 };
 };
 
 
 
 
@@ -114,6 +118,8 @@ public:
    virtual Resources getResources( const MaterialFeatureData &fd );
    virtual Resources getResources( const MaterialFeatureData &fd );
 
 
    virtual String getName() { return "Terrain Macro Texture"; }
    virtual String getName() { return "Terrain Macro Texture"; }
+
+   virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const;
 };
 };
 
 
 
 
@@ -155,4 +161,15 @@ public:
    virtual String getName() { return "Terrain Additive"; }
    virtual String getName() { return "Terrain Additive"; }
 };
 };
 
 
+class TerrainBlankInfoMapFeatHLSL : public TerrainFeatHLSL
+{
+public:
+
+   virtual void processPix(Vector<ShaderComponent*> &componentList,
+      const MaterialFeatureData &fd);
+   
+   virtual U32 getOutputTargets(const MaterialFeatureData &fd) const;
+   virtual String getName() { return "Blank Matinfo map"; }
+};
+
 #endif // _TERRFEATUREHLSL_H_
 #endif // _TERRFEATUREHLSL_H_

+ 21 - 9
Engine/source/terrain/terrCellMaterial.cpp

@@ -37,6 +37,7 @@
 #include "gfx/util/screenspace.h"
 #include "gfx/util/screenspace.h"
 #include "lighting/advanced/advancedLightBinManager.h"
 #include "lighting/advanced/advancedLightBinManager.h"
 
 
+S32 sgMaxTerrainMaterialsPerPass = 3;
 
 
 AFTER_MODULE_INIT( MaterialManager )
 AFTER_MODULE_INIT( MaterialManager )
 {
 {
@@ -310,12 +311,12 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
    if ( GFX->getPixelShaderVersion() < 3.0f )
    if ( GFX->getPixelShaderVersion() < 3.0f )
       baseOnly = true;
       baseOnly = true;
 
 
-   // NOTE: At maximum we only try to combine 3 materials 
+   // NOTE: At maximum we only try to combine sgMaxTerrainMaterialsPerPass materials 
    // into a single pass.  This is sub-optimal for the simplest
    // into a single pass.  This is sub-optimal for the simplest
    // cases, but the most common case results in much fewer
    // cases, but the most common case results in much fewer
    // shader generation failures and permutations leading to
    // shader generation failures and permutations leading to
    // faster load time and less hiccups during gameplay.
    // faster load time and less hiccups during gameplay.
-   U32 matCount = getMin( 3, materials->size() );
+   U32 matCount = getMin( sgMaxTerrainMaterialsPerPass, materials->size() );
 
 
    Vector<GFXTexHandle> normalMaps;
    Vector<GFXTexHandle> normalMaps;
 
 
@@ -349,24 +350,27 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
    {
    {
       FeatureSet features;
       FeatureSet features;
       features.addFeature( MFT_VertTransform );
       features.addFeature( MFT_VertTransform );
-      features.addFeature( MFT_TerrainBaseMap );
 
 
       if ( prePassMat )
       if ( prePassMat )
       {
       {
          features.addFeature( MFT_EyeSpaceDepthOut );
          features.addFeature( MFT_EyeSpaceDepthOut );
          features.addFeature( MFT_PrePassConditioner );
          features.addFeature( MFT_PrePassConditioner );
+         features.addFeature( MFT_DeferredTerrainBaseMap );
+         features.addFeature(MFT_isDeferred);
 
 
          if ( advancedLightmapSupport )
          if ( advancedLightmapSupport )
-            features.addFeature( MFT_RenderTarget1_Zero );
+            features.addFeature( MFT_RenderTarget3_Zero );
       }
       }
       else
       else
       {
       {
+         features.addFeature( MFT_TerrainBaseMap );
          features.addFeature( MFT_RTLighting );
          features.addFeature( MFT_RTLighting );
 
 
          // The HDR feature is always added... it will compile out
          // The HDR feature is always added... it will compile out
          // if HDR is not enabled in the engine.
          // if HDR is not enabled in the engine.
          features.addFeature( MFT_HDROut );
          features.addFeature( MFT_HDROut );
       }
       }
+      features.addFeature(MFT_DeferredTerrainBlankInfoMap);
 
 
       // Enable lightmaps and fogging if we're in BL.
       // Enable lightmaps and fogging if we're in BL.
       if ( reflectMat || useBLM )
       if ( reflectMat || useBLM )
@@ -405,8 +409,16 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
 
 
 		 // check for macro detail texture
 		 // check for macro detail texture
          if (  !(mat->getMacroSize() <= 0 || mat->getMacroDistance() <= 0 || mat->getMacroMap().isEmpty() ) )
          if (  !(mat->getMacroSize() <= 0 || mat->getMacroDistance() <= 0 || mat->getMacroMap().isEmpty() ) )
+         {
+            if(prePassMat)
+               features.addFeature( MFT_DeferredTerrainMacroMap, featureIndex );
+            else
 	         features.addFeature( MFT_TerrainMacroMap, featureIndex );
 	         features.addFeature( MFT_TerrainMacroMap, featureIndex );
+         }
 
 
+         if(prePassMat)
+             features.addFeature( MFT_DeferredTerrainDetailMap, featureIndex );
+         else
          features.addFeature( MFT_TerrainDetailMap, featureIndex );
          features.addFeature( MFT_TerrainDetailMap, featureIndex );
 
 
          pass->materials.push_back( (*materials)[i] );
          pass->materials.push_back( (*materials)[i] );
@@ -536,8 +548,8 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
       // MFT_TerrainAdditive feature to lerp the
       // MFT_TerrainAdditive feature to lerp the
       // output normal with the previous pass.
       // output normal with the previous pass.
       //
       //
-      if ( prePassMat )
-         desc.setColorWrites( true, true, false, false );
+      //if ( prePassMat )
+         //desc.setColorWrites( true, true, false, false );
    }
    }
 
 
    // We write to the zbuffer if this is a prepass
    // We write to the zbuffer if this is a prepass
@@ -656,9 +668,9 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
    if ( prePassMat )
    if ( prePassMat )
       desc.addDesc( RenderPrePassMgr::getOpaqueStenciWriteDesc( false ) );
       desc.addDesc( RenderPrePassMgr::getOpaqueStenciWriteDesc( false ) );
 
 
-   // Flip the cull for reflection materials.
-   if ( reflectMat )
-      desc.setCullMode( GFXCullCW );
+   // Shut off culling for prepass materials (reflection support).
+   if ( prePassMat )
+      desc.setCullMode( GFXCullNone );
 
 
    pass->stateBlock = GFX->createStateBlock( desc );
    pass->stateBlock = GFX->createStateBlock( desc );
 
 

+ 5 - 1
Engine/source/terrain/terrFeatureTypes.cpp

@@ -34,4 +34,8 @@ ImplementFeatureType( MFT_TerrainMacroMap, MFG_Texture, 104.0f, false );
 ImplementFeatureType( MFT_TerrainLightMap, MFG_Texture, 105.0f, false );
 ImplementFeatureType( MFT_TerrainLightMap, MFG_Texture, 105.0f, false );
 ImplementFeatureType( MFT_TerrainSideProject, MFG_Texture, 106.0f, false );
 ImplementFeatureType( MFT_TerrainSideProject, MFG_Texture, 106.0f, false );
 ImplementFeatureType( MFT_TerrainAdditive, MFG_PostProcess, 999.0f, false );
 ImplementFeatureType( MFT_TerrainAdditive, MFG_PostProcess, 999.0f, false );
-
+//Deferred Shading
+ImplementFeatureType( MFT_DeferredTerrainBaseMap, MFG_Texture, 100.1f, false );
+ImplementFeatureType( MFT_DeferredTerrainDetailMap, MFG_Texture, 102.1f, false );
+ImplementFeatureType( MFT_DeferredTerrainMacroMap, MFG_Texture, 104.1f, false );
+ImplementFeatureType( MFT_DeferredTerrainBlankInfoMap, MFG_Texture, 104.1f, false);

+ 6 - 0
Engine/source/terrain/terrFeatureTypes.h

@@ -35,6 +35,12 @@ DeclareFeatureType( MFT_TerrainParallaxMap );
 DeclareFeatureType( MFT_TerrainLightMap );
 DeclareFeatureType( MFT_TerrainLightMap );
 DeclareFeatureType( MFT_TerrainSideProject );
 DeclareFeatureType( MFT_TerrainSideProject );
 DeclareFeatureType( MFT_TerrainAdditive );
 DeclareFeatureType( MFT_TerrainAdditive );
+//Deferred Shading
+DeclareFeatureType( MFT_DeferredTerrainBaseMap );
+DeclareFeatureType( MFT_DeferredTerrainDetailMap );
+DeclareFeatureType( MFT_DeferredTerrainMacroMap );
+DeclareFeatureType( MFT_DeferredTerrainBlankInfoMap );
+
 
 
 #endif // _TERRFEATURETYPES_H_
 #endif // _TERRFEATURETYPES_H_
 
 

+ 1 - 0
Templates/Full/game/shaders/common/terrain/terrain.glsl

@@ -32,6 +32,7 @@ float calcBlend( float texId, vec2 layerCoord, float layerSize, vec4 layerSample
    vec4 diff = clamp( abs( layerSample - texId ), 0.0, 1.0 );
    vec4 diff = clamp( abs( layerSample - texId ), 0.0, 1.0 );
    float noBlend = float(any( bvec4(1 - diff) ));
    float noBlend = float(any( bvec4(1 - diff) ));
 
 
+   // Check if any of the layer samples 
    // match the current texture id.
    // match the current texture id.
    vec4 factors = vec4(0);
    vec4 factors = vec4(0);
    for(int i = 0; i < 4; i++)
    for(int i = 0; i < 4; i++)

+ 5 - 223
Templates/Full/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui

@@ -1354,132 +1354,6 @@
                            bitmap = "tools/gui/images/delete";
                            bitmap = "tools/gui/images/delete";
                         };
                         };
                      };
                      };
-                     new GuiBitmapCtrl(){
-                        position="6 357";
-                        extent ="175 2";
-                        HorizSizing = "width";
-                        bitmap ="tools/gui/images/separator-v"; 
-                     };
-                     new GuiContainer(){ // Environment Map
-                        profile="ToolsGuiDefaultProfile";
-                        isContainer = "1";
-                        position = "6 359";
-                        Extent = "185 52";
-                        HorizSizing = "width";
-                        
-                        new GuiBitmapCtrl() {
-                           canSaveDynamicFields = "0";
-                           internalName = "envMapDisplayBitmap";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiDefaultProfile";
-                           HorizSizing = "right";
-                           VertSizing = "bottom";
-                           position = "1 1";
-                           Extent = "48 48";
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           hovertime = "1000";
-                           bitmap = "tools/materialeditor/gui/unknownImage";
-                           wrap = "0";
-                        };
-                        new GuiTextCtrl() {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "EditorTextProfile";
-                           HorizSizing = "right";
-                           VertSizing = "bottom";
-                           position = "56 -3";
-                           Extent = "72 18";
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           hovertime = "1000";
-                           Margin = "0 0 0 0";
-                           Padding = "0 0 0 0";
-                           AnchorTop = "1";
-                           AnchorBottom = "0";
-                           AnchorLeft = "1";
-                           AnchorRight = "0";
-                           text = "Env Map";
-                           maxLength = "1024";
-                        };
-                        new GuiBitmapButtonCtrl() {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiDefaultProfile";
-                           HorizSizing = "right";
-                           VertSizing = "bottom";
-                           position = "1 1";
-                           Extent = "48 48";
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "MaterialEditorGui.updateTextureMap(\"env\", 1);";
-                           tooltipprofile = "ToolsGuiDefaultProfile";
-                           ToolTip = "Change the active Environment Map for this layer.";
-                           hovertime = "1000";
-                           groupNum = "-1";
-                           buttonType = "PushButton";
-                           useMouseEvents = "0";
-                           bitmap = "tools/materialEditor/gui/cubemapBtnBorder";
-                        };
-                        new GuiTextCtrl() {
-                           canSaveDynamicFields = "0";
-                           internalName = "envMapNameText";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiTextProfile";
-                           HorizSizing = "width";
-                           VertSizing = "bottom";
-                           position = "56 16";
-                           Extent = "143 17";
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           hovertime = "1000";
-                           Margin = "0 0 0 0";
-                           Padding = "0 0 0 0";
-                           AnchorTop = "1";
-                           AnchorBottom = "0";
-                           AnchorLeft = "1";
-                           AnchorRight = "0";
-                           text = "None";
-                           maxLength = "1024";
-                        };
-                        new GuiButtonCtrl(){
-                           profile="ToolsGuiButtonProfile";
-                           text ="Edit";
-                           HorizSizing = "left";
-                           VertSizing = "bottom"; 
-                           position = "134 34";
-                           Extent = "40 16";
-                           buttonType = "PushButton";
-                           command="MaterialEditorGui.updateTextureMap(\"env\", 1);";
-                        };
-                        new GuiBitmapButtonCtrl() {
-                           canSaveDynamicFields = "0";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiDefaultProfile";
-                           HorizSizing = "left";
-                           VertSizing = "bottom";
-                           position = "177 34";
-                           Extent = "16 16";
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "MaterialEditorGui.updateTextureMap(\"env\", 0);";
-                           hovertime = "1000";
-                           groupNum = "-1";
-                           buttonType = "PushButton";
-                           useMouseEvents = "0";
-                           bitmap = "tools/gui/images/delete";
-                        };
-                     };
                   };
                   };
                };
                };
                new GuiRolloutCtrl() {
                new GuiRolloutCtrl() {
@@ -1491,6 +1365,7 @@
                   Position = "0 0";
                   Position = "0 0";
                   Extent = "195 0";
                   Extent = "195 0";
                   Caption = "Accumulation Properties";
                   Caption = "Accumulation Properties";
+                  Expanded = false;
                   Margin = "-1 0 0 0";
                   Margin = "-1 0 0 0";
                   DragSizable = false;
                   DragSizable = false;
                   container = true;
                   container = true;
@@ -1967,6 +1842,7 @@
                   Position = "0 0";
                   Position = "0 0";
                   Extent = "185 0";
                   Extent = "185 0";
                   Caption = "Lighting Properties";
                   Caption = "Lighting Properties";
+                  Expanded = false;
                   Margin = "-1 0 0 0";
                   Margin = "-1 0 0 0";
                   DragSizable = false;
                   DragSizable = false;
                   container = true;
                   container = true;
@@ -2364,101 +2240,6 @@
                            useMouseEvents = "0";
                            useMouseEvents = "0";
                            useInactiveState = "0";
                            useInactiveState = "0";
                         };
                         };
-                        new GuiCheckBoxCtrl() {
-                           canSaveDynamicFields = "0";
-                           internalName = "subSurfaceCheckbox";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiCheckBoxProfile";
-                           HorizSizing = "right";
-                           VertSizing = "bottom";
-                           position = "8 46";
-                           Extent = "79 16";
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "MaterialEditorGui.updateActiveMaterial(\"subSurface[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());";
-                           tooltipprofile = "ToolsGuiDefaultProfile";
-                           ToolTip = "Enables the use of subsurface scattering for this layer.";
-                           hovertime = "1000";
-                           text = "Sub Surface";
-                           groupNum = "-1";
-                           buttonType = "ToggleButton";
-                           useMouseEvents = "0";
-                           useInactiveState = "0";
-                        };
-                        new GuiSwatchButtonCtrl() {
-                           canSaveDynamicFields = "0";
-                           internalName = "subSurfaceColorSwatch";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "GuiInspectorSwatchButtonProfile";
-                           HorizSizing = "right";
-                           VertSizing = "bottom";
-                           position = "90 46";
-                           Extent = "16 16";
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "getColorF(materialEd_PreviewMaterial.subSurfaceColor[MaterialEditorGui.currentLayer], \"MaterialEditorGui.updateSubSurfaceColor\");";
-                           tooltip = "Set the subsurface scattering color";
-                           hovertime = "1000";
-                           groupNum = "-1";
-                           buttonType = "PushButton";
-                           useMouseEvents = "0";
-                        };
-                        new GuiTextEditCtrl() {
-                           canSaveDynamicFields = "0";
-                           internalName = "subSurfaceRolloffTextEdit";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "right";
-                           VertSizing = "bottom";
-                           position = "114 45";
-                           Extent = "29 18";
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           tooltip = "Set the subsurface rolloff factor";
-                           Command = "MaterialEditorGui.updateActiveMaterial(\"subSurfaceRolloff[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getText());";
-                           hovertime = "1000";
-                           AnchorTop = "1";
-                           AnchorBottom = "0";
-                           AnchorLeft = "1";
-                           AnchorRight = "0";
-                           text = "32";
-                           maxLength = "5";
-                        };
-                        new GuiTextCtrl() {
-                           HorizSizing = "right";
-                           VertSizing = "bottom";
-                           position = "9 65";
-                           Extent = "89 16";
-                           text = "Minnaert constant";
-                        };
-                        new GuiTextEditCtrl() {
-                           canSaveDynamicFields = "0";
-                           internalName = "minnaertTextEdit";
-                           Enabled = "1";
-                           isContainer = "0";
-                           Profile = "ToolsGuiTextEditProfile";
-                           HorizSizing = "right";
-                           VertSizing = "bottom";
-                           position = "114 65";
-                           Extent = "29 18";
-                           MinExtent = "8 2";
-                           canSave = "1";
-                           Visible = "1";
-                           Command = "MaterialEditorGui.updateActiveMaterial(\"minnaertConstant[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getText());";
-                           hovertime = "1000";
-                           AnchorTop = "1";
-                           AnchorBottom = "0";
-                           AnchorLeft = "1";
-                           AnchorRight = "0";
-                           text = "32";
-                           maxLength = "3";
-                        };
                      };
                      };
                   };
                   };
                };
                };
@@ -2471,9 +2252,9 @@
                   Position = "0 0";
                   Position = "0 0";
                   Extent = "185 0";
                   Extent = "185 0";
                   Caption = "Animation Properties";
                   Caption = "Animation Properties";
+                  Expanded = false;
                   Margin = "-1 0 0 0";
                   Margin = "-1 0 0 0";
                   DragSizable = false;
                   DragSizable = false;
-                  Expanded = false;
                   container = true;
                   container = true;
                   parentRollout = %this.rollout;
                   parentRollout = %this.rollout;
                   object = %behavior;
                   object = %behavior;
@@ -3283,6 +3064,7 @@
                   Position = "0 0";
                   Position = "0 0";
                   Extent = "202 0";
                   Extent = "202 0";
                   Caption = "Advanced (all layers)";
                   Caption = "Advanced (all layers)";
+                  Expanded = false;
                   Margin = "4 4 4 0";
                   Margin = "4 4 4 0";
                   DragSizable = false;
                   DragSizable = false;
                   container = true;
                   container = true;
@@ -3519,7 +3301,7 @@
                            Profile = "ToolsGuiCheckBoxProfile";
                            Profile = "ToolsGuiCheckBoxProfile";
                            HorizSizing = "right";
                            HorizSizing = "right";
                            VertSizing = "bottom";
                            VertSizing = "bottom";
-                           position = "100 56";
+                           position = "105 55";
                            Extent = "85 16";
                            Extent = "85 16";
                            MinExtent = "8 2";
                            MinExtent = "8 2";
                            canSave = "1";
                            canSave = "1";