Browse Source

Overhauls the handling of probes to utilize an active probe list to improve performance and allow a greater total number of active probes in a scene.
Also fixes handling of metal materials during bakes to render properly, and fixes a possible double-up return in findObjectByType, which could cause doubling when getting probes in the scene

Areloch 4 years ago
parent
commit
6a3603c737

+ 1 - 4
Engine/source/T3D/lighting/boxEnvironmentProbe.cpp

@@ -158,11 +158,8 @@ void BoxEnvironmentProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
 
 
 void BoxEnvironmentProbe::updateProbeParams()
 void BoxEnvironmentProbe::updateProbeParams()
 {
 {
-   if (!mProbeInfo)
-      return;
-
    mProbeShapeType = ProbeRenderInst::Box;
    mProbeShapeType = ProbeRenderInst::Box;
-   mProbeInfo->mAtten = mAtten;
+   mProbeInfo.mAtten = mAtten;
 
 
    Parent::updateProbeParams();
    Parent::updateProbeParams();
 }
 }

+ 79 - 218
Engine/source/T3D/lighting/reflectionProbe.cpp

@@ -83,17 +83,13 @@ ImplementEnumType(ReflectionModeEnum,
 { ReflectionProbe::NoReflection, "No Reflections", "This probe does not provide any local reflection data"},
 { ReflectionProbe::NoReflection, "No Reflections", "This probe does not provide any local reflection data"},
 { ReflectionProbe::StaticCubemap, "Static Cubemap", "Uses a static CubemapData" },
 { ReflectionProbe::StaticCubemap, "Static Cubemap", "Uses a static CubemapData" },
 { ReflectionProbe::BakedCubemap, "Baked Cubemap", "Uses a cubemap baked from the probe's current position" },
 { ReflectionProbe::BakedCubemap, "Baked Cubemap", "Uses a cubemap baked from the probe's current position" },
-{ ReflectionProbe::DynamicCubemap, "Dynamic Cubemap", "Uses a cubemap baked from the probe's current position, updated at a set rate" },
+//{ ReflectionProbe::DynamicCubemap, "Dynamic Cubemap", "Uses a cubemap baked from the probe's current position, updated at a set rate" },
    EndImplementEnumType;
    EndImplementEnumType;
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // Object setup and teardown
 // Object setup and teardown
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-ReflectionProbe::ReflectionProbe() :
-   cubeDescId(0),
-   reflectorDesc(nullptr),
-   mSphereVertCount(0),
-   mSpherePrimitiveCount(0)
+ReflectionProbe::ReflectionProbe()
 {
 {
    // Flag this object so that it will always
    // Flag this object so that it will always
    // be sent across the network to clients
    // be sent across the network to clients
@@ -106,8 +102,7 @@ ReflectionProbe::ReflectionProbe() :
    mReflectionModeType = BakedCubemap;
    mReflectionModeType = BakedCubemap;
 
 
    mEnabled = true;
    mEnabled = true;
-   mBake = false;
-   mDirty = false;
+   mBakeReflections = false;
    mCubemapDirty = false;
    mCubemapDirty = false;
 
 
    mRadius = 10;
    mRadius = 10;
@@ -122,17 +117,14 @@ ReflectionProbe::ReflectionProbe() :
    mEditorShapeInst = NULL;
    mEditorShapeInst = NULL;
    mEditorShape = NULL;
    mEditorShape = NULL;
 
 
-   mRefreshRateMS = 500;
+   mRefreshRateMS = 200;
    mDynamicLastBakeMS = 0;
    mDynamicLastBakeMS = 0;
 
 
    mMaxDrawDistance = 75;
    mMaxDrawDistance = 75;
 
 
    mResourcesCreated = false;
    mResourcesCreated = false;
-
-   mProbeInfo = nullptr;
-
    mPrefilterSize = 64;
    mPrefilterSize = 64;
-   mPrefilterMipLevels = mLog2(F32(mPrefilterSize))+1;
+   mPrefilterMipLevels = mLog2(F32(mPrefilterSize));
    mPrefilterMap = nullptr;
    mPrefilterMap = nullptr;
    mIrridianceMap = nullptr;
    mIrridianceMap = nullptr;
 
 
@@ -158,7 +150,7 @@ void ReflectionProbe::initPersistFields()
 {
 {
    addGroup("Rendering");
    addGroup("Rendering");
       addProtectedField("enabled", TypeBool, Offset(mEnabled, ReflectionProbe),
       addProtectedField("enabled", TypeBool, Offset(mEnabled, ReflectionProbe),
-         &_setEnabled, &defaultProtectedGetFn, "Regenerate Voxel Grid");
+         &_setEnabled, &defaultProtectedGetFn, "Is the probe enabled or not");
    endGroup("Rendering");
    endGroup("Rendering");
 
 
    addGroup("Reflection");
    addGroup("Reflection");
@@ -168,18 +160,18 @@ void ReflectionProbe::initPersistFields()
       addProtectedField("EditPosOffset", TypeBool, Offset(mEditPosOffset, ReflectionProbe),
       addProtectedField("EditPosOffset", TypeBool, Offset(mEditPosOffset, ReflectionProbe),
       &_toggleEditPosOffset, &defaultProtectedGetFn, "Toggle Edit Pos Offset Mode", AbstractClassRep::FieldFlags::FIELD_ComponentInspectors);
       &_toggleEditPosOffset, &defaultProtectedGetFn, "Toggle Edit Pos Offset Mode", AbstractClassRep::FieldFlags::FIELD_ComponentInspectors);
 
 
-	   addField("refOffset", TypePoint3F, Offset(mProbeRefOffset, ReflectionProbe), "");
-      addField("refScale", TypePoint3F, Offset(mProbeRefScale, ReflectionProbe), "");
+	   addField("refOffset", TypePoint3F, Offset(mProbeRefOffset, ReflectionProbe), "The reference positional offset for the probe. This is used for adjusting the perceived center and area of influence.\nHelpful in adjusting parallax issues");
+      addField("refScale", TypePoint3F, Offset(mProbeRefScale, ReflectionProbe), "The reference scale for the probe. This is used for adjusting the perceived center and area of influence.\nHelpful in adjusting parallax issues");
 
 
       addProtectedField("ReflectionMode", TypeReflectionModeEnum, Offset(mReflectionModeType, ReflectionProbe), &_setReflectionMode, &defaultProtectedGetFn,
       addProtectedField("ReflectionMode", TypeReflectionModeEnum, Offset(mReflectionModeType, ReflectionProbe), &_setReflectionMode, &defaultProtectedGetFn,
-         "The type of mesh data to use for collision queries.");
+         "Used to dictate what sort of cubemap the probes use when using IBL.");
 
 
-      addField("StaticCubemap", TypeCubemapName, Offset(mCubemapName, ReflectionProbe), "Cubemap used instead of reflection texture if fullReflect is off.");
+      addField("StaticCubemap", TypeCubemapName, Offset(mCubemapName, ReflectionProbe), "This is used when a static cubemap is used. The name of the cubemap is looked up and loaded for the IBL calculations.");
 
 
-      addField("DynamicReflectionRefreshMS", TypeS32, Offset(mRefreshRateMS, ReflectionProbe), "How often the dynamic cubemap is refreshed in milliseconds. Only works when the ReflectionMode is set to DynamicCubemap.");
+      //addField("DynamicReflectionRefreshMS", TypeS32, Offset(mRefreshRateMS, ReflectionProbe), "How often the dynamic cubemap is refreshed in milliseconds. Only works when the ReflectionMode is set to DynamicCubemap.");
 
 
-      addProtectedField("Bake", TypeBool, Offset(mBake, ReflectionProbe),
-         &_doBake, &defaultProtectedGetFn, "Regenerate Voxel Grid", AbstractClassRep::FieldFlags::FIELD_ComponentInspectors);
+      addProtectedField("Bake", TypeBool, Offset(mBakeReflections, ReflectionProbe),
+         &_doBake, &defaultProtectedGetFn, "Bake Probe Reflections", AbstractClassRep::FieldFlags::FIELD_ComponentInspectors);
    endGroup("Reflection");
    endGroup("Reflection");
 
 
    Con::addVariable("$Light::renderReflectionProbes", TypeBool, &RenderProbeMgr::smRenderReflectionProbes,
    Con::addVariable("$Light::renderReflectionProbes", TypeBool, &RenderProbeMgr::smRenderReflectionProbes,
@@ -319,8 +311,7 @@ void ReflectionProbe::onRemove()
 {
 {
    if (isClientObject())
    if (isClientObject())
    {
    {
-      PROBEMGR->unregisterProbe(mProbeInfo->mProbeIdx);
-      mProbeInfo = nullptr;
+      PROBEMGR->unregisterProbe(mProbeInfo.mProbeIdx);
    }
    }
 
 
    // Remove this object from the scene
    // Remove this object from the scene
@@ -436,7 +427,6 @@ U32 ReflectionProbe::packUpdate(NetConnection *conn, U32 mask, BitStream *stream
       stream->write(mProbeUniqueID);
       stream->write(mProbeUniqueID);
       stream->write((U32)mReflectionModeType);
       stream->write((U32)mReflectionModeType);
       stream->write(mCubemapName);
       stream->write(mCubemapName);
-      stream->write(mRefreshRateMS);
    }
    }
 
 
    if (stream->writeFlag(mask & EnabledMask))
    if (stream->writeFlag(mask & EnabledMask))
@@ -463,7 +453,7 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
       resetWorldBox();
       resetWorldBox();
 
 
       mathRead(*stream, &mProbeRefOffset);
       mathRead(*stream, &mProbeRefOffset);
-      mathRead(*stream, &mProbeRefScale);      
+      mathRead(*stream, &mProbeRefScale);
 
 
       mDirty = true;
       mDirty = true;
    }
    }
@@ -490,8 +480,6 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
       if(oldReflectModeType != mReflectionModeType || oldCubemapName != mCubemapName)
       if(oldReflectModeType != mReflectionModeType || oldCubemapName != mCubemapName)
          mCubemapDirty = true;
          mCubemapDirty = true;
 
 
-      stream->read(&mRefreshRateMS);
-
       mDirty = true;
       mDirty = true;
    }
    }
 
 
@@ -501,11 +489,6 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
 
 
       mDirty = true;
       mDirty = true;
    }
    }
-
-   if (mDirty)
-   {
-      updateProbeParams();
-   }
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -513,12 +496,9 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 void ReflectionProbe::updateProbeParams()
 void ReflectionProbe::updateProbeParams()
 {
 {
-   if (!mProbeInfo)
-      return;
-
-   mProbeInfo->mIsEnabled = mEnabled;
+   mProbeInfo.mIsEnabled = mEnabled;
 
 
-   mProbeInfo->mProbeShapeType = mProbeShapeType;
+   mProbeInfo.mProbeShapeType = mProbeShapeType;
 
 
    if (mProbeShapeType == ProbeRenderInst::Sphere)
    if (mProbeShapeType == ProbeRenderInst::Sphere)
       mObjScale.set(mRadius, mRadius, mRadius);
       mObjScale.set(mRadius, mRadius, mRadius);
@@ -527,10 +507,8 @@ void ReflectionProbe::updateProbeParams()
 
 
    if (mProbeShapeType == ProbeRenderInst::Skylight)
    if (mProbeShapeType == ProbeRenderInst::Skylight)
    {
    {
-      mProbeInfo->mPosition = Point3F::Zero;
-      mProbeInfo->mTransform = MatrixF::Identity;
-
-      mProbeInfo->mIsSkylight = true;
+      mProbeInfo.mPosition = Point3F::Zero;
+      mProbeInfo.mTransform = MatrixF::Identity;
 
 
       F32 visDist = gClientSceneGraph->getVisibleDistance();
       F32 visDist = gClientSceneGraph->getVisibleDistance();
       Box3F skylightBounds = Box3F(visDist * 2);
       Box3F skylightBounds = Box3F(visDist * 2);
@@ -541,21 +519,19 @@ void ReflectionProbe::updateProbeParams()
 
 
       setGlobalBounds();
       setGlobalBounds();
 
 
-      mProbeInfo->mScore = -1.0f;
+      mProbeInfo.mScore = 10000.0f;
    }
    }
    else
    else
    {
    {
       MatrixF transform = getTransform();
       MatrixF transform = getTransform();
-      mProbeInfo->mPosition = getPosition();
+      mProbeInfo.mPosition = getPosition();
 
 
       transform.scale(getScale());
       transform.scale(getScale());
-      mProbeInfo->mTransform = transform.inverse();
-
-      mProbeInfo->mIsSkylight = false;
+      mProbeInfo.mTransform = transform.inverse();
 
 
       bounds = mWorldBox;
       bounds = mWorldBox;
 
 
-      mProbeInfo->mScore = mMaxDrawDistance;
+      mProbeInfo.mScore = 1;
    }
    }
 
 
    // Skip our transform... it just dirties mask bits.
    // Skip our transform... it just dirties mask bits.
@@ -563,14 +539,14 @@ void ReflectionProbe::updateProbeParams()
 
 
    resetWorldBox();
    resetWorldBox();
 
 
-   mProbeInfo->mBounds = bounds;
-   mProbeInfo->mExtents = getScale();
-   mProbeInfo->mRadius = mRadius;
+   mProbeInfo.mBounds = bounds;
+   mProbeInfo.mExtents = getScale();
+   mProbeInfo.mRadius = mRadius;
 
 
-   mProbeInfo->mProbeRefOffset = mProbeRefOffset;
-   mProbeInfo->mProbeRefScale = mProbeRefScale;
+   mProbeInfo.mProbeRefOffset = mProbeRefOffset;
+   mProbeInfo.mProbeRefScale = mProbeRefScale;
 
 
-   mProbeInfo->mDirty = true;
+   mProbeInfo.mDirty = true;
 
 
    if (mCubemapDirty)
    if (mCubemapDirty)
    {
    {
@@ -587,108 +563,12 @@ void ReflectionProbe::updateProbeParams()
 
 
 void ReflectionProbe::processDynamicCubemap()
 void ReflectionProbe::processDynamicCubemap()
 {
 {
-   /*if (!mProbeInfo)
-      return;
-
-   mEnabled = false;
-
-   if (mReflectionModeType == DynamicCubemap && !mDynamicCubemap.isNull())
-   {
-      mProbeInfo->mPrefilterCubemap = mDynamicCubemap;
-
-      if (reflectorDesc == nullptr)
-      {
-         //find it
-         if (!Sim::findObject("DefaultCubeDesc", reflectorDesc))
-         {
-            mProbeInfo->mIsEnabled = false;
-            return;
-         }
-      }
-
-      mCubeReflector.unregisterReflector();
-      mCubeReflector.registerReflector(this, reflectorDesc); //need to decide how we wanna do the reflectorDesc. static name or a field
-   }
-
-   if (mEnabled)
-      mProbeInfo->mIsEnabled = true;
-   else
-      mProbeInfo->mIsEnabled = false;
-
-   mCubemapDirty = false;
-
-   //Update the probe manager with our new texture!
-   //if (!mProbeInfo->mIsSkylight && mProbeInfo->mPrefilterCubemap->isInitialized() && mProbeInfo->mIrradianceCubemap->isInitialized())
-   //   PROBEMGR->updateProbeTexture(mProbeInfo->mProbeIdx);*/
-
-   if (!mProbeInfo)
-      return;
-
-   mProbeInfo->mIsEnabled = false;
-
-   if (mReflectionModeType != DynamicCubemap)
-      return;
-
-   if (reflectorDesc == nullptr)
-   {
-      //find it
-      if (!Sim::findObject("DefaultCubeDesc", reflectorDesc))
-      {
-         mProbeInfo->mIsEnabled = false;
-         return;
-      }
-
-      mCubeReflector.unregisterReflector();
-      mCubeReflector.registerReflector(this, reflectorDesc); //need to decide how we wanna do the reflectorDesc. static name or a field
-   }
-
-   if (mCubeReflector.getCubemap())
-   {
-      U32 resolution = Con::getIntVariable("$pref::ReflectionProbes::BakeResolution", 64);
-      U32 prefilterMipLevels = mLog2(F32(resolution))+1;
-
-      //Prep it with whatever resolution we've dictated for our bake
-      mIrridianceMap->mCubemap->initDynamic(resolution, PROBEMGR->PROBE_FORMAT);
-      mPrefilterMap->mCubemap->initDynamic(resolution, PROBEMGR->PROBE_FORMAT);
-
-      GFXTextureTargetRef renderTarget = GFX->allocRenderToTextureTarget(false);
-
-      IBLUtilities::GenerateIrradianceMap(renderTarget, mCubeReflector.getCubemap(), mIrridianceMap->mCubemap);
-      IBLUtilities::GeneratePrefilterMap(renderTarget, mCubeReflector.getCubemap(), prefilterMipLevels, mPrefilterMap->mCubemap);
-   }
-
-   if (mIrridianceMap == nullptr || mIrridianceMap->mCubemap.isNull())
-   {
-      Con::errorf("ReflectionProbe::processDynamicCubemap() - Unable to load baked irradiance map at %s", getIrradianceMapPath().c_str());
-      return;
-   }
-
-   if (mPrefilterMap == nullptr || mPrefilterMap->mCubemap.isNull())
-   {
-      Con::errorf("ReflectionProbe::processDynamicCubemap() - Unable to load baked prefilter map at %s", getPrefilterMapPath().c_str());
-      return;
-   }
-
-   mProbeInfo->mPrefilterCubemap = mPrefilterMap->mCubemap;
-   mProbeInfo->mIrradianceCubemap = mIrridianceMap->mCubemap;
-
-   if (mEnabled && mProbeInfo->mPrefilterCubemap->isInitialized() && mProbeInfo->mIrradianceCubemap->isInitialized())
-   {
-      mProbeInfo->mIsEnabled = true;
-
-      mCubemapDirty = false;
-
-      //Update the probe manager with our new texture!
-      PROBEMGR->updateProbeTexture(mProbeInfo);
-   }
+   
 }
 }
 
 
 void ReflectionProbe::processBakedCubemap()
 void ReflectionProbe::processBakedCubemap()
 {
 {
-   if (!mProbeInfo)
-      return;
-
-   mProbeInfo->mIsEnabled = false;
+   mProbeInfo.mIsEnabled = false;
 
 
    if ((mReflectionModeType != BakedCubemap) || mProbeUniqueID.isEmpty())
    if ((mReflectionModeType != BakedCubemap) || mProbeUniqueID.isEmpty())
       return;
       return;
@@ -700,7 +580,7 @@ void ReflectionProbe::processBakedCubemap()
       mIrridianceMap->updateFaces();
       mIrridianceMap->updateFaces();
    }
    }
 
 
-   if (mIrridianceMap == nullptr || !mIrridianceMap->mCubemap->isInitialized())
+   if (mIrridianceMap == nullptr || mIrridianceMap->mCubemap.isNull())
    {
    {
       Con::errorf("ReflectionProbe::processDynamicCubemap() - Unable to load baked irradiance map at %s", getIrradianceMapPath().c_str());
       Con::errorf("ReflectionProbe::processDynamicCubemap() - Unable to load baked irradiance map at %s", getIrradianceMapPath().c_str());
       return;
       return;
@@ -713,32 +593,33 @@ void ReflectionProbe::processBakedCubemap()
       mPrefilterMap->updateFaces();
       mPrefilterMap->updateFaces();
    }
    }
 
 
-   if (mPrefilterMap == nullptr || !mPrefilterMap->mCubemap->isInitialized())
+   if (mPrefilterMap == nullptr || mPrefilterMap->mCubemap.isNull())
    {
    {
       Con::errorf("ReflectionProbe::processDynamicCubemap() - Unable to load baked prefilter map at %s", getPrefilterMapPath().c_str());
       Con::errorf("ReflectionProbe::processDynamicCubemap() - Unable to load baked prefilter map at %s", getPrefilterMapPath().c_str());
       return;
       return;
    }
    }
 
 
-   mProbeInfo->mPrefilterCubemap = mPrefilterMap->mCubemap;
-   mProbeInfo->mIrradianceCubemap = mIrridianceMap->mCubemap;
+   mProbeInfo.mPrefilterCubemap = mPrefilterMap->mCubemap;
+   mProbeInfo.mIrradianceCubemap = mIrridianceMap->mCubemap;
 
 
-   if (mEnabled && mProbeInfo->mPrefilterCubemap->isInitialized() && mProbeInfo->mIrradianceCubemap->isInitialized())
+   if (mEnabled && mProbeInfo.mPrefilterCubemap->isInitialized() && mProbeInfo.mIrradianceCubemap->isInitialized())
    {
    {
-      mProbeInfo->mIsEnabled = true;
+      mProbeInfo.mIsEnabled = true;
 
 
       mCubemapDirty = false;
       mCubemapDirty = false;
 
 
       //Update the probe manager with our new texture!
       //Update the probe manager with our new texture!
-      PROBEMGR->updateProbeTexture(mProbeInfo);
+      PROBEMGR->updateProbeTexture(&mProbeInfo);
+
+      //now, cleanup
+      mProbeInfo.mPrefilterCubemap.free();
+      mProbeInfo.mIrradianceCubemap.free();
    }
    }
 }
 }
 
 
 void ReflectionProbe::processStaticCubemap()
 void ReflectionProbe::processStaticCubemap()
 {
 {
-   if (!mProbeInfo)
-      return;
-
-   mProbeInfo->mIsEnabled = false;
+   mProbeInfo.mIsEnabled = false;
 
 
    String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/");
    String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/");
 
 
@@ -747,45 +628,31 @@ void ReflectionProbe::processStaticCubemap()
 
 
    if (Platform::isFile(irradFileName))
    if (Platform::isFile(irradFileName))
    {
    {
-      if (mIrridianceMap == nullptr)
-      {
-         Con::errorf("ReflectionProbe::processStaticCubemap() - Unable to load baked irradiance map at %s", irradFileName);
-         return;
-      }
-
       mIrridianceMap->setCubemapFile(FileName(irradFileName));
       mIrridianceMap->setCubemapFile(FileName(irradFileName));
-
-      if (mIrridianceMap->mCubemap.isNull())
-      {
-         Con::errorf("ReflectionProbe::processStaticCubemap() - Unable to load baked irradiance map at %s", irradFileName);
-         return;
-      }
-
       mIrridianceMap->updateFaces();
       mIrridianceMap->updateFaces();
    }
    }
 
 
+   if (mIrridianceMap == nullptr || mIrridianceMap->mCubemap.isNull())
+   {
+      Con::errorf("ReflectionProbe::processStaticCubemap() - Unable to load baked irradiance map at %s", irradFileName);
+      return;
+   }
+
    char prefilterFileName[256];
    char prefilterFileName[256];
    dSprintf(prefilterFileName, 256, "%s%s_Prefilter.dds", path.c_str(), mCubemapName.c_str());
    dSprintf(prefilterFileName, 256, "%s%s_Prefilter.dds", path.c_str(), mCubemapName.c_str());
 
 
    if (Platform::isFile(prefilterFileName))
    if (Platform::isFile(prefilterFileName))
    {
    {
-      if (mPrefilterMap == nullptr)
-      {
-         Con::errorf("ReflectionProbe::processStaticCubemap() - Unable to load baked prefilter map at %s", prefilterFileName);
-         return;
-      }
-
       mPrefilterMap->setCubemapFile(FileName(prefilterFileName));
       mPrefilterMap->setCubemapFile(FileName(prefilterFileName));
-
-      if (mPrefilterMap->mCubemap.isNull())
-      {
-         Con::errorf("ReflectionProbe::processStaticCubemap() - Unable to load baked prefilter map at %s", prefilterFileName);
-         return;
-      }
-
       mPrefilterMap->updateFaces();
       mPrefilterMap->updateFaces();
    }
    }
 
 
+   if (mPrefilterMap == nullptr || mPrefilterMap->mCubemap.isNull())
+   {
+      Con::errorf("ReflectionProbe::processStaticCubemap() - Unable to load baked prefilter map at %s", prefilterFileName);
+      return;
+   }
+
    if (!Platform::isFile(prefilterFileName) || !Platform::isFile(irradFileName))
    if (!Platform::isFile(prefilterFileName) || !Platform::isFile(irradFileName))
    {
    {
       //If we are missing either of the files, just re-run the bake
       //If we are missing either of the files, just re-run the bake
@@ -823,34 +690,29 @@ void ReflectionProbe::processStaticCubemap()
       IBLUtilities::SaveCubeMap(prefilterFileName, mPrefilterMap->mCubemap);
       IBLUtilities::SaveCubeMap(prefilterFileName, mPrefilterMap->mCubemap);
    }
    }
 
 
-   if ((mIrridianceMap != nullptr && !mIrridianceMap->mCubemap.isNull()) && (mPrefilterMap != nullptr && !mPrefilterMap->mCubemap.isNull()))
+   if ((mIrridianceMap != nullptr || !mIrridianceMap->mCubemap.isNull()) && (mPrefilterMap != nullptr || !mPrefilterMap->mCubemap.isNull()))
    {
    {
-      mProbeInfo->mPrefilterCubemap = mPrefilterMap->mCubemap;
-      mProbeInfo->mIrradianceCubemap = mIrridianceMap->mCubemap;
+      mProbeInfo.mPrefilterCubemap = mPrefilterMap->mCubemap;
+      mProbeInfo.mIrradianceCubemap = mIrridianceMap->mCubemap;
    }
    }
 
 
-   if (mEnabled && mProbeInfo->mPrefilterCubemap->isInitialized() && mProbeInfo->mIrradianceCubemap->isInitialized())
+   if (mEnabled && mProbeInfo.mPrefilterCubemap->isInitialized() && mProbeInfo.mIrradianceCubemap->isInitialized())
    {
    {
-      mProbeInfo->mIsEnabled = true;
+      mProbeInfo.mIsEnabled = true;
 
 
       mCubemapDirty = false;
       mCubemapDirty = false;
 
 
       //Update the probe manager with our new texture!
       //Update the probe manager with our new texture!
-      PROBEMGR->updateProbeTexture(mProbeInfo);
+      PROBEMGR->updateProbeTexture(&mProbeInfo);
    }
    }
 }
 }
 
 
 bool ReflectionProbe::createClientResources()
 bool ReflectionProbe::createClientResources()
 {
 {
-   if (mProbeInfo == nullptr)
-   {
-      mProbeInfo = PROBEMGR->registerProbe();
-      if (!mProbeInfo)
-         return false;
-
-      mProbeInfo->mIsEnabled = false;
-   }
+   PROBEMGR->registerProbe(&mProbeInfo);
 
 
+   mProbeInfo.mIsEnabled = false;
+   
    //irridiance resources
    //irridiance resources
    if (!mIrridianceMap)
    if (!mIrridianceMap)
    {
    {
@@ -909,12 +771,10 @@ String ReflectionProbe::getIrradianceMapPath()
 
 
 void ReflectionProbe::bake()
 void ReflectionProbe::bake()
 {
 {
-   bool writeFile = mReflectionModeType == BakedCubemap ? true : false;
-
-   if (mReflectionModeType == StaticCubemap)
+   if (mReflectionModeType != BakedCubemap)
       return;
       return;
 
 
-   PROBEMGR->bakeProbe(this, writeFile);
+   PROBEMGR->bakeProbe(this);
 
 
    setMaskBits(-1);
    setMaskBits(-1);
 }
 }
@@ -922,8 +782,9 @@ void ReflectionProbe::bake()
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 //Rendering of editing/debug stuff
 //Rendering of editing/debug stuff
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-void ReflectionProbe::createGeometry()
+void ReflectionProbe::createEditorResources()
 {
 {
+#ifdef TORQUE_TOOLS
    // Clean up our previous shape
    // Clean up our previous shape
    if (mEditorShapeInst)
    if (mEditorShapeInst)
       SAFE_DELETE(mEditorShapeInst);
       SAFE_DELETE(mEditorShapeInst);
@@ -938,6 +799,7 @@ void ReflectionProbe::createGeometry()
    {
    {
       mEditorShapeInst = new TSShapeInstance(mEditorShape, isClientObject());
       mEditorShapeInst = new TSShapeInstance(mEditorShape, isClientObject());
    }
    }
+#endif
 }
 }
 
 
 void ReflectionProbe::prepRenderImage(SceneRenderState *state)
 void ReflectionProbe::prepRenderImage(SceneRenderState *state)
@@ -951,16 +813,14 @@ void ReflectionProbe::prepRenderImage(SceneRenderState *state)
    //Culling distance. Can be adjusted for performance options considerations via the scalar
    //Culling distance. Can be adjusted for performance options considerations via the scalar
    if (dist > mMaxDrawDistance * Con::getFloatVariable("$pref::GI::ProbeDrawDistScale", 1.0))
    if (dist > mMaxDrawDistance * Con::getFloatVariable("$pref::GI::ProbeDrawDistScale", 1.0))
    {
    {
-      mProbeInfo->mScore = mMaxDrawDistance;
+      mProbeInfo.mScore = mMaxDrawDistance;
       return;
       return;
    }
    }
 
 
    if (mReflectionModeType == DynamicCubemap && mRefreshRateMS < (Platform::getRealMilliseconds() - mDynamicLastBakeMS))
    if (mReflectionModeType == DynamicCubemap && mRefreshRateMS < (Platform::getRealMilliseconds() - mDynamicLastBakeMS))
    {
    {
-      //bake();
+      bake();
       mDynamicLastBakeMS = Platform::getRealMilliseconds();
       mDynamicLastBakeMS = Platform::getRealMilliseconds();
-
-      processDynamicCubemap();
    }
    }
 
 
    //Submit our probe to actually do the probe action
    //Submit our probe to actually do the probe action
@@ -968,20 +828,20 @@ void ReflectionProbe::prepRenderImage(SceneRenderState *state)
    //RenderPassManager *renderPass = state->getRenderPass();
    //RenderPassManager *renderPass = state->getRenderPass();
 
 
    //Update our score based on our radius, distance
    //Update our score based on our radius, distance
-   mProbeInfo->mScore = mProbeInfo->mRadius/mMax(dist,1.0f);
+   mProbeInfo.mScore = mMax(dist, 1.0f);
 
 
    Point3F vect = distVec;
    Point3F vect = distVec;
    vect.normalizeSafe();
    vect.normalizeSafe();
 
 
-   mProbeInfo->mScore *= mMax(mAbs(mDot(vect, state->getCameraTransform().getForwardVector())),0.001f);
+   //mProbeInfo.mScore *= mMax(mAbs(mDot(vect, state->getCameraTransform().getForwardVector())),0.001f);
 
 
-   //Register
-   //PROBEMGR->registerProbe(mProbeInfoIdx);
+   PROBEMGR->submitProbe(mProbeInfo);
 
 
+#ifdef TORQUE_TOOLS
    if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mPrefilterMap != nullptr)
    if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mPrefilterMap != nullptr)
    {
    {
       if(!mEditorShapeInst)
       if(!mEditorShapeInst)
-         createGeometry();
+         createEditorResources();
 
 
       GFXTransformSaver saver;
       GFXTransformSaver saver;
 
 
@@ -1039,7 +899,7 @@ void ReflectionProbe::prepRenderImage(SceneRenderState *state)
       saver.restore();
       saver.restore();
    }
    }
 
 
-   // If the light is selected or light visualization
+   // If the probe is selected or probe visualization
    // is enabled then register the callback.
    // is enabled then register the callback.
    const bool isSelectedInEditor = (gEditingMission && isSelected());
    const bool isSelectedInEditor = (gEditingMission && isSelected());
    if (isSelectedInEditor)
    if (isSelectedInEditor)
@@ -1049,6 +909,7 @@ void ReflectionProbe::prepRenderImage(SceneRenderState *state)
       ri->type = RenderPassManager::RIT_Editor;
       ri->type = RenderPassManager::RIT_Editor;
       state->getRenderPass()->addInst(ri);
       state->getRenderPass()->addInst(ri);
    }
    }
+#endif
 }
 }
 
 
 void ReflectionProbe::_onRenderViz(ObjectRenderInst *ri,
 void ReflectionProbe::_onRenderViz(ObjectRenderInst *ri,
@@ -1127,7 +988,7 @@ DefineEngineMethod(ReflectionProbe, postApply, void, (), ,
 }
 }
 
 
 DefineEngineMethod(ReflectionProbe, Bake, void, (), ,
 DefineEngineMethod(ReflectionProbe, Bake, void, (), ,
-   "@brief returns true if control object is inside the fog\n\n.")
+   "@brief Bakes the cubemaps for a reflection probe\n\n.")
 {
 {
    ReflectionProbe *clientProbe = (ReflectionProbe*)object->getClientObject();
    ReflectionProbe *clientProbe = (ReflectionProbe*)object->getClientObject();
 
 

+ 92 - 19
Engine/source/T3D/lighting/reflectionProbe.h

@@ -63,6 +63,9 @@ class ReflectionProbe : public SceneObject
 
 
 public:
 public:
 
 
+   /// <summary>
+   /// Used to dictate what sort of cubemap the probes use when using IBL
+   /// </summary>
    enum ReflectionModeType
    enum ReflectionModeType
    {
    {
       NoReflection = 0,
       NoReflection = 0,
@@ -87,36 +90,84 @@ protected:
       NextFreeMask = Parent::NextFreeMask << 3
       NextFreeMask = Parent::NextFreeMask << 3
    };
    };
 
 
-   bool mBake;
+   /// <summary>
+   /// Only used for interfacing with the editor's inspector bake button
+   /// </summary>
+   bool mBakeReflections;
+
+   /// <summary>
+   /// Whether this probe is enabled or not
+   /// </summary>
    bool mEnabled;
    bool mEnabled;
+   
    bool mDirty;
    bool mDirty;
+
+   /// <summary>
+   /// Whether this probe's cubemap is dirty or not
+   /// </summary>
    bool mCubemapDirty;
    bool mCubemapDirty;
 
 
+#ifdef TORQUE_TOOLS
+   /// <summary>
+   /// Used only when the editor is loaded, this is the shape data used for the probe viewing(aka, a sphere)
+   /// </summary>
    Resource<TSShape> mEditorShape;
    Resource<TSShape> mEditorShape;
+   /// <summary>
+   /// This is the shape instance of the editor shape data
+   /// </summary>
    TSShapeInstance* mEditorShapeInst;
    TSShapeInstance* mEditorShapeInst;
+#endif // TORQUE_TOOLS
 
 
    //--------------------------------------------------------------------------
    //--------------------------------------------------------------------------
    // Rendering variables
    // Rendering variables
    //--------------------------------------------------------------------------
    //--------------------------------------------------------------------------
+   /// <summary>
+   /// The shape of the probe
+   /// </summary>
    ProbeRenderInst::ProbeShapeType mProbeShapeType;
    ProbeRenderInst::ProbeShapeType mProbeShapeType;
 
 
-   ProbeRenderInst* mProbeInfo;
-
-   //Reflection Contribution stuff
+   /// <summary>
+   /// This is effectively a packed cache of the probe data actually utilized for rendering.
+   /// The RenderProbeManager uses this via the probe calling registerProbe on creation, and unregisterProbe on destruction
+   /// When the manager goes to render it has the compacted data to read over more efficiently for setting up what probes should
+   /// Actually render in that frame
+   /// </summary>
+   ProbeRenderInst mProbeInfo;
+
+   /// <summary>
+   /// Used to dictate what sort of cubemap the probes use when using IBL
+   /// </summary>
    ReflectionModeType mReflectionModeType;
    ReflectionModeType mReflectionModeType;
 
 
+   /// <summary>
+   /// The radius of the probe's influence. Only really relevent in Sphere probes
+   /// </summary>
    F32 mRadius;
    F32 mRadius;
+   /// <summary>
+   /// The reference positional offset for the probe. This is used for adjusting the perceived center and area of influence.
+   /// Helpful in adjusting parallax issues
+   /// </summary>
    Point3F mProbeRefOffset;
    Point3F mProbeRefOffset;
+   /// <summary>
+   /// The reference scale for the probe. This is used for adjusting the perceived center and area of influence.
+   /// Helpful in adjusting parallax issues
+   /// </summary>
    Point3F mProbeRefScale;
    Point3F mProbeRefScale;
+
+   /// <summary>
+   /// Only used for interfacing with the editor's inspector edit offset button
+   /// </summary>
    bool mEditPosOffset;
    bool mEditPosOffset;
 
 
+   /// <summary>
+   /// This is used when a static cubemap is used. The name of the cubemap is looked up and loaded for the IBL calculations
+   /// </summary>
    String mCubemapName;
    String mCubemapName;
    CubemapData *mStaticCubemap;
    CubemapData *mStaticCubemap;
    GFXCubemapHandle  mDynamicCubemap;
    GFXCubemapHandle  mDynamicCubemap;
 
 
    String cubeDescName;
    String cubeDescName;
    U32 cubeDescId;
    U32 cubeDescId;
-   CubeReflector mCubeReflector;
    ReflectorDesc *reflectorDesc;
    ReflectorDesc *reflectorDesc;
 
 
    //Utilized in dynamic reflections
    //Utilized in dynamic reflections
@@ -133,19 +184,12 @@ protected:
    U32 mPrefilterMipLevels;
    U32 mPrefilterMipLevels;
    U32 mPrefilterSize;
    U32 mPrefilterSize;
 
 
+   /// <summary>
+   /// This is calculated based on the object's persistantID. Effectively a unique hash ID to set it apart from other probes
+   /// Used to ensure the cubemaps named when baking are unique
+   /// </summary>
    String mProbeUniqueID;
    String mProbeUniqueID;
 
 
-   // Define our vertex format here so we don't have to
-   // change it in multiple spots later
-   typedef GFXVertexPNTTB VertexType;
-
-   // The GFX vertex and primitive buffers
-   GFXVertexBufferHandle< VertexType > mVertexBuffer;
-   GFXPrimitiveBufferHandle            mPrimitiveBuffer;
-
-   U32 mSphereVertCount;
-   U32 mSpherePrimitiveCount;
-
    //Debug rendering
    //Debug rendering
    static bool smRenderPreviewProbes;
    static bool smRenderPreviewProbes;
 
 
@@ -188,6 +232,10 @@ public:
    bool onAdd();
    bool onAdd();
    void onRemove();
    void onRemove();
 
 
+   /// <summary>
+   /// This is called when the object is deleted. It allows us to do special-case cleanup actions
+   /// In probes' case, it's used to delete baked cubemap files
+   /// </summary>
    virtual void handleDeleteAction();
    virtual void handleDeleteAction();
 
 
    // Override this so that we can dirty the network flag when it is called
    // Override this so that we can dirty the network flag when it is called
@@ -215,14 +263,26 @@ public:
    //--------------------------------------------------------------------------
    //--------------------------------------------------------------------------
 
 
    // Create the geometry for rendering
    // Create the geometry for rendering
-   void createGeometry();
+   void createEditorResources();
 
 
+   /// <summary>
+   /// Updates the probe rendering data
+   /// </summary>
    virtual void updateProbeParams();
    virtual void updateProbeParams();
-
+   
    bool createClientResources();
    bool createClientResources();
 
 
+   /// <summary>
+   /// Updates the probe's cubemaps in the array when using dynamic reflections
+   /// </summary>
    void processDynamicCubemap();
    void processDynamicCubemap();
+   /// <summary>
+   /// Updates the probe's cubemaps in the array when using baked cubemaps
+   /// </summary>
    void processBakedCubemap();
    void processBakedCubemap();
+   /// <summary>
+   /// Updates the probe's cubemaps in the array when using a static cubemaps
+   /// </summary>
    void processStaticCubemap();
    void processStaticCubemap();
 
 
    // This is the function that allows this object to submit itself for rendering
    // This is the function that allows this object to submit itself for rendering
@@ -234,9 +294,22 @@ public:
 
 
    void setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat);
    void setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat);
 
 
-   //Baking
+   /// <summary>
+   /// This gets the filepath to the prefilter cubemap associated to this probe.
+   /// In the event the probe is set to use a static cubemap, it is the prefiltered version of the cubemap's file
+   /// </summary>
+   /// <returns>The filepath to the prefilter cubemap</returns>
    String getPrefilterMapPath();
    String getPrefilterMapPath();
+   /// <summary>
+   /// This gets the filepath to the irradiance cubemap associated to this probe.
+   /// In the event the probe is set to use a static cubemap, it is the irradiance version of the cubemap's file
+   /// </summary>
+   /// <returns>The filepath to the irradiance cubemap</returns>
    String getIrradianceMapPath();
    String getIrradianceMapPath();
+
+   /// <summary>
+   /// Invokes a cubemap bake action for this probe
+   /// </summary>
    void bake();
    void bake();
 };
 };
 
 

+ 10 - 14
Engine/source/T3D/lighting/skylight.cpp

@@ -135,6 +135,11 @@ void Skylight::unpackUpdate(NetConnection *conn, BitStream *stream)
 {
 {
    // Let the Parent read any info it sent
    // Let the Parent read any info it sent
    Parent::unpackUpdate(conn, stream);
    Parent::unpackUpdate(conn, stream);
+
+   if (mDirty)
+   {
+      updateProbeParams();
+   }
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -143,9 +148,6 @@ void Skylight::unpackUpdate(NetConnection *conn, BitStream *stream)
 
 
 void Skylight::updateProbeParams()
 void Skylight::updateProbeParams()
 {
 {
-   if (!mProbeInfo)
-      return;
-
    mProbeShapeType = ProbeRenderInst::Skylight;
    mProbeShapeType = ProbeRenderInst::Skylight;
    Parent::updateProbeParams();
    Parent::updateProbeParams();
 }
 }
@@ -157,24 +159,17 @@ void Skylight::prepRenderImage(SceneRenderState *state)
 
 
    //special hook-in for skylights
    //special hook-in for skylights
    Point3F camPos = state->getCameraPosition();
    Point3F camPos = state->getCameraPosition();
-   mProbeInfo->mBounds.setCenter(camPos);
+   mProbeInfo.mBounds.setCenter(camPos);
 
 
-   mProbeInfo->setPosition(camPos);
-
-   if (mReflectionModeType == DynamicCubemap && mRefreshRateMS < (Platform::getRealMilliseconds() - mDynamicLastBakeMS))
-   {
-      //bake();
-      mDynamicLastBakeMS = Platform::getRealMilliseconds();
-
-      processDynamicCubemap();
-   }
+   mProbeInfo.setPosition(camPos);
 
 
    //Submit our probe to actually do the probe action
    //Submit our probe to actually do the probe action
    // Get a handy pointer to our RenderPassmanager
    // Get a handy pointer to our RenderPassmanager
    //RenderPassManager *renderPass = state->getRenderPass();
    //RenderPassManager *renderPass = state->getRenderPass();
 
 
-   //PROBEMGR->registerSkylight(mProbeInfo, this);
+   PROBEMGR->submitProbe(mProbeInfo);
 
 
+#ifdef TORQUE_TOOLS
    if (Skylight::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr)
    if (Skylight::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr)
    {
    {
       GFXTransformSaver saver;
       GFXTransformSaver saver;
@@ -235,6 +230,7 @@ void Skylight::prepRenderImage(SceneRenderState *state)
    if (isSelectedInEditor)
    if (isSelectedInEditor)
    {
    {
    }
    }
+#endif
 }
 }
 
 
 void Skylight::setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat)
 void Skylight::setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat)

+ 7 - 3
Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp

@@ -131,6 +131,11 @@ void SphereEnvironmentProbe::unpackUpdate(NetConnection *conn, BitStream *stream
 {
 {
    // Let the Parent read any info it sent
    // Let the Parent read any info it sent
    Parent::unpackUpdate(conn, stream);
    Parent::unpackUpdate(conn, stream);
+
+   if (mDirty)
+   {
+      updateProbeParams();
+   }
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -139,9 +144,6 @@ void SphereEnvironmentProbe::unpackUpdate(NetConnection *conn, BitStream *stream
 
 
 void SphereEnvironmentProbe::updateProbeParams()
 void SphereEnvironmentProbe::updateProbeParams()
 {
 {
-   if (!mProbeInfo)
-      return;
-
    mProbeShapeType = ProbeRenderInst::Sphere;
    mProbeShapeType = ProbeRenderInst::Sphere;
    Parent::updateProbeParams();
    Parent::updateProbeParams();
 }
 }
@@ -151,6 +153,7 @@ void SphereEnvironmentProbe::prepRenderImage(SceneRenderState *state)
    if (!mEnabled || !ReflectionProbe::smRenderPreviewProbes)
    if (!mEnabled || !ReflectionProbe::smRenderPreviewProbes)
       return;
       return;
 
 
+#ifdef TORQUE_TOOLS
    if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr)
    if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr)
    {
    {
       GFXTransformSaver saver;
       GFXTransformSaver saver;
@@ -215,6 +218,7 @@ void SphereEnvironmentProbe::prepRenderImage(SceneRenderState *state)
       ri->type = RenderPassManager::RIT_Editor;
       ri->type = RenderPassManager::RIT_Editor;
       state->getRenderPass()->addInst(ri);
       state->getRenderPass()->addInst(ri);
    }
    }
+#endif
 }
 }
 
 
 void SphereEnvironmentProbe::setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat)
 void SphereEnvironmentProbe::setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat)

