diff --git a/Engine/source/T3D/lighting/reflectionProbe.cpp b/Engine/source/T3D/lighting/reflectionProbe.cpp index 10bc07abc..6abcbf43c 100644 --- a/Engine/source/T3D/lighting/reflectionProbe.cpp +++ b/Engine/source/T3D/lighting/reflectionProbe.cpp @@ -272,6 +272,8 @@ bool ReflectionProbe::onAdd() { createGeometry(); updateProbeParams(); + + PROBEMGR->registerProbe(mProbeInfoIdx); } setMaskBits(-1); @@ -281,6 +283,10 @@ bool ReflectionProbe::onAdd() void ReflectionProbe::onRemove() { + if (isClientObject()) + { + PROBEMGR->unregisterProbe(mProbeInfoIdx); + } // Remove this object from the scene removeFromScene(); @@ -441,7 +447,7 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream) updateMaterial(); } - //PROBEMGR->updateProbes(); + PROBEMGR->updateProbes(); } void ReflectionProbe::createGeometry() @@ -597,6 +603,8 @@ void ReflectionProbe::updateMaterial() mProbeInfo->mIsEnabled = true; else mProbeInfo->mIsEnabled = false; + + PROBEMGR->updateProbes(); } bool ReflectionProbe::createClientResources() @@ -682,7 +690,7 @@ void ReflectionProbe::prepRenderImage(SceneRenderState *state) mProbeInfo->mScore *= mMax(mAbs(mDot(vect, state->getCameraTransform().getForwardVector())),0.001f); //Register - PROBEMGR->registerProbe(mProbeInfoIdx); + //PROBEMGR->registerProbe(mProbeInfoIdx); if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr) { diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index f5d3504d3..3057af993 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -230,7 +230,7 @@ void RenderProbeMgr::registerProbe(U32 probeIdx) mRegisteredProbes.push_back_unique(probeIdx); //rebuild our probe data - //_setupStaticParameters(); + _setupStaticParameters(); } void RenderProbeMgr::unregisterProbe(U32 probeIdx) @@ -242,7 +242,7 @@ void RenderProbeMgr::unregisterProbe(U32 probeIdx) mRegisteredProbes.remove(probeIdx); //rebuild our probe data - //_setupStaticParameters(); + _setupStaticParameters(); } // @@ -283,22 +283,21 @@ void RenderProbeMgr::_setupStaticParameters() probeWorldToObjData.setSize(MAXPROBECOUNT); probeBBMinData.setSize(MAXPROBECOUNT); probeBBMaxData.setSize(MAXPROBECOUNT); - probeUseSphereModeData.setSize(MAXPROBECOUNT); - probeRadiusData.setSize(MAXPROBECOUNT); - probeAttenuationData.setSize(MAXPROBECOUNT); + probeConfigData.setSize(MAXPROBECOUNT); } probePositionsData.fill(Point4F::Zero); probeWorldToObjData.fill(MatrixF::Identity); probeBBMinData.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(); 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++) { if (mEffectiveProbeCount >= MAXPROBECOUNT) @@ -320,7 +319,7 @@ void RenderProbeMgr::_setupStaticParameters() if (curEntry.mIsSkylight) continue; - mMipCount = curEntry.mCubemap.getPointer()->getMipMapLevels(); + mMipCount = curEntry.mCubemap.getPointer()->getMipMapLevels(); //Setup 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); 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); irradMaps.push_back(curEntry.mIrradianceCubemap); @@ -423,7 +422,7 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData, static AlignedArray probeLocalPositions(4, sizeof(Point3F)); static AlignedArray probeIsSphere(4, sizeof(F32)); //static AlignedArray probeCubemap(4, sizeof(CubemapData)); - F32 range; + //F32 range; // Need to clear the buffers so that we don't leak // lights from previous passes or have NaNs. @@ -437,7 +436,7 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData, matSet.restoreSceneViewProjection(); - const MatrixF &worldToCameraXfm = matSet.getWorldToCamera(); + //const MatrixF &worldToCameraXfm = matSet.getWorldToCamera(); // Gather the data for the first 4 probes. /*const ProbeRenderInst *probe; @@ -586,7 +585,7 @@ void RenderProbeMgr::render( SceneRenderState *state ) if (getProbeArrayEffect() == nullptr) return; - updateProbes(); + //updateProbes(); // Early out if nothing to draw. if (!ProbeRenderInst::all.size() || !RenderProbeMgr::smRenderReflectionProbes || mEffectiveProbeCount == 0 @@ -605,13 +604,43 @@ void RenderProbeMgr::render( SceneRenderState *state ) //_setupPerFrameParameters(state); //Array rendering - U32 probeCount = ProbeRenderInst::all.size(); + //U32 probeCount = ProbeRenderInst::all.size(); if (mEffectiveProbeCount != 0) { mProbeArrayEffect->setCubemapArrayTexture(4, mCubemapArray); 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 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("$numProbes", (float)mEffectiveProbeCount); @@ -619,9 +648,7 @@ void RenderProbeMgr::render( SceneRenderState *state ) mProbeArrayEffect->setShaderConst("$worldToObjArray", probeWorldToObjData); mProbeArrayEffect->setShaderConst("$bbMinArray", probeBBMinData); 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. diff --git a/Engine/source/renderInstance/renderProbeMgr.h b/Engine/source/renderInstance/renderProbeMgr.h index f9e2fb87e..bc931d6d5 100644 --- a/Engine/source/renderInstance/renderProbeMgr.h +++ b/Engine/source/renderInstance/renderProbeMgr.h @@ -164,9 +164,7 @@ class RenderProbeMgr : public RenderBinManager Vector probeWorldToObjData; Vector probeBBMinData; Vector probeBBMaxData; - Vector probeUseSphereModeData; - Vector probeRadiusData; - Vector probeAttenuationData; + Vector probeConfigData; Vector cubeMaps; Vector irradMaps; diff --git a/Templates/Full/game/levels/AProbeTest.mis b/Templates/Full/game/levels/AProbeTest.mis index c39162fef..76bf1422a 100644 --- a/Templates/Full/game/levels/AProbeTest.mis +++ b/Templates/Full/game/levels/AProbeTest.mis @@ -132,7 +132,7 @@ new SimGroup(MissionGroup) { posOffset = "0 0 0"; ReflectionMode = "Baked Cubemap"; Bake = "0"; - position = "0 0 4"; + position = "-0.0194688 0 4"; rotation = "1 0 0 0"; scale = "5 5 5"; canSave = "1"; @@ -152,7 +152,7 @@ new SimGroup(MissionGroup) { posOffset = "0 0 0"; ReflectionMode = "Baked Cubemap"; Bake = "0"; - position = "-10 8 4"; + position = "-7.18203 8.03441 4"; rotation = "1 0 0 0"; scale = "5 5 5"; canSave = "1"; @@ -171,7 +171,7 @@ new SimGroup(MissionGroup) { posOffset = "0 0 0"; ReflectionMode = "Baked Cubemap"; Bake = "0"; - position = "-10 0 4"; + position = "-10.0428 0.020255 4"; rotation = "1 0 0 0"; scale = "5 5 5"; canSave = "1"; @@ -190,7 +190,7 @@ new SimGroup(MissionGroup) { posOffset = "0 0 0"; ReflectionMode = "Baked Cubemap"; Bake = "0"; - position = "-10 -8 4"; + position = "-7.8725 -8.01423 4"; rotation = "1 0 0 0"; scale = "5 5 5"; canSave = "1"; @@ -203,6 +203,120 @@ new SimGroup(MissionGroup) { 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 = "-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() { Material = "Grid512_Orange_Mat"; 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 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.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 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.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 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.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 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.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 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.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 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.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 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.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"; diff --git a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl index 92327a410..735b59be8 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeArrayP.hlsl @@ -26,15 +26,20 @@ uniform float4 inProbePosArray[MAX_PROBES]; uniform float4x4 worldToObjArray[MAX_PROBES]; uniform float4 bbMinArray[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 // 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/ -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 offset = wsPosition; 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 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; 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 - 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) 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); @@ -74,14 +75,13 @@ float3 iblBoxSpecular(Surface surface, float3 surfToEye, TORQUE_SAMPLER2D(brdfTe 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 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 boxInnerRange = boxOuterRange / tempAttenVal; + float boxInnerRange = boxOuterRange / probeConfigData[id].b; float3 localDir = float3(abs(surfPosLS.x), abs(surfPosLS.y), abs(surfPosLS.z)); localDir = (localDir - boxInnerRange) / (boxOuterRange - boxInnerRange); @@ -102,52 +102,47 @@ float4 main( PFXVertToPix IN ) : SV_TARGET if (getFlag(surface.matFlag, 0)) { discard; - } - - float blendVal[MAX_PROBES]; - float3 surfToEye = normalize(surface.P - eyePosWorld); + } int i = 0; + + float blendVal[MAX_PROBES]; float blendSum = 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 { - 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. // 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++) + + //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); 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 { blendSum = 1.0f; @@ -158,6 +153,28 @@ float4 main( PFXVertToPix IN ) : SV_TARGET { 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 specular = float3(0,0,0); @@ -168,13 +185,35 @@ float4 main( PFXVertToPix IN ) : SV_TARGET kD *= 1.0 - surface.metalness; 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 float3 diffuse = kD * irradiance * surface.baseColor.rgb; float4 finalColor = float4(diffuse + specular * surface.ao, blendSum); 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 } diff --git a/Templates/Full/game/tools/worldEditor/main.cs b/Templates/Full/game/tools/worldEditor/main.cs index 28d6937f4..691363643 100644 --- a/Templates/Full/game/tools/worldEditor/main.cs +++ b/Templates/Full/game/tools/worldEditor/main.cs @@ -130,6 +130,10 @@ function initializeWorldEditor() EVisibility.addOption( "AL: Backbuffer", "$AL_BackbufferVisualizeVar", "toggleBackbufferViz" ); EVisibility.addOption( "AL: Glow Buffer", "$AL_GlowVisualizeVar", "toggleGlowViz" ); 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( "Disable Zone Culling", "$Scene::disableZoneCulling", "" ); EVisibility.addOption( "Disable Terrain Occlusion", "$Scene::disableTerrainOcclusion", "" );