Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2022-02-15 19:51:19 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2022-02-15 19:53:22 +0300
commit48b26d9c2e0f4f4b6b5b7279c5bfc40c3ec77a6f (patch)
tree87ac7bfedae5d3e64c5fcac71a740bb02872ff94 /source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
parent430ced76d559d828b6f47c5fbb22530dcc70c257 (diff)
Fix T95697: GPU subdivision ignores custom normals
Similarly to the CPU subdivision, we interpolate custom loop normals from the coarse mesh, and this for the final normals.
Diffstat (limited to 'source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc')
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc39
1 files changed, 37 insertions, 2 deletions
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
index c92cf554fda..ef88a34021e 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc
@@ -216,6 +216,16 @@ static GPUVertFormat *get_normals_format()
return &format;
}
+static GPUVertFormat *get_custom_normals_format()
+{
+ static GPUVertFormat format = {0};
+ if (format.attr_len == 0) {
+ GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ GPU_vertformat_alias_add(&format, "lnor");
+ }
+ return &format;
+}
+
static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
struct MeshBatchCache *UNUSED(cache),
@@ -223,7 +233,8 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache,
void *UNUSED(data))
{
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buffer);
- const bool do_limit_normals = subdiv_cache->do_limit_normals;
+ const bool do_limit_normals = subdiv_cache->do_limit_normals &&
+ !subdiv_cache->use_custom_loop_normals;
/* Initialize the vertex buffer, it was already allocated. */
GPU_vertbuf_init_build_on_device(
@@ -231,7 +242,31 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache,
draw_subdiv_extract_pos_nor(subdiv_cache, vbo, do_limit_normals);
- if (!do_limit_normals) {
+ if (subdiv_cache->use_custom_loop_normals) {
+ Mesh *coarse_mesh = subdiv_cache->mesh;
+ float(*lnors)[3] = static_cast<float(*)[3]>(
+ CustomData_get_layer(&coarse_mesh->ldata, CD_NORMAL));
+ BLI_assert(lnors != NULL);
+
+ GPUVertBuf *src_custom_normals = GPU_vertbuf_calloc();
+ GPU_vertbuf_init_with_format(src_custom_normals, get_custom_normals_format());
+ GPU_vertbuf_data_alloc(src_custom_normals, coarse_mesh->totloop);
+
+ memcpy(
+ GPU_vertbuf_get_data(src_custom_normals), lnors, sizeof(float[3]) * coarse_mesh->totloop);
+
+ GPUVertBuf *dst_custom_normals = GPU_vertbuf_calloc();
+ GPU_vertbuf_init_build_on_device(
+ dst_custom_normals, get_custom_normals_format(), subdiv_cache->num_subdiv_loops);
+
+ draw_subdiv_interp_custom_data(subdiv_cache, src_custom_normals, dst_custom_normals, 3, 0);
+
+ draw_subdiv_finalize_custom_normals(subdiv_cache, dst_custom_normals, vbo);
+
+ GPU_vertbuf_discard(src_custom_normals);
+ GPU_vertbuf_discard(dst_custom_normals);
+ }
+ else if (!do_limit_normals) {
/* We cannot evaluate vertex normals using the limit surface, so compute them manually. */
GPUVertBuf *subdiv_loop_subdiv_vert_index = draw_subdiv_build_origindex_buffer(
subdiv_cache->subdiv_loop_subdiv_vert_index, subdiv_cache->num_subdiv_loops);