+ 1 - 1
Engine/source/console/simSet.h

@@ -332,7 +332,7 @@ void SimSet::findObjectByType( Vector<T*> &foundObjects )
       curSet = dynamic_cast<SimSet*>( *itr );
       curSet = dynamic_cast<SimSet*>( *itr );
 
 
       // If child object is a set, call recursively into it.
       // If child object is a set, call recursively into it.
-      if ( curSet )
+      if ( curSet && curSet->size() != 0)
          curSet->findObjectByType( foundObjects ); 
          curSet->findObjectByType( foundObjects ); 
 
 
       // Add this child object if appropriate.
       // Add this child object if appropriate.

+ 173 - 228
Engine/source/renderInstance/renderProbeMgr.cpp

@@ -45,6 +45,8 @@
 //For our cameraQuery setup
 //For our cameraQuery setup
 #include "T3D/gameTSCtrl.h"
 #include "T3D/gameTSCtrl.h"
 
 
+#include "T3D/Scene.h"
+
 #define TORQUE_GFX_VISUAL_DEBUG //renderdoc debugging
 #define TORQUE_GFX_VISUAL_DEBUG //renderdoc debugging
 
 
 IMPLEMENT_CONOBJECT(RenderProbeMgr);
 IMPLEMENT_CONOBJECT(RenderProbeMgr);
