[Bf-blender-cvs] [e82827bf6ed] master: DRW: New High Quality Normal & Tangent extract
Clément Foucault
noreply at git.blender.org
Wed Feb 19 01:58:49 CET 2020
Commit: e82827bf6ed54a1d1552ac9176df9e309b4d29e2
Author: Clément Foucault
Date: Wed Feb 19 01:44:52 2020 +0100
Branches: master
https://developer.blender.org/rBe82827bf6ed54a1d1552ac9176df9e309b4d29e2
DRW: New High Quality Normal & Tangent extract
This patch adds a dedicated path to extract 16bit normals instead of packing them into 10bits/comp.
The tangents are also packed to 10bits/comp if not using the new High Quality Normal option.
Fix T61024 Degraded texture shading on dense meshes
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D6614
===================================================================
M release/scripts/startup/bl_ui/properties_render.py
M source/blender/draw/intern/draw_cache_extract.h
M source/blender/draw/intern/draw_cache_extract_mesh.c
M source/blender/draw/intern/draw_cache_impl_mesh.c
M source/blender/makesdna/DNA_scene_types.h
M source/blender/makesrna/intern/rna_scene.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index b4c864c16cd..9c422b58ee5 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -524,6 +524,25 @@ class RENDER_PT_eevee_hair(RenderButtonsPanel, Panel):
layout.prop(rd, "hair_subdiv")
+class RENDER_PT_eevee_performance(RenderButtonsPanel, Panel):
+ bl_label = "Performance"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
+
+ @classmethod
+ def poll(cls, context):
+ return (context.engine in cls.COMPAT_ENGINES)
+
+ def draw(self, context):
+ layout = self.layout
+ scene = context.scene
+ rd = scene.render
+
+ layout.use_property_split = True
+
+ layout.prop(rd, "use_high_quality_normals")
+
+
class RENDER_PT_opengl_sampling(RenderButtonsPanel, Panel):
bl_label = "Sampling"
COMPAT_ENGINES = {'BLENDER_WORKBENCH'}
@@ -674,6 +693,7 @@ classes = (
RENDER_PT_eevee_volumetric,
RENDER_PT_eevee_volumetric_lighting,
RENDER_PT_eevee_volumetric_shadows,
+ RENDER_PT_eevee_performance,
RENDER_PT_eevee_hair,
RENDER_PT_eevee_shadows,
RENDER_PT_eevee_indirect_lighting,
diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h
index 9228147af44..6226b5dcf7f 100644
--- a/source/blender/draw/intern/draw_cache_extract.h
+++ b/source/blender/draw/intern/draw_cache_extract.h
@@ -253,6 +253,7 @@ void mesh_buffer_cache_create_requested(MeshBatchCache *cache,
const bool do_uvedit,
const bool use_subsurf_fdots,
const DRW_MeshCDMask *cd_layer_used,
+ const Scene *scene,
const ToolSettings *ts,
const bool use_hide);
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index 61a4a963cf9..edd7dee004c 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -1579,6 +1579,81 @@ static const MeshExtract extract_pos_nor = {
};
/** \} */
+/* ---------------------------------------------------------------------- */
+/** \name Extract HQ Loop Normal
+ * \{ */
+
+typedef struct gpuHQNor {
+ short x, y, z, w;
+} gpuHQNor;
+
+static void *extract_lnor_hq_init(const MeshRenderData *mr, void *buf)
+{
+ static GPUVertFormat format = {0};
+ if (format.attr_len == 0) {
+ GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ GPU_vertformat_alias_add(&format, "lnor");
+ }
+ GPUVertBuf *vbo = buf;
+ GPU_vertbuf_init_with_format(vbo, &format);
+ GPU_vertbuf_data_alloc(vbo, mr->loop_len);
+
+ return vbo->data;
+}
+
+static void extract_lnor_hq_loop_bmesh(const MeshRenderData *mr, int l, BMLoop *loop, void *data)
+{
+ if (mr->loop_normals) {
+ normal_float_to_short_v3(&((gpuHQNor *)data)[l].x, mr->loop_normals[l]);
+ }
+ else if (BM_elem_flag_test(loop->f, BM_ELEM_SMOOTH)) {
+ normal_float_to_short_v3(&((gpuHQNor *)data)[l].x, loop->v->no);
+ }
+ else {
+ normal_float_to_short_v3(&((gpuHQNor *)data)[l].x, loop->f->no);
+ }
+}
+
+static void extract_lnor_hq_loop_mesh(
+ const MeshRenderData *mr, int l, const MLoop *mloop, int p, const MPoly *mpoly, void *data)
+{
+ if (mr->loop_normals) {
+ normal_float_to_short_v3(&((gpuHQNor *)data)[l].x, mr->loop_normals[l]);
+ }
+ else if (mpoly->flag & ME_SMOOTH) {
+ copy_v3_v3_short(&((gpuHQNor *)data)[l].x, mr->mvert[mloop->v].no);
+ }
+ else {
+ normal_float_to_short_v3(&((gpuHQNor *)data)[l].x, mr->poly_normals[p]);
+ }
+ /* Flag for paint mode overlay. */
+ if (mpoly->flag & ME_HIDE) {
+ ((gpuHQNor *)data)[l].w = -1;
+ }
+ else if (mpoly->flag & ME_FACE_SEL) {
+ ((gpuHQNor *)data)[l].w = 1;
+ }
+ else {
+ ((gpuHQNor *)data)[l].w = 0;
+ }
+}
+
+static const MeshExtract extract_lnor_hq = {
+ extract_lnor_hq_init,
+ NULL,
+ NULL,
+ extract_lnor_hq_loop_bmesh,
+ extract_lnor_hq_loop_mesh,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ MR_DATA_LOOP_NOR,
+ true,
+};
+
+/** \} */
/* ---------------------------------------------------------------------- */
/** \name Extract Loop Normal
* \{ */
@@ -1762,8 +1837,11 @@ static const MeshExtract extract_uv = {
/** \name Extract Tangent layers
* \{ */
-static void *extract_tan_init(const MeshRenderData *mr, void *buf)
+static void extract_tan_ex(const MeshRenderData *mr, GPUVertBuf *vbo, const bool do_hq)
{
+ GPUVertCompType comp_type = do_hq ? GPU_COMP_F32 : GPU_COMP_I10;
+ GPUVertFetchMode fetch_mode = do_hq ? GPU_FETCH_FLOAT : GPU_FETCH_INT_TO_FLOAT_UNIT;
+
GPUVertFormat format = {0};
GPU_vertformat_deinterleave(&format);
@@ -1784,7 +1862,7 @@ static void *extract_tan_init(const MeshRenderData *mr, void *buf)
GPU_vertformat_safe_attrib_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTRIB_NAME);
/* Tangent layer name. */
BLI_snprintf(attr_name, sizeof(attr_name), "t%s", attr_safe_name);
- GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ GPU_vertformat_attr_add(&format, attr_name, comp_type, 4, fetch_mode);
/* Active render layer name. */
if (i == CustomData_get_render_layer(cd_ldata, CD_MLOOPUV)) {
GPU_vertformat_alias_add(&format, "t");
@@ -1860,7 +1938,7 @@ static void *extract_tan_init(const MeshRenderData *mr, void *buf)
const char *layer_name = CustomData_get_layer_name(cd_ldata, CD_TANGENT, 0);
GPU_vertformat_safe_attrib_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTRIB_NAME);
BLI_snprintf(attr_name, sizeof(*attr_name), "t%s", attr_safe_name);
- GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ GPU_vertformat_attr_add(&format, attr_name, comp_type, 4, fetch_mode);
GPU_vertformat_alias_add(&format, "t");
GPU_vertformat_alias_add(&format, "at");
}
@@ -1876,23 +1954,56 @@ static void *extract_tan_init(const MeshRenderData *mr, void *buf)
v_len = 1;
}
- GPUVertBuf *vbo = buf;
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, v_len);
- float(*tan_data)[4] = (float(*)[4])vbo->data;
- for (int i = 0; i < tan_len; i++) {
- void *layer_data = CustomData_get_layer_named(cd_ldata, CD_TANGENT, tangent_names[i]);
- memcpy(tan_data, layer_data, sizeof(*tan_data) * mr->loop_len);
- tan_data += mr->loop_len;
+ if (do_hq) {
+ short(*tan_data)[4] = (short(*)[4])vbo->data;
+ for (int i = 0; i < tan_len; i++) {
+ const char *name = tangent_names[i];
+ float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_named(cd_ldata, CD_TANGENT, name);
+ for (int l = 0; l < mr->loop_len; l++) {
+ normal_float_to_short_v3(*tan_data, layer_data[l]);
+ (*tan_data)[3] = (layer_data[l][3] > 0.0f) ? SHRT_MAX : SHRT_MIN;
+ tan_data++;
+ }
+ }
+ if (use_orco_tan) {
+ float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_n(cd_ldata, CD_TANGENT, 0);
+ for (int l = 0; l < mr->loop_len; l++) {
+ normal_float_to_short_v3(*tan_data, layer_data[l]);
+ (*tan_data)[3] = (layer_data[l][3] > 0.0f) ? SHRT_MAX : SHRT_MIN;
+ tan_data++;
+ }
+ }
}
- if (use_orco_tan) {
- void *layer_data = CustomData_get_layer_n(cd_ldata, CD_TANGENT, 0);
- memcpy(tan_data, layer_data, sizeof(*tan_data) * mr->loop_len);
+ else {
+ GPUPackedNormal *tan_data = (GPUPackedNormal *)vbo->data;
+ for (int i = 0; i < tan_len; i++) {
+ const char *name = tangent_names[i];
+ float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_named(cd_ldata, CD_TANGENT, name);
+ for (int l = 0; l < mr->loop_len; l++) {
+ *tan_data = GPU_normal_convert_i10_v3(layer_data[l]);
+ tan_data->w = (layer_data[l][3] > 0.0f) ? 1 : -2;
+ tan_data++;
+ }
+ }
+ if (use_orco_tan) {
+ float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_n(cd_ldata, CD_TANGENT, 0);
+ for (int l = 0; l < mr->loop_len; l++) {
+ *tan_data = GPU_normal_convert_i10_v3(layer_data[l]);
+ tan_data->w = (layer_data[l][3] > 0.0f) ? 1 : -2;
+ tan_data++;
+ }
+ }
}
CustomData_free_layers(cd_ldata, CD_TANGENT, mr->loop_len);
+}
+static void *extract_tan_init(const MeshRenderData *mr, void *buf)
+{
+ extract_tan_ex(mr, buf, false);
return NULL;
}
@@ -1913,6 +2024,33 @@ static const MeshExtract extract_tan = {
/** \} */
+/* ---------------------------------------------------------------------- */
+/** \name Extract HQ Tangent layers
+ * \{ */
+
+static void *extract_tan_hq_init(const MeshRenderData *mr, void *buf)
+{
+ extract_tan_ex(mr, buf, true);
+ return NULL;
+}
+
+static const MeshExtract extract_tan_hq = {
+ extract_tan_hq_init,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ MR_DATA_POLY_NOR | MR_DATA_TAN_LOOP_NOR | MR_DATA_LOOPTRI,
+ false,
+};
+
+/** \} */
+
/* ---------------------------------------------------------------------- */
/** \name Extract VCol
* \{ */
@@ -4354,11 +4492,20 @@ static void extract_range_task_create(
}
static void extract_task_create(TaskPool *task_pool,
+ const Scene *scene,
const MeshRenderData *mr,
const MeshExtract *extract,
void *buf,
int32_t *task_counter)
{
+ const bool do_hq_normals = (scene->r.perf_flag & SCE_PERF_HQ_NORMALS) != 0;
+ if (do_hq_normals && (extract == &extract_lnor)) {
+ extract = &extract_lnor_hq;
+ }
+ if (do_hq_normals && (extract == &extract_tan)) {
+ extract = &extract_tan_hq;
+ }
+
/* Divide extraction of the VBO/IBO into sensible chunks of works. */
ExtractTaskData *taskdata = MEM_mal
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list