Skip to content

Commit bdaefeb

Browse files
committed
Keep shared-transform OpenGL raytrace scenes
1 parent 5942f33 commit bdaefeb

1 file changed

Lines changed: 95 additions & 1 deletion

File tree

frame/opengl/renderer.cpp

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,40 @@ bool HasRaytracingSourceMeshes(frame::LevelInterface& level)
136136
return !GetRaytracingSourceMeshMaterials(level).empty();
137137
}
138138

139+
bool CanUseSharedRaytraceSceneTransform(
140+
frame::LevelInterface& level,
141+
double time_seconds)
142+
{
143+
const auto source_mesh_materials = GetRaytracingSourceMeshMaterials(level);
144+
if (source_mesh_materials.empty())
145+
{
146+
return false;
147+
}
148+
149+
std::optional<glm::mat4> shared_model = std::nullopt;
150+
for (const auto& [source_node_id, source_material_id] : source_mesh_materials)
151+
{
152+
(void)source_material_id;
153+
auto* node =
154+
dynamic_cast<NodeMesh*>(&level.GetSceneNodeFromId(source_node_id));
155+
if (!node)
156+
{
157+
return false;
158+
}
159+
const glm::mat4 model = node->GetLocalModel(time_seconds);
160+
if (!shared_model)
161+
{
162+
shared_model = model;
163+
continue;
164+
}
165+
if (*shared_model != model)
166+
{
167+
return false;
168+
}
169+
}
170+
return true;
171+
}
172+
139173
std::vector<std::pair<EntityId, std::string>> GetActiveTextureBindings(
140174
const MaterialInterface& material,
141175
const ProgramInterface& program)
@@ -863,6 +897,35 @@ std::vector<std::uint8_t> BuildWorldSpaceRaytraceInstanceBytes(
863897
return EncodeRaytraceInstanceData(instances);
864898
}
865899

900+
std::vector<std::uint8_t> BuildSharedTransformRaytraceInstanceBytes(
901+
const glm::mat4& shared_model,
902+
std::uint32_t transmissive_triangle_count,
903+
std::uint32_t opaque_triangle_count)
904+
{
905+
std::vector<RaytraceInstanceData> instances = {};
906+
const float determinant = glm::determinant(glm::mat3(shared_model));
907+
const glm::mat4 world_to_object =
908+
std::abs(determinant) > 1.0e-8f ? glm::inverse(shared_model)
909+
: glm::mat4(1.0f);
910+
const auto append_instance =
911+
[&](std::uint32_t material_id,
912+
std::uint32_t triangle_count) {
913+
if (triangle_count == 0)
914+
{
915+
return;
916+
}
917+
RaytraceInstanceData instance = {};
918+
instance.object_to_world = shared_model;
919+
instance.world_to_object = world_to_object;
920+
instance.metadata =
921+
glm::uvec4(0u, material_id, 0u, triangle_count);
922+
instances.push_back(std::move(instance));
923+
};
924+
append_instance(kRaytraceMaterialTransmissive, transmissive_triangle_count);
925+
append_instance(kRaytraceMaterialOpaque, opaque_triangle_count);
926+
return EncodeRaytraceInstanceData(instances);
927+
}
928+
866929
} // namespace
867930

868931
Renderer::Renderer(LevelInterface& level, glm::uvec4 viewport)
@@ -956,6 +1019,9 @@ void Renderer::UpdateAggregateRaytraceSceneBuffers()
9561019
{
9571020
const bool use_world_space_buffers =
9581021
RaytraceSceneRequiresWorldSpaceBuffers(level_);
1022+
const bool use_shared_scene_transform =
1023+
!use_world_space_buffers &&
1024+
CanUseSharedRaytraceSceneTransform(level_, delta_time_);
9591025
const auto scene_entries = CollectRaytraceSceneEntries(level_, delta_time_);
9601026
if (scene_entries.empty())
9611027
{
@@ -1001,6 +1067,20 @@ void Renderer::UpdateAggregateRaytraceSceneBuffers()
10011067
std::vector<std::uint8_t> raytrace_instances = {};
10021068
const bool update_instance_buffer =
10031069
geometry_changed || !use_world_space_buffers;
1070+
const auto count_triangles =
1071+
[&](bool transmissive) -> std::uint32_t {
1072+
std::uint32_t triangle_count = 0;
1073+
for (const auto& entry : scene_entries)
1074+
{
1075+
if (entry.transmissive == transmissive)
1076+
{
1077+
triangle_count += entry.triangle_count;
1078+
}
1079+
}
1080+
return triangle_count;
1081+
};
1082+
const std::uint32_t transmissive_triangle_count = count_triangles(true);
1083+
const std::uint32_t opaque_triangle_count = count_triangles(false);
10041084
if (geometry_changed)
10051085
{
10061086
const auto prepared_entries = PrepareRaytraceSceneEntries(
@@ -1018,6 +1098,15 @@ void Renderer::UpdateAggregateRaytraceSceneBuffers()
10181098
transmissive_triangles,
10191099
opaque_triangles);
10201100
}
1101+
else if (use_shared_scene_transform)
1102+
{
1103+
transmissive_bvh = BuildAggregateBvhBytes(transmissive_triangles);
1104+
opaque_bvh = BuildAggregateBvhBytes(opaque_triangles);
1105+
raytrace_instances = BuildSharedTransformRaytraceInstanceBytes(
1106+
scene_entries.front().model,
1107+
transmissive_triangle_count,
1108+
opaque_triangle_count);
1109+
}
10211110
else
10221111
{
10231112
transmissive_bvh =
@@ -1028,7 +1117,12 @@ void Renderer::UpdateAggregateRaytraceSceneBuffers()
10281117
}
10291118
if (!use_world_space_buffers)
10301119
{
1031-
raytrace_instances = BuildPerMeshRaytraceInstanceBytes(scene_entries);
1120+
raytrace_instances = use_shared_scene_transform
1121+
? BuildSharedTransformRaytraceInstanceBytes(
1122+
scene_entries.front().model,
1123+
transmissive_triangle_count,
1124+
opaque_triangle_count)
1125+
: BuildPerMeshRaytraceInstanceBytes(scene_entries);
10321126
}
10331127

10341128
for (const auto& [node_id, material_id] :

0 commit comments

Comments
 (0)