@@ -59,6 +61,8 @@ ConsoleDocClass( RenderProbeMgr,
 RenderProbeMgr *RenderProbeMgr::smProbeManager = NULL;
 RenderProbeMgr *RenderProbeMgr::smProbeManager = NULL;
 
 
 bool RenderProbeMgr::smRenderReflectionProbes = true;
 bool RenderProbeMgr::smRenderReflectionProbes = true;
+F32 RenderProbeMgr::smMaxProbeDrawDistance = 100;
+S32 RenderProbeMgr::smMaxProbesPerFrame = 8;
 
 
 S32 QSORT_CALLBACK AscendingReflectProbeInfluence(const void* a, const void* b)
 S32 QSORT_CALLBACK AscendingReflectProbeInfluence(const void* a, const void* b)
 {
 {
@@ -87,7 +91,6 @@ ProbeRenderInst::ProbeRenderInst() :
    mProbeRefScale(1,1,1),
    mProbeRefScale(1,1,1),
    mAtten(0.0),
    mAtten(0.0),
    mCubemapIndex(0),
    mCubemapIndex(0),
-   mIsSkylight(false),
    mProbeIdx(0),
    mProbeIdx(0),
    mProbeShapeType(Box)
    mProbeShapeType(Box)
 {
 {
@@ -113,7 +116,6 @@ void ProbeRenderInst::set(const ProbeRenderInst *probeInfo)
    mRadius = probeInfo->mRadius;
    mRadius = probeInfo->mRadius;
    mProbeShapeType = probeInfo->mProbeShapeType;
    mProbeShapeType = probeInfo->mProbeShapeType;
    mBounds = probeInfo->mBounds;
    mBounds = probeInfo->mBounds;
-   mIsSkylight = probeInfo->mIsSkylight;
    mScore = probeInfo->mScore;
    mScore = probeInfo->mScore;
    mAtten = probeInfo->mAtten;
    mAtten = probeInfo->mAtten;
 }
 }
@@ -125,8 +127,7 @@ ProbeShaderConstants::ProbeShaderConstants()
    mShader(NULL),
    mShader(NULL),
    mProbePositionSC(NULL),
    mProbePositionSC(NULL),
    mProbeRefPosSC(NULL),
    mProbeRefPosSC(NULL),
-   mRefBoxMinSC(NULL),
-   mRefBoxMaxSC(NULL),
+   mRefScaleSC(NULL),
    mProbeConfigDataSC(NULL),
    mProbeConfigDataSC(NULL),
    mProbeSpecularCubemapSC(NULL),
    mProbeSpecularCubemapSC(NULL),
    mProbeIrradianceCubemapSC(NULL),
    mProbeIrradianceCubemapSC(NULL),
@@ -160,8 +161,7 @@ void ProbeShaderConstants::init(GFXShader* shader)
    //Reflection Probes
    //Reflection Probes
    mProbePositionSC = shader->getShaderConstHandle(ShaderGenVars::probePosition);
    mProbePositionSC = shader->getShaderConstHandle(ShaderGenVars::probePosition);
    mProbeRefPosSC = shader->getShaderConstHandle(ShaderGenVars::probeRefPos);
    mProbeRefPosSC = shader->getShaderConstHandle(ShaderGenVars::probeRefPos);
-   mRefBoxMinSC = shader->getShaderConstHandle(ShaderGenVars::refBoxMin);
-   mRefBoxMaxSC = shader->getShaderConstHandle(ShaderGenVars::refBoxMax);
+   mRefScaleSC = shader->getShaderConstHandle(ShaderGenVars::refScale);
    mWorldToObjArraySC = shader->getShaderConstHandle(ShaderGenVars::worldToObjArray);
    mWorldToObjArraySC = shader->getShaderConstHandle(ShaderGenVars::worldToObjArray);
    mProbeConfigDataSC = shader->getShaderConstHandle(ShaderGenVars::probeConfigData);
    mProbeConfigDataSC = shader->getShaderConstHandle(ShaderGenVars::probeConfigData);
    mProbeSpecularCubemapSC = shader->getShaderConstHandle(ShaderGenVars::specularCubemapAR);
    mProbeSpecularCubemapSC = shader->getShaderConstHandle(ShaderGenVars::specularCubemapAR);
@@ -179,8 +179,7 @@ bool ProbeShaderConstants::isValid()
 {
 {
    if (mProbePositionSC->isValid() ||
    if (mProbePositionSC->isValid() ||
       mProbeConfigDataSC->isValid() ||
       mProbeConfigDataSC->isValid() ||
-      mRefBoxMinSC->isValid() ||
-      mRefBoxMaxSC->isValid() ||
+      mRefScaleSC->isValid() ||
       mProbeSpecularCubemapSC->isValid() ||
       mProbeSpecularCubemapSC->isValid() ||
       mProbeIrradianceCubemapSC->isValid())
       mProbeIrradianceCubemapSC->isValid())
       return true;
       return true;
@@ -204,8 +203,7 @@ RenderProbeMgr::RenderProbeMgr()
    mHasSkylight(false),
    mHasSkylight(false),
    mSkylightCubemapIdx(-1),
    mSkylightCubemapIdx(-1),
    mCubeMapCount(0),
    mCubeMapCount(0),
-   mDefaultSkyLight(nullptr),
-   mBakeRenderTarget(nullptr)
+   mDefaultSkyLight(nullptr)
 {
 {
    mEffectiveProbeCount = 0;
    mEffectiveProbeCount = 0;
    mMipCount = 0;
    mMipCount = 0;
@@ -221,6 +219,9 @@ RenderProbeMgr::RenderProbeMgr()
    {
    {
       mCubeMapSlots[i] = false;
       mCubeMapSlots[i] = false;
    }
    }
+
+   mPrefilterSize = 64;
+   mPrefilterMipLevels = mLog2(F32(mPrefilterSize)) + 1;
 }
 }
 
 
 RenderProbeMgr::RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder)
 RenderProbeMgr::RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder)
@@ -236,6 +237,10 @@ RenderProbeMgr::RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 proce
    mLastConstants = nullptr;
    mLastConstants = nullptr;
    mMipCount = 0;
    mMipCount = 0;
    mProbesDirty = false;
    mProbesDirty = false;
+   mUseHDRCaptures = true;
+
+   mPrefilterSize = 64;
+   mPrefilterMipLevels = mLog2(F32(mPrefilterSize)) + 1;
 }
 }
 
 
 RenderProbeMgr::~RenderProbeMgr()
 RenderProbeMgr::~RenderProbeMgr()
@@ -303,35 +308,22 @@ void RenderProbeMgr::initPersistFields()
    Parent::initPersistFields();
    Parent::initPersistFields();
 }
 }
 
 
