32#include "../color_rgba.h"
50 const float gammaCorrection = 1.0f /
SRGB_GAMA;
53 return glm::mix( glm::pow( clampedColor,
SFVEC3F(gammaCorrection) ) * 1.055f - 0.055f,
54 clampedColor * 12.92f,
55 glm::lessThan( clampedColor,
SFVEC3F(0.0031308f) ) );
71 return glm::mix( glm::pow( ( aSRGBcolor +
SFVEC3F( 0.055f ) )
72 *
SFVEC3F( 0.94786729857819905213270142180095f ),
74 aSRGBcolor *
SFVEC3F( 0.07739938080495356037151702786378f ),
75 glm::lessThanEqual( aSRGBcolor,
SFVEC3F( 0.04045f ) ) );
89 m_postShaderSsao( aCamera )
91 wxLogTrace(
m_logTrace, wxT(
"RENDER_3D_RAYTRACE_BASE::RENDER_3D_RAYTRACE_BASE" ) );
119 wxLogTrace(
m_logTrace, wxT(
"RENDER_3D_RAYTRACE_BASE::~RENDER_3D_RAYTRACE_BASE" ) );
181 return SFVEC4F( aInput.r * aInput.a, aInput.g * aInput.a, aInput.b * aInput.a, aInput.a );
200 uint8_t* tmp_ptrPBO = ptrPBO + 3;
202 for(
unsigned int i = 0; i < nPixels; ++i )
230 wxASSERT_MSG(
false, wxT(
"Invalid state on m_renderState" ) );
240 aStatusReporter->
Report( wxString::Format(
_(
"Rendering time %.3f s" ), elapsed_time ) );
249 auto startTime = std::chrono::steady_clock::now();
250 std::atomic<size_t> numBlocksRendered( 0 );
251 std::atomic<size_t> currentBlock( 0 );
256 auto processBlocks = [&]()
258 for(
size_t iBlock = currentBlock.fetch_add( 1 );
260 iBlock = currentBlock.fetch_add( 1 ) )
269 auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(
270 std::chrono::steady_clock::now() - startTime );
272 if( diff.count() > timeLimit )
277 BS::multi_future<void> futures;
279 for(
size_t i = 0; i <
tp.get_thread_count(); ++i )
280 futures.push_back(
tp.submit( processBlocks ) );
286 if( aStatusReporter )
287 aStatusReporter->
Report( wxString::Format(
_(
"Rendering: %.0f %%" ),
304 bool applyColorSpaceConversion )
313 if( applyColorSpaceConversion )
317 ptrPBO[0] = (
unsigned int) glm::clamp( (
int) (
color.r * 255 ), 0, 255 );
318 ptrPBO[1] = (
unsigned int) glm::clamp( (
int) (
color.g * 255 ), 0, 255 );
319 ptrPBO[2] = (
unsigned int) glm::clamp( (
int) (
color.b * 255 ), 0, 255 );
320 ptrPBO[3] = (
unsigned int) glm::clamp( (
int) (
color.a * 255 ), 0, 255 );
329 aHitPacket[i].
m_HitInfo.
m_tHit = std::numeric_limits<float>::infinity();
346 if( aHitPacket[i].m_hitresult ==
true )
348 aOutHitColor[i] =
shadeHit( bgColorY[y], aRayPkt[i], aHitPacket[i].m_HitInfo,
349 false, 0, is_testShadow );
353 aOutHitColor[i] = bgColorY[y];
371 const RAY& rayAA = aRayPck[i];
374 hitAA.
m_tHit = std::numeric_limits<float>::infinity();
379 const unsigned int idx0y1 = ( x + 0 ) +
RAYPACKET_DIM * ( y + 1 );
380 const unsigned int idx1y1 = ( x + 1 ) +
RAYPACKET_DIM * ( y + 1 );
386 unsigned int nodex1y0 = 0;
389 nodex1y0 = aHitPck_X0Y0[i + 1].m_HitInfo.m_acc_node_info;
391 unsigned int nodex0y1 = 0;
394 nodex0y1 = aHitPck_X0Y0[idx0y1].m_HitInfo.m_acc_node_info;
396 unsigned int nodex1y1 = 0;
403 if( ( ( nodex0y0 == nodex1y0 ) || ( nodex1y0 == 0 ) )
404 && ( ( nodex0y0 == nodex0y1 ) || ( nodex0y1 == 0 ) )
405 && ( ( nodex0y0 == nodex1y1 ) || ( nodex1y1 == 0 ) )
406 && ( nodex0y0 == node_AA_x0y0 ) )
444 if( ( nodex1y0 != 0 ) && ( nodex0y0 != nodex1y0 ) )
447 if( ( nodex0y1 != 0 ) && ( nodex0y0 != nodex0y1 ) && ( nodex1y0 != nodex0y1 ) )
450 if( ( nodex1y1 != 0 ) && ( nodex0y0 != nodex1y1 ) && ( nodex0y1 != nodex1y1 ) &&
451 ( nodex1y0 != nodex1y1 ) )
454 if( (node_AA_x0y0 != 0 ) && ( nodex0y0 != node_AA_x0y0 ) &&
455 ( nodex0y1 != node_AA_x0y0 ) && ( nodex1y0 != node_AA_x0y0 ) &&
456 ( nodex1y1 != node_AA_x0y0 ) )
462 aOutHitColor[i] =
shadeHit( aBgColorY[y], rayAA, hitAA,
false, 0,
472 aOutHitColor[i] =
shadeHit( aBgColorY[y], rayAA, hitAA,
false, 0,
481#define DISP_FACTOR 0.075f
503 const float posYfactor = (float) ( blockPosI.y + y ) / (float)
m_windowSize.y;
517 const SFVEC4F& outColor = bgColor[y];
519 const unsigned int yBlockPos = blockPos.y + y;
537 const SFVEC4F& outColor = bgColor[y];
539 const unsigned int yConst = blockPos.x + ( ( y + blockPos.y ) *
m_realBufferSize.x );
543 uint8_t* ptr = &ptrPBO[( yConst + x ) * 4];
576 const SFVEC4F& outColor = bgColor[y];
579 hitColor_AA_X1Y1[i] = outColor;
594 SFVEC4F color_average = ( hitColor_X0Y0[i] + hitColor_AA_X1Y1[i] ) *
SFVEC4F( 0.5f );
596 hitColor_AA_X1Y0[i] = color_average;
597 hitColor_AA_X0Y1[i] = color_average;
598 hitColor_AA_X0Y1_half[i] = color_average;
624 blockRayPck_AA_X1Y1_half, hitColor_AA_X0Y1_half );
629 hitColor_X0Y0[i] = ( hitColor_X0Y0[i] + hitColor_AA_X1Y1[i] + hitColor_AA_X1Y0[i] +
630 hitColor_AA_X0Y1[i] + hitColor_AA_X0Y1_half[i] ) *
636 uint8_t* ptr = &ptrPBO[( blockPos.x + ( blockPos.y *
m_realBufferSize.x ) ) * 4];
651 const SFVEC4F& hColor = hitColor_X0Y0[i];
653 if( hitPacket_X0Y0[i].m_hitresult ==
true )
699 if( aStatusReporter )
700 aStatusReporter->
Report(
_(
"Rendering: Post processing shader" ) );
704 std::atomic<size_t> nextBlock( 0 );
705 std::atomic<size_t> threadsFinished( 0 );
707 size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
709 for(
size_t ii = 0; ii < parallelThreadCount; ++ii )
711 std::thread t = std::thread( [&]()
714 y = nextBlock.fetch_add( 1 ) )
716 SFVEC3F* ptr = &m_shaderBuffer[ y * m_realBufferSize.x ];
718 for( signed int x = 0; x < (int)m_realBufferSize.x; ++x )
720 *ptr = m_postShaderSsao.Shade( SFVEC2I( x, y ) );
731 while( threadsFinished < parallelThreadCount )
732 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
753 std::atomic<size_t> nextBlock( 0 );
754 std::atomic<size_t> threadsFinished( 0 );
756 size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
758 for(
size_t ii = 0; ii < parallelThreadCount; ++ii )
760 std::thread t = std::thread( [&]()
763 y = nextBlock.fetch_add( 1 ) )
765 uint8_t* ptr = &ptrPBO[ y * m_realBufferSize.x * 4 ];
767 for( signed int x = 0; x < (int)m_realBufferSize.x; ++x )
769 const SFVEC3F bluredShadeColor = m_postShaderSsao.Blur( SFVEC2I( x, y ) );
772 const SFVEC4F originColor = convertLinearToSRGBA(
773 m_postShaderSsao.GetColorAtNotProtected( SFVEC2I( x, y ) ) );
775 const SFVEC4F originColor =
776 m_postShaderSsao.GetColorAtNotProtected( SFVEC2I( x, y ) );
778 const SFVEC4F shadedColor = m_postShaderSsao.ApplyShadeColor(
779 SFVEC2I( x, y ), originColor, bluredShadeColor );
781 renderFinalColor( ptr, shadedColor, false );
793 while( threadsFinished < parallelThreadCount )
794 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
813 std::atomic<size_t> nextBlock( 0 );
814 std::atomic<size_t> threadsFinished( 0 );
816 size_t parallelThreadCount = std::min<size_t>(
817 std::max<size_t>( std::thread::hardware_concurrency(), 2 ),
820 for(
size_t ii = 0; ii < parallelThreadCount; ++ii )
822 std::thread t = std::thread( [&]()
825 iBlock = nextBlock.fetch_add( 1 ) )
827 const SFVEC2UI& windowPosUI = m_blockPositionsFast[ iBlock ];
828 const SFVEC2I windowsPos = SFVEC2I( windowPosUI.x + m_xoffset,
829 windowPosUI.y + m_yoffset );
831 RAYPACKET blockPacket( m_camera, windowsPos, 4 );
833 HITINFO_PACKET hitPacket[RAYPACKET_RAYS_PER_PACKET];
836 for( HITINFO_PACKET& packet : hitPacket )
838 packet.m_HitInfo.m_tHit = std::numeric_limits<float>::infinity();
839 packet.m_HitInfo.m_acc_node_info = 0;
840 packet.m_hitresult = false;
854 const float posYfactor =
855 (float) ( windowsPos.y + y * 4.0f ) / (float) m_windowSize.y;
857 bgColor[y] = bgTopColor * SFVEC4F( posYfactor )
858 + bgBotColor * ( SFVEC4F( 1.0f ) - SFVEC4F( posYfactor ) );
865 const SFVEC4F bhColorY = bgColor[i / RAYPACKET_DIM];
867 if( hitPacket[i].m_hitresult == true )
869 const SFVEC4F hitColor = shadeHit( bhColorY, blockPacket.m_ray[i],
870 hitPacket[i].m_HitInfo, false,
873 hitColorShading[i] = COLOR_RGBA( hitColor );
876 hitColorShading[i] = bhColorY;
883 const SFVEC4F bgColorY = bgColor[y];
904 const unsigned int iLT = ( ( x + 0 ) +
RAYPACKET_DIM * ( y + 0 ) );
905 const unsigned int iRT = ( ( x + 1 ) +
RAYPACKET_DIM * ( y + 0 ) );
906 const unsigned int iLB = ( ( x + 0 ) +
RAYPACKET_DIM * ( y + 1 ) );
907 const unsigned int iRB = ( ( x + 1 ) +
RAYPACKET_DIM * ( y + 1 ) );
910 const COLOR_RGBA& cLT = hitColorShading[ iLT ];
911 const COLOR_RGBA& cRT = hitColorShading[ iRT ];
912 const COLOR_RGBA& cLB = hitColorShading[ iLB ];
913 const COLOR_RGBA& cRB = hitColorShading[ iRB ];
918 const SFVEC3F& oriLT = blockPacket.m_ray[ iLT ].m_Origin;
919 const SFVEC3F& oriRB = blockPacket.m_ray[ iRB ].m_Origin;
921 const SFVEC3F& dirLT = blockPacket.m_ray[ iLT ].m_Dir;
922 const SFVEC3F& dirRB = blockPacket.m_ray[ iRB ].m_Dir;
928 centerHitInfo.
m_tHit = std::numeric_limits<float>::infinity();
930 bool hittedC =
false;
932 if( ( hitPacket[iLT].m_hitresult ==
true )
933 || ( hitPacket[iRT].m_hitresult ==
true )
934 || ( hitPacket[iLB].m_hitresult ==
true )
935 || ( hitPacket[iRB].m_hitresult ==
true ) )
937 oriC = ( oriLT + oriRB ) * 0.5f;
938 dirC = glm::normalize( ( dirLT + dirRB ) * 0.5f );
942 centerRay.
Init( oriC, dirC );
944 const unsigned int nodeLT = hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
945 const unsigned int nodeRT = hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
946 const unsigned int nodeLB = hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
947 const unsigned int nodeRB = hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
953 if( ( nodeRT != 0 ) && ( nodeRT != nodeLT ) )
957 if( ( nodeLB != 0 ) && ( nodeLB != nodeLT ) && ( nodeLB != nodeRT ) )
961 if( ( nodeRB != 0 ) && ( nodeRB != nodeLB ) && ( nodeRB != nodeLT )
962 && ( nodeRB != nodeRT ) )
973 centerHitInfo.
m_tHit = std::numeric_limits<float>::infinity();
985 const SFVEC3F& oriRT = blockPacket.m_ray[ iRT ].m_Origin;
986 const SFVEC3F& dirRT = blockPacket.m_ray[ iRT ].m_Dir;
992 rayLRT.
Init( ( oriLT + oriRT ) * 0.5f,
993 glm::normalize( ( dirLT + dirRT ) * 0.5f ) );
996 hitInfoLRT.
m_tHit = std::numeric_limits<float>::infinity();
998 if( hitPacket[iLT].m_hitresult && hitPacket[iRT].m_hitresult
999 && ( hitPacket[iLT].m_HitInfo.pHitObject
1000 == hitPacket[iRT].m_HitInfo.pHitObject ) )
1002 hitInfoLRT.
pHitObject = hitPacket[ iLT ].m_HitInfo.pHitObject;
1003 hitInfoLRT.
m_tHit = ( hitPacket[ iLT ].m_HitInfo.m_tHit +
1004 hitPacket[ iRT ].m_HitInfo.m_tHit ) * 0.5f;
1006 glm::normalize( ( hitPacket[iLT].m_HitInfo.m_HitNormal
1007 + hitPacket[iRT].m_HitInfo.m_HitNormal )
1017 if( hitPacket[ iLT ].m_hitresult || hitPacket[ iRT ].m_hitresult )
1019 const unsigned int nodeLT =
1020 hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
1021 const unsigned int nodeRT =
1022 hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
1024 bool hittedLRT =
false;
1030 if( ( nodeRT != 0 ) && ( nodeRT != nodeLT ) )
1036 false, 0,
false ) );
1039 hitInfoLRT.
m_tHit = std::numeric_limits<float>::infinity();
1059 const SFVEC3F &oriLB = blockPacket.m_ray[ iLB ].m_Origin;
1060 const SFVEC3F& dirLB = blockPacket.m_ray[ iLB ].m_Dir;
1064 rayLTB.
Init( ( oriLT + oriLB ) * 0.5f,
1065 glm::normalize( ( dirLT + dirLB ) * 0.5f ) );
1068 hitInfoLTB.
m_tHit = std::numeric_limits<float>::infinity();
1070 if( hitPacket[ iLT ].m_hitresult && hitPacket[ iLB ].m_hitresult
1071 && ( hitPacket[ iLT ].m_HitInfo.pHitObject ==
1072 hitPacket[ iLB ].m_HitInfo.pHitObject ) )
1074 hitInfoLTB.
pHitObject = hitPacket[ iLT ].m_HitInfo.pHitObject;
1075 hitInfoLTB.
m_tHit = ( hitPacket[ iLT ].m_HitInfo.m_tHit +
1076 hitPacket[ iLB ].m_HitInfo.m_tHit ) * 0.5f;
1078 glm::normalize( ( hitPacket[iLT].m_HitInfo.m_HitNormal
1079 + hitPacket[iLB].m_HitInfo.m_HitNormal )
1082 shadeHit( bgColorY, rayLTB, hitInfoLTB,
false, 0,
false ) );
1088 if( hitPacket[ iLT ].m_hitresult || hitPacket[ iLB ].m_hitresult )
1090 const unsigned int nodeLT =
1091 hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
1092 const unsigned int nodeLB =
1093 hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
1095 bool hittedLTB =
false;
1101 if( ( nodeLB != 0 ) && ( nodeLB != nodeLT ) )
1107 false, 0,
false ) );
1110 hitInfoLTB.
m_tHit = std::numeric_limits<float>::infinity();
1130 rayRTB.
Init( ( oriRT + oriRB ) * 0.5f,
1131 glm::normalize( ( dirRT + dirRB ) * 0.5f ) );
1134 hitInfoRTB.
m_tHit = std::numeric_limits<float>::infinity();
1136 if( hitPacket[ iRT ].m_hitresult && hitPacket[ iRB ].m_hitresult
1137 && ( hitPacket[ iRT ].m_HitInfo.pHitObject ==
1138 hitPacket[ iRB ].m_HitInfo.pHitObject ) )
1140 hitInfoRTB.
pHitObject = hitPacket[ iRT ].m_HitInfo.pHitObject;
1142 hitInfoRTB.
m_tHit = ( hitPacket[ iRT ].m_HitInfo.m_tHit +
1143 hitPacket[ iRB ].m_HitInfo.m_tHit ) * 0.5f;
1146 glm::normalize( ( hitPacket[iRT].m_HitInfo.m_HitNormal
1147 + hitPacket[iRB].m_HitInfo.m_HitNormal )
1157 if( hitPacket[ iRT ].m_hitresult || hitPacket[ iRB ].m_hitresult )
1159 const unsigned int nodeRT =
1160 hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
1161 const unsigned int nodeRB =
1162 hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
1164 bool hittedRTB =
false;
1170 if( ( nodeRB != 0 ) && ( nodeRB != nodeRT ) )
1181 hitInfoRTB.
m_tHit = std::numeric_limits<float>::infinity();
1185 false, 0,
false ) );
1195 const SFVEC3F& oriLB = blockPacket.m_ray[ iLB ].m_Origin;
1196 const SFVEC3F& dirLB = blockPacket.m_ray[ iLB ].m_Dir;
1200 rayLRB.
Init( ( oriLB + oriRB ) * 0.5f,
1201 glm::normalize( ( dirLB + dirRB ) * 0.5f ) );
1204 hitInfoLRB.
m_tHit = std::numeric_limits<float>::infinity();
1206 if( hitPacket[iLB].m_hitresult && hitPacket[iRB].m_hitresult
1207 && ( hitPacket[iLB].m_HitInfo.pHitObject ==
1208 hitPacket[iRB].m_HitInfo.pHitObject ) )
1210 hitInfoLRB.
pHitObject = hitPacket[ iLB ].m_HitInfo.pHitObject;
1212 hitInfoLRB.
m_tHit = ( hitPacket[ iLB ].m_HitInfo.m_tHit +
1213 hitPacket[ iRB ].m_HitInfo.m_tHit ) * 0.5f;
1216 glm::normalize( ( hitPacket[iLB].m_HitInfo.m_HitNormal
1217 + hitPacket[iRB].m_HitInfo.m_HitNormal )
1227 if( hitPacket[ iLB ].m_hitresult || hitPacket[ iRB ].m_hitresult )
1229 const unsigned int nodeLB =
1230 hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
1231 const unsigned int nodeRB =
1232 hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
1234 bool hittedLRB =
false;
1240 if( ( nodeRB != 0 ) && ( nodeRB != nodeLB ) )
1247 false, 0,
false ) );
1251 hitInfoLRB.
m_tHit = std::numeric_limits<float>::infinity();
1255 false, 0,
false ) );
1265 if( hitPacket[ iLT ].m_hitresult || hittedC )
1269 rayLTC.
Init( ( oriLT + oriC ) * 0.5f,
1270 glm::normalize( ( dirLT + dirC ) * 0.5f ) );
1273 hitInfoLTC.
m_tHit = std::numeric_limits<float>::infinity();
1275 bool hitted =
false;
1279 else if( hitPacket[ iLT ].m_hitresult )
1280 hitted = hitPacket[ iLT ].m_HitInfo.pHitObject->Intersect(
1292 if( hitPacket[ iRT ].m_hitresult || hittedC )
1296 rayRTC.
Init( ( oriRT + oriC ) * 0.5f,
1297 glm::normalize( ( dirRT + dirC ) * 0.5f ) );
1300 hitInfoRTC.
m_tHit = std::numeric_limits<float>::infinity();
1302 bool hitted =
false;
1306 else if( hitPacket[ iRT ].m_hitresult )
1307 hitted = hitPacket[iRT].m_HitInfo.pHitObject->Intersect(
1308 rayRTC, hitInfoRTC );
1318 if( hitPacket[ iLB ].m_hitresult || hittedC )
1322 rayLBC.
Init( ( oriLB + oriC ) * 0.5f,
1323 glm::normalize( ( dirLB + dirC ) * 0.5f ) );
1326 hitInfoLBC.
m_tHit = std::numeric_limits<float>::infinity();
1328 bool hitted =
false;
1332 else if( hitPacket[ iLB ].m_hitresult )
1333 hitted = hitPacket[iLB].m_HitInfo.pHitObject->Intersect(
1334 rayLBC, hitInfoLBC );
1344 if( hitPacket[ iRB ].m_hitresult || hittedC )
1348 rayRBC.
Init( ( oriRB + oriC ) * 0.5f,
1349 glm::normalize( ( dirRB + dirC ) * 0.5f ) );
1352 hitInfoRBC.
m_tHit = std::numeric_limits<float>::infinity();
1354 bool hitted =
false;
1358 else if( hitPacket[ iRB ].m_hitresult )
1359 hitted = hitPacket[iRB].m_HitInfo.pHitObject->Intersect(
1360 rayRBC, hitInfoRBC );
1405 while( threadsFinished < parallelThreadCount )
1406 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
1410#define USE_EXPERIMENTAL_SOFT_SHADOWS 1
1413 HITINFO& aHitInfo,
bool aIsInsideObject,
1414 unsigned int aRecursiveLevel,
bool is_testShadow )
const
1417 wxASSERT( objMaterial !=
nullptr );
1422 if( aRecursiveLevel > 7 )
1429 const SFVEC4F diffuseColorObj =
1432#if USE_EXPERIMENTAL_SOFT_SHADOWS
1436 float shadow_att_factor_sum = 0.0f;
1438 unsigned int nr_lights_that_can_cast_shadows = 0;
1446 light->GetLightParameters( hitPoint, vectorToLight, colorOfLight, distToLight );
1448 const float NdotL = glm::dot( aHitInfo.
m_HitNormal, vectorToLight );
1452 if( NdotL >= FLT_EPSILON )
1454 float shadow_att_factor_light = 1.0f;
1456 if( is_testShadow && light->GetCastShadows() )
1458 nr_lights_that_can_cast_shadows++;
1459#if USE_EXPERIMENTAL_SOFT_SHADOWS
1461 if( aRecursiveLevel > 0 )
1465 rayToLight.
Init( hitPoint, vectorToLight );
1470 shadow_att_factor_light = 0.0f;
1472#if USE_EXPERIMENTAL_SOFT_SHADOWS
1476 const unsigned int shadow_number_of_samples =
1478 const float shadow_inc_factor = 1.0f / (float) ( shadow_number_of_samples );
1480 for(
unsigned int i = 0; i < shadow_number_of_samples; ++i )
1486 rayToLight.
Init( hitPoint, vectorToLight );
1491 const SFVEC3F disturbed_vector_to_light =
1492 glm::normalize( vectorToLight + unifVector *
1495 rayToLight.
Init( hitPoint, disturbed_vector_to_light );
1503 shadow_att_factor_light -= shadow_inc_factor;
1508 shadow_att_factor_sum += shadow_att_factor_light;
1511 outColor +=
SFVEC4F( objMaterial->
Shade( aRay, aHitInfo, NdotL, diffuseColorObj,
1512 vectorToLight, colorOfLight,
1513 shadow_att_factor_light ),
1519 if( nr_lights_that_can_cast_shadows > 0 )
1522 shadow_att_factor_sum / (
float) ( nr_lights_that_can_cast_shadows * 1.0f ), 0.0f );
1530 outColor = glm::min( outColor,
SFVEC4F( 1.0f ) );
1537 && ( aRecursiveLevel < objMaterial->GetReflectionRecursionCount() ) )
1539 const unsigned int reflection_number_of_samples =
1547 for(
unsigned int i = 0; i < reflection_number_of_samples; ++i )
1553 reflectedRay.
Init( hitPoint, reflectVector );
1558 const SFVEC3F random_reflectVector =
1559 glm::normalize( reflectVector
1564 reflectedRay.
Init( hitPoint, random_reflectVector );
1568 reflectedHit.
m_tHit = std::numeric_limits<float>::infinity();
1574 shadeHit( aBgColor, reflectedRay, reflectedHit,
false,
1575 aRecursiveLevel + 1, is_testShadow ) *
1578 (1.0f / ( 1.0f + 0.75f * reflectedHit.
m_tHit *
1579 reflectedHit.
m_tHit) ) );
1585 outColor += (sum_color /
SFVEC4F( (
float)reflection_number_of_samples) );
1594 const float airIndex = 1.000293f;
1595 const float glassIndex = 1.49f;
1596 const float air_over_glass = airIndex / glassIndex;
1597 const float glass_over_air = glassIndex / airIndex;
1599 const float refractionRatio = aIsInsideObject?glass_over_air:air_over_glass;
1611 const unsigned int refractions_number_of_samples =
1616 for(
unsigned int i = 0; i < refractions_number_of_samples; ++i )
1622 refractedRay.
Init( startPoint, refractedVector );
1627 const SFVEC3F randomizeRefractedVector =
1628 glm::normalize( refractedVector +
1632 refractedRay.
Init( startPoint, randomizeRefractedVector );
1636 refractedHit.
m_tHit = std::numeric_limits<float>::infinity();
1638 SFVEC4F refractedColor = aBgColor;
1642 refractedColor =
shadeHit( aBgColor, refractedRay, refractedHit,
1643 !aIsInsideObject, aRecursiveLevel + 1,
false );
1646 (1.0f - objTransparency ) *
1650 const SFVEC4F transparency = 1.0f / ( absorbance + 1.0f );
1652 sum_color += refractedColor * transparency;
1656 sum_color += refractedColor;
1660 outColor = outColor * ( 1.0f - objTransparency ) + objTransparency * sum_color
1661 /
SFVEC4F( (
float) refractions_number_of_samples );
1665 outColor = outColor * ( 1.0f - objTransparency ) + objTransparency * aBgColor;
1676 const float dx = (float) a.x - (
float) b.x;
1677 const float dy = (float) a.y - (
float) b.y;
1678 return hypotf( dx, dy );
1737 constexpr auto hilbert_get_pos = [](
size_t aT,
size_t& aX,
size_t& aY )
1739 static const size_t htab[] = { 0b0010, 0b0100, 0b1100, 0b1001, 0b1111, 0b0101,
1740 0b0001, 0b1000, 0b0000, 0b1010, 0b1110, 0b0111,
1741 0b1101, 0b1011, 0b0011, 0b0110 };
1742 static const size_t size =
sizeof( size_t ) * 8;
1747 for(
size_t i = 0; i < ( size / 2 ); ++i )
1749 size_t abi = aT >> ( size - 2 );
1752 size_t st = htab[( c01 << 2 ) | abi];
1755 yv = ( yv << 1 ) | ( ( st >> 2 ) & 1 );
1756 xv = ( xv << 1 ) | ( st >> 3 );
1763 size_t total_blocks = blocks_x * blocks_y;
1770 hilbert_get_pos( pos++, x, y );
1772 if( x < blocks_x && y < blocks_y )
1787 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.
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 SetPixelData(unsigned int x, unsigned int y, const SFVEC3F &aNormal, const SFVEC4F &aColor, const SFVEC3F &aHitPosition, float aDepth, float aShadowAttFactor)
void UpdateSize(const SFVEC2UI &aSize)
This is a base class to hold data and functions for render targets.
wxSize m_windowSize
The window size that this camera is working.
BOARD_ADAPTER & m_boardAdapter
Settings reference in use for this render.
void renderBlockTracing(uint8_t *ptrPBO, signed int iBlock)
static SFVEC4F premultiplyAlpha(const SFVEC4F &aInput)
RENDER_3D_RAYTRACE_BASE(BOARD_ADAPTER &aAdapter, CAMERA &aCamera)
void renderFinalColor(uint8_t *ptrPBO, const SFVEC4F &rgbColor, bool applyColorSpaceConversion)
~RENDER_3D_RAYTRACE_BASE()
HITINFO_PACKET * m_firstHitinfo
void renderTracing(uint8_t *ptrPBO, REPORTER *aStatusReporter)
void render(uint8_t *ptrPBO, REPORTER *aStatusReporter)
void postProcessBlurFinish(uint8_t *ptrPBO, REPORTER *aStatusReporter)
void renderAntiAliasPackets(const SFVEC4F *aBgColorY, const HITINFO_PACKET *aHitPck_X0Y0, const HITINFO_PACKET *aHitPck_AA_X1Y1, const RAY *aRayPck, SFVEC4F *aOutHitColor)
POST_SHADER_SSAO m_postShaderSsao
bool m_is_canvas_initialized
void postProcessShading(uint8_t *ptrPBO, REPORTER *aStatusReporter)
std::vector< int > m_blockPositionsWasProcessed
Flag if a position was already processed (cleared each new render).
ACCELERATOR_3D * m_accelerator
DIRECTIONAL_LIGHT * m_cameraLight
BOARD_ITEM * IntersectBoardItem(const RAY &aRay)
unsigned int m_convertedDummyBlockCount
RT_RENDER_STATE m_renderState
State used on quality render.
SFVEC2UI m_fastPreviewModeSize
void renderRayPackets(const SFVEC4F *bgColorY, const RAY *aRayPkt, HITINFO_PACKET *aHitPacket, bool is_testShadow, SFVEC4F *aOutHitColor)
int GetWaitForEditingTimeOut() override
Give the interface the time (in ms) that it should wait for editing or movements before (this works f...
std::vector< SFVEC2UI > m_blockPositionsFast
Encode the Morton code positions (on fast preview mode).
SFVEC4F shadeHit(const SFVEC4F &aBgColor, const RAY &aRay, HITINFO &aHitInfo, bool aIsInsideObject, unsigned int aRecursiveLevel, bool is_testShadow) const
CONTAINER_2D * m_outlineBoard2dObjects
SFVEC4F m_backgroundColorBottom
SFVEC4F m_backgroundColorTop
BVH_CONTAINER_2D * m_antioutlineBoard2dObjects
void restartRenderState()
wxSize m_oldWindowsSize
Used to see if the windows size changed.
void renderPreview(uint8_t *ptrPBO)
std::list< LIGHT * > m_lights
size_t m_blockRenderProgressCount
Save the number of blocks progress of the render.
unsigned int m_converted2dRoundSegmentCount
int64_t m_renderStartTime
Time that the render starts.
void initializeBlockPositions()
std::vector< SFVEC2UI > m_blockPositions
Encode Morton code positions.
SFVEC2UI m_realBufferSize
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
COLOR_RGBA BlendColor(const COLOR_RGBA &aC1, const COLOR_RGBA &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....
int64_t 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
static SFVEC4F convertLinearToSRGBA(const SFVEC4F &aRGBAcolor)
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
static void SetPixel(uint8_t *p, const COLOR_RGBA &v)
static void HITINFO_PACKET_init(HITINFO_PACKET *aHitPacket)
static SFVEC3F convertLinearToSRGB(const SFVEC3F &aRGBcolor)
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
static void SetPixelSRGBA(uint8_t *p, const COLOR_RGBA &v)
SFVEC4F ConvertSRGBAToLinear(const SFVEC4F &aSRGBAcolor)
@ RT_RENDER_STATE_POST_PROCESS_SHADE
@ RT_RENDER_STATE_POST_PROCESS_BLUR_AND_FINISH
@ RT_RENDER_STATE_TRACING
SFVEC4F ConvertSRGBAToLinear(const SFVEC4F &aSRGBAcolor)
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
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::thread_pool thread_pool