diff --git a/src/dxvk/rtx_render/rtx_instance_manager.cpp b/src/dxvk/rtx_render/rtx_instance_manager.cpp index deb8f44a..f2f17998 100644 --- a/src/dxvk/rtx_render/rtx_instance_manager.cpp +++ b/src/dxvk/rtx_render/rtx_instance_manager.cpp @@ -652,17 +652,24 @@ namespace dxvk { // Search the BLAS for an instance matching ours { - const auto adjacentCells = blas.getSpatialMap().getDataNearPos(worldPosition); - for (const std::vector* cellPtr : adjacentCells){ - for (const RtInstance* instance : *cellPtr) { - if (instance->m_frameLastUpdated == currentFrameIdx) { - // If the transform is an exact match and the instance has already been touched this frame, - // then this is a second draw call on a single mesh. + // Search for an exact match + const std::vector* matchingCell = blas.getSpatialMap().getDataAtPos(worldPosition); + if (matchingCell != nullptr) { + for (const RtInstance* instance : *matchingCell) { const Matrix4 instanceTransform = instance->getTransform(); + // Note: this may be the second call this frame targetting the same instance. if (memcmp(&transform, &instanceTransform, sizeof(instanceTransform)) == 0) { return const_cast(instance); } - } else if (instance->m_materialHash == material.getHash()) { + } + } + + // No exact match, so find the closest match in the region + // (need to check a 2x2x2 patch of cells to account for positions close to a border) + const auto adjacentCells = blas.getSpatialMap().getDataNearPos(worldPosition); + for (const std::vector* cellPtr : adjacentCells){ + for (const RtInstance* instance : *cellPtr) { + if (instance->m_frameLastUpdated != currentFrameIdx && instance->m_materialHash == material.getHash()) { // Instance hasn't been touched yet this frame. const Vector3& prevInstanceWorldPosition = instance->getSpatialCachePosition(); diff --git a/src/util/util_spatial_map.h b/src/util/util_spatial_map.h index 3eae4c19..5d7c7646 100644 --- a/src/util/util_spatial_map.h +++ b/src/util/util_spatial_map.h @@ -45,6 +45,15 @@ namespace dxvk { return *this; } + // returns the cell closest to `position` + const std::vector* getDataAtPos(const Vector3& position) const { + auto pair = m_cache.find(getCellPos(position)); + if ( pair != m_cache.end()) { + return &pair->second; + } + return nullptr; + } + // returns the 8 cells closest to `position` const std::vector*> getDataNearPos(const Vector3& position) const { static const std::array kOffsets{