diff --git a/Engine/source/T3D/lighting/boxEnvironmentProbe.cpp b/Engine/source/T3D/lighting/boxEnvironmentProbe.cpp
index ab6ea902e..a08691d1c 100644
--- a/Engine/source/T3D/lighting/boxEnvironmentProbe.cpp
+++ b/Engine/source/T3D/lighting/boxEnvironmentProbe.cpp
@@ -158,11 +158,8 @@ void BoxEnvironmentProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
void BoxEnvironmentProbe::updateProbeParams()
{
- if (!mProbeInfo)
- return;
-
mProbeShapeType = ProbeRenderInst::Box;
- mProbeInfo->mAtten = mAtten;
+ mProbeInfo.mAtten = mAtten;
Parent::updateProbeParams();
}
diff --git a/Engine/source/T3D/lighting/reflectionProbe.cpp b/Engine/source/T3D/lighting/reflectionProbe.cpp
index ced662efc..c0bdece5e 100644
--- a/Engine/source/T3D/lighting/reflectionProbe.cpp
+++ b/Engine/source/T3D/lighting/reflectionProbe.cpp
@@ -83,17 +83,13 @@ ImplementEnumType(ReflectionModeEnum,
{ ReflectionProbe::NoReflection, "No Reflections", "This probe does not provide any local reflection data"},
{ ReflectionProbe::StaticCubemap, "Static Cubemap", "Uses a static CubemapData" },
{ ReflectionProbe::BakedCubemap, "Baked Cubemap", "Uses a cubemap baked from the probe's current position" },
-{ ReflectionProbe::DynamicCubemap, "Dynamic Cubemap", "Uses a cubemap baked from the probe's current position, updated at a set rate" },
+//{ ReflectionProbe::DynamicCubemap, "Dynamic Cubemap", "Uses a cubemap baked from the probe's current position, updated at a set rate" },
EndImplementEnumType;
//-----------------------------------------------------------------------------
// Object setup and teardown
//-----------------------------------------------------------------------------
-ReflectionProbe::ReflectionProbe() :
- cubeDescId(0),
- reflectorDesc(nullptr),
- mSphereVertCount(0),
- mSpherePrimitiveCount(0)
+ReflectionProbe::ReflectionProbe()
{
// Flag this object so that it will always
// be sent across the network to clients
@@ -106,8 +102,7 @@ ReflectionProbe::ReflectionProbe() :
mReflectionModeType = BakedCubemap;
mEnabled = true;
- mBake = false;
- mDirty = false;
+ mBakeReflections = false;
mCubemapDirty = false;
mRadius = 10;
@@ -122,17 +117,14 @@ ReflectionProbe::ReflectionProbe() :
mEditorShapeInst = NULL;
mEditorShape = NULL;
- mRefreshRateMS = 500;
+ mRefreshRateMS = 200;
mDynamicLastBakeMS = 0;
mMaxDrawDistance = 75;
mResourcesCreated = false;
-
- mProbeInfo = nullptr;
-
mPrefilterSize = 64;
- mPrefilterMipLevels = mLog2(F32(mPrefilterSize))+1;
+ mPrefilterMipLevels = mLog2(F32(mPrefilterSize));
mPrefilterMap = nullptr;
mIrridianceMap = nullptr;
@@ -158,7 +150,7 @@ void ReflectionProbe::initPersistFields()
{
addGroup("Rendering");
addProtectedField("enabled", TypeBool, Offset(mEnabled, ReflectionProbe),
- &_setEnabled, &defaultProtectedGetFn, "Regenerate Voxel Grid");
+ &_setEnabled, &defaultProtectedGetFn, "Is the probe enabled or not");
endGroup("Rendering");
addGroup("Reflection");
@@ -168,18 +160,18 @@ void ReflectionProbe::initPersistFields()
addProtectedField("EditPosOffset", TypeBool, Offset(mEditPosOffset, ReflectionProbe),
&_toggleEditPosOffset, &defaultProtectedGetFn, "Toggle Edit Pos Offset Mode", AbstractClassRep::FieldFlags::FIELD_ComponentInspectors);
- addField("refOffset", TypePoint3F, Offset(mProbeRefOffset, ReflectionProbe), "");
- addField("refScale", TypePoint3F, Offset(mProbeRefScale, ReflectionProbe), "");
+ addField("refOffset", TypePoint3F, Offset(mProbeRefOffset, ReflectionProbe), "The reference positional offset for the probe. This is used for adjusting the perceived center and area of influence.\nHelpful in adjusting parallax issues");
+ addField("refScale", TypePoint3F, Offset(mProbeRefScale, ReflectionProbe), "The reference scale for the probe. This is used for adjusting the perceived center and area of influence.\nHelpful in adjusting parallax issues");
addProtectedField("ReflectionMode", TypeReflectionModeEnum, Offset(mReflectionModeType, ReflectionProbe), &_setReflectionMode, &defaultProtectedGetFn,
- "The type of mesh data to use for collision queries.");
+ "Used to dictate what sort of cubemap the probes use when using IBL.");
- addField("StaticCubemap", TypeCubemapName, Offset(mCubemapName, ReflectionProbe), "Cubemap used instead of reflection texture if fullReflect is off.");
+ addField("StaticCubemap", TypeCubemapName, Offset(mCubemapName, ReflectionProbe), "This is used when a static cubemap is used. The name of the cubemap is looked up and loaded for the IBL calculations.");
- addField("DynamicReflectionRefreshMS", TypeS32, Offset(mRefreshRateMS, ReflectionProbe), "How often the dynamic cubemap is refreshed in milliseconds. Only works when the ReflectionMode is set to DynamicCubemap.");
+ //addField("DynamicReflectionRefreshMS", TypeS32, Offset(mRefreshRateMS, ReflectionProbe), "How often the dynamic cubemap is refreshed in milliseconds. Only works when the ReflectionMode is set to DynamicCubemap.");
- addProtectedField("Bake", TypeBool, Offset(mBake, ReflectionProbe),
- &_doBake, &defaultProtectedGetFn, "Regenerate Voxel Grid", AbstractClassRep::FieldFlags::FIELD_ComponentInspectors);
+ addProtectedField("Bake", TypeBool, Offset(mBakeReflections, ReflectionProbe),
+ &_doBake, &defaultProtectedGetFn, "Bake Probe Reflections", AbstractClassRep::FieldFlags::FIELD_ComponentInspectors);
endGroup("Reflection");
Con::addVariable("$Light::renderReflectionProbes", TypeBool, &RenderProbeMgr::smRenderReflectionProbes,
@@ -319,8 +311,7 @@ void ReflectionProbe::onRemove()
{
if (isClientObject())
{
- PROBEMGR->unregisterProbe(mProbeInfo->mProbeIdx);
- mProbeInfo = nullptr;
+ PROBEMGR->unregisterProbe(mProbeInfo.mProbeIdx);
}
// Remove this object from the scene
@@ -436,7 +427,6 @@ U32 ReflectionProbe::packUpdate(NetConnection *conn, U32 mask, BitStream *stream
stream->write(mProbeUniqueID);
stream->write((U32)mReflectionModeType);
stream->write(mCubemapName);
- stream->write(mRefreshRateMS);
}
if (stream->writeFlag(mask & EnabledMask))
@@ -463,7 +453,7 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
resetWorldBox();
mathRead(*stream, &mProbeRefOffset);
- mathRead(*stream, &mProbeRefScale);
+ mathRead(*stream, &mProbeRefScale);
mDirty = true;
}
@@ -490,8 +480,6 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
if(oldReflectModeType != mReflectionModeType || oldCubemapName != mCubemapName)
mCubemapDirty = true;
- stream->read(&mRefreshRateMS);
-
mDirty = true;
}
@@ -501,11 +489,6 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
mDirty = true;
}
-
- if (mDirty)
- {
- updateProbeParams();
- }
}
//-----------------------------------------------------------------------------
@@ -513,12 +496,9 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
//-----------------------------------------------------------------------------
void ReflectionProbe::updateProbeParams()
{
- if (!mProbeInfo)
- return;
+ mProbeInfo.mIsEnabled = mEnabled;
- mProbeInfo->mIsEnabled = mEnabled;
-
- mProbeInfo->mProbeShapeType = mProbeShapeType;
+ mProbeInfo.mProbeShapeType = mProbeShapeType;
if (mProbeShapeType == ProbeRenderInst::Sphere)
mObjScale.set(mRadius, mRadius, mRadius);
@@ -527,10 +507,8 @@ void ReflectionProbe::updateProbeParams()
if (mProbeShapeType == ProbeRenderInst::Skylight)
{
- mProbeInfo->mPosition = Point3F::Zero;
- mProbeInfo->mTransform = MatrixF::Identity;
-
- mProbeInfo->mIsSkylight = true;
+ mProbeInfo.mPosition = Point3F::Zero;
+ mProbeInfo.mTransform = MatrixF::Identity;
F32 visDist = gClientSceneGraph->getVisibleDistance();
Box3F skylightBounds = Box3F(visDist * 2);
@@ -541,21 +519,19 @@ void ReflectionProbe::updateProbeParams()
setGlobalBounds();
- mProbeInfo->mScore = -1.0f;
+ mProbeInfo.mScore = 10000.0f;
}
else
{
MatrixF transform = getTransform();
- mProbeInfo->mPosition = getPosition();
+ mProbeInfo.mPosition = getPosition();
transform.scale(getScale());
- mProbeInfo->mTransform = transform.inverse();
-
- mProbeInfo->mIsSkylight = false;
+ mProbeInfo.mTransform = transform.inverse();
bounds = mWorldBox;
- mProbeInfo->mScore = mMaxDrawDistance;
+ mProbeInfo.mScore = 1;
}
// Skip our transform... it just dirties mask bits.
@@ -563,14 +539,14 @@ void ReflectionProbe::updateProbeParams()
resetWorldBox();
- mProbeInfo->mBounds = bounds;
- mProbeInfo->mExtents = getScale();
- mProbeInfo->mRadius = mRadius;
+ mProbeInfo.mBounds = bounds;
+ mProbeInfo.mExtents = getScale();
+ mProbeInfo.mRadius = mRadius;
- mProbeInfo->mProbeRefOffset = mProbeRefOffset;
- mProbeInfo->mProbeRefScale = mProbeRefScale;
+ mProbeInfo.mProbeRefOffset = mProbeRefOffset;
+ mProbeInfo.mProbeRefScale = mProbeRefScale;
- mProbeInfo->mDirty = true;
+ mProbeInfo.mDirty = true;
if (mCubemapDirty)
{
@@ -587,108 +563,12 @@ void ReflectionProbe::updateProbeParams()
void ReflectionProbe::processDynamicCubemap()
{
- /*if (!mProbeInfo)
- return;
-
- mEnabled = false;
-
- if (mReflectionModeType == DynamicCubemap && !mDynamicCubemap.isNull())
- {
- mProbeInfo->mPrefilterCubemap = mDynamicCubemap;
-
- if (reflectorDesc == nullptr)
- {
- //find it
- if (!Sim::findObject("DefaultCubeDesc", reflectorDesc))
- {
- mProbeInfo->mIsEnabled = false;
- return;
- }
- }
-
- mCubeReflector.unregisterReflector();
- mCubeReflector.registerReflector(this, reflectorDesc); //need to decide how we wanna do the reflectorDesc. static name or a field
- }
-
- if (mEnabled)
- mProbeInfo->mIsEnabled = true;
- else
- mProbeInfo->mIsEnabled = false;
-
- mCubemapDirty = false;
-
- //Update the probe manager with our new texture!
- //if (!mProbeInfo->mIsSkylight && mProbeInfo->mPrefilterCubemap->isInitialized() && mProbeInfo->mIrradianceCubemap->isInitialized())
- // PROBEMGR->updateProbeTexture(mProbeInfo->mProbeIdx);*/
-
- if (!mProbeInfo)
- return;
-
- mProbeInfo->mIsEnabled = false;
-
- if (mReflectionModeType != DynamicCubemap)
- return;
-
- if (reflectorDesc == nullptr)
- {
- //find it
- if (!Sim::findObject("DefaultCubeDesc", reflectorDesc))
- {
- mProbeInfo->mIsEnabled = false;
- return;
- }
-
- mCubeReflector.unregisterReflector();
- mCubeReflector.registerReflector(this, reflectorDesc); //need to decide how we wanna do the reflectorDesc. static name or a field
- }
-
- if (mCubeReflector.getCubemap())
- {
- U32 resolution = Con::getIntVariable("$pref::ReflectionProbes::BakeResolution", 64);
- U32 prefilterMipLevels = mLog2(F32(resolution))+1;
-
- //Prep it with whatever resolution we've dictated for our bake
- mIrridianceMap->mCubemap->initDynamic(resolution, PROBEMGR->PROBE_FORMAT);
- mPrefilterMap->mCubemap->initDynamic(resolution, PROBEMGR->PROBE_FORMAT);
-
- GFXTextureTargetRef renderTarget = GFX->allocRenderToTextureTarget(false);
-
- IBLUtilities::GenerateIrradianceMap(renderTarget, mCubeReflector.getCubemap(), mIrridianceMap->mCubemap);
- IBLUtilities::GeneratePrefilterMap(renderTarget, mCubeReflector.getCubemap(), prefilterMipLevels, mPrefilterMap->mCubemap);
- }
-
- if (mIrridianceMap == nullptr || mIrridianceMap->mCubemap.isNull())
- {
- Con::errorf("ReflectionProbe::processDynamicCubemap() - Unable to load baked irradiance map at %s", getIrradianceMapPath().c_str());
- return;
- }
-
- if (mPrefilterMap == nullptr || mPrefilterMap->mCubemap.isNull())
- {
- Con::errorf("ReflectionProbe::processDynamicCubemap() - Unable to load baked prefilter map at %s", getPrefilterMapPath().c_str());
- return;
- }
-
- mProbeInfo->mPrefilterCubemap = mPrefilterMap->mCubemap;
- mProbeInfo->mIrradianceCubemap = mIrridianceMap->mCubemap;
-
- if (mEnabled && mProbeInfo->mPrefilterCubemap->isInitialized() && mProbeInfo->mIrradianceCubemap->isInitialized())
- {
- mProbeInfo->mIsEnabled = true;
-
- mCubemapDirty = false;
-
- //Update the probe manager with our new texture!
- PROBEMGR->updateProbeTexture(mProbeInfo);
- }
+
}
void ReflectionProbe::processBakedCubemap()
{
- if (!mProbeInfo)
- return;
-
- mProbeInfo->mIsEnabled = false;
+ mProbeInfo.mIsEnabled = false;
if ((mReflectionModeType != BakedCubemap) || mProbeUniqueID.isEmpty())
return;
@@ -700,7 +580,7 @@ void ReflectionProbe::processBakedCubemap()
mIrridianceMap->updateFaces();
}
- if (mIrridianceMap == nullptr || !mIrridianceMap->mCubemap->isInitialized())
+ if (mIrridianceMap == nullptr || mIrridianceMap->mCubemap.isNull())
{
Con::errorf("ReflectionProbe::processDynamicCubemap() - Unable to load baked irradiance map at %s", getIrradianceMapPath().c_str());
return;
@@ -713,32 +593,33 @@ void ReflectionProbe::processBakedCubemap()
mPrefilterMap->updateFaces();
}
- if (mPrefilterMap == nullptr || !mPrefilterMap->mCubemap->isInitialized())
+ if (mPrefilterMap == nullptr || mPrefilterMap->mCubemap.isNull())
{
Con::errorf("ReflectionProbe::processDynamicCubemap() - Unable to load baked prefilter map at %s", getPrefilterMapPath().c_str());
return;
}
- mProbeInfo->mPrefilterCubemap = mPrefilterMap->mCubemap;
- mProbeInfo->mIrradianceCubemap = mIrridianceMap->mCubemap;
+ mProbeInfo.mPrefilterCubemap = mPrefilterMap->mCubemap;
+ mProbeInfo.mIrradianceCubemap = mIrridianceMap->mCubemap;
- if (mEnabled && mProbeInfo->mPrefilterCubemap->isInitialized() && mProbeInfo->mIrradianceCubemap->isInitialized())
+ if (mEnabled && mProbeInfo.mPrefilterCubemap->isInitialized() && mProbeInfo.mIrradianceCubemap->isInitialized())
{
- mProbeInfo->mIsEnabled = true;
+ mProbeInfo.mIsEnabled = true;
mCubemapDirty = false;
//Update the probe manager with our new texture!
- PROBEMGR->updateProbeTexture(mProbeInfo);
+ PROBEMGR->updateProbeTexture(&mProbeInfo);
+
+ //now, cleanup
+ mProbeInfo.mPrefilterCubemap.free();
+ mProbeInfo.mIrradianceCubemap.free();
}
}
void ReflectionProbe::processStaticCubemap()
{
- if (!mProbeInfo)
- return;
-
- mProbeInfo->mIsEnabled = false;
+ mProbeInfo.mIsEnabled = false;
String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/");
@@ -747,45 +628,31 @@ void ReflectionProbe::processStaticCubemap()
if (Platform::isFile(irradFileName))
{
- if (mIrridianceMap == nullptr)
- {
- Con::errorf("ReflectionProbe::processStaticCubemap() - Unable to load baked irradiance map at %s", irradFileName);
- return;
- }
-
mIrridianceMap->setCubemapFile(FileName(irradFileName));
-
- if (mIrridianceMap->mCubemap.isNull())
- {
- Con::errorf("ReflectionProbe::processStaticCubemap() - Unable to load baked irradiance map at %s", irradFileName);
- return;
- }
-
mIrridianceMap->updateFaces();
}
+ if (mIrridianceMap == nullptr || mIrridianceMap->mCubemap.isNull())
+ {
+ Con::errorf("ReflectionProbe::processStaticCubemap() - Unable to load baked irradiance map at %s", irradFileName);
+ return;
+ }
+
char prefilterFileName[256];
dSprintf(prefilterFileName, 256, "%s%s_Prefilter.dds", path.c_str(), mCubemapName.c_str());
if (Platform::isFile(prefilterFileName))
{
- if (mPrefilterMap == nullptr)
- {
- Con::errorf("ReflectionProbe::processStaticCubemap() - Unable to load baked prefilter map at %s", prefilterFileName);
- return;
- }
-
mPrefilterMap->setCubemapFile(FileName(prefilterFileName));
-
- if (mPrefilterMap->mCubemap.isNull())
- {
- Con::errorf("ReflectionProbe::processStaticCubemap() - Unable to load baked prefilter map at %s", prefilterFileName);
- return;
- }
-
mPrefilterMap->updateFaces();
}
+ if (mPrefilterMap == nullptr || mPrefilterMap->mCubemap.isNull())
+ {
+ Con::errorf("ReflectionProbe::processStaticCubemap() - Unable to load baked prefilter map at %s", prefilterFileName);
+ return;
+ }
+
if (!Platform::isFile(prefilterFileName) || !Platform::isFile(irradFileName))
{
//If we are missing either of the files, just re-run the bake
@@ -823,34 +690,29 @@ void ReflectionProbe::processStaticCubemap()
IBLUtilities::SaveCubeMap(prefilterFileName, mPrefilterMap->mCubemap);
}
- if ((mIrridianceMap != nullptr && !mIrridianceMap->mCubemap.isNull()) && (mPrefilterMap != nullptr && !mPrefilterMap->mCubemap.isNull()))
+ if ((mIrridianceMap != nullptr || !mIrridianceMap->mCubemap.isNull()) && (mPrefilterMap != nullptr || !mPrefilterMap->mCubemap.isNull()))
{
- mProbeInfo->mPrefilterCubemap = mPrefilterMap->mCubemap;
- mProbeInfo->mIrradianceCubemap = mIrridianceMap->mCubemap;
+ mProbeInfo.mPrefilterCubemap = mPrefilterMap->mCubemap;
+ mProbeInfo.mIrradianceCubemap = mIrridianceMap->mCubemap;
}
- if (mEnabled && mProbeInfo->mPrefilterCubemap->isInitialized() && mProbeInfo->mIrradianceCubemap->isInitialized())
+ if (mEnabled && mProbeInfo.mPrefilterCubemap->isInitialized() && mProbeInfo.mIrradianceCubemap->isInitialized())
{
- mProbeInfo->mIsEnabled = true;
+ mProbeInfo.mIsEnabled = true;
mCubemapDirty = false;
//Update the probe manager with our new texture!
- PROBEMGR->updateProbeTexture(mProbeInfo);
+ PROBEMGR->updateProbeTexture(&mProbeInfo);
}
}
bool ReflectionProbe::createClientResources()
{
- if (mProbeInfo == nullptr)
- {
- mProbeInfo = PROBEMGR->registerProbe();
- if (!mProbeInfo)
- return false;
-
- mProbeInfo->mIsEnabled = false;
- }
+ PROBEMGR->registerProbe(&mProbeInfo);
+ mProbeInfo.mIsEnabled = false;
+
//irridiance resources
if (!mIrridianceMap)
{
@@ -909,12 +771,10 @@ String ReflectionProbe::getIrradianceMapPath()
void ReflectionProbe::bake()
{
- bool writeFile = mReflectionModeType == BakedCubemap ? true : false;
-
- if (mReflectionModeType == StaticCubemap)
+ if (mReflectionModeType != BakedCubemap)
return;
- PROBEMGR->bakeProbe(this, writeFile);
+ PROBEMGR->bakeProbe(this);
setMaskBits(-1);
}
@@ -922,8 +782,9 @@ void ReflectionProbe::bake()
//-----------------------------------------------------------------------------
//Rendering of editing/debug stuff
//-----------------------------------------------------------------------------
-void ReflectionProbe::createGeometry()
+void ReflectionProbe::createEditorResources()
{
+#ifdef TORQUE_TOOLS
// Clean up our previous shape
if (mEditorShapeInst)
SAFE_DELETE(mEditorShapeInst);
@@ -938,6 +799,7 @@ void ReflectionProbe::createGeometry()
{
mEditorShapeInst = new TSShapeInstance(mEditorShape, isClientObject());
}
+#endif
}
void ReflectionProbe::prepRenderImage(SceneRenderState *state)
@@ -951,16 +813,14 @@ void ReflectionProbe::prepRenderImage(SceneRenderState *state)
//Culling distance. Can be adjusted for performance options considerations via the scalar
if (dist > mMaxDrawDistance * Con::getFloatVariable("$pref::GI::ProbeDrawDistScale", 1.0))
{
- mProbeInfo->mScore = mMaxDrawDistance;
+ mProbeInfo.mScore = mMaxDrawDistance;
return;
}
if (mReflectionModeType == DynamicCubemap && mRefreshRateMS < (Platform::getRealMilliseconds() - mDynamicLastBakeMS))
{
- //bake();
+ bake();
mDynamicLastBakeMS = Platform::getRealMilliseconds();
-
- processDynamicCubemap();
}
//Submit our probe to actually do the probe action
@@ -968,20 +828,20 @@ void ReflectionProbe::prepRenderImage(SceneRenderState *state)
//RenderPassManager *renderPass = state->getRenderPass();
//Update our score based on our radius, distance
- mProbeInfo->mScore = mProbeInfo->mRadius/mMax(dist,1.0f);
+ mProbeInfo.mScore = mMax(dist, 1.0f);
Point3F vect = distVec;
vect.normalizeSafe();
- mProbeInfo->mScore *= mMax(mAbs(mDot(vect, state->getCameraTransform().getForwardVector())),0.001f);
+ //mProbeInfo.mScore *= mMax(mAbs(mDot(vect, state->getCameraTransform().getForwardVector())),0.001f);
- //Register
- //PROBEMGR->registerProbe(mProbeInfoIdx);
+ PROBEMGR->submitProbe(mProbeInfo);
+#ifdef TORQUE_TOOLS
if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mPrefilterMap != nullptr)
{
if(!mEditorShapeInst)
- createGeometry();
+ createEditorResources();
GFXTransformSaver saver;
@@ -1039,7 +899,7 @@ void ReflectionProbe::prepRenderImage(SceneRenderState *state)
saver.restore();
}
- // If the light is selected or light visualization
+ // If the probe is selected or probe visualization
// is enabled then register the callback.
const bool isSelectedInEditor = (gEditingMission && isSelected());
if (isSelectedInEditor)
@@ -1049,6 +909,7 @@ void ReflectionProbe::prepRenderImage(SceneRenderState *state)
ri->type = RenderPassManager::RIT_Editor;
state->getRenderPass()->addInst(ri);
}
+#endif
}
void ReflectionProbe::_onRenderViz(ObjectRenderInst *ri,
@@ -1127,7 +988,7 @@ DefineEngineMethod(ReflectionProbe, postApply, void, (), ,
}
DefineEngineMethod(ReflectionProbe, Bake, void, (), ,
- "@brief returns true if control object is inside the fog\n\n.")
+ "@brief Bakes the cubemaps for a reflection probe\n\n.")
{
ReflectionProbe *clientProbe = (ReflectionProbe*)object->getClientObject();
diff --git a/Engine/source/T3D/lighting/reflectionProbe.h b/Engine/source/T3D/lighting/reflectionProbe.h
index 91ca35b5d..4096bfeda 100644
--- a/Engine/source/T3D/lighting/reflectionProbe.h
+++ b/Engine/source/T3D/lighting/reflectionProbe.h
@@ -63,6 +63,9 @@ class ReflectionProbe : public SceneObject
public:
+ ///
+ /// Used to dictate what sort of cubemap the probes use when using IBL
+ ///
enum ReflectionModeType
{
NoReflection = 0,
@@ -87,36 +90,84 @@ protected:
NextFreeMask = Parent::NextFreeMask << 3
};
- bool mBake;
+ ///
+ /// Only used for interfacing with the editor's inspector bake button
+ ///
+ bool mBakeReflections;
+
+ ///
+ /// Whether this probe is enabled or not
+ ///
bool mEnabled;
+
bool mDirty;
+
+ ///
+ /// Whether this probe's cubemap is dirty or not
+ ///
bool mCubemapDirty;
+#ifdef TORQUE_TOOLS
+ ///
+ /// Used only when the editor is loaded, this is the shape data used for the probe viewing(aka, a sphere)
+ ///
Resource mEditorShape;
+ ///
+ /// This is the shape instance of the editor shape data
+ ///
TSShapeInstance* mEditorShapeInst;
+#endif // TORQUE_TOOLS
//--------------------------------------------------------------------------
// Rendering variables
//--------------------------------------------------------------------------
+ ///
+ /// The shape of the probe
+ ///
ProbeRenderInst::ProbeShapeType mProbeShapeType;
- ProbeRenderInst* mProbeInfo;
+ ///
+ /// This is effectively a packed cache of the probe data actually utilized for rendering.
+ /// The RenderProbeManager uses this via the probe calling registerProbe on creation, and unregisterProbe on destruction
+ /// When the manager goes to render it has the compacted data to read over more efficiently for setting up what probes should
+ /// Actually render in that frame
+ ///
+ ProbeRenderInst mProbeInfo;
- //Reflection Contribution stuff
+ ///
+ /// Used to dictate what sort of cubemap the probes use when using IBL
+ ///
ReflectionModeType mReflectionModeType;
+ ///
+ /// The radius of the probe's influence. Only really relevent in Sphere probes
+ ///
F32 mRadius;
+ ///
+ /// The reference positional offset for the probe. This is used for adjusting the perceived center and area of influence.
+ /// Helpful in adjusting parallax issues
+ ///
Point3F mProbeRefOffset;
+ ///
+ /// The reference scale for the probe. This is used for adjusting the perceived center and area of influence.
+ /// Helpful in adjusting parallax issues
+ ///
Point3F mProbeRefScale;
+
+ ///
+ /// Only used for interfacing with the editor's inspector edit offset button
+ ///
bool mEditPosOffset;
+ ///
+ /// This is used when a static cubemap is used. The name of the cubemap is looked up and loaded for the IBL calculations
+ ///
String mCubemapName;
CubemapData *mStaticCubemap;
GFXCubemapHandle mDynamicCubemap;
String cubeDescName;
U32 cubeDescId;
- CubeReflector mCubeReflector;
ReflectorDesc *reflectorDesc;
//Utilized in dynamic reflections
@@ -133,19 +184,12 @@ protected:
U32 mPrefilterMipLevels;
U32 mPrefilterSize;
+ ///
+ /// This is calculated based on the object's persistantID. Effectively a unique hash ID to set it apart from other probes
+ /// Used to ensure the cubemaps named when baking are unique
+ ///
String mProbeUniqueID;
- // Define our vertex format here so we don't have to
- // change it in multiple spots later
- typedef GFXVertexPNTTB VertexType;
-
- // The GFX vertex and primitive buffers
- GFXVertexBufferHandle< VertexType > mVertexBuffer;
- GFXPrimitiveBufferHandle mPrimitiveBuffer;
-
- U32 mSphereVertCount;
- U32 mSpherePrimitiveCount;
-
//Debug rendering
static bool smRenderPreviewProbes;
@@ -188,6 +232,10 @@ public:
bool onAdd();
void onRemove();
+ ///
+ /// This is called when the object is deleted. It allows us to do special-case cleanup actions
+ /// In probes' case, it's used to delete baked cubemap files
+ ///
virtual void handleDeleteAction();
// Override this so that we can dirty the network flag when it is called
@@ -215,14 +263,26 @@ public:
//--------------------------------------------------------------------------
// Create the geometry for rendering
- void createGeometry();
+ void createEditorResources();
+ ///
+ /// Updates the probe rendering data
+ ///
virtual void updateProbeParams();
-
+
bool createClientResources();
+ ///
+ /// Updates the probe's cubemaps in the array when using dynamic reflections
+ ///
void processDynamicCubemap();
+ ///
+ /// Updates the probe's cubemaps in the array when using baked cubemaps
+ ///
void processBakedCubemap();
+ ///
+ /// Updates the probe's cubemaps in the array when using a static cubemaps
+ ///
void processStaticCubemap();
// This is the function that allows this object to submit itself for rendering
@@ -234,9 +294,22 @@ public:
void setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat);
- //Baking
+ ///
+ /// This gets the filepath to the prefilter cubemap associated to this probe.
+ /// In the event the probe is set to use a static cubemap, it is the prefiltered version of the cubemap's file
+ ///
+ /// The filepath to the prefilter cubemap
String getPrefilterMapPath();
+ ///
+ /// This gets the filepath to the irradiance cubemap associated to this probe.
+ /// In the event the probe is set to use a static cubemap, it is the irradiance version of the cubemap's file
+ ///
+ /// The filepath to the irradiance cubemap
String getIrradianceMapPath();
+
+ ///
+ /// Invokes a cubemap bake action for this probe
+ ///
void bake();
};
diff --git a/Engine/source/T3D/lighting/skylight.cpp b/Engine/source/T3D/lighting/skylight.cpp
index 6f816e976..36036100b 100644
--- a/Engine/source/T3D/lighting/skylight.cpp
+++ b/Engine/source/T3D/lighting/skylight.cpp
@@ -135,6 +135,11 @@ void Skylight::unpackUpdate(NetConnection *conn, BitStream *stream)
{
// Let the Parent read any info it sent
Parent::unpackUpdate(conn, stream);
+
+ if (mDirty)
+ {
+ updateProbeParams();
+ }
}
//-----------------------------------------------------------------------------
@@ -143,9 +148,6 @@ void Skylight::unpackUpdate(NetConnection *conn, BitStream *stream)
void Skylight::updateProbeParams()
{
- if (!mProbeInfo)
- return;
-
mProbeShapeType = ProbeRenderInst::Skylight;
Parent::updateProbeParams();
}
@@ -157,24 +159,17 @@ void Skylight::prepRenderImage(SceneRenderState *state)
//special hook-in for skylights
Point3F camPos = state->getCameraPosition();
- mProbeInfo->mBounds.setCenter(camPos);
+ mProbeInfo.mBounds.setCenter(camPos);
- mProbeInfo->setPosition(camPos);
-
- if (mReflectionModeType == DynamicCubemap && mRefreshRateMS < (Platform::getRealMilliseconds() - mDynamicLastBakeMS))
- {
- //bake();
- mDynamicLastBakeMS = Platform::getRealMilliseconds();
-
- processDynamicCubemap();
- }
+ mProbeInfo.setPosition(camPos);
//Submit our probe to actually do the probe action
// Get a handy pointer to our RenderPassmanager
//RenderPassManager *renderPass = state->getRenderPass();
- //PROBEMGR->registerSkylight(mProbeInfo, this);
+ PROBEMGR->submitProbe(mProbeInfo);
+#ifdef TORQUE_TOOLS
if (Skylight::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr)
{
GFXTransformSaver saver;
@@ -235,6 +230,7 @@ void Skylight::prepRenderImage(SceneRenderState *state)
if (isSelectedInEditor)
{
}
+#endif
}
void Skylight::setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat)
diff --git a/Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp b/Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp
index ed45f606f..54e97b19f 100644
--- a/Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp
+++ b/Engine/source/T3D/lighting/sphereEnvironmentProbe.cpp
@@ -131,6 +131,11 @@ void SphereEnvironmentProbe::unpackUpdate(NetConnection *conn, BitStream *stream
{
// Let the Parent read any info it sent
Parent::unpackUpdate(conn, stream);
+
+ if (mDirty)
+ {
+ updateProbeParams();
+ }
}
//-----------------------------------------------------------------------------
@@ -139,9 +144,6 @@ void SphereEnvironmentProbe::unpackUpdate(NetConnection *conn, BitStream *stream
void SphereEnvironmentProbe::updateProbeParams()
{
- if (!mProbeInfo)
- return;
-
mProbeShapeType = ProbeRenderInst::Sphere;
Parent::updateProbeParams();
}
@@ -151,6 +153,7 @@ void SphereEnvironmentProbe::prepRenderImage(SceneRenderState *state)
if (!mEnabled || !ReflectionProbe::smRenderPreviewProbes)
return;
+#ifdef TORQUE_TOOLS
if (ReflectionProbe::smRenderPreviewProbes && gEditingMission && mEditorShapeInst && mPrefilterMap != nullptr)
{
GFXTransformSaver saver;
@@ -215,6 +218,7 @@ void SphereEnvironmentProbe::prepRenderImage(SceneRenderState *state)
ri->type = RenderPassManager::RIT_Editor;
state->getRenderPass()->addInst(ri);
}
+#endif
}
void SphereEnvironmentProbe::setPreviewMatParameters(SceneRenderState* renderState, BaseMatInstance* mat)
diff --git a/Engine/source/console/simSet.h b/Engine/source/console/simSet.h
index ed062f7da..441180d18 100644
--- a/Engine/source/console/simSet.h
+++ b/Engine/source/console/simSet.h
@@ -332,7 +332,7 @@ void SimSet::findObjectByType( Vector &foundObjects )
curSet = dynamic_cast( *itr );
// If child object is a set, call recursively into it.
- if ( curSet )
+ if ( curSet && curSet->size() != 0)
curSet->findObjectByType( foundObjects );
// Add this child object if appropriate.
diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp
index b114da55a..621a5b79f 100644
--- a/Engine/source/renderInstance/renderProbeMgr.cpp
+++ b/Engine/source/renderInstance/renderProbeMgr.cpp
@@ -45,6 +45,8 @@
//For our cameraQuery setup
#include "T3D/gameTSCtrl.h"
+#include "T3D/Scene.h"
+
#define TORQUE_GFX_VISUAL_DEBUG //renderdoc debugging
IMPLEMENT_CONOBJECT(RenderProbeMgr);
@@ -59,6 +61,8 @@ ConsoleDocClass( RenderProbeMgr,
RenderProbeMgr *RenderProbeMgr::smProbeManager = NULL;
bool RenderProbeMgr::smRenderReflectionProbes = true;
+F32 RenderProbeMgr::smMaxProbeDrawDistance = 100;
+S32 RenderProbeMgr::smMaxProbesPerFrame = 8;
S32 QSORT_CALLBACK AscendingReflectProbeInfluence(const void* a, const void* b)
{
@@ -87,7 +91,6 @@ ProbeRenderInst::ProbeRenderInst() :
mProbeRefScale(1,1,1),
mAtten(0.0),
mCubemapIndex(0),
- mIsSkylight(false),
mProbeIdx(0),
mProbeShapeType(Box)
{
@@ -113,7 +116,6 @@ void ProbeRenderInst::set(const ProbeRenderInst *probeInfo)
mRadius = probeInfo->mRadius;
mProbeShapeType = probeInfo->mProbeShapeType;
mBounds = probeInfo->mBounds;
- mIsSkylight = probeInfo->mIsSkylight;
mScore = probeInfo->mScore;
mAtten = probeInfo->mAtten;
}
@@ -125,8 +127,7 @@ ProbeShaderConstants::ProbeShaderConstants()
mShader(NULL),
mProbePositionSC(NULL),
mProbeRefPosSC(NULL),
- mRefBoxMinSC(NULL),
- mRefBoxMaxSC(NULL),
+ mRefScaleSC(NULL),
mProbeConfigDataSC(NULL),
mProbeSpecularCubemapSC(NULL),
mProbeIrradianceCubemapSC(NULL),
@@ -160,8 +161,7 @@ void ProbeShaderConstants::init(GFXShader* shader)
//Reflection Probes
mProbePositionSC = shader->getShaderConstHandle(ShaderGenVars::probePosition);
mProbeRefPosSC = shader->getShaderConstHandle(ShaderGenVars::probeRefPos);
- mRefBoxMinSC = shader->getShaderConstHandle(ShaderGenVars::refBoxMin);
- mRefBoxMaxSC = shader->getShaderConstHandle(ShaderGenVars::refBoxMax);
+ mRefScaleSC = shader->getShaderConstHandle(ShaderGenVars::refScale);
mWorldToObjArraySC = shader->getShaderConstHandle(ShaderGenVars::worldToObjArray);
mProbeConfigDataSC = shader->getShaderConstHandle(ShaderGenVars::probeConfigData);
mProbeSpecularCubemapSC = shader->getShaderConstHandle(ShaderGenVars::specularCubemapAR);
@@ -179,8 +179,7 @@ bool ProbeShaderConstants::isValid()
{
if (mProbePositionSC->isValid() ||
mProbeConfigDataSC->isValid() ||
- mRefBoxMinSC->isValid() ||
- mRefBoxMaxSC->isValid() ||
+ mRefScaleSC->isValid() ||
mProbeSpecularCubemapSC->isValid() ||
mProbeIrradianceCubemapSC->isValid())
return true;
@@ -204,8 +203,7 @@ RenderProbeMgr::RenderProbeMgr()
mHasSkylight(false),
mSkylightCubemapIdx(-1),
mCubeMapCount(0),
- mDefaultSkyLight(nullptr),
- mBakeRenderTarget(nullptr)
+ mDefaultSkyLight(nullptr)
{
mEffectiveProbeCount = 0;
mMipCount = 0;
@@ -221,6 +219,9 @@ RenderProbeMgr::RenderProbeMgr()
{
mCubeMapSlots[i] = false;
}
+
+ mPrefilterSize = 64;
+ mPrefilterMipLevels = mLog2(F32(mPrefilterSize)) + 1;
}
RenderProbeMgr::RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder)
@@ -236,6 +237,10 @@ RenderProbeMgr::RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 proce
mLastConstants = nullptr;
mMipCount = 0;
mProbesDirty = false;
+ mUseHDRCaptures = true;
+
+ mPrefilterSize = 64;
+ mPrefilterMipLevels = mLog2(F32(mPrefilterSize)) + 1;
}
RenderProbeMgr::~RenderProbeMgr()
@@ -303,35 +308,22 @@ void RenderProbeMgr::initPersistFields()
Parent::initPersistFields();
}
-void RenderProbeMgr::addElement(RenderInst *inst)
+void RenderProbeMgr::consoleInit()
{
- // If this instance is translucent handle it in RenderTranslucentMgr
- //if (inst->translucentSort)
- return;
+ Parent::consoleInit();
- //AssertFatal(inst->defaultKey != 0, "RenderMeshMgr::addElement() - Got null sort key... did you forget to set it?");
-
- /*internalAddElement(inst);
-
- ProbeRenderInst* probeInst = static_cast(inst);
-
- if (probeInst->mIsSkylight)
- {
- addSkylightProbe(probeInst);
- }
- else
- {
- if (probeInst->mProbeShapeType == ProbeInfo::Sphere)
- addSphereReflectionProbe(probeInst);
- else
- addConvexReflectionProbe(probeInst);
- }*/
+ // Vars for debug rendering while the RoadEditor is open, only used if smEditorOpen is true.
+ Con::addVariable("$pref::maxProbeDrawDistance", TypeF32, &RenderProbeMgr::smMaxProbeDrawDistance, "Max distance for reflection probes to render.\n");
+ Con::addVariable("$pref::MaxProbesPerFrame", TypeS32, &RenderProbeMgr::smMaxProbesPerFrame, "Max number of Environment Probes that can be rendered per-frame.\n");
}
-ProbeRenderInst* RenderProbeMgr::registerProbe()
+void RenderProbeMgr::registerProbe(ProbeRenderInst* newProbe)
{
- mRegisteredProbes.increment();
- ProbeRenderInst* newProbe = &mRegisteredProbes.last();
+ //Can't have over the probe limit
+ if (mRegisteredProbes.size() + 1 >= PROBE_MAX_COUNT)
+ return;
+
+ mRegisteredProbes.push_back(newProbe);
newProbe->mProbeIdx = mRegisteredProbes.size() - 1;
@@ -339,7 +331,7 @@ ProbeRenderInst* RenderProbeMgr::registerProbe()
if (cubeIndex == INVALID_CUBE_SLOT)
{
Con::warnf("RenderProbeMgr::addProbe: Invalid cubemap slot.");
- return nullptr;
+ return;
}
//check if we need to resize the cubemap array
@@ -372,8 +364,6 @@ ProbeRenderInst* RenderProbeMgr::registerProbe()
#endif
mProbesDirty = true;
-
- return newProbe;
}
void RenderProbeMgr::unregisterProbe(U32 probeIdx)
@@ -382,11 +372,11 @@ void RenderProbeMgr::unregisterProbe(U32 probeIdx)
if (probeIdx >= mRegisteredProbes.size())
return;
- if (mRegisteredProbes[probeIdx].mCubemapIndex == INVALID_CUBE_SLOT)
+ if (mRegisteredProbes[probeIdx]->mCubemapIndex == INVALID_CUBE_SLOT)
return;
//mark cubemap slot as available now
- mCubeMapSlots[mRegisteredProbes[probeIdx].mCubemapIndex] = false;
+ mCubeMapSlots[mRegisteredProbes[probeIdx]->mCubemapIndex] = false;
mCubeMapCount--;
mRegisteredProbes.erase(probeIdx);
@@ -394,13 +384,18 @@ void RenderProbeMgr::unregisterProbe(U32 probeIdx)
//recalculate all the probe's indicies just to be sure
for (U32 i = 0; i < mRegisteredProbes.size(); i++)
{
- mRegisteredProbes[i].mProbeIdx = i;
+ mRegisteredProbes[i]->mProbeIdx = i;
}
//rebuild our probe data
mProbesDirty = true;
}
+void RenderProbeMgr::submitProbe(const ProbeRenderInst& newProbe)
+{
+ mActiveProbes.push_back(newProbe);
+}
+
//
//
PostEffect* RenderProbeMgr::getProbeArrayEffect()
@@ -425,75 +420,6 @@ void RenderProbeMgr::updateProbes()
mProbesDirty = true;
}
-void RenderProbeMgr::_setupStaticParameters()
-{
- //Array rendering
- U32 probeCount = mRegisteredProbes.size();
-
- mEffectiveProbeCount = 0;
- mMipCount = 1;
-
- mHasSkylight = false;
- mSkylightCubemapIdx = -1;
-
- if (probePositionsData.size() != MAXPROBECOUNT)
- {
- probePositionsData.setSize(MAXPROBECOUNT);
- probeRefPositionsData.setSize(MAXPROBECOUNT);
- probeWorldToObjData.setSize(MAXPROBECOUNT);
- refBoxMinData.setSize(MAXPROBECOUNT);
- refBoxMaxData.setSize(MAXPROBECOUNT);
- probeConfigData.setSize(MAXPROBECOUNT);
- }
-
- probePositionsData.fill(Point4F::Zero);
- probeRefPositionsData.fill(Point4F::Zero);
- probeWorldToObjData.fill(MatrixF::Identity);
- refBoxMinData.fill(Point4F::Zero);
- refBoxMaxData.fill(Point4F::Zero);
- probeConfigData.fill(Point4F(-1,0,0,0));
-
- for (U32 i = 0; i < probeCount; i++)
- {
- if (mEffectiveProbeCount >= MAXPROBECOUNT)
- break;
-
- const ProbeRenderInst& curEntry = mRegisteredProbes[i];
- if (!curEntry.mIsEnabled)
- continue;
-
- U32 mips = mRegisteredProbes[i].mPrefilterCubemap.getPointer()->getMipMapLevels();
- mMipCount = (mips != 0 && mips >= mMipCount) ? mips : 0;
-
- if (curEntry.mIsSkylight)
- {
- mSkylightCubemapIdx = curEntry.mCubemapIndex;
- continue;
- }
-
- //Setup
- Point3F probePos = curEntry.getPosition();
- Point3F refPos = curEntry.getPosition() +curEntry.mProbeRefOffset;
- probePositionsData[mEffectiveProbeCount] = Point4F(probePos.x, probePos.y, probePos.z,0);
- probeRefPositionsData[mEffectiveProbeCount] = Point4F(refPos.x, refPos.y, refPos.z, 0);
-
- probeWorldToObjData[mEffectiveProbeCount] = curEntry.getTransform();
- Point3F bbMin = refPos - curEntry.mProbeRefScale/2 * curEntry.getTransform().getScale();
- Point3F bbMax = refPos + curEntry.mProbeRefScale/2 * curEntry.getTransform().getScale();
- refBoxMinData[mEffectiveProbeCount] = Point4F(bbMin.x, bbMin.y, bbMin.z, 0);
- refBoxMaxData[mEffectiveProbeCount] = Point4F(bbMax.x, bbMax.y, bbMax.z, 0);
-
- probeConfigData[mEffectiveProbeCount] = Point4F(curEntry.mProbeShapeType,
- curEntry.mRadius,
- curEntry.mAtten,
- curEntry.mCubemapIndex);
-
- mEffectiveProbeCount++;
- }
-
- mProbesDirty = false;
-}
-
void RenderProbeMgr::updateProbeTexture(ProbeRenderInst* probeInfo)
{
if (probeInfo->mIrradianceCubemap.isNull() || !probeInfo->mIrradianceCubemap->isInitialized())
@@ -523,7 +449,7 @@ void RenderProbeMgr::reloadTextures()
U32 probeCount = mRegisteredProbes.size();
for (U32 i = 0; i < probeCount; i++)
{
- updateProbeTexture(&mRegisteredProbes[i]);
+ updateProbeTexture(mRegisteredProbes[i]);
}
mProbesDirty = true;
@@ -532,6 +458,10 @@ void RenderProbeMgr::reloadTextures()
void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state)
{
PROFILE_SCOPE(RenderProbeMgr_SetupPerFrameParameters);
+
+ mProbeData = ProbeDataSet(smMaxProbesPerFrame);
+
+ getBestProbes(state->getCameraPosition(), &mProbeData);
}
ProbeShaderConstants* RenderProbeMgr::getProbeShaderConstants(GFXShaderConstBuffer* buffer)
@@ -579,6 +509,12 @@ ProbeShaderConstants* RenderProbeMgr::getProbeShaderConstants(GFXShaderConstBuff
return mLastConstants;
}
+void RenderProbeMgr::setupSGData(SceneData& data, const SceneRenderState* state, LightInfo* light)
+{
+ //ensure they're sorted for forward rendering
+ mActiveProbes.sort(_probeScoreCmp);
+}
+
void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
MatrixSet &matSet,
ProbeShaderConstants *probeShaderConsts,
@@ -586,10 +522,8 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
{
PROFILE_SCOPE(ProbeManager_Update4ProbeConsts);
- return;
-
// Skip over gathering lights if we don't have to!
- //if (probeShaderConsts->isValid())
+ if (probeShaderConsts->isValid())
{
PROFILE_SCOPE(ProbeManager_Update4ProbeConsts_setProbes);
@@ -600,17 +534,29 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
getBestProbes(sgData.objTrans->getPosition(), &probeSet);
+ static AlignedArray probePositionAlignedArray(probeSet.maxProbeCount, sizeof(Point4F));
+ static AlignedArray refScaleAlignedArray(probeSet.maxProbeCount, sizeof(Point4F));
+ static AlignedArray probeRefPositionAlignedArray(probeSet.maxProbeCount, sizeof(Point4F));
+ static AlignedArray probeConfigAlignedArray(probeSet.maxProbeCount, sizeof(Point4F));
+
+ for (U32 i = 0; i < probeSet.maxProbeCount; i++)
+ {
+ probePositionAlignedArray[i] = probeSet.probePositionArray[i];
+ probeRefPositionAlignedArray[i] = probeSet.probeRefPositionArray[i];
+ refScaleAlignedArray[i] = probeSet.refScaleArray[i];
+ probeConfigAlignedArray[i] = probeSet.probeConfigArray[i];
+ }
+
shaderConsts->setSafe(probeShaderConsts->mProbeCountSC, (S32)probeSet.effectiveProbeCount);
- shaderConsts->setSafe(probeShaderConsts->mProbePositionSC, probeSet.probePositionArray);
- shaderConsts->setSafe(probeShaderConsts->mProbeRefPosSC, probeSet.probeRefPositionArray);
+ shaderConsts->setSafe(probeShaderConsts->mProbePositionSC, probePositionAlignedArray);
+ shaderConsts->setSafe(probeShaderConsts->mProbeRefPosSC, probeRefPositionAlignedArray);
if(probeShaderConsts->isValid())
shaderConsts->set(probeShaderConsts->mWorldToObjArraySC, probeSet.probeWorldToObjArray.address(), probeSet.effectiveProbeCount, GFXSCT_Float4x4);
- shaderConsts->setSafe(probeShaderConsts->mRefBoxMinSC, probeSet.refBoxMinArray);
- shaderConsts->setSafe(probeShaderConsts->mRefBoxMaxSC, probeSet.refBoxMaxArray);
- shaderConsts->setSafe(probeShaderConsts->mProbeConfigDataSC, probeSet.probeConfigArray);
+ shaderConsts->setSafe(probeShaderConsts->mRefScaleSC, refScaleAlignedArray);
+ shaderConsts->setSafe(probeShaderConsts->mProbeConfigDataSC, probeConfigAlignedArray);
shaderConsts->setSafe(probeShaderConsts->mSkylightCubemapIdxSC, (float)probeSet.skyLightIdx);
@@ -624,81 +570,71 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
}
}
+S32 QSORT_CALLBACK RenderProbeMgr::_probeScoreCmp(const ProbeRenderInst* a, const ProbeRenderInst* b)
+{
+ F32 diff = a->getScore() - b->getScore();
+ return diff > 0 ? 1 : diff < 0 ? -1 : 0;
+}
+
void RenderProbeMgr::getBestProbes(const Point3F& objPosition, ProbeDataSet* probeDataSet)
{
PROFILE_SCOPE(ProbeManager_getBestProbes);
- // Skip over gathering lights if we don't have to!
- //if (probeShaderConsts->isValid())
+ //Array rendering
+ U32 probeCount = mActiveProbes.size();
+
+ Vector bestPickProbes;
+ bestPickProbes.setSize(probeDataSet->maxProbeCount);
+ bestPickProbes.fill(-1);
+
+ probeDataSet->effectiveProbeCount = 0;
+ for (U32 i = 0; i < probeCount; i++)
{
- //Array rendering
- U32 probeCount = mRegisteredProbes.size();
+ if (probeDataSet->skyLightIdx != -1 && probeDataSet->effectiveProbeCount >= probeDataSet->maxProbeCount)
+ break;
- Vector bestPickProbes;
+ const ProbeRenderInst& curEntry = mActiveProbes[i];
+ if (!curEntry.mIsEnabled)
+ continue;
- probeDataSet->effectiveProbeCount = 0;
- for (U32 i = 0; i < probeCount; i++)
+ if (curEntry.mProbeShapeType != ProbeRenderInst::Skylight)
{
- const ProbeRenderInst& curEntry = mRegisteredProbes[i];
- if (!curEntry.mIsEnabled)
- continue;
-
- if (!curEntry.mIsSkylight)
+ if (probeDataSet->effectiveProbeCount < probeDataSet->maxProbeCount)
{
- F32 dist = Point3F(objPosition - curEntry.getPosition()).len();
-
- if (dist > curEntry.mRadius || dist > curEntry.mExtents.len())
- continue;
-
- S32 bestPickIndex = -1;
- for (U32 p = 0; p < bestPickProbes.size(); p++)
- {
- if (p > probeDataSet->MAX_PROBE_COUNT)
- break;
-
- if (bestPickProbes[p] == -1 || (Point3F(objPosition - mRegisteredProbes[bestPickProbes[p]].mPosition).len() > dist))
- bestPickIndex = p;
- }
-
- //Can't have over our max count. Otherwise, if we haven't found a good slot for our best pick, insert it
- //if we have a best pick slot, update it
- if (bestPickIndex == -1 || bestPickProbes.size() >= probeDataSet->MAX_PROBE_COUNT)
- bestPickProbes.push_back(i);
- else
- bestPickProbes[bestPickIndex] = i;
- }
- else
- {
- probeDataSet->skyLightIdx = curEntry.mCubemapIndex;
+ bestPickProbes[probeDataSet->effectiveProbeCount] = i;
+ probeDataSet->effectiveProbeCount++;
}
}
-
- //Grab our best probe picks
- for (U32 i = 0; i < bestPickProbes.size(); i++)
+ else
{
- if (bestPickProbes[i] == -1)
- continue;
-
- const ProbeRenderInst& curEntry = mRegisteredProbes[bestPickProbes[i]];
-
- probeDataSet->probePositionArray[probeDataSet->effectiveProbeCount] = curEntry.getPosition();
- probeDataSet->probeRefPositionArray[probeDataSet->effectiveProbeCount] = curEntry.mProbeRefOffset;
- probeDataSet->probeWorldToObjArray[probeDataSet->effectiveProbeCount] = curEntry.getTransform();
-
- Point3F refPos = curEntry.getPosition() + curEntry.mProbeRefOffset;
- Point3F refBoxMin = refPos - curEntry.mProbeRefScale * curEntry.getTransform().getScale();
- Point3F refBoxMax = refPos + curEntry.mProbeRefScale * curEntry.getTransform().getScale();
-
- probeDataSet->refBoxMinArray[probeDataSet->effectiveProbeCount] = Point4F(refBoxMin.x, refBoxMin.y, refBoxMin.z, 0);
- probeDataSet->refBoxMaxArray[probeDataSet->effectiveProbeCount] = Point4F(refBoxMax.x, refBoxMax.y, refBoxMax.z, 0);
- probeDataSet->probeConfigArray[probeDataSet->effectiveProbeCount] = Point4F(curEntry.mProbeShapeType,
- curEntry.mRadius,
- curEntry.mAtten,
- curEntry.mCubemapIndex);
-
- probeDataSet->effectiveProbeCount++;
+ probeDataSet->skyLightIdx = curEntry.mCubemapIndex;
}
}
+
+ //Grab our best probe picks
+ for (U32 i = 0; i < bestPickProbes.size(); i++)
+ {
+ if (bestPickProbes[i] == -1)
+ continue;
+
+ const ProbeRenderInst& curEntry = mActiveProbes[bestPickProbes[i]];
+
+ MatrixF p2A = curEntry.getTransform();
+ p2A.inverse();
+ probeDataSet->refScaleArray[i] = curEntry.mProbeRefScale / p2A.getScale();
+
+ Point3F probePos = curEntry.getPosition();
+ Point3F refPos = probePos + curEntry.mProbeRefOffset * probeDataSet->refScaleArray[i].asPoint3F();
+ probeDataSet->probeWorldToObjArray[i] = curEntry.getTransform();
+
+ probeDataSet->probePositionArray[i] = Point4F(probePos.x, probePos.y, probePos.z, 0);
+ probeDataSet->probeRefPositionArray[i] = Point4F(refPos.x, refPos.y, refPos.z, 0);
+
+ probeDataSet->probeConfigArray[i] = Point4F(curEntry.mProbeShapeType,
+ curEntry.mRadius,
+ curEntry.mAtten,
+ curEntry.mCubemapIndex);
+ }
}
void RenderProbeMgr::getProbeTextureData(ProbeTextureArrayData* probeTextureSet)
@@ -720,9 +656,6 @@ void RenderProbeMgr::setProbeInfo(ProcessedMaterial *pmat,
if (sgData.binType == SceneData::DeferredBin)
return;
- // if (mRegisteredProbes.empty())
- // return;
-
PROFILE_SCOPE(ProbeManager_setProbeInfo);
ProbeShaderConstants *psc = getProbeShaderConstants(shaderConsts);
@@ -747,26 +680,29 @@ void RenderProbeMgr::setProbeInfo(ProcessedMaterial *pmat,
void RenderProbeMgr::render( SceneRenderState *state )
{
if (getProbeArrayEffect() == nullptr)
+ {
+ mActiveProbes.clear();
return;
+ }
- if (mProbesDirty)
- _setupStaticParameters();
+ GFXDEBUGEVENT_SCOPE(RenderProbeMgr_render, ColorI::WHITE);
+
+ //Sort the active probes
+ mActiveProbes.sort(_probeScoreCmp);
+
+ // Initialize and set the per-frame data
+ _setupPerFrameParameters(state);
// Early out if nothing to draw.
- if (!RenderProbeMgr::smRenderReflectionProbes || (!state->isDiffusePass() && !state->isReflectPass()) || (mEffectiveProbeCount == 0 && mSkylightCubemapIdx == -1))
+ if (!RenderProbeMgr::smRenderReflectionProbes || (!state->isDiffusePass() && !state->isReflectPass()) || (mProbeData.effectiveProbeCount == 0 && mProbeData.skyLightIdx == -1))
{
getProbeArrayEffect()->setSkip(true);
+ mActiveProbes.clear();
return;
}
GFXTransformSaver saver;
- GFXDEBUGEVENT_SCOPE(RenderProbeMgr_render, ColorI::WHITE);
-
- // Initialize and set the per-frame parameters after getting
- // the vector light material as we use lazy creation.
- //_setupPerFrameParameters(state);
-
//Visualization
String useDebugAtten = Con::getVariable("$Probes::showAttenuation", "0");
mProbeArrayEffect->setShaderMacro("DEBUGVIZ_ATTENUATION", useDebugAtten);
@@ -780,11 +716,14 @@ void RenderProbeMgr::render( SceneRenderState *state )
String useDebugContrib = Con::getVariable("$Probes::showProbeContrib", "0");
mProbeArrayEffect->setShaderMacro("DEBUGVIZ_CONTRIB", useDebugContrib);
- if(mSkylightCubemapIdx != -1 && mEffectiveProbeCount == 0)
+ if(mProbeData.skyLightIdx != -1 && mProbeData.effectiveProbeCount == 0)
mProbeArrayEffect->setShaderMacro("SKYLIGHT_ONLY", "1");
else
mProbeArrayEffect->setShaderMacro("SKYLIGHT_ONLY", "0");
+ String probePerFrame = Con::getVariable("$pref::MaxProbesPerFrame", "8");
+ mProbeArrayEffect->setShaderMacro("MAX_PROBES", probePerFrame);
+
//ssao mask
if (AdvancedLightBinManager::smUseSSAOMask)
{
@@ -795,7 +734,6 @@ void RenderProbeMgr::render( SceneRenderState *state )
{
mProbeArrayEffect->setShaderMacro("USE_SSAO_MASK");
mProbeArrayEffect->setTexture(6, pTexObj);
-
}
}
else
@@ -807,24 +745,24 @@ void RenderProbeMgr::render( SceneRenderState *state )
mProbeArrayEffect->setCubemapArrayTexture(4, mPrefilterArray);
mProbeArrayEffect->setCubemapArrayTexture(5, mIrradianceArray);
- mProbeArrayEffect->setShaderConst("$numProbes", (S32)mEffectiveProbeCount);
- mProbeArrayEffect->setShaderConst("$skylightCubemapIdx", (S32)mSkylightCubemapIdx);
+ mProbeArrayEffect->setShaderConst("$numProbes", (S32)mProbeData.effectiveProbeCount);
+ mProbeArrayEffect->setShaderConst("$skylightCubemapIdx", (S32)mProbeData.skyLightIdx);
mProbeArrayEffect->setShaderConst("$cubeMips", (float)mMipCount);
//also set up some colors
Vector contribColors;
- contribColors.setSize(MAXPROBECOUNT);
+ contribColors.setSize(mProbeData.effectiveProbeCount);
- if (mEffectiveProbeCount != 0)
+ if (mProbeData.effectiveProbeCount != 0)
{
if (useDebugContrib == String("1"))
{
MRandomLCG RandomGen;
- RandomGen.setSeed(mEffectiveProbeCount);
+ RandomGen.setSeed(mProbeData.effectiveProbeCount);
- for (U32 i = 0; i < mEffectiveProbeCount; i++)
+ for (U32 i = 0; i < mProbeData.effectiveProbeCount; i++)
{
//we're going to cheat here a little for consistent debugging behavior. The first 3 probes will always have R G and then B for their colors, every other will be random
if (i == 0)
@@ -841,20 +779,19 @@ void RenderProbeMgr::render( SceneRenderState *state )
mProbeArrayEffect->setShaderConst("$probeContribColors", contribColors);
- mProbeArrayEffect->setShaderConst("$inProbePosArray", probePositionsData);
- mProbeArrayEffect->setShaderConst("$inRefPosArray", probeRefPositionsData);
- mProbeArrayEffect->setShaderConst("$worldToObjArray", probeWorldToObjData);
- mProbeArrayEffect->setShaderConst("$refBoxMinArray", refBoxMinData);
- mProbeArrayEffect->setShaderConst("$refBoxMaxArray", refBoxMaxData);
- mProbeArrayEffect->setShaderConst("$probeConfigData", probeConfigData);
+ mProbeArrayEffect->setShaderConst("$inProbePosArray", mProbeData.probePositionArray);
+ mProbeArrayEffect->setShaderConst("$inRefPosArray", mProbeData.probeRefPositionArray);
+ mProbeArrayEffect->setShaderConst("$worldToObjArray", mProbeData.probeWorldToObjArray);
+ mProbeArrayEffect->setShaderConst("$refScaleArray", mProbeData.refScaleArray);
+ mProbeArrayEffect->setShaderConst("$probeConfigData", mProbeData.probeConfigArray);
// Make sure the effect is gonna render.
getProbeArrayEffect()->setSkip(false);
- //PROFILE_END();
+ mActiveProbes.clear();
}
-void RenderProbeMgr::bakeProbe(ReflectionProbe* probe, bool writeFiles)
+void RenderProbeMgr::bakeProbe(ReflectionProbe *probe)
{
GFXDEBUGEVENT_SCOPE(RenderProbeMgr_Bake, ColorI::WHITE);
@@ -863,15 +800,15 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe, bool writeFiles)
String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/");
U32 resolution = Con::getIntVariable("$pref::ReflectionProbes::BakeResolution", 64);
- U32 prefilterMipLevels = mLog2(F32(resolution))+1;
+ U32 prefilterMipLevels = mLog2(F32(resolution)) + 1;
bool renderWithProbes = Con::getIntVariable("$pref::ReflectionProbes::RenderWithProbes", false);
ReflectionProbe* clientProbe = nullptr;
- if (probe->isClientObject())
- clientProbe = probe;
- else
+ if (probe->isServerObject())
clientProbe = static_cast(probe->getClientObject());
+ else
+ return;
if (clientProbe == nullptr)
return;
@@ -901,7 +838,7 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe, bool writeFiles)
reflDesc.texSize = resolution;
reflDesc.farDist = farPlane;
reflDesc.detailAdjust = 1;
- reflDesc.objectTypeMask = probe->mCaptureMask;
+ reflDesc.objectTypeMask = probe->mProbeShapeType == ProbeRenderInst::ProbeShapeType::Skylight ? SKYLIGHT_CAPTURE_TYPEMASK : REFLECTION_PROBE_CAPTURE_TYPEMASK;
CubeReflector cubeRefl;
cubeRefl.registerReflector(probe, &reflDesc);
@@ -939,13 +876,16 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe, bool writeFiles)
GFXFormat reflectFormat;
- if (clientProbe->mUseHDRCaptures)
+ if (mUseHDRCaptures)
reflectFormat = GFXFormatR16G16B16A16F;
else
reflectFormat = GFXFormatR8G8B8A8;
const GFXFormat oldRefFmt = REFLECTMGR->getReflectFormat();
REFLECTMGR->setReflectFormat(reflectFormat);
- cubeRefl.updateReflection(reflParams);
+
+ mProbeArrayEffect->setShaderConst("$CAPTURING", true);
+ cubeRefl.updateReflection(reflParams, clientProbe->getTransform().getPosition()+clientProbe->mProbeRefOffset);
+ mProbeArrayEffect->setShaderConst("$CAPTURING", false);
//Now, save out the maps
//create irridiance cubemap
@@ -958,34 +898,24 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe, bool writeFiles)
clientProbe->mIrridianceMap->mCubemap->initDynamic(resolution, reflectFormat);
clientProbe->mPrefilterMap->mCubemap->initDynamic(resolution, reflectFormat);
- if (mBakeRenderTarget == nullptr)
- mBakeRenderTarget = GFX->allocRenderToTextureTarget(false);
- else
- mBakeRenderTarget->resurrect();
+ GFXTextureTargetRef renderTarget = GFX->allocRenderToTextureTarget(false);
- IBLUtilities::GenerateIrradianceMap(mBakeRenderTarget, cubeRefl.getCubemap(), clientProbe->mIrridianceMap->mCubemap);
- IBLUtilities::GeneratePrefilterMap(mBakeRenderTarget, cubeRefl.getCubemap(), prefilterMipLevels, clientProbe->mPrefilterMap->mCubemap);
+ IBLUtilities::GenerateIrradianceMap(renderTarget, cubeRefl.getCubemap(), clientProbe->mIrridianceMap->mCubemap);
+ IBLUtilities::GeneratePrefilterMap(renderTarget, cubeRefl.getCubemap(), prefilterMipLevels, clientProbe->mPrefilterMap->mCubemap);
U32 endMSTime = Platform::getRealMilliseconds();
F32 diffTime = F32(endMSTime - startMSTime);
Con::warnf("RenderProbeMgr::bake() - Finished Capture! Took %g milliseconds", diffTime);
+ Con::warnf("RenderProbeMgr::bake() - Beginning save now!");
- if (writeFiles)
- {
- Con::warnf("RenderProbeMgr::bake() - Beginning save now!");
-
- IBLUtilities::SaveCubeMap(clientProbe->getIrradianceMapPath(), clientProbe->mIrridianceMap->mCubemap);
- IBLUtilities::SaveCubeMap(clientProbe->getPrefilterMapPath(), clientProbe->mPrefilterMap->mCubemap);
- }
-
- mBakeRenderTarget->zombify();
+ IBLUtilities::SaveCubeMap(clientProbe->getIrradianceMapPath(), clientProbe->mIrridianceMap->mCubemap);
+ IBLUtilities::SaveCubeMap(clientProbe->getPrefilterMapPath(), clientProbe->mPrefilterMap->mCubemap);
}
else
{
Con::errorf("RenderProbeMgr::bake() - Didn't generate a valid scene capture cubemap, unable to generate prefilter and irradiance maps!");
}
-
if (!renderWithProbes)
RenderProbeMgr::smRenderReflectionProbes = probeRenderState;
@@ -1002,12 +932,27 @@ void RenderProbeMgr::bakeProbe(ReflectionProbe* probe, bool writeFiles)
void RenderProbeMgr::bakeProbes()
{
- //TODO: make this just find every probe in the current missionGroup and run the bake on it automagically
+ Vector probes;
+
+ Scene::getRootScene()->findObjectByType(probes);
+
+ for (U32 i = 0; i < probes.size(); i++)
+ {
+ if (probes[i]->isClientObject())
+ continue;
+
+ bakeProbe(probes[i]);
+ }
}
DefineEngineMethod(RenderProbeMgr, bakeProbe, void, (ReflectionProbe* probe), (nullAsType< ReflectionProbe*>()),
- "@brief returns true if control object is inside the fog\n\n.")
+ "@brief Bakes the cubemaps for a reflection probe\n\n.")
{
if(probe != nullptr)
object->bakeProbe(probe);
}
+
+DefineEngineMethod(RenderProbeMgr, bakeProbes, void, (),, "@brief Iterates over all reflection probes in the scene and bakes their cubemaps\n\n.")
+{
+ object->bakeProbes();
+}
diff --git a/Engine/source/renderInstance/renderProbeMgr.h b/Engine/source/renderInstance/renderProbeMgr.h
index 29673e20b..c9dbd69bd 100644
--- a/Engine/source/renderInstance/renderProbeMgr.h
+++ b/Engine/source/renderInstance/renderProbeMgr.h
@@ -85,8 +85,6 @@ struct ProbeRenderInst
/// when prioritizing lights for rendering.
F32 mScore;
- bool mIsSkylight;
-
enum ProbeShapeType
{
Box = 0, ///< Sphere shaped
@@ -115,9 +113,6 @@ public:
Point3F getPosition() const { return mPosition; }
void setPosition(const Point3F &pos) { mPosition = pos; }
- VectorF getDirection() const { return mTransform.getForwardVector(); }
- void setDirection(const VectorF &val);
-
void setPriority(F32 priority) { mPriority = priority; }
F32 getPriority() const { return mPriority; }
@@ -141,8 +136,7 @@ struct ProbeShaderConstants
//Reflection Probes
GFXShaderConstHandle *mProbePositionSC;
GFXShaderConstHandle *mProbeRefPosSC;
- GFXShaderConstHandle *mRefBoxMinSC;
- GFXShaderConstHandle *mRefBoxMaxSC;
+ GFXShaderConstHandle *mRefScaleSC;
GFXShaderConstHandle *mWorldToObjArraySC;
GFXShaderConstHandle *mProbeConfigDataSC;
GFXShaderConstHandle *mProbeSpecularCubemapSC;
@@ -167,39 +161,43 @@ typedef Map ProbeConstantMap;
struct ProbeDataSet
{
- AlignedArray probePositionArray;
- AlignedArray refBoxMinArray;
- AlignedArray refBoxMaxArray;
- AlignedArray probeRefPositionArray;
- AlignedArray probeConfigArray;
+ Vector probePositionArray;
+ Vector refScaleArray;
+ Vector probeRefPositionArray;
+ Vector probeConfigArray;
Vector probeWorldToObjArray;
S32 skyLightIdx;
U32 effectiveProbeCount;
+ U32 maxProbeCount;
- U32 MAX_PROBE_COUNT;
-
- ProbeDataSet(U32 maxProbeCount)
+ ProbeDataSet()
{
- MAX_PROBE_COUNT = maxProbeCount;
+ probePositionArray.setSize(0);
+ refScaleArray.setSize(0);
+ probeRefPositionArray.setSize(0);
+ probeConfigArray.setSize(0);
- probePositionArray = AlignedArray(maxProbeCount, sizeof(Point4F));
- refBoxMinArray = AlignedArray(maxProbeCount, sizeof(Point4F));
- refBoxMaxArray = AlignedArray(maxProbeCount, sizeof(Point4F));
- probeRefPositionArray = AlignedArray(maxProbeCount, sizeof(Point4F));
- probeConfigArray = AlignedArray(maxProbeCount, sizeof(Point4F));
+ probeWorldToObjArray.setSize(0);
+
+ skyLightIdx = -1;
+ effectiveProbeCount = 0;
+ maxProbeCount = 0;
+ }
+
+ ProbeDataSet(U32 _maxProbeCount)
+ {
+ maxProbeCount = _maxProbeCount;
+
+ probePositionArray.setSize(maxProbeCount);
+ refScaleArray.setSize(maxProbeCount);
+ probeRefPositionArray.setSize(maxProbeCount);
+ probeConfigArray.setSize(maxProbeCount);
probeWorldToObjArray.setSize(maxProbeCount);
- // Need to clear the buffers so that we don't leak
- // lights from previous passes or have NaNs.
- dMemset(probePositionArray.getBuffer(), 0, probePositionArray.getBufferSize());
- dMemset(refBoxMinArray.getBuffer(), 0, refBoxMinArray.getBufferSize());
- dMemset(refBoxMaxArray.getBuffer(), 0, refBoxMaxArray.getBufferSize());
- dMemset(probeRefPositionArray.getBuffer(), 0, probeRefPositionArray.getBufferSize());
- dMemset(probeConfigArray.getBuffer(), 0, probeConfigArray.getBufferSize());
skyLightIdx = -1;
effectiveProbeCount = 0;
}
@@ -219,10 +217,11 @@ class RenderProbeMgr : public RenderBinManager
{
typedef RenderBinManager Parent;
- Vector mRegisteredProbes;
+ Vector mRegisteredProbes;
bool mProbesDirty;
-
+
+ Vector mActiveProbes;
public:
//maximum number of allowed probes
static const U32 PROBE_MAX_COUNT = 250;
@@ -236,27 +235,17 @@ public:
static const GFXFormat PROBE_FORMAT = GFXFormatR16G16B16A16F;// GFXFormatR8G8B8A8;// when hdr fixed GFXFormatR16G16B16A16F; look into bc6h compression
static const U32 INVALID_CUBE_SLOT = U32_MAX;
+ static F32 smMaxProbeDrawDistance;
+ static S32 smMaxProbesPerFrame;
+
private:
//Array rendering
U32 mEffectiveProbeCount;
S32 mMipCount;
- Vector probePositionsData;
- Vector probeRefPositionsData;
- Vector probeWorldToObjData;
- Vector refBoxMinData;
- Vector refBoxMaxData;
- Vector probeConfigData;
bool mHasSkylight;
S32 mSkylightCubemapIdx;
- AlignedArray mProbePositions;
- AlignedArray mRefBoxMin;
- AlignedArray mRefBoxMax;
- AlignedArray mProbeUseSphereMode;
- AlignedArray mProbeRadius;
- AlignedArray mProbeAttenuation;
-
//number of cubemaps
U32 mCubeMapCount;
//number of cubemap slots allocated
@@ -280,8 +269,12 @@ private:
GFXTexHandle mBRDFTexture;
- GFXTextureTargetRef mBakeRenderTarget;
+ ProbeDataSet mProbeData;
+ ///Prevents us from saving out the cubemaps(for now) but allows us the full HDR range on the in-memory cubemap captures
+ bool mUseHDRCaptures;
+ U32 mPrefilterMipLevels;
+ U32 mPrefilterSize;
public:
RenderProbeMgr();
RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 processAddOrder);
@@ -291,6 +284,8 @@ public:
// ConsoleObject
static void initPersistFields();
+ static void consoleInit();
+
DECLARE_CONOBJECT(RenderProbeMgr);
protected:
@@ -306,7 +301,7 @@ protected:
void _setupStaticParameters();
void _setupPerFrameParameters(const SceneRenderState *state);
- virtual void addElement(RenderInst *inst);
+ virtual void addElement(RenderInst* inst) {};
virtual void render(SceneRenderState * state);
ProbeShaderConstants* getProbeShaderConstants(GFXShaderConstBuffer* buffer);
@@ -331,8 +326,11 @@ public:
/// Returns the active LM.
static inline RenderProbeMgr* getProbeManager();
- ProbeRenderInst* registerProbe();
+ void registerProbe(ProbeRenderInst* newProbe);
void unregisterProbe(U32 probeIdx);
+ void submitProbe(const ProbeRenderInst& newProbe);
+
+ static S32 QSORT_CALLBACK _probeScoreCmp(const ProbeRenderInst* a, const ProbeRenderInst* b);
virtual void setProbeInfo(ProcessedMaterial *pmat,
const Material *mat,
@@ -341,6 +339,8 @@ public:
U32 pass,
GFXShaderConstBuffer *shaderConsts);
+ void setupSGData(SceneData& data, const SceneRenderState* state, LightInfo* light);
+
void updateProbeTexture(ProbeRenderInst* probeInfo);
void reloadTextures();
@@ -348,7 +348,7 @@ public:
/// Debug rendering
static bool smRenderReflectionProbes;
- void bakeProbe(ReflectionProbe *probeInfo, bool writeFile = true);
+ void bakeProbe(ReflectionProbe *probeInfo);
void bakeProbes();
void getProbeTextureData(ProbeTextureArrayData* probeTextureSet);
diff --git a/Engine/source/scene/reflector.cpp b/Engine/source/scene/reflector.cpp
index 4f20ecbfc..8b52f4b03 100644
--- a/Engine/source/scene/reflector.cpp
+++ b/Engine/source/scene/reflector.cpp
@@ -295,7 +295,7 @@ void CubeReflector::unregisterReflector()
mEnabled = false;
}
-void CubeReflector::updateReflection( const ReflectParams ¶ms )
+void CubeReflector::updateReflection( const ReflectParams ¶ms, Point3F explicitPostion)
{
GFXDEBUGEVENT_SCOPE( CubeReflector_UpdateReflection, ColorI::WHITE );
@@ -336,7 +336,7 @@ void CubeReflector::updateReflection( const ReflectParams ¶ms )
for ( U32 i = 0; i < 6; i++ )
- updateFace( params, i );
+ updateFace( params, i, explicitPostion);
GFX->popActiveRenderTarget();
@@ -347,7 +347,7 @@ void CubeReflector::updateReflection( const ReflectParams ¶ms )
mLastTexSize = texDim;
}
-void CubeReflector::updateFace( const ReflectParams ¶ms, U32 faceidx )
+void CubeReflector::updateFace( const ReflectParams ¶ms, U32 faceidx, Point3F explicitPostion)
{
GFXDEBUGEVENT_SCOPE( CubeReflector_UpdateFace, ColorI::WHITE );
@@ -402,7 +402,15 @@ void CubeReflector::updateFace( const ReflectParams ¶ms, U32 faceidx )
matView.setColumn( 0, cross );
matView.setColumn( 1, vLookatPt );
matView.setColumn( 2, vUpVec );
- matView.setPosition( mObject->getPosition() );
+
+ if (explicitPostion == Point3F::Max)
+ {
+ matView.setPosition(mObject->getPosition());
+ }
+ else
+ {
+ matView.setPosition(explicitPostion);
+ }
matView.inverse();
GFX->setWorldMatrix(matView);
diff --git a/Engine/source/scene/reflector.h b/Engine/source/scene/reflector.h
index fd0f3e08c..4d87b69c1 100644
--- a/Engine/source/scene/reflector.h
+++ b/Engine/source/scene/reflector.h
@@ -151,11 +151,11 @@ public:
ReflectorDesc *inDesc );
virtual void unregisterReflector();
- virtual void updateReflection( const ReflectParams ¶ms );
+ virtual void updateReflection( const ReflectParams ¶ms, Point3F explicitPostion = Point3F::Max);
GFXCubemap* getCubemap() const { return mCubemap; }
- void updateFace( const ReflectParams ¶ms, U32 faceidx );
+ void updateFace( const ReflectParams ¶ms, U32 faceidx, Point3F explicitPostion = Point3F::Max);
F32 calcFaceScore( const ReflectParams ¶ms, U32 faceidx );
protected:
diff --git a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp
index 3ed5591dd..21755d80c 100644
--- a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp
+++ b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp
@@ -3004,15 +3004,10 @@ void ReflectionProbeFeatGLSL::processPix(Vector& componentList
inRefPosArray->uniform = true;
inRefPosArray->constSortPos = cspPotentialPrimitive;
- Var * refBoxMinArray = new Var("inRefBoxMin", "vec4");
- refBoxMinArray->arraySize = MAX_FORWARD_PROBES;
- refBoxMinArray->uniform = true;
- refBoxMinArray->constSortPos = cspPotentialPrimitive;
-
- Var * refBoxMaxArray = new Var("inRefBoxMax", "vec4");
- refBoxMaxArray->arraySize = MAX_FORWARD_PROBES;
- refBoxMaxArray->uniform = true;
- refBoxMaxArray->constSortPos = cspPotentialPrimitive;
+ Var * refScaleArray = new Var("inRefScale", "vec4");
+ refScaleArray->arraySize = MAX_FORWARD_PROBES;
+ refScaleArray->uniform = true;
+ refScaleArray->constSortPos = cspPotentialPrimitive;
Var * probeConfigData = new Var("probeConfigData", "vec4");
probeConfigData->arraySize = MAX_FORWARD_PROBES;
@@ -3053,11 +3048,11 @@ void ReflectionProbeFeatGLSL::processPix(Vector& componentList
Var *curColor = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget));
//Reflection vec
- String computeForwardProbes = String(" @.rgb = computeForwardProbes(@,@,@,@,@,@,@,@,@,\r\n\t\t");
+ String computeForwardProbes = String(" @.rgb = computeForwardProbes(@,@,@,@,@,@,@,@,\r\n\t\t");
computeForwardProbes += String("@,@,\r\n\t\t");
computeForwardProbes += String("@,@).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(), curColor, surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray,
skylightCubemapIdx, BRDFTexture,
irradianceCubemapAR, specularCubemapAR));
diff --git a/Engine/source/shaderGen/HLSL/debugVizFeatureHLSL.cpp b/Engine/source/shaderGen/HLSL/debugVizFeatureHLSL.cpp
index 0cc582427..38a339053 100644
--- a/Engine/source/shaderGen/HLSL/debugVizFeatureHLSL.cpp
+++ b/Engine/source/shaderGen/HLSL/debugVizFeatureHLSL.cpp
@@ -140,8 +140,7 @@ void DebugVizHLSL::processPix(Vector& componentList,
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* refScaleArray = (Var*)LangElement::find("inRefScale");
Var* probeConfigData = (Var*)LangElement::find("probeConfigData");
Var* worldToObjArray = (Var*)LangElement::find("worldToObjArray");
@@ -181,11 +180,11 @@ void DebugVizHLSL::processPix(Vector& componentList,
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");
+ 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,
+ meta->addStatement(new GenOp(computeForwardProbes.c_str(), ibl, surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray,
skylightCubemapIdx, BRDFTexture,
irradianceCubemapAR, specularCubemapAR,
showAttenVar, showContribVar, showSpecVar, showDiffVar));
diff --git a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp
index cd4fbd846..72252177a 100644
--- a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp
+++ b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp
@@ -3075,15 +3075,10 @@ void ReflectionProbeFeatHLSL::processPix(Vector &componentList
inRefPosArray->uniform = true;
inRefPosArray->constSortPos = cspPotentialPrimitive;
- Var * refBoxMinArray = new Var("inRefBoxMin", "float4");
- refBoxMinArray->arraySize = MAX_FORWARD_PROBES;
- refBoxMinArray->uniform = true;
- refBoxMinArray->constSortPos = cspPotentialPrimitive;
-
- Var * refBoxMaxArray = new Var("inRefBoxMax", "float4");
- refBoxMaxArray->arraySize = MAX_FORWARD_PROBES;
- refBoxMaxArray->uniform = true;
- refBoxMaxArray->constSortPos = cspPotentialPrimitive;
+ Var * refScaleArray = new Var("inRefScale", "float4");
+ refScaleArray->arraySize = MAX_FORWARD_PROBES;
+ refScaleArray->uniform = true;
+ refScaleArray->constSortPos = cspPotentialPrimitive;
Var *probeConfigData = new Var("probeConfigData", "float4");
probeConfigData->arraySize = MAX_FORWARD_PROBES;
@@ -3142,11 +3137,11 @@ void ReflectionProbeFeatHLSL::processPix(Vector &componentList
ibl = new Var("ibl", "float3");
}
- String computeForwardProbes = String::String(" @ = computeForwardProbes(@,@,@,@,@,@,@,@,@,\r\n\t\t");
+ 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(), new DecOp(ibl), 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, refScaleArray, inRefPosArray,
skylightCubemapIdx, BRDFTexture,
irradianceCubemapAR, specularCubemapAR));
diff --git a/Engine/source/shaderGen/shaderGenVars.cpp b/Engine/source/shaderGen/shaderGenVars.cpp
index 9ed8db43f..45d1fe7f2 100644
--- a/Engine/source/shaderGen/shaderGenVars.cpp
+++ b/Engine/source/shaderGen/shaderGenVars.cpp
@@ -81,8 +81,7 @@ const String ShaderGenVars::glowMul("$glowMul");
//Reflection Probes
const String ShaderGenVars::probePosition("$inProbePosArray");
const String ShaderGenVars::probeRefPos("$inRefPosArray");
-const String ShaderGenVars::refBoxMin("$inRefBoxMin");
-const String ShaderGenVars::refBoxMax("$inRefBoxMax");
+const String ShaderGenVars::refScale("$inRefScale");
const String ShaderGenVars::worldToObjArray("$worldToObjArray");
const String ShaderGenVars::probeConfigData("$probeConfigData");
const String ShaderGenVars::specularCubemapAR("$specularCubemapAR");
diff --git a/Engine/source/shaderGen/shaderGenVars.h b/Engine/source/shaderGen/shaderGenVars.h
index db32af16c..6c32d4522 100644
--- a/Engine/source/shaderGen/shaderGenVars.h
+++ b/Engine/source/shaderGen/shaderGenVars.h
@@ -93,8 +93,7 @@ struct ShaderGenVars
//Reflection Probes
const static String probePosition;
const static String probeRefPos;
- const static String refBoxMin;
- const static String refBoxMax;
+ const static String refScale;
const static String worldToObjArray;
const static String probeConfigData;
const static String specularCubemapAR;
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl
index c5a8ae295..2fc447a95 100644
--- a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl
@@ -44,7 +44,10 @@ uniform vec4 albedo;
#endif // !TORQUE_SHADERGEN
-#define MAX_PROBES 50
+#ifndef MAX_PROBES
+#define MAX_PROBES 8
+#endif
+
#define MAX_FORWARD_PROBES 4
#define MAX_FORWARD_LIGHT 4
@@ -216,7 +219,12 @@ vec3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
float D = D_GGX(surfaceToLight.NdotH, surface.linearRoughnessSq);
vec3 Fr = D * F * Vis;
+#if CAPTURING == true
+ return mix(Fd + Fr,surface.f0,surface.metalness);
+#else
return Fd + Fr;
+#endif
+
}
vec3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float shadow)
@@ -331,14 +339,14 @@ float defineBoxSpaceInfluence(vec3 wsPosition, mat4 worldToObj, float attenuatio
// 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/
-vec3 boxProject(vec3 wsPosition, vec3 wsReflectVec, mat4 worldToObj, vec3 refBoxMin, vec3 refBoxMax, vec3 refPosition)
+vec3 boxProject(vec3 wsPosition, vec3 wsReflectVec, mat4 worldToObj, vec3 refScale, vec3 refPosition)
{
vec3 RayLS = tMul(worldToObj, vec4(wsReflectVec, 0.0)).xyz;
vec3 PositionLS = tMul(worldToObj, vec4(wsPosition, 1.0)).xyz;
- vec3 unit = refBoxMax.xyz - refBoxMin.xyz;
- vec3 plane1vec = (unit / 2 - PositionLS) / RayLS;
- vec3 plane2vec = (-unit / 2 - PositionLS) / RayLS;
+ vec3 unit = refScale;
+ vec3 plane1vec = (unit - PositionLS) / RayLS;
+ vec3 plane2vec = (-unit - PositionLS) / RayLS;
vec3 furthestPlane = max(plane1vec, plane2vec);
float dist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z);
vec3 posonbox = wsPosition + wsReflectVec * dist;
@@ -348,7 +356,7 @@ vec3 boxProject(vec3 wsPosition, vec3 wsReflectVec, mat4 worldToObj, vec3 refBox
vec4 computeForwardProbes(Surface surface,
float cubeMips, int numProbes, mat4x4 worldToObjArray[MAX_FORWARD_PROBES], vec4 probeConfigData[MAX_FORWARD_PROBES],
- vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 refBoxMinArray[MAX_FORWARD_PROBES], vec4 refBoxMaxArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES],
+ vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 refScaleArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES],
float skylightCubemapIdx, sampler2D BRDFTexture,
samplerCubeArray irradianceCubemapAR, samplerCubeArray specularCubemapAR)
{
@@ -452,7 +460,7 @@ vec4 computeForwardProbes(Surface surface,
if (contrib > 0.0f)
{
float cubemapIdx = int(probeConfigData[i].a);
- vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refBoxMinArray[i].xyz, refBoxMaxArray[i].xyz, inRefPosArray[i].xyz);
+ vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz);
irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib;
specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib;
@@ -490,7 +498,7 @@ vec4 computeForwardProbes(Surface surface,
vec4 debugVizForwardProbes(Surface surface,
float cubeMips, int numProbes, mat4 worldToObjArray[MAX_FORWARD_PROBES], vec4 probeConfigData[MAX_FORWARD_PROBES],
- vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 refBoxMinArray[MAX_FORWARD_PROBES], vec4 refBoxMaxArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES],
+ vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 refScaleArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES],
float skylightCubemapIdx, sampler2D BRDFTexture,
samplerCubeArray irradianceCubemapAR, samplerCubeArray specularCubemapAR, int showAtten, int showContrib, int showSpec, int showDiff)
{
@@ -601,7 +609,7 @@ vec4 debugVizForwardProbes(Surface surface,
if (contrib > 0.0f)
{
float cubemapIdx = probeConfigData[i].a;
- vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refBoxMinArray[i].xyz, refBoxMaxArray[i].xyz, inRefPosArray[i].xyz);
+ vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz);
irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib;
specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib;
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl
index 25b1212d8..b948eae27 100644
--- a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl
@@ -45,7 +45,10 @@ uniform float4 albedo;
#endif // !TORQUE_SHADERGEN
-#define MAX_PROBES 50
+#ifndef MAX_PROBES
+#define MAX_PROBES 8
+#endif
+
#define MAX_FORWARD_PROBES 4
#define MAX_FORWARD_LIGHT 4
@@ -216,8 +219,13 @@ float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
float Vis = V_SmithGGXCorrelated(surface.NdotV, surfaceToLight.NdotL, surface.linearRoughnessSq);
float D = D_GGX(surfaceToLight.NdotH, surface.linearRoughnessSq);
float3 Fr = D * F * Vis;
-
+
+#if CAPTURING == true
+ return lerp(Fd + Fr,surface.f0,surface.metalness);
+#else
return Fd + Fr;
+#endif
+
}
float3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float shadow)
@@ -335,14 +343,14 @@ float defineBoxSpaceInfluence(float3 wsPosition, float4x4 worldToObj, float atte
// 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 wsReflectVec, float4x4 worldToObj, float3 refBoxMin, float3 refBoxMax, float3 refPosition)
+float3 boxProject(float3 wsPosition, float3 wsReflectVec, float4x4 worldToObj, float3 refScale, float3 refPosition)
{
float3 RayLS = mul(worldToObj, float4(wsReflectVec, 0.0)).xyz;
float3 PositionLS = mul(worldToObj, float4(wsPosition, 1.0)).xyz;
- float3 unit = refBoxMax.xyz - refBoxMin.xyz;
- float3 plane1vec = (unit / 2 - PositionLS) / RayLS;
- float3 plane2vec = (-unit / 2 - PositionLS) / RayLS;
+ float3 unit = refScale;
+ float3 plane1vec = (unit - PositionLS) / RayLS;
+ float3 plane2vec = (-unit - PositionLS) / RayLS;
float3 furthestPlane = max(plane1vec, plane2vec);
float dist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z);
float3 posonbox = wsPosition + wsReflectVec * dist;
@@ -352,7 +360,7 @@ float3 boxProject(float3 wsPosition, float3 wsReflectVec, float4x4 worldToObj, f
float4 computeForwardProbes(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],
+ float4 inProbePosArray[MAX_FORWARD_PROBES], float4 refScaleArray[MAX_FORWARD_PROBES], float4 inRefPosArray[MAX_FORWARD_PROBES],
float skylightCubemapIdx, TORQUE_SAMPLER2D(BRDFTexture),
TORQUE_SAMPLERCUBEARRAY(irradianceCubemapAR), TORQUE_SAMPLERCUBEARRAY(specularCubemapAR))
{
@@ -456,7 +464,7 @@ float4 computeForwardProbes(Surface surface,
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);
+ float3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz);
irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib;
specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib;
@@ -494,7 +502,7 @@ float4 computeForwardProbes(Surface surface,
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],
+ float4 inProbePosArray[MAX_FORWARD_PROBES], float4 refScaleArray[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)
{
@@ -605,7 +613,7 @@ float4 debugVizForwardProbes(Surface surface,
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);
+ float3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz);
irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib;
specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib;
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/prefilterP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/prefilterP.glsl
index 984729bb6..2c3b9b5ac 100644
--- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/prefilterP.glsl
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/prefilterP.glsl
@@ -127,4 +127,5 @@ void main()
{
vec3 N = getCubeDir(face, uv0);
OUT_col = prefilterEnvMap(N);
+ OUT_col.a = 1;
}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl
index 10f8a57d9..9abc5f3d5 100644
--- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl
@@ -33,8 +33,7 @@ uniform vec4 rtParams6;
uniform vec4 inProbePosArray[MAX_PROBES];
uniform vec4 inRefPosArray[MAX_PROBES];
uniform mat4 worldToObjArray[MAX_PROBES];
-uniform vec4 refBoxMinArray[MAX_PROBES];
-uniform vec4 refBoxMaxArray[MAX_PROBES];
+uniform vec4 refScaleArray[MAX_PROBES];
uniform vec4 probeConfigData[MAX_PROBES]; //r,g,b/mode,radius,atten
#if DEBUGVIZ_CONTRIB
@@ -180,7 +179,7 @@ void main()
if (contrib > 0.0f)
{
float cubemapIdx = probeConfigData[i].a;
- vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refBoxMinArray[i].xyz, refBoxMaxArray[i].xyz, inRefPosArray[i].xyz);
+ vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz);
irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib;
specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib;
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/prefilterP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/prefilterP.hlsl
index eeeb670c2..1d0840958 100644
--- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/prefilterP.hlsl
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/prefilterP.hlsl
@@ -126,5 +126,5 @@ float4 prefilterEnvMap(float3 R)
float4 main(ConnectData IN) : TORQUE_TARGET0
{
float3 N = getCubeDir(face, IN.uv);
- return prefilterEnvMap(N);
+ return float4(prefilterEnvMap(N).rgb,1.0);
}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl
index d47967c6c..c13a373ac 100644
--- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl
@@ -30,8 +30,7 @@ uniform float4 rtParams6;
uniform float4 inProbePosArray[MAX_PROBES];
uniform float4 inRefPosArray[MAX_PROBES];
uniform float4x4 worldToObjArray[MAX_PROBES];
-uniform float4 refBoxMinArray[MAX_PROBES];
-uniform float4 refBoxMaxArray[MAX_PROBES];
+uniform float4 refScaleArray[MAX_PROBES];
uniform float4 probeConfigData[MAX_PROBES]; //r,g,b/mode,radius,atten
#if DEBUGVIZ_CONTRIB
@@ -172,7 +171,7 @@ float4 main(PFXVertToPix IN) : SV_TARGET
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);
+ float3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], refScaleArray[i].xyz, inRefPosArray[i].xyz);
irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib;
specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib;
diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/probeBake.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/probeBake.ed.cs
index 9c561e0bf..352466ed0 100644
--- a/Templates/BaseGame/game/tools/worldEditor/scripts/probeBake.ed.cs
+++ b/Templates/BaseGame/game/tools/worldEditor/scripts/probeBake.ed.cs
@@ -39,17 +39,11 @@ function ProbeBakeDlg_RunBake::onClick(%this)
if(%iter != 0)
$pref::ReflectionProbes::RenderWithProbes = true;
- for(%i=0; %i < %probeCount; %i++)
- {
- %probe = getWord(%probeIds, %i);
-
- $pref::ReflectionProbes::CurrentLevelPath = filePath($Server::MissionFile) @ "/" @ fileBase($Server::MissionFile) @ "/probes/";
- ProbeBin.bakeProbe(%probe);
-
- %currentProgressValue += %progressStep;
- ProbeBakeDlg_Progress.setValue(%currentProgressValue);
- Canvas.repaint();
- }
+ $pref::ReflectionProbes::CurrentLevelPath = filePath($Server::MissionFile) @ "/" @ fileBase($Server::MissionFile) @ "/probes/";
+ ProbeBin.bakeProbes();
+
+ %currentProgressValue += %progressStep;
+ ProbeBakeDlg_Progress.setValue(%currentProgressValue);
}
EWorldEditor.isDirty = true;