| 3503 | } |
| 3504 | |
| 3505 | void Scene::fillInstanceDesc(std::vector<RtInstanceDesc>& instanceDescs, uint32_t rayTypeCount, bool perMeshHitEntry) const |
| 3506 | { |
| 3507 | instanceDescs.clear(); |
| 3508 | uint32_t instanceContributionToHitGroupIndex = 0; |
| 3509 | uint32_t instanceID = 0; |
| 3510 | |
| 3511 | for (size_t i = 0; i < mMeshGroups.size(); i++) |
| 3512 | { |
| 3513 | const auto& meshList = mMeshGroups[i].meshList; |
| 3514 | const bool isStatic = mMeshGroups[i].isStatic; |
| 3515 | |
| 3516 | FALCOR_ASSERT(mBlasData[i].blasGroupIndex < mBlasGroups.size()); |
| 3517 | const auto& pBlas = mBlasGroups[mBlasData[i].blasGroupIndex].pBlas; |
| 3518 | FALCOR_ASSERT(pBlas); |
| 3519 | |
| 3520 | RtInstanceDesc desc = {}; |
| 3521 | desc.accelerationStructure = pBlas->getGpuAddress() + mBlasData[i].blasByteOffset; |
| 3522 | desc.instanceMask = 0xFF; |
| 3523 | desc.instanceContributionToHitGroupIndex = perMeshHitEntry ? instanceContributionToHitGroupIndex : 0; |
| 3524 | |
| 3525 | instanceContributionToHitGroupIndex += rayTypeCount * (uint32_t)meshList.size(); |
| 3526 | |
| 3527 | // We expect all meshes in a group to have identical triangle winding. Verify that assumption here. |
| 3528 | FALCOR_ASSERT(!meshList.empty()); |
| 3529 | const bool frontFaceCW = mMeshDesc[meshList[0].get()].isFrontFaceCW(); |
| 3530 | for (size_t j = 1; j < meshList.size(); j++) |
| 3531 | { |
| 3532 | FALCOR_ASSERT(mMeshDesc[meshList[j].get()].isFrontFaceCW() == frontFaceCW); |
| 3533 | } |
| 3534 | |
| 3535 | // Set the triangle winding for the instance if it differs from the default. |
| 3536 | // The default in DXR is that a triangle is front facing if its vertices appear clockwise |
| 3537 | // from the ray origin, in object space in a left-handed coordinate system. |
| 3538 | // Note that Falcor uses a right-handed coordinate system, so we have to invert the flag. |
| 3539 | // Since these winding direction rules are defined in object space, they are unaffected by instance transforms. |
| 3540 | if (frontFaceCW) desc.flags = desc.flags | RtGeometryInstanceFlags::TriangleFrontCounterClockwise; |
| 3541 | |
| 3542 | // From the scene builder we can expect the following: |
| 3543 | // |
| 3544 | // If BLAS is marked as static: |
| 3545 | // - The meshes are pre-transformed to world-space. |
| 3546 | // - The meshes are guaranteed to be non-instanced, so only one INSTANCE_DESC with an identity transform is needed. |
| 3547 | // |
| 3548 | // If BLAS is not marked as static: |
| 3549 | // - The meshes are guaranteed to be non-instanced or be identically instanced, one INSTANCE_DESC per TLAS instance is needed. |
| 3550 | // - The global matrices are the same for all meshes in an instance. |
| 3551 | // |
| 3552 | FALCOR_ASSERT(!meshList.empty()); |
| 3553 | size_t instanceCount = mMeshIdToInstanceIds[meshList[0].get()].size(); |
| 3554 | |
| 3555 | FALCOR_ASSERT(instanceCount > 0); |
| 3556 | for (size_t instanceIdx = 0; instanceIdx < instanceCount; instanceIdx++) |
| 3557 | { |
| 3558 | // Validate that the ordering is matching our expectations: |
| 3559 | // InstanceID() + GeometryIndex() should look up the correct mesh instance. |
| 3560 | for (uint32_t geometryIndex = 0; geometryIndex < (uint32_t)meshList.size(); geometryIndex++) |
| 3561 | { |
| 3562 | const auto& instances = mMeshIdToInstanceIds[meshList[geometryIndex].get()]; |