Skip to content

Commit

Permalink
- Use visibleMeshletIds to remap meshlet instance indices to support …
Browse files Browse the repository at this point in the history
…scenes with more meshlet instances

- Added option to disable materials when loading a scene (use when a scene has huge materials that don't fit in VRAM)
- Fixed potential issue with VisbufferResolve.frag reading random, invalid meshlets
  • Loading branch information
JuanDiegoMontoya committed Jun 30, 2024
1 parent a3cbd08 commit 251fdc6
Show file tree
Hide file tree
Showing 16 changed files with 117 additions and 77 deletions.
2 changes: 1 addition & 1 deletion data/shaders/debug/DebugRect.vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

layout(location = 0) out vec4 v_color;

FVOG_DECLARE_ARGUMENTS(DebugAabbArguments)
FVOG_DECLARE_ARGUMENTS(DebugRectArguments)
{
FVOG_UINT32 debugRectBufferIndex;
};
Expand Down
3 changes: 2 additions & 1 deletion data/shaders/shadows/ShadowMain.vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ layout(location = 2) out vec3 i_objectSpacePos;

void main()
{
const uint meshletInstanceId = (uint(gl_VertexIndex) >> MESHLET_PRIMITIVE_BITS) & MESHLET_ID_MASK;
const uint visibleMeshletId = (uint(gl_VertexIndex) >> MESHLET_PRIMITIVE_BITS) & MESHLET_ID_MASK;
const uint meshletInstanceId = d_visibleMeshlets.indices[visibleMeshletId];
const uint primitiveId = uint(gl_VertexIndex) & MESHLET_PRIMITIVE_MASK;
const MeshletInstance meshletInstance = d_meshletInstances[meshletInstanceId];
const Meshlet meshlet = d_meshlets[meshletInstance.meshletId];
Expand Down
1 change: 1 addition & 0 deletions data/shaders/shadows/vsm/VsmCommon.h.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ FVOG_DECLARE_ARGUMENTS(VsmPushConstants)
FVOG_INT32 currentPass;

// VsmShadow + ShadowMain
FVOG_UINT32 visibleMeshletsIndex;
FVOG_UINT32 meshletInstancesIndex;
FVOG_UINT32 meshletDataIndex;
FVOG_UINT32 meshletPrimitivesIndex;
Expand Down
9 changes: 0 additions & 9 deletions data/shaders/visbuffer/CullMeshlets.comp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,6 @@ void DebugDrawMeshletAabb(in uint meshletInstanceId)
FVOG_DECLARE_SAMPLERS;
FVOG_DECLARE_SAMPLED_IMAGES(texture2D);

//layout(std430, binding = 9) restrict buffer MeshletVisibilityBuffer
FVOG_DECLARE_STORAGE_BUFFERS(restrict MeshletVisibilityBuffer)
{
uint indices[];
} visibleMeshletsBuffers[];

#define d_visibleMeshlets visibleMeshletsBuffers[visibleMeshletsIndex]

//layout(std430, binding = 10) restrict buffer CullTrianglesDispatchParams
FVOG_DECLARE_STORAGE_BUFFERS(restrict CullTrianglesDispatchParams)
{
uint groupCountX;
Expand Down
18 changes: 6 additions & 12 deletions data/shaders/visbuffer/CullTriangles.comp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,6 @@
#include "../debug/DebugCommon.h.glsl"
#include "../shadows/vsm/VsmCommon.h.glsl"

//layout(std430, binding = 9) restrict buffer MeshletVisbilityBuffer
FVOG_DECLARE_STORAGE_BUFFERS(restrict readonly MeshletVisbilityBuffer)
{
uint indices[];
} visibleMeshletsBuffers[];

#define d_visibleMeshlets visibleMeshletsBuffers[visibleMeshletsIndex]

//layout (std430, binding = 7) writeonly buffer MeshletPackedBuffer
FVOG_DECLARE_STORAGE_BUFFERS(writeonly MeshletPackedBuffer)
{
uint data[];
Expand Down Expand Up @@ -240,8 +231,11 @@ void main()
if (primitivePassed)
{
const uint indexOffset = sh_baseIndex + activePrimitiveId * 3;
d_indexBuffer.data[indexOffset + 0] = (meshletInstanceId << MESHLET_PRIMITIVE_BITS) | ((primitiveId + 0) & MESHLET_PRIMITIVE_MASK);
d_indexBuffer.data[indexOffset + 1] = (meshletInstanceId << MESHLET_PRIMITIVE_BITS) | ((primitiveId + 1) & MESHLET_PRIMITIVE_MASK);
d_indexBuffer.data[indexOffset + 2] = (meshletInstanceId << MESHLET_PRIMITIVE_BITS) | ((primitiveId + 2) & MESHLET_PRIMITIVE_MASK);
if (indexOffset + 2 < d_indexBuffer.data.length())
{
d_indexBuffer.data[indexOffset + 0] = (gl_WorkGroupID.x << MESHLET_PRIMITIVE_BITS) | ((primitiveId + 0) & MESHLET_PRIMITIVE_MASK);
d_indexBuffer.data[indexOffset + 1] = (gl_WorkGroupID.x << MESHLET_PRIMITIVE_BITS) | ((primitiveId + 1) & MESHLET_PRIMITIVE_MASK);
d_indexBuffer.data[indexOffset + 2] = (gl_WorkGroupID.x << MESHLET_PRIMITIVE_BITS) | ((primitiveId + 2) & MESHLET_PRIMITIVE_MASK);
}
}
}
4 changes: 2 additions & 2 deletions data/shaders/visbuffer/Visbuffer.frag.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "../Math.h.glsl"
#include "../Hash.h.glsl"

layout (location = 0) in flat uint i_meshletInstanceId;
layout (location = 0) in flat uint i_visibleMeshletId;
layout (location = 1) in flat uint i_primitiveId;
layout (location = 2) in vec2 i_uv;
layout (location = 3) in vec3 i_objectSpacePos;
Expand Down Expand Up @@ -67,5 +67,5 @@ void main()
}
}

o_pixel = (i_meshletInstanceId << MESHLET_PRIMITIVE_BITS) | (i_primitiveId & MESHLET_PRIMITIVE_MASK);
o_pixel = (i_visibleMeshletId << MESHLET_PRIMITIVE_BITS) | (i_primitiveId & MESHLET_PRIMITIVE_MASK);
}
7 changes: 4 additions & 3 deletions data/shaders/visbuffer/Visbuffer.vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
#extension GL_GOOGLE_include_directive : enable
#include "VisbufferCommon.h.glsl"

