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"
2019-11-01 00:06:40 +00:00
# include "lighting/advanced/advancedLightBinManager.h" //for ssao
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
//
//
2019-06-04 05:21:52 +00:00
ProbeRenderInst : : ProbeRenderInst ( ) :
mIsEnabled ( true ) ,
2019-01-26 08:05:18 +00:00
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 ) ,
2019-06-04 05:21:52 +00:00
mIsSkylight ( false ) ,
2019-06-13 05:37:12 +00:00
mProbeIdx ( 0 ) ,
mProbeShapeType ( Box )
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-06-28 15:21:50 +00:00
mRefBoxMinSC ( NULL ) ,
mRefBoxMaxSC ( 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 ) ,
2019-05-02 05:05:12 +00:00
mBRDFTextureMap ( NULL ) ,
2019-06-27 05:36:56 +00:00
mSkylightCubemapIdxSC ( NULL ) ,
2019-06-13 05:37:12 +00:00
mWorldToObjArraySC ( 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-06-28 15:21:50 +00:00
mRefBoxMinSC = shader - > getShaderConstHandle ( ShaderGenVars : : refBoxMin ) ;
mRefBoxMaxSC = shader - > getShaderConstHandle ( ShaderGenVars : : refBoxMax ) ;
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-05-02 05:05:12 +00:00
mBRDFTextureMap = shader - > getShaderConstHandle ( ShaderGenVars : : BRDFTextureMap ) ;
2019-06-27 05:36:56 +00:00
mSkylightCubemapIdxSC = shader - > getShaderConstHandle ( ShaderGenVars : : skylightCubemapIdx ) ;
2019-04-03 05:13:58 +00:00
2019-01-26 08:05:18 +00:00
mInit = true ;
}
2019-04-28 23:32:23 +00:00
bool ProbeShaderConstants : : isValid ( )
{
if ( mProbePositionSC - > isValid ( ) | |
mProbeConfigDataSC - > isValid ( ) | |
2019-06-28 15:21:50 +00:00
mRefBoxMinSC - > isValid ( ) | |
mRefBoxMaxSC - > isValid ( ) | |
2019-04-28 23:32:23 +00:00
mProbeSpecularCubemapSC - > isValid ( ) | |
mProbeIrradianceCubemapSC - > isValid ( ) )
return true ;
return false ;
}
2019-01-26 08:05:18 +00:00
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 ) ,
2019-05-08 06:27:51 +00:00
mProbesDirty ( false ) ,
2019-06-13 05:37:12 +00:00
mHasSkylight ( false ) ,
mSkylightCubemapIdx ( - 1 ) ,
mCubeMapCount ( 0 ) ,
mDefaultSkyLight ( nullptr )
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 ;
2020-04-26 21:47:29 +00:00
mCubeSlotCount = PROBE_ARRAY_SLOT_BUFFER_SIZE ;
2019-03-24 23:18:44 +00:00
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 )
2020-04-26 21:47:29 +00:00
{
mCubeMapCount = 0 ;
dMemset ( mCubeMapSlots , false , sizeof ( mCubeMapSlots ) ) ;
mCubeSlotCount = PROBE_ARRAY_SLOT_BUFFER_SIZE ;
mDefaultSkyLight = nullptr ;
mEffectiveProbeCount = 0 ;
mHasSkylight = false ;
mSkylightCubemapIdx = - 1 ;
mLastConstants = nullptr ;
mMipCount = 0 ;
mProbesDirty = false ;
2018-09-17 03:15:07 +00:00
}
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 ;
2019-05-08 06:27:51 +00:00
mDefaultSkyLight - > mIsEnabled = false ;
String defaultIrradMapPath = GFXTextureManager : : getDefaultIrradianceCubemapPath ( ) ;
if ( ! mDefaultSkyLight - > mIrradianceCubemap . set ( defaultIrradMapPath ) )
2019-03-24 23:18:44 +00:00
{
Con : : errorf ( " RenderProbeMgr::onAdd: Failed to load default irradiance cubemap " ) ;
return false ;
}
2019-05-08 06:27:51 +00:00
String defaultPrefilterPath = GFXTextureManager : : getDefaultPrefilterCubemapPath ( ) ;
if ( ! mDefaultSkyLight - > mPrefilterCubemap . set ( defaultPrefilterPath ) )
2019-03-24 23:18:44 +00:00
{
Con : : errorf ( " RenderProbeMgr::onAdd: Failed to load default prefilter cubemap " ) ;
return false ;
}
2019-06-04 05:21:52 +00:00
String brdfTexturePath = GFXTextureManager : : getBRDFTexturePath ( ) ;
2019-06-03 07:47:30 +00:00
if ( ! mBRDFTexture . set ( brdfTexturePath , & GFXTexturePersistentSRGBProfile , " BRDFTexture " ) )
{
Con : : errorf ( " RenderProbeMgr::onAdd: Failed to load BRDF Texture " ) ;
return false ;
2019-06-04 05:21:52 +00:00
}
2019-06-03 07:47:30 +00:00
2019-03-24 23:18:44 +00:00
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-06-05 06:04:47 +00:00
ProbeRenderInst * RenderProbeMgr : : registerProbe ( )
2019-01-26 08:05:18 +00:00
{
2019-07-01 04:04:16 +00:00
mRegisteredProbes . increment ( ) ;
ProbeRenderInst * newProbe = & mRegisteredProbes . last ( ) ;
2019-01-26 08:05:18 +00:00
2019-07-01 04:04:16 +00:00
newProbe - > mProbeIdx = mRegisteredProbes . size ( ) - 1 ;
2019-02-11 06:17:53 +00:00
2019-06-05 06:04:47 +00:00
const U32 cubeIndex = _findNextEmptyCubeSlot ( ) ;
if ( cubeIndex = = INVALID_CUBE_SLOT )
2019-03-24 23:18:44 +00:00
{
2019-06-05 06:04:47 +00:00
Con : : warnf ( " RenderProbeMgr::addProbe: Invalid cubemap slot. " ) ;
return nullptr ;
}
2019-03-24 23:18:44 +00:00
2019-06-05 06:04:47 +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-06-05 06:04:47 +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-06-05 06:04:47 +00:00
mIrradianceArray - > copyTo ( irr ) ;
mPrefilterArray - > copyTo ( prefilter ) ;
2019-03-24 23:18:44 +00:00
2019-06-05 06:04:47 +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-06-05 06:04:47 +00:00
mCubeSlotCount + = PROBE_ARRAY_SLOT_BUFFER_SIZE ;
}
2019-03-24 23:18:44 +00:00
2019-07-01 04:04:16 +00:00
newProbe - > mCubemapIndex = cubeIndex ;
2019-06-05 06:04:47 +00:00
//mark cubemap slot as taken
mCubeMapSlots [ cubeIndex ] = true ;
mCubeMapCount + + ;
2019-03-26 04:17:53 +00:00
2019-06-18 04:48:20 +00:00
# ifdef TORQUE_DEBUG
2019-07-01 04:04:16 +00:00
Con : : warnf ( " RenderProbeMgr::registerProbe: Registered probe %u to cubeIndex %u " , newProbe - > mProbeIdx , cubeIndex ) ;
2019-06-18 04:48:20 +00:00
# endif
2019-03-24 23:18:44 +00:00
2019-06-04 05:21:52 +00:00
mProbesDirty = true ;
2019-07-01 04:04:16 +00:00
return newProbe ;
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
2019-06-04 05:21:52 +00:00
if ( probeIdx > = mRegisteredProbes . size ( ) )
2019-02-11 06:17:53 +00:00
return ;
2019-06-04 05:21:52 +00:00
if ( mRegisteredProbes [ probeIdx ] . mCubemapIndex = = INVALID_CUBE_SLOT )
2019-03-24 23:18:44 +00:00
return ;
//mark cubemap slot as available now
2019-06-04 05:21:52 +00:00
mCubeMapSlots [ mRegisteredProbes [ probeIdx ] . mCubemapIndex ] = false ;
2019-03-24 23:18:44 +00:00
mCubeMapCount - - ;
2019-06-04 05:21:52 +00:00
mRegisteredProbes . erase ( probeIdx ) ;
2019-07-01 04:04:16 +00:00
//recalculate all the probe's indicies just to be sure
for ( U32 i = 0 ; i < mRegisteredProbes . size ( ) ; i + + )
{
2019-07-11 04:41:55 +00:00
mRegisteredProbes [ i ] . mProbeIdx = i ;
2019-07-01 04:04:16 +00:00
}
2019-02-11 06:17:53 +00:00
//rebuild our probe data
2019-06-13 05:37:12 +00:00
mProbesDirty = true ;
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
2019-06-04 05:21:52 +00:00
U32 probeCount = mRegisteredProbes . size ( ) ;
2019-02-11 06:17:53 +00:00
mEffectiveProbeCount = 0 ;
2019-06-13 05:37:12 +00:00
mMipCount = 1 ;
2019-02-11 06:17:53 +00:00
2019-06-05 05:07:46 +00:00
mHasSkylight = false ;
2019-06-05 06:04:47 +00:00
mSkylightCubemapIdx = - 1 ;
2019-06-05 05:07:46 +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 ) ;
2019-06-28 15:21:50 +00:00
refBoxMinData . setSize ( MAXPROBECOUNT ) ;
refBoxMaxData . 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 ) ;
2019-06-28 15:21:50 +00:00
refBoxMinData . fill ( Point4F : : Zero ) ;
refBoxMaxData . fill ( Point4F : : Zero ) ;
2019-06-13 05:37:12 +00:00
probeConfigData . fill ( Point4F ( - 1 , 0 , 0 , 0 ) ) ;
2019-03-24 23:18:44 +00:00
2019-02-11 06:17:53 +00:00
for ( U32 i = 0 ; i < probeCount ; i + + )
{
if ( mEffectiveProbeCount > = MAXPROBECOUNT )
break ;
2019-06-04 05:21:52 +00:00
const ProbeRenderInst & curEntry = mRegisteredProbes [ i ] ;
2019-02-14 06:35:22 +00:00
if ( ! curEntry . mIsEnabled )
2019-02-11 06:17:53 +00:00
continue ;
2019-06-13 05:37:12 +00:00
U32 mips = mRegisteredProbes [ i ] . mPrefilterCubemap . getPointer ( ) - > getMipMapLevels ( ) ;
mMipCount = mips ! = 0 & & mips > = mMipCount ? mips : 0 ;
2019-06-05 06:04:47 +00:00
2019-06-13 05:37:12 +00:00
if ( curEntry . mIsSkylight )
2019-03-24 23:18:44 +00:00
{
2019-06-05 06:04:47 +00:00
mSkylightCubemapIdx = curEntry . mCubemapIndex ;
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-06-28 15:21:50 +00:00
refBoxMinData [ mEffectiveProbeCount ] = Point4F ( bbMin . x , bbMin . y , bbMin . z , 0 ) ;
refBoxMaxData [ 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 ) ;
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-06-13 05:37:12 +00:00
void RenderProbeMgr : : updateProbeTexture ( ProbeRenderInst * probeInfo )
2019-03-24 23:18:44 +00:00
{
2019-06-13 05:37:12 +00:00
if ( probeInfo - > mIrradianceCubemap . isNull ( ) | | ! probeInfo - > mIrradianceCubemap - > isInitialized ( ) )
{
Con : : errorf ( " RenderProbeMgr::updateProbeTexture() - tried to update a probe's texture with an invalid or uninitialized irradiance map! " ) ;
2019-03-26 04:17:53 +00:00
return ;
2019-06-13 05:37:12 +00:00
}
2019-03-26 04:17:53 +00:00
2019-06-13 05:37:12 +00:00
if ( probeInfo - > mPrefilterCubemap . isNull ( ) | | ! probeInfo - > mPrefilterCubemap - > isInitialized ( ) )
{
Con : : errorf ( " RenderProbeMgr::updateProbeTexture() - tried to update a probe's texture with an invalid or uninitialized specular map! " ) ;
return ;
}
const U32 cubeIndex = probeInfo - > mCubemapIndex ;
mIrradianceArray - > updateTexture ( probeInfo - > mIrradianceCubemap , cubeIndex ) ;
mPrefilterArray - > updateTexture ( probeInfo - > mPrefilterCubemap , cubeIndex ) ;
2019-03-26 04:17:53 +00:00
2019-06-18 04:48:20 +00:00
# ifdef TORQUE_DEBUG
2019-06-13 05:37:12 +00:00
Con : : warnf ( " UpdatedProbeTexture - probeIdx: %u on cubeIndex %u, Irrad validity: %d, Prefilter validity: %d " , probeInfo - > mProbeIdx , cubeIndex ,
probeInfo - > mIrradianceCubemap - > isInitialized ( ) , probeInfo - > mPrefilterCubemap - > isInitialized ( ) ) ;
2019-06-18 04:48:20 +00:00
# endif
2019-03-24 23:18:44 +00:00
}
2020-03-19 14:47:38 +00:00
void RenderProbeMgr : : reloadTextures ( )
{
U32 probeCount = mRegisteredProbes . size ( ) ;
for ( U32 i = 0 ; i < probeCount ; i + + )
{
updateProbeTexture ( & mRegisteredProbes [ i ] ) ;
}
mProbesDirty = true ;
}
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.
2019-11-21 06:48:55 +00:00
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 ;
2019-11-21 06:48:55 +00:00
}
2019-06-27 05:36:56 +00:00
2019-11-21 06:48:55 +00:00
/*if (mLastConstants == nullptr)
{
ProbeShaderConstants * psc = new ProbeShaderConstants ( ) ;
mConstantLookup [ shader ] = psc ;
2019-06-27 05:36:56 +00:00
2019-11-21 06:48:55 +00:00
mLastConstants = psc ;
} */
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 ) ;
2020-03-19 14:47:38 +00:00
return ;
2019-01-26 08:05:18 +00:00
// Skip over gathering lights if we don't have to!
2019-06-27 05:36:56 +00:00
//if (probeShaderConsts->isValid())
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 ;
2020-03-19 14:47:38 +00:00
ProbeDataSet probeSet ( MAX_FORWARD_PROBES ) ;
2019-01-26 08:05:18 +00:00
matSet . restoreSceneViewProjection ( ) ;
2020-03-19 14:47:38 +00:00
getBestProbes ( sgData . objTrans - > getPosition ( ) , & probeSet ) ;
shaderConsts - > setSafe ( probeShaderConsts - > mProbeCountSC , ( S32 ) probeSet . effectiveProbeCount ) ;
shaderConsts - > setSafe ( probeShaderConsts - > mProbePositionSC , probeSet . probePositionArray ) ;
shaderConsts - > setSafe ( probeShaderConsts - > mProbeRefPosSC , probeSet . probeRefPositionArray ) ;
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 - > mSkylightCubemapIdxSC , ( float ) probeSet . skyLightIdx ) ;
if ( probeShaderConsts - > mBRDFTextureMap - > getSamplerRegister ( ) ! = - 1 & & mBRDFTexture . isValid ( ) )
GFX - > setTexture ( probeShaderConsts - > mBRDFTextureMap - > getSamplerRegister ( ) , mBRDFTexture ) ;
if ( probeShaderConsts - > mProbeSpecularCubemapSC - > getSamplerRegister ( ) ! = - 1 )
GFX - > setCubeArrayTexture ( probeShaderConsts - > mProbeSpecularCubemapSC - > getSamplerRegister ( ) , mPrefilterArray ) ;
if ( probeShaderConsts - > mProbeIrradianceCubemapSC - > getSamplerRegister ( ) ! = - 1 )
GFX - > setCubeArrayTexture ( probeShaderConsts - > mProbeIrradianceCubemapSC - > getSamplerRegister ( ) , mIrradianceArray ) ;
}
}
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())
{
2019-04-03 05:13:58 +00:00
//Array rendering
2019-06-04 05:21:52 +00:00
U32 probeCount = mRegisteredProbes . size ( ) ;
2019-04-03 05:13:58 +00:00
2020-03-19 14:47:38 +00:00
Vector < S8 > bestPickProbes ;
2019-05-03 05:03:58 +00:00
2020-03-19 14:47:38 +00:00
probeDataSet - > effectiveProbeCount = 0 ;
2019-04-03 05:13:58 +00:00
for ( U32 i = 0 ; i < probeCount ; i + + )
{
2019-06-04 05:21:52 +00:00
const ProbeRenderInst & curEntry = mRegisteredProbes [ i ] ;
2019-04-03 05:13:58 +00:00
if ( ! curEntry . mIsEnabled )
continue ;
2019-02-14 06:35:22 +00:00
2019-04-29 05:07:38 +00:00
if ( ! curEntry . mIsSkylight )
2019-04-08 04:57:05 +00:00
{
2020-03-19 14:47:38 +00:00
F32 dist = Point3F ( objPosition - curEntry . getPosition ( ) ) . len ( ) ;
2019-05-03 05:03:58 +00:00
if ( dist > curEntry . mRadius | | dist > curEntry . mExtents . len ( ) )
continue ;
2020-03-19 14:47:38 +00:00
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 ;
2019-05-02 05:05:12 +00:00
}
2019-06-27 05:36:56 +00:00
else
{
2020-03-19 14:47:38 +00:00
probeDataSet - > skyLightIdx = curEntry . mCubemapIndex ;
2019-06-27 05:36:56 +00:00
}
2019-04-08 04:57:05 +00:00
}
2019-04-03 05:13:58 +00:00
2019-05-03 05:03:58 +00:00
//Grab our best probe picks
2020-03-19 14:47:38 +00:00
for ( U32 i = 0 ; i < bestPickProbes . size ( ) ; i + + )
2019-05-03 05:03:58 +00:00
{
if ( bestPickProbes [ i ] = = - 1 )
continue ;
2019-06-04 05:21:52 +00:00
const ProbeRenderInst & curEntry = mRegisteredProbes [ bestPickProbes [ i ] ] ;
2019-05-03 05:03:58 +00:00
2020-03-19 14:47:38 +00:00
probeDataSet - > probePositionArray [ probeDataSet - > effectiveProbeCount ] = curEntry . getPosition ( ) ;
probeDataSet - > probeRefPositionArray [ probeDataSet - > effectiveProbeCount ] = curEntry . mProbeRefOffset ;
probeDataSet - > probeWorldToObjArray [ probeDataSet - > effectiveProbeCount ] = curEntry . getTransform ( ) ;
2019-05-05 23:30:40 +00:00
Point3F refPos = curEntry . getPosition ( ) + curEntry . mProbeRefOffset ;
2019-07-22 04:01:15 +00:00
Point3F refBoxMin = refPos - curEntry . mProbeRefScale * curEntry . getTransform ( ) . getScale ( ) ;
Point3F refBoxMax = refPos + curEntry . mProbeRefScale * curEntry . getTransform ( ) . getScale ( ) ;
2019-05-05 23:30:40 +00:00
2020-03-19 14:47:38 +00:00
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 ,
2019-05-03 05:03:58 +00:00
curEntry . mRadius ,
curEntry . mAtten ,
curEntry . mCubemapIndex ) ;
2020-03-19 14:47:38 +00:00
probeDataSet - > effectiveProbeCount + + ;
2019-05-03 05:03:58 +00:00
}
2019-05-02 05:05:12 +00:00
}
2019-01-26 08:05:18 +00:00
}
2020-03-19 14:47:38 +00:00
void RenderProbeMgr : : getProbeTextureData ( ProbeTextureArrayData * probeTextureSet )
{
probeTextureSet - > BRDFTexture = mBRDFTexture ;
probeTextureSet - > prefilterArray = mPrefilterArray ;
probeTextureSet - > irradianceArray = mIrradianceArray ;
}
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
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-07-11 04:41:55 +00:00
if ( ! RenderProbeMgr : : smRenderReflectionProbes | | ( ! state - > isDiffusePass ( ) & & ! state - > isReflectPass ( ) ) | | ( mEffectiveProbeCount = = 0 & & mSkylightCubemapIdx = = - 1 ) )
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
2019-06-05 06:04:47 +00:00
//Visualization
2019-04-16 04:11:18 +00:00
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-01-08 02:34:19 +00:00
2019-09-18 06:41:57 +00:00
if ( mSkylightCubemapIdx ! = - 1 & & mEffectiveProbeCount = = 0 )
2019-06-13 05:37:12 +00:00
mProbeArrayEffect - > setShaderMacro ( " SKYLIGHT_ONLY " , " 1 " ) ;
2019-09-18 06:41:57 +00:00
else
mProbeArrayEffect - > setShaderMacro ( " SKYLIGHT_ONLY " , " 0 " ) ;
2019-11-01 00:06:40 +00:00
//ssao mask
if ( AdvancedLightBinManager : : smUseSSAOMask )
{
//find ssaoMask
NamedTexTargetRef ssaoTarget = NamedTexTarget : : find ( " ssaoMask " ) ;
GFXTextureObject * pTexObj = ssaoTarget - > getTexture ( ) ;
if ( pTexObj )
{
mProbeArrayEffect - > setShaderMacro ( " USE_SSAO_MASK " ) ;
mProbeArrayEffect - > setTexture ( 6 , pTexObj ) ;
}
}
else
{
2019-12-06 03:30:01 +00:00
mProbeArrayEffect - > setTexture ( 6 , GFXTexHandle ( NULL ) ) ;
2019-11-01 00:06:40 +00:00
}
2019-06-13 05:37:12 +00:00
mProbeArrayEffect - > setTexture ( 3 , mBRDFTexture ) ;
mProbeArrayEffect - > setCubemapArrayTexture ( 4 , mPrefilterArray ) ;
mProbeArrayEffect - > setCubemapArrayTexture ( 5 , mIrradianceArray ) ;
2019-03-24 23:18:44 +00:00
2019-06-13 05:37:12 +00:00
mProbeArrayEffect - > setShaderConst ( " $numProbes " , ( S32 ) mEffectiveProbeCount ) ;
2019-07-01 04:04:16 +00:00
mProbeArrayEffect - > setShaderConst ( " $skylightCubemapIdx " , ( S32 ) mSkylightCubemapIdx ) ;
2019-04-16 04:11:18 +00:00
mProbeArrayEffect - > setShaderConst ( " $cubeMips " , ( float ) mMipCount ) ;
2019-06-13 05:37:12 +00:00
//also set up some colors
Vector < Point4F > contribColors ;
contribColors . setSize ( MAXPROBECOUNT ) ;
2019-02-11 06:17:53 +00:00
if ( mEffectiveProbeCount ! = 0 )
2018-11-29 00:12:12 +00:00
{
2019-02-17 09:47:40 +00:00
if ( useDebugContrib = = String ( " 1 " ) )
{
MRandomLCG RandomGen ;
RandomGen . setSeed ( mEffectiveProbeCount ) ;
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
}
}
2019-06-05 06:04:47 +00:00
}
2019-05-08 06:27:51 +00:00
2019-06-13 05:37:12 +00:00
mProbeArrayEffect - > setShaderConst ( " $probeContribColors " , contribColors ) ;
mProbeArrayEffect - > setShaderConst ( " $inProbePosArray " , probePositionsData ) ;
mProbeArrayEffect - > setShaderConst ( " $inRefPosArray " , probeRefPositionsData ) ;
mProbeArrayEffect - > setShaderConst ( " $worldToObjArray " , probeWorldToObjData ) ;
2019-06-28 15:56:38 +00:00
mProbeArrayEffect - > setShaderConst ( " $refBoxMinArray " , refBoxMinData ) ;
mProbeArrayEffect - > setShaderConst ( " $refBoxMaxArray " , refBoxMaxData ) ;
2019-06-13 05:37:12 +00:00
mProbeArrayEffect - > setShaderConst ( " $probeConfigData " , probeConfigData ) ;
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 ;
2020-01-02 04:37:27 +00:00
reflDesc . objectTypeMask = probe - > mCaptureMask ;
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 ) ;
2019-07-11 04:41:55 +00:00
probe - > setMaskBits ( - 1 ) ;
2019-02-14 06:35:22 +00:00
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 ) ;
2019-05-05 23:30:40 +00:00
}