We’re working on implementing software culling for Cesium Static Mesh tiles using the SnowOcclusionPlugin, which leverages UE4’s software culling capabilities. While we’ve successfully integrated this plugin for Cesium Static Mesh tiles, we’ve encountered two major issues during development:
- Android Issue: Unable to Access 16-Bit Index Buffer
The function below is responsible for building occlusion data:
TUniquePtr<FSnowMeshOccluderData> FSnowMeshOccluderData::Build(UStaticMesh* Owner) {
TUniquePtr<FSnowMeshOccluderData> Result;
#if !UE_BUILD_SHIPPING
if (!IsValid(Owner)) {
UE_LOG(LogTemp, Error, TEXT("Trying to build Occlusion Data for null mesh. Aborting!"));
return Result;
}
if (Owner->GetRenderData() == nullptr) {
UE_LOG(LogTemp, Error, TEXT("Trying to build Occlusion Data for null RenderData for Owner: %s. Aborting!"), *GetNameSafe(Owner));
return Result;
}
if (Owner->GetRenderData()->LODResources.IsEmpty()) {
UE_LOG(LogTemp, Error, TEXT("Trying to build Occlusion Data for empty LODResources for Owner: %s. Aborting!"), *GetNameSafe(Owner));
return Result;
}
#endif
const FStaticMeshLODResources& LODModel = Owner->GetRenderData()->LODResources[Owner->GetRenderData()->CurrentFirstLODIdx];
UE_LOG(LogTemp, Log, TEXT("DepthOnlyIndexBuffer : %d, LODIndexBuffer : %d, CPUAccess : %d"), LODModel.DepthOnlyIndexBuffer.GetNumIndices(), LODModel.IndexBuffer.GetNumIndices(), (int)Owner->bAllowCPUAccess);
const FRawStaticIndexBuffer& IndexBuffer = LODModel.DepthOnlyIndexBuffer.GetNumIndices() > 0 ? LODModel.DepthOnlyIndexBuffer : LODModel.IndexBuffer;
int32 NumVtx = LODModel.VertexBuffers.PositionVertexBuffer.GetNumVertices();
int32 NumIndices = IndexBuffer.GetNumIndices();
if (!IndexBuffer.AccessStream16()) {
UE_LOG(LogTemp, Error, TEXT("Can't access 16-bit IndexBuffer for Occlusion Mesh: %s: 32Bit : %d Aborting!"), *GetNameSafe(Owner), (int)IndexBuffer.Is32Bit());
return Result;
}
if (NumVtx > 0 && NumIndices > 0 && !IndexBuffer.Is32Bit()) {
Result = MakeUnique<FSnowMeshOccluderData>();
Result->VerticesSP->SetNumUninitialized(NumVtx);
Result->IndicesSP->SetNumUninitialized(NumIndices);
for (int i = 0; i < NumVtx; ++i) {
FVector Elem = FVector(LODModel.VertexBuffers.PositionVertexBuffer.VertexPosition(i));
Result->VerticesSP->GetData()[i] = Elem;
}
for (int i = 0; i < NumIndices; ++i) {
uint16 Elem = IndexBuffer.AccessStream16()[i];
Result->IndicesSP->GetData()[i] = Elem;
}
}
return Result;
}
On Android, we’re unable to access IndexBuffer.AccessStream16()
even though bAllowCPUAccess
is set to true
for the static mesh. This suggests that the buffer may not be correctly copied, despite CPUAccess
being enabled. The same code works flawlessly in the Windows editor.
- Windows Packaged Build Crash
We attempted to test the implementation in a Windows packaged build but encountered a crash when loading the tileset. Here’s the stack trace:
msvcp140.dll!00007ffd66392f58() Unknown
RealVrAi.exe!std::_Mutex_base::lock() Line 52 C++
RealVrAi.exe!spdlog::details::registry::default_logger() Line 88 C++
RealVrAi.exe!spdlog::default_logger() Line 77 C++
RealVrAi.exe!getCacheDatabase() Line 116 C++
RealVrAi.exe!getAssetAccessor() Line 128 C++
RealVrAi.exe!ACesium3DTileset::LoadTileset() Line 1117 C++
...
RealVrAi.exe!UWorld::Tick(ELevelTick TickType, float DeltaSeconds) Line 1516 C++
RealVrAi.exe!UGameEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 1786 C++
RealVrAi.exe!FEngineLoop::Tick() Line 5825 C++
RealVrAi.exe!GuardedMain(const wchar_t * CmdLine) Line 188 C++
RealVrAi.exe!GuardedMainWrapper(const wchar_t * CmdLine) Line 118 C++
RealVrAi.exe!LaunchWindowsStartup(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow, const wchar_t * CmdLine) Line 258 C++
RealVrAi.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * pCmdLine, int nCmdShow) Line 299 C++
We suspect this crash might be related to a mismatch in our Cesium-native build for Windows. We are building it using the following cmake
command:
cmake -B build -S . -A "x64" -G "Visual Studio 17 2022" && cmake --build build --config Release --target install -j8
Build logs indicate no major issues, but we’re curious if anyone has insights into possible mismatches or other causes for the crash.
Key Questions
- For Android: Why is
IndexBuffer.AccessStream16()
inaccessible despite enablingbAllowCPUAccess
, and is there a reliable way to ensure the buffer is properly copied for static meshes? - For Windows: Has anyone encountered similar issues with Cesium-native builds or mismatches when targeting packaged builds? Any insights into resolving the crash?
@Kevin_Ring any help or suggestions would be greatly appreciated! Let us know if you need additional details.