From 23c27807bdb30c0f334c19e147526bde48746b9f Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Tue, 17 Oct 2023 18:41:16 -0400 Subject: [PATCH] Separate base color texture and imagery layers --- exts/cesium.omniverse/mdl/cesium.mdl | 135 ++++++++----- .../include/cesium/omniverse/FabricMaterial.h | 20 +- .../omniverse/FabricMaterialDefinition.h | 7 +- .../include/cesium/omniverse/FabricUtil.h | 1 + .../include/cesium/omniverse/OmniTileset.h | 3 +- src/core/include/cesium/omniverse/Tokens.h | 143 +++++++------- src/core/src/FabricMaterial.cpp | 179 +++++++++--------- src/core/src/FabricMaterialDefinition.cpp | 32 ++-- src/core/src/FabricPrepareRenderResources.cpp | 31 +-- src/core/src/FabricResourceManager.cpp | 2 +- src/core/src/FabricUtil.cpp | 4 + src/core/src/OmniTileset.cpp | 2 +- 12 files changed, 294 insertions(+), 265 deletions(-) diff --git a/exts/cesium.omniverse/mdl/cesium.mdl b/exts/cesium.omniverse/mdl/cesium.mdl index 81b88adcd..5cadf5b6c 100644 --- a/exts/cesium.omniverse/mdl/cesium.mdl +++ b/exts/cesium.omniverse/mdl/cesium.mdl @@ -11,64 +11,95 @@ module [[ anno::display_name("Cesium MDL functions") ]]; -// For internal use only +float4 alpha_blend(float4 src, float4 dst) { + return src * float4(src.w, src.w, src.w, 1.0) + dst * (1.0 - src.w); +} + export gltf_texture_lookup_value cesium_texture_lookup(*) [[ anno::hidden() ]] = gltf_texture_lookup(); -export material cesium_material(*) [[ anno::hidden() ]] = gltf_material(); -export gltf_texture_lookup_value cesium_texture_array_lookup( - uniform int texture_count = 0, - gltf_texture_lookup_value texture_0 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_1 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_2 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_3 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_4 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_5 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_6 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_7 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_8 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_9 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_10 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_11 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_12 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_13 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_14 = gltf_texture_lookup(), - gltf_texture_lookup_value texture_15 = gltf_texture_lookup() -) [[ anno::hidden() ]] -{ - // The array length should match MAX_TEXTURE_LAYER_COUNT in Tokens.h - gltf_texture_lookup_value[16] texture_values( - texture_0, - texture_1, - texture_2, - texture_3, - texture_4, - texture_5, - texture_6, - texture_7, - texture_8, - texture_9, - texture_10, - texture_11, - texture_12, - texture_13, - texture_14, - texture_15, +export material cesium_material( + gltf_texture_lookup_value imagery_layers_texture = gltf_texture_lookup_value(true, float4(0.0)), + // gltf_material inputs below + gltf_texture_lookup_value base_color_texture = gltf_texture_lookup_value(), + uniform color base_color_factor = color(1.0), + uniform float metallic_factor = 1.0, + uniform float roughness_factor = 1.0, + uniform color emissive_factor = color(0.0), + uniform gltf_alpha_mode alpha_mode = opaque, + uniform float base_alpha = 1.0, + uniform float alpha_cutoff = 0.5 +) [[ anno::hidden() ]] = let { + auto base_color_texture_value = base_color_texture.valid ? base_color_texture.value : float4(1.0); + auto final_base_color_texture_value = alpha_blend(imagery_layers_texture.value, base_color_texture_value); + auto final_base_color_texture = gltf_texture_lookup_value(true, final_base_color_texture_value); + auto final_base_color_factor = base_color_factor; + + material base = gltf_material( + base_color_factor: final_base_color_factor, + base_color_texture: final_base_color_texture, + metallic_factor: metallic_factor, + roughness_factor: roughness_factor, + emissive_factor: emissive_factor, + alpha_mode: alpha_mode, + base_alpha: base_alpha, + alpha_cutoff: alpha_cutoff ); - float3 final = float3(1.0, 1.0, 1.0); +} in material( + thin_walled: base.thin_walled, + surface: base.surface, + volume: base.volume, + ior: base.ior, + geometry: base.geometry +); - for (int i = 0; i < texture_count; i++) { - gltf_texture_lookup_value value = texture_values[i]; - if (value.valid) { - float3 rgb = float3(value.value[0], value.value[1], value.value[2]); - float alpha = value.value[3]; - final = alpha * rgb + (1.0 - alpha) * final; +export gltf_texture_lookup_value cesium_imagery_layer_resolver( + uniform int imagery_layers_count = 0, + gltf_texture_lookup_value imagery_layer_0 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_1 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_2 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_3 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_4 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_5 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_6 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_7 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_8 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_9 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_10 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_11 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_12 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_13 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_14 = gltf_texture_lookup(), + gltf_texture_lookup_value imagery_layer_15 = gltf_texture_lookup() +) [[ anno::hidden() ]] { + // The array length should match MAX_IMAGERY_LAYERS_COUNT in Tokens.h + gltf_texture_lookup_value[16] imagery_layers( + imagery_layer_0, + imagery_layer_1, + imagery_layer_2, + imagery_layer_3, + imagery_layer_4, + imagery_layer_5, + imagery_layer_6, + imagery_layer_7, + imagery_layer_8, + imagery_layer_9, + imagery_layer_10, + imagery_layer_11, + imagery_layer_12, + imagery_layer_13, + imagery_layer_14, + imagery_layer_15, + ); + + auto resolved_value = float4(0.0); + + for (int i = 0; i < imagery_layers_count; i++) { + auto imagery_layer = imagery_layers[i]; + if (imagery_layer.valid) { + resolved_value = alpha_blend(imagery_layer.value, resolved_value); } } - gltf_texture_lookup_value tex_ret; - tex_ret.value = float4(final[0], final[1], final[2], 1.0); - tex_ret.valid = true; - - return tex_ret; + return gltf_texture_lookup_value(true, resolved_value); } diff --git a/src/core/include/cesium/omniverse/FabricMaterial.h b/src/core/include/cesium/omniverse/FabricMaterial.h index 3a0d94ab2..cf9d4a9ce 100644 --- a/src/core/include/cesium/omniverse/FabricMaterial.h +++ b/src/core/include/cesium/omniverse/FabricMaterial.h @@ -26,13 +26,19 @@ class FabricMaterial { void setMaterial(int64_t tilesetId, const MaterialInfo& materialInfo); void setBaseColorTexture( + const pxr::TfToken& textureAssetPathToken, + const TextureInfo& textureInfo, + uint64_t texcoordIndex); + void setImageryLayer( const pxr::TfToken& textureAssetPathToken, const TextureInfo& textureInfo, uint64_t texcoordIndex, - uint64_t textureIndex); + uint64_t imageryLayerIndex); void clearMaterial(); - void clearBaseColorTexture(uint64_t textureIndex); + void clearBaseColorTexture(); + void clearImageryLayer(uint64_t imageryLayerIndex); + void clearImageryLayers(); void setActive(bool active); @@ -48,8 +54,8 @@ class FabricMaterial { const omni::fabric::Path& texturePath, const omni::fabric::Path& shaderPath, const omni::fabric::Token& shaderInput); - void createTextureArray( - const omni::fabric::Path& texturePath, + void createImageryLayerResolver( + const omni::fabric::Path& imageryLayerResolverPath, const omni::fabric::Path& shaderPath, const omni::fabric::Token& shaderInput, uint64_t textureCount); @@ -60,9 +66,7 @@ class FabricMaterial { const pxr::TfToken& textureAssetPathToken, const TextureInfo& textureInfo, uint64_t texcoordIndex); - void setTilesetId(int64_t tilesetId); bool stageDestroyed(); - void clearBaseColorTextures(); omni::fabric::Path _materialPath; const FabricMaterialDefinition _materialDefinition; @@ -72,7 +76,9 @@ class FabricMaterial { omni::fabric::Path _shaderPath; omni::fabric::Path _baseColorTexturePath; - std::vector _baseColorTextureLayerPaths; + std::vector _imageryLayerPaths; + + std::vector _allPaths; }; } // namespace cesium::omniverse diff --git a/src/core/include/cesium/omniverse/FabricMaterialDefinition.h b/src/core/include/cesium/omniverse/FabricMaterialDefinition.h index 1c5758c45..b59219159 100644 --- a/src/core/include/cesium/omniverse/FabricMaterialDefinition.h +++ b/src/core/include/cesium/omniverse/FabricMaterialDefinition.h @@ -13,15 +13,16 @@ class FabricMaterialDefinition { FabricMaterialDefinition(const MaterialInfo& materialInfo, uint64_t imageryLayerCount, bool disableTextures); [[nodiscard]] bool hasVertexColors() const; - [[nodiscard]] uint64_t getBaseColorTextureCount() const; - [[nodiscard]] bool hasBaseColorTextures() const; + [[nodiscard]] bool hasBaseColorTexture() const; + [[nodiscard]] uint64_t getImageryLayerCount() const; // Make sure to update this function when adding new fields to the class bool operator==(const FabricMaterialDefinition& other) const; private: bool _hasVertexColors; - uint64_t _baseColorTextureCount; + bool _hasBaseColorTexture; + uint64_t _imageryLayerCount; }; } // namespace cesium::omniverse diff --git a/src/core/include/cesium/omniverse/FabricUtil.h b/src/core/include/cesium/omniverse/FabricUtil.h index a958d9c30..04ccc1b4b 100644 --- a/src/core/include/cesium/omniverse/FabricUtil.h +++ b/src/core/include/cesium/omniverse/FabricUtil.h @@ -34,5 +34,6 @@ void setTilesetTransform(int64_t tilesetId, const glm::dmat4& ecefToUsdTransform void setTilesetId(const omni::fabric::Path& path, int64_t tilesetId); omni::fabric::Path toFabricPath(const pxr::SdfPath& path); omni::fabric::Path joinPaths(const omni::fabric::Path& absolutePath, const omni::fabric::Token& relativePath); +bool isEmpty(const omni::fabric::Path& path); } // namespace cesium::omniverse::FabricUtil diff --git a/src/core/include/cesium/omniverse/OmniTileset.h b/src/core/include/cesium/omniverse/OmniTileset.h index c3e0bcac3..8ba34fa53 100644 --- a/src/core/include/cesium/omniverse/OmniTileset.h +++ b/src/core/include/cesium/omniverse/OmniTileset.h @@ -73,7 +73,8 @@ class OmniTileset { void reload(); void addImageryIon(const pxr::SdfPath& imageryPath); - [[nodiscard]] std::optional findImageryIndex(const Cesium3DTilesSelection::RasterOverlay& overlay) const; + [[nodiscard]] std::optional + findImageryLayerIndex(const Cesium3DTilesSelection::RasterOverlay& overlay) const; [[nodiscard]] uint64_t getImageryLayerCount() const; void onUpdateFrame(const std::vector& viewports); diff --git a/src/core/include/cesium/omniverse/Tokens.h b/src/core/include/cesium/omniverse/Tokens.h index 28fabbb90..bf6bdb204 100644 --- a/src/core/include/cesium/omniverse/Tokens.h +++ b/src/core/include/cesium/omniverse/Tokens.h @@ -14,32 +14,32 @@ __pragma(warning(push)) __pragma(warning(disable : 4003)) #define USD_TOKENS \ (base_color_texture) \ - (base_color_texture_0) \ - (base_color_texture_1) \ - (base_color_texture_2) \ - (base_color_texture_3) \ - (base_color_texture_4) \ - (base_color_texture_5) \ - (base_color_texture_6) \ - (base_color_texture_7) \ - (base_color_texture_8) \ - (base_color_texture_9) \ - (base_color_texture_10) \ - (base_color_texture_11) \ - (base_color_texture_12) \ - (base_color_texture_13) \ - (base_color_texture_14) \ - (base_color_texture_15) \ - (base_color_texture_array) \ (cesium) \ + (cesium_imagery_layer_resolver) \ (cesium_material) \ - (cesium_texture_array_lookup) \ (cesium_texture_lookup) \ (constant) \ (doubleSided) \ (extent) \ (faceVertexCounts) \ (faceVertexIndices) \ + (imagery_layer_0) \ + (imagery_layer_1) \ + (imagery_layer_2) \ + (imagery_layer_3) \ + (imagery_layer_4) \ + (imagery_layer_5) \ + (imagery_layer_6) \ + (imagery_layer_7) \ + (imagery_layer_8) \ + (imagery_layer_9) \ + (imagery_layer_10) \ + (imagery_layer_11) \ + (imagery_layer_12) \ + (imagery_layer_13) \ + (imagery_layer_14) \ + (imagery_layer_15) \ + (imagery_layer_resolver) \ (Material) \ (Mesh) \ (none) \ @@ -79,23 +79,24 @@ __pragma(warning(push)) __pragma(warning(disable : 4003)) ((inputs_scale, "inputs:scale")) \ ((inputs_tex_coord_index, "inputs:tex_coord_index")) \ ((inputs_texture, "inputs:texture")) \ - ((inputs_texture_0, "inputs:texture_0")) \ - ((inputs_texture_1, "inputs:texture_1")) \ - ((inputs_texture_2, "inputs:texture_2")) \ - ((inputs_texture_3, "inputs:texture_3")) \ - ((inputs_texture_4, "inputs:texture_4")) \ - ((inputs_texture_5, "inputs:texture_5")) \ - ((inputs_texture_6, "inputs:texture_6")) \ - ((inputs_texture_7, "inputs:texture_7")) \ - ((inputs_texture_8, "inputs:texture_8")) \ - ((inputs_texture_9, "inputs:texture_9")) \ - ((inputs_texture_10, "inputs:texture_10")) \ - ((inputs_texture_11, "inputs:texture_11")) \ - ((inputs_texture_12, "inputs:texture_12")) \ - ((inputs_texture_13, "inputs:texture_13")) \ - ((inputs_texture_14, "inputs:texture_14")) \ - ((inputs_texture_15, "inputs:texture_15")) \ - ((inputs_texture_count, "inputs:texture_count")) \ + ((inputs_imagery_layer_0, "inputs:imagery_layer_0")) \ + ((inputs_imagery_layer_1, "inputs:imagery_layer_1")) \ + ((inputs_imagery_layer_2, "inputs:imagery_layer_2")) \ + ((inputs_imagery_layer_3, "inputs:imagery_layer_3")) \ + ((inputs_imagery_layer_4, "inputs:imagery_layer_4")) \ + ((inputs_imagery_layer_5, "inputs:imagery_layer_5")) \ + ((inputs_imagery_layer_6, "inputs:imagery_layer_6")) \ + ((inputs_imagery_layer_7, "inputs:imagery_layer_7")) \ + ((inputs_imagery_layer_8, "inputs:imagery_layer_8")) \ + ((inputs_imagery_layer_9, "inputs:imagery_layer_9")) \ + ((inputs_imagery_layer_10, "inputs:imagery_layer_10")) \ + ((inputs_imagery_layer_11, "inputs:imagery_layer_11")) \ + ((inputs_imagery_layer_12, "inputs:imagery_layer_12")) \ + ((inputs_imagery_layer_13, "inputs:imagery_layer_13")) \ + ((inputs_imagery_layer_14, "inputs:imagery_layer_14")) \ + ((inputs_imagery_layer_15, "inputs:imagery_layer_15")) \ + ((inputs_imagery_layers_count, "inputs:imagery_layers_count")) \ + ((inputs_imagery_layers_texture, "inputs:imagery_layers_texture")) \ ((inputs_vertex_color_name, "inputs:vertex_color_name")) \ ((inputs_wrap_s, "inputs:wrap_s")) \ ((inputs_wrap_t, "inputs:wrap_t")) \ @@ -150,7 +151,7 @@ namespace cesium::omniverse::FabricTokens { FABRIC_DECLARE_TOKENS(USD_TOKENS); const uint64_t MAX_PRIMVAR_ST_COUNT = 10; -const uint64_t MAX_TEXTURE_LAYER_COUNT = 16; +const uint64_t MAX_IMAGERY_LAYERS_COUNT = 16; const std::array primvars_st_n = {{ primvars_st_0, @@ -165,42 +166,42 @@ const std::array primvars_st_n primvars_st_9, }}; -const std::array base_color_texture_n = {{ - base_color_texture_0, - base_color_texture_1, - base_color_texture_2, - base_color_texture_3, - base_color_texture_4, - base_color_texture_5, - base_color_texture_6, - base_color_texture_7, - base_color_texture_8, - base_color_texture_9, - base_color_texture_10, - base_color_texture_11, - base_color_texture_12, - base_color_texture_13, - base_color_texture_14, - base_color_texture_15, +const std::array imagery_layer_n = {{ + imagery_layer_0, + imagery_layer_1, + imagery_layer_2, + imagery_layer_3, + imagery_layer_4, + imagery_layer_5, + imagery_layer_6, + imagery_layer_7, + imagery_layer_8, + imagery_layer_9, + imagery_layer_10, + imagery_layer_11, + imagery_layer_12, + imagery_layer_13, + imagery_layer_14, + imagery_layer_15, }}; -const std::array inputs_texture_n = {{ - inputs_texture_0, - inputs_texture_1, - inputs_texture_2, - inputs_texture_3, - inputs_texture_4, - inputs_texture_5, - inputs_texture_6, - inputs_texture_7, - inputs_texture_8, - inputs_texture_9, - inputs_texture_10, - inputs_texture_11, - inputs_texture_12, - inputs_texture_13, - inputs_texture_14, - inputs_texture_15, +const std::array inputs_imagery_layer_n = {{ + inputs_imagery_layer_0, + inputs_imagery_layer_1, + inputs_imagery_layer_2, + inputs_imagery_layer_3, + inputs_imagery_layer_4, + inputs_imagery_layer_5, + inputs_imagery_layer_6, + inputs_imagery_layer_7, + inputs_imagery_layer_8, + inputs_imagery_layer_9, + inputs_imagery_layer_10, + inputs_imagery_layer_11, + inputs_imagery_layer_12, + inputs_imagery_layer_13, + inputs_imagery_layer_14, + inputs_imagery_layer_15, }}; } @@ -227,7 +228,7 @@ const omni::fabric::Type inputs_roughness_factor(omni::fabric::BaseDataType::eFl const omni::fabric::Type inputs_scale(omni::fabric::BaseDataType::eFloat, 2, 0, omni::fabric::AttributeRole::eNone); const omni::fabric::Type inputs_tex_coord_index(omni::fabric::BaseDataType::eInt, 1, 0, omni::fabric::AttributeRole::eNone); const omni::fabric::Type inputs_texture(omni::fabric::BaseDataType::eAsset, 1, 0, omni::fabric::AttributeRole::eNone); -const omni::fabric::Type inputs_texture_count(omni::fabric::BaseDataType::eInt, 1, 0, omni::fabric::AttributeRole::eNone); +const omni::fabric::Type inputs_imagery_layers_count(omni::fabric::BaseDataType::eInt, 1, 0, omni::fabric::AttributeRole::eNone); const omni::fabric::Type inputs_vertex_color_name(omni::fabric::BaseDataType::eUChar, 1, 1, omni::fabric::AttributeRole::eText); const omni::fabric::Type inputs_wrap_s(omni::fabric::BaseDataType::eInt, 1, 0, omni::fabric::AttributeRole::eNone); const omni::fabric::Type inputs_wrap_t(omni::fabric::BaseDataType::eInt, 1, 0, omni::fabric::AttributeRole::eNone); diff --git a/src/core/src/FabricMaterial.cpp b/src/core/src/FabricMaterial.cpp index 2bb99df4e..84207b655 100644 --- a/src/core/src/FabricMaterial.cpp +++ b/src/core/src/FabricMaterial.cpp @@ -5,6 +5,7 @@ #include "cesium/omniverse/FabricMaterialDefinition.h" #include "cesium/omniverse/FabricResourceManager.h" #include "cesium/omniverse/FabricUtil.h" +#include "cesium/omniverse/GltfUtil.h" #include "cesium/omniverse/LoggerSink.h" #include "cesium/omniverse/Tokens.h" #include "cesium/omniverse/UsdUtil.h" @@ -15,19 +16,20 @@ namespace cesium::omniverse { namespace { -uint64_t getBaseColorTextureCount(const FabricMaterialDefinition& materialDefinition) { - auto baseColorTextureCount = materialDefinition.getBaseColorTextureCount(); +uint64_t getImageryLayerCount(const FabricMaterialDefinition& materialDefinition) { + uint64_t imageryLayerCount = materialDefinition.getImageryLayerCount(); - if (baseColorTextureCount > FabricTokens::MAX_TEXTURE_LAYER_COUNT) { + if (imageryLayerCount > FabricTokens::MAX_IMAGERY_LAYERS_COUNT) { CESIUM_LOG_WARN( - "Number of textures ({}) exceeds maximum texture layer count ({}). Excess textures will be ignored.", - baseColorTextureCount, - FabricTokens::MAX_TEXTURE_LAYER_COUNT); + "Number of imagery layers ({}) exceeds maximum imagery layer count ({}). Excess imagery layers will be " + "ignored.", + imageryLayerCount, + FabricTokens::MAX_IMAGERY_LAYERS_COUNT); } - baseColorTextureCount = glm::min(baseColorTextureCount, FabricTokens::MAX_TEXTURE_LAYER_COUNT); + imageryLayerCount = glm::min(imageryLayerCount, FabricTokens::MAX_IMAGERY_LAYERS_COUNT); - return baseColorTextureCount; + return imageryLayerCount; } } // namespace @@ -56,15 +58,8 @@ FabricMaterial::~FabricMaterial() { return; } - FabricUtil::destroyPrim(_materialPath); - FabricUtil::destroyPrim(_shaderPath); - - if (_materialDefinition.hasBaseColorTextures()) { - FabricUtil::destroyPrim(_baseColorTexturePath); - - for (const auto& baseColorTextureLayerPath : _baseColorTextureLayerPaths) { - FabricUtil::destroyPrim(baseColorTextureLayerPath); - } + for (const auto& path : _allPaths) { + FabricUtil::destroyPrim(path); } } @@ -89,38 +84,47 @@ const FabricMaterialDefinition& FabricMaterial::getMaterialDefinition() const { void FabricMaterial::initialize() { const auto& materialPath = _materialPath; createMaterial(materialPath); - auto& fabricResourceManager = FabricResourceManager::getInstance(); - fabricResourceManager.retainPath(materialPath); + _allPaths.push_back(materialPath); const auto shaderPath = FabricUtil::joinPaths(materialPath, FabricTokens::Shader); createShader(shaderPath, materialPath); - fabricResourceManager.retainPath(shaderPath); _shaderPath = shaderPath; + _allPaths.push_back(shaderPath); - const auto baseColorTextureCount = getBaseColorTextureCount(_materialDefinition); - - if (baseColorTextureCount == 1) { + if (_materialDefinition.hasBaseColorTexture()) { const auto baseColorTexturePath = FabricUtil::joinPaths(materialPath, FabricTokens::base_color_texture); - fabricResourceManager.retainPath(baseColorTexturePath); - _baseColorTexturePath = baseColorTexturePath; createTexture(baseColorTexturePath, shaderPath, FabricTokens::inputs_base_color_texture); - } else if (baseColorTextureCount > 1) { - const auto baseColorTexturePath = FabricUtil::joinPaths(materialPath, FabricTokens::base_color_texture_array); - fabricResourceManager.retainPath(baseColorTexturePath); _baseColorTexturePath = baseColorTexturePath; - createTextureArray( - baseColorTexturePath, shaderPath, FabricTokens::inputs_base_color_texture, baseColorTextureCount); - - _baseColorTextureLayerPaths.reserve(baseColorTextureCount); - for (uint64_t i = 0; i < baseColorTextureCount; i++) { - const auto& baseColorTextureToken = FabricTokens::base_color_texture_n[i]; - const auto& inputsBaseColorTextureToken = FabricTokens::inputs_texture_n[i]; - const auto baseColorTextureLayerPath = FabricUtil::joinPaths(materialPath, baseColorTextureToken); - createTexture(baseColorTextureLayerPath, baseColorTexturePath, inputsBaseColorTextureToken); - fabricResourceManager.retainPath(baseColorTextureLayerPath); - _baseColorTextureLayerPaths.push_back(baseColorTextureLayerPath); + _allPaths.push_back(baseColorTexturePath); + } + + const auto imageryLayerCount = getImageryLayerCount(_materialDefinition); + + if (imageryLayerCount == 1) { + // If there's a single imagery layer plug into cesium_material directly + // instead of using a cesium_imagery_layer_resolver + const auto imageryLayerPath = FabricUtil::joinPaths(materialPath, FabricTokens::imagery_layer_n[0]); + createTexture(imageryLayerPath, shaderPath, FabricTokens::inputs_imagery_layers_texture); + _imageryLayerPaths.push_back(imageryLayerPath); + _allPaths.push_back(imageryLayerPath); + } else if (imageryLayerCount > 1) { + const auto imageryLayerResolverPath = FabricUtil::joinPaths(materialPath, FabricTokens::imagery_layer_resolver); + createImageryLayerResolver( + imageryLayerResolverPath, shaderPath, FabricTokens::inputs_imagery_layers_texture, imageryLayerCount); + _allPaths.push_back(imageryLayerResolverPath); + + _imageryLayerPaths.reserve(imageryLayerCount); + for (uint64_t i = 0; i < imageryLayerCount; i++) { + const auto imageryLayerPath = FabricUtil::joinPaths(materialPath, FabricTokens::imagery_layer_n[i]); + createTexture(imageryLayerPath, imageryLayerResolverPath, FabricTokens::inputs_imagery_layer_n[i]); + _imageryLayerPaths.push_back(imageryLayerPath); + _allPaths.push_back(imageryLayerPath); } } + + for (const auto& path : _allPaths) { + FabricResourceManager::getInstance().retainPath(path); + } } void FabricMaterial::createMaterial(const omni::fabric::Path& materialPath) { @@ -263,19 +267,19 @@ void FabricMaterial::createTexture( srw.createConnection(shaderPath, shaderInput, omni::fabric::Connection{texturePath, FabricTokens::outputs_out}); } -void FabricMaterial::createTextureArray( - const omni::fabric::Path& texturePath, +void FabricMaterial::createImageryLayerResolver( + const omni::fabric::Path& imageryLayerResolverPath, const omni::fabric::Path& shaderPath, const omni::fabric::Token& shaderInput, - uint64_t textureCount) { + uint64_t imageryLayerCount) { auto srw = UsdUtil::getFabricStageReaderWriter(); - srw.createPrim(texturePath); + srw.createPrim(imageryLayerResolverPath); FabricAttributesBuilder attributes; // clang-format off - attributes.addAttribute(FabricTypes::inputs_texture_count, FabricTokens::inputs_texture_count); + attributes.addAttribute(FabricTypes::inputs_imagery_layers_count, FabricTokens::inputs_imagery_layers_count); attributes.addAttribute(FabricTypes::inputs_excludeFromWhiteMode, FabricTokens::inputs_excludeFromWhiteMode); attributes.addAttribute(FabricTypes::outputs_out, FabricTokens::outputs_out); attributes.addAttribute(FabricTypes::info_implementationSource, FabricTokens::info_implementationSource); @@ -286,30 +290,32 @@ void FabricMaterial::createTextureArray( attributes.addAttribute(FabricTypes::_cesium_tilesetId, FabricTokens::_cesium_tilesetId); // clang-format on - attributes.createAttributes(texturePath); + attributes.createAttributes(imageryLayerResolverPath); // clang-format off - auto inputsTextureCountFabric = srw.getAttributeWr(texturePath, FabricTokens::inputs_texture_count); - auto inputsExcludeFromWhiteModeFabric = srw.getAttributeWr(texturePath, FabricTokens::inputs_excludeFromWhiteMode); - auto infoImplementationSourceFabric = srw.getAttributeWr(texturePath, FabricTokens::info_implementationSource); - auto infoMdlSourceAssetFabric = srw.getAttributeWr(texturePath, FabricTokens::info_mdl_sourceAsset); - auto infoMdlSourceAssetSubIdentifierFabric = srw.getAttributeWr(texturePath, FabricTokens::info_mdl_sourceAsset_subIdentifier); + auto imageryLayerCountFabric = srw.getAttributeWr(imageryLayerResolverPath, FabricTokens::inputs_imagery_layers_count); + auto inputsExcludeFromWhiteModeFabric = srw.getAttributeWr(imageryLayerResolverPath, FabricTokens::inputs_excludeFromWhiteMode); + auto infoImplementationSourceFabric = srw.getAttributeWr(imageryLayerResolverPath, FabricTokens::info_implementationSource); + auto infoMdlSourceAssetFabric = srw.getAttributeWr(imageryLayerResolverPath, FabricTokens::info_mdl_sourceAsset); + auto infoMdlSourceAssetSubIdentifierFabric = srw.getAttributeWr(imageryLayerResolverPath, FabricTokens::info_mdl_sourceAsset_subIdentifier); // clang-format on - *inputsTextureCountFabric = static_cast(textureCount); + *imageryLayerCountFabric = static_cast(imageryLayerCount); *inputsExcludeFromWhiteModeFabric = false; *infoImplementationSourceFabric = FabricTokens::sourceAsset; infoMdlSourceAssetFabric->assetPath = Context::instance().getCesiumMdlPathToken(); infoMdlSourceAssetFabric->resolvedPath = pxr::TfToken(); - *infoMdlSourceAssetSubIdentifierFabric = FabricTokens::cesium_texture_array_lookup; + *infoMdlSourceAssetSubIdentifierFabric = FabricTokens::cesium_imagery_layer_resolver; - // Create connection from shader to texture. - srw.createConnection(shaderPath, shaderInput, omni::fabric::Connection{texturePath, FabricTokens::outputs_out}); + // Create connection to shader + srw.createConnection( + shaderPath, shaderInput, omni::fabric::Connection{imageryLayerResolverPath, FabricTokens::outputs_out}); } void FabricMaterial::reset() { clearMaterial(); - clearBaseColorTextures(); + clearBaseColorTexture(); + clearImageryLayers(); } void FabricMaterial::setMaterial(int64_t tilesetId, const MaterialInfo& materialInfo) { @@ -320,67 +326,58 @@ void FabricMaterial::setMaterial(int64_t tilesetId, const MaterialInfo& material auto srw = UsdUtil::getFabricStageReaderWriter(); setShaderValues(_shaderPath, materialInfo); - setTilesetId(tilesetId); + + for (const auto& path : _allPaths) { + FabricUtil::setTilesetId(path, tilesetId); + } } void FabricMaterial::setBaseColorTexture( const pxr::TfToken& textureAssetPathToken, const TextureInfo& textureInfo, - uint64_t texcoordIndex, - uint64_t textureIndex) { + uint64_t texcoordIndex) { if (stageDestroyed()) { return; } - if (!_materialDefinition.hasBaseColorTextures()) { + if (FabricUtil::isEmpty(_baseColorTexturePath)) { return; } - if (textureIndex >= FabricTokens::MAX_TEXTURE_LAYER_COUNT) { + setTextureValues(_baseColorTexturePath, textureAssetPathToken, textureInfo, texcoordIndex); +} + +void FabricMaterial::setImageryLayer( + const pxr::TfToken& textureAssetPathToken, + const TextureInfo& textureInfo, + uint64_t texcoordIndex, + uint64_t imageryLayerIndex) { + if (stageDestroyed()) { return; } - if (_baseColorTextureLayerPaths.empty()) { - assert(textureIndex == 0); - setTextureValues(_baseColorTexturePath, textureAssetPathToken, textureInfo, texcoordIndex); - } else { - setTextureValues(_baseColorTextureLayerPaths[textureIndex], textureAssetPathToken, textureInfo, texcoordIndex); + if (imageryLayerIndex >= _imageryLayerPaths.size()) { + return; } + + setTextureValues(_imageryLayerPaths[imageryLayerIndex], textureAssetPathToken, textureInfo, texcoordIndex); } void FabricMaterial::clearMaterial() { setMaterial(NO_TILESET_ID, GltfUtil::getDefaultMaterialInfo()); } -void FabricMaterial::clearBaseColorTextures() { - if (!_materialDefinition.hasBaseColorTextures()) { - return; - } - - if (_baseColorTextureLayerPaths.empty()) { - clearBaseColorTexture(0); - } else { - for (uint64_t i = 0; i < _baseColorTextureLayerPaths.size(); i++) { - clearBaseColorTexture(i); - } - } +void FabricMaterial::clearBaseColorTexture() { + setBaseColorTexture(_defaultTextureAssetPathToken, GltfUtil::getDefaultTextureInfo(), 0); } -void FabricMaterial::clearBaseColorTexture(uint64_t textureIndex) { - const auto& token = textureIndex == 0 ? _defaultTextureAssetPathToken : _defaultTransparentTextureAssetPathToken; - setBaseColorTexture(token, GltfUtil::getDefaultTextureInfo(), 0, textureIndex); +void FabricMaterial::clearImageryLayer(uint64_t imageryLayerIndex) { + setImageryLayer(_defaultTransparentTextureAssetPathToken, GltfUtil::getDefaultTextureInfo(), 0, imageryLayerIndex); } -void FabricMaterial::setTilesetId(int64_t tilesetId) { - FabricUtil::setTilesetId(_materialPath, tilesetId); - FabricUtil::setTilesetId(_shaderPath, tilesetId); - - if (_materialDefinition.hasBaseColorTextures()) { - FabricUtil::setTilesetId(_baseColorTexturePath, tilesetId); - - for (const auto& baseColorTextureLayerPath : _baseColorTextureLayerPaths) { - FabricUtil::setTilesetId(baseColorTextureLayerPath, tilesetId); - } +void FabricMaterial::clearImageryLayers() { + for (uint64_t i = 0; i < _imageryLayerPaths.size(); i++) { + clearImageryLayer(i); } } @@ -410,7 +407,7 @@ void FabricMaterial::setTextureValues( const TextureInfo& textureInfo, uint64_t texcoordIndex) { - if (texcoordIndex >= FabricTokens::MAX_TEXTURE_LAYER_COUNT) { + if (texcoordIndex >= FabricTokens::MAX_PRIMVAR_ST_COUNT) { return; } diff --git a/src/core/src/FabricMaterialDefinition.cpp b/src/core/src/FabricMaterialDefinition.cpp index 0550c2270..61e8bf05f 100644 --- a/src/core/src/FabricMaterialDefinition.cpp +++ b/src/core/src/FabricMaterialDefinition.cpp @@ -16,30 +16,28 @@ FabricMaterialDefinition::FabricMaterialDefinition( uint64_t imageryLayerCount, bool disableTextures) { - uint64_t baseColorTextureCount = 0; + auto hasBaseColorTexture = materialInfo.baseColorTexture.has_value(); - if (!disableTextures) { - if (materialInfo.baseColorTexture.has_value()) { - baseColorTextureCount++; - } - - baseColorTextureCount += imageryLayerCount; + if (disableTextures) { + hasBaseColorTexture = false; + imageryLayerCount = 0; } _hasVertexColors = materialInfo.hasVertexColors; - _baseColorTextureCount = baseColorTextureCount; + _hasBaseColorTexture = hasBaseColorTexture; + _imageryLayerCount = imageryLayerCount; } -uint64_t FabricMaterialDefinition::getBaseColorTextureCount() const { - return _baseColorTextureCount; +bool FabricMaterialDefinition::hasVertexColors() const { + return _hasVertexColors; } -bool FabricMaterialDefinition::hasBaseColorTextures() const { - return _baseColorTextureCount > 0; +bool FabricMaterialDefinition::hasBaseColorTexture() const { + return _hasBaseColorTexture; } -bool FabricMaterialDefinition::hasVertexColors() const { - return _hasVertexColors; +uint64_t FabricMaterialDefinition::getImageryLayerCount() const { + return _imageryLayerCount; } // In C++ 20 we can use the default equality comparison (= default) @@ -48,7 +46,11 @@ bool FabricMaterialDefinition::operator==(const FabricMaterialDefinition& other) return false; } - if (_baseColorTextureCount != other._baseColorTextureCount) { + if (_hasBaseColorTexture != other._hasBaseColorTexture) { + return false; + } + + if (_imageryLayerCount != other._imageryLayerCount) { return false; } diff --git a/src/core/src/FabricPrepareRenderResources.cpp b/src/core/src/FabricPrepareRenderResources.cpp index da4f546f1..bd32b5e78 100644 --- a/src/core/src/FabricPrepareRenderResources.cpp +++ b/src/core/src/FabricPrepareRenderResources.cpp @@ -56,22 +56,10 @@ struct TileLoadThreadResult { }; bool hasBaseColorTextureGltf(const FabricMesh& fabricMesh) { - return fabricMesh.material != nullptr && fabricMesh.material->getMaterialDefinition().hasBaseColorTextures() && + return fabricMesh.material != nullptr && fabricMesh.material->getMaterialDefinition().hasBaseColorTexture() && fabricMesh.materialInfo.baseColorTexture.has_value(); } -uint64_t getBaseColorTextureIndexForGltf() { - return 0; -} - -uint64_t getBaseColorTextureIndexForImagery(const FabricMesh& fabricMesh, uint64_t imageryIndex) { - if (hasBaseColorTextureGltf(fabricMesh)) { - return imageryIndex + 1; - } - - return imageryIndex; -} - std::vector gatherMeshes(const OmniTileset& tileset, const glm::dmat4& tileTransform, const CesiumGltf::Model& model) { CESIUM_TRACE("FabricPrepareRenderResources::gatherMeshes"); @@ -219,9 +207,8 @@ void setFabricMeshes( if (hasBaseColorTextureGltf(mesh)) { const auto& textureInfo = materialInfo.baseColorTexture.value(); const auto texcoordIndex = mesh.texcoordIndexMapping[textureInfo.setIndex]; - const auto textureIndex = getBaseColorTextureIndexForGltf(); const auto& textureAssetPath = baseColorTexture->getAssetPathToken(); - material->setBaseColorTexture(textureAssetPath, textureInfo, texcoordIndex, textureIndex); + material->setBaseColorTexture(textureAssetPath, textureInfo, texcoordIndex); } } else if (!tilesetMaterialPath.IsEmpty()) { geometry->setMaterial(FabricUtil::toFabricPath(tilesetMaterialPath)); @@ -459,8 +446,8 @@ void FabricPrepareRenderResources::attachRasterInMainThread( return; } - auto imageryIndex = _tileset->findImageryIndex(rasterTile.getOverlay()); - if (!imageryIndex.has_value()) { + auto imageryLayerIndex = _tileset->findImageryLayerIndex(rasterTile.getOverlay()); + if (!imageryLayerIndex.has_value()) { return; } @@ -479,9 +466,8 @@ void FabricPrepareRenderResources::attachRasterInMainThread( }; const auto texcoordIndex = mesh.imageryTexcoordIndexMapping.at(gltfSetIndex); - const auto textureIndex = getBaseColorTextureIndexForImagery(mesh, imageryIndex.value()); const auto& textureAssetPath = texture->getAssetPathToken(); - material->setBaseColorTexture(textureAssetPath, textureInfo, texcoordIndex, textureIndex); + material->setImageryLayer(textureAssetPath, textureInfo, texcoordIndex, imageryLayerIndex.value()); } } } @@ -507,16 +493,15 @@ void FabricPrepareRenderResources::detachRasterInMainThread( return; } - auto imageryIndex = _tileset->findImageryIndex(rasterTile.getOverlay()); - if (!imageryIndex.has_value()) { + auto imageryLayerIndex = _tileset->findImageryLayerIndex(rasterTile.getOverlay()); + if (!imageryLayerIndex.has_value()) { return; } for (const auto& mesh : pTileRenderResources->fabricMeshes) { auto& material = mesh.material; if (material != nullptr) { - const auto textureIndex = getBaseColorTextureIndexForImagery(mesh, imageryIndex.value()); - material->clearBaseColorTexture(textureIndex); + material->clearImageryLayer(imageryLayerIndex.value()); } } } diff --git a/src/core/src/FabricResourceManager.cpp b/src/core/src/FabricResourceManager.cpp index 2dbbebb41..c87be8af8 100644 --- a/src/core/src/FabricResourceManager.cpp +++ b/src/core/src/FabricResourceManager.cpp @@ -90,7 +90,7 @@ std::shared_ptr FabricResourceManager::acquireGeometry( } bool useSharedMaterial(const FabricMaterialDefinition& materialDefinition) { - if (materialDefinition.hasBaseColorTextures()) { + if (materialDefinition.hasBaseColorTexture() || materialDefinition.getImageryLayerCount() > 0) { return false; } diff --git a/src/core/src/FabricUtil.cpp b/src/core/src/FabricUtil.cpp index 9d0e672a0..218f08fb5 100644 --- a/src/core/src/FabricUtil.cpp +++ b/src/core/src/FabricUtil.cpp @@ -680,4 +680,8 @@ omni::fabric::Path joinPaths(const omni::fabric::Path& absolutePath, const omni: return {fmt::format("{}/{}", absolutePath.getText(), relativePath.getText()).c_str()}; } +bool isEmpty(const omni::fabric::Path& path) { + return omni::fabric::PathC(path) == omni::fabric::kUninitializedPath; +} + } // namespace cesium::omniverse::FabricUtil diff --git a/src/core/src/OmniTileset.cpp b/src/core/src/OmniTileset.cpp index ba137a757..ca2742d66 100644 --- a/src/core/src/OmniTileset.cpp +++ b/src/core/src/OmniTileset.cpp @@ -411,7 +411,7 @@ void OmniTileset::addImageryIon(const pxr::SdfPath& imageryPath) { _tileset->getOverlays().add(ionRasterOverlay); } -std::optional OmniTileset::findImageryIndex(const Cesium3DTilesSelection::RasterOverlay& overlay) const { +std::optional OmniTileset::findImageryLayerIndex(const Cesium3DTilesSelection::RasterOverlay& overlay) const { uint64_t overlayIndex = 0; for (const auto& pOverlay : _tileset->getOverlays()) { if (&overlay == pOverlay.get()) {