layout (location = 0) out flat uint o_meshletInstanceId;
layout (location = 0) out flat uint o_visibleMeshletId;
layout (location = 1) out flat uint o_primitiveId;
layout (location = 2) out vec2 o_uv;
layout (location = 3) out vec3 o_objectSpacePos;
layout (location = 4) out flat uint o_materialId;

void main()
{
const uint meshletInstanceId = (uint(gl_VertexIndex) >> MESHLET_PRIMITIVE_BITS) & MESHLET_ID_MASK;
const uint visibleMeshletId = (uint(gl_VertexIndex) >> MESHLET_PRIMITIVE_BITS) & MESHLET_ID_MASK;
const uint meshletInstanceId = d_visibleMeshlets.indices[visibleMeshletId];
const uint primitiveId = uint(gl_VertexIndex) & MESHLET_PRIMITIVE_MASK;
const MeshletInstance meshletInstance = d_meshletInstances[meshletInstanceId];
const Meshlet meshlet = d_meshlets[meshletInstance.meshletId];
Expand All @@ -26,7 +27,7 @@ void main()
const mat4 transform = d_transforms[instanceId].modelCurrent;
const vec2 uv = PackedToVec2(vertex.uv);

o_meshletInstanceId = meshletInstanceId;
o_visibleMeshletId = visibleMeshletId;
o_primitiveId = primitiveId / 3;
o_uv = uv;
o_objectSpacePos = position;
Expand Down
9 changes: 8 additions & 1 deletion data/shaders/visbuffer/VisbufferCommon.h.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ FVOG_DECLARE_ARGUMENTS(VisbufferPushConstants)
FVOG_UINT32 hzbSamplerIndex;
FVOG_UINT32 cullTrianglesDispatchIndex;

// CullMeshlets.comp and CullTriangles.comp
// CullMeshlets.comp, CullTriangles.comp, all vertex shaders
FVOG_UINT32 visibleMeshletsIndex;

// CullTriangles.comp
Expand Down Expand Up @@ -206,4 +206,11 @@ FVOG_DECLARE_STORAGE_BUFFERS(restrict readonly ViewBuffer)

#define d_currentView ViewBuffers[viewIndex].currentView

FVOG_DECLARE_STORAGE_BUFFERS(restrict MeshletVisbilityBuffer)
{
uint indices[];
} visibleMeshletsBuffers[];

#define d_visibleMeshlets visibleMeshletsBuffers[visibleMeshletsIndex]

#endif // VISBUFFER_COMMON_H
8 changes: 6 additions & 2 deletions data/shaders/visbuffer/VisbufferResolve.frag.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
layout(early_fragment_tests) in;

layout(location = 0) in vec2 i_uv;
layout(location = 1) in flat uint i_materialId;

layout(location = 0) out vec4 o_albedo;
layout(location = 1) out vec3 o_metallicRoughnessAo;
Expand Down Expand Up @@ -243,7 +242,12 @@ void main()
{
const ivec2 position = ivec2(gl_FragCoord.xy);
const uint payload = texelFetch(Fvog_utexture2D(visbufferIndex), position, 0).x;
const uint meshletInstanceId = (payload >> MESHLET_PRIMITIVE_BITS) & MESHLET_ID_MASK;
if (payload == ~0u)
{
discard;
}
const uint visibleMeshletId = (payload >> MESHLET_PRIMITIVE_BITS) & MESHLET_ID_MASK;
const uint meshletInstanceId = d_visibleMeshlets.indices[visibleMeshletId];
const uint primitiveId = payload & MESHLET_PRIMITIVE_MASK;
const MeshletInstance meshletInstance = d_meshletInstances[meshletInstanceId];
const Meshlet meshlet = d_meshlets[meshletInstance.meshletId];
Expand Down
5 changes: 1 addition & 4 deletions data/shaders/visbuffer/VisbufferResolve.vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@
#include "VisbufferCommon.h.glsl"

layout (location = 0) out vec2 v_uv;
layout (location = 1) out flat uint v_materialId;

void main()
{
v_materialId = gl_BaseInstance;
const highp float materialId = uintBitsToFloat(0x3f7fffff - (uint(gl_BaseInstance) & MESHLET_MATERIAL_ID_MASK));
vec2 pos = vec2(gl_VertexIndex == 0, gl_VertexIndex == 2);
v_uv = pos.xy * 2.0;
gl_Position = vec4(pos * 4.0 - 1.0, materialId, 1.0);
gl_Position = vec4(pos * 4.0 - 1.0, 0.0, 1.0);
}
51 changes: 33 additions & 18 deletions src/FrogRenderer2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ FrogRenderer2::FrogRenderer2(const Application::CreateInfo& createInfo)
//Utility::LoadModelFromFileMeshlet(*device_, scene, "H:/Repositories/glTF-Sample-Models/downloaded schtuff/sponza_compressed_tu.glb", glm::scale(glm::vec3{1}));
//Utility::LoadModelFromFileMeshlet(*device_, scene, "H:/Repositories/glTF-Sample-Models/downloaded schtuff/subdiv_deccer_cubes.glb", glm::scale(glm::vec3{1}));
//Utility::LoadModelFromFileMeshlet(*device_, scene, "H:/Repositories/glTF-Sample-Models/downloaded schtuff/SM_Deccer_Cubes_Textured.glb", glm::scale(glm::vec3{1}));
//Utility::LoadModelFromFileMeshlet(*device_, scene, "H:/Repositories/glTF-Sample-Models/downloaded schtuff/small_city.glb", glm::scale(glm::vec3{1}));

meshletIndirectCommand = Fvog::TypedBuffer<Fvog::DrawIndexedIndirectCommand>(*device_, {}, "Meshlet Indirect Command");
cullTrianglesDispatchParams = Fvog::TypedBuffer<Fvog::DispatchIndirectCommand>(*device_, {}, "Cull Triangles Dispatch Params");
Expand Down Expand Up @@ -406,14 +407,18 @@ void FrogRenderer2::OnUpdate([[maybe_unused]] double dt)
}
}

