mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-13 03:33:48 +00:00
Finished current cleanup/reorg.
Temporarily disabled logic for forward render of probes to avoid data mangle. TODO: fix up forward once deferred math is locked in Split probe modes out into distinct environmental probe objects Removed the probes from tracking their own baked cubemap file paths and instead have a pref store it Removed old probe shaders and materials that aren't used now. Fixed mLastConst memory leak by removing nono line.
This commit is contained in:
parent
58e3349286
commit
788e265477
18 changed files with 1024 additions and 1282 deletions
|
|
@ -38,6 +38,11 @@
|
|||
#include "gfx/gfxTextureManager.h"
|
||||
|
||||
#include "postFx/postEffect.h"
|
||||
#include "T3D/lighting/reflectionProbe.h"
|
||||
#include "T3D/lighting/IBLUtilities.h"
|
||||
|
||||
//For our cameraQuery setup
|
||||
#include "T3D/gameTSCtrl.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(RenderProbeMgr);
|
||||
|
||||
|
|
@ -69,22 +74,13 @@ S32 QSORT_CALLBACK AscendingReflectProbeInfluence(const void* a, const void* b)
|
|||
ProbeRenderInst::ProbeRenderInst() : SystemInterface(),
|
||||
mTransform(true),
|
||||
mDirty(false),
|
||||
mAmbient(0.0f, 0.0f, 0.0f, 1.0f),
|
||||
mPriority(1.0f),
|
||||
mScore(0.0f),
|
||||
mDebugRender(false),
|
||||
mCubemap(NULL),
|
||||
mIrradianceCubemap(NULL),
|
||||
mBRDFTexture(NULL),
|
||||
mRadius(1.0f),
|
||||
mIntensity(1.0f),
|
||||
mProbePosOffset(0, 0, 0),
|
||||
numPrims(0)
|
||||
mProbePosOffset(0, 0, 0)
|
||||
{
|
||||
for (U32 i = 0; i < 5; ++i)
|
||||
{
|
||||
mSHConstants[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ProbeRenderInst::~ProbeRenderInst()
|
||||
|
|
@ -97,46 +93,22 @@ ProbeRenderInst::~ProbeRenderInst()
|
|||
{
|
||||
mIrradianceCubemap.free();
|
||||
}
|
||||
if (mBRDFTexture && mBRDFTexture->isValid())
|
||||
{
|
||||
mBRDFTexture->free();
|
||||
}
|
||||
}
|
||||
|
||||
void ProbeRenderInst::set(const ProbeRenderInst *probeInfo)
|
||||
{
|
||||
mTransform = probeInfo->mTransform;
|
||||
mAmbient = probeInfo->mAmbient;
|
||||
mCubemap = probeInfo->mCubemap;
|
||||
mIrradianceCubemap = probeInfo->mIrradianceCubemap;
|
||||
mBRDFTexture = probeInfo->mBRDFTexture;
|
||||
mRadius = probeInfo->mRadius;
|
||||
mIntensity = probeInfo->mIntensity;
|
||||
mProbeShapeType = probeInfo->mProbeShapeType;
|
||||
numPrims = probeInfo->numPrims;
|
||||
numVerts = probeInfo->numVerts;
|
||||
numIndicesForPoly = probeInfo->numIndicesForPoly;
|
||||
mBounds = probeInfo->mBounds;
|
||||
mIsSkylight = probeInfo->mIsSkylight;
|
||||
mScore = probeInfo->mScore;
|
||||
|
||||
for (U32 i = 0; i < 9; i++)
|
||||
{
|
||||
mSHTerms[i] = probeInfo->mSHTerms[i];
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < 5; i++)
|
||||
{
|
||||
mSHConstants[i] = probeInfo->mSHConstants[i];
|
||||
}
|
||||
}
|
||||
|
||||
void ProbeRenderInst::getWorldToLightProj(MatrixF *outMatrix) const
|
||||
{
|
||||
*outMatrix = getTransform();
|
||||
outMatrix->inverse();
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
ProbeShaderConstants::ProbeShaderConstants()
|
||||
: mInit(false),
|
||||
mShader(NULL),
|
||||
|
|
@ -193,69 +165,18 @@ void ProbeShaderConstants::_onShaderReload()
|
|||
init(mShader);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
bool ReflectProbeMatInstance::init(const FeatureSet &features, const GFXVertexFormat *vertexFormat)
|
||||
{
|
||||
mShaderMat = nullptr;
|
||||
|
||||
bool success = Parent::init(features, vertexFormat);
|
||||
|
||||
// If the initialization failed don't continue.
|
||||
if (!success || !mProcessedMaterial || mProcessedMaterial->getNumPasses() == 0)
|
||||
return false;
|
||||
|
||||
mShaderMat = static_cast<ProcessedShaderMaterial*>(getShaderMaterial());
|
||||
mShaderMat->init(features, vertexFormat, mFeaturesDelegate);
|
||||
|
||||
//mShaderMat->setMaterialParameters(mDefaultParameters, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReflectProbeMatInstance::setupPass(SceneRenderState *state, const SceneData &sgData)
|
||||
{
|
||||
if (!Parent::setupPass(state, sgData))
|
||||
return false;
|
||||
|
||||
AssertFatal(mProcessedMaterial->getNumPasses() > 0, "No passes created! Ohnoes");
|
||||
const RenderPassData *rpd = mProcessedMaterial->getPass(0);
|
||||
AssertFatal(rpd, "No render pass data!");
|
||||
AssertFatal(rpd->mRenderStates[0], "No render state 0!");
|
||||
|
||||
if (!mProjectionState)
|
||||
{
|
||||
GFXStateBlockDesc desc;
|
||||
desc.setZReadWrite(false);
|
||||
desc.zWriteEnable = false;
|
||||
desc.setCullMode(GFXCullNone);
|
||||
desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvDestAlpha, GFXBlendOpAdd);
|
||||
mProjectionState = GFX->createStateBlock(desc);
|
||||
}
|
||||
// Now override stateblock with our own
|
||||
GFX->setStateBlock(mProjectionState);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
RenderProbeMgr::RenderProbeMgr()
|
||||
: RenderBinManager(RenderPassManager::RIT_Probes, 1.0f, 1.0f),
|
||||
mReflectProbeMaterial(nullptr),
|
||||
mLastShader(nullptr),
|
||||
mLastConstants(nullptr)
|
||||
{
|
||||
String brdfPath = Con::getVariable("$Core::BRDFTexture", "core/art/pbr/brdfTexture.dds");
|
||||
mBrdfTexture = TEXMGR->createTexture(brdfPath, &GFXTexturePersistentProfile);
|
||||
|
||||
mEffectiveProbeCount = 0;
|
||||
mMipCount = 0;
|
||||
|
||||
mProbeArrayEffect = nullptr;
|
||||
|
||||
numProbesSC = nullptr;
|
||||
|
||||
smProbeManager = this;
|
||||
}
|
||||
|
||||
|
|
@ -264,6 +185,12 @@ RenderProbeMgr::RenderProbeMgr(RenderInstType riType, F32 renderOrder, F32 proce
|
|||
{
|
||||
}
|
||||
|
||||
void RenderProbeMgr::onRemove()
|
||||
{
|
||||
SAFE_DELETE(mLastConstants);
|
||||
|
||||
Parent::onRemove();
|
||||
}
|
||||
void RenderProbeMgr::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
|
|
@ -350,13 +277,24 @@ void RenderProbeMgr::_setupStaticParameters()
|
|||
mEffectiveProbeCount = 0;
|
||||
mMipCount = 0;
|
||||
|
||||
probePositions.setSize(MAXPROBECOUNT);
|
||||
probeWorldToObj.setSize(MAXPROBECOUNT);
|
||||
probeBBMin.setSize(MAXPROBECOUNT);
|
||||
probeBBMax.setSize(MAXPROBECOUNT);
|
||||
probeUseSphereMode.setSize(MAXPROBECOUNT);
|
||||
probeRadius.setSize(MAXPROBECOUNT);
|
||||
probeAttenuation.setSize(MAXPROBECOUNT);
|
||||
if (probePositionsData.size() != MAXPROBECOUNT)
|
||||
{
|
||||
probePositionsData.setSize(MAXPROBECOUNT);
|
||||
probeWorldToObjData.setSize(MAXPROBECOUNT);
|
||||
probeBBMinData.setSize(MAXPROBECOUNT);
|
||||
probeBBMaxData.setSize(MAXPROBECOUNT);
|
||||
probeUseSphereModeData.setSize(MAXPROBECOUNT);
|
||||
probeRadiusData.setSize(MAXPROBECOUNT);
|
||||
probeAttenuationData.setSize(MAXPROBECOUNT);
|
||||
}
|
||||
|
||||
probePositionsData.fill(Point4F::Zero);
|
||||
probeWorldToObjData.fill(MatrixF::Identity);
|
||||
probeBBMinData.fill(Point4F::Zero);
|
||||
probeBBMaxData.fill(Point4F::Zero);
|
||||
probeUseSphereModeData.fill(Point4F::Zero);
|
||||
probeRadiusData.fill(Point4F::Zero);
|
||||
probeAttenuationData.fill(Point4F::Zero);
|
||||
|
||||
cubeMaps.clear();
|
||||
irradMaps.clear();
|
||||
|
|
@ -366,43 +304,40 @@ void RenderProbeMgr::_setupStaticParameters()
|
|||
if (mEffectiveProbeCount >= MAXPROBECOUNT)
|
||||
break;
|
||||
|
||||
ProbeRenderInst* curEntry = ProbeRenderInst::all[i];
|
||||
if (!curEntry->mIsEnabled)
|
||||
const ProbeRenderInst& curEntry = *ProbeRenderInst::all[i];
|
||||
if (!curEntry.mIsEnabled)
|
||||
continue;
|
||||
|
||||
if (curEntry->mCubemap.isNull() || curEntry->mIrradianceCubemap.isNull())
|
||||
if (curEntry.mCubemap.isNull() || curEntry.mIrradianceCubemap.isNull())
|
||||
continue;
|
||||
|
||||
if (!curEntry->mCubemap->isInitialised())
|
||||
if (!curEntry.mCubemap->isInitialised())
|
||||
continue;
|
||||
|
||||
if (!curEntry->mIrradianceCubemap->isInitialised())
|
||||
if (!curEntry.mIrradianceCubemap->isInitialised())
|
||||
continue;
|
||||
|
||||
if (curEntry->mIsSkylight)
|
||||
if (curEntry.mIsSkylight)
|
||||
continue;
|
||||
|
||||
mMipCount = curEntry->mCubemap.getPointer()->getMipMapLevels();
|
||||
mMipCount = curEntry.mCubemap.getPointer()->getMipMapLevels();
|
||||
|
||||
//Setup
|
||||
const Point3F &probePos = curEntry->getPosition();
|
||||
probePositions[mEffectiveProbeCount] = probePos + curEntry->mProbePosOffset;
|
||||
Point3F probePos = curEntry.getPosition() + curEntry.mProbePosOffset;
|
||||
probePositionsData[mEffectiveProbeCount] = Point4F(probePos.x, probePos.y, probePos.z,0);
|
||||
|
||||
MatrixF trans = curEntry->getTransform();
|
||||
trans.inverse();
|
||||
probeWorldToObjData[mEffectiveProbeCount] = curEntry.getTransform();
|
||||
|
||||
probeWorldToObj[mEffectiveProbeCount] = trans;
|
||||
probeBBMinData[mEffectiveProbeCount] = Point4F(curEntry.mBounds.minExtents.x, curEntry.mBounds.minExtents.y, curEntry.mBounds.minExtents.z, 0);
|
||||
probeBBMaxData[mEffectiveProbeCount] = Point4F(curEntry.mBounds.maxExtents.x, curEntry.mBounds.maxExtents.y, curEntry.mBounds.maxExtents.z, 0);
|
||||
|
||||
probeBBMin[mEffectiveProbeCount] = curEntry->mBounds.minExtents;
|
||||
probeBBMax[mEffectiveProbeCount] = curEntry->mBounds.maxExtents;
|
||||
probeUseSphereModeData[mEffectiveProbeCount] = Point4F(curEntry.mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0, 0,0,0);
|
||||
|
||||
probeUseSphereMode[mEffectiveProbeCount] = Point4F(curEntry->mProbeShapeType == ProbeRenderInst::Sphere ? 1 : 0, 0,0,0);
|
||||
probeRadiusData[mEffectiveProbeCount] = Point4F(curEntry.mRadius,0,0,0);
|
||||
probeAttenuationData[mEffectiveProbeCount] = Point4F(1, 0, 0, 0);
|
||||
|
||||
probeRadius[mEffectiveProbeCount] = Point4F(curEntry->mRadius,0,0,0);
|
||||
probeAttenuation[mEffectiveProbeCount] = Point4F(1, 0, 0, 0);
|
||||
|
||||
cubeMaps.push_back(curEntry->mCubemap);
|
||||
irradMaps.push_back(curEntry->mIrradianceCubemap);
|
||||
cubeMaps.push_back(curEntry.mCubemap);
|
||||
irradMaps.push_back(curEntry.mIrradianceCubemap);
|
||||
|
||||
mEffectiveProbeCount++;
|
||||
}
|
||||
|
|
@ -420,75 +355,6 @@ void RenderProbeMgr::_setupStaticParameters()
|
|||
void RenderProbeMgr::_setupPerFrameParameters(const SceneRenderState *state)
|
||||
{
|
||||
PROFILE_SCOPE(RenderProbeMgr_SetupPerFrameParameters);
|
||||
const Frustum &frustum = state->getCameraFrustum();
|
||||
|
||||
MatrixF invCam(frustum.getTransform());
|
||||
invCam.inverse();
|
||||
|
||||
const Point3F *wsFrustumPoints = frustum.getPoints();
|
||||
const Point3F& cameraPos = frustum.getPosition();
|
||||
|
||||
// Perform a camera offset. We need to manually perform this offset on the sun (or vector) light's
|
||||
// polygon, which is at the far plane.
|
||||
Point3F cameraOffsetPos = cameraPos;
|
||||
|
||||
// Now build the quad for drawing full-screen vector light
|
||||
// passes.... this is a volatile VB and updates every frame.
|
||||
FarFrustumQuadVert verts[4];
|
||||
{
|
||||
verts[0].point.set(wsFrustumPoints[Frustum::FarTopLeft] - cameraPos);
|
||||
invCam.mulP(wsFrustumPoints[Frustum::FarTopLeft], &verts[0].normal);
|
||||
verts[0].texCoord.set(-1.0, 1.0);
|
||||
verts[0].tangent.set(wsFrustumPoints[Frustum::FarTopLeft] - cameraOffsetPos);
|
||||
|
||||
verts[1].point.set(wsFrustumPoints[Frustum::FarTopRight] - cameraPos);
|
||||
invCam.mulP(wsFrustumPoints[Frustum::FarTopRight], &verts[1].normal);
|
||||
verts[1].texCoord.set(1.0, 1.0);
|
||||
verts[1].tangent.set(wsFrustumPoints[Frustum::FarTopRight] - cameraOffsetPos);
|
||||
|
||||
verts[2].point.set(wsFrustumPoints[Frustum::FarBottomLeft] - cameraPos);
|
||||
invCam.mulP(wsFrustumPoints[Frustum::FarBottomLeft], &verts[2].normal);
|
||||
verts[2].texCoord.set(-1.0, -1.0);
|
||||
verts[2].tangent.set(wsFrustumPoints[Frustum::FarBottomLeft] - cameraOffsetPos);
|
||||
|
||||
verts[3].point.set(wsFrustumPoints[Frustum::FarBottomRight] - cameraPos);
|
||||
invCam.mulP(wsFrustumPoints[Frustum::FarBottomRight], &verts[3].normal);
|
||||
verts[3].texCoord.set(1.0, -1.0);
|
||||
verts[3].tangent.set(wsFrustumPoints[Frustum::FarBottomRight] - cameraOffsetPos);
|
||||
}
|
||||
|
||||
mFarFrustumQuadVerts.set(GFX, 4);
|
||||
dMemcpy(mFarFrustumQuadVerts.lock(), verts, sizeof(verts));
|
||||
mFarFrustumQuadVerts.unlock();
|
||||
|
||||
PlaneF farPlane(wsFrustumPoints[Frustum::FarBottomLeft], wsFrustumPoints[Frustum::FarTopLeft], wsFrustumPoints[Frustum::FarTopRight]);
|
||||
PlaneF vsFarPlane(verts[0].normal, verts[1].normal, verts[2].normal);
|
||||
|
||||
ReflectProbeMaterialInfo* reflProbeMat = getReflectProbeMaterial();
|
||||
|
||||
if (reflProbeMat != nullptr && reflProbeMat->matInstance != nullptr)
|
||||
{
|
||||
reflProbeMat->setViewParameters(frustum.getNearDist(),
|
||||
frustum.getFarDist(),
|
||||
frustum.getPosition(),
|
||||
farPlane,
|
||||
vsFarPlane);
|
||||
}
|
||||
}
|
||||
|
||||
RenderProbeMgr::ReflectProbeMaterialInfo* RenderProbeMgr::getReflectProbeMaterial()
|
||||
{
|
||||
PROFILE_SCOPE(AdvancedLightBinManager_getReflectProbeMaterial);
|
||||
|
||||
//ReflectProbeMaterialInfo *info = NULL;
|
||||
|
||||
if (!mReflectProbeMaterial)
|
||||
|
||||
// Now create the material info object.
|
||||
mReflectProbeMaterial = new ReflectProbeMaterialInfo("ReflectionProbeMaterial",
|
||||
getGFXVertexFormat<GFXVertexPC>());
|
||||
|
||||
return mReflectProbeMaterial;
|
||||
}
|
||||
|
||||
ProbeShaderConstants* RenderProbeMgr::getProbeShaderConstants(GFXShaderConstBuffer* buffer)
|
||||
|
|
@ -507,27 +373,25 @@ ProbeShaderConstants* RenderProbeMgr::getProbeShaderConstants(GFXShaderConstBuff
|
|||
ProbeConstantMap::Iterator iter = mConstantLookup.find(shader);
|
||||
if (iter != mConstantLookup.end())
|
||||
{
|
||||
mLastForwardConstants = iter->value;
|
||||
mLastConstants = iter->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
ProbeShaderConstants* psc = new ProbeShaderConstants();
|
||||
mConstantLookup[shader] = psc;
|
||||
|
||||
mLastForwardConstants = psc;
|
||||
mLastConstants = psc;
|
||||
}
|
||||
|
||||
// Set our new shader
|
||||
mLastShader = shader;
|
||||
}
|
||||
|
||||
mLastForwardConstants = new ProbeShaderConstants();
|
||||
|
||||
// Make sure that our current lighting constants are initialized
|
||||
if (!mLastForwardConstants->mInit)
|
||||
mLastForwardConstants->init(shader);
|
||||
if (mLastConstants && !mLastConstants->mInit)
|
||||
mLastConstants->init(shader);
|
||||
|
||||
return mLastForwardConstants;
|
||||
return mLastConstants;
|
||||
}
|
||||
|
||||
void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
|
||||
|
|
@ -548,7 +412,7 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
|
|||
probeRadiusSC->isValid() ||
|
||||
probeBoxMinSC->isValid() ||
|
||||
probeBoxMaxSC->isValid() ||
|
||||
probeCubemapSC->isValid() && (!ProbeRenderInst::all.empty()))
|
||||
probeCubemapSC->isValid()/* && (!ProbeRenderInst::all.empty())*/)
|
||||
{
|
||||
PROFILE_SCOPE(ProbeManager_Update4ProbeConsts_setProbes);
|
||||
|
||||
|
|
@ -576,7 +440,7 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
|
|||
const MatrixF &worldToCameraXfm = matSet.getWorldToCamera();
|
||||
|
||||
// Gather the data for the first 4 probes.
|
||||
const ProbeRenderInst *probe;
|
||||
/*const ProbeRenderInst *probe;
|
||||
for (U32 i = 0; i < 4; i++)
|
||||
{
|
||||
if (i >= ProbeRenderInst::all.size())
|
||||
|
|
@ -625,6 +489,33 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
|
|||
if (samplerReg != -1)
|
||||
GFX->setCubeTexture(samplerReg + i, probe->mCubemap.getPointer());
|
||||
}
|
||||
}*/
|
||||
|
||||
for (U32 i = 0; i < 4; i++)
|
||||
{
|
||||
probePositions[i].x = 0;
|
||||
probePositions[i].y = 0;
|
||||
probePositions[i].z = 0;
|
||||
|
||||
probeRadius[i] = 0;
|
||||
|
||||
probeBoxMins[i].x = 0;
|
||||
probeBoxMins[i].y = 0;
|
||||
probeBoxMins[i].z = 0;
|
||||
|
||||
probeBoxMaxs[i].x = 0;
|
||||
probeBoxMaxs[i].y = 0;
|
||||
probeBoxMaxs[i].z = 0;
|
||||
|
||||
probeIsSphere[i] = 0;
|
||||
|
||||
probeLocalPositions[i].x = 0;
|
||||
probeLocalPositions[i].y = 0;
|
||||
probeLocalPositions[i].z = 0;
|
||||
|
||||
S32 samplerReg = probeCubemapSC->getSamplerRegister();
|
||||
|
||||
GFX->setCubeTexture(samplerReg + i, nullptr);
|
||||
}
|
||||
|
||||
shaderConsts->setSafe(probePositionSC, probePositions);
|
||||
|
|
@ -633,18 +524,9 @@ void RenderProbeMgr::_update4ProbeConsts(const SceneData &sgData,
|
|||
shaderConsts->setSafe(probeBoxMaxSC, probeBoxMaxs);
|
||||
shaderConsts->setSafe(probeLocalPosSC, probeLocalPositions);
|
||||
shaderConsts->setSafe(probeIsSphereSC, probeIsSphere);
|
||||
|
||||
//
|
||||
|
||||
//shaderConsts->setSafe(lightSpotAngleSC, lightSpotAngle);
|
||||
//shaderConsts->setSafe(lightSpotFalloffSC, lightSpotFalloff);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*if (probe->mCubemap && !probe->mCubemap.isNull())
|
||||
{
|
||||
GFX->setCubeTexture(1, probe->mCubemap.getPointer());
|
||||
}*/
|
||||
if (probeCubemapSC->isValid())
|
||||
{
|
||||
for (U32 i = 0; i < 4; ++i)
|
||||
|
|
@ -672,9 +554,6 @@ void RenderProbeMgr::setProbeInfo(ProcessedMaterial *pmat,
|
|||
|
||||
ProbeShaderConstants *psc = getProbeShaderConstants(shaderConsts);
|
||||
|
||||
//ProbeInfo *probe;
|
||||
//probe = mRegisteredProbes[0];
|
||||
|
||||
// NOTE: If you encounter a crash from this point forward
|
||||
// while setting a shader constant its probably because the
|
||||
// mConstantLookup has bad shaders/constants in it.
|
||||
|
|
@ -683,7 +562,6 @@ void RenderProbeMgr::setProbeInfo(ProcessedMaterial *pmat,
|
|||
// are reloaded and the light manager is not reset.
|
||||
//
|
||||
// We should look to fix this by clearing the table.
|
||||
|
||||
MatrixSet matSet = state->getRenderPass()->getMatrixSet();
|
||||
|
||||
// Update the forward shading light constants.
|
||||
|
|
@ -708,6 +586,8 @@ void RenderProbeMgr::render( SceneRenderState *state )
|
|||
if (getProbeArrayEffect() == nullptr)
|
||||
return;
|
||||
|
||||
updateProbes();
|
||||
|
||||
// Early out if nothing to draw.
|
||||
if (!ProbeRenderInst::all.size() || !RenderProbeMgr::smRenderReflectionProbes || mEffectiveProbeCount == 0
|
||||
|| !state->isDiffusePass() || cubeMaps.empty() || irradMaps.empty())
|
||||
|
|
@ -723,223 +603,161 @@ void RenderProbeMgr::render( SceneRenderState *state )
|
|||
// Initialize and set the per-frame parameters after getting
|
||||
// the vector light material as we use lazy creation.
|
||||
//_setupPerFrameParameters(state);
|
||||
|
||||
//Specular
|
||||
//PROFILE_START(RenderProbeManager_ReflectProbeRender);
|
||||
|
||||
// If this is a non-diffuse pass or we have no objects to
|
||||
// render then tell the effect to skip rendering.
|
||||
|
||||
//Array rendering
|
||||
U32 probeCount = ProbeRenderInst::all.size();
|
||||
|
||||
if (mEffectiveProbeCount != 0)
|
||||
{
|
||||
//These will in theory be set by the postFX
|
||||
/*NamedTexTarget *deferredTarget = NamedTexTarget::find(RenderDeferredMgr::BufferName);
|
||||
if (deferredTarget)
|
||||
GFX->setTexture(0, deferredTarget->getTexture());
|
||||
else
|
||||
GFX->setTexture(0, NULL);
|
||||
|
||||
NamedTexTarget *colorTarget = NamedTexTarget::find(RenderDeferredMgr::ColorBufferName);
|
||||
if (colorTarget)
|
||||
GFX->setTexture(1, colorTarget->getTexture());
|
||||
else
|
||||
GFX->setTexture(1, NULL);
|
||||
|
||||
NamedTexTarget *matinfoTarget = NamedTexTarget::find(RenderDeferredMgr::MatInfoBufferName);
|
||||
if (matinfoTarget)
|
||||
GFX->setTexture(2, matinfoTarget->getTexture());
|
||||
else
|
||||
GFX->setTexture(2, NULL);*/
|
||||
|
||||
/*if (mBrdfTexture)
|
||||
{
|
||||
GFX->setTexture(3, mBrdfTexture);
|
||||
}
|
||||
else
|
||||
GFX->setTexture(3, NULL);*/
|
||||
|
||||
//GFX->setCubeArrayTexture(4, mCubemapArray);
|
||||
//GFX->setCubeArrayTexture(5, mIrradArray);
|
||||
mProbeArrayEffect->setCubemapArrayTexture(4, mCubemapArray);
|
||||
mProbeArrayEffect->setCubemapArrayTexture(5, mIrradArray);
|
||||
|
||||
mProbeArrayEffect->setShaderConst("$cubeMips", (float)mMipCount);
|
||||
|
||||
mProbeArrayEffect->setShaderConst("$numProbes", (float)mEffectiveProbeCount);
|
||||
mProbeArrayEffect->setShaderConst("$inProbePosArray", probePositions);
|
||||
mProbeArrayEffect->setShaderConst("$worldToObjArray", probeWorldToObj);
|
||||
mProbeArrayEffect->setShaderConst("$bbMinArray", probeBBMin);
|
||||
mProbeArrayEffect->setShaderConst("$bbMaxArray", probeBBMax);
|
||||
mProbeArrayEffect->setShaderConst("$useSphereMode", probeUseSphereMode);
|
||||
mProbeArrayEffect->setShaderConst("$radius", probeRadius);
|
||||
mProbeArrayEffect->setShaderConst("$attenuation", probeAttenuation);
|
||||
mProbeArrayEffect->setShaderConst("$inProbePosArray", probePositionsData);
|
||||
mProbeArrayEffect->setShaderConst("$worldToObjArray", probeWorldToObjData);
|
||||
mProbeArrayEffect->setShaderConst("$bbMinArray", probeBBMinData);
|
||||
mProbeArrayEffect->setShaderConst("$bbMaxArray", probeBBMaxData);
|
||||
mProbeArrayEffect->setShaderConst("$useSphereMode", probeUseSphereModeData);
|
||||
mProbeArrayEffect->setShaderConst("$radius", probeRadiusData);
|
||||
mProbeArrayEffect->setShaderConst("$attenuation", probeAttenuationData);
|
||||
}
|
||||
|
||||
// Finish up.
|
||||
//if (isRenderingToTarget)
|
||||
// _onPostRender();
|
||||
|
||||
// Make sure the effect is gonna render.
|
||||
getProbeArrayEffect()->setSkip(false);
|
||||
|
||||
//PROFILE_END();
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
RenderProbeMgr::ReflectProbeMaterialInfo::ReflectProbeMaterialInfo(const String &matName,
|
||||
const GFXVertexFormat *vertexFormat)
|
||||
: matInstance(NULL),
|
||||
zNearFarInvNearFar(NULL),
|
||||
farPlane(NULL),
|
||||
vsFarPlane(NULL),
|
||||
negFarPlaneDotEye(NULL),
|
||||
probeWSPos(NULL),
|
||||
attenuation(NULL),
|
||||
radius(NULL),
|
||||
cubeMips(NULL)
|
||||
void RenderProbeMgr::bakeProbe(ReflectionProbe *probe)
|
||||
{
|
||||
Material *mat = MATMGR->getMaterialDefinitionByName(matName);
|
||||
if (!mat)
|
||||
return;
|
||||
GFXDEBUGEVENT_SCOPE(RenderProbeMgr_Bake, ColorI::WHITE);
|
||||
|
||||
matInstance = new ReflectProbeMatInstance(*mat);
|
||||
Con::warnf("RenderProbeMgr::bakeProbe() - Beginning bake!");
|
||||
U32 startMSTime = Platform::getRealMilliseconds();
|
||||
|
||||
const Vector<GFXShaderMacro> ¯os = Vector<GFXShaderMacro>();
|
||||
String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/");
|
||||
U32 resolution = Con::getIntVariable("$pref::ReflectionProbes::BakeResolution", 64);
|
||||
U32 prefilterMipLevels = mLog2(F32(resolution));
|
||||
bool renderWithProbes = Con::getIntVariable("$pref::ReflectionProbes::RenderWithProbes", false);
|
||||
|
||||
for (U32 i = 0; i < macros.size(); i++)
|
||||
matInstance->addShaderMacro(macros[i].name, macros[i].value);
|
||||
ReflectionProbe *clientProbe = static_cast<ReflectionProbe*>(probe->getClientObject());
|
||||
|
||||
matInstance->init(MATMGR->getDefaultFeatures(), vertexFormat);
|
||||
String probePrefilterPath = clientProbe->getPrefilterMapPath();
|
||||
String probeIrradPath = clientProbe->getIrradianceMapPath();
|
||||
|
||||
attenuation = matInstance->getMaterialParameterHandle("$attenuation");
|
||||
radius = matInstance->getMaterialParameterHandle("$radius");
|
||||
probeLSPos = matInstance->getMaterialParameterHandle("$probeLSPos");
|
||||
probeWSPos = matInstance->getMaterialParameterHandle("$probeWSPos");
|
||||
farPlane = matInstance->getMaterialParameterHandle("$farPlane");
|
||||
vsFarPlane = matInstance->getMaterialParameterHandle("$vsFarPlane");
|
||||
negFarPlaneDotEye = matInstance->getMaterialParameterHandle("$negFarPlaneDotEye");
|
||||
zNearFarInvNearFar = matInstance->getMaterialParameterHandle("$zNearFarInvNearFar");
|
||||
|
||||
useCubemap = matInstance->getMaterialParameterHandle("$useCubemap");
|
||||
|
||||
cubemap = matInstance->getMaterialParameterHandle("$cubeMap");
|
||||
cubeMips = matInstance->getMaterialParameterHandle("$cubeMips");
|
||||
|
||||
eyePosWorld = matInstance->getMaterialParameterHandle("$eyePosWorld");
|
||||
bbMin = matInstance->getMaterialParameterHandle("$bbMin");
|
||||
bbMax = matInstance->getMaterialParameterHandle("$bbMax");
|
||||
|
||||
useSphereMode = matInstance->getMaterialParameterHandle("$useSphereMode");
|
||||
|
||||
probeCount = matInstance->getMaterialParameterHandle("$numProbes");
|
||||
|
||||
for (U32 i = 0; i < 9; i++)
|
||||
shTerms[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHTerms%d", i));
|
||||
|
||||
for (U32 i = 0; i < 5; i++)
|
||||
shConsts[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHConsts%d", i));
|
||||
}
|
||||
|
||||
RenderProbeMgr::ReflectProbeMaterialInfo::~ReflectProbeMaterialInfo()
|
||||
{
|
||||
SAFE_DELETE(matInstance);
|
||||
}
|
||||
|
||||
void RenderProbeMgr::ReflectProbeMaterialInfo::setViewParameters(const F32 _zNear,
|
||||
const F32 _zFar,
|
||||
const Point3F &_eyePos,
|
||||
const PlaneF &_farPlane,
|
||||
const PlaneF &_vsFarPlane)
|
||||
{
|
||||
MaterialParameters *matParams = matInstance->getMaterialParameters();
|
||||
|
||||
matParams->setSafe(farPlane, *((const Point4F *)&_farPlane));
|
||||
|
||||
matParams->setSafe(vsFarPlane, *((const Point4F *)&_vsFarPlane));
|
||||
|
||||
if (negFarPlaneDotEye->isValid())
|
||||
if (clientProbe->mReflectionModeType != ReflectionProbe::DynamicCubemap)
|
||||
{
|
||||
// -dot( farPlane, eyePos )
|
||||
const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d);
|
||||
matParams->set(negFarPlaneDotEye, negFarPlaneDotEyeVal);
|
||||
//Prep our bake path
|
||||
if (probePrefilterPath.isEmpty() || probeIrradPath.isEmpty())
|
||||
{
|
||||
Con::errorf("RenderProbeMgr::bake() - Unable to bake our captures because probe doesn't have a path set");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
matParams->setSafe(zNearFarInvNearFar, Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar));
|
||||
// Save the current transforms so we can restore
|
||||
// it for child control rendering below.
|
||||
GFXTransformSaver saver;
|
||||
|
||||
Point4F frPlane = *((const Point4F *)&_farPlane);
|
||||
Point4F vsFrPlane = *((const Point4F *)&_vsFarPlane);
|
||||
Point4F nearFarInvNearFar = Point4F(_zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar);
|
||||
const F32 negFarPlaneDotEyeVal = -(mDot(*((const Point3F *)&_farPlane), _eyePos) + _farPlane.d);
|
||||
}
|
||||
bool probeRenderState = RenderProbeMgr::smRenderReflectionProbes;
|
||||
|
||||
void RenderProbeMgr::ReflectProbeMaterialInfo::setProbeParameters(const ProbeRenderInst *probeInfo, const SceneRenderState* renderState, const MatrixF &worldViewOnly)
|
||||
{
|
||||
//Set up the params
|
||||
MaterialParameters *matParams = matInstance->getMaterialParameters();
|
||||
F32 farPlane = 1000.0f;
|
||||
|
||||
matParams->setSafe(radius, probeInfo->mRadius);
|
||||
ReflectorDesc reflDesc;
|
||||
reflDesc.texSize = resolution;
|
||||
reflDesc.farDist = farPlane;
|
||||
reflDesc.detailAdjust = 1;
|
||||
reflDesc.objectTypeMask = -1;
|
||||
|
||||
Point3F probePos = probeInfo->getPosition() + probeInfo->mProbePosOffset;
|
||||
//worldViewOnly.mulP(probeInfo->getPosition(), &probePos);
|
||||
matParams->setSafe(probeWSPos, probePos);
|
||||
CubeReflector cubeRefl;
|
||||
cubeRefl.registerReflector(probe, &reflDesc);
|
||||
|
||||
worldViewOnly.mulP(probeInfo->getPosition(), &probePos);
|
||||
matParams->setSafe(probeLSPos, probePos);
|
||||
ReflectParams reflParams;
|
||||
|
||||
// Get the attenuation falloff ratio and normalize it.
|
||||
Point3F attenRatio = Point3F(0.0f, 1.0f, 1.0f);
|
||||
F32 total = attenRatio.x + attenRatio.y + attenRatio.z;
|
||||
if (total > 0.0f)
|
||||
attenRatio /= total;
|
||||
//need to get the query somehow. Likely do some sort of get function to fetch from the guiTSControl that's active
|
||||
CameraQuery query; //need to get the last cameraQuery
|
||||
query.fov = 90; //90 degree slices for each of the 6 sides
|
||||
query.nearPlane = 0.1f;
|
||||
query.farPlane = farPlane;
|
||||
query.headMatrix = MatrixF();
|
||||
query.cameraMatrix = clientProbe->getTransform();
|
||||
|
||||
F32 probeRadius = probeInfo->mRadius;
|
||||
Frustum culler;
|
||||
culler.set(false,
|
||||
query.fov,
|
||||
(F32)resolution / (F32)resolution,
|
||||
query.nearPlane,
|
||||
query.farPlane,
|
||||
query.cameraMatrix);
|
||||
|
||||
Point2F attenParams((1.0f / probeRadius) * attenRatio.y,
|
||||
(1.0f / (probeRadius * probeRadius)) * attenRatio.z);
|
||||
S32 stereoTarget = GFX->getCurrentStereoTarget();
|
||||
|
||||
matParams->setSafe(attenuation, attenParams);
|
||||
Point2I maxRes(2048, 2048); //basically a boundary so we don't go over this and break stuff
|
||||
|
||||
NamedTexTarget* deferredTexTarget = NamedTexTarget::find("deferred");
|
||||
NamedTexTarget* matInfoTexTarget = NamedTexTarget::find("matinfo");
|
||||
NamedTexTarget* colorTexTarget = NamedTexTarget::find("color");
|
||||
reflParams.culler = culler;
|
||||
reflParams.eyeId = stereoTarget;
|
||||
reflParams.query = &query;
|
||||
reflParams.startOfUpdateMs = startMSTime;
|
||||
reflParams.viewportExtent = maxRes;
|
||||
|
||||
if (!deferredTexTarget || !matInfoTexTarget || !colorTexTarget)
|
||||
if (!renderWithProbes)
|
||||
RenderProbeMgr::smRenderReflectionProbes = false;
|
||||
|
||||
cubeRefl.updateReflection(reflParams);
|
||||
|
||||
//Now, save out the maps
|
||||
//create irridiance cubemap
|
||||
if (cubeRefl.getCubemap())
|
||||
{
|
||||
Con::errorf("ProbeManager::ReflectProbeMaterialInfo::setProbeParameters: Could not retrieve gbuffer");
|
||||
return;
|
||||
}
|
||||
//Just to ensure we're prepped for the generation
|
||||
clientProbe->createClientResources();
|
||||
|
||||
//set textures
|
||||
GFX->setTexture(0, deferredTexTarget->getTexture());
|
||||
GFX->setTexture(1, colorTexTarget->getTexture());
|
||||
GFX->setTexture(2, matInfoTexTarget->getTexture());
|
||||
//Prep it with whatever resolution we've dictated for our bake
|
||||
if (clientProbe->mUseHDRCaptures)
|
||||
{
|
||||
clientProbe->mIrridianceMap->mCubemap->initDynamic(resolution, GFXFormatR16G16B16A16F);
|
||||
clientProbe->mPrefilterMap->mCubemap->initDynamic(resolution, GFXFormatR16G16B16A16F);
|
||||
}
|
||||
else
|
||||
{
|
||||
clientProbe->mIrridianceMap->mCubemap->initDynamic(resolution, GFXFormatR8G8B8A8);
|
||||
clientProbe->mPrefilterMap->mCubemap->initDynamic(resolution, GFXFormatR8G8B8A8);
|
||||
}
|
||||
|
||||
//Add some safety catches in the event the cubemaps aren't fully initialized yet
|
||||
if (probeInfo->mCubemap == nullptr || probeInfo->mCubemap.isNull())
|
||||
{
|
||||
GFX->setCubeTexture(3, nullptr);
|
||||
matParams->setSafe(cubeMips, 2.0f);
|
||||
GFXTextureTargetRef renderTarget = GFX->allocRenderToTextureTarget(false);
|
||||
|
||||
IBLUtilities::GenerateIrradianceMap(renderTarget, cubeRefl.getCubemap(), clientProbe->mIrridianceMap->mCubemap);
|
||||
IBLUtilities::GeneratePrefilterMap(renderTarget, cubeRefl.getCubemap(), prefilterMipLevels, clientProbe->mPrefilterMap->mCubemap);
|
||||
|
||||
IBLUtilities::SaveCubeMap(clientProbe->getIrradianceMapPath(), clientProbe->mIrridianceMap->mCubemap);
|
||||
IBLUtilities::SaveCubeMap(clientProbe->getPrefilterMapPath(), clientProbe->mPrefilterMap->mCubemap);
|
||||
}
|
||||
else
|
||||
{
|
||||
GFX->setCubeTexture(3, probeInfo->mCubemap.getPointer());
|
||||
matParams->setSafe(cubeMips, mPow(probeInfo->mCubemap.getPointer()->getMipMapLevels(), 2.0f));
|
||||
Con::errorf("RenderProbeMgr::bake() - Didn't generate a valid scene capture cubemap, unable to generate prefilter and irradiance maps!");
|
||||
}
|
||||
|
||||
if (probeInfo->mIrradianceCubemap == nullptr || probeInfo->mIrradianceCubemap.isNull())
|
||||
GFX->setCubeTexture(4, nullptr);
|
||||
else
|
||||
GFX->setCubeTexture(4, probeInfo->mIrradianceCubemap.getPointer());
|
||||
if (!renderWithProbes)
|
||||
RenderProbeMgr::smRenderReflectionProbes = probeRenderState;
|
||||
|
||||
GFX->setTexture(5, probeInfo->mBRDFTexture->getPointer());
|
||||
cubeRefl.unregisterReflector();
|
||||
|
||||
//set material params
|
||||
matParams->setSafe(eyePosWorld, renderState->getCameraPosition());
|
||||
matParams->setSafe(bbMin, probeInfo->mBounds.minExtents);
|
||||
matParams->setSafe(bbMax, probeInfo->mBounds.maxExtents);
|
||||
matParams->setSafe(useSphereMode, probeInfo->mProbeShapeType == ProbeRenderInst::Sphere ? 1.0f : 0.0f);
|
||||
U32 endMSTime = Platform::getRealMilliseconds();
|
||||
F32 diffTime = F32(endMSTime - startMSTime);
|
||||
|
||||
Con::warnf("RenderProbeMgr::bake() - Finished bake! Took %g milliseconds", diffTime);
|
||||
}
|
||||
|
||||
void RenderProbeMgr::bakeProbes()
|
||||
{
|
||||
//TODO: make this just find every probe in the current missionGroup and run the bake on it automagically
|
||||
}
|
||||
|
||||
DefineEngineMethod(RenderProbeMgr, bakeProbe, void, (ReflectionProbe* probe), (nullAsType< ReflectionProbe*>()),
|
||||
"@brief returns true if control object is inside the fog\n\n.")
|
||||
{
|
||||
if(probe != nullptr)
|
||||
object->bakeProbe(probe);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue