dualParaboloidLightShadowMap.cpp
Engine/source/lighting/shadowMap/dualParaboloidLightShadowMap.cpp
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "lighting/shadowMap/dualParaboloidLightShadowMap.h" 26#include "lighting/common/lightMapParams.h" 27#include "lighting/shadowMap/shadowMapManager.h" 28#include "math/mathUtils.h" 29#include "scene/sceneManager.h" 30#include "scene/sceneRenderState.h" 31#include "gfx/gfxDebugEvent.h" 32#include "gfx/gfxDevice.h" 33#include "gfx/gfxTransformSaver.h" 34#include "gfx/util/gfxFrustumSaver.h" 35#include "renderInstance/renderPassManager.h" 36#include "materials/materialDefinition.h" 37#include "math/util/matrixSet.h" 38 39DualParaboloidLightShadowMap::DualParaboloidLightShadowMap( LightInfo *light ) 40 : Parent( light ) 41{ 42} 43 44void DualParaboloidLightShadowMap::_render( RenderPassManager* renderPass, 45 const SceneRenderState *diffuseState ) 46{ 47 PROFILE_SCOPE(DualParaboloidLightShadowMap_render); 48 49 const ShadowMapParams *p = mLight->getExtended<ShadowMapParams>(); 50 const LightMapParams *lmParams = mLight->getExtended<LightMapParams>(); 51 const bool bUseLightmappedGeometry = lmParams ? !lmParams->representedInLightmap || lmParams->includeLightmappedGeometryInShadow : true; 52 53 const U32 texSize = getBestTexSize( 2 ); 54 55 if ( mShadowMapTex.isNull() || 56 mTexSize != texSize ) 57 { 58 mTexSize = texSize; 59 60 mShadowMapTex.set( mTexSize * 2, mTexSize, 61 ShadowMapFormat, &ShadowMapProfile, 62 "DualParaboloidLightShadowMap" ); 63 mShadowMapDepth = _getDepthTarget( mShadowMapTex->getWidth(), mShadowMapTex->getHeight() ); 64 } 65 66 GFXFrustumSaver frustSaver; 67 GFXTransformSaver saver; 68 69 // Set and Clear target 70 GFX->pushActiveRenderTarget(); 71 72 mTarget->attachTexture(GFXTextureTarget::Color0, mShadowMapTex); 73 mTarget->attachTexture( GFXTextureTarget::DepthStencil, mShadowMapDepth ); 74 GFX->setActiveRenderTarget(mTarget); 75 GFX->clear(GFXClearTarget | GFXClearStencil | GFXClearZBuffer, ColorI::WHITE, 1.0f, 0); 76 77 const bool bUseSinglePassDPM = (p->shadowType == ShadowType_DualParaboloidSinglePass); 78 79 // Set up matrix and visible distance 80 mWorldToLightProj = mLight->getTransform(); 81 mWorldToLightProj.inverse(); 82 83 const F32 &lightRadius = mLight->getRange().x; 84 const F32 paraboloidNearPlane = 0.01f; 85 const F32 renderPosOffset = 0.01f; 86 87 // Alter for creation of scene state if this is a single pass map 88 if(bUseSinglePassDPM) 89 { 90 VectorF camDir; 91 MatrixF temp = mLight->getTransform(); 92 temp.getColumn(1, &camDir); 93 temp.setPosition(mLight->getPosition() - camDir * (lightRadius + renderPosOffset)); 94 temp.inverse(); 95 GFX->setWorldMatrix(temp); 96 GFX->setOrtho(-lightRadius, lightRadius, -lightRadius, lightRadius, paraboloidNearPlane, 2.0f * lightRadius, true); 97 } 98 else 99 { 100 VectorF camDir; 101 MatrixF temp = mLight->getTransform(); 102 temp.getColumn(1, &camDir); 103 temp.setPosition(mLight->getPosition() - camDir * renderPosOffset); 104 temp.inverse(); 105 GFX->setWorldMatrix(temp); 106 107 GFX->setOrtho(-lightRadius, lightRadius, -lightRadius, lightRadius, paraboloidNearPlane, lightRadius, true); 108 } 109 110 SceneManager* sceneManager = diffuseState->getSceneManager(); 111 112 // Front map render 113 { 114 SceneRenderState frontMapRenderState 115 ( 116 sceneManager, 117 SPT_Shadow, 118 SceneCameraState::fromGFXWithViewport( diffuseState->getViewport() ), 119 renderPass 120 ); 121 122 frontMapRenderState.getMaterialDelegate().bind( this, &LightShadowMap::getShadowMaterial ); 123 frontMapRenderState.renderNonLightmappedMeshes( true ); 124 frontMapRenderState.renderLightmappedMeshes( bUseLightmappedGeometry ); 125 frontMapRenderState.setDiffuseCameraTransform( diffuseState->getCameraTransform() ); 126 frontMapRenderState.setWorldToScreenScale( diffuseState->getWorldToScreenScale() ); 127 128 if(bUseSinglePassDPM) 129 { 130 GFX->setWorldMatrix(mWorldToLightProj); 131 frontMapRenderState.getRenderPass()->getMatrixSet().setSceneView(mWorldToLightProj); 132 GFX->setOrtho(-lightRadius, lightRadius, -lightRadius, lightRadius, paraboloidNearPlane, lightRadius, true); 133 } 134 135 GFXDEBUGEVENT_SCOPE( DualParaboloidLightShadowMap_Render_FrontFacingParaboloid, ColorI::RED ); 136 mShadowMapScale.set(0.5f, 1.0f); 137 mShadowMapOffset.set(-0.5f, 0.0f); 138 sceneManager->renderSceneNoLights( &frontMapRenderState, SHADOW_TYPEMASK ); 139 _debugRender( &frontMapRenderState ); 140 } 141 142 // Back map render 143 if(!bUseSinglePassDPM) 144 { 145 GFXDEBUGEVENT_SCOPE( DualParaboloidLightShadowMap_Render_BackFacingParaboloid, ColorI::RED ); 146 147 mShadowMapScale.set(0.5f, 1.0f); 148 mShadowMapOffset.set(0.5f, 0.0f); 149 150 // Invert direction on camera matrix 151 VectorF right, forward; 152 MatrixF temp = mLight->getTransform(); 153 temp.getColumn( 1, &forward ); 154 temp.getColumn( 0, &right ); 155 forward *= -1.0f; 156 right *= -1.0f; 157 temp.setColumn( 1, forward ); 158 temp.setColumn( 0, right ); 159 temp.setPosition(mLight->getPosition() - forward * -renderPosOffset); 160 temp.inverse(); 161 GFX->setWorldMatrix(temp); 162 163 // Create an inverted scene state for the back-map 164 165 SceneRenderState backMapRenderState 166 ( 167 sceneManager, 168 SPT_Shadow, 169 SceneCameraState::fromGFXWithViewport( diffuseState->getViewport() ), 170 renderPass 171 ); 172 173 backMapRenderState.getMaterialDelegate().bind( this, &LightShadowMap::getShadowMaterial ); 174 backMapRenderState.renderNonLightmappedMeshes( true ); 175 backMapRenderState.renderLightmappedMeshes( bUseLightmappedGeometry ); 176 backMapRenderState.setDiffuseCameraTransform( diffuseState->getCameraTransform() ); 177 backMapRenderState.setWorldToScreenScale( diffuseState->getWorldToScreenScale() ); 178 179 backMapRenderState.getRenderPass()->getMatrixSet().setSceneView(temp); 180 181 // Draw scene 182 sceneManager->renderSceneNoLights( &backMapRenderState ); 183 _debugRender( &backMapRenderState ); 184 } 185 186 mTarget->resolve(); 187 GFX->popActiveRenderTarget(); 188} 189