소스 검색

Merge branch 'PBR_ProbeArrayWIP' of https://github.com/Areloch/Torque3D into PBR_ProbeArrayWIP

# Conflicts:
#	Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl
Azaezel 6 년 전
부모
커밋
903efc7cfd

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

@@ -168,6 +168,10 @@ void BoxEnvironmentProbe::updateProbeParams()
 
    mProbeInfo->mProbeShapeType = ProbeRenderInst::Box;
    mProbeInfo->mAtten = mAtten;
+
+   PROBEMGR->updateProbes();
+
+   updateCubemaps();
 }
 
 void BoxEnvironmentProbe::setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat)

+ 18 - 13
Engine/source/T3D/lighting/reflectionProbe.cpp

@@ -294,8 +294,6 @@ bool ReflectionProbe::onAdd()
    {
       createGeometry();
       updateProbeParams();
-
-      PROBEMGR->registerProbe(mProbeInfoIdx);
    }
   
    setMaskBits(-1);
@@ -458,6 +456,8 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
 
       mathRead(*stream, &mProbeRefOffset);
       mathRead(*stream, &mProbeRefScale);      
+
+      mDirty = true;
    }
 
    if (stream->readFlag())  // ShapeTypeMask
@@ -467,24 +467,30 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
 
       mProbeShapeType = (ProbeRenderInst::ProbeShapeType)shapeType;
       createGeometry();
+
+      mDirty = true;
    }
 
    if (stream->readFlag())  // UpdateMask
    {
       stream->read(&mRadius);
+
+      mDirty = true;
    }
 
    if (stream->readFlag())  // BakeInfoMask
    {
       stream->read(&mProbeUniqueID);
+
+      mDirty = true;
    }
 
    if (stream->readFlag())  // EnabledMask
    {
       mEnabled = stream->readFlag();
-   }
 
-   bool isMaterialDirty = false;
+      mDirty = true;
+   }
 
    if (stream->readFlag())  // ModeMask
    {
@@ -492,7 +498,7 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
       stream->read(&reflectModeType);
       mReflectionModeType = (ReflectionModeType)reflectModeType;
 
-      isMaterialDirty = true;
+      mDirty = true;
    }
 
    if (stream->readFlag())  // CubemapMask
@@ -505,7 +511,7 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
          processStaticCubemap();
       }
 
-      isMaterialDirty = true;
+      mDirty = true;
    }
 
    if (mDirty)
@@ -524,9 +530,9 @@ void ReflectionProbe::updateProbeParams()
       mProbeInfo = new ProbeRenderInst();
       mProbeInfoIdx = ProbeRenderInst::all.size() - 1;
       mProbeInfo->mIsEnabled = false;
-   }
 
-   updateCubemaps();
+      PROBEMGR->registerProbe(mProbeInfoIdx);
+   }
 
    mProbeInfo->mProbeShapeType = mProbeShapeType;
 
@@ -607,7 +613,8 @@ void ReflectionProbe::processStaticCubemap()
    mProbeInfo->mIrradianceCubemap = mIrridianceMap->mCubemap;
 
    //Update the probe manager with our new texture!
-   //PROBEMGR->updateProbeTexture(mProbeInfo);
+   if(!mProbeInfo->mIsSkylight)
+      PROBEMGR->updateProbeTexture(mProbeInfo);
 }
 
 void ReflectionProbe::updateCubemaps()
@@ -658,10 +665,8 @@ void ReflectionProbe::updateCubemaps()
    else
       mProbeInfo->mIsEnabled = false;
 
-   PROBEMGR->updateProbes();
-
-   //if (mProbeInfo->mPrefilterCubemap->isInitialized() && mProbeInfo->mIrradianceCubemap->isInitialized())
-   //   PROBEMGR->updateProbeTexture(mProbeInfo);
+   if (!mProbeInfo->mIsSkylight && mProbeInfo->mPrefilterCubemap->isInitialized() && mProbeInfo->mIrradianceCubemap->isInitialized())
+      PROBEMGR->updateProbeTexture(mProbeInfo);
 }
 
 bool ReflectionProbe::createClientResources()

+ 4 - 0
Engine/source/T3D/lighting/skylight.cpp

@@ -179,6 +179,10 @@ void Skylight::updateProbeParams()
 
    mProbeInfo->mIsSkylight = true; 
    mProbeInfo->mScore = -1.0f; //sky comes first
+
+   PROBEMGR->updateProbes();
+
+   updateCubemaps();
 }
 
 void Skylight::prepRenderImage(SceneRenderState *state)

