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;