improve anti-aliasing

+re-implement anti-aliasing, making it more acurate, not blured, better
and much faster (unsing much less lines of code)
+rewrite some function on camera and raypacket.
+small improvements on raytracing realtime, remove useless ifs
comparisons.
This commit is contained in:
Mario Luzeiro 2016-10-22 23:37:13 +01:00 committed by Wayne Stambaugh
parent d470ac9c24
commit 86dcfeb69d
7 changed files with 560 additions and 699 deletions

View File

@ -120,7 +120,7 @@ public:
// Imported from CGENERICACCELERATOR
bool Intersect( const RAY &aRay, HITINFO &aHitInfo ) const override;
bool Intersect( const RAY &aRay, HITINFO &aHitInfo, unsigned int aAccNodeInfo ) const override;
bool Intersect(const RAYPACKET &aRayPacket, HITINFO_PACKET *aHitInfoPacket ) const override;
bool Intersect( const RAYPACKET &aRayPacket, HITINFO_PACKET *aHitInfoPacket ) const override;
bool IntersectP( const RAY &aRay, float aMaxDistance ) const override;
private:

View File

@ -83,6 +83,18 @@ private:
void rt_render_trace_block( GLubyte *ptrPBO , signed int iBlock );
void rt_final_color( GLubyte *ptrPBO, const SFVEC3F &rgbColor, bool applyColorSpaceConversion );
void rt_shades_packet( const SFVEC3F *bgColorY,
const RAY *aRayPkt,
HITINFO_PACKET *aHitPacket,
bool is_testShadow,
SFVEC3F *aOutHitColor );
void rt_trace_AA_packet( const SFVEC3F *aBgColorY,
const HITINFO_PACKET *aHitPck_X0Y0,
const HITINFO_PACKET *aHitPck_AA_X1Y1,
const RAY *aRayPck,
SFVEC3F *aOutHitColor );
// Materials
void setupMaterials();
@ -109,7 +121,8 @@ private:
const RAY &aRay,
HITINFO &aHitInfo,
bool aIsInsideObject,
unsigned int aRecursiveLevel ) const;
unsigned int aRecursiveLevel,
bool is_testShadow ) const;
/// State used on quality render
RT_RENDER_STATE m_rt_render_state;

View File