+ 4 - 0
Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp

@@ -154,6 +154,10 @@ void SphereEnvironmentProbe::updateProbeParams()
    Parent::updateProbeParams();
 
    mProbeInfo->mProbeShapeType = ProbeRenderInst::Sphere;
+
+   PROBEMGR->updateProbes();
+
+   updateCubemaps();
 }
 
 void SphereEnvironmentProbe::prepRenderImage(SceneRenderState *state)

+ 40 - 27
Engine/source/renderInstance/renderProbeMgr.cpp

@@ -84,7 +84,8 @@ ProbeRenderInst::ProbeRenderInst() : SystemInterface(),
    mProbeRefOffset(0, 0, 0),
    mProbeRefScale(1,1,1),
    mAtten(0.0),
-   mCubemapIndex(0)
+   mCubemapIndex(0),
+   mIsSkylight(false)
 {
 }
 
@@ -285,37 +286,42 @@ void RenderProbeMgr::registerProbe(U32 probeIdx)
 
    mRegisteredProbes.push_back_unique(probeIdx);
 
-   const U32 cubeIndex = _findNextEmptyCubeSlot();
-   if (cubeIndex == INVALID_CUBE_SLOT)
+   if (!ProbeRenderInst::all[probeIdx]->mIsSkylight)
    {
-      Con::warnf("RenderProbeMgr::addProbe: Invalid cubemap slot.");
-      return;
-   }
+      const U32 cubeIndex = _findNextEmptyCubeSlot();
+      if (cubeIndex == INVALID_CUBE_SLOT)
+      {
+         Con::warnf("RenderProbeMgr::addProbe: Invalid cubemap slot.");
+         return;
+      }
 
-   //check if we need to resize the cubemap array
-   if (cubeIndex >= mCubeSlotCount)
-   {
-      //alloc temp array handles
-      GFXCubemapArrayHandle irr = GFXCubemapArrayHandle(GFX->createCubemapArray());
-      GFXCubemapArrayHandle prefilter = GFXCubemapArrayHandle(GFX->createCubemapArray());
+      //check if we need to resize the cubemap array
+      if (cubeIndex >= mCubeSlotCount)
+      {
+         //alloc temp array handles
+         GFXCubemapArrayHandle irr = GFXCubemapArrayHandle(GFX->createCubemapArray());
+         GFXCubemapArrayHandle prefilter = GFXCubemapArrayHandle(GFX->createCubemapArray());
 
-      irr->init(mCubeSlotCount + PROBE_ARRAY_SLOT_BUFFER_SIZE, PROBE_IRRAD_SIZE, PROBE_FORMAT);
-      prefilter->init(mCubeSlotCount + PROBE_ARRAY_SLOT_BUFFER_SIZE, PROBE_PREFILTER_SIZE, PROBE_FORMAT);
+         irr->init(mCubeSlotCount + PROBE_ARRAY_SLOT_BUFFER_SIZE, PROBE_IRRAD_SIZE, PROBE_FORMAT);
+         prefilter->init(mCubeSlotCount + PROBE_ARRAY_SLOT_BUFFER_SIZE, PROBE_PREFILTER_SIZE, PROBE_FORMAT);
 
-      mIrradianceArray->copyTo(irr);
-      mPrefilterArray->copyTo(prefilter);
+         mIrradianceArray->copyTo(irr);
+         mPrefilterArray->copyTo(prefilter);
 
-      //assign the temp handles to the new ones, this will destroy the old ones as well
-      mIrradianceArray = irr;
-      mPrefilterArray = prefilter;
+         //assign the temp handles to the new ones, this will destroy the old ones as well
+         mIrradianceArray = irr;
+         mPrefilterArray = prefilter;
 
-      mCubeSlotCount += PROBE_ARRAY_SLOT_BUFFER_SIZE;
-   }
+         mCubeSlotCount += PROBE_ARRAY_SLOT_BUFFER_SIZE;
+      }
 
-   ProbeRenderInst::all[probeIdx]->mCubemapIndex = cubeIndex;
-   //mark cubemap slot as taken
-   mCubeMapSlots[cubeIndex] = true;
-   mCubeMapCount++;
+      ProbeRenderInst::all[probeIdx]->mCubemapIndex = cubeIndex;
+      //mark cubemap slot as taken
+      mCubeMapSlots[cubeIndex] = true;
+      mCubeMapCount++;
+
+      Con::warnf("RenderProbeMgr::registerProbe: Registered probe %u to cubeIndex %u", probeIdx, cubeIndex);
+   }
 
    //rebuild our probe data
    _setupStaticParameters();