-void RenderProbeMgr::addElement(RenderInst *inst)
+void RenderProbeMgr::consoleInit()
 {
 {
-   // If this instance is translucent handle it in RenderTranslucentMgr
-   //if (inst->translucentSort)
-      return;
+   Parent::consoleInit();
 
 
-   //AssertFatal(inst->defaultKey != 0, "RenderMeshMgr::addElement() - Got null sort key... did you forget to set it?");
-
-   /*internalAddElement(inst);
-
-   ProbeRenderInst* probeInst = static_cast<ProbeRenderInst*>(inst);
-
-   if (probeInst->mIsSkylight)
-   {
-      addSkylightProbe(probeInst);
-   }
-   else
-   {
-      if (probeInst->mProbeShapeType == ProbeInfo::Sphere)
-         addSphereReflectionProbe(probeInst);
-      else
-         addConvexReflectionProbe(probeInst);
-   }*/
+   // Vars for debug rendering while the RoadEditor is open, only used if smEditorOpen is true.
+   Con::addVariable("$pref::maxProbeDrawDistance", TypeF32, &RenderProbeMgr::smMaxProbeDrawDistance, "Max distance for reflection probes to render.\n");
+   Con::addVariable("$pref::MaxProbesPerFrame", TypeS32, &RenderProbeMgr::smMaxProbesPerFrame, "Max number of Environment Probes that can be rendered per-frame.\n");
 }
 }
 
 
-ProbeRenderInst* RenderProbeMgr::registerProbe()
+void RenderProbeMgr::registerProbe(ProbeRenderInst* newProbe)
 {
 {
-   mRegisteredProbes.increment();
-   ProbeRenderInst* newProbe = &mRegisteredProbes.last();
+   //Can't have over the probe limit
+   if (mRegisteredProbes.size() + 1 >= PROBE_MAX_COUNT)
+      return;
+
+   mRegisteredProbes.push_back(newProbe);
 
 
    newProbe->mProbeIdx = mRegisteredProbes.size() - 1;
    newProbe->mProbeIdx = mRegisteredProbes.size() - 1;
 
 
@@ -339,7 +331,7 @@ ProbeRenderInst* RenderProbeMgr::registerProbe()
    if (cubeIndex == INVALID_CUBE_SLOT)
    if (cubeIndex == INVALID_CUBE_SLOT)
    {
    {
       Con::warnf("RenderProbeMgr::addProbe: Invalid cubemap slot.");
       Con::warnf("RenderProbeMgr::addProbe: Invalid cubemap slot.");
-      return nullptr;
+      return;
    }
    }
 
 
    //check if we need to resize the cubemap array
    //check if we need to resize the cubemap array
@@ -372,8 +364,6 @@ ProbeRenderInst* RenderProbeMgr::registerProbe()
 #endif
 #endif
 
 
    mProbesDirty = true;
    mProbesDirty = true;
-
-   return newProbe;
 }
 }
 
 
 void RenderProbeMgr::unregisterProbe(U32 probeIdx)
 void RenderProbeMgr::unregisterProbe(U32 probeIdx)
@@ -382,11 +372,11 @@ void RenderProbeMgr::unregisterProbe(U32 probeIdx)
    if (probeIdx >= mRegisteredProbes.size())
    if (probeIdx >= mRegisteredProbes.size())
       return;
       return;
 
 
-   if (mRegisteredProbes[probeIdx].mCubemapIndex == INVALID_CUBE_SLOT)
+   if (mRegisteredProbes[probeIdx]->mCubemapIndex == INVALID_CUBE_SLOT)
       return;
       return;
 
 
    //mark cubemap slot as available now
    //mark cubemap slot as available now
-   mCubeMapSlots[mRegisteredProbes[probeIdx].mCubemapIndex] = false;
+   mCubeMapSlots[mRegisteredProbes[probeIdx]->mCubemapIndex] = false;
    mCubeMapCount--;
    mCubeMapCount--;
 
 
    mRegisteredProbes.erase(probeIdx);
    mRegisteredProbes.erase(probeIdx);
@@ -394,13 +384,18 @@ void RenderProbeMgr::unregisterProbe(U32 probeIdx)
    //recalculate all the probe's indicies just to be sure
    //recalculate all the probe's indicies just to be sure
    for (U32 i = 0; i < mRegisteredProbes.size(); i++)
    for (U32 i = 0; i < mRegisteredProbes.size(); i++)
    {
    {
-      mRegisteredProbes[i].mProbeIdx = i;
+      mRegisteredProbes[i]->mProbeIdx = i;
    }
    }
 
 
    //rebuild our probe data
    //rebuild our probe data
    mProbesDirty = true;
    mProbesDirty = true;
 }
 }
 
 
+void RenderProbeMgr::submitProbe(const ProbeRenderInst& newProbe)
+{
+   mActiveProbes.push_back(newProbe);
+}
+
 //
 //
 //
 //
 PostEffect* RenderProbeMgr::getProbeArrayEffect()
 PostEffect* RenderProbeMgr::getProbeArrayEffect()
@@ -425,75 +420,6 @@ void RenderProbeMgr::updateProbes()
 	mProbesDirty = true;
 	mProbesDirty = true;
 }
 }
 
 
-void RenderProbeMgr::_setupStaticParameters()
-{
-   //Array rendering
-   U32 probeCount = mRegisteredProbes.size();
-
-   mEffectiveProbeCount = 0;
-   mMipCount = 1;
-
-   mHasSkylight = false;
-   mSkylightCubemapIdx = -1;
-
-   if (probePositionsData.size() != MAXPROBECOUNT)
-   {
-      probePositionsData.setSize(MAXPROBECOUNT);
-      probeRefPositionsData.setSize(MAXPROBECOUNT);
-      probeWorldToObjData.setSize(MAXPROBECOUNT);
-      refBoxMinData.setSize(MAXPROBECOUNT);
-      refBoxMaxData.setSize(MAXPROBECOUNT);
-      probeConfigData.setSize(MAXPROBECOUNT);
-   }
-
-   probePositionsData.fill(Point4F::Zero);
-   probeRefPositionsData.fill(Point4F::Zero);
-   probeWorldToObjData.fill(MatrixF::Identity);
-   refBoxMinData.fill(Point4F::Zero);
-   refBoxMaxData.fill(Point4F::Zero);
-   probeConfigData.fill(Point4F(-1,0,0,0));
-
-   for (U32 i = 0; i < probeCount; i++)
-   {
-      if (mEffectiveProbeCount >= MAXPROBECOUNT)
-         break;
-
-      const ProbeRenderInst& curEntry = mRegisteredProbes[i];
-      if (!curEntry.mIsEnabled)
-         continue;
-
-      U32 mips = mRegisteredProbes[i].mPrefilterCubemap.getPointer()->getMipMapLevels();
-      mMipCount = (mips != 0 && mips >= mMipCount) ? mips : 0;
-
-      if (curEntry.mIsSkylight)
-      {
-         mSkylightCubemapIdx = curEntry.mCubemapIndex;
-         continue;
-      }
-
-      //Setup
-      Point3F probePos = curEntry.getPosition();
-      Point3F refPos = curEntry.getPosition() +curEntry.mProbeRefOffset;
-      probePositionsData[mEffectiveProbeCount] = Point4F(probePos.x, probePos.y, probePos.z,0);
-      probeRefPositionsData[mEffectiveProbeCount] = Point4F(refPos.x, refPos.y, refPos.z, 0);
-
-      probeWorldToObjData[mEffectiveProbeCount] = curEntry.getTransform();
-      Point3F bbMin = refPos - curEntry.mProbeRefScale/2 * curEntry.getTransform().getScale();
-      Point3F bbMax = refPos + curEntry.mProbeRefScale/2 * curEntry.getTransform().getScale();
-      refBoxMinData[mEffectiveProbeCount] = Point4F(bbMin.x, bbMin.y, bbMin.z, 0);
-      refBoxMaxData[mEffectiveProbeCount] = Point4F(bbMax.x, bbMax.y, bbMax.z, 0);
-
-      probeConfigData[mEffectiveProbeCount] = Point4F(curEntry.mProbeShapeType, 
-         curEntry.mRadius,
-         curEntry.mAtten,
-         curEntry.mCubemapIndex);
-
-      mEffectiveProbeCount++;
-   }
-
-   mProbesDirty = false;
-}
-
 void RenderProbeMgr::updateProbeTexture(ProbeRenderInst* probeInfo)
 void RenderProbeMgr::updateProbeTexture(ProbeRenderInst* probeInfo)
 {
 {
    if (probeInfo->mIrradianceCubemap.isNull() || !probeInfo->mIrradianceCubemap->isInitialized())
    if (probeInfo->mIrradianceCubemap.isNull() || !probeInfo->mIrradianceCubemap->isInitialized())
@@ -523,7 +449,7 @@ void RenderProbeMgr::reloadTextures()
    U32 probeCount = mRegisteredProbes.size();
    U32 probeCount = mRegisteredProbes.size();
    for (U32 i = 0; i < probeCount; i++)
    for (U32 i = 0; i < probeCount; i++)
    {
    {
-      updateProbeTexture(&mRegisteredProbes[i]);
+      updateProbeTexture(mRegisteredProbes[i]);
    }
    }
 
 
    mProbesDirty = true;
    mProbesDirty = true;
@@ -532,6 +458,10 @@ void RenderProbeMgr::reloadTextures()
 void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state)
 void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state)
 {
 {
    PROFILE_SCOPE(RenderProbeMgr_SetupPerFrameParameters);
    PROFILE_SCOPE(RenderProbeMgr_SetupPerFrameParameters);
+
+   mProbeData = ProbeDataSet(smMaxProbesPerFrame);
+
+   getBestProbes(state->getCameraPosition(), &mProbeData);
 }
 }
 
 
 ProbeShaderConstants* RenderProbeMgr::getProbeShaderConstants(GFXShaderConstBuffer* buffer)
 ProbeShaderConstants* RenderProbeMgr::getProbeShaderConstants(GFXShaderConstBuffer* buffer)
@@ -579,6 +509,12 @@ ProbeShaderConstants* RenderProbeMgr::getProbeShaderConstants(GFXShaderConstBuff
    return mLastConstants;
    return mLastConstants;
 }
 }
 
 
+void RenderProbeMgr::setupSGData(SceneData& data, const SceneRenderState* state, LightInfo* light)
+{
+   //ensure they're sorted for forward rendering
+   mActiveProbes.sort(_probeScoreCmp);
+}
+
 void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
 void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
    MatrixSet &matSet,
    MatrixSet &matSet,
    ProbeShaderConstants *probeShaderConsts,
    ProbeShaderConstants *probeShaderConsts,
@@ -586,10 +522,8 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
 {
 {
    PROFILE_SCOPE(ProbeManager_Update4ProbeConsts);
    PROFILE_SCOPE(ProbeManager_Update4ProbeConsts);
 
 
-   return;
-
    // Skip over gathering lights if we don't have to!
    // Skip over gathering lights if we don't have to!
-   //if (probeShaderConsts->isValid())
+   if (probeShaderConsts->isValid())
    {
    {
       PROFILE_SCOPE(ProbeManager_Update4ProbeConsts_setProbes);
       PROFILE_SCOPE(ProbeManager_Update4ProbeConsts_setProbes);
 
 
@@ -600,17 +534,29 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
 
 
       getBestProbes(sgData.objTrans->getPosition(), &probeSet);
       getBestProbes(sgData.objTrans->getPosition(), &probeSet);
 
 
+      static AlignedArray<Point4F> probePositionAlignedArray(probeSet.maxProbeCount, sizeof(Point4F));
+      static AlignedArray<Point4F> refScaleAlignedArray(probeSet.maxProbeCount, sizeof(Point4F));
+      static AlignedArray<Point4F> probeRefPositionAlignedArray(probeSet.maxProbeCount, sizeof(Point4F));
+      static AlignedArray<Point4F> probeConfigAlignedArray(probeSet.maxProbeCount, sizeof(Point4F));
+
+      for (U32 i = 0; i < probeSet.maxProbeCount; i++)
+      {
+         probePositionAlignedArray[i] = probeSet.probePositionArray[i];
+         probeRefPositionAlignedArray[i] = probeSet.probeRefPositionArray[i];
+         refScaleAlignedArray[i] = probeSet.refScaleArray[i];
+         probeConfigAlignedArray[i] = probeSet.probeConfigArray[i];
+      }
+
       shaderConsts->setSafe(probeShaderConsts->mProbeCountSC, (S32)probeSet.effectiveProbeCount);
       shaderConsts->setSafe(probeShaderConsts->mProbeCountSC, (S32)probeSet.effectiveProbeCount);
 
 
-      shaderConsts->setSafe(probeShaderConsts->mProbePositionSC, probeSet.probePositionArray);
-      shaderConsts->setSafe(probeShaderConsts->mProbeRefPosSC, probeSet.probeRefPositionArray);
+      shaderConsts->setSafe(probeShaderConsts->mProbePositionSC, probePositionAlignedArray);
+      shaderConsts->setSafe(probeShaderConsts->mProbeRefPosSC, probeRefPositionAlignedArray);
 
 
       if(probeShaderConsts->isValid())
       if(probeShaderConsts->isValid())
          shaderConsts->set(probeShaderConsts->mWorldToObjArraySC, probeSet.probeWorldToObjArray.address(), probeSet.effectiveProbeCount, GFXSCT_Float4x4);
          shaderConsts->set(probeShaderConsts->mWorldToObjArraySC, probeSet.probeWorldToObjArray.address(), probeSet.effectiveProbeCount, GFXSCT_Float4x4);
 
 
-      shaderConsts->setSafe(probeShaderConsts->mRefBoxMinSC, probeSet.refBoxMinArray);
-      shaderConsts->setSafe(probeShaderConsts->mRefBoxMaxSC, probeSet.refBoxMaxArray);
-      shaderConsts->setSafe(probeShaderConsts->mProbeConfigDataSC, probeSet.probeConfigArray);
+      shaderConsts->setSafe(probeShaderConsts->mRefScaleSC, refScaleAlignedArray);
+      shaderConsts->setSafe(probeShaderConsts->mProbeConfigDataSC, probeConfigAlignedArray);
 
 
       shaderConsts->setSafe(probeShaderConsts->mSkylightCubemapIdxSC, (float)probeSet.skyLightIdx);
       shaderConsts->setSafe(probeShaderConsts->mSkylightCubemapIdxSC, (float)probeSet.skyLightIdx);
 
 
@@ -624,80 +570,70 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
    }
    }
 }
 }
 
 
