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:
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl27
-rw-r--r--source/blender/draw/intern/draw_cache_impl_subdivision.cc32
-rw-r--r--source/blender/draw/intern/draw_subdivision.h5
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc39
-rw-r--r--source/blender/draw/intern/shaders/common_subdiv_custom_data_interp_comp.glsl4
-rw-r--r--source/blender/draw/intern/shaders/common_subdiv_normals_finalize_comp.glsl21
6 files changed, 97 insertions, 31 deletions
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
index e9525ce9de0..d8f8a1cc03f 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
@@ -254,31 +254,8 @@ void main()
* Morgan McGuire and Kyle Whitson
* http://graphics.cs.williams.edu
*
- *
- * Copyright (c) Morgan McGuire and Williams College, 2006
- * All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-2-Clause
+ * Copyright 2006 Morgan McGuire and Williams College, All rights reserved.
*/
#ifdef BLUR2
diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc
index 7efd0de7a44..ac2e5bbca2e 100644
--- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc
+++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc
@@ -1340,8 +1340,9 @@ void draw_subdiv_interp_custom_data(const DRWSubdivCache *cache,
drw_subdiv_compute_dispatch(cache, shader, 0, dst_offset, cache->num_subdiv_quads);
- /* This generates a vertex buffer, so we need to put a barrier on the vertex attribute array. */
- GPU_memory_barrier(GPU_BARRIER_VERTEX_ATTRIB_ARRAY);
+ /* This generates a vertex buffer, so we need to put a barrier on the vertex attribute array. Put
+ * a barrier on the shader storage as we may use the result in another compute shader. */
+ GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE | GPU_BARRIER_VERTEX_ATTRIB_ARRAY);
/* Cleanup. */
GPU_shader_unbind();
@@ -1422,6 +1423,28 @@ void draw_subdiv_finalize_normals(const DRWSubdivCache *cache,
GPU_shader_unbind();
}
+void draw_subdiv_finalize_custom_normals(const DRWSubdivCache *cache,
+ GPUVertBuf *src_custom_normals,
+ GPUVertBuf *pos_nor)
+{
+ GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_NORMALS_FINALIZE, "#define CUSTOM_NORMALS");
+ GPU_shader_bind(shader);
+
+ GPU_vertbuf_bind_as_ssbo(src_custom_normals, 0);
+ /* outputPosNor is bound at index 2 in the base shader. */
+ GPU_vertbuf_bind_as_ssbo(pos_nor, 2);
+
+ drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache->num_subdiv_quads);
+
+ /* This generates a vertex buffer, so we need to put a barrier on the vertex attribute array.
+ * We also need it for subsequent compute shaders, so a barrier on the shader storage is also
+ * needed. */
+ GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE | GPU_BARRIER_VERTEX_ATTRIB_ARRAY);
+
+ /* Cleanup. */
+ GPU_shader_unbind();
+}
+
void draw_subdiv_build_tris_buffer(const DRWSubdivCache *cache,
GPUIndexBuf *subdiv_tris,
const int material_count)
@@ -1813,6 +1836,11 @@ static bool draw_subdiv_create_requested_buffers(const Scene *scene,
/* We can only evaluate limit normals if the patches are adaptive. */
draw_cache->do_limit_normals = settings.is_adaptive;
+ draw_cache->use_custom_loop_normals = (smd->flags & eSubsurfModifierFlag_UseCustomNormals) &&
+ (mesh_eval->flag & ME_AUTOSMOOTH) &&
+ CustomData_has_layer(&mesh_eval->ldata,
+ CD_CUSTOMLOOPNORMAL);
+
if (DRW_ibo_requested(mbc->buff.ibo.tris)) {
draw_subdiv_cache_ensure_mat_offsets(draw_cache, mesh_eval, batch_cache->mat_len);
}
diff --git a/source/blender/draw/intern/draw_subdivision.h b/source/blender/draw/intern/draw_subdivision.h
index 394482c0862..6714ba571e5 100644
--- a/source/blender/draw/intern/draw_subdivision.h
+++ b/source/blender/draw/intern/draw_subdivision.h
@@ -52,6 +52,7 @@ typedef struct DRWSubdivCache {
struct Subdiv *subdiv;
bool optimal_display;
bool do_limit_normals;
+ bool use_custom_loop_normals;
/* Coordinates used to evaluate patches for UVs, positions, and normals. */
struct GPUVertBuf *patch_coords;
@@ -171,6 +172,10 @@ void draw_subdiv_finalize_normals(const DRWSubdivCache *cache,
struct GPUVertBuf *subdiv_loop_subdiv_vert_index,
struct GPUVertBuf *pos_nor);
+void draw_subdiv_finalize_custom_normals(const DRWSubdivCache *cache,
+ GPUVertBuf *src_custom_normals,
+ GPUVertBuf *pos_nor);
+
void draw_subdiv_extract_pos_nor(const DRWSubdivCache *cache,
struct GPUVertBuf *pos_nor,
bool do_limit_normals);
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 6e2cb8ad3e3..bd7f1ba0128 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
@@ -200,6 +200,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),
@@ -207,7 +217,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(
@@ -215,7 +226,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);
diff --git a/source/blender/draw/intern/shaders/common_subdiv_custom_data_interp_comp.glsl b/source/blender/draw/intern/shaders/common_subdiv_custom_data_interp_comp.glsl
index 36c3970d9a0..df0016761e2 100644
--- a/source/blender/draw/intern/shaders/common_subdiv_custom_data_interp_comp.glsl
+++ b/source/blender/draw/intern/shaders/common_subdiv_custom_data_interp_comp.glsl
@@ -185,7 +185,7 @@ void main()
}
else {
/* Interpolate the src data for the center. */
- uint loop_end = loop_start + number_of_vertices - 1;
+ uint loop_end = loop_start + number_of_vertices;
Vertex center_value;
clear(center_value);
@@ -202,7 +202,7 @@ void main()
uint prev_coarse_corner = (current_coarse_corner + number_of_vertices - 1) %
number_of_vertices;
- v0 = read_vertex(loop_start);
+ v0 = read_vertex(loop_start + current_coarse_corner);
v1 = average(v0, read_vertex(loop_start + next_coarse_corner));
v3 = average(v0, read_vertex(loop_start + prev_coarse_corner));
diff --git a/source/blender/draw/intern/shaders/common_subdiv_normals_finalize_comp.glsl b/source/blender/draw/intern/shaders/common_subdiv_normals_finalize_comp.glsl
index 84cd65d4161..c2e0e752783 100644
--- a/source/blender/draw/intern/shaders/common_subdiv_normals_finalize_comp.glsl
+++ b/source/blender/draw/intern/shaders/common_subdiv_normals_finalize_comp.glsl
@@ -1,6 +1,18 @@
/* To be compile with common_subdiv_lib.glsl */
+#ifdef CUSTOM_NORMALS
+struct CustomNormal {
+ float x;
+ float y;
+ float z;
+};
+
+layout(std430, binding = 0) readonly buffer inputNormals
+{
+ CustomNormal custom_normals[];
+};
+#else
layout(std430, binding = 0) readonly buffer inputNormals
{
vec3 vertex_normals[];
@@ -10,6 +22,7 @@ layout(std430, binding = 1) readonly buffer inputSubdivVertLoopMap
{
uint vert_loop_map[];
};
+#endif
layout(std430, binding = 2) buffer outputPosNor
{
@@ -26,9 +39,17 @@ void main()
uint start_loop_index = quad_index * 4;
+#ifdef CUSTOM_NORMALS
+ for (int i = 0; i < 4; i++) {
+ CustomNormal custom_normal = custom_normals[start_loop_index + i];
+ vec3 nor = vec3(custom_normal.x, custom_normal.y, custom_normal.z);
+ set_vertex_nor(pos_nor[start_loop_index + i], normalize(nor));
+ }
+#else
for (int i = 0; i < 4; i++) {
uint subdiv_vert_index = vert_loop_map[start_loop_index + i];
vec3 nor = vertex_normals[subdiv_vert_index];
set_vertex_nor(pos_nor[start_loop_index + i], nor);
}
+#endif
}