@@ -446,7 +452,7 @@ void RenderProbeMgr::_setupStaticParameters()
       mEffectiveProbeCount++;
    }
 
-   if (mEffectiveProbeCount != 0)
+   /*if (mEffectiveProbeCount != 0)
    {
       bool useOldWay = false;
       if (useOldWay)
@@ -470,11 +476,15 @@ void RenderProbeMgr::_setupStaticParameters()
             mPrefilterArray->updateTexture(cubeMaps[i], cubeIndex);
          }
       }
-   }
+   }*/
 }
 
 void RenderProbeMgr::updateProbeTexture(ProbeRenderInst* probe)
 {
+   //We don't stuff skylights into the array, so we can just skip out on this if it's a skylight
+   if (probe->mIsSkylight)
+      return;
+
    S32 probeIdx = ProbeRenderInst::all.find_next(probe);
 
    if (probeIdx != -1) //i mean, the opposite shouldn't even be possible
@@ -489,6 +499,9 @@ void RenderProbeMgr::updateProbeTexture(U32 probeIdx)
    const U32 cubeIndex = ProbeRenderInst::all[probeIdx]->mCubemapIndex;
    mIrradianceArray->updateTexture(ProbeRenderInst::all[probeIdx]->mIrradianceCubemap, cubeIndex);
    mPrefilterArray->updateTexture(ProbeRenderInst::all[probeIdx]->mPrefilterCubemap, cubeIndex);
+
+   Con::warnf("UpdatedProbeTexture - probeIdx: %u on cubeIndex %u, Irrad validity: %d, Prefilter validity: %d", probeIdx, cubeIndex, 
+      ProbeRenderInst::all[probeIdx]->mIrradianceCubemap->isInitialized(), ProbeRenderInst::all[probeIdx]->mPrefilterCubemap->isInitialized());
 }
 
 void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state)

+ 9 - 124
Templates/Full/game/levels/AProbeTest.mis

