Browse Source

Core implementation of Physical Based Rendering.

Areloch 7 years ago
parent
commit
b4a1d18f42
100 changed files with 1550 additions and 536 deletions
  1. 3 3
      Engine/source/T3D/levelInfo.cpp
  2. 19 0
      Engine/source/T3D/shapeBase.cpp
  3. 1 1
      Engine/source/T3D/shapeBase.h
  4. 4 0
      Engine/source/T3D/tsStatic.cpp
  5. 8 3
      Engine/source/gfx/D3D11/gfxD3D11OcclusionQuery.cpp
  6. 1 1
      Engine/source/gfx/D3D11/gfxD3D11OcclusionQuery.h
  7. 336 0
      Engine/source/gfx/bitmap/cubemapSaver.cpp
  8. 41 0
      Engine/source/gfx/bitmap/cubemapSaver.h
  9. 10 1
      Engine/source/gfx/bitmap/gBitmap.cpp
  10. 2 2
      Engine/source/gfx/bitmap/loaders/bitmapPng.cpp
  11. 0 1
      Engine/source/gfx/gfxDevice.h
  12. 23 0
      Engine/source/gfx/gfxTextureHandle.cpp
  13. 4 0
      Engine/source/gfx/gfxTextureHandle.h
  14. 9 5
      Engine/source/gfx/gfxTextureManager.cpp
  15. 37 5
      Engine/source/gfx/gl/gfxGLOcclusionQuery.cpp
  16. 1 0
      Engine/source/gfx/gl/gfxGLOcclusionQuery.h
  17. 16 0
      Engine/source/gfx/sim/cubemapData.cpp
  18. 1 1
      Engine/source/gui/3d/guiTSControl.cpp
  19. 1 1
      Engine/source/gui/core/guiCanvas.cpp
  20. 4 6
      Engine/source/lighting/advanced/advancedLightBinManager.cpp
  21. 47 47
      Engine/source/lighting/advanced/glsl/advancedLightingFeaturesGLSL.cpp
  22. 31 41
      Engine/source/lighting/advanced/glsl/deferredShadingFeaturesGLSL.cpp
  23. 0 12
      Engine/source/lighting/advanced/glsl/deferredShadingFeaturesGLSL.h
  24. 63 62
      Engine/source/lighting/advanced/hlsl/advancedLightingFeaturesHLSL.cpp
  25. 24 44
      Engine/source/lighting/advanced/hlsl/deferredShadingFeaturesHLSL.cpp
  26. 0 12
      Engine/source/lighting/advanced/hlsl/deferredShadingFeaturesHLSL.h
  27. 48 19
      Engine/source/materials/materialDefinition.cpp
  28. 11 4
      Engine/source/materials/materialDefinition.h
  29. 9 9
      Engine/source/materials/materialFeatureTypes.cpp
  30. 2 1
      Engine/source/materials/materialFeatureTypes.h
  31. 63 38
      Engine/source/materials/processedMaterial.cpp
  32. 1 0
      Engine/source/materials/processedMaterial.h
  33. 15 10
      Engine/source/materials/processedShaderMaterial.cpp
  34. 2 2
      Engine/source/materials/processedShaderMaterial.h
  35. 7 0
      Engine/source/math/mMathFn.h
  36. 5 0
      Engine/source/math/mPoint4.h
  37. 1 2
      Engine/source/platformWin32/threads/thread.cpp
  38. 6 0
      Engine/source/renderInstance/renderBinManager.cpp
  39. 44 48
      Engine/source/renderInstance/renderDeferredMgr.cpp
  40. 4 3
      Engine/source/renderInstance/renderDeferredMgr.h
  41. 45 1
      Engine/source/renderInstance/renderTranslucentMgr.cpp
  42. 1 1
      Engine/source/scene/culling/sceneCullingState.cpp
  43. 13 1
      Engine/source/shaderGen/GLSL/pixSpecularGLSL.cpp
  44. 59 28
      Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp
  45. 2 1
      Engine/source/shaderGen/GLSL/shaderGenGLSLInit.cpp
  46. 13 7
      Engine/source/shaderGen/HLSL/pixSpecularHLSL.cpp
  47. 67 40
      Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp
  48. 2 1
      Engine/source/shaderGen/HLSL/shaderGenHLSLInit.cpp
  49. 2 2
      Engine/source/shaderGen/shaderGenVars.cpp
  50. 2 2
      Engine/source/shaderGen/shaderGenVars.h
  51. 25 11
      Engine/source/terrain/glsl/terrFeatureGLSL.cpp
  52. 52 29
      Engine/source/terrain/hlsl/terrFeatureHLSL.cpp
  53. 5 8
      Engine/source/terrain/terrCellMaterial.cpp
  54. 0 3
      Engine/source/terrain/terrFeatureTypes.cpp
  55. 0 3
      Engine/source/terrain/terrFeatureTypes.h
  56. 14 11
      Engine/source/ts/collada/colladaAppMaterial.cpp
  57. 5 3
      Engine/source/ts/collada/colladaAppMaterial.h
  58. 1 0
      Templates/Full/game/art/decals/managedDecalData.cs
  59. BIN
      Templates/Full/game/art/particles/fireplace.png
  60. BIN
      Templates/Full/game/art/particles/test.png
  61. BIN
      Templates/Full/game/art/shapes/Cheetah/Cheetah_c.dds
  62. BIN
      Templates/Full/game/art/shapes/actors/Soldier/soldier_c.png
  63. BIN
      Templates/Full/game/art/shapes/station/building01walls_c.dds
  64. BIN
      Templates/Full/game/art/shapes/station/building01walls_n.dds
  65. BIN
      Templates/Full/game/art/shapes/station/grid_c.dds
  66. BIN
      Templates/Full/game/art/shapes/station/grid_c.png
  67. BIN
      Templates/Full/game/art/shapes/station/grid_n.dds
  68. BIN
      Templates/Full/game/art/shapes/station/plate_c.dds
  69. BIN
      Templates/Full/game/art/shapes/station/plate_n.dds
  70. BIN
      Templates/Full/game/art/shapes/textures/Metal_A.png
  71. BIN
      Templates/Full/game/art/shapes/textures/Metal_N.png
  72. BIN
      Templates/Full/game/art/shapes/textures/Metal_S.png
  73. BIN
      Templates/Full/game/art/shapes/textures/PBRGrid_a.dds
  74. BIN
      Templates/Full/game/art/shapes/textures/PBRGrid_c.dds
  75. BIN
      Templates/Full/game/art/shapes/textures/PBRGrid_n.png
  76. 6 0
      Templates/Full/game/art/shapes/textures/PBRTEST.cs
  77. 108 0
      Templates/Full/game/art/shapes/textures/PBRTEST.dae
  78. 11 0
      Templates/Full/game/art/shapes/textures/PBRTEST2.cs
  79. 50 0
      Templates/Full/game/art/shapes/textures/PBRTEST2.dae
  80. BIN
      Templates/Full/game/art/shapes/textures/Stone_A.dds
  81. BIN
      Templates/Full/game/art/shapes/textures/Stone_N.png
  82. BIN
      Templates/Full/game/art/shapes/textures/Stone_S.dds
  83. BIN
      Templates/Full/game/art/shapes/textures/T3D_Metal_2_any.png
  84. BIN
      Templates/Full/game/art/shapes/textures/T3D_Metal_2_basecolor.png
  85. BIN
      Templates/Full/game/art/shapes/textures/T3D_Metal_2_normal.png
  86. 0 0
      Templates/Full/game/art/shapes/textures/T3D_Metal_6.sbs
  87. BIN
      Templates/Full/game/art/shapes/textures/T3D_Metal_6.sbsar
  88. BIN
      Templates/Full/game/art/shapes/textures/T3D_Metal_6_any.png
  89. BIN
      Templates/Full/game/art/shapes/textures/T3D_Metal_6_basecolor.png
  90. BIN
      Templates/Full/game/art/shapes/textures/T3D_Metal_6_normal.png
  91. BIN
      Templates/Full/game/art/shapes/textures/Wood1_A.dds
  92. BIN
      Templates/Full/game/art/shapes/textures/Wood1_N.png
  93. BIN
      Templates/Full/game/art/shapes/textures/Wood1_S.dds
  94. BIN
      Templates/Full/game/art/shapes/textures/black.dds
  95. BIN
      Templates/Full/game/art/shapes/textures/copperalb.png
  96. BIN
      Templates/Full/game/art/shapes/textures/coppermtl.png
  97. BIN
      Templates/Full/game/art/shapes/textures/coppernrm.png
  98. BIN
      Templates/Full/game/art/shapes/textures/copperrgh.png
  99. 113 0
      Templates/Full/game/art/shapes/textures/materials.cs
  100. 50 0
      Templates/Full/game/art/shapes/textures/pbrGrid.dae

+ 3 - 3
Engine/source/T3D/levelInfo.cpp

@@ -97,7 +97,7 @@ LevelInfo::LevelInfo()
 
 
    mNetFlags.set( ScopeAlways | Ghostable );
    mNetFlags.set( ScopeAlways | Ghostable );
 
 
-   mAdvancedLightmapSupport = false;
+   mAdvancedLightmapSupport = true;
    mAccuTextureName = "";
    mAccuTextureName = "";
    mAccuTexture = NULL;
    mAccuTexture = NULL;
 
 
@@ -163,8 +163,8 @@ void LevelInfo::initPersistFields()
       addField( "ambientLightBlendCurve", TypeEaseF, Offset( mAmbientLightBlendCurve, LevelInfo ),
       addField( "ambientLightBlendCurve", TypeEaseF, Offset( mAmbientLightBlendCurve, LevelInfo ),
          "Interpolation curve to use for blending from one ambient light color to a different one." );
          "Interpolation curve to use for blending from one ambient light color to a different one." );
 
 
-      addField( "advancedLightmapSupport", TypeBool, Offset( mAdvancedLightmapSupport, LevelInfo ),
-         "Enable expanded support for mixing static and dynamic lighting (more costly)" );
+      //addField( "advancedLightmapSupport", TypeBool, Offset( mAdvancedLightmapSupport, LevelInfo ),
+      //   "Enable expanded support for mixing static and dynamic lighting (more costly)" );
 
 
       addProtectedField("AccuTexture", TypeStringFilename, Offset(mAccuTextureName, LevelInfo),
       addProtectedField("AccuTexture", TypeStringFilename, Offset(mAccuTextureName, LevelInfo),
          &_setLevelAccuTexture, &defaultProtectedGetFn, "Accumulation texture.");
          &_setLevelAccuTexture, &defaultProtectedGetFn, "Accumulation texture.");

+ 19 - 0
Engine/source/T3D/shapeBase.cpp

@@ -1176,6 +1176,13 @@ void ShapeBase::onRemove()
       for (S32 i = 0; i < MaxSoundThreads; i++)
       for (S32 i = 0; i < MaxSoundThreads; i++)
          stopAudio(i);
          stopAudio(i);
 
 
+   // Accumulation and environment mapping
+   if (isClientObject() && mShapeInstance)
+   {
+      if (mShapeInstance->hasAccumulation())
+         AccumulationVolume::removeObject(this);
+   }
+
    if ( isClientObject() )   
    if ( isClientObject() )   
    {
    {
       mCubeReflector.unregisterReflector();
       mCubeReflector.unregisterReflector();
@@ -3724,6 +3731,18 @@ void ShapeBase::setCurrentWaterObject( WaterObject *obj )
    mCurrentWaterObject = obj;
    mCurrentWaterObject = obj;
 }
 }
 
 