+S32 QSORT_CALLBACK RenderProbeMgr::_probeScoreCmp(const ProbeRenderInst* a, const  ProbeRenderInst* b)
+{
+   F32 diff = a->getScore() - b->getScore();
+   return diff > 0 ? 1 : diff < 0 ? -1 : 0;
+}
+
 void RenderProbeMgr::getBestProbes(const Point3F& objPosition, ProbeDataSet* probeDataSet)
 void RenderProbeMgr::getBestProbes(const Point3F& objPosition, ProbeDataSet* probeDataSet)
 {
 {
    PROFILE_SCOPE(ProbeManager_getBestProbes);
    PROFILE_SCOPE(ProbeManager_getBestProbes);
 
 
-   // Skip over gathering lights if we don't have to!
-   //if (probeShaderConsts->isValid())
-   {
-      //Array rendering
-      U32 probeCount = mRegisteredProbes.size();
-
-      Vector<S8> bestPickProbes;
-
-      probeDataSet->effectiveProbeCount = 0;
-      for (U32 i = 0; i < probeCount; i++)
-      {
-         const ProbeRenderInst& curEntry = mRegisteredProbes[i];
-         if (!curEntry.mIsEnabled)
-            continue;
-
-         if (!curEntry.mIsSkylight)
-         {
-            F32 dist = Point3F(objPosition - curEntry.getPosition()).len();
+   //Array rendering
+   U32 probeCount = mActiveProbes.size();
 
 
-            if (dist > curEntry.mRadius || dist > curEntry.mExtents.len())
-               continue;
+   Vector<S8> bestPickProbes;
+   bestPickProbes.setSize(probeDataSet->maxProbeCount);
+   bestPickProbes.fill(-1);
 
 
-            S32 bestPickIndex = -1;
-            for (U32 p = 0; p < bestPickProbes.size(); p++)
-            {
-               if (p > probeDataSet->MAX_PROBE_COUNT)
-                  break;
+   probeDataSet->effectiveProbeCount = 0;
+   for (U32 i = 0; i < probeCount; i++)
+   {
+      if (probeDataSet->skyLightIdx != -1 && probeDataSet->effectiveProbeCount >= probeDataSet->maxProbeCount)
+         break;
 
 
-               if (bestPickProbes[p] == -1 || (Point3F(objPosition - mRegisteredProbes[bestPickProbes[p]].mPosition).len() > dist))
-                  bestPickIndex = p;
-            }
+      const ProbeRenderInst& curEntry = mActiveProbes[i];
+      if (!curEntry.mIsEnabled)
+         continue;
 
 
-            //Can't have over our max count. Otherwise, if we haven't found a good slot for our best pick, insert it
-            //if we have a best pick slot, update it
-            if (bestPickIndex == -1 || bestPickProbes.size() >= probeDataSet->MAX_PROBE_COUNT)
-               bestPickProbes.push_back(i);
-            else
-               bestPickProbes[bestPickIndex] = i;
-         }
-         else
+      if (curEntry.mProbeShapeType != ProbeRenderInst::Skylight)
+      {
+         if (probeDataSet->effectiveProbeCount < probeDataSet->maxProbeCount)
          {
          {
-            probeDataSet->skyLightIdx = curEntry.mCubemapIndex;
+            bestPickProbes[probeDataSet->effectiveProbeCount] = i;
+            probeDataSet->effectiveProbeCount++;
          }
          }
       }
       }
-
-      //Grab our best probe picks
-      for (U32 i = 0; i < bestPickProbes.size(); i++)
+      else
       {
       {
-         if (bestPickProbes[i] == -1)
-            continue;
+         probeDataSet->skyLightIdx = curEntry.mCubemapIndex;
+      }
+   }
+
+   //Grab our best probe picks
+   for (U32 i = 0; i < bestPickProbes.size(); i++)
+   {
+      if (bestPickProbes[i] == -1)
+         continue;
 
 
-         const ProbeRenderInst& curEntry = mRegisteredProbes[bestPickProbes[i]];
+      const ProbeRenderInst& curEntry = mActiveProbes[bestPickProbes[i]];
 
 
-         probeDataSet->probePositionArray[probeDataSet->effectiveProbeCount] = curEntry.getPosition();
-         probeDataSet->probeRefPositionArray[probeDataSet->effectiveProbeCount] = curEntry.mProbeRefOffset;
-         probeDataSet->probeWorldToObjArray[probeDataSet->effectiveProbeCount] = curEntry.getTransform();
+      MatrixF p2A = curEntry.getTransform();
+      p2A.inverse();
+      probeDataSet->refScaleArray[i] = curEntry.mProbeRefScale / p2A.getScale();
 
 
-         Point3F refPos = curEntry.getPosition() + curEntry.mProbeRefOffset;
-         Point3F refBoxMin = refPos - curEntry.mProbeRefScale * curEntry.getTransform().getScale();
-         Point3F refBoxMax = refPos + curEntry.mProbeRefScale * curEntry.getTransform().getScale();
+      Point3F probePos = curEntry.getPosition();
+      Point3F refPos = probePos + curEntry.mProbeRefOffset * probeDataSet->refScaleArray[i].asPoint3F();
+      probeDataSet->probeWorldToObjArray[i] = curEntry.getTransform();
 
 
-         probeDataSet->refBoxMinArray[probeDataSet->effectiveProbeCount] = Point4F(refBoxMin.x, refBoxMin.y, refBoxMin.z, 0);
-         probeDataSet->refBoxMaxArray[probeDataSet->effectiveProbeCount] = Point4F(refBoxMax.x, refBoxMax.y, refBoxMax.z, 0);
-         probeDataSet->probeConfigArray[probeDataSet->effectiveProbeCount] = Point4F(curEntry.mProbeShapeType,
-            curEntry.mRadius,
-            curEntry.mAtten,
-            curEntry.mCubemapIndex);
+      probeDataSet->probePositionArray[i] = Point4F(probePos.x, probePos.y, probePos.z, 0);
+      probeDataSet->probeRefPositionArray[i] = Point4F(refPos.x, refPos.y, refPos.z, 0);
 
 
-         probeDataSet->effectiveProbeCount++;
-      }
+      probeDataSet->probeConfigArray[i] = Point4F(curEntry.mProbeShapeType,
+         curEntry.mRadius,
+         curEntry.mAtten,
+         curEntry.mCubemapIndex);
    }
    }
 }
 }
 
 