@ -32,6 +32,16 @@
#include <wx/debug.h>
static void RAYPACKET_GenerateFrustum( CFRUSTUM *m_Frustum, RAY *m_ray )
{
m_Frustum->GenerateFrustum(
m_ray[ 0 * RAYPACKET_DIM + 0 ],
m_ray[ 0 * RAYPACKET_DIM + (RAYPACKET_DIM - 1) ],
m_ray[ (RAYPACKET_DIM - 1) * RAYPACKET_DIM + 0 ],
m_ray[ (RAYPACKET_DIM - 1) * RAYPACKET_DIM + (RAYPACKET_DIM - 1) ] );
}
RAYPACKET::RAYPACKET( const CCAMERA &aCamera, const SFVEC2I &aWindowsPosition )
{
unsigned int i = 0;
@ -55,12 +65,29 @@ RAYPACKET::RAYPACKET( const CCAMERA &aCamera, const SFVEC2I &aWindowsPosition )
wxASSERT( i == RAYPACKET_RAYS_PER_PACKET );
m_Frustum.GenerateFrustum(
m_ray[ 0 * RAYPACKET_DIM + 0 ],
m_ray[ 0 * RAYPACKET_DIM + (RAYPACKET_DIM - 1) ],
m_ray[ (RAYPACKET_DIM - 1) * RAYPACKET_DIM + 0 ],
m_ray[ (RAYPACKET_DIM - 1) * RAYPACKET_DIM + (RAYPACKET_DIM - 1) ] );
RAYPACKET_GenerateFrustum( &m_Frustum, m_ray );
}
RAYPACKET::RAYPACKET( const CCAMERA &aCamera,
const SFVEC2F &aWindowsPosition )
{
RAYPACKET_InitRays( aCamera, aWindowsPosition, m_ray );
RAYPACKET_GenerateFrustum( &m_Frustum, m_ray );
}
RAYPACKET::RAYPACKET( const CCAMERA &aCamera,
const SFVEC2F &aWindowsPosition,
const SFVEC2F &a2DWindowsPosDisplacementFactor )
{
RAYPACKET_InitRays_with2DDisplacement( aCamera,
aWindowsPosition,
a2DWindowsPosDisplacementFactor,
m_ray );
RAYPACKET_GenerateFrustum( &m_Frustum, m_ray );
}
@ -91,11 +118,7 @@ RAYPACKET::RAYPACKET( const CCAMERA &aCamera,
wxASSERT( i == RAYPACKET_RAYS_PER_PACKET );
m_Frustum.GenerateFrustum( m_ray[ 0 * RAYPACKET_DIM + 0 ],
m_ray[ 0 * RAYPACKET_DIM + (RAYPACKET_DIM - 1) ],
m_ray[ (RAYPACKET_DIM - 1) * RAYPACKET_DIM + 0 ],
m_ray[ (RAYPACKET_DIM - 1) * RAYPACKET_DIM + (RAYPACKET_DIM - 1) ] );
RAYPACKET_GenerateFrustum( &m_Frustum, m_ray );
}
@ -124,8 +147,49 @@ RAYPACKET::RAYPACKET( const CCAMERA &aCamera,
wxASSERT( i == RAYPACKET_RAYS_PER_PACKET );
m_Frustum.GenerateFrustum( m_ray[ 0 * RAYPACKET_DIM + 0 ],
m_ray[ 0 * RAYPACKET_DIM + (RAYPACKET_DIM - 1) ],
m_ray[ (RAYPACKET_DIM - 1) * RAYPACKET_DIM + 0 ],
m_ray[ (RAYPACKET_DIM - 1) * RAYPACKET_DIM + (RAYPACKET_DIM - 1) ] );
RAYPACKET_GenerateFrustum( &m_Frustum, m_ray );
}
void RAYPACKET_InitRays( const CCAMERA &aCamera,
const SFVEC2F &aWindowsPosition,
RAY *aRayPck )
{
for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
{
for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
{
SFVEC3F rayOrigin;
SFVEC3F rayDir;
aCamera.MakeRay( SFVEC2F( aWindowsPosition.x + (float)x,
aWindowsPosition.y + (float)y ),
rayOrigin, rayDir );
aRayPck[i].Init( rayOrigin, rayDir );
}
}
}
void RAYPACKET_InitRays_with2DDisplacement( const CCAMERA &aCamera,
const SFVEC2F &aWindowsPosition,
const SFVEC2F &a2DWindowsPosDisplacementFactor,
RAY *aRayPck )
{
for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
{
for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
{
SFVEC3F rayOrigin;
SFVEC3F rayDir;
aCamera.MakeRay( SFVEC2F( aWindowsPosition.x +(float)x +
Fast_RandFloat() * a2DWindowsPosDisplacementFactor.x,
aWindowsPosition.y + (float)y +
Fast_RandFloat() * a2DWindowsPosDisplacementFactor.y ),
rayOrigin, rayDir );
aRayPck[i].Init( rayOrigin, rayDir );
}
}
}

View File

@ -55,7 +55,22 @@ struct RAYPACKET
RAYPACKET( const CCAMERA &aCamera,
const SFVEC2I &aWindowsPosition,
unsigned int aPixelMultiple );
RAYPACKET( const CCAMERA &aCamera,
const SFVEC2F &aWindowsPosition );
RAYPACKET( const CCAMERA &aCamera,
const SFVEC2F &aWindowsPosition,
const SFVEC2F &a2DWindowsPosDisplacementFactor );
};
void RAYPACKET_InitRays( const CCAMERA &aCamera,
const SFVEC2F &aWindowsPosition,
RAY *aRayPck );
void RAYPACKET_InitRays_with2DDisplacement( const CCAMERA &aCamera,
const SFVEC2F &aWindowsPosition,
const SFVEC2F &a2DWindowsPosDisplacementFactor,
RAY *aRayPck );
#endif // _RAYPACKET_H_

