Mesh: Add viewport normals simplify option #113975

Merged
Hans Goudey merged 154 commits from HooglyBoogly/blender:mesh-normals-simplify-option into main 2023-12-16 00:18:49 +01:00
8 changed files with 46 additions and 13 deletions

View File

@ -2272,6 +2272,7 @@ class CYCLES_RENDER_PT_simplify_viewport(CyclesButtonsPanel, Panel):
col.prop(rd, "simplify_child_particles", text="Child Particles")
col.prop(cscene, "texture_limit", text="Texture Limit")
col.prop(rd, "simplify_volumes", text="Volume Resolution")
col.prop(rd, "use_simplify_normals", text="Normals")
class CYCLES_RENDER_PT_simplify_render(CyclesButtonsPanel, Panel):

View File

@ -1162,6 +1162,9 @@ class RENDER_PT_simplify_viewport(RenderButtonsPanel, Panel):
col = flow.column()
col.prop(rd, "simplify_shadows", text="Shadow Resolution")
col = flow.column()
col.prop(rd, "use_simplify_normals", text="Normals")
class RENDER_PT_simplify_render(RenderButtonsPanel, Panel):
bl_label = "Render"

View File

@ -4674,7 +4674,7 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
}
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
scene->r.mode &= ~(R_MODE_UNUSED_1 | R_MODE_UNUSED_2 | R_MODE_UNUSED_3 | R_MODE_UNUSED_4 |
scene->r.mode &= ~(R_SIMPLIFY_NORMALS | R_MODE_UNUSED_2 | R_MODE_UNUSED_3 | R_MODE_UNUSED_4 |
R_MODE_UNUSED_5 | R_MODE_UNUSED_6 | R_MODE_UNUSED_7 | R_MODE_UNUSED_8 |
R_MODE_UNUSED_10 | R_MODE_UNUSED_13 | R_MODE_UNUSED_16 |
R_MODE_UNUSED_17 | R_MODE_UNUSED_18 | R_MODE_UNUSED_19 |

View File

@ -699,6 +699,7 @@ void mesh_buffer_cache_create_requested(TaskGraph *task_graph,
mr->use_hide = use_hide;
mr->use_subsurf_fdots = mr->mesh && !mr->mesh->runtime->subsurf_face_dot_tags.is_empty();
mr->use_final_mesh = do_final;
mr->use_simplify_normals = (scene->r.mode & R_SIMPLIFY) && (scene->r.mode & R_SIMPLIFY_NORMALS);
#ifdef DEBUG_TIME
double rdata_end = PIL_check_seconds_timer();

View File

@ -492,7 +492,7 @@ void mesh_render_data_update_normals(MeshRenderData &mr, const eMRDataType data_
if (data_flag & (MR_DATA_POLY_NOR | MR_DATA_LOOP_NOR | MR_DATA_TAN_LOOP_NOR)) {
mr.face_normals = mr.mesh->face_normals();
}
if (((data_flag & MR_DATA_LOOP_NOR) &&
if (((data_flag & MR_DATA_LOOP_NOR) && !mr.use_simplify_normals &&
mr.normals_domain == blender::bke::MeshNormalDomain::Corner) ||
(data_flag & MR_DATA_TAN_LOOP_NOR))
{
@ -504,7 +504,8 @@ void mesh_render_data_update_normals(MeshRenderData &mr, const eMRDataType data_
if (data_flag & MR_DATA_POLY_NOR) {
/* Use #BMFace.no instead. */
}
if (((data_flag & MR_DATA_LOOP_NOR) && bm_loop_normals_required(mr.bm)) ||
if (((data_flag & MR_DATA_LOOP_NOR) && !mr.use_simplify_normals &&
bm_loop_normals_required(mr.bm)) ||
(data_flag & MR_DATA_TAN_LOOP_NOR))
{

View File

@ -56,6 +56,7 @@ struct MeshRenderData {
bool use_subsurf_fdots;
bool use_final_mesh;
bool hide_unmapped_edges;
bool use_simplify_normals;
/** Use for #MeshStatVis calculation which use world-space coords. */
float obmat[4][4];

View File

@ -2090,7 +2090,7 @@ enum {
/** #RenderData::mode. */
enum {
R_MODE_UNUSED_0 = 1 << 0, /* dirty */
R_MODE_UNUSED_1 = 1 << 1, /* cleared */
R_SIMPLIFY_NORMALS = 1 << 1,
R_MODE_UNUSED_2 = 1 << 2, /* cleared */
R_MODE_UNUSED_3 = 1 << 3, /* cleared */
R_MODE_UNUSED_4 = 1 << 4, /* cleared */

View File

@ -2012,7 +2012,7 @@ static void rna_Scene_uv_select_mode_update(bContext *C, PointerRNA * /*ptr*/)
ED_uvedit_selectmode_clean_multi(C);
}
static void object_simplify_update(Object *ob)
static void object_simplify_update(Scene *scene, Object *ob, bool update_normals)
{
ModifierData *md;
ParticleSystem *psys;
@ -2037,7 +2037,7 @@ static void object_simplify_update(Object *ob)
if (ob->instance_collection) {
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (ob->instance_collection, ob_collection) {
object_simplify_update(ob_collection);
object_simplify_update(scene, ob_collection, update_normals);
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
@ -2045,22 +2045,27 @@ static void object_simplify_update(Object *ob)
if (ob->type == OB_VOLUME) {
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
}
if (scene->r.mode & R_SIMPLIFY_NORMALS || update_normals) {
if (OB_TYPE_IS_GEOMETRY(ob->type)) {
HooglyBoogly marked this conversation as resolved Outdated

Couldn't non-geometry objects skip the DEG_id_tag_update? e.g. check OB_TYPE_IS_GEOMETRY(ob) before tagging.

Couldn't non-geometry objects skip the `DEG_id_tag_update`? e.g. check `OB_TYPE_IS_GEOMETRY(ob)` before tagging.
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
}
}
}
HooglyBoogly marked this conversation as resolved Outdated

Prefer rna_Scene_use_simplify_update_impl when an implementation function needs to be split out, matching: rna_Object_internal_update_data_impl, rna_userdef_is_dirty_update_impl.

Prefer `rna_Scene_use_simplify_update_impl` when an implementation function needs to be split out, matching: `rna_Object_internal_update_data_impl`, `rna_userdef_is_dirty_update_impl`.
static void rna_Scene_use_simplify_update(Main *bmain, Scene * /*scene*/, PointerRNA *ptr)
static void rna_Scene_simplify_update_impl(Main *bmain, Scene *sce, bool update_normals)
{
Scene *sce = (Scene *)ptr->owner_id;
Scene *sce_iter;
Base *base;
BKE_main_id_tag_listbase(&bmain->objects, LIB_TAG_DOIT, true);
FOREACH_SCENE_OBJECT_BEGIN (sce, ob) {
object_simplify_update(ob);
object_simplify_update(sce, ob, update_normals);
}
FOREACH_SCENE_OBJECT_END;
for (SETLOOPER_SET_ONLY(sce, sce_iter, base)) {
object_simplify_update(base->object);
object_simplify_update(sce, base->object, update_normals);
}
WM_main_add_notifier(NC_GEOM | ND_DATA, nullptr);
@ -2068,12 +2073,25 @@ static void rna_Scene_use_simplify_update(Main *bmain, Scene * /*scene*/, Pointe
DEG_id_tag_update(&sce->id, ID_RECALC_COPY_ON_WRITE);
}
static void rna_Scene_simplify_update(Main *bmain, Scene *scene, PointerRNA *ptr)
static void rna_Scene_use_simplify_update(Main *bmain, Scene * /*scene*/, PointerRNA *ptr)
{
Scene *sce = (Scene *)ptr->owner_id;
rna_Scene_simplify_update_impl(bmain, sce, false);
}
if (sce->r.mode & R_SIMPLIFY) {
rna_Scene_use_simplify_update(bmain, scene, ptr);
static void rna_Scene_simplify_update(Main *bmain, Scene *scene, PointerRNA * /*ptr*/)
{
if (scene->r.mode & R_SIMPLIFY) {
rna_Scene_simplify_update_impl(bmain, scene, false);
}
}
static void rna_Scene_use_simplify_normals_update(Main *bmain, Scene *scene, PointerRNA * /*ptr*/)
{
/* NOTE: Ideally this would just force recalculation of the draw batch cache normals.
* That's complicated enough to not be worth it here. */
if (scene->r.mode & R_SIMPLIFY) {
rna_Scene_simplify_update_impl(bmain, scene, true);
}
}
@ -7080,6 +7098,14 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop, "Simplify Volumes", "Resolution percentage of volume objects in viewport");
RNA_def_property_update(prop, 0, "rna_Scene_simplify_update");
prop = RNA_def_property(srna, "use_simplify_normals", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, nullptr, "mode", R_SIMPLIFY_NORMALS);
RNA_def_property_ui_text(prop,
"Mesh Normals",
"Skip computing custom normals and face corner normals for displaying "
"meshes in the viewport");
RNA_def_property_update(prop, 0, "rna_Scene_use_simplify_normals_update");
/* EEVEE - Simplify Options */
prop = RNA_def_property(srna, "simplify_shadows_render", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_default(prop, 1.0);