+void ShapeBase::setTransform(const MatrixF & mat)
+{
+	Parent::setTransform(mat);
+
+	// Accumulation and environment mapping
+	if (isClientObject() && mShapeInstance)
+	{
+		if (mShapeInstance->hasAccumulation())
+			AccumulationVolume::updateObject(this);
+	}
+}
+
 void ShapeBase::notifyCollisionCallbacks(SceneObject* obj, const VectorF& vel)
 void ShapeBase::notifyCollisionCallbacks(SceneObject* obj, const VectorF& vel)
 {
 {
    for (S32 i = 0; i < collision_callbacks.size(); i++)
    for (S32 i = 0; i < collision_callbacks.size(); i++)

+ 1 - 1
Engine/source/T3D/shapeBase.h

@@ -1842,7 +1842,7 @@ public:
    virtual WaterObject* getCurrentWaterObject();
    virtual WaterObject* getCurrentWaterObject();
 
 
    void setCurrentWaterObject( WaterObject *obj );
    void setCurrentWaterObject( WaterObject *obj );
-
+   void setTransform(const MatrixF & mat);
    virtual F32 getMass() const { return mMass; }
    virtual F32 getMass() const { return mMass; }
 
 
    /// @name Network
    /// @name Network

+ 4 - 0
Engine/source/T3D/tsStatic.cpp

@@ -377,6 +377,10 @@ bool TSStatic::_createShape()
    resetWorldBox();
    resetWorldBox();
 
 
    mShapeInstance = new TSShapeInstance( mShape, isClientObject() );
    mShapeInstance = new TSShapeInstance( mShape, isClientObject() );
+   if (isClientObject())
+   {
+      mShapeInstance->cloneMaterialList();
+   }
 
 
    if (isClientObject())
    if (isClientObject())
       mShapeInstance->cloneMaterialList();
       mShapeInstance->cloneMaterialList();

+ 8 - 3
Engine/source/gfx/D3D11/gfxD3D11OcclusionQuery.cpp

@@ -32,7 +32,8 @@
 
 
 GFXD3D11OcclusionQuery::GFXD3D11OcclusionQuery(GFXDevice *device)
 GFXD3D11OcclusionQuery::GFXD3D11OcclusionQuery(GFXDevice *device)
  : GFXOcclusionQuery(device), 
  : GFXOcclusionQuery(device), 
-   mQuery(NULL)   
+   mQuery(NULL), 
+   mTesting(false)   
 {
 {
 #ifdef TORQUE_GATHER_METRICS
 #ifdef TORQUE_GATHER_METRICS
    mTimer = PlatformTimer::create();
    mTimer = PlatformTimer::create();
@@ -73,8 +74,11 @@ bool GFXD3D11OcclusionQuery::begin()
       AssertISV(hRes != E_OUTOFMEMORY, "GFXD3D11OcclusionQuery::begin - Out of memory");
       AssertISV(hRes != E_OUTOFMEMORY, "GFXD3D11OcclusionQuery::begin - Out of memory");
    }
    }
 
 
-   // Add a begin marker to the command buffer queue.
-   D3D11DEVICECONTEXT->Begin(mQuery);
+   if (!mTesting)
+   {
+      D3D11DEVICECONTEXT->Begin(mQuery);
+      mTesting = true;
+   }
 
 
 #ifdef TORQUE_GATHER_METRICS
 #ifdef TORQUE_GATHER_METRICS
    mBeginFrame = GuiTSCtrl::getFrameCount();
    mBeginFrame = GuiTSCtrl::getFrameCount();
@@ -90,6 +94,7 @@ void GFXD3D11OcclusionQuery::end()
 
 
    // Add an end marker to the command buffer queue.
    // Add an end marker to the command buffer queue.
    D3D11DEVICECONTEXT->End(mQuery);
    D3D11DEVICECONTEXT->End(mQuery);
+   mTesting = false;
 
 
 #ifdef TORQUE_GATHER_METRICS
 #ifdef TORQUE_GATHER_METRICS
    AssertFatal( mBeginFrame == GuiTSCtrl::getFrameCount(), "GFXD3D11OcclusionQuery::end - ended query on different frame than begin!" );   
    AssertFatal( mBeginFrame == GuiTSCtrl::getFrameCount(), "GFXD3D11OcclusionQuery::end - ended query on different frame than begin!" );   

+ 1 - 1
Engine/source/gfx/D3D11/gfxD3D11OcclusionQuery.h

@@ -34,7 +34,7 @@ class GFXD3D11OcclusionQuery : public GFXOcclusionQuery
 {
 {
 private:
 private:
    mutable ID3D11Query *mQuery;
    mutable ID3D11Query *mQuery;
-
+   bool mTesting;
 #ifdef TORQUE_GATHER_METRICS
 #ifdef TORQUE_GATHER_METRICS
    U32 mBeginFrame;
    U32 mBeginFrame;
    U32 mTimeSinceEnd;
    U32 mTimeSinceEnd;

+ 336 - 0
Engine/source/gfx/bitmap/cubemapSaver.cpp

@@ -0,0 +1,336 @@
+//-----------------------------------------------------------------------------
+// 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 "gfx/bitmap/cubemapSaver.h"
+#include "platform/platform.h"
+#include "gfx/bitmap/ddsFile.h"
+#include "gfx/bitmap/imageUtils.h"
+#include "gfx/gfxDevice.h"
+#include "gfx/gfxTransformSaver.h"
+#include "gfx/gfxTextureManager.h"
+#include "materials/shaderData.h"
+#include "core/stream/fileStream.h"
+#include "math/mathUtils.h"
+#include "math/mTransform.h"
+
+
+namespace CubemapSaver
+{
+   const U32 CubeFaces = 6;
+
+   void _setConstBuffer(GFXShaderConstHandle* handle, GFXShaderConstBuffer *cbuf, const VectorF &vLookatPt, const VectorF &vUpVec)
+   {
+      VectorF cross = mCross(vUpVec, vLookatPt);
+      cross.normalizeSafe();
+
+      MatrixF matView(true);
+      matView.setColumn(0, cross);
+      matView.setColumn(1, vLookatPt);
+      matView.setColumn(2, vUpVec);
+      matView.setPosition(VectorF(0.0f, 0.0f, 1.0f));
+      matView.inverse();
+
+      if (handle->isValid())
+         cbuf->set(handle, matView);
+      else
+         Con::errorf("CubemapSaver: Failed to set a shader constant handle.");
+   }
+
+   bool save(GFXCubemapHandle cubemap, const Torque::Path &path, GFXFormat compressionFormat)
+   {
+      if (!cubemap.isValid())
+      {
+         Con::errorf("CubemapSaver: cubemap handle is not valid");
+         return false;
+      }
+
+      // This can sometimes occur outside a begin/end scene.
+      const bool sceneBegun = GFX->canCurrentlyRender();
+      if (!sceneBegun)
+         GFX->beginScene();
+
+      GFXCubemap *pCubemap = cubemap.getPointer();
+      U32 faceSize = pCubemap->getSize();
+
+      ShaderData *shaderData = nullptr;
+      GFXShaderRef shader = Sim::findObject("CubemapSaveShader", shaderData) ? shaderData->getShader() : nullptr;
+      if (!shader)
+      {
+         Con::errorf("CubemapSaver::save - could not find CubemapSaveShader");
+         return false;
+      }
+
+      GFXShaderConstHandle *matHandles[CubeFaces];
+
+      matHandles[0] = shader->getShaderConstHandle("$matrix0");
+      matHandles[1] = shader->getShaderConstHandle("$matrix1");
+      matHandles[2] = shader->getShaderConstHandle("$matrix2");
+      matHandles[3] = shader->getShaderConstHandle("$matrix3");
+      matHandles[4] = shader->getShaderConstHandle("$matrix4");
+      matHandles[5] = shader->getShaderConstHandle("$matrix5");
+
+      GFXShaderConstBufferRef cbuffer = shader->allocConstBuffer();
+
+      GFXTextureTarget *pTarget = GFX->allocRenderToTextureTarget();
+      GFX->pushActiveRenderTarget();
+
+      GFXFormat renderTargetFmt = GFXFormatR8G8B8A8;
+      //setup render targets
+      GFXTexHandle pTextures[CubeFaces];
+      for (U32 i = 0; i < CubeFaces; i++)
+      {
+         pTextures[i].set(faceSize, faceSize, renderTargetFmt,
+            &GFXRenderTargetProfile, avar("%s() - (line %d)", __FUNCTION__, __LINE__),
+            1, GFXTextureManager::AA_MATCH_BACKBUFFER);
+
+         pTarget->attachTexture(GFXTextureTarget::RenderSlot(GFXTextureTarget::Color0 + i), pTextures[i]);
+      }
+
+      //create stateblock
+      GFXStateBlockDesc desc;
+      desc.setZReadWrite(false, false);
+      desc.samplersDefined = true;
+      desc.samplers[0].addressModeU = GFXAddressClamp;
+      desc.samplers[0].addressModeV = GFXAddressClamp;
+      desc.samplers[0].addressModeW = GFXAddressClamp;
+      desc.samplers[0].magFilter = GFXTextureFilterLinear;
+      desc.samplers[0].minFilter = GFXTextureFilterLinear;
+      desc.samplers[0].mipFilter = GFXTextureFilterLinear;
+
+      //yep funky order and rotations with t3d z up
+      _setConstBuffer(matHandles[0], cbuffer, VectorF(0.0f, 1.0f, 0.0f), VectorF(-1.0f, 0.0f, 0.0f));
+      _setConstBuffer(matHandles[1], cbuffer, VectorF(0.0f, 1.0f, 0.0f), VectorF(1.0f, 0.0f, 0.0f));
+      _setConstBuffer(matHandles[2], cbuffer, VectorF(0.0f, 1.0f, 0.0f), VectorF(0.0f, 0.0f, -1.0f));
+      _setConstBuffer(matHandles[3], cbuffer, VectorF(0.0f, 1.0f, 0.0f), VectorF(0.0f, 0.0f, 1.0f));
+      _setConstBuffer(matHandles[4], cbuffer, VectorF(0.0f, 0.0f, -1.0f), VectorF(0.0f, -1.0f, 0.0f));
+      _setConstBuffer(matHandles[5], cbuffer, VectorF(0.0f, 0.0f, 1.0f), VectorF(0.0f, 1.0f, 0.0f));
+
+      GFXTransformSaver saver;
+      GFX->setActiveRenderTarget(pTarget);
+      GFX->clear(GFXClearTarget, ColorI(0, 0, 0, 0), 1.0f, 0);
+      GFX->setStateBlockByDesc(desc);
+      GFX->setWorldMatrix(MatrixF::Identity);
+      GFX->setProjectionMatrix(MatrixF::Identity);
+      GFX->setCubeTexture(0, pCubemap);
+      GFX->setShaderConstBuffer(cbuffer);
+      GFX->setShader(shader);
+      GFX->drawPrimitive(GFXTriangleList, 0, 3);
+      pTarget->resolve();
+
+      GBitmap *pBitmaps[CubeFaces];
+      bool error = false;
+      const bool compressedFormat = ImageUtil::isCompressedFormat(compressionFormat);
+      for (U32 i = 0; i < CubeFaces; i++)
+      {
+         pBitmaps[i] = new GBitmap(faceSize, faceSize, false, renderTargetFmt);
+         bool result = pTextures[i].copyToBmp(pBitmaps[i]);
+         if (!result)
+         {
+            Con::errorf("CubemapSaver: cubemap number %u failed to copy", i);
+            error = true;
+         }
+         //gen mip maps
+         pBitmaps[i]->extrudeMipLevels();
+      }
+
+      if (!error)
+      {
+         DDSFile *pDds = DDSFile::createDDSCubemapFileFromGBitmaps(pBitmaps);
+         if (pDds)
+         {
+            // non compressed format needs swizzling
+            if (!compressedFormat)
+               ImageUtil::swizzleDDS(pDds, Swizzles::bgra);
+
+            if(compressedFormat)
+               ImageUtil::ddsCompress(pDds, compressionFormat);
+
+            FileStream  stream;
+            stream.open(path, Torque::FS::File::Write);
+
+            if (stream.getStatus() == Stream::Ok)
+               pDds->write(stream);
+            else
+               Con::errorf("CubemapSaver: failed to open file stream for file %s", path.getFullPath().c_str());
+
+            SAFE_DELETE(pDds);
+         }
+      }
+
+      for (U32 i = 0; i < CubeFaces; i++)
+         SAFE_DELETE(pBitmaps[i]);
+
+      //cleaup
+      GFX->popActiveRenderTarget();
+      GFX->setTexture(0, NULL);
+      GFX->setShader(NULL);
+      GFX->setShaderConstBuffer(NULL);
+      GFX->setVertexBuffer(NULL);
+
+      // End it if we begun it.
+      if (!sceneBegun)
+         GFX->endScene();
+
+
+      return true;
+   }
+
+   bool getBitmaps(GFXCubemapHandle cubemap, GFXFormat compressionFormat, GBitmap* faceBitmaps[6])
+   {
+      if (!cubemap.isValid())
+      {
+         Con::errorf("CubemapSaver: cubemap handle is not valid");
+         return false;
+      }
+
+      // This can sometimes occur outside a begin/end scene.
+      const bool sceneBegun = GFX->canCurrentlyRender();
+      if (!sceneBegun)
+         GFX->beginScene();
+
+      GFXCubemap *pCubemap = cubemap.getPointer();
+      U32 faceSize = pCubemap->getSize();
+
+      ShaderData *shaderData = nullptr;
+      GFXShaderRef shader = Sim::findObject("CubemapSaveShader", shaderData) ? shaderData->getShader() : nullptr;
+      if (!shader)
+      {
+         Con::errorf("CubemapSaver::save - could not find CubemapSaveShader");
+         return false;
+      }
+
+      GFXShaderConstHandle *matHandles[CubeFaces];
+
+      matHandles[0] = shader->getShaderConstHandle("$matrix0");
+      matHandles[1] = shader->getShaderConstHandle("$matrix1");
+      matHandles[2] = shader->getShaderConstHandle("$matrix2");
+      matHandles[3] = shader->getShaderConstHandle("$matrix3");
+      matHandles[4] = shader->getShaderConstHandle("$matrix4");
+      matHandles[5] = shader->getShaderConstHandle("$matrix5");
+
+      GFXShaderConstBufferRef cbuffer = shader->allocConstBuffer();
+
+      GFXTextureTarget *pTarget = GFX->allocRenderToTextureTarget();
+      GFX->pushActiveRenderTarget();
+
+      GFXFormat renderTargetFmt = GFXFormatR8G8B8A8;
+      //setup render targets
+      GFXTexHandle pTextures[CubeFaces];
+      for (U32 i = 0; i < CubeFaces; i++)
+      {
+         pTextures[i].set(faceSize, faceSize, renderTargetFmt,
+            &GFXRenderTargetProfile, avar("%s() - (line %d)", __FUNCTION__, __LINE__),
+            1, GFXTextureManager::AA_MATCH_BACKBUFFER);
+
+         pTarget->attachTexture(GFXTextureTarget::RenderSlot(GFXTextureTarget::Color0 + i), pTextures[i]);
+      }
+
+      //create stateblock
+      GFXStateBlockDesc desc;
+      desc.setZReadWrite(false, false);
+      desc.samplersDefined = true;
+      desc.samplers[0].addressModeU = GFXAddressClamp;
+      desc.samplers[0].addressModeV = GFXAddressClamp;
+      desc.samplers[0].addressModeW = GFXAddressClamp;
+      desc.samplers[0].magFilter = GFXTextureFilterLinear;
+      desc.samplers[0].minFilter = GFXTextureFilterLinear;
+      desc.samplers[0].mipFilter = GFXTextureFilterLinear;
+
+      //yep funky order and rotations with t3d z up
+      _setConstBuffer(matHandles[0], cbuffer, VectorF(0.0f, 1.0f, 0.0f), VectorF(-1.0f, 0.0f, 0.0f));
+      _setConstBuffer(matHandles[1], cbuffer, VectorF(0.0f, 1.0f, 0.0f), VectorF(1.0f, 0.0f, 0.0f));
+      _setConstBuffer(matHandles[2], cbuffer, VectorF(0.0f, 1.0f, 0.0f), VectorF(0.0f, 0.0f, -1.0f));
+      _setConstBuffer(matHandles[3], cbuffer, VectorF(0.0f, 1.0f, 0.0f), VectorF(0.0f, 0.0f, 1.0f));
+      _setConstBuffer(matHandles[4], cbuffer, VectorF(0.0f, 0.0f, -1.0f), VectorF(0.0f, -1.0f, 0.0f));
+      _setConstBuffer(matHandles[5], cbuffer, VectorF(0.0f, 0.0f, 1.0f), VectorF(0.0f, 1.0f, 0.0f));
+
+      GFXTransformSaver saver;
+      GFX->setActiveRenderTarget(pTarget);
+      GFX->clear(GFXClearTarget, ColorI(0, 0, 0, 0), 1.0f, 0);
+      GFX->setStateBlockByDesc(desc);
+      GFX->setWorldMatrix(MatrixF::Identity);
+      GFX->setProjectionMatrix(MatrixF::Identity);
+      GFX->setCubeTexture(0, pCubemap);
+      GFX->setShaderConstBuffer(cbuffer);
+      GFX->setShader(shader);
+      GFX->drawPrimitive(GFXTriangleList, 0, 3);
+      pTarget->resolve();
+
+      bool error = false;
+      const bool compressedFormat = ImageUtil::isCompressedFormat(compressionFormat);
+      for (U32 i = 0; i < CubeFaces; i++)
+      {
+         //faceBitmaps[i] = new GBitmap(faceSize, faceSize, false, renderTargetFmt);
+         bool result = pTextures[i].copyToBmp(faceBitmaps[i]);
+         if (!result)
+         {
+            Con::errorf("CubemapSaver: cubemap number %u failed to copy", i);
+            error = true;
+         }
+         //gen mip maps
+         faceBitmaps[i]->extrudeMipLevels();
+      }
+
+      /*if (!error)
+      {
+         DDSFile *pDds = DDSFile::createDDSCubemapFileFromGBitmaps(pBitmaps);
+         if (pDds)
+         {
+            // non compressed format needs swizzling
+            if (!compressedFormat)
+               ImageUtil::swizzleDDS(pDds, Swizzles::bgra);
+
+            if (compressedFormat)
+               ImageUtil::ddsCompress(pDds, compressionFormat);
+
+            FileStream  stream;
+            stream.open(path, Torque::FS::File::Write);
+
+            if (stream.getStatus() == Stream::Ok)
+               pDds->write(stream);
+            else
+               Con::errorf("CubemapSaver: failed to open file stream for file %s", path.getFullPath().c_str());
+
+            SAFE_DELETE(pDds);
+         }
+      }
+
+      for (U32 i = 0; i < CubeFaces; i++)
+         SAFE_DELETE(pBitmaps[i]);*/
+
+      //cleaup
+      GFX->popActiveRenderTarget();
+      GFX->setTexture(0, NULL);
+      GFX->setShader(NULL);
+      GFX->setShaderConstBuffer(NULL);
+      GFX->setVertexBuffer(NULL);
+
+      // End it if we begun it.
+      if (!sceneBegun)
+         GFX->endScene();
+
+      if (error)
+         return false;
+
+      return true;
+   }
+}

+ 41 - 0
Engine/source/gfx/bitmap/cubemapSaver.h

@@ -0,0 +1,41 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2016 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 _CUBEMAP_SAVER_H_
+#define _CUBEMAP_SAVER_H_
+
+#ifndef _GFXCUBEMAP_H_
+#include "gfx/gfxCubemap.h"
+#endif
+#ifndef __RESOURCE_H__
+#include "core/resource.h"
+#endif
+
+namespace CubemapSaver
+{
+   // save cubemap handle to a dds cubemap with optional compression
+   bool save(GFXCubemapHandle cubemap, const Torque::Path &path, GFXFormat compressionFormat = GFXFormat_FIRST);
+
+   bool getBitmaps(GFXCubemapHandle cubemap, GFXFormat compressionFormat, GBitmap* faceBitmaps[6]);
+};
+
+#endif

+ 10 - 1
Engine/source/gfx/bitmap/gBitmap.cpp

@@ -297,6 +297,7 @@ void GBitmap::allocateBitmap(const U32 in_width, const U32 in_height, const bool
      case GFXFormatR8G8B8X8:
      case GFXFormatR8G8B8X8:
      case GFXFormatR8G8B8A8:     mBytesPerPixel = 4;
      case GFXFormatR8G8B8A8:     mBytesPerPixel = 4;
       break;
       break;
+	 case GFXFormatL16:
      case GFXFormatR5G6B5:
      case GFXFormatR5G6B5:
      case GFXFormatR5G5B5A1:     mBytesPerPixel = 2;
      case GFXFormatR5G5B5A1:     mBytesPerPixel = 2;
       break;
       break;
@@ -371,6 +372,7 @@ void GBitmap::allocateBitmapWithMips(const U32 in_width, const U32 in_height, co
    case GFXFormatR8G8B8X8:
    case GFXFormatR8G8B8X8:
    case GFXFormatR8G8B8A8:     mBytesPerPixel = 4;
    case GFXFormatR8G8B8A8:     mBytesPerPixel = 4;
       break;
       break;
+   case GFXFormatL16:
    case GFXFormatR5G6B5:
    case GFXFormatR5G6B5:
    case GFXFormatR5G5B5A1:     mBytesPerPixel = 2;
    case GFXFormatR5G5B5A1:     mBytesPerPixel = 2;
       break;
       break;
@@ -679,6 +681,7 @@ bool GBitmap::checkForTransparency()
    {
    {
       // Non-transparent formats
       // Non-transparent formats
       case GFXFormatL8:
       case GFXFormatL8:
+	  case GFXFormatL16:
       case GFXFormatR8G8B8:
       case GFXFormatR8G8B8:
       case GFXFormatR5G6B5:
       case GFXFormatR5G6B5:
          break;
          break;
@@ -754,7 +757,8 @@ bool GBitmap::getColor(const U32 x, const U32 y, ColorI& rColor) const
      case GFXFormatL8:
      case GFXFormatL8:
       rColor.set( *pLoc, *pLoc, *pLoc, *pLoc );
       rColor.set( *pLoc, *pLoc, *pLoc, *pLoc );
       break;
       break;
-
+	 case GFXFormatL16:
+		 rColor.set(U8(U16((pLoc[0] << 8) + pLoc[2])), 0, 0, 0);
      case GFXFormatR8G8B8:
      case GFXFormatR8G8B8:
      case GFXFormatR8G8B8X8:
      case GFXFormatR8G8B8X8:
         rColor.set( pLoc[0], pLoc[1], pLoc[2], 255 );
         rColor.set( pLoc[0], pLoc[1], pLoc[2], 255 );
@@ -803,6 +807,10 @@ bool GBitmap::setColor(const U32 x, const U32 y, const ColorI& rColor)
       *pLoc = rColor.alpha;
       *pLoc = rColor.alpha;
       break;
       break;
 
 
+	 case GFXFormatL16:
+		 dMemcpy(pLoc, &rColor, 2 * sizeof(U8));
+		 break;
+
      case GFXFormatR8G8B8:
      case GFXFormatR8G8B8:
       dMemcpy( pLoc, &rColor, 3 * sizeof( U8 ) );
       dMemcpy( pLoc, &rColor, 3 * sizeof( U8 ) );
       break;
       break;
@@ -1122,6 +1130,7 @@ bool GBitmap::read(Stream& io_rStream)
       break;
       break;
      case GFXFormatR8G8B8A8:       mBytesPerPixel = 4;
      case GFXFormatR8G8B8A8:       mBytesPerPixel = 4;
       break;
       break;
+	 case GFXFormatL16:
      case GFXFormatR5G6B5:
      case GFXFormatR5G6B5:
      case GFXFormatR5G5B5A1:    mBytesPerPixel = 2;
      case GFXFormatR5G5B5A1:    mBytesPerPixel = 2;
       break;
       break;

+ 2 - 2
Engine/source/gfx/bitmap/loaders/bitmapPng.cpp

@@ -240,7 +240,7 @@ static bool sReadPNG(Stream &stream, GBitmap *bitmap)
       png_set_expand(png_ptr);
       png_set_expand(png_ptr);
 
 
       if (bit_depth == 16)
       if (bit_depth == 16)
-         format = GFXFormatR5G6B5;
+         format = GFXFormatL16;
       else
       else
          format = GFXFormatA8;
          format = GFXFormatA8;
    }
    }
@@ -276,7 +276,7 @@ static bool sReadPNG(Stream &stream, GBitmap *bitmap)
       AssertFatal(rowBytes == width * 4,
       AssertFatal(rowBytes == width * 4,
          "Error, our rowbytes are incorrect for this transform... (4)");
          "Error, our rowbytes are incorrect for this transform... (4)");
    }
    }
-   else if (format == GFXFormatR5G6B5) 
+   else if (format == GFXFormatL16)
    {
    {
       AssertFatal(rowBytes == width * 2,
       AssertFatal(rowBytes == width * 2,
          "Error, our rowbytes are incorrect for this transform... (2)");
          "Error, our rowbytes are incorrect for this transform... (2)");

+ 0 - 1
Engine/source/gfx/gfxDevice.h

@@ -809,7 +809,6 @@ public:
    virtual U32 getNumRenderTargets() const = 0;
    virtual U32 getNumRenderTargets() const = 0;
 
 
    virtual void setShader( GFXShader *shader, bool force = false ) {}
    virtual void setShader( GFXShader *shader, bool force = false ) {}
-   virtual void disableShaders( bool force = false ) {} // TODO Remove when T3D 4.0
 
 
    /// Set the buffer! (Actual set happens on the next draw call, just like textures, state blocks, etc)
    /// Set the buffer! (Actual set happens on the next draw call, just like textures, state blocks, etc)
    void setShaderConstBuffer(GFXShaderConstBuffer* buffer);
    void setShaderConstBuffer(GFXShaderConstBuffer* buffer);

+ 23 - 0
Engine/source/gfx/gfxTextureHandle.cpp

@@ -52,6 +52,11 @@ GFXTexHandle::GFXTexHandle( const String &texName, GFXTextureProfile *profile, c
    set( texName, profile, desc );
    set( texName, profile, desc );
 }
 }
 
 
+GFXTexHandle::GFXTexHandle(const String &texNameR, const String &texNameG, const String &texNameB, const String &texNameA, U32 inputKey[4], GFXTextureProfile *profile, const String &desc)
+{
+   set(texNameR, texNameG, texNameB, texNameA, inputKey, profile, desc);
+}
+
 bool GFXTexHandle::set( const String &texName, GFXTextureProfile *profile, const String &desc )
 bool GFXTexHandle::set( const String &texName, GFXTextureProfile *profile, const String &desc )
 {
 {
    // Clear the existing texture first, so that
    // Clear the existing texture first, so that
@@ -70,6 +75,24 @@ bool GFXTexHandle::set( const String &texName, GFXTextureProfile *profile, const
    return isValid();
    return isValid();
 }
 }
 
 
+bool GFXTexHandle::set(const String &texNameR, const String &texNameG, const String &texNameB, const String &texNameA, U32 inputKey[4], GFXTextureProfile *profile, const String &desc)
+{
+   // Clear the existing texture first, so that
+   // its memory is free for the new allocation.
+   free();
+   
+   // Create and set the new texture.
+   AssertFatal( texNameR.isNotEmpty(), "Texture name is empty" );
+   StrongObjectRef::set( TEXMGR->createCompositeTexture( texNameR, texNameG, texNameB, texNameA, inputKey, profile ) );
+   
+   #ifdef TORQUE_DEBUG
+      if ( getPointer() )
+         getPointer()->mDebugDescription = desc;
+   #endif
+   
+   return isValid();
+}
+
 GFXTexHandle::GFXTexHandle( GBitmap *bmp, GFXTextureProfile *profile, bool deleteBmp, const String &desc )
 GFXTexHandle::GFXTexHandle( GBitmap *bmp, GFXTextureProfile *profile, bool deleteBmp, const String &desc )
 {
 {
    set( bmp, profile, deleteBmp, desc );
    set( bmp, profile, deleteBmp, desc );

+ 4 - 0
Engine/source/gfx/gfxTextureHandle.h

@@ -46,6 +46,10 @@ public:
    GFXTexHandle( const String &texName, GFXTextureProfile *profile, const String &desc );
    GFXTexHandle( const String &texName, GFXTextureProfile *profile, const String &desc );
    bool set( const String &texName, GFXTextureProfile *profile, const String &desc );
    bool set( const String &texName, GFXTextureProfile *profile, const String &desc );
 
 
+   // load composite
+   GFXTexHandle(const String &texNameR, const String &texNameG, const String &texNameB, const String &texNameA, U32 inputKey[4], GFXTextureProfile *profile, const String &desc);
+   bool set( const String &texNameR, const String &texNameG, const String &texNameB, const String &texNameA, U32 inputKey[4], GFXTextureProfile *profile, const String &desc );
+
    // register texture
    // register texture
    GFXTexHandle( GBitmap *bmp, GFXTextureProfile *profile, bool deleteBmp, const String &desc );
    GFXTexHandle( GBitmap *bmp, GFXTextureProfile *profile, bool deleteBmp, const String &desc );
    bool set( GBitmap *bmp, GFXTextureProfile *profile, bool deleteBmp, const String &desc );
    bool set( GBitmap *bmp, GFXTextureProfile *profile, bool deleteBmp, const String &desc );

+ 9 - 5
Engine/source/gfx/gfxTextureManager.cpp

@@ -1122,7 +1122,8 @@ GFXTextureObject *GFXTextureManager::createCompositeTexture(GBitmap*bmp[4], U32
    }
    }
 
 
    U8 rChan, gChan, bChan, aChan;
    U8 rChan, gChan, bChan, aChan;
-   
+   GBitmap *outBitmap = new GBitmap();
+   outBitmap->allocateBitmap(bmp[0]->getWidth(), bmp[0]->getHeight(),false, GFXFormatR8G8B8A8);
    //pack additional bitmaps into the origional
    //pack additional bitmaps into the origional
    for (U32 x = 0; x < bmp[0]->getWidth(); x++)
    for (U32 x = 0; x < bmp[0]->getWidth(); x++)
    {
    {
@@ -1145,7 +1146,7 @@ GFXTextureObject *GFXTextureManager::createCompositeTexture(GBitmap*bmp[4], U32
          else
          else
             aChan = 255;
             aChan = 255;
 
 
-         bmp[0]->setColor(x, y, ColorI(rChan, gChan, bChan, aChan));
+		 outBitmap->setColor(x, y, ColorI(rChan, gChan, bChan, aChan));
       }
       }
    }
    }
 
 
@@ -1153,12 +1154,15 @@ GFXTextureObject *GFXTextureManager::createCompositeTexture(GBitmap*bmp[4], U32
    if (cacheHit != NULL)
    if (cacheHit != NULL)
    {
    {
       // Con::errorf("Cached texture '%s'", (resourceName.isNotEmpty() ? resourceName.c_str() : "unknown"));
       // Con::errorf("Cached texture '%s'", (resourceName.isNotEmpty() ? resourceName.c_str() : "unknown"));
-      if (deleteBmp)
-         delete bmp[0];
+	  if (deleteBmp)
+	  {
+		  delete outBitmap;
+		  delete[] bmp;
+	  }
       return cacheHit;
       return cacheHit;
    }
    }
 
 
-   return _createTexture(bmp[0], resourceName, profile, deleteBmp, NULL);
+   return _createTexture(outBitmap, resourceName, profile, deleteBmp, NULL);
 }
 }
 
 
 GFXTextureObject* GFXTextureManager::_findPooledTexure(  U32 width, 
 GFXTextureObject* GFXTextureManager::_findPooledTexure(  U32 width, 

+ 37 - 5
Engine/source/gfx/gl/gfxGLOcclusionQuery.cpp

@@ -25,7 +25,9 @@
 #include "gfx/gl/tGL/tGL.h"
 #include "gfx/gl/tGL/tGL.h"
 
 
 GFXGLOcclusionQuery::GFXGLOcclusionQuery(GFXDevice* device) : 
 GFXGLOcclusionQuery::GFXGLOcclusionQuery(GFXDevice* device) : 
-   GFXOcclusionQuery(device), mQuery(-1)
+   GFXOcclusionQuery(device), 
+   mQuery(-1), 
+   mTesting(false)
 {
 {
    
    
 }
 }
@@ -37,16 +39,29 @@ GFXGLOcclusionQuery::~GFXGLOcclusionQuery()
 
 
 bool GFXGLOcclusionQuery::begin()
 bool GFXGLOcclusionQuery::begin()
 {
 {
-   if(mQuery == -1)
+   if (GFXDevice::getDisableOcclusionQuery())
+      return true;
+
+   if (!glIsQuery(mQuery))
       glGenQueries(1, &mQuery);
       glGenQueries(1, &mQuery);
 
 
-   glBeginQuery(GL_SAMPLES_PASSED, mQuery);
+   if (!mTesting)
+   {
+      glBeginQuery(GL_SAMPLES_PASSED, mQuery);
+      mTesting = true;
+   }
    return true;
    return true;
 }
 }
 
 
 void GFXGLOcclusionQuery::end()
 void GFXGLOcclusionQuery::end()
 {
 {
+   if (GFXDevice::getDisableOcclusionQuery())
+      return;
+
+   if (!glIsQuery(mQuery))
+      return;
    glEndQuery(GL_SAMPLES_PASSED);
    glEndQuery(GL_SAMPLES_PASSED);
+   mTesting = false;
 }
 }
 
 
 GFXOcclusionQuery::OcclusionQueryStatus GFXGLOcclusionQuery::getStatus(bool block, U32* data)
 GFXOcclusionQuery::OcclusionQueryStatus GFXGLOcclusionQuery::getStatus(bool block, U32* data)
@@ -55,16 +70,33 @@ GFXOcclusionQuery::OcclusionQueryStatus GFXGLOcclusionQuery::getStatus(bool bloc
    // then your system is GPU bound.
    // then your system is GPU bound.
    PROFILE_SCOPE(GFXGLOcclusionQuery_getStatus);
    PROFILE_SCOPE(GFXGLOcclusionQuery_getStatus);
 
 
-   if(mQuery == -1)
+   if (GFXDevice::getDisableOcclusionQuery())
+      return NotOccluded;
+
+   if (!glIsQuery(mQuery))
       return NotOccluded;
       return NotOccluded;
    
    
    GLint numPixels = 0;
    GLint numPixels = 0;
    GLint queryDone = false;
    GLint queryDone = false;
    
    
    if (block)
    if (block)
-      queryDone = true;
+   {
+      while (!queryDone)
+      {
+         //If we're stalled out, proceed with worst-case scenario -BJR
+         if (GFX->mFrameTime->getElapsedMs()>4)
+         {
+            this->begin();
+            this->end();
+            return NotOccluded;
+         }
+         glGetQueryObjectiv(mQuery, GL_QUERY_RESULT_AVAILABLE, &queryDone);
+      }
+   }
    else
    else
+   {
       glGetQueryObjectiv(mQuery, GL_QUERY_RESULT_AVAILABLE, &queryDone);
       glGetQueryObjectiv(mQuery, GL_QUERY_RESULT_AVAILABLE, &queryDone);
+   }
    
    
    if (queryDone)
    if (queryDone)
       glGetQueryObjectiv(mQuery, GL_QUERY_RESULT, &numPixels);
       glGetQueryObjectiv(mQuery, GL_QUERY_RESULT, &numPixels);

+ 1 - 0
Engine/source/gfx/gl/gfxGLOcclusionQuery.h

@@ -44,6 +44,7 @@ public:
    
    
 private:
 private:
    U32 mQuery;
    U32 mQuery;
+   bool mTesting;
 };
 };
 
 
 #endif // _GFX_GL_OCCLUSIONQUERY_H_
 #endif // _GFX_GL_OCCLUSIONQUERY_H_

+ 16 - 0
Engine/source/gfx/sim/cubemapData.cpp

@@ -34,6 +34,7 @@
 #include "scene/sceneManager.h"
 #include "scene/sceneManager.h"
 #include "console/engineAPI.h"
 #include "console/engineAPI.h"
 #include "math/mathUtils.h"
 #include "math/mathUtils.h"
+#include "gfx/bitmap/cubemapSaver.h"
 
 
 IMPLEMENT_CONOBJECT( CubemapData );
 IMPLEMENT_CONOBJECT( CubemapData );
 
 
@@ -183,3 +184,18 @@ DefineEngineMethod( CubemapData, getFilename, const char*, (),,
 {
 {
    return object->getFilename();
    return object->getFilename();
 }
 }
+
+DefineEngineMethod(CubemapData, save, void, (const char* filename, const GFXFormat format), ("", GFXFormatBC1),
+	"Returns the script filename of where the CubemapData object was "
+	"defined.  This is used by the material editor.")
+{
+	if (filename == "")
+      filename = object->getName();
+
+   //add dds extension if needed
+   String finalName = String(filename);
+   if(!finalName.endsWith(".dds") || !finalName.endsWith(".DDS"))
+      finalName += String(".dds");
+
+   CubemapSaver::save(object->mCubemap, finalName, format);
+}

+ 1 - 1
Engine/source/gui/3d/guiTSControl.cpp

@@ -132,9 +132,9 @@ namespace
       desc.setCullMode(GFXCullNone);
       desc.setCullMode(GFXCullNone);
       desc.setZReadWrite(false);
       desc.setZReadWrite(false);
       desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
       desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
-      GFX->setStateBlockByDesc( desc );
 
 
       GFX->setupGenericShaders();
       GFX->setupGenericShaders();
+      GFX->setStateBlockByDesc( desc );      
       GFX->drawPrimitive( GFXTriangleStrip, 0, 2 );
       GFX->drawPrimitive( GFXTriangleStrip, 0, 2 );
    }
    }
 }
 }

+ 1 - 1
Engine/source/gui/core/guiCanvas.cpp

@@ -1830,7 +1830,7 @@ void GuiCanvas::renderFrame(bool preRenderOnly, bool bufferSwap /* = true */)
    if (GuiOffscreenCanvas::sList.size() != 0)
    if (GuiOffscreenCanvas::sList.size() != 0)
    {
    {
       // Reset the entire state since oculus shit will have barfed it.
       // Reset the entire state since oculus shit will have barfed it.
-      //GFX->disableShaders(true);
+
       GFX->updateStates(true);
       GFX->updateStates(true);
 
 
       for (Vector<GuiOffscreenCanvas*>::iterator itr = GuiOffscreenCanvas::sList.begin(); itr != GuiOffscreenCanvas::sList.end(); itr++)
       for (Vector<GuiOffscreenCanvas*>::iterator itr = GuiOffscreenCanvas::sList.begin(); itr != GuiOffscreenCanvas::sList.end(); itr++)

+ 4 - 6
Engine/source/lighting/advanced/advancedLightBinManager.cpp

@@ -41,8 +41,8 @@
 #include "math/util/matrixSet.h"
 #include "math/util/matrixSet.h"
 #include "console/consoleTypes.h"
 #include "console/consoleTypes.h"
 
 
-const RenderInstType AdvancedLightBinManager::RIT_LightInfo( "LightInfo" );
-const String AdvancedLightBinManager::smBufferName( "lightinfo" );
+const RenderInstType AdvancedLightBinManager::RIT_LightInfo( "directLighting" );
+const String AdvancedLightBinManager::smBufferName( "directLighting" );
 
 
 ShadowFilterMode AdvancedLightBinManager::smShadowFilterMode = ShadowFilterMode_SoftShadowHighQuality;
 ShadowFilterMode AdvancedLightBinManager::smShadowFilterMode = ShadowFilterMode_SoftShadowHighQuality;
 bool AdvancedLightBinManager::smPSSMDebugRender = false;
 bool AdvancedLightBinManager::smPSSMDebugRender = false;
@@ -130,7 +130,7 @@ AdvancedLightBinManager::AdvancedLightBinManager( AdvancedLightManager *lm /* =
    // We want a full-resolution buffer
    // We want a full-resolution buffer
    mTargetSizeType = RenderTexTargetBinManager::WindowSize;
    mTargetSizeType = RenderTexTargetBinManager::WindowSize;
 
 
-   mMRTLightmapsDuringDeferred = false;
+   mMRTLightmapsDuringDeferred = true;
 
 
    Con::NotifyDelegate callback( this, &AdvancedLightBinManager::_deleteLightMaterials );
    Con::NotifyDelegate callback( this, &AdvancedLightBinManager::_deleteLightMaterials );
    Con::addVariableNotify( "$pref::Shadows::filterMode", callback );
    Con::addVariableNotify( "$pref::Shadows::filterMode", callback );
@@ -252,9 +252,7 @@ void AdvancedLightBinManager::render( SceneRenderState *state )
    if ( !_onPreRender( state ) )
    if ( !_onPreRender( state ) )
       return;
       return;
 
 
-   // Clear as long as there isn't MRT population of light buffer with lightmap data
-   if ( !MRTLightmapsDuringDeferred() )
-      GFX->clear(GFXClearTarget, ColorI(0, 0, 0, 0), 1.0f, 0);
+   GFX->clear(GFXClearTarget, ColorI(0, 0, 0, 0), 1.0f, 0);
 
 
    // Restore transforms
    // Restore transforms
    MatrixSet &matrixSet = getRenderPass()->getMatrixSet();
    MatrixSet &matrixSet = getRenderPass()->getMatrixSet();

+ 47 - 47
Engine/source/lighting/advanced/glsl/advancedLightingFeaturesGLSL.cpp

@@ -36,7 +36,7 @@ void DeferredRTLightingFeatGLSL::processPixMacros( Vector<GFXShaderMacro> &macro
                                                    const MaterialFeatureData &fd  )
                                                    const MaterialFeatureData &fd  )
 {
 {
    // Skip deferred features, and use forward shading instead
    // Skip deferred features, and use forward shading instead
-   if ( fd.features[MFT_ForwardShading] )
+   if ( !fd.features[MFT_isDeferred] )
    {
    {
       Parent::processPixMacros( macros, fd );
       Parent::processPixMacros( macros, fd );
       return;
       return;
@@ -56,7 +56,7 @@ void DeferredRTLightingFeatGLSL::processVert(   Vector<ShaderComponent*> &compon
                                                 const MaterialFeatureData &fd )
                                                 const MaterialFeatureData &fd )
 {
 {
    // Skip deferred features, and use forward shading instead
    // Skip deferred features, and use forward shading instead
-   if ( fd.features[MFT_ForwardShading] )
+   if ( !fd.features[MFT_isDeferred] )
    {
    {
       Parent::processVert( componentList, fd );
       Parent::processVert( componentList, fd );
       return;
       return;
@@ -79,7 +79,7 @@ void DeferredRTLightingFeatGLSL::processPix( Vector<ShaderComponent*> &component
                                              const MaterialFeatureData &fd )
                                              const MaterialFeatureData &fd )
 {
 {
    // Skip deferred features, and use forward shading instead
    // Skip deferred features, and use forward shading instead
-   if ( fd.features[MFT_ForwardShading] )
+   if ( !fd.features[MFT_isDeferred] )
    {
    {
       Parent::processPix( componentList, fd );
       Parent::processPix( componentList, fd );
       return;
       return;
@@ -98,7 +98,7 @@ void DeferredRTLightingFeatGLSL::processPix( Vector<ShaderComponent*> &component
    uvScene->setName( "uvScene" );
    uvScene->setName( "uvScene" );
    LangElement *uvSceneDecl = new DecOp( uvScene );
    LangElement *uvSceneDecl = new DecOp( uvScene );
 
 
-   String rtParamName = String::ToString( "rtParams%s", "lightInfoBuffer" );
+   String rtParamName = String::ToString( "rtParams%s", "directLightingBuffer" );
    Var *rtParams = (Var*) LangElement::find( rtParamName );
    Var *rtParams = (Var*) LangElement::find( rtParamName );
    if( !rtParams )
    if( !rtParams )
    {
    {
@@ -121,7 +121,7 @@ void DeferredRTLightingFeatGLSL::processPix( Vector<ShaderComponent*> &component
    // create texture var
    // create texture var
    Var *lightInfoBuffer = new Var;
    Var *lightInfoBuffer = new Var;
    lightInfoBuffer->setType( "sampler2D" );
    lightInfoBuffer->setType( "sampler2D" );
-   lightInfoBuffer->setName( "lightInfoBuffer" );
+   lightInfoBuffer->setName( "directLightingBuffer" );
    lightInfoBuffer->uniform = true;
    lightInfoBuffer->uniform = true;
    lightInfoBuffer->sampler = true;
    lightInfoBuffer->sampler = true;
    lightInfoBuffer->constNum = Var::getTexUnitNum();     // used as texture unit num here
    lightInfoBuffer->constNum = Var::getTexUnitNum();     // used as texture unit num here
@@ -175,7 +175,7 @@ void DeferredRTLightingFeatGLSL::processPix( Vector<ShaderComponent*> &component
 ShaderFeature::Resources DeferredRTLightingFeatGLSL::getResources( const MaterialFeatureData &fd )
 ShaderFeature::Resources DeferredRTLightingFeatGLSL::getResources( const MaterialFeatureData &fd )
 {
 {
    // Skip deferred features, and use forward shading instead
    // Skip deferred features, and use forward shading instead
-   if ( fd.features[MFT_ForwardShading] )
+   if ( !fd.features[MFT_isDeferred] )
       return Parent::getResources( fd );
       return Parent::getResources( fd );
 
 
    // HACK: See DeferredRTLightingFeatGLSL::setTexData.
    // HACK: See DeferredRTLightingFeatGLSL::setTexData.
@@ -193,7 +193,7 @@ void DeferredRTLightingFeatGLSL::setTexData( Material::StageData &stageDat,
                                              U32 &texIndex )
                                              U32 &texIndex )
 {
 {
    // Skip deferred features, and use forward shading instead
    // Skip deferred features, and use forward shading instead
-   if ( fd.features[MFT_ForwardShading] )
+   if ( !fd.features[MFT_isDeferred] )
    {
    {
       Parent::setTexData( stageDat, fd, passData, texIndex );
       Parent::setTexData( stageDat, fd, passData, texIndex );
       return;
       return;
@@ -207,7 +207,7 @@ void DeferredRTLightingFeatGLSL::setTexData( Material::StageData &stageDat,
       mLastTexIndex = texIndex;
       mLastTexIndex = texIndex;
 
 
       passData.mTexType[ texIndex ] = Material::TexTarget;      
       passData.mTexType[ texIndex ] = Material::TexTarget;      
-      passData.mSamplerNames[ texIndex ]= "lightInfoBuffer";
+      passData.mSamplerNames[ texIndex ]= "directLightingBuffer";
       passData.mTexSlot[ texIndex++ ].texTarget = texTarget;
       passData.mTexSlot[ texIndex++ ].texTarget = texTarget;
    }
    }
 }
 }
@@ -227,7 +227,7 @@ void DeferredBumpFeatGLSL::processVert(   Vector<ShaderComponent*> &componentLis
 
 
       const bool useTexAnim = fd.features[MFT_TexAnim];
       const bool useTexAnim = fd.features[MFT_TexAnim];
       // Make sure there are texcoords
       // Make sure there are texcoords
-      if( !fd.features[MFT_Parallax] && !fd.features[MFT_DiffuseMap] )
+      if( !fd.features[MFT_Parallax] && !fd.features[MFT_DiffuseMap])
       {
       {
 
 
          getOutTexCoord(   "texCoord", 
          getOutTexCoord(   "texCoord", 
@@ -245,7 +245,7 @@ void DeferredBumpFeatGLSL::processVert(   Vector<ShaderComponent*> &componentLis
       output = meta;
       output = meta;
    }
    }
    else if (   fd.materialFeatures[MFT_NormalsOut] || 
    else if (   fd.materialFeatures[MFT_NormalsOut] || 
-               fd.features[MFT_ForwardShading] || 
+               !fd.features[MFT_isDeferred] || 
                !fd.features[MFT_RTLighting] )
                !fd.features[MFT_RTLighting] )
    {
    {
       Parent::processVert( componentList, fd );
       Parent::processVert( componentList, fd );
@@ -382,7 +382,7 @@ void DeferredBumpFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
       }
       }
    }
    }
    else if (   fd.materialFeatures[MFT_NormalsOut] || 
    else if (   fd.materialFeatures[MFT_NormalsOut] || 
-               fd.features[MFT_ForwardShading] || 
+               !fd.features[MFT_isDeferred] || 
                !fd.features[MFT_RTLighting] )
                !fd.features[MFT_RTLighting] )
    {
    {
       Parent::processPix( componentList, fd );
       Parent::processPix( componentList, fd );
@@ -413,7 +413,7 @@ void DeferredBumpFeatGLSL::processPix( Vector<ShaderComponent*> &componentList,
 ShaderFeature::Resources DeferredBumpFeatGLSL::getResources( const MaterialFeatureData &fd )
 ShaderFeature::Resources DeferredBumpFeatGLSL::getResources( const MaterialFeatureData &fd )
 {
 {
    if (  fd.materialFeatures[MFT_NormalsOut] || 
    if (  fd.materialFeatures[MFT_NormalsOut] || 
-         fd.features[MFT_ForwardShading] || 
+         !fd.features[MFT_isDeferred] || 
          fd.features[MFT_Parallax] ||
          fd.features[MFT_Parallax] ||
          !fd.features[MFT_RTLighting] )
          !fd.features[MFT_RTLighting] )
       return Parent::getResources( fd );
       return Parent::getResources( fd );
@@ -442,7 +442,7 @@ void DeferredBumpFeatGLSL::setTexData( Material::StageData &stageDat,
                                        U32 &texIndex )
                                        U32 &texIndex )
 {
 {
    if (  fd.materialFeatures[MFT_NormalsOut] || 
    if (  fd.materialFeatures[MFT_NormalsOut] || 
-         fd.features[MFT_ForwardShading] || 
+         !fd.features[MFT_isDeferred] || 
          !fd.features[MFT_RTLighting] )
          !fd.features[MFT_RTLighting] )
    {
    {
       Parent::setTexData( stageDat, fd, passData, texIndex );
       Parent::setTexData( stageDat, fd, passData, texIndex );
@@ -484,7 +484,7 @@ void DeferredBumpFeatGLSL::setTexData( Material::StageData &stageDat,
 void DeferredPixelSpecularGLSL::processVert( Vector<ShaderComponent*> &componentList, 
 void DeferredPixelSpecularGLSL::processVert( Vector<ShaderComponent*> &componentList, 
                                              const MaterialFeatureData &fd )
                                              const MaterialFeatureData &fd )
 {
 {
-   if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
+   if( !fd.features[MFT_isDeferred] || !fd.features[MFT_RTLighting] )
    {
    {
       Parent::processVert( componentList, fd );
       Parent::processVert( componentList, fd );
       return;
       return;
@@ -495,7 +495,7 @@ void DeferredPixelSpecularGLSL::processVert( Vector<ShaderComponent*> &component
 void DeferredPixelSpecularGLSL::processPix(  Vector<ShaderComponent*> &componentList, 
 void DeferredPixelSpecularGLSL::processPix(  Vector<ShaderComponent*> &componentList, 
                                              const MaterialFeatureData &fd )
                                              const MaterialFeatureData &fd )
 {
 {
-   if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
+   if( !fd.features[MFT_isDeferred] || !fd.features[MFT_RTLighting] )
    {
    {
       Parent::processPix( componentList, fd );
       Parent::processPix( componentList, fd );
       return;
       return;
@@ -518,26 +518,28 @@ void DeferredPixelSpecularGLSL::processPix(  Vector<ShaderComponent*> &component
       specCol->constSortPos = cspPotentialPrimitive;
       specCol->constSortPos = cspPotentialPrimitive;
    }
    }
 
 
-   Var *specPow = new Var;
-   specPow->setType( "float" );
-   specPow->setName( "specularPower" );
-
-   // If the gloss map flag is set, than the specular power is in the alpha
-   // channel of the specular map
-   if( fd.features[ MFT_GlossMap ] )
-      meta->addStatement( new GenOp( "   @ = @.a * 255;\r\n", new DecOp( specPow ), specCol ) );
-   else
+   Var *smoothness = (Var*)LangElement::find("smoothness");
+   if (!smoothness)
    {
    {
-      specPow->uniform = true;
-      specPow->constSortPos = cspPotentialPrimitive;
+      smoothness = new Var("smoothness", "float");
+
+      // If the gloss map flag is set, than the specular power is in the alpha
+      // channel of the specular map
+      if (fd.features[MFT_GlossMap])
+         meta->addStatement(new GenOp("   @ = @.a;\r\n", new DecOp(smoothness), specCol));
+      else
+      {
+         smoothness->uniform = true;
+         smoothness->constSortPos = cspPotentialPrimitive;
+      }
    }
    }
 
 
-   Var *specStrength = (Var*)LangElement::find( "specularStrength" );
-   if (!specStrength)
+   Var *metalness = (Var*)LangElement::find("metalness");
+   if (!metalness)
    {
    {
-       specStrength = new Var( "specularStrength", "float" );
-       specStrength->uniform = true;
-       specStrength->constSortPos = cspPotentialPrimitive;
+       metalness = new Var("metalness", "float");
+       metalness->uniform = true;
+       metalness->constSortPos = cspPotentialPrimitive;
    }
    }
 
 
    Var *lightInfoSamp = (Var *)LangElement::find( "lightInfoSample" );
    Var *lightInfoSamp = (Var *)LangElement::find( "lightInfoSample" );
@@ -557,7 +559,7 @@ void DeferredPixelSpecularGLSL::processPix(  Vector<ShaderComponent*> &component
    }
    }
    // (a^m)^n = a^(m*n)
    // (a^m)^n = a^(m*n)
    		meta->addStatement( new GenOp( "   @ = pow( abs(@), max((@ / AL_ConstantSpecularPower),1.0f)) * @;\r\n", 
    		meta->addStatement( new GenOp( "   @ = pow( abs(@), max((@ / AL_ConstantSpecularPower),1.0f)) * @;\r\n", 
-      specDecl, d_specular, specPow, specStrength ) );
+            specDecl, d_specular, smoothness, metalness));
 
 
    LangElement *specMul = new GenOp( "vec4( @.rgb, 0 ) * @", specCol, specular );
    LangElement *specMul = new GenOp( "vec4( @.rgb, 0 ) * @", specCol, specular );
    LangElement *final = specMul;
    LangElement *final = specMul;
@@ -577,7 +579,7 @@ void DeferredPixelSpecularGLSL::processPix(  Vector<ShaderComponent*> &component
 
 
 ShaderFeature::Resources DeferredPixelSpecularGLSL::getResources( const MaterialFeatureData &fd )
 ShaderFeature::Resources DeferredPixelSpecularGLSL::getResources( const MaterialFeatureData &fd )
 {
 {
-   if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
+   if( !fd.features[MFT_isDeferred] || !fd.features[MFT_RTLighting] )
       return Parent::getResources( fd );
       return Parent::getResources( fd );
 
 
    Resources res; 
    Resources res; 
@@ -588,7 +590,7 @@ ShaderFeature::Resources DeferredPixelSpecularGLSL::getResources( const Material
 ShaderFeature::Resources DeferredMinnaertGLSL::getResources( const MaterialFeatureData &fd )
 ShaderFeature::Resources DeferredMinnaertGLSL::getResources( const MaterialFeatureData &fd )
 {
 {
    Resources res;
    Resources res;
-   if( !fd.features[MFT_ForwardShading] && fd.features[MFT_RTLighting] )
+   if( fd.features[MFT_isDeferred] && fd.features[MFT_RTLighting] )
    {
    {
       res.numTex = 1;
       res.numTex = 1;
       res.numTexReg = 1;
       res.numTexReg = 1;
@@ -601,7 +603,7 @@ void DeferredMinnaertGLSL::setTexData( Material::StageData &stageDat,
                                        RenderPassData &passData, 
                                        RenderPassData &passData, 
                                        U32 &texIndex )
                                        U32 &texIndex )
 {
 {
-   if( !fd.features[MFT_ForwardShading] && fd.features[MFT_RTLighting] )
+   if( fd.features[MFT_isDeferred] && fd.features[MFT_RTLighting] )
    {
    {
       NamedTexTarget *texTarget = NamedTexTarget::find(RenderDeferredMgr::BufferName);
       NamedTexTarget *texTarget = NamedTexTarget::find(RenderDeferredMgr::BufferName);
       if ( texTarget )
       if ( texTarget )
@@ -616,7 +618,7 @@ void DeferredMinnaertGLSL::setTexData( Material::StageData &stageDat,
 void DeferredMinnaertGLSL::processPixMacros( Vector<GFXShaderMacro> &macros, 
 void DeferredMinnaertGLSL::processPixMacros( Vector<GFXShaderMacro> &macros, 
                                              const MaterialFeatureData &fd  )
                                              const MaterialFeatureData &fd  )
 {
 {
-   if( !fd.features[MFT_ForwardShading] && fd.features[MFT_RTLighting] )
+   if( fd.features[MFT_isDeferred] && fd.features[MFT_RTLighting] )
    {
    {
       // Pull in the uncondition method for the g buffer
       // Pull in the uncondition method for the g buffer
       NamedTexTarget *texTarget = NamedTexTarget::find( RenderDeferredMgr::BufferName );
       NamedTexTarget *texTarget = NamedTexTarget::find( RenderDeferredMgr::BufferName );
@@ -633,7 +635,7 @@ void DeferredMinnaertGLSL::processVert(   Vector<ShaderComponent*> &componentLis
                                           const MaterialFeatureData &fd )
                                           const MaterialFeatureData &fd )
 {
 {
    // If there is no deferred information, bail on this feature
    // If there is no deferred information, bail on this feature
-   if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
+   if( !fd.features[MFT_isDeferred] || !fd.features[MFT_RTLighting] )
    {
    {
       output = NULL;
       output = NULL;
       return;
       return;
@@ -650,7 +652,7 @@ void DeferredMinnaertGLSL::processPix( Vector<ShaderComponent*> &componentList,
                                        const MaterialFeatureData &fd )
                                        const MaterialFeatureData &fd )
 {
 {
    // If there is no deferred information, bail on this feature
    // If there is no deferred information, bail on this feature
-   if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
+   if( !fd.features[MFT_isDeferred] || !fd.features[MFT_RTLighting] )
    {
    {
       output = NULL;
       output = NULL;
       return;
       return;
@@ -695,12 +697,6 @@ void DeferredMinnaertGLSL::processPix( Vector<ShaderComponent*> &componentList,
 void DeferredSubSurfaceGLSL::processPix(  Vector<ShaderComponent*> &componentList, 
 void DeferredSubSurfaceGLSL::processPix(  Vector<ShaderComponent*> &componentList, 
                                           const MaterialFeatureData &fd )
                                           const MaterialFeatureData &fd )
 {
 {
-   // If there is no deferred information, bail on this feature
-   if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
-   {
-      output = NULL;
-      return;
-   }
 
 
    Var *subSurfaceParams = new Var;
    Var *subSurfaceParams = new Var;
    subSurfaceParams->setType( "vec4" );
    subSurfaceParams->setType( "vec4" );
@@ -712,9 +708,13 @@ void DeferredSubSurfaceGLSL::processPix(  Vector<ShaderComponent*> &componentLis
    Var *d_NL_Att = (Var*)LangElement::find( "d_NL_Att" );
    Var *d_NL_Att = (Var*)LangElement::find( "d_NL_Att" );
 
 
    MultiLine *meta = new MultiLine;
    MultiLine *meta = new MultiLine;
-   meta->addStatement( new GenOp( "   float subLamb = smoothstep([email protected], 1.0, @) - smoothstep(0.0, 1.0, @);\r\n", subSurfaceParams, d_NL_Att, d_NL_Att ) );
-   meta->addStatement( new GenOp( "   subLamb = max(0.0, subLamb);\r\n" ) );
-   meta->addStatement( new GenOp( "   @;\r\n", assignColor( new GenOp( "vec4(@ + (subLamb * @.rgb), 1.0)", d_lightcolor, subSurfaceParams ), Material::Mul ) ) );
+   if (fd.features[MFT_isDeferred])
+   {
+      Var* targ = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget3));
+      meta->addStatement(new GenOp("   @.rgb += @.rgb*@.a;\r\n", targ, subSurfaceParams, subSurfaceParams));
+      output = meta;
+      return;
+   }
 
 
    output = meta;
    output = meta;
 }
 }

+ 31 - 41
Engine/source/lighting/advanced/glsl/deferredShadingFeaturesGLSL.cpp

@@ -62,10 +62,24 @@ void DeferredSpecMapGLSL::processPix( Vector<ShaderComponent*> &componentList, c
    specularMap->uniform = true;
    specularMap->uniform = true;
    specularMap->sampler = true;
    specularMap->sampler = true;
    specularMap->constNum = Var::getTexUnitNum();
    specularMap->constNum = Var::getTexUnitNum();
-   //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));
+   LangElement *texOp = new GenOp( "tex2D(@, @)", specularMap, texCoord );
+
+   Var *specularColor = (Var*)LangElement::find("specularColor");
+   if (!specularColor) specularColor = new Var("specularColor", "vec4");
+   Var *metalness = (Var*)LangElement::find("metalness");
+   if (!metalness) metalness = new Var("metalness", "float");
+   Var *smoothness = (Var*)LangElement::find("smoothness");
+   if (!smoothness) smoothness = new Var("smoothness", "float");
+
+   meta->addStatement(new GenOp("   @ = @.r;\r\n", new DecOp(smoothness), texOp));
+      meta->addStatement(new GenOp("   @ = @.b;\r\n", new DecOp(metalness), texOp));
+
+   if (fd.features[MFT_InvertSmoothness])
+      meta->addStatement(new GenOp("   @ = 1.0-@;\r\n", smoothness, smoothness));
+
+   meta->addStatement(new GenOp("   @ = @.ggga;\r\n", new DecOp(specularColor), texOp));
+
+   meta->addStatement(new GenOp("   @.bga = vec3(@,@.g,@);\r\n", material, smoothness, specularColor, metalness));
    output = meta;
    output = meta;
 }
 }
 
 
@@ -145,44 +159,20 @@ void DeferredSpecVarsGLSL::processPix( Vector<ShaderComponent*> &componentList,
       material->setName( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
       material->setName( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
       material->setStructName("OUT");
       material->setStructName("OUT");
    }
    }
+   
+   Var *metalness = new Var("metalness", "float");
+   metalness->uniform = true;
+   metalness->constSortPos = cspPotentialPrimitive;
 
 
-   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;
+   Var *smoothness = new Var("smoothness", "float");
+   smoothness->uniform = true;
+   smoothness->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("   @.a = @/128;\r\n", material, specPower));
-   meta->addStatement(new GenOp("   @.b = @/5;\r\n", material, specStrength));
-   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));
+	MultiLine *meta = new MultiLine;
+    meta->addStatement(new GenOp("   @.g = 1.0;\r\n", material));
+    meta->addStatement(new GenOp("   @.b = @;\r\n", material, smoothness));
+    if (fd.features[MFT_InvertSmoothness])
+       meta->addStatement(new GenOp("   @ = 1.0-@;\r\n", smoothness, smoothness));
+    meta->addStatement(new GenOp("   @.a = @;\r\n", material, metalness));
    output = meta;
    output = meta;
 }
 }

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

@@ -70,16 +70,4 @@ public:
    virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const { return ShaderFeature::RenderTarget2; }
    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
 #endif

+ 63 - 62
Engine/source/lighting/advanced/hlsl/advancedLightingFeaturesHLSL.cpp

@@ -36,7 +36,7 @@ void DeferredRTLightingFeatHLSL::processPixMacros( Vector<GFXShaderMacro> &macro
                                                    const MaterialFeatureData &fd  )
                                                    const MaterialFeatureData &fd  )
 {
 {
    // Skip deferred features, and use forward shading instead
    // Skip deferred features, and use forward shading instead
-   if ( fd.features[MFT_ForwardShading] )
+   if ( !fd.features[MFT_isDeferred] )
    {
    {
       Parent::processPixMacros( macros, fd );
       Parent::processPixMacros( macros, fd );
       return;
       return;
@@ -56,7 +56,7 @@ void DeferredRTLightingFeatHLSL::processVert(   Vector<ShaderComponent*> &compon
                                                 const MaterialFeatureData &fd )
                                                 const MaterialFeatureData &fd )
 {
 {
    // Skip deferred features, and use forward shading instead
    // Skip deferred features, and use forward shading instead
-   if ( fd.features[MFT_ForwardShading] )
+   if ( !fd.features[MFT_isDeferred] )
    {
    {
       Parent::processVert( componentList, fd );
       Parent::processVert( componentList, fd );
       return;
       return;
@@ -79,32 +79,33 @@ void DeferredRTLightingFeatHLSL::processPix( Vector<ShaderComponent*> &component
                                              const MaterialFeatureData &fd )
                                              const MaterialFeatureData &fd )
 {
 {
    // Skip deferred features, and use forward shading instead
    // Skip deferred features, and use forward shading instead
-   if ( fd.features[MFT_ForwardShading] )
+
+   if ( !fd.features[MFT_isDeferred] )
    {
    {
-      Parent::processPix( componentList, fd );
+      Parent::processPix(componentList, fd);
       return;
       return;
    }
    }
 
 
    MultiLine *meta = new MultiLine;
    MultiLine *meta = new MultiLine;
 
 
-   ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] );
-   Var *ssPos = connectComp->getElement( RT_TEXCOORD );
-   ssPos->setName( "screenspacePos" );
-   ssPos->setStructName( "IN" );
-   ssPos->setType( "float4" );
+   ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>(componentList[C_CONNECTOR]);
+   Var *ssPos = connectComp->getElement(RT_TEXCOORD);
+   ssPos->setName("screenspacePos");
+   ssPos->setStructName("IN");
+   ssPos->setType("float4");
 
 
    Var *uvScene = new Var;
    Var *uvScene = new Var;
-   uvScene->setType( "float2" );
-   uvScene->setName( "uvScene" );
-   LangElement *uvSceneDecl = new DecOp( uvScene );
+   uvScene->setType("float2");
+   uvScene->setName("uvScene");
+   LangElement *uvSceneDecl = new DecOp(uvScene);
 
 
-   String rtParamName = String::ToString( "rtParams%s", "lightInfoBuffer" );
-   Var *rtParams = (Var*) LangElement::find( rtParamName );
-   if( !rtParams )
+   String rtParamName = String::ToString("rtParams%s", "directLightingBuffer");
+   Var *rtParams = (Var*)LangElement::find(rtParamName);
+   if (!rtParams)
    {
    {
       rtParams = new Var;
       rtParams = new Var;
-      rtParams->setType( "float4" );
-      rtParams->setName( rtParamName );
+      rtParams->setType("float4");
+      rtParams->setName(rtParamName);
       rtParams->uniform = true;
       rtParams->uniform = true;
       rtParams->constSortPos = cspPass;
       rtParams->constSortPos = cspPass;
    }
    }
@@ -182,7 +183,7 @@ void DeferredRTLightingFeatHLSL::processPix( Vector<ShaderComponent*> &component
 ShaderFeature::Resources DeferredRTLightingFeatHLSL::getResources( const MaterialFeatureData &fd )
 ShaderFeature::Resources DeferredRTLightingFeatHLSL::getResources( const MaterialFeatureData &fd )
 {
 {
    // Skip deferred features, and use forward shading instead
    // Skip deferred features, and use forward shading instead
-   if ( fd.features[MFT_ForwardShading] )
+   if ( !fd.features[MFT_isDeferred] )
       return Parent::getResources( fd );
       return Parent::getResources( fd );
 
 
    // HACK: See DeferredRTLightingFeatHLSL::setTexData.
    // HACK: See DeferredRTLightingFeatHLSL::setTexData.
@@ -200,7 +201,7 @@ void DeferredRTLightingFeatHLSL::setTexData( Material::StageData &stageDat,
                                              U32 &texIndex )
                                              U32 &texIndex )
 {
 {
    // Skip deferred features, and use forward shading instead
    // Skip deferred features, and use forward shading instead
-   if ( fd.features[MFT_ForwardShading] )
+   if ( !fd.features[MFT_isDeferred] )
    {
    {
       Parent::setTexData( stageDat, fd, passData, texIndex );
       Parent::setTexData( stageDat, fd, passData, texIndex );
       return;
       return;
@@ -214,7 +215,7 @@ void DeferredRTLightingFeatHLSL::setTexData( Material::StageData &stageDat,
       mLastTexIndex = texIndex;
       mLastTexIndex = texIndex;
 
 
       passData.mTexType[ texIndex ] = Material::TexTarget;
       passData.mTexType[ texIndex ] = Material::TexTarget;
-      passData.mSamplerNames[ texIndex ]= "lightInfoBuffer";
+      passData.mSamplerNames[ texIndex ]= "directLightingBuffer";
       passData.mTexSlot[ texIndex++ ].texTarget = texTarget;
       passData.mTexSlot[ texIndex++ ].texTarget = texTarget;
    }
    }
 }
 }
@@ -252,7 +253,7 @@ void DeferredBumpFeatHLSL::processVert(   Vector<ShaderComponent*> &componentLis
       output = meta;
       output = meta;
    }
    }
    else if (   fd.materialFeatures[MFT_NormalsOut] || 
    else if (   fd.materialFeatures[MFT_NormalsOut] || 
-               fd.features[MFT_ForwardShading] || 
+               !fd.features[MFT_isDeferred] || 
                !fd.features[MFT_RTLighting] )
                !fd.features[MFT_RTLighting] )
    {
    {
       Parent::processVert( componentList, fd );
       Parent::processVert( componentList, fd );
@@ -412,7 +413,7 @@ void DeferredBumpFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
       }
       }
    } 
    } 
    else if (   fd.materialFeatures[MFT_NormalsOut] || 
    else if (   fd.materialFeatures[MFT_NormalsOut] || 
-               fd.features[MFT_ForwardShading] || 
+               !fd.features[MFT_isDeferred] || 
                !fd.features[MFT_RTLighting] )
                !fd.features[MFT_RTLighting] )
    {
    {
       Parent::processPix( componentList, fd );
       Parent::processPix( componentList, fd );
@@ -426,13 +427,13 @@ void DeferredBumpFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
          Var *texCoord = getInTexCoord( "texCoord", "float2", componentList );
          Var *texCoord = getInTexCoord( "texCoord", "float2", componentList );
 
 
          Var *bumpMap = getNormalMapTex();
          Var *bumpMap = getNormalMapTex();
+         Var *bumpMapTex = (Var *)LangElement::find("bumpMapTex");
 
 
          bumpSample = new Var;
          bumpSample = new Var;
-         bumpSample->setType( "float4" );
-         bumpSample->setName( "bumpSample" );
-         LangElement *bumpSampleDecl = new DecOp( bumpSample );
+         bumpSample->setType("float4");
+         bumpSample->setName("bumpSample");
 
 
-         Var *bumpMapTex = (Var *)LangElement::find("bumpMapTex");
+         LangElement *bumpSampleDecl = new DecOp(bumpSample);
          output = new GenOp("   @ = @.Sample(@, @);\r\n", bumpSampleDecl, bumpMapTex, bumpMap, texCoord);
          output = new GenOp("   @ = @.Sample(@, @);\r\n", bumpSampleDecl, bumpMapTex, bumpMap, texCoord);
 
 
          return;
          return;
@@ -445,7 +446,7 @@ void DeferredBumpFeatHLSL::processPix( Vector<ShaderComponent*> &componentList,
 ShaderFeature::Resources DeferredBumpFeatHLSL::getResources( const MaterialFeatureData &fd )
 ShaderFeature::Resources DeferredBumpFeatHLSL::getResources( const MaterialFeatureData &fd )
 {
 {
    if (  fd.materialFeatures[MFT_NormalsOut] || 
    if (  fd.materialFeatures[MFT_NormalsOut] || 
-         fd.features[MFT_ForwardShading] || 
+         !fd.features[MFT_isDeferred] || 
          fd.features[MFT_Parallax] ||
          fd.features[MFT_Parallax] ||
          !fd.features[MFT_RTLighting] )
          !fd.features[MFT_RTLighting] )
       return Parent::getResources( fd );
       return Parent::getResources( fd );
@@ -474,7 +475,7 @@ void DeferredBumpFeatHLSL::setTexData( Material::StageData &stageDat,
                                        U32 &texIndex )
                                        U32 &texIndex )
 {
 {
    if (  fd.materialFeatures[MFT_NormalsOut] || 
    if (  fd.materialFeatures[MFT_NormalsOut] || 
-         fd.features[MFT_ForwardShading] || 
+         !fd.features[MFT_isDeferred] || 
          !fd.features[MFT_RTLighting] )
          !fd.features[MFT_RTLighting] )
    {
    {
       Parent::setTexData( stageDat, fd, passData, texIndex );
       Parent::setTexData( stageDat, fd, passData, texIndex );
@@ -516,7 +517,7 @@ void DeferredBumpFeatHLSL::setTexData( Material::StageData &stageDat,
 void DeferredPixelSpecularHLSL::processVert( Vector<ShaderComponent*> &componentList, 
 void DeferredPixelSpecularHLSL::processVert( Vector<ShaderComponent*> &componentList, 
                                              const MaterialFeatureData &fd )
                                              const MaterialFeatureData &fd )
 {
 {
-   if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
+   if( !fd.features[MFT_isDeferred] || !fd.features[MFT_RTLighting] )
    {
    {
       Parent::processVert( componentList, fd );
       Parent::processVert( componentList, fd );
       return;
       return;
@@ -527,7 +528,7 @@ void DeferredPixelSpecularHLSL::processVert( Vector<ShaderComponent*> &component
 void DeferredPixelSpecularHLSL::processPix(  Vector<ShaderComponent*> &componentList, 
 void DeferredPixelSpecularHLSL::processPix(  Vector<ShaderComponent*> &componentList, 
                                              const MaterialFeatureData &fd )
                                              const MaterialFeatureData &fd )
 {
 {
-   if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
+   if( !fd.features[MFT_isDeferred] || !fd.features[MFT_RTLighting] )
    {
    {
       Parent::processPix( componentList, fd );
       Parent::processPix( componentList, fd );
       return;
       return;
@@ -550,26 +551,28 @@ void DeferredPixelSpecularHLSL::processPix(  Vector<ShaderComponent*> &component
       specCol->constSortPos = cspPotentialPrimitive;
       specCol->constSortPos = cspPotentialPrimitive;
    }
    }
 
 
-   Var *specPow = new Var;
-   specPow->setType( "float" );
-   specPow->setName( "specularPower" );
-
-   // If the gloss map flag is set, than the specular power is in the alpha
-   // channel of the specular map
-   if( fd.features[ MFT_GlossMap ] )
-      meta->addStatement( new GenOp( "   @ = @.a * 255;\r\n", new DecOp( specPow ), specCol ) );
-   else
+   Var *smoothness = (Var*)LangElement::find("smoothness");
+   if (!smoothness)
    {
    {
-      specPow->uniform = true;
-      specPow->constSortPos = cspPotentialPrimitive;
+      smoothness = new Var("smoothness", "float");
+
+      // If the gloss map flag is set, than the specular power is in the alpha
+      // channel of the specular map
+      if (fd.features[MFT_GlossMap])
+         meta->addStatement(new GenOp("   @ = @.a;\r\n", new DecOp(smoothness), specCol));
+      else
+      {
+         smoothness->uniform = true;
+         smoothness->constSortPos = cspPotentialPrimitive;
+      }
    }
    }
 
 
-   Var *specStrength = (Var*)LangElement::find( "specularStrength" );
-   if (!specStrength)
+   Var *metalness = (Var*)LangElement::find("metalness");
+   if (!metalness)
    {
    {
-       specStrength = new Var( "specularStrength", "float" );
-       specStrength->uniform = true;
-       specStrength->constSortPos = cspPotentialPrimitive;
+       metalness = new Var("metalness", "float");
+       metalness->uniform = true;
+       metalness->constSortPos = cspPotentialPrimitive;
    }
    }
 
 
    Var *lightInfoSamp = (Var *)LangElement::find( "lightInfoSample" );
    Var *lightInfoSamp = (Var *)LangElement::find( "lightInfoSample" );
@@ -591,7 +594,7 @@ void DeferredPixelSpecularHLSL::processPix(  Vector<ShaderComponent*> &component
 	  
 	  
    // (a^m)^n = a^(m*n)
    // (a^m)^n = a^(m*n)
    meta->addStatement( new GenOp( "   @ = pow( abs(@), max((@ / AL_ConstantSpecularPower),1.0f)) * @;\r\n", 
    meta->addStatement( new GenOp( "   @ = pow( abs(@), max((@ / AL_ConstantSpecularPower),1.0f)) * @;\r\n", 
-		   specDecl, d_specular, specPow, specStrength));
+       specDecl, d_specular, smoothness, metalness));
 
 
    LangElement *specMul = new GenOp( "float4( @.rgb, 0 ) * @", specCol, specular );
    LangElement *specMul = new GenOp( "float4( @.rgb, 0 ) * @", specCol, specular );
    LangElement *final = specMul;
    LangElement *final = specMul;
@@ -611,7 +614,7 @@ void DeferredPixelSpecularHLSL::processPix(  Vector<ShaderComponent*> &component
 
 
 ShaderFeature::Resources DeferredPixelSpecularHLSL::getResources( const MaterialFeatureData &fd )
 ShaderFeature::Resources DeferredPixelSpecularHLSL::getResources( const MaterialFeatureData &fd )
 {
 {
-   if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
+   if( !fd.features[MFT_isDeferred] || !fd.features[MFT_RTLighting] )
       return Parent::getResources( fd );
       return Parent::getResources( fd );
 
 
    Resources res; 
    Resources res; 
@@ -622,7 +625,7 @@ ShaderFeature::Resources DeferredPixelSpecularHLSL::getResources( const Material
 ShaderFeature::Resources DeferredMinnaertHLSL::getResources( const MaterialFeatureData &fd )
 ShaderFeature::Resources DeferredMinnaertHLSL::getResources( const MaterialFeatureData &fd )
 {
 {
    Resources res;
    Resources res;
-   if( !fd.features[MFT_ForwardShading] && fd.features[MFT_RTLighting] )
+   if( fd.features[MFT_isDeferred] && fd.features[MFT_RTLighting] )
    {
    {
       res.numTex = 1;
       res.numTex = 1;
       res.numTexReg = 1;
       res.numTexReg = 1;
@@ -635,7 +638,7 @@ void DeferredMinnaertHLSL::setTexData( Material::StageData &stageDat,
                                        RenderPassData &passData, 
                                        RenderPassData &passData, 
                                        U32 &texIndex )
                                        U32 &texIndex )
 {
 {
-   if( !fd.features[MFT_ForwardShading] && fd.features[MFT_RTLighting] )
+   if( fd.features[MFT_isDeferred] && fd.features[MFT_RTLighting] )
    {
    {
       NamedTexTarget *texTarget = NamedTexTarget::find(RenderDeferredMgr::BufferName);
       NamedTexTarget *texTarget = NamedTexTarget::find(RenderDeferredMgr::BufferName);
       if ( texTarget )
       if ( texTarget )
@@ -650,7 +653,7 @@ void DeferredMinnaertHLSL::setTexData( Material::StageData &stageDat,
 void DeferredMinnaertHLSL::processPixMacros( Vector<GFXShaderMacro> &macros, 
 void DeferredMinnaertHLSL::processPixMacros( Vector<GFXShaderMacro> &macros, 
                                              const MaterialFeatureData &fd  )
                                              const MaterialFeatureData &fd  )
 {
 {
-   if( !fd.features[MFT_ForwardShading] && fd.features[MFT_RTLighting] )
+   if( fd.features[MFT_isDeferred] && fd.features[MFT_RTLighting] )
    {
    {
       // Pull in the uncondition method for the g buffer
       // Pull in the uncondition method for the g buffer
       NamedTexTarget *texTarget = NamedTexTarget::find( RenderDeferredMgr::BufferName );
       NamedTexTarget *texTarget = NamedTexTarget::find( RenderDeferredMgr::BufferName );
@@ -667,7 +670,7 @@ void DeferredMinnaertHLSL::processVert(   Vector<ShaderComponent*> &componentLis
                                           const MaterialFeatureData &fd )
                                           const MaterialFeatureData &fd )
 {
 {
    // If there is no deferred information, bail on this feature
    // If there is no deferred information, bail on this feature
-   if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
+   if( !fd.features[MFT_isDeferred] || !fd.features[MFT_RTLighting] )
    {
    {
       output = NULL;
       output = NULL;
       return;
       return;
@@ -684,7 +687,7 @@ void DeferredMinnaertHLSL::processPix( Vector<ShaderComponent*> &componentList,
                                        const MaterialFeatureData &fd )
                                        const MaterialFeatureData &fd )
 {
 {
    // If there is no deferred information, bail on this feature
    // If there is no deferred information, bail on this feature
-   if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
+   if( !fd.features[MFT_isDeferred] || !fd.features[MFT_RTLighting] )
    {
    {
       output = NULL;
       output = NULL;
       return;
       return;
@@ -737,12 +740,6 @@ void DeferredMinnaertHLSL::processPix( Vector<ShaderComponent*> &componentList,
 void DeferredSubSurfaceHLSL::processPix(  Vector<ShaderComponent*> &componentList, 
 void DeferredSubSurfaceHLSL::processPix(  Vector<ShaderComponent*> &componentList, 
                                           const MaterialFeatureData &fd )
                                           const MaterialFeatureData &fd )
 {
 {
-   // If there is no deferred information, bail on this feature
-   if( fd.features[MFT_ForwardShading] || !fd.features[MFT_RTLighting] )
-   {
-      output = NULL;
-      return;
-   }
 
 
    Var *subSurfaceParams = new Var;
    Var *subSurfaceParams = new Var;
    subSurfaceParams->setType( "float4" );
    subSurfaceParams->setType( "float4" );
@@ -754,9 +751,13 @@ void DeferredSubSurfaceHLSL::processPix(  Vector<ShaderComponent*> &componentLis
    Var *d_NL_Att = (Var*)LangElement::find( "d_NL_Att" );
    Var *d_NL_Att = (Var*)LangElement::find( "d_NL_Att" );
 
 
    MultiLine *meta = new MultiLine;
    MultiLine *meta = new MultiLine;
-   meta->addStatement( new GenOp( "   float subLamb = smoothstep([email protected], 1.0, @) - smoothstep(0.0, 1.0, @);\r\n", subSurfaceParams, d_NL_Att, d_NL_Att ) );
-   meta->addStatement( new GenOp( "   subLamb = max(0.0, subLamb);\r\n" ) );
-   meta->addStatement( new GenOp( "   @;\r\n", assignColor( new GenOp( "float4(@ + (subLamb * @.rgb), 1.0)", d_lightcolor, subSurfaceParams ), Material::Mul ) ) );
+   if (fd.features[MFT_isDeferred])
+   {
+      Var* targ = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget3));
+      meta->addStatement(new GenOp("   @.rgb += @.rgb*@.a;\r\n", targ, subSurfaceParams, subSurfaceParams));
+      output = meta;
+      return;
+   }
 
 
    output = meta;
    output = meta;
 }
 }

+ 24 - 44
Engine/source/lighting/advanced/hlsl/deferredShadingFeaturesHLSL.cpp

@@ -69,20 +69,23 @@ void DeferredSpecMapHLSL::processPix( Vector<ShaderComponent*> &componentList, c
    specularMapTex->uniform = true;
    specularMapTex->uniform = true;
    specularMapTex->texture = true;
    specularMapTex->texture = true;
    specularMapTex->constNum = specularMap->constNum;
    specularMapTex->constNum = specularMap->constNum;
+   LangElement *texOp = new GenOp("   @.Sample(@, @)", specularMapTex, specularMap, texCoord);
+   
+   Var *specularColor = (Var*)LangElement::find("specularColor");
+   if (!specularColor) specularColor = new Var("specularColor", "float4");
+   Var *metalness = (Var*)LangElement::find("metalness");
+   if (!metalness) metalness = new Var("metalness", "float");
+   Var *smoothness = (Var*)LangElement::find("smoothness");
+   if (!smoothness) smoothness = new Var("smoothness", "float");
 
 
-   //matinfo.g slot reserved for AO later
-   Var* specColor = new Var;
-   specColor->setName("specColor");
-   specColor->setType("float4");
-   LangElement *specColorElem = new DecOp(specColor);
+   meta->addStatement(new GenOp("   @ = @.r;\r\n", new DecOp(smoothness), texOp));
+   meta->addStatement(new GenOp("   @ = @.b;\r\n", new DecOp(metalness), texOp));
 
 
-   meta->addStatement(new GenOp("   @.g = 1.0;\r\n", material));
-   //sample specular map
-   meta->addStatement(new GenOp("   @ = @.Sample(@, @);\r\n", specColorElem, specularMapTex, specularMap, texCoord));
-   
-   meta->addStatement(new GenOp("   @.b = dot(@.rgb, float3(0.3, 0.59, 0.11));\r\n", material, specColor));
-   meta->addStatement(new GenOp("   @.a = @.a;\r\n", material, specColor));
+   if (fd.features[MFT_InvertSmoothness])
+      meta->addStatement(new GenOp("   @ = 1.0-@;\r\n", smoothness, smoothness));
 
 
+   meta->addStatement(new GenOp("   @ = @.ggga;\r\n", new DecOp(specularColor), texOp));
+   meta->addStatement(new GenOp("   @.bga = float3(@,@.g,@);\r\n", material, smoothness, specularColor, metalness));
    output = meta;
    output = meta;
 }
 }
 
 
@@ -159,43 +162,20 @@ void DeferredSpecVarsHLSL::processPix( Vector<ShaderComponent*> &componentList,
       material->setStructName( "OUT" );
       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("   @.a = @/128;\r\n", material, specPower));
-   meta->addStatement(new GenOp("   @.b = @/5;\r\n", material, specStrength));
-   output = meta;
-}
+   Var *metalness = new Var("metalness", "float");
+   metalness->uniform = true;
+   metalness->constSortPos = cspPotentialPrimitive;
 
 
-// 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");
-   }
+   Var *smoothness = new Var("smoothness", "float");
+   smoothness->uniform = true;
+   smoothness->constSortPos = cspPotentialPrimitive;
 
 
    MultiLine * meta = new MultiLine;
    MultiLine * meta = new MultiLine;
    //matinfo.g slot reserved for AO later
    //matinfo.g slot reserved for AO later
    meta->addStatement(new GenOp("   @.g = 1.0;\r\n", material));
    meta->addStatement(new GenOp("   @.g = 1.0;\r\n", material));
-   meta->addStatement(new GenOp("   @.ba = 0.0;\r\n", material));
+   meta->addStatement(new GenOp("   @.b = @;\r\n", material, smoothness));
+   if (fd.features[MFT_InvertSmoothness])
+      meta->addStatement(new GenOp("   @ = 1.0-@;\r\n", smoothness, smoothness));
+   meta->addStatement(new GenOp("   @.a = @;\r\n", material, metalness));
    output = meta;
    output = meta;
 }
 }

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

@@ -69,16 +69,4 @@ public:
    
    
    virtual U32 getOutputTargets( const MaterialFeatureData &fd ) const { return ShaderFeature::RenderTarget2; }
    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
 #endif

+ 48 - 19
Engine/source/materials/materialDefinition.cpp

@@ -116,11 +116,17 @@ Material::Material()
    {
    {
       mDiffuse[i].set( 1.0f, 1.0f, 1.0f, 1.0f );
       mDiffuse[i].set( 1.0f, 1.0f, 1.0f, 1.0f );
       mDiffuseMapSRGB[i] = true;
       mDiffuseMapSRGB[i] = true;
-      mSpecular[i].set( 1.0f, 1.0f, 1.0f, 1.0f );
 
 
-      mSpecularPower[i] = 8.0f;
-      mSpecularStrength[i] = 1.0f;
+      mSmoothness[i] = 0.0f;
+      mMetalness[i] = 0.0f;
+
       mPixelSpecular[i] = false;
       mPixelSpecular[i] = false;
+	  mIsSRGb[i] = false;
+      mInvertSmoothness[i] = false;
+
+      mSmoothnessChan[i] = 0;
+      mAOChan[i] = 1;
+      mMetalChan[i] = 2;
 
 
       mAccuEnabled[i]   = false;
       mAccuEnabled[i]   = false;
       mAccuScale[i]     = 1.0f;
       mAccuScale[i]     = 1.0f;
@@ -166,6 +172,9 @@ Material::Material()
 
 
       // Deferred Shading
       // Deferred Shading
       mMatInfoFlags[i] = 0.0f;
       mMatInfoFlags[i] = 0.0f;
+      mRoughMapFilename[i].clear();
+      mAOMapFilename[i].clear();
+      mMetalMapFilename[i].clear();
    }
    }
 
 
    dMemset(mCellIndex, 0, sizeof(mCellIndex));
    dMemset(mCellIndex, 0, sizeof(mCellIndex));
@@ -255,20 +264,12 @@ void Material::initPersistFields()
 
 
       addField( "detailNormalMapStrength", TypeF32, Offset(mDetailNormalMapStrength, Material), MAX_STAGES,
       addField( "detailNormalMapStrength", TypeF32, Offset(mDetailNormalMapStrength, Material), MAX_STAGES,
          "Used to scale the strength of the detail normal map when blended with the base normal map." );
          "Used to scale the strength of the detail normal map when blended with the base normal map." );
+      
+      addField("smoothness", TypeF32, Offset(mSmoothness, Material), MAX_STAGES,
+         "The degree of smoothness when not using a specularMap." );
 
 
-      addField("specular", TypeColorF, Offset(mSpecular, Material), MAX_STAGES,
-         "The color of the specular highlight when not using a specularMap." );
-
-      addField("specularPower", TypeF32, Offset(mSpecularPower, Material), MAX_STAGES,
-         "The hardness of the specular highlight when not using a specularMap." );
-
-		addField("specularStrength", TypeF32, Offset(mSpecularStrength, Material), MAX_STAGES,
-         "The strength of the specular highlight when not using a specularMap." );
-
-      addField("pixelSpecular", TypeBool, Offset(mPixelSpecular, Material), MAX_STAGES, 
-         "This enables per-pixel specular highlights controlled by the alpha channel of the "
-         "normal map texture.  Note that if pixel specular is enabled the DXTnm format will not "
-         "work with your normal map, unless you are also using a specular map." );
+		addField("metalness", TypeF32, Offset(mMetalness, Material), MAX_STAGES,
+         "The degree of Metalness when not using a specularMap." );
 
 
       addProtectedField( "accuEnabled", TYPEID< bool >(), Offset( mAccuEnabled, Material ),
       addProtectedField( "accuEnabled", TYPEID< bool >(), Offset( mAccuEnabled, Material ),
             &_setAccuEnabled, &defaultProtectedGetFn, MAX_STAGES, "Accumulation texture." );
             &_setAccuEnabled, &defaultProtectedGetFn, MAX_STAGES, "Accumulation texture." );
@@ -288,10 +289,31 @@ void Material::initPersistFields()
       addField("accuSpecular",   TypeF32, Offset(mAccuSpecular, Material), MAX_STAGES,
       addField("accuSpecular",   TypeF32, Offset(mAccuSpecular, Material), MAX_STAGES,
          "Changes specularity to this value where the accumulated material is present.");
          "Changes specularity to this value where the accumulated material is present.");
 
 
+      addField("isSRGb", TypeBool, Offset(mIsSRGb, Material), MAX_STAGES,
+         "Substance Designer Workaround.");
+
+      addField("invertSmoothness", TypeBool, Offset(mInvertSmoothness, Material), MAX_STAGES,
+         "Treat Smoothness as Roughness");
+
       addField( "specularMap", TypeImageFilename, Offset(mSpecularMapFilename, Material), MAX_STAGES,
       addField( "specularMap", TypeImageFilename, Offset(mSpecularMapFilename, Material), MAX_STAGES,
-         "The specular map texture. The RGB channels of this texture provide a per-pixel replacement for the 'specular' parameter on the material. "
-         "If this texture contains alpha information, the alpha channel of the texture will be used as the gloss map. "
-         "This provides a per-pixel replacement for the 'specularPower' on the material" );
+         "Prepacked specular map texture. The RGB channels of this texture provide per-pixel reference values for: "
+         "smoothness (R), Ambient Occlusion (G), and metalness(B)");
+
+      addField("roughMap", TypeImageFilename, Offset(mRoughMapFilename, Material), MAX_STAGES,
+         "smoothness map. will be packed into the R channel of a packed 'specular' map");
+      addField("smoothnessChan", TypeF32, Offset(mSmoothnessChan, Material), MAX_STAGES,
+         "The input channel smoothness maps use.");
+
+      addField("aoMap", TypeImageFilename, Offset(mAOMapFilename, Material), MAX_STAGES,
+         "Ambient Occlusion map. will be packed into the G channel of a packed 'specular' map");
+      addField("AOChan", TypeF32, Offset(mAOChan, Material), MAX_STAGES,
+         "The input channel AO maps use.");
+
+      addField("metalMap", TypeImageFilename, Offset(mMetalMapFilename, Material), MAX_STAGES,
+         "Metalness map. will be packed into the B channel of a packed 'specular' map");
+      addField("metalChan", TypeF32, Offset(mMetalChan, Material), MAX_STAGES,
+         "The input channel metalness maps use.");
+
 
 
       addField( "parallaxScale", TypeF32, Offset(mParallaxScale, Material), MAX_STAGES,
       addField( "parallaxScale", TypeF32, Offset(mParallaxScale, Material), MAX_STAGES,
          "Enables parallax mapping and defines the scale factor for the parallax effect.  Typically "
          "Enables parallax mapping and defines the scale factor for the parallax effect.  Typically "
@@ -706,6 +728,13 @@ DefineConsoleMethod( Material, setAutoGenerated, void, (bool isAutoGenerated), ,
    object->setAutoGenerated(isAutoGenerated);
    object->setAutoGenerated(isAutoGenerated);
 }
 }
 
 
+DefineConsoleMethod(Material, getAutogeneratedFile, const char*, (), , "Get filename of autogenerated shader file")
+{
+   SimObject *material = static_cast<SimObject *>(object);
+   return material->getFilename();
+}
+
+
 // Accumulation
 // Accumulation
 bool Material::_setAccuEnabled( void *object, const char *index, const char *data )
 bool Material::_setAccuEnabled( void *object, const char *index, const char *data )
 {
 {

+ 11 - 4
Engine/source/materials/materialDefinition.h

@@ -213,7 +213,15 @@ public:
    FileName mDetailMapFilename[MAX_STAGES];
    FileName mDetailMapFilename[MAX_STAGES];
    FileName mNormalMapFilename[MAX_STAGES];
    FileName mNormalMapFilename[MAX_STAGES];
 
 
+   bool     mIsSRGb[MAX_STAGES];
+   bool     mInvertSmoothness[MAX_STAGES];
    FileName mSpecularMapFilename[MAX_STAGES];
    FileName mSpecularMapFilename[MAX_STAGES];
+   FileName mRoughMapFilename[MAX_STAGES];
+   F32      mSmoothnessChan[MAX_STAGES];
+   FileName mAOMapFilename[MAX_STAGES];
+   F32      mAOChan[MAX_STAGES];
+   FileName mMetalMapFilename[MAX_STAGES];
+   F32      mMetalChan[MAX_STAGES];
 
 
    /// A second normal map which repeats at the detail map
    /// A second normal map which repeats at the detail map
    /// scale and blended with the base normal map.
    /// scale and blended with the base normal map.
@@ -226,11 +234,10 @@ public:
    /// or if it has a texture it is multiplied against 
    /// or if it has a texture it is multiplied against 
    /// the diffuse texture color.
    /// the diffuse texture color.
    LinearColorF mDiffuse[MAX_STAGES];
    LinearColorF mDiffuse[MAX_STAGES];
+   
+   F32 mSmoothness[MAX_STAGES];
+   F32 mMetalness[MAX_STAGES];
 
 
-   LinearColorF mSpecular[MAX_STAGES];
-
-   F32 mSpecularPower[MAX_STAGES];
-   F32 mSpecularStrength[MAX_STAGES];
    bool mPixelSpecular[MAX_STAGES];
    bool mPixelSpecular[MAX_STAGES];
 
 
    bool mVertLit[MAX_STAGES];
    bool mVertLit[MAX_STAGES];

+ 9 - 9
Engine/source/materials/materialFeatureTypes.cpp

@@ -43,6 +43,7 @@ ImplementFeatureType( MFT_DetailMap, MFG_Texture, 4.0f, true );
 ImplementFeatureType( MFT_DiffuseColor, MFG_Texture, 5.0f, true );
 ImplementFeatureType( MFT_DiffuseColor, MFG_Texture, 5.0f, true );
 ImplementFeatureType( MFT_DiffuseVertColor, MFG_Texture, 6.0f, true );
 ImplementFeatureType( MFT_DiffuseVertColor, MFG_Texture, 6.0f, true );
 ImplementFeatureType( MFT_AlphaTest, MFG_Texture, 7.0f, true );
 ImplementFeatureType( MFT_AlphaTest, MFG_Texture, 7.0f, true );
+ImplementFeatureType(MFT_InvertSmoothness, U32(-1), -1, true);
 ImplementFeatureType( MFT_SpecularMap, MFG_Texture, 8.0f, true );
 ImplementFeatureType( MFT_SpecularMap, MFG_Texture, 8.0f, true );
 ImplementFeatureType( MFT_NormalMap, MFG_Texture, 9.0f, true );
 ImplementFeatureType( MFT_NormalMap, MFG_Texture, 9.0f, true );
 ImplementFeatureType( MFT_DetailNormalMap, MFG_Texture, 10.0f, true );
 ImplementFeatureType( MFT_DetailNormalMap, MFG_Texture, 10.0f, true );
@@ -51,14 +52,15 @@ ImplementFeatureType( MFT_Imposter, U32(-1), -1, true );
 ImplementFeatureType( MFT_AccuMap, MFG_PreLighting, 2.0f, true );
 ImplementFeatureType( MFT_AccuMap, MFG_PreLighting, 2.0f, true );
 
 
 ImplementFeatureType( MFT_RTLighting, MFG_Lighting, 2.0f, true );
 ImplementFeatureType( MFT_RTLighting, MFG_Lighting, 2.0f, true );
-ImplementFeatureType( MFT_SubSurface, MFG_Lighting, 3.0f, true );
-ImplementFeatureType( MFT_LightMap, MFG_Lighting, 4.0f, true );
-ImplementFeatureType( MFT_ToneMap, MFG_Lighting, 5.0f, true );
-ImplementFeatureType( MFT_VertLitTone, MFG_Lighting, 6.0f, false );
-ImplementFeatureType( MFT_VertLit, MFG_Lighting, 7.0f, true );
-ImplementFeatureType( MFT_PixSpecular, MFG_Lighting, 9.0f, true );
+ImplementFeatureType( MFT_LightMap, MFG_Lighting, 3.0f, true );
+ImplementFeatureType( MFT_ToneMap, MFG_Lighting, 4.0f, true );
+ImplementFeatureType( MFT_VertLitTone, MFG_Lighting, 5.0f, false );
+ImplementFeatureType( MFT_PixSpecular, MFG_Lighting, 6.0f, true );
+ImplementFeatureType( MFT_StaticCubemap, U32(-1), -1.0, true );
+ImplementFeatureType( MFT_CubeMap, MFG_Lighting, 7.0f, true );
+ImplementFeatureType( MFT_SubSurface, MFG_Lighting, 8.0f, true );
+ImplementFeatureType( MFT_VertLit, MFG_Lighting, 9.0f, true );
 ImplementFeatureType( MFT_MinnaertShading, MFG_Lighting, 10.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 );
@@ -99,8 +101,6 @@ ImplementFeatureType( MFT_ImposterVert, MFG_PreTransform, 1.0, false );
 // Deferred Shading
 // Deferred Shading
 ImplementFeatureType( MFT_isDeferred, U32(-1), -1, true );
 ImplementFeatureType( MFT_isDeferred, U32(-1), -1, true );
 ImplementFeatureType( MFT_SkyBox, MFG_Transform, 1.0f, false );
 ImplementFeatureType( MFT_SkyBox, MFG_Transform, 1.0f, false );
-ImplementFeatureType( MFT_DeferredEmptySpec, MFG_Texture, 8.01f, false );
-
 ImplementFeatureType( MFT_DeferredSpecMap, MFG_Texture, 8.2f, false );
 ImplementFeatureType( MFT_DeferredSpecMap, MFG_Texture, 8.2f, false );
 ImplementFeatureType( MFT_DeferredSpecVars, MFG_Texture, 8.5f, false );
 ImplementFeatureType( MFT_DeferredSpecVars, MFG_Texture, 8.5f, false );
 ImplementFeatureType( MFT_DeferredMatInfoFlags, MFG_Texture, 8.7f, false );
 ImplementFeatureType( MFT_DeferredMatInfoFlags, MFG_Texture, 8.7f, false );

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

@@ -122,8 +122,10 @@ DeclareFeatureType( MFT_ToneMap );
 DeclareFeatureType( MFT_VertLit );
 DeclareFeatureType( MFT_VertLit );
 DeclareFeatureType( MFT_VertLitTone );
 DeclareFeatureType( MFT_VertLitTone );
 
 
+DeclareFeatureType( MFT_StaticCubemap );
 DeclareFeatureType( MFT_CubeMap );
 DeclareFeatureType( MFT_CubeMap );
 DeclareFeatureType( MFT_PixSpecular );
 DeclareFeatureType( MFT_PixSpecular );
+DeclareFeatureType( MFT_InvertSmoothness );
 DeclareFeatureType( MFT_SpecularMap );
 DeclareFeatureType( MFT_SpecularMap );
 DeclareFeatureType( MFT_GlossMap );
 DeclareFeatureType( MFT_GlossMap );
 
 
@@ -189,5 +191,4 @@ DeclareFeatureType( MFT_SkyBox );
 DeclareFeatureType( MFT_DeferredSpecMap );
 DeclareFeatureType( MFT_DeferredSpecMap );
 DeclareFeatureType( MFT_DeferredSpecVars );
 DeclareFeatureType( MFT_DeferredSpecVars );
 DeclareFeatureType( MFT_DeferredMatInfoFlags );
 DeclareFeatureType( MFT_DeferredMatInfoFlags );
-DeclareFeatureType( MFT_DeferredEmptySpec );
 #endif // _MATERIALFEATURETYPES_H_
 #endif // _MATERIALFEATURETYPES_H_

+ 63 - 38
Engine/source/materials/processedMaterial.cpp

@@ -125,7 +125,7 @@ void ProcessedMaterial::_setBlendState(Material::BlendOp blendOp, GFXStateBlockD
    case Material::Mul:
    case Material::Mul:
       {
       {
          desc.blendSrc = GFXBlendDestColor;
          desc.blendSrc = GFXBlendDestColor;
-         desc.blendDest = GFXBlendZero;
+         desc.blendDest = GFXBlendInvSrcAlpha;
          break;
          break;
       }
       }
    case Material::LerpAlpha:
    case Material::LerpAlpha:
@@ -174,6 +174,11 @@ GFXTexHandle ProcessedMaterial::_createTexture( const char* filename, GFXTexture
    return GFXTexHandle( _getTexturePath(filename), profile, avar("%s() - NA (line %d)", __FUNCTION__, __LINE__) );
    return GFXTexHandle( _getTexturePath(filename), profile, avar("%s() - NA (line %d)", __FUNCTION__, __LINE__) );
 }
 }
 
 
+GFXTexHandle ProcessedMaterial::_createCompositeTexture(const char *filenameR, const char *filenameG, const char *filenameB, const char *filenameA, U32 inputKey[4], GFXTextureProfile *profile)
+{
+   return GFXTexHandle(_getTexturePath(filenameR), _getTexturePath(filenameG), _getTexturePath(filenameB), _getTexturePath(filenameA), inputKey, profile, avar("%s() - NA (line %d)", __FUNCTION__, __LINE__));
+}
+
 void ProcessedMaterial::addStateBlockDesc(const GFXStateBlockDesc& sb)
 void ProcessedMaterial::addStateBlockDesc(const GFXStateBlockDesc& sb)
 {
 {
    mUserDefined = sb;
    mUserDefined = sb;
@@ -379,100 +384,120 @@ void ProcessedMaterial::_setRenderState(  const SceneRenderState *state,
 void ProcessedMaterial::_setStageData()
 void ProcessedMaterial::_setStageData()
 {
 {
    // Only do this once
    // Only do this once
-   if ( mHasSetStageData ) 
+   if (mHasSetStageData)
       return;
       return;
    mHasSetStageData = true;
    mHasSetStageData = true;
 
 
    U32 i;
    U32 i;
 
 
    // Load up all the textures for every possible stage
    // Load up all the textures for every possible stage
-   for( i=0; i<Material::MAX_STAGES; i++ )
+   for (i = 0; i < Material::MAX_STAGES; i++)
    {
    {
       // DiffuseMap
       // DiffuseMap
-      if( mMaterial->mDiffuseMapFilename[i].isNotEmpty() )
+      if (mMaterial->mDiffuseMapFilename[i].isNotEmpty())
       {
       {
-         mStages[i].setTex( MFT_DiffuseMap, _createTexture( mMaterial->mDiffuseMapFilename[i], &GFXStaticTextureSRGBProfile) );
-         if (!mStages[i].getTex( MFT_DiffuseMap ))
+         mStages[i].setTex(MFT_DiffuseMap, _createTexture(mMaterial->mDiffuseMapFilename[i], &GFXStaticTextureSRGBProfile));
+         if (!mStages[i].getTex(MFT_DiffuseMap))
          {
          {
             //If we start with a #, we're probably actually attempting to hit a named target and it may not get a hit on the first pass. So we'll
             //If we start with a #, we're probably actually attempting to hit a named target and it may not get a hit on the first pass. So we'll
             //pass on the error rather than spamming the console
             //pass on the error rather than spamming the console
             if (!mMaterial->mDiffuseMapFilename[i].startsWith("#"))
             if (!mMaterial->mDiffuseMapFilename[i].startsWith("#"))
                mMaterial->logError("Failed to load diffuse map %s for stage %i", _getTexturePath(mMaterial->mDiffuseMapFilename[i]).c_str(), i);
                mMaterial->logError("Failed to load diffuse map %s for stage %i", _getTexturePath(mMaterial->mDiffuseMapFilename[i]).c_str(), i);
-            
+
             // Load a debug texture to make it clear to the user 
             // Load a debug texture to make it clear to the user 
             // that the texture for this stage was missing.
             // that the texture for this stage was missing.
-            mStages[i].setTex( MFT_DiffuseMap, _createTexture( GFXTextureManager::getMissingTexturePath().c_str(), &GFXStaticTextureSRGBProfile) );
+            mStages[i].setTex(MFT_DiffuseMap, _createTexture(GFXTextureManager::getMissingTexturePath().c_str(), &GFXStaticTextureSRGBProfile));
          }
          }
       }
       }
 
 
       // OverlayMap
       // OverlayMap
-      if( mMaterial->mOverlayMapFilename[i].isNotEmpty() )
+      if (mMaterial->mOverlayMapFilename[i].isNotEmpty())
       {
       {
-         mStages[i].setTex( MFT_OverlayMap, _createTexture( mMaterial->mOverlayMapFilename[i], &GFXStaticTextureSRGBProfile ) );
-         if(!mStages[i].getTex( MFT_OverlayMap ))
+         mStages[i].setTex(MFT_OverlayMap, _createTexture(mMaterial->mOverlayMapFilename[i], &GFXStaticTextureSRGBProfile));
+         if (!mStages[i].getTex(MFT_OverlayMap))
             mMaterial->logError("Failed to load overlay map %s for stage %i", _getTexturePath(mMaterial->mOverlayMapFilename[i]).c_str(), i);
             mMaterial->logError("Failed to load overlay map %s for stage %i", _getTexturePath(mMaterial->mOverlayMapFilename[i]).c_str(), i);
       }
       }
 
 
       // LightMap
       // LightMap
-      if( mMaterial->mLightMapFilename[i].isNotEmpty() )
+      if (mMaterial->mLightMapFilename[i].isNotEmpty())
       {
       {
-         mStages[i].setTex( MFT_LightMap, _createTexture( mMaterial->mLightMapFilename[i], &GFXStaticTextureSRGBProfile ) );
-         if(!mStages[i].getTex( MFT_LightMap ))
+         mStages[i].setTex(MFT_LightMap, _createTexture(mMaterial->mLightMapFilename[i], &GFXStaticTextureSRGBProfile));
+         if (!mStages[i].getTex(MFT_LightMap))
             mMaterial->logError("Failed to load light map %s for stage %i", _getTexturePath(mMaterial->mLightMapFilename[i]).c_str(), i);
             mMaterial->logError("Failed to load light map %s for stage %i", _getTexturePath(mMaterial->mLightMapFilename[i]).c_str(), i);
       }
       }
 
 
       // ToneMap
       // ToneMap
-      if( mMaterial->mToneMapFilename[i].isNotEmpty() )
+      if (mMaterial->mToneMapFilename[i].isNotEmpty())
       {
       {
-         mStages[i].setTex( MFT_ToneMap, _createTexture( mMaterial->mToneMapFilename[i], &GFXStaticTextureProfile) );
-         if(!mStages[i].getTex( MFT_ToneMap ))
+         mStages[i].setTex(MFT_ToneMap, _createTexture(mMaterial->mToneMapFilename[i], &GFXStaticTextureProfile));
+         if (!mStages[i].getTex(MFT_ToneMap))
             mMaterial->logError("Failed to load tone map %s for stage %i", _getTexturePath(mMaterial->mToneMapFilename[i]).c_str(), i);
             mMaterial->logError("Failed to load tone map %s for stage %i", _getTexturePath(mMaterial->mToneMapFilename[i]).c_str(), i);
       }
       }
 
 
       // DetailMap
       // DetailMap
-      if( mMaterial->mDetailMapFilename[i].isNotEmpty() )
+      if (mMaterial->mDetailMapFilename[i].isNotEmpty())
       {
       {
-         mStages[i].setTex( MFT_DetailMap, _createTexture( mMaterial->mDetailMapFilename[i], &GFXStaticTextureProfile) );
-         if(!mStages[i].getTex( MFT_DetailMap ))
+         mStages[i].setTex(MFT_DetailMap, _createTexture(mMaterial->mDetailMapFilename[i], &GFXStaticTextureProfile));
+         if (!mStages[i].getTex(MFT_DetailMap))
             mMaterial->logError("Failed to load detail map %s for stage %i", _getTexturePath(mMaterial->mDetailMapFilename[i]).c_str(), i);
             mMaterial->logError("Failed to load detail map %s for stage %i", _getTexturePath(mMaterial->mDetailMapFilename[i]).c_str(), i);
       }
       }
 
 
       // NormalMap
       // NormalMap
-      if( mMaterial->mNormalMapFilename[i].isNotEmpty() )
+      if (mMaterial->mNormalMapFilename[i].isNotEmpty())
       {
       {
-         mStages[i].setTex( MFT_NormalMap, _createTexture( mMaterial->mNormalMapFilename[i], &GFXNormalMapProfile) );
-         if(!mStages[i].getTex( MFT_NormalMap ))
+         mStages[i].setTex(MFT_NormalMap, _createTexture(mMaterial->mNormalMapFilename[i], &GFXNormalMapProfile));
+         if (!mStages[i].getTex(MFT_NormalMap))
             mMaterial->logError("Failed to load normal map %s for stage %i", _getTexturePath(mMaterial->mNormalMapFilename[i]).c_str(), i);
             mMaterial->logError("Failed to load normal map %s for stage %i", _getTexturePath(mMaterial->mNormalMapFilename[i]).c_str(), i);
       }
       }
 
 
       // Detail Normal Map
       // Detail Normal Map
-      if( mMaterial->mDetailNormalMapFilename[i].isNotEmpty() )
+      if (mMaterial->mDetailNormalMapFilename[i].isNotEmpty())
       {
       {
-         mStages[i].setTex( MFT_DetailNormalMap, _createTexture( mMaterial->mDetailNormalMapFilename[i], &GFXNormalMapProfile) );
-         if(!mStages[i].getTex( MFT_DetailNormalMap ))
+         mStages[i].setTex(MFT_DetailNormalMap, _createTexture(mMaterial->mDetailNormalMapFilename[i], &GFXNormalMapProfile));
+         if (!mStages[i].getTex(MFT_DetailNormalMap))
             mMaterial->logError("Failed to load normal map %s for stage %i", _getTexturePath(mMaterial->mDetailNormalMapFilename[i]).c_str(), i);
             mMaterial->logError("Failed to load normal map %s for stage %i", _getTexturePath(mMaterial->mDetailNormalMapFilename[i]).c_str(), i);
       }
       }
-      
+
+      GFXTextureProfile* profile = &GFXStaticTextureProfile;
+      if (mMaterial->mIsSRGb[i])
+         profile = &GFXStaticTextureSRGBProfile;
+
       // SpecularMap
       // SpecularMap
-      if( mMaterial->mSpecularMapFilename[i].isNotEmpty() )
+      if (mMaterial->mSpecularMapFilename[i].isNotEmpty())
       {
       {
-         mStages[i].setTex( MFT_SpecularMap, _createTexture( mMaterial->mSpecularMapFilename[i], &GFXStaticTextureSRGBProfile) );
-         if(!mStages[i].getTex( MFT_SpecularMap ))
+         mStages[i].setTex(MFT_SpecularMap, _createTexture(mMaterial->mSpecularMapFilename[i], profile));
+         if (!mStages[i].getTex(MFT_SpecularMap))
             mMaterial->logError("Failed to load specular map %s for stage %i", _getTexturePath(mMaterial->mSpecularMapFilename[i]).c_str(), i);
             mMaterial->logError("Failed to load specular map %s for stage %i", _getTexturePath(mMaterial->mSpecularMapFilename[i]).c_str(), i);
       }
       }
+      else
+      {
+         if (mMaterial->mRoughMapFilename[i].isNotEmpty() && mMaterial->mMetalMapFilename[i].isNotEmpty())
+         {
+            U32 inputKey[4];
+            inputKey[0] = mMaterial->mSmoothnessChan[i];
+            inputKey[1] = mMaterial->mAOChan[i];
+            inputKey[2] = mMaterial->mMetalChan[i];
+            inputKey[3] = NULL;
+            mStages[i].setTex(MFT_SpecularMap, _createCompositeTexture(mMaterial->mRoughMapFilename[i], mMaterial->mAOMapFilename[i],
+               mMaterial->mMetalMapFilename[i], "",
+               inputKey, profile));
+            if (!mStages[i].getTex(MFT_SpecularMap))
+               mMaterial->logError("Failed to load specular map %s for stage %i", _getTexturePath(mMaterial->mSpecularMapFilename[i]).c_str(), i);
+         }
+      }
    }
    }
 
 
-	mMaterial->mCubemapData = dynamic_cast<CubemapData*>(Sim::findObject( mMaterial->mCubemapName ));
-	if( !mMaterial->mCubemapData )
-		mMaterial->mCubemapData = NULL;
-		
-		
+   mMaterial->mCubemapData = dynamic_cast<CubemapData*>(Sim::findObject(mMaterial->mCubemapName));
+   if (!mMaterial->mCubemapData)
+      mMaterial->mCubemapData = NULL;
+
+
    // If we have a cubemap put it on stage 0 (cubemaps only supported on stage 0)
    // If we have a cubemap put it on stage 0 (cubemaps only supported on stage 0)
-   if( mMaterial->mCubemapData )
+   if (mMaterial->mCubemapData)
    {
    {
       mMaterial->mCubemapData->createMap();
       mMaterial->mCubemapData->createMap();
-      mStages[0].setCubemap( mMaterial->mCubemapData->mCubemap ); 
-      if ( !mStages[0].getCubemap() )
+      mStages[0].setCubemap(mMaterial->mCubemapData->mCubemap);
+      if (!mStages[0].getCubemap())
          mMaterial->logError("Failed to load cubemap");
          mMaterial->logError("Failed to load cubemap");
    }
    }
 }
 }

+ 1 - 0
Engine/source/materials/processedMaterial.h

@@ -285,6 +285,7 @@ protected:
 
 
    /// Loads the texture located at _getTexturePath(filename) and gives it the specified profile
    /// Loads the texture located at _getTexturePath(filename) and gives it the specified profile
    GFXTexHandle _createTexture( const char *filename, GFXTextureProfile *profile );
    GFXTexHandle _createTexture( const char *filename, GFXTextureProfile *profile );
+   GFXTexHandle _createCompositeTexture(const char *filenameR, const char *filenameG, const char *filenameB, const char *filenameA, U32 inputKey[4], GFXTextureProfile *profile);
 
 
    /// @name State blocks
    /// @name State blocks
    ///
    ///

+ 15 - 10
Engine/source/materials/processedShaderMaterial.cpp

@@ -56,8 +56,8 @@ void ShaderConstHandles::init( GFXShader *shader, CustomMaterial* mat /*=NULL*/
    mTexMatSC = shader->getShaderConstHandle(ShaderGenVars::texMat);
    mTexMatSC = shader->getShaderConstHandle(ShaderGenVars::texMat);
    mToneMapTexSC = shader->getShaderConstHandle(ShaderGenVars::toneMap);
    mToneMapTexSC = shader->getShaderConstHandle(ShaderGenVars::toneMap);
    mSpecularColorSC = shader->getShaderConstHandle(ShaderGenVars::specularColor);
    mSpecularColorSC = shader->getShaderConstHandle(ShaderGenVars::specularColor);
-   mSpecularPowerSC = shader->getShaderConstHandle(ShaderGenVars::specularPower);
-   mSpecularStrengthSC = shader->getShaderConstHandle(ShaderGenVars::specularStrength);
+   mSmoothnessSC = shader->getShaderConstHandle(ShaderGenVars::smoothness);
+   mMetalnessSC = shader->getShaderConstHandle(ShaderGenVars::metalness);
    mAccuScaleSC = shader->getShaderConstHandle("$accuScale");
    mAccuScaleSC = shader->getShaderConstHandle("$accuScale");
    mAccuDirectionSC = shader->getShaderConstHandle("$accuDirection");
    mAccuDirectionSC = shader->getShaderConstHandle("$accuDirection");
    mAccuStrengthSC = shader->getShaderConstHandle("$accuStrength");
    mAccuStrengthSC = shader->getShaderConstHandle("$accuStrength");
@@ -299,6 +299,8 @@ void ProcessedShaderMaterial::_determineFeatures(  U32 stageNum,
 
 
    // First we add all the features which the 
    // First we add all the features which the 
    // material has defined.
    // material has defined.
+   if (mMaterial->mInvertSmoothness[stageNum])
+      fd.features.addFeature(MFT_InvertSmoothness);
 
 
    if ( mMaterial->isTranslucent() )
    if ( mMaterial->isTranslucent() )
    {
    {
@@ -335,7 +337,6 @@ void ProcessedShaderMaterial::_determineFeatures(  U32 stageNum,
    if (  features.hasFeature( MFT_UseInstancing ) &&
    if (  features.hasFeature( MFT_UseInstancing ) &&
          mMaxStages == 1 &&
          mMaxStages == 1 &&
          !mMaterial->mGlow[0] &&
          !mMaterial->mGlow[0] &&
-         !mMaterial->mDynamicCubemap &&
          shaderVersion >= 3.0f )
          shaderVersion >= 3.0f )
       fd.features.addFeature( MFT_UseInstancing );
       fd.features.addFeature( MFT_UseInstancing );
 
 
@@ -363,6 +364,7 @@ void ProcessedShaderMaterial::_determineFeatures(  U32 stageNum,
 
 
    if (features.hasFeature(MFT_SkyBox))
    if (features.hasFeature(MFT_SkyBox))
    {
    {
+      fd.features.addFeature(MFT_StaticCubemap);
       fd.features.addFeature(MFT_CubeMap);
       fd.features.addFeature(MFT_CubeMap);
       fd.features.addFeature(MFT_SkyBox);
       fd.features.addFeature(MFT_SkyBox);
    }
    }
@@ -1090,9 +1092,8 @@ void ProcessedShaderMaterial::_setShaderConstants(SceneRenderState * state, cons
    if ( !shaderConsts->wasLost() )
    if ( !shaderConsts->wasLost() )
       return;
       return;
 
 
-   shaderConsts->setSafe(handles->mSpecularColorSC, mMaterial->mSpecular[stageNum]);   
-   shaderConsts->setSafe(handles->mSpecularPowerSC, mMaterial->mSpecularPower[stageNum]);
-   shaderConsts->setSafe(handles->mSpecularStrengthSC, mMaterial->mSpecularStrength[stageNum]);
+   shaderConsts->setSafe(handles->mSmoothnessSC, mMaterial->mSmoothness[stageNum]);
+   shaderConsts->setSafe(handles->mMetalnessSC, mMaterial->mMetalness[stageNum]);
 
 
    shaderConsts->setSafe(handles->mParallaxInfoSC, mMaterial->mParallaxScale[stageNum]);   
    shaderConsts->setSafe(handles->mParallaxInfoSC, mMaterial->mParallaxScale[stageNum]);   
    shaderConsts->setSafe(handles->mMinnaertConstantSC, mMaterial->mMinnaertConstant[stageNum]);
    shaderConsts->setSafe(handles->mMinnaertConstantSC, mMaterial->mMinnaertConstant[stageNum]);
@@ -1262,21 +1263,25 @@ void ProcessedShaderMaterial::setNodeTransforms(const MatrixF *transforms, const
 
 
 void ProcessedShaderMaterial::setSceneInfo(SceneRenderState * state, const SceneData& sgData, U32 pass)
 void ProcessedShaderMaterial::setSceneInfo(SceneRenderState * state, const SceneData& sgData, U32 pass)
 {
 {
-   PROFILE_SCOPE( ProcessedShaderMaterial_setSceneInfo );
+   PROFILE_SCOPE(ProcessedShaderMaterial_setSceneInfo);
 
 
    GFXShaderConstBuffer* shaderConsts = _getShaderConstBuffer(pass);
    GFXShaderConstBuffer* shaderConsts = _getShaderConstBuffer(pass);
    ShaderConstHandles* handles = _getShaderConstHandles(pass);
    ShaderConstHandles* handles = _getShaderConstHandles(pass);
 
 
    // Set cubemap stuff here (it's convenient!)
    // Set cubemap stuff here (it's convenient!)
    const Point3F &eyePosWorld = state->getCameraPosition();
    const Point3F &eyePosWorld = state->getCameraPosition();
-   if ( handles->mCubeEyePosSC->isValid() )
+   if (_hasCubemap(pass) || mMaterial->mDynamicCubemap)
    {
    {
-      if(_hasCubemap(pass) || mMaterial->mDynamicCubemap)
+      if (handles->mCubeEyePosSC->isValid())
       {
       {
          Point3F cubeEyePos = eyePosWorld - sgData.objTrans->getPosition();
          Point3F cubeEyePos = eyePosWorld - sgData.objTrans->getPosition();
-         shaderConsts->set(handles->mCubeEyePosSC, cubeEyePos);      
+         shaderConsts->set(handles->mCubeEyePosSC, cubeEyePos);
       }
       }
    }
    }
+   if (sgData.cubemap)
+      shaderConsts->setSafe(handles->mCubeMipsSC, (F32)sgData.cubemap->getMipMapLevels());
+   else
+      shaderConsts->setSafe(handles->mCubeMipsSC, 1.0f);
 
 
    shaderConsts->setSafe(handles->mVisiblitySC, sgData.visibility);
    shaderConsts->setSafe(handles->mVisiblitySC, sgData.visibility);
 
 

+ 2 - 2
Engine/source/materials/processedShaderMaterial.h

@@ -45,8 +45,8 @@ public:
    GFXShaderConstHandle* mToneMapTexSC;
    GFXShaderConstHandle* mToneMapTexSC;
    GFXShaderConstHandle* mTexMatSC;
    GFXShaderConstHandle* mTexMatSC;
    GFXShaderConstHandle* mSpecularColorSC;
    GFXShaderConstHandle* mSpecularColorSC;
-   GFXShaderConstHandle* mSpecularPowerSC;
-   GFXShaderConstHandle* mSpecularStrengthSC;
+   GFXShaderConstHandle* mSmoothnessSC;
+   GFXShaderConstHandle* mMetalnessSC;
    GFXShaderConstHandle* mParallaxInfoSC;
    GFXShaderConstHandle* mParallaxInfoSC;
    GFXShaderConstHandle* mAccuScaleSC;
    GFXShaderConstHandle* mAccuScaleSC;
    GFXShaderConstHandle* mAccuDirectionSC;
    GFXShaderConstHandle* mAccuDirectionSC;

+ 7 - 0
Engine/source/math/mMathFn.h

@@ -175,6 +175,13 @@ inline F32 mMax(const F32 x, const F32 y)
    return y;
    return y;
 }
 }
 
 
+inline F32 mMin(const F32 x, const F32 y)
+{
+   if (x < y)
+      return x;
+   return y;
+}
+
 inline F32 mFloor(const F32 val)
 inline F32 mFloor(const F32 val)
 {
 {
    return (F32) floor(val);
    return (F32) floor(val);

+ 5 - 0
Engine/source/math/mPoint4.h

@@ -221,6 +221,11 @@ inline Point4F Point4F::operator /(F32 t) const
    return Point4F( x * f, y * f, z * f, w * f );
    return Point4F( x * f, y * f, z * f, w * f );
 }
 }
 
 
+inline F32 mDot(const Point4F &p1, const Point4F &p2)
+{
+   return (p1.x*p2.x + p1.y*p2.y + p1.z*p2.z + p1.w*p2.w);
+}
+
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 //-------------------------------------- Point4F
 //-------------------------------------- Point4F
 
 

+ 1 - 2
Engine/source/platformWin32/threads/thread.cpp

@@ -20,9 +20,8 @@
 // IN THE SOFTWARE.
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
-#ifndef TORQUE_OS_XENON
+
 #include "platformWin32/platformWin32.h"
 #include "platformWin32/platformWin32.h"
-#endif
 #include "platform/threads/thread.h"
 #include "platform/threads/thread.h"
 #include "platform/threads/semaphore.h"
 #include "platform/threads/semaphore.h"
 #include "platform/platformIntrinsics.h"
 #include "platform/platformIntrinsics.h"

+ 6 - 0
Engine/source/renderInstance/renderBinManager.cpp

@@ -179,3 +179,9 @@ DefineEngineMethod( RenderBinManager, getBinType, const char*, (),,
 {
 {
    return object->getRenderInstType().getName();
    return object->getRenderInstType().getName();
 }
 }
+
+DefineEngineMethod(RenderBinManager, getRenderOrder, F32, (), ,
+   "Returns the bin render order.")
+{
+   return object->getRenderOrder();
+}

+ 44 - 48
Engine/source/renderInstance/renderDeferredMgr.cpp

@@ -56,6 +56,7 @@ const String RenderDeferredMgr::BufferName("deferred");
 const RenderInstType RenderDeferredMgr::RIT_Deferred("Deferred");
 const RenderInstType RenderDeferredMgr::RIT_Deferred("Deferred");
 const String RenderDeferredMgr::ColorBufferName("color");
 const String RenderDeferredMgr::ColorBufferName("color");
 const String RenderDeferredMgr::MatInfoBufferName("matinfo");
 const String RenderDeferredMgr::MatInfoBufferName("matinfo");
+const String RenderDeferredMgr::LightMapBufferName("indirectLighting");
 
 
 IMPLEMENT_CONOBJECT(RenderDeferredMgr);
 IMPLEMENT_CONOBJECT(RenderDeferredMgr);
 
 
@@ -101,6 +102,7 @@ RenderDeferredMgr::RenderDeferredMgr( bool gatherDepth,
    mNamedTarget.registerWithName( BufferName );
    mNamedTarget.registerWithName( BufferName );
    mColorTarget.registerWithName( ColorBufferName );
    mColorTarget.registerWithName( ColorBufferName );
    mMatInfoTarget.registerWithName( MatInfoBufferName );
    mMatInfoTarget.registerWithName( MatInfoBufferName );
+   mLightMapTarget.registerWithName( LightMapBufferName );
 
 
    mClearGBufferShader = NULL;
    mClearGBufferShader = NULL;
 
 
@@ -113,6 +115,7 @@ RenderDeferredMgr::~RenderDeferredMgr()
 
 
    mColorTarget.release();
    mColorTarget.release();
    mMatInfoTarget.release();
    mMatInfoTarget.release();
+   mLightMapTarget.release();
    _unregisterFeatures();
    _unregisterFeatures();
    SAFE_DELETE( mDeferredMatInstance );
    SAFE_DELETE( mDeferredMatInstance );
 }
 }
@@ -136,6 +139,7 @@ bool RenderDeferredMgr::setTargetSize(const Point2I &newTargetSize)
    mNamedTarget.setViewport( GFX->getViewport() );
    mNamedTarget.setViewport( GFX->getViewport() );
    mColorTarget.setViewport( GFX->getViewport() );
    mColorTarget.setViewport( GFX->getViewport() );
    mMatInfoTarget.setViewport( GFX->getViewport() );
    mMatInfoTarget.setViewport( GFX->getViewport() );
+   mLightMapTarget.setViewport( GFX->getViewport() );
    return ret;
    return ret;
 }
 }
 
 
@@ -182,32 +186,18 @@ bool RenderDeferredMgr::_updateTargets()
          mTargetChain[i]->attachTexture(GFXTextureTarget::Color2, mMatInfoTarget.getTexture());
          mTargetChain[i]->attachTexture(GFXTextureTarget::Color2, mMatInfoTarget.getTexture());
    }
    }
 
 
-   GFX->finalizeReset();
-
-   // Attach the light info buffer as a second render target, if there is
-   // lightmapped geometry in the scene.
-   AdvancedLightBinManager *lightBin;
-   if (  Sim::findObject( "AL_LightBinMgr", lightBin ) &&
-         lightBin->MRTLightmapsDuringDeferred() &&
-         lightBin->isProperlyAdded() )
+   if (mLightMapTex.getFormat() != mTargetFormat || mLightMapTex.getWidthHeight() != mTargetSize || GFX->recentlyReset())
    {
    {
-      // Update the size of the light bin target here. This will call _updateTargets
-      // on the light bin
-      ret &= lightBin->setTargetSize( mTargetSize );
-      if ( ret )
-      {
-         // Sanity check
-         AssertFatal(lightBin->getTargetChainLength() == mTargetChainLength, "Target chain length mismatch");
+      mLightMapTarget.release();
+      mLightMapTex.set(mTargetSize.x, mTargetSize.y, mTargetFormat,
+         &GFXRenderTargetProfile, avar("%s() - (line %d)", __FUNCTION__, __LINE__),
+         1, GFXTextureManager::AA_MATCH_BACKBUFFER);
+      mLightMapTarget.setTexture(mLightMapTex);
 
 
-         // Attach light info buffer to Color1 for each target in the chain
-         for ( U32 i = 0; i < mTargetChainLength; i++ )
-         {
-            GFXTexHandle lightInfoTex = lightBin->getTargetTexture(0, i);
-            mTargetChain[i]->attachTexture(GFXTextureTarget::Color3, lightInfoTex);
-         }
-      }
+      for (U32 i = 0; i < mTargetChainLength; i++)
+         mTargetChain[i]->attachTexture(GFXTextureTarget::Color3, mLightMapTarget.getTexture());
    }
    }
-
+   GFX->finalizeReset();
    _initShaders();
    _initShaders();
 
 
    return ret;
    return ret;
@@ -255,10 +245,6 @@ void RenderDeferredMgr::addElement( RenderInst *inst )
 
 
    if (matInst)
    if (matInst)
    {
    {
-      // Skip decals if they don't have normal maps.
-      if (isDecalMeshInst && !matInst->hasNormalMap())
-         return;
-
       // If its a custom material and it refracts... skip it.
       // If its a custom material and it refracts... skip it.
       if (matInst->isCustomMaterial() &&
       if (matInst->isCustomMaterial() &&
          static_cast<CustomMaterial*>(matInst->getMaterial())->mRefract)
          static_cast<CustomMaterial*>(matInst->getMaterial())->mRefract)
@@ -631,19 +617,18 @@ void ProcessedDeferredMaterial::_determineFeatures( U32 stageNum,
       newFeatures.addFeature(MFT_DiffuseMap);
       newFeatures.addFeature(MFT_DiffuseMap);
    }
    }
    newFeatures.addFeature( MFT_DiffuseColor );
    newFeatures.addFeature( MFT_DiffuseColor );
+   
+   if (mMaterial->mInvertSmoothness[stageNum])
+      newFeatures.addFeature(MFT_InvertSmoothness);
 
 
    // Deferred Shading : Specular
    // Deferred Shading : Specular
    if( mStages[stageNum].getTex( MFT_SpecularMap ) )
    if( mStages[stageNum].getTex( MFT_SpecularMap ) )
    {
    {
        newFeatures.addFeature( MFT_DeferredSpecMap );
        newFeatures.addFeature( MFT_DeferredSpecMap );
    }
    }
-   else if ( mMaterial->mPixelSpecular[stageNum] )
-   {
-       newFeatures.addFeature( MFT_DeferredSpecVars );
-   }
    else
    else
-       newFeatures.addFeature(MFT_DeferredEmptySpec);
-   
+       newFeatures.addFeature( MFT_DeferredSpecVars );
+
    // Deferred Shading : Material Info Flags
    // Deferred Shading : Material Info Flags
    newFeatures.addFeature( MFT_DeferredMatInfoFlags );
    newFeatures.addFeature( MFT_DeferredMatInfoFlags );
 
 
@@ -751,7 +736,19 @@ void ProcessedDeferredMaterial::_determineFeatures( U32 stageNum,
    if ( stageNum < 1 && 
    if ( stageNum < 1 && 
          (  (  mMaterial->mCubemapData && mMaterial->mCubemapData->mCubemap ) ||
          (  (  mMaterial->mCubemapData && mMaterial->mCubemapData->mCubemap ) ||
                mMaterial->mDynamicCubemap ) )
                mMaterial->mDynamicCubemap ) )
-   newFeatures.addFeature( MFT_CubeMap );
+   {
+      if (!mMaterial->mDynamicCubemap)
+         fd.features.addFeature(MFT_StaticCubemap);
+      newFeatures.addFeature( MFT_CubeMap );
+   }
+   if (mMaterial->mVertLit[stageNum])
+      newFeatures.addFeature(MFT_VertLit);
+
+   if (mMaterial->mMinnaertConstant[stageNum] > 0.0f)
+      newFeatures.addFeature(MFT_MinnaertShading);
+
+   if (mMaterial->mSubSurface[stageNum])
+      newFeatures.addFeature(MFT_SubSurface);
    
    
 #endif
 #endif
 
 
@@ -1057,25 +1054,26 @@ Var* LinearEyeDepthConditioner::printMethodHeader( MethodType methodType, const
          bufferSample->setType("float4");
          bufferSample->setType("float4");
       DecOp *bufferSampleDecl = new DecOp(bufferSample);
       DecOp *bufferSampleDecl = new DecOp(bufferSample);
 
 
-      meta->addStatement( new GenOp( "@(@, @)\r\n", methodDecl, deferredSamplerDecl, screenUVDecl ) );
+      if (deferredTex)
+         meta->addStatement(new GenOp("@(@, @, @)\r\n", methodDecl, deferredSamplerDecl, deferredTexDecl, screenUVDecl));
+      else
+         meta->addStatement(new GenOp("@(@, @)\r\n", methodDecl, deferredSamplerDecl, screenUVDecl));
 
 
-      meta->addStatement( new GenOp( "{\r\n" ) );
+      meta->addStatement(new GenOp("{\r\n"));
 
 
-      meta->addStatement( new GenOp( "   // Sampler g-buffer\r\n" ) );
+      meta->addStatement(new GenOp("   // Sampler g-buffer\r\n"));
 
 
       // The linear depth target has no mipmaps, so use tex2dlod when
       // The linear depth target has no mipmaps, so use tex2dlod when
       // possible so that the shader compiler can optimize.
       // possible so that the shader compiler can optimize.
-      meta->addStatement( new GenOp( "   #if TORQUE_SM >= 30\r\n" ) );
       if (GFX->getAdapterType() == OpenGL)
       if (GFX->getAdapterType() == OpenGL)
-         meta->addStatement( new GenOp( "    @ = textureLod(@, @, 0); \r\n", bufferSampleDecl, deferredSampler, screenUV) );
+         meta->addStatement(new GenOp("@ = texture2DLod(@, @, 0); \r\n", bufferSampleDecl, deferredSampler, screenUV));
       else
       else
-         meta->addStatement( new GenOp( "      @ = tex2Dlod(@, float4(@,0,0));\r\n", bufferSampleDecl, deferredSampler, screenUV ) );
-      meta->addStatement( new GenOp( "   #else\r\n" ) );
-      if (GFX->getAdapterType() == OpenGL)
-         meta->addStatement( new GenOp( "    @ = texture(@, @);\r\n", bufferSampleDecl, deferredSampler, screenUV) );
-      else
-         meta->addStatement( new GenOp( "      @ = tex2D(@, @);\r\n", bufferSampleDecl, deferredSampler, screenUV ) );
-      meta->addStatement( new GenOp( "   #endif\r\n\r\n" ) );
+      {
+         if (deferredTex)
+            meta->addStatement(new GenOp("@ = @.SampleLevel(@, @, 0);\r\n", bufferSampleDecl, deferredTex, deferredSampler, screenUV));
+         else
+            meta->addStatement(new GenOp("@ = tex2Dlod(@, float4(@,0,0));\r\n", bufferSampleDecl, deferredSampler, screenUV));
+      }
 
 
       // We don't use this way of passing var's around, so this should cause a crash
       // We don't use this way of passing var's around, so this should cause a crash
       // if something uses this improperly
       // if something uses this improperly
@@ -1116,8 +1114,6 @@ void RenderDeferredMgr::_initShaders()
 
 
    // Set up shader constants.
    // Set up shader constants.
    mShaderConsts = mClearGBufferShader->allocConstBuffer();
    mShaderConsts = mClearGBufferShader->allocConstBuffer();
-   mSpecularStrengthSC = mClearGBufferShader->getShaderConstHandle( "$specularStrength" );
-   mSpecularPowerSC = mClearGBufferShader->getShaderConstHandle( "$specularPower" );
 }
 }
 
 
 void RenderDeferredMgr::clearBuffers()
 void RenderDeferredMgr::clearBuffers()

+ 4 - 3
Engine/source/renderInstance/renderDeferredMgr.h

@@ -46,6 +46,7 @@ public:
    // andremwac: Deferred Rendering
    // andremwac: Deferred Rendering
    static const String ColorBufferName;
    static const String ColorBufferName;
    static const String MatInfoBufferName;
    static const String MatInfoBufferName;
+   static const String LightMapBufferName;
 
 
    // Generic Deferred Render Instance Type
    // Generic Deferred Render Instance Type
    static const RenderInstType RIT_Deferred;
    static const RenderInstType RIT_Deferred;
@@ -104,11 +105,11 @@ protected:
    GFXStateBlockRef                    mStateblock;
    GFXStateBlockRef                    mStateblock;
    NamedTexTarget                      mColorTarget;
    NamedTexTarget                      mColorTarget;
    NamedTexTarget                      mMatInfoTarget;
    NamedTexTarget                      mMatInfoTarget;
+   NamedTexTarget                      mLightMapTarget;
    GFXTexHandle                        mColorTex;
    GFXTexHandle                        mColorTex;
    GFXTexHandle                        mMatInfoTex;
    GFXTexHandle                        mMatInfoTex;
-   GFXShaderConstBufferRef             mShaderConsts;
-   GFXShaderConstHandle                *mSpecularStrengthSC;  
-   GFXShaderConstHandle                *mSpecularPowerSC;
+   GFXTexHandle                        mLightMapTex;
+   GFXShaderConstBufferRef             mShaderConsts; 
 
 
 public:
 public:
    void clearBuffers();
    void clearBuffers();

+ 45 - 1
Engine/source/renderInstance/renderTranslucentMgr.cpp

@@ -64,7 +64,7 @@ void RenderTranslucentMgr::setupSGData(MeshRenderInst *ri, SceneData &data )
 
 
    // We do not support these in the translucent bin.
    // We do not support these in the translucent bin.
    data.backBuffTex = NULL;
    data.backBuffTex = NULL;
-   data.cubemap = NULL;   
+   //data.cubemap = NULL;   
    data.lightmap = NULL;
    data.lightmap = NULL;
 }
 }
 
 
@@ -143,6 +143,13 @@ void RenderTranslucentMgr::render( SceneRenderState *state )
 
 
    GFXDEBUGEVENT_SCOPE(RenderTranslucentMgr_Render, ColorI::BLUE);
    GFXDEBUGEVENT_SCOPE(RenderTranslucentMgr_Render, ColorI::BLUE);
 
 
+   // init loop data
+   GFXTextureObject *lastLM = NULL;
+   GFXCubemap *lastCubemap = NULL;
+   GFXTextureObject *lastReflectTex = NULL;
+   GFXTextureObject *lastMiscTex = NULL;
+   GFXTextureObject *lastAccuTex = NULL;
+
    // Find the particle render manager (if we don't have it)
    // Find the particle render manager (if we don't have it)
    if(mParticleRenderMgr == NULL)
    if(mParticleRenderMgr == NULL)
    {
    {
@@ -263,6 +270,43 @@ void RenderTranslucentMgr::render( SceneRenderState *state )
                   continue;
                   continue;
                }
                }
 
 
+               bool dirty = false;
+
+               // set the lightmaps if different
+               if (passRI->lightmap && passRI->lightmap != lastLM)
+               {
+                  sgData.lightmap = passRI->lightmap;
+                  lastLM = passRI->lightmap;
+                  dirty = true;
+               }
+
+               // set the cubemap if different.
+               if (passRI->cubemap != lastCubemap)
+               {
+                  sgData.cubemap = passRI->cubemap;
+                  lastCubemap = passRI->cubemap;
+                  dirty = true;
+               }
+
+               if (passRI->reflectTex != lastReflectTex)
+               {
+                  sgData.reflectTex = passRI->reflectTex;
+                  lastReflectTex = passRI->reflectTex;
+                  dirty = true;
+               }
+
+               // Update accumulation texture if it changed.
+               // Note: accumulation texture can be NULL, and must be updated.
+               if (passRI->accuTex != lastAccuTex)
+               {
+                  sgData.accuTex = passRI->accuTex;
+                  lastAccuTex = lastAccuTex;
+                  dirty = true;
+               }
+
+               if (dirty)
+                  mat->setTextureStages(state, sgData);
+
                // Setup the vertex and index buffers.
                // Setup the vertex and index buffers.
                mat->setBuffers( passRI->vertBuff, passRI->primBuff );
                mat->setBuffers( passRI->vertBuff, passRI->primBuff );
 
 

+ 1 - 1
Engine/source/scene/culling/sceneCullingState.cpp

@@ -36,7 +36,7 @@
 extern bool gEditingMission;
 extern bool gEditingMission;
 
 
 
 
-bool SceneCullingState::smDisableTerrainOcclusion = false;
+bool SceneCullingState::smDisableTerrainOcclusion = true;
 bool SceneCullingState::smDisableZoneCulling = false;
 bool SceneCullingState::smDisableZoneCulling = false;
 U32 SceneCullingState::smMaxOccludersPerZone = 4;
 U32 SceneCullingState::smMaxOccludersPerZone = 4;
 F32 SceneCullingState::smOccluderMinWidthPercentage = 0.1f;
 F32 SceneCullingState::smOccluderMinWidthPercentage = 0.1f;

+ 13 - 1
Engine/source/shaderGen/GLSL/pixSpecularGLSL.cpp

@@ -140,8 +140,20 @@ void SpecularMapGLSL::processPix( Vector<ShaderComponent*> &componentList, const
    LangElement *texOp = new GenOp( "texture(@, @)", specularMap, texCoord );
    LangElement *texOp = new GenOp( "texture(@, @)", specularMap, texCoord );
 
 
    Var *specularColor = new Var( "specularColor", "vec4" );
    Var *specularColor = new Var( "specularColor", "vec4" );
+   Var *metalness = (Var*)LangElement::find("metalness");
+   if (!metalness) metalness = new Var("metalness", "float");
+   Var *smoothness = (Var*)LangElement::find("smoothness");
+   if (!smoothness) smoothness = new Var("smoothness", "float");
+   MultiLine * meta = new MultiLine;
 
 
-   output = new GenOp( "   @ = @;\r\n", new DecOp( specularColor ), texOp );
+   meta->addStatement(new GenOp("   @ = @.r;\r\n", new DecOp(smoothness), texOp));
+   meta->addStatement(new GenOp("   @ = @.b;\r\n", new DecOp(metalness), texOp));
+
+   if (fd.features[MFT_InvertSmoothness])
+      meta->addStatement(new GenOp("   @ = 1.0-@;\r\n", smoothness, smoothness));
+
+   meta->addStatement(new GenOp("   @ = @.ggga;\r\n", new DecOp(specularColor), texOp));
+   output = meta;
 }
 }
 
 
 ShaderFeature::Resources SpecularMapGLSL::getResources( const MaterialFeatureData &fd )
 ShaderFeature::Resources SpecularMapGLSL::getResources( const MaterialFeatureData &fd )

+ 59 - 28
Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp

@@ -1794,12 +1794,10 @@ void ReflectCubeFeatGLSL::processPix(  Vector<ShaderComponent*> &componentList,
          meta->addStatement( new GenOp( "   @ = tex2D( @, @ );\r\n", colorDecl, newMap, inTex ) );
          meta->addStatement( new GenOp( "   @ = tex2D( @, @ );\r\n", colorDecl, newMap, inTex ) );
       }
       }
    }
    }
-   else
+   if (!glossColor)
    {
    {
       if (fd.features[MFT_isDeferred])
       if (fd.features[MFT_isDeferred])
          glossColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget1));
          glossColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget1));
-      if (!glossColor)
-         glossColor = (Var*)LangElement::find("specularColor");  
       if (!glossColor)
       if (!glossColor)
          glossColor = (Var*)LangElement::find("diffuseColor");
          glossColor = (Var*)LangElement::find("diffuseColor");
       if (!glossColor)
       if (!glossColor)
@@ -1821,6 +1819,12 @@ void ReflectCubeFeatGLSL::processPix(  Vector<ShaderComponent*> &componentList,
    cubeMap->sampler = true;
    cubeMap->sampler = true;
    cubeMap->constNum = Var::getTexUnitNum();     // used as texture unit num here
    cubeMap->constNum = Var::getTexUnitNum();     // used as texture unit num here
 
 
+   Var *cubeMips = new Var;
+   cubeMips->setType("float");
+   cubeMips->setName("cubeMips");
+   cubeMips->uniform = true;
+   cubeMips->constSortPos = cspPotentialPrimitive;
+
    // TODO: Restore the lighting attenuation here!
    // TODO: Restore the lighting attenuation here!
    Var *attn = NULL;
    Var *attn = NULL;
    //if ( fd.materialFeatures[MFT_DynamicLight] )
    //if ( fd.materialFeatures[MFT_DynamicLight] )
@@ -1831,18 +1835,12 @@ void ReflectCubeFeatGLSL::processPix(  Vector<ShaderComponent*> &componentList,
 
 
    LangElement *texCube = NULL;
    LangElement *texCube = NULL;
    Var* matinfo = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
    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(  @, @, (([email protected])*6) )", cubeMap, reflectVec, matinfo);
-   }
-   else if(glossColor) //failing that, rtry and find color data
-      texCube = new GenOp("textureLod( @, @, @.a*5)", cubeMap, reflectVec, glossColor);
-   else
+   Var *smoothness = (Var*)LangElement::find("smoothness");
+   if (smoothness) //try to grab smoothness directly
+      texCube = new GenOp("textureLod(  @, @, min((1.0 - @)*@ + 1.0, @))", cubeMap, reflectVec, smoothness, cubeMips, cubeMips);
+   else if (glossColor) //failing that, try and find color data
+      texCube = new GenOp("textureLod( @, @, min((1.0 - @.b)*@ + 1.0, @))", cubeMap, reflectVec, glossColor, cubeMips, cubeMips);
+   else //failing *that*, just draw the cubemap
       texCube = new GenOp("texture( @, @)", cubeMap, reflectVec);
       texCube = new GenOp("texture( @, @)", cubeMap, reflectVec);
       
       
    LangElement *lerpVal = NULL;
    LangElement *lerpVal = NULL;
@@ -1872,13 +1870,34 @@ void ReflectCubeFeatGLSL::processPix(  Vector<ShaderComponent*> &componentList,
       else
       else
          blendOp = Material::Mul;
          blendOp = Material::Mul;
    }
    }
+   
+   Var* targ = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget3));
    if (fd.features[MFT_isDeferred])
    if (fd.features[MFT_isDeferred])
    {
    {
-      Var* targ = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget1));
-      meta->addStatement(new GenOp("   @.rgb = lerp( @.rgb, (@).rgb, (@.b));\r\n", targ, targ, texCube, lerpVal));
+      //metalness: black(0) = color, white(1) = reflection
+      if (fd.features[MFT_ToneMap])
+         meta->addStatement(new GenOp("   @ *= @;\r\n", targ, texCube));
+      else
+         meta->addStatement(new GenOp("   @ = @;\r\n", targ, texCube));
    }
    }
    else
    else
