mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-15 16:44:36 +00:00
Merge pull request #1442 from Azaezel/shadow_caching
This all seems to work pretty well.
This commit is contained in:
commit
92aa785bb2
61 changed files with 1490 additions and 466 deletions
|
|
@ -60,6 +60,8 @@ LightBase::LightBase()
|
||||||
mColor( ColorF::WHITE ),
|
mColor( ColorF::WHITE ),
|
||||||
mBrightness( 1.0f ),
|
mBrightness( 1.0f ),
|
||||||
mCastShadows( false ),
|
mCastShadows( false ),
|
||||||
|
mStaticRefreshFreq( 250 ),
|
||||||
|
mDynamicRefreshFreq( 8 ),
|
||||||
mPriority( 1.0f ),
|
mPriority( 1.0f ),
|
||||||
mAnimationData( NULL ),
|
mAnimationData( NULL ),
|
||||||
mFlareData( NULL ),
|
mFlareData( NULL ),
|
||||||
|
|
@ -90,6 +92,8 @@ void LightBase::initPersistFields()
|
||||||
addField( "color", TypeColorF, Offset( mColor, LightBase ), "Changes the base color hue of the light." );
|
addField( "color", TypeColorF, Offset( mColor, LightBase ), "Changes the base color hue of the light." );
|
||||||
addField( "brightness", TypeF32, Offset( mBrightness, LightBase ), "Adjusts the lights power, 0 being off completely." );
|
addField( "brightness", TypeF32, Offset( mBrightness, LightBase ), "Adjusts the lights power, 0 being off completely." );
|
||||||
addField( "castShadows", TypeBool, Offset( mCastShadows, LightBase ), "Enables/disabled shadow casts by this light." );
|
addField( "castShadows", TypeBool, Offset( mCastShadows, LightBase ), "Enables/disabled shadow casts by this light." );
|
||||||
|
addField( "staticRefreshFreq", TypeS32, Offset( mStaticRefreshFreq, LightBase ), "static shadow refresh rate (milliseconds)" );
|
||||||
|
addField( "dynamicRefreshFreq", TypeS32, Offset( mDynamicRefreshFreq, LightBase ), "dynamic shadow refresh rate (milliseconds)" );
|
||||||
addField( "priority", TypeF32, Offset( mPriority, LightBase ), "Used for sorting of lights by the light manager. "
|
addField( "priority", TypeF32, Offset( mPriority, LightBase ), "Used for sorting of lights by the light manager. "
|
||||||
"Priority determines if a light has a stronger effect than, those with a lower value" );
|
"Priority determines if a light has a stronger effect than, those with a lower value" );
|
||||||
|
|
||||||
|
|
@ -277,6 +281,8 @@ U32 LightBase::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
|
||||||
stream->write( mBrightness );
|
stream->write( mBrightness );
|
||||||
|
|
||||||
stream->writeFlag( mCastShadows );
|
stream->writeFlag( mCastShadows );
|
||||||
|
stream->write(mStaticRefreshFreq);
|
||||||
|
stream->write(mDynamicRefreshFreq);
|
||||||
|
|
||||||
stream->write( mPriority );
|
stream->write( mPriority );
|
||||||
|
|
||||||
|
|
@ -322,6 +328,8 @@ void LightBase::unpackUpdate( NetConnection *conn, BitStream *stream )
|
||||||
stream->read( &mColor );
|
stream->read( &mColor );
|
||||||
stream->read( &mBrightness );
|
stream->read( &mBrightness );
|
||||||
mCastShadows = stream->readFlag();
|
mCastShadows = stream->readFlag();
|
||||||
|
stream->read(&mStaticRefreshFreq);
|
||||||
|
stream->read(&mDynamicRefreshFreq);
|
||||||
|
|
||||||
stream->read( &mPriority );
|
stream->read( &mPriority );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,8 @@ protected:
|
||||||
F32 mBrightness;
|
F32 mBrightness;
|
||||||
|
|
||||||
bool mCastShadows;
|
bool mCastShadows;
|
||||||
|
S32 mStaticRefreshFreq;
|
||||||
|
S32 mDynamicRefreshFreq;
|
||||||
F32 mPriority;
|
F32 mPriority;
|
||||||
|
|
||||||
LightInfo *mLight;
|
LightInfo *mLight;
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@ LightDescription::LightDescription()
|
||||||
brightness( 1.0f ),
|
brightness( 1.0f ),
|
||||||
range( 5.0f ),
|
range( 5.0f ),
|
||||||
castShadows( false ),
|
castShadows( false ),
|
||||||
|
mStaticRefreshFreq( 250 ),
|
||||||
|
mDynamicRefreshFreq( 8 ),
|
||||||
animationData( NULL ),
|
animationData( NULL ),
|
||||||
animationDataId( 0 ),
|
animationDataId( 0 ),
|
||||||
animationPeriod( 1.0f ),
|
animationPeriod( 1.0f ),
|
||||||
|
|
@ -94,6 +96,8 @@ void LightDescription::initPersistFields()
|
||||||
addField( "brightness", TypeF32, Offset( brightness, LightDescription ), "Adjusts the lights power, 0 being off completely." );
|
addField( "brightness", TypeF32, Offset( brightness, LightDescription ), "Adjusts the lights power, 0 being off completely." );
|
||||||
addField( "range", TypeF32, Offset( range, LightDescription ), "Controls the size (radius) of the light" );
|
addField( "range", TypeF32, Offset( range, LightDescription ), "Controls the size (radius) of the light" );
|
||||||
addField( "castShadows", TypeBool, Offset( castShadows, LightDescription ), "Enables/disabled shadow casts by this light." );
|
addField( "castShadows", TypeBool, Offset( castShadows, LightDescription ), "Enables/disabled shadow casts by this light." );
|
||||||
|
addField( "staticRefreshFreq", TypeS32, Offset( mStaticRefreshFreq, LightDescription ), "static shadow refresh rate (milliseconds)" );
|
||||||
|
addField( "dynamicRefreshFreq", TypeS32, Offset( mDynamicRefreshFreq, LightDescription ), "dynamic shadow refresh rate (milliseconds)" );
|
||||||
|
|
||||||
endGroup( "Light" );
|
endGroup( "Light" );
|
||||||
|
|
||||||
|
|
@ -153,6 +157,8 @@ void LightDescription::packData( BitStream *stream )
|
||||||
stream->write( brightness );
|
stream->write( brightness );
|
||||||
stream->write( range );
|
stream->write( range );
|
||||||
stream->writeFlag( castShadows );
|
stream->writeFlag( castShadows );
|
||||||
|
stream->write(mStaticRefreshFreq);
|
||||||
|
stream->write(mDynamicRefreshFreq);
|
||||||
|
|
||||||
stream->write( animationPeriod );
|
stream->write( animationPeriod );
|
||||||
stream->write( animationPhase );
|
stream->write( animationPhase );
|
||||||
|
|
@ -181,6 +187,8 @@ void LightDescription::unpackData( BitStream *stream )
|
||||||
stream->read( &brightness );
|
stream->read( &brightness );
|
||||||
stream->read( &range );
|
stream->read( &range );
|
||||||
castShadows = stream->readFlag();
|
castShadows = stream->readFlag();
|
||||||
|
stream->read(&mStaticRefreshFreq);
|
||||||
|
stream->read(&mDynamicRefreshFreq);
|
||||||
|
|
||||||
stream->read( &animationPeriod );
|
stream->read( &animationPeriod );
|
||||||
stream->read( &animationPhase );
|
stream->read( &animationPhase );
|
||||||
|
|
@ -200,6 +208,8 @@ void LightDescription::submitLight( LightState *state, const MatrixF &xfm, Light
|
||||||
li->setRange( range );
|
li->setRange( range );
|
||||||
li->setColor( color );
|
li->setColor( color );
|
||||||
li->setCastShadows( castShadows );
|
li->setCastShadows( castShadows );
|
||||||
|
li->setStaticRefreshFreq(mStaticRefreshFreq);
|
||||||
|
li->setDynamicRefreshFreq(mDynamicRefreshFreq);
|
||||||
li->setTransform( xfm );
|
li->setTransform( xfm );
|
||||||
|
|
||||||
if ( animationData )
|
if ( animationData )
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,8 @@ public:
|
||||||
F32 brightness;
|
F32 brightness;
|
||||||
F32 range;
|
F32 range;
|
||||||
bool castShadows;
|
bool castShadows;
|
||||||
|
S32 mStaticRefreshFreq;
|
||||||
|
S32 mDynamicRefreshFreq;
|
||||||
|
|
||||||
LightAnimData *animationData;
|
LightAnimData *animationData;
|
||||||
S32 animationDataId;
|
S32 animationDataId;
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,8 @@ void PointLight::_conformLights()
|
||||||
|
|
||||||
mLight->setBrightness( mBrightness );
|
mLight->setBrightness( mBrightness );
|
||||||
mLight->setCastShadows( mCastShadows );
|
mLight->setCastShadows( mCastShadows );
|
||||||
|
mLight->setStaticRefreshFreq(mStaticRefreshFreq);
|
||||||
|
mLight->setDynamicRefreshFreq(mDynamicRefreshFreq);
|
||||||
mLight->setPriority( mPriority );
|
mLight->setPriority( mPriority );
|
||||||
|
|
||||||
// Update the bounds and scale to fit our light.
|
// Update the bounds and scale to fit our light.
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,8 @@ void SpotLight::_conformLights()
|
||||||
mLight->setColor( mColor );
|
mLight->setColor( mColor );
|
||||||
mLight->setBrightness( mBrightness );
|
mLight->setBrightness( mBrightness );
|
||||||
mLight->setCastShadows( mCastShadows );
|
mLight->setCastShadows( mCastShadows );
|
||||||
|
mLight->setStaticRefreshFreq(mStaticRefreshFreq);
|
||||||
|
mLight->setDynamicRefreshFreq(mDynamicRefreshFreq);
|
||||||
mLight->setPriority( mPriority );
|
mLight->setPriority( mPriority );
|
||||||
|
|
||||||
mOuterConeAngle = getMax( 0.01f, mOuterConeAngle );
|
mOuterConeAngle = getMax( 0.01f, mOuterConeAngle );
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,8 @@ ScatterSky::ScatterSky()
|
||||||
mBrightness = 1.0f;
|
mBrightness = 1.0f;
|
||||||
|
|
||||||
mCastShadows = true;
|
mCastShadows = true;
|
||||||
|
mStaticRefreshFreq = 8;
|
||||||
|
mDynamicRefreshFreq = 8;
|
||||||
mDirty = true;
|
mDirty = true;
|
||||||
|
|
||||||
mLight = LightManager::createLightInfo();
|
mLight = LightManager::createLightInfo();
|
||||||
|
|
@ -264,6 +266,8 @@ void ScatterSky::_conformLights()
|
||||||
mLight->setAmbient( mAmbientColor );
|
mLight->setAmbient( mAmbientColor );
|
||||||
mLight->setColor( mSunColor );
|
mLight->setColor( mSunColor );
|
||||||
mLight->setCastShadows( mCastShadows );
|
mLight->setCastShadows( mCastShadows );
|
||||||
|
mLight->setStaticRefreshFreq(mStaticRefreshFreq);
|
||||||
|
mLight->setDynamicRefreshFreq(mDynamicRefreshFreq);
|
||||||
|
|
||||||
FogData fog = getSceneManager()->getFogData();
|
FogData fog = getSceneManager()->getFogData();
|
||||||
fog.color = mFogColor;
|
fog.color = mFogColor;
|
||||||
|
|
@ -374,6 +378,9 @@ void ScatterSky::initPersistFields()
|
||||||
addField( "castShadows", TypeBool, Offset( mCastShadows, ScatterSky ),
|
addField( "castShadows", TypeBool, Offset( mCastShadows, ScatterSky ),
|
||||||
"Enables/disables shadows cast by objects due to ScatterSky light." );
|
"Enables/disables shadows cast by objects due to ScatterSky light." );
|
||||||
|
|
||||||
|
addField("staticRefreshFreq", TypeS32, Offset(mStaticRefreshFreq, ScatterSky), "static shadow refresh rate (milliseconds)");
|
||||||
|
addField("dynamicRefreshFreq", TypeS32, Offset(mDynamicRefreshFreq, ScatterSky), "dynamic shadow refresh rate (milliseconds)");
|
||||||
|
|
||||||
addField( "brightness", TypeF32, Offset( mBrightness, ScatterSky ),
|
addField( "brightness", TypeF32, Offset( mBrightness, ScatterSky ),
|
||||||
"The brightness of the ScatterSky's light object." );
|
"The brightness of the ScatterSky's light object." );
|
||||||
|
|
||||||
|
|
@ -480,6 +487,8 @@ U32 ScatterSky::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
|
||||||
stream->write( mBrightness );
|
stream->write( mBrightness );
|
||||||
|
|
||||||
stream->writeFlag( mCastShadows );
|
stream->writeFlag( mCastShadows );
|
||||||
|
stream->write(mStaticRefreshFreq);
|
||||||
|
stream->write(mDynamicRefreshFreq);
|
||||||
|
|
||||||
stream->write( mFlareScale );
|
stream->write( mFlareScale );
|
||||||
|
|
||||||
|
|
@ -581,6 +590,8 @@ void ScatterSky::unpackUpdate(NetConnection *con, BitStream *stream)
|
||||||
stream->read( &mBrightness );
|
stream->read( &mBrightness );
|
||||||
|
|
||||||
mCastShadows = stream->readFlag();
|
mCastShadows = stream->readFlag();
|
||||||
|
stream->read(&mStaticRefreshFreq);
|
||||||
|
stream->read(&mDynamicRefreshFreq);
|
||||||
|
|
||||||
stream->read( &mFlareScale );
|
stream->read( &mFlareScale );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,8 @@ protected:
|
||||||
LightInfo *mLight;
|
LightInfo *mLight;
|
||||||
|
|
||||||
bool mCastShadows;
|
bool mCastShadows;
|
||||||
|
S32 mStaticRefreshFreq;
|
||||||
|
S32 mDynamicRefreshFreq;
|
||||||
bool mDirty;
|
bool mDirty;
|
||||||
|
|
||||||
LightFlareData *mFlareData;
|
LightFlareData *mFlareData;
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,8 @@ Sun::Sun()
|
||||||
mSunAzimuth = 0.0f;
|
mSunAzimuth = 0.0f;
|
||||||
mSunElevation = 35.0f;
|
mSunElevation = 35.0f;
|
||||||
mCastShadows = true;
|
mCastShadows = true;
|
||||||
|
mStaticRefreshFreq = 250;
|
||||||
|
mDynamicRefreshFreq = 8;
|
||||||
|
|
||||||
mAnimateSun = false;
|
mAnimateSun = false;
|
||||||
mTotalTime = 0.0f;
|
mTotalTime = 0.0f;
|
||||||
|
|
@ -165,6 +167,9 @@ void Sun::initPersistFields()
|
||||||
addField( "castShadows", TypeBool, Offset( mCastShadows, Sun ),
|
addField( "castShadows", TypeBool, Offset( mCastShadows, Sun ),
|
||||||
"Enables/disables shadows cast by objects due to Sun light");
|
"Enables/disables shadows cast by objects due to Sun light");
|
||||||
|
|
||||||
|
addField("staticRefreshFreq", TypeS32, Offset(mStaticRefreshFreq, Sun), "static shadow refresh rate (milliseconds)");
|
||||||
|
addField("dynamicRefreshFreq", TypeS32, Offset(mDynamicRefreshFreq, Sun), "dynamic shadow refresh rate (milliseconds)");
|
||||||
|
|
||||||
endGroup( "Lighting" );
|
endGroup( "Lighting" );
|
||||||
|
|
||||||
addGroup( "Corona" );
|
addGroup( "Corona" );
|
||||||
|
|
@ -221,6 +226,8 @@ U32 Sun::packUpdate(NetConnection *conn, U32 mask, BitStream *stream )
|
||||||
stream->write( mLightAmbient );
|
stream->write( mLightAmbient );
|
||||||
stream->write( mBrightness );
|
stream->write( mBrightness );
|
||||||
stream->writeFlag( mCastShadows );
|
stream->writeFlag( mCastShadows );
|
||||||
|
stream->write(mStaticRefreshFreq);
|
||||||
|
stream->write(mDynamicRefreshFreq);
|
||||||
stream->write( mFlareScale );
|
stream->write( mFlareScale );
|
||||||
|
|
||||||
if ( stream->writeFlag( mFlareData ) )
|
if ( stream->writeFlag( mFlareData ) )
|
||||||
|
|
@ -254,6 +261,8 @@ void Sun::unpackUpdate( NetConnection *conn, BitStream *stream )
|
||||||
stream->read( &mLightAmbient );
|
stream->read( &mLightAmbient );
|
||||||
stream->read( &mBrightness );
|
stream->read( &mBrightness );
|
||||||
mCastShadows = stream->readFlag();
|
mCastShadows = stream->readFlag();
|
||||||
|
stream->read(&mStaticRefreshFreq);
|
||||||
|
stream->read(&mDynamicRefreshFreq);
|
||||||
stream->read( &mFlareScale );
|
stream->read( &mFlareScale );
|
||||||
|
|
||||||
if ( stream->readFlag() )
|
if ( stream->readFlag() )
|
||||||
|
|
@ -426,6 +435,8 @@ void Sun::_conformLights()
|
||||||
// directional color are the same.
|
// directional color are the same.
|
||||||
bool castShadows = mLightColor != mLightAmbient && mCastShadows;
|
bool castShadows = mLightColor != mLightAmbient && mCastShadows;
|
||||||
mLight->setCastShadows( castShadows );
|
mLight->setCastShadows( castShadows );
|
||||||
|
mLight->setStaticRefreshFreq(mStaticRefreshFreq);
|
||||||
|
mLight->setDynamicRefreshFreq(mDynamicRefreshFreq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sun::_initCorona()
|
void Sun::_initCorona()
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,8 @@ protected:
|
||||||
F32 mEndElevation;
|
F32 mEndElevation;
|
||||||
|
|
||||||
bool mCastShadows;
|
bool mCastShadows;
|
||||||
|
S32 mStaticRefreshFreq;
|
||||||
|
S32 mDynamicRefreshFreq;
|
||||||
|
|
||||||
LightInfo *mLight;
|
LightInfo *mLight;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,9 @@ S32 ForestCell::renderBatches( SceneRenderState *state, Frustum *culler )
|
||||||
if ( culler && culler->isCulled( mBatches[i]->getWorldBox() ) )
|
if ( culler && culler->isCulled( mBatches[i]->getWorldBox() ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if( state->getCullingState().isOccludedWithExtraPlanesCull( mBatches[i]->getWorldBox() ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
mBatches[i]->render( state );
|
mBatches[i]->render( state );
|
||||||
renderedItems += mBatches[i]->getItemCount();
|
renderedItems += mBatches[i]->getItemCount();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -197,6 +197,10 @@ void Forest::prepRenderImage( SceneRenderState *state )
|
||||||
if ( smDisableImposters )
|
if ( smDisableImposters )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// if cell are to far for largest item, then skip out.
|
||||||
|
if( TSShapeInstance::smLastPixelSize < TSShapeInstance::smSmallestVisiblePixelSize )
|
||||||
|
continue;
|
||||||
|
|
||||||
PROFILE_SCOPE(Forest_RenderBatches);
|
PROFILE_SCOPE(Forest_RenderBatches);
|
||||||
|
|
||||||
// Keep track of how many cells were batched.
|
// Keep track of how many cells were batched.
|
||||||
|
|
|
||||||
|
|
@ -191,6 +191,7 @@ void AdvancedLightBinManager::addLight( LightInfo *light )
|
||||||
// Find a shadow map for this light, if it has one
|
// Find a shadow map for this light, if it has one
|
||||||
ShadowMapParams *lsp = light->getExtended<ShadowMapParams>();
|
ShadowMapParams *lsp = light->getExtended<ShadowMapParams>();
|
||||||
LightShadowMap *lsm = lsp->getShadowMap();
|
LightShadowMap *lsm = lsp->getShadowMap();
|
||||||
|
LightShadowMap *dynamicShadowMap = lsp->getShadowMap(true);
|
||||||
|
|
||||||
// Get the right shadow type.
|
// Get the right shadow type.
|
||||||
ShadowType shadowType = ShadowType_None;
|
ShadowType shadowType = ShadowType_None;
|
||||||
|
|
@ -203,6 +204,7 @@ void AdvancedLightBinManager::addLight( LightInfo *light )
|
||||||
LightBinEntry lEntry;
|
LightBinEntry lEntry;
|
||||||
lEntry.lightInfo = light;
|
lEntry.lightInfo = light;
|
||||||
lEntry.shadowMap = lsm;
|
lEntry.shadowMap = lsm;
|
||||||
|
lEntry.dynamicShadowMap = dynamicShadowMap;
|
||||||
lEntry.lightMaterial = _getLightMaterial( lightType, shadowType, lsp->hasCookieTex() );
|
lEntry.lightMaterial = _getLightMaterial( lightType, shadowType, lsp->hasCookieTex() );
|
||||||
|
|
||||||
if( lightType == LightInfo::Spot )
|
if( lightType == LightInfo::Spot )
|
||||||
|
|
@ -325,10 +327,12 @@ void AdvancedLightBinManager::render( SceneRenderState *state )
|
||||||
setupSGData( sgData, state, curLightInfo );
|
setupSGData( sgData, state, curLightInfo );
|
||||||
curLightMat->setLightParameters( curLightInfo, state, worldToCameraXfm );
|
curLightMat->setLightParameters( curLightInfo, state, worldToCameraXfm );
|
||||||
mShadowManager->setLightShadowMap( curEntry.shadowMap );
|
mShadowManager->setLightShadowMap( curEntry.shadowMap );
|
||||||
|
mShadowManager->setLightDynamicShadowMap( curEntry.dynamicShadowMap );
|
||||||
|
|
||||||
// Let the shadow know we're about to render from it.
|
// Let the shadow know we're about to render from it.
|
||||||
if ( curEntry.shadowMap )
|
if ( curEntry.shadowMap )
|
||||||
curEntry.shadowMap->preLightRender();
|
curEntry.shadowMap->preLightRender();
|
||||||
|
if ( curEntry.dynamicShadowMap ) curEntry.dynamicShadowMap->preLightRender();
|
||||||
|
|
||||||
// Set geometry
|
// Set geometry
|
||||||
GFX->setVertexBuffer( curEntry.vertBuffer );
|
GFX->setVertexBuffer( curEntry.vertBuffer );
|
||||||
|
|
@ -351,10 +355,12 @@ void AdvancedLightBinManager::render( SceneRenderState *state )
|
||||||
// Tell it we're done rendering.
|
// Tell it we're done rendering.
|
||||||
if ( curEntry.shadowMap )
|
if ( curEntry.shadowMap )
|
||||||
curEntry.shadowMap->postLightRender();
|
curEntry.shadowMap->postLightRender();
|
||||||
|
if ( curEntry.dynamicShadowMap ) curEntry.dynamicShadowMap->postLightRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set NULL for active shadow map (so nothing gets confused)
|
// Set NULL for active shadow map (so nothing gets confused)
|
||||||
mShadowManager->setLightShadowMap(NULL);
|
mShadowManager->setLightShadowMap(NULL);
|
||||||
|
mShadowManager->setLightDynamicShadowMap(NULL);
|
||||||
GFX->setVertexBuffer( NULL );
|
GFX->setVertexBuffer( NULL );
|
||||||
GFX->setPrimitiveBuffer( NULL );
|
GFX->setPrimitiveBuffer( NULL );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,7 @@ protected:
|
||||||
{
|
{
|
||||||
LightInfo* lightInfo;
|
LightInfo* lightInfo;
|
||||||
LightShadowMap* shadowMap;
|
LightShadowMap* shadowMap;
|
||||||
|
LightShadowMap* dynamicShadowMap;
|
||||||
LightMaterialInfo* lightMaterial;
|
LightMaterialInfo* lightMaterial;
|
||||||
GFXPrimitiveBuffer* primBuffer;
|
GFXPrimitiveBuffer* primBuffer;
|
||||||
GFXVertexBuffer* vertBuffer;
|
GFXVertexBuffer* vertBuffer;
|
||||||
|
|
|
||||||
|
|
@ -357,10 +357,13 @@ void AdvancedLightManager::setLightInfo( ProcessedMaterial *pmat,
|
||||||
LightingShaderConstants *lsc = getLightingShaderConstants(shaderConsts);
|
LightingShaderConstants *lsc = getLightingShaderConstants(shaderConsts);
|
||||||
|
|
||||||
LightShadowMap *lsm = SHADOWMGR->getCurrentShadowMap();
|
LightShadowMap *lsm = SHADOWMGR->getCurrentShadowMap();
|
||||||
|
LightShadowMap *dynamicShadowMap = SHADOWMGR->getCurrentDynamicShadowMap();
|
||||||
|
|
||||||
LightInfo *light;
|
LightInfo *light;
|
||||||
if (lsm)
|
if (lsm)
|
||||||
light = lsm->getLightInfo();
|
light = lsm->getLightInfo();
|
||||||
|
else if ( dynamicShadowMap )
|
||||||
|
light = dynamicShadowMap->getLightInfo();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
light = sgData.lights[0];
|
light = sgData.lights[0];
|
||||||
|
|
@ -388,6 +391,7 @@ void AdvancedLightManager::setLightInfo( ProcessedMaterial *pmat,
|
||||||
lsc->mLightSpotFalloffSC,
|
lsc->mLightSpotFalloffSC,
|
||||||
shaderConsts );
|
shaderConsts );
|
||||||
|
|
||||||
|
// Static
|
||||||
if (lsm && light->getCastShadows())
|
if (lsm && light->getCastShadows())
|
||||||
{
|
{
|
||||||
if ( lsc->mWorldToLightProjSC->isValid() )
|
if ( lsc->mWorldToLightProjSC->isValid() )
|
||||||
|
|
@ -426,6 +430,46 @@ void AdvancedLightManager::setLightInfo( ProcessedMaterial *pmat,
|
||||||
lsc->mViewToLightProjSC->getType() );
|
lsc->mViewToLightProjSC->getType() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dynamic
|
||||||
|
if ( dynamicShadowMap )
|
||||||
|
{
|
||||||
|
if ( lsc->mDynamicWorldToLightProjSC->isValid() )
|
||||||
|
shaderConsts->set( lsc->mDynamicWorldToLightProjSC,
|
||||||
|
dynamicShadowMap->getWorldToLightProj(),
|
||||||
|
lsc->mDynamicWorldToLightProjSC->getType() );
|
||||||
|
|
||||||
|
if ( lsc->mDynamicViewToLightProjSC->isValid() )
|
||||||
|
{
|
||||||
|
// TODO: Should probably cache these results and
|
||||||
|
// not do this mul here on every material that needs
|
||||||
|
// this transform.
|
||||||
|
|
||||||
|
shaderConsts->set( lsc->mDynamicViewToLightProjSC,
|
||||||
|
dynamicShadowMap->getWorldToLightProj() * state->getCameraTransform(),
|
||||||
|
lsc->mDynamicViewToLightProjSC->getType() );
|
||||||
|
}
|
||||||
|
|
||||||
|
shaderConsts->setSafe( lsc->mShadowMapSizeSC, 1.0f / (F32)dynamicShadowMap->getTexSize() );
|
||||||
|
|
||||||
|
// Do this last so that overrides can properly override parameters previously set
|
||||||
|
dynamicShadowMap->setShaderParameters(shaderConsts, lsc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( lsc->mDynamicViewToLightProjSC->isValid() )
|
||||||
|
{
|
||||||
|
// TODO: Should probably cache these results and
|
||||||
|
// not do this mul here on every material that needs
|
||||||
|
// this transform.
|
||||||
|
MatrixF proj;
|
||||||
|
light->getWorldToLightProj( &proj );
|
||||||
|
|
||||||
|
shaderConsts->set( lsc->mDynamicViewToLightProjSC,
|
||||||
|
proj * state->getCameraTransform(),
|
||||||
|
lsc->mDynamicViewToLightProjSC->getType() );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvancedLightManager::registerGlobalLight(LightInfo *light, SimObject *obj)
|
void AdvancedLightManager::registerGlobalLight(LightInfo *light, SimObject *obj)
|
||||||
|
|
@ -454,22 +498,34 @@ bool AdvancedLightManager::setTextureStage( const SceneData &sgData,
|
||||||
ShaderConstHandles *handles )
|
ShaderConstHandles *handles )
|
||||||
{
|
{
|
||||||
LightShadowMap* lsm = SHADOWMGR->getCurrentShadowMap();
|
LightShadowMap* lsm = SHADOWMGR->getCurrentShadowMap();
|
||||||
|
LightShadowMap* dynamicShadowMap = SHADOWMGR->getCurrentDynamicShadowMap();
|
||||||
|
|
||||||
// Assign Shadowmap, if it exists
|
// Assign Shadowmap, if it exists
|
||||||
LightingShaderConstants* lsc = getLightingShaderConstants(shaderConsts);
|
LightingShaderConstants* lsc = getLightingShaderConstants(shaderConsts);
|
||||||
if ( !lsc )
|
if ( !lsc )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if ( currTexFlag == Material::DynamicLight )
|
||||||
|
{
|
||||||
|
// Static
|
||||||
if ( lsm && lsm->getLightInfo()->getCastShadows() )
|
if ( lsm && lsm->getLightInfo()->getCastShadows() )
|
||||||
return lsm->setTextureStage( currTexFlag, lsc );
|
return lsm->setTextureStage( currTexFlag, lsc );
|
||||||
|
|
||||||
|
|
||||||
if ( currTexFlag == Material::DynamicLight )
|
|
||||||
{
|
|
||||||
S32 reg = lsc->mShadowMapSC->getSamplerRegister();
|
S32 reg = lsc->mShadowMapSC->getSamplerRegister();
|
||||||
if ( reg != -1 )
|
if ( reg != -1 )
|
||||||
GFX->setTexture( reg, GFXTexHandle::ONE );
|
GFX->setTexture( reg, GFXTexHandle::ONE );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else if ( currTexFlag == Material::DynamicShadowMap )
|
||||||
|
{
|
||||||
|
// Dynamic
|
||||||
|
if ( dynamicShadowMap )
|
||||||
|
return dynamicShadowMap->setTextureStage( currTexFlag, lsc );
|
||||||
|
|
||||||
|
S32 reg = lsc->mDynamicShadowMapSC->getSamplerRegister();
|
||||||
|
if ( reg != -1 )
|
||||||
|
GFX->setTexture( reg, GFXTexHandle::ONE );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if ( currTexFlag == Material::DynamicLightMask )
|
else if ( currTexFlag == Material::DynamicLightMask )
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,8 @@ LightInfo::LightInfo()
|
||||||
mOuterConeAngle( 90.0f ),
|
mOuterConeAngle( 90.0f ),
|
||||||
mType( Vector ),
|
mType( Vector ),
|
||||||
mCastShadows( false ),
|
mCastShadows( false ),
|
||||||
|
mStaticRefreshFreq( 250 ),
|
||||||
|
mDynamicRefreshFreq( 8 ),
|
||||||
mPriority( 1.0f ),
|
mPriority( 1.0f ),
|
||||||
mScore( 0.0f ),
|
mScore( 0.0f ),
|
||||||
mDebugRender( false )
|
mDebugRender( false )
|
||||||
|
|
@ -72,6 +74,8 @@ void LightInfo::set( const LightInfo *light )
|
||||||
mOuterConeAngle = light->mOuterConeAngle;
|
mOuterConeAngle = light->mOuterConeAngle;
|
||||||
mType = light->mType;
|
mType = light->mType;
|
||||||
mCastShadows = light->mCastShadows;
|
mCastShadows = light->mCastShadows;
|
||||||
|
mStaticRefreshFreq = light->mStaticRefreshFreq;
|
||||||
|
mDynamicRefreshFreq = light->mDynamicRefreshFreq;
|
||||||
|
|
||||||
for ( U32 i=0; i < mExtended.size(); i++ )
|
for ( U32 i=0; i < mExtended.size(); i++ )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,9 @@ protected:
|
||||||
|
|
||||||
bool mCastShadows;
|
bool mCastShadows;
|
||||||
|
|
||||||
|
S32 mStaticRefreshFreq;
|
||||||
|
S32 mDynamicRefreshFreq;
|
||||||
|
|
||||||
::Vector<LightInfoEx*> mExtended;
|
::Vector<LightInfoEx*> mExtended;
|
||||||
|
|
||||||
/// The priority of this light used for
|
/// The priority of this light used for
|
||||||
|
|
@ -191,6 +194,12 @@ public:
|
||||||
bool getCastShadows() const { return mCastShadows; }
|
bool getCastShadows() const { return mCastShadows; }
|
||||||
void setCastShadows( bool castShadows ) { mCastShadows = castShadows; }
|
void setCastShadows( bool castShadows ) { mCastShadows = castShadows; }
|
||||||
|
|
||||||
|
S32 getStaticRefreshFreq() const { return mStaticRefreshFreq; }
|
||||||
|
void setStaticRefreshFreq(S32 _staticRefreshFreq) { mStaticRefreshFreq = _staticRefreshFreq; }
|
||||||
|
|
||||||
|
S32 getDynamicRefreshFreq() const { return mDynamicRefreshFreq; }
|
||||||
|
void setDynamicRefreshFreq(S32 _dynamicRefreshFreq) { mDynamicRefreshFreq = _dynamicRefreshFreq; }
|
||||||
|
|
||||||
void setPriority( F32 priority ) { mPriority = priority; }
|
void setPriority( F32 priority ) { mPriority = priority; }
|
||||||
F32 getPriority() const { return mPriority; }
|
F32 getPriority() const { return mPriority; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,8 @@ LightShadowMap::LightShadowMap( LightInfo *light )
|
||||||
mVizQuery( NULL ),
|
mVizQuery( NULL ),
|
||||||
mWasOccluded( false ),
|
mWasOccluded( false ),
|
||||||
mLastScreenSize( 0.0f ),
|
mLastScreenSize( 0.0f ),
|
||||||
mLastPriority( 0.0f )
|
mLastPriority( 0.0f ),
|
||||||
|
mIsDynamic( false )
|
||||||
{
|
{
|
||||||
GFXTextureManager::addEventDelegate( this, &LightShadowMap::_onTextureEvent );
|
GFXTextureManager::addEventDelegate( this, &LightShadowMap::_onTextureEvent );
|
||||||
|
|
||||||
|
|
@ -100,6 +101,8 @@ LightShadowMap::LightShadowMap( LightInfo *light )
|
||||||
mVizQuery = GFX->createOcclusionQuery();
|
mVizQuery = GFX->createOcclusionQuery();
|
||||||
|
|
||||||
smShadowMaps.push_back(this);
|
smShadowMaps.push_back(this);
|
||||||
|
mStaticRefreshTimer = PlatformTimer::create();
|
||||||
|
mDynamicRefreshTimer = PlatformTimer::create();
|
||||||
}
|
}
|
||||||
|
|
||||||
LightShadowMap::~LightShadowMap()
|
LightShadowMap::~LightShadowMap()
|
||||||
|
|
@ -268,9 +271,18 @@ GFXTextureObject* LightShadowMap::_getDepthTarget( U32 width, U32 height )
|
||||||
|
|
||||||
bool LightShadowMap::setTextureStage( U32 currTexFlag, LightingShaderConstants* lsc )
|
bool LightShadowMap::setTextureStage( U32 currTexFlag, LightingShaderConstants* lsc )
|
||||||
{
|
{
|
||||||
if ( currTexFlag == Material::DynamicLight )
|
if ( currTexFlag == Material::DynamicLight && !isDynamic() )
|
||||||
{
|
{
|
||||||
S32 reg = lsc->mShadowMapSC->getSamplerRegister();
|
S32 reg = lsc->mShadowMapSC->getSamplerRegister();
|
||||||
|
|
||||||
|
if ( reg != -1 )
|
||||||
|
GFX->setTexture( reg, mShadowMapTex);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else if ( currTexFlag == Material::DynamicShadowMap && isDynamic() )
|
||||||
|
{
|
||||||
|
S32 reg = lsc->mDynamicShadowMapSC->getSamplerRegister();
|
||||||
|
|
||||||
if ( reg != -1 )
|
if ( reg != -1 )
|
||||||
GFX->setTexture( reg, mShadowMapTex);
|
GFX->setTexture( reg, mShadowMapTex);
|
||||||
|
|
||||||
|
|
@ -296,8 +308,18 @@ bool LightShadowMap::setTextureStage( U32 currTexFlag, LightingShaderConstants*
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightShadowMap::render( RenderPassManager* renderPass,
|
void LightShadowMap::render( RenderPassManager* renderPass,
|
||||||
const SceneRenderState *diffuseState )
|
const SceneRenderState *diffuseState,
|
||||||
|
bool _dynamic)
|
||||||
{
|
{
|
||||||
|
// control how often shadow maps are refreshed
|
||||||
|
if (!_dynamic && (mStaticRefreshTimer->getElapsedMs() < getLightInfo()->getStaticRefreshFreq()))
|
||||||
|
return;
|
||||||
|
mStaticRefreshTimer->reset();
|
||||||
|
|
||||||
|
if (_dynamic && (mDynamicRefreshTimer->getElapsedMs() < getLightInfo()->getDynamicRefreshFreq()))
|
||||||
|
return;
|
||||||
|
mDynamicRefreshTimer->reset();
|
||||||
|
|
||||||
mDebugTarget.setTexture( NULL );
|
mDebugTarget.setTexture( NULL );
|
||||||
_render( renderPass, diffuseState );
|
_render( renderPass, diffuseState );
|
||||||
mDebugTarget.setTexture( mShadowMapTex );
|
mDebugTarget.setTexture( mShadowMapTex );
|
||||||
|
|
@ -458,23 +480,33 @@ LightingShaderConstants::LightingShaderConstants()
|
||||||
mLightSpotAngleSC(NULL),
|
mLightSpotAngleSC(NULL),
|
||||||
mLightSpotFalloffSC(NULL),
|
mLightSpotFalloffSC(NULL),
|
||||||
mShadowMapSC(NULL),
|
mShadowMapSC(NULL),
|
||||||
|
mDynamicShadowMapSC(NULL),
|
||||||
mShadowMapSizeSC(NULL),
|
mShadowMapSizeSC(NULL),
|
||||||
mCookieMapSC(NULL),
|
mCookieMapSC(NULL),
|
||||||
mRandomDirsConst(NULL),
|
mRandomDirsConst(NULL),
|
||||||
mShadowSoftnessConst(NULL),
|
mShadowSoftnessConst(NULL),
|
||||||
|
mAtlasXOffsetSC(NULL),
|
||||||
|
mAtlasYOffsetSC(NULL),
|
||||||
|
mAtlasScaleSC(NULL),
|
||||||
|
mFadeStartLength(NULL),
|
||||||
|
mOverDarkFactorPSSM(NULL),
|
||||||
|
mTapRotationTexSC(NULL),
|
||||||
|
|
||||||
mWorldToLightProjSC(NULL),
|
mWorldToLightProjSC(NULL),
|
||||||
mViewToLightProjSC(NULL),
|
mViewToLightProjSC(NULL),
|
||||||
mScaleXSC(NULL),
|
mScaleXSC(NULL),
|
||||||
mScaleYSC(NULL),
|
mScaleYSC(NULL),
|
||||||
mOffsetXSC(NULL),
|
mOffsetXSC(NULL),
|
||||||
mOffsetYSC(NULL),
|
mOffsetYSC(NULL),
|
||||||
mAtlasXOffsetSC(NULL),
|
|
||||||
mAtlasYOffsetSC(NULL),
|
|
||||||
mAtlasScaleSC(NULL),
|
|
||||||
mFadeStartLength(NULL),
|
|
||||||
mFarPlaneScalePSSM(NULL),
|
mFarPlaneScalePSSM(NULL),
|
||||||
mOverDarkFactorPSSM(NULL),
|
|
||||||
mTapRotationTexSC(NULL)
|
mDynamicWorldToLightProjSC(NULL),
|
||||||
|
mDynamicViewToLightProjSC(NULL),
|
||||||
|
mDynamicScaleXSC(NULL),
|
||||||
|
mDynamicScaleYSC(NULL),
|
||||||
|
mDynamicOffsetXSC(NULL),
|
||||||
|
mDynamicOffsetYSC(NULL),
|
||||||
|
mDynamicFarPlaneScalePSSM(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -513,29 +545,35 @@ void LightingShaderConstants::init(GFXShader* shader)
|
||||||
mLightSpotFalloffSC = shader->getShaderConstHandle( ShaderGenVars::lightSpotFalloff );
|
mLightSpotFalloffSC = shader->getShaderConstHandle( ShaderGenVars::lightSpotFalloff );
|
||||||
|
|
||||||
mShadowMapSC = shader->getShaderConstHandle("$shadowMap");
|
mShadowMapSC = shader->getShaderConstHandle("$shadowMap");
|
||||||
|
mDynamicShadowMapSC = shader->getShaderConstHandle("$dynamicShadowMap");
|
||||||
mShadowMapSizeSC = shader->getShaderConstHandle("$shadowMapSize");
|
mShadowMapSizeSC = shader->getShaderConstHandle("$shadowMapSize");
|
||||||
|
|
||||||
mCookieMapSC = shader->getShaderConstHandle("$cookieMap");
|
mCookieMapSC = shader->getShaderConstHandle("$cookieMap");
|
||||||
|
|
||||||
mShadowSoftnessConst = shader->getShaderConstHandle("$shadowSoftness");
|
mShadowSoftnessConst = shader->getShaderConstHandle("$shadowSoftness");
|
||||||
|
|
||||||
mWorldToLightProjSC = shader->getShaderConstHandle("$worldToLightProj");
|
|
||||||
mViewToLightProjSC = shader->getShaderConstHandle("$viewToLightProj");
|
|
||||||
|
|
||||||
mScaleXSC = shader->getShaderConstHandle("$scaleX");
|
|
||||||
mScaleYSC = shader->getShaderConstHandle("$scaleY");
|
|
||||||
mOffsetXSC = shader->getShaderConstHandle("$offsetX");
|
|
||||||
mOffsetYSC = shader->getShaderConstHandle("$offsetY");
|
|
||||||
mAtlasXOffsetSC = shader->getShaderConstHandle("$atlasXOffset");
|
mAtlasXOffsetSC = shader->getShaderConstHandle("$atlasXOffset");
|
||||||
mAtlasYOffsetSC = shader->getShaderConstHandle("$atlasYOffset");
|
mAtlasYOffsetSC = shader->getShaderConstHandle("$atlasYOffset");
|
||||||
mAtlasScaleSC = shader->getShaderConstHandle("$atlasScale");
|
mAtlasScaleSC = shader->getShaderConstHandle("$atlasScale");
|
||||||
|
|
||||||
mFadeStartLength = shader->getShaderConstHandle("$fadeStartLength");
|
mFadeStartLength = shader->getShaderConstHandle("$fadeStartLength");
|
||||||
|
mOverDarkFactorPSSM = shader->getShaderConstHandle("$overDarkPSSM");
|
||||||
|
mTapRotationTexSC = shader->getShaderConstHandle( "$gTapRotationTex" );
|
||||||
|
|
||||||
|
mWorldToLightProjSC = shader->getShaderConstHandle("$worldToLightProj");
|
||||||
|
mViewToLightProjSC = shader->getShaderConstHandle("$viewToLightProj");
|
||||||
|
mScaleXSC = shader->getShaderConstHandle("$scaleX");
|
||||||
|
mScaleYSC = shader->getShaderConstHandle("$scaleY");
|
||||||
|
mOffsetXSC = shader->getShaderConstHandle("$offsetX");
|
||||||
|
mOffsetYSC = shader->getShaderConstHandle("$offsetY");
|
||||||
mFarPlaneScalePSSM = shader->getShaderConstHandle("$farPlaneScalePSSM");
|
mFarPlaneScalePSSM = shader->getShaderConstHandle("$farPlaneScalePSSM");
|
||||||
|
|
||||||
mOverDarkFactorPSSM = shader->getShaderConstHandle("$overDarkPSSM");
|
mDynamicWorldToLightProjSC = shader->getShaderConstHandle("$dynamicWorldToLightProj");
|
||||||
|
mDynamicViewToLightProjSC = shader->getShaderConstHandle("$dynamicViewToLightProj");
|
||||||
mTapRotationTexSC = shader->getShaderConstHandle( "$gTapRotationTex" );
|
mDynamicScaleXSC = shader->getShaderConstHandle("$dynamicScaleX");
|
||||||
|
mDynamicScaleYSC = shader->getShaderConstHandle("$dynamicScaleY");
|
||||||
|
mDynamicOffsetXSC = shader->getShaderConstHandle("$dynamicOffsetX");
|
||||||
|
mDynamicOffsetYSC = shader->getShaderConstHandle("$dynamicOffsetY");
|
||||||
|
mDynamicFarPlaneScalePSSM = shader->getShaderConstHandle("$dynamicFarPlaneScalePSSM");
|
||||||
|
|
||||||
mInit = true;
|
mInit = true;
|
||||||
}
|
}
|
||||||
|
|
@ -558,7 +596,9 @@ LightInfoExType ShadowMapParams::Type( "" );
|
||||||
|
|
||||||
ShadowMapParams::ShadowMapParams( LightInfo *light )
|
ShadowMapParams::ShadowMapParams( LightInfo *light )
|
||||||
: mLight( light ),
|
: mLight( light ),
|
||||||
mShadowMap( NULL )
|
mShadowMap( NULL ),
|
||||||
|
mDynamicShadowMap ( NULL ),
|
||||||
|
isDynamic ( true )
|
||||||
{
|
{
|
||||||
attenuationRatio.set( 0.0f, 1.0f, 1.0f );
|
attenuationRatio.set( 0.0f, 1.0f, 1.0f );
|
||||||
shadowType = ShadowType_Spot;
|
shadowType = ShadowType_Spot;
|
||||||
|
|
@ -576,6 +616,7 @@ ShadowMapParams::ShadowMapParams( LightInfo *light )
|
||||||
ShadowMapParams::~ShadowMapParams()
|
ShadowMapParams::~ShadowMapParams()
|
||||||
{
|
{
|
||||||
SAFE_DELETE( mShadowMap );
|
SAFE_DELETE( mShadowMap );
|
||||||
|
SAFE_DELETE( mDynamicShadowMap );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShadowMapParams::_validate()
|
void ShadowMapParams::_validate()
|
||||||
|
|
@ -632,40 +673,56 @@ void ShadowMapParams::_validate()
|
||||||
texSize = mClamp( texSize, 32, maxTexSize );
|
texSize = mClamp( texSize, 32, maxTexSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
LightShadowMap* ShadowMapParams::getOrCreateShadowMap()
|
LightShadowMap* ShadowMapParams::getOrCreateShadowMap(bool _isDynamic)
|
||||||
{
|
{
|
||||||
if ( mShadowMap )
|
if (_isDynamic && mDynamicShadowMap)
|
||||||
|
return mDynamicShadowMap;
|
||||||
|
|
||||||
|
if (!_isDynamic && mShadowMap)
|
||||||
return mShadowMap;
|
return mShadowMap;
|
||||||
|
|
||||||
if ( !mLight->getCastShadows() )
|
if ( !mLight->getCastShadows() )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
LightShadowMap* newShadowMap = NULL;
|
||||||
|
|
||||||
switch ( mLight->getType() )
|
switch ( mLight->getType() )
|
||||||
{
|
{
|
||||||
case LightInfo::Spot:
|
case LightInfo::Spot:
|
||||||
mShadowMap = new SingleLightShadowMap( mLight );
|
newShadowMap = new SingleLightShadowMap( mLight );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LightInfo::Vector:
|
case LightInfo::Vector:
|
||||||
mShadowMap = new PSSMLightShadowMap( mLight );
|
newShadowMap = new PSSMLightShadowMap( mLight );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LightInfo::Point:
|
case LightInfo::Point:
|
||||||
|
|
||||||
if ( shadowType == ShadowType_CubeMap )
|
if ( shadowType == ShadowType_CubeMap )
|
||||||
mShadowMap = new CubeLightShadowMap( mLight );
|
newShadowMap = new CubeLightShadowMap( mLight );
|
||||||
else if ( shadowType == ShadowType_Paraboloid )
|
else if ( shadowType == ShadowType_Paraboloid )
|
||||||
mShadowMap = new ParaboloidLightShadowMap( mLight );
|
newShadowMap = new ParaboloidLightShadowMap( mLight );
|
||||||
else
|
else
|
||||||
mShadowMap = new DualParaboloidLightShadowMap( mLight );
|
newShadowMap = new DualParaboloidLightShadowMap( mLight );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( _isDynamic )
|
||||||
|
{
|
||||||
|
newShadowMap->setDynamic( true );
|
||||||
|
mDynamicShadowMap = newShadowMap;
|
||||||
|
return mDynamicShadowMap;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newShadowMap->setDynamic(false);
|
||||||
|
mShadowMap = newShadowMap;
|
||||||
return mShadowMap;
|
return mShadowMap;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GFXTextureObject* ShadowMapParams::getCookieTex()
|
GFXTextureObject* ShadowMapParams::getCookieTex()
|
||||||
{
|
{
|
||||||
|
|
@ -739,6 +796,7 @@ void ShadowMapParams::unpackUpdate( BitStream *stream )
|
||||||
// map so it can be reallocated on the next render.
|
// map so it can be reallocated on the next render.
|
||||||
shadowType = newType;
|
shadowType = newType;
|
||||||
SAFE_DELETE( mShadowMap );
|
SAFE_DELETE( mShadowMap );
|
||||||
|
SAFE_DELETE( mDynamicShadowMap );
|
||||||
}
|
}
|
||||||
|
|
||||||
mathRead( *stream, &attenuationRatio );
|
mathRead( *stream, &attenuationRatio );
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,9 @@
|
||||||
#ifndef _GFXSHADER_H_
|
#ifndef _GFXSHADER_H_
|
||||||
#include "gfx/gfxShader.h"
|
#include "gfx/gfxShader.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef _PLATFORM_PLATFORMTIMER_H_
|
||||||
|
#include "platform/platformTimer.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class ShadowMapManager;
|
class ShadowMapManager;
|
||||||
class SceneManager;
|
class SceneManager;
|
||||||
|
|
@ -88,20 +91,13 @@ struct LightingShaderConstants
|
||||||
GFXShaderConstHandle *mLightSpotFalloffSC;
|
GFXShaderConstHandle *mLightSpotFalloffSC;
|
||||||
|
|
||||||
GFXShaderConstHandle* mShadowMapSC;
|
GFXShaderConstHandle* mShadowMapSC;
|
||||||
|
GFXShaderConstHandle* mDynamicShadowMapSC;
|
||||||
GFXShaderConstHandle* mShadowMapSizeSC;
|
GFXShaderConstHandle* mShadowMapSizeSC;
|
||||||
|
|
||||||
GFXShaderConstHandle* mCookieMapSC;
|
GFXShaderConstHandle* mCookieMapSC;
|
||||||
|
|
||||||
GFXShaderConstHandle* mRandomDirsConst;
|
GFXShaderConstHandle* mRandomDirsConst;
|
||||||
GFXShaderConstHandle* mShadowSoftnessConst;
|
GFXShaderConstHandle* mShadowSoftnessConst;
|
||||||
|
|
||||||
GFXShaderConstHandle* mWorldToLightProjSC;
|
|
||||||
GFXShaderConstHandle* mViewToLightProjSC;
|
|
||||||
|
|
||||||
GFXShaderConstHandle* mScaleXSC;
|
|
||||||
GFXShaderConstHandle* mScaleYSC;
|
|
||||||
GFXShaderConstHandle* mOffsetXSC;
|
|
||||||
GFXShaderConstHandle* mOffsetYSC;
|
|
||||||
GFXShaderConstHandle* mAtlasXOffsetSC;
|
GFXShaderConstHandle* mAtlasXOffsetSC;
|
||||||
GFXShaderConstHandle* mAtlasYOffsetSC;
|
GFXShaderConstHandle* mAtlasYOffsetSC;
|
||||||
GFXShaderConstHandle* mAtlasScaleSC;
|
GFXShaderConstHandle* mAtlasScaleSC;
|
||||||
|
|
@ -109,11 +105,28 @@ struct LightingShaderConstants
|
||||||
// fadeStartLength.x = Distance in eye space to start fading shadows
|
// fadeStartLength.x = Distance in eye space to start fading shadows
|
||||||
// fadeStartLength.y = 1 / Length of fade
|
// fadeStartLength.y = 1 / Length of fade
|
||||||
GFXShaderConstHandle* mFadeStartLength;
|
GFXShaderConstHandle* mFadeStartLength;
|
||||||
GFXShaderConstHandle* mFarPlaneScalePSSM;
|
|
||||||
GFXShaderConstHandle* mOverDarkFactorPSSM;
|
GFXShaderConstHandle* mOverDarkFactorPSSM;
|
||||||
|
|
||||||
GFXShaderConstHandle* mTapRotationTexSC;
|
GFXShaderConstHandle* mTapRotationTexSC;
|
||||||
|
|
||||||
|
// Static Specific:
|
||||||
|
GFXShaderConstHandle* mWorldToLightProjSC;
|
||||||
|
GFXShaderConstHandle* mViewToLightProjSC;
|
||||||
|
GFXShaderConstHandle* mScaleXSC;
|
||||||
|
GFXShaderConstHandle* mScaleYSC;
|
||||||
|
GFXShaderConstHandle* mOffsetXSC;
|
||||||
|
GFXShaderConstHandle* mOffsetYSC;
|
||||||
|
GFXShaderConstHandle* mFarPlaneScalePSSM;
|
||||||
|
|
||||||
|
// Dynamic Specific:
|
||||||
|
GFXShaderConstHandle* mDynamicWorldToLightProjSC;
|
||||||
|
GFXShaderConstHandle* mDynamicViewToLightProjSC;
|
||||||
|
GFXShaderConstHandle* mDynamicScaleXSC;
|
||||||
|
GFXShaderConstHandle* mDynamicScaleYSC;
|
||||||
|
GFXShaderConstHandle* mDynamicOffsetXSC;
|
||||||
|
GFXShaderConstHandle* mDynamicOffsetYSC;
|
||||||
|
GFXShaderConstHandle* mDynamicFarPlaneScalePSSM;
|
||||||
|
|
||||||
LightingShaderConstants();
|
LightingShaderConstants();
|
||||||
~LightingShaderConstants();
|
~LightingShaderConstants();
|
||||||
|
|
||||||
|
|
@ -147,7 +160,8 @@ public:
|
||||||
virtual ~LightShadowMap();
|
virtual ~LightShadowMap();
|
||||||
|
|
||||||
void render( RenderPassManager* renderPass,
|
void render( RenderPassManager* renderPass,
|
||||||
const SceneRenderState *diffuseState );
|
const SceneRenderState *diffuseState,
|
||||||
|
bool _dynamic);
|
||||||
|
|
||||||
U32 getLastUpdate() const { return mLastUpdate; }
|
U32 getLastUpdate() const { return mLastUpdate; }
|
||||||
|
|
||||||
|
|
@ -237,6 +251,8 @@ protected:
|
||||||
|
|
||||||
/// The time this shadow was last updated.
|
/// The time this shadow was last updated.
|
||||||
U32 mLastUpdate;
|
U32 mLastUpdate;
|
||||||
|
PlatformTimer *mStaticRefreshTimer;
|
||||||
|
PlatformTimer *mDynamicRefreshTimer;
|
||||||
|
|
||||||
/// The time this shadow was last culled and prioritized.
|
/// The time this shadow was last culled and prioritized.
|
||||||
U32 mLastCull;
|
U32 mLastCull;
|
||||||
|
|
@ -274,6 +290,13 @@ protected:
|
||||||
/// The callback used to get texture events.
|
/// The callback used to get texture events.
|
||||||
/// @see GFXTextureManager::addEventDelegate
|
/// @see GFXTextureManager::addEventDelegate
|
||||||
void _onTextureEvent( GFXTexCallbackCode code );
|
void _onTextureEvent( GFXTexCallbackCode code );
|
||||||
|
|
||||||
|
bool mIsDynamic;
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool isDynamic() { return mIsDynamic; }
|
||||||
|
void setDynamic(bool value) { mIsDynamic = value; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GFX_DeclareTextureProfile( ShadowMapProfile );
|
GFX_DeclareTextureProfile( ShadowMapProfile );
|
||||||
|
|
@ -296,9 +319,9 @@ public:
|
||||||
virtual void packUpdate( BitStream *stream ) const;
|
virtual void packUpdate( BitStream *stream ) const;
|
||||||
virtual void unpackUpdate( BitStream *stream );
|
virtual void unpackUpdate( BitStream *stream );
|
||||||
|
|
||||||
LightShadowMap* getShadowMap() const { return mShadowMap; }
|
LightShadowMap* getShadowMap(bool _isDynamic = false) const { return _isDynamic ? mDynamicShadowMap : mShadowMap; }
|
||||||
|
|
||||||
LightShadowMap* getOrCreateShadowMap();
|
LightShadowMap* getOrCreateShadowMap(bool _isDynamic = false);
|
||||||
|
|
||||||
bool hasCookieTex() const { return cookie.isNotEmpty(); }
|
bool hasCookieTex() const { return cookie.isNotEmpty(); }
|
||||||
|
|
||||||
|
|
@ -315,6 +338,7 @@ protected:
|
||||||
|
|
||||||
///
|
///
|
||||||
LightShadowMap *mShadowMap;
|
LightShadowMap *mShadowMap;
|
||||||
|
LightShadowMap *mDynamicShadowMap;
|
||||||
|
|
||||||
LightInfo *mLight;
|
LightInfo *mLight;
|
||||||
|
|
||||||
|
|
@ -376,6 +400,7 @@ public:
|
||||||
bool lastSplitTerrainOnly;
|
bool lastSplitTerrainOnly;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
bool isDynamic;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _LIGHTSHADOWMAP_H_
|
#endif // _LIGHTSHADOWMAP_H_
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
#include "materials/shaderData.h"
|
#include "materials/shaderData.h"
|
||||||
#include "ts/tsShapeInstance.h"
|
#include "ts/tsShapeInstance.h"
|
||||||
#include "console/consoleTypes.h"
|
#include "console/consoleTypes.h"
|
||||||
|
#include "math/mathUtils.h"
|
||||||
|
|
||||||
|
|
||||||
AFTER_MODULE_INIT( Sim )
|
AFTER_MODULE_INIT( Sim )
|
||||||
|
|
@ -248,6 +249,9 @@ void PSSMLightShadowMap::_render( RenderPassManager* renderPass,
|
||||||
TSShapeInstance::smDetailAdjust *= smDetailAdjustScale;
|
TSShapeInstance::smDetailAdjust *= smDetailAdjustScale;
|
||||||
TSShapeInstance::smSmallestVisiblePixelSize = smSmallestVisiblePixelSize;
|
TSShapeInstance::smSmallestVisiblePixelSize = smSmallestVisiblePixelSize;
|
||||||
|
|
||||||
|
Vector< Vector<PlaneF> > _extraCull;
|
||||||
|
_calcPlanesCullForShadowCasters( _extraCull, fullFrustum, mLight->getDirection() );
|
||||||
|
|
||||||
for (U32 i = 0; i < mNumSplits; i++)
|
for (U32 i = 0; i < mNumSplits; i++)
|
||||||
{
|
{
|
||||||
GFXTransformSaver saver;
|
GFXTransformSaver saver;
|
||||||
|
|
@ -365,12 +369,17 @@ void PSSMLightShadowMap::_render( RenderPassManager* renderPass,
|
||||||
shadowRenderState.setDiffuseCameraTransform( diffuseState->getCameraTransform() );
|
shadowRenderState.setDiffuseCameraTransform( diffuseState->getCameraTransform() );
|
||||||
shadowRenderState.setWorldToScreenScale( diffuseState->getWorldToScreenScale() );
|
shadowRenderState.setWorldToScreenScale( diffuseState->getWorldToScreenScale() );
|
||||||
|
|
||||||
|
PlaneSetF planeSet( _extraCull[i].address(), _extraCull[i].size() );
|
||||||
|
shadowRenderState.getCullingState().setExtraPlanesCull( planeSet );
|
||||||
|
|
||||||
U32 objectMask = SHADOW_TYPEMASK;
|
U32 objectMask = SHADOW_TYPEMASK;
|
||||||
if ( i == mNumSplits-1 && params->lastSplitTerrainOnly )
|
if ( i == mNumSplits-1 && params->lastSplitTerrainOnly )
|
||||||
objectMask = TerrainObjectType;
|
objectMask = TerrainObjectType;
|
||||||
|
|
||||||
sceneManager->renderSceneNoLights( &shadowRenderState, objectMask );
|
sceneManager->renderSceneNoLights( &shadowRenderState, objectMask );
|
||||||
|
|
||||||
|
shadowRenderState.getCullingState().clearExtraPlanesCull();
|
||||||
|
|
||||||
_debugRender( &shadowRenderState );
|
_debugRender( &shadowRenderState );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -435,10 +444,22 @@ void PSSMLightShadowMap::setShaderParameters(GFXShaderConstBuffer* params, Light
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These values change based on static/dynamic.
|
||||||
|
if ( mIsDynamic )
|
||||||
|
{
|
||||||
|
params->setSafe(lsc->mDynamicScaleXSC, sx);
|
||||||
|
params->setSafe(lsc->mDynamicScaleYSC, sy);
|
||||||
|
params->setSafe(lsc->mDynamicOffsetXSC, ox);
|
||||||
|
params->setSafe(lsc->mDynamicOffsetYSC, oy);
|
||||||
|
params->setSafe( lsc->mDynamicFarPlaneScalePSSM, mFarPlaneScalePSSM);
|
||||||
|
} else {
|
||||||
params->setSafe(lsc->mScaleXSC, sx);
|
params->setSafe(lsc->mScaleXSC, sx);
|
||||||
params->setSafe(lsc->mScaleYSC, sy);
|
params->setSafe(lsc->mScaleYSC, sy);
|
||||||
params->setSafe(lsc->mOffsetXSC, ox);
|
params->setSafe(lsc->mOffsetXSC, ox);
|
||||||
params->setSafe(lsc->mOffsetYSC, oy);
|
params->setSafe(lsc->mOffsetYSC, oy);
|
||||||
|
params->setSafe( lsc->mFarPlaneScalePSSM, mFarPlaneScalePSSM);
|
||||||
|
}
|
||||||
|
|
||||||
params->setSafe(lsc->mAtlasXOffsetSC, aXOff);
|
params->setSafe(lsc->mAtlasXOffsetSC, aXOff);
|
||||||
params->setSafe(lsc->mAtlasYOffsetSC, aYOff);
|
params->setSafe(lsc->mAtlasYOffsetSC, aYOff);
|
||||||
params->setSafe(lsc->mAtlasScaleSC, shadowMapAtlas);
|
params->setSafe(lsc->mAtlasScaleSC, shadowMapAtlas);
|
||||||
|
|
@ -446,8 +467,6 @@ void PSSMLightShadowMap::setShaderParameters(GFXShaderConstBuffer* params, Light
|
||||||
Point4F lightParams( mLight->getRange().x, p->overDarkFactor.x, 0.0f, 0.0f );
|
Point4F lightParams( mLight->getRange().x, p->overDarkFactor.x, 0.0f, 0.0f );
|
||||||
params->setSafe( lsc->mLightParamsSC, lightParams );
|
params->setSafe( lsc->mLightParamsSC, lightParams );
|
||||||
|
|
||||||
params->setSafe( lsc->mFarPlaneScalePSSM, mFarPlaneScalePSSM);
|
|
||||||
|
|
||||||
Point2F fadeStartLength(p->fadeStartDist, 0.0f);
|
Point2F fadeStartLength(p->fadeStartDist, 0.0f);
|
||||||
if (fadeStartLength.x == 0.0f)
|
if (fadeStartLength.x == 0.0f)
|
||||||
{
|
{
|
||||||
|
|
@ -462,3 +481,117 @@ void PSSMLightShadowMap::setShaderParameters(GFXShaderConstBuffer* params, Light
|
||||||
// The softness is a factor of the texel size.
|
// The softness is a factor of the texel size.
|
||||||
params->setSafe( lsc->mShadowSoftnessConst, p->shadowSoftness * ( 1.0f / mTexSize ) );
|
params->setSafe( lsc->mShadowSoftnessConst, p->shadowSoftness * ( 1.0f / mTexSize ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PSSMLightShadowMap::_calcPlanesCullForShadowCasters(Vector< Vector<PlaneF> > &out, const Frustum &viewFrustum, const Point3F &_ligthDir)
|
||||||
|
{
|
||||||
|
|
||||||
|
#define ENABLE_CULL_ASSERT
|
||||||
|
|
||||||
|
PROFILE_SCOPE(PSSMLightShadowMap_render_getCullFrustrum);
|
||||||
|
|
||||||
|
Point3F ligthDir = _ligthDir;
|
||||||
|
PlaneF lightFarPlane, lightNearPlane;
|
||||||
|
MatrixF lightFarPlaneMat(true);
|
||||||
|
MatrixF invLightFarPlaneMat(true);
|
||||||
|
|
||||||
|
// init data
|
||||||
|
{
|
||||||
|
ligthDir.normalize();
|
||||||
|
Point3F viewDir = viewFrustum.getTransform().getForwardVector();
|
||||||
|
viewDir.normalize();
|
||||||
|
const Point3F viewPosition = viewFrustum.getPosition();
|
||||||
|
const F32 viewDistance = viewFrustum.getBounds().len();
|
||||||
|
lightNearPlane = PlaneF(viewPosition + (viewDistance * -ligthDir), ligthDir);
|
||||||
|
|
||||||
|
const Point3F lightFarPlanePos = viewPosition + (viewDistance * ligthDir);
|
||||||
|
lightFarPlane = PlaneF(lightFarPlanePos, -ligthDir);
|
||||||
|
|
||||||
|
lightFarPlaneMat = MathUtils::createOrientFromDir(-ligthDir);
|
||||||
|
lightFarPlaneMat.setPosition(lightFarPlanePos);
|
||||||
|
lightFarPlaneMat.invertTo(&invLightFarPlaneMat);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<Point2F> projVertices;
|
||||||
|
|
||||||
|
//project all frustum vertices into plane
|
||||||
|
// all vertices are 2d and local to far plane
|
||||||
|
projVertices.setSize(8);
|
||||||
|
for (int i = 0; i < 8; ++i) //
|
||||||
|
{
|
||||||
|
const Point3F &point = viewFrustum.getPoints()[i];
|
||||||
|
#ifdef ENABLE_CULL_ASSERT
|
||||||
|
AssertFatal( PlaneF::Front == lightNearPlane.whichSide(point), "" );
|
||||||
|
AssertFatal( PlaneF::Front == lightFarPlane.whichSide(point), "" );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Point3F localPoint(lightFarPlane.project(point));
|
||||||
|
invLightFarPlaneMat.mulP(localPoint);
|
||||||
|
projVertices[i] = Point2F(localPoint.x, localPoint.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
//create hull arround projected proints
|
||||||
|
Vector<Point2F> hullVerts;
|
||||||
|
MathUtils::mBuildHull2D(projVertices, hullVerts);
|
||||||
|
|
||||||
|
Vector<PlaneF> planes;
|
||||||
|
planes.push_back(lightNearPlane);
|
||||||
|
planes.push_back(lightFarPlane);
|
||||||
|
|
||||||
|
//build planes
|
||||||
|
for (int i = 0; i < (hullVerts.size() - 1); ++i)
|
||||||
|
{
|
||||||
|
Point2F pos2D = (hullVerts[i] + hullVerts[i + 1]) / 2;
|
||||||
|
Point3F pos3D(pos2D.x, 0, pos2D.y);
|
||||||
|
|
||||||
|
Point3F pos3DA(hullVerts[i].x, 0, hullVerts[i].y);
|
||||||
|
Point3F pos3DB(hullVerts[i + 1].x, 0, hullVerts[i + 1].y);
|
||||||
|
|
||||||
|
// move hull points to 3d space
|
||||||
|
lightFarPlaneMat.mulP(pos3D);
|
||||||
|
lightFarPlaneMat.mulP(pos3DA);
|
||||||
|
lightFarPlaneMat.mulP(pos3DB);
|
||||||
|
|
||||||
|
PlaneF plane(pos3D, MathUtils::mTriangleNormal(pos3DB, pos3DA, (pos3DA - ligthDir)));
|
||||||
|
planes.push_back(plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
//recalculate planes for each splits
|
||||||
|
for (int split = 0; split < mNumSplits; ++split)
|
||||||
|
{
|
||||||
|
Frustum subFrustum(viewFrustum);
|
||||||
|
subFrustum.cropNearFar(mSplitDist[split], mSplitDist[split + 1]);
|
||||||
|
subFrustum.setFarDist(getMin(subFrustum.getFarDist()*2.5f, viewFrustum.getFarDist()));
|
||||||
|
subFrustum.update();
|
||||||
|
|
||||||
|
Vector<PlaneF> subPlanes = planes;
|
||||||
|
|
||||||
|
for (int planeIdx = 0; planeIdx < subPlanes.size(); ++planeIdx)
|
||||||
|
{
|
||||||
|
PlaneF &plane = subPlanes[planeIdx];
|
||||||
|
F32 minDist = 0;
|
||||||
|
|
||||||
|
//calculate near vertex distance
|
||||||
|
for (int vertexIdx = 0; vertexIdx < 8; ++vertexIdx)
|
||||||
|
{
|
||||||
|
Point3F point = subFrustum.getPoints()[vertexIdx];
|
||||||
|
minDist = getMin(plane.distToPlane(point), minDist);
|
||||||
|
}
|
||||||
|
|
||||||
|
// move plane to near vertex
|
||||||
|
Point3F newPos = plane.getPosition() + (plane.getNormal() * minDist);
|
||||||
|
plane = PlaneF(newPos, plane.getNormal());
|
||||||
|
|
||||||
|
#ifdef ENABLE_CULL_ASSERT
|
||||||
|
for(int x = 0; x < 8; ++x)
|
||||||
|
{
|
||||||
|
AssertFatal( PlaneF::Back != plane.whichSide( subFrustum.getPoints()[x] ), "");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
out.push_back(subPlanes);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef ENABLE_CULL_ASSERT
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ protected:
|
||||||
void _setNumSplits( U32 numSplits, U32 texSize );
|
void _setNumSplits( U32 numSplits, U32 texSize );
|
||||||
void _calcSplitPos(const Frustum& currFrustum);
|
void _calcSplitPos(const Frustum& currFrustum);
|
||||||
Box3F _calcClipSpaceAABB(const Frustum& f, const MatrixF& transform, F32 farDist);
|
Box3F _calcClipSpaceAABB(const Frustum& f, const MatrixF& transform, F32 farDist);
|
||||||
|
void _calcPlanesCullForShadowCasters(Vector< Vector<PlaneF> > &out, const Frustum &viewFrustum, const Point3F &_ligthDir);
|
||||||
void _roundProjection(const MatrixF& lightMat, const MatrixF& cropMatrix, Point3F &offset, U32 splitNum);
|
void _roundProjection(const MatrixF& lightMat, const MatrixF& cropMatrix, Point3F &offset, U32 splitNum);
|
||||||
|
|
||||||
static const S32 MAX_SPLITS = 4;
|
static const S32 MAX_SPLITS = 4;
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,7 @@ Signal<void(void)> ShadowMapManager::smShadowDeactivateSignal;
|
||||||
ShadowMapManager::ShadowMapManager()
|
ShadowMapManager::ShadowMapManager()
|
||||||
: mShadowMapPass(NULL),
|
: mShadowMapPass(NULL),
|
||||||
mCurrentShadowMap(NULL),
|
mCurrentShadowMap(NULL),
|
||||||
|
mCurrentDynamicShadowMap(NULL),
|
||||||
mIsActive(false)
|
mIsActive(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -98,9 +99,15 @@ void ShadowMapManager::setLightShadowMapForLight( LightInfo *light )
|
||||||
{
|
{
|
||||||
ShadowMapParams *params = light->getExtended<ShadowMapParams>();
|
ShadowMapParams *params = light->getExtended<ShadowMapParams>();
|
||||||
if ( params )
|
if ( params )
|
||||||
|
{
|
||||||
mCurrentShadowMap = params->getShadowMap();
|
mCurrentShadowMap = params->getShadowMap();
|
||||||
|
mCurrentDynamicShadowMap = params->getShadowMap(true);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
mCurrentShadowMap = NULL;
|
mCurrentShadowMap = NULL;
|
||||||
|
mCurrentDynamicShadowMap = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShadowMapManager::activate()
|
void ShadowMapManager::activate()
|
||||||
|
|
|
||||||
|
|
@ -60,12 +60,14 @@ public:
|
||||||
|
|
||||||
/// Sets the current shadowmap (used in setLightInfo/setTextureStage calls)
|
/// Sets the current shadowmap (used in setLightInfo/setTextureStage calls)
|
||||||
void setLightShadowMap( LightShadowMap *lm ) { mCurrentShadowMap = lm; }
|
void setLightShadowMap( LightShadowMap *lm ) { mCurrentShadowMap = lm; }
|
||||||
|
void setLightDynamicShadowMap( LightShadowMap *lm ) { mCurrentDynamicShadowMap = lm; }
|
||||||
|
|
||||||
/// Looks up the shadow map for the light then sets it.
|
/// Looks up the shadow map for the light then sets it.
|
||||||
void setLightShadowMapForLight( LightInfo *light );
|
void setLightShadowMapForLight( LightInfo *light );
|
||||||
|
|
||||||
/// Return the current shadow map
|
/// Return the current shadow map
|
||||||
LightShadowMap* getCurrentShadowMap() const { return mCurrentShadowMap; }
|
LightShadowMap* getCurrentShadowMap() const { return mCurrentShadowMap; }
|
||||||
|
LightShadowMap* getCurrentDynamicShadowMap() const { return mCurrentDynamicShadowMap; }
|
||||||
|
|
||||||
ShadowMapPass* getShadowMapPass() const { return mShadowMapPass; }
|
ShadowMapPass* getShadowMapPass() const { return mShadowMapPass; }
|
||||||
|
|
||||||
|
|
@ -88,6 +90,7 @@ protected:
|
||||||
|
|
||||||
ShadowMapPass *mShadowMapPass;
|
ShadowMapPass *mShadowMapPass;
|
||||||
LightShadowMap *mCurrentShadowMap;
|
LightShadowMap *mCurrentShadowMap;
|
||||||
|
LightShadowMap *mCurrentDynamicShadowMap;
|
||||||
|
|
||||||
///
|
///
|
||||||
GFXTexHandle mTapRotationTex;
|
GFXTexHandle mTapRotationTex;
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,11 @@ bool ShadowMapPass::smDisableShadows = false;
|
||||||
bool ShadowMapPass::smDisableShadowsEditor = false;
|
bool ShadowMapPass::smDisableShadowsEditor = false;
|
||||||
bool ShadowMapPass::smDisableShadowsPref = false;
|
bool ShadowMapPass::smDisableShadowsPref = false;
|
||||||
|
|
||||||
|
/// milliseconds before static redraw
|
||||||
|
S32 ShadowMapPass::smStaticShadowUpdateFreq = 32;
|
||||||
|
/// milliseconds before dynamic redraw
|
||||||
|
S32 ShadowMapPass::smDynamicShadowUpdateFreq = 16;
|
||||||
|
|
||||||
/// We have a default 8ms render budget for shadow rendering.
|
/// We have a default 8ms render budget for shadow rendering.
|
||||||
U32 ShadowMapPass::smRenderBudgetMs = 8;
|
U32 ShadowMapPass::smRenderBudgetMs = 8;
|
||||||
|
|
||||||
|
|
@ -62,18 +67,27 @@ ShadowMapPass::ShadowMapPass(LightManager* lightManager, ShadowMapManager* shado
|
||||||
{
|
{
|
||||||
mLightManager = lightManager;
|
mLightManager = lightManager;
|
||||||
mShadowManager = shadowManager;
|
mShadowManager = shadowManager;
|
||||||
|
|
||||||
|
// Setup our render pass managers
|
||||||
|
|
||||||
|
// Static
|
||||||
mShadowRPM = new ShadowRenderPassManager();
|
mShadowRPM = new ShadowRenderPassManager();
|
||||||
mShadowRPM->assignName( "ShadowRenderPassManager" );
|
mShadowRPM->assignName( "ShadowRenderPassManager" );
|
||||||
mShadowRPM->registerObject();
|
mShadowRPM->registerObject();
|
||||||
Sim::getRootGroup()->addObject( mShadowRPM );
|
Sim::getRootGroup()->addObject( mShadowRPM );
|
||||||
|
|
||||||
// Setup our render pass manager
|
|
||||||
|
|
||||||
mShadowRPM->addManager( new RenderMeshMgr(RenderPassManager::RIT_Mesh, 0.3f, 0.3f) );
|
mShadowRPM->addManager( new RenderMeshMgr(RenderPassManager::RIT_Mesh, 0.3f, 0.3f) );
|
||||||
//mShadowRPM->addManager( new RenderObjectMgr() );
|
|
||||||
mShadowRPM->addManager( new RenderTerrainMgr( 0.5f, 0.5f ) );
|
mShadowRPM->addManager( new RenderTerrainMgr( 0.5f, 0.5f ) );
|
||||||
mShadowRPM->addManager( new RenderImposterMgr( 0.6f, 0.6f ) );
|
mShadowRPM->addManager( new RenderImposterMgr( 0.6f, 0.6f ) );
|
||||||
|
|
||||||
|
// Dynamic
|
||||||
|
mDynamicShadowRPM = new DynamicShadowRenderPassManager();
|
||||||
|
mDynamicShadowRPM->assignName( "DynamicShadowRenderPassManager" );
|
||||||
|
mDynamicShadowRPM->registerObject();
|
||||||
|
Sim::getRootGroup()->addObject( mDynamicShadowRPM );
|
||||||
|
mDynamicShadowRPM->addManager( new RenderMeshMgr(RenderPassManager::RIT_Mesh, 0.3f, 0.3f) );
|
||||||
|
mDynamicShadowRPM->addManager( new RenderTerrainMgr( 0.5f, 0.5f ) );
|
||||||
|
mDynamicShadowRPM->addManager( new RenderImposterMgr( 0.6f, 0.6f ) );
|
||||||
|
|
||||||
mActiveLights = 0;
|
mActiveLights = 0;
|
||||||
|
|
||||||
mTimer = PlatformTimer::create();
|
mTimer = PlatformTimer::create();
|
||||||
|
|
@ -117,6 +131,9 @@ ShadowMapPass::~ShadowMapPass()
|
||||||
|
|
||||||
if ( mShadowRPM )
|
if ( mShadowRPM )
|
||||||
mShadowRPM->deleteObject();
|
mShadowRPM->deleteObject();
|
||||||
|
|
||||||
|
if ( mDynamicShadowRPM )
|
||||||
|
mDynamicShadowRPM->deleteObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShadowMapPass::render( SceneManager *sceneManager,
|
void ShadowMapPass::render( SceneManager *sceneManager,
|
||||||
|
|
@ -147,7 +164,7 @@ void ShadowMapPass::render( SceneManager *sceneManager,
|
||||||
// First do a loop thru the lights setting up the shadow
|
// First do a loop thru the lights setting up the shadow
|
||||||
// info array for this pass.
|
// info array for this pass.
|
||||||
Vector<LightShadowMap*> shadowMaps;
|
Vector<LightShadowMap*> shadowMaps;
|
||||||
shadowMaps.reserve( mActiveLights );
|
shadowMaps.reserve( mActiveLights * 2 );
|
||||||
for ( U32 i = 0; i < mActiveLights; i++ )
|
for ( U32 i = 0; i < mActiveLights; i++ )
|
||||||
{
|
{
|
||||||
ShadowMapParams *params = mLights[i]->getExtended<ShadowMapParams>();
|
ShadowMapParams *params = mLights[i]->getExtended<ShadowMapParams>();
|
||||||
|
|
@ -156,11 +173,13 @@ void ShadowMapPass::render( SceneManager *sceneManager,
|
||||||
if ( !mLights[i]->getCastShadows() || smDisableShadows )
|
if ( !mLights[i]->getCastShadows() || smDisableShadows )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// --- Static Shadow Map ---
|
||||||
LightShadowMap *lsm = params->getOrCreateShadowMap();
|
LightShadowMap *lsm = params->getOrCreateShadowMap();
|
||||||
|
LightShadowMap *dlsm = params->getOrCreateShadowMap(true);
|
||||||
|
|
||||||
// First check the visiblity query... if it wasn't
|
// First check the visiblity query... if it wasn't
|
||||||
// visible skip it.
|
// visible skip it.
|
||||||
if ( lsm->wasOccluded() )
|
if (lsm->wasOccluded() || dlsm->wasOccluded())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Any shadow that is visible is counted as being
|
// Any shadow that is visible is counted as being
|
||||||
|
|
@ -171,10 +190,22 @@ void ShadowMapPass::render( SceneManager *sceneManager,
|
||||||
lsm->updatePriority(diffuseState, currTime);
|
lsm->updatePriority(diffuseState, currTime);
|
||||||
|
|
||||||
shadowMaps.push_back(lsm);
|
shadowMaps.push_back(lsm);
|
||||||
|
|
||||||
|
// --- Dynamic Shadow Map ---
|
||||||
|
|
||||||
|
// Any shadow that is visible is counted as being
|
||||||
|
// active regardless if we update it or not.
|
||||||
|
++smActiveShadowMaps;
|
||||||
|
|
||||||
|
// Do a priority update for this shadow.
|
||||||
|
dlsm->updatePriority(diffuseState, currTime);
|
||||||
|
|
||||||
|
shadowMaps.push_back( dlsm );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now sort the shadow info by priority.
|
// Now sort the shadow info by priority.
|
||||||
shadowMaps.sort( LightShadowMap::cmpPriority );
|
// andrewmac: tempoarily disabled until I find a better solution.
|
||||||
|
//shadowMaps.sort( LightShadowMap::cmpPriority );
|
||||||
|
|
||||||
GFXDEBUGEVENT_SCOPE( ShadowMapPass_Render, ColorI::RED );
|
GFXDEBUGEVENT_SCOPE( ShadowMapPass_Render, ColorI::RED );
|
||||||
|
|
||||||
|
|
@ -183,22 +214,28 @@ void ShadowMapPass::render( SceneManager *sceneManager,
|
||||||
mTimer->getElapsedMs();
|
mTimer->getElapsedMs();
|
||||||
mTimer->reset();
|
mTimer->reset();
|
||||||
|
|
||||||
for ( U32 i = 0; i < shadowMaps.size(); i++ )
|
// 2 Shadow Maps per Light. This may fail.
|
||||||
|
for ( U32 i = 0; i < shadowMaps.size(); i += 2 )
|
||||||
{
|
{
|
||||||
LightShadowMap *lsm = shadowMaps[i];
|
LightShadowMap *lsm = shadowMaps[i];
|
||||||
|
LightShadowMap *dlsm = shadowMaps[i + 1];
|
||||||
|
|
||||||
{
|
{
|
||||||
GFXDEBUGEVENT_SCOPE( ShadowMapPass_Render_Shadow, ColorI::RED );
|
GFXDEBUGEVENT_SCOPE( ShadowMapPass_Render_Shadow, ColorI::RED );
|
||||||
|
|
||||||
mShadowManager->setLightShadowMap(lsm);
|
mShadowManager->setLightShadowMap(lsm);
|
||||||
lsm->render( mShadowRPM, diffuseState );
|
mShadowManager->setLightDynamicShadowMap( dlsm );
|
||||||
|
|
||||||
|
lsm->render(mShadowRPM, diffuseState, false);
|
||||||
|
dlsm->render(mDynamicShadowRPM, diffuseState, true);
|
||||||
|
|
||||||
++smUpdatedShadowMaps;
|
++smUpdatedShadowMaps;
|
||||||
}
|
}
|
||||||
|
|
||||||
// View dependent shadows or ones that are covering the entire
|
// View dependent shadows or ones that are covering the entire
|
||||||
// screen are updated every frame no matter the time left in
|
// screen are updated every frame no matter the time left in
|
||||||
// our shadow rendering budget.
|
// our shadow rendering budget.
|
||||||
if ( lsm->isViewDependent() || lsm->getLastScreenSize() >= 1.0f )
|
if ( dlsm->isViewDependent() || dlsm->getLastScreenSize() >= 1.0f )
|
||||||
{
|
{
|
||||||
++smNearShadowMaps;
|
++smNearShadowMaps;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -224,6 +261,7 @@ void ShadowMapPass::render( SceneManager *sceneManager,
|
||||||
// The NULL here is importaint as having it around
|
// The NULL here is importaint as having it around
|
||||||
// will cause extra work in AdvancedLightManager::setLightInfo().
|
// will cause extra work in AdvancedLightManager::setLightInfo().
|
||||||
mShadowManager->setLightShadowMap( NULL );
|
mShadowManager->setLightShadowMap( NULL );
|
||||||
|
mShadowManager->setLightDynamicShadowMap( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShadowRenderPassManager::addInst( RenderInst *inst )
|
void ShadowRenderPassManager::addInst( RenderInst *inst )
|
||||||
|
|
@ -237,7 +275,29 @@ void ShadowRenderPassManager::addInst( RenderInst *inst )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const BaseMaterialDefinition *mat = meshRI->matInst->getMaterial();
|
const BaseMaterialDefinition *mat = meshRI->matInst->getMaterial();
|
||||||
if ( !mat->castsShadows() || mat->isTranslucent() )
|
if ( !mat->castsShadows() || mat->castsDynamicShadows() || mat->isTranslucent() )
|
||||||
|
{
|
||||||
|
// Do not add this instance, return here and avoid the default behavior
|
||||||
|
// of calling up to Parent::addInst()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Parent::addInst(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynamicShadowRenderPassManager::addInst( RenderInst *inst )
|
||||||
|
{
|
||||||
|
PROFILE_SCOPE(DynamicShadowRenderPassManager_addInst);
|
||||||
|
|
||||||
|
if ( inst->type == RIT_Mesh )
|
||||||
|
{
|
||||||
|
MeshRenderInst *meshRI = static_cast<MeshRenderInst*>( inst );
|
||||||
|
if ( !meshRI->matInst )
|
||||||
|
return;
|
||||||
|
|
||||||
|
const BaseMaterialDefinition *mat = meshRI->matInst->getMaterial();
|
||||||
|
if ( !mat->castsShadows() || !mat->castsDynamicShadows() || mat->isTranslucent() )
|
||||||
{
|
{
|
||||||
// Do not add this instance, return here and avoid the default behavior
|
// Do not add this instance, return here and avoid the default behavior
|
||||||
// of calling up to Parent::addInst()
|
// of calling up to Parent::addInst()
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ class RenderObjectMgr;
|
||||||
class RenderTerrainMgr;
|
class RenderTerrainMgr;
|
||||||
class PlatformTimer;
|
class PlatformTimer;
|
||||||
class ShadowRenderPassManager;
|
class ShadowRenderPassManager;
|
||||||
|
class DynamicShadowRenderPassManager;
|
||||||
|
|
||||||
/// ShadowMapPass, this is plugged into the SceneManager to generate
|
/// ShadowMapPass, this is plugged into the SceneManager to generate
|
||||||
/// ShadowMaps for the scene.
|
/// ShadowMaps for the scene.
|
||||||
|
|
@ -83,6 +84,11 @@ public:
|
||||||
static bool smDisableShadowsEditor;
|
static bool smDisableShadowsEditor;
|
||||||
static bool smDisableShadowsPref;
|
static bool smDisableShadowsPref;
|
||||||
|
|
||||||
|
/// milliseconds before static redraw
|
||||||
|
static S32 smStaticShadowUpdateFreq;
|
||||||
|
/// milliseconds before dynamic redraw
|
||||||
|
static S32 smDynamicShadowUpdateFreq;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static U32 smActiveShadowMaps;
|
static U32 smActiveShadowMaps;
|
||||||
|
|
@ -103,6 +109,7 @@ private:
|
||||||
LightInfoList mLights;
|
LightInfoList mLights;
|
||||||
U32 mActiveLights;
|
U32 mActiveLights;
|
||||||
SimObjectPtr<ShadowRenderPassManager> mShadowRPM;
|
SimObjectPtr<ShadowRenderPassManager> mShadowRPM;
|
||||||
|
SimObjectPtr<DynamicShadowRenderPassManager> mDynamicShadowRPM;
|
||||||
LightManager* mLightManager;
|
LightManager* mLightManager;
|
||||||
ShadowMapManager* mShadowManager;
|
ShadowMapManager* mShadowManager;
|
||||||
};
|
};
|
||||||
|
|
@ -117,4 +124,14 @@ public:
|
||||||
virtual void addInst( RenderInst *inst );
|
virtual void addInst( RenderInst *inst );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DynamicShadowRenderPassManager : public RenderPassManager
|
||||||
|
{
|
||||||
|
typedef RenderPassManager Parent;
|
||||||
|
public:
|
||||||
|
DynamicShadowRenderPassManager() : Parent() {}
|
||||||
|
|
||||||
|
/// Add a RenderInstance to the list
|
||||||
|
virtual void addInst(RenderInst *inst);
|
||||||
|
};
|
||||||
|
|
||||||
#endif // _SHADOWMAPPASS_H_
|
#endif // _SHADOWMAPPASS_H_
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ public:
|
||||||
virtual bool isDoubleSided() const = 0;
|
virtual bool isDoubleSided() const = 0;
|
||||||
virtual bool isLightmapped() const = 0;
|
virtual bool isLightmapped() const = 0;
|
||||||
virtual bool castsShadows() const = 0;
|
virtual bool castsShadows() const = 0;
|
||||||
|
virtual bool castsDynamicShadows() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _BASEMATERIALDEFINITION_H_
|
#endif // _BASEMATERIALDEFINITION_H_
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,7 @@ Material::Material()
|
||||||
mAlphaRef = 1;
|
mAlphaRef = 1;
|
||||||
|
|
||||||
mCastShadows = true;
|
mCastShadows = true;
|
||||||
|
mCastDynamicShadows = false;
|
||||||
|
|
||||||
mPlanarReflection = false;
|
mPlanarReflection = false;
|
||||||
|
|
||||||
|
|
@ -390,6 +391,9 @@ void Material::initPersistFields()
|
||||||
addField( "castShadows", TypeBool, Offset(mCastShadows, Material),
|
addField( "castShadows", TypeBool, Offset(mCastShadows, Material),
|
||||||
"If set to false the lighting system will not cast shadows from this material." );
|
"If set to false the lighting system will not cast shadows from this material." );
|
||||||
|
|
||||||
|
addField( "castDynamicShadows", TypeBool, Offset(mCastDynamicShadows, Material),
|
||||||
|
"If set to false the lighting system will not cast dynamic shadows from this material." );
|
||||||
|
|
||||||
addField("planarReflection", TypeBool, Offset(mPlanarReflection, Material), "@internal" );
|
addField("planarReflection", TypeBool, Offset(mPlanarReflection, Material), "@internal" );
|
||||||
|
|
||||||
addField("translucent", TypeBool, Offset(mTranslucent, Material),
|
addField("translucent", TypeBool, Offset(mTranslucent, Material),
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@ public:
|
||||||
NormalizeCube,
|
NormalizeCube,
|
||||||
TexTarget,
|
TexTarget,
|
||||||
AccuMap,
|
AccuMap,
|
||||||
|
DynamicShadowMap,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BlendOp
|
enum BlendOp
|
||||||
|
|
@ -299,6 +300,7 @@ public:
|
||||||
/// A generic setting which tells the system to skip
|
/// A generic setting which tells the system to skip
|
||||||
/// generation of shadows from this material.
|
/// generation of shadows from this material.
|
||||||
bool mCastShadows;
|
bool mCastShadows;
|
||||||
|
bool mCastDynamicShadows;
|
||||||
|
|
||||||
bool mAlphaTest;
|
bool mAlphaTest;
|
||||||
U32 mAlphaRef;
|
U32 mAlphaRef;
|
||||||
|
|
@ -355,6 +357,7 @@ public:
|
||||||
virtual void setAutoGenerated(bool isAutoGenerated) { mAutoGenerated = isAutoGenerated; }
|
virtual void setAutoGenerated(bool isAutoGenerated) { mAutoGenerated = isAutoGenerated; }
|
||||||
virtual bool isLightmapped() const;
|
virtual bool isLightmapped() const;
|
||||||
virtual bool castsShadows() const { return mCastShadows; }
|
virtual bool castsShadows() const { return mCastShadows; }
|
||||||
|
virtual bool castsDynamicShadows() const { return mCastDynamicShadows; }
|
||||||
const String &getPath() const { return mPath; }
|
const String &getPath() const { return mPath; }
|
||||||
|
|
||||||
void flush();
|
void flush();
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,14 @@ void ProcessedCustomMaterial::_setStageData()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(filename.equal(String("$dynamicShadowMap"), String::NoCase))
|
||||||
|
{
|
||||||
|
rpd->mTexType[i] = Material::DynamicShadowMap;
|
||||||
|
rpd->mSamplerNames[i] = mCustomMaterial->mSamplerNames[i];
|
||||||
|
mMaxTex = i+1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(filename.equal(String("$dynamiclightmask"), String::NoCase))
|
if(filename.equal(String("$dynamiclightmask"), String::NoCase))
|
||||||
{
|
{
|
||||||
rpd->mTexType[i] = Material::DynamicLightMask;
|
rpd->mTexType[i] = Material::DynamicLightMask;
|
||||||
|
|
|
||||||
|
|
@ -908,6 +908,14 @@ inline bool mIsNaN( const Point2F &p )
|
||||||
return mIsNaN_F( p.x ) || mIsNaN_F( p.y );
|
return mIsNaN_F( p.x ) || mIsNaN_F( p.y );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return 0 if points are colinear
|
||||||
|
/// Return positive if p0p1p2 are counter-clockwise
|
||||||
|
/// Return negative if p0p1p2 are clockwise
|
||||||
|
inline F64 mCross(const Point2F &p0, const Point2F &p1, const Point2F &pt2)
|
||||||
|
{
|
||||||
|
return (p1.x - p0.x) * (pt2.y - p0.y) - (p1.y - p0.y) * (pt2.x - p0.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace DictHash
|
namespace DictHash
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1845,4 +1845,55 @@ U32 extrudePolygonEdgesFromPoint( const Point3F* vertices, U32 numVertices, cons
|
||||||
return numPlanes;
|
return numPlanes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void MathUtils::mBuildHull2D(const Vector<Point2F> _inPoints, Vector<Point2F> &hullPoints)
|
||||||
|
{
|
||||||
|
/// Andrew's monotone chain convex hull algorithm implementation
|
||||||
|
|
||||||
|
struct Util
|
||||||
|
{
|
||||||
|
//compare by x and then by y
|
||||||
|
static int CompareLexicographic( const Point2F *a, const Point2F *b)
|
||||||
|
{
|
||||||
|
return a->x < b->x || (a->x == b->x && a->y < b->y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
hullPoints.clear();
|
||||||
|
hullPoints.setSize( _inPoints.size()*2 );
|
||||||
|
|
||||||
|
// sort in points by x and then by y
|
||||||
|
Vector<Point2F> inSortedPoints = _inPoints;
|
||||||
|
inSortedPoints.sort( &Util::CompareLexicographic );
|
||||||
|
|
||||||
|
Point2F* lowerHullPtr = hullPoints.address();
|
||||||
|
U32 lowerHullIdx = 0;
|
||||||
|
|
||||||
|
//lower part of hull
|
||||||
|
for( int i = 0; i < inSortedPoints.size(); ++i )
|
||||||
|
{
|
||||||
|
while( lowerHullIdx >= 2 && mCross( lowerHullPtr[ lowerHullIdx - 2], lowerHullPtr[lowerHullIdx - 1], inSortedPoints[i] ) <= 0 )
|
||||||
|
--lowerHullIdx;
|
||||||
|
|
||||||
|
lowerHullPtr[lowerHullIdx++] = inSortedPoints[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
--lowerHullIdx; // last point are the same as first in upperHullPtr
|
||||||
|
|
||||||
|
Point2F* upperHullPtr = hullPoints.address() + lowerHullIdx;
|
||||||
|
U32 upperHullIdx = 0;
|
||||||
|
|
||||||
|
//upper part of hull
|
||||||
|
for( int i = inSortedPoints.size()-1; i >= 0; --i )
|
||||||
|
{
|
||||||
|
while( upperHullIdx >= 2 && mCross( upperHullPtr[ upperHullIdx - 2], upperHullPtr[upperHullIdx - 1], inSortedPoints[i] ) <= 0 )
|
||||||
|
--upperHullIdx;
|
||||||
|
|
||||||
|
upperHullPtr[upperHullIdx++] = inSortedPoints[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
hullPoints.setSize( lowerHullIdx + upperHullIdx );
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace MathUtils
|
} // namespace MathUtils
|
||||||
|
|
|
||||||
|
|
@ -417,6 +417,9 @@ namespace MathUtils
|
||||||
|
|
||||||
//void findFarthestPoint( const Point3F* points, U32 numPoints, const Point3F& fromPoint, )
|
//void findFarthestPoint( const Point3F* points, U32 numPoints, const Point3F& fromPoint, )
|
||||||
|
|
||||||
|
/// Build a convex hull from a cloud of 2D points, first and last hull point are the same.
|
||||||
|
void mBuildHull2D(const Vector<Point2F> inPoints, Vector<Point2F> &hullPoints);
|
||||||
|
|
||||||
} // namespace MathUtils
|
} // namespace MathUtils
|
||||||
|
|
||||||
#endif // _MATHUTILS_H_
|
#endif // _MATHUTILS_H_
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,8 @@ SceneCullingState::SceneCullingState( SceneManager* sceneManager, const SceneCam
|
||||||
SceneCullingVolume::Includer,
|
SceneCullingVolume::Includer,
|
||||||
PlaneSetF( planes, 4 )
|
PlaneSetF( planes, 4 )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
clearExtraPlanesCull();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -789,6 +791,9 @@ U32 SceneCullingState::cullObjects( SceneObject** objects, U32 numObjects, U32 c
|
||||||
result == SceneZoneCullingState::CullingTestPositiveByOcclusion );
|
result == SceneZoneCullingState::CullingTestPositiveByOcclusion );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( !isCulled )
|
||||||
|
isCulled = isOccludedWithExtraPlanesCull( object->getWorldBox() );
|
||||||
|
|
||||||
if( !isCulled )
|
if( !isCulled )
|
||||||
objects[ numRemainingObjects ++ ] = object;
|
objects[ numRemainingObjects ++ ] = object;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,9 @@ class SceneCullingState
|
||||||
/// The root culling frustum, which may be different from the camera frustum
|
/// The root culling frustum, which may be different from the camera frustum
|
||||||
Frustum mCullingFrustum;
|
Frustum mCullingFrustum;
|
||||||
|
|
||||||
|
/// Extra planes for culling.
|
||||||
|
PlaneSetF mExtraPlanesCull;
|
||||||
|
|
||||||
/// Occluders that have been added to this render state. Adding an occluder does not
|
/// Occluders that have been added to this render state. Adding an occluder does not
|
||||||
/// necessarily result in an occluder volume being added. To not repeatedly try to
|
/// necessarily result in an occluder volume being added. To not repeatedly try to
|
||||||
/// process the same occluder object, all objects that are added are recorded here.
|
/// process the same occluder object, all objects that are added are recorded here.
|
||||||
|
|
@ -301,6 +304,21 @@ class SceneCullingState
|
||||||
/// (or, if no zone is selected, all volumes in the outdoor zone) to the debug drawer.
|
/// (or, if no zone is selected, all volumes in the outdoor zone) to the debug drawer.
|
||||||
void debugRenderCullingVolumes() const;
|
void debugRenderCullingVolumes() const;
|
||||||
|
|
||||||
|
/// Set planes for extra culling
|
||||||
|
void setExtraPlanesCull( const PlaneSetF &cull) { mExtraPlanesCull = cull; }
|
||||||
|
|
||||||
|
/// Clear planes for extra culling.
|
||||||
|
void clearExtraPlanesCull() { mExtraPlanesCull = PlaneSetF(NULL, 0); }
|
||||||
|
|
||||||
|
/// Check extra planes culling
|
||||||
|
bool isOccludedWithExtraPlanesCull(const Box3F &box) const
|
||||||
|
{
|
||||||
|
if(mExtraPlanesCull.getNumPlanes())
|
||||||
|
return mExtraPlanesCull.testPotentialIntersection( box ) == GeometryOutside;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
typedef SceneZoneCullingState::CullingTestResult CullingTestResult;
|
typedef SceneZoneCullingState::CullingTestResult CullingTestResult;
|
||||||
|
|
|
||||||
|
|
@ -62,9 +62,10 @@ new ShaderData( AL_VectorLightShader )
|
||||||
OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/vectorLightP.glsl";
|
OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/vectorLightP.glsl";
|
||||||
|
|
||||||
samplerNames[0] = "$prePassBuffer";
|
samplerNames[0] = "$prePassBuffer";
|
||||||
samplerNames[1] = "$ShadowMap";
|
samplerNames[1] = "$shadowMap";
|
||||||
samplerNames[2] = "$ssaoMask";
|
samplerNames[2] = "$dynamicShadowMap";
|
||||||
samplerNames[3] = "$gTapRotationTex";
|
samplerNames[3] = "$ssaoMask";
|
||||||
|
samplerNames[4] = "$gTapRotationTex";
|
||||||
|
|
||||||
pixVersion = 3.0;
|
pixVersion = 3.0;
|
||||||
};
|
};
|
||||||
|
|
@ -75,7 +76,8 @@ new CustomMaterial( AL_VectorLightMaterial )
|
||||||
stateBlock = AL_VectorLightState;
|
stateBlock = AL_VectorLightState;
|
||||||
|
|
||||||
sampler["prePassBuffer"] = "#prepass";
|
sampler["prePassBuffer"] = "#prepass";
|
||||||
sampler["ShadowMap"] = "$dynamiclight";
|
sampler["shadowMap"] = "$dynamiclight";
|
||||||
|
sampler["dynamicShadowMap"] = "$dynamicShadowMap";
|
||||||
sampler["ssaoMask"] = "#ssaoMask";
|
sampler["ssaoMask"] = "#ssaoMask";
|
||||||
|
|
||||||
target = "lightinfo";
|
target = "lightinfo";
|
||||||
|
|
@ -128,8 +130,9 @@ new ShaderData( AL_PointLightShader )
|
||||||
|
|
||||||
samplerNames[0] = "$prePassBuffer";
|
samplerNames[0] = "$prePassBuffer";
|
||||||
samplerNames[1] = "$shadowMap";
|
samplerNames[1] = "$shadowMap";
|
||||||
samplerNames[2] = "$cookieMap";
|
samplerNames[2] = "$dynamicShadowMap";
|
||||||
samplerNames[3] = "$gTapRotationTex";
|
samplerNames[3] = "$cookieMap";
|
||||||
|
samplerNames[4] = "$gTapRotationTex";
|
||||||
|
|
||||||
pixVersion = 3.0;
|
pixVersion = 3.0;
|
||||||
};
|
};
|
||||||
|
|
@ -141,6 +144,7 @@ new CustomMaterial( AL_PointLightMaterial )
|
||||||
|
|
||||||
sampler["prePassBuffer"] = "#prepass";
|
sampler["prePassBuffer"] = "#prepass";
|
||||||
sampler["shadowMap"] = "$dynamiclight";
|
sampler["shadowMap"] = "$dynamiclight";
|
||||||
|
sampler["dynamicShadowMap"] = "$dynamicShadowMap";
|
||||||
sampler["cookieMap"] = "$dynamiclightmask";
|
sampler["cookieMap"] = "$dynamiclightmask";
|
||||||
|
|
||||||
target = "lightinfo";
|
target = "lightinfo";
|
||||||
|
|
@ -159,8 +163,9 @@ new ShaderData( AL_SpotLightShader )
|
||||||
|
|
||||||
samplerNames[0] = "$prePassBuffer";
|
samplerNames[0] = "$prePassBuffer";
|
||||||
samplerNames[1] = "$shadowMap";
|
samplerNames[1] = "$shadowMap";
|
||||||
samplerNames[2] = "$cookieMap";
|
samplerNames[2] = "$dynamicShadowMap";
|
||||||
samplerNames[3] = "$gTapRotationTex";
|
samplerNames[3] = "$cookieMap";
|
||||||
|
samplerNames[4] = "$gTapRotationTex";
|
||||||
|
|
||||||
pixVersion = 3.0;
|
pixVersion = 3.0;
|
||||||
};
|
};
|
||||||
|
|
@ -172,6 +177,7 @@ new CustomMaterial( AL_SpotLightMaterial )
|
||||||
|
|
||||||
sampler["prePassBuffer"] = "#prepass";
|
sampler["prePassBuffer"] = "#prepass";
|
||||||
sampler["shadowMap"] = "$dynamiclight";
|
sampler["shadowMap"] = "$dynamiclight";
|
||||||
|
sampler["dynamicShadowMap"] = "$dynamicShadowMap";
|
||||||
sampler["cookieMap"] = "$dynamiclightmask";
|
sampler["cookieMap"] = "$dynamiclightmask";
|
||||||
|
|
||||||
target = "lightinfo";
|
target = "lightinfo";
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
#include "../../../gl/lighting.glsl"
|
#include "../../../gl/lighting.glsl"
|
||||||
#include "../../shadowMap/shadowMapIO_GLSL.h"
|
#include "../../shadowMap/shadowMapIO_GLSL.h"
|
||||||
#include "softShadow.glsl"
|
#include "softShadow.glsl"
|
||||||
|
#include "../../../gl/torque.glsl"
|
||||||
|
|
||||||
in vec4 wsEyeDir;
|
in vec4 wsEyeDir;
|
||||||
in vec4 ssPos;
|
in vec4 ssPos;
|
||||||
|
|
@ -107,6 +108,7 @@ uniform sampler2D prePassBuffer;
|
||||||
uniform samplerCube shadowMap;
|
uniform samplerCube shadowMap;
|
||||||
#else
|
#else
|
||||||
uniform sampler2D shadowMap;
|
uniform sampler2D shadowMap;
|
||||||
|
uniform sampler2D dynamicShadowMap;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uniform vec4 rtParams0;
|
uniform vec4 rtParams0;
|
||||||
|
|
@ -119,6 +121,7 @@ uniform vec2 lightAttenuation;
|
||||||
uniform vec4 lightMapParams;
|
uniform vec4 lightMapParams;
|
||||||
uniform vec4 vsFarPlane;
|
uniform vec4 vsFarPlane;
|
||||||
uniform mat3 viewToLightProj;
|
uniform mat3 viewToLightProj;
|
||||||
|
uniform mat3 dynamicViewToLightProj;
|
||||||
uniform vec4 lightParams;
|
uniform vec4 lightParams;
|
||||||
uniform float shadowSoftness;
|
uniform float shadowSoftness;
|
||||||
|
|
||||||
|
|
@ -175,7 +178,7 @@ void main()
|
||||||
|
|
||||||
vec2 shadowCoord = decodeShadowCoord( tMul( viewToLightProj, -lightVec ) ).xy;
|
vec2 shadowCoord = decodeShadowCoord( tMul( viewToLightProj, -lightVec ) ).xy;
|
||||||
|
|
||||||
float shadowed = softShadow_filter( shadowMap,
|
float static_shadowed = softShadow_filter( shadowMap,
|
||||||
ssPos.xy,
|
ssPos.xy,
|
||||||
shadowCoord,
|
shadowCoord,
|
||||||
shadowSoftness,
|
shadowSoftness,
|
||||||
|
|
@ -183,17 +186,28 @@ void main()
|
||||||
nDotL,
|
nDotL,
|
||||||
lightParams.y );
|
lightParams.y );
|
||||||
|
|
||||||
|
vec2 dynamicShadowCoord = decodeShadowCoord( tMul( dynamicViewToLightProj, -lightVec ) ).xy;
|
||||||
|
float dynamic_shadowed = softShadow_filter( dynamicShadowMap,
|
||||||
|
ssPos.xy,
|
||||||
|
dynamicShadowCoord,
|
||||||
|
shadowSoftness,
|
||||||
|
distToLight,
|
||||||
|
nDotL,
|
||||||
|
lightParams.y );
|
||||||
|
|
||||||
|
float shadowed = min(static_shadowed, dynamic_shadowed);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // !NO_SHADOW
|
#endif // !NO_SHADOW
|
||||||
|
|
||||||
|
vec3 lightcol = lightColor.rgb;
|
||||||
#ifdef USE_COOKIE_TEX
|
#ifdef USE_COOKIE_TEX
|
||||||
|
|
||||||
// Lookup the cookie sample.
|
// Lookup the cookie sample.
|
||||||
vec4 cookie = texture( cookieMap, tMul( viewToLightProj, -lightVec ) );
|
vec4 cookie = texture( cookieMap, tMul( viewToLightProj, -lightVec ) );
|
||||||
|
|
||||||
// Multiply the light with the cookie tex.
|
// Multiply the light with the cookie tex.
|
||||||
lightColor.rgb *= cookie.rgb;
|
lightcol *= cookie.rgb;
|
||||||
|
|
||||||
// Use a maximum channel luminance to attenuate
|
// Use a maximum channel luminance to attenuate
|
||||||
// the lighting else we get specular in the dark
|
// the lighting else we get specular in the dark
|
||||||
|
|
@ -211,7 +225,7 @@ void main()
|
||||||
normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
|
normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
|
||||||
|
|
||||||
float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
|
float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
|
||||||
vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb;
|
vec3 lightColorOut = lightMapParams.rgb * lightcol;
|
||||||
vec4 addToResult = vec4(0.0);
|
vec4 addToResult = vec4(0.0);
|
||||||
|
|
||||||
// TODO: This needs to be removed when lightmapping is disabled
|
// TODO: This needs to be removed when lightmapping is disabled
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include "shadergen:/autogenConditioners.h"
|
#include "shadergen:/autogenConditioners.h"
|
||||||
#include "softShadow.glsl"
|
#include "softShadow.glsl"
|
||||||
#include "../../../gl/lighting.glsl"
|
#include "../../../gl/lighting.glsl"
|
||||||
|
#include "../../../gl/torque.glsl"
|
||||||
|
|
||||||
in vec4 wsEyeDir;
|
in vec4 wsEyeDir;
|
||||||
in vec4 ssPos;
|
in vec4 ssPos;
|
||||||
|
|
@ -45,6 +46,7 @@ uniform sampler2D cookieMap;
|
||||||
|
|
||||||
uniform sampler2D prePassBuffer;
|
uniform sampler2D prePassBuffer;
|
||||||
uniform sampler2D shadowMap;
|
uniform sampler2D shadowMap;
|
||||||
|
uniform sampler2D dynamicShadowMap;
|
||||||
|
|
||||||
uniform vec4 rtParams0;
|
uniform vec4 rtParams0;
|
||||||
|
|
||||||
|
|
@ -59,6 +61,7 @@ uniform vec4 lightMapParams;
|
||||||
|
|
||||||
uniform vec4 vsFarPlane;
|
uniform vec4 vsFarPlane;
|
||||||
uniform mat4 viewToLightProj;
|
uniform mat4 viewToLightProj;
|
||||||
|
uniform mat4 dynamicViewToLightProj;
|
||||||
|
|
||||||
uniform vec4 lightParams;
|
uniform vec4 lightParams;
|
||||||
uniform float shadowSoftness;
|
uniform float shadowSoftness;
|
||||||
|
|
@ -102,6 +105,10 @@ void main()
|
||||||
vec2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 );
|
vec2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 );
|
||||||
shadowCoord.y = 1.0f - shadowCoord.y;
|
shadowCoord.y = 1.0f - shadowCoord.y;
|
||||||
|
|
||||||
|
// Get the dynamic shadow texture coordinate
|
||||||
|
vec4 dynpxlPosLightProj = tMul( dynamicViewToLightProj, vec4( viewSpacePos, 1 ) );
|
||||||
|
vec2 dynshadowCoord = ( ( dynpxlPosLightProj.xy / dynpxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 );
|
||||||
|
dynshadowCoord.y = 1.0f - dynshadowCoord.y;
|
||||||
#ifdef NO_SHADOW
|
#ifdef NO_SHADOW
|
||||||
|
|
||||||
float shadowed = 1.0;
|
float shadowed = 1.0;
|
||||||
|
|
@ -111,7 +118,7 @@ void main()
|
||||||
// Get a linear depth from the light source.
|
// Get a linear depth from the light source.
|
||||||
float distToLight = pxlPosLightProj.z / lightRange;
|
float distToLight = pxlPosLightProj.z / lightRange;
|
||||||
|
|
||||||
float shadowed = softShadow_filter( shadowMap,
|
float static_shadowed = softShadow_filter( shadowMap,
|
||||||
ssPos.xy,
|
ssPos.xy,
|
||||||
shadowCoord,
|
shadowCoord,
|
||||||
shadowSoftness,
|
shadowSoftness,
|
||||||
|
|
@ -119,15 +126,24 @@ void main()
|
||||||
nDotL,
|
nDotL,
|
||||||
lightParams.y );
|
lightParams.y );
|
||||||
|
|
||||||
|
float dynamic_shadowed = softShadow_filter( dynamicShadowMap,
|
||||||
|
ssPos.xy,
|
||||||
|
dynshadowCoord,
|
||||||
|
shadowSoftness,
|
||||||
|
distToLight,
|
||||||
|
nDotL,
|
||||||
|
lightParams.y );
|
||||||
|
float shadowed = min(static_shadowed, dynamic_shadowed);
|
||||||
#endif // !NO_SHADOW
|
#endif // !NO_SHADOW
|
||||||
|
|
||||||
|
vec3 lightcol = lightColor.rgb;
|
||||||
#ifdef USE_COOKIE_TEX
|
#ifdef USE_COOKIE_TEX
|
||||||
|
|
||||||
// Lookup the cookie sample.
|
// Lookup the cookie sample.
|
||||||
vec4 cookie = texture( cookieMap, shadowCoord );
|
vec4 cookie = texture( cookieMap, shadowCoord );
|
||||||
|
|
||||||
// Multiply the light with the cookie tex.
|
// Multiply the light with the cookie tex.
|
||||||
lightColor.rgb *= cookie.rgb;
|
lightcol *= cookie.rgb;
|
||||||
|
|
||||||
// Use a maximum channel luminance to attenuate
|
// Use a maximum channel luminance to attenuate
|
||||||
// the lighting else we get specular in the dark
|
// the lighting else we get specular in the dark
|
||||||
|
|
@ -145,7 +161,7 @@ void main()
|
||||||
normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
|
normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
|
||||||
|
|
||||||
float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
|
float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
|
||||||
vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb;
|
vec3 lightColorOut = lightMapParams.rgb * lightcol;
|
||||||
vec4 addToResult = vec4(0.0);
|
vec4 addToResult = vec4(0.0);
|
||||||
|
|
||||||
// TODO: This needs to be removed when lightmapping is disabled
|
// TODO: This needs to be removed when lightmapping is disabled
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,8 @@ in vec2 uv0;
|
||||||
in vec3 wsEyeRay;
|
in vec3 wsEyeRay;
|
||||||
in vec3 vsEyeRay;
|
in vec3 vsEyeRay;
|
||||||
|
|
||||||
uniform sampler2D ShadowMap ;
|
uniform sampler2D shadowMap;
|
||||||
|
uniform sampler2D dynamicShadowMap;
|
||||||
|
|
||||||
#ifdef USE_SSAO_MASK
|
#ifdef USE_SSAO_MASK
|
||||||
uniform sampler2D ssaoMask ;
|
uniform sampler2D ssaoMask ;
|
||||||
|
|
@ -47,23 +48,146 @@ uniform vec4 lightColor;
|
||||||
uniform float lightBrightness;
|
uniform float lightBrightness;
|
||||||
uniform vec4 lightAmbient;
|
uniform vec4 lightAmbient;
|
||||||
uniform vec3 eyePosWorld;
|
uniform vec3 eyePosWorld;
|
||||||
uniform mat4x4 worldToLightProj;
|
uniform mat4x4 eyeMat;
|
||||||
uniform vec4 scaleX;
|
|
||||||
uniform vec4 scaleY;
|
|
||||||
uniform vec4 offsetX;
|
|
||||||
uniform vec4 offsetY;
|
|
||||||
uniform vec4 atlasXOffset;
|
uniform vec4 atlasXOffset;
|
||||||
uniform vec4 atlasYOffset;
|
uniform vec4 atlasYOffset;
|
||||||
uniform vec2 atlasScale;
|
uniform vec2 atlasScale;
|
||||||
uniform vec4 zNearFarInvNearFar;
|
uniform vec4 zNearFarInvNearFar;
|
||||||
uniform vec4 lightMapParams;
|
uniform vec4 lightMapParams;
|
||||||
uniform vec2 fadeStartLength;
|
uniform vec2 fadeStartLength;
|
||||||
uniform vec4 farPlaneScalePSSM;
|
|
||||||
uniform vec4 overDarkPSSM;
|
uniform vec4 overDarkPSSM;
|
||||||
uniform float shadowSoftness;
|
uniform float shadowSoftness;
|
||||||
|
|
||||||
out vec4 OUT_col;
|
//static shadowMap
|
||||||
|
uniform mat4x4 worldToLightProj;
|
||||||
|
uniform vec4 scaleX;
|
||||||
|
uniform vec4 scaleY;
|
||||||
|
uniform vec4 offsetX;
|
||||||
|
uniform vec4 offsetY;
|
||||||
|
uniform vec4 farPlaneScalePSSM;
|
||||||
|
|
||||||
|
//dynamic shadowMap
|
||||||
|
uniform mat4x4 dynamicWorldToLightProj;
|
||||||
|
uniform vec4 dynamicScaleX;
|
||||||
|
uniform vec4 dynamicScaleY;
|
||||||
|
uniform vec4 dynamicOffsetX;
|
||||||
|
uniform vec4 dynamicOffsetY;
|
||||||
|
uniform vec4 dynamicFarPlaneScalePSSM;
|
||||||
|
|
||||||
|
vec4 AL_VectorLightShadowCast( sampler2D _sourceshadowMap,
|
||||||
|
vec2 _texCoord,
|
||||||
|
mat4 _worldToLightProj,
|
||||||
|
vec4 _worldPos,
|
||||||
|
vec4 _scaleX, vec4 _scaleY,
|
||||||
|
vec4 _offsetX, vec4 _offsetY,
|
||||||
|
vec4 _farPlaneScalePSSM,
|
||||||
|
vec4 _atlasXOffset, vec4 _atlasYOffset,
|
||||||
|
vec2 _atlasScale,
|
||||||
|
float _shadowSoftness,
|
||||||
|
float _dotNL ,
|
||||||
|
vec4 _overDarkPSSM
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Compute shadow map coordinate
|
||||||
|
vec4 pxlPosLightProj = tMul(_worldToLightProj, _worldPos);
|
||||||
|
vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
|
||||||
|
|
||||||
|
// Distance to light, in shadowMap space
|
||||||
|
float distToLight = pxlPosLightProj.z / pxlPosLightProj.w;
|
||||||
|
|
||||||
|
// Figure out which split to sample from. Basically, we compute the shadowMap sample coord
|
||||||
|
// for all of the splits and then check if its valid.
|
||||||
|
vec4 shadowCoordX = vec4( baseShadowCoord.x );
|
||||||
|
vec4 shadowCoordY = vec4( baseShadowCoord.y );
|
||||||
|
vec4 farPlaneDists = vec4( distToLight );
|
||||||
|
shadowCoordX *= _scaleX;
|
||||||
|
shadowCoordY *= _scaleY;
|
||||||
|
shadowCoordX += _offsetX;
|
||||||
|
shadowCoordY += _offsetY;
|
||||||
|
farPlaneDists *= _farPlaneScalePSSM;
|
||||||
|
|
||||||
|
// If the shadow sample is within -1..1 and the distance
|
||||||
|
// to the light for this pixel is less than the far plane
|
||||||
|
// of the split, use it.
|
||||||
|
vec4 finalMask;
|
||||||
|
if ( shadowCoordX.x > -0.99 && shadowCoordX.x < 0.99 &&
|
||||||
|
shadowCoordY.x > -0.99 && shadowCoordY.x < 0.99 &&
|
||||||
|
farPlaneDists.x < 1.0 )
|
||||||
|
finalMask = vec4(1, 0, 0, 0);
|
||||||
|
|
||||||
|
else if ( shadowCoordX.y > -0.99 && shadowCoordX.y < 0.99 &&
|
||||||
|
shadowCoordY.y > -0.99 && shadowCoordY.y < 0.99 &&
|
||||||
|
farPlaneDists.y < 1.0 )
|
||||||
|
finalMask = vec4(0, 1, 0, 0);
|
||||||
|
|
||||||
|
else if ( shadowCoordX.z > -0.99 && shadowCoordX.z < 0.99 &&
|
||||||
|
shadowCoordY.z > -0.99 && shadowCoordY.z < 0.99 &&
|
||||||
|
farPlaneDists.z < 1.0 )
|
||||||
|
finalMask = vec4(0, 0, 1, 0);
|
||||||
|
|
||||||
|
else
|
||||||
|
finalMask = vec4(0, 0, 0, 1);
|
||||||
|
|
||||||
|
vec3 debugColor = vec3(0);
|
||||||
|
|
||||||
|
#ifdef NO_SHADOW
|
||||||
|
debugColor = vec3(1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PSSM_DEBUG_RENDER
|
||||||
|
if ( finalMask.x > 0 )
|
||||||
|
debugColor += vec3( 1, 0, 0 );
|
||||||
|
else if ( finalMask.y > 0 )
|
||||||
|
debugColor += vec3( 0, 1, 0 );
|
||||||
|
else if ( finalMask.z > 0 )
|
||||||
|
debugColor += vec3( 0, 0, 1 );
|
||||||
|
else if ( finalMask.w > 0 )
|
||||||
|
debugColor += vec3( 1, 1, 0 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Here we know what split we're sampling from, so recompute the _texCoord location
|
||||||
|
// Yes, we could just use the result from above, but doing it this way actually saves
|
||||||
|
// shader instructions.
|
||||||
|
vec2 finalScale;
|
||||||
|
finalScale.x = dot(finalMask, _scaleX);
|
||||||
|
finalScale.y = dot(finalMask, _scaleY);
|
||||||
|
|
||||||
|
vec2 finalOffset;
|
||||||
|
finalOffset.x = dot(finalMask, _offsetX);
|
||||||
|
finalOffset.y = dot(finalMask, _offsetY);
|
||||||
|
|
||||||
|
vec2 shadowCoord;
|
||||||
|
shadowCoord = baseShadowCoord * finalScale;
|
||||||
|
shadowCoord += finalOffset;
|
||||||
|
|
||||||
|
// Convert to _texCoord space
|
||||||
|
shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5);
|
||||||
|
shadowCoord.y = 1.0f - shadowCoord.y;
|
||||||
|
|
||||||
|
// Move around inside of atlas
|
||||||
|
vec2 aOffset;
|
||||||
|
aOffset.x = dot(finalMask, _atlasXOffset);
|
||||||
|
aOffset.y = dot(finalMask, _atlasYOffset);
|
||||||
|
|
||||||
|
shadowCoord *= _atlasScale;
|
||||||
|
shadowCoord += aOffset;
|
||||||
|
|
||||||
|
// Each split has a different far plane, take this into account.
|
||||||
|
float farPlaneScale = dot( _farPlaneScalePSSM, finalMask );
|
||||||
|
distToLight *= farPlaneScale;
|
||||||
|
|
||||||
|
return vec4(debugColor,
|
||||||
|
softShadow_filter( _sourceshadowMap,
|
||||||
|
_texCoord,
|
||||||
|
shadowCoord,
|
||||||
|
farPlaneScale * _shadowSoftness,
|
||||||
|
distToLight,
|
||||||
|
_dotNL,
|
||||||
|
dot( finalMask, _overDarkPSSM ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
out vec4 OUT_col;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Sample/unpack the normal/z data
|
// Sample/unpack the normal/z data
|
||||||
|
|
@ -92,101 +216,51 @@ void main()
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// Compute shadow map coordinate
|
vec4 static_shadowed_colors = AL_VectorLightShadowCast( shadowMap,
|
||||||
vec4 pxlPosLightProj = tMul(worldToLightProj, worldPos);
|
uv0.xy,
|
||||||
vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
|
worldToLightProj,
|
||||||
|
worldPos,
|
||||||
|
scaleX, scaleY,
|
||||||
|
offsetX, offsetY,
|
||||||
|
farPlaneScalePSSM,
|
||||||
|
atlasXOffset, atlasYOffset,
|
||||||
|
atlasScale,
|
||||||
|
shadowSoftness,
|
||||||
|
dotNL,
|
||||||
|
overDarkPSSM);
|
||||||
|
|
||||||
// Distance to light, in shadowmap space
|
|
||||||
float distToLight = pxlPosLightProj.z / pxlPosLightProj.w;
|
|
||||||
|
|
||||||
// Figure out which split to sample from. Basically, we compute the shadowmap sample coord
|
vec4 dynamic_shadowed_colors = AL_VectorLightShadowCast( dynamicShadowMap,
|
||||||
// for all of the splits and then check if its valid.
|
uv0.xy,
|
||||||
vec4 shadowCoordX = vec4( baseShadowCoord.x );
|
dynamicWorldToLightProj,
|
||||||
vec4 shadowCoordY = vec4( baseShadowCoord.y );
|
worldPos,
|
||||||
vec4 farPlaneDists = vec4( distToLight );
|
dynamicScaleX, dynamicScaleY,
|
||||||
shadowCoordX *= scaleX;
|
dynamicOffsetX, dynamicOffsetY,
|
||||||
shadowCoordY *= scaleY;
|
dynamicFarPlaneScalePSSM,
|
||||||
shadowCoordX += offsetX;
|
atlasXOffset, atlasYOffset,
|
||||||
shadowCoordY += offsetY;
|
atlasScale,
|
||||||
farPlaneDists *= farPlaneScalePSSM;
|
shadowSoftness,
|
||||||
|
dotNL,
|
||||||
// If the shadow sample is within -1..1 and the distance
|
overDarkPSSM);
|
||||||
// to the light for this pixel is less than the far plane
|
|
||||||
// of the split, use it.
|
|
||||||
vec4 finalMask;
|
|
||||||
if ( shadowCoordX.x > -0.99 && shadowCoordX.x < 0.99 &&
|
|
||||||
shadowCoordY.x > -0.99 && shadowCoordY.x < 0.99 &&
|
|
||||||
farPlaneDists.x < 1.0 )
|
|
||||||
finalMask = vec4(1, 0, 0, 0);
|
|
||||||
|
|
||||||
else if ( shadowCoordX.y > -0.99 && shadowCoordX.y < 0.99 &&
|
|
||||||
shadowCoordY.y > -0.99 && shadowCoordY.y < 0.99 &&
|
|
||||||
farPlaneDists.y < 1.0 )
|
|
||||||
finalMask = vec4(0, 1, 0, 0);
|
|
||||||
|
|
||||||
else if ( shadowCoordX.z > -0.99 && shadowCoordX.z < 0.99 &&
|
|
||||||
shadowCoordY.z > -0.99 && shadowCoordY.z < 0.99 &&
|
|
||||||
farPlaneDists.z < 1.0 )
|
|
||||||
finalMask = vec4(0, 0, 1, 0);
|
|
||||||
|
|
||||||
else
|
|
||||||
finalMask = vec4(0, 0, 0, 1);
|
|
||||||
|
|
||||||
|
float static_shadowed = static_shadowed_colors.a;
|
||||||
|
float dynamic_shadowed = dynamic_shadowed_colors.a;
|
||||||
|
|
||||||
#ifdef PSSM_DEBUG_RENDER
|
#ifdef PSSM_DEBUG_RENDER
|
||||||
if ( finalMask.x > 0 )
|
debugColor = static_shadowed_colors.rgb*0.5+dynamic_shadowed_colors.rgb*0.5;
|
||||||
debugColor += vec3( 1, 0, 0 );
|
|
||||||
else if ( finalMask.y > 0 )
|
|
||||||
debugColor += vec3( 0, 1, 0 );
|
|
||||||
else if ( finalMask.z > 0 )
|
|
||||||
debugColor += vec3( 0, 0, 1 );
|
|
||||||
else if ( finalMask.w > 0 )
|
|
||||||
debugColor += vec3( 1, 1, 0 );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Here we know what split we're sampling from, so recompute the texcoord location
|
|
||||||
// Yes, we could just use the result from above, but doing it this way actually saves
|
|
||||||
// shader instructions.
|
|
||||||
vec2 finalScale;
|
|
||||||
finalScale.x = dot(finalMask, scaleX);
|
|
||||||
finalScale.y = dot(finalMask, scaleY);
|
|
||||||
|
|
||||||
vec2 finalOffset;
|
|
||||||
finalOffset.x = dot(finalMask, offsetX);
|
|
||||||
finalOffset.y = dot(finalMask, offsetY);
|
|
||||||
|
|
||||||
vec2 shadowCoord;
|
|
||||||
shadowCoord = baseShadowCoord * finalScale;
|
|
||||||
shadowCoord += finalOffset;
|
|
||||||
|
|
||||||
// Convert to texcoord space
|
|
||||||
shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5);
|
|
||||||
shadowCoord.y = 1.0f - shadowCoord.y;
|
|
||||||
|
|
||||||
// Move around inside of atlas
|
|
||||||
vec2 aOffset;
|
|
||||||
aOffset.x = dot(finalMask, atlasXOffset);
|
|
||||||
aOffset.y = dot(finalMask, atlasYOffset);
|
|
||||||
|
|
||||||
shadowCoord *= atlasScale;
|
|
||||||
shadowCoord += aOffset;
|
|
||||||
|
|
||||||
// Each split has a different far plane, take this into account.
|
|
||||||
float farPlaneScale = dot( farPlaneScalePSSM, finalMask );
|
|
||||||
distToLight *= farPlaneScale;
|
|
||||||
|
|
||||||
float shadowed = softShadow_filter( ShadowMap,
|
|
||||||
uv0.xy,
|
|
||||||
shadowCoord,
|
|
||||||
farPlaneScale * shadowSoftness,
|
|
||||||
distToLight,
|
|
||||||
dotNL,
|
|
||||||
dot( finalMask, overDarkPSSM ) );
|
|
||||||
|
|
||||||
// Fade out the shadow at the end of the range.
|
// Fade out the shadow at the end of the range.
|
||||||
vec4 zDist = vec4(zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth);
|
vec4 zDist = vec4(zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth);
|
||||||
float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y;
|
float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y;
|
||||||
shadowed = mix( shadowed, 1.0, saturate( fadeOutAmt ) );
|
|
||||||
|
static_shadowed = mix( static_shadowed, 1.0, saturate( fadeOutAmt ) );
|
||||||
|
dynamic_shadowed = mix( dynamic_shadowed, 1.0, saturate( fadeOutAmt ) );
|
||||||
|
|
||||||
|
// temp for debugging. uncomment one or the other.
|
||||||
|
//float shadowed = static_shadowed;
|
||||||
|
//float shadowed = dynamic_shadowed;
|
||||||
|
float shadowed = min(static_shadowed, dynamic_shadowed);
|
||||||
|
|
||||||
#ifdef PSSM_DEBUG_RENDER
|
#ifdef PSSM_DEBUG_RENDER
|
||||||
if ( fadeOutAmt > 1.0 )
|
if ( fadeOutAmt > 1.0 )
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
#include "../../lighting.hlsl"
|
#include "../../lighting.hlsl"
|
||||||
#include "../shadowMap/shadowMapIO_HLSL.h"
|
#include "../shadowMap/shadowMapIO_HLSL.h"
|
||||||
#include "softShadow.hlsl"
|
#include "softShadow.hlsl"
|
||||||
|
#include "../../torque.hlsl"
|
||||||
|
|
||||||
struct ConvexConnectP
|
struct ConvexConnectP
|
||||||
{
|
{
|
||||||
|
|
@ -40,7 +40,7 @@ struct ConvexConnectP
|
||||||
#ifdef USE_COOKIE_TEX
|
#ifdef USE_COOKIE_TEX
|
||||||
|
|
||||||
/// The texture for cookie rendering.
|
/// The texture for cookie rendering.
|
||||||
uniform samplerCUBE cookieMap : register(S2);
|
uniform samplerCUBE cookieMap : register(S3);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -114,6 +114,7 @@ float4 main( ConvexConnectP IN,
|
||||||
uniform samplerCUBE shadowMap : register(S1),
|
uniform samplerCUBE shadowMap : register(S1),
|
||||||
#else
|
#else
|
||||||
uniform sampler2D shadowMap : register(S1),
|
uniform sampler2D shadowMap : register(S1),
|
||||||
|
uniform sampler2D dynamicShadowMap : register(S2),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uniform float4 rtParams0,
|
uniform float4 rtParams0,
|
||||||
|
|
@ -127,6 +128,7 @@ float4 main( ConvexConnectP IN,
|
||||||
|
|
||||||
uniform float4 vsFarPlane,
|
uniform float4 vsFarPlane,
|
||||||
uniform float3x3 viewToLightProj,
|
uniform float3x3 viewToLightProj,
|
||||||
|
uniform float3x3 dynamicViewToLightProj,
|
||||||
|
|
||||||
uniform float4 lightParams,
|
uniform float4 lightParams,
|
||||||
uniform float shadowSoftness ) : COLOR0
|
uniform float shadowSoftness ) : COLOR0
|
||||||
|
|
@ -178,9 +180,9 @@ float4 main( ConvexConnectP IN,
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
// Static
|
||||||
float2 shadowCoord = decodeShadowCoord( mul( viewToLightProj, -lightVec ) ).xy;
|
float2 shadowCoord = decodeShadowCoord( mul( viewToLightProj, -lightVec ) ).xy;
|
||||||
|
float static_shadowed = softShadow_filter( shadowMap,
|
||||||
float shadowed = softShadow_filter( shadowMap,
|
|
||||||
ssPos.xy,
|
ssPos.xy,
|
||||||
shadowCoord,
|
shadowCoord,
|
||||||
shadowSoftness,
|
shadowSoftness,
|
||||||
|
|
@ -188,17 +190,30 @@ float4 main( ConvexConnectP IN,
|
||||||
nDotL,
|
nDotL,
|
||||||
lightParams.y );
|
lightParams.y );
|
||||||
|
|
||||||
|
// Dynamic
|
||||||
|
float2 dynamicShadowCoord = decodeShadowCoord( mul( dynamicViewToLightProj, -lightVec ) ).xy;
|
||||||
|
float dynamic_shadowed = softShadow_filter( dynamicShadowMap,
|
||||||
|
ssPos.xy,
|
||||||
|
dynamicShadowCoord,
|
||||||
|
shadowSoftness,
|
||||||
|
distToLight,
|
||||||
|
nDotL,
|
||||||
|
lightParams.y );
|
||||||
|
|
||||||
|
float shadowed = min(static_shadowed, dynamic_shadowed);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // !NO_SHADOW
|
#endif // !NO_SHADOW
|
||||||
|
|
||||||
|
float3 lightcol = lightColor.rgb;
|
||||||
#ifdef USE_COOKIE_TEX
|
#ifdef USE_COOKIE_TEX
|
||||||
|
|
||||||
// Lookup the cookie sample.
|
// Lookup the cookie sample.
|
||||||
float4 cookie = texCUBE( cookieMap, mul( viewToLightProj, -lightVec ) );
|
float4 cookie = texCUBE( cookieMap, mul( viewToLightProj, -lightVec ) );
|
||||||
|
|
||||||
// Multiply the light with the cookie tex.
|
// Multiply the light with the cookie tex.
|
||||||
lightColor.rgb *= cookie.rgb;
|
lightcol *= cookie.rgb;
|
||||||
|
|
||||||
// Use a maximum channel luminance to attenuate
|
// Use a maximum channel luminance to attenuate
|
||||||
// the lighting else we get specular in the dark
|
// the lighting else we get specular in the dark
|
||||||
|
|
@ -216,7 +231,7 @@ float4 main( ConvexConnectP IN,
|
||||||
normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
|
normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
|
||||||
|
|
||||||
float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
|
float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
|
||||||
float3 lightColorOut = lightMapParams.rgb * lightColor.rgb;
|
float3 lightColorOut = lightMapParams.rgb * lightcol;
|
||||||
float4 addToResult = 0.0;
|
float4 addToResult = 0.0;
|
||||||
|
|
||||||
// TODO: This needs to be removed when lightmapping is disabled
|
// TODO: This needs to be removed when lightmapping is disabled
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ static float2 sNonUniformTaps[NUM_PRE_TAPS] =
|
||||||
|
|
||||||
/// The texture used to do per-pixel pseudorandom
|
/// The texture used to do per-pixel pseudorandom
|
||||||
/// rotations of the filter taps.
|
/// rotations of the filter taps.
|
||||||
uniform sampler2D gTapRotationTex : register(S3);
|
uniform sampler2D gTapRotationTex : register(S4);
|
||||||
|
|
||||||
|
|
||||||
float softShadow_sampleTaps( sampler2D shadowMap,
|
float softShadow_sampleTaps( sampler2D shadowMap,
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
#include "../../lighting.hlsl"
|
#include "../../lighting.hlsl"
|
||||||
#include "../shadowMap/shadowMapIO_HLSL.h"
|
#include "../shadowMap/shadowMapIO_HLSL.h"
|
||||||
#include "softShadow.hlsl"
|
#include "softShadow.hlsl"
|
||||||
|
#include "../../torque.hlsl"
|
||||||
|
|
||||||
struct ConvexConnectP
|
struct ConvexConnectP
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +39,7 @@ struct ConvexConnectP
|
||||||
#ifdef USE_COOKIE_TEX
|
#ifdef USE_COOKIE_TEX
|
||||||
|
|
||||||
/// The texture for cookie rendering.
|
/// The texture for cookie rendering.
|
||||||
uniform sampler2D cookieMap : register(S2);
|
uniform sampler2D cookieMap : register(S3);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -48,6 +48,7 @@ float4 main( ConvexConnectP IN,
|
||||||
|
|
||||||
uniform sampler2D prePassBuffer : register(S0),
|
uniform sampler2D prePassBuffer : register(S0),
|
||||||
uniform sampler2D shadowMap : register(S1),
|
uniform sampler2D shadowMap : register(S1),
|
||||||
|
uniform sampler2D dynamicShadowMap : register(S2),
|
||||||
|
|
||||||
uniform float4 rtParams0,
|
uniform float4 rtParams0,
|
||||||
|
|
||||||
|
|
@ -62,6 +63,7 @@ float4 main( ConvexConnectP IN,
|
||||||
|
|
||||||
uniform float4 vsFarPlane,
|
uniform float4 vsFarPlane,
|
||||||
uniform float4x4 viewToLightProj,
|
uniform float4x4 viewToLightProj,
|
||||||
|
uniform float4x4 dynamicViewToLightProj,
|
||||||
|
|
||||||
uniform float4 lightParams,
|
uniform float4 lightParams,
|
||||||
uniform float shadowSoftness ) : COLOR0
|
uniform float shadowSoftness ) : COLOR0
|
||||||
|
|
@ -101,6 +103,11 @@ float4 main( ConvexConnectP IN,
|
||||||
float2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 );
|
float2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 );
|
||||||
shadowCoord.y = 1.0f - shadowCoord.y;
|
shadowCoord.y = 1.0f - shadowCoord.y;
|
||||||
|
|
||||||
|
// Get the dynamic shadow texture coordinate
|
||||||
|
float4 dynpxlPosLightProj = mul( dynamicViewToLightProj, float4( viewSpacePos, 1 ) );
|
||||||
|
float2 dynshadowCoord = ( ( dynpxlPosLightProj.xy / dynpxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 );
|
||||||
|
dynshadowCoord.y = 1.0f - dynshadowCoord.y;
|
||||||
|
|
||||||
#ifdef NO_SHADOW
|
#ifdef NO_SHADOW
|
||||||
|
|
||||||
float shadowed = 1.0;
|
float shadowed = 1.0;
|
||||||
|
|
@ -110,7 +117,7 @@ float4 main( ConvexConnectP IN,
|
||||||
// Get a linear depth from the light source.
|
// Get a linear depth from the light source.
|
||||||
float distToLight = pxlPosLightProj.z / lightRange;
|
float distToLight = pxlPosLightProj.z / lightRange;
|
||||||
|
|
||||||
float shadowed = softShadow_filter( shadowMap,
|
float static_shadowed = softShadow_filter( shadowMap,
|
||||||
ssPos.xy,
|
ssPos.xy,
|
||||||
shadowCoord,
|
shadowCoord,
|
||||||
shadowSoftness,
|
shadowSoftness,
|
||||||
|
|
@ -118,15 +125,24 @@ float4 main( ConvexConnectP IN,
|
||||||
nDotL,
|
nDotL,
|
||||||
lightParams.y );
|
lightParams.y );
|
||||||
|
|
||||||
|
float dynamic_shadowed = softShadow_filter( dynamicShadowMap,
|
||||||
|
ssPos.xy,
|
||||||
|
dynshadowCoord,
|
||||||
|
shadowSoftness,
|
||||||
|
distToLight,
|
||||||
|
nDotL,
|
||||||
|
lightParams.y );
|
||||||
|
float shadowed = min(static_shadowed, dynamic_shadowed);
|
||||||
#endif // !NO_SHADOW
|
#endif // !NO_SHADOW
|
||||||
|
|
||||||
|
float3 lightcol = lightColor.rgb;
|
||||||
#ifdef USE_COOKIE_TEX
|
#ifdef USE_COOKIE_TEX
|
||||||
|
|
||||||
// Lookup the cookie sample.
|
// Lookup the cookie sample.
|
||||||
float4 cookie = tex2D( cookieMap, shadowCoord );
|
float4 cookie = tex2D( cookieMap, shadowCoord );
|
||||||
|
|
||||||
// Multiply the light with the cookie tex.
|
// Multiply the light with the cookie tex.
|
||||||
lightColor.rgb *= cookie.rgb;
|
lightcol *= cookie.rgb;
|
||||||
|
|
||||||
// Use a maximum channel luminance to attenuate
|
// Use a maximum channel luminance to attenuate
|
||||||
// the lighting else we get specular in the dark
|
// the lighting else we get specular in the dark
|
||||||
|
|
@ -144,7 +160,7 @@ float4 main( ConvexConnectP IN,
|
||||||
normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
|
normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
|
||||||
|
|
||||||
float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
|
float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
|
||||||
float3 lightColorOut = lightMapParams.rgb * lightColor.rgb;
|
float3 lightColorOut = lightMapParams.rgb * lightcol;
|
||||||
float4 addToResult = 0.0;
|
float4 addToResult = 0.0;
|
||||||
|
|
||||||
// TODO: This needs to be removed when lightmapping is disabled
|
// TODO: This needs to be removed when lightmapping is disabled
|
||||||
|
|
|
||||||
|
|
@ -30,68 +30,31 @@
|
||||||
#include "softShadow.hlsl"
|
#include "softShadow.hlsl"
|
||||||
|
|
||||||
|
|
||||||
uniform sampler2D ShadowMap : register(S1);
|
uniform sampler2D shadowMap : register(S1);
|
||||||
|
uniform sampler2D dynamicShadowMap : register(S2);
|
||||||
|
|
||||||
#ifdef USE_SSAO_MASK
|
#ifdef USE_SSAO_MASK
|
||||||
uniform sampler2D ssaoMask : register(S2);
|
uniform sampler2D ssaoMask : register(S3);
|
||||||
uniform float4 rtParams2;
|
uniform float4 rtParams2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
float4 AL_VectorLightShadowCast( sampler2D sourceShadowMap,
|
||||||
float4 main( FarFrustumQuadConnectP IN,
|
float2 texCoord,
|
||||||
|
float4x4 worldToLightProj,
|
||||||
uniform sampler2D prePassBuffer : register(S0),
|
float4 worldPos,
|
||||||
|
float4 scaleX,
|
||||||
uniform float3 lightDirection,
|
float4 scaleY,
|
||||||
uniform float4 lightColor,
|
float4 offsetX,
|
||||||
uniform float lightBrightness,
|
float4 offsetY,
|
||||||
uniform float4 lightAmbient,
|
float4 farPlaneScalePSSM,
|
||||||
|
float4 atlasXOffset,
|
||||||
uniform float3 eyePosWorld,
|
float4 atlasYOffset,
|
||||||
|
float2 atlasScale,
|
||||||
uniform float4x4 worldToLightProj,
|
float shadowSoftness,
|
||||||
|
float dotNL ,
|
||||||
uniform float4 scaleX,
|
float4 overDarkPSSM
|
||||||
uniform float4 scaleY,
|
)
|
||||||
uniform float4 offsetX,
|
|
||||||
uniform float4 offsetY,
|
|
||||||
uniform float4 atlasXOffset,
|
|
||||||
uniform float4 atlasYOffset,
|
|
||||||
uniform float2 atlasScale,
|
|
||||||
uniform float4 zNearFarInvNearFar,
|
|
||||||
uniform float4 lightMapParams,
|
|
||||||
|
|
||||||
uniform float2 fadeStartLength,
|
|
||||||
uniform float4 farPlaneScalePSSM,
|
|
||||||
uniform float4 overDarkPSSM,
|
|
||||||
uniform float shadowSoftness ) : COLOR0
|
|
||||||
{
|
{
|
||||||
// Sample/unpack the normal/z data
|
|
||||||
float4 prepassSample = prepassUncondition( prePassBuffer, IN.uv0 );
|
|
||||||
float3 normal = prepassSample.rgb;
|
|
||||||
float depth = prepassSample.a;
|
|
||||||
|
|
||||||
// Use eye ray to get ws pos
|
|
||||||
float4 worldPos = float4(eyePosWorld + IN.wsEyeRay * depth, 1.0f);
|
|
||||||
|
|
||||||
// Get the light attenuation.
|
|
||||||
float dotNL = dot(-lightDirection, normal);
|
|
||||||
|
|
||||||
#ifdef PSSM_DEBUG_RENDER
|
|
||||||
float3 debugColor = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NO_SHADOW
|
|
||||||
|
|
||||||
// Fully unshadowed.
|
|
||||||
float shadowed = 1.0;
|
|
||||||
|
|
||||||
#ifdef PSSM_DEBUG_RENDER
|
|
||||||
debugColor = 1.0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// Compute shadow map coordinate
|
// Compute shadow map coordinate
|
||||||
float4 pxlPosLightProj = mul(worldToLightProj, worldPos);
|
float4 pxlPosLightProj = mul(worldToLightProj, worldPos);
|
||||||
float2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
|
float2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
|
||||||
|
|
@ -132,6 +95,11 @@ float4 main( FarFrustumQuadConnectP IN,
|
||||||
else
|
else
|
||||||
finalMask = float4(0, 0, 0, 1);
|
finalMask = float4(0, 0, 0, 1);
|
||||||
|
|
||||||
|
float3 debugColor = float3(0,0,0);
|
||||||
|
|
||||||
|
#ifdef NO_SHADOW
|
||||||
|
debugColor = float3(1.0,1.0,1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PSSM_DEBUG_RENDER
|
#ifdef PSSM_DEBUG_RENDER
|
||||||
if ( finalMask.x > 0 )
|
if ( finalMask.x > 0 )
|
||||||
|
|
@ -175,18 +143,124 @@ float4 main( FarFrustumQuadConnectP IN,
|
||||||
float farPlaneScale = dot( farPlaneScalePSSM, finalMask );
|
float farPlaneScale = dot( farPlaneScalePSSM, finalMask );
|
||||||
distToLight *= farPlaneScale;
|
distToLight *= farPlaneScale;
|
||||||
|
|
||||||
float shadowed = softShadow_filter( ShadowMap,
|
return float4(debugColor,
|
||||||
IN.uv0.xy,
|
softShadow_filter( sourceShadowMap,
|
||||||
|
texCoord,
|
||||||
shadowCoord,
|
shadowCoord,
|
||||||
farPlaneScale * shadowSoftness,
|
farPlaneScale * shadowSoftness,
|
||||||
distToLight,
|
distToLight,
|
||||||
dotNL,
|
dotNL,
|
||||||
dot( finalMask, overDarkPSSM ) );
|
dot( finalMask, overDarkPSSM ) ) );
|
||||||
|
};
|
||||||
|
|
||||||
|
float4 main( FarFrustumQuadConnectP IN,
|
||||||
|
|
||||||
|
uniform sampler2D prePassBuffer : register(S0),
|
||||||
|
|
||||||
|
uniform float3 lightDirection,
|
||||||
|
uniform float4 lightColor,
|
||||||
|
uniform float lightBrightness,
|
||||||
|
uniform float4 lightAmbient,
|
||||||
|
uniform float4x4 eyeMat,
|
||||||
|
|
||||||
|
uniform float3 eyePosWorld,
|
||||||
|
uniform float4 atlasXOffset,
|
||||||
|
uniform float4 atlasYOffset,
|
||||||
|
uniform float2 atlasScale,
|
||||||
|
uniform float4 zNearFarInvNearFar,
|
||||||
|
uniform float4 lightMapParams,
|
||||||
|
uniform float2 fadeStartLength,
|
||||||
|
uniform float4 overDarkPSSM,
|
||||||
|
uniform float shadowSoftness,
|
||||||
|
|
||||||
|
// Static Shadows
|
||||||
|
uniform float4x4 worldToLightProj,
|
||||||
|
uniform float4 scaleX,
|
||||||
|
uniform float4 scaleY,
|
||||||
|
uniform float4 offsetX,
|
||||||
|
uniform float4 offsetY,
|
||||||
|
uniform float4 farPlaneScalePSSM,
|
||||||
|
|
||||||
|
// Dynamic Shadows
|
||||||
|
uniform float4x4 dynamicWorldToLightProj,
|
||||||
|
uniform float4 dynamicScaleX,
|
||||||
|
uniform float4 dynamicScaleY,
|
||||||
|
uniform float4 dynamicOffsetX,
|
||||||
|
uniform float4 dynamicOffsetY,
|
||||||
|
uniform float4 dynamicFarPlaneScalePSSM
|
||||||
|
|
||||||
|
) : COLOR0
|
||||||
|
{
|
||||||
|
// Sample/unpack the normal/z data
|
||||||
|
float4 prepassSample = prepassUncondition( prePassBuffer, IN.uv0 );
|
||||||
|
float3 normal = prepassSample.rgb;
|
||||||
|
float depth = prepassSample.a;
|
||||||
|
|
||||||
|
// Use eye ray to get ws pos
|
||||||
|
float4 worldPos = float4(eyePosWorld + IN.wsEyeRay * depth, 1.0f);
|
||||||
|
|
||||||
|
// Get the light attenuation.
|
||||||
|
float dotNL = dot(-lightDirection, normal);
|
||||||
|
|
||||||
|
#ifdef PSSM_DEBUG_RENDER
|
||||||
|
float3 debugColor = float3(0,0,0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NO_SHADOW
|
||||||
|
|
||||||
|
// Fully unshadowed.
|
||||||
|
float shadowed = 1.0;
|
||||||
|
|
||||||
|
#ifdef PSSM_DEBUG_RENDER
|
||||||
|
debugColor = float3(1.0,1.0,1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
float4 static_shadowed_colors = AL_VectorLightShadowCast( shadowMap,
|
||||||
|
IN.uv0.xy,
|
||||||
|
worldToLightProj,
|
||||||
|
worldPos,
|
||||||
|
scaleX, scaleY,
|
||||||
|
offsetX, offsetY,
|
||||||
|
farPlaneScalePSSM,
|
||||||
|
atlasXOffset, atlasYOffset,
|
||||||
|
atlasScale,
|
||||||
|
shadowSoftness,
|
||||||
|
dotNL,
|
||||||
|
overDarkPSSM);
|
||||||
|
|
||||||
|
float4 dynamic_shadowed_colors = AL_VectorLightShadowCast( dynamicShadowMap,
|
||||||
|
IN.uv0.xy,
|
||||||
|
dynamicWorldToLightProj,
|
||||||
|
worldPos,
|
||||||
|
dynamicScaleX, dynamicScaleY,
|
||||||
|
dynamicOffsetX, dynamicOffsetY,
|
||||||
|
dynamicFarPlaneScalePSSM,
|
||||||
|
atlasXOffset, atlasYOffset,
|
||||||
|
atlasScale,
|
||||||
|
shadowSoftness,
|
||||||
|
dotNL,
|
||||||
|
overDarkPSSM);
|
||||||
|
|
||||||
|
float static_shadowed = static_shadowed_colors.a;
|
||||||
|
float dynamic_shadowed = dynamic_shadowed_colors.a;
|
||||||
|
|
||||||
|
#ifdef PSSM_DEBUG_RENDER
|
||||||
|
debugColor = static_shadowed_colors.rgb*0.5+dynamic_shadowed_colors.rgb*0.5;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Fade out the shadow at the end of the range.
|
// Fade out the shadow at the end of the range.
|
||||||
float4 zDist = (zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth);
|
float4 zDist = (zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth);
|
||||||
float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y;
|
float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y;
|
||||||
shadowed = lerp( shadowed, 1.0, saturate( fadeOutAmt ) );
|
|
||||||
|
static_shadowed = lerp( static_shadowed, 1.0, saturate( fadeOutAmt ) );
|
||||||
|
dynamic_shadowed = lerp( dynamic_shadowed, 1.0, saturate( fadeOutAmt ) );
|
||||||
|
|
||||||
|
// temp for debugging. uncomment one or the other.
|
||||||
|
//float shadowed = static_shadowed;
|
||||||
|
//float shadowed = dynamic_shadowed;
|
||||||
|
float shadowed = min(static_shadowed, dynamic_shadowed);
|
||||||
|
|
||||||
#ifdef PSSM_DEBUG_RENDER
|
#ifdef PSSM_DEBUG_RENDER
|
||||||
if ( fadeOutAmt > 1.0 )
|
if ( fadeOutAmt > 1.0 )
|
||||||
|
|
|
||||||
|
|
@ -3309,7 +3309,7 @@
|
||||||
HorizSizing = "width";
|
HorizSizing = "width";
|
||||||
VertSizing = "bottom";
|
VertSizing = "bottom";
|
||||||
Position = "0 0";
|
Position = "0 0";
|
||||||
Extent = "210 71";
|
Extent = "210 89";
|
||||||
|
|
||||||
new GuiPopUpMenuCtrl() {
|
new GuiPopUpMenuCtrl() {
|
||||||
internalName = "blendingTypePopUp";
|
internalName = "blendingTypePopUp";
|
||||||
|
|
@ -3480,7 +3480,7 @@
|
||||||
Visible = "1";
|
Visible = "1";
|
||||||
Command = "MaterialEditorGui.updateActiveMaterial(\"castShadows\", $ThisControl.getValue());";
|
Command = "MaterialEditorGui.updateActiveMaterial(\"castShadows\", $ThisControl.getValue());";
|
||||||
tooltipprofile = "ToolsGuiDefaultProfile";
|
tooltipprofile = "ToolsGuiDefaultProfile";
|
||||||
ToolTip = "Alows object to cast shadows.";
|
ToolTip = "Object casts shadows.";
|
||||||
hovertime = "1000";
|
hovertime = "1000";
|
||||||
text = "Cast Shadows";
|
text = "Cast Shadows";
|
||||||
groupNum = "-1";
|
groupNum = "-1";
|
||||||
|
|
@ -3488,6 +3488,29 @@
|
||||||
useMouseEvents = "0";
|
useMouseEvents = "0";
|
||||||
useInactiveState = "0";
|
useInactiveState = "0";
|
||||||
};
|
};
|
||||||
|
new GuiCheckBoxCtrl() {
|
||||||
|
canSaveDynamicFields = "0";
|
||||||
|
internalName = "castDynamicShadows";
|
||||||
|
Enabled = "1";
|
||||||
|
isContainer = "0";
|
||||||
|
Profile = "ToolsGuiCheckBoxProfile";
|
||||||
|
HorizSizing = "right";
|
||||||
|
VertSizing = "bottom";
|
||||||
|
position = "3 70";
|
||||||
|
Extent = "112 16";
|
||||||
|
MinExtent = "8 2";
|
||||||
|
canSave = "1";
|
||||||
|
Visible = "1";
|
||||||
|
Command = "MaterialEditorGui.updateActiveMaterial(\"castDynamicShadows\", $ThisControl.getValue());";
|
||||||
|
tooltipprofile = "ToolsGuiDefaultProfile";
|
||||||
|
ToolTip = "Object casts dynamic shadows.";
|
||||||
|
hovertime = "1000";
|
||||||
|
text = "Dynamic Shadows";
|
||||||
|
groupNum = "-1";
|
||||||
|
buttonType = "ToggleButton";
|
||||||
|
useMouseEvents = "0";
|
||||||
|
useInactiveState = "0";
|
||||||
|
};
|
||||||
new GuiCheckBoxCtrl() {
|
new GuiCheckBoxCtrl() {
|
||||||
canSaveDynamicFields = "0";
|
canSaveDynamicFields = "0";
|
||||||
internalName = "doubleSidedCheckBox";
|
internalName = "doubleSidedCheckBox";
|
||||||
|
|
|
||||||
|
|
@ -754,6 +754,7 @@ function MaterialEditorGui::guiSync( %this, %material )
|
||||||
MaterialEditorPropertiesWindow-->transZWriteCheckBox.setValue((%material).translucentZWrite);
|
MaterialEditorPropertiesWindow-->transZWriteCheckBox.setValue((%material).translucentZWrite);
|
||||||
MaterialEditorPropertiesWindow-->alphaTestCheckBox.setValue((%material).alphaTest);
|
MaterialEditorPropertiesWindow-->alphaTestCheckBox.setValue((%material).alphaTest);
|
||||||
MaterialEditorPropertiesWindow-->castShadows.setValue((%material).castShadows);
|
MaterialEditorPropertiesWindow-->castShadows.setValue((%material).castShadows);
|
||||||
|
MaterialEditorPropertiesWindow-->castDynamicShadows.setValue((%material).castDynamicShadows);
|
||||||
MaterialEditorPropertiesWindow-->translucentCheckbox.setValue((%material).translucent);
|
MaterialEditorPropertiesWindow-->translucentCheckbox.setValue((%material).translucent);
|
||||||
|
|
||||||
switch$((%material).translucentBlendOp)
|
switch$((%material).translucentBlendOp)
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ singleton Material(Cheetah_Main)
|
||||||
translucentBlendOp = "None";
|
translucentBlendOp = "None";
|
||||||
normalMap[0] = "art/shapes/Cheetah/Cheetah_N";
|
normalMap[0] = "art/shapes/Cheetah/Cheetah_N";
|
||||||
specularMap[0] = "art/shapes/Cheetah/Cheetah_S";
|
specularMap[0] = "art/shapes/Cheetah/Cheetah_S";
|
||||||
|
castDynamicShadows = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
singleton Material(Cheetah_TailLights)
|
singleton Material(Cheetah_TailLights)
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ singleton Material(Mat_Soldier_Main)
|
||||||
doubleSided = false;
|
doubleSided = false;
|
||||||
translucent = false;
|
translucent = false;
|
||||||
showFootprints = "0";
|
showFootprints = "0";
|
||||||
|
castDynamicShadows = true;
|
||||||
materialTag0 = "Player";
|
materialTag0 = "Player";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -55,6 +56,7 @@ singleton Material(Mat_Soldier_Dazzle)
|
||||||
emissive[0] = "1";
|
emissive[0] = "1";
|
||||||
castShadows = "0";
|
castShadows = "0";
|
||||||
showFootprints = "0";
|
showFootprints = "0";
|
||||||
|
castDynamicShadows = true;
|
||||||
materialTag0 = "Player";
|
materialTag0 = "Player";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ singleton Material(grenade_grenade)
|
||||||
doubleSided = false;
|
doubleSided = false;
|
||||||
translucent = false;
|
translucent = false;
|
||||||
translucentBlendOp = "None";
|
translucentBlendOp = "None";
|
||||||
|
castDynamicShadows = true;
|
||||||
materialTag0 = "Weapon";
|
materialTag0 = "Weapon";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ singleton Material(Lurker_Base)
|
||||||
specularPower[0] = "10";
|
specularPower[0] = "10";
|
||||||
translucentBlendOp = "None";
|
translucentBlendOp = "None";
|
||||||
useAnisotropic[0] = "1";
|
useAnisotropic[0] = "1";
|
||||||
|
castDynamicShadows = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
singleton Material(Lurker_MuzzleFlash_Base)
|
singleton Material(Lurker_MuzzleFlash_Base)
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ singleton Material(ProxMine_Base)
|
||||||
pixelSpecular[0] = "1";
|
pixelSpecular[0] = "1";
|
||||||
specularMap[0] = "ProxMine_S.dds";
|
specularMap[0] = "ProxMine_S.dds";
|
||||||
useAnisotropic[0] = "1";
|
useAnisotropic[0] = "1";
|
||||||
|
castDynamicShadows = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
singleton Material(ProxMine_Glow_Base)
|
singleton Material(ProxMine_Glow_Base)
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ singleton Material(FP_Ryder_Base)
|
||||||
translucentBlendOp = "None";
|
translucentBlendOp = "None";
|
||||||
pixelSpecular[0] = "1";
|
pixelSpecular[0] = "1";
|
||||||
useAnisotropic[0] = "1";
|
useAnisotropic[0] = "1";
|
||||||
|
castDynamicShadows = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
singleton Material(TP_Ryder_Base)
|
singleton Material(TP_Ryder_Base)
|
||||||
|
|
@ -43,6 +44,7 @@ singleton Material(TP_Ryder_Base)
|
||||||
specularPower[0] = "10";
|
specularPower[0] = "10";
|
||||||
translucentBlendOp = "None";
|
translucentBlendOp = "None";
|
||||||
pixelSpecular[0] = "1";
|
pixelSpecular[0] = "1";
|
||||||
|
castDynamicShadows = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
singleton Material(Ryder_MuzzleFlash_Base)
|
singleton Material(Ryder_MuzzleFlash_Base)
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ singleton Material(Turret_Base)
|
||||||
pixelSpecular[0] = "1";
|
pixelSpecular[0] = "1";
|
||||||
specularMap[0] = "art/shapes/weapons/Turret/Turret_D.dds";
|
specularMap[0] = "art/shapes/weapons/Turret/Turret_D.dds";
|
||||||
useAnisotropic[0] = "1";
|
useAnisotropic[0] = "1";
|
||||||
|
castDynamicShadows = true;
|
||||||
materialTag0 = "Weapon";
|
materialTag0 = "Weapon";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -53,6 +54,7 @@ singleton Material(Turret_Lazer_Base)
|
||||||
waveFreq[0] = "0";
|
waveFreq[0] = "0";
|
||||||
waveAmp[0] = "0";
|
waveAmp[0] = "0";
|
||||||
castShadows = "1";
|
castShadows = "1";
|
||||||
|
castDynamicShadows = true;
|
||||||
translucentZWrite = "0";
|
translucentZWrite = "0";
|
||||||
materialTag0 = "Weapon";
|
materialTag0 = "Weapon";
|
||||||
materialTag1 = "FX";
|
materialTag1 = "FX";
|
||||||
|
|
@ -68,6 +70,7 @@ singleton Material(Turret_Lazer_Base)
|
||||||
glow[0] = "1";
|
glow[0] = "1";
|
||||||
emissive[0] = "1";
|
emissive[0] = "1";
|
||||||
translucentBlendOp = "Add";
|
translucentBlendOp = "Add";
|
||||||
|
castDynamicShadows = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
singleton Material(CollisionMat)
|
singleton Material(CollisionMat)
|
||||||
|
|
|
||||||
|
|
@ -62,9 +62,10 @@ new ShaderData( AL_VectorLightShader )
|
||||||
OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/vectorLightP.glsl";
|
OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/vectorLightP.glsl";
|
||||||
|
|
||||||
samplerNames[0] = "$prePassBuffer";
|
samplerNames[0] = "$prePassBuffer";
|
||||||
samplerNames[1] = "$ShadowMap";
|
samplerNames[1] = "$shadowMap";
|
||||||
samplerNames[2] = "$ssaoMask";
|
samplerNames[2] = "$dynamicShadowMap";
|
||||||
samplerNames[3] = "$gTapRotationTex";
|
samplerNames[3] = "$ssaoMask";
|
||||||
|
samplerNames[4] = "$gTapRotationTex";
|
||||||
|
|
||||||
pixVersion = 3.0;
|
pixVersion = 3.0;
|
||||||
};
|
};
|
||||||
|
|
@ -75,7 +76,8 @@ new CustomMaterial( AL_VectorLightMaterial )
|
||||||
stateBlock = AL_VectorLightState;
|
stateBlock = AL_VectorLightState;
|
||||||
|
|
||||||
sampler["prePassBuffer"] = "#prepass";
|
sampler["prePassBuffer"] = "#prepass";
|
||||||
sampler["ShadowMap"] = "$dynamiclight";
|
sampler["shadowMap"] = "$dynamiclight";
|
||||||
|
sampler["dynamicShadowMap"] = "$dynamicShadowMap";
|
||||||
sampler["ssaoMask"] = "#ssaoMask";
|
sampler["ssaoMask"] = "#ssaoMask";
|
||||||
|
|
||||||
target = "lightinfo";
|
target = "lightinfo";
|
||||||
|
|
@ -128,8 +130,9 @@ new ShaderData( AL_PointLightShader )
|
||||||
|
|
||||||
samplerNames[0] = "$prePassBuffer";
|
samplerNames[0] = "$prePassBuffer";
|
||||||
samplerNames[1] = "$shadowMap";
|
samplerNames[1] = "$shadowMap";
|
||||||
samplerNames[2] = "$cookieMap";
|
samplerNames[2] = "$dynamicShadowMap";
|
||||||
samplerNames[3] = "$gTapRotationTex";
|
samplerNames[3] = "$cookieMap";
|
||||||
|
samplerNames[4] = "$gTapRotationTex";
|
||||||
|
|
||||||
pixVersion = 3.0;
|
pixVersion = 3.0;
|
||||||
};
|
};
|
||||||
|
|
@ -141,6 +144,7 @@ new CustomMaterial( AL_PointLightMaterial )
|
||||||
|
|
||||||
sampler["prePassBuffer"] = "#prepass";
|
sampler["prePassBuffer"] = "#prepass";
|
||||||
sampler["shadowMap"] = "$dynamiclight";
|
sampler["shadowMap"] = "$dynamiclight";
|
||||||
|
sampler["dynamicShadowMap"] = "$dynamicShadowMap";
|
||||||
sampler["cookieMap"] = "$dynamiclightmask";
|
sampler["cookieMap"] = "$dynamiclightmask";
|
||||||
|
|
||||||
target = "lightinfo";
|
target = "lightinfo";
|
||||||
|
|
@ -159,8 +163,9 @@ new ShaderData( AL_SpotLightShader )
|
||||||
|
|
||||||
samplerNames[0] = "$prePassBuffer";
|
samplerNames[0] = "$prePassBuffer";
|
||||||
samplerNames[1] = "$shadowMap";
|
samplerNames[1] = "$shadowMap";
|
||||||
samplerNames[2] = "$cookieMap";
|
samplerNames[2] = "$dynamicShadowMap";
|
||||||
samplerNames[3] = "$gTapRotationTex";
|
samplerNames[3] = "$cookieMap";
|
||||||
|
samplerNames[4] = "$gTapRotationTex";
|
||||||
|
|
||||||
pixVersion = 3.0;
|
pixVersion = 3.0;
|
||||||
};
|
};
|
||||||
|
|
@ -172,6 +177,7 @@ new CustomMaterial( AL_SpotLightMaterial )
|
||||||
|
|
||||||
sampler["prePassBuffer"] = "#prepass";
|
sampler["prePassBuffer"] = "#prepass";
|
||||||
sampler["shadowMap"] = "$dynamiclight";
|
sampler["shadowMap"] = "$dynamiclight";
|
||||||
|
sampler["dynamicShadowMap"] = "$dynamicShadowMap";
|
||||||
sampler["cookieMap"] = "$dynamiclightmask";
|
sampler["cookieMap"] = "$dynamiclightmask";
|
||||||
|
|
||||||
target = "lightinfo";
|
target = "lightinfo";
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
#include "../../../gl/lighting.glsl"
|
#include "../../../gl/lighting.glsl"
|
||||||
#include "../../shadowMap/shadowMapIO_GLSL.h"
|
#include "../../shadowMap/shadowMapIO_GLSL.h"
|
||||||
#include "softShadow.glsl"
|
#include "softShadow.glsl"
|
||||||
|
#include "../../../gl/torque.glsl"
|
||||||
|
|
||||||
in vec4 wsEyeDir;
|
in vec4 wsEyeDir;
|
||||||
in vec4 ssPos;
|
in vec4 ssPos;
|
||||||
|
|
@ -107,6 +108,7 @@ uniform sampler2D prePassBuffer;
|
||||||
uniform samplerCube shadowMap;
|
uniform samplerCube shadowMap;
|
||||||
#else
|
#else
|
||||||
uniform sampler2D shadowMap;
|
uniform sampler2D shadowMap;
|
||||||
|
uniform sampler2D dynamicShadowMap;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uniform vec4 rtParams0;
|
uniform vec4 rtParams0;
|
||||||
|
|
@ -119,6 +121,7 @@ uniform vec2 lightAttenuation;
|
||||||
uniform vec4 lightMapParams;
|
uniform vec4 lightMapParams;
|
||||||
uniform vec4 vsFarPlane;
|
uniform vec4 vsFarPlane;
|
||||||
uniform mat3 viewToLightProj;
|
uniform mat3 viewToLightProj;
|
||||||
|
uniform mat3 dynamicViewToLightProj;
|
||||||
uniform vec4 lightParams;
|
uniform vec4 lightParams;
|
||||||
uniform float shadowSoftness;
|
uniform float shadowSoftness;
|
||||||
|
|
||||||
|
|
@ -175,7 +178,7 @@ void main()
|
||||||
|
|
||||||
vec2 shadowCoord = decodeShadowCoord( tMul( viewToLightProj, -lightVec ) ).xy;
|
vec2 shadowCoord = decodeShadowCoord( tMul( viewToLightProj, -lightVec ) ).xy;
|
||||||
|
|
||||||
float shadowed = softShadow_filter( shadowMap,
|
float static_shadowed = softShadow_filter( shadowMap,
|
||||||
ssPos.xy,
|
ssPos.xy,
|
||||||
shadowCoord,
|
shadowCoord,
|
||||||
shadowSoftness,
|
shadowSoftness,
|
||||||
|
|
@ -183,6 +186,16 @@ void main()
|
||||||
nDotL,
|
nDotL,
|
||||||
lightParams.y );
|
lightParams.y );
|
||||||
|
|
||||||
|
vec2 dynamicShadowCoord = decodeShadowCoord( tMul( dynamicViewToLightProj, -lightVec ) ).xy;
|
||||||
|
float dynamic_shadowed = softShadow_filter( dynamicShadowMap,
|
||||||
|
ssPos.xy,
|
||||||
|
dynamicShadowCoord,
|
||||||
|
shadowSoftness,
|
||||||
|
distToLight,
|
||||||
|
nDotL,
|
||||||
|
lightParams.y );
|
||||||
|
|
||||||
|
float shadowed = min(static_shadowed, dynamic_shadowed);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // !NO_SHADOW
|
#endif // !NO_SHADOW
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include "shadergen:/autogenConditioners.h"
|
#include "shadergen:/autogenConditioners.h"
|
||||||
#include "softShadow.glsl"
|
#include "softShadow.glsl"
|
||||||
#include "../../../gl/lighting.glsl"
|
#include "../../../gl/lighting.glsl"
|
||||||
|
#include "../../../gl/torque.glsl"
|
||||||
|
|
||||||
in vec4 wsEyeDir;
|
in vec4 wsEyeDir;
|
||||||
in vec4 ssPos;
|
in vec4 ssPos;
|
||||||
|
|
@ -45,6 +46,7 @@ uniform sampler2D cookieMap;
|
||||||
|
|
||||||
uniform sampler2D prePassBuffer;
|
uniform sampler2D prePassBuffer;
|
||||||
uniform sampler2D shadowMap;
|
uniform sampler2D shadowMap;
|
||||||
|
uniform sampler2D dynamicShadowMap;
|
||||||
|
|
||||||
uniform vec4 rtParams0;
|
uniform vec4 rtParams0;
|
||||||
|
|
||||||
|
|
@ -59,6 +61,7 @@ uniform vec4 lightMapParams;
|
||||||
|
|
||||||
uniform vec4 vsFarPlane;
|
uniform vec4 vsFarPlane;
|
||||||
uniform mat4 viewToLightProj;
|
uniform mat4 viewToLightProj;
|
||||||
|
uniform mat4 dynamicViewToLightProj;
|
||||||
|
|
||||||
uniform vec4 lightParams;
|
uniform vec4 lightParams;
|
||||||
uniform float shadowSoftness;
|
uniform float shadowSoftness;
|
||||||
|
|
@ -102,6 +105,10 @@ void main()
|
||||||
vec2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 );
|
vec2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 );
|
||||||
shadowCoord.y = 1.0f - shadowCoord.y;
|
shadowCoord.y = 1.0f - shadowCoord.y;
|
||||||
|
|
||||||
|
// Get the dynamic shadow texture coordinate
|
||||||
|
vec4 dynpxlPosLightProj = tMul( dynamicViewToLightProj, vec4( viewSpacePos, 1 ) );
|
||||||
|
vec2 dynshadowCoord = ( ( dynpxlPosLightProj.xy / dynpxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 );
|
||||||
|
dynshadowCoord.y = 1.0f - dynshadowCoord.y;
|
||||||
#ifdef NO_SHADOW
|
#ifdef NO_SHADOW
|
||||||
|
|
||||||
float shadowed = 1.0;
|
float shadowed = 1.0;
|
||||||
|
|
@ -111,7 +118,7 @@ void main()
|
||||||
// Get a linear depth from the light source.
|
// Get a linear depth from the light source.
|
||||||
float distToLight = pxlPosLightProj.z / lightRange;
|
float distToLight = pxlPosLightProj.z / lightRange;
|
||||||
|
|
||||||
float shadowed = softShadow_filter( shadowMap,
|
float static_shadowed = softShadow_filter( shadowMap,
|
||||||
ssPos.xy,
|
ssPos.xy,
|
||||||
shadowCoord,
|
shadowCoord,
|
||||||
shadowSoftness,
|
shadowSoftness,
|
||||||
|
|
@ -119,6 +126,14 @@ void main()
|
||||||
nDotL,
|
nDotL,
|
||||||
lightParams.y );
|
lightParams.y );
|
||||||
|
|
||||||
|
float dynamic_shadowed = softShadow_filter( dynamicShadowMap,
|
||||||
|
ssPos.xy,
|
||||||
|
dynshadowCoord,
|
||||||
|
shadowSoftness,
|
||||||
|
distToLight,
|
||||||
|
nDotL,
|
||||||
|
lightParams.y );
|
||||||
|
float shadowed = min(static_shadowed, dynamic_shadowed);
|
||||||
#endif // !NO_SHADOW
|
#endif // !NO_SHADOW
|
||||||
|
|
||||||
vec3 lightcol = lightColor.rgb;
|
vec3 lightcol = lightColor.rgb;
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,8 @@ in vec2 uv0;
|
||||||
in vec3 wsEyeRay;
|
in vec3 wsEyeRay;
|
||||||
in vec3 vsEyeRay;
|
in vec3 vsEyeRay;
|
||||||
|
|
||||||
uniform sampler2D ShadowMap ;
|
uniform sampler2D shadowMap;
|
||||||
|
uniform sampler2D dynamicShadowMap;
|
||||||
|
|
||||||
#ifdef USE_SSAO_MASK
|
#ifdef USE_SSAO_MASK
|
||||||
uniform sampler2D ssaoMask ;
|
uniform sampler2D ssaoMask ;
|
||||||
|
|
@ -47,23 +48,146 @@ uniform vec4 lightColor;
|
||||||
uniform float lightBrightness;
|
uniform float lightBrightness;
|
||||||
uniform vec4 lightAmbient;
|
uniform vec4 lightAmbient;
|
||||||
uniform vec3 eyePosWorld;
|
uniform vec3 eyePosWorld;
|
||||||
uniform mat4x4 worldToLightProj;
|
uniform mat4x4 eyeMat;
|
||||||
uniform vec4 scaleX;
|
|
||||||
uniform vec4 scaleY;
|
|
||||||
uniform vec4 offsetX;
|
|
||||||
uniform vec4 offsetY;
|
|
||||||
uniform vec4 atlasXOffset;
|
uniform vec4 atlasXOffset;
|
||||||
uniform vec4 atlasYOffset;
|
uniform vec4 atlasYOffset;
|
||||||
uniform vec2 atlasScale;
|
uniform vec2 atlasScale;
|
||||||
uniform vec4 zNearFarInvNearFar;
|
uniform vec4 zNearFarInvNearFar;
|
||||||
uniform vec4 lightMapParams;
|
uniform vec4 lightMapParams;
|
||||||
uniform vec2 fadeStartLength;
|
uniform vec2 fadeStartLength;
|
||||||
uniform vec4 farPlaneScalePSSM;
|
|
||||||
uniform vec4 overDarkPSSM;
|
uniform vec4 overDarkPSSM;
|
||||||
uniform float shadowSoftness;
|
uniform float shadowSoftness;
|
||||||
|
|
||||||
out vec4 OUT_col;
|
//static shadowMap
|
||||||
|
uniform mat4x4 worldToLightProj;
|
||||||
|
uniform vec4 scaleX;
|
||||||
|
uniform vec4 scaleY;
|
||||||
|
uniform vec4 offsetX;
|
||||||
|
uniform vec4 offsetY;
|
||||||
|
uniform vec4 farPlaneScalePSSM;
|
||||||
|
|
||||||
|
//dynamic shadowMap
|
||||||
|
uniform mat4x4 dynamicWorldToLightProj;
|
||||||
|
uniform vec4 dynamicScaleX;
|
||||||
|
uniform vec4 dynamicScaleY;
|
||||||
|
uniform vec4 dynamicOffsetX;
|
||||||
|
uniform vec4 dynamicOffsetY;
|
||||||
|
uniform vec4 dynamicFarPlaneScalePSSM;
|
||||||
|
|
||||||
|
vec4 AL_VectorLightShadowCast( sampler2D _sourceshadowMap,
|
||||||
|
vec2 _texCoord,
|
||||||
|
mat4 _worldToLightProj,
|
||||||
|
vec4 _worldPos,
|
||||||
|
vec4 _scaleX, vec4 _scaleY,
|
||||||
|
vec4 _offsetX, vec4 _offsetY,
|
||||||
|
vec4 _farPlaneScalePSSM,
|
||||||
|
vec4 _atlasXOffset, vec4 _atlasYOffset,
|
||||||
|
vec2 _atlasScale,
|
||||||
|
float _shadowSoftness,
|
||||||
|
float _dotNL ,
|
||||||
|
vec4 _overDarkPSSM
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Compute shadow map coordinate
|
||||||
|
vec4 pxlPosLightProj = tMul(_worldToLightProj, _worldPos);
|
||||||
|
vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
|
||||||
|
|
||||||
|
// Distance to light, in shadowMap space
|
||||||
|
float distToLight = pxlPosLightProj.z / pxlPosLightProj.w;
|
||||||
|
|
||||||
|
// Figure out which split to sample from. Basically, we compute the shadowMap sample coord
|
||||||
|
// for all of the splits and then check if its valid.
|
||||||
|
vec4 shadowCoordX = vec4( baseShadowCoord.x );
|
||||||
|
vec4 shadowCoordY = vec4( baseShadowCoord.y );
|
||||||
|
vec4 farPlaneDists = vec4( distToLight );
|
||||||
|
shadowCoordX *= _scaleX;
|
||||||
|
shadowCoordY *= _scaleY;
|
||||||
|
shadowCoordX += _offsetX;
|
||||||
|
shadowCoordY += _offsetY;
|
||||||
|
farPlaneDists *= _farPlaneScalePSSM;
|
||||||
|
|
||||||
|
// If the shadow sample is within -1..1 and the distance
|
||||||
|
// to the light for this pixel is less than the far plane
|
||||||
|
// of the split, use it.
|
||||||
|
vec4 finalMask;
|
||||||
|
if ( shadowCoordX.x > -0.99 && shadowCoordX.x < 0.99 &&
|
||||||
|
shadowCoordY.x > -0.99 && shadowCoordY.x < 0.99 &&
|
||||||
|
farPlaneDists.x < 1.0 )
|
||||||
|
finalMask = vec4(1, 0, 0, 0);
|
||||||
|
|
||||||
|
else if ( shadowCoordX.y > -0.99 && shadowCoordX.y < 0.99 &&
|
||||||
|
shadowCoordY.y > -0.99 && shadowCoordY.y < 0.99 &&
|
||||||
|
farPlaneDists.y < 1.0 )
|
||||||
|
finalMask = vec4(0, 1, 0, 0);
|
||||||
|
|
||||||
|
else if ( shadowCoordX.z > -0.99 && shadowCoordX.z < 0.99 &&
|
||||||
|
shadowCoordY.z > -0.99 && shadowCoordY.z < 0.99 &&
|
||||||
|
farPlaneDists.z < 1.0 )
|
||||||
|
finalMask = vec4(0, 0, 1, 0);
|
||||||
|
|
||||||
|
else
|
||||||
|
finalMask = vec4(0, 0, 0, 1);
|
||||||
|
|
||||||
|
vec3 debugColor = vec3(0);
|
||||||
|
|
||||||
|
#ifdef NO_SHADOW
|
||||||
|
debugColor = vec3(1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PSSM_DEBUG_RENDER
|
||||||
|
if ( finalMask.x > 0 )
|
||||||
|
debugColor += vec3( 1, 0, 0 );
|
||||||
|
else if ( finalMask.y > 0 )
|
||||||
|
debugColor += vec3( 0, 1, 0 );
|
||||||
|
else if ( finalMask.z > 0 )
|
||||||
|
debugColor += vec3( 0, 0, 1 );
|
||||||
|
else if ( finalMask.w > 0 )
|
||||||
|
debugColor += vec3( 1, 1, 0 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Here we know what split we're sampling from, so recompute the _texCoord location
|
||||||
|
// Yes, we could just use the result from above, but doing it this way actually saves
|
||||||
|
// shader instructions.
|
||||||
|
vec2 finalScale;
|
||||||
|
finalScale.x = dot(finalMask, _scaleX);
|
||||||
|
finalScale.y = dot(finalMask, _scaleY);
|
||||||
|
|
||||||
|
vec2 finalOffset;
|
||||||
|
finalOffset.x = dot(finalMask, _offsetX);
|
||||||
|
finalOffset.y = dot(finalMask, _offsetY);
|
||||||
|
|
||||||
|
vec2 shadowCoord;
|
||||||
|
shadowCoord = baseShadowCoord * finalScale;
|
||||||
|
shadowCoord += finalOffset;
|
||||||
|
|
||||||
|
// Convert to _texCoord space
|
||||||
|
shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5);
|
||||||
|
shadowCoord.y = 1.0f - shadowCoord.y;
|
||||||
|
|
||||||
|
// Move around inside of atlas
|
||||||
|
vec2 aOffset;
|
||||||
|
aOffset.x = dot(finalMask, _atlasXOffset);
|
||||||
|
aOffset.y = dot(finalMask, _atlasYOffset);
|
||||||
|
|
||||||
|
shadowCoord *= _atlasScale;
|
||||||
|
shadowCoord += aOffset;
|
||||||
|
|
||||||
|
// Each split has a different far plane, take this into account.
|
||||||
|
float farPlaneScale = dot( _farPlaneScalePSSM, finalMask );
|
||||||
|
distToLight *= farPlaneScale;
|
||||||
|
|
||||||
|
return vec4(debugColor,
|
||||||
|
softShadow_filter( _sourceshadowMap,
|
||||||
|
_texCoord,
|
||||||
|
shadowCoord,
|
||||||
|
farPlaneScale * _shadowSoftness,
|
||||||
|
distToLight,
|
||||||
|
_dotNL,
|
||||||
|
dot( finalMask, _overDarkPSSM ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
out vec4 OUT_col;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Sample/unpack the normal/z data
|
// Sample/unpack the normal/z data
|
||||||
|
|
@ -92,101 +216,51 @@ void main()
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// Compute shadow map coordinate
|
vec4 static_shadowed_colors = AL_VectorLightShadowCast( shadowMap,
|
||||||
vec4 pxlPosLightProj = tMul(worldToLightProj, worldPos);
|
uv0.xy,
|
||||||
vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
|
worldToLightProj,
|
||||||
|
worldPos,
|
||||||
|
scaleX, scaleY,
|
||||||
|
offsetX, offsetY,
|
||||||
|
farPlaneScalePSSM,
|
||||||
|
atlasXOffset, atlasYOffset,
|
||||||
|
atlasScale,
|
||||||
|
shadowSoftness,
|
||||||
|
dotNL,
|
||||||
|
overDarkPSSM);
|
||||||
|
|
||||||
// Distance to light, in shadowmap space
|
|
||||||
float distToLight = pxlPosLightProj.z / pxlPosLightProj.w;
|
|
||||||
|
|
||||||
// Figure out which split to sample from. Basically, we compute the shadowmap sample coord
|
vec4 dynamic_shadowed_colors = AL_VectorLightShadowCast( dynamicShadowMap,
|
||||||
// for all of the splits and then check if its valid.
|
uv0.xy,
|
||||||
vec4 shadowCoordX = vec4( baseShadowCoord.x );
|
dynamicWorldToLightProj,
|
||||||
vec4 shadowCoordY = vec4( baseShadowCoord.y );
|
worldPos,
|
||||||
vec4 farPlaneDists = vec4( distToLight );
|
dynamicScaleX, dynamicScaleY,
|
||||||
shadowCoordX *= scaleX;
|
dynamicOffsetX, dynamicOffsetY,
|
||||||
shadowCoordY *= scaleY;
|
dynamicFarPlaneScalePSSM,
|
||||||
shadowCoordX += offsetX;
|
atlasXOffset, atlasYOffset,
|
||||||
shadowCoordY += offsetY;
|
atlasScale,
|
||||||
farPlaneDists *= farPlaneScalePSSM;
|
shadowSoftness,
|
||||||
|
dotNL,
|
||||||
// If the shadow sample is within -1..1 and the distance
|
overDarkPSSM);
|
||||||
// to the light for this pixel is less than the far plane
|
|
||||||
// of the split, use it.
|
|
||||||
vec4 finalMask;
|
|
||||||
if ( shadowCoordX.x > -0.99 && shadowCoordX.x < 0.99 &&
|
|
||||||
shadowCoordY.x > -0.99 && shadowCoordY.x < 0.99 &&
|
|
||||||
farPlaneDists.x < 1.0 )
|
|
||||||
finalMask = vec4(1, 0, 0, 0);
|
|
||||||
|
|
||||||
else if ( shadowCoordX.y > -0.99 && shadowCoordX.y < 0.99 &&
|
|
||||||
shadowCoordY.y > -0.99 && shadowCoordY.y < 0.99 &&
|
|
||||||
farPlaneDists.y < 1.0 )
|
|
||||||
finalMask = vec4(0, 1, 0, 0);
|
|
||||||
|
|
||||||
else if ( shadowCoordX.z > -0.99 && shadowCoordX.z < 0.99 &&
|
|
||||||
shadowCoordY.z > -0.99 && shadowCoordY.z < 0.99 &&
|
|
||||||
farPlaneDists.z < 1.0 )
|
|
||||||
finalMask = vec4(0, 0, 1, 0);
|
|
||||||
|
|
||||||
else
|
|
||||||
finalMask = vec4(0, 0, 0, 1);
|
|
||||||
|
|
||||||
|
float static_shadowed = static_shadowed_colors.a;
|
||||||
|
float dynamic_shadowed = dynamic_shadowed_colors.a;
|
||||||
|
|
||||||
#ifdef PSSM_DEBUG_RENDER
|
#ifdef PSSM_DEBUG_RENDER
|
||||||
if ( finalMask.x > 0 )
|
debugColor = static_shadowed_colors.rgb*0.5+dynamic_shadowed_colors.rgb*0.5;
|
||||||
debugColor += vec3( 1, 0, 0 );
|
|
||||||
else if ( finalMask.y > 0 )
|
|
||||||
debugColor += vec3( 0, 1, 0 );
|
|
||||||
else if ( finalMask.z > 0 )
|
|
||||||
debugColor += vec3( 0, 0, 1 );
|
|
||||||
else if ( finalMask.w > 0 )
|
|
||||||
debugColor += vec3( 1, 1, 0 );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Here we know what split we're sampling from, so recompute the texcoord location
|
|
||||||
// Yes, we could just use the result from above, but doing it this way actually saves
|
|
||||||
// shader instructions.
|
|
||||||
vec2 finalScale;
|
|
||||||
finalScale.x = dot(finalMask, scaleX);
|
|
||||||
finalScale.y = dot(finalMask, scaleY);
|
|
||||||
|
|
||||||
vec2 finalOffset;
|
|
||||||
finalOffset.x = dot(finalMask, offsetX);
|
|
||||||
finalOffset.y = dot(finalMask, offsetY);
|
|
||||||
|
|
||||||
vec2 shadowCoord;
|
|
||||||
shadowCoord = baseShadowCoord * finalScale;
|
|
||||||
shadowCoord += finalOffset;
|
|
||||||
|
|
||||||
// Convert to texcoord space
|
|
||||||
shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5);
|
|
||||||
shadowCoord.y = 1.0f - shadowCoord.y;
|
|
||||||
|
|
||||||
// Move around inside of atlas
|
|
||||||
vec2 aOffset;
|
|
||||||
aOffset.x = dot(finalMask, atlasXOffset);
|
|
||||||
aOffset.y = dot(finalMask, atlasYOffset);
|
|
||||||
|
|
||||||
shadowCoord *= atlasScale;
|
|
||||||
shadowCoord += aOffset;
|
|
||||||
|
|
||||||
// Each split has a different far plane, take this into account.
|
|
||||||
float farPlaneScale = dot( farPlaneScalePSSM, finalMask );
|
|
||||||
distToLight *= farPlaneScale;
|
|
||||||
|
|
||||||
float shadowed = softShadow_filter( ShadowMap,
|
|
||||||
uv0.xy,
|
|
||||||
shadowCoord,
|
|
||||||
farPlaneScale * shadowSoftness,
|
|
||||||
distToLight,
|
|
||||||
dotNL,
|
|
||||||
dot( finalMask, overDarkPSSM ) );
|
|
||||||
|
|
||||||
// Fade out the shadow at the end of the range.
|
// Fade out the shadow at the end of the range.
|
||||||
vec4 zDist = vec4(zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth);
|
vec4 zDist = vec4(zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth);
|
||||||
float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y;
|
float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y;
|
||||||
shadowed = mix( shadowed, 1.0, saturate( fadeOutAmt ) );
|
|
||||||
|
static_shadowed = mix( static_shadowed, 1.0, saturate( fadeOutAmt ) );
|
||||||
|
dynamic_shadowed = mix( dynamic_shadowed, 1.0, saturate( fadeOutAmt ) );
|
||||||
|
|
||||||
|
// temp for debugging. uncomment one or the other.
|
||||||
|
//float shadowed = static_shadowed;
|
||||||
|
//float shadowed = dynamic_shadowed;
|
||||||
|
float shadowed = min(static_shadowed, dynamic_shadowed);
|
||||||
|
|
||||||
#ifdef PSSM_DEBUG_RENDER
|
#ifdef PSSM_DEBUG_RENDER
|
||||||
if ( fadeOutAmt > 1.0 )
|
if ( fadeOutAmt > 1.0 )
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
#include "../../lighting.hlsl"
|
#include "../../lighting.hlsl"
|
||||||
#include "../shadowMap/shadowMapIO_HLSL.h"
|
#include "../shadowMap/shadowMapIO_HLSL.h"
|
||||||
#include "softShadow.hlsl"
|
#include "softShadow.hlsl"
|
||||||
|
#include "../../torque.hlsl"
|
||||||
|
|
||||||
struct ConvexConnectP
|
struct ConvexConnectP
|
||||||
{
|
{
|
||||||
|
|
@ -40,7 +40,7 @@ struct ConvexConnectP
|
||||||
#ifdef USE_COOKIE_TEX
|
#ifdef USE_COOKIE_TEX
|
||||||
|
|
||||||
/// The texture for cookie rendering.
|
/// The texture for cookie rendering.
|
||||||
uniform samplerCUBE cookieMap : register(S2);
|
uniform samplerCUBE cookieMap : register(S3);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -114,6 +114,7 @@ float4 main( ConvexConnectP IN,
|
||||||
uniform samplerCUBE shadowMap : register(S1),
|
uniform samplerCUBE shadowMap : register(S1),
|
||||||
#else
|
#else
|
||||||
uniform sampler2D shadowMap : register(S1),
|
uniform sampler2D shadowMap : register(S1),
|
||||||
|
uniform sampler2D dynamicShadowMap : register(S2),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uniform float4 rtParams0,
|
uniform float4 rtParams0,
|
||||||
|
|
@ -127,6 +128,7 @@ float4 main( ConvexConnectP IN,
|
||||||
|
|
||||||
uniform float4 vsFarPlane,
|
uniform float4 vsFarPlane,
|
||||||
uniform float3x3 viewToLightProj,
|
uniform float3x3 viewToLightProj,
|
||||||
|
uniform float3x3 dynamicViewToLightProj,
|
||||||
|
|
||||||
uniform float4 lightParams,
|
uniform float4 lightParams,
|
||||||
uniform float shadowSoftness ) : COLOR0
|
uniform float shadowSoftness ) : COLOR0
|
||||||
|
|
@ -178,9 +180,9 @@ float4 main( ConvexConnectP IN,
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
// Static
|
||||||
float2 shadowCoord = decodeShadowCoord( mul( viewToLightProj, -lightVec ) ).xy;
|
float2 shadowCoord = decodeShadowCoord( mul( viewToLightProj, -lightVec ) ).xy;
|
||||||
|
float static_shadowed = softShadow_filter( shadowMap,
|
||||||
float shadowed = softShadow_filter( shadowMap,
|
|
||||||
ssPos.xy,
|
ssPos.xy,
|
||||||
shadowCoord,
|
shadowCoord,
|
||||||
shadowSoftness,
|
shadowSoftness,
|
||||||
|
|
@ -188,6 +190,18 @@ float4 main( ConvexConnectP IN,
|
||||||
nDotL,
|
nDotL,
|
||||||
lightParams.y );
|
lightParams.y );
|
||||||
|
|
||||||
|
// Dynamic
|
||||||
|
float2 dynamicShadowCoord = decodeShadowCoord( mul( dynamicViewToLightProj, -lightVec ) ).xy;
|
||||||
|
float dynamic_shadowed = softShadow_filter( dynamicShadowMap,
|
||||||
|
ssPos.xy,
|
||||||
|
dynamicShadowCoord,
|
||||||
|
shadowSoftness,
|
||||||
|
distToLight,
|
||||||
|
nDotL,
|
||||||
|
lightParams.y );
|
||||||
|
|
||||||
|
float shadowed = min(static_shadowed, dynamic_shadowed);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // !NO_SHADOW
|
#endif // !NO_SHADOW
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ static float2 sNonUniformTaps[NUM_PRE_TAPS] =
|
||||||
|
|
||||||
/// The texture used to do per-pixel pseudorandom
|
/// The texture used to do per-pixel pseudorandom
|
||||||
/// rotations of the filter taps.
|
/// rotations of the filter taps.
|
||||||
uniform sampler2D gTapRotationTex : register(S3);
|
uniform sampler2D gTapRotationTex : register(S4);
|
||||||
|
|
||||||
|
|
||||||
float softShadow_sampleTaps( sampler2D shadowMap,
|
float softShadow_sampleTaps( sampler2D shadowMap,
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
#include "../../lighting.hlsl"
|
#include "../../lighting.hlsl"
|
||||||
#include "../shadowMap/shadowMapIO_HLSL.h"
|
#include "../shadowMap/shadowMapIO_HLSL.h"
|
||||||
#include "softShadow.hlsl"
|
#include "softShadow.hlsl"
|
||||||
|
#include "../../torque.hlsl"
|
||||||
|
|
||||||
struct ConvexConnectP
|
struct ConvexConnectP
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +39,7 @@ struct ConvexConnectP
|
||||||
#ifdef USE_COOKIE_TEX
|
#ifdef USE_COOKIE_TEX
|
||||||
|
|
||||||
/// The texture for cookie rendering.
|
/// The texture for cookie rendering.
|
||||||
uniform sampler2D cookieMap : register(S2);
|
uniform sampler2D cookieMap : register(S3);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -48,6 +48,7 @@ float4 main( ConvexConnectP IN,
|
||||||
|
|
||||||
uniform sampler2D prePassBuffer : register(S0),
|
uniform sampler2D prePassBuffer : register(S0),
|
||||||
uniform sampler2D shadowMap : register(S1),
|
uniform sampler2D shadowMap : register(S1),
|
||||||
|
uniform sampler2D dynamicShadowMap : register(S2),
|
||||||
|
|
||||||
uniform float4 rtParams0,
|
uniform float4 rtParams0,
|
||||||
|
|
||||||
|
|
@ -62,6 +63,7 @@ float4 main( ConvexConnectP IN,
|
||||||
|
|
||||||
uniform float4 vsFarPlane,
|
uniform float4 vsFarPlane,
|
||||||
uniform float4x4 viewToLightProj,
|
uniform float4x4 viewToLightProj,
|
||||||
|
uniform float4x4 dynamicViewToLightProj,
|
||||||
|
|
||||||
uniform float4 lightParams,
|
uniform float4 lightParams,
|
||||||
uniform float shadowSoftness ) : COLOR0
|
uniform float shadowSoftness ) : COLOR0
|
||||||
|
|
@ -101,6 +103,11 @@ float4 main( ConvexConnectP IN,
|
||||||
float2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 );
|
float2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 );
|
||||||
shadowCoord.y = 1.0f - shadowCoord.y;
|
shadowCoord.y = 1.0f - shadowCoord.y;
|
||||||
|
|
||||||
|
// Get the dynamic shadow texture coordinate
|
||||||
|
float4 dynpxlPosLightProj = mul( dynamicViewToLightProj, float4( viewSpacePos, 1 ) );
|
||||||
|
float2 dynshadowCoord = ( ( dynpxlPosLightProj.xy / dynpxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 );
|
||||||
|
dynshadowCoord.y = 1.0f - dynshadowCoord.y;
|
||||||
|
|
||||||
#ifdef NO_SHADOW
|
#ifdef NO_SHADOW
|
||||||
|
|
||||||
float shadowed = 1.0;
|
float shadowed = 1.0;
|
||||||
|
|
@ -110,7 +117,7 @@ float4 main( ConvexConnectP IN,
|
||||||
// Get a linear depth from the light source.
|
// Get a linear depth from the light source.
|
||||||
float distToLight = pxlPosLightProj.z / lightRange;
|
float distToLight = pxlPosLightProj.z / lightRange;
|
||||||
|
|
||||||
float shadowed = softShadow_filter( shadowMap,
|
float static_shadowed = softShadow_filter( shadowMap,
|
||||||
ssPos.xy,
|
ssPos.xy,
|
||||||
shadowCoord,
|
shadowCoord,
|
||||||
shadowSoftness,
|
shadowSoftness,
|
||||||
|
|
@ -118,6 +125,14 @@ float4 main( ConvexConnectP IN,
|
||||||
nDotL,
|
nDotL,
|
||||||
lightParams.y );
|
lightParams.y );
|
||||||
|
|
||||||
|
float dynamic_shadowed = softShadow_filter( dynamicShadowMap,
|
||||||
|
ssPos.xy,
|
||||||
|
dynshadowCoord,
|
||||||
|
shadowSoftness,
|
||||||
|
distToLight,
|
||||||
|
nDotL,
|
||||||
|
lightParams.y );
|
||||||
|
float shadowed = min(static_shadowed, dynamic_shadowed);
|
||||||
#endif // !NO_SHADOW
|
#endif // !NO_SHADOW
|
||||||
|
|
||||||
float3 lightcol = lightColor.rgb;
|
float3 lightcol = lightColor.rgb;
|
||||||
|
|
|
||||||
|
|
@ -30,68 +30,31 @@
|
||||||
#include "softShadow.hlsl"
|
#include "softShadow.hlsl"
|
||||||
|
|
||||||
|
|
||||||
uniform sampler2D ShadowMap : register(S1);
|
uniform sampler2D shadowMap : register(S1);
|
||||||
|
uniform sampler2D dynamicShadowMap : register(S2);
|
||||||
|
|
||||||
#ifdef USE_SSAO_MASK
|
#ifdef USE_SSAO_MASK
|
||||||
uniform sampler2D ssaoMask : register(S2);
|
uniform sampler2D ssaoMask : register(S3);
|
||||||
uniform float4 rtParams2;
|
uniform float4 rtParams3;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
float4 AL_VectorLightShadowCast( sampler2D sourceShadowMap,
|
||||||
float4 main( FarFrustumQuadConnectP IN,
|
float2 texCoord,
|
||||||
|
float4x4 worldToLightProj,
|
||||||
uniform sampler2D prePassBuffer : register(S0),
|
float4 worldPos,
|
||||||
|
float4 scaleX,
|
||||||
uniform float3 lightDirection,
|
float4 scaleY,
|
||||||
uniform float4 lightColor,
|
float4 offsetX,
|
||||||
uniform float lightBrightness,
|
float4 offsetY,
|
||||||
uniform float4 lightAmbient,
|
float4 farPlaneScalePSSM,
|
||||||
|
float4 atlasXOffset,
|
||||||
uniform float3 eyePosWorld,
|
float4 atlasYOffset,
|
||||||
|
float2 atlasScale,
|
||||||
uniform float4x4 worldToLightProj,
|
float shadowSoftness,
|
||||||
|
float dotNL ,
|
||||||
uniform float4 scaleX,
|
float4 overDarkPSSM
|
||||||
uniform float4 scaleY,
|
)
|
||||||
uniform float4 offsetX,
|
|
||||||
uniform float4 offsetY,
|
|
||||||
uniform float4 atlasXOffset,
|
|
||||||
uniform float4 atlasYOffset,
|
|
||||||
uniform float2 atlasScale,
|
|
||||||
uniform float4 zNearFarInvNearFar,
|
|
||||||
uniform float4 lightMapParams,
|
|
||||||
|
|
||||||
uniform float2 fadeStartLength,
|
|
||||||
uniform float4 farPlaneScalePSSM,
|
|
||||||
uniform float4 overDarkPSSM,
|
|
||||||
uniform float shadowSoftness ) : COLOR0
|
|
||||||
{
|
{
|
||||||
// Sample/unpack the normal/z data
|
|
||||||
float4 prepassSample = prepassUncondition( prePassBuffer, IN.uv0 );
|
|
||||||
float3 normal = prepassSample.rgb;
|
|
||||||
float depth = prepassSample.a;
|
|
||||||
|
|
||||||
// Use eye ray to get ws pos
|
|
||||||
float4 worldPos = float4(eyePosWorld + IN.wsEyeRay * depth, 1.0f);
|
|
||||||
|
|
||||||
// Get the light attenuation.
|
|
||||||
float dotNL = dot(-lightDirection, normal);
|
|
||||||
|
|
||||||
#ifdef PSSM_DEBUG_RENDER
|
|
||||||
float3 debugColor = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NO_SHADOW
|
|
||||||
|
|
||||||
// Fully unshadowed.
|
|
||||||
float shadowed = 1.0;
|
|
||||||
|
|
||||||
#ifdef PSSM_DEBUG_RENDER
|
|
||||||
debugColor = 1.0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// Compute shadow map coordinate
|
// Compute shadow map coordinate
|
||||||
float4 pxlPosLightProj = mul(worldToLightProj, worldPos);
|
float4 pxlPosLightProj = mul(worldToLightProj, worldPos);
|
||||||
float2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
|
float2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
|
||||||
|
|
@ -132,6 +95,11 @@ float4 main( FarFrustumQuadConnectP IN,
|
||||||
else
|
else
|
||||||
finalMask = float4(0, 0, 0, 1);
|
finalMask = float4(0, 0, 0, 1);
|
||||||
|
|
||||||
|
float3 debugColor = float3(0,0,0);
|
||||||
|
|
||||||
|
#ifdef NO_SHADOW
|
||||||
|
debugColor = float3(1.0,1.0,1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PSSM_DEBUG_RENDER
|
#ifdef PSSM_DEBUG_RENDER
|
||||||
if ( finalMask.x > 0 )
|
if ( finalMask.x > 0 )
|
||||||
|
|
@ -175,18 +143,124 @@ float4 main( FarFrustumQuadConnectP IN,
|
||||||
float farPlaneScale = dot( farPlaneScalePSSM, finalMask );
|
float farPlaneScale = dot( farPlaneScalePSSM, finalMask );
|
||||||
distToLight *= farPlaneScale;
|
distToLight *= farPlaneScale;
|
||||||
|
|
||||||
float shadowed = softShadow_filter( ShadowMap,
|
return float4(debugColor,
|
||||||
IN.uv0.xy,
|
softShadow_filter( sourceShadowMap,
|
||||||
|
texCoord,
|
||||||
shadowCoord,
|
shadowCoord,
|
||||||
farPlaneScale * shadowSoftness,
|
farPlaneScale * shadowSoftness,
|
||||||
distToLight,
|
distToLight,
|
||||||
dotNL,
|
dotNL,
|
||||||
dot( finalMask, overDarkPSSM ) );
|
dot( finalMask, overDarkPSSM ) ) );
|
||||||
|
};
|
||||||
|
|
||||||
|
float4 main( FarFrustumQuadConnectP IN,
|
||||||
|
|
||||||
|
uniform sampler2D prePassBuffer : register(S0),
|
||||||
|
|
||||||
|
uniform float3 lightDirection,
|
||||||
|
uniform float4 lightColor,
|
||||||
|
uniform float lightBrightness,
|
||||||
|
uniform float4 lightAmbient,
|
||||||
|
uniform float4x4 eyeMat,
|
||||||
|
|
||||||
|
uniform float3 eyePosWorld,
|
||||||
|
uniform float4 atlasXOffset,
|
||||||
|
uniform float4 atlasYOffset,
|
||||||
|
uniform float2 atlasScale,
|
||||||
|
uniform float4 zNearFarInvNearFar,
|
||||||
|
uniform float4 lightMapParams,
|
||||||
|
uniform float2 fadeStartLength,
|
||||||
|
uniform float4 overDarkPSSM,
|
||||||
|
uniform float shadowSoftness,
|
||||||
|
|
||||||
|
// Static Shadows
|
||||||
|
uniform float4x4 worldToLightProj,
|
||||||
|
uniform float4 scaleX,
|
||||||
|
uniform float4 scaleY,
|
||||||
|
uniform float4 offsetX,
|
||||||
|
uniform float4 offsetY,
|
||||||
|
uniform float4 farPlaneScalePSSM,
|
||||||
|
|
||||||
|
// Dynamic Shadows
|
||||||
|
uniform float4x4 dynamicWorldToLightProj,
|
||||||
|
uniform float4 dynamicScaleX,
|
||||||
|
uniform float4 dynamicScaleY,
|
||||||
|
uniform float4 dynamicOffsetX,
|
||||||
|
uniform float4 dynamicOffsetY,
|
||||||
|
uniform float4 dynamicFarPlaneScalePSSM
|
||||||
|
|
||||||
|
) : COLOR0
|
||||||
|
{
|
||||||
|
// Sample/unpack the normal/z data
|
||||||
|
float4 prepassSample = prepassUncondition( prePassBuffer, IN.uv0 );
|
||||||
|
float3 normal = prepassSample.rgb;
|
||||||
|
float depth = prepassSample.a;
|
||||||
|
|
||||||
|
// Use eye ray to get ws pos
|
||||||
|
float4 worldPos = float4(eyePosWorld + IN.wsEyeRay * depth, 1.0f);
|
||||||
|
|
||||||
|
// Get the light attenuation.
|
||||||
|
float dotNL = dot(-lightDirection, normal);
|
||||||
|
|
||||||
|
#ifdef PSSM_DEBUG_RENDER
|
||||||
|
float3 debugColor = float3(0,0,0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NO_SHADOW
|
||||||
|
|
||||||
|
// Fully unshadowed.
|
||||||
|
float shadowed = 1.0;
|
||||||
|
|
||||||
|
#ifdef PSSM_DEBUG_RENDER
|
||||||
|
debugColor = float3(1.0,1.0,1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
float4 static_shadowed_colors = AL_VectorLightShadowCast( shadowMap,
|
||||||
|
IN.uv0.xy,
|
||||||
|
worldToLightProj,
|
||||||
|
worldPos,
|
||||||
|
scaleX, scaleY,
|
||||||
|
offsetX, offsetY,
|
||||||
|
farPlaneScalePSSM,
|
||||||
|
atlasXOffset, atlasYOffset,
|
||||||
|
atlasScale,
|
||||||
|
shadowSoftness,
|
||||||
|
dotNL,
|
||||||
|
overDarkPSSM);
|
||||||
|
|
||||||
|
float4 dynamic_shadowed_colors = AL_VectorLightShadowCast( dynamicShadowMap,
|
||||||
|
IN.uv0.xy,
|
||||||
|
dynamicWorldToLightProj,
|
||||||
|
worldPos,
|
||||||
|
dynamicScaleX, dynamicScaleY,
|
||||||
|
dynamicOffsetX, dynamicOffsetY,
|
||||||
|
dynamicFarPlaneScalePSSM,
|
||||||
|
atlasXOffset, atlasYOffset,
|
||||||
|
atlasScale,
|
||||||
|
shadowSoftness,
|
||||||
|
dotNL,
|
||||||
|
overDarkPSSM);
|
||||||
|
|
||||||
|
float static_shadowed = static_shadowed_colors.a;
|
||||||
|
float dynamic_shadowed = dynamic_shadowed_colors.a;
|
||||||
|
|
||||||
|
#ifdef PSSM_DEBUG_RENDER
|
||||||
|
debugColor = static_shadowed_colors.rgb*0.5+dynamic_shadowed_colors.rgb*0.5;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Fade out the shadow at the end of the range.
|
// Fade out the shadow at the end of the range.
|
||||||
float4 zDist = (zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth);
|
float4 zDist = (zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth);
|
||||||
float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y;
|
float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y;
|
||||||
shadowed = lerp( shadowed, 1.0, saturate( fadeOutAmt ) );
|
|
||||||
|
static_shadowed = lerp( static_shadowed, 1.0, saturate( fadeOutAmt ) );
|
||||||
|
dynamic_shadowed = lerp( dynamic_shadowed, 1.0, saturate( fadeOutAmt ) );
|
||||||
|
|
||||||
|
// temp for debugging. uncomment one or the other.
|
||||||
|
//float shadowed = static_shadowed;
|
||||||
|
//float shadowed = dynamic_shadowed;
|
||||||
|
float shadowed = min(static_shadowed, dynamic_shadowed);
|
||||||
|
|
||||||
#ifdef PSSM_DEBUG_RENDER
|
#ifdef PSSM_DEBUG_RENDER
|
||||||
if ( fadeOutAmt > 1.0 )
|
if ( fadeOutAmt > 1.0 )
|
||||||
|
|
@ -221,7 +295,7 @@ float4 main( FarFrustumQuadConnectP IN,
|
||||||
|
|
||||||
// Sample the AO texture.
|
// Sample the AO texture.
|
||||||
#ifdef USE_SSAO_MASK
|
#ifdef USE_SSAO_MASK
|
||||||
float ao = 1.0 - tex2D( ssaoMask, viewportCoordToRenderTarget( IN.uv0.xy, rtParams2 ) ).r;
|
float ao = 1.0 - tex2D( ssaoMask, viewportCoordToRenderTarget( IN.uv0.xy, rtParams3 ) ).r;
|
||||||
addToResult *= ao;
|
addToResult *= ao;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3309,7 +3309,7 @@
|
||||||
HorizSizing = "width";
|
HorizSizing = "width";
|
||||||
VertSizing = "bottom";
|
VertSizing = "bottom";
|
||||||
Position = "0 0";
|
Position = "0 0";
|
||||||
Extent = "210 71";
|
Extent = "210 89";
|
||||||
|
|
||||||
new GuiPopUpMenuCtrl() {
|
new GuiPopUpMenuCtrl() {
|
||||||
internalName = "blendingTypePopUp";
|
internalName = "blendingTypePopUp";
|
||||||
|
|
@ -3480,7 +3480,7 @@
|
||||||
Visible = "1";
|
Visible = "1";
|
||||||
Command = "MaterialEditorGui.updateActiveMaterial(\"castShadows\", $ThisControl.getValue());";
|
Command = "MaterialEditorGui.updateActiveMaterial(\"castShadows\", $ThisControl.getValue());";
|
||||||
tooltipprofile = "ToolsGuiDefaultProfile";
|
tooltipprofile = "ToolsGuiDefaultProfile";
|
||||||
ToolTip = "Alows object to cast shadows.";
|
ToolTip = "Object casts shadows.";
|
||||||
hovertime = "1000";
|
hovertime = "1000";
|
||||||
text = "Cast Shadows";
|
text = "Cast Shadows";
|
||||||
groupNum = "-1";
|
groupNum = "-1";
|
||||||
|
|
@ -3488,6 +3488,29 @@
|
||||||
useMouseEvents = "0";
|
useMouseEvents = "0";
|
||||||
useInactiveState = "0";
|
useInactiveState = "0";
|
||||||
};
|
};
|
||||||
|
new GuiCheckBoxCtrl() {
|
||||||
|
canSaveDynamicFields = "0";
|
||||||
|
internalName = "castDynamicShadows";
|
||||||
|
Enabled = "1";
|
||||||
|
isContainer = "0";
|
||||||
|
Profile = "ToolsGuiCheckBoxProfile";
|
||||||
|
HorizSizing = "right";
|
||||||
|
VertSizing = "bottom";
|
||||||
|
position = "3 70";
|
||||||
|
Extent = "112 16";
|
||||||
|
MinExtent = "8 2";
|
||||||
|
canSave = "1";
|
||||||
|
Visible = "1";
|
||||||
|
Command = "MaterialEditorGui.updateActiveMaterial(\"castDynamicShadows\", $ThisControl.getValue());";
|
||||||
|
tooltipprofile = "ToolsGuiDefaultProfile";
|
||||||
|
ToolTip = "Object casts dynamic shadows.";
|
||||||
|
hovertime = "1000";
|
||||||
|
text = "Dynamic Shadows";
|
||||||
|
groupNum = "-1";
|
||||||
|
buttonType = "ToggleButton";
|
||||||
|
useMouseEvents = "0";
|
||||||
|
useInactiveState = "0";
|
||||||
|
};
|
||||||
new GuiCheckBoxCtrl() {
|
new GuiCheckBoxCtrl() {
|
||||||
canSaveDynamicFields = "0";
|
canSaveDynamicFields = "0";
|
||||||
internalName = "doubleSidedCheckBox";
|
internalName = "doubleSidedCheckBox";
|
||||||
|
|
|
||||||
|
|
@ -754,6 +754,7 @@ function MaterialEditorGui::guiSync( %this, %material )
|
||||||
MaterialEditorPropertiesWindow-->transZWriteCheckBox.setValue((%material).translucentZWrite);
|
MaterialEditorPropertiesWindow-->transZWriteCheckBox.setValue((%material).translucentZWrite);
|
||||||
MaterialEditorPropertiesWindow-->alphaTestCheckBox.setValue((%material).alphaTest);
|
MaterialEditorPropertiesWindow-->alphaTestCheckBox.setValue((%material).alphaTest);
|
||||||
MaterialEditorPropertiesWindow-->castShadows.setValue((%material).castShadows);
|
MaterialEditorPropertiesWindow-->castShadows.setValue((%material).castShadows);
|
||||||
|
MaterialEditorPropertiesWindow-->castDynamicShadows.setValue((%material).castDynamicShadows);
|
||||||
MaterialEditorPropertiesWindow-->translucentCheckbox.setValue((%material).translucent);
|
MaterialEditorPropertiesWindow-->translucentCheckbox.setValue((%material).translucent);
|
||||||
|
|
||||||
switch$((%material).translucentBlendOp)
|
switch$((%material).translucentBlendOp)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue