diff --git a/Engine/source/T3D/lightFlareData.cpp b/Engine/source/T3D/lightFlareData.cpp index 8faf7d952..2fae80fa9 100644 --- a/Engine/source/T3D/lightFlareData.cpp +++ b/Engine/source/T3D/lightFlareData.cpp @@ -121,7 +121,6 @@ LightFlareData::LightFlareData() mElementCount( 0 ), mScale( 1.0f ), mOcclusionRadius( 0.0f ), - mVisibility( 1.0f ), //sunBokeh feature mRenderReflectPass( true ) { dMemset( mElementRect, 0, sizeof( RectF ) * MAX_ELEMENTS ); @@ -446,8 +445,6 @@ void LightFlareData::prepRender( SceneRenderState *state, LightFlareState *flare const RectI &viewport = GFX->getViewport(); Point3F oneOverViewportExtent( 1.0f / (F32)viewport.extent.x, 1.0f / (F32)viewport.extent.y, 0.0f ); - // Sun visibility, assume 0 at start of frame - mVisibility = 0; //sunBokeh feature // Really convert it to screen space. lightPosSS.x -= viewport.point.x; lightPosSS.y -= viewport.point.y; @@ -517,7 +514,6 @@ void LightFlareData::prepRender( SceneRenderState *state, LightFlareState *flare // These are the factors which affect the "alpha" of the flare effect. // Modulate more in as appropriate. ColorF baseColor = ColorF::WHITE * lightSourceBrightnessScale * occlusionFade; - mVisibility = lightSourceBrightnessScale * fadeInOutScale * occlusionFade; //sunBokeh feature // Setup the vertex buffer for the maximum flare elements. const U32 vertCount = 4 * mElementCount; diff --git a/Engine/source/T3D/lightFlareData.h b/Engine/source/T3D/lightFlareData.h index cd9b4d509..3d387e9c7 100644 --- a/Engine/source/T3D/lightFlareData.h +++ b/Engine/source/T3D/lightFlareData.h @@ -94,8 +94,6 @@ public: /// Submits render instances for corona and flare effects. void prepRender( SceneRenderState *state, LightFlareState *flareState ); - /// sunBokeh feature - F32 getVisibility() const { return mVisibility; } protected: @@ -114,7 +112,6 @@ protected: static Point3F sBasePoints[4]; // Fields... - F32 mVisibility; //sunBokeh feature F32 mScale; bool mFlareEnabled; String mFlareTextureName; diff --git a/Engine/source/environment/scatterSky.cpp b/Engine/source/environment/scatterSky.cpp index 8df2d6d46..3e5fe8de7 100644 --- a/Engine/source/environment/scatterSky.cpp +++ b/Engine/source/environment/scatterSky.cpp @@ -42,7 +42,6 @@ #include "materials/sceneData.h" #include "environment/timeOfDay.h" - ConsoleDocClass( ScatterSky, "@brief Represents both the sun and sky for scenes with a dynamic time of day.\n\n" @@ -655,11 +654,6 @@ void ScatterSky::prepRenderImage( SceneRenderState *state ) state->getRenderPass()->addInst( ri ); } */ - // Screen flare occlusion fix //sunBokeh feature - F32 screenRadius = GFX->getViewport().extent.y * mFlareScale * 0.01f; - Point3F lightWorldPos = state->getCameraPosition() - state->getFarPlane() * mLight->getDirection() * 0.9f; - F32 dist = ( lightWorldPos - state->getCameraPosition() ).len(); - mFlareState.worldRadius = screenRadius * dist / state->getWorldToScreenScale().y; // Light flare effect render instance. if ( mFlareData && mNightInterpolant != 1.0f ) diff --git a/Engine/source/environment/scatterSky.h b/Engine/source/environment/scatterSky.h index 37bc5c7a4..21041648b 100644 --- a/Engine/source/environment/scatterSky.h +++ b/Engine/source/environment/scatterSky.h @@ -109,11 +109,7 @@ public: F32 getAzimuth() const { return mSunAzimuth; } /// F32 getElevation() const { return mSunElevation; } - /// sunBokeh feature - F32 getSunVisibility() const { if (mFlareData) return mFlareData->getVisibility(); else return 0; } - // Same method as above, but also checks if the data is valid, needs more CPU time, only use if above method fails - //F32 getSunVisibility() const { if dynamic_cast(mFlareData) return mFlareData->getVisibility(); else return 0; } - + protected: void _render( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ); diff --git a/Engine/source/postFx/postEffect.cpp b/Engine/source/postFx/postEffect.cpp index 4988eb9aa..b94ac2f7e 100644 --- a/Engine/source/postFx/postEffect.cpp +++ b/Engine/source/postFx/postEffect.cpp @@ -45,6 +45,8 @@ #include "postFx/postEffectManager.h" #include "postFx/postEffectVis.h" #include "environment/scatterSky.h" //sunBokeh feature +#include "T3D/gameBase/gameConnection.h" //sunBokeh feature +#include "T3D/lightFlareData.h" //sunBokeh feature using namespace Torque; @@ -855,9 +857,10 @@ void PostEffect::_setupConstants( const SceneRenderState *state ) if( mSunVisibilitySC->isValid() ) //sunBokeh feature { - ScatterSky* pSky = dynamic_cast(Sim::findObject("Himmel")); - if(pSky) - mShaderConsts->set( mSunVisibilitySC, pSky->getSunVisibility() ); + LightInfo *sunLight = LIGHTMGR->getSpecialLight( LightManager::slSunLightType ); + + if(sunLight) + mShaderConsts->set( mSunVisibilitySC, _testVisibility(state) ); else mShaderConsts->set( mSunVisibilitySC, 0.0f ); } @@ -918,6 +921,79 @@ void PostEffect::_setupConstants( const SceneRenderState *state ) iter->value->setToBuffer( mShaderConsts ); } +// sunBokeh feature to test if sun is visible +F32 PostEffect::_testVisibility(const SceneRenderState *state) +{ + // Grab our projection matrix + // from the frustum. + Frustum frust = state->getCameraFrustum(); + MatrixF proj( true ); + frust.getProjectionMatrix( &proj ); + + // Grab the ScatterSky world matrix. + MatrixF camMat = state->getCameraTransform(); + camMat.inverse(); + MatrixF tmp( true ); + tmp = camMat; + tmp.setPosition( Point3F( 0, 0, 0 ) ); + + Point3F sunPos( 0, 0, 0 ); + + // Get the light manager and sun light object. + LightInfo *sunLight = LIGHTMGR->getSpecialLight( LightManager::slSunLightType ); + + // Grab the light direction and scale + // by the ScatterSky radius to get the world + // space sun position. + const VectorF &lightDir = sunLight->getDirection(); + + Point3F lightPos = sunLight->getPosition(); + + RectI viewPort = GFX->getViewport(); + + // Get the screen space sun position. + MathUtils::mProjectWorldToScreen(lightPos, &sunPos, viewPort, tmp, proj); + + // And normalize it to the 0 to 1 range. + sunPos.x -= (F32)viewPort.point.x; + sunPos.y -= (F32)viewPort.point.y; + sunPos.x /= (F32)viewPort.extent.x; + sunPos.y /= (F32)viewPort.extent.y; + + //------------------------------------------------------------ + + const Point3F &camPos = state->getCameraPosition(); + + // Use a raycast to determine occlusion. + GameConnection *conn = GameConnection::getConnectionToServer(); + if ( !conn ) + return false; + + const bool fps = conn->isFirstPerson(); + GameBase *control = conn->getControlObject(); + if ( control && fps ) + control->disableCollision(); + + RayInfo rayInfo; + + U32 LosMask = STATIC_COLLISION_TYPEMASK | + ShapeBaseObjectType | + StaticShapeObjectType | + ItemObjectType; + + F32 lightVisible = 0.0f; + + if ( !gClientContainer.castRay( camPos, lightPos, LosMask, &rayInfo ) ) + + lightVisible = 1.0f ; + + + if ( control && fps ) + control->enableCollision(); + + return lightVisible; +} + void PostEffect::_setupTexture( U32 stage, GFXTexHandle &inputTex, const RectI *inTexViewport ) { const String &texFilename = mTexFilename[ stage ]; diff --git a/Engine/source/postFx/postEffect.h b/Engine/source/postFx/postEffect.h index 06b951600..142305b6b 100644 --- a/Engine/source/postFx/postEffect.h +++ b/Engine/source/postFx/postEffect.h @@ -179,6 +179,9 @@ protected: String mRenderBin; F32 mRenderPriority; + + /// Test sun visibility feature for sunBokeh + F32 _testVisibility( const SceneRenderState *state ); /// This is true if the effect has been succesfully /// initialized and all requirements are met for use.