diff --git a/CMake b/CMake index 3818effff1..d6c5410071 160000 --- a/CMake +++ b/CMake @@ -1 +1 @@ -Subproject commit 3818effff171f863d0c23e6fbbf79911f03cc6d3 +Subproject commit d6c5410071cfc8958b4084394a2715fd2dd40c6e diff --git a/CMakePresets.json b/CMakePresets.json index 6aa86b3807..1bd4aabf26 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -56,6 +56,17 @@ "CMAKE_BUILD_TYPE": "Release" } }, + { + "name": "user-osx", + "displayName": "Castor3D User OSX Ninja Config", + "description": "Build configuration using Ninja, on OSX, for Castor3D users", + "inherits": "user-base", + "generator": "Ninja", + "cacheVariables": { + "VCPKG_MANIFEST_FEATURES": "assimp;freeimage;glsl;gltf;vkfft;tools", + "CMAKE_BUILD_TYPE": "Release" + } + }, { "name": "dev-base", "hidden": true, @@ -67,7 +78,6 @@ "CASTOR_BUILDGRP_INTEROP": false, "CASTOR_BUILDGRP_TEST": true, "CASTOR_BUILDGRP_TOOL": true, - "CASTOR_DEBUG_TARGETS": true, "CASTOR_DISABLE_DELAYED_INITIALISATION": true, "CASTOR_FORCE_VCPKG_SUBMODULES": false, "CASTOR_GUICOMMON_NEEDS_HLSL": true, @@ -157,6 +167,73 @@ "CMAKE_BUILD_TYPE": "Release" } }, + { + "name": "dev-osx-base", + "hidden": true, + "generator": "Ninja", + "installDir": "${sourceDir}/package/Castor3D", + "cacheVariables": { + "VCPKG_MANIFEST_FEATURES": "assimp;freeimage;glsl;gltf;vkfft;tools", + "CASTOR_BUILD_PLUGINS": true, + "CASTOR_BUILDGRP_DEMO": true, + "CASTOR_BUILDGRP_INTEROP": false, + "CASTOR_BUILDGRP_TEST": false, + "CASTOR_BUILDGRP_TOOL": true, + "CASTOR_FORCE_VCPKG_SUBMODULES": false, + "CASTOR_GUICOMMON_NEEDS_HLSL": true, + "CASTOR_USE_GLSLANG": true, + "CASTOR_USE_MESH_SHADERS": false, + "CASTOR_USE_TASK_SHADERS": false, + "PROJECTS_UNITY_BUILD": false, + "PROJECTS_USE_PRECOMPILED_HEADERS": true + } + }, + { + "name": "dev-osx-debug", + "displayName": "Castor3D Developer OSX Config, Debug", + "description": "Build configuration using Ninja, for Castor3D developers, OSX Debug", + "inherits": "dev-osx-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "dev-osx-release", + "displayName": "Castor3D Developer OSX Config, Release", + "description": "Build configuration using Ninja, for Castor3D developers, OSX Release", + "inherits": "dev-osx-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "dev-osx-vcpkg-base", + "inherits": "dev-osx-base", + "hidden": true, + "cacheVariables": { + "PROJECTS_UNITY_BUILD": false, + "VCPKG_MANIFEST_FEATURES": "assimp;freeimage;glsl;gltf;vkfft;tools", + "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/external/vcpkg/scripts/buildsystems/vcpkg.cmake" + } + }, + { + "name": "dev-osx-vcpkg-debug", + "displayName": "Castor3D Developer OSX Config, using vcpkg, Debug", + "description": "Build configuration using Ninja, for Castor3D developers, OSX Debug", + "inherits": "dev-osx-vcpkg-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "dev-osx-vcpkg-release", + "displayName": "Castor3D Developer OSX Config, using vcpkg, Release", + "description": "Build configuration using Ninja, for Castor3D developers,OSX Release", + "inherits": "dev-osx-vcpkg-base", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, { "name": "ci-vcpkg-base", "installDir": "${sourceDir}/package/Castor3D", diff --git a/data/vcpkg/ports/ashes/portfile.cmake b/data/vcpkg/ports/ashes/portfile.cmake index 8548e6d6bf..a0212bafef 100644 --- a/data/vcpkg/ports/ashes/portfile.cmake +++ b/data/vcpkg/ports/ashes/portfile.cmake @@ -3,9 +3,9 @@ vcpkg_check_linkage(ONLY_DYNAMIC_LIBRARY) vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH REPO DragonJoker/Ashes - REF 96bbc7756b88f58dfc49b4305edad6f1078bbc90 + REF 8511d0d68b6f16a45de17222899e24b7fc1cd8b0 HEAD_REF master - SHA512 22d57ef346d2b514e832597f35bfa59d1b21186200b301cba80117c0fd39220b4633fbec583f58e1ea3c6c0ca7d1039c1ac4e1bff36b3b71165196e134c3b5f4 + SHA512 cc0ddbc0969d4dc35f5ebca37ab2b1a8d50ecf99e78196c47f5c9badd86e3292280dbf946da8b1b38cddecfd62952d6a730b89ee9c304633e71b9a969e295f48 ) vcpkg_from_github( diff --git a/data/vcpkg/ports/castor3d/portfile.cmake b/data/vcpkg/ports/castor3d/portfile.cmake index 5a1c6ff357..6894ed22a6 100644 --- a/data/vcpkg/ports/castor3d/portfile.cmake +++ b/data/vcpkg/ports/castor3d/portfile.cmake @@ -23,6 +23,7 @@ vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS assimp CASTOR_BUILD_IMPORTER_ASSIMP freeimage CASTOR_USE_FREEIMAGE glsl CASTOR_C3D_NEEDS_GLSL + gltf CASTOR_BUILD_IMPORTER_GLTF vkfft CASTOR_HAS_VKFFT ) @@ -34,7 +35,6 @@ vcpkg_cmake_configure( -DCASTOR_BUILDGRP_INTEROP=OFF -DCASTOR_BUILDGRP_TEST=OFF -DCASTOR_BUILDGRP_TOOL=OFF - -DCASTOR_DISABLE_DELAYED_INITIALISATION=ON -DCASTOR_USE_GLSLANG=ON -DCASTOR_USE_MESH_SHADERS=OFF -DCASTOR_USE_TASK_SHADERS=OFF diff --git a/data/vcpkg/ports/castor3d/vcpkg.json b/data/vcpkg/ports/castor3d/vcpkg.json index 79858e87f9..3608daf950 100644 --- a/data/vcpkg/ports/castor3d/vcpkg.json +++ b/data/vcpkg/ports/castor3d/vcpkg.json @@ -10,6 +10,7 @@ "freetype", "gli", "meshoptimizer", + "mikktspace", "minizip", "rendergraph", { @@ -28,12 +29,14 @@ "name": "vcpkg-cmake-config", "host": true }, + "vulkan-headers", "zlib" ], "default-features": [ "assimp", "freeimage", "glsl", + "gltf", "vkfft" ], "features": { @@ -56,6 +59,13 @@ "spirv-cross" ] }, + "gltf": { + "description": "Use fastgltf library to import glTF scenes.", + "dependencies": [ + "fastgltf", + "simdjson" + ] + }, "vkfft": { "description": "Use VkFFT to compute Fast Fourier Transforms (Necessary for FFTOcean plugin).", "dependencies": [ diff --git a/data/vcpkg/ports/draco/install-linkage.diff b/data/vcpkg/ports/draco/install-linkage.diff new file mode 100644 index 0000000000..c34a60f11c --- /dev/null +++ b/data/vcpkg/ports/draco/install-linkage.diff @@ -0,0 +1,19 @@ +diff --git a/cmake/draco_install.cmake b/cmake/draco_install.cmake +index 3be1ba1..b91938c 100644 +--- a/cmake/draco_install.cmake ++++ b/cmake/draco_install.cmake +@@ -65,10 +65,14 @@ macro(draco_setup_install_target) + ARCHIVE DESTINATION "${libs_path}" + LIBRARY DESTINATION "${libs_path}") + else() ++ if(BUILD_SHARED_LIBS) ++ set_target_properties(draco_static PROPERTIES EXCLUDE_FROM_ALL 1) ++ else() + install( + TARGETS draco_static + EXPORT dracoExport + DESTINATION "${libs_path}") ++ endif() + + if(BUILD_SHARED_LIBS) + install( diff --git a/data/vcpkg/ports/draco/portfile.cmake b/data/vcpkg/ports/draco/portfile.cmake index 9eebf32421..7c6bc8c986 100644 --- a/data/vcpkg/ports/draco/portfile.cmake +++ b/data/vcpkg/ports/draco/portfile.cmake @@ -1,5 +1,3 @@ -vcpkg_check_linkage(ONLY_STATIC_LIBRARY) - vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH REPO google/draco @@ -12,24 +10,28 @@ vcpkg_from_github( fix-pkgconfig.patch fix-regex.patch disable-symlinks.patch + install-linkage.diff ) +if(VCPKG_TARGET_IS_EMSCRIPTEN) + set(ENV{EMSCRIPTEN} "${EMSCRIPTEN_ROOT}") +endif() + vcpkg_cmake_configure( SOURCE_PATH "${SOURCE_PATH}" + OPTIONS + -DPYTHON_EXECUTABLE=: # unused with DRACO_JS_GLUE off + -DDRACO_JS_GLUE=OFF ) vcpkg_cmake_install() - -vcpkg_cmake_config_fixup(CONFIG_PATH share/cmake/${PORT}) +vcpkg_cmake_config_fixup(CONFIG_PATH share/cmake/draco) vcpkg_fixup_pkgconfig() # Install tools and plugins -vcpkg_copy_tools( - TOOL_NAMES - draco_encoder - draco_decoder - AUTO_CLEAN -) +if(NOT VCPKG_TARGET_IS_EMSCRIPTEN) + vcpkg_copy_tools(TOOL_NAMES draco_encoder draco_decoder AUTO_CLEAN) +endif() file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include" "${CURRENT_PACKAGES_DIR}/debug/share") diff --git a/data/vcpkg/ports/draco/vcpkg.json b/data/vcpkg/ports/draco/vcpkg.json index 636f863eaa..8304f2b728 100644 --- a/data/vcpkg/ports/draco/vcpkg.json +++ b/data/vcpkg/ports/draco/vcpkg.json @@ -1,6 +1,7 @@ { "name": "draco", "version": "1.5.6", + "port-version": 1, "description": " A library for compressing and decompressing 3D geometric meshes and point clouds. It is intended to improve the storage and transmission of 3D graphics.", "homepage": "https://github.com/google/draco", "license": "Apache-2.0", diff --git a/data/vcpkg/ports/fastgltf/fix_uri_escape_spaces.patch b/data/vcpkg/ports/fastgltf/fix_uri_escape_spaces.patch index bb9a8a79c4..5a295d6798 100644 --- a/data/vcpkg/ports/fastgltf/fix_uri_escape_spaces.patch +++ b/data/vcpkg/ports/fastgltf/fix_uri_escape_spaces.patch @@ -1,24 +1,14 @@ diff --git a/src/fastgltf.cpp b/src/fastgltf.cpp -index 9244fe1..f968f59 100644 +index 775c9bd..7cd12d0 100644 --- a/src/fastgltf.cpp +++ b/src/fastgltf.cpp -@@ -1487,7 +1487,8 @@ fg::Error fg::Parser::parseBuffers(simdjson::dom::array& buffers, Asset& asset) +@@ -1733,7 +1733,8 @@ fg::Error fg::Parser::parseBuffers(simdjson::dom::array& buffers, Asset& asset) // file. Otherwise, data must be specified in the "uri" field. std::string_view uriString; - if (bufferObject["uri"].get_string().get(uriString) == SUCCESS) { + if (bufferObject["uri"].get_string().get(uriString) == SUCCESS) FASTGLTF_LIKELY { - URIView uriView(uriString); + fg::URI uri(uriString); + fg::URIView uriView(uri.string()); if (!uriView.valid()) { return Error::InvalidURI; -@@ -1821,7 +1822,8 @@ fg::Error fg::Parser::parseImages(simdjson::dom::array& images, Asset& asset) { - return Error::InvalidGltf; - } - -- URIView uriView(uriString); -+ fg::URI uri(uriString); -+ fg::URIView uriView(uri.string()); - if (!uriView.valid()) { - return Error::InvalidURI; - } diff --git a/data/vcpkg/ports/fastgltf/portfile.cmake b/data/vcpkg/ports/fastgltf/portfile.cmake index a974d979c2..47ae543053 100644 --- a/data/vcpkg/ports/fastgltf/portfile.cmake +++ b/data/vcpkg/ports/fastgltf/portfile.cmake @@ -1,21 +1,25 @@ vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH REPO spnda/fastgltf - REF 46f28f1355657c42c9f73bfcdde4ba37d05c2a2f - SHA512 8e26d8d8061a4416d0c2d934a74e8569d3d60db9f01fa7eeae9b251b61e151941c569ea8da70050746e241ca2f0cb4ff14809701f7247f9f31a8538ae28f5c3c + REF "v${VERSION}" + SHA512 66be8e5a05210d023ec5e47dd3aa721b3cf98428bd00e227007cfc97fda35c669b5e8b82254d26c6ce2254297d16fd7a5f6bbbf3da17432df09186091d1ae351 HEAD_REF main - PATCHES find_package.patch - fix_uri_escape_spaces.patch + PATCHES fix_uri_escape_spaces.patch ) vcpkg_cmake_configure( SOURCE_PATH "${SOURCE_PATH}" - OPTIONS -DFASTGLTF_DOWNLOAD_SIMDJSON=OFF - -DFASTGLTF_ENABLE_DEPRECATED_EXT=ON + OPTIONS -DFASTGLTF_ENABLE_DEPRECATED_EXT=ON ) vcpkg_cmake_install() vcpkg_cmake_config_fixup(CONFIG_PATH lib/cmake/${PORT}) vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE.md") vcpkg_copy_pdbs() +file(READ "${CURRENT_PACKAGES_DIR}/share/fastgltf/fastgltfConfig.cmake" contents) +file(WRITE "${CURRENT_PACKAGES_DIR}/share/fastgltf/fastgltfConfig.cmake" " +include(CMakeFindDependencyMacro) +find_dependency(simdjson) +${contents}") + file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include") diff --git a/data/vcpkg/ports/fastgltf/vcpkg.json b/data/vcpkg/ports/fastgltf/vcpkg.json index febb0b262b..96f5c953bb 100644 --- a/data/vcpkg/ports/fastgltf/vcpkg.json +++ b/data/vcpkg/ports/fastgltf/vcpkg.json @@ -1,7 +1,8 @@ { "name": "fastgltf", - "version": "0.5.0", - "description": "Blazing fast C++17 glTF 2.0 loader powered by SIMD", + "version": "0.7.0", + "port-version": 1, + "description": "A modern C++17 glTF 2.0 library focused on speed, correctness, and usability", "homepage": "https://github.com/spnda/fastgltf", "license": "MIT", "dependencies": [ diff --git a/data/vcpkg/ports/rendergraph/portfile.cmake b/data/vcpkg/ports/rendergraph/portfile.cmake index edb2a7364c..9267a9c560 100644 --- a/data/vcpkg/ports/rendergraph/portfile.cmake +++ b/data/vcpkg/ports/rendergraph/portfile.cmake @@ -1,8 +1,8 @@ vcpkg_from_github(OUT_SOURCE_PATH SOURCE_PATH REPO DragonJoker/RenderGraph - REF 8fb5f892c9ca495c9e4b9c1161c85e8119866afc + REF b65f85a7260115493065dd475c4f2ebc6a4b15ee HEAD_REF master - SHA512 c618c57a1012ae3929261ed4bac2e58e721c65f91452435bcf85d1e5a2ea176b76609a5163d03a03bec699b7845f1bc0cc9d5253fe43fbeadf552fb6ed75437a + SHA512 87bfeae31d356c4e63162755f00fa2c695fc9b777e770820b631741ec5b8551e5bf481a51aaf55825b47a0bed6fc6c26ff1389c58ee2dd6366438697d13ed7c2 ) vcpkg_from_github(OUT_SOURCE_PATH CMAKE_SOURCE_PATH diff --git a/data/vcpkg/ports/shaderwriter/portfile.cmake b/data/vcpkg/ports/shaderwriter/portfile.cmake index 81b1f821cd..98ce109825 100644 --- a/data/vcpkg/ports/shaderwriter/portfile.cmake +++ b/data/vcpkg/ports/shaderwriter/portfile.cmake @@ -2,9 +2,9 @@ vcpkg_minimum_required(VERSION 2022-10-12) # for ${VERSION} vcpkg_from_github(OUT_SOURCE_PATH SOURCE_PATH REPO DragonJoker/ShaderWriter - REF 4bc7a7cb6578631eccfa9fadc94a227356f27b70 + REF fec73e97439f14e5b28975cd621803219495b94f HEAD_REF development - SHA512 29e9db9021cb965b5760d5bfa866f41d3a47128bc4f7d602468a0697491413920c24ee6944728960f003b6ce89afc164659b489d763aaa118c98063ff0e20341 + SHA512 df944a49521dc99ece55edc1acec953bed52dd82055e4cb616ef5c0ca6a459c3f2a35e63200e3b3d01f467327d3edfa18ededb00368c2a1669a7f4d6441969f4 ) vcpkg_from_github(OUT_SOURCE_PATH CMAKE_SOURCE_PATH diff --git a/data/vcpkg/ports/vkfft/portfile.cmake b/data/vcpkg/ports/vkfft/portfile.cmake deleted file mode 100644 index ab9283298e..0000000000 --- a/data/vcpkg/ports/vkfft/portfile.cmake +++ /dev/null @@ -1,12 +0,0 @@ -# header-only library -vcpkg_from_github( - OUT_SOURCE_PATH SOURCE_PATH - REPO DTolm/VkFFT - REF e1c58868a9581725dd595975daf780da0a37dad1 #v1.2.31 - SHA512 b113f0117336ef2f6a285166cb4d68ea372e0dbb46025b7fcbae30f4f5147ad0fb1f7abfd91e1a73e2b4d72446c16ac0e90efc467785e035f176e81d95979706 - HEAD_REF master -) - -file(COPY "${SOURCE_PATH}/vkFFT/" DESTINATION "${CURRENT_PACKAGES_DIR}/include/VkFFT") - -file(INSTALL "${SOURCE_PATH}/LICENSE" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright) diff --git a/data/vcpkg/ports/vkfft/vcpkg.json b/data/vcpkg/ports/vkfft/vcpkg.json deleted file mode 100644 index 6c4076fe48..0000000000 --- a/data/vcpkg/ports/vkfft/vcpkg.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "vkfft", - "version": "1.2.31", - "description": "Vulkan/CUDA/HIP/OpenCL/Level Zero Fast Fourier Transform library", - "homepage": "https://github.com/DTolm/VkFFT", - "license": "MIT" -} diff --git a/external/Ashes b/external/Ashes index 96bbc7756b..8511d0d68b 160000 --- a/external/Ashes +++ b/external/Ashes @@ -1 +1 @@ -Subproject commit 96bbc7756b88f58dfc49b4305edad6f1078bbc90 +Subproject commit 8511d0d68b6f16a45de17222899e24b7fc1cd8b0 diff --git a/external/RenderGraph b/external/RenderGraph index 8fb5f892c9..b65f85a726 160000 --- a/external/RenderGraph +++ b/external/RenderGraph @@ -1 +1 @@ -Subproject commit 8fb5f892c9ca495c9e4b9c1161c85e8119866afc +Subproject commit b65f85a7260115493065dd475c4f2ebc6a4b15ee diff --git a/external/ShaderWriter b/external/ShaderWriter index 4bc7a7cb65..fec73e9743 160000 --- a/external/ShaderWriter +++ b/external/ShaderWriter @@ -1 +1 @@ -Subproject commit 4bc7a7cb6578631eccfa9fadc94a227356f27b70 +Subproject commit fec73e97439f14e5b28975cd621803219495b94f diff --git a/external/vcpkg b/external/vcpkg index 3b21386457..13bde2ff13 160000 --- a/external/vcpkg +++ b/external/vcpkg @@ -1 +1 @@ -Subproject commit 3b213864579b6fa686e38715508f7cd41a50900f +Subproject commit 13bde2ff13192e1b2fdd37bd9b475c7665ae6ae5 diff --git a/include/Core/Castor3D/Castor3DPch.hpp b/include/Core/Castor3D/Castor3DPch.hpp index 668c4099f6..5772128e99 100644 --- a/include/Core/Castor3D/Castor3DPch.hpp +++ b/include/Core/Castor3D/Castor3DPch.hpp @@ -19,7 +19,6 @@ See LICENSE file in root folder #include #include #include -#include #include #include #include @@ -93,6 +92,7 @@ See LICENSE file in root folder #include #include +#include #include #include @@ -199,4 +199,6 @@ See LICENSE file in root folder #include #include +#include + #endif diff --git a/include/Core/Castor3D/Material/Pass/Component/ComponentModule.hpp b/include/Core/Castor3D/Material/Pass/Component/ComponentModule.hpp index c6244beb27..0864e20668 100644 --- a/include/Core/Castor3D/Material/Pass/Component/ComponentModule.hpp +++ b/include/Core/Castor3D/Material/Pass/Component/ComponentModule.hpp @@ -13,6 +13,7 @@ See LICENSE file in root folder #include #include +#include #define C3D_PluginMakePassComponentName( p, x ) C3D_Join3Strings( cuT( p ), cuT( "pass" ), cuT( x ) ) #define C3D_MakePassComponentName( x ) C3D_PluginMakePassComponentName( "c3d", x ) @@ -541,8 +542,17 @@ namespace castor3d namespace shader { struct BlendComponents; - struct SurfaceBase; class Utils; + + template< typename ValueT, sdw::StringLiteralT StructNameT > + struct DerivativeValueT; + template< typename Position3T, typename Position4T, typename NormalT > + struct SurfaceBaseT; + + using DerivVec3 = DerivativeValueT< sdw::Vec3, "C3D_DerivVec3" >; + using DerivVec4 = DerivativeValueT< sdw::Vec4, "C3D_DerivVec4" >; + using SurfaceBase = SurfaceBaseT< sdw::Vec3, sdw::Vec4, sdw::Vec3 >; + using DerivSurfaceBase = SurfaceBaseT< DerivVec3, DerivVec4, DerivVec3 >; /** \~english \brief Base class for all component shaders. @@ -648,7 +658,7 @@ namespace castor3d , TextureCombine const & combine , shader::BlendComponents & components , bool isFrontCulled ) >; - using FinishComponent = castor::Function< void( shader::SurfaceBase const & surface + using FinishComponent = castor::Function< void( shader::DerivSurfaceBase const & surface , sdw::Vec3 const worldEye , shader::Utils & utils , shader::BlendComponents & components ) >; diff --git a/include/Core/Castor3D/Material/Pass/Component/Lighting/IridescenceComponent.hpp b/include/Core/Castor3D/Material/Pass/Component/Lighting/IridescenceComponent.hpp index accd6c4567..5bf5623427 100644 --- a/include/Core/Castor3D/Material/Pass/Component/Lighting/IridescenceComponent.hpp +++ b/include/Core/Castor3D/Material/Pass/Component/Lighting/IridescenceComponent.hpp @@ -93,7 +93,7 @@ namespace castor3d } private: - static void finishComponent( shader::SurfaceBase const & surface + static void finishComponent( shader::DerivSurfaceBase const & surface , sdw::Vec3 const worldEye , shader::Utils & utils , shader::BlendComponents & components ); diff --git a/include/Core/Castor3D/Material/Pass/Pass.hpp b/include/Core/Castor3D/Material/Pass/Pass.hpp index f2349ef655..dc4df68caa 100644 --- a/include/Core/Castor3D/Material/Pass/Pass.hpp +++ b/include/Core/Castor3D/Material/Pass/Pass.hpp @@ -36,8 +36,15 @@ namespace castor3d class Pass : public castor::OwnedBy< Material > { + private: friend struct PassComponent; + C3D_API Pass( Material & parent + , LightingModelID lightingModelId + , RenderPassRegisterInfo * renderPassInfo + , bool implicit = false + , bool automaticShader = true ); + public: using UnitArray = castor::Vector< TextureUnitRPtr >; using PassTextureSource = castor::Pair< TextureSourceInfo, PassTextureConfig >; @@ -53,7 +60,7 @@ namespace castor3d *\param[in] parent Le matériau parent. *\param[in] lightingModelId L'ID du modèle d'éclairage du matériau. */ - C3D_API explicit Pass( Material & parent + C3D_API Pass( Material & parent , LightingModelID lightingModelId ); /** *\~english @@ -487,8 +494,8 @@ namespace castor3d * Mutateurs. */ /**@{*/ - C3D_API void enableLighting( bool value ); - C3D_API void enablePicking( bool value ); + C3D_API void enableLighting( bool value )const; + C3D_API void enablePicking( bool value )const; void setId( uint32_t value )noexcept { diff --git a/include/Core/Castor3D/Material/Pass/Shaders/GlslPbrLighting.hpp b/include/Core/Castor3D/Material/Pass/Shaders/GlslPbrLighting.hpp index 551b45e53c..97861deb09 100644 --- a/include/Core/Castor3D/Material/Pass/Shaders/GlslPbrLighting.hpp +++ b/include/Core/Castor3D/Material/Pass/Shaders/GlslPbrLighting.hpp @@ -40,7 +40,6 @@ namespace castor3d::shader protected: C3D_API void doFinish( PassShaders const & passShaders - , RasterizerSurfaceBase const & surface , BlendComponents & components )override; C3D_API sdw::Vec3 doComputeDiffuseTerm( sdw::Vec3 const & radiance , sdw::Float const & intensity diff --git a/include/Core/Castor3D/Material/Pass/Shaders/GlslPhongLighting.hpp b/include/Core/Castor3D/Material/Pass/Shaders/GlslPhongLighting.hpp index e6f69897d9..90e51469e4 100644 --- a/include/Core/Castor3D/Material/Pass/Shaders/GlslPhongLighting.hpp +++ b/include/Core/Castor3D/Material/Pass/Shaders/GlslPhongLighting.hpp @@ -38,7 +38,6 @@ namespace castor3d::shader protected: C3D_API void doFinish( PassShaders const & passShaders - , RasterizerSurfaceBase const & surface , BlendComponents & components )override; C3D_API sdw::Vec3 doComputeDiffuseTerm( sdw::Vec3 const & radiance , sdw::Float const & intensity diff --git a/include/Core/Castor3D/Material/Texture/Sampler.hpp b/include/Core/Castor3D/Material/Texture/Sampler.hpp index 477d859b19..d018b39c06 100644 --- a/include/Core/Castor3D/Material/Texture/Sampler.hpp +++ b/include/Core/Castor3D/Material/Texture/Sampler.hpp @@ -25,7 +25,8 @@ namespace castor3d , VkSamplerMipmapMode mipFilter , VkSamplerAddressMode U , VkSamplerAddressMode V - , VkSamplerAddressMode W ); + , VkSamplerAddressMode W + , VkBorderColor borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK ); class Sampler : public castor::Named diff --git a/include/Core/Castor3D/Model/Mesh/MeshModule.hpp b/include/Core/Castor3D/Model/Mesh/MeshModule.hpp index e0f6da8350..1e8f0776d0 100644 --- a/include/Core/Castor3D/Model/Mesh/MeshModule.hpp +++ b/include/Core/Castor3D/Model/Mesh/MeshModule.hpp @@ -124,6 +124,7 @@ namespace castor3d struct MeshletDrawConstants { uint32_t pipelineId; + uint32_t drawId; uint32_t drawOffset; uint32_t meshletOffset; }; diff --git a/include/Core/Castor3D/Render/Node/QueueRenderNodes.hpp b/include/Core/Castor3D/Render/Node/QueueRenderNodes.hpp index d86d3c025b..169af5813e 100644 --- a/include/Core/Castor3D/Render/Node/QueueRenderNodes.hpp +++ b/include/Core/Castor3D/Render/Node/QueueRenderNodes.hpp @@ -123,6 +123,11 @@ namespace castor3d void doAddBillboard( CulledNodeT< BillboardRenderNode > const & node ); void doRemoveSubmesh( CulledNodeT< SubmeshRenderNode > const & node ); void doRemoveBillboard( CulledNodeT< BillboardRenderNode > const & node ); + uint32_t doPrepareMeshTraditionalNoDrawIDCommandBuffers( ashes::CommandBuffer const & commandBuffer + , ashes::Optional< VkViewport > const & viewport + , ashes::Optional< VkRect2D > const & scissors + , PipelineNodes * nodesIdsBuffer + , VkDeviceSize maxNodesCount ); uint32_t doPrepareMeshTraditionalCommandBuffers( ashes::CommandBuffer const & commandBuffer , ashes::Optional< VkViewport > const & viewport , ashes::Optional< VkRect2D > const & scissors @@ -142,6 +147,11 @@ namespace castor3d , PipelineNodes * nodesIdsBuffer , VkDeviceSize maxNodesCount ); #endif + uint32_t doPrepareBillboardNoDrawIDCommandBuffers( ashes::CommandBuffer const & commandBuffer + , ashes::Optional< VkViewport > const & viewport + , ashes::Optional< VkRect2D > const & scissors + , PipelineNodes * nodesIdsBuffer + , VkDeviceSize maxNodesCount ); uint32_t doPrepareBillboardCommandBuffers( ashes::CommandBuffer const & commandBuffer , ashes::Optional< VkViewport > const & viewport , ashes::Optional< VkRect2D > const & scissors diff --git a/include/Core/Castor3D/Render/Opaque/OpaqueRendering.hpp b/include/Core/Castor3D/Render/Opaque/OpaqueRendering.hpp index a73879ce3a..61d780a6a7 100644 --- a/include/Core/Castor3D/Render/Opaque/OpaqueRendering.hpp +++ b/include/Core/Castor3D/Render/Opaque/OpaqueRendering.hpp @@ -20,7 +20,6 @@ See LICENSE file in root folder #include "Castor3D/Scene/Background/BackgroundModule.hpp" #include "Castor3D/Shader/Ubos/UbosModule.hpp" -#include #include #include diff --git a/include/Core/Castor3D/Render/Overlays/OverlayPreparer.hpp b/include/Core/Castor3D/Render/Overlays/OverlayPreparer.hpp index 0cf50ce09a..6a7360e193 100644 --- a/include/Core/Castor3D/Render/Overlays/OverlayPreparer.hpp +++ b/include/Core/Castor3D/Render/Overlays/OverlayPreparer.hpp @@ -53,6 +53,11 @@ namespace castor3d , uint32_t drawCount , uint32_t & offset , ashes::CommandBuffer const & commandBuffer )noexcept; + void doRegisterDrawCommands( OverlayDrawPipeline const & pipeline + , VkDrawIndirectCommand const & command + , uint32_t drawId + , uint32_t & offset + , ashes::CommandBuffer const & commandBuffer )noexcept; void doUpdateUbo( OverlayUboConfiguration & data , PanelOverlay const & overlay , Pass const & pass diff --git a/include/Core/Castor3D/Render/RenderDevice.hpp b/include/Core/Castor3D/Render/RenderDevice.hpp index 1411b265cf..6cd35e00bf 100644 --- a/include/Core/Castor3D/Render/RenderDevice.hpp +++ b/include/Core/Castor3D/Render/RenderDevice.hpp @@ -323,6 +323,8 @@ namespace castor3d C3D_API uint32_t getMaxBindlessSampled()const noexcept; C3D_API uint32_t getMaxBindlessStorage()const noexcept; C3D_API void fillGPUMeshInformations( GpuInformations & gpuInformations )const noexcept; + C3D_API bool hasGeometryShader()const noexcept; + C3D_API bool hasDrawId()const noexcept; bool prefersMeshShaderEXT()const noexcept { @@ -446,6 +448,10 @@ namespace castor3d , nullptr , {} }; #endif +#if VK_KHR_portability_subset + VkPhysicalDevicePortabilitySubsetFeaturesKHR m_portabilitySubsetFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR }; + VkPhysicalDevicePortabilitySubsetPropertiesKHR m_portabilitySubsetProperties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR }; +#endif #if VK_KHR_8bit_storage VkPhysicalDevice8BitStorageFeaturesKHR m_8bitFeatures{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR }; #endif diff --git a/include/Core/Castor3D/Render/RenderModule.hpp b/include/Core/Castor3D/Render/RenderModule.hpp index fb6b6085ca..3d3431ab01 100644 --- a/include/Core/Castor3D/Render/RenderModule.hpp +++ b/include/Core/Castor3D/Render/RenderModule.hpp @@ -142,6 +142,7 @@ namespace castor3d struct DrawConstants { uint32_t pipelineId; + int32_t drawId; }; /** *\~english diff --git a/include/Core/Castor3D/Render/ShadowMap/ShadowMap.hpp b/include/Core/Castor3D/Render/ShadowMap/ShadowMap.hpp index c64d7b1e1f..f9bc999f8d 100644 --- a/include/Core/Castor3D/Render/ShadowMap/ShadowMap.hpp +++ b/include/Core/Castor3D/Render/ShadowMap/ShadowMap.hpp @@ -237,7 +237,6 @@ namespace castor3d ShadowMapResult m_staticsResult; ShadowMapResult m_result; uint32_t m_count; - castor::Set< castor::ReferenceWrapper< GeometryBuffers > > m_geometryBuffers; castor::Array< AllPasses, 4u > m_passes; uint32_t m_passesIndex{}; }; diff --git a/include/Core/Castor3D/Shader/Shaders/GlslBlendComponents.hpp b/include/Core/Castor3D/Shader/Shaders/GlslBlendComponents.hpp index 955305c13a..e06370074c 100644 --- a/include/Core/Castor3D/Shader/Shaders/GlslBlendComponents.hpp +++ b/include/Core/Castor3D/Shader/Shaders/GlslBlendComponents.hpp @@ -1,4 +1,4 @@ -/* +/* See LICENSE file in root folder */ #ifndef ___C3D_GlslBlendComponents_H___ @@ -41,20 +41,41 @@ namespace castor3d::shader BlendComponents( Materials const & materials , Material const & material , SurfaceBase const & surface ); + BlendComponents( Materials const & materials + , Material const & material + , DerivSurfaceBase const & surface ); BlendComponents( Materials const & materials , Material const & material , SurfaceBase const & surface , sdw::Vec4 const & clrCot ); + BlendComponents( Materials const & materials + , Material const & material + , DerivSurfaceBase const & surface + , sdw::Vec4 const & clrCot ); BlendComponents( Materials const & materials , bool zeroInit = false ); SDW_DeclStructInstance( , BlendComponents ); void finish( PassShaders const & passShaders - , SurfaceBase const & surface + , DerivSurfaceBase const & surface , Utils & utils , sdw::Vec3 const worldEye ); + void setNormal( sdw::Vec3 const v ); + void normalizeNormal(); + sdw::Vec3 getRawNormal()const; + sdw::Vec4 getRawTangent()const; + sdw::Vec3 getRawBitangent()const; + shader::DerivVec3 getDerivNormal()const; + shader::DerivVec4 getDerivTangent()const; + shader::DerivVec3 getDerivBitangent()const; + + bool usesDerivativeValues()const noexcept + { + return m_derivativeValues; + } + static ast::type::BaseStructPtr makeType( ast::type::TypesCache & cache , Materials const & materials , bool zeroInit @@ -104,7 +125,6 @@ namespace castor3d::shader public: sdw::DefaultedT< sdw::Vec3 > f0; sdw::DefaultedT< sdw::Vec3 > f90; - sdw::DefaultedT< sdw::Vec3 > normal; sdw::DefaultedT< sdw::Vec3 > colour; sdw::DefaultedT< sdw::Vec3 > emissiveColour; sdw::DefaultedT< sdw::Float > emissiveFactor; @@ -164,6 +184,9 @@ namespace castor3d::shader , Material const & material , sdw::StructInstance const & surface , sdw::Vec4 const * clrCot ); + + private: + bool m_derivativeValues{}; }; } diff --git a/include/Core/Castor3D/Shader/Shaders/GlslDerivativeValue.hpp b/include/Core/Castor3D/Shader/Shaders/GlslDerivativeValue.hpp new file mode 100644 index 0000000000..5f17119381 --- /dev/null +++ b/include/Core/Castor3D/Shader/Shaders/GlslDerivativeValue.hpp @@ -0,0 +1,213 @@ +/* +See LICENSE file in root folder +*/ +#ifndef ___C3D_GlslDerivativeValue_H___ +#define ___C3D_GlslDerivativeValue_H___ + +#include "Castor3D/Shader/Shaders/SdwModule.hpp" + +#include +#include + +namespace castor3d::shader +{ + template< typename ValueT + , sdw::StringLiteralT StructNameT > + using DerivativeValueHelperT = sdw::StructInstanceHelperT < StructNameT + , sdw::type::MemoryLayout::eC + , sdw::StructFieldT< ValueT, "value" > + , sdw::StructFieldT< ValueT, "dPdx" > + , sdw::StructFieldT< ValueT, "dPdy" > >; + + template< typename ValueT + , sdw::StringLiteralT StructNameT > + struct DerivativeValueT + : public DerivativeValueHelperT< ValueT, StructNameT > + { + DerivativeValueT( sdw::ShaderWriter & writer + , ast::expr::ExprPtr expr + , bool enabled ) + : DerivativeValueHelperT< ValueT, StructNameT >{ writer, castor::move( expr ), enabled } + { + } + + DerivativeValueT( ValueT const & pvalue + , ValueT const & pdPdx + , ValueT const & pdPdy ) + : DerivativeValueT{ sdw::findWriterMandat( pvalue, pdPdx, pdPdy ) + , sdw::makeAggrInit( DerivativeValueHelperT< ValueT, StructNameT >::makeType( pvalue.getType()->getTypesCache() ) + , [&pvalue, &pdPdx, &pdPdy]() + { + sdw::expr::ExprList result; + result.emplace_back( makeExpr( pvalue ) ); + result.emplace_back( makeExpr( pdPdx ) ); + result.emplace_back( makeExpr( pdPdy ) ); + return result; + }() ) + , true } + { + } + + auto value()const { return this->template getMember< "value" >(); } + auto dPdx()const { return this->template getMember< "dPdx" >(); } + auto dPdy()const { return this->template getMember< "dPdy" >(); } + + DerivativeValueT operator-()const; + DerivativeValueT & operator+=( DerivativeValueT const & rhs ); + DerivativeValueT & operator-=( DerivativeValueT const & rhs ); + DerivativeValueT & operator*=( DerivativeValueT const & rhs ); + DerivativeValueT & operator+=( ValueT const & rhs ); + DerivativeValueT & operator-=( ValueT const & rhs ); + DerivativeValueT & operator*=( ValueT const & rhs ); + }; +} + +namespace sdw +{ + template< typename ValueT, StringLiteralT StructNameT > + struct TypeTraits< castor3d::shader::DerivativeValueT< ValueT, StructNameT > > + { + static ast::type::Kind constexpr TypeEnum = TypeTraits< StructInstance >::TypeEnum; + static bool constexpr HasArithmeticOperators = TypeTraits< StructInstance >::HasArithmeticOperators; + using CppType = typename TypeTraits< StructInstance >::CppType; + using OperandType = typename TypeTraits< StructInstance >::OperandType; + using LargestType = typename TypeTraits< StructInstance >::LargestType; + using ComponentType = typename TypeTraits< StructInstance >::ComponentType; + static size_t constexpr Size = TypeTraits< StructInstance >::Size; + static size_t constexpr ComponentCount = TypeTraits< StructInstance >::ComponentCount; + }; +} + +namespace castor3d::shader +{ + C3D_API sdw::expr::ExprPtr makeRawExpr( DerivFloat const & value ); + C3D_API sdw::expr::ExprPtr makeRawExpr( DerivVec2 const & value ); + C3D_API sdw::expr::ExprPtr makeRawExpr( DerivVec3 const & value ); + C3D_API sdw::expr::ExprPtr makeRawExpr( DerivVec4 const & value ); + C3D_API RetDerivFloat dot( DerivVec3 const lhs, DerivVec3 const rhs ); + C3D_API RetDerivVec3 cross( DerivVec3 const lhs, DerivVec3 const rhs ); + C3D_API RetDerivVec3 normalize( DerivVec3 const v ); + C3D_API RetDerivVec4 normalize( DerivVec4 const v ); + C3D_API RetDerivVec3 refract( DerivVec3 const i, DerivVec3 const n, sdw::Float const ior ); + C3D_API RetDerivFloat clamp( DerivFloat const v, sdw::Float const min, sdw::Float const max ); + C3D_API RetDerivFloat length( DerivVec3 const v ); + C3D_API RetDerivFloat max( DerivFloat const lhs, DerivFloat const rhs ); + C3D_API RetDerivVec3 mix( DerivVec3 const a, DerivVec3 const b, DerivVec3 const c ); + C3D_API RetDerivFloat fma( DerivFloat const a, DerivFloat const b, DerivFloat const c ); + C3D_API RetDerivVec2 fma( DerivVec2 const a, DerivVec2 const b, DerivVec2 const c ); + C3D_API RetDerivVec3 fma( DerivVec3 const a, DerivVec3 const b, DerivVec3 const c ); + C3D_API RetDerivVec4 fma( DerivVec4 const a, DerivVec4 const b, DerivVec4 const c ); + C3D_API sdw::Float fwidth( DerivFloat const a ); + C3D_API sdw::Vec2 fwidth( DerivVec2 const a ); + C3D_API sdw::Vec3 fwidth( DerivVec3 const a ); + C3D_API sdw::Vec4 fwidth( DerivVec4 const a ); + C3D_API DerivFloat negate( DerivFloat const a ); + C3D_API DerivVec2 negate( DerivVec2 const a ); + C3D_API DerivVec3 negate( DerivVec3 const a ); + C3D_API DerivVec4 negate( DerivVec4 const a ); + C3D_API sdw::Float computeMip( DerivVec2 const & uv + , sdw::Vec2 const & texSize ); + + C3D_API DerivFloat derivFloat( sdw::Float const v ); + C3D_API DerivFloat derivX( DerivVec2 const v ); + C3D_API DerivFloat derivX( DerivVec3 const v ); + C3D_API DerivFloat derivX( DerivVec4 const v ); + C3D_API DerivFloat derivY( DerivVec2 const v ); + C3D_API DerivFloat derivY( DerivVec3 const v ); + C3D_API DerivFloat derivY( DerivVec4 const v ); + C3D_API DerivFloat derivZ( DerivVec3 const v ); + C3D_API DerivFloat derivZ( DerivVec4 const v ); + C3D_API DerivFloat derivW( DerivVec4 const v ); + C3D_API DerivVec2 derivVec2( sdw::Float const v ); + C3D_API DerivVec2 derivVec2( sdw::Vec2 const v ); + C3D_API DerivVec2 derivVec2( DerivFloat const v ); + C3D_API DerivVec2 derivVec2( DerivVec3 const v ); + C3D_API DerivVec2 derivVec2( DerivVec4 const v ); + C3D_API DerivVec2 derivVec2( DerivFloat const v, sdw::Float const a ); + C3D_API DerivVec3 derivVec3( sdw::Float const v ); + C3D_API DerivVec3 derivVec3( sdw::Vec3 const v ); + C3D_API DerivVec3 derivVec3( DerivFloat const v ); + C3D_API DerivVec3 derivVec3( DerivVec4 const v ); + C3D_API DerivVec4 derivVec4( sdw::Float const v ); + C3D_API DerivVec4 derivVec4( sdw::Vec4 const v ); + C3D_API DerivVec4 derivVec4( DerivFloat const v ); + C3D_API DerivVec4 derivVec4( DerivVec3 const v, sdw::Float const a ); + C3D_API DerivVec4 derivVec4( DerivVec3 const v, DerivFloat const a ); + C3D_API void negateXYZ( sdw::Vec4 in ); + C3D_API void negateXYZ( DerivVec4 in ); + C3D_API void mulXY( sdw::Vec4 in, sdw::Vec2 const mul ); + C3D_API void mulXY( DerivVec4 in, sdw::Vec2 const mul ); + C3D_API void addXYZ( sdw::Vec4 in, sdw::Vec3 const add ); + C3D_API void addXYZ( DerivVec4 in, sdw::Vec3 const add ); + C3D_API void addXYZ( DerivVec4 in, DerivVec3 const add ); + C3D_API sdw::Vec3 getRaw( sdw::Vec3 const in ); + C3D_API sdw::Vec3 getRaw( DerivVec3 const in ); + C3D_API sdw::Vec4 getRaw( sdw::Vec4 const in ); + C3D_API sdw::Vec4 getRaw( DerivVec4 const in ); + C3D_API sdw::Vec3 getRawXYZ( sdw::Vec3 const in ); + C3D_API sdw::Vec3 getRawXYZ( DerivVec3 const in ); + C3D_API sdw::Vec3 getRawXYZ( sdw::Vec4 const in ); + C3D_API sdw::Vec3 getRawXYZ( DerivVec4 const in ); + C3D_API sdw::Vec3 getXYZ( sdw::Vec4 const in ); + C3D_API DerivVec3 getXYZ( DerivVec4 const in ); + C3D_API sdw::Vec3 getXYW( sdw::Vec4 const in ); + C3D_API DerivVec3 getXYW( DerivVec4 const in ); + C3D_API sdw::Float getW( sdw::Vec4 const in ); + C3D_API DerivFloat getW( DerivVec4 const in ); + + C3D_API DerivVec4 operator*( sdw::Mat4 const lhs, DerivVec4 const rhs ); + C3D_API DerivVec3 operator*( sdw::Mat3 const lhs, DerivVec3 const rhs ); + + C3D_API DerivFloat operator+( DerivFloat const lhs, DerivFloat const rhs ); + C3D_API DerivFloat operator+( DerivFloat const lhs, sdw::Float const rhs ); + C3D_API DerivFloat operator*( DerivFloat const lhs, DerivFloat const rhs ); + C3D_API DerivFloat operator*( DerivFloat const lhs, sdw::Float const rhs ); + C3D_API DerivFloat operator-( DerivFloat const lhs, DerivFloat const rhs ); + C3D_API DerivFloat operator-( DerivFloat const lhs, sdw::Float const rhs ); + + C3D_API DerivVec2 operator+( DerivVec2 const lhs, DerivVec2 const rhs ); + C3D_API DerivVec2 operator+( DerivVec2 const lhs, sdw::Vec2 const rhs ); + C3D_API DerivVec2 operator+( DerivVec2 const lhs, DerivFloat const rhs ); + C3D_API DerivVec2 operator+( DerivVec2 const lhs, sdw::Float const rhs ); + C3D_API DerivVec2 operator-( DerivVec2 const lhs, DerivVec2 const rhs ); + C3D_API DerivVec2 operator-( DerivVec2 const lhs, sdw::Vec2 const rhs ); + C3D_API DerivVec2 operator-( DerivVec2 const lhs, DerivFloat const rhs ); + C3D_API DerivVec2 operator-( DerivVec2 const lhs, sdw::Float const rhs ); + C3D_API DerivVec2 operator*( DerivVec2 const lhs, DerivVec2 const rhs ); + C3D_API DerivVec2 operator*( DerivVec2 const lhs, sdw::Vec2 const rhs ); + C3D_API DerivVec2 operator*( DerivVec2 const lhs, DerivFloat const rhs ); + C3D_API DerivVec2 operator*( DerivVec2 const lhs, sdw::Float const rhs ); + + C3D_API DerivVec3 operator+( DerivVec3 const lhs, DerivVec3 const rhs ); + C3D_API DerivVec3 operator+( DerivVec3 const lhs, sdw::Vec3 const rhs ); + C3D_API DerivVec3 operator+( DerivVec3 const lhs, DerivFloat const rhs ); + C3D_API DerivVec3 operator+( DerivVec3 const lhs, sdw::Float const rhs ); + C3D_API DerivVec3 operator-( DerivVec3 const lhs, DerivVec3 const rhs ); + C3D_API DerivVec3 operator-( DerivVec3 const lhs, sdw::Vec3 const rhs ); + C3D_API DerivVec3 operator-( DerivVec3 const lhs, DerivFloat const rhs ); + C3D_API DerivVec3 operator-( DerivVec3 const lhs, sdw::Float const rhs ); + C3D_API DerivVec3 operator*( DerivVec3 const lhs, DerivVec3 const rhs ); + C3D_API DerivVec3 operator*( DerivVec3 const lhs, sdw::Vec3 const rhs ); + C3D_API DerivVec3 operator*( DerivVec3 const lhs, DerivFloat const rhs ); + C3D_API DerivVec3 operator*( DerivVec3 const lhs, sdw::Float const rhs ); + + C3D_API DerivVec4 operator+( DerivVec4 const lhs, DerivVec4 const rhs ); + C3D_API DerivVec4 operator+( DerivVec4 const lhs, sdw::Vec4 const rhs ); + C3D_API DerivVec4 operator+( DerivVec4 const lhs, DerivFloat const rhs ); + C3D_API DerivVec4 operator+( DerivVec4 const lhs, sdw::Float const rhs ); + C3D_API DerivVec4 operator-( DerivVec4 const lhs, DerivVec4 const rhs ); + C3D_API DerivVec4 operator-( DerivVec4 const lhs, sdw::Vec4 const rhs ); + C3D_API DerivVec4 operator-( DerivVec4 const lhs, DerivFloat const rhs ); + C3D_API DerivVec4 operator-( DerivVec4 const lhs, sdw::Float const rhs ); + C3D_API DerivVec4 operator*( DerivVec4 const lhs, DerivVec4 const rhs ); + C3D_API DerivVec4 operator*( DerivVec4 const lhs, sdw::Vec4 const rhs ); + C3D_API DerivVec4 operator*( DerivVec4 const lhs, DerivFloat const rhs ); + C3D_API DerivVec4 operator*( DerivVec4 const lhs, sdw::Float const rhs ); + + //@} + //@} +} + +#include "GlslDerivativeValue.inl" + +#endif diff --git a/include/Core/Castor3D/Shader/Shaders/GlslDerivativeValue.inl b/include/Core/Castor3D/Shader/Shaders/GlslDerivativeValue.inl new file mode 100644 index 0000000000..1add71d67e --- /dev/null +++ b/include/Core/Castor3D/Shader/Shaders/GlslDerivativeValue.inl @@ -0,0 +1,56 @@ +namespace castor3d::shader +{ + template< typename ValueT, sdw::StringLiteralT StructNameT > + DerivativeValueT< ValueT, StructNameT > DerivativeValueT< ValueT, StructNameT >::operator-()const + { + return negate( *this ); + } + + template< typename ValueT, sdw::StringLiteralT StructNameT > + DerivativeValueT< ValueT, StructNameT > & DerivativeValueT< ValueT, StructNameT >::operator+=( DerivativeValueT< ValueT, StructNameT > const & rhs ) + { + value() = value() + rhs.value(); + dPdx() = dPdx() + rhs.dPdx(); + dPdy() = dPdy() + rhs.dPdy(); + return *this; + } + + template< typename ValueT, sdw::StringLiteralT StructNameT > + DerivativeValueT< ValueT, StructNameT > & DerivativeValueT< ValueT, StructNameT >::operator-=( DerivativeValueT< ValueT, StructNameT > const & rhs ) + { + value() = value() - rhs.value(); + dPdx() = dPdx() - rhs.dPdx(); + dPdy() = dPdy() - rhs.value(); + return *this; + } + + template< typename ValueT, sdw::StringLiteralT StructNameT > + DerivativeValueT< ValueT, StructNameT > & DerivativeValueT< ValueT, StructNameT >::operator*=( DerivativeValueT< ValueT, StructNameT > const & rhs ) + { + value() = value() * rhs.value(); + dPdx() = dPdx() * rhs.dPdx(); + dPdy() = dPdy() * rhs.dPdy(); + return *this; + } + + template< typename ValueT, sdw::StringLiteralT StructNameT > + DerivativeValueT< ValueT, StructNameT > & DerivativeValueT< ValueT, StructNameT >::operator+=( ValueT const & rhs ) + { + value() = value() + rhs.value(); + return *this; + } + + template< typename ValueT, sdw::StringLiteralT StructNameT > + DerivativeValueT< ValueT, StructNameT > & DerivativeValueT< ValueT, StructNameT >::operator-=( ValueT const & rhs ) + { + value() = value() - rhs.value(); + return *this; + } + + template< typename ValueT, sdw::StringLiteralT StructNameT > + DerivativeValueT< ValueT, StructNameT > & DerivativeValueT< ValueT, StructNameT >::operator*=( ValueT const & rhs ) + { + value() = value() * rhs.value(); + return *this; + } +} diff --git a/include/Core/Castor3D/Shader/Shaders/GlslLightSurface.hpp b/include/Core/Castor3D/Shader/Shaders/GlslLightSurface.hpp index 73739c269b..a898369c03 100644 --- a/include/Core/Castor3D/Shader/Shaders/GlslLightSurface.hpp +++ b/include/Core/Castor3D/Shader/Shaders/GlslLightSurface.hpp @@ -6,6 +6,8 @@ See LICENSE file in root folder #include "SdwModule.hpp" +#include "GlslDerivativeValue.hpp" + #include #include @@ -18,10 +20,10 @@ namespace castor3d::shader , sdw::expr::ExprPtr expr , bool enabled ); C3D_API LightSurface( sdw::Vec3 const eye - , sdw::Vec4 const world - , sdw::Vec3 const view + , DerivVec4 const world + , DerivVec3 const view , sdw::Vec3 const clip - , sdw::Vec3 const normal + , DerivVec3 const normal , bool enableDotProducts , bool enableFresnel , bool enableIridescence ); @@ -36,18 +38,18 @@ namespace castor3d::shader C3D_API static LightSurface create( sdw::ShaderWriter & writer , castor::MbString const & name , sdw::Vec3 const eye - , sdw::Vec4 const world - , sdw::Vec3 const view + , DerivVec4 const world + , DerivVec3 const view , sdw::Vec3 const clip - , sdw::Vec3 const normal + , DerivVec3 const normal , bool enableDotProducts = true , bool enableFresnel = true , bool enableIridescence = true ); C3D_API static LightSurface create( sdw::ShaderWriter & writer , castor::MbString const & name - , sdw::Vec4 const world + , DerivVec4 const world , sdw::Vec3 const clip - , sdw::Vec3 const normal + , DerivVec3 const normal , bool enableDotProducts = false , bool enableFresnel = false , bool enableIridescence = false ); @@ -55,25 +57,25 @@ namespace castor3d::shader , Utils & utils , castor::MbString const & name , sdw::Vec3 const eye - , sdw::Vec4 const world - , sdw::Vec3 const view + , DerivVec4 const world + , DerivVec3 const view , sdw::Vec3 const clip - , sdw::Vec3 const normal + , DerivVec3 const normal , sdw::Vec3 const f0 , BlendComponents const & components , bool enableDotProducts = true , bool enableFresnel = true , bool enableIridescence = true ); - C3D_API void updateN( sdw::Vec3 const N )const; - C3D_API void updateL( sdw::Vec3 const VtoL )const; + C3D_API void updateN( DerivVec3 const N )const; + C3D_API void updateL( DerivVec3 const VtoL )const; C3D_API void updateN( Utils & utils - , sdw::Vec3 const N + , DerivVec3 const N , sdw::Vec3 const f0 , BlendComponents const & components )const; C3D_API void updateL( Utils & utils - , sdw::Vec3 const VtoL + , DerivVec3 const VtoL , sdw::Vec3 const f0 , BlendComponents const & components )const; @@ -89,33 +91,33 @@ namespace castor3d::shader auto lengthV()const { return m_lengthV; } auto lengthL()const { return m_lengthL; } auto NdotV()const { return m_NdotV; } - sdw::Float NdotL()const { return m_NdotL; } - sdw::Float NdotH()const { return m_NdotH; } - sdw::Vec3 F()const { return m_F; } - sdw::Vec3 spcF()const { return m_spcF; } - sdw::Vec3 difF()const { return m_difF; } + DerivFloat NdotL()const { return m_NdotL; } + DerivFloat NdotH()const { return m_NdotH; } + DerivVec3 F()const { return m_F; } + DerivVec3 spcF()const { return m_spcF; } + DerivVec3 difF()const { return m_difF; } private: sdw::Vec3 m_eyePosition; - sdw::Vec4 m_worldPosition; - sdw::Vec3 m_viewPosition; + DerivVec4 m_worldPosition; + DerivVec3 m_viewPosition; sdw::Vec3 m_clipPosition; - sdw::Vec3 m_vertexToLight; - sdw::Vec3 m_V; - sdw::Vec3 m_N; - sdw::Vec3 m_L; - sdw::Vec3 m_H; - sdw::Float m_lengthV; - sdw::Float m_lengthL; - mutable sdw::Float m_NdotV; + DerivVec3 m_vertexToLight; + DerivVec3 m_V; + DerivVec3 m_N; + DerivVec3 m_L; + DerivVec3 m_H; + DerivFloat m_lengthV; + DerivFloat m_lengthL; + mutable DerivFloat m_NdotV; - mutable sdw::DefaultedT< sdw::Float > m_NdotL; - mutable sdw::DefaultedT< sdw::Float > m_NdotH; - mutable sdw::DefaultedT< sdw::Float > m_HdotV; + mutable sdw::DefaultedT< DerivFloat > m_NdotL; + mutable sdw::DefaultedT< DerivFloat > m_NdotH; + mutable sdw::DefaultedT< DerivFloat > m_HdotV; - mutable sdw::DefaultedT< sdw::Vec3 > m_F; - mutable sdw::DefaultedT< sdw::Vec3 > m_spcF; - mutable sdw::DefaultedT< sdw::Vec3 > m_difF; + mutable sdw::DefaultedT< DerivVec3 > m_F; + mutable sdw::DefaultedT< DerivVec3 > m_spcF; + mutable sdw::DefaultedT< DerivVec3 > m_difF; private: auto HdotV()const { return m_HdotV; } @@ -123,13 +125,13 @@ namespace castor3d::shader C3D_API void doUpdateF( Utils & utils , sdw::Vec3 const f0 , BlendComponents const & components - , sdw::Float const & dotProduct )const; + , DerivFloat const & dotProduct )const; C3D_API static sdw::expr::ExprPtr makeInit( sdw::type::BaseStructPtr type , sdw::Vec3 const eye - , sdw::Vec4 const world - , sdw::Vec3 const view + , DerivVec4 const world + , DerivVec3 const view , sdw::Vec3 const clip - , sdw::Vec3 const normal + , DerivVec3 const normal , bool enableDotProducts , bool enableFresnel , bool enableIridescence ); diff --git a/include/Core/Castor3D/Shader/Shaders/GlslLighting.hpp b/include/Core/Castor3D/Shader/Shaders/GlslLighting.hpp index c156ce058b..323b203d08 100644 --- a/include/Core/Castor3D/Shader/Shaders/GlslLighting.hpp +++ b/include/Core/Castor3D/Shader/Shaders/GlslLighting.hpp @@ -44,8 +44,7 @@ namespace castor3d::shader } C3D_API void finish( PassShaders const & passShaders - , RasterizerSurfaceBase const & rasterSurface - , SurfaceBase const & surface + , DerivSurfaceBase const & surface , Utils & utils , sdw::Vec3 const worldEye , BlendComponents & components ); @@ -226,13 +225,12 @@ namespace castor3d::shader , sdw::Vec3 output ); C3D_API virtual void doInitLightSpecifics( LightSurface const & lightSurface , BlendComponents const & components ); - C3D_API virtual sdw::Float doGetNdotL( LightSurface const & lightSurface + C3D_API virtual DerivFloat doGetNdotL( LightSurface const & lightSurface , BlendComponents const & components ); - C3D_API virtual sdw::Float doGetNdotH( LightSurface const & lightSurface + C3D_API virtual DerivFloat doGetNdotH( LightSurface const & lightSurface , BlendComponents const & components ); C3D_API virtual void doFinish( PassShaders const & passShaders - , RasterizerSurfaceBase const & rasterSurface , BlendComponents & components ) = 0; C3D_API virtual sdw::Vec3 doComputeDiffuseTerm( sdw::Vec3 const & radiance , sdw::Float const & intensity diff --git a/include/Core/Castor3D/Shader/Shaders/GlslPassShaders.hpp b/include/Core/Castor3D/Shader/Shaders/GlslPassShaders.hpp index 0c6af59245..62bf4ff3b2 100644 --- a/include/Core/Castor3D/Shader/Shaders/GlslPassShaders.hpp +++ b/include/Core/Castor3D/Shader/Shaders/GlslPassShaders.hpp @@ -86,7 +86,7 @@ namespace castor3d::shader , Material const & material , BlendComponents & components , bool isFrontCulled = false )const; - C3D_API void finishComponents( SurfaceBase const & surface + C3D_API void finishComponents( DerivSurfaceBase const & surface , sdw::Vec3 const worldEye , Utils & utils , BlendComponents & components )const; diff --git a/include/Core/Castor3D/Shader/Shaders/GlslReflection.hpp b/include/Core/Castor3D/Shader/Shaders/GlslReflection.hpp index 46f23a75dc..012cb830bf 100644 --- a/include/Core/Castor3D/Shader/Shaders/GlslReflection.hpp +++ b/include/Core/Castor3D/Shader/Shaders/GlslReflection.hpp @@ -21,6 +21,8 @@ namespace castor3d::shader C3D_API sdw::RetVec3 computeIncident( sdw::Vec3 const & wsPosition , sdw::Vec3 const & wsCamera )const; + C3D_API DerivVec3 computeIncident( DerivVec3 const & wsPosition + , sdw::Vec3 const & wsCamera )const; C3D_API void computeCombined( BlendComponents & components , LightSurface const & lightSurface , sdw::Vec3 const & position diff --git a/include/Core/Castor3D/Shader/Shaders/GlslShadow.hpp b/include/Core/Castor3D/Shader/Shaders/GlslShadow.hpp index d9919fe270..a882f3efe5 100644 --- a/include/Core/Castor3D/Shader/Shaders/GlslShadow.hpp +++ b/include/Core/Castor3D/Shader/Shaders/GlslShadow.hpp @@ -149,27 +149,6 @@ namespace castor3d::shader class Shadow { - public: - C3D_API static castor::MbString const MapDepthDirectional; - C3D_API static castor::MbString const MapDepthSpot; - C3D_API static castor::MbString const MapDepthPoint; - C3D_API static castor::MbString const MapDepthCmpDirectional; - C3D_API static castor::MbString const MapDepthCmpSpot; - C3D_API static castor::MbString const MapDepthCmpPoint; - C3D_API static castor::MbString const MapVarianceDirectional; - C3D_API static castor::MbString const MapVarianceSpot; - C3D_API static castor::MbString const MapVariancePoint; - C3D_API static castor::MbString const MapNormalDirectional; - C3D_API static castor::MbString const MapNormalSpot; - C3D_API static castor::MbString const MapNormalPoint; - C3D_API static castor::MbString const MapPositionDirectional; - C3D_API static castor::MbString const MapPositionSpot; - C3D_API static castor::MbString const MapPositionPoint; - C3D_API static castor::MbString const MapFluxDirectional; - C3D_API static castor::MbString const MapFluxSpot; - C3D_API static castor::MbString const MapFluxPoint; - C3D_API static castor::MbString const RandomBuffer; - public: C3D_API Shadow( ShadowOptions shadowOptions , sdw::ShaderWriter & writer ); @@ -183,6 +162,15 @@ namespace castor3d::shader C3D_API void declareSpot( uint32_t & index , uint32_t set ); + C3D_API bool hasMapDepthDirectional()const; + C3D_API bool hasMapDepthPoint()const; + C3D_API bool hasMapDepthSpot()const; + + C3D_API sdw::CombinedImage2DArrayR32 getMapDepthDirectional()const; + C3D_API sdw::CombinedImageCubeArrayR32 getMapDepthPoint()const; + C3D_API sdw::CombinedImage2DArrayR32 getMapDepthSpot()const; + C3D_API sdw::UInt getMaxCascadeCount()const; + C3D_API DirectionalShadowData getDirectionalShadows(); C3D_API PointShadowData getPointShadows( sdw::Int const & index ); C3D_API SpotShadowData getSpotShadows( sdw::Int const & index ); @@ -255,6 +243,21 @@ namespace castor3d::shader , sdw::Float const & depthBias , sdw::UInt const & sampleCount , sdw::Float const & filterSize ); + sdw::RetFloat filterPCF( sdw::Vec3 const & lightSpacePosition + , sdw::CombinedImage2DArrayShadowR32 const & shadowMap + , sdw::Vec2 const & invTexDim + , sdw::UInt const & arrayIndex + , sdw::Float const & depthBias + , sdw::UInt const & sampleCount + , sdw::Float const & filterSize ); + sdw::RetFloat filterPCF( sdw::Vec3 const & lightToVertex + , sdw::CombinedImageCubeArrayShadowR32 const & shadowMap + , sdw::Vec2 const & invTexDim + , sdw::UInt const & cubeIndex + , sdw::Float const & depth + , sdw::Float const & depthBias + , sdw::UInt const & sampleCount + , sdw::Float const & filterSize ); sdw::RetFloat chebyshevUpperBound( sdw::Vec2 const & moments , sdw::Float const & depth , sdw::Float const & minVariance @@ -293,6 +296,23 @@ namespace castor3d::shader , sdw::InFloat , sdw::InUInt , sdw::InFloat > m_filterPCFCube; + sdw::Function< sdw::Float + , sdw::InVec3 + , sdw::InCombinedImage2DArrayShadowR32 + , sdw::InVec2 + , sdw::InUInt + , sdw::InFloat + , sdw::InUInt + , sdw::InFloat > m_filterPCFArrayShadow; + sdw::Function< sdw::Float + , sdw::InVec3 + , sdw::InCombinedImageCubeArrayShadowR32 + , sdw::InVec2 + , sdw::InUInt + , sdw::InFloat + , sdw::InFloat + , sdw::InUInt + , sdw::InFloat > m_filterPCFCubeShadow; sdw::Function< sdw::Vec4 , sdw::InMat4 , sdw::InVec3 > m_getLightSpacePosition; diff --git a/include/Core/Castor3D/Shader/Shaders/GlslSssTransmittance.hpp b/include/Core/Castor3D/Shader/Shaders/GlslSssTransmittance.hpp index 39e19f767d..d674caf554 100644 --- a/include/Core/Castor3D/Shader/Shaders/GlslSssTransmittance.hpp +++ b/include/Core/Castor3D/Shader/Shaders/GlslSssTransmittance.hpp @@ -16,6 +16,7 @@ namespace castor3d::shader { public: C3D_API SssTransmittance( sdw::ShaderWriter & writer + , Shadow const & shadows , ShadowOptions shadowOptions , SssProfiles const & sssProfiles ); @@ -45,9 +46,10 @@ namespace castor3d::shader , sdw::Vec3 const & lightToVertex ); sdw::ShaderWriter & m_writer; + Shadow const & m_shadows; SssProfiles const & m_sssProfiles; - SceneFlags m_shadows; + SceneFlags m_shadowsType; sdw::Function< sdw::Vec3 , sdw::InFloat diff --git a/include/Core/Castor3D/Shader/Shaders/GlslSurface.hpp b/include/Core/Castor3D/Shader/Shaders/GlslSurface.hpp index 0af5f41720..0222fa3ea8 100644 --- a/include/Core/Castor3D/Shader/Shaders/GlslSurface.hpp +++ b/include/Core/Castor3D/Shader/Shaders/GlslSurface.hpp @@ -7,144 +7,226 @@ See LICENSE file in root folder #include "SdwModule.hpp" #include "Castor3D/Model/Mesh/Submesh/SubmeshModule.hpp" #include "Castor3D/Render/RenderModule.hpp" +#include "Castor3D/Shader/Shaders/GlslDerivativeValue.hpp" #include "Castor3D/Shader/Ubos/UbosModule.hpp" #include #include +#include #include namespace castor3d::shader { - struct SurfaceBase + template< typename Position3T, typename Position4T, typename NormalT > + struct SurfaceBaseT : public sdw::StructInstance { - C3D_API SurfaceBase( sdw::ShaderWriter & writer + SurfaceBaseT( sdw::ShaderWriter & writer , sdw::expr::ExprPtr expr , bool enabled ); sdw::Vec3 clipPosition; - sdw::Vec4 viewPosition; - sdw::Vec4 worldPosition; - sdw::Vec3 normal; + Position4T viewPosition; + Position4T worldPosition; + NormalT normal; protected: - C3D_API static void fillType( sdw::type::BaseStruct & type ); - C3D_API static void fillIOType( sdw::type::IOStruct & type + static void fillType( sdw::type::BaseStruct & type ); + static void fillIOType( sdw::type::IOStruct & type , PipelineFlags const & flags , uint32_t & index ); - C3D_API static void fillType( sdw::type::BaseStruct & type + static void fillType( sdw::type::BaseStruct & type , PipelineFlags const & flags ); - C3D_API static void fillInit( sdw::expr::ExprList & init + static void fillInit( sdw::expr::ExprList & init , sdw::Vec3 clip - , sdw::Vec4 view - , sdw::Vec4 world - , sdw::Vec3 normal ); - C3D_API static void fillInit( sdw::expr::ExprList & init + , Position4T view + , Position4T world + , NormalT normal ); + static void fillInit( sdw::expr::ExprList & init , PipelineFlags const & flags , sdw::Vec3 clip - , sdw::Vec4 view - , sdw::Vec4 world - , sdw::Vec3 normal ); + , Position4T view + , Position4T world + , NormalT normal ); + + static Position3T makePosition3( sdw::Vec3 const & in ) + requires std::is_same_v< Position3T, sdw::Vec3 > + { + return in; + } + + static Position3T makePosition3( sdw::Vec3 const & in ) + requires std::is_same_v< Position3T, DerivVec3 > + { + return derivVec3( in ); + } + + static Position3T makePosition3( sdw::Float const & in ) + { + return makePosition3( vec3( in ) ); + } + + static Position4T makePosition4( sdw::Vec4 const & in ) + requires std::is_same_v< Position4T, sdw::Vec4 > + { + return in; + } + + static Position4T makePosition4( sdw::Vec4 const & in ) + requires std::is_same_v< Position4T, DerivVec4 > + { + return derivVec4( in ); + } + + static Position4T makePosition4( sdw::Vec3 const & rgb + , sdw::Float const & a ) + requires std::is_same_v< Position4T, sdw::Vec4 > + { + return vec4( rgb, a ); + } + + static Position4T makePosition4( DerivVec3 const & rgb + , DerivFloat const & a ) + requires std::is_same_v< Position4T, DerivVec4 > + { + return derivVec4( rgb, a ); + } + + static Position4T makePosition4( sdw::Vec3 const & in ) + requires std::is_same_v< Position4T, sdw::Vec4 > + { + return vec4( in, 1.0_f ); + } + + static Position4T makePosition4( DerivVec3 const & in ) + requires std::is_same_v< Position4T, DerivVec4 > + { + return derivVec4( in, 1.0_f ); + } + + static Position4T makePosition4( sdw::Float const & in ) + { + return makePosition4( vec4( in ) ); + } + + static NormalT makeNormal( sdw::Vec3 const & in ) + requires std::is_same_v< NormalT, sdw::Vec3 > + { + return in; + } + + static NormalT makeNormal( sdw::Vec3 const & in ) + requires std::is_same_v< NormalT, DerivVec3 > + { + return derivVec3( in ); + } + + static NormalT makeNormal( sdw::Float const & in ) + { + return makeNormal( vec3( in ) ); + } }; - struct Surface - : public SurfaceBase + template< typename Position3T, typename Position4T, typename NormalT > + struct SurfaceT + : public SurfaceBaseT< Position3T, Position4T, NormalT > { - C3D_API Surface( sdw::ShaderWriter & writer + SurfaceT( sdw::ShaderWriter & writer , sdw::expr::ExprPtr expr , bool enabled ); - C3D_API Surface( sdw::Vec3 clip - , sdw::Vec4 view - , sdw::Vec4 world - , sdw::Vec3 normal + SurfaceT( sdw::Vec3 clip + , Position4T view + , Position4T world + , NormalT normal , sdw::Vec3 texCoord ); - C3D_API Surface( sdw::Vec3 clip - , sdw::Vec3 view - , sdw::Vec3 world - , sdw::Vec3 normal + SurfaceT( sdw::Vec3 clip + , Position3T view + , Position3T world + , NormalT normal , sdw::Vec3 texCoord ); - C3D_API Surface( sdw::Vec3 clip - , sdw::Vec4 view - , sdw::Vec4 world - , sdw::Vec3 normal ); - C3D_API Surface( sdw::Vec3 clip - , sdw::Vec3 view - , sdw::Vec3 world - , sdw::Vec3 normal ); - C3D_API Surface( sdw::Vec3 world - , sdw::Vec3 normal ); - SDW_DeclStructInstance( C3D_API, Surface ); - - C3D_API static sdw::type::BaseStructPtr makeType( sdw::type::TypesCache & cache ); - C3D_API static sdw::type::BaseStructPtr makeType( sdw::type::TypesCache & cache + SurfaceT( sdw::Vec3 clip + , Position4T view + , Position4T world + , NormalT normal ); + SurfaceT( sdw::Vec3 clip + , Position3T view + , Position3T world + , NormalT normal ); + SurfaceT( NormalT world + , NormalT normal ); + SDW_DeclStructInstance( , SurfaceT ); + + static sdw::type::BaseStructPtr makeType( sdw::type::TypesCache & cache ); + static sdw::type::BaseStructPtr makeType( sdw::type::TypesCache & cache , PipelineFlags const & flags ); sdw::Vec3 texCoord; protected: - C3D_API static void fillType( sdw::type::BaseStruct & type ); - C3D_API static void fillType( sdw::type::BaseStruct & type + static void fillType( sdw::type::BaseStruct & type ); + static void fillType( sdw::type::BaseStruct & type , PipelineFlags const & flags ); - C3D_API static void fillInit( sdw::expr::ExprList & init + static void fillInit( sdw::expr::ExprList & init , sdw::Vec3 clip - , sdw::Vec4 view - , sdw::Vec4 world - , sdw::Vec3 normal + , Position4T view + , Position4T world + , NormalT normal , sdw::Vec3 texCoord ); - C3D_API static void fillInit( sdw::expr::ExprList & init + static void fillInit( sdw::expr::ExprList & init , PipelineFlags const & flags , sdw::Vec3 clip - , sdw::Vec4 view - , sdw::Vec4 world - , sdw::Vec3 normal + , Position4T view + , Position4T world + , NormalT normal , sdw::Vec3 texCoord ); }; - struct RasterizerSurfaceBase - : public SurfaceBase + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T > + struct RasterizerSurfaceBaseT + : public SurfaceBaseT< Position3T, Position4T, Normal3T > { - C3D_API RasterizerSurfaceBase( sdw::ShaderWriter & writer + RasterizerSurfaceBaseT( sdw::ShaderWriter & writer , sdw::expr::ExprPtr expr , bool enabled ); // Vertex shader side - C3D_API void computeVelocity( CameraData const & cameraData - , sdw::Vec4 & curPos - , sdw::Vec4 & prvPos ); - C3D_API void computeTangentSpace( PipelineFlags const & flags + void computeVelocity( CameraData const & cameraData + , Position4T & curPos + , Position4T & prvPos ); + void computeTangentSpace( PipelineFlags const & flags , sdw::Vec3 const & cameraPosition - , sdw::Vec3 const & worldPos - , sdw::Vec3 const & nml - , sdw::Vec4 const & tan ); - C3D_API void computeTangentSpace( PipelineFlags const & flags + , Position3T const & worldPos + , Normal3T const & nml + , Normal4T const & tan ); + void computeTangentSpace( PipelineFlags const & flags , sdw::Vec3 const & cameraPosition - , sdw::Vec3 const & worldPos + , Position3T const & worldPos , sdw::Mat3 const & mtx - , sdw::Vec3 const & nml - , sdw::Vec4 const & tan ); - C3D_API void computeTangentSpace( PipelineFlags const & flags + , Normal3T const & nml + , Normal4T const & tan ); + void computeTangentSpace( PipelineFlags const & flags , sdw::Vec3 const & cameraPosition - , sdw::Vec3 const & worldPos + , Position3T const & worldPos , sdw::Mat3 const & mtx - , sdw::Vec3 const & nml - , sdw::Vec4 const & tan - , sdw::Vec3 const & bin ); - C3D_API void computeTangentSpace( PipelineFlags const & flags + , Normal3T const & nml + , Normal4T const & tan + , Normal3T const & bin ); + void computeTangentSpace( PipelineFlags const & flags , sdw::Vec3 const & cameraPosition - , sdw::Vec3 const & worldPos - , sdw::Vec3 const & nml - , sdw::Vec4 const & tan - , sdw::Vec3 const & bin ); + , Position3T const & worldPos + , Normal3T const & nml + , Normal4T const & tan + , Normal3T const & bin ); // Fragment shader side - C3D_API sdw::Vec2 getVelocity()const; + sdw::Vec2 getVelocity()const; - sdw::Vec4 curPosition; - sdw::Vec4 prvPosition; - sdw::Vec3 tangentSpaceFragPosition; + Position4T curPosition; + Position4T prvPosition; + Position3T tangentSpaceFragPosition; sdw::Vec3 tangentSpaceViewPosition; - sdw::Vec4 tangent; - sdw::Vec3 bitangent; + Normal4T tangent; + Normal3T bitangent; sdw::Vec3 colour; sdw::Array< sdw::Vec4 > passMultipliers; sdw::UInt nodeId; @@ -152,16 +234,16 @@ namespace castor3d::shader sdw::UInt meshletId; protected: - C3D_API static void fillIOType( sdw::type::IOStruct & type + static void fillIOType( sdw::type::IOStruct & type , SubmeshShaders const & submeshShaders , PassShaders const & passShaders , PipelineFlags const & flags , uint32_t & index ); - C3D_API static void fillType( sdw::type::BaseStruct & type + static void fillType( sdw::type::BaseStruct & type , SubmeshShaders const & submeshShaders , PassShaders const & passShaders , PipelineFlags const & flags ); - C3D_API static void fillType( sdw::type::BaseStruct & type + static void fillType( sdw::type::BaseStruct & type , SubmeshShaders const & submeshShaders ); }; @@ -185,21 +267,21 @@ namespace castor3d::shader sdw::Vec3 center; }; - template< typename TexcoordT, sdw::var::Flag FlagT > + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T, typename TexcoordT, sdw::var::Flag FlagT > struct RasterizerSurfaceT - : public RasterizerSurfaceBase + : public RasterizerSurfaceBaseT< Position3T, Position4T, Normal3T, Normal4T > { public: RasterizerSurfaceT( sdw::ShaderWriter & writer , sdw::expr::ExprPtr expr , bool enabled ); RasterizerSurfaceT( sdw::Vec3 clip - , sdw::Vec3 view - , sdw::Vec3 world - , sdw::Vec3 normal + , Position3T view + , Position3T world + , Normal3T normal , TexcoordT texCoord ); template< sdw::var::Flag FlagU > - RasterizerSurfaceT( RasterizerSurfaceT< TexcoordT, FlagU > const & rhs ); + RasterizerSurfaceT( RasterizerSurfaceT< Position3T, Position4T, Normal3T, Normal4T, TexcoordT, FlagU > const & rhs ); SDW_DeclStructInstance( , RasterizerSurfaceT ); diff --git a/include/Core/Castor3D/Shader/Shaders/GlslSurface.inl b/include/Core/Castor3D/Shader/Shaders/GlslSurface.inl index ccd053e84a..e1d08f358b 100644 --- a/include/Core/Castor3D/Shader/Shaders/GlslSurface.inl +++ b/include/Core/Castor3D/Shader/Shaders/GlslSurface.inl @@ -1,6 +1,8 @@ #include "Castor3D/Shader/Shaders/GlslSurface.hpp" #include "Castor3D/Render/RenderNodesPass.hpp" +#include "Castor3D/Shader/Shaders/GlslPassShaders.hpp" +#include "Castor3D/Shader/Shaders/GlslSubmeshShaders.hpp" #include "Castor3D/Shader/Ubos/CameraUbo.hpp" #include "Castor3D/Shader/Ubos/MorphingUbo.hpp" @@ -68,30 +70,612 @@ namespace castor3d::shader //***************************************************************************************** - template< typename TexcoordT, ast::var::Flag FlagT > - RasterizerSurfaceT< TexcoordT, FlagT >::RasterizerSurfaceT( sdw::ShaderWriter & writer + template< typename Position3T, typename Position4T, typename NormalT > + SurfaceBaseT< Position3T, Position4T, NormalT >::SurfaceBaseT( sdw::ShaderWriter & writer + , ast::expr::ExprPtr expr + , bool enabled ) + : StructInstance{ writer, castor::move( expr ), enabled } + , clipPosition{ this->template getMember< sdw::Vec3 >( "clipPosition", true ) } + , viewPosition{ this->template getMember< Position4T >( "viewPosition", true ) } + , worldPosition{ this->template getMember< Position4T >( "worldPosition", true ) } + , normal{ this->template getMember< NormalT >( "normal", true ) } + { + } + + template< typename Position3T, typename Position4T, typename NormalT > + void SurfaceBaseT< Position3T, Position4T, NormalT >::fillType( sdw::type::BaseStruct & type ) + { + type.declMember( "clipPosition", sdw::Vec3::makeType( type.getTypesCache() ) ); + type.declMember( "viewPosition", Position4T::makeType( type.getTypesCache() ) ); + type.declMember( "worldPosition", Position4T::makeType( type.getTypesCache() ) ); + type.declMember( "normal", NormalT::makeType( type.getTypesCache() ) ); + } + + template< typename Position3T, typename Position4T, typename NormalT > + void SurfaceBaseT< Position3T, Position4T, NormalT >::fillIOType( sdw::type::IOStruct & type + , PipelineFlags const & flags + , uint32_t & index ) + { + type.declMember( "viewPosition" + , Position4T::makeType( type.getTypesCache() ) + , ast::type::NotArray + , flags.usesViewSpace() ? index++ : 0u + , flags.usesViewSpace() ); + type.declMember( "worldPosition" + , Position4T::makeType( type.getTypesCache() ) + , ast::type::NotArray + , flags.usesWorldSpace() ? index++ : 0u + , flags.usesWorldSpace() ); + type.declMember( "normal" + , NormalT::makeType( type.getTypesCache() ) + , ast::type::NotArray + , flags.enableNormal() ? index++ : 0u + , flags.enableNormal() ); + } + + template< typename Position3T, typename Position4T, typename NormalT > + void SurfaceBaseT< Position3T, Position4T, NormalT >::fillType( sdw::type::BaseStruct & type + , PipelineFlags const & flags ) + { + type.declMember( "clipPosition" + , sdw::Vec3::makeType( type.getTypesCache() ) ); + type.declMember( "viewPosition" + , Position4T::makeType( type.getTypesCache() ) + , ast::type::NotArray + , flags.usesViewSpace() ); + type.declMember( "worldPosition" + , Position4T::makeType( type.getTypesCache() ) + , ast::type::NotArray + , flags.usesWorldSpace() ); + type.declMember( "normal" + , NormalT::makeType( type.getTypesCache() ) + , ast::type::NotArray + , flags.enableNormal() ); + } + + template< typename Position3T, typename Position4T, typename NormalT > + void SurfaceBaseT< Position3T, Position4T, NormalT >::fillInit( sdw::expr::ExprList & init + , sdw::Vec3 clip + , Position4T view + , Position4T world + , NormalT normal ) + { + init.emplace_back( makeExpr( clip.isEnabled() ? clip : vec3( 0.0_f ) ) ); + init.emplace_back( makeExpr( view.isEnabled() ? view : SurfaceBaseT::makePosition4( 0.0_f ) ) ); + init.emplace_back( makeExpr( world.isEnabled() ? world : SurfaceBaseT::makePosition4( 0.0_f ) ) ); + init.emplace_back( makeExpr( normal.isEnabled() ? normal : SurfaceBaseT::makeNormal( 0.0_f ) ) ); + } + + template< typename Position3T, typename Position4T, typename NormalT > + void SurfaceBaseT< Position3T, Position4T, NormalT >::fillInit( sdw::expr::ExprList & init + , PipelineFlags const & flags + , sdw::Vec3 clip + , Position4T view + , Position4T world + , NormalT normal ) + { + init.emplace_back( makeExpr( clip ) ); + + if ( flags.usesViewSpace() ) + { + init.emplace_back( makeExpr( SurfaceBaseT::makePosition4( shader::getXYZ( view ) ) ) ); + } + + if ( flags.usesWorldSpace() ) + { + init.emplace_back( makeExpr( SurfaceBaseT::makePosition4( shader::getXYZ( world ) ) ) ); + } + + if ( flags.enableNormal() ) + { + init.emplace_back( makeExpr( normal ) ); + } + } + + //***************************************************************************************** + + template< typename Position3T, typename Position4T, typename NormalT > + SurfaceT< Position3T, Position4T, NormalT >::SurfaceT( sdw::ShaderWriter & writer + , ast::expr::ExprPtr expr + , bool enabled ) + : SurfaceBaseT< Position3T, Position4T, NormalT >{ writer, castor::move( expr ), enabled } + , texCoord{ this->template getMember< sdw::Vec3 >( "texture0" ) } + { + } + + template< typename Position3T, typename Position4T, typename NormalT > + SurfaceT< Position3T, Position4T, NormalT >::SurfaceT( sdw::Vec3 clip + , Position4T view + , Position4T world + , NormalT normal + , sdw::Vec3 coord ) + : SurfaceT{ findWriterMandat( clip, view, world, normal, coord ) + , sdw::makeAggrInit( makeType( findTypesCache( clip, view, world, normal, coord ) ) + , [&clip, &view, &world, &normal, &coord]() + { + sdw::expr::ExprList result; + fillInit( result, clip, view, world, normal, coord ); + return result; + }() ) + , true } + { + } + + template< typename Position3T, typename Position4T, typename NormalT > + SurfaceT< Position3T, Position4T, NormalT >::SurfaceT( sdw::Vec3 clip + , Position3T view + , Position3T world + , NormalT normal + , sdw::Vec3 coord ) + : SurfaceT{ castor::move( clip ) + , SurfaceBaseT< Position3T, Position4T, NormalT >::makePosition4( view ) + , SurfaceBaseT< Position3T, Position4T, NormalT >::makePosition4( world ) + , castor::move( normal ) + , coord } + { + } + + template< typename Position3T, typename Position4T, typename NormalT > + SurfaceT< Position3T, Position4T, NormalT >::SurfaceT( sdw::Vec3 clip + , Position4T view + , Position4T world + , NormalT normal ) + : SurfaceT{ castor::move( clip ) + , castor::move( view ) + , castor::move( world ) + , castor::move( normal ) + , vec3( 0.0_f ) } + { + } + + template< typename Position3T, typename Position4T, typename NormalT > + SurfaceT< Position3T, Position4T, NormalT >::SurfaceT( sdw::Vec3 clip + , Position3T view + , Position3T world + , NormalT normal ) + : SurfaceT{ castor::move( clip ) + , castor::move( view ) + , castor::move( world ) + , castor::move( normal ) + , vec3( 0.0_f ) } + { + } + + template< typename Position3T, typename Position4T, typename NormalT > + SurfaceT< Position3T, Position4T, NormalT >::SurfaceT( NormalT world + , NormalT normal ) + : SurfaceT{ vec3( 0.0_f ) + , SurfaceBaseT< Position3T, Position4T, NormalT >::makePosition4( 0.0_f ) + , SurfaceBaseT< Position3T, Position4T, NormalT >::makePosition4( world ) + , castor::move( normal ) + , vec3( 0.0_f ) } + { + } + + template< typename Position3T, typename Position4T, typename NormalT > + ast::type::BaseStructPtr SurfaceT< Position3T, Position4T, NormalT >::makeType( ast::type::TypesCache & cache ) + { + auto result = cache.getStruct( ast::type::MemoryLayout::eStd430 + , "C3D_TexSurface" ); + + if ( result->empty() ) + { + fillType( *result ); + } + + return result; + } + + template< typename Position3T, typename Position4T, typename NormalT > + void SurfaceT< Position3T, Position4T, NormalT >::fillType( sdw::type::BaseStruct & type ) + { + SurfaceBaseT< Position3T, Position4T, NormalT >::fillType( type ); + type.declMember( "texture0" + , ast::type::Kind::eVec3F ); + } + + template< typename Position3T, typename Position4T, typename NormalT > + void SurfaceT< Position3T, Position4T, NormalT >::fillType( sdw::type::BaseStruct & type + , PipelineFlags const & flags ) + { + SurfaceBaseT< Position3T, Position4T, NormalT >::fillType( type, flags ); + type.declMember( "texture0" + , ast::type::Kind::eVec3F + , flags.enableTexcoord0() ); + } + + template< typename Position3T, typename Position4T, typename NormalT > + void SurfaceT< Position3T, Position4T, NormalT >::fillInit( sdw::expr::ExprList & init + , sdw::Vec3 clip + , Position4T view + , Position4T world + , NormalT normal + , sdw::Vec3 texCoord ) + { + SurfaceBaseT< Position3T, Position4T, NormalT >::fillInit( init, clip, view, world, normal ); + init.emplace_back( makeExpr( texCoord ) ); + } + + template< typename Position3T, typename Position4T, typename NormalT > + void SurfaceT< Position3T, Position4T, NormalT >::fillInit( sdw::expr::ExprList & init + , PipelineFlags const & flags + , sdw::Vec3 clip + , Position4T view + , Position4T world + , NormalT normal + , sdw::Vec3 texCoord ) + { + SurfaceBaseT< Position3T, Position4T, NormalT >::fillInit( init, flags, clip, view, world, normal ); + + if ( flags.enableTexcoord0() ) + { + init.emplace_back( makeExpr( texCoord ) ); + } + } + + //***************************************************************************************** + + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T > + RasterizerSurfaceBaseT< Position3T, Position4T, Normal3T, Normal4T >::RasterizerSurfaceBaseT( sdw::ShaderWriter & writer + , sdw::expr::ExprPtr expr + , bool enabled ) + : SurfaceBaseT< Position3T, Position4T, Normal3T >{ writer, castor::move( expr ), enabled } + , curPosition{ this->template getMember< Position4T >( "curPosition", true ) } + , prvPosition{ this->template getMember< Position4T >( "prvPosition", true ) } + , tangentSpaceFragPosition{ this->template getMember< Position3T >( "tangentSpaceFragPosition", true ) } + , tangentSpaceViewPosition{ this->template getMember< sdw::Vec3 >( "tangentSpaceViewPosition", true ) } + , tangent{ this->template getMember< Normal4T >( "tangent", true ) } + , bitangent{ this->template getMember< Normal3T >( "bitangent", true ) } + , colour{ this->template getMember< sdw::Vec3 >( "colour", true ) } + , passMultipliers{ this->template getMemberArray< sdw::Vec4 >( "passMultipliers", true ) } + , nodeId{ this->template getMember< sdw::UInt >( "nodeId", true ) } + , vertexId{ this->template getMember< sdw::UInt >( "vertexId", true ) } + , meshletId{ this->template getMember< sdw::UInt >( "meshletId", true ) } + { + } + + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T > + void RasterizerSurfaceBaseT< Position3T, Position4T, Normal3T, Normal4T >::computeVelocity( CameraData const & cameraData + , Position4T & csCurPos + , Position4T & csPrvPos ) + { + // Convert the jitter from non-homogeneous coordinates to homogeneous + // coordinates and add it: + // (note that for providing the jitter in non-homogeneous projection space, + // pixel coordinates (screen space) need to multiplied by two in the C++ + // code) + cameraData.jitter( csCurPos ); + cameraData.jitter( csPrvPos ); + + curPosition = SurfaceBaseT< Position3T, Position4T, Normal3T >::makePosition4( shader::getXYW( csCurPos ) ); + prvPosition = SurfaceBaseT< Position3T, Position4T, Normal3T >::makePosition4( shader::getXYW( csPrvPos ) ); + + // Positions in projection space are in [-1, 1] range, while texture + // coordinates are in [0, 1] range. So, we divide by 2 to get velocities in + // the scale (and flip the y axis): + shader::mulXY( curPosition, vec2( 0.5_f, -0.5_f ) ); + shader::mulXY( prvPosition, vec2( 0.5_f, -0.5_f ) ); + } + + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T > + void RasterizerSurfaceBaseT< Position3T, Position4T, Normal3T, Normal4T >::computeTangentSpace( PipelineFlags const & flags + , sdw::Vec3 const & cameraPosition + , Position3T const & worldPos + , Normal3T const & nml + , Normal4T const & tan ) + { + if ( flags.enableTangentSpace() ) + { + this->normal = nml; + tangent = tan; + bitangent = cross( this->normal, shader::getXYZ( tangent ) ) * shader::getW( tangent ); + + if ( flags.isFrontCulled() ) + { + this->normal = -this->normal; + shader::negateXYZ( tangent ); + bitangent = -bitangent; + } + + if ( !tangentSpaceFragPosition.getExpr()->isDummy() ) + { + CU_Require( !worldPos.getExpr()->isDummy() ); + CU_Require( !tangentSpaceViewPosition.getExpr()->isDummy() ); + auto tbn = this->getWriter()->declLocale( "tbn" + , transpose( mat3( shader::getRawXYZ( tangent ), shader::getRawXYZ( bitangent ), shader::getRawXYZ( this->normal ) ) ) ); + tangentSpaceFragPosition = tbn * worldPos; + tangentSpaceViewPosition = tbn * cameraPosition.xyz(); + } + } + else if ( this->normal.isEnabled() ) + { + this->normal = nml; + + if ( flags.isFrontCulled() ) + { + this->normal = -this->normal; + } + } + } + + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T > + void RasterizerSurfaceBaseT< Position3T, Position4T, Normal3T, Normal4T >::computeTangentSpace( PipelineFlags const & flags + , sdw::Vec3 const & cameraPosition + , Position3T const & worldPos + , sdw::Mat3 const & mtx + , Normal3T const & nml + , Normal4T const & tan ) + { + return computeTangentSpace( flags + , cameraPosition + , worldPos + , normalize( mtx * nml ) + , SurfaceBaseT< Position3T, Position4T, Normal3T >::makePosition4( normalize( mtx * shader::getXYZ( tan ) ), shader::getW( tan ) ) ); + } + + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T > + void RasterizerSurfaceBaseT< Position3T, Position4T, Normal3T, Normal4T >::computeTangentSpace( PipelineFlags const & flags + , sdw::Vec3 const & cameraPosition + , Position3T const & worldPos + , sdw::Mat3 const & mtx + , Normal3T const & nml + , Normal4T const & tan + , Normal3T const & bin ) + { + if ( bin.isEnabled() ) + { + return computeTangentSpace( flags + , cameraPosition + , worldPos + , normalize( mtx * nml ) + , SurfaceBaseT< Position3T, Position4T, Normal3T >::makePosition4( normalize( mtx * shader::getXYZ( tan ) ), shader::getW( tan ) ) + , normalize( mtx * bin ) ); + } + + return computeTangentSpace( flags + , cameraPosition + , worldPos + , normalize( mtx * nml ) + , SurfaceBaseT< Position3T, Position4T, Normal3T >::makePosition4( normalize( mtx * shader::getXYZ( tan ) ), shader::getW( tan ) ) ); + } + + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T > + void RasterizerSurfaceBaseT< Position3T, Position4T, Normal3T, Normal4T >::computeTangentSpace( PipelineFlags const & flags + , sdw::Vec3 const & cameraPosition + , Position3T const & worldPos + , Normal3T const & nml + , Normal4T const & tan + , Normal3T const & bin ) + { + if ( bin.isEnabled() ) + { + if ( flags.enableTangentSpace() ) + { + this->normal = nml; + tangent = tan; + bitangent = bin; + + if ( flags.isFrontCulled() ) + { + this->normal = -this->normal; + shader::negateXYZ( tangent ); + bitangent = -bitangent; + } + + if ( !tangentSpaceFragPosition.getExpr()->isDummy() ) + { + CU_Require( !worldPos.getExpr()->isDummy() ); + CU_Require( !tangentSpaceViewPosition.getExpr()->isDummy() ); + auto tbn = this->getWriter()->declLocale( "tbn" + , transpose( mat3( shader::getRawXYZ( tangent ), shader::getRawXYZ( bitangent ), shader::getRawXYZ( this->normal ) ) ) ); + tangentSpaceFragPosition = tbn * worldPos; + tangentSpaceViewPosition = tbn * cameraPosition.xyz(); + } + } + else + { + this->normal = nml; + + if ( flags.isFrontCulled() ) + { + this->normal = -this->normal; + } + } + } + else + { + computeTangentSpace( flags, cameraPosition, worldPos, nml, tan ); + } + } + + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T > + sdw::Vec2 RasterizerSurfaceBaseT< Position3T, Position4T, Normal3T, Normal4T >::getVelocity()const + { + return ( curPosition.xy() / curPosition.z() ) - ( prvPosition.xy() / prvPosition.z() ); + } + + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T > + void RasterizerSurfaceBaseT< Position3T, Position4T, Normal3T, Normal4T >::fillIOType( sdw::type::IOStruct & type + , SubmeshShaders const & submeshShaders + , PassShaders const & shaders + , PipelineFlags const & flags + , uint32_t & index ) + { + SurfaceBaseT< Position3T, Position4T, Normal3T >::fillIOType( type, flags, index ); + type.declMember( "nodeId", ast::type::Kind::eUInt + , ast::type::NotArray + , index ); + ++index; + type.declMember( "vertexId" + , ast::type::Kind::eUInt + , ast::type::NotArray + , ( flags.enableVertexID() ? index++ : 0 ) + , flags.enableVertexID() ); + type.declMember( "meshletId" + , ast::type::Kind::eUInt + , ast::type::NotArray + , ( flags.enableMeshletID() ? index++ : 0 ) + , flags.enableMeshletID() ); + type.declMember( "curPosition" + , Position4T::makeType( type.getTypesCache() ) + , ast::type::NotArray + , ( flags.writeVelocity() ? index++ : 0 ) + , flags.writeVelocity() ); + type.declMember( "prvPosition" + , Position4T::makeType( type.getTypesCache() ) + , ast::type::NotArray + , ( flags.writeVelocity() ? index++ : 0 ) + , flags.writeVelocity() ); + type.declMember( "tangentSpaceFragPosition" + , Position3T::makeType( type.getTypesCache() ) + , ast::type::NotArray + , ( shaders.enableParallaxOcclusionMapping( flags ) ? index++ : 0 ) + , shaders.enableParallaxOcclusionMapping( flags ) ); + type.declMember( "tangentSpaceViewPosition" + , ast::type::Kind::eVec3F + , ast::type::NotArray + , ( shaders.enableParallaxOcclusionMapping( flags) ? index++ : 0 ) + , shaders.enableParallaxOcclusionMapping( flags ) ); + type.declMember( "tangent" + , Normal4T::makeType( type.getTypesCache() ) + , ( flags.enableTangentSpace() ? index++ : 0 ) + , flags.enableTangentSpace() ); + type.declMember( "bitangent" + , Normal3T::makeType( type.getTypesCache() ) + , ast::type::NotArray + , ( ( flags.enableBitangent() || flags.enableTangentSpace() ) ? index++ : 0 ) + , ( flags.enableBitangent() || flags.enableTangentSpace() ) ); + type.declMember( "colour", ast::type::Kind::eVec3F + , ast::type::NotArray + , ( flags.enableColours() ? index++ : 0 ) + , flags.enableColours() ); + type.declMember( "passMultipliers" + , ast::type::Kind::eVec4F + , 4u + , ( flags.enablePassMasks() ? index : 0 ) + , flags.enablePassMasks() ); + + if ( flags.enablePassMasks() ) + { + index += 4u; + } + + submeshShaders.fillRasterSurface( type, index ); + } + + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T > + void RasterizerSurfaceBaseT< Position3T, Position4T, Normal3T, Normal4T >::fillType( sdw::type::BaseStruct & type + , SubmeshShaders const & submeshShaders + , PassShaders const & shaders + , PipelineFlags const & flags ) + { + SurfaceBaseT< Position3T, Position4T, Normal3T >::fillType( type, flags ); + type.declMember( "nodeId" + , ast::type::Kind::eUInt + , ast::type::NotArray ); + type.declMember( "vertexId" + , ast::type::Kind::eUInt + , ast::type::NotArray + , flags.enableVertexID() ); + type.declMember( "meshletId" + , ast::type::Kind::eUInt + , ast::type::NotArray + , flags.enableMeshletID() ); + type.declMember( "curPosition" + , Position4T::makeType( type.getTypesCache() ) + , ast::type::NotArray + , flags.writeVelocity() ); + type.declMember( "prvPosition" + , Position4T::makeType( type.getTypesCache() ) + , ast::type::NotArray + , flags.writeVelocity() ); + type.declMember( "tangentSpaceFragPosition" + , Position3T::makeType( type.getTypesCache() ) + , ast::type::NotArray + , shaders.enableParallaxOcclusionMapping( flags ) ); + type.declMember( "tangentSpaceViewPosition" + , ast::type::Kind::eVec3F + , ast::type::NotArray + , shaders.enableParallaxOcclusionMapping( flags ) ); + type.declMember( "tangent" + , Normal4T::makeType( type.getTypesCache() ) + , ast::type::NotArray + , flags.enableTangentSpace() ); + type.declMember( "bitangent" + , Normal3T::makeType( type.getTypesCache() ) + , ast::type::NotArray + , flags.enableBitangent() || flags.enableTangentSpace() ); + type.declMember( "colour" + , ast::type::Kind::eVec3F + , ast::type::NotArray + , flags.enableColours() ); + type.declMember( "passMultipliers" + , ast::type::Kind::eVec4F + , 4u + , flags.enablePassMasks() ); + submeshShaders.fillRasterSurface( type ); + } + + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T > + void RasterizerSurfaceBaseT< Position3T, Position4T, Normal3T, Normal4T >::fillType( sdw::type::BaseStruct & type + , SubmeshShaders const & submeshShaders ) + { + SurfaceBaseT< Position3T, Position4T, Normal3T >::fillType( type ); + type.declMember( "nodeId", ast::type::Kind::eUInt + , ast::type::NotArray ); + type.declMember( "vertexId", ast::type::Kind::eUInt + , ast::type::NotArray ); + type.declMember( "meshletId", ast::type::Kind::eUInt + , ast::type::NotArray ); + type.declMember( "curPosition", Position4T::makeType( type.getTypesCache() ) + , ast::type::NotArray ); + type.declMember( "prvPosition", Position4T::makeType( type.getTypesCache() ) + , ast::type::NotArray ); + type.declMember( "tangentSpaceFragPosition", Position3T::makeType( type.getTypesCache() ) + , ast::type::NotArray ); + type.declMember( "tangentSpaceViewPosition", ast::type::Kind::eVec3F + , ast::type::NotArray ); + type.declMember( "tangent", Normal4T::makeType( type.getTypesCache() ) + , ast::type::NotArray ); + type.declMember( "bitangent", Normal3T::makeType( type.getTypesCache() ) + , ast::type::NotArray ); + type.declMember( "colour", ast::type::Kind::eVec3F + , ast::type::NotArray ); + type.declMember( "passMultipliers", ast::type::Kind::eVec4F + , 4u ); + submeshShaders.fillRasterSurface( type ); + } + + //***************************************************************************************** + + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T, typename TexcoordT, ast::var::Flag FlagT > + RasterizerSurfaceT< Position3T, Position4T, Normal3T, Normal4T, TexcoordT, FlagT >::RasterizerSurfaceT( sdw::ShaderWriter & writer , sdw::expr::ExprPtr expr , bool enabled ) - : RasterizerSurfaceBase{ writer, castor::move( expr ), enabled } - , texture0{ this->getMember< TexcoordT >( "texture0", true ) } - , texture1{ this->getMember< TexcoordT >( "texture1", true ) } - , texture2{ this->getMember< TexcoordT >( "texture2", true ) } - , texture3{ this->getMember< TexcoordT >( "texture3", true ) } + : RasterizerSurfaceBaseT< Position3T, Position4T, Normal3T, Normal4T >{ writer, castor::move( expr ), enabled } + , texture0{ this->template getMember< TexcoordT >( "texture0", true ) } + , texture1{ this->template getMember< TexcoordT >( "texture1", true ) } + , texture2{ this->template getMember< TexcoordT >( "texture2", true ) } + , texture3{ this->template getMember< TexcoordT >( "texture3", true ) } { } - template< typename TexcoordT, ast::var::Flag FlagT > - RasterizerSurfaceT< TexcoordT, FlagT >::RasterizerSurfaceT( sdw::Vec3 clip - , sdw::Vec3 view - , sdw::Vec3 world - , sdw::Vec3 normal + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T, typename TexcoordT, ast::var::Flag FlagT > + RasterizerSurfaceT< Position3T, Position4T, Normal3T, Normal4T, TexcoordT, FlagT >::RasterizerSurfaceT( sdw::Vec3 clip + , Position3T view + , Position3T world + , Normal3T normal , TexcoordT coord ) : RasterizerSurfaceT{ findWriterMandat( clip, view, world, normal, coord ) , sdw::makeAggrInit( makeType( findTypesCache( clip, view, world, normal, coord ) ) , [&clip, &view, &world, &normal, &coord]() { sdw::expr::ExprList result; - SurfaceBase::fillInit( result, clip, vec4( view, 1.0_f ), vec4( world, 1.0_f ), normal ); + SurfaceBaseT< Position3T, Position4T, Normal3T >::fillInit( result + , clip + , SurfaceBaseT< Position3T, Position4T, Normal3T >::makePosition4( view ) + , SurfaceBaseT< Position3T, Position4T, Normal3T >::makePosition4( world ) + , normal ); result.emplace_back( makeExpr( coord ) ); return result; }() ) @@ -99,17 +683,17 @@ namespace castor3d::shader { } - template< typename TexcoordT, ast::var::Flag FlagT > + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T, typename TexcoordT, ast::var::Flag FlagT > template< ast::var::Flag FlagU > - RasterizerSurfaceT< TexcoordT, FlagT >::RasterizerSurfaceT( RasterizerSurfaceT< TexcoordT, FlagU > const & rhs ) + RasterizerSurfaceT< Position3T, Position4T, Normal3T, Normal4T, TexcoordT, FlagT >::RasterizerSurfaceT( RasterizerSurfaceT< Position3T, Position4T, Normal3T, Normal4T, TexcoordT, FlagU > const & rhs ) : RasterizerSurfaceT{ *rhs.getWriter() , sdw::makeAggrInit( rhs.getType(), rhs.makeAggrInit() ) , rhs.isEnabled() } { } - template< typename TexcoordT, ast::var::Flag FlagT > - ast::type::IOStructPtr RasterizerSurfaceT< TexcoordT, FlagT >::makeIOType( ast::type::TypesCache & cache + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T, typename TexcoordT, ast::var::Flag FlagT > + ast::type::IOStructPtr RasterizerSurfaceT< Position3T, Position4T, Normal3T, Normal4T, TexcoordT, FlagT >::makeIOType( ast::type::TypesCache & cache , sdw::EntryPoint entryPoint , SubmeshShaders const & submeshShaders , PassShaders const & passShaders @@ -123,7 +707,7 @@ namespace castor3d::shader { auto texType = TexcoordT::makeType( cache ); uint32_t index = 0u; - RasterizerSurfaceBase::fillIOType( *result, submeshShaders, passShaders, flags, index ); + RasterizerSurfaceBaseT< Position3T, Position4T, Normal3T, Normal4T >::fillIOType( *result, submeshShaders, passShaders, flags, index ); result->declMember( "texture0", texType , ast::type::NotArray , ( flags.enableTexcoord0() ? index++ : 0 ) @@ -145,8 +729,8 @@ namespace castor3d::shader return result; } - template< typename TexcoordT, ast::var::Flag FlagT > - ast::type::BaseStructPtr RasterizerSurfaceT< TexcoordT, FlagT >::makeType( ast::type::TypesCache & cache + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T, typename TexcoordT, ast::var::Flag FlagT > + ast::type::BaseStructPtr RasterizerSurfaceT< Position3T, Position4T, Normal3T, Normal4T, TexcoordT, FlagT >::makeType( ast::type::TypesCache & cache , SubmeshShaders const & submeshShaders , PassShaders const & passShaders , PipelineFlags const & flags ) @@ -157,7 +741,7 @@ namespace castor3d::shader if ( result->empty() ) { auto texType = TexcoordT::makeType( cache ); - RasterizerSurfaceBase::fillType( *result, submeshShaders, passShaders, flags ); + RasterizerSurfaceBaseT< Position3T, Position4T, Normal3T, Normal4T >::fillType( *result, submeshShaders, passShaders, flags ); result->declMember( "texture0", texType , ast::type::NotArray , flags.enableTexcoord0() ); @@ -175,8 +759,8 @@ namespace castor3d::shader return result; } - template< typename TexcoordT, ast::var::Flag FlagT > - ast::type::BaseStructPtr RasterizerSurfaceT< TexcoordT, FlagT >::makeType( ast::type::TypesCache & cache + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T, typename TexcoordT, ast::var::Flag FlagT > + ast::type::BaseStructPtr RasterizerSurfaceT< Position3T, Position4T, Normal3T, Normal4T, TexcoordT, FlagT >::makeType( ast::type::TypesCache & cache , SubmeshShaders const & submeshShaders ) { auto result = cache.getStruct( ast::type::MemoryLayout::eC, "C3D_RasterSurface" ); @@ -184,7 +768,7 @@ namespace castor3d::shader if ( result->empty() ) { auto texType = TexcoordT::makeType( cache ); - RasterizerSurfaceBase::fillType( *result, submeshShaders ); + RasterizerSurfaceBaseT< Position3T, Position4T, Normal3T, Normal4T >::fillType( *result, submeshShaders ); result->declMember( "texture0", texType , ast::type::NotArray ); result->declMember( "texture1", texType diff --git a/include/Core/Castor3D/Shader/Shaders/GlslTextureConfiguration.hpp b/include/Core/Castor3D/Shader/Shaders/GlslTextureConfiguration.hpp index afe6689a31..1c39c36803 100644 --- a/include/Core/Castor3D/Shader/Shaders/GlslTextureConfiguration.hpp +++ b/include/Core/Castor3D/Shader/Shaders/GlslTextureConfiguration.hpp @@ -5,6 +5,7 @@ See LICENSE file in root folder #define ___GLSL_TextureConfiguration_H___ #include "GlslBuffer.hpp" +#include "GlslDerivativeValue.hpp" #include "GlslTextureTransform.hpp" #include @@ -88,6 +89,11 @@ namespace castor3d::shader auto isTileAnim()const { return getMember< "isTileAnim" >() != 0_u; } auto texSet()const { return getMember< "texSet" >(); } + C3D_API sdw::Vec2 getUv( DerivTex const & uvw )const; + C3D_API void setUv( DerivTex & lhs + , DerivTex const & rhs )const; + C3D_API DerivTex toUv( DerivTex const & uvw )const; + sdw::Vec2 getUv( sdw::Vec3 const & uvw )const { return uvw.xy(); @@ -104,22 +110,6 @@ namespace castor3d::shader lhs.xy() = rhs; } - sdw::Vec2 getUv( DerivTex const & uvw )const - { - return uvw.uv(); - } - - DerivTex toUv( DerivTex const & uvw )const - { - return uvw; - } - - void setUv( DerivTex & lhs - , DerivTex const & rhs )const - { - lhs.uv() = rhs.uv(); - } - sdw::Float fneedYI; }; diff --git a/include/Core/Castor3D/Shader/Shaders/GlslUtils.hpp b/include/Core/Castor3D/Shader/Shaders/GlslUtils.hpp index 3eff7e2d94..94ca50a9f5 100644 --- a/include/Core/Castor3D/Shader/Shaders/GlslUtils.hpp +++ b/include/Core/Castor3D/Shader/Shaders/GlslUtils.hpp @@ -95,6 +95,11 @@ namespace castor3d::shader , sdw::Vec3 const & f90 ); C3D_API sdw::RetVec3 conductorFresnel( sdw::Float const & product , sdw::Vec3 const & f0 ); + C3D_API RetDerivVec3 conductorFresnel( DerivFloat const & product + , sdw::Vec3 const & f0 + , sdw::Vec3 const & f90 ); + C3D_API RetDerivVec3 conductorFresnel( DerivFloat const & product + , sdw::Vec3 const & f0 ); C3D_API sdw::RetFloat fresnelMix( sdw::Float const & VdotH , sdw::Float const & refractionRatio ); C3D_API sdw::RetFloat fresnelMix( sdw::Vec3 const & incident @@ -210,6 +215,10 @@ namespace castor3d::shader , sdw::InFloat , sdw::InVec3 , sdw::InVec3 > m_conductorFresnel3; + sdw::Function< DerivVec3 + , InDerivFloat + , sdw::InVec3 + , sdw::InVec3 > m_conductorFresnelDeriv3; sdw::Function< sdw::Vec3 , sdw::InVec3 , sdw::InFloat > m_fresnelToF0; diff --git a/include/Core/Castor3D/Shader/Shaders/SdwModule.hpp b/include/Core/Castor3D/Shader/Shaders/SdwModule.hpp index 204d2d289b..0ee6d1d25c 100644 --- a/include/Core/Castor3D/Shader/Shaders/SdwModule.hpp +++ b/include/Core/Castor3D/Shader/Shaders/SdwModule.hpp @@ -84,7 +84,6 @@ namespace castor3d::shader struct AABB; struct Cone; - struct DerivTex; struct DirectionalLight; struct DirectionalShadowData; struct DirectLighting; @@ -112,11 +111,16 @@ namespace castor3d::shader struct VoxelData; struct BlendComponents; - struct SurfaceBase; - struct RasterizerSurfaceBase; - struct Surface; - template< typename TexcoordT, ast::var::Flag FlagT > + template< typename Position3T, typename Position4T, typename NormalT > + struct SurfaceBaseT; + + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T > + struct RasterizerSurfaceBaseT; + + template< typename Position3T, typename Position4T, typename NormalT > + struct SurfaceT; + template< typename Position3T, typename Position4T, typename Normal3T, typename Normal4T, typename TexcoordT, ast::var::Flag FlagT > struct RasterizerSurfaceT; template< ast::var::Flag FlagT > struct MeshVertexT; @@ -132,13 +136,29 @@ namespace castor3d::shader struct PosUvT; template< typename UvTypeT, sdw::var::Flag FlagT > struct UvT; + template< typename ValueT, sdw::StringLiteralT StructNameT > + struct DerivativeValueT; + + using DerivFloat = DerivativeValueT< sdw::Float, "C3D_DerivFloat" >; + using DerivVec2 = DerivativeValueT< sdw::Vec2, "C3D_DerivVec2" >; + using DerivVec3 = DerivativeValueT< sdw::Vec3, "C3D_DerivVec3" >; + using DerivVec4 = DerivativeValueT< sdw::Vec4, "C3D_DerivVec4" >; + using DerivTex = DerivVec2; + + using SurfaceBase = SurfaceBaseT< sdw::Vec3, sdw::Vec4, sdw::Vec3 >; + using Surface = SurfaceT< sdw::Vec3, sdw::Vec4, sdw::Vec3 >; + using DerivSurfaceBase = SurfaceBaseT< DerivVec3, DerivVec4, DerivVec3 >; + using DerivSurface = SurfaceT< DerivVec3, DerivVec4, DerivVec3 >; + using RasterizerSurfaceBase = RasterizerSurfaceBaseT< sdw::Vec3, sdw::Vec4, sdw::Vec3, sdw::Vec4 >; + using DerivRasterizerSurfaceBase = RasterizerSurfaceBaseT< DerivVec3, DerivVec4, DerivVec3, DerivVec4 >; template< ast::var::Flag FlagT > - using FragmentSurfaceT = RasterizerSurfaceT< sdw::Vec3, FlagT >; - using RasterizerSurface = RasterizerSurfaceT< sdw::Vec3, ast::var::Flag::eNone >; - using DerivFragmentSurface = RasterizerSurfaceT< DerivTex, ast::var::Flag::eNone >; + using FragmentSurfaceT = RasterizerSurfaceT< sdw::Vec3, sdw::Vec4, sdw::Vec3, sdw::Vec4, sdw::Vec3, FlagT >; + using RasterizerSurface = RasterizerSurfaceT< sdw::Vec3, sdw::Vec4, sdw::Vec3, sdw::Vec4, sdw::Vec3, ast::var::Flag::eNone >; + using DerivFragmentSurface = RasterizerSurfaceT< sdw::Vec3, sdw::Vec4, sdw::Vec3, sdw::Vec4, DerivTex, ast::var::Flag::eNone >; + using AllDerivFragmentSurface = RasterizerSurfaceT< DerivVec3, DerivVec4, DerivVec3, DerivVec4, DerivTex, ast::var::Flag::eNone >; template< typename TexcoordT > - using RasterSurfaceT = RasterizerSurfaceT< TexcoordT, ast::var::Flag::eNone >; + using RasterSurfaceT = RasterizerSurfaceT< sdw::Vec3, sdw::Vec4, sdw::Vec3, sdw::Vec4, TexcoordT, ast::var::Flag::eNone >; using MeshVertex = MeshVertexT< sdw::var::Flag::eNone >; using VoxelSurface = VoxelSurfaceT< sdw::var::Flag::eNone >; using OverlaySurface = OverlaySurfaceT< sdw::var::Flag::eNone >; @@ -232,9 +252,14 @@ namespace castor3d::shader , BackgroundModelID >; Writer_Parameter( AABB ); + Writer_Parameter( AllDerivFragmentSurface ); Writer_Parameter( BlendComponents ); Writer_Parameter( Cone ); + Writer_Parameter( DerivFloat ); Writer_Parameter( DerivTex ); + Writer_Parameter( DerivVec2 ); + Writer_Parameter( DerivVec3 ); + Writer_Parameter( DerivVec4 ); Writer_Parameter( DerivFragmentSurface ); Writer_Parameter( DirectionalLight ); Writer_Parameter( DirectionalShadowData ); @@ -268,44 +293,6 @@ namespace castor3d::shader C3D_API castor::String concatModelNames( castor::String lhs , castor::String rhs ); - struct DerivTex - : public sdw::StructInstanceHelperT< "C3D_DerivTex" - , sdw::type::MemoryLayout::eC - , sdw::Vec2Field< "uv" > - , sdw::Vec2Field< "dPdx" > - , sdw::Vec2Field< "dPdy" > > - { - DerivTex( sdw::ShaderWriter & writer - , ast::expr::ExprPtr expr - , bool enabled ) - : StructInstanceHelperT{ writer, castor::move( expr ), enabled } - { - } - - DerivTex( sdw::Vec2 const & puv - , sdw::Vec2 const & pdPdx - , sdw::Vec2 const & pdPdy ) - : DerivTex{ sdw::findWriterMandat( puv, pdPdx, pdPdy ) - , sdw::makeAggrInit( makeType( puv.getType()->getTypesCache() ) - , [&puv, &pdPdx, &pdPdy]() - { - sdw::expr::ExprList result; - result.emplace_back( makeExpr( puv ) ); - result.emplace_back( makeExpr( pdPdx ) ); - result.emplace_back( makeExpr( pdPdy ) ); - return result; - }() ) - , true } - { - } - - C3D_API sdw::Float computeMip( sdw::Vec2 const & texSize )const; - - auto uv()const { return getMember< "uv" >(); } - auto dPdx()const { return getMember< "dPdx" >(); } - auto dPdy()const { return getMember< "dPdy" >(); } - }; - struct BufferData : public sdw::StructInstanceHelperT < "C3D_BufferData" , sdw::type::MemoryLayout::eStd430 diff --git a/include/Core/Castor3D/Shader/Ubos/CameraUbo.hpp b/include/Core/Castor3D/Shader/Ubos/CameraUbo.hpp index c8b79a0c0c..4bc08e29d1 100644 --- a/include/Core/Castor3D/Shader/Ubos/CameraUbo.hpp +++ b/include/Core/Castor3D/Shader/Ubos/CameraUbo.hpp @@ -51,14 +51,17 @@ namespace castor3d } C3D_API sdw::Vec4 projToView( sdw::Vec4 const & psPosition )const; + C3D_API DerivVec4 projToView( DerivVec4 const & psPosition )const; C3D_API sdw::Vec4 viewToProj( sdw::Vec4 const & vsPosition )const; C3D_API sdw::Vec3 worldToCurView( sdw::Vec3 const & wsPosition )const; C3D_API sdw::Vec4 worldToCurView( sdw::Vec4 const & wsPosition )const; C3D_API sdw::Vec4 worldToPrvView( sdw::Vec4 const & wsPosition )const; C3D_API sdw::Vec4 curViewToWorld( sdw::Vec4 const & vsPosition )const; + C3D_API DerivVec4 curViewToWorld( DerivVec4 const & vsPosition )const; C3D_API sdw::Vec4 prvViewToWorld( sdw::Vec4 const & vsPosition )const; C3D_API sdw::Vec4 worldToCurProj( sdw::Vec4 const & wsPosition )const; C3D_API sdw::Vec4 worldToPrvProj( sdw::Vec4 const & wsPosition )const; + C3D_API DerivVec4 worldToPrvProj( DerivVec4 const & wsPosition )const; C3D_API sdw::Vec2 viewToScreenUV( Utils & utils , sdw::Vec4 vsPosition )const; C3D_API sdw::Vec2 worldToCurScreenUV( Utils & utils @@ -86,6 +89,7 @@ namespace castor3d C3D_API sdw::Vec3 getPrvViewCenter()const; C3D_API sdw::Mat4 getInvViewProjMtx()const; C3D_API void jitter( sdw::Vec4 & csPosition )const; + C3D_API void jitter( DerivVec4 & csPosition )const; C3D_API sdw::Vec3 transformCamera( sdw::Mat3 const & transform )const; C3D_API sdw::Vec3 getPosToCamera( sdw::Vec3 const & position )const; C3D_API sdw::Vec3 getCameraToPos( sdw::Vec3 const & position )const; diff --git a/include/Core/Castor3D/Shader/Ubos/ModelDataUbo.hpp b/include/Core/Castor3D/Shader/Ubos/ModelDataUbo.hpp index 8a84ea622c..cf8cd38567 100644 --- a/include/Core/Castor3D/Shader/Ubos/ModelDataUbo.hpp +++ b/include/Core/Castor3D/Shader/Ubos/ModelDataUbo.hpp @@ -42,6 +42,7 @@ namespace castor3d::shader C3D_API sdw::Mat3 getNormalMtx( PipelineFlags const & flags , sdw::Mat4 const & curModelMatrix )const; C3D_API sdw::Vec4 worldToModel( sdw::Vec4 const & pos )const; + C3D_API DerivVec4 worldToModel( DerivVec4 const & pos )const; C3D_API sdw::Vec4 modelToWorld( sdw::Vec4 const & pos )const; C3D_API sdw::Vec4 modelToCurWorld( sdw::Vec4 const & pos )const; C3D_API sdw::Vec4 modelToPrvWorld( sdw::Vec4 const & pos )const; diff --git a/include/Core/CastorUtils/Config/CompilerConfig.hpp b/include/Core/CastorUtils/Config/CompilerConfig.hpp index 3768a40554..49de41db54 100644 --- a/include/Core/CastorUtils/Config/CompilerConfig.hpp +++ b/include/Core/CastorUtils/Config/CompilerConfig.hpp @@ -46,10 +46,4 @@ See LICENSE file in root folder # error "Yet unsupported compiler" #endif -#if defined( CU_CompilerMSVC ) -# define CU_SharedLibPrefix cuT( "") -#else -# define CU_SharedLibPrefix cuT( "lib") -#endif - #endif diff --git a/include/Core/CastorUtils/Config/Macros.hpp b/include/Core/CastorUtils/Config/Macros.hpp index b00314add5..2e16ebd522 100644 --- a/include/Core/CastorUtils/Config/Macros.hpp +++ b/include/Core/CastorUtils/Config/Macros.hpp @@ -16,11 +16,8 @@ See LICENSE file in root folder # define __FUNCTION__ "" #endif -#define CU_Coucou std::clog << "Coucou " << __COUNTER__ << " : " << __FUNCTION__ << " @ line " << __LINE__ << std::endl; - #if defined( CU_CompilerMSVC ) # include -# define cvsnprintf _vsntprintf_s # if CU_CompilerVersion < 1900 # define sscanf sscanf_s # endif @@ -28,26 +25,20 @@ See LICENSE file in root folder # pragma clang diagnostic ignored "-Wduplicate-enum" # if !defined( CU_PlatformWindows ) # define _FILE_OFFSET_BITS 64 -# define cvsnprintf( buf, sz, cnt, fmt, arg ) vsnprintf( buf, cnt, fmt, arg ) # else # define _FILE_OFFSET_BITS 64 -# define cvsnprintf( buf, sz, cnt, fmt, arg ) vsnprintf( buf, cnt, fmt, arg ) # endif #elif defined( CU_CompilerGNUC ) # if !defined( CU_PlatformWindows ) # define _FILE_OFFSET_BITS 64 -# define cvsnprintf( buf, sz, cnt, fmt, arg ) vsnprintf( buf, cnt, fmt, arg ) # else # define _FILE_OFFSET_BITS 64 -# define cvsnprintf( buf, sz, cnt, fmt, arg ) vsnprintf( buf, cnt, fmt, arg ) # endif #elif defined( CU_CompilerBORLAND ) # if !defined( CU_PlatformWindows ) # define _FILE_OFFSET_BITS 64 -# define cvsnprintf( buf, sz, cnt, fmt, arg ) vsnprintf( buf, cnt, fmt, arg ) # else # define _FILE_OFFSET_BITS 64 -# define cvsnprintf( buf, sz, cnt, fmt, arg ) vsnprintf( buf, cnt, fmt, arg ) # endif #endif diff --git a/include/Core/CastorUtils/Config/PlatformConfig.hpp b/include/Core/CastorUtils/Config/PlatformConfig.hpp index e023db4a56..0a457e923d 100644 --- a/include/Core/CastorUtils/Config/PlatformConfig.hpp +++ b/include/Core/CastorUtils/Config/PlatformConfig.hpp @@ -21,19 +21,21 @@ See LICENSE file in root folder # define CU_API __declspec(dllimport) # endif # define CU_SharedLibExt cuT( "dll" ) +# define CU_SharedLibPrefix cuT( "") # define CU_LibPrefix cuT( "" ) -# define dlerror() ::getLastError() # define CU_stdcall __stdcall # ifndef NOMINMAX # define NOMINMAX # endif #elif defined( CU_PlatformApple ) # define CU_SharedLibExt cuT( "dylib" ) +# define CU_SharedLibPrefix cuT( "lib") # define CU_LibPrefix cuT( "lib" ) # define CU_API # define CU_stdcall #else # define CU_SharedLibExt cuT( "so" ) +# define CU_SharedLibPrefix cuT( "lib") # define CU_LibPrefix cuT( "lib" ) # define CU_API # define CU_stdcall diff --git a/include/Core/CastorUtils/Design/DelayedInitialiser.hpp b/include/Core/CastorUtils/Design/DelayedInitialiser.hpp deleted file mode 100644 index a36dfbf417..0000000000 --- a/include/Core/CastorUtils/Design/DelayedInitialiser.hpp +++ /dev/null @@ -1,269 +0,0 @@ -/* -See LICENSE file in root folder -*/ -#ifndef ___CU_DelayedInitialiser_H___ -#define ___CU_DelayedInitialiser_H___ - -#include "DesignModule.hpp" - -#include "CastorUtils/Config/BeginExternHeaderGuard.hpp" -#include -#include -#include "CastorUtils/Config/EndExternHeaderGuard.hpp" - -namespace castor -{ -#if defined( CU_NoDelayedInit ) - template< typename TypeT > - class DelayedInitialiserT - { - public: - template< typename RhsT > - friend class DelayedInitialiserT; - - DelayedInitialiserT( DelayedInitialiserT const & rhs ) = delete; - DelayedInitialiserT & operator=( DelayedInitialiserT const & rhs ) = delete; - DelayedInitialiserT( DelayedInitialiserT && rhs )noexcept = default; - DelayedInitialiserT & operator=( DelayedInitialiserT && rhs )noexcept = default; - ~DelayedInitialiserT()noexcept = default; - - explicit DelayedInitialiserT( castor::RawUniquePtr< TypeT > ptr = nullptr ) - : m_ptr{ castor::move( ptr ) } - { - } - - template< typename RhsT, typename ... ParamsT > - static DelayedInitialiserT make( ParamsT && ... params ) - { - static_assert( std::is_same_v< TypeT, RhsT > || std::is_base_of_v< TypeT, RhsT > ); - return DelayedInitialiserT{ castor::make_unique< RhsT >( castor::forward< ParamsT >( params )... ) }; - } - - template< typename RhsT > - DelayedInitialiserT & operator=( DelayedInitialiserT< RhsT > && rhs ) - { - static_assert( std::is_same_v< TypeT, RhsT > || std::is_base_of_v< TypeT, RhsT > ); - m_ptr = castor::move( rhs.m_ptr ); - return *this; - } - - DelayedInitialiserT & operator=( castor::RawUniquePtr< TypeT > ptr ) - { - m_ptr = castor::move( ptr ); - return *this; - } - - TypeT & operator*() - { - return *m_ptr; - } - - TypeT const & operator*()const - { - return *m_ptr; - } - - TypeT * operator->() - { - return m_ptr.get(); - } - - TypeT const * operator->()const - { - return m_ptr.get(); - } - - TypeT * get()const - { - return m_ptr.get(); - } - - TypeT * raw()const - { - return m_ptr.get(); - } - - void reset() - { - m_ptr.reset(); - } - - operator bool()const - { - return bool( m_ptr ); - } - - template< typename ... ParamsT > - void cleanup( ParamsT && ... params ) - { - CU_Require( m_ptr ); - m_ptr->cleanup( castor::forward< ParamsT >( params )... ); - } - - template< typename ... ParamsT > - void initialise( ParamsT && ... params ) - { - CU_Require( m_ptr ); - m_ptr->initialise( castor::forward< ParamsT >( params )... ); - } - - private: - castor::RawUniquePtr< TypeT > m_ptr; - }; -#else - template< typename TypeT > - class DelayedInitialiserT - { - public: - template< typename RhsT > - friend class DelayedInitialiserT; - - DelayedInitialiserT( DelayedInitialiserT const & rhs ) = delete; - DelayedInitialiserT & operator=( DelayedInitialiserT const & rhs ) = delete; - DelayedInitialiserT( DelayedInitialiserT && rhs )noexcept = default; - DelayedInitialiserT & operator=( DelayedInitialiserT && rhs )noexcept = default; - ~DelayedInitialiserT()noexcept = default; - - explicit DelayedInitialiserT( castor::RawUniquePtr< TypeT > ptr = nullptr ) - : m_ptr{ castor::move( ptr ) } - { - } - - template< typename RhsT, typename ... ParamsT > - static DelayedInitialiserT make( ParamsT && ... params ) - { - static_assert( std::is_same_v< TypeT, RhsT > || std::is_base_of_v< TypeT, RhsT > ); - return DelayedInitialiserT{ castor::make_unique< RhsT >( castor::forward< ParamsT >( params )... ) }; - } - - template< typename RhsT > - DelayedInitialiserT & operator=( DelayedInitialiserT< RhsT > && rhs ) - { - static_assert( std::is_same_v< TypeT, RhsT > || std::is_base_of_v< TypeT, RhsT > ); - m_ptr = castor::move( rhs.m_ptr ); - m_initialised = rhs.m_initialised.exchange( false ); - m_initialiseExecuted = rhs.m_initialiseExecuted.exchange( false ); - m_initialise = castor::move( rhs.m_initialise ); - return *this; - } - - DelayedInitialiserT & operator=( castor::RawUniquePtr< TypeT > ptr ) - { - m_ptr = castor::move( ptr ); - - if ( m_initialised.exchange( false ) ) - { - m_initialise = [](){}; - m_initialiseExecuted = false; - } - - return *this; - } - - TypeT & operator*() - { - checkInitialise(); - return *m_ptr; - } - - TypeT const & operator*()const - { - checkInitialise(); - return *m_ptr; - } - - TypeT * operator->() - { - checkInitialise(); - return m_ptr.get(); - } - - TypeT const * operator->()const - { - checkInitialise(); - return m_ptr.get(); - } - - TypeT * get()const - { - checkInitialise(); - return m_ptr.get(); - } - - TypeT * raw()const - { - return m_ptr.get(); - } - - void reset() - { - m_ptr.reset(); - } - - operator bool()const - { - return bool( m_ptr ); - } - - template< typename ... ParamsT > - void cleanup( ParamsT && ... params ) - { - CU_Require( m_ptr ); - if ( m_initialised.exchange( false ) ) - { - if ( m_initialiseExecuted.exchange( false ) ) - { - m_ptr->cleanup( castor::forward< ParamsT >( params )... ); - } - - m_initialise = [](){}; - } - } - - template< typename ... ParamsT > - void initialise( ParamsT && ... params ) - { - CU_Require( m_ptr ); - if ( !m_initialised.exchange( true ) ) - { - m_initialise = [this, ¶ms...]() - { - m_ptr->initialise( castor::forward< ParamsT >( params )... ); - m_initialiseExecuted = true; - m_initialise = []() - {}; - }; - } - } - - private: - void checkInitialise()const - { - if ( m_initialised ) - { - m_initialise(); - } - } - - private: - castor::RawUniquePtr< TypeT > m_ptr; - std::atomic_bool m_initialised{ false }; - std::atomic_bool m_initialiseExecuted{ false }; - castor::Function< void() > m_initialise{ [](){} }; - }; -#endif - - template< typename LhsT, typename RhsT, typename ... ParamsT > - inline DelayedInitialiserT< LhsT > makeDerivedDelayedInitialiser( ParamsT && ... params ) - { - return DelayedInitialiserT< LhsT >::template make< RhsT >( castor::forward< ParamsT >( params )... ); - } - - template< typename LhsT, typename ... ParamsT > - inline DelayedInitialiserT< LhsT > makeDelayedInitialiser( ParamsT && ... params ) - { - return DelayedInitialiserT< LhsT >::template make< LhsT >( castor::forward< ParamsT >( params )... ); - } -} - -#endif diff --git a/include/Core/CastorUtils/Design/DesignModule.hpp b/include/Core/CastorUtils/Design/DesignModule.hpp index fda1a74712..49bb839a8c 100644 --- a/include/Core/CastorUtils/Design/DesignModule.hpp +++ b/include/Core/CastorUtils/Design/DesignModule.hpp @@ -125,14 +125,6 @@ namespace castor template< class Data, size_t Index = 0u > class DataHolderT; /** - \~english - \brief Used to delay initialisation of an object to next use of it. - \~french - \brief Utilisé pour délayer l'initialisation d'un objet à sa prochaine utilisation. - */ - template< typename TypeT > - class DelayedInitialiserT; - /** *\~english *\brief * Dynamic bitset class, with configurable block type. diff --git a/include/Core/CastorUtils/Math/Matrix.hpp b/include/Core/CastorUtils/Math/Matrix.hpp index 5033dae773..17942fc823 100644 --- a/include/Core/CastorUtils/Math/Matrix.hpp +++ b/include/Core/CastorUtils/Math/Matrix.hpp @@ -18,6 +18,8 @@ namespace castor protected: static const std::size_t count = Rows * Columns; static const std::size_t size = sizeof( T ) * Rows * Columns; + template< typename ... Types > + static bool constexpr isRightSize = sizeof...( Types ) == count; public: //!\~english The data type. @@ -58,6 +60,12 @@ namespace castor explicit Matrix( Matrix< Type, Columns, Rows > const & matrix ); explicit Matrix( std::initializer_list< T > rhs ); ~Matrix()noexcept = default; + + template< typename ... Types > + explicit Matrix( Types && ... inits ) requires isRightSize< Types... > + : Matrix{ Array< T, Columns * Rows >{ std::forward< Types >( inits )... } } + { + } /**@}*/ /** *\~english diff --git a/include/Core/CastorUtils/Math/SquareMatrix.hpp b/include/Core/CastorUtils/Math/SquareMatrix.hpp index 0e9fc76f39..8e0d4b8c29 100644 --- a/include/Core/CastorUtils/Math/SquareMatrix.hpp +++ b/include/Core/CastorUtils/Math/SquareMatrix.hpp @@ -22,6 +22,8 @@ namespace castor using /*value_type = */typename Matrix< T, Count, Count >::value_type; using /*col_type = */typename Matrix< T, Count, Count >::col_type; using /*row_type = */typename Matrix< T, Count, Count >::row_type; + template< typename ... Types > + static bool constexpr isRightSize = sizeof...( Types ) == Count * Count; //!\~english This matrix type //!\~french Le type de cette matrice @@ -57,6 +59,12 @@ namespace castor template< typename Type > explicit SquareMatrix( Type const * rhs ); explicit SquareMatrix( std::initializer_list< T > rhs ); + + template< typename ... Types > + explicit SquareMatrix( Types && ... inits ) requires isRightSize< Types... > + : matrix_type{ std::forward< Types >( inits )... } + { + } /**@}*/ /** *\~english diff --git a/source/Core/Castor3D/CMakeLists.txt b/source/Core/Castor3D/CMakeLists.txt index 9c5e818939..5ae106d145 100644 --- a/source/Core/Castor3D/CMakeLists.txt +++ b/source/Core/Castor3D/CMakeLists.txt @@ -1984,6 +1984,7 @@ set( ${PROJECT_NAME}_FOLDER_SRC_FILES ${CASTOR_SOURCE_DIR}/source/Core/${PROJECT_NAME}/Shader/Shaders/GlslCookTorranceBRDF.cpp ${CASTOR_SOURCE_DIR}/source/Core/${PROJECT_NAME}/Shader/Shaders/GlslCullData.cpp ${CASTOR_SOURCE_DIR}/source/Core/${PROJECT_NAME}/Shader/Shaders/GlslDebugOutput.cpp + ${CASTOR_SOURCE_DIR}/source/Core/${PROJECT_NAME}/Shader/Shaders/GlslDerivativeValue.cpp ${CASTOR_SOURCE_DIR}/source/Core/${PROJECT_NAME}/Shader/Shaders/GlslFog.cpp ${CASTOR_SOURCE_DIR}/source/Core/${PROJECT_NAME}/Shader/Shaders/GlslFont.cpp ${CASTOR_SOURCE_DIR}/source/Core/${PROJECT_NAME}/Shader/Shaders/GlslGlobalIllumination.cpp @@ -2020,6 +2021,8 @@ set( ${PROJECT_NAME}_FOLDER_HDR_FILES ${CASTOR_SOURCE_DIR}/include/Core/${PROJECT_NAME}/Shader/Shaders/GlslCookTorranceBRDF.hpp ${CASTOR_SOURCE_DIR}/include/Core/${PROJECT_NAME}/Shader/Shaders/GlslCullData.hpp ${CASTOR_SOURCE_DIR}/include/Core/${PROJECT_NAME}/Shader/Shaders/GlslDebugOutput.hpp + ${CASTOR_SOURCE_DIR}/include/Core/${PROJECT_NAME}/Shader/Shaders/GlslDerivativeValue.hpp + ${CASTOR_SOURCE_DIR}/include/Core/${PROJECT_NAME}/Shader/Shaders/GlslDerivativeValue.inl ${CASTOR_SOURCE_DIR}/include/Core/${PROJECT_NAME}/Shader/Shaders/GlslFog.hpp ${CASTOR_SOURCE_DIR}/include/Core/${PROJECT_NAME}/Shader/Shaders/GlslFont.hpp ${CASTOR_SOURCE_DIR}/include/Core/${PROJECT_NAME}/Shader/Shaders/GlslGlobalIllumination.hpp @@ -2211,6 +2214,7 @@ else () endif () endif () +set( mikktspace_DIR ${VCPKG_SHARE_DIR}/mikktspace ) find_package( mikktspace CONFIG REQUIRED ) target_link_libraries( ${PROJECT_NAME} diff --git a/source/Core/Castor3D/Engine.cpp b/source/Core/Castor3D/Engine.cpp index 0b5fceace9..3f26a4e2cf 100644 --- a/source/Core/Castor3D/Engine.cpp +++ b/source/Core/Castor3D/Engine.cpp @@ -63,8 +63,6 @@ namespace castor3d namespace eng { static bool constexpr C3D_GenerateBRDFIntegration = false; - - static constexpr bool C3D_EnableAPITrace = false; static castor::StringView constexpr noRenderSystem{ cuT( "No RenderSystem loaded, call castor3d::Engine::loadRenderer before castor3d::Engine::Initialise" ) }; static castor::StringView constexpr defaultName{ cuT( "C3D_Default" ) }; static castor::StringView constexpr samplerName{ cuT( "C3D_Lights" ) }; diff --git a/source/Core/Castor3D/Material/MaterialImporter.cpp b/source/Core/Castor3D/Material/MaterialImporter.cpp index 0883612fb8..1afa177fe3 100644 --- a/source/Core/Castor3D/Material/MaterialImporter.cpp +++ b/source/Core/Castor3D/Material/MaterialImporter.cpp @@ -194,7 +194,7 @@ namespace castor3d } bool allowCompression = !checkFlag( config.textureSpace, TextureSpace::eTangentSpace ); - return TextureSourceInfo{ image->getPath().getFileName( true ) + return TextureSourceInfo{ image->getName() , config , image->getPath().getPath() , image->getPath().getFileName( true ) diff --git a/source/Core/Castor3D/Material/Pass/Component/Base/FractalMappingComponent.cpp b/source/Core/Castor3D/Material/Pass/Component/Base/FractalMappingComponent.cpp index 3509ff102d..1eaed2f1cc 100644 --- a/source/Core/Castor3D/Material/Pass/Component/Base/FractalMappingComponent.cpp +++ b/source/Core/Castor3D/Material/Pass/Component/Base/FractalMappingComponent.cpp @@ -5,6 +5,7 @@ #include "Castor3D/Material/Texture/TextureConfiguration.hpp" #include "Castor3D/Scene/SceneFileParserData.hpp" #include "Castor3D/Shader/Shaders/GlslBlendComponents.hpp" +#include "Castor3D/Shader/Shaders/GlslDerivativeValue.hpp" #include @@ -92,7 +93,26 @@ namespace castor3d if ( surface ) { - inits.emplace_back( sdw::makeExpr( abs( surface->getMember< sdw::Vec3 >( "viewPosition", vec3( 0.0_f ) ).z() ) ) ); + auto & structType = static_cast< ast::type::Struct const & >( *surface->getType() ); + auto index = structType.findMember( "viewPosition" ); + + if ( index != ast::type::Struct::NotFound ) + { + auto member = structType.getMember( index ); + + if ( member.type->getKind() == ast::type::Kind::eStruct ) + { + inits.emplace_back( sdw::makeExpr( abs( surface->getMember< shader::DerivVec3 >( "viewPosition" ).value().z() ) ) ); + } + else + { + inits.emplace_back( sdw::makeExpr( abs( surface->getMember< sdw::Vec3 >( "viewPosition" ).z() ) ) ); + } + } + else + { + inits.emplace_back( sdw::makeExpr( 0.0_f ) ); + } } else { @@ -130,7 +150,7 @@ namespace castor3d } return sampleFractal( map - , texCoords.uv() + , texCoords.value() , texCoords.dPdx() , texCoords.dPdy() , components.getMember< sdw::Float >( "viewDepth" ) ); diff --git a/source/Core/Castor3D/Material/Pass/Component/Base/NormalComponent.cpp b/source/Core/Castor3D/Material/Pass/Component/Base/NormalComponent.cpp index 0a0f775632..4ee5281cdb 100644 --- a/source/Core/Castor3D/Material/Pass/Component/Base/NormalComponent.cpp +++ b/source/Core/Castor3D/Material/Pass/Component/Base/NormalComponent.cpp @@ -6,6 +6,7 @@ #include "Castor3D/Scene/SceneFileParserData.hpp" #include "Castor3D/Shader/ShaderBuffers/PassBuffer.hpp" #include "Castor3D/Shader/Shaders/GlslBlendComponents.hpp" +#include "Castor3D/Shader/Shaders/GlslDerivativeValue.hpp" #include "Castor3D/Shader/Shaders/GlslMaterial.hpp" #include "Castor3D/Shader/Shaders/GlslSurface.hpp" #include "Castor3D/Shader/Shaders/GlslTextureConfiguration.hpp" @@ -31,9 +32,18 @@ namespace castor3d if ( !components.hasMember( "normal" ) ) { - components.declMember( "normal", sdw::type::Kind::eVec3F ); - components.declMember( "tangent", sdw::type::Kind::eVec4F ); - components.declMember( "bitangent", sdw::type::Kind::eVec3F ); + if ( checkFlag( materials.getFilter(), ComponentModeFlag::eDerivTex ) ) + { + components.declMember( "normal", shader::DerivVec3::makeType( components.getTypesCache() ) ); + components.declMember( "tangent", shader::DerivVec4::makeType( components.getTypesCache() ) ); + components.declMember( "bitangent", shader::DerivVec3::makeType( components.getTypesCache() ) ); + } + else + { + components.declMember( "normal", sdw::type::Kind::eVec3F ); + components.declMember( "tangent", sdw::type::Kind::eVec4F ); + components.declMember( "bitangent", sdw::type::Kind::eVec3F ); + } } } @@ -51,15 +61,24 @@ namespace castor3d if ( surface ) { - inits.emplace_back( sdw::makeExpr( surface->getMember< sdw::Vec3 >( "normal", vec3( 0.0_f ) ) ) ); - inits.emplace_back( sdw::makeExpr( surface->getMember< sdw::Vec4 >( "tangent", vec4( 0.0_f ) ) ) ); - inits.emplace_back( sdw::makeExpr( surface->getMember< sdw::Vec3 >( "bitangent", vec3( 0.0_f ) ) ) ); + if ( checkFlag( materials.getFilter(), ComponentModeFlag::eDerivTex ) ) + { + inits.emplace_back( makeExpr( surface->getMember< shader::DerivVec3 >( "normal", shader::derivVec3( 0.0_f ) ) ) ); + inits.emplace_back( makeExpr( surface->getMember< shader::DerivVec4 >( "tangent", shader::derivVec4( 0.0_f ) ) ) ); + inits.emplace_back( makeExpr( surface->getMember< shader::DerivVec3 >( "bitangent", shader::derivVec3( 0.0_f ) ) ) ); + } + else + { + inits.emplace_back( makeExpr( surface->getMember< sdw::Vec3 >( "normal", vec3( 0.0_f ) ) ) ); + inits.emplace_back( makeExpr( surface->getMember< sdw::Vec4 >( "tangent", vec4( 0.0_f ) ) ) ); + inits.emplace_back( makeExpr( surface->getMember< sdw::Vec3 >( "bitangent", vec3( 0.0_f ) ) ) ); + } } else { - inits.emplace_back( sdw::makeExpr( vec3( 0.0_f ) ) ); - inits.emplace_back( sdw::makeExpr( vec4( 0.0_f ) ) ); - inits.emplace_back( sdw::makeExpr( vec3( 0.0_f ) ) ); + inits.emplace_back( makeExpr( vec3( 0.0_f ) ) ); + inits.emplace_back( makeExpr( vec4( 0.0_f ) ) ); + inits.emplace_back( makeExpr( vec3( 0.0_f ) ) ); } } @@ -70,9 +89,19 @@ namespace castor3d { if ( res.hasMember( "normal" ) ) { - res.getMember< sdw::Vec3 >( "normal" ) += src.getMember< sdw::Vec3 >( "normal" ) * passMultiplier; - res.getMember< sdw::Vec4 >( "tangent" ) += src.getMember< sdw::Vec4 >( "tangent" ) * passMultiplier; - res.getMember< sdw::Vec3 >( "bitangent" ) += src.getMember< sdw::Vec3 >( "bitangent" ) * passMultiplier; + if ( res.usesDerivativeValues() ) + { + using shader::operator*; + res.getMember< shader::DerivVec3 >( "normal" ) += src.getMember< shader::DerivVec3 >( "normal" ) * passMultiplier; + res.getMember< shader::DerivVec4 >( "tangent" ) += src.getMember< shader::DerivVec4 >( "tangent" ) * passMultiplier; + res.getMember< shader::DerivVec3 >( "bitangent" ) += src.getMember< shader::DerivVec3 >( "bitangent" ) * passMultiplier; + } + else + { + res.getMember< sdw::Vec3 >( "normal" ) += src.getMember< sdw::Vec3 >( "normal" ) * passMultiplier; + res.getMember< sdw::Vec4 >( "tangent" ) += src.getMember< sdw::Vec4 >( "tangent" ) * passMultiplier; + res.getMember< sdw::Vec3 >( "bitangent" ) += src.getMember< sdw::Vec3 >( "bitangent" ) * passMultiplier; + } } } diff --git a/source/Core/Castor3D/Material/Pass/Component/Base/TexturesComponent.cpp b/source/Core/Castor3D/Material/Pass/Component/Base/TexturesComponent.cpp index 03001da3fb..6b7ebd93fc 100644 --- a/source/Core/Castor3D/Material/Pass/Component/Base/TexturesComponent.cpp +++ b/source/Core/Castor3D/Material/Pass/Component/Base/TexturesComponent.cpp @@ -7,6 +7,7 @@ #include "Castor3D/Scene/SceneFileParserData.hpp" #include "Castor3D/Shader/ShaderBuffers/PassBuffer.hpp" #include "Castor3D/Shader/Shaders/GlslBlendComponents.hpp" +#include "Castor3D/Shader/Shaders/GlslDerivativeValue.hpp" #include "Castor3D/Shader/Shaders/GlslMaterial.hpp" #include @@ -206,28 +207,28 @@ namespace castor3d { if ( res.hasMember( "texture0" ) && src.hasMember( "texture0" ) ) { - res.getMember< shader::DerivTex >( "texture0", true ).uv() += src.getMember< shader::DerivTex >( "texture0", true ).uv() * passMultiplier; + res.getMember< shader::DerivTex >( "texture0", true ).value() += src.getMember< shader::DerivTex >( "texture0", true ).value() * passMultiplier; res.getMember< shader::DerivTex >( "texture0", true ).dPdx() += src.getMember< shader::DerivTex >( "texture0", true ).dPdx() * passMultiplier; res.getMember< shader::DerivTex >( "texture0", true ).dPdy() += src.getMember< shader::DerivTex >( "texture0", true ).dPdy() * passMultiplier; } if ( res.hasMember( "texture1" ) && src.hasMember( "texture1" ) ) { - res.getMember< shader::DerivTex >( "texture1", true ).uv() += src.getMember< shader::DerivTex >( "texture1", true ).uv() * passMultiplier; + res.getMember< shader::DerivTex >( "texture1", true ).value() += src.getMember< shader::DerivTex >( "texture1", true ).value() * passMultiplier; res.getMember< shader::DerivTex >( "texture1", true ).dPdx() += src.getMember< shader::DerivTex >( "texture1", true ).dPdx() * passMultiplier; res.getMember< shader::DerivTex >( "texture1", true ).dPdy() += src.getMember< shader::DerivTex >( "texture1", true ).dPdy() * passMultiplier; } if ( res.hasMember( "texture2" ) && src.hasMember( "texture2" ) ) { - res.getMember< shader::DerivTex >( "texture2", true ).uv() += src.getMember< shader::DerivTex >( "texture2", true ).uv() * passMultiplier; + res.getMember< shader::DerivTex >( "texture2", true ).value() += src.getMember< shader::DerivTex >( "texture2", true ).value() * passMultiplier; res.getMember< shader::DerivTex >( "texture2", true ).dPdx() += src.getMember< shader::DerivTex >( "texture2", true ).dPdx() * passMultiplier; res.getMember< shader::DerivTex >( "texture2", true ).dPdy() += src.getMember< shader::DerivTex >( "texture2", true ).dPdy() * passMultiplier; } if ( res.hasMember( "texture3" ) && src.hasMember( "texture3" ) ) { - res.getMember< shader::DerivTex >( "texture3", true ).uv() += src.getMember< shader::DerivTex >( "texture3", true ).uv() * passMultiplier; + res.getMember< shader::DerivTex >( "texture3", true ).value() += src.getMember< shader::DerivTex >( "texture3", true ).value() * passMultiplier; res.getMember< shader::DerivTex >( "texture3", true ).dPdx() += src.getMember< shader::DerivTex >( "texture3", true ).dPdx() * passMultiplier; res.getMember< shader::DerivTex >( "texture3", true ).dPdy() += src.getMember< shader::DerivTex >( "texture3", true ).dPdy() * passMultiplier; } diff --git a/source/Core/Castor3D/Material/Pass/Component/Base/UntileMappingComponent.cpp b/source/Core/Castor3D/Material/Pass/Component/Base/UntileMappingComponent.cpp index 621efeec2c..bf80aca240 100644 --- a/source/Core/Castor3D/Material/Pass/Component/Base/UntileMappingComponent.cpp +++ b/source/Core/Castor3D/Material/Pass/Component/Base/UntileMappingComponent.cpp @@ -4,6 +4,7 @@ #include "Castor3D/Miscellaneous/ConfigurationVisitor.hpp" #include "Castor3D/Material/Texture/TextureConfiguration.hpp" #include "Castor3D/Scene/SceneFileParserData.hpp" +#include "Castor3D/Shader/Shaders/GlslDerivativeValue.hpp" #include @@ -75,7 +76,7 @@ namespace castor3d , shader::BlendComponents const & components )const { return sampleUntiled( map - , texCoords.uv() + , texCoords.value() , texCoords.dPdx() , texCoords.dPdy() ); } diff --git a/source/Core/Castor3D/Material/Pass/Component/Lighting/ClearcoatComponent.cpp b/source/Core/Castor3D/Material/Pass/Component/Lighting/ClearcoatComponent.cpp index 288da05226..19a5fafb16 100644 --- a/source/Core/Castor3D/Material/Pass/Component/Lighting/ClearcoatComponent.cpp +++ b/source/Core/Castor3D/Material/Pass/Component/Lighting/ClearcoatComponent.cpp @@ -123,7 +123,14 @@ namespace castor3d { if ( surface ) { - inits.emplace_back( sdw::makeExpr( surface->getMember< sdw::Vec3 >( "normal" ) ) ); + if ( checkFlag( materials.getFilter(), ComponentModeFlag::eDerivTex ) ) + { + inits.emplace_back( shader::makeRawExpr( surface->getMember< shader::DerivVec3 >( "normal", shader::derivVec3( 0.0_f ) ) ) ); + } + else + { + inits.emplace_back( sdw::makeExpr( surface->getMember< sdw::Vec3 >( "normal", vec3( 0.0_f ) ) ) ); + } } else { diff --git a/source/Core/Castor3D/Material/Pass/Component/Lighting/IridescenceComponent.cpp b/source/Core/Castor3D/Material/Pass/Component/Lighting/IridescenceComponent.cpp index 2a75743ce6..9ff83c2a2d 100644 --- a/source/Core/Castor3D/Material/Pass/Component/Lighting/IridescenceComponent.cpp +++ b/source/Core/Castor3D/Material/Pass/Component/Lighting/IridescenceComponent.cpp @@ -266,7 +266,7 @@ namespace castor3d || checkFlag( filter, ComponentModeFlag::eSpecularLighting ); } - void IridescenceComponent::Plugin::finishComponent( shader::SurfaceBase const & surface + void IridescenceComponent::Plugin::finishComponent( shader::DerivSurfaceBase const & surface , sdw::Vec3 const worldEye , shader::Utils & utils , shader::BlendComponents & components ) @@ -286,13 +286,10 @@ namespace castor3d IF( writer, components.iridescenceFactor != 0.0_f ) { - auto incident = writer.declLocale( "incident" - , normalize( surface.worldPosition.xyz() - worldEye ) ); - sdw::Vec3 normal = components.hasMember( "normal" ) - ? components.normal - : surface.normal; + auto incident = writer.declLocale( "c3d_iridescenceIncident" + , normalize( surface.worldPosition.value().xyz() - worldEye ) ); auto NdotV = writer.declLocale( "NdotV" - , dot( normal, -incident ) ); + , dot( components.getRawNormal(), -incident ) ); components.iridescenceFresnel = utils.evalIridescence( 1.0_f , components.iridescenceIor , NdotV diff --git a/source/Core/Castor3D/Material/Pass/Component/Map/HeightMapComponent.cpp b/source/Core/Castor3D/Material/Pass/Component/Map/HeightMapComponent.cpp index 811edb1f02..cc80d0d72d 100644 --- a/source/Core/Castor3D/Material/Pass/Component/Map/HeightMapComponent.cpp +++ b/source/Core/Castor3D/Material/Pass/Component/Map/HeightMapComponent.cpp @@ -11,6 +11,7 @@ #include "Castor3D/Scene/SceneImporter.hpp" #include "Castor3D/Shader/ShaderBuffers/PassBuffer.hpp" #include "Castor3D/Shader/Shaders/GlslBlendComponents.hpp" +#include "Castor3D/Shader/Shaders/GlslDerivativeValue.hpp" #include "Castor3D/Shader/Shaders/GlslLighting.hpp" #include "Castor3D/Shader/Shaders/GlslMaterial.hpp" #include "Castor3D/Shader/Shaders/GlslSurface.hpp" @@ -365,7 +366,7 @@ namespace castor3d , shader::TextureConfigData const & textureConfig , sdw::UInt const & mask )const { - parallaxMapping( texCoords.uv() + parallaxMapping( texCoords.value() , texCoords.dPdx() , texCoords.dPdy() , viewDir diff --git a/source/Core/Castor3D/Material/Pass/Component/Map/NormalMapComponent.cpp b/source/Core/Castor3D/Material/Pass/Component/Map/NormalMapComponent.cpp index aefddd7500..40718e701c 100644 --- a/source/Core/Castor3D/Material/Pass/Component/Map/NormalMapComponent.cpp +++ b/source/Core/Castor3D/Material/Pass/Component/Map/NormalMapComponent.cpp @@ -218,16 +218,47 @@ namespace castor3d , sdw::Vec4 const & sampled ) { auto & writer{ *sampled.getWriter() }; - auto tbn = shader::Utils::getTBN( components.getMember< sdw::Vec3 >( "normal" ) - , components.getMember< sdw::Vec4 >( "tangent" ).xyz() - , components.getMember< sdw::Vec3 >( "bitangent" ) ); - sampled[mask + 1u] = nmlGMul * sampled[mask + 1u]; - components.getMember< sdw::Vec3 >( "normal" ) = normalize( tbn - * fma( vec3( 2.0_f ) + + if ( components.usesDerivativeValues() ) + { + auto normal = components.getMember< shader::DerivVec3 >( "normal" ); + auto tangent = components.getMember< shader::DerivVec4 >( "tangent" ); + auto bitangent = components.getMember< shader::DerivVec3 >( "bitangent" ); + auto tbn00 = shader::Utils::getTBN( normal.value(), tangent.value().xyz(), bitangent.value() ); + auto tbn10 = shader::Utils::getTBN( normal.value() + normal.dPdx(), tangent.value().xyz() + tangent.dPdx().xyz(), bitangent.value() + bitangent.dPdx() ); + auto tbn01 = shader::Utils::getTBN( normal.value() + normal.dPdy(), tangent.value().xyz() + tangent.dPdy().xyz(), bitangent.value() + bitangent.dPdy() ); + + sampled[mask + 1u] = nmlGMul * sampled[mask + 1u]; + auto reconstructedNormal = writer.declLocale( "c3d_reconstructedNormalMikkt" , writer.ternary( nml2Chan != 0_u , shader::Utils::reconstructNormal( sampled[mask], sampled[mask + 1u] ) - , shader::TextureConfigData::getVec3( sampled, mask ) ) - , -vec3( 1.0_f ) ) ); + , shader::TextureConfigData::getVec3( sampled, mask ) ) ); + reconstructedNormal = fma( vec3( 2.0_f ), reconstructedNormal, -vec3( 1.0_f ) ); + + auto res00 = writer.declLocale( "c3d_mikktDerivRes00" + , normalize( tbn00 * reconstructedNormal ) ); + auto res10 = writer.declLocale( "c3d_mikktDerivRes10" + , normalize( tbn10 * reconstructedNormal ) ); + auto res01 = writer.declLocale( "c3d_mikktDerivRes01" + , normalize( tbn01 * reconstructedNormal ) ); + normal.value() = res00; + normal.dPdx() = res10 - res00; + normal.dPdy() = res01 - res00; + } + else + { + auto normal = components.getMember< sdw::Vec3 >( "normal" ); + auto tangent = components.getMember< sdw::Vec4 >( "tangent" ); + auto bitangent = components.getMember< sdw::Vec3 >( "bitangent" ); + auto tbn = shader::Utils::getTBN( normal, tangent.xyz(), bitangent ); + sampled[mask + 1u] = nmlGMul * sampled[mask + 1u]; + normal = normalize( tbn + * fma( vec3( 2.0_f ) + , writer.ternary( nml2Chan != 0_u + , shader::Utils::reconstructNormal( sampled[mask], sampled[mask + 1u] ) + , shader::TextureConfigData::getVec3( sampled, mask ) ) + , -vec3( 1.0_f ) ) ); + } } //********************************************************************************************* diff --git a/source/Core/Castor3D/Material/Pass/Component/Other/DefaultReflRefrComponent.cpp b/source/Core/Castor3D/Material/Pass/Component/Other/DefaultReflRefrComponent.cpp index b2c100eaaf..1433a39598 100644 --- a/source/Core/Castor3D/Material/Pass/Component/Other/DefaultReflRefrComponent.cpp +++ b/source/Core/Castor3D/Material/Pass/Component/Other/DefaultReflRefrComponent.cpp @@ -49,7 +49,7 @@ namespace castor3d auto debugOutputBlock = debugOutput.pushBlock( cuT( "Reflections" ) ); reflections.computeCombined( components , lightSurface - , lightSurface.worldPosition().xyz() + , lightSurface.worldPosition().value().xyz() , backgroundModel , mippedScene , camera diff --git a/source/Core/Castor3D/Material/Pass/Component/Other/HeightComponent.cpp b/source/Core/Castor3D/Material/Pass/Component/Other/HeightComponent.cpp index 7fdefe49ac..84b8c42b9a 100644 --- a/source/Core/Castor3D/Material/Pass/Component/Other/HeightComponent.cpp +++ b/source/Core/Castor3D/Material/Pass/Component/Other/HeightComponent.cpp @@ -96,7 +96,15 @@ namespace castor3d if ( surface ) { inits.emplace_back( sdw::makeExpr( surface->getMember( "tangentSpaceViewPosition", vec3( 0.0_f ) ) ) ); - inits.emplace_back( sdw::makeExpr( surface->getMember( "tangentSpaceFragPosition", vec3( 0.0_f ) ) ) ); + + if ( checkFlag( materials.getFilter(), ComponentModeFlag::eDerivTex ) ) + { + inits.emplace_back( shader::makeRawExpr( surface->getMember< shader::DerivVec3 >( "tangentSpaceFragPosition", shader::derivVec3( 0.0_f ) ) ) ); + } + else + { + inits.emplace_back( sdw::makeExpr( surface->getMember< sdw::Vec3 >( "tangentSpaceFragPosition", vec3( 0.0_f ) ) ) ); + } } else { diff --git a/source/Core/Castor3D/Material/Pass/Component/PassComponent.cpp b/source/Core/Castor3D/Material/Pass/Component/PassComponent.cpp index d451845545..b97cf1b343 100644 --- a/source/Core/Castor3D/Material/Pass/Component/PassComponent.cpp +++ b/source/Core/Castor3D/Material/Pass/Component/PassComponent.cpp @@ -7,6 +7,7 @@ #include "Castor3D/Material/Texture/TextureConfiguration.hpp" #include "Castor3D/Material/Texture/Animation/TextureAnimation.hpp" #include "Castor3D/Shader/Shaders/GlslBlendComponents.hpp" +#include "Castor3D/Shader/Shaders/GlslDerivativeValue.hpp" #include "Castor3D/Shader/Shaders/GlslTextureConfiguration.hpp" #include @@ -37,7 +38,7 @@ namespace castor3d , shader::DerivTex const & texCoords , shader::BlendComponents const & components )const { - return map.grad( texCoords.uv() + return map.grad( texCoords.value() , texCoords.dPdx() , texCoords.dPdy() ); } diff --git a/source/Core/Castor3D/Material/Pass/Pass.cpp b/source/Core/Castor3D/Material/Pass/Pass.cpp index f5b32463c3..3fdd4df07e 100644 --- a/source/Core/Castor3D/Material/Pass/Pass.cpp +++ b/source/Core/Castor3D/Material/Pass/Pass.cpp @@ -166,10 +166,15 @@ namespace castor3d //********************************************************************************************* Pass::Pass( Material & parent - , LightingModelID lightingModelId ) + , LightingModelID lightingModelId + , RenderPassRegisterInfo * renderPassInfo + , bool implicit + , bool automaticShader ) : OwnedBy< Material >{ parent } , m_index{ parent.getPassCount() } - , m_renderPassInfo{ getOwner()->getRenderPassInfo() } + , m_implicit{ implicit } + , m_automaticShader{ automaticShader } + , m_renderPassInfo{ renderPassInfo } { createComponent< BlendComponent >(); createComponent< PassHeaderComponent >(); @@ -182,13 +187,15 @@ namespace castor3d } Pass::Pass( Material & parent - , Pass const & rhs ) - : Pass{ parent, rhs.getLightingModelId() } + , LightingModelID lightingModelId ) + : Pass{ parent, lightingModelId, parent.getRenderPassInfo() } { - m_implicit = rhs.m_implicit; - m_automaticShader = rhs.m_automaticShader; - m_renderPassInfo = rhs.m_renderPassInfo; + } + Pass::Pass( Material & parent + , Pass const & rhs ) + : Pass{ parent, rhs.getLightingModelId(), rhs.m_renderPassInfo, rhs.m_implicit, rhs.m_automaticShader } + { for ( auto & [id, component] : rhs.m_components ) { addComponent( component->clone( *this ) ); @@ -304,7 +311,7 @@ namespace castor3d if ( m_dirty.exchange( false ) ) { - auto oldComponents = m_componentCombine; + auto const & oldComponents = m_componentCombine; m_componentCombine = getOwner()->getOwner()->getPassComponentsRegister().registerPassComponentCombine( *this ); onChanged( *this, oldComponents.baseId, m_componentCombine.baseId ); } @@ -424,7 +431,7 @@ namespace castor3d } ); it != m_components.end() ) { - auto tmp = castor::move( it->second ); + PassComponentUPtr tmp = castor::move( it->second ); m_components.erase( it ); if ( tmp->getPlugin().getComponentFlags() == m_reflRefrFlag ) @@ -506,6 +513,8 @@ namespace castor3d void Pass::registerTexture( TextureSourceInfo sourceInfo , PassTextureConfig configuration ) { + auto texcoordSet = configuration.texcoordSet; + if ( auto it = std::find_if( m_sources.begin() , m_sources.end() , [&sourceInfo, &configuration]( PassTextureSource const & lookup ) @@ -521,7 +530,7 @@ namespace castor3d } else { - auto resConfig = it->first.textureConfig(); + TextureConfiguration resConfig = it->first.textureConfig(); for ( auto const & flagConfig : sourceInfo.textureConfig().components ) { @@ -534,7 +543,7 @@ namespace castor3d it->first = TextureSourceInfo{ it->first, resConfig }; } - m_maxTexcoordSet = std::max( m_maxTexcoordSet, configuration.texcoordSet ); + m_maxTexcoordSet = std::max( m_maxTexcoordSet, texcoordSet ); doUpdateTextureFlags(); } @@ -894,7 +903,7 @@ namespace castor3d return result; } - void Pass::enableLighting( bool value ) + void Pass::enableLighting( bool value )const { if ( auto component = getComponent< PassHeaderComponent >() ) { @@ -902,7 +911,7 @@ namespace castor3d } } - void Pass::enablePicking( bool value ) + void Pass::enablePicking( bool value )const { if ( auto component = getComponent< PickableComponent >() ) { diff --git a/source/Core/Castor3D/Material/Pass/Shaders/GlslPbrLighting.cpp b/source/Core/Castor3D/Material/Pass/Shaders/GlslPbrLighting.cpp index fe2063e91b..19c4756a8e 100644 --- a/source/Core/Castor3D/Material/Pass/Shaders/GlslPbrLighting.cpp +++ b/source/Core/Castor3D/Material/Pass/Shaders/GlslPbrLighting.cpp @@ -68,7 +68,6 @@ namespace castor3d::shader } void PbrLightingModel::doFinish( PassShaders const & passShaders - , RasterizerSurfaceBase const & surface , BlendComponents & components ) { auto ior = m_writer.declLocale( "ior" @@ -97,8 +96,8 @@ namespace castor3d::shader auto rawDiffuse = m_writer.declLocale( "rawDiffuse" , m_cookTorrance.computeDiffuse( radiance , intensity - , lightSurface.difF() ) ); - output = doGetNdotL( lightSurface, components ) * rawDiffuse; + , lightSurface.difF().value() ) ); + output = doGetNdotL( lightSurface, components ).value() * rawDiffuse; return rawDiffuse; } @@ -111,12 +110,12 @@ namespace castor3d::shader { output = m_cookTorrance.computeSpecular( radiance , intensity - , doGetNdotL( lightSurface, components ) - , doGetNdotH( lightSurface, components ) - , lightSurface.NdotV() - , lightSurface.spcF() + , doGetNdotL( lightSurface, components ).value() + , doGetNdotH( lightSurface, components ).value() + , lightSurface.NdotV().value() + , lightSurface.spcF().value() , components.roughness * components.roughness ); - output *= doGetNdotL( lightSurface, components ); + output *= doGetNdotL( lightSurface, components ).value(); } void PbrLightingModel::doComputeCoatingTerm( sdw::Vec3 const & radiance @@ -128,15 +127,15 @@ namespace castor3d::shader { IF( m_writer, components.clearcoatFactor != 0.0_f ) { - lightSurface.updateN( components.clearcoatNormal ); + lightSurface.updateN( derivVec3( components.clearcoatNormal ) ); output = m_cookTorrance.computeSpecular( radiance , intensity - , doGetNdotL( lightSurface, components ) - , doGetNdotH( lightSurface, components ) - , lightSurface.NdotV() - , lightSurface.F() + , doGetNdotL( lightSurface, components ).value() + , doGetNdotH( lightSurface, components ).value() + , lightSurface.NdotV().value() + , lightSurface.F().value() , components.clearcoatRoughness ); - output *= doGetNdotL( lightSurface, components ); + output *= doGetNdotL( lightSurface, components ).value(); } FI; } @@ -151,8 +150,8 @@ namespace castor3d::shader IF( m_writer, !all( components.sheenFactor == vec3( 0.0_f ) ) ) { output = m_sheen.compute( lightSurface - , doGetNdotL( lightSurface, components ) - , doGetNdotH( lightSurface, components ) + , doGetNdotL( lightSurface, components ).value() + , doGetNdotH( lightSurface, components ).value() , components.sheenRoughness ); } FI; diff --git a/source/Core/Castor3D/Material/Pass/Shaders/GlslPhongLighting.cpp b/source/Core/Castor3D/Material/Pass/Shaders/GlslPhongLighting.cpp index 3c4145d696..486b0ace43 100644 --- a/source/Core/Castor3D/Material/Pass/Shaders/GlslPhongLighting.cpp +++ b/source/Core/Castor3D/Material/Pass/Shaders/GlslPhongLighting.cpp @@ -71,7 +71,6 @@ namespace castor3d::shader } void PhongLightingModel::doFinish( PassShaders const & passShaders - , RasterizerSurfaceBase const & surface , BlendComponents & components ) { components.f0 = components.specular; @@ -84,12 +83,12 @@ namespace castor3d::shader , sdw::Float & isLit , sdw::Vec3 output ) { - isLit = 1.0_f - step( doGetNdotL( lightSurface, components ), 0.0_f ); + isLit = 1.0_f - step( doGetNdotL( lightSurface, components ).value(), 0.0_f ); auto rawDiffuse = m_writer.declLocale( "rawDiffuse" , radiance * intensity ); output = isLit * rawDiffuse - * doGetNdotL( lightSurface, components ); + * doGetNdotL( lightSurface, components ).value(); return rawDiffuse; } @@ -103,7 +102,7 @@ namespace castor3d::shader output = isLit * radiance * intensity - * pow( doGetNdotH( lightSurface, components ) + * pow( doGetNdotH( lightSurface, components ).value() , clamp( components.shininess, 1.0_f, 256.0_f ) ); } @@ -116,11 +115,11 @@ namespace castor3d::shader { IF( m_writer, components.clearcoatFactor != 0.0_f ) { - lightSurface.updateN( components.clearcoatNormal ); + lightSurface.updateN( derivVec3( components.clearcoatNormal ) ); output = isLit * radiance * intensity - * pow( doGetNdotH( lightSurface, components ) + * pow( doGetNdotH( lightSurface, components ).value() , clamp( components.shininess, 1.0_f, 256.0_f ) ); } FI; diff --git a/source/Core/Castor3D/Material/Texture/Sampler.cpp b/source/Core/Castor3D/Material/Texture/Sampler.cpp index 5456233ff9..24911d0e90 100644 --- a/source/Core/Castor3D/Material/Texture/Sampler.cpp +++ b/source/Core/Castor3D/Material/Texture/Sampler.cpp @@ -90,6 +90,32 @@ namespace castor3d return cuT( "Unsupported VkSamplerAddressMode" ); } } + + static castor::String getName( VkBorderColor value ) + { + switch ( value ) + { + case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK: + return cuT( "Ftb" ); + case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK: + return cuT( "Itb" ); + case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK: + return cuT( "Fob" ); + case VK_BORDER_COLOR_INT_OPAQUE_BLACK: + return cuT( "Iob" ); + case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE: + return cuT( "Fow" ); + case VK_BORDER_COLOR_INT_OPAQUE_WHITE: + return cuT( "Iow" ); + case VK_BORDER_COLOR_FLOAT_CUSTOM_EXT: + return cuT( "Fc" ); + case VK_BORDER_COLOR_INT_CUSTOM_EXT: + return cuT( "Ic" ); + default: + assert( false && "Unsupported VkBorderColor." ); + return cuT( "Unsupported VkBorderColor" ); + } + } } SamplerObs createSampler( Engine & engine @@ -149,7 +175,8 @@ namespace castor3d , VkSamplerMipmapMode mipFilter , VkSamplerAddressMode U , VkSamplerAddressMode V - , VkSamplerAddressMode W ) + , VkSamplerAddressMode W + , VkBorderColor borderColor ) { return sampler::getName( compareOp ) + sampler::getName( minFilter ) @@ -157,7 +184,8 @@ namespace castor3d + sampler::getName( mipFilter ) + cuT( "U" ) + sampler::getName( U ) + cuT( "V" ) + sampler::getName( V ) - + cuT( "W" ) + sampler::getName( W ); + + cuT( "W" ) + sampler::getName( W ) + + sampler::getName( borderColor ); } //********************************************************************************************* diff --git a/source/Core/Castor3D/Model/Mesh/Submesh/Component/DefaultRenderComponent.cpp b/source/Core/Castor3D/Model/Mesh/Submesh/Component/DefaultRenderComponent.cpp index 84de6f9afc..38271d8597 100644 --- a/source/Core/Castor3D/Model/Mesh/Submesh/Component/DefaultRenderComponent.cpp +++ b/source/Core/Castor3D/Model/Mesh/Submesh/Component/DefaultRenderComponent.cpp @@ -84,17 +84,18 @@ namespace castor3d sdw::PushConstantBuffer pcb{ writer, "C3D_DrawData", "c3d_drawData" }; auto pipelineID = pcb.declMember< sdw::UInt >( "pipelineID" ); + auto drawID = pcb.declMember< sdw::Int >( "drawID", !engine.getRenderDevice()->hasDrawId() ); pcb.end(); writer.implementMainT< shader::BillboardSurfaceT, shader::FragmentSurfaceT >( sdw::VertexInT< shader::BillboardSurfaceT >{ writer, flags } , sdw::VertexOutT< shader::FragmentSurfaceT >{ writer, submeshShaders, passShaders, flags } - , [&writer, &pipelineID, &c3d_billboardData, &c3d_cameraData, &c3d_modelsData, &c3d_objectIdsData, flags]( sdw::VertexInT< shader::BillboardSurfaceT > const & in + , [&engine, &writer, &drawID, &pipelineID, &c3d_billboardData, &c3d_cameraData, &c3d_modelsData, &c3d_objectIdsData, flags]( sdw::VertexInT< shader::BillboardSurfaceT > const & in , sdw::VertexOutT< shader::FragmentSurfaceT > out ) { auto nodeId = writer.declLocale( "nodeId" , shader::getNodeId( c3d_objectIdsData , pipelineID - , writer.cast< sdw::UInt >( in.drawID ) ) ); + , writer.cast< sdw::UInt >( engine.getRenderDevice()->hasDrawId() ? in.drawID : drawID ) ) ); auto modelData = writer.declLocale( "modelData" , c3d_modelsData[nodeId - 1u] ); auto passMultipliers = castor::Vector< sdw::Vec4 >{ vec4( 1.0_f, 0.0_f, 0.0_f, 0.0_f ) @@ -185,18 +186,19 @@ namespace castor3d sdw::PushConstantBuffer pcb{ writer, "C3D_DrawData", "c3d_drawData" }; auto pipelineID = pcb.declMember< sdw::UInt >( "pipelineID" ); + auto drawID = pcb.declMember< sdw::Int >( "drawID", !engine.getRenderDevice()->hasDrawId() ); pcb.end(); writer.implementMainT< shader::MeshVertexT, shader::FragmentSurfaceT >( sdw::VertexInT< shader::MeshVertexT >{ writer, submeshShaders } , sdw::VertexOutT< shader::FragmentSurfaceT >{ writer, submeshShaders, passShaders, flags } - , [&writer, &materials, &c3d_cameraData, &c3d_modelsData, &c3d_objectIdsData, &pipelineID, &flags]( sdw::VertexInT< shader::MeshVertexT > const & in + , [&engine, &writer, &materials, &c3d_cameraData, &c3d_modelsData, &c3d_objectIdsData, &drawID, &pipelineID, &flags]( sdw::VertexInT< shader::MeshVertexT > const & in , sdw::VertexOutT< shader::FragmentSurfaceT > out ) { auto nodeId = writer.declLocale( "nodeId" , shader::getNodeId( c3d_objectIdsData , in , pipelineID - , writer.cast< sdw::UInt >( in.drawID ) + , writer.cast< sdw::UInt >( engine.getRenderDevice()->hasDrawId() ? in.drawID : drawID ) , flags ) ); auto curPosition = writer.declLocale( "curPosition" , in.position ); @@ -298,6 +300,7 @@ namespace castor3d sdw::PushConstantBuffer pcb{ writer, "C3D_DrawData", "c3d_drawData" }; auto pipelineID = pcb.declMember< sdw::UInt >( "pipelineID" ); + auto drawID = pcb.declMember< sdw::UInt >( "drawID", !engine.getRenderDevice()->hasDrawId() ); auto drawOffset = pcb.declMember< sdw::UInt >( "drawOffset" ); auto meshletOffset = pcb.declMember< sdw::UInt >( "meshletOffset" ); pcb.end(); @@ -320,7 +323,7 @@ namespace castor3d auto laneId = writer.declLocale( "laneId" , in.localInvocationID.x() ); auto drawId = writer.declLocale( "drawId" - , in.drawID + drawOffset ); + , ( engine.getRenderDevice()->hasDrawId() ? in.drawID : drawID ) + drawOffset ); auto nodeId = writer.declLocale( "nodeId" , shader::getNodeId( c3d_objectIdsData , meshlets.instances @@ -530,7 +533,7 @@ namespace castor3d writer.implementEntryPointT< shader::PayloadT >( 32u, 1u, 1u , sdw::TaskPayloadOutEXTT< shader::PayloadT >{ writer } - , [&writer, &drawOffset, &meshlets, &pipelineID, &c3d_objectIdsData, &checkVisible, &flags]( sdw::TaskSubgroupInEXT const & in + , [&engine, &writer, &drawOffset, &meshlets, &drawID, &pipelineID, &c3d_objectIdsData, &checkVisible, &flags]( sdw::TaskSubgroupInEXT const & in , sdw::TaskPayloadOutEXTT< shader::PayloadT > const & payload ) { auto laneId = in.localInvocationID.x(); @@ -538,7 +541,7 @@ namespace castor3d auto meshletId = writer.declLocale( "meshletId" , ( baseId * 32u + laneId ) ); auto drawId = writer.declLocale( "drawId" - , in.drawID + drawOffset ); + , ( engine.getRenderDevice()->hasDrawId() ? in.drawID : drawID ) + drawOffset ); auto nodeId = writer.declLocale( "nodeId" , shader::getNodeId( c3d_objectIdsData , meshlets.instances @@ -629,6 +632,7 @@ namespace castor3d sdw::PushConstantBuffer pcb{ writer, "C3D_DrawData", "c3d_drawData" }; auto pipelineID = pcb.declMember< sdw::UInt >( "pipelineID" ); + auto drawID = pcb.declMember< sdw::UInt >( "drawID", !engine.getRenderDevice()->hasDrawId() ); auto drawOffset = pcb.declMember< sdw::UInt >( "drawOffset" ); auto meshletOffset = pcb.declMember< sdw::UInt >( "meshletOffset" ); pcb.end(); @@ -651,7 +655,7 @@ namespace castor3d auto laneId = writer.declLocale( "laneId" , in.localInvocationID ); auto drawId = writer.declLocale( "drawId" - , in.drawID + drawOffset ); + , ( engine.getRenderDevice()->hasDrawId() ? in.drawID : drawID ) + drawOffset ); auto nodeId = writer.declLocale( "nodeId" , shader::getNodeId( c3d_objectIdsData , meshlets.instances @@ -861,7 +865,7 @@ namespace castor3d writer.implementEntryPointT< shader::PayloadT >( 32u , sdw::TaskPayloadOutNVT< shader::PayloadT >{ writer } - , [&writer, &meshlets, &drawOffset, &c3d_objectIdsData, &pipelineID, &flags, &checkVisible]( sdw::TaskSubgroupInNV const & in + , [&engine, &writer, &meshlets, &drawOffset, &c3d_objectIdsData, &drawID, &pipelineID, &flags, &checkVisible]( sdw::TaskSubgroupInNV const & in , sdw::TaskPayloadOutNVT< shader::PayloadT > const & payload ) { auto const & laneId = in.localInvocationID; @@ -869,7 +873,7 @@ namespace castor3d auto meshletId = writer.declLocale( "meshletId" , ( baseId * 32u + laneId ) ); auto drawId = writer.declLocale( "drawId" - , in.drawID + drawOffset ); + , ( engine.getRenderDevice()->hasDrawId() ? in.drawID : drawID ) + drawOffset ); auto nodeId = writer.declLocale( "nodeId" , shader::getNodeId( c3d_objectIdsData , meshlets.instances diff --git a/source/Core/Castor3D/Render/Clustered/ReduceLightsAABB.cpp b/source/Core/Castor3D/Render/Clustered/ReduceLightsAABB.cpp index 7afee99699..80d2eeea17 100644 --- a/source/Core/Castor3D/Render/Clustered/ReduceLightsAABB.cpp +++ b/source/Core/Castor3D/Render/Clustered/ReduceLightsAABB.cpp @@ -27,8 +27,6 @@ #include -#define C3D_DebugEnableWarpOptimisation 0 - namespace castor3d { //********************************************************************************************* diff --git a/source/Core/Castor3D/Render/GlobalIllumination/VoxelConeTracing/VoxelizePass.cpp b/source/Core/Castor3D/Render/GlobalIllumination/VoxelConeTracing/VoxelizePass.cpp index f94d730c05..b98406b5b6 100644 --- a/source/Core/Castor3D/Render/GlobalIllumination/VoxelConeTracing/VoxelizePass.cpp +++ b/source/Core/Castor3D/Render/GlobalIllumination/VoxelConeTracing/VoxelizePass.cpp @@ -277,6 +277,7 @@ namespace castor3d sdw::PushConstantBuffer pcb{ writer, "C3D_DrawData", "c3d_drawData" }; auto pipelineID = pcb.declMember< sdw::UInt >( "pipelineID" ); + auto drawID = pcb.declMember< sdw::Int >( "drawID", !getEngine()->getRenderDevice()->hasDrawId() ); pcb.end(); if ( flags.isBillboard() ) @@ -293,7 +294,7 @@ namespace castor3d auto nodeId = writer.declLocale( "nodeId" , shader::getNodeId( c3d_objectIdsData , pipelineID - , writer.cast< sdw::UInt >( in.drawID ) ) ); + , writer.cast< sdw::UInt >( getEngine()->getRenderDevice()->hasDrawId() ? in.drawID : drawID ) ) ); auto modelData = writer.declLocale( "modelData" , c3d_modelsData[nodeId - 1u] ); out.nodeId = writer.cast< sdw::Int >( nodeId ); @@ -347,7 +348,7 @@ namespace castor3d , shader::getNodeId( c3d_objectIdsData , in , pipelineID - , writer.cast< sdw::UInt >( in.drawID ) + , writer.cast< sdw::UInt >( getEngine()->getRenderDevice()->hasDrawId() ? in.drawID : drawID ) , flags ) ); auto curPosition = writer.declLocale( "curPosition" , in.position ); @@ -574,10 +575,10 @@ namespace castor3d , utils , "lightSurface" , c3d_cameraData.position() - , in.worldPosition - , in.worldPosition.xyz() + , { in.worldPosition, dFdx( in.worldPosition ), dFdy( in.worldPosition ) } + , { in.worldPosition.xyz(), dFdx( in.worldPosition.xyz() ), dFdy( in.worldPosition.xyz() ) } , in.fragCoord.xyz() - , normalize( components.normal ) + , normalize( components.getDerivNormal() ) , components.f0 , components , true, true, false ); @@ -596,7 +597,7 @@ namespace castor3d auto encodedColor = writer.declLocale( "encodedColor" , utils.encodeColor( vec4( color.xyz(), components.opacity ) ) ); auto encodedNormal = writer.declLocale( "encodedNormal" - , utils.encodeNormal( components.normal ) ); + , utils.encodeNormal( components.getRawNormal() ) ); auto writecoord = writer.declLocale( "writecoord" , uvec3( floor( uvw * c3d_voxelData.clipToGrid ) ) ); auto id = writer.declLocale( "id" diff --git a/source/Core/Castor3D/Render/Node/QueueRenderNodes.cpp b/source/Core/Castor3D/Render/Node/QueueRenderNodes.cpp index fafc4e8318..a990e9828c 100644 --- a/source/Core/Castor3D/Render/Node/QueueRenderNodes.cpp +++ b/source/Core/Castor3D/Render/Node/QueueRenderNodes.cpp @@ -130,7 +130,8 @@ namespace castor3d , RenderPipeline const & pipeline , ashes::BufferBase const & buffer , ashes::Optional< VkViewport > const & viewport - , ashes::Optional< VkRect2D > const & scissor ) + , ashes::Optional< VkRect2D > const & scissor + , bool hasDrawId ) { commandBuffer.bindPipeline( pipeline.getPipeline() ); @@ -159,9 +160,10 @@ namespace castor3d pipelineId = queueNodes.getPipelineNodesIndex( pipeline.getFlagsHash() , buffer ); - if ( !pipeline.hasMeshletDescriptorSetLayout() ) + if ( hasDrawId + && !pipeline.hasMeshletDescriptorSetLayout() ) { - DrawConstants constants{ pipelineId }; + DrawConstants constants{ pipelineId, 0u }; commandBuffer.pushConstants( pipeline.getPipelineLayout() , VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT , 0u @@ -210,6 +212,83 @@ namespace castor3d } } + static void registerNodeCommands( RenderPipeline const & pipeline + , RenderedNodeT< SubmeshRenderNode > const & node + , ashes::CommandBuffer const & commandBuffer + , uint32_t instanceCount + , uint32_t pipelineId + , uint32_t drawId + , uint32_t *& pipelinesBuffer + , uint32_t & idxIndex + , uint32_t & nidxIndex ) + { + if ( pipelinesBuffer ) + { + ( *pipelinesBuffer ) = node.node->getId(); + ++pipelinesBuffer; + } + + auto & geometryBuffers = node.node->getGeometryBuffers( pipeline.getFlags() ); + commandBuffer.bindVertexBuffers( geometryBuffers.layouts[0].get().vertexBindingDescriptions[0].binding + , geometryBuffers.buffers + , geometryBuffers.offsets ); + DrawConstants constants{ pipelineId, int32_t( drawId ) }; + commandBuffer.pushConstants( pipeline.getPipelineLayout() + , VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT + , 0u + , sizeof( DrawConstants ) + , &constants ); + + if ( geometryBuffers.indexOffset.hasData() ) + { + commandBuffer.bindIndexBuffer( geometryBuffers.indexOffset.getBuffer() + , 0u + , VK_INDEX_TYPE_UINT32 ); + commandBuffer.drawIndexed( node.command.indexCount + , instanceCount + , geometryBuffers.indexOffset.getFirst< uint32_t >() + , node.node->getFinalBufferOffsets().getBufferChunk( SubmeshData::ePositions ).getFirst< castor::Point4f >() + , 0u ); + ++idxIndex; + } + else + { + commandBuffer.draw( node.command.indexCount + , instanceCount + , node.node->getFinalBufferOffsets().getBufferChunk( SubmeshData::ePositions ).getFirst< castor::Point4f >() + , 0u ); + ++nidxIndex; + } + } + + static void registerNodeCommands( RenderPipeline const & pipeline + , RenderedNodeT< BillboardRenderNode > const & node + , ashes::CommandBuffer const & commandBuffer + , uint32_t instanceCount + , uint32_t pipelineId + , uint32_t drawId + , uint32_t *& pipelinesBuffer + , uint32_t & index ) + { + ( *pipelinesBuffer ) = node.node->getId(); + ++pipelinesBuffer; + auto & geometryBuffers = node.node->getGeometryBuffers( pipeline.getFlags() ); + commandBuffer.bindVertexBuffers( geometryBuffers.layouts[0].get().vertexBindingDescriptions[0].binding + , geometryBuffers.buffers + , geometryBuffers.offsets ); + DrawConstants constants{ pipelineId, int32_t( drawId ) }; + commandBuffer.pushConstants( pipeline.getPipelineLayout() + , VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT + , 0u + , sizeof( DrawConstants ) + , &constants ); + commandBuffer.draw( node.command.vertexCount + , instanceCount + , 0u + , 0u ); + ++index; + } + #if VK_NV_mesh_shader static void registerNodeCommands( RenderPipeline const & pipeline @@ -224,6 +303,7 @@ namespace castor3d commandBuffer.bindDescriptorSet( node.getMeshletDescriptorSet() , pipeline.getPipelineLayout() ); MeshletDrawConstants constants{ pipelineId + , 0u , drawOffset , node.getSourceBufferOffsets().getFirst< Meshlet >( SubmeshData::eMeshlets ) }; commandBuffer.pushConstants( pipeline.getPipelineLayout() @@ -253,6 +333,7 @@ namespace castor3d commandBuffer.bindDescriptorSet( node.getMeshletDescriptorSet() , pipeline.getPipelineLayout() ); MeshletDrawConstants constants{ pipelineId + , 0u , drawOffset , node.getSourceBufferOffsets().getFirst< Meshlet >( SubmeshData::eMeshlets ) }; commandBuffer.pushConstants( pipeline.getPipelineLayout() @@ -1051,14 +1132,26 @@ namespace castor3d } else #endif + if ( renderPass.getEngine()->getRenderDevice()->hasDrawId() ) { result += doPrepareMeshTraditionalCommandBuffers( commandBuffer, viewport, scissors, nodesIdsBuffer, maxNodesCount ); } + else + { + result += doPrepareMeshTraditionalNoDrawIDCommandBuffers( commandBuffer, viewport, scissors, nodesIdsBuffer, maxNodesCount ); + } } if ( !m_billboardNodes.empty() ) { - result += doPrepareBillboardCommandBuffers( commandBuffer, viewport, scissors, nodesIdsBuffer, maxNodesCount ); + if ( renderPass.getEngine()->getRenderDevice()->hasDrawId() ) + { + result += doPrepareBillboardCommandBuffers( commandBuffer, viewport, scissors, nodesIdsBuffer, maxNodesCount ); + } + else + { + result += doPrepareBillboardNoDrawIDCommandBuffers( commandBuffer, viewport, scissors, nodesIdsBuffer, maxNodesCount ); + } } m_pipelinesNodes->flush( 0u, ashes::WholeSize ); @@ -1342,6 +1435,108 @@ namespace castor3d } } + uint32_t QueueRenderNodes::doPrepareMeshTraditionalNoDrawIDCommandBuffers( ashes::CommandBuffer const & commandBuffer + , ashes::Optional< VkViewport > const & viewport + , ashes::Optional< VkRect2D > const & scissors + , PipelineNodes * nodesIdsBuffer + , VkDeviceSize maxNodesCount ) + { + uint32_t result{}; + uint32_t idxIndex{}; + uint32_t nidxIndex{}; + { + C3D_DebugTime( getOwner()->getOwner()->getTypeName() + " - Single" ); + for ( auto const & [_, pipelinesNodes] : m_submeshNodes ) + { + auto const & pipeline = pipelinesNodes.pipeline; + + for ( auto const & [buffer, nodes] : pipelinesNodes.nodes ) + { + if ( queuerndnd::hasVisibleNode( nodes ) ) + { + auto & pipelineNodes = getPipelineNodes( pipeline.pipeline->getFlagsHash() + , *buffer + , m_nodesIds + , nodesIdsBuffer + , maxNodesCount ); + auto pipelinesBuffer = pipelineNodes.data(); + auto pipelineId = queuerndnd::bindPipeline( commandBuffer + , *this + , *pipeline.pipeline + , *buffer + , viewport + , scissors + , false ); + uint32_t visibleNodesCount{}; + + for ( auto const & node : nodes ) + { + if ( node.visible ) + { + auto instanceCount = node.node->getInstanceCount(); + queuerndnd::registerNodeCommands( *pipeline.pipeline + , node + , commandBuffer + , instanceCount + , pipelineId + , visibleNodesCount + , pipelinesBuffer + , idxIndex + , nidxIndex ); + CU_Require( size_t( std::distance( pipelineNodes.data(), pipelinesBuffer ) ) <= pipelineNodes.size() ); + m_visible.objectCount += instanceCount; + m_visible.faceCount += node.node->data.getFaceCount() * instanceCount; + m_visible.vertexCount += node.node->data.getPointsCount() * instanceCount; + ++visibleNodesCount; + } + } + + ++result; + } + } + } + } + { + C3D_DebugTime( getOwner()->getOwner()->getTypeName() + " - Instantiated" ); + for ( auto const & [_, pipelinesNodes] : m_instancedSubmeshNodes ) + { + auto const & pipeline = pipelinesNodes.pipeline; + auto const & buffers = pipelinesNodes.nodes; + uint32_t * pipelinesBuffer = nullptr; + + for ( auto const & [buffer, submeshes] : buffers ) + { + auto pipelineId = queuerndnd::bindPipeline( commandBuffer + , *this + , *pipeline.pipeline + , *buffer + , viewport + , scissors + , false ); + + for ( auto const & [submesh, node] : submeshes ) + { + auto instanceCount = node.node->getInstanceCount(); + queuerndnd::registerNodeCommands( *pipeline.pipeline + , node + , commandBuffer + , instanceCount + , pipelineId + , 0u + , pipelinesBuffer + , idxIndex + , nidxIndex ); + m_visible.objectCount += instanceCount; + m_visible.faceCount += uint32_t( submesh->getFaceCount() * instanceCount ); + m_visible.vertexCount += uint32_t( submesh->getPointsCount() * instanceCount ); + ++result; + } + } + } + } + return result; + } + uint32_t QueueRenderNodes::doPrepareMeshTraditionalCommandBuffers( ashes::CommandBuffer const & commandBuffer , ashes::Optional< VkViewport > const & viewport , ashes::Optional< VkRect2D > const & scissors @@ -1380,7 +1575,8 @@ namespace castor3d , *pipeline.pipeline , *buffer , viewport - , scissors ); + , scissors + , true ); uint32_t visibleNodesCount{}; for ( auto const & node : nodes ) @@ -1430,7 +1626,8 @@ namespace castor3d , *pipeline.pipeline , *buffer , viewport - , scissors ); + , scissors + , true ); for ( auto const & [submesh, node] : submeshes ) { @@ -1508,7 +1705,8 @@ namespace castor3d , *pipeline.pipeline , *buffer , viewport - , scissors ); + , scissors + , true ); if ( pipeline.pipeline->hasMeshletDescriptorSetLayout() ) { @@ -1597,7 +1795,8 @@ namespace castor3d , *pipelinesNodes.pipeline.pipeline , *buffer , viewport - , scissors ); + , scissors + , true ); if ( pipeline.pipeline->hasMeshletDescriptorSetLayout() ) { @@ -1710,7 +1909,8 @@ namespace castor3d , *pipeline.pipeline , *buffer , viewport - , scissors ); + , scissors + , true ); if ( pipeline.pipeline->hasMeshletDescriptorSetLayout() ) { @@ -1799,7 +1999,8 @@ namespace castor3d , *pipelinesNodes.pipeline.pipeline , *buffer , viewport - , scissors ); + , scissors + , true ); if ( pipeline.pipeline->hasMeshletDescriptorSetLayout() ) { @@ -1869,6 +2070,66 @@ namespace castor3d } #endif + uint32_t QueueRenderNodes::doPrepareBillboardNoDrawIDCommandBuffers( ashes::CommandBuffer const & commandBuffer + , ashes::Optional< VkViewport > const & viewport + , ashes::Optional< VkRect2D > const & scissors + , PipelineNodes * nodesIdsBuffer + , VkDeviceSize maxNodesCount ) + { + C3D_DebugTime( getOwner()->getOwner()->getTypeName() + " - Billboards" ); + uint32_t result{}; + uint32_t nidxIndex{}; + + for ( auto const & [_, pipelinesNodes] : m_billboardNodes ) + { + auto const & pipeline = pipelinesNodes.pipeline; + + for ( auto const & [buffer, nodes] : pipelinesNodes.nodes ) + { + if ( queuerndnd::hasVisibleNode( nodes ) ) + { + auto & pipelineNodes = getPipelineNodes( pipeline.pipeline->getFlagsHash() + , *buffer + , m_nodesIds + , nodesIdsBuffer + , maxNodesCount ); + auto pipelinesBuffer = pipelineNodes.data(); + auto pipelineId = queuerndnd::bindPipeline( commandBuffer + , *this + , *pipeline.pipeline + , *buffer + , viewport + , scissors + , true ); + uint32_t visibleNodesCount{}; + + for ( auto const & node : nodes ) + { + if ( node.visible ) + { + auto instanceCount = node.node->getInstanceCount(); + queuerndnd::registerNodeCommands( *pipeline.pipeline + , node + , commandBuffer + , instanceCount + , pipelineId + , visibleNodesCount + , pipelinesBuffer + , nidxIndex ); + CU_Require( size_t( std::distance( pipelineNodes.data(), pipelinesBuffer ) ) <= pipelineNodes.size() ); + m_visible.billboardCount += node.node->data.getCount(); + ++visibleNodesCount; + } + } + + ++result; + } + } + } + + return result; + } + uint32_t QueueRenderNodes::doPrepareBillboardCommandBuffers( ashes::CommandBuffer const & commandBuffer , ashes::Optional< VkViewport > const & viewport , ashes::Optional< VkRect2D > const & scissors @@ -1904,7 +2165,8 @@ namespace castor3d , *pipeline.pipeline , *buffer , viewport - , scissors ); + , scissors + , true ); uint32_t visibleNodesCount{}; for ( auto const & node : nodes ) diff --git a/source/Core/Castor3D/Render/Opaque/VisibilityReorderPass.cpp b/source/Core/Castor3D/Render/Opaque/VisibilityReorderPass.cpp index 964d64fd25..f205ed6cae 100644 --- a/source/Core/Castor3D/Render/Opaque/VisibilityReorderPass.cpp +++ b/source/Core/Castor3D/Render/Opaque/VisibilityReorderPass.cpp @@ -156,8 +156,8 @@ namespace castor3d } ROF - indirectCounts[pipelineId * 3u + 0u] = writer.cast< sdw::UInt >( ceil( writer.cast< sdw::Float >( materialsCounts[pipelineId] ) / 16.0_f ) ); - indirectCounts[pipelineId * 3u + 1u] = 1u; + indirectCounts[pipelineId * 3u + 0u] = writer.cast< sdw::UInt >( ceil( writer.cast< sdw::Float >( materialsCounts[pipelineId] ) / 64.0_f ) ); + indirectCounts[pipelineId * 3u + 1u] = 4u; indirectCounts[pipelineId * 3u + 2u] = 1u; materialStarts[pipelineId] = result; } diff --git a/source/Core/Castor3D/Render/Opaque/VisibilityResolvePass.cpp b/source/Core/Castor3D/Render/Opaque/VisibilityResolvePass.cpp index bb6233b5e3..847d9a19d8 100644 --- a/source/Core/Castor3D/Render/Opaque/VisibilityResolvePass.cpp +++ b/source/Core/Castor3D/Render/Opaque/VisibilityResolvePass.cpp @@ -31,6 +31,7 @@ #include "Castor3D/Shader/Shaders/GlslClusteredLights.hpp" #include "Castor3D/Shader/Shaders/GlslCookTorranceBRDF.hpp" #include "Castor3D/Shader/Shaders/GlslDebugOutput.hpp" +#include "Castor3D/Shader/Shaders/GlslDerivativeValue.hpp" #include "Castor3D/Shader/Shaders/GlslFog.hpp" #include "Castor3D/Shader/Shaders/GlslGlobalIllumination.hpp" #include "Castor3D/Shader/Shaders/GlslLight.hpp" @@ -236,7 +237,7 @@ namespace castor3d auto c3d_imgOutResult = writer.declStorageImg< sdw::WImage2DRgba32 >( "c3d_imgOutResult", uint32_t( InOutBindings::eOutResult ), Sets::eInOuts ); auto c3d_imgOutScattering = writer.declStorageImg< sdw::WImage2DRgba32 >( "c3d_imgOutScattering", uint32_t( InOutBindings::eOutScattering ), Sets::eInOuts, outputScattering ); - writer.implementMainT< sdw::VoidT >( sdw::ComputeIn{ writer, 16u, 4u, 1u } + writer.implementMainT< sdw::VoidT >( sdw::ComputeIn{ writer, 4u, 4u, 1u } , [&]( sdw::ComputeIn const & in ) { auto pos = in.globalInvocationID.xy(); @@ -247,7 +248,7 @@ namespace castor3d IF( writer, index < materialsCounts[pipelineId] ) { auto pixelIndex = writer.declLocale( "pixelIndex" - , materialsStart + pos.x() ); + , materialsStart + index ); auto pixel = writer.declLocale( "pixel" , pixelsXY[pixelIndex] ); auto ipixel = writer.declLocale( "ipixel" @@ -340,48 +341,142 @@ namespace castor3d , dot( mergedV, dy() ) ); } - shader::DerivTex computeGradient( sdw::Vec3 const & pv0tex - , sdw::Vec3 const & pv1tex - , sdw::Vec3 const & pv2tex ) + shader::DerivVec2 computeGradient( sdw::Vec2 const & pv0 + , sdw::Vec2 const & pv1 + , sdw::Vec2 const & pv2 ) { - if ( !m_computeGradient ) + if ( !m_computeGradient2 ) { auto & writer = *getWriter(); - m_computeGradient = writer.implementFunction< shader::DerivTex >( "computeGradient" + m_computeGradient2 = writer.implementFunction< shader::DerivVec2 >( "computeGradient2" , [&writer]( BarycentricFullDerivatives const & derivatives - , sdw::Vec2 const & v0tex - , sdw::Vec2 const & v1tex - , sdw::Vec2 const & v2tex ) + , sdw::Vec2 const & v0 + , sdw::Vec2 const & v1 + , sdw::Vec2 const & v2 ) { - auto mergedX = writer.declLocale( "merged0X" - , vec3( v0tex.x(), v1tex.x(), v2tex.x() ) ); - auto mergedY = writer.declLocale( "merged0Y" - , vec3( v0tex.y(), v1tex.y(), v2tex.y() ) ); - auto resultsX = writer.declLocale( "results0X" + auto mergedX = writer.declLocale( "mergedX" + , vec3( v0.x(), v1.x(), v2.x() ) ); + auto mergedY = writer.declLocale( "mergedY" + , vec3( v0.y(), v1.y(), v2.y() ) ); + auto resultsX = writer.declLocale( "resultsX" , derivatives.computeGradient( mergedX ) ); - auto resultsY = writer.declLocale( "results0Y" + auto resultsY = writer.declLocale( "resultsY" , derivatives.computeGradient( mergedY ) ); - auto result = writer.declLocale< shader::DerivTex >( "result" ); - result.uv() = vec2( resultsX.x(), resultsY.x() ); + auto result = writer.declLocale< shader::DerivVec2 >( "result" ); + result.value() = vec2( resultsX.x(), resultsY.x() ); result.dPdx() = vec2( resultsX.y(), resultsY.y() ); result.dPdy() = vec2( resultsX.z(), resultsY.z() ); writer.returnStmt( result ); } , InBarycentricFullDerivatives{ writer, "derivatives" } - , sdw::InVec2{ writer, "v0tex" } - , sdw::InVec2{ writer, "v1tex" } - , sdw::InVec2{ writer, "v2tex" } ); + , sdw::InVec2{ writer, "v0" } + , sdw::InVec2{ writer, "v1" } + , sdw::InVec2{ writer, "v2" } ); } - return m_computeGradient( *this, pv0tex.xy(), pv1tex.xy(), pv2tex.xy() ); + return m_computeGradient2( *this, pv0, pv1, pv2 ); + } + + shader::DerivVec3 computeGradient( sdw::Vec3 const & pv0 + , sdw::Vec3 const & pv1 + , sdw::Vec3 const & pv2 ) + { + if ( !m_computeGradient3 ) + { + auto & writer = *getWriter(); + m_computeGradient3 = writer.implementFunction< shader::DerivVec3 >( "computeGradient3" + , [&writer]( BarycentricFullDerivatives const & derivatives + , sdw::Vec3 const & v0 + , sdw::Vec3 const & v1 + , sdw::Vec3 const & v2 ) + { + auto mergedX = writer.declLocale( "mergedX" + , vec3( v0.x(), v1.x(), v2.x() ) ); + auto mergedY = writer.declLocale( "mergedY" + , vec3( v0.y(), v1.y(), v2.y() ) ); + auto mergedZ = writer.declLocale( "mergedZ" + , vec3( v0.z(), v1.z(), v2.z() ) ); + auto resultsX = writer.declLocale( "resultsX" + , derivatives.computeGradient( mergedX ) ); + auto resultsY = writer.declLocale( "resultsY" + , derivatives.computeGradient( mergedY ) ); + auto resultsZ = writer.declLocale( "resultsZ" + , derivatives.computeGradient( mergedZ ) ); + auto result = writer.declLocale< shader::DerivVec3 >( "result" ); + result.value() = vec3( resultsX.x(), resultsY.x(), resultsZ.x() ); + result.dPdx() = vec3( resultsX.y(), resultsY.y(), resultsZ.y() ); + result.dPdy() = vec3( resultsX.z(), resultsY.z(), resultsZ.z() ); + writer.returnStmt( result ); + } + , InBarycentricFullDerivatives{ writer, "derivatives" } + , sdw::InVec3{ writer, "v0" } + , sdw::InVec3{ writer, "v1" } + , sdw::InVec3{ writer, "v2" } ); + } + + return m_computeGradient3( *this, pv0, pv1, pv2 ); + } + + shader::DerivVec4 computeGradient( sdw::Vec4 const & pv0 + , sdw::Vec4 const & pv1 + , sdw::Vec4 const & pv2 ) + { + if ( !m_computeGradient4 ) + { + auto & writer = *getWriter(); + m_computeGradient4 = writer.implementFunction< shader::DerivVec4 >( "computeGradient4" + , [&writer]( BarycentricFullDerivatives const & derivatives + , sdw::Vec4 const & v0 + , sdw::Vec4 const & v1 + , sdw::Vec4 const & v2 ) + { + auto mergedX = writer.declLocale( "mergedX" + , vec3( v0.x(), v1.x(), v2.x() ) ); + auto mergedY = writer.declLocale( "mergedY" + , vec3( v0.y(), v1.y(), v2.y() ) ); + auto mergedZ = writer.declLocale( "mergedZ" + , vec3( v0.z(), v1.z(), v2.z() ) ); + auto mergedW = writer.declLocale( "mergedW" + , vec3( v0.w(), v1.w(), v2.w() ) ); + auto resultsX = writer.declLocale( "resultsX" + , derivatives.computeGradient( mergedX ) ); + auto resultsY = writer.declLocale( "resultsY" + , derivatives.computeGradient( mergedY ) ); + auto resultsZ = writer.declLocale( "resultsZ" + , derivatives.computeGradient( mergedZ ) ); + auto resultsW = writer.declLocale( "resultsW" + , derivatives.computeGradient( mergedW ) ); + auto result = writer.declLocale< shader::DerivVec4 >( "result" ); + result.value() = vec4( resultsX.x(), resultsY.x(), resultsZ.x(), resultsW.x() ); + result.dPdx() = vec4( resultsX.y(), resultsY.y(), resultsZ.y(), resultsW.y() ); + result.dPdy() = vec4( resultsX.z(), resultsY.z(), resultsZ.z(), resultsW.z() ); + writer.returnStmt( result ); + } + , InBarycentricFullDerivatives{ writer, "derivatives" } + , sdw::InVec4{ writer, "v0" } + , sdw::InVec4{ writer, "v1" } + , sdw::InVec4{ writer, "v2" } ); + } + + return m_computeGradient4( *this, pv0, pv1, pv2 ); } private: - sdw::Function< shader::DerivTex + sdw::Function< shader::DerivVec2 , InBarycentricFullDerivatives , sdw::InVec2 , sdw::InVec2 - , sdw::InVec2 > m_computeGradient; + , sdw::InVec2 > m_computeGradient2; + sdw::Function< shader::DerivVec3 + , InBarycentricFullDerivatives + , sdw::InVec3 + , sdw::InVec3 + , sdw::InVec3 > m_computeGradient3; + sdw::Function< shader::DerivVec4 + , InBarycentricFullDerivatives + , sdw::InVec4 + , sdw::InVec4 + , sdw::InVec4 > m_computeGradient4; }; struct Position @@ -722,7 +817,7 @@ namespace castor3d , sdw::Float const & pdepth , shader::CameraData const & c3d_cameraData , sdw::Array< shader::BillboardData > const & c3d_billboardData - , shader::DerivFragmentSurface const & presult ) + , shader::AllDerivFragmentSurface const & presult ) { if ( !m_loadSurface ) { @@ -734,29 +829,21 @@ namespace castor3d , shader::ModelData const & modelData , shader::Material const & material , sdw::Float depth - , shader::DerivFragmentSurface result ) + , shader::AllDerivFragmentSurface result ) { - result.worldPosition = vec4( 0.0_f ); - result.viewPosition = vec4( 0.0_f ); - result.curPosition = vec4( 0.0_f ); - result.prvPosition = vec4( 0.0_f ); - result.tangentSpaceFragPosition = vec3( 0.0_f ); + result.worldPosition = shader::derivVec4( 0.0_f ); + result.viewPosition = shader::derivVec4( 0.0_f ); + result.curPosition = shader::derivVec4( 0.0_f ); + result.prvPosition = shader::derivVec4( 0.0_f ); + result.tangentSpaceFragPosition = shader::derivVec3( 0.0_f ); result.tangentSpaceViewPosition = vec3( 0.0_f ); - result.normal = vec3( 0.0_f ); - result.tangent = vec4( 0.0_f ); - result.bitangent = vec3( 0.0_f ); - result.texture0.uv() = vec2( 0.0_f ); - result.texture1.uv() = vec2( 0.0_f ); - result.texture2.uv() = vec2( 0.0_f ); - result.texture3.uv() = vec2( 0.0_f ); - result.texture0.dPdx() = vec2( 0.0_f ); - result.texture1.dPdx() = vec2( 0.0_f ); - result.texture2.dPdx() = vec2( 0.0_f ); - result.texture3.dPdx() = vec2( 0.0_f ); - result.texture0.dPdy() = vec2( 0.0_f ); - result.texture1.dPdy() = vec2( 0.0_f ); - result.texture2.dPdy() = vec2( 0.0_f ); - result.texture3.dPdy() = vec2( 0.0_f ); + result.normal = shader::derivVec3( 0.0_f ); + result.tangent = shader::derivVec4( 0.0_f ); + result.bitangent = shader::derivVec3( 0.0_f ); + result.texture0 = shader::derivVec2( 0.0_f ); + result.texture1 = shader::derivVec2( 0.0_f ); + result.texture2 = shader::derivVec2( 0.0_f ); + result.texture3 = shader::derivVec2( 0.0_f ); result.colour = vec3( 1.0_f ); auto hdrCoords = m_writer.declLocale( "hdrCoords" @@ -802,30 +889,30 @@ namespace castor3d // Interpolate texture coordinates and calculate the gradients for texture sampling with mipmapping support if ( m_flags.enableTexcoord0() ) { - result.texture0 = derivatives.computeGradient( v0.texture0 - , v1.texture0 - , v2.texture0 ); + result.texture0 = derivatives.computeGradient( v0.texture0.xy() + , v1.texture0.xy() + , v2.texture0.xy() ); } if ( m_flags.enableTexcoord1() ) { - result.texture1 = derivatives.computeGradient( v0.texture1 - , v1.texture1 - , v2.texture1 ); + result.texture1 = derivatives.computeGradient( v0.texture1.xy() + , v1.texture1.xy() + , v2.texture1.xy() ); } if ( m_flags.enableTexcoord2() ) { - result.texture2 = derivatives.computeGradient( v0.texture2 - , v1.texture2 - , v2.texture2 ); + result.texture2 = derivatives.computeGradient( v0.texture2.xy() + , v1.texture2.xy() + , v2.texture2.xy() ); } if ( m_flags.enableTexcoord3() ) { - result.texture3 = derivatives.computeGradient( v0.texture3 - , v1.texture3 - , v2.texture3 ); + result.texture3 = derivatives.computeGradient( v0.texture3.xy() + , v1.texture3.xy() + , v2.texture3.xy() ); } if ( m_flags.enableColours() ) @@ -836,38 +923,27 @@ namespace castor3d } auto normal = m_writer.declLocale( "normal" - , vec3( 0.0_f ) + , ( m_flags.enableNormal() + ? normalize( derivatives.computeGradient( v0.normal, v1.normal, v2.normal ) ) + : shader::derivVec3( 0.0_f ) ) , m_flags.enableNormal() ); - - if ( m_flags.enableNormal() ) - { - normal = normalize( derivatives.interpolate( v0.normal.xyz() - , v1.normal.xyz() - , v2.normal.xyz() ) ); - } - auto tangent = m_writer.declLocale( "tangent" - , vec4( 0.0_f ) + , ( m_flags.enableTangentSpace() + ? derivatives.computeGradient( v0.tangent, v1.tangent, v2.tangent ) + : shader::derivVec4( 0.0_f ) ) , m_flags.enableTangentSpace() ); if ( m_flags.enableTangentSpace() ) { - tangent = normalize( derivatives.interpolate( v0.tangent - , v1.tangent - , v2.tangent ) ); + tangent = derivVec4( normalize( getXYZ( tangent ) ), getW( tangent ) ); } auto bitangent = m_writer.declLocale( "bitangent" - , vec3( 0.0_f ) + , ( m_flags.enableBitangent() + ? normalize( derivatives.computeGradient( v0.bitangent, v1.bitangent, v2.bitangent ) ) + : shader::derivVec3( 0.0_f ) ) , m_flags.enableBitangent() ); - if ( m_flags.enableBitangent() ) - { - bitangent = normalize( derivatives.interpolate( v0.bitangent - , v1.bitangent - , v2.bitangent ) ); - } - if ( m_flags.enablePassMasks() ) { auto passMultipliers0 = m_writer.declLocaleArray< sdw::Vec4 >( "passMultipliers0", 4u ); @@ -892,15 +968,17 @@ namespace castor3d } auto curProjPosition = m_writer.declLocale( "curProjPosition" - , derivatives.interpolate( p0, p1, p2 ) ); + , derivatives.computeGradient( p0, p1, p2 ) ); - IF( m_writer, curProjPosition.w() == 0.0_f ) + IF( m_writer, curProjPosition.value().w() == 0.0_f ) { - curProjPosition.w() = 1.0_f; + curProjPosition.value().w() = 1.0_f; + curProjPosition.dPdx().w() = 0.0_f; + curProjPosition.dPdy().w() = 0.0_f; } FI - depth = ( curProjPosition.z() / curProjPosition.w() ); + depth = ( curProjPosition.value().z() / curProjPosition.value().w() ); auto curPosition = m_writer.declLocale( "curPosition" , c3d_cameraData.projToView( curProjPosition ) ); result.viewPosition = curPosition; @@ -916,10 +994,10 @@ namespace castor3d if ( m_flags.hasWorldPosInputs() ) { auto velocity = m_writer.declLocale( "velocity" - , derivatives.interpolate( v0.velocity.xyz() + , derivatives.computeGradient( v0.velocity.xyz() , v1.velocity.xyz() , v2.velocity.xyz() ) ); - prvPosition.xyz() += velocity; + shader::addXYZ( prvPosition, velocity ); } else if ( m_flags.enableNormal() ) { @@ -934,7 +1012,7 @@ namespace castor3d auto prvMtxModel = m_writer.declLocale( "prvMtxModel" , modelData.getPrvModelMtx( m_flags, curMtxModel ) ); prvPosition = prvMtxModel * curPosition; - tangent = vec4( normalize( mtxNormal * tangent.xyz() ), tangent.w() ); + tangent = derivVec4( normalize( mtxNormal * shader::getXYZ( tangent ) ), shader::getW( tangent ) ); bitangent = normalize( mtxNormal * bitangent ); } } @@ -949,7 +1027,7 @@ namespace castor3d { result.computeTangentSpace( m_flags , c3d_cameraData.position() - , result.worldPosition.xyz() + , shader::getXYZ( result.worldPosition ) , normal , tangent , bitangent ); @@ -962,7 +1040,7 @@ namespace castor3d , shader::InModelData{ m_writer, "modelData" } , shader::InMaterial{ m_writer, "material", m_passShaders } , sdw::OutFloat{ m_writer, "depth" } - , shader::OutDerivFragmentSurface{ m_writer, "result", m_submeshShaders } ); + , shader::OutAllDerivFragmentSurface{ m_writer, "result", m_submeshShaders } ); } m_loadSurface( pnodeId, pprimitiveId, pmeshletId, ppixelCoord, pmodelData, pmaterial, pdepth, presult ); @@ -998,7 +1076,7 @@ namespace castor3d , shader::InModelData , shader::InMaterial , sdw::OutFloat - , shader::OutDerivFragmentSurface > m_loadSurface; + , shader::OutAllDerivFragmentSurface > m_loadSurface; }; static ShaderPtr getProgram( RenderDevice const & device @@ -1159,7 +1237,7 @@ namespace castor3d , ( hasSsao ? c3d_mapOcclusion.fetch( ipixel, 0_i ) : 1.0_f ) ); - auto baseSurface = writer.declLocale< shader::DerivFragmentSurface >( "baseSurface" + auto baseSurface = writer.declLocale< shader::AllDerivFragmentSurface >( "baseSurface" , true , submeshShaders ); visHelpers.loadSurface( curNodeId @@ -1186,11 +1264,11 @@ namespace castor3d , modelData.getMaterialId() , baseSurface.passMultipliers , components ); - output.registerOutput( cuT( "Surface" ), cuT( "Normal" ), fma( components.normal, vec3( 0.5_f ), vec3( 0.5_f ) ) ); - output.registerOutput( cuT( "Surface" ), cuT( "Tangent" ), fma( baseSurface.tangent.xyz(), vec3( 0.5_f ), vec3( 0.5_f ) ) ); - output.registerOutput( cuT( "Surface" ), cuT( "Bitangent" ), fma( baseSurface.bitangent, vec3( 0.5_f ), vec3( 0.5_f ) ) ); - output.registerOutput( cuT( "Surface" ), cuT( "World Position" ), baseSurface.worldPosition ); - output.registerOutput( cuT( "Surface" ), cuT( "View Position" ), baseSurface.viewPosition ); + output.registerOutput( cuT( "Surface" ), cuT( "Normal" ), fma( shader::getRawXYZ( components.getRawNormal() ), vec3( 0.5_f ), vec3( 0.5_f ) ) ); + output.registerOutput( cuT( "Surface" ), cuT( "Tangent" ), fma( shader::getRawXYZ( baseSurface.tangent ), vec3( 0.5_f ), vec3( 0.5_f ) ) ); + output.registerOutput( cuT( "Surface" ), cuT( "Bitangent" ), fma( shader::getRawXYZ( baseSurface.bitangent ), vec3( 0.5_f ), vec3( 0.5_f ) ) ); + output.registerOutput( cuT( "Surface" ), cuT( "World Position" ), shader::getRaw( baseSurface.worldPosition ) ); + output.registerOutput( cuT( "Surface" ), cuT( "View Position" ), shader::getRaw( baseSurface.viewPosition ) ); if ( components.occlusion ) { @@ -1198,7 +1276,7 @@ namespace castor3d } auto incident = writer.declLocale( "incident" - , reflections.computeIncident( baseSurface.worldPosition.xyz(), c3d_cameraData.position() ) ); + , reflections.computeIncident( shader::getXYZ( baseSurface.worldPosition ), c3d_cameraData.position() ) ); if ( components.transmission ) { @@ -1215,13 +1293,12 @@ namespace castor3d IF( writer, material.lighting ) { auto surface = writer.declLocale( "surface" - , shader::Surface{ vec3( vec2( ipixel ), depth ) + , shader::DerivSurface{ vec3( vec2( ipixel ), depth ) , baseSurface.viewPosition , baseSurface.worldPosition - , normalize( components.normal ) } ); + , components.getDerivNormal() } ); lightingModel->finish( passShaders - , baseSurface , surface , utils , c3d_cameraData.position() @@ -1230,7 +1307,7 @@ namespace castor3d , "lightSurface" , c3d_cameraData.position() , surface.worldPosition - , surface.viewPosition.xyz() + , getXYZ( surface.viewPosition ) , surface.clipPosition , surface.normal ); @@ -1244,7 +1321,7 @@ namespace castor3d , lightSurface , modelData.isShadowReceiver() , lightSurface.clipPosition().xy() - , lightSurface.viewPosition().z() + , lightSurface.viewPosition().value().z() , output , diffuse ); inoutDiffuse = vec4( diffuse, components.transmittance ); @@ -1263,7 +1340,7 @@ namespace castor3d , lightSurface , modelData.isShadowReceiver() , lightSurface.clipPosition().xy() - , lightSurface.viewPosition().z() + , lightSurface.viewPosition().value().z() , inoutDiffuse.rgb() , output , directLighting ); @@ -1276,7 +1353,7 @@ namespace castor3d , lightSurface , modelData.isShadowReceiver() , lightSurface.clipPosition().xy() - , lightSurface.viewPosition().z() + , lightSurface.viewPosition().value().z() , output , directLighting ); } @@ -1288,7 +1365,7 @@ namespace castor3d // Indirect Lighting lightSurface.updateL( utils - , components.normal + , components.getDerivNormal() , components.f0 , components ); auto indirectLighting = writer.declLocale( "indirectLighting" @@ -1320,7 +1397,7 @@ namespace castor3d } lightSurface.updateN( utils - , components.normal + , components.getDerivNormal() , components.f0 , components ); passShaders.computeReflRefr( reflections @@ -1332,7 +1409,7 @@ namespace castor3d , indirectLighting , vec2( ipixel ) , modelData.getEnvMapIndex() - , incident + , shader::getRaw( incident ) , components.hasReflection , components.hasRefraction , components.refractionRatio @@ -1342,12 +1419,12 @@ namespace castor3d , coatReflected , sheenReflected , output ); - output.registerOutput( cuT( "Reflections" ), cuT( "Incident" ), sdw::fma( incident, vec3( 0.5_f ), vec3( 0.5_f ) ) ); + output.registerOutput( cuT( "Reflections" ), cuT( "Incident" ), sdw::fma( shader::getRaw( incident ), vec3( 0.5_f ), vec3( 0.5_f ) ) ); // Combine outResult = vec4( lightingModel->combine( output , components - , incident + , shader::getRaw( incident ) , directLighting , indirectLighting , occlusion @@ -1393,7 +1470,7 @@ namespace castor3d { outResult = fog.apply( c3d_sceneData.getBackgroundColour( utils, c3d_cameraData.gamma() ) , outResult - , baseSurface.worldPosition.xyz() + , shader::getRawXYZ( baseSurface.worldPosition ) , c3d_cameraData.position() , c3d_sceneData ); @@ -1401,7 +1478,7 @@ namespace castor3d { outScattering = fog.apply( c3d_sceneData.getBackgroundColour( utils, c3d_cameraData.gamma() ) , outScattering - , baseSurface.worldPosition.xyz() + , shader::getRawXYZ( baseSurface.worldPosition ) , c3d_cameraData.position() , c3d_sceneData ); } diff --git a/source/Core/Castor3D/Render/Overlays/OverlayPreparer.cpp b/source/Core/Castor3D/Render/Overlays/OverlayPreparer.cpp index 0f3eda2811..c017ca6a77 100644 --- a/source/Core/Castor3D/Render/Overlays/OverlayPreparer.cpp +++ b/source/Core/Castor3D/Render/Overlays/OverlayPreparer.cpp @@ -126,12 +126,35 @@ namespace castor3d } } #endif - doRegisterDrawCommands( data.node->pipeline - , pipelineData->descriptorSets->all - , pipelineData->indirectCommandsBuffer->getBuffer() - , uint32_t( overlayDatas.size() ) - , count - , commandBuffer ); + if ( m_device.hasDrawId() ) + { + doRegisterDrawCommands( data.node->pipeline + , pipelineData->descriptorSets->all + , pipelineData->indirectCommandsBuffer->getBuffer() + , uint32_t( overlayDatas.size() ) + , count + , commandBuffer ); + } + else + { + commandBuffer.bindPipeline( *data.node->pipeline.pipeline ); + commandBuffer.bindDescriptorSets( pipelineData->descriptorSets->all + , *data.node->pipeline.pipelineLayout ); + uint32_t index{}; + + for ( auto const & command : castor::makeArrayView( pipelineData->indirectCommands.begin() + count + , uint32_t( overlayDatas.size() ) ) ) + { + doRegisterDrawCommands( data.node->pipeline + , command + , index + , count + , commandBuffer ); + ++index; + } + + count += uint32_t( overlayDatas.size() ); + } } } } @@ -307,7 +330,7 @@ namespace castor3d { commandBuffer.bindPipeline( *pipeline.pipeline ); commandBuffer.bindDescriptorSets( descriptorSets, *pipeline.pipelineLayout ); - DrawConstants constants{ offset }; + DrawConstants constants{ offset, 0u }; commandBuffer.pushConstants( *pipeline.pipelineLayout , VK_SHADER_STAGE_VERTEX_BIT , 0u @@ -325,6 +348,29 @@ namespace castor3d } } + void OverlayPreparer::doRegisterDrawCommands( OverlayDrawPipeline const & pipeline + , VkDrawIndirectCommand const & command + , uint32_t drawId + , uint32_t & offset + , ashes::CommandBuffer const & commandBuffer )noexcept + { + DrawConstants constants{ offset, int32_t( drawId ) }; + commandBuffer.pushConstants( *pipeline.pipelineLayout + , VK_SHADER_STAGE_VERTEX_BIT + , 0u + , sizeof( constants ) + , &constants ); + commandBuffer.draw( command.vertexCount + , command.instanceCount + , command.firstVertex + , command.firstInstance ); + + if ( m_drawCounts ) + { + ++( *m_drawCounts ); + } + } + void OverlayPreparer::doUpdateUbo( OverlayUboConfiguration & data , PanelOverlay const & overlay , Pass const & pass diff --git a/source/Core/Castor3D/Render/Overlays/OverlayRenderer.cpp b/source/Core/Castor3D/Render/Overlays/OverlayRenderer.cpp index 3f0ea235ba..04be42721d 100644 --- a/source/Core/Castor3D/Render/Overlays/OverlayRenderer.cpp +++ b/source/Core/Castor3D/Render/Overlays/OverlayRenderer.cpp @@ -902,6 +902,7 @@ namespace castor3d sdw::PushConstantBuffer pcb{ writer, "C3D_DrawData", "c3d_drawData" }; auto pipelineBaseIndex = pcb.declMember< sdw::UInt >( "pipelineBaseIndex" ); + auto drawID = pcb.declMember< sdw::Int >( "drawID" ); pcb.end(); // Vertex shader @@ -911,7 +912,7 @@ namespace castor3d , sdw::VertexOutT< shader::OverlaySurfaceT > out ) { auto overlaySubID = writer.declLocale( "overlaySubID" - , pipelineBaseIndex + ( writer.cast< sdw::UInt >( in.drawID ) ) ); + , pipelineBaseIndex + ( writer.cast< sdw::UInt >( engine.getRenderDevice()->hasDrawId() ? in.drawID : drawID ) ) ); auto overlayID = writer.declLocale( "overlayID" , c3d_overlaysIDs[overlaySubID] ); auto overlay = writer.declLocale( "overlay" diff --git a/source/Core/Castor3D/Render/Passes/ForwardRenderTechniquePass.cpp b/source/Core/Castor3D/Render/Passes/ForwardRenderTechniquePass.cpp index 5fafe9a269..25b889e963 100644 --- a/source/Core/Castor3D/Render/Passes/ForwardRenderTechniquePass.cpp +++ b/source/Core/Castor3D/Render/Passes/ForwardRenderTechniquePass.cpp @@ -356,7 +356,7 @@ namespace castor3d occlusion *= components.occlusion; } - output.registerOutput( cuT( "Surface" ), cuT( "Normal" ), fma( components.normal, vec3( 0.5_f ), vec3( 0.5_f ) ) ); + output.registerOutput( cuT( "Surface" ), cuT( "Normal" ), fma( components.getRawNormal(), vec3( 0.5_f ), vec3( 0.5_f ) ) ); output.registerOutput( cuT( "Surface" ), cuT( "Tangent" ), fma( in.tangent.xyz(), vec3( 0.5_f ), vec3( 0.5_f ) ) ); output.registerOutput( cuT( "Surface" ), cuT( "Bitangent" ), fma( in.bitangent, vec3( 0.5_f ), vec3( 0.5_f ) ) ); output.registerOutput( cuT( "Surface" ), cuT( "World Position" ), in.worldPosition ); @@ -382,12 +382,11 @@ namespace castor3d { // Direct Lighting auto surface = writer.declLocale( "surface" - , shader::Surface{ in.fragCoord.xyz() - , in.viewPosition - , in.worldPosition - , normalize( components.normal ) } ); + , shader::DerivSurface{ in.fragCoord.xyz() + , { in.viewPosition, dFdx( in.viewPosition ), dFdy( in.viewPosition ) } + , { in.worldPosition, dFdx( in.worldPosition ), dFdy( in.worldPosition ) } + , normalize( components.getDerivNormal() ) } ); lightingModel->finish( passShaders - , in , surface , utils , c3d_cameraData.position() @@ -396,7 +395,7 @@ namespace castor3d , "lightSurface" , c3d_cameraData.position() , surface.worldPosition - , surface.viewPosition.xyz() + , getXYZ( surface.viewPosition ) , surface.clipPosition , surface.normal ); @@ -410,7 +409,7 @@ namespace castor3d , lightSurface , modelData.isShadowReceiver() , lightSurface.clipPosition().xy() - , lightSurface.viewPosition().z() + , lightSurface.viewPosition().value().z() , output , diffuse ); outDiffuse = vec4( diffuse, components.transmittance ); @@ -431,7 +430,7 @@ namespace castor3d , lightSurface , modelData.isShadowReceiver() , lightSurface.clipPosition().xy() - , lightSurface.viewPosition().z() + , lightSurface.viewPosition().value().z() , c3d_imgDiffuse.load( ivec2( in.fragCoord.xy() ) ).rgb() , output , directLighting ); @@ -444,7 +443,7 @@ namespace castor3d , lightSurface , modelData.isShadowReceiver() , lightSurface.clipPosition().xy() - , lightSurface.viewPosition().z() + , lightSurface.viewPosition().value().z() , output , directLighting ); } @@ -456,7 +455,7 @@ namespace castor3d // Indirect Lighting lightSurface.updateL( utils - , components.normal + , components.getDerivNormal() , components.f0 , components ); auto indirectLighting = writer.declLocale( "indirectLighting" @@ -488,13 +487,13 @@ namespace castor3d } lightSurface.updateN( utils - , components.normal + , components.getDerivNormal() , components.f0 , components ); passShaders.computeReflRefr( reflections , components , lightSurface - , lightSurface.worldPosition() + , lightSurface.worldPosition().value() , *backgroundModel , c3d_mapScene , c3d_cameraData diff --git a/source/Core/Castor3D/Render/Prepass/DepthPass.cpp b/source/Core/Castor3D/Render/Prepass/DepthPass.cpp index 28f6b99bd8..14b1b63de5 100644 --- a/source/Core/Castor3D/Render/Prepass/DepthPass.cpp +++ b/source/Core/Castor3D/Render/Prepass/DepthPass.cpp @@ -201,7 +201,7 @@ namespace castor3d , writer.cast< sdw::Float >( in.nodeId ) , writer.cast< sdw::Float >( material.lightingModel ) ); out.velocity = in.getVelocity(); - out.nmlOcc = vec4( components.normal, components.occlusion ); + out.nmlOcc = vec4( components.getRawNormal(), components.occlusion ); } ); } } diff --git a/source/Core/Castor3D/Render/Prepass/PrepassRendering.cpp b/source/Core/Castor3D/Render/Prepass/PrepassRendering.cpp index 0140152ea5..3a3af5028f 100644 --- a/source/Core/Castor3D/Render/Prepass/PrepassRendering.cpp +++ b/source/Core/Castor3D/Render/Prepass/PrepassRendering.cpp @@ -126,7 +126,8 @@ namespace castor3d bool PrepassRendering::hasVisibility()const noexcept { - return bool( m_result[PpTexture::eVisibility] ); + return m_device.hasBindless() + && bool( m_result[PpTexture::eVisibility] ); } crg::FramePass & PrepassRendering::doCreateVisibilityPass( ProgressBar * progress diff --git a/source/Core/Castor3D/Render/Prepass/VisibilityPass.cpp b/source/Core/Castor3D/Render/Prepass/VisibilityPass.cpp index b21706fbdb..ded7c5d221 100644 --- a/source/Core/Castor3D/Render/Prepass/VisibilityPass.cpp +++ b/source/Core/Castor3D/Render/Prepass/VisibilityPass.cpp @@ -216,7 +216,7 @@ namespace castor3d } out.velocity = in.getVelocity(); - out.nmlOcc = vec4( components.normal, components.occlusion ); + out.nmlOcc = vec4( components.getRawNormal(), components.occlusion ); } ); } } diff --git a/source/Core/Castor3D/Render/RenderDevice.cpp b/source/Core/Castor3D/Render/RenderDevice.cpp index 7e84344c87..805438202f 100644 --- a/source/Core/Castor3D/Render/RenderDevice.cpp +++ b/source/Core/Castor3D/Render/RenderDevice.cpp @@ -389,6 +389,9 @@ namespace castor3d #endif if ( hasFeatures2 ) { +#if defined( VK_KHR_portability_subset ) + doTryAddExtension( VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME, &m_portabilitySubsetFeatures, &m_portabilitySubsetProperties ); +#endif #if VK_KHR_shader_float_controls if ( !hasFloatControls ) { @@ -1013,6 +1016,20 @@ namespace castor3d #endif } + bool RenderDevice::hasGeometryShader()const noexcept + { + return features.geometryShader == VK_TRUE; + } + + bool RenderDevice::hasDrawId()const noexcept + { +#if VK_VERSION_1_1 + return m_features11.shaderDrawParameters == VK_TRUE; +#elif VK_KHR_draw_parameters + return m_drawParamsFeatures.shaderDrawParameters == VK_TRUE; +#endif + } + bool RenderDevice::doTryAddExtension( castor::MbString const & name , void * pFeature , void * pProperty ) diff --git a/source/Core/Castor3D/Render/RenderSystem.cpp b/source/Core/Castor3D/Render/RenderSystem.cpp index 310eb29b22..ea85c20bcf 100644 --- a/source/Core/Castor3D/Render/RenderSystem.cpp +++ b/source/Core/Castor3D/Render/RenderSystem.cpp @@ -803,6 +803,12 @@ namespace castor3d { instanceExtensions.addExtension( VK_KHR_WIN32_SURFACE_EXTENSION_NAME ); } +#endif +#if VK_KHR_portability_enumeration + if ( rendsys::isExtensionAvailable( globalLayerExtensions, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME ) ) + { + instanceExtensions.addExtension( VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME ); + } #endif if ( engine.isValidationEnabled() ) { diff --git a/source/Core/Castor3D/Render/RenderTarget.cpp b/source/Core/Castor3D/Render/RenderTarget.cpp index 8d83b1f018..2696acf21f 100644 --- a/source/Core/Castor3D/Render/RenderTarget.cpp +++ b/source/Core/Castor3D/Render/RenderTarget.cpp @@ -27,7 +27,6 @@ #include "Castor3D/Render/Overlays/OverlayRenderer.hpp" #include "Castor3D/Render/PostEffect/PostEffect.hpp" #include "Castor3D/Render/ToneMapping/ToneMapping.hpp" -#include "Castor3D/Render/ToTexture/Texture3DTo2D.hpp" #include "Castor3D/Scene/Camera.hpp" #include "Castor3D/Scene/Scene.hpp" #include "Castor3D/Scene/SceneFileParserData.hpp" diff --git a/source/Core/Castor3D/Render/RenderTechnique.cpp b/source/Core/Castor3D/Render/RenderTechnique.cpp index 3fe0f0c014..cf0c97061d 100644 --- a/source/Core/Castor3D/Render/RenderTechnique.cpp +++ b/source/Core/Castor3D/Render/RenderTechnique.cpp @@ -393,7 +393,7 @@ namespace castor3d , progress ) : nullptr ) } #endif - , m_voxelizer{ ( ( m_renderTarget.isFullLoadingEnabled() || m_renderTarget.getScene()->getVoxelConeTracingConfig().enabled ) + , m_voxelizer{ ( ( ( m_renderTarget.isFullLoadingEnabled() || m_renderTarget.getScene()->getVoxelConeTracingConfig().enabled ) && m_device.hasGeometryShader() ) ? castor::makeUnique< Voxelizer >( m_renderTarget.getResources() , m_device , progress diff --git a/source/Core/Castor3D/Render/RenderWindow.cpp b/source/Core/Castor3D/Render/RenderWindow.cpp index 7b319bcfb5..cb37addb8b 100644 --- a/source/Core/Castor3D/Render/RenderWindow.cpp +++ b/source/Core/Castor3D/Render/RenderWindow.cpp @@ -617,7 +617,11 @@ namespace castor3d updater.gridCenter = {}; } - m_texture3Dto2D->update( updater ); + if (m_texture3Dto2D ) + { + m_texture3Dto2D->update( updater ); + } + auto & config = m_configUbo.getData(); config.multiply = castor::Point4f{ intermediate.factors.multiply }; config.add = castor::Point4f{ intermediate.factors.add }; @@ -1461,20 +1465,24 @@ namespace castor3d return; } - VkExtent2D extent{ m_size.getWidth(), m_size.getHeight() }; - m_texture3Dto2D = castor::makeUnique< Texture3DTo2D >( m_device - , m_resources - , extent - , target->getCameraUbo() ); - m_tex3DTo2DIntermediate = { cuT( "Texture3DTo2DResult" ) - , m_texture3Dto2D->getTarget().sampledViewId - , VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL - , castor3d::TextureFactors{}.invert( true ) }; auto intermediates = getEngine()->areDebugTargetsEnabled() ? target->getIntermediateViews() : IntermediateViewArray{ target->getIntermediateViews()[0] }; - m_texture3Dto2D->createPasses( queueData, intermediates ); + + if ( m_device.hasGeometryShader() ) + { + VkExtent2D extent{ m_size.getWidth(), m_size.getHeight() }; + m_texture3Dto2D = castor::makeUnique< Texture3DTo2D >( m_device + , m_resources + , extent + , target->getCameraUbo() ); + m_texture3Dto2D->createPasses( queueData, intermediates ); + } + m_tex3DTo2DIntermediate = { cuT( "Texture3DTo2DResult" ) + , m_texture3Dto2D->getTarget().sampledViewId + , VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + , castor3d::TextureFactors{}.invert( true ) }; m_intermediateBarrierViews = rendwndw::doCreateBarrierViews( m_device , m_tex3DTo2DIntermediate , intermediates ); @@ -1844,7 +1852,7 @@ namespace castor3d doRecordCommandBuffer( passIndex ); #if !C3D_DebugPicking && !C3D_DebugBackgroundPicking - if ( getEngine()->areDebugTargetsEnabled() ) + if ( getEngine()->areDebugTargetsEnabled() && m_texture3Dto2D ) { m_texture3Dto2D->render( *queueData.queue , semaphores diff --git a/source/Core/Castor3D/Render/ShadowMap/ShadowMap.cpp b/source/Core/Castor3D/Render/ShadowMap/ShadowMap.cpp index c053ac83f8..b2ccaaf694 100644 --- a/source/Core/Castor3D/Render/ShadowMap/ShadowMap.cpp +++ b/source/Core/Castor3D/Render/ShadowMap/ShadowMap.cpp @@ -22,21 +22,6 @@ namespace castor3d { namespace shdmap { - static inline ashes::VkClearValueArray const ClearValues - { - []() - { - ashes::VkClearValueArray tmp; - - for ( uint32_t i = 0u; i < uint32_t( SmTexture::eCount ); ++i ) - { - tmp.push_back( getClearValue( SmTexture( i ) ) ); - } - - return tmp; - }() - }; - static uint32_t getPassesIndex( bool needsVsm , bool needsRsm ) { @@ -279,7 +264,21 @@ namespace castor3d ashes::VkClearValueArray const & ShadowMap::getClearValues()const { - return shdmap::ClearValues; + static ashes::VkClearValueArray const result + { + []() + { + ashes::VkClearValueArray tmp; + + for ( uint32_t i = 0u; i < uint32_t( SmTexture::eCount ); ++i ) + { + tmp.push_back( getClearValue( SmTexture( i ) ) ); + } + + return tmp; + }( ) + }; + return result; } ashes::Sampler const & ShadowMap::getSampler( SmTexture texture diff --git a/source/Core/Castor3D/Render/ShadowMap/ShadowMapPassDirectional.cpp b/source/Core/Castor3D/Render/ShadowMap/ShadowMapPassDirectional.cpp index 9bf71402a7..cf2cb512ec 100644 --- a/source/Core/Castor3D/Render/ShadowMap/ShadowMapPassDirectional.cpp +++ b/source/Core/Castor3D/Render/ShadowMap/ShadowMapPassDirectional.cpp @@ -171,6 +171,7 @@ namespace castor3d sdw::PushConstantBuffer pcb{ writer, "C3D_DrawData", "c3d_drawData" }; auto pipelineID = pcb.declMember< sdw::UInt >( "pipelineID" ); + auto drawID = pcb.declMember< sdw::Int >( "drawID", !getEngine()->getRenderDevice()->hasDrawId() ); pcb.end(); writer.implementMainT< shader::MeshVertexT, shader::FragmentSurfaceT >( sdw::VertexInT< shader::MeshVertexT >{ writer, submeshShaders } @@ -182,7 +183,7 @@ namespace castor3d , shader::getNodeId( c3d_objectIdsData , in , pipelineID - , writer.cast< sdw::UInt >( in.drawID ) + , writer.cast< sdw::UInt >( getEngine()->getRenderDevice()->hasDrawId() ? in.drawID : drawID ) , flags ) ); auto curPosition = writer.declLocale( "curPosition" , in.position ); @@ -354,7 +355,7 @@ namespace castor3d out.flux.rgb() = components.colour * light.base().colour() * light.base().intensity().x(); - out.normal.xyz() = components.normal; + out.normal.xyz() = components.getRawNormal(); out.position.xyz() = in.worldPosition.xyz(); } } ); diff --git a/source/Core/Castor3D/Render/ShadowMap/ShadowMapPassPoint.cpp b/source/Core/Castor3D/Render/ShadowMap/ShadowMapPassPoint.cpp index 2ba8de0cd8..db44df66c8 100644 --- a/source/Core/Castor3D/Render/ShadowMap/ShadowMapPassPoint.cpp +++ b/source/Core/Castor3D/Render/ShadowMap/ShadowMapPassPoint.cpp @@ -163,6 +163,7 @@ namespace castor3d sdw::PushConstantBuffer pcb{ writer, "C3D_DrawData", "c3d_drawData" }; auto pipelineID = pcb.declMember< sdw::UInt >( "pipelineID" ); + auto drawID = pcb.declMember< sdw::Int >( "drawID", !getEngine()->getRenderDevice()->hasDrawId() ); pcb.end(); writer.implementMainT< shader::MeshVertexT, shader::FragmentSurfaceT >( sdw::VertexInT< shader::MeshVertexT >{ writer, submeshShaders } @@ -174,7 +175,7 @@ namespace castor3d , shader::getNodeId( c3d_objectIdsData , in , pipelineID - , writer.cast< sdw::UInt >( in.drawID ) + , writer.cast< sdw::UInt >( getEngine()->getRenderDevice()->hasDrawId() ? in.drawID : drawID ) , flags ) ); auto curPosition = writer.declLocale( "curPosition" , in.position ); @@ -351,9 +352,9 @@ namespace castor3d out.flux.rgb() = ( components.colour * light.base().colour() * light.base().intensity().x() - * clamp( dot( lightToVertex / distance, components.normal ), 0.0_f, 1.0_f ) ) + * clamp( dot( lightToVertex / distance, components.getRawNormal() ), 0.0_f, 1.0_f ) ) * attenuation; - out.normal.xyz() = components.normal; + out.normal.xyz() = components.getRawNormal(); out.position.xyz() = in.worldPosition.xyz(); } } ); diff --git a/source/Core/Castor3D/Render/ShadowMap/ShadowMapPassSpot.cpp b/source/Core/Castor3D/Render/ShadowMap/ShadowMapPassSpot.cpp index e22f2e2888..0f6b2277ed 100644 --- a/source/Core/Castor3D/Render/ShadowMap/ShadowMapPassSpot.cpp +++ b/source/Core/Castor3D/Render/ShadowMap/ShadowMapPassSpot.cpp @@ -153,6 +153,7 @@ namespace castor3d sdw::PushConstantBuffer pcb{ writer, "C3D_DrawData", "c3d_drawData" }; auto pipelineID = pcb.declMember< sdw::UInt >( "pipelineID" ); + auto drawID = pcb.declMember< sdw::Int >( "drawID", !getEngine()->getRenderDevice()->hasDrawId() ); pcb.end(); writer.implementMainT< shader::MeshVertexT, shader::FragmentSurfaceT >( sdw::VertexInT< shader::MeshVertexT >{ writer, submeshShaders } @@ -164,7 +165,7 @@ namespace castor3d , shader::getNodeId( c3d_objectIdsData , in , pipelineID - , writer.cast< sdw::UInt >( in.drawID ) + , writer.cast< sdw::UInt >( getEngine()->getRenderDevice()->hasDrawId() ? in.drawID : drawID ) , flags ) ); auto curPosition = writer.declLocale( "curPosition" , in.position ); @@ -363,9 +364,9 @@ namespace castor3d out.flux.rgb() = ( components.colour * light.base().colour() * light.base().intensity().x() - * clamp( dot( L, components.normal ), 0.0_f, 1.0_f ) ) + * clamp( dot( L, components.getRawNormal() ), 0.0_f, 1.0_f ) ) * attenuation; - out.normal.xyz() = components.normal; + out.normal.xyz() = components.getRawNormal(); out.position.xyz() = in.worldPosition.xyz(); } } ); diff --git a/source/Core/Castor3D/Render/ShadowMap/ShadowMapResult.cpp b/source/Core/Castor3D/Render/ShadowMap/ShadowMapResult.cpp index 5aabeb9210..30febc41de 100644 --- a/source/Core/Castor3D/Render/ShadowMap/ShadowMapResult.cpp +++ b/source/Core/Castor3D/Render/ShadowMap/ShadowMapResult.cpp @@ -34,12 +34,12 @@ namespace castor3d static castor::Array< VkFormat, size_t( SmTexture::eCount ) > Values { { - VK_FORMAT_D16_UNORM, // Depth - VK_FORMAT_R32_SFLOAT, // Linear - VK_FORMAT_R32G32_SFLOAT, // Variance - device.selectSmallestFormatRGBSFloatFormat( getFeatureFlags( getUsageFlags( SmTexture::eNormal ) ) ), // Normal - device.selectSmallestFormatRGBSFloatFormat( getFeatureFlags( getUsageFlags( SmTexture::ePosition ) ) ), // Position - device.selectSmallestFormatRGBUFloatFormat( getFeatureFlags( getUsageFlags( SmTexture::eFlux ) ) ), // Flux + VK_FORMAT_D16_UNORM, // Depth + VK_FORMAT_R32_SFLOAT, // Linear + VK_FORMAT_R32G32_SFLOAT, // Variance + device.selectSmallestFormatRGBSFloatFormat( getFeatureFlags( getUsageFlags( SmTexture::eNormal ) ) ), // Normal + device.selectSmallestFormatRGBSFloatFormat( getFeatureFlags( getUsageFlags( SmTexture::ePosition ) ) ), // Position + device.selectSmallestFormatRGBUFloatFormat( getFeatureFlags( getUsageFlags( SmTexture::eFlux ) ) ), // Flux } }; return Values[size_t( texture )]; diff --git a/source/Core/Castor3D/Render/Texture.cpp b/source/Core/Castor3D/Render/Texture.cpp index 0cc6049730..9c10575398 100644 --- a/source/Core/Castor3D/Render/Texture.cpp +++ b/source/Core/Castor3D/Render/Texture.cpp @@ -56,7 +56,8 @@ namespace castor3d , mipFilter , addressMode , addressMode - , addressMode ); + , addressMode + , borderColor ); engine.hasSampler( splName ) ) { c3dSampler = engine.findSampler( splName ); diff --git a/source/Core/Castor3D/Render/Transparent/TransparentPass.cpp b/source/Core/Castor3D/Render/Transparent/TransparentPass.cpp index 27d34ea2f1..56aa1b8358 100644 --- a/source/Core/Castor3D/Render/Transparent/TransparentPass.cpp +++ b/source/Core/Castor3D/Render/Transparent/TransparentPass.cpp @@ -361,7 +361,7 @@ namespace castor3d , modelData.getMaterialId() , in.passMultipliers , components ); - output.registerOutput( cuT( "Surface" ), cuT( "Normal" ), fma( components.normal, vec3( 0.5_f ), vec3( 0.5_f ) ) ); + output.registerOutput( cuT( "Surface" ), cuT( "Normal" ), fma( components.getRawNormal(), vec3( 0.5_f ), vec3( 0.5_f ) ) ); output.registerOutput( cuT( "Surface" ), cuT( "Tangent" ), fma( in.tangent.xyz(), vec3( 0.5_f ), vec3( 0.5_f ) ) ); output.registerOutput( cuT( "Surface" ), cuT( "Bitangent" ), fma( in.bitangent, vec3( 0.5_f ), vec3( 0.5_f ) ) ); output.registerOutput( cuT( "Surface" ), cuT( "World Position" ), in.worldPosition ); @@ -383,12 +383,11 @@ namespace castor3d , shader::DirectLighting{ writer } ); // Direct Lighting auto surface = writer.declLocale( "surface" - , shader::Surface{ in.fragCoord.xyz() - , in.viewPosition - , in.worldPosition - , normalize( components.normal ) } ); + , shader::DerivSurface{ in.fragCoord.xyz() + , { in.viewPosition, dFdx( in.viewPosition ), dFdy( in.viewPosition ) } + , { in.worldPosition, dFdx( in.worldPosition ), dFdy( in.worldPosition ) } + , normalize( components.getDerivNormal() ) } ); lightingModel->finish( passShaders - , in , surface , utils , c3d_cameraData.position() @@ -397,7 +396,7 @@ namespace castor3d , "lightSurface" , c3d_cameraData.position() , surface.worldPosition - , surface.viewPosition.xyz() + , getXYZ( surface.viewPosition ) , surface.clipPosition , surface.normal ); lights.computeCombinedDifSpec( clusteredLights @@ -406,7 +405,7 @@ namespace castor3d , lightSurface , modelData.isShadowReceiver() , lightSurface.clipPosition().xy() - , lightSurface.viewPosition().z() + , lightSurface.viewPosition().value().z() , output , directLighting ); directLighting.ambient() = components.ambientColour * c3d_sceneData.ambientLight() * components.ambientFactor; @@ -416,7 +415,7 @@ namespace castor3d // Indirect Lighting lightSurface.updateL( utils - , components.normal + , components.getDerivNormal() , components.f0 , components ); auto indirectLighting = writer.declLocale( "indirectLighting" @@ -448,15 +447,15 @@ namespace castor3d } auto incident = writer.declLocale( "incident" - , reflections.computeIncident( lightSurface.worldPosition().xyz(), c3d_cameraData.position() ) ); + , reflections.computeIncident( lightSurface.worldPosition().value().xyz(), c3d_cameraData.position() ) ); lightSurface.updateN( utils - , components.normal + , components.getDerivNormal() , components.f0 , components ); passShaders.computeReflRefr( reflections , components , lightSurface - , lightSurface.worldPosition() + , lightSurface.worldPosition().value() , *backgroundModel , c3d_mapScene , c3d_cameraData diff --git a/source/Core/Castor3D/Shader/Shaders/GlslBlendComponents.cpp b/source/Core/Castor3D/Shader/Shaders/GlslBlendComponents.cpp index d5e0f05108..3b13b873db 100644 --- a/source/Core/Castor3D/Shader/Shaders/GlslBlendComponents.cpp +++ b/source/Core/Castor3D/Shader/Shaders/GlslBlendComponents.cpp @@ -7,6 +7,7 @@ #include "Castor3D/Shader/Shaders/GlslSurface.hpp" #include +#include namespace castor3d::shader { @@ -18,7 +19,6 @@ namespace castor3d::shader : sdw::StructInstance{ writer, castor::move( expr ), enabled } , f0{ getMember( "f0", vec3( 0.04_f ) ) } , f90{ getMember( "f90", vec3( 1.0_f ) ) } - , normal{ getMember( "normal", vec3( 0.0_f ) ) } , colour{ getMember( "colour", vec3( 0.0_f ) ) } , emissiveColour{ getMember( "emissiveColour", vec3( 0.0_f ) ) } , emissiveFactor{ getMember( "emissiveFactor", 0.0_f ) } @@ -52,6 +52,13 @@ namespace castor3d::shader , shininess{ computeShininessFromRoughness( roughness ) } , specular{ getMember( "specular", vec3( 0.0_f ) ) } { + auto & structType = static_cast< sdw::type::Struct const & >( *sdw::StructInstance::getType() ); + + if ( auto index = structType.findMember( "normal" ); + index != ast::type::Struct::NotFound ) + { + m_derivativeValues = ast::type::isStructType( structType.getMember( index ).type ); + } } BlendComponents::BlendComponents( Materials const & materials @@ -63,6 +70,15 @@ namespace castor3d::shader { } + BlendComponents::BlendComponents( Materials const & materials + , Material const & material + , DerivSurfaceBase const & surface ) + : BlendComponents{ *materials.getWriter() + , makeInit( materials, material, surface, nullptr ) + , true } + { + } + BlendComponents::BlendComponents( Materials const & materials , Material const & material , SurfaceBase const & surface @@ -73,6 +89,15 @@ namespace castor3d::shader { } + BlendComponents::BlendComponents( Materials const & materials + , Material const & material + , DerivSurfaceBase const & surface + , sdw::Vec4 const & clrCot ) + : BlendComponents{ *materials.getWriter() + , makeInit( materials, material, surface, &clrCot ) + , true } + {} + BlendComponents::BlendComponents( Materials const & materials , bool zeroInit ) : BlendComponents{ *materials.getWriter() @@ -82,13 +107,85 @@ namespace castor3d::shader } void BlendComponents::finish( PassShaders const & passShaders - , SurfaceBase const & surface + , DerivSurfaceBase const & surface , Utils & utils , sdw::Vec3 const worldEye ) { passShaders.finishComponents( surface, worldEye, utils, *this ); } + void BlendComponents::setNormal( sdw::Vec3 const v ) + { + if ( usesDerivativeValues() ) + { + getMember< shader::DerivVec3 >( "normal" ).value() = v; + } + else + { + getMember< sdw::Vec3 >( "normal" ) = v; + } + } + + void BlendComponents::normalizeNormal() + { + if ( usesDerivativeValues() ) + { + getMember< shader::DerivVec3 >( "normal" ) = normalize( getMember< shader::DerivVec3 >( "normal" ) ); + } + else + { + getMember< sdw::Vec3 >( "normal" ) = normalize( getMember< sdw::Vec3 >( "normal" ) ); + } + } + + sdw::Vec3 BlendComponents::getRawNormal()const + { + return usesDerivativeValues() + ? getMember< shader::DerivVec3 >( "normal" ).value() + : getMember< sdw::Vec3 >( "normal" ); + } + + sdw::Vec4 BlendComponents::getRawTangent()const + { + return usesDerivativeValues() + ? getMember< shader::DerivVec4 >( "tangent" ).value() + : getMember< sdw::Vec4 >( "tangent" ); + } + + sdw::Vec3 BlendComponents::getRawBitangent()const + { + return usesDerivativeValues() + ? getMember< shader::DerivVec3 >( "bitangent" ).value() + : getMember< sdw::Vec3 >( "bitangent" ); + } + + shader::DerivVec3 BlendComponents::getDerivNormal()const + { + return usesDerivativeValues() + ? getMember< shader::DerivVec3 >( "normal" ) + : shader::DerivVec3{ normalize( getMember< sdw::Vec3 >( "normal" ) ) + , dFdx( getMember< sdw::Vec3 >( "normal" ) ) + , dFdy( getMember< sdw::Vec3 >( "normal" ) ) }; + } + + shader::DerivVec4 BlendComponents::getDerivTangent()const + { + return usesDerivativeValues() + ? getMember< shader::DerivVec4 >( "tangent" ) + : shader::DerivVec4{ normalize( getMember< sdw::Vec4 >( "tangent" ) ) + , dFdx( getMember< sdw::Vec4 >( "tangent" ) ) + , dFdy( getMember< sdw::Vec4 >( "tangent" ) ) }; + } + + shader::DerivVec3 BlendComponents::getDerivBitangent()const + { + return usesDerivativeValues() + ? getMember< shader::DerivVec3 >( "bitangent" ) + : shader::DerivVec3{ normalize( getMember< sdw::Vec3 >( "bitangent" ) ) + , dFdx( getMember< sdw::Vec3 >( "bitangent" ) ) + , dFdy( getMember< sdw::Vec3 >( "bitangent" ) ) }; + } + sdw::type::BaseStructPtr BlendComponents::makeType( ast::type::TypesCache & cache , Materials const & materials , bool zeroInit diff --git a/source/Core/Castor3D/Shader/Shaders/GlslDerivativeValue.cpp b/source/Core/Castor3D/Shader/Shaders/GlslDerivativeValue.cpp new file mode 100644 index 0000000000..390d69aee0 --- /dev/null +++ b/source/Core/Castor3D/Shader/Shaders/GlslDerivativeValue.cpp @@ -0,0 +1,930 @@ +#include "Castor3D/Shader/Shaders/GlslDerivativeValue.hpp" + +namespace castor3d::shader +{ + namespace deriv + { + template< typename ReturnT, typename FuncT, typename DerivT > + ReturnT applyMbr( FuncT func, std::string const & name + , DerivT const & pa ) + { + auto & writer = sdw::findWriterMandat( pa ); + auto function = writer.template implementFunction< ReturnT >( name + , [&writer, func]( DerivT const & a ) + { + auto a00 = writer.declLocale( "a00", a.value() ); + auto a10 = writer.declLocale( "a10", a.value() + a.dPdx() ); + auto a01 = writer.declLocale( "a01", a.value() + a.dPdy() ); + auto r00 = writer.declLocale( "r00", ( a00.*func )() ); + auto r10 = writer.declLocale( "r10", ( a10.*func )() ); + auto r01 = writer.declLocale( "r01", ( a01.*func )() ); + writer.returnStmt( ReturnT{ r00, r10 - r00, r01 - r00 } ); + } + , sdw::InParam< DerivT >{ writer, "a" } ); + return function( pa ); + } + + template< typename ReturnT, typename FuncT, typename DerivT > + sdw::ReturnWrapperT< ReturnT > apply( FuncT func, std::string const & name + , DerivT const & pa ) + { + auto & writer = sdw::findWriterMandat( pa ); + auto function = writer.template implementFunction< ReturnT >( name + , [&writer, func]( DerivT const & a ) + { + auto a00 = writer.declLocale( "a00", a.value() ); + auto a10 = writer.declLocale( "a10", a.value() + a.dPdx() ); + auto a01 = writer.declLocale( "a01", a.value() + a.dPdy() ); + auto r00 = writer.declLocale( "r00", func( a00 ) ); + auto r10 = writer.declLocale( "r10", func( a10 ) ); + auto r01 = writer.declLocale( "r01", func( a01 ) ); + writer.returnStmt( ReturnT{ r00, r10 - r00, r01 - r00 } ); + } + , sdw::InParam< DerivT >{ writer, "a" } ); + return function( pa ); + } + + template< typename ReturnT, typename FuncT, typename DerivT > + sdw::ReturnWrapperT< ReturnT > apply( FuncT func, std::string const & name + , DerivT const & pa, DerivT const & pb ) + { + auto & writer = sdw::findWriterMandat( pa, pb ); + auto function = writer.template implementFunction< ReturnT >( name + , [&writer, func]( DerivT const & a + , DerivT const & b ) + { + auto a00 = writer.declLocale( "a00", a.value() ); + auto a10 = writer.declLocale( "a10", a.value() + a.dPdx() ); + auto a01 = writer.declLocale( "a01", a.value() + a.dPdy() ); + auto b00 = writer.declLocale( "b00", b.value() ); + auto b10 = writer.declLocale( "b10", b.value() + b.dPdx() ); + auto b01 = writer.declLocale( "b01", b.value() + b.dPdy() ); + auto r00 = writer.declLocale( "r00", func( a00, b00 ) ); + auto r10 = writer.declLocale( "r10", func( a10, b10 ) ); + auto r01 = writer.declLocale( "r01", func( a01, b01 ) ); + writer.returnStmt( ReturnT{ r00, r10 - r00, r01 - r00 } ); + } + , sdw::InParam< DerivT >{ writer, "a" } + , sdw::InParam< DerivT >{ writer, "b" } ); + return function( pa, pb ); + } + + template< typename ReturnT, typename FuncT, typename DerivT > + sdw::ReturnWrapperT< ReturnT > apply( FuncT func, std::string const & name + , DerivT const & pa, DerivT const & pb, DerivT const & pc ) + { + auto & writer = sdw::findWriterMandat( pa, pb, pc ); + auto function = writer.template implementFunction< ReturnT >( name + , [&writer, func]( DerivT const & a + , DerivT const & b + , DerivT const & c ) + { + auto a00 = writer.declLocale( "a00", a.value() ); + auto a10 = writer.declLocale( "a10", a.value() + a.dPdx() ); + auto a01 = writer.declLocale( "a01", a.value() + a.dPdy() ); + auto b00 = writer.declLocale( "b00", b.value() ); + auto b10 = writer.declLocale( "b10", b.value() + b.dPdx() ); + auto b01 = writer.declLocale( "b01", b.value() + b.dPdy() ); + auto c00 = writer.declLocale( "c00", c.value() ); + auto c10 = writer.declLocale( "c10", c.value() + c.dPdx() ); + auto c01 = writer.declLocale( "c01", c.value() + c.dPdy() ); + auto r00 = writer.declLocale( "r00", func( a00, b00, c00 ) ); + auto r10 = writer.declLocale( "r10", func( a10, b10, c10 ) ); + auto r01 = writer.declLocale( "r01", func( a01, b01, c01 ) ); + writer.returnStmt( ReturnT{ r00, r10 - r00, r01 - r00 } ); + } + , sdw::InParam< DerivT >{ writer, "a" } + , sdw::InParam< DerivT >{ writer, "b" } + , sdw::InParam< DerivT >{ writer, "c" } ); + return function( pa, pb, pc ); + } + + template< typename ReturnT, typename FuncT, typename DerivT > + sdw::ReturnWrapperT< ReturnT > apply( FuncT func, std::string const & name + , DerivT const & pa, DerivT const & pb, sdw::Float const & pc ) + { + auto & writer = sdw::findWriterMandat( pa, pb, pc ); + auto function = writer.template implementFunction< ReturnT >( name + , [&writer, func]( DerivT const & a + , DerivT const & b + , sdw::Float const & c ) + { + auto a00 = writer.declLocale( "a00", a.value() ); + auto a10 = writer.declLocale( "a10", a.value() + a.dPdx() ); + auto a01 = writer.declLocale( "a01", a.value() + a.dPdy() ); + auto b00 = writer.declLocale( "b00", b.value() ); + auto b10 = writer.declLocale( "b10", b.value() + b.dPdx() ); + auto b01 = writer.declLocale( "b01", b.value() + b.dPdy() ); + auto r00 = writer.declLocale( "r00", func( a00, b00, c ) ); + auto r10 = writer.declLocale( "r10", func( a10, b10, c ) ); + auto r01 = writer.declLocale( "r01", func( a01, b01, c ) ); + writer.returnStmt( ReturnT{ r00, r10 - r00, r01 - r00 } ); + } + , sdw::InParam< DerivT >{ writer, "a" } + , sdw::InParam< DerivT >{ writer, "b" } + , sdw::InParam< sdw::Float >{ writer, "c" } ); + return function( pa, pb, pc ); + } + + template< typename ReturnT, typename FuncT, typename DerivT > + sdw::ReturnWrapperT< ReturnT > apply( FuncT func, std::string const & name + , DerivT const & pa, sdw::Float const & pb, sdw::Float const & pc ) + { + auto & writer = sdw::findWriterMandat( pa, pb, pc ); + auto function = writer.template implementFunction< ReturnT >( name + , [&writer, func]( DerivT const & a + , sdw::Float const & b + , sdw::Float const & c ) + { + auto a00 = writer.declLocale( "a00", a.value() ); + auto a10 = writer.declLocale( "a10", a.value() + a.dPdx() ); + auto a01 = writer.declLocale( "a01", a.value() + a.dPdy() ); + auto r00 = writer.declLocale( "r00", func( a00, b, c ) ); + auto r10 = writer.declLocale( "r10", func( a10, b, c ) ); + auto r01 = writer.declLocale( "r01", func( a01, b, c ) ); + writer.returnStmt( ReturnT{ r00, r10 - r00, r01 - r00 } ); + } + , sdw::InParam< DerivT >{ writer, "a" } + , sdw::InParam< sdw::Float >{ writer, "b" } + , sdw::InParam< sdw::Float >{ writer, "c" } ); + return function( pa, pb, pc ); + } + + template< typename FuncT, typename ValueT, typename ValueU, sdw::StringLiteralT StructNameT > + DerivativeValueT< ValueU, StructNameT > applyOp( FuncT func, std::string const & name + , ValueT const & pa, DerivativeValueT< ValueU, StructNameT > const & pb ) + { + auto & writer = sdw::findWriterMandat( pa, pb ); + auto function = writer.template implementFunction< DerivativeValueT< ValueU, StructNameT > >( name + , [&writer, func]( ValueT const & a + , DerivativeValueT< ValueU, StructNameT > const & b ) + { + auto b00 = writer.declLocale( "a00", b.value() ); + auto b10 = writer.declLocale( "a10", b.value() + b.dPdx() ); + auto b01 = writer.declLocale( "a01", b.value() + b.dPdy() ); + auto r00 = writer.declLocale( "r00", func( a, b00 ) ); + auto r10 = writer.declLocale( "r10", func( a, b10 ) ); + auto r01 = writer.declLocale( "r01", func( a, b01 ) ); + writer.returnStmt( DerivativeValueT< ValueU, StructNameT >{ r00, r10 - r00, r01 - r00 } ); + } + , sdw::InParam< ValueT >{ writer, "a" } + , sdw::InParam< DerivativeValueT< ValueU, StructNameT > >{ writer, "b" } ); + return function( pa, pb ); + } + + template< typename FuncT, typename ValueT, sdw::StringLiteralT StructNameT > + DerivativeValueT< ValueT, StructNameT > applyOp( FuncT func, std::string const & name + , DerivativeValueT< ValueT, StructNameT > const & pa, ValueT const & pb ) + { + auto & writer = sdw::findWriterMandat( pa, pb ); + auto function = writer.template implementFunction< DerivativeValueT< ValueT, StructNameT > >( name + , [&writer, func]( DerivativeValueT< ValueT, StructNameT > const & a + , ValueT const & b ) + { + auto a00 = writer.declLocale( "a00", a.value() ); + auto a10 = writer.declLocale( "a10", a.value() + a.dPdx() ); + auto a01 = writer.declLocale( "a01", a.value() + a.dPdy() ); + auto r00 = writer.declLocale( "r00", func( a00, b ) ); + auto r10 = writer.declLocale( "r10", func( a10, b ) ); + auto r01 = writer.declLocale( "r01", func( a01, b ) ); + writer.returnStmt( DerivativeValueT< ValueT, StructNameT >{ r00, r10 - r00, r01 - r00 } ); + } + , sdw::InParam< DerivativeValueT< ValueT, StructNameT > >{ writer, "a" } + , sdw::InParam< ValueT >{ writer, "b" } ); + return function( pa, pb ); + } + + template< typename FuncT, typename ValueT, sdw::StringLiteralT StructNameT > + DerivativeValueT< ValueT, StructNameT > applyOp( FuncT func, std::string const & name + , DerivativeValueT< ValueT, StructNameT > const & pa, DerivativeValueT< ValueT, StructNameT > const & pb ) + { + auto & writer = sdw::findWriterMandat( pa, pb ); + auto function = writer.template implementFunction< DerivativeValueT< ValueT, StructNameT > >( name + , [&writer, func]( DerivativeValueT< ValueT, StructNameT > const & a + , DerivativeValueT< ValueT, StructNameT > const & b ) + { + auto a00 = writer.declLocale( "a00", a.value() ); + auto a10 = writer.declLocale( "a10", a.value() + a.dPdx() ); + auto a01 = writer.declLocale( "a01", a.value() + a.dPdy() ); + auto b00 = writer.declLocale( "b00", b.value() ); + auto b10 = writer.declLocale( "b10", b.value() + b.dPdx() ); + auto b01 = writer.declLocale( "b01", b.value() + b.dPdy() ); + auto r00 = writer.declLocale( "r00", func( a00, b00 ) ); + auto r10 = writer.declLocale( "r10", func( a10, b10 ) ); + auto r01 = writer.declLocale( "r01", func( a01, b01 ) ); + writer.returnStmt( DerivativeValueT< ValueT, StructNameT >{ r00, r10 - r00, r01 - r00 } ); + } + , sdw::InParam< DerivativeValueT< ValueT, StructNameT > >{ writer, "a" } + , sdw::InParam< DerivativeValueT< ValueT, StructNameT > >{ writer, "b" } ); + return function( pa, pb ); + } + + template< typename ReturnT, typename FuncT, typename ValueT, sdw::StringLiteralT StructNameT > + sdw::ReturnWrapperT< ReturnT > applyMbrSel( FuncT func, std::string const & name + , DerivativeValueT< ValueT, StructNameT > const & pa ) + { + auto & writer = sdw::findWriterMandat( pa ); + auto function = writer.template implementFunction< ReturnT >( name + , [&writer, func]( DerivativeValueT< ValueT, StructNameT > const & a ) + { + writer.returnStmt( ReturnT{ ( a.value().*func )() + , ( a.dPdx().*func )() + , ( a.dPdy().*func )() } ); + } + , sdw::InParam< DerivativeValueT< ValueT, StructNameT > >{ writer, "a" } ); + return function( pa ); + } + + template< typename ReturnT, typename FuncT, typename ValueT, sdw::StringLiteralT StructNameT > + sdw::ReturnWrapperT< ReturnT > applySel( FuncT func, std::string const & name + , DerivativeValueT< ValueT, StructNameT > const & pa ) + { + auto & writer = sdw::findWriterMandat( pa ); + auto function = writer.template implementFunction< ReturnT >( name + , [&writer, func]( DerivativeValueT< ValueT, StructNameT > const & a ) + { + writer.returnStmt( ReturnT{ func( a.value() ) + , func( a.dPdx() ) + , func( a.dPdy() ) } ); + } + , sdw::InParam< DerivativeValueT< ValueT, StructNameT > >{ writer, "a" } ); + return function( pa ); + } + } + + //********************************************************************************************* + + sdw::expr::ExprPtr makeRawExpr( DerivFloat const & value ) + { + return sdw::makeExpr( value.value() ); + } + + sdw::expr::ExprPtr makeRawExpr( DerivVec2 const & value ) + { + return sdw::makeExpr( value.value() ); + } + + sdw::expr::ExprPtr makeRawExpr( DerivVec3 const & value ) + { + return sdw::makeExpr( value.value() ); + } + + sdw::expr::ExprPtr makeRawExpr( DerivVec4 const & value ) + { + return sdw::makeExpr( value.value() ); + } + + RetDerivFloat dot( DerivVec3 const x, DerivVec3 const y ) + { + using Func = sdw::RetFloat( * )( sdw::Vec3 const, sdw::Vec3 const ); + return deriv::apply< DerivFloat, Func >( sdw::dot, "derivDot3", x, y ); + } + + RetDerivVec3 cross( DerivVec3 const x, DerivVec3 const y ) + { + using Func = sdw::RetVec3( * )( sdw::Vec3 const, sdw::Vec3 const ); + return deriv::apply< DerivVec3, Func >( sdw::cross, "derivCross3", x, y ); + } + + RetDerivVec3 normalize( DerivVec3 const v ) + { + using Func = sdw::RetVec3( * )( sdw::Vec3 const ); + return deriv::apply< DerivVec3, Func >( sdw::normalize, "derivNormalize3", v ); + } + + RetDerivVec4 normalize( DerivVec4 const v ) + { + using Func = sdw::RetVec4( * )( sdw::Vec4 const ); + return deriv::apply< DerivVec4, Func >( sdw::normalize, "derivNormalize4", v ); + } + + RetDerivVec3 refract( DerivVec3 const i, DerivVec3 const n, sdw::Float const ior ) + { + using Func = sdw::RetVec3( * )( sdw::Vec3 const, sdw::Vec3 const, sdw::Float const ); + return deriv::apply< DerivVec3, Func >( sdw::refract, "derivRefract3", i, n, ior ); + } + + RetDerivFloat clamp( DerivFloat const v, sdw::Float const min, sdw::Float const max ) + { + using Func = sdw::RetFloat( * )( sdw::Float const, sdw::Float const, sdw::Float const ); + return deriv::apply< DerivFloat, Func >( sdw::clamp, "derivClamp1", v, min, max ); + } + + RetDerivFloat length( DerivVec3 const v ) + { + using Func = sdw::RetFloat( * )( sdw::Vec3 const ); + return deriv::apply< DerivFloat, Func >( sdw::length, "derivLength3", v ); + } + + RetDerivFloat max( DerivFloat const x, DerivFloat const y ) + { + using Func = sdw::RetFloat( * )( sdw::Float const, sdw::Float const ); + return deriv::apply< DerivFloat, Func >( sdw::max, "derivMax1", x, y ); + } + + RetDerivVec3 mix( DerivVec3 const a, DerivVec3 const b, DerivVec3 const c ) + { + using Func = sdw::RetVec3( * )( sdw::Vec3 const, sdw::Vec3 const, sdw::Vec3 const ); + return deriv::apply< DerivVec3, Func >( sdw::mix, "derivMix3", a, b, c ); + } + + RetDerivFloat fma( DerivFloat const a, DerivFloat const b, DerivFloat const c ) + { + using Func = sdw::RetFloat( * )( sdw::Float const, sdw::Float const, sdw::Float const ); + return deriv::apply< DerivFloat, Func >( sdw::fma, "derivFma1", a, b, c ); + } + + RetDerivVec2 fma( DerivVec2 const a, DerivVec2 const b, DerivVec2 const c ) + { + using Func = sdw::RetVec2( * )( sdw::Vec2 const, sdw::Vec2 const, sdw::Vec2 const ); + return deriv::apply< DerivVec2, Func >( sdw::fma, "derivFma2", a, b, c ); + } + + RetDerivVec3 fma( DerivVec3 const a, DerivVec3 const b, DerivVec3 const c ) + { + using Func = sdw::RetVec3( * )( sdw::Vec3 const, sdw::Vec3 const, sdw::Vec3 const ); + return deriv::apply< DerivVec3, Func >( sdw::fma, "derivFma3", a, b, c ); + } + + RetDerivVec4 fma( DerivVec4 const a, DerivVec4 const b, DerivVec4 const c ) + { + using Func = sdw::RetVec4( * )( sdw::Vec4 const, sdw::Vec4 const, sdw::Vec4 const ); + return deriv::apply< DerivVec4, Func >( sdw::fma, "derivFma4", a, b, c ); + } + + sdw::Float fwidth( DerivFloat const a ) + { + auto tmp = a.getWriter()->declLocale( "tmpFwidth1", a ); + return sdw::abs( tmp.dPdx() ) + sdw::abs( tmp.dPdy() ); + } + + sdw::Vec2 fwidth( DerivVec2 const a ) + { + auto tmp = a.getWriter()->declLocale( "tmpFwidth2", a ); + return sdw::abs( tmp.dPdx() ) + sdw::abs( tmp.dPdy() ); + } + + sdw::Vec3 fwidth( DerivVec3 const a ) + { + auto tmp = a.getWriter()->declLocale( "tmpFwidth3", a ); + return sdw::abs( tmp.dPdx() ) + sdw::abs( tmp.dPdy() ); + } + + sdw::Vec4 fwidth( DerivVec4 const a ) + { + auto tmp = a.getWriter()->declLocale( "tmpFwidth4", a ); + return sdw::abs( tmp.dPdx() ) + sdw::abs( tmp.dPdy() ); + } + + DerivFloat negate( DerivFloat const a ) + { + using Func = sdw::Float ( sdw::Float::* )()const; + return deriv::applyMbr< DerivFloat, Func >( &sdw::Float::operator-, "derivNegate1", a ); + } + + DerivVec2 negate( DerivVec2 const a ) + { + using Func = sdw::Vec2( sdw::Vec2::* )( )const; + return deriv::applyMbr< DerivVec2, Func >( &sdw::Vec2::operator-, "derivNegate2", a ); + } + + DerivVec3 negate( DerivVec3 const a ) + { + using Func = sdw::Vec3( sdw::Vec3::* )( )const; + return deriv::applyMbr< DerivVec3, Func >( &sdw::Vec3::operator-, "derivNegate3", a ); + } + + DerivVec4 negate( DerivVec4 const a ) + { + using Func = sdw::Vec4( sdw::Vec4::* )( )const; + return deriv::applyMbr< DerivVec4, Func >( &sdw::Vec4::operator-, "derivNegate4", a ); + } + + sdw::Float computeMip( DerivVec2 const & uv + , sdw::Vec2 const & texSize ) + { + // see https://registry.khronos.org/OpenGL/extensions/EXT/EXT_shader_texture_lod.txt + auto dSdx = uv.dPdx().x(); + auto dSdy = uv.dPdy().x(); + auto dTdx = uv.dPdx().y(); + auto dTdy = uv.dPdy().y(); + auto dUdx = texSize.x() * dSdx; + auto dUdy = texSize.x() * dSdy; + auto dVdx = texSize.y() * dTdx; + auto dVdy = texSize.y() * dTdy; + return 0.5_f * log2( max( dUdx * dUdx + dVdx * dVdx + , dUdy * dUdy + dVdy * dVdy ) ); + } + + DerivFloat derivFloat( sdw::Float const v ) + { + return { v, 0.0_f, 0.0_f }; + } + + DerivFloat derivX( DerivVec2 const v ) + { + using Func = sdw::Float( sdw::Vec2::* )( )const; + return deriv::applyMbrSel< DerivFloat, Func >( &sdw::Vec2::x, "derivDerivX2", v ); + } + + DerivFloat derivX( DerivVec3 const v ) + { + using Func = sdw::Float( sdw::Vec3::* )( )const; + return deriv::applyMbrSel< DerivFloat, Func >( &sdw::Vec3::x, "derivDerivX3", v ); + } + + DerivFloat derivX( DerivVec4 const v ) + { + using Func = sdw::Float( sdw::Vec4::* )( )const; + return deriv::applyMbrSel< DerivFloat, Func >( &sdw::Vec4::x, "derivDerivX4", v ); + } + + DerivFloat derivY( DerivVec2 const v ) + { + using Func = sdw::Float( sdw::Vec2::* )( )const; + return deriv::applyMbrSel< DerivFloat, Func >( &sdw::Vec2::y, "derivDerivY2", v ); + } + + DerivFloat derivY( DerivVec3 const v ) + { + using Func = sdw::Float( sdw::Vec3::* )( )const; + return deriv::applyMbrSel< DerivFloat, Func >( &sdw::Vec3::y, "derivDerivY3", v ); + } + + DerivFloat derivY( DerivVec4 const v ) + { + using Func = sdw::Float( sdw::Vec4::* )( )const; + return deriv::applyMbrSel< DerivFloat, Func >( &sdw::Vec4::y, "derivDerivY4", v ); + } + + DerivFloat derivZ( DerivVec3 const v ) + { + using Func = sdw::Float( sdw::Vec3::* )( )const; + return deriv::applyMbrSel< DerivFloat, Func >( &sdw::Vec3::z, "derivDerivZ3", v ); + } + + DerivFloat derivZ( DerivVec4 const v ) + { + using Func = sdw::Float( sdw::Vec4::* )( )const; + return deriv::applyMbrSel< DerivFloat, Func >( &sdw::Vec4::z, "derivDerivZ4", v ); + } + + DerivFloat derivW( DerivVec4 const v ) + { + using Func = sdw::Float( sdw::Vec4::* )( )const; + return deriv::applyMbrSel< DerivFloat, Func >( &sdw::Vec4::w, "derivDerivW4", v ); + } + + DerivVec2 derivVec2( sdw::Float const v ) + { + return { vec2( v ), vec2( 0.0_f ), vec2( 0.0_f ) }; + } + + DerivVec2 derivVec2( sdw::Vec2 const v ) + { + return { v, vec2( 0.0_f ), vec2( 0.0_f ) }; + } + + DerivVec2 derivVec2( DerivFloat const v ) + { + auto tmp = v.getWriter()->declLocale( "tmpVDerivVec21", v ); + return { vec2( tmp.value() ), vec2( tmp.dPdx() ), vec2( tmp.dPdy() ) }; + } + + DerivVec2 derivVec2( DerivVec3 const v ) + { + auto tmp = v.getWriter()->declLocale( "tmpVDerivVec23", v ); + return { tmp.value().xy(), tmp.dPdx().xy(), tmp.dPdy().xy() }; + } + + DerivVec2 derivVec2( DerivVec4 const v ) + { + auto tmp = v.getWriter()->declLocale( "tmpVDerivVec24", v ); + return { tmp.value().xy(), tmp.dPdx().xy(), tmp.dPdy().xy() }; + } + + DerivVec2 derivVec2( DerivFloat const v, sdw::Float const a ) + { + auto tmp = v.getWriter()->declLocale( "tmpVDerivVec211", v ); + return { vec2( tmp.value(), a ), vec2( tmp.dPdx(), 0.0_f ), vec2( tmp.dPdy(), 0.0_f ) }; + } + + DerivVec3 derivVec3( sdw::Float const v ) + { + return { vec3( v ), vec3( 0.0_f ), vec3( 0.0_f ) }; + } + + DerivVec3 derivVec3( sdw::Vec3 const v ) + { + return { v, vec3( 0.0_f ), vec3( 0.0_f ) }; + } + + DerivVec3 derivVec3( DerivFloat const v ) + { + auto tmp = v.getWriter()->declLocale( "tmpVDerivVec31", v ); + return { vec3( tmp.value() ), vec3( tmp.dPdx() ), vec3( tmp.dPdy() ) }; + } + + DerivVec3 derivVec3( DerivVec4 const v ) + { + auto tmp = v.getWriter()->declLocale( "tmpVDerivVec34", v ); + return { tmp.value().xyz(), tmp.dPdx().xyz(), tmp.dPdy().xyz() }; + } + + DerivVec4 derivVec4( sdw::Float const v ) + { + return { vec4( v ), vec4( 0.0_f ), vec4( 0.0_f ) }; + } + + DerivVec4 derivVec4( sdw::Vec4 const v ) + { + return { v, vec4( 0.0_f ), vec4( 0.0_f ) }; + } + + DerivVec4 derivVec4( DerivFloat const v ) + { + auto tmp = v.getWriter()->declLocale( "tmpVDerivVec41", v ); + return { vec4( tmp.value() ), vec4( tmp.dPdx() ), vec4( tmp.dPdy() ) }; + } + + DerivVec4 derivVec4( DerivVec3 const v, sdw::Float const a ) + { + auto tmp = v.getWriter()->declLocale( "tmpVDerivVec43N1", v ); + return { vec4( tmp.value(), a ), vec4( tmp.dPdx(), 0.0_f ), vec4( tmp.dPdy(), 0.0_f ) }; + } + + DerivVec4 derivVec4( DerivVec3 const v, DerivFloat const a ) + { + auto tmpV = v.getWriter()->declLocale( "tmpVDerivVec43D1", v ); + auto tmpA = v.getWriter()->declLocale( "tmpADerivVec43D1", a ); + return { vec4( tmpV.value(), tmpA.value() ), vec4( tmpV.dPdx(), tmpA.dPdx() ), vec4( tmpV.dPdy(), tmpA.dPdy() ) }; + } + + void negateXYZ( sdw::Vec4 in ) + { + in.xyz() = -in.xyz(); + } + + void negateXYZ( DerivVec4 in ) + { + auto tmp = in.getWriter()->declLocale( "tmpNegateXYZ", in ); + negateXYZ( tmp.value() ); + negateXYZ( tmp.dPdx() ); + negateXYZ( tmp.dPdy() ); + in = tmp; + } + + void mulXY( sdw::Vec4 in, sdw::Vec2 const mul ) + { + in.xy() *= mul; + } + + void mulXY( DerivVec4 in, sdw::Vec2 const mul ) + { + auto tmp = in.getWriter()->declLocale( "tmpMulXY", in ); + mulXY( tmp.value(), mul ); + mulXY( tmp.dPdx(), mul ); + mulXY( tmp.dPdy(), mul ); + in = tmp; + } + + void addXYZ( sdw::Vec4 in, sdw::Vec3 const add ) + { + in.xyz() += add; + } + + void addXYZ( DerivVec4 in, sdw::Vec3 const add ) + { + addXYZ( in.value(), add ); + } + + void addXYZ( DerivVec4 in, DerivVec3 const add ) + { + auto tmp = in.getWriter()->declLocale( "tmpAddXYZ", getXYZ( in ) ); + tmp += add; + in.value().xyz() = tmp.value(); + in.dPdx().xyz() = tmp.dPdx(); + in.dPdy().xyz() = tmp.dPdy(); + } + + sdw::Vec3 getRaw( sdw::Vec3 const in ) + { + return in; + } + + sdw::Vec3 getRaw( DerivVec3 const in ) + { + return getRaw( in.value() ); + } + + sdw::Vec4 getRaw( sdw::Vec4 const in ) + { + return in; + } + + sdw::Vec4 getRaw( DerivVec4 const in ) + { + return getRaw( in.value() ); + } + + sdw::Vec3 getRawXYZ( sdw::Vec3 const in ) + { + return in; + } + + sdw::Vec3 getRawXYZ( DerivVec3 const in ) + { + return getRawXYZ( in.value() ); + } + + sdw::Vec3 getRawXYZ( sdw::Vec4 const in ) + { + return in.xyz(); + } + + sdw::Vec3 getRawXYZ( DerivVec4 const in ) + { + return getRawXYZ( in.value() ); + } + + sdw::Vec3 getXYZ( sdw::Vec4 const in ) + { + return in.xyz(); + } + + DerivVec3 getXYZ( DerivVec4 const in ) + { + using Func = sdw::Vec3( * )( sdw::Vec4 const ); + return deriv::applySel< DerivVec3, Func >( getXYZ, "derivGetXYZ4", in ); + } + + sdw::Vec3 getXYW( sdw::Vec4 const in ) + { + return in.xyw(); + } + + DerivVec3 getXYW( DerivVec4 const in ) + { + using Func = sdw::Vec3( * )( sdw::Vec4 const ); + return deriv::applySel< DerivVec3, Func >( getXYW, "derivGetXYW4", in ); + } + + sdw::Float getW( sdw::Vec4 const in ) + { + return in.w(); + } + + DerivFloat getW( DerivVec4 const in ) + { + using Func = sdw::Float( * )( sdw::Vec4 const ); + return deriv::applySel< DerivFloat, Func >( getW, "derivGetW4", in ); + } + + DerivVec4 operator*( sdw::Mat4 const lhs, DerivVec4 const rhs ) + { + using Func = sdw::Vec4( * )( sdw::Mat4 const &, sdw::Vec4 const & ); + return deriv::applyOp< Func >( sdw::operator*, "derivMultiplayM4D4", lhs, rhs ); + } + + DerivVec3 operator*( sdw::Mat3 const lhs, DerivVec3 const rhs ) + { + using Func = sdw::Vec3( * )( sdw::Mat3 const &, sdw::Vec3 const & ); + return deriv::applyOp< Func >( sdw::operator*, "derivMultiplayM3D3", lhs, rhs ); + } + + DerivFloat operator+( DerivFloat const lhs, DerivFloat const rhs ) + { + using Func = sdw::Float( * )( sdw::Float const &, sdw::Float const & ); + return deriv::applyOp< Func >( sdw::operator+, "derivAdd1D1", lhs, rhs ); + } + + DerivFloat operator+( DerivFloat const lhs, sdw::Float const rhs ) + { + using Func = sdw::Float( * )( sdw::Float const &, sdw::Float const & ); + return deriv::applyOp< Func >( sdw::operator+, "derivAdd1N1", lhs, rhs ); + } + + DerivFloat operator-( DerivFloat const lhs, DerivFloat const rhs ) + { + using Func = sdw::Float( * )( sdw::Float const &, sdw::Float const & ); + return deriv::applyOp< Func >( sdw::operator-, "derivSubtract1D1", lhs, rhs ); + } + + DerivFloat operator-( DerivFloat const lhs, sdw::Float const rhs ) + { + using Func = sdw::Float( * )( sdw::Float const &, sdw::Float const & ); + return deriv::applyOp< Func >( sdw::operator-, "derivSubtract1N1", lhs, rhs ); + } + + DerivFloat operator*( DerivFloat const lhs, DerivFloat const rhs ) + { + using Func = sdw::Float( * )( sdw::Float const &, sdw::Float const & ); + return deriv::applyOp< Func >( sdw::operator*, "derivMultiply1D1", lhs, rhs ); + } + + DerivFloat operator*( DerivFloat const lhs, sdw::Float const rhs ) + { + using Func = sdw::Float( * )( sdw::Float const &, sdw::Float const & ); + return deriv::applyOp< Func >( sdw::operator*, "derivMultiply1N1", lhs, rhs ); + } + + DerivVec2 operator+( DerivVec2 const lhs, DerivVec2 const rhs ) + { + using Func = sdw::Vec2( * )( sdw::Vec2 const &, sdw::Vec2 const & ); + return deriv::applyOp< Func >( sdw::operator+, "derivAdd2D2", lhs, rhs ); + } + + DerivVec2 operator+( DerivVec2 const lhs, sdw::Vec2 const rhs ) + { + using Func = sdw::Vec2( * )( sdw::Vec2 const &, sdw::Vec2 const & ); + return deriv::applyOp< Func >( sdw::operator+, "derivAdd2N2", lhs, rhs ); + } + + DerivVec2 operator+( DerivVec2 const lhs, DerivFloat const rhs ) + { + return lhs + derivVec2( rhs ); + } + + DerivVec2 operator+( DerivVec2 const lhs, sdw::Float const rhs ) + { + return lhs + derivVec2( rhs ); + } + + DerivVec2 operator-( DerivVec2 const lhs, DerivVec2 const rhs ) + { + using Func = sdw::Vec2( * )( sdw::Vec2 const &, sdw::Vec2 const & ); + return deriv::applyOp< Func >( sdw::operator-, "derivSubtract2D2", lhs, rhs ); + } + + DerivVec2 operator-( DerivVec2 const lhs, sdw::Vec2 const rhs ) + { + using Func = sdw::Vec2( * )( sdw::Vec2 const &, sdw::Vec2 const & ); + return deriv::applyOp< Func >( sdw::operator-, "derivSubtract2N2", lhs, rhs ); + } + + DerivVec2 operator-( DerivVec2 const lhs, DerivFloat const rhs ) + { + return lhs - derivVec2( rhs ); + } + + DerivVec2 operator-( DerivVec2 const lhs, sdw::Float const rhs ) + { + return lhs - derivVec2( rhs ); + } + + DerivVec2 operator*( DerivVec2 const lhs, DerivVec2 const rhs ) + { + using Func = sdw::Vec2( * )( sdw::Vec2 const &, sdw::Vec2 const & ); + return deriv::applyOp< Func >( sdw::operator*, "derivMultiply2D2", lhs, rhs ); + } + + DerivVec2 operator*( DerivVec2 const lhs, sdw::Vec2 const rhs ) + { + using Func = sdw::Vec2( * )( sdw::Vec2 const &, sdw::Vec2 const & ); + return deriv::applyOp< Func >( sdw::operator*, "derivMultiply2N2", lhs, rhs ); + } + + DerivVec2 operator*( DerivVec2 const lhs, DerivFloat const rhs ) + { + return lhs * derivVec2( rhs ); + } + + DerivVec2 operator*( DerivVec2 const lhs, sdw::Float const rhs ) + { + return lhs * derivVec2( rhs ); + } + + DerivVec3 operator+( DerivVec3 const lhs, DerivVec3 const rhs ) + { + using Func = sdw::Vec3( * )( sdw::Vec3 const &, sdw::Vec3 const & ); + return deriv::applyOp< Func >( sdw::operator+, "derivAdd3D3", lhs, rhs ); + } + + DerivVec3 operator+( DerivVec3 const lhs, sdw::Vec3 const rhs ) + { + using Func = sdw::Vec3( * )( sdw::Vec3 const &, sdw::Vec3 const & ); + return deriv::applyOp< Func >( sdw::operator+, "derivAdd3N3", lhs, rhs ); + } + + DerivVec3 operator+( DerivVec3 const lhs, DerivFloat const rhs ) + { + return lhs + derivVec3( rhs ); + } + + DerivVec3 operator+( DerivVec3 const lhs, sdw::Float const rhs ) + { + return lhs + derivVec3( rhs ); + } + + DerivVec3 operator-( DerivVec3 const lhs, DerivVec3 const rhs ) + { + using Func = sdw::Vec3( * )( sdw::Vec3 const &, sdw::Vec3 const & ); + return deriv::applyOp< Func >( sdw::operator-, "derivSubtract3D3", lhs, rhs ); + } + + DerivVec3 operator-( DerivVec3 const lhs, sdw::Vec3 const rhs ) + { + using Func = sdw::Vec3( * )( sdw::Vec3 const &, sdw::Vec3 const & ); + return deriv::applyOp< Func >( sdw::operator-, "derivSubtract3N3", lhs, rhs ); + } + + DerivVec3 operator-( DerivVec3 const lhs, DerivFloat const rhs ) + { + return lhs - derivVec3( rhs ); + } + + DerivVec3 operator-( DerivVec3 const lhs, sdw::Float const rhs ) + { + return lhs - derivVec3( rhs ); + } + + DerivVec3 operator*( DerivVec3 const lhs, DerivVec3 const rhs ) + { + using Func = sdw::Vec3( * )( sdw::Vec3 const &, sdw::Vec3 const & ); + return deriv::applyOp< Func >( sdw::operator*, "derivMultiply3D3", lhs, rhs ); + } + + DerivVec3 operator*( DerivVec3 const lhs, sdw::Vec3 const rhs ) + { + using Func = sdw::Vec3( * )( sdw::Vec3 const &, sdw::Vec3 const & ); + return deriv::applyOp< Func >( sdw::operator*, "derivMultiply3N3", lhs, rhs ); + } + + DerivVec3 operator*( DerivVec3 const lhs, DerivFloat const rhs ) + { + return lhs * derivVec3( rhs ); + } + + DerivVec3 operator*( DerivVec3 const lhs, sdw::Float const rhs ) + { + return lhs * derivVec3( rhs ); + } + + DerivVec4 operator+( DerivVec4 const lhs, DerivVec4 const rhs ) + { + using Func = sdw::Vec4( * )( sdw::Vec4 const &, sdw::Vec4 const & ); + return deriv::applyOp< Func >( sdw::operator+, "derivAdd4D4", lhs, rhs ); + } + + DerivVec4 operator+( DerivVec4 const lhs, sdw::Vec4 const rhs ) + { + using Func = sdw::Vec4( * )( sdw::Vec4 const &, sdw::Vec4 const & ); + return deriv::applyOp< Func >( sdw::operator+, "derivAdd4N4", lhs, rhs ); + } + + DerivVec4 operator+( DerivVec4 const lhs, DerivFloat const rhs ) + { + return lhs + derivVec4( rhs ); + } + + DerivVec4 operator+( DerivVec4 const lhs, sdw::Float const rhs ) + { + return lhs + derivVec4( rhs ); + } + + DerivVec4 operator-( DerivVec4 const lhs, DerivVec4 const rhs ) + { + using Func = sdw::Vec4( * )( sdw::Vec4 const &, sdw::Vec4 const & ); + return deriv::applyOp< Func >( sdw::operator-, "derivSubtract4D4", lhs, rhs ); + } + + DerivVec4 operator-( DerivVec4 const lhs, sdw::Vec4 const rhs ) + { + using Func = sdw::Vec4( * )( sdw::Vec4 const &, sdw::Vec4 const & ); + return deriv::applyOp< Func >( sdw::operator-, "derivSubtract4N4", lhs, rhs ); + } + + DerivVec4 operator-( DerivVec4 const lhs, DerivFloat const rhs ) + { + return lhs - derivVec4( rhs ); + } + + DerivVec4 operator-( DerivVec4 const lhs, sdw::Float const rhs ) + { + return lhs - derivVec4( rhs ); + } + + DerivVec4 operator*( DerivVec4 const lhs, DerivVec4 const rhs ) + { + using Func = sdw::Vec4( * )( sdw::Vec4 const &, sdw::Vec4 const & ); + return deriv::applyOp< Func >( sdw::operator*, "derivMultiply4D4", lhs, rhs ); + } + + DerivVec4 operator*( DerivVec4 const lhs, sdw::Vec4 const rhs ) + { + using Func = sdw::Vec4( * )( sdw::Vec4 const &, sdw::Vec4 const & ); + return deriv::applyOp< Func >( sdw::operator*, "derivMultiply4N4", lhs, rhs ); + } + + DerivVec4 operator*( DerivVec4 const lhs, DerivFloat const rhs ) + { + return lhs * derivVec4( rhs ); + } + + DerivVec4 operator*( DerivVec4 const lhs, sdw::Float const rhs ) + { + return lhs * derivVec4( rhs ); + } + + //********************************************************************************************* +} diff --git a/source/Core/Castor3D/Shader/Shaders/GlslGlobalIllumination.cpp b/source/Core/Castor3D/Shader/Shaders/GlslGlobalIllumination.cpp index c8e501a2ec..347e359d91 100644 --- a/source/Core/Castor3D/Shader/Shaders/GlslGlobalIllumination.cpp +++ b/source/Core/Castor3D/Shader/Shaders/GlslGlobalIllumination.cpp @@ -97,7 +97,7 @@ namespace castor3d indirectLighting.diffuseColour() = ( hasDiffuseGI ? cookTorrance.computeDiffuse( normalize( indirectLighting.diffuseColour() ) , length( indirectLighting.diffuseColour() ) - , lightSurface.difF() ) + , lightSurface.difF().value() ) : vec3( 0.0_f ) ); debugOutput.registerOutput( cuT( "Indirect" ), cuT( "Diffuse" ), indirectLighting.diffuseColour() ); } @@ -202,8 +202,8 @@ namespace castor3d , indirectLighting.diffuseBlend() , voxelData ); auto envBRDF = m_writer.declLocale( "envBRDF" - , brdfMap.lod( vec2( lightSurface.NdotV(), roughness ), 0.0_f ) ); - indirectLighting.specular() *= sdw::fma( m_utils.conductorFresnel( lightSurface.NdotV(), indirectLighting.specular() ) + , brdfMap.lod( vec2( lightSurface.NdotV().value(), roughness ), 0.0_f ) ); + indirectLighting.specular() *= sdw::fma( m_utils.conductorFresnel( lightSurface.NdotV().value(), indirectLighting.specular() ) , vec3( envBRDF.x() ) , vec3( envBRDF.y() ) ); } @@ -286,8 +286,8 @@ namespace castor3d , VoxelData const & voxelData ) { return traceConeRadiance( voxels - , lightSurface.N() - , lightSurface.worldPosition().xyz() + , lightSurface.N().value() + , lightSurface.worldPosition().value().xyz() , voxelData ); } @@ -462,7 +462,7 @@ namespace castor3d FI auto vxlPosition = m_writer.declLocale( "vxlPosition" - , clamp( abs( voxelData.worldToClip( lightSurface.worldPosition().xyz() ) ), vec3( -1.0_f ), vec3( 1.0_f ) ) ); + , clamp( abs( voxelData.worldToClip( lightSurface.worldPosition().value().xyz() ) ), vec3( -1.0_f ), vec3( 1.0_f ) ) ); auto vxlBlend = m_writer.declLocale( "vxlBlend" , 1.0_f - pow( max( vxlPosition.x(), max( vxlPosition.y(), vxlPosition.z() ) ), 4.0_f ) ); return vec4( mix( vec3( 0.0_f ) @@ -506,8 +506,8 @@ namespace castor3d , LpvGridData lpvGridData ) { CU_Require( m_computeLPVRadiance ); - return m_computeLPVRadiance( lightSurface.N() - , lightSurface.worldPosition().xyz() + return m_computeLPVRadiance( lightSurface.N().value() + , lightSurface.worldPosition().value().xyz() , lpvGridData ); } @@ -515,8 +515,8 @@ namespace castor3d , LayeredLpvGridData llpvGridData ) { CU_Require( m_computeLLPVRadiance ); - return m_computeLLPVRadiance( lightSurface.N() - , lightSurface.worldPosition().xyz() + return m_computeLLPVRadiance( lightSurface.N().value() + , lightSurface.worldPosition().value().xyz() , llpvGridData ); } @@ -638,9 +638,9 @@ namespace castor3d } return m_traceConeReflection( pvoxels - , plightSurface.N() - , plightSurface.worldPosition().xyz() - , plightSurface.V() + , plightSurface.N().value() + , plightSurface.worldPosition().value().xyz() + , plightSurface.V().value() , proughness , pvoxelData ); } @@ -710,9 +710,9 @@ namespace castor3d } return m_traceConeOcclusion( pvoxels - , plightSurface.N() - , plightSurface.worldPosition().xyz() - , plightSurface.L() + , plightSurface.N().value() + , plightSurface.worldPosition().value().xyz() + , plightSurface.L().value() , pvoxelData ); } } diff --git a/source/Core/Castor3D/Shader/Shaders/GlslLight.cpp b/source/Core/Castor3D/Shader/Shaders/GlslLight.cpp index 1e39dde929..723940d520 100644 --- a/source/Core/Castor3D/Shader/Shaders/GlslLight.cpp +++ b/source/Core/Castor3D/Shader/Shaders/GlslLight.cpp @@ -220,6 +220,7 @@ namespace castor3d::shader , m_shadowModel{ castor::makeUnique< Shadow >( shadowOptions, m_writer ) } , m_sssTransmittance{ ( ( sssProfiles && sssProfiles->isEnabled() ) ? castor::makeUnique< SssTransmittance >( m_writer + , *m_shadowModel , castor::move( shadowOptions ) , *sssProfiles ) : nullptr ) } diff --git a/source/Core/Castor3D/Shader/Shaders/GlslLightSurface.cpp b/source/Core/Castor3D/Shader/Shaders/GlslLightSurface.cpp index df1f5aa7f1..9ee226ce44 100644 --- a/source/Core/Castor3D/Shader/Shaders/GlslLightSurface.cpp +++ b/source/Core/Castor3D/Shader/Shaders/GlslLightSurface.cpp @@ -12,31 +12,31 @@ namespace castor3d::shader , bool enabled ) : StructInstance{ writer, castor::move( expr ), enabled } , m_eyePosition{ getMember< sdw::Vec3 >( "eyePosition" ) } - , m_worldPosition{ getMember< sdw::Vec4 >( "worldPosition" ) } - , m_viewPosition{ getMember< sdw::Vec3 >( "viewPosition" ) } + , m_worldPosition{ getMember< DerivVec4 >( "worldPosition" ) } + , m_viewPosition{ getMember< DerivVec3 >( "viewPosition" ) } , m_clipPosition{ getMember< sdw::Vec3 >( "clipPosition" ) } - , m_vertexToLight{ getMember< sdw::Vec3 >( "vertexToLight" ) } - , m_V{ getMember< sdw::Vec3 >( "V" ) } - , m_N{ getMember< sdw::Vec3 >( "N" ) } - , m_L{ getMember< sdw::Vec3 >( "L" ) } - , m_H{ getMember< sdw::Vec3 >( "H" ) } - , m_lengthV{ getMember< sdw::Float >( "lengthV" ) } - , m_lengthL{ getMember< sdw::Float >( "lengthL" ) } - , m_NdotV{ getMember< sdw::Float >( "NdotV" ) } - , m_NdotL{ getMember< sdw::Float >( "NdotL", 0.0_f ) } - , m_NdotH{ getMember< sdw::Float >( "NdotH", 0.0_f ) } - , m_HdotV{ getMember< sdw::Float >( "HdotV", 0.0_f ) } - , m_F{ getMember< sdw::Vec3 >( "F", vec3( 0.0_f ) ) } - , m_spcF{ getMember< sdw::Vec3 >( "spcF", m_F ) } - , m_difF{ getMember< sdw::Vec3 >( "difF", m_F ) } + , m_vertexToLight{ getMember< DerivVec3 >( "vertexToLight" ) } + , m_V{ getMember< DerivVec3 >( "V" ) } + , m_N{ getMember< DerivVec3 >( "N" ) } + , m_L{ getMember< DerivVec3 >( "L" ) } + , m_H{ getMember< DerivVec3 >( "H" ) } + , m_lengthV{ getMember< DerivFloat >( "lengthV" ) } + , m_lengthL{ getMember< DerivFloat >( "lengthL" ) } + , m_NdotV{ getMember< DerivFloat >( "NdotV" ) } + , m_NdotL{ getMember< DerivFloat >( "NdotL", derivFloat( 0.0_f ) ) } + , m_NdotH{ getMember< DerivFloat >( "NdotH", derivFloat( 0.0_f ) ) } + , m_HdotV{ getMember< DerivFloat >( "HdotV", derivFloat( 0.0_f ) ) } + , m_F{ getMember< DerivVec3 >( "F", derivVec3( 0.0_f ) ) } + , m_spcF{ getMember< DerivVec3 >( "spcF", m_F ) } + , m_difF{ getMember< DerivVec3 >( "difF", m_F ) } { } LightSurface::LightSurface( sdw::Vec3 const eye - , sdw::Vec4 const world - , sdw::Vec3 const view + , DerivVec4 const world + , DerivVec3 const view , sdw::Vec3 const clip - , sdw::Vec3 const normal + , DerivVec3 const normal , bool enableDotProducts , bool enableFresnel , bool enableIridescence ) @@ -67,24 +67,24 @@ namespace castor3d::shader if ( type->empty() ) { - type->declMember( "eyePosition", ast::type::Kind::eVec3F, ast::type::NotArray ); - type->declMember( "worldPosition", ast::type::Kind::eVec4F, ast::type::NotArray ); - type->declMember( "viewPosition", ast::type::Kind::eVec3F, ast::type::NotArray ); - type->declMember( "clipPosition", ast::type::Kind::eVec3F, ast::type::NotArray ); - type->declMember( "vertexToLight", ast::type::Kind::eVec3F, ast::type::NotArray ); - type->declMember( "V", ast::type::Kind::eVec3F, ast::type::NotArray ); - type->declMember( "N", ast::type::Kind::eVec3F, ast::type::NotArray ); - type->declMember( "L", ast::type::Kind::eVec3F, ast::type::NotArray ); - type->declMember( "H", ast::type::Kind::eVec3F, ast::type::NotArray ); - type->declMember( "lengthV", ast::type::Kind::eFloat, ast::type::NotArray ); - type->declMember( "lengthL", ast::type::Kind::eFloat, ast::type::NotArray ); - type->declMember( "NdotV", ast::type::Kind::eFloat, ast::type::NotArray ); - type->declMember( "NdotL", ast::type::Kind::eFloat, ast::type::NotArray, enableDotProducts ); - type->declMember( "NdotH", ast::type::Kind::eFloat, ast::type::NotArray, enableDotProducts ); - type->declMember( "HdotV", ast::type::Kind::eFloat, ast::type::NotArray, enableDotProducts ); - type->declMember( "F", ast::type::Kind::eVec3F, ast::type::NotArray, enableFresnel ); - type->declMember( "spcF", ast::type::Kind::eVec3F, ast::type::NotArray, enableFresnel && enableIridescence ); - type->declMember( "difF", ast::type::Kind::eVec3F, ast::type::NotArray, enableFresnel && enableIridescence ); + type->declMember( "eyePosition", sdw::Vec3::makeType( cache ), ast::type::NotArray ); + type->declMember( "worldPosition", DerivVec4::makeType( cache ), ast::type::NotArray ); + type->declMember( "viewPosition", DerivVec3::makeType( cache ), ast::type::NotArray ); + type->declMember( "clipPosition", sdw::Vec3::makeType( cache ), ast::type::NotArray ); + type->declMember( "vertexToLight", DerivVec3::makeType( cache ), ast::type::NotArray ); + type->declMember( "V", DerivVec3::makeType( cache ), ast::type::NotArray ); + type->declMember( "N", DerivVec3::makeType( cache ), ast::type::NotArray ); + type->declMember( "L", DerivVec3::makeType( cache ), ast::type::NotArray ); + type->declMember( "H", DerivVec3::makeType( cache ), ast::type::NotArray ); + type->declMember( "lengthV", DerivFloat::makeType( cache ), ast::type::NotArray ); + type->declMember( "lengthL", DerivFloat::makeType( cache ), ast::type::NotArray ); + type->declMember( "NdotV", DerivFloat::makeType( cache ), ast::type::NotArray ); + type->declMember( "NdotL", DerivFloat::makeType( cache ), ast::type::NotArray, enableDotProducts ); + type->declMember( "NdotH", DerivFloat::makeType( cache ), ast::type::NotArray, enableDotProducts ); + type->declMember( "HdotV", DerivFloat::makeType( cache ), ast::type::NotArray, enableDotProducts ); + type->declMember( "F", DerivVec3::makeType( cache ), ast::type::NotArray, enableFresnel ); + type->declMember( "spcF", DerivVec3::makeType( cache ), ast::type::NotArray, enableFresnel && enableIridescence ); + type->declMember( "difF", DerivVec3::makeType( cache ), ast::type::NotArray, enableFresnel && enableIridescence ); } return type; @@ -93,10 +93,10 @@ namespace castor3d::shader LightSurface LightSurface::create( sdw::ShaderWriter & writer , castor::MbString const & name , sdw::Vec3 const eye - , sdw::Vec4 const world - , sdw::Vec3 const view + , DerivVec4 const world + , DerivVec3 const view , sdw::Vec3 const clip - , sdw::Vec3 const normal + , DerivVec3 const normal , bool enableDotProducts , bool enableFresnel , bool enableIridescence ) @@ -104,20 +104,20 @@ namespace castor3d::shader auto result = writer.declLocale< LightSurface >( name , LightSurface{ eye, world, view, clip, normal , enableDotProducts, enableFresnel, enableIridescence } ); - result.m_NdotV = max( 0.0_f, dot( result.N(), result.V() ) ); + result.m_NdotV = max( derivFloat( 0.0_f ), dot( result.N(), result.V() ) ); return result; } LightSurface LightSurface::create( sdw::ShaderWriter & writer , castor::MbString const & name - , sdw::Vec4 const world + , DerivVec4 const world , sdw::Vec3 const clip - , sdw::Vec3 const normal + , DerivVec3 const normal , bool enableDotProducts , bool enableFresnel , bool enableIridescence ) { - return create( writer, name, vec3( 0.0_f ), world, vec3( 0.0_f ), clip, normal + return create( writer, name, vec3( 0.0_f ), world, derivVec3( 0.0_f ), clip, normal , enableDotProducts, enableFresnel, enableIridescence ); } @@ -125,10 +125,10 @@ namespace castor3d::shader , Utils & utils , castor::MbString const & name , sdw::Vec3 const eye - , sdw::Vec4 const world - , sdw::Vec3 const view + , DerivVec4 const world + , DerivVec3 const view , sdw::Vec3 const clip - , sdw::Vec3 const normal + , DerivVec3 const normal , sdw::Vec3 const f0 , BlendComponents const & components , bool enableDotProducts @@ -141,29 +141,29 @@ namespace castor3d::shader return result; } - void LightSurface::updateN( sdw::Vec3 const n )const + void LightSurface::updateN( DerivVec3 const n )const { N() = n; - m_NdotL = max( 0.0_f, dot( N(), L() ) ); - m_NdotH = max( 0.0_f, dot( N(), H() ) ); - m_NdotV = max( 0.0_f, dot( N(), V() ) ); + m_NdotL = max( derivFloat( 0.0_f ), dot( N(), L() ) ); + m_NdotH = max( derivFloat( 0.0_f ), dot( N(), H() ) ); + m_NdotV = max( derivFloat( 0.0_f ), dot( N(), V() ) ); } - void LightSurface::updateL( sdw::Vec3 const VtoL )const + void LightSurface::updateL( DerivVec3 const VtoL )const { vertexToLight() = VtoL; L() = normalize( vertexToLight() ); lengthL() = length( vertexToLight() ); H() = normalize( L() + V() ); - m_NdotL = max( 0.0_f, dot( N(), L() ) ); - m_NdotH = max( 0.0_f, dot( N(), H() ) ); - m_HdotV = max( 0.0_f, dot( H(), V() ) ); + m_NdotL = max( derivFloat( 0.0_f ), dot( N(), L() ) ); + m_NdotH = max( derivFloat( 0.0_f ), dot( N(), H() ) ); + m_HdotV = max( derivFloat( 0.0_f ), dot( H(), V() ) ); } void LightSurface::updateN( Utils & utils - , sdw::Vec3 const n + , DerivVec3 const n , sdw::Vec3 const f0 , BlendComponents const & components )const { @@ -172,7 +172,7 @@ namespace castor3d::shader } void LightSurface::updateL( Utils & utils - , sdw::Vec3 const VtoL + , DerivVec3 const VtoL , sdw::Vec3 const f0 , BlendComponents const & components )const { @@ -183,7 +183,7 @@ namespace castor3d::shader void LightSurface::doUpdateF( Utils & utils , sdw::Vec3 const f0 , BlendComponents const & components - , sdw::Float const & dotProduct )const + , DerivFloat const & dotProduct )const { m_F = utils.conductorFresnel( dotProduct , f0 @@ -196,12 +196,12 @@ namespace castor3d::shader IF( writer, components.iridescenceFactor != 0.0_f ) { // Blend default specular Fresnel with iridescence Fresnel - m_spcF = mix( F(), components.iridescenceFresnel, vec3( components.iridescenceFactor ) ); + m_spcF = mix( F(), derivVec3( components.iridescenceFresnel ), derivVec3( components.iridescenceFactor ) ); // Use the maximum component of the iridescence Fresnel color // Maximum is used instead of the RGB value to not get inverse colors for the diffuse BRDF m_difF = mix( F() - , vec3( max( max( components.iridescenceFresnel.r(), components.iridescenceFresnel.g() ), components.iridescenceFresnel.b() ) ) - , vec3( components.iridescenceFactor ) ); + , derivVec3( max( max( components.iridescenceFresnel.r(), components.iridescenceFresnel.g() ), components.iridescenceFresnel.b() ) ) + , derivVec3( components.iridescenceFactor ) ); } ELSE { @@ -214,43 +214,44 @@ namespace castor3d::shader sdw::expr::ExprPtr LightSurface::makeInit( sdw::type::BaseStructPtr type , sdw::Vec3 const eye - , sdw::Vec4 const world - , sdw::Vec3 const view + , DerivVec4 const world + , DerivVec3 const view , sdw::Vec3 const clip - , sdw::Vec3 const normal + , DerivVec3 const normal , bool enableDotProducts , bool enableFresnel , bool enableIridescence ) { + using shader::operator-; sdw::expr::ExprList inits; inits.push_back( makeExpr( eye ) ); // eyePosition inits.push_back( makeExpr( world ) ); // worldPosition inits.push_back( makeExpr( view ) ); // viewPosition inits.push_back( makeExpr( clip ) ); // clipPosition - inits.push_back( makeExpr( vec3( 0.0_f ) ) ); // vertexToLight - inits.push_back( makeExpr( normalize( eye - world.xyz() ) ) ); // V + inits.push_back( makeExpr( derivVec3( 0.0_f ) ) ); // vertexToLight + inits.push_back( makeExpr( normalize( derivVec3( eye ) - getXYZ( world ) ) ) ); // V inits.push_back( makeExpr( normal ) ); // N - inits.push_back( makeExpr( vec3( 0.0_f ) ) ); // L - inits.push_back( makeExpr( vec3( 0.0_f ) ) ); // H - inits.push_back( makeExpr( length( eye - world.xyz() ) ) ); // lengthV - inits.push_back( makeExpr( 0.0_f ) ); // lengthL - inits.push_back( makeExpr( 0.0_f ) ); // NdotV + inits.push_back( makeExpr( derivVec3( 0.0_f ) ) ); // L + inits.push_back( makeExpr( derivVec3( 0.0_f ) ) ); // H + inits.push_back( makeExpr( length( derivVec3( eye ) - getXYZ( world ) ) ) ); // lengthV + inits.push_back( makeExpr( derivFloat( 0.0_f ) ) ); // lengthL + inits.push_back( makeExpr( derivFloat( 0.0_f ) ) ); // NdotV if ( enableDotProducts ) { - inits.push_back( makeExpr( 0.0_f ) ); // NdotL - inits.push_back( makeExpr( 0.0_f ) ); // NdotH - inits.push_back( makeExpr( 0.0_f ) ); // HdotV + inits.push_back( makeExpr( derivFloat( 0.0_f ) ) ); // NdotL + inits.push_back( makeExpr( derivFloat( 0.0_f ) ) ); // NdotH + inits.push_back( makeExpr( derivFloat( 0.0_f ) ) ); // HdotV } if ( enableFresnel ) { - inits.push_back( makeExpr( vec3( 0.0_f ) ) ); // F + inits.push_back( makeExpr( derivVec3( 0.0_f ) ) ); // F if ( enableIridescence ) { - inits.push_back( makeExpr( vec3( 0.0_f ) ) ); // spcF - inits.push_back( makeExpr( vec3( 0.0_f ) ) ); // difF + inits.push_back( makeExpr( derivVec3( 0.0_f ) ) ); // spcF + inits.push_back( makeExpr( derivVec3( 0.0_f ) ) ); // difF } } diff --git a/source/Core/Castor3D/Shader/Shaders/GlslLighting.cpp b/source/Core/Castor3D/Shader/Shaders/GlslLighting.cpp index d6be07b71a..55065ad3b9 100644 --- a/source/Core/Castor3D/Shader/Shaders/GlslLighting.cpp +++ b/source/Core/Castor3D/Shader/Shaders/GlslLighting.cpp @@ -50,8 +50,7 @@ namespace castor3d::shader } void LightingModel::finish( PassShaders const & passShaders - , RasterizerSurfaceBase const & rasterSurface - , SurfaceBase const & surface + , DerivSurfaceBase const & surface , Utils & utils , sdw::Vec3 const worldEye , BlendComponents & components ) @@ -61,7 +60,6 @@ namespace castor3d::shader , utils , worldEye ); doFinish( passShaders - , rasterSurface , components ); } @@ -130,7 +128,7 @@ namespace castor3d::shader || components.hasMember( "hasTransmission" ) ) ) : m_writer.declLocale( "fresnelFactor" , m_utils.fresnelMix( incident - , components.normal + , components.getRawNormal() , components.refractionRatio ) , ( components.hasMember( "specularFactor" ) || components.hasMember( "refractionRatio" ) @@ -234,7 +232,7 @@ namespace castor3d::shader auto radiance = m_writer.declLocale( "radiance" , vec3( 0.0_f ) ); lightSurface.updateL( m_utils - , -light.direction() + , derivVec3( -light.direction() ) , components.f0 , components ); doComputeLight( light.base() @@ -325,7 +323,7 @@ namespace castor3d::shader auto radiance = m_writer.declLocale( "radiance" , vec3( 0.0_f ) ); lightSurface.updateL( m_utils - , light.position() - lightSurface.worldPosition().xyz() + , derivVec3( light.position() ) - getXYZ( lightSurface.worldPosition() ) , components.f0 , components ); doComputeLight( light.base() @@ -334,7 +332,7 @@ namespace castor3d::shader , radiance , output ); auto attenuation = m_writer.declLocale( "attenuation", 1.0_f ); - light.getAttenuationFactor( lightSurface.lengthL(), attenuation ); + light.getAttenuationFactor( lightSurface.lengthL().value(), attenuation ); if ( m_shadowModel.isEnabled() ) { @@ -409,11 +407,11 @@ namespace castor3d::shader , DirectLighting const & parentOutput ) { lightSurface.updateL( m_utils - , light.position() - lightSurface.worldPosition().xyz() + , derivVec3( light.position() ) - getXYZ( lightSurface.worldPosition() ) , components.f0 , components ); auto spotFactor = m_writer.declLocale( "spotFactor" - , dot( lightSurface.L(), light.direction() ) ); + , dot( lightSurface.L().value(), light.direction() ) ); IF( m_writer, spotFactor > light.outerCutOffCos() ) { @@ -433,7 +431,7 @@ namespace castor3d::shader output.coatingSpecular() = spotFactor * output.coatingSpecular(); output.sheen().x() = spotFactor * output.sheen().x(); auto attenuation = m_writer.declLocale( "attenuation", 1.0_f ); - light.getAttenuationFactor( lightSurface.lengthL(), attenuation ); + light.getAttenuationFactor( lightSurface.lengthL().value(), attenuation ); if ( m_shadowModel.isEnabled() ) { @@ -509,7 +507,7 @@ namespace castor3d::shader , LightSurface const & lightSurface , sdw::UInt const & receivesShadows ) { - lightSurface.updateL( -light.direction() ); + lightSurface.updateL( derivVec3( -light.direction() ) ); auto radiance = m_writer.declLocale( "radiance" , vec3( 0.0_f ) ); auto diffuse = doComputeLightDiffuse( light.base() @@ -579,7 +577,7 @@ namespace castor3d::shader , LightSurface const & lightSurface , sdw::UInt const & receivesShadows ) { - lightSurface.updateL( light.position() - lightSurface.worldPosition().xyz() ); + lightSurface.updateL( derivVec3( light.position() ) - getXYZ( lightSurface.worldPosition() ) ); auto radiance = m_writer.declLocale( "radiance" , vec3( 0.0_f ) ); auto diffuse = doComputeLightDiffuse( light.base() @@ -587,7 +585,7 @@ namespace castor3d::shader , lightSurface , radiance ); auto attenuation = m_writer.declLocale( "attenuation", 1.0_f ); - light.getAttenuationFactor( lightSurface.lengthL(), attenuation ); + light.getAttenuationFactor( lightSurface.lengthL().value(), attenuation ); if ( m_shadowModel.isEnabled() ) { @@ -653,9 +651,9 @@ namespace castor3d::shader , LightSurface const & lightSurface , sdw::UInt const & receivesShadows ) { - lightSurface.updateL( light.position() - lightSurface.worldPosition().xyz() ); + lightSurface.updateL( derivVec3( light.position() ) - getXYZ( lightSurface.worldPosition() ) ); auto spotFactor = m_writer.declLocale( "spotFactor" - , dot( lightSurface.L(), light.direction() ) ); + , dot( lightSurface.L().value(), light.direction() ) ); auto diffuse = m_writer.declLocale( "diffuse" , vec3( 0.0_f ) ); @@ -670,7 +668,7 @@ namespace castor3d::shader spotFactor = clamp( ( spotFactor - light.outerCutOffCos() ) / light.cutOffsCosDiff(), 0.0_f, 1.0_f ); diffuse = spotFactor * diffuse; auto attenuation = m_writer.declLocale( "attenuation", 1.0_f ); - light.getAttenuationFactor( lightSurface.lengthL(), attenuation ); + light.getAttenuationFactor( lightSurface.lengthL().value(), attenuation ); if ( m_shadowModel.isEnabled() ) { @@ -749,7 +747,7 @@ namespace castor3d::shader auto radiance = m_writer.declLocale( "radiance" , vec3( 0.0_f ) ); lightSurface.updateL( m_utils - , -light.direction() + , derivVec3( -light.direction() ) , components.f0 , components ); doComputeLightAllButDiffuse( light.base() @@ -839,7 +837,7 @@ namespace castor3d::shader auto radiance = m_writer.declLocale( "radiance" , vec3( 0.0_f ) ); lightSurface.updateL( m_utils - , light.position() - lightSurface.worldPosition().xyz() + , derivVec3( light.position() ) - getXYZ( lightSurface.worldPosition() ) , components.f0 , components ); doComputeLightAllButDiffuse( light.base() @@ -848,7 +846,7 @@ namespace castor3d::shader , radiance , output ); auto attenuation = m_writer.declLocale( "attenuation", 1.0_f ); - light.getAttenuationFactor( lightSurface.lengthL(), attenuation ); + light.getAttenuationFactor( lightSurface.lengthL().value(), attenuation ); if ( m_shadowModel.isEnabled() ) { @@ -923,11 +921,11 @@ namespace castor3d::shader , DirectLighting const & parentOutput ) { lightSurface.updateL( m_utils - , light.position() - lightSurface.worldPosition().xyz() + , derivVec3( light.position() ) - getXYZ( lightSurface.worldPosition() ) , components.f0 , components ); auto spotFactor = m_writer.declLocale( "spotFactor" - , dot( lightSurface.L(), light.direction() ) ); + , dot( lightSurface.L().value(), light.direction() ) ); IF( m_writer, spotFactor > light.outerCutOffCos() ) { @@ -946,7 +944,7 @@ namespace castor3d::shader output.coatingSpecular() = spotFactor * output.coatingSpecular(); output.sheen().x() = spotFactor * output.sheen().x(); auto attenuation = m_writer.declLocale( "attenuation", 1.0_f ); - light.getAttenuationFactor( lightSurface.lengthL(), attenuation ); + light.getAttenuationFactor( lightSurface.lengthL().value(), attenuation ); if ( m_shadowModel.isEnabled() ) { @@ -1043,8 +1041,8 @@ namespace castor3d::shader { auto cascadeFactors = m_writer.declLocale( "cascadeFactors" , m_lights.getCascadeFactors( shadows - , lightSurface.viewPosition() - , m_writer.getVariable< sdw::UInt >( "c3d_maxCascadeCount" ) ) ); + , lightSurface.viewPosition().value() + , m_shadowModel.getMaxCascadeCount() ) ); *m_directionalCascadeIndex = m_writer.cast< sdw::UInt >( cascadeFactors.x() ); *m_directionalCascadeCount = shadows.cascadeCount(); m_directionalTransform = castor::make_unique< sdw::Mat4 >( m_writer.declLocale( "directionalTransform" @@ -1149,7 +1147,7 @@ namespace castor3d::shader , m_shadowModel.computePoint( baseShadows , shadowMapIndex , lightSurface - , 1.0_f - ( length( -lightSurface.vertexToLight() ) / lightRange ) ) ); + , 1.0_f - ( lightSurface.lengthL().value() / lightRange ) ) ); if ( withDiffuse ) { @@ -1185,7 +1183,7 @@ namespace castor3d::shader , shadowMapIndex , lightSurface , shadows.transform() - , length( -lightSurface.vertexToLight() ) / lightRange ) ); + , lightSurface.lengthL().value() / lightRange ) ); if ( withDiffuse ) { @@ -1257,7 +1255,7 @@ namespace castor3d::shader , m_shadowModel.computePoint( baseShadows , shadowMapIndex , lightSurface - , 1.0_f - ( length( -lightSurface.vertexToLight() ) / lightRange ) ) ); + , 1.0_f - ( lightSurface.lengthL().value() / lightRange ) ) ); output *= shadowFactor; } FI @@ -1284,7 +1282,7 @@ namespace castor3d::shader , shadowMapIndex , lightSurface , shadows.transform() - , length( -lightSurface.vertexToLight() ) / lightRange ) ); + , lightSurface.lengthL().value() / lightRange ) ); output *= shadowFactor; } FI @@ -1365,13 +1363,13 @@ namespace castor3d::shader { } - sdw::Float LightingModel::doGetNdotL( LightSurface const & lightSurface + DerivFloat LightingModel::doGetNdotL( LightSurface const & lightSurface , BlendComponents const & components ) { return lightSurface.NdotL(); } - sdw::Float LightingModel::doGetNdotH( LightSurface const & lightSurface + DerivFloat LightingModel::doGetNdotH( LightSurface const & lightSurface , BlendComponents const & components ) { return lightSurface.NdotH(); @@ -1383,7 +1381,7 @@ namespace castor3d::shader , sdw::Vec3 & radiance , DirectLighting & output ) { - radiance = doComputeRadiance( light, lightSurface.L() ); + radiance = doComputeRadiance( light, lightSurface.L().value() ); auto isLit = m_writer.declLocale( "isLit", 0.0_f ); doInitLightSpecifics( lightSurface, components ); auto rawDiffuse = doComputeDiffuseTerm( radiance @@ -1420,7 +1418,7 @@ namespace castor3d::shader { auto isLit = m_writer.declLocale( "isLit", 0.0_f ); auto result = m_writer.declLocale( "result", vec3( 0.0_f ) ); - radiance = doComputeRadiance( light, lightSurface.L() ); + radiance = doComputeRadiance( light, lightSurface.L().value() ); doInitLightSpecifics( lightSurface, components ); doComputeDiffuseTerm( radiance , light.intensity().x() @@ -1437,7 +1435,7 @@ namespace castor3d::shader , sdw::Vec3 & radiance , DirectLighting & output ) { - radiance = doComputeRadiance( light, lightSurface.L() ); + radiance = doComputeRadiance( light, lightSurface.L().value() ); auto isLit = m_writer.declLocale( "isLit", 0.0_f ); doInitLightSpecifics( lightSurface, components ); doComputeSpecularTerm( radiance diff --git a/source/Core/Castor3D/Shader/Shaders/GlslMaterial.cpp b/source/Core/Castor3D/Shader/Shaders/GlslMaterial.cpp index daa12706fd..33eb1126d4 100644 --- a/source/Core/Castor3D/Shader/Shaders/GlslMaterial.cpp +++ b/source/Core/Castor3D/Shader/Shaders/GlslMaterial.cpp @@ -5,6 +5,7 @@ #include "Castor3D/Cache/MaterialCache.hpp" #include "Castor3D/Shader/Shaders/GlslBlendComponents.hpp" #include "Castor3D/Shader/Shaders/GlslDebugOutput.hpp" +#include "Castor3D/Shader/Shaders/GlslDerivativeValue.hpp" #include "Castor3D/Shader/Shaders/GlslLighting.hpp" #include "Castor3D/Shader/Shaders/GlslPassShaders.hpp" #include "Castor3D/Shader/Shaders/GlslTextureAnimation.hpp" @@ -79,7 +80,7 @@ namespace castor3d::shader ROF output = result; - output.normal = normalize( result.normal ); + output.normalizeNormal(); } else { diff --git a/source/Core/Castor3D/Shader/Shaders/GlslPassShaders.cpp b/source/Core/Castor3D/Shader/Shaders/GlslPassShaders.cpp index c5808d9d07..384e7dbb68 100644 --- a/source/Core/Castor3D/Shader/Shaders/GlslPassShaders.cpp +++ b/source/Core/Castor3D/Shader/Shaders/GlslPassShaders.cpp @@ -4,6 +4,7 @@ #include "Castor3D/Material/Pass/Component/PassComponentRegister.hpp" #include "Castor3D/Material/Pass/Component/PassMapComponent.hpp" #include "Castor3D/Shader/Shaders/GlslBlendComponents.hpp" +#include "Castor3D/Shader/Shaders/GlslDerivativeValue.hpp" #include "Castor3D/Shader/Shaders/GlslMaterial.hpp" #include "Castor3D/Shader/Shaders/GlslSurface.hpp" #include "Castor3D/Shader/Shaders/GlslTextureConfiguration.hpp" @@ -235,7 +236,7 @@ namespace castor3d::shader updateComponents( flags.textures, maps, material, components, flags.isFrontCulled() ); } - void PassShaders::finishComponents( SurfaceBase const & surface + void PassShaders::finishComponents( DerivSurfaceBase const & surface , sdw::Vec3 const worldEye , Utils & utils , BlendComponents & components )const @@ -290,7 +291,7 @@ namespace castor3d::shader return it != m_shaders.end() ? ( *it )->sampleMap( map, texCoords, components ) : ( m_forceLod0 - ? m_utils.sampleMap( map, texCoords.uv(), 0.0_f ) + ? m_utils.sampleMap( map, texCoords.value(), 0.0_f ) : m_utils.sampleMap( map, texCoords ) ); } @@ -316,7 +317,7 @@ namespace castor3d::shader , shader::BlendComponents const & components )const { return ( m_forceLod0 - ? m_utils.sampleMap( map, texCoords.uv(), 0.0_f ) + ? m_utils.sampleMap( map, texCoords.value(), 0.0_f ) : m_utils.sampleMap( map, texCoords ) ); } diff --git a/source/Core/Castor3D/Shader/Shaders/GlslReflection.cpp b/source/Core/Castor3D/Shader/Shaders/GlslReflection.cpp index 2da97e8a91..e882fd2040 100644 --- a/source/Core/Castor3D/Shader/Shaders/GlslReflection.cpp +++ b/source/Core/Castor3D/Shader/Shaders/GlslReflection.cpp @@ -3,6 +3,7 @@ #include "Castor3D/Shader/Shaders/GlslBackground.hpp" #include "Castor3D/Shader/Shaders/GlslBlendComponents.hpp" #include "Castor3D/Shader/Shaders/GlslDebugOutput.hpp" +#include "Castor3D/Shader/Shaders/GlslDerivativeValue.hpp" #include "Castor3D/Shader/Shaders/GlslLightSurface.hpp" #include "Castor3D/Shader/Shaders/GlslSurface.hpp" #include "Castor3D/Shader/Shaders/GlslUtils.hpp" @@ -46,11 +47,11 @@ namespace castor3d::shader , DebugOutputCategory & debugOutput ) { computeCombined( components - , lightSurface.N() - , lightSurface.difF() - , lightSurface.spcF() - , lightSurface.V() - , lightSurface.NdotV() + , lightSurface.N().value() + , lightSurface.difF().value() + , lightSurface.spcF().value() + , lightSurface.V().value() + , lightSurface.NdotV().value() , position , background , mippedScene @@ -240,11 +241,11 @@ namespace castor3d::shader , DebugOutputCategory & debugOutput ) { computeCombined( pcomponents - , lightSurface.N() - , lightSurface.difF() - , lightSurface.spcF() - , lightSurface.V() - , lightSurface.NdotV() + , lightSurface.N().value() + , lightSurface.difF().value() + , lightSurface.spcF().value() + , lightSurface.V().value() + , lightSurface.NdotV().value() , background , envMapIndex , hasReflection @@ -401,11 +402,11 @@ namespace castor3d::shader , DebugOutputCategory & debugOutput ) { computeReflections( components - , lightSurface.N() - , lightSurface.difF() - , lightSurface.spcF() - , lightSurface.V() - , lightSurface.NdotV() + , lightSurface.N().value() + , lightSurface.difF().value() + , lightSurface.spcF().value() + , lightSurface.V().value() + , lightSurface.NdotV().value() , background , envMapIndex , reflection @@ -459,8 +460,8 @@ namespace castor3d::shader , DebugOutputCategory & debugOutput ) { return computeRefractions( components - , lightSurface.N() - , lightSurface.V() + , lightSurface.N().value() + , lightSurface.V().value() , background , envMapIndex , refractionRatio @@ -500,6 +501,12 @@ namespace castor3d::shader return normalize( wsPosition - wsCamera ); } + DerivVec3 ReflectionModel::computeIncident( DerivVec3 const & wsPosition + , sdw::Vec3 const & wsCamera )const + { + return normalize( wsPosition - wsCamera ); + } + sdw::Vec4 ReflectionModel::computeScreenSpace( CameraData const & cameraData , sdw::Vec3 const & pviewPosition , sdw::Vec3 const & pworldNormal diff --git a/source/Core/Castor3D/Shader/Shaders/GlslShadow.cpp b/source/Core/Castor3D/Shader/Shaders/GlslShadow.cpp index f173a6f537..92cffd0a29 100644 --- a/source/Core/Castor3D/Shader/Shaders/GlslShadow.cpp +++ b/source/Core/Castor3D/Shader/Shaders/GlslShadow.cpp @@ -20,6 +20,36 @@ namespace castor3d::shader { //********************************************************************************************* + namespace shadow + { + castor::MbString const MapDepthDirectional = "c3d_shdMapDepthDirectional"; + castor::MbString const MapDepthSpot = "c3d_shdMapDepthSpot"; + castor::MbString const MapDepthPoint = "c3d_shdMapDepthPoint"; + castor::MbString const MapDepthCmpDirectional = "c3d_shdMapDepthCmpDirectional"; + castor::MbString const MapDepthCmpSpot = "c3d_shdMapDepthCmpSpot"; + castor::MbString const MapDepthCmpPoint = "c3d_shdMapDepthCmpPoint"; + castor::MbString const MapVarianceDirectional = "c3d_shdMapVarianceDirectional"; + castor::MbString const MapVarianceSpot = "c3d_shdMapVarianceSpot"; + castor::MbString const MapVariancePoint = "c3d_shdMapVariancePoint"; + castor::MbString const MapNormalDirectional = "c3d_shdMapNormalDirectional"; + castor::MbString const MapNormalSpot = "c3d_shdMapNormalSpot"; + castor::MbString const MapNormalPoint = "c3d_shdMapNormalPoint"; + castor::MbString const MapPositionDirectional = "c3d_shdMapPositionDirectional"; + castor::MbString const MapPositionSpot = "c3d_shdMapPositionSpot"; + castor::MbString const MapPositionPoint = "c3d_shdMapPositionPoint"; + castor::MbString const MapFluxDirectional = "c3d_shdMapFluxDirectional"; + castor::MbString const MapFluxSpot = "c3d_shdMapFluxSpot"; + castor::MbString const MapFluxPoint = "c3d_shdMapFluxPoint"; + castor::MbString const RandomBuffer = "c3d_shdRandomBuffer"; + castor::MbString const MaxCascadeCount = "c3d_maxCascadeCount"; + castor::MbString const VolumetricDither = "c3d_volumetricDither"; + + using CombinedImage2DArray = sdw::CombinedImage2DArrayR32; + using CombinedImageCubeArray = sdw::CombinedImageCubeArrayR32; + } + + //********************************************************************************************* + void ShadowData::updateShadowType( ShadowType type )const { shadowType() = uint32_t( type ); @@ -60,26 +90,6 @@ namespace castor3d::shader //********************************************************************************************* - castor::MbString const Shadow::MapDepthDirectional = "c3d_shdMapDepthDirectional"; - castor::MbString const Shadow::MapDepthSpot = "c3d_shdMapDepthSpot"; - castor::MbString const Shadow::MapDepthPoint = "c3d_shdMapDepthPoint"; - castor::MbString const Shadow::MapDepthCmpDirectional = "c3d_shdMapDepthCmpDirectional"; - castor::MbString const Shadow::MapDepthCmpSpot = "c3d_shdMapDepthCmpSpot"; - castor::MbString const Shadow::MapDepthCmpPoint = "c3d_shdMapDepthCmpPoint"; - castor::MbString const Shadow::MapVarianceDirectional = "c3d_shdMapVarianceDirectional"; - castor::MbString const Shadow::MapVarianceSpot = "c3d_shdMapVarianceSpot"; - castor::MbString const Shadow::MapVariancePoint = "c3d_shdMapVariancePoint"; - castor::MbString const Shadow::MapNormalDirectional = "c3d_shdMapNormalDirectional"; - castor::MbString const Shadow::MapNormalSpot = "c3d_shdMapNormalSpot"; - castor::MbString const Shadow::MapNormalPoint = "c3d_shdMapNormalPoint"; - castor::MbString const Shadow::MapPositionDirectional = "c3d_shdMapPositionDirectional"; - castor::MbString const Shadow::MapPositionSpot = "c3d_shdMapPositionSpot"; - castor::MbString const Shadow::MapPositionPoint = "c3d_shdMapPositionPoint"; - castor::MbString const Shadow::MapFluxDirectional = "c3d_shdMapFluxDirectional"; - castor::MbString const Shadow::MapFluxSpot = "c3d_shdMapFluxSpot"; - castor::MbString const Shadow::MapFluxPoint = "c3d_shdMapFluxPoint"; - castor::MbString const Shadow::RandomBuffer = "c3d_shdRandomBuffer"; - Shadow::Shadow( ShadowOptions shadowOptions , sdw::ShaderWriter & writer ) : m_writer{ writer } @@ -161,49 +171,49 @@ namespace castor3d::shader if ( m_shadowOptions.type ) { - m_writer.declConstant( "c3d_maxCascadeCount" + m_writer.declConstant( shadow::MaxCascadeCount , sdw::UInt( MaxDirectionalCascadesCount ) ); - m_writer.declConstantArray( "c3d_volumetricDither" + m_writer.declConstantArray( shadow::VolumetricDither , castor::Vector< sdw::Vec4 >{ vec4( 0.0_f, 0.5_f, 0.125_f, 0.625_f ) , vec4( 0.75_f, 0.22_f, 0.875_f, 0.375_f ) , vec4( 0.1875_f, 0.6875_f, 0.0625_f, 0.5625_f ) , vec4( 0.9375_f, 0.4375_f, 0.8125_f, 0.3125_f ) } ); - m_writer.declCombinedImg< FImg2DArrayR32 >( MapDepthDirectional + m_writer.declCombinedImg< sdw::CombinedImage2DArrayR32 >( shadow::MapDepthDirectional , ( ( directionalEnabled || m_shadowOptions.reserveIds ) ? index++ : index ) , set , directionalEnabled ); - m_writer.declCombinedImg< FImg2DArrayR32 >( MapDepthCmpDirectional + m_writer.declCombinedImg< shadow::CombinedImage2DArray >( shadow::MapDepthCmpDirectional , ( ( directionalEnabled || m_shadowOptions.reserveIds ) ? index++ : index ) , set , directionalEnabled ); - m_writer.declCombinedImg< FImg2DArrayRg32 >( MapVarianceDirectional + m_writer.declCombinedImg< sdw::CombinedImage2DArrayRg32 >( shadow::MapVarianceDirectional , ( ( directionalEnabled || m_shadowOptions.reserveIds ) ? index++ : index ) , set , directionalEnabled ); - m_writer.declCombinedImg< FImgCubeArrayR32 >( MapDepthPoint + m_writer.declCombinedImg< sdw::CombinedImageCubeArrayR32 >( shadow::MapDepthPoint , ( ( pointEnabled || m_shadowOptions.reserveIds ) ? index++ : index ) , set , pointEnabled ); - m_writer.declCombinedImg< FImgCubeArrayR32 >( MapDepthCmpPoint + m_writer.declCombinedImg< shadow::CombinedImageCubeArray >( shadow::MapDepthCmpPoint , ( ( pointEnabled || m_shadowOptions.reserveIds ) ? index++ : index ) , set , pointEnabled ); - m_writer.declCombinedImg< FImgCubeArrayRg32 >( MapVariancePoint + m_writer.declCombinedImg< sdw::CombinedImageCubeArrayRg32 >( shadow::MapVariancePoint , ( ( pointEnabled || m_shadowOptions.reserveIds ) ? index++ : index ) , set , pointEnabled ); - m_writer.declCombinedImg< FImg2DArrayR32 >( MapDepthSpot + m_writer.declCombinedImg< sdw::CombinedImage2DArrayR32 >( shadow::MapDepthSpot , ( ( spotEnabled || m_shadowOptions.reserveIds ) ? index++ : index ) , set , spotEnabled ); - m_writer.declCombinedImg< FImg2DArrayR32 >( MapDepthCmpSpot + m_writer.declCombinedImg< shadow::CombinedImage2DArray >( shadow::MapDepthCmpSpot , ( ( spotEnabled || m_shadowOptions.reserveIds ) ? index++ : index ) , set , spotEnabled ); - m_writer.declCombinedImg< FImg2DArrayRg32 >( MapVarianceSpot + m_writer.declCombinedImg< sdw::CombinedImage2DArrayRg32 >( shadow::MapVarianceSpot , ( ( spotEnabled || m_shadowOptions.reserveIds ) ? index++ : index ) , set , spotEnabled ); @@ -212,7 +222,7 @@ namespace castor3d::shader , index , set ); ++index; - auto randomSsbo = m_writer.declStorageBuffer( RandomBuffer + auto randomSsbo = m_writer.declStorageBuffer( shadow::RandomBuffer , index , set ); ++index; @@ -233,23 +243,23 @@ namespace castor3d::shader { if ( checkFlag( m_shadowOptions.type, SceneFlag::eShadowDirectional ) ) { - m_writer.declConstant( "c3d_maxCascadeCount" + m_writer.declConstant( shadow::MaxCascadeCount , sdw::UInt( MaxDirectionalCascadesCount ) ); - m_writer.declConstantArray( "c3d_volumetricDither" + m_writer.declConstantArray( shadow::VolumetricDither , castor::Vector< sdw::Vec4 >{ vec4( 0.0_f, 0.5_f, 0.125_f, 0.625_f ) , vec4( 0.75_f, 0.22_f, 0.875_f, 0.375_f ) , vec4( 0.1875_f, 0.6875_f, 0.0625_f, 0.5625_f ) , vec4( 0.9375_f, 0.4375_f, 0.8125_f, 0.3125_f ) } ); - m_writer.declCombinedImg< FImg2DArrayR32 >( MapDepthDirectional + m_writer.declCombinedImg< sdw::CombinedImage2DArrayR32 >( shadow::MapDepthDirectional , index , set ); ++index; - m_writer.declCombinedImg< FImg2DArrayR32 >( MapDepthCmpDirectional + m_writer.declCombinedImg< shadow::CombinedImage2DArray >( shadow::MapDepthCmpDirectional , index , set ); ++index; - m_writer.declCombinedImg< FImg2DArrayRg32 >( MapVarianceDirectional + m_writer.declCombinedImg< sdw::CombinedImage2DArrayRg32 >( shadow::MapVarianceDirectional , index , set ); ++index; @@ -258,7 +268,7 @@ namespace castor3d::shader , index , set ); ++index; - auto randomSsbo = m_writer.declStorageBuffer( RandomBuffer + auto randomSsbo = m_writer.declStorageBuffer( shadow::RandomBuffer , index , set ); ++index; @@ -277,15 +287,15 @@ namespace castor3d::shader { if ( checkFlag( m_shadowOptions.type, SceneFlag::eShadowPoint ) ) { - m_writer.declCombinedImg< FImgCubeArrayR32 >( MapDepthPoint + m_writer.declCombinedImg< sdw::CombinedImageCubeArrayR32 >( shadow::MapDepthPoint , index , set ); ++index; - m_writer.declCombinedImg< FImgCubeArrayR32 >( MapDepthCmpPoint + m_writer.declCombinedImg< shadow::CombinedImageCubeArray >( shadow::MapDepthCmpPoint , index , set ); ++index; - m_writer.declCombinedImg< FImgCubeArrayRg32 >( MapVariancePoint + m_writer.declCombinedImg< sdw::CombinedImageCubeArrayRg32 >( shadow::MapVariancePoint , index , set ); ++index; @@ -294,7 +304,7 @@ namespace castor3d::shader , index , set ); ++index; - auto randomSsbo = m_writer.declStorageBuffer( RandomBuffer + auto randomSsbo = m_writer.declStorageBuffer( shadow::RandomBuffer , index , set ); ++index; @@ -313,15 +323,15 @@ namespace castor3d::shader { if ( checkFlag( m_shadowOptions.type, SceneFlag::eShadowSpot ) ) { - m_writer.declCombinedImg< FImg2DArrayR32 >( MapDepthSpot + m_writer.declCombinedImg< sdw::CombinedImage2DArrayR32 >( shadow::MapDepthSpot , index , set ); ++index; - m_writer.declCombinedImg< FImg2DArrayR32 >( MapDepthCmpSpot + m_writer.declCombinedImg< shadow::CombinedImage2DArray >( shadow::MapDepthCmpSpot , index , set ); ++index; - m_writer.declCombinedImg< FImg2DArrayRg32 >( MapVarianceSpot + m_writer.declCombinedImg< sdw::CombinedImage2DArrayRg32 >( shadow::MapVarianceSpot , index , set ); ++index; @@ -330,7 +340,7 @@ namespace castor3d::shader , index , set ); ++index; - auto randomSsbo = m_writer.declStorageBuffer( RandomBuffer + auto randomSsbo = m_writer.declStorageBuffer( shadow::RandomBuffer , index , set ); ++index; @@ -344,6 +354,41 @@ namespace castor3d::shader } } + bool Shadow::hasMapDepthDirectional()const + { + return m_writer.hasGlobalVariable( shadow::MapDepthDirectional ); + } + + bool Shadow::hasMapDepthPoint()const + { + return m_writer.hasGlobalVariable( shadow::MapDepthPoint ); + } + + bool Shadow::hasMapDepthSpot()const + { + return m_writer.hasGlobalVariable( shadow::MapDepthSpot ); + } + + sdw::CombinedImage2DArrayR32 Shadow::getMapDepthDirectional()const + { + return m_writer.getVariable< sdw::CombinedImage2DArrayR32 >( shadow::MapDepthDirectional ); + } + + sdw::CombinedImageCubeArrayR32 Shadow::getMapDepthPoint()const + { + return m_writer.getVariable< sdw::CombinedImageCubeArrayR32 >( shadow::MapDepthPoint ); + } + + sdw::CombinedImage2DArrayR32 Shadow::getMapDepthSpot()const + { + return m_writer.getVariable< sdw::CombinedImage2DArrayR32 >( shadow::MapDepthSpot ); + } + + sdw::UInt Shadow::getMaxCascadeCount()const + { + return m_writer.getVariable< sdw::UInt >( shadow::MaxCascadeCount ); + } + DirectionalShadowData Shadow::getDirectionalShadows() { if ( m_shadowsBuffer ) @@ -404,7 +449,7 @@ namespace castor3d::shader IF( m_writer, shadows.shadowType() == sdw::UInt( int( ShadowType::eVariance ) ) ) { - auto c3d_mapVarianceDirectional = m_writer.getVariable< sdw::CombinedImage2DArrayRg32 >( Shadow::MapVarianceDirectional ); + auto c3d_mapVarianceDirectional = m_writer.getVariable< sdw::CombinedImage2DArrayRg32 >( shadow::MapVarianceDirectional ); auto moments = m_writer.declLocale( "moments" , c3d_mapVarianceDirectional.lod( vec3( lightSpacePosition.xy(), m_writer.cast< sdw::Float >( cascadeIndex ) ), 0.0_f ) ); result = chebyshevUpperBound( moments @@ -414,7 +459,7 @@ namespace castor3d::shader } ELSEIF( shadows.shadowType() == sdw::UInt( int( ShadowType::ePCF ) ) ) { - auto c3d_mapNormalDepthCmpDirectional = m_writer.getVariable< sdw::CombinedImage2DArrayR32 >( Shadow::MapDepthCmpDirectional ); + auto c3d_mapNormalDepthCmpDirectional = m_writer.getVariable< shadow::CombinedImage2DArray >( shadow::MapDepthCmpDirectional ); auto depthBias = m_writer.declLocale( "depthBias" , getShadowOffset( wsNormal , lightToVertex @@ -430,7 +475,7 @@ namespace castor3d::shader } ELSE { - auto c3d_mapNormalDepthDirectional = m_writer.getVariable< sdw::CombinedImage2DArrayR32 >( Shadow::MapDepthDirectional ); + auto c3d_mapNormalDepthDirectional = m_writer.getVariable< sdw::CombinedImage2DArrayR32 >( shadow::MapDepthDirectional ); auto depthBias = m_writer.declLocale( "depthBias" , getShadowOffset( wsNormal , lightToVertex @@ -474,9 +519,9 @@ namespace castor3d::shader , sdw::UInt const & pmaxCascade ) { return computeDirectional( pshadows - , plightSurface.vertexToLight() - , plightSurface.N() - , plightSurface.worldPosition().xyz() + , plightSurface.vertexToLight().value() + , plightSurface.N().value() + , plightSurface.worldPosition().value().xyz() , plightMatrix , pcascadeIndex , pmaxCascade ); @@ -512,7 +557,7 @@ namespace castor3d::shader IF( m_writer, shadows.shadowType() == sdw::UInt( int( ShadowType::eVariance ) ) ) { - auto c3d_mapVarianceSpot = m_writer.getVariable< sdw::CombinedImage2DArrayRg32 >( Shadow::MapVarianceSpot ); + auto c3d_mapVarianceSpot = m_writer.getVariable< sdw::CombinedImage2DArrayRg32 >( shadow::MapVarianceSpot ); auto moments = m_writer.declLocale( "moments" , c3d_mapVarianceSpot.lod( vec3( lightSpacePosition.xy(), shadowMapIndex ), 0.0_f ) ); result = chebyshevUpperBound( moments @@ -524,7 +569,7 @@ namespace castor3d::shader { IF( m_writer, shadows.shadowType() == sdw::UInt( int( ShadowType::ePCF ) ) ) { - auto c3d_mapNormalDepthCmpSpot = m_writer.getVariable< sdw::CombinedImage2DArrayR32 >( Shadow::MapDepthCmpSpot ); + auto c3d_mapNormalDepthCmpSpot = m_writer.getVariable< shadow::CombinedImage2DArray >( shadow::MapDepthCmpSpot ); auto depthBias = m_writer.declLocale( "depthBias" , getShadowOffset( wsNormal , lightDirection @@ -540,7 +585,7 @@ namespace castor3d::shader } ELSE { - auto c3d_mapNormalDepthSpot = m_writer.getVariable< sdw::CombinedImage2DArrayR32 >( Shadow::MapDepthSpot ); + auto c3d_mapNormalDepthSpot = m_writer.getVariable< sdw::CombinedImage2DArrayR32 >( shadow::MapDepthSpot ); auto depthBias = m_writer.declLocale( "depthBias" , getShadowOffset( wsNormal , lightDirection @@ -573,9 +618,9 @@ namespace castor3d::shader return m_computeSpot( pshadows , pshadowMapIndex , pdepth - , plightSurface.vertexToLight() - , plightSurface.N() - , plightSurface.worldPosition().xyz() + , plightSurface.vertexToLight().value() + , plightSurface.N().value() + , plightSurface.worldPosition().value().xyz() , plightMatrix ); } @@ -605,7 +650,7 @@ namespace castor3d::shader IF( m_writer, shadows.shadowType() == sdw::UInt( int( ShadowType::eVariance ) ) ) { - auto c3d_mapVariancePoint = m_writer.getVariable< sdw::CombinedImageCubeArrayRg32 >( Shadow::MapVariancePoint ); + auto c3d_mapVariancePoint = m_writer.getVariable< sdw::CombinedImageCubeArrayRg32 >( shadow::MapVariancePoint ); auto moments = m_writer.declLocale( "moments" , c3d_mapVariancePoint.lod( vec4( lightToVertex, shadowMapIndex ), 0.0_f ) ); result = chebyshevUpperBound( moments @@ -617,7 +662,7 @@ namespace castor3d::shader { IF( m_writer, shadows.shadowType() == sdw::UInt( int( ShadowType::ePCF ) ) ) { - auto c3d_mapDepthCmpPoint = m_writer.getVariable< sdw::CombinedImageCubeArrayR32 >( Shadow::MapDepthCmpPoint ); + auto c3d_mapDepthCmpPoint = m_writer.getVariable< shadow::CombinedImageCubeArray >( shadow::MapDepthCmpPoint ); auto depthBias = m_writer.declLocale( "depthBias" , getShadowOffset( wsNormal , lightDirection @@ -634,7 +679,7 @@ namespace castor3d::shader } ELSE { - auto c3d_mapDepthPoint = m_writer.getVariable< sdw::CombinedImageCubeArrayR32 >( Shadow::MapDepthPoint ); + auto c3d_mapDepthPoint = m_writer.getVariable< sdw::CombinedImageCubeArrayR32 >( shadow::MapDepthPoint ); auto depthBias = m_writer.declLocale( "depthBias" , getShadowOffset( wsNormal , lightDirection @@ -666,9 +711,9 @@ namespace castor3d::shader return m_computePoint( pshadows , pshadowMapIndex , pdepth - , plightSurface.vertexToLight() - , plightSurface.N() - , plightSurface.worldPosition().xyz() ); + , plightSurface.vertexToLight().value() + , plightSurface.N().value() + , plightSurface.worldPosition().value().xyz() ); } sdw::Float Shadow::computeVolumetric( shader::ShadowData const & shadows @@ -677,11 +722,11 @@ namespace castor3d::shader , sdw::UInt const & cascadeIndex , sdw::UInt const & maxCascade ) { - auto c3d_volumetricDither = m_writer.getVariableArray< sdw::Vec4 >( "c3d_volumetricDither" ); + auto c3d_volumetricDither = m_writer.getVariableArray< sdw::Vec4 >( shadow::VolumetricDither ); // Prepare ray auto rayVector = m_writer.declLocale( "rayVector" - , lightSurface.worldPosition().xyz() - lightSurface.eyePosition() ); + , lightSurface.worldPosition().value().xyz() - lightSurface.eyePosition() ); auto rayLength = m_writer.declLocale( "rayLength" , length( rayVector ) ); auto rayDirection = m_writer.declLocale( "rayDirection" @@ -700,7 +745,7 @@ namespace castor3d::shader // Compute scattering value auto RdotL = m_writer.declLocale( "RdotL" - , dot( rayDirection, -lightSurface.L() ) ); + , dot( rayDirection, -lightSurface.L().value() ) ); auto sqVolumetricScattering = m_writer.declLocale( "sqVolumetricScattering" , shadows.volumetricScattering() * shadows.volumetricScattering() ); auto dblVolumetricScattering = m_writer.declLocale( "dblVolumetricScattering" @@ -727,13 +772,13 @@ namespace castor3d::shader , sdw::UInt const & maxCascade , sdw::Float const & scattering ) { - auto c3d_volumetricDither = m_writer.getVariableArray< sdw::Vec4 >( "c3d_volumetricDither" ); + auto c3d_volumetricDither = m_writer.getVariableArray< sdw::Vec4 >( shadow::VolumetricDither ); // Prepare ray auto rayLength = m_writer.declLocale( "rayLength" - , lightSurface.lengthV() ); + , lightSurface.lengthV().value() ); auto rayDirection = m_writer.declLocale( "rayDirection" - , -lightSurface.V() ); + , -lightSurface.V().value() ); auto stepLength = m_writer.declLocale( "stepLength" , rayLength / m_writer.cast< sdw::Float >( shadows.volumetricSteps() ) ); auto screenUV = m_writer.declLocale( "screenUV" @@ -828,8 +873,8 @@ namespace castor3d::shader } return m_computeVolumetric( pshadows - , plightSurface.L() - , plightSurface.N() + , plightSurface.L().value() + , plightSurface.N().value() , pray , pstepLength , plightMatrix @@ -1044,6 +1089,158 @@ namespace castor3d::shader , pfilterSize ); } + sdw::RetFloat Shadow::filterPCF( sdw::Vec3 const & plightSpacePosition + , sdw::CombinedImage2DArrayShadowR32 const & pshadowMap + , sdw::Vec2 const & pinvTexDim + , sdw::UInt const & parrayIndex + , sdw::Float const & pdepthBias + , sdw::UInt const & psampleCount + , sdw::Float const & pfilterSize ) + { + if ( !m_filterPCFArrayShadow ) + { + m_filterPCFArrayShadow = m_writer.implementFunction< sdw::Float >( "c3d_shdFilterPCFArrayShadow" + , [this]( sdw::Vec3 const & lightSpacePosition + , sdw::CombinedImage2DArrayShadowR32 const & shadowMap + , sdw::Vec2 const & invTexDim + , sdw::UInt const & arrayIndex + , sdw::Float const & depthBias + , sdw::UInt const & sampleCount + , sdw::Float const & filterSize ) + { + auto sampleScale = m_writer.declLocale( "sampleScale" + , filterSize * invTexDim ); + auto shadowFactor = m_writer.declLocale( "shadowFactor" + , 0.0_f ); + + // Get a value to randomly rotate the kernel by + auto screenPos = m_writer.declLocale( "screenPos" + , uvec2( lightSpacePosition.xy() * invTexDim ) ); + auto randomSamplePos = m_writer.declLocale( "randomSamplePos" + , screenPos.x() % RandomDataCount ); + auto theta = m_writer.declLocale( "theta" + , ( *m_randomData )[randomSamplePos][screenPos.y() % 4_u] * sdw::Float{ castor::Pi< float > } ); + auto randomRotationMatrix = m_writer.declLocale( "randomRotationMatrix" + , mat2x2( vec2( cos( theta ), -sin( theta ) ) + , vec2( sin( theta ), cos( theta ) ) ) ); + auto shadowMapDepth = m_writer.declLocale( "shadowMapDepth" + , 0.0_f ); + + FOR( m_writer, sdw::UInt, i, 0_u, i < sampleCount, ++i ) + { + auto sampleOffset = m_writer.declLocale( "sampleOffset" + , ( randomRotationMatrix * m_poissonSamples[i] ) * sampleScale ); + shadowFactor += shadowMap.lod( vec3( lightSpacePosition.xy() + sampleOffset, m_writer.cast< sdw::Float >( arrayIndex ) ) + , lightSpacePosition.z() - depthBias + , 0.0_f ); + } + ROF + + m_writer.returnStmt( shadowFactor / m_writer.cast< sdw::Float >( sampleCount ) ); + } + , sdw::InVec3{ m_writer, "lightSpacePosition" } + , sdw::InCombinedImage2DArrayShadowR32{ m_writer, "shadowMap" } + , sdw::InVec2{ m_writer, "invTexDim" } + , sdw::InUInt{ m_writer, "arrayIndex" } + , sdw::InFloat{ m_writer, "depthBias" } + , sdw::InUInt{ m_writer, "sampleCount" } + , sdw::InFloat{ m_writer, "filterSize" } ); + } + + return m_filterPCFArrayShadow( plightSpacePosition + , pshadowMap + , pinvTexDim + , parrayIndex + , pdepthBias + , psampleCount + , pfilterSize ); + } + + sdw::RetFloat Shadow::filterPCF( sdw::Vec3 const & plightToVertex + , sdw::CombinedImageCubeArrayShadowR32 const & pshadowMap + , sdw::Vec2 const & pinvTexDim + , sdw::UInt const & pcubeIndex + , sdw::Float const & pdepth + , sdw::Float const & pdepthBias + , sdw::UInt const & psampleCount + , sdw::Float const & pfilterSize ) + { + if ( !m_filterPCFCubeShadow ) + { + m_filterPCFCubeShadow = m_writer.implementFunction< sdw::Float >( "c3d_shdFilterPCFCubeShadow" + , [this]( sdw::Vec3 const & lightToVertex + , sdw::CombinedImageCubeArrayShadowR32 const & shadowMap + , sdw::Vec2 const & + , sdw::UInt const & cubeIndex + , sdw::Float const & depth + , sdw::Float const & depthBias + , sdw::UInt const & + , sdw::Float const & filterSize ) + { + int count = 0; + int const samples = 4; + + auto offset = m_writer.declLocale( "offset" + , ( filterSize * depth ) / 4.0_f ); + auto dx = m_writer.declLocale( "dx" + , -offset ); + auto dy = m_writer.declLocale( "dy" + , -offset ); + auto dz = m_writer.declLocale( "dz" + , -offset ); + auto inc = m_writer.declLocale( "inc" + , offset / ( samples * 0.5f ) ); + auto shadowFactor = m_writer.declLocale( "shadowFactor" + , 0.0_f ); + auto shadowMapDepth = m_writer.declLocale( "shadowMapDepth" + , 0.0_f); + auto sampleOffset = m_writer.declLocale( "sampleOffset" + , vec3( 0.0_f ) ); + + for ( int i = 0; i < samples; ++i ) + { + for ( int j = 0; j < samples; ++j ) + { + for ( int k = 0; k < samples; ++k ) + { + sampleOffset = vec3( dx, dy, dz ); + shadowFactor += shadowMap.lod( vec4( lightToVertex + sampleOffset, m_writer.cast< sdw::Float >( cubeIndex ) ) + , depth - depthBias + , 0.0_f ); + ++count; + dz += inc; + } + + dy += inc; + dz = -offset; + } + + dx += inc; + dy = -offset; + } + + m_writer.returnStmt( shadowFactor / float( count ) ); + } + , sdw::InVec3{ m_writer, "lightToVertex" } + , sdw::InCombinedImageCubeArrayShadowR32{ m_writer, "shadowMap" } + , sdw::InVec2{ m_writer, "invTexDim" } + , sdw::InUInt{ m_writer, "cubeIndex" } + , sdw::InFloat{ m_writer, "depth" } + , sdw::InFloat{ m_writer, "depthBias" } + , sdw::InUInt{ m_writer, "sampleCount" } + , sdw::InFloat{ m_writer, "filterSize" } ); + } + + return m_filterPCFCubeShadow( plightToVertex + , pshadowMap + , pinvTexDim + , pcubeIndex + , pdepth + , pdepthBias + , psampleCount + , pfilterSize ); + } + sdw::RetFloat Shadow::chebyshevUpperBound( sdw::Vec2 const & pmoments , sdw::Float const & pdepth , sdw::Float const & pminVariance diff --git a/source/Core/Castor3D/Shader/Shaders/GlslSheenBRDF.cpp b/source/Core/Castor3D/Shader/Shaders/GlslSheenBRDF.cpp index 2429074345..f571696e93 100644 --- a/source/Core/Castor3D/Shader/Shaders/GlslSheenBRDF.cpp +++ b/source/Core/Castor3D/Shader/Shaders/GlslSheenBRDF.cpp @@ -92,7 +92,7 @@ namespace castor3d::shader } return m_computeSheen( pNdotH - , lightSurface.NdotV() + , lightSurface.NdotV().value() , pNdotL , proughness ); } diff --git a/source/Core/Castor3D/Shader/Shaders/GlslSssTransmittance.cpp b/source/Core/Castor3D/Shader/Shaders/GlslSssTransmittance.cpp index ed829399ed..8982301e2e 100644 --- a/source/Core/Castor3D/Shader/Shaders/GlslSssTransmittance.cpp +++ b/source/Core/Castor3D/Shader/Shaders/GlslSssTransmittance.cpp @@ -17,11 +17,13 @@ CU_ImplementSmartPtr( castor3d::shader, SssTransmittance ) namespace castor3d::shader { SssTransmittance::SssTransmittance( sdw::ShaderWriter & writer + , Shadow const & shadows , ShadowOptions shadowOptions , SssProfiles const & sssProfiles ) : m_writer{ writer } + , m_shadows{ shadows } , m_sssProfiles{ sssProfiles } - , m_shadows{ shadowOptions.type } + , m_shadowsType{ shadowOptions.type } { } @@ -31,8 +33,8 @@ namespace castor3d::shader , DirectionalShadowData const & pshadow , LightSurface const & plightSurface ) { - if ( !checkFlag( m_shadows, SceneFlag::eShadowDirectional ) - || !m_writer.hasGlobalVariable( Shadow::MapDepthDirectional ) ) + if ( !checkFlag( m_shadowsType, SceneFlag::eShadowDirectional ) + || !m_shadows.hasMapDepthDirectional() ) { return vec3( 0.0_f ); } @@ -49,7 +51,7 @@ namespace castor3d::shader { auto result = m_writer.declLocale( "result" , vec3( 0.0_f ) ); - auto c3d_mapNormalDepthDirectional = m_writer.getVariable< sdw::CombinedImage2DArrayR32 >( Shadow::MapDepthDirectional ); + auto c3d_mapNormalDepthDirectional = m_shadows.getMapDepthDirectional(); // We shrink the position inwards the surface to avoid artifacts. auto shrinkedPos = m_writer.declLocale( "shrinkedPos" @@ -92,8 +94,8 @@ namespace castor3d::shader , sssTransmittance , plight , pshadow.transforms()[0] - , plightSurface.N() - , plightSurface.worldPosition().xyz() ); + , plightSurface.N().value() + , plightSurface.worldPosition().value().xyz() ); } sdw::Vec3 SssTransmittance::compute( DebugOutput & debugOutput @@ -102,8 +104,8 @@ namespace castor3d::shader , PointShadowData const & pshadow , LightSurface const & plightSurface ) { - if ( !checkFlag( m_shadows, SceneFlag::eShadowPoint ) - || !m_writer.hasGlobalVariable( Shadow::MapDepthPoint ) ) + if ( !checkFlag( m_shadowsType, SceneFlag::eShadowPoint ) + || !m_shadows.hasMapDepthPoint() ) { return vec3( 0.0_f ); } @@ -120,7 +122,7 @@ namespace castor3d::shader { auto result = m_writer.declLocale( "result" , vec3( 0.0_f ) ); - auto c3d_mapNormalDepthPoint = m_writer.getVariable< sdw::CombinedImageCubeArrayR32 >( Shadow::MapDepthPoint ); + auto c3d_mapNormalDepthPoint = m_shadows.getMapDepthPoint(); // We shrink the position inwards the surface to avoid artifacts. auto shrinkedPos = m_writer.declLocale( "shrinkedPos" @@ -156,8 +158,8 @@ namespace castor3d::shader , sssTransmittance , plight , plight.shadowMapIndex() - , plightSurface.N() - , plightSurface.worldPosition().xyz() ); + , plightSurface.N().value() + , plightSurface.worldPosition().value().xyz() ); } sdw::Vec3 SssTransmittance::compute( DebugOutput & debugOutput @@ -166,8 +168,8 @@ namespace castor3d::shader , SpotShadowData const & pshadow , LightSurface const & plightSurface ) { - if ( !checkFlag( m_shadows, SceneFlag::eShadowSpot ) - || !m_writer.hasGlobalVariable( Shadow::MapDepthSpot ) ) + if ( !checkFlag( m_shadowsType, SceneFlag::eShadowSpot ) + || !m_shadows.hasMapDepthSpot() ) { return vec3( 0.0_f ); } @@ -185,7 +187,7 @@ namespace castor3d::shader { auto result = m_writer.declLocale( "result" , vec3( 0.0_f ) ); - auto c3d_mapDepthSpot = m_writer.getVariable< sdw::CombinedImage2DArrayR32 >( Shadow::MapDepthSpot ); + auto c3d_mapDepthSpot = m_shadows.getMapDepthSpot(); // We shrink the position inwards the surface to avoid artifacts. auto shrinkedPos = m_writer.declLocale( "shrinkedPos" @@ -236,8 +238,8 @@ namespace castor3d::shader , plight , pshadow.transform() , plight.shadowMapIndex() - , plightSurface.N() - , plightSurface.worldPosition().xyz() ); + , plightSurface.N().value() + , plightSurface.worldPosition().value().xyz() ); } sdw::Vec3 SssTransmittance::doCompute( DebugOutput & debugOutput diff --git a/source/Core/Castor3D/Shader/Shaders/GlslSurface.cpp b/source/Core/Castor3D/Shader/Shaders/GlslSurface.cpp index d687f60729..e69de29bb2 100644 --- a/source/Core/Castor3D/Shader/Shaders/GlslSurface.cpp +++ b/source/Core/Castor3D/Shader/Shaders/GlslSurface.cpp @@ -1,553 +0,0 @@ -#include "Castor3D/Shader/Shaders/GlslSurface.hpp" - -#include "Castor3D/Render/RenderNodesPass.hpp" -#include "Castor3D/Shader/Shaders/GlslBlendComponents.hpp" -#include "Castor3D/Shader/Shaders/GlslPassShaders.hpp" -#include "Castor3D/Shader/Shaders/GlslSubmeshShaders.hpp" -#include "Castor3D/Shader/Shaders/GlslUtils.hpp" -#include "Castor3D/Shader/Ubos/CameraUbo.hpp" -#include "Castor3D/Shader/Ubos/MorphingUbo.hpp" - -#include -#include - -namespace castor3d::shader -{ - //***************************************************************************************** - - SurfaceBase::SurfaceBase( sdw::ShaderWriter & writer - , ast::expr::ExprPtr expr - , bool enabled ) - : StructInstance{ writer, castor::move( expr ), enabled } - , clipPosition{ this->getMember< sdw::Vec3 >( "clipPosition", true ) } - , viewPosition{ this->getMember< sdw::Vec4 >( "viewPosition", true ) } - , worldPosition{ this->getMember< sdw::Vec4 >( "worldPosition", true ) } - , normal{ this->getMember< sdw::Vec3 >( "normal", true ) } - { - } - - void SurfaceBase::fillType( sdw::type::BaseStruct & type ) - { - type.declMember( "clipPosition", ast::type::Kind::eVec3F ); - type.declMember( "viewPosition", ast::type::Kind::eVec4F ); - type.declMember( "worldPosition", ast::type::Kind::eVec4F ); - type.declMember( "normal", ast::type::Kind::eVec3F ); - } - - void SurfaceBase::fillIOType( sdw::type::IOStruct & type - , PipelineFlags const & flags - , uint32_t & index ) - { - type.declMember( "viewPosition" - , ast::type::Kind::eVec4F - , ast::type::NotArray - , flags.usesViewSpace() ? index++ : 0u - , flags.usesViewSpace() ); - type.declMember( "worldPosition" - , ast::type::Kind::eVec4F - , ast::type::NotArray - , flags.usesWorldSpace() ? index++ : 0u - , flags.usesWorldSpace() ); - type.declMember( "normal" - , ast::type::Kind::eVec3F - , ast::type::NotArray - , flags.enableNormal() ? index++ : 0u - , flags.enableNormal() ); - } - - void SurfaceBase::fillType( sdw::type::BaseStruct & type - , PipelineFlags const & flags ) - { - type.declMember( "clipPosition" - , ast::type::Kind::eVec3F ); - type.declMember( "viewPosition" - , ast::type::Kind::eVec4F - , ast::type::NotArray - , flags.usesViewSpace() ); - type.declMember( "worldPosition" - , ast::type::Kind::eVec4F - , ast::type::NotArray - , flags.usesWorldSpace() ); - type.declMember( "normal" - , ast::type::Kind::eVec3F - , ast::type::NotArray - , flags.enableNormal() ); - } - - void SurfaceBase::fillInit( sdw::expr::ExprList & init - , sdw::Vec3 clip - , sdw::Vec4 view - , sdw::Vec4 world - , sdw::Vec3 normal ) - { - init.emplace_back( makeExpr( clip.isEnabled() ? clip : vec3( 0.0_f ) ) ); - init.emplace_back( makeExpr( view.isEnabled() ? view : vec4( 0.0_f ) ) ); - init.emplace_back( makeExpr( world.isEnabled() ? world : vec4( 0.0_f ) ) ); - init.emplace_back( makeExpr( normal.isEnabled() ? normal : vec3( 0.0_f ) ) ); - } - - void SurfaceBase::fillInit( sdw::expr::ExprList & init - , PipelineFlags const & flags - , sdw::Vec3 clip - , sdw::Vec4 view - , sdw::Vec4 world - , sdw::Vec3 normal ) - { - init.emplace_back( makeExpr( clip ) ); - - if ( flags.usesViewSpace() ) - { - init.emplace_back( makeExpr( vec4( view.xyz(), 1.0_f ) ) ); - } - - if ( flags.usesWorldSpace() ) - { - init.emplace_back( makeExpr( vec4( world.xyz(), 1.0_f ) ) ); - } - - if ( flags.enableNormal() ) - { - init.emplace_back( makeExpr( normal ) ); - } - } - - //***************************************************************************************** - - Surface::Surface( sdw::ShaderWriter & writer - , ast::expr::ExprPtr expr - , bool enabled ) - : SurfaceBase{ writer, castor::move( expr ), enabled } - , texCoord{ this->getMember< sdw::Vec3 >( "texture0" ) } - { - } - - Surface::Surface( sdw::Vec3 clip - , sdw::Vec4 view - , sdw::Vec4 world - , sdw::Vec3 normal - , sdw::Vec3 coord ) - : Surface{ findWriterMandat( clip, view, world, normal, coord ) - , sdw::makeAggrInit( makeType( findTypesCache( clip, view, world, normal, coord ) ) - , [&clip, &view, &world, &normal, &coord]() - { - sdw::expr::ExprList result; - fillInit( result, clip, view, world, normal, coord ); - return result; - }() ) - , true } - { - } - - Surface::Surface( sdw::Vec3 clip - , sdw::Vec3 view - , sdw::Vec3 world - , sdw::Vec3 normal - , sdw::Vec3 coord ) - : Surface{ castor::move( clip ) - , vec4( view, 1.0_f ) - , vec4( world, 1.0_f ) - , castor::move( normal ) - , vec3( 0.0_f ) } - { - } - - Surface::Surface( sdw::Vec3 clip - , sdw::Vec4 view - , sdw::Vec4 world - , sdw::Vec3 normal ) - : Surface{ castor::move( clip ) - , castor::move( view ) - , castor::move( world ) - , castor::move( normal ) - , vec3( 0.0_f ) } - { - } - - Surface::Surface( sdw::Vec3 clip - , sdw::Vec3 view - , sdw::Vec3 world - , sdw::Vec3 normal ) - : Surface{ castor::move( clip ) - , castor::move( view ) - , castor::move( world ) - , castor::move( normal ) - , vec3( 0.0_f ) } - { - } - - Surface::Surface( sdw::Vec3 world - , sdw::Vec3 normal ) - : Surface{ vec3( 0.0_f ) - , vec4( 0.0_f ) - , vec4( world, 1.0_f ) - , castor::move( normal ) - , vec3( 0.0_f ) } - { - } - - ast::type::BaseStructPtr Surface::makeType( ast::type::TypesCache & cache ) - { - auto result = cache.getStruct( ast::type::MemoryLayout::eStd430 - , "C3D_TexSurface" ); - - if ( result->empty() ) - { - fillType( *result ); - } - - return result; - } - - void Surface::fillType( sdw::type::BaseStruct & type ) - { - SurfaceBase::fillType( type ); - type.declMember( "texture0" - , ast::type::Kind::eVec3F ); - } - - void Surface::fillType( sdw::type::BaseStruct & type - , PipelineFlags const & flags ) - { - SurfaceBase::fillType( type, flags ); - type.declMember( "texture0" - , ast::type::Kind::eVec3F - , flags.enableTexcoord0() ); - } - - void Surface::fillInit( sdw::expr::ExprList & init - , sdw::Vec3 clip - , sdw::Vec4 view - , sdw::Vec4 world - , sdw::Vec3 normal - , sdw::Vec3 texCoord ) - { - SurfaceBase::fillInit( init, clip, view, world, normal ); - init.emplace_back( makeExpr( texCoord ) ); - } - - void Surface::fillInit( sdw::expr::ExprList & init - , PipelineFlags const & flags - , sdw::Vec3 clip - , sdw::Vec4 view - , sdw::Vec4 world - , sdw::Vec3 normal - , sdw::Vec3 texCoord ) - { - SurfaceBase::fillInit( init, flags, clip, view, world, normal ); - - if ( flags.enableTexcoord0() ) - { - init.emplace_back( makeExpr( texCoord ) ); - } - } - - //***************************************************************************************** - - RasterizerSurfaceBase::RasterizerSurfaceBase( sdw::ShaderWriter & writer - , sdw::expr::ExprPtr expr - , bool enabled ) - : SurfaceBase{ writer, castor::move( expr ), enabled } - , curPosition{ this->getMember< sdw::Vec4 >( "curPosition", true ) } - , prvPosition{ this->getMember< sdw::Vec4 >( "prvPosition", true ) } - , tangentSpaceFragPosition{ this->getMember< sdw::Vec3 >( "tangentSpaceFragPosition", true ) } - , tangentSpaceViewPosition{ this->getMember< sdw::Vec3 >( "tangentSpaceViewPosition", true ) } - , tangent{ this->getMember< sdw::Vec4 >( "tangent", true ) } - , bitangent{ this->getMember< sdw::Vec3 >( "bitangent", true ) } - , colour{ this->getMember< sdw::Vec3 >( "colour", true ) } - , passMultipliers{ this->getMemberArray< sdw::Vec4 >( "passMultipliers", true ) } - , nodeId{ this->getMember< sdw::UInt >( "nodeId", true ) } - , vertexId{ this->getMember< sdw::UInt >( "vertexId", true ) } - , meshletId{ this->getMember< sdw::UInt >( "meshletId", true ) } - { - } - - void RasterizerSurfaceBase::computeVelocity( CameraData const & cameraData - , sdw::Vec4 & csCurPos - , sdw::Vec4 & csPrvPos ) - { - // Convert the jitter from non-homogeneous coordinates to homogeneous - // coordinates and add it: - // (note that for providing the jitter in non-homogeneous projection space, - // pixel coordinates (screen space) need to multiplied by two in the C++ - // code) - cameraData.jitter( csCurPos ); - cameraData.jitter( csPrvPos ); - - curPosition = vec4( csCurPos.xyw(), 1.0_f ); - prvPosition = vec4( csPrvPos.xyw(), 1.0_f ); - - // Positions in projection space are in [-1, 1] range, while texture - // coordinates are in [0, 1] range. So, we divide by 2 to get velocities in - // the scale (and flip the y axis): - curPosition.xy() *= vec2( 0.5_f, -0.5_f ); - prvPosition.xy() *= vec2( 0.5_f, -0.5_f ); - } - - void RasterizerSurfaceBase::computeTangentSpace( PipelineFlags const & flags - , sdw::Vec3 const & cameraPosition - , sdw::Vec3 const & worldPos - , sdw::Vec3 const & nml - , sdw::Vec4 const & tan ) - { - if ( flags.enableTangentSpace() ) - { - normal = nml; - tangent = tan; - bitangent = tangent.w() * cross( normal, tangent.xyz() ); - - if ( flags.isFrontCulled() ) - { - normal = -normal; - tangent.xyz() = -tangent.xyz(); - bitangent = -bitangent; - } - - if ( !tangentSpaceFragPosition.getExpr()->isDummy() ) - { - CU_Require( !worldPos.getExpr()->isDummy() ); - CU_Require( !tangentSpaceViewPosition.getExpr()->isDummy() ); - auto tbn = getWriter()->declLocale( "tbn" - , transpose( mat3( tangent.xyz(), bitangent, normal ) ) ); - tangentSpaceFragPosition = tbn * worldPos; - tangentSpaceViewPosition = tbn * cameraPosition.xyz(); - } - } - else if ( normal.isEnabled() ) - { - normal = nml; - - if ( flags.isFrontCulled() ) - { - normal = -normal; - } - } - } - - void RasterizerSurfaceBase::computeTangentSpace( PipelineFlags const & flags - , sdw::Vec3 const & cameraPosition - , sdw::Vec3 const & worldPos - , sdw::Mat3 const & mtx - , sdw::Vec3 const & nml - , sdw::Vec4 const & tan ) - { - return computeTangentSpace( flags - , cameraPosition - , worldPos - , normalize( mtx * nml ) - , vec4( normalize( mtx * tan.xyz() ), tan.w() ) ); - } - - void RasterizerSurfaceBase::computeTangentSpace( PipelineFlags const & flags - , sdw::Vec3 const & cameraPosition - , sdw::Vec3 const & worldPos - , sdw::Mat3 const & mtx - , sdw::Vec3 const & nml - , sdw::Vec4 const & tan - , sdw::Vec3 const & bin ) - { - if ( bin.isEnabled() ) - { - return computeTangentSpace( flags - , cameraPosition - , worldPos - , normalize( mtx * nml ) - , vec4( normalize( mtx * tan.xyz() ), tan.w() ) - , vec3( normalize( mtx * bin ) ) ); - } - - return computeTangentSpace( flags - , cameraPosition - , worldPos - , normalize( mtx * nml ) - , vec4( normalize( mtx * tan.xyz() ), tan.w() ) ); - } - - void RasterizerSurfaceBase::computeTangentSpace( PipelineFlags const & flags - , sdw::Vec3 const & cameraPosition - , sdw::Vec3 const & worldPos - , sdw::Vec3 const & nml - , sdw::Vec4 const & tan - , sdw::Vec3 const & bin ) - { - if ( bin.isEnabled() ) - { - if ( flags.enableTangentSpace() ) - { - normal = nml; - tangent = tan; - bitangent = bin; - - if ( flags.isFrontCulled() ) - { - normal = -normal; - tangent.xyz() = -tangent.xyz(); - bitangent = -bitangent; - } - - if ( !tangentSpaceFragPosition.getExpr()->isDummy() ) - { - CU_Require( !worldPos.getExpr()->isDummy() ); - CU_Require( !tangentSpaceViewPosition.getExpr()->isDummy() ); - auto tbn = getWriter()->declLocale( "tbn" - , transpose( mat3( tangent.xyz(), bitangent, normal ) ) ); - tangentSpaceFragPosition = tbn * worldPos; - tangentSpaceViewPosition = tbn * cameraPosition.xyz(); - } - } - else - { - normal = nml; - - if ( flags.isFrontCulled() ) - { - normal = -normal; - } - } - } - else - { - computeTangentSpace( flags, cameraPosition, worldPos, nml, tan ); - } - } - - sdw::Vec2 RasterizerSurfaceBase::getVelocity()const - { - return ( curPosition.xy() / curPosition.z() ) - ( prvPosition.xy() / prvPosition.z() ); - } - - void RasterizerSurfaceBase::fillIOType( sdw::type::IOStruct & type - , SubmeshShaders const & submeshShaders - , PassShaders const & shaders - , PipelineFlags const & flags - , uint32_t & index ) - { - SurfaceBase::fillIOType( type, flags, index ); - type.declMember( "nodeId", ast::type::Kind::eUInt - , ast::type::NotArray - , index ); - ++index; - type.declMember( "vertexId", ast::type::Kind::eUInt - , ast::type::NotArray - , ( flags.enableVertexID() ? index++ : 0 ) - , flags.enableVertexID() ); - type.declMember( "meshletId", ast::type::Kind::eUInt - , ast::type::NotArray - , ( flags.enableMeshletID() ? index++ : 0 ) - , flags.enableMeshletID() ); - type.declMember( "curPosition", ast::type::Kind::eVec4F - , ast::type::NotArray - , ( flags.writeVelocity() ? index++ : 0 ) - , flags.writeVelocity() ); - type.declMember( "prvPosition", ast::type::Kind::eVec4F - , ast::type::NotArray - , ( flags.writeVelocity() ? index++ : 0 ) - , flags.writeVelocity() ); - type.declMember( "tangentSpaceFragPosition" - , ast::type::Kind::eVec3F - , ast::type::NotArray - , ( shaders.enableParallaxOcclusionMapping( flags ) ? index++ : 0 ) - , shaders.enableParallaxOcclusionMapping( flags ) ); - type.declMember( "tangentSpaceViewPosition" - , ast::type::Kind::eVec3F - , ast::type::NotArray - , ( shaders.enableParallaxOcclusionMapping( flags) ? index++ : 0 ) - , shaders.enableParallaxOcclusionMapping( flags ) ); - type.declMember( "tangent", ast::type::Kind::eVec4F - , ast::type::NotArray - , ( flags.enableTangentSpace() ? index++ : 0 ) - , flags.enableTangentSpace() ); - type.declMember( "bitangent", ast::type::Kind::eVec3F - , ast::type::NotArray - , ( ( flags.enableBitangent() || flags.enableTangentSpace() ) ? index++ : 0 ) - , ( flags.enableBitangent() || flags.enableTangentSpace() ) ); - type.declMember( "colour", ast::type::Kind::eVec3F - , ast::type::NotArray - , ( flags.enableColours() ? index++ : 0 ) - , flags.enableColours() ); - type.declMember( "passMultipliers", ast::type::Kind::eVec4F - , 4u - , ( flags.enablePassMasks() ? index : 0 ) - , flags.enablePassMasks() ); - - if ( flags.enablePassMasks() ) - { - index += 4u; - } - - submeshShaders.fillRasterSurface( type, index ); - } - - void RasterizerSurfaceBase::fillType( sdw::type::BaseStruct & type - , SubmeshShaders const & submeshShaders - , PassShaders const & shaders - , PipelineFlags const & flags ) - { - SurfaceBase::fillType( type, flags ); - type.declMember( "nodeId", ast::type::Kind::eUInt - , ast::type::NotArray ); - type.declMember( "vertexId", ast::type::Kind::eUInt - , ast::type::NotArray - , flags.enableVertexID() ); - type.declMember( "meshletId", ast::type::Kind::eUInt - , ast::type::NotArray - , flags.enableMeshletID() ); - type.declMember( "curPosition", ast::type::Kind::eVec4F - , ast::type::NotArray - , flags.writeVelocity() ); - type.declMember( "prvPosition", ast::type::Kind::eVec4F - , ast::type::NotArray - , flags.writeVelocity() ); - type.declMember( "tangentSpaceFragPosition" - , ast::type::Kind::eVec3F - , ast::type::NotArray - , shaders.enableParallaxOcclusionMapping( flags ) ); - type.declMember( "tangentSpaceViewPosition" - , ast::type::Kind::eVec3F - , ast::type::NotArray - , shaders.enableParallaxOcclusionMapping( flags ) ); - type.declMember( "tangent", ast::type::Kind::eVec4F - , ast::type::NotArray - , flags.enableTangentSpace() ); - type.declMember( "bitangent", ast::type::Kind::eVec3F - , ast::type::NotArray - , flags.enableBitangent() || flags.enableTangentSpace() ); - type.declMember( "colour", ast::type::Kind::eVec3F - , ast::type::NotArray - , flags.enableColours() ); - type.declMember( "passMultipliers", ast::type::Kind::eVec4F - , 4u - , flags.enablePassMasks() ); - submeshShaders.fillRasterSurface( type ); - } - - void RasterizerSurfaceBase::fillType( sdw::type::BaseStruct & type - , SubmeshShaders const & submeshShaders ) - { - SurfaceBase::fillType( type ); - type.declMember( "nodeId", ast::type::Kind::eUInt - , ast::type::NotArray ); - type.declMember( "vertexId", ast::type::Kind::eUInt - , ast::type::NotArray ); - type.declMember( "meshletId", ast::type::Kind::eUInt - , ast::type::NotArray ); - type.declMember( "curPosition", ast::type::Kind::eVec4F - , ast::type::NotArray ); - type.declMember( "prvPosition", ast::type::Kind::eVec4F - , ast::type::NotArray ); - type.declMember( "tangentSpaceFragPosition", ast::type::Kind::eVec3F - , ast::type::NotArray ); - type.declMember( "tangentSpaceViewPosition", ast::type::Kind::eVec3F - , ast::type::NotArray ); - type.declMember( "tangent", ast::type::Kind::eVec4F - , ast::type::NotArray ); - type.declMember( "bitangent", ast::type::Kind::eVec3F - , ast::type::NotArray ); - type.declMember( "colour", ast::type::Kind::eVec3F - , ast::type::NotArray ); - type.declMember( "passMultipliers", ast::type::Kind::eVec4F - , 4u ); - submeshShaders.fillRasterSurface( type ); - } - - //***************************************************************************************** -} diff --git a/source/Core/Castor3D/Shader/Shaders/GlslTextureConfiguration.cpp b/source/Core/Castor3D/Shader/Shaders/GlslTextureConfiguration.cpp index e0567b1538..0096686036 100644 --- a/source/Core/Castor3D/Shader/Shaders/GlslTextureConfiguration.cpp +++ b/source/Core/Castor3D/Shader/Shaders/GlslTextureConfiguration.cpp @@ -1,5 +1,6 @@ #include "Castor3D/Shader/Shaders/GlslTextureConfiguration.hpp" +#include "Castor3D/Shader/Shaders/GlslDerivativeValue.hpp" #include "Castor3D/Shader/Shaders/GlslLighting.hpp" #include "Castor3D/Shader/Shaders/GlslMaterial.hpp" #include "Castor3D/Shader/Shaders/GlslTextureAnimation.hpp" @@ -39,7 +40,7 @@ namespace castor3d::shader , TextureTransformData const & anim , DerivTex & uv )const { - uv.uv() = utils.transformUV( *this, anim, uv.uv() ); + uv.value() = utils.transformUV( *this, anim, uv.value() ); } sdw::Float TextureConfigData::getFloat( sdw::Vec4 const & sampled @@ -56,6 +57,22 @@ namespace castor3d::shader , sampled[mask + 2u] ); } + sdw::Vec2 TextureConfigData::getUv( DerivTex const & uvw )const + { + return uvw.value(); + } + + void TextureConfigData::setUv( DerivTex & lhs + , DerivTex const & rhs )const + { + lhs.value() = rhs.value(); + } + + DerivTex TextureConfigData::toUv( DerivTex const & uvw )const + { + return uvw; + } + //********************************************************************************************* TextureConfigurations::TextureConfigurations( sdw::ShaderWriter & writer diff --git a/source/Core/Castor3D/Shader/Shaders/GlslUtils.cpp b/source/Core/Castor3D/Shader/Shaders/GlslUtils.cpp index d6f0b848c6..731a73dab3 100644 --- a/source/Core/Castor3D/Shader/Shaders/GlslUtils.cpp +++ b/source/Core/Castor3D/Shader/Shaders/GlslUtils.cpp @@ -1,6 +1,7 @@ #include "Castor3D/Shader/Shaders/GlslUtils.hpp" #include "Castor3D/Engine.hpp" +#include "Castor3D/Shader/Shaders/GlslDerivativeValue.hpp" #include "Castor3D/Shader/Shaders/GlslLighting.hpp" #include "Castor3D/Shader/Shaders/GlslSurface.hpp" #include "Castor3D/Shader/Shaders/GlslTextureAnimation.hpp" @@ -14,23 +15,6 @@ namespace castor3d::shader { //********************************************************************************************* - sdw::Float DerivTex::computeMip( sdw::Vec2 const & texSize )const - { - // see https://registry.khronos.org/OpenGL/extensions/EXT/EXT_shader_texture_lod.txt - auto dSdx = dPdx().x(); - auto dSdy = dPdy().x(); - auto dTdx = dPdx().y(); - auto dTdy = dPdy().y(); - auto dUdx = texSize.x() * dSdx; - auto dUdy = texSize.x() * dSdy; - auto dVdx = texSize.y() * dTdx; - auto dVdy = texSize.y() * dTdy; - return 0.5_f * log2( max( dUdx * dUdx + dVdx * dVdx - , dUdy * dUdy + dVdy * dVdy ) ); - } - - //********************************************************************************************* - Utils::Utils( sdw::ShaderWriter & writer ) : m_writer{ writer } { @@ -156,7 +140,7 @@ namespace castor3d::shader sdw::Vec4 Utils::sampleMap( sdw::CombinedImage2DRgba32 const map , DerivTex const texCoords ) { - return map.grad( texCoords.uv(), texCoords.dPdx(), texCoords.dPdy() ); + return map.grad( texCoords.value(), texCoords.dPdx(), texCoords.dPdy() ); } sdw::RetVec2 Utils::transformUV( TextureConfigData const & pconfig @@ -605,6 +589,41 @@ namespace castor3d::shader , clamp( f0 * 50.0_f, vec3( 0.0_f ), vec3( 1.0_f ) ) ); } + shader::RetDerivVec3 Utils::conductorFresnel( DerivFloat const & pproduct + , sdw::Vec3 const & pf0 + , sdw::Vec3 const & pf90 ) + { + if ( !m_conductorFresnelDeriv3 ) + { + m_conductorFresnelDeriv3 = m_writer.implementFunction< DerivVec3 >( "c3d_conductorFresnelDeriv3" + , [this]( DerivFloat const & product + , sdw::Vec3 const & f0 + , sdw::Vec3 const & f90 ) + { + auto r00 = m_writer.declLocale( "r00" + , conductorFresnel( product.value(), f0, f90 ) ); + auto r10 = m_writer.declLocale( "r10" + , conductorFresnel( product.value() + product.dPdx(), f0, f90 ) ); + auto r01 = m_writer.declLocale( "r01" + , conductorFresnel( product.value() + product.dPdy(), f0, f90 ) ); + m_writer.returnStmt( DerivVec3{ r00, r10 - r00, r01 - r00 } ); + } + , InDerivFloat{ m_writer, "product" } + , sdw::InVec3{ m_writer, "f0" } + , sdw::InVec3{ m_writer, "f90" } ); + } + + return m_conductorFresnelDeriv3( pproduct, pf0, pf90 ); + } + + RetDerivVec3 Utils::conductorFresnel( DerivFloat const & product + , sdw::Vec3 const & f0 ) + { + return conductorFresnel( product + , f0 + , clamp( f0 * 50.0_f, vec3( 0.0_f ), vec3( 1.0_f ) ) ); + } + sdw::RetFloat Utils::fresnelMix( sdw::Float const & VdotH , sdw::Float const & ior ) { diff --git a/source/Core/Castor3D/Shader/Ubos/CameraUbo.cpp b/source/Core/Castor3D/Shader/Ubos/CameraUbo.cpp index 968d142524..3736757023 100644 --- a/source/Core/Castor3D/Shader/Ubos/CameraUbo.cpp +++ b/source/Core/Castor3D/Shader/Ubos/CameraUbo.cpp @@ -6,6 +6,7 @@ #include "Castor3D/Render/RenderSystem.hpp" #include "Castor3D/Scene/Camera.hpp" #include "Castor3D/Scene/Scene.hpp" +#include "Castor3D/Shader/Shaders/GlslDerivativeValue.hpp" #include "Castor3D/Shader/Shaders/GlslUtils.hpp" #include @@ -21,6 +22,11 @@ namespace castor3d return invProjection() * psPosition; } + DerivVec4 CameraData::projToView( DerivVec4 const & psPosition )const + { + return invProjection() * psPosition; + } + sdw::Vec4 CameraData::viewToProj( sdw::Vec4 const & vsPosition )const { return projection() * vsPosition; @@ -46,6 +52,11 @@ namespace castor3d return invCurView() * vsPosition; } + DerivVec4 CameraData::curViewToWorld( DerivVec4 const & vsPosition )const + { + return invCurView() * vsPosition; + } + sdw::Vec4 CameraData::prvViewToWorld( sdw::Vec4 const & vsPosition )const { return invPrvView() * vsPosition; @@ -61,6 +72,11 @@ namespace castor3d return prvViewProj() * wsPosition; } + DerivVec4 CameraData::worldToPrvProj( DerivVec4 const & wsPosition )const + { + return prvViewProj() * wsPosition; + } + sdw::Vec2 CameraData::viewToScreenUV( Utils & utils , sdw::Vec4 vsPosition )const { @@ -145,6 +161,13 @@ namespace castor3d csPosition.xy() -= jitter() * csPosition.w(); } + void CameraData::jitter( DerivVec4 & csPosition )const + { + csPosition.value().xy() -= jitter() * csPosition.value().w(); + csPosition.dPdx().xy() -= jitter() * csPosition.dPdx().w(); + csPosition.dPdy().xy() -= jitter() * csPosition.dPdy().w(); + } + sdw::Vec3 CameraData::transformCamera( sdw::Mat3 const & transform )const { return transform * position(); diff --git a/source/Core/Castor3D/Shader/Ubos/ModelDataUbo.cpp b/source/Core/Castor3D/Shader/Ubos/ModelDataUbo.cpp index df01f2816d..da11578afe 100644 --- a/source/Core/Castor3D/Shader/Ubos/ModelDataUbo.cpp +++ b/source/Core/Castor3D/Shader/Ubos/ModelDataUbo.cpp @@ -1,6 +1,7 @@ #include "Castor3D/Shader/Ubos/ModelDataUbo.hpp" #include "Castor3D/Limits.hpp" +#include "Castor3D/Shader/Shaders/GlslDerivativeValue.hpp" #include "Castor3D/Shader/Ubos/SkinningUbo.hpp" #include @@ -46,6 +47,11 @@ namespace castor3d::shader return inverse( getModelMtx() ) * pos; } + DerivVec4 ModelData::worldToModel( DerivVec4 const & pos )const + { + return inverse( getModelMtx() ) * pos; + } + sdw::Vec4 ModelData::modelToWorld( sdw::Vec4 const & pos )const { return getModelMtx() * pos; diff --git a/source/Core/CastorUtils/CMakeLists.txt b/source/Core/CastorUtils/CMakeLists.txt index 0aa7eb05dd..7d2f361611 100644 --- a/source/Core/CastorUtils/CMakeLists.txt +++ b/source/Core/CastorUtils/CMakeLists.txt @@ -2,11 +2,11 @@ project( CastorUtils ) set( unofficial-convectionkernels_DIR ${VCPKG_SHARE_DIR}/unofficial-convectionkernels ) set( gli_DIR ${VCPKG_SHARE_DIR}/gli ) -set( minizip_DIR ${VCPKG_SHARE_DIR}/minizip ) find_package( unofficial-convectionkernels CONFIG REQUIRED ) find_package( gli CONFIG REQUIRED ) if ( VCPKG_TOOLCHAIN ) + set( unofficial-minizip_DIR ${VCPKG_SHARE_DIR}/unofficial-minizip ) find_package( unofficial-minizip CONFIG REQUIRED ) set( minizip_LIB unofficial::minizip::minizip ) else () @@ -77,7 +77,6 @@ if ( ZLIB_FOUND AND FreeType_FOUND ) endif () option( CASTOR_USE_TRACK "Enable function tracking" OFF ) - option( CASTOR_DISABLE_DELAYED_INITIALISATION "Replaces castor::DelayedInitialiserT implementation by a dummy one." OFF ) set( CastorBinsDependencies ${CastorBinsDependencies} @@ -223,7 +222,6 @@ if ( ZLIB_FOUND AND FreeType_FOUND ) ${CASTOR_SOURCE_DIR}/include/Core/${PROJECT_NAME}/Design/BlockGuard.hpp ${CASTOR_SOURCE_DIR}/include/Core/${PROJECT_NAME}/Design/ChangeTracked.hpp ${CASTOR_SOURCE_DIR}/include/Core/${PROJECT_NAME}/Design/DataHolder.hpp - ${CASTOR_SOURCE_DIR}/include/Core/${PROJECT_NAME}/Design/DelayedInitialiser.hpp ${CASTOR_SOURCE_DIR}/include/Core/${PROJECT_NAME}/Design/DesignModule.hpp ${CASTOR_SOURCE_DIR}/include/Core/${PROJECT_NAME}/Design/DynamicBitset.hpp ${CASTOR_SOURCE_DIR}/include/Core/${PROJECT_NAME}/Design/DynamicBitset.inl @@ -653,12 +651,6 @@ if ( ZLIB_FOUND AND FreeType_FOUND ) PRIVATE ${CASTOR_EDITORCONFIG_FILE} ) - if ( CASTOR_DISABLE_DELAYED_INITIALISATION ) - target_compile_definitions( ${PROJECT_NAME} - PUBLIC - CU_NoDelayedInit=1 - ) - endif () target_compile_definitions( ${PROJECT_NAME} PUBLIC _UNICODE diff --git a/source/Core/CastorUtils/FileParser/FileParser.cpp b/source/Core/CastorUtils/FileParser/FileParser.cpp index c811de2861..da3868b9f7 100644 --- a/source/Core/CastorUtils/FileParser/FileParser.cpp +++ b/source/Core/CastorUtils/FileParser/FileParser.cpp @@ -91,6 +91,11 @@ namespace castor , uint64_t & lineIndex , size_t & offset ) { + if ( offset == content.size() ) + { + return StringView{}; + } + auto current = std::next( content.begin(), ptrdiff_t( offset ) ); auto it = std::find_if( current , content.end() diff --git a/source/Core/CastorUtils/Platform/MacOS/MacOSFile.cpp b/source/Core/CastorUtils/Platform/MacOS/MacOSFile.cpp index bb8ef7d21a..9ce34157d8 100644 --- a/source/Core/CastorUtils/Platform/MacOS/MacOSFile.cpp +++ b/source/Core/CastorUtils/Platform/MacOS/MacOSFile.cpp @@ -72,19 +72,6 @@ namespace castor } } - static bool isLink( Path const & filePath ) - { - auto cfilePath = toUtf8( filePath ); - struct stat buf; - - if ( lstat( cfilePath.c_str(), &buf ) ) - { - printErrnoName( cuT( "file" ), filePath ); - } - - return S_ISLNK( buf.st_mode ); - } - template< typename TraverseDirT, typename HitFileT > static void traverse( Path const & folderPath , TraverseDirT const & directoryFunction @@ -99,7 +86,7 @@ namespace castor { result = directoryFunction( folderPath / name ); } - else if ( !file::isLink( folderPath / name ) ) + else { fileFunction( folderPath, name ); } diff --git a/source/Plugins/Generic/FFTOceanRendering/FFTWaterComponent.cpp b/source/Plugins/Generic/FFTOceanRendering/FFTWaterComponent.cpp index d7f4c6d9bf..5c50e974d7 100644 --- a/source/Plugins/Generic/FFTOceanRendering/FFTWaterComponent.cpp +++ b/source/Plugins/Generic/FFTOceanRendering/FFTWaterComponent.cpp @@ -186,7 +186,7 @@ namespace ocean_fft finalNormal = -finalNormal; } - components.normal = normalize( finalNormal ); + components.setNormal( normalize( finalNormal ) ); if ( components.hasMember( "waterColourMod" ) ) { diff --git a/source/Plugins/Generic/FFTOceanRendering/FFTWavesComponent.cpp b/source/Plugins/Generic/FFTOceanRendering/FFTWavesComponent.cpp index 017d557cc1..49e02d75b2 100644 --- a/source/Plugins/Generic/FFTOceanRendering/FFTWavesComponent.cpp +++ b/source/Plugins/Generic/FFTOceanRendering/FFTWavesComponent.cpp @@ -514,6 +514,7 @@ namespace ocean_fft sdw::PushConstantBuffer pcb{ writer, "C3D_DrawData", "c3d_drawData" }; auto pipelineID = pcb.declMember< sdw::UInt >( "pipelineID" ); + auto drawID = pcb.declMember< sdw::Int >( "drawID", !engine.getRenderDevice()->hasDrawId() ); pcb.end(); auto tessLevel1f = writer.implementFunction< sdw::Float >( "tessLevel1f" @@ -613,7 +614,7 @@ namespace ocean_fft auto nodeId = writer.declLocale( "nodeId" , shader::getNodeId( c3d_objectIdsData , pipelineID - , writer.cast< sdw::UInt >( in.drawID ) ) ); + , writer.cast< sdw::UInt >( engine.getRenderDevice()->hasDrawId() ? in.drawID : drawID ) ) ); auto modelData = writer.declLocale( "modelData" , c3d_modelsData[nodeId - 1u] ); @@ -660,7 +661,7 @@ namespace ocean_fft , shader::getNodeId( c3d_objectIdsData , in , pipelineID - , writer.cast< sdw::UInt >( in.drawID ) + , writer.cast< sdw::UInt >( engine.getRenderDevice()->hasDrawId() ? in.drawID : drawID ) , flags ) ); auto modelData = writer.declLocale( "modelData" , c3d_modelsData[nodeId - 1u] ); diff --git a/source/Plugins/Generic/FFTOceanRendering/OceanFFT.cpp b/source/Plugins/Generic/FFTOceanRendering/OceanFFT.cpp index 25c1e401ab..77645f765c 100644 --- a/source/Plugins/Generic/FFTOceanRendering/OceanFFT.cpp +++ b/source/Plugins/Generic/FFTOceanRendering/OceanFFT.cpp @@ -12,6 +12,10 @@ #include #include +#include +#include +#include +#include #include #include diff --git a/source/Plugins/Generic/ToonMaterial/Shaders/GlslToonLighting.cpp b/source/Plugins/Generic/ToonMaterial/Shaders/GlslToonLighting.cpp index b009106231..27719df153 100644 --- a/source/Plugins/Generic/ToonMaterial/Shaders/GlslToonLighting.cpp +++ b/source/Plugins/Generic/ToonMaterial/Shaders/GlslToonLighting.cpp @@ -22,26 +22,32 @@ namespace toon::shader { auto & writer = *lightSurface.getWriter(); auto smoothBand = components.getMember< sdw::Float >( "smoothBand", true ); - auto ndotl = smoothStep( 0.0_f - , fwidth( lightSurface.NdotL() ) * smoothBand - , lightSurface.NdotL() ); + auto ndotl = c3d::DerivFloat{ smoothStep( 0.0_f + , fwidth( lightSurface.NdotL() ) * smoothBand + , lightSurface.NdotL().value() ) + , lightSurface.NdotL().dPdx() + , lightSurface.NdotL().dPdy() }; if ( !m_NdotL ) { - m_NdotL = castor::make_unique< sdw::Float >( writer.declLocale( "toonNdotL", castor::move( ndotl ) ) ); + m_NdotL = castor::make_unique< c3d::DerivFloat >( writer.declLocale( "toonNdotL" + , castor::move( ndotl ) ) ); } else { *m_NdotL = ndotl; } - auto ndoth = smoothStep( 0.0_f - , 0.01_f * smoothBand - , lightSurface.NdotH() * getNdotL( lightSurface, components ) ); + auto ndoth = c3d::DerivFloat{ smoothStep( 0.0_f + , 0.01_f * smoothBand + , ( lightSurface.NdotH() * getNdotL( lightSurface, components ) ).value() ) + , lightSurface.NdotH().dPdx() + , lightSurface.NdotH().dPdy() }; if ( !m_NdotH ) { - m_NdotH = castor::make_unique< sdw::Float >( writer.declLocale( "toonNdotH", castor::move( ndoth ) ) ); + m_NdotH = castor::make_unique< c3d::DerivFloat >( writer.declLocale( "toonNdotH" + , castor::move( ndoth ) ) ); } else { @@ -49,13 +55,13 @@ namespace toon::shader } } - sdw::Float ToonLightingModel::getNdotL( c3d::LightSurface const & lightSurface + c3d::DerivFloat ToonLightingModel::getNdotL( c3d::LightSurface const & lightSurface , c3d::BlendComponents const & components ) { return *m_NdotL; } - sdw::Float ToonLightingModel::getNdotH( c3d::LightSurface const & lightSurface + c3d::DerivFloat ToonLightingModel::getNdotH( c3d::LightSurface const & lightSurface , c3d::BlendComponents const & components ) { return *m_NdotH; @@ -110,19 +116,36 @@ namespace toon::shader void ToonPhongLightingModel::doInitLightSpecifics( c3d::LightSurface const & lightSurface , c3d::BlendComponents const & components ) { - initLightSpecifics( lightSurface, components ); + if ( components.hasMember( "smoothBand" ) ) + { + initLightSpecifics( lightSurface, components ); + } + else + { + c3d::PhongLightingModel::doInitLightSpecifics( lightSurface, components ); + } } - sdw::Float ToonPhongLightingModel::doGetNdotL( c3d::LightSurface const & lightSurface + c3d::DerivFloat ToonPhongLightingModel::doGetNdotL( c3d::LightSurface const & lightSurface , c3d::BlendComponents const & components ) { - return getNdotL( lightSurface, components ); + if ( components.hasMember( "smoothBand" ) ) + { + return getNdotL( lightSurface, components ); + } + + return c3d::PhongLightingModel::doGetNdotL( lightSurface, components ); } - sdw::Float ToonPhongLightingModel::doGetNdotH( c3d::LightSurface const & lightSurface + c3d::DerivFloat ToonPhongLightingModel::doGetNdotH( c3d::LightSurface const & lightSurface , c3d::BlendComponents const & components ) { - return getNdotH( lightSurface, components ); + if ( components.hasMember( "smoothBand" ) ) + { + return getNdotH( lightSurface, components ); + } + + return c3d::PhongLightingModel::doGetNdotH( lightSurface, components ); } //********************************************************************************************* @@ -174,19 +197,36 @@ namespace toon::shader void ToonPbrLightingModel::doInitLightSpecifics( c3d::LightSurface const & lightSurface , c3d::BlendComponents const & components ) { - initLightSpecifics( lightSurface, components ); + if ( components.hasMember( "smoothBand" ) ) + { + initLightSpecifics( lightSurface, components ); + } + else + { + c3d::PbrLightingModel::doInitLightSpecifics( lightSurface, components ); + } } - sdw::Float ToonPbrLightingModel::doGetNdotL( c3d::LightSurface const & lightSurface + c3d::DerivFloat ToonPbrLightingModel::doGetNdotL( c3d::LightSurface const & lightSurface , c3d::BlendComponents const & components ) { - return getNdotL( lightSurface, components ); + if ( components.hasMember( "smoothBand" ) ) + { + return getNdotL( lightSurface, components ); + } + + return c3d::PbrLightingModel::doGetNdotL( lightSurface, components ); } - sdw::Float ToonPbrLightingModel::doGetNdotH( c3d::LightSurface const & lightSurface + c3d::DerivFloat ToonPbrLightingModel::doGetNdotH( c3d::LightSurface const & lightSurface , c3d::BlendComponents const & components ) { - return getNdotH( lightSurface, components ); + if ( components.hasMember( "smoothBand" ) ) + { + return getNdotH( lightSurface, components ); + } + + return c3d::PbrLightingModel::doGetNdotH( lightSurface, components ); } //********************************************************************************************* diff --git a/source/Plugins/Generic/ToonMaterial/Shaders/GlslToonLighting.hpp b/source/Plugins/Generic/ToonMaterial/Shaders/GlslToonLighting.hpp index c063a1e8ee..4c4f98e2f6 100644 --- a/source/Plugins/Generic/ToonMaterial/Shaders/GlslToonLighting.hpp +++ b/source/Plugins/Generic/ToonMaterial/Shaders/GlslToonLighting.hpp @@ -32,14 +32,14 @@ namespace toon::shader protected: void initLightSpecifics( c3d::LightSurface const & lightSurface , c3d::BlendComponents const & components ); - sdw::Float getNdotL( c3d::LightSurface const & lightSurface + c3d::DerivFloat getNdotL( c3d::LightSurface const & lightSurface , c3d::BlendComponents const & components ); - sdw::Float getNdotH( c3d::LightSurface const & lightSurface + c3d::DerivFloat getNdotH( c3d::LightSurface const & lightSurface , c3d::BlendComponents const & components ); private: - castor::RawUniquePtr< sdw::Float > m_NdotL; - castor::RawUniquePtr< sdw::Float > m_NdotH; + castor::RawUniquePtr< c3d::DerivFloat > m_NdotL; + castor::RawUniquePtr< c3d::DerivFloat > m_NdotH; }; class ToonPhongLightingModel @@ -69,9 +69,9 @@ namespace toon::shader protected: void doInitLightSpecifics( c3d::LightSurface const & lightSurface , c3d::BlendComponents const & components )override; - sdw::Float doGetNdotL( c3d::LightSurface const & lightSurface + c3d::DerivFloat doGetNdotL( c3d::LightSurface const & lightSurface , c3d::BlendComponents const & components )override; - sdw::Float doGetNdotH( c3d::LightSurface const & lightSurface + c3d::DerivFloat doGetNdotH( c3d::LightSurface const & lightSurface , c3d::BlendComponents const & components )override; }; @@ -102,9 +102,9 @@ namespace toon::shader protected: void doInitLightSpecifics( c3d::LightSurface const & lightSurface , c3d::BlendComponents const & components )override; - sdw::Float doGetNdotL( c3d::LightSurface const & lightSurface + c3d::DerivFloat doGetNdotL( c3d::LightSurface const & lightSurface , c3d::BlendComponents const & components )override; - sdw::Float doGetNdotH( c3d::LightSurface const & lightSurface + c3d::DerivFloat doGetNdotH( c3d::LightSurface const & lightSurface , c3d::BlendComponents const & components )override; }; } diff --git a/source/Plugins/Generic/WaterMaterial/WaterComponent.cpp b/source/Plugins/Generic/WaterMaterial/WaterComponent.cpp index 2aea77f041..c23a35d57e 100644 --- a/source/Plugins/Generic/WaterMaterial/WaterComponent.cpp +++ b/source/Plugins/Generic/WaterMaterial/WaterComponent.cpp @@ -476,9 +476,9 @@ namespace water auto & writer{ *components.getWriter() }; auto tbn = writer.declLocale( "waterTBN" - , castor3d::shader::Utils::getTBN( components.normal - , components.getMember< sdw::Vec4 >( "tangent" ).xyz() - , components.getMember< sdw::Vec3 >( "bitangent" ) ) ); + , castor3d::shader::Utils::getTBN( components.getRawNormal() + , components.getRawTangent().xyz() + , components.getRawBitangent() ) ); auto finalNormal = writer.declLocale( "finalNormal" , vec3( 0.0_f ) ); @@ -502,7 +502,7 @@ namespace water finalNormal = -finalNormal; } - components.normal = normalize( finalNormal ); + components.setNormal( normalize( finalNormal ) ); } if ( components.hasMember( "transmission" ) ) diff --git a/source/Plugins/Generic/WaterMaterial/WaterFoamMapComponent.cpp b/source/Plugins/Generic/WaterMaterial/WaterFoamMapComponent.cpp index aa47d5b2de..7dc46258d4 100644 --- a/source/Plugins/Generic/WaterMaterial/WaterFoamMapComponent.cpp +++ b/source/Plugins/Generic/WaterMaterial/WaterFoamMapComponent.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -181,7 +182,7 @@ namespace water if ( checkFlag( passShaders.getFilter(), ComponentModeFlag::eDerivTex ) ) { auto texCoords = components.getMember< castor3d::shader::DerivTex >( "texCoords" ); - waterFoamNoiseUV = texCoords.uv(); + waterFoamNoiseUV = texCoords.value(); } else if ( passShaders.getPassCombine().baseId == 0u ) { diff --git a/source/Plugins/Generic/WaterMaterial/WaterNoiseMapComponent.cpp b/source/Plugins/Generic/WaterMaterial/WaterNoiseMapComponent.cpp index 172935a53b..55e41813df 100644 --- a/source/Plugins/Generic/WaterMaterial/WaterNoiseMapComponent.cpp +++ b/source/Plugins/Generic/WaterMaterial/WaterNoiseMapComponent.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -184,7 +185,7 @@ namespace water if ( checkFlag( passShaders.getFilter(), ComponentModeFlag::eDerivTex ) ) { auto texCoords = components.getMember< castor3d::shader::DerivTex >( "texCoords" ); - texCoords.uv() *= 0.5_f * tiling; + texCoords.value() *= 0.5_f * tiling; } else if ( passShaders.getPassCombine().baseId == 0u ) { diff --git a/source/Plugins/Generic/WaterMaterial/WaterNormal1MapComponent.cpp b/source/Plugins/Generic/WaterMaterial/WaterNormal1MapComponent.cpp index a71ab54260..9698a77c2a 100644 --- a/source/Plugins/Generic/WaterMaterial/WaterNormal1MapComponent.cpp +++ b/source/Plugins/Generic/WaterMaterial/WaterNormal1MapComponent.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/source/Plugins/Generic/WaterMaterial/WaterNormal2MapComponent.cpp b/source/Plugins/Generic/WaterMaterial/WaterNormal2MapComponent.cpp index 34e79e1a76..f81999d066 100644 --- a/source/Plugins/Generic/WaterMaterial/WaterNormal2MapComponent.cpp +++ b/source/Plugins/Generic/WaterMaterial/WaterNormal2MapComponent.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/source/Plugins/Generic/WaterMaterial/WaterReflRefrComponent.cpp b/source/Plugins/Generic/WaterMaterial/WaterReflRefrComponent.cpp index f57ccbc559..d0a9542be2 100644 --- a/source/Plugins/Generic/WaterMaterial/WaterReflRefrComponent.cpp +++ b/source/Plugins/Generic/WaterMaterial/WaterReflRefrComponent.cpp @@ -131,8 +131,8 @@ namespace water debugOutputBlock.registerOutput( cuT( "Background Reflection" ), backgroundReflection ); auto ssrResult = writer.declLocale( "ssrResult" , reflections.computeScreenSpace( camera - , lightSurface.viewPosition() - , components.normal + , lightSurface.viewPosition().value() + , components.getRawNormal() , hdrCoords , vec4( ssrStepSize , writer.cast< sdw::Float >( ssrForwardStepsCount ) @@ -155,9 +155,9 @@ namespace water auto distanceFactor = writer.declLocale( "distanceFactor" , refractionDistanceFactor * ( camera.farPlane() - camera.nearPlane() ) ); auto distortedTexCoord = writer.declLocale( "distortedTexCoord" - , fma( ( components.normal.xz() + components.normal.xy() ) * 0.5_f + , fma( ( components.getRawNormal().xz() + components.getRawNormal().xy() ) * 0.5_f , vec2( ( ( components.hasMember( "mdlPosition" ) && components.hasMember( "waterDensity" ) ) - ? refractionDistortionFactor * utils.saturate( length( scenePosition - lightSurface.worldPosition().xyz() ) * 0.5_f ) + ? refractionDistortionFactor * utils.saturate( length( scenePosition - lightSurface.worldPosition().value().xyz() ) * 0.5_f ) : refractionDistortionFactor ) ) , hdrCoords ) ); auto distortedDepth = writer.declLocale( "distortedDepth" @@ -165,7 +165,7 @@ namespace water auto distortedPosition = writer.declLocale( "distortedPosition" , camera.curProjToWorld( utils, distortedTexCoord, distortedDepth ) ); auto refractionTexCoord = writer.declLocale( "refractionTexCoord" - , writer.ternary( distortedPosition.y() < lightSurface.worldPosition().y(), distortedTexCoord, hdrCoords ) ); + , writer.ternary( distortedPosition.y() < lightSurface.worldPosition().value().y(), distortedTexCoord, hdrCoords ) ); refractionResult = mapColours.lod( refractionTexCoord, 0.0_f ).rgb(); debugOutputBlock.registerOutput( cuT( "Raw Refraction" ), refractionResult ); auto waterTransmission = writer.declLocale( "waterTransmission" @@ -195,17 +195,17 @@ namespace water // Depth softening, to fade the alpha of the water where it meets the scene geometry by some predetermined distance. auto depthSoftenedAlpha = writer.declLocale( "depthSoftenedAlpha" - , clamp( distance( scenePosition, lightSurface.worldPosition().xyz() ) / depthSofteningDistance, 0.0_f, 1.0_f ) ); + , clamp( distance( scenePosition, lightSurface.worldPosition().value().xyz() ) / depthSofteningDistance, 0.0_f, 1.0_f ) ); debugOutputBlock.registerOutput( cuT( "Depth Softened Alpha" ), depthSoftenedAlpha ); auto waterSurfacePosition = writer.declLocale( "waterSurfacePosition" - , writer.ternary( distortedPosition.y() < lightSurface.worldPosition().y(), distortedPosition, scenePosition ) ); + , writer.ternary( distortedPosition.y() < lightSurface.worldPosition().value().y(), distortedPosition, scenePosition ) ); refractionResult = mix( refractionResult , waterTransmission - , vec3( clamp( ( lightSurface.worldPosition().y() - waterSurfacePosition.y() ) / heightFactor, 0.0_f, 1.0_f ) ) ); + , vec3( clamp( ( lightSurface.worldPosition().value().y() - waterSurfacePosition.y() ) / heightFactor, 0.0_f, 1.0_f ) ) ); debugOutputBlock.registerOutput( cuT( "Height Mixed Refraction" ), refractionResult ); refractionResult = mix( refractionResult , waterTransmission - , utils.saturate( vec3( utils.saturate( length( lightSurface.viewPosition() ) / distanceFactor ) ) ) ); + , utils.saturate( vec3( utils.saturate( length( lightSurface.viewPosition().value() ) / distanceFactor ) ) ) ); debugOutputBlock.registerOutput( cuT( "Distance Mixed Refraction" ), refractionResult ); if ( components.hasMember( "waterNoise" ) ) @@ -235,7 +235,7 @@ namespace water debugOutputBlock.registerOutput( cuT( "Foam Noise" ), waterFoamNoise ); debugOutputBlock.registerOutput( cuT( "Foam Colour" ), waterFoam ); auto foamAmount = writer.declLocale( "foamAmount" - , utils.saturate( ( lightSurface.worldPosition().w() - foamHeightStart ) / foamFadeDistance ) * pow( utils.saturate( dot( components.normal, vec3( 0.0_f, 1.0_f, 0.0_f ) ) ), foamAngleExponent ) * waterFoamNoise ); + , utils.saturate( ( lightSurface.worldPosition().value().w() - foamHeightStart ) / foamFadeDistance ) * pow( utils.saturate( dot( components.getRawNormal(), vec3( 0.0_f, 1.0_f, 0.0_f ) ) ), foamAngleExponent ) * waterFoamNoise ); debugOutputBlock.registerOutput( cuT( "Raw Foam Amount" ), foamAmount ); foamAmount += pow( ( 1.0_f - depthSoftenedAlpha ), 3.0_f ); debugOutputBlock.registerOutput( cuT( "Depth Softened Foam Amount" ), foamAmount ); @@ -250,7 +250,7 @@ namespace water auto fresnelFactor = writer.declLocale( "fresnelFactor" , utils.fresnelMix( incident - , components.normal + , components.getRawNormal() , components.refractionRatio ) ); debugOutputBlock.registerOutput( cuT( "Fresnel Factor" ), fresnelFactor ); reflectionResult *= fresnelFactor; diff --git a/source/Plugins/Generic/WavesRendering/WavesComponent.cpp b/source/Plugins/Generic/WavesRendering/WavesComponent.cpp index 9dc322b3fa..fefea19a2c 100644 --- a/source/Plugins/Generic/WavesRendering/WavesComponent.cpp +++ b/source/Plugins/Generic/WavesRendering/WavesComponent.cpp @@ -353,6 +353,7 @@ namespace waves sdw::PushConstantBuffer pcb{ writer, "C3D_DrawData", "c3d_drawData" }; auto pipelineID = pcb.declMember< sdw::UInt >( "pipelineID" ); + auto drawID = pcb.declMember< sdw::Int >( "drawID", !engine.getRenderDevice()->hasDrawId() ); pcb.end(); auto calculateWave = writer.implementFunction< shd::WaveResult >( "calculateWave" @@ -428,7 +429,7 @@ namespace waves auto nodeId = writer.declLocale( "nodeId" , shader::getNodeId( c3d_objectIdsData , pipelineID - , writer.cast< sdw::UInt >( in.drawID ) ) ); + , writer.cast< sdw::UInt >( engine.getRenderDevice()->hasDrawId() ? in.drawID : drawID ) ) ); auto modelData = writer.declLocale( "modelData" , c3d_modelsData[nodeId - 1u] ); out.nodeId = writer.cast< sdw::Int >( nodeId ); @@ -475,7 +476,7 @@ namespace waves , shader::getNodeId( c3d_objectIdsData , in , pipelineID - , writer.cast< sdw::UInt >( in.drawID ) + , writer.cast< sdw::UInt >( engine.getRenderDevice()->hasDrawId() ? in.drawID : drawID ) , flags ) ); out.vtx.position = in.position; out.texture0 = in.texture0; diff --git a/source/Plugins/Importers/AssimpImporter/CMakeLists.txt b/source/Plugins/Importers/AssimpImporter/CMakeLists.txt index d8b0d66e3c..906aa215fd 100644 --- a/source/Plugins/Importers/AssimpImporter/CMakeLists.txt +++ b/source/Plugins/Importers/AssimpImporter/CMakeLists.txt @@ -6,14 +6,18 @@ if ( VCPKG_TOOLCHAIN ) endif () if ( VCPKG_BUILD OR ( VCPKG_TOOLCHAIN AND NOT CASTOR_USE_SYSTEM_ASSIMP ) ) - set( irrlicht_DIR ${VCPKG_SHARE_DIR}/irrlicht ) - set( polyclipping_DIR ${VCPKG_SHARE_DIR}/polyclipping ) - set( minizip_DIR ${VCPKG_SHARE_DIR}/minizip ) + set( draco_DIR ${VCPKG_SHARE_DIR}/draco ) set( kubazip_DIR ${VCPKG_SHARE_DIR}/kubazip ) + set( minizip_DIR ${VCPKG_SHARE_DIR}/unofficial-minizip ) + set( unofficial-minizip_DIR ${VCPKG_SHARE_DIR}/unofficial-minizip ) set( poly2tri_DIR ${VCPKG_SHARE_DIR}/poly2tri ) + set( polyclipping_DIR ${VCPKG_SHARE_DIR}/polyclipping ) set( pugixml_DIR ${VCPKG_SHARE_DIR}/pugixml ) set( RapidJSON_DIR ${VCPKG_SHARE_DIR}/rapidjson ) + set( stb_DIR ${VCPKG_SHARE_DIR}/stb ) set( utf8cpp_DIR ${VCPKG_SHARE_DIR}/utf8cpp ) + set( zlib_DIR ${VCPKG_SHARE_DIR}/zlib ) + set( ZLIB_DIR ${VCPKG_SHARE_DIR}/zlib ) if ( VCPKG_BUILD ) find_library( ZLIB_LIBRARY_DEBUG zlib PATHS ${_VCPKG_INSTALLED_DIR}/debug/lib ) find_library( ZLIB_LIBRARY_RELEASE zlib PATHS ${_VCPKG_INSTALLED_DIR}/lib ) diff --git a/source/Plugins/Importers/GltfImporter/GltfAnimationImporter.cpp b/source/Plugins/Importers/GltfImporter/GltfAnimationImporter.cpp index 4fee24c915..f4b09cdc42 100644 --- a/source/Plugins/Importers/GltfImporter/GltfAnimationImporter.cpp +++ b/source/Plugins/Importers/GltfImporter/GltfAnimationImporter.cpp @@ -335,12 +335,17 @@ namespace c3d_gltf , lookup.second.end() , [&result, meshIndex, &file]( AnimationChannelSampler const & channelSampler ) { - auto & node = file.getAsset().nodes[channelSampler.first.nodeIndex]; - bool ret{ node.meshIndex && *node.meshIndex == meshIndex }; + bool ret = bool( channelSampler.first.nodeIndex ); if ( ret ) { - result = channelSampler.first.nodeIndex; + auto & node = file.getAsset().nodes[*channelSampler.first.nodeIndex]; + ret = node.meshIndex && ( *node.meshIndex == meshIndex ); + + if ( ret ) + { + result = *channelSampler.first.nodeIndex; + } } return ret; diff --git a/source/Plugins/Importers/GltfImporter/GltfImporterFile.cpp b/source/Plugins/Importers/GltfImporter/GltfImporterFile.cpp index 39e0a15a01..e994b3276f 100644 --- a/source/Plugins/Importers/GltfImporter/GltfImporterFile.cpp +++ b/source/Plugins/Importers/GltfImporter/GltfImporterFile.cpp @@ -62,18 +62,14 @@ namespace c3d_gltf return fastgltf::Expected< fastgltf::Asset >( fastgltf::Error::InvalidPath ); } - auto type = fastgltf::determineGltfFileType( &data ); - - if ( type != fastgltf::GltfType::glTF - && type != fastgltf::GltfType::GLB ) + if ( auto type = fastgltf::determineGltfFileType( &data ); + type != fastgltf::GltfType::glTF && type != fastgltf::GltfType::GLB ) { castor3d::log::error << "Failed to determine glTF container" << std::endl; return fastgltf::Expected< fastgltf::Asset >( fastgltf::Error::InvalidPath ); } - auto result = type == fastgltf::GltfType::glTF - ? parser.loadGLTF( &data, path.parent_path(), gltfOptions ) - : parser.loadBinaryGLTF( &data, path.parent_path(), gltfOptions ); + auto result = parser.loadGltf( &data, path.parent_path(), gltfOptions ); if ( result.error() != fastgltf::Error::None ) { @@ -334,9 +330,10 @@ namespace c3d_gltf , fastgltf::AnimationChannel const & channel , GltfSubmeshData const & submeshData ) { - return *asset.nodes[channel.nodeIndex].meshIndex == submeshData.meshIndex + return channel.nodeIndex + && ( *asset.nodes[*channel.nodeIndex].meshIndex == submeshData.meshIndex ) && channel.path == fastgltf::AnimationPath::Weights - && asset.nodes[channel.nodeIndex].meshIndex; + && asset.nodes[*channel.nodeIndex].meshIndex; } template< typename DataT > @@ -519,11 +516,11 @@ namespace c3d_gltf //********************************************************************************************* - castor3d::NodeTransform convert( std::variant< fastgltf::Node::TRS, fastgltf::Node::TransformMatrix > const & transform ) + castor3d::NodeTransform convert( std::variant< fastgltf::TRS, fastgltf::Node::TransformMatrix > const & transform ) { if ( transform.index() == 0u ) { - fastgltf::Node::TRS const & trs = std::get< 0 >( transform ); + fastgltf::TRS const & trs = std::get< 0 >( transform ); return { convert( trs.translation ) , convert( trs.scale ) , convert( trs.rotation ) }; @@ -757,8 +754,9 @@ namespace c3d_gltf if ( ( channel.path == fastgltf::AnimationPath::Rotation || channel.path == fastgltf::AnimationPath::Scale || channel.path == fastgltf::AnimationPath::Translation ) - && isSkeletonNode( channel.nodeIndex ) - && skeleton.findNode( getNodeName( channel.nodeIndex, 0u ) ) != nullptr ) + && channel.nodeIndex + && isSkeletonNode( *channel.nodeIndex ) + && skeleton.findNode( getNodeName( *channel.nodeIndex, 0u ) ) != nullptr ) { auto & channelSamplers = result.emplace( getAnimationName( index ), AnimationChannelSamplers{} ).first->second; auto & nodeSamplers = channelSamplers.emplace( channel.path, NodeAnimationChannelSampler{} ).first->second; @@ -971,7 +969,8 @@ namespace c3d_gltf if ( ( channel.path == fastgltf::AnimationPath::Rotation || channel.path == fastgltf::AnimationPath::Scale || channel.path == fastgltf::AnimationPath::Translation ) - && isSkeletonNode( channel.nodeIndex ) ) + && channel.nodeIndex + && isSkeletonNode( *channel.nodeIndex ) ) { result.insert( getAnimationName( index ) ); } @@ -1039,7 +1038,8 @@ namespace c3d_gltf if ( ( channel.path == fastgltf::AnimationPath::Rotation || channel.path == fastgltf::AnimationPath::Scale || channel.path == fastgltf::AnimationPath::Translation ) - && isSkeletonNode( channel.nodeIndex ) ) + && channel.nodeIndex + && isSkeletonNode( *channel.nodeIndex ) ) { result.insert( getAnimationName( index ) ); } diff --git a/source/Plugins/Importers/GltfImporter/GltfImporterFile.hpp b/source/Plugins/Importers/GltfImporter/GltfImporterFile.hpp index 4c2e46b485..66d93127ed 100644 --- a/source/Plugins/Importers/GltfImporter/GltfImporterFile.hpp +++ b/source/Plugins/Importers/GltfImporter/GltfImporterFile.hpp @@ -11,7 +11,7 @@ See LICENSE file in root folder # undef None #endif #pragma warning( disable: 4715 ) -#include +#include #include #include @@ -61,7 +61,7 @@ namespace c3d_gltf { inline const castor::String DefaultMaterial = cuT( "GLTF_DefaultMaterial" ); - castor3d::NodeTransform convert( std::variant< fastgltf::Node::TRS, fastgltf::Node::TransformMatrix > const & transform ); + castor3d::NodeTransform convert( std::variant< fastgltf::TRS, fastgltf::Node::TransformMatrix > const & transform ); castor::Point3f convert( castor::Array< float, 3u > const & value ); castor::Quaternion convert( castor::Array< float, 4u > const & value ); diff --git a/source/Plugins/Importers/GltfImporter/GltfMaterialImporter.cpp b/source/Plugins/Importers/GltfImporter/GltfMaterialImporter.cpp index c223500a77..62a253067d 100644 --- a/source/Plugins/Importers/GltfImporter/GltfMaterialImporter.cpp +++ b/source/Plugins/Importers/GltfImporter/GltfMaterialImporter.cpp @@ -69,7 +69,7 @@ namespace c3d_gltf { static castor3d::LightingModelID getLightingModel( castor3d::Engine const & engine ) { - auto & factory = engine.getLightingModelFactory(); + auto const & factory = engine.getLightingModelFactory(); return factory.getNameId( castor::String{ castor3d::PbrPass::LightingModel } ); } @@ -117,14 +117,12 @@ namespace c3d_gltf return cuT( "ktx" ); case fastgltf::MimeType::DDS: return cuT( "dds" ); - case fastgltf::MimeType::None: default: - return cuT( "" ); + return cuT( "png" ); } } - static castor::ByteArray getData( fastgltf::Asset const & impAsset - , fastgltf::sources::URI const & impData + static castor::ByteArray getData( fastgltf::sources::URI const & impData , size_t offset , size_t size ) { @@ -140,8 +138,7 @@ namespace c3d_gltf return result; } - static castor::ByteArray getData( fastgltf::Asset const & impAsset - , fastgltf::sources::Vector const & impData + static castor::ByteArray getData( fastgltf::sources::Array const & impData , size_t offset , size_t size ) { @@ -152,17 +149,26 @@ namespace c3d_gltf return result; } - static castor::ByteArray getData( fastgltf::Asset const & impAsset - , fastgltf::sources::CustomBuffer const & impData + static castor::ByteArray getData( fastgltf::sources::Vector const & impData , size_t offset , size_t size ) + { + castor::ByteArray result; + size = std::min( size, impData.bytes.size() ); + result.resize( size ); + std::memcpy( result.data(), impData.bytes.data() + offset, size ); + return result; + } + + static castor::ByteArray getData( CU_UnusedParam( fastgltf::sources::CustomBuffer const &, impData ) + , CU_UnusedParam( size_t, offset ) + , CU_UnusedParam( size_t, size ) ) { castor::ByteArray result; return result; } - static castor::ByteArray getData( fastgltf::Asset const & impAsset - , fastgltf::sources::ByteView const & impData + static castor::ByteArray getData( fastgltf::sources::ByteView const & impData , size_t offset , size_t size ) { @@ -194,6 +200,38 @@ namespace c3d_gltf return cuT( "Image_" ) + texName + cuT( "_" ) + imgName; } + static castor3d::SamplerRPtr loadSampler( GltfImporterFile const & file + , fastgltf::Asset const & impAsset + , fastgltf::Optional< size_t > const & samplerIndex ) + { + auto & engine = *file.getOwner(); + + if ( samplerIndex + && *samplerIndex < impAsset.samplers.size() ) + { + fastgltf::Sampler const & impSampler = impAsset.samplers[*samplerIndex]; + auto defaultSampler = engine.getDefaultSampler(); + auto & cache = engine.getSamplerCache(); + auto name = file.getSamplerName( impSampler ); + + if ( !cache.has( name ) ) + { + auto sampler = engine.createSampler( name, engine ); + sampler->setMinFilter( impSampler.minFilter ? convert( *impSampler.minFilter ) : defaultSampler->getMinFilter() ); + sampler->setMagFilter( impSampler.magFilter ? convert( *impSampler.magFilter ) : defaultSampler->getMagFilter() ); + sampler->setMipFilter( impSampler.minFilter ? getMipFilter( *impSampler.minFilter ) : defaultSampler->getMipFilter() ); + sampler->setWrapS( convert( impSampler.wrapS ) ); + sampler->setWrapT( convert( impSampler.wrapT ) ); + sampler->setWrapR( defaultSampler->getWrapR() ); + cache.add( name, sampler, false ); + } + + return cache.find( name ); + } + + return engine.getDefaultSampler(); + } + static castor::RawUniquePtr< castor3d::TextureSourceInfo > loadTexture( fastgltf::Asset const & impAsset , castor::String const & name , fastgltf::Texture const & impTexture @@ -218,19 +256,23 @@ namespace c3d_gltf { case 2: mimeType = std::get< 2 >( impDataSource ).mimeType; - data = getData( impAsset, std::get< 2 >( impDataSource ), offset, size ); + data = getData( std::get< 2 >( impDataSource ), offset, size ); break; case 3: mimeType = std::get< 3 >( impDataSource ).mimeType; - data = getData( impAsset, std::get< 3 >( impDataSource ), offset, size ); + data = getData( std::get< 3 >( impDataSource ), offset, size ); break; case 4: mimeType = std::get< 4 >( impDataSource ).mimeType; - data = getData( impAsset, std::get< 4 >( impDataSource ), offset, size ); + data = getData( std::get< 4 >( impDataSource ), offset, size ); break; case 5: mimeType = std::get< 5 >( impDataSource ).mimeType; - data = getData( impAsset, std::get< 5 >( impDataSource ), offset, size ); + data = getData( std::get< 5 >( impDataSource ), offset, size ); + break; + case 6: + mimeType = std::get< 6 >( impDataSource ).mimeType; + data = getData( std::get< 6 >( impDataSource ), offset, size ); break; default: break; @@ -247,40 +289,7 @@ namespace c3d_gltf return nullptr; } - static castor3d::SamplerRPtr loadSampler( GltfImporterFile const & file - , fastgltf::Asset const & impAsset - , fastgltf::Optional< size_t > const & samplerIndex ) - { - auto & engine = *file.getOwner(); - - if ( samplerIndex - && *samplerIndex < impAsset.samplers.size() ) - { - fastgltf::Sampler const & impSampler = impAsset.samplers[*samplerIndex]; - auto defaultSampler = engine.getDefaultSampler(); - auto & cache = engine.getSamplerCache(); - auto name = file.getSamplerName( impSampler ); - - if ( !cache.has( name ) ) - { - auto sampler = engine.createSampler( name, engine ); - sampler->setMinFilter( impSampler.minFilter ? convert( *impSampler.minFilter ) : defaultSampler->getMinFilter() ); - sampler->setMagFilter( impSampler.magFilter ? convert( *impSampler.magFilter ) : defaultSampler->getMagFilter() ); - sampler->setMipFilter( impSampler.minFilter ? getMipFilter( *impSampler.minFilter ) : defaultSampler->getMipFilter() ); - sampler->setWrapS( convert( impSampler.wrapS ) ); - sampler->setWrapT( convert( impSampler.wrapT ) ); - sampler->setWrapR( defaultSampler->getWrapR() ); - cache.add( name, sampler, false ); - } - - return cache.find( name ); - } - - return engine.getDefaultSampler(); - } - - static castor::RawUniquePtr< castor3d::TextureSourceInfo > loadTexture( GltfImporterFile const & file - , fastgltf::Asset const & impAsset + static castor::RawUniquePtr< castor3d::TextureSourceInfo > loadTexture( fastgltf::Asset const & impAsset , fastgltf::TextureInfo const & texInfo , castor3d::TextureConfiguration const & texConfig , castor3d::MaterialImporter & importer ) @@ -306,9 +315,9 @@ namespace c3d_gltf } static castor::Image const & loadImage( castor3d::TextureSourceInfo const & source - , castor3d::MaterialImporter & importer ) + , castor3d::MaterialImporter const & importer ) { - castor::ImageRPtr result{}; + castor::Image const * result{}; if ( source.isBufferImage() ) { @@ -332,12 +341,12 @@ namespace c3d_gltf return *result; } - static void parseTransform( castor::RawUniquePtr< fastgltf::TextureTransform > const & transform + static void parseTransform( fastgltf::TextureTransform const & transform , castor3d::TextureTransform & result , uint32_t & texCoordIndex ) { - result.scale = { transform->uvScale[0], transform->uvScale[1], 1.0f }; - result.rotate = castor::Angle::fromRadians( -transform->rotation );// must be negated + result.scale = { transform.uvScale[0], transform.uvScale[1], 1.0f }; + result.rotate = castor::Angle::fromRadians( -transform.rotation );// must be negated // A change of coordinates is required to map glTF UV transformations into the space used by // Castor3D. In glTF all UV origins are at 0,1 (top left of texture) in Castor3D space. In Castor3D @@ -347,31 +356,29 @@ namespace c3d_gltf // coordinate of the actual meshes during import. float const rcos( ( -result.rotate ).cos() ); float const rsin( ( -result.rotate ).sin() ); - result.translate->x = ( 0.5f * result.scale->x ) * ( -rcos + rsin + 1 ) + transform->uvOffset[0]; - result.translate->y = ( 0.5f * result.scale->y ) * ( rsin + rcos - 1 ) + 1 - result.scale->y - transform->uvOffset[1]; + result.translate->x = ( 0.5f * result.scale->x ) * ( -rcos + rsin + 1 ) + transform.uvOffset[0]; + result.translate->y = ( 0.5f * result.scale->y ) * ( rsin + rcos - 1 ) + 1 - result.scale->y - transform.uvOffset[1]; - if ( transform->texCoordIndex ) + if ( transform.texCoordIndex ) { - texCoordIndex = uint32_t( *transform->texCoordIndex ); + texCoordIndex = uint32_t( *transform.texCoordIndex ); } } static void parseColOpaTexture( GltfImporterFile const & file , castor3d::Pass & pass , fastgltf::Asset const & impAsset - , castor::Map< castor3d::PassComponentTextureFlag, castor3d::TextureConfiguration > const & textureRemaps - , std::optional< fastgltf::TextureInfo > const & texInfo + , fastgltf::Optional< fastgltf::TextureInfo > const & texInfo , castor3d::MaterialImporter & importer ) { if ( texInfo ) { auto texConfig = pass.getComponentPlugin< castor3d::ColourMapComponent >().getBaseTextureConfiguration(); - if ( auto sourceInfo = loadTexture( file, impAsset, *texInfo, texConfig, importer ) ) + if ( auto sourceInfo = loadTexture( impAsset, *texInfo, texConfig, importer ) ) { - auto & image = loadImage( *sourceInfo, importer ); - - if ( hasAlphaChannel( image ) ) + if ( auto & image = loadImage( *sourceInfo, importer ); + hasAlphaChannel( image ) ) { addFlagConfiguration( texConfig, { pass.getComponentPlugin< castor3d::OpacityMapComponent >().getTextureFlags(), 0xFF000000 } ); *sourceInfo = castor3d::TextureSourceInfo{ *sourceInfo, texConfig }; @@ -382,7 +389,7 @@ namespace c3d_gltf if ( texInfo->transform ) { - parseTransform( texInfo->transform, texConfig.transform, texCoordIndex ); + parseTransform( *texInfo->transform, texConfig.transform, texCoordIndex ); *sourceInfo = castor3d::TextureSourceInfo{ *sourceInfo, texConfig }; } @@ -392,11 +399,33 @@ namespace c3d_gltf } } + static void parseTexture( GltfImporterFile const & file + , castor3d::Pass & pass + , castor3d::TextureConfiguration texConfig + , fastgltf::Asset const & impAsset + , fastgltf::TextureInfo const & texInfo + , castor3d::MaterialImporter & importer ) + { + if ( auto sourceInfo = loadTexture( impAsset, texInfo, texConfig, importer ) ) + { + fastgltf::Texture const & impTexture = impAsset.textures[texInfo.textureIndex]; + auto texCoordIndex = uint32_t( texInfo.texCoordIndex ); + + if ( texInfo.transform ) + { + parseTransform( *texInfo.transform, texConfig.transform, texCoordIndex ); + *sourceInfo = castor3d::TextureSourceInfo{ *sourceInfo, texConfig }; + } + + castor3d::PassTextureConfig passTexConfig{ loadSampler( file, impAsset, impTexture.samplerIndex ), texCoordIndex }; + pass.registerTexture( castor::move( *sourceInfo ), passTexConfig ); + } + } + static void parseRghMetTexture( GltfImporterFile const & file , castor3d::Pass & pass , fastgltf::Asset const & impAsset - , castor::Map< castor3d::PassComponentTextureFlag, castor3d::TextureConfiguration > const & textureRemaps - , std::optional< fastgltf::TextureInfo > const & texInfo + , fastgltf::Optional< fastgltf::TextureInfo > const & texInfo , castor3d::MaterialImporter & importer ) { if ( texInfo ) @@ -405,29 +434,16 @@ namespace c3d_gltf texConfig.components[1] = pass.getComponentPlugin< castor3d::MetalnessMapComponent >().getBaseTextureConfiguration().components[0]; texConfig.components[0].componentsMask = 0x0000FF00; texConfig.components[1].componentsMask = 0x000000FF; - - if ( auto sourceInfo = loadTexture( file, impAsset, *texInfo, texConfig, importer ) ) - { - fastgltf::Texture const & impTexture = impAsset.textures[texInfo->textureIndex]; - auto texCoordIndex = uint32_t( texInfo->texCoordIndex ); - - if ( texInfo->transform ) - { - parseTransform( texInfo->transform, texConfig.transform, texCoordIndex ); - *sourceInfo = castor3d::TextureSourceInfo{ *sourceInfo, texConfig }; - } - - castor3d::PassTextureConfig passTexConfig{ loadSampler( file, impAsset, impTexture.samplerIndex ), texCoordIndex }; - pass.registerTexture( castor::move( *sourceInfo ), passTexConfig ); - } + parseTexture( file, pass + , std::move( texConfig ) + , impAsset, *texInfo, importer ); } } static void parseSpcGlsTexture( GltfImporterFile const & file , castor3d::Pass & pass , fastgltf::Asset const & impAsset - , castor::Map< castor3d::PassComponentTextureFlag, castor3d::TextureConfiguration > const & textureRemaps - , std::optional< fastgltf::TextureInfo > const & texInfo + , fastgltf::Optional< fastgltf::TextureInfo > const & texInfo , castor3d::MaterialImporter & importer ) { if ( texInfo ) @@ -436,21 +452,9 @@ namespace c3d_gltf texConfig.components[1] = pass.getComponentPlugin< castor3d::GlossinessMapComponent >().getBaseTextureConfiguration().components[0]; texConfig.components[0].componentsMask = 0x00FFFFFF; texConfig.components[1].componentsMask = 0xFF000000; - - if ( auto sourceInfo = loadTexture( file, impAsset, *texInfo, texConfig, importer ) ) - { - fastgltf::Texture const & impTexture = impAsset.textures[texInfo->textureIndex]; - auto texCoordIndex = uint32_t( texInfo->texCoordIndex ); - - if ( texInfo->transform ) - { - parseTransform( texInfo->transform, texConfig.transform, texCoordIndex ); - *sourceInfo = castor3d::TextureSourceInfo{ *sourceInfo, texConfig }; - } - - castor3d::PassTextureConfig passTexConfig{ loadSampler( file, impAsset, impTexture.samplerIndex ), texCoordIndex }; - pass.registerTexture( castor::move( *sourceInfo ), passTexConfig ); - } + parseTexture( file, pass + , std::move( texConfig ) + , impAsset, *texInfo, importer ); } } @@ -458,28 +462,42 @@ namespace c3d_gltf static void parseTexture( GltfImporterFile const & file , castor3d::Pass & pass , fastgltf::Asset const & impAsset - , castor::Map< castor3d::PassComponentTextureFlag, castor3d::TextureConfiguration > const & textureRemaps - , std::optional< fastgltf::TextureInfo > const & texInfo + , fastgltf::Optional< fastgltf::TextureInfo > const & texInfo , castor3d::MaterialImporter & importer ) { if ( texInfo ) { - castor3d::TextureConfiguration texConfig = pass.getComponentPlugin< ComponentT >().getBaseTextureConfiguration(); - - if ( auto sourceInfo = loadTexture( file, impAsset, *texInfo, texConfig, importer ) ) - { - fastgltf::Texture const & impTexture = impAsset.textures[texInfo->textureIndex]; - auto texCoordIndex = uint32_t( texInfo->texCoordIndex ); + parseTexture( file, pass + , pass.getComponentPlugin< ComponentT >().getBaseTextureConfiguration() + , impAsset, *texInfo, importer ); + } + } - if ( texInfo->transform ) - { - parseTransform( texInfo->transform, texConfig.transform, texCoordIndex ); - *sourceInfo = castor3d::TextureSourceInfo{ *sourceInfo, texConfig }; - } + static void parseNmlTexture( GltfImporterFile const & file + , castor3d::Pass & pass + , fastgltf::Asset const & impAsset + , fastgltf::Optional< fastgltf::NormalTextureInfo > const & texInfo + , castor3d::MaterialImporter & importer ) + { + if ( texInfo ) + { + parseTexture( file, pass + , pass.getComponentPlugin< castor3d::NormalMapComponent >().getBaseTextureConfiguration() + , impAsset, *texInfo, importer ); + } + } - castor3d::PassTextureConfig passTexConfig{ loadSampler( file, impAsset, impTexture.samplerIndex ), texCoordIndex }; - pass.registerTexture( castor::move( *sourceInfo ), passTexConfig ); - } + static void parseOccTexture( GltfImporterFile const & file + , castor3d::Pass & pass + , fastgltf::Asset const & impAsset + , fastgltf::Optional< fastgltf::OcclusionTextureInfo > const & texInfo + , castor3d::MaterialImporter & importer ) + { + if ( texInfo ) + { + parseTexture( file, pass + , pass.getComponentPlugin< castor3d::OcclusionMapComponent >().getBaseTextureConfiguration() + , impAsset, *texInfo, importer ); } } } @@ -571,9 +589,11 @@ namespace c3d_gltf uint32_t index{}; auto it = std::find_if( impAsset.materials.begin() , impAsset.materials.end() - , [&file, &name, &index]( fastgltf::Material const & lookup ) + , [&file, &name, &index]( fastgltf::Material const & ) { - return name == file.getMaterialName( index++ ); + auto result = ( name == file.getMaterialName( index ) ); + ++index; + return result; } ); if ( it == impAsset.materials.end() ) @@ -592,8 +612,8 @@ namespace c3d_gltf } materials::parseComponentData< castor3d::TwoSidedComponent >( *pass, impMaterial.doubleSided ); - materials::parseTexture< castor3d::NormalMapComponent >( file, *pass, impAsset, m_textureRemaps, impMaterial.normalTexture, *this ); - materials::parseTexture< castor3d::OcclusionMapComponent >( file, *pass, impAsset, m_textureRemaps, impMaterial.occlusionTexture, *this ); + materials::parseNmlTexture( file, *pass, impAsset, impMaterial.normalTexture, *this ); + materials::parseOccTexture( file, *pass, impAsset, impMaterial.occlusionTexture, *this ); doImportSpecularData( impMaterial, *pass ); doImportIridescenceData( impMaterial, *pass ); doImportVolumeData( impMaterial, *pass ); @@ -627,8 +647,8 @@ namespace c3d_gltf pass.createComponent< castor3d::MetalnessComponent >()->setMetalness( impMaterial.pbrData.metallicFactor ); pass.createComponent< castor3d::RoughnessComponent >()->setRoughness( impMaterial.pbrData.roughnessFactor ); - materials::parseColOpaTexture( file, pass, impAsset, m_textureRemaps, impMaterial.pbrData.baseColorTexture, *this ); - materials::parseRghMetTexture( file, pass, impAsset, m_textureRemaps, impMaterial.pbrData.metallicRoughnessTexture, *this ); + materials::parseColOpaTexture( file, pass, impAsset, impMaterial.pbrData.baseColorTexture, *this ); + materials::parseRghMetTexture( file, pass, impAsset, impMaterial.pbrData.metallicRoughnessTexture, *this ); if ( impMaterial.specular ) { @@ -638,8 +658,8 @@ namespace c3d_gltf spcComponent->setSpecular( castor::RgbColour::fromComponents( impMaterial.specular->specularColorFactor[0] , impMaterial.specular->specularColorFactor[1] , impMaterial.specular->specularColorFactor[2] ) ); - materials::parseTexture< castor3d::SpecularMapComponent >( file, pass, impAsset, m_textureRemaps, impMaterial.specular->specularColorTexture, *this ); - materials::parseTexture< castor3d::SpecularFactorMapComponent >( file, pass, impAsset, m_textureRemaps, impMaterial.specular->specularTexture, *this ); + materials::parseTexture< castor3d::SpecularMapComponent >( file, pass, impAsset, impMaterial.specular->specularColorTexture, *this ); + materials::parseTexture< castor3d::SpecularFactorMapComponent >( file, pass, impAsset, impMaterial.specular->specularTexture, *this ); } } else if ( impMaterial.specularGlossiness ) @@ -662,8 +682,8 @@ namespace c3d_gltf auto rghComponent = pass.createComponent< castor3d::RoughnessComponent >(); rghComponent->setGlossiness( impMaterial.specularGlossiness->glossinessFactor ); - materials::parseColOpaTexture( file, pass, impAsset, m_textureRemaps, impMaterial.specularGlossiness->diffuseTexture, *this ); - materials::parseSpcGlsTexture( file, pass, impAsset, m_textureRemaps, impMaterial.specularGlossiness->specularGlossinessTexture, *this ); + materials::parseColOpaTexture( file, pass, impAsset, impMaterial.specularGlossiness->diffuseTexture, *this ); + materials::parseSpcGlsTexture( file, pass, impAsset, impMaterial.specularGlossiness->specularGlossinessTexture, *this ); } } @@ -680,8 +700,8 @@ namespace c3d_gltf component->setIor( impMaterial.iridescence->iridescenceIor ); component->setMinThickness( impMaterial.iridescence->iridescenceThicknessMinimum ); component->setMaxThickness( impMaterial.iridescence->iridescenceThicknessMaximum ); - materials::parseTexture< castor3d::IridescenceMapComponent >( file, pass, impAsset, m_textureRemaps, impMaterial.iridescence->iridescenceTexture, *this ); - materials::parseTexture< castor3d::IridescenceThicknessMapComponent >( file, pass, impAsset, m_textureRemaps, impMaterial.iridescence->iridescenceThicknessTexture, *this ); + materials::parseTexture< castor3d::IridescenceMapComponent >( file, pass, impAsset, impMaterial.iridescence->iridescenceTexture, *this ); + materials::parseTexture< castor3d::IridescenceThicknessMapComponent >( file, pass, impAsset, impMaterial.iridescence->iridescenceThicknessTexture, *this ); } } @@ -701,7 +721,7 @@ namespace c3d_gltf auto thicknessComponent = pass.createComponent< castor3d::ThicknessComponent >(); thicknessComponent->setThicknessFactor( impMaterial.volume->thicknessFactor ); - materials::parseTexture< castor3d::AttenuationMapComponent >( file, pass, impAsset, m_textureRemaps, impMaterial.volume->thicknessTexture, *this ); + materials::parseTexture< castor3d::AttenuationMapComponent >( file, pass, impAsset, impMaterial.volume->thicknessTexture, *this ); } } @@ -714,7 +734,7 @@ namespace c3d_gltf if ( impMaterial.transmission ) { pass.createComponent< castor3d::TransmissionComponent >()->setTransmission( impMaterial.transmission->transmissionFactor ); - materials::parseTexture< castor3d::TransmissionMapComponent >( file, pass, impAsset, m_textureRemaps, impMaterial.transmission->transmissionTexture, *this ); + materials::parseTexture< castor3d::TransmissionMapComponent >( file, pass, impAsset, impMaterial.transmission->transmissionTexture, *this ); } } @@ -729,9 +749,9 @@ namespace c3d_gltf auto component = pass.createComponent< castor3d::ClearcoatComponent >(); component->setClearcoatFactor( impMaterial.clearcoat->clearcoatFactor ); component->setRoughnessFactor( impMaterial.clearcoat->clearcoatRoughnessFactor ); - materials::parseTexture< castor3d::ClearcoatMapComponent >( file, pass, impAsset, m_textureRemaps, impMaterial.clearcoat->clearcoatTexture, *this ); - materials::parseTexture< castor3d::ClearcoatNormalMapComponent >( file, pass, impAsset, m_textureRemaps, impMaterial.clearcoat->clearcoatNormalTexture, *this ); - materials::parseTexture< castor3d::ClearcoatRoughnessMapComponent >( file, pass, impAsset, m_textureRemaps, impMaterial.clearcoat->clearcoatRoughnessTexture, *this ); + materials::parseTexture< castor3d::ClearcoatMapComponent >( file, pass, impAsset, impMaterial.clearcoat->clearcoatTexture, *this ); + materials::parseTexture< castor3d::ClearcoatNormalMapComponent >( file, pass, impAsset, impMaterial.clearcoat->clearcoatNormalTexture, *this ); + materials::parseTexture< castor3d::ClearcoatRoughnessMapComponent >( file, pass, impAsset, impMaterial.clearcoat->clearcoatRoughnessTexture, *this ); } } @@ -748,15 +768,15 @@ namespace c3d_gltf , impMaterial.sheen->sheenColorFactor[1] , impMaterial.sheen->sheenColorFactor[2] ) ); component->setRoughnessFactor( impMaterial.sheen->sheenRoughnessFactor ); - materials::parseTexture< castor3d::SheenMapComponent >( file, pass, impAsset, m_textureRemaps, impMaterial.sheen->sheenColorTexture, *this ); - materials::parseTexture< castor3d::SheenRoughnessMapComponent >( file, pass, impAsset, m_textureRemaps, impMaterial.sheen->sheenRoughnessTexture, *this ); + materials::parseTexture< castor3d::SheenMapComponent >( file, pass, impAsset, impMaterial.sheen->sheenColorTexture, *this ); + materials::parseTexture< castor3d::SheenRoughnessMapComponent >( file, pass, impAsset, impMaterial.sheen->sheenRoughnessTexture, *this ); } } void GltfMaterialImporter::doImportEmissiveData( fastgltf::Material const & impMaterial , castor3d::Pass & pass ) { - if ( impMaterial.emissiveStrength + if ( impMaterial.emissiveStrength != 0.0f || impMaterial.emissiveTexture || std::any_of( impMaterial.emissiveFactor.begin() , impMaterial.emissiveFactor.end() @@ -770,29 +790,29 @@ namespace c3d_gltf auto component = pass.createComponent< castor3d::EmissiveComponent >(); - if ( impMaterial.emissiveStrength ) + if ( impMaterial.emissiveStrength != 0.0f ) { float emissiveMult = 1.0f; - float value; - if ( m_parameters.get( cuT( "emissive_mult" ), value ) - && std::abs( value - 1.0f ) > std::numeric_limits< float >::epsilon() ) + if ( float value; + m_parameters.get( cuT( "emissive_mult" ), value ) + && std::abs( value - 1.0f ) > std::numeric_limits< float >::epsilon() ) { emissiveMult = value; } - component->setEmissiveFactor( *impMaterial.emissiveStrength * emissiveMult ); + component->setEmissiveFactor( impMaterial.emissiveStrength * emissiveMult ); } component->setEmissive( castor::RgbColour::fromComponents( impMaterial.emissiveFactor[0] , impMaterial.emissiveFactor[1] , impMaterial.emissiveFactor[2] ) ); - materials::parseTexture< castor3d::EmissiveMapComponent >( file, pass, impAsset, m_textureRemaps, impMaterial.emissiveTexture, *this ); + materials::parseTexture< castor3d::EmissiveMapComponent >( file, pass, impAsset, impMaterial.emissiveTexture, *this ); } } void GltfMaterialImporter::doImportAlphaModeData( fastgltf::Material const & impMaterial - , castor3d::Pass & pass ) + , castor3d::Pass & pass )const { if ( impMaterial.alphaMode == fastgltf::AlphaMode::Mask ) { @@ -823,11 +843,11 @@ namespace c3d_gltf } void GltfMaterialImporter::doImportIorData( fastgltf::Material const & impMaterial - , castor3d::Pass & pass ) + , castor3d::Pass & pass )const { - if ( impMaterial.ior ) + if ( impMaterial.ior != 0.0f ) { - pass.createComponent< castor3d::RefractionComponent >()->setRefractionRatio( *impMaterial.ior ); + pass.createComponent< castor3d::RefractionComponent >()->setRefractionRatio( impMaterial.ior ); auto transmission = pass.getComponent< castor3d::TransmissionComponent >(); if ( !transmission ) diff --git a/source/Plugins/Importers/GltfImporter/GltfMaterialImporter.hpp b/source/Plugins/Importers/GltfImporter/GltfMaterialImporter.hpp index e7f76f13fe..e36d39a0f3 100644 --- a/source/Plugins/Importers/GltfImporter/GltfMaterialImporter.hpp +++ b/source/Plugins/Importers/GltfImporter/GltfMaterialImporter.hpp @@ -40,9 +40,9 @@ namespace c3d_gltf void doImportEmissiveData( fastgltf::Material const & impMaterial , castor3d::Pass & pass ); void doImportAlphaModeData( fastgltf::Material const & impMaterial - , castor3d::Pass & pass ); + , castor3d::Pass & pass )const; void doImportIorData( fastgltf::Material const & impMaterial - , castor3d::Pass & pass ); + , castor3d::Pass & pass )const; }; } diff --git a/test/CastorTest/UnitTest.hpp b/test/CastorTest/UnitTest.hpp index b67e731e06..4dd6fe4fcd 100644 --- a/test/CastorTest/UnitTest.hpp +++ b/test/CastorTest/UnitTest.hpp @@ -72,9 +72,9 @@ namespace Testing }; template<> - struct Stringifier< int8_t > + struct Stringifier< signed char > { - static std::string get( int8_t const & value ) + static std::string get( signed char const & value ) { std::stringstream stream; stream << int16_t( value ); @@ -83,9 +83,9 @@ namespace Testing }; template<> - struct Stringifier< uint8_t > + struct Stringifier< unsigned char > { - static std::string get( uint8_t const & value ) + static std::string get( unsigned char const & value ) { std::stringstream stream; stream << uint16_t( value ); @@ -94,9 +94,9 @@ namespace Testing }; template<> - struct Stringifier< int16_t > + struct Stringifier< signed short > { - static std::string get( int16_t const & value ) + static std::string get( signed short const & value ) { std::stringstream stream; stream << value; @@ -105,9 +105,9 @@ namespace Testing }; template<> - struct Stringifier< uint16_t > + struct Stringifier< unsigned short > { - static std::string get( uint16_t const & value ) + static std::string get( unsigned short const & value ) { std::stringstream stream; stream << value; @@ -116,9 +116,9 @@ namespace Testing }; template<> - struct Stringifier< int32_t > + struct Stringifier< signed int > { - static std::string get( int32_t const & value ) + static std::string get( signed int const & value ) { std::stringstream stream; stream << value; @@ -127,9 +127,9 @@ namespace Testing }; template<> - struct Stringifier< uint32_t > + struct Stringifier< unsigned int > { - static std::string get( uint32_t const & value ) + static std::string get( unsigned int const & value ) { std::stringstream stream; stream << value; @@ -138,9 +138,9 @@ namespace Testing }; template<> - struct Stringifier< int64_t > + struct Stringifier< signed long > { - static std::string get( int64_t const & value ) + static std::string get( signed long const & value ) { std::stringstream stream; stream << value; @@ -149,9 +149,31 @@ namespace Testing }; template<> - struct Stringifier< uint64_t > + struct Stringifier< unsigned long > { - static std::string get( uint64_t const & value ) + static std::string get( unsigned long const & value ) + { + std::stringstream stream; + stream << value; + return stream.str(); + } + }; + + template<> + struct Stringifier< signed long long > + { + static std::string get( signed long long const & value ) + { + std::stringstream stream; + stream << value; + return stream.str(); + } + }; + + template<> + struct Stringifier< unsigned long long > + { + static std::string get( unsigned long long const & value ) { std::stringstream stream; stream << value; diff --git a/test/CastorUtils/CastorUtilsArrayViewTest.cpp b/test/CastorUtils/CastorUtilsArrayViewTest.cpp index 84b0a0ca41..84cb55c559 100644 --- a/test/CastorUtils/CastorUtilsArrayViewTest.cpp +++ b/test/CastorUtils/CastorUtilsArrayViewTest.cpp @@ -67,7 +67,7 @@ namespace Testing } { CT_ON(" Check build buffer part" ); - size_t const size = 0; + uint32_t const size = 0; int * tmp = new int[size + 1]; castor::ArrayView< int > view1 = castor::makeArrayView( tmp, size ); CT_CHECK( view1.size() == size ); diff --git a/tools/GuiCommon/Shader/LanguageFileParser.cpp b/tools/GuiCommon/Shader/LanguageFileParser.cpp index acc61dc240..2230fac224 100644 --- a/tools/GuiCommon/Shader/LanguageFileParser.cpp +++ b/tools/GuiCommon/Shader/LanguageFileParser.cpp @@ -20,7 +20,7 @@ namespace GuiCommon return *static_cast< LanguageFileContext * >( context.getUserContext( ParsersName ) ); } - CU_ImplementAttributeParser( Root_Language ) + static CU_ImplementAttributeParser( Root_Language ) { auto & langContext = getParserContext( context ); diff --git a/tools/GuiCommon/System/CastorApplication.cpp b/tools/GuiCommon/System/CastorApplication.cpp index 477261cb3d..1674bf995f 100644 --- a/tools/GuiCommon/System/CastorApplication.cpp +++ b/tools/GuiCommon/System/CastorApplication.cpp @@ -263,7 +263,7 @@ namespace GuiCommon void read( CastorApplication::Config & config ) { -#if defined( _MSC_VER ) +#if defined( CU_CompilerMSVC ) if ( has( option::st::WaitDebugger ) ) { while ( !::IsDebuggerPresent() ) diff --git a/vcpkg.json b/vcpkg.json index 1b31115b51..83724d5060 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -2,7 +2,7 @@ "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json", "name": "castor3d", "version": "0.15.0", - "builtin-baseline": "3b213864579b6fa686e38715508f7cd41a50900f", + "builtin-baseline": "13bde2ff13192e1b2fdd37bd9b475c7665ae6ae5", "dependencies": [ "convectionkernels", "freetype", @@ -26,8 +26,7 @@ "./data/vcpkg/ports/draco", "./data/vcpkg/ports/fastgltf", "./data/vcpkg/ports/rendergraph", - "./data/vcpkg/ports/shaderwriter", - "./data/vcpkg/ports/vkfft" + "./data/vcpkg/ports/shaderwriter" ] }, "features": { @@ -53,14 +52,8 @@ "gltf": { "description": "Use fastgltf library to import glTF scenes.", "dependencies": [ - { - "name": "fastgltf", - "platform": "!osx" - }, - { - "name": "simdjson", - "platform": "!osx" - } + "fastgltf", + "simdjson" ] }, "vkfft": {