diff --git a/.gitignore b/.gitignore index 42cc67af..f2a1fd58 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,5 @@ Editor/Resources/Cache Lux.slnx Editor/SandboxProject/Assets/Cache/Thumbnails Editor/SandboxProject/Assets/AssetRegistry.lzr +*.lap +*.aps diff --git a/Core/Source/Lux/Project/Project.cpp b/Core/Source/Lux/Project/Project.cpp index 0b5849c6..b0e838b3 100644 --- a/Core/Source/Lux/Project/Project.cpp +++ b/Core/Source/Lux/Project/Project.cpp @@ -69,10 +69,28 @@ namespace Lux if (!s_ActiveProject) return; + if (s_ActiveProject->m_ProjectDirectory.empty()) + s_ActiveProject->m_ProjectDirectory = s_ActiveProject->m_Config.ProjectDirectory; + if (s_ActiveProject->m_ProjectFilePath.empty() && !s_ActiveProject->m_ProjectDirectory.empty()) + s_ActiveProject->m_ProjectFilePath = s_ActiveProject->m_ProjectDirectory / s_ActiveProject->m_Config.ProjectFileName; + s_ActiveProject->m_Config.ProjectDirectory = s_ActiveProject->m_ProjectDirectory; s_ActiveProject->m_Config.ProjectFileName = s_ActiveProject->m_ProjectFilePath.filename().string(); + + if (AudioEngine::HasInitializedEngine()) + { + AudioEngine::Shutdown(); + AudioEngine::SetInitalizedEngine(false); + } + s_AssetManager = Ref::Create(); GetRuntimeAssetManager()->SetAssetPack(assetPack); + + if (!AudioEngine::HasInitializedEngine()) + { + AudioEngine::Init(); + AudioEngine::SetInitalizedEngine(true); + } } Ref Project::New() @@ -83,6 +101,23 @@ namespace Lux return s_ActiveProject; } + Ref Project::LoadRuntime(const std::filesystem::path& path, Ref assetPack) + { + Ref project = Ref::Create(); + + ProjectSerializer serializer(project); + if (!serializer.DeserializeRuntime(path)) + return nullptr; + + project->m_ProjectFilePath = path.lexically_normal(); + project->m_ProjectDirectory = path.parent_path(); + project->m_Config.ProjectDirectory = project->m_ProjectDirectory; + project->m_Config.ProjectFileName = project->m_ProjectFilePath.filename().string(); + + SetActiveRuntime(project, assetPack); + return s_ActiveProject; + } + Ref Project::Load(const std::filesystem::path& path) { Ref project = Ref::Create(); diff --git a/Core/Source/Lux/Project/Project.h b/Core/Source/Lux/Project/Project.h index 7aa4fd01..f2736d54 100644 --- a/Core/Source/Lux/Project/Project.h +++ b/Core/Source/Lux/Project/Project.h @@ -291,6 +291,7 @@ namespace Lux static Ref New(); static Ref Load(const std::filesystem::path& path); + static Ref LoadRuntime(const std::filesystem::path& path, Ref assetPack); static bool SaveActive(const std::filesystem::path& path); private: diff --git a/Core/Source/Lux/Renderer/Framebuffer.cpp b/Core/Source/Lux/Renderer/Framebuffer.cpp index 436844bc..fc04306e 100644 --- a/Core/Source/Lux/Renderer/Framebuffer.cpp +++ b/Core/Source/Lux/Renderer/Framebuffer.cpp @@ -3,9 +3,31 @@ #include "Lux/Core/Application.h" #include "Lux/Renderer/Renderer.h" +#include "Lux/Platform/Vulkan/VulkanSwapChain.h" namespace Lux { + namespace + { + static void PopulateClearValues(const FramebufferSpecification& specification, std::vector& clearValues) + { + clearValues.resize(specification.Attachments.Attachments.size()); + + for (uint32_t attachmentIndex = 0; attachmentIndex < specification.Attachments.Attachments.size(); attachmentIndex++) + { + const auto& attachmentSpec = specification.Attachments.Attachments[attachmentIndex]; + if (Utils::IsDepthFormat(attachmentSpec.Format)) + { + clearValues[attachmentIndex].DepthStencil = { specification.DepthClearValue, 0 }; + continue; + } + + const auto& clearColor = specification.ClearColor; + clearValues[attachmentIndex].Color = { { clearColor.r, clearColor.g, clearColor.b, clearColor.a } }; + } + } + } + #if WENEEDTODEALWITHTHIS namespace Utils { @@ -39,6 +61,12 @@ namespace Lux { m_Height = (uint32_t)(specification.Height * m_Specification.Scale); } + if (m_Specification.SwapChainTarget) + { + PopulateClearValues(m_Specification, m_ClearValues); + return; + } + // Create all image objects immediately so we can start referencing them // elsewhere uint32_t attachmentIndex = 0; @@ -96,6 +124,30 @@ namespace Lux { Release(); } + uint32_t Framebuffer::GetWidth() const + { + if (m_Specification.SwapChainTarget) + return Application::Get().GetWindow().GetSwapChain().GetWidth(); + + return m_Width; + } + + uint32_t Framebuffer::GetHeight() const + { + if (m_Specification.SwapChainTarget) + return Application::Get().GetWindow().GetSwapChain().GetHeight(); + + return m_Height; + } + + nvrhi::FramebufferHandle Framebuffer::GetHandle() const + { + if (m_Specification.SwapChainTarget) + return Application::Get().GetWindow().GetSwapChain().GetCurrentFramebuffer(); + + return m_Handle; + } + void Framebuffer::Release() { #if DEAL @@ -166,14 +218,10 @@ namespace Lux { m_Width = (uint32_t)(width * m_Specification.Scale); m_Height = (uint32_t)(height * m_Specification.Scale); - if (!m_Specification.SwapChainTarget) - { - RT_Invalidate(); - } + if (m_Specification.SwapChainTarget) + PopulateClearValues(m_Specification, m_ClearValues); else - { - LUX_CORE_VERIFY(false); - } + RT_Invalidate(); for (auto& callback : m_ResizeCallbacks) callback(this); diff --git a/Core/Source/Lux/Renderer/Framebuffer.h b/Core/Source/Lux/Renderer/Framebuffer.h index d038e6ca..5173cd0a 100644 --- a/Core/Source/Lux/Renderer/Framebuffer.h +++ b/Core/Source/Lux/Renderer/Framebuffer.h @@ -117,15 +117,15 @@ namespace Lux { void Resize(uint32_t width, uint32_t height, bool forceRecreate = false); void AddResizeCallback(const std::function)>& func); - virtual uint32_t GetWidth() const { return m_Width; } - virtual uint32_t GetHeight() const { return m_Height; } + virtual uint32_t GetWidth() const; + virtual uint32_t GetHeight() const; Ref GetImage(uint32_t attachmentIndex = 0) const { LUX_CORE_ASSERT(attachmentIndex < m_AttachmentImages.size()); return m_AttachmentImages[attachmentIndex]; } Ref GetDepthImage() const { return m_DepthAttachmentImage; } size_t GetColorAttachmentCount() const { return m_Specification.SwapChainTarget ? 1 : m_AttachmentImages.size(); } bool HasDepthAttachment() const { return (bool)m_DepthAttachmentImage; } - virtual nvrhi::FramebufferHandle GetHandle() const { return m_Handle; } + virtual nvrhi::FramebufferHandle GetHandle() const; const nvrhi::FramebufferDesc& GetFramebufferDesc() const { return m_FramebufferDesc; } const std::vector& GetClearValues() const { return m_ClearValues; } diff --git a/Core/Source/Lux/Scripting/ScriptEngine.cpp b/Core/Source/Lux/Scripting/ScriptEngine.cpp index eee5727b..65134cbe 100644 --- a/Core/Source/Lux/Scripting/ScriptEngine.cpp +++ b/Core/Source/Lux/Scripting/ScriptEngine.cpp @@ -197,8 +197,12 @@ namespace Lux { void ScriptEngine::Shutdown() { + if (!s_Data) + return; + ShutdownMono(); delete s_Data; + s_Data = nullptr; } void ScriptEngine::InitMono() @@ -232,10 +236,16 @@ namespace Lux { void ScriptEngine::ShutdownMono() { + if (!s_Data || !s_Data->RootDomain) + return; + mono_domain_set(mono_get_root_domain(), false); - mono_domain_unload(s_Data->AppDomain); - s_Data->AppDomain = nullptr; + if (s_Data->AppDomain) + { + mono_domain_unload(s_Data->AppDomain); + s_Data->AppDomain = nullptr; + } mono_jit_cleanup(s_Data->RootDomain); s_Data->RootDomain = nullptr; diff --git a/Editor/SandboxProject/Assets/Scenes/NewSceneSystem.luxscene b/Editor/SandboxProject/Assets/Scenes/NewSceneSystem.luxscene index de60b3d1..0e630081 100644 --- a/Editor/SandboxProject/Assets/Scenes/NewSceneSystem.luxscene +++ b/Editor/SandboxProject/Assets/Scenes/NewSceneSystem.luxscene @@ -19,6 +19,8 @@ Entities: Falloff: 1 Intensity: 2.5999999 Range: 24.5 + ShadowDistance: 0 + ShadowResolutionTier: 1 - Entity: 1639952346674441217 TagComponent: Tag: Camera diff --git a/Editor/SandboxProject/Sandbox.luxproj b/Editor/SandboxProject/Sandbox.luxproj index 23fc0b8b..9b22b66f 100644 --- a/Editor/SandboxProject/Sandbox.luxproj +++ b/Editor/SandboxProject/Sandbox.luxproj @@ -8,53 +8,55 @@ Project: AnimationPath: Animation ScriptModulePath: Scripts/Binaries/Sandbox.dll DefaultNamespace: Sandbox - StartScene: "" + StartScene: Scenes/NewSceneSystem.luxscene AutomaticallyReloadAssembly: true AutoSave: true AutoSaveInterval: 300 RenderingTechnique: Forward SceneRenderer: Rendering: + QualityPreset: Cinematic FrustumCulling: true OcclusionCulling: true GPUDrivenRendering: true GTAO: true GTAOBentNormals: true GTAODenoisePasses: 8 - AOShadowTolerance: 4 + AOShadowTolerance: 1 SSR: true JumpFloodOutline: true RenderScaleMode: Scale100 DynamicResolutionMinScale: 0.5 DynamicResolutionMaxScale: 1 DynamicResolutionTargetGPUTime: 16.6700001 - TextureMipBias: 0 - DistanceMipBias: false - DistanceMipBiasStart: 50 - DistanceMipBiasEnd: 250 - DistanceMipBiasMax: 2 + TextureMipBias: -1.5 + DistanceMipBias: true + DistanceMipBiasStart: 10 + DistanceMipBiasEnd: 100 + DistanceMipBiasMax: 0.5 OcclusionDepthBias: 0.00300000003 OcclusionBoundsScale: 1.14999998 GTAOResolutionScale: 1 GTAOTemporalAccumulation: true - GTAOTemporalBlend: 0.850000024 + GTAOTemporalBlend: 0.949999988 SSRQuality: Full SSRResolutionScale: 1 SSRTemporalAccumulation: true - SSRTemporalBlend: 0.899999976 + SSRTemporalBlend: 0.949999988 Shadows: SoftShadows: true ShadowCulling: true - MaxDistance: 200 - DistanceFade: 25 + MaxDistance: 450 + DistanceFade: 50 SplitLambda: 0.920000017 NearOffset: 0 FarOffset: 50 CascadeFade: 1 + ResolutionLimit: 8K PostFX: Bloom: Enabled: true - ResolutionScale: 2 + ResolutionScale: 1 Threshold: 1 Knee: 0.100000001 UpsampleScale: 1 @@ -67,7 +69,7 @@ Project: BlurSize: 0.75 SSR: HalfRes: false - MaxSteps: 70 + MaxSteps: 128 Brightness: 0.699999988 DepthTolerance: 0.800000012 Audio: diff --git a/Editor/Source/EditorLayer.cpp b/Editor/Source/EditorLayer.cpp index 282960e3..762ea6c6 100644 --- a/Editor/Source/EditorLayer.cpp +++ b/Editor/Source/EditorLayer.cpp @@ -5,6 +5,8 @@ #include "Lux/Scripting/ScriptEngine.h" #include "Lux/Renderer/Renderer.h" #include "Lux/Renderer/SceneRenderer.h" +#include "Lux/Serialization/AssetPack.h" +#include "Lux/Project/ProjectSerializer.h" #include "Lux/Utilities/FileSystem.h" @@ -37,6 +39,8 @@ #include "Panels/ProjectSettingsWindow.h" #include "Lux/Editor/SceneHierarchyPanel.h" #include +#include +#include #include #include #include @@ -129,6 +133,163 @@ namespace Lux { return imguiRenderer->CreateFrameTexture(image->GetHandle().Get(), nvrhi::AllSubresources); } + constexpr const char* s_RuntimeProjectFile = "Project.luxruntime"; + constexpr const char* s_RuntimeAssetPackFile = "AssetPack.lap"; + + std::string SanitizeBuildName(std::string value) + { + if (value.empty()) + value = "LuxGame"; + + for (char& c : value) + { + const bool valid = std::isalnum((unsigned char)c) || c == '-' || c == '_'; + if (!valid) + c = '_'; + } + + return value; + } + + bool CopyFileIfExists(const std::filesystem::path& source, const std::filesystem::path& destination, bool required = false) + { + std::error_code ec; + if (!std::filesystem::exists(source, ec) || ec) + { + if (required) + LUX_CONSOLE_LOG_ERROR("Missing export file: {}", source.string()); + return false; + } + + std::filesystem::create_directories(destination.parent_path(), ec); + ec.clear(); + std::filesystem::copy_file(source, destination, std::filesystem::copy_options::overwrite_existing, ec); + if (ec) + { + LUX_CONSOLE_LOG_ERROR("Failed to copy '{}' to '{}': {}", source.string(), destination.string(), ec.message()); + return false; + } + + return true; + } + + bool CopyDirectoryRecursive(const std::filesystem::path& source, const std::filesystem::path& destination) + { + std::error_code ec; + if (!std::filesystem::exists(source, ec) || ec) + return false; + + for (const auto& entry : std::filesystem::recursive_directory_iterator(source, ec)) + { + if (ec) + break; + + const std::filesystem::path relativePath = std::filesystem::relative(entry.path(), source, ec); + if (ec) + continue; + + if (!relativePath.empty() && *relativePath.begin() == "Cache") + continue; + + const std::filesystem::path target = destination / relativePath; + if (entry.is_directory(ec)) + { + std::filesystem::create_directories(target, ec); + continue; + } + + if (entry.is_regular_file(ec)) + CopyFileIfExists(entry.path(), target); + } + + return true; + } + + std::filesystem::path FindFirstExistingDirectory(std::initializer_list candidates) + { + std::error_code ec; + for (const std::filesystem::path& candidate : candidates) + { + if (!candidate.empty() && std::filesystem::exists(candidate, ec) && std::filesystem::is_directory(candidate, ec)) + return candidate; + } + + return {}; + } + + bool FileExists(const std::filesystem::path& path) + { + std::error_code ec; + return !path.empty() && std::filesystem::exists(path, ec) && std::filesystem::is_regular_file(path, ec); + } + + bool IsBuildConfigurationDirectory(const std::filesystem::path& path) + { + const std::string directoryName = path.filename().string(); + return path.parent_path().filename() == "bin" && directoryName.find("-windows-x86_64") != std::string::npos; + } + + std::filesystem::path FindRepositoryRootFrom(std::filesystem::path start) + { + if (start.empty()) + return {}; + + std::error_code ec; + start = std::filesystem::absolute(start, ec).lexically_normal(); + if (ec) + return {}; + + if (std::filesystem::is_regular_file(start, ec)) + start = start.parent_path(); + + for (std::filesystem::path directory = start; !directory.empty(); directory = directory.parent_path()) + { + if (std::filesystem::exists(directory / "premake5.lua", ec) + && std::filesystem::exists(directory / "Core", ec) + && std::filesystem::exists(directory / "Lux-Runtime" / "premake5.lua", ec)) + { + return directory; + } + + if (directory == directory.root_path()) + break; + } + + return {}; + } + + std::filesystem::path GetRuntimeExecutablePath() + { + std::error_code ec; + const std::filesystem::path current = std::filesystem::current_path(ec); + if (ec) + return {}; + + const std::string runtimeOutputDirectory = std::string(Application::GetConfigurationName()) + "-windows-x86_64"; + std::vector candidates; + + if (std::filesystem::path root = FindRepositoryRootFrom(current); !root.empty()) + candidates.emplace_back((root / "bin" / runtimeOutputDirectory / "Lux-Runtime" / "Lux-Runtime.exe").lexically_normal()); + + if (Ref activeProject = Project::GetActive()) + { + if (std::filesystem::path root = FindRepositoryRootFrom(activeProject->GetProjectDirectory()); !root.empty()) + candidates.emplace_back((root / "bin" / runtimeOutputDirectory / "Lux-Runtime" / "Lux-Runtime.exe").lexically_normal()); + } + + const std::filesystem::path buildConfigDirectory = current.filename() == "Editor" ? current.parent_path() : current; + if (IsBuildConfigurationDirectory(buildConfigDirectory)) + candidates.emplace_back((buildConfigDirectory / "Lux-Runtime" / "Lux-Runtime.exe").lexically_normal()); + + for (const std::filesystem::path& candidate : candidates) + { + if (FileExists(candidate)) + return candidate; + } + + return {}; + } + std::string GetSceneDisplayName(const std::filesystem::path& scenePath) { if (scenePath.empty()) @@ -629,6 +790,8 @@ namespace Lux { OpenProject(); if (ImGui::MenuItem("Save Project")) SaveProject(); + if (ImGui::MenuItem("Export Runtime...")) + ExportRuntime(); if (ImGui::BeginMenu("Recent Projects")) { @@ -1682,6 +1845,101 @@ namespace Lux { AddRecentProject(projectFilePath); } + void EditorLayer::ExportRuntime() + { + Ref project = Project::GetActive(); + if (!project) + { + LUX_CONSOLE_LOG_ERROR("No active project to export."); + return; + } + + if (m_SceneState != SceneState::Edit) + OnSceneStop(); + + SaveScene(); + SaveProject(); + + const std::filesystem::path selectedFolder = FileSystem::OpenFolderDialog(project->GetProjectDirectory().string().c_str()); + if (selectedFolder.empty()) + return; + + const std::string buildName = SanitizeBuildName(project->GetConfig().Name); + const std::filesystem::path exportRoot = selectedFolder / (buildName + "-Windows-x86_64"); + const std::filesystem::path exportAssets = exportRoot / "Assets"; + + std::error_code ec; + std::filesystem::create_directories(exportAssets, ec); + if (ec) + { + LUX_CONSOLE_LOG_ERROR("Failed to create export directory '{}': {}", exportRoot.string(), ec.message()); + return; + } + + std::atomic assetPackProgress = 0.0f; + Ref assetPack = AssetPack::CreateFromActiveProject(assetPackProgress); + if (!assetPack) + { + LUX_CONSOLE_LOG_ERROR("Runtime export failed while building the asset pack."); + return; + } + + ProjectSerializer serializer(project); + const std::filesystem::path runtimeProjectFile = exportAssets / s_RuntimeProjectFile; + if (!serializer.SerializeRuntime(runtimeProjectFile)) + { + LUX_CONSOLE_LOG_ERROR("Runtime export failed while writing '{}'.", runtimeProjectFile.string()); + return; + } + + CopyFileIfExists(Project::GetActiveAssetDirectory() / s_RuntimeAssetPackFile, exportAssets / s_RuntimeAssetPackFile, true); + + const std::filesystem::path runtimeExe = GetRuntimeExecutablePath(); + const std::filesystem::path exportedExe = exportRoot / (buildName + ".exe"); + if (!CopyFileIfExists(runtimeExe, exportedExe, true)) + LUX_CONSOLE_LOG_WARN("Build the Lux-Runtime project once before exporting a standalone executable."); + + const std::filesystem::path runtimeDirectory = runtimeExe.parent_path(); + if (!runtimeDirectory.empty() && std::filesystem::exists(runtimeDirectory, ec)) + { + for (const auto& entry : std::filesystem::directory_iterator(runtimeDirectory, ec)) + { + if (!entry.is_regular_file(ec)) + continue; + + const std::filesystem::path extension = entry.path().extension(); + if (extension == ".dll" || extension == ".pdb") + CopyFileIfExists(entry.path(), exportRoot / entry.path().filename()); + } + } + + const std::filesystem::path current = std::filesystem::current_path(ec); + const std::filesystem::path resourcesSource = FindFirstExistingDirectory({ + current / "Resources", + current / ".." / "Editor" / "Resources", + std::filesystem::path("Editor") / "Resources" + }); + if (!resourcesSource.empty()) + CopyDirectoryRecursive(resourcesSource, exportRoot / "Resources"); + else + LUX_CONSOLE_LOG_WARN("Runtime export could not find an editor Resources directory to copy."); + + const std::filesystem::path monoSource = FindFirstExistingDirectory({ + current / "mono", + current / ".." / "Editor" / "mono", + std::filesystem::path("Editor") / "mono" + }); + if (!monoSource.empty()) + CopyDirectoryRecursive(monoSource, exportRoot / "mono"); + + const std::filesystem::path scriptModule = Project::GetActiveScriptModuleFilePath(); + if (std::filesystem::exists(scriptModule, ec)) + CopyFileIfExists(scriptModule, exportAssets / project->GetConfig().ScriptModulePath); + + LUX_CONSOLE_LOG_INFO("Runtime export complete: {}", exportRoot.string()); + FileSystem::OpenDirectoryInExplorer(exportRoot); + } + void EditorLayer::NewScene() { m_EditorScene = CreateRef(); diff --git a/Editor/Source/EditorLayer.h b/Editor/Source/EditorLayer.h index 919ec641..f3d8df0a 100644 --- a/Editor/Source/EditorLayer.h +++ b/Editor/Source/EditorLayer.h @@ -59,6 +59,7 @@ namespace Lux bool OpenProject(); void OpenProject(const std::filesystem::path& path); void SaveProject(); + void ExportRuntime(); void NewScene(); void OpenScene(); diff --git a/Editor/Source/LuxEditorApp.cpp b/Editor/Source/LuxEditorApp.cpp index 671f5c8a..e30e0b87 100644 --- a/Editor/Source/LuxEditorApp.cpp +++ b/Editor/Source/LuxEditorApp.cpp @@ -39,7 +39,7 @@ namespace Lux { if (!raw.empty()) projectPath = raw[0]; Lux::ApplicationSpecification specification; - specification.Name = "Sandbox"; + specification.Name = "Lux Editor"; specification.WindowWidth = 1600; specification.WindowHeight = 900; specification.StartMaximized = true; diff --git a/Editor/Source/Panels/ProjectSettingsWindow.cpp b/Editor/Source/Panels/ProjectSettingsWindow.cpp index 97f49edc..135a8c23 100644 --- a/Editor/Source/Panels/ProjectSettingsWindow.cpp +++ b/Editor/Source/Panels/ProjectSettingsWindow.cpp @@ -180,6 +180,21 @@ namespace Lux { return; auto& config = m_Project->GetConfig(); + auto syncStartupScenePath = [&config](AssetHandle sceneHandle) + { + config.StartSceneHandle = sceneHandle; + config.StartScene.clear(); + + if (!sceneHandle) + return; + + if (Ref editorAssetManager = Project::GetEditorAssetManager()) + { + const AssetMetadata metadata = editorAssetManager->GetMetadata(sceneHandle); + if (metadata.IsValid()) + config.StartScene = metadata.FilePath.generic_string(); + } + }; ImGuiEx::BeginPropertyGrid(); if (ImGuiEx::Property("Name", m_NameBuffer, sizeof(m_NameBuffer))) @@ -242,56 +257,19 @@ namespace Lux { config.AutoSaveIntervalSeconds = autoSaveInterval; m_Dirty = true; } - ImGuiEx::EndPropertyGrid(); - - ImGui::TextDisabled("Path changes affect the active project immediately and are persisted on save."); - - ImGui::Spacing(); - ImGui::TextUnformatted("Startup Scene"); - - std::string sceneLabel = "None"; - if (m_DefaultScene) - { - const AssetMetadata metadata = Project::GetEditorAssetManager()->GetMetadata(m_DefaultScene); - if (metadata.IsValid()) - sceneLabel = metadata.FilePath.generic_string(); - } - ImGui::Button(sceneLabel.c_str(), ImVec2(ImGui::GetContentRegionAvail().x, 0.0f)); - if (ImGui::BeginDragDropTarget()) + AssetHandle startupScene = config.StartSceneHandle; + ImGuiEx::PropertyAssetReferenceSettings startupSceneSettings; + startupSceneSettings.ShowFullFilePath = true; + if (ImGuiEx::PropertyAssetReference("Startup Scene", startupScene, "Scene loaded when entering play mode and when exporting a runtime build.", nullptr, startupSceneSettings)) { - if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("CONTENT_BROWSER_ITEM")) - { - const size_t itemCount = payload->DataSize / sizeof(AssetHandle); - if (itemCount > 0) - { - const AssetHandle droppedHandle = *(const AssetHandle*)payload->Data; - if (AssetManager::GetAssetType(droppedHandle) == AssetType::Scene) - { - const AssetMetadata metadata = Project::GetEditorAssetManager()->GetMetadata(droppedHandle); - if (metadata.IsValid()) - { - m_DefaultScene = droppedHandle; - config.StartSceneHandle = droppedHandle; - config.StartScene = metadata.FilePath.generic_string(); - m_Dirty = true; - } - } - } - } - ImGui::EndDragDropTarget(); + m_DefaultScene = startupScene; + syncStartupScenePath(startupScene); + m_Dirty = true; } + ImGuiEx::EndPropertyGrid(); - if (m_DefaultScene) - { - if (ImGui::Button("Clear Startup Scene")) - { - m_DefaultScene = 0; - config.StartSceneHandle = 0; - config.StartScene.clear(); - m_Dirty = true; - } - } + ImGui::TextDisabled("Path changes affect the active project immediately and are persisted on save."); ImGui::TreePop(); } diff --git a/Lux-Runtime/Lux-Runtime.ico b/Lux-Runtime/Lux-Runtime.ico new file mode 100644 index 00000000..52361aa1 Binary files /dev/null and b/Lux-Runtime/Lux-Runtime.ico differ diff --git a/Lux-Runtime/Lux-Runtime.rc b/Lux-Runtime/Lux-Runtime.rc new file mode 100644 index 00000000..7fd43913 --- /dev/null +++ b/Lux-Runtime/Lux-Runtime.rc @@ -0,0 +1,90 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +MAINICON ICON "Lux-Runtime.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 2026,1,0,0 + PRODUCTVERSION 2026,1,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "Lux Engine" + VALUE "FileDescription", "Lux Runtime" + VALUE "FileVersion", "2026.1.0.0" + VALUE "LegalCopyright", "Lux Engine" + VALUE "ProductName", "Lux Runtime" + VALUE "ProductVersion", "2026.1.0.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (United States) resources diff --git a/Lux-Runtime/premake5.lua b/Lux-Runtime/premake5.lua new file mode 100644 index 00000000..19d45b69 --- /dev/null +++ b/Lux-Runtime/premake5.lua @@ -0,0 +1,83 @@ +project "Lux-Runtime" + kind "ConsoleApp" + targetname "Lux-Runtime" + + targetdir ("../bin/" .. outputdir .. "/%{prj.name}") + objdir ("../bin-int/" .. outputdir .. "/%{prj.name}") + + links { "Core" } + + defines { "GLM_FORCE_DEPTH_ZERO_TO_ONE" } + + files { + "src/**.h", + "src/**.c", + "src/**.hpp", + "src/**.cpp" + } + + includedirs { + "src/", + "../Core/Source", + "../Core/vendor" + } + + filter "system:windows" + systemversion "latest" + defines { "LUX_PLATFORM_WINDOWS" } + files { + "Lux-Runtime.rc", + "resource.h" + } + + filter { "system:windows", "configurations:Debug or configurations:Debug-AS" } + postbuildcommands { + '{COPY} "../Core/vendor/assimp/bin/windows/Debug/assimp-vc143-mtd.dll" "%{cfg.targetdir}"', + } + + filter { "system:windows", "configurations:Release or configurations:Dist" } + postbuildcommands { + '{COPY} "../Core/vendor/assimp/bin/windows/Release/assimp-vc143-mt.dll" "%{cfg.targetdir}"', + } + + filter "system:linux" + defines { "LUX_PLATFORM_LINUX", "__EMULATE_UUID", "BACKWARD_HAS_DW", "BACKWARD_HAS_LIBUNWIND" } + links { "dw", "dl", "unwind", "pthread" } + + result, err = os.outputof("pkg-config --libs gtk+-3.0") + linkoptions { result } + + filter "configurations:Debug or configurations:Debug-AS" + symbols "On" + defines { "LUX_DEBUG" } + + ProcessDependencies("Debug") + + filter { "system:windows", "configurations:Debug-AS" } + sanitize { "Address" } + flags { "NoRuntimeChecks", "NoIncrementalLink" } + + filter "configurations:Release" + optimize "On" + vectorextensions "AVX2" + isaextensions { "BMI", "POPCNT", "LZCNT", "F16C" } + defines { "LUX_RELEASE" } + + ProcessDependencies("Release") + + filter "configurations:Debug or configurations:Debug-AS or configurations:Release" + defines { + "LUX_TRACK_MEMORY", + + "JPH_DEBUG_RENDERER", + "JPH_FLOATING_POINT_EXCEPTIONS_ENABLED", + "JPH_EXTERNAL_PROFILE" + } + + filter "configurations:Dist" + kind "WindowedApp" + optimize "Full" + symbols "Off" + defines { "LUX_DIST" } + + ProcessDependencies("Dist") diff --git a/Lux-Runtime/resource.h b/Lux-Runtime/resource.h new file mode 100644 index 00000000..d8d3ced0 --- /dev/null +++ b/Lux-Runtime/resource.h @@ -0,0 +1,13 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Lux-Runtime.rc +// + +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Lux-Runtime/src/RuntimeApplication.cpp b/Lux-Runtime/src/RuntimeApplication.cpp new file mode 100644 index 00000000..1904ea8e --- /dev/null +++ b/Lux-Runtime/src/RuntimeApplication.cpp @@ -0,0 +1,61 @@ +#include "RuntimeLayer.h" + +#include "Lux/EntryPoint.h" +#include "Lux/Utilities/CommandLineParser.h" +#include "Lux/Utilities/FileSystem.h" + +namespace Lux +{ + class RuntimeApplication : public Application + { + public: + RuntimeApplication(const ApplicationSpecification& specification, std::filesystem::path projectPath) + : Application(specification), m_ProjectPath(std::move(projectPath)) + { + s_IsRuntime = true; + } + + void OnInit() override + { + PushLayer(new RuntimeLayer(m_ProjectPath)); + } + + private: + std::filesystem::path m_ProjectPath; + }; + + Application* CreateApplication(int argc, char** argv) + { + CommandLineParser cli(argc, argv); + + const std::string_view workingDirectory = cli.GetOpt("C"); + if (!workingDirectory.empty()) + FileSystem::SetWorkingDirectory(workingDirectory); + + std::filesystem::path projectPath = "."; + if (std::string_view projectOpt = cli.GetOpt("project"); !projectOpt.empty()) + projectPath = projectOpt; + else + { + std::vector rawArgs = cli.GetRawArgs(); + if (!rawArgs.empty()) + projectPath = rawArgs.front(); + } + + ApplicationSpecification specification; + specification.Name = LUX_VERSION_LONG; + specification.WindowWidth = 1920; + specification.WindowHeight = 1080; + specification.WindowDecorated = true; + specification.Fullscreen = false; + specification.Resizable = false; + specification.StartMaximized = false; + specification.EnableImGui = false; + specification.VSync = true; + specification.IconPath = "Resources/Editor/Hazel-IconLogo-2023.png"; + specification.RenderConfig.FramesInFlight = 3; + specification.CoreThreadingPolicy = ThreadingPolicy::SingleThreaded; + + return new RuntimeApplication(specification, projectPath); + } +} diff --git a/Lux-Runtime/src/RuntimeLayer.cpp b/Lux-Runtime/src/RuntimeLayer.cpp new file mode 100644 index 00000000..1f0276fd --- /dev/null +++ b/Lux-Runtime/src/RuntimeLayer.cpp @@ -0,0 +1,361 @@ +#include "RuntimeLayer.h" + +#include "Lux/Asset/AssetManager.h" +#include "Lux/Core/Application.h" +#include "Lux/Core/Input.h" +#include "Lux/Project/Project.h" +#include "Lux/Project/ProjectSerializer.h" +#include "Lux/Renderer/Renderer.h" +#include "Lux/Renderer/UI/Font.h" +#include "Lux/Scripting/ScriptEngine.h" +#include "Lux/Utilities/StringUtils.h" +#include "Lux/Platform/Vulkan/VulkanSwapChain.h" + +#include + +namespace Lux +{ + namespace + { + constexpr const char* s_RuntimeProjectFile = "Project.luxruntime"; + constexpr const char* s_RuntimeAssetPackFile = "AssetPack.lap"; + + std::filesystem::path ResolveRuntimeProjectFile(const std::filesystem::path& projectPath) + { + std::error_code ec; + if (std::filesystem::is_regular_file(projectPath, ec)) + return projectPath; + + const std::filesystem::path assetDirectoryPath = projectPath / "Assets" / s_RuntimeProjectFile; + if (std::filesystem::exists(assetDirectoryPath, ec)) + return assetDirectoryPath; + + return projectPath / s_RuntimeProjectFile; + } + } + + RuntimeLayer::RuntimeLayer(std::filesystem::path projectPath) + : m_ProjectPath(std::move(projectPath)) + { + } + + void RuntimeLayer::OnAttach() + { + if (!OpenProject()) + { + Application::Get().Close(); + return; + } + + SceneRendererSpecification rendererSpec; + rendererSpec.ViewportWidth = Application::Get().GetWindow().GetWidth(); + rendererSpec.ViewportHeight = Application::Get().GetWindow().GetHeight(); + + m_SceneRenderer = Ref::Create(m_RuntimeScene, rendererSpec); + m_SceneRenderer->ApplyProjectSettings(m_RuntimeProject->GetConfig().SceneRenderer); + m_SceneRenderer->GetOptions().ShowGrid = false; + m_SceneRenderer->SetDebugViewMode(SceneRenderer::DebugViewMode::Final); + + m_Renderer2D = Ref::Create(); + m_Renderer2D->SetLineWidth(2.0f); + + CreateSwapChainResources(); + OnScenePlay(); + } + + void RuntimeLayer::OnDetach() + { + OnSceneStop(); + + if (m_SceneRenderer) + m_SceneRenderer->SetScene(nullptr); + + m_RuntimeScene = nullptr; + m_RuntimeProject = nullptr; + m_AssetPack = nullptr; + Project::SetActiveRuntime(nullptr, nullptr); + } + + bool RuntimeLayer::OpenProject() + { + const std::filesystem::path runtimeProjectFile = ResolveRuntimeProjectFile(m_ProjectPath); + const std::filesystem::path assetPackFile = runtimeProjectFile.parent_path() / s_RuntimeAssetPackFile; + + std::error_code ec; + if (!std::filesystem::exists(runtimeProjectFile, ec)) + { + LUX_CORE_ERROR("Runtime project file not found: {}", runtimeProjectFile.string()); + return false; + } + + if (!std::filesystem::exists(assetPackFile, ec)) + { + LUX_CORE_ERROR("Runtime asset pack not found: {}", assetPackFile.string()); + return false; + } + + m_AssetPack = AssetPack::Load(assetPackFile); + if (!m_AssetPack) + return false; + + m_RuntimeProject = Project::LoadRuntime(runtimeProjectFile, m_AssetPack); + if (!m_RuntimeProject) + return false; + + ScriptEngine::Init(); + + return LoadScene(m_RuntimeProject->GetConfig().StartSceneHandle); + } + + bool RuntimeLayer::LoadScene(AssetHandle sceneHandle) + { + if (!sceneHandle) + { + LUX_CORE_ERROR("Runtime project does not have a start scene."); + return false; + } + + Ref scene = Project::GetRuntimeAssetManager()->LoadScene(sceneHandle); + if (!scene) + { + LUX_CORE_ERROR("Failed to load runtime scene {}", (uint64_t)sceneHandle); + return false; + } + + m_RuntimeScene = scene; + if (m_SceneRenderer) + m_SceneRenderer->SetScene(m_RuntimeScene); + + Application::Get().GetWindow().SetTitle(m_RuntimeScene->GetName().empty() ? "Lux Runtime" : m_RuntimeScene->GetName()); + return true; + } + + void RuntimeLayer::OnScenePlay() + { + if (!m_RuntimeScene || m_SceneRunning) + return; + + m_RuntimeScene->OnRuntimeStart(); + m_SceneRunning = true; + } + + void RuntimeLayer::OnSceneStop() + { + if (!m_RuntimeScene || !m_SceneRunning) + return; + + m_RuntimeScene->OnRuntimeStop(); + m_SceneRunning = false; + } + + void RuntimeLayer::CreateSwapChainResources() + { + FramebufferSpecification framebufferSpec; + framebufferSpec.DebugName = "RuntimeSwapChain"; + framebufferSpec.SwapChainTarget = true; + framebufferSpec.ClearColor = { 0.01f, 0.01f, 0.012f, 1.0f }; + framebufferSpec.Attachments = { ImageFormat::RGBA }; + m_SwapChainFramebuffer = Framebuffer::Create(framebufferSpec); + + PipelineSpecification pipelineSpec; + pipelineSpec.Layout = { + { ShaderDataType::Float3, "a_Position" }, + { ShaderDataType::Float2, "a_TexCoord" } + }; + pipelineSpec.BackfaceCulling = false; + pipelineSpec.DepthTest = false; + pipelineSpec.DepthWrite = false; + pipelineSpec.Shader = Renderer::GetShaderLibrary()->Get("TexturePass"); + pipelineSpec.TargetFramebuffer = m_SwapChainFramebuffer; + pipelineSpec.DebugName = "RuntimeSwapChain"; + + RenderPassSpecification renderPassSpec; + renderPassSpec.DebugName = "RuntimeSwapChain"; + renderPassSpec.Pipeline = Pipeline::Create(pipelineSpec); + m_SwapChainRenderPass = RenderPass::Create(renderPassSpec); + m_SwapChainRenderPass->Bake(); + + m_SwapChainMaterial = Material::Create(pipelineSpec.Shader, "RuntimeSwapChain"); + m_CommandBuffer = RenderCommandBuffer::Create(0, "RuntimeSwapChain", true); + } + + void RuntimeLayer::RecreateSwapChainResources(uint32_t width, uint32_t height) + { + if (!m_SwapChainFramebuffer) + return; + + m_SwapChainFramebuffer->Resize(width, height, true); + if (m_SwapChainRenderPass && m_SwapChainRenderPass->GetPipeline()) + m_SwapChainRenderPass->GetPipeline()->Invalidate(); + } + + void RuntimeLayer::OnUpdate(Timestep ts) + { + if (!m_RuntimeScene || !m_SceneRenderer) + return; + + AssetManager::SyncWithAssetThread(); + + m_UpdateFPSTimer -= ts; + if (m_UpdateFPSTimer <= 0.0f) + { + UpdateFPSStat(); + m_UpdateFPSTimer = 1.0f; + } + + m_UpdatePerformanceTimer -= ts; + if (m_UpdatePerformanceTimer <= 0.0f) + { + UpdatePerformanceTimers(); + m_UpdatePerformanceTimer = 0.2f; + } + + auto [width, height] = Application::Get().GetWindow().GetSize(); + if (width == 0 || height == 0) + return; + + if (m_Width != width || m_Height != height) + { + m_Width = width; + m_Height = height; + RecreateSwapChainResources(width, height); + } + + m_SceneRenderer->SetViewportSize(width, height); + m_RuntimeScene->OnViewportResize(width, height); + m_Renderer2DProjection = glm::ortho(0.0f, (float)width, 0.0f, (float)height); + + m_RuntimeScene->OnUpdateRuntime(ts); + m_RuntimeScene->OnRenderRuntime(m_SceneRenderer); + + DrawRuntimeOverlay(); + SubmitFinalImageToSwapChain(); + } + + void RuntimeLayer::SubmitFinalImageToSwapChain() + { + if (!m_CommandBuffer || !m_SwapChainRenderPass || !m_SwapChainMaterial) + return; + + if (Ref finalImage = m_SceneRenderer->GetFinalPassImage()) + m_SwapChainMaterial->Set("u_Texture", finalImage); + + m_CommandBuffer->Begin(); + Renderer::BeginRenderPass(m_CommandBuffer, m_SwapChainRenderPass, true); + if (m_SceneRenderer->GetFinalPassImage()) + Renderer::SubmitFullscreenQuad(m_CommandBuffer, m_SwapChainRenderPass->GetPipeline(), m_SwapChainMaterial); + Renderer::EndRenderPass(m_CommandBuffer); + m_CommandBuffer->End(); + + SubmitCommandBufferToSwapChain(); + } + + void RuntimeLayer::SubmitCommandBufferToSwapChain() + { + Ref commandBuffer = m_CommandBuffer; + vk::Semaphore acquiredSemaphore = Application::Get().GetWindow().GetSwapChain().GetAcquiredImageSemaphore(); + + Renderer::Submit([commandBuffer, acquiredSemaphore]() mutable + { + if ((VkSemaphore)acquiredSemaphore) + commandBuffer->RT_Wait((VkSemaphore)acquiredSemaphore); + commandBuffer->RT_Submit(); + }); + } + + void RuntimeLayer::DrawRuntimeOverlay() + { + if (!m_Renderer2D || (!m_ShowDebugDisplay && !ShouldShowIntroVersion())) + return; + + m_Renderer2D->SetTargetFramebuffer(m_SceneRenderer->GetExternalCompositeFramebuffer()); + m_Renderer2D->BeginScene(m_Renderer2DProjection, glm::mat4(1.0f)); + + if (m_ShowDebugDisplay) + DrawDebugStats(); + if (ShouldShowIntroVersion()) + DrawVersionInfo(); + + m_Renderer2D->EndScene(); + } + + void RuntimeLayer::DrawDebugStats() + { + const float fontSize = 22.0f; + glm::vec2 position = { 20.0f, (float)m_Height - 35.0f }; + + DrawString(std::format("{} fps", m_FramesPerSecond), position, { 0.2f, 1.0f, 0.2f, 1.0f }, fontSize); + position.y -= fontSize; + DrawString(std::format("{:.2f} ms frame", m_FrameTime), position, { 0.2f, 1.0f, 0.2f, 1.0f }, fontSize); + position.y -= fontSize; + DrawString(std::format("{:.2f} ms CPU", m_CPUTime), position, { 0.2f, 1.0f, 0.2f, 1.0f }, fontSize); + position.y -= fontSize; + DrawString(std::format("{:.2f} ms GPU", m_GPUTime), position, { 0.2f, 1.0f, 0.2f, 1.0f }, fontSize); + + const auto gpuStats = Renderer::GetGPUMemoryStats(); + position.y -= fontSize; + DrawString(std::format("{}/{} VRAM", Utils::BytesToString(gpuStats.Used), Utils::BytesToString(gpuStats.TotalAvailable)), position, { 0.2f, 1.0f, 0.2f, 1.0f }, fontSize); + position.y -= fontSize; + DrawString(std::format("{} draws, {} instances", Renderer::GetDrawcallCount(), Renderer::GetInstanceCount()), position, { 0.2f, 1.0f, 0.2f, 1.0f }, fontSize); + } + + void RuntimeLayer::DrawVersionInfo() + { + const float alpha = glm::clamp(1.0f - (Application::Get().GetTime() / m_IntroVersionDuration), 0.0f, 1.0f); + DrawString(LUX_VERSION_LONG, { 20.0f, 25.0f }, { 1.0f, 1.0f, 1.0f, alpha }, 26.0f, false); + if (m_AssetPack) + DrawString(std::format("AssetPack {}", m_AssetPack->GetBuildVersion()), { 20.0f, 55.0f }, { 1.0f, 1.0f, 1.0f, alpha }, 20.0f, false); + } + + void RuntimeLayer::DrawString(const std::string& text, const glm::vec2& position, const glm::vec4& color, float size, bool shadow) + { + if (!m_Renderer2D) + return; + + glm::mat4 scale = glm::scale(glm::mat4(1.0f), glm::vec3(size)); + if (shadow) + { + glm::mat4 shadowTransform = glm::translate(glm::mat4(1.0f), { position.x + 1.0f, position.y - 1.0f, -0.20f }) * scale; + m_Renderer2D->DrawString(text, Font::GetDefaultMonoSpacedFont(), shadowTransform, 1000.0f, { 0.0f, 0.0f, 0.0f, color.a }); + } + + glm::mat4 transform = glm::translate(glm::mat4(1.0f), { position.x, position.y, -0.21f }) * scale; + m_Renderer2D->DrawString(text, Font::GetDefaultMonoSpacedFont(), transform, 1000.0f, color); + } + + void RuntimeLayer::UpdateFPSStat() + { + const float frameTime = (float)Application::Get().GetFrametime(); + m_FramesPerSecond = frameTime > 0.0f ? (uint32_t)(1.0f / frameTime) : 0; + } + + void RuntimeLayer::UpdatePerformanceTimers() + { + const auto& app = Application::Get(); + m_FrameTime = (float)app.GetFrametime().GetMilliseconds(); + + const auto& appTimers = app.GetPerformanceTimers(); + m_CPUTime = appTimers.MainThreadWorkTime + appTimers.MainThreadWaitTime + appTimers.RenderThreadWorkTime + appTimers.RenderThreadWaitTime; + m_GPUTime = m_SceneRenderer ? m_SceneRenderer->GetStatistics().TotalGPUTime : 0.0f; + } + + bool RuntimeLayer::ShouldShowIntroVersion() const + { + return Application::Get().GetTime() < m_IntroVersionDuration; + } + + void RuntimeLayer::OnEvent(Event& event) + { + EventDispatcher dispatcher(event); + dispatcher.Dispatch([this](KeyPressedEvent& keyEvent) + { + if (keyEvent.GetRepeatCount() == 0 && Input::IsKeyDown(KeyCode::LeftControl) && keyEvent.GetKeyCode() == KeyCode::F3) + { + m_ShowDebugDisplay = !m_ShowDebugDisplay; + return true; + } + + return false; + }); + } +} diff --git a/Lux-Runtime/src/RuntimeLayer.h b/Lux-Runtime/src/RuntimeLayer.h new file mode 100644 index 00000000..9278a84e --- /dev/null +++ b/Lux-Runtime/src/RuntimeLayer.h @@ -0,0 +1,73 @@ +#pragma once + +#include "Lux.h" + +#include "Lux/Renderer/SceneRenderer.h" +#include "Lux/Serialization/AssetPack.h" + +#include + +namespace Lux +{ + class Project; + + class RuntimeLayer : public Layer + { + public: + explicit RuntimeLayer(std::filesystem::path projectPath); + virtual ~RuntimeLayer() = default; + + void OnAttach() override; + void OnDetach() override; + void OnUpdate(Timestep ts) override; + void OnEvent(Event& event) override; + + private: + bool OpenProject(); + bool LoadScene(AssetHandle sceneHandle); + + void OnScenePlay(); + void OnSceneStop(); + void CreateSwapChainResources(); + void RecreateSwapChainResources(uint32_t width, uint32_t height); + void SubmitFinalImageToSwapChain(); + void SubmitCommandBufferToSwapChain(); + + void DrawRuntimeOverlay(); + void DrawDebugStats(); + void DrawVersionInfo(); + void DrawString(const std::string& text, const glm::vec2& position, const glm::vec4& color = glm::vec4(1.0f), float size = 24.0f, bool shadow = true); + void UpdateFPSStat(); + void UpdatePerformanceTimers(); + bool ShouldShowIntroVersion() const; + + private: + std::filesystem::path m_ProjectPath; + + Ref m_RuntimeProject; + Ref m_RuntimeScene; + Ref m_SceneRenderer; + Ref m_Renderer2D; + Ref m_AssetPack; + + Ref m_CommandBuffer; + Ref m_SwapChainFramebuffer; + Ref m_SwapChainRenderPass; + Ref m_SwapChainMaterial; + + glm::mat4 m_Renderer2DProjection{ 1.0f }; + + uint32_t m_Width = 0; + uint32_t m_Height = 0; + uint32_t m_FramesPerSecond = 0; + float m_UpdateFPSTimer = 0.0f; + float m_UpdatePerformanceTimer = 0.0f; + float m_FrameTime = 0.0f; + float m_CPUTime = 0.0f; + float m_GPUTime = 0.0f; + float m_IntroVersionDuration = 5.0f; + + bool m_SceneRunning = false; + bool m_ShowDebugDisplay = false; + }; +} diff --git a/README.md b/README.md index 1ebea6cd..ea12cfa0 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ If the repository was cloned non-recursively previously, use `git submodule upda 1. Run the [Setup.bat](scripts/Setup.bat) file found in the `scripts` folder. This validates Python packages, checks the Vulkan SDK, pulls Git LFS assets and submodules, and generates project files. 2. One prerequisite is the Vulkan SDK 1.4.x. If it is not installed, the script will download `VulkanSDK.exe` and prompt the user to install the SDK. 3. After installation, run [Setup.bat](scripts/Setup.bat) again. Debug builds require the Vulkan SDK shader debug libraries. -4. The setup script generates the root Visual Studio solution and the Sandbox project files. If changes are made, or if you want to regenerate project files, rerun the [Win-GenProjects.bat](scripts/Win-GenProjects.bat) script file found in the `scripts` folder. +4. The setup script generates the root Visual Studio solution, Editor project files, and Lux-Runtime project files. If changes are made, or if you want to regenerate project files, rerun the [Win-GenProjects.bat](scripts/Win-GenProjects.bat) script file found in the `scripts` folder. *** diff --git a/Sandbox/Resources/Fonts/FontAwesome/LICENSE.txt b/Sandbox/Resources/Fonts/FontAwesome/LICENSE.txt deleted file mode 100644 index fcb0548d..00000000 --- a/Sandbox/Resources/Fonts/FontAwesome/LICENSE.txt +++ /dev/null @@ -1,165 +0,0 @@ -Fonticons, Inc. (https://fontawesome.com) - --------------------------------------------------------------------------------- - -Font Awesome Free License - -Font Awesome Free is free, open source, and GPL friendly. You can use it for -commercial projects, open source projects, or really almost whatever you want. -Full Font Awesome Free license: https://fontawesome.com/license/free. - --------------------------------------------------------------------------------- - -# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) - -The Font Awesome Free download is licensed under a Creative Commons -Attribution 4.0 International License and applies to all icons packaged -as SVG and JS file types. - --------------------------------------------------------------------------------- - -# Fonts: SIL OFL 1.1 License - -In the Font Awesome Free download, the SIL OFL license applies to all icons -packaged as web and desktop font files. - -Copyright (c) 2022 Fonticons, Inc. (https://fontawesome.com) -with Reserved Font Name: "Font Awesome". - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - -SIL OPEN FONT LICENSE -Version 1.1 - 26 February 2007 - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting — in part or in whole — any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. - --------------------------------------------------------------------------------- - -# Code: MIT License (https://opensource.org/licenses/MIT) - -In the Font Awesome Free download, the MIT license applies to all non-font and -non-icon files. - -Copyright 2022 Fonticons, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in the -Software without restriction, including without limitation the rights to use, copy, -modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, -and to permit persons to whom the Software is furnished to do so, subject to the -following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - --------------------------------------------------------------------------------- - -# Attribution - -Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font -Awesome Free files already contain embedded comments with sufficient -attribution, so you shouldn't need to do anything additional when using these -files normally. - -We've kept attribution comments terse, so we ask that you do not actively work -to remove them from files, especially code. They're a great way for folks to -learn about Font Awesome. - --------------------------------------------------------------------------------- - -# Brand Icons - -All brand icons are trademarks of their respective owners. The use of these -trademarks does not indicate endorsement of the trademark holder by Font -Awesome, nor vice versa. **Please do not use brand logos for any purpose except -to represent the company, product, or service to which they refer.** \ No newline at end of file diff --git a/Sandbox/Resources/Fonts/FontAwesome/fontawesome-webfont.ttf b/Sandbox/Resources/Fonts/FontAwesome/fontawesome-webfont.ttf deleted file mode 100644 index 35acda2f..00000000 Binary files a/Sandbox/Resources/Fonts/FontAwesome/fontawesome-webfont.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/Roboto/LICENSE.txt b/Sandbox/Resources/Fonts/Roboto/LICENSE.txt deleted file mode 100644 index d6456956..00000000 --- a/Sandbox/Resources/Fonts/Roboto/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Sandbox/Resources/Fonts/Roboto/Roboto-Black.ttf b/Sandbox/Resources/Fonts/Roboto/Roboto-Black.ttf deleted file mode 100644 index 43a00e0d..00000000 Binary files a/Sandbox/Resources/Fonts/Roboto/Roboto-Black.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/Roboto/Roboto-BlackItalic.ttf b/Sandbox/Resources/Fonts/Roboto/Roboto-BlackItalic.ttf deleted file mode 100644 index 5082cdc4..00000000 Binary files a/Sandbox/Resources/Fonts/Roboto/Roboto-BlackItalic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/Roboto/Roboto-Bold.ttf b/Sandbox/Resources/Fonts/Roboto/Roboto-Bold.ttf deleted file mode 100644 index 37424579..00000000 Binary files a/Sandbox/Resources/Fonts/Roboto/Roboto-Bold.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/Roboto/Roboto-BoldItalic.ttf b/Sandbox/Resources/Fonts/Roboto/Roboto-BoldItalic.ttf deleted file mode 100644 index e85e7fb9..00000000 Binary files a/Sandbox/Resources/Fonts/Roboto/Roboto-BoldItalic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/Roboto/Roboto-Italic.ttf b/Sandbox/Resources/Fonts/Roboto/Roboto-Italic.ttf deleted file mode 100644 index c9df607a..00000000 Binary files a/Sandbox/Resources/Fonts/Roboto/Roboto-Italic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/Roboto/Roboto-Light.ttf b/Sandbox/Resources/Fonts/Roboto/Roboto-Light.ttf deleted file mode 100644 index 0e977514..00000000 Binary files a/Sandbox/Resources/Fonts/Roboto/Roboto-Light.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/Roboto/Roboto-LightItalic.ttf b/Sandbox/Resources/Fonts/Roboto/Roboto-LightItalic.ttf deleted file mode 100644 index 3ad14fa7..00000000 Binary files a/Sandbox/Resources/Fonts/Roboto/Roboto-LightItalic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/Roboto/Roboto-Medium.ttf b/Sandbox/Resources/Fonts/Roboto/Roboto-Medium.ttf deleted file mode 100644 index e89b0b79..00000000 Binary files a/Sandbox/Resources/Fonts/Roboto/Roboto-Medium.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/Roboto/Roboto-MediumItalic.ttf b/Sandbox/Resources/Fonts/Roboto/Roboto-MediumItalic.ttf deleted file mode 100644 index a5a41d3d..00000000 Binary files a/Sandbox/Resources/Fonts/Roboto/Roboto-MediumItalic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/Roboto/Roboto-Regular.ttf b/Sandbox/Resources/Fonts/Roboto/Roboto-Regular.ttf deleted file mode 100644 index 3d6861b4..00000000 Binary files a/Sandbox/Resources/Fonts/Roboto/Roboto-Regular.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/Roboto/Roboto-SemiMedium.ttf b/Sandbox/Resources/Fonts/Roboto/Roboto-SemiMedium.ttf deleted file mode 100644 index 33ce09a3..00000000 Binary files a/Sandbox/Resources/Fonts/Roboto/Roboto-SemiMedium.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/Roboto/Roboto-Thin.ttf b/Sandbox/Resources/Fonts/Roboto/Roboto-Thin.ttf deleted file mode 100644 index 7d084aed..00000000 Binary files a/Sandbox/Resources/Fonts/Roboto/Roboto-Thin.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/Roboto/Roboto-ThinItalic.ttf b/Sandbox/Resources/Fonts/Roboto/Roboto-ThinItalic.ttf deleted file mode 100644 index c1733896..00000000 Binary files a/Sandbox/Resources/Fonts/Roboto/Roboto-ThinItalic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/OFL.txt b/Sandbox/Resources/Fonts/SourceCodePro/OFL.txt deleted file mode 100644 index 366206f5..00000000 --- a/Sandbox/Resources/Fonts/SourceCodePro/OFL.txt +++ /dev/null @@ -1,93 +0,0 @@ -Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/Sandbox/Resources/Fonts/SourceCodePro/README.txt b/Sandbox/Resources/Fonts/SourceCodePro/README.txt deleted file mode 100644 index 2e57b72e..00000000 --- a/Sandbox/Resources/Fonts/SourceCodePro/README.txt +++ /dev/null @@ -1,79 +0,0 @@ -Source Code Pro Variable Font -============================= - -This download contains Source Code Pro as both variable fonts and static fonts. - -Source Code Pro is a variable font with this axis: - wght - -This means all the styles are contained in these files: - SourceCodePro-VariableFont_wght.ttf - SourceCodePro-Italic-VariableFont_wght.ttf - -If your app fully supports variable fonts, you can now pick intermediate styles -that aren’t available as static fonts. Not all apps support variable fonts, and -in those cases you can use the static font files for Source Code Pro: - static/SourceCodePro-ExtraLight.ttf - static/SourceCodePro-Light.ttf - static/SourceCodePro-Regular.ttf - static/SourceCodePro-Medium.ttf - static/SourceCodePro-SemiBold.ttf - static/SourceCodePro-Bold.ttf - static/SourceCodePro-ExtraBold.ttf - static/SourceCodePro-Black.ttf - static/SourceCodePro-ExtraLightItalic.ttf - static/SourceCodePro-LightItalic.ttf - static/SourceCodePro-Italic.ttf - static/SourceCodePro-MediumItalic.ttf - static/SourceCodePro-SemiBoldItalic.ttf - static/SourceCodePro-BoldItalic.ttf - static/SourceCodePro-ExtraBoldItalic.ttf - static/SourceCodePro-BlackItalic.ttf - -Get started ------------ - -1. Install the font files you want to use - -2. Use your app's font picker to view the font family and all the -available styles - -Learn more about variable fonts -------------------------------- - - https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts - https://variablefonts.typenetwork.com - https://medium.com/variable-fonts - -In desktop apps - - https://theblog.adobe.com/can-variable-fonts-illustrator-cc - https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts - -Online - - https://developers.google.com/fonts/docs/getting_started - https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide - https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts - -Installing fonts - - MacOS: https://support.apple.com/en-us/HT201749 - Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux - Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows - -Android Apps - - https://developers.google.com/fonts/docs/android - https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts - -License -------- -Please read the full license text (OFL.txt) to understand the permissions, -restrictions and requirements for usage, redistribution, and modification. - -You can use them in your products & projects – print or digital, -commercial or otherwise. - -This isn't legal advice, please consider consulting a lawyer and see the full -license for all details. diff --git a/Sandbox/Resources/Fonts/SourceCodePro/SourceCodePro-Italic-VariableFont_wght.ttf b/Sandbox/Resources/Fonts/SourceCodePro/SourceCodePro-Italic-VariableFont_wght.ttf deleted file mode 100644 index e2e4903b..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/SourceCodePro-Italic-VariableFont_wght.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/SourceCodePro-VariableFont_wght.ttf b/Sandbox/Resources/Fonts/SourceCodePro/SourceCodePro-VariableFont_wght.ttf deleted file mode 100644 index 48f68f9b..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/SourceCodePro-VariableFont_wght.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Black.ttf b/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Black.ttf deleted file mode 100644 index 8f1b17e4..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Black.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-BlackItalic.ttf b/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-BlackItalic.ttf deleted file mode 100644 index edfad280..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-BlackItalic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Bold.ttf b/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Bold.ttf deleted file mode 100644 index 4344dd6e..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Bold.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-BoldItalic.ttf b/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-BoldItalic.ttf deleted file mode 100644 index 2c6e32f0..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-BoldItalic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-ExtraBold.ttf b/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-ExtraBold.ttf deleted file mode 100644 index a7f7374b..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-ExtraBold.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-ExtraBoldItalic.ttf b/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-ExtraBoldItalic.ttf deleted file mode 100644 index e18890a6..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-ExtraBoldItalic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-ExtraLight.ttf b/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-ExtraLight.ttf deleted file mode 100644 index 60a4d1f9..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-ExtraLight.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-ExtraLightItalic.ttf b/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-ExtraLightItalic.ttf deleted file mode 100644 index 3185d8c4..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-ExtraLightItalic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Italic.ttf b/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Italic.ttf deleted file mode 100644 index 12763f90..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Italic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Light.ttf b/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Light.ttf deleted file mode 100644 index c16e15c1..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Light.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-LightItalic.ttf b/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-LightItalic.ttf deleted file mode 100644 index 3a16fbd2..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-LightItalic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Medium.ttf b/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Medium.ttf deleted file mode 100644 index 2283fa5e..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Medium.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-MediumItalic.ttf b/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-MediumItalic.ttf deleted file mode 100644 index 030ce16d..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-MediumItalic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Regular.ttf b/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Regular.ttf deleted file mode 100644 index c37a7b78..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-Regular.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-SemiBold.ttf b/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-SemiBold.ttf deleted file mode 100644 index 93ce08c5..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-SemiBold.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-SemiBoldItalic.ttf b/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-SemiBoldItalic.ttf deleted file mode 100644 index 2992d87a..00000000 Binary files a/Sandbox/Resources/Fonts/SourceCodePro/static/SourceCodePro-SemiBoldItalic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/msgothic.ttc b/Sandbox/Resources/Fonts/msgothic.ttc deleted file mode 100644 index 7bfcdf77..00000000 Binary files a/Sandbox/Resources/Fonts/msgothic.ttc and /dev/null differ diff --git a/Sandbox/Resources/Fonts/opensans/LICENSE.txt b/Sandbox/Resources/Fonts/opensans/LICENSE.txt deleted file mode 100644 index d6456956..00000000 --- a/Sandbox/Resources/Fonts/opensans/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Sandbox/Resources/Fonts/opensans/OpenSans-Bold.ttf b/Sandbox/Resources/Fonts/opensans/OpenSans-Bold.ttf deleted file mode 100644 index efdd5e84..00000000 Binary files a/Sandbox/Resources/Fonts/opensans/OpenSans-Bold.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/opensans/OpenSans-BoldItalic.ttf b/Sandbox/Resources/Fonts/opensans/OpenSans-BoldItalic.ttf deleted file mode 100644 index 9bf9b4e9..00000000 Binary files a/Sandbox/Resources/Fonts/opensans/OpenSans-BoldItalic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/opensans/OpenSans-ExtraBold.ttf b/Sandbox/Resources/Fonts/opensans/OpenSans-ExtraBold.ttf deleted file mode 100644 index 67fcf0fb..00000000 Binary files a/Sandbox/Resources/Fonts/opensans/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/opensans/OpenSans-ExtraBoldItalic.ttf b/Sandbox/Resources/Fonts/opensans/OpenSans-ExtraBoldItalic.ttf deleted file mode 100644 index 08672280..00000000 Binary files a/Sandbox/Resources/Fonts/opensans/OpenSans-ExtraBoldItalic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/opensans/OpenSans-Italic.ttf b/Sandbox/Resources/Fonts/opensans/OpenSans-Italic.ttf deleted file mode 100644 index 11785670..00000000 Binary files a/Sandbox/Resources/Fonts/opensans/OpenSans-Italic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/opensans/OpenSans-Light.ttf b/Sandbox/Resources/Fonts/opensans/OpenSans-Light.ttf deleted file mode 100644 index 6580d3a1..00000000 Binary files a/Sandbox/Resources/Fonts/opensans/OpenSans-Light.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/opensans/OpenSans-LightItalic.ttf b/Sandbox/Resources/Fonts/opensans/OpenSans-LightItalic.ttf deleted file mode 100644 index 1e0c3319..00000000 Binary files a/Sandbox/Resources/Fonts/opensans/OpenSans-LightItalic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/opensans/OpenSans-Regular.ttf b/Sandbox/Resources/Fonts/opensans/OpenSans-Regular.ttf deleted file mode 100644 index 29bfd35a..00000000 Binary files a/Sandbox/Resources/Fonts/opensans/OpenSans-Regular.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/opensans/OpenSans-SemiBold.ttf b/Sandbox/Resources/Fonts/opensans/OpenSans-SemiBold.ttf deleted file mode 100644 index 54e7059c..00000000 Binary files a/Sandbox/Resources/Fonts/opensans/OpenSans-SemiBold.ttf and /dev/null differ diff --git a/Sandbox/Resources/Fonts/opensans/OpenSans-SemiBoldItalic.ttf b/Sandbox/Resources/Fonts/opensans/OpenSans-SemiBoldItalic.ttf deleted file mode 100644 index aebcf142..00000000 Binary files a/Sandbox/Resources/Fonts/opensans/OpenSans-SemiBoldItalic.ttf and /dev/null differ diff --git a/Sandbox/Resources/Renderer/BRDF_LUT.png b/Sandbox/Resources/Renderer/BRDF_LUT.png deleted file mode 100644 index 7c76686b..00000000 Binary files a/Sandbox/Resources/Renderer/BRDF_LUT.png and /dev/null differ diff --git a/Sandbox/Resources/Shaders/DirShadowMap.glsl b/Sandbox/Resources/Shaders/DirShadowMap.glsl deleted file mode 100644 index ca574e0e..00000000 --- a/Sandbox/Resources/Shaders/DirShadowMap.glsl +++ /dev/null @@ -1,34 +0,0 @@ -// Shadow Map shader - -#version 450 core -#pragma stage : vert - -#include - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec3 a_Normal; -layout(location = 2) in vec3 a_Tangent; -layout(location = 3) in vec3 a_Binormal; -layout(location = 4) in vec2 a_TexCoord; - -layout (push_constant) uniform PushConstants -{ - uint ObjectIndexBase; - uint Cascade; - uint _pad0; - uint _pad1; -} u_PushConstants; - -void main() -{ - mat4 transform = GetInstanceTransform(u_PushConstants.ObjectIndexBase + gl_InstanceIndex); - gl_Position = u_DirShadow.DirLightMatrices[u_PushConstants.Cascade] * transform * vec4(a_Position, 1.0); -} - -#version 450 core -#pragma stage : frag - -void main() -{ - // TODO: Check for alpha in texture -} diff --git a/Sandbox/Resources/Shaders/DirShadowMap_Anim.glsl b/Sandbox/Resources/Shaders/DirShadowMap_Anim.glsl deleted file mode 100644 index 74baa90d..00000000 --- a/Sandbox/Resources/Shaders/DirShadowMap_Anim.glsl +++ /dev/null @@ -1,44 +0,0 @@ -// Shadow Map shader - -#version 450 core -#pragma stage : vert - -#include - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec3 a_Normal; -layout(location = 2) in vec3 a_Tangent; -layout(location = 3) in vec3 a_Binormal; -layout(location = 4) in vec2 a_TexCoord; - -// Bone influences -layout(location = 5) in ivec4 a_BoneIndices; -layout(location = 6) in vec4 a_BoneWeights; - -layout(push_constant) uniform PushConstants -{ - uint ObjectIndexBase; - uint Cascade; - uint BoneTransformBaseIndex; - uint BoneTransformStride; -} u_PushConstants; - -void main() -{ - mat4 transform = GetInstanceTransform(u_PushConstants.ObjectIndexBase + gl_InstanceIndex); - - mat4 boneTransform = r_BoneTransforms.BoneTransforms[u_PushConstants.BoneTransformBaseIndex + (gl_InstanceIndex * u_PushConstants.BoneTransformStride) + a_BoneIndices[0]] * a_BoneWeights[0]; - boneTransform += r_BoneTransforms.BoneTransforms[u_PushConstants.BoneTransformBaseIndex + (gl_InstanceIndex * u_PushConstants.BoneTransformStride) + a_BoneIndices[1]] * a_BoneWeights[1]; - boneTransform += r_BoneTransforms.BoneTransforms[u_PushConstants.BoneTransformBaseIndex + (gl_InstanceIndex * u_PushConstants.BoneTransformStride) + a_BoneIndices[2]] * a_BoneWeights[2]; - boneTransform += r_BoneTransforms.BoneTransforms[u_PushConstants.BoneTransformBaseIndex + (gl_InstanceIndex * u_PushConstants.BoneTransformStride) + a_BoneIndices[3]] * a_BoneWeights[3]; - - gl_Position = u_DirShadow.DirLightMatrices[u_PushConstants.Cascade] * transform * boneTransform * vec4(a_Position, 1.0); -} - -#version 450 core -#pragma stage : frag - -void main() -{ - // TODO: Check for alpha in texture -} diff --git a/Sandbox/Resources/Shaders/EnvironmentIrradiance.glsl b/Sandbox/Resources/Shaders/EnvironmentIrradiance.glsl deleted file mode 100644 index 32ebb870..00000000 --- a/Sandbox/Resources/Shaders/EnvironmentIrradiance.glsl +++ /dev/null @@ -1,45 +0,0 @@ -#version 450 core -#pragma stage : comp - -#include -#include - -// Computes diffuse irradiance cubemap convolution for image-based lighting. -// Uses quasi Monte Carlo sampling with Hammersley sequence. - -layout(binding = 0, rgba16f) restrict writeonly uniform imageCube o_IrradianceMap; -layout(binding = 1) uniform textureCube u_RadianceMap; - -layout(push_constant) uniform Uniforms -{ - uint Samples; -} u_Uniforms; - -layout(local_size_x=32, local_size_y=32, local_size_z=1) in; -void main() -{ - vec3 N = GetCubeMapTexCoord(vec2(imageSize(o_IrradianceMap))); - - vec3 S, T; - ComputeBasisVectors(N, S, T); - - uint samples = 64 * u_Uniforms.Samples; - - // Monte Carlo integration of hemispherical irradiance. - // As a small optimization this also includes Lambertian BRDF assuming perfectly white surface (albedo of 1.0) - // so we don't need to normalize in PBR fragment shader (so technically it encodes exitant radiance rather than irradiance). - vec3 irradiance = vec3(0); - for(uint i = 0; i < samples; i++) - { - vec2 u = SampleHammersley(i, samples); - vec3 Li = TangentToWorld(SampleHemisphere(u.x, u.y), N, S, T); - float cosTheta = max(0.0, dot(Li, N)); - - // PIs here cancel out because of division by pdf. - vec3 radianceSample = textureLod(samplerCube(u_RadianceMap, r_LinearSampler), Li, 0).rgb; - irradiance += 2.0 * radianceSample * cosTheta; - } - irradiance /= vec3(samples); - - imageStore(o_IrradianceMap, ivec3(gl_GlobalInvocationID), vec4(irradiance, 1.0)); -} diff --git a/Sandbox/Resources/Shaders/EnvironmentMipFilter.glsl b/Sandbox/Resources/Shaders/EnvironmentMipFilter.glsl deleted file mode 100644 index 6c665697..00000000 --- a/Sandbox/Resources/Shaders/EnvironmentMipFilter.glsl +++ /dev/null @@ -1,90 +0,0 @@ -#version 450 core -#pragma stage : comp -#include -#include -#include - -// Pre-filters environment cube map using GGX NDF importance sampling. -// Part of specular IBL split-sum approximation. - - -const uint NumSamples = 1024; -const float InvNumSamples = 1.0 / float(NumSamples); - -vec2 SampleHammersley(uint i) -{ - return vec2(i * InvNumSamples, RadicalInverse_VdC(i)); -} - -//const int NumMipLevels = 1; -layout(binding = 0, rgba16f) restrict writeonly uniform imageCube outputTexture;//[NumMipLevels]; -layout(binding = 1) uniform textureCube inputTexture; - -layout (push_constant) uniform Uniforms -{ - float Roughness; -} u_Uniforms; - -#define PARAM_LEVEL 0 -#define PARAM_ROUGHNESS u_Uniforms.Roughness - - -layout(local_size_x=32, local_size_y=32, local_size_z=1) in; -void main(void) -{ - // Make sure we won't write past output when computing higher mipmap levels. - ivec2 outputSize = imageSize(outputTexture); - if(gl_GlobalInvocationID.x >= outputSize.x || gl_GlobalInvocationID.y >= outputSize.y) { - return; - } - - // Solid angle associated with a single cubemap texel at zero mipmap level. - // This will come in handy for importance sampling below. - vec2 inputSize = vec2(textureSize(samplerCube(inputTexture, r_LinearSampler), 0)); - float wt = 4.0 * PI / (6 * inputSize.x * inputSize.y); - - // Approximation: Assume zero viewing angle (isotropic reflections). - vec3 N = GetCubeMapTexCoord(vec2(imageSize(outputTexture))); - vec3 Lo = N; - - vec3 S, T; - ComputeBasisVectors(N, S, T); - - vec3 color = vec3(0); - float weight = 0; - - // Convolve environment map using GGX NDF importance sampling. - // Weight by cosine term since Epic claims it generally improves quality. - for(uint i = 0; i < NumSamples; i++) - { - vec2 u = SampleHammersley(i); - vec3 Lh = TangentToWorld(SampleGGX(u.x, u.y, PARAM_ROUGHNESS), N, S, T); - - // Compute incident direction (Li) by reflecting viewing direction (Lo) around half-vector (Lh). - vec3 Li = 2.0 * dot(Lo, Lh) * Lh - Lo; - - float cosLi = dot(N, Li); - if(cosLi > 0.0) { - // Use Mipmap Filtered Importance Sampling to improve convergence. - // See: https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch20.html, section 20.4 - - float cosLh = max(dot(N, Lh), 0.0); - - // GGX normal distribution function (D term) probability density function. - // Scaling by 1/4 is due to change of density in terms of Lh to Li (and since N=V, rest of the scaling factor cancels out). - float pdf = NdfGGX(cosLh, PARAM_ROUGHNESS) * 0.25; - - // Solid angle associated with this sample. - float ws = 1.0 / (NumSamples * pdf); - - // Mip level to sample from. - float mipLevel = max(0.5 * log2(ws / wt) + 1.0, 0.0); - - color += textureLod(samplerCube(inputTexture, r_LinearSampler), Li, mipLevel).rgb * cosLi; - weight += cosLi; - } - } - color /= weight; - - imageStore(outputTexture, ivec3(gl_GlobalInvocationID), vec4(color, 1.0)); -} diff --git a/Sandbox/Resources/Shaders/EquirectangularToCubeMap.glsl b/Sandbox/Resources/Shaders/EquirectangularToCubeMap.glsl deleted file mode 100644 index 54428758..00000000 --- a/Sandbox/Resources/Shaders/EquirectangularToCubeMap.glsl +++ /dev/null @@ -1,24 +0,0 @@ -// Converts equirectangular (lat-long) projection texture into a cubemap -#version 450 core -#pragma stage : comp -#include -#include - -layout(binding = 0, rgba16f) restrict writeonly uniform imageCube o_CubeMap; -layout(binding = 1) uniform texture2D u_EquirectangularTex; - -layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in; -void main() -{ - vec3 cubeTC = GetCubeMapTexCoord(vec2(imageSize(o_CubeMap))); - - // Calculate sampling coords for equirectangular texture - // https://en.wikipedia.org/wiki/Spherical_coordinate_system#Cartesian_coordinates - float phi = atan(cubeTC.z, cubeTC.x); - float theta = acos(cubeTC.y); - vec2 uv = vec2(phi / (2.0 * PI) + 0.5, theta / PI); - - vec4 color = texture(sampler2D(u_EquirectangularTex, r_LinearSampler), uv); - color = min(color, vec4(500.0)); - imageStore(o_CubeMap, ivec3(gl_GlobalInvocationID), color); -} diff --git a/Sandbox/Resources/Shaders/Grid.glsl b/Sandbox/Resources/Shaders/Grid.glsl deleted file mode 100644 index 1798dba7..00000000 --- a/Sandbox/Resources/Shaders/Grid.glsl +++ /dev/null @@ -1,60 +0,0 @@ -// Grid Shader - -#version 450 core -#pragma stage : vert -#include - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec2 a_TexCoord; - -layout(location = 0) out vec2 v_TexCoord; - -layout(push_constant) uniform PushConstants -{ - // Vertex shader - mat4 Transform; - - // Fragment shader - float Scale; - float Size; -} u_Renderer; - -void main() -{ - vec4 position = u_Camera.ViewProjectionMatrix * u_Renderer.Transform * vec4(a_Position, 1.0); - gl_Position = position; - - v_TexCoord = a_TexCoord; -} - -#version 450 core -#pragma stage : frag - -layout(location = 0) out vec4 color; - -layout(push_constant) uniform PushConstants -{ - // Vertex shader - mat4 Transform; - - // Fragment shader - float Scale; - float Size; -} u_Settings; - -layout(location = 0) in vec2 v_TexCoord; - -float grid(vec2 st, float res) -{ - vec2 grid = fract(st); - return step(res, grid.x) * step(res, grid.y); -} - -void main() -{ - float x = grid(v_TexCoord * u_Settings.Scale, u_Settings.Size); - color = vec4(vec3(0.2), 0.5) * (1.0 - x); - - if (color.a == 0.0) - discard; -} diff --git a/Sandbox/Resources/Shaders/HZB.glsl b/Sandbox/Resources/Shaders/HZB.glsl deleted file mode 100644 index 210b0ec6..00000000 --- a/Sandbox/Resources/Shaders/HZB.glsl +++ /dev/null @@ -1,113 +0,0 @@ -// --------------------------------------- -// -- Hazel Engine HZB shader -- -// --------------------------------------- -// - Adopted from Unreal's Engine 4 HZB shader - -#version 430 core -#pragma stage : comp - -#include - -#define MAX_MIP_BATCH_SIZE 4 -#define LOCAL_SIZE 8 - -layout(push_constant) uniform Info -{ - vec2 u_DispatchThreadIdToBufferUV; - vec2 u_InputViewportMaxBound; - vec2 u_InvSize; - int u_FirstLod; - bool u_IsFirstPass; -}; - -layout(binding = 0, r32f) writeonly uniform image2D o_HZB[4]; -layout(binding = 1) uniform texture2D u_InputDepth; -shared float sharedClosestDeviceZ[LOCAL_SIZE * LOCAL_SIZE]; - -vec4 Gather4(texture2D tex, vec2 bufferUV, float lod) -{ - vec2 uv[4]; - uv[0] = min(bufferUV + vec2(-0.5f, -0.5f) * u_InvSize, u_InputViewportMaxBound); - uv[1] = min(bufferUV + vec2( 0.5f, -0.5f) * u_InvSize, u_InputViewportMaxBound); - uv[2] = min(bufferUV + vec2(-0.5f, 0.5f) * u_InvSize, u_InputViewportMaxBound); - uv[3] = min(bufferUV + vec2( 0.5f, 0.5f) * u_InvSize, u_InputViewportMaxBound); - vec4 depth; - depth.x = SampleLinearLOD(tex, uv[0], lod).r; - depth.y = SampleLinearLOD(tex, uv[1], lod).r; - depth.z = SampleLinearLOD(tex, uv[2], lod).r; - depth.w = SampleLinearLOD(tex, uv[3], lod).r; - return depth; -} - - -uint SignedRightShift(uint x, const int bitshift) -{ - if (bitshift > 0) - { - return x << uint(bitshift); - } - else if (bitshift < 0) - { - return x >> uint(-bitshift); - } - return x; -} - -ivec2 InitialTilePixelPositionForReduction2x2(const uint tileSizeLog2, uint sharedArrayId) -{ - uint x = 0u; - uint y = 0u; - for (uint i = 0u; i < tileSizeLog2; i++) - { - const uint destBitId = tileSizeLog2 - 1u - i; - const uint destBitMask = 1u << destBitId; - x |= destBitMask & SignedRightShift(sharedArrayId, int(destBitId) - int(i * 2u + 0u)); - y |= destBitMask & SignedRightShift(sharedArrayId, int(destBitId) - int(i * 2u + 1u)); - } - return ivec2(x, y); -} - -layout(local_size_x = LOCAL_SIZE, local_size_y = LOCAL_SIZE, local_size_z = 1) in; -void main() -{ - ivec2 groupThreadId = InitialTilePixelPositionForReduction2x2(uint(MAX_MIP_BATCH_SIZE - 1), gl_LocalInvocationIndex); - ivec2 dispatchThreadId = ivec2(LOCAL_SIZE * gl_WorkGroupID) + groupThreadId; - vec2 bufferUV = (vec2(dispatchThreadId) + vec2(0.5)) * u_DispatchThreadIdToBufferUV.xy; - vec4 deviceZ = Gather4(u_InputDepth, bufferUV, u_FirstLod - 1); - float closestDeviceZ = max(max(deviceZ.x, deviceZ.y), max(deviceZ.z, deviceZ.w)); - ivec2 outputPixelPos = dispatchThreadId; - if(u_IsFirstPass) - { - imageStore(o_HZB[0], outputPixelPos, SampleLinearLOD(u_InputDepth, bufferUV, 0).xxxx); - } - else - { - imageStore(o_HZB[0], ivec2(outputPixelPos), closestDeviceZ.xxxx); - } - sharedClosestDeviceZ[gl_LocalInvocationIndex] = closestDeviceZ; - - barrier(); - - for (int mipLevel = 1; mipLevel < MAX_MIP_BATCH_SIZE; mipLevel++) - { - const int tileSize = LOCAL_SIZE / (1 << mipLevel); - const int reduceBankSize = tileSize * tileSize; - - if (gl_LocalInvocationIndex < reduceBankSize) - { - vec4 parentDeviceZ; - parentDeviceZ.x = closestDeviceZ; - for (uint i = 1u; i < MAX_MIP_BATCH_SIZE; i++) - { - // LDS index - parentDeviceZ[i] = sharedClosestDeviceZ[gl_LocalInvocationIndex + i * reduceBankSize]; - } - closestDeviceZ = max(max(parentDeviceZ.x, parentDeviceZ.y), max(parentDeviceZ.z, parentDeviceZ.w)); - outputPixelPos = outputPixelPos >> ivec2(1); - sharedClosestDeviceZ[gl_LocalInvocationIndex] = closestDeviceZ; - imageStore(o_HZB[mipLevel], outputPixelPos, closestDeviceZ.xxxx); - } - } -} - - diff --git a/Sandbox/Resources/Shaders/HazelPBR_Anim.glsl b/Sandbox/Resources/Shaders/HazelPBR_Anim.glsl deleted file mode 100644 index 2e6cf1db..00000000 --- a/Sandbox/Resources/Shaders/HazelPBR_Anim.glsl +++ /dev/null @@ -1,361 +0,0 @@ -/*// -- Hazel Engine PBR shader -- -// ----------------------------- -// Note: this shader is still very much in progress. There are likely many bugs and future additions that will go in. -// Currently heavily updated. -// -// References upon which this is based: -// - Unreal Engine 4 PBR notes (https://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf) -// - Frostbite's SIGGRAPH 2014 paper (https://seblagarde.wordpress.com/2015/07/14/siggraph-2014-moving-frostbite-to-physically-based-rendering/) -// - Michał Siejak's PBR project (https://github.com/Nadrin) -// - My implementation from years ago in the Sparky engine (https://github.com/TheCherno/Sparky) -*/ -#version 450 core -#pragma stage:vert - -#include -#include -#include - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec3 a_Normal; -layout(location = 2) in vec3 a_Tangent; -layout(location = 3) in vec3 a_Binormal; -layout(location = 4) in vec2 a_TexCoord; - -// Bone influences -layout(location = 5) in ivec4 a_BoneIndices; -layout(location = 6) in vec4 a_BoneWeights; - -layout(push_constant) uniform PushConstants -{ - // Vertex Shader - uint ObjectIndexBase; - uint _pad; - uint BoneBase; - uint BoneStride; - - // Fragment Shader - vec3 AlbedoColor; - float Metalness; - float Roughness; - float Emission; - - float EnvMapRotation; - - bool UseNormalMap; -} u_MaterialUniforms; - -struct VertexOutput -{ - vec3 WorldPosition; - vec3 Normal; - vec2 TexCoord; - mat3 WorldNormals; - mat3 WorldTransform; - vec3 Binormal; - - mat3 CameraView; - - vec3 ShadowMapCoords[4]; - vec3 ViewPosition; -}; - -layout(location = 0) out VertexOutput Output; - -// Make sure both shaders compute the exact same answer(PreDepth). -// We need to have the same exact calculations to produce the gl_Position value (eg. matrix multiplications). -invariant gl_Position; - -void main() -{ - mat4 transform = GetInstanceTransform(u_MaterialUniforms.ObjectIndexBase + gl_InstanceIndex); - - mat4 boneTransform = r_BoneTransforms.BoneTransforms[u_MaterialUniforms.BoneBase + (gl_InstanceIndex * u_MaterialUniforms.BoneStride) + a_BoneIndices[0]] * a_BoneWeights[0]; - boneTransform += r_BoneTransforms.BoneTransforms[u_MaterialUniforms.BoneBase + (gl_InstanceIndex * u_MaterialUniforms.BoneStride) + a_BoneIndices[1]] * a_BoneWeights[1]; - boneTransform += r_BoneTransforms.BoneTransforms[u_MaterialUniforms.BoneBase + (gl_InstanceIndex * u_MaterialUniforms.BoneStride) + a_BoneIndices[2]] * a_BoneWeights[2]; - boneTransform += r_BoneTransforms.BoneTransforms[u_MaterialUniforms.BoneBase + (gl_InstanceIndex * u_MaterialUniforms.BoneStride) + a_BoneIndices[3]] * a_BoneWeights[3]; - - vec4 worldPosition = transform * boneTransform * vec4(a_Position, 1.0); - - Output.WorldPosition = worldPosition.xyz; - Output.Normal = mat3(transform) * mat3(boneTransform) * a_Normal; - Output.TexCoord = vec2(a_TexCoord.x, 1.0 - a_TexCoord.y); - Output.WorldNormals = mat3(transform) * mat3(boneTransform) * mat3(a_Tangent, a_Binormal, a_Normal); - Output.WorldTransform = mat3(transform) * mat3(boneTransform); - Output.Binormal = mat3(transform) * mat3(boneTransform) * a_Binormal; - - Output.CameraView = mat3(u_Camera.ViewMatrix); - - vec4 shadowCoords[4]; - shadowCoords[0] = u_DirShadow.DirLightMatrices[0] * vec4(Output.WorldPosition.xyz, 1.0); - shadowCoords[1] = u_DirShadow.DirLightMatrices[1] * vec4(Output.WorldPosition.xyz, 1.0); - shadowCoords[2] = u_DirShadow.DirLightMatrices[2] * vec4(Output.WorldPosition.xyz, 1.0); - shadowCoords[3] = u_DirShadow.DirLightMatrices[3] * vec4(Output.WorldPosition.xyz, 1.0); - Output.ShadowMapCoords[0] = vec3(shadowCoords[0].xyz / shadowCoords[0].w); - Output.ShadowMapCoords[1] = vec3(shadowCoords[1].xyz / shadowCoords[1].w); - Output.ShadowMapCoords[2] = vec3(shadowCoords[2].xyz / shadowCoords[2].w); - Output.ShadowMapCoords[3] = vec3(shadowCoords[3].xyz / shadowCoords[3].w); - - Output.ViewPosition = vec3(u_Camera.ViewMatrix * vec4(Output.WorldPosition, 1.0)); - - gl_Position = u_Camera.ViewProjectionMatrix * worldPosition; -} - - -#version 450 core - -#pragma stage : frag - -#include -#include -#include -#include -#include -#include - -// Constant normal incidence Fresnel factor for all dielectrics. -const vec3 Fdielectric = vec3(0.04); - -struct VertexOutput -{ - vec3 WorldPosition; - vec3 Normal; - vec2 TexCoord; - mat3 WorldNormals; - mat3 WorldTransform; - vec3 Binormal; - - mat3 CameraView; - - vec3 ShadowMapCoords[4]; - vec3 ViewPosition; -}; - -layout(location = 0) in VertexOutput Input; - -layout(location = 0) out vec4 color; -layout(location = 1) out vec4 o_ViewNormalsLuminance; -layout(location = 2) out vec4 o_MetalnessRoughness; - -layout(push_constant) uniform PushConstants -{ - // Vertex Shader - uint ObjectIndexBase; - uint _pad; - uint BoneBase; - uint BoneStride; - - // Fragment Shader - vec3 AlbedoColor; - float Metalness; - float Roughness; - float Emission; - - float EnvMapRotation; - - bool UseNormalMap; -} u_MaterialUniforms; - -vec3 IBL(vec3 F0, vec3 Lr) -{ - vec3 irradiance = SampleLinear(u_EnvIrradianceTex, m_Params.Normal).rgb; - vec3 F = FresnelSchlickRoughness(F0, m_Params.NdotV, m_Params.Roughness); - vec3 kd = (1.0 - F) * (1.0 - m_Params.Metalness); - vec3 diffuseIBL = m_Params.Albedo * irradiance; - - int envRadianceTexLevels = textureQueryLevels(samplerCube(u_EnvRadianceTex, r_LinearSampler)); - vec3 specularIrradiance = SampleLinearLOD(u_EnvRadianceTex, RotateVectorAboutY(u_MaterialUniforms.EnvMapRotation, Lr), m_Params.Roughness * envRadianceTexLevels).rgb; - - vec2 specularBRDF = SampleLinear(u_BRDFLUTTexture, vec2(m_Params.NdotV, m_Params.Roughness)).rg; - vec3 specularIBL = specularIrradiance * (F0 * specularBRDF.x + specularBRDF.y); - - return kd * diffuseIBL + specularIBL; -} - - -///////////////////////////////////////////// - -vec3 GetGradient(float value) -{ - vec3 zero = vec3(0.0, 0.0, 0.0); - vec3 white = vec3(0.0, 0.1, 0.9); - vec3 red = vec3(0.2, 0.9, 0.4); - vec3 blue = vec3(0.8, 0.8, 0.3); - vec3 green = vec3(0.9, 0.2, 0.3); - - float step0 = 0.0f; - float step1 = 2.0f; - float step2 = 4.0f; - float step3 = 8.0f; - float step4 = 16.0f; - - vec3 color = mix(zero, white, smoothstep(step0, step1, value)); - color = mix(color, white, smoothstep(step1, step2, value)); - color = mix(color, red, smoothstep(step1, step2, value)); - color = mix(color, blue, smoothstep(step2, step3, value)); - color = mix(color, green, smoothstep(step3, step4, value)); - - return color; -} - - -void main() -{ - // Standard PBR inputs - vec4 albedoTexColor = SampleLinear(u_AlbedoTexture, Input.TexCoord); - m_Params.Albedo = albedoTexColor.rgb * ToLinear(vec4(u_MaterialUniforms.AlbedoColor, 1.0)).rgb; // MaterialUniforms.AlbedoColor is perceptual, must be converted to linear. - float alpha = albedoTexColor.a; - // note: Metalness and roughness could be in the same texture. - // Per GLTF spec, we read metalness from the B channel and roughness from the G channel - // This will still work if metalness and roughness are independent greyscale textures, - // but it will not work if metalness and roughness are independent textures containing only R channel. - m_Params.Metalness = SampleLinear(u_MetalnessTexture, Input.TexCoord).b * u_MaterialUniforms.Metalness; - m_Params.Roughness = SampleLinear(u_RoughnessTexture, Input.TexCoord).g * u_MaterialUniforms.Roughness; - o_MetalnessRoughness = vec4(m_Params.Metalness, m_Params.Roughness, 0.f, 1.f); - m_Params.Roughness = max(m_Params.Roughness, 0.05); // Minimum roughness of 0.05 to keep specular highlight - - // Normals (either from vertex or map) - m_Params.Normal = normalize(Input.Normal); - if (u_MaterialUniforms.UseNormalMap) - { - m_Params.Normal = normalize(SampleLinear(u_NormalTexture, Input.TexCoord).rgb * 2.0f - 1.0f); - m_Params.Normal = normalize(Input.WorldNormals * m_Params.Normal); - } - // View normals - o_ViewNormalsLuminance.xyz = Input.CameraView * m_Params.Normal; - - m_Params.View = normalize(u_Scene.CameraPosition - Input.WorldPosition); - m_Params.NdotV = max(dot(m_Params.Normal, m_Params.View), 0.0); - - // Specular reflection vector - vec3 Lr = 2.0 * m_Params.NdotV * m_Params.Normal - m_Params.View; - - // Fresnel reflectance, metals use albedo - vec3 F0 = mix(Fdielectric, m_Params.Albedo, m_Params.Metalness); - - uint cascadeIndex = 0; - - const uint SHADOW_MAP_CASCADE_COUNT = 4; - for (uint i = 0; i < SHADOW_MAP_CASCADE_COUNT - 1; i++) - { - if (Input.ViewPosition.z < u_RendererData.CascadeSplits[i]) - cascadeIndex = i + 1; - } - - float shadowDistance = u_RendererData.MaxShadowDistance;//u_CascadeSplits[3]; - float transitionDistance = u_RendererData.ShadowFade; - float distance = length(Input.ViewPosition); - ShadowFade = distance - (shadowDistance - transitionDistance); - ShadowFade /= transitionDistance; - ShadowFade = clamp(1.0 - ShadowFade, 0.0, 1.0); - - float shadowScale; - - bool fadeCascades = u_RendererData.CascadeFading; - if (fadeCascades) - { - float cascadeTransitionFade = u_RendererData.CascadeTransitionFade; - - float c0 = smoothstep(u_RendererData.CascadeSplits[0] + cascadeTransitionFade * 0.5f, u_RendererData.CascadeSplits[0] - cascadeTransitionFade * 0.5f, Input.ViewPosition.z); - float c1 = smoothstep(u_RendererData.CascadeSplits[1] + cascadeTransitionFade * 0.5f, u_RendererData.CascadeSplits[1] - cascadeTransitionFade * 0.5f, Input.ViewPosition.z); - float c2 = smoothstep(u_RendererData.CascadeSplits[2] + cascadeTransitionFade * 0.5f, u_RendererData.CascadeSplits[2] - cascadeTransitionFade * 0.5f, Input.ViewPosition.z); - if (c0 > 0.0 && c0 < 1.0) - { - // Sample 0 & 1 - vec3 shadowMapCoords = GetShadowMapCoords(Input.ShadowMapCoords, 0); - float shadowAmount0 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 0, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 0, shadowMapCoords); - shadowMapCoords = GetShadowMapCoords(Input.ShadowMapCoords, 1); - float shadowAmount1 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 1, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 1, shadowMapCoords); - - shadowScale = mix(shadowAmount0, shadowAmount1, c0); - } - else if (c1 > 0.0 && c1 < 1.0) - { - // Sample 1 & 2 - vec3 shadowMapCoords = GetShadowMapCoords(Input.ShadowMapCoords, 1); - float shadowAmount1 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 1, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 1, shadowMapCoords); - shadowMapCoords = GetShadowMapCoords(Input.ShadowMapCoords, 2); - float shadowAmount2 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 2, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 2, shadowMapCoords); - - shadowScale = mix(shadowAmount1, shadowAmount2, c1); - } - else if (c2 > 0.0 && c2 < 1.0) - { - // Sample 2 & 3 - vec3 shadowMapCoords = GetShadowMapCoords(Input.ShadowMapCoords, 2); - float shadowAmount2 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 2, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 2, shadowMapCoords); - shadowMapCoords = GetShadowMapCoords(Input.ShadowMapCoords, 3); - float shadowAmount3 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 3, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 3, shadowMapCoords); - - shadowScale = mix(shadowAmount2, shadowAmount3, c2); - } - else - { - vec3 shadowMapCoords = GetShadowMapCoords(Input.ShadowMapCoords, cascadeIndex); - shadowScale = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, cascadeIndex, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, cascadeIndex, shadowMapCoords); - } - } - else - { - vec3 shadowMapCoords = GetShadowMapCoords(Input.ShadowMapCoords, cascadeIndex); - shadowScale = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, cascadeIndex, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, cascadeIndex, shadowMapCoords); - } - - shadowScale = 1.0 - clamp(u_Scene.DirectionalLights.ShadowAmount - shadowScale, 0.0f, 1.0f); - - // Direct lighting - vec3 lightContribution = CalculateDirLights(F0) * shadowScale; - lightContribution += CalculatePointLights(F0, Input.WorldPosition); - lightContribution += CalculateSpotLightsShadowed(F0, Input.WorldPosition, u_SpotShadowTexture);//CalculateSpotLights(F0, Input.WorldPosition) * SpotShadowCalculation(u_SpotShadowTexture, Input.WorldPosition); - lightContribution += m_Params.Albedo * u_MaterialUniforms.Emission; - - // Indirect lighting - vec3 iblContribution = IBL(F0, Lr) * u_Scene.EnvironmentMapIntensity; - - // Final color - color = vec4(iblContribution + lightContribution, 1.0); - - // TODO: Temporary bug fix. - if (u_Scene.DirectionalLights.Multiplier <= 0.0f) - shadowScale = 0.0f; - - // Shadow mask with respect to bright surfaces. - o_ViewNormalsLuminance.a = clamp(shadowScale + dot(color.rgb, vec3(0.2125f, 0.7154f, 0.0721f)), 0.0f, 1.0f); - - if (u_RendererData.ShowLightComplexity) - { - int pointLightCount = GetPointLightCount(); - int spotLightCount = GetSpotLightCount(); - - float value = float(pointLightCount + spotLightCount); - color.rgb = (color.rgb * 0.2) + GetGradient(value); - } - - // TODO(Karim): Have a separate render pass for translucent and transparent objects. - // Because we use the pre-depth image for depth test. - // color.a = alpha; - - // (shading-only) - // color.rgb = vec3(1.0) * shadowScale + 0.2f; - - if (u_RendererData.ShowCascades) - { - switch (cascadeIndex) - { - case 0: - color.rgb *= vec3(1.0f, 0.25f, 0.25f); - break; - case 1: - color.rgb *= vec3(0.25f, 1.0f, 0.25f); - break; - case 2: - color.rgb *= vec3(0.25f, 0.25f, 1.0f); - break; - case 3: - color.rgb *= vec3(1.0f, 1.0f, 0.25f); - break; - } - } -} - - diff --git a/Sandbox/Resources/Shaders/HazelPBR_Static.glsl b/Sandbox/Resources/Shaders/HazelPBR_Static.glsl deleted file mode 100644 index d5015572..00000000 --- a/Sandbox/Resources/Shaders/HazelPBR_Static.glsl +++ /dev/null @@ -1,345 +0,0 @@ -/*// -- Hazel Engine PBR shader -- -// ----------------------------- -// Note: this shader is still very much in progress. There are likely many bugs and future additions that will go in. -// Currently heavily updated. -// -// References upon which this is based: -// - Unreal Engine 4 PBR notes (https://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf) -// - Frostbite's SIGGRAPH 2014 paper (https://seblagarde.wordpress.com/2015/07/14/siggraph-2014-moving-frostbite-to-physically-based-rendering/) -// - Michał Siejak's PBR project (https://github.com/Nadrin) -// - My implementation from years ago in the Sparky engine (https://github.com/TheCherno/Sparky) -*/ -#version 450 core -#pragma stage:vert - -#include -#include -#include - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec3 a_Normal; -layout(location = 2) in vec3 a_Tangent; -layout(location = 3) in vec3 a_Binormal; -layout(location = 4) in vec2 a_TexCoord; - -struct VertexOutput -{ - vec3 WorldPosition; - vec3 Normal; - vec2 TexCoord; - mat3 WorldNormals; - mat3 WorldTransform; - vec3 Binormal; - - mat3 CameraView; - - vec3 ShadowMapCoords[4]; - vec3 ViewPosition; -}; - -layout(location = 0) out VertexOutput Output; - -layout(push_constant) uniform PushConstants -{ - uint ObjectIndexBase; - uint _pad0; - uint _pad1; - uint _pad2; - vec3 AlbedoColor; - float Metalness; - float Roughness; - float Emission; - - float EnvMapRotation; - - bool UseNormalMap; -} u_MaterialUniforms; - -// Make sure both shaders compute the exact same answer(PreDepth). -// We need to have the same exact calculations to produce the gl_Position value (eg. matrix multiplications). -invariant gl_Position; - -void main() -{ - mat4 transform = GetInstanceTransform(u_MaterialUniforms.ObjectIndexBase + gl_InstanceIndex); - vec4 worldPosition = transform * vec4(a_Position, 1.0); - - Output.WorldPosition = worldPosition.xyz; - Output.Normal = mat3(transform) * a_Normal; - Output.TexCoord = vec2(a_TexCoord.x, 1.0 - a_TexCoord.y); - Output.WorldNormals = mat3(transform) * mat3(a_Tangent, a_Binormal, a_Normal); - Output.WorldTransform = mat3(transform); - Output.Binormal = a_Binormal; - - Output.CameraView = mat3(u_Camera.ViewMatrix); - - vec4 shadowCoords[4]; - shadowCoords[0] = u_DirShadow.DirLightMatrices[0] * vec4(Output.WorldPosition.xyz, 1.0); - shadowCoords[1] = u_DirShadow.DirLightMatrices[1] * vec4(Output.WorldPosition.xyz, 1.0); - shadowCoords[2] = u_DirShadow.DirLightMatrices[2] * vec4(Output.WorldPosition.xyz, 1.0); - shadowCoords[3] = u_DirShadow.DirLightMatrices[3] * vec4(Output.WorldPosition.xyz, 1.0); - Output.ShadowMapCoords[0] = vec3(shadowCoords[0].xyz / shadowCoords[0].w); - Output.ShadowMapCoords[1] = vec3(shadowCoords[1].xyz / shadowCoords[1].w); - Output.ShadowMapCoords[2] = vec3(shadowCoords[2].xyz / shadowCoords[2].w); - Output.ShadowMapCoords[3] = vec3(shadowCoords[3].xyz / shadowCoords[3].w); - - Output.ViewPosition = vec3(u_Camera.ViewMatrix * vec4(Output.WorldPosition, 1.0)); - - gl_Position = u_Camera.ViewProjectionMatrix * worldPosition; -} - - -#version 450 core - -#pragma stage : frag - -#include -#include -#include -#include -#include -#include - -// Constant normal incidence Fresnel factor for all dielectrics. -const vec3 Fdielectric = vec3(0.04); - -struct VertexOutput -{ - vec3 WorldPosition; - vec3 Normal; - vec2 TexCoord; - mat3 WorldNormals; - mat3 WorldTransform; - vec3 Binormal; - - mat3 CameraView; - - vec3 ShadowMapCoords[4]; - vec3 ViewPosition; -}; - -layout(location = 0) in VertexOutput Input; - -layout(location = 0) out vec4 color; -layout(location = 1) out vec4 o_ViewNormalsLuminance; -layout(location = 2) out vec4 o_MetalnessRoughness; - -layout(push_constant) uniform PushConstants -{ - uint ObjectIndexBase; - uint _pad0; - uint _pad1; - uint _pad2; - vec3 AlbedoColor; - float Metalness; - float Roughness; - float Emission; - - float EnvMapRotation; - - bool UseNormalMap; -} u_MaterialUniforms; - -vec3 IBL(vec3 F0, vec3 Lr) -{ - vec3 irradiance = SampleLinear(u_EnvIrradianceTex, m_Params.Normal).rgb; - vec3 F = FresnelSchlickRoughness(F0, m_Params.NdotV, m_Params.Roughness); - vec3 kd = (1.0 - F) * (1.0 - m_Params.Metalness); - vec3 diffuseIBL = m_Params.Albedo * irradiance; - - int envRadianceTexLevels = textureQueryLevels(samplerCube(u_EnvRadianceTex, r_LinearSampler)); - vec3 specularIrradiance = SampleLinearLOD(u_EnvRadianceTex, RotateVectorAboutY(u_MaterialUniforms.EnvMapRotation, Lr), m_Params.Roughness * envRadianceTexLevels).rgb; - - vec2 specularBRDF = SampleLinear(u_BRDFLUTTexture, vec2(m_Params.NdotV, m_Params.Roughness)).rg; - vec3 specularIBL = specularIrradiance * (F0 * specularBRDF.x + specularBRDF.y); - - return kd * diffuseIBL + specularIBL; -} - - -///////////////////////////////////////////// - -vec3 GetGradient(float value) -{ - vec3 zero = vec3(0.0, 0.0, 0.0); - vec3 white = vec3(0.0, 0.1, 0.9); - vec3 red = vec3(0.2, 0.9, 0.4); - vec3 blue = vec3(0.8, 0.8, 0.3); - vec3 green = vec3(0.9, 0.2, 0.3); - - float step0 = 0.0f; - float step1 = 2.0f; - float step2 = 4.0f; - float step3 = 8.0f; - float step4 = 16.0f; - - vec3 color = mix(zero, white, smoothstep(step0, step1, value)); - color = mix(color, white, smoothstep(step1, step2, value)); - color = mix(color, red, smoothstep(step1, step2, value)); - color = mix(color, blue, smoothstep(step2, step3, value)); - color = mix(color, green, smoothstep(step3, step4, value)); - - return color; -} - - -void main() -{ - // Standard PBR inputs - vec4 albedoTexColor = SampleLinear(u_AlbedoTexture, Input.TexCoord); - m_Params.Albedo = albedoTexColor.rgb * ToLinear(vec4(u_MaterialUniforms.AlbedoColor, 1.0)).rgb; // MaterialUniforms.AlbedoColor is perceptual, must be converted to linear. - float alpha = albedoTexColor.a; - // note: Metalness and roughness could be in the same texture. - // Per GLTF spec, we read metalness from the B channel and roughness from the G channel - // This will still work if metalness and roughness are independent greyscale textures, - // but it will not work if metalness and roughness are independent textures containing only R channel. - m_Params.Metalness = SampleLinear(u_MetalnessTexture, Input.TexCoord).b * u_MaterialUniforms.Metalness; - m_Params.Roughness = SampleLinear(u_RoughnessTexture, Input.TexCoord).g * u_MaterialUniforms.Roughness; - o_MetalnessRoughness = vec4(m_Params.Metalness, m_Params.Roughness, 0.f, 1.f); - m_Params.Roughness = max(m_Params.Roughness, 0.05); // Minimum roughness of 0.05 to keep specular highlight - - // Normals (either from vertex or map) - m_Params.Normal = normalize(Input.Normal); - if (u_MaterialUniforms.UseNormalMap) - { - m_Params.Normal = normalize(SampleLinear(u_NormalTexture, Input.TexCoord).rgb * 2.0f - 1.0f); - m_Params.Normal = normalize(Input.WorldNormals * m_Params.Normal); - } - // View normals - o_ViewNormalsLuminance.xyz = Input.CameraView * m_Params.Normal; - - m_Params.View = normalize(u_Scene.CameraPosition - Input.WorldPosition); - m_Params.NdotV = max(dot(m_Params.Normal, m_Params.View), 0.0); - - // Specular reflection vector - vec3 Lr = 2.0 * m_Params.NdotV * m_Params.Normal - m_Params.View; - - // Fresnel reflectance, metals use albedo - vec3 F0 = mix(Fdielectric, m_Params.Albedo, m_Params.Metalness); - - uint cascadeIndex = 0; - - const uint SHADOW_MAP_CASCADE_COUNT = 4; - for (uint i = 0; i < SHADOW_MAP_CASCADE_COUNT - 1; i++) - { - if (Input.ViewPosition.z < u_RendererData.CascadeSplits[i]) - cascadeIndex = i + 1; - } - - float shadowDistance = u_RendererData.MaxShadowDistance;//u_CascadeSplits[3]; - float transitionDistance = u_RendererData.ShadowFade; - float distance = length(Input.ViewPosition); - ShadowFade = distance - (shadowDistance - transitionDistance); - ShadowFade /= transitionDistance; - ShadowFade = clamp(1.0 - ShadowFade, 0.0, 1.0); - - float shadowScale; - - bool fadeCascades = u_RendererData.CascadeFading; - if (fadeCascades) - { - float cascadeTransitionFade = u_RendererData.CascadeTransitionFade; - - float c0 = smoothstep(u_RendererData.CascadeSplits[0] + cascadeTransitionFade * 0.5f, u_RendererData.CascadeSplits[0] - cascadeTransitionFade * 0.5f, Input.ViewPosition.z); - float c1 = smoothstep(u_RendererData.CascadeSplits[1] + cascadeTransitionFade * 0.5f, u_RendererData.CascadeSplits[1] - cascadeTransitionFade * 0.5f, Input.ViewPosition.z); - float c2 = smoothstep(u_RendererData.CascadeSplits[2] + cascadeTransitionFade * 0.5f, u_RendererData.CascadeSplits[2] - cascadeTransitionFade * 0.5f, Input.ViewPosition.z); - if (c0 > 0.0 && c0 < 1.0) - { - // Sample 0 & 1 - vec3 shadowMapCoords = GetShadowMapCoords(Input.ShadowMapCoords, 0); - float shadowAmount0 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 0, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 0, shadowMapCoords); - shadowMapCoords = GetShadowMapCoords(Input.ShadowMapCoords, 1); - float shadowAmount1 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 1, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 1, shadowMapCoords); - - shadowScale = mix(shadowAmount0, shadowAmount1, c0); - } - else if (c1 > 0.0 && c1 < 1.0) - { - // Sample 1 & 2 - vec3 shadowMapCoords = GetShadowMapCoords(Input.ShadowMapCoords, 1); - float shadowAmount1 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 1, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 1, shadowMapCoords); - shadowMapCoords = GetShadowMapCoords(Input.ShadowMapCoords, 2); - float shadowAmount2 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 2, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 2, shadowMapCoords); - - shadowScale = mix(shadowAmount1, shadowAmount2, c1); - } - else if (c2 > 0.0 && c2 < 1.0) - { - // Sample 2 & 3 - vec3 shadowMapCoords = GetShadowMapCoords(Input.ShadowMapCoords, 2); - float shadowAmount2 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 2, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 2, shadowMapCoords); - shadowMapCoords = GetShadowMapCoords(Input.ShadowMapCoords, 3); - float shadowAmount3 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 3, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 3, shadowMapCoords); - - shadowScale = mix(shadowAmount2, shadowAmount3, c2); - } - else - { - vec3 shadowMapCoords = GetShadowMapCoords(Input.ShadowMapCoords, cascadeIndex); - shadowScale = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, cascadeIndex, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, cascadeIndex, shadowMapCoords); - } - } - else - { - vec3 shadowMapCoords = GetShadowMapCoords(Input.ShadowMapCoords, cascadeIndex); - shadowScale = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, cascadeIndex, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, cascadeIndex, shadowMapCoords); - } - - shadowScale = 1.0 - clamp(u_Scene.DirectionalLights.ShadowAmount - shadowScale, 0.0f, 1.0f); - - // Direct lighting - vec3 lightContribution = CalculateDirLights(F0) * shadowScale; - lightContribution += CalculatePointLights(F0, Input.WorldPosition); - lightContribution += CalculateSpotLightsShadowed(F0, Input.WorldPosition, u_SpotShadowTexture); - lightContribution += m_Params.Albedo * u_MaterialUniforms.Emission; - - // Indirect lighting - vec3 iblContribution = IBL(F0, Lr) * u_Scene.EnvironmentMapIntensity; - - // Final color - color = vec4(iblContribution + lightContribution, 1.0); - - // TODO: Temporary bug fix. - if (u_Scene.DirectionalLights.Multiplier <= 0.0f) - shadowScale = 0.0f; - - // Shadow mask with respect to bright surfaces. - o_ViewNormalsLuminance.a = clamp(shadowScale + dot(color.rgb, vec3(0.2125f, 0.7154f, 0.0721f)), 0.0f, 1.0f); - - if (u_RendererData.ShowLightComplexity) - { - int pointLightCount = GetPointLightCount(); - int spotLightCount = GetSpotLightCount(); - - float value = float(pointLightCount + spotLightCount); - color.rgb = (color.rgb * 0.2) + GetGradient(value); - } - - // TODO(Karim): Have a separate render pass for translucent and transparent objects. - // Because we use the pre-depth image for depth test. - // color.a = alpha; - - // (shading-only) - // color.rgb = vec3(1.0) * shadowScale + 0.2f; - - if (u_RendererData.ShowCascades) - { - switch (cascadeIndex) - { - case 0: - color.rgb *= vec3(1.0f, 0.25f, 0.25f); - break; - case 1: - color.rgb *= vec3(0.25f, 1.0f, 0.25f); - break; - case 2: - color.rgb *= vec3(0.25f, 0.25f, 1.0f); - break; - case 3: - color.rgb *= vec3(1.0f, 1.0f, 0.25f); - break; - } - } -} - - diff --git a/Sandbox/Resources/Shaders/HazelPBR_Transparent.glsl b/Sandbox/Resources/Shaders/HazelPBR_Transparent.glsl deleted file mode 100644 index ab92b243..00000000 --- a/Sandbox/Resources/Shaders/HazelPBR_Transparent.glsl +++ /dev/null @@ -1,324 +0,0 @@ -/*// -- Hazel Engine PBR shader -- -// ----------------------------- -// Note: this shader is still very much in progress. There are likely many bugs and future additions that will go in. -// Currently heavily updated. -// -// References upon which this is based: -// - Unreal Engine 4 PBR notes (https://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf) -// - Frostbite's SIGGRAPH 2014 paper (https://seblagarde.wordpress.com/2015/07/14/siggraph-2014-moving-frostbite-to-physically-based-rendering/) -// - Michał Siejak's PBR project (https://github.com/Nadrin) -// - My implementation from years ago in the Sparky engine (https://github.com/TheCherno/Sparky) -*/ -#version 450 core -#pragma stage:vert - -#include -#include -#include - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec3 a_Normal; -layout(location = 2) in vec3 a_Tangent; -layout(location = 3) in vec3 a_Binormal; -layout(location = 4) in vec2 a_TexCoord; - -// Transform buffer -layout(location = 5) in vec4 a_MRow0; -layout(location = 6) in vec4 a_MRow1; -layout(location = 7) in vec4 a_MRow2; - -struct VertexOutput -{ - vec3 WorldPosition; - vec3 Normal; - vec2 TexCoord; - mat3 WorldNormals; - mat3 WorldTransform; - vec3 Binormal; - - mat3 CameraView; - - vec4 ShadowMapCoords[4]; - vec3 ViewPosition; -}; - -layout(location = 0) out VertexOutput Output; - -// Make sure both shaders compute the exact same answer(PreDepth). -// We need to have the same exact calculations to produce the gl_Position value (eg. matrix multiplications). -invariant gl_Position; - -void main() -{ - mat4 transform = mat4( - vec4(a_MRow0.x, a_MRow1.x, a_MRow2.x, 0.0), - vec4(a_MRow0.y, a_MRow1.y, a_MRow2.y, 0.0), - vec4(a_MRow0.z, a_MRow1.z, a_MRow2.z, 0.0), - vec4(a_MRow0.w, a_MRow1.w, a_MRow2.w, 1.0) - ); - vec4 worldPosition = transform * vec4(a_Position, 1.0); - - Output.WorldPosition = worldPosition.xyz; - Output.Normal = mat3(transform) * a_Normal; - Output.TexCoord = vec2(a_TexCoord.x, 1.0 - a_TexCoord.y); - Output.WorldNormals = mat3(transform) * mat3(a_Tangent, a_Binormal, a_Normal); - Output.WorldTransform = mat3(transform); - Output.Binormal = a_Binormal; - - Output.CameraView = mat3(u_Camera.ViewMatrix); - - Output.ShadowMapCoords[0] = u_DirShadow.DirLightMatrices[0] * vec4(Output.WorldPosition, 1.0); - Output.ShadowMapCoords[1] = u_DirShadow.DirLightMatrices[1] * vec4(Output.WorldPosition, 1.0); - Output.ShadowMapCoords[2] = u_DirShadow.DirLightMatrices[2] * vec4(Output.WorldPosition, 1.0); - Output.ShadowMapCoords[3] = u_DirShadow.DirLightMatrices[3] * vec4(Output.WorldPosition, 1.0); - Output.ViewPosition = vec3(u_Camera.ViewMatrix * vec4(Output.WorldPosition, 1.0)); - - gl_Position = u_Camera.ViewProjectionMatrix * worldPosition; -} - - -#version 450 core - -#pragma stage : frag - -#include -#include -#include -#include -#include -#include - -// Constant normal incidence Fresnel factor for all dielectrics. -const vec3 Fdielectric = vec3(0.04); - -struct VertexOutput -{ - vec3 WorldPosition; - vec3 Normal; - vec2 TexCoord; - mat3 WorldNormals; - mat3 WorldTransform; - vec3 Binormal; - - mat3 CameraView; - - vec4 ShadowMapCoords[4]; - vec3 ViewPosition; -}; - -layout(location = 0) in VertexOutput Input; - -layout(location = 0) out vec4 color; -layout(location = 1) out vec4 o_ViewNormalsLuminance; -layout(location = 2) out vec4 o_MetalnessRoughness; - -layout(push_constant) uniform Material -{ - uint ObjectIndexBase; - uint _pad; - uint BoneBase; - uint BoneStride; - - vec3 AlbedoColor; - float Transparency; - float Roughness; - float Emission; - - float EnvMapRotation; - - bool UseNormalMap; -} u_MaterialUniforms; - -vec3 IBL(vec3 F0, vec3 Lr) -{ - vec3 irradiance = SampleLinear(u_EnvIrradianceTex, m_Params.Normal).rgb; - vec3 F = FresnelSchlickRoughness(F0, m_Params.NdotV, m_Params.Roughness); - vec3 kd = (1.0 - F) * (1.0 - m_Params.Metalness); - vec3 diffuseIBL = m_Params.Albedo * irradiance; - - int envRadianceTexLevels = textureQueryLevels(samplerCube(u_EnvRadianceTex, r_LinearSampler)); - vec3 specularIrradiance = SampleLinearLOD(u_EnvRadianceTex, RotateVectorAboutY(u_MaterialUniforms.EnvMapRotation, Lr), m_Params.Roughness * envRadianceTexLevels).rgb; - - vec2 specularBRDF = SampleLinear(u_BRDFLUTTexture, vec2(m_Params.NdotV, m_Params.Roughness)).rg; - vec3 specularIBL = specularIrradiance * (F0 * specularBRDF.x + specularBRDF.y); - - return kd * diffuseIBL + specularIBL; -} - - -///////////////////////////////////////////// - -vec3 GetGradient(float value) -{ - vec3 zero = vec3(0.0, 0.0, 0.0); - vec3 white = vec3(0.0, 0.1, 0.9); - vec3 red = vec3(0.2, 0.9, 0.4); - vec3 blue = vec3(0.8, 0.8, 0.3); - vec3 green = vec3(0.9, 0.2, 0.3); - - float step0 = 0.0f; - float step1 = 2.0f; - float step2 = 4.0f; - float step3 = 8.0f; - float step4 = 16.0f; - - vec3 color = mix(zero, white, smoothstep(step0, step1, value)); - color = mix(color, white, smoothstep(step1, step2, value)); - color = mix(color, red, smoothstep(step1, step2, value)); - color = mix(color, blue, smoothstep(step2, step3, value)); - color = mix(color, green, smoothstep(step3, step4, value)); - - return color; -} - - -void main() -{ - // Standard PBR inputs - vec4 albedoTexColor = SampleLinear(u_AlbedoTexture, Input.TexCoord); - m_Params.Albedo = albedoTexColor.rgb * ToLinear(vec4(u_MaterialUniforms.AlbedoColor, 1.0)).rgb; // MaterialUniforms.AlbedoColor is perceptual, must be converted to linear. - float alpha = albedoTexColor.a; - m_Params.Metalness = 0.0f; - m_Params.Roughness = 0.0f; - m_Params.Roughness = max(m_Params.Roughness, 0.05); // Minimum roughness of 0.05 to keep specular highlight - - // Normals (either from vertex or map) - m_Params.Normal = normalize(Input.Normal); - - // View normals - //o_ViewNormalsLuminance.xyz = vec3(0.0); - - m_Params.View = normalize(u_Scene.CameraPosition - Input.WorldPosition); - m_Params.NdotV = max(dot(m_Params.Normal, m_Params.View), 0.0); - - // Specular reflection vector - vec3 Lr = 2.0 * m_Params.NdotV * m_Params.Normal - m_Params.View; - - // Fresnel reflectance, metals use albedo - vec3 F0 = mix(Fdielectric, m_Params.Albedo, m_Params.Metalness); - - uint cascadeIndex = 0; - - const uint SHADOW_MAP_CASCADE_COUNT = 4; - for (uint i = 0; i < SHADOW_MAP_CASCADE_COUNT - 1; i++) - { - if (Input.ViewPosition.z < u_RendererData.CascadeSplits[i]) - cascadeIndex = i + 1; - } - - float shadowDistance = u_RendererData.MaxShadowDistance;//u_CascadeSplits[3]; - float transitionDistance = u_RendererData.ShadowFade; - float distance = length(Input.ViewPosition); - ShadowFade = distance - (shadowDistance - transitionDistance); - ShadowFade /= transitionDistance; - ShadowFade = clamp(1.0 - ShadowFade, 0.0, 1.0); - - float shadowScale; - - bool fadeCascades = u_RendererData.CascadeFading; - if (fadeCascades) - { - float cascadeTransitionFade = u_RendererData.CascadeTransitionFade; - - float c0 = smoothstep(u_RendererData.CascadeSplits[0] + cascadeTransitionFade * 0.5f, u_RendererData.CascadeSplits[0] - cascadeTransitionFade * 0.5f, Input.ViewPosition.z); - float c1 = smoothstep(u_RendererData.CascadeSplits[1] + cascadeTransitionFade * 0.5f, u_RendererData.CascadeSplits[1] - cascadeTransitionFade * 0.5f, Input.ViewPosition.z); - float c2 = smoothstep(u_RendererData.CascadeSplits[2] + cascadeTransitionFade * 0.5f, u_RendererData.CascadeSplits[2] - cascadeTransitionFade * 0.5f, Input.ViewPosition.z); - if (c0 > 0.0 && c0 < 1.0) - { - // Sample 0 & 1 - vec3 shadowMapCoords = (Input.ShadowMapCoords[0].xyz / Input.ShadowMapCoords[0].w); - float shadowAmount0 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 0, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 0, shadowMapCoords); - shadowMapCoords = (Input.ShadowMapCoords[1].xyz / Input.ShadowMapCoords[1].w); - float shadowAmount1 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 1, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 1, shadowMapCoords); - - shadowScale = mix(shadowAmount0, shadowAmount1, c0); - } - else if (c1 > 0.0 && c1 < 1.0) - { - // Sample 1 & 2 - vec3 shadowMapCoords = (Input.ShadowMapCoords[1].xyz / Input.ShadowMapCoords[1].w); - float shadowAmount1 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 1, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 1, shadowMapCoords); - shadowMapCoords = (Input.ShadowMapCoords[2].xyz / Input.ShadowMapCoords[2].w); - float shadowAmount2 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 2, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 2, shadowMapCoords); - - shadowScale = mix(shadowAmount1, shadowAmount2, c1); - } - else if (c2 > 0.0 && c2 < 1.0) - { - // Sample 2 & 3 - vec3 shadowMapCoords = (Input.ShadowMapCoords[2].xyz / Input.ShadowMapCoords[2].w); - float shadowAmount2 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 2, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 2, shadowMapCoords); - shadowMapCoords = (Input.ShadowMapCoords[3].xyz / Input.ShadowMapCoords[3].w); - float shadowAmount3 = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, 3, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, 3, shadowMapCoords); - - shadowScale = mix(shadowAmount2, shadowAmount3, c2); - } - else - { - vec3 shadowMapCoords = (Input.ShadowMapCoords[cascadeIndex].xyz / Input.ShadowMapCoords[cascadeIndex].w); - shadowScale = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, cascadeIndex, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, cascadeIndex, shadowMapCoords); - } - } - else - { - vec3 shadowMapCoords = (Input.ShadowMapCoords[cascadeIndex].xyz / Input.ShadowMapCoords[cascadeIndex].w); - shadowScale = u_RendererData.SoftShadows ? PCSS_DirectionalLight(u_ShadowMapTexture, cascadeIndex, shadowMapCoords, u_RendererData.LightSize) : HardShadows_DirectionalLight(u_ShadowMapTexture, cascadeIndex, shadowMapCoords); - } - - shadowScale = 1.0 - clamp(u_Scene.DirectionalLights.ShadowAmount - shadowScale, 0.0f, 1.0f); - - vec3 lightContribution = CalculateDirLights(F0) * shadowScale; - lightContribution += CalculatePointLights(F0, Input.WorldPosition); - lightContribution += CalculateSpotLightsShadowed(F0, Input.WorldPosition, u_SpotShadowTexture); - lightContribution += m_Params.Albedo * u_MaterialUniforms.Emission; - - // Indirect lighting - vec3 iblContribution = IBL(F0, Lr) * u_Scene.EnvironmentMapIntensity; - - //color = vec4(iblContribution + lightContribution, 1.0); - color = vec4(m_Params.Albedo, u_MaterialUniforms.Transparency); - - // TODO: Temporary bug fix. - if (u_Scene.DirectionalLights.Multiplier <= 0.0f) - shadowScale = 0.0f; - - // Shadow mask with respect to bright surfaces. - //o_ViewNormalsLuminance.a = clamp(shadowScale + dot(color.rgb, vec3(0.2125f, 0.7154f, 0.0721f)), 0.0f, 1.0f); - - if (u_RendererData.ShowLightComplexity) - { - int pointLightCount = GetPointLightCount(); - int spotLightCount = GetSpotLightCount(); - - float value = float(pointLightCount + spotLightCount); - color.rgb = (color.rgb * 0.2) + GetGradient(value); - } - - // TODO(Karim): Have a separate render pass for translucent and transparent objects. - // Because we use the pre-depth image for depth test. - // color.a = alpha; - - // (shading-only) - // color.rgb = vec3(1.0) * shadowScale + 0.2f; - - if (u_RendererData.ShowCascades) - { - switch (cascadeIndex) - { - case 0: - color.rgb *= vec3(1.0f, 0.25f, 0.25f); - break; - case 1: - color.rgb *= vec3(0.25f, 1.0f, 0.25f); - break; - case 2: - color.rgb *= vec3(0.25f, 0.25f, 1.0f); - break; - case 3: - color.rgb *= vec3(1.0f, 1.0f, 0.25f); - break; - } - } -} - - diff --git a/Sandbox/Resources/Shaders/ImGui.glsl b/Sandbox/Resources/Shaders/ImGui.glsl deleted file mode 100644 index 96326056..00000000 --- a/Sandbox/Resources/Shaders/ImGui.glsl +++ /dev/null @@ -1,50 +0,0 @@ -#version 450 core -#pragma stage : vert - -layout(location = 0) in vec2 a_Position; -layout(location = 1) in vec2 a_TexCoord; -layout(location = 2) in vec4 a_Color; - -layout (push_constant) uniform Uniforms -{ - vec2 Scale; - vec2 Translate; -} u_Uniforms; - -struct VertexOutput -{ - vec4 Color; - vec2 TexCoord; -}; - -layout(location = 0) out VertexOutput Output; - -void main() -{ - gl_Position.xy = a_Position.xy * u_Uniforms.Scale + u_Uniforms.Translate; - gl_Position.y = -gl_Position.y; - gl_Position.zw = vec2(0, 1); - - Output.Color = a_Color; - Output.TexCoord = a_TexCoord; -} - -#version 450 core -#pragma stage : frag - -struct VertexOutput -{ - vec4 Color; - vec2 TexCoord; -}; - -layout(location = 0) in VertexOutput Input; - -layout(location = 0) out vec4 o_Color; - -layout(binding = 0) uniform sampler2D u_Texture; - -void main() -{ - o_Color = texture(u_Texture, Input.TexCoord) * Input.Color; -} diff --git a/Sandbox/Resources/Shaders/ImGui.hlsl b/Sandbox/Resources/Shaders/ImGui.hlsl deleted file mode 100644 index a86ccb3e..00000000 --- a/Sandbox/Resources/Shaders/ImGui.hlsl +++ /dev/null @@ -1,73 +0,0 @@ -#pragma stage : vert - -struct Constants -{ - float2 Scale; - float2 Translate; -}; - -[[vk::push_constant]] ConstantBuffer g_Const : register(b0, space0); - -struct VS_INPUT -{ - float2 pos : POSITION; - float2 uv : TEXCOORD0; - float4 col : COLOR0; -}; - -struct PS_INPUT -{ - float4 out_pos : SV_POSITION; - float4 out_col : COLOR0; - float2 out_uv : TEXCOORD0; -}; - -PS_INPUT main(VS_INPUT input) -{ - PS_INPUT output; - output.out_pos.xy = input.pos.xy * g_Const.Scale + g_Const.Translate; - output.out_pos.zw = float2(0, 1); - output.out_col = input.col; - output.out_uv = input.uv; - return output; -} - -#pragma stage : frag - -struct Constants -{ - float2 Scale; - float2 Translate; - uint Flags; // Bit 0: ForceOpaque, Bit 1: IsGrayscale -}; - -[[vk::push_constant]] ConstantBuffer g_ConstPS : register(b0, space0); - -struct PS_INPUT -{ - float4 pos : SV_POSITION; - float4 col : COLOR0; - float2 uv : TEXCOORD0; -}; - -[[vk::binding(0)]] Texture2D u_Texture : register(t0); -[[vk::binding(1)]] sampler u_Sampler : register(s0); - -float4 main(PS_INPUT input) : SV_Target -{ - float4 sample = u_Texture.Sample(u_Sampler, input.uv); - - // Display single-channel textures as grayscale (for depth maps) - if (g_ConstPS.Flags & 2) - { - sample.rgb = sample.r; - } - - // Force opaque rendering for debug texture visualization - if (g_ConstPS.Flags & 1) - { - sample.a = 1.0; - } - - return input.col * sample; -} diff --git a/Sandbox/Resources/Shaders/Include/Common/Common.slh b/Sandbox/Resources/Shaders/Include/Common/Common.slh deleted file mode 100644 index fb6eb613..00000000 --- a/Sandbox/Resources/Shaders/Include/Common/Common.slh +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -#define BIT(x) (1 << x) diff --git a/Sandbox/Resources/Shaders/Include/Common/GTAO.slh b/Sandbox/Resources/Shaders/Include/Common/GTAO.slh deleted file mode 100644 index 7a40d21a..00000000 --- a/Sandbox/Resources/Shaders/Include/Common/GTAO.slh +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "Common.slh" - -#define HZ_AO_METHOD_GTAO BIT(1) -#define HZ_AO_METHOD_HBAO BIT(2) - -#define HZ_REFLECTION_OCCLUSION_METHOD_GTAO BIT(1) -#define HZ_REFLECTION_OCCLUSION_METHOD_HBAO BIT(2) - -#define XE_GTAO_OCCLUSION_TERM_SCALE (1.5f) // for packing in UNORM (because raw, pre-denoised occlusion term can overshoot 1 but will later average out to 1) diff --git a/Sandbox/Resources/Shaders/Include/GLSL/Buffers.glslh b/Sandbox/Resources/Shaders/Include/GLSL/Buffers.glslh deleted file mode 100644 index 2c281e84..00000000 --- a/Sandbox/Resources/Shaders/Include/GLSL/Buffers.glslh +++ /dev/null @@ -1,182 +0,0 @@ -#pragma once - -// -// SET 1 -// - -layout (std140, set = 1, binding = 4) uniform ShadowData -{ - mat4 DirLightMatrices[4]; -} u_DirShadow; - -struct DirectionalLight -{ - vec3 Direction; - float ShadowAmount; - vec3 Radiance; - float Multiplier; -}; - -layout(std140, set = 1, binding = 5) uniform SceneData -{ - DirectionalLight DirectionalLights; - vec3 CameraPosition; // Offset = 32 - float EnvironmentMapIntensity; -} u_Scene; - - -struct PointLight -{ - vec3 Position; - float Multiplier; - vec3 Radiance; - float MinRadius; - float Radius; - float Falloff; - float LightSize; - bool CastsShadows; -}; - -layout(std140, set = 1, binding = 6) uniform PointLightData -{ - uint LightCount; - PointLight Lights[1000]; -} u_PointLights; - -struct SpotLight -{ - vec3 Position; - float Multiplier; - vec3 Direction; - float AngleAttenuation; - vec3 Radiance; - float Range; - float Angle; - float Falloff; - uint ShadowIndex; - bool SoftShadows; - bool CastsShadows; - float AtlasOffsetX; // Shadow atlas quadrant offset X - float AtlasOffsetY; // Shadow atlas quadrant offset Y - float AtlasScale; // Shadow atlas scale (0.5 for 2x2 grid) -}; - -layout(std140, set = 1, binding = 7) uniform SpotLightData -{ - uint LightCount; - SpotLight Lights[1024]; -} u_SpotLights; - -layout(std140, set = 1, binding = 8) uniform SpotShadowData -{ - mat4 Mats[16]; - uint Count; - vec3 Padding; -} u_SpotLightMatrices; - -/*layout(std430, set = 1, binding = 9) readonly buffer VisiblePointLightIndicesBuffer -{ - int Indices[]; -} s_VisiblePointLightIndicesBuffer;*/ - -/*layout(std430, set = 1, binding = 10) readonly buffer VisibleSpotLightIndicesBuffer -{ - int Indices[]; -} s_VisibleSpotLightIndicesBuffer;*/ - -// -// SET 2 -// - -layout(std140, set = 2, binding = 0) uniform Camera -{ - mat4 ViewProjectionMatrix; - mat4 InverseViewProjectionMatrix; - mat4 ProjectionMatrix; - mat4 InverseProjectionMatrix; - mat4 ViewMatrix; - mat4 InverseViewMatrix; - vec2 NDCToViewMul; - vec2 NDCToViewAdd; - vec2 DepthUnpackConsts; - vec2 CameraTanHalfFOV; -} u_Camera; - -layout(std140, set = 2, binding = 1) uniform RendererData -{ - uniform vec4 CascadeSplits; - uniform int TilesCountX; - uniform bool ShowCascades; - uniform bool SoftShadows; - uniform float LightSize; - uniform float MaxShadowDistance; - uniform float ShadowFade; - uniform bool CascadeFading; - uniform float CascadeTransitionFade; - uniform bool ShowLightComplexity; -} u_RendererData; - -layout(std140, set = 2, binding = 2) uniform ScreenData -{ - vec2 InvFullResolution; - vec2 FullResolution; - vec2 InvHalfResolution; - vec2 HalfResolution; -} u_ScreenData; - - -//layout(std140, set = 2, binding = 3) uniform HBAOData -//{ -// vec4 PerspectiveInfo; -// vec2 InvQuarterResolution; -// float RadiusToScreen; -// float NegInvR2; -// float NDotVBias; -// float AOMultiplier; -// float PowExponent; -// bool IsOrtho; -// vec4 Float2Offsets[16]; -// vec4 Jitters[16]; -// vec3 Padding; -// float ShadowTolerance; -//} u_HBAO; - - -const int AVG_NUM_BONES = 50; -const int MAX_ANIMATED_MESHES = 1024; - -layout (std140, set = 2, binding = 4) readonly buffer BoneTransforms -{ - mat4 BoneTransforms[MAX_ANIMATED_MESHES * AVG_NUM_BONES]; -} r_BoneTransforms; - -// Per object shared data buffer. Stores matrices as 3 contiguous vec4s right now. Use GetInstanceTransform to access -layout (std430, set = 2, binding = 5) readonly buffer InstanceTransforms -{ - vec4 Rows[]; -} r_InstanceTransforms; - -// Object index indirection buffer - maps gl_InstanceIndex to offset on r_InstanceTransforms -layout (std430, set = 2, binding = 6) readonly buffer ObjectIndexes -{ - uint Indices[]; -} r_ObjectIndexes; - -// Fetch instance transform from indirection buffer -// objectIndex: index into ObjectIndexes SSBO (typically objectIndexBase + gl_InstanceIndex) -// Returns the 4x4 transform matrix for this instance -mat4 GetInstanceTransform(uint objectIndex) -{ - uint transformIndex = r_ObjectIndexes.Indices[objectIndex]; - vec4 row0 = r_InstanceTransforms.Rows[transformIndex + 0]; - vec4 row1 = r_InstanceTransforms.Rows[transformIndex + 1]; - vec4 row2 = r_InstanceTransforms.Rows[transformIndex + 2]; - - return mat4( - vec4(row0.x, row1.x, row2.x, 0.0), - vec4(row0.y, row1.y, row2.y, 0.0), - vec4(row0.z, row1.z, row2.z, 0.0), - vec4(row0.w, row1.w, row2.w, 1.0) - ); -} - diff --git a/Sandbox/Resources/Shaders/Include/GLSL/Common.glslh b/Sandbox/Resources/Shaders/Include/GLSL/Common.glslh deleted file mode 100644 index 513cf5e4..00000000 --- a/Sandbox/Resources/Shaders/Include/GLSL/Common.glslh +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -const float PI = 3.141592; -const float TwoPI = 2 * PI; -const float Epsilon = 0.00001; - -vec3 RotateVectorAboutY(float angle, vec3 vec) -{ - angle = radians(angle); - mat3x3 rotationMatrix = { vec3(cos(angle),0.0,sin(angle)), - vec3(0.0,1.0,0.0), - vec3(-sin(angle),0.0,cos(angle)) }; - return rotationMatrix * vec; -} - -float Convert_sRGB_FromLinear(float theLinearValue) -{ - return theLinearValue <= 0.0031308f - ? theLinearValue * 12.92f - : pow(theLinearValue, 1.0f / 2.4f) * 1.055f - 0.055f; -} - -vec4 ToLinear(vec4 sRGB) -{ - bvec4 cutoff = lessThan(sRGB, vec4(0.04045)); - vec4 higher = pow((sRGB + vec4(0.055))/vec4(1.055), vec4(2.4)); - vec4 lower = sRGB/vec4(12.92); - - return mix(higher, lower, cutoff); -} diff --git a/Sandbox/Resources/Shaders/Include/GLSL/EnvironmentMapping.glslh b/Sandbox/Resources/Shaders/Include/GLSL/EnvironmentMapping.glslh deleted file mode 100644 index 003b51fe..00000000 --- a/Sandbox/Resources/Shaders/Include/GLSL/EnvironmentMapping.glslh +++ /dev/null @@ -1,122 +0,0 @@ -#pragma once -#include -// --------------------------------------------------------------------------------------------------- -// The following code (from Unreal Engine 4's paper) shows how to filter the environment map -// for different roughnesses. This is mean to be computed offline and stored in cube map mips, -// so turning this on online will cause poor performance -// Compute Van der Corput radical inverse -// See: http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html -float RadicalInverse_VdC(uint bits) -{ - bits = (bits << 16u) | (bits >> 16u); - bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); - bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); - bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); - bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); - return float(bits) * 2.3283064365386963e-10; // / 0x100000000 -} - -// Sample i-th point from Hammersley point set of NumSamples points total. -vec2 SampleHammersley(uint i, uint samples) -{ - float invSamples = 1.0 / float(samples); - return vec2(i * invSamples, RadicalInverse_VdC(i)); -} - -vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) -{ - float a = Roughness * Roughness; - float Phi = 2 * PI * Xi.x; - float CosTheta = sqrt((1 - Xi.y) / (1 + (a * a - 1) * Xi.y)); - float SinTheta = sqrt(1 - CosTheta * CosTheta); - vec3 H; - H.x = SinTheta * cos(Phi); - H.y = SinTheta * sin(Phi); - H.z = CosTheta; - vec3 UpVector = abs(N.z) < 0.999 ? vec3(0, 0, 1) : vec3(1, 0, 0); - vec3 TangentX = normalize(cross(UpVector, N)); - vec3 TangentY = cross(N, TangentX); - // Tangent to world space - return TangentX * H.x + TangentY * H.y + N * H.z; -} - - -// Importance sample GGX normal distribution function for a fixed roughness value. -// This returns normalized half-vector between Li & Lo. -// For derivation see: http://blog.tobias-franke.eu/2014/03/30/notes_on_importance_sampling.html -vec3 SampleGGX(float u1, float u2, float roughness) -{ - float alpha = roughness * roughness; - - float cosTheta = sqrt((1.0 - u2) / (1.0 + (alpha*alpha - 1.0) * u2)); - float sinTheta = sqrt(1.0 - cosTheta*cosTheta); // Trig. identity - float phi = TwoPI * u1; - - // Convert to Cartesian upon return. - return vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta); -} - -float TotalWeight = 0.0; - -vec3 PrefilterEnvMap(float Roughness, vec3 R) -{ - vec3 N = R; - vec3 V = R; - vec3 PrefilteredColor = vec3(0.0); - int NumSamples = 1024; - for (int i = 0; i < NumSamples; i++) - { - vec2 Xi = SampleHammersley(i, NumSamples); - vec3 H = ImportanceSampleGGX(Xi, Roughness, N); - vec3 L = 2 * dot(V, H) * H - V; - float NoL = clamp(dot(N, L), 0.0, 1.0); - if (NoL > 0) - { - //PrefilteredColor += texture(u_EnvRadianceTex, L).rgb * NoL; - TotalWeight += NoL; - } - } - return PrefilteredColor / TotalWeight; -} - -vec3 GetCubeMapTexCoord(vec2 imageSize) -{ - vec2 st = gl_GlobalInvocationID.xy / imageSize; - vec2 uv = 2.0 * vec2(st.x, 1.0 - st.y) - vec2(1.0); - - vec3 ret; - if (gl_GlobalInvocationID.z == 0) ret = vec3( 1.0, uv.y, -uv.x); - else if (gl_GlobalInvocationID.z == 1) ret = vec3( -1.0, uv.y, uv.x); - else if (gl_GlobalInvocationID.z == 2) ret = vec3( uv.x, 1.0, -uv.y); - else if (gl_GlobalInvocationID.z == 3) ret = vec3( uv.x, -1.0, uv.y); - else if (gl_GlobalInvocationID.z == 4) ret = vec3( uv.x, uv.y, 1.0); - else if (gl_GlobalInvocationID.z == 5) ret = vec3(-uv.x, uv.y, -1.0); - return normalize(ret); -} - -// Compute orthonormal basis for converting from tanget/shading space to world space. -void ComputeBasisVectors(const vec3 N, out vec3 S, out vec3 T) -{ - // Branchless select non-degenerate T. - T = cross(N, vec3(0.0, 1.0, 0.0)); - T = mix(cross(N, vec3(1.0, 0.0, 0.0)), T, step(Epsilon, dot(T, T))); - - T = normalize(T); - S = normalize(cross(N, T)); -} - -// Convert point from tangent/shading space to world space. -vec3 TangentToWorld(const vec3 v, const vec3 N, const vec3 S, const vec3 T) -{ - return S * v.x + T * v.y + N * v.z; -} - -// Uniformly sample point on a hemisphere. -// Cosine-weighted sampling would be a better fit for Lambertian BRDF but since this -// compute shader runs only once as a pre-processing step performance is not *that* important. -// See: "Physically Based Rendering" 2nd ed., section 13.6.1. -vec3 SampleHemisphere(float u1, float u2) -{ - const float u1p = sqrt(max(0.0, 1.0 - u1*u1)); - return vec3(cos(TwoPI*u2) * u1p, sin(TwoPI*u2) * u1p, u1); -} diff --git a/Sandbox/Resources/Shaders/Include/GLSL/Lighting.glslh b/Sandbox/Resources/Shaders/Include/GLSL/Lighting.glslh deleted file mode 100644 index 282ae54c..00000000 --- a/Sandbox/Resources/Shaders/Include/GLSL/Lighting.glslh +++ /dev/null @@ -1,216 +0,0 @@ -#pragma once - -#pragma stage : frag -#include -#include - -layout(std430, set = 1, binding = 9) readonly buffer VisiblePointLightIndicesBuffer -{ - int Indices[]; -} s_VisiblePointLightIndicesBuffer; - -layout(std430, set = 1, binding = 10) readonly buffer VisibleSpotLightIndicesBuffer -{ - int Indices[]; -} s_VisibleSpotLightIndicesBuffer; - -const int LIGHT_CULLING_TILE_SIZE = 16; -const int MAX_VISIBLE_LIGHTS_PER_TILE = 256; - -// Used in PBR shader -struct PBRParameters -{ - vec3 Albedo; - float Roughness; - float Metalness; - - vec3 Normal; - vec3 View; - float NdotV; -} m_Params; - -vec3 CalculateDirLights(vec3 F0) -{ - vec3 result = vec3(0.0); - for (int i = 0; i < 1; i++) //Only one light for now - { - if (u_Scene.DirectionalLights.Multiplier == 0.0) - continue; - - vec3 Li = u_Scene.DirectionalLights.Direction; - vec3 Lradiance = u_Scene.DirectionalLights.Radiance * u_Scene.DirectionalLights.Multiplier; - vec3 Lh = normalize(Li + m_Params.View); - - // Calculate angles between surface normal and various light vectors. - float cosLi = max(0.0, dot(m_Params.Normal, Li)); - float cosLh = max(0.0, dot(m_Params.Normal, Lh)); - - vec3 F = FresnelSchlickRoughness(F0, max(0.0, dot(Lh, m_Params.View)), m_Params.Roughness); - float D = NdfGGX(cosLh, m_Params.Roughness); - float G = GaSchlickGGX(cosLi, m_Params.NdotV, m_Params.Roughness); - - vec3 kd = (1.0 - F) * (1.0 - m_Params.Metalness); - vec3 diffuseBRDF = kd * m_Params.Albedo; - - // Cook-Torrance - vec3 specularBRDF = (F * D * G) / max(Epsilon, 4.0 * cosLi * m_Params.NdotV); - specularBRDF = clamp(specularBRDF, vec3(0.0f), vec3(10.0f)); - result += (diffuseBRDF + specularBRDF) * Lradiance * cosLi; - } - return result; -} - -////////////////////////////////////////// -// POINT LIGHT -////////////////////////////////////////// - - -int GetPointLightBufferIndex(int i) -{ - if (u_RendererData.TilesCountX == 0) - return i; - - ivec2 tileID = ivec2(gl_FragCoord.xy) / LIGHT_CULLING_TILE_SIZE; - tileID.x = clamp(tileID.x, 0, int(u_RendererData.TilesCountX) - 1); - int tileIndex = tileID.y * int(u_RendererData.TilesCountX) + tileID.x; - return s_VisiblePointLightIndicesBuffer.Indices[tileIndex * MAX_VISIBLE_LIGHTS_PER_TILE + i]; -} - -int GetPointLightCount() -{ - if (u_RendererData.TilesCountX == 0) - return int(u_PointLights.LightCount); - - int result = 0; - for (int i = 0; i < MAX_VISIBLE_LIGHTS_PER_TILE; i++) - { - if (GetPointLightBufferIndex(i) < 0) - break; - - result++; - } - - return result; -} - -vec3 CalculatePointLights(in vec3 F0, vec3 worldPos) -{ - vec3 result = vec3(0.0); - for (int i = 0; i < GetPointLightCount(); i++) - { - int visibleIndex = GetPointLightBufferIndex(i); - if (visibleIndex < 0) - break; - - uint lightIndex = uint(visibleIndex); - - PointLight light = u_PointLights.Lights[lightIndex]; - vec3 Li = normalize(light.Position - worldPos); - float lightDistance = length(light.Position - worldPos); - vec3 Lh = normalize(Li + m_Params.View); - - float attenuation = clamp(1.0 - (lightDistance * lightDistance) / (light.Radius * light.Radius), 0.0, 1.0); - attenuation *= mix(attenuation, 1.0, light.Falloff); - - vec3 Lradiance = light.Radiance * light.Multiplier * attenuation; - - // Calculate angles between surface normal and various light vectors. - float cosLi = max(0.0, dot(m_Params.Normal, Li)); - float cosLh = max(0.0, dot(m_Params.Normal, Lh)); - - vec3 F = FresnelSchlickRoughness(F0, max(0.0, dot(Lh, m_Params.View)), m_Params.Roughness); - float D = NdfGGX(cosLh, m_Params.Roughness); - float G = GaSchlickGGX(cosLi, m_Params.NdotV, m_Params.Roughness); - - vec3 kd = (1.0 - F) * (1.0 - m_Params.Metalness); - vec3 diffuseBRDF = kd * m_Params.Albedo; - - // Cook-Torrance - vec3 specularBRDF = (F * D * G) / max(Epsilon, 4.0 * cosLi * m_Params.NdotV); - specularBRDF = clamp(specularBRDF, vec3(0.0f), vec3(10.0f)); - result += (diffuseBRDF + specularBRDF) * Lradiance * cosLi; - } - return result; -} - - -////////////////////////////////////////// -// SPOT LIGHT -////////////////////////////////////////// - -int GetSpotLightBufferIndex(int i) -{ - if (u_RendererData.TilesCountX == 0) - return i; - - ivec2 tileID = ivec2(gl_FragCoord.xy) / LIGHT_CULLING_TILE_SIZE; - tileID.x = clamp(tileID.x, 0, int(u_RendererData.TilesCountX) - 1); - int tileIndex = tileID.y * int(u_RendererData.TilesCountX) + tileID.x; - return s_VisibleSpotLightIndicesBuffer.Indices[tileIndex * MAX_VISIBLE_LIGHTS_PER_TILE + i]; -} - - -int GetSpotLightCount() -{ - if (u_RendererData.TilesCountX == 0) - return int(u_SpotLights.LightCount); - - int result = 0; - for (int i = 0; i < MAX_VISIBLE_LIGHTS_PER_TILE; i++) - { - if (GetSpotLightBufferIndex(i) < 0) - break; - - result++; - } - - return result; -} - -vec3 CalculateSpotLights(in vec3 F0, vec3 worldPos) -{ - vec3 result = vec3(0.0); - for (int i = 0; i < GetSpotLightCount(); i++) - { - int visibleIndex = GetSpotLightBufferIndex(i); - if (visibleIndex < 0) - break; - - uint lightIndex = uint(visibleIndex); - - SpotLight light = u_SpotLights.Lights[lightIndex]; - vec3 Li = normalize(light.Position - worldPos); - float lightDistance = length(light.Position - worldPos); - - float cutoff = cos(radians(light.Angle * 0.5f)); - float scos = max(dot(-Li, normalize(light.Direction)), cutoff); - float rim = (1.0 - scos) / (1.0 - cutoff); - - float attenuation = clamp(1.0 - (lightDistance * lightDistance) / (light.Range * light.Range), 0.0, 1.0); - attenuation *= mix(attenuation, 1.0, light.Falloff); - attenuation *= 1.0 - pow(max(rim, 0.001), light.AngleAttenuation); - - vec3 Lradiance = light.Radiance * light.Multiplier * attenuation; - vec3 Lh = normalize(Li + m_Params.View); - - // Calculate angles between surface normal and various light vectors. - float cosLi = max(0.0, dot(m_Params.Normal, Li)); - float cosLh = max(0.0, dot(m_Params.Normal, Lh)); - - vec3 F = FresnelSchlickRoughness(F0, max(0.0, dot(Lh, m_Params.View)), m_Params.Roughness); - float D = NdfGGX(cosLh, m_Params.Roughness); - float G = GaSchlickGGX(cosLi, m_Params.NdotV, m_Params.Roughness); - - vec3 kd = (1.0 - F) * (1.0 - m_Params.Metalness); - vec3 diffuseBRDF = kd * m_Params.Albedo; - - // Cook-Torrance - vec3 specularBRDF = (F * D * G) / max(Epsilon, 4.0 * cosLi * m_Params.NdotV); - specularBRDF = clamp(specularBRDF, vec3(0.0f), vec3(10.0f)); - result += (diffuseBRDF + specularBRDF) * Lradiance * cosLi; - - } - return result; -} - - diff --git a/Sandbox/Resources/Shaders/Include/GLSL/PBR.glslh b/Sandbox/Resources/Shaders/Include/GLSL/PBR.glslh deleted file mode 100644 index da770cb0..00000000 --- a/Sandbox/Resources/Shaders/Include/GLSL/PBR.glslh +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once -#include - -// GGX/Towbridge-Reitz normal distribution function. -// Uses Disney's reparametrization of alpha = roughness^2 -float NdfGGX(float cosLh, float roughness) -{ - float alpha = roughness * roughness; - float alphaSq = alpha * alpha; - - float denom = (cosLh * cosLh) * (alphaSq - 1.0) + 1.0; - return alphaSq / (PI * denom * denom); -} - -// Single term for separable Schlick-GGX below. -float GaSchlickG1(float cosTheta, float k) -{ - return cosTheta / (cosTheta * (1.0 - k) + k); -} - -// Schlick-GGX approximation of geometric attenuation function using Smith's method. -float GaSchlickGGX(float cosLi, float NdotV, float roughness) -{ - float r = roughness + 1.0; - float k = (r * r) / 8.0; // Epic suggests using this roughness remapping for analytic lights. - return GaSchlickG1(cosLi, k) * GaSchlickG1(NdotV, k); -} - -float GeometrySchlickGGX(float NdotV, float roughness) -{ - float r = (roughness + 1.0); - float k = (r * r) / 8.0; - - float nom = NdotV; - float denom = NdotV * (1.0 - k) + k; - - return nom / denom; -} - -float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) -{ - float NdotV = max(dot(N, V), 0.0); - float NdotL = max(dot(N, L), 0.0); - float ggx2 = GeometrySchlickGGX(NdotV, roughness); - float ggx1 = GeometrySchlickGGX(NdotL, roughness); - - return ggx1 * ggx2; -} - -// Shlick's approximation of the Fresnel factor. -vec3 FresnelSchlick(vec3 F0, float cosTheta) -{ - return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); -} - -vec3 FresnelSchlickRoughness(vec3 F0, float cosTheta, float roughness) -{ - return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0); -} - - - - diff --git a/Sandbox/Resources/Shaders/Include/GLSL/PBR_Resources.glslh b/Sandbox/Resources/Shaders/Include/GLSL/PBR_Resources.glslh deleted file mode 100644 index af93a5db..00000000 --- a/Sandbox/Resources/Shaders/Include/GLSL/PBR_Resources.glslh +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -// PBR texture inputs -layout(set = 0, binding = 0) uniform texture2D u_AlbedoTexture; -layout(set = 0, binding = 1) uniform texture2D u_NormalTexture; -layout(set = 0, binding = 2) uniform texture2D u_MetalnessTexture; -layout(set = 0, binding = 3) uniform texture2D u_RoughnessTexture; - -// Environment maps -layout(set = 1, binding = 0) uniform textureCube u_EnvRadianceTex; -layout(set = 1, binding = 1) uniform textureCube u_EnvIrradianceTex; - -// TODO(Yan): move to header -// BRDF LUT -layout(set = 3, binding = 5) uniform texture2D u_BRDFLUTTexture; - -// Shadow maps -layout(set = 1, binding = 2) uniform texture2DArray u_ShadowMapTexture; -layout(set = 1, binding = 3) uniform texture2D u_SpotShadowTexture; diff --git a/Sandbox/Resources/Shaders/Include/GLSL/Samplers.glslh b/Sandbox/Resources/Shaders/Include/GLSL/Samplers.glslh deleted file mode 100644 index cf2bfcaf..00000000 --- a/Sandbox/Resources/Shaders/Include/GLSL/Samplers.glslh +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -layout (set = 3, binding = 0) uniform sampler r_DefaultSampler; -layout (set = 3, binding = 1) uniform sampler r_PointSampler; -layout (set = 3, binding = 2) uniform sampler r_LinearSampler; - -vec4 SampleDefault(texture2D tex, vec2 texCoord) -{ - return texture(sampler2D(tex, r_DefaultSampler), texCoord); -} - -vec4 SampleLinear(texture2D tex, vec2 texCoord) -{ - return texture(sampler2D(tex, r_LinearSampler), texCoord); -} - -vec4 SampleLinear(texture2DArray tex, vec3 texCoord) -{ - return texture(sampler2DArray(tex, r_LinearSampler), texCoord); -} - -vec4 SampleLinear(textureCube tex, vec3 texCoord) -{ - return texture(samplerCube(tex, r_LinearSampler), texCoord); -} - -uvec4 SampleLinearLOD(utexture2D tex, vec2 texCoord, float lod) -{ - return textureLod(usampler2D(tex, r_LinearSampler), texCoord, lod); -} - -vec4 SampleLinearLOD(texture2D tex, vec2 texCoord, float lod) -{ - return textureLod(sampler2D(tex, r_LinearSampler), texCoord, lod); -} - -vec4 SampleLinearLOD(texture2DArray tex, vec3 texCoord, float lod) -{ - return texture(sampler2DArray(tex, r_LinearSampler), texCoord, lod); -} - -vec4 SampleLinearLOD(textureCube tex, vec3 texCoord, float lod) -{ - return texture(samplerCube(tex, r_LinearSampler), texCoord, lod); -} - -ivec2 GetTextureSize(texture2D tex) -{ - return textureSize(sampler2D(tex, r_DefaultSampler), 0); -} - -ivec2 GetTextureSize(texture2D tex, int lod) -{ - return textureSize(sampler2D(tex, r_DefaultSampler), lod); -} \ No newline at end of file diff --git a/Sandbox/Resources/Shaders/Include/GLSL/ShadowMapping.glslh b/Sandbox/Resources/Shaders/Include/GLSL/ShadowMapping.glslh deleted file mode 100644 index 700a6517..00000000 --- a/Sandbox/Resources/Shaders/Include/GLSL/ShadowMapping.glslh +++ /dev/null @@ -1,371 +0,0 @@ - -#pragma once - -#if defined(__FRAGMENT_STAGE__) || defined(__COMPUTE_STAGE__) -#include -#include -#include - -///////////////////////////////////////////// -// PCSS -///////////////////////////////////////////// - -float ShadowFade = 1.0; //TODO(Karim): A better placement of this? - -vec3 GetShadowMapCoords(vec3 shadowMapCoords[4], uint cascade) -{ - // NOTE(Yan): this exists because AMD doesn't seem to like indexing of varyings (causes artifacts) - switch (cascade) - { - case 0: return shadowMapCoords[0]; - case 1: return shadowMapCoords[1]; - case 2: return shadowMapCoords[2]; - case 3: return shadowMapCoords[3]; - } - return vec3(0.0f); -} - -float GetDirShadowBias() -{ - const float MINIMUM_SHADOW_BIAS = 0.002; - float bias = max(MINIMUM_SHADOW_BIAS * (1.0 - dot(m_Params.Normal, u_Scene.DirectionalLights.Direction)), MINIMUM_SHADOW_BIAS); - return bias; -} - -// Convert shadow coords from clip space [-1,1] to UV space [0,1] -// Flips Y to compensate for NVRHI viewport Y-axis inversion -vec2 ShadowCoordsToUV(vec2 shadowCoords) -{ - return vec2(shadowCoords.x * 0.5 + 0.5, -shadowCoords.y * 0.5 + 0.5); -} - -float HardShadows_DirectionalLight(texture2DArray shadowMap, uint cascade, vec3 shadowCoords) -{ - float bias = GetDirShadowBias(); - float shadowMapDepth = SampleLinear(shadowMap, vec3(ShadowCoordsToUV(shadowCoords.xy), cascade)).x; - return step(shadowCoords.z, shadowMapDepth + bias) * ShadowFade; -} - -// Penumbra -// this search area estimation comes from the following article: -// http://developer.download.nvidia.com/whitepapers/2008/PCSS_Integration.pdf -float SearchWidth(float uvLightSize, float receiverDistance) -{ - const float NEAR = 0.1; - return uvLightSize * (receiverDistance - NEAR) / u_Scene.CameraPosition.z; -} - -float SearchRegionRadiusUV(float zWorld) -{ - const float light_zNear = 0.0; // 0.01 gives artifacts? maybe because of ortho proj? - const float lightRadiusUV = 0.05; - return lightRadiusUV * (zWorld - light_zNear) / zWorld; -} - -const vec2 PoissonDistribution[64] = vec2[]( - vec2(-0.94201624, -0.39906216), - vec2(0.94558609, -0.76890725), - vec2(-0.094184101, -0.92938870), - vec2(0.34495938, 0.29387760), - vec2(-0.91588581, 0.45771432), - vec2(-0.81544232, -0.87912464), - vec2(-0.38277543, 0.27676845), - vec2(0.97484398, 0.75648379), - vec2(0.44323325, -0.97511554), - vec2(0.53742981, -0.47373420), - vec2(-0.26496911, -0.41893023), - vec2(0.79197514, 0.19090188), - vec2(-0.24188840, 0.99706507), - vec2(-0.81409955, 0.91437590), - vec2(0.19984126, 0.78641367), - vec2(0.14383161, -0.14100790), - vec2(-0.413923, -0.439757), - vec2(-0.979153, -0.201245), - vec2(-0.865579, -0.288695), - vec2(-0.243704, -0.186378), - vec2(-0.294920, -0.055748), - vec2(-0.604452, -0.544251), - vec2(-0.418056, -0.587679), - vec2(-0.549156, -0.415877), - vec2(-0.238080, -0.611761), - vec2(-0.267004, -0.459702), - vec2(-0.100006, -0.229116), - vec2(-0.101928, -0.380382), - vec2(-0.681467, -0.700773), - vec2(-0.763488, -0.543386), - vec2(-0.549030, -0.750749), - vec2(-0.809045, -0.408738), - vec2(-0.388134, -0.773448), - vec2(-0.429392, -0.894892), - vec2(-0.131597, 0.065058), - vec2(-0.275002, 0.102922), - vec2(-0.106117, -0.068327), - vec2(-0.294586, -0.891515), - vec2(-0.629418, 0.379387), - vec2(-0.407257, 0.339748), - vec2(0.071650, -0.384284), - vec2(0.022018, -0.263793), - vec2(0.003879, -0.136073), - vec2(-0.137533, -0.767844), - vec2(-0.050874, -0.906068), - vec2(0.114133, -0.070053), - vec2(0.163314, -0.217231), - vec2(-0.100262, -0.587992), - vec2(-0.004942, 0.125368), - vec2(0.035302, -0.619310), - vec2(0.195646, -0.459022), - vec2(0.303969, -0.346362), - vec2(-0.678118, 0.685099), - vec2(-0.628418, 0.507978), - vec2(-0.508473, 0.458753), - vec2(0.032134, -0.782030), - vec2(0.122595, 0.280353), - vec2(-0.043643, 0.312119), - vec2(0.132993, 0.085170), - vec2(-0.192106, 0.285848), - vec2(0.183621, -0.713242), - vec2(0.265220, -0.596716), - vec2(-0.009628, -0.483058), - vec2(-0.018516, 0.435703) - ); - -const vec2 poissonDisk[16] = vec2[]( - vec2(-0.94201624, -0.39906216), - vec2(0.94558609, -0.76890725), - vec2(-0.094184101, -0.92938870), - vec2(0.34495938, 0.29387760), - vec2(-0.91588581, 0.45771432), - vec2(-0.81544232, -0.87912464), - vec2(-0.38277543, 0.27676845), - vec2(0.97484398, 0.75648379), - vec2(0.44323325, -0.97511554), - vec2(0.53742981, -0.47373420), - vec2(-0.26496911, -0.41893023), - vec2(0.79197514, 0.19090188), - vec2(-0.24188840, 0.99706507), - vec2(-0.81409955, 0.91437590), - vec2(0.19984126, 0.78641367), - vec2(0.14383161, -0.14100790) - ); - -vec2 SamplePoisson(int index) -{ - return PoissonDistribution[index % 64]; -} - -///////////////////////////////////////////// -// Directional Shadows -///////////////////////////////////////////// - -float FindBlockerDistance_DirectionalLight(texture2DArray shadowMap, uint cascade, vec3 shadowCoords, float uvLightSize) -{ - float bias = GetDirShadowBias(); - - int numBlockerSearchSamples = 64; - int blockers = 0; - float avgBlockerDistance = 0; - - float searchWidth = SearchRegionRadiusUV(shadowCoords.z); - for (int i = 0; i < numBlockerSearchSamples; i++) - { - float z = SampleLinearLOD(shadowMap, vec3(ShadowCoordsToUV(shadowCoords.xy) + SamplePoisson(i) * searchWidth, cascade), 0).r; - if (z < (shadowCoords.z - bias)) - { - blockers++; - avgBlockerDistance += z; - } - } - - if (blockers > 0) - return avgBlockerDistance / float(blockers); - - return -1; -} - -float PCF_DirectionalLight(texture2DArray shadowMap, uint cascade, vec3 shadowCoords, float uvRadius) -{ - float bias = GetDirShadowBias(); - int numPCFSamples = 64; - - float sum = 0; - for (int i = 0; i < numPCFSamples; i++) - { - vec2 offset = SamplePoisson(i) * uvRadius; - float z = SampleLinearLOD(shadowMap, vec3(ShadowCoordsToUV(shadowCoords.xy) + offset, cascade), 0).r; - sum += step(shadowCoords.z - bias, z); - } - return sum / numPCFSamples; -} - -float NV_PCF_DirectionalLight(texture2DArray shadowMap, uint cascade, vec3 shadowCoords, float uvRadius) -{ - float bias = GetDirShadowBias(); - - float sum = 0; - for (int i = 0; i < 16; i++) - { - vec2 offset = poissonDisk[i] * uvRadius; - float z = SampleLinearLOD(shadowMap, vec3(ShadowCoordsToUV(shadowCoords.xy) + offset, cascade), 0).r; - sum += step(shadowCoords.z - bias, z); - } - return sum / 16.0f; -} - -float PCSS_DirectionalLight(texture2DArray shadowMap, uint cascade, vec3 shadowCoords, float uvLightSize) -{ - float blockerDistance = FindBlockerDistance_DirectionalLight(shadowMap, cascade, shadowCoords, uvLightSize); - if (blockerDistance == -1) // No occlusion - return 1.0f; - - float penumbraWidth = (shadowCoords.z - blockerDistance) / blockerDistance; - - float NEAR = 0.01; // Should this value be tweakable? - float uvRadius = penumbraWidth * uvLightSize * NEAR / shadowCoords.z; // Do we need to divide by shadowCoords.z? - uvRadius = min(uvRadius, 0.002f); - return PCF_DirectionalLight(shadowMap, cascade, shadowCoords, uvRadius) * ShadowFade; -} - -///////////////////////////////////////////// -// Spot light Shadows (with dynamic atlas support) -// Supports up to 16 spotlights with grids: 1x1, 2x2, 3x3, 4x4 -///////////////////////////////////////////// - -const float SPOT_SHADOW_BIAS = 0.00025f; - -float HardShadows_SpotLight(texture2D shadowMap, vec2 atlasOffset, float atlasScale, vec3 shadowCoords) -{ - // Transform UV to atlas quadrant - vec2 atlasUV = shadowCoords.xy * atlasScale + atlasOffset; - float shadowMapDepth = SampleLinear(shadowMap, atlasUV).x; - return step(shadowCoords.z, shadowMapDepth + SPOT_SHADOW_BIAS); -} - -float FindBlockerDistance_SpotLight(texture2D shadowMap, vec2 atlasOffset, float atlasScale, vec3 shadowCoords, float uvLightSize) -{ - int numBlockerSearchSamples = 16; - int blockers = 0; - float avgBlockerDistance = 0; - - float searchWidth = 0.01 * atlasScale; // Scale search by atlas - for (int i = 0; i < numBlockerSearchSamples; i++) - { - vec2 sampleUV = shadowCoords.xy + SamplePoisson(i) * searchWidth; - vec2 atlasUV = sampleUV * atlasScale + atlasOffset; - float z = SampleLinearLOD(shadowMap, atlasUV, 0).r; - if (z < (shadowCoords.z - SPOT_SHADOW_BIAS)) - { - blockers++; - avgBlockerDistance += z; - } - } - - if (blockers > 0) - return avgBlockerDistance / float(blockers); - - return -1; -} - - -float PCF_SpotLight(texture2D shadowMap, vec2 atlasOffset, float atlasScale, vec3 shadowCoords, float uvRadius) -{ - float scaledRadius = uvRadius * atlasScale; // Scale radius by atlas - int numPCFSamples = 64; - - float sum = 0; - for (int i = 0; i < numPCFSamples; i++) - { - vec2 offset = SamplePoisson(i) * scaledRadius; - vec2 sampleUV = shadowCoords.xy + offset; - vec2 atlasUV = sampleUV * atlasScale + atlasOffset; - float z = SampleLinearLOD(shadowMap, atlasUV, 0).r; - sum += step(shadowCoords.z - SPOT_SHADOW_BIAS, z); - } - return sum / float(numPCFSamples); -} - - -float PCSS_SpotLight(texture2D shadowMap, vec2 atlasOffset, float atlasScale, vec3 shadowCoords, float uvLightSize) -{ - float blockerDistance = FindBlockerDistance_SpotLight(shadowMap, atlasOffset, atlasScale, shadowCoords, uvLightSize); - if (blockerDistance == -1) // No occlusion - return 1.0f; - - float penumbraWidth = (shadowCoords.z - blockerDistance) / blockerDistance; - - float NEAR = 1.0; - float uvRadius = penumbraWidth * uvLightSize * NEAR / shadowCoords.z; - uvRadius = min(uvRadius, 0.002f); - return PCF_SpotLight(shadowMap, atlasOffset, atlasScale, shadowCoords, uvRadius); -} - -vec3 CalculateSpotLightsShadowed(in vec3 F0, vec3 worldPos, texture2D SpotAtlas) -{ - vec3 result = vec3(0.0); - for (int i = 0; i < GetSpotLightCount(); i++) - { - int visibleIndex = GetSpotLightBufferIndex(i); - if (visibleIndex < 0) - break; - - uint lightIndex = uint(visibleIndex); - - SpotLight light = u_SpotLights.Lights[lightIndex]; - vec3 Li = normalize(light.Position - worldPos); - float lightDistance = length(light.Position - worldPos); - - float cutoff = cos(radians(light.Angle * 0.5f)); - float scos = max(dot(-Li, normalize(light.Direction)), cutoff); - float rim = (1.0 - scos) / (1.0 - cutoff); - - float attenuation = clamp(1.0 - (lightDistance * lightDistance) / (light.Range * light.Range), 0.0, 1.0); - attenuation *= mix(attenuation, 1.0, light.Falloff); - attenuation *= 1.0 - pow(max(rim, 0.001), light.AngleAttenuation); - - // Shadow sampling - supports up to 16 spotlights with dynamic atlas - if(light.CastsShadows && light.ShadowIndex < 16 && light.ShadowIndex < u_SpotLightMatrices.Count) - { - vec4 coords = u_SpotLightMatrices.Mats[light.ShadowIndex] * vec4(worldPos, 1.0f); - if (coords.w <= 0.0f) - continue; - - vec3 shadowMapCoords = (coords.xyz / coords.w); - // Flip Y to compensate for NVRHI viewport Y-axis inversion - shadowMapCoords.xy = ShadowCoordsToUV(shadowMapCoords.xy); - - bool outsideShadowmap = any(lessThan(shadowMapCoords.xyz, vec3(0.0f))) || any(greaterThan(shadowMapCoords.xyz, vec3(1.0f))); - - if (!outsideShadowmap) - { - // Get atlas offset and scale from light struct - vec2 atlasOffset = vec2(light.AtlasOffsetX, light.AtlasOffsetY); - float atlasScale = light.AtlasScale; - attenuation *= light.SoftShadows - ? PCSS_SpotLight(SpotAtlas, atlasOffset, atlasScale, shadowMapCoords, light.Falloff) - : HardShadows_SpotLight(SpotAtlas, atlasOffset, atlasScale, shadowMapCoords); - } - } - - vec3 Lradiance = light.Radiance * light.Multiplier * attenuation; - vec3 Lh = normalize(Li + m_Params.View); - - // Calculate angles between surface normal and various light vectors. - float cosLi = max(0.0, dot(m_Params.Normal, Li)); - float cosLh = max(0.0, dot(m_Params.Normal, Lh)); - - vec3 F = FresnelSchlickRoughness(F0, max(0.0, dot(Lh, m_Params.View)), m_Params.Roughness); - float D = NdfGGX(cosLh, m_Params.Roughness); - float G = GaSchlickGGX(cosLi, m_Params.NdotV, m_Params.Roughness); - - vec3 kd = (1.0 - F) * (1.0 - m_Params.Metalness); - vec3 diffuseBRDF = kd * m_Params.Albedo; - - // Cook-Torrance - vec3 specularBRDF = (F * D * G) / max(Epsilon, 4.0 * cosLi * m_Params.NdotV); - specularBRDF = clamp(specularBRDF, vec3(0.0f), vec3(10.0f)); - result += (diffuseBRDF + specularBRDF) * Lradiance * cosLi; - - } - return result; -} - -#endif // defined(__FRAGMENT_STAGE) || defined(__COMPUTE_STAGE) diff --git a/Sandbox/Resources/Shaders/Include/HLSL/Buffers.hlslh b/Sandbox/Resources/Shaders/Include/HLSL/Buffers.hlslh deleted file mode 100644 index b3662e02..00000000 --- a/Sandbox/Resources/Shaders/Include/HLSL/Buffers.hlslh +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -struct Camera -{ - float4x4 ViewProjectionMatrix; - float4x4 InverseViewProjectionMatrix; - float4x4 ProjectionMatrix; - float4x4 InverseProjectionMatrix; - float4x4 ViewMatrix; - float4x4 InverseViewMatrix; - float2 NDCToViewMul; - float2 NDCToViewAdd; - float2 DepthUnpackConsts; - float2 CameraTanHalfFOV; -}; -[[vk::binding(0,2)]] ConstantBuffer u_Camera; - -struct ScreenData -{ - float2 InvFullResolution; - float2 FullResolution; - float2 InvHalfResolution; - float2 HalfResolution; -}; -[[vk::binding(2,2)]] ConstantBuffer u_ScreenData; - \ No newline at end of file diff --git a/Sandbox/Resources/Shaders/Include/HLSL/Types.hlslh b/Sandbox/Resources/Shaders/Include/HLSL/Types.hlslh deleted file mode 100644 index 61c52685..00000000 --- a/Sandbox/Resources/Shaders/Include/HLSL/Types.hlslh +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#if (USE_HALF_FLOAT_PRECISION != 0) - #if 1 // old fp16 approach ( - -layout(location = 0) out vec4 o_Color; - -struct VertexOutput -{ - vec2 TexCoords; -}; -layout (location = 0) in VertexOutput Input; - -layout(set = 2, binding = 0) uniform texture2D u_Texture; - -void main() -{ - vec4 pixel = SampleLinear(u_Texture, Input.TexCoords); - - // Signed distance (squared) - float dist = sqrt(pixel.z); - float alpha = smoothstep(0.004f, 0.002f, dist); - if (alpha == 0.0) - discard; - - vec3 outlineColor = vec3(1.0f, 0.5f, 0.0f); - o_Color = vec4(outlineColor, alpha); -} \ No newline at end of file diff --git a/Sandbox/Resources/Shaders/JumpFlood_Init.glsl b/Sandbox/Resources/Shaders/JumpFlood_Init.glsl deleted file mode 100644 index cbaec304..00000000 --- a/Sandbox/Resources/Shaders/JumpFlood_Init.glsl +++ /dev/null @@ -1,55 +0,0 @@ -#version 450 core -#pragma stage : vert - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec2 a_TexCoords; - -struct VertexOutput -{ - vec2 TexCoords; -}; -layout (location = 0) out VertexOutput Output; - -void main() -{ - Output.TexCoords = a_TexCoords; - - gl_Position = vec4(a_Position, 1.0f); -} - -#version 450 core -#pragma stage : frag - -#include - -layout(location = 0) out vec4 outColor; - -struct VertexOutput -{ - vec2 TexCoords; -}; -layout (location = 0) in VertexOutput Input; - -layout(set = 2, binding = 0) uniform texture2D u_Texture; - -float ScreenDistance(vec2 v, vec2 texelSize) -{ - float ratio = texelSize.x / texelSize.y; - v.x /= ratio; - return dot(v, v); -} - -void main() -{ - vec4 color = SampleLinear(u_Texture, Input.TexCoords); - - ivec2 texSize = GetTextureSize(u_Texture, 0); - vec2 texelSize = vec2(1.0f / float(texSize.x), 1.0f / float(texSize.y)); - - vec4 result; - result.xy = vec2(100, 100); - result.z = ScreenDistance(result.xy, texelSize); - // Inside vs. outside - result.w = color.a > 0.5f ? 1.0f : 0.0f; - outColor = result; -} \ No newline at end of file diff --git a/Sandbox/Resources/Shaders/JumpFlood_Pass.glsl b/Sandbox/Resources/Shaders/JumpFlood_Pass.glsl deleted file mode 100644 index ca9f8f32..00000000 --- a/Sandbox/Resources/Shaders/JumpFlood_Pass.glsl +++ /dev/null @@ -1,97 +0,0 @@ -#version 450 core -#pragma stage : vert - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec2 a_TexCoords; - -struct VertexOutput -{ - vec2 TexCoords; - vec2 TexelSize; - vec2 UV[9]; -}; -layout (location = 0) out VertexOutput Output; - -layout(push_constant) uniform Uniforms -{ - vec2 TexelSize; - int Step; -} u_Renderer; - -void main() -{ - Output.TexCoords = a_TexCoords; - Output.TexelSize = u_Renderer.TexelSize; - - vec2 dx = vec2(u_Renderer.TexelSize.x, 0.0f) * u_Renderer.Step; - vec2 dy = vec2(0.0f, u_Renderer.TexelSize.y) * u_Renderer.Step; - - Output.UV[0] = Output.TexCoords; - - //Sample all pixels within a 3x3 block - Output.UV[1] = Output.TexCoords + dx; - Output.UV[2] = Output.TexCoords - dx; - Output.UV[3] = Output.TexCoords + dy; - Output.UV[4] = Output.TexCoords - dy; - Output.UV[5] = Output.TexCoords + dx + dy; - Output.UV[6] = Output.TexCoords + dx - dy; - Output.UV[7] = Output.TexCoords - dx + dy; - Output.UV[8] = Output.TexCoords - dx - dy; - - gl_Position = vec4(a_Position, 1.0f); -} - -#version 450 core -#pragma stage : frag - -#include - -layout(location = 0) out vec4 o_Color; - -struct VertexOutput -{ - vec2 TexCoords; - vec2 TexelSize; - vec2 UV[9]; -}; -layout (location = 0) in VertexOutput Input; - -layout(set = 2, binding = 0) uniform texture2D u_Texture; - -float ScreenDistance(vec2 v) -{ - float ratio = Input.TexelSize.x / Input.TexelSize.y; - v.x /= ratio; - return dot(v, v); -} - -void BoundsCheck(inout vec2 xy, vec2 uv) -{ - if (uv.x < 0.0f || uv.x > 1.0f || uv.y < 0.0f || uv.y > 1.0f) - xy = vec2(1000.0f); -} - -void main() -{ - vec4 pixel = SampleLinear(u_Texture, Input.UV[0]); - - for (int j = 1; j <= 8; j++) - { - // Sample neighbouring pixel and make sure it's - // on the same side as us - vec4 n = SampleLinear(u_Texture, Input.UV[j]); - if (n.w != pixel.w) - n.xyz = vec3(0.0f); - - n.xy += Input.UV[j] - Input.UV[0]; - - // Invalidate out of bounds neighbours - BoundsCheck(n.xy, Input.UV[j]); - - float dist = ScreenDistance(n.xy); - if (dist < pixel.z) - pixel.xyz = vec3(n.xy, dist); - } - - o_Color = pixel; -} \ No newline at end of file diff --git a/Sandbox/Resources/Shaders/LightCulling.glsl b/Sandbox/Resources/Shaders/LightCulling.glsl deleted file mode 100644 index 9b12a7a9..00000000 --- a/Sandbox/Resources/Shaders/LightCulling.glsl +++ /dev/null @@ -1,234 +0,0 @@ -// --------------------------------------- -// -- Hazel Engine light culling shader -- -// --------------------------------------- -// -// References: -// - SIGGRAPH 2011 - Rendering in Battlefield 3 -// - Implementation mostly adapted from https://github.com/bcrusco/Forward-Plus-Renderer -// -#version 450 core -#pragma stage : comp -#include -#include - -layout(set = 1, binding = 0) uniform texture2D u_DepthMap; - -#define TILE_SIZE 16 -#define MAX_LIGHT_COUNT 256 - -layout(std430, set = 1, binding = 9) writeonly buffer VisiblePointLightIndicesBuffer -{ - int Indices[]; -} s_VisiblePointLightIndicesBuffer; - -layout(std430, set = 1, binding = 10) writeonly buffer VisibleSpotLightIndicesBuffer -{ - int Indices[]; -} s_VisibleSpotLightIndicesBuffer; - -struct Sphere -{ - vec3 c; // Center point. - float r; // Radius. -}; - -bool TestFrustumSides(vec3 c, float r, vec3 plane0, vec3 plane1, vec3 plane2, vec3 plane3) -{ - bool intersectingOrInside0 = dot(c, plane0) < r; - bool intersectingOrInside1 = dot(c, plane1) < r; - bool intersectingOrInside2 = dot(c, plane2) < r; - bool intersectingOrInside3 = dot(c, plane3) < r; - - return (intersectingOrInside0 && intersectingOrInside1 && - intersectingOrInside2 && intersectingOrInside3); -} - -// From XeGTAO -float ScreenSpaceToViewSpaceDepth(const float screenDepth) -{ - float depthLinearizeMul = u_Camera.DepthUnpackConsts.x; - float depthLinearizeAdd = u_Camera.DepthUnpackConsts.y; - // Optimised version of "-cameraClipNear / (cameraClipFar - projDepth * (cameraClipFar - cameraClipNear)) * cameraClipFar" - return depthLinearizeMul / (depthLinearizeAdd - screenDepth); -} -// Shared values between all the threads in the group -shared uint minDepthInt; -shared uint maxDepthInt; -shared uint visiblePointLightCount; -shared uint visibleSpotLightCount; -shared vec4 frustumPlanes[6]; - -// Shared local storage for visible indices, will be written out to the global buffer at the end -shared int visiblePointLightIndices[MAX_LIGHT_COUNT]; -shared int visibleSpotLightIndices[MAX_LIGHT_COUNT]; - -layout(local_size_x = TILE_SIZE, local_size_y = TILE_SIZE, local_size_z = 1) in; -void main() -{ - ivec2 location = ivec2(gl_GlobalInvocationID.xy); - ivec2 screenSize = ivec2(u_ScreenData.FullResolution); - ivec2 clampedLocation = clamp(location, ivec2(0), max(screenSize - ivec2(1), ivec2(0))); - ivec2 itemID = ivec2(gl_LocalInvocationID.xy); - ivec2 tileID = ivec2(gl_WorkGroupID.xy); - ivec2 tileNumber = ivec2(gl_NumWorkGroups.xy); - uint index = tileID.y * tileNumber.x + tileID.x; - - // Initialize shared global values for depth and light count - if (gl_LocalInvocationIndex == 0) - { - minDepthInt = 0xFFFFFFFF; - maxDepthInt = 0; - visiblePointLightCount = 0; - visibleSpotLightCount = 0; - } - - barrier(); - - // Step 1: Calculate the minimum and maximum depth values (from the depth buffer) for this group's tile - vec2 tc = (vec2(clampedLocation) + vec2(0.5)) * u_ScreenData.InvFullResolution; - float linearDepth = ScreenSpaceToViewSpaceDepth(textureLod(sampler2D(u_DepthMap, r_DefaultSampler), tc, 0).r); - - // Convert depth to uint so we can do atomic min and max comparisons between the threads - uint depthInt = floatBitsToUint(linearDepth); - atomicMin(minDepthInt, depthInt); - atomicMax(maxDepthInt, depthInt); - - barrier(); - - // Step 2: One thread should calculate the frustum planes to be used for this tile - if (gl_LocalInvocationIndex == 0) - { - // Convert the min and max across the entire tile back to float - float minDepth = uintBitsToFloat(minDepthInt); - float maxDepth = uintBitsToFloat(maxDepthInt); - - // Steps based on tile sale - vec2 negativeStep = (2.0 * vec2(tileID)) / vec2(tileNumber); - vec2 positiveStep = (2.0 * vec2(tileID + ivec2(1, 1))) / vec2(tileNumber); - - // Set up starting values for planes using steps and min and max z values - frustumPlanes[0] = vec4(1.0, 0.0, 0.0, 1.0 - negativeStep.x); // Left - frustumPlanes[1] = vec4(-1.0, 0.0, 0.0, -1.0 + positiveStep.x); // Right - - frustumPlanes[2] = vec4(0.0, 1.0, 0.0, -1.0 + negativeStep.y); // Bottom - frustumPlanes[3] = vec4(0.0, -1.0, 0.0, 1.0 - positiveStep.y); // Top - - frustumPlanes[4] = vec4(0.0, 0.0, -1.0, -minDepth); // Near - frustumPlanes[5] = vec4(0.0, 0.0, 1.0, maxDepth); // Far - - // Transform the first four planes - for (uint i = 0; i < 4; i++) - { - frustumPlanes[i] *= u_Camera.ViewProjectionMatrix; - frustumPlanes[i] /= length(frustumPlanes[i].xyz); - } - - // Transform the depth planes - frustumPlanes[4] *= u_Camera.ViewMatrix; - frustumPlanes[4] /= length(frustumPlanes[4].xyz); - frustumPlanes[5] *= u_Camera.ViewMatrix; - frustumPlanes[5] /= length(frustumPlanes[5].xyz); - } - - barrier(); - - // Step 3: Cull lights. - // Parallelize the threads against the lights now. - // Can handle 256 simultaniously. Anymore lights than that and additional passes are performed - const uint threadCount = TILE_SIZE * TILE_SIZE; - uint pointLightCount = min(u_PointLights.LightCount, uint(MAX_LIGHT_COUNT)); - uint passCount = (pointLightCount + threadCount - 1) / threadCount; - for (uint i = 0; i < passCount; i++) - { - // Get the lightIndex to test for this thread / pass. If the index is >= light count, then this thread can stop testing lights - uint lightIndex = i * threadCount + gl_LocalInvocationIndex; - if (lightIndex >= pointLightCount) - break; - - vec4 position = vec4(u_PointLights.Lights[lightIndex].Position, 1.0f); - float radius = u_PointLights.Lights[lightIndex].Radius; - radius += radius * 0.3f; - - // Check if light radius is in frustum - float distance = 0.0; - for (uint j = 0; j < 6; j++) - { - distance = dot(position, frustumPlanes[j]) + radius; - if (distance <= 0.0) // No intersection - break; - } - - // If greater than zero, then it is a visible light - if (distance > 0.0) - { - // Add index to the shared array of visible indices - uint offset = atomicAdd(visiblePointLightCount, 1); - if (offset < uint(MAX_LIGHT_COUNT)) - visiblePointLightIndices[offset] = int(lightIndex); - } - } - - uint spotLightCount = min(u_SpotLights.LightCount, uint(MAX_LIGHT_COUNT)); - passCount = (spotLightCount + threadCount - 1) / threadCount; - for (uint i = 0; i < passCount; i++) - { - // Get the lightIndex to test for this thread / pass. If the index is >= light count, then this thread can stop testing lights - uint lightIndex = i * threadCount + gl_LocalInvocationIndex; - if (lightIndex >= spotLightCount) - break; - - SpotLight light = u_SpotLights.Lights[lightIndex]; - float radius = light.Range; - // Check if light radius is in frustum - float distance = 0.0; - for (uint j = 0; j < 6; j++) - { - distance = dot(vec4(light.Position - light.Direction * (light.Range * 0.7), 1.0), frustumPlanes[j]) + radius * 1.3; - if (distance < 0.0) // No intersection - break; - } - - // If greater than zero, then it is a visible light - if (distance > 0.0) - { - // Add index to the shared array of visible indices - uint offset = atomicAdd(visibleSpotLightCount, 1); - if (offset < uint(MAX_LIGHT_COUNT)) - visibleSpotLightIndices[offset] = int(lightIndex); - } - - } - - barrier(); - - // One thread should fill the global light buffer - if (gl_LocalInvocationIndex == 0) - { - const uint offset = index * MAX_LIGHT_COUNT; // Determine position in global buffer - for (uint i = 0; i < min(visiblePointLightCount, uint(MAX_LIGHT_COUNT)); i++) - { - s_VisiblePointLightIndicesBuffer.Indices[offset + i] = visiblePointLightIndices[i]; - } - - for (uint i = 0; i < min(visibleSpotLightCount, uint(MAX_LIGHT_COUNT)); i++) { - s_VisibleSpotLightIndicesBuffer.Indices[offset + i] = visibleSpotLightIndices[i]; - } - - uint pointWriteCount = min(visiblePointLightCount, uint(MAX_LIGHT_COUNT)); - uint spotWriteCount = min(visibleSpotLightCount, uint(MAX_LIGHT_COUNT)); - - if (pointWriteCount != uint(MAX_LIGHT_COUNT)) - { - // Unless we have totally filled the entire array, mark it's end with -1 - // Final shader step will use this to determine where to stop (without having to pass the light count) - s_VisiblePointLightIndicesBuffer.Indices[offset + pointWriteCount] = -1; - } - - if (spotWriteCount != uint(MAX_LIGHT_COUNT)) - { - // Unless we have totally filled the entire array, mark it's end with -1 - // Final shader step will use this to determine where to stop (without having to pass the light count) - s_VisibleSpotLightIndicesBuffer.Indices[offset + spotWriteCount] = -1; - } - } -} diff --git a/Sandbox/Resources/Shaders/LinearSample.glsl b/Sandbox/Resources/Shaders/LinearSample.glsl deleted file mode 100644 index 8a535266..00000000 --- a/Sandbox/Resources/Shaders/LinearSample.glsl +++ /dev/null @@ -1,29 +0,0 @@ -#version 450 core -#pragma stage : comp - -#include - -layout(binding = 0) uniform texture2D u_InputTexture; - -layout(binding = 1) uniform writeonly image2D o_OutputTexture; - -layout(push_constant) uniform PushConstants -{ - vec2 TexelSize; - int SourceMipLevel; -} u_PushConstants; - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -void main() -{ - ivec2 outputCoord = ivec2(gl_GlobalInvocationID.xy); - - ivec2 outputSize = imageSize(o_OutputTexture); - if (outputCoord.x >= outputSize.x || outputCoord.y >= outputSize.y) - return; - - vec2 uv = (vec2(outputCoord) + 0.5) * u_PushConstants.TexelSize; - - vec4 color = SampleLinearLOD(u_InputTexture, uv, float(u_PushConstants.SourceMipLevel)); - imageStore(o_OutputTexture, outputCoord, color); -} diff --git a/Sandbox/Resources/Shaders/LinearSampleUInt.glsl b/Sandbox/Resources/Shaders/LinearSampleUInt.glsl deleted file mode 100644 index 27546376..00000000 --- a/Sandbox/Resources/Shaders/LinearSampleUInt.glsl +++ /dev/null @@ -1,29 +0,0 @@ -#version 450 core -#pragma stage : comp - -#include - -layout(binding = 0) uniform utexture2D u_InputTexture; - -layout(binding = 1) uniform writeonly uimage2D o_OutputTexture; - -layout(push_constant) uniform PushConstants -{ - vec2 TexelSize; - int SourceMipLevel; -} u_PushConstants; - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -void main() -{ - ivec2 outputCoord = ivec2(gl_GlobalInvocationID.xy); - - ivec2 outputSize = imageSize(o_OutputTexture); - if (outputCoord.x >= outputSize.x || outputCoord.y >= outputSize.y) - return; - - vec2 uv = (vec2(outputCoord) + 0.5) * u_PushConstants.TexelSize; - - uvec4 color = SampleLinearLOD(u_InputTexture, uv, float(u_PushConstants.SourceMipLevel)); - imageStore(o_OutputTexture, outputCoord, color); -} diff --git a/Sandbox/Resources/Shaders/PostProcessing/AO-Composite.glsl b/Sandbox/Resources/Shaders/PostProcessing/AO-Composite.glsl deleted file mode 100644 index 43b363a6..00000000 --- a/Sandbox/Resources/Shaders/PostProcessing/AO-Composite.glsl +++ /dev/null @@ -1,51 +0,0 @@ -#version 430 core -#pragma stage : vert - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec2 a_TexCoord; - -layout(location = 0) out vec2 o_TexCoord; -void main() -{ - o_TexCoord = a_TexCoord; - gl_Position = vec4(a_Position.xy, 0.0, 1.0); -} - -#version 450 core -#pragma stage : frag - -#include -#include - -#define ENABLED_GTAO (__HZ_AO_METHOD & HZ_AO_METHOD_GTAO) -#define ENABLED_HBAO (__HZ_AO_METHOD & HZ_AO_METHOD_HBAO) - -#if ENABLED_GTAO -layout(set = 1, binding = 0) uniform utexture2D u_GTAOTex; -#endif - -#if ENABLED_HBAO -layout(binding = 1) uniform texture2D u_HBAOTex; -#endif - -layout(location = 0) out vec4 o_Occlusion; -layout(location = 0) in vec2 vs_TexCoord; - -void main() -{ - float occlusion = 1.0f; -#if ENABLED_GTAO - #if __HZ_GTAO_COMPUTE_BENT_NORMALS - float ao = (texture(usampler2D(u_GTAOTex, r_LinearSampler), vs_TexCoord).x >> 24) / 255.f; - #else - float ao = texture(usampler2D(u_GTAOTex, r_LinearSampler), vs_TexCoord).x / 255.f; - #endif - occlusion = min(ao * XE_GTAO_OCCLUSION_TERM_SCALE, 1.0f); -#endif -#if ENABLED_HBAO - occlusion *= SampleLinear(u_HBAOTex, vs_TexCoord).x; -#endif - - o_Occlusion = occlusion.xxxx; -} - diff --git a/Sandbox/Resources/Shaders/PostProcessing/Bloom.glsl b/Sandbox/Resources/Shaders/PostProcessing/Bloom.glsl deleted file mode 100644 index 8e7d9c28..00000000 --- a/Sandbox/Resources/Shaders/PostProcessing/Bloom.glsl +++ /dev/null @@ -1,152 +0,0 @@ -#version 450 core -#pragma stage : comp - -#include - -layout(binding = 0, rgba32f) restrict writeonly uniform image2D o_Image; - -const float Epsilon = 1.0e-4; - -layout(binding = 1) uniform texture2D u_Texture; -layout(binding = 2) uniform texture2D u_BloomTexture; - -layout(push_constant) uniform Uniforms -{ - vec4 Params; // (x) threshold, (y) threshold - knee, (z) knee * 2, (w) 0.25 / knee - vec4 TexSize; - float LOD; - int Mode; // See defines below -} u_Uniforms; - -#define MODE_PREFILTER 0 -#define MODE_DOWNSAMPLE 1 -#define MODE_UPSAMPLE_FIRST 2 -#define MODE_UPSAMPLE 3 - -vec3 DownsampleBox13(texture2D tex, float lod, vec2 uv, vec2 texelSize) -{ - // Center - vec3 A = SampleLinearLOD(tex, uv, lod).rgb; - - texelSize *= 0.5f; // Sample from center of texels - - // Inner box - vec3 B = SampleLinearLOD(tex, uv + texelSize * vec2(-1.0f, -1.0f), lod).rgb; - vec3 C = SampleLinearLOD(tex, uv + texelSize * vec2(-1.0f, 1.0f), lod).rgb; - vec3 D = SampleLinearLOD(tex, uv + texelSize * vec2(1.0f, 1.0f), lod).rgb; - vec3 E = SampleLinearLOD(tex, uv + texelSize * vec2(1.0f, -1.0f), lod).rgb; - - // Outer box - vec3 F = SampleLinearLOD(tex, uv + texelSize * vec2(-2.0f, -2.0f), lod).rgb; - vec3 G = SampleLinearLOD(tex, uv + texelSize * vec2(-2.0f, 0.0f), lod).rgb; - vec3 H = SampleLinearLOD(tex, uv + texelSize * vec2(0.0f, 2.0f), lod).rgb; - vec3 I = SampleLinearLOD(tex, uv + texelSize * vec2(2.0f, 2.0f), lod).rgb; - vec3 J = SampleLinearLOD(tex, uv + texelSize * vec2(2.0f, 2.0f), lod).rgb; - vec3 K = SampleLinearLOD(tex, uv + texelSize * vec2(2.0f, 0.0f), lod).rgb; - vec3 L = SampleLinearLOD(tex, uv + texelSize * vec2(-2.0f, -2.0f), lod).rgb; - vec3 M = SampleLinearLOD(tex, uv + texelSize * vec2(0.0f, -2.0f), lod).rgb; - - // Weights - vec3 result = vec3(0.0); - // Inner box - result += (B + C + D + E) * 0.5f; - // Bottom-left box - result += (F + G + A + M) * 0.125f; - // Top-left box - result += (G + H + I + A) * 0.125f; - // Top-right box - result += (A + I + J + K) * 0.125f; - // Bottom-right box - result += (M + A + K + L) * 0.125f; - - // 4 samples each - result *= 0.25f; - - return result; -} - -// Quadratic color thresholding -// curve = (threshold - knee, knee * 2, 0.25 / knee) -vec4 QuadraticThreshold(vec4 color, float threshold, vec3 curve) -{ - // Maximum pixel brightness - float brightness = max(max(color.r, color.g), color.b); - // Quadratic curve - float rq = clamp(brightness - curve.x, 0.0, curve.y); - rq = (rq * rq) * curve.z; - color *= max(rq, brightness - threshold) / max(brightness, Epsilon); - return color; -} - -vec4 Prefilter(vec4 color, vec2 uv) -{ - float clampValue = 20.0f; - color = clamp(color, vec4(0.0f), vec4(clampValue)); - color = QuadraticThreshold(color, u_Uniforms.Params.x, u_Uniforms.Params.yzw); - return color; -} - -vec3 UpsampleTent9(texture2D tex, float lod, vec2 uv, vec2 texelSize, float radius) -{ - vec4 offset = texelSize.xyxy * vec4(1.0f, 1.0f, -1.0f, 0.0f) * radius; - - // Center - vec3 result = SampleLinearLOD(tex, uv, lod).rgb * 4.0f; - - result += SampleLinearLOD(tex, uv - offset.xy, lod).rgb; - result += SampleLinearLOD(tex, uv - offset.wy, lod).rgb * 2.0; - result += SampleLinearLOD(tex, uv - offset.zy, lod).rgb; - - result += SampleLinearLOD(tex, uv + offset.zw, lod).rgb * 2.0; - result += SampleLinearLOD(tex, uv + offset.xw, lod).rgb * 2.0; - - result += SampleLinearLOD(tex, uv + offset.zy, lod).rgb; - result += SampleLinearLOD(tex, uv + offset.wy, lod).rgb * 2.0; - result += SampleLinearLOD(tex, uv + offset.xy, lod).rgb; - - return result * (1.0f / 16.0f); -} - -layout(local_size_x = 4, local_size_y = 4) in; -void main() -{ - vec2 imgSize = vec2(imageSize(o_Image)); - - ivec2 invocID = ivec2(gl_GlobalInvocationID); - vec2 texCoords = vec2(float(invocID.x) / imgSize.x, float(invocID.y) / imgSize.y); - texCoords += (1.0f / imgSize) * 0.5f; - - vec2 texSize = vec2(GetTextureSize(u_Texture, int(u_Uniforms.LOD))); - vec4 color = vec4(1, 0, 1, 1); - if (u_Uniforms.Mode == MODE_PREFILTER) - { - color.rgb = DownsampleBox13(u_Texture, 0, texCoords, 1.0f / texSize); - color = Prefilter(color, texCoords); - color.a = 1.0f; - } - else if (u_Uniforms.Mode == MODE_UPSAMPLE_FIRST) - { - vec2 bloomTexSize = u_Uniforms.TexSize.xy; - float sampleScale = 1.0f; - vec3 upsampledTexture = UpsampleTent9(u_Texture, u_Uniforms.LOD + 1.0f, texCoords, 1.0f / bloomTexSize, sampleScale); - - vec3 existing = SampleLinearLOD(u_Texture, texCoords, u_Uniforms.LOD).rgb; - color.rgb = existing + upsampledTexture; - } - else if (u_Uniforms.Mode == MODE_UPSAMPLE) - { - vec2 bloomTexSize = u_Uniforms.TexSize.xy; - float sampleScale = 1.0f; - vec3 upsampledTexture = UpsampleTent9(u_BloomTexture, u_Uniforms.LOD + 1.0f, texCoords, 1.0f / bloomTexSize, sampleScale); - - vec3 existing = SampleLinearLOD(u_Texture, texCoords, u_Uniforms.LOD).rgb; - color.rgb = existing + upsampledTexture; - } - else if (u_Uniforms.Mode == MODE_DOWNSAMPLE) - { - // Downsample - color.rgb = DownsampleBox13(u_Texture, u_Uniforms.LOD, texCoords, 1.0f / texSize); - } - - imageStore(o_Image, ivec2(gl_GlobalInvocationID), color); -} diff --git a/Sandbox/Resources/Shaders/PostProcessing/DOF.glsl b/Sandbox/Resources/Shaders/PostProcessing/DOF.glsl deleted file mode 100644 index 1a00dc7d..00000000 --- a/Sandbox/Resources/Shaders/PostProcessing/DOF.glsl +++ /dev/null @@ -1,97 +0,0 @@ -#version 450 core -#pragma stage : vert - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec2 a_TexCoord; - -struct OutputBlock -{ - vec2 TexCoord; -}; - -layout (location = 0) out OutputBlock Output; - -void main() -{ - vec4 position = vec4(a_Position.xy, 0.0, 1.0); - Output.TexCoord = a_TexCoord; - gl_Position = position; -} - -#version 450 core -#pragma stage : frag - -#include -#include - -layout(location = 0) out vec4 o_Color; - -struct OutputBlock -{ - vec2 TexCoord; -}; - -layout (location = 0) in OutputBlock Input; - -layout (set = 1, binding = 5) uniform texture2D u_Texture; -layout (set = 1, binding = 6) uniform texture2D u_DepthTexture; - -layout(push_constant) uniform Uniforms -{ - vec2 DOFParams; // x = FocusDistance, y = BlurSize -} u_Uniforms; - -// WIP depth of field from https://blog.tuxedolabs.com/2018/05/04/bokeh-depth-of-field-in-single-pass.html -// NOTE(Yan): this is a pretty slow approach (especially on a full-size framebuffer) but it looks nice, -// so worth experimenting with (also like most things, would be better in compute) -const float GOLDEN_ANGLE = 2.39996323; -const float MAX_BLUR_SIZE = 20.0; -const float RAD_SCALE = 1.0; // Smaller = nicer blur, larger = faster - -float LinearizeDepth(const float screenDepth) -{ - float depthLinearizeMul = u_Camera.DepthUnpackConsts.x; - float depthLinearizeAdd = u_Camera.DepthUnpackConsts.y; - return depthLinearizeMul / (depthLinearizeAdd - screenDepth); -} - -float GetBlurSize(float depth, float focusPoint, float focusScale) -{ - float coc = clamp((1.0 / focusPoint - 1.0 / depth) * focusScale, -1.0, 1.0); - return abs(coc) * MAX_BLUR_SIZE; -} - -vec3 DepthOfField(vec2 texCoord, float focusPoint, float focusScale, vec2 texelSize) -{ - float centerDepth = LinearizeDepth(SampleLinear(u_DepthTexture, texCoord).r); - float centerSize = GetBlurSize(centerDepth, focusPoint, focusScale); - vec3 color = SampleLinear(u_Texture, texCoord).rgb; - float tot = 1.0; - float radius = RAD_SCALE; - for (float ang = 0.0; radius < MAX_BLUR_SIZE; ang += GOLDEN_ANGLE) - { - vec2 tc = texCoord + vec2(cos(ang), sin(ang)) * texelSize * radius; - vec3 sampleColor = SampleLinear(u_Texture, tc).rgb; - float sampleDepth = LinearizeDepth(SampleLinear(u_DepthTexture, tc).r); - float sampleSize = GetBlurSize(sampleDepth, focusPoint, focusScale); - if (sampleDepth > centerDepth) - sampleSize = clamp(sampleSize, 0.0, centerSize * 2.0); - float m = smoothstep(radius - 0.5, radius + 0.5, sampleSize); - color += mix(color / tot, sampleColor, m); - tot += 1.0; - radius += RAD_SCALE / radius; - } - return color /= tot; -} - -void main() -{ - ivec2 texSize = GetTextureSize(u_Texture, 0); - vec2 fTexSize = vec2(float(texSize.x), float(texSize.y)); - - float focusPoint = u_Uniforms.DOFParams.x; - float blurScale = u_Uniforms.DOFParams.y; - - vec3 color = DepthOfField(Input.TexCoord, focusPoint, blurScale, 1.0 / fTexSize); - o_Color = vec4(color, 1.0); -} \ No newline at end of file diff --git a/Sandbox/Resources/Shaders/PostProcessing/EdgeDetection.glsl b/Sandbox/Resources/Shaders/PostProcessing/EdgeDetection.glsl deleted file mode 100644 index 632e5660..00000000 --- a/Sandbox/Resources/Shaders/PostProcessing/EdgeDetection.glsl +++ /dev/null @@ -1,83 +0,0 @@ -#version 450 core -#pragma stage : vert - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec2 a_TexCoord; - -struct OutputBlock -{ - vec2 TexCoord; -}; - -layout (location = 0) out OutputBlock Output; - -void main() -{ - vec4 position = vec4(a_Position.xy, 0.0, 1.0); - Output.TexCoord = a_TexCoord; - gl_Position = position; -} - -#version 450 core -#pragma stage : frag - -#include - -layout(location = 0) out vec4 o_Color; - -struct OutputBlock -{ - vec2 TexCoord; -}; - -layout (location = 0) in OutputBlock Input; - -layout (set = 1, binding = 0) uniform sampler2D u_ViewNormalsTexture; -layout (set = 1, binding = 1) uniform sampler2D u_DepthTexture; - -float LinearizeDepth(const float screenDepth) -{ - float depthLinearizeMul = u_Camera.DepthUnpackConsts.x; - float depthLinearizeAdd = u_Camera.DepthUnpackConsts.y; - return depthLinearizeMul / (depthLinearizeAdd - screenDepth); -} - -float checkSame(vec4 center, float centerDepth, vec4 samplef, float sampleDepth, vec2 sensitivity) -{ - vec2 centerNormal = center.xy; - vec2 sampleNormal = samplef.xy; - - vec2 diffNormal = abs(centerNormal - sampleNormal) * sensitivity.x; - bool isSameNormal = (diffNormal.x + diffNormal.y) < 0.1; - float diffDepth = abs(centerDepth - sampleDepth) * sensitivity.y; - bool isSameDepth = diffDepth < 0.1; - - return (isSameNormal && isSameDepth) ? 1.0 : 0.0; - return (isSameNormal) ? 1.0 : 0.0; -} - -void main() -{ - ivec2 texSize = textureSize(u_ViewNormalsTexture, 0); - vec2 fTexSize = vec2(float(texSize.x), float(texSize.y)); - - vec2 sensitivity = (vec2(0.3, 1.5) * fTexSize.y / 800.0); - vec2 singleTexel = vec2(1.0) / fTexSize; - - vec4 sample1 = texture(u_ViewNormalsTexture, Input.TexCoord + singleTexel); - vec4 sample2 = texture(u_ViewNormalsTexture, Input.TexCoord + -singleTexel); - vec4 sample3 = texture(u_ViewNormalsTexture, Input.TexCoord + vec2(-singleTexel.x, singleTexel.y)); - vec4 sample4 = texture(u_ViewNormalsTexture, Input.TexCoord + vec2(singleTexel.x, -singleTexel.y)); - - float sampleDepth1 = LinearizeDepth(texture(u_DepthTexture, Input.TexCoord + singleTexel).r) / 10.0; - float sampleDepth2 = LinearizeDepth(texture(u_DepthTexture, Input.TexCoord + -singleTexel).r)/ 10.0; - float sampleDepth3 = LinearizeDepth(texture(u_DepthTexture, Input.TexCoord + vec2(-singleTexel.x, singleTexel.y)).r)/ 10.0; - float sampleDepth4 = LinearizeDepth(texture(u_DepthTexture, Input.TexCoord + vec2(singleTexel.x, -singleTexel.y)).r)/ 10.0; - - float edge = checkSame(sample1, sampleDepth1, sample2, sampleDepth2, sensitivity) * checkSame(sample3, sampleDepth3, sample4, sampleDepth4, sensitivity); - - //float rawDepth = texture(u_DepthTexture, Input.TexCoord).r; - //float depth = LinearizeDepth(rawDepth); - - o_Color = vec4(vec3(edge), 1.0); -} \ No newline at end of file diff --git a/Sandbox/Resources/Shaders/PostProcessing/GTAO-Denoise.glsl b/Sandbox/Resources/Shaders/PostProcessing/GTAO-Denoise.glsl deleted file mode 100644 index ce3d73fa..00000000 --- a/Sandbox/Resources/Shaders/PostProcessing/GTAO-Denoise.glsl +++ /dev/null @@ -1,190 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016-2021, Intel Corporation -// -// SPDX-License-Identifier: MIT -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#version 450 core -#pragma stage : comp -#include -#include -#include - -layout(set = 1, binding = 0, r8ui) uniform writeonly uimage2D o_AOTerm; -layout(set = 1, binding = 1) uniform texture2D u_Edges; -layout(set = 1, binding = 2) uniform utexture2D u_AOTerm; - -layout(push_constant) uniform DenoiseConstants -{ - float DenoiseBlurBeta; - bool HalfRes; -} u_Settings; - -#if __HZ_GTAO_COMPUTE_BENT_NORMALS -#define AOTermType vec4 // .xyz is bent normal, .w is visibility term -#else -#define AOTermType float // .x is visibility term -#endif - - -vec4 XeGTAO_R8G8B8A8_UNORM_to_FLOAT4(uint packedInput) -{ - vec4 unpackedOutput; - unpackedOutput.x = float(packedInput & 0x000000ff) / 255.f; - unpackedOutput.y = float(((packedInput >> 8) & 0x000000ff)) / 255.f; - unpackedOutput.z = float(((packedInput >> 16) & 0x000000ff)) / 255.f; - unpackedOutput.w = float(packedInput >> 24) / 255.f; - return unpackedOutput; -} - -void XeGTAO_DecodeVisibilityBentNormal(const uint packedValue, out float visibility, out vec3 bentNormal) -{ - vec4 decoded = XeGTAO_R8G8B8A8_UNORM_to_FLOAT4(packedValue); - bentNormal = decoded.xyz * 2.0.xxx - 1.0.xxx; // could normalize - don't want to since it's done so many times, better to do it at the final step only - visibility = decoded.w; -} - - -void XeGTAO_DecodeGatherPartial(const uvec4 packedValue, out AOTermType outDecoded[4]) -{ - for( int i = 0; i < 4; i++ ) - { - #if __HZ_GTAO_COMPUTE_BENT_NORMALS - XeGTAO_DecodeVisibilityBentNormal(packedValue[i], outDecoded[i].w, outDecoded[i].xyz); - #else - outDecoded[i] = float(packedValue[i]) / 255.0; - #endif - } -} - -vec4 XeGTAO_UnpackEdges(float _packedVal) -{ - uint packedVal = uint(_packedVal * 255.5); - vec4 edgesLRTB; - edgesLRTB.x = float((packedVal >> 6) & 0x03) / 3.0; // there's really no need for mask (as it's an 8 bit input) but I'll leave it in so it doesn't cause any trouble in the future - edgesLRTB.y = float((packedVal >> 4) & 0x03) / 3.0; - edgesLRTB.z = float((packedVal >> 2) & 0x03) / 3.0; - edgesLRTB.w = float((packedVal >> 0) & 0x03) / 3.0; - - return clamp(edgesLRTB, 0.0, 1.0); -} - -void XeGTAO_AddSample(AOTermType ssaoValue, float edgeValue, inout AOTermType sum, inout float sumWeight) -{ - float weight = edgeValue; - - sum += (weight * ssaoValue); - sumWeight += weight; -} - -uint XeGTAO_FLOAT4_to_R8G8B8A8_UNORM(vec4 unpackedInput) -{ - return ((uint(clamp(unpackedInput.x, 0.0, 1.0) * 255.f + 0.5f)) | - (uint(clamp(unpackedInput.y, 0.0, 1.0) * 255.f + 0.5f) << 8 ) | - (uint(clamp(unpackedInput.z, 0.0, 1.0) * 255.f + 0.5f) << 16 ) | - (uint(clamp(unpackedInput.w, 0.0, 1.0) * 255.f + 0.5f) << 24 ) ); -} - - -uint XeGTAO_EncodeVisibilityBentNormal(float visibility, vec3 bentNormal) -{ - return XeGTAO_FLOAT4_to_R8G8B8A8_UNORM(vec4(bentNormal * 0.5 + 0.5, visibility)); -} - -void XeGTAO_Output(ivec2 pixCoord, AOTermType outputValue) -{ -#if __HZ_GTAO_COMPUTE_BENT_NORMALS - float visibility = outputValue.w; - vec3 bentNormal = normalize(outputValue.xyz); - imageStore(o_AOTerm, pixCoord, uint(XeGTAO_EncodeVisibilityBentNormal(visibility, bentNormal)).xxxx); -#else - imageStore(o_AOTerm, pixCoord, uint(min(outputValue * 255.0 + 0.5, 255.f)).xxxx); -#endif -} - -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -void main() -{ - - const float blurAmount = (u_Settings.DenoiseBlurBeta / 5.0); - const float diagWeight = 0.85 * 0.5; - - AOTermType aoTerm[2]; // pixel pixCoordBase and pixel pixCoordBase + ivec2( 1, 0 ) - vec4 edgesC_LRTB[2]; - float weightTL[2]; - float weightTR[2]; - float weightBL[2]; - float weightBR[2]; - - // we're computing 2 horizontal pixels at a time (performance optimization) - ivec2 pixCoordBase = ivec2(gl_GlobalInvocationID.xy * ivec2(2, 1)); - - // gather edge and visibility quads, used later - vec2 gatherCenter = vec2(pixCoordBase) * u_ScreenData.InvFullResolution * (1 + int(u_Settings.HalfRes)); - - vec4 edgesQ0 = textureGather(sampler2D(u_Edges, r_LinearSampler), gatherCenter); - vec4 edgesQ1 = textureGatherOffset(sampler2D(u_Edges, r_LinearSampler), gatherCenter, ivec2(2, 0)); - vec4 edgesQ2 = textureGatherOffset(sampler2D(u_Edges, r_LinearSampler), gatherCenter, ivec2(1, 2)); - - AOTermType visQ0[4]; XeGTAO_DecodeGatherPartial(textureGatherOffset(usampler2D(u_AOTerm, r_LinearSampler), gatherCenter, ivec2(0, 0)), visQ0); - AOTermType visQ1[4]; XeGTAO_DecodeGatherPartial(textureGatherOffset(usampler2D(u_AOTerm, r_LinearSampler), gatherCenter, ivec2(2, 0)), visQ1); - AOTermType visQ2[4]; XeGTAO_DecodeGatherPartial(textureGatherOffset(usampler2D(u_AOTerm, r_LinearSampler), gatherCenter, ivec2(0, 2)), visQ2); - AOTermType visQ3[4]; XeGTAO_DecodeGatherPartial(textureGatherOffset(usampler2D(u_AOTerm, r_LinearSampler), gatherCenter, ivec2(2, 2)), visQ3); - - for(int side = 0; side < 2; side++) - { - const ivec2 pixCoord = ivec2(pixCoordBase.x + side, pixCoordBase.y); - - vec4 edgesL_LRTB = XeGTAO_UnpackEdges((side == 0) ? (edgesQ0.x) : (edgesQ0.y)); - vec4 edgesT_LRTB = XeGTAO_UnpackEdges((side == 0) ? (edgesQ0.z) : (edgesQ1.w)); - vec4 edgesR_LRTB = XeGTAO_UnpackEdges((side == 0) ? (edgesQ1.x) : (edgesQ1.y)); - vec4 edgesB_LRTB = XeGTAO_UnpackEdges((side == 0) ? (edgesQ2.w) : (edgesQ2.z)); - - edgesC_LRTB[side] = XeGTAO_UnpackEdges((side == 0) ? edgesQ0.y : edgesQ1.x); - - // Edges aren't perfectly symmetrical: edge detection algorithm does not guarantee that a left edge on the right pixel will match the right edge on the left pixel (although - // they will match in majority of cases). This line further enforces the symmetricity, creating a slightly sharper blur. Works real nice with TAA. - edgesC_LRTB[side] *= vec4(edgesL_LRTB.y, edgesR_LRTB.x, edgesT_LRTB.w, edgesB_LRTB.z); - -#if 1 // this allows some small amount of AO leaking from neighbours if there are 3 or 4 edges; this reduces both spatial and temporal aliasing - const float leak_threshold = 2.5; const float leak_strength = 0.5; - float edginess = (clamp(4.0 - leak_threshold - dot(edgesC_LRTB[side], vec4(1.0)), 0.0, 1.0) / (4 - leak_threshold)) * leak_strength; - edgesC_LRTB[side] = clamp(edgesC_LRTB[side] + edginess, 0.0, 1.0); -#endif - - // for diagonals; used by first and second pass - weightTL[side] = diagWeight * (edgesC_LRTB[side].x * edgesL_LRTB.z + edgesC_LRTB[side].z * edgesT_LRTB.x); - weightTR[side] = diagWeight * (edgesC_LRTB[side].z * edgesT_LRTB.y + edgesC_LRTB[side].y * edgesR_LRTB.z); - weightBL[side] = diagWeight * (edgesC_LRTB[side].w * edgesB_LRTB.x + edgesC_LRTB[side].x * edgesL_LRTB.w); - weightBR[side] = diagWeight * (edgesC_LRTB[side].y * edgesR_LRTB.w + edgesC_LRTB[side].w * edgesB_LRTB.y); - - // first pass - AOTermType ssaoValue = side == 0 ? visQ0[1] : visQ1[0]; - AOTermType ssaoValueL = side == 0 ? visQ0[0] : visQ0[1]; - AOTermType ssaoValueT = side == 0 ? visQ0[2] : visQ1[3]; - AOTermType ssaoValueR = side == 0 ? visQ1[0] : visQ1[1]; - AOTermType ssaoValueB = side == 0 ? visQ2[2] : visQ3[3]; - AOTermType ssaoValueTL = side == 0 ? visQ0[3] : visQ0[2]; - AOTermType ssaoValueBR = side == 0 ? visQ3[3] : visQ3[2]; - AOTermType ssaoValueTR = side == 0 ? visQ1[3] : visQ1[2]; - AOTermType ssaoValueBL = side == 0 ? visQ2[3] : visQ2[2]; - - float sumWeight = blurAmount; - AOTermType sum = ssaoValue * sumWeight; - - XeGTAO_AddSample(ssaoValueL, edgesC_LRTB[side].x, sum, sumWeight); - XeGTAO_AddSample(ssaoValueR, edgesC_LRTB[side].y, sum, sumWeight); - XeGTAO_AddSample(ssaoValueT, edgesC_LRTB[side].z, sum, sumWeight); - XeGTAO_AddSample(ssaoValueB, edgesC_LRTB[side].w, sum, sumWeight); - - XeGTAO_AddSample(ssaoValueTL, weightTL[side], sum, sumWeight); - XeGTAO_AddSample(ssaoValueTR, weightTR[side], sum, sumWeight); - XeGTAO_AddSample(ssaoValueBL, weightBL[side], sum, sumWeight); - XeGTAO_AddSample(ssaoValueBR, weightBR[side], sum, sumWeight); - - aoTerm[side] = sum / sumWeight; - - XeGTAO_Output(pixCoord, aoTerm[side]); - } -} - - diff --git a/Sandbox/Resources/Shaders/PostProcessing/GTAO.hlsl b/Sandbox/Resources/Shaders/PostProcessing/GTAO.hlsl deleted file mode 100644 index fad75971..00000000 --- a/Sandbox/Resources/Shaders/PostProcessing/GTAO.hlsl +++ /dev/null @@ -1,474 +0,0 @@ -#pragma stage : comp -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2016-2021, Intel Corporation -// -// SPDX-License-Identifier: MIT -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// XeGTAO is based on GTAO/GTSO "Jimenez et al. / Practical Real-Time Strategies for Accurate Indirect Occlusion", -// https://www.activision.com/cdn/research/Practical_Real_Time_Strategies_for_Accurate_Indirect_Occlusion_NEW%20VERSION_COLOR.pdf -// -// Implementation: Filip Strugar (filip.strugar@intel.com), Steve Mccalla (\_/) -// Details: https://github.com/GameTechDev/XeGTAO (")_(") -// -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#ifndef XE_GTAO_USE_HALF_FLOAT_PRECISION -#define XE_GTAO_USE_HALF_FLOAT_PRECISION 1 -#endif -#include -#include -#include - -// input output textures for the second pass -[[vk::binding(1, 1)]] Texture2D u_ViewNormal; // source normal map -[[vk::binding(2, 1)]] Texture2D u_HilbertLut; // hilbert lookup table -[[vk::binding(3, 1)]] Texture2D u_HiZDepth; -[[vk::binding(6, 1)]] SamplerState u_samplerPointClamp; -[[vk::binding(4, 1)]] [[vk::image_format("r8ui")]] RWTexture2D o_AOwBentNormals; // output AO term (includes bent normals if enabled - packed as R11G11B10 scaled by AO) -[[vk::binding(5, 1)]] [[vk::image_format("r8")]] RWTexture2D o_Edges; // output depth-based edges used by the denoiser - -#define XE_GTAO_DEPTH_MIP_LEVELS 5 // this one is hard-coded to 5 for now -#define XE_GTAO_NUMTHREADS_X 16 // these can be changed -#define XE_GTAO_NUMTHREADS_Y 16 // these can be changed - -struct GTAOConstants -{ - float2 NDCToViewMul_x_PixelSize; - float EffectRadius; // world (viewspace) maximum size of the shadow - float EffectFalloffRange; - - float RadiusMultiplier; - float FinalValuePower; - float DenoiseBlurBeta; - bool HalfRes; - - float SampleDistributionPower; - float ThinOccluderCompensation; - float DepthMIPSamplingOffset; - int NoiseIndex; // frameIndex % 64 if using TAA or 0 otherwise - - float2 HZBUVFactor; - float ShadowTolerance; - float Padding; -}; -[[vk::push_constant]] ConstantBuffer u_GTAOConsts; - - - -#ifndef XE_GTAO_USE_DEFAULT_CONSTANTS -#define XE_GTAO_USE_DEFAULT_CONSTANTS 0 -#endif - -// some constants reduce performance if provided as dynamic values; if these constants are not required to be dynamic and they match default values, -// set XE_GTAO_USE_DEFAULT_CONSTANTS and the code will compile into a more efficient shader -#define XE_GTAO_DEFAULT_RADIUS_MULTIPLIER (1.457f ) // allows us to use different value as compared to ground truth radius to counter inherent screen space biases -#define XE_GTAO_DEFAULT_FALLOFF_RANGE (0.615f ) // distant samples contribute less -#define XE_GTAO_DEFAULT_SAMPLE_DISTRIBUTION_POWER (2.0f ) // small crevices more important than big surfaces -#define XE_GTAO_DEFAULT_THIN_OCCLUDER_COMPENSATION (0.0f ) // the new 'thickness heuristic' approach -#define XE_GTAO_DEFAULT_FINAL_VALUE_POWER (2.2f ) // modifies the final ambient occlusion value using power function - this allows some of the above heuristics to do different things -#define XE_GTAO_DEFAULT_DEPTH_MIP_SAMPLING_OFFSET (3.30f ) // main trade-off between performance (memory bandwidth) and quality (temporal stability is the first affected, thin objects next) - -#define XE_GTAO_PI (3.1415926535897932384626433832795) -#define XE_GTAO_PI_HALF (1.5707963267948966192313216916398) - -#if defined(XE_GTAO_FP32_DEPTHS) && XE_GTAO_USE_HALF_FLOAT_PRECISION -#error Using XE_GTAO_USE_HALF_FLOAT_PRECISION with 32bit depths is not supported yet unfortunately (it is possible to apply fp16 on parts not related to depth but this has not been done yet) -#endif - -uint XeGTAO_FLOAT4_to_R8G8B8A8_UNORM(lpfloat4 unpackedInput) -{ - return ((uint(saturate(unpackedInput.x) * (lpfloat)255 + (lpfloat)0.5)) | - (uint(saturate(unpackedInput.y) * (lpfloat)255 + (lpfloat)0.5) << 8) | - (uint(saturate(unpackedInput.z) * (lpfloat)255 + (lpfloat)0.5) << 16) | - (uint(saturate(unpackedInput.w) * (lpfloat)255 + (lpfloat)0.5) << 24)); -} - - -// Inputs are screen XY and viewspace depth, output is viewspace position -float3 XeGTAO_ComputeViewspacePosition(const float2 screenPos, const float viewspaceDepth) -{ - float3 ret; - ret.xy = mad(u_Camera.NDCToViewMul, screenPos.xy, u_Camera.NDCToViewAdd) * viewspaceDepth; - ret.z = viewspaceDepth; - return ret; -} - -lpfloat4 XeGTAO_CalculateEdges(const lpfloat centerZ, const lpfloat leftZ, const lpfloat rightZ, const lpfloat topZ, const lpfloat bottomZ) -{ - lpfloat4 edgesLRTB = lpfloat4(leftZ, rightZ, topZ, bottomZ) - (lpfloat)centerZ; - - lpfloat slopeLR = (edgesLRTB.y - edgesLRTB.x) * 0.5; - lpfloat slopeTB = (edgesLRTB.w - edgesLRTB.z) * 0.5; - lpfloat4 edgesLRTBSlopeAdjusted = edgesLRTB + lpfloat4(slopeLR, -slopeLR, slopeTB, -slopeTB); - edgesLRTB = min(abs(edgesLRTB), abs(edgesLRTBSlopeAdjusted)); - return lpfloat4(saturate((1.25 - edgesLRTB / (centerZ * 0.011)))); -} - -// packing/unpacking for edges; 2 bits per edge mean 4 gradient values (0, 0.33, 0.66, 1) for smoother transitions! -lpfloat XeGTAO_PackEdges(lpfloat4 edgesLRTB) -{ - // integer version: - // edgesLRTB = saturate(edgesLRTB) * 2.9.xxxx + 0.5.xxxx; - // return (((uint)edgesLRTB.x) << 6) + (((uint)edgesLRTB.y) << 4) + (((uint)edgesLRTB.z) << 2) + (((uint)edgesLRTB.w)); - // - // optimized, should be same as above - edgesLRTB = round(saturate(edgesLRTB) * 2.9); - return dot(edgesLRTB, lpfloat4(64.0 / 255.0, 16.0 / 255.0, 4.0 / 255.0, 1.0 / 255.0)); -} - -// http://h14s.p5r.org/2012/09/0x5f3759df.html, [Drobot2014a] Low Level Optimizations for GCN, https://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pdf slide 63 -lpfloat XeGTAO_FastSqrt(float x) -{ - return (lpfloat)(asfloat(0x1fbd1df5 + (asint(x) >> 1))); -} -// input [-1, 1] and output [0, PI], from https://seblagarde.wordpress.com/2014/12/01/inverse-trigonometric-functions-gpu-optimization-for-amd-gcn-architecture/ -lpfloat XeGTAO_FastACos(lpfloat inX) -{ - const lpfloat PI = 3.141593; - const lpfloat HALF_PI = 1.570796; - lpfloat x = abs(inX); - lpfloat res = -0.156583 * x + HALF_PI; - res *= XeGTAO_FastSqrt(1.0 - x); - return (inX >= 0) ? res : PI - res; -} - -uint XeGTAO_EncodeVisibilityBentNormal(lpfloat visibility, lpfloat3 bentNormal) -{ - return XeGTAO_FLOAT4_to_R8G8B8A8_UNORM(lpfloat4(bentNormal * 0.5 + 0.5, visibility)); -} - -void XeGTAO_OutputWorkingTerm(const uint2 pixCoord, lpfloat visibility, lpfloat3 bentNormal, RWTexture2D o_AOwBentNormals) -{ - visibility = (lpfloat)saturate(visibility / XE_GTAO_OCCLUSION_TERM_SCALE); -#if __HZ_GTAO_COMPUTE_BENT_NORMALS - o_AOwBentNormals[pixCoord] = XeGTAO_EncodeVisibilityBentNormal(visibility, bentNormal); -#else - o_AOwBentNormals[pixCoord] = uint(visibility * 255.0 + 0.5); -#endif -} - -// "Efficiently building a matrix to rotate one vector to another" -// http://cs.brown.edu/research/pubs/pdfs/1999/Moller-1999-EBA.pdf / https://dl.acm.org/doi/10.1080/10867651.1999.10487509 -// (using https://github.com/assimp/assimp/blob/master/include/assimp/matrix3x3.inl#L275 as a code reference as it seems to be best) -lpfloat3x3 XeGTAO_RotFromToMatrix(lpfloat3 from, lpfloat3 to) -{ - const lpfloat e = dot(from, to); - const lpfloat f = abs(e); //(e < 0)? -e:e; - - // WARNING: This has not been tested/worked through, especially not for 16bit floats; seems to work in our special use case (from is always {0, 0, -1}) but wouldn't use it in general - if (f > lpfloat(1.0 - 0.0003)) - return lpfloat3x3(1, 0, 0, 0, 1, 0, 0, 0, 1); - - const lpfloat3 v = cross(from, to); - /* ... use this hand optimized version (9 mults less) */ - const lpfloat h = (1.0) / (1.0 + e); /* optimization by Gottfried Chen */ - const lpfloat hvx = h * v.x; - const lpfloat hvz = h * v.z; - const lpfloat hvxy = hvx * v.y; - const lpfloat hvxz = hvx * v.z; - const lpfloat hvyz = hvz * v.y; - - lpfloat3x3 mtx; - mtx[0][0] = e + hvx * v.x; - mtx[0][1] = hvxy - v.z; - mtx[0][2] = hvxz + v.y; - - mtx[1][0] = hvxy + v.z; - mtx[1][1] = e + h * v.y * v.y; - mtx[1][2] = hvyz - v.x; - - mtx[2][0] = hvxz - v.y; - mtx[2][1] = hvyz + v.x; - mtx[2][2] = e + hvz * v.z; - - return mtx; -} - -float LinearizeDepth(const float screenDepth) -{ - float depthLinearizeMul = u_Camera.DepthUnpackConsts.x; - float depthLinearizeAdd = u_Camera.DepthUnpackConsts.y; - // Optimised version of "-cameraClipNear / (cameraClipFar - projDepth * (cameraClipFar - cameraClipNear)) * cameraClipFar" - return depthLinearizeMul / (depthLinearizeAdd - screenDepth); -} - -float4 LinearizeDepth(const float4 screenDepths) -{ - return float4(LinearizeDepth(screenDepths.x), LinearizeDepth(screenDepths.y), LinearizeDepth(screenDepths.z), LinearizeDepth(screenDepths.w)); -} - -void XeGTAO_MainPass(const int2 outputPixCoord, const int2 inputPixCoords, lpfloat sliceCount, lpfloat stepsPerSlice, const lpfloat2 localNoise) -{ - lpfloat4 viewspaceNormalLuminance = (lpfloat4)u_ViewNormal.Load(int3(inputPixCoords, 0)); - lpfloat3 viewspaceNormal = viewspaceNormalLuminance.xyz; - - viewspaceNormal.z = -viewspaceNormalLuminance.z; - - float2 normalizedScreenPos = (inputPixCoords + 0.5.xx) * u_ScreenData.InvFullResolution; - - float4 deviceZs = u_HiZDepth.GatherRed(u_samplerPointClamp, float2(inputPixCoords * u_ScreenData.InvFullResolution * u_GTAOConsts.HZBUVFactor)); - lpfloat4 valuesUL = (lpfloat4)LinearizeDepth(deviceZs); - lpfloat4 valuesBR = (lpfloat4)LinearizeDepth(u_HiZDepth.GatherRed(u_samplerPointClamp, float2(inputPixCoords * u_ScreenData.InvFullResolution * u_GTAOConsts.HZBUVFactor), int2(1, 1))); - - // viewspace Z at the center - lpfloat viewspaceZ = valuesUL.y; //u_HiZDepth.SampleLevel( u_samplerPointClamp, normalizedScreenPos, 0 ).x; - - // viewspace Zs left top right bottom - const lpfloat pixLZ = valuesUL.x; - const lpfloat pixTZ = valuesUL.z; - const lpfloat pixRZ = valuesBR.z; - const lpfloat pixBZ = valuesBR.x; - - lpfloat4 edgesLRTB = XeGTAO_CalculateEdges((lpfloat)viewspaceZ, (lpfloat)pixLZ, (lpfloat)pixRZ, (lpfloat)pixTZ, (lpfloat)pixBZ); - o_Edges[outputPixCoord] = XeGTAO_PackEdges(edgesLRTB); - - // Move center pixel slightly towards camera to avoid imprecision artifacts due to depth buffer imprecision; offset depends on depth texture format used -#ifdef XE_GTAO_FP32_DEPTHS - viewspaceZ *= 0.99999; // this is good for FP32 depth buffer -#else - viewspaceZ *= 0.99920; // this is good for FP16 depth buffer -#endif - - const float3 pixCenterPos = XeGTAO_ComputeViewspacePosition(normalizedScreenPos, viewspaceZ); - const lpfloat3 viewVec = (lpfloat3)normalize(-pixCenterPos); - - // prevents normals that are facing away from the view vector - xeGTAO struggles with extreme cases, but in Vanilla it seems rare so it's disabled by default - // viewspaceNormal = normalize( viewspaceNormal + max( 0, -dot( viewspaceNormal, viewVec ) ) * viewVec ); - -#if XE_GTAO_USE_DEFAULT_CONSTANTS - const lpfloat effectRadius = (lpfloat)u_GTAOConsts.EffectRadius * (lpfloat)XE_GTAO_DEFAULT_RADIUS_MULTIPLIER; - const lpfloat sampleDistributionPower = (lpfloat)XE_GTAO_DEFAULT_SAMPLE_DISTRIBUTION_POWER; - const lpfloat thinOccluderCompensation = (lpfloat)XE_GTAO_DEFAULT_THIN_OCCLUDER_COMPENSATION; - const lpfloat falloffRange = (lpfloat)XE_GTAO_DEFAULT_FALLOFF_RANGE * effectRadius; -#else - const lpfloat effectRadius = (lpfloat)u_GTAOConsts.EffectRadius * (lpfloat)u_GTAOConsts.RadiusMultiplier; - const lpfloat sampleDistributionPower = (lpfloat)u_GTAOConsts.SampleDistributionPower; - const lpfloat thinOccluderCompensation = (lpfloat)u_GTAOConsts.ThinOccluderCompensation; - const lpfloat falloffRange = (lpfloat)u_GTAOConsts.EffectFalloffRange * effectRadius; -#endif - - const lpfloat falloffFrom = effectRadius * ((lpfloat)1 - (lpfloat)u_GTAOConsts.EffectFalloffRange); - - // fadeout precompute optimisation - const lpfloat falloffMul = (lpfloat)-1.0 / (falloffRange); - const lpfloat falloffAdd = falloffFrom / (falloffRange)+(lpfloat)1.0; - - lpfloat visibility = 0; -#if __HZ_GTAO_COMPUTE_BENT_NORMALS - lpfloat3 bentNormal = 0; -#else - lpfloat3 bentNormal = viewspaceNormal; -#endif - - // see "Algorithm 1" in https://www.activision.com/cdn/research/Practical_Real_Time_Strategies_for_Accurate_Indirect_Occlusion_NEW%20VERSION_COLOR.pdf - { - const lpfloat noiseSlice = (lpfloat)localNoise.x; - const lpfloat noiseSample = (lpfloat)localNoise.y; - - // quality settings / tweaks / hacks - const lpfloat pixelTooCloseThreshold = 1.3; // if the offset is under approx pixel size (pixelTooCloseThreshold), push it out to the minimum distance - - // approx viewspace pixel size at inputPixCoords; approximation of NDCToViewspace( normalizedScreenPos.xy + u_ScreenData.InvFullResolution.xy, pixCenterPos.z ).xy - pixCenterPos.xy; - const float2 pixelDirRBViewspaceSizeAtCenterZ = viewspaceZ.xx * u_GTAOConsts.NDCToViewMul_x_PixelSize; - - lpfloat screenspaceRadius = effectRadius / (lpfloat)pixelDirRBViewspaceSizeAtCenterZ.x; - - // fade out for small screen radii - visibility += saturate((10 - screenspaceRadius) / 100) * 0.5; - -#if 1 // sensible early-out for even more performance; disabled because not yet tested - lpfloat normals = (lpfloat)viewspaceNormal; - [branch] - if (!deviceZs.y || screenspaceRadius < pixelTooCloseThreshold) - { - XeGTAO_OutputWorkingTerm(outputPixCoord, 1, viewspaceNormal, o_AOwBentNormals); - return; - } -#endif - - // this is the min distance to start sampling from to avoid sampling from the center pixel (no useful data obtained from sampling center pixel) - const lpfloat minS = (lpfloat)pixelTooCloseThreshold / screenspaceRadius; - - [unroll] - for (lpfloat slice = 0; slice < sliceCount; slice++) - { - lpfloat sliceK = (slice + noiseSlice) / sliceCount; - // lines 5, 6 from the paper - lpfloat phi = sliceK * XE_GTAO_PI; - lpfloat cosPhi = cos(phi); - lpfloat sinPhi = sin(phi); - lpfloat2 omega = lpfloat2(cosPhi, -sinPhi); //lpfloat2 on omega causes issues with big radii - - // convert to screen units (pixels) for later use - omega *= screenspaceRadius; - - // line 8 from the paper - const lpfloat3 directionVec = lpfloat3(cosPhi, sinPhi, 0); - - // line 9 from the paper - const lpfloat3 orthoDirectionVec = directionVec - (dot(directionVec, viewVec) * viewVec); - - // line 10 from the paper - //axisVec is orthogonal to directionVec and viewVec, used to define projectedNormal - const lpfloat3 axisVec = normalize(cross(orthoDirectionVec, viewVec)); - - // alternative line 9 from the paper - // float3 orthoDirectionVec = cross( viewVec, axisVec ); - - // line 11 from the paper - lpfloat3 projectedNormalVec = viewspaceNormal - axisVec * dot(viewspaceNormal, axisVec); - - // line 13 from the paper - lpfloat signNorm = (lpfloat)sign(dot(orthoDirectionVec, projectedNormalVec)); - - // line 14 from the paper - lpfloat projectedNormalVecLength = length(projectedNormalVec); - lpfloat cosNorm = (lpfloat)saturate(dot(projectedNormalVec, viewVec) / projectedNormalVecLength); - - // line 15 from the paper - lpfloat n = signNorm * XeGTAO_FastACos(cosNorm); - - // this is a lower weight target; not using -1 as in the original paper because it is under horizon, so a 'weight' has different meaning based on the normal - const lpfloat lowHorizonCos0 = cos(n + XE_GTAO_PI_HALF); - const lpfloat lowHorizonCos1 = cos(n - XE_GTAO_PI_HALF); - - // lines 17, 18 from the paper, manually unrolled the 'side' loop - lpfloat horizonCos0 = lowHorizonCos0; //-1; - lpfloat horizonCos1 = lowHorizonCos1; //-1; - - [unroll] - for (lpfloat step = 0; step < stepsPerSlice; step++) - { - // R1 sequence (http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/) - const lpfloat stepBaseNoise = lpfloat(slice + step * stepsPerSlice) * 0.6180339887498948482; // <- this should unroll - lpfloat stepNoise = frac(noiseSample + stepBaseNoise); - - // approx line 20 from the paper, with added noise - lpfloat s = (step + stepNoise) / (stepsPerSlice); // + (lpfloat2)1e-6f); - - // additional distribution modifier - s = (lpfloat)pow(s, (lpfloat)sampleDistributionPower); - - // avoid sampling center pixel - s += minS; - - // approx lines 21-22 from the paper, unrolled - lpfloat2 sampleOffset = s * omega; - - lpfloat sampleOffsetLength = length(sampleOffset); - - // note: when sampling, using point_point_point or point_point_linear sampler works, but linear_linear_linear will cause unwanted interpolation between neighbouring depth values on the same MIP level! - const lpfloat mipLevel = (lpfloat)clamp(log2(sampleOffsetLength) - u_GTAOConsts.DepthMIPSamplingOffset, 0, XE_GTAO_DEPTH_MIP_LEVELS); - - // Snap to pixel center (more correct direction math, avoids artifacts due to sampling pos not matching depth texel center - messes up slope - but adds other - // artifacts due to them being pushed off the slice). Also use full precision for high res cases. - sampleOffset = round(sampleOffset) * (lpfloat2)u_ScreenData.InvFullResolution; - - float2 sampleScreenPos0 = normalizedScreenPos + sampleOffset; - float SZ0 = LinearizeDepth(u_HiZDepth.SampleLevel(u_samplerPointClamp, sampleScreenPos0 * u_GTAOConsts.HZBUVFactor, mipLevel).x); - float3 samplePos0 = XeGTAO_ComputeViewspacePosition(sampleScreenPos0, SZ0); - - float2 sampleScreenPos1 = normalizedScreenPos - sampleOffset; - float SZ1 = LinearizeDepth(u_HiZDepth.SampleLevel(u_samplerPointClamp, sampleScreenPos1 * u_GTAOConsts.HZBUVFactor, mipLevel).x); - float3 samplePos1 = XeGTAO_ComputeViewspacePosition(sampleScreenPos1, SZ1); - - float3 sampleDelta0 = (samplePos0 - float3(pixCenterPos)); // using lpfloat for sampleDelta causes precision issues - float3 sampleDelta1 = (samplePos1 - float3(pixCenterPos)); // using lpfloat for sampleDelta causes precision issues - lpfloat sampleDist0 = (lpfloat)length(sampleDelta0); - lpfloat sampleDist1 = (lpfloat)length(sampleDelta1); - - // approx lines 23, 24 from the paper, unrolled - lpfloat3 sampleHorizonVec0 = (lpfloat3)(sampleDelta0 / sampleDist0); - lpfloat3 sampleHorizonVec1 = (lpfloat3)(sampleDelta1 / sampleDist1); - - // any sample out of radius should be discarded - also use fallof range for smooth transitions; this is a modified idea from "4.3 Implementation details, Bounding the sampling area" -#if XE_GTAO_USE_DEFAULT_CONSTANTS != 0 && XE_GTAO_DEFAULT_THIN_OBJECT_HEURISTIC == 0 - lpfloat weight0 = saturate(sampleDist0 * falloffMul + falloffAdd); - lpfloat weight1 = saturate(sampleDist1 * falloffMul + falloffAdd); -#else - // this is our own thickness heuristic that relies on sooner discarding samples behind the center - lpfloat falloffBase0 = length(lpfloat3(sampleDelta0.x, sampleDelta0.y, sampleDelta0.z * (1 + thinOccluderCompensation))); - lpfloat falloffBase1 = length(lpfloat3(sampleDelta1.x, sampleDelta1.y, sampleDelta1.z * (1 + thinOccluderCompensation))); - lpfloat weight0 = saturate(falloffBase0 * falloffMul + falloffAdd); - lpfloat weight1 = saturate(falloffBase1 * falloffMul + falloffAdd); -#endif - - // sample horizon cos - lpfloat shc0 = (lpfloat)dot(sampleHorizonVec0, viewVec); - lpfloat shc1 = (lpfloat)dot(sampleHorizonVec1, viewVec); - - // discard unwanted samples - shc0 = lerp(lowHorizonCos0, shc0, weight0); // this would be more correct but too expensive: cos(lerp( acos(lowHorizonCos0), acos(shc0), weight0 )); - shc1 = lerp(lowHorizonCos1, shc1, weight1); // this would be more correct but too expensive: cos(lerp( acos(lowHorizonCos1), acos(shc1), weight1 )); - - // thickness heuristic - see "4.3 Implementation details, Height-field assumption considerations" -#if 0 // (disabled, not used) this should match the paper - lpfloat newhorizonCos0 = max(horizonCos0, shc0); - lpfloat newhorizonCos1 = max(horizonCos1, shc1); - horizonCos0 = (horizonCos0 > shc0) ? (lerp(newhorizonCos0, shc0, thinOccluderCompensation)) : (newhorizonCos0); - horizonCos1 = (horizonCos1 > shc1) ? (lerp(newhorizonCos1, shc1, thinOccluderCompensation)) : (newhorizonCos1); -#elif 0 // (disabled, not used) this is slightly different from the paper but cheaper and provides very similar results - horizonCos0 = lerp(max(horizonCos0, shc0), shc0, thinOccluderCompensation); - horizonCos1 = lerp(max(horizonCos1, shc1), shc1, thinOccluderCompensation); -#else // this is a version where thicknessHeuristic is completely disabled - horizonCos0 = max(horizonCos0, shc0); - horizonCos1 = max(horizonCos1, shc1); -#endif - } - -#if 1 // I can't figure out the slight overdarkening on high slopes, so I'm adding this fudge - in the training set, 0.05 is close (PSNR 21.34) to disabled (PSNR 21.45) - projectedNormalVecLength = lerp(projectedNormalVecLength, 1, 0.05); -#endif - - // line ~27, unrolled - lpfloat h0 = -XeGTAO_FastACos((lpfloat)horizonCos1); - lpfloat h1 = XeGTAO_FastACos((lpfloat)horizonCos0); -#if 0 // we can skip clamping for a tiny little bit more performance - h0 = n + clamp(h0 - n, (lpfloat)-XE_GTAO_PI_HALF, (lpfloat)XE_GTAO_PI_HALF); - h1 = n + clamp(h1 - n, (lpfloat)-XE_GTAO_PI_HALF, (lpfloat)XE_GTAO_PI_HALF); -#endif - lpfloat iarc0 = ((lpfloat)cosNorm + (lpfloat)2 * (lpfloat)h0 * (lpfloat)sin(n) - (lpfloat)cos((lpfloat)2 * (lpfloat)h0 - n)) / (lpfloat)4; - lpfloat iarc1 = ((lpfloat)cosNorm + (lpfloat)2 * (lpfloat)h1 * (lpfloat)sin(n) - (lpfloat)cos((lpfloat)2 * (lpfloat)h1 - n)) / (lpfloat)4; - lpfloat localVisibility = (lpfloat)projectedNormalVecLength * (lpfloat)(iarc0 + iarc1); - visibility += localVisibility; - -#if __HZ_GTAO_COMPUTE_BENT_NORMALS - // see "Algorithm 2 Extension that computes bent normals b." - lpfloat t0 = (6 * sin(h0 - n) - sin(3 * h0 - n) + 6 * sin(h1 - n) - sin(3 * h1 - n) + 16 * sin(n) - 3 * (sin(h0 + n) + sin(h1 + n))) / 12; - lpfloat t1 = (-cos(3 * h0 - n) - cos(3 * h1 - n) + 8 * cos(n) - 3 * (cos(h0 + n) + cos(h1 + n))) / 12; - lpfloat3 localBentNormal = lpfloat3(directionVec.x * (lpfloat)t0, directionVec.y * (lpfloat)t0, -lpfloat(t1)); - localBentNormal = (lpfloat3)mul(XeGTAO_RotFromToMatrix(lpfloat3(0, 0, -1), viewVec), localBentNormal) * projectedNormalVecLength; - bentNormal += localBentNormal; -#endif - } - visibility /= (lpfloat)sliceCount; - visibility = (lpfloat)pow(visibility, (lpfloat)u_GTAOConsts.FinalValuePower * lerp(1.0f, (lpfloat)u_GTAOConsts.ShadowTolerance, viewspaceNormalLuminance.a)); - visibility = max((lpfloat)0.03, visibility); // disallow total occlusion (which wouldn't make any sense anyhow since pixel is visible but also helps with packing bent normals) - -#if __HZ_GTAO_COMPUTE_BENT_NORMALS - bentNormal = normalize(bentNormal); -#endif - } - - XeGTAO_OutputWorkingTerm(outputPixCoord, visibility, bentNormal, o_AOwBentNormals); -} - -// Engine-specific screen & temporal noise loader -lpfloat2 SpatioTemporalNoise(uint2 pixCoord, uint temporalIndex) // without TAA, temporalIndex is always 0 -{ - float2 noise; - // Hilbert curve driving R2 (see https://www.shadertoy.com/view/3tB3z3) - uint index = u_HilbertLut.Load(uint3(pixCoord % 64, 0)).x; - index += 288 * (temporalIndex % 64); // why 288? tried out a few and that's the best so far (with XE_HILBERT_LEVEL 6U) - but there's probably better :) - // R2 sequence - see http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/ - return lpfloat2(frac(0.5 + index * float2(0.75487766624669276005, 0.5698402909980532659114))); -} - -// Engine-specific entry point for the second pass -[numthreads(XE_GTAO_NUMTHREADS_X, XE_GTAO_NUMTHREADS_Y, 1)] -void main(const uint2 pixCoord : SV_DispatchThreadID) -{ - const int2 outputPixCoords = pixCoord; - const int2 inputPixCoords = outputPixCoords * (1 + int(u_GTAOConsts.HalfRes)); - XeGTAO_MainPass(outputPixCoords, inputPixCoords, 9, 3, SpatioTemporalNoise(inputPixCoords, u_GTAOConsts.NoiseIndex)); -} \ No newline at end of file diff --git a/Sandbox/Resources/Shaders/PostProcessing/Pre-Convolution.glsl b/Sandbox/Resources/Shaders/PostProcessing/Pre-Convolution.glsl deleted file mode 100644 index 7e8b4f54..00000000 --- a/Sandbox/Resources/Shaders/PostProcessing/Pre-Convolution.glsl +++ /dev/null @@ -1,76 +0,0 @@ -#version 430 core -#pragma stage : comp - -#include - -layout(binding = 0, rgba32f) restrict writeonly uniform image2D o_Image; -layout(binding = 1) uniform texture2D u_Input; - -layout(push_constant) uniform Uniforms -{ - int PrevLod; - int Mode; //See defines below -} u_Info; - -#define MODE_COPY (0) -#define MODE_HORIZONTAL_GAUSSIAN (1) -#define MODE_VERTICAL_GAUSSIAN (2) - -#define WEIGHT0 0.1749379741597446 -#define WEIGHT1 0.16556904917484133 -#define WEIGHT2 0.14036678002195038 -#define WEIGHT3 0.106595183723336 - -vec4 GaussianHorizontal(vec2 uv, vec2 pixelSize) -{ - vec4 color = SampleLinear(u_Input, uv + pixelSize.x * vec2(-3.0f, 0.0f)) * WEIGHT3; - color += SampleLinear(u_Input, uv + pixelSize.x * vec2(-2.0f, 0.0f)) * WEIGHT2; - color += SampleLinear(u_Input, uv + pixelSize.x * vec2(-1.0f, 0.0f)) * WEIGHT1; - color += SampleLinear(u_Input, uv) * WEIGHT0; - color += SampleLinear(u_Input, uv + pixelSize.x * vec2( 1.0f, 0.0f)) * WEIGHT1; - color += SampleLinear(u_Input, uv + pixelSize.x * vec2( 2.0f, 0.0f)) * WEIGHT2; - color += SampleLinear(u_Input, uv + pixelSize.x * vec2( 3.0f, 0.0f)) * WEIGHT3; - - return color; -} - -vec4 GaussianVertical(vec2 uv, vec2 pixelSize) -{ - vec4 color = SampleLinear(u_Input, uv + pixelSize.y * vec2(0.0f, -3.0f)) * WEIGHT3; - color += SampleLinear(u_Input, uv + pixelSize.y * vec2(0.0f, -2.0f)) * WEIGHT2; - color += SampleLinear(u_Input, uv + pixelSize.y * vec2(0.0f, -1.0f)) * WEIGHT1; - color += SampleLinear(u_Input, uv) * WEIGHT0; - color += SampleLinear(u_Input, uv + pixelSize.y * vec2(0.0f, 1.0f)) * WEIGHT1; - color += SampleLinear(u_Input, uv + pixelSize.y * vec2(0.0f, 2.0f)) * WEIGHT2; - color += SampleLinear(u_Input, uv + pixelSize.y * vec2(0.0f, 3.0f)) * WEIGHT3; - return color; -} - - -layout(local_size_x = 16, local_size_y = 16) in; -void main() -{ - vec2 imgSize = imageSize(o_Image); - ivec2 invocID = ivec2(gl_GlobalInvocationID); - vec2 pixelSize = 1.0f / imgSize; - vec2 texCoords = invocID * pixelSize + pixelSize * 0.5; - vec4 finalColor; - if (u_Info.Mode == MODE_COPY) - { - finalColor = SampleLinear(u_Input, texCoords); - } - else if (u_Info.Mode == MODE_HORIZONTAL_GAUSSIAN) - { - finalColor = GaussianHorizontal(texCoords, pixelSize); - } - else if(u_Info.Mode == MODE_VERTICAL_GAUSSIAN) - { - finalColor = GaussianVertical(texCoords, pixelSize); - } - - imageStore(o_Image, invocID, finalColor); -} - - - - diff --git a/Sandbox/Resources/Shaders/PostProcessing/SSR-Composite.glsl b/Sandbox/Resources/Shaders/PostProcessing/SSR-Composite.glsl deleted file mode 100644 index 020af172..00000000 --- a/Sandbox/Resources/Shaders/PostProcessing/SSR-Composite.glsl +++ /dev/null @@ -1,112 +0,0 @@ -#version 430 core -#pragma stage:vert - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec2 a_TexCoord; - -layout(location = 0) out vec2 vs_TexCoords; - -void main() -{ - vs_TexCoords = a_TexCoord; - gl_Position = vec4(a_Position.xy, 0.0, 1.0); -} - -#version 450 core -#pragma stage:frag - -#include -#include - -layout(set = 1, binding = 0) uniform texture2D u_SSR; -layout(set = 1, binding = 1) uniform texture2D u_Depth; -layout(set = 1, binding = 2) uniform texture2D u_Normal; - -layout(push_constant) uniform Uniforms -{ - uint ResolutionScale; - uint BilateralUpscale; - uint QuarterDebug; - float DepthSigma; - float NormalSigma; -} u_Uniforms; - -layout(location = 0) out vec4 outColor; -layout(location = 0) in vec2 vs_TexCoords; - -float LinearizeDepth(float screenDepth) -{ - float depthLinearizeMul = u_Camera.DepthUnpackConsts.x; - float depthLinearizeAdd = u_Camera.DepthUnpackConsts.y; - return depthLinearizeMul / (depthLinearizeAdd - screenDepth); -} - -float ReadDepth(vec2 uv) -{ - return LinearizeDepth(texture(sampler2D(u_Depth, r_PointSampler), uv).r); -} - -vec3 ReadNormal(vec2 uv) -{ - vec3 normal = texture(sampler2D(u_Normal, r_PointSampler), uv).xyz; - float normalLength = length(normal); - if (normalLength < 0.0001) - return vec3(0.0, 0.0, 1.0); - - return normal / normalLength; -} - -vec4 BilateralUpscaleSSR(vec2 uv) -{ - ivec2 ssrSize = GetTextureSize(u_SSR, 0); - vec2 ssrTexelSize = 1.0 / vec2(max(ssrSize, ivec2(1))); - - float centerDepth = ReadDepth(uv); - vec3 centerNormal = ReadNormal(uv); - - vec4 centerSSR = SampleLinear(u_SSR, uv); - vec4 weightedSSR = vec4(0.0); - float totalWeight = 0.0; - - for (int y = -1; y <= 1; y++) - { - for (int x = -1; x <= 1; x++) - { - vec2 offset = vec2(x, y); - vec2 sampleUV = clamp(uv + offset * ssrTexelSize, vec2(0.0), vec2(1.0)); - vec4 sampleSSR = SampleLinear(u_SSR, sampleUV); - - float sampleDepth = ReadDepth(sampleUV); - vec3 sampleNormal = ReadNormal(sampleUV); - - float relativeDepthDelta = abs(sampleDepth - centerDepth) / max(abs(centerDepth), 1.0); - float depthWeight = exp(-relativeDepthDelta / max(u_Uniforms.DepthSigma, 0.0001)); - float normalWeight = pow(clamp(dot(centerNormal, sampleNormal), 0.0, 1.0), max(u_Uniforms.NormalSigma, 1.0)); - float spatialWeight = exp(-dot(offset, offset) * 0.55); - float confidenceWeight = max(sampleSSR.a, 0.001); - float weight = depthWeight * normalWeight * spatialWeight * confidenceWeight; - - weightedSSR += sampleSSR * weight; - totalWeight += weight; - } - } - - if (totalWeight <= 0.0001) - return centerSSR; - - vec4 result = weightedSSR / totalWeight; - result.a = clamp(result.a, 0.0, 1.0); - return result; -} - -void main() -{ - bool useBilateralUpscale = u_Uniforms.BilateralUpscale != 0u || u_Uniforms.QuarterDebug != 0u; - if (u_Uniforms.ResolutionScale <= 1u || !useBilateralUpscale) - { - outColor = SampleLinear(u_SSR, vs_TexCoords); - return; - } - - outColor = BilateralUpscaleSSR(vs_TexCoords); -} diff --git a/Sandbox/Resources/Shaders/PostProcessing/SSR.glsl b/Sandbox/Resources/Shaders/PostProcessing/SSR.glsl deleted file mode 100644 index d7c2e3f6..00000000 --- a/Sandbox/Resources/Shaders/PostProcessing/SSR.glsl +++ /dev/null @@ -1,410 +0,0 @@ -// --------------------------------------- -// -- Hazel Engine SSR shader -- -// --------------------------------------- -// - References: -// AMD's Stochastic screen-space reflections https://gpuopen.com/fidelityfx-sssr/ -// GPU Pro 5 book chapter 4 by Yasin Uludag -// Will Pearce's blog http://roar11.com/2015/07/screen-space-glossy-reflections/ -// Unreal Engine 4 SSR implimentation -// Lukas Hermanns's thesis https://lukas-hermanns.info/download/bachelorthesis_ssct_lhermanns.pdf -#version 430 core -#pragma stage : comp -#include -#include - -#include -#include - -layout(set = 1, binding = 1, rgba16f) restrict writeonly uniform image2D outColor; -layout(set = 1, binding = 2) uniform texture2D u_InputColor; -layout(set = 1, binding = 3) uniform texture2D u_Normal; -layout(set = 1, binding = 4) uniform texture2D u_HiZBuffer; -layout(set = 1, binding = 5) uniform texture2D u_MetalnessRoughness; -layout(set = 1, binding = 6) uniform texture2D u_VisibilityBuffer; - -#define GTAO_REFLECTION_OCCLUSION (__HZ_REFLECTION_OCCLUSION_METHOD & HZ_REFLECTION_OCCLUSION_METHOD_GTAO) -#define HBAO_REFLECTION_OCCLUSION (__HZ_REFLECTION_OCCLUSION_METHOD & HZ_REFLECTION_OCCLUSION_METHOD_HBAO) - -#if GTAO_REFLECTION_OCCLUSION - layout(set = 1, binding = 7) uniform usampler2D u_GTAOTex; -#endif - -#if HBAO_REFLECTION_OCCLUSION - layout(set = 1, binding = 8) uniform sampler2D u_HBAOTex; -#endif - -layout(push_constant) uniform SSRInfo -{ - vec2 HZBUVFactor; - vec2 FadeIn; - float Brightness; - float DepthTolerance; - float FacingReflectionsFading; - int MaxSteps; - uint NumDepthMips; - float RoughnessDepthTolerance; // The higher the roughness the more we have depth tolerance - bool HalfRes; - bool EnableConeTracing; - float LuminanceFactor; -} u_SSRInfo; - - -#define INVERTED_DEPTH_RANGE -const float M_PI = 3.14159265359f; -const float FLOAT_MAX = 3.402823466e+38f; -const int BASE_LOD = 0; - -/////////////////////////////////////////////////////////////////////////////////////// -// Hi-Z cone tracing -/////////////////////////////////////////////////////////////////////////////////////// - -float IsoscelesTriangleOpposite(float adjacentLength, float coneTheta) -{ - return 2.0 * tan(coneTheta) * adjacentLength; -} - -float IsoscelesTriangleInRadius(float a, float h) -{ - float a2 = a * a; - float fh2 = 4.0f * h * h; - return (a * (sqrt(a2 + fh2) - a)) / (4.0f * h); -} - -vec4 ConeSampleWeightedColor(vec2 samplePos, float mipLevel) -{ - /* Sample color buffer with pre-integrated visibility */ - vec3 color = SampleLinearLOD(u_InputColor, samplePos, mipLevel).rgb; - float visibility = SampleLinearLOD(u_VisibilityBuffer, samplePos, mipLevel).r; - return vec4(color * visibility, visibility); -} - -float IsoscelesTriangleNextAdjacent(float adjacentLength, float incircleRadius) -{ - // subtract the diameter of the incircle to get the adjacent side of the next level on the cone - return adjacentLength - (incircleRadius * 2.0); -} - -vec4 ConeTracing(float roughness, vec2 rayOriginSS, vec2 rayPosSS) -{ - float coneTheta = roughness * M_PI * 0.025; - - vec2 res = u_ScreenData.FullResolution * (1 + int(!u_SSRInfo.HalfRes)); - - /* Cone tracing using an isosceles triangle to approximate a cone in screen space */ - vec2 deltaPos = rayPosSS - rayOriginSS; - - - float adjacentLength = length(deltaPos); - vec2 adjacentUnit = normalize(deltaPos); - - vec4 reflectionColor = vec4(0.0); - vec2 samplePos; - float remainingAlpha = 1.0f; - for (int i = 0; i < 7; ++i) - { - // intersection length is the adjacent side, get the opposite side using trig - float oppositeLength = IsoscelesTriangleOpposite(adjacentLength, coneTheta); - - // calculate in-radius of the isosceles triangle - float incircleSize = IsoscelesTriangleInRadius(oppositeLength, adjacentLength); - - // get the sample position in screen space - samplePos = rayOriginSS + adjacentUnit * (adjacentLength - incircleSize); - - // convert the in-radius into screen size then check what power N to raise 2 to reach it - that power N becomes mip level to sample from - float mipChannel = clamp(log2(incircleSize * max(res.x, res.y)), 0.0f, u_SSRInfo.NumDepthMips); - - /* - * Read color and accumulate it using trilinear filtering and weight it. - * Uses pre-convolved image (color buffer) and glossiness to weigh color contributions. - * Visibility is accumulated in the alpha channel. Break if visibility is 100% or greater (>= 1.0f). - */ - vec4 newColor = ConeSampleWeightedColor(samplePos.xy, mipChannel); - remainingAlpha -= newColor.a; - if (remainingAlpha < 0.0f) - { - newColor.rgb *= (1.0f - abs(remainingAlpha)); - } - reflectionColor += newColor; - - if (reflectionColor.a >= 1.0f) - { - break; - } - - adjacentLength = IsoscelesTriangleNextAdjacent(adjacentLength, incircleSize); - } - - return reflectionColor; -} - -/////////////////////////////////////////////////////////////////////////////////////// -// Hi-Z ray tracing methods -/////////////////////////////////////////////////////////////////////////////////////// - -float FetchDepth(ivec2 coords, int lod) -{ - return texelFetch(sampler2D(u_HiZBuffer, r_LinearSampler), coords, lod).x; -} - -ivec2 GetDepthMipResolution(int mipLevel) -{ - return ivec2(GetTextureSize(u_HiZBuffer, mipLevel) * u_SSRInfo.HZBUVFactor); -} - -// Inputs are screen XY and viewspace depth, output is viewspace position -// From XeGTAO -vec3 ComputeViewspacePosition(const vec2 screenPos, const float viewspaceDepth) -{ - vec3 ret; - ret.xy = (u_Camera.NDCToViewMul * screenPos.xy + u_Camera.NDCToViewAdd) * viewspaceDepth; - ret.z = -viewspaceDepth; - return ret; -} - -//// From XeGTAO -float ScreenSpaceToViewSpaceDepth(const float screenDepth) -{ - float depthLinearizeMul = u_Camera.DepthUnpackConsts.x; - float depthLinearizeAdd = u_Camera.DepthUnpackConsts.y; - // Optimised version of "-cameraClipNear / (cameraClipFar - projDepth * (cameraClipFar - cameraClipNear)) * cameraClipFar" - return depthLinearizeMul / (depthLinearizeAdd - screenDepth); -} - -void InitialAdvanceRay(vec3 origin, vec3 direction, vec3 invDirection, vec2 currentMipResolution, vec2 currentMipResolutionInv, vec2 floorOffset, vec2 uvOffset, out vec3 position, out float currentT) -{ - vec2 currentMipPosition = currentMipResolution * origin.xy; - - // Intersect ray with the half box that is pointing away from the ray origin. - vec2 xyPlane = floor(currentMipPosition) + floorOffset; - xyPlane = xyPlane * currentMipResolutionInv + uvOffset; - - // o + d * t = p' => t = (p' - o) / d - vec2 t = xyPlane * invDirection.xy - origin.xy * invDirection.xy; - currentT = min(t.x, t.y); - position = origin + currentT * direction; -} - -void SecondAdvanceRay(vec3 origin, vec3 direction, vec3 invDirection, vec2 currentMipPosition, vec2 currentMipResolutionInv, vec2 floorOffset, vec2 uvOffset, inout vec3 position, inout float currentT) -{ - // Create boundary planes - vec2 xyPlane = floor(currentMipPosition) + floorOffset; - xyPlane = xyPlane * currentMipResolutionInv + uvOffset; - - // o + d * t = p' => t = (p' - o) / d - vec2 t = xyPlane * invDirection.xy - origin.xy * invDirection.xy; - currentT = min(t.x, t.y); - position = origin + currentT * direction; -} - -bool AdvanceRay(vec3 origin, vec3 direction, vec3 invDirection, vec2 currentMipPosition, vec2 currentMipResolutionInv, vec2 floorOffset, vec2 uvOffset, float surfaceZ, inout vec3 position, inout float currentT) -{ - // Create boundary planes - vec2 xyPlane = floor(currentMipPosition) + floorOffset; - xyPlane = xyPlane * currentMipResolutionInv + uvOffset; - vec3 boundaryPlanes = vec3(xyPlane, surfaceZ); - - // Intersect ray with the half box that is pointing away from the ray origin. - // o + d * t = p' => t = (p' - o) / d - vec3 t = boundaryPlanes * invDirection - origin * invDirection; - - // Prevent using z plane when shooting out of the depth buffer. - #ifdef INVERTED_DEPTH_RANGE - t.z = direction.z < 0 ? t.z : FLOAT_MAX; - #else - t.z = direction.z > 0 ? t.z : FLOAT_MAX; - #endif - - // Choose nearest intersection with a boundary. - float tMin = min(min(t.x, t.y), t.z); - - #ifdef INVERTED_DEPTH_RANGE - // Larger z means closer to the camera. - bool aboveSurface = surfaceZ < position.z; - #else - // Smaller z means closer to the camera. - bool aboveSurface = surfaceZ > position.z; - #endif - - // Decide whether we are able to advance the ray until we hit the xy boundaries or if we had to clamp it at the surface. - // We use the asuint comparison to avoid NaN / Inf logic, also we actually care about bitwise equality here to see if t_min is the t.z we fed into the min3 above. - bool skippedTile = floatBitsToUint(tMin) != floatBitsToUint(t.z) && aboveSurface; - - // Make sure to only advance the ray if we're still above the surface. - currentT = aboveSurface ? tMin : currentT; - - // Advance ray - position = origin + currentT * direction; - - return skippedTile; -} - -// Requires origin and direction of the ray to be in screen space [0, 1] x [0, 1] -vec3 HierarchicalRaymarch(vec3 origin, vec3 direction, vec2 screenSize, int mostDetailedMip, uint minTraversalOccupancy, uint maxTraversalIntersections, out uint iterations, out bool validHit) -{ - const vec3 invDirection = direction != vec3(0) ? 1.0 / direction : vec3(FLOAT_MAX); - - // Start on mip with highest detail. - int currentMip = mostDetailedMip; - - // Could recompute these every iteration, but it's faster to hoist them out and update them. - vec2 currentMipResolution = GetDepthMipResolution(currentMip); - vec2 currentMipResolutionInv = 1 / currentMipResolution; - - // Offset to the bounding boxes uv space to intersect the ray with the center of the next pixel. - // This means we ever so slightly over shoot into the next region. - vec2 uvOffset = 0.005 * exp2(mostDetailedMip) / screenSize; - uvOffset.x = (direction.x < 0.0 ? -uvOffset.x : uvOffset.x); - uvOffset.y = (direction.y < 0.0 ? -uvOffset.y : uvOffset.y); - - // Offset applied depending on current mip resolution to move the boundary to the left/right upper/lower border depending on ray direction. - vec2 floorOffset; - floorOffset.x = (direction.x < 0.0 ? 0.0 : 1.0); - floorOffset.y = (direction.y < 0.0 ? 0.0 : 1.0); - - float currentT; - vec3 position; - // Initially advance ray to avoid immediate self intersections. - InitialAdvanceRay(origin, direction, invDirection, currentMipResolution, currentMipResolutionInv, floorOffset, uvOffset, position, currentT); - vec2 currentMipPosition = currentMipResolution * position.xy; - - // This is a way to prevent artifacts on bumpy surfaces (rough normals). - SecondAdvanceRay(origin, direction, invDirection, currentMipPosition, currentMipResolutionInv, floorOffset, uvOffset, position, currentT); - - iterations = 0; - while (iterations < maxTraversalIntersections && currentMip >= mostDetailedMip) - { - currentMipPosition = currentMipResolution * position.xy; - float surfaceZ = FetchDepth(ivec2(currentMipPosition), currentMip); - bool skippedTile = AdvanceRay(origin, direction, invDirection, currentMipPosition, currentMipResolutionInv, floorOffset, uvOffset, surfaceZ, position, currentT); - currentMip += skippedTile ? 1 : -1; - currentMipResolution *= skippedTile ? 0.5 : 2; - currentMipResolutionInv *= skippedTile ? 2 : 0.5; - ++iterations; - } - - validHit = (iterations < maxTraversalIntersections); - - return position; -} - -float ValidateHit(vec3 origin, vec3 ray, vec3 originPosVS, vec3 rayDirVS, float roughness) -{ - // Reject hits outside the view frustum - if (any(lessThan(ray.xy, vec2(0.0))) || any(greaterThan(ray.xy, vec2(1.0)))) - return 0; - - // Reject the ray if we didnt advance the ray significantly to avoid immediate self reflection - vec2 manhattanDist = abs(ray.xy - origin.xy); - if (all(lessThan(manhattanDist, u_ScreenData.InvHalfResolution))) - return 0; - - // Don't lookup radiance from the background. - float surfaceZ = FetchDepth(ivec2(GetDepthMipResolution(0) * ray.xy), 0).x; -#ifdef INVERTED_DEPTH_RANGE - if (surfaceZ == 0.0) -#else - if (surfaceZ == 1.0) -#endif - return 0; - - float surfaceDepthVS = ScreenSpaceToViewSpaceDepth(surfaceZ); - vec3 surfacePosVS = ComputeViewspacePosition(ray.xy, surfaceDepthVS); - - float hitDepthVS = ScreenSpaceToViewSpaceDepth(ray.z); - vec3 hitPositionVS = ComputeViewspacePosition(ray.xy, hitDepthVS); - - float distanceTravelled = length(surfacePosVS - hitPositionVS); - - // We accept all hits that are within a reasonable minimum distance below the surface. - // Add constant in linear space to avoid growing of the reflections toward the reflected objects. - // Roughness depth tolerance allows rough surfaces to be more depth tolerant, meaning with less failing rays. - float confidence = 1.0f - smoothstep(0.0f, u_SSRInfo.DepthTolerance + mix(0.0f, u_SSRInfo.RoughnessDepthTolerance, roughness), distanceTravelled); - - // Fade out hits near the screen borders - vec2 viewportSize = u_ScreenData.FullResolution; - vec2 fov = u_SSRInfo.FadeIn * vec2(viewportSize.y / viewportSize.x, 1.0f); - vec2 border = smoothstep(vec2(0.0f), fov, ray.xy) * (1.0f - smoothstep(1.0f - fov, vec2(1.0f), ray.xy)); - float vignette = border.x * border.y; - - // Fade rays pointing towards camera - float fadeOnMirror = clamp(max(dot(originPosVS, rayDirVS), 0.0f) + u_SSRInfo.FacingReflectionsFading, 0.0f, 1.0f); - return confidence * fadeOnMirror * vignette * (1.0f - roughness); -} - -vec3 FresnelSchlickRoughness(vec3 F0, float cosTheta, float roughness) -{ - return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0); -} - -layout(local_size_x = 8, local_size_y = 8) in; -void main() -{ - const ivec2 base = ivec2(gl_GlobalInvocationID); - vec2 uv = u_SSRInfo.HalfRes ? u_ScreenData.InvHalfResolution * (base + 0.25) : u_ScreenData.InvFullResolution * (base + 0.50); - const ivec2 baseDepthResolution = GetDepthMipResolution(BASE_LOD); - const float depth = FetchDepth(ivec2(baseDepthResolution * uv), 0).r; - - const vec4 albedo = SampleLinear(u_InputColor, uv); - const vec2 metalnessRoughness = SampleLinear(u_MetalnessRoughness, uv).xy; - - //const vec4 albedo = vec4(1,1,1,1);//SampleLinear(u_InputColor, uv); - //const vec2 metalnessRoughness = vec2(1,0.7); - - vec3 normalVS = SampleLinear(u_Normal, uv).xyz; - //Y Flip from vulkan->nvrhi - normalVS.y *= -1; - - const float depthVS = ScreenSpaceToViewSpaceDepth(depth); - const vec3 positionVS = ComputeViewspacePosition(uv, depthVS); - const vec3 toPositionVS = normalize(positionVS.xyz); - const vec3 reflectVS = reflect(toPositionVS, normalVS); - const vec4 positionPrimeSS4 = u_Camera.ProjectionMatrix * vec4(positionVS.xyz + reflectVS, 1.0f); - vec3 positionPrimeSS = (positionPrimeSS4.xyz / positionPrimeSS4.w); - - positionPrimeSS.xy = positionPrimeSS.xy * 0.5f + 0.5f; - - const vec3 positionSS = vec3(uv, depth); - const vec3 reflectSS = vec3(positionPrimeSS - positionSS); - - uint iterations; - bool validHit = false; - vec3 ray = HierarchicalRaymarch(positionSS, reflectSS, baseDepthResolution, BASE_LOD, 4, u_SSRInfo.MaxSteps, iterations, validHit); - - vec4 totalColor; - if (u_SSRInfo.EnableConeTracing) - totalColor = ConeTracing(metalnessRoughness.g, positionSS.xy, ray.xy); - else - totalColor = texelFetch(sampler2D(u_InputColor, r_LinearSampler), ivec2(ray.xy * GetTextureSize(u_InputColor, 0)), 0); - - vec3 F0 = mix(vec3(0.04), albedo.rgb, metalnessRoughness.r); - - totalColor.rgb *= FresnelSchlickRoughness(F0, max(dot(normalVS, toPositionVS), 0.0), metalnessRoughness.g); - - float confidence = validHit ? ValidateHit(positionSS, ray, toPositionVS, reflectVS, metalnessRoughness.g) : 0; - - // From CesiumJS https://github.com/CesiumGS/cesium - totalColor *= max(1.f, dot(totalColor.rgb, vec3(0.2125, 0.7154, 0.0721) * u_SSRInfo.LuminanceFactor)) * u_SSRInfo.Brightness; - - // Reflection occlusion - float ao = 1.0f; - -#if GTAO_REFLECTION_OCCLUSION - #if __HZ_GTAO_COMPUTE_BENT_NORMALS - ao = (SampleLinear(u_GTAOTex, positionSS.xy).x >> 24) / 255.f; - #else - ao = SampleLinear(u_GTAOTex, positionSS.xy).x / 255.f; - #endif - ao = min(ao * XE_GTAO_OCCLUSION_TERM_SCALE, 1.0f); -#endif - -#if HBAO_REFLECTION_OCCLUSION - ao *= SampleLinear(u_HBAOTex, positionSS.xy).x; -#endif - float roughnessFactor = mix(clamp(0.0, 1.0, metalnessRoughness.r + ao), 0.0625f, pow(metalnessRoughness.g, 4)); - - // Confidence can be negtive. If it is, it will leave unwanted reflections. - imageStore(outColor, ivec2(base), vec4(roughnessFactor * totalColor.rgb, max(confidence, 0.0))); -} - - diff --git a/Sandbox/Resources/Shaders/PostProcessing/SceneComposite.glsl b/Sandbox/Resources/Shaders/PostProcessing/SceneComposite.glsl deleted file mode 100644 index d198c11a..00000000 --- a/Sandbox/Resources/Shaders/PostProcessing/SceneComposite.glsl +++ /dev/null @@ -1,214 +0,0 @@ -#version 450 core -#pragma stage : vert - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec2 a_TexCoord; - -struct OutputBlock -{ - vec2 TexCoord; -}; - -layout (location = 0) out OutputBlock Output; - -void main() -{ - vec4 position = vec4(a_Position.xy, 0.0, 1.0); - Output.TexCoord = a_TexCoord; - gl_Position = position; -} - -#version 450 core -#pragma stage : frag - -#define HZ_RENDERER_EDGE_OUTLINE_EFFECT 0 -#define HZ_RENDERER_FOG_EFFECT 0 - -#include -#include - -layout(location = 0) out vec4 o_Color; - -struct OutputBlock -{ - vec2 TexCoord; -}; - -layout (location = 0) in OutputBlock Input; - -layout (set = 1, binding = 0) uniform texture2D u_Texture; -layout (set = 1, binding = 1) uniform texture2D u_BloomTexture; -layout (set = 1, binding = 2) uniform texture2D u_BloomDirtTexture; -layout (set = 1, binding = 3) uniform texture2D u_DepthTexture; -layout (set = 1, binding = 4) uniform texture2D u_TransparentDepthTexture; - -#if HZ_RENDERER_EDGE_OUTLINE_EFFECT -layout (set = 1, binding = 5) uniform texture2D u_EdgeTexture; -#endif - -layout(push_constant) uniform Uniforms -{ - float Exposure; - float BloomIntensity; - float BloomDirtIntensity; - float Opacity; - float Time; -} u_Uniforms; - -float LinearizeDepth(const float screenDepth) -{ - float depthLinearizeMul = u_Camera.DepthUnpackConsts.x; - float depthLinearizeAdd = u_Camera.DepthUnpackConsts.y; - return depthLinearizeMul / (depthLinearizeAdd - screenDepth); -} - -vec4 LinearizeDepth(vec4 deviceZs) -{ - return vec4(LinearizeDepth(deviceZs.x), LinearizeDepth(deviceZs.y), LinearizeDepth(deviceZs.z), LinearizeDepth(deviceZs.w)); -} - -vec3 UpsampleTent9(texture2D tex, float lod, vec2 uv, vec2 texelSize, float radius) -{ - vec4 offset = texelSize.xyxy * vec4(1.0f, 1.0f, -1.0f, 0.0f) * radius; - - // Center - vec3 result = SampleLinearLOD(tex, uv, lod).rgb * 4.0f; - - result += SampleLinearLOD(tex, uv - offset.xy, lod).rgb; - result += SampleLinearLOD(tex, uv - offset.wy, lod).rgb * 2.0; - result += SampleLinearLOD(tex, uv - offset.zy, lod).rgb; - - result += SampleLinearLOD(tex, uv + offset.zw, lod).rgb * 2.0; - result += SampleLinearLOD(tex, uv + offset.xw, lod).rgb * 2.0; - - result += SampleLinearLOD(tex, uv + offset.zy, lod).rgb; - result += SampleLinearLOD(tex, uv + offset.wy, lod).rgb * 2.0; - result += SampleLinearLOD(tex, uv + offset.xy, lod).rgb; - - return result * (1.0f / 16.0f); -} - -// Based on http://www.oscars.org/science-technology/sci-tech-projects/aces -vec3 ACESTonemap(vec3 color) -{ - mat3 m1 = mat3( - 0.59719, 0.07600, 0.02840, - 0.35458, 0.90834, 0.13383, - 0.04823, 0.01566, 0.83777 - ); - mat3 m2 = mat3( - 1.60475, -0.10208, -0.00327, - -0.53108, 1.10813, -0.07276, - -0.07367, -0.00605, 1.07602 - ); - vec3 v = m1 * color; - vec3 a = v * (v + 0.0245786) - 0.000090537; - vec3 b = v * (0.983729 * v + 0.4329510) + 0.238081; - return clamp(m2 * (a / b), 0.0, 1.0); -} - -vec3 GammaCorrect(vec3 color, float gamma) -{ - return pow(color, vec3(1.0f / gamma)); -} - -void main() -{ - const float gamma = 2.2; - const float pureWhite = 1.0; - float sampleScale = 0.5; - - vec3 color = SampleLinear(u_Texture, Input.TexCoord).rgb; - -#if HZ_RENDERER_EDGE_OUTLINE_EFFECT - { - const vec4 edgeColor = vec4(0.2, 0.2, 0.15, 1.0); - const vec4 backgroundColor = vec4(1,0.95,0.85,1); - float errorPeriod = 30.0; - float errorRange = 0.001; - - vec2 uvs[3]; - uvs[0] = Input.TexCoord + vec2(errorRange * sin(errorPeriod * Input.TexCoord.y + 0.0), errorRange * sin(errorPeriod * Input.TexCoord.x + 0.0)); - uvs[1] = Input.TexCoord + vec2(errorRange * sin(errorPeriod * Input.TexCoord.y + 1.047), errorRange * sin(errorPeriod * Input.TexCoord.x + 3.142)); - uvs[2] = Input.TexCoord + vec2(errorRange * sin(errorPeriod * Input.TexCoord.y + 2.094), errorRange * sin(errorPeriod * Input.TexCoord.x + 1.571)); - - float edge = SampleLinear(u_EdgeTexture, uvs[0]).r * SampleLinear(u_EdgeTexture, uvs[1]).r * SampleLinear(u_EdgeTexture, uvs[2]).r; - - // float edge = texture(u_EdgeTexture, Input.TexCoord).r; - // color *= edge; - - if (edge < 0.5) - { - color = mix(color, edgeColor.rgb * 0.1, 0.9); - } - - float diffuse = (color.x + color.y + color.z) / 3.0; - - float w = fwidth(diffuse) * 2.0; - vec4 mCol = mix(backgroundColor * 0.5, backgroundColor, mix(0.0, 1.0, smoothstep(-w, w, diffuse - 0.3))); - vec3 newCol = mix(edgeColor, mCol, edge).xyz; - //color = mix(newCol, color, 0.0); - edge += 0.5; - edge = clamp(edge, 0.0, 1.0); - } -#endif - - ivec2 texSize = GetTextureSize(u_BloomTexture, 0); - vec2 fTexSize = vec2(float(texSize.x), float(texSize.y)); - vec3 bloom = UpsampleTent9(u_BloomTexture, 0, Input.TexCoord, 1.0f / fTexSize, sampleScale) * u_Uniforms.BloomIntensity; - vec3 bloomDirt = SampleLinear(u_BloomDirtTexture, Input.TexCoord).rgb * u_Uniforms.BloomDirtIntensity; - - // Fog -#if HZ_RENDERER_FOG_EFFECT - { - float depth = SampleLinear(u_DepthTexture, Input.TexCoord).r; - depth = LinearizeDepth(depth); - - float fogStartDistance = 5.5f; - //fogStartDistance = 1.0f; - float bloomFogStartDistance = 50.0f; - float fogFallOffDistance = 30.0f; - float bloomFogFallOffDistance = 50.0f; - - float fogAmount = smoothstep(fogStartDistance, fogStartDistance + fogFallOffDistance, depth); - float fogAmountBloom = smoothstep(bloomFogStartDistance, bloomFogStartDistance + bloomFogFallOffDistance, depth); - - // Skybox - //if (d == 0.0) - //{ - // color *= 0.2f; - // fogAmount = 0.0; - // fogAmountBloom = 0.0; - //} - - vec3 fogColor = vec3(0.11f, 0.12f, 0.15f); - fogColor *= 2.0f; - vec3 bloomClamped = clamp(bloom * (1.0f - fogAmountBloom), 0.0f, 1.0f); - float intensity = (bloomClamped.r + bloomClamped.g + bloomClamped.b) / 3.0f; - fogColor = mix(fogColor, color, intensity); - - color = mix(color, fogColor, fogAmount); - fogAmountBloom = clamp(fogAmountBloom, 0, 1); - //bloom *= (1.0f - fogAmountBloom); - } -#endif - - color += bloom; - color += bloom * bloomDirt; - color *= u_Uniforms.Exposure; - - // Grain - float strength = 5.0; - - float x = (Input.TexCoord.x + 1.0 ) * (Input.TexCoord.y + 1.0 ) * u_Uniforms.Time; - float grain = mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01) - 0.006; - - //color += grain * strength; - color = ACESTonemap(color); - - color = GammaCorrect(color.rgb, gamma); - - color *= u_Uniforms.Opacity; - - o_Color = vec4(color, 1.0); -} diff --git a/Sandbox/Resources/Shaders/Pre-Integration.glsl b/Sandbox/Resources/Shaders/Pre-Integration.glsl deleted file mode 100644 index 865d150a..00000000 --- a/Sandbox/Resources/Shaders/Pre-Integration.glsl +++ /dev/null @@ -1,51 +0,0 @@ -#version 430 core -#pragma stage : comp - -#include - -layout(push_constant) uniform Info -{ - vec2 u_HZBInvRes; - vec2 u_InvRes; - vec2 u_ProjectionParams; //(x) = Near plane, (y) = Far plane // Reversed - int u_PrevMip; -}; - -layout(binding = 0, r8) restrict uniform writeonly image2D o_VisibilityImage; -layout(binding = 1) uniform texture2D u_VisibilityTex; -layout(binding = 2) uniform texture2D u_HZB; - -float LinearizeDepth(float d) -{ - return u_ProjectionParams.x * u_ProjectionParams.y / (u_ProjectionParams.y + d * (u_ProjectionParams.x - u_ProjectionParams.y)); -} - -layout(local_size_x = 8, local_size_y = 8) in; -void main() -{ - ivec2 base = ivec2(gl_GlobalInvocationID); - vec2 hzbUV = u_HZBInvRes * base; - vec2 uv = u_InvRes * base; - - vec4 fineZ; - fineZ.x = LinearizeDepth(SampleLinearLOD(u_HZB, hzbUV + u_HZBInvRes * vec2(-0.5, -0.5), u_PrevMip).x); - fineZ.y = LinearizeDepth(SampleLinearLOD(u_HZB, hzbUV + u_HZBInvRes * vec2(-0.5, 0.0), u_PrevMip).x); - fineZ.z = LinearizeDepth(SampleLinearLOD(u_HZB, hzbUV + u_HZBInvRes * vec2( 0.0, -0.5), u_PrevMip).x); - fineZ.w = LinearizeDepth(SampleLinearLOD(u_HZB, hzbUV + u_HZBInvRes * vec2( 0.5, 0.5), u_PrevMip).x); - - /* Fetch fine visibility from previous visibility map LOD */ - vec4 visibility; - visibility.x = SampleLinearLOD(u_VisibilityTex, uv + u_InvRes * vec2(-0.5, -0.5), u_PrevMip).r; - visibility.y = SampleLinearLOD(u_VisibilityTex, uv + u_InvRes * vec2(-0.5, 0.0), u_PrevMip).r; - visibility.z = SampleLinearLOD(u_VisibilityTex, uv + u_InvRes * vec2( 0.0, -0.5), u_PrevMip).r; - visibility.w = SampleLinearLOD(u_VisibilityTex, uv + u_InvRes * vec2( 0.5, 0.5), u_PrevMip).r; - - /* Integrate visibility */ - float maxZ = max(max(fineZ.x, fineZ.y), max(fineZ.z, fineZ.w)); - vec4 integration = (fineZ / maxZ) * visibility; - - /* Compute coarse visibility (with SIMD 'dot' intrinsic) */ - float coarseVisibility = dot(vec4(0.25), integration); - - imageStore(o_VisibilityImage, base, coarseVisibility.xxxx); -} \ No newline at end of file diff --git a/Sandbox/Resources/Shaders/PreDepth.glsl b/Sandbox/Resources/Shaders/PreDepth.glsl deleted file mode 100644 index b377bc5f..00000000 --- a/Sandbox/Resources/Shaders/PreDepth.glsl +++ /dev/null @@ -1,40 +0,0 @@ -// Pre-depth shader - -#version 450 core -#pragma stage : vert - -#include - -// Vertex buffer -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec3 a_Normal; -layout(location = 2) in vec3 a_Tangent; -layout(location = 3) in vec3 a_Binormal; -layout(location = 4) in vec2 a_TexCoord; - -layout(push_constant) uniform PushConstants -{ - uint ObjectIndexBase; - uint _pad0; - uint _pad1; - uint _pad2; -} u_PushConstants; - -// Make sure both shaders compute the exact same answer(PBR shader). -// We need to have the same exact calculations to produce the gl_Position value (eg. matrix multiplications). -precise invariant gl_Position; - -void main() -{ - mat4 transform = GetInstanceTransform(u_PushConstants.ObjectIndexBase + gl_InstanceIndex); - vec4 worldPosition = transform * vec4(a_Position, 1.0); - - gl_Position = u_Camera.ViewProjectionMatrix * worldPosition; -} - -#version 450 core -#pragma stage : frag - -void main() -{ -} diff --git a/Sandbox/Resources/Shaders/PreDepth_Anim.glsl b/Sandbox/Resources/Shaders/PreDepth_Anim.glsl deleted file mode 100644 index 8ba6be01..00000000 --- a/Sandbox/Resources/Shaders/PreDepth_Anim.glsl +++ /dev/null @@ -1,53 +0,0 @@ -// Pre-depth shader - -#version 450 core -#pragma stage : vert - -#include - -// Vertex buffer -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec3 a_Normal; -layout(location = 2) in vec3 a_Tangent; -layout(location = 3) in vec3 a_Binormal; -layout(location = 4) in vec2 a_TexCoord; - -// Bone influences -layout(location = 5) in ivec4 a_BoneIndices; -layout(location = 6) in vec4 a_BoneWeights; - -layout(push_constant) uniform PushConstants -{ - uint ObjectIndexBase; - uint _pad; - uint BoneBase; - uint BoneStride; -} u_PushConstants; - -// Make sure both shaders compute the exact same answer(PBR shader). -// We need to have the same exact calculations to produce the gl_Position value (eg. matrix multiplications). -precise invariant gl_Position; - -void main() -{ - mat4 transform = GetInstanceTransform(u_PushConstants.ObjectIndexBase + gl_InstanceIndex); - - mat4 boneTransform = r_BoneTransforms.BoneTransforms[u_PushConstants.BoneBase + (gl_InstanceIndex * u_PushConstants.BoneStride) + a_BoneIndices[0]] * a_BoneWeights[0]; - boneTransform += r_BoneTransforms.BoneTransforms[u_PushConstants.BoneBase + (gl_InstanceIndex * u_PushConstants.BoneStride) + a_BoneIndices[1]] * a_BoneWeights[1]; - boneTransform += r_BoneTransforms.BoneTransforms[u_PushConstants.BoneBase + (gl_InstanceIndex * u_PushConstants.BoneStride) + a_BoneIndices[2]] * a_BoneWeights[2]; - boneTransform += r_BoneTransforms.BoneTransforms[u_PushConstants.BoneBase + (gl_InstanceIndex * u_PushConstants.BoneStride) + a_BoneIndices[3]] * a_BoneWeights[3]; - - vec4 worldPosition = transform * boneTransform * vec4(a_Position, 1.0); - - // Near and far are flipped for better precision. - // Only change along with the PBR shader. - gl_Position = u_Camera.ViewProjectionMatrix * worldPosition; -} - -#version 450 core -#pragma stage : frag - -void main() -{ - // TODO: Check for alpha in texture -} diff --git a/Sandbox/Resources/Shaders/PreethamSky.glsl b/Sandbox/Resources/Shaders/PreethamSky.glsl deleted file mode 100644 index 2cc15da6..00000000 --- a/Sandbox/Resources/Shaders/PreethamSky.glsl +++ /dev/null @@ -1,143 +0,0 @@ -// -// Preetham Sky shader -// Heavily adapted from https://www.shadertoy.com/view/llSSDR -// - -#version 450 core -#pragma stage : comp - -const float PI = 3.141592; - -layout(binding = 0, rgba32f) restrict writeonly uniform imageCube o_CubeMap; - -layout (push_constant) uniform Uniforms -{ - vec3 TurbidityAzimuthInclination; -} u_Uniforms; - -vec3 GetCubeMapTexCoord() -{ - vec2 st = gl_GlobalInvocationID.xy / vec2(imageSize(o_CubeMap)); - vec2 uv = 2.0 * vec2(st.x, 1.0 - st.y) - vec2(1.0); - - vec3 ret; - if (gl_GlobalInvocationID.z == 0) ret = vec3( 1.0, uv.y, -uv.x); - else if (gl_GlobalInvocationID.z == 1) ret = vec3( -1.0, uv.y, uv.x); - else if (gl_GlobalInvocationID.z == 2) ret = vec3( uv.x, 1.0, -uv.y); - else if (gl_GlobalInvocationID.z == 3) ret = vec3( uv.x, -1.0, uv.y); - else if (gl_GlobalInvocationID.z == 4) ret = vec3( uv.x, uv.y, 1.0); - else if (gl_GlobalInvocationID.z == 5) ret = vec3(-uv.x, uv.y, -1.0); - return normalize(ret); -} - -#define PI 3.14159265359 - -float saturatedDot( in vec3 a, in vec3 b ) -{ - return max( dot( a, b ), 0.0 ); -} - -vec3 YxyToXYZ( in vec3 Yxy ) -{ - float Y = Yxy.r; - float x = Yxy.g; - float y = Yxy.b; - - float X = x * ( Y / y ); - float Z = ( 1.0 - x - y ) * ( Y / y ); - - return vec3(X,Y,Z); -} - -vec3 XYZToRGB( in vec3 XYZ ) -{ - // CIE/E - mat3 M = mat3 - ( - 2.3706743, -0.9000405, -0.4706338, - -0.5138850, 1.4253036, 0.0885814, - 0.0052982, -0.0146949, 1.0093968 - ); - - return XYZ * M; -} - - -vec3 YxyToRGB( in vec3 Yxy ) -{ - vec3 XYZ = YxyToXYZ( Yxy ); - vec3 RGB = XYZToRGB( XYZ ); - return RGB; -} - -void calculatePerezDistribution( in float t, out vec3 A, out vec3 B, out vec3 C, out vec3 D, out vec3 E ) -{ - A = vec3( 0.1787 * t - 1.4630, -0.0193 * t - 0.2592, -0.0167 * t - 0.2608 ); - B = vec3( -0.3554 * t + 0.4275, -0.0665 * t + 0.0008, -0.0950 * t + 0.0092 ); - C = vec3( -0.0227 * t + 5.3251, -0.0004 * t + 0.2125, -0.0079 * t + 0.2102 ); - D = vec3( 0.1206 * t - 2.5771, -0.0641 * t - 0.8989, -0.0441 * t - 1.6537 ); - E = vec3( -0.0670 * t + 0.3703, -0.0033 * t + 0.0452, -0.0109 * t + 0.0529 ); -} - -vec3 calculateZenithLuminanceYxy( in float t, in float thetaS ) -{ - float chi = ( 4.0 / 9.0 - t / 120.0 ) * ( PI - 2.0 * thetaS ); - float Yz = ( 4.0453 * t - 4.9710 ) * tan( chi ) - 0.2155 * t + 2.4192; - - float theta2 = thetaS * thetaS; - float theta3 = theta2 * thetaS; - float T = t; - float T2 = t * t; - - float xz = - ( 0.00165 * theta3 - 0.00375 * theta2 + 0.00209 * thetaS + 0.0) * T2 + - (-0.02903 * theta3 + 0.06377 * theta2 - 0.03202 * thetaS + 0.00394) * T + - ( 0.11693 * theta3 - 0.21196 * theta2 + 0.06052 * thetaS + 0.25886); - - float yz = - ( 0.00275 * theta3 - 0.00610 * theta2 + 0.00317 * thetaS + 0.0) * T2 + - (-0.04214 * theta3 + 0.08970 * theta2 - 0.04153 * thetaS + 0.00516) * T + - ( 0.15346 * theta3 - 0.26756 * theta2 + 0.06670 * thetaS + 0.26688); - - return vec3( Yz, xz, yz ); -} - -vec3 calculatePerezLuminanceYxy( in float theta, in float gamma, in vec3 A, in vec3 B, in vec3 C, in vec3 D, in vec3 E ) -{ - return ( 1.0 + A * exp( B / cos( theta ) ) ) * ( 1.0 + C * exp( D * gamma ) + E * cos( gamma ) * cos( gamma ) ); -} - -vec3 calculateSkyLuminanceRGB( in vec3 s, in vec3 e, in float t ) -{ - vec3 A, B, C, D, E; - calculatePerezDistribution( t, A, B, C, D, E ); - - float thetaS = acos( saturatedDot( s, vec3(0,1,0) ) ); - float thetaE = acos( saturatedDot( e, vec3(0,1,0) ) ); - float gammaE = acos( saturatedDot( s, e ) ); - - vec3 Yz = calculateZenithLuminanceYxy( t, thetaS ); - - vec3 fThetaGamma = calculatePerezLuminanceYxy( thetaE, gammaE, A, B, C, D, E ); - vec3 fZeroThetaS = calculatePerezLuminanceYxy( 0.0, thetaS, A, B, C, D, E ); - - vec3 Yp = Yz * ( fThetaGamma / fZeroThetaS ); - - return YxyToRGB( Yp ); -} - -layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in; -void main() -{ - vec3 cubeTC = GetCubeMapTexCoord(); - - float turbidity = u_Uniforms.TurbidityAzimuthInclination.x; - float azimuth = u_Uniforms.TurbidityAzimuthInclination.y;; - float inclination = u_Uniforms.TurbidityAzimuthInclination.z; - vec3 sunDir = normalize( vec3( sin(inclination) * cos(azimuth), cos(inclination), sin(inclination) * sin(azimuth) ) ); - vec3 viewDir = cubeTC; - vec3 skyLuminance = calculateSkyLuminanceRGB( sunDir, viewDir, turbidity ); - - vec4 color = vec4(skyLuminance * 0.05, 1.0); - imageStore(o_CubeMap, ivec3(gl_GlobalInvocationID), color); -} diff --git a/Sandbox/Resources/Shaders/Renderer2D.glsl b/Sandbox/Resources/Shaders/Renderer2D.glsl deleted file mode 100644 index af739dcd..00000000 --- a/Sandbox/Resources/Shaders/Renderer2D.glsl +++ /dev/null @@ -1,66 +0,0 @@ -// Basic Texture Shader - -#version 450 core -#pragma stage : vert - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 2) in vec2 a_TexCoord; -layout(location = 3) in float a_TexIndex; -layout(location = 4) in float a_TilingFactor; - -layout (std140, set = 1, binding = 0) uniform Camera -{ - mat4 u_ViewProjection; -}; - -layout (push_constant) uniform Transform -{ - mat4 Transform; -} u_Renderer; - -struct VertexOutput -{ - vec4 Color; - vec2 TexCoord; - float TilingFactor; -}; - -layout (location = 0) out VertexOutput Output; -layout (location = 5) out flat float TexIndex; - -void main() -{ - Output.Color = a_Color; - Output.TexCoord = a_TexCoord; - TexIndex = a_TexIndex; - Output.TilingFactor = a_TilingFactor; - gl_Position = u_ViewProjection * u_Renderer.Transform * vec4(a_Position, 1.0); -} - -#version 450 core -#pragma stage : frag - -#include - -layout(location = 0) out vec4 color; - -struct VertexOutput -{ - vec4 Color; - vec2 TexCoord; - float TilingFactor; -}; - -layout (location = 0) in VertexOutput Input; -layout (location = 5) in flat float TexIndex; - -layout (set = 0, binding = 0) uniform texture2D u_Textures[32]; - -void main() -{ - color = SampleDefault(u_Textures[int(TexIndex)], Input.TexCoord * Input.TilingFactor) * Input.Color; - // Discard to avoid depth write - if (color.a == 0.0) - discard; -} \ No newline at end of file diff --git a/Sandbox/Resources/Shaders/Renderer2D_Circle.glsl b/Sandbox/Resources/Shaders/Renderer2D_Circle.glsl deleted file mode 100644 index 37a9162a..00000000 --- a/Sandbox/Resources/Shaders/Renderer2D_Circle.glsl +++ /dev/null @@ -1,63 +0,0 @@ -// Basic Texture Shader - -#version 430 core -#pragma stage : vert - -layout(location = 0) in vec3 a_WorldPosition; -layout(location = 1) in float a_Thickness; -layout(location = 2) in vec2 a_LocalPosition; -layout(location = 3) in vec4 a_Color; - -layout (std140, set = 1, binding = 0) uniform Camera -{ - mat4 u_ViewProjection; -}; - -layout (push_constant) uniform Transform -{ - mat4 Transform; -} u_Renderer; - -struct VertexOutput -{ - vec2 LocalPosition; - float Thickness; - vec4 Color; -}; - -layout (location = 0) out VertexOutput Output; - -void main() -{ - Output.LocalPosition = a_LocalPosition; - Output.Thickness = a_Thickness; - Output.Color = a_Color; - gl_Position = u_ViewProjection * u_Renderer.Transform * vec4(a_WorldPosition, 1.0); -} - -#version 430 core -#pragma stage : frag - -layout(location = 0) out vec4 color; - -struct VertexOutput -{ - vec2 LocalPosition; - float Thickness; - vec4 Color; -}; - -layout (location = 0) in VertexOutput Input; - -void main() -{ - float fade = 0.01; - float dist = sqrt(dot(Input.LocalPosition, Input.LocalPosition)); - if (dist > 1.0 || dist < 1.0 - Input.Thickness - fade) - discard; - - float alpha = 1.0 - smoothstep(1.0f - fade, 1.0f, dist); - alpha *= smoothstep(1.0 - Input.Thickness - fade, 1.0 - Input.Thickness, dist); - color = Input.Color; - color.a = alpha; -} \ No newline at end of file diff --git a/Sandbox/Resources/Shaders/Renderer2D_Line.glsl b/Sandbox/Resources/Shaders/Renderer2D_Line.glsl deleted file mode 100644 index c56d960c..00000000 --- a/Sandbox/Resources/Shaders/Renderer2D_Line.glsl +++ /dev/null @@ -1,37 +0,0 @@ -// Basic Texture Shader - -#version 450 core -#pragma stage : vert - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; - -layout (std140, set = 1, binding = 0) uniform Camera -{ - mat4 u_ViewProjection; -}; - -layout (push_constant) uniform Transform -{ - mat4 Transform; -} u_Renderer; - -layout (location = 0) out vec4 v_Color; - -void main() -{ - v_Color = a_Color; - gl_Position = u_ViewProjection * u_Renderer.Transform * vec4(a_Position, 1.0); -} - -#version 450 core -#pragma stage : frag - -layout(location = 0) out vec4 color; - -layout (location = 0) in vec4 v_Color; - -void main() -{ - color = v_Color; -} \ No newline at end of file diff --git a/Sandbox/Resources/Shaders/Renderer2D_Text.glsl b/Sandbox/Resources/Shaders/Renderer2D_Text.glsl deleted file mode 100644 index 48d965ec..00000000 --- a/Sandbox/Resources/Shaders/Renderer2D_Text.glsl +++ /dev/null @@ -1,90 +0,0 @@ -// Basic Texture Shader - -#version 450 core -#pragma stage : vert - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 2) in vec2 a_TexCoord; -layout(location = 3) in float a_TexIndex; - -layout (std140, set = 1, binding = 0) uniform Camera -{ - mat4 u_ViewProjection; -}; - -layout (push_constant) uniform Transform -{ - mat4 Transform; -} u_Renderer; - -struct VertexOutput -{ - vec4 Color; - vec2 TexCoord; -}; - -layout (location = 0) out VertexOutput Output; -layout (location = 5) out flat float TexIndex; - -void main() -{ - Output.Color = a_Color; - Output.TexCoord = a_TexCoord; - TexIndex = a_TexIndex; - gl_Position = u_ViewProjection * u_Renderer.Transform * vec4(a_Position, 1.0); -} - -#version 450 core -#pragma stage : frag - -#include - -layout(location = 0) out vec4 color; - -struct VertexOutput -{ - vec4 Color; - vec2 TexCoord; -}; - -layout (location = 0) in VertexOutput Input; -layout (location = 5) in flat float TexIndex; - -layout (set = 0, binding = 0) uniform texture2D u_FontAtlases[32]; - -float median(float r, float g, float b) -{ - return max(min(r, g), min(max(r, g), b)); -} - -/* For 2D -float ScreenPxRange() -{ - float pixRange = 2.0f; - float geoSize = 72.0f; - return geoSize / 32.0f * pixRange; -} -*/ - -float ScreenPxRange() -{ - float pxRange = 2.0f; - vec2 unitRange = vec2(pxRange)/vec2(textureSize(sampler2D(u_FontAtlases[int(TexIndex)], r_DefaultSampler), 0)); - vec2 screenTexSize = vec2(1.0)/fwidth(Input.TexCoord); - return max(0.5*dot(unitRange, screenTexSize), 1.0); -} - -void main() -{ - vec4 bgColor = vec4(Input.Color.rgb, 0.0); // TODO(Yan): outlines - vec4 fgColor = Input.Color; - - // NOTE(Yan): MSDF texture has no mips (only LOD 0), but in the future it might - // be nice to do some sort of fading/smoothing when camera is far - vec3 msd = SampleDefault(u_FontAtlases[int(TexIndex)], Input.TexCoord).rgb; - float sd = median(msd.r, msd.g, msd.b); - float screenPxDistance = ScreenPxRange() * (sd - 0.5f); - float opacity = clamp(screenPxDistance + 0.5, 0.0, 1.0); - color = mix(bgColor, fgColor, opacity); -} \ No newline at end of file diff --git a/Sandbox/Resources/Shaders/SelectedGeometry.glsl b/Sandbox/Resources/Shaders/SelectedGeometry.glsl deleted file mode 100644 index a3bc28d0..00000000 --- a/Sandbox/Resources/Shaders/SelectedGeometry.glsl +++ /dev/null @@ -1,35 +0,0 @@ -#version 450 core -#pragma stage : vert - -#include - -// Vertex buffer -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec3 a_Normal; -layout(location = 2) in vec3 a_Tangent; -layout(location = 3) in vec3 a_Binormal; -layout(location = 4) in vec2 a_TexCoord; - -layout(push_constant) uniform PushConstants -{ - uint ObjectIndexBase; - uint _pad0; - uint _pad1; - uint _pad2; -} u_PushConstants; - -void main() -{ - mat4 transform = GetInstanceTransform(u_PushConstants.ObjectIndexBase + gl_InstanceIndex); - gl_Position = u_Camera.ViewProjectionMatrix * transform * vec4(a_Position, 1.0); -} - -#version 450 core -#pragma stage : frag - -layout(location = 0) out vec4 o_Color; - -void main() -{ - o_Color = vec4(1.0f); -} diff --git a/Sandbox/Resources/Shaders/SelectedGeometry_Anim.glsl b/Sandbox/Resources/Shaders/SelectedGeometry_Anim.glsl deleted file mode 100644 index 782bbb69..00000000 --- a/Sandbox/Resources/Shaders/SelectedGeometry_Anim.glsl +++ /dev/null @@ -1,45 +0,0 @@ -#version 450 core -#pragma stage : vert - -#include - -// Vertex buffer -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec3 a_Normal; -layout(location = 2) in vec3 a_Tangent; -layout(location = 3) in vec3 a_Binormal; -layout(location = 4) in vec2 a_TexCoord; - -// Bone influences -layout(location = 5) in ivec4 a_BoneIndices; -layout(location = 6) in vec4 a_BoneWeights; - -layout(push_constant) uniform PushConstants -{ - uint ObjectIndexBase; - uint _pad; - uint BoneBase; - uint BoneStride; -} u_PushConstants; - -void main() -{ - mat4 transform = GetInstanceTransform(u_PushConstants.ObjectIndexBase + gl_InstanceIndex); - - mat4 boneTransform = r_BoneTransforms.BoneTransforms[u_PushConstants.BoneBase + (gl_InstanceIndex * u_PushConstants.BoneStride) + a_BoneIndices[0]] * a_BoneWeights[0]; - boneTransform += r_BoneTransforms.BoneTransforms[u_PushConstants.BoneBase + (gl_InstanceIndex * u_PushConstants.BoneStride) + a_BoneIndices[1]] * a_BoneWeights[1]; - boneTransform += r_BoneTransforms.BoneTransforms[u_PushConstants.BoneBase + (gl_InstanceIndex * u_PushConstants.BoneStride) + a_BoneIndices[2]] * a_BoneWeights[2]; - boneTransform += r_BoneTransforms.BoneTransforms[u_PushConstants.BoneBase + (gl_InstanceIndex * u_PushConstants.BoneStride) + a_BoneIndices[3]] * a_BoneWeights[3]; - - gl_Position = u_Camera.ViewProjectionMatrix * transform * boneTransform * vec4(a_Position, 1.0); -} - -#version 450 core -#pragma stage : frag - -layout(location = 0) out vec4 o_Color; - -void main() -{ - o_Color = vec4(1.0f); -} diff --git a/Sandbox/Resources/Shaders/Skybox.glsl b/Sandbox/Resources/Shaders/Skybox.glsl deleted file mode 100644 index 14430d71..00000000 --- a/Sandbox/Resources/Shaders/Skybox.glsl +++ /dev/null @@ -1,42 +0,0 @@ -// Skybox shader - -#version 450 core -#pragma stage : vert -#include - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec2 a_TexCoord; - -layout(location = 0) out vec3 v_Position; - -void main() -{ - vec4 position = vec4(a_Position.xy, 0.0, 1.0); - gl_Position = position; - - v_Position = (u_Camera.InverseViewProjectionMatrix * position).xyz; -} - -#version 450 core -#pragma stage : frag - -#include - -layout(location = 0) out vec4 finalColor; - -layout (set = 0, binding = 1) uniform textureCube u_Texture; - -layout (push_constant) uniform Uniforms -{ - float TextureLod; - float Intensity; -} u_Uniforms; - -layout (location = 0) in vec3 v_Position; - -void main() -{ - vec3 sampleDirection = vec3(v_Position.x, -v_Position.y, v_Position.z); - finalColor = SampleLinearLOD(u_Texture, sampleDirection, u_Uniforms.TextureLod) * u_Uniforms.Intensity; - finalColor.a = 1.0f; -} diff --git a/Sandbox/Resources/Shaders/SpotShadowMap.glsl b/Sandbox/Resources/Shaders/SpotShadowMap.glsl deleted file mode 100644 index 51cd4331..00000000 --- a/Sandbox/Resources/Shaders/SpotShadowMap.glsl +++ /dev/null @@ -1,34 +0,0 @@ -// Spot Shadow Map shader - -#version 450 core -#pragma stage : vert - -#include - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec3 a_Normal; -layout(location = 2) in vec3 a_Tangent; -layout(location = 3) in vec3 a_Binormal; -layout(location = 4) in vec2 a_TexCoord; - -layout(push_constant) uniform PushConstants -{ - uint ObjectIndexBase; - int LightIndex; - uint _pad0; - uint _pad1; -} u_Renderer; - -void main() -{ - mat4 transform = GetInstanceTransform(u_Renderer.ObjectIndexBase + gl_InstanceIndex); - gl_Position = u_SpotLightMatrices.Mats[u_Renderer.LightIndex] * transform * vec4(a_Position, 1.0); -} - -#version 450 core -#pragma stage : frag - -void main() -{ - // TODO: Check for alpha in texture -} diff --git a/Sandbox/Resources/Shaders/SpotShadowMap_Anim.glsl b/Sandbox/Resources/Shaders/SpotShadowMap_Anim.glsl deleted file mode 100644 index dbfde8d2..00000000 --- a/Sandbox/Resources/Shaders/SpotShadowMap_Anim.glsl +++ /dev/null @@ -1,44 +0,0 @@ -// Spot Shadow Map shader - -#version 450 core -#pragma stage : vert - -#include - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec3 a_Normal; -layout(location = 2) in vec3 a_Tangent; -layout(location = 3) in vec3 a_Binormal; -layout(location = 4) in vec2 a_TexCoord; - -// Bone influences -layout(location = 5) in ivec4 a_BoneIndices; -layout(location = 6) in vec4 a_BoneWeights; - -layout(push_constant) uniform PushConstants -{ - uint ObjectIndexBase; - uint LightIndex; - uint BoneTransformBaseIndex; - uint BoneTransformStride; -} u_PushConstants; - -void main() -{ - mat4 transform = GetInstanceTransform(u_PushConstants.ObjectIndexBase + gl_InstanceIndex); - - mat4 boneTransform = r_BoneTransforms.BoneTransforms[u_PushConstants.BoneTransformBaseIndex + (gl_InstanceIndex * u_PushConstants.BoneTransformStride) + a_BoneIndices[0]] * a_BoneWeights[0]; - boneTransform += r_BoneTransforms.BoneTransforms[u_PushConstants.BoneTransformBaseIndex + (gl_InstanceIndex * u_PushConstants.BoneTransformStride) + a_BoneIndices[1]] * a_BoneWeights[1]; - boneTransform += r_BoneTransforms.BoneTransforms[u_PushConstants.BoneTransformBaseIndex + (gl_InstanceIndex * u_PushConstants.BoneTransformStride) + a_BoneIndices[2]] * a_BoneWeights[2]; - boneTransform += r_BoneTransforms.BoneTransforms[u_PushConstants.BoneTransformBaseIndex + (gl_InstanceIndex * u_PushConstants.BoneTransformStride) + a_BoneIndices[3]] * a_BoneWeights[3]; - - gl_Position = u_SpotLightMatrices.Mats[u_PushConstants.LightIndex] * transform * boneTransform * vec4(a_Position, 1.0); -} - -#version 450 core -#pragma stage : frag - -void main() -{ - // TODO: Check for alpha in texture -} diff --git a/Sandbox/Resources/Shaders/TexturePass.glsl b/Sandbox/Resources/Shaders/TexturePass.glsl deleted file mode 100644 index a78a90e5..00000000 --- a/Sandbox/Resources/Shaders/TexturePass.glsl +++ /dev/null @@ -1,37 +0,0 @@ -#version 450 core -#pragma stage : vert -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec2 a_TexCoord; - -struct OutputBlock -{ - vec2 TexCoord; -}; - -layout (location = 0) out OutputBlock Output; - -void main() -{ - vec4 position = vec4(a_Position.xy, 0.0, 1.0); - Output.TexCoord = a_TexCoord; - gl_Position = position; -} - -#version 450 core -#pragma stage : frag - -layout(location = 0) out vec4 o_Color; - -struct OutputBlock -{ - vec2 TexCoord; -}; - -layout (location = 0) in OutputBlock Input; - -layout (binding = 0) uniform sampler2D u_Texture; - -void main() -{ - o_Color = texture(u_Texture, Input.TexCoord); -} diff --git a/Sandbox/Resources/Shaders/Wireframe.glsl b/Sandbox/Resources/Shaders/Wireframe.glsl deleted file mode 100644 index 690b62a4..00000000 --- a/Sandbox/Resources/Shaders/Wireframe.glsl +++ /dev/null @@ -1,50 +0,0 @@ -// Outline Shader - -#version 450 core -#pragma stage : vert -#include - -layout(location = 0) in vec3 a_Position; - -////////////////////////////////////////// -// UNUSED -////////////////////////////////////////// -layout(location = 1) in vec3 a_Normal; -layout(location = 2) in vec3 a_Tangent; -layout(location = 3) in vec3 a_Binormal; -layout(location = 4) in vec2 a_TexCoord; -////////////////////////////////////////// - -layout(push_constant) uniform PushConstants -{ - uint ObjectIndexBase; - uint _pad0; - uint _pad1; - uint _pad2; - vec4 Color; -} u_MaterialUniforms; - -void main() -{ - mat4 transform = GetInstanceTransform(u_MaterialUniforms.ObjectIndexBase + gl_InstanceIndex); - gl_Position = u_Camera.ViewProjectionMatrix * transform * vec4(a_Position, 1.0); -} - -#version 450 core -#pragma stage : frag - -layout(location = 0) out vec4 color; - -layout(push_constant) uniform PushConstants -{ - uint ObjectIndexBase; - uint _pad0; - uint _pad1; - uint _pad2; - vec4 Color; -} u_MaterialUniforms; - -void main() -{ - color = u_MaterialUniforms.Color; -} diff --git a/Sandbox/Resources/Shaders/Wireframe_Anim.glsl b/Sandbox/Resources/Shaders/Wireframe_Anim.glsl deleted file mode 100644 index bc078468..00000000 --- a/Sandbox/Resources/Shaders/Wireframe_Anim.glsl +++ /dev/null @@ -1,66 +0,0 @@ -// Outline Shader - -#version 450 core -#pragma stage : vert -#include - -layout(location = 0) in vec3 a_Position; - -////////////////////////////////////////// -// UNUSED -////////////////////////////////////////// -layout(location = 1) in vec3 a_Normal; -layout(location = 2) in vec3 a_Tangent; -layout(location = 3) in vec3 a_Binormal; -layout(location = 4) in vec2 a_TexCoord; -////////////////////////////////////////// - -// Bone influences -layout(location = 5) in ivec4 a_BoneIndices; -layout(location = 6) in vec4 a_BoneWeights; - -layout(push_constant) uniform PushConstants -{ - // Vertex shader - uint ObjectIndexBase; - uint _pad; - uint BoneBase; - uint BoneStride; - - // Fragment shader - vec4 Color; -} u_MaterialUniforms; - -void main() -{ - mat4 transform = GetInstanceTransform(u_MaterialUniforms.ObjectIndexBase + gl_InstanceIndex); - - mat4 boneTransform = r_BoneTransforms.BoneTransforms[u_MaterialUniforms.BoneBase + (gl_InstanceIndex * u_MaterialUniforms.BoneStride) + a_BoneIndices[0]] * a_BoneWeights[0]; - boneTransform += r_BoneTransforms.BoneTransforms[u_MaterialUniforms.BoneBase + (gl_InstanceIndex * u_MaterialUniforms.BoneStride) + a_BoneIndices[1]] * a_BoneWeights[1]; - boneTransform += r_BoneTransforms.BoneTransforms[u_MaterialUniforms.BoneBase + (gl_InstanceIndex * u_MaterialUniforms.BoneStride) + a_BoneIndices[2]] * a_BoneWeights[2]; - boneTransform += r_BoneTransforms.BoneTransforms[u_MaterialUniforms.BoneBase + (gl_InstanceIndex * u_MaterialUniforms.BoneStride) + a_BoneIndices[3]] * a_BoneWeights[3]; - - gl_Position = u_Camera.ViewProjectionMatrix * transform * boneTransform * vec4(a_Position, 1.0); -} - -#version 450 core -#pragma stage : frag - -layout(location = 0) out vec4 color; - -layout(push_constant) uniform PushConstants -{ - // Vertex shader - uint ObjectIndexBase; - uint BoneBase; - uint BoneStride; - uint _pad; - - // Fragment shader - vec4 Color; -} u_MaterialUniforms; - -void main() -{ - color = u_MaterialUniforms.Color; -} diff --git a/Sandbox/Resources/Shaders/shader.glsl b/Sandbox/Resources/Shaders/shader.glsl deleted file mode 100644 index bec93c2e..00000000 --- a/Sandbox/Resources/Shaders/shader.glsl +++ /dev/null @@ -1,35 +0,0 @@ -#version 430 -#pragma stage : vert - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec3 a_Normal; -layout(location = 2) in vec3 a_Tangent; -layout(location = 3) in vec3 a_Bitangent; -layout(location = 4) in vec2 a_TexCoord; - -uniform mat4 u_MVP; - -out vec3 v_Normal; - -void main() -{ - gl_Position = u_MVP * vec4(a_Position, 1.0); - v_Normal = a_Normal; -} - -#version 430 -#pragma stage : frag - -layout(location = 0) out vec4 finalColor; - -uniform vec4 u_Color; - -in vec3 v_Normal; - -void main() -{ - finalColor = vec4(0.8, 0.0, 0.8, 1.0); - - - finalColor = vec4((v_Normal * 0.5 + 0.5), 1.0);// * u_Color.xyz, 1.0); -} \ No newline at end of file diff --git a/Sandbox/Resources/Textures/ErrorTexture.png b/Sandbox/Resources/Textures/ErrorTexture.png deleted file mode 100644 index 89d0b29c..00000000 Binary files a/Sandbox/Resources/Textures/ErrorTexture.png and /dev/null differ diff --git a/Sandbox/Source/Sandbox2D.cpp b/Sandbox/Source/Sandbox2D.cpp deleted file mode 100644 index 59b90fc2..00000000 --- a/Sandbox/Source/Sandbox2D.cpp +++ /dev/null @@ -1,500 +0,0 @@ -#include "Sandbox2D.h" - -#include -#include - -#include -#include - -#include "Lux/Core/Application.h" -#include "Lux/Core/Input.h" -#include "Lux/Core/Window.h" -#include "Lux/Debug/Profiler.h" -#include "Lux/Renderer/Framebuffer.h" -#include "Lux/Renderer/Renderer.h" -#include "Lux/Renderer/Renderer2D.h" -#include "Lux/Renderer/RendererTypes.h" -#include "Lux/Renderer/UI/Font.h" - -#include - -// --------------------------------------------------------------------------- -// Constructor -// --------------------------------------------------------------------------- - -Sandbox2D::Sandbox2D() - : Layer("Sandbox2D") - , m_EditorCamera(60.0f, 1600.0f, 900.0f, 0.1f, 1000.0f) - , m_SquareColor({ 0.2f, 0.3f, 0.8f, 1.0f }) -{ -} - -// --------------------------------------------------------------------------- -// OnAttach -// --------------------------------------------------------------------------- - -void Sandbox2D::OnAttach() -{ - LUX_PROFILE_FUNCTION("Sandbox2D::OnAttach"); - - Lux::TextureSpecification checkerboardSpec; - checkerboardSpec.Format = Lux::ImageFormat::SRGBA; - checkerboardSpec.GenerateMips = false; - checkerboardSpec.DebugName = "assets/textures/Checkerboard.png"; - m_CheckerboardTexture = Lux::Texture2D::Create(checkerboardSpec, "assets/textures/Checkerboard.png"); - - // ------------------------------------------------------------------ - // Renderer2D - // Renderer2D is self-contained: it creates its own RenderCommandBuffer, - // internal framebuffer, and RenderPasses (quad/line/text) inside Init(). - // ------------------------------------------------------------------ - m_Renderer2D = Lux::Ref::Create(); - m_Renderer2D->SetLineWidth(2.0f); - - // Camera must be explicitly activated or OnUpdate returns immediately. - m_EditorCamera.SetActive(true); - - // ------------------------------------------------------------------ - // Offscreen Framebuffer - // We create our own framebuffer and hand it to Renderer2D via - // SetTargetFramebuffer(). This rebuilds all internal pipelines to - // target our FB, so draws go into it instead of the default one. - // The colour attachment (index 0) is then shown in the ImGui viewport. - // ------------------------------------------------------------------ - Lux::FramebufferSpecification fbSpec; - fbSpec.Attachments = { Lux::ImageFormat::RGBA32F, Lux::ImageFormat::Depth }; - fbSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f }; - fbSpec.ClearColorOnLoad = true; - fbSpec.ClearDepthOnLoad = true; - fbSpec.DebugName = "Sandbox2D-Viewport"; - m_Framebuffer = Lux::Framebuffer::Create(fbSpec); - - // Point Renderer2D at our framebuffer. Internally this calls - // Pipeline::Create for quad/line/text with TargetFramebuffer = m_Framebuffer. - m_Renderer2D->SetTargetFramebuffer(m_Framebuffer); -} - -// --------------------------------------------------------------------------- -// OnDetach -// --------------------------------------------------------------------------- - -void Sandbox2D::OnDetach() -{ - LUX_PROFILE_FUNCTION("Sandbox2D::OnDetach"); -} - -// --------------------------------------------------------------------------- -// OnUpdate -// -// Frame structure: -// 1. Throttled FPS + perf timers -// 2. Viewport resize detection → resize framebuffer + camera -// 3. Camera update -// 4. Scene pass: BeginScene(editorCam VP+V) → draws → EndScene -// 5. Overlay pass: BeginScene(orthoProj, I) → text → EndScene -// (both passes submit their own command buffers internally) -// 6. Post-update deferred queue -// --------------------------------------------------------------------------- - -void Sandbox2D::OnUpdate(Lux::Timestep ts) -{ - LUX_PROFILE_FUNCTION("Sandbox2D::OnUpdate"); - - // ------------------------------------------------------------------ - // 1. Throttled stat updates - // ------------------------------------------------------------------ - - m_UpdateFPSTimer -= ts; - if (m_UpdateFPSTimer <= 0.0f) - { - UpdateFPSStat(); - m_UpdateFPSTimer = 1.0f; - } - - m_UpdatePerfTimer -= ts; - if (m_UpdatePerfTimer <= 0.0f) - { - UpdatePerformanceTimers(); - m_UpdatePerfTimer = 0.2f; - } - - // ------------------------------------------------------------------ - // 2. Viewport resize detection - // m_ViewportSize is written by OnImGuiRender the previous frame. - // When it differs from our tracked size, resize the framebuffer and - // update the camera aspect ratio. - // ------------------------------------------------------------------ - - if (m_ViewportSize.x > 0.0f && m_ViewportSize.y > 0.0f) - { - const uint32_t vpW = static_cast(m_ViewportSize.x); - const uint32_t vpH = static_cast(m_ViewportSize.y); - - if (vpW != m_Width || vpH != m_Height) - OnViewportResize(vpW, vpH); - } - - // Screen-space ortho projection for the debug overlay. - // Y=0 at top, Y=height at bottom - matches Vulkan clip-space where Y increases downward. - // Without this flip the font atlas UV coords render the glyphs upside down. - m_Renderer2DProj = glm::ortho(0.0f, m_ViewportSize.x, m_ViewportSize.y, 0.0f); - - // ------------------------------------------------------------------ - // 3. Camera - // ------------------------------------------------------------------ - - m_EditorCamera.OnUpdate(ts); - - // ------------------------------------------------------------------ - // 4. Scene geometry pass - // BeginScene uploads the camera UBO and resets all vertex buffer ptrs. - // EndScene flushes all batches: for each batch it calls - // Renderer::BeginRenderPass / RenderGeometry / EndRenderPass - // and submits its own internal RenderCommandBuffer. - // ------------------------------------------------------------------ - - m_Renderer2D->ResetStats(); - - { - // Accumulate in degrees, convert to radians for glm::rotate. - // 50 deg/s is a gentle, visible spin. The old ts * 50.0f was - // 50 rad/s (~8 full rotations per second) which looked insane. - static float rotation = 0.0f; - rotation += ts * 50.0f; // degrees per second - - LUX_PROFILE_SCOPE("Renderer Draw"); - - Lux::Ref bgTexture = - m_CheckerboardTexture ? m_CheckerboardTexture : Lux::Renderer::GetWhiteTexture(); - - m_Renderer2D->BeginScene(m_EditorCamera.GetViewProjection(), - m_EditorCamera.GetViewMatrix()); - - // Background at z=-0.1 so it is always behind the rotating quad. - // Pass uv1={10,10} so the texture coordinates actually span 0→10 - // across the quad, giving the repeating tile effect. The tilingFactor - // argument alone doesn't scale UVs - the shader uses it as a multiplier - // only when the vertex UVs cover the full 0→1 range first. - m_Renderer2D->DrawQuad({ 0.0f, 0.0f, -0.1f }, { 20.0f, 20.0f }, bgTexture, - 1.0f, glm::vec4(1.0f), glm::vec2(0.0f), glm::vec2(10.0f)); - - // Rotating quad at z=0, clearly in front of the background. - m_Renderer2D->DrawRotatedQuad({ 1.0f, 0.0f, 0.0f }, { 0.8f, 0.8f }, - glm::radians(rotation), - { 0.8f, 0.2f, 0.3f, 1.0f }); - - m_Renderer2D->EndScene(); - } - - // ------------------------------------------------------------------ - // 5. 2D overlay pass (debug/FPS text, screen-space, no depth test) - // ------------------------------------------------------------------ - - OnRender2D(); - - // ------------------------------------------------------------------ - // 6. Post-update deferred queue (e.g. VSync toggle) - // ------------------------------------------------------------------ - - auto queue = m_PostSceneUpdateQueue; - m_PostSceneUpdateQueue.clear(); - for (auto& fn : queue) - fn(); -} - -// --------------------------------------------------------------------------- -// OnRender2D -// -// Second BeginScene/EndScene using a screen-space ortho projection so all -// text draws land in pixel coordinates on top of the scene, still inside -// m_Framebuffer (Renderer2D targets the same framebuffer for both passes). -// depthTest = false so text isn't occluded by scene geometry depth. -// --------------------------------------------------------------------------- - -void Sandbox2D::OnRender2D() -{ - if (!m_ShowDebugDisplay) - return; - - m_Renderer2D->BeginScene(m_Renderer2DProj, - glm::mat4(1.0f), // identity view = screen-space - false); // depthTest off - - DrawFPSStats(); - DrawDebugStats(); - - m_Renderer2D->EndScene(); -} - -// --------------------------------------------------------------------------- -// OnViewportResize -// -// Resizes m_Framebuffer to match the new ImGui viewport panel dimensions. -// The Framebuffer::Resize call recreates all attachment images at the new -// size via RT_Invalidate. The Renderer2D pipelines hold a Ref to the same -// Framebuffer object, so they automatically use the new images next frame. -// --------------------------------------------------------------------------- - -void Sandbox2D::OnViewportResize(uint32_t width, uint32_t height) -{ - m_Width = width; - m_Height = height; - - m_Framebuffer->Resize(width, height); - - // SetViewportBounds already handles the projection matrix update internally: - // when (right-left) or (bottom-top) differs from the previous size it calls - // SetPerspectiveProjectionMatrix, so this is the only call needed. - m_EditorCamera.SetViewportBounds(0, 0, width, height); -} - -// --------------------------------------------------------------------------- -// DrawFPSStats - anchored to bottom-right corner -// --------------------------------------------------------------------------- - -void Sandbox2D::DrawFPSStats() -{ - const float fontSize = 18.0f; - const float margin = 10.0f; - - glm::vec2 pos = { - m_ViewportSize.x - 200.0f - margin, - margin - }; - - DrawString(std::format("{} fps", m_FramesPerSecond), pos, { 0.0f, 1.0f, 0.0f, 1.0f }, fontSize); - pos.y += fontSize; - DrawString(std::format("{:.2f} ms frame", m_FrameTime), pos, { 0.0f, 1.0f, 0.0f, 1.0f }, fontSize); - pos.y += fontSize; - DrawString(std::format("{:.2f} ms CPU", m_CPUTime), pos, { 0.0f, 1.0f, 0.0f, 1.0f }, fontSize); - pos.y += fontSize; - DrawString(std::format("{:.2f} ms GPU", m_GPUTime), pos, { 0.0f, 1.0f, 0.0f, 1.0f }, fontSize); -} - -// --------------------------------------------------------------------------- -// DrawDebugStats - anchored to top-left corner -// --------------------------------------------------------------------------- - -void Sandbox2D::DrawDebugStats() -{ - const float fontSize = 25.0f; - glm::vec2 pos = { 20.0f, m_ViewportSize.y - 50.0f }; - - DrawString(std::format("{:.2f} ms frame", m_FrameTime), pos, glm::vec4(1.0f), fontSize); - pos.y -= fontSize; - DrawString(std::format("{:.2f} ms CPU", m_CPUTime), pos, glm::vec4(1.0f), fontSize); - pos.y -= fontSize; - DrawString(std::format("{:.2f} ms GPU", m_GPUTime), pos, glm::vec4(1.0f), fontSize); - pos.y -= fontSize; - DrawString(std::format("{} fps", m_FramesPerSecond), pos, glm::vec4(1.0f), fontSize); -} - -// --------------------------------------------------------------------------- -// DrawString -// --------------------------------------------------------------------------- - -void Sandbox2D::DrawString(const std::string& string, - const glm::vec2& position, - const glm::vec4& color, - float size, - bool shadow) -{ - glm::mat4 scale = glm::scale(glm::mat4(1.0f), glm::vec3(size)); - - if (shadow) - { - const float offset = 1.0f; - glm::mat4 shadowTransform = glm::translate(glm::mat4(1.0f), - { position.x + offset, position.y - offset, -0.20f }) * scale; - - m_Renderer2D->DrawString(string, Lux::Font::GetDefaultMonoSpacedFont(), - shadowTransform, 1000.0f, { 0.0f, 0.0f, 0.0f, 1.0f }); - } - - glm::mat4 transform = glm::translate(glm::mat4(1.0f), - { position.x, position.y, -0.21f }) * scale; - - m_Renderer2D->DrawString(string, Lux::Font::GetDefaultMonoSpacedFont(), - transform, 1000.0f, color); -} - -// --------------------------------------------------------------------------- -// UpdateFPSStat -// --------------------------------------------------------------------------- - -void Sandbox2D::UpdateFPSStat() -{ - m_FramesPerSecond = static_cast(1.0f / (float)Lux::Application::Get().GetFrametime()); -} - -// --------------------------------------------------------------------------- -// UpdatePerformanceTimers -// --------------------------------------------------------------------------- - -void Sandbox2D::UpdatePerformanceTimers() -{ - auto& app = Lux::Application::Get(); - m_FrameTime = (float)app.GetFrametime().GetMilliseconds(); - - // MainThreadWorkTime is the CPU time actually measured in Application::Run(). - // RenderThreadGPUWaitTime exists in the struct but is never populated by the - // engine yet, so GPU time is shown as (FrameTime - CPU) as a best approximation. - const auto& perf = app.GetPerformanceTimers(); - m_CPUTime = perf.MainThreadWorkTime; - m_GPUTime = m_FrameTime - m_CPUTime; -} - -// --------------------------------------------------------------------------- -// OnImGuiRender -// --------------------------------------------------------------------------- - -void Sandbox2D::OnImGuiRender() -{ - LUX_PROFILE_FUNCTION("Sandbox2D::OnImGuiRender"); - - static bool dockspaceOpen = true; - static bool opt_fullscreen_persistant = true; - bool opt_fullscreen = opt_fullscreen_persistant; - static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None; - - ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking; - if (opt_fullscreen) - { - ImGuiViewport* viewport = ImGui::GetMainViewport(); - ImGui::SetNextWindowPos(viewport->Pos); - ImGui::SetNextWindowSize(viewport->Size); - ImGui::SetNextWindowViewport(viewport->ID); - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); - ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); - window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | - ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove; - window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus; - } - - if (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode) - window_flags |= ImGuiWindowFlags_NoBackground; - - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); - ImGui::Begin("DockSpace Demo", &dockspaceOpen, window_flags); - ImGui::PopStyleVar(); - - if (opt_fullscreen) - ImGui::PopStyleVar(2); - - ImGuiIO& io = ImGui::GetIO(); - ImGuiStyle& style = ImGui::GetStyle(); - float minWinSizeX = style.WindowMinSize.x; - style.WindowMinSize.x = 370.0f; - if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) - { - ImGuiID dockspace_id = ImGui::GetID("MyDockSpace"); - ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags); - } - style.WindowMinSize.x = minWinSizeX; - - // ------------------------------------------------------------------ - // Renderer info panel - // ------------------------------------------------------------------ - - ImGui::Begin("Renderer Info"); - - auto stats = m_Renderer2D->GetDrawStats(); - ImGui::Text("Renderer2D Stats:"); - ImGui::Text("Draw Calls : %d", stats.DrawCalls); - ImGui::Text("Quads : %d", stats.QuadCount); - ImGui::Text("Vertices : %d", stats.GetTotalVertexCount()); - ImGui::Text("Indices : %d", stats.GetTotalIndexCount()); - - ImGui::Separator(); - - ImGui::Text("Frame : %.3f ms (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); - ImGui::Text("CPU : %.2f ms", m_CPUTime); - ImGui::Text("GPU : %.2f ms", m_GPUTime); - - ImGui::Separator(); - - if (ImGui::Checkbox("VSync", &m_VSync)) - { - m_PostSceneUpdateQueue.push_back([this]() - { - Lux::Application::Get().GetWindow().SetVSync(m_VSync); - }); - } - - ImGui::Checkbox("Debug overlay (Ctrl+F3)", &m_ShowDebugDisplay); - - ImGui::End(); // Renderer Info - - // ------------------------------------------------------------------ - // Viewport panel - // - // Displays m_Framebuffer's colour attachment (index 0), which holds - // the fully composited scene + overlay written by OnUpdate. - // - // We only RECORD the panel size here. Actual framebuffer resize happens - // at the top of OnUpdate via OnViewportResize(), keeping all GPU work - // on the render-thread path and away from the ImGui submission path. - // ------------------------------------------------------------------ - - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); - ImGui::Begin("Viewport"); - ImGui::PopStyleVar(); - - auto viewportMinRegion = ImGui::GetWindowContentRegionMin(); - auto viewportMaxRegion = ImGui::GetWindowContentRegionMax(); - auto viewportOffset = ImGui::GetWindowPos(); - m_ViewportBounds[0] = { viewportMinRegion.x + viewportOffset.x, - viewportMinRegion.y + viewportOffset.y }; - m_ViewportBounds[1] = { viewportMaxRegion.x + viewportOffset.x, - viewportMaxRegion.y + viewportOffset.y }; - - m_ViewportFocused = ImGui::IsWindowFocused(); - m_ViewportHovered = ImGui::IsWindowHovered(); - Lux::Application::Get().GetImGuiLayer()->AllowInputEvents(m_ViewportFocused || m_ViewportHovered); - - // Store panel size; OnUpdate will resize the framebuffer next frame if it changed. - // Guard against zero/negative size which occurs while the panel is being dragged - // or docked - passing 0 to Framebuffer::Resize frees images and produces an - // invalid 0xFFFFFFFFFFFFFFFF handle that crashes the ImGui renderer. - ImVec2 viewportPanelSize = ImGui::GetContentRegionAvail(); - if (viewportPanelSize.x > 1.0f && viewportPanelSize.y > 1.0f) - m_ViewportSize = { viewportPanelSize.x, viewportPanelSize.y }; - - // CreateFrameTexture registers the NVRHI texture in the shared registry - // for this frame and returns an encoded index handle. All ImGuiRenderer - // instances (main + per-viewport) share the same registry, so this handle - // is valid when any of them decode it during draw-command processing. - // UV flip (0,1)->(1,0) corrects Vulkan's top-left NDC origin. - nvrhi::ITexture* nvrhiTex = m_Framebuffer->GetImage(0)->GetHandle().Get(); - ImTextureID texID = Lux::Application::Get().GetImGuiLayer()->GetImGuiRenderer() - ->CreateFrameTexture(nvrhiTex); - ImGui::Image(texID, ImVec2{ m_ViewportSize.x, m_ViewportSize.y }, - ImVec2{ 0, 1 }, ImVec2{ 1, 0 }); - - ImGui::End(); // Viewport - - ImGui::End(); // DockSpace Demo -} - -// --------------------------------------------------------------------------- -// OnEvent -// --------------------------------------------------------------------------- - -void Sandbox2D::OnEvent(Lux::Event& e) -{ - m_EditorCamera.OnEvent(e); - - Lux::EventDispatcher dispatcher(e); - dispatcher.Dispatch([this](Lux::KeyPressedEvent& ke) -> bool - { - if (ke.GetRepeatCount() == 0 && Lux::Input::IsKeyDown(Lux::KeyCode::LeftControl)) - { - if (ke.GetKeyCode() == Lux::KeyCode::F3) - { - m_ShowDebugDisplay = !m_ShowDebugDisplay; - return true; - } - } - return false; - }); -} diff --git a/Sandbox/Source/Sandbox2D.h b/Sandbox/Source/Sandbox2D.h deleted file mode 100644 index 92120b21..00000000 --- a/Sandbox/Source/Sandbox2D.h +++ /dev/null @@ -1,91 +0,0 @@ -#pragma once - -#include "Lux.h" - -#include -#include - -class Sandbox2D : public Lux::Layer -{ -public: - Sandbox2D(); - virtual ~Sandbox2D() = default; - - virtual void OnAttach() override; - virtual void OnDetach() override; - - void OnUpdate(Lux::Timestep ts) override; - virtual void OnImGuiRender() override; - void OnEvent(Lux::Event& e) override; - -private: - // Draws 2D overlays (FPS, debug stats) as a second BeginScene/EndScene pass. - void OnRender2D(); - - void OnViewportResize(uint32_t width, uint32_t height); - - // Draws FPS + frame timing lines anchored to the bottom-right corner. - void DrawFPSStats(); - - // Draws a broader timing breakdown anchored to the top-left corner. - void DrawDebugStats(); - - // Renders text at a 2D screen-space position with an optional drop shadow. - // Must be called between BeginScene/EndScene with an ortho projection. - void DrawString(const std::string& string, - const glm::vec2& position, - const glm::vec4& color = glm::vec4(1.0f), - float size = 20.0f, - bool shadow = true); - - // Throttled stat helpers - called from OnUpdate timers. - void UpdateFPSStat(); - void UpdatePerformanceTimers(); - -private: - Lux::EditorCamera m_EditorCamera; - - // Ortho projection rebuilt every frame to match viewport size. - // Used for the debug/FPS overlay BeginScene call. - glm::mat4 m_Renderer2DProj{ 1.0f }; - - // Offscreen framebuffer the scene is rendered into. - // Displayed as an ImGui::Image in the Viewport panel. - // Renderer2D targets this via SetTargetFramebuffer(). - Lux::Ref m_Framebuffer; - - Lux::Ref m_CheckerboardTexture; - - // Renderer2D is self-contained: it owns its own RenderCommandBuffer and - // internal RenderPasses (quad/line/text). All we do is call - // SetTargetFramebuffer() once, then BeginScene/EndScene each frame. - Lux::Ref m_Renderer2D; - - // Viewport dimensions - tracked so we detect resize each frame. - glm::vec2 m_ViewportSize = { 0.0f, 0.0f }; - uint32_t m_Width = 0; - uint32_t m_Height = 0; - - // Throttled FPS / perf timers. - uint32_t m_FramesPerSecond = 0; - float m_UpdateFPSTimer = 0.0f; // resets to 1.0 s - float m_UpdatePerfTimer = 0.0f; // resets to 0.2 s - - float m_FrameTime = 0.0f; - float m_CPUTime = 0.0f; - float m_GPUTime = 0.0f; - - // Ctrl+F3 toggles the on-screen debug overlay. - bool m_ShowDebugDisplay = false; - - // Lambdas pushed here are flushed at the end of OnUpdate (post-render). - std::vector> m_PostSceneUpdateQueue; - - glm::vec2 m_ViewportBounds[2]; - - bool m_VSync = true; - bool m_ViewportFocused = false; - bool m_ViewportHovered = false; - - glm::vec4 m_SquareColor = { 0.2f, 0.3f, 0.8f, 1.0f }; -}; diff --git a/Sandbox/Source/SandboxApp.cpp b/Sandbox/Source/SandboxApp.cpp deleted file mode 100644 index 06a1b135..00000000 --- a/Sandbox/Source/SandboxApp.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "Sandbox2D.h" -#include "Lux/Utilities/FileSystem.h" -#include "Lux/Utilities/CommandLineParser.h" - -#include "Lux/EntryPoint.h" - -class Sandbox : public Lux::Application -{ -public: - Sandbox(const Lux::ApplicationSpecification& specification) - : Application(specification) - { - //PushLayer(new ExampleLayer()); - PushLayer(new Sandbox2D()); - } - - ~Sandbox() - { - - } - -}; - -Lux::Application* Lux::CreateApplication(int argc, char** argv) -{ - Lux::CommandLineParser cli(argc, argv); - - auto raw = cli.GetRawArgs(); - if(raw.size() > 1) { - LUX_CORE_WARN("More than one project path specified, using `{}'", raw[0]); - } - - auto cd = cli.GetOpt("C"); - if(!cd.empty()) { - Lux::FileSystem::SetWorkingDirectory(cd); - } - - std::string_view projectPath; - if(!raw.empty()) projectPath = raw[0]; - - Lux::ApplicationSpecification specification; - specification.Name = "Sandbox"; - specification.WindowWidth = 1600; - specification.WindowHeight = 900; - specification.StartMaximized = true; - specification.VSync = true; - // specification.RenderConfig.ShaderPackPath = "Resources/ShaderPack.hsp"; - - /*specification.ScriptConfig.CoreAssemblyPath = "Resources/Scripts/Hazel-ScriptCore.dll"; - specification.ScriptConfig.EnableDebugging = true; - specification.ScriptConfig.EnableProfiling = true;*/ - - specification.CoreThreadingPolicy = Lux::ThreadingPolicy::SingleThreaded; - - return new Sandbox(specification); -} diff --git a/Sandbox/assets/fonts/opensans/LICENSE.txt b/Sandbox/assets/fonts/opensans/LICENSE.txt deleted file mode 100644 index cb7002a8..00000000 --- a/Sandbox/assets/fonts/opensans/LICENSE.txt +++ /dev/null @@ -1,93 +0,0 @@ -Copyright 2020 The Open Sans Project Authors (https://github.com/googlefonts/opensans) - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -https://openfontlicense.org - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/Sandbox/assets/fonts/opensans/OpenSans-Bold.ttf b/Sandbox/assets/fonts/opensans/OpenSans-Bold.ttf deleted file mode 100644 index 98c74e0a..00000000 Binary files a/Sandbox/assets/fonts/opensans/OpenSans-Bold.ttf and /dev/null differ diff --git a/Sandbox/assets/fonts/opensans/OpenSans-BoldItalic.ttf b/Sandbox/assets/fonts/opensans/OpenSans-BoldItalic.ttf deleted file mode 100644 index 85589283..00000000 Binary files a/Sandbox/assets/fonts/opensans/OpenSans-BoldItalic.ttf and /dev/null differ diff --git a/Sandbox/assets/fonts/opensans/OpenSans-ExtraBold.ttf b/Sandbox/assets/fonts/opensans/OpenSans-ExtraBold.ttf deleted file mode 100644 index 4eb33935..00000000 Binary files a/Sandbox/assets/fonts/opensans/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/Sandbox/assets/fonts/opensans/OpenSans-ExtraBoldItalic.ttf b/Sandbox/assets/fonts/opensans/OpenSans-ExtraBoldItalic.ttf deleted file mode 100644 index 75789b42..00000000 Binary files a/Sandbox/assets/fonts/opensans/OpenSans-ExtraBoldItalic.ttf and /dev/null differ diff --git a/Sandbox/assets/fonts/opensans/OpenSans-Italic.ttf b/Sandbox/assets/fonts/opensans/OpenSans-Italic.ttf deleted file mode 100644 index 29ff6938..00000000 Binary files a/Sandbox/assets/fonts/opensans/OpenSans-Italic.ttf and /dev/null differ diff --git a/Sandbox/assets/fonts/opensans/OpenSans-Light.ttf b/Sandbox/assets/fonts/opensans/OpenSans-Light.ttf deleted file mode 100644 index ea175cc3..00000000 Binary files a/Sandbox/assets/fonts/opensans/OpenSans-Light.ttf and /dev/null differ diff --git a/Sandbox/assets/fonts/opensans/OpenSans-LightItalic.ttf b/Sandbox/assets/fonts/opensans/OpenSans-LightItalic.ttf deleted file mode 100644 index edbfe0b7..00000000 Binary files a/Sandbox/assets/fonts/opensans/OpenSans-LightItalic.ttf and /dev/null differ diff --git a/Sandbox/assets/fonts/opensans/OpenSans-Medium.ttf b/Sandbox/assets/fonts/opensans/OpenSans-Medium.ttf deleted file mode 100644 index ae716936..00000000 Binary files a/Sandbox/assets/fonts/opensans/OpenSans-Medium.ttf and /dev/null differ diff --git a/Sandbox/assets/fonts/opensans/OpenSans-MediumItalic.ttf b/Sandbox/assets/fonts/opensans/OpenSans-MediumItalic.ttf deleted file mode 100644 index 6d1e09b2..00000000 Binary files a/Sandbox/assets/fonts/opensans/OpenSans-MediumItalic.ttf and /dev/null differ diff --git a/Sandbox/assets/fonts/opensans/OpenSans-Regular.ttf b/Sandbox/assets/fonts/opensans/OpenSans-Regular.ttf deleted file mode 100644 index 67803bb6..00000000 Binary files a/Sandbox/assets/fonts/opensans/OpenSans-Regular.ttf and /dev/null differ diff --git a/Sandbox/assets/fonts/opensans/OpenSans-SemiBold.ttf b/Sandbox/assets/fonts/opensans/OpenSans-SemiBold.ttf deleted file mode 100644 index e5ab4644..00000000 Binary files a/Sandbox/assets/fonts/opensans/OpenSans-SemiBold.ttf and /dev/null differ diff --git a/Sandbox/assets/fonts/opensans/OpenSans-SemiBoldItalic.ttf b/Sandbox/assets/fonts/opensans/OpenSans-SemiBoldItalic.ttf deleted file mode 100644 index cd23e154..00000000 Binary files a/Sandbox/assets/fonts/opensans/OpenSans-SemiBoldItalic.ttf and /dev/null differ diff --git a/Sandbox/assets/game/textures/RPGpack_sheet_2X.png b/Sandbox/assets/game/textures/RPGpack_sheet_2X.png deleted file mode 100644 index 35a8cd96..00000000 Binary files a/Sandbox/assets/game/textures/RPGpack_sheet_2X.png and /dev/null differ diff --git a/Sandbox/assets/shaders/FlatColor.glsl b/Sandbox/assets/shaders/FlatColor.glsl deleted file mode 100644 index 2d39fc5b..00000000 --- a/Sandbox/assets/shaders/FlatColor.glsl +++ /dev/null @@ -1,26 +0,0 @@ -// Flat Color Shader - -#type vertex -#version 330 core - -layout(location = 0) in vec3 a_Position; - -uniform mat4 u_ViewProjection; -uniform mat4 u_Transform; - -void main() -{ - gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0); -} - -#type fragment -#version 330 core - -layout(location = 0) out vec4 color; - -uniform vec4 u_Color; - -void main() -{ - color = u_Color; -} \ No newline at end of file diff --git a/Sandbox/assets/shaders/Texture.glsl b/Sandbox/assets/shaders/Texture.glsl deleted file mode 100644 index 607467e5..00000000 --- a/Sandbox/assets/shaders/Texture.glsl +++ /dev/null @@ -1,101 +0,0 @@ -// Basic Texture Shader - -#type vertex -#version 450 core - -layout(location = 0) in vec3 a_Position; -layout(location = 1) in vec4 a_Color; -layout(location = 2) in vec2 a_TexCoord; -layout(location = 3) in float a_TexIndex; -layout(location = 4) in float a_TilingFactor; -layout(location = 5) in int a_EntityID; - -layout(std140, binding = 0) uniform Camera -{ - mat4 u_ViewProjection; -}; - -struct VertexOutput -{ - vec4 Color; - vec2 TexCoord; - float TexIndex; - float TilingFactor; -}; - -layout (location = 0) out VertexOutput Output; -layout (location = 4) out flat int v_EntityID; - -void main() -{ - Output.Color = a_Color; - Output.TexCoord = a_TexCoord; - Output.TexIndex = a_TexIndex; - Output.TilingFactor = a_TilingFactor; - v_EntityID = a_EntityID; - - gl_Position = u_ViewProjection * vec4(a_Position, 1.0); -} - -#type fragment -#version 450 core - -layout(location = 0) out vec4 color; -layout(location = 1) out int color2; - -struct VertexOutput -{ - vec4 Color; - vec2 TexCoord; - float TexIndex; - float TilingFactor; -}; - -layout (location = 0) in VertexOutput Input; -layout (location = 4) in flat int v_EntityID; - -layout (binding = 0) uniform sampler2D u_Textures[32]; - -void main() -{ - vec4 texColor = Input.Color; - - switch(int(Input.TexIndex)) - { - case 0: texColor *= texture(u_Textures[ 0], Input.TexCoord * Input.TilingFactor); break; - case 1: texColor *= texture(u_Textures[ 1], Input.TexCoord * Input.TilingFactor); break; - case 2: texColor *= texture(u_Textures[ 2], Input.TexCoord * Input.TilingFactor); break; - case 3: texColor *= texture(u_Textures[ 3], Input.TexCoord * Input.TilingFactor); break; - case 4: texColor *= texture(u_Textures[ 4], Input.TexCoord * Input.TilingFactor); break; - case 5: texColor *= texture(u_Textures[ 5], Input.TexCoord * Input.TilingFactor); break; - case 6: texColor *= texture(u_Textures[ 6], Input.TexCoord * Input.TilingFactor); break; - case 7: texColor *= texture(u_Textures[ 7], Input.TexCoord * Input.TilingFactor); break; - case 8: texColor *= texture(u_Textures[ 8], Input.TexCoord * Input.TilingFactor); break; - case 9: texColor *= texture(u_Textures[ 9], Input.TexCoord * Input.TilingFactor); break; - case 10: texColor *= texture(u_Textures[10], Input.TexCoord * Input.TilingFactor); break; - case 11: texColor *= texture(u_Textures[11], Input.TexCoord * Input.TilingFactor); break; - case 12: texColor *= texture(u_Textures[12], Input.TexCoord * Input.TilingFactor); break; - case 13: texColor *= texture(u_Textures[13], Input.TexCoord * Input.TilingFactor); break; - case 14: texColor *= texture(u_Textures[14], Input.TexCoord * Input.TilingFactor); break; - case 15: texColor *= texture(u_Textures[15], Input.TexCoord * Input.TilingFactor); break; - case 16: texColor *= texture(u_Textures[16], Input.TexCoord * Input.TilingFactor); break; - case 17: texColor *= texture(u_Textures[17], Input.TexCoord * Input.TilingFactor); break; - case 18: texColor *= texture(u_Textures[18], Input.TexCoord * Input.TilingFactor); break; - case 19: texColor *= texture(u_Textures[19], Input.TexCoord * Input.TilingFactor); break; - case 20: texColor *= texture(u_Textures[20], Input.TexCoord * Input.TilingFactor); break; - case 21: texColor *= texture(u_Textures[21], Input.TexCoord * Input.TilingFactor); break; - case 22: texColor *= texture(u_Textures[22], Input.TexCoord * Input.TilingFactor); break; - case 23: texColor *= texture(u_Textures[23], Input.TexCoord * Input.TilingFactor); break; - case 24: texColor *= texture(u_Textures[24], Input.TexCoord * Input.TilingFactor); break; - case 25: texColor *= texture(u_Textures[25], Input.TexCoord * Input.TilingFactor); break; - case 26: texColor *= texture(u_Textures[26], Input.TexCoord * Input.TilingFactor); break; - case 27: texColor *= texture(u_Textures[27], Input.TexCoord * Input.TilingFactor); break; - case 28: texColor *= texture(u_Textures[28], Input.TexCoord * Input.TilingFactor); break; - case 29: texColor *= texture(u_Textures[29], Input.TexCoord * Input.TilingFactor); break; - case 30: texColor *= texture(u_Textures[30], Input.TexCoord * Input.TilingFactor); break; - case 31: texColor *= texture(u_Textures[31], Input.TexCoord * Input.TilingFactor); break; - } - color = texColor; - - color2 = v_EntityID; -} \ No newline at end of file diff --git a/Sandbox/assets/textures/Checkerboard.png b/Sandbox/assets/textures/Checkerboard.png deleted file mode 100644 index a384354d..00000000 Binary files a/Sandbox/assets/textures/Checkerboard.png and /dev/null differ diff --git a/Sandbox/assets/textures/luxLogo.png b/Sandbox/assets/textures/luxLogo.png deleted file mode 100644 index 9092f582..00000000 Binary files a/Sandbox/assets/textures/luxLogo.png and /dev/null differ diff --git a/Sandbox/premake5.lua b/Sandbox/premake5.lua deleted file mode 100644 index 3677c65a..00000000 --- a/Sandbox/premake5.lua +++ /dev/null @@ -1,59 +0,0 @@ -project "Sandbox" - kind "ConsoleApp" - - targetdir ("../bin/" .. outputdir .. "/%{prj.name}") - objdir ("../bin-int/" .. outputdir .. "/%{prj.name}") - - links { "Core" } - - defines { "GLM_FORCE_DEPTH_ZERO_TO_ONE", } - - files { - "Source/**.h", - "Source/**.c", - "Source/**.hpp", - "Source/**.cpp", - } - - includedirs { - "Source/", - - "../Core/Source/", - "../Core/vendor/" - } - - defines - { - "TRACY_ENABLE", - "TRACY_ON_DEMAND", - "TRACY_CALLSTACK=10" - } - - filter "system:windows" - systemversion "latest" - defines { "LUX_PLATFORM_WINDOWS" } - - filter "system:linux" - defines { "LUX_PLATFORM_LINUX", "__EMULATE_UUID", "BACKWARD_HAS_DW", "BACKWARD_HAS_LIBUNWIND" } - links { "dw", "dl", "unwind", "pthread" } - - filter "configurations:Debug" - defines "LUX_DEBUG" - runtime "Debug" - symbols "on" - ProcessDependencies("Debug") - - filter "configurations:Release" - defines "LUX_RELEASE" - runtime "Release" - optimize "on" - ProcessDependencies("Release") - - filter "configurations:Dist" - defines "LUX_DIST" - runtime "Release" - optimize "on" - ProcessDependencies("Dist") - - filter "action:vs2022" - buildoptions { "/utf-8" } \ No newline at end of file diff --git a/premake5.lua b/premake5.lua index 892974ce..731b5a89 100644 --- a/premake5.lua +++ b/premake5.lua @@ -86,4 +86,5 @@ group "Tools" group "" group "Runtime" + include "Lux-Runtime" group "" diff --git a/scripts/Linux-Build.sh b/scripts/Linux-Build.sh index 5c8fd707..695fba54 100644 --- a/scripts/Linux-Build.sh +++ b/scripts/Linux-Build.sh @@ -39,10 +39,6 @@ fi cp $CORAL_DIR/Build/$BUILD_CONFIG/Coral.Managed.pdb $DOTNET_DIR/Coral.Managed.pdb cp $CORAL_DIR/Build/$BUILD_CONFIG/Coral.Managed.deps.json $DOTNET_DIR/Coral.Managed.deps.json -# Build Sandbox - premake5 vs2022 --file=Sandbox/premake5.lua - dotnet build -c $BUILD_CONFIG --property WarningLevel=0 Sandbox/Sandbox.sln - # Build Lux premake5 gmake --cc=clang --verbose make config=$(echo "$BUILD_CONFIG" | tr '[:upper:]' '[:lower:]') "$@"