This is the first step of moving the create infos back inside shader sources. All info files are now treated as source files. However, they are not considered in the include tree yet. This will come in another following PR. Each shader source file now generate a `.info` file containing only the create info declarations. This renames all info files so that they do not conflict with their previous versions that were copied (non-generated). Pull Request: https://projects.blender.org/blender/blender/pulls/146676
82 lines
3.1 KiB
GLSL
82 lines
3.1 KiB
GLSL
/* SPDX-FileCopyrightText: 2022-2023 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/**
|
|
* Finish computation of a few draw resource after sync.
|
|
*/
|
|
|
|
#include "draw_view_infos.hh"
|
|
|
|
#include "gpu_shader_math_matrix_transform_lib.glsl"
|
|
#include "gpu_shader_math_vector_reduce_lib.glsl"
|
|
#include "gpu_shader_math_vector_safe_lib.glsl"
|
|
#include "gpu_shader_utildefines_lib.glsl"
|
|
|
|
COMPUTE_SHADER_CREATE_INFO(draw_resource_finalize)
|
|
|
|
void main()
|
|
{
|
|
uint resource_id = gl_GlobalInvocationID.x;
|
|
if (resource_id >= uint(resource_len)) {
|
|
return;
|
|
}
|
|
|
|
float4x4 model_mat = matrix_buf[resource_id].model;
|
|
ObjectInfos infos = infos_buf[resource_id];
|
|
ObjectBounds bounds = bounds_buf[resource_id];
|
|
|
|
if (drw_bounds_corners_are_valid(bounds)) {
|
|
/* Convert corners to origin + sides in world space. */
|
|
float3 p0 = bounds.bounding_corners[0].xyz;
|
|
float3 p01 = bounds.bounding_corners[1].xyz - p0;
|
|
float3 p02 = bounds.bounding_corners[2].xyz - p0;
|
|
float3 p03 = bounds.bounding_corners[3].xyz - p0;
|
|
/* Avoid flat box. */
|
|
p01.x = max(p01.x, 1e-4f);
|
|
p02.y = max(p02.y, 1e-4f);
|
|
p03.z = max(p03.z, 1e-4f);
|
|
float3 diagonal = p01 + p02 + p03;
|
|
float3 center = p0 + diagonal * 0.5f;
|
|
float min_axis = reduce_min(abs(diagonal));
|
|
bounds.bounding_sphere.xyz = transform_point(model_mat, center);
|
|
/* We have to apply scaling to the diagonal. */
|
|
bounds.bounding_sphere.w = length(transform_direction(model_mat, diagonal)) * 0.5f;
|
|
bounds._inner_sphere_radius = min_axis;
|
|
bounds.bounding_corners[0].xyz = transform_point(model_mat, p0);
|
|
bounds.bounding_corners[1].xyz = transform_direction(model_mat, p01);
|
|
bounds.bounding_corners[2].xyz = transform_direction(model_mat, p02);
|
|
bounds.bounding_corners[3].xyz = transform_direction(model_mat, p03);
|
|
/* Always have correct handedness in the corners vectors. */
|
|
if (flag_test(infos.flag, OBJECT_NEGATIVE_SCALE)) {
|
|
bounds.bounding_corners[0].xyz += bounds.bounding_corners[1].xyz;
|
|
bounds.bounding_corners[1].xyz = -bounds.bounding_corners[1].xyz;
|
|
}
|
|
|
|
/* TODO: Bypass test for very large objects (see #67319). */
|
|
if (bounds.bounding_sphere.w > 1e12f) {
|
|
bounds.bounding_sphere.w = -2.0f;
|
|
}
|
|
|
|
/* Bypass culling test for objects that are flattened on one or more axes (see #127774).
|
|
* Fixing them is too much computation but might be worth doing if a use case for it.
|
|
* Do not compute the real length to save some instructions. */
|
|
float3 object_scale = float3(reduce_add(abs(model_mat[0].xyz)),
|
|
reduce_add(abs(model_mat[1].xyz)),
|
|
reduce_add(abs(model_mat[2].xyz)));
|
|
if (any(lessThan(abs(object_scale), float3(1e-10f)))) {
|
|
bounds.bounding_sphere.w = -2.0f;
|
|
}
|
|
|
|
/* Update bounds. */
|
|
bounds_buf[resource_id] = bounds;
|
|
}
|
|
|
|
float3 loc = infos.orco_add; /* Box center. */
|
|
float3 size = infos.orco_mul; /* Box half-extent. */
|
|
float3 orco_mul = safe_rcp(size * 2.0f);
|
|
float3 orco_add = (loc - size) * -orco_mul;
|
|
infos_buf[resource_id].orco_add = orco_add;
|
|
infos_buf[resource_id].orco_mul = orco_mul;
|
|
}
|