Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use distance to AABB surface to calculate Mesh LOD instead of using supports #92290

Merged
merged 1 commit into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 14 additions & 27 deletions drivers/gles3/rasterizer_scene_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1363,38 +1363,25 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const

GeometryInstanceSurface *surf = inst->surface_caches;

float lod_distance = 0.0;

if (p_render_data->cam_orthogonal) {
lod_distance = 1.0;
} else {
Vector3 aabb_min = inst->transformed_aabb.position;
Vector3 aabb_max = inst->transformed_aabb.position + inst->transformed_aabb.size;
Vector3 camera_position = p_render_data->main_cam_transform.origin;
Vector3 surface_distance = Vector3(0.0, 0.0, 0.0).max(aabb_min - camera_position).max(camera_position - aabb_max);
akien-mga marked this conversation as resolved.
Show resolved Hide resolved

lod_distance = surface_distance.length();
}

while (surf) {
// LOD

if (p_render_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) {
float distance = 0.0;

// Check if camera is NOT inside the mesh AABB.
if (!inst->transformed_aabb.has_point(p_render_data->main_cam_transform.origin)) {
// Get the LOD support points on the mesh AABB.
Vector3 lod_support_min = inst->transformed_aabb.get_support(p_render_data->main_cam_transform.basis.get_column(Vector3::AXIS_Z));
Vector3 lod_support_max = inst->transformed_aabb.get_support(-p_render_data->main_cam_transform.basis.get_column(Vector3::AXIS_Z));

// Get the distances to those points on the AABB from the camera origin.
float distance_min = (float)p_render_data->main_cam_transform.origin.distance_to(lod_support_min);
float distance_max = (float)p_render_data->main_cam_transform.origin.distance_to(lod_support_max);

if (distance_min * distance_max < 0.0) {
//crossing plane
distance = 0.0;
} else if (distance_min >= 0.0) {
distance = distance_min;
} else if (distance_max <= 0.0) {
distance = -distance_max;
}
}

if (p_render_data->cam_orthogonal) {
distance = 1.0;
}

uint32_t indices = 0;
surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, indices);
surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, lod_distance * p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, indices);
surf->index_count = indices;

if (p_render_data->render_info) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -962,40 +962,27 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con

GeometryInstanceSurfaceDataCache *surf = inst->surface_caches;

float lod_distance = 0.0;

if (p_render_data->scene_data->cam_orthogonal) {
lod_distance = 1.0;
} else {
Vector3 aabb_min = inst->transformed_aabb.position;
Vector3 aabb_max = inst->transformed_aabb.position + inst->transformed_aabb.size;
Vector3 camera_position = p_render_data->scene_data->main_cam_transform.origin;
Vector3 surface_distance = Vector3(0.0, 0.0, 0.0).max(aabb_min - camera_position).max(camera_position - aabb_max);
akien-mga marked this conversation as resolved.
Show resolved Hide resolved

lod_distance = surface_distance.length();
}

while (surf) {
surf->sort.uses_forward_gi = 0;
surf->sort.uses_lightmap = 0;

// LOD

if (p_render_data->scene_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) {
float distance = 0.0;

// Check if camera is NOT inside the mesh AABB.
if (!inst->transformed_aabb.has_point(p_render_data->scene_data->main_cam_transform.origin)) {
// Get the LOD support points on the mesh AABB.
Vector3 lod_support_min = inst->transformed_aabb.get_support(p_render_data->scene_data->main_cam_transform.basis.get_column(Vector3::AXIS_Z));
Vector3 lod_support_max = inst->transformed_aabb.get_support(-p_render_data->scene_data->main_cam_transform.basis.get_column(Vector3::AXIS_Z));

// Get the distances to those points on the AABB from the camera origin.
float distance_min = (float)p_render_data->scene_data->main_cam_transform.origin.distance_to(lod_support_min);
float distance_max = (float)p_render_data->scene_data->main_cam_transform.origin.distance_to(lod_support_max);

if (distance_min * distance_max < 0.0) {
//crossing plane
distance = 0.0;
} else if (distance_min >= 0.0) {
distance = distance_min;
} else if (distance_max <= 0.0) {
distance = -distance_max;
}
}
if (p_render_data->scene_data->cam_orthogonal) {
distance = 1.0;
}

uint32_t indices = 0;
surf->sort.lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, indices);
surf->sort.lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, lod_distance * p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, indices);
if (p_render_data->render_info) {
indices = _indices_to_primitives(surf->primitive, indices);
if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1884,39 +1884,27 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const

GeometryInstanceSurfaceDataCache *surf = inst->surface_caches;

float lod_distance = 0.0;

if (p_render_data->scene_data->cam_orthogonal) {
lod_distance = 1.0;
} else {
Vector3 aabb_min = inst->transformed_aabb.position;
Vector3 aabb_max = inst->transformed_aabb.position + inst->transformed_aabb.size;
Vector3 camera_position = p_render_data->scene_data->main_cam_transform.origin;
Vector3 surface_distance = Vector3(0.0, 0.0, 0.0).max(aabb_min - camera_position).max(camera_position - aabb_max);
akien-mga marked this conversation as resolved.
Show resolved Hide resolved

lod_distance = surface_distance.length();
}

while (surf) {
surf->sort.uses_lightmap = 0;

// LOD

if (p_render_data->scene_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) {
float distance = 0.0;

// Check if camera is NOT inside the mesh AABB.
if (!inst->transformed_aabb.has_point(p_render_data->scene_data->main_cam_transform.origin)) {
// Get the LOD support points on the mesh AABB.
Vector3 lod_support_min = inst->transformed_aabb.get_support(p_render_data->scene_data->main_cam_transform.basis.get_column(Vector3::AXIS_Z));
Vector3 lod_support_max = inst->transformed_aabb.get_support(-p_render_data->scene_data->main_cam_transform.basis.get_column(Vector3::AXIS_Z));

// Get the distances to those points on the AABB from the camera origin.
float distance_min = (float)p_render_data->scene_data->main_cam_transform.origin.distance_to(lod_support_min);
float distance_max = (float)p_render_data->scene_data->main_cam_transform.origin.distance_to(lod_support_max);

if (distance_min * distance_max < 0.0) {
//crossing plane
distance = 0.0;
} else if (distance_min >= 0.0) {
distance = distance_min;
} else if (distance_max <= 0.0) {
distance = -distance_max;
}
}
if (p_render_data->scene_data->cam_orthogonal) {
distance = 1.0;
}

uint32_t indices = 0;
surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, indices);
surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, lod_distance * p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, indices);
if (p_render_data->render_info) {
indices = _indices_to_primitives(surf->primitive, indices);
if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
Expand Down
Loading