-        meta->addStatement( new GenOp( "   @;\r\n", assignColor( texCube, blendOp, lerpVal ) ) );         
+   {
+      meta->addStatement(new GenOp("   //forward lit cubemapping\r\n"));
+      targ = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
+
+      Var *metalness = (Var*)LangElement::find("metalness");
+      if (metalness)
+      {
+         Var *dColor = new Var("dColor", "vec3");
+         Var *envColor = new Var("envColor", "vec3");
+         meta->addStatement(new GenOp("   @ = @.rgb - (@.rgb * @);\r\n", new DecOp(dColor), targ, targ, metalness));
+         meta->addStatement(new GenOp("   @ = @.rgb*(@).rgb;\r\n", new DecOp(envColor), targ, texCube));
+      }
+      else if (lerpVal)
+         meta->addStatement(new GenOp("   @ *= vec4(@.rgb*@.a, @.a);\r\n", targ, texCube, lerpVal, targ));
+      else
+         meta->addStatement(new GenOp("   @.rgb *= @.rgb;\r\n", targ, texCube));
+   }
    output = meta;
    output = meta;
 }
 }
 
 
@@ -2109,28 +2128,40 @@ void RTLightingFeatGLSL::processPix(   Vector<ShaderComponent*> &componentList,
    lightSpotFalloff->uniform = true;
    lightSpotFalloff->uniform = true;
    lightSpotFalloff->constSortPos = cspPotentialPrimitive;
    lightSpotFalloff->constSortPos = cspPotentialPrimitive;
 
 
-   Var *specularPower  = new Var( "specularPower", "float" );
-   specularPower->uniform = true;
-   specularPower->constSortPos = cspPotentialPrimitive;
+   Var *smoothness = (Var*)LangElement::find("smoothness");
+   if (!fd.features[MFT_SpecularMap])
+   {
+      if (!smoothness)
+      {
+         smoothness = new Var("smoothness", "float");
+         smoothness->uniform = true;
+         smoothness->constSortPos = cspPotentialPrimitive;
+      }
+   }
 
 
-   Var *specularColor = (Var*)LangElement::find( "specularColor" );
-   if ( !specularColor )
+   Var *metalness = (Var*)LangElement::find("metalness");
+   if (!fd.features[MFT_SpecularMap])
    {
    {
-      specularColor  = new Var( "specularColor", "vec4" );
-      specularColor->uniform = true;
-      specularColor->constSortPos = cspPotentialPrimitive;
+      if (!metalness)
+      {
+         metalness = new Var("metalness", "float");
+         metalness->uniform = true;
+         metalness->constSortPos = cspPotentialPrimitive;
+      }
    }
    }
 
 
+   Var *albedo = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
+
    Var *ambient  = new Var( "ambient", "vec4" );
    Var *ambient  = new Var( "ambient", "vec4" );
    ambient->uniform = true;
    ambient->uniform = true;
    ambient->constSortPos = cspPass;
    ambient->constSortPos = cspPass;
 
 
    // Calculate the diffuse shading and specular powers.
    // Calculate the diffuse shading and specular powers.
    meta->addStatement( new GenOp( "   compute4Lights( @, @, @, @,\r\n"
    meta->addStatement( new GenOp( "   compute4Lights( @, @, @, @,\r\n"
-                                  "      @, @, @, @, @, @, @, @,\r\n"
+                                  "      @, @, @, @, @, @, @, @, @,\r\n"
                                   "      @, @ );\r\n", 
                                   "      @, @ );\r\n", 
       wsView, wsPosition, wsNormal, lightMask,
       wsView, wsPosition, wsNormal, lightMask,
-      inLightPos, inLightInvRadiusSq, inLightColor, inLightSpotDir, inLightSpotAngle, lightSpotFalloff, specularPower, specularColor,
+      inLightPos, inLightInvRadiusSq, inLightColor, inLightSpotDir, inLightSpotAngle, lightSpotFalloff, smoothness, metalness, albedo,
       rtShading, specular ) );
       rtShading, specular ) );
 
 
    // Apply the lighting to the diffuse color.
    // Apply the lighting to the diffuse color.

+ 2 - 1
Engine/source/shaderGen/GLSL/shaderGenGLSLInit.cpp

@@ -63,8 +63,10 @@ void _initShaderGenGLSL( ShaderGen *shaderGen )
    FEATUREMGR->registerFeature( MFT_NormalMap, new BumpFeatGLSL );
    FEATUREMGR->registerFeature( MFT_NormalMap, new BumpFeatGLSL );
 	FEATUREMGR->registerFeature( MFT_DetailNormalMap, new NamedFeatureGLSL( "Detail Normal Map" ) );
 	FEATUREMGR->registerFeature( MFT_DetailNormalMap, new NamedFeatureGLSL( "Detail Normal Map" ) );
    FEATUREMGR->registerFeature( MFT_DetailMap, new DetailFeatGLSL );
    FEATUREMGR->registerFeature( MFT_DetailMap, new DetailFeatGLSL );
+	FEATUREMGR->registerFeature( MFT_StaticCubemap, new NamedFeatureGLSL( "Static Cubemap" ) );
    FEATUREMGR->registerFeature( MFT_CubeMap, new ReflectCubeFeatGLSL );
    FEATUREMGR->registerFeature( MFT_CubeMap, new ReflectCubeFeatGLSL );
    FEATUREMGR->registerFeature( MFT_PixSpecular, new PixelSpecularGLSL );
    FEATUREMGR->registerFeature( MFT_PixSpecular, new PixelSpecularGLSL );
+   FEATUREMGR->registerFeature( MFT_InvertSmoothness, new NamedFeatureGLSL("Roughest = 1.0"));
    FEATUREMGR->registerFeature( MFT_SpecularMap, new SpecularMapGLSL );
    FEATUREMGR->registerFeature( MFT_SpecularMap, new SpecularMapGLSL );
    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" ) );
@@ -104,7 +106,6 @@ void _initShaderGenGLSL( ShaderGen *shaderGen )
    FEATUREMGR->registerFeature( MFT_DeferredSpecMap, new DeferredSpecMapGLSL );
    FEATUREMGR->registerFeature( MFT_DeferredSpecMap, new DeferredSpecMapGLSL );
    FEATUREMGR->registerFeature( MFT_DeferredSpecVars, new DeferredSpecVarsGLSL );
    FEATUREMGR->registerFeature( MFT_DeferredSpecVars, new DeferredSpecVarsGLSL );
    FEATUREMGR->registerFeature( MFT_DeferredMatInfoFlags, new DeferredMatInfoFlagsGLSL );
    FEATUREMGR->registerFeature( MFT_DeferredMatInfoFlags, new DeferredMatInfoFlagsGLSL );
-   FEATUREMGR->registerFeature( MFT_DeferredEmptySpec, new DeferredEmptySpecGLSL );
    FEATUREMGR->registerFeature( MFT_SkyBox, new NamedFeatureGLSL( "skybox" ) );
    FEATUREMGR->registerFeature( MFT_SkyBox, new NamedFeatureGLSL( "skybox" ) );
    FEATUREMGR->registerFeature( MFT_HardwareSkinning, new HardwareSkinningFeatureGLSL );
    FEATUREMGR->registerFeature( MFT_HardwareSkinning, new HardwareSkinningFeatureGLSL );
 }
 }

