Bladeren bron

Enabled probe viz item for live updates of probes when working with them(auto-baking while on)
Updated debug forward mat viz to work with probe visualization
More correct premult math
Updated probe viz menu behavior to properly toggle and mark which is active

Areloch 5 jaren geleden
bovenliggende
commit
60d0e73190

+ 6 - 0
Engine/source/T3D/lighting/reflectionProbe.cpp

@@ -200,6 +200,12 @@ void ReflectionProbe::inspectPostApply()
 
    mDirty = true;
 
+   bool liveUpdates = Con::getBoolVariable("$Probes::liveUpdates", false);
+   if (liveUpdates)
+   {
+      bake();
+   }
+
    // Flag the network mask to send the updates
    // to the client object
    setMaskBits(-1);

+ 97 - 5
Engine/source/shaderGen/HLSL/debugVizFeatureHLSL.cpp

@@ -24,19 +24,21 @@ void DebugVizHLSL::processPix(Vector<ShaderComponent*>& componentList,
 {
    MultiLine* meta = new MultiLine;
    Var* surface = (Var*)LangElement::find("surface");
+   Var* color = (Var*)LangElement::find("col");
+
+   if (!surface)
+      return;
 
    //0 == display both forward and deferred viz, 1 = display forward only viz, 2 = display deferred only viz
    S32 vizDisplayMode = Con::getIntVariable("$Viz_DisplayMode", 0);
+   S32 surfaceVizMode = Con::getIntVariable("$Viz_SurfacePropertiesModeVar", -1);
 
-   if (surface && (vizDisplayMode == 0 || vizDisplayMode == 1))
+   if (surfaceVizMode != -1 && vizDisplayMode == 0 || vizDisplayMode == 1)
    {
-      Var* color = (Var*)LangElement::find("col");
       if (color)
       {
          Var* specularColor = (Var*)LangElement::find("specularColor");
 
-         S32 surfaceVizMode = Con::getIntVariable("$Viz_SurfacePropertiesModeVar", -1);
-
          switch (surfaceVizMode)
          {
          case 0:
@@ -100,7 +102,97 @@ void DebugVizHLSL::processPix(Vector<ShaderComponent*>& componentList,
             break;
          };
       }
+
+      output = meta;
+      return;
    }
 
-   output = meta;
+   //if not that, try the probe viz
+   Var* ibl = (Var*)LangElement::find("ibl");
+   if (ibl && color)
+   {
+      const char* showAtten = Con::getVariable("$Probes::showAttenuation", "0");
+      const char* showContrib = Con::getVariable("$Probes::showProbeContrib", "0");
+      const char* showSpec = Con::getVariable("$Probes::showSpecularCubemaps", "0");
+      const char* showDiff = Con::getVariable("$Probes::showDiffuseCubemaps", "0");
+
+      if (showAtten == "0" && showContrib == "0" && showSpec == "0" && showDiff == "0")
+         return;
+
+      if (fd.features[MFT_LightMap] || fd.features[MFT_ToneMap] || fd.features[MFT_VertLit])
+         return;
+
+      ShaderConnector* connectComp = dynamic_cast<ShaderConnector*>(componentList[C_CONNECTOR]);
+
+      MultiLine* meta = new MultiLine;
+
+      // Now the wsPosition and wsView.
+      Var* worldToTangent = getInWorldToTangent(componentList);
+      Var* wsNormal = getInWorldNormal(componentList);
+      Var* wsPosition = getInWsPosition(componentList);
+      Var* wsView = getWsView(wsPosition, meta);
+
+      //Reflection Probe WIP
+      U32 MAX_FORWARD_PROBES = 4;
+
+      Var* numProbes = (Var*)LangElement::find("numProbes");
+      Var* cubeMips = (Var*)LangElement::find("cubeMips");
+      Var* skylightCubemapIdx = (Var*)LangElement::find("skylightCubemapIdx");
+      Var* inProbePosArray = (Var*)LangElement::find("inProbePosArray");
+      Var* inRefPosArray = (Var*)LangElement::find("inRefPosArray");
+      Var* refBoxMinArray = (Var*)LangElement::find("inRefBoxMin");
+      Var* refBoxMaxArray = (Var*)LangElement::find("inRefBoxMax");
+
+      Var* probeConfigData = (Var*)LangElement::find("probeConfigData");
+      Var* worldToObjArray = (Var*)LangElement::find("worldToObjArray");
+
+      Var* BRDFTexture = (Var*)LangElement::find("BRDFTexture");
+      Var* BRDFTextureTex = (Var*)LangElement::find("texture_BRDFTexture");
+
+      Var* specularCubemapAR = (Var*)LangElement::find("specularCubemapAR");
+      Var* specularCubemapARTex = (Var*)LangElement::find("texture_specularCubemapAR");
+
+      Var* irradianceCubemapAR = (Var*)LangElement::find("irradianceCubemapAR");
+      Var* irradianceCubemapARTex = (Var*)LangElement::find("texture_irradianceCubemapAR");
+
+      Var* matinfo = (Var*)LangElement::find("PBRConfig");
+      Var* metalness = (Var*)LangElement::find("metalness");
+      Var* smoothness = (Var*)LangElement::find("smoothness");
+
+      Var* wsEyePos = (Var*)LangElement::find("eyePosWorld");
+
+      Var* ibl = (Var*)LangElement::find("ibl");
+
+      //Reflection vec
+      Var* showAttenVar = new Var("showAttenVar", "int");
+      char buf[64];
+      dSprintf(buf, sizeof(buf), "   @ = %s;\r\n", showAtten);
+      meta->addStatement(new GenOp(buf, new DecOp(showAttenVar)));
+
+      Var* showContribVar = new Var("showContribVar", "int");
+      dSprintf(buf, sizeof(buf), "   @ = %s;\r\n", showContrib);
+      meta->addStatement(new GenOp(buf, new DecOp(showContribVar)));
+
+      Var* showSpecVar = new Var("showSpecVar", "int");
+      dSprintf(buf, sizeof(buf), "   @ = %s;\r\n", showSpec);
+      meta->addStatement(new GenOp(buf, new DecOp(showSpecVar)));
+
+      Var* showDiffVar = new Var("showDiffVar", "int");
+      dSprintf(buf, sizeof(buf), "   @ = %s;\r\n", showDiff);
+      meta->addStatement(new GenOp(buf, new DecOp(showDiffVar)));
+
+      String computeForwardProbes = String::String("   @ = debugVizForwardProbes(@,@,@,@,@,@,@,@,@,\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");
+
+      meta->addStatement(new GenOp(computeForwardProbes.c_str(), ibl, surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refBoxMinArray, refBoxMaxArray, inRefPosArray,
+         skylightCubemapIdx, BRDFTexture,
+         irradianceCubemapAR, specularCubemapAR,
+         showAttenVar, showContribVar, showSpecVar, showDiffVar));
+
+      meta->addStatement(new GenOp("   @.rgb = @.rgb;\r\n", color, ibl));
+
+      output = meta;
+      return;
+   }
 }

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

@@ -112,7 +112,8 @@ LangElement* ShaderFeatureHLSL::assignColor( LangElement *elem,
          break;
 
       case Material::PreMult:
-         assign = new GenOp("@ *= @", color, elem);
+         //result = src.rgb + (dst.rgb * (1 - src.A))
+         assign = new GenOp("@.rgb = @.rgb + (@.rgb * (1 - @.a))", color, color, elem, color);
          break;
 
       case Material::Mul:
@@ -3141,15 +3142,21 @@ void ReflectionProbeFeatHLSL::processPix(Vector<ShaderComponent*> &componentList
    Var* wsEyePos = (Var*)LangElement::find("eyePosWorld");
 
    //Reflection vec
-   String computeForwardProbes = String::String("   @.rgb = computeForwardProbes(@,@,@,@,@,@,@,@,@,\r\n\t\t");
+   Var* ibl = (Var*)LangElement::find("ibl");
+   if (!ibl)
+   {
+      ibl = new Var("ibl", "float3");
+   }
+
+   String computeForwardProbes = String::String("   @ = computeForwardProbes(@,@,@,@,@,@,@,@,@,\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");
       
-   meta->addStatement(new GenOp(computeForwardProbes.c_str(), curColor, 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, refBoxMinArray, refBoxMaxArray, inRefPosArray,
       skylightCubemapIdx, BRDFTexture,
       irradianceCubemapAR, specularCubemapAR));
 
-   //meta->addStatement(new GenOp("   @.rgb = @.roughness.xxx;\r\n", albedo, surface));
+   meta->addStatement(new GenOp("   @.rgb = @.rgb;\r\n", curColor, ibl));
 
    output = meta;
 }

+ 153 - 0
Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl

@@ -481,5 +481,158 @@ float4 computeForwardProbes(Surface surface,
    irradiance *= surface.ao;
    specular *= computeSpecOcclusion(surface.NdotV, surface.ao, surface.roughness);
 
+   return float4(irradiance + specular, 0);//alpha writes disabled
+}
+
+float4 debugVizForwardProbes(Surface surface,
+    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],
+    float skylightCubemapIdx, TORQUE_SAMPLER2D(BRDFTexture), 
+	 TORQUE_SAMPLERCUBEARRAY(irradianceCubemapAR), TORQUE_SAMPLERCUBEARRAY(specularCubemapAR), int showAtten, int showContrib, int showSpec, int showDiff)
+{
+   int i = 0;
+   float alpha = 1;
+   float blendFactor[MAX_FORWARD_PROBES];
+   float blendSum = 0;
+   float blendFacSum = 0;
+   float invBlendSum = 0;
+   float probehits = 0;
+   //Set up our struct data
+   float contribution[MAX_FORWARD_PROBES];
+  for (i = 0; i < numProbes; ++i)
+  {
+      contribution[i] = 0;
+
+      if (probeConfigData[i].r == 0) //box
+      {
+         contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b);
+         if (contribution[i] > 0.0)
+            probehits++;
+      }
+      else if (probeConfigData[i].r == 1) //sphere
+      {
+         contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, probeConfigData[i].g);
+         if (contribution[i] > 0.0)
+            probehits++;
+      }
+
+      contribution[i] = max(contribution[i], 0);
+
+      blendSum += contribution[i];
+      invBlendSum += (1.0f - contribution[i]);
+   }
+
+   if (probehits > 1.0)
+   {
+      for (i = 0; i < numProbes; i++)
+      {
+         blendFactor[i] = ((contribution[i] / blendSum)) / probehits;
+         blendFactor[i] *= ((contribution[i]) / invBlendSum);
+         blendFactor[i] = saturate(blendFactor[i]);
+         blendFacSum += blendFactor[i];
+      }
+
+      // Normalize blendVal
+      if (blendFacSum == 0.0f) // Possible with custom weight
+      {
+         blendFacSum = 1.0f;
+      }
+
+      float invBlendSumWeighted = 1.0f / blendFacSum;
+      for (i = 0; i < numProbes; ++i)
+      {
+         blendFactor[i] *= invBlendSumWeighted;
+         contribution[i] *= blendFactor[i];
+      }
+   }
+
+   if(showAtten == 1)
+   {
+      float contribAlpha = 1;
+      for (i = 0; i < numProbes; ++i)
+      {
+         contribAlpha -= contribution[i];
+      }
+
+      return float4(1 - contribAlpha, 1 - contribAlpha, 1 - contribAlpha, 1);
+   }
+
+   if(showContrib == 1)
+   {
+      float3 probeContribColors[4];
+      probeContribColors[0] = float3(1,0,0);
+      probeContribColors[1] = float3(0,1,0);
+      probeContribColors[2] = float3(0,0,1);
+      probeContribColors[3] = float3(1,1,0);
+
+      float3 finalContribColor = float3(0, 0, 0);
+      float contribAlpha = 1;
+      for (i = 0; i < numProbes; ++i)
+      {
+         finalContribColor += contribution[i] *probeContribColors[i].rgb;
+         contribAlpha -= contribution[i];
+      }
+
+      //Skylight coloration for anything not covered by probes above
+      if(skylightCubemapIdx != -1)
+         finalContribColor += float3(0.3, 0.3, 0.3) * contribAlpha;
+
+      return float4(finalContribColor, 1);
+   }
+
+   float3 irradiance = float3(0, 0, 0);
+   float3 specular = float3(0, 0, 0);
+
+   // Radiance (Specular)
+   float lod = surface.roughness*cubeMips;
+
+   if(showSpec == 1)
+   {
+      lod = 0;
+   }
+
+   for (i = 0; i < numProbes; ++i)
+   {
+      float contrib = contribution[i];
+      if (contrib > 0.0f)
+      {
+         int cubemapIdx = probeConfigData[i].a;
+         float3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refBoxMinArray[i].xyz, refBoxMaxArray[i].xyz, inRefPosArray[i].xyz);
+
+         irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib;
+         specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib;
+         alpha -= contrib;
+      }
+   }
+
+   if(skylightCubemapIdx != -1 && alpha >= 0.001)
+   {
+      irradiance = lerp(irradiance,TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, surface.R, skylightCubemapIdx, 0).xyz,alpha);
+      specular = lerp(specular,TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, surface.R, skylightCubemapIdx, lod).xyz,alpha);
+   }
+
+   if(showSpec == 1)
+   {
+      return float4(specular, 0);
+   }
+
+   if(showDiff == 1)
+   {
+      return float4(irradiance, 0);
+   }
+
+   //energy conservation
+   float3 kD = 1.0f - surface.F;
+   kD *= 1.0f - surface.metalness;
+
+   float dfgNdotV = max( surface.NdotV , 0.0009765625f ); //0.5f/512.0f (512 is size of dfg/brdf lookup tex)
+   float2 envBRDF = TORQUE_TEX2DLOD(BRDFTexture, float4(dfgNdotV, surface.roughness,0,0)).rg;
+   specular *= surface.F * envBRDF.x + surface.f90 * envBRDF.y;
+   irradiance *= kD * surface.baseColor.rgb;
+
+   //AO
+   irradiance *= surface.ao;
+   specular *= computeSpecOcclusion(surface.NdotV, surface.ao, surface.roughness);
+
    return float4(irradiance + specular, 0);//alpha writes disabled
 }

