Browse Source

Corrected the blending logic somewhat, added visualization modes for spec/diffuse probe influences, attenuation and contribution.

Areloch 6 years ago
parent
commit
b754c022ba

+ 10 - 2
Engine/source/T3D/lighting/reflectionProbe.cpp

@@ -272,6 +272,8 @@ bool ReflectionProbe::onAdd()
    {
    {
       createGeometry();
       createGeometry();
       updateProbeParams();
       updateProbeParams();
+
+      PROBEMGR->registerProbe(mProbeInfoIdx);
    }
    }
   
   
    setMaskBits(-1);
    setMaskBits(-1);
@@ -281,6 +283,10 @@ bool ReflectionProbe::onAdd()
 
 
 void ReflectionProbe::onRemove()
 void ReflectionProbe::onRemove()
 {
 {
+   if (isClientObject())
+   {
+      PROBEMGR->unregisterProbe(mProbeInfoIdx);
+   }
    // Remove this object from the scene
    // Remove this object from the scene
    removeFromScene();
    removeFromScene();
 
 
@@ -441,7 +447,7 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
       updateMaterial();
       updateMaterial();
    }
    }
 
 
-   //PROBEMGR->updateProbes();
+   PROBEMGR->updateProbes();
 }
 }
 
 
 void ReflectionProbe::createGeometry()
 void ReflectionProbe::createGeometry()
@@ -597,6 +603,8 @@ void ReflectionProbe::updateMaterial()
       mProbeInfo->mIsEnabled = true;
       mProbeInfo->mIsEnabled = true;
    else
    else
       mProbeInfo->mIsEnabled = false;
       mProbeInfo->mIsEnabled = false;
+
+   PROBEMGR->updateProbes();
 }
 }
 
 
 bool ReflectionProbe::createClientResources()
 bool ReflectionProbe::createClientResources()
@@ -682,7 +690,7 @@ void ReflectionProbe::prepRenderImage(SceneRenderState *state)
    mProbeInfo->mScore *= mMax(mAbs(mDot(vect, state->getCameraTransform().getForwardVector())),0.001f);
    mProbeInfo->mScore *= mMax(mAbs(mDot(vect, state->getCameraTransform().getForwardVector())),0.001f);
 
 
    //Register
    //Register
-   PROBEMGR->registerProbe(mProbeInfoIdx);
+   //PROBEMGR->registerProbe(mProbeInfoIdx);
 
 
    if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr)
    if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr)
    {
    {

+ 47 - 20
Engine/source/renderInstance/renderProbeMgr.cpp

@@ -230,7 +230,7 @@ void RenderProbeMgr::registerProbe(U32 probeIdx)
    mRegisteredProbes.push_back_unique(probeIdx);
    mRegisteredProbes.push_back_unique(probeIdx);
 
 
    //rebuild our probe data
    //rebuild our probe data
-   //_setupStaticParameters();
+   _setupStaticParameters();
 }
 }
 
 
 void RenderProbeMgr::unregisterProbe(U32 probeIdx)
 void RenderProbeMgr::unregisterProbe(U32 probeIdx)
@@ -242,7 +242,7 @@ void RenderProbeMgr::unregisterProbe(U32 probeIdx)
    mRegisteredProbes.remove(probeIdx);
    mRegisteredProbes.remove(probeIdx);
 
 
    //rebuild our probe data
    //rebuild our probe data
-   //_setupStaticParameters();
+   _setupStaticParameters();
 }
 }
 
 
 //
 //
@@ -283,22 +283,21 @@ void RenderProbeMgr::_setupStaticParameters()
       probeWorldToObjData.setSize(MAXPROBECOUNT);
       probeWorldToObjData.setSize(MAXPROBECOUNT);
       probeBBMinData.setSize(MAXPROBECOUNT);
       probeBBMinData.setSize(MAXPROBECOUNT);
       probeBBMaxData.setSize(MAXPROBECOUNT);
       probeBBMaxData.setSize(MAXPROBECOUNT);
-      probeUseSphereModeData.setSize(MAXPROBECOUNT);
-      probeRadiusData.setSize(MAXPROBECOUNT);
-      probeAttenuationData.setSize(MAXPROBECOUNT);
+      probeConfigData.setSize(MAXPROBECOUNT);
    }
    }
 
 
    probePositionsData.fill(Point4F::Zero);
    probePositionsData.fill(Point4F::Zero);
    probeWorldToObjData.fill(MatrixF::Identity);
    probeWorldToObjData.fill(MatrixF::Identity);
    probeBBMinData.fill(Point4F::Zero);
    probeBBMinData.fill(Point4F::Zero);
    probeBBMaxData.fill(Point4F::Zero);
    probeBBMaxData.fill(Point4F::Zero);
-   probeUseSphereModeData.fill(Point4F::Zero);
-   probeRadiusData.fill(Point4F::Zero);
-   probeAttenuationData.fill(Point4F::Zero);
+   probeConfigData.fill(Point4F::Zero);
 
 
    cubeMaps.clear();
    cubeMaps.clear();
    irradMaps.clear();
    irradMaps.clear();
 
 