+ 13 - 7
Engine/source/shaderGen/HLSL/pixSpecularHLSL.cpp

@@ -148,17 +148,23 @@ void SpecularMapHLSL::processPix( Vector<ShaderComponent*> &componentList, const
    specularMapTex->uniform = true;
    specularMapTex->uniform = true;
    specularMapTex->texture = true;
    specularMapTex->texture = true;
    specularMapTex->constNum = specularMap->constNum;
    specularMapTex->constNum = specularMap->constNum;
+   LangElement *texOp = new GenOp("@.Sample(@, @)", specularMapTex, specularMap, texCoord);
 
 
-   LangElement *texOp = NULL;
 
 
-   if (specularMapTex)
-      texOp = new GenOp("@.Sample(@, @)", specularMapTex, specularMap, texCoord);
-   else
-      texOp = new GenOp("tex2D(@, @)", specularMap, texCoord);
+   Var *specularColor = new Var( "specularColor", "float4" );
+   Var *metalness = (Var*)LangElement::find("metalness");
+   if (!metalness) metalness = new Var("metalness", "float");
+   Var *smoothness = (Var*)LangElement::find("smoothness");
+   if (!smoothness) smoothness = new Var("smoothness", "float");
+   MultiLine * meta = new MultiLine;
 
 
-   Var *specularColor = new Var("specularColor", "float4");
+   meta->addStatement(new GenOp("   @ = @.r;\r\n", new DecOp(smoothness), texOp));
+   meta->addStatement(new GenOp("   @ = @.b;\r\n", new DecOp(metalness), texOp));
 
 
-   output = new GenOp("   @ = @;\r\n", new DecOp(specularColor), texOp);
+   if (fd.features[MFT_InvertSmoothness])
+      meta->addStatement(new GenOp("   @ = 1.0-@;\r\n", smoothness, smoothness));
+   meta->addStatement(new GenOp("   @ = @.ggga;\r\n", new DecOp(specularColor), texOp));
+   output = meta;
 }
 }
 
 
 ShaderFeature::Resources SpecularMapHLSL::getResources( const MaterialFeatureData &fd )
 ShaderFeature::Resources SpecularMapHLSL::getResources( const MaterialFeatureData &fd )

