Merge pull request #92290 from clayjohn/LOD-fixes
Use distance to AABB surface to calculate Mesh LOD instead of using supports
This commit is contained in:
commit
8c6210a3eb
|
@ -1363,38 +1363,25 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const
|
||||||
|
|
||||||
GeometryInstanceSurface *surf = inst->surface_caches;
|
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);
|
||||||
|
|
||||||
|
lod_distance = surface_distance.length();
|
||||||
|
}
|
||||||
|
|
||||||
while (surf) {
|
while (surf) {
|
||||||
// LOD
|
// LOD
|
||||||
|
|
||||||
if (p_render_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) {
|
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;
|
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;
|
surf->index_count = indices;
|
||||||
|
|
||||||
if (p_render_data->render_info) {
|
if (p_render_data->render_info) {
|
||||||
|
|
|
@ -962,40 +962,27 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
|
||||||
|
|
||||||
GeometryInstanceSurfaceDataCache *surf = inst->surface_caches;
|
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);
|
||||||
|
|
||||||
|
lod_distance = surface_distance.length();
|
||||||
|
}
|
||||||
|
|
||||||
while (surf) {
|
while (surf) {
|
||||||
surf->sort.uses_forward_gi = 0;
|
surf->sort.uses_forward_gi = 0;
|
||||||
surf->sort.uses_lightmap = 0;
|
surf->sort.uses_lightmap = 0;
|
||||||
|
|
||||||
// LOD
|
// LOD
|
||||||
|
|
||||||
if (p_render_data->scene_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) {
|
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;
|
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) {
|
if (p_render_data->render_info) {
|
||||||
indices = _indices_to_primitives(surf->primitive, indices);
|
indices = _indices_to_primitives(surf->primitive, indices);
|
||||||
if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
|
if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
|
||||||
|
|
|
@ -1884,39 +1884,27 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
|
||||||
|
|
||||||
GeometryInstanceSurfaceDataCache *surf = inst->surface_caches;
|
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);
|
||||||
|
|
||||||
|
lod_distance = surface_distance.length();
|
||||||
|
}
|
||||||
|
|
||||||
while (surf) {
|
while (surf) {
|
||||||
surf->sort.uses_lightmap = 0;
|
surf->sort.uses_lightmap = 0;
|
||||||
|
|
||||||
// LOD
|
// LOD
|
||||||
|
|
||||||
if (p_render_data->scene_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) {
|
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;
|
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) {
|
if (p_render_data->render_info) {
|
||||||
indices = _indices_to_primitives(surf->primitive, indices);
|
indices = _indices_to_primitives(surf->primitive, indices);
|
||||||
if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
|
if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
|
||||||
|
|
Loading…
Reference in New Issue