@@ -41,7 +41,7 @@ new SimGroup(MissionGroup) {
       enabled = "1";
       ReflectionMode = "Baked Cubemap";
       StaticCubemap = "sky_day_hdr_cubemap";
-      position = "0 0 -0.0560153";
+      position = "0 0.704113 16.1515";
       rotation = "1 0 0 0";
       canSave = "1";
       canSaveDynamicFields = "1";
@@ -81,7 +81,7 @@ new SimGroup(MissionGroup) {
       squareSize = "128";
       scaleU = "25";
       scaleV = "25";
-      Material = "Grid512_Grey_Mat";
+      Material = "Floor_Material";
       canSave = "1";
       canSaveDynamicFields = "1";
          enabled = "1";
@@ -130,32 +130,13 @@ new SimGroup(MissionGroup) {
       refOffset = "0 0 0";
       refScale = "10 10 10";
       ReflectionMode = "Baked Cubemap";
-      position = "0.130544 0.492826 4.70918";
+      position = "0.130544 0.239855 4.8594";
       rotation = "1 0 0 0";
       scale = "10 10 10";
       canSave = "1";
       canSaveDynamicFields = "1";
       persistentId = "8072e1be-2846-11e7-9f56-abd46b190c60";
-   };
-   new BoxEnvironmentProbe() {
-      enabled = "1";
-      refOffset = "0 0 0";
-      refScale = "10 10 10";
-      ReflectionMode = "Baked Cubemap";
-      position = "-26.7509 2.50947 1.94424";
-      rotation = "0 0 -1 27.2465";
-      scale = "10 5 10";
-      canSave = "1";
-      canSaveDynamicFields = "1";
-      persistentId = "f281a5ff-1ae9-11e9-9c9a-df9135416cc7";
-         GroundColor = "0.8 0.7 0.5 1";
-         IndirectLight = "1 1 1 1";
-         IndirectLightMode = "Spherical Harmonics";
-         Intensity = "1";
-         posOffset = "0 0 0";
-         radius = "5";
-         reflectionPath = "levels/probeTest/probes/";
-         SkyColor = "0.5 0.5 1 1";
+      attenuation = "0";
    };
    new ConvexShape() {
       Material = "Grid512_Orange_Mat";
@@ -324,114 +305,18 @@ new SimGroup(MissionGroup) {
       canSave = "1";
       canSaveDynamicFields = "1";
    };
-   new SphereEnvironmentProbe() {
+   new BoxEnvironmentProbe() {
       enabled = "1";
-      radius = "5";
       refOffset = "0 0 0";
       refScale = "10 10 10";
       ReflectionMode = "Baked Cubemap";
-      StaticCubemap = "HdrSkyCubemap";
-      position = "-25.5075 8.33063 1.52035";
-      rotation = "1 0 0 0";
-      canSave = "1";
-      canSaveDynamicFields = "1";
-      persistentId = "c4bc9059-3cb4-11e9-933c-d270d89e32b9";
-   };
-   new TSStatic() {
-      shapeName = "art/yorks/chapel/Module_Common/SB_chapel_ext.dae";
-      playAmbient = "1";
-      meshCulling = "0";
-      originSort = "0";
-      CollisionType = "Collision Mesh";
-      DecalType = "Collision Mesh";
-      allowPlayerStep = "0";
-      alphaFadeEnable = "0";
-      alphaFadeStart = "100";
-      alphaFadeEnd = "150";
-      alphaFadeInverse = "0";
-      renderNormals = "0";
-      forceDetail = "-1";
-      ignoreZodiacs = "0";
-      useGradientRange = "0";
-      gradientRange = "0 180";
-      invertGradientRange = "0";
-      position = "0.569034 -19.8511 -0.101853";
+      position = "-22.7696 0.224002 4.70918";
       rotation = "1 0 0 0";
-      scale = "1 1 1";
-      canSave = "1";
-      canSaveDynamicFields = "1";
-   };
-   new TSStatic() {
-      shapeName = "art/yorks/chapel/Module_Common/LMA_chapel_int.dae";
-      playAmbient = "1";
-      meshCulling = "0";
-      originSort = "0";
-      CollisionType = "Collision Mesh";
-      DecalType = "Collision Mesh";
-      allowPlayerStep = "0";
-      alphaFadeEnable = "0";
-      alphaFadeStart = "100";
-      alphaFadeEnd = "150";
-      alphaFadeInverse = "0";
-      renderNormals = "0";
-      forceDetail = "-1";
-      ignoreZodiacs = "0";
-      useGradientRange = "0";
-      gradientRange = "0 180";
-      invertGradientRange = "0";
-      position = "0.569034 -19.8511 -0.101853";
-      rotation = "1 0 0 0";
-      scale = "1 1 1";
-      canSave = "1";
-      canSaveDynamicFields = "1";
-   };
-   new TSStatic() {
-      shapeName = "art/yorks/chapel/Module_Common/LMX_chapel_props.dae";
-      playAmbient = "1";
-      meshCulling = "0";
-      originSort = "0";
-      CollisionType = "Collision Mesh";
-      DecalType = "Collision Mesh";
-      allowPlayerStep = "0";
-      alphaFadeEnable = "0";
-      alphaFadeStart = "100";
-      alphaFadeEnd = "150";
-      alphaFadeInverse = "0";
-      renderNormals = "0";
-      forceDetail = "-1";
-      ignoreZodiacs = "0";
-      useGradientRange = "0";
-      gradientRange = "0 180";
-      invertGradientRange = "0";
-      position = "0.569034 -19.8511 -0.101853";
-      rotation = "1 0 0 0";
-      scale = "1 1 1";
-      canSave = "1";
-      canSaveDynamicFields = "1";
-   };
-   new TSStatic() {
-      shapeName = "art/yorks/chapel/Module_Common/SB_chapel_glass.dae";
-      playAmbient = "1";
-      meshCulling = "0";
-      originSort = "0";
-      CollisionType = "Collision Mesh";
-      DecalType = "Collision Mesh";
-      allowPlayerStep = "0";
-      alphaFadeEnable = "0";
-      alphaFadeStart = "100";
-      alphaFadeEnd = "150";
-      alphaFadeInverse = "0";
-      renderNormals = "0";
-      forceDetail = "-1";
-      ignoreZodiacs = "0";
-      useGradientRange = "0";
-      gradientRange = "0 180";
-      invertGradientRange = "0";
-      position = "0.569034 -19.8511 -0.101853";
-      rotation = "1 0 0 0";
-      scale = "1 1 1";
+      scale = "10 10 10";
       canSave = "1";
       canSaveDynamicFields = "1";
+      persistentId = "d84cbe5b-4f76-11e9-977c-a561a736e3eb";
+      attenuation = "0";
    };
 };
 //--- OBJECT WRITE END ---

+ 53 - 87
Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl

@@ -78,8 +78,8 @@ float defineBoxSpaceInfluence(Surface surface, ProbeData probe, float3 wsEyeRay)
    float3 surfPosLS = mul(probe.worldToLocal, float4(surface.P, 1.0)).xyz;
    float atten = 1.0-probe.attenuation;
    float baseVal = 0.25;
-   float dist = getDistBoxToPoint(surfPosLS, float3(baseVal, baseVal, baseVal));
-   return saturate(smoothstep(baseVal + 0.0001, atten*baseVal, dist));
+   float dist = getDistBoxToPoint(surfPosLS,float3(baseVal,baseVal,baseVal));
+   return saturate(smoothstep(baseVal+0.0001,atten*baseVal,dist));
 }
 
 // Box Projected IBL Lighting
@@ -105,10 +105,7 @@ float3 iblBoxDiffuse(Surface surface, ProbeData probe)
    float3 dir = boxProject(surface, probe);
 
    float3 color = TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, probe.cubemapIdx, 0).xyz;
-   if (probe.contribution>0)
-      return color;
-   else
-      return float3(0, 0, 0);
+   return color;
 }
 
 float3 iblBoxSpecular(Surface surface, ProbeData probe)