+ 67 - 40
Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp

@@ -1842,12 +1842,12 @@ void ReflectCubeFeatHLSL::processPix(  Vector<ShaderComponent*> &componentList,
           meta->addStatement(new GenOp("   @ = @.Sample( @, @ );\r\n", colorDecl, glowMapTex, newMap, inTex));
           meta->addStatement(new GenOp("   @ = @.Sample( @, @ );\r\n", colorDecl, glowMapTex, newMap, inTex));
       }
       }
    }
    }
-   else
+   if (!glossColor)
    {
    {
       if (fd.features[MFT_isDeferred])
       if (fd.features[MFT_isDeferred])
          glossColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget1));
          glossColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget1));
-      if (!glossColor)
-         glossColor = (Var*)LangElement::find("specularColor");
+      //if (!glossColor)
+         //glossColor = (Var*)LangElement::find("specularColor"); 
       if (!glossColor)
       if (!glossColor)
          glossColor = (Var*)LangElement::find("diffuseColor");
          glossColor = (Var*)LangElement::find("diffuseColor");
       if (!glossColor)
       if (!glossColor)
@@ -1876,6 +1876,12 @@ void ReflectCubeFeatHLSL::processPix(  Vector<ShaderComponent*> &componentList,
    cubeMapTex->texture = true;
    cubeMapTex->texture = true;
    cubeMapTex->constNum = cubeMap->constNum;
    cubeMapTex->constNum = cubeMap->constNum;
 
 
+   Var *cubeMips = new Var;
+   cubeMips->setType("float");
+   cubeMips->setName("cubeMips");
+   cubeMips->uniform = true;
+   cubeMips->constSortPos = cspPotentialPrimitive;
+
    // TODO: Restore the lighting attenuation here!
    // TODO: Restore the lighting attenuation here!
    Var *attn = NULL;
    Var *attn = NULL;
    //if ( fd.materialFeatures[MFT_DynamicLight] )
    //if ( fd.materialFeatures[MFT_DynamicLight] )
@@ -1886,32 +1892,19 @@ void ReflectCubeFeatHLSL::processPix(  Vector<ShaderComponent*> &componentList,
       
       
    LangElement *texCube = NULL;
    LangElement *texCube = NULL;
    Var* matinfo = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget2) );
    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 );
