diff --git a/CMakeLists.txt b/CMakeLists.txt index 678d4bb9ae21..269e88da548e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -794,7 +794,7 @@ set(POSTCONFIGURE_SCRIPT "" CACHE FILEPATH "Run given CMake script as the last s mark_as_advanced(POSTCONFIGURE_SCRIPT) # USD Hydra plugin. -if(WIN32 AND WITH_USD) +if(WIN32 AND WITH_USD AND WITH_MATERIALX) option(WITH_HYDRA "Enable USD Hydra plugin" ON) endif() diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index 675429deb770..a47d0cf47d5d 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -899,6 +899,13 @@ if(WITH_USD) endif() endif() +if(WITH_MATERIALX) + windows_find_package(MaterialX) + if(NOT MaterialX_FOUND) + include("${LIBDIR}/MaterialX/lib/cmake/MaterialX/MaterialXTargets.cmake") + endif() +endif() + if(WINDOWS_PYTHON_DEBUG) # Include the system scripts in the blender_python_system_scripts project. file(GLOB_RECURSE inFiles "${CMAKE_SOURCE_DIR}/release/scripts/*.*" ) diff --git a/source/blender/render/hydra/CMakeLists.txt b/source/blender/render/hydra/CMakeLists.txt index 883177b61977..4982fab72b7e 100644 --- a/source/blender/render/hydra/CMakeLists.txt +++ b/source/blender/render/hydra/CMakeLists.txt @@ -1,6 +1,10 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright 2011-2022 Blender Foundation +if(NOT TARGET MaterialXCore OR NOT TARGET MaterialXFormat) + message(FATAL_ERROR "Hydra Scene Delegate requires MaterialX") +endif() + if(WIN32) add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN -DBOOST_DEBUG_PYTHON) endif() @@ -70,6 +74,8 @@ set(SRC sceneDelegate/material.cc sceneDelegate/mesh.h sceneDelegate/mesh.cc + sceneDelegate/mtlxHydraAdapter.h + sceneDelegate/mtlxHydraAdapter.cc sceneDelegate/light.h sceneDelegate/light.cc sceneDelegate/world.h @@ -86,4 +92,8 @@ set(LIB blender_add_lib(bf_render_hydra "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") +target_link_libraries(bf_render_hydra PRIVATE + MaterialXCore + MaterialXFormat) + add_dependencies(bf_render_hydra bf_rna) diff --git a/source/blender/render/hydra/sceneDelegate/material.cc b/source/blender/render/hydra/sceneDelegate/material.cc index 492157bfa5cd..a7ab14190995 100644 --- a/source/blender/render/hydra/sceneDelegate/material.cc +++ b/source/blender/render/hydra/sceneDelegate/material.cc @@ -5,6 +5,7 @@ #include #include +#include #include "glog/logging.h" @@ -12,6 +13,7 @@ #include "BKE_lib_id.h" #include "material.h" +#include "mtlxHydraAdapter.h" using namespace pxr; @@ -49,7 +51,18 @@ VtValue MaterialData::get_data(TfToken const &key) pxr::VtValue MaterialData::material_resource() { - /* TODO: Implement return of HdMaterialNetwork */ + std::string const &path = mtlx_path.GetResolvedPath(); + if (!path.empty()) { + HdRenderDelegate *render_delegate = scene_delegate->GetRenderIndex().GetRenderDelegate(); + TfTokenVector shader_source_types = render_delegate->GetShaderSourceTypes(); + TfTokenVector render_contexts = render_delegate->GetMaterialRenderContexts(); + + HdMaterialNetworkMap material_network_map; + HdMtlxConvertToMaterialNetworkMap( + path, shader_source_types, render_contexts, &material_network_map); + return VtValue(material_network_map); + } + return pxr::VtValue(); } diff --git a/source/blender/render/hydra/sceneDelegate/mtlxHydraAdapter.cc b/source/blender/render/hydra/sceneDelegate/mtlxHydraAdapter.cc new file mode 100644 index 000000000000..4888af16945e --- /dev/null +++ b/source/blender/render/hydra/sceneDelegate/mtlxHydraAdapter.cc @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#include "mtlxHydraAdapter.h" + +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#include + +namespace mx = MaterialX; + +PXR_NAMESPACE_OPEN_SCOPE + +void HdMtlxConvertToMaterialNetworkMap(std::string const &mtlxPath, + TfTokenVector const &shaderSourceTypes, + TfTokenVector const &renderContexts, + HdMaterialNetworkMap *out) +{ + if (mtlxPath.empty()) { + return; + } + + std::string basePath = TfGetPathName(mtlxPath); + + ArResolver &resolver = ArGetResolver(); + const ArResolverContext context = resolver.CreateDefaultContextForAsset(mtlxPath); + ArResolverContextBinder binder(context); + ArResolverScopedCache resolverCache; + + std::string mtlxName = TfGetBaseName(mtlxPath); + std::string stageId = TfStringPrintf( + "%s%s%s.usda", basePath.c_str(), ARCH_PATH_SEP, mtlxName.c_str()); + UsdStageRefPtr stage = UsdStage::CreateInMemory(stageId, context); + + try { + mx::DocumentPtr doc = UsdMtlxReadDocument(mtlxPath); + UsdMtlxRead(doc, stage); + } + catch (mx::ExceptionFoundCycle &x) { + TF_RUNTIME_ERROR("MaterialX cycle found: %s\n", x.what()); + return; + } + catch (mx::Exception &x) { + TF_RUNTIME_ERROR("MaterialX error: %s\n", x.what()); + return; + } + + if (UsdPrim materials = stage->GetPrimAtPath(SdfPath("/MaterialX/Materials"))) { + if (UsdPrimSiblingRange children = materials.GetChildren()) { + if (auto material = UsdShadeMaterial(*children.begin())) { + if (UsdShadeShader mtlxSurface = material.ComputeSurfaceSource(renderContexts)) { + UsdImagingBuildHdMaterialNetworkFromTerminal(mtlxSurface.GetPrim(), + HdMaterialTerminalTokens->surface, + shaderSourceTypes, + renderContexts, + out, + UsdTimeCode::Default()); + } + } + } + } +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/source/blender/render/hydra/sceneDelegate/mtlxHydraAdapter.h b/source/blender/render/hydra/sceneDelegate/mtlxHydraAdapter.h new file mode 100644 index 000000000000..7bfcafd40cc1 --- /dev/null +++ b/source/blender/render/hydra/sceneDelegate/mtlxHydraAdapter.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#pragma once + +#include +#include + +#include + +PXR_NAMESPACE_OPEN_SCOPE + +struct HdMaterialNetworkMap; + +void HdMtlxConvertToMaterialNetworkMap(std::string const &mtlxPath, + TfTokenVector const &shaderSourceTypes, + TfTokenVector const &renderContexts, + HdMaterialNetworkMap *out); + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 4c8dc9a49718..f89f243d6f56 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -980,6 +980,9 @@ elseif(WIN32) ${LIBDIR}/materialx/bin/MaterialXGenMdl.dll ${LIBDIR}/materialx/bin/MaterialXGenOsl.dll ${LIBDIR}/materialx/bin/MaterialXGenShader.dll + ${LIBDIR}/materialx/bin/MaterialXRender.dll + ${LIBDIR}/materialx/bin/MaterialXRenderHw.dll + ${LIBDIR}/materialx/bin/MaterialXRenderGlsl.dll RELEASE ) windows_install_shared_manifest( @@ -990,6 +993,9 @@ elseif(WIN32) ${LIBDIR}/materialx/bin/MaterialXGenMdl_d.dll ${LIBDIR}/materialx/bin/MaterialXGenOsl_d.dll ${LIBDIR}/materialx/bin/MaterialXGenShader_d.dll + ${LIBDIR}/materialx/bin/MaterialXRender_d.dll + ${LIBDIR}/materialx/bin/MaterialXRenderHw_d.dll + ${LIBDIR}/materialx/bin/MaterialXRenderGlsl_d.dll DEBUG )