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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorPablo Dobarro <pablodp606@gmail.com>2021-03-14 23:14:58 +0300
committerPablo Dobarro <pablodp606@gmail.com>2021-03-14 23:14:58 +0300
commit476b333a3ef8dff9fa8b5b3b6adff2565c7be840 (patch)
tree97e0c3745f223c73317a171bd581db06deb0d604 /source
parent4ad1a7ab313d9a0382cf4c522412b3b882184b86 (diff)
parenta01fb22f28df21acab103a5216591355b1dc85d7 (diff)
Merge branch 'master' into sculpt-dev
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_attribute.h1
-rw-r--r--source/blender/blenkernel/BKE_mesh_boolean_convert.h1
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc5
-rw-r--r--source/blender/blenkernel/intern/attribute_access_intern.hh3
-rw-r--r--source/blender/blenkernel/intern/geometry_component_mesh.cc117
-rw-r--r--source/blender/blenkernel/intern/geometry_component_pointcloud.cc2
-rw-r--r--source/blender/blenkernel/intern/geometry_set_instances.cc2
-rw-r--r--source/blender/blenkernel/intern/mesh_boolean_convert.cc36
-rw-r--r--source/blender/blenkernel/intern/node.cc5
-rw-r--r--source/blender/blenkernel/intern/pbvh.c9
-rw-r--r--source/blender/blenlib/intern/mesh_boolean.cc1
-rw-r--r--source/blender/draw/CMakeLists.txt5
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c47
-rw-r--r--source/blender/draw/engines/eevee/eevee_occlusion.c34
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h24
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_screen_raytrace.c56
-rw-r--r--source/blender/draw/engines/eevee/eevee_shaders.c163
-rw-r--r--source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl21
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl100
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl19
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_downsample_cube_frag.glsl7
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl7
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl50
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl101
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl (renamed from source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl)228
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl149
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl8
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl13
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl9
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl9
-rw-r--r--source/blender/draw/engines/eevee/shaders/random_lib.glsl38
-rw-r--r--source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/surface_frag.glsl2
-rw-r--r--source/blender/draw/intern/shaders/common_math_geom_lib.glsl10
-rw-r--r--source/blender/draw/tests/shaders_test.cc8
-rw-r--r--source/blender/editors/screen/screen_ops.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c12
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c24
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c105
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_boundary.c18
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_cloth.c12
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_expand.c12
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_face_set.c6
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_color.c3
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mask.c9
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mesh.c6
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_mask_expand.c9
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_mask_init.c3
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c6
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_paint_color.c15
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_pose.c9
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_smooth.c12
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_transform.c9
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c15
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl3
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl2
-rw-r--r--source/blender/makesdna/DNA_node_types.h8
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c48
-rw-r--r--source/blender/modifiers/intern/MOD_boolean.c40
-rw-r--r--source/blender/nodes/CMakeLists.txt1
-rw-r--r--source/blender/nodes/NOD_geometry.h1
-rw-r--r--source/blender/nodes/NOD_static_types.h1
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_convert.cc164
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc2
-rw-r--r--source/blender/nodes/intern/node_socket.cc1
-rw-r--r--source/blender/nodes/intern/node_tree_multi_function.cc6
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c3
-rw-r--r--source/blender/windowmanager/intern/wm.c5
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c97
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(
&params, 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(&params, 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 &params,
+ 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) {