+   Var *smoothness = (Var*)LangElement::find("smoothness");
 
 
-      if (fd.features[MFT_DeferredSpecMap])
-      {
-         texCube = new GenOp("@.SampleLevel( @, @, @.a*5)", cubeMapTex, cubeMap, reflectVec, matinfo);
-      }
-      else
-      {
-         texCube = new GenOp("@.SampleLevel( @, @, ([email protected])*6 )", cubeMapTex, cubeMap, reflectVec, matinfo);
-      }
+   if (smoothness) //try to grab smoothness directly
+   {
+      texCube = new GenOp("@.SampleLevel( @, float3(@).rgb, min((1.0 - @)*@ + 1.0, @))", cubeMapTex, cubeMap, reflectVec, smoothness, cubeMips, cubeMips);
    }
    }
-   else
+   else if (glossColor)//failing that, try and find color data
    {
    {
-      if (glossColor) //failing that, rtry and find color data
-      {
-         texCube = new GenOp("@.SampleLevel( @, @, @.a*5)", cubeMapTex, cubeMap, reflectVec, glossColor);
-      }
-      else //failing *that*, just draw the cubemap
-      {
-         texCube = new GenOp("@.Sample( @, @ )", cubeMapTex, cubeMap, reflectVec);
-      }
+      texCube = new GenOp("@.SampleLevel( @, float3(@).rgb, min((1.0 - @.b)*@ + 1.0, @))", cubeMapTex, cubeMap, reflectVec, glossColor, cubeMips, cubeMips);
+   }
+   else //failing *that*, just draw the cubemap
+   {
+      texCube = new GenOp("@.Sample( @, @ )", cubeMapTex, cubeMap, reflectVec);
    }
    }
 
 
    LangElement *lerpVal = NULL;
    LangElement *lerpVal = NULL;
