From a167fb5bc081d1e7162070edcec70f57fe8e9df9 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Tue, 2 Jan 2024 15:21:17 +0000 Subject: [PATCH] @wip Signed-off-by: Michael Carroll --- .../gz/rendering/ogre2/Ogre2RenderEngine.hh | 5 - ogre2/src/Ogre2RenderEngine.cc | 243 ++++------- .../Common/Any/AtmosphereNprSky_ps.any | 90 ++++ .../Common/Any/PccDepthCompressor_ps.any | 47 +++ .../materials/Common/Atmosphere.material | 62 +++ .../2.0/scripts/materials/Common/DPM.material | 65 +++ .../Common/GLSL/AtmosphereNprSky_ps.glsl | 56 +++ .../Common/GLSLES/CubeToDpsm_ps.glsles | 35 ++ .../Common/GLSLES/QuadCameraDir_vs.glsles | 25 ++ .../materials/Common/GLSLES/Quad_vs.glsles | 22 + .../Common/HLSL/AtmosphereNprSky_ps.hlsl | 47 +++ .../Common/HLSL/Copyback_1xFP32_ps.hlsl | 8 + .../HLSL/Copyback_4xFP32_2DArray_ps.hlsl | 8 + .../Common/HLSL/Copyback_4xFP32_ps.hlsl | 8 + .../Common/HLSL/CubeToDpm_4xFP16_ps.hlsl | 25 ++ .../materials/Common/HLSL/CubeToDpsm_ps.hlsl | 30 ++ .../Common/HLSL/DepthDownscaleMax_ps.hlsl | 21 + .../HLSL/EsmGaussianBlurLogFilter_cs.hlsl | 22 + .../Common/HLSL/GaussianBlurBase_cs.hlsl | 242 +++++++++++ .../HLSL/GaussianBlurLogFilterBase_cs.hlsl | 263 ++++++++++++ .../Common/HLSL/GaussianBlurLogFilter_ps.hlsl | 43 ++ .../Common/HLSL/HiddenAreaMeshVr_ps.hlsl | 4 + .../Common/HLSL/HiddenAreaMeshVr_vs.hlsl | 27 ++ .../Common/HLSL/MipmapsGaussianBlur_cs.hlsl | 37 ++ .../Common/HLSL/PccDepthCompressor_ps.hlsl | 39 ++ .../Common/HLSL/QuadCameraDirNoUV_vs.hlsl | 31 ++ .../Common/HLSL/QuadCameraDir_vs.hlsl | 31 ++ .../materials/Common/HLSL/Quad_vs.hlsl | 25 ++ .../Common/HLSL/RadialDensityMask_ps.hlsl | 35 ++ .../Common/HLSL/RadialDensityMask_vs.hlsl | 31 ++ .../HLSL/Resolve_1xFP32_Subsample0_ps.hlsl | 16 + .../materials/Common/HLSL/SkyCubemap_ps.hlsl | 16 + .../Common/HLSL/SkyEquirectangular_ps.hlsl | 25 ++ .../Common/HiddenAreaMeshVr.material | 95 +++++ .../Common/Metal/AtmosphereNprSky_ps.metal | 56 +++ .../Common/Metal/MipmapsGaussianBlur_cs.metal | 5 +- .../Common/PccDepthCompressor.material | 74 ++++ .../2.0/scripts/materials/Common/Quad.program | 2 +- .../Common/RadialDensityMask.material | 90 ++++ .../2.0/scripts/materials/Common/Sky.material | 137 +++++++ .../scripts/materials/Common/brtfLutDfg.dds | Bin 32916 -> 32916 bytes .../Hlms/Common/Any/Cubemap_piece_all.any | 44 +- .../Common/Any/DualParaboloid_piece_ps.any | 10 +- .../GLSL/CrossPlatformSettings_piece_all.glsl | 230 ++++++++++- .../Common/GLSL/QuaternionCode_piece_all.glsl | 135 ++++-- .../HLSL/CrossPlatformSettings_piece_all.hlsl | 61 +++ .../CrossPlatformSettings_piece_all.metal | 85 +++- .../Metal/QuaternionCode_piece_all.metal | 135 ++++-- .../Metal/RenderDepthOnly_piece_ps.metal | 2 +- .../Hlms/Pbs/Any/AmbientLighting_piece_ps.any | 12 +- .../Hlms/Pbs/Any/AreaLights_LTC_piece_ps.any | 67 ++- .../Hlms/Pbs/Any/AreaLights_piece_ps.any | 102 ++--- .../200.AtmosphereNprSkyHlms_piece_all.any | 42 ++ .../200.AtmosphereNprSkyHlms_piece_vs.any | 91 +++++ .../ForwardPlus_DecalsCubemaps_piece_ps.any | 100 ++--- .../Hlms/Pbs/Any/LightProfiles_piece_ps.any | 6 +- .../Hlms/Pbs/Any/Main/200.BRDFs_piece_ps.any | 257 +++++++----- .../Pbs/Any/Main/200.BlendModes_piece_ps.any | 24 +- .../Pbs/Any/Main/200.ForwardPlus_piece_ps.any | 50 +-- .../Pbs/Any/Main/200.Textures_piece_ps.any | 8 +- .../Main/500.Structs_piece_vs_piece_ps.any | 46 ++- .../Pbs/Any/Main/800.PixelShader_piece_ps.any | 383 ++++++++++++------ .../Any/Main/800.VertexShader_piece_vs.any | 139 ++++--- .../Pbs/Any/PlanarReflections_piece_ps.any | 6 +- .../Hlms/Pbs/Any/Refractions_piece_ps.any | 36 +- .../Hlms/Pbs/Any/ShadowMapping_piece_all.any | 6 +- .../Hlms/Pbs/Any/ShadowMapping_piece_ps.any | 132 ++++-- .../Hlms/Pbs/GLSL/Forward3D_piece_ps.glsl | 6 +- .../media/Hlms/Pbs/GLSL/PixelShader_ps.glsl | 24 +- .../media/Hlms/Pbs/GLSL/VertexShader_vs.glsl | 12 +- .../Hlms/Pbs/HLSL/Textures_piece_ps.hlsl | 4 +- .../Hlms/Pbs/Metal/Forward3D_piece_ps.metal | 6 +- .../media/Hlms/Pbs/Metal/PixelShader_ps.metal | 23 +- .../Hlms/Pbs/Metal/Textures_piece_ps.metal | 4 +- .../Hlms/Pbs/Metal/VertexShader_vs.metal | 7 +- .../Any/500.Structs_piece_vs_piece_ps.any | 5 + .../Any/550.DetailTriplanar_piece_ps.any | 175 ++++++++ .../Terra/Any/800.PixelShader_piece_ps.any | 227 ++++++----- .../Terra/Any/800.VertexShader_piece_vs.any | 23 +- .../PbsTerraShadows_piece_vs_piece_ps.glsl | 12 +- .../media/Hlms/Terra/GLSL/PixelShader_ps.glsl | 41 +- .../Hlms/Terra/GLSL/VertexShader_vs.glsl | 2 +- .../PbsTerraShadows_piece_vs_piece_ps.glsl | 38 ++ .../Hlms/Terra/GLSLES/PixelShader_ps.glsl | 334 +++++++++++++++ .../GLSLES/Structs_piece_vs_piece_ps.glsl | 46 +++ .../Hlms/Terra/GLSLES/Textures_piece_ps.glsl | 12 + .../Hlms/Terra/GLSLES/VertexShader_vs.glsl | 126 ++++++ .../PbsTerraShadows_piece_vs_piece_ps.hlsl | 12 +- .../PbsTerraShadows_piece_vs_piece_ps.metal | 12 +- .../Hlms/Terra/Metal/PixelShader_ps.metal | 23 +- .../Hlms/Terra/Metal/VertexShader_vs.metal | 1 + .../Unlit/Any/500.StructsUnlit_piece_all.any | 7 +- .../Unlit/Any/700.BlendModes_piece_ps.any | 20 +- .../Unlit/Any/800.PixelShader_piece_ps.any | 19 +- .../Unlit/Any/800.VertexShader_piece_vs.any | 4 +- .../media/Hlms/Unlit/GLSL/PixelShader_ps.glsl | 12 +- .../Hlms/Unlit/GLSL/VertexShader_vs.glsl | 2 +- .../Hlms/Unlit/Metal/PixelShader_ps.metal | 4 +- 98 files changed, 4499 insertions(+), 1096 deletions(-) create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/Any/AtmosphereNprSky_ps.any create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/Any/PccDepthCompressor_ps.any create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/Atmosphere.material create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/DPM.material create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/GLSL/AtmosphereNprSky_ps.glsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/GLSLES/CubeToDpsm_ps.glsles create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/GLSLES/QuadCameraDir_vs.glsles create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/GLSLES/Quad_vs.glsles create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/AtmosphereNprSky_ps.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/Copyback_1xFP32_ps.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/Copyback_4xFP32_2DArray_ps.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/Copyback_4xFP32_ps.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/CubeToDpm_4xFP16_ps.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/CubeToDpsm_ps.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/DepthDownscaleMax_ps.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/EsmGaussianBlurLogFilter_cs.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/GaussianBlurBase_cs.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/GaussianBlurLogFilterBase_cs.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/GaussianBlurLogFilter_ps.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/HiddenAreaMeshVr_ps.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/HiddenAreaMeshVr_vs.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/MipmapsGaussianBlur_cs.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/PccDepthCompressor_ps.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/QuadCameraDirNoUV_vs.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/QuadCameraDir_vs.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/Quad_vs.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/RadialDensityMask_ps.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/RadialDensityMask_vs.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/Resolve_1xFP32_Subsample0_ps.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/SkyCubemap_ps.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HLSL/SkyEquirectangular_ps.hlsl create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/HiddenAreaMeshVr.material create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/Metal/AtmosphereNprSky_ps.metal create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/PccDepthCompressor.material create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/RadialDensityMask.material create mode 100644 ogre2/src/media/2.0/scripts/materials/Common/Sky.material create mode 100644 ogre2/src/media/Hlms/Pbs/Any/Atmosphere/200.AtmosphereNprSkyHlms_piece_all.any create mode 100644 ogre2/src/media/Hlms/Pbs/Any/Atmosphere/200.AtmosphereNprSkyHlms_piece_vs.any create mode 100644 ogre2/src/media/Hlms/Terra/Any/550.DetailTriplanar_piece_ps.any create mode 100644 ogre2/src/media/Hlms/Terra/GLSLES/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.glsl create mode 100644 ogre2/src/media/Hlms/Terra/GLSLES/PixelShader_ps.glsl create mode 100644 ogre2/src/media/Hlms/Terra/GLSLES/Structs_piece_vs_piece_ps.glsl create mode 100644 ogre2/src/media/Hlms/Terra/GLSLES/Textures_piece_ps.glsl create mode 100644 ogre2/src/media/Hlms/Terra/GLSLES/VertexShader_vs.glsl diff --git a/ogre2/include/gz/rendering/ogre2/Ogre2RenderEngine.hh b/ogre2/include/gz/rendering/ogre2/Ogre2RenderEngine.hh index 76c10d7ad..d1a8c4441 100644 --- a/ogre2/include/gz/rendering/ogre2/Ogre2RenderEngine.hh +++ b/ogre2/include/gz/rendering/ogre2/Ogre2RenderEngine.hh @@ -87,8 +87,6 @@ namespace gz /// \brief Destructor public: virtual ~Ogre2RenderEngine(); - public: void ManualLoad(const std::map &_params); - // Documentation Inherited. public: virtual void Destroy() override; @@ -264,9 +262,6 @@ namespace gz /// \brief True to use the current opengl context private: bool useCurrentGLContext = false; - private: std::string SDL2x11 = {}; - private: std::string parentWindowHandle = {}; - /// \brief Pointer to private data private: std::unique_ptr dataPtr; diff --git a/ogre2/src/Ogre2RenderEngine.cc b/ogre2/src/Ogre2RenderEngine.cc index 97d9be678..3983ffe4c 100644 --- a/ogre2/src/Ogre2RenderEngine.cc +++ b/ogre2/src/Ogre2RenderEngine.cc @@ -15,6 +15,7 @@ * */ +#include #ifdef _WIN32 // Ensure that Winsock2.h is included before Windows.h, which can get // pulled in by anybody (e.g., Boost). @@ -73,6 +74,37 @@ #include #endif + +class GZ_RENDERING_OGRE2_HIDDEN Ogre2LogListener: public Ogre::LogListener +{ + public: + ~Ogre2LogListener() override = default; + void messageLogged( + const Ogre::String &message, + Ogre::LogMessageLevel lml, + bool maskDebug, + const Ogre::String &logName, + bool &skipThisMessage ) override + { + std::stringstream msg; + + msg << "[" << logName << "] " << message << std::endl; + + switch (lml) + { + case Ogre::LogMessageLevel::LML_NORMAL: + gz::common::Console::msg() << msg.str(); + break; + case Ogre::LogMessageLevel::LML_TRIVIAL: + gz::common::Console::dbg() << msg.str(); + break; + case Ogre::LogMessageLevel::LML_CRITICAL: + gz::common::Console::err() << msg.str(); + break; + } + } +}; + class GZ_RENDERING_OGRE2_HIDDEN gz::rendering::Ogre2RenderEnginePrivate { @@ -170,9 +202,7 @@ Ogre::Window * Ogre2RenderEngine::OgreWindow() const } ////////////////////////////////////////////////// -Ogre2RenderEngine::~Ogre2RenderEngine() -{ -} +Ogre2RenderEngine::~Ogre2RenderEngine() = default; ////////////////////////////////////////////////// void Ogre2RenderEngine::Destroy() @@ -189,7 +219,7 @@ void Ogre2RenderEngine::Destroy() this->dataPtr->hlmsPbsTerraShadows.reset(); - if (this->ogreRoot) + if (this->ogreRoot != nullptr) { // Clean up any textures that may still be in flight. Ogre::TextureGpuManager *mgr = @@ -218,19 +248,19 @@ void Ogre2RenderEngine::Destroy() this->ogreLogManager = nullptr; #if HAVE_GLX - if (this->dummyDisplay) + if (this->dummyDisplay != nullptr) { - Display *x11Display = static_cast(this->dummyDisplay); - if (this->dummyContext) + auto *x11Display = static_cast(this->dummyDisplay); + if (this->dummyContext != nullptr) { - GLXContext x11Context = static_cast(this->dummyContext); + auto *x11Context = static_cast(this->dummyContext); glXDestroyContext(x11Display, x11Context); this->dummyContext = nullptr; } XDestroyWindow(x11Display, this->dummyWindowId); XCloseDisplay(x11Display); this->dummyDisplay = nullptr; - if (this->dataPtr->dummyFBConfigs) + if (this->dataPtr->dummyFBConfigs != nullptr) { XFree(this->dataPtr->dummyFBConfigs); this->dataPtr->dummyFBConfigs = nullptr; @@ -362,142 +392,6 @@ SceneStorePtr Ogre2RenderEngine::Scenes() const return this->scenes; } -////////////////////////////////////////////////// -void Ogre2RenderEngine::ManualLoad(const std::map &_params) -{ - this->dataPtr->vkExternalInstance.instance = nullptr; - this->dataPtr->vkExternalDevice.physicalDevice = nullptr; - this->dataPtr->vkExternalDevice.device = nullptr; - this->dataPtr->vkExternalDevice.graphicsQueue = nullptr; - this->dataPtr->vkExternalDevice.presentQueue = nullptr; - - auto it = _params.find("vulkan"); - if (it != _params.end()) - { - bool useVulkan {false}; - std::istringstream(it->second) >> useVulkan; - if (useVulkan) - { - gzdbg << "[OGRE2] Using Vulkan Backend" << std::endl; - this->dataPtr->graphicsAPI = GraphicsAPI::VULKAN; - - it = _params.find("external_instance"); - if (it != _params.end()) - { - const auto *gzExternalInstance = - reinterpret_cast( - Ogre::StringConverter::parseUnsignedLong(it->second)); - - this->dataPtr->vkExternalInstance.instance = - gzExternalInstance->instance; - // This works as long as std::vector memory is actually contiguous - this->dataPtr->vkExternalInstance.instanceLayers.appendPOD( - &*gzExternalInstance->instanceLayers.begin(), - &*gzExternalInstance->instanceLayers.end()); - this->dataPtr->vkExternalInstance.instanceExtensions.appendPOD( - &*gzExternalInstance->instanceExtensions.begin(), - &*gzExternalInstance->instanceExtensions.end()); - } - - it = _params.find("external_device"); - if (it != _params.end()) - { - const auto *gzExternalDevice = - reinterpret_cast( - Ogre::StringConverter::parseUnsignedLong(it->second)); - - this->dataPtr->vkExternalDevice.physicalDevice = - gzExternalDevice->physicalDevice; - this->dataPtr->vkExternalDevice.device = gzExternalDevice->device; - this->dataPtr->vkExternalDevice.graphicsQueue = - gzExternalDevice->graphicsQueue; - this->dataPtr->vkExternalDevice.presentQueue = - gzExternalDevice->presentQueue; - // This works as long as std::vector memory is actually contiguous - this->dataPtr->vkExternalDevice.deviceExtensions.appendPOD( - &*gzExternalDevice->deviceExtensions.begin(), - &*gzExternalDevice->deviceExtensions.end()); - } - } - } - - // init the resources - - try - { - this->CreateLogger(); - this->CreateRoot(); - this->CreateOverlay(); - this->LoadPlugins(); - - this->CreateRenderSystem(); - this->ogreRoot->initialise(false); - - Ogre::StringVector paramsVector; - Ogre::NameValuePairList params; - this->window = nullptr; - - params["SDL2x11"] = _params.find("SDL2x11")->second; - params["parentWindowHandle"] = _params.find("parentWindowHandle")->second; - params["FSAA"] = "0"; - params["stereoMode"] = "Frame Sequential"; - params["border"] = "none"; - - std::ostringstream stream; - stream << "OgreWindow(0)" << "_1"; - - // Needed for retina displays - params["contentScalingFactor"] = "1"; - params["gamma"] = "Yes"; - params["parentWindowHandle"] = this->winID; - - int attempts = 0; - while (this->window == nullptr && (attempts++) < 10) - { - try - { - this->window = Ogre::Root::getSingleton().createRenderWindow( - stream.str(), 640, 480, false, ¶ms); - } - catch(const std::exception &_e) - { - gzerr << " Unable to create the rendering window: " << _e.what() - << std::endl; - this->window = nullptr; - } - } - - if (attempts >= 10) - { - gzerr << "Unable to create the rendering window after [" << attempts - << "] attempts." << std::endl; - } - - this->RegisterHlms(); - - if (this->window) - { - this->window->_setVisible(true); - } - - this->CreateResources(); - - this->loaded = true; - this->initialized = true; - } - catch (Ogre::Exception &ex) - { - gzerr << ex.what() << std::endl; - } - catch (...) - { - gzerr << "Failed to load render-engine" << std::endl; - } - - Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(false); - this->scenes = Ogre2SceneStorePtr(new Ogre2SceneStore); -} - ////////////////////////////////////////////////// bool Ogre2RenderEngine::LoadImpl( const std::map &_params) @@ -518,22 +412,12 @@ bool Ogre2RenderEngine::LoadImpl( it = _params.find("metal"); if (it != _params.end()) { - bool useMetal; + bool useMetal {false}; std::istringstream(it->second) >> useMetal; - if(useMetal) + if (useMetal) this->dataPtr->graphicsAPI = GraphicsAPI::METAL; } - it = _params.find("SDL2x11"); - if (it != _params.end()) - std::istringstream(it->second) >> this->SDL2x11; - - it = _params.find("parentWindowHandle"); - if (it != _params.end()) - { - std::istringstream(it->second) >> this->parentWindowHandle; - } - #ifdef OGRE_BUILD_RENDERSYSTEM_VULKAN this->dataPtr->vkExternalInstance.instance = nullptr; this->dataPtr->vkExternalDevice.physicalDevice = nullptr; @@ -545,7 +429,7 @@ bool Ogre2RenderEngine::LoadImpl( it = _params.find("vulkan"); if (it != _params.end()) { - bool useVulkan; + bool useVulkan {false}; std::istringstream(it->second) >> useVulkan; if(useVulkan) { @@ -635,8 +519,7 @@ void Ogre2RenderEngine::LoadAttempt() this->CreateLogger(); if (!this->useCurrentGLContext && (this->dataPtr->graphicsAPI == GraphicsAPI::OPENGL || - this->dataPtr->graphicsAPI == GraphicsAPI::VULKAN) && - !this->SDL2x11.empty()) + this->dataPtr->graphicsAPI == GraphicsAPI::VULKAN)) { this->CreateContext(); } @@ -662,7 +545,8 @@ void Ogre2RenderEngine::CreateLogger() // create actual log this->ogreLogManager = new Ogre::LogManager(); - this->ogreLogManager->createLog(logPath, true, false, false); + auto *log = this->ogreLogManager->createLog(logPath, true, false, false); + log->addListener(new Ogre2LogListener()); } ////////////////////////////////////////////////// @@ -843,7 +727,6 @@ void Ogre2RenderEngine::LoadPlugins() if (!common::exists(filename)) { filename = filename + "." + std::string(OGRE2_VERSION); - if (!common::exists(filename)) { if (piter->name.find("RenderSystem") != std::string::npos) @@ -1049,14 +932,32 @@ void Ogre2RenderEngine::RegisterHlms() rootHlmsFolder, "2.0", "scripts", "Compositors"); Ogre::ResourceGroupManager::getSingleton().addResourceLocation( pbsCompositorFolder, "FileSystem", "General"); + Ogre::String commonMaterialFolder = common::joinPaths( rootHlmsFolder, "2.0", "scripts", "materials", "Common"); Ogre::ResourceGroupManager::getSingleton().addResourceLocation( commonMaterialFolder, "FileSystem", "General"); + + Ogre::String commonAnyMaterialFolder = common::joinPaths( + rootHlmsFolder, "2.0", "scripts", "materials", "Common", "Any"); + Ogre::ResourceGroupManager::getSingleton().addResourceLocation( + commonAnyMaterialFolder, "FileSystem", "General"); + Ogre::String commonGLSLMaterialFolder = common::joinPaths( rootHlmsFolder, "2.0", "scripts", "materials", "Common", "GLSL"); Ogre::ResourceGroupManager::getSingleton().addResourceLocation( commonGLSLMaterialFolder, "FileSystem", "General"); + + Ogre::String commonGLESMaterialFolder = common::joinPaths( + rootHlmsFolder, "2.0", "scripts", "materials", "Common", "GLES"); + Ogre::ResourceGroupManager::getSingleton().addResourceLocation( + commonGLESMaterialFolder, "FileSystem", "General"); + + Ogre::String commonHLSLMaterialFolder = common::joinPaths( + rootHlmsFolder, "2.0", "scripts", "materials", "Common", "HLSL"); + Ogre::ResourceGroupManager::getSingleton().addResourceLocation( + commonHLSLMaterialFolder, "FileSystem", "General"); + Ogre::String terraMaterialFolder = common::joinPaths( rootHlmsFolder, "2.0", "scripts", "materials", "Terra"); Ogre::ResourceGroupManager::getSingleton().addResourceLocation( @@ -1284,6 +1185,8 @@ void Ogre2RenderEngine::CreateResources() std::make_pair(p + "/Hlms/Common/Any", "General")); archNames.push_back( std::make_pair(p + "/Hlms/Common/GLSL", "General")); + archNames.push_back( + std::make_pair(p + "/Hlms/Common/HLSL", "General")); archNames.push_back( std::make_pair(p + "/Hlms/Pbs/Any", "General")); @@ -1346,13 +1249,16 @@ std::string Ogre2RenderEngine::CreateRenderWindow(const std::string &_handle, const unsigned int _width, const unsigned int _height, const double _ratio, const unsigned int _antiAliasing) { - Ogre::StringVector paramsVector; + Ogre::StringVector paramsVector; Ogre::NameValuePairList params; this->window = nullptr; - if (this->dataPtr->graphicsAPI == GraphicsAPI::VULKAN && !this->SDL2x11.empty()) + if (this->dataPtr->graphicsAPI == GraphicsAPI::VULKAN) { - params["SDL2x11"] = this->SDL2x11; + if (!_handle.empty()) + { + params["SDL2x11"] = _handle; + } } else { @@ -1386,7 +1292,7 @@ std::string Ogre2RenderEngine::CreateRenderWindow(const std::string &_handle, stream << "OgreWindow(0)" << "_" << _handle; // Needed for retina displays - params["contentScalingFactor"] = (_ratio); + params["contentScalingFactor"] = std::to_string(_ratio); // Ogre 2 PBS expects gamma correction params["gamma"] = "Yes"; @@ -1435,12 +1341,12 @@ std::string Ogre2RenderEngine::CreateRenderWindow(const std::string &_handle, { gzerr << "Unable to create the rendering window after [" << attempts << "] attempts." << std::endl; - return std::string(); + return {}; } this->RegisterHlms(); - if (this->window) + if (this->window != nullptr) { this->window->_setVisible(true); @@ -1448,7 +1354,6 @@ std::string Ogre2RenderEngine::CreateRenderWindow(const std::string &_handle, // this->window->reposition(0, 0); } return stream.str(); - } ////////////////////////////////////////////////// diff --git a/ogre2/src/media/2.0/scripts/materials/Common/Any/AtmosphereNprSky_ps.any b/ogre2/src/media/2.0/scripts/materials/Common/Any/AtmosphereNprSky_ps.any new file mode 100644 index 000000000..2180d2839 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/Any/AtmosphereNprSky_ps.any @@ -0,0 +1,90 @@ +// NPR = Non-Physically-based Rendering Atmo +// +// This file is used by both Hlms and low level materials +// Which is why Hlms syntax is in comments + +//#include "SyntaxHighlightingMisc.h" + +// @property( atmosky_npr ) + +#ifdef HEADER + +float getSunDisk( const float LdotV, const float sunY, const float sunPower ) +{ + return pow( LdotV, lerp( 4.0f, 8500.0f, sunY ) * 0.25f ) * sunPower; +} + +float getMie( const float LdotV, const float sunY ) +{ + return pow( LdotV, lerp( 1.0f, 1.0f, sunY ) ); +} + +// See https://en.wikipedia.org/wiki/Rayleigh_distribution +// It's inspired, not fully based. +// +// The formula also gives us the nice property that for inputs +// where absorption is in range [0; 1] the output i also in range [0; 1] +float3 getSkyRayleighAbsorption( float3 vDir, const float density ) +{ + float3 absorption = -density * vDir; + absorption = exp2( absorption ) * 2.0f; + return absorption; +} + +float3 pow3( float3 v, float e ) +{ + return float3( pow( v.x, e ), pow( v.y, e ), pow( v.z, e ) ); +} + +#else + +float3 atmoCameraDir = normalize( inPs.cameraDir ); + +const float LdotV = max( dot( atmoCameraDir, p_sunDir ), 0.0f ); + +atmoCameraDir.y += p_densityDiffusion * 0.075f * ( 1.0f - atmoCameraDir.y ) * ( 1.0f - atmoCameraDir.y ); +atmoCameraDir += p_cameraDisplacement.xyz; +atmoCameraDir = normalize( atmoCameraDir ); + +atmoCameraDir.y = max( atmoCameraDir.y, p_borderLimit ); + +// It's not a mistake. We do this twice. Doing it before p_borderLimit +// allows the horizon to shift. Doing it after p_borderLimit lets +// the sky to get darker as we get upwards. +atmoCameraDir += p_cameraDisplacement.xyz; +atmoCameraDir = normalize( atmoCameraDir ); + +const float LdotV360 = dot( atmoCameraDir, p_sunDir ) * 0.5f + 0.5f; + +// ptDensity gets smaller as sunHeight gets bigger +// ptDensity gets smaller as atmoCameraDir.y gets bigger +const float ptDensity = + p_densityCoeff / pow( max( atmoCameraDir.y / ( 1.0f - p_sunHeight ), 0.0035f ), + lerp( 0.10f, p_densityDiffusion, pow( atmoCameraDir.y, 0.3f ) ) ); + +const float sunDisk = getSunDisk( LdotV, p_sunHeight, p_sunPower ); + +const float antiMie = max( p_sunHeightWeight, 0.08f ); + +const float3 skyAbsorption = getSkyRayleighAbsorption( p_skyColour, ptDensity ); +// const float3 skyColourGradient = pow3( exp2( -atmoCameraDir.y / p_skyColour ), +// lerp( 15.5f, 1.5f, pow( p_sunHeightWeight, 0.5f ) ) ); +const float3 skyColourGradient = pow3( exp2( -atmoCameraDir.y / p_skyColour ), 1.5f ); + +const float mie = getMie( LdotV360, p_sunHeightWeight ); + +float3 atmoColour = float3( 0.0f, 0.0f, 0.0f ); + +const float3 sharedTerms = skyColourGradient * skyAbsorption; + +atmoColour += antiMie * sharedTerms * p_sunAbsorption; +atmoColour += ( mie * ptDensity * p_lightDensity ) * sharedTerms * p_skyLightAbsorption; +atmoColour += mie * p_mieAbsorption; +atmoColour *= p_lightDensity; + +atmoColour *= p_finalMultiplier; +atmoColour += sunDisk * p_skyLightAbsorption; + +#endif + +// @end !atmosky_npr diff --git a/ogre2/src/media/2.0/scripts/materials/Common/Any/PccDepthCompressor_ps.any b/ogre2/src/media/2.0/scripts/materials/Common/Any/PccDepthCompressor_ps.any new file mode 100644 index 000000000..2efaf1be5 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/Any/PccDepthCompressor_ps.any @@ -0,0 +1,47 @@ + +//#include "SyntaxHighlightingMisc.h" + +#ifdef HEADER +/** + Finds the intersection between the cube of half size probeShapeHalfSize and center at origin + and the reflDir, so that posLS + reflDirLS * retVal = intersectionPos; +*/ +INLINE float findIntersectionDistance( float3 reflDirLS, float3 posLS, float3 probeShapeHalfSize ) +{ + //Find the ray intersection with box plane + float3 invReflDirLS = float3( 1.0, 1.0, 1.0 ) / reflDirLS; + float3 intersectAtMinPlane = ( -probeShapeHalfSize - posLS ) * invReflDirLS; + float3 intersectAtMaxPlane = ( probeShapeHalfSize - posLS ) * invReflDirLS; + //Get the largest intersection values (we are not interested in negative values) + float3 largestIntersect = max( intersectAtMaxPlane.xyz, intersectAtMinPlane.xyz ); + //Get the closest of all solutions + float distance = min( min( largestIntersect.x, largestIntersect.y ), largestIntersect.z ); + return distance; +} + +#else + + float fDepth = OGRE_Sample( depthTexture, pointSampler, inPs.uv0 ).x; + + float linearDepth = p_projectionParams.y / (fDepth - p_projectionParams.x); + + float3 viewSpacePosition = inPs.cameraDir * linearDepth; + + float fDist = length( viewSpacePosition.xyz ); + float3 probeToPosDir = viewSpacePosition / fDist; + + probeToPosDir = mul( p_viewSpaceToProbeLocalSpace, probeToPosDir ); + + float fApproxDist = findIntersectionDistance( probeToPosDir, p_cameraPosLS, p_probeShapeHalfSize ); + + //We can't store fDist directly because we have limited precision (often 8 bits) + //Thus we store it in terms of + // fApproxDist * alpha = fDist; + //During render we'll know fApproxDist and alpha, but want to know fDist + //We also know alpha >= 0 + //For precision issues and because it's good enough, we force alpha <= 2.0 + float alpha = fDist / fApproxDist; + alpha *= 0.5; + alpha = min( alpha, 1.0 ); + +#endif diff --git a/ogre2/src/media/2.0/scripts/materials/Common/Atmosphere.material b/ogre2/src/media/2.0/scripts/materials/Common/Atmosphere.material new file mode 100644 index 000000000..61e7d92e0 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/Atmosphere.material @@ -0,0 +1,62 @@ + +// GLSL shaders +fragment_program Ogre/Atmo/NprSky_ps_GLSL glsl +{ + source AtmosphereNprSky_ps.glsl + preprocessor_defines GL + enable_include_header true +} + +fragment_program Ogre/Atmo/NprSky_ps_VK glslvk +{ + source AtmosphereNprSky_ps.glsl + enable_include_header true +} + +// HLSL shaders +fragment_program Ogre/Atmo/NprSky_ps_HLSL hlsl +{ + source AtmosphereNprSky_ps.hlsl + entry_point main + target ps_5_0 ps_4_0 ps_4_0_level_9_1 ps_4_0_level_9_3 +} + +// Metal shaders +fragment_program Ogre/Atmo/NprSky_ps_Metal metal +{ + source AtmosphereNprSky_ps.metal + enable_include_header true + shader_reflection_pair_hint Ogre/Compositor/QuadCameraDirNoUV_vs +} + +// Unified definitions +fragment_program Ogre/Atmo/NprSky_ps unified +{ + delegate Ogre/Atmo/NprSky_ps_HLSL + delegate Ogre/Atmo/NprSky_ps_VK + delegate Ogre/Atmo/NprSky_ps_GLSL + delegate Ogre/Atmo/NprSky_ps_Metal +} + +// Material definition +material Ogre/Atmo/NprSky +{ + technique + { + pass + { + depth_check on + depth_write off + + cull_hardware none + + vertex_program_ref Ogre/Compositor/QuadCameraDirNoUV_vs + { + } + + fragment_program_ref Ogre/Atmo/NprSky_ps + { + } + } + } +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/DPM.material b/ogre2/src/media/2.0/scripts/materials/Common/DPM.material new file mode 100644 index 000000000..23b6c941c --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/DPM.material @@ -0,0 +1,65 @@ +//DPM stands for Dual Parabolloid Mapping. + +fragment_program Ogre/DPM/CubeToDpm_4xFP16_ps_GLSL glsl +{ + source CubeToDpm_4xFP16_ps.glsl + default_params + { + param_named cubeTexture int 0 + } +} + +fragment_program Ogre/DPM/CubeToDpm_4xFP16_ps_VK glslvk +{ + source CubeToDpm_4xFP16_ps.glsl +} + +fragment_program Ogre/DPM/CubeToDpm_4xFP16_ps_HLSL hlsl +{ + source CubeToDpm_4xFP16_ps.hlsl + entry_point main + target ps_5_0 ps_4_0 ps_4_0_level_9_1 ps_4_0_level_9_3 +} + +fragment_program Ogre/DPM/CubeToDpm_4xFP16_ps_Metal metal +{ + source CubeToDpm_4xFP16_ps.metal + shader_reflection_pair_hint Ogre/Compositor/Quad_vs +} + +fragment_program Ogre/DPM/CubeToDpm_4xFP16_ps unified +{ + delegate Ogre/DPM/CubeToDpm_4xFP16_ps_GLSL + delegate Ogre/DPM/CubeToDpm_4xFP16_ps_VK + delegate Ogre/DPM/CubeToDpm_4xFP16_ps_HLSL + delegate Ogre/DPM/CubeToDpm_4xFP16_ps_Metal +} + +// Converts a cubemap to DPM in the pixel shader. +material Ogre/DPM/CubeToDpm +{ + technique + { + pass + { + depth_check off + depth_func always_pass + + cull_hardware none + + vertex_program_ref Ogre/Compositor/Quad_vs + { + } + + fragment_program_ref Ogre/DPM/CubeToDpm_4xFP16_ps + { + } + + texture_unit depthTexture + { + filtering bilinear + tex_address_mode clamp + } + } + } +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/GLSL/AtmosphereNprSky_ps.glsl b/ogre2/src/media/2.0/scripts/materials/Common/GLSL/AtmosphereNprSky_ps.glsl new file mode 100644 index 000000000..820fb1e01 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/GLSL/AtmosphereNprSky_ps.glsl @@ -0,0 +1,56 @@ +#version ogre_glsl_ver_330 + +#ifdef GL + #define const +#endif + +#define float2 vec2 +#define float3 vec3 +#define float4 vec4 +#define lerp mix + +vulkan_layout( location = 0 ) +in block +{ + vec3 cameraDir; +} inPs; + +vulkan_layout( location = 0 ) +out vec4 fragColour; + +vulkan( layout( ogre_P0 ) uniform Params { ) + uniform float4 packedParams0; + uniform float3 skyLightAbsorption; + uniform float4 sunAbsorption; + uniform float4 cameraDisplacement; + uniform float4 packedParams1; + uniform float4 packedParams2; + uniform float4 packedParams3; +vulkan( }; ) + +#define p_densityCoeff packedParams0.x +#define p_lightDensity packedParams0.y +#define p_sunHeight packedParams0.z +#define p_sunHeightWeight packedParams0.w +#define p_skyLightAbsorption skyLightAbsorption +#define p_sunAbsorption sunAbsorption.xyz +#define p_sunPower sunAbsorption.w +#define p_cameraDisplacement cameraDisplacement +#define p_mieAbsorption packedParams1.xyz +#define p_finalMultiplier packedParams1.w +#define p_sunDir packedParams2.xyz +#define p_borderLimit packedParams2.w +#define p_skyColour packedParams3.xyz +#define p_densityDiffusion packedParams3.w + +#define HEADER +#include "AtmosphereNprSky_ps.any" +#undef HEADER + +void main() +{ + #include "AtmosphereNprSky_ps.any" + + fragColour.xyz = atmoColour; + fragColour.w = 1.0f; +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/GLSLES/CubeToDpsm_ps.glsles b/ogre2/src/media/2.0/scripts/materials/Common/GLSLES/CubeToDpsm_ps.glsles new file mode 100644 index 000000000..034906965 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/GLSLES/CubeToDpsm_ps.glsles @@ -0,0 +1,35 @@ +#version 300 es +precision highp float; + +uniform samplerCube depthTexture; + +in block +{ + vec2 uv0; +} inPs; + +in vec4 gl_FragCoord; +//out float gl_FragDepth; + +#if OUTPUT_TO_COLOUR + out float fragColour; +#endif + +void main() +{ + vec3 cubeDir; + + cubeDir.x = mod( inPs.uv0.x, 0.5 ) * 4.0 - 1.0; + cubeDir.y = inPs.uv0.y * 2.0 - 1.0; + cubeDir.z = 0.5 - 0.5 * (cubeDir.x * cubeDir.x + cubeDir.y * cubeDir.y); + + cubeDir.z = inPs.uv0.x < 0.5 ? cubeDir.z : -cubeDir.z; + + float depthValue = textureLod( depthTexture, cubeDir.xyz, 0 ).x; + +#if OUTPUT_TO_COLOUR + fragColour = depthValue; +#else + gl_FragDepth = depthValue; +#endif +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/GLSLES/QuadCameraDir_vs.glsles b/ogre2/src/media/2.0/scripts/materials/Common/GLSLES/QuadCameraDir_vs.glsles new file mode 100644 index 000000000..c24467e56 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/GLSLES/QuadCameraDir_vs.glsles @@ -0,0 +1,25 @@ +#version 300 es +precision highp float; + +in vec4 vertex; +in vec3 normal; +in vec2 uv0; +uniform mat4 worldViewProj; + +out gl_PerVertex +{ + vec4 gl_Position; +}; + +out block +{ + vec2 uv0; + vec3 cameraDir; +} outVs; + +void main() +{ + gl_Position = (worldViewProj * vertex).xyzw; + outVs.uv0.xy = uv0.xy; + outVs.cameraDir.xyz = normal.xyz; +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/GLSLES/Quad_vs.glsles b/ogre2/src/media/2.0/scripts/materials/Common/GLSLES/Quad_vs.glsles new file mode 100644 index 000000000..3a4479fdd --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/GLSLES/Quad_vs.glsles @@ -0,0 +1,22 @@ +#version 300 es +precision highp float; + +in vec4 vertex; +in vec2 uv0; +uniform mat4 worldViewProj; + +out gl_PerVertex +{ + vec4 gl_Position; +}; + +out block +{ + vec2 uv0; +} outVs; + +void main() +{ + gl_Position = worldViewProj * vertex; + outVs.uv0.xy = uv0.xy; +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/AtmosphereNprSky_ps.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/AtmosphereNprSky_ps.hlsl new file mode 100644 index 000000000..0972322e8 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/AtmosphereNprSky_ps.hlsl @@ -0,0 +1,47 @@ + +struct PS_INPUT +{ + float3 cameraDir : TEXCOORD0; +}; + +#define p_densityCoeff packedParams0.x +#define p_lightDensity packedParams0.y +#define p_sunHeight packedParams0.z +#define p_sunHeightWeight packedParams0.w +#define p_skyLightAbsorption skyLightAbsorption +#define p_sunAbsorption sunAbsorption.xyz +#define p_sunPower sunAbsorption.w +#define p_cameraDisplacement cameraDisplacement +#define p_mieAbsorption packedParams1.xyz +#define p_finalMultiplier packedParams1.w +#define p_sunDir packedParams2.xyz +#define p_borderLimit packedParams2.w +#define p_skyColour packedParams3.xyz +#define p_densityDiffusion packedParams3.w + +#define HEADER +#include "AtmosphereNprSky_ps.any" +#undef HEADER + +float4 main +( + PS_INPUT inPs, + + uniform float4 packedParams0, + uniform float3 skyLightAbsorption, + uniform float4 sunAbsorption, + uniform float4 cameraDisplacement, + uniform float4 packedParams1, + uniform float4 packedParams2, + uniform float4 packedParams3 +) : SV_Target0 +{ + float4 fragColour; + + #include "AtmosphereNprSky_ps.any" + + fragColour.xyz = atmoColour; + fragColour.w = 1.0f; + + return fragColour; +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/Copyback_1xFP32_ps.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/Copyback_1xFP32_ps.hlsl new file mode 100644 index 000000000..6861022d3 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/Copyback_1xFP32_ps.hlsl @@ -0,0 +1,8 @@ + +Texture2D myTexture : register(t0); +SamplerState mySampler : register(s0); + +float main( float2 uv : TEXCOORD0 ) : SV_Target +{ + return myTexture.Sample( mySampler, uv ).x; +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/Copyback_4xFP32_2DArray_ps.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/Copyback_4xFP32_2DArray_ps.hlsl new file mode 100644 index 000000000..8d9ac85d4 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/Copyback_4xFP32_2DArray_ps.hlsl @@ -0,0 +1,8 @@ + +Texture2DArray myTexture : register(t0); +SamplerState mySampler : register(s0); + +float4 main( float2 uv : TEXCOORD0, uniform float sliceIdx ) : SV_Target +{ + return myTexture.Sample( mySampler, float3( uv, sliceIdx ) ).xyzw; +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/Copyback_4xFP32_ps.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/Copyback_4xFP32_ps.hlsl new file mode 100644 index 000000000..ab105ed23 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/Copyback_4xFP32_ps.hlsl @@ -0,0 +1,8 @@ + +Texture2D myTexture : register(t0); +SamplerState mySampler : register(s0); + +float4 main( float2 uv : TEXCOORD0 ) : SV_Target +{ + return myTexture.Sample( mySampler, uv ).xyzw; +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/CubeToDpm_4xFP16_ps.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/CubeToDpm_4xFP16_ps.hlsl new file mode 100644 index 000000000..cf9efaade --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/CubeToDpm_4xFP16_ps.hlsl @@ -0,0 +1,25 @@ + +TextureCube cubeTexture : register(t0); +SamplerState samplerState : register(s0); + +struct PS_INPUT +{ + float2 uv0 : TEXCOORD0; +}; + +float4 main +( + PS_INPUT inPs, + uniform float lodLevel +) : SV_Target0 +{ + float3 cubeDir; + + cubeDir.x = fmod( inPs.uv0.x, 0.5 ) * 4.0 - 1.0; + cubeDir.y = inPs.uv0.y * 2.0 - 1.0; + cubeDir.z = 0.5 - 0.5 * (cubeDir.x * cubeDir.x + cubeDir.y * cubeDir.y); + + cubeDir.z = inPs.uv0.x < 0.5 ? cubeDir.z : -cubeDir.z; + + return cubeTexture.SampleLevel( samplerState, cubeDir.xyz, lodLevel ).xyzw; +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/CubeToDpsm_ps.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/CubeToDpsm_ps.hlsl new file mode 100644 index 000000000..5b461d1c6 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/CubeToDpsm_ps.hlsl @@ -0,0 +1,30 @@ + +TextureCube depthTexture : register(t0); +SamplerState samplerState : register(s0); + +struct PS_INPUT +{ + float2 uv0 : TEXCOORD0; +}; + +float main +( + PS_INPUT inPs +#if OUTPUT_TO_COLOUR +) : SV_Target0 +#else +) : SV_Depth +#endif +{ + float3 cubeDir; + + cubeDir.x = fmod( inPs.uv0.x, 0.5 ) * 4.0 - 1.0; + cubeDir.y = inPs.uv0.y * 2.0 - 1.0; + cubeDir.z = 0.5 - 0.5 * (cubeDir.x * cubeDir.x + cubeDir.y * cubeDir.y); + + cubeDir.z = inPs.uv0.x < 0.5 ? cubeDir.z : -cubeDir.z; + + float depthValue = depthTexture.SampleLevel( samplerState, cubeDir.xyz, 0 ).x; + + return depthValue; +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/DepthDownscaleMax_ps.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/DepthDownscaleMax_ps.hlsl new file mode 100644 index 000000000..a8023c123 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/DepthDownscaleMax_ps.hlsl @@ -0,0 +1,21 @@ +struct PS_INPUT +{ + float2 uv0 : TEXCOORD0; +}; + +Texture2D depthTexture : register(t0); + +float main +( + PS_INPUT inPs, + float4 gl_FragCoord : SV_Position +) : SV_Depth +{ + float fDepth0 = depthTexture.Load( int3( int2(gl_FragCoord.xy * 2.0), 0 ) ).x; + float fDepth1 = depthTexture.Load( int3( int2(gl_FragCoord.xy * 2.0) + int2( 0, 1 ), 0 ) ).x; + float fDepth2 = depthTexture.Load( int3( int2(gl_FragCoord.xy * 2.0) + int2( 1, 0 ), 0 ) ).x; + float fDepth3 = depthTexture.Load( int3( int2(gl_FragCoord.xy * 2.0) + int2( 1, 1 ), 0 ) ).x; + + //return depthTexture.Load( int3( int2(gl_FragCoord.xy * 2.0), 0 ) ).x; + return max( max( fDepth0, fDepth1 ), max( fDepth2, fDepth3 ) ); +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/EsmGaussianBlurLogFilter_cs.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/EsmGaussianBlurLogFilter_cs.hlsl new file mode 100644 index 000000000..8a4a906c2 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/EsmGaussianBlurLogFilter_cs.hlsl @@ -0,0 +1,22 @@ +//Based on GPUOpen's samples SeparableFilter11 +//https://github.com/GPUOpen-LibrariesAndSDKs/SeparableFilter11 +//For better understanding, read "Efficient Compute Shader Programming" from Bill Bilodeau +//http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/Efficient%20Compute%20Shader%20Programming.pps + +//TL;DR: +// * Each thread works on 4 pixels at a time (for VLIW hardware, i.e. Radeon HD 5000 & 6000 series). +// * 256 pixels per threadgroup. Each threadgroup works on 2 rows of 128 pixels each. +// That means 32x2 threads = 64. 64 threads x 4 pixels per thread = 256 + +@piece( data_type )float@end +@piece( lds_data_type )float@end +@piece( lds_definition )groupshared float g_f3LDS[ 2 ] [ @value( samples_per_threadgroup ) ];@end + +@piece( image_sample ) + return inputImage.SampleLevel( inputSampler, f2SamplePosition, 0 ).x; +@end + +@piece( image_store ) + @foreach( 4, iPixel ) + outputImage[i2Center + @iPixel * i2Inc] = outColour[ @iPixel ];@end +@end diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/GaussianBlurBase_cs.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/GaussianBlurBase_cs.hlsl new file mode 100644 index 000000000..314ae513b --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/GaussianBlurBase_cs.hlsl @@ -0,0 +1,242 @@ + +//Based on GPUOpen's samples SeparableFilter11 +//https://github.com/GPUOpen-LibrariesAndSDKs/SeparableFilter11 +//For better understanding, read "Efficient Compute Shader Programming" from Bill Bilodeau +//http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/Efficient%20Compute%20Shader%20Programming.pps + +//TL;DR: +// * Each thread works on 4 pixels at a time (for VLIW hardware, i.e. Radeon HD 5000 & 6000 series). +// * 256 pixels per threadgroup. Each threadgroup works on 2 rows of 128 pixels each. +// That means 32x2 threads = 64. 64 threads x 4 pixels per thread = 256 + +// For this shader to work, several pieces need to be defined: +// data_type (i.e. float3) +// lds_data_type (i.e. float3, uint) +// lds_definition +// image_store +// image_sample +// decode_lds (optional, i.e. when lds_data_type != data_type) +// Define the property "downscale" if you're doing a downsample. +// Define "downscale_lq" (must also define downscale) for SLIGHTLY lower quality downscale +// The script uses the template syntax to automatically set the num. of threadgroups +// based on the bound input texture. + +SamplerState inputSampler : register(s0); +@property( texture0_texture_type == TextureTypes_Type2DArray ) + Texture2DArray inputImage : register(t0); +@else + Texture2D inputImage : register(t0); +@end + +@property( uav0_texture_type == TextureTypes_Type2DArray ) + RWTexture2DArray<@insertpiece(uav0_pf_type)> outputImage : register(u0); +@else + RWTexture2D<@insertpiece(uav0_pf_type)> outputImage : register(u0); +@end + +// 32 = 128 / 4 +@pset( threads_per_group_x, 32 ) +@pset( threads_per_group_y, 2 ) +@pset( threads_per_group_z, 1 ) + +@pmul( pixelsPerRow, threads_per_group_x, 4 ) +@pset( rowsPerThreadGroup, threads_per_group_y ) +@pset( num_thread_groups_z, 1 ) + +@set( input_width, uav0_width_with_lod ) +@set( input_height, uav0_height_with_lod ) + +@property( horizontal_pass ) + @property( downscale ) @mul( input_width, 2 ) @end + + /// Calculate num_thread_groups_ + /// num_thread_groups_x = (texture0_width + pixelsPerRow - 1) / pixelsPerRow + /// num_thread_groups_y = (texture0_height + rowsPerThreadGroup - 1) / rowsPerThreadGroup + @add( num_thread_groups_x, input_width, pixelsPerRow ) + @sub( num_thread_groups_x, 1 ) + @div( num_thread_groups_x, pixelsPerRow ) + + @add( num_thread_groups_y, input_height, rowsPerThreadGroup ) + @sub( num_thread_groups_y, 1 ) + @div( num_thread_groups_y, rowsPerThreadGroup ) +@end @property( !horizontal_pass ) + @property( downscale ) @mul( input_height, 2 ) @end + + /// Calculate num_thread_groups_ + /// num_thread_groups_x = (texture0_width + rowsPerThreadGroup - 1) / rowsPerThreadGroup + /// num_thread_groups_y = (texture0_height + pixelsPerRow - 1) / pixelsPerRow + @add( num_thread_groups_x, input_width, rowsPerThreadGroup ) + @sub( num_thread_groups_x, 1 ) + @div( num_thread_groups_x, rowsPerThreadGroup ) + + @add( num_thread_groups_y, input_height, pixelsPerRow ) + @sub( num_thread_groups_y, 1 ) + @div( num_thread_groups_y, pixelsPerRow ) +@end + +/// groupshared float3 g_f3LDS[ 2 ] [ @value( samples_per_threadgroup ) ]; +@insertpiece( lds_definition ) + +uniform float4 g_f4OutputSize; + +//Tightly pack the weights +uniform float4 c_weights[(@value( kernel_radius_plus1 ) + 3u) / 4u]; + +@insertpiece( lds_data_type ) sampleTex( int2 i2Position , float2 f2Offset ) +{ + float2 f2SamplePosition = float2( i2Position ) + float2( 0.5f, 0.5f ); + + f2SamplePosition *= g_f4OutputSize.zw; + ///return inputImage.SampleLevel( inputSampler, f2SamplePosition, 0 ).xyz; + @insertpiece( image_sample ) +} + +void ComputeFilterKernel( int iPixelOffset, int iLineOffset, int2 i2Center, int2 i2Inc ) +{ + @property( !downscale_lq ) + @insertpiece( data_type ) outColour[ 4 ]; + @end @property( downscale_lq ) + @insertpiece( data_type ) outColour[ 2 ]; + @end + @insertpiece( data_type ) RDI[ 4 ] ; + + @foreach( 4, iPixel ) + RDI[ @iPixel ] = @insertpiece( decode_lds )( g_f3LDS[ iLineOffset ][ iPixelOffset + @value( kernel_radius ) + @iPixel ] );@end + + @property( !downscale_lq ) + @foreach( 4, iPixel ) + outColour[ @iPixel ] = RDI[ @iPixel ] * c_weights[ @value( kernel_radius ) >> 2u ][ @value( kernel_radius ) & 3u ];@end + @end @property( downscale_lq ) + @foreach( 2, iPixel ) + outColour[ @iPixel ] = RDI[ @iPixel * 2 ] * c_weights[ @value( kernel_radius ) >> 2u ][ @value( kernel_radius ) & 3u ];@end + @end + + @foreach( 4, iPixel ) + RDI[ @iPixel ] = @insertpiece( decode_lds )( g_f3LDS[ iLineOffset ][ iPixelOffset + @iPixel ] );@end + + iPixelOffset += 4; + + /// Deal with taps to our left. + /// for ( iIteration = 0; iIteration < radius; iIteration += 1 ) + @foreach( kernel_radius, iIteration ) + @property( !downscale_lq ) + @foreach( 4, iPixel ) + outColour[ @iPixel ] += RDI[ @iPixel ] * c_weights[ @iIteration >> 2u ][ @iIteration & 3u ];@end + @end @property( downscale_lq ) + @foreach( 2, iPixel ) + outColour[ @iPixel ] += RDI[ @iPixel * 2 ] * c_weights[ @iIteration >> 2u ][ @iIteration & 3u ];@end + @end + @foreach( 3, iPixel ) + RDI[ @iPixel ] = RDI[ @iPixel + ( 1 ) ];@end + @foreach( 1, iPixel ) + RDI[ 4 - 1 + @iPixel ] = @insertpiece( decode_lds )( g_f3LDS[ iLineOffset ][ iPixelOffset + @iIteration + @iPixel ] );@end + @end + + @foreach( 4, iPixel ) + RDI[ @iPixel ] = @insertpiece( decode_lds )( g_f3LDS[ iLineOffset ][ iPixelOffset - 4 + @value( kernel_radius ) + 1 + @iPixel ] );@end + + @padd( kernel_radius_plus1, kernel_radius, 1 ) + @pmul( kernel_radius2x_plus1, kernel_radius, 2 ) + @padd( kernel_radius2x_plus1, 1 ) + + @pmul( kernel_radius2x, kernel_radius, 2 ) + + /// Deal with taps to our right. + /// for ( iIteration = radius + 1; iIteration < ( radius * 2 + 1 ); iIteration += 1 ) + @foreach( kernel_radius2x_plus1, iIteration, kernel_radius_plus1 ) + @property( !downscale_lq ) + @foreach( 4, iPixel ) + outColour[ @iPixel ] += RDI[ @iPixel ] * c_weights[ (@value( kernel_radius2x ) - @iIteration) >> 2u ][ (@value( kernel_radius2x ) - @iIteration) & 3u ];@end + @end @property( downscale_lq ) + @foreach( 2, iPixel ) + outColour[ @iPixel ] += RDI[ @iPixel * 2 ] * c_weights[ (@value( kernel_radius2x ) - @iIteration) >> 2u ][ (@value( kernel_radius2x ) - @iIteration) & 3u ];@end + @end + @foreach( 3, iPixel ) + RDI[ @iPixel ] = RDI[ @iPixel + ( 1 ) ];@end + @foreach( 1, iPixel ) + RDI[ 4 - 1 + @iPixel ] = @insertpiece( decode_lds )( g_f3LDS[ iLineOffset ][ iPixelOffset + @iIteration + @iPixel ] );@end + @end + + /* + foreach( 4, iPixel ) + outputImage[i2Center + iPixel * i2Inc] = float4( outColour[ iPixel ], 1.0 ) );end + */ + @insertpiece( image_store ) +} + +[numthreads(@value( threads_per_group_x ), @value( threads_per_group_y ), @value( threads_per_group_z ))] +void main( uint3 gl_WorkGroupID : SV_GroupID, uint3 gl_LocalInvocationID : SV_GroupThreadID ) +{ + /// samples_per_threadgroup = 128 + ( ( kernel_radius * 2 + 1 ) - 1 ) + /// samples_per_thread = ( 128 + ( ( kernel_radius * 2 + 1 ) - 1 ) ) / ( 128 / 4 ) + @padd( samples_per_threadgroup, 127, kernel_radius2x_plus1 ) + @pdiv( samples_per_thread, samples_per_threadgroup, 32 ) + +@property( horizontal_pass ) + int iSampleOffset = int( gl_LocalInvocationID.x * @value( samples_per_thread ) ); + int iLineOffset = int( gl_LocalInvocationID.y ); + + int2 i2GroupCoord = int2( ( gl_WorkGroupID.x << 7u ) - @value( kernel_radius )u, gl_WorkGroupID.y << 1u ); + int2 i2Coord = int2( i2GroupCoord.x + iSampleOffset, i2GroupCoord.y ); + + @foreach( samples_per_thread, i ) + g_f3LDS[ iLineOffset ][ iSampleOffset + @i ] = sampleTex( i2Coord + int2( @i, gl_LocalInvocationID.y ) , float2( 0.5f, 0.0f ) );@end + + if( gl_LocalInvocationID.x < @value( samples_per_threadgroup )u - 32u * @value( samples_per_thread )u ) + { + g_f3LDS[ iLineOffset ][ @value(samples_per_threadgroup)u - 1u - gl_LocalInvocationID.x ] = + sampleTex( i2GroupCoord + int2( @value(samples_per_threadgroup)u - 1u - gl_LocalInvocationID.x, gl_LocalInvocationID.y ), float2( 0.5f, 0.0f ) ); + } + + GroupMemoryBarrierWithGroupSync(); + + int iPixelOffset = int( gl_LocalInvocationID.x << 2u ); //gl_LocalInvocationID.x * 4u + i2Coord = int2( i2GroupCoord.x + iPixelOffset, i2GroupCoord.y ); + i2Coord.x += @value( kernel_radius ); + + if( i2Coord.x < int(g_f4OutputSize.x) ) + { + int2 i2Center = i2Coord + int2( 0, gl_LocalInvocationID.y ); + int2 i2Inc = int2 ( 1, 0 ); + + @property( downscale ) + i2Center.x = int( uint( i2Center.x ) >> 1u ); + @end + + ComputeFilterKernel( iPixelOffset, iLineOffset, i2Center, i2Inc ); + } +@end @property( !horizontal_pass ) + int iSampleOffset = int( gl_LocalInvocationID.x * @value( samples_per_thread ) ); + int iLineOffset = int( gl_LocalInvocationID.y ); + + int2 i2GroupCoord = int2( gl_WorkGroupID.x << 1u, ( gl_WorkGroupID.y << 7u ) - @value( kernel_radius )u ); + int2 i2Coord = int2( i2GroupCoord.x, i2GroupCoord.y + iSampleOffset ); + + @foreach( samples_per_thread, i ) + g_f3LDS[ iLineOffset ][ iSampleOffset + @i ] = sampleTex( i2Coord + int2( gl_LocalInvocationID.y, @i ) , float2( 0.0f, 0.5f ) );@end + + if( gl_LocalInvocationID.x < @value( samples_per_threadgroup )u - 32u * @value( samples_per_thread )u ) + { + g_f3LDS[ iLineOffset ][ @value(samples_per_threadgroup)u - 1u - gl_LocalInvocationID.x ] = + sampleTex( i2GroupCoord + int2( gl_LocalInvocationID.y, @value(samples_per_threadgroup)u - 1u - gl_LocalInvocationID.x ), float2( 0.0f, 0.5f ) ); + } + + GroupMemoryBarrierWithGroupSync(); + + int iPixelOffset = int( gl_LocalInvocationID.x << 2u ); //gl_LocalInvocationID.x * 4u + i2Coord = int2( i2GroupCoord.x, i2GroupCoord.y + iPixelOffset ); + i2Coord.y += @value( kernel_radius ); + + if( i2Coord.y < int(g_f4OutputSize.y) ) + { + int2 i2Center = i2Coord + int2( gl_LocalInvocationID.y, 0 ); + int2 i2Inc = int2 ( 0, 1 ); + + @property( downscale ) + i2Center.y = int( uint( i2Center.y ) >> 1u ); + @end + + ComputeFilterKernel( iPixelOffset, iLineOffset, i2Center, i2Inc ); + } +@end +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/GaussianBlurLogFilterBase_cs.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/GaussianBlurLogFilterBase_cs.hlsl new file mode 100644 index 000000000..3369ebe5d --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/GaussianBlurLogFilterBase_cs.hlsl @@ -0,0 +1,263 @@ + +//See GaussianBlurBase_cs for the original. +//This is a derived version which is used for filtering ESM (Exponential Shadow Maps). +//Normally ESM is in exponential space: exp( K * linearSpaceDepth ); +//Filtering should be done in that space. +//However because of precision reasons, we store linearSpaceDepth instead. In order to perform +//correct filtering, we use the following formula: +// exp( filteredDepth ) = w0 * exp( d0 ) + w1 * exp( d1 ) + w2 * exp( d2 ) + ... +// +//But this is not precision friendly. So we do instead: +// = w0 * exp( d0 ) + w1 * exp( d1 ) + w2 * exp( d2 ) +// = exp( d0 ) * ( w0 + w1 * exp( d1 ) / exp( d0 ) + w2 * exp( d2 ) / exp( d0 ) ) +// = exp( d0 ) * ( w0 + w1 * exp( d1 - d0 ) + w2 * exp( d2 - d0 ) ) +// = exp( d0 ) * exp( log( w0 + w1 * exp( d1 - d0 ) + w2 * exp( d2 - d0 ) ) ) +// = exp( d0 + log( w0 + w1 * exp( d1 - d0 ) + w2 * exp( d2 - d0 ) ) ) +// exp( filteredDepth ) = exp( d0 + log( w0 + w1 * exp( d1 - d0 ) + w2 * exp( d2 - d0 ) ) ) +//Almost final formula: +// filteredDepth = d0 + log( w0 + w1 * exp( d1 - d0 ) + w2 * exp( d2 - d0 ) ) +// +//The formula is actually: +// exp( K * filteredDepth ) = w0 * exp( K * d0 ) + w1 * exp( K * d1 ) + w2 * exp( K * d2 ) + ... +//Final formula: +// = d0 + log( w0 + w1 * exp( K * (d1 - d0) ) + w2 * exp( K * (d2 - d0) ) ) / K + +//Like in the original filter: +// * Each thread works on 4 pixels at a time (for VLIW hardware, i.e. Radeon HD 5000 & 6000 series). +// * 256 pixels per threadgroup. Each threadgroup works on 2 rows of 128 pixels each. +// That means 32x2 threads = 64. 64 threads x 4 pixels per thread = 256 + +// For this shader to work, several pieces need to be defined: +// data_type (i.e. float3) +// lds_data_type (i.e. float3, uint) +// lds_definition +// image_store +// image_sample +// decode_lds (optional, i.e. when lds_data_type != data_type) +// Define the property "downscale" if you're doing a downsample. +// Define "downscale_lq" (must also define downscale) for SLIGHTLY lower quality downscale +// The script uses the template syntax to automatically set the num. of threadgroups +// based on the bound input texture. + +SamplerState inputSampler : register(s0); +Texture2D inputImage : register(t0); +RWTexture2D<@insertpiece(uav0_pf_type)> outputImage : register(u0); + +// 32 = 128 / 4 +@pset( threads_per_group_x, 32 ) +@pset( threads_per_group_y, 2 ) +@pset( threads_per_group_z, 1 ) + +@pmul( pixelsPerRow, threads_per_group_x, 4 ) +@pset( rowsPerThreadGroup, threads_per_group_y ) +@pset( num_thread_groups_z, 1 ) + +@set( input_width, uav0_width_with_lod ) +@set( input_height, uav0_height_with_lod ) + +@property( horizontal_pass ) + @property( downscale ) @mul( input_width, 2 ) @end + + /// Calculate num_thread_groups_ + /// num_thread_groups_x = (texture0_width + pixelsPerRow - 1) / pixelsPerRow + /// num_thread_groups_y = (texture0_height + rowsPerThreadGroup - 1) / rowsPerThreadGroup + @add( num_thread_groups_x, input_width, pixelsPerRow ) + @sub( num_thread_groups_x, 1 ) + @div( num_thread_groups_x, pixelsPerRow ) + + @add( num_thread_groups_y, input_height, rowsPerThreadGroup ) + @sub( num_thread_groups_y, 1 ) + @div( num_thread_groups_y, rowsPerThreadGroup ) +@end @property( !horizontal_pass ) + @property( downscale ) @mul( input_height, 2 ) @end + + /// Calculate num_thread_groups_ + /// num_thread_groups_x = (texture0_width + rowsPerThreadGroup - 1) / rowsPerThreadGroup + /// num_thread_groups_y = (texture0_height + pixelsPerRow - 1) / pixelsPerRow + @add( num_thread_groups_x, input_width, rowsPerThreadGroup ) + @sub( num_thread_groups_x, 1 ) + @div( num_thread_groups_x, rowsPerThreadGroup ) + + @add( num_thread_groups_y, input_height, pixelsPerRow ) + @sub( num_thread_groups_y, 1 ) + @div( num_thread_groups_y, pixelsPerRow ) +@end + +/// groupshared float3 g_f3LDS[ 2 ] [ @value( samples_per_threadgroup ) ]; +@insertpiece( lds_definition ) + +uniform float4 g_f4OutputSize; + +//Tightly pack the weights +uniform float4 c_weights[(@value( kernel_radius_plus1 ) + 3u) / 4u]; + +@insertpiece( lds_data_type ) sampleTex( int2 i2Position , float2 f2Offset ) +{ + float2 f2SamplePosition = float2( i2Position ) + float2( 0.5f, 0.5f ); + + f2SamplePosition *= g_f4OutputSize.zw; + ///return inputImage.SampleLevel( inputSampler, f2SamplePosition, 0 ).x; + @insertpiece( image_sample ) +} + +void ComputeFilterKernel( int iPixelOffset, int iLineOffset, int2 i2Center, int2 i2Inc ) +{ + @property( !downscale_lq ) + @insertpiece( data_type ) outColour[ 4 ]; + @insertpiece( data_type ) firstSmpl[ 4 ]; + @end @property( downscale_lq ) + @insertpiece( data_type ) outColour[ 2 ]; + @insertpiece( data_type ) firstSmpl[ 2 ]; + @end + @insertpiece( data_type ) RDI[ 4 ] ; + + @foreach( 4, iPixel ) + RDI[ @iPixel ] = @insertpiece( decode_lds )( g_f3LDS[ iLineOffset ][ iPixelOffset + @value( kernel_radius ) + @iPixel ] );@end + + @property( !downscale_lq ) + @foreach( 4, iPixel ) + firstSmpl[ @iPixel ].x = RDI[ @iPixel ]; + outColour[ @iPixel ].x = c_weights[ @value( kernel_radius ) >> 2u ][ @value( kernel_radius ) & 3u ];@end + @end @property( downscale_lq ) + @foreach( 2, iPixel ) + firstSmpl[ @iPixel ].x = RDI[ @iPixel * 2 ]; + outColour[ @iPixel ].x = c_weights[ @value( kernel_radius ) >> 2u ][ @value( kernel_radius ) & 3u ];@end + @end + + @foreach( 4, iPixel ) + RDI[ @iPixel ] = @insertpiece( decode_lds )( g_f3LDS[ iLineOffset ][ iPixelOffset + @iPixel ] );@end + + iPixelOffset += 4; + + /// Deal with taps to our left. + /// for ( iIteration = 0; iIteration < radius; iIteration += 1 ) + @foreach( kernel_radius, iIteration ) + @property( !downscale_lq ) + @foreach( 4, iPixel ) + outColour[ @iPixel ].x += exp(@value(K)*(RDI[ @iPixel ] - firstSmpl[ @iPixel ])) * c_weights[ @iIteration >> 2u ][ @iIteration & 3u ];@end + @end @property( downscale_lq ) + @foreach( 2, iPixel ) + outColour[ @iPixel ].x += exp(@value(K)*(RDI[ @iPixel * 2 ] - firstSmpl[ @iPixel ])) * c_weights[ @iIteration >> 2u ][ @iIteration & 3u ];@end + @end + @foreach( 3, iPixel ) + RDI[ @iPixel ] = RDI[ @iPixel + ( 1 ) ];@end + @foreach( 1, iPixel ) + RDI[ 4 - 1 + @iPixel ] = @insertpiece( decode_lds )( g_f3LDS[ iLineOffset ][ iPixelOffset + @iIteration + @iPixel ] );@end + @end + + @foreach( 4, iPixel ) + RDI[ @iPixel ] = @insertpiece( decode_lds )( g_f3LDS[ iLineOffset ][ iPixelOffset - 4 + @value( kernel_radius ) + 1 + @iPixel ] );@end + + @padd( kernel_radius_plus1, kernel_radius, 1 ) + @pmul( kernel_radius2x_plus1, kernel_radius, 2 ) + @padd( kernel_radius2x_plus1, 1 ) + + @pmul( kernel_radius2x, kernel_radius, 2 ) + + /// Deal with taps to our right. + /// for ( iIteration = radius + 1; iIteration < ( radius * 2 + 1 ); iIteration += 1 ) + @foreach( kernel_radius2x_plus1, iIteration, kernel_radius_plus1 ) + @property( !downscale_lq ) + @foreach( 4, iPixel ) + outColour[ @iPixel ].x += exp(@value(K)*(RDI[ @iPixel ] - firstSmpl[ @iPixel ])) * c_weights[ (@value( kernel_radius2x ) - @iIteration) >> 2u ][ (@value( kernel_radius2x ) - @iIteration) & 3u ];@end + @end @property( downscale_lq ) + @foreach( 2, iPixel ) + outColour[ @iPixel ].x += exp(@value(K)*(RDI[ @iPixel * 2 ] - firstSmpl[ @iPixel ])) * c_weights[ (@value( kernel_radius2x ) - @iIteration) >> 2u ][ (@value( kernel_radius2x ) - @iIteration) & 3u ];@end + @end + @foreach( 3, iPixel ) + RDI[ @iPixel ] = RDI[ @iPixel + ( 1 ) ];@end + @foreach( 1, iPixel ) + RDI[ 4 - 1 + @iPixel ] = @insertpiece( decode_lds )( g_f3LDS[ iLineOffset ][ iPixelOffset + @iIteration + @iPixel ] );@end + @end + + @property( !downscale_lq ) + @foreach( 4, iPixel ) + outColour[ @iPixel ] = firstSmpl[ @iPixel ] + log( outColour[ @iPixel ] ) / @value(K);@end + @end @property( downscale_lq ) + @foreach( 2, iPixel ) + outColour[ @iPixel ] = firstSmpl[ @iPixel ] + log( outColour[ @iPixel ] ) / @value(K);@end + @end + + /* + foreach( 4, iPixel ) + outputImage[i2Center + iPixel * i2Inc] = float4( outColour[ iPixel ], 1.0 ) );end + */ + @insertpiece( image_store ) +} + +[numthreads(@value( threads_per_group_x ), @value( threads_per_group_y ), @value( threads_per_group_z ))] +void main( uint3 gl_WorkGroupID : SV_GroupID, uint3 gl_LocalInvocationID : SV_GroupThreadID ) +{ + /// samples_per_threadgroup = 128 + ( ( kernel_radius * 2 + 1 ) - 1 ) + /// samples_per_thread = ( 128 + ( ( kernel_radius * 2 + 1 ) - 1 ) ) / ( 128 / 4 ) + @padd( samples_per_threadgroup, 127, kernel_radius2x_plus1 ) + @pdiv( samples_per_thread, samples_per_threadgroup, 32 ) + +@property( horizontal_pass ) + int iSampleOffset = int( gl_LocalInvocationID.x * @value( samples_per_thread ) ); + int iLineOffset = int( gl_LocalInvocationID.y ); + + int2 i2GroupCoord = int2( ( gl_WorkGroupID.x << 7u ) - @value( kernel_radius )u, gl_WorkGroupID.y << 1u ); + int2 i2Coord = int2( i2GroupCoord.x + iSampleOffset, i2GroupCoord.y ); + + @foreach( samples_per_thread, i ) + g_f3LDS[ iLineOffset ][ iSampleOffset + @i ] = sampleTex( i2Coord + int2( @i, gl_LocalInvocationID.y ) , float2( 0.5f, 0.0f ) );@end + + if( gl_LocalInvocationID.x < @value( samples_per_threadgroup )u - 32u * @value( samples_per_thread )u ) + { + g_f3LDS[ iLineOffset ][ @value(samples_per_threadgroup)u - 1u - gl_LocalInvocationID.x ] = + sampleTex( i2GroupCoord + int2( @value(samples_per_threadgroup)u - 1u - gl_LocalInvocationID.x, gl_LocalInvocationID.y ), float2( 0.5f, 0.0f ) ); + } + + GroupMemoryBarrierWithGroupSync(); + + int iPixelOffset = int( gl_LocalInvocationID.x << 2u ); //gl_LocalInvocationID.x * 4u + i2Coord = int2( i2GroupCoord.x + iPixelOffset, i2GroupCoord.y ); + i2Coord.x += @value( kernel_radius ); + + if( i2Coord.x < int(g_f4OutputSize.x) ) + { + int2 i2Center = i2Coord + int2( 0, gl_LocalInvocationID.y ); + int2 i2Inc = int2 ( 1, 0 ); + + @property( downscale ) + i2Center.x = int( uint( i2Center.x ) >> 1u ); + @end + + ComputeFilterKernel( iPixelOffset, iLineOffset, i2Center, i2Inc ); + } +@end @property( !horizontal_pass ) + int iSampleOffset = int( gl_LocalInvocationID.x * @value( samples_per_thread ) ); + int iLineOffset = int( gl_LocalInvocationID.y ); + + int2 i2GroupCoord = int2( gl_WorkGroupID.x << 1u, ( gl_WorkGroupID.y << 7u ) - @value( kernel_radius )u ); + int2 i2Coord = int2( i2GroupCoord.x, i2GroupCoord.y + iSampleOffset ); + + @foreach( samples_per_thread, i ) + g_f3LDS[ iLineOffset ][ iSampleOffset + @i ] = sampleTex( i2Coord + int2( gl_LocalInvocationID.y, @i ) , float2( 0.0f, 0.5f ) );@end + + if( gl_LocalInvocationID.x < @value( samples_per_threadgroup )u - 32u * @value( samples_per_thread )u ) + { + g_f3LDS[ iLineOffset ][ @value(samples_per_threadgroup)u - 1u - gl_LocalInvocationID.x ] = + sampleTex( i2GroupCoord + int2( gl_LocalInvocationID.y, @value(samples_per_threadgroup)u - 1u - gl_LocalInvocationID.x ), float2( 0.0f, 0.5f ) ); + } + + GroupMemoryBarrierWithGroupSync(); + + int iPixelOffset = int( gl_LocalInvocationID.x << 2u ); //gl_LocalInvocationID.x * 4u + i2Coord = int2( i2GroupCoord.x, i2GroupCoord.y + iPixelOffset ); + i2Coord.y += @value( kernel_radius ); + + if( i2Coord.y < int(g_f4OutputSize.y) ) + { + int2 i2Center = i2Coord + int2( gl_LocalInvocationID.y, 0 ); + int2 i2Inc = int2 ( 0, 1 ); + + @property( downscale ) + i2Center.y = int( uint( i2Center.y ) >> 1u ); + @end + + ComputeFilterKernel( iPixelOffset, iLineOffset, i2Center, i2Inc ); + } +@end +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/GaussianBlurLogFilter_ps.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/GaussianBlurLogFilter_ps.hlsl new file mode 100644 index 000000000..471cbde9f --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/GaussianBlurLogFilter_ps.hlsl @@ -0,0 +1,43 @@ + +struct PS_INPUT +{ + float2 uv0 : TEXCOORD0; +}; + +Texture2D tex : register(t0); + +float4 main +( + PS_INPUT inPs, + uniform float4 weights[(NUM_WEIGHTS + 3u) / 4u], + float4 gl_FragCoord : SV_Position +) : SV_Target +{ + float val; + float outColour; + float firstSmpl; + + firstSmpl = tex.Load( int3( int2( gl_FragCoord.xy ) - int2( HORIZONTAL_STEP * (NUM_WEIGHTS - 1), + VERTICAL_STEP * (NUM_WEIGHTS - 1) ), 0 ) ).x; + outColour = weights[0][0]; + + int i; + for( i=NUM_WEIGHTS - 1; (--i) > 0; ) + { + val = tex.Load( int3( int2( gl_FragCoord.xy ) - int2( HORIZONTAL_STEP * i, + VERTICAL_STEP * i ), 0 ) ).x; + outColour += exp( K * (val - firstSmpl) ) * weights[(NUM_WEIGHTS-i-1u) >> 2u][(NUM_WEIGHTS-i-1u) & 3u]; + } + + val = tex.Load( int3( gl_FragCoord.xy, 0 ) ).x; + outColour += exp( K * (val - firstSmpl) ) * weights[(NUM_WEIGHTS-1u) >> 2u][(NUM_WEIGHTS-1u) & 3u]; + + for( i=0; i> 2u][(NUM_WEIGHTS-i-2u) & 3u]; + } + + return firstSmpl + log( outColour ) / K; +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/HiddenAreaMeshVr_ps.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/HiddenAreaMeshVr_ps.hlsl new file mode 100644 index 000000000..5459e7559 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/HiddenAreaMeshVr_ps.hlsl @@ -0,0 +1,4 @@ +float4 main() : SV_Target +{ + return float4( 0, 0, 0, 0 ); +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/HiddenAreaMeshVr_vs.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/HiddenAreaMeshVr_vs.hlsl new file mode 100644 index 000000000..dfd4aeaca --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/HiddenAreaMeshVr_vs.hlsl @@ -0,0 +1,27 @@ +struct VS_INPUT +{ + float4 position : POSITION; +}; + +struct PS_INPUT +{ + float4 gl_Position : SV_Position; + uint gl_ViewportIndex : SV_ViewportArrayIndex; +}; + +PS_INPUT main +( + VS_INPUT input, + uniform float4x4 projectionMatrix, + uniform float2 rsDepthRange +) +{ + PS_INPUT outVs; + + outVs.gl_Position.xy = mul( projectionMatrix, float4( input.position.xy, 0.0f, 1.0f ) ).xy; + outVs.gl_Position.z = rsDepthRange.x; + outVs.gl_Position.w = 1.0f; + outVs.gl_ViewportIndex = int( input.position.z ); + + return outVs; +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/MipmapsGaussianBlur_cs.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/MipmapsGaussianBlur_cs.hlsl new file mode 100644 index 000000000..5c304ed17 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/MipmapsGaussianBlur_cs.hlsl @@ -0,0 +1,37 @@ +//Based on GPUOpen's samples SeparableFilter11 +//https://github.com/GPUOpen-LibrariesAndSDKs/SeparableFilter11 +//For better understanding, read "Efficient Compute Shader Programming" from Bill Bilodeau +//http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/Efficient%20Compute%20Shader%20Programming.pps + +//TL;DR: +// * Each thread works on 4 pixels at a time (for VLIW hardware, i.e. Radeon HD 5000 & 6000 series). +// * 256 pixels per threadgroup. Each threadgroup works on 2 rows of 128 pixels each. +// That means 32x2 threads = 64. 64 threads x 4 pixels per thread = 256 + +@piece( data_type )float3@end +@piece( lds_data_type )float3@end +@piece( lds_definition ) + groupshared float3 g_f3LDS[ 2 ] [ @value( samples_per_threadgroup ) ]; + uniform float srcLodIdx; +@end + +@piece( image_sample ) + return inputImage.SampleLevel( inputSampler, f2SamplePosition, srcLodIdx ).xyz; +@end + +//Overwrite these so that num_thread_groups gets correctly calculated by accounting LOD. +@pset( texture0_width, width_with_lod ) +@pset( texture0_height, height_with_lod ) + +@pset( downscale_lq, 1 ) + +@piece( image_store ) + @property( downscale_lq ) + @foreach( 2, iPixel ) + outputImage[i2Center + @iPixel * i2Inc] = float4( outColour[ @iPixel ], 1.0 );@end + @end @property( !downscale_lq ) + @foreach( 2, iPixel ) + outputImage[i2Center + @iPixel * i2Inc] = float4( (outColour[ @iPixel * 2 ] + + outColour[ @iPixel * 2 + 1 ]) * 0.5, 1.0 );@end + @end +@end diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/PccDepthCompressor_ps.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/PccDepthCompressor_ps.hlsl new file mode 100644 index 000000000..c40a01f27 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/PccDepthCompressor_ps.hlsl @@ -0,0 +1,39 @@ + +#define INLINE + +#define OGRE_Sample( tex, sampler, uv ) tex.Sample( sampler, uv ) + +struct PS_INPUT +{ + float2 uv0 : TEXCOORD0; + float3 cameraDir : TEXCOORD1; +}; + +Texture2D depthTexture : register(t0); +SamplerState pointSampler : register(s0); + +uniform float2 projectionParams; +uniform float3 probeShapeHalfSize; +uniform float3 cameraPosLS; + +uniform float3x3 viewSpaceToProbeLocalSpace; + +#define p_projectionParams projectionParams +#define p_probeShapeHalfSize probeShapeHalfSize +#define p_cameraPosLS cameraPosLS +#define p_viewSpaceToProbeLocalSpace viewSpaceToProbeLocalSpace + +#define HEADER + #include "PccDepthCompressor_ps.any" +#undef HEADER + +float4 main +( + PS_INPUT inPs +) : SV_Target0 +{ + #include "PccDepthCompressor_ps.any" + + //RGB writes should be masked off + return float4( 0, 0, 0, alpha ); +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/QuadCameraDirNoUV_vs.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/QuadCameraDirNoUV_vs.hlsl new file mode 100644 index 000000000..991642434 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/QuadCameraDirNoUV_vs.hlsl @@ -0,0 +1,31 @@ + +struct VS_INPUT +{ + float2 vertex : POSITION; + float3 normal : NORMAL; +}; + +struct PS_INPUT +{ + float3 cameraDir : TEXCOORD0; + + float4 gl_Position : SV_Position; +}; + +PS_INPUT main +( + VS_INPUT input, + + uniform float2 rsDepthRange, + uniform matrix worldViewProj +) +{ + PS_INPUT outVs; + + outVs.gl_Position.xy= mul( worldViewProj, float4( input.vertex.xy, 0.0f, 1.0f ) ).xy; + outVs.gl_Position.z = rsDepthRange.y; + outVs.gl_Position.w = 1.0f; + outVs.cameraDir = input.normal; + + return outVs; +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/QuadCameraDir_vs.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/QuadCameraDir_vs.hlsl new file mode 100644 index 000000000..cbd569d50 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/QuadCameraDir_vs.hlsl @@ -0,0 +1,31 @@ + +struct VS_INPUT +{ + float4 vertex : POSITION; + float3 normal : NORMAL; + float2 uv0 : TEXCOORD0; +}; + +struct PS_INPUT +{ + float2 uv0 : TEXCOORD0; + float3 cameraDir : TEXCOORD1; + + float4 gl_Position : SV_Position; +}; + +PS_INPUT main +( + VS_INPUT input, + + uniform matrix worldViewProj +) +{ + PS_INPUT outVs; + + outVs.gl_Position = mul( worldViewProj, input.vertex ).xyzw; + outVs.uv0 = input.uv0; + outVs.cameraDir = input.normal; + + return outVs; +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/Quad_vs.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/Quad_vs.hlsl new file mode 100644 index 000000000..503133b27 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/Quad_vs.hlsl @@ -0,0 +1,25 @@ +struct VS_INPUT +{ + float4 vertex : POSITION; + float2 uv0 : TEXCOORD0; +}; + +struct PS_INPUT +{ + float2 uv0 : TEXCOORD0; + float4 gl_Position : SV_Position; +}; + +PS_INPUT main +( + VS_INPUT input, + uniform matrix worldViewProj +) +{ + PS_INPUT outVs; + + outVs.gl_Position = mul( worldViewProj, input.vertex ).xyzw; + outVs.uv0 = input.uv0; + + return outVs; +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/RadialDensityMask_ps.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/RadialDensityMask_ps.hlsl new file mode 100644 index 000000000..5f7f2eecf --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/RadialDensityMask_ps.hlsl @@ -0,0 +1,35 @@ + +#define p_leftEyeCenter leftEyeCenter_rightEyeCenter.xy +#define p_rightEyeCenter leftEyeCenter_rightEyeCenter.zw +#define p_rightEyeStart rightEyeStart_radius.x +#define p_radius rightEyeStart_radius.yzw +#define p_invBlockResolution invBlockResolution + +float4 main +( + float4 gl_FragCoord : SV_Position, + + uniform float4 rightEyeStart_radius, + uniform float4 leftEyeCenter_rightEyeCenter, + uniform float2 invBlockResolution +) : SV_Target +{ + float2 eyeCenter = gl_FragCoord.x >= p_rightEyeStart ? p_rightEyeCenter : p_leftEyeCenter; + + //We must work in blocks so the reconstruction filter can work properly + float2 toCenter = trunc(gl_FragCoord.xy * 0.125f) * p_invBlockResolution.xy - eyeCenter; + toCenter.x *= 2.0f; //Twice because of stereo (each eye is half the size of the full res) + float distToCenter = length( toCenter ); + + uint2 iFragCoordHalf = uint2( gl_FragCoord.xy * 0.5f ); + if( distToCenter < p_radius.x ) + discard; + else if( (iFragCoordHalf.x & 0x01u) == (iFragCoordHalf.y & 0x01u) && distToCenter < p_radius.y ) + discard; + else if( !((iFragCoordHalf.x & 0x01u) != 0u || (iFragCoordHalf.y & 0x01u) != 0u) && distToCenter < p_radius.z ) + discard; + else if( !((iFragCoordHalf.x & 0x03u) != 0u || (iFragCoordHalf.y & 0x03u) != 0u) ) + discard; + + return float4( 0, 0, 0, 0 ); +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/RadialDensityMask_vs.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/RadialDensityMask_vs.hlsl new file mode 100644 index 000000000..7dfe97236 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/RadialDensityMask_vs.hlsl @@ -0,0 +1,31 @@ +struct VS_INPUT +{ + float2 vertex : POSITION; + uint vertexId : SV_VertexID; + #define gl_VertexID input.vertexId +}; + +struct PS_INPUT +{ + float4 gl_Position : SV_Position; + uint gl_ViewportIndex : SV_ViewportArrayIndex; +}; + +PS_INPUT main +( + VS_INPUT input, + + uniform float ogreBaseVertex, + uniform float2 rsDepthRange, + uniform matrix worldViewProj +) +{ + PS_INPUT outVs; + + outVs.gl_Position.xy= mul( worldViewProj, float4( input.vertex.xy, 0.0f, 1.0f ) ).xy; + outVs.gl_Position.z = rsDepthRange.x; + outVs.gl_Position.w = 1.0f; + outVs.gl_ViewportIndex = gl_VertexID >= (3 * 4) ? 1 : 0; + + return outVs; +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/Resolve_1xFP32_Subsample0_ps.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/Resolve_1xFP32_Subsample0_ps.hlsl new file mode 100644 index 000000000..f228b5cfa --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/Resolve_1xFP32_Subsample0_ps.hlsl @@ -0,0 +1,16 @@ + +Texture2DMS myTexture : register(t0); + +struct PS_INPUT +{ + float2 uv0 : TEXCOORD0; +}; + +float main +( + PS_INPUT inPs, + float4 gl_FragCoord : SV_Position +) : SV_Target +{ + return myTexture.Load( int2( gl_FragCoord.xy ), 0 ).x; +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/SkyCubemap_ps.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/SkyCubemap_ps.hlsl new file mode 100644 index 000000000..61e814f09 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/SkyCubemap_ps.hlsl @@ -0,0 +1,16 @@ +struct PS_INPUT +{ + float3 cameraDir : TEXCOORD0; +}; + +TextureCube skyCubemap : register(t0); +SamplerState samplerState : register(s0); + +float4 main +( + PS_INPUT inPs +) : SV_Target0 +{ + //Cubemaps are left-handed + return skyCubemap.Sample( samplerState, float3( inPs.cameraDir.xy, -inPs.cameraDir.z ) ); +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HLSL/SkyEquirectangular_ps.hlsl b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/SkyEquirectangular_ps.hlsl new file mode 100644 index 000000000..f781e63a5 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HLSL/SkyEquirectangular_ps.hlsl @@ -0,0 +1,25 @@ +#define PI 3.14159265359f + +struct PS_INPUT +{ + float3 cameraDir : TEXCOORD0; +}; + +Texture2DArray skyEquirectangular : register(t0); +SamplerState samplerState : register(s0); + +float4 main +( + PS_INPUT inPs, + + uniform float sliceIdx +) : SV_Target0 +{ + float3 cameraDir = normalize( inPs.cameraDir ); + float2 longlat; + longlat.x = atan2( cameraDir.x, -cameraDir.z ) + PI; + longlat.y = acos( cameraDir.y ); + float2 uv = longlat / float2( 2.0f * PI, PI ); + + return skyEquirectangular.Sample( samplerState, float3( uv.xy, sliceIdx ) ); +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/HiddenAreaMeshVr.material b/ogre2/src/media/2.0/scripts/materials/Common/HiddenAreaMeshVr.material new file mode 100644 index 000000000..830e833b7 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/HiddenAreaMeshVr.material @@ -0,0 +1,95 @@ +vertex_program Ogre/VR/HiddenAreaMeshVr_vs_GLSL glsl +{ + source HiddenAreaMeshVr_vs.glsl +} + +vertex_program Ogre/VR/HiddenAreaMeshVr_vs_VK glslvk +{ + source HiddenAreaMeshVr_vs.glsl +} + +vertex_program Ogre/VR/HiddenAreaMeshVr_vs_HLSL hlsl +{ + source HiddenAreaMeshVr_vs.hlsl + entry_point main + sets_vp_or_rt_array_index true + target vs_5_0 vs_4_0 vs_4_0_level_9_1 vs_4_0_level_9_3 +} + +vertex_program Ogre/VR/HiddenAreaMeshVr_vs_Metal metal +{ + source HiddenAreaMeshVr_vs.metal + shader_reflection_pair_hint Ogre/VR/HiddenAreaMeshVr_vs +} + +vertex_program Ogre/VR/HiddenAreaMeshVr_vs unified +{ + delegate Ogre/VR/HiddenAreaMeshVr_vs_GLSL + delegate Ogre/VR/HiddenAreaMeshVr_vs_VK + delegate Ogre/VR/HiddenAreaMeshVr_vs_HLSL + delegate Ogre/VR/HiddenAreaMeshVr_vs_Metal + + default_params + { + param_named_auto projectionMatrix projection_matrix + param_named_auto rsDepthRange rs_depth_range + } +} + +fragment_program Ogre/VR/HiddenAreaMeshVr_ps_GLSL glsl +{ + source HiddenAreaMeshVr_ps.glsl +} + +fragment_program Ogre/VR/HiddenAreaMeshVr_ps_VK glslvk +{ + source HiddenAreaMeshVr_ps.glsl +} + +fragment_program Ogre/VR/HiddenAreaMeshVr_ps_HLSL hlsl +{ + source HiddenAreaMeshVr_ps.hlsl + entry_point main + target ps_5_0 ps_4_0 ps_4_0_level_9_1 ps_4_0_level_9_3 +} + +fragment_program Ogre/VR/HiddenAreaMeshVr_ps_Metal metal +{ + source HiddenAreaMeshVr_ps.metal + shader_reflection_pair_hint Ogre/VR/HiddenAreaMeshVr_vs +} + +fragment_program Ogre/VR/HiddenAreaMeshVr_ps unified +{ + delegate Ogre/VR/HiddenAreaMeshVr_ps_GLSL + delegate Ogre/VR/HiddenAreaMeshVr_ps_VK + delegate Ogre/VR/HiddenAreaMeshVr_ps_HLSL + delegate Ogre/VR/HiddenAreaMeshVr_ps_Metal +} + +material Ogre/VR/HiddenAreaMeshVr +{ + technique + { + pass + { + //depth_check off + //depth_write off + + cull_hardware none + + depth_func always_pass + + //Do not write colour at all + channel_mask 0 + + vertex_program_ref Ogre/VR/HiddenAreaMeshVr_vs + { + } + + fragment_program_ref Ogre/VR/HiddenAreaMeshVr_ps + { + } + } + } +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/Metal/AtmosphereNprSky_ps.metal b/ogre2/src/media/2.0/scripts/materials/Common/Metal/AtmosphereNprSky_ps.metal new file mode 100644 index 000000000..deea9fa2d --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/Metal/AtmosphereNprSky_ps.metal @@ -0,0 +1,56 @@ +#include +using namespace metal; + +#define lerp mix + +struct PS_INPUT +{ + float3 cameraDir; +}; + +struct Params +{ + float4 packedParams0; + float3 skyLightAbsorption; + float4 sunAbsorption; + float4 cameraDisplacement; + float4 packedParams1; + float4 packedParams2; + float4 packedParams3; +}; + +#define p_densityCoeff p.packedParams0.x +#define p_lightDensity p.packedParams0.y +#define p_sunHeight p.packedParams0.z +#define p_sunHeightWeight p.packedParams0.w +#define p_skyLightAbsorption p.skyLightAbsorption +#define p_sunAbsorption p.sunAbsorption.xyz +#define p_sunPower p.sunAbsorption.w +#define p_cameraDisplacement p.cameraDisplacement +#define p_mieAbsorption p.packedParams1.xyz +#define p_finalMultiplier p.packedParams1.w +#define p_sunDir p.packedParams2.xyz +#define p_borderLimit p.packedParams2.w +#define p_skyColour p.packedParams3.xyz +#define p_densityDiffusion p.packedParams3.w + +#define HEADER +#include "AtmosphereNprSky_ps.any" +#undef HEADER + +fragment float4 main_metal +( + PS_INPUT inPs [[stage_in]], + + constant Params &p [[buffer(PARAMETER_SLOT)]] +) +{ + float4 fragColour; + + #include "AtmosphereNprSky_ps.any" + + fragColour.xyz = atmoColour; + fragColour.w = 1.0f; + + return fragColour; +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/Metal/MipmapsGaussianBlur_cs.metal b/ogre2/src/media/2.0/scripts/materials/Common/Metal/MipmapsGaussianBlur_cs.metal index bf23ddd2e..782b52a7b 100644 --- a/ogre2/src/media/2.0/scripts/materials/Common/Metal/MipmapsGaussianBlur_cs.metal +++ b/ogre2/src/media/2.0/scripts/materials/Common/Metal/MipmapsGaussianBlur_cs.metal @@ -15,7 +15,6 @@ @end @piece( extra_params ) float srcLodIdx; - uint dstLodIdx; @end @piece( image_sample ) @@ -32,11 +31,11 @@ @property( downscale_lq ) @foreach( 2, iPixel ) outputImage.write( float4( outColour[ @iPixel ], 1.0 ), uint2( i2Center + @iPixel * i2Inc ), - p.dstLodIdx );@end + 0u );@end @end @property( !downscale_lq ) @foreach( 2, iPixel ) outputImage.write( float4( (outColour[ @iPixel * 2 ] + outColour[ @iPixel * 2 + 1 ]) * 0.5, 1.0 ), uint2( i2Center + @iPixel * i2Inc ), - p.dstLodIdx );@end + 0u );@end @end @end diff --git a/ogre2/src/media/2.0/scripts/materials/Common/PccDepthCompressor.material b/ogre2/src/media/2.0/scripts/materials/Common/PccDepthCompressor.material new file mode 100644 index 000000000..ada1aa4c4 --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/PccDepthCompressor.material @@ -0,0 +1,74 @@ + +// GLSL shaders +fragment_program PccDepthCompressor_ps_GLSL glsl +{ + source PccDepthCompressor_ps.glsl + enable_include_header true + default_params + { + param_named depthTexture int 0 + } +} + +fragment_program PccDepthCompressor_ps_VK glslvk +{ + source PccDepthCompressor_ps.glsl + enable_include_header true +} + +// HLSL shaders +fragment_program PccDepthCompressor_ps_HLSL hlsl +{ + source PccDepthCompressor_ps.hlsl + entry_point main + target ps_5_0 ps_4_0 ps_4_0_level_9_1 ps_4_0_level_9_3 +} + +// Metal shaders +fragment_program PccDepthCompressor_ps_Metal metal +{ + source PccDepthCompressor_ps.metal + enable_include_header true + shader_reflection_pair_hint Ogre/Compositor/QuadCameraDir_vs +} + +// Unified definitions +fragment_program PccDepthCompressor_ps unified +{ + delegate PccDepthCompressor_ps_HLSL + delegate PccDepthCompressor_ps_GLSL + delegate PccDepthCompressor_ps_VK + delegate PccDepthCompressor_ps_Metal +} + +// Material definition +material PCC/DepthCompressor +{ + technique + { + pass + { + depth_check off + depth_write off + + cull_hardware none + + //Only write to alpha channel + channel_mask a + + vertex_program_ref Ogre/Compositor/QuadCameraDir_vs + { + } + + fragment_program_ref PccDepthCompressor_ps + { + } + + texture_unit + { + filtering none + tex_address_mode clamp + } + } + } +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/Quad.program b/ogre2/src/media/2.0/scripts/materials/Common/Quad.program index 10dc15a92..bfb0159c0 100644 --- a/ogre2/src/media/2.0/scripts/materials/Common/Quad.program +++ b/ogre2/src/media/2.0/scripts/materials/Common/Quad.program @@ -5,7 +5,7 @@ vertex_program Ogre/Compositor/Quad_vs_GLSL glsl vertex_program Ogre/Compositor/Quad_vs_VK glslvk { - source Quad_vs.glsl + source Quad_vs.glsl } vertex_program Ogre/Compositor/Quad_vs_GLSLES glsles diff --git a/ogre2/src/media/2.0/scripts/materials/Common/RadialDensityMask.material b/ogre2/src/media/2.0/scripts/materials/Common/RadialDensityMask.material new file mode 100644 index 000000000..73271da1f --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/RadialDensityMask.material @@ -0,0 +1,90 @@ +vertex_program Ogre/Compositor/RadialDensityMask_vs_GLSL glsl +{ + source RadialDensityMask_vs.glsl +} + +vertex_program Ogre/Compositor/RadialDensityMask_vs_VK glslvk +{ + source RadialDensityMask_vs.glsl +} + +vertex_program Ogre/Compositor/RadialDensityMask_vs_HLSL hlsl +{ + source RadialDensityMask_vs.hlsl + entry_point main + sets_vp_or_rt_array_index true + target vs_5_0 vs_4_0 vs_4_0_level_9_1 vs_4_0_level_9_3 +} + +vertex_program Ogre/Compositor/RadialDensityMask_vs_Metal metal +{ + source RadialDensityMask_vs.metal +} + +// Unified definitions +vertex_program Ogre/Compositor/RadialDensityMask_vs unified +{ + delegate Ogre/Compositor/RadialDensityMask_vs_GLSL + delegate Ogre/Compositor/RadialDensityMask_vs_VK + delegate Ogre/Compositor/RadialDensityMask_vs_HLSL + delegate Ogre/Compositor/RadialDensityMask_vs_Metal + + default_params + { + param_named_auto worldViewProj worldviewproj_matrix + param_named_auto rsDepthRange rs_depth_range + } +} + +fragment_program Ogre/VR/RadialDensityMask_ps_GLSL glsl +{ + source RadialDensityMask_ps.glsl +} + +fragment_program Ogre/VR/RadialDensityMask_ps_VK glslvk +{ + source RadialDensityMask_ps.glsl +} + +fragment_program Ogre/VR/RadialDensityMask_ps_HLSL hlsl +{ + source RadialDensityMask_ps.hlsl + entry_point main + target ps_5_0 ps_4_0 ps_4_0_level_9_1 ps_4_0_level_9_3 +} + +fragment_program Ogre/VR/RadialDensityMask_ps_Metal metal +{ + source RadialDensityMask_ps.metal + shader_reflection_pair_hint Ogre/Compositor/RadialDensityMask_vs +} + +fragment_program Ogre/VR/RadialDensityMask_ps unified +{ + delegate Ogre/VR/RadialDensityMask_ps_GLSL + delegate Ogre/VR/RadialDensityMask_ps_VK + delegate Ogre/VR/RadialDensityMask_ps_HLSL + delegate Ogre/VR/RadialDensityMask_ps_Metal +} + +material Ogre/VR/RadialDensityMask +{ + technique + { + pass + { + cull_hardware none + + //Do not write colour at all + //channel_mask 0 + + vertex_program_ref Ogre/Compositor/RadialDensityMask_vs + { + } + + fragment_program_ref Ogre/VR/RadialDensityMask_ps + { + } + } + } +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/Sky.material b/ogre2/src/media/2.0/scripts/materials/Common/Sky.material new file mode 100644 index 000000000..7e11bdc7e --- /dev/null +++ b/ogre2/src/media/2.0/scripts/materials/Common/Sky.material @@ -0,0 +1,137 @@ + +// GLSL shaders +fragment_program Ogre/Sky/Cubemap_ps_GLSL glsl +{ + source SkyCubemap_ps.glsl + default_params + { + param_named skyCubemap int 0 + } +} + +fragment_program Ogre/Sky/Cubemap_ps_VK glslvk +{ + source SkyCubemap_ps.glsl +} + +// HLSL shaders +fragment_program Ogre/Sky/Cubemap_ps_HLSL hlsl +{ + source SkyCubemap_ps.hlsl + entry_point main + target ps_5_0 ps_4_0 ps_4_0_level_9_1 ps_4_0_level_9_3 +} + +// Metal shaders +fragment_program Ogre/Sky/Cubemap_ps_Metal metal +{ + source SkyCubemap_ps.metal + shader_reflection_pair_hint Ogre/Compositor/QuadCameraDirNoUV_vs +} + +// Unified definitions +fragment_program Ogre/Sky/Cubemap_ps unified +{ + delegate Ogre/Sky/Cubemap_ps_HLSL + delegate Ogre/Sky/Cubemap_ps_VK + delegate Ogre/Sky/Cubemap_ps_GLSL + delegate Ogre/Sky/Cubemap_ps_Metal +} + +// Material definition +material Ogre/Sky/Cubemap +{ + technique + { + pass + { + depth_check on + depth_write off + + cull_hardware none + + vertex_program_ref Ogre/Compositor/QuadCameraDirNoUV_vs + { + } + + fragment_program_ref Ogre/Sky/Cubemap_ps + { + } + + texture_unit + { + filtering trilinear + tex_address_mode clamp + } + } + } +} + +// GLSL shaders +fragment_program Ogre/Sky/Equirectangular_ps_GLSL glsl +{ + source SkyEquirectangular_ps.glsl + default_params + { + param_named skyEquirectangular int 0 + } +} + +fragment_program Ogre/Sky/Equirectangular_ps_VK glslvk +{ + source SkyEquirectangular_ps.glsl +} + +// HLSL shaders +fragment_program Ogre/Sky/Equirectangular_ps_HLSL hlsl +{ + source SkyEquirectangular_ps.hlsl + entry_point main + target ps_5_0 ps_4_0 ps_4_0_level_9_1 ps_4_0_level_9_3 +} + +// Metal shaders +fragment_program Ogre/Sky/Equirectangular_ps_Metal metal +{ + source SkyEquirectangular_ps.metal + shader_reflection_pair_hint Ogre/Compositor/QuadCameraDirNoUV_vs +} + +// Unified definitions +fragment_program Ogre/Sky/Equirectangular_ps unified +{ + delegate Ogre/Sky/Equirectangular_ps_HLSL + delegate Ogre/Sky/Equirectangular_ps_VK + delegate Ogre/Sky/Equirectangular_ps_GLSL + delegate Ogre/Sky/Equirectangular_ps_Metal +} + +// Material definition +material Ogre/Sky/Equirectangular +{ + technique + { + pass + { + depth_check on + depth_write off + + cull_hardware none + + vertex_program_ref Ogre/Compositor/QuadCameraDirNoUV_vs + { + } + + fragment_program_ref Ogre/Sky/Equirectangular_ps + { + param_named sliceIdx float 0.0 + } + + texture_unit + { + filtering trilinear + tex_address_mode clamp + } + } + } +} diff --git a/ogre2/src/media/2.0/scripts/materials/Common/brtfLutDfg.dds b/ogre2/src/media/2.0/scripts/materials/Common/brtfLutDfg.dds index b91c1da0e95501071ee8def1df995610bfc5792e..c9a628d0f64945d42f73ec0c4b0ecc6aa459846f 100644 GIT binary patch literal 32916 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 11u ) ); - return texelFetch( sampl, pos, 0 ); - } - ivec4 bufferFetch(in isampler2D sampl, in int pixelIdx) - { - ivec2 pos = ivec2( mod( pixelIdx, 2048 ), int( uint(pixelIdx) >> 11u ) ); - return texelFetch( sampl, pos, 0 ); - } - uvec4 bufferFetch( in usampler2D sampl, in int pixelIdx ) - { - ivec2 pos = ivec2( mod( pixelIdx, 2048 ), int( uint(pixelIdx) >> 11u ) ); - return texelFetch( sampl, pos, 0 ); - } + #define samplerBuffer sampler2D + #define isamplerBuffer isampler2D + #define usamplerBuffer usampler2D + vec4 bufferFetch( in sampler2D sampl, in int pixelIdx ) + { + ivec2 pos = ivec2( mod( pixelIdx, 2048 ), int( uint(pixelIdx) >> 11u ) ); + return texelFetch( sampl, pos, 0 ); + } + ivec4 bufferFetch(in isampler2D sampl, in int pixelIdx) + { + ivec2 pos = ivec2( mod( pixelIdx, 2048 ), int( uint(pixelIdx) >> 11u ) ); + return texelFetch( sampl, pos, 0 ); + } + uvec4 bufferFetch( in usampler2D sampl, in int pixelIdx ) + { + ivec2 pos = ivec2( mod( pixelIdx, 2048 ), int( uint(pixelIdx) >> 11u ) ); + return texelFetch( sampl, pos, 0 ); + } + + float bufferFetch1( in sampler2D sampl, in int pixelIdx ) + { + ivec2 pos = ivec2( mod( pixelIdx, 2048 ), int( uint(pixelIdx) >> 11u ) ); + return texelFetch( sampl, pos, 0 ).x; + } + int bufferFetch1(in isampler2D sampl, in int pixelIdx) + { + ivec2 pos = ivec2( mod( pixelIdx, 2048 ), int( uint(pixelIdx) >> 11u ) ); + return texelFetch( sampl, pos, 0 ).x; + } + uint bufferFetch1( in usampler2D sampl, in int pixelIdx ) + { + ivec2 pos = ivec2( mod( pixelIdx, 2048 ), int( uint(pixelIdx) >> 11u ) ); + return texelFetch( sampl, pos, 0 ).x; + } @end @end @end diff --git a/ogre2/src/media/Hlms/Common/GLSL/QuaternionCode_piece_all.glsl b/ogre2/src/media/Hlms/Common/GLSL/QuaternionCode_piece_all.glsl index b72defabf..01f0fe59a 100644 --- a/ogre2/src/media/Hlms/Common/GLSL/QuaternionCode_piece_all.glsl +++ b/ogre2/src/media/Hlms/Common/GLSL/QuaternionCode_piece_all.glsl @@ -1,51 +1,104 @@ @piece( DeclQuat_xAxis ) -vec3 xAxis( vec4 qQuat ) -{ - float fTy = 2.0 * qQuat.y; - float fTz = 2.0 * qQuat.z; - float fTwy = fTy * qQuat.w; - float fTwz = fTz * qQuat.w; - float fTxy = fTy * qQuat.x; - float fTxz = fTz * qQuat.x; - float fTyy = fTy * qQuat.y; - float fTzz = fTz * qQuat.z; - - return vec3( 1.0-(fTyy+fTzz), fTxy+fTwz, fTxz-fTwy ); -} + @property( precision_mode != relaxed ) + vec3 xAxis( vec4 qQuat ) + { + float fTy = 2.0 * qQuat.y; + float fTz = 2.0 * qQuat.z; + float fTwy = fTy * qQuat.w; + float fTwz = fTz * qQuat.w; + float fTxy = fTy * qQuat.x; + float fTxz = fTz * qQuat.x; + float fTyy = fTy * qQuat.y; + float fTzz = fTz * qQuat.z; + + return vec3( 1.0-(fTyy+fTzz), fTxy+fTwz, fTxz-fTwy ); + } + @end + @property( precision_mode != full32 ) + midf3 xAxis( midf4 qQuat ) + { + midf fTy = _h( 2.0 ) * qQuat.y; + midf fTz = _h( 2.0 ) * qQuat.z; + midf fTwy = fTy * qQuat.w; + midf fTwz = fTz * qQuat.w; + midf fTxy = fTy * qQuat.x; + midf fTxz = fTz * qQuat.x; + midf fTyy = fTy * qQuat.y; + midf fTzz = fTz * qQuat.z; + + return midf3_c( _h( 1.0 )-(fTyy+fTzz), fTxy+fTwz, fTxz-fTwy ); + } + @end @end @piece( DeclQuat_yAxis ) -vec3 yAxis( vec4 qQuat ) -{ - float fTx = 2.0 * qQuat.x; - float fTy = 2.0 * qQuat.y; - float fTz = 2.0 * qQuat.z; - float fTwx = fTx * qQuat.w; - float fTwz = fTz * qQuat.w; - float fTxx = fTx * qQuat.x; - float fTxy = fTy * qQuat.x; - float fTyz = fTz * qQuat.y; - float fTzz = fTz * qQuat.z; - - return vec3( fTxy-fTwz, 1.0-(fTxx+fTzz), fTyz+fTwx ); -} + @property( precision_mode != relaxed ) + vec3 yAxis( vec4 qQuat ) + { + float fTx = 2.0 * qQuat.x; + float fTy = 2.0 * qQuat.y; + float fTz = 2.0 * qQuat.z; + float fTwx = fTx * qQuat.w; + float fTwz = fTz * qQuat.w; + float fTxx = fTx * qQuat.x; + float fTxy = fTy * qQuat.x; + float fTyz = fTz * qQuat.y; + float fTzz = fTz * qQuat.z; + + return vec3( fTxy-fTwz, 1.0-(fTxx+fTzz), fTyz+fTwx ); + } + @end + @property( precision_mode != full32 ) + midf3 yAxis( midf4 qQuat ) + { + midf fTx = _h( 2.0 ) * qQuat.x; + midf fTy = _h( 2.0 ) * qQuat.y; + midf fTz = _h( 2.0 ) * qQuat.z; + midf fTwx = fTx * qQuat.w; + midf fTwz = fTz * qQuat.w; + midf fTxx = fTx * qQuat.x; + midf fTxy = fTy * qQuat.x; + midf fTyz = fTz * qQuat.y; + midf fTzz = fTz * qQuat.z; + + return midf3_c( fTxy-fTwz, _h( 1.0 )-(fTxx+fTzz), fTyz+fTwx ); + } + @end @end @piece( DeclQuat_zAxis ) -vec3 zAxis( vec4 qQuat ) -{ - float fTx = 2.0 * qQuat.x; - float fTy = 2.0 * qQuat.y; - float fTz = 2.0 * qQuat.z; - float fTwx = fTx * qQuat.w; - float fTwy = fTy * qQuat.w; - float fTxx = fTx * qQuat.x; - float fTxz = fTz * qQuat.x; - float fTyy = fTy * qQuat.y; - float fTyz = fTz * qQuat.y; - - return vec3( fTxz+fTwy, fTyz-fTwx, 1.0-(fTxx+fTyy) ); -} + @property( precision_mode != relaxed ) + vec3 zAxis( vec4 qQuat ) + { + float fTx = 2.0 * qQuat.x; + float fTy = 2.0 * qQuat.y; + float fTz = 2.0 * qQuat.z; + float fTwx = fTx * qQuat.w; + float fTwy = fTy * qQuat.w; + float fTxx = fTx * qQuat.x; + float fTxz = fTz * qQuat.x; + float fTyy = fTy * qQuat.y; + float fTyz = fTz * qQuat.y; + + return vec3( fTxz+fTwy, fTyz-fTwx, 1.0-(fTxx+fTyy) ); + } + @end + @property( precision_mode != full32 ) + midf3 zAxis( midf4 qQuat ) + { + midf fTx = _h( 2.0 ) * qQuat.x; + midf fTy = _h( 2.0 ) * qQuat.y; + midf fTz = _h( 2.0 ) * qQuat.z; + midf fTwx = fTx * qQuat.w; + midf fTwy = fTy * qQuat.w; + midf fTxx = fTx * qQuat.x; + midf fTxz = fTz * qQuat.x; + midf fTyy = fTy * qQuat.y; + midf fTyz = fTz * qQuat.y; + + return midf3_c( fTxz+fTwy, fTyz-fTwx, _h( 1.0 )-(fTxx+fTyy) ); + } + @end @end @piece( DeclQuat_AllAxis ) diff --git a/ogre2/src/media/Hlms/Common/HLSL/CrossPlatformSettings_piece_all.hlsl b/ogre2/src/media/Hlms/Common/HLSL/CrossPlatformSettings_piece_all.hlsl index b0f14fa76..c5b7bc3d1 100644 --- a/ogre2/src/media/Hlms/Common/HLSL/CrossPlatformSettings_piece_all.hlsl +++ b/ogre2/src/media/Hlms/Common/HLSL/CrossPlatformSettings_piece_all.hlsl @@ -15,6 +15,57 @@ #define toFloat3x3( x ) ((float3x3)(x)) #define buildFloat3x3( row0, row1, row2 ) transpose( float3x3( row0, row1, row2 ) ) +// See CrossPlatformSettings_piece_all.glsl for an explanation +@property( precision_mode == full32 ) + #define _h(x) (x) + + #define midf float + #define midf2 float2 + #define midf3 float3 + #define midf4 float4 + #define midf2x2 float2x2 + #define midf3x3 float3x3 + #define midf4x4 float4x4 + + #define midf_c float + #define midf2_c float2 + #define midf3_c float3 + #define midf4_c float4 + #define midf2x2_c float2x2 + #define midf3x3_c float3x3 + #define midf4x4_c float4x4 + + #define toMidf3x3( x ) ((float3x3)( x )) + #define buildMidf3x3( row0, row1, row2 ) transpose( float3x3( row0, row1, row2 ) ) + + #define ensureValidRangeF16(x) +@end +@property( precision_mode == relaxed ) + #define _h(x) min16float((x)) + + #define midf min16float + #define midf2 min16float2 + #define midf3 min16float3 + #define midf4 min16float4 + #define midf2x2 min16float2x2 + #define midf3x3 min16float3x3 + #define midf4x4 min16float4x4 + + // For casting to midf + #define midf_c min16float + #define midf2_c min16float2 + #define midf3_c min16float3 + #define midf4_c min16float4 + #define midf2x2_c min16float2x2 + #define midf3x3_c min16float3x3 + #define midf4x4_c min16float4x4 + + #define toMidf3x3( x ) ((min16float3x3)( x )) + #define buildMidf3x3( row0, row1, row2 ) transpose( min16float3x3( row0, row1, row2 ) ) + + #define ensureValidRangeF16(x) x = min(x, min16float(65504.0)) +@end + #define min3( a, b, c ) min( a, min( b, c ) ) #define max3( a, b, c ) max( a, max( b, c ) ) @@ -78,6 +129,16 @@ #define OGRE_Load3D( tex, iuv, lod ) tex.Load( int4( iuv, lod ) ) +#define OGRE_Load2DF16( tex, iuv, lod ) tex.Load( int3( iuv, lod ) ) +#define OGRE_Load2DMSF16( tex, iuv, subsample ) tex.Load( iuv, subsample ) +#define OGRE_SampleF16( tex, sampler, uv ) tex.Sample( sampler, uv ) +#define OGRE_SampleLevelF16( tex, sampler, uv, lod ) tex.SampleLevel( sampler, uv, lod ) +#define OGRE_SampleArray2DF16( tex, sampler, uv, arrayIdx ) tex.Sample( sampler, float3( uv, arrayIdx ) ) +#define OGRE_SampleArray2DLevelF16( tex, sampler, uv, arrayIdx, lod ) tex.SampleLevel( sampler, float3( uv, arrayIdx ), lod ) +#define OGRE_SampleArrayCubeLevelF16( tex, sampler, uv, arrayIdx, lod ) tex.SampleLevel( sampler, float4( uv, arrayIdx ), lod ) +#define OGRE_SampleGradF16( tex, sampler, uv, ddx, ddy ) tex.SampleGrad( sampler, uv, ddx, ddy ) +#define OGRE_SampleArray2DGradF16( tex, sampler, uv, arrayIdx, ddx, ddy ) tex.SampleGrad( sampler, float3( uv, arrayIdx ), ddx, ddy ) + #define bufferFetch( buffer, idx ) buffer.Load( idx ) #define bufferFetch1( buffer, idx ) buffer.Load( idx ).x diff --git a/ogre2/src/media/Hlms/Common/Metal/CrossPlatformSettings_piece_all.metal b/ogre2/src/media/Hlms/Common/Metal/CrossPlatformSettings_piece_all.metal index e32d00d86..3fe63c9c9 100644 --- a/ogre2/src/media/Hlms/Common/Metal/CrossPlatformSettings_piece_all.metal +++ b/ogre2/src/media/Hlms/Common/Metal/CrossPlatformSettings_piece_all.metal @@ -11,13 +11,30 @@ struct float1 inline float3x3 toMat3x3( float4x4 m ) { - return float3x3( m[0].xyz, m[1].xyz, m[2].xyz ); + return float3x3( m[0].xyz, m[1].xyz, m[2].xyz ); } inline float3x3 toMat3x3( float3x4 m ) { return float3x3( m[0].xyz, m[1].xyz, m[2].xyz ); } +inline half3x3 toMatHalf3x3( half4x4 m ) +{ + return half3x3( m[0].xyz, m[1].xyz, m[2].xyz ); +} +inline half3x3 toMatHalf3x3( half3x4 m ) +{ + return half3x3( m[0].xyz, m[1].xyz, m[2].xyz ); +} +inline half3x3 toMatHalf3x3( float4x4 m ) +{ + return half3x3( half3( m[0].xyz ), half3( m[1].xyz ), half3( m[2].xyz ) ); +} +inline half3x3 toMatHalf3x3( float3x4 m ) +{ + return half3x3( half3( m[0].xyz ), half3( m[1].xyz ), half3( m[2].xyz ) ); +} + #define ogre_float4x3 float3x4 //Short used for read operations. It's an int in GLSL & HLSL. An ushort in Metal @@ -29,7 +46,61 @@ inline float3x3 toMat3x3( float3x4 m ) #define wshort3 ushort3 #define toFloat3x3( x ) toMat3x3( x ) -#define buildFloat3x3( row0, row1, row2 ) float3x3( row0, row1, row2 ) +#define buildFloat3x3( row0, row1, row2 ) float3x3( float3( row0 ), float3( row1 ), float3( row2 ) ) + +// See CrossPlatformSettings_piece_all.glsl for an explanation +@property( precision_mode == full32 ) + // In Metal 'half' is an actual datatype. It should be OK to override it + // as long as we do it before including metal_stdlib + #define _h(x) (x) + + #define midf float + #define midf2 float2 + #define midf3 float3 + #define midf4 float4 + #define midf2x2 float2x2 + #define midf3x3 float3x3 + #define midf4x4 float4x4 + + #define midf_c float + #define midf2_c float2 + #define midf3_c float3 + #define midf4_c float4 + #define midf2x2_c float2x2 + #define midf3x3_c float3x3 + #define midf4x4_c float4x4 + + #define toMidf3x3( x ) toMat3x3( x ) + #define buildMidf3x3( row0, row1, row2 ) float3x3( row0, row1, row2 ) + + #define ensureValidRangeF16(x) +@end +@property( precision_mode == midf16 ) + // In Metal 'half' is an actual datatype. It should be OK to override it + // as long as we do it before including metal_stdlib + #define _h(x) half(x) + + #define midf half + #define midf2 half2 + #define midf3 half3 + #define midf4 half4 + #define midf2x2 half2x2 + #define midf3x3 half3x3 + #define midf4x4 half4x4 + + #define midf_c half + #define midf2_c half2 + #define midf3_c half3 + #define midf4_c half4 + #define midf2x2_c half2x2 + #define midf3x3_c half3x3 + #define midf4x4_c half4x4 + + #define toMidf3x3( x ) toMatHalf3x3( x ) + #define buildMidf3x3( row0, row1, row2 ) half3x3( half3( row0 ), half3( row1 ), half3( row2 ) ) + + #define ensureValidRangeF16(x) x = min(x, 65504.0h) +@end #define min3( a, b, c ) min( a, min( b, c ) ) #define max3( a, b, c ) max( a, max( b, c ) ) @@ -101,6 +172,16 @@ inline float3x3 toMat3x3( float3x4 m ) #define OGRE_Load3D( tex, iuv, lod ) tex.read( ushort3( iuv ), lod ) +#define OGRE_Load2DF16( tex, iuv, lod ) tex.read( iuv, lod ) +#define OGRE_Load2DMSF16( tex, iuv, subsample ) tex.read( iuv, subsample ) +#define OGRE_SampleF16( tex, sampler, uv ) tex.sample( sampler, uv ) +#define OGRE_SampleLevelF16( tex, sampler, uv, lod ) tex.sample( sampler, uv, level( lod ) ) +#define OGRE_SampleArray2DF16( tex, sampler, uv, arrayIdx ) tex.sample( sampler, float2( uv ), arrayIdx ) +#define OGRE_SampleArray2DLevelF16( tex, sampler, uv, arrayIdx, lod ) tex.sample( sampler, float2( uv ), ushort( arrayIdx ), level( lod ) ) +#define OGRE_SampleArrayCubeLevelF16( tex, sampler, uv, arrayIdx, lod ) tex.sample( sampler, float3( uv ), ushort( arrayIdx ), level( lod ) ) +#define OGRE_SampleGradF16( tex, sampler, uv, ddx, ddy ) tex.sample( sampler, uv, gradient2d( ddx, ddy ) ) +#define OGRE_SampleArray2DGradF16( tex, sampler, uv, arrayIdx, ddx, ddy ) tex.sample( sampler, uv, ushort( arrayIdx ), gradient2d( ddx, ddy ) ) + #define bufferFetch( buffer, idx ) buffer[idx] #define bufferFetch1( buffer, idx ) buffer[idx] #define readOnlyFetch( bufferVar, idx ) bufferVar[idx] diff --git a/ogre2/src/media/Hlms/Common/Metal/QuaternionCode_piece_all.metal b/ogre2/src/media/Hlms/Common/Metal/QuaternionCode_piece_all.metal index c703afafe..2c94baa18 100644 --- a/ogre2/src/media/Hlms/Common/Metal/QuaternionCode_piece_all.metal +++ b/ogre2/src/media/Hlms/Common/Metal/QuaternionCode_piece_all.metal @@ -1,51 +1,104 @@ @piece( DeclQuat_xAxis ) -inline float3 xAxis( float4 qQuat ) -{ - float fTy = 2.0 * qQuat.y; - float fTz = 2.0 * qQuat.z; - float fTwy = fTy * qQuat.w; - float fTwz = fTz * qQuat.w; - float fTxy = fTy * qQuat.x; - float fTxz = fTz * qQuat.x; - float fTyy = fTy * qQuat.y; - float fTzz = fTz * qQuat.z; - - return float3( 1.0-(fTyy+fTzz), fTxy+fTwz, fTxz-fTwy ); -} + @property( precision_mode != relaxed ) + float3 xAxis( float4 qQuat ) + { + float fTy = 2.0 * qQuat.y; + float fTz = 2.0 * qQuat.z; + float fTwy = fTy * qQuat.w; + float fTwz = fTz * qQuat.w; + float fTxy = fTy * qQuat.x; + float fTxz = fTz * qQuat.x; + float fTyy = fTy * qQuat.y; + float fTzz = fTz * qQuat.z; + + return float3( 1.0-(fTyy+fTzz), fTxy+fTwz, fTxz-fTwy ); + } + @end + @property( precision_mode != full32 ) + midf3 xAxis( midf4 qQuat ) + { + midf fTy = _h( 2.0 ) * qQuat.y; + midf fTz = _h( 2.0 ) * qQuat.z; + midf fTwy = fTy * qQuat.w; + midf fTwz = fTz * qQuat.w; + midf fTxy = fTy * qQuat.x; + midf fTxz = fTz * qQuat.x; + midf fTyy = fTy * qQuat.y; + midf fTzz = fTz * qQuat.z; + + return midf3_c( _h( 1.0 )-(fTyy+fTzz), fTxy+fTwz, fTxz-fTwy ); + } + @end @end @piece( DeclQuat_yAxis ) -inline float3 yAxis( float4 qQuat ) -{ - float fTx = 2.0 * qQuat.x; - float fTy = 2.0 * qQuat.y; - float fTz = 2.0 * qQuat.z; - float fTwx = fTx * qQuat.w; - float fTwz = fTz * qQuat.w; - float fTxx = fTx * qQuat.x; - float fTxy = fTy * qQuat.x; - float fTyz = fTz * qQuat.y; - float fTzz = fTz * qQuat.z; - - return float3( fTxy-fTwz, 1.0-(fTxx+fTzz), fTyz+fTwx ); -} + @property( precision_mode != relaxed ) + float3 yAxis( float4 qQuat ) + { + float fTx = 2.0 * qQuat.x; + float fTy = 2.0 * qQuat.y; + float fTz = 2.0 * qQuat.z; + float fTwx = fTx * qQuat.w; + float fTwz = fTz * qQuat.w; + float fTxx = fTx * qQuat.x; + float fTxy = fTy * qQuat.x; + float fTyz = fTz * qQuat.y; + float fTzz = fTz * qQuat.z; + + return float3( fTxy-fTwz, 1.0-(fTxx+fTzz), fTyz+fTwx ); + } + @end + @property( precision_mode != full32 ) + midf3 yAxis( midf4 qQuat ) + { + midf fTx = _h( 2.0 ) * qQuat.x; + midf fTy = _h( 2.0 ) * qQuat.y; + midf fTz = _h( 2.0 ) * qQuat.z; + midf fTwx = fTx * qQuat.w; + midf fTwz = fTz * qQuat.w; + midf fTxx = fTx * qQuat.x; + midf fTxy = fTy * qQuat.x; + midf fTyz = fTz * qQuat.y; + midf fTzz = fTz * qQuat.z; + + return midf3_c( fTxy-fTwz, _h( 1.0 )-(fTxx+fTzz), fTyz+fTwx ); + } + @end @end @piece( DeclQuat_zAxis ) -inline float3 zAxis( float4 qQuat ) -{ - float fTx = 2.0 * qQuat.x; - float fTy = 2.0 * qQuat.y; - float fTz = 2.0 * qQuat.z; - float fTwx = fTx * qQuat.w; - float fTwy = fTy * qQuat.w; - float fTxx = fTx * qQuat.x; - float fTxz = fTz * qQuat.x; - float fTyy = fTy * qQuat.y; - float fTyz = fTz * qQuat.y; - - return float3( fTxz+fTwy, fTyz-fTwx, 1.0-(fTxx+fTyy) ); -} + @property( precision_mode != relaxed ) + float3 zAxis( float4 qQuat ) + { + float fTx = 2.0 * qQuat.x; + float fTy = 2.0 * qQuat.y; + float fTz = 2.0 * qQuat.z; + float fTwx = fTx * qQuat.w; + float fTwy = fTy * qQuat.w; + float fTxx = fTx * qQuat.x; + float fTxz = fTz * qQuat.x; + float fTyy = fTy * qQuat.y; + float fTyz = fTz * qQuat.y; + + return float3( fTxz+fTwy, fTyz-fTwx, 1.0-(fTxx+fTyy) ); + } + @end + @property( precision_mode != full32 ) + midf3 zAxis( midf4 qQuat ) + { + midf fTx = _h( 2.0 ) * qQuat.x; + midf fTy = _h( 2.0 ) * qQuat.y; + midf fTz = _h( 2.0 ) * qQuat.z; + midf fTwx = fTx * qQuat.w; + midf fTwy = fTy * qQuat.w; + midf fTxx = fTx * qQuat.x; + midf fTxz = fTz * qQuat.x; + midf fTyy = fTy * qQuat.y; + midf fTyz = fTz * qQuat.y; + + return midf3_c( fTxz+fTwy, fTyz-fTwx, _h( 1.0 )-(fTxx+fTyy) ); + } + @end @end @piece( DeclQuat_AllAxis ) diff --git a/ogre2/src/media/Hlms/Common/Metal/RenderDepthOnly_piece_ps.metal b/ogre2/src/media/Hlms/Common/Metal/RenderDepthOnly_piece_ps.metal index 4c0127897..f01c8b75d 100644 --- a/ogre2/src/media/Hlms/Common/Metal/RenderDepthOnly_piece_ps.metal +++ b/ogre2/src/media/Hlms/Common/Metal/RenderDepthOnly_piece_ps.metal @@ -13,7 +13,7 @@ struct PS_OUTPUT { @property( !hlms_shadowcaster ) - float4 colour0 [[ color(@counter(rtv_target)) ]]; + midf4 colour0 [[ color(@counter(rtv_target)) ]]; @else @property( !hlms_render_depth_only ) float colour0 [[ color(@counter(rtv_target)) ]]; diff --git a/ogre2/src/media/Hlms/Pbs/Any/AmbientLighting_piece_ps.any b/ogre2/src/media/Hlms/Pbs/Any/AmbientLighting_piece_ps.any index 5bb8186c8..d7c8e1d0b 100644 --- a/ogre2/src/media/Hlms/Pbs/Any/AmbientLighting_piece_ps.any +++ b/ogre2/src/media/Hlms/Pbs/Any/AmbientLighting_piece_ps.any @@ -49,8 +49,10 @@ @property( ambient_hemisphere || vct_ambient_hemisphere ) @piece( DoAmbientHeader ) - float ambientWD = dot( passBuf.ambientHemisphereDir.xyz, pixelData.normal ) * 0.5 + 0.5; - float ambientWS = dot( passBuf.ambientHemisphereDir.xyz, pixelData.reflDir ) * 0.5 + 0.5; + midf ambientWD = + dot( midf3_c( passBuf.ambientHemisphereDir.xyz ), pixelData.normal ) * _h( 0.5 ) + _h( 0.5 ); + midf ambientWS = + dot( midf3_c( passBuf.ambientHemisphereDir.xyz ), pixelData.reflDir ) * _h( 0.5 ) + _h( 0.5 ); @end @end @@ -75,8 +77,10 @@ if( vctSpecular.w == 0 ) { @end - pixelData.envColourS += lerp( passBuf.ambientLowerHemi.xyz, passBuf.ambientUpperHemi.xyz, ambientWD ); - pixelData.envColourD += lerp( passBuf.ambientLowerHemi.xyz, passBuf.ambientUpperHemi.xyz, ambientWS ); + pixelData.envColourS += lerp( midf3_c( passBuf.ambientLowerHemi.xyz ), + midf3_c( passBuf.ambientUpperHemi.xyz ), ambientWD ); + pixelData.envColourD += lerp( midf3_c( passBuf.ambientLowerHemi.xyz ), + midf3_c( passBuf.ambientUpperHemi.xyz ), ambientWS ); @property( vct_num_probes ) } @end diff --git a/ogre2/src/media/Hlms/Pbs/Any/AreaLights_LTC_piece_ps.any b/ogre2/src/media/Hlms/Pbs/Any/AreaLights_LTC_piece_ps.any index 7367df1ec..584b349f3 100644 --- a/ogre2/src/media/Hlms/Pbs/Any/AreaLights_LTC_piece_ps.any +++ b/ogre2/src/media/Hlms/Pbs/Any/AreaLights_LTC_piece_ps.any @@ -48,11 +48,11 @@ INLINE float3 IntegrateEdgeVec( float3 v1, float3 v2 ) float x = dot(v1, v2); float y = abs(x); - float a = 0.8543985 + (0.4965155 + 0.0145206*y)*y; - float b = 3.4175940 + (4.1616724 + y)*y; + float a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y; + float b = 3.4175940 + ( 4.1616724 + y ) * y; float v = a / b; - float theta_sintheta = (x > 0.0) ? v : 0.5*rsqrt(max(1.0 - x*x, 1e-7)) - v; + float theta_sintheta = ( x > 0.0 ) ? v : 0.5 * rsqrt( max( 1.0 - x * x, 1e-7 ) ) - v; return cross( v1, v2 ) * theta_sintheta; } @@ -71,10 +71,10 @@ INLINE void ClipQuadToHorizon( inout float3 L[5], out int n ) { // detect clipping config int config = 0; - if (L[0].z > 0.0) config += 1; - if (L[1].z > 0.0) config += 2; - if (L[2].z > 0.0) config += 4; - if (L[3].z > 0.0) config += 8; + if (L[0].z > _h( 0.0 )) config += 1; + if (L[1].z > _h( 0.0 )) config += 2; + if (L[2].z > _h( 0.0 )) config += 4; + if (L[3].z > _h( 0.0 )) config += 8; // clip n = 0; @@ -178,12 +178,12 @@ INLINE void ClipQuadToHorizon( inout float3 L[5], out int n ) L[4] = L[0]; } -INLINE float LTC_Evaluate( float3 N, float3 V, float3 P, float3x3 Minv, - @property( syntax == metal )constant@end float4 points[4], - bool twoSided ) +INLINE midf LTC_Evaluate( midf3 N, midf3 V, float3 P, float3x3 Minv, + @property( syntax == metal )constant@end float4 points[4], + bool twoSided ) { // construct orthonormal basis around N - float3 T1, T2; + midf3 T1, T2; T1 = normalize( V - N*dot(V, N) ); T2 = cross(N, T1); @@ -205,16 +205,16 @@ INLINE float LTC_Evaluate( float3 N, float3 V, float3 P, float3x3 Minv, float sum = 0.0; @property( hlms_lights_ltc_clipless ) - float3 dir = points[0].xyz - P; - float3 lightNormal = cross( points[1].xyz - points[0].xyz, points[3].xyz - points[0].xyz ); - bool behind = (dot(dir, lightNormal) < 0.0); + midf3 dir = midf3_c( points[0].xyz - P ); + midf3 lightNormal = midf3_c( cross( points[1].xyz - points[0].xyz, points[3].xyz - points[0].xyz ) ); + bool behind = (dot(dir, lightNormal) < _h( 0.0 )); L[0] = normalize(L[0]); L[1] = normalize(L[1]); L[2] = normalize(L[2]); L[3] = normalize(L[3]); - float3 vsum = float3(0.0); + float3 vsum = midf3_c(0.0); vsum += IntegrateEdgeVec(L[0], L[1]); vsum += IntegrateEdgeVec(L[1], L[2]); @@ -230,19 +230,18 @@ INLINE float LTC_Evaluate( float3 N, float3 V, float3 P, float3x3 Minv, float2 uv = float2(z*0.5 + 0.5, len); uv = uv * LUT_SCALE + LUT_BIAS; - float scale = OGRE_SampleArray2DLevel( ltcMatrix, ltcSampler, uv, 1, 0 ).w; + float scale = float( OGRE_SampleArray2DLevelF16( ltcMatrix, ltcSampler, uv, 1, 0 ).w ); - sum = len*scale; + sum = len * scale; if( behind && !twoSided ) sum = 0.0; - @end - @property( !hlms_lights_ltc_clipless ) + @else int n; ClipQuadToHorizon( L, n ); if( n == 0 ) - return 0; + return _h( 0 ); // project onto sphere L[0] = normalize( L[0] ); L[1] = normalize( L[1] ); @@ -259,10 +258,10 @@ INLINE float LTC_Evaluate( float3 N, float3 V, float3 P, float3x3 Minv, if( n == 5 ) sum += IntegrateEdge( L[4], L[0] ); - sum = twoSided ? abs(sum) : max(0.0, sum); + sum = twoSided ? abs(sum) : max( 0.0f, sum ); @end - return sum; + return midf( sum ); } @end @end @@ -291,8 +290,8 @@ for( int i=0; i areaLightMasks : register(t@value(areaLightMasks)); + Texture2DArray areaLightMasks : register(t@value(areaLightMasks)); @else - Texture2DArray areaLightMasks : register(t@value(areaLightMasks)); + Texture2DArray areaLightMasks: register(t@value(areaLightMasks)); @end SamplerState areaLightMasksSampler : register(s@value(areaLightMasks)); @end @property( syntax == metal ) - , texture2d_array areaLightMasks [[texture(@value(areaLightMasks))]] + , texture2d_array areaLightMasks [[texture(@value(areaLightMasks))]] , sampler areaLightMasksSampler [[sampler(@value(areaLightMasks))]] @end @end @@ -43,9 +43,9 @@ fDistance = length( lightDir ); @property( obb_restraint_approx ) - float obbRestraintFade = getObbRestraintFade( light1Buf.areaApproxLights[i].obbRestraint, inPs.pos, - light1Buf.areaApproxLights[i].obbFadeFactorApprox.xyz ); - @piece( obbRestraintTestApprox )&& obbRestraintFade > 0.0@end + midf obbRestraintFade = getObbRestraintFade( light1Buf.areaApproxLights[i].obbRestraint, inPs.pos, + light1Buf.areaApproxLights[i].obbFadeFactorApprox.xyz ); + @piece( obbRestraintTestApprox )&& obbRestraintFade > _h( 0.0 )@end @end if( fDistance <= light1Buf.areaApproxLights[i].attenuation.x @@ -53,8 +53,8 @@ /*&& dot( -lightDir, light1Buf.areaApproxLights[i].direction.xyz ) > 0*/ @insertpiece( andObjAreaApproxLightMaskCmp ) ) { projectedPosInPlane.xyz -= light1Buf.areaApproxLights[i].position.xyz; - float3 areaLightBitangent = cross( light1Buf.areaApproxLights[i].direction.xyz, - light1Buf.areaApproxLights[i].tangent.xyz ); + float3 areaLightBitangent = cross( light1Buf.areaApproxLights[i].tangent.xyz, + light1Buf.areaApproxLights[i].direction.xyz ); float2 invHalfRectSize = float2( light1Buf.areaApproxLights[i].direction.w, light1Buf.areaApproxLights[i].tangent.w ); //lightUV is in light space, in range [-0.5; 0.5] @@ -67,18 +67,18 @@ //a surface is close and perpendicular to the light. This is fully a hack and //the values (e.g. 0.25) is completely eye balled. lightUVForTex.xy = lightUV.xy; - lightUV.xy += float2( dot( light1Buf.areaApproxLights[i].tangent.xyz, pixelData.normal ), - dot( areaLightBitangent, pixelData.normal ) ) * 3.75 * invHalfRectSize.xy; + lightUV.xy += float2( dot( ( light1Buf.areaApproxLights[i].tangent.xyz ), float3( pixelData.normal ) ), + dot( areaLightBitangent, float3( pixelData.normal ) ) ) * 3.75 * invHalfRectSize.xy; lightUV.xy = clamp( lightUV.xy, -0.5f, 0.5f ); lightUVForTex = clamp( lightUVForTex.xy, -0.5f, 0.5f ); // float booster = 1.0f - smoothstep( 0.2f, 1.9f, max( abs( lightUV.x ), abs( lightUV.y ) ) ); // booster = 1.0f + booster * 2.25f; - float booster = lerp( 1.0f, 4.0f, pixelData.roughness ); + midf booster = lerp( _h( 1.0f ), _h( 4.0f ), pixelData.roughness ); @property( !hlms_lights_area_tex_colour || !hlms_lights_area_tex_mask ) - float diffuseMask = 1.0f; + midf diffuseMask = _h( 1.0f ); @else - float3 diffuseMask = float3( 1.0f, 1.0f, 1.0f ); + midf3 diffuseMask = midf3_c( 1.0f, 1.0f, 1.0f ); @end @property( hlms_lights_area_tex_mask ) if( i < floatBitsToInt( light1Buf.numAreaApproxLightsWithMask ) ) @@ -86,11 +86,11 @@ // 1 / (1 - 0.02) = 1.020408163 float diffuseMipsLeft = light1Buf.areaLightNumMipmapsSpecFactor * 0.5 - light1Buf.areaLightDiffuseMipmapStart * 1.020408163f; - diffuseMask = OGRE_SampleArray2DLevel( areaLightMasks, areaLightMasksSampler, - lightUVForTex + 0.5f, - light1Buf.areaApproxLights[i].attenuation.w, - light1Buf.areaLightDiffuseMipmapStart + - (pixelData.roughness - 0.02f) * diffuseMipsLeft ).AREA_LIGHTS_TEX_SWIZZLE; + diffuseMask = OGRE_SampleArray2DLevelF16( areaLightMasks, areaLightMasksSampler, + lightUVForTex + 0.5f, + light1Buf.areaApproxLights[i].attenuation.w, + light1Buf.areaLightDiffuseMipmapStart + + (pixelData.roughness - 0.02f) * diffuseMipsLeft ).AREA_LIGHTS_TEX_SWIZZLE; } @end @@ -102,20 +102,20 @@ lightDir = closestPoint.xyz - inPs.pos; fDistance= length( lightDir ); - float3 toShapeLight = reflect( -pixelData.viewDir, pixelData.normal ); - float denom = dot( toShapeLight, -light1Buf.areaApproxLights[i].direction.xyz ); + midf3 toShapeLight = reflect( -pixelData.viewDir, pixelData.normal ); + midf denom = dot( toShapeLight, midf3_c( -light1Buf.areaApproxLights[i].direction.xyz ) ); @property( !hlms_lights_area_tex_mask || !hlms_lights_area_tex_colour ) - float specCol = 0; + midf specCol = _h( 0 ); @else - float3 specCol = float3( 0, 0, 0 ); + midf3 specCol = midf3_c( 0, 0, 0 ); @end if( denom > 1e-6f || light1Buf.areaApproxLights[i].doubleSided.x != 0.0f ) { float3 p0l0 = light1Buf.areaApproxLights[i].position.xyz - inPs.pos; - float t = dot( p0l0, -light1Buf.areaApproxLights[i].direction.xyz ) / denom; + float t = dot( p0l0, -light1Buf.areaApproxLights[i].direction.xyz ) / float( denom ); if( t >= 0 ) { - float3 posInShape = inPs.pos.xyz + toShapeLight.xyz * t - light1Buf.areaApproxLights[i].position.xyz; + float3 posInShape = inPs.pos.xyz + float3( toShapeLight.xyz ) * t - light1Buf.areaApproxLights[i].position.xyz; float2 reflClipSpace; reflClipSpace.x = dot( light1Buf.areaApproxLights[i].tangent.xyz, posInShape ); reflClipSpace.y = dot( areaLightBitangent, posInShape ); @@ -129,19 +129,19 @@ specVal = pow( specVal, areaPower ) * min( areaPower * areaPower, 1.0f ); @property( !hlms_lights_area_tex_mask || !hlms_lights_area_tex_colour ) - specCol = specVal; + specCol = midf_c( specVal ); @else - specCol = float3( specVal, specVal, specVal ); + specCol = midf3_c( specVal, specVal, specVal ); @end @property( hlms_lights_area_tex_mask ) if( i < floatBitsToInt( light1Buf.numAreaApproxLightsWithMask ) ) { - specCol *= OGRE_SampleArray2DLevel( areaLightMasks, areaLightMasksSampler, - reflClipSpace * invHalfRectSize + 0.5f, - light1Buf.areaApproxLights[i].attenuation.w, - (pixelData.roughness - 0.02f) * - light1Buf.areaLightNumMipmapsSpecFactor ).AREA_LIGHTS_TEX_SWIZZLE; + specCol *= OGRE_SampleArray2DLevelF16( areaLightMasks, areaLightMasksSampler, + reflClipSpace * invHalfRectSize + 0.5f, + light1Buf.areaApproxLights[i].attenuation.w, + (pixelData.roughness - _h( 0.02f )) * + light1Buf.areaLightNumMipmapsSpecFactor ).AREA_LIGHTS_TEX_SWIZZLE; } @end } @@ -151,13 +151,13 @@ //float fAreaW = dot( lightDir, -light1Buf.areaApproxLights[i].direction.xyz ) * 0.5f + 0.5f; //lightDir = (-light1Buf.areaApproxLights[i].direction.xyz + lightDir) * 0.50f; //lightDir = lerp( lightDir2, lightDir, fAreaW ); - float globalDot = saturate( dot( -lightDir, light1Buf.areaApproxLights[i].direction.xyz ) ); - globalDot = light1Buf.areaApproxLights[i].doubleSided.x != 0.0f ? 1.0f : globalDot; - tmpColour = BRDF_AreaLightApprox( lightDir, - light1Buf.areaApproxLights[i].diffuse.xyz * diffuseMask, - light1Buf.areaApproxLights[i].specular.xyz * specCol, + midf globalDot = midf_c( saturate( dot( -lightDir, light1Buf.areaApproxLights[i].direction.xyz ) ) ); + globalDot = light1Buf.areaApproxLights[i].doubleSided.x != 0.0f ? _h( 1.0f ) : globalDot; + tmpColour = BRDF_AreaLightApprox( midf3_c( lightDir ), + midf3_c( light1Buf.areaApproxLights[i].diffuse.xyz ) * diffuseMask, + midf3_c( light1Buf.areaApproxLights[i].specular.xyz ) * specCol, pixelData ) * ( globalDot * globalDot ) * booster; - float atten = 1.0 / (0.5 + (light1Buf.areaApproxLights[i].attenuation.y + light1Buf.areaApproxLights[i].attenuation.z * fDistance) * fDistance ); + midf atten = midf_c( 1.0 / (0.5 + (light1Buf.areaApproxLights[i].attenuation.y + light1Buf.areaApproxLights[i].attenuation.z * fDistance) * fDistance ) ); @property( obb_restraint_approx ) atten *= obbRestraintFade; @@ -173,38 +173,38 @@ @end @piece( DeclareBRDF_AreaLightApprox ) -INLINE float3 BRDF_AreaLightApprox +INLINE midf3 BRDF_AreaLightApprox ( - float3 lightDir, float3 lightDiffuse, float3 lightSpecular, PixelData pixelData + midf3 lightDir, midf3 lightDiffuse, midf3 lightSpecular, PixelData pixelData ) { - float3 halfWay= normalize( lightDir + pixelData.viewDir ); - float NdotL = saturate( dot( pixelData.normal, lightDir ) ); - float VdotH = saturate( dot( pixelData.viewDir, halfWay ) ); + midf3 halfWay= normalize( lightDir + pixelData.viewDir ); + midf NdotL = saturate( dot( pixelData.normal, lightDir ) ); + midf VdotH = saturate( dot( pixelData.viewDir, halfWay ) ); //Formula: // fresnelS = lerp( (1 - V*H)^5, 1, F0 ) float_fresnel fresnelS = @insertpiece( getSpecularFresnel ); //We should divide Rs by PI, but it was done inside G for performance - float3 Rs = fresnelS * pixelData.specular.xyz * lightSpecular; + midf3 Rs = fresnelS * pixelData.specular.xyz * lightSpecular; //Diffuse BRDF (*Normalized* Disney, see course_notes_moving_frostbite_to_pbr.pdf //"Moving Frostbite to Physically Based Rendering" Sebastien Lagarde & Charles de Rousiers) - float energyBias = pixelData.roughness * 0.5; - float energyFactor = lerp( 1.0, 1.0 / 1.51, pixelData.roughness ); - float fd90 = energyBias + 2.0 * VdotH * VdotH * pixelData.roughness; - float lightScatter = 1.0 + (fd90 - 1.0) * pow( 1.0 - NdotL, 5.0 ); - float viewScatter = 1.0 + (fd90 - 1.0) * pow( 1.0 - pixelData.NdotV, 5.0 ); + midf energyBias = pixelData.roughness * _h( 0.5 ); + midf energyFactor = lerp( _h( 1.0 ), _h( 1.0 / 1.51 ), pixelData.roughness ); + midf fd90 = energyBias + _h( 2.0 ) * VdotH * VdotH * pixelData.roughness; + midf lightScatter = _h( 1.0 ) + (fd90 - _h( 1.0 )) * pow( _h( 1.0 ) - NdotL, _h( 5.0 ) ); + midf viewScatter = _h( 1.0 ) + (fd90 - _h( 1.0 )) * pow( _h( 1.0 ) - pixelData.NdotV, _h( 5.0 ) ); @property( fresnel_separate_diffuse ) float_fresnel fresnelD = @insertpiece( getDiffuseFresnel ); @else - float fresnelD = 1.0f - @insertpiece( getMaxFresnelS ); + midf fresnelD = _h( 1.0f ) - @insertpiece( getMaxFresnelS ); @end //We should divide Rd by PI, but it is already included in kD - float3 Rd = (lightScatter * viewScatter * energyFactor * fresnelD) * pixelData.diffuse.xyz * lightDiffuse; + midf3 Rd = (lightScatter * viewScatter * energyFactor * fresnelD) * pixelData.diffuse.xyz * lightDiffuse; return NdotL * (Rs + Rd); } diff --git a/ogre2/src/media/Hlms/Pbs/Any/Atmosphere/200.AtmosphereNprSkyHlms_piece_all.any b/ogre2/src/media/Hlms/Pbs/Any/Atmosphere/200.AtmosphereNprSkyHlms_piece_all.any new file mode 100644 index 000000000..737e555bb --- /dev/null +++ b/ogre2/src/media/Hlms/Pbs/Any/Atmosphere/200.AtmosphereNprSkyHlms_piece_all.any @@ -0,0 +1,42 @@ +// NPR = Non-Physically-based Rendering Atmo + +//#include "SyntaxHighlightingMisc.h" + +@property( atmosky_npr ) + +@piece( AtmosphereNprSkyStructDecl ) + struct AtmoSettings + { + float densityCoeff; + float lightDensity; + float sunHeight; + float sunHeightWeight; + + float4 skyLightAbsorption; + float4 sunAbsorption; + float4 cameraDisplacement; + float4 packedParams1; + float4 packedParams2; + float4 packedParams3; + + float fogDensity; + float fogBreakMinBrightness; + float fogBreakFalloff; + float padding0; + }; + + @property( syntax != metal ) + CONST_BUFFER( AtmoSettingsBuf, @value(atmosky_npr) ) + { + AtmoSettings atmoSettings; + }; + @end +@end + +@property( syntax == metal ) + @piece( AtmosphereNprSkyDecl ) + , constant AtmoSettings &atmoSettings [[buffer(CONST_SLOT_START+@value(atmosky_npr))]] + @end +@end + +@end diff --git a/ogre2/src/media/Hlms/Pbs/Any/Atmosphere/200.AtmosphereNprSkyHlms_piece_vs.any b/ogre2/src/media/Hlms/Pbs/Any/Atmosphere/200.AtmosphereNprSkyHlms_piece_vs.any new file mode 100644 index 000000000..f266d3fe0 --- /dev/null +++ b/ogre2/src/media/Hlms/Pbs/Any/Atmosphere/200.AtmosphereNprSkyHlms_piece_vs.any @@ -0,0 +1,91 @@ +// NPR = Non-Physically-based Rendering Atmo + +//#include "SyntaxHighlightingMisc.h" + +// @property( atmosky_npr ) + +// @piece( DeclAtmosphereNprSkyFuncs ) + +// See https://en.wikipedia.org/wiki/Rayleigh_distribution +// It's inspired, not fully based. +// +// The formula also gives us the nice property that for inputs +// where absorption is in range [0; 1] the output i also in range [0; 1] +midf3 getSkyRayleighAbsorption( midf3 vDir, const midf density ) +{ + midf3 absorption = -density * vDir; + absorption = exp2( absorption ) * _h( 2.0 ); + return absorption; +} + +midf3 pow3( midf3 v, midf e ) +{ + return midf3_c( pow( v.x, e ), pow( v.y, e ), pow( v.z, e ) ); +} + +// @endpiece + +// @piece( DoAtmosphereNprSky ) +// clang-format off +#define p_densityCoeff midf_c( atmoSettings.densityCoeff ) +#define p_lightDensity midf_c( atmoSettings.lightDensity ) +#define p_sunHeight midf_c( atmoSettings.sunHeight ) +#define p_sunHeightWeight midf_c( atmoSettings.sunHeightWeight ) +#define p_skyLightAbsorption midf3_c( atmoSettings.skyLightAbsorption.xyz ) +#define p_sunAbsorption midf3_c( atmoSettings.sunAbsorption.xyz ) +#define p_cameraDisplacement midf3_c( atmoSettings.cameraDisplacement.xyz ) +#define p_mieAbsorption midf3_c( atmoSettings.packedParams1.xyz ) +#define p_finalMultiplier midf_c( atmoSettings.packedParams1.w ) +#define p_sunDir midf3_c( atmoSettings.packedParams2.xyz ) +#define p_borderLimit midf_c( atmoSettings.packedParams2.w ) +#define p_skyColour midf3_c( atmoSettings.packedParams3.xyz ) +#define p_densityDiffusion midf_c( atmoSettings.packedParams3.w ) +// clang-format on + +const float3 cameraPos = float3( atmoSettings.skyLightAbsorption.w, atmoSettings.sunAbsorption.w, + atmoSettings.cameraDisplacement.w ); +float3 cameraDir = worldPos.xyz - cameraPos; +float distToCamera = length( cameraDir ); +midf3 atmoCameraDir = midf3_c( cameraDir * ( 1.0f / distToCamera ) ); + +const midf LdotV = max( dot( atmoCameraDir, p_sunDir ), _h( 0.0 ) ); + +atmoCameraDir.y += + p_densityDiffusion * _h( 0.075 ) * ( _h( 1.0 ) - atmoCameraDir.y ) * ( _h( 1.0 ) - atmoCameraDir.y ); +atmoCameraDir += p_cameraDisplacement; +atmoCameraDir = normalize( atmoCameraDir ); + +atmoCameraDir.y = max( atmoCameraDir.y, p_borderLimit ); +atmoCameraDir.y = atmoCameraDir.y * _h( 0.9 ) + _h( 0.1 ); +atmoCameraDir = normalize( atmoCameraDir ); + +const midf LdotV360 = dot( atmoCameraDir, p_sunDir ) * _h( 0.5 ) + _h( 0.5 ); + +// ptDensity gets smaller as sunHeight gets bigger +// ptDensity gets smaller as atmoCameraDir.y gets bigger +const midf ptDensity = + p_densityCoeff / + pow( max( atmoCameraDir.y / ( _h( 1.0 ) - p_sunHeight ), _h( 0.0035 ) ), p_densityDiffusion ); + +const midf antiMie = max( p_sunHeightWeight, _h( 0.08 ) ); + +const midf3 skyAbsorption = getSkyRayleighAbsorption( p_skyColour, ptDensity ); +const midf3 skyColourGradient = pow3( exp2( -atmoCameraDir.y / p_skyColour ), _h( 1.5 ) ); + +const midf mie = LdotV360; + +midf3 atmoColour = midf3_c( 0.0f, 0.0f, 0.0f ); + +const midf3 sharedTerms = skyColourGradient * skyAbsorption; + +atmoColour += antiMie * sharedTerms * p_sunAbsorption; +atmoColour += ( mie * ptDensity * p_lightDensity ) * sharedTerms * p_skyLightAbsorption; +atmoColour += mie * p_mieAbsorption; +atmoColour *= p_lightDensity; + +atmoColour *= p_finalMultiplier; + +outVs.fog.xyz = atmoColour; +// @end + +// @end diff --git a/ogre2/src/media/Hlms/Pbs/Any/ForwardPlus_DecalsCubemaps_piece_ps.any b/ogre2/src/media/Hlms/Pbs/Any/ForwardPlus_DecalsCubemaps_piece_ps.any index 48e343dd0..da650d5b9 100644 --- a/ogre2/src/media/Hlms/Pbs/Any/ForwardPlus_DecalsCubemaps_piece_ps.any +++ b/ogre2/src/media/Hlms/Pbs/Any/ForwardPlus_DecalsCubemaps_piece_ps.any @@ -8,10 +8,10 @@ @insertpiece( forward3dHeader ) @property( hlms_decals_normals && normal_map ) - float3 finalDecalTsNormal = float3( 0.0f, 0.0f, 1.0f ); + midf3 finalDecalTsNormal = midf3_c( 0.0f, 0.0f, 1.0f ); @end @property( hlms_decals_emissive ) - float3 finalDecalEmissive = float3( 0.0f, 0.0f, 0.0f ); + midf3 finalDecalEmissive = midf3_c( 0.0f, 0.0f, 0.0f ); @end ushort numLightsInGrid = bufferFetch1( f3dGrid, int(sampleOffset + @value(hlms_forwardplus_decals_slot_offset)u) ); @@ -47,18 +47,18 @@ @property( hlms_decals_diffuse ) ushort decalDiffuseIdx = floatBitsToUint( texIndices.x ) & 0xFFFFu; - float4 decalDiffuse = OGRE_SampleArray2DGrad( decalsDiffuseTex, decalsSampler, decalUV.xy, - decalDiffuseIdx, decalUvDdx, decalUvDdy ).xyzw; + midf4 decalDiffuse = OGRE_SampleArray2DGradF16( decalsDiffuseTex, decalsSampler, decalUV.xy, + decalDiffuseIdx, decalUvDdx, decalUvDdy ).xyzw; @end @property( hlms_decals_normals && normal_map ) ushort decalNormalsIdx = floatBitsToUint( texIndices.x ) >> 16u; - float2 decalNormals = OGRE_SampleArray2DGrad( decalsNormalsTex, decalsSampler, decalUV.xy, - decalNormalsIdx, decalUvDdx, decalUvDdy ).xy; + midf2 decalNormals = OGRE_SampleArray2DGradF16( decalsNormalsTex, decalsSampler, decalUV.xy, + decalNormalsIdx, decalUvDdx, decalUvDdy ).xy; @end @property( hlms_decals_emissive ) ushort decalEmissiveIdx = floatBitsToUint( texIndices.y ) & 0xFFFFu; - float3 decalEmissive = OGRE_SampleArray2DGrad( decalsEmissiveTex, decalsSampler, decalUV.xy, - decalEmissiveIdx, decalUvDdx, decalUvDdy ).xyz; + midf3 decalEmissive = OGRE_SampleArray2DGradF16( decalsEmissiveTex, decalsSampler, decalUV.xy, + decalEmissiveIdx, decalUvDdx, decalUvDdy ).xyz; @end @property( hlms_decals_diffuse && (hlms_decals_normals || hlms_decals_emissive) ) @@ -77,27 +77,27 @@ // //Use a smooth fade to avoid flickering due to floating point precision when the normal //and the decal are perpendicular to each other. (tolerance set to 0.0002) - float3 decalDir = normalize( float3( invWorldView1.xyz ) ); + midf3 decalDir = normalize( midf3_c( invWorldView1.xyz ) ); //isOutsideDecal = dot( decalDir.xyz, inPs.normal.xyz ) <= 0.0 ? true : isOutsideDecal; - float normalAway = saturate( (dot( decalDir.xyz, inPs.normal.xyz ) + 0.0002) / 0.0002 ); - normalAway = isOutsideDecal ? 0.0f : normalAway; + midf normalAway = saturate( (dot( decalDir.xyz, inPs.normal.xyz ) + _h( 0.0002 ) ) / _h( 0.0002 ) ); + normalAway = isOutsideDecal ? _h( 0.0f ) : normalAway; - float decalMask = normalAway; + midf decalMask = normalAway; @property( hlms_decals_diffuse ) decalMask *= decalDiffuse.w; - float decalMetalness = texIndices.z; - float3 decalF0 = lerp( float3( 0.03f, 0.03f, 0.03f ), decalDiffuse.xyz, decalMetalness ); + midf decalMetalness = midf_c( texIndices.z ); + midf3 decalF0 = lerp( midf3_c( 0.03f, 0.03f, 0.03f ), decalDiffuse.xyz, decalMetalness ); decalDiffuse.xyz = decalDiffuse.xyz - decalDiffuse.xyz * decalMetalness; - pixelData.diffuse.xyz = lerp( pixelData.diffuse.xyz, decalDiffuse.xyz * 0.318309886f, decalMask ); - pixelData.roughness = lerp( pixelData.roughness, texIndices.w, decalMask ); + pixelData.diffuse.xyz = lerp( pixelData.diffuse.xyz, decalDiffuse.xyz * _h( 0.318309886f ), decalMask ); + pixelData.roughness = lerp( pixelData.roughness, midf_c( texIndices.w ), decalMask ); @property( !metallic_workflow && !fresnel_workflow && !fresnel_scalar ) pixelData.specular = lerp( pixelData.specular.xyz, decalF0, decalMask ); pixelData.F0 = lerp( pixelData.F0, decalMetalness, decalMask ); @else - pixelData.specular = lerp( pixelData.specular.xyz, float3( 1.0f, 1.0f, 1.0f ), decalMask ); + pixelData.specular = lerp( pixelData.specular.xyz, midf3_c( 1.0f, 1.0f, 1.0f ), decalMask ); pixelData.F0.xyz = lerp( pixelData.F0.xyz, decalF0.xyz, decalMask ); @end @@ -111,7 +111,7 @@ @end @property( hlms_decals_emissive ) finalDecalEmissive += (absLocalPos.x > 0.5f || absLocalPos.y > 0.5f || - absLocalPos.z > 0.5f) ? float3( 0.0f, 0.0f, 0.0f ) : + absLocalPos.z > 0.5f) ? midf3_c( 0.0f, 0.0f, 0.0f ) : (decalEmissive.xyz * decalMask); @end @@ -140,13 +140,13 @@ @property( hlms_forwardplus_debug )totalNumLightsInGrid += numLightsInGrid;@end - float cubemapAccumWeight = 0; + midf cubemapAccumWeight = _h( 0 ); - float3 pccEnvS = float3( 0, 0, 0 ); - float3 pccEnvD = float3( 0, 0, 0 ); + midf3 pccEnvS = midf3_c( 0, 0, 0 ); + midf3 pccEnvD = midf3_c( 0, 0, 0 ); @property( clear_coat ) - float3 clearCoatPccEnvS = float3( 0, 0, 0 ); + midf3 clearCoatPccEnvS = midf3_c( 0, 0, 0 ); @end @property( vct_num_probes ) @@ -171,46 +171,46 @@ float4 probeInnerRange = readOnlyFetch( f3dLightList, int(idx + 6u) ).xyzw; float4 probeOuterRange = readOnlyFetch( f3dLightList, int(idx + 7u) ).xyzw; - float3 posInProbSpace = toProbeLocalSpace( inPs.pos, probe ); - float probeFade = getProbeFade( posInProbSpace, probe ); + midf3 posInProbSpace = midf3_c( toProbeLocalSpace( inPs.pos, probe ) ); + midf probeFade = getProbeFade( posInProbSpace, probe ); - if( probeFade > 0 ) + if( probeFade > _h( 0 ) ) { float2 cubemapIdx_priority = unpackUshort2ToFloat2( floatBitsToUint( probe.halfSize.w ) ); float probeCubemapIdx = cubemapIdx_priority.x; float probePriority = cubemapIdx_priority.y; - float3 probeToAreaCenterOffsetLS = float3( probe.cubemapPosLS.w, + midf3 probeToAreaCenterOffsetLS = midf3_c( probe.cubemapPosLS.w, probe.cubemapPosVS.w, probeInnerRange.w ); - float ndf = getProbeNDF( posInProbSpace.xyz, probeToAreaCenterOffsetLS.xyz, - probeInnerRange.xyz, probeOuterRange.xyz ); + midf ndf = getProbeNDF( posInProbSpace.xyz, probeToAreaCenterOffsetLS.xyz, + midf3_c( probeInnerRange.xyz ), midf3_c( probeOuterRange.xyz ) ); ndf = saturate( ndf ); - probeFade = 1.0 - ndf; + probeFade = _h( 1.0 ) - ndf; probeFade = probeFade * probeFade; probeFade = probeFade * probeFade; - probeFade *= probePriority; + probeFade *= midf_c( probePriority ); @property( vct_num_probes ) - float4 reflDirLS_dist = localCorrect( pixelData.reflDir, posInProbSpace, probe ); - float3 reflDirLS = reflDirLS_dist.xyz; + midf4 reflDirLS_dist = localCorrect( pixelData.reflDir, posInProbSpace, probe ); + midf3 reflDirLS = reflDirLS_dist.xyz; @else - float3 reflDirLS = localCorrect( pixelData.reflDir, posInProbSpace, probe ).xyz; + midf3 reflDirLS = localCorrect( pixelData.reflDir, posInProbSpace, probe ).xyz; @end - float3 normalLS = localCorrect( pixelData.normal, posInProbSpace, probe ).xyz; + midf3 normalLS = localCorrect( pixelData.normal, posInProbSpace, probe ).xyz; - float4 pccSingleEnvS; + midf4 pccSingleEnvS; @property( clear_coat ) - float3 clearCoatPccSingleEnvS; + midf3 clearCoatPccSingleEnvS; @end @property( !hlms_cubemaps_use_dpm ) - pccSingleEnvS = OGRE_SampleArrayCubeLevel( - texEnvProbeMap, samplerState@value(envMapRegSampler), reflDirLS, + pccSingleEnvS = OGRE_SampleArrayCubeLevelF16( + texEnvProbeMap, samplerState@value(envMapRegSampler), float3( reflDirLS ), probeCubemapIdx, @insertpiece( envSpecularRoughness ) ); @property( cubemaps_as_diffuse_gi ) - pccEnvD += OGRE_SampleArrayCubeLevel( + pccEnvD += OGRE_SampleArrayCubeLevelF16( texEnvProbeMap, samplerState@value(envMapRegSampler), normalLS, probeCubemapIdx, 11.0 ).xyz @insertpiece( ApplyEnvMapScale ) * probeFade; @@ -218,34 +218,34 @@ @property( clear_coat ) clearCoatPccSingleEnvS = OGRE_SampleArrayCubeLevel( texEnvProbeMap, samplerState@value( envMapRegSampler ), - reflDirLS, + float3( reflDirLS ), probeCubemapIdx, @insertpiece( envSpecularRoughnessClearCoat ) ).xyz @insertpiece( ApplyEnvMapScale ); clearCoatPccSingleEnvS *= probeFade; @end @else - pccSingleEnvS = OGRE_SampleArray2DLevel( + pccSingleEnvS = OGRE_SampleArray2DLevelF16( texEnvProbeMap, samplerState@value(envMapRegSampler), mapCubemapToDpm( reflDirLS ), probeCubemapIdx, @insertpiece( envSpecularRoughness ) ); @property( cubemaps_as_diffuse_gi ) - pccEnvD += OGRE_SampleArray2DLevel( + pccEnvD += OGRE_SampleArray2DLevelF16( texEnvProbeMap, samplerState@value(envMapRegSampler), mapCubemapToDpm( normalLS ), probeCubemapIdx, 11.0 ).xyz @insertpiece( ApplyEnvMapScale ) * probeFade; @end @property( clear_coat ) - clearCoatPccSingleEnvS = OGRE_SampleArray2DLevel( texEnvProbeMap, samplerState@value( envMapRegSampler ), - mapCubemapToDpm( reflDirLS ), - probeCubemapIdx, - @insertpiece( envSpecularRoughnessClearCoat ) ).xyz @insertpiece( ApplyEnvMapScale ); + clearCoatPccSingleEnvS = OGRE_SampleArray2DLevelF16( texEnvProbeMap, samplerState@value( envMapRegSampler ), + mapCubemapToDpm( reflDirLS ), + probeCubemapIdx, + @insertpiece( envSpecularRoughnessClearCoat ) ).xyz @insertpiece( ApplyEnvMapScale ); clearCoatPccSingleEnvS *= probeFade; @end @end pccSingleEnvS.xyz *= probeFade; @property( envmap_scale ) - pccSingleEnvS.xyz *= passBuf.ambientUpperHemi.w; + pccSingleEnvS.xyz *= midf_c( passBuf.ambientUpperHemi.w ); @end @property( vct_num_probes ) @@ -278,9 +278,9 @@ } @property( cubemaps_as_diffuse_gi ) - pccEnvD.xyz *= cubemapAccumWeight == 0.0f ? 1.0f : (1.0f / cubemapAccumWeight); + pccEnvD.xyz *= cubemapAccumWeight == _h( 0.0f ) ? _h( 1.0f ) : (_h( 1.0f ) / cubemapAccumWeight); @end - pccEnvS.xyz *= cubemapAccumWeight == 0.0f ? 1.0f : (1.0f / cubemapAccumWeight); + pccEnvS.xyz *= cubemapAccumWeight == _h( 0.0f ) ? _h( 1.0f ) : (_h( 1.0f ) / cubemapAccumWeight); @property( clear_coat ) clearCoatPccEnvS *= cubemapAccumWeight == 0.0f ? 1.0f : ( 1.0f / cubemapAccumWeight ); @@ -292,7 +292,7 @@ pixelData.envColourS * (numProbesVctLerp - accumVctLerp) ) / numProbesVctLerp; @property( cubemaps_as_diffuse_gi ) - pixelData.envColourD += vctSpecular.w > 0 ? float3( 0, 0, 0 ) : pccEnvD; + pixelData.envColourD += vctSpecular.w > 0 ? midf3_c( 0, 0, 0 ) : pccEnvD; @end @property( clear_coat ) diff --git a/ogre2/src/media/Hlms/Pbs/Any/LightProfiles_piece_ps.any b/ogre2/src/media/Hlms/Pbs/Any/LightProfiles_piece_ps.any index e456d0903..24f452488 100644 --- a/ogre2/src/media/Hlms/Pbs/Any/LightProfiles_piece_ps.any +++ b/ogre2/src/media/Hlms/Pbs/Any/LightProfiles_piece_ps.any @@ -44,12 +44,12 @@ return (inX >= 0) ? res : 3.14159265359f - res; // Undo range reduction } - float getPhotometricAttenuation( float cosAngle, float profileIdx OGRE_PHOTOMETRIC_ARG_DECL ) + midf getPhotometricAttenuation( float cosAngle, float profileIdx OGRE_PHOTOMETRIC_ARG_DECL ) { //float angle = acos( clamp( cosAngle, -1.0, 1.0 ) ) * ( 1.0 / 3.14159265359f ); float angle = fast_acos( clamp( cosAngle, -1.0, 1.0 ) ) * ( 1.0 / 3.14159265359f ); - return OGRE_SampleLevel( lightProfiles, lightProfilesSampler, - float2( angle, profileIdx ), 0.0 ).r; + return OGRE_SampleLevelF16( lightProfiles, lightProfilesSampler, + float2( angle, profileIdx ), 0.0 ).r; } @end diff --git a/ogre2/src/media/Hlms/Pbs/Any/Main/200.BRDFs_piece_ps.any b/ogre2/src/media/Hlms/Pbs/Any/Main/200.BRDFs_piece_ps.any index 8908b3268..76a7a12c7 100644 --- a/ogre2/src/media/Hlms/Pbs/Any/Main/200.BRDFs_piece_ps.any +++ b/ogre2/src/media/Hlms/Pbs/Any/Main/200.BRDFs_piece_ps.any @@ -6,10 +6,10 @@ // getDiffuseFresnel = 1.0 - F0 + pow( 1.0 - NdotL, 5.0 ) * F0 // getSpecularFresnelWithRoughness = F0 + pow( 1.0 - VdotH, 5.0 ) * (max(roughness, (1.0 - F0)) - F0) // getDiffuseFresnelWithRoughness = max(roughness, (1.0 - F0) - F0 + pow( 1.0 - NdotL, 5.0 ) * F0 -@piece( getSpecularFresnel )pixelData.F0 + pow( 1.0 - VdotH, 5.0 ) * (1.0 - pixelData.F0)@end -@piece( getDiffuseFresnel )1.0 - pixelData.F0 + pow( 1.0 - NdotL, 5.0 ) * pixelData.F0@end -@piece( getSpecularFresnelWithRoughness )pixelData.F0 + pow( 1.0 - pixelData.NdotV, 5.0 ) * (max( make_float_fresnel( 1.0 - pixelData.roughness ), pixelData.F0 ) - pixelData.F0)@end -@piece( getDiffuseFresnelWithRoughness )max( make_float_fresnel( 1.0 - pixelData.roughness ), pixelData.F0 ) - pixelData.F0 + pow( 1.0 - NdotL, 5.0 ) * pixelData.F0@end +@piece( getSpecularFresnel )pixelData.F0 + pow( _h( 1.0 ) - VdotH, _h( 5.0 ) ) * (_h( 1.0 ) - pixelData.F0)@end +@piece( getDiffuseFresnel )_h( 1.0 ) - pixelData.F0 + pow( _h( 1.0 ) - NdotL, _h( 5.0 ) ) * pixelData.F0@end +@piece( getSpecularFresnelWithRoughness )pixelData.F0 + pow( _h( 1.0 ) - pixelData.NdotV, _h( 5.0 ) ) * (max( make_float_fresnel( _h( 1.0 ) - pixelData.perceptualRoughness ), pixelData.F0 ) - pixelData.F0)@end +@piece( getDiffuseFresnelWithRoughness )max( make_float_fresnel( _h( 1.0 ) - pixelData.perceptualRoughness ), pixelData.F0 ) - pixelData.F0 + pow( _h( 1.0 ) - NdotL, _h( 5.0 ) ) * pixelData.F0@end @property( !fresnel_scalar ) @piece( getMaxFresnelS )fresnelS@end @@ -20,45 +20,49 @@ @property( BRDF_BlinnPhong ) @piece( DeclareBRDF ) //Blinn-Phong -INLINE float3 BRDF( float3 lightDir, float3 lightDiffuse, float3 lightSpecular, PixelData pixelData ) +INLINE midf3 BRDF( midf3 lightDir, midf3 lightDiffuse, midf3 lightSpecular, PixelData pixelData PASSBUF_ARG_DECL ) { - float3 halfWay = normalize( lightDir + pixelData.viewDir ); - float NdotL = saturate( dot( pixelData.normal, lightDir ) ); //Diffuse (Lambert) - float NdotH = clamp( dot( pixelData.normal, halfWay ), 0.001, 1.0 ); //Specular + midf3 halfWay = normalize( lightDir + pixelData.viewDir ); + midf NdotL = saturate( dot( pixelData.normal, lightDir ) ); //Diffuse (Lambert) + midf NdotH = clamp( dot( pixelData.normal, halfWay ), _h( 0.001 ), _h( 1.0 ) ); //Specular @property( !legacy_math_brdf ) - float VdotH = clamp( dot( pixelData.viewDir, halfWay ), 0.001, 1.0 ); //Fresnel + midf VdotH = clamp( dot( pixelData.viewDir, halfWay ), _h( 0.001 ), _h( 1.0 ) ); //Fresnel //Fresnel term (Schlick's approximation) float_fresnel fresnelS = @insertpiece( getSpecularFresnel ); - @property( fresnel_separate_diffuse ) - float_fresnel fresnelD = @insertpiece( getDiffuseFresnel ); - @else - float fresnelD = 1.0f - @insertpiece( getMaxFresnelS ); + @property( fresnel_has_diffuse ) + @property( fresnel_separate_diffuse ) + float_fresnel fresnelD = @insertpiece( getDiffuseFresnel ); + @else + midf fresnelD = _h( 1.0f ) - @insertpiece( getMaxFresnelS ); + @end + @else + midf fresnelD = _h( 1.0f ); @end @end @property( !roughness_is_shininess ) - float shininess = exp2( 10.0 * (1.0 - pixelData.roughness) + 1.0 ) * 0.25; + midf shininess = exp2( _h( 10.0 ) * (_h( 1.0 ) - pixelData.roughness) + _h( 1.0 ) ) * _h( 0.25 ); @else - float shininess = pixelData.roughness; + midf shininess = pixelData.roughness; @end - float blinnPhong = pow( NdotH, shininess ); + midf blinnPhong = pow( NdotH, shininess ); @property( !legacy_math_brdf ) //Normalize Blinn-Phong using (n + 8) / (8 * pi) //Note this factor is an approximation. The real normalization is //*much* more expensive. See: //http://www.rorydriscoll.com/2009/01/25/energy-conservation-in-games/ - blinnPhong *= (shininess + 8.0) / (8.0 * 3.141592654); + blinnPhong *= ( shininess + _h( 8.0 ) ) / _h( 8.0 * 3.141592654 ); //Avoid very small denominators, they go to NaN or cause aliasing artifacts //Note: For blinn-phong we use larger denominators otherwise specular blows out of proportion - float_fresnel Rs = ( fresnelS * blinnPhong ) / max( 4.0 * pixelData.NdotV * NdotL, 0.75 ); + float_fresnel Rs = ( fresnelS * blinnPhong ) / max( _h( 4.0 ) * pixelData.NdotV * NdotL, _h( 0.75 ) ); //Make diffuse look closer to Default. - fresnelD *= lerp( 1.0, 1.0 / 1.51, pixelData.roughness ); + fresnelD *= lerp( _h( 1.0 ), _h( 1.0 / 1.51 ), pixelData.roughness ); @else - float Rs = blinnPhong; - float fresnelD = 1.0; + midf Rs = blinnPhong; + midf fresnelD = _h( 1.0 ); @end return NdotL * (pixelData.specular.xyz * lightSpecular * Rs + @@ -70,50 +74,69 @@ INLINE float3 BRDF( float3 lightDir, float3 lightDiffuse, float3 lightSpecular, @property( BRDF_CookTorrance ) @piece( DeclareBRDF ) //Cook-Torrance -INLINE float3 BRDF( float3 lightDir, float3 lightDiffuse, float3 lightSpecular, PixelData pixelData ) +INLINE midf3 BRDF( midf3 lightDir, midf3 lightDiffuse, midf3 lightSpecular, PixelData pixelData PASSBUF_ARG_DECL ) { - float3 halfWay = normalize( lightDir + pixelData.viewDir ); - float NdotL = saturate( dot( pixelData.normal, lightDir ) ); - float NdotH = clamp( dot( pixelData.normal, halfWay ), 0.001, 1.0 ); - float VdotH = clamp( dot( pixelData.viewDir, halfWay ), 0.001, 1.0 ); + midf3 halfWay = normalize( lightDir + pixelData.viewDir ); + midf NdotL = saturate( dot( pixelData.normal, lightDir ) ); + midf NdotH = clamp( dot( pixelData.normal, halfWay ), _h( 0.001 ), _h( 1.0 ) ); + midf VdotH = clamp( dot( pixelData.viewDir, halfWay ), _h( 0.001 ), _h( 1.0 ) ); - float sqR = pixelData.roughness * pixelData.roughness; + midf sqR = pixelData.roughness * pixelData.roughness; //Roughness/Distribution/NDF term (Beckmann distribution) //Formula: // Where alpha = NdotH and m = roughness // R = [ 1 / (m^2 x cos(alpha)^4 ] x [ e^( -tan(alpha)^2 / m^2 ) ] // R = [ 1 / (m^2 x cos(alpha)^4 ] x [ e^( ( cos(alpha)^2 - 1 ) / (m^2 cos(alpha)^2 ) ] - float NdotH_sq = NdotH * NdotH; - float roughness_a = 1.0 / ( 3.141592654 * sqR * NdotH_sq * NdotH_sq );//( 1 / (m^2 x cos(alpha)^4 ) - float roughness_b = NdotH_sq - 1.0; //( cos(alpha)^2 - 1 ) - float roughness_c = sqR * NdotH_sq; //( m^2 cos(alpha)^2 ) +@property( precision_mode == full32 ) + midf NdotH_sq = NdotH * NdotH; + midf roughness_b = NdotH_sq - _h( 1.0 ); //( cos(alpha)^2 - 1 ) +@else + // Use Lagrange's identity to compute 1 - NdotH_sq with mediump + // ||a x b||^2 = ||a||^2 ||b||^2 - (a . b)^2 + // since N and H are unit vectors: ||N x H||^2 = 1.0 - NoH^2 + // + // See https://github.com/google/filament/blob/f40b08d826c69df9fca2711841f1a9ecb77386e8/shaders/src/brdf.fs#L55 + // for details + midf3 NcrossH = cross( pixelData.normal, halfWay ); + midf roughness_b = -dot( NcrossH, NcrossH );//( cos(alpha)^2 - 1 ) + midf NdotH_sq = roughness_b + _h( 1.0 ); +@end + midf roughness_a = _h( 1.0 ) / ( _h( 3.141592654 ) * sqR * NdotH_sq * NdotH_sq );//( 1 / (m^2 x cos(alpha)^4 ) + midf roughness_c = sqR * NdotH_sq; //( m^2 cos(alpha)^2 ) //Avoid Inf * 0 = NaN; we need Inf * 0 = 0 - float R = min( roughness_a, 65504.0 ) * exp( roughness_b / roughness_c ); + midf R = min( roughness_a, _h( 65504.0 ) ) * exp( roughness_b / roughness_c ); + + ensureValidRangeF16( R ); //Geometric/Visibility term (Cook Torrance) - float shared_geo = 2.0 * NdotH / VdotH; - float geo_b = shared_geo * pixelData.NdotV; - float geo_c = shared_geo * NdotL; - float G = min( 1.0, min( geo_b, geo_c ) ); + midf shared_geo = _h( 2.0 ) * NdotH / VdotH; + ensureValidRangeF16( shared_geo ); + midf geo_b = shared_geo * pixelData.NdotV; + midf geo_c = shared_geo * NdotL; + midf G = min( _h( 1.0 ), min( geo_b, geo_c ) ); //Fresnel term (Schlick's approximation) //Formula: // fresnelS = lerp( (1 - V*H)^5, 1, F0 ) // fresnelD = lerp( (1 - N*L)^5, 1, 1 - F0 ) [See s2010_course_note_practical_implementation_at_triace.pdf] - float_fresnel fresnelS = @insertpiece( getSpecularFresnel ); - @property( fresnel_separate_diffuse ) - float_fresnel fresnelD = @insertpiece( getDiffuseFresnel ); - @else - float fresnelD = 1.0f - @insertpiece( getMaxFresnelS ); - @end + float_fresnel fresnelS = @insertpiece( getSpecularFresnel ); + @property( fresnel_has_diffuse ) + @property( fresnel_separate_diffuse ) + float_fresnel fresnelD = @insertpiece( getDiffuseFresnel ); + @else + midf fresnelD = _h( 1.0f ) - @insertpiece( getMaxFresnelS ); + @end + @else + midf fresnelD = _h( 1.0f ); + @end //Avoid very small denominators, they go to NaN or cause aliasing artifacts - float_fresnel Rs = ( fresnelS * (R * G) ) / max( 4.0 * pixelData.NdotV * NdotL, 0.01 ); + float_fresnel Rs = ( fresnelS * (R * G) ) / max( _h( 4.0 ) * pixelData.NdotV * NdotL, _h( 0.01 ) ); - return NdotL * (pixelData.specular.xyz * lightSpecular * Rs + - pixelData.diffuse.xyz * lightDiffuse * fresnelD); + return NdotL * (pixelData.specular.xyz * lightSpecular * Rs + + pixelData.diffuse.xyz * lightDiffuse * fresnelD); } @end @end @@ -121,32 +144,50 @@ INLINE float3 BRDF( float3 lightDir, float3 lightDiffuse, float3 lightSpecular, @property( BRDF_Default ) @piece( DeclareBRDF ) //Default BRDF -INLINE float3 BRDF( float3 lightDir, float3 lightDiffuse, float3 lightSpecular, PixelData pixelData ) +INLINE midf3 BRDF( midf3 lightDir, midf3 lightDiffuse, midf3 lightSpecular, PixelData pixelData PASSBUF_ARG_DECL ) { - float3 halfWay = normalize( lightDir + pixelData.viewDir ); - float NdotL = saturate( dot( pixelData.normal, lightDir ) ); - float NdotH = saturate( dot( pixelData.normal, halfWay ) ); - float VdotH = saturate( dot( pixelData.viewDir, halfWay ) ); + midf3 halfWay = normalize( lightDir + pixelData.viewDir ); + midf NdotL = saturate( dot( pixelData.normal, lightDir ) ); + midf NdotH = saturate( dot( pixelData.normal, halfWay ) ); + midf VdotH = saturate( dot( pixelData.viewDir, halfWay ) ); - float sqR = pixelData.roughness * pixelData.roughness; + midf sqR = pixelData.roughness * pixelData.roughness; + //Geometric/Visibility term (Smith GGX Height-Correlated) +@property( GGX_height_correlated ) + midf Lambda_GGXV = NdotL * sqrt( (-pixelData.NdotV * sqR + pixelData.NdotV) * pixelData.NdotV + sqR ); + midf Lambda_GGXL = pixelData.NdotV * sqrt( (-NdotL * sqR + NdotL) * NdotL + sqR ); + + midf G = _h( 0.5 ) / (( Lambda_GGXV + Lambda_GGXL + _h( 1e-6f ) ) * _h( 3.141592654 )); +@else + midf k = ( pixelData.perceptualRoughness + _h( 1 ) ) * ( pixelData.perceptualRoughness + _h( 1 ) ) * _h( 0.125 ); + midf gL = NdotL * ( _h( 1 ) - k ) + k; + midf gV = pixelData.NdotV * ( _h( 1 ) - k ) + k; + midf G = _h( 1.0 ) / (( gL * gV + _h( 1e-4f ) ) * _h( 4 * 3.141592654 ) ); +@end + +@property( precision_mode == full32 ) //Roughness/Distribution/NDF term (GGX) //Formula: // Where alpha = roughness // R = alpha^2 / [ PI * [ ( NdotH^2 * (alpha^2 - 1) ) + 1 ]^2 ] - float f = ( NdotH * sqR - NdotH ) * NdotH + 1.0; - float R = sqR / (f * f); // f is guaranteed to not be 0 because we clamped pixelData.roughness + const midf f = ( NdotH * sqR - NdotH ) * NdotH + _h( 1.0 ); + midf R = sqR / (f * f); // f is guaranteed to not be 0 because we clamped pixelData.roughness - //Geometric/Visibility term (Smith GGX Height-Correlated) -@property( GGX_height_correlated ) - float Lambda_GGXV = NdotL * sqrt( (-pixelData.NdotV * sqR + pixelData.NdotV) * pixelData.NdotV + sqR ); - float Lambda_GGXL = pixelData.NdotV * sqrt( (-NdotL * sqR + NdotL) * NdotL + sqR ); - - float G = 0.5 / (( Lambda_GGXV + Lambda_GGXL + 1e-6f ) * 3.141592654); + const midf RG = R * G; @else - float gL = NdotL * (1-sqR) + sqR; - float gV = pixelData.NdotV * (1-sqR) + sqR; - float G = 1.0 / (( gL * gV + 1e-4f ) * 4 * 3.141592654); + // Lagrange identity + const midf3 NcrossH = cross( pixelData.normal, halfWay ); + const midf roughness_b = dot( NcrossH, NcrossH ); // 1.0 - NdotH * NdotH + + // We need to do 10000 / (100 * 100) because otherwise it flushes to 0, loosing a lot of info + const midf f = (-roughness_b * sqR + sqR + roughness_b) * _h( 100.0 ) ; + midf R = sqR * _h( 10000.0 ) / (f * f); + + // Avoid INF and NaNs + R = min( R, _h( 128.0 ) ); + G = min( G, _h( 128.0 ) ); + const midf RG = R * G; @end //Formula: @@ -154,38 +195,42 @@ INLINE float3 BRDF( float3 lightDir, float3 lightDiffuse, float3 lightSpecular, float_fresnel fresnelS = @insertpiece( getSpecularFresnel ); //We should divide Rs by PI, but it was done inside G for performance - float3 Rs = ( fresnelS * (R * G) ) * pixelData.specular.xyz; + midf3 Rs = ( fresnelS * RG ) * pixelData.specular.xyz; //Diffuse BRDF (*Normalized* Disney, see course_notes_moving_frostbite_to_pbr.pdf //"Moving Frostbite to Physically Based Rendering" Sebastien Lagarde & Charles de Rousiers) - float energyBias = pixelData.perceptualRoughness * 0.5; - float energyFactor = lerp( 1.0, 1.0 / 1.51, pixelData.perceptualRoughness ); - float fd90 = energyBias + 2.0 * VdotH * VdotH * pixelData.perceptualRoughness; - float lightScatter = 1.0 + (fd90 - 1.0) * pow( 1.0 - NdotL, 5.0 ); - float viewScatter = 1.0 + (fd90 - 1.0) * pow( 1.0 - pixelData.NdotV, 5.0 ); - - @property( fresnel_separate_diffuse ) - float_fresnel fresnelD = @insertpiece( getDiffuseFresnel ); - @else - float fresnelD = 1.0f - @insertpiece( getMaxFresnelS ); - @end + midf energyBias = pixelData.perceptualRoughness * _h( 0.5 ); + midf energyFactor = lerp( _h( 1.0 ), _h( 1.0 / 1.51 ), pixelData.perceptualRoughness ); + midf fd90 = energyBias + _h( 2.0 ) * VdotH * VdotH * pixelData.perceptualRoughness; + midf lightScatter = _h( 1.0 ) + (fd90 - _h( 1.0 )) * pow( _h( 1.0 ) - NdotL, _h( 5.0 ) ); + midf viewScatter = _h( 1.0 ) + (fd90 - _h( 1.0 )) * pow( _h( 1.0 ) - pixelData.NdotV, _h( 5.0 ) ); + + @property( fresnel_has_diffuse ) + @property( fresnel_separate_diffuse ) + float_fresnel fresnelD = @insertpiece( getDiffuseFresnel ); + @else + midf fresnelD = _h( 1.0f ) - @insertpiece( getMaxFresnelS ); + @end + @else + midf fresnelD = _h( 1.0f ); + @end //We should divide Rd by PI, but it is already included in kD - float3 Rd = (lightScatter * viewScatter * energyFactor * fresnelD) * pixelData.diffuse.xyz; + midf3 Rd = (lightScatter * viewScatter * energyFactor * fresnelD) * pixelData.diffuse.xyz; @property( clear_coat ) - float3 color = Rd + Rs; + midf3 color = Rd + Rs; - float Fcc; - float clearCoat = clearCoatLobe(pixelData, halfWay, NdotH, VdotH, Fcc); - float attenuation = 1.0 - Fcc; + midf Fcc; + midf clearCoat = clearCoatLobe(pixelData, halfWay, NdotH, VdotH, Fcc); + midf attenuation = _h( 1.0 ) - Fcc; @property( normal_map ) color *= attenuation * NdotL; // If the material has a normal map, we want to use the geometric normal // instead to avoid applying the normal map details to the clear coat layer - float clearCoatNoL = saturate(dot(pixelData.geomNormal, lightDir)); + midf clearCoatNoL = saturate(dot(pixelData.geomNormal, lightDir)); color += clearCoat * clearCoatNoL; return color * lightSpecular; @@ -196,7 +241,7 @@ INLINE float3 BRDF( float3 lightDir, float3 lightDiffuse, float3 lightSpecular, return color * lightSpecular * NdotL; @end @else - return NdotL * (Rs * lightSpecular + Rd * lightDiffuse); + return NdotL * (Rs * lightSpecular + Rd * lightDiffuse); @end } @end @@ -205,9 +250,9 @@ INLINE float3 BRDF( float3 lightDir, float3 lightDiffuse, float3 lightSpecular, @property( hlms_enable_vpls ) @piece( DeclareBRDF_InstantRadiosity ) //Simplified cheap BRDF for Instant Radiosity. -float3 BRDF_IR( float3 lightDir, float3 lightDiffuse, PixelData pixelData ) +midf3 BRDF_IR( midf3 lightDir, midf3 lightDiffuse, PixelData pixelData ) { - float NdotL = clamp( dot( pixelData.normal, lightDir ), 0.0, 1.0 ); + midf NdotL = saturate( dot( pixelData.normal, lightDir ) ); float_fresnel fresnelD = @insertpiece( getDiffuseFresnel ); //We should divide Rd by PI, but it is already included in kD @@ -239,22 +284,31 @@ float3 BRDF_IR( float3 lightDir, float3 lightDiffuse, PixelData pixelData ) @property( ltc_texture_available ) #define brdfLUT ltcMatrix - float2 envBRDF = OGRE_SampleArray2D( brdfLUT, ltcSampler, - float2( pixelData.NdotV, - 1.0 - pixelData.perceptualRoughness ), 2 ).xy; + midf3 envBRDF = OGRE_SampleArray2DF16( brdfLUT, ltcSampler, + float2( pixelData.NdotV, + 1.0 - pixelData.perceptualRoughness ), 2 ).xyz; @else - float2 envBRDF = float2( 1.0f, 0.0f ); + midf3 envBRDF = midf3_c( 1.0f, 0.0f, 1.0f ); @end - @property( fresnel_separate_diffuse ) - float NdotL = saturate( dot( pixelData.normal, pixelData.reflDir ) ); - float_fresnel fresnelD = @insertpiece( getDiffuseFresnelWithRoughness ); + @property( fresnel_has_diffuse ) + @property( fresnel_separate_diffuse ) + midf NdotL = saturate( dot( pixelData.normal, pixelData.reflDir ) ); + float_fresnel fresnelD = @insertpiece( getDiffuseFresnelWithRoughness ); + @else + midf fresnelD = _h( 1.0f ) - @insertpiece( getMaxFresnelS ); + @end @else - float fresnelD = 1.0f - @insertpiece( getMaxFresnelS ); + midf fresnelD = _h( 1.0f ); @end - float3 Rd = pixelData.envColourD * pixelData.diffuse.xyz * fresnelD; - float3 Rs = pixelData.envColourS * pixelData.specular.xyz * ( fresnelS * envBRDF.x + envBRDF.y ); + midf3 Rd = pixelData.envColourD * pixelData.diffuse.xyz * _h( 3.141592654 ) * fresnelD * envBRDF.z; + midf3 Rs = pixelData.envColourS * pixelData.specular.xyz * + @property( industry_compatible ) + ( pixelData.F0 * envBRDF.x + envBRDF.y ); + @else + ( fresnelS * envBRDF.x + envBRDF.y ); + @end @property( clear_coat ) @property( normal_map ) @@ -268,7 +322,16 @@ float3 BRDF_IR( float3 lightDir, float3 lightDiffuse, PixelData pixelData ) float attenuation = 1.0 - Fc; Rd *= attenuation; Rs *= attenuation; - Rs += pixelData.clearCoatEnvColourS * Fc; + + @property( ltc_texture_available ) + midf3 clearCoatEnvBRDF = OGRE_SampleArray2DF16( brdfLUT, ltcSampler, + float2( clearCoatNoV, + 1.0 - pixelData.clearCoatPerceptualRoughness ), 2 ).xyz; + @else + midf3 clearCoatEnvBRDF = midf3_c( 1.0f, 0.0f, 1.0f ); + @end + + Rs += pixelData.clearCoatEnvColourS * pixelData.specular.xyz * ( _h( 0.04 ) * clearCoatEnvBRDF.x + clearCoatEnvBRDF.y ) * pixelData.clearCoat; @end finalColour += Rd + Rs; @@ -290,6 +353,9 @@ float3 BRDF_IR( float3 lightDir, float3 lightDiffuse, PixelData pixelData ) @piece( ObjLightMaskCmpNonCasterLoopEnd )@add( fineMaskLightIdx, hlms_lights_directional_non_caster )@end @end @piece( andObjLightMaskCmp )&& ((objLightMask & floatBitsToUint( light0Buf.lights[@counter(fineMaskLightIdx)].position.w )) != 0u)@end + @property( hlms_static_branch_shadow_map_lights ) + @piece( andObjLightMaskCmp_light_idx )&& ((objLightMask & floatBitsToUint( light0Buf.lights[light_idx].position.w )) != 0u)@end + @end @piece( andObjAreaApproxLightMaskCmp )&& ((objLightMask & floatBitsToUint( light1Buf.areaApproxLights[i].position.w )) != 0u)@end @piece( andObjAreaLtcLightMaskCmp )&& ((objLightMask & floatBitsToUint( light2Buf.areaLtcLights[i].position.w )) != 0u)@end @else @@ -299,6 +365,9 @@ float3 BRDF_IR( float3 lightDir, float3 lightDiffuse, PixelData pixelData ) @piece( ObjLightMaskCmpNonCasterLoopEnd )@add( fineMaskLightIdx, hlms_lights_directional_non_caster )@end @end @piece( andObjLightMaskCmp )&& ((objLightMask & light0Buf.lights[@counter(fineMaskLightIdx)].lightMask) != 0u)@end + @property( hlms_static_branch_shadow_map_lights ) + @piece( andObjLightMaskCmp_light_idx )&& ((objLightMask & light0Buf.lights[light_idx].lightMask) != 0u)@end + @end @piece( andObjAreaApproxLightMaskCmp )&& ((objLightMask & light1Buf.areaApproxLights[i].lightMask) != 0u)@end @piece( andObjAreaLtcLightMaskCmp )&& ((objLightMask & light2Buf.areaLtcLights[i].lightMask) != 0u)@end @end diff --git a/ogre2/src/media/Hlms/Pbs/Any/Main/200.BlendModes_piece_ps.any b/ogre2/src/media/Hlms/Pbs/Any/Main/200.BlendModes_piece_ps.any index e5f133807..cc3cfe286 100644 --- a/ogre2/src/media/Hlms/Pbs/Any/Main/200.BlendModes_piece_ps.any +++ b/ogre2/src/media/Hlms/Pbs/Any/Main/200.BlendModes_piece_ps.any @@ -8,26 +8,26 @@ @piece( NormalNonPremul ) //Normal Non Premultiplied @value(t) pixelData.diffuse.xyz = lerp( pixelData.diffuse.xyz, detailCol@value(t).xyz, detailCol@value(t).a ); - pixelData.diffuse.w = lerp( pixelData.diffuse.w, 1.0, detailCol@value(t).w ); + pixelData.diffuse.w = lerp( pixelData.diffuse.w, _h( 1.0 ), detailCol@value(t).w ); @end @piece( NormalPremul ) //Normal Premultiplied @value(t) - pixelData.diffuse.xyz = (1.0 - detailCol@value(t).a) * pixelData.diffuse.xyz + detailCol@value(t).xyz; - pixelData.diffuse.w = lerp( pixelData.diffuse.w, 1.0, detailCol@value(t).w ); + pixelData.diffuse.xyz = (_h( 1.0 ) - detailCol@value(t).a) * pixelData.diffuse.xyz + detailCol@value(t).xyz; + pixelData.diffuse.w = lerp( pixelData.diffuse.w, _h( 1.0 ), detailCol@value(t).w ); @end @piece( Add ) //Add @value(t) pixelData.diffuse.xyz = lerp( pixelData.diffuse.xyz, - min( pixelData.diffuse.xyz + detailCol@value(t).xyz, float3(1.0, 1.0, 1.0) ), + min( pixelData.diffuse.xyz + detailCol@value(t).xyz, midf3_c(1.0, 1.0, 1.0) ), detailCol@value(t).a ); @end @piece( Subtract ) //Subtract @value(t) pixelData.diffuse.xyz = lerp( pixelData.diffuse.xyz, - max( pixelData.diffuse.xyz - detailCol@value(t).xyz, float3(0.0, 0.0, 0.0) ), + max( pixelData.diffuse.xyz - detailCol@value(t).xyz, midf3_c(0.0, 0.0, 0.0) ), detailCol@value(t).a ); @end @@ -41,21 +41,21 @@ @piece( Multiply2x ) //Multiply2x @value(t) pixelData.diffuse.xyz = lerp( pixelData.diffuse.xyz, - min( pixelData.diffuse.xyz * detailCol@value(t).xyz * 2.0, float3(1.0, 1.0, 1.0) ), + min( pixelData.diffuse.xyz * detailCol@value(t).xyz * 2.0, midf3_c(1.0, 1.0, 1.0) ), detailCol@value(t).a ); @end @piece( Screen ) //Screen @value(t) pixelData.diffuse.xyz = lerp( pixelData.diffuse.xyz, - 1.0 - (1.0 - pixelData.diffuse.xyz) * (1.0 - detailCol@value(t).xyz), + _h( 1.0 ) - (_h( 1.0 ) - pixelData.diffuse.xyz) * (_h( 1.0 ) - detailCol@value(t).xyz), detailCol@value(t).a ); @end @piece( Overlay ) //Overlay @value(t) pixelData.diffuse.xyz = lerp( pixelData.diffuse.xyz, - pixelData.diffuse.xyz * ( pixelData.diffuse.xyz + 2.0 * detailCol@value(t).xyz * (1.0 - pixelData.diffuse.xyz) ), + pixelData.diffuse.xyz * ( pixelData.diffuse.xyz + _h( 2.0 ) * detailCol@value(t).xyz * (_h( 1.0 ) - pixelData.diffuse.xyz) ), detailCol@value(t).a ); @end @@ -76,14 +76,14 @@ @piece( GrainExtract ) //GrainExtract @value(t) pixelData.diffuse.xyz = lerp( pixelData.diffuse.xyz, - (pixelData.diffuse.xyz - detailCol@value(t).xyz) + 0.5f, + (pixelData.diffuse.xyz - detailCol@value(t).xyz) + _h( 0.5f ), detailCol@value(t).a ); @end @piece( GrainMerge ) //GrainMerge @value(t) pixelData.diffuse.xyz = lerp( pixelData.diffuse.xyz, - (pixelData.diffuse.xyz + detailCol@value(t).xyz) - 0.5f, + (pixelData.diffuse.xyz + detailCol@value(t).xyz) - _h( 0.5f ), detailCol@value(t).a ); @end @@ -97,12 +97,12 @@ @piece( NormalNonPremul ) //Normal Non Premultiplied @value(t) - pixelData.diffuse = lerp( pixelData.diffuse, float4( 1.0, 1.0, 1.0,1.0 ), detailCol@value(t) ); + pixelData.diffuse = lerp( pixelData.diffuse, midf4_c( 1.0, 1.0, 1.0, 1.0 ), detailCol@value(t) ); @end @piece( NormalPremul ) //Normal Premultiplied @value(t) - pixelData.diffuse = lerp( pixelData.diffuse, float4( 1.0, 1.0, 1.0,1.0 ), detailCol@value(t) ); + pixelData.diffuse = lerp( pixelData.diffuse, midf4_c( 1.0, 1.0, 1.0, 1.0 ), detailCol@value(t) ); @end @end diff --git a/ogre2/src/media/Hlms/Pbs/Any/Main/200.ForwardPlus_piece_ps.any b/ogre2/src/media/Hlms/Pbs/Any/Main/200.ForwardPlus_piece_ps.any index 864e04fc3..605f8b725 100644 --- a/ogre2/src/media/Hlms/Pbs/Any/Main/200.ForwardPlus_piece_ps.any +++ b/ogre2/src/media/Hlms/Pbs/Any/Main/200.ForwardPlus_piece_ps.any @@ -121,11 +121,11 @@ float4 posAndType = readOnlyFetch( f3dLightList, int(idx) ); @property( !hlms_forwardplus_fine_light_mask ) - float3 lightDiffuse = readOnlyFetch( f3dLightList, int(idx + 1u) ).xyz; + midf3 lightDiffuse = midf3_c( readOnlyFetch( f3dLightList, int(idx + 1u) ).xyz ); @else float4 lightDiffuse = readOnlyFetch( f3dLightList, int(idx + 1u) ).xyzw; @end - float3 lightSpecular= readOnlyFetch( f3dLightList, int(idx + 2u) ).xyz; + midf3 lightSpecular = midf3_c( readOnlyFetch( f3dLightList, int(idx + 2u) ).xyz ); float4 attenuation = readOnlyFetch( f3dLightList, int(idx + 3u) ).xyzw; @property( light_profiles_texture ) float4 spotDirection= readOnlyFetch( f3dLightList, int(idx + 4u) ).xyzw; @@ -137,19 +137,20 @@ if( fDistance <= attenuation.x @insertpiece( andObjLightMaskFwdPlusCmp ) ) { lightDir *= 1.0 / fDistance; - float atten = 1.0 / (0.5 + (attenuation.y + attenuation.z * fDistance) * fDistance ); + midf atten = midf_c( 1.0 / (0.5 + (attenuation.y + attenuation.z * fDistance) * fDistance ) ); @property( hlms_forward_fade_attenuation_range ) - atten *= max( (attenuation.x - fDistance) * attenuation.w, 0.0f ); + atten *= midf_c( max( (attenuation.x - fDistance) * attenuation.w, 0.0f ) ); @end @property( light_profiles_texture ) - float spotCosAngle = dot( -lightDir, spotDirection.xyz ); + midf spotCosAngle = dot( midf3_c( -lightDir ), midf3_c( spotDirection.xyz ) ); atten *= getPhotometricAttenuation( spotCosAngle, spotDirection.w OGRE_PHOTOMETRIC_ARG ); @end //Point light - float3 tmpColour = BRDF( lightDir, lightDiffuse.xyz, lightSpecular, pixelData ); + midf3 tmpColour = + BRDF( midf3_c( lightDir ), midf3_c( lightDiffuse.xyz ), lightSpecular, pixelData PASSBUF_ARG ); finalColour += tmpColour * atten; } } @@ -168,18 +169,18 @@ float4 posAndType = readOnlyFetch( f3dLightList, int(idx) ); @property( !hlms_forwardplus_fine_light_mask ) - float3 lightDiffuse = readOnlyFetch( f3dLightList, int(idx + 1u) ).xyz; + midf3 lightDiffuse = midf3_c( readOnlyFetch( f3dLightList, int(idx + 1u) ).xyz ); @else float4 lightDiffuse = readOnlyFetch( f3dLightList, int(idx + 1u) ).xyzw; @end - float3 lightSpecular = readOnlyFetch( f3dLightList, int(idx + 2u) ).xyz; + midf3 lightSpecular = midf3_c( readOnlyFetch( f3dLightList, int(idx + 2u) ).xyz ); float4 attenuation = readOnlyFetch( f3dLightList, int(idx + 3u) ).xyzw; @property( !light_profiles_texture ) float3 spotDirection = readOnlyFetch( f3dLightList, int(idx + 4u) ).xyz; @else float4 spotDirection = readOnlyFetch( f3dLightList, int(idx + 4u) ).xyzw; @end - float3 spotParams = readOnlyFetch( f3dLightList, int(idx + 5u) ).xyz; + midf3 spotParams = midf3_c( readOnlyFetch( f3dLightList, int(idx + 5u) ).xyz ); float3 lightDir = posAndType.xyz - inPs.pos; float fDistance = length( lightDir ); @@ -187,9 +188,9 @@ if( fDistance <= attenuation.x @insertpiece( andObjLightMaskFwdPlusCmp ) ) { lightDir *= 1.0 / fDistance; - float atten = 1.0 / (0.5 + (attenuation.y + attenuation.z * fDistance) * fDistance ); + midf atten = midf_c( 1.0 / (0.5 + (attenuation.y + attenuation.z * fDistance) * fDistance ) ); @property( hlms_forward_fade_attenuation_range ) - atten *= max( (attenuation.x - fDistance) * attenuation.w, 0.0f ); + atten *= midf_c( max( (attenuation.x - fDistance) * attenuation.w, 0.0f ) ); @end //spotParams.x = 1.0 / cos( InnerAngle ) - cos( OuterAngle ) @@ -197,9 +198,9 @@ //spotParams.z = falloff //Spot light - float spotCosAngle = dot( -lightDir, spotDirection.xyz ); + midf spotCosAngle = dot( midf3_c( -lightDir ), midf3_c( spotDirection.xyz ) ); - float spotAtten = saturate( (spotCosAngle - spotParams.y) * spotParams.x ); + midf spotAtten = saturate( (spotCosAngle - spotParams.y) * spotParams.x ); spotAtten = pow( spotAtten, spotParams.z ); atten *= spotAtten; @@ -210,7 +211,8 @@ if( spotCosAngle >= spotParams.y ) { - float3 tmpColour = BRDF( lightDir, lightDiffuse.xyz, lightSpecular, pixelData ); + midf3 tmpColour = + BRDF( midf3_c( lightDir ), midf3_c( lightDiffuse.xyz ), lightSpecular, pixelData PASSBUF_ARG ); finalColour += tmpColour * atten; } } @@ -230,7 +232,7 @@ //Get the light float4 posAndType = readOnlyFetch( f3dLightList, int(idx) ); - float3 lightDiffuse = readOnlyFetch( f3dLightList, int(idx + 1u) ).xyz; + midf3 lightDiffuse = midf3_c( readOnlyFetch( f3dLightList, int(idx + 1u) ).xyz ); float4 attenuation = readOnlyFetch( f3dLightList, int(idx + 3u) ).xyzw; float3 lightDir = posAndType.xyz - inPs.pos; @@ -239,35 +241,35 @@ if( fDistance <= attenuation.x ) { //lightDir *= 1.0 / fDistance; - float atten = 1.0 / (0.5 + (attenuation.y + attenuation.z * fDistance) * fDistance ); + midf atten = midf_c( 1.0 / (0.5 + (attenuation.y + attenuation.z * fDistance) * fDistance ) ); @property( hlms_forward_fade_attenuation_range ) - atten *= max( (attenuation.x - fDistance) * attenuation.w, 0.0f ); + atten *= midf_c( max( (attenuation.x - fDistance) * attenuation.w, 0.0f ) ); @end //float3 lightDir2 = posAndType.xyz - inPs.pos; //lightDir2 *= 1.0 / max( 1, fDistance ); //lightDir2 *= 1.0 / fDistance; - finalColour += BRDF_IR( lightDir, lightDiffuse, pixelData ) * atten; + finalColour += BRDF_IR( midf3_c( lightDir ), lightDiffuse, pixelData ) * atten; } } @end @property( hlms_forwardplus_debug ) @property( hlms_forwardplus == forward3d ) - float occupancy = (totalNumLightsInGrid / passBuf.f3dGridHWW[0].w); + midf occupancy = midf_c(totalNumLightsInGrid / passBuf.f3dGridHWW[0].w); @else - float occupancy = (totalNumLightsInGrid / float( @value( fwd_clustered_lights_per_cell ) )); + midf occupancy = midf_c(totalNumLightsInGrid / float( @value( fwd_clustered_lights_per_cell ) )); @end - float3 occupCol = float3( 0.0, 0.0, 0.0 ); - if( occupancy < 1.0 / 3.0 ) + midf3 occupCol = midf3_c( 0.0, 0.0, 0.0 ); + if( occupancy < _h( 1.0 / 3.0 ) ) occupCol.z = occupancy; - else if( occupancy < 2.0 / 3.0 ) + else if( occupancy < _h( 2.0 / 3.0 ) ) occupCol.y = occupancy; else occupCol.x = occupancy; - finalColour.xyz = lerp( finalColour.xyz, occupCol.xyz, 0.55f ) * 2; + finalColour.xyz = lerp( finalColour.xyz, occupCol.xyz, _h( 0.55f ) ) * _h( 2 ); @end @end @end diff --git a/ogre2/src/media/Hlms/Pbs/Any/Main/200.Textures_piece_ps.any b/ogre2/src/media/Hlms/Pbs/Any/Main/200.Textures_piece_ps.any index d730ecf05..0ffb34736 100644 --- a/ogre2/src/media/Hlms/Pbs/Any/Main/200.Textures_piece_ps.any +++ b/ogre2/src/media/Hlms/Pbs/Any/Main/200.Textures_piece_ps.any @@ -7,22 +7,22 @@ uniform sampler2DArray ltcMatrix; @end @property( syntax == glslvk ) - layout( ogre_t@value(ltcMatrix) ) uniform texture2DArray ltcMatrix; - layout( ogre_s@value(ltcMatrix) ) uniform sampler ltcSampler; + layout( ogre_t@value(ltcMatrix) ) midf_tex uniform texture2DArray ltcMatrix; + layout( ogre_s@value(ltcMatrix) ) midf_tex uniform sampler ltcSampler; @end @property( syntax == hlsl ) Texture2DArray ltcMatrix : register(t@value(ltcMatrix)); SamplerState ltcSampler : register(s@value(ltcMatrix)); @end @property( syntax == metal ) - , texture2d_array ltcMatrix [[texture(@value(ltcMatrix))]] + , texture2d_array ltcMatrix [[texture(@value(ltcMatrix))]] , sampler ltcSampler [[sampler(@value(ltcMatrix))]] @end @end @end @property( envmap_scale ) - @piece( ApplyEnvMapScale )* passBuf.ambientUpperHemi.w@end + @piece( ApplyEnvMapScale )* midf_c( passBuf.ambientUpperHemi.w )@end @end @property( use_envprobe_map ) diff --git a/ogre2/src/media/Hlms/Pbs/Any/Main/500.Structs_piece_vs_piece_ps.any b/ogre2/src/media/Hlms/Pbs/Any/Main/500.Structs_piece_vs_piece_ps.any index 40a493af1..c225d94af 100644 --- a/ogre2/src/media/Hlms/Pbs/Any/Main/500.Structs_piece_vs_piece_ps.any +++ b/ogre2/src/media/Hlms/Pbs/Any/Main/500.Structs_piece_vs_piece_ps.any @@ -168,6 +168,10 @@ CONST_BUFFER_STRUCT_BEGIN( PassBuffer, 0 ) float pssmBlendPoints@n;@end @end @property( hlms_pssm_fade ) float pssmFadePoint;@end +@property( hlms_static_branch_shadow_map_lights ) + float numShadowMapPointLights; + float numShadowMapSpotLights; +@end @property( !use_light_buffers ) @property( hlms_lights_spot )Light lights[@value(hlms_lights_spot)];@end @@ -226,19 +230,19 @@ CONST_BUFFER_STRUCT_END( passBuf ); @property( use_light_buffers ) -CONST_BUFFER_STRUCT_BEGIN( Light0Buffer, 4 ) +CONST_BUFFER_STRUCT_BEGIN( Light0Buffer, 3 ) { Light lights[16]; } CONST_BUFFER_STRUCT_END( light0Buf ); -CONST_BUFFER_STRUCT_BEGIN( Light1Buffer, 5 ) +CONST_BUFFER_STRUCT_BEGIN( Light1Buffer, 4 ) { AreaLight areaApproxLights[2]; } CONST_BUFFER_STRUCT_END( light1Buf ); -CONST_BUFFER_STRUCT_BEGIN( Light2Buffer, 6 ) +CONST_BUFFER_STRUCT_BEGIN( Light2Buffer, 5 ) { AreaLtcLight areaLtcLights[2]; } @@ -259,9 +263,9 @@ CONST_BUFFER_STRUCT_END( light2Buf ); @piece( PassDecl ) , constant PassBuffer &passBuf [[buffer(CONST_SLOT_START+0)]] @property( use_light_buffers ) - , constant Light0Buffer &light0Buf [[buffer(CONST_SLOT_START+4)]] - , constant Light1Buffer &light1Buf [[buffer(CONST_SLOT_START+5)]] - , constant Light2Buffer &light2Buf [[buffer(CONST_SLOT_START+6)]] + , constant Light0Buffer &light0Buf [[buffer(CONST_SLOT_START+3)]] + , constant Light1Buffer &light1Buf [[buffer(CONST_SLOT_START+4)]] + , constant Light2Buffer &light2Buf [[buffer(CONST_SLOT_START+5)]] @end // use_light_buffers @end @end @@ -368,12 +372,12 @@ struct Material @property( envprobe_map && envprobe_map != target_envprobe_map && use_parallax_correct_cubemaps && !hlms_enable_cubemaps_auto ) @piece( PccManualProbeDecl ) @property( syntax != metal ) - CONST_BUFFER( ManualProbe, 3 ) + CONST_BUFFER( ManualProbe, @value( num_pass_const_buffers ) ) { CubemapProbe manualProbe; }; @else - , constant CubemapProbe &manualProbe [[buffer(CONST_SLOT_START+3)]] + , constant CubemapProbe &manualProbe [[buffer(CONST_SLOT_START+@value( num_pass_const_buffers ))]] @end @end @end @@ -382,15 +386,15 @@ struct Material @pset( texcoord, 0 ) @piece( VStoPS_block ) - @property( syntax == metal ) + @property( syntax == metal || lower_gpu_overhead ) @property( (!hlms_shadowcaster || alpha_test) && !lower_gpu_overhead ) - ushort materialId [[flat]]; + FLAT_INTERPOLANT( ushort materialId, @counter(texcoord) ); @end @property( hlms_fine_light_mask || hlms_forwardplus_fine_light_mask ) - uint objLightMask [[flat]]; + FLAT_INTERPOLANT( uint objLightMask, @counter(texcoord) ); @end @property( use_planar_reflections ) - ushort planarReflectionIdx [[flat]]; + FLAT_INTERPOLANT( ushort planarReflectionIdx, @counter(texcoord) ); @end @else @property( (!hlms_shadowcaster || alpha_test) && !lower_gpu_overhead ) @@ -401,10 +405,10 @@ struct Material @property( !hlms_shadowcaster ) @property( hlms_normal || hlms_qtangent ) INTERPOLANT( float3 pos, @counter(texcoord) ); - INTERPOLANT( float3 normal, @counter(texcoord) ); + INTERPOLANT( midf3 normal, @counter(texcoord) ); @property( normal_map ) - INTERPOLANT( float3 tangent, @counter(texcoord) ); - @property( hlms_qtangent || hlms_tangent4 )FLAT_INTERPOLANT( float biNormalReflection, @counter(texcoord) );@end + INTERPOLANT( midf3 tangent, @counter(texcoord) ); + @property( hlms_qtangent || hlms_tangent4 )FLAT_INTERPOLANT( midf biNormalReflection, @counter(texcoord) );@end @end @end @foreach( hlms_uv_count, n ) @@ -420,7 +424,7 @@ struct Material @property( hlms_num_shadow_map_lights && !hlms_all_point_lights ) INTERPOLANT( float3 worldPos, @counter(texcoord) ); @property( hlms_normal || hlms_qtangent ) - INTERPOLANT( float3 worldNorm, @counter(texcoord) ); + INTERPOLANT( midf3 worldNorm, @counter(texcoord) ); @end @end @end @@ -433,6 +437,11 @@ struct Material @property( hlms_forwardplus && hlms_instanced_stereo ) INTERPOLANT( float3 cullCamPosXY, @counter(texcoord) ); @end + + @property( hlms_fog ) + // fog.xyz = colour + INTERPOLANT( midf3 fog, @counter(texcoord) ); + @end @else @property( alpha_test ) @foreach( hlms_uv_count, n ) @@ -448,5 +457,10 @@ struct Material @end @end @end + @property( hlms_emulate_clip_distances && hlms_pso_clip_distances ) + @foreach( hlms_pso_clip_distances, n ) + INTERPOLANT( float clipDistance@n, @counter(texcoord) ); + @end + @end @insertpiece( custom_VStoPS ) @end diff --git a/ogre2/src/media/Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any b/ogre2/src/media/Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any index da77c434f..99752eb78 100644 --- a/ogre2/src/media/Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any +++ b/ogre2/src/media/Hlms/Pbs/Any/Main/800.PixelShader_piece_ps.any @@ -1,5 +1,8 @@ -@piece( envSpecularRoughness ) pixelData.perceptualRoughness * passBuf.envMapNumMipmaps @end -@piece( envSpecularRoughnessClearCoat ) pixelData.clearCoatPerceptualRoughness * passBuf.envMapNumMipmaps @end +// The mapping below is a quadratic fit for log2(perceptualRoughness)+iblRoughnessOneLevel when +// iblRoughnessOneLevel is 4. We found empirically that this mapping works very well for +// a 256 cubemap with 5 levels used. But also scales well for other iblRoughnessOneLevel values. +@piece( envSpecularRoughness ) pixelData.perceptualRoughness * midf_c( passBuf.envMapNumMipmaps ) * ( _h( 2.0 ) - pixelData.perceptualRoughness ) @end +@piece( envSpecularRoughnessClearCoat ) pixelData.clearCoatPerceptualRoughness * midf_c( passBuf.envMapNumMipmaps ) * ( _h( 2.0 ) - pixelData.clearCoatPerceptualRoughness ) @end @piece( DefaultHeaderPS ) // START UNIFORM DECLARATION @@ -9,16 +12,19 @@ @end @insertpiece( MaterialStructDecl ) @insertpiece( InstanceStructDecl ) + @insertpiece( AtmosphereNprSkyStructDecl ) @end @insertpiece( custom_ps_uniformStructDeclaration ) // END UNIFORM DECLARATION @property( !fresnel_scalar ) - #define float_fresnel float - #define make_float_fresnel( x ) x + #define float_fresnel midf + #define float_fresnel_c( x ) midf_c( x ) + #define make_float_fresnel( x ) midf_c( x ) @else - #define float_fresnel float3 - #define make_float_fresnel( x ) float3( x, x, x ) + #define float_fresnel midf3 + #define float_fresnel_c( x ) midf3_c( x ) + #define make_float_fresnel( x ) midf3_c( x, x, x ) @end @insertpiece( DeclReverseDepthMacros ) @@ -38,64 +44,73 @@ struct PixelData { @property( !hlms_shadowcaster ) - float3 normal; + midf3 normal; @property( normal_map ) - float3 geomNormal; + midf3 geomNormal; @else #define geomNormal normal @end - float4 diffuse; - float3 specular; + @property( detail_triplanar ) + midf3 worldSpaceNormal; + @end + midf4 diffuse; + midf3 specular; @property( clear_coat ) - float clearCoat; - float clearCoatPerceptualRoughness; - float clearCoatRoughness; + midf clearCoat; + midf clearCoatPerceptualRoughness; + midf clearCoatRoughness; @end - float perceptualRoughness; - float roughness; + midf perceptualRoughness; + midf roughness; float_fresnel F0; @property( needs_view_dir ) - float3 viewDir; - float NdotV; + midf3 viewDir; + midf NdotV; @end @property( needs_refl_dir ) - float3 reflDir; + midf3 reflDir; @property( needs_env_brdf ) - float3 envColourS; - float3 envColourD; + midf3 envColourS; + midf3 envColourD; @property( clear_coat ) - float3 clearCoatEnvColourS; + midf3 clearCoatEnvColourS; @end @end @end @else - float4 diffuse; //We only use the .w component, Alpha + midf4 diffuse; //We only use the .w component, Alpha @end + + @insertpiece( custom_ps_pixelData ) }; - #define SampleDetailWeightMap( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2D( tex, sampler, uv, arrayIdx ) + #define SampleDetailWeightMap( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2DF16( tex, sampler, uv, arrayIdx ) @foreach( detail_maps_diffuse, n ) - @property( detail_map@n )#define SampleDetailCol@n( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2D( tex, sampler, uv, arrayIdx )@end + @property( detail_map@n )#define SampleDetailCol@n( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2DF16( tex, sampler, uv, arrayIdx )@end @end @property( diffuse_map ) - #define SampleDiffuse( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2D( tex, sampler, uv, arrayIdx ) @property( diffuse_map_grayscale ).rrra@end + #define SampleDiffuse( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2DF16( tex, sampler, uv, arrayIdx ) @property( diffuse_map_grayscale ).rrra@end @end @property( specular_map ) - #define SampleSpecular( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2D( tex, sampler, uv, arrayIdx ) + #define SampleSpecular( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2DF16( tex, sampler, uv, arrayIdx ) @end @property( roughness_map ) - #define SampleRoughness( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2D( tex, sampler, uv, arrayIdx ) + #define SampleRoughness( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2DF16( tex, sampler, uv, arrayIdx ) @end @property( emissive_map ) - #define SampleEmissive( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2D( tex, sampler, uv, arrayIdx ) @property( emissive_map_grayscale ).rrr@end + #define SampleEmissive( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2DF16( tex, sampler, uv, arrayIdx ) @property( emissive_map_grayscale ).rrr@end @end @property( use_envprobe_map ) - #define SampleEnvProbe( tex, sampler, uv, lod ) OGRE_SampleLevel( tex, sampler, uv, lod ) + @property( syntax == metal ) + #define SampleEnvProbe( tex, sampler, uv, lod ) OGRE_SampleLevelF16( tex, sampler, float3( uv ), lod ) + @else + #define SampleEnvProbe( tex, sampler, uv, lod ) OGRE_SampleLevelF16( tex, sampler, uv, lod ) + @end @end @property( hlms_lights_spot_textured ) @@ -107,37 +122,37 @@ @end @property( normal_map_tex || detail_maps_normal ) - INLINE float3 reconstructZfromTSNormal( float2 tsNormal2 ) + INLINE midf3 reconstructZfromTSNormal( midf2 tsNormal2 ) { - float3 tsNormal; + midf3 tsNormal; tsNormal.xy = tsNormal2.xy; - tsNormal.z = sqrt( max( 0.0f, 1.0f - tsNormal.x * tsNormal.x - tsNormal.y * tsNormal.y ) ); + tsNormal.z = sqrt( max( _h(0.0f), _h(1.0f) - tsNormal.x * tsNormal.x - tsNormal.y * tsNormal.y ) ); return tsNormal.xyz; } @property( normal_sampling_format == normal_rg_snorm ) //Normal texture must be in UV8/RG8_SNORM or BC5S format! - #define getTSNormal( normalMap, samplerState, uv, normalIdx ) reconstructZfromTSNormal( OGRE_SampleArray2D( normalMap, samplerState, uv, normalIdx ).xy ) + #define getTSNormal( normalMap, samplerState, uv, normalIdx ) reconstructZfromTSNormal( OGRE_SampleArray2DF16( normalMap, samplerState, uv, normalIdx ).xy ) @end @property( normal_sampling_format == normal_rg_unorm ) //Normal texture must be in RG8_UNORM or similar format! - #define getTSNormal( normalMap, samplerState, uv, normalIdx ) reconstructZfromTSNormal( OGRE_SampleArray2D( normalMap, samplerState, uv, normalIdx ).xy * 2.0 - 1.0 ) + #define getTSNormal( normalMap, samplerState, uv, normalIdx ) reconstructZfromTSNormal( OGRE_SampleArray2DF16( normalMap, samplerState, uv, normalIdx ).xy * 2.0 - 1.0 ) @end @property( normal_sampling_format == normal_bc3_unorm ) //Normal texture must be in BC3 or similar format! - #define getTSNormal( normalMap, samplerState, uv, normalIdx ) reconstructZfromTSNormal( OGRE_SampleArray2D( normalMap, samplerState, uv, normalIdx ).yw * 2.0 - 1.0 ) + #define getTSNormal( normalMap, samplerState, uv, normalIdx ) reconstructZfromTSNormal( OGRE_SampleArray2DF16( normalMap, samplerState, uv, normalIdx ).yw * 2.0 - 1.0 ) @end @property( normal_sampling_format == normal_la ) //Normal texture must be in LA format! - #define getTSNormal( normalMap, samplerState, uv, normalIdx ) reconstructZfromTSNormal( OGRE_SampleArray2D( normalMap, samplerState, uv, normalIdx ).xw * 2.0 - 1.0 ) + #define getTSNormal( normalMap, samplerState, uv, normalIdx ) reconstructZfromTSNormal( OGRE_SampleArray2DF16( normalMap, samplerState, uv, normalIdx ).xw * 2.0 - 1.0 ) @end @end @property( obb_restraint_approx || obb_restraint_ltc ) /// Returns value in range [-inf; 1] /// Values <= 0 means 'pos' is outside the obb - float getObbRestraintFade( @property( syntax == metal )constant@end float4 obbRestraint[3], - float3 pos, float3 obbFadeFactors ) + midf getObbRestraintFade( @property( syntax == metal )constant@end float4 obbRestraint[3], + float3 pos, float3 obbFadeFactors ) { float3 obbDistToBounds; obbDistToBounds.x = dot( obbRestraint[0].xyzw, float4( pos.xyz, 1.0 ) ); @@ -147,7 +162,7 @@ obbDistToBounds = abs( obbDistToBounds ); float3 obbFade = (1.0 - obbDistToBounds) * obbFadeFactors; - return min( min3( obbFade.x, obbFade.y, obbFade.z ), 1.0 ); + return min( midf_c( min3( obbFade.x, obbFade.y, obbFade.z ) ), _h( 1.0 ) ); } @end @@ -229,16 +244,16 @@ @property( detail_maps_diffuse || detail_maps_normal ) //Prepare weight map for the detail maps. @property( detail_weight_map ) - float4 detailWeights = SampleDetailWeightMap( textureMaps@value(detail_weight_map_idx), + midf4 detailWeights = SampleDetailWeightMap( textureMaps@value(detail_weight_map_idx), samplerState@value(detail_weight_map_sampler), UV_DETAIL_WEIGHT( inPs.uv@value(uv_detail_weight).xy ), texIndex_weightMapIdx ); - @property( detail_weights )detailWeights *= material.cDetailWeights;@end + @property( detail_weights )detailWeights *= midf4_c( material.cDetailWeights );@end @else @property( detail_weights ) - float4 detailWeights = material.cDetailWeights; + midf4 detailWeights = midf4_c( material.cDetailWeights ); @else - float4 detailWeights = float4( 1.0, 1.0, 1.0, 1.0 ); + midf4 detailWeights = midf4_c( 1.0, 1.0, 1.0, 1.0 ); @end @end @end @@ -248,9 +263,9 @@ /// Sample detail maps and weight them against the weight map in the next foreach loop. @foreach( detail_maps_diffuse, n ) @property( detail_map@n ) - float4 detailCol@n = SampleDetailCol@n( textureMaps@value(detail_map@n_idx), + midf4 detailCol@n = SampleDetailCol@n@property( detail_triplanar_diffuse )Triplanar@end ( textureMaps@value(detail_map@n_idx), samplerState@value(detail_map@n_sampler), - UV_DETAIL@n( inPs.uv@value(uv_detail@n).xy@insertpiece( offsetDetail@n ) ), + UV_DETAIL@n( @property( detail_triplanar )GetTriplanarUVTp( inPs.worldPos, pixelData.worldSpaceNormal )@else inPs.uv@value(uv_detail@n).xy@end @insertpiece( offsetDetail@n ) ), texIndex_detailMapIdx@n ); detailWeights.@insertpiece(detail_swizzle@n) *= detailCol@n.w; detailCol@n.w = detailWeights.@insertpiece(detail_swizzle@n); @@ -267,7 +282,7 @@ texIndex_diffuseIdx ); @else /// If there are no diffuse maps, we must initialize it to some value. - pixelData.diffuse.xyzw = material.bgDiffuse.xyzw; + pixelData.diffuse.xyzw = midf4_c( material.bgDiffuse.xyzw ); @end /// Blend the detail diffuse maps with the main diffuse. @@ -275,7 +290,7 @@ @insertpiece( blend_mode_idx@n ) @add( t, 1 ) @end /// Apply the material's diffuse over the textures - pixelData.diffuse.xyz *= material.kD.xyz; + pixelData.diffuse.xyz *= midf3_c( material.kD.xyz ); @property( transparent_mode || hlms_screen_space_refractions ) pixelData.diffuse.xyz *= (pixelData.diffuse.w * pixelData.diffuse.w); @end @@ -288,9 +303,9 @@ @piece( SampleSpecularMap ) /// SPECUlAR MAP - pixelData.specular.xyz = material.kS.xyz; + pixelData.specular.xyz = midf3_c( material.kS.xyz ); @property( !metallic_workflow ) - pixelData.F0 = material.F0.@insertpiece( FresnelSwizzle ); + pixelData.F0 = float_fresnel_c( material.F0.@insertpiece( FresnelSwizzle ) ); @property( specular_map && !fresnel_workflow ) pixelData.specular.xyz *= SampleSpecular( textureMaps@value( specular_map_idx ), samplerState@value(specular_map_sampler), @@ -304,17 +319,17 @@ texIndex_specularIdx ).@insertpiece( FresnelSwizzle ); @end @else - float metalness = material.F0.x; + midf metalness = midf_c( material.F0.x ); @property( specular_map ) metalness *= SampleSpecular( textureMaps@value( specular_map_idx ), samplerState@value(specular_map_sampler), UV_SPECULAR( inPs.uv@value(uv_specular).xy ), texIndex_specularIdx ).x; @end - pixelData.F0 = lerp( make_float_fresnel( 0.03f ), pixelData.diffuse.xyz * 3.14159f, metalness ); + pixelData.F0 = lerp( make_float_fresnel( 0.04f ), pixelData.diffuse.xyz * _h( 3.14159f ), metalness ); pixelData.diffuse.xyz = pixelData.diffuse.xyz - pixelData.diffuse.xyz * metalness; @property( hlms_alphablend || hlms_screen_space_refractions ) - pixelData.F0 *= material.F0.w; ///Should this be done for non-metallic as well??? + pixelData.F0 *= midf_c( material.F0.w ); ///Should this be done for non-metallic as well??? @end @end @property( transparent_mode || hlms_screen_space_refractions ) @@ -324,7 +339,7 @@ @piece( SampleRoughnessMap ) /// ROUGHNESS MAP - pixelData.perceptualRoughness = material.kS.w; + pixelData.perceptualRoughness = midf_c( material.kS.w ); @property( roughness_map ) pixelData.perceptualRoughness *= SampleRoughness( textureMaps@value( roughness_map_idx ), @@ -343,9 +358,9 @@ @end @property( perceptual_roughness ) - pixelData.roughness = max( pixelData.perceptualRoughness * pixelData.perceptualRoughness, 0.001f ); + pixelData.roughness = max( pixelData.perceptualRoughness * pixelData.perceptualRoughness, _h( 0.001f ) ); @else - pixelData.roughness = max( pixelData.perceptualRoughness, 0.001f ); + pixelData.roughness = max( pixelData.perceptualRoughness, _h( 0.001f ) ); @end @end @@ -363,15 +378,15 @@ @else //Normal mapping. pixelData.geomNormal = normalize( inPs.normal ) @insertpiece( two_sided_flip_normal ); - float3 vTangent = normalize( inPs.tangent ); + midf3 vTangent = normalize( inPs.tangent ); @property( hlms_qtangent || hlms_tangent4 ) @piece( tbnApplyReflection ) * inPs.biNormalReflection@end @end //Get the TBN matrix - float3 vBinormal = normalize( cross( pixelData.geomNormal, vTangent )@insertpiece( tbnApplyReflection ) ); - float3x3 TBN = buildFloat3x3( vTangent, vBinormal, pixelData.geomNormal ); + midf3 vBinormal = normalize( cross( pixelData.geomNormal, vTangent )@insertpiece( tbnApplyReflection ) ); + midf3x3 TBN = buildMidf3x3( vTangent, vBinormal, pixelData.geomNormal ); @property( normal_map_tex ) pixelData.normal = getTSNormal( textureMaps@value( normal_map_tex_idx ), @@ -379,11 +394,11 @@ UV_NORMAL( inPs.uv@value(uv_normal).xy ), texIndex_normalIdx ); @else - pixelData.normal = float3( 0.0, 0.0, 1.0 ); + pixelData.normal = midf3_c( 0.0, 0.0, 1.0 ); @end @property( normal_weight_tex ) // Apply the weight to the main normal map - pixelData.normal = lerp( float3( 0.0, 0.0, 1.0 ), pixelData.normal, normalMapWeight ); + pixelData.normal = lerp( midf3_c( 0.0, 0.0, 1.0 ), pixelData.normal, normalMapWeight ); @end @end @end @@ -402,7 +417,7 @@ @property( detail_maps_normal ) @foreach( 4, n ) @property( normal_weight_detail@n ) - @piece( detail@n_nm_weight_mul ) * material.normalWeights.@insertpiece( detail_swizzle@n )@end + @piece( detail@n_nm_weight_mul ) * midf_c( material.normalWeights.@insertpiece( detail_swizzle@n ) )@end @end @end @end @@ -410,7 +425,7 @@ @foreach( detail_maps_normal, n ) @piece( SampleDetailMapNm@n )getTSNormal( textureMaps@value(detail_map_nm@n_idx), samplerState@value(detail_map_nm@n_sampler), - UV_DETAIL_NM@n( inPs.uv@value(uv_detail_nm@n).xy@insertpiece( offsetDetail@n ) ), + UV_DETAIL_NM@n( @property( detail_triplanar )GetTriplanarUVTp( inPs.worldPos, pixelData.worldSpaceNormal )@else inPs.uv@value(uv_detail_nm@n).xy@end @insertpiece( offsetDetail@n ) ), texIndex_detailNormMapIdx@n ) * detailWeights.@insertpiece(detail_swizzle@n) @insertpiece( detail@n_nm_weight_mul )@end @end @@ -433,30 +448,53 @@ //Everything's in Camera space @property( needs_view_dir ) @property( !hlms_instanced_stereo ) - pixelData.viewDir = normalize( -inPs.pos ); + pixelData.viewDir = midf3_c( normalize( -inPs.pos ) ); @else - pixelData.viewDir = -inPs.pos; if( gl_FragCoord.x > passBuf.rightEyePixelStartX ) - pixelData.viewDir += passBuf.leftToRightView.xyz; - pixelData.viewDir = normalize( pixelData.viewDir ); + pixelData.viewDir = midf3_c( normalize( -inPs.pos + passBuf.leftToRightView.xyz ) ); + else + pixelData.viewDir = midf3_c( normalize( -inPs.pos ) ); @end pixelData.NdotV = saturate( dot( pixelData.normal, pixelData.viewDir ) ); @end @property( !ambient_fixed || vct_num_probes ) - float3 finalColour = float3(0, 0, 0); + midf3 finalColour = midf3_c(0, 0, 0); @else - float3 finalColour = passBuf.ambientUpperHemi.xyz * pixelData.diffuse.xyz; + midf3 finalColour = midf3_c( passBuf.ambientUpperHemi.xyz ) * pixelData.diffuse.xyz; @end - @property( hlms_lights_point || hlms_lights_spot || hlms_lights_area_approx || hlms_lights_area_ltc ) + @property( hlms_static_branch_shadow_map_lights || hlms_lights_point || hlms_lights_spot || hlms_lights_area_approx || hlms_lights_area_ltc ) float3 lightDir; float fDistance; - float3 tmpColour; - float spotCosAngle; + midf3 tmpColour; + midf spotCosAngle; + @end + + @property( hlms_static_branch_shadow_map_lights ) + const float2 shadowmap_uv_min[@value(hlms_num_shadow_map_lights)] = + OGRE_ARRAY_START( float2 ) + hlms_shadowmap0_uv_min + @foreach( hlms_num_shadow_map_lights, n, 1 ) + , hlms_shadowmap@n_uv_min@end + OGRE_ARRAY_END; + const float2 shadowmap_uv_max[@value(hlms_num_shadow_map_lights)] = + OGRE_ARRAY_START( float2 ) + hlms_shadowmap0_uv_max + @foreach( hlms_num_shadow_map_lights, n, 1 ) + , hlms_shadowmap@n_uv_max@end + OGRE_ARRAY_END; + const float2 shadowmap_uv_length[@value(hlms_num_shadow_map_lights)] = + OGRE_ARRAY_START( float2 ) + hlms_shadowmap0_uv_length + @foreach( hlms_num_shadow_map_lights, n, 1 ) + , hlms_shadowmap@n_uv_length@end + OGRE_ARRAY_END; @end + @property( needs_refl_dir ) - pixelData.reflDir = 2.0 * dot( pixelData.viewDir, pixelData.normal ) * pixelData.normal - pixelData.viewDir; + pixelData.reflDir = _h( 2.0 ) * dot( pixelData.viewDir, pixelData.normal ) * pixelData.normal - + pixelData.viewDir; @end @insertpiece( DoAmbientHeader ) @@ -465,22 +503,30 @@ @piece( DoDirectionalLights ) @property( hlms_lights_directional ) @insertpiece( ObjLightMaskCmp ) - finalColour += BRDF( light0Buf.lights[0].position.xyz, light0Buf.lights[0].diffuse.xyz, light0Buf.lights[0].specular, pixelData ) @insertpiece( DarkenWithShadowFirstLight ); + finalColour += BRDF( midf3_c( light0Buf.lights[0].position.xyz ), + midf3_c( light0Buf.lights[0].diffuse.xyz ), + midf3_c( light0Buf.lights[0].specular ), pixelData PASSBUF_ARG ) @insertpiece( DarkenWithShadowFirstLight ); @end @foreach( hlms_lights_directional, n, 1 ) @insertpiece( ObjLightMaskCmp ) - finalColour += BRDF( light0Buf.lights[@n].position.xyz, light0Buf.lights[@n].diffuse.xyz, light0Buf.lights[@n].specular, pixelData )@insertpiece( DarkenWithShadow );@end + finalColour += BRDF( midf3_c( light0Buf.lights[@n].position.xyz ), + midf3_c( light0Buf.lights[@n].diffuse.xyz ), + midf3_c( light0Buf.lights[@n].specular ), pixelData PASSBUF_ARG )@insertpiece( DarkenWithShadow );@end @property( !hlms_static_branch_lights ) @foreach( hlms_lights_directional_non_caster, n, hlms_lights_directional ) @insertpiece( ObjLightMaskCmp ) - finalColour += BRDF( light0Buf.lights[@n].position.xyz, light0Buf.lights[@n].diffuse.xyz, light0Buf.lights[@n].specular, pixelData );@end + finalColour += BRDF( midf3_c( light0Buf.lights[@n].position.xyz ), + midf3_c( light0Buf.lights[@n].diffuse.xyz ), + midf3_c( light0Buf.lights[@n].specular ), pixelData PASSBUF_ARG );@end @else for( int n=0; n= light0Buf.lights[light_idx].spotParams.y @insertpiece( andObjLightMaskCmp_light_idx ) ) + { + midf spotAtten = saturate( (spotCosAngle - midf_c( light0Buf.lights[light_idx].spotParams.y )) * midf_c( light0Buf.lights[light_idx].spotParams.x ) ); + spotAtten = pow( spotAtten, midf_c( light0Buf.lights[light_idx].spotParams.z ) ); + + @property( light_profiles_texture ) + spotAtten *= getPhotometricAttenuation( spotCosAngle, + light0Buf.lights[light_idx].lightTexProfileIdx + OGRE_PHOTOMETRIC_ARG ); + @end + + tmpColour = BRDF( midf3_c( lightDir ), midf3_c( light0Buf.lights[light_idx].diffuse.xyz ), + midf3_c( light0Buf.lights[light_idx].specular ), + pixelData PASSBUF_ARG )@insertpiece( DarkenWithShadow_cur_shadow_map ); + midf atten = midf_c( 1.0 / (0.5 + (light0Buf.lights[light_idx].attenuation.y + light0Buf.lights[light_idx].attenuation.z * fDistance) * fDistance ) ); + finalColour += tmpColour * (atten * spotAtten); + } + cur_shadow_map++; + } +@else @foreach( hlms_lights_spot, n, hlms_lights_point ) lightDir = light0Buf.lights[@n].position.xyz - inPs.pos; fDistance= length( lightDir ); lightDir *= 1.0 / fDistance; @property( !hlms_lights_spot_textured ) - spotCosAngle = dot( -lightDir, light0Buf.lights[@n].spotDirection.xyz ); + spotCosAngle = dot( midf3_c( -lightDir ), midf3_c( light0Buf.lights[@n].spotDirection.xyz ) ); @else - spotCosAngle = dot( -lightDir, zAxis( light0Buf.lights[@n].spotQuaternion ) ); + spotCosAngle = dot( midf3_c( -lightDir ), zAxis( midf4_c( light0Buf.lights[@n].spotQuaternion ) ) ); @end if( fDistance <= light0Buf.lights[@n].attenuation.x && spotCosAngle >= light0Buf.lights[@n].spotParams.y @insertpiece( andObjLightMaskCmp ) ) { @property( hlms_lights_spot_textured ) float3 posInLightSpace = qmul( spotQuaternion[@value(spot_params)], inPs.pos ); - float spotAtten = texture( texSpotLight, normalize( posInLightSpace ).xy ).x; //TODO + midf spotAtten = texture( texSpotLight, normalize( posInLightSpace ).xy ).x; //TODO @else - float spotAtten = saturate( (spotCosAngle - light0Buf.lights[@n].spotParams.y) * light0Buf.lights[@n].spotParams.x ); - spotAtten = pow( spotAtten, light0Buf.lights[@n].spotParams.z ); + midf spotAtten = saturate( (spotCosAngle - midf_c( light0Buf.lights[@n].spotParams.y )) * midf_c( light0Buf.lights[@n].spotParams.x ) ); + spotAtten = pow( spotAtten, midf_c( light0Buf.lights[@n].spotParams.z ) ); @end @property( light_profiles_texture ) @@ -532,68 +631,71 @@ OGRE_PHOTOMETRIC_ARG ); @end - tmpColour = BRDF( lightDir, light0Buf.lights[@n].diffuse.xyz, light0Buf.lights[@n].specular, pixelData )@insertpiece( DarkenWithShadow ); - float atten = 1.0 / (0.5 + (light0Buf.lights[@n].attenuation.y + light0Buf.lights[@n].attenuation.z * fDistance) * fDistance ); + tmpColour = BRDF( midf3_c( lightDir ), midf3_c( light0Buf.lights[@n].diffuse.xyz ), + midf3_c( light0Buf.lights[@n].specular ), + pixelData PASSBUF_ARG )@insertpiece( DarkenWithShadow ); + midf atten = midf_c( 1.0 / (0.5 + (light0Buf.lights[@n].attenuation.y + light0Buf.lights[@n].attenuation.z * fDistance) * fDistance ) ); finalColour += tmpColour * (atten * spotAtten); } @end @end +@end @piece( DoEmissiveLight ) @property( emissive_map || emissive_constant ) ///Emissive is not part of PixelData because emissive can just be accumulated to finalColour @property( emissive_map ) - float3 emissiveCol = SampleEmissive( textureMaps@value( emissive_map_idx ), - samplerState@value(emissive_map_sampler), - UV_EMISSIVE( inPs.uv@value(uv_emissive).xy ), - texIndex_emissiveMapIdx ).xyz; + midf3 emissiveCol = SampleEmissive( textureMaps@value( emissive_map_idx ), + samplerState@value(emissive_map_sampler), + UV_EMISSIVE( inPs.uv@value(uv_emissive).xy ), + texIndex_emissiveMapIdx ).xyz; @property( emissive_constant ) - emissiveCol *= material.emissive.xyz; + emissiveCol *= midf3_c( material.emissive.xyz ); @end @property( emissive_as_lightmap ) emissiveCol *= pixelData.diffuse.xyz; @end finalColour += emissiveCol; @else - finalColour += material.emissive.xyz; + finalColour += midf3_c( material.emissive.xyz ); @end @end @end @piece( CubemapManualPcc ) - float3 posInProbSpace = toProbeLocalSpace( inPs.pos, @insertpiece( pccProbeSource ) ); - float probeFade = getProbeFade( posInProbSpace, @insertpiece( pccProbeSource ) ); + midf3 posInProbSpace = midf3_c( toProbeLocalSpace( inPs.pos, @insertpiece( pccProbeSource ) ) ); + midf probeFade = getProbeFade( posInProbSpace, @insertpiece( pccProbeSource ) ); @property( vct_num_probes ) - if( probeFade > 0 && (pixelData.roughness < 1.0f || vctSpecular.w == 0) ) + if( probeFade > _h( 0 ) && (pixelData.roughness < _h( 1.0f ) || vctSpecular.w == 0) ) @else - if( probeFade > 0 ) + if( probeFade > _h( 0 ) ) @end { - probeFade = saturate( probeFade * 200.0 ); + probeFade = saturate( probeFade * _h( 200.0 ) ); @property( vct_num_probes ) - float4 reflDirLS_dist = localCorrect( pixelData.reflDir, posInProbSpace, @insertpiece( pccProbeSource ) ); - float3 reflDirLS = reflDirLS_dist.xyz; + midf4 reflDirLS_dist = localCorrect( pixelData.reflDir, posInProbSpace, @insertpiece( pccProbeSource ) ); + midf3 reflDirLS = reflDirLS_dist.xyz; @else - float3 reflDirLS = localCorrect( pixelData.reflDir, posInProbSpace, @insertpiece( pccProbeSource ) ).xyz; + midf3 reflDirLS = localCorrect( pixelData.reflDir, posInProbSpace, @insertpiece( pccProbeSource ) ).xyz; @end - float3 nNormalLS = localCorrect( pixelData.normal, posInProbSpace, @insertpiece( pccProbeSource ) ).xyz; - float4 envS = SampleEnvProbe( texEnvProbeMap, samplerState@value(envMapRegSampler), - reflDirLS, @insertpiece( envSpecularRoughness ) ); + midf3 nNormalLS = localCorrect( pixelData.normal, posInProbSpace, @insertpiece( pccProbeSource ) ).xyz; + midf4 envS = SampleEnvProbe( texEnvProbeMap, samplerState@value(envMapRegSampler), + reflDirLS, @insertpiece( envSpecularRoughness ) ); @property( envmap_scale ) - envS.xyz *= passBuf.ambientUpperHemi.w; + envS.xyz *= midf3_c( passBuf.ambientUpperHemi.w ); @end @property( cubemaps_as_diffuse_gi ) - float3 envD = SampleEnvProbe( texEnvProbeMap, samplerState@value(envMapRegSampler), - nNormalLS, 11.0 ).xyz @insertpiece( ApplyEnvMapScale ); + midf3 envD = SampleEnvProbe( texEnvProbeMap, samplerState@value(envMapRegSampler), + nNormalLS, 11.0 ).xyz @insertpiece( ApplyEnvMapScale ); envD.xyz *= probeFade; @end envS.xyz *= probeFade; @property( clear_coat ) - float3 clearCoatEnvS = SampleEnvProbe( texEnvProbeMap, samplerState@value( envMapRegSampler ), - reflDirLS, - @insertpiece( envSpecularRoughnessClearCoat ) ).xyz @insertpiece( ApplyEnvMapScale ); + midf3 clearCoatEnvS = SampleEnvProbe( texEnvProbeMap, samplerState@value( envMapRegSampler ), + reflDirLS, + @insertpiece( envSpecularRoughnessClearCoat ) ).xyz @insertpiece( ApplyEnvMapScale ); clearCoatEnvS *= probeFade; @end @@ -608,7 +710,7 @@ pixelData.envColourS = lerp( envS.xyz, pixelData.envColourS, vctLerp ); @property( cubemaps_as_diffuse_gi ) - pixelData.envColourD += vctSpecular.w > 0 ? float3( 0, 0, 0 ) : envD; + pixelData.envColourD += vctSpecular.w > 0 ? midf3_c( 0, 0, 0 ) : envD; @end @property( clear_coat ) @@ -629,23 +731,30 @@ @piece( CubemapGlobal ) pixelData.envColourS += SampleEnvProbe( texEnvProbeMap, samplerState@value(envMapRegSampler), - mul( pixelData.reflDir, passBuf.invViewMatCubemap ), + mul( pixelData.reflDir, midf3x3_c( passBuf.invViewMatCubemap ) ), @insertpiece( envSpecularRoughness ) ).xyz @insertpiece( ApplyEnvMapScale ); @property( cubemaps_as_diffuse_gi ) pixelData.envColourD += SampleEnvProbe( texEnvProbeMap, samplerState@value(envMapRegSampler), - mul( pixelData.normal, passBuf.invViewMatCubemap ), + mul( pixelData.normal, midf3x3_c( passBuf.invViewMatCubemap ) ), 11.0 ).xyz @insertpiece( ApplyEnvMapScale ); @end @property( clear_coat ) pixelData.clearCoatEnvColourS += SampleEnvProbe( texEnvProbeMap, samplerState@value( envMapRegSampler ), - mul( pixelData.reflDir, passBuf.invViewMatCubemap ), + mul( pixelData.reflDir, midf3x3_c( passBuf.invViewMatCubemap ) ), @insertpiece( envSpecularRoughnessClearCoat ) ).xyz @insertpiece( ApplyEnvMapScale ); @end @end @property( !hlms_shadowcaster ) @piece( DefaultBodyPS ) + @property( hlms_emulate_clip_distances && hlms_global_clip_planes && hlms_pso_clip_distances && syntax == glslvk ) + @foreach( hlms_pso_clip_distances, n ) + if( inPs.clipDistance@n < 0.0 ) + discard; + @end + @end + @property( hlms_screen_pos_uv ) float2 screenPosUv = gl_FragCoord.xy * passBuf.invWindowRes.xy; @end @@ -732,17 +841,17 @@ int gBufSubsample = int( findLSB( sampleMask ) ); - pixelData.normal = normalize( OGRE_Load2DMS( gBuf_normals, iFragCoord, gBufSubsample ).xyz * 2.0 - 1.0 ); - float2 shadowRoughness = OGRE_Load2DMS( gBuf_shadowRoughness, iFragCoord, gBufSubsample ).xy; + pixelData.normal = normalize( OGRE_Load2DMSF16( gBuf_normals, iFragCoord, gBufSubsample ).xyz * _h( 2.0 ) - _h( 1.0 ) ); + midf2 shadowRoughness = OGRE_Load2DMSF16( gBuf_shadowRoughness, iFragCoord, gBufSubsample ).xy; @else - pixelData.normal = normalize( OGRE_Load2D( gBuf_normals, iFragCoord, 0 ).xyz * 2.0 - 1.0 ); - float2 shadowRoughness = OGRE_Load2D( gBuf_shadowRoughness, iFragCoord, 0 ).xy; + pixelData.normal = normalize( OGRE_Load2DF16( gBuf_normals, iFragCoord, 0 ).xyz * _h( 2.0 ) - _h( 1.0 ) ); + midf2 shadowRoughness = OGRE_Load2DF16( gBuf_shadowRoughness, iFragCoord, 0 ).xy; @end - float fShadow = shadowRoughness.x; + midf fShadow = shadowRoughness.x; @property( roughness_map ) - pixelData.roughness = shadowRoughness.y * 0.98 + 0.02; + pixelData.roughness = shadowRoughness.y * _h( 0.98 ) + _h( 0.02 ); @end @end @@ -764,11 +873,11 @@ @insertpiece( forward3dLighting ) @property( needs_env_brdf ) - pixelData.envColourS = float3( 0, 0, 0 ); - pixelData.envColourD = float3( 0, 0, 0 ); + pixelData.envColourS = midf3_c( 0, 0, 0 ); + pixelData.envColourD = midf3_c( 0, 0, 0 ); @property( clear_coat ) - pixelData.clearCoatEnvColourS = float3( 0, 0, 0 ); + pixelData.clearCoatEnvColourS = midf3_c( 0, 0, 0 ); @end @end @@ -807,6 +916,18 @@ @end @insertpiece( applyRefractions ) + + @property( hlms_fog ) + const float distToCamera = length( inPs.pos.xyz ); + const midf luminance = dot( finalColour.xyz, + midf3_c( _h( 0.212655 ), _h( 0.715158 ), _h( 0.072187 ) ) ); + const midf lumFogWeight = max( exp2( atmoSettings.fogBreakFalloff * luminance + + atmoSettings.fogBreakMinBrightness ), + _h( 0.0 ) ); + midf fogWeight = midf_c( exp2( -distToCamera * atmoSettings.fogDensity ) ); + fogWeight = lerp( _h( 1.0 ), fogWeight, lumFogWeight ); + finalColour.xyz = lerp( inPs.fog.xyz, finalColour.xyz, fogWeight ); + @end @end ///!hlms_prepass @end ///!hlms_normal || hlms_qtangent @@ -823,32 +944,32 @@ @property( hlms_alphablend || hlms_alpha_to_coverage ) @property( use_texture_alpha ) - outPs_colour0.w = material.F0.w * pixelData.diffuse.w; + outPs_colour0.w = midf_c( material.F0.w ) * pixelData.diffuse.w; @else - outPs_colour0.w = material.F0.w; + outPs_colour0.w = midf_c( material.F0.w ); @end @else - outPs_colour0.w = 1.0; + outPs_colour0.w = _h( 1.0 ); @end @property( debug_pssm_splits ) - outPs_colour0.xyz = mix( outPs_colour0.xyz, debugPssmSplit.xyz, 0.2f ); + outPs_colour0.xyz = lerp( outPs_colour0.xyz, debugPssmSplit.xyz, _h( 0.2f ) ); @end @property( hlms_gen_normals_gbuffer ) - outPs_normals = float4( pixelData.normal * 0.5 + 0.5, 1.0 ); + outPs_normals = midf4_c( pixelData.normal * _h( 0.5 ) + _h( 0.5 ), 1.0 ); @end @else - outPs_colour0 = float4( 1.0, 1.0, 1.0, 1.0 ); + outPs_colour0 = midf4_c( 1.0, 1.0, 1.0, 1.0 ); @property( hlms_gen_normals_gbuffer ) - outPs_normals = float4( 0.5, 0.5, 1.0, 1.0 ); + outPs_normals = midf4_c( 0.5, 0.5, 1.0, 1.0 ); @end @end @else - outPs_normals = float4( pixelData.normal * 0.5 + 0.5, 1.0 ); + outPs_normals = midf4_c( pixelData.normal * _h( 0.5 ) + _h( 0.5 ), 1.0 ); @property( hlms_pssm_splits ) - outPs_shadowRoughness = float2( fShadow, (pixelData.roughness - 0.02) * 1.02040816 ); + outPs_shadowRoughness = midf2_c( fShadow, (pixelData.roughness - 0.02) * 1.02040816 ); @end @property( !hlms_pssm_splits ) - outPs_shadowRoughness = float2( 1.0, (pixelData.roughness - 0.02) * 1.02040816 ); + outPs_shadowRoughness = midf2_c( 1.0, (pixelData.roughness - 0.02) * 1.02040816 ); @end @end @end diff --git a/ogre2/src/media/Hlms/Pbs/Any/Main/800.VertexShader_piece_vs.any b/ogre2/src/media/Hlms/Pbs/Any/Main/800.VertexShader_piece_vs.any index 4e0f17728..1016983eb 100644 --- a/ogre2/src/media/Hlms/Pbs/Any/Main/800.VertexShader_piece_vs.any +++ b/ogre2/src/media/Hlms/Pbs/Any/Main/800.VertexShader_piece_vs.any @@ -13,7 +13,8 @@ // START UNIFORM DECLARATION @insertpiece( PassStructDecl ) - @property( hlms_skeleton || hlms_shadowcaster || hlms_pose )@insertpiece( InstanceStructDecl )@end + @property( hlms_skeleton || hlms_shadowcaster || hlms_pose || syntax == metal || lower_gpu_overhead )@insertpiece( InstanceStructDecl )@end + @insertpiece( AtmosphereNprSkyStructDecl ) @insertpiece( custom_vs_uniformStructDeclaration ) // END UNIFORM DECLARATION @@ -25,6 +26,24 @@ @end @insertpiece( DeclShadowMapMacros ) + @insertpiece( DeclAtmosphereNprSkyFuncs ) + + @property( accurate_non_uniform_scaled_normals ) + midf3x3 adjugate( midf3x3 m ) + { + midf3x3 n; + n[0][0] = m[1][1] * m[2][2] - m[1][2] * m[2][1]; + n[0][1] = m[0][2] * m[2][1] - m[0][1] * m[2][2]; + n[0][2] = m[0][1] * m[1][2] - m[0][2] * m[1][1]; + n[1][0] = m[1][2] * m[2][0] - m[1][0] * m[2][2]; + n[1][1] = m[0][0] * m[2][2] - m[0][2] * m[2][0]; + n[1][2] = m[0][2] * m[1][0] - m[0][0] * m[1][2]; + n[2][0] = m[1][0] * m[2][1] - m[2][0] * m[1][1]; + n[2][1] = m[0][1] * m[2][0] - m[0][0] * m[2][1]; + n[2][2] = m[0][0] * m[1][1] - m[0][1] * m[1][0]; + return n; + } + @end @end @property( !hlms_skeleton ) @@ -51,45 +70,46 @@ worldPos.z = dot( worldMat[2], inputPos ); worldPos.xyz *= inVs_blendWeights[0]; @property( hlms_normal || hlms_qtangent ) - float3 worldNorm; - worldNorm.x = dot( worldMat[0].xyz, inputNormal ); - worldNorm.y = dot( worldMat[1].xyz, inputNormal ); - worldNorm.z = dot( worldMat[2].xyz, inputNormal ); - worldNorm *= inVs_blendWeights[0]; + midf3 worldNorm; + worldNorm.x = dot( midf3_c( worldMat[0].xyz ), inputNormal ); + worldNorm.y = dot( midf3_c( worldMat[1].xyz ), inputNormal ); + worldNorm.z = dot( midf3_c( worldMat[2].xyz ), inputNormal ); + worldNorm *= midf_c( inVs_blendWeights[0] ); @end @property( normal_map ) - float3 worldTang; - worldTang.x = dot( worldMat[0].xyz, inputTangent ); - worldTang.y = dot( worldMat[1].xyz, inputTangent ); - worldTang.z = dot( worldMat[2].xyz, inputTangent ); - worldTang *= inVs_blendWeights[0]; + midf3 worldTang; + worldTang.x = dot( midf3_c( worldMat[0].xyz ), inputTangent ); + worldTang.y = dot( midf3_c( worldMat[1].xyz ), inputTangent ); + worldTang.z = dot( midf3_c( worldMat[2].xyz ), inputTangent ); + worldTang *= midf_c( inVs_blendWeights[0] ); @end @psub( NeedsMoreThan1BonePerVertex, hlms_bones_per_vertex, 1 ) @property( NeedsMoreThan1BonePerVertex ) - float4 tmp; - tmp.w = 1.0; + float4 tmp4; + tmp4.w = 1.0; + midf3 tmp3; @end //!NeedsMoreThan1BonePerVertex @foreach( hlms_bones_per_vertex, n, 1 ) _idx = (inVs_blendIndices[@n] << 1u) + inVs_blendIndices[@n]; //inVs_blendIndices[@n] * 3; a 32-bit int multiply is 4 cycles on GCN! (and mul24 is not exposed to GLSL...) worldMat[0] = readOnlyFetch( worldMatBuf, int(matStart + _idx + 0u) ); worldMat[1] = readOnlyFetch( worldMatBuf, int(matStart + _idx + 1u) ); worldMat[2] = readOnlyFetch( worldMatBuf, int(matStart + _idx + 2u) ); - tmp.x = dot( worldMat[0], inputPos ); - tmp.y = dot( worldMat[1], inputPos ); - tmp.z = dot( worldMat[2], inputPos ); - worldPos.xyz += (tmp * inVs_blendWeights[@n]).xyz; + tmp4.x = dot( worldMat[0], inputPos ); + tmp4.y = dot( worldMat[1], inputPos ); + tmp4.z = dot( worldMat[2], inputPos ); + worldPos.xyz += (tmp4 * inVs_blendWeights[@n]).xyz; @property( hlms_normal || hlms_qtangent ) - tmp.x = dot( worldMat[0].xyz, inputNormal ); - tmp.y = dot( worldMat[1].xyz, inputNormal ); - tmp.z = dot( worldMat[2].xyz, inputNormal ); - worldNorm += tmp.xyz * inVs_blendWeights[@n]; + tmp3.x = dot( midf3_c( worldMat[0].xyz ), inputNormal ); + tmp3.y = dot( midf3_c( worldMat[1].xyz ), inputNormal ); + tmp3.z = dot( midf3_c( worldMat[2].xyz ), inputNormal ); + worldNorm += tmp3.xyz * midf_c( inVs_blendWeights[@n] ); @end @property( normal_map ) - tmp.x = dot( worldMat[0].xyz, inputTangent ); - tmp.y = dot( worldMat[1].xyz, inputTangent ); - tmp.z = dot( worldMat[2].xyz, inputTangent ); - worldTang += tmp.xyz * inVs_blendWeights[@n]; + tmp3.x = dot( midf3_c( worldMat[0].xyz ), inputTangent ); + tmp3.y = dot( midf3_c( worldMat[1].xyz ), inputTangent ); + tmp3.z = dot( midf3_c( worldMat[2].xyz ), inputTangent ); + worldTang += tmp3.xyz * midf_c( inVs_blendWeights[@n] ); @end @end @@ -116,10 +136,10 @@ @psub( MoreThanOnePose, hlms_pose, 1 ) @property( !MoreThanOnePose ) float4 poseWeights = readOnlyFetch( worldMatBuf, int(poseDataStart + 1u) ); - float4 posePos = bufferFetch( poseBuf, int( vertexID @property( hlms_pose_normals )<< 1u@end ) ); + float4 posePos = float4( bufferFetch( poseBuf, int( vertexID @property( hlms_pose_normals )<< 1u@end ) ) ); inputPos += posePos * poseWeights.x; @property( hlms_pose_normals && (hlms_normal || hlms_qtangent) ) - float4 poseNormal = bufferFetch( poseBuf, int( (vertexID << 1u) + 1u ) ); + float4 poseNormal = float4( bufferFetch( poseBuf, int( (vertexID << 1u) + 1u ) ) ); inputNormal += poseNormal.xyz * poseWeights.x; @end @pset( NumPoseWeightVectors, 1 ) @@ -135,9 +155,9 @@ @property( !MoreThanOnePoseWeightVector ) float4 poseWeights = readOnlyFetch( worldMatBuf, int( poseDataStart + 1u ) ); @foreach( hlms_pose, n ) - inputPos += bufferFetch( poseBuf, int( (vertexID + numVertices * @nu) @property( hlms_pose_normals )<< 1u@end ) ) * poseWeights[@n]; + inputPos += float4( bufferFetch( poseBuf, int( (vertexID + numVertices * @nu) @property( hlms_pose_normals )<< 1u@end ) ) ) * poseWeights[@n]; @property( hlms_pose_normals && (hlms_normal || hlms_qtangent) ) - inputNormal += bufferFetch( poseBuf, int( ((vertexID + numVertices * @nu) << 1u) + 1u ) ).xyz * poseWeights[@n]; + inputNormal += midf3_c( bufferFetch( poseBuf, int( ((vertexID + numVertices * @nu) << 1u) + 1u ) ).xyz * poseWeights[@n] ); @end @end @else @@ -150,9 +170,9 @@ poseWeights[@n * 4 + 3] = weights@n[3]; @end @foreach( hlms_pose, n ) - inputPos += bufferFetch( poseBuf, int( (vertexID + numVertices * @nu) @property( hlms_pose_normals )<< 1u@end ) ) * poseWeights[@n]; + inputPos += float4( bufferFetch( poseBuf, int( (vertexID + numVertices * @nu) @property( hlms_pose_normals )<< 1u@end ) ) ) * poseWeights[@n]; @property( hlms_pose_normals && (hlms_normal || hlms_qtangent) ) - inputNormal += bufferFetch( poseBuf, int( ((vertexID + numVertices * @nu) << 1u) + 1u ) ).xyz * poseWeights[@nu]; + inputNormal += midf3_c( bufferFetch( poseBuf, int( ((vertexID + numVertices * @nu) << 1u) + 1u ) ).xyz * poseWeights[@nu] ); @end @end @end @@ -190,8 +210,16 @@ @insertpiece( custom_vs_preTransform ) //Lighting is in view space @property( hlms_normal || hlms_qtangent ) outVs.pos = @insertpiece( CalculatePsPos );@end - @property( hlms_normal || hlms_qtangent ) outVs.normal = mul( @insertpiece(local_normal), toFloat3x3( worldViewMat ) );@end - @property( normal_map ) outVs.tangent = mul( @insertpiece(local_tangent), toFloat3x3( worldViewMat ) );@end + @property( hlms_normal || hlms_qtangent ) + midf3x3 worldMat3x3 = toMidf3x3( worldViewMat ); + @property( accurate_non_uniform_scaled_normals ) + midf3x3 normalMat = transpose( adjugate( worldMat3x3 ) ); + outVs.normal = normalize( mul( @insertpiece(local_normal), normalMat ) ); + @else + outVs.normal = mul( @insertpiece(local_normal), worldMat3x3 ); + @end + @end + @property( normal_map ) outVs.tangent = mul( @insertpiece(local_tangent), toMidf3x3( worldViewMat ) );@end @property( !hlms_dual_paraboloid_mapping ) @property( !hlms_use_uv_baking ) @property( !hlms_instanced_stereo ) @@ -233,24 +261,21 @@ // Define inputNormal and inputTangent using inVs_normal, inVs_tangent, inVs_qtangent @property( hlms_qtangent ) //Decode qTangent to TBN with reflection - float3 inputNormal = xAxis( normalize( inVs_qtangent ) ); + const midf4 qTangent = normalize( inVs_qtangent ); + midf3 inputNormal = xAxis( qTangent ); @property( normal_map ) - float3 inputTangent = yAxis( inVs_qtangent ); + midf3 inputTangent = yAxis( qTangent ); outVs.biNormalReflection = sign( inVs_qtangent.w ); //We ensure in C++ qtangent.w is never 0 @end @else - @property( hlms_normal && hlms_pose && hlms_pose_normals ) - float3 inputNormal = inVs_normal; // We need inputNormal as lvalue for PoseTransform - @else - #define inputNormal inVs_normal + @property( hlms_normal ) + midf3 inputNormal = midf3_c( inVs_normal ); // We need inputNormal as lvalue for PoseTransform @end - @property( hlms_tangent4 ) - #define inputTangent inVs_tangent.xyz - @property( normal_map ) - outVs.biNormalReflection = sign( inVs_tangent.w ); + @property( normal_map ) + midf3 inputTangent = midf3_c( inVs_tangent.xyz ); + @property( hlms_tangent4 ) + outVs.biNormalReflection = sign( midf( inVs_tangent.w ) ); @end - @else - #define inputTangent inVs_tangent @end @end @@ -263,7 +288,7 @@ float4 worldPos = float4( mul(inVs_vertex, worldMat).xyz, 1.0f ); @property( ( hlms_normal || hlms_qtangent) && hlms_num_shadow_map_lights ) // We need worldNorm for normal offset bias - float3 worldNorm = mul( inputNormal, toFloat3x3( worldMat ) ).xyz; + midf3 worldNorm = mul( inputNormal, toMidf3x3( worldMat ) ).xyz; @end @end @@ -271,10 +296,10 @@ @property( !hlms_skeleton && hlms_pose && ( hlms_normal || hlms_qtangent) && hlms_num_shadow_map_lights ) // We need worldNorm for normal offset bias, special path when using poses - float3 worldNorm; - worldNorm.x = dot( worldMat[0].xyz, inputNormal ); - worldNorm.y = dot( worldMat[1].xyz, inputNormal ); - worldNorm.z = dot( worldMat[2].xyz, inputNormal ); + midf3 worldNorm; + worldNorm.x = dot( midf3_c( worldMat[0].xyz ), inputNormal ); + worldNorm.y = dot( midf3_c( worldMat[1].xyz ), inputNormal ); + worldNorm.z = dot( midf3_c( worldMat[2].xyz ), inputNormal ); @end @insertpiece( SkeletonTransform ) @@ -283,15 +308,13 @@ @insertpiece( DoShadowReceiveVS ) @insertpiece( DoShadowCasterVS ) + @insertpiece( DoAtmosphereNprSky ) + /// hlms_uv_count will be 0 on shadow caster passes w/out alpha test @foreach( hlms_uv_count, n ) outVs.uv@n = inVs_uv@n;@end -@property( syntax != metal ) - @property( (!hlms_shadowcaster || alpha_test) && !lower_gpu_overhead ) - outVs.drawId = inVs_drawId; - @end -@else +@property( syntax == metal || lower_gpu_overhead ) @property( (!hlms_shadowcaster || alpha_test) && !lower_gpu_overhead ) outVs.materialId = worldMaterialIdx[inVs_drawId].x & 0x1FFu; @end @@ -301,7 +324,11 @@ @end @property( use_planar_reflections ) - outVs.planarReflectionIdx = (ushort)(worldMaterialIdx[inVs_drawId].w); + outVs.planarReflectionIdx = ushort( worldMaterialIdx[inVs_drawId].w ); + @end +@else + @property( (!hlms_shadowcaster || alpha_test) && !lower_gpu_overhead ) + outVs.drawId = inVs_drawId; @end @end diff --git a/ogre2/src/media/Hlms/Pbs/Any/PlanarReflections_piece_ps.any b/ogre2/src/media/Hlms/Pbs/Any/PlanarReflections_piece_ps.any index 0e639a203..395a49f12 100644 --- a/ogre2/src/media/Hlms/Pbs/Any/PlanarReflections_piece_ps.any +++ b/ogre2/src/media/Hlms/Pbs/Any/PlanarReflections_piece_ps.any @@ -23,10 +23,10 @@ @end @piece( DoPlanarReflectionsPS ) - @property( syntax != metal ) - uint planarReflectionIdx = worldMaterialIdx[inPs.drawId].w; - @else + @property( syntax == metal || lower_gpu_overhead ) ushort planarReflectionIdx = inPs.planarReflectionIdx; + @else + uint planarReflectionIdx = worldMaterialIdx[inPs.drawId].w; @end float4 planarReflection = passBuf.planarReflections[planarReflectionIdx]; diff --git a/ogre2/src/media/Hlms/Pbs/Any/Refractions_piece_ps.any b/ogre2/src/media/Hlms/Pbs/Any/Refractions_piece_ps.any index 415ccbe30..e238c2610 100644 --- a/ogre2/src/media/Hlms/Pbs/Any/Refractions_piece_ps.any +++ b/ogre2/src/media/Hlms/Pbs/Any/Refractions_piece_ps.any @@ -3,12 +3,12 @@ @property( hlms_screen_space_refractions ) @piece( DeclRefractionsFuncs ) - float3 OGRE_refract( float3 viewDir, float3 normal, float refractionIndex, float NdotV ) + midf3 OGRE_refract( midf3 viewDir, midf3 normal, midf refractionIndex, midf NdotV ) { - float3 retVal; - float k = 1.0 - refractionIndex * refractionIndex * (1.0 - NdotV * NdotV); - if( k < 0.0 ) - retVal = float3( 0, 0, 0 ); + midf3 retVal; + midf k = _h( 1.0 ) - refractionIndex * refractionIndex * (_h( 1.0 ) - NdotV * NdotV); + if( k < _h( 0.0 ) ) + retVal = midf3_c( 0, 0, 0 ); else retVal = -refractionIndex * viewDir - (sqrt( k ) - refractionIndex * NdotV) * normal; return retVal; @@ -17,27 +17,27 @@ @piece( applyRefractions ) @property( !fresnel_scalar ) - float refractF0 = pixelData.F0; + midf refractF0 = pixelData.F0; @else - float refractF0 = max( pixelData.F0.x, pixelData.F0.y, pixelData.F0.z ); + midf refractF0 = max( pixelData.F0.x, pixelData.F0.y, pixelData.F0.z ); @end // refractNormal must be in view space, and we ignore .z component - float2 refractNormal2d = OGRE_refract( pixelData.viewDir, pixelData.normal, - refractF0, pixelData.NdotV ).xy; - float2 refractUv = screenPosUv.xy + refractNormal2d.xy * + midf2 refractNormal2d = OGRE_refract( pixelData.viewDir, pixelData.normal, + refractF0, pixelData.NdotV ).xy; + float2 refractUv = screenPosUv.xy + float2( refractNormal2d.xy ) * float2( material.refractionStrength, material.refractionStrength * passBuf.aspectRatio ) / ( (-inPs.pos.z + 1.0) * (-inPs.pos.z + 1.0) ); - float3 refractionCol = OGRE_SampleLevel( refractionMap, refractionMapSampler, refractUv, 0 ).xyz; - float refractionDepth = OGRE_SampleLevel( depthTextureNoMsaa, refractionMapSampler, refractUv, 0 ).x; + midf3 refractionCol = OGRE_SampleLevelF16( refractionMap, refractionMapSampler, refractUv, 0 ).xyz; + midf refractionDepth = OGRE_SampleLevelF16( depthTextureNoMsaa, refractionMapSampler, refractUv, 0 ).x; // We may need to fallback to regular transparency if we're sampling to close to the edges // or the object being refracted is in front of us. - float3 fallbackRefractionCol = OGRE_Load2D( refractionMap, iFragCoord.xy, 0 ).xyz; + midf3 fallbackRefractionCol = OGRE_Load2DF16( refractionMap, iFragCoord.xy, 0 ).xyz; refractUv = saturate( abs( screenPosUv.xy * 2.0 - 1.0 ) * 10.0 - 9.0 ); - float fallbackRefrW = max( refractUv.x, refractUv.y ); + midf fallbackRefrW = midf_c( max( refractUv.x, refractUv.y ) ); fallbackRefrW = fallbackRefrW * fallbackRefrW; @property( hlms_no_reverse_depth ) @@ -47,17 +47,17 @@ @end { // We're trying to refract an object that is in front of us. We can't do that. - fallbackRefrW = 1.0; + fallbackRefrW = _h( 1.0 ); } refractionCol = lerp( refractionCol, fallbackRefractionCol, fallbackRefrW ); @property( use_texture_alpha ) - float refractionAlpha = material.F0.w * pixelData.diffuse.w; + midf refractionAlpha = midf_c( material.F0.w ) * pixelData.diffuse.w; @else - float refractionAlpha = material.F0.w; + midf refractionAlpha = midf_c( material.F0.w ); @end - finalColour += refractionCol.xyz * (1.0 - refractionAlpha); + finalColour += refractionCol.xyz * (_h( 1.0 ) - refractionAlpha); @end @end diff --git a/ogre2/src/media/Hlms/Pbs/Any/ShadowMapping_piece_all.any b/ogre2/src/media/Hlms/Pbs/Any/ShadowMapping_piece_all.any index cd6a57797..2d36bc9dc 100644 --- a/ogre2/src/media/Hlms/Pbs/Any/ShadowMapping_piece_all.any +++ b/ogre2/src/media/Hlms/Pbs/Any/ShadowMapping_piece_all.any @@ -5,7 +5,7 @@ @piece( DeclNormalOffsetBiasFunc ) @foreach( 2, m ) // Perform normal offset bias. See https://github.com/OGRECave/ogre-next/issues/100 - INLINE float3 getNormalOffsetBias( float3 worldNormal, float3 viewSpaceNormal, + INLINE float3 getNormalOffsetBias( midf3 worldNormal, midf3 viewSpaceNormal, float3 lightDir, float shadowMapTexSize, float depthRange, float normalOffsetBias @property( @m == 0 ) @@ -14,13 +14,13 @@ , float2 minUV, float2 maxUV ) @end { - float tmpNdotL = saturate( dot( lightDir.xyz, viewSpaceNormal.xyz ) ); + float tmpNdotL = saturate( dot( lightDir.xyz, float3( viewSpaceNormal.xyz ) ) ); @property( @m == 1 ) shadowMapTexSize /= maxUV.x - minUV.x; @end - return ( ( 1.0f - tmpNdotL ) * normalOffsetBias * worldNormal.xyz * shadowMapTexSize ); + return ( ( 1.0f - tmpNdotL ) * normalOffsetBias * float3( worldNormal.xyz ) * shadowMapTexSize ); } @end @end diff --git a/ogre2/src/media/Hlms/Pbs/Any/ShadowMapping_piece_ps.any b/ogre2/src/media/Hlms/Pbs/Any/ShadowMapping_piece_ps.any index 82d4c8a2c..92789f0c1 100644 --- a/ogre2/src/media/Hlms/Pbs/Any/ShadowMapping_piece_ps.any +++ b/ogre2/src/media/Hlms/Pbs/Any/ShadowMapping_piece_ps.any @@ -26,8 +26,10 @@ #define hlms_shadowmap@n_uv_min float2( @value( hlms_shadowmap@n_uv_min_x_int ).@value( hlms_shadowmap@n_uv_min_x_fract ), @value( hlms_shadowmap@n_uv_min_y_int ).@value( hlms_shadowmap@n_uv_min_y_fract ) ) #define hlms_shadowmap@n_uv_max float2( @value( hlms_shadowmap@n_uv_max_x_int ).@value( hlms_shadowmap@n_uv_max_x_fract ), @value( hlms_shadowmap@n_uv_max_y_int ).@value( hlms_shadowmap@n_uv_max_y_fract ) ) @property( hlms_shadowmap@n_uvs_fulltex ) - @property( hlms_shadowmap@n_is_point_light ) + @property( hlms_shadowmap@n_is_point_light || hlms_static_branch_shadow_map_lights ) #define hlms_shadowmap@n_uv_length float2( @value( hlms_shadowmap@n_uv_length_x_int ).@value( hlms_shadowmap@n_uv_length_x_fract ), @value( hlms_shadowmap@n_uv_length_y_int ).@value( hlms_shadowmap@n_uv_length_y_fract ) ) + @end + @property( hlms_shadowmap@n_is_point_light ) #define hlms_shadowmap@n_uv_param , hlms_shadowmap@n_uv_min, hlms_shadowmap@n_uv_max, hlms_shadowmap@n_uv_length @else #define hlms_shadowmap@n_uv_param , hlms_shadowmap@n_uv_min, hlms_shadowmap@n_uv_max @@ -38,22 +40,22 @@ @end @property( syntax == glsl || syntax == glsles ) - #define OGRE_SAMPLE_SHADOW( tex, sampler, uv, depth ) (OGRE_DEPTH_CMP_GE( depth, OGRE_DEPTH_DEFAULT_CLEAR ) ? 1.0 : texture( tex, vec3( uv, depth ) )) + #define OGRE_SAMPLE_SHADOW( tex, sampler, uv, depth ) (OGRE_DEPTH_CMP_GE( depth, OGRE_DEPTH_DEFAULT_CLEAR ) ? _h( 1.0 ) : midf_c( texture( tex, vec3( uv, depth ) ) )) #define OGRE_SAMPLE_SHADOW_ESM( tex, sampler, uv ) textureLod( tex, uv, 0 ).x @end @property( syntax == glslvk ) - #define OGRE_SAMPLE_SHADOW( tex, sampler, uv, depth ) (OGRE_DEPTH_CMP_GE( depth, OGRE_DEPTH_DEFAULT_CLEAR ) ? 1.0 : texture( sampler2DShadow( tex, sampler ), vec3( uv, depth ) ) ) + #define OGRE_SAMPLE_SHADOW( tex, sampler, uv, depth ) (OGRE_DEPTH_CMP_GE( depth, OGRE_DEPTH_DEFAULT_CLEAR ) ? _h( 1.0 ) : midf_c( texture( sampler2DShadow( tex, sampler ), vec3( uv, depth ) ) ) ) #define OGRE_SAMPLE_SHADOW_ESM( tex, sampler, uv ) textureLod( sampler2D( tex, sampler ), uv, 0 ).x @end @property( syntax == hlsl ) - #define OGRE_SAMPLE_SHADOW( tex, sampler, uv, depth ) (OGRE_DEPTH_CMP_GE( depth, OGRE_DEPTH_DEFAULT_CLEAR ) ? 1.0 : tex.SampleCmpLevelZero( sampler, uv.xy, depth ).x) + #define OGRE_SAMPLE_SHADOW( tex, sampler, uv, depth ) (OGRE_DEPTH_CMP_GE( depth, OGRE_DEPTH_DEFAULT_CLEAR ) ? _h( 1.0 ) : midf_c( tex.SampleCmpLevelZero( sampler, uv.xy, depth ).x )) #define OGRE_SAMPLE_SHADOW_ESM( tex, sampler, uv ) tex.SampleLevel( sampler, uv, 0 ).x @end @property( syntax == metal ) - #define OGRE_SAMPLE_SHADOW( tex, sampler, uv, depth ) (OGRE_DEPTH_CMP_GE( depth, OGRE_DEPTH_DEFAULT_CLEAR ) ? 1.0 : tex.sample_compare( sampler, float2( uv.xy ), depth )) + #define OGRE_SAMPLE_SHADOW( tex, sampler, uv, depth ) (OGRE_DEPTH_CMP_GE( depth, OGRE_DEPTH_DEFAULT_CLEAR ) ? _h( 1.0 ) : tex.sample_compare( sampler, float2( uv.xy ), depth )) #define OGRE_SAMPLE_SHADOW_ESM( tex, sampler, uv ) tex.sample( sampler, float2( uv.xy ), level(0) ).x @end @end @@ -90,19 +92,19 @@ @property( pcf < 3 ) //2x2 PCF: It's slightly faster to calculate this directly. - retVal += mix( - mix( c.w, c.z, fW.x ), - mix( c.x, c.y, fW.x ), + retVal += lerp( + lerp( c.w, c.z, fW.x ), + lerp( c.x, c.y, fW.x ), fW.y ); @else - row[0] += mix( c.w, c.z, fW.x ); - row[1] += mix( c.x, c.y, fW.x ); + row[0] += lerp( c.w, c.z, fW.x ); + row[1] += lerp( c.x, c.y, fW.x ); @end @end @property( pcf >= 3 ) //NxN PCF: It's much faster to leave the final mix out of the loop (when N > 2). - retVal = mix( row[0], row[1], fW.y ); + retVal = lerp( row[0], row[1], fW.y ); @end @end @end @@ -181,6 +183,15 @@ #define inPs_posL@n worldPosToSpotLightSpace( inPs.worldPos, passBuf.shadowRcv[@n], @insertpiece( shadowMapNormalOffsetBias@n ) ) @end @end + @property( hlms_static_branch_shadow_map_lights ) + @property( !skip_normal_offset_bias_vs ) + @piece( shadowMapNormalOffsetBias_cur_shadow_map )getNormalOffsetBias( inPs.worldNorm, pixelData.geomNormal, light0Buf.lights[light_idx].spotDirection.xyz, passBuf.shadowRcv[cur_shadow_map].invShadowMapSize.x, passBuf.shadowRcv[cur_shadow_map].shadowDepthRange.y, passBuf.shadowRcv[cur_shadow_map].normalOffsetBias, shadowmap_uv_min[cur_shadow_map], shadowmap_uv_max[cur_shadow_map] )@end + @else + @piece( shadowMapNormalOffsetBias_cur_shadow_map )float3( 0.0f, 0.0f, 0.0f )@end + @end + + #define inPs_posL_cur_shadow_map worldPosToSpotLightSpace( inPs.worldPos, passBuf.shadowRcv[cur_shadow_map], @insertpiece( shadowMapNormalOffsetBias_cur_shadow_map ) ) + @end @foreach( 2, m ) @property( @m == 0 ) @@ -224,7 +235,7 @@ @foreach( 2, m ) // Perform normal offset bias. See https://github.com/OGRECave/ogre-next/issues/100 - INLINE float3 getNormalOffsetBiasPoint( float3 geomNormal, float3 lightDir, + INLINE float3 getNormalOffsetBiasPoint( midf3 geomNormal, float3 lightDir, float normalOffsetBias, float shadowMapTexSize, float depthRange @property( @m == 0 ) @@ -233,30 +244,30 @@ , float2 minUV, float2 maxUV ) @end { - float tmpNdotL = saturate( dot( lightDir.xyz, geomNormal.xyz ) ); + float tmpNdotL = saturate( dot( lightDir.xyz, float3( geomNormal.xyz ) ) ); @property( @m == 1 ) shadowMapTexSize /= maxUV.x - minUV.x; @end - return ( ( 1.0f - tmpNdotL ) * normalOffsetBias * geomNormal.xyz * shadowMapTexSize ); + return ( ( 1.0f - tmpNdotL ) * normalOffsetBias * float3( geomNormal.xyz ) * shadowMapTexSize ); } @end @foreach( 4, m ) @property( @m == 0 ) - INLINE float getShadow( @insertpiece( TEXTURE2DSHADOW ) shadowMap, @insertpiece( SamplerShadow ) + INLINE midf getShadow( @insertpiece( TEXTURE2DSHADOW ) shadowMap, @insertpiece( SamplerShadow ) float4 psPosLN, float4 invShadowMapSize ) @end @property( @m == 1 ) - INLINE float getShadow( @insertpiece( TEXTURE2DSHADOW ) shadowMap, @insertpiece( SamplerShadow ) + INLINE midf getShadow( @insertpiece( TEXTURE2DSHADOW ) shadowMap, @insertpiece( SamplerShadow ) float4 psPosLN, float4 invShadowMapSize, float2 minUV, float2 maxUV ) @end @property( @m == 2 ) - INLINE float getShadowPoint( @insertpiece( TEXTURE2DSHADOW ) shadowMap, @insertpiece( SamplerShadow ) - float3 geomNormal, float normalOffsetBias, + INLINE midf getShadowPoint( @insertpiece( TEXTURE2DSHADOW ) shadowMap, @insertpiece( SamplerShadow ) + midf3 geomNormal, float normalOffsetBias, float3 posVS, float3 lightPos,float4 invShadowMapSize, float2 invDepthRange PASSBUF_ARG_DECL ) @end @property( @m == 3 ) - INLINE float getShadowPoint( @insertpiece( TEXTURE2DSHADOW ) shadowMap, @insertpiece( SamplerShadow ) - float3 geomNormal, float normalOffsetBias, + INLINE midf getShadowPoint( @insertpiece( TEXTURE2DSHADOW ) shadowMap, @insertpiece( SamplerShadow ) + midf3 geomNormal, float normalOffsetBias, float3 posVS, float3 lightPos, float4 invShadowMapSize, float2 invDepthRange, float2 minUV, float2 maxUV, float2 lengthUV PASSBUF_ARG_DECL ) @@ -302,7 +313,7 @@ @end @property( !exponential_shadow_maps ) - float retVal = 0.; + midf retVal = _h( 0. ); @property( pcf >= 3 ) float2 offsets[@value(pcf_iterations)] = @@ -397,30 +408,30 @@ @end @property( pcf == 3 ) - retVal *= 0.25; + retVal *= _h( 0.25 ); @end @property( pcf == 4 ) - retVal *= 0.11111111111111; + retVal *= _h( 0.11111111111111 ); @end @property( pcf == 5) - retVal *= 0.0625; + retVal *= _h( 0.0625 ); @end @property( pcf == 6 ) - retVal *= 0.04; + retVal *= _h( 0.04 ); @end @end ///! exponential_shadow_maps @property( exponential_shadow_maps ) float expDepth = OGRE_SAMPLE_SHADOW_ESM( shadowMap, shadowSampler, uv ); - float retVal = exp( @value( exponential_shadow_maps ).0 * (expDepth - fDepth) ); - retVal = min( retVal, 1.0 ); + float unclampedVal = exp( @value( exponential_shadow_maps ).0 * (expDepth - fDepth) ); + midf retVal = midf_c( min( unclampedVal, 1.0 ) ); @end ///! exponential_shadow_maps @property( (@m == 0 || @m == 2) && syntax == metal ) //Metal does not support clamp to border colour retVal = (uv.x <= 0.0h || uv.x >= 1.0h || - uv.y <= 0.0h || uv.y >= 1.0h) ? 1.0 : retVal; + uv.y <= 0.0h || uv.y >= 1.0h) ? _h( 1.0 ) : retVal; @end @property( @m == 1 || @m == 3 ) retVal = (uv.x <= minUV.x || uv.x >= maxUV.x || - uv.y <= minUV.y || uv.y >= maxUV.y) ? 1.0 : retVal; + uv.y <= minUV.y || uv.y >= maxUV.y) ? _h( 1.0 ) : retVal; @end return retVal; @@ -437,9 +448,9 @@ @property( debug_pssm_splits ) float3 debugPssmSplit = float3( 0, 0, 0 ); @end - float fShadow = 1.0; + midf fShadow = _h( 1.0 ); @property( hlms_pssm_blend ) - float fShadowBlend = 1.0; + midf fShadowBlend = _h( 1.0 ); @end @property( receive_shadows ) if( inPs.depth <= passBuf.pssmSplitPoints@value(CurrentShadowMap) ) @@ -455,9 +466,11 @@ inPs_posL1, passBuf.shadowRcv[@value(CurrentShadowMap)].invShadowMapSize hlms_shadowmap@value(CurrentShadowMap)_uv_param ); - fShadow = lerp( fShadow, fShadowBlend, - (inPs.depth - passBuf.pssmBlendPoints@value(CurrentShadowMapBlend)) / - (passBuf.pssmSplitPoints@value(CurrentShadowMapBlend) - passBuf.pssmBlendPoints@counter(CurrentShadowMapBlend)) ); + fShadow = lerp( + fShadow, fShadowBlend, + midf_c( ( inPs.depth - passBuf.pssmBlendPoints@value( CurrentShadowMapBlend ) ) / + ( passBuf.pssmSplitPoints@value( CurrentShadowMapBlend ) - + passBuf.pssmBlendPoints@counter( CurrentShadowMapBlend ) ) ) ); } @end @property( debug_pssm_splits ) @@ -478,16 +491,19 @@ inPs_posL@value(CurrentShadowMap), passBuf.shadowRcv[@value(CurrentShadowMap)].invShadowMapSize hlms_shadowmap@value(CurrentShadowMap)_uv_param ); - fShadow = lerp( fShadow, fShadowBlend, - (inPs.depth - passBuf.pssmBlendPoints@value(CurrentShadowMapBlend)) / - (passBuf.pssmSplitPoints@value(CurrentShadowMapBlend) - passBuf.pssmBlendPoints@counter(CurrentShadowMapBlend)) ); + fShadow = lerp( + fShadow, fShadowBlend, + midf_c( ( inPs.depth - passBuf.pssmBlendPoints@value( CurrentShadowMapBlend ) ) / + ( passBuf.pssmSplitPoints@value( CurrentShadowMapBlend ) - + passBuf.pssmBlendPoints@counter( CurrentShadowMapBlend ) ) ) ); } @end @property( hlms_pssm_fade && @n == hlms_pssm_splits_minus_one ) if( inPs.depth > passBuf.pssmFadePoint ) { - fShadow = lerp( fShadow, 1.0, - (inPs.depth - passBuf.pssmFadePoint) / - (passBuf.pssmSplitPoints@value(hlms_pssm_splits_minus_one) - passBuf.pssmFadePoint) ); + fShadow = lerp( fShadow, _h( 1.0 ), + midf_c( ( inPs.depth - passBuf.pssmFadePoint ) / + ( passBuf.pssmSplitPoints@value( hlms_pssm_splits_minus_one ) - + passBuf.pssmFadePoint ) ) ); } @end @property( debug_pssm_splits ) @@ -503,12 +519,12 @@ @end @end @property( !hlms_pssm_splits && hlms_num_shadow_map_lights && hlms_lights_directional ) @property( receive_shadows ) - float fShadow = getShadow( hlms_shadowmap@value(CurrentShadowMap), @insertpiece( UseSamplerShadow ) - inPs_posL0, - passBuf.shadowRcv[@value(CurrentShadowMap)].invShadowMapSize - hlms_shadowmap@counter(CurrentShadowMap)_uv_param ); + midf fShadow = getShadow( hlms_shadowmap@value(CurrentShadowMap), @insertpiece( UseSamplerShadow ) + inPs_posL0, + passBuf.shadowRcv[@value(CurrentShadowMap)].invShadowMapSize + hlms_shadowmap@counter(CurrentShadowMap)_uv_param ); @else - float fShadow = 1.0; + midf fShadow = _h( 1.0 ); @end @end @end @@ -516,6 +532,29 @@ @property( receive_shadows ) @piece( DarkenWithShadowFirstLight )* fShadow@end +@property( hlms_static_branch_shadow_map_lights ) + + // All point and spot lights must share the same hlms_shadowmap atlas + // See HlmsPbs::setStaticBranchingLights + @piece( DarkenWithShadow_cur_shadow_map ) + * getShadow( hlms_shadowmap@value(CurrentShadowMap), @insertpiece( UseSamplerShadow ) + inPs_posL_cur_shadow_map, + passBuf.shadowRcv[cur_shadow_map].invShadowMapSize + , shadowmap_uv_min[cur_shadow_map], shadowmap_uv_max[cur_shadow_map] ) + @end + + @piece( DarkenWithShadowPoint_cur_shadow_map ) + * getShadowPoint( hlms_shadowmap@value(CurrentShadowMap), @insertpiece( UseSamplerShadow ) + pixelData.geomNormal, + passBuf.shadowRcv[cur_shadow_map].normalOffsetBias, + inPs.pos.xyz, light0Buf.lights[light_idx].position.xyz, + passBuf.shadowRcv[cur_shadow_map].invShadowMapSize, + passBuf.shadowRcv[cur_shadow_map].shadowDepthRange.xy + , shadowmap_uv_min[cur_shadow_map], shadowmap_uv_max[cur_shadow_map], shadowmap_uv_length[cur_shadow_map] PASSBUF_ARG ) + @end + +@else + @piece( DarkenWithShadow ) * getShadow( hlms_shadowmap@value(CurrentShadowMap), @insertpiece( UseSamplerShadow ) inPs_posL@value(CurrentShadowMap), @@ -534,6 +573,9 @@ passBuf.shadowRcv[@value(CurrentShadowMap)].shadowDepthRange.xy hlms_shadowmap@counter(CurrentShadowMap)_uv_param PASSBUF_ARG ) @end + +@end + @end ///!receive_shadows @end diff --git a/ogre2/src/media/Hlms/Pbs/GLSL/Forward3D_piece_ps.glsl b/ogre2/src/media/Hlms/Pbs/GLSL/Forward3D_piece_ps.glsl index 27d4a0563..aae9c0cde 100644 --- a/ogre2/src/media/Hlms/Pbs/GLSL/Forward3D_piece_ps.glsl +++ b/ogre2/src/media/Hlms/Pbs/GLSL/Forward3D_piece_ps.glsl @@ -5,13 +5,13 @@ @property( syntax == glslvk ) layout( ogre_s@value(decalsSampler) ) uniform sampler decalsSampler; @end - @property( hlms_decals_diffuse )vulkan_layout( ogre_t@value(decalsDiffuseTex) ) uniform texture2DArray decalsDiffuseTex;@end - @property( hlms_decals_normals )vulkan_layout( ogre_t@value(decalsNormalsTex) ) uniform texture2DArray decalsNormalsTex;@end + @property( hlms_decals_diffuse )vulkan_layout( ogre_t@value(decalsDiffuseTex) ) midf_tex uniform texture2DArray decalsDiffuseTex;@end + @property( hlms_decals_normals )vulkan_layout( ogre_t@value(decalsNormalsTex) ) midf_tex uniform texture2DArray decalsNormalsTex;@end @property( hlms_decals_diffuse == hlms_decals_emissive ) #define decalsEmissiveTex decalsDiffuseTex @end @property( hlms_decals_emissive && hlms_decals_diffuse != hlms_decals_emissive ) - vulkan_layout( ogre_t@value(decalsEmissiveTex) ) uniform texture2DArray decalsEmissiveTex; + vulkan_layout( ogre_t@value(decalsEmissiveTex) ) midf_tex uniform texture2DArray decalsEmissiveTex; @end @end @end diff --git a/ogre2/src/media/Hlms/Pbs/GLSL/PixelShader_ps.glsl b/ogre2/src/media/Hlms/Pbs/GLSL/PixelShader_ps.glsl index 6a6b632fe..b2c3e7519 100644 --- a/ogre2/src/media/Hlms/Pbs/GLSL/PixelShader_ps.glsl +++ b/ogre2/src/media/Hlms/Pbs/GLSL/PixelShader_ps.glsl @@ -10,15 +10,15 @@ layout(std140) uniform; @property( !hlms_render_depth_only ) @property( !hlms_shadowcaster ) @property( !hlms_prepass ) - layout(location = @counter(rtv_target), index = 0) out vec4 outColour; + layout(location = @counter(rtv_target), index = 0) out midf4 outColour; @end @property( hlms_gen_normals_gbuffer ) #define outPs_normals outNormals - layout(location = @counter(rtv_target)) out vec4 outNormals; + layout(location = @counter(rtv_target)) out midf4 outNormals; @end @property( hlms_prepass ) #define outPs_shadowRoughness outShadowRoughness - layout(location = @counter(rtv_target)) out vec2 outShadowRoughness; + layout(location = @counter(rtv_target)) out midf2 outShadowRoughness; @end @else layout(location = @counter(rtv_target), index = 0) out float outColour; @@ -49,8 +49,8 @@ layout(std140) uniform; vulkan_layout( ogre_t@value(depthTextureNoMsaa) ) uniform texture2D depthTextureNoMsaa; @end @end - vulkan_layout( ogre_t@value(refractionMap) ) uniform texture2D refractionMap; - vulkan( layout( ogre_s@value(refractionMap) ) uniform sampler refractionMapSampler ); + vulkan_layout( ogre_t@value(refractionMap) ) midf_tex uniform texture2D refractionMap; + vulkan( layout( ogre_s@value(refractionMap) ) uniform sampler refractionMapSampler ); @end @insertpiece( DeclPlanarReflTextures ) @@ -82,21 +82,21 @@ vulkan_layout( location = 0 ) in block ReadOnlyBufferF( @value(f3dLightList), float4, f3dLightList ); @end @property( irradiance_volumes ) - vulkan_layout( ogre_t@value(irradianceVolume) ) uniform texture3D irradianceVolume; - vulkan( layout( ogre_s@value(irradianceVolume) )uniform sampler irradianceVolumeSampler ); + vulkan_layout( ogre_t@value(irradianceVolume) ) midf_tex uniform texture3D irradianceVolume; + vulkan( layout( ogre_s@value(irradianceVolume) )uniform sampler irradianceVolumeSampler ); @end @foreach( num_textures, n ) - vulkan_layout( ogre_t@value(textureMaps@n) ) uniform texture2DArray textureMaps@n;@end + vulkan_layout( ogre_t@value(textureMaps@n) ) midf_tex uniform texture2DArray textureMaps@n;@end @property( use_envprobe_map ) @property( !hlms_enable_cubemaps_auto ) - vulkan_layout( ogre_t@value(texEnvProbeMap) ) uniform textureCube texEnvProbeMap; + vulkan_layout( ogre_t@value(texEnvProbeMap) ) midf_tex uniform textureCube texEnvProbeMap; @else @property( !hlms_cubemaps_use_dpm ) - vulkan_layout( ogre_t@value(texEnvProbeMap) ) uniform textureCubeArray texEnvProbeMap; + vulkan_layout( ogre_t@value(texEnvProbeMap) ) midf_tex uniform textureCubeArray texEnvProbeMap; @else - vulkan_layout( ogre_t@value(texEnvProbeMap) ) uniform texture2DArray texEnvProbeMap; + vulkan_layout( ogre_t@value(texEnvProbeMap) ) midf_tex uniform texture2DArray texEnvProbeMap; @insertpiece( DeclDualParaboloidFunc ) @end @end @@ -140,7 +140,7 @@ void main() @property( alpha_test ) @foreach( num_textures, n ) - vulkan_layout( ogre_t@value(textureMaps@n) ) uniform texture2DArray textureMaps@n;@end + vulkan_layout( ogre_t@value(textureMaps@n) ) midf_tex uniform texture2DArray textureMaps@n;@end @property( syntax == glslvk ) @foreach( num_samplers, n ) diff --git a/ogre2/src/media/Hlms/Pbs/GLSL/VertexShader_vs.glsl b/ogre2/src/media/Hlms/Pbs/GLSL/VertexShader_vs.glsl index c33c951b0..3082b996c 100644 --- a/ogre2/src/media/Hlms/Pbs/GLSL/VertexShader_vs.glsl +++ b/ogre2/src/media/Hlms/Pbs/GLSL/VertexShader_vs.glsl @@ -4,7 +4,7 @@ out gl_PerVertex { vec4 gl_Position; -@property( hlms_pso_clip_distances ) +@property( hlms_pso_clip_distances && !hlms_emulate_clip_distances ) float gl_ClipDistance[@value(hlms_pso_clip_distances)]; @end }; @@ -16,13 +16,13 @@ layout(std140) uniform; vulkan_layout( OGRE_POSITION ) in vec4 vertex; -@property( hlms_normal )vulkan_layout( OGRE_NORMAL ) in vec3 normal;@end -@property( hlms_qtangent )vulkan_layout( OGRE_NORMAL ) in vec4 qtangent;@end +@property( hlms_normal )vulkan_layout( OGRE_NORMAL ) in float3 normal;@end +@property( hlms_qtangent )vulkan_layout( OGRE_NORMAL ) in midf4 qtangent;@end @property( normal_map && !hlms_qtangent ) - @property( hlms_tangent4 )vulkan_layout( OGRE_TANGENT ) in vec4 tangent;@end - @property( !hlms_tangent4 )vulkan_layout( OGRE_TANGENT ) in vec3 tangent;@end - @property( hlms_binormal )vulkan_layout( OGRE_BIRNORMAL ) in vec3 binormal;@end + @property( hlms_tangent4 )vulkan_layout( OGRE_TANGENT ) in float4 tangent;@end + @property( !hlms_tangent4 )vulkan_layout( OGRE_TANGENT ) in float3 tangent;@end + @property( hlms_binormal )vulkan_layout( OGRE_BIRNORMAL ) in float3 binormal;@end @end @property( hlms_skeleton ) diff --git a/ogre2/src/media/Hlms/Pbs/HLSL/Textures_piece_ps.hlsl b/ogre2/src/media/Hlms/Pbs/HLSL/Textures_piece_ps.hlsl index 2e1df3879..c3ea30413 100644 --- a/ogre2/src/media/Hlms/Pbs/HLSL/Textures_piece_ps.hlsl +++ b/ogre2/src/media/Hlms/Pbs/HLSL/Textures_piece_ps.hlsl @@ -2,10 +2,10 @@ @property( !hlms_render_depth_only && !hlms_shadowcaster ) @piece( ExtraOutputTypes ) @property( hlms_gen_normals_gbuffer ) - float4 normals : SV_Target@counter(rtv_target); + midf4 normals : SV_Target@counter(rtv_target); @end @property( hlms_prepass ) - float2 shadowRoughness : SV_Target@counter(rtv_target); + midf2 shadowRoughness : SV_Target@counter(rtv_target); @end @end @end diff --git a/ogre2/src/media/Hlms/Pbs/Metal/Forward3D_piece_ps.metal b/ogre2/src/media/Hlms/Pbs/Metal/Forward3D_piece_ps.metal index c3ad0672e..bc9895245 100644 --- a/ogre2/src/media/Hlms/Pbs/Metal/Forward3D_piece_ps.metal +++ b/ogre2/src/media/Hlms/Pbs/Metal/Forward3D_piece_ps.metal @@ -3,13 +3,13 @@ @property( hlms_enable_decals ) @piece( DeclDecalsSamplers ) , sampler decalsSampler [[sampler(@value(decalsSampler))]] - @property( hlms_decals_diffuse ), texture2d_array decalsDiffuseTex [[texture(@value(decalsDiffuseTex))]]@end - @property( hlms_decals_normals ), texture2d_array decalsNormalsTex [[texture(@value(decalsNormalsTex))]]@end + @property( hlms_decals_diffuse ), texture2d_array decalsDiffuseTex [[texture(@value(decalsDiffuseTex))]]@end + @property( hlms_decals_normals ), texture2d_array decalsNormalsTex [[texture(@value(decalsNormalsTex))]]@end @property( hlms_decals_diffuse == hlms_decals_emissive ) #define decalsEmissiveTex decalsDiffuseTex @end @property( hlms_decals_emissive && hlms_decals_diffuse != hlms_decals_emissive ) - , texture2d_array decalsEmissiveTex [[texture(@value(decalsEmissiveTex))]] + , texture2d_array decalsEmissiveTex [[texture(@value(decalsEmissiveTex))]] @end @end @end diff --git a/ogre2/src/media/Hlms/Pbs/Metal/PixelShader_ps.metal b/ogre2/src/media/Hlms/Pbs/Metal/PixelShader_ps.metal index fbe5b4ca7..92ef17edd 100644 --- a/ogre2/src/media/Hlms/Pbs/Metal/PixelShader_ps.metal +++ b/ogre2/src/media/Hlms/Pbs/Metal/PixelShader_ps.metal @@ -67,6 +67,7 @@ fragment @insertpiece( output_type ) main_metal @end @insertpiece( MaterialDecl ) @insertpiece( PccManualProbeDecl ) + @insertpiece( AtmosphereNprSkyDecl ) @end @insertpiece( custom_ps_uniformDeclaration ) // END UNIFORM DECLARATION @@ -77,11 +78,11 @@ fragment @insertpiece( output_type ) main_metal @property( hlms_use_prepass ) @property( !hlms_use_prepass_msaa ) - , texture2d gBuf_normals [[texture(@value(gBuf_normals))]] - , texture2d gBuf_shadowRoughness [[texture(@value(gBuf_shadowRoughness))]] + , texture2d gBuf_normals [[texture(@value(gBuf_normals))]] + , texture2d gBuf_shadowRoughness [[texture(@value(gBuf_shadowRoughness))]] @end @property( hlms_use_prepass_msaa ) - , texture2d_ms gBuf_normals [[texture(@value(gBuf_normals))]] - , texture2d_ms gBuf_shadowRoughness[[texture(@value(gBuf_shadowRoughness))]] + , texture2d_ms gBuf_normals [[texture(@value(gBuf_normals))]] + , texture2d_ms gBuf_shadowRoughness[[texture(@value(gBuf_shadowRoughness))]] @end @property( hlms_use_ssr ) @@ -98,7 +99,7 @@ fragment @insertpiece( output_type ) main_metal , texture2d depthTextureNoMsaa [[texture(@value(depthTextureNoMsaa))]] @end @end - , texture2d refractionMap [[texture(@value(refractionMap))]] + , texture2d refractionMap [[texture(@value(refractionMap))]] , sampler refractionMapSampler [[sampler(@value(refractionMap))]] @end @@ -107,22 +108,22 @@ fragment @insertpiece( output_type ) main_metal @insertpiece( DeclLightProfilesTexture ) @property( irradiance_volumes ) - , texture3d irradianceVolume [[texture(@value(irradianceVolume))]] + , texture3d irradianceVolume [[texture(@value(irradianceVolume))]] , sampler irradianceVolumeSampler [[sampler(@value(irradianceVolume))]] @end @foreach( num_textures, n ) - , texture2d_array textureMaps@n [[texture(@value(textureMaps@n))]]@end + , texture2d_array textureMaps@n [[texture(@value(textureMaps@n))]]@end @property( use_envprobe_map ) @property( !hlms_enable_cubemaps_auto ) - , texturecube texEnvProbeMap [[texture(@value(texEnvProbeMap))]] + , texturecube texEnvProbeMap [[texture(@value(texEnvProbeMap))]] @end @property( hlms_enable_cubemaps_auto ) @property( !hlms_cubemaps_use_dpm ) - , texturecube_array texEnvProbeMap [[texture(@value(texEnvProbeMap))]] + , texturecube_array texEnvProbeMap [[texture(@value(texEnvProbeMap))]] @end @property( hlms_cubemaps_use_dpm ) - , texture2d_array texEnvProbeMap [[texture(@value(texEnvProbeMap))]] + , texture2d_array texEnvProbeMap [[texture(@value(texEnvProbeMap))]] @end @end @property( envMapRegSampler < samplerStateStart ) @@ -172,7 +173,7 @@ fragment @insertpiece( output_type ) main_metal // END UNIFORM DECLARATION @foreach( num_textures, n ) - , texture2d_array textureMaps@n [[texture(@value(textureMaps@n))]]@end + , texture2d_array textureMaps@n [[texture(@value(textureMaps@n))]]@end @foreach( num_samplers, n ) , sampler samplerState@value(samplerStateStart) [[sampler(@counter(samplerStateStart))]]@end ) diff --git a/ogre2/src/media/Hlms/Pbs/Metal/Textures_piece_ps.metal b/ogre2/src/media/Hlms/Pbs/Metal/Textures_piece_ps.metal index fb76fb715..4773328bc 100644 --- a/ogre2/src/media/Hlms/Pbs/Metal/Textures_piece_ps.metal +++ b/ogre2/src/media/Hlms/Pbs/Metal/Textures_piece_ps.metal @@ -2,10 +2,10 @@ @property( !hlms_render_depth_only && !hlms_shadowcaster ) @piece( ExtraOutputTypes ) @property( hlms_gen_normals_gbuffer ) - float4 normals [[ color(@counter(rtv_target)) ]]; + midf4 normals [[ color(@counter(rtv_target)) ]]; @end @property( hlms_prepass ) - float2 shadowRoughness [[ color(@counter(rtv_target)) ]]; + midf2 shadowRoughness [[ color(@counter(rtv_target)) ]]; @end @end @end diff --git a/ogre2/src/media/Hlms/Pbs/Metal/VertexShader_vs.metal b/ogre2/src/media/Hlms/Pbs/Metal/VertexShader_vs.metal index 575ccd561..6f8ad6adf 100644 --- a/ogre2/src/media/Hlms/Pbs/Metal/VertexShader_vs.metal +++ b/ogre2/src/media/Hlms/Pbs/Metal/VertexShader_vs.metal @@ -9,7 +9,7 @@ struct VS_INPUT { float4 position [[attribute(VES_POSITION)]]; @property( hlms_normal ) float3 normal [[attribute(VES_NORMAL)]];@end -@property( hlms_qtangent ) float4 qtangent [[attribute(VES_NORMAL)]];@end +@property( hlms_qtangent ) midf4 qtangent [[attribute(VES_NORMAL)]];@end @property( normal_map && !hlms_qtangent ) @property( hlms_tangent4 )float4 tangent [[attribute(VES_TANGENT)]];@end @@ -53,6 +53,7 @@ vertex PS_INPUT main_metal // START UNIFORM DECLARATION @insertpiece( PassDecl ) @insertpiece( InstanceDecl ) + @insertpiece( AtmosphereNprSkyDecl ) , device const float4 *worldMatBuf [[buffer(TEX_SLOT_START+0)]] @property( hlms_pose ) @property( !hlms_pose_half ) @@ -62,8 +63,8 @@ vertex PS_INPUT main_metal @end @end @property( hlms_vertex_id ) - , uint vertexId [[vertex_id]] - , uint baseVertex [[base_vertex]] + , uint inVs_vertexId [[vertex_id]] + , uint baseVertexID [[base_vertex]] @end @insertpiece( custom_vs_uniformDeclaration ) // END UNIFORM DECLARATION diff --git a/ogre2/src/media/Hlms/Terra/Any/500.Structs_piece_vs_piece_ps.any b/ogre2/src/media/Hlms/Terra/Any/500.Structs_piece_vs_piece_ps.any index c30ac6824..ea4e6717a 100644 --- a/ogre2/src/media/Hlms/Terra/Any/500.Structs_piece_vs_piece_ps.any +++ b/ogre2/src/media/Hlms/Terra/Any/500.Structs_piece_vs_piece_ps.any @@ -86,6 +86,11 @@ struct CellData @piece( Terra_VStoPS_block ) INTERPOLANT( float3 pos, @counter(texcoord) ); INTERPOLANT( float2 uv0, @counter(texcoord) ); + + @property( detail_triplanar ) + INTERPOLANT( float3 worldPos, @counter(texcoord) ); + @end + @insertpiece( VStoPS_block ) @end diff --git a/ogre2/src/media/Hlms/Terra/Any/550.DetailTriplanar_piece_ps.any b/ogre2/src/media/Hlms/Terra/Any/550.DetailTriplanar_piece_ps.any new file mode 100644 index 000000000..3baaa2c81 --- /dev/null +++ b/ogre2/src/media/Hlms/Terra/Any/550.DetailTriplanar_piece_ps.any @@ -0,0 +1,175 @@ +@piece( DeclDetailTriplanarFuncs ) + @property( detail_triplanar ) + // https://catlikecoding.com/unity/tutorials/advanced-rendering/triplanar-mapping/ + + // Side view projection + midf2 GetTriplanarUVSd( midf3 position, midf3 normal ) + { + midf2 uv = -position.zy; + + if( normal.x < _h( 0.0 ) ) + { + uv.x = -uv.x; + } + + return uv; + } + + // Top view projection + midf2 GetTriplanarUVTp( midf3 position, midf3 normal ) + { + return position.xz; + } + + // Front view projection + midf2 GetTriplanarUVFr( midf3 position, midf3 normal ) + { + midf2 uv = -position.xy; + + if( normal.z >= _h( 0.0 ) ) + { + uv.x = -uv.x; + } + + return uv; + } + @end + + @property( detail_triplanar_diffuse ) + @foreach( detail_maps_diffuse, n )@property( detail_map@n ) + #define SampleDetailCol@nTriplanar( tex, sampler, uv, arrayIdx ) (SampleDetailCol@n( tex, \ + sampler, \ + UV_DETAIL@n( GetTriplanarUVSd( inPs.worldPos, pixelData.worldSpaceNormal )@insertpiece( offsetDetail@n ) ), \ + arrayIdx ) * triplanarBlend.x + \ + \ + SampleDetailCol@n( tex, \ + sampler, \ + UV_DETAIL@n( GetTriplanarUVTp( inPs.worldPos, pixelData.worldSpaceNormal )@insertpiece( offsetDetail@n ) ), \ + arrayIdx ) * triplanarBlend.y + \ + \ + SampleDetailCol@n( tex, \ + sampler, \ + UV_DETAIL@n( GetTriplanarUVFr( inPs.worldPos, pixelData.worldSpaceNormal )@insertpiece( offsetDetail@n ) ), \ + arrayIdx ) * triplanarBlend.z) + @end @end + @end + + @property( detail_triplanar_normal ) + // https://catlikecoding.com/unity/tutorials/advanced-rendering/triplanar-mapping/ + midf3 BlendTriplanarNormal( midf3 mappedNormal, midf3 surfaceNormal ) + { + midf3 n; + n.xy = mappedNormal.xy + surfaceNormal.xy; + n.z = mappedNormal.z * surfaceNormal.z; + return n; + } + + @foreach( detail_maps_normal, n )@property( detail_map_nm@n ) + #define SampleDetailMapNm@nSd( tex, sampler, uv, arrayIdx ) SampleDetailMapNm@nSdFn( tex, sampler, uv, arrayIdx, detailWeights, pixelData.worldSpaceNormal ) + #define SampleDetailMapNm@nTp( tex, sampler, uv, arrayIdx ) SampleDetailMapNm@nTpFn( tex, sampler, uv, arrayIdx, detailWeights, pixelData.worldSpaceNormal ) + #define SampleDetailMapNm@nFr( tex, sampler, uv, arrayIdx ) SampleDetailMapNm@nFrFn( tex, sampler, uv, arrayIdx, detailWeights, pixelData.worldSpaceNormal ) + + // Side view projection + midf3 SampleDetailMapNm@nSdFn( Texture2DArray tex, SamplerState smp, midf2 uv, uint arrayIdx, midf4 weights, midf3 normal ) + { + midf3 tangentNormal = getTSNormal( tex, smp, uv, arrayIdx ) * weights.@insertpiece( detail_swizzle@n ); + + if( normal.x >= _h( 0.0 ) ) + { + tangentNormal.x = -tangentNormal.x; + } + + midf3 worldNormal = BlendTriplanarNormal( tangentNormal, normal.zyx ).zyx; + worldNormal.x += _h( 1.0 ) - weights.@insertpiece( detail_swizzle@n ); + + return worldNormal; + } + + // Top view projection + midf3 SampleDetailMapNm@nTpFn( Texture2DArray tex, SamplerState smp, midf2 uv, uint arrayIdx, midf4 weights, midf3 normal ) + { + midf3 tangentNormal = getTSNormal( tex, smp, uv, arrayIdx ) * weights.@insertpiece( detail_swizzle@n ); + tangentNormal.y = -tangentNormal.y; + + midf3 worldNormal = BlendTriplanarNormal( tangentNormal, normal.xzy ).xzy; + worldNormal.y += _h( 1.0 ) - weights.@insertpiece( detail_swizzle@n ); + + return worldNormal; + } + + // Front view projection + midf3 SampleDetailMapNm@nFrFn( Texture2DArray tex, SamplerState smp, midf2 uv, uint arrayIdx, midf4 weights, midf3 normal ) + { + midf3 tangentNormal = getTSNormal( tex, smp, uv, arrayIdx ) * weights.@insertpiece( detail_swizzle@n ); + + if( normal.z < _h( 0.0 ) ) + { + tangentNormal.x = -tangentNormal.x; + } + + midf3 worldNormal = BlendTriplanarNormal( tangentNormal, normal ); + worldNormal.z += _h( 1.0 ) - weights.@insertpiece( detail_swizzle@n ); + + return worldNormal; + } + @end @end + @end + + @property( detail_triplanar_roughness ) + @foreach( 4, n )@property( roughness_map@n ) + #define SampleRoughness@nTriplanar( tex, sampler, uv, arrayIdx ) (SampleRoughness@n( tex, \ + sampler, \ + GetTriplanarUVSd( inPs.worldPos, pixelData.worldSpaceNormal )@insertpiece( offsetDetail@n ), \ + arrayIdx ) * triplanarBlend.x + \ + \ + SampleRoughness@n( tex, \ + sampler, \ + GetTriplanarUVTp( inPs.worldPos, pixelData.worldSpaceNormal )@insertpiece( offsetDetail@n ), \ + arrayIdx ) * triplanarBlend.y + \ + \ + SampleRoughness@n( tex, \ + sampler, \ + GetTriplanarUVFr( inPs.worldPos, pixelData.worldSpaceNormal )@insertpiece( offsetDetail@n ), \ + arrayIdx ) * triplanarBlend.z) + @end @end + @end + + @property( detail_triplanar_metalness ) + @foreach( 4, n )@property( metalness_map@n ) + #define SampleMetalness@nTriplanar( tex, sampler, uv, arrayIdx ) (SampleMetalness@n( tex, \ + sampler, \ + GetTriplanarUVSd( inPs.worldPos, pixelData.worldSpaceNormal )@insertpiece( offsetDetail@n ), \ + arrayIdx ) * triplanarBlend.x + \ + \ + SampleMetalness@n( tex, \ + sampler, \ + GetTriplanarUVTp( inPs.worldPos, pixelData.worldSpaceNormal )@insertpiece( offsetDetail@n ), \ + arrayIdx ) * triplanarBlend.y + \ + \ + SampleMetalness@n( tex, \ + sampler, \ + GetTriplanarUVFr( inPs.worldPos, pixelData.worldSpaceNormal )@insertpiece( offsetDetail@n ), \ + arrayIdx ) * triplanarBlend.z) + @end @end + @end +@end + + +@piece( SampleAndApplyDetailNormalMapsTriplanar ) + @foreach( detail_maps_normal, n )@property( detail_map_nm@n ) + pixelData.normal = SampleDetailMapNm@nSd( textureMaps@value( detail_map_nm@n_idx ), + samplerState@value( detail_map_nm@n_sampler ), + UV_DETAIL_NM@n( GetTriplanarUVSd( inPs.worldPos, pixelData.worldSpaceNormal )@insertpiece( offsetDetail@n ) ), + texIndex_detailNormMapIdx@n ) * triplanarBlend.x + + + SampleDetailMapNm@nTp( textureMaps@value( detail_map_nm@n_idx ), + samplerState@value( detail_map_nm@n_sampler ), + UV_DETAIL_NM@n( GetTriplanarUVTp( inPs.worldPos, pixelData.worldSpaceNormal )@insertpiece( offsetDetail@n ) ), + texIndex_detailNormMapIdx@n ) * triplanarBlend.y + + + SampleDetailMapNm@nFr( textureMaps@value( detail_map_nm@n_idx ), + samplerState@value( detail_map_nm@n_sampler ), + UV_DETAIL_NM@n( GetTriplanarUVFr( inPs.worldPos, pixelData.worldSpaceNormal )@insertpiece( offsetDetail@n ) ), + texIndex_detailNormMapIdx@n ) * triplanarBlend.z; + @end @end +@end diff --git a/ogre2/src/media/Hlms/Terra/Any/800.PixelShader_piece_ps.any b/ogre2/src/media/Hlms/Terra/Any/800.PixelShader_piece_ps.any index fc67ebfb2..fff0d10f9 100644 --- a/ogre2/src/media/Hlms/Terra/Any/800.PixelShader_piece_ps.any +++ b/ogre2/src/media/Hlms/Terra/Any/800.PixelShader_piece_ps.any @@ -22,18 +22,27 @@ @insertpiece( DeclareBRDF_AreaLightApprox ) @end - #define SampleMetalness0( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2D( tex, sampler, uv, arrayIdx ) - #define SampleMetalness1( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2D( tex, sampler, uv, arrayIdx ) - #define SampleMetalness2( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2D( tex, sampler, uv, arrayIdx ) - #define SampleMetalness3( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2D( tex, sampler, uv, arrayIdx ) + #define SampleMetalness0( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2DF16( tex, sampler, uv, arrayIdx ) + #define SampleMetalness1( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2DF16( tex, sampler, uv, arrayIdx ) + #define SampleMetalness2( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2DF16( tex, sampler, uv, arrayIdx ) + #define SampleMetalness3( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2DF16( tex, sampler, uv, arrayIdx ) - #define SampleRoughness0( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2D( tex, sampler, uv, arrayIdx ) - #define SampleRoughness1( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2D( tex, sampler, uv, arrayIdx ) - #define SampleRoughness2( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2D( tex, sampler, uv, arrayIdx ) - #define SampleRoughness3( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2D( tex, sampler, uv, arrayIdx ) + #define SampleRoughness0( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2DF16( tex, sampler, uv, arrayIdx ) + #define SampleRoughness1( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2DF16( tex, sampler, uv, arrayIdx ) + #define SampleRoughness2( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2DF16( tex, sampler, uv, arrayIdx ) + #define SampleRoughness3( tex, sampler, uv, arrayIdx ) OGRE_SampleArray2DF16( tex, sampler, uv, arrayIdx ) #define OGRE_UNPACK_X_2x16( packedInt ) ((packedInt) & 0x0000FFFFu) #define OGRE_UNPACK_Y_2x16( packedInt ) ((packedInt) >> 16u) + + @insertpiece( DeclDetailTriplanarFuncs ) + + @property( detail_triplanar ) + midf3 pow3( midf3 v, midf e ) + { + return midf3_c( pow( v.x, e ), pow( v.y, e ), pow( v.z, e ) ); + } + @end @end //----------------------------------------------------------------------------- @@ -103,27 +112,23 @@ texIndex_diffuseIdx ); @else /// If there are no diffuse maps, we must initialize it to some value. - pixelData.diffuse.xyzw = float4( 1, 1, 1, 1 ); + pixelData.diffuse.xyzw = midf4_c( 1, 1, 1, 1 ); @end @foreach( detail_maps_diffuse, n ) - @property( !detail_map@n )float3 detailCol@n = float3( 0.0f, 0.0f, 0.0f );@end + @property( !detail_map@n )midf3 detailCol@n = midf3_c( 0.0f, 0.0f, 0.0f );@end @end @property( !detail_maps_diffuse && !detail_maps_normal ) - float4 detailWeights = float4( 0.25f, 0.25f, 0.25f, 0.25f ); - @insertpiece( gz_weights ) + midf4 detailWeights = midf4_c( 0.25f, 0.25f, 0.25f, 0.25f ); @else - // GZ CUSTOMIZE BEGIN - //pixelData.diffuse.xyz *= (detailCol0.xyz * detailWeights.x + detailCol1.xyz * detailWeights.y) + - // (detailCol2.xyz * detailWeights.z + detailCol3.xyz * detailWeights.w); - @insertpiece( gz_weights ) - // GZ CUSTOMIZE END + pixelData.diffuse.xyz *= (detailCol0.xyz * detailWeights.x + detailCol1.xyz * detailWeights.y) + + (detailCol2.xyz * detailWeights.z + detailCol3.xyz * detailWeights.w); @end /// Apply the material's diffuse over the textures - pixelData.diffuse.xyz *= material.kD.xyz; + pixelData.diffuse.xyz *= midf3_c( material.kD.xyz ); @end @undefpiece( SampleSpecularMap ) @@ -131,31 +136,23 @@ /// SPECUlAR MAP @foreach( 4, n ) @property( metalness_map@n ) - float metalness@n = SampleMetalness@n( textureMaps@value( metalness_map@n_idx ), - samplerState@value(metalness_map@n_sampler), - inPs.uv0.xy * material.detailOffsetScale[@n].zw + - material.detailOffsetScale[@n].xy, - texIndex_detailMetalnessIdx@n ).x; + midf metalness@n = SampleMetalness@n@property( detail_triplanar_metalness )Triplanar@end ( textureMaps@value( metalness_map@n_idx ), + samplerState@value(metalness_map@n_sampler), + @property( detail_triplanar )GetTriplanarUVTp( inPs.worldPos, pixelData.worldSpaceNormal )@else inPs.uv0.xy@end * material.detailOffsetScale[@n].zw + + material.detailOffsetScale[@n].xy, + texIndex_detailMetalnessIdx@n ).x; @else - float metalness@n = 0; + midf metalness@n = _h( 1.0 ); @end @end - pixelData.specular.xyz = float3( 1.0f, 1.0f, 1.0f ); - - // GZ CUSTOMIZE BEGIN - // float metalness = (metalness0 * detailWeights.x * material.metalness.x + - // metalness1 * detailWeights.y * material.metalness.y) + - // (metalness2 * detailWeights.z * material.metalness.z + - // metalness3 * detailWeights.w * material.metalness.w); - float metalness = 0.0f; - metalness = lerp( metalness, metalness0, detailWeights.x ); - metalness = lerp( metalness, metalness1, detailWeights.y ); - metalness = lerp( metalness, metalness2, detailWeights.z ); - metalness = lerp( metalness, metalness3, detailWeights.w ); - // GZ CUSTOMIZE END - - pixelData.F0 = lerp( float3( 0.03f, 0.03f, 0.03f ), pixelData.diffuse.xyz * 3.14159f, metalness ); + pixelData.specular.xyz = midf3_c( 1.0f, 1.0f, 1.0f ); + midf metalness = (metalness0 * detailWeights.x * midf_c( material.metalness.x ) + + metalness1 * detailWeights.y * midf_c( material.metalness.y )) + + (metalness2 * detailWeights.z * midf_c( material.metalness.z ) + + metalness3 * detailWeights.w * midf_c( material.metalness.w )); + + pixelData.F0 = lerp( midf3_c( 0.03f, 0.03f, 0.03f ), pixelData.diffuse.xyz * _h( 3.14159f ), metalness ); pixelData.diffuse.xyz = pixelData.diffuse.xyz - pixelData.diffuse.xyz * metalness; @end @@ -164,55 +161,63 @@ /// ROUGHNESS MAP @foreach( 4, n ) @property( roughness_map@n ) - float roughness@n = SampleRoughness@n( textureMaps@value( roughness_map@n_idx ), - samplerState@value(roughness_map@n_sampler), - inPs.uv0.xy * material.detailOffsetScale[@n].zw + - material.detailOffsetScale[@n].xy, - texIndex_detailRoughnessIdx@n ).x; + midf roughness@n = SampleRoughness@n@property( detail_triplanar_roughness )Triplanar@end ( textureMaps@value( roughness_map@n_idx ), + samplerState@value(roughness_map@n_sampler), + @property( detail_triplanar )GetTriplanarUVTp( inPs.worldPos, pixelData.worldSpaceNormal )@else inPs.uv0.xy@end * material.detailOffsetScale[@n].zw + + material.detailOffsetScale[@n].xy, + texIndex_detailRoughnessIdx@n ).x; @else - float roughness@n = 0; + midf roughness@n = _h( 1.0 ); @end @end - // GZ CUSTOMIZE BEGIN - // pixelData.perceptualRoughness = (roughness0 * detailWeights.x * material.roughness.x + - // roughness1 * detailWeights.y * material.roughness.y) + - // (roughness2 * detailWeights.z * material.roughness.z + - // roughness3 * detailWeights.w * material.roughness.w); - float roughness = 1.0f; - roughness = lerp( roughness, roughness0, detailWeights.x ); - roughness = lerp( roughness, roughness1, detailWeights.y ); - roughness = lerp( roughness, roughness2, detailWeights.z ); - roughness = lerp( roughness, roughness3, detailWeights.w ); - pixelData.perceptualRoughness = roughness; - // GZ CUSTOMIZE END + pixelData.perceptualRoughness = (roughness0 * detailWeights.x * midf_c( material.roughness.x ) + + roughness1 * detailWeights.y * midf_c( material.roughness.y )) + + (roughness2 * detailWeights.z * midf_c( material.roughness.z ) + + roughness3 * detailWeights.w * midf_c( material.roughness.w )); @property( perceptual_roughness ) - pixelData.roughness = max( pixelData.perceptualRoughness * pixelData.perceptualRoughness, 0.001f ); + pixelData.roughness = max( pixelData.perceptualRoughness * pixelData.perceptualRoughness, _h( 0.001f ) ); @else - pixelData.roughness = max( pixelData.perceptualRoughness, 0.001f ); + pixelData.roughness = max( pixelData.perceptualRoughness, _h( 0.001f ) ); @end @end @undefpiece( LoadNormalData ) @piece( LoadNormalData ) // Geometric normal - pixelData.geomNormal = OGRE_Sample( terrainNormals, samplerStateTerra, inPs.uv0.xy ).xyz * 2.0 - 1.0; + pixelData.geomNormal = OGRE_SampleF16( terrainNormals, samplerStateTerra, inPs.uv0.xy ).xyz * _h( 2.0 ) - _h( 1.0 ); @property( z_up ) - pixelData.geomNormal.yz = float2( -pixelData.geomNormal.z, pixelData.geomNormal.y ); + pixelData.geomNormal.yz = midf2_c( -pixelData.geomNormal.z, pixelData.geomNormal.y ); @end - pixelData.geomNormal = mul( pixelData.geomNormal, toFloat3x3( passBuf.view ) ); + + @property( detail_triplanar ) + pixelData.worldSpaceNormal = pixelData.geomNormal; + // https://bgolus.medium.com/normal-mapping-for-a-triplanar-shader-10bf39dca05a + midf3 triplanarBlend = pow3( pixelData.worldSpaceNormal, _h( 4.0 ) ); + triplanarBlend /= dot( triplanarBlend, midf3_c( 1.0, 1.0, 1.0 ) ); + @end + + pixelData.geomNormal = mul( pixelData.geomNormal, toMidf3x3( passBuf.view ) ); + @property( normal_map ) //Get the TBN matrix - float3 viewSpaceUnitX = mul( float3( 1, 0, 0 ) , toFloat3x3( passBuf.view ) ); - float3 vTangent = normalize( cross( pixelData.geomNormal, viewSpaceUnitX ) ); - float3 vBinormal = cross( vTangent, pixelData.geomNormal ); - float3x3 TBN = buildFloat3x3( vBinormal, vTangent, pixelData.geomNormal ); + midf3 viewSpaceUnitX = mul( midf3_c( 1, 0, 0 ), toMidf3x3( passBuf.view ) ); + midf3 vTangent = normalize( cross( pixelData.geomNormal, viewSpaceUnitX ) ); + midf3 vBinormal = cross( vTangent, pixelData.geomNormal ); + midf3x3 TBN = buildMidf3x3( vBinormal, vTangent, pixelData.geomNormal ); @end @end @piece( DefaultTerraBodyPS ) PixelData pixelData; + @property( hlms_emulate_clip_distances && hlms_global_clip_planes && hlms_pso_clip_distances && syntax == glslvk) + @foreach( hlms_pso_clip_distances, n ) + if( inPs.clipDistance@n < 0.0 ) + discard; + @end + @end + @insertpiece( LoadMaterial ) @insertpiece( UnpackTextureIndices0 ) @insertpiece( UnpackTextureIndices1 ) @@ -221,6 +226,11 @@ @insertpiece( LoadDetailWeights ) + @property( !hlms_use_prepass ) + @insertpiece( LoadNormalData ) + @insertpiece( SampleAndApplyDetailNormalMaps@property( detail_triplanar_normal )Triplanar@end ) + @end + @insertpiece( SampleDetailMaps ) @property( !hlms_prepass ) @@ -233,15 +243,16 @@ @insertpiece( forwardPlusDoDecals ) @property( !hlms_use_prepass ) - @insertpiece( LoadNormalData ) - @insertpiece( SampleAndApplyDetailNormalMaps ) - @insertpiece( custom_ps_posSampleNormal ) @insertpiece( forwardPlusApplyDecalsNormal ) @property( normal_map ) - pixelData.normal = normalize( mul( TBN, pixelData.normal ) ); + @property( detail_triplanar_normal ) + pixelData.normal = mul( pixelData.normal, toMidf3x3( passBuf.view ) ); + @else + pixelData.normal = normalize( mul( TBN, pixelData.normal ) ); + @end @end @insertpiece( DoDirectionalShadowMaps ) @@ -284,14 +295,14 @@ int gBufSubsample = int( findLSB( sampleMask ) ); - pixelData.normal = normalize( OGRE_Load2DMS( gBuf_normals, iFragCoord, gBufSubsample ).xyz * 2.0 - 1.0 ); - float2 shadowRoughness = OGRE_Load2DMS( gBuf_shadowRoughness, iFragCoord, gBufSubsample ).xy; + pixelData.normal = normalize( OGRE_Load2DMSF16( gBuf_normals, iFragCoord, gBufSubsample ).xyz * _h( 2.0 ) - _h( 1.0 ) ); + midf2 shadowRoughness = OGRE_Load2DMSF16( gBuf_shadowRoughness, iFragCoord, gBufSubsample ).xy; @else - pixelData.normal = normalize( OGRE_Load2D( gBuf_normals, iFragCoord, 0 ).xyz * 2.0 - 1.0 ); - float2 shadowRoughness = OGRE_Load2D( gBuf_shadowRoughness, iFragCoord, 0 ).xy; + pixelData.normal = normalize( OGRE_Load2DF16( gBuf_normals, iFragCoord, 0 ).xyz * _h( 2.0 ) - _h( 1.0 ) ); + midf2 shadowRoughness = OGRE_Load2DF16( gBuf_shadowRoughness, iFragCoord, 0 ).xy; @end - float fShadow = shadowRoughness.x; + midf fShadow = shadowRoughness.x; @property( roughness_map ) pixelData.roughness = shadowRoughness.y * 0.98 + 0.02; @@ -304,9 +315,9 @@ @insertpiece( custom_ps_preLights ) @property( !custom_disable_directional_lights ) - float fTerrainShadow = OGRE_Sample( terrainShadows, samplerStateTerra, inPs.uv0.xy ).x; + midf fTerrainShadow = OGRE_SampleF16( terrainShadows, samplerStateTerra, inPs.uv0.xy ).x; @property( !(hlms_pssm_splits || (!hlms_pssm_splits && hlms_num_shadow_map_lights && hlms_lights_directional)) ) - float fShadow = 1.0f; + midf fShadow = _h( 1.0f ); @end fShadow *= fTerrainShadow; @@ -322,8 +333,8 @@ @insertpiece( forward3dLighting ) @property( needs_env_brdf && (use_envprobe_map || hlms_use_ssr || use_planar_reflections || vct_num_probes) ) - pixelData.envColourS = float3( 0, 0, 0 ); - pixelData.envColourD = float3( 0, 0, 0 ); + pixelData.envColourS = midf3_c( 0, 0, 0 ); + pixelData.envColourD = midf3_c( 0, 0, 0 ); @end @insertpiece( applyVoxelConeTracing ) @@ -360,25 +371,41 @@ if( vctSpecular.w == 0 ) { @end - pixelData.envColourS += lerp( passBuf.ambientLowerHemi.xyz, passBuf.ambientUpperHemi.xyz, ambientWD ); - pixelData.envColourD += lerp( passBuf.ambientLowerHemi.xyz, passBuf.ambientUpperHemi.xyz, ambientWS ); - @property( vct_num_probes ) + pixelData.envColourS += lerp( midf3_c( passBuf.ambientLowerHemi.xyz ), + midf3_c( passBuf.ambientUpperHemi.xyz ), ambientWD ); + pixelData.envColourD += lerp( midf3_c( passBuf.ambientLowerHemi.xyz ), + midf3_c( passBuf.ambientUpperHemi.xyz ), ambientWS ); + @property( vct_num_probes ) } @end - @else - pixelData.envColourS = lerp( passBuf.ambientLowerHemi.xyz, passBuf.ambientUpperHemi.xyz, ambientWD ); - pixelData.envColourD = lerp( passBuf.ambientLowerHemi.xyz, passBuf.ambientUpperHemi.xyz, ambientWS ); - @end - @end - @property( ambient_fixed && vct_num_probes ) - //Only use ambient lighting if object is outside any VCT probe - finalColour += vctSpecular.w == 0 ? float3( 0, 0, 0 ) : - (passBuf.ambientUpperHemi.xyz * pixelData.diffuse.xyz); + @else + pixelData.envColourS = lerp( midf3_c( passBuf.ambientLowerHemi.xyz ), + midf3_c( passBuf.ambientUpperHemi.xyz ), ambientWD ); + pixelData.envColourD = lerp( midf3_c( passBuf.ambientLowerHemi.xyz ), + midf3_c( passBuf.ambientUpperHemi.xyz ), ambientWS ); @end + @end + @property( ambient_fixed && vct_num_probes ) + //Only use ambient lighting if object is outside any VCT probe + finalColour += vctSpecular.w == 0 ? midf3_c( 0, 0, 0 ) : + (midf3_c( passBuf.ambientUpperHemi.xyz ) * pixelData.diffuse.xyz); + @end @property( needs_env_brdf ) @insertpiece( BRDF_EnvMap ) @end + + @property( hlms_fog ) + const float distToCamera = length( inPs.pos.xyz ); + const midf luminance = dot( finalColour.xyz, + midf3_c( _h( 0.212655 ), _h( 0.715158 ), _h( 0.072187 ) ) ); + const midf lumFogWeight = max( exp2( atmoSettings.fogBreakFalloff * luminance + + atmoSettings.fogBreakMinBrightness ), + _h( 0.0 ) ); + midf fogWeight = midf_c( exp2( -distToCamera * atmoSettings.fogDensity ) ); + fogWeight = lerp( _h( 1.0 ), fogWeight, lumFogWeight ); + finalColour.xyz = lerp( inPs.fog.xyz, finalColour.xyz, fogWeight ); + @end @end ///!hlms_prepass @property( !hlms_render_depth_only ) @@ -392,27 +419,27 @@ @property( hlms_alphablend ) @property( use_texture_alpha ) - outPs_colour0.w = material.F0.w * pixelData.diffuse.w; + outPs_colour0.w = _h( material.F0.w ) * pixelData.diffuse.w; @else - outPs_colour0.w = material.F0.w; + outPs_colour0.w = _h( material.F0.w ); @end @else - outPs_colour0.w = 1.0; + outPs_colour0.w = _h( 1.0 ); @end @property( debug_pssm_splits ) - outPs_colour0.xyz = mix( outPs_colour0.xyz, debugPssmSplit.xyz, 0.2f ); + outPs_colour0.xyz = lerp( outPs_colour0.xyz, debugPssmSplit.xyz, _h( 0.2f ) ); @end - @property( hlms_gen_normals_gbuffer ) - outPs_normals = float4( pixelData.normal * 0.5 + 0.5, 1.0 ); + @property( hlms_gen_normals_gbuffer ) + outPs_normals = midf4_c( pixelData.normal * _h( 0.5 ) + _h( 0.5 ), 1.0 ); @end @else - outPs_normals = float4( pixelData.normal * 0.5 + 0.5, 1.0 ); + outPs_normals = midf4_c( pixelData.normal * _h( 0.5 ) + _h( 0.5 ), 1.0 ); @property( hlms_pssm_splits ) - outPs_shadowRoughness = float2( fShadow, (pixelData.roughness - 0.02) * 1.02040816 ); + outPs_shadowRoughness = midf2_c( fShadow, (pixelData.roughness - 0.02) * 1.02040816 ); @end @property( !hlms_pssm_splits ) - outPs_shadowRoughness = float2( 1.0, (pixelData.roughness - 0.02) * 1.02040816 ); + outPs_shadowRoughness = midf2_c( 1.0, (pixelData.roughness - 0.02) * 1.02040816 ); @end @end @end diff --git a/ogre2/src/media/Hlms/Terra/Any/800.VertexShader_piece_vs.any b/ogre2/src/media/Hlms/Terra/Any/800.VertexShader_piece_vs.any index 345a0d002..383e6e688 100644 --- a/ogre2/src/media/Hlms/Terra/Any/800.VertexShader_piece_vs.any +++ b/ogre2/src/media/Hlms/Terra/Any/800.VertexShader_piece_vs.any @@ -20,8 +20,11 @@ @insertpiece( TerraMaterialStructDecl ) #define material materialArray[0] @end + @insertpiece( AtmosphereNprSkyStructDecl ) @insertpiece( custom_vs_uniformStructDeclaration ) // END UNIFORM DECLARATION + + @insertpiece( DeclAtmosphereNprSkyFuncs ) @end @piece( VertexTerraTransform ) @@ -111,6 +114,10 @@ worldPos.yz = float2( -worldPos.z, worldPos.y ); @end + @property( detail_triplanar ) + outVs.worldPos = worldPos.xyz; + @end + @insertpiece( VertexTerraTransform ) outVs.uv0.xy = float2( uVertexPos.xy ) * float2( cellData.pos.w, cellData.scale.w ); @@ -125,11 +132,9 @@ @insertpiece( DoShadowCasterVS ) @end -@property( syntax != metal ) - @property( (!hlms_shadowcaster || alpha_test) && !lower_gpu_overhead ) - outVs.drawId = inVs_drawId; - @end -@else + @insertpiece( DoAtmosphereNprSky ) + +@property( syntax == metal || lower_gpu_overhead ) @property( hlms_fine_light_mask || hlms_forwardplus_fine_light_mask ) outVs.objLightMask = worldMaterialIdx[inVs_drawId].z; @end @@ -137,12 +142,20 @@ @property( use_planar_reflections ) outVs.planarReflectionIdx = (ushort)(worldMaterialIdx[inVs_drawId].w); @end +@else + @property( (!hlms_shadowcaster || alpha_test) && !lower_gpu_overhead ) + outVs.drawId = inVs_drawId; + @end @end @property( hlms_use_prepass_msaa > 1 ) outVs.zwDepth.xy = outVs_Position.zw; @end + @property( hlms_global_clip_planes ) + outVs_clipDistance0 = dot( float4( worldPos.xyz, 1.0 ), passBuf.clipPlane0.xyzw ); + @end + @property( hlms_instanced_stereo ) outVs_viewportIndex = int( inVs_stereoDrawId & 0x01u ); @end diff --git a/ogre2/src/media/Hlms/Terra/GLSL/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.glsl b/ogre2/src/media/Hlms/Terra/GLSL/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.glsl index 95b42365b..0f80f6605 100644 --- a/ogre2/src/media/Hlms/Terra/GLSL/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.glsl +++ b/ogre2/src/media/Hlms/Terra/GLSL/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.glsl @@ -1,12 +1,12 @@ @property( !hlms_shadowcaster && terra_enabled ) -@piece( custom_VStoPS_terra ) - float terrainShadow; +@piece( custom_VStoPS ) + midf terrainShadow; @end /// Extra per-pass global data we need for applying our /// shadows to regular objects, passed to all PBS shaders. -@piece( custom_passBuffer_terra ) +@piece( custom_passBuffer ) vec4 terraOrigin; //Normalized. i.e. -terrainOrigin / terrainDimensions //.xz = terrain 1.0 / XZ dimensions. //.y = 1.0 / terrainHeight; @@ -14,7 +14,7 @@ @end /// Add the shadows' texture to the vertex shader -@piece( custom_vs_uniformDeclaration_terra ) +@piece( custom_vs_uniformDeclaration ) vulkan_layout( ogre_t@value(terrainShadows) ) uniform texture2D terrainShadows; vulkan( layout( ogre_s@value(terrainShadows) ) uniform sampler terrainShadowSampler ); @end @@ -22,7 +22,7 @@ /// Evaluate the shadow based on world XZ position & height in the vertex shader. /// Doing it at the pixel shader level would be more accurate, but the difference /// is barely noticeable, and slower -@piece( custom_vs_posExecution_terra ) +@piece( custom_vs_posExecution ) @property( z_up ) vec3 terraWorldPos = vec3( worldPos.x, -worldPos.z, worldPos.y ); @else @@ -33,7 +33,7 @@ passBuf.terraOrigin.xz, 0 ).xyz; float terraHeightWeight = terraWorldPos.y * passBuf.invTerraBounds.y + passBuf.terraOrigin.y; terraHeightWeight = (terraHeightWeight - terraShadowData.y) * terraShadowData.z * 1023.0; - outVs.terrainShadow = mix( terraShadowData.x, 1.0, clamp( terraHeightWeight, 0.0, 1.0 ) ); + outVs.terrainShadow = mix( midf_c( terraShadowData.x ), _h( 1.0 ), midf_c( saturate( terraHeightWeight ) ) ); @end @property( hlms_lights_directional && hlms_num_shadow_map_lights ) diff --git a/ogre2/src/media/Hlms/Terra/GLSL/PixelShader_ps.glsl b/ogre2/src/media/Hlms/Terra/GLSL/PixelShader_ps.glsl index 186ec618f..7df903db0 100644 --- a/ogre2/src/media/Hlms/Terra/GLSL/PixelShader_ps.glsl +++ b/ogre2/src/media/Hlms/Terra/GLSL/PixelShader_ps.glsl @@ -28,7 +28,7 @@ in block @property( !hlms_render_depth_only ) @property( !hlms_shadowcaster ) @property( !hlms_prepass ) - layout(location = @counter(rtv_target), index = 0) out vec4 outColour; + layout(location = @counter(rtv_target), index = 0) out midf4 outColour; @end @property( hlms_gen_normals_gbuffer ) #define outPs_normals outNormals @@ -67,8 +67,8 @@ in block in vec4 gl_FragCoord; @end -vulkan_layout( ogre_t@value(terrainNormals) ) uniform texture2D terrainNormals; -vulkan_layout( ogre_t@value(terrainShadows) ) uniform texture2D terrainShadows; +vulkan_layout( ogre_t@value(terrainNormals) ) midf_tex uniform texture2D terrainNormals; +vulkan_layout( ogre_t@value(terrainShadows) ) midf_tex uniform texture2D terrainShadows; vulkan( layout( ogre_s@value(terrainNormals) ) uniform sampler samplerStateTerra ); @property( hlms_forwardplus ) @@ -76,21 +76,21 @@ vulkan( layout( ogre_s@value(terrainNormals) ) uniform sampler samplerStateTerra ReadOnlyBufferF( @value(f3dLightList), float4, f3dLightList ); @end @property( irradiance_volumes ) - vulkan_layout( ogre_t@value(irradianceVolume) ) uniform texture3D irradianceVolume; - vulkan( layout( ogre_s@value(irradianceVolume) )uniform sampler irradianceVolumeSampler ); + vulkan_layout( ogre_t@value(irradianceVolume) ) midf_tex uniform texture3D irradianceVolume; + vulkan( layout( ogre_s@value(irradianceVolume) )uniform sampler irradianceVolumeSampler ); @end @foreach( num_textures, n ) - vulkan_layout( ogre_t@value(textureMaps@n) ) uniform texture2DArray textureMaps@n;@end + vulkan_layout( ogre_t@value(textureMaps@n) ) midf_tex uniform texture2DArray textureMaps@n;@end @property( use_envprobe_map ) @property( !hlms_enable_cubemaps_auto ) - vulkan_layout( ogre_t@value(texEnvProbeMap) ) uniform textureCube texEnvProbeMap; + vulkan_layout( ogre_t@value(texEnvProbeMap) ) midf_tex uniform textureCube texEnvProbeMap; @else @property( !hlms_cubemaps_use_dpm ) - vulkan_layout( ogre_t@value(texEnvProbeMap) ) uniform textureCubeArray texEnvProbeMap; + vulkan_layout( ogre_t@value(texEnvProbeMap) ) midf_tex uniform textureCubeArray texEnvProbeMap; @else - vulkan_layout( ogre_t@value(texEnvProbeMap) ) uniform texture2DArray texEnvProbeMap; + vulkan_layout( ogre_t@value(texEnvProbeMap) ) midf_tex uniform texture2DArray texEnvProbeMap; @insertpiece( DeclDualParaboloidFunc ) @end @end @@ -108,28 +108,7 @@ vulkan( layout( ogre_s@value(terrainNormals) ) uniform sampler samplerStateTerra @insertpiece( DeclParallaxLocalCorrect ) @end -// The DeclDecalsSamplers insertpiece does not seem to do anything. -// The contents from DeclDecalsSamplers are manually pasted below -// This prevents a crash when there are decals in the scene -// @insertpiece( DeclDecalsSamplers ) -@property( hlms_forwardplus ) -@property( hlms_enable_decals ) - @piece( DeclDecalsSamplers ) - @property( syntax == glslvk ) - layout( ogre_s@value(decalsSampler) ) uniform sampler decalsSampler; - @end - @property( hlms_decals_diffuse ) vulkan_layout( ogre_t@value(decalsDiffuseTex) ) uniform texture2DArray decalsDiffuseTex;@end - @property( hlms_decals_normals )vulkan_layout( ogre_t@value(decalsNormalsTex) ) uniform texture2DArray decalsNormalsTex;@end - @property( hlms_decals_diffuse == hlms_decals_emissive ) - #define decalsEmissiveTex decalsDiffuseTex - @end - @property( hlms_decals_emissive && hlms_decals_diffuse != hlms_decals_emissive ) - vulkan_layout( ogre_t@value(decalsEmissiveTex) ) uniform texture2DArray decalsEmissiveTex; - @end - @end -@end -@end - +@insertpiece( DeclDecalsSamplers ) @insertpiece( DeclShadowMapMacros ) @insertpiece( DeclShadowSamplers ) diff --git a/ogre2/src/media/Hlms/Terra/GLSL/VertexShader_vs.glsl b/ogre2/src/media/Hlms/Terra/GLSL/VertexShader_vs.glsl index 6c8a1cee0..35d9bf77f 100644 --- a/ogre2/src/media/Hlms/Terra/GLSL/VertexShader_vs.glsl +++ b/ogre2/src/media/Hlms/Terra/GLSL/VertexShader_vs.glsl @@ -4,7 +4,7 @@ out gl_PerVertex { vec4 gl_Position; -@property( hlms_pso_clip_distances ) +@property( hlms_pso_clip_distances && !hlms_emulate_clip_distances ) float gl_ClipDistance[@value(hlms_pso_clip_distances)]; @end }; diff --git a/ogre2/src/media/Hlms/Terra/GLSLES/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.glsl b/ogre2/src/media/Hlms/Terra/GLSLES/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.glsl new file mode 100644 index 000000000..0a13d01d6 --- /dev/null +++ b/ogre2/src/media/Hlms/Terra/GLSLES/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.glsl @@ -0,0 +1,38 @@ +@property( !hlms_shadowcaster && terra_enabled ) + +@piece( custom_VStoPS ) + float terrainShadow; +@end + +/// Extra per-pass global data we need for applying our +/// shadows to regular objects, passed to all PBS shaders. +@piece( custom_passBuffer ) + vec4 terraOrigin; //Normalized. i.e. -terrainOrigin / terrainDimensions + //.xz = terrain 1.0 / XZ dimensions. + //.y = 1.0 / terrainHeight; + vec4 invTerraBounds; +@end + +/// Add the shadows' texture to the vertex shader +@piece( custom_vs_uniformDeclaration ) + uniform sampler2D terrainShadows; +@end + +/// Evaluate the shadow based on world XZ position & height in the vertex shader. +/// Doing it at the pixel shader level would be more accurate, but the difference +/// is barely noticeable, and slower +@piece( custom_vs_posExecution ) + vec3 terraShadowData = textureLod( terrainShadows, worldPos.xz * passBuf.invTerraBounds.xz + passBuf.terraOrigin.xz, 0 ).xyz; + float terraHeightWeight = worldPos.y * passBuf.invTerraBounds.y + passBuf.terraOrigin.y; + terraHeightWeight = (terraHeightWeight - terraShadowData.y) * terraShadowData.z * 1023.0; + outVs.terrainShadow = mix( terraShadowData.x, 1.0, clamp( terraHeightWeight, 0.0, 1.0 ) ); +@end + +@property( hlms_lights_directional ) + @piece( custom_ps_preLights )fShadow *= inPs.terrainShadow;@end +@end @property( !hlms_num_shadow_map_lights ) + @piece( custom_ps_preLights )float fShadow = inPs.terrainShadow;@end + @piece( DarkenWithShadowFirstLight )* fShadow@end +@end + +@end diff --git a/ogre2/src/media/Hlms/Terra/GLSLES/PixelShader_ps.glsl b/ogre2/src/media/Hlms/Terra/GLSLES/PixelShader_ps.glsl new file mode 100644 index 000000000..a30680158 --- /dev/null +++ b/ogre2/src/media/Hlms/Terra/GLSLES/PixelShader_ps.glsl @@ -0,0 +1,334 @@ +@property( false ) +@insertpiece( SetCrossPlatformSettings ) +@insertpiece( SetCompatibilityLayer ) + +layout(std140) uniform; +#define FRAG_COLOR 0 +layout(location = FRAG_COLOR) out vec4 outColour; + +uniform sampler2D terrainNormals; + +in block +{ +@insertpiece( Terra_VStoPS_block ) +} inPs; + +void main() +{ + outColour = vec4( inPs.uv0.xy, 0.0, 1.0 ); +} + +@end +@property( !false ) +@insertpiece( SetCrossPlatformSettings ) +@property( GL3+ < 430 ) + @property( hlms_tex_gather )#extension GL_ARB_texture_gather: require@end +@end + +@property( hlms_amd_trinary_minmax )#extension GL_AMD_shader_trinary_minmax: require@end +@insertpiece( SetCompatibilityLayer ) + +layout(std140) uniform; +#define FRAG_COLOR 0 +layout(location = FRAG_COLOR) out vec4 outColour; + +@property( hlms_vpos ) +in vec4 gl_FragCoord; +@end + +// START UNIFORM DECLARATION +@insertpiece( PassDecl ) +@insertpiece( TerraMaterialDecl ) +@insertpiece( TerraInstanceDecl ) +@insertpiece( custom_ps_uniformDeclaration ) +// END UNIFORM DECLARATION +in block +{ +@insertpiece( Terra_VStoPS_block ) +} inPs; + +uniform sampler2D terrainNormals; +uniform sampler2D terrainShadows; + +@property( hlms_forwardplus ) +/*layout(binding = 1) */uniform usamplerBuffer f3dGrid; +/*layout(binding = 2) */uniform samplerBuffer f3dLightList; +@end +@property( num_textures )uniform sampler2DArray textureMaps[@value( num_textures )];@end +@property( envprobe_map )uniform samplerCube texEnvProbeMap;@end + +vec4 diffuseCol; +@insertpiece( FresnelType ) F0; +float ROUGHNESS; + +vec3 nNormal; + +@property( hlms_lights_spot_textured )@insertpiece( DeclQuat_zAxis ) +vec3 qmul( vec4 q, vec3 v ) +{ + return v + 2.0 * cross( cross( v, q.xyz ) + q.w * v, q.xyz ); +} +@end + +@property( detail_maps_normal )vec3 getTSDetailNormal( sampler2DArray normalMap, vec3 uv ) +{ + vec3 tsNormal; +@property( signed_int_textures ) + //Normal texture must be in U8V8 or BC5 format! + tsNormal.xy = texture( normalMap, uv ).xy; +@end @property( !signed_int_textures ) + //Normal texture must be in LA format! + tsNormal.xy = texture( normalMap, uv ).xw * 2.0 - 1.0; +@end + tsNormal.z = sqrt( max( 0.0, 1.0 - tsNormal.x * tsNormal.x - tsNormal.y * tsNormal.y ) ); + + return tsNormal; +} + @foreach( 4, n ) + @property( normal_weight_detail@n ) + @piece( detail@n_nm_weight_mul ) * material.normalWeights.@insertpiece( detail_swizzle@n )@end + @end + @end +@end + +@insertpiece( DeclareBRDF ) + +@insertpiece( DeclShadowMapMacros ) +@insertpiece( DeclShadowSamplers ) +@insertpiece( DeclShadowSamplingFuncs ) + +void main() +{ + @insertpiece( custom_ps_preExecution ) + + @insertpiece( custom_ps_posMaterialLoad ) + +//Prepare weight map for the detail maps. +@property( detail_weight_map ) + vec4 detailWeights = texture( textureMaps[@value( detail_weight_map_idx )], + vec3( inPs.uv0.xy, @value(detail_weight_map_idx_slice) ) ); +@end @property( !detail_weight_map ) + vec4 detailWeights = vec4( 1.0, 1.0, 1.0, 1.0 ); +@end + +@property( diffuse_map ) + diffuseCol = texture( textureMaps[@value( diffuse_map_idx )], vec3( inPs.uv0.xy, @value(diffuse_map_idx_slice) ) ); +@end + + /// Sample detail maps +@foreach( 4, n ) + @property( detail_map@n ) + vec3 detailCol@n = texture( textureMaps[@value(detail_map@n_idx)], + vec3( inPs.uv0.xy * material.detailOffsetScale[@value(currOffsetDetail)].zw + + material.detailOffsetScale[@value(currOffsetDetail)].xy, + @value(detail_map@n_idx_slice) ) ).xyz; + @end @property( !detail_map@n ) + vec3 detailCol@n = vec3( 0, 0, 0 ); + @end + + @property( metalness_map@n ) + float metalness@n = texture( textureMaps[@value( metalness_map@n_idx )], + vec3( inPs.uv0.xy * material.detailOffsetScale[@value(currOffsetDetail)].zw + + material.detailOffsetScale[@value(currOffsetDetail)].xy, + @value( metalness_map@n_idx_slice ) ) ).x; + @end @property( !metalness_map@n ) + float metalness@n = 0; + @end + + @property( roughness_map@n ) + float roughness@n = texture( textureMaps[@value( roughness_map@n_idx )], + vec3( inPs.uv0.xy * material.detailOffsetScale[@value(currOffsetDetail)].zw + + material.detailOffsetScale[@value(currOffsetDetail)].xy, + @value( roughness_map@n_idx_slice ) ) ).x; + @end @property( !roughness_map@n ) + float roughness@n = 0; + @end + + @add( currOffsetDetail, 1 ) +@end + + float metalness = (metalness0 * detailWeights.x * material.metalness.x + + metalness1 * detailWeights.y * material.metalness.y) + + (metalness2 * detailWeights.z * material.metalness.z + + metalness3 * detailWeights.w * material.metalness.w); + + ROUGHNESS = (roughness0 * detailWeights.x * material.roughness.x + + roughness1 * detailWeights.y * material.roughness.y) + + (roughness2 * detailWeights.z * material.roughness.z + + roughness3 * detailWeights.w * material.roughness.w); + ROUGHNESS = max( ROUGHNESS, 0.02 ); + +@property( diffuse_map ) + diffuseCol.xyz *= (detailCol0 * detailWeights.x + detailCol1 * detailWeights.y) + + (detailCol2 * detailWeights.z + detailCol3 * detailWeights.w); +@end @property( !diffuse_map ) + @property( detail_maps_diffuse ) + diffuseCol.xyz = (detailCol0 * detailWeights.x + detailCol1 * detailWeights.y) + + (detailCol2 * detailWeights.z + detailCol3 * detailWeights.w); + @end @property( !detail_maps_diffuse ) + diffuseCol.xyzw = vec4( 1, 1, 1, 1 ); + @end +@end + + /// Apply the material's diffuse over the textures + diffuseCol.xyz *= material.kD.xyz; + + //Calculate F0 from metalness, and dim kD as metalness gets bigger. + F0 = mix( vec3( 0.03f ), @insertpiece( kD ).xyz * 3.14159f, metalness ); + @insertpiece( kD ).xyz = @insertpiece( kD ).xyz - @insertpiece( kD ).xyz * metalness; + +@property( !detail_maps_normal ) + // Geometric normal + nNormal = texture( terrainNormals, inPs.uv0.xy ).xyz * 2.0 - 1.0; + //nNormal.xz = texture( terrainNormals, inPs.uv0.xy ).xy; + //nNormal.y = sqrt( max( 1.0 - nNormal.x * nNormal.x - nNormal.z * nNormal.z, 0.0 ) ); + nNormal = nNormal * mat3(passBuf.view); +@end @property( detail_maps_normal ) + vec3 geomNormal = texture( terrainNormals, inPs.uv0.xy ).xyz * 2.0 - 1.0; + geomNormal = geomNormal * mat3(passBuf.view); + + //Get the TBN matrix + vec3 viewSpaceUnitX = vec3( passBuf.view[0].x, passBuf.view[1].x, passBuf.view[2].x ); + vec3 vTangent = normalize( cross( geomNormal, viewSpaceUnitX ) ); + vec3 vBinormal = cross( vTangent, geomNormal ); + mat3 TBN = mat3( vBinormal, vTangent, geomNormal ); +@end + + float fTerrainShadow = texture( terrainShadows, inPs.uv0.xy ).x; + @property( !(hlms_pssm_splits || (!hlms_pssm_splits && hlms_num_shadow_map_lights && hlms_lights_directional)) ) + float fShadow = 1.0f; + @end + @insertpiece( DoDirectionalShadowMaps ) + fShadow *= fTerrainShadow; + + /// The first iteration must initialize nNormal instead of try to merge with it. + /// Blend the detail normal maps with the main normal. +@foreach( second_valid_detail_map_nm, n, first_valid_detail_map_nm ) + vec3 vDetail = @insertpiece( SampleDetailMapNm@n ) * detailWeights.@insertpiece(detail_swizzle@n); + nNormal.xy = vDetail.xy; + nNormal.z = vDetail.z + 1.0 - detailWeights.@insertpiece(detail_swizzle@n);@end +@foreach( detail_maps_normal, n, second_valid_detail_map_nm )@property( detail_map_nm@n ) + vDetail = @insertpiece( SampleDetailMapNm@n ) * detailWeights.@insertpiece(detail_swizzle@n); + nNormal.xy += vDetail.xy; + nNormal.z *= vDetail.z + 1.0 - detailWeights.@insertpiece(detail_swizzle@n);@end @end + +@property( detail_maps_normal ) + nNormal = normalize( TBN * nNormal ); +@end + + //Everything's in Camera space +@property( hlms_lights_spot || ambient_hemisphere || envprobe_map || hlms_forwardplus ) + vec3 viewDir = normalize( -inPs.pos ); + float NdotV = clamp( dot( nNormal, viewDir ), 0.0, 1.0 );@end + +@property( !ambient_fixed ) + vec3 finalColour = vec3(0); +@end @property( ambient_fixed ) + vec3 finalColour = passBuf.ambientUpperHemi.xyz * @insertpiece( kD ).xyz; +@end + + @insertpiece( custom_ps_preLights ) + +@property( !custom_disable_directional_lights ) +@property( hlms_lights_directional ) + finalColour += BRDF( passBuf.lights[0].position.xyz, viewDir, NdotV, passBuf.lights[0].diffuse, passBuf.lights[0].specular ) @insertpiece(DarkenWithShadowFirstLight); +@end +@foreach( hlms_lights_directional, n, 1 ) + finalColour += BRDF( passBuf.lights[@n].position.xyz, viewDir, NdotV, passBuf.lights[@n].diffuse, passBuf.lights[@n].specular )@insertpiece( DarkenWithShadow );@end +@foreach( hlms_lights_directional_non_caster, n, hlms_lights_directional ) + finalColour += BRDF( passBuf.lights[@n].position.xyz, viewDir, NdotV, passBuf.lights[@n].diffuse, passBuf.lights[@n].specular );@end +@end + +@property( hlms_lights_point || hlms_lights_spot ) vec3 lightDir; + float fDistance; + vec3 tmpColour; + float spotCosAngle;@end + + //Point lights +@foreach( hlms_lights_point, n, hlms_lights_directional_non_caster ) + lightDir = passBuf.lights[@n].position.xyz - inPs.pos; + fDistance= length( lightDir ); + if( fDistance <= passBuf.lights[@n].attenuation.x ) + { + lightDir *= 1.0 / fDistance; + tmpColour = BRDF( lightDir, viewDir, NdotV, passBuf.lights[@n].diffuse, passBuf.lights[@n].specular )@insertpiece( DarkenWithShadowPoint ); + float atten = 1.0 / (0.5 + (passBuf.lights[@n].attenuation.y + passBuf.lights[@n].attenuation.z * fDistance) * fDistance ); + finalColour += tmpColour * atten; + }@end + + //Spot lights + //spotParams[@value(spot_params)].x = 1.0 / cos( InnerAngle ) - cos( OuterAngle ) + //spotParams[@value(spot_params)].y = cos( OuterAngle / 2 ) + //spotParams[@value(spot_params)].z = falloff +@foreach( hlms_lights_spot, n, hlms_lights_point ) + lightDir = passBuf.lights[@n].position.xyz - inPs.pos; + fDistance= length( lightDir ); +@property( !hlms_lights_spot_textured ) spotCosAngle = dot( normalize( inPs.pos - passBuf.lights[@n].position.xyz ), passBuf.lights[@n].spotDirection );@end +@property( hlms_lights_spot_textured ) spotCosAngle = dot( normalize( inPs.pos - passBuf.lights[@n].position.xyz ), zAxis( passBuf.lights[@n].spotQuaternion ) );@end + if( fDistance <= passBuf.lights[@n].attenuation.x && spotCosAngle >= passBuf.lights[@n].spotParams.y ) + { + lightDir *= 1.0 / fDistance; + @property( hlms_lights_spot_textured ) + vec3 posInLightSpace = qmul( spotQuaternion[@value(spot_params)], inPs.pos ); + float spotAtten = texture( texSpotLight, normalize( posInLightSpace ).xy ).x; + @end + @property( !hlms_lights_spot_textured ) + float spotAtten = clamp( (spotCosAngle - passBuf.lights[@n].spotParams.y) * passBuf.lights[@n].spotParams.x, 0.0, 1.0 ); + spotAtten = pow( spotAtten, passBuf.lights[@n].spotParams.z ); + @end + tmpColour = BRDF( lightDir, viewDir, NdotV, passBuf.lights[@n].diffuse, passBuf.lights[@n].specular )@insertpiece( DarkenWithShadow ); + float atten = 1.0 / (0.5 + (passBuf.lights[@n].attenuation.y + passBuf.lights[@n].attenuation.z * fDistance) * fDistance ); + finalColour += tmpColour * (atten * spotAtten); + }@end + +@insertpiece( forward3dLighting ) + +@property( envprobe_map || ambient_hemisphere ) + vec3 reflDir = 2.0 * dot( viewDir, nNormal ) * nNormal - viewDir; + + @property( envprobe_map ) + vec3 envColourS = textureLod( texEnvProbeMap, reflDir * passBuf.invViewMatCubemap, ROUGHNESS * 12.0 ).xyz @insertpiece( ApplyEnvMapScale );// * 0.0152587890625; + vec3 envColourD = textureLod( texEnvProbeMap, nNormal * passBuf.invViewMatCubemap, 11.0 ).xyz @insertpiece( ApplyEnvMapScale );// * 0.0152587890625; + @property( !hw_gamma_read ) //Gamma to linear space + envColourS = envColourS * envColourS; + envColourD = envColourD * envColourD; + @end + @end + @property( ambient_hemisphere ) + float ambientWD = dot( passBuf.ambientHemisphereDir.xyz, nNormal ) * 0.5 + 0.5; + float ambientWS = dot( passBuf.ambientHemisphereDir.xyz, reflDir ) * 0.5 + 0.5; + + @property( envprobe_map ) + envColourS += mix( passBuf.ambientLowerHemi.xyz, passBuf.ambientUpperHemi.xyz, ambientWD ); + envColourD += mix( passBuf.ambientLowerHemi.xyz, passBuf.ambientUpperHemi.xyz, ambientWS ); + @end @property( !envprobe_map ) + vec3 envColourS = mix( passBuf.ambientLowerHemi.xyz, passBuf.ambientUpperHemi.xyz, ambientWD ); + vec3 envColourD = mix( passBuf.ambientLowerHemi.xyz, passBuf.ambientUpperHemi.xyz, ambientWS ); + @end + @end + + @insertpiece( BRDF_EnvMap ) +@end +@property( !hw_gamma_write ) + //Linear to Gamma space + outColour.xyz = sqrt( finalColour ); +@end @property( hw_gamma_write ) + outColour.xyz = finalColour; +@end + +@property( hlms_alphablend ) + @property( use_texture_alpha ) + outColour.w = material.F0.w * diffuseCol.w; + @end @property( !use_texture_alpha ) + outColour.w = material.F0.w; + @end +@end @property( !hlms_alphablend ) + outColour.w = 1.0;@end + + @property( debug_pssm_splits ) + outColour.xyz = mix( outColour.xyz, debugPssmSplit.xyz, 0.2f ); + @end + + @insertpiece( custom_ps_posExecution ) +} +@end diff --git a/ogre2/src/media/Hlms/Terra/GLSLES/Structs_piece_vs_piece_ps.glsl b/ogre2/src/media/Hlms/Terra/GLSLES/Structs_piece_vs_piece_ps.glsl new file mode 100644 index 000000000..21f7c4fea --- /dev/null +++ b/ogre2/src/media/Hlms/Terra/GLSLES/Structs_piece_vs_piece_ps.glsl @@ -0,0 +1,46 @@ + +@piece( TerraMaterialDecl ) +layout_constbuffer(binding = 1) uniform MaterialBuf +{ + /* kD is already divided by PI to make it energy conserving. + (formula is finalDiffuse = NdotL * surfaceDiffuse / PI) + */ + vec4 kD; //kD.w is padding + vec4 roughness; + vec4 metalness; + vec4 detailOffsetScale[4]; + + @insertpiece( custom_materialBuffer ) +} material; +@end + +@piece( TerraInstanceDecl ) +struct CellData +{ + //.x = numVertsPerLine + //.y = lodLevel + //.z = vao->getPrimitiveCount() / m_verticesPerLine - 2u + //.w = skirtY (float) + uvec4 numVertsPerLine; + ivec4 xzTexPosBounds; //XZXZ + vec4 pos; //.w contains 1.0 / xzTexPosBounds.z + vec4 scale; //.w contains 1.0 / xzTexPosBounds.w +}; + +layout_constbuffer(binding = 2) uniform InstanceBuffer +{ + CellData cellData[256]; +} instance; +@end + +@piece( Terra_VStoPS_block ) + //flat uint drawId; + vec3 pos; + vec2 uv0; + + @foreach( hlms_num_shadow_map_lights, n ) + @property( !hlms_shadowmap@n_is_point_light ) + vec4 posL@n;@end @end + @property( hlms_pssm_splits )float depth;@end + @insertpiece( custom_VStoPS ) +@end diff --git a/ogre2/src/media/Hlms/Terra/GLSLES/Textures_piece_ps.glsl b/ogre2/src/media/Hlms/Terra/GLSLES/Textures_piece_ps.glsl new file mode 100644 index 000000000..5ae13440d --- /dev/null +++ b/ogre2/src/media/Hlms/Terra/GLSLES/Textures_piece_ps.glsl @@ -0,0 +1,12 @@ + +@undefpiece( kD ) +@piece( kD )diffuseCol@end + +@undefpiece( kS ) +@piece( kS )vec3( 1, 1, 1 )@end + +@foreach( detail_maps_normal, n ) + @undefpiece( SampleDetailMapNm@n ) + @piece( SampleDetailMapNm@n )getTSDetailNormal( textureMaps[@value(detail_map_nm@n_idx)], vec3( inPs.uv0.xy * material.detailOffsetScale[@n].zw + + material.detailOffsetScale[@n].xy , @value(detail_map_nm@n_idx_slice) ) )@end +@end diff --git a/ogre2/src/media/Hlms/Terra/GLSLES/VertexShader_vs.glsl b/ogre2/src/media/Hlms/Terra/GLSLES/VertexShader_vs.glsl new file mode 100644 index 000000000..2377a38b5 --- /dev/null +++ b/ogre2/src/media/Hlms/Terra/GLSLES/VertexShader_vs.glsl @@ -0,0 +1,126 @@ +@insertpiece( SetCrossPlatformSettings ) +@insertpiece( SetCompatibilityLayer ) + +@property( GL3+ ) +out gl_PerVertex +{ + vec4 gl_Position; +}; +@end + +layout(std140) uniform; + +//To render a 2x2 (quads) terrain: +//You'll normally need 6 vertices per line + 2 for degenerates. +//You'll need 8 vertices per line. +//So you'll need a total of 16 vertices. + +//To render a 4x2 (quads) terrain: +//You'll need 10 vertices per line. +//If we include degenerate vertices, you'll need 12 per line +//So you'll need a total of 24 vertices. +//in int gl_VertexID; + +@property( GL_ARB_base_instance ) + in uint drawId; +@end + +@insertpiece( custom_vs_attributes ) + +out block +{ +@insertpiece( Terra_VStoPS_block ) +} outVs; + +// START UNIFORM DECLARATION +@insertpiece( PassDecl ) +@insertpiece( TerraInstanceDecl ) +uniform sampler2D heightMap; +@insertpiece( custom_vs_uniformDeclaration ) +@property( !GL_ARB_base_instance )uniform uint baseInstance;@end +// END UNIFORM DECLARATION + +@piece( VertexTransform ) + //Lighting is in view space + outVs.pos = ( vec4(worldPos.xyz, 1.0f) * passBuf.view ).xyz; +@property( !hlms_dual_paraboloid_mapping ) + gl_Position = vec4(worldPos.xyz, 1.0f) * passBuf.viewProj;@end +@property( hlms_dual_paraboloid_mapping ) + //Dual Paraboloid Mapping + gl_Position.w = 1.0f; + gl_Position.xyz = outVs.pos; + float L = length( gl_Position.xyz ); + gl_Position.z += 1.0f; + gl_Position.xy /= gl_Position.z; + gl_Position.z = (L - NearPlane) / (FarPlane - NearPlane);@end +@end + +void main() +{ +@property( !GL_ARB_base_instance ) + uint drawId = baseInstance + uint( gl_InstanceID ); +@end + + @insertpiece( custom_vs_preExecution ) + + CellData cellData = instance.cellData[drawId]; + + //Map pointInLine from range [0; 12) to range [0; 9] so that it reads: + // 0 0 1 2 3 4 5 6 7 8 9 9 + uint pointInLine = uint(gl_VertexID) % (cellData.numVertsPerLine.x); //cellData.numVertsPerLine.x = 12 + pointInLine = uint(clamp( int(pointInLine) - 1, 0, int(cellData.numVertsPerLine.x - 3u) )); + + uvec2 uVertexPos; + + uVertexPos.x = pointInLine >> 1u; + //Even numbers are the next line, odd numbers are current line. + uVertexPos.y = (pointInLine & 0x01u) == 0u ? 1u : 0u; + uVertexPos.y += uint(gl_VertexID) / cellData.numVertsPerLine.x; + //uVertexPos.y += floor( (float)gl_VertexID / (float)cellData.numVertsPerLine ); Could be faster on GCN. + +@property( use_skirts ) + //Apply skirt. + bool isSkirt =( pointInLine.x <= 1u || + pointInLine.x >= (cellData.numVertsPerLine.x - 4u) || + uVertexPos.y == 0u || + uVertexPos.y == (cellData.numVertsPerLine.z + 2u) ); + + //Now shift X position for the left & right skirts + uVertexPos.x = uint( max( int(uVertexPos.x) - 1, 0 ) ); + uVertexPos.x = min( uVertexPos.x, ((cellData.numVertsPerLine.x - 7u) >> 1u) ); + // uVertexPos.x becomes: + // 0 0 0 1 1 2 2 3 3 4 4 4 + // 0 0 0 0 0 1 1 2 2 3 3 3 + // 0 0 0 0 0 1 1 2 2 2 2 2 + + //Now shift Y position for the front & back skirts + uVertexPos.y = uint( max( int(uVertexPos.y) - 1, 0 ) ); + uVertexPos.y = min( uVertexPos.y, cellData.numVertsPerLine.z ); +@end + + uint lodLevel = cellData.numVertsPerLine.y; + uVertexPos = uVertexPos << lodLevel; + + uVertexPos.xy = uvec2( clamp( ivec2(uVertexPos.xy) + cellData.xzTexPosBounds.xy, + ivec2( 0, 0 ), cellData.xzTexPosBounds.zw ) ); + + vec3 worldPos; + worldPos.y = texelFetch( heightMap, ivec2( uVertexPos.xy ), 0 ).x; +@property( use_skirts ) + worldPos.y = isSkirt ? uintBitsToFloat(cellData.numVertsPerLine.w) : worldPos.y; +@end + worldPos.xz = uVertexPos.xy; + worldPos.xyz = worldPos.xyz * cellData.scale.xyz + cellData.pos.xyz; + + @insertpiece( VertexTransform ) + + outVs.uv0.xy = vec2( uVertexPos.xy ) * vec2( cellData.pos.w, cellData.scale.w ); + + @insertpiece( DoShadowReceiveVS ) + +@property( hlms_pssm_splits ) outVs.depth = gl_Position.z;@end + + //outVs.drawId = drawId; + + @insertpiece( custom_vs_posExecution ) +} diff --git a/ogre2/src/media/Hlms/Terra/HLSL/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.hlsl b/ogre2/src/media/Hlms/Terra/HLSL/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.hlsl index daeadd43a..305e91568 100644 --- a/ogre2/src/media/Hlms/Terra/HLSL/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.hlsl +++ b/ogre2/src/media/Hlms/Terra/HLSL/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.hlsl @@ -1,12 +1,12 @@ @property( !hlms_shadowcaster && terra_enabled ) -@piece( custom_VStoPS_terra ) - float terrainShadow : TEXCOORD@counter(texcoord); +@piece( custom_VStoPS ) + midf terrainShadow : TEXCOORD@counter(texcoord); @end /// Extra per-pass global data we need for applying our /// shadows to regular objects, passed to all PBS shaders. -@piece( custom_passBuffer_terra ) +@piece( custom_passBuffer ) float4 terraOrigin; //Normalized. i.e. -terrainOrigin / terrainDimensions //.xz = terrain 1.0 / XZ dimensions. //.y = 1.0 / terrainHeight; @@ -14,7 +14,7 @@ @end /// Add the shadows' texture to the vertex shader -@piece( custom_vs_uniformDeclaration_terra ) +@piece( custom_vs_uniformDeclaration ) SamplerState terrainShadowSampler : register(s@value(terrainShadows)); Texture2D terrainShadows : register(t@value(terrainShadows)); @end @@ -22,7 +22,7 @@ /// Evaluate the shadow based on world XZ position & height in the vertex shader. /// Doing it at the pixel shader level would be more accurate, but the difference /// is barely noticeable, and slower -@piece( custom_vs_posExecution_terra ) +@piece( custom_vs_posExecution ) @property( z_up ) float3 terraWorldPos = float3( worldPos.x, -worldPos.z, worldPos.y ); @else @@ -33,7 +33,7 @@ 0 ).xyz; float terraHeightWeight = terraWorldPos.y * passBuf.invTerraBounds.y + passBuf.terraOrigin.y; terraHeightWeight = (terraHeightWeight - terraShadowData.y) * terraShadowData.z * 1023.0; - outVs.terrainShadow = lerp( terraShadowData.x, 1.0, saturate( terraHeightWeight ) ); + outVs.terrainShadow = lerp( midf_c( terraShadowData.x ), _h( 1.0 ), midf_c( saturate( terraHeightWeight ) ) ); @end @property( hlms_lights_directional && hlms_num_shadow_map_lights ) diff --git a/ogre2/src/media/Hlms/Terra/Metal/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.metal b/ogre2/src/media/Hlms/Terra/Metal/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.metal index 9633edece..e8e6548ae 100644 --- a/ogre2/src/media/Hlms/Terra/Metal/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.metal +++ b/ogre2/src/media/Hlms/Terra/Metal/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.metal @@ -1,12 +1,12 @@ @property( !hlms_shadowcaster && terra_enabled ) -@piece( custom_VStoPS_terra ) - float terrainShadow; +@piece( custom_VStoPS ) + midf terrainShadow; @end /// Extra per-pass global data we need for applying our /// shadows to regular objects, passed to all PBS shaders. -@piece( custom_passBuffer_terra ) +@piece( custom_passBuffer ) float4 terraOrigin; //Normalized. i.e. -terrainOrigin / terrainDimensions //.xz = terrain 1.0 / XZ dimensions. //.y = 1.0 / terrainHeight; @@ -14,7 +14,7 @@ @end /// Add the shadows' texture to the vertex shader -@piece( custom_vs_uniformDeclaration_terra ) +@piece( custom_vs_uniformDeclaration ) , sampler terrainShadowSampler [[sampler(@value(terrainShadows))]] , texture2d terrainShadows [[texture(@value(terrainShadows))]] @end @@ -22,7 +22,7 @@ /// Evaluate the shadow based on world XZ position & height in the vertex shader. /// Doing it at the pixel shader level would be more accurate, but the difference /// is barely noticeable, and slower -@piece( custom_vs_posExecution_terra ) +@piece( custom_vs_posExecution ) @property( z_up ) float3 terraWorldPos = float3( worldPos.x, -worldPos.z, worldPos.y ); @else @@ -33,7 +33,7 @@ level(0) ).xyz; float terraHeightWeight = terraWorldPos.y * passBuf.invTerraBounds.y + passBuf.terraOrigin.y; terraHeightWeight = (terraHeightWeight - terraShadowData.y) * terraShadowData.z * 1023.0; - outVs.terrainShadow = lerp( terraShadowData.x, 1.0, saturate( terraHeightWeight ) ); + outVs.terrainShadow = lerp( midf_c( terraShadowData.x ), _h( 1.0 ), midf_c( saturate( terraHeightWeight ) ) ); @end @property( hlms_lights_directional && hlms_num_shadow_map_lights ) diff --git a/ogre2/src/media/Hlms/Terra/Metal/PixelShader_ps.metal b/ogre2/src/media/Hlms/Terra/Metal/PixelShader_ps.metal index b70be5100..03c0522f7 100644 --- a/ogre2/src/media/Hlms/Terra/Metal/PixelShader_ps.metal +++ b/ogre2/src/media/Hlms/Terra/Metal/PixelShader_ps.metal @@ -72,11 +72,12 @@ fragment @insertpiece( output_type ) main_metal @insertpiece( TerraMaterialDecl ) @insertpiece( PccManualProbeDecl ) @end + @insertpiece( AtmosphereNprSkyDecl ) @insertpiece( custom_ps_uniformDeclaration ) // END UNIFORM DECLARATION - , texture2d terrainNormals [[texture(@value(terrainNormals))]] - , texture2d terrainShadows [[texture(@value(terrainShadows))]] + , texture2d terrainNormals [[texture(@value(terrainNormals))]] + , texture2d terrainShadows [[texture(@value(terrainShadows))]] , sampler samplerStateTerra [[sampler(@value(terrainNormals))]] @property( hlms_forwardplus ) @@ -86,11 +87,11 @@ fragment @insertpiece( output_type ) main_metal @property( hlms_use_prepass ) @property( !hlms_use_prepass_msaa ) - , texture2d gBuf_normals [[texture(@value(gBuf_normals))]] - , texture2d gBuf_shadowRoughness [[texture(@value(gBuf_shadowRoughness))]] + , texture2d gBuf_normals [[texture(@value(gBuf_normals))]] + , texture2d gBuf_shadowRoughness [[texture(@value(gBuf_shadowRoughness))]] @end @property( hlms_use_prepass_msaa ) - , texture2d_ms gBuf_normals [[texture(@value(gBuf_normals))]] - , texture2d_ms gBuf_shadowRoughness[[texture(@value(gBuf_shadowRoughness))]] + , texture2d_ms gBuf_normals [[texture(@value(gBuf_normals))]] + , texture2d_ms gBuf_shadowRoughness[[texture(@value(gBuf_shadowRoughness))]] @end @property( hlms_use_ssr ) @@ -103,20 +104,20 @@ fragment @insertpiece( output_type ) main_metal @property( irradiance_volumes ) - , texture3d irradianceVolume [[texture(@value(irradianceVolume))]] + , texture3d irradianceVolume [[texture(@value(irradianceVolume))]] , sampler irradianceVolumeSampler [[sampler(@value(irradianceVolume))]] @end @foreach( num_textures, n ) - , texture2d_array textureMaps@n [[texture(@value(textureMaps@n))]]@end + , texture2d_array textureMaps@n [[texture(@value(textureMaps@n))]]@end @property( use_envprobe_map ) @property( !hlms_enable_cubemaps_auto ) - , texturecube texEnvProbeMap [[texture(@value(texEnvProbeMap))]] + , texturecube texEnvProbeMap [[texture(@value(texEnvProbeMap))]] @else @property( !hlms_cubemaps_use_dpm ) - , texturecube_array texEnvProbeMap [[texture(@value(texEnvProbeMap))]] + , texturecube_array texEnvProbeMap [[texture(@value(texEnvProbeMap))]] @else - , texture2d_array texEnvProbeMap [[texture(@value(texEnvProbeMap))]] + , texture2d_array texEnvProbeMap [[texture(@value(texEnvProbeMap))]] @end @end @property( envMapRegSampler < samplerStateStart ) diff --git a/ogre2/src/media/Hlms/Terra/Metal/VertexShader_vs.metal b/ogre2/src/media/Hlms/Terra/Metal/VertexShader_vs.metal index 302272d11..b6eac9773 100644 --- a/ogre2/src/media/Hlms/Terra/Metal/VertexShader_vs.metal +++ b/ogre2/src/media/Hlms/Terra/Metal/VertexShader_vs.metal @@ -37,6 +37,7 @@ vertex PS_INPUT main_metal @property( hlms_shadowcaster ) @insertpiece( MaterialDecl ) @end + @insertpiece( AtmosphereNprSkyDecl ) @property( !terra_use_uint ) , texture2d heightMap [[texture(@value(heightMap))]] @else diff --git a/ogre2/src/media/Hlms/Unlit/Any/500.StructsUnlit_piece_all.any b/ogre2/src/media/Hlms/Unlit/Any/500.StructsUnlit_piece_all.any index 533f6a467..05bca8a58 100644 --- a/ogre2/src/media/Hlms/Unlit/Any/500.StructsUnlit_piece_all.any +++ b/ogre2/src/media/Hlms/Unlit/Any/500.StructsUnlit_piece_all.any @@ -99,7 +99,7 @@ @end @end @property( hlms_colour ) - INTERPOLANT( float4 colour, @counter(texcoord) ); + INTERPOLANT( midf4 colour, @counter(texcoord) ); @end @foreach( out_uv_half_count, n ) INTERPOLANT( float@value( out_uv_half_count@n ) uv@n, @counter(texcoord) );@end @@ -114,6 +114,11 @@ @end @end @end + @property( hlms_emulate_clip_distances && hlms_pso_clip_distances ) + @foreach( hlms_pso_clip_distances, n ) + INTERPOLANT( float clipDistance@n, @counter(texcoord) ); + @end + @end @insertpiece( custom_VStoPS ) @end diff --git a/ogre2/src/media/Hlms/Unlit/Any/700.BlendModes_piece_ps.any b/ogre2/src/media/Hlms/Unlit/Any/700.BlendModes_piece_ps.any index fe29e89c9..7ae5b16ae 100644 --- a/ogre2/src/media/Hlms/Unlit/Any/700.BlendModes_piece_ps.any +++ b/ogre2/src/media/Hlms/Unlit/Any/700.BlendModes_piece_ps.any @@ -4,26 +4,26 @@ @piece( NormalNonPremul ) //Normal Non Premultiplied @counter(t) diffuseCol.xyz = lerp( diffuseCol.xyz, topImage@value(t).xyz, topImage@value(t).a ); - diffuseCol.w = lerp( diffuseCol.w, 1.0, topImage@value(t).w ); + diffuseCol.w = lerp( diffuseCol.w, _h( 1.0 ), topImage@value(t).w ); @end @piece( NormalPremul ) //Normal Premultiplied @counter(t) - diffuseCol.xyz = (1.0 - topImage@value(t).a) * diffuseCol.xyz + topImage@value(t).xyz; - diffuseCol.w = lerp( diffuseCol.w, 1.0, topImage@value(t).w ); + diffuseCol.xyz = (_h( 1.0 ) - topImage@value(t).a) * diffuseCol.xyz + topImage@value(t).xyz; + diffuseCol.w = lerp( diffuseCol.w, _h( 1.0 ), topImage@value(t).w ); @end @piece( Add ) //Add @counter(t) diffuseCol.xyz = lerp( diffuseCol.xyz, - min( diffuseCol.xyz + topImage@value(t).xyz, float3(1.0,1.0,1.0) ), + min( diffuseCol.xyz + topImage@value(t).xyz, midf3_c(1.0,1.0,1.0) ), topImage@value(t).a ); @end @piece( Subtract ) //Subtract @counter(t) diffuseCol.xyz = lerp( diffuseCol.xyz, - max( diffuseCol.xyz - topImage@value(t).xyz, float3(0.0,0.0,0.0) ), + max( diffuseCol.xyz - topImage@value(t).xyz, midf3_c(0.0,0.0,0.0) ), topImage@value(t).a ); @end @@ -37,21 +37,21 @@ @piece( Multiply2x ) //Multiply2x @counter(t) diffuseCol.xyz = lerp( diffuseCol.xyz, - min( diffuseCol.xyz * topImage@value(t).xyz * 2.0, float3(1.0,1.0,1.0) ), + min( diffuseCol.xyz * topImage@value(t).xyz * _h( 2.0 ), midf3_c(1.0,1.0,1.0) ), topImage@value(t).a ); @end @piece( Screen ) //Screen @counter(t) diffuseCol.xyz = lerp( diffuseCol.xyz, - 1.0 - (1.0 - diffuseCol.xyz) * (1.0 - topImage@value(t).xyz), + _h( 1.0 ) - (_h( 1.0 ) - diffuseCol.xyz) * (_h( 1.0 ) - topImage@value(t).xyz), topImage@value(t).a ); @end @piece( Overlay ) //Overlay @counter(t) diffuseCol.xyz = lerp( diffuseCol.xyz, - diffuseCol.xyz * ( diffuseCol.xyz + 2.0 * topImage@value(t).xyz * (1.0 - diffuseCol.xyz) ), + diffuseCol.xyz * ( diffuseCol.xyz + _h( 2.0 ) * topImage@value(t).xyz * (_h( 1.0 ) - diffuseCol.xyz) ), topImage@value(t).a ); @end @@ -72,14 +72,14 @@ @piece( GrainExtract ) //GrainExtract @counter(t) diffuseCol.xyz = lerp( diffuseCol.xyz, - (diffuseCol.xyz - topImage@value(t).xyz) + 0.5f, + (diffuseCol.xyz - topImage@value(t).xyz) + _h( 0.5f ), topImage@value(t).a ); @end @piece( GrainMerge ) //GrainMerge @counter(t) diffuseCol.xyz = lerp( diffuseCol.xyz, - (diffuseCol.xyz + topImage@value(t).xyz) - 0.5f, + (diffuseCol.xyz + topImage@value(t).xyz) - _h( 0.5f ), topImage@value(t).a ); @end diff --git a/ogre2/src/media/Hlms/Unlit/Any/800.PixelShader_piece_ps.any b/ogre2/src/media/Hlms/Unlit/Any/800.PixelShader_piece_ps.any index 7e18e1bd3..5b061d9f7 100644 --- a/ogre2/src/media/Hlms/Unlit/Any/800.PixelShader_piece_ps.any +++ b/ogre2/src/media/Hlms/Unlit/Any/800.PixelShader_piece_ps.any @@ -5,11 +5,11 @@ @foreach( diffuse_map, n ) #define DiffuseSampler@n samplerState@value(diffuse_map@n_sampler) @property( diffuse_map@n_array ) - #define SampleDiffuse@n( tex, sampler, uv, d ) OGRE_SampleArray2D( tex, sampler, uv, d ) + #define SampleDiffuse@n( tex, sampler, uv, d ) OGRE_SampleArray2DF16( tex, sampler, uv, d ) #define DiffuseTexture@n textureMapsArray@value(diffuse_map@n_idx) @piece( diffuseIdx@n ), diffuseIdx@n@end @else - #define SampleDiffuse@n( tex, sampler, uv ) OGRE_Sample( tex, sampler, uv ) + #define SampleDiffuse@n( tex, sampler, uv ) OGRE_SampleF16( tex, sampler, uv ) #define DiffuseTexture@n textureMaps@value(diffuse_map@n_idx) @end @@ -54,7 +54,14 @@ @end @piece( DefaultBodyPS ) - float4 diffuseCol = float4( 1.0f, 1.0f, 1.0f, 1.0f ); + @property( hlms_emulate_clip_distances && hlms_global_clip_planes && hlms_pso_clip_distances && syntax == glslvk) + @foreach( hlms_pso_clip_distances, n ) + if( inPs.clipDistance@n < 0.0 ) + discard; + @end + @end + + midf4 diffuseCol = midf4_c( 1.0f, 1.0f, 1.0f, 1.0f ); @property( diffuse_map || alpha_test || diffuse ) @insertpiece( LoadMaterial ) @@ -86,8 +93,8 @@ // Load each additional layer and blend it @foreach( diffuse_map, n, 1 ) @property( diffuse_map@n ) - float4 topImage@n = SampleDiffuse@n( DiffuseTexture@n, DiffuseSampler@n, - DiffuseUV@n @insertpiece( diffuseIdx@n ) ).@insertpiece(diffuse_map@n_tex_swizzle); + midf4 topImage@n = SampleDiffuse@n( DiffuseTexture@n, DiffuseSampler@n, + DiffuseUV@n @insertpiece( diffuseIdx@n ) ).@insertpiece(diffuse_map@n_tex_swizzle); @insertpiece( blend_mode_idx@n ) @end @end @@ -97,7 +104,7 @@ diffuseCol *= inPs.colour; @else @property( diffuse ) - diffuseCol *= material.diffuse; + diffuseCol *= midf4_c( material.diffuse ); @end @end diff --git a/ogre2/src/media/Hlms/Unlit/Any/800.VertexShader_piece_vs.any b/ogre2/src/media/Hlms/Unlit/Any/800.VertexShader_piece_vs.any index d6ac995b9..af62d3c7c 100644 --- a/ogre2/src/media/Hlms/Unlit/Any/800.VertexShader_piece_vs.any +++ b/ogre2/src/media/Hlms/Unlit/Any/800.VertexShader_piece_vs.any @@ -80,11 +80,11 @@ @property( !hlms_shadowcaster || alpha_test ) @property( hlms_colour ) - outVs.colour = inVs_colour; + outVs.colour = midf4_c( inVs_colour ); @property( diffuse ) @insertpiece( LoadMaterial ) @insertpiece( custom_vs_posMaterialLoad ) - outVs.colour *= material.diffuse; + outVs.colour *= midf4_c( material.diffuse ); @end @end diff --git a/ogre2/src/media/Hlms/Unlit/GLSL/PixelShader_ps.glsl b/ogre2/src/media/Hlms/Unlit/GLSL/PixelShader_ps.glsl index c90469c18..38f47c952 100644 --- a/ogre2/src/media/Hlms/Unlit/GLSL/PixelShader_ps.glsl +++ b/ogre2/src/media/Hlms/Unlit/GLSL/PixelShader_ps.glsl @@ -9,9 +9,9 @@ in vec4 gl_FragCoord; @end @property( !hlms_shadowcaster ) -layout(location = FRAG_COLOR, index = 0) out vec4 outColour; +layout(location = FRAG_COLOR, index = 0) out midf4 outColour; @end @property( hlms_shadowcaster ) -layout(location = FRAG_COLOR, index = 0) out float outColour; +layout(location = FRAG_COLOR, index = 0) out midf outColour; @end // START UNIFORM DECLARATION @@ -28,17 +28,17 @@ layout(location = FRAG_COLOR, index = 0) out float outColour; @property( syntax != glslvk ) @foreach( num_textures, n ) @property( is_texture@n_array ) - uniform sampler2DArray textureMapsArray@n; + midf_tex uniform sampler2DArray textureMapsArray@n; @else - uniform sampler2D textureMaps@n; + midf_tex uniform sampler2D textureMaps@n; @end @end @else @foreach( num_textures, n ) @property( is_texture@n_array ) - layout( ogre_t@value(textureMapsArray@n) ) uniform texture2DArray textureMapsArray@n; + layout( ogre_t@value(textureMapsArray@n) ) midf_tex uniform texture2DArray textureMapsArray@n; @else - layout( ogre_t@value(textureMaps@n) ) uniform texture2D textureMaps@n; + layout( ogre_t@value(textureMaps@n) ) midf_tex uniform texture2D textureMaps@n; @end @end @end diff --git a/ogre2/src/media/Hlms/Unlit/GLSL/VertexShader_vs.glsl b/ogre2/src/media/Hlms/Unlit/GLSL/VertexShader_vs.glsl index 9a6f4d57f..1978c8465 100644 --- a/ogre2/src/media/Hlms/Unlit/GLSL/VertexShader_vs.glsl +++ b/ogre2/src/media/Hlms/Unlit/GLSL/VertexShader_vs.glsl @@ -4,7 +4,7 @@ out gl_PerVertex { vec4 gl_Position; -@property( hlms_pso_clip_distances ) +@property( hlms_pso_clip_distances && !hlms_emulate_clip_distances ) float gl_ClipDistance[@value(hlms_pso_clip_distances)]; @end }; diff --git a/ogre2/src/media/Hlms/Unlit/Metal/PixelShader_ps.metal b/ogre2/src/media/Hlms/Unlit/Metal/PixelShader_ps.metal index 7296fa4d6..a49065067 100644 --- a/ogre2/src/media/Hlms/Unlit/Metal/PixelShader_ps.metal +++ b/ogre2/src/media/Hlms/Unlit/Metal/PixelShader_ps.metal @@ -30,9 +30,9 @@ fragment @insertpiece( output_type ) main_metal @property( !hlms_shadowcaster || alpha_test ) @foreach( num_textures, n ) @property( is_texture@n_array ) - , texture2d_array textureMapsArray@n [[texture(@value(textureMapsArray@n))]] + , texture2d_array textureMapsArray@n [[texture(@value(textureMapsArray@n))]] @else - , texture2d textureMaps@n [[texture(@value(textureMaps@n))]] + , texture2d textureMaps@n [[texture(@value(textureMaps@n))]] @end @end @end