diff options
author | Pablo Dobarro <pablodp606@gmail.com> | 2021-03-14 23:14:58 +0300 |
---|---|---|
committer | Pablo Dobarro <pablodp606@gmail.com> | 2021-03-14 23:14:58 +0300 |
commit | 476b333a3ef8dff9fa8b5b3b6adff2565c7be840 (patch) | |
tree | 97e0c3745f223c73317a171bd581db06deb0d604 /source | |
parent | 4ad1a7ab313d9a0382cf4c522412b3b882184b86 (diff) | |
parent | a01fb22f28df21acab103a5216591355b1dc85d7 (diff) |
Merge branch 'master' into sculpt-dev
Diffstat (limited to 'source')
73 files changed, 1061 insertions, 915 deletions
diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h index 574d9904dc4..a98bfd1e3df 100644 --- a/source/blender/blenkernel/BKE_attribute.h +++ b/source/blender/blenkernel/BKE_attribute.h @@ -39,6 +39,7 @@ struct ReportList; /* Attribute.domain */ typedef enum AttributeDomain { + ATTR_DOMAIN_AUTO = -1, /* Use for nodes to choose automatically based on other data. */ ATTR_DOMAIN_POINT = 0, /* Mesh, Hair or PointCloud Point */ ATTR_DOMAIN_EDGE = 1, /* Mesh Edge */ ATTR_DOMAIN_CORNER = 2, /* Mesh Corner */ diff --git a/source/blender/blenkernel/BKE_mesh_boolean_convert.h b/source/blender/blenkernel/BKE_mesh_boolean_convert.h index a87f2609e46..1bb1d9ea8dc 100644 --- a/source/blender/blenkernel/BKE_mesh_boolean_convert.h +++ b/source/blender/blenkernel/BKE_mesh_boolean_convert.h @@ -29,6 +29,7 @@ extern "C" { Mesh *BKE_mesh_boolean(const Mesh **meshes, const float (*obmats[])[4][4], + const short **material_remaps, const int meshes_len, const bool use_self, const bool hole_tolerant, diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 2c543a0a014..0379dea9e8c 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -1373,6 +1373,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree, #define GEO_NODE_ATTRIBUTE_SEPARATE_XYZ 1028 #define GEO_NODE_SUBDIVIDE 1029 #define GEO_NODE_ATTRIBUTE_REMOVE 1030 +#define GEO_NODE_ATTRIBUTE_CONVERT 1031 /** \} */ diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index 01a1333c3ce..8482f096df1 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -31,7 +31,6 @@ #include "BLI_color.hh" #include "BLI_float2.hh" #include "BLI_span.hh" -#include "BLI_threads.h" #include "CLG_log.h" @@ -375,10 +374,6 @@ ReadAttributePtr BuiltinCustomDataLayerProvider::try_get_for_read( return {}; } - if (update_on_read_ != nullptr) { - update_on_read_(component); - } - const int domain_size = component.attribute_domain_size(domain_); const void *data = CustomData_get_layer(custom_data, stored_type_); if (data == nullptr) { diff --git a/source/blender/blenkernel/intern/attribute_access_intern.hh b/source/blender/blenkernel/intern/attribute_access_intern.hh index 299da4c97fe..19349c69662 100644 --- a/source/blender/blenkernel/intern/attribute_access_intern.hh +++ b/source/blender/blenkernel/intern/attribute_access_intern.hh @@ -405,7 +405,6 @@ class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider { const CustomDataAccessInfo custom_data_access_; const AsReadAttribute as_read_attribute_; const AsWriteAttribute as_write_attribute_; - const UpdateOnRead update_on_read_; const UpdateOnWrite update_on_write_; public: @@ -419,7 +418,6 @@ class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider { const CustomDataAccessInfo custom_data_access, const AsReadAttribute as_read_attribute, const AsWriteAttribute as_write_attribute, - const UpdateOnRead update_on_read, const UpdateOnWrite update_on_write) : BuiltinAttributeProvider( std::move(attribute_name), domain, attribute_type, creatable, writable, deletable), @@ -427,7 +425,6 @@ class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider { custom_data_access_(custom_data_access), as_read_attribute_(as_read_attribute), as_write_attribute_(as_write_attribute), - update_on_read_(update_on_read), update_on_write_(update_on_write) { } diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index 4019ceb123f..c6e32c3e8bd 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -15,7 +15,6 @@ */ #include "BLI_listbase.h" -#include "BLI_threads.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -535,43 +534,6 @@ static WriteAttributePtr make_material_index_write_attribute(void *data, const i ATTR_DOMAIN_POLYGON, MutableSpan<MPoly>((MPoly *)data, domain_size)); } -static float3 get_vertex_normal(const MVert &vert) -{ - float3 result; - normal_short_to_float_v3(result, vert.no); - return result; -} - -static ReadAttributePtr make_vertex_normal_read_attribute(const void *data, const int domain_size) -{ - return std::make_unique<DerivedArrayReadAttribute<MVert, float3, get_vertex_normal>>( - ATTR_DOMAIN_POINT, Span<MVert>((const MVert *)data, domain_size)); -} - -static void update_vertex_normals_when_dirty(const GeometryComponent &component) -{ - const Mesh *mesh = get_mesh_from_component_for_read(component); - if (mesh == nullptr) { - return; - } - - /* Since normals are derived data, const write access to them is okay. However, ensure that - * two threads don't use write normals to a mesh at the same time. Note that this relies on - * the idempotence of the operation; calculating the normals just fills the MVert struct - * rather than allocating new memory. */ - if (mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) { - ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime.eval_mutex; - BLI_mutex_lock(mesh_eval_mutex); - - /* Check again to avoid a second thread needlessly recalculating the same normals. */ - if (mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) { - BKE_mesh_calc_normals(const_cast<Mesh *>(mesh)); - } - - BLI_mutex_unlock(mesh_eval_mutex); - } -} - static bool get_shade_smooth(const MPoly &mpoly) { return mpoly.flag & ME_SMOOTH; @@ -805,6 +767,65 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider { }; /** + * This provider makes face normals available as a read-only float3 attribute. + */ +class NormalAttributeProvider final : public BuiltinAttributeProvider { + public: + NormalAttributeProvider() + : BuiltinAttributeProvider( + "normal", ATTR_DOMAIN_POLYGON, CD_PROP_FLOAT3, NonCreatable, Readonly, NonDeletable) + { + } + + ReadAttributePtr try_get_for_read(const GeometryComponent &component) const + { + const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component); + const Mesh *mesh = mesh_component.get_for_read(); + if (mesh == nullptr) { + return {}; + } + + /* Use existing normals if possible. */ + if (!(mesh->runtime.cd_dirty_poly & CD_MASK_NORMAL) && + CustomData_has_layer(&mesh->pdata, CD_NORMAL)) { + const void *data = CustomData_get_layer(&mesh->pdata, CD_NORMAL); + + return std::make_unique<ArrayReadAttribute<float3>>( + ATTR_DOMAIN_POLYGON, Span<float3>((const float3 *)data, mesh->totpoly)); + } + + Array<float3> normals(mesh->totpoly); + for (const int i : IndexRange(mesh->totpoly)) { + const MPoly *poly = &mesh->mpoly[i]; + BKE_mesh_calc_poly_normal(poly, &mesh->mloop[poly->loopstart], mesh->mvert, normals[i]); + } + + return std::make_unique<OwnedArrayReadAttribute<float3>>(ATTR_DOMAIN_POLYGON, + std::move(normals)); + } + + WriteAttributePtr try_get_for_write(GeometryComponent &UNUSED(component)) const + { + return {}; + } + + bool try_delete(GeometryComponent &UNUSED(component)) const + { + return false; + } + + bool try_create(GeometryComponent &UNUSED(component)) const + { + return false; + } + + bool exists(const GeometryComponent &component) const + { + return component.attribute_domain_size(ATTR_DOMAIN_POLYGON) != 0; + } +}; + +/** * In this function all the attribute providers for a mesh component are created. Most data in this * function is statically allocated, because it does not change over time. */ @@ -854,9 +875,10 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() point_access, make_vertex_position_read_attribute, make_vertex_position_write_attribute, - nullptr, tag_normals_dirty_when_writing_position); + static NormalAttributeProvider normal; + static BuiltinCustomDataLayerProvider material_index("material_index", ATTR_DOMAIN_POLYGON, CD_PROP_INT32, @@ -867,7 +889,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() polygon_access, make_material_index_read_attribute, make_material_index_write_attribute, - nullptr, nullptr); static BuiltinCustomDataLayerProvider shade_smooth("shade_smooth", @@ -880,22 +901,8 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() polygon_access, make_shade_smooth_read_attribute, make_shade_smooth_write_attribute, - nullptr, nullptr); - static BuiltinCustomDataLayerProvider vertex_normal("vertex_normal", - ATTR_DOMAIN_POINT, - CD_PROP_FLOAT3, - CD_MVERT, - BuiltinAttributeProvider::NonCreatable, - BuiltinAttributeProvider::Readonly, - BuiltinAttributeProvider::NonDeletable, - point_access, - make_vertex_normal_read_attribute, - nullptr, - update_vertex_normals_when_dirty, - nullptr); - static NamedLegacyCustomDataProvider uvs(ATTR_DOMAIN_CORNER, CD_PROP_FLOAT2, CD_MLOOPUV, @@ -916,7 +923,7 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() static CustomDataAttributeProvider edge_custom_data(ATTR_DOMAIN_EDGE, edge_access); static CustomDataAttributeProvider polygon_custom_data(ATTR_DOMAIN_POLYGON, polygon_access); - return ComponentAttributeProviders({&position, &material_index, &vertex_normal, &shade_smooth}, + return ComponentAttributeProviders({&position, &material_index, &shade_smooth, &normal}, {&uvs, &vertex_colors, &corner_custom_data, diff --git a/source/blender/blenkernel/intern/geometry_component_pointcloud.cc b/source/blender/blenkernel/intern/geometry_component_pointcloud.cc index c428e93cfa9..073f457ae54 100644 --- a/source/blender/blenkernel/intern/geometry_component_pointcloud.cc +++ b/source/blender/blenkernel/intern/geometry_component_pointcloud.cc @@ -175,7 +175,6 @@ static ComponentAttributeProviders create_attribute_providers_for_point_cloud() point_access, make_array_read_attribute<float3, ATTR_DOMAIN_POINT>, make_array_write_attribute<float3, ATTR_DOMAIN_POINT>, - nullptr, nullptr); static BuiltinCustomDataLayerProvider radius( "radius", @@ -188,7 +187,6 @@ static ComponentAttributeProviders create_attribute_providers_for_point_cloud() point_access, make_array_read_attribute<float, ATTR_DOMAIN_POINT>, make_array_write_attribute<float, ATTR_DOMAIN_POINT>, - nullptr, nullptr); static CustomDataAttributeProvider point_custom_data(ATTR_DOMAIN_POINT, point_access); return ComponentAttributeProviders({&position, &radius}, {&point_custom_data}); diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc index 70b48a253ed..fc9d793c119 100644 --- a/source/blender/blenkernel/intern/geometry_set_instances.cc +++ b/source/blender/blenkernel/intern/geometry_set_instances.cc @@ -381,7 +381,7 @@ static void join_instance_groups_mesh(Span<GeometryInstanceGroup> set_groups, gather_attribute_info(attributes, component_types, set_groups, - {"position", "material_index", "vertex_normal", "shade_smooth"}); + {"position", "material_index", "normal", "shade_smooth"}); join_attributes( set_groups, component_types, attributes, static_cast<GeometryComponent &>(dst_component)); } diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index 61c9f74531d..824f791d400 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -93,6 +93,9 @@ class MeshesToIMeshInfo { /* Transformation matrix to transform a coordinate in the corresponding * Mesh to the local space of the first Mesh. */ Array<float4x4> to_obj0; + /* For each input mesh, how to remap the material slot numbers to + * the material slots in the first mesh. */ + Array<const short *> material_remaps; /* Total number of input mesh vertices. */ int tot_meshes_verts; /* Total number of input mesh edges. */ @@ -238,6 +241,7 @@ const MEdge *MeshesToIMeshInfo::input_medge_for_orig_index(int orig_index, */ static IMesh meshes_to_imesh(Span<const Mesh *> meshes, Span<const float4x4 *> obmats, + Span<const short *> material_remaps, IMeshArena &arena, MeshesToIMeshInfo *r_info) { @@ -267,6 +271,7 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes, r_info->mesh_edge_offset = Array<int>(nmeshes); r_info->mesh_poly_offset = Array<int>(nmeshes); r_info->to_obj0 = Array<float4x4>(nmeshes); + r_info->material_remaps = Array<const short *>(nmeshes); int v = 0; int e = 0; int f = 0; @@ -305,6 +310,7 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes, r_info->mesh_edge_offset[mi] = 0; r_info->mesh_poly_offset[mi] = 0; unit_m4(r_info->to_obj0[0].values); + r_info->material_remaps[0] = nullptr; } else { r_info->mesh_vert_offset[mi] = v; @@ -321,6 +327,12 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes, } objn_to_obj0_mat = inv_obj0_mat * objn_mat; r_info->to_obj0[mi] = objn_to_obj0_mat; + if (mi < material_remaps.size()) { + r_info->material_remaps[mi] = material_remaps[mi]; + } + else { + r_info->material_remaps[mi] = nullptr; + } } for (int vi = 0; vi < me->totvert; ++vi) { float3 co = me->mvert[vi].co; @@ -390,12 +402,21 @@ static void copy_poly_attributes(Mesh *dest_mesh, const MPoly *orig_mp, const Mesh *orig_me, int mp_index, - int index_in_orig_me) + int index_in_orig_me, + const short *material_remap) { mp->mat_nr = orig_mp->mat_nr; if (mp->mat_nr >= dest_mesh->totcol) { mp->mat_nr = 0; } + else { + if (material_remap) { + short mat_nr = material_remap[orig_mp->mat_nr]; + if (mat_nr >= 0 && mat_nr < dest_mesh->totcol) { + mp->mat_nr = mat_nr; + } + } + } mp->flag = orig_mp->flag; CustomData *target_cd = &dest_mesh->pdata; const CustomData *source_cd = &orig_me->pdata; @@ -721,7 +742,9 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) ++l; ++cur_loop_index; } - copy_poly_attributes(result, mp, orig_mp, orig_me, fi, index_in_orig_me); + + copy_poly_attributes( + result, mp, orig_mp, orig_me, fi, index_in_orig_me, mim.material_remaps[orig_me_index]); copy_or_interp_loop_attributes(result, f, mp, orig_mp, orig_me, orig_me_index, mim); } @@ -761,6 +784,7 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) */ static Mesh *direct_mesh_boolean(Span<const Mesh *> meshes, Span<const float4x4 *> obmats, + Span<const short *> material_remaps, const bool use_self, const bool hole_tolerant, const BoolOpType boolean_mode) @@ -776,7 +800,7 @@ static Mesh *direct_mesh_boolean(Span<const Mesh *> meshes, } MeshesToIMeshInfo mim; IMeshArena arena; - IMesh m_in = meshes_to_imesh(meshes, obmats, arena, &mim); + IMesh m_in = meshes_to_imesh(meshes, obmats, material_remaps, arena, &mim); std::function<int(int)> shape_fn = [&mim](int f) { for (int mi = 0; mi < mim.mesh_poly_offset.size() - 1; ++mi) { if (f < mim.mesh_poly_offset[mi + 1]) { @@ -804,10 +828,14 @@ extern "C" { /* Do a mesh boolean directly on meshes (without going back and forth to BMesh). * The \a meshes argument is an array of \a meshes_len of Mesh pointers. * The \a obmats argument is an array of \a meshes_len of pointers to the obmat + * The \a material_remaps is an array of pointers to arrays of maps from material + * slot numbers in the corresponding mesh to the material slot in the first mesh. + * It is OK for material_remaps or any of its constituent arrays to be NULL. * matrices that transform local coordinates to global ones. It is allowed * for the pointers to be nullptr, meaning the transformation is the identity. */ Mesh *BKE_mesh_boolean(const Mesh **meshes, const float (*obmats[])[4][4], + const short **material_remaps, const int meshes_len, const bool use_self, const bool hole_tolerant, @@ -817,6 +845,7 @@ Mesh *BKE_mesh_boolean(const Mesh **meshes, return blender::meshintersect::direct_mesh_boolean( blender::Span(meshes, meshes_len), blender::Span(transforms, meshes_len), + blender::Span(material_remaps, material_remaps ? meshes_len : 0), use_self, hole_tolerant, static_cast<blender::meshintersect::BoolOpType>(boolean_mode)); @@ -825,6 +854,7 @@ Mesh *BKE_mesh_boolean(const Mesh **meshes, #else Mesh *BKE_mesh_boolean(const Mesh **UNUSED(meshes), const float (*obmats[])[4][4], + const short **UNUSED(material_remaps), const int UNUSED(meshes_len), const bool UNUSED(use_self), const bool UNUSED(hole_tolerant), diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 528088b2ee7..b6f02128353 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -1568,6 +1568,8 @@ const char *nodeStaticSocketType(int type, int subtype) return "NodeSocketFloatAngle"; case PROP_TIME: return "NodeSocketFloatTime"; + case PROP_DISTANCE: + return "NodeSocketFloatDistance"; case PROP_NONE: default: return "NodeSocketFloat"; @@ -1637,6 +1639,8 @@ const char *nodeStaticSocketInterfaceType(int type, int subtype) return "NodeSocketInterfaceFloatAngle"; case PROP_TIME: return "NodeSocketInterfaceFloatTime"; + case PROP_DISTANCE: + return "NodeSocketInterfaceFloatDistance"; case PROP_NONE: default: return "NodeSocketInterfaceFloat"; @@ -4788,6 +4792,7 @@ static void registerGeometryNodes() register_node_type_geo_attribute_color_ramp(); register_node_type_geo_attribute_combine_xyz(); register_node_type_geo_attribute_compare(); + register_node_type_geo_attribute_convert(); register_node_type_geo_attribute_fill(); register_node_type_geo_attribute_math(); register_node_type_geo_attribute_mix(); diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 61603dc754b..18584e05dd5 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -137,8 +137,7 @@ static void update_node_vb(PBVH *pbvh, PBVHNode *node) if (node->flag & PBVH_Leaf) { PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(pbvh, node, vd, PBVH_ITER_ALL) - { + BKE_pbvh_vertex_iter_begin (pbvh, node, vd, PBVH_ITER_ALL) { BB_expand(&vb, vd.co); } BKE_pbvh_vertex_iter_end; @@ -1143,8 +1142,7 @@ static void pbvh_update_mask_redraw_task_cb(void *__restrict userdata, if (node->flag & PBVH_Leaf) { PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(pbvh, node, vd, PBVH_ITER_ALL) - { + BKE_pbvh_vertex_iter_begin (pbvh, node, vd, PBVH_ITER_ALL) { if (vd.mask && *vd.mask < 1.0f) { has_unmasked = true; } @@ -1191,8 +1189,7 @@ static void pbvh_update_visibility_redraw_task_cb(void *__restrict userdata, BKE_pbvh_node_fully_hidden_set(node, true); if (node->flag & PBVH_Leaf) { PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(pbvh, node, vd, PBVH_ITER_ALL) - { + BKE_pbvh_vertex_iter_begin (pbvh, node, vd, PBVH_ITER_ALL) { if (vd.visible) { BKE_pbvh_node_fully_hidden_set(node, false); return; diff --git a/source/blender/blenlib/intern/mesh_boolean.cc b/source/blender/blenlib/intern/mesh_boolean.cc index cd7d0a812e4..bc12ff1a652 100644 --- a/source/blender/blenlib/intern/mesh_boolean.cc +++ b/source/blender/blenlib/intern/mesh_boolean.cc @@ -408,6 +408,7 @@ class Cell { void add_patch(int p) { patches_.add(p); + zero_volume_ = false; /* If it was true before, it no longer is. */ } const Set<int> &patches() const diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index dff9e302fdf..196b46953c4 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -234,6 +234,9 @@ data_to_c_simple(engines/eevee/shaders/effect_dof_resolve_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_dof_scatter_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_dof_scatter_vert.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_dof_setup_frag.glsl SRC) +data_to_c_simple(engines/eevee/shaders/effect_reflection_lib.glsl SRC) +data_to_c_simple(engines/eevee/shaders/effect_reflection_resolve_frag.glsl SRC) +data_to_c_simple(engines/eevee/shaders/effect_reflection_trace_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_downsample_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_downsample_cube_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_gtao_frag.glsl SRC) @@ -242,7 +245,6 @@ data_to_c_simple(engines/eevee/shaders/effect_velocity_tile_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_minmaxz_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_mist_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_motion_blur_frag.glsl SRC) -data_to_c_simple(engines/eevee/shaders/effect_ssr_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_subsurface_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_translucency_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_temporal_aa.glsl SRC) @@ -263,6 +265,7 @@ data_to_c_simple(engines/eevee/shaders/irradiance_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/octahedron_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/cubemap_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/bsdf_sampling_lib.glsl SRC) +data_to_c_simple(engines/eevee/shaders/random_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/raytrace_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/renderpass_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/renderpass_postprocess_frag.glsl SRC) diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index 582bfad323b..ae726d7af9a 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -69,7 +69,7 @@ static void eevee_engine_init(void *ved) stl->g_data->render_timesteps = 1; /* Main Buffer */ - DRW_texture_ensure_fullscreen_2d(&txl->color, GPU_RGBA16F, DRW_TEX_FILTER | DRW_TEX_MIPMAP); + DRW_texture_ensure_fullscreen_2d(&txl->color, GPU_RGBA16F, DRW_TEX_FILTER); GPU_framebuffer_ensure_config(&fbl->main_fb, {GPU_ATTACHMENT_TEXTURE(dtxl->depth), @@ -286,7 +286,7 @@ static void eevee_draw_scene(void *vedata) EEVEE_create_minmax_buffer(vedata, dtxl->depth, -1); DRW_stats_group_end(); - EEVEE_occlusion_compute(sldata, vedata, dtxl->depth, -1); + EEVEE_occlusion_compute(sldata, vedata); EEVEE_volumes_compute(sldata, vedata); /* Shading pass */ diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index 3e1d4a8aaa6..e2e865bcfad 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -50,12 +50,10 @@ #include "WM_types.h" static struct { - struct GPUTexture *hammersley; struct GPUTexture *planar_pool_placeholder; struct GPUTexture *depth_placeholder; struct GPUTexture *depth_array_placeholder; - struct GPUVertFormat *format_probe_display_cube; struct GPUVertFormat *format_probe_display_planar; } e_data = {NULL}; /* Engine data */ @@ -90,25 +88,6 @@ bool EEVEE_lightprobes_obj_visibility_cb(bool vis_in, void *user_data) return vis_in && oed->ob_vis; } -static struct GPUTexture *create_hammersley_sample_texture(int samples) -{ - struct GPUTexture *tex; - float(*texels)[2] = MEM_mallocN(sizeof(float[2]) * samples, "hammersley_tex"); - int i; - - for (i = 0; i < samples; i++) { - double dphi; - BLI_hammersley_1d(i, &dphi); - float phi = (float)dphi * 2.0f * M_PI; - texels[i][0] = cosf(phi); - texels[i][1] = sinf(phi); - } - - tex = DRW_texture_create_1d(samples, GPU_RG16F, DRW_TEX_WRAP, (float *)texels); - MEM_freeN(texels); - return tex; -} - static void planar_pool_ensure_alloc(EEVEE_Data *vedata, int num_planar_ref) { EEVEE_TextureList *txl = vedata->txl; @@ -166,10 +145,7 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); vedata->info[0] = '\0'; - if (!e_data.hammersley) { - EEVEE_shaders_lightprobe_shaders_init(); - e_data.hammersley = create_hammersley_sample_texture(HAMMERSLEY_SIZE); - } + EEVEE_shaders_material_shaders_init(); memset(stl->g_data->bake_views, 0, sizeof(stl->g_data->bake_views)); memset(stl->g_data->cube_views, 0, sizeof(stl->g_data->cube_views)); @@ -244,7 +220,6 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1); DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_len, 1); - DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->samples_len_inv, 1); DRW_shgroup_uniform_float(grp, "roughness", &pinfo->roughness, 1); DRW_shgroup_uniform_float(grp, "lodFactor", &pinfo->lodfactor, 1); DRW_shgroup_uniform_float(grp, "lodMax", &pinfo->lod_rt_max, 1); @@ -252,7 +227,6 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, DRW_shgroup_uniform_float(grp, "paddingSize", &pinfo->padding_size, 1); DRW_shgroup_uniform_float(grp, "fireflyFactor", &pinfo->firefly_fac, 1); DRW_shgroup_uniform_int(grp, "Layer", &pinfo->layer, 1); - DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley); // DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter); DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); @@ -270,10 +244,8 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, DRW_shgroup_uniform_int(grp, "probeSize", &pinfo->shres, 1); #else DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_len, 1); - DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->samples_len_inv, 1); DRW_shgroup_uniform_float(grp, "lodFactor", &pinfo->lodfactor, 1); DRW_shgroup_uniform_float(grp, "lodMax", &pinfo->lod_rt_max, 1); - DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley); #endif DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1); DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color); @@ -292,11 +264,9 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, DRW_shgroup_uniform_float(grp, "visibilityRange", &pinfo->visibility_range, 1); DRW_shgroup_uniform_float(grp, "visibilityBlur", &pinfo->visibility_blur, 1); DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_len, 1); - DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->samples_len_inv, 1); DRW_shgroup_uniform_float(grp, "storedTexelSize", &pinfo->texel_size, 1); DRW_shgroup_uniform_float(grp, "nearClip", &pinfo->near_clip, 1); DRW_shgroup_uniform_float(grp, "farClip", &pinfo->far_clip, 1); - DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley); DRW_shgroup_uniform_texture(grp, "probeDepth", rt_depth); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); @@ -961,7 +931,7 @@ static void lightbake_render_scene_reflected(int layer, EEVEE_BakeRenderData *us DRW_draw_pass(psl->probe_background); EEVEE_create_minmax_buffer(vedata, tmp_planar_depth, layer); - EEVEE_occlusion_compute(sldata, vedata, tmp_planar_depth, layer); + EEVEE_occlusion_compute(sldata, vedata); GPU_framebuffer_bind(fbl->planarref_fb); @@ -1078,10 +1048,7 @@ void EEVEE_lightbake_filter_glossy(EEVEE_ViewLayerData *sldata, CLAMP(filter_quality, 1.0f, 8.0f); pinfo->samples_len *= filter_quality; - pinfo->samples_len_inv = 1.0f / pinfo->samples_len; - pinfo->lodfactor = bias + - 0.5f * log((float)(target_size * target_size) * pinfo->samples_len_inv) / - log(2); + pinfo->lodfactor = bias + 0.5f * log(square_f(target_size) / pinfo->samples_len) / log(2); pinfo->firefly_fac = (firefly_fac > 0.0) ? firefly_fac : 1e16; GPU_framebuffer_ensure_config(&fb, @@ -1129,10 +1096,7 @@ void EEVEE_lightbake_filter_diffuse(EEVEE_ViewLayerData *sldata, #ifndef IRRADIANCE_SH_L2 /* Tweaking parameters to balance perf. vs precision */ const float bias = 0.0f; - pinfo->samples_len_inv = 1.0f / pinfo->samples_len; - pinfo->lodfactor = bias + 0.5f * - log((float)(target_size * target_size) * pinfo->samples_len_inv) / - log(2); + pinfo->lodfactor = bias + 0.5f * log(square_f(target_size) / pinfo->samples_len) / log(2); pinfo->lod_rt_max = log2_floor_u(target_size) - 2.0f; #else pinfo->shres = 32; /* Less texture fetches & reduce branches */ @@ -1170,7 +1134,6 @@ void EEVEE_lightbake_filter_visibility(EEVEE_ViewLayerData *sldata, LightCache *light_cache = vedata->stl->g_data->light_cache; pinfo->samples_len = 512.0f; /* TODO refine */ - pinfo->samples_len_inv = 1.0f / pinfo->samples_len; pinfo->shres = vis_size; pinfo->visibility_range = vis_range; pinfo->visibility_blur = vis_blur; @@ -1293,9 +1256,7 @@ void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) void EEVEE_lightprobes_free(void) { - MEM_SAFE_FREE(e_data.format_probe_display_cube); MEM_SAFE_FREE(e_data.format_probe_display_planar); - DRW_TEXTURE_FREE_SAFE(e_data.hammersley); DRW_TEXTURE_FREE_SAFE(e_data.planar_pool_placeholder); DRW_TEXTURE_FREE_SAFE(e_data.depth_placeholder); DRW_TEXTURE_FREE_SAFE(e_data.depth_array_placeholder); diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c index a7874440895..8f8317498ec 100644 --- a/source/blender/draw/engines/eevee/eevee_occlusion.c +++ b/source/blender/draw/engines/eevee/eevee_occlusion.c @@ -157,8 +157,6 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) EEVEE_EffectsInfo *effects = stl->effects; DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); - if ((effects->enabled_effects & EFFECT_GTAO) != 0) { /** Occlusion algorithm overview * @@ -176,21 +174,9 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) psl->ao_horizon_search); DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer); - DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &effects->ao_src_depth); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); - DRW_shgroup_call(grp, quad, NULL); - - DRW_PASS_CREATE(psl->ao_horizon_search_layer, DRW_STATE_WRITE_COLOR); - grp = DRW_shgroup_create(EEVEE_shaders_effect_ambient_occlusion_layer_sh_get(), - psl->ao_horizon_search_layer); - DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); - DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer); - DRW_shgroup_uniform_texture_ref(grp, "depthBufferLayered", &effects->ao_src_depth); - DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); - DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); - DRW_shgroup_uniform_int(grp, "layer", &stl->effects->ao_depth_layer, 1); - DRW_shgroup_call(grp, quad, NULL); + DRW_shgroup_call_procedural_triangles(grp, NULL, 1); if (G.debug_value == 6) { DRW_PASS_CREATE(psl->ao_horizon_debug, DRW_STATE_WRITE_COLOR); @@ -203,15 +189,12 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons_renderpass); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); - DRW_shgroup_call(grp, quad, NULL); + DRW_shgroup_call_procedural_triangles(grp, NULL, 1); } } } -void EEVEE_occlusion_compute(EEVEE_ViewLayerData *UNUSED(sldata), - EEVEE_Data *vedata, - struct GPUTexture *depth_src, - int layer) +void EEVEE_occlusion_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) { EEVEE_PassList *psl = vedata->psl; EEVEE_FramebufferList *fbl = vedata->fbl; @@ -220,17 +203,10 @@ void EEVEE_occlusion_compute(EEVEE_ViewLayerData *UNUSED(sldata), if ((effects->enabled_effects & EFFECT_GTAO) != 0) { DRW_stats_group_start("GTAO Horizon Scan"); - effects->ao_src_depth = depth_src; - effects->ao_depth_layer = layer; GPU_framebuffer_bind(fbl->gtao_fb); - if (layer >= 0) { - DRW_draw_pass(psl->ao_horizon_search_layer); - } - else { - DRW_draw_pass(psl->ao_horizon_search); - } + DRW_draw_pass(psl->ao_horizon_search); if (GPU_mip_render_workaround() || GPU_type_matches(GPU_DEVICE_INTEL_UHD, GPU_OS_WIN, GPU_DRIVER_ANY)) { @@ -275,7 +251,7 @@ void EEVEE_occlusion_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data * /* Update the min_max/horizon buffers so the refraction materials appear in it. */ EEVEE_create_minmax_buffer(vedata, dtxl->depth, -1); - EEVEE_occlusion_compute(sldata, vedata, dtxl->depth, -1); + EEVEE_occlusion_compute(sldata, vedata); GPU_framebuffer_bind(fbl->ao_accum_fb); DRW_draw_pass(psl->ao_accum_ps); diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 1ffd4a071f1..e98ba4136ed 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -63,7 +63,6 @@ extern struct DrawEngineType draw_engine_eevee_type; /* Only define one of these. */ // #define IRRADIANCE_SH_L2 #define IRRADIANCE_HL2 -#define HAMMERSLEY_SIZE 1024 #if defined(IRRADIANCE_SH_L2) # define SHADER_IRRADIANCE "#define IRRADIANCE_SH_L2\n" @@ -201,13 +200,6 @@ enum { KEY_SHADOW = (1 << 3), }; -/* SSR shader variations */ -typedef enum EEVEE_SSRShaderOptions { - SSR_RESOLVE = (1 << 0), - SSR_FULL_TRACE = (1 << 1), - SSR_MAX_SHADER = (1 << 2), -} EEVEE_SSRShaderOptions; - /* DOF Gather pass shader variations */ typedef enum EEVEE_DofGatherPass { DOF_GATHER_FOREGROUND = 0, @@ -271,7 +263,6 @@ typedef struct EEVEE_PassList { /* Effects */ struct DRWPass *ao_horizon_search; - struct DRWPass *ao_horizon_search_layer; struct DRWPass *ao_horizon_debug; struct DRWPass *ao_accum_ps; struct DRWPass *mist_accum_ps; @@ -608,7 +599,6 @@ typedef struct EEVEE_LightProbesInfo { float texel_size; float padding_size; float samples_len; - float samples_len_inv; float near_clip; float far_clip; float roughness; @@ -732,8 +722,6 @@ typedef struct EEVEE_EffectsInfo { bool reflection_trace_full; bool ssr_was_persp; bool ssr_was_valid_double_buffer; - int ssr_neighbor_ofs; - int ssr_halfres_ofs[2]; struct GPUTexture *ssr_normal_input; /* Textures from pool */ struct GPUTexture *ssr_specrough_input; struct GPUTexture *ssr_hit_output; @@ -750,8 +738,6 @@ typedef struct EEVEE_EffectsInfo { float prev_drw_persmat[4][4]; /* Used for checking view validity and reprojection. */ struct DRWView *taa_view; /* Ambient Occlusion */ - int ao_depth_layer; - struct GPUTexture *ao_src_depth; /* pointer copy */ struct GPUTexture *gtao_horizons; /* Textures from pool */ struct GPUTexture *gtao_horizons_renderpass; /* Texture when rendering render pass */ struct GPUTexture *gtao_horizons_debug; @@ -1180,7 +1166,6 @@ void EEVEE_sample_ellipse(int sample_ofs, void EEVEE_random_rotation_m4(int sample_ofs, float scale, float r_mat[4][4]); /* eevee_shaders.c */ -void EEVEE_shaders_lightprobe_shaders_init(void); void EEVEE_shaders_material_shaders_init(void); struct DRWShaderLibrary *EEVEE_shader_lib_get(void); struct GPUShader *EEVEE_shaders_bloom_blit_get(bool high_quality); @@ -1216,9 +1201,9 @@ struct GPUShader *EEVEE_shaders_effect_motion_blur_hair_sh_get(void); struct GPUShader *EEVEE_shaders_effect_motion_blur_velocity_tiles_sh_get(void); struct GPUShader *EEVEE_shaders_effect_motion_blur_velocity_tiles_expand_sh_get(void); struct GPUShader *EEVEE_shaders_effect_ambient_occlusion_sh_get(void); -struct GPUShader *EEVEE_shaders_effect_ambient_occlusion_layer_sh_get(void); struct GPUShader *EEVEE_shaders_effect_ambient_occlusion_debug_sh_get(void); -struct GPUShader *EEVEE_shaders_effect_screen_raytrace_sh_get(EEVEE_SSRShaderOptions options); +struct GPUShader *EEVEE_shaders_effect_reflection_trace_sh_get(void); +struct GPUShader *EEVEE_shaders_effect_reflection_resolve_sh_get(void); struct GPUShader *EEVEE_shaders_renderpasses_post_process_sh_get(void); struct GPUShader *EEVEE_shaders_cryptomatte_sh_get(bool is_hair); struct GPUShader *EEVEE_shaders_shadow_sh_get(void); @@ -1363,10 +1348,7 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, uint tot_samples); void EEVEE_occlusion_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); -void EEVEE_occlusion_compute(EEVEE_ViewLayerData *sldata, - EEVEE_Data *vedata, - struct GPUTexture *depth_src, - int layer); +void EEVEE_occlusion_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_occlusion_draw_debug(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_occlusion_free(void); diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c index bc05b7915c3..aaa087f9eb4 100644 --- a/source/blender/draw/engines/eevee/eevee_render.c +++ b/source/blender/draw/engines/eevee/eevee_render.c @@ -116,7 +116,7 @@ bool EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph * /* TODO 32 bit depth */ DRW_texture_ensure_fullscreen_2d(&dtxl->depth, GPU_DEPTH24_STENCIL8, 0); - DRW_texture_ensure_fullscreen_2d(&txl->color, GPU_RGBA32F, DRW_TEX_FILTER | DRW_TEX_MIPMAP); + DRW_texture_ensure_fullscreen_2d(&txl->color, GPU_RGBA32F, DRW_TEX_FILTER); GPU_framebuffer_ensure_config( &dfbl->default_fb, @@ -630,7 +630,7 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl DRW_draw_pass(psl->depth_ps); /* Create minmax texture */ EEVEE_create_minmax_buffer(vedata, dtxl->depth, -1); - EEVEE_occlusion_compute(sldata, vedata, dtxl->depth, -1); + EEVEE_occlusion_compute(sldata, vedata); EEVEE_volumes_compute(sldata, vedata); /* Shading pass */ eevee_render_draw_background(vedata); diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c index f5b4e4d43a5..54f23073bd0 100644 --- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c +++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c @@ -32,11 +32,6 @@ #include "GPU_texture.h" #include "eevee_private.h" -static struct { - /* These are just references, not actually allocated */ - struct GPUTexture *depth_src; -} e_data = {NULL}; /* Engine data */ - int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) { EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; @@ -126,14 +121,12 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v EEVEE_EffectsInfo *effects = stl->effects; LightCache *lcache = stl->g_data->light_cache; - struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); - if ((effects->enabled_effects & EFFECT_SSR) != 0) { - EEVEE_SSRShaderOptions options = (effects->reflection_trace_full) ? SSR_FULL_TRACE : 0; + struct GPUShader *trace_shader = EEVEE_shaders_effect_reflection_trace_sh_get(); + struct GPUShader *resolve_shader = EEVEE_shaders_effect_reflection_resolve_sh_get(); - struct GPUShader *trace_shader = EEVEE_shaders_effect_screen_raytrace_sh_get(options); - struct GPUShader *resolve_shader = EEVEE_shaders_effect_screen_raytrace_sh_get(SSR_RESOLVE | - options); + int hitbuf_size[3]; + GPU_texture_get_mipmap_size(effects->ssr_hit_output, 0, hitbuf_size); /** Screen space raytracing overview * @@ -160,10 +153,10 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); - if (!effects->reflection_trace_full) { - DRW_shgroup_uniform_ivec2(grp, "halfresOffset", effects->ssr_halfres_ofs, 1); - } - DRW_shgroup_call(grp, quad, NULL); + DRW_shgroup_uniform_vec2_copy(grp, "targetSize", (float[2]){hitbuf_size[0], hitbuf_size[1]}); + DRW_shgroup_uniform_float_copy( + grp, "randomScale", effects->reflection_trace_full ? 0.0f : 0.5f); + DRW_shgroup_call_procedural_triangles(grp, NULL, 1); eGPUSamplerState no_filter = GPU_SAMPLER_DEFAULT; @@ -188,10 +181,9 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); - DRW_shgroup_uniform_int(grp, "neighborOffset", &effects->ssr_neighbor_ofs, 1); + DRW_shgroup_uniform_int(grp, "samplePoolOffset", &effects->taa_current_sample, 1); DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons); - - DRW_shgroup_call(grp, quad, NULL); + DRW_shgroup_call_procedural_triangles(grp, NULL, 1); } } @@ -219,9 +211,6 @@ void EEVEE_reflection_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v EEVEE_EffectsInfo *effects = stl->effects; if (((effects->enabled_effects & EFFECT_SSR) != 0) && stl->g_data->valid_double_buffer) { - DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - e_data.depth_src = dtxl->depth; - DRW_stats_group_start("SSR"); /* Raytrace. */ @@ -230,31 +219,6 @@ void EEVEE_reflection_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v EEVEE_effects_downsample_radiance_buffer(vedata, txl->color_double_buffer); - /* Resolve at fullres */ - int samp = (DRW_state_is_image_render()) ? effects->taa_render_sample : - effects->taa_current_sample; - /* Doing a neighbor shift only after a few iteration. - * We wait for a prime number of cycles to avoid noise correlation. - * This reduces variance faster. */ - effects->ssr_neighbor_ofs = ((samp / 5) % 8) * 4; - switch ((samp / 11) % 4) { - case 0: - effects->ssr_halfres_ofs[0] = 0; - effects->ssr_halfres_ofs[1] = 0; - break; - case 1: - effects->ssr_halfres_ofs[0] = 0; - effects->ssr_halfres_ofs[1] = 1; - break; - case 2: - effects->ssr_halfres_ofs[0] = 1; - effects->ssr_halfres_ofs[1] = 0; - break; - case 4: - effects->ssr_halfres_ofs[0] = 1; - effects->ssr_halfres_ofs[1] = 1; - break; - } GPU_framebuffer_bind(fbl->main_color_fb); DRW_draw_pass(psl->ssr_resolve); diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c index 74c4803928a..90b7eeb9293 100644 --- a/source/blender/draw/engines/eevee/eevee_shaders.c +++ b/source/blender/draw/engines/eevee/eevee_shaders.c @@ -41,11 +41,11 @@ #include "eevee_engine.h" #include "eevee_private.h" -static const char *filter_defines = "#define HAMMERSLEY_SIZE " STRINGIFY(HAMMERSLEY_SIZE) "\n" +static const char *filter_defines = #if defined(IRRADIANCE_SH_L2) - "#define IRRADIANCE_SH_L2\n"; + "#define IRRADIANCE_SH_L2\n"; #elif defined(IRRADIANCE_HL2) - "#define IRRADIANCE_HL2\n"; + "#define IRRADIANCE_HL2\n"; #endif static struct { @@ -132,7 +132,8 @@ static struct { struct GPUShader *cryptomatte_sh[2]; /* Screen Space Reflection */ - struct GPUShader *ssr_sh[SSR_MAX_SHADER]; + struct GPUShader *reflection_trace; + struct GPUShader *reflection_resolve; /* Shadows */ struct GPUShader *shadow_sh; @@ -217,7 +218,9 @@ extern char datatoc_effect_gtao_frag_glsl[]; extern char datatoc_effect_minmaxz_frag_glsl[]; extern char datatoc_effect_mist_frag_glsl[]; extern char datatoc_effect_motion_blur_frag_glsl[]; -extern char datatoc_effect_ssr_frag_glsl[]; +extern char datatoc_effect_reflection_lib_glsl[]; +extern char datatoc_effect_reflection_resolve_frag_glsl[]; +extern char datatoc_effect_reflection_trace_frag_glsl[]; extern char datatoc_effect_subsurface_frag_glsl[]; extern char datatoc_effect_temporal_aa_glsl[]; extern char datatoc_effect_translucency_frag_glsl[]; @@ -252,6 +255,7 @@ extern char datatoc_object_motion_vert_glsl[]; extern char datatoc_octahedron_lib_glsl[]; extern char datatoc_prepass_frag_glsl[]; extern char datatoc_prepass_vert_glsl[]; +extern char datatoc_random_lib_glsl[]; extern char datatoc_raytrace_lib_glsl[]; extern char datatoc_renderpass_lib_glsl[]; extern char datatoc_renderpass_postprocess_frag_glsl[]; @@ -286,6 +290,7 @@ static void eevee_shader_library_ensure(void) DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib); DRW_SHADER_LIB_ADD(e_data.lib, common_uniforms_lib); DRW_SHADER_LIB_ADD(e_data.lib, gpu_shader_common_obinfos_lib); + DRW_SHADER_LIB_ADD(e_data.lib, random_lib); DRW_SHADER_LIB_ADD(e_data.lib, renderpass_lib); DRW_SHADER_LIB_ADD(e_data.lib, bsdf_common_lib); DRW_SHADER_LIB_ADD(e_data.lib, common_utiltex_lib); @@ -302,6 +307,7 @@ static void eevee_shader_library_ensure(void) DRW_SHADER_LIB_ADD(e_data.lib, volumetric_lib); DRW_SHADER_LIB_ADD(e_data.lib, ssr_lib); DRW_SHADER_LIB_ADD(e_data.lib, effect_dof_lib); + DRW_SHADER_LIB_ADD(e_data.lib, effect_reflection_lib); DRW_SHADER_LIB_ADD(e_data.lib, closure_type_lib); DRW_SHADER_LIB_ADD(e_data.lib, closure_eval_lib); DRW_SHADER_LIB_ADD(e_data.lib, closure_eval_diffuse_lib); @@ -320,35 +326,6 @@ static void eevee_shader_library_ensure(void) } } -void EEVEE_shaders_lightprobe_shaders_init(void) -{ - BLI_assert(e_data.probe_filter_glossy_sh == NULL); - - eevee_shader_library_ensure(); - - e_data.probe_filter_glossy_sh = DRW_shader_create_with_shaderlib( - datatoc_lightprobe_vert_glsl, - datatoc_lightprobe_geom_glsl, - datatoc_lightprobe_filter_glossy_frag_glsl, - e_data.lib, - filter_defines); - - e_data.probe_filter_diffuse_sh = DRW_shader_create_fullscreen_with_shaderlib( - datatoc_lightprobe_filter_diffuse_frag_glsl, e_data.lib, filter_defines); - - e_data.probe_filter_visibility_sh = DRW_shader_create_fullscreen_with_shaderlib( - datatoc_lightprobe_filter_visibility_frag_glsl, e_data.lib, filter_defines); - - e_data.probe_grid_fill_sh = DRW_shader_create_fullscreen_with_shaderlib( - datatoc_lightprobe_grid_fill_frag_glsl, e_data.lib, filter_defines); - - e_data.probe_planar_downsample_sh = DRW_shader_create( - datatoc_lightprobe_planar_downsample_vert_glsl, - datatoc_lightprobe_planar_downsample_geom_glsl, - datatoc_lightprobe_planar_downsample_frag_glsl, - NULL); -} - void EEVEE_shaders_material_shaders_init(void) { eevee_shader_library_ensure(); @@ -362,26 +339,54 @@ DRWShaderLibrary *EEVEE_shader_lib_get(void) GPUShader *EEVEE_shaders_probe_filter_glossy_sh_get(void) { + if (e_data.probe_filter_glossy_sh == NULL) { + e_data.probe_filter_glossy_sh = DRW_shader_create_with_shaderlib( + datatoc_lightprobe_vert_glsl, + datatoc_lightprobe_geom_glsl, + datatoc_lightprobe_filter_glossy_frag_glsl, + e_data.lib, + filter_defines); + } return e_data.probe_filter_glossy_sh; } GPUShader *EEVEE_shaders_probe_filter_diffuse_sh_get(void) { + if (e_data.probe_filter_diffuse_sh == NULL) { + e_data.probe_filter_diffuse_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_lightprobe_filter_diffuse_frag_glsl, e_data.lib, filter_defines); + } return e_data.probe_filter_diffuse_sh; } GPUShader *EEVEE_shaders_probe_filter_visibility_sh_get(void) { + if (e_data.probe_filter_visibility_sh == NULL) { + e_data.probe_filter_visibility_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_lightprobe_filter_visibility_frag_glsl, e_data.lib, filter_defines); + } return e_data.probe_filter_visibility_sh; } GPUShader *EEVEE_shaders_probe_grid_fill_sh_get(void) { + if (e_data.probe_grid_fill_sh == NULL) { + e_data.probe_grid_fill_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_lightprobe_grid_fill_frag_glsl, e_data.lib, filter_defines); + } return e_data.probe_grid_fill_sh; } GPUShader *EEVEE_shaders_probe_planar_downsample_sh_get(void) { + if (e_data.probe_planar_downsample_sh == NULL) { + e_data.probe_planar_downsample_sh = DRW_shader_create_with_shaderlib( + datatoc_lightprobe_planar_downsample_vert_glsl, + datatoc_lightprobe_planar_downsample_geom_glsl, + datatoc_lightprobe_planar_downsample_frag_glsl, + e_data.lib, + NULL); + } return e_data.probe_planar_downsample_sh; } @@ -474,10 +479,12 @@ GPUShader *EEVEE_shaders_effect_downsample_sh_get(void) GPUShader *EEVEE_shaders_effect_downsample_cube_sh_get(void) { if (e_data.downsample_cube_sh == NULL) { - e_data.downsample_cube_sh = DRW_shader_create(datatoc_lightprobe_vert_glsl, - datatoc_lightprobe_geom_glsl, - datatoc_effect_downsample_cube_frag_glsl, - NULL); + e_data.downsample_cube_sh = DRW_shader_create_with_shaderlib( + datatoc_lightprobe_vert_glsl, + datatoc_lightprobe_geom_glsl, + datatoc_effect_downsample_cube_frag_glsl, + e_data.lib, + NULL); } return e_data.downsample_cube_sh; } @@ -588,7 +595,7 @@ GPUShader *EEVEE_shaders_ggx_refraction_lut_sh_get(void) { if (e_data.ggx_refraction_lut_sh == NULL) { e_data.ggx_refraction_lut_sh = DRW_shader_create_fullscreen_with_shaderlib( - datatoc_btdf_lut_frag_glsl, e_data.lib, "#define HAMMERSLEY_SIZE 8192\n"); + datatoc_btdf_lut_frag_glsl, e_data.lib, NULL); } return e_data.ggx_refraction_lut_sh; } @@ -680,20 +687,14 @@ GPUShader *EEVEE_shaders_effect_ambient_occlusion_sh_get(void) return e_data.gtao_sh; } -GPUShader *EEVEE_shaders_effect_ambient_occlusion_layer_sh_get(void) -{ - if (e_data.gtao_layer_sh == NULL) { - e_data.gtao_layer_sh = DRW_shader_create_fullscreen_with_shaderlib( - datatoc_effect_gtao_frag_glsl, e_data.lib, "#define LAYERED_DEPTH\n"); - } - return e_data.gtao_layer_sh; -} - GPUShader *EEVEE_shaders_effect_ambient_occlusion_debug_sh_get(void) { if (e_data.gtao_debug_sh == NULL) { e_data.gtao_debug_sh = DRW_shader_create_fullscreen_with_shaderlib( - datatoc_effect_gtao_frag_glsl, e_data.lib, "#define DEBUG_AO\n"); + datatoc_effect_gtao_frag_glsl, + e_data.lib, + "#define DEBUG_AO\n" + "#define ENABLE_DEFERED_AO"); } return e_data.gtao_debug_sh; } @@ -744,36 +745,29 @@ GPUShader *EEVEE_shaders_cryptomatte_sh_get(bool is_hair) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Screen Raytrace +/** \name Raytraced Reflections * \{ */ -struct GPUShader *EEVEE_shaders_effect_screen_raytrace_sh_get(EEVEE_SSRShaderOptions options) +struct GPUShader *EEVEE_shaders_effect_reflection_trace_sh_get(void) { - if (e_data.ssr_sh[options] == NULL) { - DRWShaderLibrary *lib = EEVEE_shader_lib_get(); - - DynStr *ds_defines = BLI_dynstr_new(); - BLI_dynstr_append(ds_defines, SHADER_DEFINES); - if (options & SSR_RESOLVE) { - BLI_dynstr_append(ds_defines, "#define STEP_RESOLVE\n"); - } - else { - BLI_dynstr_append(ds_defines, "#define STEP_RAYTRACE\n"); - BLI_dynstr_append(ds_defines, "#define PLANAR_PROBE_RAYTRACE\n"); - } - if (options & SSR_FULL_TRACE) { - BLI_dynstr_append(ds_defines, "#define FULLRES\n"); - } - char *ssr_define_str = BLI_dynstr_get_cstring(ds_defines); - BLI_dynstr_free(ds_defines); - - e_data.ssr_sh[options] = DRW_shader_create_fullscreen_with_shaderlib( - datatoc_effect_ssr_frag_glsl, lib, ssr_define_str); - - MEM_freeN(ssr_define_str); + if (e_data.reflection_trace == NULL) { + e_data.reflection_trace = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_reflection_trace_frag_glsl, + e_data.lib, + SHADER_DEFINES "#define STEP_RAYTRACE\n"); } + return e_data.reflection_trace; +} - return e_data.ssr_sh[options]; +struct GPUShader *EEVEE_shaders_effect_reflection_resolve_sh_get(void) +{ + if (e_data.reflection_resolve == NULL) { + e_data.reflection_resolve = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_reflection_resolve_frag_glsl, + e_data.lib, + SHADER_DEFINES "#define STEP_RESOLVE\n"); + } + return e_data.reflection_resolve; } /** \} */ @@ -972,8 +966,8 @@ GPUShader *EEVEE_shaders_bloom_blit_get(bool high_quality) const char *define = high_quality ? "#define STEP_BLIT\n" "#define HIGH_QUALITY\n" : "#define STEP_BLIT\n"; - e_data.bloom_blit_sh[index] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, - define); + e_data.bloom_blit_sh[index] = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_bloom_frag_glsl, e_data.lib, define); } return e_data.bloom_blit_sh[index]; } @@ -986,8 +980,8 @@ GPUShader *EEVEE_shaders_bloom_downsample_get(bool high_quality) const char *define = high_quality ? "#define STEP_DOWNSAMPLE\n" "#define HIGH_QUALITY\n" : "#define STEP_DOWNSAMPLE\n"; - e_data.bloom_downsample_sh[index] = DRW_shader_create_fullscreen( - datatoc_effect_bloom_frag_glsl, define); + e_data.bloom_downsample_sh[index] = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_bloom_frag_glsl, e_data.lib, define); } return e_data.bloom_downsample_sh[index]; } @@ -1000,8 +994,8 @@ GPUShader *EEVEE_shaders_bloom_upsample_get(bool high_quality) const char *define = high_quality ? "#define STEP_UPSAMPLE\n" "#define HIGH_QUALITY\n" : "#define STEP_UPSAMPLE\n"; - e_data.bloom_upsample_sh[index] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, - define); + e_data.bloom_upsample_sh[index] = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_bloom_frag_glsl, e_data.lib, define); } return e_data.bloom_upsample_sh[index]; } @@ -1014,8 +1008,8 @@ GPUShader *EEVEE_shaders_bloom_resolve_get(bool high_quality) const char *define = high_quality ? "#define STEP_RESOLVE\n" "#define HIGH_QUALITY\n" : "#define STEP_RESOLVE\n"; - e_data.bloom_resolve_sh[index] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, - define); + e_data.bloom_resolve_sh[index] = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_bloom_frag_glsl, e_data.lib, define); } return e_data.bloom_resolve_sh[index]; } @@ -1627,9 +1621,8 @@ void EEVEE_shaders_free(void) DRW_SHADER_FREE_SAFE(e_data.bloom_upsample_sh[i]); DRW_SHADER_FREE_SAFE(e_data.bloom_resolve_sh[i]); } - for (int i = 0; i < SSR_MAX_SHADER; i++) { - DRW_SHADER_FREE_SAFE(e_data.ssr_sh[i]); - } + DRW_SHADER_FREE_SAFE(e_data.reflection_trace); + DRW_SHADER_FREE_SAFE(e_data.reflection_resolve); DRW_SHADER_LIB_FREE_SAFE(e_data.lib); if (e_data.default_world) { diff --git a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl index 4398247472d..e65993175ab 100644 --- a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl @@ -193,6 +193,7 @@ void occlusion_eval(OcclusionData data, vec3 Ng, const float inverted, out float visibility, + out float visibility_error, out vec3 bent_normal) { if ((int(aoSettings) & USE_AO) == 0) { @@ -219,6 +220,7 @@ void occlusion_eval(OcclusionData data, vec2 noise = get_ao_noise(); vec2 dir = get_ao_dir(noise.x); + visibility_error = 0.0; visibility = 0.0; bent_normal = N * 0.001; @@ -258,12 +260,17 @@ void occlusion_eval(OcclusionData data, float a = dot(-cos(2.0 * h - angle_N) + N_cos + 2.0 * h * N_sin, vec2(0.25)); /* Correct normal not on plane (Eq. 8). */ visibility += proj_N_len * a; + /* Using a very low number of slices (2) leads to over-darkening of surfaces orthogonal to + * the view. This is particularly annoying for sharp reflections occlusion. So we compute how + * much the error is and correct the visibility later. */ + visibility_error += proj_N_len; /* Rotate 90 degrees. */ dir = vec2(-dir.y, dir.x); } /* We integrated 2 directions. */ visibility *= 0.5; + visibility_error *= 0.5; visibility = min(visibility, data.custom_occlusion); @@ -297,8 +304,9 @@ float gtao_multibounce(float visibility, vec3 albedo) float diffuse_occlusion(OcclusionData data, vec3 V, vec3 N, vec3 Ng) { vec3 unused; + float unused_error; float visibility; - occlusion_eval(data, V, N, Ng, 0.0, visibility, unused); + occlusion_eval(data, V, N, Ng, 0.0, visibility, unused_error, unused); /* Scale by user factor */ visibility = pow(saturate(visibility), aoFactor); return visibility; @@ -308,7 +316,8 @@ float diffuse_occlusion( OcclusionData data, vec3 V, vec3 N, vec3 Ng, vec3 albedo, out vec3 bent_normal) { float visibility; - occlusion_eval(data, V, N, Ng, 0.0, visibility, bent_normal); + float unused_error; + occlusion_eval(data, V, N, Ng, 0.0, visibility, unused_error, bent_normal); visibility = gtao_multibounce(visibility, albedo); /* Scale by user factor */ @@ -351,8 +360,12 @@ float specular_occlusion( OcclusionData data, vec3 V, vec3 N, float roughness, inout vec3 specular_dir) { vec3 visibility_dir; + float visibility_error; float visibility; - occlusion_eval(data, V, N, N, 0.0, visibility, visibility_dir); + occlusion_eval(data, V, N, N, 0.0, visibility, visibility_error, visibility_dir); + + /* Correct visibility error for very sharp surfaces. */ + visibility *= mix(safe_rcp(visibility_error), 1.0, roughness); specular_dir = normalize(mix(specular_dir, visibility_dir, roughness * (1.0 - visibility))); @@ -368,7 +381,7 @@ float specular_occlusion( float specular_solid_angle = spherical_cap_intersection(M_PI_2, spec_angle, cone_nor_dist); float specular_occlusion = isect_solid_angle / specular_solid_angle; /* Mix because it is unstable in unoccluded areas. */ - visibility = mix(isect_solid_angle / specular_solid_angle, 1.0, pow(visibility, 8.0)); + visibility = mix(specular_occlusion, 1.0, pow(visibility, 8.0)); /* Scale by user factor */ visibility = pow(saturate(visibility), aoFactor); diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl index 004d884dc75..7ce95a4aff2 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl @@ -1,32 +1,14 @@ +/** + * Sampling distribution routines for Monte-carlo integration. + **/ + #pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) #pragma BLENDER_REQUIRE(bsdf_common_lib.glsl) -uniform sampler1D texHammersley; - -vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B) -{ - return T * vector.x + B * vector.y + N * vector.z; -} - -vec3 world_to_tangent(vec3 vector, vec3 N, vec3 T, vec3 B) -{ - return vec3(dot(T, vector), dot(B, vector), dot(N, vector)); -} - -#ifdef HAMMERSLEY_SIZE -vec3 hammersley_3d(float i, float invsamplenbr) -{ - vec3 Xi; /* Theta, cos(Phi), sin(Phi) */ - - Xi.x = i * invsamplenbr; - Xi.yz = texelFetch(texHammersley, int(i), 0).rg; - - return Xi; -} -#endif - -/* -------------- BSDFS -------------- */ +/* -------------------------------------------------------------------- */ +/** \name Microfacet GGX distribution + * \{ */ #define USE_VISIBLE_NORMAL 1 @@ -42,11 +24,6 @@ float pdf_ggx_reflect(float NH, float NV, float VH, float alpha) #endif } -float pdf_hemisphere() -{ - return 0.5 * M_1_PI; -} - vec3 sample_ggx(vec3 rand, float alpha, vec3 Vt) { #if USE_VISIBLE_NORMAL @@ -94,54 +71,53 @@ vec3 sample_ggx(vec3 rand, float alpha, vec3 V, vec3 N, vec3 T, vec3 B, out floa return tangent_to_world(Ht, N, T, B); } -vec3 sample_hemisphere(vec3 rand) +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Uniform Hemisphere + * \{ */ + +float pdf_uniform_hemisphere() +{ + return 0.5 * M_1_PI; +} + +vec3 sample_uniform_hemisphere(vec3 rand) { - /* Theta is the cone angle. */ float z = rand.x; /* cos theta */ float r = sqrt(max(0.0, 1.0 - z * z)); /* sin theta */ float x = r * rand.y; float y = r * rand.z; - return vec3(x, y, z); } -vec3 sample_hemisphere(vec3 rand, vec3 N, vec3 T, vec3 B) +vec3 sample_uniform_hemisphere(vec3 rand, vec3 N, vec3 T, vec3 B, out float pdf) { - vec3 Ht = sample_hemisphere(rand); + vec3 Ht = sample_uniform_hemisphere(rand); + pdf = pdf_uniform_hemisphere(); return tangent_to_world(Ht, N, T, B); } -#ifdef HAMMERSLEY_SIZE -vec3 sample_ggx(float nsample, - float inv_sample_count, - float alpha, - vec3 V, - vec3 N, - vec3 T, - vec3 B, - out float pdf) -{ - vec3 Xi = hammersley_3d(nsample, inv_sample_count); - return sample_ggx(Xi, alpha, V, N, T, B, pdf); -} +/** \} */ -vec3 sample_hemisphere(float nsample, float inv_sample_count, vec3 N, vec3 T, vec3 B) -{ - vec3 Xi = hammersley_3d(nsample, inv_sample_count); - return sample_hemisphere(Xi, N, T, B); -} +/* -------------------------------------------------------------------- */ +/** \name Uniform Cone sampling + * \{ */ -vec3 sample_cone(float nsample, float inv_sample_count, float angle, vec3 N, vec3 T, vec3 B) +vec3 sample_uniform_cone(vec3 rand, float angle) { - vec3 Xi = hammersley_3d(nsample, inv_sample_count); - - float z = cos(angle * Xi.x); /* cos theta */ + float z = cos(angle * rand.x); /* cos theta */ float r = sqrt(max(0.0, 1.0 - z * z)); /* sin theta */ - float x = r * Xi.y; - float y = r * Xi.z; - - vec3 Ht = vec3(x, y, z); + float x = r * rand.y; + float y = r * rand.z; + return vec3(x, y, z); +} +vec3 sample_uniform_cone(vec3 rand, float angle, vec3 N, vec3 T, vec3 B) +{ + vec3 Ht = sample_uniform_cone(rand, angle); + /* TODO pdf? */ return tangent_to_world(Ht, N, T, B); } -#endif + +/** \} */ diff --git a/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl index 33d7347a377..c6f61d1d443 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl @@ -26,6 +26,8 @@ * THE SOFTWARE. */ +#pragma BLENDER_REQUIRE(common_math_lib.glsl) + uniform sampler2D sourceBuffer; /* Buffer to filter */ uniform vec2 sourceBufferTexelSize; @@ -54,11 +56,6 @@ vec3 safe_color(vec3 c) return clamp(c, vec3(0.0), vec3(1e20)); /* 1e20 arbitrary. */ } -float brightness(vec3 c) -{ - return max(max(c.r, c.g), c.b); -} - /* 3-tap median filter */ vec3 median(vec3 a, vec3 b, vec3 c) { @@ -78,10 +75,10 @@ vec3 downsample_filter_high(sampler2D tex, vec2 uv, vec2 texelSize) vec3 s4 = textureLod(tex, uv + d.zw, 0.0).rgb; /* Karis's luma weighted average (using brightness instead of luma) */ - float s1w = 1.0 / (brightness(s1) + 1.0); - float s2w = 1.0 / (brightness(s2) + 1.0); - float s3w = 1.0 / (brightness(s3) + 1.0); - float s4w = 1.0 / (brightness(s4) + 1.0); + float s1w = 1.0 / (max_v3(s1) + 1.0); + float s2w = 1.0 / (max_v3(s2) + 1.0); + float s3w = 1.0 / (max_v3(s3) + 1.0); + float s4w = 1.0 / (max_v3(s4) + 1.0); float one_div_wsum = 1.0 / (s1w + s2w + s3w + s4w); return (s1 * s1w + s2 * s2w + s3 * s3w + s4 * s4w) * one_div_wsum; @@ -156,7 +153,7 @@ vec4 step_blit(void) #endif /* Pixel brightness */ - float br = brightness(m); + float br = max_v3(m); /* Under-threshold part: quadratic curve */ float rq = clamp(br - curveThreshold.x, 0, curveThreshold.y); @@ -167,7 +164,7 @@ vec4 step_blit(void) /* Clamp pixel intensity if clamping enabled */ if (clampIntensity > 0.0) { - br = max(1e-5, brightness(m)); + br = max(1e-5, max_v3(m)); m *= 1.0 - max(0.0, br - clampIntensity) / br; } diff --git a/source/blender/draw/engines/eevee/shaders/effect_downsample_cube_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_downsample_cube_frag.glsl index 0ac1cda9e3d..05f16b866e0 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_downsample_cube_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_downsample_cube_frag.glsl @@ -2,6 +2,8 @@ * Simple down-sample shader. Takes the average of the 4 texels of lower mip. */ +#pragma BLENDER_REQUIRE(common_math_lib.glsl) + uniform samplerCube source; uniform float texelSize; @@ -28,11 +30,6 @@ const vec3 y_axis[6] = vec3[6](vec3(0.0, -1.0, 0.0), vec3(0.0, -1.0, 0.0), vec3(0.0, -1.0, 0.0)); -float brightness(vec3 c) -{ - return max(max(c.r, c.g), c.b); -} - void main() { vec2 uvs = gl_FragCoord.xy * texelSize; diff --git a/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl index 5bf850fe229..d1cb25af82f 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl @@ -11,11 +11,6 @@ uniform float fireflyFactor; out vec4 FragColor; -float brightness(vec3 c) -{ - return max(max(c.r, c.g), c.b); -} - void main() { vec2 texel_size = 1.0 / vec2(textureSize(source, 0)); @@ -26,7 +21,7 @@ void main() FragColor = safe_color(FragColor); /* Clamped brightness. */ - float luma = max(1e-8, brightness(FragColor.rgb)); + float luma = max(1e-8, max_v3(FragColor.rgb)); FragColor *= 1.0 - max(0.0, luma - fireflyFactor) / luma; #else diff --git a/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl index 16b1a7ffeaa..70f1e9f1e66 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl @@ -10,21 +10,11 @@ * The final integration is done at the resolve stage with the shading normal. */ +in vec4 uvcoordsvar; + out vec4 FragColor; uniform sampler2D normalBuffer; -#ifdef LAYERED_DEPTH -uniform sampler2DArray depthBufferLayered; -uniform int layer; -# define gtao_depthBuffer depthBufferLayered -# define gtao_textureLod(a, b, c) textureLod(a, vec3(b, layer), c) - -#else -uniform sampler2D depthBuffer; -# define gtao_depthBuffer depthBuffer -# define gtao_textureLod(a, b, c) textureLod(a, b, c) - -#endif /* Similar to https://atyuwen.github.io/posts/normal-reconstruction/. * This samples the depth buffer 4 time for each direction to get the most correct @@ -36,10 +26,10 @@ vec3 view_position_derivative_from_depth(vec2 uvs, vec2 ofs, vec3 vP, float dept vec2 uv3 = uvs + ofs; vec2 uv4 = uvs + ofs * 2.0; vec4 H; - H.x = gtao_textureLod(gtao_depthBuffer, uv1, 0.0).r; - H.y = gtao_textureLod(gtao_depthBuffer, uv2, 0.0).r; - H.z = gtao_textureLod(gtao_depthBuffer, uv3, 0.0).r; - H.w = gtao_textureLod(gtao_depthBuffer, uv4, 0.0).r; + H.x = textureLod(maxzBuffer, uv1, 0.0).r; + H.y = textureLod(maxzBuffer, uv2, 0.0).r; + H.z = textureLod(maxzBuffer, uv3, 0.0).r; + H.w = textureLod(maxzBuffer, uv4, 0.0).r; /* Fix issue with depth precision. Take even larger diff. */ vec4 diff = abs(vec4(depth_center, H.yzw) - H.x); if (max_v4(diff) < 2.4e-7 && all(lessThan(diff.xyz, diff.www))) { @@ -56,16 +46,10 @@ vec3 view_position_derivative_from_depth(vec2 uvs, vec2 ofs, vec3 vP, float dept } /* TODO(fclem) port to a common place for other effects to use. */ -bool reconstruct_view_position_and_normal_from_depth(vec2 texel, out vec3 vP, out vec3 vNg) +bool reconstruct_view_position_and_normal_from_depth(vec2 uvs, out vec3 vP, out vec3 vNg) { - vec2 texel_size = 1.0 / vec2(textureSize(gtao_depthBuffer, 0).xy); - vec2 uvs = gl_FragCoord.xy * texel_size; - float depth_center = gtao_textureLod(gtao_depthBuffer, uvs, 0.0).r; - - /* Background case. */ - if (depth_center == 1.0) { - return false; - } + vec2 texel_size = vec2(abs(dFdx(uvs.x)), abs(dFdy(uvs.y))); + float depth_center = textureLod(maxzBuffer, uvs, 0.0).r; vP = get_view_space_from_depth(uvs, depth_center); @@ -74,18 +58,22 @@ bool reconstruct_view_position_and_normal_from_depth(vec2 texel, out vec3 vP, ou vNg = safe_normalize(cross(dPdx, dPdy)); + /* Background case. */ + if (depth_center == 1.0) { + return false; + } + return true; } #ifdef DEBUG_AO -in vec4 uvcoordsvar; - void main() { vec3 vP, vNg; + vec2 uvs = uvcoordsvar.xy; - if (!reconstruct_view_position_and_normal_from_depth(gl_FragCoord.xy, vP, vNg)) { + if (!reconstruct_view_position_and_normal_from_depth(uvs * hizUvScale.xy, vP, vNg)) { /* Handle Background case. Prevent artifact due to uncleared Horizon Render Target. */ FragColor = vec4(0.0); } @@ -93,7 +81,7 @@ void main() vec3 P = transform_point(ViewMatrixInverse, vP); vec3 V = cameraVec(P); vec3 vV = viewCameraVec(vP); - vec3 vN = normal_decode(texture(normalBuffer, uvcoordsvar.xy).rg, vV); + vec3 vN = normal_decode(texture(normalBuffer, uvs).rg, vV); vec3 N = transform_direction(ViewMatrixInverse, vN); vec3 Ng = transform_direction(ViewMatrixInverse, vNg); @@ -112,8 +100,8 @@ void main() void main() { - vec2 uvs = gl_FragCoord.xy / vec2(textureSize(gtao_depthBuffer, 0).xy); - float depth = gtao_textureLod(gtao_depthBuffer, uvs, 0.0).r; + vec2 uvs = uvcoordsvar.xy; + float depth = textureLod(maxzBuffer, uvs * hizUvScale.xy, 0.0).r; vec3 vP = get_view_space_from_depth(uvs, depth); OcclusionData data = NO_OCCLUSION_DATA; diff --git a/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl b/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl new file mode 100644 index 00000000000..cc73bbbfe29 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl @@ -0,0 +1,101 @@ + +#pragma BLENDER_REQUIRE(common_view_lib.glsl) + +/* Based on: + * "Stochastic Screen Space Reflections" + * by Tomasz Stachowiak. + * https://www.ea.com/frostbite/news/stochastic-screen-space-reflections + * and + * "Stochastic all the things: raytracing in hybrid real-time rendering" + * by Tomasz Stachowiak. + * https://media.contentapi.ea.com/content/dam/ea/seed/presentations/dd18-seed-raytracing-in-hybrid-real-time-rendering.pdf + */ + +uniform ivec2 halfresOffset; + +struct HitData { + /** Hit direction scaled by intersection time. */ + vec3 hit_dir; + /** Screen space [0..1] depth of the reflection hit position, or -1.0 for planar reflections. */ + float hit_depth; + /** Inverse probability of ray spawning in this direction. */ + float ray_pdf_inv; + /** True if ray has hit valid geometry. */ + bool is_hit; + /** True if ray was generated from a planar reflection probe. */ + bool is_planar; +}; + +void encode_hit_data(HitData data, vec3 hit_sP, vec3 vP, out vec4 hit_data, out float hit_depth) +{ + vec3 hit_vP = get_view_space_from_depth(hit_sP.xy, hit_sP.z); + hit_data.xyz = hit_vP - vP; + hit_depth = data.is_planar ? -1.0 : hit_sP.z; + /* Record 1.0 / pdf to reduce the computation in the resolve phase. */ + /* Encode hit validity in sign. */ + hit_data.w = data.ray_pdf_inv * ((data.is_hit) ? 1.0 : -1.0); +} + +HitData decode_hit_data(vec4 hit_data, float hit_depth) +{ + HitData data; + data.hit_dir.xyz = hit_data.xyz; + data.hit_depth = hit_depth; + data.is_planar = (hit_depth == -1.0); + data.ray_pdf_inv = abs(hit_data.w); + data.is_hit = (hit_data.w > 0.0); + return data; +} + +/* Blue noise categorised into 4 sets of samples. + * See "Stochastic all the things" presentation slide 32-37. */ +const int resolve_samples_count = 9; +const vec2 resolve_sample_offsets[36] = vec2[36]( + /* Set 1. */ + /* First Ring (2x2). */ + vec2(0, 0), + /* Second Ring (6x6). */ + vec2(-1, 3), + vec2(1, 3), + vec2(-1, 1), + vec2(3, 1), + vec2(-2, 0), + vec2(3, 0), + vec2(2, -1), + vec2(1, -2), + /* Set 2. */ + /* First Ring (2x2). */ + vec2(1, 1), + /* Second Ring (6x6). */ + vec2(-2, 3), + vec2(3, 3), + vec2(0, 2), + vec2(2, 2), + vec2(-2, -1), + vec2(1, -1), + vec2(0, -2), + vec2(3, -2), + /* Set 3. */ + /* First Ring (2x2). */ + vec2(0, 1), + /* Second Ring (6x6). */ + vec2(0, 3), + vec2(3, 2), + vec2(-2, 1), + vec2(2, 1), + vec2(-1, 0), + vec2(-2, -2), + vec2(0, -1), + vec2(2, -2), + /* Set 4. */ + /* First Ring (2x2). */ + vec2(1, 0), + /* Second Ring (6x6). */ + vec2(2, 3), + vec2(-2, 2), + vec2(-1, 2), + vec2(1, 2), + vec2(2, 0), + vec2(-1, -1), + vec2(3, -1), + vec2(-1, -2));
\ No newline at end of file diff --git a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl index 11048a46f8e..6f2619127e3 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl @@ -1,14 +1,12 @@ #pragma BLENDER_REQUIRE(common_math_lib.glsl) #pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) -#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl) #pragma BLENDER_REQUIRE(closure_eval_glossy_lib.glsl) #pragma BLENDER_REQUIRE(closure_eval_lib.glsl) -#pragma BLENDER_REQUIRE(raytrace_lib.glsl) #pragma BLENDER_REQUIRE(lightprobe_lib.glsl) #pragma BLENDER_REQUIRE(bsdf_common_lib.glsl) -#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl) #pragma BLENDER_REQUIRE(surface_lib.glsl) +#pragma BLENDER_REQUIRE(effect_reflection_lib.glsl) /* Based on: * "Stochastic Screen Space Reflections" @@ -20,207 +18,18 @@ * https://media.contentapi.ea.com/content/dam/ea/seed/presentations/dd18-seed-raytracing-in-hybrid-real-time-rendering.pdf */ -uniform ivec2 halfresOffset; - -struct HitData { - /** Hit direction scaled by intersection time. */ - vec3 hit_dir; - /** Screen space [0..1] depth of the reflection hit position, or -1.0 for planar reflections. */ - float hit_depth; - /** Inverse probability of ray spawning in this direction. */ - float ray_pdf_inv; - /** True if ray has hit valid geometry. */ - bool is_hit; - /** True if ray was generated from a planar reflection probe. */ - bool is_planar; -}; - -void encode_hit_data(HitData data, vec3 hit_sP, vec3 vP, out vec4 hit_data, out float hit_depth) -{ - vec3 hit_vP = get_view_space_from_depth(hit_sP.xy, hit_sP.z); - hit_data.xyz = hit_vP - vP; - hit_depth = data.is_planar ? -1.0 : hit_sP.z; - /* Record 1.0 / pdf to reduce the computation in the resolve phase. */ - /* Encode hit validity in sign. */ - hit_data.w = data.ray_pdf_inv * ((data.is_hit) ? 1.0 : -1.0); -} - -HitData decode_hit_data(vec4 hit_data, float hit_depth) -{ - HitData data; - data.hit_dir.xyz = hit_data.xyz; - data.hit_depth = hit_depth; - data.is_planar = (hit_depth == -1.0); - data.ray_pdf_inv = abs(hit_data.w); - data.is_hit = (hit_data.w > 0.0); - return data; -} - -#ifdef STEP_RAYTRACE - -uniform sampler2D normalBuffer; -uniform sampler2D specroughBuffer; - -layout(location = 0) out vec4 hitData; -layout(location = 1) out float hitDepth; - -void do_planar_ssr(int index, - vec3 vV, - vec3 vN, - vec3 vT, - vec3 vB, - vec3 viewPlaneNormal, - vec3 vP, - float alpha, - vec4 rand) -{ - float pdf; - /* Microfacet normal */ - vec3 vH = sample_ggx(rand.xzw, alpha, vV, vN, vT, vB, pdf); - vec3 vR = reflect(-vV, vH); - vR = reflect(vR, viewPlaneNormal); - - Ray ray; - ray.origin = vP; - ray.direction = vR * 1e16; - - RayTraceParameters params; - params.jitter = rand.y; - params.trace_quality = ssrQuality; - params.roughness = alpha * alpha; - - vec3 hit_sP; - HitData data; - data.is_planar = true; - data.ray_pdf_inv = safe_rcp(pdf); - data.is_hit = raytrace_planar(ray, params, index, hit_sP); - - encode_hit_data(data, hit_sP, ray.origin, hitData, hitDepth); -} - -void do_ssr(vec3 vV, vec3 vN, vec3 vT, vec3 vB, vec3 vP, float alpha, vec4 rand) -{ - float pdf; - /* Microfacet normal */ - vec3 vH = sample_ggx(rand.xzw, alpha, vV, vN, vT, vB, pdf); - vec3 vR = reflect(-vV, vH); - - Ray ray; - ray.origin = vP + vN * 1e-4; - ray.direction = vR * 1e16; - - RayTraceParameters params; - params.thickness = ssrThickness; - params.jitter = rand.y; - params.trace_quality = ssrQuality; - params.roughness = alpha * alpha; - - vec3 hit_sP; - HitData data; - data.is_planar = false; - data.ray_pdf_inv = safe_rcp(pdf); - data.is_hit = raytrace(ray, params, true, hit_sP); - - encode_hit_data(data, hit_sP, ray.origin, hitData, hitDepth); -} - -in vec4 uvcoordsvar; - -void main() -{ - vec2 uvs = uvcoordsvar.xy; - float depth = textureLod(maxzBuffer, uvs * hizUvScale.xy, 0.0).r; - - HitData data; - data.is_planar = false; - data.ray_pdf_inv = 0.0; - data.is_hit = false; - data.hit_dir = vec3(0.0, 0.0, 0.0); - - /* Default: not hits. */ - encode_hit_data(data, data.hit_dir, data.hit_dir, hitData, hitDepth); - - /* Early out */ - /* We can't do discard because we don't clear the render target. */ - if (depth == 1.0) { - return; - } - - /* Using view space */ - vec3 vP = get_view_space_from_depth(uvs, depth); - vec3 P = transform_point(ViewMatrixInverse, vP); - vec3 vV = viewCameraVec(vP); - vec3 V = cameraVec(P); - vec3 vN = normal_decode(texture(normalBuffer, uvs, 0).rg, vV); - vec3 N = transform_direction(ViewMatrixInverse, vN); - - /* Retrieve pixel data */ - vec4 speccol_roughness = texture(specroughBuffer, uvs, 0).rgba; - - /* Early out */ - if (dot(speccol_roughness.rgb, vec3(1.0)) == 0.0) { - return; - } - - float roughness = speccol_roughness.a; - float alpha = max(1e-3, roughness * roughness); - - /* Early out */ - if (roughness > ssrMaxRoughness + 0.2) { - return; - } - - vec4 rand = texelfetch_noise_tex(vec2(gl_FragCoord.xy)); - - /* Gives *perfect* reflection for very small roughness */ - if (roughness < 0.04) { - rand.xzw *= 0.0; - } - /* Importance sampling bias */ - rand.x = mix(rand.x, 0.0, ssrBrdfBias); - - vec3 vT, vB; - make_orthonormal_basis(vN, vT, vB); /* Generate tangent space */ - - /* Planar Reflections */ - for (int i = 0; i < MAX_PLANAR && i < prbNumPlanar; i++) { - PlanarData pd = planars_data[i]; - - float fade = probe_attenuation_planar(pd, P); - fade *= probe_attenuation_planar_normal_roughness(pd, N, 0.0); - - if (fade > 0.5) { - /* Find view vector / reflection plane intersection. */ - /* TODO optimize, use view space for all. */ - vec3 tracePosition = line_plane_intersect(P, V, pd.pl_plane_eq); - tracePosition = transform_point(ViewMatrix, tracePosition); - vec3 viewPlaneNormal = transform_direction(ViewMatrix, pd.pl_normal); - - do_planar_ssr(i, vV, vN, vT, vB, viewPlaneNormal, tracePosition, alpha, rand); - return; - } - } - - do_ssr(vV, vN, vT, vB, vP, alpha, rand); -} - -#else /* STEP_RESOLVE */ - -uniform sampler2D colorBuffer; /* previous frame */ +uniform sampler2D colorBuffer; uniform sampler2D normalBuffer; uniform sampler2D specroughBuffer; uniform sampler2D hitBuffer; uniform sampler2D hitDepth; +uniform int samplePoolOffset; + in vec4 uvcoordsvar; out vec4 fragColor; -float brightness(vec3 c) -{ - return max(max(c.r, c.g), c.b); -} - vec4 ssr_get_scene_color_and_mask(vec3 hit_vP, int planar_index, float mip) { vec2 uv; @@ -246,7 +55,7 @@ vec4 ssr_get_scene_color_and_mask(vec3 hit_vP, int planar_index, float mip) } /* Clamped brightness. */ - float luma = brightness(color); + float luma = max_v3(color); color *= 1.0 - max(0.0, luma - ssrFireflyFac) * safe_rcp(luma); float mask = screen_border_mask(uv); @@ -263,8 +72,8 @@ void resolve_reflection_sample(int planar_index, inout float weight_accum, inout vec4 ssr_accum) { - vec4 hit_data = texture(hitBuffer, sample_uv * ssrUvScale); - float hit_depth = texture(hitDepth, sample_uv * ssrUvScale).r; + vec4 hit_data = texture(hitBuffer, sample_uv); + float hit_depth = texture(hitDepth, sample_uv).r; HitData data = decode_hit_data(hit_data, hit_depth); float hit_dist = length(data.hit_dir); @@ -274,9 +83,12 @@ void resolve_reflection_sample(int planar_index, float weight = bsdf * data.ray_pdf_inv; + /* Do not reuse hitpoint from planar reflections for normal reflections and vice versa. */ + if ((planar_index == -1 && data.is_planar) || (planar_index != -1 && !data.is_planar)) { + return; + } /* Do not add light if ray has failed but still weight it. */ - if (!data.is_hit || (planar_index == -1 && data.is_planar) || - (planar_index != -1 && !data.is_planar)) { + if (!data.is_hit) { weight_accum += weight; return; } @@ -343,10 +155,18 @@ void raytrace_resolve(ClosureInputGlossy cl_in, float cone_tan = sqrt(1.0 - cone_cos * cone_cos) / cone_cos; cone_tan *= mix(saturate(dot(vN, -vV) * 2.0), 1.0, roughness); /* Elongation fit */ - vec2 sample_uv = uvcoordsvar.xy; + int sample_pool = int((uint(gl_FragCoord.x) & 1u) + (uint(gl_FragCoord.y) & 1u) * 2u); + sample_pool = (sample_pool + (samplePoolOffset / 5)) % 4; - resolve_reflection_sample( - planar_index, sample_uv, vP, vN, vV, roughness_squared, cone_tan, weight_acc, ssr_accum); + for (int i = 0; i < resolve_samples_count; i++) { + int sample_id = sample_pool * resolve_samples_count + i; + vec2 texture_size = vec2(textureSize(hitBuffer, 0)); + vec2 sample_texel = texture_size * uvcoordsvar.xy * ssrUvScale; + vec2 sample_uv = (sample_texel + resolve_sample_offsets[sample_id]) / texture_size; + + resolve_reflection_sample( + planar_index, sample_uv, vP, vN, vV, roughness_squared, cone_tan, weight_acc, ssr_accum); + } } /* Compute SSR contribution */ @@ -398,5 +218,3 @@ void main() fragColor = vec4(out_Glossy_0.radiance * brdf, 1.0); } - -#endif diff --git a/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl new file mode 100644 index 00000000000..b1f17cb7b07 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl @@ -0,0 +1,149 @@ + +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) +#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl) +#pragma BLENDER_REQUIRE(raytrace_lib.glsl) +#pragma BLENDER_REQUIRE(lightprobe_lib.glsl) +#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl) +#pragma BLENDER_REQUIRE(effect_reflection_lib.glsl) + +/* Based on: + * "Stochastic Screen Space Reflections" + * by Tomasz Stachowiak. + * https://www.ea.com/frostbite/news/stochastic-screen-space-reflections + * and + * "Stochastic all the things: raytracing in hybrid real-time rendering" + * by Tomasz Stachowiak. + * https://media.contentapi.ea.com/content/dam/ea/seed/presentations/dd18-seed-raytracing-in-hybrid-real-time-rendering.pdf + */ + +uniform sampler2D normalBuffer; +uniform sampler2D specroughBuffer; +uniform vec2 targetSize; +uniform float randomScale; + +in vec4 uvcoordsvar; + +layout(location = 0) out vec4 hitData; +layout(location = 1) out float hitDepth; + +void main() +{ + vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); + /* Decorrelate from AA. */ + /* TODO(fclem) we should use a more general approach for more random number dimensions. */ + vec2 random_px = floor(fract(rand.xy * 2.2074408460575947536) * 1.99999) - 0.5; + rand.xy = fract(rand.xy * 3.2471795724474602596); + + /* Randomly choose the pixel to start the ray from when tracing at lower resolution. + * This method also make sure we always start from the center of a fullres texel. */ + vec2 uvs = (gl_FragCoord.xy + random_px * randomScale) / (targetSize * ssrUvScale); + + float depth = textureLod(maxzBuffer, uvs * hizUvScale.xy, 0.0).r; + + HitData data; + data.is_planar = false; + data.ray_pdf_inv = 0.0; + data.is_hit = false; + data.hit_dir = vec3(0.0, 0.0, 0.0); + /* Default: not hits. */ + encode_hit_data(data, data.hit_dir, data.hit_dir, hitData, hitDepth); + + /* Early out */ + /* We can't do discard because we don't clear the render target. */ + if (depth == 1.0) { + return; + } + + /* Using view space */ + vec3 vP = get_view_space_from_depth(uvs, depth); + vec3 P = transform_point(ViewMatrixInverse, vP); + vec3 vV = viewCameraVec(vP); + vec3 V = cameraVec(P); + vec3 vN = normal_decode(texture(normalBuffer, uvs, 0).rg, vV); + vec3 N = transform_direction(ViewMatrixInverse, vN); + + /* Retrieve pixel data */ + vec4 speccol_roughness = texture(specroughBuffer, uvs, 0).rgba; + + /* Early out */ + if (dot(speccol_roughness.rgb, vec3(1.0)) == 0.0) { + return; + } + + float roughness = speccol_roughness.a; + float alpha = max(1e-3, roughness * roughness); + + /* Early out */ + if (roughness > ssrMaxRoughness + 0.2) { + return; + } + + /* Planar Reflections */ + int planar_id = -1; + for (int i = 0; i < MAX_PLANAR && i < prbNumPlanar; i++) { + PlanarData pd = planars_data[i]; + + float fade = probe_attenuation_planar(pd, P); + fade *= probe_attenuation_planar_normal_roughness(pd, N, 0.0); + + if (fade > 0.5) { + /* Find view vector / reflection plane intersection. */ + /* TODO optimize, use view space for all. */ + vec3 P_plane = line_plane_intersect(P, V, pd.pl_plane_eq); + vP = transform_point(ViewMatrix, P_plane); + + planar_id = i; + data.is_planar = true; + break; + } + } + + /* Gives *perfect* reflection for very small roughness */ + if (roughness < 0.04) { + rand.xzw *= 0.0; + } + /* Importance sampling bias */ + rand.x = mix(rand.x, 0.0, ssrBrdfBias); + + vec3 vT, vB; + make_orthonormal_basis(vN, vT, vB); /* Generate tangent space */ + + float pdf; + vec3 vH = sample_ggx(rand.xzw, alpha, vV, vN, vT, vB, pdf); + vec3 vR = reflect(-vV, vH); + + if (isnan(pdf)) { + /* Seems that somethings went wrong. + * This only happens on extreme cases where the normal deformed too much to have any valid + * reflections. */ + return; + } + + if (data.is_planar) { + vec3 view_plane_normal = transform_direction(ViewMatrix, planars_data[planar_id].pl_normal); + /* For planar reflections, we trace inside the reflected view. */ + vR = reflect(vR, view_plane_normal); + } + + Ray ray; + ray.origin = vP; + ray.direction = vR * 1e16; + + RayTraceParameters params; + params.thickness = ssrThickness; + params.jitter = rand.y; + params.trace_quality = ssrQuality; + params.roughness = alpha * alpha; + + vec3 hit_sP; + if (data.is_planar) { + data.is_hit = raytrace_planar(ray, params, planar_id, hit_sP); + } + else { + data.is_hit = raytrace(ray, params, true, hit_sP); + } + data.ray_pdf_inv = safe_rcp(pdf); + + encode_hit_data(data, hit_sP, ray.origin, hitData, hitDepth); +} diff --git a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl index 1964adf3059..b79cd17c567 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl @@ -45,6 +45,8 @@ void main(void) vec2 scale = vec2(ProjectionMatrix[0][0], ProjectionMatrix[1][1]) * sss_radius / homcoord; vec2 finalStep = scale * 0.5; /* samples range -1..1 */ + float sss_radius_inv = 1.0 / max(1e-8, sss_radius); + /* Center sample */ vec3 accum = sss_irradiance * kernel[0].rgb; @@ -58,7 +60,7 @@ void main(void) * by Jimenez, eqs. 2 and 9, and D9740. * Coefficient -2 follows from gaussian_profile() from gpu_material.c and * from the definition of finalStep. */ - float depth_delta = (depth_view - sample_depth) / sss_radius; + float depth_delta = (depth_view - sample_depth) * sss_radius_inv; float s = exp(-2.0 * sqr(depth_delta)); /* Out of view samples. */ if (any(lessThan(sample_uv, vec2(0.0))) || any(greaterThan(sample_uv, vec2(1.0)))) { diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl index 0d0ae6ea4a5..9ecc50d9df5 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl @@ -1,4 +1,5 @@ +#pragma BLENDER_REQUIRE(random_lib.glsl) #pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl) #pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) #pragma BLENDER_REQUIRE(irradiance_lib.glsl) @@ -10,7 +11,6 @@ uniform float lodMax; uniform float intensityFac; uniform float sampleCount; -uniform float invSampleCount; in vec3 worldPosition; @@ -147,14 +147,16 @@ void main() float weight = 0.0; vec3 out_radiance = vec3(0.0); for (float i = 0; i < sampleCount; i++) { - vec3 L = sample_hemisphere(i, invSampleCount, N, T, B); /* Microfacet normal */ + vec3 Xi = rand2d_to_cylinder(hammersley_2d(i, sampleCount)); + + float pdf; + vec3 L = sample_uniform_hemisphere(Xi, N, T, B, pdf); float NL = dot(N, L); if (NL > 0.0) { /* Coarse Approximation of the mapping distortion * Unit Sphere -> Cubemap Face */ const float dist = 4.0 * M_PI / 6.0; - float pdf = pdf_hemisphere(); /* http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html : Equation 13 */ float lod = clamp(lodFactor - 0.5 * log2(pdf * dist), 0.0, lodMax); diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl index 99cbf2839ad..a5d11f52a1d 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl @@ -1,4 +1,5 @@ +#pragma BLENDER_REQUIRE(random_lib.glsl) #pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl) #pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) @@ -12,17 +13,11 @@ uniform float intensityFac; uniform float fireflyFactor; uniform float sampleCount; -uniform float invSampleCount; in vec3 worldPosition; out vec4 FragColor; -float brightness(vec3 c) -{ - return max(max(c.r, c.g), c.b); -} - vec3 octahedral_to_cubemap_proj(vec2 co) { co = co * 2.0 - 1.0; @@ -52,9 +47,11 @@ void main() float weight = 0.0; vec3 out_radiance = vec3(0.0); for (float i = 0; i < sampleCount; i++) { + vec3 Xi = rand2d_to_cylinder(hammersley_2d(i, sampleCount)); + float pdf; /* Microfacet normal */ - vec3 H = sample_ggx(i, invSampleCount, roughness, V, N, T, B, pdf); + vec3 H = sample_ggx(Xi, roughness, V, N, T, B, pdf); vec3 L = -reflect(V, H); float NL = dot(N, L); @@ -70,7 +67,7 @@ void main() vec3 l_col = textureLod(probeHdr, L, lod).rgb; /* Clamped brightness. */ - float luma = max(1e-8, brightness(l_col)); + float luma = max(1e-8, max_v3(l_col)); l_col *= 1.0 - max(0.0, luma - fireflyFactor) / luma; out_radiance += l_col * NL; diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl index b802b39c56e..d25ef23a706 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl @@ -1,4 +1,5 @@ +#pragma BLENDER_REQUIRE(random_lib.glsl) #pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) #pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl) #pragma BLENDER_REQUIRE(irradiance_lib.glsl) @@ -14,7 +15,7 @@ uniform float visibilityRange; uniform float visibilityBlur; uniform float sampleCount; -uniform float invSampleCount; +uniform float; out vec4 FragColor; @@ -80,13 +81,15 @@ void main() vec2 accum = vec2(0.0); for (float i = 0; i < sampleCount; i++) { - vec3 samp = sample_cone(i, invSampleCount, M_PI_2 * visibilityBlur, cos, T, B); + vec3 Xi = rand2d_to_cylinder(hammersley_2d(i, sampleCount)); + + vec3 samp = sample_uniform_cone(Xi, M_PI_2 * visibilityBlur, cos, T, B); float depth = texture(probeDepth, samp).r; depth = get_world_distance(depth, samp); accum += vec2(depth, depth * depth); } - accum *= invSampleCount; + accum /= sampleCount; accum = abs(accum); /* Encode to normalized RGBA 8 */ diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl index 0f575dfc2ed..cf44a04b707 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl @@ -2,6 +2,8 @@ * Simple down-sample shader. Takes the average of the 4 texels of lower mip. */ +#pragma BLENDER_REQUIRE(common_math_lib.glsl) + uniform sampler2DArray source; uniform float fireflyFactor; @@ -10,11 +12,6 @@ flat in float layer; out vec4 FragColor; -float brightness(vec3 c) -{ - return max(max(c.r, c.g), c.b); -} - void main() { #if 0 @@ -34,7 +31,7 @@ void main() FragColor *= 0.25; /* Clamped brightness. */ - float luma = max(1e-8, brightness(FragColor.rgb)); + float luma = max(1e-8, max_v3(FragColor.rgb)); FragColor *= 1.0 - max(0.0, luma - fireflyFactor) / luma; #endif } diff --git a/source/blender/draw/engines/eevee/shaders/random_lib.glsl b/source/blender/draw/engines/eevee/shaders/random_lib.glsl new file mode 100644 index 00000000000..25a3e0f56b4 --- /dev/null +++ b/source/blender/draw/engines/eevee/shaders/random_lib.glsl @@ -0,0 +1,38 @@ + +/** + * Random numbers and low discrepency sequences utilities. + **/ + +#pragma BLENDER_REQUIRE(common_math_lib.glsl) + +/* From: http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html */ +float van_der_corput_radical_inverse(uint bits) +{ + bits = (bits << 16u) | (bits >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + /* Same as dividing by 0x100000000. */ + return float(bits) * 2.3283064365386963e-10; +} + +vec2 hammersley_2d(float i, float sample_count) +{ + vec2 rand; + rand.x = i / sample_count; + rand.y = van_der_corput_radical_inverse(uint(i)); + return rand; +} + +/* This transform a 2d random sample (in [0..1] range) to a sample located on a cylinder of the + * same range. This is because the sampling functions expect such a random sample which is + * normally precomputed. */ +vec3 rand2d_to_cylinder(vec2 rand) +{ + float theta = rand.x; + float phi = (rand.y - 0.5) * M_2PI; + float cos_phi = cos(phi); + float sin_phi = sqrt(1.0 - sqr(cos_phi)) * sign(phi); + return vec3(theta, cos_phi, sin_phi); +} diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl index 8975397b62a..5ea7e502a55 100644 --- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl @@ -148,7 +148,7 @@ bool raytrace(Ray ray, /* Check if the ray is below the surface ... */ hit = (delta < 0.0); /* ... and above it with the added thickness. */ - hit = hit && (delta > ss_p.z - ss_p.w || abs(delta) < abs(ssray.direction.z * stride)); + hit = hit && (delta > ss_p.z - ss_p.w || abs(delta) < abs(ssray.direction.z * stride * 2.0)); } /* Discard backface hits. */ hit = hit && !(discard_backface && prev_delta < 0.0); diff --git a/source/blender/draw/engines/eevee/shaders/surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl index 62930b9944a..889bf439d5f 100644 --- a/source/blender/draw/engines/eevee/shaders/surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl @@ -79,7 +79,7 @@ void main() #endif #ifndef USE_ALPHA_BLEND - float alpha_div = 1.0 / max(1e-8, alpha); + float alpha_div = safe_rcp(alpha); outRadiance.rgb *= alpha_div; ssrData.rgb *= alpha_div; # ifdef USE_SSS diff --git a/source/blender/draw/intern/shaders/common_math_geom_lib.glsl b/source/blender/draw/intern/shaders/common_math_geom_lib.glsl index 643d7e7d942..6b0a7b028ee 100644 --- a/source/blender/draw/intern/shaders/common_math_geom_lib.glsl +++ b/source/blender/draw/intern/shaders/common_math_geom_lib.glsl @@ -116,4 +116,14 @@ vec3 normal_decode(vec2 enc, vec3 view) return n; } +vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B) +{ + return T * vector.x + B * vector.y + N * vector.z; +} + +vec3 world_to_tangent(vec3 vector, vec3 N, vec3 T, vec3 B) +{ + return vec3(dot(T, vector), dot(B, vector), dot(N, vector)); +} + /** \} */ diff --git a/source/blender/draw/tests/shaders_test.cc b/source/blender/draw/tests/shaders_test.cc index 8ab626ed7ba..96d544fd855 100644 --- a/source/blender/draw/tests/shaders_test.cc +++ b/source/blender/draw/tests/shaders_test.cc @@ -288,7 +288,6 @@ TEST_F(DrawTest, overlay_glsl_shaders) TEST_F(DrawTest, eevee_glsl_shaders_static) { - EEVEE_shaders_lightprobe_shaders_init(); EEVEE_shaders_material_shaders_init(); EXPECT_NE(EEVEE_shaders_bloom_blit_get(false), nullptr); @@ -340,7 +339,6 @@ TEST_F(DrawTest, eevee_glsl_shaders_static) EXPECT_NE(EEVEE_shaders_effect_motion_blur_velocity_tiles_sh_get(), nullptr); EXPECT_NE(EEVEE_shaders_effect_motion_blur_velocity_tiles_expand_sh_get(), nullptr); EXPECT_NE(EEVEE_shaders_effect_ambient_occlusion_sh_get(), nullptr); - EXPECT_NE(EEVEE_shaders_effect_ambient_occlusion_layer_sh_get(), nullptr); EXPECT_NE(EEVEE_shaders_effect_ambient_occlusion_debug_sh_get(), nullptr); EXPECT_NE(EEVEE_shaders_ggx_lut_sh_get(), nullptr); EXPECT_NE(EEVEE_shaders_ggx_refraction_lut_sh_get(), nullptr); @@ -373,10 +371,8 @@ TEST_F(DrawTest, eevee_glsl_shaders_static) EXPECT_NE(EEVEE_shaders_velocity_resolve_sh_get(), nullptr); EXPECT_NE(EEVEE_shaders_taa_resolve_sh_get(EFFECT_TAA), nullptr); EXPECT_NE(EEVEE_shaders_taa_resolve_sh_get(EFFECT_TAA_REPROJECT), nullptr); - for (int index = 0; index < SSR_MAX_SHADER; index++) { - EEVEE_SSRShaderOptions ssr_option = (EEVEE_SSRShaderOptions)index; - EXPECT_NE(EEVEE_shaders_effect_screen_raytrace_sh_get(ssr_option), nullptr); - } + EXPECT_NE(EEVEE_shaders_effect_reflection_trace_sh_get(), nullptr); + EXPECT_NE(EEVEE_shaders_effect_reflection_resolve_sh_get(), nullptr); EEVEE_shaders_free(); } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 8a53154cc85..797c3bcf132 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -5540,10 +5540,6 @@ void ED_keymap_screen(wmKeyConfig *keyconf) /* Screen Editing ------------------------------------------------ */ WM_keymap_ensure(keyconf, "Screen Editing", 0, 0); - /* Header Editing ------------------------------------------------ */ - /* note: this is only used when the cursor is inside the header */ - WM_keymap_ensure(keyconf, "Header", 0, 0); - /* Screen General ------------------------------------------------ */ WM_keymap_ensure(keyconf, "Screen", 0, 0); diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 41d1920a2fb..be189ed88a9 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -132,8 +132,7 @@ static void mask_flood_fill_task_cb(void *__restrict userdata, SCULPT_undo_push_node(data->ob, node, SCULPT_UNDO_MASK); - BKE_pbvh_vertex_iter_begin(data->pbvh, node, vi, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (data->pbvh, node, vi, PBVH_ITER_UNIQUE) { float prevmask = *vi.mask; mask_flood_fill_set_elem(vi.mask, mode, value); if (prevmask != *vi.mask) { @@ -758,8 +757,7 @@ static void face_set_gesture_apply_task_cb(void *__restrict userdata, PBVHVertexIter vd; bool any_updated = false; - BKE_pbvh_vertex_iter_begin(sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { if (sculpt_gesture_is_vertex_effected(sgcontext, &vd)) { SCULPT_vertex_face_set_set(sgcontext->ss, vd.index, face_set_operation->new_face_set_id); any_updated = true; @@ -833,8 +831,7 @@ static void mask_gesture_apply_task_cb(void *__restrict userdata, bool any_masked = false; bool redraw = false; - BKE_pbvh_vertex_iter_begin(sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { if (sculpt_gesture_is_vertex_effected(sgcontext, &vd)) { float prevmask = *vd.mask; if (!any_masked) { @@ -1492,8 +1489,7 @@ static void project_line_gesture_apply_task_cb(void *__restrict userdata, SCULPT_undo_push_node(sgcontext->vc.obact, node, SCULPT_UNDO_COORDS); - BKE_pbvh_vertex_iter_begin(sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { if (!sculpt_gesture_is_vertex_effected(sgcontext, &vd)) { continue; } diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index f45c244f675..fc52f6fea7c 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1841,8 +1841,7 @@ static void do_wpaint_brush_blur_task_cb_ex(void *__restrict userdata, /* For each vertex */ PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { /* Test to see if the vertex coordinates are within the spherical brush region. */ if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* For grid based pbvh, take the vert whose loop corresponds to the current grid. @@ -1938,8 +1937,7 @@ static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata, /* For each vertex */ PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { /* Test to see if the vertex coordinates are within the spherical brush region. */ if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* For grid based pbvh, take the vert whose loop corresponds to the current grid. @@ -2045,8 +2043,7 @@ static void do_wpaint_brush_draw_task_cb_ex(void *__restrict userdata, /* For each vertex */ PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { /* Test to see if the vertex coordinates are within the spherical brush region. */ if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* Note: grids are 1:1 with corners (aka loops). @@ -2114,8 +2111,7 @@ static void do_wpaint_brush_calc_average_weight_cb_ex( /* For each vertex */ PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { /* Test to see if the vertex coordinates are within the spherical brush region. */ if (sculpt_brush_test_sq_fn(&test, vd.co)) { const float angle_cos = (use_normal && vd.no) ? dot_vf3vs3(sculpt_normal_frontface, vd.no) : @@ -2810,8 +2806,7 @@ static void do_vpaint_brush_calc_average_color_cb_ex(void *__restrict userdata, /* For each vertex */ PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { /* Test to see if the vertex coordinates are within the spherical brush region. */ if (sculpt_brush_test_sq_fn(&test, vd.co)) { const int v_index = has_grids ? data->me->mloop[vd.grid_indices[vd.g]].v : @@ -2880,8 +2875,7 @@ static void do_vpaint_brush_draw_task_cb_ex(void *__restrict userdata, /* For each vertex */ PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { /* Test to see if the vertex coordinates are within the spherical brush region. */ if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* Note: Grids are 1:1 with corners (aka loops). @@ -2979,8 +2973,7 @@ static void do_vpaint_brush_blur_task_cb_ex(void *__restrict userdata, /* For each vertex */ PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { /* Test to see if the vertex coordinates are within the spherical brush region. */ if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* For grid based pbvh, take the vert whose loop corresponds to the current grid. @@ -3103,8 +3096,7 @@ static void do_vpaint_brush_smear_task_cb_ex(void *__restrict userdata, /* For each vertex */ PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { /* Test to see if the vertex coordinates are within the spherical brush region. */ if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* For grid based pbvh, take the vert whose loop corresponds to the current grid. diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index fc9450a8a71..5d523852baa 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1006,8 +1006,7 @@ static void do_nearest_vertex_get_task_cb(void *__restrict userdata, NearestVertexTLSData *nvtd = tls->userdata_chunk; PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { float distance_squared = len_squared_v3v3(vd.co, data->nearest_vertex_search_co); if (distance_squared < nvtd->nearest_vertex_distance_squared && distance_squared < data->max_distance_squared) { @@ -1528,8 +1527,7 @@ static void paint_mesh_restore_co_task_cb(void *__restrict userdata, SCULPT_orig_vert_data_unode_init(&orig_data, data->ob, unode); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); if (orig_data.unode->type == SCULPT_UNDO_COORDS) { @@ -2090,8 +2088,7 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata, } } else { - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { float co[3]; /* For bm_vert only. */ @@ -2985,8 +2982,7 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata, const int thread_id = BLI_task_parallel_thread_id(tls); PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -3058,8 +3054,7 @@ static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -3135,8 +3130,7 @@ static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata, const int thread_id = BLI_task_parallel_thread_id(tls); PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -3359,8 +3353,7 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata, const int thread_id = BLI_task_parallel_thread_id(tls); PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -3440,8 +3433,7 @@ static void do_displacement_smear_store_prev_disp_task_cb_ex( SculptSession *ss = data->ob->sculpt; PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { sub_v3_v3v3(ss->cache->prev_displacement[vd.index], SCULPT_vertex_co_get(ss, vd.index), ss->cache->limit_surface_co[vd.index]); @@ -3504,8 +3496,7 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -3583,8 +3574,7 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) { continue; @@ -3900,8 +3890,7 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) { continue; @@ -4058,8 +4047,7 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) { continue; @@ -4225,8 +4213,7 @@ static void do_crease_brush_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -4343,8 +4330,7 @@ static void do_pinch_brush_task_cb_ex(void *__restrict userdata, copy_v3_v3(x_object_space, stroke_xz[0]); copy_v3_v3(z_object_space, stroke_xz[1]); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -4459,8 +4445,7 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata, const bool grab_silhouette = brush->flag2 & BRUSH_GRAB_SILHOUETTE; const bool use_geodesic_dists = brush->flag2 & BRUSH_USE_SURFACE_FALLOFF; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) { @@ -4581,8 +4566,7 @@ static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata, BKE_kelvinlet_init_params( ¶ms, ss->cache->radius, force, 1.0f, brush->elastic_deform_volume_preservation); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); float final_disp[3]; @@ -4840,8 +4824,7 @@ static void do_nudge_brush_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -4920,8 +4903,7 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata, KelvinletParams params; BKE_kelvinlet_init_params(¶ms, ss->cache->radius, bstrength, 1.0f, 0.4f); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!do_elastic && !sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -5058,8 +5040,7 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) { @@ -5132,8 +5113,7 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) { @@ -5205,8 +5185,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); if (!sculpt_brush_test_sq_fn(&test, orig_data.co)) { @@ -5320,8 +5299,7 @@ static void do_inflate_brush_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -5426,8 +5404,7 @@ static void do_flatten_brush_task_cb_ex(void *__restrict userdata, plane_from_point_normal_v3(test.plane_tool, area_co, area_no); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -5533,8 +5510,7 @@ static void calc_clay_surface_task_cb(void *__restrict userdata, return; } - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -5584,8 +5560,7 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata, plane_from_point_normal_v3(test.plane_tool, area_co, area_no); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -5704,8 +5679,7 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata, plane_from_point_normal_v3(test.plane_tool, area_co, area_no_sp); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!SCULPT_brush_test_cube(&test, vd.co, mat, brush->tip_roundness)) { continue; } @@ -5858,8 +5832,7 @@ static void do_fill_brush_task_cb_ex(void *__restrict userdata, plane_from_point_normal_v3(test.plane_tool, area_co, area_no); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -5957,8 +5930,7 @@ static void do_scrape_brush_task_cb_ex(void *__restrict userdata, const int thread_id = BLI_task_parallel_thread_id(tls); plane_from_point_normal_v3(test.plane_tool, area_co, area_no); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -6072,8 +6044,7 @@ static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata, /* Tilted plane (front part of the brush). */ plane_from_point_normal_v3(plane_tilt, area_co, normal_tilt); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -6228,8 +6199,7 @@ static void do_gravity_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -6741,8 +6711,7 @@ static void sculpt_combine_proxies_task_cb(void *__restrict userdata, BKE_pbvh_node_get_proxies(data->nodes[n], &proxies, &proxy_count); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { float val[3]; if (use_orco) { @@ -6875,8 +6844,7 @@ static void SCULPT_flush_stroke_deform_task_cb(void *__restrict userdata, PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { sculpt_flush_pbvhvert_deform(ob, &vd); if (!vertCos) { @@ -9515,8 +9483,7 @@ static void do_fake_neighbor_search_task_cb(void *__restrict userdata, NearestVertexFakeNeighborTLSData *nvtd = tls->userdata_chunk; PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { int vd_topology_id = SCULPT_vertex_get_connected_component(ss, vd.index); if (vd_topology_id != nvtd->current_topology_id && ss->fake_neighbors.fake_neighbor_index[vd.index] == FAKE_NEIGHBOR_NONE) { @@ -9786,8 +9753,7 @@ static void do_mask_by_color_contiguous_update_nodes_cb( const bool preserve_mask = data->mask_by_color_preserve_mask; PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { const float current_mask = *vd.mask; const float new_mask = data->mask_by_color_floodfill[vd.index]; *vd.mask = sculpt_mask_by_color_final_mask_get(current_mask, new_mask, invert, preserve_mask); @@ -9893,8 +9859,7 @@ static void do_mask_by_color_task_cb(void *__restrict userdata, const float *active_color = SCULPT_vertex_color_get(ss, data->mask_by_color_vertex); PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { const float current_mask = *vd.mask; const float new_mask = sculpt_mask_by_color_delta_get(active_color, vd.col, threshold, invert); *vd.mask = sculpt_mask_by_color_final_mask_get(current_mask, new_mask, invert, preserve_mask); diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c index 605bb6364c1..ebf65b28346 100644 --- a/source/blender/editors/sculpt_paint/sculpt_boundary.c +++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c @@ -708,8 +708,7 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata, } const float angle = angle_factor * M_PI; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (boundary->edit_info[vd.index].num_propagation_steps == -1) { continue; } @@ -757,8 +756,7 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata, const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, boundary); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (boundary->edit_info[vd.index].num_propagation_steps == -1) { continue; } @@ -804,8 +802,7 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata, const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, boundary); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (boundary->edit_info[vd.index].num_propagation_steps == -1) { continue; } @@ -851,8 +848,7 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata, SculptOrigVertData orig_data; SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (boundary->edit_info[vd.index].num_propagation_steps == -1) { continue; } @@ -903,8 +899,7 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata, } const float angle = angle_factor * M_PI; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (boundary->edit_info[vd.index].num_propagation_steps == -1) { continue; } @@ -950,8 +945,7 @@ static void do_boundary_brush_smooth_task_cb_ex(void *__restrict userdata, SculptOrigVertData orig_data; SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (boundary->edit_info[vd.index].num_propagation_steps == -1) { continue; } diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c index 4f27ac177b4..a4fb530aed4 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.c +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c @@ -381,8 +381,7 @@ static void do_cloth_brush_build_constraints_task_cb_ex( data->cloth_sim_radius * data->cloth_sim_radius : FLT_MAX; - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { const float len_squared = len_squared_v3v3(vd.co, data->cloth_sim_initial_location); if (len_squared < cloth_sim_radius_squared) { @@ -544,8 +543,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, madd_v3_v3fl(gravity, ss->cache->gravity_direction, -data->sd->gravity_factor); } - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { float force[3]; float sim_location[3]; cloth_brush_simulation_location_get(ss, brush, sim_location); @@ -840,8 +838,7 @@ static void do_cloth_brush_solve_simulation_task_cb_ex( AutomaskingCache *automasking = SCULPT_automasking_active_cache_get(ss); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { float sim_location[3]; cloth_brush_simulation_location_get(ss, brush, sim_location); const float sim_factor = @@ -1528,8 +1525,7 @@ static void cloth_filter_apply_forces_task_cb(void *__restrict userdata, mul_v3_fl(sculpt_gravity, sd->gravity_factor * data->filter_strength); PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { float fade = vd.mask ? *vd.mask : 0.0f; fade *= SCULPT_automasking_factor_get(ss->filter_cache->automasking, ss, vd.index); fade = 1.0f - fade; diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c index bd59bb781cc..1e1223295d4 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_expand.c @@ -1143,8 +1143,7 @@ static void sculpt_expand_restore_color_data(SculptSession *ss, ExpandCache *exp for (int n = 0; n < totnode; n++) { PBVHNode *node = nodes[n]; PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { copy_v4_v4(vd.col, expand_cache->original_colors[vd.index]); } BKE_pbvh_vertex_iter_end; @@ -1161,8 +1160,7 @@ static void sculpt_expand_restore_mask_data(SculptSession *ss, ExpandCache *expa for (int n = 0; n < totnode; n++) { PBVHNode *node = nodes[n]; PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { *vd.mask = expand_cache->original_mask[vd.index]; } BKE_pbvh_vertex_iter_end; @@ -1231,8 +1229,7 @@ static void sculpt_expand_mask_update_task_cb(void *__restrict userdata, bool any_changed = false; PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_ALL) { const float initial_mask = *vd.mask; const bool enabled = sculpt_expand_state_get(ss, expand_cache, vd.index); @@ -1304,8 +1301,7 @@ static void sculpt_expand_colors_update_task_cb(void *__restrict userdata, bool any_changed = false; PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_ALL) { float initial_color[4]; copy_v4_v4(initial_color, vd.col); diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c index bc4961b58b6..49884ac4a1c 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.c +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c @@ -138,8 +138,7 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, MVert *mvert = SCULPT_mesh_deformed_mverts_get(ss); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) { MeshElemMap *vert_map = &ss->pmap[vd.index]; for (int j = 0; j < ss->pmap[vd.index].count; j++) { @@ -214,8 +213,7 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata, const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.c index 3912c031313..93f20eba1b1 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_color.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.c @@ -110,8 +110,7 @@ static void color_filter_task_cb(void *__restrict userdata, SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]); PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); float orig_color[3], final_color[4], hsv_color[3]; int hue; diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c b/source/blender/editors/sculpt_paint/sculpt_filter_mask.c index 001c8f98ee9..90509232c11 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mask.c @@ -112,8 +112,7 @@ static void mask_filter_task_cb(void *__restrict userdata, contrast = -0.1f; } - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { float delta, gain, offset, max, min; float prev_val = *vd.mask; SculptVertexNeighborIter ni; @@ -1133,8 +1132,7 @@ static void dirty_mask_compute_range_task_cb(void *__restrict userdata, DirtyMaskRangeData *range = tls->userdata_chunk; PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { float dirty_mask = neighbor_dirty_mask(ss, &vd); range->min = min_ff(dirty_mask, range->min); range->max = max_ff(dirty_mask, range->max); @@ -1173,8 +1171,7 @@ static void dirty_mask_apply_task_cb(void *__restrict userdata, range = 1.0f / range; } - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { float dirty_mask = neighbor_dirty_mask(ss, &vd); float mask = *vd.mask + (1.0f - ((dirty_mask - min) * range)); if (dirty_only) { diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c index 915f0e57ccc..455a1d3b033 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c @@ -333,8 +333,7 @@ static void mesh_filter_task_cb(void *__restrict userdata, const bool relax_face_sets = !(ss->filter_cache->iteration_count % 3 == 0); PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); float orig_co[3], val[3], avg[3], normal[3], disp[3], disp2[3], transform[3][3], final_pos[3]; float fade = vd.mask ? *vd.mask : 0.0f; @@ -648,8 +647,7 @@ static void mesh_filter_surface_smooth_displace_task_cb( PBVHNode *node = data->nodes[i]; PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { float fade = vd.mask ? *vd.mask : 0.0f; fade = 1.0f - fade; fade *= data->filter_strength; diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c index 7a966568076..7f91c5dbc6e 100644 --- a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c @@ -85,8 +85,7 @@ static void sculpt_mask_expand_cancel(bContext *C, wmOperator *op) } else { PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { *vd.mask = ss->filter_cache->prev_mask[vd.index]; } BKE_pbvh_vertex_iter_end; @@ -114,8 +113,7 @@ static void sculpt_expand_task_cb(void *__restrict userdata, PBVHVertexIter vd; int update_it = data->mask_expand_update_it; - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_ALL) { int vi = vd.index; float final_mask = *vd.mask; if (data->mask_expand_use_normals) { @@ -227,8 +225,7 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent * for (int n = 0; n < ss->filter_cache->totnode; n++) { PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, ss->filter_cache->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, ss->filter_cache->nodes[n], vd, PBVH_ITER_UNIQUE) { const float mask = (vd.mask) ? *vd.mask : 0.0f; if (mask < (0.5f + threshold) && mask > (0.5f - threshold)) { if (SCULPT_check_vertex_pivot_symmetry( diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_init.c b/source/blender/editors/sculpt_paint/sculpt_mask_init.c index bad154bccb5..0c383cdf035 100644 --- a/source/blender/editors/sculpt_paint/sculpt_mask_init.c +++ b/source/blender/editors/sculpt_paint/sculpt_mask_init.c @@ -109,8 +109,7 @@ static void mask_init_task_cb(void *__restrict userdata, const int mode = data->mask_init_mode; const int seed = data->mask_init_seed; SCULPT_undo_push_node(data->ob, node, SCULPT_UNDO_MASK); - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { switch (mode) { case SCULPT_MASK_INIT_RANDOM_PER_VERTEX: *vd.mask = BLI_hash_int_01(vd.index + seed); diff --git a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c index cfc31e1dcdd..f78f30a2cfd 100644 --- a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c +++ b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c @@ -85,8 +85,7 @@ static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata, test_radius *= brush->normal_radius_factor; test.radius_squared = test_radius * test_radius; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; @@ -166,8 +165,7 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c index 5fdf8415f28..c3977b28178 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c +++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c @@ -85,8 +85,7 @@ static void do_color_smooth_task_cb_exec(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -139,8 +138,7 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata, BKE_brush_color_get(ss->scene, brush)); IMB_colormanagement_srgb_to_scene_linear_v3(brush_color); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); bool affect_vertex = false; @@ -227,8 +225,7 @@ static void do_sample_wet_paint_task_cb(void *__restrict userdata, test.radius *= data->brush->wet_paint_radius_factor; test.radius_squared = test.radius * test.radius; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -384,8 +381,7 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -454,8 +450,7 @@ static void do_smear_store_prev_colors_task_cb_exec(void *__restrict userdata, SculptSession *ss = data->ob->sculpt; PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { copy_v4_v4(ss->cache->prev_colors[vd.index], SCULPT_vertex_color_get(ss, vd.index)); } BKE_pbvh_vertex_iter_end; diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c index e4c0cceb0d6..8c4f68715b9 100644 --- a/source/blender/editors/sculpt_paint/sculpt_pose.c +++ b/source/blender/editors/sculpt_paint/sculpt_pose.c @@ -244,8 +244,7 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata, SculptOrigVertData orig_data; SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); float total_disp[3]; @@ -302,8 +301,7 @@ static void pose_brush_grow_factor_task_cb_ex(void *__restrict userdata, SculptSession *ss = data->ob->sculpt; const char symm = SCULPT_mesh_symmetry_xyz_get(data->ob); PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { SculptVertexNeighborIter ni; float max = 0.0f; @@ -675,8 +673,7 @@ static void pose_brush_init_task_cb_ex(void *__restrict userdata, SculptThreadedTaskData *data = userdata; SculptSession *ss = data->ob->sculpt; PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { SculptVertexNeighborIter ni; float avg = 0.0f; int total = 0; diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c index ab70f42a5e0..a68bacb2315 100644 --- a/source/blender/editors/sculpt_paint/sculpt_smooth.c +++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c @@ -229,8 +229,7 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -312,8 +311,7 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata, const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } @@ -473,8 +471,7 @@ static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex( SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; @@ -516,8 +513,7 @@ static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex( ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.c b/source/blender/editors/sculpt_paint/sculpt_transform.c index a9250610bda..4584f91b03a 100644 --- a/source/blender/editors/sculpt_paint/sculpt_transform.c +++ b/source/blender/editors/sculpt_paint/sculpt_transform.c @@ -189,8 +189,7 @@ static void sculpt_transform_task_cb(void *__restrict userdata, PBVHVertexIter vd; SCULPT_undo_push_node(data->ob, node, SCULPT_UNDO_COORDS); - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); float transformed_co[3], orig_co[3], disp[3]; float *start_co; @@ -474,8 +473,7 @@ static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op) if (mode == SCULPT_PIVOT_POSITION_UNMASKED) { for (int n = 0; n < totnode; n++) { PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { const float mask = (vd.mask) ? *vd.mask : 0.0f; if (mask < 1.0f) { if (SCULPT_check_vertex_pivot_symmetry(vd.co, ss->pivot_pos, symm)) { @@ -493,8 +491,7 @@ static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op) for (int n = 0; n < totnode; n++) { PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { const float mask = (vd.mask) ? *vd.mask : 0.0f; if (mask < (0.5f + threshold) && mask > (0.5f - threshold)) { if (SCULPT_check_vertex_pivot_symmetry(vd.co, ss->pivot_pos, symm)) { diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index b1e71a27dfc..4d063099216 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -1104,8 +1104,7 @@ static void sculpt_undo_store_coords(Object *ob, SculptUndoNode *unode) SculptSession *ss = ob->sculpt; PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, unode->node, vd, PBVH_ITER_ALL) { copy_v3_v3(unode->co[vd.i], vd.co); if (vd.no) { copy_v3_v3_short(unode->no[vd.i], vd.no); @@ -1147,8 +1146,7 @@ static void sculpt_undo_store_mask(Object *ob, SculptUndoNode *unode) SculptSession *ss = ob->sculpt; PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, unode->node, vd, PBVH_ITER_ALL) { unode->mask[vd.i] = *vd.mask; } BKE_pbvh_vertex_iter_end; @@ -1159,8 +1157,7 @@ static void sculpt_undo_store_color(Object *ob, SculptUndoNode *unode) SculptSession *ss = ob->sculpt; PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, unode->node, vd, PBVH_ITER_ALL) { copy_v4_v4(unode->col[vd.i], vd.col); } BKE_pbvh_vertex_iter_end; @@ -1258,8 +1255,7 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt case SCULPT_UNDO_MASK: /* Before any vertex values get modified, ensure their * original positions are logged. */ - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_ALL) { BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset); } BKE_pbvh_vertex_iter_end; @@ -1268,8 +1264,7 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt case SCULPT_UNDO_HIDDEN: { GSetIterator gs_iter; GSet *faces = BKE_pbvh_bmesh_node_faces(node); - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) - { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_ALL) { BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset); } BKE_pbvh_vertex_iter_end; diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl index edf2c93c9a0..12921a31b23 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl @@ -15,8 +15,9 @@ void node_ambient_occlusion(vec4 color, vec3 N = normalize(normal); vec3 Ng = safe_normalize(cross(dFdx(worldPosition), dFdy(worldPosition))); + float unused_error; vec3 unused; - occlusion_eval(data, V, N, Ng, inverted, result_ao, unused); + occlusion_eval(data, V, N, Ng, inverted, result_ao, unused_error, unused); result_color = result_ao * color; } #else diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl index 49c8973a8ce..2e0515e324e 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl @@ -193,7 +193,7 @@ void node_bsdf_principled(vec4 base_color, result.radiance *= alpha; result.ssr_data.rgb *= alpha; # ifdef USE_SSS - result.sss_irradiance *= alpha; + result.sss_albedo *= alpha; # endif } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index d19d270a7ac..ad1def0f3ec 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -1226,6 +1226,14 @@ typedef struct NodeAttributeSeparateXYZ { uint8_t input_type; } NodeAttributeSeparateXYZ; +typedef struct NodeAttributeConvert { + /* CustomDataType. */ + uint8_t data_type; + char _pad[1]; + /* AttributeDomain. */ + int16_t domain; +} NodeAttributeConvert; + /* script node mode */ #define NODE_SCRIPT_INTERNAL 0 #define NODE_SCRIPT_EXTERNAL 1 diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index dfb882cde33..622460979e7 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1929,6 +1929,23 @@ static void rna_GeometryNodeAttributeRandomize_data_type_update(Main *bmain, rna_Node_socket_update(bmain, scene, ptr); } +static bool attribute_convert_type_supported(const EnumPropertyItem *item) +{ + return ELEM(item->value, + CD_PROP_FLOAT, + CD_PROP_FLOAT2, + CD_PROP_FLOAT3, + CD_PROP_COLOR, + CD_PROP_BOOL, + CD_PROP_INT32); +} +static const EnumPropertyItem *rna_GeometryNodeAttributeConvert_type_itemf( + bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) +{ + *r_free = true; + return itemf_function_check(rna_enum_attribute_type_items, attribute_convert_type_supported); +} + static bool attribute_fill_type_supported(const EnumPropertyItem *item) { return ELEM( @@ -8647,6 +8664,35 @@ static void def_geo_attribute_fill(StructRNA *srna) "rna_GeometryNodeAttributeFill_domain_itemf"); } +static void def_geo_attribute_convert(StructRNA *srna) +{ + static const EnumPropertyItem rna_enum_attribute_convert_domain_items[] = { + {ATTR_DOMAIN_AUTO, "AUTO", 0, "Auto", ""}, + {ATTR_DOMAIN_POINT, "POINT", 0, "Point", "Attribute on point"}, + {ATTR_DOMAIN_EDGE, "EDGE", 0, "Edge", "Attribute on mesh edge"}, + {ATTR_DOMAIN_CORNER, "CORNER", 0, "Corner", "Attribute on mesh polygon corner"}, + {ATTR_DOMAIN_POLYGON, "POLYGON", 0, "Polygon", "Attribute on mesh polygons"}, + {0, NULL, 0, NULL, NULL}, + }; + + PropertyRNA *prop; + + RNA_def_struct_sdna_from(srna, "NodeAttributeConvert", "storage"); + + prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, rna_enum_attribute_type_items); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeConvert_type_itemf"); + RNA_def_property_enum_default(prop, CD_PROP_FLOAT); + RNA_def_property_ui_text(prop, "Data Type", "The data type to save the result attribute with"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update"); + + prop = RNA_def_property(srna, "domain", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, rna_enum_attribute_convert_domain_items); + RNA_def_property_enum_default(prop, ATTR_DOMAIN_AUTO); + RNA_def_property_ui_text(prop, "Domain", "The geometry domain to save the result attribute in"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); +} + static void def_geo_attribute_math(StructRNA *srna) { PropertyRNA *prop; @@ -10042,6 +10088,8 @@ static void rna_def_node_socket_standard_types(BlenderRNA *brna) brna, "NodeSocketFloatAngle", "NodeSocketInterfaceFloatAngle", PROP_ANGLE); rna_def_node_socket_float( brna, "NodeSocketFloatTime", "NodeSocketInterfaceFloatTime", PROP_TIME); + rna_def_node_socket_float( + brna, "NodeSocketFloatDistance", "NodeSocketInterfaceFloatDistance", PROP_DISTANCE); rna_def_node_socket_int(brna, "NodeSocketInt", "NodeSocketInterfaceInt", PROP_NONE); rna_def_node_socket_int( diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c index 6ffbf518dd1..cc42c89a60e 100644 --- a/source/blender/modifiers/intern/MOD_boolean.c +++ b/source/blender/modifiers/intern/MOD_boolean.c @@ -615,6 +615,23 @@ static Mesh *collection_boolean_exact(BooleanModifierData *bmd, } #ifdef WITH_GMP + +/* Get a mapping from material slot numbers in the src_ob to slot numbers in the dst_ob. + * If a material doesn't exist in the dst_ob, the mapping just goes to the same slot + * or to zero if there aren't enough slots in the destination. + * Caller must MEM_freeN the returned array. */ +static short *get_material_remap(Object *dest_ob, Object *src_ob) +{ + short *remap; + int n = dest_ob->totcol; + if (n <= 0) { + n = 1; + } + remap = MEM_mallocN(n * sizeof(short), __func__); + BKE_object_material_remap_calc(dest_ob, src_ob, remap); + return remap; +} + /* New method: bypass trip through BMesh. */ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd, const ModifierEvalContext *ctx, @@ -622,25 +639,32 @@ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd, { Mesh *result; Mesh *mesh_operand; + short *remap; Mesh **meshes = NULL; const float(**obmats)[4][4] = NULL; + short **material_remaps = NULL; BLI_array_declare(meshes); BLI_array_declare(obmats); + BLI_array_declare(material_remaps); # ifdef DEBUG_TIME TIMEIT_START(boolean_bmesh); # endif + if ((bmd->flag & eBooleanModifierFlag_Object) && bmd->object == NULL) { + return mesh; + } + BLI_array_append(meshes, mesh); BLI_array_append(obmats, &ctx->object->obmat); + BLI_array_append(material_remaps, NULL); if (bmd->flag & eBooleanModifierFlag_Object) { - if (bmd->object == NULL) { - return mesh; - } mesh_operand = BKE_modifier_get_evaluated_mesh_from_evaluated_object(bmd->object, false); BKE_mesh_wrapper_ensure_mdata(mesh_operand); BLI_array_append(meshes, mesh_operand); BLI_array_append(obmats, &bmd->object->obmat); + remap = get_material_remap(ctx->object, bmd->object); + BLI_array_append(material_remaps, remap); } else if (bmd->flag & eBooleanModifierFlag_Collection) { Collection *collection = bmd->collection; @@ -652,6 +676,8 @@ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd, BKE_mesh_wrapper_ensure_mdata(collection_mesh); BLI_array_append(meshes, collection_mesh); BLI_array_append(obmats, &ob->obmat); + remap = get_material_remap(ctx->object, ob); + BLI_array_append(material_remaps, remap); } } FOREACH_COLLECTION_OBJECT_RECURSIVE_END; @@ -662,6 +688,7 @@ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd, const bool hole_tolerant = (bmd->flag & eBooleanModifierFlag_HoleTolerant) != 0; result = BKE_mesh_boolean((const Mesh **)meshes, (const float(**)[4][4])obmats, + (const short **)material_remaps, BLI_array_len(meshes), use_self, hole_tolerant, @@ -669,6 +696,13 @@ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd, BLI_array_free(meshes); BLI_array_free(obmats); + for (int i = 0; i < BLI_array_len(material_remaps); i++) { + remap = material_remaps[i]; + if (remap) { + MEM_freeN(remap); + } + } + BLI_array_free(material_remaps); # ifdef DEBUG_TIME TIMEIT_END(boolean_bmesh); diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 9408e5348dd..bbc14751cdd 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -146,6 +146,7 @@ set(SRC geometry/nodes/node_geo_attribute_color_ramp.cc geometry/nodes/node_geo_attribute_combine_xyz.cc geometry/nodes/node_geo_attribute_compare.cc + geometry/nodes/node_geo_attribute_convert.cc geometry/nodes/node_geo_attribute_fill.cc geometry/nodes/node_geo_attribute_math.cc geometry/nodes/node_geo_attribute_mix.cc diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h index d7f56464b36..d28dc8209d4 100644 --- a/source/blender/nodes/NOD_geometry.h +++ b/source/blender/nodes/NOD_geometry.h @@ -30,6 +30,7 @@ void register_node_type_geo_align_rotation_to_vector(void); void register_node_type_geo_attribute_color_ramp(void); void register_node_type_geo_attribute_combine_xyz(void); void register_node_type_geo_attribute_compare(void); +void register_node_type_geo_attribute_convert(void); void register_node_type_geo_attribute_fill(void); void register_node_type_geo_attribute_math(void); void register_node_type_geo_attribute_mix(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 6669f47c6aa..493aaa05675 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -300,6 +300,7 @@ DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_COMBINE_XYZ, def_geo_attribute_combine_ DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_SEPARATE_XYZ, def_geo_attribute_separate_xyz, "ATTRIBUTE_SEPARATE_XYZ", AttributeSeparateXYZ, "Attribute Separate XYZ", "") DefNode(GeometryNode, GEO_NODE_SUBDIVIDE, 0, "SUBDIVIDE", Subdivide, "Subdivide", "") DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_REMOVE, 0, "ATTRIBUTE_REMOVE", AttributeRemove, "Attribute Remove", "") +DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_CONVERT, def_geo_attribute_convert, "ATTRIBUTE_CONVERT", AttributeConvert, "Attribute Convert", "") /* undefine macros */ #undef DefNode diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_convert.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_convert.cc new file mode 100644 index 00000000000..11d220dd903 --- /dev/null +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_convert.cc @@ -0,0 +1,164 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "node_geometry_util.hh" + +#include "UI_interface.h" +#include "UI_resources.h" + +static bNodeSocketTemplate geo_node_attribute_convert_in[] = { + {SOCK_GEOMETRY, N_("Geometry")}, + {SOCK_STRING, N_("Attribute")}, + {SOCK_STRING, N_("Result")}, + {-1, ""}, +}; + +static bNodeSocketTemplate geo_node_attribute_convert_out[] = { + {SOCK_GEOMETRY, N_("Geometry")}, + {-1, ""}, +}; + +static void geo_node_attribute_convert_layout(uiLayout *layout, + bContext *UNUSED(C), + PointerRNA *ptr) +{ + uiItemR(layout, ptr, "domain", 0, "", ICON_NONE); + uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE); +} + +static void geo_node_attribute_convert_init(bNodeTree *UNUSED(tree), bNode *node) +{ + NodeAttributeConvert *data = (NodeAttributeConvert *)MEM_callocN(sizeof(NodeAttributeConvert), + __func__); + + data->data_type = CD_PROP_FLOAT; + data->domain = ATTR_DOMAIN_AUTO; + node->storage = data; +} + +namespace blender::nodes { + +static AttributeDomain get_result_domain(const GeometryComponent &component, + StringRef source_name, + StringRef result_name) +{ + ReadAttributePtr result_attribute = component.attribute_try_get_for_read(result_name); + if (result_attribute) { + return result_attribute->domain(); + } + ReadAttributePtr source_attribute = component.attribute_try_get_for_read(source_name); + if (source_attribute) { + return source_attribute->domain(); + } + return ATTR_DOMAIN_POINT; +} + +static void attribute_convert_calc(GeometryComponent &component, + const GeoNodeExecParams ¶ms, + const StringRef source_name, + const StringRef result_name, + const CustomDataType result_type, + const AttributeDomain domain) +{ + const AttributeDomain result_domain = (domain == ATTR_DOMAIN_AUTO) ? + get_result_domain( + component, source_name, result_name) : + domain; + + ReadAttributePtr source_attribute = component.attribute_try_get_for_read( + source_name, result_domain, result_type); + if (!source_attribute) { + params.error_message_add(NodeWarningType::Error, + TIP_("No attribute with name \"") + source_name + "\""); + return; + } + + OutputAttributePtr result_attribute = component.attribute_try_get_for_output( + result_name, result_domain, result_type); + if (!result_attribute) { + return; + } + + fn::GSpan source_span = source_attribute->get_span(); + fn::GMutableSpan result_span = result_attribute->get_span_for_write_only(); + if (source_span.is_empty() || result_span.is_empty()) { + return; + } + BLI_assert(source_span.size() == result_span.size()); + + const CPPType *cpp_type = bke::custom_data_type_to_cpp_type(result_type); + BLI_assert(cpp_type != nullptr); + + cpp_type->copy_to_initialized_n(source_span.data(), result_span.data(), result_span.size()); + + result_attribute.apply_span_and_save(); +} + +static void geo_node_attribute_convert_exec(GeoNodeExecParams params) +{ + GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry"); + + geometry_set = geometry_set_realize_instances(geometry_set); + + const std::string result_name = params.extract_input<std::string>("Result"); + const std::string source_name = params.extract_input<std::string>("Attribute"); + const NodeAttributeConvert &node_storage = *(const NodeAttributeConvert *)params.node().storage; + const CustomDataType data_type = static_cast<CustomDataType>(node_storage.data_type); + const AttributeDomain domain = static_cast<AttributeDomain>(node_storage.domain); + + if (result_name.empty()) { + params.set_output("Geometry", geometry_set); + return; + } + + if (geometry_set.has<MeshComponent>()) { + attribute_convert_calc(geometry_set.get_component_for_write<MeshComponent>(), + params, + source_name, + result_name, + data_type, + domain); + } + if (geometry_set.has<PointCloudComponent>()) { + attribute_convert_calc(geometry_set.get_component_for_write<PointCloudComponent>(), + params, + source_name, + result_name, + data_type, + domain); + } + + params.set_output("Geometry", geometry_set); +} + +} // namespace blender::nodes + +void register_node_type_geo_attribute_convert() +{ + static bNodeType ntype; + + geo_node_type_base( + &ntype, GEO_NODE_ATTRIBUTE_CONVERT, "Attribute Convert", NODE_CLASS_ATTRIBUTE, 0); + node_type_socket_templates( + &ntype, geo_node_attribute_convert_in, geo_node_attribute_convert_out); + ntype.geometry_node_execute = blender::nodes::geo_node_attribute_convert_exec; + ntype.draw_buttons = geo_node_attribute_convert_layout; + node_type_init(&ntype, geo_node_attribute_convert_init); + node_type_storage( + &ntype, "NodeAttributeConvert", node_free_standard_storage, node_copy_standard_storage); + + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc index 45aaf81d63f..54b0c07a0a0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc @@ -224,7 +224,7 @@ static void join_components(Span<const MeshComponent *> src_components, Geometry /* Don't copy attributes that are stored directly in the mesh data structs. */ join_attributes(to_base_components(src_components), dst_component, - {"position", "material_index", "vertex_normal", "shade_smooth"}); + {"position", "material_index", "normal", "shade_smooth"}); } static void join_components(Span<const PointCloudComponent *> src_components, GeometrySet &result) diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc index 60c2d6c37e1..2d60e959c44 100644 --- a/source/blender/nodes/intern/node_socket.cc +++ b/source/blender/nodes/intern/node_socket.cc @@ -712,6 +712,7 @@ void register_standard_node_socket_types(void) nodeRegisterSocketType(make_socket_type_float(PROP_FACTOR)); nodeRegisterSocketType(make_socket_type_float(PROP_ANGLE)); nodeRegisterSocketType(make_socket_type_float(PROP_TIME)); + nodeRegisterSocketType(make_socket_type_float(PROP_DISTANCE)); nodeRegisterSocketType(make_socket_type_int(PROP_NONE)); nodeRegisterSocketType(make_socket_type_int(PROP_UNSIGNED)); diff --git a/source/blender/nodes/intern/node_tree_multi_function.cc b/source/blender/nodes/intern/node_tree_multi_function.cc index abd9940cf56..c9729d43a42 100644 --- a/source/blender/nodes/intern/node_tree_multi_function.cc +++ b/source/blender/nodes/intern/node_tree_multi_function.cc @@ -175,12 +175,12 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<float2, int32_t>( conversions, "float2 to int32_t", [](float2 a) { return (int32_t)a.length(); }); add_implicit_conversion<float2, bool>( - conversions, "float2 to bool", [](float2 a) { return a.length_squared() == 0.0f; }); + conversions, "float2 to bool", [](float2 a) { return !is_zero_v2(a); }); add_implicit_conversion<float2, Color4f>( conversions, "float2 to Color4f", [](float2 a) { return Color4f(a.x, a.y, 0.0f, 1.0f); }); add_implicit_conversion<float3, bool>( - conversions, "float3 to boolean", [](float3 a) { return a.length_squared() == 0.0f; }); + conversions, "float3 to boolean", [](float3 a) { return !is_zero_v3(a); }); add_implicit_conversion<float3, float>( conversions, "Vector Length", [](float3 a) { return a.length(); }); add_implicit_conversion<float3, int32_t>( @@ -207,7 +207,7 @@ static DataTypeConversions create_implicit_conversions() }); add_implicit_conversion<Color4f, bool>(conversions, "Color4f to boolean", [](Color4f a) { - return a.r == 0.0f && a.g == 0.0f && a.b == 0.0f; + return a.r != 0.0f && a.g != 0.0f && a.b != 0.0f; }); add_implicit_conversion<Color4f, float>( conversions, "Color4f to float", [](Color4f a) { return rgb_to_grayscale(a); }); diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c index 051e3e4c1a9..9b38f010205 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c @@ -1258,9 +1258,6 @@ void wm_gizmomaptypes_free(void) */ void wm_gizmos_keymap(wmKeyConfig *keyconf) { - /* we add this item-less keymap once and use it to group gizmo-group keymaps into it */ - WM_keymap_ensure(keyconf, "Gizmos", 0, 0); - LISTBASE_FOREACH (wmGizmoMapType *, gzmap_type, &gizmomaptypes) { LISTBASE_FOREACH (wmGizmoGroupTypeRef *, gzgt_ref, &gzmap_type->grouptype_refs) { wm_gizmogrouptype_setup_keymap(gzgt_ref->type, keyconf); diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index b66544831f1..3f1bbb7a669 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -473,7 +473,10 @@ void WM_keyconfig_init(bContext *C) wm->defaultconf->flag |= KEYCONF_INIT_DEFAULT; } - WM_keyconfig_update_tag(NULL, NULL); + /* Harmless, but no need to update in background mode. */ + if (!G.background) { + WM_keyconfig_update_tag(NULL, NULL); + } WM_keyconfig_update(wm); wm->initialized |= WM_KEYCONFIG_IS_INIT; diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 6cc9a4c9b64..38d06ea83d3 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -1773,10 +1773,6 @@ void WM_keyconfig_update(wmWindowManager *wm) { bool compat_update = false; - if (G.background) { - return; - } - if (wm_keymap_update_flag == 0) { return; } @@ -1805,72 +1801,71 @@ void WM_keyconfig_update(wmWindowManager *wm) wm_keymap_update_flag &= ~WM_KEYMAP_UPDATE_OPERATORTYPE; } - if (wm_keymap_update_flag == 0) { - return; - } - - /* update operator properties for non-modal user keymaps */ - LISTBASE_FOREACH (wmKeyMap *, km, &U.user_keymaps) { - if ((km->flag & KEYMAP_MODAL) == 0) { - LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &km->diff_items) { - if (kmdi->add_item) { - wm_keymap_item_properties_set(kmdi->add_item); + if (wm_keymap_update_flag & WM_KEYMAP_UPDATE_RECONFIGURE) { + /* update operator properties for non-modal user keymaps */ + LISTBASE_FOREACH (wmKeyMap *, km, &U.user_keymaps) { + if ((km->flag & KEYMAP_MODAL) == 0) { + LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &km->diff_items) { + if (kmdi->add_item) { + wm_keymap_item_properties_set(kmdi->add_item); + } + if (kmdi->remove_item) { + wm_keymap_item_properties_set(kmdi->remove_item); + } } - if (kmdi->remove_item) { - wm_keymap_item_properties_set(kmdi->remove_item); + + LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) { + wm_keymap_item_properties_set(kmi); } } + } - LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) { - wm_keymap_item_properties_set(kmi); + /* update U.user_keymaps with user key configuration changes */ + LISTBASE_FOREACH (wmKeyMap *, km, &wm->userconf->keymaps) { + /* only diff if the user keymap was modified */ + if (wm_keymap_test_and_clear_update(km)) { + /* find keymaps */ + wmKeyMap *defaultmap = wm_keymap_preset(wm, km); + wmKeyMap *addonmap = WM_keymap_list_find( + &wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid); + + /* diff */ + if (defaultmap) { + wm_keymap_diff_update(&U.user_keymaps, defaultmap, addonmap, km); + } } } - } - /* update U.user_keymaps with user key configuration changes */ - LISTBASE_FOREACH (wmKeyMap *, km, &wm->userconf->keymaps) { - /* only diff if the user keymap was modified */ - if (wm_keymap_test_and_clear_update(km)) { + /* create user key configuration from preset + addon + user preferences */ + LISTBASE_FOREACH (wmKeyMap *, km, &wm->defaultconf->keymaps) { /* find keymaps */ wmKeyMap *defaultmap = wm_keymap_preset(wm, km); wmKeyMap *addonmap = WM_keymap_list_find( &wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid); + wmKeyMap *usermap = WM_keymap_list_find( + &U.user_keymaps, km->idname, km->spaceid, km->regionid); - /* diff */ - if (defaultmap) { - wm_keymap_diff_update(&U.user_keymaps, defaultmap, addonmap, km); - } - } - } - - /* create user key configuration from preset + addon + user preferences */ - LISTBASE_FOREACH (wmKeyMap *, km, &wm->defaultconf->keymaps) { - /* find keymaps */ - wmKeyMap *defaultmap = wm_keymap_preset(wm, km); - wmKeyMap *addonmap = WM_keymap_list_find( - &wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid); - wmKeyMap *usermap = WM_keymap_list_find( - &U.user_keymaps, km->idname, km->spaceid, km->regionid); + /* For now only the default map defines modal key-maps, + * if we support modal keymaps for 'addonmap', these will need to be enabled too. */ + wm_user_modal_keymap_set_items(wm, defaultmap); - /* For now only the default map defines modal key-maps, - * if we support modal keymaps for 'addonmap', these will need to be enabled too. */ - wm_user_modal_keymap_set_items(wm, defaultmap); + /* add */ + wmKeyMap *kmn = wm_keymap_patch_update( + &wm->userconf->keymaps, defaultmap, addonmap, usermap); - /* add */ - wmKeyMap *kmn = wm_keymap_patch_update(&wm->userconf->keymaps, defaultmap, addonmap, usermap); + if (kmn) { + kmn->modal_items = km->modal_items; + kmn->poll = km->poll; + kmn->poll_modal_item = km->poll_modal_item; + } - if (kmn) { - kmn->modal_items = km->modal_items; - kmn->poll = km->poll; - kmn->poll_modal_item = km->poll_modal_item; + /* in case of old non-diff keymaps, force extra update to create diffs */ + compat_update = compat_update || (usermap && !(usermap->flag & KEYMAP_DIFF)); } - /* in case of old non-diff keymaps, force extra update to create diffs */ - compat_update = compat_update || (usermap && !(usermap->flag & KEYMAP_DIFF)); + wm_keymap_update_flag &= ~WM_KEYMAP_UPDATE_RECONFIGURE; } - wm_keymap_update_flag &= ~WM_KEYMAP_UPDATE_RECONFIGURE; - BLI_assert(wm_keymap_update_flag == 0); if (compat_update) { |