@@ -126,21 +123,16 @@ float3 iblBoxSpecular(Surface surface, ProbeData probe)
 #endif
 
    float3 color = TORQUE_TEXCUBEARRAYLOD(cubeMapAR, dir, probe.cubemapIdx, lod).xyz * (brdf.x + brdf.y);
-
-   if (probe.contribution>0)
-      return color;
-   else
-      return float3(0, 0, 0);
+   return color;
 }
 
-float3 iblSkylightDiffuse(Surface surface, ProbeData probe)
+float3 iblSkylightDiffuse(Surface surface)
 {
-   float3 color = TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, surface.R, probe.probeIdx, 0).xyz;
-
+   float3 color = TORQUE_TEXCUBELOD(skylightIrradMap, float4(surface.R, 0)).xyz;
    return color;
 }
 
-float3 iblSkylightSpecular(Surface surface, ProbeData probe)
+float3 iblSkylightSpecular(Surface surface)
 {
    // BRDF
    float2 brdf = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.roughness, surface.NdotV, 0.0, 0.0)).xy;
@@ -152,8 +144,7 @@ float3 iblSkylightSpecular(Surface surface, ProbeData probe)
    float lod = 0;
 #endif
 
-   float3 color = TORQUE_TEXCUBEARRAYLOD(cubeMapAR, surface.R, probe.probeIdx, lod).xyz * (brdf.x + brdf.y);
-
+   float3 color = TORQUE_TEXCUBELOD(skylightPrefilterMap, float4(surface.R, lod)).xyz * (brdf.x + brdf.y);
    return color;
 }
 
@@ -221,24 +212,24 @@ float4 main(PFXVertToPix IN) : SV_TARGET
       }
 
       // 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). 
-      // respect constraint B.
-      // Weight1 = normalized inverted NDF, so we have 1 at center, 0 at boundary
-      // and respect constraint A.
-      for (i = 0; i < numProbes; i++)
-      {
-         if (probehits>1.0)
-         {
-            blendFactor[i] = ((probes[i].contribution / blendSum)) / (probehits - 1);
-            blendFactor[i] *= ((probes[i].contribution) / invBlendSum);
-            blendFacSum += blendFactor[i];
-         }
-         else
-         {
-            blendFactor[i] = probes[i].contribution;
-            blendFacSum = probes[i].contribution;
-         }
-      }
+	   // And as we invert, we need to divide by Num-1 to stay normalized (else sum is > 1). 
+	   // respect constraint B.
+	   // Weight1 = normalized inverted NDF, so we have 1 at center, 0 at boundary
+	   // and respect constraint A.
+	   for (i = 0; i < numProbes; i++)
+	   {
+	      if (probehits>1.0)
+	      {
+	         blendFactor[i] = ((probes[i].contribution / blendSum)) / (probehits - 1);
+	         blendFactor[i] *= ((probes[i].contribution) / invBlendSum);
+	         blendFacSum += blendFactor[i];
+	      }
+	      else
+	      {
+	         blendFactor[i] = probes[i].contribution;
+	         blendFacSum = probes[i].contribution;
+	      }
+	   }
 
 
       // Normalize blendVal
@@ -249,28 +240,25 @@ float4 main(PFXVertToPix IN) : SV_TARGET
       }
 #endif
 