// TODO: This is an expensive call! Seek to minimize the parts of the scene that need to be re-traversed to those that actually changed.
sceneFlattened = scene.Flatten();
shadingUniforms.numberOfLights = (uint32_t)sceneFlattened.lights.size();

// A few of these buffers are really slow (2-3ms) to create and destroy every frame (large ones hit vkAllocateMemory), so
// this scheme is still not ideal as e.g. adding geometry every frame will cause reallocs.
// The current scheme works fine when the scene is mostly static.
const auto numMeshlets = static_cast<uint32_t>(sceneFlattened.meshletInstances.size());
const auto maxIndices = numMeshlets * Utility::maxMeshletPrimitives * 3;

// Soft cap of 1 billion indices should prevent oversubscribing memory (on my system) when loading huge scenes.
// This limit should be OK as it only limits post-culling geometry.
const auto maxIndices = glm::min(1'000'000'000u, numMeshlets * Utility::maxMeshletPrimitives * 3);
if (!instancedMeshletBuffer || instancedMeshletBuffer->Size() < maxIndices)
{
instancedMeshletBuffer = Fvog::TypedBuffer<uint32_t>(*device_, {.count = maxIndices}, "Instanced Meshlets");
Expand All @@ -429,9 +434,14 @@ void FrogRenderer2::OnUpdate([[maybe_unused]] double dt)
transformBuffer = Fvog::NDeviceBuffer<Utility::ObjectUniforms>(*device_, (uint32_t)sceneFlattened.transforms.size(), "Transforms");
}

if (!visibleMeshletIds || visibleMeshletIds->Size() < numMeshlets)
if (!persistentVisibleMeshletIds || persistentVisibleMeshletIds->Size() < numMeshlets)
{
persistentVisibleMeshletIds = Fvog::TypedBuffer<uint32_t>(*device_, {.count = numMeshlets}, "Persistent Visible Meshlet IDs");
}

if (!transientVisibleMeshletIds || transientVisibleMeshletIds->Size() < numMeshlets)
{
visibleMeshletIds = Fvog::TypedBuffer<uint32_t>(*device_, {.count = numMeshlets}, "Visible Meshlet IDs");
transientVisibleMeshletIds = Fvog::TypedBuffer<uint32_t>(*device_, {.count = numMeshlets}, "Transient Visible Meshlet IDs");
}

if (!meshletInstancesBuffer || meshletInstancesBuffer->Size() < numMeshlets)
Expand All @@ -447,7 +457,7 @@ void FrogRenderer2::OnUpdate([[maybe_unused]] double dt)
}
}