+   //This should probably ultimately be a per-probe value, but for now, global for testing/adjustability
+   F32 attenuation = Con::getFloatVariable("$pref::ReflectionProbes::AttenuationStrength", 3.5);
+
    for (U32 i = 0; i < probeCount; i++)
    for (U32 i = 0; i < probeCount; i++)
    {
    {
       if (mEffectiveProbeCount >= MAXPROBECOUNT)
       if (mEffectiveProbeCount >= MAXPROBECOUNT)
@@ -320,7 +319,7 @@ void RenderProbeMgr::_setupStaticParameters()
       if (curEntry.mIsSkylight)
       if (curEntry.mIsSkylight)
          continue;
          continue;
 
 
-	  mMipCount = curEntry.mCubemap.getPointer()->getMipMapLevels();
+	   mMipCount = curEntry.mCubemap.getPointer()->getMipMapLevels();
 
 
       //Setup
       //Setup
       Point3F probePos = curEntry.getPosition() + curEntry.mProbePosOffset;
       Point3F probePos = curEntry.getPosition() + curEntry.mProbePosOffset;
@@ -331,10 +330,10 @@ void RenderProbeMgr::_setupStaticParameters()
       probeBBMinData[mEffectiveProbeCount] = Point4F(curEntry.mBounds.minExtents.x, curEntry.mBounds.minExtents.y, curEntry.mBounds.minExtents.z, 0);
       probeBBMinData[mEffectiveProbeCount] = Point4F(curEntry.mBounds.minExtents.x, curEntry.mBounds.minExtents.y, curEntry.mBounds.minExtents.z, 0);
       probeBBMaxData[mEffectiveProbeCount] = Point4F(curEntry.mBounds.maxExtents.x, curEntry.mBounds.maxExtents.y, curEntry.mBounds.maxExtents.z, 0);
       probeBBMaxData[mEffectiveProbeCount] = Point4F(curEntry.mBounds.maxExtents.x, curEntry.mBounds.maxExtents.y, curEntry.mBounds.maxExtents.z, 0);
 
 
-      probeUseSphereModeData[mEffectiveProbeCount] = Point4F(curEntry.mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0, 0,0,0);
-
-      probeRadiusData[mEffectiveProbeCount] = Point4F(curEntry.mRadius,0,0,0);
-      probeAttenuationData[mEffectiveProbeCount] = Point4F(1, 0, 0, 0);
+      probeConfigData[mEffectiveProbeCount] = Point4F(curEntry.mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0, 
+         curEntry.mRadius,
+         attenuation,
+         1);
 
 
       cubeMaps.push_back(curEntry.mCubemap);
       cubeMaps.push_back(curEntry.mCubemap);
       irradMaps.push_back(curEntry.mIrradianceCubemap);
       irradMaps.push_back(curEntry.mIrradianceCubemap);
@@ -423,7 +422,7 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
       static AlignedArray<Point3F> probeLocalPositions(4, sizeof(Point3F));
       static AlignedArray<Point3F> probeLocalPositions(4, sizeof(Point3F));
       static AlignedArray<F32> probeIsSphere(4, sizeof(F32));
       static AlignedArray<F32> probeIsSphere(4, sizeof(F32));
       //static AlignedArray<CubemapData> probeCubemap(4, sizeof(CubemapData));
       //static AlignedArray<CubemapData> probeCubemap(4, sizeof(CubemapData));
-      F32 range;
+      //F32 range;
 
 
       // Need to clear the buffers so that we don't leak
       // Need to clear the buffers so that we don't leak
       // lights from previous passes or have NaNs.
       // lights from previous passes or have NaNs.
@@ -437,7 +436,7 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
 
 
       matSet.restoreSceneViewProjection();
       matSet.restoreSceneViewProjection();
 
 
-      const MatrixF &worldToCameraXfm = matSet.getWorldToCamera();
+      //const MatrixF &worldToCameraXfm = matSet.getWorldToCamera();
 
 
       // Gather the data for the first 4 probes.
       // Gather the data for the first 4 probes.
       /*const ProbeRenderInst *probe;
       /*const ProbeRenderInst *probe;
@@ -586,7 +585,7 @@ void RenderProbeMgr::render( SceneRenderState *state )
    if (getProbeArrayEffect() == nullptr)
    if (getProbeArrayEffect() == nullptr)
       return;
       return;
 
 
-   updateProbes();
+   //updateProbes();
 
 
    // Early out if nothing to draw.
    // Early out if nothing to draw.
    if (!ProbeRenderInst::all.size() || !RenderProbeMgr::smRenderReflectionProbes || mEffectiveProbeCount == 0
    if (!ProbeRenderInst::all.size() || !RenderProbeMgr::smRenderReflectionProbes || mEffectiveProbeCount == 0
@@ -605,13 +604,43 @@ void RenderProbeMgr::render( SceneRenderState *state )
    //_setupPerFrameParameters(state);
    //_setupPerFrameParameters(state);
    
    
    //Array rendering
    //Array rendering
-   U32 probeCount = ProbeRenderInst::all.size();
+   //U32 probeCount = ProbeRenderInst::all.size();
 
 
    if (mEffectiveProbeCount != 0)
    if (mEffectiveProbeCount != 0)
    {
    {
       mProbeArrayEffect->setCubemapArrayTexture(4, mCubemapArray);
       mProbeArrayEffect->setCubemapArrayTexture(4, mCubemapArray);
       mProbeArrayEffect->setCubemapArrayTexture(5, mIrradArray);
       mProbeArrayEffect->setCubemapArrayTexture(5, mIrradArray);
 
 
+      String useDebugAtten = Con::getVariable("$Probes::showAttenuation", "0");
+      mProbeArrayEffect->setShaderMacro("DEBUGVIZ_ATTENUATION", useDebugAtten);
+
+      String useDebugSpecCubemap = Con::getVariable("$Probes::showSpecularCubemaps", "0");
+      mProbeArrayEffect->setShaderMacro("DEBUGVIZ_SPECCUBEMAP", useDebugSpecCubemap);
+
+      String useDebugDiffuseCubemap = Con::getVariable("$Probes::showDiffuseCubemaps", "0");
+      mProbeArrayEffect->setShaderMacro("DEBUGVIZ_DIFFCUBEMAP", useDebugDiffuseCubemap);
+
+      String useDebugContrib = Con::getVariable("$Probes::showProbeContrib", "0");
+      mProbeArrayEffect->setShaderMacro("DEBUGVIZ_CONTRIB", useDebugContrib);
+
+      if (useDebugContrib == String("1"))
+      {
+         MRandomLCG RandomGen;
+         RandomGen.setSeed(mEffectiveProbeCount);
+
+         //also set up some colors
+         Vector<Point4F> contribColors;
+
+         contribColors.setSize(MAXPROBECOUNT);
+
+         for (U32 i = 0; i < mEffectiveProbeCount; i++)
+         {
+            contribColors[i] = Point4F(RandomGen.randF(0, 1), RandomGen.randF(0, 1), RandomGen.randF(0, 1),1);
+         }
+
+         mProbeArrayEffect->setShaderConst("$probeContribColors", contribColors);
+      }
+
       mProbeArrayEffect->setShaderConst("$cubeMips", (float)mMipCount);
       mProbeArrayEffect->setShaderConst("$cubeMips", (float)mMipCount);
       
       
       mProbeArrayEffect->setShaderConst("$numProbes", (float)mEffectiveProbeCount);
       mProbeArrayEffect->setShaderConst("$numProbes", (float)mEffectiveProbeCount);
@@ -619,9 +648,7 @@ void RenderProbeMgr::render( SceneRenderState *state )
       mProbeArrayEffect->setShaderConst("$worldToObjArray", probeWorldToObjData);
       mProbeArrayEffect->setShaderConst("$worldToObjArray", probeWorldToObjData);
       mProbeArrayEffect->setShaderConst("$bbMinArray", probeBBMinData);
       mProbeArrayEffect->setShaderConst("$bbMinArray", probeBBMinData);
       mProbeArrayEffect->setShaderConst("$bbMaxArray", probeBBMaxData);
       mProbeArrayEffect->setShaderConst("$bbMaxArray", probeBBMaxData);
-      mProbeArrayEffect->setShaderConst("$useSphereMode", probeUseSphereModeData);
-      mProbeArrayEffect->setShaderConst("$radius", probeRadiusData);
-      mProbeArrayEffect->setShaderConst("$attenuation", probeAttenuationData);
+      mProbeArrayEffect->setShaderConst("$probeConfigData", probeConfigData);
    }
    }
 
 
    // Make sure the effect is gonna render.
    // Make sure the effect is gonna render.

+ 1 - 3
Engine/source/renderInstance/renderProbeMgr.h

@@ -164,9 +164,7 @@ class RenderProbeMgr : public RenderBinManager
    Vector<MatrixF> probeWorldToObjData;
    Vector<MatrixF> probeWorldToObjData;
    Vector<Point4F> probeBBMinData;
    Vector<Point4F> probeBBMinData;
    Vector<Point4F> probeBBMaxData;
    Vector<Point4F> probeBBMaxData;
-   Vector<Point4F> probeUseSphereModeData;
-   Vector<Point4F> probeRadiusData;
-   Vector<Point4F> probeAttenuationData;
+   Vector<Point4F> probeConfigData;
    Vector<GFXCubemapHandle> cubeMaps;
    Vector<GFXCubemapHandle> cubeMaps;
    Vector<GFXCubemapHandle> irradMaps;
    Vector<GFXCubemapHandle> irradMaps;
 
 

+ 125 - 11
Templates/Full/game/levels/AProbeTest.mis

@@ -132,7 +132,7 @@ new SimGroup(MissionGroup) {
       posOffset = "0 0 0";
       posOffset = "0 0 0";
       ReflectionMode = "Baked Cubemap";
       ReflectionMode = "Baked Cubemap";
       Bake = "0";
       Bake = "0";
-      position = "0 0 4";
+      position = "-0.0194688 0 4";
       rotation = "1 0 0 0";
       rotation = "1 0 0 0";
       scale = "5 5 5";
       scale = "5 5 5";
       canSave = "1";
       canSave = "1";
@@ -152,7 +152,7 @@ new SimGroup(MissionGroup) {
       posOffset = "0 0 0";
       posOffset = "0 0 0";
       ReflectionMode = "Baked Cubemap";
       ReflectionMode = "Baked Cubemap";
       Bake = "0";
       Bake = "0";
-      position = "-10 8 4";
+      position = "-7.18203 8.03441 4";
       rotation = "1 0 0 0";
       rotation = "1 0 0 0";
       scale = "5 5 5";
       scale = "5 5 5";
       canSave = "1";
       canSave = "1";
@@ -171,7 +171,7 @@ new SimGroup(MissionGroup) {
       posOffset = "0 0 0";
       posOffset = "0 0 0";
       ReflectionMode = "Baked Cubemap";
       ReflectionMode = "Baked Cubemap";
       Bake = "0";
       Bake = "0";
-      position = "-10 0 4";
+      position = "-10.0428 0.020255 4";
       rotation = "1 0 0 0";
       rotation = "1 0 0 0";
       scale = "5 5 5";
       scale = "5 5 5";
       canSave = "1";
       canSave = "1";
@@ -190,7 +190,7 @@ new SimGroup(MissionGroup) {
       posOffset = "0 0 0";
       posOffset = "0 0 0";
       ReflectionMode = "Baked Cubemap";
       ReflectionMode = "Baked Cubemap";
       Bake = "0";
       Bake = "0";
-      position = "-10 -8 4";
+      position = "-7.8725 -8.01423 4";
       rotation = "1 0 0 0";
       rotation = "1 0 0 0";
       scale = "5 5 5";
       scale = "5 5 5";
       canSave = "1";
       canSave = "1";
@@ -203,6 +203,120 @@ new SimGroup(MissionGroup) {
          reflectionPath = "levels/probeTest/probes/";
          reflectionPath = "levels/probeTest/probes/";
          SkyColor = "0.5 0.5 1 1";
          SkyColor = "0.5 0.5 1 1";
    };
    };
+   new BoxEnvironmentProbe() {
+      enabled = "1";
+      radius = "5";
+      posOffset = "0 0 0";
+      ReflectionMode = "Baked Cubemap";
+      Bake = "0";
+      position = "-0.618301 -7.21245 4";
+      rotation = "1 0 0 0";
+      scale = "5 5 5";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+      persistentId = "9b2db461-3291-11e9-8898-df29fd75d18c";
+         GroundColor = "0.8 0.7 0.5 1";
+         IndirectLight = "1 1 1 1";
+         IndirectLightMode = "Spherical Harmonics";
+         Intensity = "1";
+         reflectionPath = "levels/probeTest/probes/";
+         SkyColor = "0.5 0.5 1 1";
+   };
+   new BoxEnvironmentProbe() {
+      enabled = "1";
+      radius = "5";
+      posOffset = "0 0 0";
+      ReflectionMode = "Baked Cubemap";
+      Bake = "0";
+      position = "-19.8124 -1.4213 4";
+      rotation = "1 0 0 0";
+      scale = "5 5 5";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+      persistentId = "9850277f-3291-11e9-8898-df29fd75d18c";
+         GroundColor = "0.8 0.7 0.5 1";
+         IndirectLight = "1 1 1 1";
+         IndirectLightMode = "Spherical Harmonics";
+         Intensity = "1";
+         reflectionPath = "levels/probeTest/probes/";
+         SkyColor = "0.5 0.5 1 1";
+   };
+   new BoxEnvironmentProbe() {
+      enabled = "1";
+      radius = "5";
+      posOffset = "0 0 0";
+      ReflectionMode = "Baked Cubemap";
+      Bake = "0";
+      position = "-4.665 12.4006 4";
+      rotation = "1 0 0 0";
+      scale = "5 5 5";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+      persistentId = "9752cd1f-3291-11e9-8898-df29fd75d18c";
+         GroundColor = "0.8 0.7 0.5 1";
+         IndirectLight = "1 1 1 1";
+         IndirectLightMode = "Spherical Harmonics";
+         Intensity = "1";
+         reflectionPath = "levels/probeTest/probes/";
+         SkyColor = "0.5 0.5 1 1";
+   };
+   new BoxEnvironmentProbe() {
+      enabled = "1";
+      radius = "5";
+      posOffset = "0 0 0";
+      ReflectionMode = "Baked Cubemap";
+      Bake = "0";
+      position = "-12.7966 11.7207 4";
+      rotation = "1 0 0 0";
+      scale = "5 5 5";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+      persistentId = "9536f9d8-3291-11e9-8898-df29fd75d18c";
+         GroundColor = "0.8 0.7 0.5 1";
+         IndirectLight = "1 1 1 1";
+         IndirectLightMode = "Spherical Harmonics";
+         Intensity = "1";
+         reflectionPath = "levels/probeTest/probes/";
+         SkyColor = "0.5 0.5 1 1";
+   };
+   new BoxEnvironmentProbe() {
+      enabled = "1";
+      radius = "5";
+      posOffset = "0 0 0";
+      ReflectionMode = "Baked Cubemap";
+      Bake = "0";
+      position = "-16.0723 -6.9977 4";
+      rotation = "1 0 0 0";
+      scale = "5 5 5";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+      persistentId = "8f479759-3291-11e9-8898-df29fd75d18c";
+         GroundColor = "0.8 0.7 0.5 1";
+         IndirectLight = "1 1 1 1";
+         IndirectLightMode = "Spherical Harmonics";
+         Intensity = "1";
+         reflectionPath = "levels/probeTest/probes/";
+         SkyColor = "0.5 0.5 1 1";
+   };
+   new BoxEnvironmentProbe() {
+      enabled = "1";
+      radius = "5";
+      posOffset = "0 0 0";
+      ReflectionMode = "Baked Cubemap";
+      Bake = "0";
+      position = "-16.0723 5.77606 4";
+      rotation = "1 0 0 0";
+      scale = "5 5 5";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+      persistentId = "8856e1d2-3291-11e9-8898-df29fd75d18c";
+         GroundColor = "0.8 0.7 0.5 1";
+         IndirectLight = "1 1 1 1";
+         IndirectLightMode = "Spherical Harmonics";
+         Intensity = "1";
+         reflectionPath = "levels/probeTest/probes/";
+         SkyColor = "0.5 0.5 1 1";
+   };
    new ConvexShape() {
    new ConvexShape() {
       Material = "Grid512_Orange_Mat";
       Material = "Grid512_Orange_Mat";
       position = "0.487092 0.454657 9.4951";
       position = "0.487092 0.454657 9.4951";
@@ -213,7 +327,7 @@ new SimGroup(MissionGroup) {
 
 
       surface = "0 0 0 1 0 0 0.5";
       surface = "0 0 0 1 0 0 0.5";
       surface = "0 1 0 0 0 0 -0.5";
       surface = "0 1 0 0 0 0 -0.5";
-      surface = "0.707107 0 0 0.707107 0 0.5 0";
+      surface = "0.707107 0 0 0.707106 0 0.5 0";
       surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
       surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
       surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
       surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
       surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
       surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
@@ -228,7 +342,7 @@ new SimGroup(MissionGroup) {
 
 
       surface = "0 0 0 1 0 0 0.5";
       surface = "0 0 0 1 0 0 0.5";
       surface = "0 1 0 0 0 0 -0.5";
       surface = "0 1 0 0 0 0 -0.5";
-      surface = "0.707107 0 0 0.707107 0 0.5 0";
+      surface = "0.707107 0 0 0.707106 0 0.5 0";
       surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
       surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
       surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
       surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
       surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
       surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
@@ -243,7 +357,7 @@ new SimGroup(MissionGroup) {
 
 
       surface = "0 0 0 1 0 0 0.5";
       surface = "0 0 0 1 0 0 0.5";
       surface = "0 1 0 0 0 0 -0.5";
       surface = "0 1 0 0 0 0 -0.5";
-      surface = "0.707107 0 0 0.707106 0 0.5 0";
+      surface = "0.707107 0 0 0.707107 0 0.5 0";
       surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
       surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
       surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
       surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
       surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
       surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
@@ -258,7 +372,7 @@ new SimGroup(MissionGroup) {
 
 
       surface = "0 0 0 1 0 0 0.5";
       surface = "0 0 0 1 0 0 0.5";
       surface = "0 1 0 0 0 0 -0.5";
       surface = "0 1 0 0 0 0 -0.5";
-      surface = "0.707107 0 0 0.707106 0 0.5 0";
+      surface = "0.707107 0 0 0.707107 0 0.5 0";
       surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
       surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
       surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
       surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
       surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
       surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
@@ -273,7 +387,7 @@ new SimGroup(MissionGroup) {
 
 
       surface = "0 0 0 1 0 0 0.5";
       surface = "0 0 0 1 0 0 0.5";
       surface = "0 1 0 0 0 0 -0.5";
       surface = "0 1 0 0 0 0 -0.5";
-      surface = "0.707107 0 0 0.707106 0 0.5 0";
+      surface = "0.707107 0 0 0.707107 0 0.5 0";
       surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
       surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
       surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
       surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
       surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
       surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
@@ -288,7 +402,7 @@ new SimGroup(MissionGroup) {
 
 
       surface = "0 0 0 1 0 0 0.5";
       surface = "0 0 0 1 0 0 0.5";
       surface = "0 1 0 0 0 0 -0.5";
       surface = "0 1 0 0 0 0 -0.5";
-      surface = "0.707107 0 0 0.707107 0 0.5 0";
+      surface = "0.707107 0 0 0.707106 0 0.5 0";
       surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
       surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
       surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
       surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
       surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
       surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
@@ -303,7 +417,7 @@ new SimGroup(MissionGroup) {
 
 
       surface = "0 0 0 1 0 0 0.5";
       surface = "0 0 0 1 0 0 0.5";
       surface = "0 1 0 0 0 0 -0.5";
       surface = "0 1 0 0 0 0 -0.5";
-      surface = "0.707107 0 0 0.707106 0 0.5 0";
+      surface = "0.707107 0 0 0.707107 0 0.5 0";
       surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
       surface = "0 0.707107 -0.707107 0 0 -0.5 -2.84217e-14";
       surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
       surface = "0.5 0.5 -0.5 0.5 -0.5 0 -9.93411e-08";
       surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";
       surface = "0.5 -0.5 0.5 0.5 0.5 0 -9.93411e-08";

+ 84 - 45
Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl

@@ -26,15 +26,20 @@ uniform float4    inProbePosArray[MAX_PROBES];
 uniform float4x4  worldToObjArray[MAX_PROBES];
 uniform float4x4  worldToObjArray[MAX_PROBES];
 uniform float4    bbMinArray[MAX_PROBES];
 uniform float4    bbMinArray[MAX_PROBES];
 uniform float4    bbMaxArray[MAX_PROBES];
 uniform float4    bbMaxArray[MAX_PROBES];
-uniform float4     useSphereMode[MAX_PROBES];
-uniform float4     radius[MAX_PROBES];
-uniform float4    attenuation[MAX_PROBES];
+uniform float4     probeConfigData[MAX_PROBES];   //r,g,b/mode,radius,atten
+
+#if DEBUGVIZ_CONTRIB
+uniform float4    probeContribColors[MAX_PROBES];
+#endif
 
 
 // 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 reflectDir, float3 boxWSPos, float3 boxMin, float3 boxMax)
+float3 boxProject(float3 wsPosition, float3 wsEyeRay, float3 reflectDir, float3 boxWSPos, float3 boxMin, float3 boxMax)
 { 
 { 
+   //float3 rayLS = mul(worldToObjArray[id], float4(wsEyeRay, 1.0)).xyz;
+   //float3 reflCameraLS = mul(worldToObjArray[id], float4(reflectDir), 1.0)).xyz;
+
    float3 nrdir = reflectDir;
    float3 nrdir = reflectDir;
 	float3 offset = wsPosition;
 	float3 offset = wsPosition;
    float3 plane1vec = (boxMax - offset) / nrdir;
    float3 plane1vec = (boxMax - offset) / nrdir;
@@ -49,23 +54,19 @@ float3 boxProject(float3 wsPosition, float3 reflectDir, float3 boxWSPos, float3
 
 
 float3 iblBoxDiffuse( Surface surface, int id)
 float3 iblBoxDiffuse( Surface surface, int id)
 {
 {
-   float3 cubeN = boxProject(surface.P, surface.N, inProbePosArray[id].xyz, bbMinArray[id].xyz, bbMaxArray[id].xyz);
+   float3 cubeN = boxProject(surface.P, surface.V, surface.R, inProbePosArray[id].xyz, bbMinArray[id].xyz, bbMaxArray[id].xyz);
    cubeN.z *=-1;
    cubeN.z *=-1;
    return TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR,cubeN,id,0).xyz;
    return TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR,cubeN,id,0).xyz;
 }
 }
 
 
-float3 iblBoxSpecular(Surface surface, float3 surfToEye, TORQUE_SAMPLER2D(brdfTexture), int id)
+float3 iblBoxSpecular(Surface surface, TORQUE_SAMPLER2D(brdfTexture), int id)
 {
 {
-   float ndotv = clamp(dot(surface.N, surfToEye), 0.0, 1.0);
-
     // BRDF
     // BRDF
-   float2 brdf = TORQUE_TEX2DLOD(brdfTexture, float4(surface.roughness, ndotv,0.0,0.0)).xy;
+   float2 brdf = TORQUE_TEX2DLOD(brdfTexture, float4(surface.roughness, surface.NdotV,0.0,0.0)).xy;
 
 
     // Radiance (Specular)
     // Radiance (Specular)
    float lod = surface.roughness*cubeMips;
    float lod = surface.roughness*cubeMips;
-   float3 r = reflect(surfToEye, surface.N);
-   float3 cubeR = normalize(r);
-   cubeR = boxProject(surface.P, surface.N, inProbePosArray[id].xyz, bbMinArray[id].xyz, bbMaxArray[id].xyz);
+   float3 cubeR = boxProject(surface.P, surface.V, surface.R, inProbePosArray[id].xyz, bbMinArray[id].xyz, bbMaxArray[id].xyz);
 	
 	
    float3 radiance = TORQUE_TEXCUBEARRAYLOD(cubeMapAR,cubeR,id,lod).xyz * (brdf.x + brdf.y);
    float3 radiance = TORQUE_TEXCUBEARRAYLOD(cubeMapAR,cubeR,id,lod).xyz * (brdf.x + brdf.y);
     
     
@@ -74,14 +75,13 @@ float3 iblBoxSpecular(Surface surface, float3 surfToEye, TORQUE_SAMPLER2D(brdfTe
 
 
 float defineBoxSpaceInfluence(Surface surface, int id)
 float defineBoxSpaceInfluence(Surface surface, int id)
 {
 {
-    float tempAttenVal = 3.5; //replace with per probe atten
     float3 surfPosLS = mul( worldToObjArray[id], float4(surface.P,1.0)).xyz;
     float3 surfPosLS = mul( worldToObjArray[id], float4(surface.P,1.0)).xyz;
 
 
-    float3 boxMinLS = inProbePosArray[id].xyz-(float3(1,1,1)*radius[id].x);
-    float3 boxMaxLS = inProbePosArray[id].xyz+(float3(1,1,1)*radius[id].x);
+    float3 boxMinLS = inProbePosArray[id].xyz-(float3(1,1,1)*probeConfigData[id].g);
+    float3 boxMaxLS = inProbePosArray[id].xyz+(float3(1,1,1)*probeConfigData[id].g);
 
 
     float boxOuterRange = length(boxMaxLS - boxMinLS);
     float boxOuterRange = length(boxMaxLS - boxMinLS);
-    float boxInnerRange = boxOuterRange / tempAttenVal;
+    float boxInnerRange = boxOuterRange / probeConfigData[id].b;
 
 
     float3 localDir = float3(abs(surfPosLS.x), abs(surfPosLS.y), abs(surfPosLS.z));
     float3 localDir = float3(abs(surfPosLS.x), abs(surfPosLS.y), abs(surfPosLS.z));
     localDir = (localDir - boxInnerRange) / (boxOuterRange - boxInnerRange);
     localDir = (localDir - boxInnerRange) / (boxOuterRange - boxInnerRange);
@@ -102,52 +102,47 @@ float4 main( PFXVertToPix IN ) : SV_TARGET
    if (getFlag(surface.matFlag, 0))
    if (getFlag(surface.matFlag, 0))
    {   
    {   
       discard;
       discard;
-   }                                    
-	
-   float blendVal[MAX_PROBES];
-   float3 surfToEye = normalize(surface.P - eyePosWorld);
+   }      
 
 
    int i = 0;
    int i = 0;
+
+   float blendVal[MAX_PROBES];
    float blendSum = 0;
    float blendSum = 0;
    float invBlendSum = 0;
    float invBlendSum = 0;
-      
-   for(i=0; i < numProbes; i++)
-   {      
-      if(useSphereMode[i].r)
+
+   for (i = 0; i < numProbes; i++)
+   {
+      if (probeConfigData[i].r)
       {
       {
-          float3 L = inProbePosArray[i].xyz - surface.P;
-          blendVal[i] = 1.0-length(L)/radius[i].r;
-          blendVal[i] = max(0,blendVal[i]);
+         float3 L = inProbePosArray[i].xyz - surface.P;
+         blendVal[i] = 1.0 - length(L) / probeConfigData[i].g;
+         blendVal[i] = max(0, blendVal[i]);
       }
       }
       else
       else
       {
       {
-          blendVal[i] = defineBoxSpaceInfluence(surface, i);
-          blendVal[i] = max(0,blendVal[i]);		
+         blendVal[i] = defineBoxSpaceInfluence(surface, i);
+         blendVal[i] = max(0, blendVal[i]);
       }
       }
-		blendSum += blendVal[i];
-      invBlendSum +=(1.0f - blendVal[i]);
+      blendSum += blendVal[i];
+      invBlendSum += (1.0f - blendVal[i]);
    }
    }
-	
+
    // Weight0 = normalized NDF, inverted to have 1 at center, 0 at boundary.
    // Weight0 = normalized NDF, inverted to have 1 at center, 0 at boundary.
    // And as we invert, we need to divide by Num-1 to stay normalized (else sum is > 1). 
    // And as we invert, we need to divide by Num-1 to stay normalized (else sum is > 1). 
    // respect constraint B.
    // respect constraint B.
    // Weight1 = normalized inverted NDF, so we have 1 at center, 0 at boundary
    // Weight1 = normalized inverted NDF, so we have 1 at center, 0 at boundary
    // and respect constraint A.
    // and respect constraint A.
-   for(i=0; i < numProbes; i++)
+
+   //This is what's cross-contaminating between probe's influence areas. 
+   //Need to review this logic before we utilize it again
+   /*for (i = 0; i < numProbes; i++)
    {
    {
-      blendVal[i] = (1.0f - ( blendVal[i] / blendSum)) / (numProbes - 1);
+      blendVal[i] = (1.0f - (blendVal[i] / blendSum)) / (numProbes - 1);
       blendVal[i] *= ((1.0f - blendVal[i]) / invBlendSum);
       blendVal[i] *= ((1.0f - blendVal[i]) / invBlendSum);
       blendSum += blendVal[i];
       blendSum += blendVal[i];
-   }
+   }*/
 
 
-   float finalSum = blendSum;
-
-    //return TORQUE_TEX2D(colorBuffer, IN.uv0.xy);
-    //return float4(surface.N,1);
-   //return float4(1,1,1, 1);
-   //return float4(finalSum,finalSum,finalSum, 1);
-
-    // Normalize blendVal
+   // Normalize blendVal
    if (blendSum == 0.0f) // Possible with custom weight
    if (blendSum == 0.0f) // Possible with custom weight
    {
    {
       blendSum = 1.0f;
       blendSum = 1.0f;
@@ -158,6 +153,28 @@ float4 main( PFXVertToPix IN ) : SV_TARGET
    {
    {
       blendVal[i] *= invBlendSumWeighted;
       blendVal[i] *= invBlendSumWeighted;
    }
    }
+
+   //return float4(blendVal[0], blendVal[0], blendVal[0], 1);
+   
+#if DEBUGVIZ_ATTENUATION == 1
+   return float4(blendSum, blendSum, blendSum, 1);
+#endif
+
+#if DEBUGVIZ_CONTRIB == 1
+
+   float3 finalContribColor = float3(0, 0, 0);
+   for (i = 0; i < numProbes; ++i)
+   {
+      if (blendVal[i] == 0)
+         continue;
+
+      finalContribColor += blendSum * probeContribColors[i].rgb;
+   }
+
+   return float4(finalContribColor, 1);
+#endif
+
+#if DEBUGVIZ_SPECCUBEMAP == 0 && DEBUGVIZ_DIFFCUBEMAP == 0
     
     
    float3 irradiance = float3(0,0,0);
    float3 irradiance = float3(0,0,0);
    float3 specular = float3(0,0,0);
    float3 specular = float3(0,0,0);
@@ -168,13 +185,35 @@ float4 main( PFXVertToPix IN ) : SV_TARGET
    kD *= 1.0 - surface.metalness;
    kD *= 1.0 - surface.metalness;
    for (i = 0; i < numProbes; ++i)
    for (i = 0; i < numProbes; ++i)
    {
    {
-      irradiance += blendVal[i]*iblBoxDiffuse(surface,i);
+      if (blendVal[i] == 0)
+         continue;
+
+      irradiance += blendVal[i]*iblBoxDiffuse(surface, i);
       
       
-      specular += blendVal[i]*F*iblBoxSpecular(surface, surfToEye, TORQUE_SAMPLER2D_MAKEARG(BRDFTexture),i);
+      specular += blendVal[i]*F*iblBoxSpecular(surface, TORQUE_SAMPLER2D_MAKEARG(BRDFTexture),i);
    }
    }
+
    //final diffuse color
    //final diffuse color
    float3 diffuse = kD * irradiance * surface.baseColor.rgb;
    float3 diffuse = kD * irradiance * surface.baseColor.rgb;
 	float4 finalColor = float4(diffuse + specular * surface.ao, blendSum);
 	float4 finalColor = float4(diffuse + specular * surface.ao, blendSum);
 
 
     return finalColor;
     return finalColor;
+
+#elif DEBUGVIZ_SPECCUBEMAP == 1 && DEBUGVIZ_DIFFCUBEMAP == 0
+   float3 cubeColor = float3(0, 0, 0);
+   for (i = 0; i < numProbes; ++i)
+   {
+      cubeColor += blendVal[i] * iblBoxSpecular(surface, TORQUE_SAMPLER2D_MAKEARG(BRDFTexture), i);
+   }
+
+   return float4(cubeColor,1);
+#elif DEBUGVIZ_DIFFCUBEMAP == 1
+   float3 cubeColor = float3(0, 0, 0);
+   for (i = 0; i < numProbes; ++i)
+   {
+      cubeColor += blendVal[i] * iblBoxDiffuse(surface, i);
+   }
+
+   return float4(cubeColor, 1);
+#endif
 }
 }

+ 4 - 0
Templates/Full/game/tools/worldEditor/main.cs

@@ -130,6 +130,10 @@ function initializeWorldEditor()
    EVisibility.addOption( "AL: Backbuffer", "$AL_BackbufferVisualizeVar", "toggleBackbufferViz" );
    EVisibility.addOption( "AL: Backbuffer", "$AL_BackbufferVisualizeVar", "toggleBackbufferViz" );
    EVisibility.addOption( "AL: Glow Buffer", "$AL_GlowVisualizeVar", "toggleGlowViz" );
    EVisibility.addOption( "AL: Glow Buffer", "$AL_GlowVisualizeVar", "toggleGlowViz" );
    EVisibility.addOption( "AL: PSSM Cascade Viz", "$AL::PSSMDebugRender", "" );
    EVisibility.addOption( "AL: PSSM Cascade Viz", "$AL::PSSMDebugRender", "" );
+   EVisibility.addOption( "Probes: Attenuation", "$Probes::showAttenuation", "" );   
+   EVisibility.addOption( "Probes: Specular Cubemaps", "$Probes::showSpecularCubemaps", "" );   
+   EVisibility.addOption( "Probes: Diffuse Cubemaps", "$Probes::showDiffuseCubemaps", "" );   
+   EVisibility.addOption( "Probes: Contribution", "$Probes::showProbeContrib", "" );   
    EVisibility.addOption( "Frustum Lock", "$Scene::lockCull", "" );
    EVisibility.addOption( "Frustum Lock", "$Scene::lockCull", "" );
    EVisibility.addOption( "Disable Zone Culling", "$Scene::disableZoneCulling", "" );
    EVisibility.addOption( "Disable Zone Culling", "$Scene::disableZoneCulling", "" );
    EVisibility.addOption( "Disable Terrain Occlusion", "$Scene::disableTerrainOcclusion", "" );
    EVisibility.addOption( "Disable Terrain Occlusion", "$Scene::disableTerrainOcclusion", "" );