2018-09-17 03:15:07 +00:00
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
# include "renderProbeMgr.h"
# include "console/consoleTypes.h"
# include "scene/sceneObject.h"
# include "materials/materialManager.h"
# include "scene/sceneRenderState.h"
# include "math/util/sphereMesh.h"
# include "math/util/matrixSet.h"
# include "materials/processedMaterial.h"
# include "renderInstance/renderDeferredMgr.h"
# include "math/mPolyhedron.impl.h"
# include "gfx/gfxTransformSaver.h"
2018-10-24 23:27:43 +00:00
# include "gfx/gfxDebugEvent.h"
2019-01-26 08:05:18 +00:00
# include "shaderGen/shaderGenVars.h"
2019-01-08 02:34:19 +00:00
# include "materials/shaderData.h"
2019-01-28 07:36:17 +00:00
# include "gfx/gfxTextureManager.h"
2019-02-08 07:35:35 +00:00
# include "postFx/postEffect.h"
2019-02-14 06:35:22 +00:00
# include "T3D/lighting/reflectionProbe.h"
# include "T3D/lighting/IBLUtilities.h"
//For our cameraQuery setup
# include "T3D/gameTSCtrl.h"
2019-02-08 07:35:35 +00:00
2019-02-18 06:43:21 +00:00
# define TORQUE_GFX_VISUAL_DEBUG //renderdoc debugging
2018-09-17 03:15:07 +00:00
IMPLEMENT_CONOBJECT ( RenderProbeMgr ) ;
ConsoleDocClass ( RenderProbeMgr ,
" @brief A render bin which uses object callbacks for rendering. \n \n "
" This render bin gathers object render instances and calls its delegate "
" method to perform rendering. It is used infrequently for specialized "
" scene objects which perform custom rendering. \n \n "
" @ingroup RenderBin \n " ) ;
2019-01-26 08:05:18 +00:00
RenderProbeMgr * RenderProbeMgr : : smProbeManager = NULL ;
bool RenderProbeMgr : : smRenderReflectionProbes = true ;
2018-09-17 03:15:07 +00:00
S32 QSORT_CALLBACK AscendingReflectProbeInfluence ( const void * a , const void * b )
{
// Debug Profiling.
PROFILE_SCOPE ( AdvancedLightBinManager_AscendingReflectProbeInfluence ) ;
// Fetch asset definitions.
2018-11-27 14:28:33 +00:00
const ProbeRenderInst * pReflectProbeA = ( * ( ProbeRenderInst * * ) a ) ;
const ProbeRenderInst * pReflectProbeB = ( * ( ProbeRenderInst * * ) b ) ;
2018-11-25 18:35:35 +00:00
//sort by score
return pReflectProbeA - > mScore - pReflectProbeB - > mScore ;
2018-09-17 03:15:07 +00:00
}
2019-01-26 08:05:18 +00:00
//
//
ProbeRenderInst : : ProbeRenderInst ( ) : SystemInterface ( ) ,
mTransform ( true ) ,
mDirty ( false ) ,
mPriority ( 1.0f ) ,
mScore ( 0.0f ) ,
2019-03-24 23:18:44 +00:00
mPrefilterCubemap ( NULL ) ,
2019-01-26 08:05:18 +00:00
mIrradianceCubemap ( NULL ) ,
mRadius ( 1.0f ) ,
2019-02-19 14:58:02 +00:00
mProbeRefOffset ( 0 , 0 , 0 ) ,
2019-03-22 04:47:01 +00:00
mProbeRefScale ( 1 , 1 , 1 ) ,
2019-03-24 23:18:44 +00:00
mAtten ( 0.0 ) ,
2019-03-26 04:17:53 +00:00
mCubemapIndex ( 0 ) ,
mIsSkylight ( false )
2019-01-26 08:05:18 +00:00
{
}
ProbeRenderInst : : ~ ProbeRenderInst ( )
{
2019-03-24 23:18:44 +00:00
if ( mPrefilterCubemap & & mPrefilterCubemap . isValid ( ) )
2019-01-26 08:05:18 +00:00
{
2019-03-24 23:18:44 +00:00
mPrefilterCubemap . free ( ) ;
2019-01-26 08:05:18 +00:00
}
if ( mIrradianceCubemap & & mIrradianceCubemap . isValid ( ) )
{
mIrradianceCubemap . free ( ) ;
}
}
void ProbeRenderInst : : set ( const ProbeRenderInst * probeInfo )
{
mTransform = probeInfo - > mTransform ;
2019-03-24 23:18:44 +00:00
mPrefilterCubemap = probeInfo - > mPrefilterCubemap ;
2019-01-26 08:05:18 +00:00
mIrradianceCubemap = probeInfo - > mIrradianceCubemap ;
mRadius = probeInfo - > mRadius ;
mProbeShapeType = probeInfo - > mProbeShapeType ;
mBounds = probeInfo - > mBounds ;
mIsSkylight = probeInfo - > mIsSkylight ;
mScore = probeInfo - > mScore ;
2019-03-22 04:47:01 +00:00
mAtten = probeInfo - > mAtten ;
2019-01-26 08:05:18 +00:00
}
2019-02-14 06:35:22 +00:00
//
//
2019-01-26 08:05:18 +00:00
ProbeShaderConstants : : ProbeShaderConstants ( )
: mInit ( false ) ,
mShader ( NULL ) ,
mProbePositionSC ( NULL ) ,
2019-04-03 05:13:58 +00:00
mProbeRefPosSC ( NULL ) ,
2019-01-26 08:05:18 +00:00
mProbeBoxMinSC ( NULL ) ,
mProbeBoxMaxSC ( NULL ) ,
2019-04-03 05:13:58 +00:00
mProbeConfigDataSC ( NULL ) ,
mProbeSpecularCubemapSC ( NULL ) ,
mProbeIrradianceCubemapSC ( NULL ) ,
2019-04-10 17:54:46 +00:00
mProbeCountSC ( NULL ) ,
mSkylightSpecularMap ( NULL ) ,
mSkylightIrradMap ( NULL ) ,
mHasSkylight ( NULL )
2019-01-26 08:05:18 +00:00
{
}
ProbeShaderConstants : : ~ ProbeShaderConstants ( )
{
if ( mShader . isValid ( ) )
{
mShader - > getReloadSignal ( ) . remove ( this , & ProbeShaderConstants : : _onShaderReload ) ;
mShader = NULL ;
}
}
void ProbeShaderConstants : : init ( GFXShader * shader )
{
if ( mShader . getPointer ( ) ! = shader )
{
if ( mShader . isValid ( ) )
mShader - > getReloadSignal ( ) . remove ( this , & ProbeShaderConstants : : _onShaderReload ) ;
mShader = shader ;
mShader - > getReloadSignal ( ) . notify ( this , & ProbeShaderConstants : : _onShaderReload ) ;
}
2019-04-10 17:54:46 +00:00
2019-01-26 08:05:18 +00:00
//Reflection Probes
mProbePositionSC = shader - > getShaderConstHandle ( ShaderGenVars : : probePosition ) ;
2019-04-03 05:13:58 +00:00
mProbeRefPosSC = shader - > getShaderConstHandle ( ShaderGenVars : : probeRefPos ) ;
2019-01-26 08:05:18 +00:00
mProbeBoxMinSC = shader - > getShaderConstHandle ( ShaderGenVars : : probeBoxMin ) ;
mProbeBoxMaxSC = shader - > getShaderConstHandle ( ShaderGenVars : : probeBoxMax ) ;
2019-04-03 05:13:58 +00:00
mWorldToObjArraySC = shader - > getShaderConstHandle ( ShaderGenVars : : worldToObjArray ) ;
mProbeConfigDataSC = shader - > getShaderConstHandle ( ShaderGenVars : : probeConfigData ) ;
mProbeSpecularCubemapSC = shader - > getShaderConstHandle ( ShaderGenVars : : specularCubemapAR ) ;
mProbeIrradianceCubemapSC = shader - > getShaderConstHandle ( ShaderGenVars : : irradianceCubemapAR ) ;
2019-01-26 08:05:18 +00:00
mProbeCountSC = shader - > getShaderConstHandle ( ShaderGenVars : : probeCount ) ;
2019-04-08 04:57:05 +00:00
mSkylightSpecularMap = shader - > getShaderConstHandle ( ShaderGenVars : : skylightPrefilterMap ) ;
2019-04-03 05:13:58 +00:00
mSkylightIrradMap = shader - > getShaderConstHandle ( ShaderGenVars : : skylightIrradMap ) ;
mHasSkylight = shader - > getShaderConstHandle ( ShaderGenVars : : hasSkylight ) ;
2019-01-26 08:05:18 +00:00
mInit = true ;
}
void ProbeShaderConstants : : _onShaderReload ( )
{
if ( mShader . isValid ( ) )
init ( mShader ) ;
}
//
//
2018-09-17 03:15:07 +00:00
RenderProbeMgr : : RenderProbeMgr ( )
2019-01-26 08:05:18 +00:00
: RenderBinManager ( RenderPassManager : : RIT_Probes , 1.0f , 1.0f ) ,
mLastShader ( nullptr ) ,
2019-04-22 20:39:55 +00:00
mLastConstants ( nullptr ) ,
mProbesDirty ( false )
2018-09-17 03:15:07 +00:00
{
2019-02-11 06:17:53 +00:00
mEffectiveProbeCount = 0 ;
2019-02-13 22:56:28 +00:00
mMipCount = 0 ;
2019-02-11 06:17:53 +00:00
mProbeArrayEffect = nullptr ;
2019-02-13 22:56:28 +00:00
smProbeManager = this ;
2019-03-24 23:18:44 +00:00
mCubeMapCount = 0 ;
for ( U32 i = 0 ; i < PROBE_MAX_COUNT ; i + + )
{
mCubeMapSlots [ i ] = false ;
}
2018-09-17 03:15:07 +00:00
}
RenderProbeMgr : : RenderProbeMgr ( RenderInstType riType , F32 renderOrder , F32 processAddOrder )
: RenderBinManager ( riType , renderOrder , processAddOrder )
{
}
2019-02-20 22:59:58 +00:00
RenderProbeMgr : : ~ RenderProbeMgr ( )
2019-02-14 06:35:22 +00:00
{
2019-02-20 22:59:58 +00:00
mLastShader = NULL ;
mLastConstants = NULL ;
for ( ProbeConstantMap : : Iterator i = mConstantLookup . begin ( ) ; i ! = mConstantLookup . end ( ) ; i + + )
{
if ( i - > value )
SAFE_DELETE ( i - > value ) ;
}
mConstantLookup . clear ( ) ;
}
2019-02-14 06:35:22 +00:00
2019-03-24 23:18:44 +00:00
bool RenderProbeMgr : : onAdd ( )
{
if ( ! Parent : : onAdd ( ) )
return false ;
mIrradianceArray = GFXCubemapArrayHandle ( GFX - > createCubemapArray ( ) ) ;
mPrefilterArray = GFXCubemapArrayHandle ( GFX - > createCubemapArray ( ) ) ;
//pre-allocate a few slots
mIrradianceArray - > init ( PROBE_ARRAY_SLOT_BUFFER_SIZE , PROBE_IRRAD_SIZE , PROBE_FORMAT ) ;
mPrefilterArray - > init ( PROBE_ARRAY_SLOT_BUFFER_SIZE , PROBE_PREFILTER_SIZE , PROBE_FORMAT ) ;
mCubeSlotCount = PROBE_ARRAY_SLOT_BUFFER_SIZE ;
//create our own default default skylight
mDefaultSkyLight = new ProbeRenderInst ;
mDefaultSkyLight - > mProbeShapeType = ProbeRenderInst : : Skylight ;
if ( ! mDefaultSkyLight - > mIrradianceCubemap . set ( " core/art/pbr/default_irradiance.dds " ) )
{
Con : : errorf ( " RenderProbeMgr::onAdd: Failed to load default irradiance cubemap " ) ;
return false ;
}
if ( ! mDefaultSkyLight - > mPrefilterCubemap . set ( " core/art/pbr/default_prefilter.dds " ) )
{
Con : : errorf ( " RenderProbeMgr::onAdd: Failed to load default prefilter cubemap " ) ;
return false ;
}
return true ;
}
2019-02-20 22:59:58 +00:00
void RenderProbeMgr : : onRemove ( )
{
2019-02-14 06:35:22 +00:00
Parent : : onRemove ( ) ;
}
2019-02-20 22:59:58 +00:00
2018-09-17 03:15:07 +00:00
void RenderProbeMgr : : initPersistFields ( )
{
Parent : : initPersistFields ( ) ;
}
void RenderProbeMgr : : addElement ( RenderInst * inst )
{
// If this instance is translucent handle it in RenderTranslucentMgr
2018-10-07 22:32:23 +00:00
//if (inst->translucentSort)
2018-09-17 03:15:07 +00:00
return ;
//AssertFatal(inst->defaultKey != 0, "RenderMeshMgr::addElement() - Got null sort key... did you forget to set it?");
2018-10-07 22:32:23 +00:00
/*internalAddElement(inst);
2018-09-17 03:15:07 +00:00
ProbeRenderInst * probeInst = static_cast < ProbeRenderInst * > ( inst ) ;
if ( probeInst - > mIsSkylight )
{
addSkylightProbe ( probeInst ) ;
}
else
{
if ( probeInst - > mProbeShapeType = = ProbeInfo : : Sphere )
addSphereReflectionProbe ( probeInst ) ;
else
addConvexReflectionProbe ( probeInst ) ;
2018-10-07 22:32:23 +00:00
} */
2018-09-17 03:15:07 +00:00
}
2019-01-26 08:05:18 +00:00
void RenderProbeMgr : : registerProbe ( U32 probeIdx )
{
//Mostly for consolidation, but also lets us sanity check or prep any other data we need for rendering this in one place at time of flagging for render
if ( probeIdx > = ProbeRenderInst : : all . size ( ) )
return ;
mRegisteredProbes . push_back_unique ( probeIdx ) ;
2019-02-11 06:17:53 +00:00
2019-03-26 04:17:53 +00:00
if ( ! ProbeRenderInst : : all [ probeIdx ] - > mIsSkylight )
2019-03-24 23:18:44 +00:00
{
2019-03-26 04:17:53 +00:00
const U32 cubeIndex = _findNextEmptyCubeSlot ( ) ;
if ( cubeIndex = = INVALID_CUBE_SLOT )
{
Con : : warnf ( " RenderProbeMgr::addProbe: Invalid cubemap slot. " ) ;
return ;
}
2019-03-24 23:18:44 +00:00
2019-03-26 04:17:53 +00:00
//check if we need to resize the cubemap array
if ( cubeIndex > = mCubeSlotCount )
{
//alloc temp array handles
GFXCubemapArrayHandle irr = GFXCubemapArrayHandle ( GFX - > createCubemapArray ( ) ) ;
GFXCubemapArrayHandle prefilter = GFXCubemapArrayHandle ( GFX - > createCubemapArray ( ) ) ;
2019-03-24 23:18:44 +00:00
2019-03-26 04:17:53 +00:00
irr - > init ( mCubeSlotCount + PROBE_ARRAY_SLOT_BUFFER_SIZE , PROBE_IRRAD_SIZE , PROBE_FORMAT ) ;
prefilter - > init ( mCubeSlotCount + PROBE_ARRAY_SLOT_BUFFER_SIZE , PROBE_PREFILTER_SIZE , PROBE_FORMAT ) ;
2019-03-24 23:18:44 +00:00
2019-03-26 04:17:53 +00:00
mIrradianceArray - > copyTo ( irr ) ;
mPrefilterArray - > copyTo ( prefilter ) ;
2019-03-24 23:18:44 +00:00
2019-03-26 04:17:53 +00:00
//assign the temp handles to the new ones, this will destroy the old ones as well
mIrradianceArray = irr ;
mPrefilterArray = prefilter ;
2019-03-24 23:18:44 +00:00
2019-03-26 04:17:53 +00:00
mCubeSlotCount + = PROBE_ARRAY_SLOT_BUFFER_SIZE ;
}
2019-03-24 23:18:44 +00:00
2019-03-26 04:17:53 +00:00
ProbeRenderInst : : all [ probeIdx ] - > mCubemapIndex = cubeIndex ;
//mark cubemap slot as taken
mCubeMapSlots [ cubeIndex ] = true ;
mCubeMapCount + + ;
Con : : warnf ( " RenderProbeMgr::registerProbe: Registered probe %u to cubeIndex %u " , probeIdx , cubeIndex ) ;
}
2019-03-24 23:18:44 +00:00
2019-02-11 06:17:53 +00:00
//rebuild our probe data
2019-02-17 09:47:40 +00:00
_setupStaticParameters ( ) ;
2019-02-11 06:17:53 +00:00
}
void RenderProbeMgr : : unregisterProbe ( U32 probeIdx )
{
//Mostly for consolidation, but also lets us sanity check or prep any other data we need for rendering this in one place at time of flagging for render
if ( probeIdx > = ProbeRenderInst : : all . size ( ) )
return ;
mRegisteredProbes . remove ( probeIdx ) ;
2019-03-24 23:18:44 +00:00
if ( ProbeRenderInst : : all [ probeIdx ] - > mCubemapIndex = = INVALID_CUBE_SLOT )
return ;
//mark cubemap slot as available now
mCubeMapSlots [ ProbeRenderInst : : all [ probeIdx ] - > mCubemapIndex ] = false ;
mCubeMapCount - - ;
2019-02-11 06:17:53 +00:00
//rebuild our probe data
2019-02-17 09:47:40 +00:00
_setupStaticParameters ( ) ;
2019-01-26 08:05:18 +00:00
}
2019-02-08 07:35:35 +00:00
//
//
PostEffect * RenderProbeMgr : : getProbeArrayEffect ( )
{
if ( ! mProbeArrayEffect )
2019-02-11 06:17:53 +00:00
{
2019-02-08 07:35:35 +00:00
mProbeArrayEffect = dynamic_cast < PostEffect * > ( Sim : : findObject ( " reflectionProbeArrayPostFX " ) ) ;
2019-02-11 06:17:53 +00:00
if ( ! mProbeArrayEffect )
return nullptr ;
}
2019-02-08 07:35:35 +00:00
return mProbeArrayEffect ;
}
2018-09-17 03:15:07 +00:00
//remove
//Con::setIntVariable("lightMetrics::activeReflectionProbes", mReflectProbeBin.size());
//Con::setIntVariable("lightMetrics::culledReflectProbes", 0/*mNumLightsCulled*/);
//
2019-02-13 22:56:28 +00:00
void RenderProbeMgr : : updateProbes ( )
{
2019-04-22 20:39:55 +00:00
mProbesDirty = true ;
2019-02-13 22:56:28 +00:00
}
2019-02-08 07:35:35 +00:00
void RenderProbeMgr : : _setupStaticParameters ( )
{
2019-02-11 06:17:53 +00:00
//Array rendering
U32 probeCount = ProbeRenderInst : : all . size ( ) ;
mEffectiveProbeCount = 0 ;
2019-02-13 22:56:28 +00:00
mMipCount = 0 ;
2019-02-11 06:17:53 +00:00
2019-02-14 06:35:22 +00:00
if ( probePositionsData . size ( ) ! = MAXPROBECOUNT )
{
probePositionsData . setSize ( MAXPROBECOUNT ) ;
2019-02-19 14:58:02 +00:00
probeRefPositionsData . setSize ( MAXPROBECOUNT ) ;
2019-02-14 06:35:22 +00:00
probeWorldToObjData . setSize ( MAXPROBECOUNT ) ;
probeBBMinData . setSize ( MAXPROBECOUNT ) ;
probeBBMaxData . setSize ( MAXPROBECOUNT ) ;
2019-02-17 09:47:40 +00:00
probeConfigData . setSize ( MAXPROBECOUNT ) ;
2019-02-14 06:35:22 +00:00
}
probePositionsData . fill ( Point4F : : Zero ) ;
2019-02-19 14:58:02 +00:00
probeRefPositionsData . fill ( Point4F : : Zero ) ;
2019-02-14 06:35:22 +00:00
probeWorldToObjData . fill ( MatrixF : : Identity ) ;
probeBBMinData . fill ( Point4F : : Zero ) ;
probeBBMaxData . fill ( Point4F : : Zero ) ;
2019-02-17 09:47:40 +00:00
probeConfigData . fill ( Point4F : : Zero ) ;
2019-02-12 07:10:30 +00:00
2019-02-13 22:56:28 +00:00
cubeMaps . clear ( ) ;
irradMaps . clear ( ) ;
2019-03-25 05:06:08 +00:00
Vector < U32 > cubemapIdxes ;
2019-02-12 07:10:30 +00:00
2019-03-24 23:18:44 +00:00
if ( probeCount ! = 0 & & ProbeRenderInst : : all [ 0 ] - > mPrefilterCubemap ! = nullptr )
{
//Get our mipCount
mMipCount = ProbeRenderInst : : all [ 0 ] - > mPrefilterCubemap . getPointer ( ) - > getMipMapLevels ( ) ;
}
else
{
mMipCount = 1 ;
}
2019-02-11 06:17:53 +00:00
for ( U32 i = 0 ; i < probeCount ; i + + )
{
if ( mEffectiveProbeCount > = MAXPROBECOUNT )
break ;
2019-02-14 06:35:22 +00:00
const ProbeRenderInst & curEntry = * ProbeRenderInst : : all [ i ] ;
if ( ! curEntry . mIsEnabled )
2019-02-11 06:17:53 +00:00
continue ;
2019-04-16 04:11:18 +00:00
if ( curEntry . mProbeShapeType = = ProbeRenderInst : : ProbeShapeType : : Skylight | | curEntry . mIsSkylight )
2019-03-24 23:18:44 +00:00
{
skylightPos = curEntry . getPosition ( ) ;
skylightPrefilterMap = curEntry . mPrefilterCubemap ;
skylightIrradMap = curEntry . mIrradianceCubemap ;
hasSkylight = true ;
2019-02-11 06:17:53 +00:00
continue ;
2019-03-24 23:18:44 +00:00
}
2019-02-11 06:17:53 +00:00
//Setup
2019-02-19 14:58:02 +00:00
Point3F probePos = curEntry . getPosition ( ) ;
Point3F refPos = curEntry . getPosition ( ) + curEntry . mProbeRefOffset ;
2019-02-14 06:35:22 +00:00
probePositionsData [ mEffectiveProbeCount ] = Point4F ( probePos . x , probePos . y , probePos . z , 0 ) ;
2019-02-19 14:58:02 +00:00
probeRefPositionsData [ mEffectiveProbeCount ] = Point4F ( refPos . x , refPos . y , refPos . z , 0 ) ;
2019-02-11 06:17:53 +00:00
2019-03-18 09:09:34 +00:00
probeWorldToObjData [ mEffectiveProbeCount ] = curEntry . getTransform ( ) ;
2019-03-26 11:48:56 +00:00
Point3F bbMin = refPos - curEntry . mProbeRefScale / 2 * curEntry . getTransform ( ) . getScale ( ) ;
Point3F bbMax = refPos + curEntry . mProbeRefScale / 2 * curEntry . getTransform ( ) . getScale ( ) ;
2019-02-19 14:58:02 +00:00
probeBBMinData [ mEffectiveProbeCount ] = Point4F ( bbMin . x , bbMin . y , bbMin . z , 0 ) ;
probeBBMaxData [ mEffectiveProbeCount ] = Point4F ( bbMax . x , bbMax . y , bbMax . z , 0 ) ;
2019-02-11 06:17:53 +00:00
2019-03-02 10:48:07 +00:00
probeConfigData [ mEffectiveProbeCount ] = Point4F ( curEntry . mProbeShapeType ,
2019-02-17 09:47:40 +00:00
curEntry . mRadius ,
2019-03-22 04:47:01 +00:00
curEntry . mAtten ,
2019-03-25 05:06:08 +00:00
curEntry . mCubemapIndex ) ;
cubeMaps . push_back ( curEntry . mPrefilterCubemap ) ;
irradMaps . push_back ( curEntry . mIrradianceCubemap ) ;
2019-02-11 06:17:53 +00:00
2019-03-25 05:06:08 +00:00
cubemapIdxes . push_back ( i ) ;
2019-02-11 06:17:53 +00:00
mEffectiveProbeCount + + ;
}
2019-04-22 20:39:55 +00:00
mProbesDirty = false ;
2019-02-08 07:35:35 +00:00
}
2019-03-24 23:18:44 +00:00
void RenderProbeMgr : : updateProbeTexture ( ProbeRenderInst * probe )
{
2019-03-26 04:17:53 +00:00
//We don't stuff skylights into the array, so we can just skip out on this if it's a skylight
if ( probe - > mIsSkylight )
return ;
2019-03-24 23:18:44 +00:00
S32 probeIdx = ProbeRenderInst : : all . find_next ( probe ) ;
if ( probeIdx ! = - 1 ) //i mean, the opposite shouldn't even be possible
updateProbeTexture ( probeIdx ) ;
}
void RenderProbeMgr : : updateProbeTexture ( U32 probeIdx )
{
if ( probeIdx > = ProbeRenderInst : : all . size ( ) )
return ;
const U32 cubeIndex = ProbeRenderInst : : all [ probeIdx ] - > mCubemapIndex ;
mIrradianceArray - > updateTexture ( ProbeRenderInst : : all [ probeIdx ] - > mIrradianceCubemap , cubeIndex ) ;
mPrefilterArray - > updateTexture ( ProbeRenderInst : : all [ probeIdx ] - > mPrefilterCubemap , cubeIndex ) ;
2019-03-26 04:17:53 +00:00
Con : : warnf ( " UpdatedProbeTexture - probeIdx: %u on cubeIndex %u, Irrad validity: %d, Prefilter validity: %d " , probeIdx , cubeIndex ,
ProbeRenderInst : : all [ probeIdx ] - > mIrradianceCubemap - > isInitialized ( ) , ProbeRenderInst : : all [ probeIdx ] - > mPrefilterCubemap - > isInitialized ( ) ) ;
2019-03-24 23:18:44 +00:00
}
2018-09-17 03:15:07 +00:00
void RenderProbeMgr : : _setupPerFrameParameters ( const SceneRenderState * state )
{
PROFILE_SCOPE ( RenderProbeMgr_SetupPerFrameParameters ) ;
2019-01-26 08:05:18 +00:00
}
ProbeShaderConstants * RenderProbeMgr : : getProbeShaderConstants ( GFXShaderConstBuffer * buffer )
{
if ( ! buffer )
return NULL ;
PROFILE_SCOPE ( ProbeManager_GetProbeShaderConstants ) ;
GFXShader * shader = buffer - > getShader ( ) ;
// Check to see if this is the same shader, we'll get hit repeatedly by
// the same one due to the render bin loops.
if ( mLastShader . getPointer ( ) ! = shader )
2018-09-17 03:15:07 +00:00
{
2019-01-26 08:05:18 +00:00
ProbeConstantMap : : Iterator iter = mConstantLookup . find ( shader ) ;
if ( iter ! = mConstantLookup . end ( ) )
{
2019-02-14 06:35:22 +00:00
mLastConstants = iter - > value ;
2019-01-26 08:05:18 +00:00
}
else
{
ProbeShaderConstants * psc = new ProbeShaderConstants ( ) ;
mConstantLookup [ shader ] = psc ;
2019-02-14 06:35:22 +00:00
mLastConstants = psc ;
2019-01-26 08:05:18 +00:00
}
// Set our new shader
mLastShader = shader ;
2018-09-17 03:15:07 +00:00
}
2019-01-08 02:34:19 +00:00
2019-01-26 08:05:18 +00:00
// Make sure that our current lighting constants are initialized
2019-02-14 06:35:22 +00:00
if ( mLastConstants & & ! mLastConstants - > mInit )
mLastConstants - > init ( shader ) ;
2019-01-08 02:34:19 +00:00
2019-02-14 06:35:22 +00:00
return mLastConstants ;
2019-01-26 08:05:18 +00:00
}
void RenderProbeMgr : : _update4ProbeConsts ( const SceneData & sgData ,
MatrixSet & matSet ,
2019-04-03 05:13:58 +00:00
ProbeShaderConstants * probeShaderConsts ,
2019-01-26 08:05:18 +00:00
GFXShaderConstBuffer * shaderConsts )
{
PROFILE_SCOPE ( ProbeManager_Update4ProbeConsts ) ;
// Skip over gathering lights if we don't have to!
2019-04-03 05:13:58 +00:00
if ( probeShaderConsts - > mProbePositionSC - > isValid ( ) | |
probeShaderConsts - > mProbeConfigDataSC - > isValid ( ) | |
probeShaderConsts - > mProbeBoxMinSC - > isValid ( ) | |
probeShaderConsts - > mProbeBoxMaxSC - > isValid ( ) | |
probeShaderConsts - > mProbeSpecularCubemapSC - > isValid ( ) | |
probeShaderConsts - > mProbeIrradianceCubemapSC - > isValid ( ) /* && (!ProbeRenderInst::all.empty())*/ )
2019-01-08 02:34:19 +00:00
{
2019-01-26 08:05:18 +00:00
PROFILE_SCOPE ( ProbeManager_Update4ProbeConsts_setProbes ) ;
2019-04-08 04:57:05 +00:00
const U32 MAX_FORWARD_PROBES = 4 ;
static AlignedArray < Point4F > probePositionArray ( MAX_FORWARD_PROBES , sizeof ( Point4F ) ) ;
static AlignedArray < Point4F > probeBoxMinArray ( MAX_FORWARD_PROBES , sizeof ( Point4F ) ) ;
static AlignedArray < Point4F > probeBoxMaxArray ( MAX_FORWARD_PROBES , sizeof ( Point4F ) ) ;
static AlignedArray < Point4F > probeRefPositionArray ( MAX_FORWARD_PROBES , sizeof ( Point4F ) ) ;
static AlignedArray < Point4F > probeConfigArray ( MAX_FORWARD_PROBES , sizeof ( Point4F ) ) ;
Vector < MatrixF > probeWorldToObjArray ;
probeWorldToObjArray . setSize ( MAX_FORWARD_PROBES ) ;
2019-01-26 08:05:18 +00:00
//static AlignedArray<CubemapData> probeCubemap(4, sizeof(CubemapData));
2019-02-17 09:47:40 +00:00
//F32 range;
2019-01-26 08:05:18 +00:00
// Need to clear the buffers so that we don't leak
// lights from previous passes or have NaNs.
2019-04-08 04:57:05 +00:00
dMemset ( probePositionArray . getBuffer ( ) , 0 , probePositionArray . getBufferSize ( ) ) ;
dMemset ( probeBoxMinArray . getBuffer ( ) , 0 , probeBoxMinArray . getBufferSize ( ) ) ;
dMemset ( probeBoxMaxArray . getBuffer ( ) , 0 , probeBoxMaxArray . getBufferSize ( ) ) ;
dMemset ( probeRefPositionArray . getBuffer ( ) , 0 , probeRefPositionArray . getBufferSize ( ) ) ;
dMemset ( probeConfigArray . getBuffer ( ) , 0 , probeConfigArray . getBufferSize ( ) ) ;
2019-01-26 08:05:18 +00:00
matSet . restoreSceneViewProjection ( ) ;
// Gather the data for the first 4 probes.
2019-02-14 06:35:22 +00:00
/*const ProbeRenderInst *probe;
2019-01-26 08:05:18 +00:00
for ( U32 i = 0 ; i < 4 ; i + + )
{
if ( i > = ProbeRenderInst : : all . size ( ) )
break ;
probe = ProbeRenderInst : : all [ i ] ;
if ( ! probe )
continue ;
if ( ! probe - > mIsEnabled )
continue ;
2019-04-03 05:13:58 +00:00
// The light positions and spot directions are
2019-01-26 08:05:18 +00:00
// in SoA order to make optimal use of the GPU.
const Point3F & probePos = probe - > getPosition ( ) ;
probePositions [ i ] . x = probePos . x ;
probePositions [ i ] . y = probePos . y ;
probePositions [ i ] . z = probePos . z ;
probeRadius [ i ] = probe - > mRadius ;
const Point3F & minExt = probe - > mBounds . minExtents ;
probeBoxMins [ i ] . x = minExt . x ;
probeBoxMins [ i ] . y = minExt . y ;
probeBoxMins [ i ] . z = minExt . z ;
const Point3F & maxExt = probe - > mBounds . maxExtents ;
probeBoxMaxs [ i ] . x = maxExt . x ;
probeBoxMaxs [ i ] . y = maxExt . y ;
probeBoxMaxs [ i ] . z = maxExt . z ;
probeIsSphere [ i ] = probe - > mProbeShapeType = = ProbeRenderInst : : Sphere ? 1.0 : 0.0 ;
Point3F localProbePos ;
worldToCameraXfm . mulP ( probe - > getPosition ( ) , & localProbePos ) ;
probeLocalPositions [ i ] . x = localProbePos . x ;
probeLocalPositions [ i ] . y = localProbePos . y ;
probeLocalPositions [ i ] . z = localProbePos . z ;
if ( probe - > mCubemap & & ! probe - > mCubemap . isNull ( ) )
{
S32 samplerReg = probeCubemapSC - > getSamplerRegister ( ) ;
if ( samplerReg ! = - 1 )
GFX - > setCubeTexture ( samplerReg + i , probe - > mCubemap . getPointer ( ) ) ;
}
2019-02-14 06:35:22 +00:00
} */
2019-04-03 05:13:58 +00:00
//Array rendering
U32 probeCount = ProbeRenderInst : : all . size ( ) ;
2019-04-16 16:47:21 +00:00
//mEffectiveProbeCount = 0;
//mMipCount = 0;
2019-04-03 05:13:58 +00:00
2019-04-08 04:57:05 +00:00
/*if (probePositionArray.size() != MAX_FORWARD_PROBES)
2019-02-14 06:35:22 +00:00
{
2019-04-08 04:57:05 +00:00
probePositionArray . setSize ( MAX_FORWARD_PROBES ) ;
probeBoxMinArray . setSize ( MAX_FORWARD_PROBES ) ;
probeBoxMaxArray . setSize ( MAX_FORWARD_PROBES ) ;
probeBoxMaxArray . setSize ( MAX_FORWARD_PROBES ) ;
probeRefPositionArray . setSize ( MAX_FORWARD_PROBES ) ;
probeConfigArray . setSize ( MAX_FORWARD_PROBES ) ;
probeWorldToObjArray . setSize ( MAX_FORWARD_PROBES ) ;
} */
2019-02-14 06:35:22 +00:00
2019-04-08 04:57:05 +00:00
//cubeMaps.clear();
//irradMaps.clear();
//Vector<U32> cubemapIdxes;
2019-02-14 06:35:22 +00:00
2019-04-03 05:13:58 +00:00
U32 effectiveProbeCount = 0 ;
bool hasSkylight = false ;
for ( U32 i = 0 ; i < probeCount ; i + + )
{
if ( effectiveProbeCount > = 4 )
break ;
2019-02-14 06:35:22 +00:00
2019-04-03 05:13:58 +00:00
const ProbeRenderInst & curEntry = * ProbeRenderInst : : all [ i ] ;
if ( ! curEntry . mIsEnabled )
continue ;
2019-02-14 06:35:22 +00:00
2019-04-03 05:13:58 +00:00
if ( curEntry . mIsSkylight )
{
2019-04-08 04:57:05 +00:00
if ( curEntry . mPrefilterCubemap . isValid ( ) & & curEntry . mPrefilterCubemap . isValid ( ) )
{
GFX - > setCubeTexture ( probeShaderConsts - > mSkylightSpecularMap - > getSamplerRegister ( ) , curEntry . mPrefilterCubemap ) ;
GFX - > setCubeTexture ( probeShaderConsts - > mSkylightIrradMap - > getSamplerRegister ( ) , curEntry . mIrradianceCubemap ) ;
shaderConsts - > setSafe ( probeShaderConsts - > mHasSkylight , 1.0f ) ;
hasSkylight = true ;
continue ;
}
}
else
{
/*probePositions[effectiveProbeCount] = curEntry.getPosition();
probeRefPositions [ effectiveProbeCount ] = curEntry . mProbeRefOffset ;
probeWorldToObj [ effectiveProbeCount ] = curEntry . getTransform ( ) ;
probeBBMin [ effectiveProbeCount ] = curEntry . mBounds . minExtents ;
probeBBMax [ effectiveProbeCount ] = curEntry . mBounds . maxExtents ;
probeConfig [ effectiveProbeCount ] = Point4F ( curEntry . mProbeShapeType ,
curEntry . mRadius ,
curEntry . mAtten ,
curEntry . mCubemapIndex ) ; */
2019-04-03 05:13:58 +00:00
}
2019-04-08 04:57:05 +00:00
effectiveProbeCount + + ;
}
2019-04-03 05:13:58 +00:00
2019-04-08 04:57:05 +00:00
shaderConsts - > setSafe ( probeShaderConsts - > mProbeCountSC , ( float ) effectiveProbeCount ) ;
2019-04-03 05:13:58 +00:00
2019-04-08 04:57:05 +00:00
shaderConsts - > setSafe ( probeShaderConsts - > mProbePositionSC , probePositionArray ) ;
shaderConsts - > setSafe ( probeShaderConsts - > mProbeRefPosSC , probeRefPositionArray ) ;
2019-04-03 05:13:58 +00:00
2019-04-08 04:57:05 +00:00
shaderConsts - > set ( probeShaderConsts - > mWorldToObjArraySC , probeWorldToObjArray . address ( ) , effectiveProbeCount , GFXSCT_Float4x4 ) ;
2019-02-14 06:35:22 +00:00
2019-04-08 04:57:05 +00:00
shaderConsts - > setSafe ( probeShaderConsts - > mProbeBoxMinSC , probeBoxMinArray ) ;
shaderConsts - > setSafe ( probeShaderConsts - > mProbeBoxMaxSC , probeBoxMaxArray ) ;
shaderConsts - > setSafe ( probeShaderConsts - > mProbeConfigDataSC , probeConfigArray ) ;
2019-04-26 18:33:28 +00:00
//GFX->setCubeArrayTexture(probeShaderConsts->mProbeSpecularCubemapSC->getSamplerRegister(), mPrefilterArray);
//GFX->setCubeArrayTexture(probeShaderConsts->mProbeIrradianceCubemapSC->getSamplerRegister(), mIrradianceArray);
2019-01-26 08:05:18 +00:00
2019-04-03 05:13:58 +00:00
if ( ! hasSkylight )
2019-04-08 04:57:05 +00:00
shaderConsts - > setSafe ( probeShaderConsts - > mHasSkylight , 0.0f ) ;
2019-01-08 02:34:19 +00:00
}
2019-04-03 05:13:58 +00:00
/*else
2019-01-26 08:05:18 +00:00
{
if ( probeCubemapSC - > isValid ( ) )
{
for ( U32 i = 0 ; i < 4 ; + + i )
GFX - > setCubeTexture ( probeCubemapSC - > getSamplerRegister ( ) + i , NULL ) ;
}
2019-04-03 05:13:58 +00:00
} */
2019-01-26 08:05:18 +00:00
}
void RenderProbeMgr : : setProbeInfo ( ProcessedMaterial * pmat ,
const Material * mat ,
const SceneData & sgData ,
const SceneRenderState * state ,
U32 pass ,
GFXShaderConstBuffer * shaderConsts )
{
// Skip this if we're rendering from the deferred bin.
if ( sgData . binType = = SceneData : : DeferredBin )
return ;
// if (mRegisteredProbes.empty())
// return;
PROFILE_SCOPE ( ProbeManager_setProbeInfo ) ;
ProbeShaderConstants * psc = getProbeShaderConstants ( shaderConsts ) ;
// 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.
//
// This is a known crash bug that can occur if materials/shaders
// 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.
2019-04-03 05:13:58 +00:00
_update4ProbeConsts ( sgData , matSet , psc , shaderConsts ) ;
2018-09-17 03:15:07 +00:00
}
//-----------------------------------------------------------------------------
// render objects
//-----------------------------------------------------------------------------
void RenderProbeMgr : : render ( SceneRenderState * state )
{
2019-02-11 06:17:53 +00:00
//PROFILE_SCOPE(RenderProbeMgr_render);
if ( getProbeArrayEffect ( ) = = nullptr )
return ;
2018-09-17 03:15:07 +00:00
2019-04-22 20:39:55 +00:00
if ( mProbesDirty )
_setupStaticParameters ( ) ;
2019-02-14 06:35:22 +00:00
2018-09-17 03:15:07 +00:00
// Early out if nothing to draw.
2019-04-16 04:11:18 +00:00
if ( ! RenderProbeMgr : : smRenderReflectionProbes | | ! state - > isDiffusePass ( ) | | ( ! ProbeRenderInst : : all . size ( ) | | mEffectiveProbeCount = = 0 | | mCubeMapCount ! = 0 ) & & ! hasSkylight )
2019-02-13 22:56:28 +00:00
{
2019-03-24 23:18:44 +00:00
getProbeArrayEffect ( ) - > setSkip ( true ) ;
return ;
2019-02-13 22:56:28 +00:00
}
2019-02-11 06:17:53 +00:00
2018-09-17 03:15:07 +00:00
GFXTransformSaver saver ;
2018-10-24 23:27:43 +00:00
GFXDEBUGEVENT_SCOPE ( RenderProbeMgr_render , ColorI : : WHITE ) ;
2018-09-17 03:15:07 +00:00
// Initialize and set the per-frame parameters after getting
// the vector light material as we use lazy creation.
2019-02-11 06:17:53 +00:00
//_setupPerFrameParameters(state);
2019-04-16 04:11:18 +00:00
//Visualization
String useDebugAtten = Con : : getVariable ( " $Probes::showAttenuation " , " 0 " ) ;
mProbeArrayEffect - > setShaderMacro ( " DEBUGVIZ_ATTENUATION " , useDebugAtten ) ;
String useDebugSpecCubemap = Con : : getVariable ( " $Probes::showSpecularCubemaps " , " 0 " ) ;
mProbeArrayEffect - > setShaderMacro ( " DEBUGVIZ_SPECCUBEMAP " , useDebugSpecCubemap ) ;
String useDebugDiffuseCubemap = Con : : getVariable ( " $Probes::showDiffuseCubemaps " , " 0 " ) ;
mProbeArrayEffect - > setShaderMacro ( " DEBUGVIZ_DIFFCUBEMAP " , useDebugDiffuseCubemap ) ;
String useDebugContrib = Con : : getVariable ( " $Probes::showProbeContrib " , " 0 " ) ;
mProbeArrayEffect - > setShaderMacro ( " DEBUGVIZ_CONTRIB " , useDebugContrib ) ;
2019-02-13 22:56:28 +00:00
2019-01-08 02:34:19 +00:00
//Array rendering
2019-02-17 09:47:40 +00:00
//U32 probeCount = ProbeRenderInst::all.size();
2019-01-08 02:34:19 +00:00
2019-03-24 23:18:44 +00:00
mProbeArrayEffect - > setShaderConst ( " $hasSkylight " , ( float ) hasSkylight ) ;
if ( hasSkylight )
{
mProbeArrayEffect - > setCubemapTexture ( 6 , skylightPrefilterMap ) ;
mProbeArrayEffect - > setCubemapTexture ( 7 , skylightIrradMap ) ;
}
2019-04-16 04:11:18 +00:00
mProbeArrayEffect - > setShaderConst ( " $numProbes " , ( float ) mEffectiveProbeCount ) ;
mProbeArrayEffect - > setShaderConst ( " $cubeMips " , ( float ) mMipCount ) ;
2019-02-11 06:17:53 +00:00
if ( mEffectiveProbeCount ! = 0 )
2018-11-29 00:12:12 +00:00
{
2019-03-24 23:18:44 +00:00
mProbeArrayEffect - > setCubemapArrayTexture ( 4 , mPrefilterArray ) ;
mProbeArrayEffect - > setCubemapArrayTexture ( 5 , mIrradianceArray ) ;
2019-02-12 07:10:30 +00:00
2019-02-17 09:47:40 +00:00
if ( useDebugContrib = = String ( " 1 " ) )
{
MRandomLCG RandomGen ;
RandomGen . setSeed ( mEffectiveProbeCount ) ;
//also set up some colors
Vector < Point4F > contribColors ;
contribColors . setSize ( MAXPROBECOUNT ) ;
for ( U32 i = 0 ; i < mEffectiveProbeCount ; i + + )
{
2019-02-22 14:12:03 +00:00
//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 )
contribColors [ i ] = Point4F ( 1 , 0 , 0 , 1 ) ;
else if ( i = = 1 )
contribColors [ i ] = Point4F ( 0 , 1 , 0 , 1 ) ;
else if ( i = = 2 )
contribColors [ i ] = Point4F ( 0 , 0 , 1 , 1 ) ;
else
2019-04-16 04:11:18 +00:00
contribColors [ i ] = Point4F ( RandomGen . randF ( 0 , 1 ) , RandomGen . randF ( 0 , 1 ) , RandomGen . randF ( 0 , 1 ) , 1 ) ;
2019-02-17 09:47:40 +00:00
}
mProbeArrayEffect - > setShaderConst ( " $probeContribColors " , contribColors ) ;
}
2019-02-12 07:10:30 +00:00
2019-02-14 06:35:22 +00:00
mProbeArrayEffect - > setShaderConst ( " $inProbePosArray " , probePositionsData ) ;
2019-02-19 14:58:02 +00:00
mProbeArrayEffect - > setShaderConst ( " $inRefPosArray " , probeRefPositionsData ) ;
2019-02-14 06:35:22 +00:00
mProbeArrayEffect - > setShaderConst ( " $worldToObjArray " , probeWorldToObjData ) ;
mProbeArrayEffect - > setShaderConst ( " $bbMinArray " , probeBBMinData ) ;
mProbeArrayEffect - > setShaderConst ( " $bbMaxArray " , probeBBMaxData ) ;
2019-02-17 09:47:40 +00:00
mProbeArrayEffect - > setShaderConst ( " $probeConfigData " , probeConfigData ) ;
2018-09-17 03:15:07 +00:00
}
2019-02-11 06:17:53 +00:00
// Make sure the effect is gonna render.
getProbeArrayEffect ( ) - > setSkip ( false ) ;
2018-09-17 03:15:07 +00:00
2019-02-11 06:17:53 +00:00
//PROFILE_END();
2019-01-26 08:05:18 +00:00
}
2019-02-14 06:35:22 +00:00
void RenderProbeMgr : : bakeProbe ( ReflectionProbe * probe )
2019-01-26 08:05:18 +00:00
{
2019-02-14 06:35:22 +00:00
GFXDEBUGEVENT_SCOPE ( RenderProbeMgr_Bake , ColorI : : WHITE ) ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
Con : : warnf ( " RenderProbeMgr::bakeProbe() - Beginning bake! " ) ;
U32 startMSTime = Platform : : getRealMilliseconds ( ) ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
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 ) ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
ReflectionProbe * clientProbe = static_cast < ReflectionProbe * > ( probe - > getClientObject ( ) ) ;
2019-01-26 08:05:18 +00:00
2019-03-02 10:48:07 +00:00
if ( clientProbe = = nullptr )
return ;
2019-02-14 06:35:22 +00:00
String probePrefilterPath = clientProbe - > getPrefilterMapPath ( ) ;
String probeIrradPath = clientProbe - > getIrradianceMapPath ( ) ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
if ( clientProbe - > mReflectionModeType ! = ReflectionProbe : : DynamicCubemap )
{
//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 ;
}
}
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
// Save the current transforms so we can restore
// it for child control rendering below.
GFXTransformSaver saver ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
bool probeRenderState = RenderProbeMgr : : smRenderReflectionProbes ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
F32 farPlane = 1000.0f ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
ReflectorDesc reflDesc ;
reflDesc . texSize = resolution ;
reflDesc . farDist = farPlane ;
reflDesc . detailAdjust = 1 ;
reflDesc . objectTypeMask = - 1 ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
CubeReflector cubeRefl ;
cubeRefl . registerReflector ( probe , & reflDesc ) ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
ReflectParams reflParams ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
//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 ( ) ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
Frustum culler ;
culler . set ( false ,
query . fov ,
( F32 ) resolution / ( F32 ) resolution ,
query . nearPlane ,
query . farPlane ,
query . cameraMatrix ) ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
S32 stereoTarget = GFX - > getCurrentStereoTarget ( ) ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
Point2I maxRes ( 2048 , 2048 ) ; //basically a boundary so we don't go over this and break stuff
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
reflParams . culler = culler ;
reflParams . eyeId = stereoTarget ;
reflParams . query = & query ;
reflParams . startOfUpdateMs = startMSTime ;
reflParams . viewportExtent = maxRes ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
if ( ! renderWithProbes )
RenderProbeMgr : : smRenderReflectionProbes = false ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
cubeRefl . updateReflection ( reflParams ) ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
//Now, save out the maps
//create irridiance cubemap
if ( cubeRefl . getCubemap ( ) )
{
//Just to ensure we're prepped for the generation
clientProbe - > createClientResources ( ) ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
//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 ) ;
}
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
GFXTextureTargetRef renderTarget = GFX - > allocRenderToTextureTarget ( false ) ;
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
IBLUtilities : : GenerateIrradianceMap ( renderTarget , cubeRefl . getCubemap ( ) , clientProbe - > mIrridianceMap - > mCubemap ) ;
IBLUtilities : : GeneratePrefilterMap ( renderTarget , cubeRefl . getCubemap ( ) , prefilterMipLevels , clientProbe - > mPrefilterMap - > mCubemap ) ;
2019-01-26 08:05:18 +00:00
2019-03-25 05:06:08 +00:00
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! " ) ;
2019-02-14 06:35:22 +00:00
IBLUtilities : : SaveCubeMap ( clientProbe - > getIrradianceMapPath ( ) , clientProbe - > mIrridianceMap - > mCubemap ) ;
IBLUtilities : : SaveCubeMap ( clientProbe - > getPrefilterMapPath ( ) , clientProbe - > mPrefilterMap - > mCubemap ) ;
2019-01-26 08:05:18 +00:00
}
else
{
2019-02-14 06:35:22 +00:00
Con : : errorf ( " RenderProbeMgr::bake() - Didn't generate a valid scene capture cubemap, unable to generate prefilter and irradiance maps! " ) ;
2019-01-26 08:05:18 +00:00
}
2019-02-14 06:35:22 +00:00
if ( ! renderWithProbes )
RenderProbeMgr : : smRenderReflectionProbes = probeRenderState ;
cubeRefl . unregisterReflector ( ) ;
U32 endMSTime = Platform : : getRealMilliseconds ( ) ;
F32 diffTime = F32 ( endMSTime - startMSTime ) ;
Con : : warnf ( " RenderProbeMgr::bake() - Finished bake! Took %g milliseconds " , diffTime ) ;
}
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
void RenderProbeMgr : : bakeProbes ( )
{
//TODO: make this just find every probe in the current missionGroup and run the bake on it automagically
}
2019-01-26 08:05:18 +00:00
2019-02-14 06:35:22 +00:00
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 ) ;
2018-10-07 22:32:23 +00:00
}