void FrogRenderer2::CullMeshletsForView(VkCommandBuffer commandBuffer, const ViewParams& view, std::string_view name)
void FrogRenderer2::CullMeshletsForView(VkCommandBuffer commandBuffer, const ViewParams& view, Fvog::Buffer& visibleMeshletIds, std::string_view name)
{
ZoneScoped;
TracyVkZoneTransient(tracyVkContext_, tracyProfileVar, commandBuffer, name.data(), true);
Expand Down Expand Up @@ -493,7 +503,7 @@ void FrogRenderer2::CullMeshletsForView(VkCommandBuffer commandBuffer, const Vie
.hzbIndex = frame.hzb->ImageView().GetSampledResourceHandle().index,
.hzbSamplerIndex = hzbSampler.GetResourceHandle().index,
.cullTrianglesDispatchIndex = cullTrianglesDispatchParams->GetResourceHandle().index,
.visibleMeshletsIndex = visibleMeshletIds->GetResourceHandle().index,
.visibleMeshletsIndex = visibleMeshletIds.GetResourceHandle().index,
.debugAabbBufferIndex = debugGpuAabbsBuffer->GetResourceHandle().index,
.debugRectBufferIndex = debugGpuRectsBuffer->GetResourceHandle().index,
};
Expand Down Expand Up @@ -546,10 +556,12 @@ void FrogRenderer2::OnRender([[maybe_unused]] double dt, VkCommandBuffer command
auto gpuMaterials = std::vector<Utility::GpuMaterial>(scene.materials.size());
std::ranges::transform(scene.materials, gpuMaterials.begin(), [](const auto& mat) { return mat.gpuMaterial; });

// TODO: These buffers should only be updated when changed (these uploads can be quite costly in larger scenes).
materialStorageBuffer->UpdateData(commandBuffer, gpuMaterials);
lightBuffer->UpdateData(commandBuffer, sceneFlattened.lights);
transformBuffer->UpdateData(commandBuffer, sceneFlattened.transforms);
meshletInstancesBuffer->UpdateData(commandBuffer, sceneFlattened.meshletInstances);

// VSM lod bias corresponds to upscaling lod bias, otherwise shadows become blocky as the upscaling ratio increases.
auto actualVsmUniforms = vsmUniforms;
actualVsmUniforms.lodBias += fsr2LodBias;
Expand Down Expand Up @@ -674,7 +686,7 @@ void FrogRenderer2::OnRender([[maybe_unused]] double dt, VkCommandBuffer command
if (executeMeshletGeneration)
{
TIME_SCOPE_GPU(StatGroup::eMainGpu, eCullMeshletsMain, commandBuffer);
CullMeshletsForView(commandBuffer, mainView, "Cull Meshlets Main");
CullMeshletsForView(commandBuffer, mainView, persistentVisibleMeshletIds.value(), "Cull Meshlets Main");
}

ctx.ImageBarrierDiscard(*frame.visbuffer, VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL);
Expand All @@ -697,19 +709,20 @@ void FrogRenderer2::OnRender([[maybe_unused]] double dt, VkCommandBuffer command
.depthAttachment = visbufferDepthAttachment,
});
{
// TIME_SCOPE_GPU(StatGroup::eMainGpu, eRenderVisbufferMain);
TIME_SCOPE_GPU(StatGroup::eMainGpu, eRenderVisbufferMain, commandBuffer);
ctx.BindGraphicsPipeline(visbufferPipeline);
auto visbufferArguments = VisbufferPushConstants{
.globalUniformsIndex = globalUniformsBuffer.GetDeviceBuffer().GetResourceHandle().index,
.meshletInstancesIndex = meshletInstancesBuffer->GetDeviceBuffer().GetResourceHandle().index,
.meshletDataIndex = meshletBuffer->GetResourceHandle().index,
.globalUniformsIndex = globalUniformsBuffer.GetDeviceBuffer().GetResourceHandle().index,
.meshletInstancesIndex = meshletInstancesBuffer->GetDeviceBuffer().GetResourceHandle().index,
.meshletDataIndex = meshletBuffer->GetResourceHandle().index,
.meshletPrimitivesIndex = primitiveBuffer->GetResourceHandle().index,
.meshletVerticesIndex = vertexBuffer->GetResourceHandle().index,
.meshletIndicesIndex = indexBuffer->GetResourceHandle().index,
.transformsIndex = transformBuffer->GetDeviceBuffer().GetResourceHandle().index,
.indirectDrawIndex = meshletIndirectCommand->GetResourceHandle().index,
.materialsIndex = materialStorageBuffer->GetDeviceBuffer().GetResourceHandle().index,
.viewIndex = viewBuffer->GetResourceHandle().index,
.meshletVerticesIndex = vertexBuffer->GetResourceHandle().index,
.meshletIndicesIndex = indexBuffer->GetResourceHandle().index,
.transformsIndex = transformBuffer->GetDeviceBuffer().GetResourceHandle().index,
.indirectDrawIndex = meshletIndirectCommand->GetResourceHandle().index,
.materialsIndex = materialStorageBuffer->GetDeviceBuffer().GetResourceHandle().index,
.viewIndex = viewBuffer->GetResourceHandle().index,
.visibleMeshletsIndex = persistentVisibleMeshletIds->GetResourceHandle().index,
};
ctx.SetPushConstants(visbufferArguments);
ctx.BindIndexBuffer(*instancedMeshletBuffer, 0, VK_INDEX_TYPE_UINT32);
Expand Down Expand Up @@ -766,7 +779,7 @@ void FrogRenderer2::OnRender([[maybe_unused]] double dt, VkCommandBuffer command
};
Math::MakeFrustumPlanes(sunCurrentClipmapView.viewProj, sunCurrentClipmapView.frustumPlanes);

CullMeshletsForView(commandBuffer, sunCurrentClipmapView, "Cull Sun VSM Meshlets, View " + std::to_string(i));
CullMeshletsForView(commandBuffer, sunCurrentClipmapView, transientVisibleMeshletIds.value(), "Cull Sun VSM Meshlets, View " + std::to_string(i));

const auto vsmExtent = Fvog::Extent2D{Techniques::VirtualShadowMaps::maxExtent, Techniques::VirtualShadowMaps::maxExtent};
ctx.Barrier();
Expand Down Expand Up @@ -802,6 +815,7 @@ void FrogRenderer2::OnRender([[maybe_unused]] double dt, VkCommandBuffer command
pushConstants.materialSamplerIndex = materialSampler.GetResourceHandle().index;
pushConstants.clipmapLod = vsmSun.GetClipmapTableIndices()[i];
pushConstants.clipmapUniformsBufferIndex = vsmSun.clipmapUniformsBuffer_.GetResourceHandle().index;
pushConstants.visibleMeshletsIndex = transientVisibleMeshletIds->GetResourceHandle().index,

ctx.BindIndexBuffer(*instancedMeshletBuffer, 0, VK_INDEX_TYPE_UINT32);

Expand Down Expand Up @@ -921,9 +935,10 @@ void FrogRenderer2::OnRender([[maybe_unused]] double dt, VkCommandBuffer command
.meshletIndicesIndex = indexBuffer->GetResourceHandle().index,
.transformsIndex = transformBuffer->GetDeviceBuffer().GetResourceHandle().index,
.materialsIndex = materialStorageBuffer->GetDeviceBuffer().GetResourceHandle().index,
.visibleMeshletsIndex = persistentVisibleMeshletIds->GetResourceHandle().index,
.materialSamplerIndex = materialSampler.GetResourceHandle().index,

.visbufferIndex = frame.visbuffer->ImageView().GetSampledResourceHandle().index,
.visbufferIndex = frame.visbuffer->ImageView().GetSampledResourceHandle().index,
};

ctx.SetPushConstants(pushConstants);
Expand Down
11 changes: 9 additions & 2 deletions src/FrogRenderer2.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ class FrogRenderer2 final : public Application
void GuiDrawSceneGraph(VkCommandBuffer commandBuffer);
void GuiDrawSceneGraphHelper(Utility::Node* node);

void CullMeshletsForView(VkCommandBuffer commandBuffer, const ViewParams& view, std::string_view name = "Cull Meshlet Pass");
void CullMeshletsForView(VkCommandBuffer commandBuffer, const ViewParams& view, Fvog::Buffer& visibleMeshletIds, std::string_view name = "Cull Meshlet Pass");
void MakeStaticSceneBuffers(VkCommandBuffer commandBuffer);

enum class GlobalFlags : uint32_t
Expand Down Expand Up @@ -388,7 +388,14 @@ class FrogRenderer2 final : public Application
std::optional<Fvog::TypedBuffer<Fvog::DrawIndexedIndirectCommand>> meshletIndirectCommand;
std::optional<Fvog::TypedBuffer<uint32_t>> instancedMeshletBuffer;
std::optional<Fvog::TypedBuffer<Fvog::DispatchIndirectCommand>> cullTrianglesDispatchParams;
std::optional<Fvog::TypedBuffer<uint32_t>> visibleMeshletIds;

// These buffers serve two purposes:
// First, they store the IDs of meshlet instances that passed meshlet culling.
// Second, they allow us to remap the range 0-2^24 to meshlet instances that may
// have an index outside that range. That can allow us to render scenes with more than 2^24
// meshlet instances correctly, as long as 2^24 meshlet instances or fewer are visible.
std::optional<Fvog::TypedBuffer<uint32_t>> persistentVisibleMeshletIds; // For when the data needs to be retrieved later (i.e. it is stored in the visbuffer)
std::optional<Fvog::TypedBuffer<uint32_t>> transientVisibleMeshletIds; // For shadows or forward passes

Fvog::ComputePipeline cullMeshletsPipeline;
Fvog::ComputePipeline cullTrianglesPipeline;
Expand Down
Loading

0 comments on commit 251fdc6

Please sign in to comment.