diff --git a/Engine/source/T3D/lightFlareData.cpp b/Engine/source/T3D/lightFlareData.cpp index 2fae80fa9..5ce430755 100644 --- a/Engine/source/T3D/lightFlareData.cpp +++ b/Engine/source/T3D/lightFlareData.cpp @@ -33,6 +33,7 @@ #include "gfx/gfxOcclusionQuery.h" #include "gfx/gfxDrawUtil.h" #include "gfx/gfxTextureManager.h" +#include "gfx/sim/debugDraw.h" #include "renderInstance/renderPassManager.h" #include "T3D/gameBase/gameConnection.h" #include "T3D/gameBase/processList.h" @@ -275,12 +276,10 @@ bool LightFlareData::_testVisibility(const SceneRenderState *state, LightFlareSt // is on scren at all... if not then return // the last result. const Point3F &lightPos = flareState->lightMat.getPosition(); - const RectI &viewport = GFX->getViewport(); - MatrixF projMatrix; - state->getCameraFrustum().getProjectionMatrix(&projMatrix); - if( state->isReflectPass() ) - projMatrix = state->getSceneManager()->getNonClipProjection(); - bool onScreen = MathUtils::mProjectWorldToScreen( lightPos, outLightPosSS, viewport, GFX->getWorldMatrix(), projMatrix ); + const RectI &viewport = RectI(Point2I(0, 0), GFX->getViewport().extent); + + MatrixF camProjMatrix = projMatrix = state->getSceneManager()->getNonClipProjection(); + bool onScreen = MathUtils::mProjectWorldToScreen( lightPos, outLightPosSS, viewport, GFX->getWorldMatrix(), camProjMatrix ); // It is onscreen, so raycast as a simple occlusion test. const LightInfo *lightInfo = flareState->lightInfo; @@ -297,7 +296,7 @@ bool LightFlareData::_testVisibility(const SceneRenderState *state, LightFlareSt // Always treat light as onscreen if using HOQ // it will be faded out if offscreen anyway. onScreen = true; - needsRaycast = false; + needsRaycast = false; // Test the hardware queries for rendered pixels. U32 pixels = 0, fullPixels = 0; @@ -400,63 +399,75 @@ bool LightFlareData::_testVisibility(const SceneRenderState *state, LightFlareSt return lightVisible; } -void LightFlareData::prepRender( SceneRenderState *state, LightFlareState *flareState ) +void LightFlareData::prepRender(SceneRenderState *state, LightFlareState *flareState) { - PROFILE_SCOPE( LightFlareData_prepRender ); + PROFILE_SCOPE(LightFlareData_prepRender); const LightInfo *lightInfo = flareState->lightInfo; - if ( mIsZero( flareState->fullBrightness ) || - mIsZero( lightInfo->getBrightness() ) ) - return; + if (mIsZero(flareState->fullBrightness) || + mIsZero(lightInfo->getBrightness())) + return; // Figure out the element count to render. U32 elementCount = mElementCount; const bool isReflectPass = state->isReflectPass(); - if ( isReflectPass ) + if (isReflectPass) { // Then we don't render anything this pass. - if ( !mRenderReflectPass ) + if (!mRenderReflectPass) return; // Find the zero distance elements which make // up the corona of the light flare. elementCount = 0.0f; - for ( U32 i=0; i < mElementCount; i++ ) - if ( mIsZero( mElementDist[i] ) ) - elementCount++; + for (U32 i = 0; i < mElementCount; i++) + if (mIsZero(mElementDist[i])) + elementCount++; } // Better have something to render. - if ( elementCount == 0 ) + if (elementCount == 0) return; - + U32 visDelta = U32_MAX; F32 occlusionFade = 1.0f; Point3F lightPosSS; - bool lightVisible = _testVisibility( state, flareState, &visDelta, &occlusionFade, &lightPosSS ); - + bool lightVisible = _testVisibility(state, flareState, &visDelta, &occlusionFade, &lightPosSS); + + //DebugDrawer::get()->drawBox(flareState->lightMat.getPosition() + Point3F(-0.5, -0.5, -0.5) * 4, flareState->lightMat.getPosition() + Point3F(0.5, 0.5, 0.5) * 4, ColorI::BLUE); + // We can only skip rendering if the light is not // visible, and it has elapsed the fade out time. - if ( mIsZero( occlusionFade ) || - !lightVisible && visDelta > FadeOutTime ) + if (mIsZero(occlusionFade) || + !lightVisible && visDelta > FadeOutTime) return; const RectI &viewport = GFX->getViewport(); - Point3F oneOverViewportExtent( 1.0f / (F32)viewport.extent.x, 1.0f / (F32)viewport.extent.y, 0.0f ); + Point3F oneOverViewportExtent(1.0f / (F32)viewport.extent.x, 1.0f / (F32)viewport.extent.y, 0.0f); - // Really convert it to screen space. - lightPosSS.x -= viewport.point.x; - lightPosSS.y -= viewport.point.y; lightPosSS *= oneOverViewportExtent; - lightPosSS = ( lightPosSS * 2.0f ) - Point3F::One; + lightPosSS = (lightPosSS * 2.0f) - Point3F::One; lightPosSS.y = -lightPosSS.y; lightPosSS.z = 0.0f; + // Determine the center of the current projection so we can converge there + Point3F centerProj(0); + { + MatrixF camProjMatrix = state->getSceneManager()->getNonClipProjection(); + Point3F outCenterPos; + RectI centerViewport = RectI(Point2I(0, 0), viewport.extent); + MathUtils::mProjectWorldToScreen(Point3F(0,state->getSceneManager()->getNearClip(),0), &outCenterPos, centerViewport, MatrixF::Identity, camProjMatrix); + centerProj = outCenterPos; + centerProj *= oneOverViewportExtent; + centerProj = (centerProj * 2.0f) - Point3F::One; + centerProj.y = -centerProj.y; + centerProj.z = 0.0f; + } + // Take any projection offset into account so that the point where the flare's // elements converge is at the 'eye' point rather than the center of the viewport. - const Point2F& projOffset = state->getCameraFrustum().getProjectionOffset(); - Point3F flareVec( -lightPosSS + Point3F(projOffset.x, projOffset.y, 0.0f) ); + Point3F flareVec( centerProj - lightPosSS ); const F32 flareLength = flareVec.len(); if ( flareLength > 0.0f ) flareVec *= 1.0f / flareLength; diff --git a/Engine/source/environment/scatterSky.cpp b/Engine/source/environment/scatterSky.cpp index 7607246f4..9b25d71ea 100644 --- a/Engine/source/environment/scatterSky.cpp +++ b/Engine/source/environment/scatterSky.cpp @@ -667,11 +667,11 @@ void ScatterSky::prepRenderImage( SceneRenderState *state ) mFlareState.scale = mFlareScale; mFlareState.lightInfo = mLight; - Point3F lightPos = state->getCameraPosition() - state->getFarPlane() * mLight->getDirection() * 0.9f; + Point3F lightPos = state->getDiffuseCameraPosition() - state->getFarPlane() * mLight->getDirection() * 0.9f; mFlareState.lightMat.identity(); mFlareState.lightMat.setPosition( lightPos ); - F32 dist = ( lightPos - state->getCameraPosition( ) ).len( ); + F32 dist = ( lightPos - state->getDiffuseCameraPosition( ) ).len( ); F32 coronaScale = 0.5f; F32 screenRadius = GFX->getViewport( ).extent.y * coronaScale * 0.5f; mFlareState.worldRadius = screenRadius * dist / state->getWorldToScreenScale( ).y; diff --git a/Engine/source/math/util/frustum.cpp b/Engine/source/math/util/frustum.cpp index 181e140ef..bfb42a6bf 100644 --- a/Engine/source/math/util/frustum.cpp +++ b/Engine/source/math/util/frustum.cpp @@ -216,7 +216,7 @@ void Frustum::setNearFarDist( F32 nearDist, F32 farDist ) // Recalculate the frustum. MatrixF xfm( mTransform ); - const F32 CENTER_EPSILON = 0.01; + const F32 CENTER_EPSILON = 0.001; F32 centerX = mNearLeft + (mNearRight - mNearLeft) * 0.5; F32 centerY = mNearBottom + (mNearTop - mNearBottom) * 0.5; if ((centerX > CENTER_EPSILON || centerX < -CENTER_EPSILON) || (centerY > CENTER_EPSILON || centerY < -CENTER_EPSILON) )