365 const bool is_testShadow =
m_boardAdapter.m_Cfg->m_Render.raytrace_shadows;
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;
391 unsigned int nodex0y1 = 0;
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 ) )
442 hitted |=
m_accelerator->Intersect( rayAA, hitAA, nodex0y0 );
444 if( ( nodex1y0 != 0 ) && ( nodex0y0 != nodex1y0 ) )
445 hitted |=
m_accelerator->Intersect( rayAA, hitAA, nodex1y0 );
447 if( ( nodex0y1 != 0 ) && ( nodex0y0 != nodex0y1 ) && ( nodex1y0 != nodex0y1 ) )
448 hitted |=
m_accelerator->Intersect( rayAA, hitAA, nodex0y1 );
450 if( ( nodex1y1 != 0 ) && ( nodex0y0 != nodex1y1 ) && ( nodex0y1 != nodex1y1 ) &&
451 ( nodex1y0 != nodex1y1 ) )
452 hitted |=
m_accelerator->Intersect( rayAA, hitAA, 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 ) )
457 hitted |=
m_accelerator->Intersect( rayAA, hitAA, node_AA_x0y0 );
462 aOutHitColor[i] =
shadeHit( aBgColorY[y], rayAA, hitAA,
false, 0,
472 aOutHitColor[i] =
shadeHit( aBgColorY[y], rayAA, hitAA,
false, 0,
506 const float posYfactor = (float) ( blockPosI.y + y ) / (float)
m_windowSize.y;
513 if( !
m_accelerator->Intersect( blockPacket, hitPacket_X0Y0 ) )
520 const SFVEC4F& outColor = bgColor[y];
522 const unsigned int yBlockPos = blockPos.y + y;
536 const bool isFinalColor = !
m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing;
540 const SFVEC4F& outColor = bgColor[y];
542 const unsigned int yConst = blockPos.x + ( ( y + blockPos.y ) *
m_realBufferSize.x );
546 uint8_t* ptr = &ptrPBO[( yConst + x ) * 4];
574 if( !
m_accelerator->Intersect( blockPacket_AA_X1Y1, hitPacket_AA_X1Y1 ) )
579 const SFVEC4F& outColor = bgColor[y];
582 hitColor_AA_X1Y1[i] = outColor;
588 m_boardAdapter.m_Cfg->m_Render.raytrace_shadows, hitColor_AA_X1Y1 );
597 SFVEC4F color_average = ( hitColor_X0Y0[i] + hitColor_AA_X1Y1[i] ) *
SFVEC4F( 0.5f );
599 hitColor_AA_X1Y0[i] = color_average;
600 hitColor_AA_X0Y1[i] = color_average;
601 hitColor_AA_X0Y1_half[i] = color_average;
610 randDisp, blockRayPck_AA_X1Y0 );
614 randDisp, blockRayPck_AA_X0Y1 );
618 randDisp, blockRayPck_AA_X1Y1_half );
627 blockRayPck_AA_X1Y1_half, hitColor_AA_X0Y1_half );
632 hitColor_X0Y0[i] = ( hitColor_X0Y0[i] + hitColor_AA_X1Y1[i] + hitColor_AA_X1Y0[i] +
633 hitColor_AA_X0Y1[i] + hitColor_AA_X0Y1_half[i] ) *
639 uint8_t* ptr = &ptrPBO[( blockPos.x + ( blockPos.y *
m_realBufferSize.x ) ) * 4];
654 const SFVEC4F& hColor = hitColor_X0Y0[i];
656 if( hitPacket_X0Y0[i].m_hitresult ==
true )
816 std::atomic<size_t> nextBlock( 0 );
817 std::atomic<size_t> threadsFinished( 0 );
819 size_t parallelThreadCount = std::min<size_t>(
820 std::max<size_t>( std::thread::hardware_concurrency(), 2 ),
823 for(
size_t ii = 0; ii < parallelThreadCount; ++ii )
825 std::thread t = std::thread( [&]()
828 iBlock = nextBlock.fetch_add( 1 ) )
841 packet.m_HitInfo.m_tHit = std::numeric_limits<float>::infinity();
842 packet.m_HitInfo.m_acc_node_info = 0;
843 packet.m_hitresult =
false;
857 const float posYfactor =
858 (float) ( windowsPos.y + y * 4.0f ) / (float)
m_windowSize.y;
860 bgColor[y] = bgTopColor *
SFVEC4F( posYfactor )
870 if( hitPacket[i].m_hitresult ==
true )
879 hitColorShading[i] = bhColorY;
886 const SFVEC4F bgColorY = bgColor[y];
907 const unsigned int iLT = ( ( x + 0 ) +
RAYPACKET_DIM * ( y + 0 ) );
908 const unsigned int iRT = ( ( x + 1 ) +
RAYPACKET_DIM * ( y + 0 ) );
909 const unsigned int iLB = ( ( x + 0 ) +
RAYPACKET_DIM * ( y + 1 ) );
910 const unsigned int iRB = ( ( x + 1 ) +
RAYPACKET_DIM * ( y + 1 ) );
913 const COLOR_RGBA& cLT = hitColorShading[ iLT ];
914 const COLOR_RGBA& cRT = hitColorShading[ iRT ];
915 const COLOR_RGBA& cLB = hitColorShading[ iLB ];
916 const COLOR_RGBA& cRB = hitColorShading[ iRB ];
931 centerHitInfo.
m_tHit = std::numeric_limits<float>::infinity();
933 bool hittedC =
false;
935 if( ( hitPacket[iLT].m_hitresult ==
true )
936 || ( hitPacket[iRT].m_hitresult ==
true )
937 || ( hitPacket[iLB].m_hitresult ==
true )
938 || ( hitPacket[iRB].m_hitresult ==
true ) )
940 oriC = ( oriLT + oriRB ) * 0.5f;
941 dirC = glm::normalize( ( dirLT + dirRB ) * 0.5f );
945 centerRay.
Init( oriC, dirC );
953 hittedC |=
m_accelerator->Intersect( centerRay, centerHitInfo,
956 if( ( nodeRT != 0 ) && ( nodeRT != nodeLT ) )
957 hittedC |=
m_accelerator->Intersect( centerRay, centerHitInfo,
960 if( ( nodeLB != 0 ) && ( nodeLB != nodeLT ) && ( nodeLB != nodeRT ) )
961 hittedC |=
m_accelerator->Intersect( centerRay, centerHitInfo,
964 if( ( nodeRB != 0 ) && ( nodeRB != nodeLB ) && ( nodeRB != nodeLT )
965 && ( nodeRB != nodeRT ) )
966 hittedC |=
m_accelerator->Intersect( centerRay, centerHitInfo,
976 centerHitInfo.
m_tHit = std::numeric_limits<float>::infinity();
977 hittedC =
m_accelerator->Intersect( centerRay, centerHitInfo );
995 rayLRT.
Init( ( oriLT + oriRT ) * 0.5f,
996 glm::normalize( ( dirLT + dirRT ) * 0.5f ) );
999 hitInfoLRT.
m_tHit = std::numeric_limits<float>::infinity();
1001 if( hitPacket[iLT].m_hitresult && hitPacket[iRT].m_hitresult
1002 && ( hitPacket[iLT].m_HitInfo.pHitObject
1009 glm::normalize( ( hitPacket[iLT].m_HitInfo.m_HitNormal
1020 if( hitPacket[ iLT ].m_hitresult || hitPacket[ iRT ].m_hitresult )
1022 const unsigned int nodeLT =
1024 const unsigned int nodeRT =
1027 bool hittedLRT =
false;
1033 if( ( nodeRT != 0 ) && ( nodeRT != nodeLT ) )
1039 false, 0,
false ) );
1042 hitInfoLRT.
m_tHit = std::numeric_limits<float>::infinity();
1067 rayLTB.
Init( ( oriLT + oriLB ) * 0.5f,
1068 glm::normalize( ( dirLT + dirLB ) * 0.5f ) );
1071 hitInfoLTB.
m_tHit = std::numeric_limits<float>::infinity();
1073 if( hitPacket[ iLT ].m_hitresult && hitPacket[ iLB ].m_hitresult
1074 && ( hitPacket[ iLT ].m_HitInfo.pHitObject ==
1081 glm::normalize( ( hitPacket[iLT].m_HitInfo.m_HitNormal
1085 shadeHit( bgColorY, rayLTB, hitInfoLTB,
false, 0,
false ) );
1091 if( hitPacket[ iLT ].m_hitresult || hitPacket[ iLB ].m_hitresult )
1093 const unsigned int nodeLT =
1095 const unsigned int nodeLB =
1098 bool hittedLTB =
false;
1104 if( ( nodeLB != 0 ) && ( nodeLB != nodeLT ) )
1110 false, 0,
false ) );
1113 hitInfoLTB.
m_tHit = std::numeric_limits<float>::infinity();
1133 rayRTB.
Init( ( oriRT + oriRB ) * 0.5f,
1134 glm::normalize( ( dirRT + dirRB ) * 0.5f ) );
1137 hitInfoRTB.
m_tHit = std::numeric_limits<float>::infinity();
1139 if( hitPacket[ iRT ].m_hitresult && hitPacket[ iRB ].m_hitresult
1140 && ( hitPacket[ iRT ].m_HitInfo.pHitObject ==
1149 glm::normalize( ( hitPacket[iRT].m_HitInfo.m_HitNormal
1160 if( hitPacket[ iRT ].m_hitresult || hitPacket[ iRB ].m_hitresult )
1162 const unsigned int nodeRT =
1164 const unsigned int nodeRB =
1167 bool hittedRTB =
false;
1173 if( ( nodeRB != 0 ) && ( nodeRB != nodeRT ) )
1184 hitInfoRTB.
m_tHit = std::numeric_limits<float>::infinity();
1188 false, 0,
false ) );
1203 rayLRB.
Init( ( oriLB + oriRB ) * 0.5f,
1204 glm::normalize( ( dirLB + dirRB ) * 0.5f ) );
1207 hitInfoLRB.
m_tHit = std::numeric_limits<float>::infinity();
1209 if( hitPacket[iLB].m_hitresult && hitPacket[iRB].m_hitresult
1210 && ( hitPacket[iLB].m_HitInfo.pHitObject ==
1219 glm::normalize( ( hitPacket[iLB].m_HitInfo.m_HitNormal
1230 if( hitPacket[ iLB ].m_hitresult || hitPacket[ iRB ].m_hitresult )
1232 const unsigned int nodeLB =
1234 const unsigned int nodeRB =
1237 bool hittedLRB =
false;
1243 if( ( nodeRB != 0 ) && ( nodeRB != nodeLB ) )
1250 false, 0,
false ) );
1254 hitInfoLRB.
m_tHit = std::numeric_limits<float>::infinity();
1258 false, 0,
false ) );
1268 if( hitPacket[ iLT ].m_hitresult || hittedC )
1272 rayLTC.
Init( ( oriLT + oriC ) * 0.5f,
1273 glm::normalize( ( dirLT + dirC ) * 0.5f ) );
1276 hitInfoLTC.
m_tHit = std::numeric_limits<float>::infinity();
1278 bool hitted =
false;
1282 else if( hitPacket[ iLT ].m_hitresult )
1295 if( hitPacket[ iRT ].m_hitresult || hittedC )
1299 rayRTC.
Init( ( oriRT + oriC ) * 0.5f,
1300 glm::normalize( ( dirRT + dirC ) * 0.5f ) );
1303 hitInfoRTC.
m_tHit = std::numeric_limits<float>::infinity();
1305 bool hitted =
false;
1309 else if( hitPacket[ iRT ].m_hitresult )
1311 rayRTC, hitInfoRTC );
1321 if( hitPacket[ iLB ].m_hitresult || hittedC )
1325 rayLBC.
Init( ( oriLB + oriC ) * 0.5f,
1326 glm::normalize( ( dirLB + dirC ) * 0.5f ) );
1329 hitInfoLBC.
m_tHit = std::numeric_limits<float>::infinity();
1331 bool hitted =
false;
1335 else if( hitPacket[ iLB ].m_hitresult )
1337 rayLBC, hitInfoLBC );
1347 if( hitPacket[ iRB ].m_hitresult || hittedC )
1351 rayRBC.
Init( ( oriRB + oriC ) * 0.5f,
1352 glm::normalize( ( dirRB + dirC ) * 0.5f ) );
1355 hitInfoRBC.
m_tHit = std::numeric_limits<float>::infinity();
1357 bool hitted =
false;
1361 else if( hitPacket[ iRB ].m_hitresult )
1363 rayRBC, hitInfoRBC );
1408 while( threadsFinished < parallelThreadCount )
1409 std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
1416 HITINFO& aHitInfo,
bool aIsInsideObject,
1417 unsigned int aRecursiveLevel,
bool is_testShadow )
const
1420 wxASSERT( objMaterial !=
nullptr );
1425 if( aRecursiveLevel > 7 )
1432 const SFVEC4F diffuseColorObj =
1435#if USE_EXPERIMENTAL_SOFT_SHADOWS
1439 float shadow_att_factor_sum = 0.0f;
1441 unsigned int nr_lights_that_can_cast_shadows = 0;
1449 light->GetLightParameters( hitPoint, vectorToLight, colorOfLight, distToLight );
1451 const float NdotL = glm::dot( aHitInfo.
m_HitNormal, vectorToLight );
1455 if( NdotL >= FLT_EPSILON )
1457 float shadow_att_factor_light = 1.0f;
1459 if( is_testShadow && light->GetCastShadows() )
1461 nr_lights_that_can_cast_shadows++;
1462#if USE_EXPERIMENTAL_SOFT_SHADOWS
1464 if( aRecursiveLevel > 0 )
1468 rayToLight.
Init( hitPoint, vectorToLight );
1473 shadow_att_factor_light = 0.0f;
1475#if USE_EXPERIMENTAL_SOFT_SHADOWS
1479 const unsigned int shadow_number_of_samples =
1481 const float shadow_inc_factor = 1.0f / (float) ( shadow_number_of_samples );
1483 for(
unsigned int i = 0; i < shadow_number_of_samples; ++i )
1489 rayToLight.
Init( hitPoint, vectorToLight );
1494 const SFVEC3F disturbed_vector_to_light =
1495 glm::normalize( vectorToLight + unifVector *
1498 rayToLight.
Init( hitPoint, disturbed_vector_to_light );
1506 shadow_att_factor_light -= shadow_inc_factor;
1511 shadow_att_factor_sum += shadow_att_factor_light;
1514 outColor +=
SFVEC4F( objMaterial->
Shade( aRay, aHitInfo, NdotL, diffuseColorObj,
1515 vectorToLight, colorOfLight,
1516 shadow_att_factor_light ),
1522 if( nr_lights_that_can_cast_shadows > 0 )
1525 shadow_att_factor_sum / (
float) ( nr_lights_that_can_cast_shadows * 1.0f ), 0.0f );
1533 outColor = glm::min( outColor,
SFVEC4F( 1.0f ) );
1540 && ( aRecursiveLevel < objMaterial->GetReflectionRecursionCount() ) )
1542 const unsigned int reflection_number_of_samples =
1550 for(
unsigned int i = 0; i < reflection_number_of_samples; ++i )
1556 reflectedRay.
Init( hitPoint, reflectVector );
1561 const SFVEC3F random_reflectVector =
1562 glm::normalize( reflectVector
1565 .raytrace_spread_reflections );
1567 reflectedRay.
Init( hitPoint, random_reflectVector );
1571 reflectedHit.
m_tHit = std::numeric_limits<float>::infinity();
1573 if(
m_accelerator->Intersect( reflectedRay, reflectedHit ) )
1577 shadeHit( aBgColor, reflectedRay, reflectedHit,
false,
1578 aRecursiveLevel + 1, is_testShadow ) *
1581 (1.0f / ( 1.0f + 0.75f * reflectedHit.
m_tHit *
1582 reflectedHit.
m_tHit) ) );
1588 outColor += (sum_color /
SFVEC4F( (
float)reflection_number_of_samples) );
1594 if( ( objTransparency > 0.0f ) &&
m_boardAdapter.m_Cfg->m_Render.raytrace_refractions
1595 && ( aRecursiveLevel < objMaterial->GetRefractionRecursionCount() ) )
1597 const float airIndex = 1.000293f;
1598 const float glassIndex = 1.49f;
1599 const float air_over_glass = airIndex / glassIndex;
1600 const float glass_over_air = glassIndex / airIndex;
1602 const float refractionRatio = aIsInsideObject?glass_over_air:air_over_glass;
1614 const unsigned int refractions_number_of_samples =
1619 for(
unsigned int i = 0; i < refractions_number_of_samples; ++i )
1625 refractedRay.
Init( startPoint, refractedVector );
1630 const SFVEC3F randomizeRefractedVector =
1631 glm::normalize( refractedVector +
1635 refractedRay.
Init( startPoint, randomizeRefractedVector );
1639 refractedHit.
m_tHit = std::numeric_limits<float>::infinity();
1641 SFVEC4F refractedColor = aBgColor;
1643 if(
m_accelerator->Intersect( refractedRay, refractedHit ) )
1645 refractedColor =
shadeHit( aBgColor, refractedRay, refractedHit,
1646 !aIsInsideObject, aRecursiveLevel + 1,
false );
1649 (1.0f - objTransparency ) *
1653 const SFVEC4F transparency = 1.0f / ( absorbance + 1.0f );
1655 sum_color += refractedColor * transparency;
1659 sum_color += refractedColor;
1663 outColor = outColor * ( 1.0f - objTransparency ) + objTransparency * sum_color
1664 /
SFVEC4F( (
float) refractions_number_of_samples );
1668 outColor = outColor * ( 1.0f - objTransparency ) + objTransparency * aBgColor;