From 60d0e7319010cefef3615e229fdf94b01586f267 Mon Sep 17 00:00:00 2001 From: Areloch Date: Fri, 22 Nov 2019 01:30:49 -0600 Subject: [PATCH] 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 --- .../source/T3D/lighting/reflectionProbe.cpp | 6 + .../shaderGen/HLSL/debugVizFeatureHLSL.cpp | 102 +++++++++++- .../shaderGen/HLSL/shaderFeatureHLSL.cpp | 15 +- .../game/core/rendering/shaders/lighting.hlsl | 153 ++++++++++++++++++ .../scripts/visibility/probeViz.cs | 45 +++++- .../scripts/visibility/visibilityLayer.ed.cs | 5 +- 6 files changed, 313 insertions(+), 13 deletions(-) diff --git a/Engine/source/T3D/lighting/reflectionProbe.cpp b/Engine/source/T3D/lighting/reflectionProbe.cpp index cdf948cc1..f96937aba 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.cpp +++ b/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); diff --git a/Engine/source/shaderGen/HLSL/debugVizFeatureHLSL.cpp b/Engine/source/shaderGen/HLSL/debugVizFeatureHLSL.cpp index f7c6ab3b1..4ac85abce 100644 --- a/Engine/source/shaderGen/HLSL/debugVizFeatureHLSL.cpp +++ b/Engine/source/shaderGen/HLSL/debugVizFeatureHLSL.cpp @@ -24,19 +24,21 @@ void DebugVizHLSL::processPix(Vector& 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& 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(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; + } } diff --git a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp index 8c3898f9f..6b8576247 100644 --- a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp +++ b/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 &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; } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl index 8b372c149..aff2221d2 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl +++ b/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 } \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/visibility/probeViz.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/visibility/probeViz.cs index 800d14011..3a9e43174 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/visibility/probeViz.cs +++ b/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); } \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/visibility/visibilityLayer.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/visibility/visibilityLayer.ed.cs index 327e9d88d..8f4b93462 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/visibility/visibilityLayer.ed.cs +++ b/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";