WIP: Brush assets project #106303

Draft
Julian Eisel wants to merge 354 commits from brush-assets-project into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
16 changed files with 204 additions and 67 deletions
Showing only changes of commit 7ac21ae357 - Show all commits

View File

@ -737,7 +737,7 @@ PACKAGES_ALL = (
DISTRO_ID_ARCH: "intel-oneapi-tbb",
},
),
Package(name="OpenColorIO Library", is_mandatory=False, version="2.3.0", version_short="2.3", version_min="2.0", version_mex="3.0",
Package(name="OpenColorIO Library", is_mandatory=False, version="2.3.2", version_short="2.3", version_min="2.0", version_mex="3.0",
sub_packages=(),
distro_package_names={DISTRO_ID_DEBIAN: "libopencolorio-dev",
DISTRO_ID_FEDORA: "OpenColorIO-devel",
@ -883,7 +883,7 @@ PACKAGES_ALL = (
DISTRO_ID_ARCH: "embree",
},
),
Package(name="OpenImageDenoiser Library", is_mandatory=False, version="2.1.0", version_short="2.1", version_min="2.0.0", version_mex="3.0",
Package(name="OpenImageDenoiser Library", is_mandatory=False, version="2.2.0", version_short="2.2", version_min="2.0.0", version_mex="3.0",
sub_packages=(),
distro_package_names={DISTRO_ID_DEBIAN: None,
DISTRO_ID_FEDORA: "oidn-devel",
@ -891,7 +891,7 @@ PACKAGES_ALL = (
DISTRO_ID_ARCH: "openimagedenoise",
},
),
Package(name="Level Zero Library", is_mandatory=False, version="1.8.8", version_short="1.8", version_min="1.7", version_mex="2.0",
Package(name="Level Zero Library", is_mandatory=False, version="1.15.8", version_short="1.15", version_min="1.7", version_mex="2.0",
sub_packages=(),
distro_package_names={DISTRO_ID_DEBIAN: None,
DISTRO_ID_FEDORA: "oneapi-level-zero-devel",

View File

@ -65,8 +65,6 @@ class AssetLibrary {
*/
std::unique_ptr<AssetStorage> asset_storage_;
std::function<void(AssetLibrary &self)> on_refresh_;
std::optional<eAssetImportMethod> import_method_;
/** Assets owned by this library may be imported with a different method than set in
* #import_method_ above, it's just a default. */
@ -95,7 +93,7 @@ class AssetLibrary {
* \param root_path: If this is an asset library on disk, the top-level directory path.
*/
AssetLibrary(eAssetLibraryType library_type, StringRef name = "", StringRef root_path = "");
~AssetLibrary();
virtual ~AssetLibrary();
/**
* Execute \a fn for every asset library that is loaded. The asset library is passed to the
@ -112,9 +110,6 @@ class AssetLibrary {
void load_catalogs();
/** Load catalogs that have changed on disk. */
void refresh();
/**
* Create a representation of an asset to be considered part of this library. Once the
* representation is not needed anymore, it must be freed using #remove_asset(), or there will be
@ -172,6 +167,10 @@ class AssetLibrary {
eAssetLibraryType library_type() const;
StringRefNull name() const;
StringRefNull root_path() const;
protected:
/** Load catalogs that have changed on disk. */
virtual void refresh_catalogs();
};
Vector<AssetLibraryReference> all_valid_asset_library_refs();

View File

@ -18,6 +18,9 @@ set(SRC
intern/asset_essentials_library.cc
intern/asset_identifier.cc
intern/asset_library.cc
intern/asset_library_all.cc
intern/asset_library_on_disk.cc
intern/asset_library_runtime.cc
intern/asset_library_service.cc
intern/asset_representation.cc
intern/asset_storage.cc
@ -30,6 +33,9 @@ set(SRC
AS_asset_library.hh
AS_asset_representation.hh
AS_essentials_library.hh
intern/asset_library_all.hh
intern/asset_library_on_disk.hh
intern/asset_library_runtime.hh
intern/asset_library_service.hh
intern/asset_storage.hh
intern/utils.hh

View File

@ -216,12 +216,7 @@ void AssetLibrary::load_catalogs()
this->catalog_service = std::move(catalog_service);
}
void AssetLibrary::refresh()
{
if (on_refresh_) {
on_refresh_(*this);
}
}
void AssetLibrary::refresh_catalogs() {}
AssetRepresentation &AssetLibrary::add_external_asset(StringRef relative_asset_path,
StringRef name,

View File

@ -0,0 +1,40 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system
*/
#include <memory>
#include "AS_asset_catalog_tree.hh"
#include "asset_library_all.hh"
namespace blender::asset_system {
AllAssetLibrary::AllAssetLibrary() : AssetLibrary(ASSET_LIBRARY_ALL) {}
void AllAssetLibrary::rebuild(const bool reload_catalogs)
{
/* Start with empty catalog storage. */
catalog_service = std::make_unique<AssetCatalogService>(AssetCatalogService::read_only_tag());
AssetLibrary::foreach_loaded(
[&](AssetLibrary &nested) {
if (reload_catalogs) {
nested.catalog_service->reload_catalogs();
}
catalog_service->add_from_existing(*nested.catalog_service);
},
false);
catalog_service->rebuild_tree();
}
void AllAssetLibrary::refresh_catalogs()
{
rebuild(/*reload_catalogs=*/true);
}
} // namespace blender::asset_system

View File

@ -0,0 +1,24 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system
*/
#pragma once
#include "AS_asset_library.hh"
namespace blender::asset_system {
class AllAssetLibrary : public AssetLibrary {
public:
AllAssetLibrary();
void refresh_catalogs() override;
void rebuild(const bool reload_catalogs);
};
} // namespace blender::asset_system

View File

@ -0,0 +1,26 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system
*/
#include "asset_library_on_disk.hh"
namespace blender::asset_system {
OnDiskAssetLibrary::OnDiskAssetLibrary(eAssetLibraryType library_type,
StringRef name,
StringRef root_path)
: AssetLibrary(library_type, name, root_path)
{
on_blend_save_handler_register();
}
void OnDiskAssetLibrary::refresh_catalogs()
{
catalog_service->reload_catalogs();
}
} // namespace blender::asset_system

View File

@ -0,0 +1,24 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system
*/
#pragma once
#include "AS_asset_library.hh"
namespace blender::asset_system {
class OnDiskAssetLibrary : public AssetLibrary {
public:
OnDiskAssetLibrary(eAssetLibraryType library_type,
StringRef name = "",
StringRef root_path = "");
void refresh_catalogs() override;
};
} // namespace blender::asset_system

View File

@ -0,0 +1,18 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system
*/
#include "asset_library_runtime.hh"
namespace blender::asset_system {
RuntimeAssetLibrary::RuntimeAssetLibrary() : AssetLibrary(ASSET_LIBRARY_LOCAL)
{
on_blend_save_handler_register();
}
} // namespace blender::asset_system

View File

@ -0,0 +1,23 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup asset_system
*
* An asset library that is purely stored in-memory. Used for the "Current File" asset library
* while the file has not been saved on disk yet.
*/
#pragma once
#include "AS_asset_library.hh"
namespace blender::asset_system {
class RuntimeAssetLibrary : public AssetLibrary {
public:
RuntimeAssetLibrary();
};
} // namespace blender::asset_system

View File

@ -17,9 +17,11 @@
#include "CLG_log.h"
#include "AS_asset_catalog_tree.hh"
#include "AS_asset_library.hh"
#include "AS_essentials_library.hh"
#include "asset_library_all.hh"
#include "asset_library_on_disk.hh"
#include "asset_library_runtime.hh"
#include "asset_library_service.hh"
#include "utils.hh"
@ -121,23 +123,20 @@ AssetLibrary *AssetLibraryService::get_asset_library_on_disk(eAssetLibraryType l
std::string normalized_root_path = utils::normalize_directory_path(root_path);
std::unique_ptr<AssetLibrary> *lib_uptr_ptr = on_disk_libraries_.lookup_ptr(
std::unique_ptr<OnDiskAssetLibrary> *lib_uptr_ptr = on_disk_libraries_.lookup_ptr(
{library_type, normalized_root_path});
if (lib_uptr_ptr != nullptr) {
CLOG_INFO(&LOG, 2, "get \"%s\" (cached)", normalized_root_path.c_str());
AssetLibrary *lib = lib_uptr_ptr->get();
lib->refresh();
lib->refresh_catalogs();
return lib;
}
std::unique_ptr lib_uptr = std::make_unique<AssetLibrary>(
std::unique_ptr lib_uptr = std::make_unique<OnDiskAssetLibrary>(
library_type, name, normalized_root_path);
AssetLibrary *lib = lib_uptr.get();
lib->on_blend_save_handler_register();
lib->load_catalogs();
/* Reload catalogs on refresh. */
lib->on_refresh_ = [](AssetLibrary &self) { self.catalog_service->reload_catalogs(); };
on_disk_libraries_.add_new({library_type, normalized_root_path}, std::move(lib_uptr));
CLOG_INFO(&LOG, 2, "get \"%s\" (loaded)", normalized_root_path.c_str());
@ -166,39 +165,21 @@ AssetLibrary *AssetLibraryService::get_asset_library_current_file()
{
if (current_file_library_) {
CLOG_INFO(&LOG, 2, "get current file lib (cached)");
current_file_library_->refresh();
current_file_library_->refresh_catalogs();
}
else {
CLOG_INFO(&LOG, 2, "get current file lib (loaded)");
current_file_library_ = std::make_unique<AssetLibrary>(ASSET_LIBRARY_LOCAL);
current_file_library_->on_blend_save_handler_register();
current_file_library_ = std::make_unique<RuntimeAssetLibrary>();
}
AssetLibrary *lib = current_file_library_.get();
return lib;
}
static void rebuild_all_library_ex(AssetLibrary &all_library, const bool reload_catalogs)
{
/* Start with empty catalog storage. */
all_library.catalog_service = std::make_unique<AssetCatalogService>(
AssetCatalogService::read_only_tag());
AssetLibrary::foreach_loaded(
[&](AssetLibrary &nested) {
if (reload_catalogs) {
nested.catalog_service->reload_catalogs();
}
all_library.catalog_service->add_from_existing(*nested.catalog_service);
},
false);
all_library.catalog_service->rebuild_tree();
}
void AssetLibraryService::rebuild_all_library()
{
if (all_library_) {
rebuild_all_library_ex(*all_library_, false);
all_library_->rebuild(false);
}
}
@ -217,19 +198,15 @@ AssetLibrary *AssetLibraryService::get_asset_library_all(const Main *bmain)
if (all_library_) {
CLOG_INFO(&LOG, 2, "get all lib (cached)");
all_library_->refresh();
all_library_->refresh_catalogs();
return all_library_.get();
}
CLOG_INFO(&LOG, 2, "get all lib (loaded)");
all_library_ = std::make_unique<AssetLibrary>(ASSET_LIBRARY_ALL);
all_library_ = std::make_unique<AllAssetLibrary>();
/* Don't reload catalogs on this initial read, they've just been loaded above. */
rebuild_all_library_ex(*all_library_, /*reload_catlogs=*/false);
all_library_->on_refresh_ = [](AssetLibrary &all_library) {
rebuild_all_library_ex(all_library, /*reload_catalogs=*/true);
};
all_library_->rebuild(/*reload_catalogs=*/false);
return all_library_.get();
}
@ -247,7 +224,7 @@ bUserAssetLibrary *AssetLibraryService::find_custom_preferences_asset_library_fr
AssetLibrary *AssetLibraryService::find_loaded_on_disk_asset_library_from_name(
StringRef name) const
{
for (const std::unique_ptr<AssetLibrary> &library : on_disk_libraries_.values()) {
for (const std::unique_ptr<OnDiskAssetLibrary> &library : on_disk_libraries_.values()) {
if (library->name_ == name) {
return library.get();
}

View File

@ -23,6 +23,10 @@ struct bUserAssetLibrary;
namespace blender::asset_system {
class AllAssetLibrary;
class OnDiskAssetLibrary;
class RuntimeAssetLibrary;
/**
* Global singleton-ish that provides access to individual #AssetLibrary instances.
*
@ -44,13 +48,13 @@ class AssetLibraryService {
* library may point to the same path as a custom library. */
using OnDiskLibraryIdentifier = std::pair<eAssetLibraryType, std::string>;
/* Mapping of a (type, root path) pair to the AssetLibrary instance. */
Map<OnDiskLibraryIdentifier, std::unique_ptr<AssetLibrary>> on_disk_libraries_;
Map<OnDiskLibraryIdentifier, std::unique_ptr<OnDiskAssetLibrary>> on_disk_libraries_;
/** Library without a known path, i.e. the "Current File" library if the file isn't saved yet. If
* the file was saved, a valid path for the library can be determined and #on_disk_libraries_
* above should be used. */
std::unique_ptr<AssetLibrary> current_file_library_;
std::unique_ptr<RuntimeAssetLibrary> current_file_library_;
/** The "all" asset library, merging all other libraries into one. */
std::unique_ptr<AssetLibrary> all_library_;
std::unique_ptr<AllAssetLibrary> all_library_;
/* Handlers for managing the life cycle of the AssetLibraryService instance. */
bCallbackFuncStore on_load_callback_store_;

View File

@ -522,12 +522,9 @@ void DeferredLayer::begin_sync()
void DeferredLayer::end_sync()
{
eClosureBits evaluated_closures = CLOSURE_DIFFUSE | CLOSURE_TRANSLUCENT | CLOSURE_REFLECTION |
CLOSURE_REFRACTION;
use_combined_lightprobe_eval = inst_.pipelines.data.use_combined_lightprobe_eval;
if (closure_bits_ & evaluated_closures) {
{
RenderBuffersInfoData &rbuf_data = inst_.render_buffers.data;
/* Add the stencil classification step at the end of the GBuffer pass. */

View File

@ -1277,6 +1277,9 @@ enum GBufferMode : uint32_t {
GBUF_REFRACTION = 4u,
GBUF_SUBSURFACE = 5u,
/** Used for surfaces that have no lit closure and just encode a normal layer. */
GBUF_UNLIT = 11u,
/** Parameter Optimized. Packs one closure into less layer. */
GBUF_REFLECTION_COLORLESS = 12u,
GBUF_REFRACTION_COLORLESS = 13u,

View File

@ -47,18 +47,13 @@ void main()
GBufferReader gbuf = gbuffer_read(gbuf_header_tx, gbuf_closure_tx, gbuf_normal_tx, texel);
/* TODO: use stencil buffer to avoid fragment invocations here. */
out_combined = vec4(0.0, 0.0, 0.0, 0.0);
if (gbuf.closure_count == 0) {
return;
}
vec3 diffuse_color = vec3(0.0);
vec3 diffuse_light = vec3(0.0);
vec3 specular_color = vec3(0.0);
vec3 specular_light = vec3(0.0);
vec3 average_normal = vec3(0.0);
out_combined = vec4(0.0, 0.0, 0.0, 0.0);
for (int i = 0; i < GBUFFER_LAYER_MAX && i < gbuf.closure_count; i++) {
vec3 closure_light = load_radiance_direct(texel, i);
ClosureUndetermined cl = gbuffer_closure_get(gbuf, i);

View File

@ -467,6 +467,14 @@ void gbuffer_additional_info_load(inout GBufferReader gbuf, samplerGBufferNormal
*
* \{ */
/* Outputing dummy closure is required for correct render passes in case of unlit materials. */
void gbuffer_closure_unlit_pack(inout GBufferWriter gbuf, vec3 N)
{
gbuffer_append_closure(gbuf, GBUF_UNLIT);
gbuffer_append_data(gbuf, vec4(0.0));
gbuffer_append_normal(gbuf, N);
}
void gbuffer_closure_diffuse_pack(inout GBufferWriter gbuf, ClosureUndetermined cl)
{
gbuffer_append_closure(gbuf, GBUF_DIFFUSE);
@ -752,9 +760,7 @@ GBufferWriter gbuffer_pack(GBufferData data_in)
}
if (gbuf.layer_normal == 0) {
/* If no lit BDSF is outputted, still output the surface normal in the first layer.
* This is needed by some algorithms. */
gbuffer_append_normal(gbuf, data_in.surface_N);
gbuffer_closure_unlit_pack(gbuf, data_in.surface_N);
}
if (has_additional_data) {