+ 44 - 1
Templates/BaseGame/game/tools/worldEditor/scripts/visibility/probeViz.cs

@@ -1,27 +1,70 @@
 function toggleProbeViz(%mode)
 {
-   setLightingMode("ReflectionsOnly");
+   if($Probes::showAttenuation == 1)
+      %lastMode = "Attenuation";
+   else if($Probes::showProbeContrib == 1)
+      %lastMode = "Contribution";
+   else if($Probes::showSpecularCubemaps == 1)
+      %lastMode = "Specular";
+   else if($Probes::showDiffuseCubemaps == 1)
+      %lastMode = "Diffuse";
    
    $Probes::showAttenuation = 0;
    $Probes::showSpecularCubemaps = 0;
    $Probes::showDiffuseCubemaps = 0;
    $Probes::showProbeContrib = 0;
+   
+   for(%i=0; %i < 4; %i++)
+   {
+      EVisibilityProbesOptions.checkItem(%i, false);
+   }
+   
+   if(%mode $= %lastMode)
+   {
+      setLightingMode("Lit"); 
+      
+      //forces the forward materials to get dis viz properly
+      reInitMaterials();
+   
+      return;
+   }
+   else
+   {
+      setLightingMode("ReflectionsOnly");  
+   }
          
    switch$(%mode)
    {
       case "Attenuation":
          $Probes::showAttenuation = 1;
+         EVisibilityProbesOptions.checkItem(0, true);
       case "Contribution":
          $Probes::showProbeContrib = 1;
+         EVisibilityProbesOptions.checkItem(1, true);
       case "Specular":
          $Probes::showSpecularCubemaps = 1;
+         EVisibilityProbesOptions.checkItem(2, true);
       case "Diffuse":
          $Probes::showDiffuseCubemaps = 1;
+         EVisibilityProbesOptions.checkItem(3, true);
    }
+   
+   //forces the forward materials to get dis viz properly
+   reInitMaterials();
 }
 
 function disableProbeViz()
 {
    setLightingMode("Lit");
    toggleProbeViz(-1);
+}
+
+function toggleProbeLiveUpdates()
+{
+   if($Probes::liveUpdates $= "")
+      $Probes::liveUpdates = false;
+      
+   $Probes::liveUpdates = !$Probes::liveUpdates;
+   
+   EVisibilityProbesOptions.checkItem(5, $Probes::liveUpdates);
 }

+ 2 - 3
Templates/BaseGame/game/tools/worldEditor/scripts/visibility/visibilityLayer.ed.cs

@@ -150,11 +150,10 @@ function setupEditorVisibilityMenu()
       item[ 1 ] = "Show Probe Contribution" TAB "" TAB "toggleProbeViz(\"Contribution\");";
       item[ 2 ] = "Show Probe Specular Reflections Only" TAB "" TAB "toggleProbeViz(\"Specular\");";
       item[ 3 ] = "Show Probe Diffuse Reflections Only" TAB "" TAB "toggleProbeViz(\"Diffuse\");";
-      item[ 4 ] = "Enable Live Updates on Selected Probe" TAB "" TAB "";
+      item[ 4 ] = "-";
+      item[ 5 ] = "Enable Live Updates on Selected Probe" TAB "" TAB "toggleProbeLiveUpdates();";
    };
    
-   %probespopup.enableItem(4, false);
-   
    %bufferVizpopup = new PopupMenu(EBufferVizModeOptions)
    {
       superClass = "MenuBuilder";