@@ -1941,13 +1934,35 @@ void ReflectCubeFeatHLSL::processPix(  Vector<ShaderComponent*> &componentList,
       else
       else
          blendOp = Material::Mul;
          blendOp = Material::Mul;
    }
    }
+   
+   Var* targ = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget3));
    if (fd.features[MFT_isDeferred])
    if (fd.features[MFT_isDeferred])
    {
    {
-      Var* targ = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget1));
-      meta->addStatement(new GenOp("   @.rgb = lerp( @.rgb, (@).rgb, (@.b));\r\n", targ, targ, texCube, lerpVal));
+       //metalness: black(0) = color, white(1) = reflection
+       if (fd.features[MFT_ToneMap])
+          meta->addStatement(new GenOp("   @ *= @;\r\n", targ, texCube));
+       else
+          meta->addStatement(new GenOp("   @ = @;\r\n", targ, texCube));
    }
    }
    else
    else
-       meta->addStatement( new GenOp( "   @;\r\n", assignColor( texCube, blendOp, lerpVal ) ) );         
+   {
+      meta->addStatement(new GenOp("   //forward lit cubemapping\r\n"));
+      targ = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
+      
+      Var *metalness = (Var*)LangElement::find("metalness");
+      if (metalness)
+      {
+         Var *dColor = new Var("dColor", "float3");
+         Var *reflectColor = new Var("reflectColor", "float3");
+         meta->addStatement(new GenOp("   @ = @.rgb - (@.rgb * @);\r\n", new DecOp(dColor), targ, targ, metalness));
+         meta->addStatement(new GenOp("   @ = @.rgb*(@).rgb*@;\r\n", new DecOp(reflectColor), targ, texCube, metalness));
+         meta->addStatement(new GenOp("   @.rgb = @+@;\r\n", targ, dColor, reflectColor));
+      }
+      else if (lerpVal)
+         meta->addStatement(new GenOp("   @ *= float4(@.rgb*@.a, @.a);\r\n", targ, texCube, lerpVal, targ));
+      else
+         meta->addStatement(new GenOp("   @.rgb *= @.rgb;\r\n", targ, texCube));
+   }
    output = meta;
    output = meta;
 }
 }
 
 
@@ -2177,29 +2192,41 @@ void RTLightingFeatHLSL::processPix(   Vector<ShaderComponent*> &componentList,
    Var *lightSpotFalloff  = new Var( "inLightSpotFalloff", "float4" );
    Var *lightSpotFalloff  = new Var( "inLightSpotFalloff", "float4" );
    lightSpotFalloff->uniform = true;
    lightSpotFalloff->uniform = true;
    lightSpotFalloff->constSortPos = cspPotentialPrimitive;
    lightSpotFalloff->constSortPos = cspPotentialPrimitive;
+   
+   Var *smoothness = (Var*)LangElement::find("smoothness");
+   if (!fd.features[MFT_SpecularMap])
+   {
+      if (!smoothness)
+      {
+         smoothness = new Var("smoothness", "float");
+         smoothness->uniform = true;
+         smoothness->constSortPos = cspPotentialPrimitive;
+      }
+   }
 
 
-   Var *specularPower  = new Var( "specularPower", "float" );
-   specularPower->uniform = true;
-   specularPower->constSortPos = cspPotentialPrimitive;
-
-   Var *specularColor = (Var*)LangElement::find( "specularColor" );
-   if ( !specularColor )
+   Var *metalness = (Var*)LangElement::find("metalness");
+   if (!fd.features[MFT_SpecularMap])
    {
    {
-      specularColor  = new Var( "specularColor", "float4" );
-      specularColor->uniform = true;
-      specularColor->constSortPos = cspPotentialPrimitive;
+      if (!metalness)
+      {
+         metalness = new Var("metalness", "float");
+         metalness->uniform = true;
+         metalness->constSortPos = cspPotentialPrimitive;
+      }
    }
    }
 
 
+   Var *albedo = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
+
    Var *ambient  = new Var( "ambient", "float4" );
    Var *ambient  = new Var( "ambient", "float4" );
    ambient->uniform = true;
    ambient->uniform = true;
    ambient->constSortPos = cspPass;
    ambient->constSortPos = cspPass;
 
 
    // Calculate the diffuse shading and specular powers.
    // Calculate the diffuse shading and specular powers.
    meta->addStatement( new GenOp( "   compute4Lights( @, @, @, @,\r\n"
    meta->addStatement( new GenOp( "   compute4Lights( @, @, @, @,\r\n"
-                                  "      @, @, @, @, @, @, @, @,\r\n"
+                                  "      @, @, @, @, @, @, @, @, @,\r\n"
                                   "      @, @ );\r\n", 
                                   "      @, @ );\r\n", 
       wsView, wsPosition, wsNormal, lightMask,
       wsView, wsPosition, wsNormal, lightMask,
-      inLightPos, inLightInvRadiusSq, inLightColor, inLightSpotDir, inLightSpotAngle, lightSpotFalloff, specularPower, specularColor,
+      inLightPos, inLightInvRadiusSq, inLightColor, inLightSpotDir, inLightSpotAngle, lightSpotFalloff, smoothness, metalness, albedo,
       rtShading, specular ) );
       rtShading, specular ) );
 
 
    // Apply the lighting to the diffuse color.
    // Apply the lighting to the diffuse color.

+ 2 - 1
Engine/source/shaderGen/HLSL/shaderGenHLSLInit.cpp

@@ -62,8 +62,10 @@ void _initShaderGenHLSL( ShaderGen *shaderGen )
    FEATUREMGR->registerFeature( MFT_NormalMap, new BumpFeatHLSL );
    FEATUREMGR->registerFeature( MFT_NormalMap, new BumpFeatHLSL );
    FEATUREMGR->registerFeature( MFT_DetailNormalMap, new NamedFeatureHLSL( "Detail Normal Map" ) );
    FEATUREMGR->registerFeature( MFT_DetailNormalMap, new NamedFeatureHLSL( "Detail Normal Map" ) );
    FEATUREMGR->registerFeature( MFT_DetailMap, new DetailFeatHLSL );
    FEATUREMGR->registerFeature( MFT_DetailMap, new DetailFeatHLSL );
+	FEATUREMGR->registerFeature( MFT_StaticCubemap, new NamedFeatureHLSL( "Static Cubemap" ) );
    FEATUREMGR->registerFeature( MFT_CubeMap, new ReflectCubeFeatHLSL );
    FEATUREMGR->registerFeature( MFT_CubeMap, new ReflectCubeFeatHLSL );
    FEATUREMGR->registerFeature( MFT_PixSpecular, new PixelSpecularHLSL );
    FEATUREMGR->registerFeature( MFT_PixSpecular, new PixelSpecularHLSL );
+   FEATUREMGR->registerFeature( MFT_InvertSmoothness, new NamedFeatureHLSL( "Roughest = 1.0" ) );
    FEATUREMGR->registerFeature( MFT_IsTranslucent, new NamedFeatureHLSL( "Translucent" ) );
    FEATUREMGR->registerFeature( MFT_IsTranslucent, new NamedFeatureHLSL( "Translucent" ) );
    FEATUREMGR->registerFeature( MFT_IsTranslucentZWrite, new NamedFeatureHLSL( "Translucent ZWrite" ) );
    FEATUREMGR->registerFeature( MFT_IsTranslucentZWrite, new NamedFeatureHLSL( "Translucent ZWrite" ) );
    FEATUREMGR->registerFeature( MFT_Visibility, new VisibilityFeatHLSL );
    FEATUREMGR->registerFeature( MFT_Visibility, new VisibilityFeatHLSL );
@@ -105,7 +107,6 @@ void _initShaderGenHLSL( ShaderGen *shaderGen )
    FEATUREMGR->registerFeature( MFT_DeferredSpecMap, new DeferredSpecMapHLSL );
    FEATUREMGR->registerFeature( MFT_DeferredSpecMap, new DeferredSpecMapHLSL );
    FEATUREMGR->registerFeature( MFT_DeferredSpecVars, new DeferredSpecVarsHLSL );
    FEATUREMGR->registerFeature( MFT_DeferredSpecVars, new DeferredSpecVarsHLSL );
    FEATUREMGR->registerFeature( MFT_DeferredMatInfoFlags, new DeferredMatInfoFlagsHLSL );
    FEATUREMGR->registerFeature( MFT_DeferredMatInfoFlags, new DeferredMatInfoFlagsHLSL );
-   FEATUREMGR->registerFeature( MFT_DeferredEmptySpec, new DeferredEmptySpecHLSL );
    FEATUREMGR->registerFeature( MFT_SkyBox,  new NamedFeatureHLSL( "skybox" ) );
    FEATUREMGR->registerFeature( MFT_SkyBox,  new NamedFeatureHLSL( "skybox" ) );
    FEATUREMGR->registerFeature( MFT_HardwareSkinning, new HardwareSkinningFeatureHLSL );
    FEATUREMGR->registerFeature( MFT_HardwareSkinning, new HardwareSkinningFeatureHLSL );
 }
 }

+ 2 - 2
Engine/source/shaderGen/shaderGenVars.cpp

@@ -65,8 +65,8 @@ const String ShaderGenVars::lightSpotDir("$inLightSpotDir");
 const String ShaderGenVars::lightSpotAngle("$inLightSpotAngle");
 const String ShaderGenVars::lightSpotAngle("$inLightSpotAngle");
 const String ShaderGenVars::lightSpotFalloff("$inLightSpotFalloff");
 const String ShaderGenVars::lightSpotFalloff("$inLightSpotFalloff");
 const String ShaderGenVars::specularColor("$specularColor");
 const String ShaderGenVars::specularColor("$specularColor");
-const String ShaderGenVars::specularPower("$specularPower");
-const String ShaderGenVars::specularStrength("$specularStrength");
+const String ShaderGenVars::smoothness("$smoothness");
+const String ShaderGenVars::metalness("$metalness");
 
 
 // These are ignored by the D3D layers.
 // These are ignored by the D3D layers.
 const String ShaderGenVars::fogMap("$fogMap");
 const String ShaderGenVars::fogMap("$fogMap");

+ 2 - 2
Engine/source/shaderGen/shaderGenVars.h

@@ -78,8 +78,8 @@ struct ShaderGenVars
    const static String lightSpotAngle;
    const static String lightSpotAngle;
    const static String lightSpotFalloff;
    const static String lightSpotFalloff;
    const static String specularColor;
    const static String specularColor;
-   const static String specularPower;
-   const static String specularStrength;
+   const static String smoothness;
+   const static String metalness;
    
    
    // Textures
    // Textures
    const static String fogMap;
    const static String fogMap;

+ 25 - 11
Engine/source/terrain/glsl/terrFeatureGLSL.cpp

@@ -48,10 +48,7 @@ namespace
       FEATUREMGR->registerFeature( MFT_TerrainMacroMap, new TerrainMacroMapFeatGLSL );
       FEATUREMGR->registerFeature( MFT_TerrainMacroMap, new TerrainMacroMapFeatGLSL );
       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_DeferredTerrainBaseMap, new TerrainBaseMapFeatGLSL );
-      FEATUREMGR->registerFeature( MFT_DeferredTerrainMacroMap, new TerrainMacroMapFeatGLSL );
-      FEATUREMGR->registerFeature( MFT_DeferredTerrainDetailMap, new TerrainDetailMapFeatGLSL ); 
+      FEATUREMGR->registerFeature( MFT_TerrainAdditive, new TerrainAdditiveFeatGLSL );
       FEATUREMGR->registerFeature( MFT_DeferredTerrainBlankInfoMap, new TerrainBlankInfoMapFeatGLSL );
       FEATUREMGR->registerFeature( MFT_DeferredTerrainBlankInfoMap, new TerrainBlankInfoMapFeatGLSL );
    }
    }
 
 
@@ -484,7 +481,7 @@ void TerrainDetailMapFeatGLSL::processPix(   Vector<ShaderComponent*> &component
 
 
    ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
    ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
 
 
-   if(fd.features.hasFeature( MFT_DeferredTerrainDetailMap ))
+   if (fd.features.hasFeature(MFT_isDeferred))
       target= ShaderFeature::RenderTarget1;
       target= ShaderFeature::RenderTarget1;
 
 
    Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
    Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
@@ -581,6 +578,22 @@ void TerrainDetailMapFeatGLSL::processPix(   Vector<ShaderComponent*> &component
          inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend));
          inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend));
       }
       }
    }
    }
+   
+   // 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));
+   }
 
 
    // 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.
@@ -659,7 +672,7 @@ ShaderFeature::Resources TerrainDetailMapFeatGLSL::getResources( const MaterialF
 
 
 U32 TerrainDetailMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 U32 TerrainDetailMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 {
 {
-   return fd.features[MFT_DeferredTerrainDetailMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+   return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
 }
 }
 
 
 
 
@@ -862,9 +875,10 @@ 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;
    ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
 
 
-   if(fd.features.hasFeature(MFT_DeferredTerrainMacroMap))
+   if (fd.features.hasFeature(MFT_isDeferred))
       target= ShaderFeature::RenderTarget1;
       target= ShaderFeature::RenderTarget1;
 
 
    Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
    Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
@@ -891,7 +905,7 @@ ShaderFeature::Resources TerrainMacroMapFeatGLSL::getResources( const MaterialFe
    {
    {
       // If this is the first detail pass then we 
       // If this is the first detail pass then we 
       // samples from the layer tex.
       // samples from the layer tex.
-         res.numTex += 1;
+      res.numTex += 1;
    }
    }
 
 
       res.numTex += 1;
       res.numTex += 1;
@@ -905,7 +919,7 @@ ShaderFeature::Resources TerrainMacroMapFeatGLSL::getResources( const MaterialFe
 
 
 U32 TerrainMacroMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 U32 TerrainMacroMapFeatGLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 {
 {
-   return fd.features[MFT_DeferredTerrainMacroMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+   return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
 }
 }
 
 
 void TerrainNormalMapFeatGLSL::processVert(  Vector<ShaderComponent*> &componentList, 
 void TerrainNormalMapFeatGLSL::processVert(  Vector<ShaderComponent*> &componentList, 
@@ -1068,13 +1082,13 @@ void TerrainAdditiveFeatGLSL::processPix( Vector<ShaderComponent*> &componentLis
 {
 {
    Var *color = NULL;
    Var *color = NULL;
    Var *normal = NULL;
    Var *normal = NULL;
-   if (fd.features[MFT_DeferredTerrainDetailMap])
+   if (fd.features[MFT_isDeferred])
    {
    {
        color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget1) );
        color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget1) );
        normal = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::DefaultTarget) );
        normal = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::DefaultTarget) );
    }
    }
    else
    else
-       color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::DefaultTarget) );
+      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 )

+ 52 - 29
Engine/source/terrain/hlsl/terrFeatureHLSL.cpp

@@ -48,10 +48,7 @@ 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_DeferredTerrainBaseMap, new TerrainBaseMapFeatHLSL );
-      FEATUREMGR->registerFeature( MFT_DeferredTerrainMacroMap, new TerrainMacroMapFeatHLSL );
-      FEATUREMGR->registerFeature( MFT_DeferredTerrainDetailMap, new TerrainDetailMapFeatHLSL );
+      FEATUREMGR->registerFeature( MFT_TerrainAdditive, new TerrainAdditiveFeatHLSL );  
       FEATUREMGR->registerFeature( MFT_DeferredTerrainBlankInfoMap, new TerrainBlankInfoMapFeatHLSL );
       FEATUREMGR->registerFeature( MFT_DeferredTerrainBlankInfoMap, new TerrainBlankInfoMapFeatHLSL );
    }
    }
 };
 };
