| 1198 | } |
| 1199 | |
| 1200 | void Sample::BuildTLAS(nvrhi::ICommandList* commandList) const |
| 1201 | { |
| 1202 | std::vector<nvrhi::rt::InstanceDesc> instances; // TODO: make this a member, avoid allocs :) |
| 1203 | |
| 1204 | uint subInstanceCount = 0; |
| 1205 | for (const auto& instance : m_scene->GetSceneGraph()->GetMeshInstances()) |
| 1206 | { |
| 1207 | const bool ommDebugViewEnabled = m_ommBaker && m_ommBaker->UIData().DebugView != OpacityMicroMapDebugView::Disabled; |
| 1208 | // ommDebugViewEnabled must do two things: use a BLAS without OMMs and disable all alpha testing. |
| 1209 | // This may sound a bit counter intuitive, the goal is to intersect micro-triangles marked as transparent without them actually being treated as such. |
| 1210 | |
| 1211 | const std::shared_ptr<MeshInfoEx>& mesh = std::static_pointer_cast<MeshInfoEx>(instance->GetMesh()); |
| 1212 | |
| 1213 | const bool forceOpaque = ommDebugViewEnabled || m_ui.AS.ForceOpaque; |
| 1214 | const bool hasAttachementOMM = m_ommBaker && mesh->AccelStructOMM.Get() != nullptr; |
| 1215 | const bool useOmmBLAS = m_ommBaker && m_ommBaker->UIData().Enable && hasAttachementOMM && !forceOpaque; |
| 1216 | |
| 1217 | nvrhi::rt::InstanceDesc instanceDesc; |
| 1218 | instanceDesc.bottomLevelAS = useOmmBLAS ? mesh->AccelStructOMM.Get() : mesh->accelStruct.Get(); |
| 1219 | instanceDesc.instanceMask = (m_ommBaker && m_ommBaker->UIData().OnlyOMMs && !hasAttachementOMM) ? 0 : 1; |
| 1220 | instanceDesc.instanceID = instance->GetGeometryInstanceIndex(); |
| 1221 | instanceDesc.instanceContributionToHitGroupIndex = subInstanceCount; |
| 1222 | instanceDesc.flags = (m_ommBaker && m_ommBaker->UIData().Force2State) ? nvrhi::rt::InstanceFlags::ForceOMM2State : nvrhi::rt::InstanceFlags::None; |
| 1223 | if (forceOpaque) |
| 1224 | instanceDesc.flags = (nvrhi::rt::InstanceFlags)((uint32_t)instanceDesc.flags | (uint32_t)nvrhi::rt::InstanceFlags::ForceOpaque); |
| 1225 | |
| 1226 | assert( subInstanceCount == instance->GetGeometryInstanceIndex() ); |
| 1227 | subInstanceCount += (uint)mesh->geometries.size(); |
| 1228 | |
| 1229 | auto node = instance->GetNode(); |
| 1230 | assert(node); |
| 1231 | dm::affineToColumnMajor(node->GetLocalToWorldTransformFloat(), instanceDesc.transform); |
| 1232 | |
| 1233 | instances.push_back(instanceDesc); |
| 1234 | } |
| 1235 | assert (m_subInstanceCount == subInstanceCount); |
| 1236 | |
| 1237 | commandList->beginMarker("TLAS Update"); |
| 1238 | commandList->buildTopLevelAccelStruct(m_topLevelAS, instances.data(), instances.size(), nvrhi::rt::AccelStructBuildFlags::AllowEmptyInstances); |
| 1239 | commandList->endMarker(); |
| 1240 | } |
| 1241 | |
| 1242 | |
| 1243 | void Sample::BackBufferResizing() |