From 64c45059cf45cde7b69e2adf880e40df0b29c2d9 Mon Sep 17 00:00:00 2001 From: D-AIRY <admin@ds-servers.com> Date: Tue, 7 Apr 2020 13:30:34 +0300 Subject: [PATCH] Some LPV improvements --- build/engine/shaders/base/skybox.vs | 10 +- build/engine/shaders/gi/gi_cubes.gs | 10 +- build/engine/shaders/gi/gi_cubes.ps | 4 +- build/engine/shaders/gi/gi_cubes.vs | 10 +- build/engine/shaders/gi/gi_inject.gs | 2 +- build/engine/shaders/gi/gi_inject.ps | 2 +- build/engine/shaders/gi/gi_inject.vs | 6 +- build/engine/shaders/gi/gi_inject_cube.vs | 2 +- build/engine/shaders/lighting/lighting_gi.ps | 22 +- build/engine/shaders/struct.h | 3 + source/game/BaseCharacter.cpp | 2 +- source/game/GameData.cpp | 2 +- source/light/IXLight.h | 8 +- source/light/light.cpp | 12 +- source/light/light.h | 17 +- source/render/RenderPipeline.cpp | 118 +++++-- source/render/ShadowCache.cpp | 336 ++++++++++++------- source/render/ShadowCache.h | 177 +++++++++- source/render/shadow.cpp | 18 +- source/render/shadow.h | 12 +- 20 files changed, 561 insertions(+), 212 deletions(-) diff --git a/build/engine/shaders/base/skybox.vs b/build/engine/shaders/base/skybox.vs index 8feabafbe..4bcd80608 100644 --- a/build/engine/shaders/base/skybox.vs +++ b/build/engine/shaders/base/skybox.vs @@ -4,8 +4,8 @@ skybox.vs Скайбокс */ -#include "../struct.h" -#include "../const.h" +#include <struct.h> +#include <const.h> //########################################################################## @@ -13,8 +13,10 @@ VSO_SkyBox main(VSI_SkyBox IN) { VSO_SkyBox OUT = (VSO_SkyBox)0; - OUT.vPosition = mul(half4(IN.vPosition + g_vPosCam.xyz, 1.f), g_mVP); + OUT.vPosition = mul(float4(IN.vPosition + g_vPosCam.xyz, 1.f), g_mVP); OUT.vTexUV = IN.vTexUV; - + OUT.vNormal = -IN.vPosition; + OUT.vPos = OUT.vPosition; + return OUT; } diff --git a/build/engine/shaders/gi/gi_cubes.gs b/build/engine/shaders/gi/gi_cubes.gs index e0813a667..c93ebcc98 100644 --- a/build/engine/shaders/gi/gi_cubes.gs +++ b/build/engine/shaders/gi/gi_cubes.gs @@ -4,16 +4,16 @@ terrax_colored.vs */ -#include "../struct.h" +#include <struct.h> //########################################################################## cbuffer perFrame: register(b1) { - half4x4 g_mVP; - half4x4 g_mViewInv; - half2 g_vNearFar; - half3 g_vParamProj; + float4x4 g_mVP; + float4x4 g_mViewInv; + float2 g_vNearFar; + float3 g_vParamProj; }; //########################################################################## diff --git a/build/engine/shaders/gi/gi_cubes.ps b/build/engine/shaders/gi/gi_cubes.ps index 7daaf9228..36bcd694d 100644 --- a/build/engine/shaders/gi/gi_cubes.ps +++ b/build/engine/shaders/gi/gi_cubes.ps @@ -3,8 +3,8 @@ .ps */ -#include "../lpv.h" -#include "../struct.h" +#include <lpv.h> +#include <struct.h> //########################################################################## diff --git a/build/engine/shaders/gi/gi_cubes.vs b/build/engine/shaders/gi/gi_cubes.vs index e04748139..fbf745edf 100644 --- a/build/engine/shaders/gi/gi_cubes.vs +++ b/build/engine/shaders/gi/gi_cubes.vs @@ -4,16 +4,16 @@ terrax_colored.vs */ -#include "../struct.h" +#include <struct.h> //########################################################################## cbuffer perFrame: register(b1) { - half4x4 g_mVP; - half4x4 g_mViewInv; - half2 g_vNearFar; - half3 g_vParamProj; + float4x4 g_mVP; + float4x4 g_mViewInv; + float2 g_vNearFar; + float3 g_vParamProj; }; cbuffer b8: register(b8) diff --git a/build/engine/shaders/gi/gi_inject.gs b/build/engine/shaders/gi/gi_inject.gs index 49def7304..3211681dc 100644 --- a/build/engine/shaders/gi/gi_inject.gs +++ b/build/engine/shaders/gi/gi_inject.gs @@ -1,5 +1,5 @@ -#include "../lpv.h" +#include <lpv.h> struct GS_IN { diff --git a/build/engine/shaders/gi/gi_inject.ps b/build/engine/shaders/gi/gi_inject.ps index 3f6af2b4f..23ba047ed 100644 --- a/build/engine/shaders/gi/gi_inject.ps +++ b/build/engine/shaders/gi/gi_inject.ps @@ -1,4 +1,4 @@ -#include "../lpv.h" +#include <lpv.h> struct PS_IN { diff --git a/build/engine/shaders/gi/gi_inject.vs b/build/engine/shaders/gi/gi_inject.vs index e8d108594..d370489a9 100644 --- a/build/engine/shaders/gi/gi_inject.vs +++ b/build/engine/shaders/gi/gi_inject.vs @@ -1,5 +1,5 @@ -#include "../lpv.h" +#include <lpv.h> cbuffer perLight: register(b7) { @@ -82,8 +82,8 @@ RsmTexel GetRsmTexel(int2 coords, uint2 vTexSize) return(tx); } -#define KERNEL_SIZE 4 -#define STEP_SIZE 1 +// #define KERNEL_SIZE 4 +// #define STEP_SIZE 1 GS_IN main(VS_IN input) { diff --git a/build/engine/shaders/gi/gi_inject_cube.vs b/build/engine/shaders/gi/gi_inject_cube.vs index 2dd7345d2..921fad332 100644 --- a/build/engine/shaders/gi/gi_inject_cube.vs +++ b/build/engine/shaders/gi/gi_inject_cube.vs @@ -1,5 +1,5 @@ -#include "../lpv.h" +#include <lpv.h> cbuffer perLight: register(b7) { diff --git a/build/engine/shaders/lighting/lighting_gi.ps b/build/engine/shaders/lighting/lighting_gi.ps index 40ffd8973..a7ea35324 100644 --- a/build/engine/shaders/lighting/lighting_gi.ps +++ b/build/engine/shaders/lighting/lighting_gi.ps @@ -4,15 +4,15 @@ lighting_gi.ps */ -#include "../lpv.h" -#include "../struct.h" -#include "../mtrl.h" +#include <lpv.h> +#include <struct.h> +#include <mtrl.h> //########################################################################## cbuffer perFrame: register(b1) { - half3 g_vViewPos; + float3 g_vViewPos; }; cbuffer b8: register(b8) @@ -39,17 +39,17 @@ PSO_Lbuffer main(VSO_ResPos IN) { PSO_Lbuffer OUT; - half4 vNormals = g_txNormals.Sample(g_sPointClamp, IN.vTexUV); - half fDepth = g_txDepth.Sample(g_sPointClamp,IN.vTexUV).r; + float4 vNormals = g_txNormals.Sample(g_sPointClamp, IN.vTexUV); + float fDepth = g_txDepth.Sample(g_sPointClamp,IN.vTexUV).r; // xy_ - размеры пикселя текстуры, __z - размер сетки в мировых - half3 vTexSize = half3(1.0 / 32.0, 1.0 / 32.0, 16); - half3 vOrigin = half3(0, 0, 0); // Центр сетки - half4 vPosition = half4(g_vViewPos.xyz + IN.vWorldRay * fDepth, 1.0); // Мировая позиция пиксела + float3 vTexSize = float3(1.0 / 32.0, 1.0 / 32.0, 16); + float3 vOrigin = float3(0, 0, 0); // Центр сетки + float4 vPosition = float4(g_vViewPos.xyz + IN.vWorldRay * fDepth, 1.0); // Мировая позиция пиксела vPosition -= floor(g_vPosCam); - half3 vNormalPixel = normalize(NormalDecode(vNormals.xyz).xyz); + float3 vNormalPixel = normalize(NormalDecode(vNormals.xyz).xyz); /* half3 vLocalPos = (vPosition - vOrigin); @@ -92,7 +92,7 @@ PSO_Lbuffer main(VSO_ResPos IN) float g = saturate(dot(SHintensity, vColorG)); float b = saturate(dot(SHintensity, vColorB)); - OUT.vAmdient.xyz = float3(r, g, b) / PI; + OUT.vAmdient.xyz = float3(r, g, b) / PI/* * 6.0f */; OUT.vAmdient.w = 1; OUT.vSpecular = 0; diff --git a/build/engine/shaders/struct.h b/build/engine/shaders/struct.h index 92b48e02b..a72254e40 100644 --- a/build/engine/shaders/struct.h +++ b/build/engine/shaders/struct.h @@ -172,6 +172,9 @@ struct VSO_SkyBox { float4 vPosition :POSITION0; float3 vTexUV :TEXCOORD0; + + float3 vNormal :TEXCOORD1; + float4 vPos :TEXCOORD2; }; //!@} diff --git a/source/game/BaseCharacter.cpp b/source/game/BaseCharacter.cpp index d3c4109dd..853df59f5 100644 --- a/source/game/BaseCharacter.cpp +++ b/source/game/BaseCharacter.cpp @@ -112,7 +112,7 @@ CBaseCharacter::CBaseCharacter(CEntityManager * pMgr): m_flashlight->setOrient(m_pHeadEnt->getOrient() * SMQuaternion(SM_PIDIV2, 'x')); m_flashlight->setParent(m_pHeadEnt); m_flashlight->setDist(20.f); - m_flashlight->setOuterAngle(SMToRadian(60)); + m_flashlight->setOuterAngle(SMToRadian(30)); // 60 m_flashlight->setInnerAngle(SMToRadian(10)); m_flashlight->setColor(float3(3.5, 3.5, 3.5)); //m_flashlight->setShadowType(-1); diff --git a/source/game/GameData.cpp b/source/game/GameData.cpp index e55186694..4206db5e7 100644 --- a/source/game/GameData.cpp +++ b/source/game/GameData.cpp @@ -441,7 +441,7 @@ GameData::GameData(HWND hWnd, bool isGame): m_pLightSystem = (IXLightSystem*)Core_GetIXCore()->getPluginManager()->getInterface(IXLIGHTSYSTEM_GUID); - if(m_pLightSystem) + if(m_pLightSystem && false) { // 252, 212, 64 IXLightSun *pSun = m_pLightSystem->createSun(); diff --git a/source/light/IXLight.h b/source/light/IXLight.h index 3efcb4806..b2995edd8 100644 --- a/source/light/IXLight.h +++ b/source/light/IXLight.h @@ -39,6 +39,8 @@ enum LIGHT_RENDER_TYPE LRT_LIGHT = 1, //!< Только освещение, без LPV LRT_LPV = 2, //!< Рендер для LPV в 32x32 LRT_FULL = 3, //!< Полноразмерный рендер + + LRT_ALL = LRT_FULL }; DEFINE_ENUM_FLAG_OPERATORS(LIGHT_RENDER_TYPE); @@ -73,9 +75,11 @@ public: //@TODO: Remove this method virtual LIGHT_RENDER_TYPE getRenderType() = 0; //@TODO: Remove this method - virtual bool isDirty() = 0; + virtual bool isDirty(LIGHT_RENDER_TYPE type) = 0; + //@TODO: Remove this method + virtual void markClean(LIGHT_RENDER_TYPE type) = 0; //@TODO: Remove this method - virtual void markClean() = 0; + virtual void testDirty() = 0; virtual IXLightSpot *asSpot() = 0; virtual IXLightSun *asSun() = 0; diff --git a/source/light/light.cpp b/source/light/light.cpp index e65fb1b0a..44dd97b3d 100644 --- a/source/light/light.cpp +++ b/source/light/light.cpp @@ -53,7 +53,7 @@ void CXLight::setColor(const float3 &vColor) m_pMutationObserver->setHalfExtents(float3(getMaxDistance() * 0.5f)); m_isVSDataDirty = true; m_isPSDataDirty = true; - m_isDirty = true; + m_dirty = LRT_ALL; } float3 CXLight::getPosition() @@ -70,7 +70,7 @@ void CXLight::setPosition(const float3 &vPosition) m_pMutationObserver->setPosition(vPosition); m_isVSDataDirty = true; m_isPSDataDirty = true; - m_isDirty = true; + m_dirty = LRT_ALL; } float CXLight::getShadowIntencity() @@ -99,7 +99,7 @@ void CXLight::setEnabled(bool isEnabled) } m_isEnable = isEnabled; m_pMutationObserver->setEnabled(isEnabled); - m_isDirty = true; + m_dirty = LRT_ALL; } bool CXLight::isShadowDynamic() @@ -292,7 +292,7 @@ void CXLightSun::setDirection(const SMQuaternion &qDirection) } m_qDirection = qDirection; m_isVSDataDirty = true; - m_isDirty = true; + m_dirty = LRT_ALL; } void CXLightSun::updatePSConstants(IGXDevice *pDevice) @@ -369,7 +369,7 @@ void CXLightSpot::setOuterAngle(float fAngle) m_fOuterAngle = fAngle; m_isVSDataDirty = true; m_isPSDataDirty = true; - m_isDirty = true; + m_dirty = LRT_ALL; } SMQuaternion CXLightSpot::getDirection() { @@ -384,7 +384,7 @@ void CXLightSpot::setDirection(const SMQuaternion &qDirection) m_qDirection = qDirection; m_isVSDataDirty = true; m_isPSDataDirty = true; - m_isDirty = true; + m_dirty = LRT_ALL; } void CXLightSpot::updatePSConstants(IGXDevice *pDevice) diff --git a/source/light/light.h b/source/light/light.h index b171211b1..850fcc887 100644 --- a/source/light/light.h +++ b/source/light/light.h @@ -58,18 +58,21 @@ public: return(m_renderType); } - bool isDirty() override + void testDirty() override { - if(m_isDirty) + if(m_pMutationObserver->wasTriggered()) { m_pMutationObserver->reset(); + m_dirty = LRT_ALL; } - return(m_isDirty || m_pMutationObserver->wasTriggered()); } - void markClean() override + bool isDirty(LIGHT_RENDER_TYPE type) override { - m_isDirty = false; - m_pMutationObserver->reset(); + return(m_dirty & type); + } + void markClean(LIGHT_RENDER_TYPE type) override + { + m_dirty &= ~type; } protected: @@ -105,7 +108,7 @@ protected: IFrustum *m_pFrustum = NULL; IXRenderableVisibility *m_pVisibility = NULL; LIGHT_RENDER_TYPE m_renderType = LRT_NONE; - bool m_isDirty = true; + LIGHT_RENDER_TYPE m_dirty = LRT_ALL; IXMutationObserver *m_pMutationObserver = NULL; }; diff --git a/source/render/RenderPipeline.cpp b/source/render/RenderPipeline.cpp index dee40bda6..26d0648b6 100644 --- a/source/render/RenderPipeline.cpp +++ b/source/render/RenderPipeline.cpp @@ -21,6 +21,9 @@ CRenderPipeline::CRenderPipeline(IGXDevice *pDevice): IPluginManager *pPluginManager = pCore->getPluginManager(); m_pMaterialSystem = (IXMaterialSystem*)pPluginManager->getInterface(IXMATERIALSYSTEM_GUID); + Core_0RegisterCVarBool("dev_lpv_cubes", false, "Отображать сетку LPV"); + Core_0RegisterCVarBool("dev_lpv_points", false, "Отображать VPL при инъекции в LPV"); + XVertexOutputElement voelGeneric[] = { {"vPosition", GXDECLTYPE_FLOAT4, GXDECLUSAGE_POSITION}, {"vTexUV", GXDECLTYPE_FLOAT2, GXDECLUSAGE_TEXCOORD}, @@ -176,9 +179,20 @@ CRenderPipeline::CRenderPipeline(IGXDevice *pDevice): GXMacro pVariant1[] = { {"IS_CUBEMAP", "1"}, {NULL, NULL} + }; + GXMacro pVariant2[] = { + {"ENABLE_RSM", "1"}, + {NULL, NULL} + }; + GXMacro pVariant3[] = { + {"IS_CUBEMAP", "1"}, + {"ENABLE_RSM", "1"}, + {NULL, NULL} }; XRenderPassVariantElement pVariants[] = { pVariant1, + pVariant2, + pVariant3, NULL }; @@ -626,7 +640,12 @@ void CRenderPipeline::renderFrame() #endif end: - //showGICubes(); + const bool *dev_lpv_cubes = GET_PCVAR_BOOL("dev_lpv_cubes"); + if(*dev_lpv_cubes) + { + showGICubes(); + } + showFrameStats(); getXUI()->render(); @@ -696,12 +715,12 @@ void CRenderPipeline::showGICubes() pCtx->setRenderBuffer(m_pGICubesRB); SGCore_ShaderBind(m_idGICubesShader); pCtx->setGSConstant(m_pLightingShaderDataVS, 1); - pCtx->setDepthStencilState(NULL); + pCtx->setDepthStencilState(m_pDepthStencilStateDefault); pCtx->setPSTexture(m_pGIAccumRed2, 0); pCtx->setPSTexture(m_pGIAccumGreen2, 1); pCtx->setPSTexture(m_pGIAccumBlue2, 2); pCtx->setSamplerState(gdata::rstates::pSamplerPointClamp, 0); - + pCtx->drawPrimitive(0, m_uGICubesCount); pCtx->setPrimitiveTopology(GXPT_TRIANGLELIST); @@ -798,6 +817,7 @@ void CRenderPipeline::renderGI() ++uCounts[m_pLightSystem->getLight(i)->getType()]; } m_pShadowCache->setLightsCount(uCounts[LIGHT_TYPE_POINT], uCounts[LIGHT_TYPE_SPOT], uCounts[LIGHT_TYPE_SUN] != 0); + m_pShadowCache->setRSMLightsCount(uCounts[LIGHT_TYPE_POINT], uCounts[LIGHT_TYPE_SPOT], uCounts[LIGHT_TYPE_SUN] != 0); m_pShadowCache->setObserverCamera(gdata::pCamera); @@ -860,7 +880,14 @@ void CRenderPipeline::renderGI() //если свет виден фрустуму камеры (это надо было заранее просчитать) и если свет включен if(pLight->isEnabled() && pLight->getRenderType() != LRT_NONE) { - m_pShadowCache->addLight(pLight); + if(pLight->getRenderType() & LRT_LPV) + { + m_pShadowCache->addRSMLight(pLight); + } + if(pLight->getRenderType() & LRT_LIGHT) + { + m_pShadowCache->addLight(pLight); + } } } @@ -904,15 +931,7 @@ void CRenderPipeline::renderGI() { pLight = m_pShadowCache->getLight(i); pShadow = m_pShadowCache->getShadow(i); - - if(pLight->getType() == LIGHT_TYPE_SUN) - { - // continue; - } - - //пока что назначаем шейдер без теней - //ID idshaderkit = pLight->getType() == LIGHT_TYPE_SPOT ? gdata::shaders_id::kit::idComLightingSpotNonShadow : gdata::shaders_id::kit::idComLightingNonShadow; - + //если не глобальный источник if(pLight->getType() != LIGHT_TYPE_SUN) { @@ -990,7 +1009,18 @@ void CRenderPipeline::renderGI() SGCore_ScreenQuadDraw(); } - + } + + bool isFirstRun = true; + while((uShadowCount = m_pShadowCache->processNextRSMBunch())) + { + pCtx->setDepthStencilSurface(pOldDSSurface); + pCtx->setBlendState(gdata::rstates::pBlendAlphaOneOne); + + pCtx->setVSConstant(m_pLightingShaderDataVS, 1); + pCtx->setPSConstant(m_pLightingShaderDataPS, 1); + + IGXSurface *pLPVRed = m_pGIAccumRed->asRenderTarget(); IGXSurface *pLPVGreen = m_pGIAccumGreen->asRenderTarget(); IGXSurface *pLPVBlue = m_pGIAccumBlue->asRenderTarget(); @@ -1007,36 +1037,64 @@ void CRenderPipeline::renderGI() IGXDepthStencilSurface *pOldSurface = pCtx->getDepthStencilSurface(); pCtx->unsetDepthStencilSurface(); - pCtx->clear(GX_CLEAR_COLOR); + if(isFirstRun) + { + pCtx->clear(GX_CLEAR_COLOR); + isFirstRun = false; + } + IBaseReflectiveShadowMap *pShadow = NULL; //inject VPLs into LPV grid for(UINT i = 0; i < uShadowCount; ++i) { - pShadow = m_pShadowCache->getShadow(i); - // pShadow->genLPV(); + pShadow = m_pShadowCache->getRSMShadow(i); + pShadow->genLPV(); } pCtx->setColorTarget(NULL); pCtx->setColorTarget(NULL, 1); pCtx->setColorTarget(NULL, 2); -#if 0 - auto pTarget = m_pGBufferColor->asRenderTarget(); - m_pDevice->setColorTarget(pAmbientSurf); - mem_release(pTarget); - for(UINT i = 0; i < uShadowCount; ++i) + const bool *dev_lpv_points = GET_PCVAR_BOOL("dev_lpv_points"); + if(*dev_lpv_points) { - pShadow = m_pShadowCache->getShadow(i); - pShadow->genLPV(true); + auto pTarget = m_pGBufferColor->asRenderTarget(); + pCtx->setColorTarget(pAmbientSurf); + mem_release(pTarget); + for(UINT i = 0; i < uShadowCount; ++i) + { + pShadow = m_pShadowCache->getRSMShadow(i); + pShadow->genLPV(true); + } + pCtx->setColorTarget(NULL); } - m_pDevice->setColorTarget(NULL); -#endif pCtx->setDepthStencilSurface(pOldSurface); mem_release(pOldSurface); //break; } + if(isFirstRun) + { + IGXSurface *pLPVRed = m_pGIAccumRed->asRenderTarget(); + IGXSurface *pLPVGreen = m_pGIAccumGreen->asRenderTarget(); + IGXSurface *pLPVBlue = m_pGIAccumBlue->asRenderTarget(); + + pCtx->setColorTarget(pLPVRed); + pCtx->setColorTarget(pLPVGreen, 1); + pCtx->setColorTarget(pLPVBlue, 2); + + mem_release(pLPVRed); + mem_release(pLPVGreen); + mem_release(pLPVBlue); + + pCtx->clear(GX_CLEAR_COLOR); + isFirstRun = false; + + pCtx->setColorTarget(NULL); + pCtx->setColorTarget(NULL, 1); + pCtx->setColorTarget(NULL, 2); + } SGCore_ShaderUnBind(); @@ -1048,7 +1106,7 @@ void CRenderPipeline::renderGI() { SGCore_ShaderBind(m_idLPVPropagateShader); - for(UINT i = 0; i < 1/*6*/; ++i) + for(UINT i = 0; i < 6/*6*/; ++i) { pCtx->setCSTexture(m_pGIAccumRed, 0); pCtx->setCSTexture(m_pGIAccumGreen, 1); @@ -1069,8 +1127,6 @@ void CRenderPipeline::renderGI() pCtx->setCSTexture(NULL, 2); - - pCtx->setCSTexture(m_pGIAccumRed2, 0); pCtx->setCSTexture(m_pGIAccumGreen2, 1); pCtx->setCSTexture(m_pGIAccumBlue2, 2); @@ -1108,6 +1164,8 @@ void CRenderPipeline::renderGI() //SGCore_ShaderSetVRF(SHADER_TYPE_PIXEL, idshader, "g_vViewPos", &gdata::vConstCurrCamPos); + // pCtx->setPSConstant(m_pCameraShaderDataVS, 8); + SGCore_ShaderBind(idshaderkit); pCtx->setSamplerState(gdata::rstates::pSamplerPointClamp, 0); @@ -1169,6 +1227,8 @@ void CRenderPipeline::renderGI() pCtx->setColorTarget(pBackBuf); mem_release(pBackBuf); + + //Sleep(16); } void CRenderPipeline::renderPostprocessMain() { diff --git a/source/render/ShadowCache.cpp b/source/render/ShadowCache.cpp index 3ac1f20d7..b65f5a153 100644 --- a/source/render/ShadowCache.cpp +++ b/source/render/ShadowCache.cpp @@ -33,7 +33,11 @@ private: CShadowCache::CShadowCache(IXRenderPipeline *pRenderPipeline, IXMaterialSystem *pMaterialSystem): m_pRenderPipeline(pRenderPipeline), - m_pMaterialSystem(pMaterialSystem) + m_pMaterialSystem(pMaterialSystem), + m_shadowMaps(m_aFrameLights, m_aReadyMaps, m_pRenderPipeline, LRT_LIGHT), + m_shadowCubeMaps(m_aFrameLights, m_aReadyMaps, m_pRenderPipeline, LRT_LIGHT), + m_reflectiveShadowMaps(m_aFrameRSMLights, m_aReadyReflectiveMaps, m_pRenderPipeline, LRT_LPV), + m_reflectiveShadowCubeMaps(m_aFrameRSMLights, m_aReadyReflectiveMaps, m_pRenderPipeline, LRT_LPV) { m_pShadowSizeCvarListener = new CRShadowSizeCvarListener(Core_GetIXCore(), this); Core_GetIXCore()->getEventChannel<XEventCvarChanged>(EVENT_CVAR_CHANGED_GUID)->addListener(m_pShadowSizeCvarListener); @@ -73,13 +77,13 @@ CShadowCache::CShadowCache(IXRenderPipeline *pRenderPipeline, IXMaterialSystem * //rasterizerDesc.cullMode = GXCULL_FRONT; //rasterizerDesc.useConservativeRasterization = true; m_pRasterizerConservative = m_pRenderPipeline->getDevice()->createRasterizerState(&rasterizerDesc); - } CShadowCache::~CShadowCache() { Core_GetIXCore()->getEventChannel<XEventCvarChanged>(EVENT_CVAR_CHANGED_GUID)->removeListener(m_pShadowSizeCvarListener); mem_delete(m_pShadowSizeCvarListener); mem_delete(m_pShadowPSSM); + mem_delete(m_pReflectiveShadowSun); } void CShadowCache::setLightsCount(UINT uPoints, UINT uSpots, bool hasGlobal) @@ -96,7 +100,7 @@ void CShadowCache::setLightsCount(UINT uPoints, UINT uSpots, bool hasGlobal) size_t stPointsMemory = uPoints * CShadowCubeMap::GetMapMemory(uPointShadowmapSize); size_t stSpotsMemory = uSpots * CShadowMap::GetMapMemory(uSpotShadowmapSize); - size_t stSunMemory = 0; + size_t stSunMemory = CShadowPSSM::GetMapMemory(uSunShadowmapSize); size_t stTotal = stPointsMemory + stSpotsMemory; stMaxMem -= stSunMemory; @@ -125,46 +129,84 @@ void CShadowCache::setLightsCount(UINT uPoints, UINT uSpots, bool hasGlobal) } } } + + m_shadowMaps.setSize(uSpots, uSpotShadowmapSize); + m_shadowCubeMaps.setSize(uPoints, uPointShadowmapSize); + + m_aReadyMaps.resizeFast(uSpots + uPoints + (hasGlobal ? 1 : 0)); - if(m_aShadowMaps.size() != uSpots) + if(hasGlobal) { - UINT i = m_aShadowMaps.size(); - m_aShadowMaps.resizeFast(uSpots); - for(; i < uSpots; ++i) + if(!m_pShadowPSSM) { - m_aShadowMaps[i].map.init(m_pRenderPipeline->getDevice(), uSpotShadowmapSize); + m_pShadowPSSM = new ShadowPSSM(); + m_pShadowPSSM->map.init(m_pRenderPipeline->getDevice(), uSunShadowmapSize); } } + else + { + mem_delete(m_pShadowPSSM); + } +} + +void CShadowCache::setRSMLightsCount(UINT uPoints, UINT uSpots, bool hasGlobal) +{ + //static const float *s_pfRRSMQuality = GET_PCVAR_FLOAT("r_rsm_quality"); + const UINT uSpotShadowmapSize = (UINT)(RSM_SPOT_SIZE); + const UINT uPointShadowmapSize = (UINT)(RSM_POINT_SIZE); + const UINT uSunShadowmapSize = (UINT)(RSM_SUN_SIZE); + + //size_t stMaxMem = (size_t)(m_pRenderPipeline->getDevice()->getAdapterDesc()->sizeTotalMemory * *s_pfRSMMaxMemory); + size_t stMaxMem = (size_t)(m_pRenderPipeline->getDevice()->getAdapterDesc()->sizeTotalMemory * 0.3f); - if(m_aShadowCubeMaps.size() != uPoints) + size_t stPointsMemory = uPoints * CReflectiveShadowCubeMap::GetMapMemory(uPointShadowmapSize); + size_t stSpotsMemory = uSpots * CReflectiveShadowMap::GetMapMemory(uSpotShadowmapSize); + size_t stSunMemory = CReflectiveShadowSun::GetMapMemory(uSunShadowmapSize); + + size_t stTotal = stPointsMemory + stSpotsMemory; + stMaxMem -= stSunMemory; + + if(stTotal > stMaxMem) { - UINT i = m_aShadowCubeMaps.size(); - m_aShadowCubeMaps.resizeFast(uPoints); - m_aShadowCubeMapsQueue.resizeFast(uPoints); - for(; i < uPoints; ++i) + float fCoeff = (float)stMaxMem / (float)stTotal; + + stPointsMemory = (size_t)(stPointsMemory * fCoeff); + stSpotsMemory = (size_t)(stSpotsMemory * fCoeff); + + if(uSpots) { - m_aShadowCubeMaps[i].map.init(m_pRenderPipeline->getDevice(), uPointShadowmapSize); + uSpots = (UINT)(stSpotsMemory / CReflectiveShadowMap::GetMapMemory(uSpotShadowmapSize)); + if(!uSpots) + { + uSpots = 1; + } } - - for(i = 0; i < uPoints; ++i) + if(uPoints) { - m_aShadowCubeMapsQueue[i] = &m_aShadowCubeMaps[i]; + uPoints = (UINT)(stPointsMemory / CReflectiveShadowCubeMap::GetMapMemory(uPointShadowmapSize)); + if(!uPoints) + { + uPoints = 1; + } } } - m_aReadyMaps.resizeFast(uSpots + uPoints + (hasGlobal ? 1 : 0)); + m_reflectiveShadowMaps.setSize(uSpots, uSpotShadowmapSize); + m_reflectiveShadowCubeMaps.setSize(uPoints, uPointShadowmapSize); + + m_aReadyReflectiveMaps.resizeFast(uSpots + uPoints + (hasGlobal ? 1 : 0)); if(hasGlobal) { - if(!m_pShadowPSSM) + if(!m_pReflectiveShadowSun) { - m_pShadowPSSM = new ShadowPSSM(); - m_pShadowPSSM->map.init(m_pRenderPipeline->getDevice(), uSunShadowmapSize); + m_pReflectiveShadowSun = new ReflectiveShadowSun(); + m_pReflectiveShadowSun->map.init(m_pRenderPipeline->getDevice(), uSunShadowmapSize); } } else { - mem_delete(m_pShadowPSSM); + mem_delete(m_pReflectiveShadowSun); } } @@ -172,27 +214,27 @@ void CShadowCache::nextFrame() { ++m_uCurrentFrame; m_aFrameLights.clearFast(); + m_aFrameRSMLights.clearFast(); m_isFirstBunch = true; - - { - ShadowCubeMap *pSM; - for(UINT i = 0, l = m_aShadowCubeMaps.size(); i < l; ++i) - { - pSM = &m_aShadowCubeMaps[i]; - - if(pSM->uLastUsed != UINT_MAX) - { - ++pSM->uLastUsed; - } - } - } + + m_shadowMaps.updateLastUsed(); + m_shadowCubeMaps.updateLastUsed(); + m_reflectiveShadowMaps.updateLastUsed(); + m_reflectiveShadowCubeMaps.updateLastUsed(); } void CShadowCache::addLight(IXLight *pLight) { + pLight->testDirty(); m_aFrameLights.push_back(pLight); } +void CShadowCache::addRSMLight(IXLight *pLight) +{ + pLight->testDirty(); + m_aFrameRSMLights.push_back(pLight); +} + UINT CShadowCache::processNextBunch() { if(!m_aFrameLights.size()) @@ -212,50 +254,21 @@ UINT CShadowCache::processNextBunch() bool isSomeFound = false; if(m_isFirstBunch) { - ID id; + if(m_shadowMaps.processFirstBunch()) { - ShadowMap *pSM; - for(UINT i = 0, l = m_aShadowMaps.size(); i < l; ++i) - { - pSM = &m_aShadowMaps[i]; - if(!pSM->isDirty && (id = m_aFrameLights.indexOf(pSM->pLight)) >= 0) - { - if(pSM->pLight->isDirty()) - { - pSM->pLight->markClean(); - pSM->isDirty = true; - } - m_aFrameLights.erase(id); - pSM->shouldProcess = true; - isSomeFound = true; - } - } + isSomeFound = true; } - + if(m_shadowCubeMaps.processFirstBunch()) { - ShadowCubeMap *pSM; - for(UINT i = 0, l = m_aShadowCubeMaps.size(); i < l; ++i) - { - pSM = &m_aShadowCubeMaps[i]; - if(!pSM->isDirty && (id = m_aFrameLights.indexOf(pSM->pLight)) >= 0) - { - if(pSM->pLight->isDirty()) - { - pSM->pLight->markClean(); - pSM->isDirty = true; - } - m_aFrameLights.erase(id); - pSM->shouldProcess = true; - isSomeFound = true; - } - } + isSomeFound = true; } + ID id; if(false && m_pShadowPSSM && !m_pShadowPSSM->isDirty && (id = m_aFrameLights.indexOf(m_pShadowPSSM->pLight)) >= 0) { - if(m_pShadowPSSM->pLight->isDirty()) + if(m_pShadowPSSM->pLight->isDirty(LRT_LIGHT)) { - m_pShadowPSSM->pLight->markClean(); + m_pShadowPSSM->pLight->markClean(LRT_LIGHT); m_pShadowPSSM->isDirty = true; } m_aFrameLights.erase(id); @@ -271,33 +284,24 @@ UINT CShadowCache::processNextBunch() UINT uPoints = 0, uSpots = 0; bool isFound = false; - m_aShadowCubeMapsQueue.quickSort([](const ShadowCubeMap *a, const ShadowCubeMap *b){ - return(a->uLastUsed > b->uLastUsed); - }); + m_shadowMaps.sortQueue(); + m_shadowCubeMaps.sortQueue(); for(int i = (int)m_aFrameLights.size() - 1; i >= 0; --i) { switch(m_aFrameLights[i]->getType()) { case LIGHT_TYPE_SPOT: - if(m_aShadowMaps.size() > uSpots) + if(m_shadowMaps.checkIthLight(uSpots, i)) { - m_aShadowMaps[uSpots].isDirty = true; - m_aShadowMaps[uSpots].shouldProcess = true; - m_aShadowMaps[uSpots].pLight = m_aFrameLights[i]; ++uSpots; - m_aFrameLights.erase(i); isFound = true; } break; case LIGHT_TYPE_POINT: - if(m_aShadowCubeMapsQueue.size() > uPoints) + if(m_shadowCubeMaps.checkIthLight(uSpots, i)) { - m_aShadowCubeMapsQueue[uPoints]->isDirty = true; - m_aShadowCubeMapsQueue[uPoints]->shouldProcess = true; - m_aShadowCubeMapsQueue[uPoints]->pLight = m_aFrameLights[i]; ++uPoints; - m_aFrameLights.erase(i); isFound = true; } break; @@ -319,25 +323,8 @@ UINT CShadowCache::processNextBunch() // render shadows m_pMaterialSystem->bindRenderPass(m_pRenderPassShadow); - { - ShadowMap *pSM; - for(UINT i = 0, l = m_aShadowMaps.size(); i < l; ++i) - { - pSM = &m_aShadowMaps[i]; - if(pSM->shouldProcess) - { - pSM->shouldProcess = false; - if(pSM->isDirty) - { - pSM->map.setLight(pSM->pLight); - pSM->map.process(m_pRenderPipeline); - pSM->isDirty = false; - } - m_aReadyMaps.push_back({&pSM->map, pSM->pLight}); - } - } - } + m_shadowMaps.processTheRest(); m_pMaterialSystem->bindGS(m_pPSSMGeometryShader[*r_pssm_splits - 1]); @@ -359,33 +346,135 @@ UINT CShadowCache::processNextBunch() m_pMaterialSystem->bindGS(m_pCubemapGeometryShader); m_pMaterialSystem->bindRenderPass(m_pRenderPassShadow, 1); + + m_shadowCubeMaps.processTheRest(); + + m_pMaterialSystem->bindGS(NULL); + + Core_RMatrixSet(G_RI_MATRIX_VIEW, &mOldView); + Core_RMatrixSet(G_RI_MATRIX_PROJECTION, &mOldProj); + + return(m_aReadyMaps.size()); +} + +UINT CShadowCache::processNextRSMBunch() +{ + if(!m_aFrameRSMLights.size()) { - ShadowCubeMap *pSM; - for(UINT i = 0, l = m_aShadowCubeMaps.size(); i < l; ++i) + return(0); + } + + SMMATRIX mOldView, mOldProj; + Core_RMatrixGet(G_RI_MATRIX_VIEW, &mOldView); + Core_RMatrixGet(G_RI_MATRIX_PROJECTION, &mOldProj); + + m_pRenderPipeline->getDevice()->getThreadContext()->setDepthStencilState(NULL); + m_pRenderPipeline->getDevice()->getThreadContext()->setRasterizerState(m_pRasterizerConservative); + + bool isSomeFound = false; + if(m_isFirstRSMBunch) + { + if(m_reflectiveShadowMaps.processFirstBunch()) + { + isSomeFound = true; + } + if(m_reflectiveShadowCubeMaps.processFirstBunch()) + { + isSomeFound = true; + } + + ID id; + if(false && m_pReflectiveShadowSun && !m_pReflectiveShadowSun->isDirty && (id = m_aFrameRSMLights.indexOf(m_pReflectiveShadowSun->pLight)) >= 0) + { + if(m_pReflectiveShadowSun->pLight->isDirty(LRT_LPV)) + { + m_pReflectiveShadowSun->pLight->markClean(LRT_LPV); + m_pReflectiveShadowSun->isDirty = true; + } + m_aFrameRSMLights.erase(id); + m_pReflectiveShadowSun->shouldProcess = true; + isSomeFound = true; + } + + m_isFirstBunch = false; + } + + if(!isSomeFound) + { + UINT uPoints = 0, uSpots = 0; + bool isFound = false; + + m_reflectiveShadowMaps.sortQueue(); + m_reflectiveShadowCubeMaps.sortQueue(); + + for(int i = (int)m_aFrameRSMLights.size() - 1; i >= 0; --i) { - pSM = &m_aShadowCubeMaps[i]; - if(pSM->shouldProcess) + switch(m_aFrameRSMLights[i]->getType()) { - pSM->uLastUsed = 0; - pSM->shouldProcess = false; - if(pSM->isDirty) + case LIGHT_TYPE_SPOT: + if(m_reflectiveShadowMaps.checkIthLight(uSpots, i)) { - pSM->map.setLight(pSM->pLight); - pSM->map.process(m_pRenderPipeline); - pSM->isDirty = false; + ++uSpots; + isFound = true; } - - m_aReadyMaps.push_back({&pSM->map, pSM->pLight}); + break; + case LIGHT_TYPE_POINT: + if(m_reflectiveShadowCubeMaps.checkIthLight(uSpots, i)) + { + ++uPoints; + isFound = true; + } + break; + case LIGHT_TYPE_SUN: + m_pReflectiveShadowSun->isDirty = true; + m_pReflectiveShadowSun->shouldProcess = true; + m_pReflectiveShadowSun->pLight = m_aFrameRSMLights[i]; + m_aFrameRSMLights.erase(i); + isFound = true; + break; + } + if(!isFound) + { + break; } } } + m_aReadyReflectiveMaps.clearFast(); + + // render shadows + m_pMaterialSystem->bindRenderPass(m_pRenderPassShadow, 2); + + m_reflectiveShadowMaps.processTheRest(); + + //m_pMaterialSystem->bindGS(m_pPSSMGeometryShader[*r_pssm_splits - 1]); + + if(m_pReflectiveShadowSun && m_pReflectiveShadowSun->shouldProcess && m_pCamera) + { + m_pReflectiveShadowSun->shouldProcess = false; + + if(m_pReflectiveShadowSun->isDirty) + { + m_pReflectiveShadowSun->map.setObserverCamera(m_pCamera); + m_pReflectiveShadowSun->map.setLight(m_pReflectiveShadowSun->pLight); + m_pReflectiveShadowSun->map.process(m_pRenderPipeline); + m_pReflectiveShadowSun->isDirty = false; + } + + m_aReadyReflectiveMaps.push_back({&m_pReflectiveShadowSun->map, m_pReflectiveShadowSun->pLight}); + } + + m_pMaterialSystem->bindGS(m_pCubemapGeometryShader); + + m_pMaterialSystem->bindRenderPass(m_pRenderPassShadow, 3); + + m_reflectiveShadowCubeMaps.processTheRest(); m_pMaterialSystem->bindGS(NULL); Core_RMatrixSet(G_RI_MATRIX_VIEW, &mOldView); Core_RMatrixSet(G_RI_MATRIX_PROJECTION, &mOldProj); - return(m_aReadyMaps.size()); + return(m_aReadyReflectiveMaps.size()); } IXLight* CShadowCache::getLight(ID id) @@ -394,12 +483,24 @@ IXLight* CShadowCache::getLight(ID id) return(m_aReadyMaps[id].pLight); } +IXLight* CShadowCache::getRSMLight(ID id) +{ + assert(ID_VALID(id) && m_aReadyReflectiveMaps.size() > (UINT)id); + return(m_aReadyReflectiveMaps[id].pLight); +} + IBaseShadowMap* CShadowCache::getShadow(ID id) { assert(ID_VALID(id) && m_aReadyMaps.size() > (UINT)id); return(m_aReadyMaps[id].pShadowMap); } +IBaseReflectiveShadowMap* CShadowCache::getRSMShadow(ID id) +{ + assert(ID_VALID(id) && m_aReadyReflectiveMaps.size() > (UINT)id); + return(m_aReadyReflectiveMaps[id].pShadowMap); +} + void CShadowCache::setObserverCamera(ICamera *pCamera) { m_pCamera = pCamera; @@ -407,8 +508,7 @@ void CShadowCache::setObserverCamera(ICamera *pCamera) void CShadowCache::dropCaches() { - m_aShadowMaps.resizeFast(0); - m_aShadowCubeMaps.resizeFast(0); - m_aShadowCubeMapsQueue.resizeFast(0); + m_shadowMaps.dropCaches(); + m_shadowCubeMaps.dropCaches(); mem_delete(m_pShadowPSSM); } diff --git a/source/render/ShadowCache.h b/source/render/ShadowCache.h index b7f35df6e..e25bb24f5 100644 --- a/source/render/ShadowCache.h +++ b/source/render/ShadowCache.h @@ -26,6 +26,7 @@ public: //! Установка количества лампочек, инициализация кэша void setLightsCount(UINT iPoints, UINT iSpots, bool hasGlobal); + void setRSMLightsCount(UINT iPoints, UINT iSpots, bool hasGlobal); //! Указывает, что начался новый кадр void nextFrame(); @@ -34,10 +35,14 @@ public: //! Добавляет источник к текущему проходу, В случае отсутствия свободных слотов, возвращает false void addLight(IXLight *pLight); + void addRSMLight(IXLight *pLight); UINT processNextBunch(); + UINT processNextRSMBunch(); IXLight *getLight(ID id); + IXLight *getRSMLight(ID id); IBaseShadowMap *getShadow(ID id); + IBaseReflectiveShadowMap *getRSMShadow(ID id); protected: IXRenderPipeline *m_pRenderPipeline; @@ -50,7 +55,9 @@ protected: UINT m_uCurrentFrame = 0; Array<IXLight*> m_aFrameLights; + Array<IXLight*> m_aFrameRSMLights; bool m_isFirstBunch = true; + bool m_isFirstRSMBunch = true; struct ShadowMap { @@ -58,6 +65,7 @@ protected: bool isDirty = false; bool shouldProcess = false; IXLight *pLight = NULL; + UINT uLastUsed = UINT_MAX; }; struct ShadowCubeMap @@ -78,11 +86,156 @@ protected: SX_ALIGNED_OP_MEM2(); }; + + struct ReflectiveShadowMap + { + CReflectiveShadowMap map; + bool isDirty = false; + bool shouldProcess = false; + IXLight *pLight = NULL; + UINT uLastUsed = UINT_MAX; + }; - Array<ShadowMap> m_aShadowMaps; - Array<ShadowCubeMap> m_aShadowCubeMaps; - Array<ShadowCubeMap*> m_aShadowCubeMapsQueue; - ShadowPSSM *m_pShadowPSSM = NULL; + struct ReflectiveShadowCubeMap + { + CReflectiveShadowCubeMap map; + bool isDirty = false; + bool shouldProcess = false; + IXLight *pLight = NULL; + UINT uLastUsed = UINT_MAX; + }; + + struct ReflectiveShadowSun + { + CReflectiveShadowSun map; + bool isDirty = false; + bool shouldProcess = false; + IXLight *pLight = NULL; + + SX_ALIGNED_OP_MEM2(); + }; + + + template<class T, class R> struct Cache + { + private: + IXRenderPipeline *m_pRenderPipeline; + Array<T> m_aMaps; + Array<T*> m_aMapsQueue; + LIGHT_RENDER_TYPE m_renderType; + Array<IXLight*> &m_aFrameLights; + Array<R> &m_aReadyMaps; + public: + Cache(Array<IXLight*> &aFrameLights, Array<R> &aReadyMaps, IXRenderPipeline *pRenderPipeline, LIGHT_RENDER_TYPE renderType): + m_aFrameLights(aFrameLights), + m_aReadyMaps(aReadyMaps), + m_pRenderPipeline(pRenderPipeline), + m_renderType(renderType) + { + } + void setRenderType(LIGHT_RENDER_TYPE renderType) + { + m_renderType = renderType; + } + void setSize(UINT uSize, UINT uMapSize) + { + if(m_aMaps.size() != uSize) + { + UINT i = m_aMaps.size(); + m_aMaps.resizeFast(uSize); + m_aMapsQueue.resizeFast(uSize); + for(; i < uSize; ++i) + { + m_aMaps[i].map.init(m_pRenderPipeline->getDevice(), uMapSize); + } + + for(i = 0; i < uSize; ++i) + { + m_aMapsQueue[i] = &m_aMaps[i]; + } + } + } + void updateLastUsed() + { + T *pSM; + for(UINT i = 0, l = m_aMaps.size(); i < l; ++i) + { + pSM = &m_aMaps[i]; + + if(pSM->uLastUsed != UINT_MAX) + { + ++pSM->uLastUsed; + } + } + } + + bool processFirstBunch() + { + T *pSM; + ID id; + bool isSomeFound = false; + for(UINT i = 0, l = m_aMaps.size(); i < l; ++i) + { + pSM = &m_aMaps[i]; + if(!pSM->isDirty && (id = m_aFrameLights.indexOf(pSM->pLight)) >= 0) + { + if(pSM->pLight->isDirty(m_renderType)) + { + pSM->pLight->markClean(m_renderType); + pSM->isDirty = true; + } + m_aFrameLights.erase(id); + pSM->shouldProcess = true; + isSomeFound = true; + } + } + return(isSomeFound); + } + void sortQueue() + { + m_aMapsQueue.quickSort([](const T *a, const T *b){ + return(a->uLastUsed > b->uLastUsed); + }); + } + bool checkIthLight(UINT uMap, int i) + { + if(m_aMapsQueue.size() > uMap) + { + m_aMapsQueue[uMap]->isDirty = true; + m_aMapsQueue[uMap]->shouldProcess = true; + m_aMapsQueue[uMap]->pLight = m_aFrameLights[i]; + m_aFrameLights.erase(i); + return(true); + } + return(false); + } + void processTheRest() + { + T *pSM; + for(UINT i = 0, l = m_aMaps.size(); i < l; ++i) + { + pSM = &m_aMaps[i]; + if(pSM->shouldProcess) + { + pSM->uLastUsed = 0; + pSM->shouldProcess = false; + if(pSM->isDirty) + { + pSM->map.setLight(pSM->pLight); + pSM->map.process(m_pRenderPipeline); + pSM->isDirty = false; + } + + m_aReadyMaps.push_back({&pSM->map, pSM->pLight}); + } + } + } + void dropCaches() + { + m_aMaps.resizeFast(0); + m_aMapsQueue.resizeFast(0); + } + }; struct ReadyShadows { @@ -92,6 +245,22 @@ protected: Array<ReadyShadows> m_aReadyMaps; + struct ReadyReflectiveShadows + { + IBaseReflectiveShadowMap *pShadowMap; + IXLight *pLight; + }; + + Array<ReadyReflectiveShadows> m_aReadyReflectiveMaps; + + Cache<ShadowMap, ReadyShadows> m_shadowMaps; + Cache<ShadowCubeMap, ReadyShadows> m_shadowCubeMaps; + Cache<ReflectiveShadowMap, ReadyReflectiveShadows> m_reflectiveShadowMaps; + Cache<ReflectiveShadowCubeMap, ReadyReflectiveShadows> m_reflectiveShadowCubeMaps; + + ShadowPSSM *m_pShadowPSSM = NULL; + ReflectiveShadowSun *m_pReflectiveShadowSun = NULL; + //XGeometryShaderHandler *m_pRSMGeometryShader = NULL; XGeometryShaderHandler *m_pCubemapGeometryShader = NULL; XGeometryShaderHandler *m_pPSSMGeometryShader[PSSM_MAX_SPLITS]; diff --git a/source/render/shadow.cpp b/source/render/shadow.cpp index da8630757..e2adbab0e 100644 --- a/source/render/shadow.cpp +++ b/source/render/shadow.cpp @@ -774,11 +774,11 @@ void CShadowPSSM::genShadow(IGXTexture2D *pShadowMap, IGXTexture2D *pGBufferDept //########################################################################## -CReflectiveShadowPSSM::CReflectiveShadowPSSM() +CReflectiveShadowSun::CReflectiveShadowSun() { } -CReflectiveShadowPSSM::~CReflectiveShadowPSSM() +CReflectiveShadowSun::~CReflectiveShadowSun() { mem_release(m_pSamplerComparisonLinearClamp); mem_release(m_pDepthStencilSurface); @@ -798,7 +798,7 @@ CReflectiveShadowPSSM::~CReflectiveShadowPSSM() } } -UINT CReflectiveShadowPSSM::GetMapMemory(UINT uSize) +UINT CReflectiveShadowSun::GetMapMemory(UINT uSize) { //GXFMT_R32F - shadow //GXFMT_A8R8G8B8 - xyz:color; w:??? @@ -807,12 +807,12 @@ UINT CReflectiveShadowPSSM::GetMapMemory(UINT uSize) return(uSize * uSize * 12 * PSSM_MAX_SPLITS); } -void CReflectiveShadowPSSM::setObserverCamera(ICamera *pCamera) +void CReflectiveShadowSun::setObserverCamera(ICamera *pCamera) { m_pCamera = pCamera; } -void CReflectiveShadowPSSM::init(IGXDevice *pContext, UINT uSize) +void CReflectiveShadowSun::init(IGXDevice *pContext, UINT uSize) { m_pDevice = pContext; @@ -882,12 +882,12 @@ void CReflectiveShadowPSSM::init(IGXDevice *pContext, UINT uSize) m_pCameraShaderDataVS = m_pDevice->createConstantBuffer(sizeof(m_cameraShaderData.vs)); } -void CReflectiveShadowPSSM::setLight(IXLight *pLight) +void CReflectiveShadowSun::setLight(IXLight *pLight) { m_pLight = pLight; } -void CReflectiveShadowPSSM::process(IXRenderPipeline *pRenderPipeline) +void CReflectiveShadowSun::process(IXRenderPipeline *pRenderPipeline) { assert(m_pLight && m_pLight->getType() == LIGHT_TYPE_SUN); if(!m_pDevice) @@ -960,6 +960,10 @@ void CReflectiveShadowPSSM::process(IXRenderPipeline *pRenderPipeline) #endif } +void CReflectiveShadowSun::genLPV(bool isDebug) +{ +} + //########################################################################## CShadowCubeMap::CShadowCubeMap() diff --git a/source/render/shadow.h b/source/render/shadow.h index 6ef64f394..4d56c2612 100644 --- a/source/render/shadow.h +++ b/source/render/shadow.h @@ -15,6 +15,10 @@ See the license in LICENSE #include <gcore/sxgcore.h> #include <light/IXLight.h> +#define RSM_POINT_SIZE 32 +#define RSM_SPOT_SIZE 32 +#define RSM_SUN_SIZE 32 + class IXTexture; class IBaseShadowMap { @@ -258,11 +262,11 @@ private: //########################################################################## -class CReflectiveShadowPSSM: public IBaseShadowMap +class CReflectiveShadowSun: public IBaseReflectiveShadowMap { public: - CReflectiveShadowPSSM(); - ~CReflectiveShadowPSSM(); + CReflectiveShadowSun(); + ~CReflectiveShadowSun(); SX_ALIGNED_OP_MEM2(); @@ -273,7 +277,7 @@ public: void setObserverCamera(ICamera *pCamera); void setLight(IXLight *pLight); void process(IXRenderPipeline *pRenderPipeline); - // void genLPV(bool isDebug = false) override; + void genLPV(bool isDebug = false) override; private: IGXDevice *m_pDevice = NULL; -- GitLab