Browse Source

Undid debug work, shifted logic over entirely to utilize the updateTexture methods. Refactored probe init'ing so they'll load correctly without nudging, properly sequestered skylights from the probe array and updated the shader to contain az's changes as well as skylight and probe array changes.

Areloch 6 năm trước cách đây
mục cha
commit
e2b194182c

+ 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 ---

+ 54 - 90
Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl

@@ -76,11 +76,10 @@ float getDistBoxToPoint(float3 pt, float3 extents)
 float defineBoxSpaceInfluence(Surface surface, ProbeData probe, float3 wsEyeRay)
 {
    float3 surfPosLS = mul(probe.worldToLocal, float4(surface.P, 1.0)).xyz;
-   float probeattenuationvalue = 0.5; // feed meh
-   float atten = 1.0 - probeattenuationvalue;
+   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
@@ -106,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*probe.contribution;
-   else
-      return float3(0, 0, 0);
+   return color;
 }
 
 float3 iblBoxSpecular(Surface surface, ProbeData probe)
@@ -127,22 +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*probe.contribution;
-   else
-      return float3(0, 0, 0);
+   return color;
 }
 
-float3 iblSkylightDiffuse(Surface surface, ProbeData probe)
+float3 iblSkylightDiffuse(Surface surface)
 {
-   float lod = surface.roughness*cubeMips;
-   float3 color = TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, surface.R, probe.probeIdx, lod).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;
@@ -154,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;
 }
 
@@ -223,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
@@ -251,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
@@ -290,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);
@@ -336,15 +294,21 @@ 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;
-   float4 finalColor = float4(diffuse + specular * surface.ao, blendFacSum);
+   float4 finalColor = float4(diffuse + specular * surface.ao, 1.0);
 
    return finalColor;