diff --git a/CMakeLists.txt b/CMakeLists.txt index 011c332e54..69826e79b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -573,13 +573,8 @@ if(MATERIALX_BUILD_RENDER) set(MATERIALX_BUILD_RENDER_HW ON) add_subdirectory(source/MaterialXRenderMsl) endif() - if(MATERIALX_BUILD_RENDER_HW) - add_subdirectory(source/MaterialXRenderHw) - endif() - if(MATERIALX_BUILD_GEN_OSL) - add_subdirectory(source/MaterialXRenderOsl) - endif() if(MATERIALX_BUILD_GEN_SLANG AND (MATERIALX_BUILD_RENDER_SLANG OR MATERIALX_SLANG_RHI_SOURCE_DIR)) + set(MATERIALX_BUILD_RENDER_HW ON) if(NOT MATERIALX_SLANG_RHI_SOURCE_DIR) include(FetchContent) FetchContent_Declare( @@ -594,6 +589,12 @@ if(MATERIALX_BUILD_RENDER) endif() add_subdirectory(source/MaterialXRenderSlang) endif() + if(MATERIALX_BUILD_RENDER_HW) + add_subdirectory(source/MaterialXRenderHw) + endif() + if(MATERIALX_BUILD_GEN_OSL) + add_subdirectory(source/MaterialXRenderOsl) + endif() endif() if(MATERIALX_BUILD_VIEWER) add_subdirectory(source/MaterialXView) diff --git a/python/MaterialX/__init__.py b/python/MaterialX/__init__.py index 05348b0a64..7c22956de5 100644 --- a/python/MaterialX/__init__.py +++ b/python/MaterialX/__init__.py @@ -6,18 +6,28 @@ import os import sys if sys.platform == "win32" and sys.version_info >= (3, 8): - import importlib.metadata - try: - importlib.metadata.version('MaterialX') - except importlib.metadata.PackageNotFoundError: - # On a non-pip installation, this file is in %INSTALLDIR%\python\MaterialX - # We need to add %INSTALLDIR%\bin to the DLL path. - mxdir = os.path.dirname(__file__) - pydir = os.path.split(mxdir)[0] - installdir = os.path.split(pydir)[0] - bindir = os.path.join(installdir, "bin") - if os.path.exists(bindir): - os.add_dll_directory(bindir) + _dll_directories = [] + mxdir = os.path.dirname(__file__) + if os.path.exists(mxdir): + try: + _dll_directories.append(os.add_dll_directory(mxdir)) + except (AttributeError, OSError): + pass + # On a non-pip installation or editable install, this file is in %INSTALLDIR%\python\MaterialX + # We need to add %INSTALLDIR%\bin to the DLL path. + pydir = os.path.split(mxdir)[0] + installdir = os.path.split(pydir)[0] + bindir = os.path.join(installdir, "bin") + if os.path.exists(bindir): + try: + _dll_directories.append(os.add_dll_directory(bindir)) + except (AttributeError, OSError): + pass + if "MATERIALX_BIN_DIR" in os.environ and os.path.exists(os.environ["MATERIALX_BIN_DIR"]): + try: + _dll_directories.append(os.add_dll_directory(os.environ["MATERIALX_BIN_DIR"])) + except (AttributeError, OSError): + pass from .main import * diff --git a/source/MaterialXRenderSlang/CMakeLists.txt b/source/MaterialXRenderSlang/CMakeLists.txt index 97136c7d7c..47c4ca1c43 100644 --- a/source/MaterialXRenderSlang/CMakeLists.txt +++ b/source/MaterialXRenderSlang/CMakeLists.txt @@ -8,6 +8,7 @@ mx_add_library(MaterialXRenderSlang ${materialx_headers} MTLX_MODULES MaterialXRender + MaterialXRenderHw EXPORT_DEFINE MATERIALX_RENDERSLANG_EXPORTS SKIP_INSTALL) diff --git a/source/MaterialXRenderSlang/SlangProgram.cpp b/source/MaterialXRenderSlang/SlangProgram.cpp index e30fa12ee7..dad6a87acf 100644 --- a/source/MaterialXRenderSlang/SlangProgram.cpp +++ b/source/MaterialXRenderSlang/SlangProgram.cpp @@ -1013,6 +1013,12 @@ const SlangProgram::UniformInputMap& SlangProgram::updateUniformsList() } } + if (fieldIndex < cursor.m_typeLayout->getFieldCount() && + std::string(cursor.m_typeLayout->getFieldByIndex(fieldIndex)->getName()) == HW::LIGHT_DATA_INSTANCE) + { + ++fieldIndex; + } + if (fieldIndex != cursor.m_typeLayout->getFieldCount()) throw ExceptionRenderError("ShaderCursor has " + std::to_string(cursor.m_typeLayout->getFieldCount()) + " members, while Uniforms have " + std::to_string(fieldIndex) + " ports."); }; diff --git a/source/MaterialXRenderSlang/TextureBaker.h b/source/MaterialXRenderSlang/TextureBaker.h index 47a6e1f138..edf52c3242 100644 --- a/source/MaterialXRenderSlang/TextureBaker.h +++ b/source/MaterialXRenderSlang/TextureBaker.h @@ -17,6 +17,7 @@ #include #include +#include #include MATERIALX_NAMESPACE_BEGIN diff --git a/source/PyMaterialX/CMakeLists.txt b/source/PyMaterialX/CMakeLists.txt index cafbb79245..d46358ee01 100644 --- a/source/PyMaterialX/CMakeLists.txt +++ b/source/PyMaterialX/CMakeLists.txt @@ -66,6 +66,9 @@ if (MATERIALX_BUILD_RENDER) if (APPLE AND MATERIALX_BUILD_GEN_MSL) add_subdirectory(PyMaterialXRenderMsl) endif() + if (MATERIALX_BUILD_RENDER_PLATFORMS AND MATERIALX_BUILD_GEN_SLANG AND (MATERIALX_BUILD_RENDER_SLANG OR MATERIALX_SLANG_RHI_SOURCE_DIR)) + add_subdirectory(PyMaterialXRenderSlang) + endif() endif() if (MATERIALX_BUILD_DOCS) @@ -88,7 +91,7 @@ if (MATERIALX_BUILD_DOCS) foreach(_py_mod IN ITEMS PyMaterialXCore PyMaterialXFormat PyMaterialXGenShader PyMaterialXGenGlsl PyMaterialXGenMsl PyMaterialXGenMdl PyMaterialXGenOsl PyMaterialXRender PyMaterialXRenderGlsl - PyMaterialXRenderOsl PyMaterialXRenderMsl) + PyMaterialXRenderOsl PyMaterialXRenderMsl PyMaterialXRenderSlang) if(TARGET ${_py_mod}) add_dependencies(${_py_mod} PyBindDocs) endif() diff --git a/source/PyMaterialX/PyMaterialXRenderSlang/CMakeLists.txt b/source/PyMaterialX/PyMaterialXRenderSlang/CMakeLists.txt new file mode 100644 index 0000000000..3cb3987e35 --- /dev/null +++ b/source/PyMaterialX/PyMaterialXRenderSlang/CMakeLists.txt @@ -0,0 +1,52 @@ +file(GLOB pymaterialxrenderslang_source "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") +file(GLOB pymaterialxrenderslang_headers "${CMAKE_CURRENT_SOURCE_DIR}/*.h") + +pybind11_add_module(PyMaterialXRenderSlang SHARED ${PYBIND11_MODULE_FLAGS} ${pymaterialxrenderslang_source} ${pymaterialxrenderslang_headers}) + +if(APPLE) + set_target_properties(PyMaterialXRenderSlang PROPERTIES CXX_VISIBILITY_PRESET "default") +endif() + +set_target_properties( + PyMaterialXRenderSlang + PROPERTIES + OUTPUT_NAME PyMaterialXRenderSlang + COMPILE_FLAGS "${EXTERNAL_COMPILE_FLAGS}" + LINK_FLAGS "${EXTERNAL_LINK_FLAGS}" + INSTALL_RPATH "${MATERIALX_UP_TWO_RPATH}" + DEBUG_POSTFIX "${MATERIALX_PYTHON_DEBUG_POSTFIX}") + +target_link_libraries( + PyMaterialXRenderSlang + PUBLIC PyMaterialXRender + MaterialXRenderSlang + MaterialXRenderHw + PyMaterialXGenSlang + MaterialXGenSlang + PRIVATE ${CMAKE_DL_LIBS}) + +install(TARGETS PyMaterialXRenderSlang + DESTINATION "${MATERIALX_PYTHON_FOLDER_NAME}") + +if(WIN32) + # Install slang-rhi runtime DLL dependencies to python package directory + install(FILES + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$/slang.dll + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$/slang-compiler.dll + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$/dxcompiler.dll + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$/dxil.dll + DESTINATION "${MATERIALX_PYTHON_FOLDER_NAME}" + OPTIONAL) +elseif(APPLE) + install(FILES + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/libslang.dylib + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/libslang-compiler.dylib + DESTINATION "${MATERIALX_PYTHON_FOLDER_NAME}" + OPTIONAL) +else() + install(FILES + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/libslang.so + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/libslang-compiler.so + DESTINATION "${MATERIALX_PYTHON_FOLDER_NAME}" + OPTIONAL) +endif() diff --git a/source/PyMaterialX/PyMaterialXRenderSlang/PyModule.cpp b/source/PyMaterialX/PyMaterialXRenderSlang/PyModule.cpp new file mode 100644 index 0000000000..48645718d3 --- /dev/null +++ b/source/PyMaterialX/PyMaterialXRenderSlang/PyModule.cpp @@ -0,0 +1,26 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +namespace py = pybind11; + +void bindPySlangProgram(py::module& mod); +void bindPySlangRenderer(py::module& mod); +void bindPySlangTextureHandler(py::module& mod); +void bindPyTextureBaker(py::module& mod); + +PYBIND11_MODULE(PyMaterialXRenderSlang, mod) +{ + mod.doc() = "Rendering support for the Slang shading language."; + + // PyMaterialXRenderSlang depends on types defined in PyMaterialXRender + PYMATERIALX_IMPORT_MODULE(PyMaterialXRender); + + bindPySlangProgram(mod); + bindPySlangRenderer(mod); + bindPySlangTextureHandler(mod); + bindPyTextureBaker(mod); +} diff --git a/source/PyMaterialX/PyMaterialXRenderSlang/PySlangProgram.cpp b/source/PyMaterialX/PyMaterialXRenderSlang/PySlangProgram.cpp new file mode 100644 index 0000000000..14f3772882 --- /dev/null +++ b/source/PyMaterialX/PyMaterialXRenderSlang/PySlangProgram.cpp @@ -0,0 +1,33 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include + +namespace py = pybind11; +namespace mx = MaterialX; + +void bindPySlangProgram(py::module& mod) +{ + py::class_(mod, "SlangProgram") + .def("setStages", &mx::SlangProgram::setStages) + .def("addStage", &mx::SlangProgram::addStage) + .def("getStageSourceCode", &mx::SlangProgram::getStageSourceCode) + .def("clearStages", &mx::SlangProgram::clearStages) + .def("getShader", &mx::SlangProgram::getShader) + .def("build", &mx::SlangProgram::build) + .def("hasUniform", &mx::SlangProgram::hasUniform) + .def("bindUniform", &mx::SlangProgram::bindUniform, + py::arg("name"), py::arg("value"), py::arg("errorIfMissing") = true) + .def("bindMesh", static_cast(&mx::SlangProgram::bindMesh)) + .def("unbindGeometry", &mx::SlangProgram::unbindGeometry) + .def("bindTextures", &mx::SlangProgram::bindTextures) + .def("bindLighting", &mx::SlangProgram::bindLighting) + .def("bindViewInformation", &mx::SlangProgram::bindViewInformation) + .def("bindTimeAndFrame", &mx::SlangProgram::bindTimeAndFrame, + py::arg("time") = 0.0f, py::arg("frame") = 1.0f) + .def("unbind", &mx::SlangProgram::unbind); +} diff --git a/source/PyMaterialX/PyMaterialXRenderSlang/PySlangRenderer.cpp b/source/PyMaterialX/PyMaterialXRenderSlang/PySlangRenderer.cpp new file mode 100644 index 0000000000..ab95426716 --- /dev/null +++ b/source/PyMaterialX/PyMaterialXRenderSlang/PySlangRenderer.cpp @@ -0,0 +1,30 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include + +namespace py = pybind11; +namespace mx = MaterialX; + +void bindPySlangRenderer(py::module& mod) +{ + py::class_(mod, "SlangRenderer") + .def_static("create", &mx::SlangRenderer::create, + py::arg("width") = 512, py::arg("height") = 512, py::arg("baseType") = mx::Image::BaseType::UINT8) + .def("initialize", &mx::SlangRenderer::initialize, py::arg("renderContextHandle") = nullptr) + .def("createImageHandler", &mx::SlangRenderer::createImageHandler, + py::arg("imageLoader") = nullptr) + .def("createProgram", static_cast(&mx::SlangRenderer::createProgram)) + .def("createProgram", static_cast(&mx::SlangRenderer::createProgram)) + .def("validateInputs", &mx::SlangRenderer::validateInputs) + .def("render", &mx::SlangRenderer::render) + .def("renderTextureSpace", &mx::SlangRenderer::renderTextureSpace, + py::arg("uvMin") = mx::Vector2(0.0f, 0.0f), py::arg("uvMax") = mx::Vector2(1.0f, 1.0f)) + .def("captureImage", &mx::SlangRenderer::captureImage, + py::arg("image") = nullptr) + .def("getProgram", &mx::SlangRenderer::getProgram); +} diff --git a/source/PyMaterialX/PyMaterialXRenderSlang/PySlangTextureHandler.cpp b/source/PyMaterialX/PyMaterialXRenderSlang/PySlangTextureHandler.cpp new file mode 100644 index 0000000000..58d8272870 --- /dev/null +++ b/source/PyMaterialX/PyMaterialXRenderSlang/PySlangTextureHandler.cpp @@ -0,0 +1,22 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include + +namespace py = pybind11; +namespace mx = MaterialX; + +void bindPySlangTextureHandler(py::module& mod) +{ + py::class_(mod, "SlangTextureHandler") + .def("bindImage", static_cast(&mx::SlangTextureHandler::bindImage)) + .def("unbindImage", &mx::SlangTextureHandler::unbindImage) + .def("createRenderResources", &mx::SlangTextureHandler::createRenderResources, + py::arg("image"), py::arg("generateMipMaps") = true, py::arg("useAsRenderTarget") = false) + .def("releaseRenderResources", &mx::SlangTextureHandler::releaseRenderResources, + py::arg("image") = nullptr); +} diff --git a/source/PyMaterialX/PyMaterialXRenderSlang/PyTextureBaker.cpp b/source/PyMaterialX/PyMaterialXRenderSlang/PyTextureBaker.cpp new file mode 100644 index 0000000000..1c58ae119d --- /dev/null +++ b/source/PyMaterialX/PyMaterialXRenderSlang/PyTextureBaker.cpp @@ -0,0 +1,47 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#include + +#include +#include + +namespace py = pybind11; +namespace mx = MaterialX; + +void bindPyTextureBaker(py::module& mod) +{ + py::class_(mod, "TextureBaker") + .def_static("create", &mx::TextureBakerSlang::create) + .def("setExtension", &mx::TextureBakerSlang::setExtension) + .def("getExtension", &mx::TextureBakerSlang::getExtension) + .def("setColorSpace", &mx::TextureBakerSlang::setColorSpace) + .def("getColorSpace", &mx::TextureBakerSlang::getColorSpace) + .def("setDistanceUnit", &mx::TextureBakerSlang::setDistanceUnit) + .def("getDistanceUnit", &mx::TextureBakerSlang::getDistanceUnit) + .def("setAverageImages", &mx::TextureBakerSlang::setAverageImages) + .def("getAverageImages", &mx::TextureBakerSlang::getAverageImages) + .def("setOptimizeConstants", &mx::TextureBakerSlang::setOptimizeConstants) + .def("getOptimizeConstants", &mx::TextureBakerSlang::getOptimizeConstants) + .def("setOutputImagePath", &mx::TextureBakerSlang::setOutputImagePath) + .def("getOutputImagePath", &mx::TextureBakerSlang::getOutputImagePath) + .def("setBakedGraphName", &mx::TextureBakerSlang::setBakedGraphName) + .def("getBakedGraphName", &mx::TextureBakerSlang::getBakedGraphName) + .def("setBakedGeomInfoName", &mx::TextureBakerSlang::setBakedGeomInfoName) + .def("getBakedGeomInfoName", &mx::TextureBakerSlang::getBakedGeomInfoName) + .def("setTextureFilenameTemplate", &mx::TextureBakerSlang::setTextureFilenameTemplate) + .def("getTextureFilenameTemplate", &mx::TextureBakerSlang::getTextureFilenameTemplate) + .def("setFilenameTemplateVarOverride", &mx::TextureBakerSlang::setFilenameTemplateVarOverride) + .def("setHashImageNames", &mx::TextureBakerSlang::setHashImageNames) + .def("getHashImageNames", &mx::TextureBakerSlang::getHashImageNames) + .def("setTextureSpaceMin", &mx::TextureBakerSlang::setTextureSpaceMin) + .def("getTextureSpaceMin", &mx::TextureBakerSlang::getTextureSpaceMin) + .def("setTextureSpaceMax", &mx::TextureBakerSlang::setTextureSpaceMax) + .def("getTextureSpaceMax", &mx::TextureBakerSlang::getTextureSpaceMax) + .def("setupUnitSystem", &mx::TextureBakerSlang::setupUnitSystem) + .def("bakeMaterialToDoc", &mx::TextureBakerSlang::bakeMaterialToDoc) + .def("bakeAllMaterials", &mx::TextureBakerSlang::bakeAllMaterials) + .def("writeDocumentPerMaterial", &mx::TextureBakerSlang::writeDocumentPerMaterial); +}