34#include "../color_rgb.h"
37#include "../common_ogl/ogl_utils.h"
44 m_postShaderSsao( aCamera )
46 wxLogTrace(
m_logTrace, wxT(
"RENDER_3D_RAYTRACE::RENDER_3D_RAYTRACE" ) );
74 wxLogTrace(
m_logTrace, wxT(
"RENDER_3D_RAYTRACE::~RENDER_3D_RAYTRACE" ) );
104 glDeleteBuffers( 1, &
m_pboId );
151 bool requestRedraw =
false;
160 requestRedraw =
true;
173 if( aStatusReporter )
174 aStatusReporter->
Report(
_(
"Loading..." ) );
177 requestRedraw =
true;
178 Reload( aStatusReporter, aWarningReporter,
false );
187 requestRedraw =
true;
194 glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
195 glClearDepth( 1.0f );
196 glClearStencil( 0x00 );
197 glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
200 glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
202 glDisable( GL_STENCIL_TEST );
203 glDisable( GL_LIGHTING );
204 glDisable( GL_COLOR_MATERIAL );
205 glDisable( GL_DEPTH_TEST );
206 glDisable( GL_TEXTURE_2D );
207 glDisable( GL_BLEND );
208 glDisable( GL_MULTISAMPLE );
212 if( requestRedraw || aIsMoving || was_camera_changed )
217 if( aIsMoving || was_camera_changed )
227 glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB,
m_pboId );
230 GLubyte* ptrPBO = (GLubyte *)glMapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB,
238 glUnmapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB );
246 glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB,
m_pboId );
251 GLubyte* ptrPBO = (GLubyte *)glMapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB,
256 render( ptrPBO, aStatusReporter );
259 requestRedraw =
true;
262 glUnmapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB );
268 glClear( GL_COLOR_BUFFER_BIT );
276 glEnable( GL_BLEND );
277 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
278 glEnable( GL_ALPHA_TEST );
280 glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, 0 );
282 return requestRedraw;
301 GLubyte* tmp_ptrPBO = ptrPBO + 3;
303 for(
unsigned int i = 0; i < nPixels; ++i )
329 wxASSERT_MSG(
false, wxT(
"Invalid state on m_renderState" ) );
339 aStatusReporter->
Report( wxString::Format(
_(
"Rendering time %.3f s" ), elapsed_time ) );
348 auto startTime = std::chrono::steady_clock::now();
349 bool breakLoop =
false;
351 std::atomic<size_t> numBlocksRendered( 0 );
352 std::atomic<size_t> currentBlock( 0 );
353 std::atomic<size_t> threadsFinished( 0 );
355 size_t parallelThreadCount = std::min<size_t>(
356 std::max<size_t>( std::thread::hardware_concurrency(), 2 ),
359 for(
size_t ii = 0; ii < parallelThreadCount; ++ii )
361 std::thread t = std::thread( [&]()
363 for(
size_t iBlock = currentBlock.fetch_add( 1 );
365 iBlock = currentBlock.fetch_add( 1 ) )
367 if( !m_blockPositionsWasProcessed[iBlock] )
369 renderBlockTracing( ptrPBO, iBlock );
371 m_blockPositionsWasProcessed[iBlock] = 1;
375 if( std::chrono::duration_cast<std::chrono::milliseconds>(
376 std::chrono::steady_clock::now() - startTime ).count() > 150 )
387 while( threadsFinished < parallelThreadCount )
388 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
390 m_blockRenderProgressCount += numBlocksRendered;
392 if( aStatusReporter )
393 aStatusReporter->Report( wxString::Format(
_(
"Rendering: %.0f %%" ),
394 (
float) ( m_blockRenderProgressCount * 100 )
395 / (
float) m_blockPositions.size() ) );
399 if( m_blockRenderProgressCount >= m_blockPositions.size() )
401 if( m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing )
412#define SRGB_GAMA 2.4f
419 const float gammaCorrection = 1.0f /
SRGB_GAMA;
422 return glm::mix( glm::pow( clampedColor,
SFVEC3F(gammaCorrection) ) * 1.055f - 0.055f,
423 clampedColor * 12.92f,
424 glm::lessThan( clampedColor,
SFVEC3F(0.0031308f) ) );
434 return glm::mix( glm::pow( ( aSRGBcolor +
SFVEC3F( 0.055f ) )
435 *
SFVEC3F( 0.94786729857819905213270142180095f ),
437 aSRGBcolor *
SFVEC3F( 0.07739938080495356037151702786378f ),
438 glm::lessThanEqual( aSRGBcolor,
SFVEC3F( 0.04045f ) ) );
445 bool applyColorSpaceConversion )
454 if( applyColorSpaceConversion )
458 ptrPBO[0] = (
unsigned int) glm::clamp( (
int) (
color.r * 255 ), 0, 255 );
459 ptrPBO[1] = (
unsigned int) glm::clamp( (
int) (
color.g * 255 ), 0, 255 );
460 ptrPBO[2] = (
unsigned int) glm::clamp( (
int) (
color.b * 255 ), 0, 255 );
470 aHitPacket[i].
m_HitInfo.
m_tHit = std::numeric_limits<float>::infinity();
487 if( aHitPacket[i].m_hitresult ==
true )
489 aOutHitColor[i] =
shadeHit( bgColorY[y], aRayPkt[i], aHitPacket[i].m_HitInfo,
490 false, 0, is_testShadow );
494 aOutHitColor[i] = bgColorY[y];
512 const RAY& rayAA = aRayPck[i];
515 hitAA.
m_tHit = std::numeric_limits<float>::infinity();
520 const unsigned int idx0y1 = ( x + 0 ) +
RAYPACKET_DIM * ( y + 1 );
521 const unsigned int idx1y1 = ( x + 1 ) +
RAYPACKET_DIM * ( y + 1 );
527 unsigned int nodex1y0 = 0;
530 nodex1y0 = aHitPck_X0Y0[ i + 1 ].m_HitInfo.m_acc_node_info;
532 unsigned int nodex0y1 = 0;
535 nodex0y1 = aHitPck_X0Y0[idx0y1].m_HitInfo.m_acc_node_info;
537 unsigned int nodex1y1 = 0;
544 if( ( ( nodex0y0 == nodex1y0 ) || ( nodex1y0 == 0 ) )
545 && ( ( nodex0y0 == nodex0y1 ) || ( nodex0y1 == 0 ) )
546 && ( ( nodex0y0 == nodex1y1 ) || ( nodex1y1 == 0 ) )
547 && ( nodex0y0 == node_AA_x0y0 ) )
585 if( ( nodex1y0 != 0 ) && ( nodex0y0 != nodex1y0 ) )
588 if( ( nodex0y1 != 0 ) && ( nodex0y0 != nodex0y1 ) && ( nodex1y0 != nodex0y1 ) )
591 if( ( nodex1y1 != 0 ) && ( nodex0y0 != nodex1y1 ) && ( nodex0y1 != nodex1y1 ) &&
592 ( nodex1y0 != nodex1y1 ) )
595 if( (node_AA_x0y0 != 0 ) && ( nodex0y0 != node_AA_x0y0 ) &&
596 ( nodex0y1 != node_AA_x0y0 ) && ( nodex1y0 != node_AA_x0y0 ) &&
597 ( nodex1y1 != node_AA_x0y0 ) )
603 aOutHitColor[i] =
shadeHit( aBgColorY[y], rayAA, hitAA,
false, 0,
613 aOutHitColor[i] =
shadeHit( aBgColorY[y], rayAA, hitAA,
false, 0,
622#define DISP_FACTOR 0.075f
644 const float posYfactor = (float) ( blockPosI.y + y ) / (float)
m_windowSize.y;
658 const SFVEC3F& outColor = bgColor[y];
660 const unsigned int yBlockPos = blockPos.y + y;
678 const SFVEC3F& outColor = bgColor[y];
680 const unsigned int yConst = blockPos.x + ( ( y + blockPos.y ) *
m_realBufferSize.x );
684 GLubyte* ptr = &ptrPBO[( yConst + x ) * 4];
717 const SFVEC3F& outColor = bgColor[y];
720 hitColor_AA_X1Y1[i] = outColor;
735 SFVEC3F color_average = ( hitColor_X0Y0[i] + hitColor_AA_X1Y1[i] ) *
SFVEC3F( 0.5f );
737 hitColor_AA_X1Y0[i] = color_average;
738 hitColor_AA_X0Y1[i] = color_average;
739 hitColor_AA_X0Y1_half[i] = color_average;
765 blockRayPck_AA_X1Y1_half, hitColor_AA_X0Y1_half );
770 hitColor_X0Y0[i] = ( hitColor_X0Y0[i] + hitColor_AA_X1Y1[i] + hitColor_AA_X1Y0[i] +
771 hitColor_AA_X0Y1[i] + hitColor_AA_X0Y1_half[i] ) *
777 GLubyte* ptr = &ptrPBO[( blockPos.x + ( blockPos.y *
m_realBufferSize.x ) ) * 4];
792 const SFVEC3F& hColor = hitColor_X0Y0[i];
794 if( hitPacket_X0Y0[i].m_hitresult ==
true )
840 if( aStatusReporter )
841 aStatusReporter->
Report(
_(
"Rendering: Post processing shader" ) );
845 std::atomic<size_t> nextBlock( 0 );
846 std::atomic<size_t> threadsFinished( 0 );
848 size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
850 for(
size_t ii = 0; ii < parallelThreadCount; ++ii )
852 std::thread t = std::thread( [&]()
855 y = nextBlock.fetch_add( 1 ) )
857 SFVEC3F* ptr = &m_shaderBuffer[ y * m_realBufferSize.x ];
859 for( signed int x = 0; x < (int)m_realBufferSize.x; ++x )
861 *ptr = m_postShaderSsao.Shade( SFVEC2I( x, y ) );
872 while( threadsFinished < parallelThreadCount )
873 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
893 std::atomic<size_t> nextBlock( 0 );
894 std::atomic<size_t> threadsFinished( 0 );
896 size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
898 for(
size_t ii = 0; ii < parallelThreadCount; ++ii )
900 std::thread t = std::thread( [&]()
903 y = nextBlock.fetch_add( 1 ) )
905 GLubyte* ptr = &ptrPBO[ y * m_realBufferSize.x * 4 ];
907 for( signed int x = 0; x < (int)m_realBufferSize.x; ++x )
909 const SFVEC3F bluredShadeColor = m_postShaderSsao.Blur( SFVEC2I( x, y ) );
912 const SFVEC3F originColor = convertLinearToSRGB(
913 m_postShaderSsao.GetColorAtNotProtected( SFVEC2I( x, y ) ) );
915 const SFVEC3F originColor =
916 m_postShaderSsao.GetColorAtNotProtected( SFVEC2I( x, y ) );
918 const SFVEC3F shadedColor = m_postShaderSsao.ApplyShadeColor(
919 SFVEC2I( x, y ), originColor, bluredShadeColor );
921 renderFinalColor( ptr, shadedColor, false );
933 while( threadsFinished < parallelThreadCount )
934 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
949 std::atomic<size_t> nextBlock( 0 );
950 std::atomic<size_t> threadsFinished( 0 );
952 size_t parallelThreadCount = std::min<size_t>(
953 std::max<size_t>( std::thread::hardware_concurrency(), 2 ),
956 for(
size_t ii = 0; ii < parallelThreadCount; ++ii )
958 std::thread t = std::thread( [&]()
961 iBlock = nextBlock.fetch_add( 1 ) )
963 const SFVEC2UI& windowPosUI = m_blockPositionsFast[ iBlock ];
964 const SFVEC2I windowsPos = SFVEC2I( windowPosUI.x + m_xoffset,
965 windowPosUI.y + m_yoffset );
967 RAYPACKET blockPacket( m_camera, windowsPos, 4 );
969 HITINFO_PACKET hitPacket[RAYPACKET_RAYS_PER_PACKET];
972 for( HITINFO_PACKET& packet : hitPacket )
974 packet.m_HitInfo.m_tHit = std::numeric_limits<float>::infinity();
975 packet.m_HitInfo.m_acc_node_info = 0;
976 packet.m_hitresult = false;
987 const float posYfactor =
988 (float) ( windowsPos.y + y * 4.0f ) / (float) m_windowSize.y;
990 bgColor[y] = (SFVEC3F) m_boardAdapter.m_BgColorTop * SFVEC3F( posYfactor )
991 + (SFVEC3F) m_boardAdapter.m_BgColorBot
992 * ( SFVEC3F( 1.0f ) - SFVEC3F( posYfactor ) );
999 const SFVEC3F bhColorY = bgColor[i / RAYPACKET_DIM];
1001 if( hitPacket[i].m_hitresult == true )
1003 const SFVEC3F hitColor = shadeHit( bhColorY, blockPacket.m_ray[i],
1004 hitPacket[i].m_HitInfo, false,
1007 hitColorShading[i] = COLOR_RGB( hitColor );
1010 hitColorShading[i] = bhColorY;
1017 const SFVEC3F bgColorY = bgColor[y];
1038 const unsigned int iLT = ( ( x + 0 ) +
RAYPACKET_DIM * ( y + 0 ) );
1039 const unsigned int iRT = ( ( x + 1 ) +
RAYPACKET_DIM * ( y + 0 ) );
1040 const unsigned int iLB = ( ( x + 0 ) +
RAYPACKET_DIM * ( y + 1 ) );
1041 const unsigned int iRB = ( ( x + 1 ) +
RAYPACKET_DIM * ( y + 1 ) );
1044 const COLOR_RGB& cLT = hitColorShading[ iLT ];
1045 const COLOR_RGB& cRT = hitColorShading[ iRT ];
1046 const COLOR_RGB& cLB = hitColorShading[ iLB ];
1047 const COLOR_RGB& cRB = hitColorShading[ iRB ];
1052 const SFVEC3F& oriLT = blockPacket.m_ray[ iLT ].m_Origin;
1053 const SFVEC3F& oriRB = blockPacket.m_ray[ iRB ].m_Origin;
1055 const SFVEC3F& dirLT = blockPacket.m_ray[ iLT ].m_Dir;
1056 const SFVEC3F& dirRB = blockPacket.m_ray[ iRB ].m_Dir;
1062 centerHitInfo.
m_tHit = std::numeric_limits<float>::infinity();
1064 bool hittedC =
false;
1066 if( ( hitPacket[iLT].m_hitresult ==
true )
1067 || ( hitPacket[iRT].m_hitresult ==
true )
1068 || ( hitPacket[iLB].m_hitresult ==
true )
1069 || ( hitPacket[iRB].m_hitresult ==
true ) )
1071 oriC = ( oriLT + oriRB ) * 0.5f;
1072 dirC = glm::normalize( ( dirLT + dirRB ) * 0.5f );
1076 centerRay.
Init( oriC, dirC );
1078 const unsigned int nodeLT = hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
1079 const unsigned int nodeRT = hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
1080 const unsigned int nodeLB = hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
1081 const unsigned int nodeRB = hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
1087 if( ( nodeRT != 0 ) && ( nodeRT != nodeLT ) )
1091 if( ( nodeLB != 0 ) && ( nodeLB != nodeLT ) && ( nodeLB != nodeRT ) )
1095 if( ( nodeRB != 0 ) && ( nodeRB != nodeLB ) && ( nodeRB != nodeLT )
1096 && ( nodeRB != nodeRT ) )
1103 false, 0,
false ) );
1107 centerHitInfo.
m_tHit = std::numeric_limits<float>::infinity();
1112 false, 0,
false ) );
1119 const SFVEC3F& oriRT = blockPacket.m_ray[ iRT ].m_Origin;
1120 const SFVEC3F& dirRT = blockPacket.m_ray[ iRT ].m_Dir;
1126 rayLRT.
Init( ( oriLT + oriRT ) * 0.5f,
1127 glm::normalize( ( dirLT + dirRT ) * 0.5f ) );
1130 hitInfoLRT.
m_tHit = std::numeric_limits<float>::infinity();
1132 if( hitPacket[iLT].m_hitresult && hitPacket[iRT].m_hitresult
1133 && ( hitPacket[iLT].m_HitInfo.pHitObject
1134 == hitPacket[iRT].m_HitInfo.pHitObject ) )
1136 hitInfoLRT.
pHitObject = hitPacket[ iLT ].m_HitInfo.pHitObject;
1137 hitInfoLRT.
m_tHit = ( hitPacket[ iLT ].m_HitInfo.m_tHit +
1138 hitPacket[ iRT ].m_HitInfo.m_tHit ) * 0.5f;
1140 glm::normalize( ( hitPacket[ iLT ].m_HitInfo.m_HitNormal +
1141 hitPacket[ iRT ].m_HitInfo.m_HitNormal ) * 0.5f );
1150 if( hitPacket[ iLT ].m_hitresult || hitPacket[ iRT ].m_hitresult )
1152 const unsigned int nodeLT =
1153 hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
1154 const unsigned int nodeRT =
1155 hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
1157 bool hittedLRT =
false;
1163 if( ( nodeRT != 0 ) && ( nodeRT != nodeLT ) )
1169 false, 0,
false ) );
1172 hitInfoLRT.
m_tHit = std::numeric_limits<float>::infinity();
1192 const SFVEC3F &oriLB = blockPacket.m_ray[ iLB ].m_Origin;
1193 const SFVEC3F& dirLB = blockPacket.m_ray[ iLB ].m_Dir;
1197 rayLTB.
Init( ( oriLT + oriLB ) * 0.5f,
1198 glm::normalize( ( dirLT + dirLB ) * 0.5f ) );
1201 hitInfoLTB.
m_tHit = std::numeric_limits<float>::infinity();
1203 if( hitPacket[ iLT ].m_hitresult && hitPacket[ iLB ].m_hitresult
1204 && ( hitPacket[ iLT ].m_HitInfo.pHitObject ==
1205 hitPacket[ iLB ].m_HitInfo.pHitObject ) )
1207 hitInfoLTB.
pHitObject = hitPacket[ iLT ].m_HitInfo.pHitObject;
1208 hitInfoLTB.
m_tHit = ( hitPacket[ iLT ].m_HitInfo.m_tHit +
1209 hitPacket[ iLB ].m_HitInfo.m_tHit ) * 0.5f;
1211 glm::normalize( ( hitPacket[ iLT ].m_HitInfo.m_HitNormal +
1212 hitPacket[ iLB ].m_HitInfo.m_HitNormal ) * 0.5f );
1220 if( hitPacket[ iLT ].m_hitresult || hitPacket[ iLB ].m_hitresult )
1222 const unsigned int nodeLT =
1223 hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
1224 const unsigned int nodeLB =
1225 hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
1227 bool hittedLTB =
false;
1233 if( ( nodeLB != 0 ) && ( nodeLB != nodeLT ) )
1239 false, 0,
false ) );
1242 hitInfoLTB.
m_tHit = std::numeric_limits<float>::infinity();
1262 rayRTB.
Init( ( oriRT + oriRB ) * 0.5f,
1263 glm::normalize( ( dirRT + dirRB ) * 0.5f ) );
1266 hitInfoRTB.
m_tHit = std::numeric_limits<float>::infinity();
1268 if( hitPacket[ iRT ].m_hitresult && hitPacket[ iRB ].m_hitresult
1269 && ( hitPacket[ iRT ].m_HitInfo.pHitObject ==
1270 hitPacket[ iRB ].m_HitInfo.pHitObject ) )
1272 hitInfoRTB.
pHitObject = hitPacket[ iRT ].m_HitInfo.pHitObject;
1274 hitInfoRTB.
m_tHit = ( hitPacket[ iRT ].m_HitInfo.m_tHit +
1275 hitPacket[ iRB ].m_HitInfo.m_tHit ) * 0.5f;
1278 glm::normalize( ( hitPacket[ iRT ].m_HitInfo.m_HitNormal +
1279 hitPacket[ iRB ].m_HitInfo.m_HitNormal ) * 0.5f );
1288 if( hitPacket[ iRT ].m_hitresult || hitPacket[ iRB ].m_hitresult )
1290 const unsigned int nodeRT =
1291 hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
1292 const unsigned int nodeRB =
1293 hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
1295 bool hittedRTB =
false;
1301 if( ( nodeRB != 0 ) && ( nodeRB != nodeRT ) )
1312 hitInfoRTB.
m_tHit = std::numeric_limits<float>::infinity();
1316 false, 0,
false ) );
1326 const SFVEC3F& oriLB = blockPacket.m_ray[ iLB ].m_Origin;
1327 const SFVEC3F& dirLB = blockPacket.m_ray[ iLB ].m_Dir;
1331 rayLRB.
Init( ( oriLB + oriRB ) * 0.5f,
1332 glm::normalize( ( dirLB + dirRB ) * 0.5f ) );
1335 hitInfoLRB.
m_tHit = std::numeric_limits<float>::infinity();
1337 if( hitPacket[iLB].m_hitresult && hitPacket[iRB].m_hitresult
1338 && ( hitPacket[iLB].m_HitInfo.pHitObject ==
1339 hitPacket[iRB].m_HitInfo.pHitObject ) )
1341 hitInfoLRB.
pHitObject = hitPacket[ iLB ].m_HitInfo.pHitObject;
1343 hitInfoLRB.
m_tHit = ( hitPacket[ iLB ].m_HitInfo.m_tHit +
1344 hitPacket[ iRB ].m_HitInfo.m_tHit ) * 0.5f;
1347 glm::normalize( ( hitPacket[ iLB ].m_HitInfo.m_HitNormal +
1348 hitPacket[ iRB ].m_HitInfo.m_HitNormal ) * 0.5f );
1357 if( hitPacket[ iLB ].m_hitresult || hitPacket[ iRB ].m_hitresult )
1359 const unsigned int nodeLB =
1360 hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
1361 const unsigned int nodeRB =
1362 hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
1364 bool hittedLRB =
false;
1370 if( ( nodeRB != 0 ) && ( nodeRB != nodeLB ) )
1377 false, 0,
false ) );
1381 hitInfoLRB.
m_tHit = std::numeric_limits<float>::infinity();
1385 false, 0,
false ) );
1395 if( hitPacket[ iLT ].m_hitresult || hittedC )
1399 rayLTC.
Init( ( oriLT + oriC ) * 0.5f,
1400 glm::normalize( ( dirLT + dirC ) * 0.5f ) );
1403 hitInfoLTC.
m_tHit = std::numeric_limits<float>::infinity();
1405 bool hitted =
false;
1409 else if( hitPacket[ iLT ].m_hitresult )
1410 hitted = hitPacket[ iLT ].m_HitInfo.pHitObject->Intersect(
1422 if( hitPacket[ iRT ].m_hitresult || hittedC )
1426 rayRTC.
Init( ( oriRT + oriC ) * 0.5f,
1427 glm::normalize( ( dirRT + dirC ) * 0.5f ) );
1430 hitInfoRTC.
m_tHit = std::numeric_limits<float>::infinity();
1432 bool hitted =
false;
1436 else if( hitPacket[ iRT ].m_hitresult )
1437 hitted = hitPacket[ iRT ].m_HitInfo.pHitObject->Intersect( rayRTC,
1448 if( hitPacket[ iLB ].m_hitresult || hittedC )
1452 rayLBC.
Init( ( oriLB + oriC ) * 0.5f,
1453 glm::normalize( ( dirLB + dirC ) * 0.5f ) );
1456 hitInfoLBC.
m_tHit = std::numeric_limits<float>::infinity();
1458 bool hitted =
false;
1462 else if( hitPacket[ iLB ].m_hitresult )
1463 hitted = hitPacket[ iLB ].m_HitInfo.pHitObject->Intersect( rayLBC,
1474 if( hitPacket[ iRB ].m_hitresult || hittedC )
1478 rayRBC.
Init( ( oriRB + oriC ) * 0.5f,
1479 glm::normalize( ( dirRB + dirC ) * 0.5f ) );
1482 hitInfoRBC.
m_tHit = std::numeric_limits<float>::infinity();
1484 bool hitted =
false;
1488 else if( hitPacket[ iRB ].m_hitresult )
1489 hitted = hitPacket[ iRB ].m_HitInfo.pHitObject->Intersect( rayRBC,
1534 while( threadsFinished < parallelThreadCount )
1535 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
1539#define USE_EXPERIMENTAL_SOFT_SHADOWS 1
1542 bool aIsInsideObject,
unsigned int aRecursiveLevel,
1543 bool is_testShadow )
const
1546 wxASSERT( objMaterial !=
nullptr );
1550 if( aRecursiveLevel > 7 )
1559#if USE_EXPERIMENTAL_SOFT_SHADOWS
1563 float shadow_att_factor_sum = 0.0f;
1565 unsigned int nr_lights_that_can_cast_shadows = 0;
1573 light->GetLightParameters( hitPoint, vectorToLight, colorOfLight, distToLight );
1576 colorOfLight =
SFVEC3F( 1.0f );
1578 const float NdotL = glm::dot( aHitInfo.
m_HitNormal, vectorToLight );
1582 if( NdotL >= FLT_EPSILON )
1584 float shadow_att_factor_light = 1.0f;
1586 if( is_testShadow && light->GetCastShadows() )
1588 nr_lights_that_can_cast_shadows++;
1589#if USE_EXPERIMENTAL_SOFT_SHADOWS
1591 if( aRecursiveLevel > 0 )
1595 rayToLight.
Init( hitPoint, vectorToLight );
1600 shadow_att_factor_light = 0.0f;
1602#if USE_EXPERIMENTAL_SOFT_SHADOWS
1606 const unsigned int shadow_number_of_samples =
1608 const float shadow_inc_factor = 1.0f / (float) ( shadow_number_of_samples );
1610 for(
unsigned int i = 0; i < shadow_number_of_samples; ++i )
1616 rayToLight.
Init( hitPoint, vectorToLight );
1621 const SFVEC3F disturbed_vector_to_light =
1622 glm::normalize( vectorToLight + unifVector *
1625 rayToLight.
Init( hitPoint, disturbed_vector_to_light );
1633 shadow_att_factor_light -= shadow_inc_factor;
1638 shadow_att_factor_sum += shadow_att_factor_light;
1641 outColor += objMaterial->
Shade( aRay, aHitInfo, NdotL, diffuseColorObj, vectorToLight,
1642 colorOfLight, shadow_att_factor_light );
1651 if( nr_lights_that_can_cast_shadows > 0 )
1654 shadow_att_factor_sum / (
float) ( nr_lights_that_can_cast_shadows * 1.0f ), 0.0f );
1662 outColor = glm::min( outColor,
SFVEC3F( 1.0f ) );
1669 && ( aRecursiveLevel < objMaterial->GetReflectionRecursionCount() ) )
1671 const unsigned int reflection_number_of_samples =
1679 for(
unsigned int i = 0; i < reflection_number_of_samples; ++i )
1685 reflectedRay.
Init( hitPoint, reflectVector );
1690 const SFVEC3F random_reflectVector =
1691 glm::normalize( reflectVector +
1695 reflectedRay.
Init( hitPoint, random_reflectVector );
1699 reflectedHit.
m_tHit = std::numeric_limits<float>::infinity();
1704 shadeHit( aBgColor, reflectedRay, reflectedHit,
false,
1705 aRecursiveLevel + 1, is_testShadow ) *
1708 (1.0f / ( 1.0f + 0.75f * reflectedHit.
m_tHit *
1709 reflectedHit.
m_tHit) ) );
1713 outColor += (sum_color /
SFVEC3F( (
float)reflection_number_of_samples) );
1722 const float airIndex = 1.000293f;
1723 const float glassIndex = 1.49f;
1724 const float air_over_glass = airIndex / glassIndex;
1725 const float glass_over_air = glassIndex / airIndex;
1727 const float refractionRatio = aIsInsideObject?glass_over_air:air_over_glass;
1739 const unsigned int refractions_number_of_samples =
1744 for(
unsigned int i = 0; i < refractions_number_of_samples; ++i )
1750 refractedRay.
Init( startPoint, refractedVector );
1755 const SFVEC3F randomizeRefractedVector =
1756 glm::normalize( refractedVector +
1760 refractedRay.
Init( startPoint, randomizeRefractedVector );
1764 refractedHit.
m_tHit = std::numeric_limits<float>::infinity();
1766 SFVEC3F refractedColor = aBgColor;
1770 refractedColor =
shadeHit( aBgColor, refractedRay, refractedHit,
1771 !aIsInsideObject, aRecursiveLevel + 1,
false );
1774 (1.0f - objTransparency ) *
1778 const SFVEC3F transparency = 1.0f / ( absorbance + 1.0f );
1780 sum_color += refractedColor * transparency;
1784 sum_color += refractedColor;
1788 outColor = outColor * ( 1.0f - objTransparency ) + objTransparency * sum_color
1789 /
SFVEC3F( (
float) refractions_number_of_samples );
1793 outColor = outColor * ( 1.0f - objTransparency ) + objTransparency * aBgColor;
1810 if( GLEW_ARB_pixel_buffer_object )
1826 glGenBuffersARB( 1, &
m_pboId );
1827 glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB,
m_pboId );
1828 glBufferDataARB( GL_PIXEL_UNPACK_BUFFER_ARB,
m_pboDataSize, 0, GL_STREAM_DRAW_ARB );
1829 glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, 0 );
1832 wxT(
"RENDER_3D_RAYTRACE:: GLEW_ARB_pixel_buffer_object is supported" ) );
1847 const float dx = (float) a.x - (
float) b.x;
1848 const float dy = (float) a.y - (
float) b.y;
1849 return hypotf( dx, dy );
1905 for(
int x = 0; x < blocks_x; ++x )
1907 for(
int y = 0; y < blocks_y; ++y )
1916 float distanceA = distance( a, center );
1917 float distanceB = distance( b, center );
1919 if( distanceA != distanceB )
1920 return distanceA < distanceB;
1939 hitInfo.
m_tHit = std::numeric_limits<float>::infinity();
Defines math related functions.
Defines math related functions.
bool Refract(const SFVEC3F &aInVector, const SFVEC3F &aNormal, float aRin_over_Rout, SFVEC3F &aOutVector)
Based on: https://github.com/mmp/pbrt-v3/blob/master/src/core/reflection.h See also: http://www....
SFVEC3F UniformRandomHemisphereDirection()
virtual bool Intersect(const RAY &aRay, HITINFO &aHitInfo) const =0
virtual bool IntersectP(const RAY &aRay, float aMaxDistance) const =0
Helper class to handle information needed to display 3D board.
SFVEC4F m_BgColorTop
background top color
float GetNonCopperLayerThickness() const noexcept
Get the non copper layers thickness (in 3D units).
EDA_3D_VIEWER_SETTINGS * m_Cfg
SFVEC4F m_BgColorBot
background bottom color
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
A class used to derive camera objects from.
const SFVEC3F & GetDir() const
void SetDirection(const SFVEC3F &aDir)
Set directional light orientation.
Implement a canvas based on a wxGLCanvas.
A base light class to derive to implement other light classes.
Base material class that can be used to derive other material implementations.
float GetAbsorvance() const
virtual SFVEC3F Shade(const RAY &aRay, const HITINFO &aHitInfo, float NdotL, const SFVEC3F &aDiffuseObjColor, const SFVEC3F &aDirToLight, const SFVEC3F &aLightColor, float aShadowAttenuationFactor) const =0
Shade an intersection point.
const SFVEC3F & GetAmbientColor() const
unsigned int GetRefractionRayCount() const
unsigned int GetRefractionRecursionCount() const
const SFVEC3F & GetSpecularColor() const
const SFVEC3F & GetEmissiveColor() const
float GetReflection() const
unsigned int GetReflectionRayCount() const
virtual SFVEC3F GetDiffuseColor(const HITINFO &aHitInfo) const =0
BOARD_ITEM * GetBoardItem() const
virtual bool Intersect(const RAY &aRay, HITINFO &aHitInfo) const =0
float GetModelTransparency() const
const MATERIAL * GetMaterial() const
void SetShadedBuffer(SFVEC3F *aShadedBuffer)
void SetShadowsEnabled(bool aIsShadowsEnabled)
void UpdateSize(const SFVEC2UI &aSize)
void SetPixelData(unsigned int x, unsigned int y, const SFVEC3F &aNormal, const SFVEC3F &aColor, const SFVEC3F &aHitPosition, float aDepth, float aShadowAttFactor)
This is a base class to hold data and functions for render targets.
CAMERA & m_camera
Flag if the opengl specific for this render was already initialized.
std::unique_ptr< BUSY_INDICATOR > CreateBusyIndicator() const
Return a created busy indicator, if a factory has been set, else a null pointer.
bool m_reloadRequested
The window size that this camera is working.
bool m_is_opengl_initialized
BOARD_ADAPTER & m_boardAdapter
DIRECTIONAL_LIGHT * m_cameraLight
bool m_openglSupportsVertexBufferObjects
unsigned int m_converted2dRoundSegmentCount
std::vector< SFVEC2UI > m_blockPositionsFast
SFVEC2UI m_realBufferSize
int GetWaitForEditingTimeOut() override
Give the interface the time (in ms) that it should wait for editing or movements before (this works f...
void restartRenderState()
HITINFO_PACKET * m_firstHitinfo
void initializeNewWindowSize()
POST_SHADER_SSAO m_postShaderSsao
unsigned long int m_renderStartTime
Time that the render starts.
void SetCurWindowSize(const wxSize &aSize) override
Before each render, the canvas will tell the render what is the size of its windows,...
RENDER_3D_RAYTRACE(EDA_3D_CANVAS *aCanvas, BOARD_ADAPTER &aAdapter, CAMERA &aCamera)
BOARD_ITEM * IntersectBoardItem(const RAY &aRay)
CONTAINER_2D * m_outlineBoard2dObjects
std::vector< SFVEC2UI > m_blockPositions
Flag if a position was already processed (cleared each new render).
wxSize m_oldWindowsSize
Encode Morton code positions.
ACCELERATOR_3D * m_accelerator
unsigned int m_convertedDummyBlockCount
void postProcessShading(GLubyte *ptrPBO, REPORTER *aStatusReporter)
size_t m_blockRenderProgressCount
Save the number of blocks progress of the render.
void renderTracing(GLubyte *ptrPBO, REPORTER *aStatusReporter)
SFVEC3F shadeHit(const SFVEC3F &aBgColor, const RAY &aRay, HITINFO &aHitInfo, bool aIsInsideObject, unsigned int aRecursiveLevel, bool is_testShadow) const
SFVEC3F m_backgroundColorTop
void renderFinalColor(GLubyte *ptrPBO, const SFVEC3F &rgbColor, bool applyColorSpaceConversion)
std::vector< int > m_blockPositionsWasProcessed
Encode the Morton code positions (on fast preview mode).
void renderBlockTracing(GLubyte *ptrPBO, signed int iBlock)
void initializeBlockPositions()
void postProcessBlurFinish(GLubyte *ptrPBO, REPORTER *aStatusReporter)
void render(GLubyte *ptrPBO, REPORTER *aStatusReporter)
SFVEC2UI m_fastPreviewModeSize
SFVEC3F m_backgroundColorBottom
Used to see if the windows size changed.
RT_RENDER_STATE m_renderState
State used on quality render.
void renderRayPackets(const SFVEC3F *bgColorY, const RAY *aRayPkt, HITINFO_PACKET *aHitPacket, bool is_testShadow, SFVEC3F *aOutHitColor)
std::list< LIGHT * > m_lights
void renderPreview(GLubyte *ptrPBO)
void Reload(REPORTER *aStatusReporter, REPORTER *aWarningReporter, bool aOnlyLoadCopperAndShapes)
void renderAntiAliasPackets(const SFVEC3F *aBgColorY, const HITINFO_PACKET *aHitPck_X0Y0, const HITINFO_PACKET *aHitPck_AA_X1Y1, const RAY *aRayPck, SFVEC3F *aOutHitColor)
BVH_CONTAINER_2D * m_antioutlineBoard2dObjects
bool Redraw(bool aIsMoving, REPORTER *aStatusReporter, REPORTER *aWarningReporter) override
Redraw the view.
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
COLOR_RGB BlendColor(const COLOR_RGB &aC1, const COLOR_RGB &aC2)
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.
uint32_t DecodeMorton2Y(uint32_t code)
uint32_t DecodeMorton2X(uint32_t code)
Implements Morton Codes https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/ http://www....
void OglDrawBackground(const SFVEC3F &aTopColor, const SFVEC3F &aBotColor)
unsigned GetRunningMicroSecs()
An alternate way to calculate an elapsed time (in microsecondes) to class PROF_COUNTER.
void RAYPACKET_InitRays_with2DDisplacement(const CAMERA &aCamera, const SFVEC2F &aWindowsPosition, const SFVEC2F &a2DWindowsPosDisplacementFactor, RAY *aRayPck)
#define RAYPACKET_INVMASK
#define RAYPACKET_RAYS_PER_PACKET
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
static void SetPixel(GLubyte *p, const COLOR_RGB &v)
static void HITINFO_PACKET_init(HITINFO_PACKET *aHitPacket)
static SFVEC3F convertLinearToSRGB(const SFVEC3F &aRGBcolor)
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
@ RT_RENDER_STATE_POST_PROCESS_SHADE
@ RT_RENDER_STATE_POST_PROCESS_BLUR_AND_FINISH
@ RT_RENDER_STATE_TRACING
bool raytrace_post_processing
float raytrace_spread_shadows
bool raytrace_reflections
float raytrace_spread_reflections
int raytrace_nrsamples_shadows
bool raytrace_refractions
float raytrace_spread_refractions
bool raytrace_anti_aliasing
Stores the hit information of a ray with a point on the surface of a object.
unsigned int m_acc_node_info
( 4) The acc stores here the node that it hits
float m_tHit
( 4) distance
const OBJECT_3D * pHitObject
( 4) Object that was hitted
float m_ShadowFactor
( 4) Shadow attenuation (1.0 no shadow, 0.0f darkness)
SFVEC3F m_HitNormal
(12) normal at the hit point
SFVEC3F m_HitPoint
(12) hit position
RAY m_ray[RAYPACKET_RAYS_PER_PACKET]
void Init(const SFVEC3F &o, const SFVEC3F &d)
SFVEC3F at(float t) const