@@ -720,9 +656,6 @@ void RenderProbeMgr::setProbeInfo(ProcessedMaterial *pmat,
    if (sgData.binType == SceneData::DeferredBin)
    if (sgData.binType == SceneData::DeferredBin)
       return;
       return;
 
 
-   // if (mRegisteredProbes.empty())
-   //    return;
-
    PROFILE_SCOPE(ProbeManager_setProbeInfo);
    PROFILE_SCOPE(ProbeManager_setProbeInfo);
 
 
    ProbeShaderConstants *psc = getProbeShaderConstants(shaderConsts);
    ProbeShaderConstants *psc = getProbeShaderConstants(shaderConsts);
@@ -747,26 +680,29 @@ void RenderProbeMgr::setProbeInfo(ProcessedMaterial *pmat,
 void RenderProbeMgr::render( SceneRenderState *state )
 void RenderProbeMgr::render( SceneRenderState *state )
 {
 {
    if (getProbeArrayEffect() == nullptr)
    if (getProbeArrayEffect() == nullptr)
+   {
+      mActiveProbes.clear();
       return;
       return;
+   }
+
+   GFXDEBUGEVENT_SCOPE(RenderProbeMgr_render, ColorI::WHITE);
+
+   //Sort the active probes
+   mActiveProbes.sort(_probeScoreCmp);
 
 
-   if (mProbesDirty)
-	   _setupStaticParameters();
+   // Initialize and set the per-frame data
+   _setupPerFrameParameters(state);
 
 
    // Early out if nothing to draw.
    // Early out if nothing to draw.
-   if (!RenderProbeMgr::smRenderReflectionProbes || (!state->isDiffusePass() && !state->isReflectPass()) || (mEffectiveProbeCount == 0 && mSkylightCubemapIdx == -1))
+   if (!RenderProbeMgr::smRenderReflectionProbes || (!state->isDiffusePass() && !state->isReflectPass()) || (mProbeData.effectiveProbeCount == 0 && mProbeData.skyLightIdx == -1))
    {
    {
       getProbeArrayEffect()->setSkip(true);
       getProbeArrayEffect()->setSkip(true);
+      mActiveProbes.clear();
       return;
       return;
    }
    }
 
 
    GFXTransformSaver saver;
    GFXTransformSaver saver;
 
 
-   GFXDEBUGEVENT_SCOPE(RenderProbeMgr_render, ColorI::WHITE);
-
-   // Initialize and set the per-frame parameters after getting
-   // the vector light material as we use lazy creation.
-   //_setupPerFrameParameters(state);
-
    //Visualization
    //Visualization
    String useDebugAtten = Con::getVariable("$Probes::showAttenuation", "0");
    String useDebugAtten = Con::getVariable("$Probes::showAttenuation", "0");
    mProbeArrayEffect->setShaderMacro("DEBUGVIZ_ATTENUATION", useDebugAtten);
    mProbeArrayEffect->setShaderMacro("DEBUGVIZ_ATTENUATION", useDebugAtten);
@@ -780,11 +716,14 @@ void RenderProbeMgr::render( SceneRenderState *state )
    String useDebugContrib = Con::getVariable("$Probes::showProbeContrib", "0");
    String useDebugContrib = Con::getVariable("$Probes::showProbeContrib", "0");
    mProbeArrayEffect->setShaderMacro("DEBUGVIZ_CONTRIB", useDebugContrib);
    mProbeArrayEffect->setShaderMacro("DEBUGVIZ_CONTRIB", useDebugContrib);
 
 
-   if(mSkylightCubemapIdx != -1 && mEffectiveProbeCount == 0)
+   if(mProbeData.skyLightIdx != -1 && mProbeData.effectiveProbeCount == 0)
       mProbeArrayEffect->setShaderMacro("SKYLIGHT_ONLY", "1");
       mProbeArrayEffect->setShaderMacro("SKYLIGHT_ONLY", "1");
    else
    else
       mProbeArrayEffect->setShaderMacro("SKYLIGHT_ONLY", "0");
       mProbeArrayEffect->setShaderMacro("SKYLIGHT_ONLY", "0");
 
 
+   String probePerFrame = Con::getVariable("$pref::MaxProbesPerFrame", "8");
+   mProbeArrayEffect->setShaderMacro("MAX_PROBES", probePerFrame);
+
    //ssao mask
    //ssao mask
    if (AdvancedLightBinManager::smUseSSAOMask)
    if (AdvancedLightBinManager::smUseSSAOMask)
    {
    {
@@ -795,7 +734,6 @@ void RenderProbeMgr::render( SceneRenderState *state )
       {
       {
          mProbeArrayEffect->setShaderMacro("USE_SSAO_MASK");
          mProbeArrayEffect->setShaderMacro("USE_SSAO_MASK");
          mProbeArrayEffect->setTexture(6, pTexObj);
          mProbeArrayEffect->setTexture(6, pTexObj);
-         
       }
       }
    }
    }
    else
    else
@@ -807,24 +745,24 @@ void RenderProbeMgr::render( SceneRenderState *state )
    mProbeArrayEffect->setCubemapArrayTexture(4, mPrefilterArray);
    mProbeArrayEffect->setCubemapArrayTexture(4, mPrefilterArray);
    mProbeArrayEffect->setCubemapArrayTexture(5, mIrradianceArray);
    mProbeArrayEffect->setCubemapArrayTexture(5, mIrradianceArray);
 
 
-   mProbeArrayEffect->setShaderConst("$numProbes", (S32)mEffectiveProbeCount);
-   mProbeArrayEffect->setShaderConst("$skylightCubemapIdx", (S32)mSkylightCubemapIdx);
+   mProbeArrayEffect->setShaderConst("$numProbes", (S32)mProbeData.effectiveProbeCount);
+   mProbeArrayEffect->setShaderConst("$skylightCubemapIdx", (S32)mProbeData.skyLightIdx);
 
 
    mProbeArrayEffect->setShaderConst("$cubeMips", (float)mMipCount);
    mProbeArrayEffect->setShaderConst("$cubeMips", (float)mMipCount);
 
 
    //also set up some colors
    //also set up some colors
    Vector<Point4F> contribColors;
    Vector<Point4F> contribColors;
 
 
-   contribColors.setSize(MAXPROBECOUNT);
+   contribColors.setSize(mProbeData.effectiveProbeCount);
 
 
-   if (mEffectiveProbeCount != 0)
+   if (mProbeData.effectiveProbeCount != 0)
    {
    {
       if (useDebugContrib == String("1"))
       if (useDebugContrib == String("1"))
       {
       {
          MRandomLCG RandomGen;
          MRandomLCG RandomGen;
-         RandomGen.setSeed(mEffectiveProbeCount);
+         RandomGen.setSeed(mProbeData.effectiveProbeCount);
 
 
-         for (U32 i = 0; i < mEffectiveProbeCount; i++)
+         for (U32 i = 0; i < mProbeData.effectiveProbeCount; i++)
          {
          {
             //we're going to cheat here a little for consistent debugging behavior. The first 3 probes will always have R G and then B for their colors, every other will be random
             //we're going to cheat here a little for consistent debugging behavior. The first 3 probes will always have R G and then B for their colors, every other will be random
             if (i == 0)
             if (i == 0)
@@ -841,20 +779,19 @@ void RenderProbeMgr::render( SceneRenderState *state )
 
 
    mProbeArrayEffect->setShaderConst("$probeContribColors", contribColors);
    mProbeArrayEffect->setShaderConst("$probeContribColors", contribColors);
 
 
-   mProbeArrayEffect->setShaderConst("$inProbePosArray", probePositionsData);
-   mProbeArrayEffect->setShaderConst("$inRefPosArray", probeRefPositionsData);
-   mProbeArrayEffect->setShaderConst("$worldToObjArray", probeWorldToObjData);
-   mProbeArrayEffect->setShaderConst("$refBoxMinArray", refBoxMinData);
-   mProbeArrayEffect->setShaderConst("$refBoxMaxArray", refBoxMaxData);
-   mProbeArrayEffect->setShaderConst("$probeConfigData", probeConfigData);
+   mProbeArrayEffect->setShaderConst("$inProbePosArray", mProbeData.probePositionArray);
+   mProbeArrayEffect->setShaderConst("$inRefPosArray", mProbeData.probeRefPositionArray);
+   mProbeArrayEffect->setShaderConst("$worldToObjArray", mProbeData.probeWorldToObjArray);
+   mProbeArrayEffect->setShaderConst("$refScaleArray", mProbeData.refScaleArray);
+   mProbeArrayEffect->setShaderConst("$probeConfigData", mProbeData.probeConfigArray);
 
 
    // Make sure the effect is gonna render.
    // Make sure the effect is gonna render.
    getProbeArrayEffect()->setSkip(false);
    getProbeArrayEffect()->setSkip(false);
 
 
-   //PROFILE_END();
+   mActiveProbes.clear();
 }
 }
 
 
-void RenderProbeMgr::bakeProbe(ReflectionProbe* probe, bool writeFiles)
+void RenderProbeMgr::bakeProbe(ReflectionProbe *probe)
 {
 {
    GFXDEBUGEVENT_SCOPE(RenderProbeMgr_Bake, ColorI::WHITE);
    GFXDEBUGEVENT_SCOPE(RenderProbeMgr_Bake, ColorI::WHITE);
 
 
@@ -863,15 +800,15 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe, bool writeFiles)
 
 
    String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/");
    String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/");
    U32 resolution = Con::getIntVariable("$pref::ReflectionProbes::BakeResolution", 64);
    U32 resolution = Con::getIntVariable("$pref::ReflectionProbes::BakeResolution", 64);
-   U32 prefilterMipLevels = mLog2(F32(resolution))+1;
+   U32 prefilterMipLevels = mLog2(F32(resolution)) + 1;
    bool renderWithProbes = Con::getIntVariable("$pref::ReflectionProbes::RenderWithProbes", false);
    bool renderWithProbes = Con::getIntVariable("$pref::ReflectionProbes::RenderWithProbes", false);
 
 
    ReflectionProbe* clientProbe = nullptr;
    ReflectionProbe* clientProbe = nullptr;
 
 
-   if (probe->isClientObject())
-      clientProbe = probe;
-   else
+   if (probe->isServerObject())
       clientProbe = static_cast<ReflectionProbe*>(probe->getClientObject());
       clientProbe = static_cast<ReflectionProbe*>(probe->getClientObject());
+   else
+      return;
 
 
    if (clientProbe == nullptr)
    if (clientProbe == nullptr)
       return;
       return;
@@ -901,7 +838,7 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe, bool writeFiles)
    reflDesc.texSize = resolution;
    reflDesc.texSize = resolution;
    reflDesc.farDist = farPlane;
    reflDesc.farDist = farPlane;
    reflDesc.detailAdjust = 1;
    reflDesc.detailAdjust = 1;
-   reflDesc.objectTypeMask = probe->mCaptureMask;
+   reflDesc.objectTypeMask = probe->mProbeShapeType == ProbeRenderInst::ProbeShapeType::Skylight ? SKYLIGHT_CAPTURE_TYPEMASK : REFLECTION_PROBE_CAPTURE_TYPEMASK;
 
 
    CubeReflector cubeRefl;
    CubeReflector cubeRefl;
    cubeRefl.registerReflector(probe, &reflDesc);
    cubeRefl.registerReflector(probe, &reflDesc);
@@ -939,13 +876,16 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe, bool writeFiles)
 
 
    GFXFormat reflectFormat;
    GFXFormat reflectFormat;
 
 
-   if (clientProbe->mUseHDRCaptures)
+   if (mUseHDRCaptures)
       reflectFormat = GFXFormatR16G16B16A16F;
       reflectFormat = GFXFormatR16G16B16A16F;
    else
    else
       reflectFormat = GFXFormatR8G8B8A8;
       reflectFormat = GFXFormatR8G8B8A8;
    const GFXFormat oldRefFmt = REFLECTMGR->getReflectFormat();
    const GFXFormat oldRefFmt = REFLECTMGR->getReflectFormat();
    REFLECTMGR->setReflectFormat(reflectFormat);
    REFLECTMGR->setReflectFormat(reflectFormat);
-   cubeRefl.updateReflection(reflParams);
+   
+   mProbeArrayEffect->setShaderConst("$CAPTURING", true);
+   cubeRefl.updateReflection(reflParams, clientProbe->getTransform().getPosition()+clientProbe->mProbeRefOffset);
+   mProbeArrayEffect->setShaderConst("$CAPTURING", false);
 
 
    //Now, save out the maps
    //Now, save out the maps
    //create irridiance cubemap
    //create irridiance cubemap
@@ -958,34 +898,24 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe, bool writeFiles)
       clientProbe->mIrridianceMap->mCubemap->initDynamic(resolution, reflectFormat);
       clientProbe->mIrridianceMap->mCubemap->initDynamic(resolution, reflectFormat);
       clientProbe->mPrefilterMap->mCubemap->initDynamic(resolution, reflectFormat);
       clientProbe->mPrefilterMap->mCubemap->initDynamic(resolution, reflectFormat);
 
 
-      if (mBakeRenderTarget == nullptr)
-         mBakeRenderTarget = GFX->allocRenderToTextureTarget(false);
-      else
-         mBakeRenderTarget->resurrect();
+      GFXTextureTargetRef renderTarget = GFX->allocRenderToTextureTarget(false);
 
 
-      IBLUtilities::GenerateIrradianceMap(mBakeRenderTarget, cubeRefl.getCubemap(), clientProbe->mIrridianceMap->mCubemap);
-      IBLUtilities::GeneratePrefilterMap(mBakeRenderTarget, cubeRefl.getCubemap(), prefilterMipLevels, clientProbe->mPrefilterMap->mCubemap);
+      IBLUtilities::GenerateIrradianceMap(renderTarget, cubeRefl.getCubemap(), clientProbe->mIrridianceMap->mCubemap);
+      IBLUtilities::GeneratePrefilterMap(renderTarget, cubeRefl.getCubemap(), prefilterMipLevels, clientProbe->mPrefilterMap->mCubemap);
 
 
       U32 endMSTime = Platform::getRealMilliseconds();
       U32 endMSTime = Platform::getRealMilliseconds();
       F32 diffTime = F32(endMSTime - startMSTime);
       F32 diffTime = F32(endMSTime - startMSTime);
       Con::warnf("RenderProbeMgr::bake() - Finished Capture! Took %g milliseconds", diffTime);
       Con::warnf("RenderProbeMgr::bake() - Finished Capture! Took %g milliseconds", diffTime);
+      Con::warnf("RenderProbeMgr::bake() - Beginning save now!");
 
 
-      if (writeFiles)
-      {
-         Con::warnf("RenderProbeMgr::bake() - Beginning save now!");
-
-         IBLUtilities::SaveCubeMap(clientProbe->getIrradianceMapPath(), clientProbe->mIrridianceMap->mCubemap);
-         IBLUtilities::SaveCubeMap(clientProbe->getPrefilterMapPath(), clientProbe->mPrefilterMap->mCubemap);
-      }
-
-      mBakeRenderTarget->zombify();
+      IBLUtilities::SaveCubeMap(clientProbe->getIrradianceMapPath(), clientProbe->mIrridianceMap->mCubemap);
+      IBLUtilities::SaveCubeMap(clientProbe->getPrefilterMapPath(), clientProbe->mPrefilterMap->mCubemap);
    }
    }
    else
    else
    {
    {
       Con::errorf("RenderProbeMgr::bake() - Didn't generate a valid scene capture cubemap, unable to generate prefilter and irradiance maps!");
       Con::errorf("RenderProbeMgr::bake() - Didn't generate a valid scene capture cubemap, unable to generate prefilter and irradiance maps!");
    }
    }
 
 
-
    if (!renderWithProbes)
    if (!renderWithProbes)
       RenderProbeMgr::smRenderReflectionProbes = probeRenderState;
       RenderProbeMgr::smRenderReflectionProbes = probeRenderState;
 
 
@@ -1002,12 +932,27 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe, bool writeFiles)
 
 
 void RenderProbeMgr::bakeProbes()
 void RenderProbeMgr::bakeProbes()
 {
 {
-   //TODO: make this just find every probe in the current missionGroup and run the bake on it automagically
+   Vector<ReflectionProbe*> probes;
+
+   Scene::getRootScene()->findObjectByType<ReflectionProbe>(probes);
+
+   for (U32 i = 0; i < probes.size(); i++)
+   {
+      if (probes[i]->isClientObject())
+         continue;
+
+      bakeProbe(probes[i]);
+   }
 }
 }
 
 
 DefineEngineMethod(RenderProbeMgr, bakeProbe, void, (ReflectionProbe* probe), (nullAsType< ReflectionProbe*>()),
 DefineEngineMethod(RenderProbeMgr, bakeProbe, void, (ReflectionProbe* probe), (nullAsType< ReflectionProbe*>()),
-   "@brief returns true if control object is inside the fog\n\n.")
+   "@brief Bakes the cubemaps for a reflection probe\n\n.")
 {
 {
    if(probe != nullptr)
    if(probe != nullptr)
       object->bakeProbe(probe);
       object->bakeProbe(probe);
 }
 }
+
+DefineEngineMethod(RenderProbeMgr, bakeProbes, void, (),, "@brief Iterates over all reflection probes in the scene and bakes their cubemaps\n\n.")
+{
+   object->bakeProbes();
+}

+ 46 - 46
Engine/source/renderInstance/renderProbeMgr.h

@@ -85,8 +85,6 @@ struct ProbeRenderInst
    /// when prioritizing lights for rendering.
    /// when prioritizing lights for rendering.
    F32 mScore;
    F32 mScore;
 
 
-   bool mIsSkylight;
-
    enum ProbeShapeType
    enum ProbeShapeType
    {
    {
       Box = 0,            ///< Sphere shaped
       Box = 0,            ///< Sphere shaped
@@ -115,9 +113,6 @@ public:
    Point3F getPosition() const { return mPosition; }
    Point3F getPosition() const { return mPosition; }
    void setPosition(const Point3F &pos) { mPosition = pos; }
    void setPosition(const Point3F &pos) { mPosition = pos; }
 
 
-   VectorF getDirection() const { return mTransform.getForwardVector(); }
-   void setDirection(const VectorF &val);
-
    void setPriority(F32 priority) { mPriority = priority; }
    void setPriority(F32 priority) { mPriority = priority; }
    F32 getPriority() const { return mPriority; }
    F32 getPriority() const { return mPriority; }
 
 
@@ -141,8 +136,7 @@ struct ProbeShaderConstants
    //Reflection Probes
    //Reflection Probes
    GFXShaderConstHandle *mProbePositionSC;
    GFXShaderConstHandle *mProbePositionSC;
    GFXShaderConstHandle *mProbeRefPosSC;
    GFXShaderConstHandle *mProbeRefPosSC;
-   GFXShaderConstHandle *mRefBoxMinSC;
-   GFXShaderConstHandle *mRefBoxMaxSC;
+   GFXShaderConstHandle *mRefScaleSC;
    GFXShaderConstHandle *mWorldToObjArraySC;
    GFXShaderConstHandle *mWorldToObjArraySC;
    GFXShaderConstHandle *mProbeConfigDataSC;
    GFXShaderConstHandle *mProbeConfigDataSC;
    GFXShaderConstHandle *mProbeSpecularCubemapSC;
    GFXShaderConstHandle *mProbeSpecularCubemapSC;
@@ -167,39 +161,43 @@ typedef Map<GFXShader*, ProbeShaderConstants*> ProbeConstantMap;
 
 
 struct ProbeDataSet
 struct ProbeDataSet
 {
 {
-   AlignedArray<Point4F> probePositionArray;
-   AlignedArray<Point4F> refBoxMinArray;
-   AlignedArray<Point4F> refBoxMaxArray;
-   AlignedArray<Point4F> probeRefPositionArray;
-   AlignedArray<Point4F> probeConfigArray;
+   Vector<Point4F> probePositionArray;
+   Vector<Point4F> refScaleArray;
+   Vector<Point4F> probeRefPositionArray;
+   Vector<Point4F> probeConfigArray;
 
 
    Vector<MatrixF> probeWorldToObjArray;
    Vector<MatrixF> probeWorldToObjArray;
 
 
    S32 skyLightIdx;
    S32 skyLightIdx;
 
 
    U32 effectiveProbeCount;
    U32 effectiveProbeCount;
+   U32 maxProbeCount;
+
+   ProbeDataSet()
+   {
+      probePositionArray.setSize(0);
+      refScaleArray.setSize(0);
+      probeRefPositionArray.setSize(0);
+      probeConfigArray.setSize(0);
 
 
-   U32 MAX_PROBE_COUNT;
+      probeWorldToObjArray.setSize(0);
+
+      skyLightIdx = -1;
+      effectiveProbeCount = 0;
+      maxProbeCount = 0;
+   }
 
 
-   ProbeDataSet(U32 maxProbeCount)
+   ProbeDataSet(U32 _maxProbeCount)
    {
    {
-      MAX_PROBE_COUNT = maxProbeCount;
+      maxProbeCount = _maxProbeCount;
 
 
-      probePositionArray = AlignedArray<Point4F>(maxProbeCount, sizeof(Point4F));
-      refBoxMinArray = AlignedArray<Point4F>(maxProbeCount, sizeof(Point4F));
-      refBoxMaxArray = AlignedArray<Point4F>(maxProbeCount, sizeof(Point4F));
-      probeRefPositionArray = AlignedArray<Point4F>(maxProbeCount, sizeof(Point4F));
-      probeConfigArray = AlignedArray<Point4F>(maxProbeCount, sizeof(Point4F));
+      probePositionArray.setSize(maxProbeCount);
+      refScaleArray.setSize(maxProbeCount);
+      probeRefPositionArray.setSize(maxProbeCount);
+      probeConfigArray.setSize(maxProbeCount);
 
 
       probeWorldToObjArray.setSize(maxProbeCount);
       probeWorldToObjArray.setSize(maxProbeCount);
 
 
-      // Need to clear the buffers so that we don't leak
-      // lights from previous passes or have NaNs.
-      dMemset(probePositionArray.getBuffer(), 0, probePositionArray.getBufferSize());
-      dMemset(refBoxMinArray.getBuffer(), 0, refBoxMinArray.getBufferSize());
-      dMemset(refBoxMaxArray.getBuffer(), 0, refBoxMaxArray.getBufferSize());
-      dMemset(probeRefPositionArray.getBuffer(), 0, probeRefPositionArray.getBufferSize());
-      dMemset(probeConfigArray.getBuffer(), 0, probeConfigArray.getBufferSize());
       skyLightIdx = -1;
       skyLightIdx = -1;
       effectiveProbeCount = 0;
       effectiveProbeCount = 0;
    }
    }
@@ -219,10 +217,11 @@ class RenderProbeMgr : public RenderBinManager
 {
 {
    typedef RenderBinManager Parent;
    typedef RenderBinManager Parent;
 
 
-   Vector<ProbeRenderInst> mRegisteredProbes;
+   Vector<ProbeRenderInst*> mRegisteredProbes;
 
 
    bool mProbesDirty;
    bool mProbesDirty;
-
+   
+   Vector<ProbeRenderInst>  mActiveProbes;
 public:
 public:
    //maximum number of allowed probes
    //maximum number of allowed probes
    static const U32 PROBE_MAX_COUNT = 250;
    static const U32 PROBE_MAX_COUNT = 250;
@@ -236,27 +235,17 @@ public:
    static const GFXFormat PROBE_FORMAT = GFXFormatR16G16B16A16F;// GFXFormatR8G8B8A8;// when hdr fixed GFXFormatR16G16B16A16F; look into bc6h compression
    static const GFXFormat PROBE_FORMAT = GFXFormatR16G16B16A16F;// GFXFormatR8G8B8A8;// when hdr fixed GFXFormatR16G16B16A16F; look into bc6h compression
    static const U32 INVALID_CUBE_SLOT = U32_MAX;
    static const U32 INVALID_CUBE_SLOT = U32_MAX;
 
 
+   static F32 smMaxProbeDrawDistance;
+   static S32 smMaxProbesPerFrame;
+
 private:
 private:
    //Array rendering
    //Array rendering
    U32 mEffectiveProbeCount;
    U32 mEffectiveProbeCount;
    S32 mMipCount;
    S32 mMipCount;
-   Vector<Point4F> probePositionsData;
-   Vector<Point4F> probeRefPositionsData;
-   Vector<MatrixF> probeWorldToObjData;
-   Vector<Point4F> refBoxMinData;
-   Vector<Point4F> refBoxMaxData;
-   Vector<Point4F> probeConfigData;
 
 
    bool            mHasSkylight;
    bool            mHasSkylight;
    S32             mSkylightCubemapIdx;
    S32             mSkylightCubemapIdx;
 
 
-   AlignedArray<Point4F> mProbePositions;
-   AlignedArray<Point4F> mRefBoxMin;
-   AlignedArray<Point4F> mRefBoxMax;
-   AlignedArray<float> mProbeUseSphereMode;
-   AlignedArray<float> mProbeRadius;
-   AlignedArray<float> mProbeAttenuation;
-
    //number of cubemaps
    //number of cubemaps
    U32 mCubeMapCount;
    U32 mCubeMapCount;
    //number of cubemap slots allocated
    //number of cubemap slots allocated
@@ -280,8 +269,12 @@ private:
 
 
    GFXTexHandle mBRDFTexture;
    GFXTexHandle mBRDFTexture;
 
 
-   GFXTextureTargetRef mBakeRenderTarget;
+   ProbeDataSet mProbeData;
+   ///Prevents us from saving out the cubemaps(for now) but allows us the full HDR range on the in-memory cubemap captures
+   bool mUseHDRCaptures;
 
 
+   U32 mPrefilterMipLevels;
+   U32 mPrefilterSize;
 public:
 public:
    RenderProbeMgr();
    RenderProbeMgr();
    RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder);
    RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder);
@@ -291,6 +284,8 @@ public:
 
 
    // ConsoleObject
    // ConsoleObject
    static void initPersistFields();
    static void initPersistFields();
+   static void consoleInit();
+
    DECLARE_CONOBJECT(RenderProbeMgr);
    DECLARE_CONOBJECT(RenderProbeMgr);
 
 
 protected:
 protected:
@@ -306,7 +301,7 @@ protected:
 
 
    void _setupStaticParameters();
    void _setupStaticParameters();
    void _setupPerFrameParameters(const SceneRenderState *state);
    void _setupPerFrameParameters(const SceneRenderState *state);
-   virtual void addElement(RenderInst *inst);
+   virtual void addElement(RenderInst* inst) {};
    virtual void render(SceneRenderState * state);
    virtual void render(SceneRenderState * state);
 
 
    ProbeShaderConstants* getProbeShaderConstants(GFXShaderConstBuffer* buffer);
    ProbeShaderConstants* getProbeShaderConstants(GFXShaderConstBuffer* buffer);
@@ -331,8 +326,11 @@ public:
    /// Returns the active LM.
    /// Returns the active LM.
    static inline RenderProbeMgr* getProbeManager();
    static inline RenderProbeMgr* getProbeManager();
 
 
-   ProbeRenderInst* registerProbe();
+   void registerProbe(ProbeRenderInst* newProbe);
    void unregisterProbe(U32 probeIdx);
    void unregisterProbe(U32 probeIdx);
+   void submitProbe(const ProbeRenderInst& newProbe);
+
+   static S32 QSORT_CALLBACK _probeScoreCmp(const ProbeRenderInst* a, const  ProbeRenderInst* b);
 
 
    virtual void setProbeInfo(ProcessedMaterial *pmat,
    virtual void setProbeInfo(ProcessedMaterial *pmat,
 	   const Material *mat,
 	   const Material *mat,
@@ -341,6 +339,8 @@ public:
 	   U32 pass,
 	   U32 pass,
 	   GFXShaderConstBuffer *shaderConsts);
 	   GFXShaderConstBuffer *shaderConsts);
 
 
+   void setupSGData(SceneData& data, const SceneRenderState* state, LightInfo* light);
+   
    void updateProbeTexture(ProbeRenderInst* probeInfo);
    void updateProbeTexture(ProbeRenderInst* probeInfo);
 
 
    void reloadTextures();
    void reloadTextures();
@@ -348,7 +348,7 @@ public:
    /// Debug rendering
    /// Debug rendering
    static bool smRenderReflectionProbes;
    static bool smRenderReflectionProbes;
 
 
-   void bakeProbe(ReflectionProbe *probeInfo, bool writeFile = true);
+   void bakeProbe(ReflectionProbe *probeInfo);
    void bakeProbes();
    void bakeProbes();
 
 
    void getProbeTextureData(ProbeTextureArrayData* probeTextureSet);
    void getProbeTextureData(ProbeTextureArrayData* probeTextureSet);

+ 12 - 4
Engine/source/scene/reflector.cpp

@@ -295,7 +295,7 @@ void CubeReflector::unregisterReflector()
    mEnabled = false;
    mEnabled = false;
 }
 }
 
 
-void CubeReflector::updateReflection( const ReflectParams &params )
+void CubeReflector::updateReflection( const ReflectParams &params, Point3F explicitPostion)
 {
 {
    GFXDEBUGEVENT_SCOPE( CubeReflector_UpdateReflection, ColorI::WHITE );
    GFXDEBUGEVENT_SCOPE( CubeReflector_UpdateReflection, ColorI::WHITE );
 
 
@@ -336,7 +336,7 @@ void CubeReflector::updateReflection( const ReflectParams &params )
 
 
 
 
    for ( U32 i = 0; i < 6; i++ )
    for ( U32 i = 0; i < 6; i++ )
-      updateFace( params, i );
+      updateFace( params, i, explicitPostion);
    
    
 
 
    GFX->popActiveRenderTarget();
    GFX->popActiveRenderTarget();
@@ -347,7 +347,7 @@ void CubeReflector::updateReflection( const ReflectParams &params )
    mLastTexSize = texDim;
    mLastTexSize = texDim;
 }
 }
 
 
-void CubeReflector::updateFace( const ReflectParams &params, U32 faceidx )
+void CubeReflector::updateFace( const ReflectParams &params, U32 faceidx, Point3F explicitPostion)
 {
 {
    GFXDEBUGEVENT_SCOPE( CubeReflector_UpdateFace, ColorI::WHITE );
    GFXDEBUGEVENT_SCOPE( CubeReflector_UpdateFace, ColorI::WHITE );
 
 
@@ -402,7 +402,15 @@ void CubeReflector::updateFace( const ReflectParams &params, U32 faceidx )
    matView.setColumn( 0, cross );
    matView.setColumn( 0, cross );
    matView.setColumn( 1, vLookatPt );
    matView.setColumn( 1, vLookatPt );
    matView.setColumn( 2, vUpVec );
    matView.setColumn( 2, vUpVec );
-   matView.setPosition( mObject->getPosition() );
+
+   if (explicitPostion == Point3F::Max)
+   {
+      matView.setPosition(mObject->getPosition());
+   }
+   else
+   {
+      matView.setPosition(explicitPostion);
+   }
    matView.inverse();
    matView.inverse();
 
 
    GFX->setWorldMatrix(matView);
    GFX->setWorldMatrix(matView);

+ 2 - 2
Engine/source/scene/reflector.h

@@ -151,11 +151,11 @@ public:
                            ReflectorDesc *inDesc );
                            ReflectorDesc *inDesc );
 
 
    virtual void unregisterReflector();
    virtual void unregisterReflector();
-   virtual void updateReflection( const ReflectParams &params );   
+   virtual void updateReflection( const ReflectParams &params, Point3F explicitPostion = Point3F::Max);
 
 
    GFXCubemap* getCubemap() const { return mCubemap; }
    GFXCubemap* getCubemap() const { return mCubemap; }
 
 
-   void updateFace( const ReflectParams &params, U32 faceidx );
+   void updateFace( const ReflectParams &params, U32 faceidx, Point3F explicitPostion = Point3F::Max);
    F32 calcFaceScore( const ReflectParams &params, U32 faceidx );
    F32 calcFaceScore( const ReflectParams &params, U32 faceidx );
 
 
 protected:
 protected:

+ 6 - 11
Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp

@@ -3004,15 +3004,10 @@ void ReflectionProbeFeatGLSL::processPix(Vector<ShaderComponent*>& componentList
    inRefPosArray->uniform = true;
    inRefPosArray->uniform = true;
    inRefPosArray->constSortPos = cspPotentialPrimitive;
    inRefPosArray->constSortPos = cspPotentialPrimitive;
 
 
-   Var * refBoxMinArray = new Var("inRefBoxMin", "vec4");
-   refBoxMinArray->arraySize = MAX_FORWARD_PROBES;
-   refBoxMinArray->uniform = true;
-   refBoxMinArray->constSortPos = cspPotentialPrimitive;
-
-   Var * refBoxMaxArray = new Var("inRefBoxMax", "vec4");
-   refBoxMaxArray->arraySize = MAX_FORWARD_PROBES;
-   refBoxMaxArray->uniform = true;
-   refBoxMaxArray->constSortPos = cspPotentialPrimitive;
+   Var * refScaleArray = new Var("inRefScale", "vec4");
+   refScaleArray->arraySize = MAX_FORWARD_PROBES;
+   refScaleArray->uniform = true;
+   refScaleArray->constSortPos = cspPotentialPrimitive;
 
 
    Var * probeConfigData = new Var("probeConfigData", "vec4");
    Var * probeConfigData = new Var("probeConfigData", "vec4");
    probeConfigData->arraySize = MAX_FORWARD_PROBES;
    probeConfigData->arraySize = MAX_FORWARD_PROBES;
@@ -3053,11 +3048,11 @@ void ReflectionProbeFeatGLSL::processPix(Vector<ShaderComponent*>& componentList
    Var *curColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
    Var *curColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
       
       
    //Reflection vec
    //Reflection vec
-   String computeForwardProbes = String("   @.rgb = computeForwardProbes(@,@,@,@,@,@,@,@,@,\r\n\t\t");
+   String computeForwardProbes = String("   @.rgb = computeForwardProbes(@,@,@,@,@,@,@,@,\r\n\t\t");
    computeForwardProbes += String("@,@,\r\n\t\t");
    computeForwardProbes += String("@,@,\r\n\t\t");
    computeForwardProbes += String("@,@).rgb; \r\n");
    computeForwardProbes += String("@,@).rgb; \r\n");
 
 
-   meta->addStatement(new GenOp(computeForwardProbes.c_str(), curColor, surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refBoxMinArray, refBoxMaxArray, inRefPosArray,
+   meta->addStatement(new GenOp(computeForwardProbes.c_str(), curColor, surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray,
       skylightCubemapIdx, BRDFTexture,
       skylightCubemapIdx, BRDFTexture,
       irradianceCubemapAR, specularCubemapAR));
       irradianceCubemapAR, specularCubemapAR));
 
 

+ 3 - 4
Engine/source/shaderGen/HLSL/debugVizFeatureHLSL.cpp

@@ -140,8 +140,7 @@ void DebugVizHLSL::processPix(Vector<ShaderComponent*>& componentList,
       Var* skylightCubemapIdx = (Var*)LangElement::find("skylightCubemapIdx");
       Var* skylightCubemapIdx = (Var*)LangElement::find("skylightCubemapIdx");
       Var* inProbePosArray = (Var*)LangElement::find("inProbePosArray");
       Var* inProbePosArray = (Var*)LangElement::find("inProbePosArray");
       Var* inRefPosArray = (Var*)LangElement::find("inRefPosArray");
       Var* inRefPosArray = (Var*)LangElement::find("inRefPosArray");
-      Var* refBoxMinArray = (Var*)LangElement::find("inRefBoxMin");
-      Var* refBoxMaxArray = (Var*)LangElement::find("inRefBoxMax");
+      Var* refScaleArray = (Var*)LangElement::find("inRefScale");
 
 
       Var* probeConfigData = (Var*)LangElement::find("probeConfigData");
       Var* probeConfigData = (Var*)LangElement::find("probeConfigData");
       Var* worldToObjArray = (Var*)LangElement::find("worldToObjArray");
       Var* worldToObjArray = (Var*)LangElement::find("worldToObjArray");
@@ -181,11 +180,11 @@ void DebugVizHLSL::processPix(Vector<ShaderComponent*>& componentList,
       dSprintf(buf, sizeof(buf), "   @ = %s;\r\n", showDiff);
       dSprintf(buf, sizeof(buf), "   @ = %s;\r\n", showDiff);
       meta->addStatement(new GenOp(buf, new DecOp(showDiffVar)));
       meta->addStatement(new GenOp(buf, new DecOp(showDiffVar)));
 
 
-      String computeForwardProbes = String::String("   @ = debugVizForwardProbes(@,@,@,@,@,@,@,@,@,\r\n\t\t");
+      String computeForwardProbes = String::String("   @ = debugVizForwardProbes(@,@,@,@,@,@,@,@,\r\n\t\t");
       computeForwardProbes += String::String("@,TORQUE_SAMPLER2D_MAKEARG(@),\r\n\t\t");
       computeForwardProbes += String::String("@,TORQUE_SAMPLER2D_MAKEARG(@),\r\n\t\t");
       computeForwardProbes += String::String("TORQUE_SAMPLERCUBEARRAY_MAKEARG(@),TORQUE_SAMPLERCUBEARRAY_MAKEARG(@), @, @, @, @).rgb; \r\n");
       computeForwardProbes += String::String("TORQUE_SAMPLERCUBEARRAY_MAKEARG(@),TORQUE_SAMPLERCUBEARRAY_MAKEARG(@), @, @, @, @).rgb; \r\n");
 
 
-      meta->addStatement(new GenOp(computeForwardProbes.c_str(), ibl, surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refBoxMinArray, refBoxMaxArray, inRefPosArray,
+      meta->addStatement(new GenOp(computeForwardProbes.c_str(), ibl, surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray,
          skylightCubemapIdx, BRDFTexture,
          skylightCubemapIdx, BRDFTexture,
          irradianceCubemapAR, specularCubemapAR,
          irradianceCubemapAR, specularCubemapAR,
          showAttenVar, showContribVar, showSpecVar, showDiffVar));
          showAttenVar, showContribVar, showSpecVar, showDiffVar));

+ 6 - 11
Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp

@@ -3075,15 +3075,10 @@ void ReflectionProbeFeatHLSL::processPix(Vector<ShaderComponent*> &componentList
    inRefPosArray->uniform = true;
    inRefPosArray->uniform = true;
    inRefPosArray->constSortPos = cspPotentialPrimitive;
    inRefPosArray->constSortPos = cspPotentialPrimitive;
 
 
-   Var * refBoxMinArray = new Var("inRefBoxMin", "float4");
-   refBoxMinArray->arraySize = MAX_FORWARD_PROBES;
-   refBoxMinArray->uniform = true;
-   refBoxMinArray->constSortPos = cspPotentialPrimitive;
-
-   Var * refBoxMaxArray = new Var("inRefBoxMax", "float4");
-   refBoxMaxArray->arraySize = MAX_FORWARD_PROBES;
-   refBoxMaxArray->uniform = true;
-   refBoxMaxArray->constSortPos = cspPotentialPrimitive;
+   Var * refScaleArray = new Var("inRefScale", "float4");
+   refScaleArray->arraySize = MAX_FORWARD_PROBES;
+   refScaleArray->uniform = true;
+   refScaleArray->constSortPos = cspPotentialPrimitive;
 
 
    Var *probeConfigData = new Var("probeConfigData", "float4");
    Var *probeConfigData = new Var("probeConfigData", "float4");
    probeConfigData->arraySize = MAX_FORWARD_PROBES;
    probeConfigData->arraySize = MAX_FORWARD_PROBES;
@@ -3142,11 +3137,11 @@ void ReflectionProbeFeatHLSL::processPix(Vector<ShaderComponent*> &componentList
       ibl = new Var("ibl", "float3");
       ibl = new Var("ibl", "float3");
    }
    }
 
 
-   String computeForwardProbes = String::String("   @ = computeForwardProbes(@,@,@,@,@,@,@,@,@,\r\n\t\t");
+   String computeForwardProbes = String::String("   @ = computeForwardProbes(@,@,@,@,@,@,@,@,\r\n\t\t");
    computeForwardProbes += String::String("@,TORQUE_SAMPLER2D_MAKEARG(@),\r\n\t\t"); 
    computeForwardProbes += String::String("@,TORQUE_SAMPLER2D_MAKEARG(@),\r\n\t\t"); 
    computeForwardProbes += String::String("TORQUE_SAMPLERCUBEARRAY_MAKEARG(@),TORQUE_SAMPLERCUBEARRAY_MAKEARG(@)).rgb; \r\n");
    computeForwardProbes += String::String("TORQUE_SAMPLERCUBEARRAY_MAKEARG(@),TORQUE_SAMPLERCUBEARRAY_MAKEARG(@)).rgb; \r\n");
       
       
-   meta->addStatement(new GenOp(computeForwardProbes.c_str(), new DecOp(ibl), surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refBoxMinArray, refBoxMaxArray, inRefPosArray,
+   meta->addStatement(new GenOp(computeForwardProbes.c_str(), new DecOp(ibl), surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray,
       skylightCubemapIdx, BRDFTexture,
       skylightCubemapIdx, BRDFTexture,
       irradianceCubemapAR, specularCubemapAR));
       irradianceCubemapAR, specularCubemapAR));
 
 

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

@@ -81,8 +81,7 @@ const String ShaderGenVars::glowMul("$glowMul");
 //Reflection Probes
 //Reflection Probes
 const String ShaderGenVars::probePosition("$inProbePosArray");
 const String ShaderGenVars::probePosition("$inProbePosArray");
 const String ShaderGenVars::probeRefPos("$inRefPosArray");
 const String ShaderGenVars::probeRefPos("$inRefPosArray");
-const String ShaderGenVars::refBoxMin("$inRefBoxMin");
-const String ShaderGenVars::refBoxMax("$inRefBoxMax");
+const String ShaderGenVars::refScale("$inRefScale");
 const String ShaderGenVars::worldToObjArray("$worldToObjArray");
 const String ShaderGenVars::worldToObjArray("$worldToObjArray");
 const String ShaderGenVars::probeConfigData("$probeConfigData");
 const String ShaderGenVars::probeConfigData("$probeConfigData");
 const String ShaderGenVars::specularCubemapAR("$specularCubemapAR");
 const String ShaderGenVars::specularCubemapAR("$specularCubemapAR");

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

@@ -93,8 +93,7 @@ struct ShaderGenVars
    //Reflection Probes
    //Reflection Probes
    const static String probePosition;
    const static String probePosition;
    const static String probeRefPos;
    const static String probeRefPos;
-   const static String refBoxMin;
-   const static String refBoxMax;
+   const static String refScale;
    const static String worldToObjArray;
    const static String worldToObjArray;
    const static String probeConfigData;
    const static String probeConfigData;
    const static String specularCubemapAR;
    const static String specularCubemapAR;

+ 17 - 9
Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl

@@ -44,7 +44,10 @@ uniform vec4 albedo;
 
 
 #endif // !TORQUE_SHADERGEN
 #endif // !TORQUE_SHADERGEN
 
 
-#define MAX_PROBES 50
+#ifndef MAX_PROBES
+#define MAX_PROBES 8
+#endif
+
 #define MAX_FORWARD_PROBES 4
 #define MAX_FORWARD_PROBES 4
 
 
 #define MAX_FORWARD_LIGHT 4
 #define MAX_FORWARD_LIGHT 4
@@ -216,7 +219,12 @@ vec3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
    float D = D_GGX(surfaceToLight.NdotH, surface.linearRoughnessSq);
    float D = D_GGX(surfaceToLight.NdotH, surface.linearRoughnessSq);
    vec3 Fr = D * F * Vis;
    vec3 Fr = D * F * Vis;
 
 
+#if CAPTURING == true
+   return mix(Fd + Fr,surface.f0,surface.metalness);
+#else
    return Fd + Fr;
    return Fd + Fr;
+#endif
+
 }
 }
 
 
 vec3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float shadow)
 vec3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float shadow)
@@ -331,14 +339,14 @@ float defineBoxSpaceInfluence(vec3 wsPosition, mat4 worldToObj, float attenuatio
 // Box Projected IBL Lighting
 // Box Projected IBL Lighting
 // Based on: http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/
 // Based on: http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/
 // and https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
 // and https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
-vec3 boxProject(vec3 wsPosition, vec3 wsReflectVec, mat4 worldToObj, vec3 refBoxMin, vec3 refBoxMax, vec3 refPosition)
+vec3 boxProject(vec3 wsPosition, vec3 wsReflectVec, mat4 worldToObj, vec3 refScale, vec3 refPosition)
 {
 {
    vec3 RayLS = tMul(worldToObj, vec4(wsReflectVec, 0.0)).xyz;
    vec3 RayLS = tMul(worldToObj, vec4(wsReflectVec, 0.0)).xyz;
    vec3 PositionLS = tMul(worldToObj, vec4(wsPosition, 1.0)).xyz;
    vec3 PositionLS = tMul(worldToObj, vec4(wsPosition, 1.0)).xyz;
 
 
-   vec3 unit = refBoxMax.xyz - refBoxMin.xyz;
-   vec3 plane1vec = (unit / 2 - PositionLS) / RayLS;
-   vec3 plane2vec = (-unit / 2 - PositionLS) / RayLS;
+   vec3 unit = refScale;
+   vec3 plane1vec = (unit - PositionLS) / RayLS;
+   vec3 plane2vec = (-unit - PositionLS) / RayLS;
    vec3 furthestPlane = max(plane1vec, plane2vec);
    vec3 furthestPlane = max(plane1vec, plane2vec);
    float dist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z);
    float dist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z);
    vec3 posonbox = wsPosition + wsReflectVec * dist;
    vec3 posonbox = wsPosition + wsReflectVec * dist;
@@ -348,7 +356,7 @@ vec3 boxProject(vec3 wsPosition, vec3 wsReflectVec, mat4 worldToObj, vec3 refBox
 
 
 vec4 computeForwardProbes(Surface surface,
 vec4 computeForwardProbes(Surface surface,
     float cubeMips, int numProbes, mat4x4 worldToObjArray[MAX_FORWARD_PROBES], vec4 probeConfigData[MAX_FORWARD_PROBES], 
     float cubeMips, int numProbes, mat4x4 worldToObjArray[MAX_FORWARD_PROBES], vec4 probeConfigData[MAX_FORWARD_PROBES], 
-    vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 refBoxMinArray[MAX_FORWARD_PROBES], vec4 refBoxMaxArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES],
+    vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 refScaleArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES],
     float skylightCubemapIdx, sampler2D BRDFTexture, 
     float skylightCubemapIdx, sampler2D BRDFTexture, 
 	samplerCubeArray irradianceCubemapAR, samplerCubeArray specularCubemapAR)
 	samplerCubeArray irradianceCubemapAR, samplerCubeArray specularCubemapAR)
 {
 {
@@ -452,7 +460,7 @@ vec4 computeForwardProbes(Surface surface,
       if (contrib > 0.0f)
       if (contrib > 0.0f)
       {
       {
          float cubemapIdx = int(probeConfigData[i].a);
          float cubemapIdx = int(probeConfigData[i].a);
-         vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refBoxMinArray[i].xyz, refBoxMaxArray[i].xyz, inRefPosArray[i].xyz);
+         vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz);
 
 
          irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib;
          irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib;
          specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib;
          specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib;
@@ -490,7 +498,7 @@ vec4 computeForwardProbes(Surface surface,
 
 
 vec4 debugVizForwardProbes(Surface surface,
 vec4 debugVizForwardProbes(Surface surface,
     float cubeMips, int numProbes, mat4 worldToObjArray[MAX_FORWARD_PROBES], vec4 probeConfigData[MAX_FORWARD_PROBES], 
     float cubeMips, int numProbes, mat4 worldToObjArray[MAX_FORWARD_PROBES], vec4 probeConfigData[MAX_FORWARD_PROBES], 
-    vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 refBoxMinArray[MAX_FORWARD_PROBES], vec4 refBoxMaxArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES],
+    vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 refScaleArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES],
     float skylightCubemapIdx, sampler2D BRDFTexture, 
     float skylightCubemapIdx, sampler2D BRDFTexture, 
 	 samplerCubeArray irradianceCubemapAR, samplerCubeArray specularCubemapAR, int showAtten, int showContrib, int showSpec, int showDiff)
 	 samplerCubeArray irradianceCubemapAR, samplerCubeArray specularCubemapAR, int showAtten, int showContrib, int showSpec, int showDiff)
 {
 {
@@ -601,7 +609,7 @@ vec4 debugVizForwardProbes(Surface surface,
       if (contrib > 0.0f)
       if (contrib > 0.0f)
       {
       {
          float cubemapIdx = probeConfigData[i].a;
          float cubemapIdx = probeConfigData[i].a;
-         vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refBoxMinArray[i].xyz, refBoxMaxArray[i].xyz, inRefPosArray[i].xyz);
+         vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz);
 
 
          irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib;
          irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib;
          specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib;
          specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib;

+ 18 - 10
Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl

@@ -45,7 +45,10 @@ uniform float4 albedo;
 
 
 #endif // !TORQUE_SHADERGEN
 #endif // !TORQUE_SHADERGEN
 
 
-#define MAX_PROBES 50
+#ifndef MAX_PROBES
+#define MAX_PROBES 8
+#endif
+
 #define MAX_FORWARD_PROBES 4
 #define MAX_FORWARD_PROBES 4
 
 
 #define MAX_FORWARD_LIGHT 4
 #define MAX_FORWARD_LIGHT 4
@@ -216,8 +219,13 @@ float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
    float Vis = V_SmithGGXCorrelated(surface.NdotV, surfaceToLight.NdotL, surface.linearRoughnessSq);
    float Vis = V_SmithGGXCorrelated(surface.NdotV, surfaceToLight.NdotL, surface.linearRoughnessSq);
    float D = D_GGX(surfaceToLight.NdotH, surface.linearRoughnessSq);
    float D = D_GGX(surfaceToLight.NdotH, surface.linearRoughnessSq);
    float3 Fr = D * F * Vis;
    float3 Fr = D * F * Vis;
-
+   
+#if CAPTURING == true
+    return lerp(Fd + Fr,surface.f0,surface.metalness);
+#else
    return Fd + Fr;
    return Fd + Fr;
+#endif
+
 }
 }
 
 
 float3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float shadow)
 float3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float shadow)
@@ -335,14 +343,14 @@ float defineBoxSpaceInfluence(float3 wsPosition, float4x4 worldToObj, float atte
 // Box Projected IBL Lighting
 // Box Projected IBL Lighting
 // Based on: http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/
 // Based on: http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/
 // and https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
 // and https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
-float3 boxProject(float3 wsPosition, float3 wsReflectVec, float4x4 worldToObj, float3 refBoxMin, float3 refBoxMax, float3 refPosition)
+float3 boxProject(float3 wsPosition, float3 wsReflectVec, float4x4 worldToObj, float3 refScale, float3 refPosition)
 {
 {
    float3 RayLS = mul(worldToObj, float4(wsReflectVec, 0.0)).xyz;
    float3 RayLS = mul(worldToObj, float4(wsReflectVec, 0.0)).xyz;
    float3 PositionLS = mul(worldToObj, float4(wsPosition, 1.0)).xyz;
    float3 PositionLS = mul(worldToObj, float4(wsPosition, 1.0)).xyz;
 
 
-   float3 unit = refBoxMax.xyz - refBoxMin.xyz;
-   float3 plane1vec = (unit / 2 - PositionLS) / RayLS;
-   float3 plane2vec = (-unit / 2 - PositionLS) / RayLS;
+   float3 unit = refScale;
+   float3 plane1vec = (unit - PositionLS) / RayLS;
+   float3 plane2vec = (-unit - PositionLS) / RayLS;
    float3 furthestPlane = max(plane1vec, plane2vec);
    float3 furthestPlane = max(plane1vec, plane2vec);
    float dist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z);
    float dist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z);
    float3 posonbox = wsPosition + wsReflectVec * dist;
    float3 posonbox = wsPosition + wsReflectVec * dist;
@@ -352,7 +360,7 @@ float3 boxProject(float3 wsPosition, float3 wsReflectVec, float4x4 worldToObj, f
 
 
 float4 computeForwardProbes(Surface surface,
 float4 computeForwardProbes(Surface surface,
     float cubeMips, int numProbes, float4x4 worldToObjArray[MAX_FORWARD_PROBES], float4 probeConfigData[MAX_FORWARD_PROBES], 
     float cubeMips, int numProbes, float4x4 worldToObjArray[MAX_FORWARD_PROBES], float4 probeConfigData[MAX_FORWARD_PROBES], 
-    float4 inProbePosArray[MAX_FORWARD_PROBES], float4 refBoxMinArray[MAX_FORWARD_PROBES], float4 refBoxMaxArray[MAX_FORWARD_PROBES], float4 inRefPosArray[MAX_FORWARD_PROBES],
+    float4 inProbePosArray[MAX_FORWARD_PROBES], float4 refScaleArray[MAX_FORWARD_PROBES], float4 inRefPosArray[MAX_FORWARD_PROBES],
     float skylightCubemapIdx, TORQUE_SAMPLER2D(BRDFTexture), 
     float skylightCubemapIdx, TORQUE_SAMPLER2D(BRDFTexture), 
 	 TORQUE_SAMPLERCUBEARRAY(irradianceCubemapAR), TORQUE_SAMPLERCUBEARRAY(specularCubemapAR))
 	 TORQUE_SAMPLERCUBEARRAY(irradianceCubemapAR), TORQUE_SAMPLERCUBEARRAY(specularCubemapAR))
 {
 {
@@ -456,7 +464,7 @@ float4 computeForwardProbes(Surface surface,
       if (contrib > 0.0f)
       if (contrib > 0.0f)
       {
       {
          int cubemapIdx = probeConfigData[i].a;
          int cubemapIdx = probeConfigData[i].a;
-         float3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refBoxMinArray[i].xyz, refBoxMaxArray[i].xyz, inRefPosArray[i].xyz);
+         float3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz);
 
 
          irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib;
          irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib;
          specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib;
          specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib;
@@ -494,7 +502,7 @@ float4 computeForwardProbes(Surface surface,
 
 
 float4 debugVizForwardProbes(Surface surface,
 float4 debugVizForwardProbes(Surface surface,
     float cubeMips, int numProbes, float4x4 worldToObjArray[MAX_FORWARD_PROBES], float4 probeConfigData[MAX_FORWARD_PROBES], 
     float cubeMips, int numProbes, float4x4 worldToObjArray[MAX_FORWARD_PROBES], float4 probeConfigData[MAX_FORWARD_PROBES], 
-    float4 inProbePosArray[MAX_FORWARD_PROBES], float4 refBoxMinArray[MAX_FORWARD_PROBES], float4 refBoxMaxArray[MAX_FORWARD_PROBES], float4 inRefPosArray[MAX_FORWARD_PROBES],
+    float4 inProbePosArray[MAX_FORWARD_PROBES], float4 refScaleArray[MAX_FORWARD_PROBES], float4 inRefPosArray[MAX_FORWARD_PROBES],
     float skylightCubemapIdx, TORQUE_SAMPLER2D(BRDFTexture), 
     float skylightCubemapIdx, TORQUE_SAMPLER2D(BRDFTexture), 
 	 TORQUE_SAMPLERCUBEARRAY(irradianceCubemapAR), TORQUE_SAMPLERCUBEARRAY(specularCubemapAR), int showAtten, int showContrib, int showSpec, int showDiff)
 	 TORQUE_SAMPLERCUBEARRAY(irradianceCubemapAR), TORQUE_SAMPLERCUBEARRAY(specularCubemapAR), int showAtten, int showContrib, int showSpec, int showDiff)
 {
 {
@@ -605,7 +613,7 @@ float4 debugVizForwardProbes(Surface surface,
       if (contrib > 0.0f)
       if (contrib > 0.0f)
       {
       {
          int cubemapIdx = probeConfigData[i].a;
          int cubemapIdx = probeConfigData[i].a;
-         float3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refBoxMinArray[i].xyz, refBoxMaxArray[i].xyz, inRefPosArray[i].xyz);
+         float3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz);
 
 
          irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib;
          irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib;
          specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib;
          specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib;

+ 1 - 0
Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/prefilterP.glsl

@@ -127,4 +127,5 @@ void main()
 {   
 {   
 	vec3 N = getCubeDir(face, uv0);
 	vec3 N = getCubeDir(face, uv0);
 	OUT_col = prefilterEnvMap(N);
 	OUT_col = prefilterEnvMap(N);
+	OUT_col.a = 1;
 }
 }

+ 2 - 3
Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl

@@ -33,8 +33,7 @@ uniform vec4 rtParams6;
 uniform vec4    inProbePosArray[MAX_PROBES];
 uniform vec4    inProbePosArray[MAX_PROBES];
 uniform vec4    inRefPosArray[MAX_PROBES];
 uniform vec4    inRefPosArray[MAX_PROBES];
 uniform mat4    worldToObjArray[MAX_PROBES];
 uniform mat4    worldToObjArray[MAX_PROBES];
-uniform vec4    refBoxMinArray[MAX_PROBES];
-uniform vec4    refBoxMaxArray[MAX_PROBES];
+uniform vec4    refScaleArray[MAX_PROBES];
 uniform vec4    probeConfigData[MAX_PROBES];   //r,g,b/mode,radius,atten
 uniform vec4    probeConfigData[MAX_PROBES];   //r,g,b/mode,radius,atten
 
 
 #if DEBUGVIZ_CONTRIB
 #if DEBUGVIZ_CONTRIB
@@ -180,7 +179,7 @@ void main()
       if (contrib > 0.0f)
       if (contrib > 0.0f)
       {
       {
          float cubemapIdx = probeConfigData[i].a;
          float cubemapIdx = probeConfigData[i].a;
-         vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refBoxMinArray[i].xyz, refBoxMaxArray[i].xyz, inRefPosArray[i].xyz);
+         vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz);
 
 
          irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib;
          irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib;
          specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib;
          specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib;

+ 1 - 1
Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/prefilterP.hlsl

@@ -126,5 +126,5 @@ float4 prefilterEnvMap(float3 R)
 float4 main(ConnectData IN) : TORQUE_TARGET0
 float4 main(ConnectData IN) : TORQUE_TARGET0
 {
 {
 	float3 N = getCubeDir(face, IN.uv);
 	float3 N = getCubeDir(face, IN.uv);
-	return prefilterEnvMap(N);
+	return float4(prefilterEnvMap(N).rgb,1.0);
 }
 }

+ 2 - 3
Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl

@@ -30,8 +30,7 @@ uniform float4 rtParams6;
 uniform float4    inProbePosArray[MAX_PROBES];
 uniform float4    inProbePosArray[MAX_PROBES];
 uniform float4    inRefPosArray[MAX_PROBES];
 uniform float4    inRefPosArray[MAX_PROBES];
 uniform float4x4  worldToObjArray[MAX_PROBES];
 uniform float4x4  worldToObjArray[MAX_PROBES];
-uniform float4    refBoxMinArray[MAX_PROBES];
-uniform float4    refBoxMaxArray[MAX_PROBES];
+uniform float4    refScaleArray[MAX_PROBES];
 uniform float4    probeConfigData[MAX_PROBES];   //r,g,b/mode,radius,atten
 uniform float4    probeConfigData[MAX_PROBES];   //r,g,b/mode,radius,atten
 
 
 #if DEBUGVIZ_CONTRIB
 #if DEBUGVIZ_CONTRIB
@@ -172,7 +171,7 @@ float4 main(PFXVertToPix IN) : SV_TARGET
       if (contrib > 0.0f)
       if (contrib > 0.0f)
       {
       {
          int cubemapIdx = probeConfigData[i].a;
          int cubemapIdx = probeConfigData[i].a;
-         float3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refBoxMinArray[i].xyz, refBoxMaxArray[i].xyz, inRefPosArray[i].xyz);
+         float3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz);
 
 
          irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib;
          irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib;
          specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib;
          specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib;

+ 5 - 11
Templates/BaseGame/game/tools/worldEditor/scripts/probeBake.ed.cs

@@ -39,17 +39,11 @@ function ProbeBakeDlg_RunBake::onClick(%this)
       if(%iter != 0)
       if(%iter != 0)
          $pref::ReflectionProbes::RenderWithProbes = true;
          $pref::ReflectionProbes::RenderWithProbes = true;
          
          
-      for(%i=0; %i < %probeCount; %i++)
-      {
-         %probe = getWord(%probeIds, %i);
-         
-         $pref::ReflectionProbes::CurrentLevelPath = filePath($Server::MissionFile) @ "/" @ fileBase($Server::MissionFile) @ "/probes/";
-         ProbeBin.bakeProbe(%probe);
-         
-         %currentProgressValue += %progressStep;
-         ProbeBakeDlg_Progress.setValue(%currentProgressValue);
-         Canvas.repaint();
-      }
+      $pref::ReflectionProbes::CurrentLevelPath = filePath($Server::MissionFile) @ "/" @ fileBase($Server::MissionFile) @ "/probes/";
+      ProbeBin.bakeProbes();
+      
+      %currentProgressValue += %progressStep;
+      ProbeBakeDlg_Progress.setValue(%currentProgressValue);
    }
    }
    
    
    EWorldEditor.isDirty = true;
    EWorldEditor.isDirty = true;