371 const bool is_testShadow =
m_boardAdapter.m_Cfg->m_Render.raytrace_shadows;
377 const RAY& rayAA = aRayPck[i];
380 hitAA.
m_tHit = std::numeric_limits<float>::infinity();
385 const unsigned int idx0y1 = ( x + 0 ) +
RAYPACKET_DIM * ( y + 1 );
386 const unsigned int idx1y1 = ( x + 1 ) +
RAYPACKET_DIM * ( y + 1 );
392 unsigned int nodex1y0 = 0;
397 unsigned int nodex0y1 = 0;
402 unsigned int nodex1y1 = 0;
412 if( ( nodex0y0 != nodex1y0 && nodex1y0 != 0 )
413 || ( nodex0y0 != nodex0y1 && nodex0y1 != 0 )
414 || ( nodex0y0 != nodex1y1 && nodex1y1 != 0 )
415 || ( nodex0y0 != node_AA_x0y0 ) )
422 hitted |=
m_accelerator->Intersect( rayAA, hitAA, nodex0y0 );
425 && nodex0y0 != nodex1y0 )
427 hitted |=
m_accelerator->Intersect( rayAA, hitAA, nodex1y0 );
431 && nodex0y0 != nodex0y1
432 && nodex1y0 != nodex0y1 )
434 hitted |=
m_accelerator->Intersect( rayAA, hitAA, nodex0y1 );
438 && nodex0y0 != nodex1y1
439 && nodex0y1 != nodex1y1
440 && nodex1y0 != nodex1y1 )
442 hitted |=
m_accelerator->Intersect( rayAA, hitAA, nodex1y1 );
445 if( node_AA_x0y0 != 0
446 && nodex0y0 != node_AA_x0y0
447 && nodex0y1 != node_AA_x0y0
448 && nodex1y0 != node_AA_x0y0
449 && nodex1y1 != node_AA_x0y0 )
451 hitted |=
m_accelerator->Intersect( rayAA, hitAA, node_AA_x0y0 );
457 aOutHitColor[i] =
shadeHit( aBgColorY[y], rayAA, hitAA,
false, 0, is_testShadow );
466 aOutHitColor[i] =
shadeHit( aBgColorY[y], rayAA, hitAA,
false, 0, is_testShadow );
499 const float posYfactor = (float) ( blockPosI.y + y ) / (float)
m_windowSize.y;
506 if( !
m_accelerator->Intersect( blockPacket, hitPacket_X0Y0 ) )
513 const SFVEC4F& outColor = bgColor[y];
515 const unsigned int yBlockPos = blockPos.y + y;
529 const bool isFinalColor = !
m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing;
533 const SFVEC4F& outColor = bgColor[y];
535 const unsigned int yConst = blockPos.x + ( ( y + blockPos.y ) *
m_realBufferSize.x );
539 uint8_t* ptr = &ptrPBO[( yConst + x ) * 4];
567 if( !
m_accelerator->Intersect( blockPacket_AA_X1Y1, hitPacket_AA_X1Y1 ) )
572 const SFVEC4F& outColor = bgColor[y];
575 hitColor_AA_X1Y1[i] = outColor;
581 m_boardAdapter.m_Cfg->m_Render.raytrace_shadows, hitColor_AA_X1Y1 );
590 SFVEC4F color_average = ( hitColor_X0Y0[i] + hitColor_AA_X1Y1[i] ) *
SFVEC4F( 0.5f );
592 hitColor_AA_X1Y0[i] = color_average;
593 hitColor_AA_X0Y1[i] = color_average;
594 hitColor_AA_X0Y1_half[i] = color_average;
603 randDisp, blockRayPck_AA_X1Y0 );
607 randDisp, blockRayPck_AA_X0Y1 );
611 randDisp, blockRayPck_AA_X1Y1_half );
620 blockRayPck_AA_X1Y1_half, hitColor_AA_X0Y1_half );
625 hitColor_X0Y0[i] = ( hitColor_X0Y0[i] + hitColor_AA_X1Y1[i] + hitColor_AA_X1Y0[i] +
626 hitColor_AA_X0Y1[i] + hitColor_AA_X0Y1_half[i] ) *
632 uint8_t* ptr = &ptrPBO[( blockPos.x + ( blockPos.y *
m_realBufferSize.x ) ) * 4];
647 const SFVEC4F& hColor = hitColor_X0Y0[i];
649 if( hitPacket_X0Y0[i].m_hitresult ==
true )
809 std::atomic<size_t> nextBlock( 0 );
810 std::atomic<size_t> threadsFinished( 0 );
812 size_t parallelThreadCount = std::min<size_t>(
813 std::max<size_t>( std::thread::hardware_concurrency(), 2 ),
816 for(
size_t ii = 0; ii < parallelThreadCount; ++ii )
818 std::thread t = std::thread( [&]()
821 iBlock = nextBlock.fetch_add( 1 ) )
834 packet.m_HitInfo.m_tHit = std::numeric_limits<float>::infinity();
835 packet.m_HitInfo.m_acc_node_info = 0;
836 packet.m_hitresult =
false;
850 const float posYfactor =
851 (float) ( windowsPos.y + y * 4.0f ) / (float)
m_windowSize.y;
853 bgColor[y] = bgTopColor *
SFVEC4F( posYfactor )
863 if( hitPacket[i].m_hitresult ==
true )
872 hitColorShading[i] = bhColorY;
879 const SFVEC4F bgColorY = bgColor[y];
900 const unsigned int iLT = ( ( x + 0 ) +
RAYPACKET_DIM * ( y + 0 ) );
901 const unsigned int iRT = ( ( x + 1 ) +
RAYPACKET_DIM * ( y + 0 ) );
902 const unsigned int iLB = ( ( x + 0 ) +
RAYPACKET_DIM * ( y + 1 ) );
903 const unsigned int iRB = ( ( x + 1 ) +
RAYPACKET_DIM * ( y + 1 ) );
906 const COLOR_RGBA& cLT = hitColorShading[ iLT ];
907 const COLOR_RGBA& cRT = hitColorShading[ iRT ];
908 const COLOR_RGBA& cLB = hitColorShading[ iLB ];
909 const COLOR_RGBA& cRB = hitColorShading[ iRB ];
924 centerHitInfo.
m_tHit = std::numeric_limits<float>::infinity();
926 bool hittedC =
false;
928 if( ( hitPacket[iLT].m_hitresult ==
true )
929 || ( hitPacket[iRT].m_hitresult ==
true )
930 || ( hitPacket[iLB].m_hitresult ==
true )
931 || ( hitPacket[iRB].m_hitresult ==
true ) )
933 oriC = ( oriLT + oriRB ) * 0.5f;
934 dirC = glm::normalize( ( dirLT + dirRB ) * 0.5f );
938 centerRay.
Init( oriC, dirC );
946 hittedC |=
m_accelerator->Intersect( centerRay, centerHitInfo,
949 if( ( nodeRT != 0 ) && ( nodeRT != nodeLT ) )
950 hittedC |=
m_accelerator->Intersect( centerRay, centerHitInfo,
953 if( ( nodeLB != 0 ) && ( nodeLB != nodeLT ) && ( nodeLB != nodeRT ) )
954 hittedC |=
m_accelerator->Intersect( centerRay, centerHitInfo,
957 if( ( nodeRB != 0 ) && ( nodeRB != nodeLB ) && ( nodeRB != nodeLT )
958 && ( nodeRB != nodeRT ) )
959 hittedC |=
m_accelerator->Intersect( centerRay, centerHitInfo,
969 centerHitInfo.
m_tHit = std::numeric_limits<float>::infinity();
970 hittedC =
m_accelerator->Intersect( centerRay, centerHitInfo );
988 rayLRT.
Init( ( oriLT + oriRT ) * 0.5f,
989 glm::normalize( ( dirLT + dirRT ) * 0.5f ) );
992 hitInfoLRT.
m_tHit = std::numeric_limits<float>::infinity();
994 if( hitPacket[iLT].m_hitresult && hitPacket[iRT].m_hitresult
995 && ( hitPacket[iLT].m_HitInfo.pHitObject
1002 glm::normalize( ( hitPacket[iLT].m_HitInfo.m_HitNormal
1013 if( hitPacket[ iLT ].m_hitresult || hitPacket[ iRT ].m_hitresult )
1015 const unsigned int nodeLT =
1017 const unsigned int nodeRT =
1020 bool hittedLRT =
false;
1026 if( ( nodeRT != 0 ) && ( nodeRT != nodeLT ) )
1032 false, 0,
false ) );
1035 hitInfoLRT.
m_tHit = std::numeric_limits<float>::infinity();
1060 rayLTB.
Init( ( oriLT + oriLB ) * 0.5f,
1061 glm::normalize( ( dirLT + dirLB ) * 0.5f ) );
1064 hitInfoLTB.
m_tHit = std::numeric_limits<float>::infinity();
1066 if( hitPacket[ iLT ].m_hitresult && hitPacket[ iLB ].m_hitresult
1067 && ( hitPacket[ iLT ].m_HitInfo.pHitObject ==
1074 glm::normalize( ( hitPacket[iLT].m_HitInfo.m_HitNormal
1078 shadeHit( bgColorY, rayLTB, hitInfoLTB,
false, 0,
false ) );
1084 if( hitPacket[ iLT ].m_hitresult || hitPacket[ iLB ].m_hitresult )
1086 const unsigned int nodeLT =
1088 const unsigned int nodeLB =
1091 bool hittedLTB =
false;
1097 if( ( nodeLB != 0 ) && ( nodeLB != nodeLT ) )
1103 false, 0,
false ) );
1106 hitInfoLTB.
m_tHit = std::numeric_limits<float>::infinity();
1126 rayRTB.
Init( ( oriRT + oriRB ) * 0.5f,
1127 glm::normalize( ( dirRT + dirRB ) * 0.5f ) );
1130 hitInfoRTB.
m_tHit = std::numeric_limits<float>::infinity();
1132 if( hitPacket[ iRT ].m_hitresult && hitPacket[ iRB ].m_hitresult
1133 && ( hitPacket[ iRT ].m_HitInfo.pHitObject ==
1142 glm::normalize( ( hitPacket[iRT].m_HitInfo.m_HitNormal
1153 if( hitPacket[ iRT ].m_hitresult || hitPacket[ iRB ].m_hitresult )
1155 const unsigned int nodeRT =
1157 const unsigned int nodeRB =
1160 bool hittedRTB =
false;
1166 if( ( nodeRB != 0 ) && ( nodeRB != nodeRT ) )
1177 hitInfoRTB.
m_tHit = std::numeric_limits<float>::infinity();
1181 false, 0,
false ) );
1196 rayLRB.
Init( ( oriLB + oriRB ) * 0.5f,
1197 glm::normalize( ( dirLB + dirRB ) * 0.5f ) );
1200 hitInfoLRB.
m_tHit = std::numeric_limits<float>::infinity();
1202 if( hitPacket[iLB].m_hitresult && hitPacket[iRB].m_hitresult
1203 && ( hitPacket[iLB].m_HitInfo.pHitObject ==
1212 glm::normalize( ( hitPacket[iLB].m_HitInfo.m_HitNormal
1223 if( hitPacket[ iLB ].m_hitresult || hitPacket[ iRB ].m_hitresult )
1225 const unsigned int nodeLB =
1227 const unsigned int nodeRB =
1230 bool hittedLRB =
false;
1236 if( ( nodeRB != 0 ) && ( nodeRB != nodeLB ) )
1243 false, 0,
false ) );
1247 hitInfoLRB.
m_tHit = std::numeric_limits<float>::infinity();
1251 false, 0,
false ) );
1261 if( hitPacket[ iLT ].m_hitresult || hittedC )
1265 rayLTC.
Init( ( oriLT + oriC ) * 0.5f,
1266 glm::normalize( ( dirLT + dirC ) * 0.5f ) );
1269 hitInfoLTC.
m_tHit = std::numeric_limits<float>::infinity();
1271 bool hitted =
false;
1275 else if( hitPacket[ iLT ].m_hitresult )
1288 if( hitPacket[ iRT ].m_hitresult || hittedC )
1292 rayRTC.
Init( ( oriRT + oriC ) * 0.5f,
1293 glm::normalize( ( dirRT + dirC ) * 0.5f ) );
1296 hitInfoRTC.
m_tHit = std::numeric_limits<float>::infinity();
1298 bool hitted =
false;
1302 else if( hitPacket[ iRT ].m_hitresult )
1304 rayRTC, hitInfoRTC );
1314 if( hitPacket[ iLB ].m_hitresult || hittedC )
1318 rayLBC.
Init( ( oriLB + oriC ) * 0.5f,
1319 glm::normalize( ( dirLB + dirC ) * 0.5f ) );
1322 hitInfoLBC.
m_tHit = std::numeric_limits<float>::infinity();
1324 bool hitted =
false;
1328 else if( hitPacket[ iLB ].m_hitresult )
1330 rayLBC, hitInfoLBC );
1340 if( hitPacket[ iRB ].m_hitresult || hittedC )
1344 rayRBC.
Init( ( oriRB + oriC ) * 0.5f,
1345 glm::normalize( ( dirRB + dirC ) * 0.5f ) );
1348 hitInfoRBC.
m_tHit = std::numeric_limits<float>::infinity();
1350 bool hitted =
false;
1354 else if( hitPacket[ iRB ].m_hitresult )
1356 rayRBC, hitInfoRBC );
1401 while( threadsFinished < parallelThreadCount )
1402 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
1409 HITINFO& aHitInfo,
bool aIsInsideObject,
1410 unsigned int aRecursiveLevel,
bool is_testShadow )
const
1413 wxASSERT( objMaterial !=
nullptr );
1418 if( aRecursiveLevel > 7 )
1425 const SFVEC4F diffuseColorObj =
1429 float shadow_att_factor_sum = 0.0f;
1431 unsigned int nr_lights_that_can_cast_shadows = 0;
1439 light->GetLightParameters( hitPoint, vectorToLight, colorOfLight, distToLight );
1441 const float NdotL = glm::dot( aHitInfo.
m_HitNormal, vectorToLight );
1445 if( NdotL >= FLT_EPSILON )
1447 float shadow_att_factor_light = 1.0f;
1449 if( is_testShadow && light->GetCastShadows() )
1451 nr_lights_that_can_cast_shadows++;
1454 if( aRecursiveLevel > 0 )
1457 rayToLight.
Init( hitPoint, vectorToLight );
1462 shadow_att_factor_light = 0.0f;
1467 const unsigned int shadow_number_of_samples =
1469 const float shadow_inc_factor = 1.0f / (float) ( shadow_number_of_samples );
1471 for(
unsigned int i = 0; i < shadow_number_of_samples; ++i )
1477 rayToLight.
Init( hitPoint, vectorToLight );
1482 const SFVEC3F disturbed_vector_to_light =
1483 glm::normalize( vectorToLight + unifVector *
1486 rayToLight.
Init( hitPoint, disturbed_vector_to_light );
1490 shadow_att_factor_light -= shadow_inc_factor;
1494 shadow_att_factor_sum += shadow_att_factor_light;
1497 outColor +=
SFVEC4F( objMaterial->
Shade( aRay, aHitInfo, NdotL, diffuseColorObj,
1498 vectorToLight, colorOfLight,
1499 shadow_att_factor_light ),
1505 if( nr_lights_that_can_cast_shadows > 0 )
1508 shadow_att_factor_sum / (
float) ( nr_lights_that_can_cast_shadows * 1.0f ), 0.0f );
1516 outColor = glm::min( outColor,
SFVEC4F( 1.0f ) );
1523 && ( aRecursiveLevel < objMaterial->GetReflectionRecursionCount() ) )
1525 const unsigned int reflection_number_of_samples =
1533 for(
unsigned int i = 0; i < reflection_number_of_samples; ++i )
1539 reflectedRay.
Init( hitPoint, reflectVector );
1544 const SFVEC3F random_reflectVector =
1545 glm::normalize( reflectVector
1548 .raytrace_spread_reflections );
1550 reflectedRay.
Init( hitPoint, random_reflectVector );
1554 reflectedHit.
m_tHit = std::numeric_limits<float>::infinity();
1556 if(
m_accelerator->Intersect( reflectedRay, reflectedHit ) )
1560 shadeHit( aBgColor, reflectedRay, reflectedHit,
false,
1561 aRecursiveLevel + 1, is_testShadow ) *
1564 (1.0f / ( 1.0f + 0.75f * reflectedHit.
m_tHit *
1565 reflectedHit.
m_tHit) ) );
1571 outColor += (sum_color /
SFVEC4F( (
float)reflection_number_of_samples) );
1577 if( ( objTransparency > 0.0f ) &&
m_boardAdapter.m_Cfg->m_Render.raytrace_refractions
1578 && ( aRecursiveLevel < objMaterial->GetRefractionRecursionCount() ) )
1580 const float airIndex = 1.000293f;
1581 const float glassIndex = 1.49f;
1582 const float air_over_glass = airIndex / glassIndex;
1583 const float glass_over_air = glassIndex / airIndex;
1585 const float refractionRatio = aIsInsideObject?glass_over_air:air_over_glass;
1597 const unsigned int refractions_number_of_samples =
1602 for(
unsigned int i = 0; i < refractions_number_of_samples; ++i )
1608 refractedRay.
Init( startPoint, refractedVector );
1613 const SFVEC3F randomizeRefractedVector =
1614 glm::normalize( refractedVector +
1618 refractedRay.
Init( startPoint, randomizeRefractedVector );
1622 refractedHit.
m_tHit = std::numeric_limits<float>::infinity();
1624 SFVEC4F refractedColor = aBgColor;
1626 if(
m_accelerator->Intersect( refractedRay, refractedHit ) )
1628 refractedColor =
shadeHit( aBgColor, refractedRay, refractedHit,
1629 !aIsInsideObject, aRecursiveLevel + 1,
false );
1632 (1.0f - objTransparency ) *
1636 const SFVEC4F transparency = 1.0f / ( absorbance + 1.0f );
1638 sum_color += refractedColor * transparency;
1642 sum_color += refractedColor;
1646 outColor = outColor * ( 1.0f - objTransparency ) + objTransparency * sum_color
1647 /
SFVEC4F( (
float) refractions_number_of_samples );
1651 outColor = outColor * ( 1.0f - objTransparency ) + objTransparency * aBgColor;