@@ -295,7 +292,7 @@ ShaderFeature::Resources TerrainBaseMapFeatHLSL::getResources( const MaterialFea
 
 
 U32 TerrainBaseMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 U32 TerrainBaseMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 {
 {
-   return fd.features[MFT_DeferredTerrainBaseMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+   return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
 }
 }
 
 
 TerrainDetailMapFeatHLSL::TerrainDetailMapFeatHLSL()
 TerrainDetailMapFeatHLSL::TerrainDetailMapFeatHLSL()
@@ -516,6 +513,22 @@ void TerrainDetailMapFeatHLSL::processPix(   Vector<ShaderComponent*> &component
          meta->addStatement(new GenOp("   @.xy += parallaxOffset( @, @, @.xy, @, @.z * @ );\r\n",
          meta->addStatement(new GenOp("   @.xy += parallaxOffset( @, @, @.xy, @, @.z * @ );\r\n",
             inDet, normalMapTex, normalMap, inDet, negViewTS, detailInfo, detailBlend));
             inDet, normalMapTex, normalMap, inDet, negViewTS, detailInfo, detailBlend));
       }
       }
+     
+   }
+   
+   // 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));
    }
    }
 
 
    Var *detailColor = (Var*)LangElement::find( "detailColor" ); 
    Var *detailColor = (Var*)LangElement::find( "detailColor" ); 
@@ -577,7 +590,7 @@ void TerrainDetailMapFeatHLSL::processPix(   Vector<ShaderComponent*> &component
 
 
    ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
    ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
 
 
-   if(fd.features.hasFeature( MFT_DeferredTerrainDetailMap ))
+   if (fd.features.hasFeature(MFT_isDeferred))
       target= ShaderFeature::RenderTarget1;
       target= ShaderFeature::RenderTarget1;
 
 
    Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
    Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
@@ -628,7 +641,7 @@ ShaderFeature::Resources TerrainDetailMapFeatHLSL::getResources( const MaterialF
 
 
 U32 TerrainDetailMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 U32 TerrainDetailMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 {
 {
-   return fd.features[MFT_DeferredTerrainDetailMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+   return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
 }
 }
 
 
 
 
@@ -791,9 +804,25 @@ void TerrainMacroMapFeatHLSL::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));
-
-   Var *detailColor = (Var*)LangElement::find( "macroColor" ); 
-   if ( !detailColor )
+   
+   // 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 ) );
+   }
+   
+   Var *detailColor = (Var*)LangElement::find("macroColor");
+   if (!detailColor)
    {
    {
       detailColor = new Var;
       detailColor = new Var;
       detailColor->setType( "float4" );
       detailColor->setType( "float4" );
@@ -847,7 +876,7 @@ void TerrainMacroMapFeatHLSL::processPix(   Vector<ShaderComponent*> &componentL
 
 
    ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
    ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget;
 
 
-   if(fd.features.hasFeature(MFT_DeferredTerrainMacroMap))
+   if (fd.features.hasFeature(MFT_isDeferred))
       target= ShaderFeature::RenderTarget1;
       target= ShaderFeature::RenderTarget1;
 
 
    Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
    Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) );
@@ -886,7 +915,7 @@ ShaderFeature::Resources TerrainMacroMapFeatHLSL::getResources( const MaterialFe
 
 
 U32 TerrainMacroMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 U32 TerrainMacroMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const
 {
 {
-   return fd.features[MFT_DeferredTerrainMacroMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
+   return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget;
 }
 }
 
 
 void TerrainNormalMapFeatHLSL::processVert(  Vector<ShaderComponent*> &componentList, 
 void TerrainNormalMapFeatHLSL::processVert(  Vector<ShaderComponent*> &componentList, 
@@ -997,20 +1026,14 @@ void TerrainNormalMapFeatHLSL::processPix(   Vector<ShaderComponent*> &component
 ShaderFeature::Resources TerrainNormalMapFeatHLSL::getResources( const MaterialFeatureData &fd )
 ShaderFeature::Resources TerrainNormalMapFeatHLSL::getResources( const MaterialFeatureData &fd )
 {
 {
    Resources res;
    Resources res;
-
-   // We only need to process normals during the deferred.
-   if ( fd.features.hasFeature( MFT_DeferredConditioner ) )
-   {
-      // If this is the first normal map and there
-      // are no parallax features then we will 
-      // generate the worldToTanget transform.
-      if (  !fd.features.hasFeature( MFT_TerrainParallaxMap ) &&
-            ( getProcessIndex() == 0 || !fd.features.hasFeature( MFT_TerrainNormalMap, getProcessIndex() - 1 ) ) )
-         res.numTexReg = 3;
-
-      res.numTex = 1;
-   }
-
+   
+   // If this is the first normal map and there
+   // are no parallax features then we will 
+   // generate the worldToTanget transform.
+   if (  !fd.features.hasFeature( MFT_TerrainParallaxMap ) &&
+      ( getProcessIndex() == 0 || !fd.features.hasFeature( MFT_TerrainNormalMap, getProcessIndex() - 1 ) ) )
+      res.numTexReg = 3;
+   res.numTex = 1;
    return res;
    return res;
 }
 }
 
 
@@ -1068,7 +1091,7 @@ void TerrainAdditiveFeatHLSL::processPix( Vector<ShaderComponent*> &componentLis
 {
 {
    Var *color = NULL;
    Var *color = NULL;
    Var *normal = NULL;
    Var *normal = NULL;
-   if (fd.features[MFT_DeferredTerrainDetailMap])
+   if (fd.features[MFT_isDeferred])
    {
    {
        color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget1) );
        color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget1) );
        normal = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::DefaultTarget) );
        normal = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::DefaultTarget) );
@@ -1098,7 +1121,7 @@ void TerrainAdditiveFeatHLSL::processPix( Vector<ShaderComponent*> &componentLis
 
 
 U32 TerrainBlankInfoMapFeatHLSL::getOutputTargets(const MaterialFeatureData &fd) const
 U32 TerrainBlankInfoMapFeatHLSL::getOutputTargets(const MaterialFeatureData &fd) const
 {
 {
-   return fd.features[MFT_DeferredTerrainBaseMap] ? ShaderFeature::RenderTarget2 : ShaderFeature::RenderTarget1;
+   return fd.features[MFT_isDeferred] ? ShaderFeature::RenderTarget2 : ShaderFeature::RenderTarget1;
 }
 }
 
 
 void TerrainBlankInfoMapFeatHLSL::processPix(Vector<ShaderComponent*> &componentList,
 void TerrainBlankInfoMapFeatHLSL::processPix(Vector<ShaderComponent*> &componentList,
@@ -1123,7 +1146,7 @@ void TerrainBlankInfoMapFeatHLSL::processPix(Vector<ShaderComponent*> &component
       material->setStructName("OUT");
       material->setStructName("OUT");
    }
    }
 
 
-   meta->addStatement(new GenOp("   @ = float4(0.0,0.0,0.0,0.0001);\r\n", material));
+   meta->addStatement(new GenOp("   @ = float4(0.0,1.0,0.0,0.0001);\r\n", material));
 
 
    output = meta;
    output = meta;
 }
 }

+ 5 - 8
Engine/source/terrain/terrCellMaterial.cpp

@@ -356,12 +356,12 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
    {
    {
       FeatureSet features;
       FeatureSet features;
       features.addFeature( MFT_VertTransform );
       features.addFeature( MFT_VertTransform );
+      features.addFeature( MFT_TerrainBaseMap );
 
 
       if ( deferredMat )
       if ( deferredMat )
       {
       {
          features.addFeature( MFT_EyeSpaceDepthOut );
          features.addFeature( MFT_EyeSpaceDepthOut );
          features.addFeature( MFT_DeferredConditioner );
          features.addFeature( MFT_DeferredConditioner );
-         features.addFeature( MFT_DeferredTerrainBaseMap );
          features.addFeature(MFT_isDeferred);
          features.addFeature(MFT_isDeferred);
 
 
          if ( advancedLightmapSupport )
          if ( advancedLightmapSupport )
@@ -369,7 +369,6 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
       }
       }
       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
@@ -389,7 +388,7 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
 
 
       // The additional passes need to be lerp blended into the
       // The additional passes need to be lerp blended into the
       // target to maintain the results of the previous passes.
       // target to maintain the results of the previous passes.
-      if ( !firstPass )
+      if (!firstPass && deferredMat)
          features.addFeature( MFT_TerrainAdditive );
          features.addFeature( MFT_TerrainAdditive );
 
 
       normalMaps.clear();
       normalMaps.clear();
@@ -417,14 +416,12 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
          if (  !(mat->getMacroSize() <= 0 || mat->getMacroDistance() <= 0 || mat->getMacroMap().isEmpty() ) )
          if (  !(mat->getMacroSize() <= 0 || mat->getMacroDistance() <= 0 || mat->getMacroMap().isEmpty() ) )
          {
          {
             if(deferredMat)
             if(deferredMat)
-               features.addFeature( MFT_DeferredTerrainMacroMap, featureIndex );
-            else
+               features.addFeature(MFT_isDeferred, featureIndex);
 	         features.addFeature( MFT_TerrainMacroMap, featureIndex );
 	         features.addFeature( MFT_TerrainMacroMap, featureIndex );
          }
          }
 
 
          if(deferredMat)
          if(deferredMat)
-             features.addFeature( MFT_DeferredTerrainDetailMap, featureIndex );
-         else
+            features.addFeature(MFT_isDeferred, featureIndex);
          features.addFeature( MFT_TerrainDetailMap, featureIndex );
          features.addFeature( MFT_TerrainDetailMap, featureIndex );
 
 
          pass->materials.push_back( (*materials)[i] );
          pass->materials.push_back( (*materials)[i] );
@@ -840,7 +837,7 @@ bool TerrainCellMaterial::setupPass(   const SceneRenderState *state,
          pass.lightParamsConst->isValid() )
          pass.lightParamsConst->isValid() )
    {
    {
       if ( !mLightInfoTarget )
       if ( !mLightInfoTarget )
-         mLightInfoTarget = NamedTexTarget::find( "lightinfo" );
+         mLightInfoTarget = NamedTexTarget::find( "directLighting" );
 
 
       GFXTextureObject *texObject = mLightInfoTarget->getTexture();
       GFXTextureObject *texObject = mLightInfoTarget->getTexture();
       
       

+ 0 - 3
Engine/source/terrain/terrFeatureTypes.cpp

@@ -35,7 +35,4 @@ 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
 //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);
 ImplementFeatureType( MFT_DeferredTerrainBlankInfoMap, MFG_Texture, 104.1f, false);

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

@@ -36,9 +36,6 @@ DeclareFeatureType( MFT_TerrainLightMap );
 DeclareFeatureType( MFT_TerrainSideProject );
 DeclareFeatureType( MFT_TerrainSideProject );
 DeclareFeatureType( MFT_TerrainAdditive );
 DeclareFeatureType( MFT_TerrainAdditive );
 //Deferred Shading
 //Deferred Shading
-DeclareFeatureType( MFT_DeferredTerrainBaseMap );
-DeclareFeatureType( MFT_DeferredTerrainDetailMap );
-DeclareFeatureType( MFT_DeferredTerrainMacroMap );
 DeclareFeatureType( MFT_DeferredTerrainBlankInfoMap );
 DeclareFeatureType( MFT_DeferredTerrainBlankInfoMap );
 
 
 
 

+ 14 - 11
Engine/source/ts/collada/colladaAppMaterial.cpp

@@ -61,7 +61,9 @@ ColladaAppMaterial::ColladaAppMaterial(const char* matName)
 
 
    diffuseColor = LinearColorF::ONE;
    diffuseColor = LinearColorF::ONE;
    specularColor = LinearColorF::ONE;
    specularColor = LinearColorF::ONE;
-   specularPower = 8.0f;
+
+   smoothness = 0.0f;
+   metalness = 0.0f;
    doubleSided = false;
    doubleSided = false;
 }
 }
 
 
@@ -69,7 +71,8 @@ ColladaAppMaterial::ColladaAppMaterial(const domMaterial *pMat)
 :  mat(pMat),
 :  mat(pMat),
    diffuseColor(LinearColorF::ONE),
    diffuseColor(LinearColorF::ONE),
    specularColor(LinearColorF::ONE),
    specularColor(LinearColorF::ONE),
-   specularPower(8.0f),
+   smoothness(0.0f),
+   metalness(0.0f),
    doubleSided(false)
    doubleSided(false)
 {
 {
    // Get the effect element for this material
    // Get the effect element for this material
@@ -95,36 +98,36 @@ ColladaAppMaterial::ColladaAppMaterial(const domMaterial *pMat)
          const domProfile_COMMON::domTechnique::domConstant* constant = commonProfile->getTechnique()->getConstant();
          const domProfile_COMMON::domTechnique::domConstant* constant = commonProfile->getTechnique()->getConstant();
          diffuseColor.set(1.0f, 1.0f, 1.0f, 1.0f);
          diffuseColor.set(1.0f, 1.0f, 1.0f, 1.0f);
          resolveColor(constant->getReflective(), &specularColor);
          resolveColor(constant->getReflective(), &specularColor);
-         resolveFloat(constant->getReflectivity(), &specularPower);
+         resolveFloat(constant->getReflectivity(), &smoothness);
          resolveTransparency(constant, &transparency);
          resolveTransparency(constant, &transparency);
       }
       }
       else if (commonProfile->getTechnique()->getLambert()) {
       else if (commonProfile->getTechnique()->getLambert()) {
          const domProfile_COMMON::domTechnique::domLambert* lambert = commonProfile->getTechnique()->getLambert();
          const domProfile_COMMON::domTechnique::domLambert* lambert = commonProfile->getTechnique()->getLambert();
          resolveColor(lambert->getDiffuse(), &diffuseColor);
          resolveColor(lambert->getDiffuse(), &diffuseColor);
          resolveColor(lambert->getReflective(), &specularColor);
          resolveColor(lambert->getReflective(), &specularColor);
-         resolveFloat(lambert->getReflectivity(), &specularPower);
+         resolveFloat(lambert->getReflectivity(), &smoothness);
          resolveTransparency(lambert, &transparency);
          resolveTransparency(lambert, &transparency);
       }
       }
       else if (commonProfile->getTechnique()->getPhong()) {
       else if (commonProfile->getTechnique()->getPhong()) {
          const domProfile_COMMON::domTechnique::domPhong* phong = commonProfile->getTechnique()->getPhong();
          const domProfile_COMMON::domTechnique::domPhong* phong = commonProfile->getTechnique()->getPhong();
          resolveColor(phong->getDiffuse(), &diffuseColor);
          resolveColor(phong->getDiffuse(), &diffuseColor);
          resolveColor(phong->getSpecular(), &specularColor);
          resolveColor(phong->getSpecular(), &specularColor);
-         resolveFloat(phong->getShininess(), &specularPower);
+         resolveFloat(phong->getShininess(), &metalness);
          resolveTransparency(phong, &transparency);
          resolveTransparency(phong, &transparency);
       }
       }
       else if (commonProfile->getTechnique()->getBlinn()) {
       else if (commonProfile->getTechnique()->getBlinn()) {
          const domProfile_COMMON::domTechnique::domBlinn* blinn = commonProfile->getTechnique()->getBlinn();
          const domProfile_COMMON::domTechnique::domBlinn* blinn = commonProfile->getTechnique()->getBlinn();
          resolveColor(blinn->getDiffuse(), &diffuseColor);
          resolveColor(blinn->getDiffuse(), &diffuseColor);
          resolveColor(blinn->getSpecular(), &specularColor);
          resolveColor(blinn->getSpecular(), &specularColor);
-         resolveFloat(blinn->getShininess(), &specularPower);
+         resolveFloat(blinn->getShininess(), &metalness);
          resolveTransparency(blinn, &transparency);
          resolveTransparency(blinn, &transparency);
       }
       }
 
 
       // Normalize specularPower (1-128). Values > 1 are assumed to be
       // Normalize specularPower (1-128). Values > 1 are assumed to be
       // already normalized.
       // already normalized.
-      if (specularPower <= 1.0f)
-         specularPower *= 128;
-      specularPower = mClampF(specularPower, 1.0f, 128.0f);
+      if (smoothness <= 1.0f)
+          smoothness *= 128;
+      smoothness = mClampF(smoothness, 1.0f, 128.0f);
 
 
       // Set translucency
       // Set translucency
       if (transparency != 0.0f) {
       if (transparency != 0.0f) {
@@ -214,8 +217,8 @@ Material *ColladaAppMaterial::createMaterial(const Torque::Path& path) const
    newMat->mSpecularMapFilename[0] = specularMap;
    newMat->mSpecularMapFilename[0] = specularMap;
 
 
    newMat->mDiffuse[0] = diffuseColor;
    newMat->mDiffuse[0] = diffuseColor;
-   newMat->mSpecular[0] = specularColor;
-   newMat->mSpecularPower[0] = specularPower;
+   newMat->mSmoothness[0] = smoothness;
+   newMat->mMetalness[0] = metalness;
 
 
    newMat->mDoubleSided = doubleSided;
    newMat->mDoubleSided = doubleSided;
    newMat->mTranslucent = (bool)(flags & TSMaterialList::Translucent);
    newMat->mTranslucent = (bool)(flags & TSMaterialList::Translucent);

+ 5 - 3
Engine/source/ts/collada/colladaAppMaterial.h

@@ -44,9 +44,11 @@ public:
    String                     diffuseMap;
    String                     diffuseMap;
    String                     normalMap;
    String                     normalMap;
    String                     specularMap;
    String                     specularMap;
-   LinearColorF                     diffuseColor;
-   LinearColorF                     specularColor;
-   F32                        specularPower;
+
+   LinearColorF               diffuseColor;
+   LinearColorF               specularColor;
+   F32                        smoothness;
+   F32                        metalness;
    bool                       doubleSided;
    bool                       doubleSided;
 
 
    ColladaAppMaterial(const char* matName);
    ColladaAppMaterial(const char* matName);

+ 1 - 0
Templates/Full/game/art/decals/managedDecalData.cs

@@ -28,6 +28,7 @@ datablock DecalData(ScorchBigDecal)
    Material = "DECAL_scorch";
    Material = "DECAL_scorch";
    size = "5.0";
    size = "5.0";
    lifeSpan = "50000";
    lifeSpan = "50000";
+   textureCoordCount = "0";
 };
 };
 
 
 datablock DecalData(ScorchRXDecal)
 datablock DecalData(ScorchRXDecal)

BIN
Templates/Full/game/art/particles/fireplace.png


BIN
Templates/Full/game/art/particles/test.png


BIN
Templates/Full/game/art/shapes/Cheetah/Cheetah_c.dds


BIN
Templates/Full/game/art/shapes/actors/Soldier/soldier_c.png


BIN
Templates/Full/game/art/shapes/station/building01walls_c.dds


BIN
Templates/Full/game/art/shapes/station/building01walls_n.dds


BIN
Templates/Full/game/art/shapes/station/grid_c.dds


BIN
Templates/Full/game/art/shapes/station/grid_c.png


BIN
Templates/Full/game/art/shapes/station/grid_n.dds


BIN
Templates/Full/game/art/shapes/station/plate_c.dds


BIN
Templates/Full/game/art/shapes/station/plate_n.dds


BIN
Templates/Full/game/art/shapes/textures/Metal_A.png


BIN
Templates/Full/game/art/shapes/textures/Metal_N.png


BIN
Templates/Full/game/art/shapes/textures/Metal_S.png


BIN
Templates/Full/game/art/shapes/textures/PBRGrid_a.dds


BIN
Templates/Full/game/art/shapes/textures/PBRGrid_c.dds


BIN
Templates/Full/game/art/shapes/textures/PBRGrid_n.png


+ 6 - 0
Templates/Full/game/art/shapes/textures/PBRTEST.cs

@@ -0,0 +1,6 @@
+
+singleton TSShapeConstructor(PBRTESTDae)
+{
+   baseShape = "./PBRTEST.dae";
+   loadLights = "0";
+};

File diff suppressed because it is too large
+ 108 - 0
Templates/Full/game/art/shapes/textures/PBRTEST.dae


+ 11 - 0
Templates/Full/game/art/shapes/textures/PBRTEST2.cs

@@ -0,0 +1,11 @@
+
+singleton TSShapeConstructor(PBRTEST2Dae)
+{
+   baseShape = "./PBRTEST2.dae";
+};
+
+function PBRTEST2Dae::onLoad(%this)
+{
+   %this.addNode("Col-1", "", "0 0 0 0 0 1 0", "0");
+   %this.addCollisionDetail("-1", "Sphere", "Bounds", "4", "30", "30", "32", "30", "30", "30");
+}

File diff suppressed because it is too large
+ 50 - 0
Templates/Full/game/art/shapes/textures/PBRTEST2.dae


BIN
Templates/Full/game/art/shapes/textures/Stone_A.dds


BIN
Templates/Full/game/art/shapes/textures/Stone_N.png


BIN
Templates/Full/game/art/shapes/textures/Stone_S.dds


BIN
Templates/Full/game/art/shapes/textures/T3D_Metal_2_any.png


BIN
Templates/Full/game/art/shapes/textures/T3D_Metal_2_basecolor.png


BIN
Templates/Full/game/art/shapes/textures/T3D_Metal_2_normal.png


File diff suppressed because it is too large
+ 0 - 0
Templates/Full/game/art/shapes/textures/T3D_Metal_6.sbs


BIN
Templates/Full/game/art/shapes/textures/T3D_Metal_6.sbsar


BIN
Templates/Full/game/art/shapes/textures/T3D_Metal_6_any.png


BIN
Templates/Full/game/art/shapes/textures/T3D_Metal_6_basecolor.png


BIN
Templates/Full/game/art/shapes/textures/T3D_Metal_6_normal.png


BIN
Templates/Full/game/art/shapes/textures/Wood1_A.dds


BIN
Templates/Full/game/art/shapes/textures/Wood1_N.png


BIN
Templates/Full/game/art/shapes/textures/Wood1_S.dds


BIN
Templates/Full/game/art/shapes/textures/black.dds


BIN
Templates/Full/game/art/shapes/textures/copperalb.png


BIN
Templates/Full/game/art/shapes/textures/coppermtl.png


BIN
Templates/Full/game/art/shapes/textures/coppernrm.png


BIN
Templates/Full/game/art/shapes/textures/copperrgh.png


+ 113 - 0
Templates/Full/game/art/shapes/textures/materials.cs

@@ -0,0 +1,113 @@
+
+singleton Material(PBRTEST_PBRMetal)
+{
+   mapTo = "PBRMetal";
+   diffuseColor[0] = "1 1 1 1";
+   roughness[0] = "1";
+   metalness[0] = "50";
+   translucentBlendOp = "None";
+   diffuseMap[0] = "art/shapes/textures/Metal_A.png";
+   normalMap[0] = "art/shapes/textures/Metal_N.png";
+   materialTag0 = "Miscellaneous";
+   metalChan[0] = "3";
+   specularMap[0] = "art/shapes/textures/Metal_S.png";
+   roughness0 = "1";
+   pixelSpecular0 = "0";
+   invertSmoothness[0] = "1";
+   isSRGb[0] = "1";
+   specularPower0 = "0.415939";
+   specular0 = "0.9 0.9 0.9 1";
+};
+
+singleton Material(PBRTEST_PBRWood)
+{
+   mapTo = "PBRWood";
+   diffuseColor[0] = "1 1 1 1";
+   roughness[0] = "1";
+   metalness[0] = "50";
+   translucentBlendOp = "None";
+   diffuseMap[0] = "art/shapes/textures/Wood1_A.dds";
+   normalMap[0] = "art/shapes/textures/Wood1_N.png";
+   materialTag0 = "Miscellaneous";
+   roughMap[0] = "art/shapes/textures/Wood1_S.dds";
+   metalMap[0] = "art/shapes/textures/Wood1_S.dds";
+   metalChan[0] = "3";
+   roughness0 = "1";
+   pixelSpecular0 = "0";
+   isSRGb[0] = "1";
+   specularPower0 = "0.415939";
+   specular0 = "0.9 0.9 0.9 1";
+};
+
+singleton Material(PBRTest2Mat)
+{
+   mapTo = "PBRTest2Mat";
+   diffuseColor[0] = "1 1 1 1";
+   roughness[0] = "1";
+   metalness[0] = "1";
+   translucentBlendOp = "None";
+   normalMap[0] = "art/shapes/textures/T3D_Metal_6_normal.png";
+   materialTag0 = "Miscellaneous";
+   metalChan[0] = "2";
+   roughness0 = "1";
+   pixelSpecular0 = "0";
+   smoothness[0] = "1";
+   specularMap[0] = "art/shapes/textures/T3D_Metal_6_any.png";
+   specularPower0 = "0.415939";
+   specular0 = "0.9 0.9 0.9 1";
+   translucent = "0";
+   diffuseMap[0] = "art/shapes/textures/T3D_Metal_6_basecolor.png";
+   isSRGb[0] = "1";
+};
+
+singleton Material(PBRTest2Mat)
+{
+   mapTo = "PBRTest2Mat";
+   diffuseColor[0] = "1 1 1 1";
+   smoothness[0] = "1";
+   metalness[0] = "1";
+   translucentBlendOp = "None";
+   diffuseMap[0] = "art/shapes/textures/T3D_Metal_6_basecolor.png";
+   normalMap[0] = "art/shapes/textures/T3D_Metal_6_normal.png";
+   pixelSpecular0 = "0";
+   materialTag0 = "Miscellaneous";
+   specularMap[0] = "art/shapes/textures/T3D_Metal_6_any.png";
+};
+
+singleton Material(PBRTEST_PBRstone)
+{
+   mapTo = "PBRstone";
+   diffuseColor[0] = "0.64 0.64 0.64 1";
+   smoothness[0] = "1";
+   metalness[0] = "1";
+   translucentBlendOp = "None";
+   diffuseMap[0] = "art/shapes/textures/Stone_A.dds";
+   normalMap[0] = "art/shapes/textures/Stone_N.png";
+   roughMap[0] = "art/shapes/textures/Stone_S.dds";
+   metalMap[0] = "art/shapes/textures/Stone_S.dds";
+   roughness0 = "1";
+   materialTag0 = "Miscellaneous";
+   pixelSpecular0 = "0";
+   metalChan[0] = "3";
+   isSRGb[0] = "1";
+   specularPower0 = "0.415939";
+   specular0 = "0.9 0.9 0.9 1";
+};
+
+singleton Material(pbrGrid)
+{
+   mapTo = "PBRGrid";
+   diffuseColor[0] = "1 1 1 1";
+   smoothness[0] = "0";
+   metalness[0] = "0";
+   translucentBlendOp = "LerpAlpha";
+   diffuseMap[0] = "art/shapes/textures/PBRGrid_a.dds";
+   alphaTest = "1";
+   materialTag0 = "Miscellaneous";
+   pixelSpecular0 = "0";
+   doubleSided = "0";
+   alphaRef = "1";
+   diffuseColor[2] = "1 1 1 1";
+   normalMap[0] = "art/shapes/textures/PBRGrid_n.png";
+   specularMap[0] = "art/shapes/textures/PBRGrid_c.dds";
+};

File diff suppressed because it is too large
+ 50 - 0
Templates/Full/game/art/shapes/textures/pbrGrid.dae


Some files were not shown because too many files changed in this diff