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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <b.mont29@gmail.com>2020-02-25 18:18:17 +0300
committerBastien Montagne <b.mont29@gmail.com>2020-02-25 18:18:17 +0300
commit1ee9fa05b6f7f35f848cc6d229170cc9dd72a054 (patch)
tree75ced6e674cba73791d2ac86ff96f2ef617714c8
parent79f09c6bf275999ee9d0163fd6b79e5e32a21f48 (diff)
parent6dd3e7d84da632402bab3ee136fc7d3b47b3b697 (diff)
Merge branch 'master' into id-ensure-unique-memory-address
-rwxr-xr-xbuild_files/build_environment/install_deps.sh342
-rw-r--r--build_files/build_environment/patches/.gitattributes2
-rw-r--r--build_files/build_environment/patches/opencollada.diff103
-rw-r--r--build_files/buildbot/codesign/archive_with_indicator.py28
-rw-r--r--build_files/buildbot/codesign/base_code_signer.py3
-rw-r--r--build_files/windows/detect_msvc_vswhere.cmd9
-rw-r--r--extern/audaspace/include/devices/IDevice.h6
-rw-r--r--extern/audaspace/include/devices/IDeviceFactory.h2
-rw-r--r--extern/audaspace/include/file/IFileInput.h2
-rw-r--r--extern/audaspace/src/fx/DynamicMusic.cpp2
-rw-r--r--extern/mantaflow/preprocessed/fileio/ioutil.cpp27
-rw-r--r--extern/mantaflow/preprocessed/gitinfo.h2
-rw-r--r--extern/mantaflow/preprocessed/grid.cpp421
-rw-r--r--extern/mantaflow/preprocessed/levelset.cpp4
-rw-r--r--intern/cycles/blender/addon/engine.py6
-rw-r--r--intern/cycles/blender/addon/properties.py21
-rw-r--r--intern/cycles/blender/addon/ui.py26
-rw-r--r--intern/cycles/blender/addon/version_update.py5
-rw-r--r--intern/cycles/blender/blender_curves.cpp8
-rw-r--r--intern/cycles/blender/blender_device.cpp5
-rw-r--r--intern/cycles/blender/blender_geometry.cpp8
-rw-r--r--intern/cycles/blender/blender_mesh.cpp8
-rw-r--r--intern/cycles/blender/blender_session.cpp7
-rw-r--r--intern/cycles/blender/blender_sync.cpp6
-rw-r--r--intern/cycles/blender/blender_sync.h12
-rw-r--r--intern/cycles/blender/blender_volume.cpp5
-rw-r--r--intern/cycles/bvh/bvh_embree.cpp46
-rw-r--r--intern/cycles/kernel/kernel_accumulate.h75
-rw-r--r--intern/cycles/kernel/kernel_bake.h20
-rw-r--r--intern/cycles/kernel/kernel_emission.h6
-rw-r--r--intern/cycles/kernel/kernel_passes.h14
-rw-r--r--intern/cycles/kernel/kernel_shader.h17
-rw-r--r--intern/cycles/kernel/kernel_types.h37
-rw-r--r--intern/cycles/kernel/shaders/node_vector_rotate.osl25
-rw-r--r--intern/cycles/kernel/svm/svm_types.h11
-rw-r--r--intern/cycles/kernel/svm/svm_vector_rotate.h22
-rw-r--r--intern/cycles/render/bake.cpp2
-rw-r--r--intern/cycles/render/film.cpp18
-rw-r--r--intern/cycles/render/nodes.cpp5
-rw-r--r--intern/cycles/render/session.cpp21
-rw-r--r--intern/cycles/render/session.h12
-rw-r--r--intern/mantaflow/CMakeLists.txt2
-rw-r--r--intern/opencolorio/gpu_shader_display_transform.glsl1
-rw-r--r--release/datafiles/userdef/userdef_default_theme.c22
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py8
-rw-r--r--release/scripts/startup/bl_ui/properties_view_layer.py95
-rw-r--r--release/scripts/startup/bl_ui/space_toolsystem_common.py72
-rw-r--r--release/scripts/startup/bl_ui/space_toolsystem_toolbar.py9
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py2
-rw-r--r--source/blender/blenfont/intern/blf.c3
-rw-r--r--source/blender/blenfont/intern/blf_font.c53
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c230
-rw-r--r--source/blender/blenfont/intern/blf_internal_types.h47
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenkernel/BKE_cdderivedmesh.h3
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c144
-rw-r--r--source/blender/blenkernel/intern/fluid.c35
-rw-r--r--source/blender/blenkernel/intern/ocean.c8
-rw-r--r--source/blender/blenkernel/intern/tracking.c2
-rw-r--r--source/blender/blenlib/BLI_fileops.h24
-rw-r--r--source/blender/blenlib/intern/storage.c64
-rw-r--r--source/blender/blenloader/intern/versioning_260.c17
-rw-r--r--source/blender/blenloader/intern/versioning_280.c42
-rw-r--r--source/blender/blenloader/intern/versioning_userdef.c13
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc163
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc4
-rw-r--r--source/blender/draw/CMakeLists.txt5
-rw-r--r--source/blender/draw/DRW_engine.h18
-rw-r--r--source/blender/draw/DRW_engine_types.h51
-rw-r--r--source/blender/draw/engines/eevee/eevee_bloom.c82
-rw-r--r--source/blender/draw/engines/eevee/eevee_data.c3
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c10
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c13
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.c6
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c22
-rw-r--r--source/blender/draw/engines/eevee/eevee_lookdev.c96
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c734
-rw-r--r--source/blender/draw/engines/eevee/eevee_mist.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_occlusion.c8
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h98
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c217
-rw-r--r--source/blender/draw/engines/eevee/eevee_renderpasses.c232
-rw-r--r--source/blender/draw/engines/eevee/eevee_screen_raytrace.c41
-rw-r--r--source/blender/draw/engines/eevee/eevee_shaders.c23
-rw-r--r--source/blender/draw/engines/eevee/eevee_shadows.c89
-rw-r--r--source/blender/draw/engines/eevee/eevee_shadows_cascade.c22
-rw-r--r--source/blender/draw/engines/eevee/eevee_subsurface.c110
-rw-r--r--source/blender/draw/engines/eevee/eevee_temporal_sampling.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_volumes.c89
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl34
-rw-r--r--source/blender/draw/engines/eevee/shaders/default_frag.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/default_world_frag.glsl15
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl7
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl11
-rw-r--r--source/blender/draw/engines/eevee/shaders/lights_lib.glsl42
-rw-r--r--source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl77
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl58
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_accum_frag.glsl11
-rw-r--r--source/blender/draw/engines/overlay/overlay_antialiasing.c55
-rw-r--r--source/blender/draw/engines/overlay/overlay_engine.c3
-rw-r--r--source/blender/draw/engines/overlay/overlay_private.h6
-rw-r--r--source/blender/draw/engines/overlay/overlay_shader.c14
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_mesh_vert.glsl11
-rw-r--r--source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl9
-rw-r--r--source/blender/draw/engines/overlay/shaders/xray_fade_frag.glsl15
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl38
-rw-r--r--source/blender/draw/engines/workbench/workbench_forward.c40
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h1
-rw-r--r--source/blender/draw/intern/DRW_render.h23
-rw-r--r--source/blender/editors/animation/anim_markers.c41
-rw-r--r--source/blender/editors/include/ED_object.h14
-rw-r--r--source/blender/editors/include/ED_screen.h4
-rw-r--r--source/blender/editors/include/ED_screen_types.h1
-rw-r--r--source/blender/editors/include/UI_icons.h2
-rw-r--r--source/blender/editors/include/UI_resources.h2
-rw-r--r--source/blender/editors/interface/interface_ops.c8
-rw-r--r--source/blender/editors/interface/interface_region_popup.c4
-rw-r--r--source/blender/editors/interface/resources.c6
-rw-r--r--source/blender/editors/object/object_constraint.c5
-rw-r--r--source/blender/editors/object/object_modifier.c68
-rw-r--r--source/blender/editors/render/render_shading.c33
-rw-r--r--source/blender/editors/screen/area.c18
-rw-r--r--source/blender/editors/screen/screen_edit.c155
-rw-r--r--source/blender/editors/screen/screen_ops.c6
-rw-r--r--source/blender/editors/space_file/file_draw.c30
-rw-r--r--source/blender/editors/space_file/filelist.c116
-rw-r--r--source/blender/editors/space_image/image_buttons.c10
-rw-r--r--source/blender/editors/space_image/image_ops.c92
-rw-r--r--source/blender/editors/space_node/node_draw.c6
-rw-r--r--source/blender/editors/space_view3d/CMakeLists.txt4
-rw-r--r--source/blender/editors/transform/transform.c168
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c10
-rw-r--r--source/blender/editors/transform/transform_generics.c15
-rw-r--r--source/blender/editors/transform/transform_mode.c162
-rw-r--r--source/blender/editors/transform/transform_mode.h2
-rw-r--r--source/blender/editors/transform/transform_orientations.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c14
-rw-r--r--source/blender/gpu/GPU_draw.h1
-rw-r--r--source/blender/gpu/intern/gpu_draw.c17
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl1
-rw-r--r--source/blender/gpu/shaders/gpu_shader_text_frag.glsl120
-rw-r--r--source/blender/gpu/shaders/gpu_shader_text_vert.glsl21
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl2
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl4
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_emission.glsl2
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl6
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl2
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl97
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl2
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl1
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl2
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_vector_rotate.glsl30
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h1
-rw-r--r--source/blender/imbuf/intern/oiio/openimageio_api.cpp4
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp13
-rw-r--r--source/blender/makesdna/DNA_image_types.h2
-rw-r--r--source/blender/makesdna/DNA_layer_types.h27
-rw-r--r--source/blender/makesdna/DNA_node_types.h5
-rw-r--r--source/blender/makesdna/DNA_scene_types.h22
-rw-r--r--source/blender/makesdna/DNA_screen_types.h2
-rw-r--r--source/blender/makesdna/DNA_space_types.h2
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h1
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h2
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h10
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/intern/rna_fluid.c2
-rw-r--r--source/blender/makesrna/intern/rna_image.c18
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c2
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c32
-rw-r--r--source/blender/makesrna/intern/rna_render.c3
-rw-r--r--source/blender/makesrna/intern/rna_scene.c36
-rw-r--r--source/blender/makesrna/intern/rna_screen.c2
-rw-r--r--source/blender/makesrna/intern/rna_space.c72
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c54
-rw-r--r--source/blender/nodes/composite/node_composite_tree.c7
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_image.c19
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_rotate.c19
-rw-r--r--source/blender/render/CMakeLists.txt4
-rw-r--r--source/blender/render/extern/include/RE_engine.h5
-rw-r--r--source/blender/render/intern/source/external_engine.c2
-rw-r--r--source/blender/render/intern/source/render_result.c9
-rw-r--r--source/blender/windowmanager/intern/wm_files.c3
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c6
-rw-r--r--source/blender/windowmanager/intern/wm_splash_screen.c2
-rw-r--r--source/blender/windowmanager/intern/wm_toolsystem.c9
-rw-r--r--tests/python/CMakeLists.txt7
-rw-r--r--tests/python/bl_constraints.py204
188 files changed, 4651 insertions, 2178 deletions
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh
index 6294ab8bdd3..0553f615805 100755
--- a/build_files/build_environment/install_deps.sh
+++ b/build_files/build_environment/install_deps.sh
@@ -377,9 +377,7 @@ OCIO_FORCE_REBUILD=false
OCIO_SKIP=false
OPENEXR_VERSION="2.4.0"
-OPENEXR_VERSION_MIN="2.0.1"
-ILMBASE_VERSION="2.4.0"
-ILMBASE_VERSION_MIN="2.3"
+OPENEXR_VERSION_MIN="2.3"
OPENEXR_FORCE_BUILD=false
OPENEXR_FORCE_REBUILD=false
OPENEXR_SKIP=false
@@ -868,16 +866,15 @@ BOOST_SOURCE=( "http://sourceforge.net/projects/boost/files/boost/$BOOST_VERSION
BOOST_BUILD_MODULES="--with-system --with-filesystem --with-thread --with-regex --with-locale --with-date_time --with-wave --with-iostreams --with-python --with-program_options"
OCIO_USE_REPO=false
-OCIO_SOURCE=( "https://github.com/imageworks/OpenColorIO/archive/v$OCIO_VERSION.tar.gz")
+OCIO_SOURCE=( "https://github.com/AcademySoftwareFoundation/OpenColorIO/archive/v$OCIO_VERSION.tar.gz")
#~ OCIO_SOURCE_REPO=( "https://github.com/imageworks/OpenColorIO.git" )
#~ OCIO_SOURCE_REPO_UID="6de971097c7f552300f669ed69ca0b6cf5a70843"
OPENEXR_USE_REPO=false
-#~ OPENEXR_SOURCE=( "https://github.com/openexr/openexr/releases/download/v$OPENEXR_VERSION/openexr-$OPENEXR_VERSION.tar.gz" )
+OPENEXR_SOURCE=( "https://github.com/AcademySoftwareFoundation/openexr/archive/v$OPENEXR_VERSION.tar.gz" )
+OPENEXR_SOURCE_REPO=( "https://github.com/AcademySoftwareFoundation/openexr.git" )
OPENEXR_SOURCE_REPO_UID="0ac2ea34c8f3134148a5df4052e40f155b76f6fb"
-OPENEXR_SOURCE=( "https://github.com/openexr/openexr/archive/$OPENEXR_SOURCE_REPO_UID.tar.gz" )
-#~ OPENEXR_SOURCE_REPO=( "https://github.com/mont29/openexr.git" )
-ILMBASE_SOURCE=( "https://github.com/openexr/openexr/releases/download/v$ILMBASE_VERSION/ilmbase-$ILMBASE_VERSION.tar.gz" )
+#~ OPENEXR_SOURCE=( "https://github.com/openexr/openexr/archive/$OPENEXR_SOURCE_REPO_UID.tar.gz" )
OIIO_USE_REPO=false
OIIO_SOURCE=( "https://github.com/OpenImageIO/oiio/archive/Release-$OIIO_VERSION.tar.gz" )
@@ -974,7 +971,7 @@ You may also want to build them yourself (optional ones are [between brackets]):
* Boost $BOOST_VERSION_MIN (from $BOOST_SOURCE, modules: $BOOST_BUILD_MODULES).
* [FFMpeg $FFMPEG_VERSION_MIN (needs libvorbis, libogg, libtheora, libx264, libmp3lame, libxvidcore, libvpx, ...)] (from $FFMPEG_SOURCE).
* [OpenColorIO $OCIO_VERSION_MIN] (from $OCIO_SOURCE).
- * ILMBase $ILMBASE_VERSION_MIN (from $ILMBASE_SOURCE).
+ * ILMBase $OPENEXR_VERSION_MIN (from $OPENEXR_SOURCE).
* OpenEXR $OPENEXR_VERSION_MIN (from $OPENEXR_SOURCE).
* OpenImageIO $OIIO_VERSION_MIN (from $OIIO_SOURCE).
* [LLVM $LLVM_VERSION_MIN (with clang)] (from $LLVM_SOURCE, and $LLVM_CLANG_SOURCE).
@@ -1201,10 +1198,15 @@ _init_python() {
_inst_shortcut=$INST/python-$PYTHON_VERSION_MIN
}
+_update_deps_python() {
+ :
+}
+
clean_Python() {
clean_Numpy
_init_python
_clean
+ _update_deps_python
}
compile_Python() {
@@ -1225,6 +1227,10 @@ compile_Python() {
if [ ! -d $_inst ]; then
INFO "Building Python-$PYTHON_VERSION"
+ _is_building=true
+
+ # Rebuild dependencies as well!
+ _update_deps_python
prepare_opt
@@ -1256,6 +1262,7 @@ compile_Python() {
cd $CWD
INFO "Done compiling Python-$PYTHON_VERSION!"
+ _is_building=false
else
INFO "Own Python-$PYTHON_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-python option."
@@ -1274,9 +1281,14 @@ _init_numpy() {
_inst_shortcut=$_python/$_site/numpy
}
+_update_deps_numpy() {
+ :
+}
+
clean_Numpy() {
_init_numpy
_clean
+ _update_deps_numpy
}
compile_Numpy() {
@@ -1297,6 +1309,10 @@ compile_Numpy() {
if [ ! -d $_inst ]; then
INFO "Building Numpy-$NUMPY_VERSION"
+ _is_building=true
+
+ # Rebuild dependencies as well!
+ _update_deps_numpy
prepare_opt
@@ -1325,6 +1341,7 @@ compile_Numpy() {
cd $CWD
INFO "Done compiling Numpy-$NUMPY_VERSION!"
+ _is_building=false
else
INFO "Own Numpy-$NUMPY_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-numpy option."
@@ -1341,9 +1358,23 @@ _init_boost() {
_inst_shortcut=$INST/boost
}
+_update_deps_boost() {
+ OIIO_FORCE_REBUILD=true
+ OSL_FORCE_REBUILD=true
+ OPENVDB_FORCE_REBUILD=true
+ ALEMBIC_FORCE_REBUILD=true
+ if [ "$_is_building" = true ]; then
+ OIIO_FORCE_BUILD=true
+ OSL_FORCE_BUILD=true
+ OPENVDB_FORCE_BUILD=true
+ ALEMBIC_FORCE_BUILD=true
+ fi
+}
+
clean_Boost() {
_init_boost
_clean
+ _update_deps_boost
}
compile_Boost() {
@@ -1365,14 +1396,10 @@ compile_Boost() {
if [ ! -d $_inst ]; then
INFO "Building Boost-$BOOST_VERSION"
+ _is_building=true
# Rebuild dependencies as well!
- OIIO_FORCE_BUILD=true
- OIIO_FORCE_REBUILD=true
- OSL_FORCE_BUILD=true
- OSL_FORCE_REBUILD=true
- OPENVDB_FORCE_BUILD=true
- OPENVDB_FORCE_REBUILD=true
+ _update_deps_boost
prepare_opt
@@ -1402,6 +1429,7 @@ compile_Boost() {
cd $CWD
INFO "Done compiling Boost-$BOOST_VERSION!"
+ _is_building=false
else
INFO "Own Boost-$BOOST_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-boost option."
@@ -1425,9 +1453,14 @@ _init_ocio() {
_inst_shortcut=$INST/ocio
}
+_update_deps_ocio() {
+ :
+}
+
clean_OCIO() {
_init_ocio
_clean
+ _update_deps_ocio
}
compile_OCIO() {
@@ -1448,6 +1481,10 @@ compile_OCIO() {
if [ ! -d $_inst ]; then
INFO "Building OpenColorIO-$OCIO_VERSION"
+ _is_building=true
+
+ # Rebuild dependencies as well!
+ _update_deps_ocio
prepare_opt
@@ -1520,6 +1557,7 @@ compile_OCIO() {
cd $CWD
INFO "Done compiling OpenColorIO-$OCIO_VERSION!"
+ _is_building=false
else
INFO "Own OpenColorIO-$OCIO_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-ocio option."
@@ -1529,112 +1567,28 @@ compile_OCIO() {
}
# ----------------------------------------------------------------------------
-# Build ILMBase
-
-_init_ilmbase() {
- _src=$SRC/ILMBase-$ILMBASE_VERSION
- _git=false
- _inst=$TMP/ilmbase-$ILMBASE_VERSION
- _inst_shortcut=$TMP/ilmbase
-}
-
-clean_ILMBASE() {
- _init_ilmbase
- _clean
-}
-
-compile_ILMBASE() {
- if [ "$NO_BUILD" = true ]; then
- WARNING "--no-build enabled, ILMBase will not be compiled!"
- return
- fi
-
- # To be changed each time we make edits that would modify the compiled result!
- ilmbase_magic=10
- _init_ilmbase
-
- # Clean install if needed!
- magic_compile_check ilmbase-$ILMBASE_VERSION $ilmbase_magic
- if [ $? -eq 1 -o "$OPENEXR_FORCE_REBUILD" = true ]; then
- clean_ILMBASE
- rm -rf $_openexr_inst
- fi
-
- if [ ! -d $_openexr_inst ]; then
- INFO "Building ILMBase-$ILMBASE_VERSION"
-
- # Rebuild dependencies as well!
- OPENEXR_FORCE_BUILD=true
- OPENEXR_FORCE_REBUILD=true
-
- prepare_opt
-
- if [ ! -d $_src ]; then
- INFO "Downloading ILMBase-$ILMBASE_VERSION"
- mkdir -p $SRC
- download ILMBASE_SOURCE[@] $_src.tar.gz
-
- INFO "Unpacking ILMBase-$ILMBASE_VERSION"
- tar -C $SRC --transform "s,(.*/?)ilmbase-[^/]*(.*),\1ILMBase-$ILMBASE_VERSION\2,x" -xf $_src.tar.gz
-
- fi
-
- cd $_src
- # Always refresh the whole build!
- if [ -d build ]; then
- rm -rf build
- fi
- mkdir build
- cd build
-
- cmake_d="-D CMAKE_BUILD_TYPE=Release"
- cmake_d="$cmake_d -D CMAKE_PREFIX_PATH=$_inst"
- cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
- cmake_d="$cmake_d -D BUILD_SHARED_LIBS=ON"
- cmake_d="$cmake_d -D NAMESPACE_VERSIONING=OFF" # VERY IMPORTANT!!!
-
- if file /bin/cp | grep -q '32-bit'; then
- cflags="-fPIC -m32 -march=i686"
- else
- cflags="-fPIC"
- fi
-
- cmake $cmake_d -D CMAKE_CXX_FLAGS="$cflags" -D CMAKE_EXE_LINKER_FLAGS="-lgcc_s -lgcc" ..
-
- make -j$THREADS && make install
-
- make clean
-
- if [ -d $_inst ]; then
- _create_inst_shortcut
- else
- ERROR "ILMBase-$ILMBASE_VERSION failed to compile, exiting"
- exit 1
- fi
- cd $CWD
- INFO "Done compiling ILMBase-$ILMBASE_VERSION!"
- else
- INFO "Own ILMBase-$ILMBASE_VERSION is up to date, nothing to do!"
- INFO "If you want to force rebuild of this lib (and openexr), use the --force-openexr option."
- fi
-
- magic_compile_set ilmbase-$ILMBASE_VERSION $ilmbase_magic
-}
-
-# ----------------------------------------------------------------------------
-# Build OpenEXR
+# Build OpenEXR (and ILMBase).
_init_openexr() {
_src=$SRC/OpenEXR-$OPENEXR_VERSION
- _git=true
+ _git=false
_inst=$_openexr_inst
_inst_shortcut=$INST/openexr
}
+_update_deps_openexr() {
+ OIIO_FORCE_REBUILD=true
+ ALEMBIC_FORCE_REBUILD=true
+ if [ "$_is_building" = true ]; then
+ OIIO_FORCE_BUILD=true
+ ALEMBIC_FORCE_BUILD=true
+ fi
+}
+
clean_OPENEXR() {
- clean_ILMBASE
_init_openexr
_clean
+ _update_deps_openexr
}
compile_OPENEXR() {
@@ -1644,7 +1598,7 @@ compile_OPENEXR() {
fi
# To be changed each time we make edits that would modify the compiled result!
- openexr_magic=14
+ openexr_magic=15
# Clean install if needed!
magic_compile_check openexr-$OPENEXR_VERSION $openexr_magic
@@ -1653,17 +1607,15 @@ compile_OPENEXR() {
fi
_openexr_inst=$INST/openexr-$OPENEXR_VERSION
- compile_ILMBASE
PRINT ""
- _ilmbase_inst=$_inst_shortcut
_init_openexr
if [ ! -d $_inst ]; then
- INFO "Building OpenEXR-$OPENEXR_VERSION"
+ INFO "Building ILMBase-$OPENEXR_VERSION and OpenEXR-$OPENEXR_VERSION"
+ _is_building=true
# Rebuild dependencies as well!
- OIIO_FORCE_BUILD=true
- OIIO_FORCE_REBUILD=true
+ _update_deps_openexr
prepare_opt
@@ -1688,9 +1640,9 @@ compile_OPENEXR() {
git pull origin master
git checkout $OPENEXR_SOURCE_REPO_UID
git reset --hard
- oiio_src_path="../OpenEXR"
+ openexr_src_path="../OpenEXR"
else
- oiio_src_path=".."
+ openexr_src_path=".."
fi
# Always refresh the whole build!
@@ -1700,12 +1652,13 @@ compile_OPENEXR() {
mkdir build
cd build
- cmake_d="-D CMAKE_BUILD_TYPE=Release"
- cmake_d="$cmake_d -D CMAKE_PREFIX_PATH=$_inst"
- cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
- cmake_d="$cmake_d -D ILMBASE_PACKAGE_PREFIX=$_ilmbase_inst"
+ cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_openexr_inst"
+ cmake_d="$cmake_d -D CMAKE_INSTALL_DOCDIR=/dev/null" # Hack, there is no option to disable that currently...
cmake_d="$cmake_d -D BUILD_SHARED_LIBS=ON"
- cmake_d="$cmake_d -D NAMESPACE_VERSIONING=OFF" # VERY IMPORTANT!!!
+ cmake_d="$cmake_d -D BUILD_TESTING=OFF"
+ cmake_d="$cmake_d -D OPENEXR_BUILD_UTILS=OFF"
+ cmake_d="$cmake_d -D PYILMBASE_ENABLE=OFF"
+ cmake_d="$cmake_d -D OPENEXR_VIEWERS_ENABLE=OFF"
if file /bin/cp | grep -q '32-bit'; then
cflags="-fPIC -m32 -march=i686"
@@ -1713,7 +1666,7 @@ compile_OPENEXR() {
cflags="-fPIC"
fi
- cmake $cmake_d -D CMAKE_CXX_FLAGS="$cflags" -D CMAKE_EXE_LINKER_FLAGS="-lgcc_s -lgcc" $oiio_src_path
+ cmake $cmake_d -D CMAKE_BUILD_TYPE=Release -D CMAKE_CXX_FLAGS="$cflags" -D CMAKE_EXE_LINKER_FLAGS="-lgcc_s -lgcc" $openexr_src_path
make -j$THREADS && make install
@@ -1721,8 +1674,6 @@ compile_OPENEXR() {
if [ -d $_inst ]; then
_create_inst_shortcut
- # Copy ilmbase files here (blender expects same dir for ilmbase and openexr :/).
- cp -an $_ilmbase_inst/* $_inst_shortcut
else
ERROR "OpenEXR-$OPENEXR_VERSION failed to compile, exiting"
exit 1
@@ -1732,6 +1683,7 @@ compile_OPENEXR() {
cd $CWD
INFO "Done compiling OpenEXR-$OPENEXR_VERSION!"
+ _is_building=false
else
INFO "Own OpenEXR-$OPENEXR_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-openexr option."
@@ -1753,9 +1705,17 @@ _init_oiio() {
_inst_shortcut=$INST/oiio
}
+_update_deps_oiio() {
+ OSL_FORCE_REBUILD=true
+ if [ "$_is_building" = true ]; then
+ OSL_FORCE_BUILD=true
+ fi
+}
+
clean_OIIO() {
_init_oiio
_clean
+ _update_deps_oiio
}
compile_OIIO() {
@@ -1776,10 +1736,10 @@ compile_OIIO() {
if [ ! -d $_inst ]; then
INFO "Building OpenImageIO-$OIIO_VERSION"
+ _is_building=true
# Rebuild dependencies as well!
- OSL_FORCE_BUILD=true
- OSL_FORCE_REBUILD=true
+ _update_deps_oiio
prepare_opt
@@ -1877,6 +1837,7 @@ compile_OIIO() {
cd $CWD
INFO "Done compiling OpenImageIO-$OIIO_VERSION!"
+ _is_building=false
else
INFO "Own OpenImageIO-$OIIO_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-oiio option."
@@ -1897,9 +1858,17 @@ _init_llvm() {
_inst_shortcut=$INST/llvm
}
+_update_deps_llvm() {
+ OSL_FORCE_REBUILD=true
+ if [ "$_is_building" = true ]; then
+ OSL_FORCE_BUILD=true
+ fi
+}
+
clean_LLVM() {
_init_llvm
_clean
+ _update_deps_llvm
}
compile_LLVM() {
@@ -1920,10 +1889,10 @@ compile_LLVM() {
if [ ! -d $_inst ]; then
INFO "Building LLVM-$LLVM_VERSION (CLANG included!)"
+ _is_building=true
# Rebuild dependencies as well!
- OSL_FORCE_BUILD=true
- OSL_FORCE_REBUILD=true
+ _update_deps_llvm
prepare_opt
@@ -1982,6 +1951,7 @@ compile_LLVM() {
cd $CWD
INFO "Done compiling LLVM-$LLVM_VERSION (CLANG included)!"
+ _is_building=false
else
INFO "Own LLVM-$LLVM_VERSION (CLANG included) is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-llvm option."
@@ -1998,9 +1968,14 @@ _init_osl() {
_inst_shortcut=$INST/osl
}
+_update_deps_osl() {
+ :
+}
+
clean_OSL() {
_init_osl
_clean
+ _update_deps_osl
}
compile_OSL() {
@@ -2022,6 +1997,10 @@ compile_OSL() {
if [ ! -d $_inst ]; then
INFO "Building OpenShadingLanguage-$OSL_VERSION"
+ _is_building=true
+
+ # Rebuild dependencies as well!
+ _update_deps_osl
prepare_opt
@@ -2066,15 +2045,16 @@ compile_OSL() {
cmake_d="$cmake_d -D USE_SIMD=sse2"
cmake_d="$cmake_d -D USE_LLVM_BITCODE=OFF"
cmake_d="$cmake_d -D USE_PARTIO=OFF"
+ cmake_d="$cmake_d -D OSL_BUILD_MATERIALX=OFF"
+ cmake_d="$cmake_d -D USE_QT=OFF"
#~ cmake_d="$cmake_d -D ILMBASE_VERSION=$ILMBASE_VERSION"
if [ "$_with_built_openexr" = true ]; then
INFO "ILMBASE_HOME=$INST/openexr"
- cmake_d="$cmake_d -D ILMBASE_HOME=$INST/openexr"
+ cmake_d="$cmake_d -D OPENEXR_ROOT_DIR=$INST/openexr"
+ cmake_d="$cmake_d -D ILMBASE_ROOT_DIR=$INST/openexr"
# XXX Temp workaround... sigh, ILMBase really messed the things up by defining their custom names ON by default :(
- cmake_d="$cmake_d -D ILMBASE_CUSTOM=ON"
- cmake_d="$cmake_d -D ILMBASE_CUSTOM_LIBRARIES='Half;Iex;Imath;IlmThread'"
fi
if [ -d $INST/boost ]; then
@@ -2112,6 +2092,7 @@ compile_OSL() {
cd $CWD
INFO "Done compiling OpenShadingLanguage-$OSL_VERSION!"
+ _is_building=false
else
INFO "Own OpenShadingLanguage-$OSL_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-osl option."
@@ -2130,9 +2111,14 @@ _init_osd() {
_inst_shortcut=$INST/osd
}
+_update_deps_osd() {
+ :
+}
+
clean_OSD() {
_init_osd
_clean
+ _update_deps_osd
}
compile_OSD() {
@@ -2153,6 +2139,10 @@ compile_OSD() {
if [ ! -d $_inst ]; then
INFO "Building OpenSubdiv-$OSD_VERSION"
+ _is_building=true
+
+ # Rebuild dependencies as well!
+ _update_deps_osd
prepare_opt
@@ -2211,6 +2201,7 @@ compile_OSD() {
cd $CWD
INFO "Done compiling OpenSubdiv-$OSD_VERSION!"
+ _is_building=false
else
INFO "Own OpenSubdiv-$OSD_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-osd option."
@@ -2229,9 +2220,17 @@ _init_blosc() {
_inst_shortcut=$INST/blosc
}
+_update_deps_blosc() {
+ OPENVDB_FORCE_REBUILD=true
+ if [ "$_is_building" = true ]; then
+ OPENVDB_FORCE_BUILD=true
+ fi
+}
+
clean_BLOSC() {
_init_blosc
_clean
+ _update_deps_blosc
}
compile_BLOSC() {
@@ -2253,10 +2252,10 @@ compile_BLOSC() {
if [ ! -d $_inst ]; then
INFO "Building Blosc-$OPENVDB_BLOSC_VERSION"
+ _is_building=true
# Rebuild dependencies as well!
- OPENVDB_FORCE_BUILD=true
- OPENVDB_FORCE_REBUILD=true
+ _update_deps_blosc
prepare_opt
@@ -2298,6 +2297,7 @@ compile_BLOSC() {
fi
cd $CWD
INFO "Done compiling Blosc-$OPENVDB_BLOSC_VERSION!"
+ _is_building=false
else
INFO "Own Blosc-$OPENVDB_BLOSC_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib (and openvdb), use the --force-openvdb option."
@@ -2318,9 +2318,14 @@ _init_openvdb() {
_inst_shortcut=$INST/openvdb
}
+_update_deps_openvdb() {
+ :
+}
+
clean_OPENVDB() {
_init_openvdb
_clean
+ _update_deps_openvdb
}
compile_OPENVDB() {
@@ -2344,6 +2349,10 @@ compile_OPENVDB() {
if [ ! -d $_inst ]; then
INFO "Building OpenVDB-$OPENVDB_VERSION"
+ _is_building=true
+
+ # Rebuild dependencies as well!
+ _update_deps_openvdb
prepare_opt
@@ -2403,6 +2412,7 @@ compile_OPENVDB() {
cd $CWD
INFO "Done compiling OpenVDB-$OPENVDB_VERSION!"
+ _is_building=false
else
INFO "Own OpenVDB-$OPENVDB_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-openvdb option."
@@ -2421,9 +2431,14 @@ _init_alembic() {
_inst_shortcut=$INST/alembic
}
+_update_deps_alembic() {
+ :
+}
+
clean_ALEMBIC() {
_init_alembic
_clean
+ _update_deps_alembic
}
compile_ALEMBIC() {
@@ -2444,6 +2459,10 @@ compile_ALEMBIC() {
if [ ! -d $_inst ]; then
INFO "Building Alembic-$ALEMBIC_VERSION"
+ _is_building=true
+
+ # Rebuild dependencies as well!
+ _update_deps_alembic
prepare_opt
@@ -2498,6 +2517,7 @@ compile_ALEMBIC() {
cd $CWD
INFO "Done compiling Alembic-$ALEMBIC_VERSION!"
+ _is_building=false
else
INFO "Own Alembic-$ALEMBIC_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-alembic option."
@@ -2514,9 +2534,14 @@ _init_usd() {
_inst_shortcut=$INST/usd
}
+_update_deps_usd() {
+ :
+}
+
clean_USD() {
_init_usd
_clean
+ _update_deps_usd
}
compile_USD() {
@@ -2537,6 +2562,10 @@ compile_USD() {
if [ ! -d $_inst ]; then
INFO "Building USD-$USD_VERSION"
+ _is_building=true
+
+ # Rebuild dependencies as well!
+ _update_deps_usd
prepare_opt
@@ -2580,6 +2609,7 @@ compile_USD() {
cd $CWD
INFO "Done compiling USD-$USD_VERSION!"
+ _is_building=true
else
INFO "Own USD-$USD_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-usd option."
@@ -2597,9 +2627,14 @@ _init_opencollada() {
_inst_shortcut=$INST/opencollada
}
+_update_deps_collada() {
+ :
+}
+
clean_OpenCOLLADA() {
_init_opencollada
_clean
+ _update_deps_collada
}
compile_OpenCOLLADA() {
@@ -2620,6 +2655,10 @@ compile_OpenCOLLADA() {
if [ ! -d $_inst ]; then
INFO "Building OpenCOLLADA-$OPENCOLLADA_VERSION"
+ _is_building=true
+
+ # Rebuild dependencies as well!
+ _update_deps_collada
prepare_opt
@@ -2675,6 +2714,7 @@ compile_OpenCOLLADA() {
cd $CWD
INFO "Done compiling OpenCOLLADA-$OPENCOLLADA_VERSION!"
+ _is_building=false
else
INFO "Own OpenCOLLADA-$OPENCOLLADA_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-opencollada option."
@@ -2691,9 +2731,14 @@ _init_embree() {
_inst_shortcut=$INST/embree
}
+_update_deps_embree() {
+ :
+}
+
clean_Embree() {
_init_embree
_clean
+ _update_deps_embree
}
compile_Embree() {
@@ -2714,6 +2759,10 @@ compile_Embree() {
if [ ! -d $_inst ]; then
INFO "Building Embree-$EMBREE_VERSION"
+ _is_building=true
+
+ # Rebuild dependencies as well!
+ _update_deps_embree
prepare_opt
@@ -2772,6 +2821,7 @@ compile_Embree() {
cd $CWD
INFO "Done compiling Embree-$EMBREE_VERSION!"
+ _is_building=false
else
INFO "Own Embree-$EMBREE_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-embree option."
@@ -2788,9 +2838,14 @@ _init_oidn() {
_inst_shortcut=$INST/oidn
}
+_update_deps_oidn() {
+ :
+}
+
clean_oidn() {
_init_oidn
_clean
+ _update_deps_oidn
}
compile_OIDN() {
@@ -2811,6 +2866,10 @@ compile_OIDN() {
if [ ! -d $_inst ]; then
INFO "Building OpenImageDenoise-$OIDN_VERSION"
+ _is_building=true
+
+ # Rebuild dependencies as well!
+ _update_deps_oidn
prepare_opt
@@ -2864,6 +2923,7 @@ compile_OIDN() {
cd $CWD
INFO "Done compiling OpenImageDenoise-$OIDN_VERSION!"
+ _is_building=false
else
INFO "Own OpenImageDenoise-$OIDN_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-oidn option."
@@ -2881,9 +2941,14 @@ _init_ffmpeg() {
_inst_shortcut=$INST/ffmpeg
}
+_update_deps_ffmpeg() {
+ :
+}
+
clean_FFmpeg() {
_init_ffmpeg
_clean
+ _update_deps_ffmpeg
}
compile_FFmpeg() {
@@ -2904,6 +2969,10 @@ compile_FFmpeg() {
if [ ! -d $_inst ]; then
INFO "Building ffmpeg-$FFMPEG_VERSION"
+ _is_building=true
+
+ # Rebuild dependencies as well!
+ _update_deps_ffmpeg
prepare_opt
@@ -2982,6 +3051,7 @@ compile_FFmpeg() {
cd $CWD
INFO "Done compiling ffmpeg-$FFMPEG_VERSION!"
+ _is_building=false
else
INFO "Own ffmpeg-$FFMPEG_VERSION is up to date, nothing to do!"
INFO "If you want to force rebuild of this lib, use the --force-ffmpeg option."
diff --git a/build_files/build_environment/patches/.gitattributes b/build_files/build_environment/patches/.gitattributes
new file mode 100644
index 00000000000..beb2d800f5b
--- /dev/null
+++ b/build_files/build_environment/patches/.gitattributes
@@ -0,0 +1,2 @@
+# Files contains mixed line endings, patch needs to preserve them to apply.
+opencollada.diff binary
diff --git a/build_files/build_environment/patches/opencollada.diff b/build_files/build_environment/patches/opencollada.diff
index e7f563acaa1..cd4cc2c1652 100644
--- a/build_files/build_environment/patches/opencollada.diff
+++ b/build_files/build_environment/patches/opencollada.diff
@@ -3,19 +3,32 @@ index 95abbe2..4f14f30 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -254,11 +254,11 @@ if(USE_STATIC_MSVC_RUNTIME)
- endif()
-
- #adding PCRE
--find_package(PCRE)
-+#find_package(PCRE)
- if (PCRE_FOUND)
- message(STATUS "SUCCESSFUL: PCRE found")
- else () # if pcre not found building its local copy from ./Externals
-- if (WIN32 OR APPLE)
-+ if (1)
- message("WARNING: Native PCRE not found, taking PCRE from ./Externals")
- add_definitions(-DPCRE_STATIC)
- add_subdirectory(${EXTERNAL_LIBRARIES}/pcre)
+ endif()
+
+ #adding PCRE
+-find_package(PCRE)
++#find_package(PCRE)
+ if (PCRE_FOUND)
+ message(STATUS "SUCCESSFUL: PCRE found")
+ else () # if pcre not found building its local copy from ./Externals
+- if (WIN32 OR APPLE)
++ if (1)
+ message("WARNING: Native PCRE not found, taking PCRE from ./Externals")
+ add_definitions(-DPCRE_STATIC)
+ add_subdirectory(${EXTERNAL_LIBRARIES}/pcre)
+diff --git a/DAEValidator/CMakeLists.txt b/DAEValidator/CMakeLists.txt
+index 03ad540..f7d05cf 100644
+--- a/DAEValidator/CMakeLists.txt
++++ b/DAEValidator/CMakeLists.txt
+@@ -98,7 +98,7 @@ if (WIN32)
+ # C4710: 'function' : function not inlined
+ # C4711: function 'function' selected for inline expansion
+ # C4820: 'bytes' bytes padding added after construct 'member_name'
+- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /Wall /WX /wd4505 /wd4514 /wd4592 /wd4710 /wd4711 /wd4820")
++ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /Wall /wd4505 /wd4514 /wd4592 /wd4710 /wd4711 /wd4820")
+ else ()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Werror")
+ endif ()
diff --git a/DAEValidator/library/include/no_warning_begin b/DAEValidator/library/include/no_warning_begin
index 7a69c32..defb315 100644
--- a/DAEValidator/library/include/no_warning_begin
@@ -30,34 +43,8 @@ index 7a69c32..defb315 100644
# if defined(_MSC_VER) && defined(_DEBUG)
# pragma warning(disable:4548)
# endif
-diff --git a/GeneratedSaxParser/src/GeneratedSaxParserUtils.cpp b/GeneratedSaxParser/src/GeneratedSaxParserUtils.cpp
-index 1f9a3ee..d151e9a 100644
---- a/GeneratedSaxParser/src/GeneratedSaxParserUtils.cpp
-+++ b/GeneratedSaxParser/src/GeneratedSaxParserUtils.cpp
-@@ -1553,7 +1553,7 @@ namespace GeneratedSaxParser
- #if defined(COLLADABU_OS_WIN) && !defined(__MINGW32__)
- return _isnan( value ) ? true : false;
- #else
--#ifdef isnan
-+#if defined(isnan) || defined(__APPLE__)
- return isnan( value );
- #else
- return std::isnan(value);
-diff --git a/DAEValidator/CMakeLists.txt b/DAEValidator/CMakeLists.txt
-index 03ad540f..f7d05cfb 100644
---- a/DAEValidator/CMakeLists.txt
-+++ b/DAEValidator/CMakeLists.txt
-@@ -98,7 +98,7 @@ if (WIN32)
- # C4710: 'function' : function not inlined
- # C4711: function 'function' selected for inline expansion
- # C4820: 'bytes' bytes padding added after construct 'member_name'
-- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /Wall /WX /wd4505 /wd4514 /wd4592 /wd4710 /wd4711 /wd4820")
-+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /Wall /wd4505 /wd4514 /wd4592 /wd4710 /wd4711 /wd4820")
- else ()
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Werror")
- endif ()
diff --git a/DAEValidator/library/src/ArgumentParser.cpp b/DAEValidator/library/src/ArgumentParser.cpp
-index 897e4dcf..98a69ff1 100644
+index 897e4dc..98a69ff 100644
--- a/DAEValidator/library/src/ArgumentParser.cpp
+++ b/DAEValidator/library/src/ArgumentParser.cpp
@@ -6,10 +6,10 @@
@@ -74,14 +61,28 @@ index 897e4dcf..98a69ff1 100644
#endif
namespace opencollada
-diff -Naur orig/Externals/LibXML/CMakeLists.txt external_opencollada/Externals/LibXML/CMakeLists.txt
---- orig/Externals/LibXML/CMakeLists.txt 2018-11-26 15:43:10 -0700
-+++ external_opencollada/Externals/LibXML/CMakeLists.txt 2020-01-21 14:15:04 -0700
-@@ -9,6 +9,7 @@
- -DLIBXML_SCHEMAS_ENABLED
- -DLIBXML_XPATH_ENABLED
- -DLIBXML_TREE_ENABLED
-+ -DLIBXML_STATIC
- )
-
- if(USE_STATIC_MSVC_RUNTIME)
+diff --git a/Externals/LibXML/CMakeLists.txt b/Externals/LibXML/CMakeLists.txt
+index 40081e7..e1d1bfa 100644
+--- a/Externals/LibXML/CMakeLists.txt
++++ b/Externals/LibXML/CMakeLists.txt
+@@ -9,6 +9,7 @@ add_definitions(
+ -DLIBXML_SCHEMAS_ENABLED
+ -DLIBXML_XPATH_ENABLED
+ -DLIBXML_TREE_ENABLED
++ -DLIBXML_STATIC
+ )
+
+ if(USE_STATIC_MSVC_RUNTIME)
+diff --git a/GeneratedSaxParser/src/GeneratedSaxParserUtils.cpp b/GeneratedSaxParser/src/GeneratedSaxParserUtils.cpp
+index 1f9a3ee..d151e9a 100644
+--- a/GeneratedSaxParser/src/GeneratedSaxParserUtils.cpp
++++ b/GeneratedSaxParser/src/GeneratedSaxParserUtils.cpp
+@@ -1553,7 +1553,7 @@ namespace GeneratedSaxParser
+ #if defined(COLLADABU_OS_WIN) && !defined(__MINGW32__)
+ return _isnan( value ) ? true : false;
+ #else
+-#ifdef isnan
++#if defined(isnan) || defined(__APPLE__)
+ return isnan( value );
+ #else
+ return std::isnan(value);
diff --git a/build_files/buildbot/codesign/archive_with_indicator.py b/build_files/buildbot/codesign/archive_with_indicator.py
index d1af207df83..085026fcf98 100644
--- a/build_files/buildbot/codesign/archive_with_indicator.py
+++ b/build_files/buildbot/codesign/archive_with_indicator.py
@@ -70,8 +70,12 @@ class ArchiveWithIndicator:
self.archive_filepath = self.base_dir / archive_name
self.ready_indicator_filepath = self.base_dir / ready_indicator_name
- def is_ready(self) -> bool:
- """Check whether the archive is ready for access."""
+ def is_ready_unsafe(self) -> bool:
+ """
+ Check whether the archive is ready for access.
+
+ No guarding about possible network failres is done here.
+ """
if not self.ready_indicator_filepath.exists():
return False
@@ -105,6 +109,26 @@ class ArchiveWithIndicator:
return True
+ def is_ready(self) -> bool:
+ """
+ Check whether the archive is ready for access.
+
+ Will tolerate possible network failures: if there is a network failure
+ or if there is still no proper permission on a file False is returned.
+ """
+
+ # There are some intermitten problem happening at a random which is
+ # translates to "OSError : [WinError 59] An unexpected network error occurred".
+ # Some reports suggests it might be due to lack of permissions to the file,
+ # which might be applicable in our case since it's possible that file is
+ # initially created with non-accessible permissions and gets chmod-ed
+ # after initial creation.
+ try:
+ return self.is_ready_unsafe()
+ except OSError as e:
+ print(f'Exception checking archive: {e}')
+ return False
+
def tag_ready(self) -> None:
"""
Tag the archive as ready by creating the corresponding indication file.
diff --git a/build_files/buildbot/codesign/base_code_signer.py b/build_files/buildbot/codesign/base_code_signer.py
index 0505905c6f4..2f86531a4d0 100644
--- a/build_files/buildbot/codesign/base_code_signer.py
+++ b/build_files/buildbot/codesign/base_code_signer.py
@@ -326,6 +326,9 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
self.copy_signed_files_to_directory(
unpacked_signed_files_dir, destination_dir)
+ logger_builder.info('Removing archive with signed files...')
+ self.signed_archive_info.clean()
+
############################################################################
# Signing server side helpers.
diff --git a/build_files/windows/detect_msvc_vswhere.cmd b/build_files/windows/detect_msvc_vswhere.cmd
index a538e506b39..609375cee89 100644
--- a/build_files/windows/detect_msvc_vswhere.cmd
+++ b/build_files/windows/detect_msvc_vswhere.cmd
@@ -34,6 +34,9 @@ if "%VS_InstallDir%"=="" (
set VCVARS=%VS_InstallDir%\VC\Auxiliary\Build\vcvarsall.bat
if exist "%VCVARS%" (
+ if NOT "%verbose%" == "" (
+ echo calling "%VCVARS%" %BUILD_ARCH%
+ )
call "%VCVARS%" %BUILD_ARCH%
) else (
if NOT "%verbose%" == "" (
@@ -43,6 +46,9 @@ if exist "%VCVARS%" (
)
rem try msbuild
+if NOT "%verbose%" == "" (
+ echo Testing for MSBuild
+)
msbuild /version > NUL
if errorlevel 1 (
if NOT "%verbose%" == "" (
@@ -56,6 +62,9 @@ if NOT "%verbose%" == "" (
)
REM try the c++ compiler
+if NOT "%verbose%" == "" (
+ echo Testing for the C/C++ Compiler
+)
cl 2> NUL 1>&2
if errorlevel 1 (
if NOT "%verbose%" == "" (
diff --git a/extern/audaspace/include/devices/IDevice.h b/extern/audaspace/include/devices/IDevice.h
index 92a85d900e2..b9414e7d187 100644
--- a/extern/audaspace/include/devices/IDevice.h
+++ b/extern/audaspace/include/devices/IDevice.h
@@ -37,10 +37,10 @@ class ISynchronizer;
/**
* @interface IDevice
* The IDevice interface represents an output device for sound sources.
- * Output devices may be several backends such as plattform independand like
- * SDL or OpenAL or plattform specific like ALSA, but they may also be
+ * Output devices may be several backends such as platform independand like
+ * SDL or OpenAL or platform specific like ALSA, but they may also be
* files, RAM buffers or other types of streams.
- * \warning Thread safety must be insured so that no reader is beeing called
+ * \warning Thread safety must be insured so that no reader is being called
* twice at the same time.
*/
class IDevice : public ILockable
diff --git a/extern/audaspace/include/devices/IDeviceFactory.h b/extern/audaspace/include/devices/IDeviceFactory.h
index 6a0f4537b13..7023cc058c5 100644
--- a/extern/audaspace/include/devices/IDeviceFactory.h
+++ b/extern/audaspace/include/devices/IDeviceFactory.h
@@ -35,6 +35,8 @@ AUD_NAMESPACE_BEGIN
class AUD_API IDeviceFactory
{
public:
+ virtual ~IDeviceFactory() {}
+
/**
* Opens an audio device for playback.
* \exception Exception Thrown if the audio device cannot be opened.
diff --git a/extern/audaspace/include/file/IFileInput.h b/extern/audaspace/include/file/IFileInput.h
index bb016a88602..aec929e7639 100644
--- a/extern/audaspace/include/file/IFileInput.h
+++ b/extern/audaspace/include/file/IFileInput.h
@@ -40,6 +40,8 @@ class Buffer;
class AUD_API IFileInput
{
public:
+ virtual ~IFileInput() {};
+
/**
* Creates a reader for a file to be read.
* \param filename Path to the file to be read.
diff --git a/extern/audaspace/src/fx/DynamicMusic.cpp b/extern/audaspace/src/fx/DynamicMusic.cpp
index c682108378f..b8f5c975b3f 100644
--- a/extern/audaspace/src/fx/DynamicMusic.cpp
+++ b/extern/audaspace/src/fx/DynamicMusic.cpp
@@ -171,7 +171,7 @@ bool DynamicMusic::pause()
bool DynamicMusic::seek(float position)
{
- bool result;
+ bool result = false;
if(m_currentHandle != nullptr)
{
diff --git a/extern/mantaflow/preprocessed/fileio/ioutil.cpp b/extern/mantaflow/preprocessed/fileio/ioutil.cpp
index 0bbbc7b6d11..e04633c5634 100644
--- a/extern/mantaflow/preprocessed/fileio/ioutil.cpp
+++ b/extern/mantaflow/preprocessed/fileio/ioutil.cpp
@@ -23,21 +23,36 @@ extern "C" {
# include <zlib.h>
}
+# if defined(WIN32) || defined(_WIN32)
+# include <windows.h>
+# include <string>
+# endif
+
+using namespace std;
+
namespace Manta {
-//! helper to handle non ascii filenames correctly, mainly problematic on windows
+# if defined(WIN32) || defined(_WIN32)
+static wstring stringToWstring(const char *str)
+{
+ const int length_wc = MultiByteToWideChar(CP_UTF8, 0, str, strlen(str), NULL, 0);
+ wstring strWide(length_wc, 0);
+ MultiByteToWideChar(CP_UTF8, 0, str, strlen(str), &strWide[0], length_wc);
+ return strWide;
+}
+# endif
+
void *safeGzopen(const char *filename, const char *mode)
{
gzFile gzfile;
-# if 0
- UTF16_ENCODE(filename);
- // gzopen_w() is supported since zlib v1.2.7
- gzfile = gzopen_w(filename_16, mode);
- UTF16_UN_ENCODE(filename);
+# if defined(WIN32) || defined(_WIN32)
+ wstring filenameWide = stringToWstring(filename);
+ gzfile = gzopen_w(filenameWide.c_str(), mode);
# else
gzfile = gzopen(filename, mode);
# endif
+
return gzfile;
}
#endif
diff --git a/extern/mantaflow/preprocessed/gitinfo.h b/extern/mantaflow/preprocessed/gitinfo.h
index 0e84563eae3..614bf2b91c4 100644
--- a/extern/mantaflow/preprocessed/gitinfo.h
+++ b/extern/mantaflow/preprocessed/gitinfo.h
@@ -1,3 +1,3 @@
-#define MANTA_GIT_VERSION "commit 7b9e0d841274c65dce911ec578bd0b4779971422"
+#define MANTA_GIT_VERSION "commit ce000bcbd7004e6549ac2f118755fcdc1f679bc3"
diff --git a/extern/mantaflow/preprocessed/grid.cpp b/extern/mantaflow/preprocessed/grid.cpp
index c21d56d8879..f10052349d5 100644
--- a/extern/mantaflow/preprocessed/grid.cpp
+++ b/extern/mantaflow/preprocessed/grid.cpp
@@ -1244,15 +1244,67 @@ void PbRegister_gridMaxDiffVec3()
}
}
+struct knCopyMacToVec3 : public KernelBase {
+ knCopyMacToVec3(MACGrid &source, Grid<Vec3> &target)
+ : KernelBase(&source, 0), source(source), target(target)
+ {
+ runMessage();
+ run();
+ }
+ inline void op(int i, int j, int k, MACGrid &source, Grid<Vec3> &target) const
+ {
+ target(i, j, k) = source(i, j, k);
+ }
+ inline MACGrid &getArg0()
+ {
+ return source;
+ }
+ typedef MACGrid type0;
+ inline Grid<Vec3> &getArg1()
+ {
+ return target;
+ }
+ typedef Grid<Vec3> type1;
+ void runMessage()
+ {
+ debMsg("Executing kernel knCopyMacToVec3 ", 3);
+ debMsg("Kernel range"
+ << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
+ 4);
+ };
+ void operator()(const tbb::blocked_range<IndexInt> &__r) const
+ {
+ const int _maxX = maxX;
+ const int _maxY = maxY;
+ if (maxZ > 1) {
+ for (int k = __r.begin(); k != (int)__r.end(); k++)
+ for (int j = 0; j < _maxY; j++)
+ for (int i = 0; i < _maxX; i++)
+ op(i, j, k, source, target);
+ }
+ else {
+ const int k = 0;
+ for (int j = __r.begin(); j != (int)__r.end(); j++)
+ for (int i = 0; i < _maxX; i++)
+ op(i, j, k, source, target);
+ }
+ }
+ void run()
+ {
+ if (maxZ > 1)
+ tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this);
+ else
+ tbb::parallel_for(tbb::blocked_range<IndexInt>(0, maxY), *this);
+ }
+ MACGrid &source;
+ Grid<Vec3> &target;
+};
// simple helper functions to copy (convert) mac to vec3 , and levelset to real grids
// (are assumed to be the same for running the test cases - in general they're not!)
void copyMacToVec3(MACGrid &source, Grid<Vec3> &target)
{
- FOR_IJK(target)
- {
- target(i, j, k) = source(i, j, k);
- }
+ knCopyMacToVec3(source, target);
}
static PyObject *_W_3(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
@@ -1323,10 +1375,14 @@ void PbRegister_convertMacToVec3()
}
}
-//! vec3->mac grid conversion , but with full resampling
-void resampleVec3ToMac(Grid<Vec3> &source, MACGrid &target)
-{
- FOR_IJK_BND(target, 1)
+struct knResampleVec3ToMac : public KernelBase {
+ knResampleVec3ToMac(Grid<Vec3> &source, MACGrid &target)
+ : KernelBase(&source, 1), source(source), target(target)
+ {
+ runMessage();
+ run();
+ }
+ inline void op(int i, int j, int k, Grid<Vec3> &source, MACGrid &target) const
{
target(i, j, k)[0] = 0.5 * (source(i - 1, j, k)[0] + source(i, j, k))[0];
target(i, j, k)[1] = 0.5 * (source(i, j - 1, k)[1] + source(i, j, k))[1];
@@ -1334,6 +1390,55 @@ void resampleVec3ToMac(Grid<Vec3> &source, MACGrid &target)
target(i, j, k)[2] = 0.5 * (source(i, j, k - 1)[2] + source(i, j, k))[2];
}
}
+ inline Grid<Vec3> &getArg0()
+ {
+ return source;
+ }
+ typedef Grid<Vec3> type0;
+ inline MACGrid &getArg1()
+ {
+ return target;
+ }
+ typedef MACGrid type1;
+ void runMessage()
+ {
+ debMsg("Executing kernel knResampleVec3ToMac ", 3);
+ debMsg("Kernel range"
+ << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
+ 4);
+ };
+ void operator()(const tbb::blocked_range<IndexInt> &__r) const
+ {
+ const int _maxX = maxX;
+ const int _maxY = maxY;
+ if (maxZ > 1) {
+ for (int k = __r.begin(); k != (int)__r.end(); k++)
+ for (int j = 1; j < _maxY; j++)
+ for (int i = 1; i < _maxX; i++)
+ op(i, j, k, source, target);
+ }
+ else {
+ const int k = 0;
+ for (int j = __r.begin(); j != (int)__r.end(); j++)
+ for (int i = 1; i < _maxX; i++)
+ op(i, j, k, source, target);
+ }
+ }
+ void run()
+ {
+ if (maxZ > 1)
+ tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this);
+ else
+ tbb::parallel_for(tbb::blocked_range<IndexInt>(1, maxY), *this);
+ }
+ Grid<Vec3> &source;
+ MACGrid &target;
+};
+//! vec3->mac grid conversion , but with full resampling
+
+void resampleVec3ToMac(Grid<Vec3> &source, MACGrid &target)
+{
+ knResampleVec3ToMac(source, target);
}
static PyObject *_W_5(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
@@ -1367,13 +1472,66 @@ void PbRegister_resampleVec3ToMac()
}
}
-//! mac->vec3 grid conversion , with full resampling
-void resampleMacToVec3(MACGrid &source, Grid<Vec3> &target)
-{
- FOR_IJK_BND(target, 1)
+struct knResampleMacToVec3 : public KernelBase {
+ knResampleMacToVec3(MACGrid &source, Grid<Vec3> &target)
+ : KernelBase(&source, 1), source(source), target(target)
+ {
+ runMessage();
+ run();
+ }
+ inline void op(int i, int j, int k, MACGrid &source, Grid<Vec3> &target) const
{
target(i, j, k) = source.getCentered(i, j, k);
}
+ inline MACGrid &getArg0()
+ {
+ return source;
+ }
+ typedef MACGrid type0;
+ inline Grid<Vec3> &getArg1()
+ {
+ return target;
+ }
+ typedef Grid<Vec3> type1;
+ void runMessage()
+ {
+ debMsg("Executing kernel knResampleMacToVec3 ", 3);
+ debMsg("Kernel range"
+ << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
+ 4);
+ };
+ void operator()(const tbb::blocked_range<IndexInt> &__r) const
+ {
+ const int _maxX = maxX;
+ const int _maxY = maxY;
+ if (maxZ > 1) {
+ for (int k = __r.begin(); k != (int)__r.end(); k++)
+ for (int j = 1; j < _maxY; j++)
+ for (int i = 1; i < _maxX; i++)
+ op(i, j, k, source, target);
+ }
+ else {
+ const int k = 0;
+ for (int j = __r.begin(); j != (int)__r.end(); j++)
+ for (int i = 1; i < _maxX; i++)
+ op(i, j, k, source, target);
+ }
+ }
+ void run()
+ {
+ if (maxZ > 1)
+ tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this);
+ else
+ tbb::parallel_for(tbb::blocked_range<IndexInt>(1, maxY), *this);
+ }
+ MACGrid &source;
+ Grid<Vec3> &target;
+};
+//! mac->vec3 grid conversion , with full resampling
+
+void resampleMacToVec3(MACGrid &source, Grid<Vec3> &target)
+{
+ knResampleMacToVec3(source, target);
}
static PyObject *_W_6(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
@@ -1407,12 +1565,65 @@ void PbRegister_resampleMacToVec3()
}
}
-void copyLevelsetToReal(LevelsetGrid &source, Grid<Real> &target)
-{
- FOR_IJK(target)
+struct knCopyLevelsetToReal : public KernelBase {
+ knCopyLevelsetToReal(LevelsetGrid &source, Grid<Real> &target)
+ : KernelBase(&source, 0), source(source), target(target)
+ {
+ runMessage();
+ run();
+ }
+ inline void op(int i, int j, int k, LevelsetGrid &source, Grid<Real> &target) const
{
target(i, j, k) = source(i, j, k);
}
+ inline LevelsetGrid &getArg0()
+ {
+ return source;
+ }
+ typedef LevelsetGrid type0;
+ inline Grid<Real> &getArg1()
+ {
+ return target;
+ }
+ typedef Grid<Real> type1;
+ void runMessage()
+ {
+ debMsg("Executing kernel knCopyLevelsetToReal ", 3);
+ debMsg("Kernel range"
+ << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
+ 4);
+ };
+ void operator()(const tbb::blocked_range<IndexInt> &__r) const
+ {
+ const int _maxX = maxX;
+ const int _maxY = maxY;
+ if (maxZ > 1) {
+ for (int k = __r.begin(); k != (int)__r.end(); k++)
+ for (int j = 0; j < _maxY; j++)
+ for (int i = 0; i < _maxX; i++)
+ op(i, j, k, source, target);
+ }
+ else {
+ const int k = 0;
+ for (int j = __r.begin(); j != (int)__r.end(); j++)
+ for (int i = 0; i < _maxX; i++)
+ op(i, j, k, source, target);
+ }
+ }
+ void run()
+ {
+ if (maxZ > 1)
+ tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this);
+ else
+ tbb::parallel_for(tbb::blocked_range<IndexInt>(0, maxY), *this);
+ }
+ LevelsetGrid &source;
+ Grid<Real> &target;
+};
+
+void copyLevelsetToReal(LevelsetGrid &source, Grid<Real> &target)
+{
+ knCopyLevelsetToReal(source, target);
}
static PyObject *_W_7(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
@@ -1446,17 +1657,95 @@ void PbRegister_copyLevelsetToReal()
}
}
-void copyVec3ToReal(Grid<Vec3> &source,
- Grid<Real> &targetX,
- Grid<Real> &targetY,
- Grid<Real> &targetZ)
-{
- FOR_IJK(source)
+struct knCopyVec3ToReal : public KernelBase {
+ knCopyVec3ToReal(Grid<Vec3> &source,
+ Grid<Real> &targetX,
+ Grid<Real> &targetY,
+ Grid<Real> &targetZ)
+ : KernelBase(&source, 0),
+ source(source),
+ targetX(targetX),
+ targetY(targetY),
+ targetZ(targetZ)
+ {
+ runMessage();
+ run();
+ }
+ inline void op(int i,
+ int j,
+ int k,
+ Grid<Vec3> &source,
+ Grid<Real> &targetX,
+ Grid<Real> &targetY,
+ Grid<Real> &targetZ) const
{
targetX(i, j, k) = source(i, j, k).x;
targetY(i, j, k) = source(i, j, k).y;
targetZ(i, j, k) = source(i, j, k).z;
}
+ inline Grid<Vec3> &getArg0()
+ {
+ return source;
+ }
+ typedef Grid<Vec3> type0;
+ inline Grid<Real> &getArg1()
+ {
+ return targetX;
+ }
+ typedef Grid<Real> type1;
+ inline Grid<Real> &getArg2()
+ {
+ return targetY;
+ }
+ typedef Grid<Real> type2;
+ inline Grid<Real> &getArg3()
+ {
+ return targetZ;
+ }
+ typedef Grid<Real> type3;
+ void runMessage()
+ {
+ debMsg("Executing kernel knCopyVec3ToReal ", 3);
+ debMsg("Kernel range"
+ << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
+ 4);
+ };
+ void operator()(const tbb::blocked_range<IndexInt> &__r) const
+ {
+ const int _maxX = maxX;
+ const int _maxY = maxY;
+ if (maxZ > 1) {
+ for (int k = __r.begin(); k != (int)__r.end(); k++)
+ for (int j = 0; j < _maxY; j++)
+ for (int i = 0; i < _maxX; i++)
+ op(i, j, k, source, targetX, targetY, targetZ);
+ }
+ else {
+ const int k = 0;
+ for (int j = __r.begin(); j != (int)__r.end(); j++)
+ for (int i = 0; i < _maxX; i++)
+ op(i, j, k, source, targetX, targetY, targetZ);
+ }
+ }
+ void run()
+ {
+ if (maxZ > 1)
+ tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this);
+ else
+ tbb::parallel_for(tbb::blocked_range<IndexInt>(0, maxY), *this);
+ }
+ Grid<Vec3> &source;
+ Grid<Real> &targetX;
+ Grid<Real> &targetY;
+ Grid<Real> &targetZ;
+};
+
+void copyVec3ToReal(Grid<Vec3> &source,
+ Grid<Real> &targetX,
+ Grid<Real> &targetY,
+ Grid<Real> &targetZ)
+{
+ knCopyVec3ToReal(source, targetX, targetY, targetZ);
}
static PyObject *_W_8(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
@@ -1492,17 +1781,95 @@ void PbRegister_copyVec3ToReal()
}
}
-void copyRealToVec3(Grid<Real> &sourceX,
- Grid<Real> &sourceY,
- Grid<Real> &sourceZ,
- Grid<Vec3> &target)
-{
- FOR_IJK(target)
+struct knCopyRealToVec3 : public KernelBase {
+ knCopyRealToVec3(Grid<Real> &sourceX,
+ Grid<Real> &sourceY,
+ Grid<Real> &sourceZ,
+ Grid<Vec3> &target)
+ : KernelBase(&sourceX, 0),
+ sourceX(sourceX),
+ sourceY(sourceY),
+ sourceZ(sourceZ),
+ target(target)
+ {
+ runMessage();
+ run();
+ }
+ inline void op(int i,
+ int j,
+ int k,
+ Grid<Real> &sourceX,
+ Grid<Real> &sourceY,
+ Grid<Real> &sourceZ,
+ Grid<Vec3> &target) const
{
target(i, j, k).x = sourceX(i, j, k);
target(i, j, k).y = sourceY(i, j, k);
target(i, j, k).z = sourceZ(i, j, k);
}
+ inline Grid<Real> &getArg0()
+ {
+ return sourceX;
+ }
+ typedef Grid<Real> type0;
+ inline Grid<Real> &getArg1()
+ {
+ return sourceY;
+ }
+ typedef Grid<Real> type1;
+ inline Grid<Real> &getArg2()
+ {
+ return sourceZ;
+ }
+ typedef Grid<Real> type2;
+ inline Grid<Vec3> &getArg3()
+ {
+ return target;
+ }
+ typedef Grid<Vec3> type3;
+ void runMessage()
+ {
+ debMsg("Executing kernel knCopyRealToVec3 ", 3);
+ debMsg("Kernel range"
+ << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
+ 4);
+ };
+ void operator()(const tbb::blocked_range<IndexInt> &__r) const
+ {
+ const int _maxX = maxX;
+ const int _maxY = maxY;
+ if (maxZ > 1) {
+ for (int k = __r.begin(); k != (int)__r.end(); k++)
+ for (int j = 0; j < _maxY; j++)
+ for (int i = 0; i < _maxX; i++)
+ op(i, j, k, sourceX, sourceY, sourceZ, target);
+ }
+ else {
+ const int k = 0;
+ for (int j = __r.begin(); j != (int)__r.end(); j++)
+ for (int i = 0; i < _maxX; i++)
+ op(i, j, k, sourceX, sourceY, sourceZ, target);
+ }
+ }
+ void run()
+ {
+ if (maxZ > 1)
+ tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this);
+ else
+ tbb::parallel_for(tbb::blocked_range<IndexInt>(0, maxY), *this);
+ }
+ Grid<Real> &sourceX;
+ Grid<Real> &sourceY;
+ Grid<Real> &sourceZ;
+ Grid<Vec3> &target;
+};
+
+void copyRealToVec3(Grid<Real> &sourceX,
+ Grid<Real> &sourceY,
+ Grid<Real> &sourceZ,
+ Grid<Vec3> &target)
+{
+ knCopyRealToVec3(sourceX, sourceY, sourceZ, target);
}
static PyObject *_W_9(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
{
diff --git a/extern/mantaflow/preprocessed/levelset.cpp b/extern/mantaflow/preprocessed/levelset.cpp
index dcc10718d71..a6f9fb40f3f 100644
--- a/extern/mantaflow/preprocessed/levelset.cpp
+++ b/extern/mantaflow/preprocessed/levelset.cpp
@@ -773,9 +773,9 @@ void LevelsetGrid::createMesh(Mesh &mesh)
Grid<int> edgeVY(mParent);
Grid<int> edgeVZ(mParent);
- for (int i = 0; i < mSize.x - 1; i++)
+ for (int k = 0; k < mSize.z - 1; k++)
for (int j = 0; j < mSize.y - 1; j++)
- for (int k = 0; k < mSize.z - 1; k++) {
+ for (int i = 0; i < mSize.x - 1; i++) {
Real value[8] = {get(i, j, k),
get(i + 1, j, k),
get(i + 1, j + 1, k),
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index ee7ac7737c0..7917edf8c88 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -245,9 +245,6 @@ def list_render_passes(srl):
if srl.use_pass_transmission_direct: yield ("TransDir", "RGB", 'COLOR')
if srl.use_pass_transmission_indirect: yield ("TransInd", "RGB", 'COLOR')
if srl.use_pass_transmission_color: yield ("TransCol", "RGB", 'COLOR')
- if srl.use_pass_subsurface_direct: yield ("SubsurfaceDir", "RGB", 'COLOR')
- if srl.use_pass_subsurface_indirect: yield ("SubsurfaceInd", "RGB", 'COLOR')
- if srl.use_pass_subsurface_color: yield ("SubsurfaceCol", "RGB", 'COLOR')
if srl.use_pass_emit: yield ("Emit", "RGB", 'COLOR')
if srl.use_pass_environment: yield ("Env", "RGB", 'COLOR')
@@ -284,8 +281,7 @@ def list_render_passes(srl):
yield ("Denoising Intensity", "X", 'VALUE')
clean_options = ("denoising_diffuse_direct", "denoising_diffuse_indirect",
"denoising_glossy_direct", "denoising_glossy_indirect",
- "denoising_transmission_direct", "denoising_transmission_indirect",
- "denoising_subsurface_direct", "denoising_subsurface_indirect")
+ "denoising_transmission_direct", "denoising_transmission_indirect")
if any(getattr(crl, option) for option in clean_options):
yield ("Denoising Clean", "RGB", 'COLOR')
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 23ff1771995..d66a1f70c48 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -178,10 +178,6 @@ enum_view3d_shading_render_pass= (
('TRANSMISSION_INDIRECT', "Transmission Indirect", "Show the Transmission Indirect render pass", 45),
('TRANSMISSION_COLOR', "Transmission Color", "Show the Transmission Color render pass", 46),
- ('SUBSURFACE_DIRECT', "Subsurface Direct", "Show the Subsurface Direct render pass", 47),
- ('SUBSURFACE_INDIRECT', "Subsurface Indirect", "Show the Subsurface Indirect render pass", 48),
- ('SUBSURFACE_COLOR', "Subsurface Color", "Show the Subsurface Color render pass", 49),
-
('VOLUME_DIRECT', "Volume Direct", "Show the Volume Direct render pass", 50),
('VOLUME_INDIRECT', "Volume Indirect", "Show the Volume Indirect render pass", 51),
@@ -573,6 +569,12 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default=64,
subtype='PIXEL'
)
+ preview_denoising_start_sample: IntProperty(
+ name="Start Denoising",
+ description="Sample to start denoising the preview at",
+ min=0, max=(1 << 24),
+ default=1,
+ )
debug_reset_timeout: FloatProperty(
name="Reset timeout",
@@ -652,7 +654,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
('DIFFUSE', "Diffuse", ""),
('GLOSSY', "Glossy", ""),
('TRANSMISSION', "Transmission", ""),
- ('SUBSURFACE', "Subsurface", ""),
),
)
@@ -1346,16 +1347,6 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
description="Denoise the indirect transmission lighting",
default=True,
)
- denoising_subsurface_direct: BoolProperty(
- name="Subsurface Direct",
- description="Denoise the direct subsurface lighting",
- default=True,
- )
- denoising_subsurface_indirect: BoolProperty(
- name="Subsurface Indirect",
- description="Denoise the indirect subsurface lighting",
- default=True,
- )
denoising_strength: FloatProperty(
name="Denoising Strength",
description="Controls neighbor pixel weighting for the denoising filter (lower values preserve more detail, but aren't as smooth)",
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index f23d141e3da..ed9e3a4c9cf 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -710,6 +710,11 @@ class CYCLES_RENDER_PT_performance_viewport(CyclesButtonsPanel, Panel):
col.prop(rd, "preview_pixel_size", text="Pixel Size")
col.prop(cscene, "preview_start_resolution", text="Start Pixels")
+ if show_optix_denoising(context):
+ sub = col.row(align=True)
+ sub.active = cscene.preview_denoising != 'NONE'
+ sub.prop(cscene, "preview_denoising_start_sample", text="Denoising Start Sample")
+
class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel):
bl_label = "Filter"
@@ -853,14 +858,6 @@ class CYCLES_RENDER_PT_passes_light(CyclesButtonsPanel, Panel):
split = layout.split(factor=0.35)
split.use_property_split = False
- split.label(text="Subsurface")
- row = split.row(align=True)
- row.prop(view_layer, "use_pass_subsurface_direct", text="Direct", toggle=True)
- row.prop(view_layer, "use_pass_subsurface_indirect", text="Indirect", toggle=True)
- row.prop(view_layer, "use_pass_subsurface_color", text="Color", toggle=True)
-
- split = layout.split(factor=0.35)
- split.use_property_split = False
split.label(text="Volume")
row = split.row(align=True)
row.prop(cycles_view_layer, "use_pass_volume_direct", text="Direct", toggle=True)
@@ -1040,15 +1037,6 @@ class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel):
split = layout.split(factor=0.5)
split.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
- col = split.column()
- col.alignment = 'RIGHT'
- col.label(text="Subsurface")
-
- row = split.row(align=True)
- row.use_property_split = False
- row.prop(cycles_view_layer, "denoising_subsurface_direct", text="Direct", toggle=True)
- row.prop(cycles_view_layer, "denoising_subsurface_indirect", text="Indirect", toggle=True)
-
class CYCLES_PT_post_processing(CyclesButtonsPanel, Panel):
bl_label = "Post Processing"
@@ -1856,7 +1844,7 @@ class CYCLES_RENDER_PT_bake_influence(CyclesButtonsPanel, Panel):
cscene = scene.cycles
rd = scene.render
if rd.use_bake_multires == False and cscene.bake_type in {
- 'NORMAL', 'COMBINED', 'DIFFUSE', 'GLOSSY', 'TRANSMISSION', 'SUBSURFACE'}:
+ 'NORMAL', 'COMBINED', 'DIFFUSE', 'GLOSSY', 'TRANSMISSION'}:
return True
def draw(self, context):
@@ -1895,7 +1883,7 @@ class CYCLES_RENDER_PT_bake_influence(CyclesButtonsPanel, Panel):
flow.prop(cbk, "use_pass_ambient_occlusion")
flow.prop(cbk, "use_pass_emit")
- elif cscene.bake_type in {'DIFFUSE', 'GLOSSY', 'TRANSMISSION', 'SUBSURFACE'}:
+ elif cscene.bake_type in {'DIFFUSE', 'GLOSSY', 'TRANSMISSION'}:
row = col.row(align=True)
row.use_property_split = False
row.prop(cbk, "use_pass_direct", toggle=True)
diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py
index 899245db03e..49f23f4ba30 100644
--- a/intern/cycles/blender/addon/version_update.py
+++ b/intern/cycles/blender/addon/version_update.py
@@ -42,10 +42,7 @@ def custom_bake_remap(scene):
'GLOSSY_COLOR',
'TRANSMISSION_DIRECT',
'TRANSMISSION_INDIRECT',
- 'TRANSMISSION_COLOR',
- 'SUBSURFACE_DIRECT',
- 'SUBSURFACE_INDIRECT',
- 'SUBSURFACE_COLOR')
+ 'TRANSMISSION_COLOR')
diffuse_direct_idx = bake_lookup.index('DIFFUSE_DIRECT')
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index affd5685337..fe0f8f3b88a 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -1154,7 +1154,10 @@ void BlenderSync::sync_particle_hair(
}
}
-void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Geometry *geom)
+void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph,
+ BL::Object b_ob,
+ Geometry *geom,
+ const vector<Shader *> &used_shaders)
{
Hair *hair = (geom->type == Geometry::HAIR) ? static_cast<Hair *>(geom) : NULL;
Mesh *mesh = (geom->type == Geometry::MESH) ? static_cast<Mesh *>(geom) : NULL;
@@ -1172,6 +1175,9 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Geometry
oldtriangles.steal_data(mesh->triangles);
}
+ geom->clear();
+ geom->used_shaders = used_shaders;
+
if (view_layer.use_hair && scene->curve_system_manager->use_curves) {
/* Particle hair. */
bool need_undeformed = geom->need_attribute(scene, ATTR_STD_GENERATED);
diff --git a/intern/cycles/blender/blender_device.cpp b/intern/cycles/blender/blender_device.cpp
index c3c307318a8..d0f8465a98f 100644
--- a/intern/cycles/blender/blender_device.cpp
+++ b/intern/cycles/blender/blender_device.cpp
@@ -115,8 +115,9 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
}
/* Ensure there is an OptiX device when using the OptiX denoiser. */
- bool use_optix_denoising = DENOISER_OPTIX ==
- get_enum(cscene, "preview_denoising", DENOISER_NUM, DENOISER_NONE);
+ bool use_optix_denoising = get_enum(cscene, "preview_denoising", DENOISER_NUM, DENOISER_NONE) ==
+ DENOISER_OPTIX &&
+ !background;
BL::Scene::view_layers_iterator b_view_layer;
for (b_scene.view_layers.begin(b_view_layer); b_view_layer != b_scene.view_layers.end();
++b_view_layer) {
diff --git a/intern/cycles/blender/blender_geometry.cpp b/intern/cycles/blender/blender_geometry.cpp
index 8b803835b62..304b3d18e27 100644
--- a/intern/cycles/blender/blender_geometry.cpp
+++ b/intern/cycles/blender/blender_geometry.cpp
@@ -117,20 +117,18 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
geometry_synced.insert(geom);
- geom->clear();
- geom->used_shaders = used_shaders;
geom->name = ustring(b_ob_data.name().c_str());
if (use_particle_hair) {
- sync_hair(b_depsgraph, b_ob, geom);
+ sync_hair(b_depsgraph, b_ob, geom, used_shaders);
}
else if (object_fluid_gas_domain_find(b_ob)) {
Mesh *mesh = static_cast<Mesh *>(geom);
- sync_volume(b_ob, mesh);
+ sync_volume(b_ob, mesh, used_shaders);
}
else {
Mesh *mesh = static_cast<Mesh *>(geom);
- sync_mesh(b_depsgraph, b_ob, mesh);
+ sync_mesh(b_depsgraph, b_ob, mesh, used_shaders);
}
return geom;
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 42300f6eb6f..075c9250e8c 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -941,7 +941,10 @@ static void sync_mesh_fluid_motion(BL::Object &b_ob, Scene *scene, Mesh *mesh)
}
}
-void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh)
+void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph,
+ BL::Object b_ob,
+ Mesh *mesh,
+ const vector<Shader *> &used_shaders)
{
array<int> oldtriangles;
array<Mesh::SubdFace> oldsubd_faces;
@@ -950,6 +953,9 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *me
oldsubd_faces.steal_data(mesh->subd_faces);
oldsubd_face_corners.steal_data(mesh->subd_face_corners);
+ mesh->clear();
+ mesh->used_shaders = used_shaders;
+
mesh->subdivision_type = Mesh::SUBDIVISION_NONE;
if (view_layer.use_surfaces) {
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 2e7a72d8072..5cfb1200c7c 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -278,8 +278,6 @@ static ShaderEvalType get_shader_type(const string &pass_type)
return SHADER_EVAL_GLOSSY_COLOR;
else if (strcmp(shader_type, "TRANSMISSION_COLOR") == 0)
return SHADER_EVAL_TRANSMISSION_COLOR;
- else if (strcmp(shader_type, "SUBSURFACE_COLOR") == 0)
- return SHADER_EVAL_SUBSURFACE_COLOR;
else if (strcmp(shader_type, "EMIT") == 0)
return SHADER_EVAL_EMISSION;
@@ -296,8 +294,6 @@ static ShaderEvalType get_shader_type(const string &pass_type)
return SHADER_EVAL_GLOSSY;
else if (strcmp(shader_type, "TRANSMISSION") == 0)
return SHADER_EVAL_TRANSMISSION;
- else if (strcmp(shader_type, "SUBSURFACE") == 0)
- return SHADER_EVAL_SUBSURFACE;
/* extra */
else if (strcmp(shader_type, "ENVIRONMENT") == 0)
@@ -640,8 +636,6 @@ static int bake_pass_filter_get(const int pass_filter)
flag |= BAKE_FILTER_GLOSSY;
if ((pass_filter & BL::BakeSettings::pass_filter_TRANSMISSION) != 0)
flag |= BAKE_FILTER_TRANSMISSION;
- if ((pass_filter & BL::BakeSettings::pass_filter_SUBSURFACE) != 0)
- flag |= BAKE_FILTER_SUBSURFACE;
if ((pass_filter & BL::BakeSettings::pass_filter_EMIT) != 0)
flag |= BAKE_FILTER_EMISSION;
@@ -855,6 +849,7 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
/* increase samples, but never decrease */
session->set_samples(session_params.samples);
+ session->set_denoising_start_sample(session_params.denoising_start_sample);
session->set_pause(session_pause);
/* copy recalc flags, outside of mutex so we can decide to do the real
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 0412654d3bd..50442c6ebdc 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -461,19 +461,16 @@ PassType BlenderSync::get_pass_type(BL::RenderPass &b_pass)
MAP_PASS("DiffDir", PASS_DIFFUSE_DIRECT);
MAP_PASS("GlossDir", PASS_GLOSSY_DIRECT);
MAP_PASS("TransDir", PASS_TRANSMISSION_DIRECT);
- MAP_PASS("SubsurfaceDir", PASS_SUBSURFACE_DIRECT);
MAP_PASS("VolumeDir", PASS_VOLUME_DIRECT);
MAP_PASS("DiffInd", PASS_DIFFUSE_INDIRECT);
MAP_PASS("GlossInd", PASS_GLOSSY_INDIRECT);
MAP_PASS("TransInd", PASS_TRANSMISSION_INDIRECT);
- MAP_PASS("SubsurfaceInd", PASS_SUBSURFACE_INDIRECT);
MAP_PASS("VolumeInd", PASS_VOLUME_INDIRECT);
MAP_PASS("DiffCol", PASS_DIFFUSE_COLOR);
MAP_PASS("GlossCol", PASS_GLOSSY_COLOR);
MAP_PASS("TransCol", PASS_TRANSMISSION_COLOR);
- MAP_PASS("SubsurfaceCol", PASS_SUBSURFACE_COLOR);
MAP_PASS("Emit", PASS_EMISSION);
MAP_PASS("Env", PASS_BACKGROUND);
@@ -556,8 +553,6 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLa
MAP_OPTION("denoising_glossy_indirect", DENOISING_CLEAN_GLOSSY_IND);
MAP_OPTION("denoising_transmission_direct", DENOISING_CLEAN_TRANSMISSION_DIR);
MAP_OPTION("denoising_transmission_indirect", DENOISING_CLEAN_TRANSMISSION_IND);
- MAP_OPTION("denoising_subsurface_direct", DENOISING_CLEAN_SUBSURFACE_DIR);
- MAP_OPTION("denoising_subsurface_indirect", DENOISING_CLEAN_SUBSURFACE_IND);
#undef MAP_OPTION
}
b_engine.add_pass("Noisy Image", 4, "RGBA", b_view_layer.name().c_str());
@@ -837,6 +832,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
/* other parameters */
params.start_resolution = get_int(cscene, "preview_start_resolution");
+ params.denoising_start_sample = get_int(cscene, "preview_denoising_start_sample");
params.pixel_size = b_engine.get_preview_pixel_size(b_scene);
/* other parameters */
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index efd4511eb1e..219a3615835 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -137,14 +137,20 @@ class BlenderSync {
bool *use_portal);
/* Volume */
- void sync_volume(BL::Object &b_ob, Mesh *mesh);
+ void sync_volume(BL::Object &b_ob, Mesh *mesh, const vector<Shader *> &used_shaders);
/* Mesh */
- void sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh);
+ void sync_mesh(BL::Depsgraph b_depsgraph,
+ BL::Object b_ob,
+ Mesh *mesh,
+ const vector<Shader *> &used_shaders);
void sync_mesh_motion(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh, int motion_step);
/* Hair */
- void sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Geometry *geom);
+ void sync_hair(BL::Depsgraph b_depsgraph,
+ BL::Object b_ob,
+ Geometry *geom,
+ const vector<Shader *> &used_shaders);
void sync_hair_motion(BL::Depsgraph b_depsgraph,
BL::Object b_ob,
Geometry *geom,
diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp
index 87fb9620725..ae70e60d60e 100644
--- a/intern/cycles/blender/blender_volume.cpp
+++ b/intern/cycles/blender/blender_volume.cpp
@@ -80,10 +80,13 @@ static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Mesh *mesh, float
}
}
-void BlenderSync::sync_volume(BL::Object &b_ob, Mesh *mesh)
+void BlenderSync::sync_volume(BL::Object &b_ob, Mesh *mesh, const vector<Shader *> &used_shaders)
{
bool old_has_voxel_attributes = mesh->has_voxel_attributes();
+ mesh->clear();
+ mesh->used_shaders = used_shaders;
+
/* Smoke domain. */
sync_smoke_volume(scene, b_ob, mesh, b_scene.frame_current());
diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp
index 84b00aab91c..639dfe3cee2 100644
--- a/intern/cycles/bvh/bvh_embree.cpp
+++ b/intern/cycles/bvh/bvh_embree.cpp
@@ -727,6 +727,12 @@ void BVHEmbree::update_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair
num_keys += c.num_keys;
}
+ /* Catmull-Rom splines need extra CVs at the beginning and end of each curve. */
+ size_t num_keys_embree = num_keys;
+ if (use_curves) {
+ num_keys_embree += num_curves * 2;
+ }
+
/* Copy the CV data to Embree */
const int t_mid = (num_motion_steps - 1) / 2;
const float *curve_radius = &hair->curve_radius[0];
@@ -741,42 +747,28 @@ void BVHEmbree::update_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair
}
float4 *rtc_verts = (float4 *)rtcSetNewGeometryBuffer(
- geom_id, RTC_BUFFER_TYPE_VERTEX, t, RTC_FORMAT_FLOAT4, sizeof(float) * 4, num_keys);
- float4 *rtc_tangents = NULL;
- if (use_curves) {
- rtc_tangents = (float4 *)rtcSetNewGeometryBuffer(
- geom_id, RTC_BUFFER_TYPE_TANGENT, t, RTC_FORMAT_FLOAT4, sizeof(float) * 4, num_keys);
- assert(rtc_tangents);
- }
+ geom_id, RTC_BUFFER_TYPE_VERTEX, t, RTC_FORMAT_FLOAT4, sizeof(float) * 4, num_keys_embree);
+
assert(rtc_verts);
if (rtc_verts) {
- if (use_curves && rtc_tangents) {
+ if (use_curves) {
const size_t num_curves = hair->num_curves();
for (size_t j = 0; j < num_curves; ++j) {
Hair::Curve c = hair->get_curve(j);
int fk = c.first_key;
- rtc_verts[0] = float3_to_float4(verts[fk]);
- rtc_verts[0].w = curve_radius[fk];
- rtc_tangents[0] = float3_to_float4(verts[fk + 1] - verts[fk]);
- rtc_tangents[0].w = curve_radius[fk + 1] - curve_radius[fk];
- ++fk;
int k = 1;
- for (; k < c.num_segments(); ++k, ++fk) {
+ for (; k < c.num_keys + 1; ++k, ++fk) {
rtc_verts[k] = float3_to_float4(verts[fk]);
rtc_verts[k].w = curve_radius[fk];
- rtc_tangents[k] = float3_to_float4((verts[fk + 1] - verts[fk - 1]) * 0.5f);
- rtc_tangents[k].w = (curve_radius[fk + 1] - curve_radius[fk - 1]) * 0.5f;
}
- rtc_verts[k] = float3_to_float4(verts[fk]);
- rtc_verts[k].w = curve_radius[fk];
- rtc_tangents[k] = float3_to_float4(verts[fk] - verts[fk - 1]);
- rtc_tangents[k].w = curve_radius[fk] - curve_radius[fk - 1];
- rtc_verts += c.num_keys;
- rtc_tangents += c.num_keys;
+ /* Duplicate Embree's Catmull-Rom spline CVs at the start and end of each curve. */
+ rtc_verts[0] = rtc_verts[1];
+ rtc_verts[k] = rtc_verts[k - 1];
+ rtc_verts += c.num_keys + 2;
}
}
else {
- for (size_t j = 0; j < num_keys; ++j) {
+ for (size_t j = 0; j < num_keys_embree; ++j) {
rtc_verts[j] = float3_to_float4(verts[j]);
rtc_verts[j].w = curve_radius[j];
}
@@ -820,8 +812,8 @@ void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i)
enum RTCGeometryType type = (!use_curves) ?
RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE :
- (use_ribbons ? RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE :
- RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE);
+ (use_ribbons ? RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE :
+ RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE);
RTCGeometry geom_id = rtcNewGeometry(rtc_shared_device, type);
rtcSetGeometryTessellationRate(geom_id, curve_subdivisions);
@@ -832,6 +824,10 @@ void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i)
Hair::Curve c = hair->get_curve(j);
for (size_t k = 0; k < c.num_segments(); ++k) {
rtc_indices[rtc_index] = c.first_key + k;
+ if (use_curves) {
+ /* Room for extra CVs at Catmull-Rom splines. */
+ rtc_indices[rtc_index] += j * 2;
+ }
/* Cycles specific data. */
pack.prim_object[prim_object_size + rtc_index] = i;
pack.prim_type[prim_type_size + rtc_index] = (PRIMITIVE_PACK_SEGMENT(
diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h
index 9ea75d54c5d..79ea03f4f6f 100644
--- a/intern/cycles/kernel/kernel_accumulate.h
+++ b/intern/cycles/kernel/kernel_accumulate.h
@@ -36,21 +36,18 @@ ccl_device_inline void bsdf_eval_init(BsdfEval *eval,
eval->glossy = make_float3(0.0f, 0.0f, 0.0f);
eval->transmission = make_float3(0.0f, 0.0f, 0.0f);
eval->transparent = make_float3(0.0f, 0.0f, 0.0f);
- eval->subsurface = make_float3(0.0f, 0.0f, 0.0f);
- eval->scatter = make_float3(0.0f, 0.0f, 0.0f);
+ eval->volume = make_float3(0.0f, 0.0f, 0.0f);
if (type == CLOSURE_BSDF_TRANSPARENT_ID)
eval->transparent = value;
- else if (CLOSURE_IS_BSDF_DIFFUSE(type))
+ else if (CLOSURE_IS_BSDF_DIFFUSE(type) || CLOSURE_IS_BSDF_BSSRDF(type))
eval->diffuse = value;
else if (CLOSURE_IS_BSDF_GLOSSY(type))
eval->glossy = value;
else if (CLOSURE_IS_BSDF_TRANSMISSION(type))
eval->transmission = value;
- else if (CLOSURE_IS_BSDF_BSSRDF(type))
- eval->subsurface = value;
else if (CLOSURE_IS_PHASE(type))
- eval->scatter = value;
+ eval->volume = value;
}
else
#endif
@@ -73,16 +70,14 @@ ccl_device_inline void bsdf_eval_accum(BsdfEval *eval,
value *= mis_weight;
#ifdef __PASSES__
if (eval->use_light_pass) {
- if (CLOSURE_IS_BSDF_DIFFUSE(type))
+ if (CLOSURE_IS_BSDF_DIFFUSE(type) || CLOSURE_IS_BSDF_BSSRDF(type))
eval->diffuse += value;
else if (CLOSURE_IS_BSDF_GLOSSY(type))
eval->glossy += value;
else if (CLOSURE_IS_BSDF_TRANSMISSION(type))
eval->transmission += value;
- else if (CLOSURE_IS_BSDF_BSSRDF(type))
- eval->subsurface += value;
else if (CLOSURE_IS_PHASE(type))
- eval->scatter += value;
+ eval->volume += value;
/* skipping transparent, this function is used by for eval(), will be zero then */
}
@@ -98,7 +93,7 @@ ccl_device_inline bool bsdf_eval_is_zero(BsdfEval *eval)
#ifdef __PASSES__
if (eval->use_light_pass) {
return is_zero(eval->diffuse) && is_zero(eval->glossy) && is_zero(eval->transmission) &&
- is_zero(eval->transparent) && is_zero(eval->subsurface) && is_zero(eval->scatter);
+ is_zero(eval->transparent) && is_zero(eval->volume);
}
else
#endif
@@ -114,8 +109,7 @@ ccl_device_inline void bsdf_eval_mis(BsdfEval *eval, float value)
eval->diffuse *= value;
eval->glossy *= value;
eval->transmission *= value;
- eval->subsurface *= value;
- eval->scatter *= value;
+ eval->volume *= value;
/* skipping transparent, this function is used by for eval(), will be zero then */
}
@@ -144,8 +138,7 @@ ccl_device_inline void bsdf_eval_mul3(BsdfEval *eval, float3 value)
eval->diffuse *= value;
eval->glossy *= value;
eval->transmission *= value;
- eval->subsurface *= value;
- eval->scatter *= value;
+ eval->volume *= value;
/* skipping transparent, this function is used by for eval(), will be zero then */
}
@@ -160,7 +153,7 @@ ccl_device_inline float3 bsdf_eval_sum(const BsdfEval *eval)
{
#ifdef __PASSES__
if (eval->use_light_pass) {
- return eval->diffuse + eval->glossy + eval->transmission + eval->subsurface + eval->scatter;
+ return eval->diffuse + eval->glossy + eval->transmission + eval->volume;
}
else
#endif
@@ -187,19 +180,16 @@ ccl_device_inline void path_radiance_init(KernelGlobals *kg, PathRadiance *L)
L->color_diffuse = make_float3(0.0f, 0.0f, 0.0f);
L->color_glossy = make_float3(0.0f, 0.0f, 0.0f);
L->color_transmission = make_float3(0.0f, 0.0f, 0.0f);
- L->color_subsurface = make_float3(0.0f, 0.0f, 0.0f);
L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
- L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
- L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f);
+ L->direct_volume = make_float3(0.0f, 0.0f, 0.0f);
L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
- L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
- L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f);
+ L->indirect_volume = make_float3(0.0f, 0.0f, 0.0f);
L->transparent = 0.0f;
L->emission = make_float3(0.0f, 0.0f, 0.0f);
@@ -211,8 +201,7 @@ ccl_device_inline void path_radiance_init(KernelGlobals *kg, PathRadiance *L)
L->state.diffuse = make_float3(0.0f, 0.0f, 0.0f);
L->state.glossy = make_float3(0.0f, 0.0f, 0.0f);
L->state.transmission = make_float3(0.0f, 0.0f, 0.0f);
- L->state.subsurface = make_float3(0.0f, 0.0f, 0.0f);
- L->state.scatter = make_float3(0.0f, 0.0f, 0.0f);
+ L->state.volume = make_float3(0.0f, 0.0f, 0.0f);
L->state.direct = make_float3(0.0f, 0.0f, 0.0f);
}
else
@@ -264,11 +253,9 @@ ccl_device_inline void path_radiance_bsdf_bounce(KernelGlobals *kg,
L_state->diffuse = bsdf_eval->diffuse * value;
L_state->glossy = bsdf_eval->glossy * value;
L_state->transmission = bsdf_eval->transmission * value;
- L_state->subsurface = bsdf_eval->subsurface * value;
- L_state->scatter = bsdf_eval->scatter * value;
+ L_state->volume = bsdf_eval->volume * value;
- *throughput = L_state->diffuse + L_state->glossy + L_state->transmission +
- L_state->subsurface + L_state->scatter;
+ *throughput = L_state->diffuse + L_state->glossy + L_state->transmission + L_state->volume;
L_state->direct = *throughput;
}
@@ -449,8 +436,7 @@ ccl_device_inline void path_radiance_accum_light(KernelGlobals *kg,
L->direct_diffuse += shaded_throughput * bsdf_eval->diffuse;
L->direct_glossy += shaded_throughput * bsdf_eval->glossy;
L->direct_transmission += shaded_throughput * bsdf_eval->transmission;
- L->direct_subsurface += shaded_throughput * bsdf_eval->subsurface;
- L->direct_scatter += shaded_throughput * bsdf_eval->scatter;
+ L->direct_volume += shaded_throughput * bsdf_eval->volume;
if (is_lamp) {
L->shadow.x += shadow.x * shadow_fac;
@@ -562,15 +548,13 @@ ccl_device_inline void path_radiance_sum_indirect(PathRadiance *L)
L->direct_diffuse += L->state.diffuse * L->direct_emission;
L->direct_glossy += L->state.glossy * L->direct_emission;
L->direct_transmission += L->state.transmission * L->direct_emission;
- L->direct_subsurface += L->state.subsurface * L->direct_emission;
- L->direct_scatter += L->state.scatter * L->direct_emission;
+ L->direct_volume += L->state.volume * L->direct_emission;
L->indirect = safe_divide_color(L->indirect, L->state.direct);
L->indirect_diffuse += L->state.diffuse * L->indirect;
L->indirect_glossy += L->state.glossy * L->indirect;
L->indirect_transmission += L->state.transmission * L->indirect;
- L->indirect_subsurface += L->state.subsurface * L->indirect;
- L->indirect_scatter += L->state.scatter * L->indirect;
+ L->indirect_volume += L->state.volume * L->indirect;
}
#endif
}
@@ -582,8 +566,7 @@ ccl_device_inline void path_radiance_reset_indirect(PathRadiance *L)
L->state.diffuse = make_float3(0.0f, 0.0f, 0.0f);
L->state.glossy = make_float3(0.0f, 0.0f, 0.0f);
L->state.transmission = make_float3(0.0f, 0.0f, 0.0f);
- L->state.subsurface = make_float3(0.0f, 0.0f, 0.0f);
- L->state.scatter = make_float3(0.0f, 0.0f, 0.0f);
+ L->state.volume = make_float3(0.0f, 0.0f, 0.0f);
L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
L->indirect = make_float3(0.0f, 0.0f, 0.0f);
@@ -647,10 +630,10 @@ ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg,
if (L->use_light_pass) {
path_radiance_sum_indirect(L);
- L_direct = L->direct_diffuse + L->direct_glossy + L->direct_transmission +
- L->direct_subsurface + L->direct_scatter + L->emission;
+ L_direct = L->direct_diffuse + L->direct_glossy + L->direct_transmission + L->direct_volume +
+ L->emission;
L_indirect = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission +
- L->indirect_subsurface + L->indirect_scatter;
+ L->indirect_volume;
if (!kernel_data.background.transparent)
L_direct += L->background;
@@ -666,14 +649,12 @@ ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg,
L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
- L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
- L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f);
+ L->direct_volume = make_float3(0.0f, 0.0f, 0.0f);
L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
- L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
- L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f);
+ L->indirect_volume = make_float3(0.0f, 0.0f, 0.0f);
L->emission = make_float3(0.0f, 0.0f, 0.0f);
}
@@ -715,7 +696,7 @@ ccl_device_inline void path_radiance_split_denoising(KernelGlobals *kg,
kernel_assert(L->use_light_pass);
*clean = L->emission + L->background;
- *noisy = L->direct_scatter + L->indirect_scatter;
+ *noisy = L->direct_volume + L->indirect_volume;
# define ADD_COMPONENT(flag, component) \
if (kernel_data.film.denoising_flags & flag) \
@@ -729,8 +710,6 @@ ccl_device_inline void path_radiance_split_denoising(KernelGlobals *kg,
ADD_COMPONENT(DENOISING_CLEAN_GLOSSY_IND, L->indirect_glossy);
ADD_COMPONENT(DENOISING_CLEAN_TRANSMISSION_DIR, L->direct_transmission);
ADD_COMPONENT(DENOISING_CLEAN_TRANSMISSION_IND, L->indirect_transmission);
- ADD_COMPONENT(DENOISING_CLEAN_SUBSURFACE_DIR, L->direct_subsurface);
- ADD_COMPONENT(DENOISING_CLEAN_SUBSURFACE_IND, L->indirect_subsurface);
# undef ADD_COMPONENT
#else
*noisy = L->emission;
@@ -767,14 +746,12 @@ ccl_device_inline void path_radiance_accum_sample(PathRadiance *L, PathRadiance
safe_float3_add(L->direct_diffuse, L_sample->direct_diffuse);
safe_float3_add(L->direct_glossy, L_sample->direct_glossy);
safe_float3_add(L->direct_transmission, L_sample->direct_transmission);
- safe_float3_add(L->direct_subsurface, L_sample->direct_subsurface);
- safe_float3_add(L->direct_scatter, L_sample->direct_scatter);
+ safe_float3_add(L->direct_volume, L_sample->direct_volume);
safe_float3_add(L->indirect_diffuse, L_sample->indirect_diffuse);
safe_float3_add(L->indirect_glossy, L_sample->indirect_glossy);
safe_float3_add(L->indirect_transmission, L_sample->indirect_transmission);
- safe_float3_add(L->indirect_subsurface, L_sample->indirect_subsurface);
- safe_float3_add(L->indirect_scatter, L_sample->indirect_scatter);
+ safe_float3_add(L->indirect_volume, L_sample->indirect_volume);
safe_float3_add(L->background, L_sample->background);
safe_float3_add(L->ao, L_sample->ao);
diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index a349b225abb..f1fc697553a 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -71,7 +71,7 @@ ccl_device_inline void compute_light_pass(
# ifdef __SUBSURFACE__
/* sample subsurface scattering */
- if ((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) {
+ if ((pass_filter & BAKE_FILTER_DIFFUSE) && (sd->flag & SD_BSSRDF)) {
/* When mixing BSSRDF and BSDF closures we should skip BSDF lighting
* if scattering was successful. */
SubsurfaceIndirectRays ss_indirect;
@@ -123,7 +123,7 @@ ccl_device_inline void compute_light_pass(
# ifdef __SUBSURFACE__
/* sample subsurface scattering */
- if ((pass_filter & BAKE_FILTER_SUBSURFACE) && (sd->flag & SD_BSSRDF)) {
+ if ((pass_filter & BAKE_FILTER_DIFFUSE) && (sd->flag & SD_BSSRDF)) {
/* When mixing BSSRDF and BSDF closures we should skip BSDF lighting
* if scattering was successful. */
kernel_branched_path_subsurface_scatter(
@@ -178,10 +178,6 @@ ccl_device_inline float3 kernel_bake_shader_bsdf(KernelGlobals *kg,
return shader_bsdf_glossy(kg, sd);
case SHADER_EVAL_TRANSMISSION:
return shader_bsdf_transmission(kg, sd);
-# ifdef __SUBSURFACE__
- case SHADER_EVAL_SUBSURFACE:
- return shader_bsdf_subsurface(kg, sd);
-# endif
default:
kernel_assert(!"Unknown bake type passed to BSDF evaluate");
return make_float3(0.0f, 0.0f, 0.0f);
@@ -385,11 +381,6 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg,
if ((pass_filter & BAKE_FILTER_TRANSMISSION_INDIRECT) == BAKE_FILTER_TRANSMISSION_INDIRECT)
out += L.indirect_transmission;
- if ((pass_filter & BAKE_FILTER_SUBSURFACE_DIRECT) == BAKE_FILTER_SUBSURFACE_DIRECT)
- out += L.direct_subsurface;
- if ((pass_filter & BAKE_FILTER_SUBSURFACE_INDIRECT) == BAKE_FILTER_SUBSURFACE_INDIRECT)
- out += L.indirect_subsurface;
-
if ((pass_filter & BAKE_FILTER_EMISSION) != 0)
out += L.emission;
@@ -414,13 +405,6 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg,
kg, &sd, &state, L.direct_transmission, L.indirect_transmission, type, pass_filter);
break;
}
- case SHADER_EVAL_SUBSURFACE: {
-# ifdef __SUBSURFACE__
- out = kernel_bake_evaluate_direct_indirect(
- kg, &sd, &state, L.direct_subsurface, L.indirect_subsurface, type, pass_filter);
-# endif
- break;
- }
# endif
/* extra */
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index c63d1149d03..71b176a0a8f 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -145,16 +145,14 @@ ccl_device_noinline_cpu bool direct_emission(KernelGlobals *kg,
#ifdef __PASSES__
/* use visibility flag to skip lights */
if (ls->shader & SHADER_EXCLUDE_ANY) {
- if (ls->shader & SHADER_EXCLUDE_DIFFUSE) {
+ if (ls->shader & SHADER_EXCLUDE_DIFFUSE)
eval->diffuse = make_float3(0.0f, 0.0f, 0.0f);
- eval->subsurface = make_float3(0.0f, 0.0f, 0.0f);
- }
if (ls->shader & SHADER_EXCLUDE_GLOSSY)
eval->glossy = make_float3(0.0f, 0.0f, 0.0f);
if (ls->shader & SHADER_EXCLUDE_TRANSMIT)
eval->transmission = make_float3(0.0f, 0.0f, 0.0f);
if (ls->shader & SHADER_EXCLUDE_SCATTER)
- eval->scatter = make_float3(0.0f, 0.0f, 0.0f);
+ eval->volume = make_float3(0.0f, 0.0f, 0.0f);
}
#endif
diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h
index e50fa07a885..187e8340c82 100644
--- a/intern/cycles/kernel/kernel_passes.h
+++ b/intern/cycles/kernel/kernel_passes.h
@@ -249,8 +249,6 @@ ccl_device_inline void kernel_write_data_passes(KernelGlobals *kg,
L->color_glossy += shader_bsdf_glossy(kg, sd) * throughput;
if (light_flag & PASSMASK_COMPONENT(TRANSMISSION))
L->color_transmission += shader_bsdf_transmission(kg, sd) * throughput;
- if (light_flag & PASSMASK_COMPONENT(SUBSURFACE))
- L->color_subsurface += shader_bsdf_subsurface(kg, sd) * throughput;
if (light_flag & PASSMASK(MIST)) {
/* bring depth into 0..1 range */
@@ -296,11 +294,8 @@ ccl_device_inline void kernel_write_light_passes(KernelGlobals *kg,
if (light_flag & PASSMASK(TRANSMISSION_INDIRECT))
kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_indirect,
L->indirect_transmission);
- if (light_flag & PASSMASK(SUBSURFACE_INDIRECT))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_indirect,
- L->indirect_subsurface);
if (light_flag & PASSMASK(VOLUME_INDIRECT))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_volume_indirect, L->indirect_scatter);
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_volume_indirect, L->indirect_volume);
if (light_flag & PASSMASK(DIFFUSE_DIRECT))
kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_direct, L->direct_diffuse);
if (light_flag & PASSMASK(GLOSSY_DIRECT))
@@ -308,11 +303,8 @@ ccl_device_inline void kernel_write_light_passes(KernelGlobals *kg,
if (light_flag & PASSMASK(TRANSMISSION_DIRECT))
kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_direct,
L->direct_transmission);
- if (light_flag & PASSMASK(SUBSURFACE_DIRECT))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_direct,
- L->direct_subsurface);
if (light_flag & PASSMASK(VOLUME_DIRECT))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_volume_direct, L->direct_scatter);
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_volume_direct, L->direct_volume);
if (light_flag & PASSMASK(EMISSION))
kernel_write_pass_float3(buffer + kernel_data.film.pass_emission, L->emission);
@@ -328,8 +320,6 @@ ccl_device_inline void kernel_write_light_passes(KernelGlobals *kg,
if (light_flag & PASSMASK(TRANSMISSION_COLOR))
kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_color,
L->color_transmission);
- if (light_flag & PASSMASK(SUBSURFACE_COLOR))
- kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_color, L->color_subsurface);
if (light_flag & PASSMASK(SHADOW)) {
float4 shadow = L->shadow;
shadow.w = kernel_data.film.pass_shadow_scale;
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index d03faff4242..9120fa7c3f3 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -901,7 +901,8 @@ ccl_device float3 shader_bsdf_diffuse(KernelGlobals *kg, ShaderData *sd)
for (int i = 0; i < sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
- if (CLOSURE_IS_BSDF_DIFFUSE(sc->type))
+ if (CLOSURE_IS_BSDF_DIFFUSE(sc->type) || CLOSURE_IS_BSSRDF(sc->type) ||
+ CLOSURE_IS_BSDF_BSSRDF(sc->type))
eval += sc->weight;
}
@@ -936,20 +937,6 @@ ccl_device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd)
return eval;
}
-ccl_device float3 shader_bsdf_subsurface(KernelGlobals *kg, ShaderData *sd)
-{
- float3 eval = make_float3(0.0f, 0.0f, 0.0f);
-
- for (int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
-
- if (CLOSURE_IS_BSSRDF(sc->type) || CLOSURE_IS_BSDF_BSSRDF(sc->type))
- eval += sc->weight;
- }
-
- return eval;
-}
-
ccl_device float3 shader_bsdf_average_normal(KernelGlobals *kg, ShaderData *sd)
{
float3 N = make_float3(0.0f, 0.0f, 0.0f);
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 68cb1e974f0..75187ad1bd2 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -220,7 +220,6 @@ typedef enum ShaderEvalType {
SHADER_EVAL_DIFFUSE_COLOR,
SHADER_EVAL_GLOSSY_COLOR,
SHADER_EVAL_TRANSMISSION_COLOR,
- SHADER_EVAL_SUBSURFACE_COLOR,
SHADER_EVAL_EMISSION,
SHADER_EVAL_AOV_COLOR,
SHADER_EVAL_AOV_VALUE,
@@ -232,7 +231,6 @@ typedef enum ShaderEvalType {
SHADER_EVAL_DIFFUSE,
SHADER_EVAL_GLOSSY,
SHADER_EVAL_TRANSMISSION,
- SHADER_EVAL_SUBSURFACE,
/* extra */
SHADER_EVAL_ENVIRONMENT,
@@ -392,9 +390,6 @@ typedef enum PassType {
PASS_TRANSMISSION_DIRECT,
PASS_TRANSMISSION_INDIRECT,
PASS_TRANSMISSION_COLOR,
- PASS_SUBSURFACE_DIRECT,
- PASS_SUBSURFACE_INDIRECT,
- PASS_SUBSURFACE_COLOR,
PASS_VOLUME_DIRECT,
PASS_VOLUME_INDIRECT,
/* No Scatter color since it's tricky to define what it would even mean. */
@@ -445,23 +440,20 @@ typedef enum eBakePassFilter {
BAKE_FILTER_DIFFUSE = (1 << 3),
BAKE_FILTER_GLOSSY = (1 << 4),
BAKE_FILTER_TRANSMISSION = (1 << 5),
- BAKE_FILTER_SUBSURFACE = (1 << 6),
- BAKE_FILTER_EMISSION = (1 << 7),
- BAKE_FILTER_AO = (1 << 8),
+ BAKE_FILTER_EMISSION = (1 << 6),
+ BAKE_FILTER_AO = (1 << 7),
} eBakePassFilter;
typedef enum BakePassFilterCombos {
BAKE_FILTER_COMBINED = (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT | BAKE_FILTER_DIFFUSE |
- BAKE_FILTER_GLOSSY | BAKE_FILTER_TRANSMISSION | BAKE_FILTER_SUBSURFACE |
- BAKE_FILTER_EMISSION | BAKE_FILTER_AO),
+ BAKE_FILTER_GLOSSY | BAKE_FILTER_TRANSMISSION | BAKE_FILTER_EMISSION |
+ BAKE_FILTER_AO),
BAKE_FILTER_DIFFUSE_DIRECT = (BAKE_FILTER_DIRECT | BAKE_FILTER_DIFFUSE),
BAKE_FILTER_GLOSSY_DIRECT = (BAKE_FILTER_DIRECT | BAKE_FILTER_GLOSSY),
BAKE_FILTER_TRANSMISSION_DIRECT = (BAKE_FILTER_DIRECT | BAKE_FILTER_TRANSMISSION),
- BAKE_FILTER_SUBSURFACE_DIRECT = (BAKE_FILTER_DIRECT | BAKE_FILTER_SUBSURFACE),
BAKE_FILTER_DIFFUSE_INDIRECT = (BAKE_FILTER_INDIRECT | BAKE_FILTER_DIFFUSE),
BAKE_FILTER_GLOSSY_INDIRECT = (BAKE_FILTER_INDIRECT | BAKE_FILTER_GLOSSY),
BAKE_FILTER_TRANSMISSION_INDIRECT = (BAKE_FILTER_INDIRECT | BAKE_FILTER_TRANSMISSION),
- BAKE_FILTER_SUBSURFACE_INDIRECT = (BAKE_FILTER_INDIRECT | BAKE_FILTER_SUBSURFACE),
} BakePassFilterCombos;
typedef enum DenoiseFlag {
@@ -471,9 +463,7 @@ typedef enum DenoiseFlag {
DENOISING_CLEAN_GLOSSY_IND = (1 << 3),
DENOISING_CLEAN_TRANSMISSION_DIR = (1 << 4),
DENOISING_CLEAN_TRANSMISSION_IND = (1 << 5),
- DENOISING_CLEAN_SUBSURFACE_DIR = (1 << 6),
- DENOISING_CLEAN_SUBSURFACE_IND = (1 << 7),
- DENOISING_CLEAN_ALL_PASSES = (1 << 8) - 1,
+ DENOISING_CLEAN_ALL_PASSES = (1 << 6) - 1,
} DenoiseFlag;
#ifdef __KERNEL_DEBUG__
@@ -493,8 +483,7 @@ typedef ccl_addr_space struct PathRadianceState {
float3 diffuse;
float3 glossy;
float3 transmission;
- float3 subsurface;
- float3 scatter;
+ float3 volume;
float3 direct;
#endif
@@ -517,19 +506,16 @@ typedef ccl_addr_space struct PathRadiance {
float3 color_diffuse;
float3 color_glossy;
float3 color_transmission;
- float3 color_subsurface;
float3 direct_diffuse;
float3 direct_glossy;
float3 direct_transmission;
- float3 direct_subsurface;
- float3 direct_scatter;
+ float3 direct_volume;
float3 indirect_diffuse;
float3 indirect_glossy;
float3 indirect_transmission;
- float3 indirect_subsurface;
- float3 indirect_scatter;
+ float3 indirect_volume;
float4 shadow;
float mist;
@@ -583,8 +569,7 @@ typedef struct BsdfEval {
float3 glossy;
float3 transmission;
float3 transparent;
- float3 subsurface;
- float3 scatter;
+ float3 volume;
#endif
#ifdef __SHADOW_TRICKS__
float3 sum_no_mis;
@@ -1214,18 +1199,15 @@ typedef struct KernelFilm {
int pass_diffuse_color;
int pass_glossy_color;
int pass_transmission_color;
- int pass_subsurface_color;
int pass_diffuse_indirect;
int pass_glossy_indirect;
int pass_transmission_indirect;
- int pass_subsurface_indirect;
int pass_volume_indirect;
int pass_diffuse_direct;
int pass_glossy_direct;
int pass_transmission_direct;
- int pass_subsurface_direct;
int pass_volume_direct;
int pass_emission;
@@ -1252,7 +1234,6 @@ typedef struct KernelFilm {
int pass_aov_color;
int pass_aov_value;
int pad1;
- int pad2;
/* XYZ to rendering color space transform. float4 instead of float3 to
* ensure consistent padding/alignment across devices. */
diff --git a/intern/cycles/kernel/shaders/node_vector_rotate.osl b/intern/cycles/kernel/shaders/node_vector_rotate.osl
index a049ee92dbc..533aa7bbe13 100644
--- a/intern/cycles/kernel/shaders/node_vector_rotate.osl
+++ b/intern/cycles/kernel/shaders/node_vector_rotate.osl
@@ -28,31 +28,6 @@ shader node_vector_rotate(string type = "axis",
if (type == "euler_xyz") {
VectorOut = transform(euler_to_mat(Rotation), VectorIn - Center) + Center;
}
- else if (type == "euler_xzy") {
- VectorOut = transform(euler_to_mat(point(-Rotation[0], -Rotation[2], -Rotation[1])),
- VectorIn - Center) +
- Center;
- }
- else if (type == "euler_yxz") {
- VectorOut = transform(euler_to_mat(point(-Rotation[1], -Rotation[0], -Rotation[2])),
- VectorIn - Center) +
- Center;
- }
- else if (type == "euler_yzx") {
- VectorOut = transform(euler_to_mat(point(Rotation[1], Rotation[2], Rotation[0])),
- VectorIn - Center) +
- Center;
- }
- else if (type == "euler_zxy") {
- VectorOut = transform(euler_to_mat(point(Rotation[2], Rotation[0], Rotation[1])),
- VectorIn - Center) +
- Center;
- }
- else if (type == "euler_zyx") {
- VectorOut = transform(euler_to_mat(point(-Rotation[2], -Rotation[1], -Rotation[0])),
- VectorIn - Center) +
- Center;
- }
else if (type == "x_axis") {
VectorOut = rotate(VectorIn - Center, Angle, point(0.0), vector(1.0, 0.0, 0.0)) + Center;
}
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index cff2b964c51..38f12ebdf48 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -358,11 +358,6 @@ typedef enum NodeVectorRotateType {
NODE_VECTOR_ROTATE_TYPE_AXIS_Y,
NODE_VECTOR_ROTATE_TYPE_AXIS_Z,
NODE_VECTOR_ROTATE_TYPE_EULER_XYZ,
- NODE_VECTOR_ROTATE_TYPE_EULER_XZY,
- NODE_VECTOR_ROTATE_TYPE_EULER_YXZ,
- NODE_VECTOR_ROTATE_TYPE_EULER_YZX,
- NODE_VECTOR_ROTATE_TYPE_EULER_ZXY,
- NODE_VECTOR_ROTATE_TYPE_EULER_ZYX,
} NodeVectorRotateType;
typedef enum NodeVectorTransformType {
@@ -532,6 +527,7 @@ typedef enum ClosureType {
CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID,
CLOSURE_BSDF_PRINCIPLED_SHEEN_ID,
CLOSURE_BSDF_DIFFUSE_TOON_ID,
+ CLOSURE_BSDF_TRANSLUCENT_ID,
/* Glossy */
CLOSURE_BSDF_REFLECTION_ID,
@@ -554,7 +550,6 @@ typedef enum ClosureType {
CLOSURE_BSDF_HAIR_REFLECTION_ID,
/* Transmission */
- CLOSURE_BSDF_TRANSLUCENT_ID,
CLOSURE_BSDF_REFRACTION_ID,
CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID,
CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID,
@@ -595,12 +590,12 @@ typedef enum ClosureType {
/* watch this, being lazy with memory usage */
#define CLOSURE_IS_BSDF(type) (type <= CLOSURE_BSDF_TRANSPARENT_ID)
#define CLOSURE_IS_BSDF_DIFFUSE(type) \
- (type >= CLOSURE_BSDF_DIFFUSE_ID && type <= CLOSURE_BSDF_DIFFUSE_TOON_ID)
+ (type >= CLOSURE_BSDF_DIFFUSE_ID && type <= CLOSURE_BSDF_TRANSLUCENT_ID)
#define CLOSURE_IS_BSDF_GLOSSY(type) \
((type >= CLOSURE_BSDF_REFLECTION_ID && type <= CLOSURE_BSDF_HAIR_REFLECTION_ID) || \
(type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID))
#define CLOSURE_IS_BSDF_TRANSMISSION(type) \
- (type >= CLOSURE_BSDF_TRANSLUCENT_ID && type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID)
+ (type >= CLOSURE_BSDF_REFRACTION_ID && type <= CLOSURE_BSDF_HAIR_TRANSMISSION_ID)
#define CLOSURE_IS_BSDF_BSSRDF(type) \
(type == CLOSURE_BSDF_BSSRDF_ID || type == CLOSURE_BSDF_BSSRDF_PRINCIPLED_ID)
#define CLOSURE_IS_BSDF_SINGULAR(type) \
diff --git a/intern/cycles/kernel/svm/svm_vector_rotate.h b/intern/cycles/kernel/svm/svm_vector_rotate.h
index c7923e10c53..903a9c1d1db 100644
--- a/intern/cycles/kernel/svm/svm_vector_rotate.h
+++ b/intern/cycles/kernel/svm/svm_vector_rotate.h
@@ -35,26 +35,8 @@ ccl_device void svm_node_vector_rotate(ShaderData *sd,
float3 center = stack_load_float3(stack, center_stack_offset);
float3 result = make_float3(0.0f, 0.0f, 0.0f);
- if (type != NODE_VECTOR_ROTATE_TYPE_AXIS && type != NODE_VECTOR_ROTATE_TYPE_AXIS_X &&
- type != NODE_VECTOR_ROTATE_TYPE_AXIS_Y && type != NODE_VECTOR_ROTATE_TYPE_AXIS_Z) {
+ if (type == NODE_VECTOR_ROTATE_TYPE_EULER_XYZ) {
float3 rotation = stack_load_float3(stack, rotation_stack_offset); // Default XYZ.
- switch (type) {
- case NODE_VECTOR_ROTATE_TYPE_EULER_XZY:
- rotation = make_float3(-rotation.x, -rotation.z, -rotation.y);
- break;
- case NODE_VECTOR_ROTATE_TYPE_EULER_YXZ:
- rotation = make_float3(-rotation.y, -rotation.x, -rotation.z);
- break;
- case NODE_VECTOR_ROTATE_TYPE_EULER_YZX:
- rotation = make_float3(rotation.y, rotation.z, rotation.x);
- break;
- case NODE_VECTOR_ROTATE_TYPE_EULER_ZXY:
- rotation = make_float3(rotation.z, rotation.x, rotation.y);
- break;
- case NODE_VECTOR_ROTATE_TYPE_EULER_ZYX:
- rotation = make_float3(-rotation.z, -rotation.y, -rotation.x);
- break;
- }
Transform rotationTransform = euler_to_transform(rotation);
result = transform_direction(&rotationTransform, vector - center) + center;
}
@@ -75,7 +57,7 @@ ccl_device void svm_node_vector_rotate(ShaderData *sd,
break;
}
float angle = stack_load_float(stack, angle_stack_offset);
- result = is_zero(axis) ? vector : rotate_around_axis(vector - center, axis, angle) + center;
+ result = len(axis) ? rotate_around_axis(vector - center, axis, angle) + center : vector;
}
/* Output */
diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp
index 9613da7c152..11ccfc95293 100644
--- a/intern/cycles/render/bake.cpp
+++ b/intern/cycles/render/bake.cpp
@@ -285,8 +285,6 @@ int BakeManager::shader_type_to_pass_filter(ShaderEvalType type, const int pass_
return BAKE_FILTER_GLOSSY | component_flags;
case SHADER_EVAL_TRANSMISSION:
return BAKE_FILTER_TRANSMISSION | component_flags;
- case SHADER_EVAL_SUBSURFACE:
- return BAKE_FILTER_SUBSURFACE | component_flags;
case SHADER_EVAL_COMBINED:
return pass_filter;
default:
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index 00356790261..172ea3dd31b 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -155,7 +155,6 @@ void Pass::add(PassType type, vector<Pass> &passes, const char *name)
case PASS_DIFFUSE_COLOR:
case PASS_GLOSSY_COLOR:
case PASS_TRANSMISSION_COLOR:
- case PASS_SUBSURFACE_COLOR:
pass.components = 4;
break;
case PASS_DIFFUSE_DIRECT:
@@ -176,12 +175,6 @@ void Pass::add(PassType type, vector<Pass> &passes, const char *name)
pass.exposure = true;
pass.divide_type = PASS_TRANSMISSION_COLOR;
break;
- case PASS_SUBSURFACE_DIRECT:
- case PASS_SUBSURFACE_INDIRECT:
- pass.components = 4;
- pass.exposure = true;
- pass.divide_type = PASS_SUBSURFACE_COLOR;
- break;
case PASS_VOLUME_DIRECT:
case PASS_VOLUME_INDIRECT:
pass.components = 4;
@@ -442,9 +435,6 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
case PASS_TRANSMISSION_COLOR:
kfilm->pass_transmission_color = kfilm->pass_stride;
break;
- case PASS_SUBSURFACE_COLOR:
- kfilm->pass_subsurface_color = kfilm->pass_stride;
- break;
case PASS_DIFFUSE_INDIRECT:
kfilm->pass_diffuse_indirect = kfilm->pass_stride;
break;
@@ -454,9 +444,6 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
case PASS_TRANSMISSION_INDIRECT:
kfilm->pass_transmission_indirect = kfilm->pass_stride;
break;
- case PASS_SUBSURFACE_INDIRECT:
- kfilm->pass_subsurface_indirect = kfilm->pass_stride;
- break;
case PASS_VOLUME_INDIRECT:
kfilm->pass_volume_indirect = kfilm->pass_stride;
break;
@@ -469,9 +456,6 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
case PASS_TRANSMISSION_DIRECT:
kfilm->pass_transmission_direct = kfilm->pass_stride;
break;
- case PASS_SUBSURFACE_DIRECT:
- kfilm->pass_subsurface_direct = kfilm->pass_stride;
- break;
case PASS_VOLUME_DIRECT:
kfilm->pass_volume_direct = kfilm->pass_stride;
break;
@@ -521,7 +505,7 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kfilm->use_display_exposure = pass.exposure && (kfilm->exposure != 1.0f);
}
else if (pass.type == PASS_DIFFUSE_COLOR || pass.type == PASS_TRANSMISSION_COLOR ||
- pass.type == PASS_GLOSSY_COLOR || pass.type == PASS_SUBSURFACE_COLOR) {
+ pass.type == PASS_GLOSSY_COLOR) {
kfilm->display_divide_pass_stride = kfilm->pass_stride;
}
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 9c909c2131f..f975ef993fc 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -6165,11 +6165,6 @@ NODE_DEFINE(VectorRotateNode)
type_enum.insert("y_axis", NODE_VECTOR_ROTATE_TYPE_AXIS_Y);
type_enum.insert("z_axis", NODE_VECTOR_ROTATE_TYPE_AXIS_Z);
type_enum.insert("euler_xyz", NODE_VECTOR_ROTATE_TYPE_EULER_XYZ);
- type_enum.insert("euler_xzy", NODE_VECTOR_ROTATE_TYPE_EULER_XZY);
- type_enum.insert("euler_yxz", NODE_VECTOR_ROTATE_TYPE_EULER_YXZ);
- type_enum.insert("euler_yzx", NODE_VECTOR_ROTATE_TYPE_EULER_YZX);
- type_enum.insert("euler_zxy", NODE_VECTOR_ROTATE_TYPE_EULER_ZXY);
- type_enum.insert("euler_zyx", NODE_VECTOR_ROTATE_TYPE_EULER_ZYX);
SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_ROTATE_TYPE_AXIS);
SOCKET_IN_VECTOR(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f));
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index acf9ca68889..ae0a2cf863a 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -908,9 +908,6 @@ void Session::set_samples(int samples)
params.samples = samples;
tile_manager.set_samples(samples);
- {
- thread_scoped_lock pause_lock(pause_mutex);
- }
pause_cond.notify_all();
}
}
@@ -946,6 +943,15 @@ void Session::set_denoising(bool denoising, bool optix_denoising)
tile_manager.schedule_denoising = denoising && !buffers;
}
+void Session::set_denoising_start_sample(int sample)
+{
+ if (sample != params.denoising_start_sample) {
+ params.denoising_start_sample = sample;
+
+ pause_cond.notify_all();
+ }
+}
+
void Session::wait()
{
if (session_thread) {
@@ -1110,8 +1116,8 @@ void Session::denoise()
return;
}
- /* It can happen that denoising was already enabled, but the scene still needs an update. */
- if (scene->film->need_update || !scene->film->denoising_data_offset) {
+ /* Do not denoise viewport until the sample at which denoising should start is reached. */
+ if (!params.background && tile_manager.state.sample < params.denoising_start_sample) {
return;
}
@@ -1122,6 +1128,11 @@ void Session::denoise()
return;
}
+ /* It can happen that denoising was already enabled, but the scene still needs an update. */
+ if (scene->film->need_update || !scene->film->denoising_data_offset) {
+ return;
+ }
+
/* Add separate denoising task. */
DeviceTask task(DeviceTask::DENOISE);
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index 3ef2b70879a..40ec3979afd 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -53,6 +53,7 @@ class SessionParams {
int2 tile_size;
TileOrder tile_order;
int start_resolution;
+ int denoising_start_sample;
int pixel_size;
int threads;
@@ -85,6 +86,7 @@ class SessionParams {
samples = 1024;
tile_size = make_int2(64, 64);
start_resolution = INT_MAX;
+ denoising_start_sample = 0;
pixel_size = 1;
threads = 0;
@@ -109,9 +111,10 @@ class SessionParams {
bool modified(const SessionParams &params)
{
return !(device == params.device && background == params.background &&
- progressive_refine == params.progressive_refine
- /* && samples == params.samples */
- && progressive == params.progressive && experimental == params.experimental &&
+ progressive_refine == params.progressive_refine &&
+ /* samples == params.samples && denoising_start_sample ==
+ params.denoising_start_sample && */
+ progressive == params.progressive && experimental == params.experimental &&
tile_size == params.tile_size && start_resolution == params.start_resolution &&
pixel_size == params.pixel_size && threads == params.threads &&
use_profiling == params.use_profiling &&
@@ -152,9 +155,10 @@ class Session {
bool ready_to_reset();
void reset(BufferParams &params, int samples);
- void set_samples(int samples);
void set_pause(bool pause);
+ void set_samples(int samples);
void set_denoising(bool denoising, bool optix_denoising);
+ void set_denoising_start_sample(int sample);
bool update_scene();
bool load_kernels(bool lock_scene = true);
diff --git a/intern/mantaflow/CMakeLists.txt b/intern/mantaflow/CMakeLists.txt
index b2a0ab30a0c..d9b64b3a199 100644
--- a/intern/mantaflow/CMakeLists.txt
+++ b/intern/mantaflow/CMakeLists.txt
@@ -28,6 +28,8 @@ add_definitions(-DWITH_FLUID=1)
if(WITH_OPENVDB)
add_definitions(-DOPENVDB=1)
add_definitions(-DOPENVDB_STATICLIB)
+else()
+ add_definitions(-DOPENVDB=0)
endif()
if(WIN32)
diff --git a/intern/opencolorio/gpu_shader_display_transform.glsl b/intern/opencolorio/gpu_shader_display_transform.glsl
index f7c64244dd6..61da755f02f 100644
--- a/intern/opencolorio/gpu_shader_display_transform.glsl
+++ b/intern/opencolorio/gpu_shader_display_transform.glsl
@@ -163,6 +163,7 @@ vec4 OCIO_ProcessColor(vec4 col, vec4 col_overlay, vec2 noise_uv)
col = OCIO_to_display_linear_with_look(col, lut3d_texture);
if (overlay) {
+ col = clamp(col, 0.0, 1.0);
col *= 1.0 - col_overlay.a;
col += col_overlay; /* Assumed unassociated alpha. */
}
diff --git a/release/datafiles/userdef/userdef_default_theme.c b/release/datafiles/userdef/userdef_default_theme.c
index df8fde40f3c..3ad2da99b9f 100644
--- a/release/datafiles/userdef/userdef_default_theme.c
+++ b/release/datafiles/userdef/userdef_default_theme.c
@@ -238,9 +238,9 @@ const bTheme U_theme_default = {
.menu_shadow_fac = 0.3f,
.menu_shadow_width = 4,
.editor_outline = RGBA(0x1f1f1fff),
- .widget_text_cursor = RGBA(0x3399e6ff),
.icon_alpha = 1.0f,
.icon_saturation = 0.5f,
+ .widget_text_cursor = RGBA(0x3399e6ff),
.xaxis = RGBA(0xff3352ff),
.yaxis = RGBA(0x8bdc00ff),
.zaxis = RGBA(0x2890ffff),
@@ -324,11 +324,11 @@ const bTheme U_theme_default = {
.edge_facesel = RGBA(0x4b4b4bff),
.edge_crease = RGBA(0xcc0099ff),
.edge_bevel = RGBA(0x00a5ffff),
- .face = RGBA(0xffffff12),
- .face_select = RGBA(0xffa5526c),
- .face_dot = RGBA(0xff8a00ff),
+ .face = RGBA(0xffffff02),
+ .face_select = RGBA(0xffa5522e),
.face_back = RGBA(0xff0000b3),
.face_front = RGBA(0x0000ffb3),
+ .face_dot = RGBA(0xff8a00ff),
.extra_edge_len = RGBA(0x150806ff),
.extra_edge_angle = RGBA(0x4d4d00ff),
.extra_face_angle = RGBA(0x0000ccff),
@@ -363,7 +363,7 @@ const bTheme U_theme_default = {
.outline_width = 1,
.obcenter_dia = 6,
.facedot_size = 3,
- .editmesh_active = RGBA(0xffffff80),
+ .editmesh_active = RGBA(0xffffff33),
.clipping_border_3d = RGBA(0x313131ff),
.bundle_solid = RGBA(0xc8c8c8ff),
.camera_path = RGBA(0x000000ff),
@@ -435,6 +435,8 @@ const bTheme U_theme_default = {
.vertex_select = RGBA(0xff8500ff),
.cframe = RGBA(0x5680c2ff),
.time_scrub_background = RGBA(0x292929e6),
+ .time_marker_line = RGBA(0x00000060),
+ .time_marker_line_selected = RGBA(0xffffff60),
.lastsel_point = RGBA(0xffffffff),
.handle_auto = RGBA(0x909000ff),
.handle_vect = RGBA(0x409030ff),
@@ -490,7 +492,7 @@ const bTheme U_theme_default = {
.info_property_text = RGBA(0xffffffff),
.info_operator = RGBA(0x3ace87ff),
.info_operator_text = RGBA(0xffffffff),
- },
+ },
.space_action = {
.back = RGBA(0x42424200),
.title = RGBA(0xeeeeeeff),
@@ -526,6 +528,8 @@ const bTheme U_theme_default = {
.strip_select = RGBA(0xff8c00cc),
.cframe = RGBA(0x5680c2ff),
.time_scrub_background = RGBA(0x292929e6),
+ .time_marker_line = RGBA(0x00000060),
+ .time_marker_line_selected = RGBA(0xffffff60),
.ds_channel = RGBA(0x0f2c4d24),
.ds_subchannel = RGBA(0x143e6624),
.ds_ipoline = RGBA(0x94e575cc),
@@ -580,6 +584,8 @@ const bTheme U_theme_default = {
.strip_select = RGBA(0xff8c00ff),
.cframe = RGBA(0x5680c2ff),
.time_scrub_background = RGBA(0x292929e6),
+ .time_marker_line = RGBA(0x00000060),
+ .time_marker_line_selected = RGBA(0xffffff60),
.ds_channel = RGBA(0x5a85b2ff),
.ds_subchannel = RGBA(0x7d98b3ff),
.keyborder = RGBA(0x000000ff),
@@ -628,6 +634,8 @@ const bTheme U_theme_default = {
.bone_pose = RGBA(0x50c8ff50),
.cframe = RGBA(0x5680c2ff),
.time_scrub_background = RGBA(0x292929e6),
+ .time_marker_line = RGBA(0x00000060),
+ .time_marker_line_selected = RGBA(0xffffff60),
.vertex_size = 3,
.outline_width = 1,
.facedot_size = 4,
@@ -909,6 +917,8 @@ const bTheme U_theme_default = {
.strip_select = RGBA(0xff8c00ff),
.cframe = RGBA(0x5680c2ff),
.time_scrub_background = RGBA(0x292929e6),
+ .time_marker_line = RGBA(0x00000060),
+ .time_marker_line_selected = RGBA(0xffffff60),
.handle_auto = RGBA(0x909000ff),
.handle_align = RGBA(0x803060ff),
.handle_sel_auto = RGBA(0xf0ff40ff),
diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
index 20c5c869e83..0195232a59d 100644
--- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
+++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
@@ -3404,7 +3404,8 @@ def km_object_non_modal(params):
)
items.extend([
-
+ ("object.mode_set",{"type": 'THREE', "value": 'PRESS'},
+ {"properties": [("mode", 'POSE')]}),
("object.mode_set_with_submode",{"type": 'ONE', "value": 'PRESS'},
{"properties": [("mode", 'EDIT'), ("mesh_select_mode", {'VERT'})]}),
("object.mode_set_with_submode",{"type": 'TWO', "value": 'PRESS'},
@@ -3423,7 +3424,6 @@ def km_object_non_modal(params):
{"properties": [("mode", 'WEIGHT_PAINT')]}),
("object.mode_set",{"type": 'EIGHT', "value": 'PRESS'},
{"properties": [("mode", 'TEXTURE_PAINT')]}),
-
("object.mode_set",{"type": 'TWO', "value": 'PRESS'},
{"properties": [("mode", 'EDIT_GPENCIL')]}),
("object.mode_set",{"type": 'THREE', "value": 'PRESS'},
@@ -3432,9 +3432,7 @@ def km_object_non_modal(params):
{"properties": [("mode", 'PAINT_GPENCIL')]}),
("object.mode_set",{"type": 'FIVE', "value": 'PRESS'},
{"properties": [("mode", 'WEIGHT_GPENCIL')]}),
-
- ("object.mode_set",{"type": 'THREE', "value": 'PRESS'},
- {"properties": [("mode", 'POSE')]})
+
])
return keymap
diff --git a/release/scripts/startup/bl_ui/properties_view_layer.py b/release/scripts/startup/bl_ui/properties_view_layer.py
index 121b8f2f401..25244b7f065 100644
--- a/release/scripts/startup/bl_ui/properties_view_layer.py
+++ b/release/scripts/startup/bl_ui/properties_view_layer.py
@@ -59,14 +59,25 @@ class VIEWLAYER_PT_eevee_layer_passes(ViewLayerButtonsPanel, Panel):
COMPAT_ENGINES = {'BLENDER_EEVEE'}
def draw(self, context):
- layout = self.layout
+ pass
- layout.use_property_split = True
- flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
+class VIEWLAYER_PT_eevee_layer_passes_data(ViewLayerButtonsPanel, Panel):
+ bl_label = "Data"
+ bl_parent_id = "VIEWLAYER_PT_eevee_layer_passes"
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ scene = context.scene
+ rd = scene.render
view_layer = context.view_layer
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
col = flow.column()
col.prop(view_layer, "use_pass_combined")
col = flow.column()
@@ -75,17 +86,83 @@ class VIEWLAYER_PT_eevee_layer_passes(ViewLayerButtonsPanel, Panel):
col.prop(view_layer, "use_pass_mist")
col = flow.column()
col.prop(view_layer, "use_pass_normal")
- col = flow.column()
- col.prop(view_layer, "use_pass_ambient_occlusion")
- col = flow.column()
- col.prop(view_layer, "use_pass_subsurface_direct", text="Subsurface Direct")
- col = flow.column()
- col.prop(view_layer, "use_pass_subsurface_color", text="Subsurface Color")
+class VIEWLAYER_PT_eevee_layer_passes_light(ViewLayerButtonsPanel, Panel):
+ bl_label = "Light"
+ bl_parent_id = "VIEWLAYER_PT_eevee_layer_passes"
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ view_layer = context.view_layer
+ view_layer_eevee = view_layer.eevee
+ scene = context.scene
+ scene_eevee = scene.eevee
+
+ split = layout.split(factor=0.35)
+ split.use_property_split = False
+ split.label(text="Diffuse")
+ row = split.row(align=True)
+ row.prop(view_layer, "use_pass_diffuse_direct", text="Light", toggle=True)
+ row.prop(view_layer, "use_pass_diffuse_color", text="Color", toggle=True)
+
+ split = layout.split(factor=0.35)
+ split.use_property_split = False
+ split.label(text="Specular")
+ row = split.row(align=True)
+ row.prop(view_layer, "use_pass_glossy_direct", text="Light", toggle=True)
+ row.prop(view_layer, "use_pass_glossy_color", text="Color", toggle=True)
+
+ split = layout.split(factor=0.35)
+ split.use_property_split = False
+ split.label(text="Volume")
+ row = split.row(align=True)
+ row.prop(view_layer_eevee, "use_pass_volume_transmittance", text="Transmittance", toggle=True)
+ row.prop(view_layer_eevee, "use_pass_volume_scatter", text="Scatter", toggle=True)
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
+
+ col = layout.column(align=True)
+ col.prop(view_layer, "use_pass_emit", text="Emission")
+ col.prop(view_layer, "use_pass_environment")
+ col.prop(view_layer, "use_pass_shadow")
+ row = col.row()
+ row.prop(view_layer, "use_pass_ambient_occlusion", text="Ambient Occlusion")
+ row.active = scene_eevee.use_gtao
+
+
+class VIEWLAYER_PT_eevee_layer_passes_effects(ViewLayerButtonsPanel, Panel):
+ bl_label = "Effects"
+ bl_parent_id = "VIEWLAYER_PT_eevee_layer_passes"
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
+
+ view_layer = context.view_layer
+ view_layer_eevee = view_layer.eevee
+ scene = context.scene
+ scene_eevee = scene.eevee
+
+ col = flow.column()
+ col.prop(view_layer_eevee, "use_pass_bloom", text="Bloom")
+ col.active = scene_eevee.use_bloom
+
classes = (
VIEWLAYER_PT_layer,
VIEWLAYER_PT_eevee_layer_passes,
+ VIEWLAYER_PT_eevee_layer_passes_data,
+ VIEWLAYER_PT_eevee_layer_passes_light,
+ VIEWLAYER_PT_eevee_layer_passes_effects,
)
if __name__ == "__main__": # only for live edit.
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py
index 4dc724299f0..d2deb70d4a2 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_common.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py
@@ -216,29 +216,52 @@ class ToolSelectPanelHelper:
else:
return 0
+ # tool flattening
+ #
+ # usually 'tools' is already expanded into ToolDef
+ # but when registering a tool, this can still be a function
+ # (_tools_flatten is usually called with cls.tools_from_context(context)
+ # [that already yields from the function])
+ # so if item is still a function (e.g._defs_XXX.generate_from_brushes)
+ # seems like we cannot expand here (have no context yet)
+ # if we yield None here, this will risk running into duplicate tool bl_idname [in register_tool()]
+ # but still better than erroring out
@staticmethod
def _tools_flatten(tools):
- for item in tools:
- if type(item) is tuple:
- yield from item
- else:
- # May be None.
- yield item
+ for item_parent in tools:
+ if item_parent is None:
+ yield None
+ for item in item_parent if (type(item_parent) is tuple) else (item_parent,):
+ if item is None or _item_is_fn(item):
+ yield None
+ else:
+ yield item
@staticmethod
def _tools_flatten_with_tool_index(tools):
- for item in tools:
- if type(item) is tuple:
- i = 0
- for sub_item in item:
- if sub_item is None:
- yield None, -1
- else:
- yield sub_item, i
- i += 1
- else:
- # May be None.
- yield item, -1
+ for item_parent in tools:
+ if item_parent is None:
+ yield None, -1
+ i = 0
+ for item in item_parent if (type(item_parent) is tuple) else (item_parent,):
+ if item is None or _item_is_fn(item):
+ yield None, -1
+ else:
+ yield item, i
+ i += 1
+
+ # Special internal function, gives use items that contain keymaps.
+ @staticmethod
+ def _tools_flatten_with_keymap(tools):
+ for item_parent in tools:
+ if item_parent is None:
+ continue
+ for item in item_parent if (type(item_parent) is tuple) else (item_parent,):
+ # skip None or generator function
+ if item is None or _item_is_fn(item):
+ continue
+ if item.keymap is not None:
+ yield item
@classmethod
def _tool_get_active(cls, context, space_type, mode, with_icon=False):
@@ -413,19 +436,6 @@ class ToolSelectPanelHelper:
keymap_fn[0](km)
keymap_fn[0] = km.name
- # Special internal function, gives use items that contain keymaps.
- @staticmethod
- def _tools_flatten_with_keymap(tools):
- for item_parent in tools:
- if item_parent is None:
- continue
- for item in item_parent if (type(item_parent) is tuple) else (item_parent,):
- # skip None or generator function
- if item is None or _item_is_fn(item):
- continue
- if item.keymap is not None:
- yield item
-
@classmethod
def register(cls):
wm = bpy.context.window_manager
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index cd1fc49ac8b..2541613d1e6 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -608,15 +608,6 @@ class _defs_edit_mesh:
region_type = context.region.type
if not extra:
- if props.offset_type == 'PERCENT':
- layout.prop(props, "offset_pct")
- else:
- offset_text = "Width"
- if props.offset_type == 'DEPTH':
- offset_text = "Depth"
- elif props.offset_type == 'OFFSET':
- offset_text = "Offset"
- layout.prop(props, "offset", text=offset_text)
if region_type == 'TOOL_HEADER':
layout.prop(props, "offset_type", text="")
else:
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 5ca6bbb20b7..e92490bcbdc 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -5415,6 +5415,7 @@ class VIEW3D_PT_shading_lighting(Panel):
col.prop(shading, "studiolight_rotate_z", text="Rotation")
col.prop(shading, "studiolight_intensity")
col.prop(shading, "studiolight_background_alpha")
+ col.prop(shading, "studiolight_background_blur")
col = split.column() # to align properly with above
elif shading.type == 'RENDERED':
@@ -5438,6 +5439,7 @@ class VIEW3D_PT_shading_lighting(Panel):
col.prop(shading, "studiolight_rotate_z", text="Rotation")
col.prop(shading, "studiolight_intensity")
col.prop(shading, "studiolight_background_alpha")
+ col.prop(shading, "studiolight_background_blur")
col = split.column() # to align properly with above
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 2b592c9e550..725c4c0712d 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -584,9 +584,6 @@ static void blf_draw_gl__start(FontBLF *font)
* in BLF_position (old ui_rasterpos_safe).
*/
- /* always bind the texture for the first glyph */
- font->tex_bind_state = 0;
-
if ((font->flags & (BLF_ROTATION | BLF_MATRIX | BLF_ASPECT)) == 0) {
return; /* glyphs will be translated individually and batched. */
}
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 25ea0770f8b..f0afe184233 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -84,16 +84,19 @@ static void blf_batch_draw_init(void)
{
GPUVertFormat format = {0};
g_batch.pos_loc = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- g_batch.tex_loc = GPU_vertformat_attr_add(&format, "tex", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
g_batch.col_loc = GPU_vertformat_attr_add(
&format, "col", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ g_batch.offset_loc = GPU_vertformat_attr_add(&format, "offset", GPU_COMP_I32, 1, GPU_FETCH_INT);
+ g_batch.glyph_size_loc = GPU_vertformat_attr_add(
+ &format, "glyph_size", GPU_COMP_I32, 2, GPU_FETCH_INT);
g_batch.verts = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_STREAM);
GPU_vertbuf_data_alloc(g_batch.verts, BLF_BATCH_DRAW_LEN_MAX);
GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.pos_loc, &g_batch.pos_step);
- GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.tex_loc, &g_batch.tex_step);
GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.col_loc, &g_batch.col_step);
+ GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.offset_loc, &g_batch.offset_step);
+ GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.glyph_size_loc, &g_batch.glyph_size_step);
g_batch.glyph_len = 0;
/* A dummy vbo containing 4 points, attribs are not used. */
@@ -177,6 +180,46 @@ void blf_batch_draw_begin(FontBLF *font)
}
}
+static GPUTexture *blf_batch_cache_texture_load(void)
+{
+ GlyphCacheBLF *gc = g_batch.glyph_cache;
+ BLI_assert(gc);
+ BLI_assert(gc->bitmap_len > 0);
+
+ if (gc->bitmap_len > gc->bitmap_len_landed) {
+ const int tex_width = GPU_texture_width(gc->texture);
+
+ int bitmap_len_landed = gc->bitmap_len_landed;
+ int remain = gc->bitmap_len - bitmap_len_landed;
+ int offset_x = bitmap_len_landed % tex_width;
+ int offset_y = bitmap_len_landed / tex_width;
+
+ /* TODO(germano): Update more than one row in a single call. */
+ while (remain) {
+ int remain_row = tex_width - offset_x;
+ int width = remain > remain_row ? remain_row : remain;
+ GPU_texture_update_sub(gc->texture,
+ GPU_DATA_UNSIGNED_BYTE,
+ &gc->bitmap_result[bitmap_len_landed],
+ offset_x,
+ offset_y,
+ 0,
+ width,
+ 1,
+ 0);
+
+ bitmap_len_landed += width;
+ remain -= width;
+ offset_x = 0;
+ offset_y += 1;
+ }
+
+ gc->bitmap_len_landed = bitmap_len_landed;
+ }
+
+ return gc->texture;
+}
+
void blf_batch_draw(void)
{
if (g_batch.glyph_len == 0) {
@@ -190,7 +233,8 @@ void blf_batch_draw(void)
/* We need to flush widget base first to ensure correct ordering. */
UI_widgetbase_draw_cache_flush();
- GPU_texture_bind(g_batch.tex_bind_state, 0);
+ GPUTexture *texture = blf_batch_cache_texture_load();
+ GPU_texture_bind(texture, 0);
GPU_vertbuf_data_len_set(g_batch.verts, g_batch.glyph_len);
GPU_vertbuf_use(g_batch.verts); /* send data */
@@ -202,8 +246,9 @@ void blf_batch_draw(void)
/* restart to 1st vertex data pointers */
GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.pos_loc, &g_batch.pos_step);
- GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.tex_loc, &g_batch.tex_step);
GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.col_loc, &g_batch.col_step);
+ GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.offset_loc, &g_batch.offset_step);
+ GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.glyph_size_loc, &g_batch.glyph_size_step);
g_batch.glyph_len = 0;
}
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 80d43a49e77..8e88bda37a5 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -143,13 +143,6 @@ GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
memset(gc->glyph_ascii_table, 0, sizeof(gc->glyph_ascii_table));
memset(gc->bucket, 0, sizeof(gc->bucket));
- gc->textures = (GPUTexture **)MEM_callocN(sizeof(GPUTexture *) * 256, __func__);
- gc->textures_len = 256;
- gc->texture_current = BLF_TEXTURE_UNSET;
- gc->offset_x = 3; /* enough padding for blur */
- gc->offset_y = 3; /* enough padding for blur */
- gc->pad = 6;
-
gc->glyphs_len_max = (int)font->face->num_glyphs;
gc->glyphs_len_free = (int)font->face->num_glyphs;
gc->ascender = ((float)font->face->size->metrics.ascender) / 64.0f;
@@ -173,9 +166,6 @@ GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
CLAMP_MIN(gc->glyph_width_max, 1);
CLAMP_MIN(gc->glyph_height_max, 1);
- gc->p2_width = 0;
- gc->p2_height = 0;
-
BLI_addhead(&font->cache, gc);
return gc;
}
@@ -229,52 +219,13 @@ void blf_glyph_cache_free(GlyphCacheBLF *gc)
blf_glyph_free(g);
}
}
- for (i = 0; i < gc->textures_len; i++) {
- if (gc->textures[i]) {
- GPU_texture_free(gc->textures[i]);
- }
+ if (gc->texture) {
+ GPU_texture_free(gc->texture);
}
- MEM_freeN(gc->textures);
- MEM_freeN(gc);
-}
-
-static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
-{
- int i;
- char error[256];
-
- /* move the index. */
- gc->texture_current++;
-
- if (UNLIKELY(gc->texture_current >= gc->textures_len)) {
- gc->textures_len *= 2;
- gc->textures = MEM_recallocN((void *)gc->textures, sizeof(GPUTexture *) * gc->textures_len);
- }
-
- gc->p2_width = (int)blf_next_p2(
- (unsigned int)((gc->glyphs_len_free * gc->glyph_width_max) + (gc->pad * 2)));
- if (gc->p2_width > font->tex_size_max) {
- gc->p2_width = font->tex_size_max;
+ if (gc->bitmap_result) {
+ MEM_freeN(gc->bitmap_result);
}
-
- i = (int)((gc->p2_width - (gc->pad * 2)) / gc->glyph_width_max);
- gc->p2_height = (int)blf_next_p2(
- (unsigned int)(((gc->glyphs_len_max / i) + 1) * gc->glyph_height_max + (gc->pad * 2)));
-
- if (gc->p2_height > font->tex_size_max) {
- gc->p2_height = font->tex_size_max;
- }
-
- GPUTexture *tex = GPU_texture_create_nD(
- gc->p2_width, gc->p2_height, 0, 2, NULL, GPU_R8, GPU_DATA_UNSIGNED_BYTE, 0, false, error);
-
- GPU_texture_bind(tex, 0);
- GPU_texture_wrap_mode(tex, false);
- GPU_texture_filters(tex, GPU_NEAREST, GPU_LINEAR);
- GPU_texture_clear(tex, GPU_DATA_UNSIGNED_BYTE, NULL);
- GPU_texture_unbind(tex);
-
- gc->textures[gc->texture_current] = tex;
+ MEM_freeN(gc);
}
GlyphBLF *blf_glyph_search(GlyphCacheBLF *gc, unsigned int c)
@@ -377,8 +328,6 @@ GlyphBLF *blf_glyph_add(FontBLF *font, GlyphCacheBLF *gc, unsigned int index, un
g = (GlyphBLF *)MEM_callocN(sizeof(GlyphBLF), "blf_glyph_add");
g->c = c;
g->idx = (FT_UInt)index;
- g->offset_x = -1;
- g->offset_y = -1;
bitmap = slot->bitmap;
g->width = (int)bitmap.width;
g->height = (int)bitmap.rows;
@@ -418,17 +367,19 @@ GlyphBLF *blf_glyph_add(FontBLF *font, GlyphCacheBLF *gc, unsigned int index, un
void blf_glyph_free(GlyphBLF *g)
{
- /* don't need free the texture, the GlyphCache already
- * have a list of all the texture and free it.
- */
if (g->bitmap) {
MEM_freeN(g->bitmap);
}
MEM_freeN(g);
}
-static void blf_texture_draw(
- const unsigned char color[4], const float uv[2][2], float x1, float y1, float x2, float y2)
+static void blf_texture_draw(const unsigned char color[4],
+ const int glyph_size[2],
+ const int offset,
+ float x1,
+ float y1,
+ float x2,
+ float y2)
{
/* Only one vertex per glyph, geometry shader expand it into a quad. */
/* TODO Get rid of Geom Shader because it's not optimal AT ALL for the GPU */
@@ -437,8 +388,10 @@ static void blf_texture_draw(
y1 + g_batch.ofs[1],
x2 + g_batch.ofs[0],
y2 + g_batch.ofs[1]);
- copy_v4_v4(GPU_vertbuf_raw_step(&g_batch.tex_step), (float *)uv);
copy_v4_v4_uchar(GPU_vertbuf_raw_step(&g_batch.col_step), color);
+ copy_v2_v2_int(GPU_vertbuf_raw_step(&g_batch.glyph_size_step), glyph_size);
+ *((int *)GPU_vertbuf_raw_step(&g_batch.offset_step)) = offset;
+
g_batch.glyph_len++;
/* Flush cache if it's full. */
if (g_batch.glyph_len == BLF_BATCH_DRAW_LEN_MAX) {
@@ -447,45 +400,35 @@ static void blf_texture_draw(
}
static void blf_texture5_draw(const unsigned char color_in[4],
- int tex_w,
- int tex_h,
- const float uv[2][2],
+ const int glyph_size[2],
+ const int offset,
float x1,
float y1,
float x2,
float y2)
{
- float ofs[2] = {2 / (float)tex_w, 2 / (float)tex_h};
- float uv_flag[2][2];
- copy_v4_v4((float *)uv_flag, (float *)uv);
+ int glyph_size_flag[2];
/* flag the x and y component signs for 5x5 blurring */
- uv_flag[0][0] = -(uv_flag[0][0] - ofs[0]);
- uv_flag[0][1] = -(uv_flag[0][1] - ofs[1]);
- uv_flag[1][0] = -(uv_flag[1][0] + ofs[0]);
- uv_flag[1][1] = -(uv_flag[1][1] + ofs[1]);
+ glyph_size_flag[0] = -glyph_size[0];
+ glyph_size_flag[1] = -glyph_size[1];
- blf_texture_draw(color_in, uv_flag, x1 - 2, y1 + 2, x2 + 2, y2 - 2);
+ blf_texture_draw(color_in, glyph_size_flag, offset, x1, y1, x2, y2);
}
static void blf_texture3_draw(const unsigned char color_in[4],
- int tex_w,
- int tex_h,
- const float uv[2][2],
+ const int glyph_size[2],
+ const int offset,
float x1,
float y1,
float x2,
float y2)
{
- float ofs[2] = {1 / (float)tex_w, 1 / (float)tex_h};
- float uv_flag[2][2];
- copy_v4_v4((float *)uv_flag, (float *)uv);
+ int glyph_size_flag[2];
/* flag the x component sign for 3x3 blurring */
- uv_flag[0][0] = -(uv_flag[0][0] - ofs[0]);
- uv_flag[0][1] = (uv_flag[0][1] - ofs[1]);
- uv_flag[1][0] = -(uv_flag[1][0] + ofs[0]);
- uv_flag[1][1] = (uv_flag[1][1] + ofs[1]);
+ glyph_size_flag[0] = -glyph_size[0];
+ glyph_size_flag[1] = glyph_size[1];
- blf_texture_draw(color_in, uv_flag, x1 - 1, y1 + 1, x2 + 1, y2 - 1);
+ blf_texture_draw(color_in, glyph_size_flag, offset, x1, y1, x2, y2);
}
static void blf_glyph_calc_rect(rctf *rect, GlyphBLF *g, float x, float y)
@@ -518,63 +461,38 @@ void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, fl
return;
}
- if (g->build_tex == 0) {
+ if (!g->cached) {
if (font->tex_size_max == -1) {
font->tex_size_max = GPU_max_texture_size();
}
- if (gc->texture_current == BLF_TEXTURE_UNSET) {
- blf_glyph_cache_texture(font, gc);
- gc->offset_x = gc->pad;
- gc->offset_y = 3; /* enough padding for blur */
- }
+ g->offset = gc->bitmap_len;
- if (gc->offset_x > (gc->p2_width - gc->glyph_width_max)) {
- gc->offset_x = gc->pad;
- gc->offset_y += gc->glyph_height_max;
+ int buff_size = g->width * g->height;
+ int bitmap_len = gc->bitmap_len + buff_size;
- if (gc->offset_y > (gc->p2_height - gc->glyph_height_max)) {
- gc->offset_y = 3; /* enough padding for blur */
- blf_glyph_cache_texture(font, gc);
- }
- }
+ if (bitmap_len > gc->bitmap_len_alloc) {
+ int w = font->tex_size_max;
+ int h = bitmap_len / w + 1;
- g->tex = gc->textures[gc->texture_current];
- g->offset_x = gc->offset_x;
- g->offset_y = gc->offset_y;
+ gc->bitmap_len_alloc = w * h;
+ gc->bitmap_result = MEM_reallocN(gc->bitmap_result, (size_t)gc->bitmap_len_alloc);
- /* prevent glTexSubImage2D from failing if the character
- * asks for pixels out of bounds, this tends only to happen
- * with very small sizes (5px high or less) */
- if (UNLIKELY((g->offset_x + g->width) > gc->p2_width)) {
- g->width -= (g->offset_x + g->width) - gc->p2_width;
- BLI_assert(g->width > 0);
- }
- if (UNLIKELY((g->offset_y + g->height) > gc->p2_height)) {
- g->height -= (g->offset_y + g->height) - gc->p2_height;
- BLI_assert(g->height > 0);
- }
-
- GPU_texture_update_sub(g->tex,
- GPU_DATA_UNSIGNED_BYTE,
- g->bitmap,
- g->offset_x,
- g->offset_y,
- 0,
- g->width,
- g->height,
- 0);
+ /* Keep in sync with the texture. */
+ if (gc->texture) {
+ GPU_texture_free(gc->texture);
+ }
+ gc->texture = GPU_texture_create_nD(
+ w, h, 0, 1, NULL, GPU_R8, GPU_DATA_UNSIGNED_BYTE, 0, false, NULL);
- g->uv[0][0] = ((float)g->offset_x) / ((float)gc->p2_width);
- g->uv[0][1] = ((float)g->offset_y) / ((float)gc->p2_height);
- g->uv[1][0] = ((float)(g->offset_x + g->width)) / ((float)gc->p2_width);
- g->uv[1][1] = ((float)(g->offset_y + g->height)) / ((float)gc->p2_height);
+ gc->bitmap_len_landed = 0;
+ }
- /* update the x offset for the next glyph. */
- gc->offset_x += (int)BLI_rctf_size_x(&g->box) + gc->pad;
+ memcpy(&gc->bitmap_result[gc->bitmap_len], g->bitmap, (size_t)buff_size);
+ gc->bitmap_len = bitmap_len;
gc->glyphs_len_free--;
- g->build_tex = 1;
+ g->cached = true;
}
if (font->flags & BLF_CLIPPING) {
@@ -587,27 +505,26 @@ void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, fl
}
}
- if (font->tex_bind_state != g->tex) {
- blf_batch_draw();
- font->tex_bind_state = g->tex;
- GPU_texture_bind(font->tex_bind_state, 0);
- }
-
- g_batch.tex_bind_state = g->tex;
+ g_batch.glyph_cache = gc;
+ BLI_assert(g->offset < gc->bitmap_len);
if (font->flags & BLF_SHADOW) {
rctf rect_ofs;
blf_glyph_calc_rect_shadow(&rect_ofs, g, x, y, font);
if (font->shadow == 0) {
- blf_texture_draw(
- font->shadow_color, g->uv, rect_ofs.xmin, rect_ofs.ymin, rect_ofs.xmax, rect_ofs.ymax);
+ blf_texture_draw(font->shadow_color,
+ (int[2]){g->width, g->height},
+ g->offset,
+ rect_ofs.xmin,
+ rect_ofs.ymin,
+ rect_ofs.xmax,
+ rect_ofs.ymax);
}
else if (font->shadow <= 4) {
blf_texture3_draw(font->shadow_color,
- gc->p2_width,
- gc->p2_height,
- g->uv,
+ (int[2]){g->width, g->height},
+ g->offset,
rect_ofs.xmin,
rect_ofs.ymin,
rect_ofs.xmax,
@@ -615,9 +532,8 @@ void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, fl
}
else {
blf_texture5_draw(font->shadow_color,
- gc->p2_width,
- gc->p2_height,
- g->uv,
+ (int[2]){g->width, g->height},
+ g->offset,
rect_ofs.xmin,
rect_ofs.ymin,
rect_ofs.xmax,
@@ -632,9 +548,8 @@ void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, fl
switch (font->blur) {
case 3:
blf_texture3_draw(font->color,
- gc->p2_width,
- gc->p2_height,
- g->uv,
+ (int[2]){g->width, g->height},
+ g->offset,
rect.xmin,
rect.ymin,
rect.xmax,
@@ -642,18 +557,29 @@ void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, fl
break;
case 5:
blf_texture5_draw(font->color,
- gc->p2_width,
- gc->p2_height,
- g->uv,
+ (int[2]){g->width, g->height},
+ g->offset,
rect.xmin,
rect.ymin,
rect.xmax,
rect.ymax);
break;
default:
- blf_texture_draw(font->color, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ blf_texture_draw(font->color,
+ (int[2]){g->width, g->height},
+ g->offset,
+ rect.xmin,
+ rect.ymin,
+ rect.xmax,
+ rect.ymax);
}
#else
- blf_texture_draw(font->color, g->uv, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ blf_texture_draw(font->color,
+ (int[2]){g->width, g->height},
+ g->offset,
+ rect.xmin,
+ rect.ymin,
+ rect.xmax,
+ rect.ymax);
#endif
}
diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index 45086de0f61..bb1697d7860 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -33,13 +33,13 @@ typedef struct BatchBLF {
struct FontBLF *font; /* can only batch glyph from the same font */
struct GPUBatch *batch;
struct GPUVertBuf *verts;
- struct GPUVertBufRaw pos_step, tex_step, col_step;
- unsigned int pos_loc, tex_loc, col_loc;
+ struct GPUVertBufRaw pos_step, col_step, offset_step, glyph_size_step;
+ unsigned int pos_loc, col_loc, offset_loc, glyph_size_loc;
unsigned int glyph_len;
float ofs[2]; /* copy of font->pos */
float mat[4][4]; /* previous call modelmatrix. */
bool enabled, active, simple_shader;
- GPUTexture *tex_bind_state;
+ struct GlyphCacheBLF *glyph_cache;
} BatchBLF;
extern BatchBLF g_batch;
@@ -72,30 +72,16 @@ typedef struct GlyphCacheBLF {
struct GlyphBLF *glyph_ascii_table[256];
/* texture array, to draw the glyphs. */
- GPUTexture **textures;
-
- /* size of the array. */
- unsigned int textures_len;
-
- /* and the last texture, aka. the current texture. */
- unsigned int texture_current;
-
- /* We draw every glyph in a big texture, so this is the
- * current position inside the texture. */
- int offset_x;
- int offset_y;
-
- /* and the space from one to other. */
- int pad;
+ GPUTexture *texture;
+ char *bitmap_result;
+ int bitmap_len;
+ int bitmap_len_landed;
+ int bitmap_len_alloc;
/* and the bigger glyph in the font. */
int glyph_width_max;
int glyph_height_max;
- /* next two integer power of two, to build the texture. */
- int p2_width;
- int p2_height;
-
/* number of glyphs in the font. */
int glyphs_len_max;
@@ -125,12 +111,8 @@ typedef struct GlyphBLF {
/* avoid conversion to int while drawing */
int advance_i;
- /* texture id where this glyph is store. */
- GPUTexture *tex;
-
/* position inside the texture where this glyph is store. */
- int offset_x;
- int offset_y;
+ int offset;
/* Bitmap data, from freetype. Take care that this
* can be NULL.
@@ -142,9 +124,6 @@ typedef struct GlyphBLF {
int height;
int pitch;
- /* uv coords. */
- float uv[2][2];
-
/* X and Y bearing of the glyph.
* The X bearing is from the origin to the glyph left bbox edge.
* The Y bearing is from the baseline to the top of the glyph edge.
@@ -152,8 +131,7 @@ typedef struct GlyphBLF {
float pos_x;
float pos_y;
- /* with value of zero mean that we need build the texture. */
- char build_tex;
+ bool cached;
} GlyphBLF;
typedef struct FontBufInfoBLF {
@@ -239,9 +217,6 @@ typedef struct FontBLF {
/* max texture size. */
int tex_size_max;
- /* cache current OpenGL texture to save calls into the API */
- GPUTexture *tex_bind_state;
-
/* font options. */
int flags;
@@ -286,6 +261,4 @@ typedef struct DirBLF {
char *path;
} DirBLF;
-#define BLF_TEXTURE_UNSET ((unsigned int)-1)
-
#endif /* __BLF_INTERNAL_TYPES_H__ */
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 09aa4ca7a6b..3e7edb175d9 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -27,7 +27,7 @@
* \note Use #STRINGIFY() rather than defining with quotes.
*/
#define BLENDER_VERSION 283
-#define BLENDER_SUBVERSION 4
+#define BLENDER_SUBVERSION 5
/** Several breakages with 280, e.g. collections vs layers. */
#define BLENDER_MINVERSION 280
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h
index 50af6c876b4..d39850a162b 100644
--- a/source/blender/blenkernel/BKE_cdderivedmesh.h
+++ b/source/blender/blenkernel/BKE_cdderivedmesh.h
@@ -49,9 +49,6 @@ struct DerivedMesh *CDDM_from_mesh_ex(struct Mesh *mesh,
eCDAllocType alloctype,
const struct CustomData_MeshMasks *mask);
-/* creates a CDDerivedMesh from the given BMEditMesh */
-DerivedMesh *CDDM_from_editbmesh(struct BMEditMesh *em, const bool use_mdisps);
-
/* Copies the given DerivedMesh with verts, faces & edges stored as
* custom element data.
*/
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index a55b5dc7817..5fc4e909fac 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -370,150 +370,6 @@ DerivedMesh *CDDM_from_mesh_ex(Mesh *mesh,
return dm;
}
-/* TODO(campbell): remove, use BKE_mesh_from_bmesh_for_eval_nomain instead. */
-
-/* used for both editbmesh and bmesh */
-static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, const bool use_mdisps)
-{
- DerivedMesh *dm = CDDM_new(bm->totvert, bm->totedge, 0, bm->totloop, bm->totface);
-
- CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
- BMIter iter;
- BMVert *eve;
- BMEdge *eed;
- BMFace *efa;
- MVert *mvert = cddm->mvert;
- MEdge *medge = cddm->medge;
- MLoop *mloop = cddm->mloop;
- MPoly *mpoly = cddm->mpoly;
- int *index, add_orig;
- CustomData_MeshMasks mask = {0};
- unsigned int i, j;
-
- const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
- const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
- const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
-
- dm->deformedOnly = 1;
-
- /* don't add origindex layer if one already exists */
- add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX);
-
- mask = CD_MASK_DERIVEDMESH;
- if (use_mdisps) {
- mask.lmask |= CD_MASK_MDISPS;
- }
-
- /* don't process shapekeys, we only feed them through the modifier stack as needed,
- * e.g. for applying modifiers or the like*/
- mask.vmask &= ~CD_MASK_SHAPEKEY;
- CustomData_merge(&bm->vdata, &dm->vertData, mask.vmask, CD_CALLOC, dm->numVertData);
- CustomData_merge(&bm->edata, &dm->edgeData, mask.emask, CD_CALLOC, dm->numEdgeData);
- CustomData_merge(&bm->ldata, &dm->loopData, mask.lmask, CD_CALLOC, dm->numLoopData);
- CustomData_merge(&bm->pdata, &dm->polyData, mask.pmask, CD_CALLOC, dm->numPolyData);
-
- index = dm->getVertDataArray(dm, CD_ORIGINDEX);
-
- BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
- MVert *mv = &mvert[i];
-
- copy_v3_v3(mv->co, eve->co);
-
- BM_elem_index_set(eve, i); /* set_inline */
-
- normal_float_to_short_v3(mv->no, eve->no);
-
- mv->flag = BM_vert_flag_to_mflag(eve);
-
- if (cd_vert_bweight_offset != -1) {
- mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
- }
-
- if (add_orig) {
- *index++ = i;
- }
-
- CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i);
- }
- bm->elem_index_dirty &= ~BM_VERT;
-
- index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
- BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
- MEdge *med = &medge[i];
-
- BM_elem_index_set(eed, i); /* set_inline */
-
- med->v1 = BM_elem_index_get(eed->v1);
- med->v2 = BM_elem_index_get(eed->v2);
-
- med->flag = BM_edge_flag_to_mflag(eed);
-
- /* handle this differently to editmode switching,
- * only enable draw for single user edges rather then calculating angle */
- if ((med->flag & ME_EDGEDRAW) == 0) {
- if (eed->l && eed->l == eed->l->radial_next) {
- med->flag |= ME_EDGEDRAW;
- }
- }
-
- if (cd_edge_crease_offset != -1) {
- med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset);
- }
- if (cd_edge_bweight_offset != -1) {
- med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset);
- }
-
- CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
- if (add_orig) {
- *index++ = i;
- }
- }
- bm->elem_index_dirty &= ~BM_EDGE;
-
- index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
- j = 0;
- BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
- BMLoop *l_iter;
- BMLoop *l_first;
- MPoly *mp = &mpoly[i];
-
- BM_elem_index_set(efa, i); /* set_inline */
-
- mp->totloop = efa->len;
- mp->flag = BM_face_flag_to_mflag(efa);
- mp->loopstart = j;
- mp->mat_nr = efa->mat_nr;
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
- do {
- mloop->v = BM_elem_index_get(l_iter->v);
- mloop->e = BM_elem_index_get(l_iter->e);
- CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l_iter->head.data, j);
-
- BM_elem_index_set(l_iter, j); /* set_inline */
-
- j++;
- mloop++;
- } while ((l_iter = l_iter->next) != l_first);
-
- CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
-
- if (add_orig) {
- *index++ = i;
- }
- }
- bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
-
- dm->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
-
- return dm;
-}
-
-DerivedMesh *CDDM_from_editbmesh(BMEditMesh *em, const bool use_mdisps)
-{
- return cddm_from_bmesh_ex(em->bm, use_mdisps);
-}
-
DerivedMesh *CDDM_copy(DerivedMesh *source)
{
CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 1d44604384a..7c5e9af728a 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -339,37 +339,32 @@ void BKE_fluid_cache_free(FluidDomainSettings *mds, Object *ob, int cache_map)
flags &= ~(FLUID_DOMAIN_BAKING_DATA | FLUID_DOMAIN_BAKED_DATA | FLUID_DOMAIN_OUTDATED_DATA);
BLI_path_join(temp_dir, sizeof(temp_dir), mds->cache_directory, FLUID_DOMAIN_DIR_CONFIG, NULL);
BLI_path_abs(temp_dir, relbase);
- if (BLI_exists(temp_dir)) {
- BLI_delete(temp_dir, true, true);
- }
+ BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
+
BLI_path_join(temp_dir, sizeof(temp_dir), mds->cache_directory, FLUID_DOMAIN_DIR_DATA, NULL);
BLI_path_abs(temp_dir, relbase);
- if (BLI_exists(temp_dir)) {
- BLI_delete(temp_dir, true, true);
- }
+ BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
+
BLI_path_join(temp_dir, sizeof(temp_dir), mds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, NULL);
BLI_path_abs(temp_dir, relbase);
- if (BLI_exists(temp_dir)) {
- BLI_delete(temp_dir, true, true);
- }
+ BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
+
mds->cache_frame_pause_data = 0;
}
if (cache_map & FLUID_DOMAIN_OUTDATED_NOISE) {
flags &= ~(FLUID_DOMAIN_BAKING_NOISE | FLUID_DOMAIN_BAKED_NOISE | FLUID_DOMAIN_OUTDATED_NOISE);
BLI_path_join(temp_dir, sizeof(temp_dir), mds->cache_directory, FLUID_DOMAIN_DIR_NOISE, NULL);
BLI_path_abs(temp_dir, relbase);
- if (BLI_exists(temp_dir)) {
- BLI_delete(temp_dir, true, true);
- }
+ BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
+
mds->cache_frame_pause_noise = 0;
}
if (cache_map & FLUID_DOMAIN_OUTDATED_MESH) {
flags &= ~(FLUID_DOMAIN_BAKING_MESH | FLUID_DOMAIN_BAKED_MESH | FLUID_DOMAIN_OUTDATED_MESH);
BLI_path_join(temp_dir, sizeof(temp_dir), mds->cache_directory, FLUID_DOMAIN_DIR_MESH, NULL);
BLI_path_abs(temp_dir, relbase);
- if (BLI_exists(temp_dir)) {
- BLI_delete(temp_dir, true, true);
- }
+ BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
+
mds->cache_frame_pause_mesh = 0;
}
if (cache_map & FLUID_DOMAIN_OUTDATED_PARTICLES) {
@@ -378,9 +373,8 @@ void BKE_fluid_cache_free(FluidDomainSettings *mds, Object *ob, int cache_map)
BLI_path_join(
temp_dir, sizeof(temp_dir), mds->cache_directory, FLUID_DOMAIN_DIR_PARTICLES, NULL);
BLI_path_abs(temp_dir, relbase);
- if (BLI_exists(temp_dir)) {
- BLI_delete(temp_dir, true, true);
- }
+ BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
+
mds->cache_frame_pause_particles = 0;
}
@@ -388,9 +382,8 @@ void BKE_fluid_cache_free(FluidDomainSettings *mds, Object *ob, int cache_map)
flags &= ~(FLUID_DOMAIN_BAKING_GUIDE | FLUID_DOMAIN_BAKED_GUIDE | FLUID_DOMAIN_OUTDATED_GUIDE);
BLI_path_join(temp_dir, sizeof(temp_dir), mds->cache_directory, FLUID_DOMAIN_DIR_GUIDE, NULL);
BLI_path_abs(temp_dir, relbase);
- if (BLI_exists(temp_dir)) {
- BLI_delete(temp_dir, true, true);
- }
+ BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */
+
mds->cache_frame_pause_guide = 0;
}
mds->cache_flag = flags;
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index 9faa61f986d..c27fb59835f 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -49,6 +49,8 @@
#include "RE_render_ext.h"
+#include "BLI_hash.h"
+
#ifdef WITH_OCEANSIM
/* Ocean code */
@@ -985,11 +987,15 @@ void BKE_ocean_init(struct Ocean *o,
}
}
- /*srand(seed);*/
rng = BLI_rng_new(seed);
for (i = 0; i < o->_M; i++) {
for (j = 0; j < o->_N; j++) {
+ /* This ensures we get a value tied to the surface location, avoiding dramatic surface
+ * change with changing resolution. */
+ int new_seed = seed + BLI_hash_int_2d(o->_kx[i] * 360.0f, o->_kz[j] * 360.0f);
+
+ BLI_rng_seed(rng, new_seed);
float r1 = gaussRand(rng);
float r2 = gaussRand(rng);
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 500c58095e6..483838ed741 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -140,7 +140,7 @@ static void tracking_dopesheet_free(MovieTrackingDopesheet *dopesheet)
{
MovieTrackingDopesheetChannel *channel;
- /* Free channel's sergments. */
+ /* Free channel's segments. */
channel = dopesheet->channels.first;
while (channel) {
if (channel->segments) {
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index 5c20e57181e..3ee22e4ad0a 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -73,6 +73,29 @@ int BLI_stat(const char *path, BLI_stat_t *buffer) ATTR_WARN_UNUSED_RESULT ATTR_
int BLI_wstat(const wchar_t *path, BLI_stat_t *buffer);
#endif
+typedef enum eFileAttributes {
+ FILE_ATTR_READONLY = 1 << 0, /* Read-only or Immutable. */
+ FILE_ATTR_HIDDEN = 1 << 1, /* Hidden or invisible. */
+ FILE_ATTR_SYSTEM = 1 << 2, /* Used by the Operating System. */
+ FILE_ATTR_ARCHIVE = 1 << 3, /* Marked as archived. */
+ FILE_ATTR_COMPRESSED = 1 << 4, /* Compressed. */
+ FILE_ATTR_ENCRYPTED = 1 << 5, /* Encrypted. */
+ FILE_ATTR_RESTRICTED = 1 << 6, /* Protected by OS. */
+ FILE_ATTR_TEMPORARY = 1 << 7, /* Used for temporary storage. */
+ FILE_ATTR_SPARSE_FILE = 1 << 8, /* Sparse File. */
+ FILE_ATTR_OFFLINE = 1 << 9, /* Data is not immediately available. */
+ FILE_ATTR_ALIAS = 1 << 10, /* Mac Alias or Windows Lnk. File-based redirection. */
+ FILE_ATTR_REPARSE_POINT = 1 << 11, /* File has associated reparse point. */
+ FILE_ATTR_SYMLINK = 1 << 12, /* Reference to another file. */
+ FILE_ATTR_JUNCTION_POINT = 1 << 13, /* Folder Symlink. */
+ FILE_ATTR_MOUNT_POINT = 1 << 14, /* Volume mounted as a folder. */
+ FILE_ATTR_HARDLINK = 1 << 15, /* Duplicated directory entry. */
+} eFileAttributes;
+
+#define FILE_ATTR_ANY_LINK \
+ (FILE_ATTR_ALIAS | FILE_ATTR_REPARSE_POINT | FILE_ATTR_SYMLINK | FILE_ATTR_JUNCTION_POINT | \
+ FILE_ATTR_MOUNT_POINT | FILE_ATTR_HARDLINK)
+
/* Directories */
struct direntry;
@@ -83,6 +106,7 @@ bool BLI_dir_create_recursive(const char *dir) ATTR_NONNULL();
double BLI_dir_free_space(const char *dir) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
char *BLI_current_working_dir(char *dir, const size_t maxlen) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL();
+eFileAttributes BLI_file_attributes(const char *path);
/* Filelist */
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 7c481868d64..d1d8c4fa2e0 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -199,6 +199,70 @@ size_t BLI_file_size(const char *path)
return stats.st_size;
}
+eFileAttributes BLI_file_attributes(const char *path)
+{
+ int ret = 0;
+
+#ifdef WIN32
+ wchar_t wline[FILE_MAXDIR];
+ BLI_strncpy_wchar_from_utf8(wline, path, ARRAY_SIZE(wline));
+ DWORD attr = GetFileAttributesW(wline);
+ if (attr & FILE_ATTRIBUTE_READONLY) {
+ ret |= FILE_ATTR_READONLY;
+ }
+ if (attr & FILE_ATTRIBUTE_HIDDEN) {
+ ret |= FILE_ATTR_HIDDEN;
+ }
+ if (attr & FILE_ATTRIBUTE_SYSTEM) {
+ ret |= FILE_ATTR_SYSTEM;
+ }
+ if (attr & FILE_ATTRIBUTE_ARCHIVE) {
+ ret |= FILE_ATTR_ARCHIVE;
+ }
+ if (attr & FILE_ATTRIBUTE_COMPRESSED) {
+ ret |= FILE_ATTR_COMPRESSED;
+ }
+ if (attr & FILE_ATTRIBUTE_ENCRYPTED) {
+ ret |= FILE_ATTR_ENCRYPTED;
+ }
+ if (attr & FILE_ATTRIBUTE_TEMPORARY) {
+ ret |= FILE_ATTR_TEMPORARY;
+ }
+ if (attr & FILE_ATTRIBUTE_SPARSE_FILE) {
+ ret |= FILE_ATTR_SPARSE_FILE;
+ }
+ if (attr & FILE_ATTRIBUTE_OFFLINE) {
+ ret |= FILE_ATTR_OFFLINE;
+ }
+ if (attr & FILE_ATTRIBUTE_REPARSE_POINT) {
+ ret |= FILE_ATTR_REPARSE_POINT;
+ }
+
+#endif
+
+#ifdef __APPLE__
+
+ /* TODO:
+ * If Hidden (Invisible) set FILE_ATTR_HIDDEN
+ * If Locked set FILE_ATTR_READONLY
+ * If Restricted set FILE_ATTR_RESTRICTED
+ */
+
+#endif
+
+#ifdef __linux__
+ UNUSED_VARS(path);
+
+ /* TODO:
+ * If Immutable set FILE_ATTR_READONLY
+ * If Archived set FILE_ATTR_ARCHIVE
+ */
+
+#endif
+
+ return ret;
+}
+
/**
* Returns the st_mode from stat-ing the specified path name, or 0 if stat fails
* (most likely doesn't exist or no access).
diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c
index f23e4b5e2a4..7c70728e50c 100644
--- a/source/blender/blenloader/intern/versioning_260.c
+++ b/source/blender/blenloader/intern/versioning_260.c
@@ -147,6 +147,23 @@ static void do_versions_nodetree_convert_angle(bNodeTree *ntree)
static void do_versions_image_settings_2_60(Scene *sce)
{
+ /* RenderData.subimtype flag options for imtype */
+ enum {
+ R_OPENEXR_HALF = (1 << 0),
+ R_OPENEXR_ZBUF = (1 << 1),
+ R_PREVIEW_JPG = (1 << 2),
+ R_CINEON_LOG = (1 << 3),
+ R_TIFF_16BIT = (1 << 4),
+
+ R_JPEG2K_12BIT = (1 << 5),
+ /* Jpeg2000 */
+ R_JPEG2K_16BIT = (1 << 6),
+ R_JPEG2K_YCC = (1 << 7),
+ /* when disabled use RGB */
+ R_JPEG2K_CINE_PRESET = (1 << 8),
+ R_JPEG2K_CINE_48FPS = (1 << 9),
+ };
+
/* note: rd->subimtype is moved into individual settings now and no longer
* exists */
RenderData *rd = &sce->r;
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index a24165713aa..627b38a58e8 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -3364,7 +3364,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
for (Image *image = bmain->images.first; image; image = image->id.next) {
- image->flag &= ~(IMA_FLAG_UNUSED_0 | IMA_FLAG_UNUSED_1 | IMA_FLAG_UNUSED_4 |
+ image->flag &= ~(IMA_HIGH_BITDEPTH | IMA_FLAG_UNUSED_1 | IMA_FLAG_UNUSED_4 |
IMA_FLAG_UNUSED_6 | IMA_FLAG_UNUSED_8 | IMA_FLAG_UNUSED_15 |
IMA_FLAG_UNUSED_16);
}
@@ -4466,18 +4466,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
- /**
- * Versioning code until next subversion bump goes here.
- *
- * \note Be sure to check when bumping the version:
- * - "versioning_userdef.c", #BLO_version_defaults_userpref_blend
- * - "versioning_userdef.c", #do_versions_theme
- *
- * \note Keep this message at the bottom of the function.
- */
- {
- /* Keep this block, even when empty. */
-
+ if (!MAIN_VERSION_ATLEAST(bmain, 283, 5)) {
/* Alembic Transform Cache changed from world to local space. */
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
LISTBASE_FOREACH (bConstraint *, con, &ob->constraints) {
@@ -4498,5 +4487,32 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
+
+ /* Add Lookdev blur property. */
+ if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "float", "studiolight_blur")) {
+ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+ v3d->shading.studiolight_blur = 0.5f;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Versioning code until next subversion bump goes here.
+ *
+ * \note Be sure to check when bumping the version:
+ * - "versioning_userdef.c", #BLO_version_defaults_userpref_blend
+ * - "versioning_userdef.c", #do_versions_theme
+ *
+ * \note Keep this message at the bottom of the function.
+ */
+ {
+ /* Keep this block, even when empty. */
}
}
diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c
index 94ee8d46675..f70988c9277 100644
--- a/source/blender/blenloader/intern/versioning_userdef.c
+++ b/source/blender/blenloader/intern/versioning_userdef.c
@@ -175,6 +175,19 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
FROM_DEFAULT_V4_UCHAR(space_info.info_operator_text);
}
+ if (!USER_VERSION_ATLEAST(283, 5)) {
+ FROM_DEFAULT_V4_UCHAR(space_graph.time_marker_line);
+ FROM_DEFAULT_V4_UCHAR(space_action.time_marker_line);
+ FROM_DEFAULT_V4_UCHAR(space_nla.time_marker_line);
+ FROM_DEFAULT_V4_UCHAR(space_sequencer.time_marker_line);
+ FROM_DEFAULT_V4_UCHAR(space_clip.time_marker_line);
+ FROM_DEFAULT_V4_UCHAR(space_graph.time_marker_line_selected);
+ FROM_DEFAULT_V4_UCHAR(space_action.time_marker_line_selected);
+ FROM_DEFAULT_V4_UCHAR(space_nla.time_marker_line_selected);
+ FROM_DEFAULT_V4_UCHAR(space_sequencer.time_marker_line_selected);
+ FROM_DEFAULT_V4_UCHAR(space_clip.time_marker_line_selected);
+ }
+
/**
* Versioning code until next subversion bump goes here.
*
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index e45644f001f..3e7fb702d6a 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -28,6 +28,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <cstring> /* required for STREQ later on. */
+#include <deque>
+#include <unordered_set>
#include "MEM_guardedalloc.h"
@@ -119,6 +121,9 @@ extern "C" {
namespace DEG {
+using std::deque;
+using std::unordered_set;
+
/* ***************** */
/* Relations Builder */
@@ -1330,48 +1335,6 @@ void DepsgraphRelationBuilder::build_animdata_drivers(ID *id)
/* create the driver's relations to targets */
build_driver(id, fcu);
- /* Special case for array drivers: we can not multithread them because
- * of the way how they work internally: animation system will write the
- * whole array back to RNA even when changing individual array value.
- *
- * Some tricky things here:
- * - array_index is -1 for single channel drivers, meaning we only have
- * to do some magic when array_index is not -1.
- * - We do relation from next array index to a previous one, so we don't
- * have to deal with array index 0.
- *
- * TODO(sergey): Avoid liner lookup somehow. */
- if (fcu->array_index > 0) {
- FCurve *fcu_prev = nullptr;
- LISTBASE_FOREACH (FCurve *, fcu_candidate, &adt->drivers) {
- /* Writing to different RNA paths is */
- const char *rna_path = fcu->rna_path ? fcu->rna_path : "";
- if (!STREQ(fcu_candidate->rna_path, rna_path)) {
- continue;
- }
- /* We only do relation from previous fcurve to previous one. */
- if (fcu_candidate->array_index >= fcu->array_index) {
- continue;
- }
- /* Choose fcurve with highest possible array index. */
- if (fcu_prev == nullptr || fcu_candidate->array_index > fcu_prev->array_index) {
- fcu_prev = fcu_candidate;
- }
- }
- if (fcu_prev != nullptr) {
- OperationKey prev_driver_key(id,
- NodeType::PARAMETERS,
- OperationCode::DRIVER,
- fcu_prev->rna_path ? fcu_prev->rna_path : "",
- fcu_prev->array_index);
- OperationKey driver_key(id,
- NodeType::PARAMETERS,
- OperationCode::DRIVER,
- fcu->rna_path ? fcu->rna_path : "",
- fcu->array_index);
- add_relation(prev_driver_key, driver_key, "Driver Order");
- }
- }
/* prevent driver from occurring before own animation... */
if (adt->action || adt->nla_tracks.first) {
@@ -1488,7 +1451,11 @@ void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu)
}
else {
/* If it's not a Bone, handle the generic single dependency case. */
- add_relation(driver_key, property_entry_key, "Driver -> Driven Property");
+ Node *node_to = get_node(property_entry_key);
+ if (node_to != nullptr) {
+ add_relation(driver_key, property_entry_key, "Driver -> Driven Property");
+ }
+
/* Similar to the case with f-curves, driver might drive a nested
* data-block, which means driver execution should wait for that
* data-block to be copied. */
@@ -2706,6 +2673,116 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node)
#endif
}
+static bool is_reachable(const Node *const from, const Node *const to)
+{
+ if (from == to) {
+ return true;
+ }
+
+ // Perform a graph walk from 'to' towards its incoming connections.
+ // Walking from 'from' towards its outgoing connections is 10x slower on the Spring rig.
+ deque<const Node *> queue;
+ unordered_set<const Node *> seen;
+ queue.push_back(to);
+ while (!queue.empty()) {
+ // Visit the next node to inspect.
+ const Node *visit = queue.back();
+ queue.pop_back();
+
+ if (visit == from) {
+ return true;
+ }
+
+ // Queue all incoming relations that we haven't seen before.
+ for (Relation *relation : visit->inlinks) {
+ const Node *prev_node = relation->from;
+ if (seen.insert(prev_node).second) {
+ queue.push_back(prev_node);
+ }
+ }
+ }
+ return false;
+}
+
+void DepsgraphRelationBuilder::build_driver_relations()
+{
+ for (IDNode *id_node : graph_->id_nodes) {
+ build_driver_relations(id_node);
+ }
+}
+
+void DepsgraphRelationBuilder::build_driver_relations(IDNode *id_node)
+{
+ /* Add relations between drivers that write to the same datablock.
+ *
+ * This prevents threading issues when two separate RNA properties write to
+ * the same memory address. For example:
+ * - Drivers on individual array elements, as the animation system will write
+ * the whole array back to RNA even when changing individual array value.
+ * - Drivers on RNA properties that map to a single bit flag. Changing the RNA
+ * value will write the entire int containing the bit, in a non-thread-safe
+ * way.
+ */
+ ID *id_orig = id_node->id_orig;
+ AnimData *adt = BKE_animdata_from_id(id_orig);
+ if (adt == nullptr) {
+ return;
+ }
+
+ // Mapping from RNA prefix -> set of driver evaluation nodes:
+ typedef vector<Node *> DriverGroup;
+ typedef map<string, DriverGroup> DriverGroupMap;
+ DriverGroupMap driver_groups;
+
+ LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
+ // Get the RNA path except the part after the last dot.
+ char *last_dot = strrchr(fcu->rna_path, '.');
+ string rna_prefix;
+ if (last_dot != nullptr) {
+ rna_prefix = string(fcu->rna_path, last_dot);
+ }
+
+ // Insert this driver node into the group belonging to the RNA prefix.
+ OperationKey driver_key(
+ id_orig, NodeType::PARAMETERS, OperationCode::DRIVER, fcu->rna_path, fcu->array_index);
+ Node *node_driver = get_node(driver_key);
+ driver_groups[rna_prefix].push_back(node_driver);
+ }
+
+ for (pair<string, DriverGroup> prefix_group : driver_groups) {
+ // For each node in the driver group, try to connect it to another node
+ // in the same group without creating any cycles.
+ int num_drivers = prefix_group.second.size();
+ for (int from_index = 0; from_index < num_drivers; ++from_index) {
+ Node *op_from = prefix_group.second[from_index];
+
+ // Start by trying the next node in the group.
+ for (int to_offset = 1; to_offset < num_drivers - 1; ++to_offset) {
+ int to_index = (from_index + to_offset) % num_drivers;
+ Node *op_to = prefix_group.second[to_index];
+
+ // Investigate whether this relation would create a dependency cycle.
+ // Example graph:
+ // A -> B -> C
+ // and investigating a potential connection C->A. Because A->C is an
+ // existing transitive connection, adding C->A would create a cycle.
+ if (is_reachable(op_to, op_from)) {
+ continue;
+ }
+
+ // No need to directly connect this node if there is already a transitive connection.
+ if (is_reachable(op_from, op_to)) {
+ break;
+ }
+
+ add_operation_relation(
+ op_from->get_exit_operation(), op_to->get_entry_operation(), "Driver Serialisation");
+ break;
+ }
+ }
+ }
+}
+
/* **** ID traversal callbacks functions **** */
void DepsgraphRelationBuilder::modifier_walk(void *user_data,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index 11eb31c68f6..7da3577a7b5 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -302,6 +302,8 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
virtual void build_copy_on_write_relations();
virtual void build_copy_on_write_relations(IDNode *id_node);
+ virtual void build_driver_relations();
+ virtual void build_driver_relations(IDNode *id_node);
template<typename KeyType> OperationNode *find_operation_node(const KeyType &key);
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index a570e042c26..3fe585ff73c 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -251,6 +251,7 @@ void DEG_graph_build_from_view_layer(Depsgraph *graph,
relation_builder.begin_build();
relation_builder.build_view_layer(scene, view_layer, DEG::DEG_ID_LINKED_DIRECTLY);
relation_builder.build_copy_on_write_relations();
+ relation_builder.build_driver_relations();
/* Finalize building. */
graph_build_finalize_common(deg_graph, bmain);
/* Finish statistics. */
@@ -284,6 +285,7 @@ void DEG_graph_build_for_render_pipeline(Depsgraph *graph,
relation_builder.begin_build();
relation_builder.build_scene_render(scene, view_layer);
relation_builder.build_copy_on_write_relations();
+ relation_builder.build_driver_relations();
/* Finalize building. */
graph_build_finalize_common(deg_graph, bmain);
/* Finish statistics. */
@@ -317,6 +319,7 @@ void DEG_graph_build_for_compositor_preview(
relation_builder.build_scene_render(scene, view_layer);
relation_builder.build_nodetree(nodetree);
relation_builder.build_copy_on_write_relations();
+ relation_builder.build_driver_relations();
/* Finalize building. */
graph_build_finalize_common(deg_graph, bmain);
/* Finish statistics. */
@@ -458,6 +461,7 @@ void DEG_graph_build_from_ids(Depsgraph *graph,
relation_builder.build_id(ids[i]);
}
relation_builder.build_copy_on_write_relations();
+ relation_builder.build_driver_relations();
/* Finalize building. */
graph_build_finalize_common(deg_graph, bmain);
/* Finish statistics. */
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 37fe04e9d8a..6d7b422c4fb 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -219,6 +219,8 @@ data_to_c_simple(engines/eevee/shaders/lightprobe_planar_downsample_geom.glsl SR
data_to_c_simple(engines/eevee/shaders/lightprobe_planar_downsample_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/prepass_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/prepass_vert.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/shadow_accum_frag.glsl SRC)
+
data_to_c_simple(engines/eevee/shaders/shadow_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/shadow_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/bsdf_lut_frag.glsl SRC)
@@ -232,6 +234,7 @@ data_to_c_simple(engines/eevee/shaders/renderpass_postprocess_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/ltc_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/ssr_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/update_noise_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/volumetric_accum_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_geom.glsl SRC)
@@ -242,7 +245,6 @@ data_to_c_simple(engines/eevee/shaders/volumetric_integration_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_cavity_lib.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_cavity_frag.glsl SRC)
-data_to_c_simple(engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_common_lib.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_data_lib.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_deferred_composite_frag.glsl SRC)
@@ -389,6 +391,7 @@ data_to_c_simple(engines/overlay/shaders/sculpt_mask_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/volume_velocity_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/wireframe_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/wireframe_frag.glsl SRC)
+data_to_c_simple(engines/overlay/shaders/xray_fade_frag.glsl SRC)
list(APPEND INC
)
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index 647d8a0841f..2462603632f 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -48,23 +48,7 @@ struct bContext;
struct rcti;
#include "DNA_object_enums.h"
-
-/* Buffer and textures used by the viewport by default */
-typedef struct DefaultFramebufferList {
- struct GPUFrameBuffer *default_fb;
- struct GPUFrameBuffer *overlay_fb;
- struct GPUFrameBuffer *in_front_fb;
- struct GPUFrameBuffer *color_only_fb;
- struct GPUFrameBuffer *depth_only_fb;
- struct GPUFrameBuffer *overlay_only_fb;
-} DefaultFramebufferList;
-
-typedef struct DefaultTextureList {
- struct GPUTexture *color;
- struct GPUTexture *color_overlay;
- struct GPUTexture *depth;
- struct GPUTexture *depth_in_front;
-} DefaultTextureList;
+#include "DRW_engine_types.h"
void DRW_engines_register(void);
void DRW_engines_free(void);
diff --git a/source/blender/draw/DRW_engine_types.h b/source/blender/draw/DRW_engine_types.h
new file mode 100644
index 00000000000..dd56f87182c
--- /dev/null
+++ b/source/blender/draw/DRW_engine_types.h
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ *
+ * Copyright 2016, Blender Foundation.
+ */
+
+/** \file
+ * \ingroup draw
+ */
+
+#ifndef __DRW_ENGINE_TYPES_H__
+#define __DRW_ENGINE_TYPES_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Buffer and textures used by the viewport by default */
+typedef struct DefaultFramebufferList {
+ struct GPUFrameBuffer *default_fb;
+ struct GPUFrameBuffer *overlay_fb;
+ struct GPUFrameBuffer *in_front_fb;
+ struct GPUFrameBuffer *color_only_fb;
+ struct GPUFrameBuffer *depth_only_fb;
+ struct GPUFrameBuffer *overlay_only_fb;
+} DefaultFramebufferList;
+
+typedef struct DefaultTextureList {
+ struct GPUTexture *color;
+ struct GPUTexture *color_overlay;
+ struct GPUTexture *depth;
+ struct GPUTexture *depth_in_front;
+} DefaultTextureList;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DRW_ENGINE_H__ */
diff --git a/source/blender/draw/engines/eevee/eevee_bloom.c b/source/blender/draw/engines/eevee/eevee_bloom.c
index c6cc336db56..53465455d57 100644
--- a/source/blender/draw/engines/eevee/eevee_bloom.c
+++ b/source/blender/draw/engines/eevee/eevee_bloom.c
@@ -40,6 +40,8 @@ static struct {
extern char datatoc_effect_bloom_frag_glsl[];
+const bool use_highres = true;
+
static void eevee_create_shader_bloom(void)
{
e_data.bloom_blit_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl,
@@ -179,7 +181,8 @@ static DRWShadingGroup *eevee_create_bloom_pass(const char *name,
EEVEE_EffectsInfo *effects,
struct GPUShader *sh,
DRWPass **pass,
- bool upsample)
+ bool upsample,
+ bool resolve)
{
struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
@@ -193,6 +196,10 @@ static DRWShadingGroup *eevee_create_bloom_pass(const char *name,
DRW_shgroup_uniform_texture_ref(grp, "baseBuffer", &effects->unf_base_buffer);
DRW_shgroup_uniform_float(grp, "sampleScale", &effects->bloom_sample_scale, 1);
}
+ if (resolve) {
+ DRW_shgroup_uniform_vec3(grp, "bloomColor", effects->bloom_color, 1);
+ DRW_shgroup_uniform_bool_copy(grp, "bloomAddBase", true);
+ }
return grp;
}
@@ -203,6 +210,8 @@ void EEVEE_bloom_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *ved
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
+ psl->bloom_accum_ps = NULL;
+
if ((effects->enabled_effects & EFFECT_BLOOM) != 0) {
/** Bloom algorithm
*
@@ -234,29 +243,41 @@ void EEVEE_bloom_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *ved
* </pre>
*/
DRWShadingGroup *grp;
- const bool use_highres = true;
const bool use_antiflicker = true;
eevee_create_bloom_pass("Bloom Downsample First",
effects,
e_data.bloom_downsample_sh[use_antiflicker],
&psl->bloom_downsample_first,
+ false,
+ false);
+ eevee_create_bloom_pass("Bloom Downsample",
+ effects,
+ e_data.bloom_downsample_sh[0],
+ &psl->bloom_downsample,
+ false,
false);
- eevee_create_bloom_pass(
- "Bloom Downsample", effects, e_data.bloom_downsample_sh[0], &psl->bloom_downsample, false);
eevee_create_bloom_pass("Bloom Upsample",
effects,
e_data.bloom_upsample_sh[use_highres],
&psl->bloom_upsample,
- true);
+ true,
+ false);
- grp = eevee_create_bloom_pass(
- "Bloom Blit", effects, e_data.bloom_blit_sh[use_antiflicker], &psl->bloom_blit, false);
+ grp = eevee_create_bloom_pass("Bloom Blit",
+ effects,
+ e_data.bloom_blit_sh[use_antiflicker],
+ &psl->bloom_blit,
+ false,
+ false);
DRW_shgroup_uniform_vec4(grp, "curveThreshold", effects->bloom_curve_threshold, 1);
DRW_shgroup_uniform_float(grp, "clampIntensity", &effects->bloom_clamp, 1);
- grp = eevee_create_bloom_pass(
- "Bloom Resolve", effects, e_data.bloom_resolve_sh[use_highres], &psl->bloom_resolve, true);
- DRW_shgroup_uniform_vec3(grp, "bloomColor", effects->bloom_color, 1);
+ grp = eevee_create_bloom_pass("Bloom Resolve",
+ effects,
+ e_data.bloom_resolve_sh[use_highres],
+ &psl->bloom_resolve,
+ true,
+ true);
}
}
@@ -322,6 +343,47 @@ void EEVEE_bloom_draw(EEVEE_Data *vedata)
}
}
+void EEVEE_bloom_output_init(EEVEE_ViewLayerData *UNUSED(sldata),
+ EEVEE_Data *vedata,
+ uint UNUSED(tot_samples))
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+
+ /* Create FrameBuffer. */
+ DRW_texture_ensure_fullscreen_2d(&txl->bloom_accum, GPU_R11F_G11F_B10F, 0);
+
+ GPU_framebuffer_ensure_config(&fbl->bloom_pass_accum_fb,
+ {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->bloom_accum)});
+
+ /* Create Pass and shgroup. */
+ DRWShadingGroup *grp = eevee_create_bloom_pass("Bloom Accumulate",
+ effects,
+ e_data.bloom_resolve_sh[use_highres],
+ &psl->bloom_accum_ps,
+ true,
+ true);
+ DRW_shgroup_uniform_bool_copy(grp, "bloomAddBase", false);
+}
+
+void EEVEE_bloom_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+
+ if (stl->g_data->render_passes & EEVEE_RENDER_PASS_BLOOM) {
+ GPU_framebuffer_bind(fbl->bloom_pass_accum_fb);
+ DRW_draw_pass(psl->bloom_accum_ps);
+
+ /* Restore */
+ GPU_framebuffer_bind(fbl->main_fb);
+ }
+}
+
void EEVEE_bloom_free(void)
{
for (int i = 0; i < 2; i++) {
diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c
index dd70ee1bd4b..e586fc7b1db 100644
--- a/source/blender/draw/engines/eevee/eevee_data.c
+++ b/source/blender/draw/engines/eevee/eevee_data.c
@@ -54,6 +54,9 @@ void EEVEE_view_layer_data_free(void *storage)
DRW_UBO_FREE_SAFE(sldata->grid_ubo);
DRW_UBO_FREE_SAFE(sldata->planar_ubo);
DRW_UBO_FREE_SAFE(sldata->common_ubo);
+ for (int i = 0; i < MAX_MATERIAL_RENDER_PASSES_UBO; i++) {
+ DRW_UBO_FREE_SAFE(sldata->renderpass_ubo[i]);
+ }
}
EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void)
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index a20921b639f..90bfad45f60 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -170,7 +170,7 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
EEVEE_subsurface_init(sldata, vedata);
/* Force normal buffer creation. */
- if (!minimal && (stl->g_data->render_passes & SCE_PASS_NORMAL) != 0) {
+ if (!minimal && (stl->g_data->render_passes & EEVEE_RENDER_PASS_NORMAL) != 0) {
effects->enabled_effects |= EFFECT_NORMAL_BUFFER;
}
@@ -333,6 +333,8 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
grp = DRW_shgroup_create(EEVEE_shaders_velocity_resolve_sh_get(), psl->velocity_resolve);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_mat4(grp, "currPersinv", effects->velocity_curr_persinv);
DRW_shgroup_uniform_mat4(grp, "pastPersmat", effects->velocity_past_persmat);
DRW_shgroup_call(grp, quad, NULL);
@@ -513,7 +515,7 @@ static void EEVEE_velocity_resolve(EEVEE_Data *vedata)
DRW_view_persmat_get(view, effects->velocity_past_persmat, false);
}
-void EEVEE_draw_effects(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+void EEVEE_draw_effects(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_TextureList *txl = vedata->txl;
EEVEE_FramebufferList *fbl = vedata->fbl;
@@ -541,6 +543,10 @@ void EEVEE_draw_effects(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
EEVEE_temporal_sampling_draw(vedata);
EEVEE_bloom_draw(vedata);
+ /* Post effect render passes are done here just after the drawing of the effects and just before
+ * the swapping of the buffers. */
+ EEVEE_renderpasses_output_accumulate(sldata, vedata, true);
+
/* Save the final texture and framebuffer for final transformation or read. */
effects->final_tx = effects->source_buffer;
effects->final_fb = (effects->target_buffer != fbl->main_color_fb) ? fbl->main_fb :
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index e3b50bb2142..6480847092b 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -151,7 +151,8 @@ void EEVEE_cache_populate(void *vedata, Object *ob)
static void eevee_cache_finish(void *vedata)
{
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
- EEVEE_PrivateData *g_data = ((EEVEE_Data *)vedata)->stl->g_data;
+ EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
+ EEVEE_PrivateData *g_data = stl->g_data;
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
@@ -307,6 +308,9 @@ static void eevee_draw_scene(void *vedata)
/* Volumetrics Resolve Opaque */
EEVEE_volumes_resolve(sldata, vedata);
+ /* Renderpasses */
+ EEVEE_renderpasses_output_accumulate(sldata, vedata, false);
+
/* Transparent */
/* TODO(fclem): should be its own Framebuffer.
* This is needed because dualsource blending only works with 1 color buffer. */
@@ -321,8 +325,6 @@ static void eevee_draw_scene(void *vedata)
EEVEE_draw_effects(sldata, vedata);
DRW_stats_group_end();
- EEVEE_renderpasses_output_accumulate(sldata, vedata);
-
DRW_view_set_active(NULL);
if (DRW_state_is_image_render() && (stl->effects->enabled_effects & EFFECT_SSR) &&
@@ -336,7 +338,7 @@ static void eevee_draw_scene(void *vedata)
}
}
- if ((stl->g_data->render_passes & SCE_PASS_COMBINED) > 0) {
+ if ((stl->g_data->render_passes & EEVEE_RENDER_PASS_COMBINED) != 0) {
/* Transfer result to default framebuffer. */
GPU_framebuffer_bind(dfbl->default_fb);
DRW_transform_none(stl->effects->final_tx);
@@ -416,9 +418,8 @@ static void eevee_render_to_image(void *vedata,
const rcti *rect)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
- EEVEE_render_init(vedata, engine, draw_ctx->depsgraph);
- if (RE_engine_test_break(engine)) {
+ if (!EEVEE_render_init(vedata, engine, draw_ctx->depsgraph)) {
return;
}
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index e8e5614e4d4..2b11a608bd0 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -264,7 +264,7 @@ static bool EEVEE_lightcache_validate(const LightCache *light_cache,
if ((irr_size[0] == light_cache->grid_tx.tex_size[0]) &&
(irr_size[1] == light_cache->grid_tx.tex_size[1]) &&
(irr_size[2] == light_cache->grid_tx.tex_size[2]) && (grid_len == light_cache->grid_len)) {
- int mip_len = (int)(floorf(log2f(cube_res)) - MIN_CUBE_LOD_LEVEL);
+ int mip_len = log2_floor_u(cube_res) - MIN_CUBE_LOD_LEVEL;
if ((cube_res == light_cache->cube_tx.tex_size[0]) &&
(cube_len == light_cache->cube_tx.tex_size[2]) && (cube_len == light_cache->cube_len) &&
(mip_len == light_cache->mips_len)) {
@@ -298,7 +298,7 @@ LightCache *EEVEE_lightcache_create(const int grid_len,
light_cache->cube_tx.tex_size[1] = cube_size;
light_cache->cube_tx.tex_size[2] = cube_len;
- light_cache->mips_len = (int)(floorf(log2f(cube_size)) - MIN_CUBE_LOD_LEVEL);
+ light_cache->mips_len = log2_floor_u(cube_size) - MIN_CUBE_LOD_LEVEL;
light_cache->vis_res = vis_size;
light_cache->ref_res = cube_size;
@@ -491,7 +491,7 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
irradiance_pool_size_get(lbake->vis_res, lbake->total_irr_samples, lbake->irr_size);
- lbake->ref_cube_res = OCTAHEDRAL_SIZE_FROM_CUBESIZE(lbake->rt_res);
+ lbake->ref_cube_res = octahedral_size_from_cubesize(lbake->rt_res);
lbake->cube_prb = MEM_callocN(sizeof(LightProbe *) * lbake->cube_len, "EEVEE Cube visgroup ptr");
lbake->grid_prb = MEM_callocN(sizeof(LightProbe *) * lbake->grid_len, "EEVEE Grid visgroup ptr");
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index 7da9af55330..5e6c11833d3 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -186,7 +186,7 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
#elif defined(IRRADIANCE_HL2)
int grid_res = 4;
#endif
- int cube_res = OCTAHEDRAL_SIZE_FROM_CUBESIZE(scene_eval->eevee.gi_cubemap_resolution);
+ int cube_res = octahedral_size_from_cubesize(scene_eval->eevee.gi_cubemap_resolution);
int vis_res = scene_eval->eevee.gi_visibility_resolution;
sldata->fallback_lightcache = EEVEE_lightcache_create(
1, 1, cube_res, vis_res, (int[3]){grid_res, grid_res, 1});
@@ -251,6 +251,8 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
// 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);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRW_shgroup_call(grp, geom, NULL);
@@ -272,6 +274,8 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1);
DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRW_shgroup_call(grp, geom, NULL);
@@ -292,6 +296,8 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
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", EEVEE_material_default_render_pass_ubo_get(sldata));
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRW_shgroup_call(grp, geom, NULL);
@@ -337,7 +343,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
const float *col = G_draw.block.colorBackground;
/* LookDev */
- EEVEE_lookdev_cache_init(vedata, &grp, psl->probe_background, 1.0f, wo, pinfo);
+ EEVEE_lookdev_cache_init(vedata, sldata, &grp, psl->probe_background, wo, pinfo);
/* END */
if (!grp && wo) {
col = &wo->horr;
@@ -360,6 +366,8 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call(grp, geom, NULL);
break;
case GPU_MAT_QUEUED:
@@ -403,6 +411,8 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
/* TODO (fclem) get rid of those UBO. */
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call_procedural_triangles(grp, NULL, cube_len * 2);
}
@@ -429,6 +439,8 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo);
DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ shgrp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
int tri_count = egrid->resolution[0] * egrid->resolution[1] * egrid->resolution[2] * 2;
DRW_shgroup_call_procedural_triangles(shgrp, NULL, tri_count);
}
@@ -446,6 +458,8 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_planar_display_sh_get(),
psl->probe_display);
DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &txl->planar_pool);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
stl->g_data->planar_display_shgrp = DRW_shgroup_call_buffer_instance(
grp, e_data.format_probe_display_planar, DRW_cache_quad_get());
@@ -1046,7 +1060,7 @@ void EEVEE_lightbake_filter_glossy(EEVEE_ViewLayerData *sldata,
float target_size = (float)GPU_texture_width(rt_color);
/* Max lod used from the render target probe */
- pinfo->lod_rt_max = floorf(log2f(target_size)) - 2.0f;
+ pinfo->lod_rt_max = log2_floor_u(target_size) - 2.0f;
pinfo->intensity_fac = intensity;
/* Start fresh */
@@ -1155,7 +1169,7 @@ void EEVEE_lightbake_filter_diffuse(EEVEE_ViewLayerData *sldata,
pinfo->lodfactor = bias + 0.5f *
log((float)(target_size * target_size) * pinfo->samples_len_inv) /
log(2);
- pinfo->lod_rt_max = floorf(log2f(target_size)) - 2.0f;
+ pinfo->lod_rt_max = log2_floor_u(target_size) - 2.0f;
#else
pinfo->shres = 32; /* Less texture fetches & reduce branches */
pinfo->lod_rt_max = 2.0f; /* Improve cache reuse */
diff --git a/source/blender/draw/engines/eevee/eevee_lookdev.c b/source/blender/draw/engines/eevee/eevee_lookdev.c
index 94d61a81fcc..d39d2a61657 100644
--- a/source/blender/draw/engines/eevee/eevee_lookdev.c
+++ b/source/blender/draw/engines/eevee/eevee_lookdev.c
@@ -57,9 +57,9 @@ static void eevee_lookdev_lightcache_delete(EEVEE_Data *vedata)
}
void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
- DRWShadingGroup **grp,
+ EEVEE_ViewLayerData *sldata,
+ DRWShadingGroup **r_grp,
DRWPass *pass,
- float background_alpha,
World *UNUSED(world),
EEVEE_LightProbesInfo *pinfo)
{
@@ -69,13 +69,27 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
EEVEE_PrivateData *g_data = stl->g_data;
const DRWContextState *draw_ctx = DRW_context_state_get();
View3D *v3d = draw_ctx->v3d;
+ View3DShading *shading = &v3d->shading;
Scene *scene = draw_ctx->scene;
+ const bool probe_render = pinfo != NULL;
+
effects->lookdev_view = NULL;
if (LOOK_DEV_OVERLAY_ENABLED(v3d)) {
/* Viewport / Spheres size. */
- const rcti *rect = ED_region_visible_rect(draw_ctx->ar);
+ const rcti *rect;
+ rcti fallback_rect;
+ if (DRW_state_is_opengl_render()) {
+ const float *vp_size = DRW_viewport_size_get();
+ fallback_rect.xmax = vp_size[0];
+ fallback_rect.ymax = vp_size[1];
+ fallback_rect.xmin = fallback_rect.ymin = 0;
+ rect = &fallback_rect;
+ }
+ else {
+ rect = ED_region_visible_rect(draw_ctx->ar);
+ }
/* Make the viewport width scale the lookdev spheres a bit.
* Scale between 1000px and 2000px. */
@@ -95,21 +109,23 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
}
if (LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d)) {
- StudioLight *sl = BKE_studiolight_find(v3d->shading.lookdev_light,
+ StudioLight *sl = BKE_studiolight_find(shading->lookdev_light,
STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE);
if (sl && (sl->flag & STUDIOLIGHT_TYPE_WORLD)) {
- GPUShader *shader = EEVEE_shaders_default_studiolight_sh_get();
- struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
- GPUTexture *tex = NULL;
+ GPUShader *shader = probe_render ? EEVEE_shaders_default_studiolight_sh_get() :
+ EEVEE_shaders_background_studiolight_sh_get();
+
+ const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
+ int cube_res = octahedral_size_from_cubesize(scene_eval->eevee.gi_cubemap_resolution);
/* If one of the component is missing we start from scratch. */
if ((stl->lookdev_grid_data == NULL) || (stl->lookdev_cube_data == NULL) ||
- (txl->lookdev_grid_tx == NULL) || (txl->lookdev_cube_tx == NULL)) {
+ (txl->lookdev_grid_tx == NULL) || (txl->lookdev_cube_tx == NULL) ||
+ (g_data->light_cache && g_data->light_cache->ref_res != cube_res)) {
eevee_lookdev_lightcache_delete(vedata);
}
if (stl->lookdev_lightcache == NULL) {
- const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
#if defined(IRRADIANCE_SH_L2)
int grid_res = 4;
#elif defined(IRRADIANCE_CUBEMAP)
@@ -117,11 +133,9 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
#elif defined(IRRADIANCE_HL2)
int grid_res = 4;
#endif
- int cube_res = OCTAHEDRAL_SIZE_FROM_CUBESIZE(scene_eval->eevee.gi_cubemap_resolution);
- int vis_res = scene_eval->eevee.gi_visibility_resolution;
stl->lookdev_lightcache = EEVEE_lightcache_create(
- 1, 1, cube_res, vis_res, (int[3]){grid_res, grid_res, 1});
+ 1, 1, cube_res, 8, (int[3]){grid_res, grid_res, 1});
/* XXX: Fix memleak. TODO find out why. */
MEM_SAFE_FREE(stl->lookdev_cube_mips);
@@ -138,49 +152,45 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
txl->lookdev_cube_tx = stl->lookdev_lightcache->cube_tx.tex;
}
- stl->g_data->light_cache = stl->lookdev_lightcache;
-
- static float background_color[4];
- UI_GetThemeColor4fv(TH_BACK, background_color);
- /* XXX: Really quick conversion to avoid washed out background.
- * Needs to be addressed properly (color managed using ocio). */
- srgb_to_linearrgb_v4(background_color, background_color);
-
- *grp = DRW_shgroup_create(shader, pass);
- axis_angle_to_mat3_single(
- stl->g_data->studiolight_matrix, 'Z', v3d->shading.studiolight_rot_z);
- DRW_shgroup_uniform_mat3(*grp, "StudioLightMatrix", stl->g_data->studiolight_matrix);
- DRW_shgroup_uniform_float_copy(*grp, "backgroundAlpha", background_alpha);
- DRW_shgroup_uniform_float(
- *grp, "studioLightIntensity", &v3d->shading.studiolight_intensity, 1);
-
- DRW_shgroup_uniform_vec3(*grp, "color", background_color, 1);
- DRW_shgroup_call(*grp, geom, NULL);
- if (!pinfo) {
+ g_data->light_cache = stl->lookdev_lightcache;
+
+ DRWShadingGroup *grp = *r_grp = DRW_shgroup_create(shader, pass);
+ axis_angle_to_mat3_single(g_data->studiolight_matrix, 'Z', shading->studiolight_rot_z);
+ DRW_shgroup_uniform_mat3(grp, "StudioLightMatrix", g_data->studiolight_matrix);
+
+ if (probe_render) {
+ DRW_shgroup_uniform_float_copy(
+ grp, "studioLightIntensity", shading->studiolight_intensity);
+ BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
+ DRW_shgroup_uniform_texture(grp, "image", sl->equirect_radiance_gputexture);
/* Do not fadeout when doing probe rendering, only when drawing the background */
- DRW_shgroup_uniform_float(
- *grp, "studioLightBackground", &v3d->shading.studiolight_background, 1);
- BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECT_IRRADIANCE_GPUTEXTURE);
- tex = sl->equirect_irradiance_gputexture;
+ DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
}
else {
- DRW_shgroup_uniform_float_copy(*grp, "studioLightBackground", 1.0f);
- BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
- tex = sl->equirect_radiance_gputexture;
+ float background_alpha = g_data->background_alpha * shading->studiolight_background;
+ float studiolight_blur = powf(shading->studiolight_blur, 2.5f);
+ DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", background_alpha);
+ DRW_shgroup_uniform_float_copy(grp, "studioLightBlur", studiolight_blur);
+ DRW_shgroup_uniform_texture(grp, "probeCubes", txl->lookdev_cube_tx);
+ DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
+ DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
+ DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
+ DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
}
- DRW_shgroup_uniform_texture(*grp, "image", tex);
+
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
/* Do we need to recalc the lightprobes? */
if (g_data->studiolight_index != sl->index ||
- g_data->studiolight_rot_z != v3d->shading.studiolight_rot_z ||
- g_data->studiolight_intensity != v3d->shading.studiolight_intensity ||
+ g_data->studiolight_rot_z != shading->studiolight_rot_z ||
+ g_data->studiolight_intensity != shading->studiolight_intensity ||
g_data->studiolight_cubemap_res != scene->eevee.gi_cubemap_resolution ||
g_data->studiolight_glossy_clamp != scene->eevee.gi_glossy_clamp ||
g_data->studiolight_filter_quality != scene->eevee.gi_filter_quality) {
stl->lookdev_lightcache->flag |= LIGHTCACHE_UPDATE_WORLD;
g_data->studiolight_index = sl->index;
- g_data->studiolight_rot_z = v3d->shading.studiolight_rot_z;
- g_data->studiolight_intensity = v3d->shading.studiolight_intensity;
+ g_data->studiolight_rot_z = shading->studiolight_rot_z;
+ g_data->studiolight_intensity = shading->studiolight_intensity;
g_data->studiolight_cubemap_res = scene->eevee.gi_cubemap_resolution;
g_data->studiolight_glossy_clamp = scene->eevee.gi_glossy_clamp;
g_data->studiolight_filter_quality = scene->eevee.gi_filter_quality;
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 1c0a1289ba4..0c9efeb0a16 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -25,6 +25,7 @@
#include "BLI_dynstr.h"
#include "BLI_ghash.h"
#include "BLI_alloca.h"
+#include "BLI_math_bits.h"
#include "BLI_rand.h"
#include "BLI_string_utils.h"
@@ -101,9 +102,37 @@ extern char datatoc_volumetric_vert_glsl[];
extern char datatoc_volumetric_geom_glsl[];
extern char datatoc_volumetric_frag_glsl[];
extern char datatoc_volumetric_lib_glsl[];
-
extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
+#define DEFAULT_RENDER_PASS_FLAG 0xefffffff
+
+/* Iterator for render passes. This iteration will only do the material based render passes. it
+ * will ignore `EEVEE_RENDER_PASS_ENVIRONMENT`.
+ *
+ * parameters:
+ * - `render_passes_` is a bitflag for render_passes that needs to be iterated over.
+ * - `render_pass_index_` is a parameter name where the index of the render_pass will be available
+ * during iteration. This index can be used to select the right pass in the `psl`.
+ * - `render_pass_` is the bitflag of the render_pass of the current iteration.
+ *
+ * The `render_pass_index_` parameter needs to be the same for the `RENDER_PASS_ITER_BEGIN` and
+ * `RENDER_PASS_ITER_END`.
+ */
+#define RENDER_PASS_ITER_BEGIN(render_passes_, render_pass_index_, render_pass_) \
+ const eViewLayerEEVEEPassType __filtered_##render_pass_index_ = render_passes_ & \
+ EEVEE_RENDERPASSES_MATERIAL & \
+ ~EEVEE_RENDER_PASS_ENVIRONMENT; \
+ if (__filtered_##render_pass_index_ != 0) { \
+ int render_pass_index_ = 1; \
+ for (int bit_##render_pass_ = 0; bit_##render_pass_ < 32; bit_##render_pass_++) { \
+ eViewLayerEEVEEPassType render_pass_ = (1 << bit_##render_pass_); \
+ if ((__filtered_##render_pass_index_ & render_pass_) != 0) {
+#define RENDER_PASS_ITER_END(render_pass_index_) \
+ render_pass_index_ += 1; \
+ } \
+ } \
+ }
+
/* *********** FUNCTIONS *********** */
#if 0 /* Used only to generate the LUT values */
@@ -337,6 +366,39 @@ static char *eevee_get_volume_defines(int options)
return str;
}
+/* Get the default render pass ubo. This is a ubo that enables all bsdf render passes. */
+struct GPUUniformBuffer *EEVEE_material_default_render_pass_ubo_get(EEVEE_ViewLayerData *sldata)
+{
+ return sldata->renderpass_ubo[0];
+}
+
+/* Get the render pass ubo for rendering the given render_pass. */
+static struct GPUUniformBuffer *get_render_pass_ubo(EEVEE_ViewLayerData *sldata,
+ eViewLayerEEVEEPassType render_pass)
+{
+ int index;
+ switch (render_pass) {
+ case EEVEE_RENDER_PASS_DIFFUSE_COLOR:
+ index = 1;
+ break;
+ case EEVEE_RENDER_PASS_DIFFUSE_LIGHT:
+ index = 2;
+ break;
+ case EEVEE_RENDER_PASS_SPECULAR_COLOR:
+ index = 3;
+ break;
+ case EEVEE_RENDER_PASS_SPECULAR_LIGHT:
+ index = 4;
+ break;
+ case EEVEE_RENDER_PASS_EMIT:
+ index = 5;
+ break;
+ default:
+ index = 0;
+ break;
+ }
+ return sldata->renderpass_ubo[index];
+}
/**
* ssr_id can be null to disable ssr contribution.
*/
@@ -349,7 +411,8 @@ static void add_standard_uniforms(DRWShadingGroup *shgrp,
bool use_glossy,
bool use_refract,
bool use_ssrefraction,
- bool use_alpha_blend)
+ bool use_alpha_blend,
+ eViewLayerEEVEEPassType render_pass)
{
LightCache *lcache = vedata->stl->g_data->light_cache;
EEVEE_EffectsInfo *effects = vedata->stl->effects;
@@ -360,9 +423,9 @@ static void add_standard_uniforms(DRWShadingGroup *shgrp,
DRW_shgroup_uniform_block(shgrp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(shgrp, "shadow_block", sldata->shadow_ubo);
DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(shgrp, "renderpass_block", get_render_pass_ubo(sldata, render_pass));
DRW_shgroup_uniform_int_copy(shgrp, "outputSssId", 1);
-
if (use_diffuse || use_glossy || use_refract) {
DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
DRW_shgroup_uniform_texture_ref(shgrp, "shadowCubeTexture", &sldata->shadow_cube_pool);
@@ -395,6 +458,24 @@ static void add_standard_uniforms(DRWShadingGroup *shgrp,
}
}
+/* Add the uniforms for the background shader to `shgrp`. */
+static void add_background_uniforms(DRWShadingGroup *shgrp,
+ EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata)
+{
+ EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
+ DRW_shgroup_uniform_float(shgrp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
+ /* TODO (fclem): remove those (need to clean the GLSL files). */
+ DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo);
+ DRW_shgroup_uniform_block(shgrp, "probe_block", sldata->probe_ubo);
+ DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo);
+ DRW_shgroup_uniform_block(shgrp, "light_block", sldata->light_ubo);
+ DRW_shgroup_uniform_block(shgrp, "shadow_block", sldata->shadow_ubo);
+ DRW_shgroup_uniform_block(
+ shgrp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
+}
+
static void create_default_shader(int options)
{
char *frag_str = BLI_string_joinN(e_data.frag_shader_lib, datatoc_default_frag_glsl);
@@ -523,6 +604,9 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
EEVEE_StorageList *stl,
EEVEE_FramebufferList *fbl)
{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ EEVEE_PrivateData *g_data = stl->g_data;
+
if (!e_data.frag_shader_lib) {
/* Shaders */
e_data.frag_shader_lib = BLI_string_joinN(datatoc_common_view_lib_glsl,
@@ -600,7 +684,6 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
datatoc_prepass_frag_glsl,
"#define HAIR_SHADER\n"
"#define CLIP_PLANES\n");
-
MEM_freeN(vert_str);
e_data.update_noise_sh = DRW_shader_create_fullscreen(datatoc_update_noise_frag_glsl, NULL);
@@ -635,6 +718,66 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
&fbl->update_noise_fb,
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE_LAYER(e_data.util_tex, 2)});
}
+
+ {
+ /* Create RenderPass UBO */
+ if (sldata->renderpass_ubo[0] == NULL) {
+ sldata->renderpass_data[0].renderPassDiffuse = true;
+ sldata->renderpass_data[0].renderPassDiffuseLight = true;
+ sldata->renderpass_data[0].renderPassGlossy = true;
+ sldata->renderpass_data[0].renderPassGlossyLight = true;
+ sldata->renderpass_data[0].renderPassEmit = true;
+ sldata->renderpass_data[0].renderPassSSSColor = false;
+ sldata->renderpass_data[1].renderPassDiffuse = true;
+ sldata->renderpass_data[1].renderPassDiffuseLight = false;
+ sldata->renderpass_data[1].renderPassGlossy = false;
+ sldata->renderpass_data[1].renderPassGlossyLight = false;
+ sldata->renderpass_data[1].renderPassEmit = false;
+ sldata->renderpass_data[1].renderPassSSSColor = true;
+ sldata->renderpass_data[2].renderPassDiffuse = true;
+ sldata->renderpass_data[2].renderPassDiffuseLight = true;
+ sldata->renderpass_data[2].renderPassGlossy = false;
+ sldata->renderpass_data[2].renderPassGlossyLight = false;
+ sldata->renderpass_data[2].renderPassEmit = false;
+ sldata->renderpass_data[2].renderPassSSSColor = false;
+ sldata->renderpass_data[3].renderPassDiffuse = false;
+ sldata->renderpass_data[3].renderPassDiffuseLight = false;
+ sldata->renderpass_data[3].renderPassGlossy = true;
+ sldata->renderpass_data[3].renderPassGlossyLight = false;
+ sldata->renderpass_data[3].renderPassEmit = false;
+ sldata->renderpass_data[3].renderPassSSSColor = false;
+ sldata->renderpass_data[4].renderPassDiffuse = false;
+ sldata->renderpass_data[4].renderPassDiffuseLight = false;
+ sldata->renderpass_data[4].renderPassGlossy = true;
+ sldata->renderpass_data[4].renderPassGlossyLight = true;
+ sldata->renderpass_data[4].renderPassEmit = false;
+ sldata->renderpass_data[4].renderPassSSSColor = false;
+ sldata->renderpass_data[5].renderPassDiffuse = false;
+ sldata->renderpass_data[5].renderPassDiffuseLight = false;
+ sldata->renderpass_data[5].renderPassGlossy = false;
+ sldata->renderpass_data[5].renderPassGlossyLight = false;
+ sldata->renderpass_data[5].renderPassEmit = true;
+ sldata->renderpass_data[5].renderPassSSSColor = false;
+
+ for (int i = 0; i < MAX_MATERIAL_RENDER_PASSES_UBO; i++) {
+ sldata->renderpass_ubo[i] = DRW_uniformbuffer_create(sizeof(EEVEE_RenderPassData),
+ &sldata->renderpass_data[i]);
+ }
+ }
+
+ /* HACK: EEVEE_material_world_background_get can create a new context. This can only be
+ * done when there is no active framebuffer. We do this here otherwise
+ * `EEVEE_renderpasses_output_init` will fail. It cannot be done in
+ * `EEVEE_renderpasses_init` as the `e_data.vertcode` can be uninitialized.
+ */
+ if (g_data->render_passes & EEVEE_RENDER_PASS_ENVIRONMENT) {
+ struct Scene *scene = draw_ctx->scene;
+ struct World *wo = scene->world;
+ if (wo && wo->use_nodes) {
+ EEVEE_material_world_background_get(scene, wo);
+ }
+ }
+ }
}
struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, World *wo)
@@ -852,7 +995,17 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create(EEVEE_ViewLaye
}
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], pass);
- add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, use_blend);
+ add_standard_uniforms(shgrp,
+ sldata,
+ vedata,
+ &ssr_id,
+ NULL,
+ true,
+ true,
+ false,
+ false,
+ use_blend,
+ DEFAULT_RENDER_PASS_FLAG);
return shgrp;
}
@@ -894,14 +1047,34 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get(EEVEE_ViewLayerDa
if (!is_hair) {
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options],
psl->default_pass[options]);
- add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, false);
+ add_standard_uniforms(shgrp,
+ sldata,
+ vedata,
+ &ssr_id,
+ NULL,
+ true,
+ true,
+ false,
+ false,
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
}
}
if (is_hair) {
DRWShadingGroup *shgrp = DRW_shgroup_hair_create(
ob, psys, md, vedata->psl->default_pass[options], e_data.default_lit[options]);
- add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, false);
+ add_standard_uniforms(shgrp,
+ sldata,
+ vedata,
+ &ssr_id,
+ NULL,
+ true,
+ true,
+ false,
+ false,
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
return shgrp;
}
else {
@@ -909,6 +1082,60 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get(EEVEE_ViewLayerDa
}
}
+static struct DRWShadingGroup *EEVEE_default_render_pass_shading_group_get(
+ EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ bool holdout,
+ bool use_ssr,
+ DRWPass *pass,
+ eViewLayerEEVEEPassType render_pass_flag)
+{
+ static int ssr_id;
+ ssr_id = (use_ssr) ? 1 : -1;
+ int options = VAR_MAT_MESH;
+
+ SET_FLAG_FROM_TEST(options, holdout, VAR_MAT_HOLDOUT);
+
+ if (e_data.default_lit[options] == NULL) {
+ create_default_shader(options);
+ }
+
+ DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], pass);
+ add_standard_uniforms(
+ shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, false, render_pass_flag);
+ return shgrp;
+}
+
+static struct DRWShadingGroup *EEVEE_default_hair_render_pass_shading_group_get(
+ EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ Object *ob,
+ ParticleSystem *psys,
+ ModifierData *md,
+ bool holdout,
+ bool use_ssr,
+ DRWPass *pass,
+ eViewLayerEEVEEPassType render_pass_flag)
+{
+ static int ssr_id;
+ ssr_id = (use_ssr) ? 1 : -1;
+ int options = VAR_MAT_MESH | VAR_MAT_HAIR;
+
+ BLI_assert((ob && psys && md));
+
+ SET_FLAG_FROM_TEST(options, holdout, VAR_MAT_HOLDOUT);
+
+ if (e_data.default_lit[options] == NULL) {
+ create_default_shader(options);
+ }
+
+ DRWShadingGroup *shgrp = DRW_shgroup_hair_create(
+ ob, psys, md, pass, e_data.default_lit[options]);
+ add_standard_uniforms(
+ shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, false, render_pass_flag);
+ return shgrp;
+}
+
void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
@@ -931,8 +1158,7 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
const float *col = G_draw.block.colorBackground;
- EEVEE_lookdev_cache_init(
- vedata, &grp, psl->background_pass, stl->g_data->background_alpha, wo, NULL);
+ EEVEE_lookdev_cache_init(vedata, sldata, &grp, psl->background_pass, wo, NULL);
if (!grp && wo) {
col = &wo->horr;
@@ -945,14 +1171,7 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
switch (GPU_material_status(gpumat)) {
case GPU_MAT_SUCCESS:
grp = DRW_shgroup_material_create(gpumat, psl->background_pass);
- DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
- /* TODO (fclem): remove those (need to clean the GLSL files). */
- DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
- DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
- DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
- DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
- DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
+ add_background_uniforms(grp, sldata, vedata);
DRW_shgroup_call(grp, geom, NULL);
break;
case GPU_MAT_QUEUED:
@@ -1071,7 +1290,17 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_PASS_CREATE(psl->lookdev_diffuse_pass, state);
shgrp = DRW_shgroup_create(e_data.default_lit[options], psl->lookdev_diffuse_pass);
- add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL, true, true, false, false, false);
+ add_standard_uniforms(shgrp,
+ sldata,
+ vedata,
+ NULL,
+ NULL,
+ true,
+ true,
+ false,
+ false,
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
DRW_shgroup_uniform_vec3(shgrp, "basecol", color_diffuse, 1);
DRW_shgroup_uniform_float_copy(shgrp, "metallic", 0.0f);
DRW_shgroup_uniform_float_copy(shgrp, "specular", 0.5f);
@@ -1080,12 +1309,31 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_PASS_CREATE(psl->lookdev_glossy_pass, state);
shgrp = DRW_shgroup_create(e_data.default_lit[options], psl->lookdev_glossy_pass);
- add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL, true, true, false, false, false);
+ add_standard_uniforms(shgrp,
+ sldata,
+ vedata,
+ NULL,
+ NULL,
+ true,
+ true,
+ false,
+ false,
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
DRW_shgroup_uniform_vec3(shgrp, "basecol", color_chrome, 1);
DRW_shgroup_uniform_float_copy(shgrp, "metallic", 1.0f);
DRW_shgroup_uniform_float_copy(shgrp, "roughness", 0.0f);
DRW_shgroup_call(shgrp, sphere, NULL);
}
+
+ {
+ memset(psl->material_accum_pass, 0, sizeof(psl->material_accum_pass));
+ for (int pass_index = 0; pass_index < stl->g_data->render_passes_material_count;
+ pass_index++) {
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ADD;
+ DRW_PASS_CREATE(psl->material_accum_pass[pass_index], state);
+ }
+ }
}
#define ADD_SHGROUP_CALL(shgrp, ob, geom, oedata) \
@@ -1109,6 +1357,7 @@ typedef struct EeveeMaterialShadingGroups {
struct DRWShadingGroup *shading_grp;
struct DRWShadingGroup *depth_grp;
struct DRWShadingGroup *depth_clip_grp;
+ struct DRWShadingGroup *material_accum_grp[MAX_MATERIAL_RENDER_PASSES];
} EeveeMaterialShadingGroups;
static void material_opaque(Material *ma,
@@ -1117,9 +1366,7 @@ static void material_opaque(Material *ma,
EEVEE_Data *vedata,
struct GPUMaterial **gpumat,
struct GPUMaterial **gpumat_depth,
- struct DRWShadingGroup **shgrp,
- struct DRWShadingGroup **shgrp_depth,
- struct DRWShadingGroup **shgrp_depth_clip,
+ struct EeveeMaterialShadingGroups *shgrps,
bool holdout)
{
EEVEE_EffectsInfo *effects = vedata->stl->effects;
@@ -1128,7 +1375,7 @@ static void material_opaque(Material *ma,
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
bool use_diffuse, use_glossy, use_refract;
-
+ bool store_material = true;
float *color_p = &ma->r;
float *metal_p = &ma->metallic;
float *spec_p = &ma->spec;
@@ -1143,9 +1390,7 @@ static void material_opaque(Material *ma,
EeveeMaterialShadingGroups *emsg = BLI_ghash_lookup(material_hash, (const void *)ma);
if (emsg) {
- *shgrp = emsg->shading_grp;
- *shgrp_depth = emsg->depth_grp;
- *shgrp_depth_clip = emsg->depth_clip_grp;
+ memcpy(shgrps, emsg, sizeof(EeveeMaterialShadingGroups));
/* This will have been created already, just perform a lookup. */
*gpumat = (use_gpumat) ? EEVEE_material_mesh_get(scene, ma, vedata, false, use_ssrefract) :
@@ -1156,6 +1401,7 @@ static void material_opaque(Material *ma,
return;
}
+ emsg = MEM_callocN(sizeof(EeveeMaterialShadingGroups), "EeveeMaterialShadingGroups");
if (use_gpumat) {
static float error_col[3] = {1.0f, 0.0f, 1.0f};
static float compile_col[3] = {0.5f, 0.5f, 0.5f};
@@ -1179,25 +1425,25 @@ static void material_opaque(Material *ma,
status_mat_surface = status_mat_depth;
}
else if (use_ssrefract) {
- *shgrp_depth = DRW_shgroup_material_create(
+ emsg->depth_grp = DRW_shgroup_material_create(
*gpumat_depth, (do_cull) ? psl->refract_depth_pass_cull : psl->refract_depth_pass);
- *shgrp_depth_clip = DRW_shgroup_material_create(
+ emsg->depth_clip_grp = DRW_shgroup_material_create(
*gpumat_depth,
(do_cull) ? psl->refract_depth_pass_clip_cull : psl->refract_depth_pass_clip);
}
else {
- *shgrp_depth = DRW_shgroup_material_create(
+ emsg->depth_grp = DRW_shgroup_material_create(
*gpumat_depth, (do_cull) ? psl->depth_pass_cull : psl->depth_pass);
- *shgrp_depth_clip = DRW_shgroup_material_create(
+ emsg->depth_clip_grp = DRW_shgroup_material_create(
*gpumat_depth, (do_cull) ? psl->depth_pass_clip_cull : psl->depth_pass_clip);
}
- if (*shgrp_depth != NULL) {
+ if (emsg->depth_grp != NULL) {
use_diffuse = GPU_material_flag_get(*gpumat_depth, GPU_MATFLAG_DIFFUSE);
use_glossy = GPU_material_flag_get(*gpumat_depth, GPU_MATFLAG_GLOSSY);
use_refract = GPU_material_flag_get(*gpumat_depth, GPU_MATFLAG_REFRACT);
- add_standard_uniforms(*shgrp_depth,
+ add_standard_uniforms(emsg->depth_grp,
sldata,
vedata,
NULL,
@@ -1206,8 +1452,9 @@ static void material_opaque(Material *ma,
use_glossy,
use_refract,
false,
- false);
- add_standard_uniforms(*shgrp_depth_clip,
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
+ add_standard_uniforms(emsg->depth_clip_grp,
sldata,
vedata,
NULL,
@@ -1216,11 +1463,13 @@ static void material_opaque(Material *ma,
use_glossy,
use_refract,
false,
- false);
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
if (ma->blend_method == MA_BM_CLIP) {
- DRW_shgroup_uniform_float(*shgrp_depth, "alphaThreshold", &ma->alpha_threshold, 1);
- DRW_shgroup_uniform_float(*shgrp_depth_clip, "alphaThreshold", &ma->alpha_threshold, 1);
+ DRW_shgroup_uniform_float(emsg->depth_grp, "alphaThreshold", &ma->alpha_threshold, 1);
+ DRW_shgroup_uniform_float(
+ emsg->depth_clip_grp, "alphaThreshold", &ma->alpha_threshold, 1);
}
}
}
@@ -1237,14 +1486,14 @@ static void material_opaque(Material *ma,
use_glossy = GPU_material_flag_get(*gpumat, GPU_MATFLAG_GLOSSY);
use_refract = GPU_material_flag_get(*gpumat, GPU_MATFLAG_REFRACT);
- *shgrp = DRW_shgroup_material_create(
+ emsg->shading_grp = DRW_shgroup_material_create(
*gpumat,
(use_ssrefract) ?
psl->refract_pass :
(use_sss) ? ((do_cull) ? psl->sss_pass_cull : psl->sss_pass) :
((do_cull) ? psl->material_pass_cull : psl->material_pass));
- add_standard_uniforms(*shgrp,
+ add_standard_uniforms(emsg->shading_grp,
sldata,
vedata,
ssr_id,
@@ -1253,7 +1502,8 @@ static void material_opaque(Material *ma,
use_glossy,
use_refract,
use_ssrefract,
- false);
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
if (use_sss) {
struct GPUTexture *sss_tex_profile = NULL;
@@ -1264,7 +1514,7 @@ static void material_opaque(Material *ma,
/* Limit of 8 bit stencil buffer. ID 255 is refraction. */
if (e_data.sss_count < 254) {
int sss_id = e_data.sss_count + 1;
- DRW_shgroup_stencil_mask(*shgrp, sss_id);
+ DRW_shgroup_stencil_mask(emsg->shading_grp, sss_id);
EEVEE_subsurface_add_pass(sldata, vedata, sss_id, sss_profile);
if (use_translucency) {
EEVEE_subsurface_translucency_add_pass(
@@ -1278,12 +1528,30 @@ static void material_opaque(Material *ma,
}
}
}
+
+ RENDER_PASS_ITER_BEGIN(stl->g_data->render_passes, render_pass_index, render_pass_flag)
+ emsg->material_accum_grp[render_pass_index] = DRW_shgroup_material_create(
+ *gpumat, psl->material_accum_pass[render_pass_index]);
+ add_standard_uniforms(emsg->material_accum_grp[render_pass_index],
+ sldata,
+ vedata,
+ ssr_id,
+ &ma->refract_depth,
+ use_diffuse,
+ use_glossy,
+ use_refract,
+ use_ssrefract,
+ false,
+ render_pass_flag);
+ RENDER_PASS_ITER_END(render_pass_index)
+
break;
}
case GPU_MAT_QUEUED: {
stl->g_data->queued_shaders_count++;
color_p = compile_col;
metal_p = spec_p = rough_p = &half;
+ store_material = false;
break;
}
case GPU_MAT_FAILED:
@@ -1295,44 +1563,61 @@ static void material_opaque(Material *ma,
}
/* Fallback to default shader */
- if (*shgrp == NULL) {
+ if (emsg->shading_grp == NULL) {
bool use_ssr = ((effects->enabled_effects & EFFECT_SSR) != 0);
- *shgrp = EEVEE_default_shading_group_get(
+ emsg->shading_grp = EEVEE_default_shading_group_get(
sldata, vedata, NULL, NULL, NULL, false, holdout, use_ssr);
- DRW_shgroup_uniform_vec3(*shgrp, "basecol", color_p, 1);
- DRW_shgroup_uniform_float(*shgrp, "metallic", metal_p, 1);
- DRW_shgroup_uniform_float(*shgrp, "specular", spec_p, 1);
- DRW_shgroup_uniform_float(*shgrp, "roughness", rough_p, 1);
+ DRW_shgroup_uniform_vec3(emsg->shading_grp, "basecol", color_p, 1);
+ DRW_shgroup_uniform_float(emsg->shading_grp, "metallic", metal_p, 1);
+ DRW_shgroup_uniform_float(emsg->shading_grp, "specular", spec_p, 1);
+ DRW_shgroup_uniform_float(emsg->shading_grp, "roughness", rough_p, 1);
+
+ RENDER_PASS_ITER_BEGIN(stl->g_data->render_passes, render_pass_index, render_pass_flag)
+ DRWShadingGroup *shgrp = EEVEE_default_render_pass_shading_group_get(
+ sldata,
+ vedata,
+ holdout,
+ use_ssr,
+ psl->material_accum_pass[render_pass_index],
+ render_pass_flag);
+
+ DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
+ emsg->material_accum_grp[render_pass_index] = shgrp;
+ RENDER_PASS_ITER_END(render_pass_index)
}
/* Fallback default depth prepass */
- if (*shgrp_depth == NULL) {
+ if (emsg->depth_grp == NULL) {
if (use_ssrefract) {
- *shgrp_depth = (do_cull) ? stl->g_data->refract_depth_shgrp_cull :
- stl->g_data->refract_depth_shgrp;
- *shgrp_depth_clip = (do_cull) ? stl->g_data->refract_depth_shgrp_clip_cull :
- stl->g_data->refract_depth_shgrp_clip;
+ emsg->depth_grp = (do_cull) ? stl->g_data->refract_depth_shgrp_cull :
+ stl->g_data->refract_depth_shgrp;
+ emsg->depth_clip_grp = (do_cull) ? stl->g_data->refract_depth_shgrp_clip_cull :
+ stl->g_data->refract_depth_shgrp_clip;
}
else {
- *shgrp_depth = (do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp;
- *shgrp_depth_clip = (do_cull) ? stl->g_data->depth_shgrp_clip_cull :
- stl->g_data->depth_shgrp_clip;
+ emsg->depth_grp = (do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp;
+ emsg->depth_clip_grp = (do_cull) ? stl->g_data->depth_shgrp_clip_cull :
+ stl->g_data->depth_shgrp_clip;
}
}
- emsg = MEM_mallocN(sizeof(EeveeMaterialShadingGroups), "EeveeMaterialShadingGroups");
- emsg->shading_grp = *shgrp;
- emsg->depth_grp = *shgrp_depth;
- emsg->depth_clip_grp = *shgrp_depth_clip;
- BLI_ghash_insert(material_hash, ma, emsg);
+ memcpy(shgrps, emsg, sizeof(EeveeMaterialShadingGroups));
+ if (store_material) {
+ BLI_ghash_insert(material_hash, ma, emsg);
+ }
+ else {
+ MEM_freeN(emsg);
+ }
}
static void material_transparent(Material *ma,
EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
struct GPUMaterial **gpumat,
- struct DRWShadingGroup **shgrp,
- struct DRWShadingGroup **shgrp_depth)
+ struct EeveeMaterialShadingGroups *shgrps)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
@@ -1357,13 +1642,13 @@ static void material_transparent(Material *ma,
/* Depth prepass */
if (use_prepass) {
- *shgrp_depth = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->transparent_pass);
+ shgrps->depth_grp = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->transparent_pass);
cur_state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0;
- DRW_shgroup_state_disable(*shgrp_depth, all_state);
- DRW_shgroup_state_enable(*shgrp_depth, cur_state);
+ DRW_shgroup_state_disable(shgrps->depth_grp, all_state);
+ DRW_shgroup_state_enable(shgrps->depth_grp, cur_state);
}
if (use_gpumat) {
@@ -1378,14 +1663,14 @@ static void material_transparent(Material *ma,
case GPU_MAT_SUCCESS: {
static int ssr_id = -1; /* TODO transparent SSR */
- *shgrp = DRW_shgroup_material_create(*gpumat, psl->transparent_pass);
+ shgrps->shading_grp = DRW_shgroup_material_create(*gpumat, psl->transparent_pass);
bool use_blend = true;
bool use_diffuse = GPU_material_flag_get(*gpumat, GPU_MATFLAG_DIFFUSE);
bool use_glossy = GPU_material_flag_get(*gpumat, GPU_MATFLAG_GLOSSY);
bool use_refract = GPU_material_flag_get(*gpumat, GPU_MATFLAG_REFRACT);
- add_standard_uniforms(*shgrp,
+ add_standard_uniforms(shgrps->shading_grp,
sldata,
vedata,
&ssr_id,
@@ -1394,7 +1679,8 @@ static void material_transparent(Material *ma,
use_glossy,
use_refract,
use_ssrefract,
- use_blend);
+ use_blend,
+ DEFAULT_RENDER_PASS_FLAG);
break;
}
case GPU_MAT_QUEUED: {
@@ -1413,13 +1699,13 @@ static void material_transparent(Material *ma,
}
/* Fallback to default shader */
- if (*shgrp == NULL) {
- *shgrp = EEVEE_default_shading_group_create(
+ if (shgrps->shading_grp == NULL) {
+ shgrps->shading_grp = EEVEE_default_shading_group_create(
sldata, vedata, psl->transparent_pass, false, true, false);
- DRW_shgroup_uniform_vec3(*shgrp, "basecol", color_p, 1);
- DRW_shgroup_uniform_float(*shgrp, "metallic", metal_p, 1);
- DRW_shgroup_uniform_float(*shgrp, "specular", spec_p, 1);
- DRW_shgroup_uniform_float(*shgrp, "roughness", rough_p, 1);
+ DRW_shgroup_uniform_vec3(shgrps->shading_grp, "basecol", color_p, 1);
+ DRW_shgroup_uniform_float(shgrps->shading_grp, "metallic", metal_p, 1);
+ DRW_shgroup_uniform_float(shgrps->shading_grp, "specular", spec_p, 1);
+ DRW_shgroup_uniform_float(shgrps->shading_grp, "roughness", rough_p, 1);
}
cur_state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM;
@@ -1427,8 +1713,8 @@ static void material_transparent(Material *ma,
cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0;
/* Disable other blend modes and use the one we want. */
- DRW_shgroup_state_disable(*shgrp, all_state);
- DRW_shgroup_state_enable(*shgrp, cur_state);
+ DRW_shgroup_state_disable(shgrps->shading_grp, all_state);
+ DRW_shgroup_state_enable(shgrps->shading_grp, cur_state);
}
/* Return correct material or empty default material if slot is empty. */
@@ -1460,10 +1746,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
const int materials_len = DRW_cache_object_material_count_get(ob);
- struct DRWShadingGroup **shgrp_array = BLI_array_alloca(shgrp_array, materials_len);
- struct DRWShadingGroup **shgrp_depth_array = BLI_array_alloca(shgrp_depth_array,
- materials_len);
- struct DRWShadingGroup **shgrp_depth_clip_array = BLI_array_alloca(shgrp_depth_clip_array,
+ struct EeveeMaterialShadingGroups *shgrps_array = BLI_array_alloca(shgrps_array,
materials_len);
struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
@@ -1472,11 +1755,9 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
for (int i = 0; i < materials_len; i++) {
ma_array[i] = eevee_object_material_get(ob, i);
+ memset(&shgrps_array[i], 0, sizeof(EeveeMaterialShadingGroups));
gpumat_array[i] = NULL;
gpumat_depth_array[i] = NULL;
- shgrp_array[i] = NULL;
- shgrp_depth_array[i] = NULL;
- shgrp_depth_clip_array[i] = NULL;
if (holdout) {
material_opaque(ma_array[i],
@@ -1485,9 +1766,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
vedata,
&gpumat_array[i],
&gpumat_depth_array[i],
- &shgrp_array[i],
- &shgrp_depth_array[i],
- &shgrp_depth_clip_array[i],
+ &shgrps_array[i],
true);
continue;
}
@@ -1502,18 +1781,11 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
vedata,
&gpumat_array[i],
&gpumat_depth_array[i],
- &shgrp_array[i],
- &shgrp_depth_array[i],
- &shgrp_depth_clip_array[i],
+ &shgrps_array[i],
false);
break;
case MA_BM_BLEND:
- material_transparent(ma_array[i],
- sldata,
- vedata,
- &gpumat_array[i],
- &shgrp_array[i],
- &shgrp_depth_array[i]);
+ material_transparent(ma_array[i], sldata, vedata, &gpumat_array[i], &shgrps_array[i]);
break;
default:
BLI_assert(0);
@@ -1538,10 +1810,32 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
if (use_sculpt_pbvh) {
/* Vcol is not supported in the modes that require PBVH drawing. */
- bool use_vcol = false;
- DRW_shgroup_call_sculpt_with_materials(shgrp_array, ob, use_vcol);
- DRW_shgroup_call_sculpt_with_materials(shgrp_depth_array, ob, use_vcol);
- DRW_shgroup_call_sculpt_with_materials(shgrp_depth_clip_array, ob, use_vcol);
+ const bool use_vcol = false;
+ struct DRWShadingGroup **sculpt_shgrps_array = BLI_array_alloca(sculpt_shgrps_array,
+ materials_len);
+ for (int i = 0; i < materials_len; i++) {
+ sculpt_shgrps_array[i] = shgrps_array[i].shading_grp;
+ }
+ DRW_shgroup_call_sculpt_with_materials(sculpt_shgrps_array, ob, use_vcol);
+
+ for (int i = 0; i < materials_len; i++) {
+ sculpt_shgrps_array[i] = shgrps_array[i].depth_grp;
+ }
+ DRW_shgroup_call_sculpt_with_materials(sculpt_shgrps_array, ob, use_vcol);
+ for (int i = 0; i < materials_len; i++) {
+ sculpt_shgrps_array[i] = shgrps_array[i].depth_clip_grp;
+ }
+ DRW_shgroup_call_sculpt_with_materials(sculpt_shgrps_array, ob, use_vcol);
+
+ for (int renderpass_index = 0;
+ renderpass_index < stl->g_data->render_passes_material_count;
+ renderpass_index++) {
+ for (int i = 0; i < materials_len; i++) {
+ sculpt_shgrps_array[i] = shgrps_array[i].material_accum_grp[renderpass_index];
+ }
+ DRW_shgroup_call_sculpt_with_materials(sculpt_shgrps_array, ob, use_vcol);
+ }
+
/* TODO(fclem): Support shadows in sculpt mode. */
}
else if (mat_geom) {
@@ -1565,10 +1859,16 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
oedata->ob = ob;
oedata->test_data = &sldata->probes->vis_data;
}
-
- ADD_SHGROUP_CALL(shgrp_array[i], ob, mat_geom[i], oedata);
- ADD_SHGROUP_CALL_SAFE(shgrp_depth_array[i], ob, mat_geom[i], oedata);
- ADD_SHGROUP_CALL_SAFE(shgrp_depth_clip_array[i], ob, mat_geom[i], oedata);
+ EeveeMaterialShadingGroups *shgrps = &shgrps_array[i];
+ ADD_SHGROUP_CALL(shgrps->shading_grp, ob, mat_geom[i], oedata);
+ ADD_SHGROUP_CALL_SAFE(shgrps->depth_grp, ob, mat_geom[i], oedata);
+ ADD_SHGROUP_CALL_SAFE(shgrps->depth_clip_grp, ob, mat_geom[i], oedata);
+ for (int renderpass_index = 0;
+ renderpass_index < stl->g_data->render_passes_material_count;
+ renderpass_index++) {
+ ADD_SHGROUP_CALL_SAFE(
+ shgrps->material_accum_grp[renderpass_index], ob, mat_geom[i], oedata);
+ }
/* Shadow Pass */
struct GPUMaterial *gpumat;
@@ -1667,9 +1967,33 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata,
shgrp = DRW_shgroup_material_hair_create(ob, psys, md, psl->material_pass, gpumat);
if (!use_diffuse && !use_glossy && !use_refract) {
- /* FIXME: Small hack to avoid issue when utilTex is needed for
+ /* HACK: Small hack to avoid issue when utilTex is needed for
+ * world_normals_get and none of the bsdfs are present.
+ * This binds utilTex even if not needed. */
+ DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
+ }
+
+ add_standard_uniforms(shgrp,
+ sldata,
+ vedata,
+ &ssr_id,
+ NULL,
+ use_diffuse,
+ use_glossy,
+ use_refract,
+ false,
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
+
+ /* Add the hair to all the render_passes that are enabled */
+ RENDER_PASS_ITER_BEGIN(
+ stl->g_data->render_passes, render_pass_index, render_pass_flag)
+ shgrp = DRW_shgroup_material_hair_create(
+ ob, psys, md, psl->material_accum_pass[render_pass_index], gpumat);
+ if (!use_diffuse && !use_glossy && !use_refract) {
+ /* Small hack to avoid issue when utilTex is needed for
* world_normals_get and none of the bsdfs that need it are present.
- * This can try to bind utilTex even if not needed. */
+ * This binds `utilTex` even if not needed. */
DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
}
@@ -1682,7 +2006,10 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata,
use_glossy,
use_refract,
false,
- false);
+ false,
+ render_pass_flag);
+ RENDER_PASS_ITER_END(render_pass_index)
+
break;
}
case GPU_MAT_QUEUED: {
@@ -1707,6 +2034,24 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata,
DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
+
+ RENDER_PASS_ITER_BEGIN(stl->g_data->render_passes, render_pass_index, render_pass_flag)
+ shgrp = EEVEE_default_hair_render_pass_shading_group_get(
+ sldata,
+ vedata,
+ ob,
+ psys,
+ md,
+ holdout,
+ use_ssr,
+ psl->material_accum_pass[render_pass_index],
+ render_pass_flag);
+
+ DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
+ RENDER_PASS_ITER_END(render_pass_index)
}
/* Shadows */
@@ -1762,3 +2107,180 @@ void EEVEE_materials_draw_opaque(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Pass
DRW_draw_pass(psl->material_pass);
DRW_draw_pass(psl->material_pass_cull);
}
+
+/* -------------------------------------------------------------------- */
+
+/** \name Render Passes
+ * \{ */
+
+void EEVEE_material_renderpasses_init(EEVEE_Data *vedata)
+{
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PrivateData *g_data = stl->g_data;
+
+ /* For diffuse and glossy we calculate the final light + color buffer where we extract the
+ * light from by dividing by the color buffer. When one the light is requested we also tag
+ * the color buffer to do the extraction. */
+ if (g_data->render_passes & EEVEE_RENDER_PASS_DIFFUSE_LIGHT) {
+ g_data->render_passes |= EEVEE_RENDER_PASS_DIFFUSE_COLOR;
+ }
+ if (g_data->render_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT) {
+ g_data->render_passes |= EEVEE_RENDER_PASS_SPECULAR_COLOR;
+ }
+
+ /* Calculate the number of material based render passes */
+ uint num_render_passes = count_bits_i(stl->g_data->render_passes & EEVEE_RENDERPASSES_MATERIAL);
+ if ((num_render_passes != 0 && stl->g_data->render_passes & EEVEE_RENDER_PASS_ENVIRONMENT) ==
+ 0) {
+ num_render_passes += 1;
+ }
+ stl->g_data->render_passes_material_count = num_render_passes;
+}
+
+void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+
+ float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ /* Create FrameBuffer. */
+
+ /* Should be enough precision for many samples. */
+ const eGPUTextureFormat texture_format_material_accum = (tot_samples > 128) ? GPU_RGBA32F :
+ GPU_RGBA16F;
+ const eViewLayerEEVEEPassType render_passes = stl->g_data->render_passes &
+ EEVEE_RENDERPASSES_MATERIAL;
+ if (render_passes != 0) {
+ GPU_framebuffer_ensure_config(&fbl->material_accum_fb,
+ {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_LEAVE});
+ int render_pass_index = ((render_passes & EEVEE_RENDER_PASS_ENVIRONMENT) != 0) ? 0 : 1;
+ for (int bit = 0; bit < 32; bit++) {
+ eViewLayerEEVEEPassType bitflag = (1 << bit);
+ if ((render_passes & bitflag) != 0) {
+
+ DRW_texture_ensure_fullscreen_2d(
+ &txl->material_accum[render_pass_index], texture_format_material_accum, 0);
+
+ /* Clear texture. */
+ if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
+ GPU_framebuffer_texture_attach(
+ fbl->material_accum_fb, txl->material_accum[render_pass_index], 0, 0);
+ GPU_framebuffer_bind(fbl->material_accum_fb);
+ GPU_framebuffer_clear_color(fbl->material_accum_fb, clear);
+ GPU_framebuffer_bind(fbl->main_fb);
+ GPU_framebuffer_texture_detach(fbl->material_accum_fb,
+ txl->material_accum[render_pass_index]);
+ }
+ render_pass_index++;
+ }
+ }
+
+ if ((render_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT) &&
+ (effects->enabled_effects & EFFECT_SSR)) {
+ EEVEE_reflection_output_init(sldata, vedata, tot_samples);
+ }
+
+ if (render_passes & EEVEE_RENDER_PASS_ENVIRONMENT) {
+ Scene *scene = draw_ctx->scene;
+ World *wo = scene->world;
+
+ if (wo && wo->use_nodes && wo->nodetree) {
+ struct GPUMaterial *gpumat = EEVEE_material_world_background_get(scene, wo);
+ if (GPU_material_status(gpumat) == GPU_MAT_SUCCESS) {
+ DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, psl->material_accum_pass[0]);
+ add_background_uniforms(grp, sldata, vedata);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ }
+ }
+ }
+ }
+}
+
+void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_TextureList *txl = vedata->txl;
+
+ if (fbl->material_accum_fb != NULL) {
+ for (int renderpass_index = 0; renderpass_index < stl->g_data->render_passes_material_count;
+ renderpass_index++) {
+ if (txl->material_accum[renderpass_index] != NULL) {
+ GPU_framebuffer_texture_attach(
+ fbl->material_accum_fb, txl->material_accum[renderpass_index], 0, 0);
+ GPU_framebuffer_bind(fbl->material_accum_fb);
+ DRW_draw_pass(psl->material_accum_pass[renderpass_index]);
+ GPU_framebuffer_bind(fbl->main_fb);
+ GPU_framebuffer_texture_detach(fbl->material_accum_fb,
+ txl->material_accum[renderpass_index]);
+ }
+ }
+ if ((stl->g_data->render_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT) &&
+ (stl->effects->enabled_effects & EFFECT_SSR)) {
+ EEVEE_reflection_output_accumulate(sldata, vedata);
+ }
+ }
+}
+
+int EEVEE_material_output_pass_index_get(EEVEE_ViewLayerData *UNUSED(sldata),
+ EEVEE_Data *vedata,
+ eViewLayerEEVEEPassType renderpass_type)
+{
+ EEVEE_StorageList *stl = vedata->stl;
+
+ BLI_assert((stl->g_data->render_passes & EEVEE_RENDERPASSES_MATERIAL) != 0);
+ BLI_assert((stl->g_data->render_passes & EEVEE_RENDERPASSES_MATERIAL & renderpass_type) != 0);
+
+ /* pass_index 0 is reserved for the environment pass. */
+ if ((stl->g_data->render_passes & EEVEE_RENDER_PASS_ENVIRONMENT & renderpass_type) != 0) {
+ return 0;
+ }
+
+ /* pass_index 0 is reserved for the environment pass. Other passes start from index 1 */
+ int index = 1;
+ eViewLayerEEVEEPassType active_material_passes = stl->g_data->render_passes &
+ EEVEE_RENDERPASSES_MATERIAL &
+ ~EEVEE_RENDER_PASS_ENVIRONMENT;
+
+ for (int bitshift = 0; bitshift < 32; bitshift++) {
+ eViewLayerEEVEEPassType pass_flag = (1 << bitshift);
+ if (pass_flag == renderpass_type) {
+ break;
+ }
+ if (active_material_passes & pass_flag) {
+ index++;
+ }
+ }
+
+ return index;
+}
+
+/* Get the pass index that contains the color pass for the given renderpass_type. */
+int EEVEE_material_output_color_pass_index_get(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ eViewLayerEEVEEPassType renderpass_type)
+{
+ BLI_assert(
+ ELEM(renderpass_type, EEVEE_RENDER_PASS_DIFFUSE_LIGHT, EEVEE_RENDER_PASS_SPECULAR_LIGHT));
+ eViewLayerEEVEEPassType color_pass_type;
+ switch (renderpass_type) {
+ case EEVEE_RENDER_PASS_DIFFUSE_LIGHT:
+ color_pass_type = EEVEE_RENDER_PASS_DIFFUSE_COLOR;
+ break;
+ case EEVEE_RENDER_PASS_SPECULAR_LIGHT:
+ color_pass_type = EEVEE_RENDER_PASS_SPECULAR_COLOR;
+ break;
+ default:
+ color_pass_type = 0;
+ BLI_assert(false);
+ }
+ return EEVEE_material_output_pass_index_get(sldata, vedata, color_pass_type);
+}
+/* \} */
diff --git a/source/blender/draw/engines/eevee/eevee_mist.c b/source/blender/draw/engines/eevee/eevee_mist.c
index c9b56a6d551..cdcfd64d995 100644
--- a/source/blender/draw/engines/eevee/eevee_mist.c
+++ b/source/blender/draw/engines/eevee/eevee_mist.c
@@ -114,6 +114,8 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRWShadingGroup *grp = DRW_shgroup_create(e_data.mist_sh, psl->mist_accum_ps);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_vec3(grp, "mistSettings", &g_data->mist_start, 1);
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c
index 6ba518b3a28..be4dfd07ce1 100644
--- a/source/blender/draw/engines/eevee/eevee_occlusion.c
+++ b/source/blender/draw/engines/eevee/eevee_occlusion.c
@@ -170,6 +170,8 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
else {
@@ -207,6 +209,8 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
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", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call(grp, quad, NULL);
DRW_PASS_CREATE(psl->ao_horizon_search_layer, DRW_STATE_WRITE_COLOR);
@@ -215,6 +219,8 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
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", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_int(grp, "layer", &stl->effects->ao_depth_layer, 1);
DRW_shgroup_call(grp, quad, NULL);
@@ -227,6 +233,8 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call(grp, quad, NULL);
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 7810de289df..a2ed0a16d89 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -136,11 +136,29 @@ extern struct DrawEngineType draw_engine_eevee_type;
((v3d->shading.type == OB_RENDER) && \
((v3d->shading.flag & V3D_SHADING_SCENE_WORLD_RENDER) == 0))))
-#define OCTAHEDRAL_SIZE_FROM_CUBESIZE(cube_size) \
- ((int)ceilf(sqrtf((cube_size * cube_size) * 6.0f)))
#define MIN_CUBE_LOD_LEVEL 3
+
+BLI_INLINE int octahedral_size_from_cubesize(int cube_size)
+{
+ int cube_pixel_count = SQUARE(cube_size) * 6.0f;
+ int octa_size = (int)ceilf(sqrtf(cube_pixel_count));
+ int lod_count = log2_floor_u(octa_size) - MIN_CUBE_LOD_LEVEL;
+ /* Find lowest lod size and grow back to avoid having non matching mipsizes that would
+ * break trilinear interpolation. */
+ octa_size /= 1 << lod_count;
+ octa_size *= 1 << lod_count;
+ return octa_size;
+}
+
#define MAX_PLANAR_LOD_LEVEL 9
+/* All the renderpasses that use the GPUMaterial for accumulation */
+#define EEVEE_RENDERPASSES_MATERIAL \
+ (EEVEE_RENDER_PASS_EMIT | EEVEE_RENDER_PASS_DIFFUSE_COLOR | EEVEE_RENDER_PASS_DIFFUSE_LIGHT | \
+ EEVEE_RENDER_PASS_SPECULAR_COLOR | EEVEE_RENDER_PASS_SPECULAR_LIGHT | \
+ EEVEE_RENDER_PASS_ENVIRONMENT)
+#define MAX_MATERIAL_RENDER_PASSES 6
+#define MAX_MATERIAL_RENDER_PASSES_UBO 6
/* World shader variations */
enum {
VAR_WORLD_BACKGROUND = 0,
@@ -198,6 +216,7 @@ typedef struct EEVEE_BoundBox {
typedef struct EEVEE_PassList {
/* Shadows */
struct DRWPass *shadow_pass;
+ struct DRWPass *shadow_accum_pass;
/* Probes */
struct DRWPass *probe_background;
@@ -220,6 +239,7 @@ typedef struct EEVEE_PassList {
struct DRWPass *bloom_downsample;
struct DRWPass *bloom_upsample;
struct DRWPass *bloom_resolve;
+ struct DRWPass *bloom_accum_ps;
struct DRWPass *dof_down;
struct DRWPass *dof_scatter;
struct DRWPass *dof_resolve;
@@ -228,11 +248,11 @@ typedef struct EEVEE_PassList {
struct DRWPass *volumetric_scatter_ps;
struct DRWPass *volumetric_integration_ps;
struct DRWPass *volumetric_resolve_ps;
+ struct DRWPass *volumetric_accum_ps;
struct DRWPass *ssr_raytrace;
struct DRWPass *ssr_resolve;
struct DRWPass *sss_blur_ps;
struct DRWPass *sss_resolve_ps;
- struct DRWPass *sss_accum_ps;
struct DRWPass *sss_translucency_ps;
struct DRWPass *color_downsample_ps;
struct DRWPass *color_downsample_cube_ps;
@@ -264,6 +284,7 @@ typedef struct EEVEE_PassList {
struct DRWPass *sss_pass_cull;
struct DRWPass *material_pass;
struct DRWPass *material_pass_cull;
+ struct DRWPass *material_accum_pass[MAX_MATERIAL_RENDER_PASSES];
struct DRWPass *refract_pass;
struct DRWPass *transparent_pass;
struct DRWPass *background_pass;
@@ -281,6 +302,9 @@ typedef struct EEVEE_FramebufferList {
struct GPUFrameBuffer *bloom_blit_fb;
struct GPUFrameBuffer *bloom_down_fb[MAX_BLOOM_STEP];
struct GPUFrameBuffer *bloom_accum_fb[MAX_BLOOM_STEP - 1];
+ struct GPUFrameBuffer *bloom_pass_accum_fb;
+ struct GPUFrameBuffer *shadow_accum_fb;
+ struct GPUFrameBuffer *ssr_accum_fb;
struct GPUFrameBuffer *sss_blur_fb;
struct GPUFrameBuffer *sss_blit_fb;
struct GPUFrameBuffer *sss_resolve_fb;
@@ -292,9 +316,11 @@ typedef struct EEVEE_FramebufferList {
struct GPUFrameBuffer *volumetric_fb;
struct GPUFrameBuffer *volumetric_scat_fb;
struct GPUFrameBuffer *volumetric_integ_fb;
+ struct GPUFrameBuffer *volumetric_accum_fb;
struct GPUFrameBuffer *screen_tracing_fb;
struct GPUFrameBuffer *refract_fb;
struct GPUFrameBuffer *mist_accum_fb;
+ struct GPUFrameBuffer *material_accum_fb;
struct GPUFrameBuffer *renderpass_fb;
struct GPUFrameBuffer *ao_accum_fb;
struct GPUFrameBuffer *velocity_resolve_fb;
@@ -320,8 +346,11 @@ typedef struct EEVEE_TextureList {
struct GPUTexture *color_post; /* R16_G16_B16 */
struct GPUTexture *mist_accum;
struct GPUTexture *ao_accum;
- struct GPUTexture *sss_dir_accum;
- struct GPUTexture *sss_col_accum;
+ struct GPUTexture *sss_accum;
+ struct GPUTexture *material_accum[MAX_MATERIAL_RENDER_PASSES];
+ struct GPUTexture *bloom_accum;
+ struct GPUTexture *ssr_accum;
+ struct GPUTexture *shadow_accum;
struct GPUTexture *refract_color;
struct GPUTexture *taa_history;
@@ -333,6 +362,8 @@ typedef struct EEVEE_TextureList {
struct GPUTexture *volume_transmit;
struct GPUTexture *volume_scatter_history;
struct GPUTexture *volume_transmit_history;
+ struct GPUTexture *volume_scatter_accum;
+ struct GPUTexture *volume_transmittance_accum;
struct GPUTexture *lookdev_grid_tx;
struct GPUTexture *lookdev_cube_tx;
@@ -361,6 +392,17 @@ typedef struct EEVEE_StorageList {
LightCacheTexture *lookdev_cube_mips;
} EEVEE_StorageList;
+/* ************ RENDERPASS UBO ************* */
+typedef struct EEVEE_RenderPassData {
+ int renderPassDiffuse;
+ int renderPassDiffuseLight;
+ int renderPassGlossy;
+ int renderPassGlossyLight;
+ int renderPassEmit;
+ int renderPassSSSColor;
+ int _pad[2];
+} EEVEE_RenderPassData;
+
/* ************ LIGHT UBO ************* */
typedef struct EEVEE_Light {
float position[3], invsqrdist;
@@ -408,6 +450,7 @@ BLI_STATIC_ASSERT_ALIGN(EEVEE_Light, 16)
BLI_STATIC_ASSERT_ALIGN(EEVEE_Shadow, 16)
BLI_STATIC_ASSERT_ALIGN(EEVEE_ShadowCube, 16)
BLI_STATIC_ASSERT_ALIGN(EEVEE_ShadowCascade, 16)
+BLI_STATIC_ASSERT_ALIGN(EEVEE_RenderPassData, 16)
BLI_STATIC_ASSERT(sizeof(EEVEE_Shadow) * MAX_SHADOW +
sizeof(EEVEE_ShadowCascade) * MAX_SHADOW_CASCADE +
@@ -708,6 +751,10 @@ typedef struct EEVEE_ViewLayerData {
struct GPUUniformBuffer *grid_ubo;
struct GPUUniformBuffer *planar_ubo;
+ /* Material Render passes */
+ struct EEVEE_RenderPassData renderpass_data[MAX_MATERIAL_RENDER_PASSES_UBO];
+ struct GPUUniformBuffer *renderpass_ubo[MAX_MATERIAL_RENDER_PASSES_UBO];
+
/* Common Uniform Buffer */
struct EEVEE_CommonUniformBuffer common_data;
struct GPUUniformBuffer *common_ubo;
@@ -759,6 +806,7 @@ typedef struct EEVEE_Data {
typedef struct EEVEE_PrivateData {
struct DRWShadingGroup *shadow_shgrp;
+ struct DRWShadingGroup *shadow_accum_shgrp;
struct DRWShadingGroup *depth_shgrp;
struct DRWShadingGroup *depth_shgrp_cull;
struct DRWShadingGroup *depth_shgrp_clip;
@@ -803,12 +851,17 @@ typedef struct EEVEE_PrivateData {
/* Renderpasses */
/* Bitmask containing the active render_passes */
- eScenePassType render_passes;
+ eViewLayerEEVEEPassType render_passes;
/* Uniform references that are referenced inside the `renderpass_pass`. They are updated
* to reuse the drawing pass and the shading group. */
int renderpass_type;
+ int renderpass_postprocess;
int renderpass_current_sample;
GPUTexture *renderpass_input;
+ GPUTexture *renderpass_col_input;
+ GPUTexture *renderpass_light_input;
+ /* The number of active material based render passes */
+ uint render_passes_material_count;
/** For rendering shadows. */
struct DRWView *cube_views[6];
@@ -860,11 +913,20 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene,
bool use_hashed_alpha,
bool is_shadow);
struct GPUMaterial *EEVEE_material_hair_get(struct Scene *scene, Material *ma);
+struct GPUUniformBuffer *EEVEE_material_default_render_pass_ubo_get(EEVEE_ViewLayerData *sldata);
void EEVEE_materials_free(void);
void EEVEE_materials_draw_opaque(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl);
void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3]);
void EEVEE_update_viewvecs(float invproj[4][4], float winmat[4][4], float (*r_viewvecs)[4]);
-
+void EEVEE_material_renderpasses_init(EEVEE_Data *vedata);
+void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples);
+void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+int EEVEE_material_output_pass_index_get(EEVEE_ViewLayerData *UNUSED(sldata),
+ EEVEE_Data *vedata,
+ eViewLayerEEVEEPassType renderpass_type);
+int EEVEE_material_output_color_pass_index_get(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ eViewLayerEEVEEPassType renderpass_type);
/* eevee_lights.c */
void eevee_light_matrix_get(const EEVEE_Light *evli, float r_mat[4][4]);
void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
@@ -896,6 +958,8 @@ void EEVEE_shadows_draw_cascades(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
DRWView *view,
int cascade_index);
+void EEVEE_shadow_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples);
+void EEVEE_shadow_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_shadows_free(void);
/* eevee_sampling.c */
@@ -923,6 +987,7 @@ struct GPUShader *EEVEE_shaders_probe_filter_visibility_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_grid_fill_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_planar_downsample_sh_get(void);
struct GPUShader *EEVEE_shaders_default_studiolight_sh_get(void);
+struct GPUShader *EEVEE_shaders_background_studiolight_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_cube_display_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_grid_display_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_planar_display_sh_get(void);
@@ -995,6 +1060,8 @@ void EEVEE_depth_of_field_free(void);
int EEVEE_bloom_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_bloom_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_bloom_draw(EEVEE_Data *vedata);
+void EEVEE_bloom_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples);
+void EEVEE_bloom_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_bloom_free(void);
/* eevee_occlusion.c */
@@ -1016,6 +1083,11 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_refraction_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_reflection_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_reflection_output_init(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ uint tot_samples);
+void EEVEE_reflection_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+
void EEVEE_screen_raytrace_free(void);
/* eevee_subsurface.c */
@@ -1055,10 +1127,12 @@ void EEVEE_renderpasses_init(EEVEE_Data *vedata);
void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
uint tot_samples);
-void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ bool post_effect);
void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
- eScenePassType renderpass_type);
+ eViewLayerEEVEEPassType renderpass_type);
void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_renderpasses_draw_debug(EEVEE_Data *vedata);
void EEVEE_renderpasses_free(void);
@@ -1087,6 +1161,8 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_volumes_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_volumes_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_volumes_resolve(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_volumes_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples);
+void EEVEE_volumes_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_volumes_free_smoke_textures(void);
void EEVEE_volumes_free(void);
@@ -1104,7 +1180,7 @@ void EEVEE_draw_effects(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_effects_free(void);
/* eevee_render.c */
-void EEVEE_render_init(EEVEE_Data *vedata,
+bool EEVEE_render_init(EEVEE_Data *vedata,
struct RenderEngine *engine,
struct Depsgraph *depsgraph);
void EEVEE_render_cache(void *vedata,
@@ -1121,9 +1197,9 @@ void EEVEE_render_update_passes(struct RenderEngine *engine,
/** eevee_lookdev.c */
void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata,
DRWShadingGroup **grp,
DRWPass *pass,
- float background_alpha,
struct World *world,
EEVEE_LightProbesInfo *pinfo);
void EEVEE_lookdev_draw(EEVEE_Data *vedata);
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index 063510d51e6..3a5d9e96b80 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -46,7 +46,8 @@
#include "eevee_private.h"
-void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *depsgraph)
+/* Return true if init properly. */
+bool EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *depsgraph)
{
EEVEE_Data *vedata = (EEVEE_Data *)ved;
EEVEE_StorageList *stl = vedata->stl;
@@ -106,7 +107,7 @@ void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
max_dim);
RE_engine_set_error_message(engine, error_msg);
G.is_break = true;
- return;
+ return false;
}
/* XXX overriding viewport size. Simplify things but is not really 100% safe. */
@@ -168,6 +169,8 @@ void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
EEVEE_subsurface_cache_init(sldata, vedata);
EEVEE_temporal_sampling_cache_init(sldata, vedata);
EEVEE_volumes_cache_init(sldata, vedata);
+
+ return true;
}
/* Used by light cache. in this case engine is NULL. */
@@ -230,6 +233,9 @@ static void eevee_render_color_result(RenderLayer *rl,
EEVEE_Data *vedata)
{
RenderPass *rp = RE_pass_find_by_name(rl, render_pass_name, viewname);
+ if (rp == NULL) {
+ return;
+ }
GPU_framebuffer_bind(framebuffer);
GPU_framebuffer_read_color(framebuffer,
vedata->stl->g_data->overscan_pixels + rect->xmin,
@@ -251,35 +257,6 @@ static void eevee_render_result_combined(RenderLayer *rl,
rl, viewname, rect, RE_PASSNAME_COMBINED, 4, vedata->stl->effects->final_fb, vedata);
}
-static void eevee_render_result_subsurface(RenderLayer *rl,
- const char *viewname,
- const rcti *rect,
- EEVEE_Data *vedata,
- EEVEE_ViewLayerData *sldata)
-{
- if (vedata->fbl->sss_accum_fb == NULL) {
- /* SSS is not enabled. */
- return;
- }
-
- if ((vedata->stl->g_data->render_passes & SCE_PASS_SUBSURFACE_COLOR) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_SUBSURFACE_COLOR);
- eevee_render_color_result(
- rl, viewname, rect, RE_PASSNAME_SUBSURFACE_COLOR, 3, vedata->fbl->renderpass_fb, vedata);
- }
-
- if ((vedata->stl->g_data->render_passes & SCE_PASS_SUBSURFACE_DIRECT) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_SUBSURFACE_DIRECT);
- eevee_render_color_result(
- rl, viewname, rect, RE_PASSNAME_SUBSURFACE_DIRECT, 3, vedata->fbl->renderpass_fb, vedata);
- }
-
- if ((vedata->stl->g_data->render_passes & SCE_PASS_SUBSURFACE_INDIRECT) != 0) {
- /* Do nothing as all the lighting is in the direct pass.
- * TODO : Separate Direct from indirect lighting. */
- }
-}
-
static void eevee_render_result_normal(RenderLayer *rl,
const char *viewname,
const rcti *rect,
@@ -293,8 +270,8 @@ static void eevee_render_result_normal(RenderLayer *rl,
return;
}
- if ((vedata->stl->g_data->render_passes & SCE_PASS_NORMAL) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_NORMAL);
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_NORMAL) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_NORMAL);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_NORMAL, 3, vedata->fbl->renderpass_fb, vedata);
}
@@ -313,8 +290,8 @@ static void eevee_render_result_z(RenderLayer *rl,
return;
}
- if ((vedata->stl->g_data->render_passes & SCE_PASS_Z) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_Z);
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_Z) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_Z);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_Z, 1, vedata->fbl->renderpass_fb, vedata);
}
@@ -326,31 +303,142 @@ static void eevee_render_result_mist(RenderLayer *rl,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
- if ((vedata->stl->g_data->render_passes & SCE_PASS_MIST) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_MIST);
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_MIST) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_MIST);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_MIST, 1, vedata->fbl->renderpass_fb, vedata);
}
}
+static void eevee_render_result_shadow(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_SHADOW) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_SHADOW);
+ eevee_render_color_result(
+ rl, viewname, rect, RE_PASSNAME_SHADOW, 3, vedata->fbl->renderpass_fb, vedata);
+ }
+}
+
static void eevee_render_result_occlusion(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
- if (vedata->fbl->ao_accum_fb == NULL) {
+ if ((vedata->stl->effects->enabled_effects & EFFECT_GTAO) == 0) {
/* AO is not enabled. */
return;
}
- if ((vedata->stl->g_data->render_passes & SCE_PASS_AO) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_AO);
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_AO) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_AO);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_AO, 3, vedata->fbl->renderpass_fb, vedata);
}
}
+static void eevee_render_result_bloom(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ if ((vedata->stl->effects->enabled_effects & EFFECT_BLOOM) == 0) {
+ /* Bloom is not enabled. */
+ return;
+ }
+
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_BLOOM) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_BLOOM);
+ eevee_render_color_result(
+ rl, viewname, rect, RE_PASSNAME_BLOOM, 3, vedata->fbl->renderpass_fb, vedata);
+ }
+}
+
+#define EEVEE_RENDER_RESULT_MATERIAL_PASS(pass_name, eevee_pass_type) \
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_##eevee_pass_type) != 0) { \
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_##eevee_pass_type); \
+ eevee_render_color_result( \
+ rl, viewname, rect, RE_PASSNAME_##pass_name, 3, vedata->fbl->renderpass_fb, vedata); \
+ }
+
+static void eevee_render_result_diffuse_color(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ EEVEE_RENDER_RESULT_MATERIAL_PASS(DIFFUSE_COLOR, DIFFUSE_COLOR)
+}
+
+static void eevee_render_result_diffuse_direct(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ EEVEE_RENDER_RESULT_MATERIAL_PASS(DIFFUSE_DIRECT, DIFFUSE_LIGHT)
+}
+
+static void eevee_render_result_specular_color(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ EEVEE_RENDER_RESULT_MATERIAL_PASS(GLOSSY_COLOR, SPECULAR_COLOR)
+}
+
+static void eevee_render_result_specular_direct(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ EEVEE_RENDER_RESULT_MATERIAL_PASS(GLOSSY_DIRECT, SPECULAR_LIGHT)
+}
+
+static void eevee_render_result_emission(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ EEVEE_RENDER_RESULT_MATERIAL_PASS(EMIT, EMIT)
+}
+
+static void eevee_render_result_environment(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ EEVEE_RENDER_RESULT_MATERIAL_PASS(ENVIRONMENT, ENVIRONMENT)
+}
+
+static void eevee_render_result_volume_scatter(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ EEVEE_RENDER_RESULT_MATERIAL_PASS(VOLUME_SCATTER, VOLUME_SCATTER)
+}
+static void eevee_render_result_volume_transmittance(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ EEVEE_RENDER_RESULT_MATERIAL_PASS(VOLUME_TRANSMITTANCE, VOLUME_TRANSMITTANCE)
+}
+
+#undef EEVEE_RENDER_RESULT_MATERIAL_PASS
+
static void eevee_render_draw_background(EEVEE_Data *vedata)
{
EEVEE_FramebufferList *fbl = vedata->fbl;
@@ -508,7 +596,7 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
/* Volumetrics Resolve Opaque */
EEVEE_volumes_resolve(sldata, vedata);
/* Subsurface output, Occlusion output, Mist output */
- EEVEE_renderpasses_output_accumulate(sldata, vedata);
+ EEVEE_renderpasses_output_accumulate(sldata, vedata, false);
/* Transparent */
GPU_framebuffer_texture_attach(fbl->main_color_fb, dtxl->depth, 0, 0);
GPU_framebuffer_bind(fbl->main_color_fb);
@@ -527,9 +615,18 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
}
eevee_render_result_combined(rl, viewname, rect, vedata, sldata);
- eevee_render_result_subsurface(rl, viewname, rect, vedata, sldata);
eevee_render_result_mist(rl, viewname, rect, vedata, sldata);
eevee_render_result_occlusion(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_shadow(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_diffuse_color(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_diffuse_direct(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_specular_color(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_specular_direct(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_emission(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_environment(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_bloom(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_volume_scatter(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_volume_transmittance(rl, viewname, rect, vedata, sldata);
/* Restore original viewport size. */
DRW_render_viewport_size_set((int[2]){g_data->size_orig[0], g_data->size_orig[1]});
@@ -537,29 +634,35 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
void EEVEE_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
{
- int type;
-
RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
-#define CHECK_PASS(name, channels, chanid) \
+#define CHECK_PASS_LEGACY(name, type, channels, chanid) \
if (view_layer->passflag & (SCE_PASS_##name)) { \
- if (channels == 4) \
- type = SOCK_RGBA; \
- else if (channels == 3) \
- type = SOCK_VECTOR; \
- else \
- type = SOCK_FLOAT; \
+ RE_engine_register_pass( \
+ engine, scene, view_layer, RE_PASSNAME_##name, channels, chanid, type); \
+ } \
+ ((void)0)
+#define CHECK_PASS_EEVEE(name, type, channels, chanid) \
+ if (view_layer->eevee.render_passes & (EEVEE_RENDER_PASS_##name)) { \
RE_engine_register_pass( \
engine, scene, view_layer, RE_PASSNAME_##name, channels, chanid, type); \
} \
((void)0)
- CHECK_PASS(Z, 1, "Z");
- CHECK_PASS(MIST, 1, "Z");
- CHECK_PASS(NORMAL, 3, "XYZ");
- CHECK_PASS(AO, 3, "RGB");
- CHECK_PASS(SUBSURFACE_COLOR, 3, "RGB");
- CHECK_PASS(SUBSURFACE_DIRECT, 3, "RGB");
+ CHECK_PASS_LEGACY(Z, SOCK_FLOAT, 1, "Z");
+ CHECK_PASS_LEGACY(MIST, SOCK_FLOAT, 1, "Z");
+ CHECK_PASS_LEGACY(NORMAL, SOCK_VECTOR, 3, "XYZ");
+ CHECK_PASS_LEGACY(SHADOW, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(AO, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(DIFFUSE_COLOR, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(DIFFUSE_DIRECT, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(GLOSSY_COLOR, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(GLOSSY_DIRECT, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(EMIT, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(ENVIRONMENT, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_EEVEE(VOLUME_SCATTER, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_EEVEE(VOLUME_TRANSMITTANCE, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_EEVEE(BLOOM, SOCK_RGBA, 3, "RGB");
#undef CHECK_PASS
}
diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c
index 44a6c41e170..2f9e8f3d555 100644
--- a/source/blender/draw/engines/eevee/eevee_renderpasses.c
+++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c
@@ -42,19 +42,35 @@ static struct {
struct GPUShader *postprocess_sh;
} e_data = {NULL}; /* Engine data */
+typedef enum eRenderPassPostProcessType {
+ PASS_POST_UNDEFINED = 0,
+ PASS_POST_ACCUMULATED_COLOR = 1,
+ PASS_POST_ACCUMULATED_LIGHT = 2,
+ PASS_POST_ACCUMULATED_VALUE = 3,
+ PASS_POST_DEPTH = 4,
+ PASS_POST_AO = 5,
+ PASS_POST_NORMAL = 6,
+ PASS_POST_TWO_LIGHT_BUFFERS = 7,
+} eRenderPassPostProcessType;
+
/* bitmask containing all renderpasses that need post-processing */
#define EEVEE_RENDERPASSES_WITH_POST_PROCESSING \
- (SCE_PASS_Z | SCE_PASS_MIST | SCE_PASS_NORMAL | SCE_PASS_AO | SCE_PASS_SUBSURFACE_COLOR | \
- SCE_PASS_SUBSURFACE_DIRECT)
-
-#define EEVEE_RENDERPASSES_SUBSURFACE \
- (SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT | SCE_PASS_SUBSURFACE_INDIRECT)
+ (EEVEE_RENDER_PASS_Z | EEVEE_RENDER_PASS_MIST | EEVEE_RENDER_PASS_NORMAL | \
+ EEVEE_RENDER_PASS_AO | EEVEE_RENDER_PASS_BLOOM | EEVEE_RENDER_PASS_VOLUME_SCATTER | \
+ EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE | EEVEE_RENDER_PASS_SHADOW | \
+ EEVEE_RENDERPASSES_MATERIAL)
-#define EEVEE_RENDERPASSES_ALL (EEVEE_RENDERPASSES_WITH_POST_PROCESSING | SCE_PASS_COMBINED)
+#define EEVEE_RENDERPASSES_ALL \
+ (EEVEE_RENDERPASSES_WITH_POST_PROCESSING | EEVEE_RENDER_PASS_COMBINED)
-#define EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE (SCE_PASS_Z | SCE_PASS_NORMAL)
+#define EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE \
+ (EEVEE_RENDER_PASS_Z | EEVEE_RENDER_PASS_NORMAL)
-#define EEVEE_RENDERPASSES_COLOR_PASS (SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT)
+#define EEVEE_RENDERPASSES_COLOR_PASS \
+ (EEVEE_RENDER_PASS_DIFFUSE_COLOR | EEVEE_RENDER_PASS_SPECULAR_COLOR | EEVEE_RENDER_PASS_EMIT | \
+ EEVEE_RENDER_PASS_BLOOM)
+#define EEVEE_RENDERPASSES_LIGHT_PASS \
+ (EEVEE_RENDER_PASS_DIFFUSE_LIGHT | EEVEE_RENDER_PASS_SPECULAR_LIGHT)
bool EEVEE_renderpasses_only_first_sample_pass_active(EEVEE_Data *vedata)
{
@@ -75,8 +91,33 @@ void EEVEE_renderpasses_init(EEVEE_Data *vedata)
g_data->render_passes = v3d->shading.render_pass;
}
else {
- g_data->render_passes = (view_layer->passflag & EEVEE_RENDERPASSES_ALL) | SCE_PASS_COMBINED;
+ eViewLayerEEVEEPassType enabled_render_passes = view_layer->eevee.render_passes;
+
+#define ENABLE_FROM_LEGACY(name_legacy, name_eevee) \
+ SET_FLAG_FROM_TEST(enabled_render_passes, \
+ (view_layer->passflag & SCE_PASS_##name_legacy) != 0, \
+ EEVEE_RENDER_PASS_##name_eevee);
+
+ ENABLE_FROM_LEGACY(Z, Z)
+ ENABLE_FROM_LEGACY(MIST, MIST)
+ ENABLE_FROM_LEGACY(NORMAL, NORMAL)
+ ENABLE_FROM_LEGACY(SHADOW, SHADOW)
+ ENABLE_FROM_LEGACY(AO, AO)
+ ENABLE_FROM_LEGACY(EMIT, EMIT)
+ ENABLE_FROM_LEGACY(ENVIRONMENT, ENVIRONMENT)
+ ENABLE_FROM_LEGACY(DIFFUSE_COLOR, DIFFUSE_COLOR)
+ ENABLE_FROM_LEGACY(GLOSSY_COLOR, SPECULAR_COLOR)
+ ENABLE_FROM_LEGACY(DIFFUSE_DIRECT, DIFFUSE_LIGHT)
+ ENABLE_FROM_LEGACY(GLOSSY_DIRECT, SPECULAR_LIGHT)
+
+ ENABLE_FROM_LEGACY(ENVIRONMENT, ENVIRONMENT)
+
+#undef ENABLE_FROM_LEGACY
+ g_data->render_passes = (enabled_render_passes & EEVEE_RENDERPASSES_ALL) |
+ EEVEE_RENDER_PASS_COMBINED;
}
+
+ EEVEE_material_renderpasses_init(vedata);
}
void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
@@ -87,6 +128,7 @@ void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
EEVEE_TextureList *txl = vedata->txl;
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
EEVEE_PrivateData *g_data = stl->g_data;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
@@ -106,33 +148,54 @@ void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
/* Should be enough to store the data needs for a single pass.
* Some passes will use less, but it is only relevant for final renderings and
- * when renderpasses other than `SCE_PASS_COMBINED` are requested */
+ * when renderpasses other than `EEVEE_RENDER_PASS_COMBINED` are requested */
DRW_texture_ensure_fullscreen_2d(&txl->renderpass, GPU_RGBA16F, 0);
GPU_framebuffer_ensure_config(&fbl->renderpass_fb,
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->renderpass)});
- if ((g_data->render_passes & EEVEE_RENDERPASSES_SUBSURFACE) != 0) {
- EEVEE_subsurface_output_init(sldata, vedata, tot_samples);
+ if ((g_data->render_passes & EEVEE_RENDERPASSES_MATERIAL) != 0) {
+ EEVEE_material_output_init(sldata, vedata, tot_samples);
}
- if ((g_data->render_passes & SCE_PASS_MIST) != 0) {
+ if ((g_data->render_passes & EEVEE_RENDER_PASS_MIST) != 0) {
EEVEE_mist_output_init(sldata, vedata);
}
+ if ((g_data->render_passes & EEVEE_RENDER_PASS_SHADOW) != 0) {
+ EEVEE_shadow_output_init(sldata, vedata, tot_samples);
+ }
- if ((g_data->render_passes & SCE_PASS_AO) != 0) {
+ if ((g_data->render_passes & EEVEE_RENDER_PASS_AO) != 0) {
EEVEE_occlusion_output_init(sldata, vedata, tot_samples);
}
+ if ((g_data->render_passes & EEVEE_RENDER_PASS_BLOOM) != 0 &&
+ (effects->enabled_effects & EFFECT_BLOOM) != 0) {
+ EEVEE_bloom_output_init(sldata, vedata, tot_samples);
+ }
+
+ if ((g_data->render_passes &
+ (EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE | EEVEE_RENDER_PASS_VOLUME_SCATTER)) != 0) {
+ EEVEE_volumes_output_init(sldata, vedata, tot_samples);
+ }
+
/* Create Pass. */
DRW_PASS_CREATE(psl->renderpass_pass, DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.postprocess_sh, psl->renderpass_pass);
/* We set a default texture as not all post processes uses the inputBuffer. */
g_data->renderpass_input = txl->color;
+ g_data->renderpass_col_input = txl->color;
+ g_data->renderpass_light_input = txl->color;
DRW_shgroup_uniform_texture_ref(grp, "inputBuffer", &g_data->renderpass_input);
+ DRW_shgroup_uniform_texture_ref(grp, "inputColorBuffer", &g_data->renderpass_col_input);
+ DRW_shgroup_uniform_texture_ref(
+ grp, "inputSecondLightBuffer", &g_data->renderpass_light_input);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_int(grp, "currentSample", &g_data->renderpass_current_sample, 1);
DRW_shgroup_uniform_int(grp, "renderpassType", &g_data->renderpass_type, 1);
+ DRW_shgroup_uniform_int(grp, "postProcessType", &g_data->renderpass_postprocess, 1);
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
else {
@@ -152,12 +215,13 @@ void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
* Only invoke this function for passes that need post-processing.
*
* After invoking this function the active framebuffer is set to `vedata->fbl->renderpass_fb`. */
-void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *UNUSED(sldata),
+void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
- eScenePassType renderpass_type)
+ eViewLayerEEVEEPassType renderpass_type)
{
EEVEE_PassList *psl = vedata->psl;
EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_PrivateData *g_data = stl->g_data;
EEVEE_EffectsInfo *effects = stl->effects;
@@ -165,51 +229,133 @@ void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *UNUSED(sldata),
const int current_sample = effects->taa_current_sample;
g_data->renderpass_current_sample = current_sample;
g_data->renderpass_type = renderpass_type;
+ g_data->renderpass_postprocess = PASS_POST_UNDEFINED;
switch (renderpass_type) {
- case SCE_PASS_AO: {
+ case EEVEE_RENDER_PASS_Z: {
+ g_data->renderpass_postprocess = PASS_POST_DEPTH;
+ break;
+ }
+ case EEVEE_RENDER_PASS_AO: {
+ g_data->renderpass_postprocess = PASS_POST_AO;
g_data->renderpass_input = txl->ao_accum;
break;
}
- case SCE_PASS_NORMAL: {
+ case EEVEE_RENDER_PASS_NORMAL: {
+ g_data->renderpass_postprocess = PASS_POST_NORMAL;
g_data->renderpass_input = effects->ssr_normal_input;
break;
}
- case SCE_PASS_MIST: {
+ case EEVEE_RENDER_PASS_MIST: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_VALUE;
g_data->renderpass_input = txl->mist_accum;
break;
}
- case SCE_PASS_SUBSURFACE_DIRECT: {
- g_data->renderpass_input = txl->sss_dir_accum;
+ case EEVEE_RENDER_PASS_VOLUME_SCATTER: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
+ g_data->renderpass_input = txl->volume_scatter_accum;
+ break;
+ }
+ case EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
+ g_data->renderpass_input = txl->volume_transmittance_accum;
+ break;
+ }
+ case EEVEE_RENDER_PASS_SHADOW: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_VALUE;
+ g_data->renderpass_input = txl->shadow_accum;
break;
}
- case SCE_PASS_SUBSURFACE_COLOR: {
- g_data->renderpass_input = txl->sss_col_accum;
+ case EEVEE_RENDER_PASS_DIFFUSE_COLOR:
+ case EEVEE_RENDER_PASS_SPECULAR_COLOR:
+ case EEVEE_RENDER_PASS_ENVIRONMENT:
+ case EEVEE_RENDER_PASS_EMIT: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
+ int renderpass_index = EEVEE_material_output_pass_index_get(sldata, vedata, renderpass_type);
+ g_data->renderpass_input = txl->material_accum[renderpass_index];
+ break;
+ }
+ case EEVEE_RENDER_PASS_SPECULAR_LIGHT: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_LIGHT;
+ int renderpass_index = EEVEE_material_output_pass_index_get(sldata, vedata, renderpass_type);
+ int renderpass_index_color = EEVEE_material_output_color_pass_index_get(
+ sldata, vedata, renderpass_type);
+ g_data->renderpass_input = txl->material_accum[renderpass_index];
+ g_data->renderpass_col_input = txl->material_accum[renderpass_index_color];
+ if ((stl->effects->enabled_effects & EFFECT_SSR) != 0) {
+ g_data->renderpass_postprocess = PASS_POST_TWO_LIGHT_BUFFERS;
+ g_data->renderpass_light_input = txl->ssr_accum;
+ }
+ else {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_LIGHT;
+ }
+ break;
+ }
+ case EEVEE_RENDER_PASS_DIFFUSE_LIGHT: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_LIGHT;
+ int renderpass_index = EEVEE_material_output_pass_index_get(sldata, vedata, renderpass_type);
+ int renderpass_index_color = EEVEE_material_output_color_pass_index_get(
+ sldata, vedata, renderpass_type);
+ g_data->renderpass_input = txl->material_accum[renderpass_index];
+ g_data->renderpass_col_input = txl->material_accum[renderpass_index_color];
+ if ((stl->effects->enabled_effects & EFFECT_SSS) != 0) {
+ g_data->renderpass_postprocess = PASS_POST_TWO_LIGHT_BUFFERS;
+ g_data->renderpass_light_input = txl->sss_accum;
+ }
+ else {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_LIGHT;
+ }
+ break;
+ }
+ case EEVEE_RENDER_PASS_BLOOM: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
+ g_data->renderpass_input = txl->bloom_accum;
+ g_data->renderpass_current_sample = 1;
break;
}
default: {
break;
}
}
- GPU_framebuffer_bind(vedata->fbl->renderpass_fb);
+ GPU_framebuffer_bind(fbl->renderpass_fb);
DRW_draw_pass(psl->renderpass_pass);
}
-void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ bool post_effect)
{
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
- eScenePassType render_pass = stl->g_data->render_passes;
+ eViewLayerEEVEEPassType render_pass = stl->g_data->render_passes;
- if ((render_pass & SCE_PASS_MIST) != 0) {
- EEVEE_mist_output_accumulate(sldata, vedata);
- }
- if ((effects->enabled_effects & EFFECT_SSS) &&
- (render_pass & EEVEE_RENDERPASSES_SUBSURFACE) != 0) {
- EEVEE_subsurface_output_accumulate(sldata, vedata);
+ if (!post_effect) {
+ if ((render_pass & EEVEE_RENDER_PASS_MIST) != 0) {
+ EEVEE_mist_output_accumulate(sldata, vedata);
+ }
+ if ((render_pass & EEVEE_RENDER_PASS_DIFFUSE_LIGHT) != 0 &&
+ (effects->enabled_effects & EFFECT_SSS) != 0) {
+ EEVEE_subsurface_output_accumulate(sldata, vedata);
+ }
+ if ((render_pass & EEVEE_RENDER_PASS_AO) != 0) {
+ EEVEE_occlusion_output_accumulate(sldata, vedata);
+ }
+ if ((render_pass & EEVEE_RENDER_PASS_SHADOW) != 0) {
+ EEVEE_shadow_output_accumulate(sldata, vedata);
+ }
+ if ((render_pass & EEVEE_RENDERPASSES_MATERIAL) != 0) {
+ EEVEE_material_output_accumulate(sldata, vedata);
+ }
+ if ((render_pass &
+ (EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE | EEVEE_RENDER_PASS_VOLUME_SCATTER)) != 0) {
+ EEVEE_volumes_output_accumulate(sldata, vedata);
+ }
}
- if ((render_pass & SCE_PASS_AO) != 0) {
- EEVEE_occlusion_output_accumulate(sldata, vedata);
+ else {
+ if ((render_pass & EEVEE_RENDER_PASS_BLOOM) != 0 &&
+ (effects->enabled_effects & EFFECT_BLOOM) != 0) {
+ EEVEE_bloom_output_accumulate(sldata, vedata);
+ }
}
}
@@ -220,7 +366,13 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
- eScenePassType render_pass = stl->g_data->render_passes;
+
+ /* We can only draw a single renderpass. Lightpasses also select their color pass (a second
+ pass). We mask the light pass when a light pass is selected. */
+ const eViewLayerEEVEEPassType render_pass =
+ ((stl->g_data->render_passes & EEVEE_RENDERPASSES_LIGHT_PASS) != 0) ?
+ (stl->g_data->render_passes & EEVEE_RENDERPASSES_LIGHT_PASS) :
+ stl->g_data->render_passes;
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
@@ -229,14 +381,14 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_state_is_opengl_render();
UNUSED_VARS(needs_color_transfer);
- /* When SSS isn't available, but the pass is requested, we mark it as invalid */
- if ((render_pass & EEVEE_RENDERPASSES_SUBSURFACE) != 0 &&
- (effects->enabled_effects & EFFECT_SSS) == 0) {
+ if ((render_pass & EEVEE_RENDER_PASS_BLOOM) != 0 &&
+ (effects->enabled_effects & EFFECT_BLOOM) == 0) {
is_valid = false;
}
/* When SSS isn't available, but the pass is requested, we mark it as invalid */
- if ((render_pass & SCE_PASS_AO) != 0 && (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0) {
+ if ((render_pass & EEVEE_RENDER_PASS_AO) != 0 &&
+ (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0) {
is_valid = false;
}
@@ -254,7 +406,7 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
}
else {
/* Draw state is not valid for this pass, clear the buffer */
- static float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ static float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
GPU_framebuffer_bind(dfbl->default_fb);
GPU_framebuffer_clear_color(dfbl->default_fb, clear_color);
}
diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
index 591ca31017c..d231edf1383 100644
--- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
+++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
@@ -235,6 +235,8 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
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", EEVEE_material_default_render_pass_ubo_get(sldata));
if (!effects->reflection_trace_full) {
DRW_shgroup_uniform_ivec2(grp, "halfresOffset", effects->ssr_halfres_ofs, 1);
}
@@ -255,6 +257,8 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
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", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_int(grp, "neighborOffset", &effects->ssr_neighbor_ofs, 1);
if ((effects->enabled_effects & EFFECT_GTAO) != 0) {
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
@@ -335,6 +339,43 @@ void EEVEE_reflection_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v
}
}
+void EEVEE_reflection_output_init(EEVEE_ViewLayerData *UNUSED(sldata),
+ EEVEE_Data *vedata,
+ uint tot_samples)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+
+ float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ /* Create FrameBuffer. */
+ const eGPUTextureFormat texture_format = (tot_samples > 256) ? GPU_RGBA32F : GPU_RGBA16F;
+ DRW_texture_ensure_fullscreen_2d(&txl->ssr_accum, texture_format, 0);
+
+ GPU_framebuffer_ensure_config(&fbl->ssr_accum_fb,
+ {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->ssr_accum)});
+
+ /* Clear texture. */
+ if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
+ GPU_framebuffer_bind(fbl->ssr_accum_fb);
+ GPU_framebuffer_clear_color(fbl->ssr_accum_fb, clear);
+ }
+}
+
+void EEVEE_reflection_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+
+ if (stl->g_data->valid_double_buffer) {
+ GPU_framebuffer_bind(fbl->ssr_accum_fb);
+ DRW_draw_pass(psl->ssr_resolve);
+ }
+}
+
void EEVEE_screen_raytrace_free(void)
{
for (int i = 0; i < SSR_MAX_SHADER; i++) {
diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c
index 34a3e723161..2d91e4bb4bd 100644
--- a/source/blender/draw/engines/eevee/eevee_shaders.c
+++ b/source/blender/draw/engines/eevee/eevee_shaders.c
@@ -44,6 +44,7 @@ static struct {
/* Probes */
struct GPUShader *probe_default_sh;
struct GPUShader *probe_default_studiolight_sh;
+ struct GPUShader *probe_background_studiolight_sh;
struct GPUShader *probe_grid_display_sh;
struct GPUShader *probe_cube_display_sh;
struct GPUShader *probe_planar_display_sh;
@@ -191,6 +192,27 @@ GPUShader *EEVEE_shaders_default_studiolight_sh_get(void)
return e_data.probe_default_studiolight_sh;
}
+GPUShader *EEVEE_shaders_background_studiolight_sh_get(void)
+{
+ if (e_data.probe_background_studiolight_sh == NULL) {
+ char *frag_str = BLI_string_joinN(datatoc_octahedron_lib_glsl,
+ datatoc_common_uniforms_lib_glsl,
+ datatoc_bsdf_common_lib_glsl,
+ datatoc_lightprobe_lib_glsl,
+ datatoc_default_world_frag_glsl);
+
+ e_data.probe_background_studiolight_sh = DRW_shader_create_with_lib(
+ datatoc_background_vert_glsl,
+ NULL,
+ frag_str,
+ datatoc_common_view_lib_glsl,
+ "#define LOOKDEV_BG\n" SHADER_DEFINES);
+
+ MEM_freeN(frag_str);
+ }
+ return e_data.probe_background_studiolight_sh;
+}
+
GPUShader *EEVEE_shaders_probe_cube_display_sh_get(void)
{
if (e_data.probe_cube_display_sh == NULL) {
@@ -299,6 +321,7 @@ void EEVEE_shaders_free(void)
DRW_SHADER_FREE_SAFE(e_data.probe_grid_fill_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_planar_downsample_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_default_studiolight_sh);
+ DRW_SHADER_FREE_SAFE(e_data.probe_background_studiolight_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_grid_display_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_cube_display_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_planar_display_sh);
diff --git a/source/blender/draw/engines/eevee/eevee_shadows.c b/source/blender/draw/engines/eevee/eevee_shadows.c
index 1776f535237..f5b98d464dd 100644
--- a/source/blender/draw/engines/eevee/eevee_shadows.c
+++ b/source/blender/draw/engines/eevee/eevee_shadows.c
@@ -21,6 +21,7 @@
*/
#include "BLI_sys_types.h" /* bool */
+#include "BLI_string_utils.h"
// #include "BLI_dynstr.h"
// #include "BLI_rand.h"
@@ -35,11 +36,17 @@
static struct {
struct GPUShader *shadow_sh;
+ struct GPUShader *shadow_accum_sh;
} e_data = {NULL}; /* Engine data */
extern char datatoc_shadow_vert_glsl[];
extern char datatoc_shadow_frag_glsl[];
+extern char datatoc_shadow_accum_frag_glsl[];
extern char datatoc_common_view_lib_glsl[];
+extern char datatoc_common_uniforms_lib_glsl[];
+extern char datatoc_bsdf_common_lib_glsl[];
+extern char datatoc_lights_lib_glsl[];
+extern char datatoc_raytrace_lib_glsl[];
void eevee_contact_shadow_setup(const Light *la, EEVEE_Shadow *evsh)
{
@@ -65,6 +72,18 @@ void EEVEE_shadows_init(EEVEE_ViewLayerData *sldata)
NULL);
}
+ if (!e_data.shadow_accum_sh) {
+ char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
+ datatoc_common_uniforms_lib_glsl,
+ datatoc_bsdf_common_lib_glsl,
+ datatoc_raytrace_lib_glsl,
+ datatoc_lights_lib_glsl,
+ datatoc_shadow_accum_frag_glsl);
+
+ e_data.shadow_accum_sh = DRW_shader_create_fullscreen(frag_str, SHADER_DEFINES);
+ MEM_freeN(frag_str);
+ }
+
if (!sldata->lights) {
sldata->lights = MEM_callocN(sizeof(EEVEE_LightsInfo), "EEVEE_LightsInfo");
sldata->light_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_Light) * MAX_LIGHT, NULL);
@@ -170,6 +189,8 @@ void EEVEE_shadows_caster_material_add(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
if (alpha_threshold != NULL) {
@@ -406,7 +427,75 @@ void EEVEE_shadows_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, DRWView
}
}
+/* -------------------------------------------------------------------- */
+
+/** \name Render Passes
+ * \{ */
+
+void EEVEE_shadow_output_init(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ uint UNUSED(tot_samples))
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ /* Create FrameBuffer. */
+ const eGPUTextureFormat texture_format = GPU_R32F;
+ DRW_texture_ensure_fullscreen_2d(&txl->shadow_accum, texture_format, 0);
+
+ GPU_framebuffer_ensure_config(&fbl->shadow_accum_fb,
+ {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->shadow_accum)});
+
+ /* Clear texture. */
+ if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
+ GPU_framebuffer_bind(fbl->shadow_accum_fb);
+ GPU_framebuffer_clear_color(fbl->shadow_accum_fb, clear);
+ }
+
+ /* Create Pass and shgroup. */
+ DRW_PASS_CREATE(psl->shadow_accum_pass,
+ DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ADD_FULL);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.shadow_accum_sh, psl->shadow_accum_pass);
+ DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
+ DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
+ DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
+ DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
+ DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
+ DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
+ DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
+ DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
+ DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool);
+ DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);
+
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
+}
+
+void EEVEE_shadow_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_PassList *psl = vedata->psl;
+
+ if (fbl->shadow_accum_fb != NULL) {
+ GPU_framebuffer_bind(fbl->shadow_accum_fb);
+ DRW_draw_pass(psl->shadow_accum_pass);
+
+ /* Restore */
+ GPU_framebuffer_bind(fbl->main_fb);
+ }
+}
+
+/* \} */
+
void EEVEE_shadows_free(void)
{
DRW_SHADER_FREE_SAFE(e_data.shadow_sh);
+ DRW_SHADER_FREE_SAFE(e_data.shadow_accum_sh);
}
diff --git a/source/blender/draw/engines/eevee/eevee_shadows_cascade.c b/source/blender/draw/engines/eevee/eevee_shadows_cascade.c
index 32045e12a1c..1fd8d818b33 100644
--- a/source/blender/draw/engines/eevee/eevee_shadows_cascade.c
+++ b/source/blender/draw/engines/eevee/eevee_shadows_cascade.c
@@ -120,11 +120,6 @@ static void frustum_min_bounding_sphere(const float corners[8][3],
#endif
}
-BLI_INLINE float lerp(float t, float a, float b)
-{
- return ((a) + (t) * ((b) - (a)));
-}
-
static void eevee_shadow_cascade_setup(EEVEE_LightsInfo *linfo,
EEVEE_Light *evli,
DRWView *view,
@@ -254,11 +249,11 @@ static void eevee_shadow_cascade_setup(EEVEE_LightsInfo *linfo,
for (int c = 1; c < cascade_nbr; c++) {
/* View Space */
- float linear_split = lerp(((float)(c) / (float)cascade_nbr), csm_start, csm_end);
- float exp_split = csm_start * powf(csm_end / csm_start, (float)(c) / (float)cascade_nbr);
+ float linear_split = interpf(csm_end, csm_start, c / (float)cascade_nbr);
+ float exp_split = csm_start * powf(csm_end / csm_start, c / (float)cascade_nbr);
if (is_persp) {
- csm_data->split_start[c] = lerp(cascade_exponent, linear_split, exp_split);
+ csm_data->split_start[c] = interpf(exp_split, linear_split, cascade_exponent);
}
else {
csm_data->split_start[c] = linear_split;
@@ -266,10 +261,10 @@ static void eevee_shadow_cascade_setup(EEVEE_LightsInfo *linfo,
csm_data->split_end[c - 1] = csm_data->split_start[c];
/* Add some overlap for smooth transition */
- csm_data->split_start[c] = lerp(cascade_fade,
- csm_data->split_end[c - 1],
- (c > 1) ? csm_data->split_end[c - 2] :
- csm_data->split_start[0]);
+ csm_data->split_start[c] = interpf((c > 1) ? csm_data->split_end[c - 2] :
+ csm_data->split_start[0],
+ csm_data->split_end[c - 1],
+ cascade_fade);
/* NDC Space */
{
@@ -298,7 +293,8 @@ static void eevee_shadow_cascade_setup(EEVEE_LightsInfo *linfo,
/* Set last cascade split fade distance into the first split_start. */
float prev_split = (cascade_nbr > 1) ? csm_data->split_end[cascade_nbr - 2] :
csm_data->split_start[0];
- csm_data->split_start[0] = lerp(cascade_fade, csm_data->split_end[cascade_nbr - 1], prev_split);
+ csm_data->split_start[0] = interpf(
+ prev_split, csm_data->split_end[cascade_nbr - 1], cascade_fade);
/* For each cascade */
for (int c = 0; c < cascade_nbr; c++) {
diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c
index e94fc903694..98e799acb5e 100644
--- a/source/blender/draw/engines/eevee/eevee_subsurface.c
+++ b/source/blender/draw/engines/eevee/eevee_subsurface.c
@@ -33,7 +33,7 @@
#include "GPU_extensions.h"
static struct {
- struct GPUShader *sss_sh[4];
+ struct GPUShader *sss_sh[3];
} e_data = {{NULL}}; /* Engine data */
extern char datatoc_common_view_lib_glsl[];
@@ -64,8 +64,7 @@ static void eevee_create_shader_subsurface(void)
e_data.sss_sh[0] = DRW_shader_create_fullscreen(frag_str, "#define FIRST_PASS\n");
e_data.sss_sh[1] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n");
- e_data.sss_sh[2] = DRW_shader_create_fullscreen(frag_str, "#define RESULT_ACCUM\n");
- e_data.sss_sh[3] = DRW_shader_create_fullscreen(frag_translucent_str,
+ e_data.sss_sh[2] = DRW_shader_create_fullscreen(frag_translucent_str,
"#define EEVEE_TRANSLUCENCY\n" SHADER_DEFINES);
MEM_freeN(frag_translucent_str);
@@ -85,9 +84,10 @@ void EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->sss_jitter_threshold = scene_eval->eevee.sss_jitter_threshold;
}
-void EEVEE_subsurface_draw_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+void EEVEE_subsurface_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_EffectsInfo *effects = vedata->stl->effects;
+ EEVEE_StorageList *stl = vedata->stl;
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
@@ -138,72 +138,64 @@ void EEVEE_subsurface_draw_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
{GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(effects->sss_irradiance),
GPU_ATTACHMENT_TEXTURE(effects->sss_radius)});
+ if ((stl->g_data->render_passes & EEVEE_RENDER_PASS_DIFFUSE_LIGHT) != 0) {
+ EEVEE_subsurface_output_init(sldata, vedata, 0);
+ }
+ else {
+ GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_accum_fb);
+ txl->sss_accum = NULL;
+ }
}
else {
/* Cleanup to release memory */
GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_blur_fb);
GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_resolve_fb);
GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_clear_fb);
+ GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_accum_fb);
effects->sss_stencil = NULL;
effects->sss_blur = NULL;
effects->sss_irradiance = NULL;
effects->sss_radius = NULL;
+ txl->sss_accum = NULL;
}
}
-static void set_shgrp_stencil(void *UNUSED(userData), DRWShadingGroup *shgrp)
-{
- DRW_shgroup_stencil_mask(shgrp, 255);
-}
-
void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata),
EEVEE_Data *vedata,
- uint tot_samples)
+ uint UNUSED(tot_samples))
{
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
- if (effects->enabled_effects & EFFECT_SSS) {
- const eGPUTextureFormat texture_format_light = (tot_samples > 128) ? GPU_RGBA32F : GPU_RGBA16F;
- const eGPUTextureFormat texture_format_color = (tot_samples > 512) ? GPU_RGBA32F : GPU_RGBA16F;
- DRW_texture_ensure_fullscreen_2d(&txl->sss_dir_accum, texture_format_light, 0);
- DRW_texture_ensure_fullscreen_2d(&txl->sss_col_accum, texture_format_color, 0);
-
- GPUTexture *stencil_tex = effects->sss_stencil;
+ const eGPUTextureFormat texture_format_light = GPU_RGBA32F;
+ const bool texture_created = txl->sss_accum == NULL;
+ DRW_texture_ensure_fullscreen_2d(&txl->sss_accum, texture_format_light, 0);
- if (GPU_depth_blitting_workaround()) {
- DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- /* Blitting stencil buffer does not work on macOS + Radeon Pro.
- * Blit depth instead and use sss_stencil's depth as depth texture,
- * and dtxl->depth as stencil mask. */
- stencil_tex = dtxl->depth;
- }
+ GPUTexture *stencil_tex = effects->sss_stencil;
- GPU_framebuffer_ensure_config(&fbl->sss_accum_fb,
- {GPU_ATTACHMENT_TEXTURE(stencil_tex),
- GPU_ATTACHMENT_TEXTURE(txl->sss_dir_accum),
- GPU_ATTACHMENT_TEXTURE(txl->sss_col_accum)});
+ if (GPU_depth_blitting_workaround()) {
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ /* Blitting stencil buffer does not work on macOS + Radeon Pro.
+ * Blit depth instead and use sss_stencil's depth as depth texture,
+ * and dtxl->depth as stencil mask. */
+ stencil_tex = dtxl->depth;
+ }
- /* Clear texture. */
- if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
- float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- GPU_framebuffer_bind(fbl->sss_accum_fb);
- GPU_framebuffer_clear_color(fbl->sss_accum_fb, clear);
- }
+ GPU_framebuffer_ensure_config(
+ &fbl->sss_accum_fb,
+ {GPU_ATTACHMENT_TEXTURE(stencil_tex), GPU_ATTACHMENT_TEXTURE(txl->sss_accum)});
- /* Make the opaque refraction pass mask the sss. */
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES |
- DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_ALWAYS;
- DRW_pass_state_set(vedata->psl->refract_pass, state);
- DRW_pass_foreach_shgroup(vedata->psl->refract_pass, &set_shgrp_stencil, NULL);
- }
- else {
- /* Cleanup to release memory */
- DRW_TEXTURE_FREE_SAFE(txl->sss_dir_accum);
- DRW_TEXTURE_FREE_SAFE(txl->sss_col_accum);
- GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_accum_fb);
+ /* Clear texture.
+ * Due to the late initialization of the SSS it can happen that the `taa_current_sample` is
+ * already higher than one. This is noticeable when loading a file that has the diffuse light
+ * pass in look dev mode active. `texture_created` will make sure that newly created textures
+ * are cleared. */
+ if (DRW_state_is_image_render() || effects->taa_current_sample == 1 || texture_created) {
+ float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ GPU_framebuffer_bind(fbl->sss_accum_fb);
+ GPU_framebuffer_clear_color(fbl->sss_accum_fb, clear);
}
}
@@ -222,7 +214,6 @@ void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL;
DRW_PASS_CREATE(psl->sss_blur_ps, state);
DRW_PASS_CREATE(psl->sss_resolve_ps, state | DRW_STATE_BLEND_ADD);
- DRW_PASS_CREATE(psl->sss_accum_ps, state | DRW_STATE_BLEND_ADD);
DRW_PASS_CREATE(psl->sss_translucency_ps, state | DRW_STATE_BLEND_ADD);
}
@@ -245,6 +236,8 @@ void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius);
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call(grp, quad, NULL);
@@ -256,22 +249,10 @@ void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius);
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call(grp, quad, NULL);
-
- if ((stl->g_data->render_passes & (SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT)) !=
- 0) {
- grp = DRW_shgroup_create(e_data.sss_sh[2], psl->sss_accum_ps);
- DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
- DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src);
- DRW_shgroup_uniform_texture_ref(grp, "sssIrradiance", &effects->sss_blur);
- DRW_shgroup_uniform_texture_ref(grp, "sssAlbedo", &effects->sss_albedo);
- DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius);
- DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
- DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_stencil_mask(grp, sss_id);
- DRW_shgroup_call(grp, quad, NULL);
- }
}
void EEVEE_subsurface_translucency_add_pass(EEVEE_ViewLayerData *sldata,
@@ -287,7 +268,7 @@ void EEVEE_subsurface_translucency_add_pass(EEVEE_ViewLayerData *sldata,
struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
GPUTexture **depth_src = GPU_depth_blitting_workaround() ? &effects->sss_stencil : &dtxl->depth;
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.sss_sh[3], psl->sss_translucency_ps);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.sss_sh[2], psl->sss_translucency_ps);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_texture(grp, "sssTexProfile", sss_tex_profile);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src);
@@ -298,6 +279,8 @@ void EEVEE_subsurface_translucency_add_pass(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call(grp, quad, NULL);
}
@@ -408,11 +391,11 @@ void EEVEE_subsurface_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEV
if (((effects->enabled_effects & EFFECT_SSS) != 0) && (fbl->sss_accum_fb != NULL)) {
/* Copy stencil channel, could be avoided (see EEVEE_subsurface_init) */
- GPU_framebuffer_blit(fbl->main_fb, 0, fbl->sss_blur_fb, 0, GPU_STENCIL_BIT);
+ GPU_framebuffer_blit(fbl->main_fb, 0, fbl->sss_accum_fb, 0, GPU_STENCIL_BIT);
/* Only do vertical pass + Resolve */
GPU_framebuffer_bind(fbl->sss_accum_fb);
- DRW_draw_pass(psl->sss_accum_ps);
+ DRW_draw_pass(psl->sss_resolve_ps);
/* Restore */
GPU_framebuffer_bind(fbl->main_fb);
@@ -424,5 +407,4 @@ void EEVEE_subsurface_free(void)
DRW_SHADER_FREE_SAFE(e_data.sss_sh[0]);
DRW_SHADER_FREE_SAFE(e_data.sss_sh[1]);
DRW_SHADER_FREE_SAFE(e_data.sss_sh[2]);
- DRW_SHADER_FREE_SAFE(e_data.sss_sh[3]);
}
diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
index 093a4780a97..bd77279eb4a 100644
--- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
+++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
@@ -290,6 +290,8 @@ void EEVEE_temporal_sampling_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data
DRW_shgroup_uniform_texture_ref(grp, "colorHistoryBuffer", &txl->taa_history);
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &effects->source_buffer);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
if (effects->enabled_effects & EFFECT_TAA_REPROJECT) {
// DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c
index 7026894076a..456673c92fa 100644
--- a/source/blender/draw/engines/eevee/eevee_volumes.c
+++ b/source/blender/draw/engines/eevee/eevee_volumes.c
@@ -54,6 +54,7 @@ static struct {
struct GPUShader *scatter_with_lights_sh;
struct GPUShader *volumetric_integration_sh;
struct GPUShader *volumetric_resolve_sh;
+ struct GPUShader *volumetric_accum_sh;
GPUTexture *depth_src;
@@ -73,6 +74,7 @@ extern char datatoc_common_view_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_lights_lib_glsl[];
+extern char datatoc_volumetric_accum_frag_glsl[];
extern char datatoc_volumetric_frag_glsl[];
extern char datatoc_volumetric_geom_glsl[];
extern char datatoc_volumetric_vert_glsl[];
@@ -136,6 +138,8 @@ static void eevee_create_shader_volumes(void)
datatoc_volumetric_resolve_frag_glsl,
e_data.volumetric_common_lib,
NULL);
+ e_data.volumetric_accum_sh = DRW_shader_create_fullscreen(datatoc_volumetric_accum_frag_glsl,
+ NULL);
float color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
e_data.dummy_density = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, color);
@@ -359,6 +363,8 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
/* Fix principle volumetric not working with world materials. */
DRW_shgroup_uniform_texture(grp, "sampdensity", e_data.dummy_density);
@@ -375,6 +381,8 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
/* If no world or volume material is present just clear the buffer with this drawcall */
grp = DRW_shgroup_create(e_data.volumetric_clear_sh, psl->volumetric_world_ps);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call_procedural_triangles(grp, NULL, common_data->vol_tex_size[2]);
}
@@ -430,8 +438,12 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_vec3(grp, "volumeOrcoLoc", texcoloc, 1);
DRW_shgroup_uniform_vec3(grp, "volumeOrcoSize", texcosize, 1);
@@ -522,6 +534,8 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call_procedural_triangles(grp, NULL, common_data->vol_tex_size[2]);
@@ -530,6 +544,8 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "volumeScattering", &txl->volume_scatter);
DRW_shgroup_uniform_texture_ref(grp, "volumeExtinction", &txl->volume_transmit);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call_procedural_triangles(
grp, NULL, USE_VOLUME_OPTI ? 1 : common_data->vol_tex_size[2]);
@@ -540,6 +556,8 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
}
@@ -729,4 +747,75 @@ void EEVEE_volumes_free(void)
DRW_SHADER_FREE_SAFE(e_data.scatter_with_lights_sh);
DRW_SHADER_FREE_SAFE(e_data.volumetric_integration_sh);
DRW_SHADER_FREE_SAFE(e_data.volumetric_resolve_sh);
+ DRW_SHADER_FREE_SAFE(e_data.volumetric_accum_sh);
+}
+
+/* -------------------------------------------------------------------- */
+
+/** \name Render Passes
+ * \{ */
+
+void EEVEE_volumes_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+
+ float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ /* Create FrameBuffer. */
+
+ /* Should be enough precision for many samples. */
+ const eGPUTextureFormat texture_format_accum = (tot_samples > 128) ? GPU_RGBA32F : GPU_RGBA16F;
+ DRW_texture_ensure_fullscreen_2d(&txl->volume_scatter_accum, texture_format_accum, 0);
+ DRW_texture_ensure_fullscreen_2d(&txl->volume_transmittance_accum, texture_format_accum, 0);
+
+ GPU_framebuffer_ensure_config(&fbl->volumetric_accum_fb,
+ {GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(txl->volume_scatter_accum),
+ GPU_ATTACHMENT_TEXTURE(txl->volume_transmittance_accum)});
+
+ /* Clear texture. */
+ if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
+ GPU_framebuffer_bind(fbl->volumetric_accum_fb);
+ GPU_framebuffer_clear_color(fbl->volumetric_accum_fb, clear);
+ }
+
+ /* Create Pass and shgroup. */
+ DRW_PASS_CREATE(psl->volumetric_accum_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL);
+ DRWShadingGroup *grp = NULL;
+ if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
+ grp = DRW_shgroup_create(e_data.volumetric_resolve_sh, psl->volumetric_accum_ps);
+ DRW_shgroup_uniform_texture_ref(grp, "inScattering", &txl->volume_scatter);
+ DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
+ DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
+ DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
+ }
+ else {
+ /* There is no volumetrics in the scene. Use a shader to fill the accum textures with a default
+ * value. */
+ grp = DRW_shgroup_create(e_data.volumetric_accum_sh, psl->volumetric_accum_ps);
+ }
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
+
+void EEVEE_volumes_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_PassList *psl = vedata->psl;
+
+ if (fbl->volumetric_accum_fb != NULL) {
+ /* Accum pass */
+ GPU_framebuffer_bind(fbl->volumetric_accum_fb);
+ DRW_draw_pass(psl->volumetric_accum_ps);
+
+ /* Restore */
+ GPU_framebuffer_bind(fbl->main_fb);
+ }
+}
+
+/* \} */
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
index c4f815b5dd4..c3518198805 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -85,6 +85,37 @@ struct ShadowCascadeData {
#define sh_shadow_vec shadow_vec_id.xyz
#define sh_tex_index shadow_vec_id.w
+/* ------ Render Passes ----- */
+layout(std140) uniform renderpass_block
+{
+ bool renderPassDiffuse;
+ bool renderPassDiffuseLight;
+ bool renderPassGlossy;
+ bool renderPassGlossyLight;
+ bool renderPassEmit;
+ bool renderPassSSSColor;
+};
+
+vec3 render_pass_diffuse_mask(vec3 diffuse_color, vec3 diffuse_light)
+{
+ return renderPassDiffuse ? (renderPassDiffuseLight ? diffuse_light : diffuse_color) : vec3(0.0);
+}
+
+vec3 render_pass_sss_mask(vec3 sss_color)
+{
+ return renderPassSSSColor ? sss_color : vec3(0.0);
+}
+
+vec3 render_pass_glossy_mask(vec3 specular_color, vec3 specular_light)
+{
+ return renderPassGlossy ? (renderPassGlossyLight ? specular_light : specular_color) : vec3(0.0);
+}
+
+vec3 render_pass_emission_mask(vec3 emission_light)
+{
+ return renderPassEmit ? emission_light : vec3(0.0);
+}
+
/* ------- Convenience functions --------- */
vec3 mul(mat3 m, vec3 v)
@@ -833,11 +864,12 @@ void closure_load_sss_data(
cl.sss_radius = radius;
cl.sss_albedo = sss_albedo;
cl.flag |= CLOSURE_SSS_FLAG;
+ cl.radiance += render_pass_diffuse_mask(sss_albedo, vec3(0));
}
else
# endif
{
- cl.radiance += sss_irradiance * sss_albedo;
+ cl.radiance += render_pass_diffuse_mask(sss_albedo, sss_irradiance * sss_albedo);
}
}
diff --git a/source/blender/draw/engines/eevee/shaders/default_frag.glsl b/source/blender/draw/engines/eevee/shaders/default_frag.glsl
index a031ed193b6..1014b25033a 100644
--- a/source/blender/draw/engines/eevee/shaders/default_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/default_frag.glsl
@@ -34,7 +34,8 @@ Closure nodetree_exec(void)
eevee_closure_default(N, albedo, f0, f90, 1, roughness, 1.0, true, out_diff, out_spec, ssr_spec);
Closure cl = CLOSURE_DEFAULT;
- cl.radiance = out_spec + out_diff * albedo;
+ cl.radiance = render_pass_glossy_mask(vec3(1.0), out_spec) +
+ render_pass_diffuse_mask(albedo, out_diff * albedo);
closure_load_ssr_data(ssr_spec, roughness, N, viewCameraVec, 1, cl);
#ifdef LOOKDEV
diff --git a/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl b/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl
index 41e103609f3..1faa02fd354 100644
--- a/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl
@@ -4,11 +4,12 @@ uniform vec3 color;
out vec4 FragColor;
-#ifdef LOOKDEV
+#if defined(LOOKDEV_BG) || defined(LOOKDEV)
+
uniform mat3 StudioLightMatrix;
uniform sampler2D image;
-uniform float studioLightBackground = 1.0;
uniform float studioLightIntensity = 1.0;
+uniform float studioLightBlur = 0.0;
in vec3 viewPosition;
# define M_PI 3.14159265358979323846
@@ -49,11 +50,17 @@ vec4 node_tex_environment_equirectangular(vec3 co, sampler2D ima)
void main()
{
vec3 background_color;
-#ifdef LOOKDEV
+
+#if defined(LOOKDEV_BG)
+ vec3 worldvec = background_transform_to_world(viewPosition);
+ background_color = probe_evaluate_world_spec(worldvec, studioLightBlur).rgb;
+ background_color *= studioLightIntensity;
+
+#elif defined(LOOKDEV)
vec3 worldvec = background_transform_to_world(viewPosition);
background_color = node_tex_environment_equirectangular(StudioLightMatrix * worldvec, image).rgb;
background_color *= studioLightIntensity;
- background_color = mix(color, background_color, studioLightBackground);
+
#else
background_color = color;
#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 299cb2094c1..18f92c0dd33 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl
@@ -40,6 +40,7 @@ uniform float sampleScale;
/* Step Resolve */
uniform vec3 bloomColor;
+uniform bool bloomAddBase;
in vec4 uvcoordsvar;
@@ -201,9 +202,9 @@ vec4 step_resolve(void)
#else
vec3 blur = upsample_filter(sourceBuffer, uvcoordsvar.xy, sourceBufferTexelSize);
#endif
- vec4 base = textureLod(baseBuffer, uvcoordsvar.xy, 0.0);
- vec3 cout = base.rgb + blur * bloomColor;
- return vec4(cout, base.a);
+ vec3 base = bloomAddBase ? textureLod(baseBuffer, uvcoordsvar.xy, 0.0).rgb : vec3(0.0);
+ vec3 cout = base + blur * bloomColor;
+ return vec4(cout, 1.0);
}
void main(void)
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 1241cf0e387..e9da49c9eb9 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
@@ -20,13 +20,7 @@ uniform sampler2DArray utilTex;
# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
#endif /* UTIL_TEX */
-#ifdef RESULT_ACCUM
-/* Render Passes Accumulation */
-layout(location = 0) out vec4 sssDirect;
-layout(location = 1) out vec4 sssColor;
-#else
layout(location = 0) out vec4 sssRadiance;
-#endif
float get_view_z_from_depth(float depth)
{
@@ -87,10 +81,7 @@ void main(void)
accum += kernel[i].rgb * mix(color, sss_irradiance, s);
}
-#ifdef RESULT_ACCUM
- sssDirect = vec4(accum, 1.0);
- sssColor = vec4(texture(sssAlbedo, uvs).rgb, 1.0);
-#elif defined(FIRST_PASS)
+#if defined(FIRST_PASS)
sssRadiance = vec4(accum, 1.0);
#else /* SECOND_PASS */
sssRadiance = vec4(accum * texture(sssAlbedo, uvs).rgb, 1.0);
diff --git a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
index 6427f02ed25..3b9d0a8f2bc 100644
--- a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
@@ -173,19 +173,17 @@ float light_attenuation(LightData ld, vec4 l_vector)
return vis;
}
-float light_visibility(LightData ld,
- vec3 W,
+float light_shadowing(LightData ld,
+ vec3 W,
#ifndef VOLUMETRICS
- vec3 viewPosition,
- float tracing_depth,
- vec3 true_normal,
- float rand_x,
- const bool use_contact_shadows,
+ vec3 viewPosition,
+ float tracing_depth,
+ vec3 true_normal,
+ float rand_x,
+ const bool use_contact_shadows,
#endif
- vec4 l_vector)
+ float vis)
{
- float vis = light_attenuation(ld, l_vector);
-
#if !defined(VOLUMETRICS) || defined(VOLUME_SHADOW)
/* shadowing */
if (ld.l_shadowid >= 0.0 && vis > 0.001) {
@@ -236,6 +234,30 @@ float light_visibility(LightData ld,
return vis;
}
+float light_visibility(LightData ld,
+ vec3 W,
+#ifndef VOLUMETRICS
+ vec3 viewPosition,
+ float tracing_depth,
+ vec3 true_normal,
+ float rand_x,
+ const bool use_contact_shadows,
+#endif
+ vec4 l_vector)
+{
+ float l_atten = light_attenuation(ld, l_vector);
+ return light_shadowing(ld,
+ W,
+#ifndef VOLUMETRICS
+ viewPosition,
+ tracing_depth,
+ true_normal,
+ rand_x,
+ use_contact_shadows,
+#endif
+ l_atten);
+}
+
#ifdef USE_LTC
float light_diffuse(LightData ld, vec3 N, vec3 V, vec4 l_vector)
{
diff --git a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
index 35bfb411cb9..5214301bc03 100644
--- a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
@@ -1,15 +1,17 @@
-#define SCE_PASS_Z (1 << 1)
-#define SCE_PASS_AO (1 << 6)
-#define SCE_PASS_NORMAL (1 << 8)
-#define SCE_PASS_MIST (1 << 14)
-#define SCE_PASS_SUBSURFACE_DIRECT (1 << 28)
-#define SCE_PASS_SUBSURFACE_COLOR (1 << 30)
+#define PASS_POST_UNDEFINED 0
+#define PASS_POST_ACCUMULATED_COLOR 1
+#define PASS_POST_ACCUMULATED_LIGHT 2
+#define PASS_POST_ACCUMULATED_VALUE 3
+#define PASS_POST_DEPTH 4
+#define PASS_POST_AO 5
+#define PASS_POST_NORMAL 6
+#define PASS_POST_TWO_LIGHT_BUFFERS 7
-#define ACCUMULATED_COLOR_PASSES (SCE_PASS_SUBSURFACE_DIRECT | SCE_PASS_SUBSURFACE_COLOR)
-#define ACCUMULATED_VALUE_PASSES (SCE_PASS_MIST)
-uniform int renderpassType;
+uniform int postProcessType;
uniform int currentSample;
uniform sampler2D inputBuffer;
+uniform sampler2D inputSecondLightBuffer;
+uniform sampler2D inputColorBuffer;
out vec4 fragColor;
@@ -17,7 +19,7 @@ void main()
{
ivec2 texel = ivec2(gl_FragCoord.xy);
- if (renderpassType == SCE_PASS_Z) {
+ if (postProcessType == PASS_POST_DEPTH) {
float depth = texelFetch(depthBuffer, texel, 0).r;
if (depth == 1.0f) {
depth = 1e10;
@@ -27,17 +29,15 @@ void main()
}
fragColor.r = depth;
}
-
- else if (renderpassType == SCE_PASS_AO) {
+ else if (postProcessType == PASS_POST_AO) {
float ao_accum = texelFetch(inputBuffer, texel, 0).r;
fragColor = vec4(vec3(min(1.0, ao_accum / currentSample)), 1.0);
}
-
- else if (renderpassType == SCE_PASS_NORMAL) {
+ else if (postProcessType == PASS_POST_NORMAL) {
float depth = texelFetch(depthBuffer, texel, 0).r;
vec2 encoded_normal = texelFetch(inputBuffer, texel, 0).rg;
- /* decode the normals only when they are valid. otherwise the result buffer will be filled with
- * NaN's */
+ /* decode the normals only when they are valid. otherwise the result buffer will be filled
+ * with NaN's */
if (depth != 1.0 && any(notEqual(encoded_normal, vec2(0.0)))) {
vec3 decoded_normal = normal_decode(texelFetch(inputBuffer, texel, 0).rg, vec3(0.0));
vec3 world_normal = mat3(ViewMatrixInverse) * decoded_normal;
@@ -47,18 +47,55 @@ void main()
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
}
-
- else if ((renderpassType & ACCUMULATED_VALUE_PASSES) != 0) {
+ else if (postProcessType == PASS_POST_ACCUMULATED_VALUE) {
float accumulated_value = texelFetch(inputBuffer, texel, 0).r;
fragColor = vec4(vec3(accumulated_value / currentSample), 1.0);
}
-
- else if ((renderpassType & ACCUMULATED_COLOR_PASSES) != 0) {
+ else if (postProcessType == PASS_POST_ACCUMULATED_COLOR) {
vec3 accumulated_color = texelFetch(inputBuffer, texel, 0).rgb;
fragColor = vec4(accumulated_color / currentSample, 1.0);
}
+ else if (postProcessType == PASS_POST_ACCUMULATED_LIGHT) {
+ vec3 accumulated_light = texelFetch(inputBuffer, texel, 0).rgb;
+ vec3 accumulated_color = texelFetch(inputColorBuffer, texel, 0).rgb;
+ /* Fix INF in the case a color component is 0.0 */
+ if (accumulated_color.r == 0.0) {
+ accumulated_color.r = 1.0;
+ accumulated_light.r = 0.0;
+ }
+ if (accumulated_color.g == 0.0) {
+ accumulated_color.g = 1.0;
+ accumulated_light.g = 0.0;
+ }
+ if (accumulated_color.b == 0.0) {
+ accumulated_color.b = 1.0;
+ accumulated_light.b = 0.0;
+ }
+ fragColor = vec4(accumulated_light / accumulated_color, 1.0);
+ }
+ else if (postProcessType == PASS_POST_TWO_LIGHT_BUFFERS) {
+ vec3 accumulated_light = texelFetch(inputBuffer, texel, 0).rgb +
+ texelFetch(inputSecondLightBuffer, texel, 0).rgb;
+ vec3 accumulated_color = texelFetch(inputColorBuffer, texel, 0).rgb;
+
+ /* Fix INF in the case a color component is 0.0 */
+ if (accumulated_color.r == 0.0) {
+ accumulated_color.r = 1.0;
+ accumulated_light.r = 0.0;
+ }
+ if (accumulated_color.g == 0.0) {
+ accumulated_color.g = 1.0;
+ accumulated_light.g = 0.0;
+ }
+ if (accumulated_color.b == 0.0) {
+ accumulated_color.b = 1.0;
+ accumulated_light.b = 0.0;
+ }
+ fragColor = vec4(accumulated_light / accumulated_color, 1.0);
+ }
else {
+ /* Output error color: Unknown how to post process this pass. */
fragColor = vec4(1.0, 0.0, 1.0, 1.0);
}
}
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl
new file mode 100644
index 00000000000..fa02bee45b7
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl
@@ -0,0 +1,58 @@
+
+out vec4 fragColor;
+
+#ifndef UTIL_TEX
+# define UTIL_TEX
+uniform sampler2DArray utilTex;
+# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
+#endif /* UTIL_TEX */
+
+void main()
+{
+ if (laNumLight == 0) {
+ /* Early exit: No lights in scene */
+ fragColor.r = 0.0;
+ return;
+ }
+
+ ivec2 texel = ivec2(gl_FragCoord.xy);
+ float depth = texelFetch(depthBuffer, texel, 0).r;
+ if (depth == 1.0f) {
+ /* Early exit background does not receive shadows */
+ fragColor.r = 1.0;
+ return;
+ }
+
+ vec2 texel_size = 1.0 / vec2(textureSize(depthBuffer, 0)).xy;
+ vec2 uvs = saturate(gl_FragCoord.xy * texel_size);
+ vec4 rand = texelfetch_noise_tex(texel);
+
+ float accum_light = 0.0;
+ float tracing_depth = depth;
+ /* Constant bias (due to depth buffer precision) */
+ /* Magic numbers for 24bits of precision.
+ * From http://terathon.com/gdc07_lengyel.pdf (slide 26) */
+ tracing_depth -= mix(2.4e-7, 4.8e-7, depth);
+ /* Convert to view Z. */
+ tracing_depth = get_view_z_from_depth(tracing_depth);
+
+ vec3 viewPosition = get_view_space_from_depth(uvs, depth);
+ vec3 worldPosition = transform_point(ViewMatrixInverse, viewPosition);
+
+ vec3 true_normal = normalize(cross(dFdx(viewPosition), dFdy(viewPosition)));
+
+ for (int i = 0; i < MAX_LIGHT && i < laNumLight; i++) {
+ LightData ld = lights_data[i];
+
+ vec4 l_vector; /* Non-Normalized Light Vector with length in last component. */
+ l_vector.xyz = ld.l_position - worldPosition;
+ l_vector.w = length(l_vector.xyz);
+
+ float l_vis = light_shadowing(
+ ld, worldPosition, viewPosition, tracing_depth, true_normal, rand.x, true, 1.0);
+
+ accum_light += l_vis;
+ }
+
+ fragColor.r = accum_light / float(laNumLight);
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_accum_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_accum_frag.glsl
new file mode 100644
index 00000000000..1b6a7b33f42
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_accum_frag.glsl
@@ -0,0 +1,11 @@
+
+/* This shader is used to add default values to the volume accum textures.
+ * so it looks similar (transmittance = 1, scattering = 0) */
+layout(location = 0, index = 0) out vec4 FragColor0;
+layout(location = 0, index = 1) out vec4 FragColor1;
+
+void main()
+{
+ FragColor0 = vec4(0.0);
+ FragColor1 = vec4(1.0);
+}
diff --git a/source/blender/draw/engines/overlay/overlay_antialiasing.c b/source/blender/draw/engines/overlay/overlay_antialiasing.c
index b8e39e3f0a9..0b7637aa098 100644
--- a/source/blender/draw/engines/overlay/overlay_antialiasing.c
+++ b/source/blender/draw/engines/overlay/overlay_antialiasing.c
@@ -68,7 +68,10 @@ void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
/* Small texture which will have very small impact on rendertime. */
- DRW_texture_ensure_2d(&txl->dummy_depth_tx, 1, 1, GPU_DEPTH_COMPONENT24, 0);
+ if (txl->dummy_depth_tx == NULL) {
+ float pixel[1] = {1.0f};
+ txl->dummy_depth_tx = DRW_texture_create_2d(1, 1, GPU_DEPTH_COMPONENT24, 0, pixel);
+ }
if (!DRW_state_is_fbo()) {
pd->antialiasing.enabled = false;
@@ -110,6 +113,16 @@ void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
GPU_ATTACHMENT_TEXTURE(color_tex),
GPU_ATTACHMENT_TEXTURE(line_tex),
});
+
+ if (pd->xray_enabled) {
+ DRW_texture_ensure_fullscreen_2d(&txl->temp_depth_tx, GPU_DEPTH24_STENCIL8, 0);
+
+ GPU_framebuffer_ensure_config(&fbl->overlay_xray_depth_copy_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(txl->temp_depth_tx),
+ GPU_ATTACHMENT_NONE,
+ });
+ }
}
void OVERLAY_antialiasing_cache_init(OVERLAY_Data *vedata)
@@ -137,6 +150,18 @@ void OVERLAY_antialiasing_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "lineTex", &txl->overlay_line_tx);
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
}
+
+ /* A bit out of place... not related to antialiasing. */
+ if (pd->xray_enabled) {
+ DRW_PASS_CREATE(psl->xray_fade_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_MUL);
+
+ sh = OVERLAY_shader_xray_fade();
+ grp = DRW_shgroup_create(sh, psl->xray_fade_ps);
+ DRW_shgroup_uniform_texture_ref(grp, "depthTex", &dtxl->depth);
+ DRW_shgroup_uniform_texture_ref(grp, "xrayDepthTex", &txl->temp_depth_tx);
+ DRW_shgroup_uniform_float_copy(grp, "opacity", 1.0f - pd->xray_opacity);
+ DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+ }
}
void OVERLAY_antialiasing_cache_finish(OVERLAY_Data *vedata)
@@ -187,6 +212,34 @@ void OVERLAY_antialiasing_start(OVERLAY_Data *vedata)
}
}
+void OVERLAY_xray_depth_copy(OVERLAY_Data *vedata)
+{
+ OVERLAY_FramebufferList *fbl = vedata->fbl;
+ OVERLAY_PrivateData *pd = vedata->stl->pd;
+
+ if (DRW_state_is_fbo() && pd->xray_enabled) {
+ if (pd->xray_opacity > 0.0f) {
+ /* We copy the depth of the rendered geometry to be able to compare to the overlays depth. */
+ GPU_framebuffer_blit(
+ fbl->overlay_default_fb, 0, fbl->overlay_xray_depth_copy_fb, 0, GPU_DEPTH_BIT);
+ }
+ /* We then clear to not occlude the overlays directly. */
+ GPU_framebuffer_bind(fbl->overlay_default_fb);
+ GPU_framebuffer_clear_depth(fbl->overlay_default_fb, 1.0f);
+ }
+}
+
+void OVERLAY_xray_fade_draw(OVERLAY_Data *vedata)
+{
+ OVERLAY_PassList *psl = vedata->psl;
+ OVERLAY_PrivateData *pd = vedata->stl->pd;
+
+ if (DRW_state_is_fbo() && pd->xray_enabled && pd->xray_opacity > 0.0f) {
+ /* Partially occlude overlays using the geometry depth pass. */
+ DRW_draw_pass(psl->xray_fade_ps);
+ }
+}
+
void OVERLAY_antialiasing_end(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c
index c41fc274f17..a8d2c4c6cf0 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.c
+++ b/source/blender/draw/engines/overlay/overlay_engine.c
@@ -75,6 +75,7 @@ static void OVERLAY_engine_init(void *vedata)
pd->wireframe_mode = (v3d->shading.type == OB_WIRE);
pd->clipping_state = RV3D_CLIPPING_ENABLED(v3d, rv3d) ? DRW_STATE_CLIP_PLANES : 0;
+ pd->xray_opacity = XRAY_ALPHA(v3d);
pd->xray_enabled = XRAY_ACTIVE(v3d);
pd->xray_enabled_and_not_wire = pd->xray_enabled && v3d->shading.type > OB_WIRE;
pd->clear_in_front = (v3d->shading.type != OB_SOLID);
@@ -410,6 +411,7 @@ static void OVERLAY_draw_scene(void *vedata)
}
OVERLAY_outline_draw(vedata);
+ OVERLAY_xray_depth_copy(vedata);
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(fbl->overlay_default_fb);
@@ -433,6 +435,7 @@ static void OVERLAY_draw_scene(void *vedata)
GPU_framebuffer_bind(fbl->overlay_color_only_fb);
}
+ OVERLAY_xray_fade_draw(vedata);
OVERLAY_grid_draw(vedata);
if (DRW_state_is_fbo()) {
diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h
index 4cd3877f21f..185df723301 100644
--- a/source/blender/draw/engines/overlay/overlay_private.h
+++ b/source/blender/draw/engines/overlay/overlay_private.h
@@ -35,6 +35,7 @@ typedef struct OVERLAY_FramebufferList {
struct GPUFrameBuffer *overlay_color_only_fb;
struct GPUFrameBuffer *overlay_in_front_fb;
struct GPUFrameBuffer *overlay_line_in_front_fb;
+ struct GPUFrameBuffer *overlay_xray_depth_copy_fb;
struct GPUFrameBuffer *outlines_prepass_fb;
struct GPUFrameBuffer *outlines_resolve_fb;
} OVERLAY_FramebufferList;
@@ -94,6 +95,7 @@ typedef struct OVERLAY_PassList {
DRWPass *sculpt_mask_ps;
DRWPass *wireframe_ps;
DRWPass *wireframe_xray_ps;
+ DRWPass *xray_fade_ps;
} OVERLAY_PassList;
/* Data used by GLSL shader. To be used as UBO. */
@@ -272,6 +274,7 @@ typedef struct OVERLAY_PrivateData {
bool hide_overlays;
bool xray_enabled;
bool xray_enabled_and_not_wire;
+ float xray_opacity;
short v3d_flag; /* TODO move to View3DOverlay */
short v3d_gridflag; /* TODO move to View3DOverlay */
DRWState clipping_state;
@@ -391,6 +394,8 @@ void OVERLAY_antialiasing_cache_init(OVERLAY_Data *vedata);
void OVERLAY_antialiasing_cache_finish(OVERLAY_Data *vedata);
void OVERLAY_antialiasing_start(OVERLAY_Data *vedata);
void OVERLAY_antialiasing_end(OVERLAY_Data *vedata);
+void OVERLAY_xray_fade_draw(OVERLAY_Data *vedata);
+void OVERLAY_xray_depth_copy(OVERLAY_Data *vedata);
bool OVERLAY_armature_is_pose_mode(Object *ob, const struct DRWContextState *draw_ctx);
void OVERLAY_armature_cache_init(OVERLAY_Data *vedata);
@@ -579,6 +584,7 @@ GPUShader *OVERLAY_shader_sculpt_mask(void);
GPUShader *OVERLAY_shader_volume_velocity(bool use_needle);
GPUShader *OVERLAY_shader_wireframe(void);
GPUShader *OVERLAY_shader_wireframe_select(void);
+GPUShader *OVERLAY_shader_xray_fade(void);
OVERLAY_InstanceFormats *OVERLAY_shader_instance_formats_get(void);
diff --git a/source/blender/draw/engines/overlay/overlay_shader.c b/source/blender/draw/engines/overlay/overlay_shader.c
index 6b8c5b23e58..d33ef239198 100644
--- a/source/blender/draw/engines/overlay/overlay_shader.c
+++ b/source/blender/draw/engines/overlay/overlay_shader.c
@@ -103,6 +103,7 @@ extern char datatoc_sculpt_mask_vert_glsl[];
extern char datatoc_volume_velocity_vert_glsl[];
extern char datatoc_wireframe_vert_glsl[];
extern char datatoc_wireframe_frag_glsl[];
+extern char datatoc_xray_fade_frag_glsl[];
extern char datatoc_gpu_shader_depth_only_frag_glsl[];
extern char datatoc_gpu_shader_point_varying_color_frag_glsl[];
@@ -179,6 +180,7 @@ typedef struct OVERLAY_Shaders {
GPUShader *volume_velocity_sh;
GPUShader *wireframe_select;
GPUShader *wireframe;
+ GPUShader *xray_fade;
} OVERLAY_Shaders;
static struct {
@@ -1265,6 +1267,18 @@ GPUShader *OVERLAY_shader_wireframe(void)
return sh_data->wireframe;
}
+GPUShader *OVERLAY_shader_xray_fade(void)
+{
+ OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
+ if (!sh_data->xray_fade) {
+ sh_data->xray_fade = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){datatoc_common_fullscreen_vert_glsl, NULL},
+ .frag = (const char *[]){datatoc_xray_fade_frag_glsl, NULL},
+ });
+ }
+ return sh_data->xray_fade;
+}
+
static OVERLAY_InstanceFormats g_formats = {NULL};
OVERLAY_InstanceFormats *OVERLAY_shader_instance_formats_get(void)
diff --git a/source/blender/draw/engines/overlay/shaders/edit_mesh_vert.glsl b/source/blender/draw/engines/overlay/shaders/edit_mesh_vert.glsl
index 8759ef80888..768b0596d17 100644
--- a/source/blender/draw/engines/overlay/shaders/edit_mesh_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/edit_mesh_vert.glsl
@@ -26,6 +26,14 @@ bool test_occlusion()
return ndc.z > texture(depthTex, ndc.xy).r;
}
+vec3 non_linear_blend_color(vec3 col1, vec3 col2, float fac)
+{
+ col1 = pow(col1, vec3(1.0 / 2.2));
+ col2 = pow(col2, vec3(1.0 / 2.2));
+ vec3 col = mix(col1, col2, fac);
+ return pow(col, vec3(2.2));
+}
+
void main()
{
GPU_INTEL_VERTEX_SHADER_WORKAROUND
@@ -88,7 +96,8 @@ void main()
float facing = dot(view_vec, view_normal);
facing = 1.0 - abs(facing) * 0.2;
- finalColor.rgb = mix(colorEditMeshMiddle.rgb, finalColor.rgb, facing);
+ /* Do interpolation in a non-linear space to have a better visual result. */
+ finalColor.rgb = non_linear_blend_color(colorEditMeshMiddle.rgb, finalColor.rgb, facing);
#endif
#ifdef USE_WORLD_CLIP_PLANES
diff --git a/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl b/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl
index 4d705a4ee2b..31ac9a2b181 100644
--- a/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/wireframe_vert.glsl
@@ -138,9 +138,12 @@ void main()
facing = clamp(abs(facing), 0.0, 1.0);
- vec3 final_front_col = mix(rim_col, wire_col, 0.4);
- vec3 final_rim_col = mix(rim_col, wire_col, 0.1);
- finalColor = mix(final_rim_col, final_front_col, facing);
+ /* Do interpolation in a non-linear space to have a better visual result. */
+ rim_col = pow(rim_col, vec3(1.0 / 2.2));
+ wire_col = pow(wire_col, vec3(1.0 / 2.2));
+ vec3 final_front_col = mix(rim_col, wire_col, 0.35);
+ finalColor = mix(rim_col, final_front_col, facing);
+ finalColor = pow(finalColor, vec3(2.2));
#endif
/* Cull flat edges below threshold. */
diff --git a/source/blender/draw/engines/overlay/shaders/xray_fade_frag.glsl b/source/blender/draw/engines/overlay/shaders/xray_fade_frag.glsl
new file mode 100644
index 00000000000..b6a5c8d895c
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/xray_fade_frag.glsl
@@ -0,0 +1,15 @@
+
+uniform sampler2D depthTex;
+uniform sampler2D xrayDepthTex;
+uniform float opacity;
+
+in vec4 uvcoordsvar;
+
+out vec4 fragColor;
+
+void main()
+{
+ float depth = texture(depthTex, uvcoordsvar.xy).r;
+ float depth_xray = texture(xrayDepthTex, uvcoordsvar.xy).r;
+ fragColor = vec4((depth < 1.0 && depth > depth_xray) ? opacity : 1.0);
+}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl
deleted file mode 100644
index c9711e9c7d6..00000000000
--- a/source/blender/draw/engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl
+++ /dev/null
@@ -1,38 +0,0 @@
-
-/* 4x4 bayer matrix. */
-#define P(x) ((x + 0.5) * (1.0 / 16.0))
-const vec4 dither_mat[4] = vec4[4](vec4(P(0.0), P(8.0), P(2.0), P(10.0)),
- vec4(P(12.0), P(4.0), P(14.0), P(6.0)),
- vec4(P(3.0), P(11.0), P(1.0), P(9.0)),
- vec4(P(15.0), P(7.0), P(13.0), P(5.0)));
-
-uniform float threshold = 0.5;
-uniform float offset = 0.0;
-
-/* Noise dithering pattern
- * 0 - Bayer matrix
- * 1 - Interlieved gradient noise
- */
-#define NOISE 1
-
-void main()
-{
-#if NOISE == 0
- ivec2 tx = ivec2(gl_FragCoord.xy) % 4;
- float noise = dither_mat[tx.x][tx.y];
-#elif NOISE == 1
- /* Interlieved gradient noise by Jorge Jimenez
- * http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare */
- float noise = fract(
- offset + 52.9829189 * fract(0.06711056 * gl_FragCoord.x + 0.00583715 * gl_FragCoord.y));
-#else
-# error
-#endif
-
- if (noise > threshold) {
- discard;
- }
- else {
- gl_FragDepth = 1.0;
- }
-}
diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c
index b8e9f9b8428..f2cc7cdf573 100644
--- a/source/blender/draw/engines/workbench/workbench_forward.c
+++ b/source/blender/draw/engines/workbench/workbench_forward.c
@@ -56,7 +56,6 @@ static struct {
WORKBENCH_FORWARD_Shaders sh_data[GPU_SHADER_CFG_LEN];
struct GPUShader *composite_sh_cache[2];
- struct GPUShader *checker_depth_sh;
struct GPUTexture *object_id_tx; /* ref only, not alloced */
struct GPUTexture *transparent_accum_tx; /* ref only, not alloced */
@@ -72,7 +71,6 @@ extern char datatoc_workbench_forward_composite_frag_glsl[];
extern char datatoc_workbench_forward_depth_frag_glsl[];
extern char datatoc_workbench_forward_transparent_accum_frag_glsl[];
extern char datatoc_workbench_data_lib_glsl[];
-extern char datatoc_workbench_checkerboard_depth_frag_glsl[];
extern char datatoc_workbench_object_outline_lib_glsl[];
extern char datatoc_workbench_curvature_lib_glsl[];
extern char datatoc_workbench_prepass_vert_glsl[];
@@ -349,11 +347,6 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
WORKBENCH_PrivateData *wpd = stl->g_data;
workbench_private_data_init(wpd);
- if (!e_data.checker_depth_sh) {
- e_data.checker_depth_sh = DRW_shader_create_fullscreen(
- datatoc_workbench_checkerboard_depth_frag_glsl, NULL);
- }
-
workbench_forward_outline_shaders_ensure(wpd, draw_ctx->sh_cfg);
workbench_volume_engine_init();
@@ -438,31 +431,9 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
workbench_aa_create_pass(vedata, &e_data.transparent_accum_tx);
}
- /* Checker Depth */
- {
- static float noise_offset = 0.0f;
- float blend_threshold = 0.0f;
-
- if (DRW_state_is_image_render()) {
- /* TODO: Should be based on the number of samples used for render. */
- noise_offset = fmodf(noise_offset + 1.0f / 8.0f, 1.0f);
- }
-
- if (XRAY_ENABLED(wpd)) {
- blend_threshold = 1.0f - XRAY_ALPHA(wpd) * 0.9f;
- }
-
- if (wpd->shading.type == OB_WIRE) {
- wpd->shading.xray_alpha = 0.0f;
- wpd->shading.xray_alpha_wire = 0.0f;
- }
-
- int state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS;
- psl->checker_depth_pass = DRW_pass_create("Checker Depth", state);
- grp = DRW_shgroup_create(e_data.checker_depth_sh, psl->checker_depth_pass);
- DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
- DRW_shgroup_uniform_float_copy(grp, "threshold", blend_threshold);
- DRW_shgroup_uniform_float_copy(grp, "offset", noise_offset);
+ if (wpd->shading.type == OB_WIRE) {
+ wpd->shading.xray_alpha = 0.0f;
+ wpd->shading.xray_alpha_wire = 0.0f;
}
}
@@ -481,7 +452,6 @@ void workbench_forward_engine_free()
for (int index = 0; index < 2; index++) {
DRW_SHADER_FREE_SAFE(e_data.composite_sh_cache[index]);
}
- DRW_SHADER_FREE_SAFE(e_data.checker_depth_sh);
workbench_volume_engine_free();
workbench_fxaa_engine_free();
@@ -828,10 +798,6 @@ void workbench_forward_draw_scene(WORKBENCH_Data *vedata)
/* Color correct and Anti aliasing */
workbench_aa_draw_pass(vedata, e_data.composite_buffer_tx);
-
- /* Apply checker pattern */
- GPU_framebuffer_bind(dfbl->depth_only_fb);
- DRW_draw_pass(psl->checker_depth_pass);
}
void workbench_forward_draw_finish(WORKBENCH_Data *vedata)
diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h
index 85e7147df1e..faf85e4a7de 100644
--- a/source/blender/draw/engines/workbench/workbench_private.h
+++ b/source/blender/draw/engines/workbench/workbench_private.h
@@ -164,7 +164,6 @@ typedef struct WORKBENCH_PassList {
struct DRWPass *transparent_accum_pass;
struct DRWPass *object_outline_pass;
struct DRWPass *depth_pass;
- struct DRWPass *checker_depth_pass;
} WORKBENCH_PassList;
typedef struct WORKBENCH_Data {
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 60c6e66bfe9..4f7554006cb 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -25,6 +25,8 @@
#ifndef __DRW_RENDER_H__
#define __DRW_RENDER_H__
+#include "DRW_engine_types.h"
+
#include "BLI_listbase.h"
#include "BLI_math_matrix.h"
#include "BLI_math_vector.h"
@@ -61,8 +63,6 @@
#include "DEG_depsgraph.h"
-struct DefaultFramebufferList;
-struct DefaultTextureList;
struct GPUBatch;
struct GPUFrameBuffer;
struct GPUMaterial;
@@ -133,25 +133,6 @@ typedef struct DrawEngineType {
const struct rcti *rect);
} DrawEngineType;
-#ifndef __DRW_ENGINE_H__
-/* Buffer and textures used by the viewport by default */
-typedef struct DefaultFramebufferList {
- struct GPUFrameBuffer *default_fb;
- struct GPUFrameBuffer *overlay_fb;
- struct GPUFrameBuffer *in_front_fb;
- struct GPUFrameBuffer *color_only_fb;
- struct GPUFrameBuffer *depth_only_fb;
- struct GPUFrameBuffer *overlay_only_fb;
-} DefaultFramebufferList;
-
-typedef struct DefaultTextureList {
- struct GPUTexture *color;
- struct GPUTexture *color_overlay;
- struct GPUTexture *depth;
- struct GPUTexture *depth_in_front;
-} DefaultTextureList;
-#endif
-
/* Textures */
typedef enum {
DRW_TEX_FILTER = (1 << 0),
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 8d3c932cbe6..4f1cab40463 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -416,41 +416,44 @@ void debug_markers_print_list(ListBase *markers)
/* ************* Marker Drawing ************ */
-static void marker_color_get(TimeMarker *marker, unsigned char *color)
+static void marker_color_get(const TimeMarker *marker, uchar *r_text_color, uchar *r_line_color)
{
if (marker->flag & SELECT) {
- UI_GetThemeColor4ubv(TH_TEXT_HI, color);
+ UI_GetThemeColor4ubv(TH_TEXT_HI, r_text_color);
+ UI_GetThemeColor4ubv(TH_TIME_MARKER_LINE_SELECTED, r_line_color);
}
else {
- UI_GetThemeColor4ubv(TH_TEXT, color);
+ UI_GetThemeColor4ubv(TH_TEXT, r_text_color);
+ UI_GetThemeColor4ubv(TH_TIME_MARKER_LINE, r_line_color);
}
}
-static void draw_marker_name(const uiFontStyle *fstyle,
+static void draw_marker_name(const uchar *text_color,
+ const uiFontStyle *fstyle,
TimeMarker *marker,
float marker_x,
float text_y)
{
- unsigned char text_color[4];
- marker_color_get(marker, text_color);
-
const char *name = marker->name;
+ uchar final_text_color[4];
+
+ copy_v4_v4_uchar(final_text_color, text_color);
#ifdef DURIAN_CAMERA_SWITCH
if (marker->camera) {
Object *camera = marker->camera;
name = camera->id.name + 2;
if (camera->restrictflag & OB_RESTRICT_RENDER) {
- text_color[3] = 100;
+ final_text_color[3] = 100;
}
}
#endif
int name_x = marker_x + UI_DPI_ICON_SIZE * 0.6;
- UI_fontstyle_draw_simple(fstyle, name_x, text_y, name, text_color);
+ UI_fontstyle_draw_simple(fstyle, name_x, text_y, name, final_text_color);
}
-static void draw_marker_line(const float color[4], int xpos, int ymin, int ymax)
+static void draw_marker_line(const uchar *color, int xpos, int ymin, int ymax)
{
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -461,7 +464,7 @@ static void draw_marker_line(const float color[4], int xpos, int ymin, int ymax)
GPU_viewport_size_get_f(viewport_size);
immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
- immUniformColor4fv(color);
+ immUniformColor4ubv(color);
immUniform1i("colors_len", 0); /* "simple" mode */
immUniform1f("dash_width", 6.0f);
immUniform1f("dash_factor", 0.5f);
@@ -493,19 +496,15 @@ static int marker_get_icon_id(TimeMarker *marker, int flag)
static void draw_marker(
const uiFontStyle *fstyle, TimeMarker *marker, int cfra, int xpos, int flag, int region_height)
{
+ uchar line_color[4], text_color[4];
+
+ marker_color_get(marker, text_color, line_color);
+
GPU_blend(true);
GPU_blend_set_func_separate(
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- float color[4];
- if (marker->flag & SELECT) {
- copy_v4_fl4(color, 1.0f, 1.0f, 1.0f, 0.38f);
- }
- else {
- copy_v4_fl4(color, 0.0f, 0.0f, 0.0f, 0.38f);
- }
-
- draw_marker_line(color, xpos, UI_DPI_FAC * 20, region_height);
+ draw_marker_line(line_color, xpos, UI_DPI_FAC * 20, region_height);
int icon_id = marker_get_icon_id(marker, flag);
UI_icon_draw(xpos - 0.55f * UI_DPI_ICON_SIZE, UI_DPI_FAC * 18, icon_id);
@@ -518,7 +517,7 @@ static void draw_marker(
if ((marker->flag & SELECT) || (cfra - 4 <= marker->frame && marker->frame <= cfra)) {
name_y += UI_DPI_FAC * 10;
}
- draw_marker_name(fstyle, marker, xpos, name_y);
+ draw_marker_name(text_color, fstyle, marker, xpos, name_y);
}
static void draw_markers_background(rctf *rect)
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index a3b7d6bd1c1..cad8b34557f 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -362,13 +362,13 @@ int ED_object_modifier_convert(struct ReportList *reports,
struct ViewLayer *view_layer,
struct Object *ob,
struct ModifierData *md);
-int ED_object_modifier_apply(struct Main *bmain,
- struct ReportList *reports,
- struct Depsgraph *depsgraph,
- struct Scene *scene,
- struct Object *ob,
- struct ModifierData *md,
- int mode);
+bool ED_object_modifier_apply(struct Main *bmain,
+ struct ReportList *reports,
+ struct Depsgraph *depsgraph,
+ struct Scene *scene,
+ struct Object *ob,
+ struct ModifierData *md,
+ int mode);
int ED_object_modifier_copy(struct ReportList *reports,
struct Object *ob,
struct ModifierData *md);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 1390567d5af..d003dac7fbf 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -230,8 +230,8 @@ bool ED_screen_change(struct bContext *C, struct bScreen *sc);
void ED_screen_scene_change(struct bContext *C, struct wmWindow *win, struct Scene *scene);
void ED_screen_set_active_region(struct bContext *C, struct wmWindow *win, const int xy[2]);
void ED_screen_exit(struct bContext *C, struct wmWindow *window, struct bScreen *screen);
-void ED_screen_animation_timer(struct bContext *C, int redraws, int refresh, int sync, int enable);
-void ED_screen_animation_timer_update(struct bScreen *screen, int redraws, int refresh);
+void ED_screen_animation_timer(struct bContext *C, int redraws, int sync, int enable);
+void ED_screen_animation_timer_update(struct bScreen *screen, int redraws);
void ED_screen_restore_temp_type(struct bContext *C, ScrArea *sa);
ScrArea *ED_screen_full_newspace(struct bContext *C, ScrArea *sa, int type);
void ED_screen_full_prevspace(struct bContext *C, ScrArea *sa);
diff --git a/source/blender/editors/include/ED_screen_types.h b/source/blender/editors/include/ED_screen_types.h
index c515d501a8d..bbbcaab165a 100644
--- a/source/blender/editors/include/ED_screen_types.h
+++ b/source/blender/editors/include/ED_screen_types.h
@@ -30,7 +30,6 @@
typedef struct ScreenAnimData {
ARegion *ar; /* do not read from this, only for comparing if region exists */
short redraws;
- short refresh;
short flag; /* flags for playback */
int sfra; /* frame that playback was started from */
int nextfra; /* next frame to go to (when ANIMPLAY_FLAG_USE_NEXT_FRAME is set) */
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index fabf6baed23..6739f7cb12c 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -793,7 +793,7 @@ DEF_ICON(BOOKMARKS)
DEF_ICON(FONTPREVIEW)
DEF_ICON(FILTER)
DEF_ICON(NEWFOLDER)
-DEF_ICON(FOLDER_REDIRECT)
+DEF_ICON_FOLDER(FOLDER_REDIRECT)
DEF_ICON(FILE_PARENT)
DEF_ICON(FILE_REFRESH)
DEF_ICON_FOLDER(FILE_FOLDER)
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index e4b11977214..10ca89c8222 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -108,6 +108,8 @@ typedef enum ThemeColorID {
TH_FACEDOT_SIZE,
TH_CFRAME,
TH_TIME_SCRUB_BACKGROUND,
+ TH_TIME_MARKER_LINE,
+ TH_TIME_MARKER_LINE_SELECTED,
TH_TIME_KEYFRAME,
TH_TIME_GP_KEYFRAME,
TH_NURB_ULINE,
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 5710be04477..093f063ebea 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -735,6 +735,8 @@ bool UI_context_copy_to_selected_list(bContext *C,
{
*r_use_path_from_id = false;
*r_path = NULL;
+ /* special case for bone constraints */
+ char *path_from_bone = NULL;
/* PropertyGroup objects don't have a reference to the struct that actually owns
* them, so it is normally necessary to do a brute force search to find it. This
@@ -797,6 +799,12 @@ bool UI_context_copy_to_selected_list(bContext *C,
else if (RNA_struct_is_a(ptr->type, &RNA_FCurve)) {
*r_lb = CTX_data_collection_get(C, "selected_editable_fcurves");
}
+ else if (RNA_struct_is_a(ptr->type, &RNA_Constraint) &&
+ (path_from_bone = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_PoseBone)) !=
+ NULL) {
+ *r_lb = CTX_data_collection_get(C, "selected_pose_bones");
+ *r_path = path_from_bone;
+ }
else if (RNA_struct_is_a(ptr->type, &RNA_Node) || RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {
ListBase lb = {NULL, NULL};
char *path = NULL;
diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c
index 867ac652505..b509f5e352b 100644
--- a/source/blender/editors/interface/interface_region_popup.c
+++ b/source/blender/editors/interface/interface_region_popup.c
@@ -555,9 +555,7 @@ static void ui_popup_block_remove(bContext *C, uiPopupBlockHandle *handle)
/* reset to region cursor (only if there's not another menu open) */
if (BLI_listbase_is_empty(&sc->regionbase)) {
- ED_region_cursor_set(win, ctx_sa, ctx_ar);
- /* in case cursor needs to be changed again */
- WM_event_add_mousemove(C);
+ win->tag_cursor_refresh = true;
}
if (handle->scrolltimer) {
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 4a6ce59de9b..cdbd049346e 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -311,6 +311,12 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
case TH_TIME_SCRUB_BACKGROUND:
cp = ts->time_scrub_background;
break;
+ case TH_TIME_MARKER_LINE:
+ cp = ts->time_marker_line;
+ break;
+ case TH_TIME_MARKER_LINE_SELECTED:
+ cp = ts->time_marker_line_selected;
+ break;
case TH_VIEW_OVERLAY:
cp = ts->view_overlay;
break;
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 8981221cb9c..454d3c07fff 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -1240,8 +1240,9 @@ static int objectsolver_set_inverse_exec(bContext *C, wmOperator *op)
/* despite 3 layers of checks, we may still not be able to find a constraint */
if (data == NULL) {
- printf("DEBUG: Child-Of Set Inverse - object = '%s'\n", (ob) ? ob->id.name + 2 : "<None>");
- BKE_report(op->reports, RPT_ERROR, "Could not find constraint data for Child-Of Set Inverse");
+ printf("DEBUG: ObjectSolver Set Inverse - object = '%s'\n", (ob) ? ob->id.name + 2 : "<None>");
+ BKE_report(
+ op->reports, RPT_ERROR, "Could not find constraint data for ObjectSolver Set Inverse");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index e440062738c..bac40b35102 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -754,30 +754,30 @@ static int modifier_apply_obdata(
return 1;
}
-int ED_object_modifier_apply(Main *bmain,
- ReportList *reports,
- Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
- ModifierData *md,
- int mode)
+bool ED_object_modifier_apply(Main *bmain,
+ ReportList *reports,
+ Depsgraph *depsgraph,
+ Scene *scene,
+ Object *ob,
+ ModifierData *md,
+ int mode)
{
int prev_mode;
if (BKE_object_is_in_editmode(ob)) {
BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in edit mode");
- return 0;
+ return false;
}
- else if (((ID *)ob->data)->us > 1) {
+ else if (ID_REAL_USERS(ob->data) > 1) {
BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied to multi-user data");
- return 0;
+ return false;
}
else if ((ob->mode & OB_MODE_SCULPT) && (find_multires_modifier_before(scene, md)) &&
(modifier_isSameTopology(md) == false)) {
BKE_report(reports,
RPT_ERROR,
"Constructive modifier cannot be applied to multi-res data in sculpt mode");
- return 0;
+ return false;
}
if (md != ob->modifiers.first) {
@@ -796,13 +796,13 @@ int ED_object_modifier_apply(Main *bmain,
if (mode == MODIFIER_APPLY_SHAPE) {
if (!modifier_apply_shape(bmain, reports, depsgraph, scene, ob, md_eval)) {
md_eval->mode = prev_mode;
- return 0;
+ return false;
}
}
else {
if (!modifier_apply_obdata(reports, depsgraph, scene, ob, md_eval)) {
md_eval->mode = prev_mode;
- return 0;
+ return false;
}
}
@@ -812,7 +812,7 @@ int ED_object_modifier_apply(Main *bmain,
BKE_object_free_derived_caches(ob);
- return 1;
+ return true;
}
int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierData *md)
@@ -931,28 +931,28 @@ bool edit_modifier_poll_generic(bContext *C,
ModifierData *mod = ptr.data; /* May be NULL. */
if (!ob || ID_IS_LINKED(ob)) {
- return 0;
+ return false;
}
if (obtype_flag && ((1 << ob->type) & obtype_flag) == 0) {
- return 0;
+ return false;
}
if (ptr.owner_id && ID_IS_LINKED(ptr.owner_id)) {
- return 0;
+ return false;
}
if (ID_IS_OVERRIDE_LIBRARY(ob)) {
if ((mod != NULL) && (mod->flag & eModifierFlag_OverrideLibrary_Local) == 0) {
CTX_wm_operator_poll_msg_set(C, "Cannot edit modifiers coming from library override");
- return 0;
+ return false;
}
}
if (!is_editmode_allowed && CTX_data_edit_object(C) != NULL) {
CTX_wm_operator_poll_msg_set(C, "This modifier operation is not allowed from Edit mode");
- return 0;
+ return false;
}
- return 1;
+ return true;
}
bool edit_modifier_poll(bContext *C)
@@ -1139,6 +1139,32 @@ void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
/************************ apply modifier operator *********************/
+static bool modifier_apply_poll(bContext *C)
+{
+ if (!edit_modifier_poll_generic(C, &RNA_Modifier, 0, false)) {
+ return false;
+ }
+
+ Scene *scene = CTX_data_scene(C);
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
+ Object *ob = (ptr.owner_id != NULL) ? (Object *)ptr.owner_id : ED_object_active_context(C);
+ ModifierData *md = ptr.data; /* May be NULL. */
+
+ if (ID_REAL_USERS(ob->data) > 1) {
+ CTX_wm_operator_poll_msg_set(C, "Modifiers cannot be applied to multi-user data");
+ return false;
+ }
+ else if (md != NULL) {
+ if ((ob->mode & OB_MODE_SCULPT) && (find_multires_modifier_before(scene, md)) &&
+ (modifier_isSameTopology(md) == false)) {
+ CTX_wm_operator_poll_msg_set(
+ C, "Constructive modifier cannot be applied to multi-res data in sculpt mode");
+ return false;
+ }
+ }
+ return true;
+}
+
static int modifier_apply_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
@@ -1187,7 +1213,7 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot)
ot->invoke = modifier_apply_invoke;
ot->exec = modifier_apply_exec;
- ot->poll = edit_modifier_poll;
+ ot->poll = modifier_apply_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 95bc90c8e5f..8ecaeefbd5f 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -217,13 +217,38 @@ static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
View3D *v3d = CTX_wm_view3d(C);
bool changed_multi = false;
+ Object *obact = CTX_data_active_object(C);
+ const Material *mat_active = obact ? BKE_object_material_get(obact, obact->actcol) : NULL;
+
uint objects_len = 0;
Object **objects = object_array_for_shading(C, &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
- if (ob->actcol <= 0) {
+ short mat_nr_active = -1;
+
+ if (ob->totcol == 0) {
continue;
}
+ if (obact && (mat_active == BKE_object_material_get(ob, obact->actcol))) {
+ /* Avoid searching since there may be multiple slots with the same material.
+ * For the active object or duplicates: match the material slot index first. */
+ mat_nr_active = obact->actcol - 1;
+ }
+ else {
+ /* Find the first matching material.
+ * Note: there may be multiple but that's not a common use case. */
+ for (short i = 0; i < ob->totcol; i++) {
+ const Material *mat = BKE_object_material_get(ob, i + 1);
+ if (mat_active == mat) {
+ mat_nr_active = i;
+ break;
+ }
+ }
+ if (mat_nr_active == -1) {
+ continue;
+ }
+ }
+
bool changed = false;
if (ob->type == OB_MESH) {
BMEditMesh *em = BKE_editmesh_from_object(ob);
@@ -234,7 +259,7 @@ static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
changed = true;
- efa->mat_nr = ob->actcol - 1;
+ efa->mat_nr = mat_nr_active;
}
}
}
@@ -247,7 +272,7 @@ static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
for (nu = nurbs->first; nu; nu = nu->next) {
if (ED_curve_nurb_select_check(v3d, nu)) {
changed = true;
- nu->mat_nr = ob->actcol - 1;
+ nu->mat_nr = mat_nr_active;
}
}
}
@@ -259,7 +284,7 @@ static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
if (ef && BKE_vfont_select_get(ob, &selstart, &selend)) {
for (i = selstart; i <= selend; i++) {
changed = true;
- ef->textbufinfo[i].mat_nr = ob->actcol;
+ ef->textbufinfo[i].mat_nr = mat_nr_active + 1;
}
}
}
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index c9e6cd24ac0..26240482e6d 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -1869,15 +1869,21 @@ void ED_region_floating_initialize(ARegion *ar)
void ED_region_cursor_set(wmWindow *win, ScrArea *sa, ARegion *ar)
{
- if (ar && sa && ar->type && ar->type->cursor) {
- ar->type->cursor(win, sa, ar);
- }
- else {
- if (WM_cursor_set_from_tool(win, sa, ar)) {
+ if (ar != NULL) {
+ if ((ar->gizmo_map != NULL) && WM_gizmomap_cursor_set(ar->gizmo_map, win)) {
+ return;
+ }
+ if (sa && ar->type && ar->type->cursor) {
+ ar->type->cursor(win, sa, ar);
return;
}
- WM_cursor_set(win, WM_CURSOR_DEFAULT);
}
+
+ if (WM_cursor_set_from_tool(win, sa, ar)) {
+ return;
+ }
+
+ WM_cursor_set(win, WM_CURSOR_DEFAULT);
}
/* for use after changing visibility of regions */
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 1520566cd9d..1fd3f258e6c 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -398,6 +398,15 @@ int screen_area_join(bContext *C, bScreen *scr, ScrArea *sa1, ScrArea *sa2)
/* ****************** EXPORTED API TO OTHER MODULES *************************** */
/* screen sets cursor based on active region */
+static void region_cursor_set_ex(wmWindow *win, ScrArea *sa, ARegion *ar, bool swin_changed)
+{
+ BLI_assert(WM_window_get_active_screen(win)->active_region == ar);
+ if (win->tag_cursor_refresh || swin_changed || (ar->type && ar->type->event_cursor)) {
+ win->tag_cursor_refresh = false;
+ ED_region_cursor_set(win, sa, ar);
+ }
+}
+
static void region_cursor_set(wmWindow *win, bool swin_changed)
{
bScreen *screen = WM_window_get_active_screen(win);
@@ -406,14 +415,7 @@ static void region_cursor_set(wmWindow *win, bool swin_changed)
{
for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar == screen->active_region) {
- if (swin_changed || (ar->type && ar->type->event_cursor)) {
- if (ar->gizmo_map != NULL) {
- if (WM_gizmomap_cursor_set(ar->gizmo_map, win)) {
- return;
- }
- }
- ED_region_cursor_set(win, sa, ar);
- }
+ region_cursor_set_ex(win, sa, ar, swin_changed);
return;
}
}
@@ -672,97 +674,98 @@ static void screen_cursor_set(wmWindow *win, const int xy[2])
}
}
-/* called in wm_event_system.c. sets state vars in screen, cursors */
-/* event type is mouse move */
+/**
+ * Called in wm_event_system.c. sets state vars in screen, cursors.
+ * event type is mouse move.
+ */
void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2])
{
bScreen *scr = WM_window_get_active_screen(win);
+ if (scr == NULL) {
+ return;
+ }
- if (scr) {
- ScrArea *sa = NULL;
- ARegion *ar;
- ARegion *old_ar = scr->active_region;
+ ScrArea *sa = NULL;
+ ARegion *ar;
+ ARegion *old_ar = scr->active_region;
- ED_screen_areas_iter(win, scr, area_iter)
- {
- if (xy[0] > area_iter->totrct.xmin && xy[0] < area_iter->totrct.xmax) {
- if (xy[1] > area_iter->totrct.ymin && xy[1] < area_iter->totrct.ymax) {
- if (ED_area_azones_update(area_iter, xy) == NULL) {
- sa = area_iter;
- break;
- }
- }
- }
- }
- if (sa) {
- /* make overlap active when mouse over */
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ED_region_contains_xy(ar, xy)) {
- scr->active_region = ar;
+ ED_screen_areas_iter(win, scr, area_iter)
+ {
+ if (xy[0] > area_iter->totrct.xmin && xy[0] < area_iter->totrct.xmax) {
+ if (xy[1] > area_iter->totrct.ymin && xy[1] < area_iter->totrct.ymax) {
+ if (ED_area_azones_update(area_iter, xy) == NULL) {
+ sa = area_iter;
break;
}
}
}
- else {
- scr->active_region = NULL;
+ }
+ if (sa) {
+ /* Make overlap active when mouse over. */
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ED_region_contains_xy(ar, xy)) {
+ scr->active_region = ar;
+ break;
+ }
}
+ }
+ else {
+ scr->active_region = NULL;
+ }
- /* check for redraw headers */
- if (old_ar != scr->active_region) {
+ /* Check for redraw headers. */
+ if (old_ar != scr->active_region) {
- ED_screen_areas_iter(win, scr, area_iter)
- {
- bool do_draw = false;
+ ED_screen_areas_iter(win, scr, area_iter)
+ {
+ bool do_draw = false;
- for (ar = area_iter->regionbase.first; ar; ar = ar->next) {
+ for (ar = area_iter->regionbase.first; ar; ar = ar->next) {
- /* call old area's deactivate if assigned */
- if (ar == old_ar && area_iter->type->deactivate) {
- area_iter->type->deactivate(area_iter);
- }
+ /* Call old area's deactivate if assigned. */
+ if (ar == old_ar && area_iter->type->deactivate) {
+ area_iter->type->deactivate(area_iter);
+ }
- if (ar == old_ar && ar != scr->active_region) {
- wmGizmoMap *gzmap = old_ar->gizmo_map;
- if (gzmap) {
- if (WM_gizmo_highlight_set(gzmap, NULL)) {
- ED_region_tag_redraw_no_rebuild(old_ar);
- }
+ if (ar == old_ar && ar != scr->active_region) {
+ wmGizmoMap *gzmap = old_ar->gizmo_map;
+ if (gzmap) {
+ if (WM_gizmo_highlight_set(gzmap, NULL)) {
+ ED_region_tag_redraw_no_rebuild(old_ar);
}
}
+ }
- if (ar == old_ar || ar == scr->active_region) {
- do_draw = true;
- }
+ if (ar == old_ar || ar == scr->active_region) {
+ do_draw = true;
}
+ }
- if (do_draw) {
- for (ar = area_iter->regionbase.first; ar; ar = ar->next) {
- if (ELEM(ar->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) {
- ED_region_tag_redraw_no_rebuild(ar);
- }
+ if (do_draw) {
+ for (ar = area_iter->regionbase.first; ar; ar = ar->next) {
+ if (ELEM(ar->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) {
+ ED_region_tag_redraw_no_rebuild(ar);
}
}
}
}
+ }
- /* cursors, for time being set always on edges, otherwise aregion doesn't switch */
- if (scr->active_region == NULL) {
- screen_cursor_set(win, xy);
- }
- else {
- /* notifier invokes freeing the buttons... causing a bit too much redraws */
- if (old_ar != scr->active_region) {
- region_cursor_set(win, true);
+ /* Cursors, for time being set always on edges,
+ * otherwise the active region doesn't switch. */
+ if (scr->active_region == NULL) {
+ screen_cursor_set(win, xy);
+ }
+ else {
+ /* Notifier invokes freeing the buttons... causing a bit too much redraws. */
+ region_cursor_set_ex(win, sa, scr->active_region, old_ar != scr->active_region);
- /* this used to be a notifier, but needs to be done immediate
- * because it can undo setting the right button as active due
- * to delayed notifier handling */
- if (C) {
- UI_screen_free_active_but(C, scr);
- }
- }
- else {
- region_cursor_set(win, false);
+ if (old_ar != scr->active_region) {
+ /* This used to be a notifier, but needs to be done immediate
+ * because it can undo setting the right button as active due
+ * to delayed notifier handling. */
+ if (C) {
+ UI_screen_free_active_but(C, scr);
}
}
}
@@ -1441,7 +1444,7 @@ void ED_refresh_viewport_fps(bContext *C)
/* redraws: uses defines from stime->redraws
* enable: 1 - forward on, -1 - backwards on, 0 - off
*/
-void ED_screen_animation_timer(bContext *C, int redraws, int refresh, int sync, int enable)
+void ED_screen_animation_timer(bContext *C, int redraws, int sync, int enable)
{
bScreen *screen = CTX_wm_screen(C);
wmWindowManager *wm = CTX_wm_manager(C);
@@ -1481,7 +1484,6 @@ void ED_screen_animation_timer(bContext *C, int redraws, int refresh, int sync,
}
}
sad->redraws = redraws;
- sad->refresh = refresh;
sad->flag |= (enable < 0) ? ANIMPLAY_FLAG_REVERSE : 0;
sad->flag |= (sync == 0) ? ANIMPLAY_FLAG_NO_SYNC : (sync == 1) ? ANIMPLAY_FLAG_SYNC : 0;
@@ -1526,14 +1528,13 @@ static ARegion *time_top_left_3dwindow(bScreen *screen)
return aret;
}
-void ED_screen_animation_timer_update(bScreen *screen, int redraws, int refresh)
+void ED_screen_animation_timer_update(bScreen *screen, int redraws)
{
if (screen && screen->animtimer) {
wmTimer *wt = screen->animtimer;
ScreenAnimData *sad = wt->customdata;
sad->redraws = redraws;
- sad->refresh = refresh;
sad->ar = NULL;
if (redraws & TIME_REGION) {
sad->ar = time_top_left_3dwindow(screen);
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index bd7475dc1a2..35d84d5d75e 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -4616,20 +4616,18 @@ int ED_screen_animation_play(bContext *C, int sync, int mode)
if (ED_screen_animation_playing(CTX_wm_manager(C))) {
/* stop playback now */
- ED_screen_animation_timer(C, 0, 0, 0, 0);
+ ED_screen_animation_timer(C, 0, 0, 0);
BKE_sound_stop_scene(scene_eval);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
else {
/* these settings are currently only available from a menu in the TimeLine */
- int refresh = SPACE_ACTION;
-
if (mode == 1) { /* XXX only play audio forwards!? */
BKE_sound_play_scene(scene_eval);
}
- ED_screen_animation_timer(C, screen->redraws_flag, refresh, sync, mode);
+ ED_screen_animation_timer(C, screen->redraws_flag, sync, mode);
if (screen->animtimer) {
wmTimer *wt = screen->animtimer;
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 0aec6d5e6a0..1739c15cbc6 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -133,8 +133,15 @@ static void draw_tile(int sx, int sy, int width, int height, int colorid, int sh
true, (float)sx, (float)(sy - height), (float)(sx + width), (float)sy, 5.0f, color);
}
-static void file_draw_icon(
- uiBlock *block, const char *path, int sx, int sy, int icon, int width, int height, bool drag)
+static void file_draw_icon(uiBlock *block,
+ const char *path,
+ int sx,
+ int sy,
+ int icon,
+ int width,
+ int height,
+ bool drag,
+ bool dimmed)
{
uiBut *but;
int x, y;
@@ -142,8 +149,11 @@ static void file_draw_icon(
x = sx;
y = sy - height;
+ /* For uiDefIconBut(), if a1==1.0 then a2 is alpha 0.0 - 1.0 */
+ const float a1 = dimmed ? 1.0f : 0.0f;
+ const float a2 = dimmed ? 0.3f : 0.0f;
but = uiDefIconBut(
- block, UI_BTYPE_LABEL, 0, icon, x, y, width, height, NULL, 0.0f, 0.0f, 0.0f, 0.0f, NULL);
+ block, UI_BTYPE_LABEL, 0, icon, x, y, width, height, NULL, 0.0f, 0.0f, a1, a2, NULL);
UI_but_func_tooltip_set(but, file_draw_tooltip_func, BLI_strdup(path));
if (drag) {
@@ -210,7 +220,8 @@ static void file_draw_preview(uiBlock *block,
FileLayout *layout,
const bool is_icon,
const int typeflags,
- const bool drag)
+ const bool drag,
+ const bool dimmed)
{
uiBut *but;
float fx, fy;
@@ -273,6 +284,10 @@ static void file_draw_preview(uiBlock *block,
UI_GetThemeColor4fv(TH_TEXT, col);
}
+ if (dimmed) {
+ col[3] *= 0.3f;
+ }
+
if (!is_icon && typeflags & FILE_TYPE_BLENDERLIB) {
/* Datablock preview images use premultiplied alpha. */
GPU_blend_set_func_separate(
@@ -775,6 +790,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
/* don't drag parent or refresh items */
do_drag = !(FILENAME_IS_CURRPAR(file->relpath));
+ const bool is_hidden = (file->attributes & FILE_ATTR_HIDDEN);
if (FILE_IMGDISPLAY == params->display) {
const int icon = filelist_geticon(files, i, false);
@@ -795,7 +811,8 @@ void file_draw_list(const bContext *C, ARegion *ar)
layout,
is_icon,
file->typeflag,
- do_drag);
+ do_drag,
+ is_hidden);
}
else {
file_draw_icon(block,
@@ -805,7 +822,8 @@ void file_draw_list(const bContext *C, ARegion *ar)
filelist_geticon(files, i, true),
ICON_DEFAULT_WIDTH_SCALE,
ICON_DEFAULT_HEIGHT_SCALE,
- do_drag);
+ do_drag,
+ is_hidden);
icon_ofs += ICON_DEFAULT_WIDTH_SCALE + 0.2f * UI_UNIT_X;
}
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index b328b32263c..28e6d95beb3 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -213,6 +213,9 @@ typedef struct FileListInternEntry {
/** not strictly needed, but used during sorting, avoids to have to recompute it there... */
char *name;
+ /** Defined in BLI_fileops.h */
+ eFileAttributes attributes;
+
BLI_stat_t st;
} FileListInternEntry;
@@ -609,54 +612,76 @@ void filelist_setsorting(struct FileList *filelist, const short sort, bool inver
/* ********** Filter helpers ********** */
-static bool is_hidden_file(const char *filename, FileListFilter *filter)
+/* True if filename is meant to be hidden, eg. starting with period. */
+static bool is_hidden_dot_filename(const char *filename, FileListInternEntry *file)
{
- char *sep = (char *)BLI_last_slash(filename);
- bool is_hidden = false;
-
- if (filter->flags & FLF_HIDE_DOT) {
- if (filename[0] == '.' && filename[1] != '.' && filename[1] != '\0') {
- is_hidden = true; /* ignore .file */
- }
- else {
- int len = strlen(filename);
- if ((len > 0) && (filename[len - 1] == '~')) {
- is_hidden = true; /* ignore file~ */
- }
- }
+ if (filename[0] == '.' && !ELEM(filename[1], '.', '\0')) {
+ return true; /* ignore .file */
}
- if (!is_hidden && (filter->flags & FLF_HIDE_PARENT)) {
- if (filename[0] == '.' && filename[1] == '.' && filename[2] == '\0') {
- is_hidden = true; /* ignore .. */
+ else {
+ int len = strlen(filename);
+ if ((len > 0) && (filename[len - 1] == '~')) {
+ return true; /* ignore file~ */
}
}
- if (!is_hidden && ((filename[0] == '.') && (filename[1] == '\0'))) {
- is_hidden = true; /* ignore . */
- }
+
/* filename might actually be a piece of path, in which case we have to check all its parts. */
- if (!is_hidden && sep) {
+
+ bool hidden = false;
+ char *sep = (char *)BLI_last_slash(filename);
+
+ if (!hidden && sep) {
char tmp_filename[FILE_MAX_LIBEXTRA];
BLI_strncpy(tmp_filename, filename, sizeof(tmp_filename));
sep = tmp_filename + (sep - filename);
while (sep) {
BLI_assert(sep[1] != '\0');
- if (is_hidden_file(sep + 1, filter)) {
- is_hidden = true;
+ if (is_hidden_dot_filename(sep + 1, file)) {
+ hidden = true;
break;
}
*sep = '\0';
sep = (char *)BLI_last_slash(tmp_filename);
}
}
- return is_hidden;
+ return hidden;
+}
+
+/* True if should be hidden, based on current filtering. */
+static bool is_filtered_hidden(const char *filename,
+ FileListFilter *filter,
+ FileListInternEntry *file)
+{
+ if ((filename[0] == '.') && (filename[1] == '\0')) {
+ return true; /* Ignore . */
+ }
+
+ if (filter->flags & FLF_HIDE_PARENT) {
+ if (filename[0] == '.' && filename[1] == '.' && filename[2] == '\0') {
+ return true; /* Ignore .. */
+ }
+ }
+
+ if ((filter->flags & FLF_HIDE_DOT) && (file->attributes & FILE_ATTR_HIDDEN)) {
+ return true; /* Ignore files with Hidden attribute. */
+ }
+
+#ifndef WIN32
+ /* Check for unix-style names starting with period. */
+ if ((filter->flags & FLF_HIDE_DOT) && is_hidden_dot_filename(filename, file)) {
+ return true;
+ }
+#endif
+
+ return false;
}
static bool is_filtered_file(FileListInternEntry *file,
const char *UNUSED(root),
FileListFilter *filter)
{
- bool is_filtered = !is_hidden_file(file->relpath, filter);
+ bool is_filtered = !is_filtered_hidden(file->relpath, filter, file);
if (is_filtered && !FILENAME_IS_CURRPAR(file->relpath)) {
/* We only check for types if some type are enabled in filtering. */
@@ -699,7 +724,7 @@ static bool is_filtered_lib(FileListInternEntry *file, const char *root, FileLis
BLI_join_dirfile(path, sizeof(path), root, file->relpath);
if (BLO_library_path_explode(path, dir, &group, &name)) {
- is_filtered = !is_hidden_file(file->relpath, filter);
+ is_filtered = !is_filtered_hidden(file->relpath, filter, file);
if (is_filtered && !FILENAME_IS_CURRPAR(file->relpath)) {
/* We only check for types if some type are enabled in filtering. */
if ((filter->filter || filter->filter_id) && (filter->flags & FLF_DO_FILTER)) {
@@ -747,7 +772,7 @@ static bool is_filtered_main(FileListInternEntry *file,
const char *UNUSED(dir),
FileListFilter *filter)
{
- return !is_hidden_file(file->relpath, filter);
+ return !is_filtered_hidden(file->relpath, filter, file);
}
static void filelist_filter_clear(FileList *filelist)
@@ -968,7 +993,7 @@ static int filelist_geticon_ex(FileDirEntry *file,
else if (is_main) {
/* Do not return icon for folders if icons are not 'main' draw type
* (e.g. when used over previews). */
- return ICON_FILE_FOLDER;
+ return (file->attributes & FILE_ATTR_ANY_LINK) ? ICON_FOLDER_REDIRECT : ICON_FILE_FOLDER;
}
else {
/* If this path is in System list then use that icon. */
@@ -984,6 +1009,19 @@ static int filelist_geticon_ex(FileDirEntry *file,
}
}
}
+
+ if (file->attributes & FILE_ATTR_ANY_LINK) {
+ return ICON_LOOP_FORWARDS;
+ }
+ else if (file->attributes & FILE_ATTR_OFFLINE) {
+ return ICON_ERROR;
+ }
+ else if (file->attributes & FILE_ATTR_TEMPORARY) {
+ return ICON_FILE_CACHE;
+ }
+ else if (file->attributes & FILE_ATTR_SYSTEM) {
+ return ICON_SYSTEM;
+ }
}
if (typeflag & FILE_TYPE_BLENDER) {
@@ -1621,7 +1659,7 @@ static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int in
memcpy(ret->uuid, entry->uuid, sizeof(ret->uuid));
ret->blentype = entry->blentype;
ret->typeflag = entry->typeflag;
-
+ ret->attributes = entry->attributes;
BLI_addtail(&cache->cached_entries, ret);
return ret;
}
@@ -2401,6 +2439,7 @@ static int filelist_readjob_list_dir(const char *root,
{
struct direntry *files;
int nbr_files, nbr_entries = 0;
+ char path[FILE_MAX];
nbr_files = BLI_filelist_dir_contents(root, &files);
if (files) {
@@ -2416,20 +2455,17 @@ static int filelist_readjob_list_dir(const char *root,
entry->relpath = MEM_dupallocN(files[i].relname);
entry->st = files[i].s;
+ BLI_join_dirfile(path, sizeof(path), root, entry->relpath);
+
/* Set file type. */
if (S_ISDIR(files[i].s.st_mode)) {
entry->typeflag = FILE_TYPE_DIR;
}
else if (do_lib && BLO_has_bfile_extension(entry->relpath)) {
/* If we are considering .blend files as libs, promote them to directory status. */
- char name[FILE_MAX];
-
entry->typeflag = FILE_TYPE_BLENDER;
-
- BLI_join_dirfile(name, sizeof(name), root, entry->relpath);
-
/* prevent current file being used as acceptable dir */
- if (BLI_path_cmp(main_name, name) != 0) {
+ if (BLI_path_cmp(main_name, path) != 0) {
entry->typeflag |= FILE_TYPE_DIR;
}
}
@@ -2441,6 +2477,16 @@ static int filelist_readjob_list_dir(const char *root,
}
}
+ /* Set file attributes. */
+ entry->attributes = BLI_file_attributes(path);
+
+#ifndef WIN32
+ /* Set linux-style dot files hidden too. */
+ if (is_hidden_dot_filename(entry->relpath, entry)) {
+ entry->attributes |= FILE_ATTR_HIDDEN;
+ }
+#endif
+
BLI_addtail(entries, entry);
nbr_entries++;
}
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 270fe0c59dc..f4688ce17fd 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -980,6 +980,16 @@ void uiTemplateImage(uiLayout *layout,
bool is_data = IMB_colormanagement_space_name_is_data(ima->colorspace_settings.name);
uiLayoutSetActive(sub, !is_data);
}
+
+ if (ima && iuser) {
+ void *lock;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
+
+ if (ibuf->rect_float && (ibuf->flags & IB_halffloat) == 0) {
+ uiItemR(col, &imaptr, "use_half_precision", 0, NULL, ICON_NONE);
+ }
+ BKE_image_release_ibuf(ima, ibuf, lock);
+ }
}
uiItemR(col, &imaptr, "use_view_as_render", 0, NULL, ICON_NONE);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 6dc4a7f950c..a3fa03b18b7 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1901,6 +1901,12 @@ void IMAGE_OT_replace(wmOperatorType *ot)
/** \name Save Image As Operator
* \{ */
+typedef struct ImageSaveData {
+ ImageUser *iuser;
+ Image *image;
+ ImageFormatData im_format;
+} ImageSaveData;
+
static char imtype_best_depth(ImBuf *ibuf, const char imtype)
{
const char depth_ok = BKE_imtype_valid_depths(imtype);
@@ -1980,9 +1986,6 @@ static int image_save_options_init(Main *bmain,
opts->im_format.views_format = ima->views_format;
}
- ///* XXX - this is lame, we need to make these available too! */
- // opts->subimtype = scene->r.subimtype;
-
BLI_strncpy(opts->filepath, ibuf->name, sizeof(opts->filepath));
/* sanitize all settings */
@@ -2030,6 +2033,8 @@ static int image_save_options_init(Main *bmain,
/* color management */
BKE_color_managed_display_settings_copy(&opts->im_format.display_settings,
&scene->display_settings);
+
+ BKE_color_managed_view_settings_free(&opts->im_format.view_settings);
BKE_color_managed_view_settings_copy(&opts->im_format.view_settings, &scene->view_settings);
}
@@ -2038,12 +2043,14 @@ static int image_save_options_init(Main *bmain,
return (ibuf != NULL);
}
-static void image_save_options_from_op(Main *bmain, ImageSaveOptions *opts, wmOperator *op)
+static void image_save_options_from_op(Main *bmain,
+ ImageSaveOptions *opts,
+ wmOperator *op,
+ ImageFormatData *imf)
{
- if (op->customdata) {
+ if (imf) {
BKE_color_managed_view_settings_free(&opts->im_format.view_settings);
-
- opts->im_format = *(ImageFormatData *)op->customdata;
+ opts->im_format = *imf;
}
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
@@ -2055,20 +2062,17 @@ static void image_save_options_from_op(Main *bmain, ImageSaveOptions *opts, wmOp
static void image_save_options_to_op(ImageSaveOptions *opts, wmOperator *op)
{
if (op->customdata) {
- BKE_color_managed_view_settings_free(&((ImageFormatData *)op->customdata)->view_settings);
-
- *(ImageFormatData *)op->customdata = opts->im_format;
+ ImageSaveData *isd = op->customdata;
+ BKE_color_managed_view_settings_free(&isd->im_format.view_settings);
+ isd->im_format = opts->im_format;
}
RNA_string_set(op->ptr, "filepath", opts->filepath);
}
-static bool save_image_op(const bContext *C, wmOperator *op, ImageSaveOptions *opts)
+static bool save_image_op(
+ Main *bmain, Image *ima, ImageUser *iuser, wmOperator *op, ImageSaveOptions *opts)
{
- Main *bmain = CTX_data_main(C);
- Image *ima = image_from_context(C);
- ImageUser *iuser = image_user_from_context(C);
-
opts->relative = (RNA_struct_find_property(op->ptr, "relative_path") &&
RNA_boolean_get(op->ptr, "relative_path"));
opts->save_copy = (RNA_struct_find_property(op->ptr, "copy") &&
@@ -2085,7 +2089,7 @@ static bool save_image_op(const bContext *C, wmOperator *op, ImageSaveOptions *o
/* Remember file path for next save. */
BLI_strncpy(G.ima, opts->filepath, sizeof(G.ima));
- WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
+ WM_main_add_notifier(NC_IMAGE | NA_EDITED, ima);
return ok;
}
@@ -2093,8 +2097,8 @@ static bool save_image_op(const bContext *C, wmOperator *op, ImageSaveOptions *o
static void image_save_as_free(wmOperator *op)
{
if (op->customdata) {
- ImageFormatData *im_format = (ImageFormatData *)op->customdata;
- BKE_color_managed_view_settings_free(&im_format->view_settings);
+ ImageSaveData *isd = op->customdata;
+ BKE_color_managed_view_settings_free(&isd->im_format.view_settings);
MEM_freeN(op->customdata);
op->customdata = NULL;
@@ -2105,20 +2109,32 @@ static int image_save_as_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- Image *image = image_from_context(C);
- ImageUser *iuser = image_user_from_context(C);
ImageSaveOptions opts;
+ Image *image = NULL;
+ ImageUser *iuser = NULL;
+ ImageFormatData *imf = NULL;
+ if (op->customdata) {
+ ImageSaveData *isd = op->customdata;
+ image = isd->image;
+ iuser = isd->iuser;
+ imf = &isd->im_format;
+ }
+ else {
+ image = image_from_context(C);
+ iuser = image_user_from_context(C);
+ }
+
BKE_image_save_options_init(&opts, bmain, scene);
/* just in case to initialize values,
* these should be set on invoke or by the caller. */
image_save_options_init(bmain, &opts, image, iuser, false, false);
- image_save_options_from_op(bmain, &opts, op);
+ image_save_options_from_op(bmain, &opts, op, imf);
opts.do_newpath = true;
- save_image_op(C, op, &opts);
+ save_image_op(bmain, image, iuser, op, &opts);
if (opts.save_copy == false) {
BKE_image_free_packedfiles(image);
@@ -2131,8 +2147,8 @@ static int image_save_as_exec(bContext *C, wmOperator *op)
static bool image_save_as_check(bContext *UNUSED(C), wmOperator *op)
{
- ImageFormatData *imf = op->customdata;
- return WM_operator_filesel_ensure_ext_imtype(op, imf);
+ ImageSaveData *isd = op->customdata;
+ return WM_operator_filesel_ensure_ext_imtype(op, &isd->im_format);
}
static int image_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
@@ -2164,8 +2180,12 @@ static int image_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS
RNA_boolean_set(op->ptr, "save_as_render", save_as_render);
- op->customdata = MEM_mallocN(sizeof(opts.im_format), __func__);
- memcpy(op->customdata, &opts.im_format, sizeof(opts.im_format));
+ ImageSaveData *isd = MEM_callocN(sizeof(*isd), __func__);
+ isd->image = ima;
+ isd->iuser = iuser;
+
+ memcpy(&isd->im_format, &opts.im_format, sizeof(opts.im_format));
+ op->customdata = isd;
/* show multiview save options only if image has multiviews */
prop = RNA_struct_find_property(op->ptr, "show_multiview");
@@ -2198,12 +2218,12 @@ static bool image_save_as_draw_check_prop(PointerRNA *ptr,
static void image_save_as_draw(bContext *UNUSED(C), wmOperator *op)
{
uiLayout *layout = op->layout;
- ImageFormatData *imf = op->customdata;
+ ImageSaveData *isd = op->customdata;
PointerRNA imf_ptr, ptr;
const bool is_multiview = RNA_boolean_get(op->ptr, "show_multiview");
/* image template */
- RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &imf_ptr);
+ RNA_pointer_create(NULL, &RNA_ImageFormatSettings, &isd->im_format, &imf_ptr);
uiTemplateImageSettings(layout, &imf_ptr, false);
/* main draw call */
@@ -2343,6 +2363,7 @@ static int image_save_exec(bContext *C, wmOperator *op)
ImageUser *iuser = image_user_from_context(C);
Scene *scene = CTX_data_scene(C);
ImageSaveOptions opts;
+ bool ok = false;
if (BKE_image_has_packedfile(image)) {
/* Save packed files to memory. */
@@ -2354,21 +2375,28 @@ static int image_save_exec(bContext *C, wmOperator *op)
if (image_save_options_init(bmain, &opts, image, iuser, false, false) == 0) {
return OPERATOR_CANCELLED;
}
- image_save_options_from_op(bmain, &opts, op);
+ image_save_options_from_op(bmain, &opts, op, NULL);
if (BLI_exists(opts.filepath) && BLI_file_is_writable(opts.filepath)) {
- if (save_image_op(C, op, &opts)) {
+ if (save_image_op(bmain, image, iuser, op, &opts)) {
/* report since this can be called from key-shortcuts */
BKE_reportf(op->reports, RPT_INFO, "Saved Image '%s'", opts.filepath);
+ ok = true;
}
}
else {
BKE_reportf(
op->reports, RPT_ERROR, "Cannot save image, path '%s' is not writable", opts.filepath);
- return OPERATOR_CANCELLED;
}
- return OPERATOR_FINISHED;
+ BKE_color_managed_view_settings_free(&opts.im_format.view_settings);
+
+ if (ok) {
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
static int image_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 7c64255380b..d9e1216e1bb 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -396,7 +396,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
NODE_WIDTH(node) - NODE_DY,
NODE_DY,
0,
- UI_style_get());
+ UI_style_get_dpi());
if (node->flag & NODE_MUTED) {
uiLayoutSetActive(layout, false);
@@ -491,7 +491,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
node->butr.xmax,
0,
0,
- UI_style_get());
+ UI_style_get_dpi());
if (node->flag & NODE_MUTED) {
uiLayoutSetActive(layout, false);
@@ -523,7 +523,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
NODE_WIDTH(node) - NODE_DY,
NODE_DY,
0,
- UI_style_get());
+ UI_style_get_dpi());
if (node->flag & NODE_MUTED) {
uiLayoutSetActive(layout, false);
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt
index 9e3c9d6725d..91694cfc1ef 100644
--- a/source/blender/editors/space_view3d/CMakeLists.txt
+++ b/source/blender/editors/space_view3d/CMakeLists.txt
@@ -94,10 +94,6 @@ if(WITH_FREESTYLE)
add_definitions(-DWITH_FREESTYLE)
endif()
-if(WITH_MOD_FLUID)
- add_definitions(-DWITH_FLUID)
-endif()
-
blender_add_lib(bf_editor_space_view3d "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
# Needed so we can use dna_type_offsets.h for defaults initialization.
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 858096f9a6d..bc81817647e 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -25,7 +25,6 @@
#include "MEM_guardedalloc.h"
-#include "DNA_armature_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_mask_types.h"
#include "DNA_mesh_types.h"
@@ -917,7 +916,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
- initTranslation(t);
+ transform_mode_init(t, NULL, TFM_TRANSLATION);
initSnapping(t, NULL); // need to reinit after mode change
t->redraw |= TREDRAW_HARD;
handled = true;
@@ -935,21 +934,20 @@ int transformEvent(TransInfo *t, const wmEvent *event)
resetTransRestrictions(t);
/* first try edge slide */
- initEdgeSlide(t);
+ transform_mode_init(t, NULL, TFM_EDGE_SLIDE);
/* if that fails, do vertex slide */
if (t->state == TRANS_CANCEL) {
resetTransModal(t);
t->state = TRANS_STARTING;
- initVertSlide(t);
+ transform_mode_init(t, NULL, TFM_VERT_SLIDE);
}
/* vert slide can fail on unconnected vertices (rare but possible) */
if (t->state == TRANS_CANCEL) {
resetTransModal(t);
- t->mode = TFM_TRANSLATION;
t->state = TRANS_STARTING;
restoreTransObjects(t);
resetTransRestrictions(t);
- initTranslation(t);
+ transform_mode_init(t, NULL, TFM_TRANSLATION);
}
initSnapping(t, NULL); // need to reinit after mode change
t->redraw |= TREDRAW_HARD;
@@ -982,10 +980,10 @@ int transformEvent(TransInfo *t, const wmEvent *event)
resetTransRestrictions(t);
if (t->mode == TFM_ROTATION) {
- initTrackball(t);
+ transform_mode_init(t, NULL, TFM_TRACKBALL);
}
else {
- initRotation(t);
+ transform_mode_init(t, NULL, TFM_ROTATION);
}
initSnapping(t, NULL); // need to reinit after mode change
t->redraw |= TREDRAW_HARD;
@@ -1010,7 +1008,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
- initResize(t);
+ transform_mode_init(t, NULL, TFM_RESIZE);
initSnapping(t, NULL); // need to reinit after mode change
t->redraw |= TREDRAW_HARD;
handled = true;
@@ -1214,7 +1212,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
else if (t->mode == TFM_ROTATION) {
restoreTransObjects(t);
- initTrackball(t);
+ transform_mode_init(t, NULL, TFM_TRACKBALL);
}
}
else {
@@ -1256,7 +1254,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
- initTranslation(t);
+ transform_mode_init(t, NULL, TFM_TRANSLATION);
initSnapping(t, NULL); // need to reinit after mode change
t->redraw |= TREDRAW_HARD;
handled = true;
@@ -1268,7 +1266,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
- initResize(t);
+ transform_mode_init(t, NULL, TFM_RESIZE);
initSnapping(t, NULL); // need to reinit after mode change
t->redraw |= TREDRAW_HARD;
handled = true;
@@ -1283,10 +1281,10 @@ int transformEvent(TransInfo *t, const wmEvent *event)
resetTransRestrictions(t);
if (t->mode == TFM_ROTATION) {
- initTrackball(t);
+ transform_mode_init(t, NULL, TFM_TRACKBALL);
}
else {
- initRotation(t);
+ transform_mode_init(t, NULL, TFM_ROTATION);
}
initSnapping(t, NULL); // need to reinit after mode change
t->redraw |= TREDRAW_HARD;
@@ -1368,7 +1366,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
- initNormalRotation(t);
+ transform_mode_init(t, NULL, TFM_NORMAL_ROTATION);
t->redraw = TREDRAW_HARD;
handled = true;
}
@@ -2113,145 +2111,7 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
initMouseInput(t, &t->mouse, t->center2d, event->mval, use_accurate);
}
- switch (mode) {
- case TFM_TRANSLATION:
- initTranslation(t);
- break;
- case TFM_ROTATION:
- initRotation(t);
- break;
- case TFM_RESIZE:
- initResize(t);
- break;
- case TFM_SKIN_RESIZE:
- initSkinResize(t);
- break;
- case TFM_TOSPHERE:
- initToSphere(t);
- break;
- case TFM_SHEAR:
- initShear(t);
- break;
- case TFM_BEND:
- initBend(t);
- break;
- case TFM_SHRINKFATTEN:
- initShrinkFatten(t);
- break;
- case TFM_TILT:
- initTilt(t);
- break;
- case TFM_CURVE_SHRINKFATTEN:
- initCurveShrinkFatten(t);
- break;
- case TFM_MASK_SHRINKFATTEN:
- initMaskShrinkFatten(t);
- break;
- case TFM_GPENCIL_SHRINKFATTEN:
- initGPShrinkFatten(t);
- break;
- case TFM_TRACKBALL:
- initTrackball(t);
- break;
- case TFM_PUSHPULL:
- initPushPull(t);
- break;
- case TFM_CREASE:
- initCrease(t);
- break;
- case TFM_BONESIZE: { /* used for both B-Bone width (bonesize) as for deform-dist (envelope) */
- /* Note: we have to pick one, use the active object. */
- TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_OK(t);
- bArmature *arm = tc->poseobj->data;
- if (arm->drawtype == ARM_ENVELOPE) {
- initBoneEnvelope(t);
- t->mode = TFM_BONE_ENVELOPE_DIST;
- }
- else {
- initBoneSize(t);
- }
- break;
- }
- case TFM_BONE_ENVELOPE:
- initBoneEnvelope(t);
- break;
- case TFM_BONE_ENVELOPE_DIST:
- initBoneEnvelope(t);
- t->mode = TFM_BONE_ENVELOPE_DIST;
- break;
- case TFM_EDGE_SLIDE:
- case TFM_VERT_SLIDE: {
- const bool use_even = (op ? RNA_boolean_get(op->ptr, "use_even") : false);
- const bool flipped = (op ? RNA_boolean_get(op->ptr, "flipped") : false);
- const bool use_clamp = (op ? RNA_boolean_get(op->ptr, "use_clamp") : true);
- if (mode == TFM_EDGE_SLIDE) {
- const bool use_double_side = (op ? !RNA_boolean_get(op->ptr, "single_side") : true);
- initEdgeSlide_ex(t, use_double_side, use_even, flipped, use_clamp);
- }
- else {
- initVertSlide_ex(t, use_even, flipped, use_clamp);
- }
- break;
- }
- case TFM_BONE_ROLL:
- initBoneRoll(t);
- break;
- case TFM_TIME_TRANSLATE:
- initTimeTranslate(t);
- break;
- case TFM_TIME_SLIDE:
- initTimeSlide(t);
- break;
- case TFM_TIME_SCALE:
- initTimeScale(t);
- break;
- case TFM_TIME_DUPLICATE:
- /* same as TFM_TIME_EXTEND, but we need the mode info for later
- * so that duplicate-culling will work properly
- */
- if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA)) {
- initTranslation(t);
- }
- else {
- initTimeTranslate(t);
- }
- t->mode = mode;
- break;
- case TFM_TIME_EXTEND:
- /* now that transdata has been made, do like for TFM_TIME_TRANSLATE (for most Animation
- * Editors because they have only 1D transforms for time values) or TFM_TRANSLATION
- * (for Graph/NLA Editors only since they uses 'standard' transforms to get 2D movement)
- * depending on which editor this was called from
- */
- if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA)) {
- initTranslation(t);
- }
- else {
- initTimeTranslate(t);
- }
- break;
- case TFM_BAKE_TIME:
- initBakeTime(t);
- break;
- case TFM_MIRROR:
- initMirror(t);
- break;
- case TFM_BWEIGHT:
- initBevelWeight(t);
- break;
- case TFM_ALIGN:
- initAlign(t);
- break;
- case TFM_SEQ_SLIDE:
- initSeqSlide(t);
- break;
- case TFM_NORMAL_ROTATION:
- initNormalRotation(t);
- break;
- case TFM_GPENCIL_OPACITY:
- initGPOpacity(t);
- break;
- }
+ transform_mode_init(t, op, mode);
if (t->state == TRANS_CANCEL) {
postTrans(C, t);
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index 5d3d1d936a2..3d9a04c060b 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -1030,7 +1030,15 @@ static void create_trans_vert_customdata_layer(BMVert *v,
void trans_mesh_customdata_correction_init(TransInfo *t)
{
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- BLI_assert(tc->custom.type.data == NULL);
+ if (tc->custom.type.data) {
+ if (tc->custom.type.free_cb == trans_mesh_customdata_free_cb) {
+ /* Custom data correction has initiated before. */
+ continue;
+ }
+ else {
+ BLI_assert(false);
+ }
+ }
int i;
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 00f34a20cb6..c925f5c9a8e 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -1374,13 +1374,6 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
bGPdata *gpd = CTX_data_gpencil_data(C);
PropertyRNA *prop;
- if (op && (prop = RNA_struct_find_property(op->ptr, "center_override")) &&
- RNA_property_is_set(op->ptr, prop)) {
- RNA_property_float_get_array(op->ptr, prop, t->center_global);
- mul_v3_v3(t->center_global, t->aspect);
- t->flag |= T_OVERRIDE_CENTER;
- }
-
if (op && (prop = RNA_struct_find_property(op->ptr, "mouse_coordinate_override")) &&
RNA_property_is_set(op->ptr, prop)) {
RNA_property_int_get_array(op->ptr, prop, t->mval);
@@ -1640,7 +1633,6 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
(RNA_enum_get(op->ptr, "orient_type") == RNA_enum_get(op->ptr, "orient_matrix_type")))) {
RNA_property_float_get_array(op->ptr, prop, &t->orient_matrix[0][0]);
copy_m3_m3(t->spacemtx, t->orient_matrix);
- negate_m3(t->spacemtx);
/* Some transform modes use this to operate on an axis. */
t->orient_matrix_is_set = true;
t->orientation.user = V3D_ORIENT_CUSTOM_MATRIX;
@@ -1780,6 +1772,13 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
setTransformViewAspect(t, t->aspect);
+ if (op && (prop = RNA_struct_find_property(op->ptr, "center_override")) &&
+ RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_float_get_array(op->ptr, prop, t->center_global);
+ mul_v3_v3(t->center_global, t->aspect);
+ t->flag |= T_OVERRIDE_CENTER;
+ }
+
setTransformViewMatrices(t);
initNumInput(&t->num);
}
diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c
index e681b649451..cdd29ccf24f 100644
--- a/source/blender/editors/transform/transform_mode.c
+++ b/source/blender/editors/transform/transform_mode.c
@@ -24,8 +24,10 @@
#include <stdlib.h>
#include "DNA_anim_types.h"
+#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_windowmanager_types.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
@@ -35,6 +37,8 @@
#include "BKE_context.h"
#include "BKE_nla.h"
+#include "RNA_access.h"
+
#include "ED_screen.h"
#include "UI_interface.h"
@@ -484,7 +488,7 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
}
/* -------------------------------------------------------------------- */
-/* Transform (Rotaion Utils) */
+/* Transform (Rotation Utils) */
/** \name Transform Rotaion Utils
* \{ */
@@ -1098,3 +1102,159 @@ void doAnimEdit_SnapFrame(
}
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/* Transform Mode API */
+
+/** \name Transform Frame Utils
+ * \{ */
+
+void transform_mode_init(TransInfo *t, wmOperator *op, const int mode)
+{
+ t->mode = mode;
+
+ switch (mode) {
+ case TFM_TRANSLATION:
+ initTranslation(t);
+ break;
+ case TFM_ROTATION:
+ initRotation(t);
+ break;
+ case TFM_RESIZE:
+ initResize(t);
+ break;
+ case TFM_SKIN_RESIZE:
+ initSkinResize(t);
+ break;
+ case TFM_TOSPHERE:
+ initToSphere(t);
+ break;
+ case TFM_SHEAR:
+ initShear(t);
+ break;
+ case TFM_BEND:
+ initBend(t);
+ break;
+ case TFM_SHRINKFATTEN:
+ initShrinkFatten(t);
+ break;
+ case TFM_TILT:
+ initTilt(t);
+ break;
+ case TFM_CURVE_SHRINKFATTEN:
+ initCurveShrinkFatten(t);
+ break;
+ case TFM_MASK_SHRINKFATTEN:
+ initMaskShrinkFatten(t);
+ break;
+ case TFM_GPENCIL_SHRINKFATTEN:
+ initGPShrinkFatten(t);
+ break;
+ case TFM_TRACKBALL:
+ initTrackball(t);
+ break;
+ case TFM_PUSHPULL:
+ initPushPull(t);
+ break;
+ case TFM_CREASE:
+ initCrease(t);
+ break;
+ case TFM_BONESIZE: { /* used for both B-Bone width (bonesize) as for deform-dist (envelope) */
+ /* Note: we have to pick one, use the active object. */
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_OK(t);
+ bArmature *arm = tc->poseobj->data;
+ if (arm->drawtype == ARM_ENVELOPE) {
+ initBoneEnvelope(t);
+ t->mode = TFM_BONE_ENVELOPE_DIST;
+ }
+ else {
+ initBoneSize(t);
+ }
+ break;
+ }
+ case TFM_BONE_ENVELOPE:
+ initBoneEnvelope(t);
+ break;
+ case TFM_BONE_ENVELOPE_DIST:
+ initBoneEnvelope(t);
+ t->mode = TFM_BONE_ENVELOPE_DIST;
+ break;
+ case TFM_EDGE_SLIDE:
+ case TFM_VERT_SLIDE: {
+ const bool use_even = (op ? RNA_boolean_get(op->ptr, "use_even") : false);
+ const bool flipped = (op ? RNA_boolean_get(op->ptr, "flipped") : false);
+ const bool use_clamp = (op ? RNA_boolean_get(op->ptr, "use_clamp") : true);
+ if (mode == TFM_EDGE_SLIDE) {
+ const bool use_double_side = (op ? !RNA_boolean_get(op->ptr, "single_side") : true);
+ initEdgeSlide_ex(t, use_double_side, use_even, flipped, use_clamp);
+ }
+ else {
+ initVertSlide_ex(t, use_even, flipped, use_clamp);
+ }
+ break;
+ }
+ case TFM_BONE_ROLL:
+ initBoneRoll(t);
+ break;
+ case TFM_TIME_TRANSLATE:
+ initTimeTranslate(t);
+ break;
+ case TFM_TIME_SLIDE:
+ initTimeSlide(t);
+ break;
+ case TFM_TIME_SCALE:
+ initTimeScale(t);
+ break;
+ case TFM_TIME_DUPLICATE:
+ /* same as TFM_TIME_EXTEND, but we need the mode info for later
+ * so that duplicate-culling will work properly
+ */
+ if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA)) {
+ initTranslation(t);
+ }
+ else {
+ initTimeTranslate(t);
+ }
+ break;
+ case TFM_TIME_EXTEND:
+ /* now that transdata has been made, do like for TFM_TIME_TRANSLATE (for most Animation
+ * Editors because they have only 1D transforms for time values) or TFM_TRANSLATION
+ * (for Graph/NLA Editors only since they uses 'standard' transforms to get 2D movement)
+ * depending on which editor this was called from
+ */
+ if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_NLA)) {
+ initTranslation(t);
+ }
+ else {
+ initTimeTranslate(t);
+ }
+ break;
+ case TFM_BAKE_TIME:
+ initBakeTime(t);
+ break;
+ case TFM_MIRROR:
+ initMirror(t);
+ break;
+ case TFM_BWEIGHT:
+ initBevelWeight(t);
+ break;
+ case TFM_ALIGN:
+ initAlign(t);
+ break;
+ case TFM_SEQ_SLIDE:
+ initSeqSlide(t);
+ break;
+ case TFM_NORMAL_ROTATION:
+ initNormalRotation(t);
+ break;
+ case TFM_GPENCIL_OPACITY:
+ initGPOpacity(t);
+ break;
+ }
+
+ /* TODO(germano): Some of these operations change the `t->mode`.
+ * This can be bad for Redo.
+ * BLI_assert(t->mode == mode); */
+}
+
+/** \} */
diff --git a/source/blender/editors/transform/transform_mode.h b/source/blender/editors/transform/transform_mode.h
index bb036a69a88..a8a930cc156 100644
--- a/source/blender/editors/transform/transform_mode.h
+++ b/source/blender/editors/transform/transform_mode.h
@@ -30,6 +30,7 @@ struct LinkNode;
struct TransInfo;
struct TransDataContainer;
struct TransData;
+struct wmOperator;
/* header of TransDataEdgeSlideVert, TransDataEdgeSlideEdge */
typedef struct TransDataGenericSlideVert {
@@ -56,6 +57,7 @@ void ElementResize(TransInfo *t, TransDataContainer *tc, TransData *td, float ma
short getAnimEdit_SnapMode(TransInfo *t);
void doAnimEdit_SnapFrame(
TransInfo *t, TransData *td, TransData2D *td2d, struct AnimData *adt, short autosnap);
+void transform_mode_init(TransInfo *t, struct wmOperator *op, const int mode);
/* transform_mode_align.c */
void initAlign(TransInfo *t);
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 1952a2c862e..ea4f1eedd81 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -512,11 +512,11 @@ void initTransformOrientation(bContext *C, TransInfo *t)
t->orientation.unset = V3D_ORIENT_VIEW;
copy_m3_m4(t->orient_matrix, t->viewinv);
normalize_m3(t->orient_matrix);
+ negate_m3(t->orient_matrix);
}
else {
copy_m3_m3(t->orient_matrix, t->spacemtx);
}
- negate_m3(t->orient_matrix);
}
}
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 1e758771f6a..49acf0ca3a4 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -53,6 +53,8 @@
#include "BKE_scene.h"
#include "BKE_editmesh.h"
#include "BKE_layer.h"
+#include "BKE_lib_id.h"
+#include "BKE_mesh.h"
#include "DEG_depsgraph.h"
@@ -500,11 +502,15 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene,
smd.levels = smd_real->levels;
smd.subdivType = smd_real->subdivType;
- initialDerived = CDDM_from_editbmesh(em, false);
- derivedMesh = subsurf_make_derived_from_derived(
- initialDerived, &smd, scene, NULL, SUBSURF_IN_EDIT_MODE);
+ {
+ Mesh *me_from_em = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL, ob->data);
+ initialDerived = CDDM_from_mesh_ex(me_from_em, CD_REFERENCE, &CD_MASK_MESH);
+ derivedMesh = subsurf_make_derived_from_derived(
+ initialDerived, &smd, scene, NULL, SUBSURF_IN_EDIT_MODE);
- initialDerived->release(initialDerived);
+ initialDerived->release(initialDerived);
+ BKE_id_free(NULL, me_from_em);
+ }
/* get the derived data */
subsurfedVerts = derivedMesh->getVertArray(derivedMesh);
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index f89a76cf49c..cc681c02009 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -71,6 +71,7 @@ void GPU_create_gl_tex(unsigned int *bind,
int recth,
int textarget,
bool mipmap,
+ bool half_float,
bool use_srgb,
struct Image *ima);
void GPU_create_gl_tex_compressed(unsigned int *bind,
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 6afff4f68f1..62a5de7ebe6 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -328,7 +328,9 @@ static uint gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf)
GLenum data_type, internal_format;
if (main_ibuf->rect_float) {
data_type = GL_FLOAT;
- internal_format = GL_RGBA16F;
+ internal_format = (!(main_ibuf->flags & IB_halffloat) && (ima->flag & IMA_HIGH_BITDEPTH)) ?
+ GL_RGBA32F :
+ GL_RGBA16F;
}
else {
data_type = GL_UNSIGNED_BYTE;
@@ -472,6 +474,7 @@ static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget)
{
uint bindcode = 0;
const bool mipmap = GPU_get_mipmap();
+ const bool half_float = (ibuf->flags & IB_halffloat) != 0;
#ifdef WITH_DDS
if (ibuf->ftype == IMB_FTYPE_DDS) {
@@ -536,6 +539,7 @@ static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget)
ibuf->y,
textarget,
mipmap,
+ half_float,
compress_as_srgb,
ima);
@@ -1043,6 +1047,7 @@ void GPU_create_gl_tex(uint *bind,
int recth,
int textarget,
bool mipmap,
+ bool half_float,
bool use_srgb,
Image *ima)
{
@@ -1072,7 +1077,8 @@ void GPU_create_gl_tex(uint *bind,
glGenTextures(1, (GLuint *)bind);
glBindTexture(textarget, *bind);
- GLenum internal_format = (frect) ? GL_RGBA16F : (use_srgb) ? GL_SRGB8_ALPHA8 : GL_RGBA8;
+ GLenum float_format = (!half_float && ima->flag & IMA_HIGH_BITDEPTH) ? GL_RGBA32F : GL_RGBA16F;
+ GLenum internal_format = (frect) ? float_format : (use_srgb) ? GL_SRGB8_ALPHA8 : GL_RGBA8;
if (textarget == GL_TEXTURE_2D) {
if (frect) {
@@ -1236,18 +1242,21 @@ void GPU_create_gl_tex_compressed(unsigned int *bind, int textarget, Image *ima,
const bool use_srgb = !(IMB_colormanagement_space_is_data(ibuf->rect_colorspace) ||
IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace));
const bool mipmap = GPU_get_mipmap();
+ const bool half_float = (ibuf->flags & IB_halffloat) != 0;
#ifndef WITH_DDS
(void)ibuf;
/* Fall back to uncompressed if DDS isn't enabled */
- GPU_create_gl_tex(bind, ibuf->rect, NULL, ibuf->x, ibuf->y, textarget, mipmap, use_srgb, ima);
+ GPU_create_gl_tex(
+ bind, ibuf->rect, NULL, ibuf->x, ibuf->y, textarget, mipmap, half_float, use_srgb, ima);
#else
glGenTextures(1, (GLuint *)bind);
glBindTexture(textarget, *bind);
if (textarget == GL_TEXTURE_2D && GPU_upload_dxt_texture(ibuf, use_srgb) == 0) {
glDeleteTextures(1, (GLuint *)bind);
- GPU_create_gl_tex(bind, ibuf->rect, NULL, ibuf->x, ibuf->y, textarget, mipmap, use_srgb, ima);
+ GPU_create_gl_tex(
+ bind, ibuf->rect, NULL, ibuf->x, ibuf->y, textarget, mipmap, half_float, use_srgb, ima);
}
glBindTexture(textarget, 0);
diff --git a/source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl
index e8323520af5..73f40c693ae 100644
--- a/source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl
@@ -33,6 +33,7 @@ void main()
vec4 overlay_col = texture(overlays_texture, texCoord_interp.st);
+ fragColor = clamp(fragColor, 0.0, 1.0);
fragColor *= 1.0 - overlay_col.a;
fragColor += overlay_col;
diff --git a/source/blender/gpu/shaders/gpu_shader_text_frag.glsl b/source/blender/gpu/shaders/gpu_shader_text_frag.glsl
index f9f195c31d6..cc12e3f78a5 100644
--- a/source/blender/gpu/shaders/gpu_shader_text_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_text_frag.glsl
@@ -1,9 +1,13 @@
flat in vec4 color_flat;
noperspective in vec2 texCoord_interp;
+flat in int glyph_offset;
+flat in ivec2 glyph_dim;
+flat in int interp_size;
+
out vec4 fragColor;
-uniform sampler2D glyph;
+uniform sampler1DArray glyph;
const vec2 offsets4[4] = vec2[4](
vec2(-0.5, 0.5), vec2(0.5, 0.5), vec2(-0.5, -0.5), vec2(-0.5, -0.5));
@@ -25,54 +29,108 @@ const vec2 offsets16[16] = vec2[16](vec2(-1.5, 1.5),
vec2(0.5, -1.5),
vec2(1.5, -1.5));
-#define sample_glyph_offset(texco, texel, ofs) texture(glyph, texco + ofs * texel).r
+//#define GPU_NEAREST
+#define sample_glyph_offset(texel, ofs) \
+ texture_1D_custom_bilinear_filter(texCoord_interp + ofs * texel)
+
+float texel_fetch(int index)
+{
+ int size_x = textureSize(glyph, 0).r;
+ if (index >= size_x) {
+ return texelFetch(glyph, ivec2(index % size_x, index / size_x), 0).r;
+ }
+ return texelFetch(glyph, ivec2(index, 0), 0).r;
+}
+
+bool is_inside_box(ivec2 v)
+{
+ return all(greaterThanEqual(v, ivec2(0))) && all(lessThan(v, glyph_dim));
+}
+
+float texture_1D_custom_bilinear_filter(vec2 uv)
+{
+ vec2 texel_2d = uv * glyph_dim + 0.5;
+ ivec2 texel_2d_near = ivec2(texel_2d) - 1;
+ int frag_offset = glyph_offset + texel_2d_near.y * glyph_dim.x + texel_2d_near.x;
+
+ float tl = 0.0;
+
+ if (is_inside_box(texel_2d_near)) {
+ tl = texel_fetch(frag_offset);
+ }
+
+#ifdef GPU_NEAREST
+ return tl;
+#else // GPU_LINEAR
+ int offset_x = 1;
+ int offset_y = glyph_dim.x;
+
+ float tr = 0.0;
+ float bl = 0.0;
+ float br = 0.0;
+
+ if (is_inside_box(texel_2d_near + ivec2(1, 0))) {
+ tr = texel_fetch(frag_offset + offset_x);
+ }
+ if (is_inside_box(texel_2d_near + ivec2(0, 1))) {
+ bl = texel_fetch(frag_offset + offset_y);
+ }
+ if (is_inside_box(texel_2d_near + ivec2(1, 1))) {
+ br = texel_fetch(frag_offset + offset_x + offset_y);
+ }
+
+ vec2 f = fract(texel_2d);
+ float tA = mix(tl, tr, f.x);
+ float tB = mix(bl, br, f.x);
+
+ return mix(tA, tB, f.y);
+#endif
+}
void main()
{
// input color replaces texture color
fragColor.rgb = color_flat.rgb;
- vec2 texel = 1.0 / vec2(textureSize(glyph, 0));
- vec2 texco = abs(texCoord_interp);
-
// modulate input alpha & texture alpha
- if (texCoord_interp.x > 0) {
- fragColor.a = texture(glyph, texco).r;
+ if (interp_size == 0) {
+ fragColor.a = texture_1D_custom_bilinear_filter(texCoord_interp);
}
else {
+ vec2 texel = 1.0 / glyph_dim;
fragColor.a = 0.0;
- if (texCoord_interp.y > 0) {
+ if (interp_size == 1) {
/* 3x3 blur */
/* Manual unroll for perf. (stupid glsl compiler) */
- fragColor.a += sample_glyph_offset(texco, texel, offsets4[0]);
- fragColor.a += sample_glyph_offset(texco, texel, offsets4[1]);
- fragColor.a += sample_glyph_offset(texco, texel, offsets4[2]);
- fragColor.a += sample_glyph_offset(texco, texel, offsets4[3]);
+ fragColor.a += sample_glyph_offset(texel, offsets4[0]);
+ fragColor.a += sample_glyph_offset(texel, offsets4[1]);
+ fragColor.a += sample_glyph_offset(texel, offsets4[2]);
+ fragColor.a += sample_glyph_offset(texel, offsets4[3]);
fragColor.a *= (1.0 / 4.0);
}
else {
/* 5x5 blur */
/* Manual unroll for perf. (stupid glsl compiler) */
- fragColor.a += sample_glyph_offset(texco, texel, offsets16[0]);
- fragColor.a += sample_glyph_offset(texco, texel, offsets16[1]);
- fragColor.a += sample_glyph_offset(texco, texel, offsets16[2]);
- fragColor.a += sample_glyph_offset(texco, texel, offsets16[3]);
-
- fragColor.a += sample_glyph_offset(texco, texel, offsets16[4]);
- fragColor.a += sample_glyph_offset(texco, texel, offsets16[5]) * 2.0;
- fragColor.a += sample_glyph_offset(texco, texel, offsets16[6]) * 2.0;
- fragColor.a += sample_glyph_offset(texco, texel, offsets16[7]);
-
- fragColor.a += sample_glyph_offset(texco, texel, offsets16[8]);
- fragColor.a += sample_glyph_offset(texco, texel, offsets16[9]) * 2.0;
- fragColor.a += sample_glyph_offset(texco, texel, offsets16[10]) * 2.0;
- fragColor.a += sample_glyph_offset(texco, texel, offsets16[11]);
-
- fragColor.a += sample_glyph_offset(texco, texel, offsets16[12]);
- fragColor.a += sample_glyph_offset(texco, texel, offsets16[13]);
- fragColor.a += sample_glyph_offset(texco, texel, offsets16[14]);
- fragColor.a += sample_glyph_offset(texco, texel, offsets16[15]);
+ fragColor.a += sample_glyph_offset(texel, offsets16[0]);
+ fragColor.a += sample_glyph_offset(texel, offsets16[1]);
+ fragColor.a += sample_glyph_offset(texel, offsets16[2]);
+ fragColor.a += sample_glyph_offset(texel, offsets16[3]);
+
+ fragColor.a += sample_glyph_offset(texel, offsets16[4]);
+ fragColor.a += sample_glyph_offset(texel, offsets16[5]) * 2.0;
+ fragColor.a += sample_glyph_offset(texel, offsets16[6]) * 2.0;
+ fragColor.a += sample_glyph_offset(texel, offsets16[7]);
+
+ fragColor.a += sample_glyph_offset(texel, offsets16[8]);
+ fragColor.a += sample_glyph_offset(texel, offsets16[9]) * 2.0;
+ fragColor.a += sample_glyph_offset(texel, offsets16[10]) * 2.0;
+ fragColor.a += sample_glyph_offset(texel, offsets16[11]);
+
+ fragColor.a += sample_glyph_offset(texel, offsets16[12]);
+ fragColor.a += sample_glyph_offset(texel, offsets16[13]);
+ fragColor.a += sample_glyph_offset(texel, offsets16[14]);
+ fragColor.a += sample_glyph_offset(texel, offsets16[15]);
fragColor.a *= (1.0 / 20.0);
}
}
diff --git a/source/blender/gpu/shaders/gpu_shader_text_vert.glsl b/source/blender/gpu/shaders/gpu_shader_text_vert.glsl
index 28437208e91..768638e5229 100644
--- a/source/blender/gpu/shaders/gpu_shader_text_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_text_vert.glsl
@@ -2,20 +2,33 @@
uniform mat4 ModelViewProjectionMatrix;
in vec4 pos; /* rect */
-in vec4 tex; /* rect */
in vec4 col;
+in int offset;
+in ivec2 glyph_size;
flat out vec4 color_flat;
noperspective out vec2 texCoord_interp;
+flat out int glyph_offset;
+flat out ivec2 glyph_dim;
+flat out int interp_size;
void main()
{
+ color_flat = col;
+ glyph_offset = offset;
+ glyph_dim = abs(glyph_size);
+ interp_size = int(glyph_size.x < 0) + int(glyph_size.y < 0);
+
/* Quad expension using instanced rendering. */
float x = float(gl_VertexID % 2);
float y = float(gl_VertexID / 2);
vec2 quad = vec2(x, y);
- gl_Position = ModelViewProjectionMatrix * vec4(mix(pos.xy, pos.zw, quad), 0.0, 1.0);
- texCoord_interp = mix(abs(tex.xy), abs(tex.zw), quad) * sign(tex.xw);
- color_flat = col;
+ vec2 interp_offset = float(interp_size) / abs(pos.zw - pos.xy);
+ texCoord_interp = mix(-interp_offset, 1.0 + interp_offset, quad);
+
+ vec2 final_pos = mix(
+ pos.xy + ivec2(-interp_size, interp_size), pos.zw + ivec2(interp_size, -interp_size), quad);
+
+ gl_Position = ModelViewProjectionMatrix * vec4(final_pos, 0.0, 1.0);
}
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl
index e029905a908..714792489f6 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl
@@ -4,8 +4,8 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result)
N = normalize(N);
result = CLOSURE_DEFAULT;
eevee_closure_diffuse(N, color.rgb, 1.0, true, result.radiance);
+ result.radiance = render_pass_diffuse_mask(color.rgb, result.radiance * color.rgb);
closure_load_ssr_data(vec3(0.0), 0.0, N, viewCameraVec, -1, result);
- result.radiance *= color.rgb;
}
#else
/* Stub diffuse because it is not compatible with volumetrics. */
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl
index 34062cc8d02..747395857ee 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl
@@ -32,7 +32,9 @@ void node_eevee_specular(vec4 diffuse,
float alpha = 1.0 - transp;
result = CLOSURE_DEFAULT;
- result.radiance = out_diff * diffuse.rgb + out_spec + emissive.rgb;
+ result.radiance = render_pass_diffuse_mask(diffuse.rgb, out_diff * diffuse.rgb);
+ result.radiance += render_pass_glossy_mask(vec3(1.0), out_spec);
+ result.radiance += render_pass_emission_mask(emissive.rgb);
result.radiance *= alpha;
result.transmittance = vec3(transp);
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_emission.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_emission.glsl
index 092b9ed08bb..502bc7f92d6 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_emission.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_emission.glsl
@@ -2,7 +2,7 @@ void node_emission(vec4 color, float strength, vec3 vN, out Closure result)
{
result = CLOSURE_DEFAULT;
#ifndef VOLUMETRICS
- result.radiance = color.rgb * strength;
+ result.radiance = render_pass_emission_mask(color.rgb) * strength;
result.ssr_normal = normal_encode(vN, viewCameraVec);
#else
result.emission = color.rgb * strength;
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl
index 5038cb3892f..ece770f0e73 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl
@@ -17,12 +17,12 @@ void node_bsdf_glass(
out_spec,
out_refr,
ssr_spec);
- out_refr *= refr_color;
- out_spec *= color.rgb;
float fresnel = F_eta(ior, dot(N, cameraVec));
vec3 vN = mat3(ViewMatrix) * N;
result = CLOSURE_DEFAULT;
- result.radiance = mix(out_refr, out_spec, fresnel);
+ result.radiance = render_pass_glossy_mask(refr_color, out_refr * refr_color) * (1.0 - fresnel);
+ result.radiance += render_pass_glossy_mask(color.rgb, out_spec * color.rgb) * fresnel;
+
closure_load_ssr_data(
ssr_spec * color.rgb * fresnel, roughness, N, viewCameraVec, int(ssr_id), result);
}
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl
index 75cc2e770c5..7513c3a4edb 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl
@@ -7,7 +7,7 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Clo
N, vec3(1.0), vec3(1.0), int(ssr_id), roughness, 1.0, true, out_spec, ssr_spec);
vec3 vN = mat3(ViewMatrix) * N;
result = CLOSURE_DEFAULT;
- result.radiance = out_spec * color.rgb;
+ result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec) * color.rgb;
closure_load_ssr_data(ssr_spec * color.rgb, roughness, N, viewCameraVec, int(ssr_id), result);
}
#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 7af409dd410..3c85dc6456c 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
@@ -18,15 +18,22 @@ void convert_metallic_to_specular_tinted(vec3 basecol,
diffuse = basecol * (1.0 - metallic);
}
-vec3 principled_sheen(float NV, vec3 basecol_tint, float sheen_tint)
+/* Output sheen is to be multiplied by sheen_color. */
+void principled_sheen(float NV,
+ vec3 basecol_tint,
+ float sheen,
+ float sheen_tint,
+ out float out_sheen,
+ out vec3 sheen_color)
{
float f = 1.0 - NV;
/* Temporary fix for T59784. Normal map seems to contain NaNs for tangent space normal maps,
* therefore we need to clamp value. */
f = clamp(f, 0.0, 1.0);
/* Empirical approximation (manual curve fitting). Can be refined. */
- float sheen = f * f * f * 0.077 + f * 0.01 + 0.00026;
- return sheen * mix(vec3(1.0), basecol_tint, sheen_tint);
+ out_sheen = f * f * f * 0.077 + f * 0.01 + 0.00026;
+
+ sheen_color = sheen * mix(vec3(1.0), basecol_tint, sheen_tint);
}
void node_bsdf_principled(vec4 base_color,
@@ -61,18 +68,23 @@ void node_bsdf_principled(vec4 base_color,
ior = max(ior, 1e-5);
metallic = saturate(metallic);
transmission = saturate(transmission);
+ float m_transmission = 1.0 - transmission;
+
float dielectric = 1.0 - metallic;
transmission *= dielectric;
sheen *= dielectric;
subsurface_color *= dielectric;
- vec3 diffuse, f0, out_diff, out_spec, out_refr, ssr_spec;
+ vec3 diffuse, f0, out_diff, out_spec, out_refr, ssr_spec, sheen_color;
+ float out_sheen;
vec3 ctint = tint_from_color(base_color.rgb);
convert_metallic_to_specular_tinted(
base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0);
float NV = dot(N, cameraVec);
- vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint);
+ principled_sheen(NV, ctint, sheen, sheen_tint, out_sheen, sheen_color);
+
+ vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic);
/* Far from being accurate, but 2 glossy evaluation is too expensive.
* Most noticeable difference is at grazing angles since the bsdf lut
@@ -81,8 +93,12 @@ void node_bsdf_principled(vec4 base_color,
float fresnel = F_eta(ior, NV);
vec3 spec_col = F_color_blend(ior, fresnel, f0_glass) * fresnel;
f0 = mix(f0, spec_col, transmission);
+ f90 = mix(f90, spec_col, transmission);
- vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic);
+ /* Really poor approximation but needed to workaround issues with renderpasses. */
+ spec_col = mix(vec3(1.0), spec_col, transmission);
+ /* Match cycles. */
+ spec_col += float(clearcoat > 1e-5);
vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface);
@@ -108,19 +124,22 @@ void node_bsdf_principled(vec4 base_color,
vec3 refr_color = base_color.rgb;
refr_color *= (refractionDepth > 0.0) ? refr_color :
vec3(1.0); /* Simulate 2 transmission event */
- out_refr *= refr_color * (1.0 - fresnel) * transmission;
+ refr_color *= saturate(1.0 - fresnel) * transmission;
+
+ sheen_color *= m_transmission;
+ mixed_ss_base_color *= m_transmission;
result = CLOSURE_DEFAULT;
- result.radiance = out_spec + out_refr;
- result.radiance += out_diff * out_sheen; /* Coarse approx. */
- result.radiance += emission.rgb;
+ result.radiance = render_pass_glossy_mask(refr_color, out_refr * refr_color);
+ result.radiance += render_pass_glossy_mask(spec_col, out_spec);
+ /* Coarse approx. */
+ result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color);
+ result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
-
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
- mixed_ss_base_color *= alpha * (1.0 - transmission);
+ mixed_ss_base_color *= alpha;
closure_load_sss_data(sss_scalef, out_diff, mixed_ss_base_color, int(sss_id), result);
-
result.transmittance = vec3(1.0 - alpha);
}
@@ -156,22 +175,26 @@ void node_bsdf_principled_dielectric(vec4 base_color,
metallic = saturate(metallic);
float dielectric = 1.0 - metallic;
- vec3 diffuse, f0, out_diff, out_spec, ssr_spec;
+ vec3 diffuse, f0, out_diff, out_spec, ssr_spec, sheen_color;
+ float out_sheen;
vec3 ctint = tint_from_color(base_color.rgb);
convert_metallic_to_specular_tinted(
base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0);
+ vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic);
+
float NV = dot(N, cameraVec);
- vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint);
+ principled_sheen(NV, ctint, sheen, sheen_tint, out_sheen, sheen_color);
eevee_closure_default(
- N, diffuse, f0, vec3(1.0), int(ssr_id), roughness, 1.0, true, out_diff, out_spec, ssr_spec);
+ N, diffuse, f0, f90, int(ssr_id), roughness, 1.0, true, out_diff, out_spec, ssr_spec);
result = CLOSURE_DEFAULT;
- result.radiance = out_spec + out_diff * (diffuse + out_sheen);
- result.radiance += emission.rgb;
+ result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec);
+ result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color);
+ result.radiance += render_pass_diffuse_mask(diffuse, out_diff * diffuse);
+ result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
-
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
result.transmittance = vec3(1.0 - alpha);
@@ -214,10 +237,9 @@ void node_bsdf_principled_metallic(vec4 base_color,
N, base_color.rgb, f90, int(ssr_id), roughness, 1.0, true, out_spec, ssr_spec);
result = CLOSURE_DEFAULT;
- result.radiance = out_spec;
- result.radiance += emission.rgb;
+ result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec);
+ result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
-
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
result.transmittance = vec3(1.0 - alpha);
@@ -268,10 +290,12 @@ void node_bsdf_principled_clearcoat(vec4 base_color,
true,
out_spec,
ssr_spec);
+ /* Match cycles. */
+ float spec_col = 1.0 + float(clearcoat > 1e-5);
result = CLOSURE_DEFAULT;
- result.radiance = out_spec;
- result.radiance += emission.rgb;
+ result.radiance = render_pass_glossy_mask(vec3(spec_col), out_spec);
+ result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
@@ -310,7 +334,8 @@ void node_bsdf_principled_subsurface(vec4 base_color,
metallic = saturate(metallic);
N = normalize(N);
- vec3 diffuse, f0, out_diff, out_spec, ssr_spec;
+ vec3 diffuse, f0, out_diff, out_spec, ssr_spec, sheen_color;
+ float out_sheen;
vec3 ctint = tint_from_color(base_color.rgb);
convert_metallic_to_specular_tinted(
base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0);
@@ -320,7 +345,7 @@ void node_bsdf_principled_subsurface(vec4 base_color,
float sss_scalef = avg(sss_scale) * subsurface;
float NV = dot(N, cameraVec);
- vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint);
+ principled_sheen(NV, ctint, sheen, sheen_tint, out_sheen, sheen_color);
vec3 f90 = mix(vec3(1.0), base_color.rgb, (1.0 - specular) * metallic);
@@ -338,14 +363,14 @@ void node_bsdf_principled_subsurface(vec4 base_color,
ssr_spec);
result = CLOSURE_DEFAULT;
- result.radiance = out_spec;
- result.radiance += out_diff * out_sheen;
- result.radiance += emission.rgb;
+ result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec);
+ result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color);
+ result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
- mixed_ss_base_color *= alpha * (1.0 - transmission);
+ mixed_ss_base_color *= alpha;
closure_load_sss_data(sss_scalef, out_diff, mixed_ss_base_color, int(sss_id), result);
result.transmittance = vec3(1.0 - alpha);
@@ -400,16 +425,18 @@ void node_bsdf_principled_glass(vec4 base_color,
vec3 refr_color = base_color.rgb;
refr_color *= (refractionDepth > 0.0) ? refr_color :
vec3(1.0); /* Simulate 2 transmission events */
- out_refr *= refr_color;
float fresnel = F_eta(ior, dot(N, cameraVec));
vec3 spec_col = F_color_blend(ior, fresnel, f0);
- out_spec *= spec_col;
- ssr_spec *= spec_col * fresnel;
+ spec_col *= fresnel;
+ refr_color *= (1.0 - fresnel);
+
+ ssr_spec *= spec_col;
result = CLOSURE_DEFAULT;
- result.radiance = mix(out_refr, out_spec, fresnel);
- result.radiance += emission.rgb;
+ result.radiance = render_pass_glossy_mask(refr_color, out_refr * refr_color);
+ result.radiance += render_pass_glossy_mask(spec_col, out_spec * spec_col);
+ result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
result.transmittance = vec3(1.0 - alpha);
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl
index 906964e1539..4088d6db06a 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl
@@ -8,7 +8,7 @@ void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Cl
vec3 vN = mat3(ViewMatrix) * N;
result = CLOSURE_DEFAULT;
result.ssr_normal = normal_encode(vN, viewCameraVec);
- result.radiance = out_refr * color.rgb;
+ result.radiance = render_pass_glossy_mask(color.rgb, out_refr * color.rgb);
}
#else
/* Stub refraction because it is not compatible with volumetrics. */
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl
index 241228c0d4c..9bbbe71b206 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl
@@ -19,6 +19,7 @@ void node_subsurface_scattering(vec4 color,
/* Not perfect for texture_blur not exactly equal to 0.0 or 1.0. */
vec3 sss_albedo = mix(color.rgb, vec3(1.0), texture_blur);
out_diff *= mix(vec3(1.0), color.rgb, texture_blur);
+ result.radiance = render_pass_sss_mask(sss_albedo);
closure_load_sss_data(scale, out_diff, sss_albedo, int(sss_id), result);
}
#else
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl
index 749b3a4c11f..5c3ed81410a 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl
@@ -5,7 +5,7 @@ void node_bsdf_translucent(vec4 color, vec3 N, out Closure result)
result = CLOSURE_DEFAULT;
eevee_closure_diffuse(-N, color.rgb, 1.0, false, result.radiance);
closure_load_ssr_data(vec3(0.0), 0.0, N, viewCameraVec, -1, result);
- result.radiance *= color.rgb;
+ result.radiance = render_pass_diffuse_mask(color.rgb, result.radiance * color.rgb);
}
#else
/* Stub translucent because it is not compatible with volumetrics. */
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_vector_rotate.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_vector_rotate.glsl
index 7d707706a03..405821e01e3 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_vector_rotate.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_vector_rotate.glsl
@@ -50,33 +50,3 @@ void node_vector_rotate_euler_xyz(
{
vec = euler_to_mat3(rotation) * (vector_in - center) + center;
}
-
-void node_vector_rotate_euler_xzy(
- vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
-{
- vec = euler_to_mat3(-rotation.xzy) * (vector_in - center) + center;
-}
-
-void node_vector_rotate_euler_yxz(
- vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
-{
- vec = euler_to_mat3(-rotation.yxz) * (vector_in - center) + center;
-}
-
-void node_vector_rotate_euler_yzx(
- vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
-{
- vec = euler_to_mat3(rotation.yzx) * (vector_in - center) + center;
-}
-
-void node_vector_rotate_euler_zxy(
- vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
-{
- vec = euler_to_mat3(rotation.zxy) * (vector_in - center) + center;
-}
-
-void node_vector_rotate_euler_zyx(
- vec3 vector_in, vec3 center, vec3 axis, float angle, vec3 rotation, out vec3 vec)
-{
- vec = euler_to_mat3(-rotation.zyx) * (vector_in - center) + center;
-}
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index 61aa1f401a0..0568c425e78 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -291,6 +291,7 @@ enum {
IB_alphamode_ignore = 1 << 15,
IB_thumbnail = 1 << 16,
IB_multiview = 1 << 17,
+ IB_halffloat = 1 << 18,
};
/** \} */
diff --git a/source/blender/imbuf/intern/oiio/openimageio_api.cpp b/source/blender/imbuf/intern/oiio/openimageio_api.cpp
index e001b8b21c4..4746cec41d4 100644
--- a/source/blender/imbuf/intern/oiio/openimageio_api.cpp
+++ b/source/blender/imbuf/intern/oiio/openimageio_api.cpp
@@ -194,7 +194,7 @@ struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspac
{
struct ImBuf *ibuf = NULL;
int width, height, components;
- bool is_float, is_alpha;
+ bool is_float, is_alpha, is_half;
int basesize;
char file_colorspace[IM_MAX_SPACE];
const bool is_colorspace_manually_set = (colorspace[0] != '\0');
@@ -243,6 +243,7 @@ struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspac
is_alpha = spec.alpha_channel != -1;
basesize = spec.format.basesize();
is_float = basesize > 1;
+ is_half = spec.format == TypeDesc::HALF;
/* we only handle certain number of components */
if (!(components >= 1 && components <= 4)) {
@@ -271,6 +272,7 @@ struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspac
ibuf->ftype = IMB_FTYPE_PSD;
ibuf->channels = 4;
ibuf->planes = (3 + (is_alpha ? 1 : 0)) * 4 << basesize;
+ ibuf->flags |= (is_float && is_half) ? IB_halffloat : 0;
try {
return ibuf;
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index e1513169736..9fa2c7a28c5 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -1757,6 +1757,18 @@ static bool exr_has_alpha(MultiPartInputFile &file)
return !(file.header(0).channels().findChannel("A") == NULL);
}
+static bool exr_is_half_float(MultiPartInputFile &file)
+{
+ const ChannelList &channels = file.header(0).channels();
+ for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) {
+ const Channel &channel = i.channel();
+ if (channel.type != HALF) {
+ return false;
+ }
+ }
+ return true;
+}
+
static bool imb_exr_is_multilayer_file(MultiPartInputFile &file)
{
const ChannelList &channels = file.header(0).channels();
@@ -1909,6 +1921,7 @@ struct ImBuf *imb_load_openexr(const unsigned char *mem,
const int is_alpha = exr_has_alpha(*file);
ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, 0);
+ ibuf->flags |= exr_is_half_float(*file) ? IB_halffloat : 0;
if (hasXDensity(file->header(0))) {
ibuf->ppm[0] = xDensity(file->header(0)) * 39.3700787f;
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index 73a9e7f8a0a..03de4fb0473 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -192,7 +192,7 @@ typedef struct Image {
/* Image.flag */
enum {
- IMA_FLAG_UNUSED_0 = (1 << 0), /* cleared */
+ IMA_HIGH_BITDEPTH = (1 << 0),
IMA_FLAG_UNUSED_1 = (1 << 1), /* cleared */
#ifdef DNA_DEPRECATED_ALLOW
IMA_DO_PREMUL = (1 << 2),
diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h
index 5480bed51e8..09d02e9a375 100644
--- a/source/blender/makesdna/DNA_layer_types.h
+++ b/source/blender/makesdna/DNA_layer_types.h
@@ -28,6 +28,26 @@ extern "C" {
#include "DNA_freestyle_types.h"
#include "DNA_listBase.h"
+/* Renderpasses for EEVEE.
+ * ViewLayerEEVEE.render_passes */
+typedef enum eViewLayerEEVEEPassType {
+ EEVEE_RENDER_PASS_COMBINED = (1 << 0),
+ EEVEE_RENDER_PASS_Z = (1 << 1),
+ EEVEE_RENDER_PASS_MIST = (1 << 2),
+ EEVEE_RENDER_PASS_NORMAL = (1 << 3),
+ EEVEE_RENDER_PASS_DIFFUSE_LIGHT = (1 << 4),
+ EEVEE_RENDER_PASS_DIFFUSE_COLOR = (1 << 5),
+ EEVEE_RENDER_PASS_SPECULAR_LIGHT = (1 << 6),
+ EEVEE_RENDER_PASS_SPECULAR_COLOR = (1 << 7),
+ EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE = (1 << 8),
+ EEVEE_RENDER_PASS_VOLUME_SCATTER = (1 << 9),
+ EEVEE_RENDER_PASS_EMIT = (1 << 10),
+ EEVEE_RENDER_PASS_ENVIRONMENT = (1 << 11),
+ EEVEE_RENDER_PASS_SHADOW = (1 << 12),
+ EEVEE_RENDER_PASS_AO = (1 << 13),
+ EEVEE_RENDER_PASS_BLOOM = (1 << 14),
+} eViewLayerEEVEEPassType;
+
typedef struct Base {
struct Base *next, *prev;
@@ -76,6 +96,12 @@ typedef struct LayerCollection {
short _pad2[3];
} LayerCollection;
+/* Type containing EEVEE settings per view-layer */
+typedef struct ViewLayerEEVEE {
+ int render_passes;
+ int _pad[1];
+} ViewLayerEEVEE;
+
typedef struct ViewLayer {
struct ViewLayer *next, *prev;
/** MAX_NAME. */
@@ -106,6 +132,7 @@ typedef struct ViewLayer {
struct IDProperty *id_properties;
struct FreestyleConfig freestyle_config;
+ struct ViewLayerEEVEE eevee;
/* Runtime data */
/** ViewLayerEngineData. */
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 5f7c42b7521..44d44b92499 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1212,11 +1212,6 @@ enum {
NODE_VECTOR_ROTATE_TYPE_AXIS_Y = 2,
NODE_VECTOR_ROTATE_TYPE_AXIS_Z = 3,
NODE_VECTOR_ROTATE_TYPE_EULER_XYZ = 4,
- NODE_VECTOR_ROTATE_TYPE_EULER_XZY = 5,
- NODE_VECTOR_ROTATE_TYPE_EULER_YXZ = 6,
- NODE_VECTOR_ROTATE_TYPE_EULER_YZX = 7,
- NODE_VECTOR_ROTATE_TYPE_EULER_ZXY = 8,
- NODE_VECTOR_ROTATE_TYPE_EULER_ZYX = 9,
};
/* math node clamp */
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 7cd6b5f5013..71f701b87ad 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -318,6 +318,9 @@ typedef enum eScenePassType {
#define RE_PASSNAME_SUBSURFACE_COLOR "SubsurfaceCol"
#define RE_PASSNAME_FREESTYLE "Freestyle"
+#define RE_PASSNAME_BLOOM "BloomCol"
+#define RE_PASSNAME_VOLUME_TRANSMITTANCE "VolumeTransmCol"
+#define RE_PASSNAME_VOLUME_SCATTER "VolumeScatterCol"
/* View - MultiView */
typedef struct SceneRenderView {
@@ -1923,25 +1926,6 @@ enum {
R_COLOR_MANAGEMENT_UNUSED_1 = (1 << 1),
};
-#ifdef DNA_DEPRECATED_ALLOW
-/* RenderData.subimtype flag options for imtype */
-enum {
- R_OPENEXR_HALF = (1 << 0), /*deprecated*/
- R_OPENEXR_ZBUF = (1 << 1), /*deprecated*/
- R_PREVIEW_JPG = (1 << 2), /*deprecated*/
- R_CINEON_LOG = (1 << 3), /*deprecated*/
- R_TIFF_16BIT = (1 << 4), /*deprecated*/
-
- R_JPEG2K_12BIT = (1 << 5),
- /* Jpeg2000 */ /*deprecated*/
- R_JPEG2K_16BIT = (1 << 6), /*deprecated*/
- R_JPEG2K_YCC = (1 << 7),
- /* when disabled use RGB */ /*deprecated*/
- R_JPEG2K_CINE_PRESET = (1 << 8), /*deprecated*/
- R_JPEG2K_CINE_48FPS = (1 << 9), /*deprecated*/
-};
-#endif
-
/* bake_mode: same as RE_BAKE_xxx defines */
/* RenderData.bake_flag */
#define R_BAKE_CLEAR (1 << 0)
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index 483e5c4a952..8fec5354d36 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -474,8 +474,8 @@ enum {
/** Update size of regions within the area. */
AREA_FLAG_REGION_SIZE_UPDATE = (1 << 3),
AREA_FLAG_ACTIVE_TOOL_UPDATE = (1 << 4),
+ // AREA_FLAG_UNUSED_5 = (1 << 5),
- // AREA_FLAG_UNUSED_5 = (1 << 5),
AREA_FLAG_UNUSED_6 = (1 << 6), /* cleared */
/**
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 159c0424ee8..bdfe5040794 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -965,6 +965,8 @@ typedef struct FileDirEntry {
short status;
short flags;
+ /* eFileAttributes defined in BLI_fileops.h */
+ int attributes;
ListBase variants;
int nbr_variants;
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 8459447a688..d0d966381d1 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -289,6 +289,7 @@ typedef struct ThemeSpace {
unsigned char time_keyframe[4], time_gp_keyframe[4];
unsigned char freestyle_edge_mark[4], freestyle_face_mark[4];
unsigned char time_scrub_background[4];
+ unsigned char time_marker_line[4], time_marker_line_selected[4];
unsigned char nurb_uline[4], nurb_vline[4];
unsigned char act_spline[4], nurb_sel_uline[4], nurb_sel_vline[4], lastsel_point[4];
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 9a3bbee115b..c45a1480087 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -170,6 +170,7 @@ typedef struct View3DShading {
float studiolight_rot_z;
float studiolight_background;
float studiolight_intensity;
+ float studiolight_blur;
float object_outline_color[3];
float xray_alpha;
@@ -185,7 +186,6 @@ typedef struct View3DShading {
/* Render pass displayed in the viewport. Is an `eScenePassType` where one bit is set */
int render_pass;
- char _pad2[4];
struct IDProperty *prop;
} View3DShading;
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index b1a797a35fe..491b481d001 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -239,11 +239,10 @@ typedef struct wmWindow {
/** Window coords. */
short posx, posy, sizex, sizey;
/** Borderless, full. */
- short windowstate;
- /** Multiscreen... no idea how to store yet. */
- short monitor;
+ char windowstate;
/** Set to 1 if an active window, for quick rejects. */
- short active;
+ char active;
+ char _pad0[4];
/** Current mouse cursor type. */
short cursor;
/** Previous cursor when setting modal one. */
@@ -254,7 +253,8 @@ typedef struct wmWindow {
short grabcursor;
/** Internal: tag this for extra mousemove event,
* makes cursors/buttons active on UI switching. */
- short addmousemove;
+ char addmousemove;
+ char tag_cursor_refresh;
/** Winid also in screens, is for retrieving this window after read. */
int winid;
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 7d82b97868d..41858fffcf5 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -677,6 +677,7 @@ extern StructRNA RNA_View3DCursor;
extern StructRNA RNA_View3DOverlay;
extern StructRNA RNA_View3DShading;
extern StructRNA RNA_ViewLayer;
+extern StructRNA RNA_ViewLayerEEVEE;
extern StructRNA RNA_VoronoiTexture;
extern StructRNA RNA_WalkNavigation;
extern StructRNA RNA_WarpModifier;
diff --git a/source/blender/makesrna/intern/rna_fluid.c b/source/blender/makesrna/intern/rna_fluid.c
index a87a091f15e..d4bc02bbf3e 100644
--- a/source/blender/makesrna/intern/rna_fluid.c
+++ b/source/blender/makesrna/intern/rna_fluid.c
@@ -1711,7 +1711,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop,
"Maximum Trapped Air Potential",
"Upper clamping threshold for marking fluid cells where air is trapped "
- "(highe value results in less marked cells)");
+ "(higher value results in less marked cells)");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_resetCache");
prop = RNA_def_property(srna, "sndparticle_potential_min_energy", PROP_FLOAT, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 9f5f1635536..94b5786665c 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -193,6 +193,17 @@ static char *rna_ImageUser_path(PointerRNA *ptr)
return BLI_strdup("");
}
+static void rna_Image_gpu_texture_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ Image *ima = (Image *)ptr->owner_id;
+
+ if (!G.background) {
+ GPU_free_image(ima);
+ }
+
+ WM_main_add_notifier(NC_IMAGE | ND_DISPLAY, &ima->id);
+}
+
static const EnumPropertyItem *rna_Image_source_itemf(bContext *UNUSED(C),
PointerRNA *ptr,
PropertyRNA *UNUSED(prop),
@@ -1119,6 +1130,13 @@ static void rna_def_image(BlenderRNA *brna)
"when saving and loading the image");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_colormanage_update");
+ prop = RNA_def_property(srna, "use_half_precision", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", IMA_HIGH_BITDEPTH);
+ RNA_def_property_ui_text(prop,
+ "Half Float Precision",
+ "Use 16bits per channel to lower the memory usage during rendering");
+ RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_gpu_texture_update");
+
/* multiview */
prop = RNA_def_property(srna, "views_format", PROP_ENUM, PROP_NONE);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 5e21fc883a9..689b36ffea0 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -2274,7 +2274,7 @@ static void rna_def_mesh_looptris(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
- RNA_def_property_srna(cprop, "MeshLoopTriangle");
+ RNA_def_property_srna(cprop, "MeshLoopTriangles");
srna = RNA_def_struct(brna, "MeshLoopTriangles", NULL);
RNA_def_struct_sdna(srna, "Mesh");
RNA_def_struct_ui_text(
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 36bb65294fb..c4672ead29d 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -131,37 +131,7 @@ const EnumPropertyItem rna_enum_vector_rotate_type_items[] = {
{NODE_VECTOR_ROTATE_TYPE_AXIS_X, "X_AXIS", 0, "X Axis", "Rotate a point using X axis"},
{NODE_VECTOR_ROTATE_TYPE_AXIS_Y, "Y_AXIS", 0, "Y Axis", "Rotate a point using Y axis"},
{NODE_VECTOR_ROTATE_TYPE_AXIS_Z, "Z_AXIS", 0, "Z Axis", "Rotate a point using Z axis"},
- {NODE_VECTOR_ROTATE_TYPE_EULER_XYZ,
- "EULER_XYZ",
- 0,
- "XYZ Euler",
- "Rotate a point using XYZ order"},
-
- {NODE_VECTOR_ROTATE_TYPE_EULER_XZY,
- "EULER_XZY",
- 0,
- "XZY Euler",
- "Rotate a point using XZY order"},
- {NODE_VECTOR_ROTATE_TYPE_EULER_YXZ,
- "EULER_YXZ",
- 0,
- "YXZ Euler",
- "Rotate a point using YXZ order"},
- {NODE_VECTOR_ROTATE_TYPE_EULER_YZX,
- "EULER_YZX",
- 0,
- "YZX Euler",
- "Rotate a point using YZX order"},
- {NODE_VECTOR_ROTATE_TYPE_EULER_ZXY,
- "EULER_ZXY",
- 0,
- "ZXY Euler",
- "Rotate a point using ZXY order"},
- {NODE_VECTOR_ROTATE_TYPE_EULER_ZYX,
- "EULER_ZYX",
- 0,
- "XZY Euler",
- "Rotate a point using ZYX order"},
+ {NODE_VECTOR_ROTATE_TYPE_EULER_XYZ, "EULER_XYZ", 0, "Euler", "Rotate a point using XYZ order"},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index c0daedba95c..a3cf6fcd0b7 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -86,7 +86,6 @@ const EnumPropertyItem rna_enum_bake_pass_type_items[] = {
{SCE_PASS_DIFFUSE_COLOR, "DIFFUSE", 0, "Diffuse", ""},
{SCE_PASS_GLOSSY_COLOR, "GLOSSY", 0, "Glossy", ""},
{SCE_PASS_TRANSM_COLOR, "TRANSMISSION", 0, "Transmission", ""},
- {SCE_PASS_SUBSURFACE_COLOR, "SUBSURFACE", 0, "Subsurface", ""},
{0, NULL, 0, NULL, NULL},
};
@@ -533,7 +532,7 @@ static void rna_def_render_engine(BlenderRNA *brna)
0,
INT_MAX,
"Pass Filter",
- "Filter to combined, diffuse, glossy, transmission and subsurface passes",
+ "Filter to combined, diffuse, glossy and transmission passes",
0,
INT_MAX);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index d2a17967de9..599b8fd91c8 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -526,7 +526,6 @@ const EnumPropertyItem rna_enum_bake_pass_filter_type_items[] = {
{R_BAKE_PASS_FILTER_DIFFUSE, "DIFFUSE", 0, "Diffuse", ""},
{R_BAKE_PASS_FILTER_GLOSSY, "GLOSSY", 0, "Glossy", ""},
{R_BAKE_PASS_FILTER_TRANSM, "TRANSMISSION", 0, "Transmission", ""},
- {R_BAKE_PASS_FILTER_SUBSURFACE, "SUBSURFACE", 0, "Subsurface", ""},
{0, NULL, 0, NULL, NULL},
};
@@ -3756,6 +3755,30 @@ static void rna_def_unit_settings(BlenderRNA *brna)
RNA_def_property_update(prop, NC_WINDOW, NULL);
}
+static void rna_def_view_layer_eevee(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+ srna = RNA_def_struct(brna, "ViewLayerEEVEE", NULL);
+ RNA_def_struct_ui_text(srna, "EEVEE Settings", "View layer settings for EEVEE");
+
+ prop = RNA_def_property(srna, "use_pass_volume_scatter", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "render_passes", EEVEE_RENDER_PASS_VOLUME_SCATTER);
+ RNA_def_property_ui_text(prop, "Volume Scatter", "Deliver volume scattering pass");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
+
+ prop = RNA_def_property(srna, "use_pass_volume_transmittance", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(
+ prop, NULL, "render_passes", EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE);
+ RNA_def_property_ui_text(prop, "Volume Transmittance", "Deliver volume transmittance pass");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
+
+ prop = RNA_def_property(srna, "use_pass_bloom", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "render_passes", EEVEE_RENDER_PASS_BLOOM);
+ RNA_def_property_ui_text(prop, "Bloom", "Deliver bloom pass");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
+}
+
void rna_def_view_layer_common(StructRNA *srna, const bool scene)
{
PropertyRNA *prop;
@@ -3801,6 +3824,11 @@ void rna_def_view_layer_common(StructRNA *srna, const bool scene)
"Z, Index, normal, UV and vector passes are only affected by surfaces with "
"alpha transparency equal to or higher than this threshold");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "eevee", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "ViewLayerEEVEE");
+ RNA_def_property_ui_text(prop, "EEVEE Settings", "View layer settings for EEVEE");
}
/* layer options */
@@ -4841,11 +4869,6 @@ static void rna_def_bake_data(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Transmission", "Add transmission contribution");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
- prop = RNA_def_property(srna, "use_pass_subsurface", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "pass_filter", R_BAKE_PASS_FILTER_SUBSURFACE);
- RNA_def_property_ui_text(prop, "Subsurface", "Add subsurface contribution");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
prop = RNA_def_property(srna, "pass_filter", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "pass_filter");
RNA_def_property_enum_items(prop, rna_enum_bake_pass_filter_type_items);
@@ -7546,6 +7569,7 @@ void RNA_def_scene(BlenderRNA *brna)
rna_def_display_safe_areas(brna);
rna_def_scene_display(brna);
rna_def_scene_eevee(brna);
+ rna_def_view_layer_eevee(brna);
RNA_define_animate_sdna(true);
/* *** Animated *** */
rna_def_scene_render_data(brna);
diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c
index b0304b742df..89f65da335a 100644
--- a/source/blender/makesrna/intern/rna_screen.c
+++ b/source/blender/makesrna/intern/rna_screen.c
@@ -80,7 +80,7 @@ static void rna_Screen_redraw_update(Main *UNUSED(bmain), Scene *UNUSED(scene),
/* the settings for this are currently only available from a menu in the TimeLine,
* hence refresh=SPACE_ACTION, as timeline is now in there
*/
- ED_screen_animation_timer_update(screen, screen->redraws_flag, SPACE_ACTION);
+ ED_screen_animation_timer_update(screen, screen->redraws_flag);
}
static bool rna_Screen_is_animation_playing_get(PointerRNA *UNUSED(ptr))
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index fdea081d8f1..3d5d5091bf1 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -382,14 +382,32 @@ static const EnumPropertyItem rna_enum_studio_light_items[] = {
};
static const EnumPropertyItem rna_enum_view3dshading_render_pass_type_items[] = {
- {SCE_PASS_COMBINED, "COMBINED", 0, "Combined", ""},
- /* {SCE_PASS_Z, "Z", 0, "Z", ""},*/
- {SCE_PASS_AO, "AO", 0, "Ambient Occlusion", ""},
- {SCE_PASS_NORMAL, "NORMAL", 0, "Normal", ""},
- {SCE_PASS_MIST, "MIST", 0, "Mist", ""},
- {SCE_PASS_SUBSURFACE_DIRECT, "SUBSURFACE_DIRECT", 0, "Subsurface Direct", ""},
- /* {SCE_PASS_SUBSURFACE_INDIRECT, "SUBSURFACE_INDIRECT", 0, "Subsurface Indirect", ""}, */
- {SCE_PASS_SUBSURFACE_COLOR, "SUBSURFACE_COLOR", 0, "Subsurface Color", ""},
+ {0, "", ICON_NONE, "General", ""},
+ {EEVEE_RENDER_PASS_COMBINED, "COMBINED", 0, "Combined", ""},
+ {EEVEE_RENDER_PASS_EMIT, "EMISSION", 0, "Emission", ""},
+ {EEVEE_RENDER_PASS_ENVIRONMENT, "ENVIRONMENT", 0, "Environment", ""},
+ {EEVEE_RENDER_PASS_AO, "AO", 0, "Ambient Occlusion", ""},
+ {EEVEE_RENDER_PASS_SHADOW, "SHADOW", 0, "Shadow", ""},
+
+ {0, "", ICON_NONE, "Light", ""},
+ {EEVEE_RENDER_PASS_DIFFUSE_LIGHT, "DIFFUSE_LIGHT", 0, "Diffuse Light", ""},
+ {EEVEE_RENDER_PASS_DIFFUSE_COLOR, "DIFFUSE_COLOR", 0, "Diffuse Color", ""},
+ {EEVEE_RENDER_PASS_SPECULAR_LIGHT, "SPECULAR_LIGHT", 0, "Specular Light", ""},
+ {EEVEE_RENDER_PASS_SPECULAR_COLOR, "SPECULAR_COLOR", 0, "Specular Color", ""},
+ {EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE,
+ "VOLUME_TRANSMITTANCE",
+ 0,
+ "Volume Transmittance",
+ ""},
+ {EEVEE_RENDER_PASS_VOLUME_SCATTER, "VOLUME_SCATTER", 0, "Volume Scattering", ""},
+
+ {0, "", ICON_NONE, "Effects", ""},
+ {EEVEE_RENDER_PASS_BLOOM, "BLOOM", 0, "Bloom", ""},
+
+ {0, "", ICON_NONE, "Data", ""},
+ {EEVEE_RENDER_PASS_NORMAL, "NORMAL", 0, "Normal", ""},
+ {EEVEE_RENDER_PASS_MIST, "MIST", 0, "Mist", ""},
+
{0, NULL, 0, NULL, NULL},
};
@@ -1242,6 +1260,30 @@ static const EnumPropertyItem *rna_View3DShading_studio_light_itemf(bContext *UN
return item;
}
+static const EnumPropertyItem *rna_3DViewShading_render_pass_itemf(bContext *C,
+ PointerRNA *UNUSED(ptr),
+ PropertyRNA *UNUSED(prop),
+ bool *r_free)
+{
+ Scene *scene = CTX_data_scene(C);
+
+ const bool ao_enabled = scene->eevee.flag & SCE_EEVEE_GTAO_ENABLED;
+ const bool bloom_enabled = scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED;
+
+ int totitem = 0;
+ EnumPropertyItem *result = NULL;
+ for (int i = 0; rna_enum_view3dshading_render_pass_type_items[i].identifier != NULL; i++) {
+ const EnumPropertyItem *item = &rna_enum_view3dshading_render_pass_type_items[i];
+ if (!((!ao_enabled && item->value == EEVEE_RENDER_PASS_AO) ||
+ (!bloom_enabled &&
+ (item->value == EEVEE_RENDER_PASS_BLOOM || STREQ(item->name, "Effects"))))) {
+ RNA_enum_item_add(&result, &totitem, item);
+ }
+ }
+ *r_free = true;
+ return result;
+}
+
static void rna_SpaceView3D_use_local_collections_update(bContext *C, PointerRNA *ptr)
{
Main *bmain = CTX_data_main(C);
@@ -3197,9 +3239,18 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
prop = RNA_def_property(srna, "studiolight_background_alpha", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "studiolight_background");
- RNA_def_property_ui_text(prop, "Background", "Show the studiolight in the background");
+ RNA_def_property_ui_text(prop, "World Opacity", "Show the studiolight in the background");
RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_ui_range(prop, 0.00f, 1.0f, 1, 3);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1, 3);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "studiolight_background_blur", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "studiolight_blur");
+ RNA_def_property_ui_text(prop, "Blur", "Blur the studiolight in the background");
+ RNA_def_property_float_default(prop, 0.5f);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1, 2);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
@@ -3328,6 +3379,7 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "render_pass");
RNA_def_property_enum_items(prop, rna_enum_view3dshading_render_pass_type_items);
RNA_def_property_ui_text(prop, "Render Pass", "Render Pass to show in the viewport");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_3DViewShading_render_pass_itemf");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
}
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 418fcfaf5f4..34f4fd45b9c 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -2338,6 +2338,16 @@ static void rna_def_userdef_theme_space_graph(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Scrubbing/Markers Region", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+ prop = RNA_def_property(srna, "time_marker_line", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Marker Line", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
+ prop = RNA_def_property(srna, "time_marker_line_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Marker Line Selected", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
prop = RNA_def_property(srna, "window_sliders", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "shade1");
RNA_def_property_array(prop, 3);
@@ -3074,6 +3084,17 @@ static void rna_def_userdef_theme_space_seq(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Scrubbing/Markers Region", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+ prop = RNA_def_property(srna, "time_marker_line", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Marker Line", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
+ prop = RNA_def_property(srna, "time_marker_line_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Marker Line Selected", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
+
prop = RNA_def_property(srna, "keyframe", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "vertex_select");
RNA_def_property_array(prop, 3);
@@ -3142,6 +3163,17 @@ static void rna_def_userdef_theme_space_action(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Scrubbing/Markers Region", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+ prop = RNA_def_property(srna, "time_marker_line", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Marker Line", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
+ prop = RNA_def_property(srna, "time_marker_line_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Marker Line Selected", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
+
prop = RNA_def_property(srna, "value_sliders", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "face");
RNA_def_property_array(prop, 3);
@@ -3451,6 +3483,17 @@ static void rna_def_userdef_theme_space_nla(BlenderRNA *brna)
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Scrubbing/Markers Region", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
+ prop = RNA_def_property(srna, "time_marker_line", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Marker Line", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
+ prop = RNA_def_property(srna, "time_marker_line_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Marker Line Selected", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
}
static void rna_def_userdef_theme_colorset(BlenderRNA *brna)
@@ -3571,6 +3614,17 @@ static void rna_def_userdef_theme_space_clip(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Scrubbing/Markers Region", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+ prop = RNA_def_property(srna, "time_marker_line", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Marker Line", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
+ prop = RNA_def_property(srna, "time_marker_line_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Marker Line Selected", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
+
prop = RNA_def_property(srna, "strips", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "strip");
RNA_def_property_array(prop, 3);
diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c
index 89349d91f94..93f2ba44a3a 100644
--- a/source/blender/nodes/composite/node_composite_tree.c
+++ b/source/blender/nodes/composite/node_composite_tree.c
@@ -281,8 +281,11 @@ void ntreeCompositUpdateRLayers(bNodeTree *ntree)
}
}
-void ntreeCompositRegisterPass(
- bNodeTree *ntree, Scene *scene, ViewLayer *view_layer, const char *name, int type)
+void ntreeCompositRegisterPass(bNodeTree *ntree,
+ Scene *scene,
+ ViewLayer *view_layer,
+ const char *name,
+ eNodeSocketDatatype type)
{
bNode *node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c
index b74f325a3fa..f8a97868959 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.c
+++ b/source/blender/nodes/composite/nodes/node_composite_image.c
@@ -72,13 +72,14 @@ static bNodeSocketTemplate cmp_node_rlayers_out[] = {
{SOCK_RGBA, 0, N_(RE_PASSNAME_SUBSURFACE_COLOR), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{-1, 0, ""},
};
+#define MAX_LEGACY_SOCKET_INDEX 30
static void cmp_node_image_add_pass_output(bNodeTree *ntree,
bNode *node,
const char *name,
const char *passname,
int rres_index,
- int type,
+ eNodeSocketDatatype type,
int is_rlayers,
LinkNodePair *available_sockets,
int *prev_index)
@@ -94,8 +95,8 @@ static void cmp_node_image_add_pass_output(bNodeTree *ntree,
* New sockets are placed behind the previously traversed one,
* but always after the first 31. */
int after_index = *prev_index;
- if (is_rlayers && after_index < 30) {
- after_index = 30;
+ if (is_rlayers && after_index < MAX_LEGACY_SOCKET_INDEX) {
+ after_index = MAX_LEGACY_SOCKET_INDEX;
}
if (rres_index >= 0) {
@@ -238,8 +239,12 @@ typedef struct RLayerUpdateData {
int prev_index;
} RLayerUpdateData;
-void node_cmp_rlayers_register_pass(
- bNodeTree *ntree, bNode *node, Scene *scene, ViewLayer *view_layer, const char *name, int type)
+void node_cmp_rlayers_register_pass(bNodeTree *ntree,
+ bNode *node,
+ Scene *scene,
+ ViewLayer *view_layer,
+ const char *name,
+ eNodeSocketDatatype type)
{
RLayerUpdateData *data = node->storage;
@@ -389,7 +394,7 @@ static void cmp_node_image_verify_outputs(bNodeTree *ntree, bNode *node, bool rl
break;
}
}
- if (!link && (!rlayer || sock_index > 30)) {
+ if (!link && (!rlayer || sock_index > MAX_LEGACY_SOCKET_INDEX)) {
MEM_freeN(sock->storage);
nodeRemoveSocket(ntree, node, sock);
}
@@ -508,7 +513,7 @@ const char *node_cmp_rlayers_sock_to_pass(int sock_index)
RE_PASSNAME_SUBSURFACE_INDIRECT,
RE_PASSNAME_SUBSURFACE_COLOR,
};
- if (sock_index > 30) {
+ if (sock_index > MAX_LEGACY_SOCKET_INDEX) {
return NULL;
}
return sock_to_passname[sock_index];
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.c b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.c
index 3fd627cd886..bee5377c438 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.c
@@ -48,11 +48,6 @@ static int gpu_shader_vector_rotate(GPUMaterial *mat,
[NODE_VECTOR_ROTATE_TYPE_AXIS_Y] = "node_vector_rotate_axis_y",
[NODE_VECTOR_ROTATE_TYPE_AXIS_Z] = "node_vector_rotate_axis_z",
[NODE_VECTOR_ROTATE_TYPE_EULER_XYZ] = "node_vector_rotate_euler_xyz",
- [NODE_VECTOR_ROTATE_TYPE_EULER_XZY] = "node_vector_rotate_euler_xzy",
- [NODE_VECTOR_ROTATE_TYPE_EULER_YXZ] = "node_vector_rotate_euler_yxz",
- [NODE_VECTOR_ROTATE_TYPE_EULER_YZX] = "node_vector_rotate_euler_yzx",
- [NODE_VECTOR_ROTATE_TYPE_EULER_ZXY] = "node_vector_rotate_euler_zxy",
- [NODE_VECTOR_ROTATE_TYPE_EULER_ZYX] = "node_vector_rotate_euler_zyx",
};
if (node->custom1 < ARRAY_SIZE(names) && names[node->custom1]) {
@@ -66,21 +61,11 @@ static int gpu_shader_vector_rotate(GPUMaterial *mat,
static void node_shader_update_vector_rotate(bNodeTree *UNUSED(ntree), bNode *node)
{
bNodeSocket *sock_rotation = nodeFindSocket(node, SOCK_IN, "Rotation");
- nodeSetSocketAvailability(sock_rotation,
- !ELEM(node->custom1,
- NODE_VECTOR_ROTATE_TYPE_AXIS,
- NODE_VECTOR_ROTATE_TYPE_AXIS_X,
- NODE_VECTOR_ROTATE_TYPE_AXIS_Y,
- NODE_VECTOR_ROTATE_TYPE_AXIS_Z));
+ nodeSetSocketAvailability(sock_rotation, ELEM(node->custom1, NODE_VECTOR_ROTATE_TYPE_EULER_XYZ));
bNodeSocket *sock_axis = nodeFindSocket(node, SOCK_IN, "Axis");
nodeSetSocketAvailability(sock_axis, ELEM(node->custom1, NODE_VECTOR_ROTATE_TYPE_AXIS));
bNodeSocket *sock_angle = nodeFindSocket(node, SOCK_IN, "Angle");
- nodeSetSocketAvailability(sock_angle,
- ELEM(node->custom1,
- NODE_VECTOR_ROTATE_TYPE_AXIS,
- NODE_VECTOR_ROTATE_TYPE_AXIS_X,
- NODE_VECTOR_ROTATE_TYPE_AXIS_Y,
- NODE_VECTOR_ROTATE_TYPE_AXIS_Z));
+ nodeSetSocketAvailability(sock_angle, !ELEM(node->custom1, NODE_VECTOR_ROTATE_TYPE_EULER_XYZ));
}
void register_node_type_sh_vector_rotate(void)
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index a92be8509d5..a1dd9b3d5b0 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -86,10 +86,6 @@ if(WITH_IMAGE_OPENEXR)
add_definitions(-DWITH_OPENEXR)
endif()
-if(WITH_MOD_FLUID)
- add_definitions(-DWITH_FLUID)
-endif()
-
if(WITH_FREESTYLE)
list(APPEND INC
../freestyle
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index 12e9123b5cb..88614de1641 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -26,6 +26,7 @@
#include "DNA_listBase.h"
#include "DNA_scene_types.h"
+#include "DNA_node_types.h"
#include "RNA_types.h"
#include "RE_bake.h"
@@ -117,7 +118,7 @@ typedef void (*update_render_passes_cb_t)(void *userdata,
const char *name,
int channels,
const char *chanid,
- int type);
+ eNodeSocketDatatype type);
typedef struct RenderEngine {
RenderEngineType *type;
@@ -212,7 +213,7 @@ void RE_engine_register_pass(struct RenderEngine *engine,
const char *name,
int channels,
const char *chanid,
- int type);
+ eNodeSocketDatatype type);
/* Engine Types */
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 90058da5f0c..598f300cf86 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -863,7 +863,7 @@ void RE_engine_register_pass(struct RenderEngine *engine,
const char *name,
int channels,
const char *chanid,
- int type)
+ eNodeSocketDatatype type)
{
if (!(scene && view_layer && engine && engine->update_render_passes_cb)) {
return;
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index 120787a8d13..b2225d70eaf 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -442,6 +442,15 @@ RenderResult *render_result_new(Render *re,
if (view_layer->passflag & SCE_PASS_SUBSURFACE_COLOR) {
RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_COLOR, view, "RGB");
}
+ if (view_layer->eevee.render_passes & EEVEE_RENDER_PASS_BLOOM) {
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_BLOOM, view, "RGB");
+ }
+ if (view_layer->eevee.render_passes & EEVEE_RENDER_PASS_VOLUME_SCATTER) {
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_VOLUME_SCATTER, view, "RGB");
+ }
+ if (view_layer->eevee.render_passes & EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE) {
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_VOLUME_TRANSMITTANCE, view, "RGB");
+ }
#undef RENDER_LAYER_ADD_PASS_SAFE
}
}
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index eff5464c885..1775d9064d9 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -2808,7 +2808,7 @@ static uiBlock *block_create_autorun_warning(struct bContext *C,
void *UNUSED(arg1))
{
wmWindowManager *wm = CTX_wm_manager(C);
- uiStyle *style = UI_style_get();
+ uiStyle *style = UI_style_get_dpi();
uiBlock *block = UI_block_begin(C, ar, "autorun_warning_popup", UI_EMBOSS);
UI_block_flag_enable(
@@ -3067,6 +3067,7 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, struct ARegi
/* Create dialog */
uiBlock *block = UI_block_begin(C, ar, close_file_dialog_name, UI_EMBOSS);
+ style = UI_style_get_dpi();
UI_block_flag_enable(
block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_LOOP | UI_BLOCK_NO_WIN_CLIP | UI_BLOCK_NUMSELECT);
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 6e5068aa6b4..bc519055af3 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -1319,7 +1319,7 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
wmOperator *op = arg_op;
uiBlock *block;
uiLayout *layout;
- uiStyle *style = UI_style_get();
+ uiStyle *style = UI_style_get_dpi();
int width = 15 * UI_UNIT_X;
block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
@@ -1401,7 +1401,7 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData)
wmOperator *op = data->op;
uiBlock *block;
uiLayout *layout;
- uiStyle *style = UI_style_get();
+ uiStyle *style = UI_style_get_dpi();
block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
UI_block_flag_disable(block, UI_BLOCK_LOOP);
@@ -1450,7 +1450,7 @@ static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData)
wmOperator *op = data->op;
uiBlock *block;
uiLayout *layout;
- uiStyle *style = UI_style_get();
+ uiStyle *style = UI_style_get_dpi();
block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
UI_block_flag_disable(block, UI_BLOCK_LOOP);
diff --git a/source/blender/windowmanager/intern/wm_splash_screen.c b/source/blender/windowmanager/intern/wm_splash_screen.c
index 3603ce81654..7f6eebb95ab 100644
--- a/source/blender/windowmanager/intern/wm_splash_screen.c
+++ b/source/blender/windowmanager/intern/wm_splash_screen.c
@@ -259,7 +259,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
{
uiBlock *block;
uiBut *but;
- uiStyle *style = UI_style_get();
+ uiStyle *style = UI_style_get_dpi();
block = UI_block_begin(C, ar, "splash", UI_EMBOSS);
diff --git a/source/blender/windowmanager/intern/wm_toolsystem.c b/source/blender/windowmanager/intern/wm_toolsystem.c
index 616cb7613ba..e335800636c 100644
--- a/source/blender/windowmanager/intern/wm_toolsystem.c
+++ b/source/blender/windowmanager/intern/wm_toolsystem.c
@@ -374,6 +374,15 @@ void WM_toolsystem_ref_set_from_runtime(struct bContext *C,
toolsystem_refresh_screen_from_active_tool(bmain, workspace, tref);
+ /* Set the cursor if possible, if not - it's fine as entering the region will refresh it. */
+ {
+ wmWindow *win = CTX_wm_window(C);
+ if (win != NULL) {
+ win->addmousemove = true;
+ win->tag_cursor_refresh = true;
+ }
+ }
+
{
struct wmMsgBus *mbus = CTX_wm_message_bus(C);
WM_msg_publish_rna_prop(mbus, &workspace->id, workspace, WorkSpace, tools);
diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt
index 358200dece4..c47c7a5b4fc 100644
--- a/tests/python/CMakeLists.txt
+++ b/tests/python/CMakeLists.txt
@@ -183,6 +183,13 @@ add_blender_test(
--run-all-tests
)
+add_blender_test(
+ constraints
+ --python ${CMAKE_CURRENT_LIST_DIR}/bl_constraints.py
+ --
+ --testdir "${TEST_SRC_DIR}/constraints"
+)
+
# ------------------------------------------------------------------------------
# OPERATORS TESTS
add_blender_test(
diff --git a/tests/python/bl_constraints.py b/tests/python/bl_constraints.py
new file mode 100644
index 00000000000..2a48ffe35ea
--- /dev/null
+++ b/tests/python/bl_constraints.py
@@ -0,0 +1,204 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# 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.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+"""
+./blender.bin --background -noaudio --factory-startup --python tests/python/bl_constraints.py -- --testdir /path/to/lib/tests/constraints
+"""
+
+import pathlib
+import sys
+import unittest
+
+import bpy
+from mathutils import Matrix
+
+
+class AbstractConstraintTests(unittest.TestCase):
+ """Useful functionality for constraint tests."""
+
+ def setUp(self):
+ bpy.ops.wm.open_mainfile(filepath=str(args.testdir / "constraints.blend"))
+
+ def assert_matrix(self, actual_matrix, expect_matrix, object_name: str, places=6, delta=None):
+ """Asserts that the matrices almost equal."""
+ self.assertEqual(len(actual_matrix), 4, 'Expected a 4x4 matrix')
+
+ # TODO(Sybren): decompose the matrices and compare loc, rot, and scale separately.
+ # That'll probably improve readability & understandability of test failures.
+ for row, (act_row, exp_row) in enumerate(zip(actual_matrix, expect_matrix)):
+ for col, (actual, expect) in enumerate(zip(act_row, exp_row)):
+ self.assertAlmostEqual(
+ actual, expect, places=places, delta=delta,
+ msg=f'Matrix of object {object_name!r} failed: {actual} != {expect} at element [{row}][{col}]')
+
+ def matrix(self, object_name: str) -> Matrix:
+ """Return the evaluated world matrix."""
+ depsgraph = bpy.context.view_layer.depsgraph
+ depsgraph.update()
+ ob_orig = bpy.context.scene.objects[object_name]
+ ob_eval = ob_orig.evaluated_get(depsgraph)
+ return ob_eval.matrix_world
+
+ def matrix_test(self, object_name: str, expect: Matrix):
+ """Assert that the object's world matrix is as expected."""
+ actual = self.matrix(object_name)
+ self.assert_matrix(actual, expect, object_name)
+
+ def constraint_context(self, constraint_name: str, owner_name: str='') -> dict:
+ """Return a context suitable for calling constraint operators.
+
+ Assumes the owner is called "{constraint_name}.owner" if owner_name=''.
+ """
+ owner = bpy.context.scene.objects[owner_name or f'{constraint_name}.owner']
+ constraint = owner.constraints[constraint_name]
+ context = {
+ **bpy.context.copy(),
+ 'object': owner,
+ 'active_object': owner,
+ 'constraint': constraint,
+ }
+ return context
+
+
+class ChildOfTest(AbstractConstraintTests):
+ def test_object_simple_parent(self):
+ """Child Of: simple evaluation of object parent."""
+ initial_matrix = Matrix((
+ (0.5872668623924255, -0.3642929494380951, 0.29567837715148926, 1.0886117219924927),
+ (0.31689348816871643, 0.7095895409584045, 0.05480116978287697, 2.178966999053955),
+ (-0.21244174242019653, 0.06738340109586716, 0.8475662469863892, 3.2520291805267334),
+ (0.0, 0.0, 0.0, 1.0),
+ ))
+ self.matrix_test('Child Of.object.owner', initial_matrix)
+
+ context = self.constraint_context('Child Of', owner_name='Child Of.object.owner')
+ bpy.ops.constraint.childof_set_inverse(context, constraint='Child Of')
+ self.matrix_test('Child Of.object.owner', Matrix((
+ (0.9992385506629944, 0.019844001159071922, -0.03359175845980644, 0.10000011324882507),
+ (-0.01744179055094719, 0.997369647026062, 0.07035345584154129, 0.1999998837709427),
+ (0.034899525344371796, -0.06971397250890732, 0.9969563484191895, 0.3000001311302185),
+ (0.0, 0.0, 0.0, 1.0),
+ )))
+
+ bpy.ops.constraint.childof_clear_inverse(context, constraint='Child Of')
+ self.matrix_test('Child Of.object.owner', initial_matrix)
+
+ def test_object_rotation_only(self):
+ """Child Of: rotation only."""
+ owner = bpy.context.scene.objects['Child Of.object.owner']
+ constraint = owner.constraints['Child Of']
+ constraint.use_location_x = constraint.use_location_y = constraint.use_location_z = False
+ constraint.use_scale_x = constraint.use_scale_y = constraint.use_scale_z = False
+
+ initial_matrix = Matrix((
+ (0.8340795636177063, -0.4500490725040436, 0.31900957226753235, 0.10000000149011612),
+ (0.4547243118286133, 0.8883093595504761, 0.06428192555904388, 0.20000000298023224),
+ (-0.31230923533439636, 0.09144517779350281, 0.9455690383911133, 0.30000001192092896),
+ (0.0, 0.0, 0.0, 1.0),
+ ))
+ self.matrix_test('Child Of.object.owner', initial_matrix)
+
+ context = self.constraint_context('Child Of', owner_name='Child Of.object.owner')
+ bpy.ops.constraint.childof_set_inverse(context, constraint='Child Of')
+ self.matrix_test('Child Of.object.owner', Matrix((
+ (0.9992386102676392, 0.019843975082039833, -0.033591702580451965, 0.10000000149011612),
+ (-0.017441781237721443, 0.9973695874214172, 0.0703534483909607, 0.20000000298023224),
+ (0.03489946573972702, -0.06971397250890732, 0.9969563484191895, 0.30000001192092896),
+ (0.0, 0.0, 0.0, 1.0),
+ )))
+
+ bpy.ops.constraint.childof_clear_inverse(context, constraint='Child Of')
+ self.matrix_test('Child Of.object.owner', initial_matrix)
+
+ def test_object_no_x_axis(self):
+ """Child Of: loc/rot/scale on only Y and Z axes."""
+ owner = bpy.context.scene.objects['Child Of.object.owner']
+ constraint = owner.constraints['Child Of']
+ constraint.use_location_x = False
+ constraint.use_rotation_x = False
+ constraint.use_scale_x = False
+
+ initial_matrix = Matrix((
+ (0.8294582366943359, -0.4013831615447998, 0.2102886438369751, 0.10000000149011612),
+ (0.46277597546577454, 0.6895919442176819, 0.18639995157718658, 2.2317214012145996),
+ (-0.31224438548088074, -0.06574578583240509, 0.8546382784843445, 3.219514846801758),
+ (0.0, 0.0, 0.0, 1.0),
+ ))
+ self.matrix_test('Child Of.object.owner', initial_matrix)
+
+ context = self.constraint_context('Child Of', owner_name='Child Of.object.owner')
+ bpy.ops.constraint.childof_set_inverse(context, constraint='Child Of')
+ self.matrix_test('Child Of.object.owner', Matrix((
+ (0.9228900671005249, 0.23250490427017212, -0.035540513694286346, 0.10000000149011612),
+ (-0.011224273592233658, 0.9838480949401855, 0.24731633067131042, 0.21246682107448578),
+ (0.0383986234664917, -0.3163823187351227, 0.9553266167640686, 0.27248233556747437),
+ (0.0, 0.0, 0.0, 1.0),
+ )))
+
+ bpy.ops.constraint.childof_clear_inverse(context, constraint='Child Of')
+ self.matrix_test('Child Of.object.owner', initial_matrix)
+
+ def test_bone_simple_parent(self):
+ """Child Of: simple evaluation of bone parent."""
+ initial_matrix = Matrix((
+ (0.5133683681488037, -0.06418320536613464, -0.014910104684531689, -0.2277737855911255),
+ (-0.03355155512690544, 0.12542974948883057, -1.080492377281189, 2.082599639892578),
+ (0.019313642755150795, 1.0446348190307617, 0.1244703009724617, 2.8542778491973877),
+ (0.0, 0.0, 0.0, 1.0),
+ ))
+ self.matrix_test('Child Of.armature.owner', initial_matrix)
+
+ context = self.constraint_context('Child Of', owner_name='Child Of.armature.owner')
+ bpy.ops.constraint.childof_set_inverse(context, constraint='Child Of')
+
+ self.matrix_test('Child Of.armature.owner', Matrix((
+ (0.9992386102676392, 0.019843988120555878, -0.03359176218509674, 0.8358089923858643),
+ (-0.017441775649785995, 0.997369647026062, 0.0703534483909607, 1.7178752422332764),
+ (0.03489949554204941, -0.06971397995948792, 0.9969563484191895, -1.8132872581481934),
+ (0.0, 0.0, 0.0, 1.0),
+ )))
+
+ bpy.ops.constraint.childof_clear_inverse(context, constraint='Child Of')
+ self.matrix_test('Child Of.armature.owner', initial_matrix)
+
+def main():
+ global args
+ import argparse
+
+ if '--' in sys.argv:
+ argv = [sys.argv[0]] + sys.argv[sys.argv.index('--') + 1:]
+ else:
+ argv = sys.argv
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--testdir', required=True, type=pathlib.Path)
+ args, remaining = parser.parse_known_args(argv)
+
+ unittest.main(argv=remaining)
+
+
+if __name__ == "__main__":
+ import traceback
+ # So a python error exits Blender itself too
+ try:
+ main()
+ except SystemExit:
+ raise
+ except:
+ traceback.print_exc()
+ sys.exit(1)