View File

@ -197,32 +197,36 @@ void CCAMERA::rebuildProjection()
break;
}
m_scr_nX.resize( m_windowSize.x );
m_scr_nY.resize( m_windowSize.y );
// Precalc X values for camera -> ray generation
for( unsigned int x = 0; x < (unsigned int)m_windowSize.x; ++x )
if ( (m_windowSize.x > 0) &&
(m_windowSize.y > 0) )
{
// Converts 0.0 .. 1.0
const float xNormalizedDeviceCoordinates = ( ( (float)x + 0.5f ) /
(m_windowSize.x - 0.0f) );
m_scr_nX.resize( m_windowSize.x + 1 );
m_scr_nY.resize( m_windowSize.y + 1 );
// Converts -1.0 .. 1.0
m_scr_nX[x] = 2.0f * xNormalizedDeviceCoordinates - 1.0f;
// Precalc X values for camera -> ray generation
for( unsigned int x = 0; x < (unsigned int)m_windowSize.x + 1; ++x )
{
// Converts 0.0 .. 1.0
const float xNormalizedDeviceCoordinates = ( ( (float)x + 0.5f ) /
(m_windowSize.x - 0.0f) );
// Converts -1.0 .. 1.0
m_scr_nX[x] = 2.0f * xNormalizedDeviceCoordinates - 1.0f;
}
// Precalc Y values for camera -> ray generation
for( unsigned int y = 0; y < (unsigned int)m_windowSize.y + 1 ; ++y )
{
// Converts 0.0 .. 1.0
const float yNormalizedDeviceCoordinates = ( ( (float)y + 0.5f ) /
(m_windowSize.y - 0.0f) );
// Converts -1.0 .. 1.0
m_scr_nY[y] = 2.0f * yNormalizedDeviceCoordinates - 1.0f;
}
updateFrustum();
}
// Precalc Y values for camera -> ray generation
for( unsigned int y = 0; y < (unsigned int)m_windowSize.y; ++y )
{
// Converts 0.0 .. 1.0
const float yNormalizedDeviceCoordinates = ( ( (float)y + 0.5f ) /
(m_windowSize.y - 0.0f) );
// Converts -1.0 .. 1.0
m_scr_nY[y] = 2.0f * yNormalizedDeviceCoordinates - 1.0f;
}
updateFrustum();
}
@ -264,21 +268,25 @@ void CCAMERA::updateFrustum()
m_frustum.fbl = m_frustum.fc - m_up * m_frustum.fh - m_right * m_frustum.fw;
m_frustum.fbr = m_frustum.fc - m_up * m_frustum.fh + m_right * m_frustum.fw;
// Reserve size for precalc values
m_right_nX.resize( m_windowSize.x );
m_up_nY.resize( m_windowSize.y );
if ( (m_windowSize.x > 0) &&
(m_windowSize.y > 0) )
{
// Reserve size for precalc values
m_right_nX.resize( m_windowSize.x + 1 );
m_up_nY.resize( m_windowSize.y + 1 );
// Precalc X values for camera -> ray generation
const SFVEC3F right_nw = m_right * m_frustum.nw;
// Precalc X values for camera -> ray generation
const SFVEC3F right_nw = m_right * m_frustum.nw;
for( unsigned int x = 0; x < (unsigned int)m_windowSize.x; ++x )
m_right_nX[x] = right_nw * m_scr_nX[x];
for( unsigned int x = 0; x < ((unsigned int)m_windowSize.x + 1); ++x )
m_right_nX[x] = right_nw * m_scr_nX[x];
// Precalc Y values for camera -> ray generation
const SFVEC3F up_nh = m_up * m_frustum.nh;
// Precalc Y values for camera -> ray generation
const SFVEC3F up_nh = m_up * m_frustum.nh;
for( unsigned int y = 0; y < (unsigned int)m_windowSize.y; ++y )
m_up_nY[y] = up_nh * m_scr_nY[y];
for( unsigned int y = 0; y < ((unsigned int)m_windowSize.y + 1); ++y )
m_up_nY[y] = up_nh * m_scr_nY[y];
}
}
@ -286,22 +294,53 @@ void CCAMERA::MakeRay( const SFVEC2I &aWindowPos,
SFVEC3F &aOutOrigin,
SFVEC3F &aOutDirection ) const
{
//const SFVEC2I minWindowsPos = glm::min( aWindowPos, m_windowSize );
wxASSERT( aWindowPos.x < m_windowSize.x );
wxASSERT( aWindowPos.y < m_windowSize.y );
const SFVEC2I &minWindowsPos = aWindowPos;
const SFVEC3F up_plus_right = m_up_nY[aWindowPos.y] +
m_right_nX[aWindowPos.x];
switch( m_projectionType )
{
default:
case PROJECTION_PERSPECTIVE:
aOutOrigin = m_up_nY[minWindowsPos.y] + m_right_nX[minWindowsPos.x] + m_frustum.nc;
aOutOrigin = up_plus_right + m_frustum.nc;
aOutDirection = glm::normalize( aOutOrigin - m_pos );
break;
case PROJECTION_ORTHO:
aOutOrigin = (m_up_nY[minWindowsPos.y] + m_right_nX[minWindowsPos.x]) * 0.5f +
m_frustum.nc;
aOutOrigin = up_plus_right * 0.5f + m_frustum.nc;
aOutDirection = -m_dir;
break;
}
}
void CCAMERA::MakeRay( const SFVEC2F &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const
{
wxASSERT( aWindowPos.x < (float)m_windowSize.x );
wxASSERT( aWindowPos.y < (float)m_windowSize.y );
const SFVEC2F floorWinPos_f = glm::floor( aWindowPos );
const SFVEC2I floorWinPos_i = (SFVEC2I)floorWinPos_f;
const SFVEC2F relativeWinPos = aWindowPos - floorWinPos_f;
// Note: size of vectors m_up and m_right are m_windowSize + 1
const SFVEC3F up_plus_right = m_up_nY[floorWinPos_i.y] * (1.0f - relativeWinPos.y) +
m_up_nY[floorWinPos_i.y + 1] * relativeWinPos.y +
m_right_nX[floorWinPos_i.x] * (1.0f - relativeWinPos.x) +
m_right_nX[floorWinPos_i.x + 1] * relativeWinPos.x;
switch( m_projectionType )
{
default:
case PROJECTION_PERSPECTIVE:
aOutOrigin = up_plus_right + m_frustum.nc;
aOutDirection = glm::normalize( aOutOrigin - m_pos );
break;
case PROJECTION_ORTHO:
aOutOrigin = up_plus_right * 0.5f + m_frustum.nc;
aOutDirection = -m_dir;
break;
}

View File

@ -226,6 +226,14 @@ class CCAMERA
*/
void MakeRay( const SFVEC2I &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const;
/**
* @brief MakeRay - Make a ray based on a windows screen position, it will interpolate based on the float aWindowPos
* @param aWindowPos: the windows buffer position (float value)
* @param aOutOrigin: out origin position of the ray
* @param aOutDirection: out direction
*/
void MakeRay( const SFVEC2F &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const;
/**
* @brief MakeRayAtCurrrentMousePosition - Make a ray based on the latest mouse position
* @param aOutOrigin: out origin position of the ray