-      //use probehits for sharp cuts when singular, 
-      //blendSum when wanting blend on all edging
-      if (blendSum>1.0)
-      {
-         float invBlendSumWeighted = 1.0f / blendFacSum;
-         for (i = 0; i < numProbes; ++i)
-         {
-            blendFactor[i] *= invBlendSumWeighted;
-            probes[i].contribution = blendFactor[i];
+	  if (probehits>1.0)
+		{
+		  float invBlendSumWeighted = 1.0f / blendFacSum;
+		  for (i = 0; i < numProbes; ++i)
+		  {
+		     blendFactor[i] *= invBlendSumWeighted;
+		     probes[i].contribution = saturate(blendFactor[i]);
 
-            alpha -= probes[i].contribution;
-         }
-      }
+			alpha -= probes[i].contribution;
+		  }
+		}
 
 #if DEBUGVIZ_ATTENUATION == 1
-      /*float attenVis = 0;
-      for (i = 0; i < numProbes; ++i)
-      {
-      attenVis += probes[i].contribution;
-      }
-      return float4(attenVis, attenVis, attenVis, 1);*/
-      return float4(alpha, alpha, alpha, 1);
+      float attenVis = 0;
+		for (i = 0; i < numProbes; ++i)
+		{
+		  attenVis += probes[i].contribution;
+		}
+		return float4(attenVis, attenVis, attenVis, 1);
 #endif
 
 #if DEBUGVIZ_CONTRIB == 1
@@ -288,34 +276,6 @@ float4 main(PFXVertToPix IN) : SV_TARGET
 #endif
    }
 
-   if (hasSkylight && alpha == 1)
-   {
-      float2 brdf = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.roughness, surface.NdotV, 0.0, 0.0)).xy;
-      float lod = surface.roughness*cubeMips;
-#if DEBUGVIZ_SPECCUBEMAP == 0 && DEBUGVIZ_DIFFCUBEMAP == 0
-      float3 specular = TORQUE_TEXCUBELOD(skylightPrefilterMap, float4(surface.R, lod)).xyz * (brdf.x + brdf.y);
-      float3 irradiance = TORQUE_TEXCUBELOD(skylightIrradMap, float4(surface.R, 0)).xyz;
-
-      float3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness);
-
-      //energy conservation
-      float3 kD = 1.0.xxx - F;
-      kD *= 1.0 - surface.metalness;
-
-      float3 diffuse = kD * irradiance * surface.baseColor.rgb;
-      float4 finalColor = float4(diffuse + specular * surface.ao, alpha);
-      return finalColor;
-#elif DEBUGVIZ_SPECCUBEMAP == 1 && DEBUGVIZ_DIFFCUBEMAP == 0
-      float3 specular = TORQUE_TEXCUBELOD(skylightPrefilterMap, float4(surface.R, lod)).xyz;
-      float4 finalColor = float4(specular, 1);
-      return finalColor;
-#elif DEBUGVIZ_DIFFCUBEMAP == 1
-      float3 irradiance = TORQUE_TEXCUBELOD(skylightIrradMap, float4(surface.R, 0)).xyz;
-      float4 finalColor = float4(irradiance, 1);
-      return finalColor;
-#endif
-   }
-
 #if DEBUGVIZ_SPECCUBEMAP == 0 && DEBUGVIZ_DIFFCUBEMAP == 0
 
    float3 irradiance = float3(0, 0, 0);
@@ -334,11 +294,17 @@ float4 main(PFXVertToPix IN) : SV_TARGET
       if (probes[i].type == 2) //skip skylight
          continue;
 
-      irradiance += iblBoxDiffuse(surface, probes[i]);
-      specular += F*iblBoxSpecular(surface, probes[i]);
-      contrib += probes[i].contribution;
+      irradiance += iblBoxDiffuse(surface, probes[i])*probes[i].contribution;
+      specular += F*iblBoxSpecular(surface, probes[i])*probes[i].contribution;
+      contrib +=probes[i].contribution;
+   }
+   //contrib = saturate(contrib);
+
+   if (hasSkylight && alpha != 0)
+   {
+      irradiance = lerp(irradiance, iblSkylightDiffuse(surface), alpha);
+      specular = lerp(specular, F*iblSkylightSpecular(surface), alpha);
    }
-   contrib = saturate(contrib);
 
    //final diffuse color
    float3 diffuse = kD * irradiance * surface.baseColor.rgb;
@@ -381,4 +347,4 @@ float4 main(PFXVertToPix IN) : SV_TARGET
    return float4(cubeColor, 1);
 
 #endif
-}
+}