From 87f15b20073782eaaab78f66b6a556e4afbaceb3 Mon Sep 17 00:00:00 2001 From: redstrate <54911369+redstrate@users.noreply.github.com> Date: Sun, 9 May 2021 19:10:23 -0400 Subject: [PATCH] Completely redo the CMake shader compilation system * Now shader recompilation happens only when it needs to. Hurray for faster compiles! * Changes to constructors for ShaderSource to make it more explicit. * The version of SPIRV-Cross is updated, and now the glslang version pulled correctly matches what SPIRV-Cross needs. This fixes the annoying "cannot parse built-ins" bug. --- CMakeLists.txt | 2 +- cmake/BuildShaders.cmake | 71 +- engine/CMakeLists.txt | 46 +- engine/renderer/CMakeLists.txt | 46 +- engine/renderer/src/dofpass.cpp | 4 +- engine/renderer/src/imguipass.cpp | 4 +- engine/renderer/src/materialcompiler.cpp | 4 +- engine/renderer/src/renderer.cpp | 30 +- engine/renderer/src/scenecapture.cpp | 12 +- engine/renderer/src/shadowpass.cpp | 7 +- engine/renderer/src/smaapass.cpp | 8 +- .../shadercompiler/include/shadercompiler.hpp | 22 +- .../shadercompiler/src/defaultresources.hpp | 211 +-- engine/shadercompiler/src/shadercompiler.cpp | 49 +- extern/CMakeLists.txt | 4 +- shaders/atmosphere.glsl | 107 -- shaders/billboard.frag.glsl | 17 - shaders/billboard.vert.glsl | 25 - shaders/blend.frag.glsl | 16 - shaders/blend.vert.glsl | 14 - shaders/brdf.frag.glsl | 48 - shaders/brdf.vert.glsl | 6 - shaders/color.frag.glsl | 10 - shaders/color.vert.glsl | 10 - shaders/common.nocompile.glsl | 161 -- shaders/debug.frag.glsl | 10 - shaders/debug.vert.glsl | 10 - shaders/dof.frag.glsl | 28 - shaders/dof.vert.glsl | 35 - shaders/edge.frag.glsl | 16 - shaders/edge.vert.glsl | 13 - shaders/filter.frag.glsl | 51 - shaders/filter.vert.glsl | 13 - shaders/font.glsl | 5 - shaders/gaussian.frag.glsl | 34 - shaders/gaussian.vert.glsl | 6 - shaders/histogram-average.comp.glsl | 44 - shaders/histogram.comp.glsl | 49 - shaders/imgui.frag.glsl | 10 - shaders/imgui.vert.glsl | 16 - shaders/irradiance.frag.glsl | 36 - shaders/irradiance.vert.glsl | 12 - shaders/mesh.vert.nocompile.glsl | 123 -- shaders/omnishadow.frag.glsl | 14 - shaders/post.frag.glsl | 159 -- shaders/post.vert.glsl | 25 - shaders/rendering.nocompile.glsl | 305 ---- shaders/scenecapture.vert.nocompile.glsl | 58 - shaders/shadow.frag.glsl | 5 - shaders/shadow.vert.nocompile.glsl | 43 - shaders/sky.frag.glsl | 47 - shaders/sky.vert.glsl | 12 - shaders/smaa.glsl | 1407 ----------------- shaders/smaa_common.glsl | 12 - shaders/text.frag.glsl | 15 - shaders/text.vert.glsl | 61 - shaders/ui.frag.glsl | 22 - shaders/ui.vert.glsl | 38 - tools/common/src/debugpass.cpp | 16 +- tools/shadercompiler/main.cpp | 25 +- 60 files changed, 281 insertions(+), 3428 deletions(-) delete mode 100755 shaders/atmosphere.glsl delete mode 100755 shaders/billboard.frag.glsl delete mode 100755 shaders/billboard.vert.glsl delete mode 100644 shaders/blend.frag.glsl delete mode 100644 shaders/blend.vert.glsl delete mode 100755 shaders/brdf.frag.glsl delete mode 100755 shaders/brdf.vert.glsl delete mode 100755 shaders/color.frag.glsl delete mode 100755 shaders/color.vert.glsl delete mode 100755 shaders/common.nocompile.glsl delete mode 100755 shaders/debug.frag.glsl delete mode 100755 shaders/debug.vert.glsl delete mode 100644 shaders/dof.frag.glsl delete mode 100644 shaders/dof.vert.glsl delete mode 100644 shaders/edge.frag.glsl delete mode 100644 shaders/edge.vert.glsl delete mode 100755 shaders/filter.frag.glsl delete mode 100755 shaders/filter.vert.glsl delete mode 100755 shaders/font.glsl delete mode 100644 shaders/gaussian.frag.glsl delete mode 100644 shaders/gaussian.vert.glsl delete mode 100755 shaders/histogram-average.comp.glsl delete mode 100755 shaders/histogram.comp.glsl delete mode 100755 shaders/imgui.frag.glsl delete mode 100755 shaders/imgui.vert.glsl delete mode 100755 shaders/irradiance.frag.glsl delete mode 100755 shaders/irradiance.vert.glsl delete mode 100755 shaders/mesh.vert.nocompile.glsl delete mode 100755 shaders/omnishadow.frag.glsl delete mode 100755 shaders/post.frag.glsl delete mode 100755 shaders/post.vert.glsl delete mode 100755 shaders/rendering.nocompile.glsl delete mode 100755 shaders/scenecapture.vert.nocompile.glsl delete mode 100755 shaders/shadow.frag.glsl delete mode 100755 shaders/shadow.vert.nocompile.glsl delete mode 100755 shaders/sky.frag.glsl delete mode 100755 shaders/sky.vert.glsl delete mode 100644 shaders/smaa.glsl delete mode 100755 shaders/smaa_common.glsl delete mode 100755 shaders/text.frag.glsl delete mode 100755 shaders/text.vert.glsl delete mode 100755 shaders/ui.frag.glsl delete mode 100755 shaders/ui.vert.glsl diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b57114..c8fe852 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.17) +cmake_minimum_required(VERSION 3.20) project(PrismEngine) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake) diff --git a/cmake/BuildShaders.cmake b/cmake/BuildShaders.cmake index 1d1310c..77b0957 100755 --- a/cmake/BuildShaders.cmake +++ b/cmake/BuildShaders.cmake @@ -1,47 +1,56 @@ -macro(compile_shader src) - string(REGEX REPLACE "\\.[^.]*$" "" MYFILE_WITHOUT_EXT ${src}) +# add custom command to output compiled shader +function(add_shader_command) + cmake_parse_arguments(ARGS "" "FILENAME;OUT" "" ${ARGN}) - set(SHADER_COMPILER_COMMAND $) + cmake_path(REMOVE_EXTENSION ARGS_FILENAME LAST_ONLY OUTPUT_VARIABLE FILENAME_WITHOUT_EXT) + + set(SHADER_COMPILER_COMMAND $) + set(EXTRA_PLATFORM_ARG "0") + + # if targeting ios, we want to use the host's shader compiler if(ENABLE_IOS) - set(SHADER_COMPILER_COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/../build/bin/Debug/ShaderCompilerTool") + set(SHADER_COMPILER_COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/../build/bin/Debug/ShaderCompilerTool") + set(EXTRA_PLATFORM_ARG "1") endif() - set(EXTRA_PLATFORM_ARG "0") - if(ENABLE_IOS) - set(EXTRA_PLATFORM_ARG "1") + set(SRC_FILENAME ${CMAKE_CURRENT_SOURCE_DIR}/${ARGS_FILENAME}) + set(OUTPUT_FILENAME ${CMAKE_BINARY_DIR}/${FILENAME_WITHOUT_EXT}) + + # we want to remove the .nocompile extension just like the tool does, if it exists + cmake_path(GET FILENAME_WITHOUT_EXT EXTENSION LAST_ONLY LAST_EXT) + + if(LAST_EXT STREQUAL ".nocompile") + cmake_path(REPLACE_EXTENSION OUTPUT_FILENAME LAST_ONLY glsl) endif() add_custom_command( - OUTPUT ${CMAKE_BINARY_DIR}/${MYFILE_WITHOUT_EXT}.glsl - COMMAND ${SHADER_COMPILER_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/../../${src} ${CMAKE_BINARY_DIR}/${src} ${EXTRA_PLATFORM_ARG} - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../../${src} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../shaders - ) -endmacro() + OUTPUT ${OUTPUT_FILENAME} + COMMAND ${SHADER_COMPILER_COMMAND} ${SRC_FILENAME} ${OUTPUT_FILENAME} ${EXTRA_PLATFORM_ARG} + DEPENDS ${SRC_FILENAME} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/shaders) -function(add_shader) + # return the actual filename + set(${ARGS_OUT} ${OUTPUT_FILENAME} PARENT_SCOPE) +endfunction() + +# add shaders to target +function(add_shaders) if(NOT ENABLE_IOS) - set(options OPTIONAL FAST) - set(oneValueArgs TARGET) - set(multiValueArgs SHADERS) - cmake_parse_arguments(add_shader "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + cmake_parse_arguments(ARGS "" "TARGET" "SHADERS" ${ARGN}) - foreach(shader ${add_shader_SHADERS}) - string(REGEX REPLACE "\\.[^.]*$" "" MYFILE_WITHOUT_EXT ${shader}) + foreach(SHADER_FILENAME ${ARGS_SHADERS}) + cmake_path(REMOVE_EXTENSION SHADER_FILENAME LAST_ONLY OUTPUT_VARIABLE FILENAME_WITHOUT_EXT) - compile_shader(${shader}) + add_shader_command(FILENAME ${SHADER_FILENAME} OUT DST_FILENAME) - list(APPEND SPV_FILES ${CMAKE_BINARY_DIR}/${MYFILE_WITHOUT_EXT}.glsl) - list(APPEND SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../${shader}) + list(APPEND SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${SHADER_FILENAME}) + list(APPEND DST_FILES ${DST_FILENAME}) endforeach() - add_custom_target(Shaders SOURCES ${SRC_FILES}) - - file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/shaders) - - add_custom_target(BuildShaders DEPENDS ${SPV_FILES} ShaderCompilerTool) - add_dependencies(${add_shader_TARGET} BuildShaders) - - set(ALL_SHADER_FILES ${SPV_FILES} CACHE INTERNAL "" FORCE) + add_custom_target(BuildShaders DEPENDS ShaderCompilerTool ${DST_FILES}) + add_dependencies(${ARGS_TARGET} BuildShaders) endif() endfunction() + +# make the shader directory if it doesnt exist already +file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/shaders) diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 4c43a39..69c42eb 100755 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -13,4 +13,48 @@ add_subdirectory(platform) if(NOT ENABLE_IOS AND NOT ENABLE_TVOS) add_subdirectory(audio) add_subdirectory(tests) -endif() \ No newline at end of file +endif() + +include(../cmake/BuildShaders.cmake) + +add_shaders(TARGET Renderer + SHADERS + shaders/mesh.vert.nocompile.glsl + shaders/post.vert.glsl + shaders/post.frag.glsl + shaders/text.vert.glsl + shaders/text.frag.glsl + shaders/ui.vert.glsl + shaders/ui.frag.glsl + shaders/imgui.vert.glsl + shaders/imgui.frag.glsl + shaders/debug.vert.glsl + shaders/debug.frag.glsl + shaders/gaussian.vert.glsl + shaders/gaussian.frag.glsl + shaders/shadow.vert.nocompile.glsl + shaders/shadow.frag.glsl + shaders/color.vert.glsl + shaders/color.frag.glsl + shaders/omnishadow.frag.glsl + shaders/edge.vert.glsl + shaders/edge.frag.glsl + shaders/blend.vert.glsl + shaders/blend.frag.glsl + shaders/sky.vert.glsl + shaders/sky.frag.glsl + shaders/billboard.vert.glsl + shaders/billboard.frag.glsl + shaders/scenecapture.vert.nocompile.glsl + shaders/irradiance.vert.glsl + shaders/irradiance.frag.glsl + shaders/filter.vert.glsl + shaders/filter.frag.glsl + shaders/brdf.vert.glsl + shaders/brdf.frag.glsl + shaders/rendering.nocompile.glsl + shaders/common.nocompile.glsl + shaders/dof.vert.glsl + shaders/dof.frag.glsl + shaders/histogram.comp.glsl + shaders/histogram-average.comp.glsl) diff --git a/engine/renderer/CMakeLists.txt b/engine/renderer/CMakeLists.txt index 30dce1f..59d5327 100755 --- a/engine/renderer/CMakeLists.txt +++ b/engine/renderer/CMakeLists.txt @@ -35,48 +35,4 @@ target_link_libraries(Renderer ShaderCompiler Core) target_include_directories(Renderer PUBLIC include) -set_engine_properties(Renderer) - -include(../../cmake/BuildShaders.cmake) - -add_shader(TARGET Renderer - SHADERS - shaders/mesh.vert.nocompile.glsl - shaders/post.vert.glsl - shaders/post.frag.glsl - shaders/text.vert.glsl - shaders/text.frag.glsl - shaders/ui.vert.glsl - shaders/ui.frag.glsl - shaders/imgui.vert.glsl - shaders/imgui.frag.glsl - shaders/debug.vert.glsl - shaders/debug.frag.glsl - shaders/gaussian.vert.glsl - shaders/gaussian.frag.glsl - shaders/shadow.vert.nocompile.glsl - shaders/shadow.frag.glsl - shaders/color.vert.glsl - shaders/color.frag.glsl - shaders/omnishadow.frag.glsl - shaders/edge.vert.glsl - shaders/edge.frag.glsl - shaders/blend.vert.glsl - shaders/blend.frag.glsl - shaders/sky.vert.glsl - shaders/sky.frag.glsl - shaders/billboard.vert.glsl - shaders/billboard.frag.glsl - shaders/scenecapture.vert.nocompile.glsl - shaders/irradiance.vert.glsl - shaders/irradiance.frag.glsl - shaders/filter.vert.glsl - shaders/filter.frag.glsl - shaders/brdf.vert.glsl - shaders/brdf.frag.glsl - shaders/rendering.nocompile.glsl - shaders/common.nocompile.glsl - shaders/dof.vert.glsl - shaders/dof.frag.glsl - shaders/histogram.comp.glsl - shaders/histogram-average.comp.glsl) +set_engine_properties(Renderer) \ No newline at end of file diff --git a/engine/renderer/src/dofpass.cpp b/engine/renderer/src/dofpass.cpp index c018fce..6826cc2 100755 --- a/engine/renderer/src/dofpass.cpp +++ b/engine/renderer/src/dofpass.cpp @@ -28,9 +28,9 @@ DoFPass::DoFPass(GFX* gfx, prism::renderer* renderer) : renderer(renderer) { height_constant.value = extent.height; GFXGraphicsPipelineCreateInfo create_info = {}; - create_info.shaders.vertex_src = file::Path("dof.vert"); + create_info.shaders.vertex_src = ShaderSource(file::Path("dof.vert")); create_info.shaders.vertex_constants = {width_constant, height_constant}; - create_info.shaders.fragment_src = file::Path("dof.frag"); + create_info.shaders.fragment_src = ShaderSource(file::Path("dof.frag")); create_info.shader_input.bindings = { {0, GFXBindingType::StorageImage}, diff --git a/engine/renderer/src/imguipass.cpp b/engine/renderer/src/imguipass.cpp index b828ff9..a7b3d9d 100755 --- a/engine/renderer/src/imguipass.cpp +++ b/engine/renderer/src/imguipass.cpp @@ -23,8 +23,8 @@ void ImGuiPass::create_render_target_resources(RenderTarget& target) { if(pipeline == nullptr) { GFXGraphicsPipelineCreateInfo createInfo; createInfo.label = "ImGui"; - createInfo.shaders.vertex_src = file::Path("imgui.vert"); - createInfo.shaders.fragment_src = file::Path("imgui.frag"); + createInfo.shaders.vertex_src = ShaderSource(file::Path("imgui.vert")); + createInfo.shaders.fragment_src = ShaderSource(file::Path("imgui.frag")); GFXVertexInput vertexInput = {}; vertexInput.stride = sizeof(ImDrawVert); diff --git a/engine/renderer/src/materialcompiler.cpp b/engine/renderer/src/materialcompiler.cpp index aa83ce3..6f2a0f4 100755 --- a/engine/renderer/src/materialcompiler.cpp +++ b/engine/renderer/src/materialcompiler.cpp @@ -31,7 +31,7 @@ ShaderSource get_shader(std::string filename, bool skinned, bool cubemap) { if(cubemap) options.add_definition("CUBEMAP"); - return *shader_compiler.compile(ShaderLanguage::GLSL, stage, shader_file->read_as_string(), engine->get_gfx()->accepted_shader_language(), options); + return *shader_compiler.compile(ShaderLanguage::GLSL, stage, ShaderSource(shader_file->read_as_string()), engine->get_gfx()->accepted_shader_language(), options); } GFXPipeline* MaterialCompiler::create_static_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only, bool cubemap) { @@ -393,5 +393,5 @@ ShaderSource MaterialCompiler::compile_material_fragment(Material& material, boo src += "}\n"; - return *shader_compiler.compile(ShaderLanguage::GLSL, ShaderStage::Fragment, src, engine->get_gfx()->accepted_shader_language()); + return *shader_compiler.compile(ShaderLanguage::GLSL, ShaderStage::Fragment, ShaderSource(src), engine->get_gfx()->accepted_shader_language()); } diff --git a/engine/renderer/src/renderer.cpp b/engine/renderer/src/renderer.cpp index 083cb4f..e6f8e2a 100755 --- a/engine/renderer/src/renderer.cpp +++ b/engine/renderer/src/renderer.cpp @@ -144,8 +144,8 @@ void renderer::resize_render_target(RenderTarget& target, const prism::Extent ex GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Text"; - pipelineInfo.shaders.vertex_src = file::Path("text.vert"); - pipelineInfo.shaders.fragment_src = file::Path("text.frag"); + pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("text.vert")); + pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("text.frag")); pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip; @@ -713,8 +713,8 @@ void renderer::create_mesh_pipeline(Material& material) const { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Mesh"; - pipelineInfo.shaders.vertex_src = file::Path("mesh.vert"); - pipelineInfo.shaders.fragment_src = file::Path("mesh.frag"); + pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("mesh.vert")); + pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("mesh.frag")); pipelineInfo.shaders.vertex_constants = {materials_constant, lights_constant, spot_lights_constant, probes_constant}; pipelineInfo.shaders.fragment_constants = {materials_constant, lights_constant, spot_lights_constant, probes_constant}; @@ -808,8 +808,8 @@ void renderer::create_render_target_resources(RenderTarget& target) { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Post"; - pipelineInfo.shaders.vertex_src = file::Path("post.vert"); - pipelineInfo.shaders.fragment_src = file::Path("post.frag"); + pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("post.vert")); + pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("post.frag")); pipelineInfo.shader_input.bindings = { {4, GFXBindingType::PushConstant}, @@ -835,8 +835,8 @@ void renderer::create_post_pipelines() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Post"; - pipelineInfo.shaders.vertex_src = file::Path("post.vert"); - pipelineInfo.shaders.fragment_src = file::Path("post.frag"); + pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("post.vert")); + pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("post.frag")); pipelineInfo.shader_input.bindings = { {4, GFXBindingType::PushConstant}, @@ -914,8 +914,8 @@ void renderer::create_ui_pipelines() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "UI"; - pipelineInfo.shaders.vertex_src = file::Path("ui.vert"); - pipelineInfo.shaders.fragment_src = file::Path("ui.frag"); + pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("ui.vert")); + pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("ui.frag")); pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip; @@ -953,8 +953,8 @@ void renderer::generate_brdf() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "BRDF"; - pipelineInfo.shaders.vertex_src = file::Path("brdf.vert"); - pipelineInfo.shaders.fragment_src = file::Path("brdf.frag"); + pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("brdf.vert")); + pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("brdf.frag")); pipelineInfo.render_pass = brdf_render_pass; @@ -1047,7 +1047,7 @@ ShaderSource renderer::register_shader(const std::string_view shader_file) { // if shader editor system is not initialized, use prebuilt shaders if(base_shader_path.empty()) - return file::Path(shader_file); + return ShaderSource(file::Path(shader_file)); shader_compiler.set_include_path(base_shader_path.string()); @@ -1062,9 +1062,9 @@ ShaderSource renderer::register_shader(const std::string_view shader_file) { if(found_shader_source.empty()) { auto file = file::open(base_shader_path / shader_path.replace_extension(shader_path.extension().string() + ".glsl")); - return shader_compiler.compile(ShaderLanguage::GLSL, stage, file->read_as_string(), gfx->accepted_shader_language()).value(); + return shader_compiler.compile(ShaderLanguage::GLSL, stage, ShaderSource(file->read_as_string()), gfx->accepted_shader_language()).value(); } else { - return shader_compiler.compile(ShaderLanguage::GLSL, stage, found_shader_source, gfx->accepted_shader_language()).value(); + return shader_compiler.compile(ShaderLanguage::GLSL, stage, ShaderSource(found_shader_source), gfx->accepted_shader_language()).value(); } } diff --git a/engine/renderer/src/scenecapture.cpp b/engine/renderer/src/scenecapture.cpp index 5fd2c8d..22363f3 100755 --- a/engine/renderer/src/scenecapture.cpp +++ b/engine/renderer/src/scenecapture.cpp @@ -399,8 +399,8 @@ void SceneCapture::createSkyResources() { pipelineInfo.label = "Sky Scene Capture"; pipelineInfo.render_pass = renderPass; - pipelineInfo.shaders.vertex_src = file::Path("sky.vert"); - pipelineInfo.shaders.fragment_src = file::Path("sky.frag"); + pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("sky.vert")); + pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("sky.frag")); pipelineInfo.shader_input.bindings = { {1, GFXBindingType::PushConstant} @@ -443,8 +443,8 @@ void SceneCapture::createIrradianceResources() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Irradiance Convolution"; - pipelineInfo.shaders.vertex_src = file::Path("irradiance.vert"); - pipelineInfo.shaders.fragment_src = file::Path("irradiance.frag"); + pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("irradiance.vert")); + pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("irradiance.frag")); GFXVertexInput input; input.stride = sizeof(Vector3); @@ -495,8 +495,8 @@ void SceneCapture::createPrefilterResources() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Prefilter"; - pipelineInfo.shaders.vertex_src = file::Path("filter.vert"); - pipelineInfo.shaders.fragment_src = file::Path("filter.frag"); + pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("filter.vert")); + pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("filter.frag")); pipelineInfo.shaders.fragment_constants = {size_constant}; diff --git a/engine/renderer/src/shadowpass.cpp b/engine/renderer/src/shadowpass.cpp index 6cd1d40..29258ac 100755 --- a/engine/renderer/src/shadowpass.cpp +++ b/engine/renderer/src/shadowpass.cpp @@ -320,11 +320,10 @@ void ShadowPass::create_pipelines() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.shaders.vertex_constants = {point_light_max_constant}; - pipelineInfo.shaders.vertex_src = file::Path("shadow.vert"); + pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("shadow.vert")); pipelineInfo.shaders.fragment_constants = { point_light_max_constant }; - //pipelineInfo.shaders.fragment_path = "shadow.frag"; - + pipelineInfo.shader_input.bindings = { {0, GFXBindingType::PushConstant}, {1, GFXBindingType::StorageBuffer}, @@ -365,7 +364,7 @@ void ShadowPass::create_pipelines() { { pipelineInfo.label = "Point Shadow"; - pipelineInfo.shaders.fragment_src = file::Path("omnishadow.frag"); + pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("omnishadow.frag")); auto [static_pipeline, skinned_pipeline] = material_compiler.create_pipeline_permutations(pipelineInfo, true); diff --git a/engine/renderer/src/smaapass.cpp b/engine/renderer/src/smaapass.cpp index 4a5c0a2..092184d 100755 --- a/engine/renderer/src/smaapass.cpp +++ b/engine/renderer/src/smaapass.cpp @@ -137,8 +137,8 @@ void SMAAPass::create_pipelines() { GFXGraphicsPipelineCreateInfo createInfo = {}; createInfo.label = "SMAA Edge"; - createInfo.shaders.vertex_src = file::Path("edge.vert"); - createInfo.shaders.fragment_src = file::Path("edge.frag"); + createInfo.shaders.vertex_src = ShaderSource(file::Path("edge.vert")); + createInfo.shaders.fragment_src = ShaderSource(file::Path("edge.frag")); createInfo.render_pass = render_pass; @@ -155,8 +155,8 @@ void SMAAPass::create_pipelines() { edge_pipeline = gfx->create_graphics_pipeline(createInfo); createInfo.label = "SMAA Blend"; - createInfo.shaders.vertex_src = file::Path("blend.vert"); - createInfo.shaders.fragment_src = file::Path("blend.frag"); + createInfo.shaders.vertex_src = ShaderSource(file::Path("blend.vert")); + createInfo.shaders.fragment_src = ShaderSource(file::Path("blend.frag")); createInfo.shader_input.bindings.push_back({3, GFXBindingType::Texture}); blend_pipeline = gfx->create_graphics_pipeline(createInfo); diff --git a/engine/shadercompiler/include/shadercompiler.hpp b/engine/shadercompiler/include/shadercompiler.hpp index e2145fb..90d71f3 100755 --- a/engine/shadercompiler/include/shadercompiler.hpp +++ b/engine/shadercompiler/include/shadercompiler.hpp @@ -41,36 +41,36 @@ class ShaderSource { public: ShaderSource() : source(std::monostate()) {} ShaderSource(const ShaderSource& rhs) : source (rhs.source) {} - ShaderSource(const std::string source_string) : source(source_string) {} - ShaderSource(const std::vector source_bytecode) : source(source_bytecode) {} - ShaderSource(const file::Path shader_path) : source(shader_path) {} + explicit ShaderSource(const std::string& source_string) : source(source_string) {} + explicit ShaderSource(const std::vector& source_bytecode) : source(source_bytecode) {} + explicit ShaderSource(const file::Path& shader_path) : source(shader_path) {} std::variant> source; /// Returns a view of the shader source as a path. - file::Path as_path() const { + [[nodiscard]] file::Path as_path() const { return std::get(source); } /// Returns a view of the shader source as plaintext. - std::string_view as_string() const { + [[nodiscard]] std::string_view as_string() const { return std::get(source); } /// Returns a copy of the shader source as bytecode. - std::vector as_bytecode() const { + [[nodiscard]] std::vector as_bytecode() const { return std::get>(source); } - bool empty() const { + [[nodiscard]] bool empty() const { return std::holds_alternative(source); } - bool is_path() const { + [[nodiscard]] bool is_path() const { return std::holds_alternative(source); } - bool is_string() const { + [[nodiscard]] bool is_string() const { return std::holds_alternative(source); } }; @@ -81,7 +81,7 @@ public: ShaderCompiler(); /// Sets the include directory used to search for files inside of #include directives. - void set_include_path(const std::string_view path); + void set_include_path(std::string_view path); /** Compiles from one shader language to another shader language. @@ -92,7 +92,7 @@ public: @param options Optional compilation parameters. @note Right now, only GLSL is supported as a source shader language. */ - std::optional compile(const ShaderLanguage from_language, const ShaderStage shader_stage, const ShaderSource& shader_source, const ShaderLanguage to_language, const CompileOptions& options = CompileOptions()); + std::optional compile(ShaderLanguage from_language, ShaderStage shader_stage, const ShaderSource& shader_source, ShaderLanguage to_language, const CompileOptions& options = CompileOptions()); }; static inline ShaderCompiler shader_compiler; diff --git a/engine/shadercompiler/src/defaultresources.hpp b/engine/shadercompiler/src/defaultresources.hpp index 74aa340..9cc12f5 100755 --- a/engine/shadercompiler/src/defaultresources.hpp +++ b/engine/shadercompiler/src/defaultresources.hpp @@ -1,108 +1,109 @@ #pragma once + const TBuiltInResource DefaultTBuiltInResource = { - /* .MaxLights = */ 32, - /* .MaxClipPlanes = */ 6, - /* .MaxTextureUnits = */ 32, - /* .MaxTextureCoords = */ 32, - /* .MaxVertexAttribs = */ 64, - /* .MaxVertexUniformComponents = */ 4096, - /* .MaxVaryingFloats = */ 64, - /* .MaxVertexTextureImageUnits = */ 32, - /* .MaxCombinedTextureImageUnits = */ 80, - /* .MaxTextureImageUnits = */ 32, - /* .MaxFragmentUniformComponents = */ 4096, - /* .MaxDrawBuffers = */ 32, - /* .MaxVertexUniformVectors = */ 128, - /* .MaxVaryingVectors = */ 8, - /* .MaxFragmentUniformVectors = */ 16, - /* .MaxVertexOutputVectors = */ 16, - /* .MaxFragmentInputVectors = */ 15, - /* .MinProgramTexelOffset = */ -8, - /* .MaxProgramTexelOffset = */ 7, - /* .MaxClipDistances = */ 8, - /* .MaxComputeWorkGroupCountX = */ 65535, - /* .MaxComputeWorkGroupCountY = */ 65535, - /* .MaxComputeWorkGroupCountZ = */ 65535, - /* .MaxComputeWorkGroupSizeX = */ 1024, - /* .MaxComputeWorkGroupSizeY = */ 1024, - /* .MaxComputeWorkGroupSizeZ = */ 64, - /* .MaxComputeUniformComponents = */ 1024, - /* .MaxComputeTextureImageUnits = */ 16, - /* .MaxComputeImageUniforms = */ 8, - /* .MaxComputeAtomicCounters = */ 8, - /* .MaxComputeAtomicCounterBuffers = */ 1, - /* .MaxVaryingComponents = */ 60, - /* .MaxVertexOutputComponents = */ 64, - /* .MaxGeometryInputComponents = */ 64, - /* .MaxGeometryOutputComponents = */ 128, - /* .MaxFragmentInputComponents = */ 128, - /* .MaxImageUnits = */ 8, - /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8, - /* .MaxCombinedShaderOutputResources = */ 8, - /* .MaxImageSamples = */ 0, - /* .MaxVertexImageUniforms = */ 0, - /* .MaxTessControlImageUniforms = */ 0, - /* .MaxTessEvaluationImageUniforms = */ 0, - /* .MaxGeometryImageUniforms = */ 0, - /* .MaxFragmentImageUniforms = */ 8, - /* .MaxCombinedImageUniforms = */ 8, - /* .MaxGeometryTextureImageUnits = */ 16, - /* .MaxGeometryOutputVertices = */ 256, - /* .MaxGeometryTotalOutputComponents = */ 1024, - /* .MaxGeometryUniformComponents = */ 1024, - /* .MaxGeometryVaryingComponents = */ 64, - /* .MaxTessControlInputComponents = */ 128, - /* .MaxTessControlOutputComponents = */ 128, - /* .MaxTessControlTextureImageUnits = */ 16, - /* .MaxTessControlUniformComponents = */ 1024, - /* .MaxTessControlTotalOutputComponents = */ 4096, - /* .MaxTessEvaluationInputComponents = */ 128, - /* .MaxTessEvaluationOutputComponents = */ 128, - /* .MaxTessEvaluationTextureImageUnits = */ 16, - /* .MaxTessEvaluationUniformComponents = */ 1024, - /* .MaxTessPatchComponents = */ 120, - /* .MaxPatchVertices = */ 32, - /* .MaxTessGenLevel = */ 64, - /* .MaxViewports = */ 16, - /* .MaxVertexAtomicCounters = */ 0, - /* .MaxTessControlAtomicCounters = */ 0, - /* .MaxTessEvaluationAtomicCounters = */ 0, - /* .MaxGeometryAtomicCounters = */ 0, - /* .MaxFragmentAtomicCounters = */ 8, - /* .MaxCombinedAtomicCounters = */ 8, - /* .MaxAtomicCounterBindings = */ 1, - /* .MaxVertexAtomicCounterBuffers = */ 0, - /* .MaxTessControlAtomicCounterBuffers = */ 0, - /* .MaxTessEvaluationAtomicCounterBuffers = */ 0, - /* .MaxGeometryAtomicCounterBuffers = */ 0, - /* .MaxFragmentAtomicCounterBuffers = */ 1, - /* .MaxCombinedAtomicCounterBuffers = */ 1, - /* .MaxAtomicCounterBufferSize = */ 16384, - /* .MaxTransformFeedbackBuffers = */ 4, - /* .MaxTransformFeedbackInterleavedComponents = */ 64, - /* .MaxCullDistances = */ 8, - /* .MaxCombinedClipAndCullDistances = */ 8, - /* .MaxSamples = */ 4, - /* .maxMeshOutputVerticesNV = */ 256, - /* .maxMeshOutputPrimitivesNV = */ 512, - /* .maxMeshWorkGroupSizeX_NV = */ 32, - /* .maxMeshWorkGroupSizeY_NV = */ 1, - /* .maxMeshWorkGroupSizeZ_NV = */ 1, - /* .maxTaskWorkGroupSizeX_NV = */ 32, - /* .maxTaskWorkGroupSizeY_NV = */ 1, - /* .maxTaskWorkGroupSizeZ_NV = */ 1, - /* .maxMeshViewCountNV = */ 4, - /* .maxDualSourceDrawBuffersEXT = */ 4, - - /* .limits = */ TLimits{ - /* .nonInductiveForLoops = */ true, - /* .whileLoops = */ true, - /* .doWhileLoops = */ true, - /* .generalUniformIndexing = */ true, - /* .generalAttributeMatrixVectorIndexing = */ true, - /* .generalVaryingIndexing = */ true, - /* .generalSamplerIndexing = */ true, - /* .generalVariableIndexing = */ true, - /* .generalConstantMatrixVectorIndexing = */ true, - }}; + /* .MaxLights = */ 32, + /* .MaxClipPlanes = */ 6, + /* .MaxTextureUnits = */ 32, + /* .MaxTextureCoords = */ 32, + /* .MaxVertexAttribs = */ 64, + /* .MaxVertexUniformComponents = */ 4096, + /* .MaxVaryingFloats = */ 64, + /* .MaxVertexTextureImageUnits = */ 32, + /* .MaxCombinedTextureImageUnits = */ 80, + /* .MaxTextureImageUnits = */ 32, + /* .MaxFragmentUniformComponents = */ 4096, + /* .MaxDrawBuffers = */ 32, + /* .MaxVertexUniformVectors = */ 128, + /* .MaxVaryingVectors = */ 8, + /* .MaxFragmentUniformVectors = */ 16, + /* .MaxVertexOutputVectors = */ 16, + /* .MaxFragmentInputVectors = */ 15, + /* .MinProgramTexelOffset = */ -8, + /* .MaxProgramTexelOffset = */ 7, + /* .MaxClipDistances = */ 8, + /* .MaxComputeWorkGroupCountX = */ 65535, + /* .MaxComputeWorkGroupCountY = */ 65535, + /* .MaxComputeWorkGroupCountZ = */ 65535, + /* .MaxComputeWorkGroupSizeX = */ 1024, + /* .MaxComputeWorkGroupSizeY = */ 1024, + /* .MaxComputeWorkGroupSizeZ = */ 64, + /* .MaxComputeUniformComponents = */ 1024, + /* .MaxComputeTextureImageUnits = */ 16, + /* .MaxComputeImageUniforms = */ 8, + /* .MaxComputeAtomicCounters = */ 8, + /* .MaxComputeAtomicCounterBuffers = */ 1, + /* .MaxVaryingComponents = */ 60, + /* .MaxVertexOutputComponents = */ 64, + /* .MaxGeometryInputComponents = */ 64, + /* .MaxGeometryOutputComponents = */ 128, + /* .MaxFragmentInputComponents = */ 128, + /* .MaxImageUnits = */ 8, + /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8, + /* .MaxCombinedShaderOutputResources = */ 8, + /* .MaxImageSamples = */ 0, + /* .MaxVertexImageUniforms = */ 0, + /* .MaxTessControlImageUniforms = */ 0, + /* .MaxTessEvaluationImageUniforms = */ 0, + /* .MaxGeometryImageUniforms = */ 0, + /* .MaxFragmentImageUniforms = */ 8, + /* .MaxCombinedImageUniforms = */ 8, + /* .MaxGeometryTextureImageUnits = */ 16, + /* .MaxGeometryOutputVertices = */ 256, + /* .MaxGeometryTotalOutputComponents = */ 1024, + /* .MaxGeometryUniformComponents = */ 1024, + /* .MaxGeometryVaryingComponents = */ 64, + /* .MaxTessControlInputComponents = */ 128, + /* .MaxTessControlOutputComponents = */ 128, + /* .MaxTessControlTextureImageUnits = */ 16, + /* .MaxTessControlUniformComponents = */ 1024, + /* .MaxTessControlTotalOutputComponents = */ 4096, + /* .MaxTessEvaluationInputComponents = */ 128, + /* .MaxTessEvaluationOutputComponents = */ 128, + /* .MaxTessEvaluationTextureImageUnits = */ 16, + /* .MaxTessEvaluationUniformComponents = */ 1024, + /* .MaxTessPatchComponents = */ 120, + /* .MaxPatchVertices = */ 32, + /* .MaxTessGenLevel = */ 64, + /* .MaxViewports = */ 16, + /* .MaxVertexAtomicCounters = */ 0, + /* .MaxTessControlAtomicCounters = */ 0, + /* .MaxTessEvaluationAtomicCounters = */ 0, + /* .MaxGeometryAtomicCounters = */ 0, + /* .MaxFragmentAtomicCounters = */ 8, + /* .MaxCombinedAtomicCounters = */ 8, + /* .MaxAtomicCounterBindings = */ 1, + /* .MaxVertexAtomicCounterBuffers = */ 0, + /* .MaxTessControlAtomicCounterBuffers = */ 0, + /* .MaxTessEvaluationAtomicCounterBuffers = */ 0, + /* .MaxGeometryAtomicCounterBuffers = */ 0, + /* .MaxFragmentAtomicCounterBuffers = */ 1, + /* .MaxCombinedAtomicCounterBuffers = */ 1, + /* .MaxAtomicCounterBufferSize = */ 16384, + /* .MaxTransformFeedbackBuffers = */ 4, + /* .MaxTransformFeedbackInterleavedComponents = */ 64, + /* .MaxCullDistances = */ 8, + /* .MaxCombinedClipAndCullDistances = */ 8, + /* .MaxSamples = */ 4, + /* .maxMeshOutputVerticesNV = */ 256, + /* .maxMeshOutputPrimitivesNV = */ 512, + /* .maxMeshWorkGroupSizeX_NV = */ 32, + /* .maxMeshWorkGroupSizeY_NV = */ 1, + /* .maxMeshWorkGroupSizeZ_NV = */ 1, + /* .maxTaskWorkGroupSizeX_NV = */ 32, + /* .maxTaskWorkGroupSizeY_NV = */ 1, + /* .maxTaskWorkGroupSizeZ_NV = */ 1, + /* .maxMeshViewCountNV = */ 4, + /* .maxDualSourceDrawBuffersEXT = */ 1, + + /* .limits = */ { + /* .nonInductiveForLoops = */ 1, + /* .whileLoops = */ 1, + /* .doWhileLoops = */ 1, + /* .generalUniformIndexing = */ 1, + /* .generalAttributeMatrixVectorIndexing = */ 1, + /* .generalVaryingIndexing = */ 1, + /* .generalSamplerIndexing = */ 1, + /* .generalVariableIndexing = */ 1, + /* .generalConstantMatrixVectorIndexing = */ 1, +}}; diff --git a/engine/shadercompiler/src/shadercompiler.cpp b/engine/shadercompiler/src/shadercompiler.cpp index cac9a3d..501c328 100755 --- a/engine/shadercompiler/src/shadercompiler.cpp +++ b/engine/shadercompiler/src/shadercompiler.cpp @@ -16,10 +16,10 @@ ShaderCompiler::ShaderCompiler() { } void ShaderCompiler::set_include_path(const std::string_view path) { - include_path.push_back(path.data()); + include_path.emplace_back(path.data()); } -const std::vector compile_glsl_to_spv(const std::string_view source_string, const EShLanguage shader_language, const CompileOptions& options) { +std::vector compile_glsl_to_spv(const std::string_view source_string, const EShLanguage shader_language, const CompileOptions& options) { std::string newString = "#version 460 core\n"; newString += "#extension GL_GOOGLE_include_directive : enable\n"; @@ -34,36 +34,35 @@ const std::vector compile_glsl_to_spv(const std::string_view source_st const char* InputCString = newString.c_str(); - glslang::TShader Shader(shader_language); - - Shader.setStrings(&InputCString, 1); + glslang::TShader shader(shader_language); + shader.setStrings(&InputCString, 1); int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100 - glslang::EShTargetClientVersion VulkanClientVersion = glslang::EShTargetVulkan_1_1; - glslang::EShTargetLanguageVersion TargetVersion = glslang::EShTargetSpv_1_0; - - Shader.setEnvInput(glslang::EShSourceGlsl, shader_language, glslang::EShClientVulkan, ClientInputSemanticsVersion); - Shader.setEnvClient(glslang::EShClientVulkan, VulkanClientVersion); - Shader.setEnvTarget(glslang::EShTargetSpv, TargetVersion); - - TBuiltInResource Resources = DefaultTBuiltInResource; - EShMessages messages = (EShMessages) (EShMsgDefault); - - DirStackFileIncluder includer; - for(auto path : include_path) - includer.pushExternalLocalDirectory(path); - if (!Shader.parse(&Resources, 100, false, messages, includer)) { - prism::log::error(System::Renderer, "{}", Shader.getInfoLog()); + shader.setEnvInput(glslang::EShSourceGlsl, + shader_language, + glslang::EShClientVulkan, + ClientInputSemanticsVersion); + + // we are targeting vulkan 1.1, so that uses SPIR-V 1.3 + shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_1); + shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3); + + DirStackFileIncluder file_includer; + for(const auto& path : include_path) + file_includer.pushExternalLocalDirectory(path); + + if (!shader.parse(&DefaultTBuiltInResource, 100, false, EShMsgDefault, file_includer)) { + prism::log::error(System::Renderer, "{}", shader.getInfoLog()); return {}; } glslang::TProgram Program; - Program.addShader(&Shader); + Program.addShader(&shader); - if(!Program.link(messages)) { - prism::log::error(System::None, "Failed to link shader: {} {} {}", source_string.data(), Shader.getInfoLog(), Shader.getInfoDebugLog()); + if(!Program.link(EShMsgDefault)) { + prism::log::error(System::None, "Failed to link shader: {} {} {}", source_string.data(), shader.getInfoLog(), shader.getInfoDebugLog()); return {}; } @@ -116,10 +115,10 @@ std::optional ShaderCompiler::compile(const ShaderLanguage from_la msl.set_msl_options(opts); - return msl.compile(); + return ShaderSource(msl.compile()); } case ShaderLanguage::SPIRV: - return spirv; + return ShaderSource(spirv); default: return {}; } diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index 472482d..f222971 100755 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -9,13 +9,13 @@ FetchContent_Declare( FetchContent_Declare( spirv-cross GIT_REPOSITORY https://github.com/KhronosGroup/SPIRV-Cross.git - GIT_TAG 2020-05-19 + GIT_TAG 2021-01-15 ) FetchContent_Declare( glslang GIT_REPOSITORY https://github.com/KhronosGroup/glslang.git - GIT_TAG master + GIT_TAG 3de5cfe50edecd001e6d703555284d9b10b3dd57 # taken from https://github.com/KhronosGroup/SPIRV-Cross/blob/2021-01-15/checkout_glslang_spirv_tools.sh#L3 ) # bullet diff --git a/shaders/atmosphere.glsl b/shaders/atmosphere.glsl deleted file mode 100755 index 3ad481f..0000000 --- a/shaders/atmosphere.glsl +++ /dev/null @@ -1,107 +0,0 @@ -#define PI 3.141592 -#define iSteps 16 -#define jSteps 8 - -vec2 rsi(vec3 r0, vec3 rd, float sr) { - // ray-sphere intersection that assumes - // the sphere is centered at the origin. - // No intersection when result.x > result.y - float a = dot(rd, rd); - float b = 2.0 * dot(rd, r0); - float c = dot(r0, r0) - (sr * sr); - float d = (b*b) - 4.0*a*c; - if (d < 0.0) return vec2(1e5,-1e5); - return vec2( - (-b - sqrt(d))/(2.0*a), - (-b + sqrt(d))/(2.0*a) - ); -} - -vec3 atmosphere(vec3 r, vec3 r0, vec3 pSun, float iSun, float rPlanet, float rAtmos, vec3 kRlh, float kMie, float shRlh, float shMie, float g) { - // Normalize the sun and view directions. - pSun = normalize(pSun); - r = normalize(r); - - // Calculate the step size of the primary ray. - vec2 p = rsi(r0, r, rAtmos); - if (p.x > p.y) return vec3(0,0,0); - p.y = min(p.y, rsi(r0, r, rPlanet).x); - float iStepSize = (p.y - p.x) / float(iSteps); - - // Initialize the primary ray time. - float iTime = 0.0; - - // Initialize accumulators for Rayleigh and Mie scattering. - vec3 totalRlh = vec3(0,0,0); - vec3 totalMie = vec3(0,0,0); - - // Initialize optical depth accumulators for the primary ray. - float iOdRlh = 0.0; - float iOdMie = 0.0; - - // Calculate the Rayleigh and Mie phases. - float mu = dot(r, pSun); - float mumu = mu * mu; - float gg = g * g; - float pRlh = 3.0 / (16.0 * PI) * (1.0 + mumu); - float pMie = 3.0 / (8.0 * PI) * ((1.0 - gg) * (mumu + 1.0)) / (pow(1.0 + gg - 2.0 * mu * g, 1.5) * (2.0 + gg)); - - // Sample the primary ray. - for (int i = 0; i < iSteps; i++) { - - // Calculate the primary ray sample position. - vec3 iPos = r0 + r * (iTime + iStepSize * 0.5); - - // Calculate the height of the sample. - float iHeight = length(iPos) - rPlanet; - - // Calculate the optical depth of the Rayleigh and Mie scattering for this step. - float odStepRlh = exp(-iHeight / shRlh) * iStepSize; - float odStepMie = exp(-iHeight / shMie) * iStepSize; - - // Accumulate optical depth. - iOdRlh += odStepRlh; - iOdMie += odStepMie; - - // Calculate the step size of the secondary ray. - float jStepSize = rsi(iPos, pSun, rAtmos).y / float(jSteps); - - // Initialize the secondary ray time. - float jTime = 0.0; - - // Initialize optical depth accumulators for the secondary ray. - float jOdRlh = 0.0; - float jOdMie = 0.0; - - // Sample the secondary ray. - for (int j = 0; j < jSteps; j++) { - - // Calculate the secondary ray sample position. - vec3 jPos = iPos + pSun * (jTime + jStepSize * 0.5); - - // Calculate the height of the sample. - float jHeight = length(jPos) - rPlanet; - - // Accumulate the optical depth. - jOdRlh += exp(-jHeight / shRlh) * jStepSize; - jOdMie += exp(-jHeight / shMie) * jStepSize; - - // Increment the secondary ray time. - jTime += jStepSize; - } - - // Calculate attenuation. - vec3 attn = exp(-(kMie * (iOdMie + jOdMie) + kRlh * (iOdRlh + jOdRlh))); - - // Accumulate scattering. - totalRlh += odStepRlh * attn; - totalMie += odStepMie * attn; - - // Increment the primary ray time. - iTime += iStepSize; - - } - - // Calculate and return the final color. - return iSun * (pRlh * kRlh * totalRlh + pMie * kMie * totalMie); -} diff --git a/shaders/billboard.frag.glsl b/shaders/billboard.frag.glsl deleted file mode 100755 index 27ecec2..0000000 --- a/shaders/billboard.frag.glsl +++ /dev/null @@ -1,17 +0,0 @@ -layout (location = 0) in vec2 inUV; - -layout (location = 0) out vec4 outColor; - -layout(push_constant, binding = 1) uniform readonly PushConstant{ - mat4 mvp; - vec4 color; -}; - -layout (binding = 2) uniform sampler2D colorSampler; - -void main() { - if(inUV.y < 0.0 || inUV.x > 1.0) - discard; - - outColor = texture(colorSampler, inUV) * color; -} diff --git a/shaders/billboard.vert.glsl b/shaders/billboard.vert.glsl deleted file mode 100755 index da8fffc..0000000 --- a/shaders/billboard.vert.glsl +++ /dev/null @@ -1,25 +0,0 @@ -layout (location = 0) out vec2 outUV; - -layout(push_constant, binding = 1) uniform readonly PushConstant{ - mat4 mvp; - vec4 color; -}; - -layout(std430, binding = 3) buffer readonly SceneInformation { - mat4 view; -}; - -void main() { - vec2 p = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); - outUV = vec2(p.x, 1.0 - p.y); - - p = p * 2.0f + -1.0f; - - const vec3 right = {view[0][0], view[1][0], view[2][0]}; - const vec3 up = {view[0][1], view[1][1], view[2][1]}; - - vec3 position = right * p.x * 0.25 + up * p.y * 0.25; - - gl_Position = mvp * vec4(position, 1.0); -} - diff --git a/shaders/blend.frag.glsl b/shaders/blend.frag.glsl deleted file mode 100644 index 0c9b477..0000000 --- a/shaders/blend.frag.glsl +++ /dev/null @@ -1,16 +0,0 @@ -#define SMAA_INCLUDE_PS 1 -#include "smaa_common.glsl" - -layout(location = 0) in vec2 inUV; -layout(location = 1) in vec4 inOffset[3]; -layout(location = 5) in vec2 inPixUV; - -layout(location = 0) out vec4 outColor; - -layout(binding = 0) uniform sampler2D edgeSampler; -layout(binding = 1) uniform sampler2D areaSampler; -layout(binding = 3) uniform sampler2D searchSampler; - -void main() { - outColor = SMAABlendingWeightCalculationPS(inUV, inPixUV, inOffset, edgeSampler, areaSampler, searchSampler, ivec4(0)); -} diff --git a/shaders/blend.vert.glsl b/shaders/blend.vert.glsl deleted file mode 100644 index 076c6b6..0000000 --- a/shaders/blend.vert.glsl +++ /dev/null @@ -1,14 +0,0 @@ -#define SMAA_INCLUDE_VS 1 -#define SMAA_INCLUDE_PS 0 -#include "smaa_common.glsl" - -layout(location = 0) out vec2 outUV; -layout(location = 1) out vec4 outOffset[3]; -layout(location = 5) out vec2 outPixUV; - -void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); - gl_Position = correctionMatrix * vec4(outUV * 2.0 + -1.0, 0.0, 1.0); - - SMAABlendingWeightCalculationVS(outUV, outPixUV, outOffset); -} diff --git a/shaders/brdf.frag.glsl b/shaders/brdf.frag.glsl deleted file mode 100755 index 370ae90..0000000 --- a/shaders/brdf.frag.glsl +++ /dev/null @@ -1,48 +0,0 @@ -#include "common.nocompile.glsl" - -layout(location = 0) in vec2 inUV; - -layout(location = 0) out vec2 outColor; - -vec2 IntegrateBRDF(float NdotV, float roughness) { - vec3 V; - V.x = sqrt(1.0 - NdotV*NdotV); - V.y = 0.0; - V.z = NdotV; - - float A = 0.0; - float B = 0.0; - - const vec3 N = vec3(0.0, 0.0, 1.0); - - const uint SAMPLE_COUNT = 1024u; - for(uint i = 0u; i < SAMPLE_COUNT; ++i) { - // generates a sample vector that's biased towards the - // preferred alignment direction (importance sampling). - const vec2 Xi = hammersley(i, SAMPLE_COUNT); - const vec3 H = importance_sample_ggx(Xi, N, roughness); - const vec3 L = 2.0 * dot(V, H) * H - V; - - const float NdotL = max(L.z, 0.0); - const float NdotH = max(H.z, 0.0); - const float VdotH = max(dot(V, H), 0.0); - - if(NdotL > 0.0) { - const float G = geometry_smith(N, V, L, roughness); - const float G_Vis = (G * VdotH) / (NdotH * NdotV); - const float Fc = pow(1.0 - VdotH, 5.0); - - A += (1.0 - Fc) * G_Vis; - B += Fc * G_Vis; - } - } - - A /= float(SAMPLE_COUNT); - B /= float(SAMPLE_COUNT); - - return vec2(A, B); -} - -void main() { - outColor = IntegrateBRDF(inUV.x, inUV.y); -} diff --git a/shaders/brdf.vert.glsl b/shaders/brdf.vert.glsl deleted file mode 100755 index 113c0d4..0000000 --- a/shaders/brdf.vert.glsl +++ /dev/null @@ -1,6 +0,0 @@ -layout(location = 0) out vec2 outUV; - -void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); - gl_Position = vec4(outUV * 2.0 + -1.0, 0.0, 1.0); -} diff --git a/shaders/color.frag.glsl b/shaders/color.frag.glsl deleted file mode 100755 index 9cfa7ba..0000000 --- a/shaders/color.frag.glsl +++ /dev/null @@ -1,10 +0,0 @@ -layout (location = 0) out vec4 outColor; - -layout(push_constant, binding = 1) uniform PushConstant{ - mat4 mvp; - vec4 color; -}; - -void main() { - outColor = color; -} diff --git a/shaders/color.vert.glsl b/shaders/color.vert.glsl deleted file mode 100755 index ad0b093..0000000 --- a/shaders/color.vert.glsl +++ /dev/null @@ -1,10 +0,0 @@ -layout (location = 0) in vec3 inPosition; - -layout(push_constant, binding = 1) uniform PushConstant{ - mat4 mvp; - vec4 color; -}; - -void main() { - gl_Position = mvp * vec4(inPosition, 1.0); -} diff --git a/shaders/common.nocompile.glsl b/shaders/common.nocompile.glsl deleted file mode 100755 index 68129c5..0000000 --- a/shaders/common.nocompile.glsl +++ /dev/null @@ -1,161 +0,0 @@ -const float PI = 3.14159265359; -const float EPSILON = 0.005; - -const vec2 PoissonOffsets[64] = { - vec2(0.0617981, 0.07294159), - vec2(0.6470215, 0.7474022), - vec2(-0.5987766, -0.7512833), - vec2(-0.693034, 0.6913887), - vec2(0.6987045, -0.6843052), - vec2(-0.9402866, 0.04474335), - vec2(0.8934509, 0.07369385), - vec2(0.1592735, -0.9686295), - vec2(-0.05664673, 0.995282), - vec2(-0.1203411, -0.1301079), - vec2(0.1741608, -0.1682285), - vec2(-0.09369049, 0.3196758), - vec2(0.185363, 0.3213367), - vec2(-0.1493771, -0.3147511), - vec2(0.4452095, 0.2580113), - vec2(-0.1080467, -0.5329178), - vec2(0.1604507, 0.5460774), - vec2(-0.4037193, -0.2611179), - vec2(0.5947998, -0.2146744), - vec2(0.3276062, 0.9244621), - vec2(-0.6518704, -0.2503952), - vec2(-0.3580975, 0.2806469), - vec2(0.8587891, 0.4838005), - vec2(-0.1596546, -0.8791054), - vec2(-0.3096867, 0.5588146), - vec2(-0.5128918, 0.1448544), - vec2(0.8581337, -0.424046), - vec2(0.1562584, -0.5610626), - vec2(-0.7647934, 0.2709858), - vec2(-0.3090832, 0.9020988), - vec2(0.3935608, 0.4609676), - vec2(0.3929337, -0.5010948), - vec2(-0.8682281, -0.1990303), - vec2(-0.01973724, 0.6478714), - vec2(-0.3897587, -0.4665619), - vec2(-0.7416366, -0.4377831), - vec2(-0.5523247, 0.4272514), - vec2(-0.5325066, 0.8410385), - vec2(0.3085465, -0.7842533), - vec2(0.8400612, -0.200119), - vec2(0.6632416, 0.3067062), - vec2(-0.4462856, -0.04265022), - vec2(0.06892014, 0.812484), - vec2(0.5149567, -0.7502338), - vec2(0.6464897, -0.4666451), - vec2(-0.159861, 0.1038342), - vec2(0.6455986, 0.04419327), - vec2(-0.7445076, 0.5035095), - vec2(0.9430245, 0.3139912), - vec2(0.0349884, -0.7968109), - vec2(-0.9517487, 0.2963554), - vec2(-0.7304786, -0.01006928), - vec2(-0.5862702, -0.5531025), - vec2(0.3029106, 0.09497032), - vec2(0.09025345, -0.3503742), - vec2(0.4356628, -0.0710125), - vec2(0.4112572, 0.7500054), - vec2(0.3401214, -0.3047142), - vec2(-0.2192158, -0.6911137), - vec2(-0.4676369, 0.6570358), - vec2(0.6295372, 0.5629555), - vec2(0.1253822, 0.9892166), - vec2(-0.1154335, 0.8248222), - vec2(-0.4230408, -0.7129914) -}; - -// GGX/Trowbridge-Reitz Normal Distribution -float ggx_distribution(const vec3 N, const vec3 H, const float roughness) { - const float roughness_squared = roughness * roughness; - - const float NdotH = dot(N, H); - - const float denominator = (NdotH * NdotH) * (roughness_squared - 1.0) + 1.0; - - return roughness_squared / (PI * (denominator * denominator)); -} - -// Slick Geometry -float geometry_slick_direct(const vec3 N, const vec3 V, const float roughness) { - const float NdotV = clamp(dot(N, V), 0.0, 1.0); - const float denominator = NdotV * (1.0 - roughness) + roughness; - - return NdotV / denominator; -} - -// GGX Smith Geometry, using GGX slick but combining both the view direction and the light direction -float geometry_smith(const vec3 N, const vec3 V, const vec3 L, float roughness) { - const float dotNV = max(dot(N, V), 0.0); - const float dotNL = max(dot(N, L), 0.0); - - const float k = (roughness * roughness) / 2.0; - const float GL = dotNL / (dotNL * (1.0 - k) + k); - const float GV = dotNV / (dotNV * (1.0 - k) + k); - - return GL * GV; -} - -// Fresnel Shlick -vec3 fresnel_schlick(const float cos_theta, const vec3 F0) { - return F0 + (1.0 - F0) * pow(1.0 - cos_theta, 5.0); -} - -vec3 fresnel_schlick_roughness(float cosTheta, vec3 F0, float roughness) { - return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0); -} - -// efficient VanDerCorpus calculation from http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html -float radical_inverse(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; -} - -vec2 hammersley(const uint i, const uint N) { - return vec2(float(i) / float(N), radical_inverse(i)); -} - -vec3 importance_sample_ggx(const vec2 Xi, const vec3 N, const float roughness) { - const float a = roughness*roughness; - - const float phi = 2.0 * PI * Xi.x; - const float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y)); - const float sinTheta = sqrt(1.0 - cosTheta*cosTheta); - - // from spherical coordinates to cartesian coordinates - halfway vector - vec3 H; - H.x = cos(phi) * sinTheta; - H.y = sin(phi) * sinTheta; - H.z = cosTheta; - - // from tangent-space H vector to world-space sample vector - const vec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); - const vec3 tangent = normalize(cross(up, N)); - const vec3 bitangent = cross(N, tangent); - - return normalize(tangent * H.x + bitangent * H.y + N * H.z); -} - -vec3 from_linear_to_srgb(const vec3 linearRGB) { - bvec3 cutoff = lessThan(linearRGB, vec3(0.0031308)); - vec3 higher = vec3(1.055)*pow(linearRGB, vec3(1.0/2.4)) - vec3(0.055); - vec3 lower = linearRGB * vec3(12.92); - - return mix(higher, lower, cutoff); -} - -vec3 from_srgb_to_linear(const vec3 sRGB) { - bvec3 cutoff = lessThan(sRGB, vec3(0.04045)); - vec3 higher = pow((sRGB + vec3(0.055))/vec3(1.055), vec3(2.4)); - vec3 lower = sRGB/vec3(12.92); - - return mix(higher, lower, cutoff); -} diff --git a/shaders/debug.frag.glsl b/shaders/debug.frag.glsl deleted file mode 100755 index 157b36b..0000000 --- a/shaders/debug.frag.glsl +++ /dev/null @@ -1,10 +0,0 @@ -layout(location = 0) out vec4 outColor; - -layout(push_constant, binding = 1) uniform PushConstant { - mat4 mvp; - vec4 color; -}; - -void main() { - outColor = color; -} diff --git a/shaders/debug.vert.glsl b/shaders/debug.vert.glsl deleted file mode 100755 index ad0b093..0000000 --- a/shaders/debug.vert.glsl +++ /dev/null @@ -1,10 +0,0 @@ -layout (location = 0) in vec3 inPosition; - -layout(push_constant, binding = 1) uniform PushConstant{ - mat4 mvp; - vec4 color; -}; - -void main() { - gl_Position = mvp * vec4(inPosition, 1.0); -} diff --git a/shaders/dof.frag.glsl b/shaders/dof.frag.glsl deleted file mode 100644 index e147b5a..0000000 --- a/shaders/dof.frag.glsl +++ /dev/null @@ -1,28 +0,0 @@ -layout(location = 0) in vec2 inUV; -layout(location = 1) in flat ivec2 inPixel; -layout(location = 2) in float depth; - -layout(location = 0) out vec4 outColor; - -layout(rgba32f, binding = 0) uniform image2D color_sampler; -layout(binding = 3) uniform sampler2D aperture_sampler; - -layout(push_constant, binding = 2) uniform readonly PushConstant{ - vec4 params; -}; - -void main() { - // far field mode - if(params.y == 0) { - if(depth < 0.98) - discard; - } - - if(inUV.y > 1.0 || inUV.x > 1.0) - discard; - - outColor = vec4(imageLoad(color_sampler, inPixel).rgb, 1.0); - if(params.y == 0) { - outColor = outColor * texture(aperture_sampler, inUV); - } -} diff --git a/shaders/dof.vert.glsl b/shaders/dof.vert.glsl deleted file mode 100644 index 8024370..0000000 --- a/shaders/dof.vert.glsl +++ /dev/null @@ -1,35 +0,0 @@ -layout(constant_id = 0) const int width = 25; -layout(constant_id = 1) const int height = 25; - -layout(location = 0) out vec2 outUV; -layout(location = 1) out flat ivec2 outPixel; -layout(location = 2) out float outDepth; - -layout(binding = 1) uniform sampler2D depth_sampler; - -layout(push_constant, binding = 2) uniform readonly PushConstant{ - vec4 params; -}; - -void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); - - ivec2 pixel = ivec2(gl_InstanceIndex % width, gl_InstanceIndex / width); - outPixel = pixel; - - const float depth = texture(depth_sampler, vec2(pixel) / vec2(width, height)).r; - outDepth = depth; - - vec2 pos = vec2(outUV * 2.0 + -1.0); - - // far field mode - if(params.y == 0) { - pos *= params.x * depth; - } - - pos += vec2(pixel.x, pixel.y); - pos *= 2.0 / vec2(width, height); - pos += vec2(-1, -1); - - gl_Position = vec4(pos.x, pos.y, 0.0, 1.0); -} diff --git a/shaders/edge.frag.glsl b/shaders/edge.frag.glsl deleted file mode 100644 index 5f58c5f..0000000 --- a/shaders/edge.frag.glsl +++ /dev/null @@ -1,16 +0,0 @@ -#define SMAA_INCLUDE_PS 1 -#include "smaa_common.glsl" - -layout(location = 0) in vec2 inUV; -layout(location = 1) in vec4 inOffset[3]; - -layout(location = 0) out vec4 outColor; - -layout(binding = 0) uniform sampler2D imageSampler; -layout(binding = 1) uniform sampler2D depthSampler; - -void main() { - vec2 edge = SMAALumaEdgeDetectionPS(inUV, inOffset, imageSampler, depthSampler); - - outColor = vec4(edge, 0.0, 1.0); -} diff --git a/shaders/edge.vert.glsl b/shaders/edge.vert.glsl deleted file mode 100644 index 57b3973..0000000 --- a/shaders/edge.vert.glsl +++ /dev/null @@ -1,13 +0,0 @@ -#define SMAA_INCLUDE_VS 1 -#define SMAA_INCLUDE_PS 0 -#include "smaa_common.glsl" - -layout(location = 0) out vec2 outUV; -layout(location = 1) out vec4 outOffset[3]; - -void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); - gl_Position = correctionMatrix * vec4(outUV * 2.0 + -1.0, 0.0, 1.0); - - SMAAEdgeDetectionVS(outUV, outOffset); -} diff --git a/shaders/filter.frag.glsl b/shaders/filter.frag.glsl deleted file mode 100755 index 37241a3..0000000 --- a/shaders/filter.frag.glsl +++ /dev/null @@ -1,51 +0,0 @@ -#include "common.nocompile.glsl" - -layout (constant_id = 0) const int texture_size = 512; - -layout(location = 0) in vec3 inPos; -layout(location = 0) out vec4 outColor; - -layout(binding = 2) uniform samplerCube environmentSampler; - -layout(push_constant, binding = 1) uniform readonly PushConstant{ - mat4 mvp; - float roughness; -}; - -void main() { - vec3 N = normalize(inPos); - - // make the simplyfying assumption that V equals R equals the normal - const vec3 R = N; - const vec3 V = R; - - const uint SAMPLE_COUNT = 1024u; - vec3 prefilteredColor = vec3(0.0); - float totalWeight = 0.0; - - for(uint i = 0u; i < SAMPLE_COUNT; ++i) { - // generates a sample vector that's biased towards the preferred alignment direction (importance sampling). - const vec2 Xi = hammersley(i, SAMPLE_COUNT); - const vec3 H = importance_sample_ggx(Xi, N, roughness); - const vec3 L = normalize(2.0 * dot(V, H) * H - V); - - float NdotL = max(dot(N, L), 0.0); - if(NdotL > 0.0) { - // sample from the environment's mip level based on roughness/pdf - const float D = geometry_slick_direct(N, H, roughness); - const float NdotH = max(dot(N, H), 0.0); - const float HdotV = max(dot(H, V), 0.0); - const float pdf = D * NdotH / (4.0 * HdotV) + 0.0001; - - const float saTexel = 4.0 * PI / (6.0 * texture_size * texture_size); - const float saSample = 1.0 / (float(SAMPLE_COUNT) * pdf + 0.0001); - - const float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel); - - prefilteredColor += textureLod(environmentSampler, L, mipLevel).rgb * NdotL; - totalWeight += NdotL; - } - } - - outColor = vec4(prefilteredColor / totalWeight, 1.0); -} diff --git a/shaders/filter.vert.glsl b/shaders/filter.vert.glsl deleted file mode 100755 index d213b6d..0000000 --- a/shaders/filter.vert.glsl +++ /dev/null @@ -1,13 +0,0 @@ -layout(location = 0) in vec3 inPosition; - -layout(location = 0) out vec3 outPos; - -layout(push_constant, binding = 1) uniform readonly PushConstant{ - mat4 mvp; - float roughness; -}; - -void main() { - gl_Position = mvp * vec4(inPosition, 1.0); - outPos = inPosition; -} diff --git a/shaders/font.glsl b/shaders/font.glsl deleted file mode 100755 index dbe02fa..0000000 --- a/shaders/font.glsl +++ /dev/null @@ -1,5 +0,0 @@ -uint getLower(const uint val) { return val & uint(0xFFFF); } -uint getUpper(const uint val) { return val >> 16 & uint(0xFFFF); } -float fixed_to_float(const uint val) { return float(val)/32.0; } -vec2 fixed2_to_vec2(const uint val) { return vec2(fixed_to_float(getLower(val)), fixed_to_float(getUpper(val))); } -vec2 uint_to_vec2(const uint val) { return vec2(getLower(val), getUpper(val)); } diff --git a/shaders/gaussian.frag.glsl b/shaders/gaussian.frag.glsl deleted file mode 100644 index 7390260..0000000 --- a/shaders/gaussian.frag.glsl +++ /dev/null @@ -1,34 +0,0 @@ -layout (location = 0) in vec2 inUV; - -layout (location = 0) out vec4 outColor; - -layout(push_constant, binding = 1) uniform PushConstants { - int horizontal; -}; - -layout (binding = 0) uniform sampler2D image; - -const float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216); - -void main() { - vec2 tex_offset = 1.0 / textureSize(image, 0); // gets size of single texel - vec3 result = texture(image, inUV).rgb * weight[0]; // current fragment's contribution - if(horizontal == 1) - { - for(int i = 1; i < 5; ++i) - { - result += max(texture(image, inUV + vec2(tex_offset.x * i, 0.0)).rgb * weight[i], vec3(0.0)); - result += max(texture(image, inUV - vec2(tex_offset.x * i, 0.0)).rgb * weight[i], vec3(0.0)); - } - } - else - { - for(int i = 1; i < 5; ++i) - { - result += max(texture(image, inUV + vec2(0.0, tex_offset.y * i)).rgb * weight[i], vec3(0.0)); - result += max(texture(image, inUV - vec2(0.0, tex_offset.y * i)).rgb * weight[i], vec3(0.0)); - } - } - - outColor = vec4(result, 1.0); -} diff --git a/shaders/gaussian.vert.glsl b/shaders/gaussian.vert.glsl deleted file mode 100644 index 71efeb2..0000000 --- a/shaders/gaussian.vert.glsl +++ /dev/null @@ -1,6 +0,0 @@ -layout (location = 0) out vec2 outUV; - -void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); - gl_Position = vec4(outUV * 2.0f + -1.0f, 0.0f, 1.0f); -} diff --git a/shaders/histogram-average.comp.glsl b/shaders/histogram-average.comp.glsl deleted file mode 100755 index 0531c8a..0000000 --- a/shaders/histogram-average.comp.glsl +++ /dev/null @@ -1,44 +0,0 @@ -#include "common.nocompile.glsl" - -layout(local_size_x = 256, local_size_y = 1) in; - -layout(r16f, binding = 0) uniform image2D target_image; - -// adapated from https://bruop.github.io/exposure/ and http://www.alextardif.com/HistogramLuminance.html - -shared uint histogram_shared[256]; - -layout(std430, binding = 1) buffer HistogramBuffer { - uint histogram[]; -}; - -layout(push_constant, binding = 2) uniform readonly PushConstant{ - vec4 params; -}; - -void main() { - uint count_for_this_bin = histogram[gl_LocalInvocationIndex]; - histogram_shared[gl_LocalInvocationIndex] = count_for_this_bin * gl_LocalInvocationIndex; - - groupMemoryBarrier(); - - histogram[gl_LocalInvocationIndex] = 0; - - for(uint cutoff = (256 >> 1); cutoff > 0; cutoff >>= 1) { - if(uint(gl_LocalInvocationIndex) < cutoff) { - histogram_shared[gl_LocalInvocationIndex] += histogram_shared[gl_LocalInvocationIndex + cutoff]; - } - - groupMemoryBarrier(); - } - - if(gl_LocalInvocationIndex == 0) { - float weightedLogAverage = (histogram_shared[0] / max(params.w - float(count_for_this_bin), 1.0)) - 1.0; - - float weightedAvgLum = exp2(weightedLogAverage / 254.0 * params.y + params.x); - - float lumLastFrame = imageLoad(target_image, ivec2(0, 0)).x; - float adaptedLum = lumLastFrame + (weightedAvgLum - lumLastFrame) * params.z; - imageStore(target_image, ivec2(0, 0), vec4(adaptedLum, 0.0, 0.0, 0.0)); - } -} diff --git a/shaders/histogram.comp.glsl b/shaders/histogram.comp.glsl deleted file mode 100755 index abeff53..0000000 --- a/shaders/histogram.comp.glsl +++ /dev/null @@ -1,49 +0,0 @@ -#include "common.nocompile.glsl" - -layout(local_size_x = 16, local_size_y = 16) in; - -layout(rgba32f, binding = 0) uniform image2D hdr_image; - -// adapated from https://bruop.github.io/exposure/ and http://www.alextardif.com/HistogramLuminance.html - -// Taken from RTR vol 4 pg. 278 -#define RGB_TO_LUM vec3(0.2125, 0.7154, 0.0721) - -shared uint histogram_shared[256]; - -layout(std430, binding = 1) buffer HistogramBuffer { - uint histogram[]; -}; - -layout(push_constant, binding = 2) uniform readonly PushConstant{ - vec4 params; -}; - -uint color_to_bin(const vec3 hdr_color, const float min_log_lum, const float inverse_log_lum_range) { - const float lum = dot(hdr_color, RGB_TO_LUM); - - if (lum < EPSILON) { - return 0; - } - - const float log_lum = clamp((log2(lum) - min_log_lum) * inverse_log_lum_range, 0.0, 1.0); - - return uint(log_lum * 254.0 + 1.0); -} - -void main() { - histogram_shared[gl_LocalInvocationIndex] = 0; - groupMemoryBarrier(); - - uvec2 dim = uvec2(params.zw); - if(gl_GlobalInvocationID.x < dim.x && gl_GlobalInvocationID.y < dim.y) { - vec3 hdr_color = imageLoad(hdr_image, ivec2(gl_GlobalInvocationID.xy)).rgb; - uint bin_index = color_to_bin(hdr_color, params.x, params.y); - - atomicAdd(histogram_shared[bin_index], 1); - } - - groupMemoryBarrier(); - - atomicAdd(histogram[gl_LocalInvocationIndex], histogram_shared[gl_LocalInvocationIndex]); -} diff --git a/shaders/imgui.frag.glsl b/shaders/imgui.frag.glsl deleted file mode 100755 index 3db777c..0000000 --- a/shaders/imgui.frag.glsl +++ /dev/null @@ -1,10 +0,0 @@ -layout(location = 0) in vec4 in_color; -layout(location = 1) in vec2 in_uv; - -layout(location = 0) out vec4 out_color; - -layout(binding = 2) uniform sampler2D bound_texture; - -void main() { - out_color = in_color * texture(bound_texture, in_uv); -} diff --git a/shaders/imgui.vert.glsl b/shaders/imgui.vert.glsl deleted file mode 100755 index ead22e0..0000000 --- a/shaders/imgui.vert.glsl +++ /dev/null @@ -1,16 +0,0 @@ -layout(location = 0) in vec2 in_position; -layout(location = 1) in vec2 in_uv; -layout(location = 2) in vec4 in_color; - -layout(location = 0) out vec4 out_color; -layout(location = 1) out vec2 out_uv; - -layout(std430, push_constant, binding = 1) uniform PushConstant { - mat4 projection; -}; - -void main() { - gl_Position = projection * vec4(in_position, 0.0, 1.0); - out_color = in_color; - out_uv = in_uv; -} diff --git a/shaders/irradiance.frag.glsl b/shaders/irradiance.frag.glsl deleted file mode 100755 index 1cceff7..0000000 --- a/shaders/irradiance.frag.glsl +++ /dev/null @@ -1,36 +0,0 @@ -layout(location = 0) in vec3 inPos; -layout(location = 0) out vec4 outColor; - -layout(binding = 2) uniform samplerCube environmentSampler; - -const float PI = 3.14159265359; - -void main() { - vec3 N = normalize(inPos); - - vec3 irradiance = vec3(0.0); - - // tangent space calculation from origin point - vec3 up = vec3(0.0, 1.0, 0.0); - vec3 right = cross(up, N); - up = cross(N, right); - - float sampleDelta = 0.025; - float nrSamples = 0.0f; - for(float phi = 0.0; phi < 2.0 * PI; phi += sampleDelta) - { - for(float theta = 0.0; theta < 0.5 * PI; theta += sampleDelta) - { - // spherical to cartesian (in tangent space) - vec3 tangentSample = vec3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)); - // tangent space to world - vec3 sampleVec = tangentSample.x * right + tangentSample.y * up + tangentSample.z * N; - - irradiance += texture(environmentSampler, sampleVec).rgb * cos(theta) * sin(theta); - nrSamples++; - } - } - irradiance = PI * irradiance * (1.0 / float(nrSamples)); - - outColor = vec4(irradiance, 1.0); -} diff --git a/shaders/irradiance.vert.glsl b/shaders/irradiance.vert.glsl deleted file mode 100755 index c1947fa..0000000 --- a/shaders/irradiance.vert.glsl +++ /dev/null @@ -1,12 +0,0 @@ -layout(location = 0) in vec3 inPosition; - -layout(location = 0) out vec3 outPos; - -layout(push_constant, binding = 1) uniform readonly PushConstant{ - mat4 mvp; -}; - -void main() { - gl_Position = mvp * vec4(inPosition, 1.0); - outPos = inPosition; -} diff --git a/shaders/mesh.vert.nocompile.glsl b/shaders/mesh.vert.nocompile.glsl deleted file mode 100755 index 76aa7fc..0000000 --- a/shaders/mesh.vert.nocompile.glsl +++ /dev/null @@ -1,123 +0,0 @@ -layout (constant_id = 0) const int max_materials = 25; -layout (constant_id = 1) const int max_lights = 25; -layout (constant_id = 2) const int max_spot_lights = 4; -layout (constant_id = 3) const int max_probes = 4; - -layout (location = 0) in vec3 inPosition; -layout (location = 1) in vec3 inNormal; -layout (location = 2) in vec2 inUV; -layout (location = 3) in vec3 inTangent; -layout (location = 4) in vec3 inBitangent; - -#ifdef BONE -layout (location = 5) in ivec4 inBoneID; -layout (location = 6) in vec4 inBoneWeight; -#endif - -layout (location = 0) out vec3 outFragPos; -layout (location = 1) out vec3 outNormal; -layout (location = 2) out vec2 outUV; -layout (location = 4) out vec4 fragPosLightSpace; -layout (location = 5) out mat3 outTBN; -layout (location = 14) out vec4 fragPostSpotLightSpace[max_spot_lights]; - -struct Material { - vec4 color, info; -}; - -struct Light { - vec4 positionType; - vec4 directionPower; - vec4 color; -}; - -struct Probe { - vec4 position, size; -}; - -layout(std430, binding = 1) buffer readonly SceneInformation { - vec4 options; - vec4 camPos; - mat4 vp, lightSpace; - mat4 spotLightSpaces[max_spot_lights]; - Material materials[max_materials]; - Light lights[max_lights]; - Probe probes[max_probes]; - int numLights; -} scene; - -#ifdef CUBEMAP -layout(push_constant, binding = 0) uniform readonly PushConstant{ - mat4 model, view; -}; -#else -layout(push_constant, binding = 0) uniform readonly PushConstant{ - mat4 model; -}; -#endif - -const mat4 biasMat = mat4( - 0.5, 0.0, 0.0, 0.0, - 0.0, 0.5, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.5, 0.5, 0.0, 1.0); - -#ifdef BONE -layout(std430, binding = 14) buffer readonly BoneInformation { - mat4 bones[128]; -}; -#endif - -void main() { - const mat3 mat = mat3(model); - const vec3 T = normalize(mat * inTangent); - const vec3 N = normalize(mat * inNormal); - const vec3 B = normalize(mat * inBitangent); - const mat3 TBN = mat3(T, B, N); - -#ifdef BONE - mat4 BoneTransform = bones[inBoneID[0]] * inBoneWeight[0]; - BoneTransform += bones[inBoneID[1]] * inBoneWeight[1]; - BoneTransform += bones[inBoneID[2]] * inBoneWeight[2]; - BoneTransform += bones[inBoneID[3]] * inBoneWeight[3]; - - BoneTransform = model * BoneTransform; - - vec4 bPos = BoneTransform * vec4(inPosition, 1.0); - vec4 bNor = BoneTransform * vec4(inNormal, 0.0); - - gl_Position = scene.vp * bPos; - outFragPos = vec3(model * vec4(inPosition, 1.0)); - outNormal = bNor.xyz; - outUV = inUV; - fragPosLightSpace = (biasMat * scene.lightSpace) * bPos; - - for(int i = 0; i < max_spot_lights; i++) { - fragPostSpotLightSpace[i] = (biasMat * scene.spotLightSpaces[i]) * bPos; - } -#else -#ifdef CUBEMAP - gl_Position = scene.vp * view * model * vec4(inPosition, 1.0); - outFragPos = vec3(model * vec4(inPosition, 1.0)); - outNormal = mat3(model) * inNormal; - outUV = inUV; - fragPosLightSpace = (biasMat * scene.lightSpace * model) * vec4(inPosition, 1.0); - - for(int i = 0; i < max_spot_lights; i++) { - fragPostSpotLightSpace[i] = (biasMat * scene.spotLightSpaces[i] * model) * vec4(inPosition, 1.0); - } -#else - gl_Position = scene.vp * model * vec4(inPosition, 1.0); - - outFragPos = vec3(model * vec4(inPosition, 1.0)); - outNormal = mat3(model) * inNormal; - outUV = inUV; - fragPosLightSpace = (biasMat * scene.lightSpace * model) * vec4(inPosition, 1.0); - - for(int i = 0; i < max_spot_lights; i++) { - fragPostSpotLightSpace[i] = (biasMat * scene.spotLightSpaces[i] * model) * vec4(inPosition, 1.0); - } -#endif -#endif - outTBN = TBN; -} diff --git a/shaders/omnishadow.frag.glsl b/shaders/omnishadow.frag.glsl deleted file mode 100755 index 61e4d2c..0000000 --- a/shaders/omnishadow.frag.glsl +++ /dev/null @@ -1,14 +0,0 @@ -layout (constant_id = 0) const int max_lights = 25; - -layout (location = 0) in vec3 inPos; -layout (location = 1) flat in int index; - -layout (location = 0) out float outFragColor; - -layout(std430, binding = 2) buffer readonly LightInformation { - vec3 light_locations[max_lights]; -}; - -void main() { - outFragColor = length(inPos - light_locations[index]); -} diff --git a/shaders/post.frag.glsl b/shaders/post.frag.glsl deleted file mode 100755 index 1d5026d..0000000 --- a/shaders/post.frag.glsl +++ /dev/null @@ -1,159 +0,0 @@ -#define SMAA_RT_METRICS viewport - -#define SMAA_PRESET_ULTRA 1 -#define SMAA_GLSL_4 1 -#define SMAA_INCLUDE_VS 0 -#define SMAA_INCLUDE_PS 1 - -layout(std430, push_constant, binding = 4) uniform PushConstant { - vec4 viewport; - vec4 options; - vec4 transform_ops; -}; - -#include "smaa.glsl" -#include "common.nocompile.glsl" - -layout (location = 0) in vec2 inUV; -layout(location = 1) in vec4 inOffset; - -layout (location = 0) out vec4 outColor; - -layout (binding = 1) uniform sampler2D colorSampler; -layout (binding = 2) uniform sampler2D backSampler; -layout (binding = 3) uniform sampler2D blendSampler; -layout (binding = 5) uniform sampler2D sobelSampler; -layout (binding = 6) uniform sampler2D averageLuminanceSampler; -layout (binding = 7) uniform sampler2D farFieldSampler; - -float calculate_sobel() { - float x = 1.0 / viewport.z; - float y = 1.0 / viewport.w; - vec4 horizEdge = vec4( 0.0 ); - horizEdge -= texture( sobelSampler, vec2( inUV.x - x, inUV.y - y ) ) * 1.0; - horizEdge -= texture( sobelSampler, vec2( inUV.x - x, inUV.y ) ) * 2.0; - horizEdge -= texture( sobelSampler, vec2( inUV.x - x, inUV.y + y ) ) * 1.0; - horizEdge += texture( sobelSampler, vec2( inUV.x + x, inUV.y - y ) ) * 1.0; - horizEdge += texture( sobelSampler, vec2( inUV.x + x, inUV.y ) ) * 2.0; - horizEdge += texture( sobelSampler, vec2( inUV.x + x, inUV.y + y ) ) * 1.0; - vec4 vertEdge = vec4( 0.0 ); - vertEdge -= texture( sobelSampler, vec2( inUV.x - x, inUV.y - y ) ) * 1.0; - vertEdge -= texture( sobelSampler, vec2( inUV.x , inUV.y - y ) ) * 2.0; - vertEdge -= texture( sobelSampler, vec2( inUV.x + x, inUV.y - y ) ) * 1.0; - vertEdge += texture( sobelSampler, vec2( inUV.x - x, inUV.y + y ) ) * 1.0; - vertEdge += texture( sobelSampler, vec2( inUV.x , inUV.y + y ) ) * 2.0; - vertEdge += texture( sobelSampler, vec2( inUV.x + x, inUV.y + y ) ) * 1.0; - return sqrt((horizEdge.rgb * horizEdge.rgb) + (vertEdge.rgb * vertEdge.rgb)).r; -} - -// adapted from https://bruop.github.io/exposure/ - -vec3 convertRGB2XYZ(vec3 _rgb) -{ - // Reference: - // RGB/XYZ Matrices - // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html - vec3 xyz; - xyz.x = dot(vec3(0.4124564, 0.3575761, 0.1804375), _rgb); - xyz.y = dot(vec3(0.2126729, 0.7151522, 0.0721750), _rgb); - xyz.z = dot(vec3(0.0193339, 0.1191920, 0.9503041), _rgb); - return xyz; -} - -vec3 convertXYZ2RGB(vec3 _xyz) -{ - vec3 rgb; - rgb.x = dot(vec3( 3.2404542, -1.5371385, -0.4985314), _xyz); - rgb.y = dot(vec3(-0.9692660, 1.8760108, 0.0415560), _xyz); - rgb.z = dot(vec3( 0.0556434, -0.2040259, 1.0572252), _xyz); - return rgb; -} - -vec3 convertXYZ2Yxy(vec3 _xyz) -{ - // Reference: - // http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_xyY.html - float inv = 1.0/dot(_xyz, vec3(1.0, 1.0, 1.0) ); - return vec3(_xyz.y, _xyz.x*inv, _xyz.y*inv); -} - -vec3 convertYxy2XYZ(vec3 _Yxy) -{ - // Reference: - // http://www.brucelindbloom.com/index.html?Eqn_xyY_to_XYZ.html - vec3 xyz; - xyz.x = _Yxy.x*_Yxy.y/_Yxy.z; - xyz.y = _Yxy.x; - xyz.z = _Yxy.x*(1.0 - _Yxy.y - _Yxy.z)/_Yxy.z; - return xyz; -} - -vec3 convertRGB2Yxy(vec3 _rgb) -{ - return convertXYZ2Yxy(convertRGB2XYZ(_rgb) ); -} - -vec3 convertYxy2RGB(vec3 _Yxy) -{ - return convertXYZ2RGB(convertYxy2XYZ(_Yxy) ); -} - -float reinhard2(float _x, float _whiteSqr) -{ - return (_x * (1.0 + _x/_whiteSqr) ) / (1.0 + _x); -} - -void main() { - // passthrough - if(options.w == 1) { - outColor = texture(colorSampler, inUV); - return; - } - - bool enable_dof = options.w == 2; - vec3 sceneColor = vec3(0); - if(enable_dof) { - sceneColor = texture(farFieldSampler, inUV).rgb; - sceneColor += texture(colorSampler, inUV).rgb; - } else { - if(options.x == 1) // enable AA - sceneColor = SMAANeighborhoodBlendingPS(inUV, inOffset, colorSampler, blendSampler).rgb; - else - sceneColor = texture(colorSampler, inUV).rgb; - } - - float sobel = 0.0; - if(textureSize(sobelSampler, 0).x > 1) - sobel = calculate_sobel(); - - vec3 sobelColor = vec3(0, 1, 1); - - vec3 hdrColor = sceneColor; // fading removed - - float avg_lum = texture(averageLuminanceSampler, inUV).r; - - vec3 transformed_color = hdrColor; - - if(transform_ops.y == 1) { - transformed_color = vec3(1.0) - exp(-transformed_color * options.z); - } else if(transform_ops.y == 2) { - vec3 Yxy = convertRGB2Yxy(transformed_color); - - // hard-coded for now - float whitePoint = 4.0; - - float lp = Yxy.x / (9.6 * avg_lum + 0.0001); - - // Replace this line with other tone mapping functions - // Here we applying the curve to the luminance exclusively - Yxy.x = reinhard2(lp, whitePoint); - - transformed_color = convertYxy2RGB(Yxy); - } - - if(transform_ops.x == 1) { - transformed_color = from_linear_to_srgb(transformed_color); - } - - outColor = vec4(transformed_color + (sobelColor * sobel), 1.0); -} diff --git a/shaders/post.vert.glsl b/shaders/post.vert.glsl deleted file mode 100755 index 3a38dbe..0000000 --- a/shaders/post.vert.glsl +++ /dev/null @@ -1,25 +0,0 @@ -#define SMAA_RT_METRICS viewport - -#define SMAA_PRESET_ULTRA 1 -#define SMAA_GLSL_4 1 -#define SMAA_INCLUDE_VS 1 -#define SMAA_INCLUDE_PS 0 - -layout(std430, push_constant, binding = 4) uniform readonlPushConstant { - vec4 viewport; - float fade; - vec4 transform_ops; -}; - -#include "smaa.glsl" - -layout (location = 0) out vec2 outUV; -layout(location = 1) out vec4 outOffset; - -void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); - gl_Position = vec4(outUV * 2.0f + -1.0f, 0.0f, 1.0f); - outUV.y = 1.0 - outUV.y; - - SMAANeighborhoodBlendingVS(outUV, outOffset); -} diff --git a/shaders/rendering.nocompile.glsl b/shaders/rendering.nocompile.glsl deleted file mode 100755 index 966ac03..0000000 --- a/shaders/rendering.nocompile.glsl +++ /dev/null @@ -1,305 +0,0 @@ -struct ComputedSurfaceInfo { - vec3 N; - vec3 V; - vec3 F0, diffuse_color; - - float NdotV; - - float roughness, metallic; -}; - -ComputedSurfaceInfo compute_surface(const vec3 diffuse, const vec3 normal, const float metallic, const float roughness) { - ComputedSurfaceInfo info; - - info.N = normalize(normal); - info.V = normalize(scene.camPos.xyz - in_frag_pos); - info.NdotV = max(dot(info.N, info.V), 0.0); - - info.metallic = metallic; - info.roughness = max(0.0001, roughness); - - info.F0 = 0.16 * (1.0 - info.metallic) + diffuse * info.metallic; - info.diffuse_color = (1.0 - info.metallic) * diffuse; - - return info; -} - -struct SurfaceBRDF { - vec3 diffuse, specular; - float NdotL; -}; - -SurfaceBRDF brdf(const vec3 L, const ComputedSurfaceInfo surface_info) { - SurfaceBRDF info; - - // half-vector - const vec3 H = normalize(surface_info.V + L); - - // fresnel reflectance function - const vec3 F = fresnel_schlick(surface_info.NdotV, surface_info.F0); - - // geometry function - const float D = ggx_distribution(surface_info.N, H, surface_info.roughness); - - // normal distribution function - const float G = geometry_smith(surface_info.N, surface_info.V, L, surface_info.roughness); - - const vec3 numerator = F * G * D; - const float denominator = 4.0 * surface_info.NdotV * clamp(dot(surface_info.N, L), 0.0, 1.0); - - // cook-torrance specular brdf - info.specular = numerator / (denominator + 0.001); - - // lambertian diffuse - info.diffuse = surface_info.diffuse_color * (1.0 / PI); - - info.NdotL = clamp(dot(surface_info.N, L), 0.0, 1.0); - - return info; -} - -struct ComputedLightInformation { - vec3 direction; - float radiance; -}; - -float pcf_sun(const vec4 shadowCoords, const float uvRadius) { - float sum = 0; - for(int i = 0; i < 16; i++) { - const float z = texture(sun_shadow, shadowCoords.xy + PoissonOffsets[i] * uvRadius).r; - sum += (z < (shadowCoords.z - 0.005)) ? 0.0 : 1.0; - } - - return sum / 16; -} - -#ifdef SHADOW_FILTER_PCSS -float search_width(const float uvLightSize, const float receiverDistance) { - return uvLightSize * (receiverDistance - 0.1f) / receiverDistance; -} - -float penumbra_size(const float zReceiver, const float zBlocker) { - return (zReceiver - zBlocker) / zBlocker; -} - -const int numBlockerSearchSamples = 16; - -void blocker_distance_sun(const vec3 shadowCoords, const float uvLightSize, inout float avgBlockerDistance, inout int blockers) { - const float searchWidth = search_width(uvLightSize, shadowCoords.z); - - float blockerSum = 0.0; - blockers = 0; - - for(int i = 0; i < numBlockerSearchSamples; i++) { - const float z = texture(sun_shadow, - shadowCoords.xy + PoissonOffsets[i] * searchWidth).r; - if(z < shadowCoords.z) { - blockerSum += z; - blockers++; - } - } - - avgBlockerDistance = blockerSum / blockers; -} - -float pcss_sun(const vec4 shadowCoords, float light_size_uv) { - float average_blocker_depth = 0.0; - int num_blockers = 0; - blocker_distance_sun(shadowCoords.xyz, light_size_uv, average_blocker_depth, num_blockers); - if(num_blockers < 1) - return 1.0; - - const float penumbraWidth = penumbra_size(-shadowCoords.z, average_blocker_depth); - - const float uvRadius = penumbraWidth * light_size_uv * 0.1 / shadowCoords.z; - return pcf_sun(shadowCoords, uvRadius); -} -#endif - -ComputedLightInformation calculate_sun(Light light) { - ComputedLightInformation light_info; - light_info.direction = normalize(light.positionType.xyz - vec3(0)); - - float shadow = 1.0; - if(light.shadowsEnable.x == 1.0) { - const vec4 shadowCoords = fragPosLightSpace / fragPosLightSpace.w; - - if(shadowCoords.z > -1.0 && shadowCoords.z < 1.0) { -#ifdef SHADOW_FILTER_NONE - shadow = (texture(sun_shadow, shadowCoords.xy).r < shadowCoords.z - 0.005) ? 0.0 : 1.0; -#endif -#ifdef SHADOW_FILTER_PCF - shadow = pcf_sun(shadowCoords, 0.1); -#endif -#ifdef SHADOW_FILTER_PCSS - shadow = pcss_sun(shadowCoords, light.shadowsEnable.y); -#endif - } - } - - light_info.radiance = light.directionPower.w * shadow; - - return light_info; -} - -float pcf_spot(const vec4 shadowCoords, const int index, const float uvRadius) { - float sum = 0; - for(int i = 0; i < 16; i++) { - const float z = texture(spot_shadow, vec3(shadowCoords.xy + PoissonOffsets[i] * uvRadius, index)).r; - sum += (z < (shadowCoords.z - 0.001)) ? 0.0 : 1.0; - } - - return sum / 16; -} - -#ifdef SHADOW_FILTER_PCSS -void blocker_distance_spot(const vec3 shadowCoords, const int index, const float uvLightSize, inout float avgBlockerDistance, inout int blockers) { - const float searchWidth = search_width(uvLightSize, shadowCoords.z); - - float blockerSum = 0.0; - blockers = 0; - - for(int i = 0; i < numBlockerSearchSamples; i++) { - const float z = texture(spot_shadow, - vec3(shadowCoords.xy + PoissonOffsets[i] * searchWidth, index)).r; - if(z < shadowCoords.z) { - blockerSum += z; - blockers++; - } - } - - avgBlockerDistance = blockerSum / blockers; -} - -float pcss_spot(const vec4 shadowCoords, const int index, float light_size_uv) { - float average_blocker_depth = 0.0; - int num_blockers = 0; - blocker_distance_spot(shadowCoords.xyz, index, light_size_uv, average_blocker_depth, num_blockers); - if(num_blockers < 1) - return 1.0; - - const float penumbraWidth = penumbra_size(-shadowCoords.z, average_blocker_depth); - - const float uvRadius = penumbraWidth * light_size_uv * 0.1 / shadowCoords.z; - return pcf_spot(shadowCoords, index, uvRadius); -} - -#endif - -int last_spot_light = 0; - -ComputedLightInformation calculate_spot(Light light) { - ComputedLightInformation light_info; - light_info.direction = normalize(light.positionType.xyz - in_frag_pos); - - float shadow = 1.0; - if(light.shadowsEnable.x == 1.0) { - const vec4 shadowCoord = fragPostSpotLightSpace[last_spot_light] / fragPostSpotLightSpace[last_spot_light].w; - -#ifdef SHADOW_FILTER_NONE - shadow = (texture(spot_shadow, vec3(shadowCoord.xy, last_spot_light)).r < shadowCoord.z) ? 0.0 : 1.0; -#endif -#ifdef SHADOW_FILTER_PCF - shadow = pcf_spot(shadowCoord, last_spot_light, 0.01); -#endif -#ifdef SHADOW_FILTER_PCSS - shadow = pcss_spot(shadowCoord, last_spot_light, light.shadowsEnable.y); -#endif - - last_spot_light++; - } - - const float inner_cutoff = light.colorSize.w + radians(5); - const float outer_cutoff = light.colorSize.w; - - const float theta = dot(light_info.direction, normalize(light.directionPower.xyz)); - const float epsilon = inner_cutoff - outer_cutoff; - const float intensity = clamp((theta - outer_cutoff) / epsilon, 0.0, 1.0); - - light_info.radiance = light.directionPower.w * shadow * intensity; - - return light_info; -} - -#ifdef POINT_SHADOWS_SUPPORTED - -float pcf_point(const vec3 shadowCoords, const int index, const float uvRadius) { - float sum = 0; - for(int i = 0; i < 16; i++) { - const float z = texture(point_shadow, vec4(shadowCoords.xyz + vec3(PoissonOffsets[i].xy, PoissonOffsets[i].x) * uvRadius, index)).r; - sum += (z < length(shadowCoords) - 0.05) ? 0.0 : 1.0; - } - - return sum / 16; -} - -#ifdef SHADOW_FILTER_PCSS -void blocker_distance_point(const vec3 shadowCoords, const int index, const float uvLightSize, inout float avgBlockerDistance, inout int blockers) { - const float searchWidth = search_width(uvLightSize, length(shadowCoords)); - - float blockerSum = 0.0; - blockers = 0; - - for(int i = 0; i < numBlockerSearchSamples; i++) { - const float z = texture(point_shadow, - vec4(shadowCoords + vec3(PoissonOffsets[i], PoissonOffsets[i].x) * searchWidth, index)).r; - if(z < length(shadowCoords)) { - blockerSum += z; - blockers++; - } - } - - avgBlockerDistance = blockerSum / blockers; -} - -float pcss_point(const vec3 shadowCoords, const int index, float light_size_uv) { - float average_blocker_depth = 0.0; - int num_blockers = 0; - blocker_distance_point(shadowCoords.xyz, index, light_size_uv, average_blocker_depth, num_blockers); - if(num_blockers < 1) - return 1.0; - - const float depth = length(shadowCoords); - const float penumbraWidth = penumbra_size(-depth, average_blocker_depth); - - const float uvRadius = penumbraWidth * light_size_uv; - return pcf_point(shadowCoords, index, uvRadius); -} -#endif - -#endif - -int last_point_light = 0; - -ComputedLightInformation calculate_point(Light light) { - ComputedLightInformation light_info; - light_info.direction = normalize(light.positionType.xyz - in_frag_pos); - - const vec3 lightVec = in_frag_pos - light.positionType.xyz; - - // Check if fragment is in shadow - float shadow = 1.0; -#ifdef POINT_SHADOWS_SUPPORTED - if(light.shadowsEnable.x == 1.0) { -#ifdef SHADOW_FILTER_NONE - const float sampledDist = texture(point_shadow, vec4(lightVec, last_point_light++)).r; - const float dist = length(lightVec); - - shadow = (dist <= sampledDist + 0.05) ? 1.0 : 0.0; -#endif -#ifdef SHADOW_FILTER_PCF - shadow = pcf_point(lightVec, last_point_light++, 1.0); -#endif -#ifdef SHADOW_FILTER_PCSS - shadow = pcss_point(lightVec, last_point_light++, light.shadowsEnable.y); -#endif - } -#endif - - const float distance = length(light.positionType.xyz - in_frag_pos); - const float attenuation = 1.0 / (distance * distance); - - light_info.radiance = attenuation * light.directionPower.w * shadow; - - return light_info; -} diff --git a/shaders/scenecapture.vert.nocompile.glsl b/shaders/scenecapture.vert.nocompile.glsl deleted file mode 100755 index c3a799d..0000000 --- a/shaders/scenecapture.vert.nocompile.glsl +++ /dev/null @@ -1,58 +0,0 @@ -layout (constant_id = 0) const int max_materials = 25; -layout (constant_id = 1) const int max_lights = 25; -layout (constant_id = 2) const int max_spot_lights = 4; - -layout (location = 0) in vec3 inPosition; -layout (location = 1) in vec3 inNormal; -layout (location = 2) in vec2 inUV; - -layout (location = 0) out vec3 outFragPos; -layout (location = 1) out vec3 outNormal; -layout (location = 2) out vec2 outUV; -layout (location = 3) out flat int outMaterialId; -layout (location = 4) out vec4 fragPosLightSpace; -layout (location = 5) out vec4 fragPostSpotLightSpace[max_spot_lights]; - -struct Material { - vec4 color, info; -}; - -struct Light { - vec4 positionType; - vec4 directionPower; - vec4 color; -}; - -layout(std430, binding = 5) buffer readonly SceneInformation { - vec4 camPos; - mat4 projection, lightSpace; - vec4 skyColor; - mat4 spotLightSpaces[max_spot_lights]; - Material materials[max_materials]; - Light lights[max_lights]; - int numLights; -} scene; - -layout(push_constant, binding = 6) uniform readonly PushConstant{ - mat4 model, view; - int materialOffset; -}; - -const mat4 biasMat = mat4( - 0.5, 0.0, 0.0, 0.0, - 0.0, 0.5, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.5, 0.5, 0.0, 1.0); - -void main() { - gl_Position = scene.projection * view * model * vec4(inPosition, 1.0); - outFragPos = vec3(model * vec4(inPosition, 1.0)); - outNormal = mat3(model) * inNormal; - outUV = inUV; - outMaterialId = materialOffset; - fragPosLightSpace = (biasMat * scene.lightSpace * model) * vec4(inPosition, 1.0); - - for(int i = 0; i < max_spot_lights; i++) { - fragPostSpotLightSpace[i] = (biasMat * scene.spotLightSpaces[i] * model) * vec4(inPosition, 1.0); - } -} diff --git a/shaders/shadow.frag.glsl b/shaders/shadow.frag.glsl deleted file mode 100755 index 2cb1536..0000000 --- a/shaders/shadow.frag.glsl +++ /dev/null @@ -1,5 +0,0 @@ -layout (location = 0) in vec3 inPos; -layout (location = 1) flat in int index; - -void main() { -} diff --git a/shaders/shadow.vert.nocompile.glsl b/shaders/shadow.vert.nocompile.glsl deleted file mode 100755 index 164e28f..0000000 --- a/shaders/shadow.vert.nocompile.glsl +++ /dev/null @@ -1,43 +0,0 @@ -layout (constant_id = 0) const int max_lights = 25; - -layout (location = 0) in vec3 inPosition; - -#ifdef BONE -layout (location = 4) in ivec4 inBoneID; -layout (location = 5) in vec4 inBoneWeight; -#endif - -layout (location = 0) out vec3 outPos; -layout (location = 1) flat out int index; - -layout(push_constant, binding = 0) uniform PushConstant { - mat4 mvp, model; -}; - -#ifdef BONE -layout(std430, binding = 14) buffer readonly BoneInformation { - mat4 bones[128]; -}; -#endif - -layout(std430, binding = 2) buffer readonly LightInformation { - vec3 light_locations[max_lights]; -}; - -void main() { -#ifdef BONE - mat4 BoneTransform; - - BoneTransform = bones[inBoneID[0]] * inBoneWeight[0]; - BoneTransform += bones[inBoneID[1]] * inBoneWeight[1]; - BoneTransform += bones[inBoneID[2]] * inBoneWeight[2]; - BoneTransform += bones[inBoneID[3]] * inBoneWeight[3]; - - gl_Position = mvp * BoneTransform * vec4(inPosition, 1.0); - outPos = vec3(model * vec4(inPosition, 1.0)); -#else - gl_Position = mvp * vec4(inPosition, 1.0); - outPos = vec3(model * vec4(inPosition, 1.0)); -#endif - index = gl_BaseInstance; -} diff --git a/shaders/sky.frag.glsl b/shaders/sky.frag.glsl deleted file mode 100755 index 3b8e634..0000000 --- a/shaders/sky.frag.glsl +++ /dev/null @@ -1,47 +0,0 @@ -#include "atmosphere.glsl" - -layout (location = 0) in vec2 in_uv; - -layout (location = 0) out vec4 out_color; - -layout(push_constant, binding = 1) uniform PushConstant{ - mat4 view; - vec4 sun_position_fov; - float aspect; -}; - -vec3 sky_ray(const vec2 uv) { - const float d = 0.5 / tan(sun_position_fov.w / 2.0); - return normalize(vec3((uv.x - 0.5) * aspect, - uv.y - 0.5, - d)); -} - -void main() { - const vec3 color = atmosphere( - // ray direction - normalize(mat3(view) * sky_ray(in_uv)), - // ray origin - vec3(0, 6372e3, 0), - // position of the sun in world space (this will be normalized) - sun_position_fov.xyz, - // intensity of the sun - 22.0, - // radius of the plant in meters - 6371e3, - // radius of the atmosphere in meters - 6471e3, - // Rayleigh scattering coefficient - vec3(5.5e-6, 13.0e-6, 22.4e-6), - // Mie scattering coefficient - 21e-6, - // Rayleigh scale height - 8e3, - // Mie scale height - 1.2e3, - // Mie preferred scattering direction - 0.758 - ); - - out_color = vec4(color, 1.0); -} diff --git a/shaders/sky.vert.glsl b/shaders/sky.vert.glsl deleted file mode 100755 index cef4fd1..0000000 --- a/shaders/sky.vert.glsl +++ /dev/null @@ -1,12 +0,0 @@ -layout (location = 0) out vec2 out_uv; - -layout(push_constant, binding = 1) uniform PushConstant{ - mat4 view; - vec4 sun_position_fov; - float aspect; -}; - -void main() { - out_uv = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); - gl_Position = vec4(out_uv * 2.0f + -1.0f, 1.0f, 1.0f); -} diff --git a/shaders/smaa.glsl b/shaders/smaa.glsl deleted file mode 100644 index af0e352..0000000 --- a/shaders/smaa.glsl +++ /dev/null @@ -1,1407 +0,0 @@ -/** - * Copyright (C) 2013 Jorge Jimenez (jorge@iryoku.com) - * Copyright (C) 2013 Jose I. Echevarria (joseignacioechevarria@gmail.com) - * Copyright (C) 2013 Belen Masia (bmasia@unizar.es) - * Copyright (C) 2013 Fernando Navarro (fernandn@microsoft.com) - * Copyright (C) 2013 Diego Gutierrez (diegog@unizar.es) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * 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. As clarification, there - * is no requirement that the copyright notice and permission be included in - * binary distributions 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. - */ - - -/** - * _______ ___ ___ ___ ___ - * / || \/ | / \ / \ - * | (---- | \ / | / ^ \ / ^ \ - * \ \ | |\/| | / /_\ \ / /_\ \ - * ----) | | | | | / _____ \ / _____ \ - * |_______/ |__| |__| /__/ \__\ /__/ \__\ - * - * E N H A N C E D - * S U B P I X E L M O R P H O L O G I C A L A N T I A L I A S I N G - * - * http://www.iryoku.com/smaa/ - * - * Hi, welcome aboard! - * - * Here you'll find instructions to get the shader up and running as fast as - * possible. - * - * IMPORTANTE NOTICE: when updating, remember to update both this file and the - * precomputed textures! They may change from version to version. - * - * The shader has three passes, chained together as follows: - * - * |input|------------------· - * v | - * [ SMAA*EdgeDetection ] | - * v | - * |edgesTex| | - * v | - * [ SMAABlendingWeightCalculation ] | - * v | - * |blendTex| | - * v | - * [ SMAANeighborhoodBlending ] <------· - * v - * |output| - * - * Note that each [pass] has its own vertex and pixel shader. Remember to use - * oversized triangles instead of quads to avoid overshading along the - * diagonal. - * - * You've three edge detection methods to choose from: luma, color or depth. - * They represent different quality/performance and anti-aliasing/sharpness - * tradeoffs, so our recommendation is for you to choose the one that best - * suits your particular scenario: - * - * - Depth edge detection is usually the fastest but it may miss some edges. - * - * - Luma edge detection is usually more expensive than depth edge detection, - * but catches visible edges that depth edge detection can miss. - * - * - Color edge detection is usually the most expensive one but catches - * chroma-only edges. - * - * For quickstarters: just use luma edge detection. - * - * The general advice is to not rush the integration process and ensure each - * step is done correctly (don't try to integrate SMAA T2x with predicated edge - * detection from the start!). Ok then, let's go! - * - * 1. The first step is to create two RGBA temporal render targets for holding - * |edgesTex| and |blendTex|. - * - * In DX10 or DX11, you can use a RG render target for the edges texture. - * In the case of NVIDIA GPUs, using RG render targets seems to actually be - * slower. - * - * On the Xbox 360, you can use the same render target for resolving both - * |edgesTex| and |blendTex|, as they aren't needed simultaneously. - * - * 2. Both temporal render targets |edgesTex| and |blendTex| must be cleared - * each frame. Do not forget to clear the alpha channel! - * - * 3. The next step is loading the two supporting precalculated textures, - * 'areaTex' and 'searchTex'. You'll find them in the 'Textures' folder as - * C++ headers, and also as regular DDS files. They'll be needed for the - * 'SMAABlendingWeightCalculation' pass. - * - * If you use the C++ headers, be sure to load them in the format specified - * inside of them. - * - * You can also compress 'areaTex' and 'searchTex' using BC5 and BC4 - * respectively, if you have that option in your content processor pipeline. - * When compressing then, you get a non-perceptible quality decrease, and a - * marginal performance increase. - * - * 4. All samplers must be set to linear filtering and clamp. - * - * After you get the technique working, remember that 64-bit inputs have - * half-rate linear filtering on GCN. - * - * If SMAA is applied to 64-bit color buffers, switching to point filtering - * when accesing them will increase the performance. Search for - * 'SMAASamplePoint' to see which textures may benefit from point - * filtering, and where (which is basically the color input in the edge - * detection and resolve passes). - * - * 5. All texture reads and buffer writes must be non-sRGB, with the exception - * of the input read and the output write in - * 'SMAANeighborhoodBlending' (and only in this pass!). If sRGB reads in - * this last pass are not possible, the technique will work anyway, but - * will perform antialiasing in gamma space. - * - * IMPORTANT: for best results the input read for the color/luma edge - * detection should *NOT* be sRGB. - * - * 6. Before including SMAA.h you'll have to setup the render target metrics, - * the target and any optional configuration defines. Optionally you can - * use a preset. - * - * You have the following targets available: - * SMAA_HLSL_3 - * SMAA_HLSL_4 - * SMAA_HLSL_4_1 - * SMAA_GLSL_3 * - * SMAA_GLSL_4 * - * - * * (See SMAA_INCLUDE_VS and SMAA_INCLUDE_PS below). - * - * And four presets: - * SMAA_PRESET_LOW (%60 of the quality) - * SMAA_PRESET_MEDIUM (%80 of the quality) - * SMAA_PRESET_HIGH (%95 of the quality) - * SMAA_PRESET_ULTRA (%99 of the quality) - * - * For example: - * #define SMAA_RT_METRICS float4(1.0 / 1280.0, 1.0 / 720.0, 1280.0, 720.0) - * #define SMAA_HLSL_4 - * #define SMAA_PRESET_HIGH - * #include "SMAA.h" - * - * Note that SMAA_RT_METRICS doesn't need to be a macro, it can be a - * uniform variable. The code is designed to minimize the impact of not - * using a constant value, but it is still better to hardcode it. - * - * Depending on how you encoded 'areaTex' and 'searchTex', you may have to - * add (and customize) the following defines before including SMAA.h: - * #define SMAA_AREATEX_SELECT(sample) sample.rg - * #define SMAA_SEARCHTEX_SELECT(sample) sample.r - * - * If your engine is already using porting macros, you can define - * SMAA_CUSTOM_SL, and define the porting functions by yourself. - * - * 7. Then, you'll have to setup the passes as indicated in the scheme above. - * You can take a look into SMAA.fx, to see how we did it for our demo. - * Checkout the function wrappers, you may want to copy-paste them! - * - * 8. It's recommended to validate the produced |edgesTex| and |blendTex|. - * You can use a screenshot from your engine to compare the |edgesTex| - * and |blendTex| produced inside of the engine with the results obtained - * with the reference demo. - * - * 9. After you get the last pass to work, it's time to optimize. You'll have - * to initialize a stencil buffer in the first pass (discard is already in - * the code), then mask execution by using it the second pass. The last - * pass should be executed in all pixels. - * - * - * After this point you can choose to enable predicated thresholding, - * temporal supersampling and motion blur integration: - * - * a) If you want to use predicated thresholding, take a look into - * SMAA_PREDICATION; you'll need to pass an extra texture in the edge - * detection pass. - * - * b) If you want to enable temporal supersampling (SMAA T2x): - * - * 1. The first step is to render using subpixel jitters. I won't go into - * detail, but it's as simple as moving each vertex position in the - * vertex shader, you can check how we do it in our DX10 demo. - * - * 2. Then, you must setup the temporal resolve. You may want to take a look - * into SMAAResolve for resolving 2x modes. After you get it working, you'll - * probably see ghosting everywhere. But fear not, you can enable the - * CryENGINE temporal reprojection by setting the SMAA_REPROJECTION macro. - * Check out SMAA_DECODE_VELOCITY if your velocity buffer is encoded. - * - * 3. The next step is to apply SMAA to each subpixel jittered frame, just as - * done for 1x. - * - * 4. At this point you should already have something usable, but for best - * results the proper area textures must be set depending on current jitter. - * For this, the parameter 'subsampleIndices' of - * 'SMAABlendingWeightCalculationPS' must be set as follows, for our T2x - * mode: - * - * @SUBSAMPLE_INDICES - * - * | S# | Camera Jitter | subsampleIndices | - * +----+------------------+---------------------+ - * | 0 | ( 0.25, -0.25) | float4(1, 1, 1, 0) | - * | 1 | (-0.25, 0.25) | float4(2, 2, 2, 0) | - * - * These jitter positions assume a bottom-to-top y axis. S# stands for the - * sample number. - * - * More information about temporal supersampling here: - * http://iryoku.com/aacourse/downloads/13-Anti-Aliasing-Methods-in-CryENGINE-3.pdf - * - * c) If you want to enable spatial multisampling (SMAA S2x): - * - * 1. The scene must be rendered using MSAA 2x. The MSAA 2x buffer must be - * created with: - * - DX10: see below (*) - * - DX10.1: D3D10_STANDARD_MULTISAMPLE_PATTERN or - * - DX11: D3D11_STANDARD_MULTISAMPLE_PATTERN - * - * This allows to ensure that the subsample order matches the table in - * @SUBSAMPLE_INDICES. - * - * (*) In the case of DX10, we refer the reader to: - * - SMAA::detectMSAAOrder and - * - SMAA::msaaReorder - * - * These functions allow to match the standard multisample patterns by - * detecting the subsample order for a specific GPU, and reordering - * them appropriately. - * - * 2. A shader must be run to output each subsample into a separate buffer - * (DX10 is required). You can use SMAASeparate for this purpose, or just do - * it in an existing pass (for example, in the tone mapping pass, which has - * the advantage of feeding tone mapped subsamples to SMAA, which will yield - * better results). - * - * 3. The full SMAA 1x pipeline must be run for each separated buffer, storing - * the results in the final buffer. The second run should alpha blend with - * the existing final buffer using a blending factor of 0.5. - * 'subsampleIndices' must be adjusted as in the SMAA T2x case (see point - * b). - * - * d) If you want to enable temporal supersampling on top of SMAA S2x - * (which actually is SMAA 4x): - * - * 1. SMAA 4x consists on temporally jittering SMAA S2x, so the first step is - * to calculate SMAA S2x for current frame. In this case, 'subsampleIndices' - * must be set as follows: - * - * | F# | S# | Camera Jitter | Net Jitter | subsampleIndices | - * +----+----+--------------------+-------------------+----------------------+ - * | 0 | 0 | ( 0.125, 0.125) | ( 0.375, -0.125) | float4(5, 3, 1, 3) | - * | 0 | 1 | ( 0.125, 0.125) | (-0.125, 0.375) | float4(4, 6, 2, 3) | - * +----+----+--------------------+-------------------+----------------------+ - * | 1 | 2 | (-0.125, -0.125) | ( 0.125, -0.375) | float4(3, 5, 1, 4) | - * | 1 | 3 | (-0.125, -0.125) | (-0.375, 0.125) | float4(6, 4, 2, 4) | - * - * These jitter positions assume a bottom-to-top y axis. F# stands for the - * frame number. S# stands for the sample number. - * - * 2. After calculating SMAA S2x for current frame (with the new subsample - * indices), previous frame must be reprojected as in SMAA T2x mode (see - * point b). - * - * e) If motion blur is used, you may want to do the edge detection pass - * together with motion blur. This has two advantages: - * - * 1. Pixels under heavy motion can be omitted from the edge detection process. - * For these pixels we can just store "no edge", as motion blur will take - * care of them. - * 2. The center pixel tap is reused. - * - * Note that in this case depth testing should be used instead of stenciling, - * as we have to write all the pixels in the motion blur pass. - * - * That's it! - */ - -//----------------------------------------------------------------------------- -// SMAA Presets - -/** - * Note that if you use one of these presets, the following configuration - * macros will be ignored if set in the "Configurable Defines" section. - */ - -#if defined(SMAA_PRESET_LOW) -#define SMAA_THRESHOLD 0.15 -#define SMAA_MAX_SEARCH_STEPS 4 -#define SMAA_DISABLE_DIAG_DETECTION -#define SMAA_DISABLE_CORNER_DETECTION -#elif defined(SMAA_PRESET_MEDIUM) -#define SMAA_THRESHOLD 0.1 -#define SMAA_MAX_SEARCH_STEPS 8 -#define SMAA_DISABLE_DIAG_DETECTION -#define SMAA_DISABLE_CORNER_DETECTION -#elif defined(SMAA_PRESET_HIGH) -#define SMAA_THRESHOLD 0.1 -#define SMAA_MAX_SEARCH_STEPS 16 -#define SMAA_MAX_SEARCH_STEPS_DIAG 8 -#define SMAA_CORNER_ROUNDING 25 -#elif defined(SMAA_PRESET_ULTRA) -#define SMAA_THRESHOLD 0.05 -#define SMAA_MAX_SEARCH_STEPS 32 -#define SMAA_MAX_SEARCH_STEPS_DIAG 16 -#define SMAA_CORNER_ROUNDING 25 -#endif - -//----------------------------------------------------------------------------- -// Configurable Defines - -/** - * SMAA_THRESHOLD specifies the threshold or sensitivity to edges. - * Lowering this value you will be able to detect more edges at the expense of - * performance. - * - * Range: [0, 0.5] - * 0.1 is a reasonable value, and allows to catch most visible edges. - * 0.05 is a rather overkill value, that allows to catch 'em all. - * - * If temporal supersampling is used, 0.2 could be a reasonable value, as low - * contrast edges are properly filtered by just 2x. - */ -#ifndef SMAA_THRESHOLD -#define SMAA_THRESHOLD 0.1 -#endif - -/** - * SMAA_DEPTH_THRESHOLD specifies the threshold for depth edge detection. - * - * Range: depends on the depth range of the scene. - */ -#ifndef SMAA_DEPTH_THRESHOLD -#define SMAA_DEPTH_THRESHOLD (0.1 * SMAA_THRESHOLD) -#endif - -/** - * SMAA_MAX_SEARCH_STEPS specifies the maximum steps performed in the - * horizontal/vertical pattern searches, at each side of the pixel. - * - * In number of pixels, it's actually the double. So the maximum line length - * perfectly handled by, for example 16, is 64 (by perfectly, we meant that - * longer lines won't look as good, but still antialiased). - * - * Range: [0, 112] - */ -#ifndef SMAA_MAX_SEARCH_STEPS -#define SMAA_MAX_SEARCH_STEPS 16 -#endif - -/** - * SMAA_MAX_SEARCH_STEPS_DIAG specifies the maximum steps performed in the - * diagonal pattern searches, at each side of the pixel. In this case we jump - * one pixel at time, instead of two. - * - * Range: [0, 20] - * - * On high-end machines it is cheap (between a 0.8x and 0.9x slower for 16 - * steps), but it can have a significant impact on older machines. - * - * Define SMAA_DISABLE_DIAG_DETECTION to disable diagonal processing. - */ -#ifndef SMAA_MAX_SEARCH_STEPS_DIAG -#define SMAA_MAX_SEARCH_STEPS_DIAG 8 -#endif - -/** - * SMAA_CORNER_ROUNDING specifies how much sharp corners will be rounded. - * - * Range: [0, 100] - * - * Define SMAA_DISABLE_CORNER_DETECTION to disable corner processing. - */ -#ifndef SMAA_CORNER_ROUNDING -#define SMAA_CORNER_ROUNDING 25 -#endif - -/** - * If there is an neighbor edge that has SMAA_LOCAL_CONTRAST_FACTOR times - * bigger contrast than current edge, current edge will be discarded. - * - * This allows to eliminate spurious crossing edges, and is based on the fact - * that, if there is too much contrast in a direction, that will hide - * perceptually contrast in the other neighbors. - */ -#ifndef SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR -#define SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR 2.0 -#endif - -/** - * Predicated thresholding allows to better preserve texture details and to - * improve performance, by decreasing the number of detected edges using an - * additional buffer like the light accumulation buffer, object ids or even the - * depth buffer (the depth buffer usage may be limited to indoor or short range - * scenes). - * - * It locally decreases the luma or color threshold if an edge is found in an - * additional buffer (so the global threshold can be higher). - * - * This method was developed by Playstation EDGE MLAA team, and used in - * Killzone 3, by using the light accumulation buffer. More information here: - * http://iryoku.com/aacourse/downloads/06-MLAA-on-PS3.pptx - */ -#ifndef SMAA_PREDICATION -#define SMAA_PREDICATION 0 -#endif - -/** - * Threshold to be used in the additional predication buffer. - * - * Range: depends on the input, so you'll have to find the magic number that - * works for you. - */ -#ifndef SMAA_PREDICATION_THRESHOLD -#define SMAA_PREDICATION_THRESHOLD 0.01 -#endif - -/** - * How much to scale the global threshold used for luma or color edge - * detection when using predication. - * - * Range: [1, 5] - */ -#ifndef SMAA_PREDICATION_SCALE -#define SMAA_PREDICATION_SCALE 2.0 -#endif - -/** - * How much to locally decrease the threshold. - * - * Range: [0, 1] - */ -#ifndef SMAA_PREDICATION_STRENGTH -#define SMAA_PREDICATION_STRENGTH 0.4 -#endif - -/** - * Temporal reprojection allows to remove ghosting artifacts when using - * temporal supersampling. We use the CryEngine 3 method which also introduces - * velocity weighting. This feature is of extreme importance for totally - * removing ghosting. More information here: - * http://iryoku.com/aacourse/downloads/13-Anti-Aliasing-Methods-in-CryENGINE-3.pdf - * - * Note that you'll need to setup a velocity buffer for enabling reprojection. - * For static geometry, saving the previous depth buffer is a viable - * alternative. - */ -#ifndef SMAA_REPROJECTION -#define SMAA_REPROJECTION 0 -#endif - -/** - * SMAA_REPROJECTION_WEIGHT_SCALE controls the velocity weighting. It allows to - * remove ghosting trails behind the moving object, which are not removed by - * just using reprojection. Using low values will exhibit ghosting, while using - * high values will disable temporal supersampling under motion. - * - * Behind the scenes, velocity weighting removes temporal supersampling when - * the velocity of the subsamples differs (meaning they are different objects). - * - * Range: [0, 80] - */ -#ifndef SMAA_REPROJECTION_WEIGHT_SCALE -#define SMAA_REPROJECTION_WEIGHT_SCALE 30.0 -#endif - -/** - * On some compilers, discard and texture cannot be used in vertex shaders. Thus, they need - * to be compiled separately. - */ -#ifndef SMAA_INCLUDE_VS -#define SMAA_INCLUDE_VS 1 -#endif -#ifndef SMAA_INCLUDE_PS -#define SMAA_INCLUDE_PS 1 -#endif - -//----------------------------------------------------------------------------- -// Texture Access Defines - -#ifndef SMAA_AREATEX_SELECT -#if defined(SMAA_HLSL_3) -#define SMAA_AREATEX_SELECT(sample) sample.ra -#else -#define SMAA_AREATEX_SELECT(sample) sample.rg -#endif -#endif - -#ifndef SMAA_SEARCHTEX_SELECT -#define SMAA_SEARCHTEX_SELECT(sample) sample.r -#endif - -#ifndef SMAA_DECODE_VELOCITY -#define SMAA_DECODE_VELOCITY(sample) sample.rg -#endif - -//----------------------------------------------------------------------------- -// Non-Configurable Defines - -#define SMAA_AREATEX_MAX_DISTANCE 16 -#define SMAA_AREATEX_MAX_DISTANCE_DIAG 20 -#define SMAA_AREATEX_PIXEL_SIZE (1.0 / float2(160.0, 560.0)) -#define SMAA_AREATEX_SUBTEX_SIZE (1.0 / 7.0) -#define SMAA_SEARCHTEX_SIZE float2(66.0, 33.0) -#define SMAA_SEARCHTEX_PACKED_SIZE float2(64.0, 16.0) -#define SMAA_CORNER_ROUNDING_NORM (float(SMAA_CORNER_ROUNDING) / 100.0) - -//----------------------------------------------------------------------------- -// Porting Functions - -#if defined(SMAA_HLSL_3) -#ifndef SMAA_FLIP_Y -#define SMAA_FLIP_Y 0 -#endif // SMAA_FLIP_Y -#define SMAATexture2D(tex) sampler2D tex -#define SMAATexturePass2D(tex) tex -#define SMAASampleLevelZero(tex, coord) tex2Dlod(tex, float4(coord, 0.0, 0.0)) -#define SMAASampleLevelZeroPoint(tex, coord) tex2Dlod(tex, float4(coord, 0.0, 0.0)) -#define SMAASampleLevelZeroOffset(tex, coord, offset) tex2Dlod(tex, float4(coord + offset * SMAA_RT_METRICS.xy, 0.0, 0.0)) -#define SMAASample(tex, coord) tex2D(tex, coord) -#define SMAASamplePoint(tex, coord) tex2D(tex, coord) -#define SMAASampleOffset(tex, coord, offset) tex2D(tex, coord + offset * SMAA_RT_METRICS.xy) -#define SMAA_FLATTEN [flatten] -#define SMAA_BRANCH [branch] -#endif -#if defined(SMAA_HLSL_4) || defined(SMAA_HLSL_4_1) -#ifndef SMAA_FLIP_Y -#define SMAA_FLIP_Y 0 -#endif // SMAA_FLIP_Y -SamplerState LinearSampler { Filter = MIN_MAG_LINEAR_MIP_POINT; AddressU = Clamp; AddressV = Clamp; }; -SamplerState PointSampler { Filter = MIN_MAG_MIP_POINT; AddressU = Clamp; AddressV = Clamp; }; -#define SMAATexture2D(tex) Texture2D tex -#define SMAATexturePass2D(tex) tex -#define SMAASampleLevelZero(tex, coord) tex.SampleLevel(LinearSampler, coord, 0) -#define SMAASampleLevelZeroPoint(tex, coord) tex.SampleLevel(PointSampler, coord, 0) -#define SMAASampleLevelZeroOffset(tex, coord, offset) tex.SampleLevel(LinearSampler, coord, 0, offset) -#define SMAASample(tex, coord) tex.Sample(LinearSampler, coord) -#define SMAASamplePoint(tex, coord) tex.Sample(PointSampler, coord) -#define SMAASampleOffset(tex, coord, offset) tex.Sample(LinearSampler, coord, offset) -#define SMAA_FLATTEN [flatten] -#define SMAA_BRANCH [branch] -#define SMAATexture2DMS2(tex) Texture2DMS tex -#define SMAALoad(tex, pos, sample) tex.Load(pos, sample) -#if defined(SMAA_HLSL_4_1) -#define SMAAGather(tex, coord) tex.Gather(LinearSampler, coord, 0) -#endif -#endif -#if defined(SMAA_GLSL_3) || defined(SMAA_GLSL_4) -#ifndef SMAA_FLIP_Y -#define SMAA_FLIP_Y 1 -#endif // SMAA_FLIP_Y - -#define SMAATexture2D(tex) sampler2D tex -#define SMAATexturePass2D(tex) tex -#define SMAASampleLevelZero(tex, coord) textureLod(tex, coord, 0.0) -#define SMAASampleLevelZeroPoint(tex, coord) textureLod(tex, coord, 0.0) -#define SMAASampleLevelZeroOffset(tex, coord, offset) textureLodOffset(tex, coord, 0.0, offset) -#define SMAASample(tex, coord) texture(tex, coord) -#define SMAASamplePoint(tex, coord) texture(tex, coord) -#define SMAASampleOffset(tex, coord, offset) texture(tex, coord, offset) -#define SMAA_FLATTEN -#define SMAA_BRANCH -#define lerp(a, b, t) mix(a, b, t) -#define saturate(a) clamp(a, 0.0, 1.0) -#if defined(SMAA_GLSL_4) -#define mad(a, b, c) fma(a, b, c) -#define SMAAGather(tex, coord) textureGather(tex, coord) -#else -#define mad(a, b, c) (a * b + c) -#endif -#define float2 vec2 -#define float3 vec3 -#define float4 vec4 -#define int2 ivec2 -#define int3 ivec3 -#define int4 ivec4 -#define bool2 bvec2 -#define bool3 bvec3 -#define bool4 bvec4 -#endif - -#if !defined(SMAA_HLSL_3) && !defined(SMAA_HLSL_4) && !defined(SMAA_HLSL_4_1) && !defined(SMAA_GLSL_3) && !defined(SMAA_GLSL_4) && !defined(SMAA_CUSTOM_SL) -#error you must define the shading language: SMAA_HLSL_*, SMAA_GLSL_* or SMAA_CUSTOM_SL -#endif - - -#if SMAA_FLIP_Y - -#define API_V_DIR(v) -(v) -#define API_V_COORD(v) (1.0 - v) -#define API_V_BELOW(v1, v2) v1 < v2 -#define API_V_ABOVE(v1, v2) v1 > v2 - -#else // VULKAN_FLIP - -#define API_V_DIR(v) v -#define API_V_COORD(v) v -#define API_V_BELOW(v1, v2) v1 > v2 -#define API_V_ABOVE(v1, v2) v1 < v2 - -#endif // VULKAN_FLIP - - -//----------------------------------------------------------------------------- -// Misc functions - -#if SMAA_INCLUDE_PS -/** - * Gathers current pixel, and the top-left neighbors. - */ -float3 SMAAGatherNeighbours(float2 texcoord, - float4 offset[3], - SMAATexture2D(tex)) { - #ifdef SMAAGather - - #if SMAA_FLIP_Y - return SMAAGather(tex, texcoord + SMAA_RT_METRICS.xy * float2(-0.5, 0.5)).zwy; - #else // SMAA_FLIP_Y - return SMAAGather(tex, texcoord + SMAA_RT_METRICS.xy * float2(-0.5, -0.5)).grb; - #endif // SMAA_FLIP_Y - - #else // SMAAGather - float P = SMAASamplePoint(tex, texcoord).r; - float Pleft = SMAASamplePoint(tex, offset[0].xy).r; - float Ptop = SMAASamplePoint(tex, offset[0].zw).r; - return float3(P, Pleft, Ptop); - #endif -} - -/** - * Adjusts the threshold by means of predication. - */ -float2 SMAACalculatePredicatedThreshold(float2 texcoord, - float4 offset[3], - SMAATexture2D(predicationTex)) { - float3 neighbours = SMAAGatherNeighbours(texcoord, offset, SMAATexturePass2D(predicationTex)); - float2 delta = abs(neighbours.xx - neighbours.yz); - float2 edges = step(SMAA_PREDICATION_THRESHOLD, delta); - return SMAA_PREDICATION_SCALE * SMAA_THRESHOLD * (1.0 - SMAA_PREDICATION_STRENGTH * edges); -} - -#endif // SMAA_INCLUDE_PS - -/** - * Conditional move: - */ -void SMAAMovc(bool2 cond, inout float2 variable, float2 value) { - SMAA_FLATTEN if (cond.x) variable.x = value.x; - SMAA_FLATTEN if (cond.y) variable.y = value.y; -} - -void SMAAMovc(bool4 cond, inout float4 variable, float4 value) { - SMAAMovc(cond.xy, variable.xy, value.xy); - SMAAMovc(cond.zw, variable.zw, value.zw); -} - - -#if SMAA_INCLUDE_VS -//----------------------------------------------------------------------------- -// Vertex Shaders - -/** - * Edge Detection Vertex Shader - */ -void SMAAEdgeDetectionVS(float2 texcoord, - out float4 offset[3]) { - offset[0] = mad(SMAA_RT_METRICS.xyxy, float4(-1.0, 0.0, 0.0, API_V_DIR(-1.0)), texcoord.xyxy); - offset[1] = mad(SMAA_RT_METRICS.xyxy, float4( 1.0, 0.0, 0.0, API_V_DIR(1.0)), texcoord.xyxy); - offset[2] = mad(SMAA_RT_METRICS.xyxy, float4(-2.0, 0.0, 0.0, API_V_DIR(-2.0)), texcoord.xyxy); -} - -/** - * Blend Weight Calculation Vertex Shader - */ -void SMAABlendingWeightCalculationVS(float2 texcoord, - out float2 pixcoord, - out float4 offset[3]) { - pixcoord = texcoord * SMAA_RT_METRICS.zw; - - // We will use these offsets for the searches later on (see @PSEUDO_GATHER4): - offset[0] = mad(SMAA_RT_METRICS.xyxy, float4(-0.25, API_V_DIR(-0.125), 1.25, API_V_DIR(-0.125)), texcoord.xyxy); - offset[1] = mad(SMAA_RT_METRICS.xyxy, float4(-0.125, API_V_DIR(-0.25), -0.125, API_V_DIR(1.25)), texcoord.xyxy); - - // And these for the searches, they indicate the ends of the loops: - offset[2] = mad(SMAA_RT_METRICS.xxyy, - float4(-2.0, 2.0, API_V_DIR(-2.0), API_V_DIR(2.0)) * float(SMAA_MAX_SEARCH_STEPS), - float4(offset[0].xz, offset[1].yw)); -} - -/** - * Neighborhood Blending Vertex Shader - */ -void SMAANeighborhoodBlendingVS(float2 texcoord, - out float4 offset) { - offset = mad(SMAA_RT_METRICS.xyxy, float4( 1.0, 0.0, 0.0, API_V_DIR(1.0)), texcoord.xyxy); -} -#endif // SMAA_INCLUDE_VS - -#if SMAA_INCLUDE_PS -//----------------------------------------------------------------------------- -// Edge Detection Pixel Shaders (First Pass) - -/** - * Luma Edge Detection - * - * IMPORTANT NOTICE: luma edge detection requires gamma-corrected colors, and - * thus 'colorTex' should be a non-sRGB texture. - */ -float2 SMAALumaEdgeDetectionPS(float2 texcoord, - float4 offset[3], - SMAATexture2D(colorTex) - #if SMAA_PREDICATION - , SMAATexture2D(predicationTex) - #endif - ) { - // Calculate the threshold: - #if SMAA_PREDICATION - float2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, SMAATexturePass2D(predicationTex)); - #else - float2 threshold = float2(SMAA_THRESHOLD, SMAA_THRESHOLD); - #endif - - // Calculate lumas: - float3 weights = float3(0.2126, 0.7152, 0.0722); - float L = dot(SMAASamplePoint(colorTex, texcoord).rgb, weights); - - float Lleft = dot(SMAASamplePoint(colorTex, offset[0].xy).rgb, weights); - float Ltop = dot(SMAASamplePoint(colorTex, offset[0].zw).rgb, weights); - - // We do the usual threshold: - float4 delta; - delta.xy = abs(L - float2(Lleft, Ltop)); - float2 edges = step(threshold, delta.xy); - - // Then discard if there is no edge: - if (dot(edges, float2(1.0, 1.0)) == 0.0) - discard; - - // Calculate right and bottom deltas: - float Lright = dot(SMAASamplePoint(colorTex, offset[1].xy).rgb, weights); - float Lbottom = dot(SMAASamplePoint(colorTex, offset[1].zw).rgb, weights); - delta.zw = abs(L - float2(Lright, Lbottom)); - - // Calculate the maximum delta in the direct neighborhood: - float2 maxDelta = max(delta.xy, delta.zw); - - // Calculate left-left and top-top deltas: - float Lleftleft = dot(SMAASamplePoint(colorTex, offset[2].xy).rgb, weights); - float Ltoptop = dot(SMAASamplePoint(colorTex, offset[2].zw).rgb, weights); - delta.zw = abs(float2(Lleft, Ltop) - float2(Lleftleft, Ltoptop)); - - // Calculate the final maximum delta: - maxDelta = max(maxDelta.xy, delta.zw); - float finalDelta = max(maxDelta.x, maxDelta.y); - - // Local contrast adaptation: - edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy); - - return edges; -} - -/** - * Color Edge Detection - * - * IMPORTANT NOTICE: color edge detection requires gamma-corrected colors, and - * thus 'colorTex' should be a non-sRGB texture. - */ -float2 SMAAColorEdgeDetectionPS(float2 texcoord, - float4 offset[3], - SMAATexture2D(colorTex) - #if SMAA_PREDICATION - , SMAATexture2D(predicationTex) - #endif - ) { - // Calculate the threshold: - #if SMAA_PREDICATION - float2 threshold = SMAACalculatePredicatedThreshold(texcoord, offset, predicationTex); - #else - float2 threshold = float2(SMAA_THRESHOLD, SMAA_THRESHOLD); - #endif - - // Calculate color deltas: - float4 delta; - float3 C = SMAASamplePoint(colorTex, texcoord).rgb; - - float3 Cleft = SMAASamplePoint(colorTex, offset[0].xy).rgb; - float3 t = abs(C - Cleft); - delta.x = max(max(t.r, t.g), t.b); - - float3 Ctop = SMAASamplePoint(colorTex, offset[0].zw).rgb; - t = abs(C - Ctop); - delta.y = max(max(t.r, t.g), t.b); - - // We do the usual threshold: - float2 edges = step(threshold, delta.xy); - - // Then discard if there is no edge: - if (dot(edges, float2(1.0, 1.0)) == 0.0) - discard; - - // Calculate right and bottom deltas: - float3 Cright = SMAASamplePoint(colorTex, offset[1].xy).rgb; - t = abs(C - Cright); - delta.z = max(max(t.r, t.g), t.b); - - float3 Cbottom = SMAASamplePoint(colorTex, offset[1].zw).rgb; - t = abs(C - Cbottom); - delta.w = max(max(t.r, t.g), t.b); - - // Calculate the maximum delta in the direct neighborhood: - float2 maxDelta = max(delta.xy, delta.zw); - - // Calculate left-left and top-top deltas: - float3 Cleftleft = SMAASamplePoint(colorTex, offset[2].xy).rgb; - t = abs(C - Cleftleft); - delta.z = max(max(t.r, t.g), t.b); - - float3 Ctoptop = SMAASamplePoint(colorTex, offset[2].zw).rgb; - t = abs(C - Ctoptop); - delta.w = max(max(t.r, t.g), t.b); - - // Calculate the final maximum delta: - maxDelta = max(maxDelta.xy, delta.zw); - float finalDelta = max(maxDelta.x, maxDelta.y); - - // Local contrast adaptation: - edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy); - - return edges; -} - -/** - * Depth Edge Detection - */ -float2 SMAADepthEdgeDetectionPS(float2 texcoord, - float4 offset[3], - SMAATexture2D(depthTex)) { - float3 neighbours = SMAAGatherNeighbours(texcoord, offset, SMAATexturePass2D(depthTex)); - float2 delta = abs(neighbours.xx - float2(neighbours.y, neighbours.z)); - float2 edges = step(SMAA_DEPTH_THRESHOLD, delta); - - if (dot(edges, float2(1.0, 1.0)) == 0.0) - discard; - - return edges; -} - -//----------------------------------------------------------------------------- -// Diagonal Search Functions - -#if !defined(SMAA_DISABLE_DIAG_DETECTION) - -/** - * Allows to decode two binary values from a bilinear-filtered access. - */ -float2 SMAADecodeDiagBilinearAccess(float2 e) { - // Bilinear access for fetching 'e' have a 0.25 offset, and we are - // interested in the R and G edges: - // - // +---G---+-------+ - // | x o R x | - // +-------+-------+ - // - // Then, if one of these edge is enabled: - // Red: (0.75 * X + 0.25 * 1) => 0.25 or 1.0 - // Green: (0.75 * 1 + 0.25 * X) => 0.75 or 1.0 - // - // This function will unpack the values (mad + mul + round): - // wolframalpha.com: round(x * abs(5 * x - 5 * 0.75)) plot 0 to 1 - e.r = e.r * abs(5.0 * e.r - 5.0 * 0.75); - return round(e); -} - -float4 SMAADecodeDiagBilinearAccess(float4 e) { - e.rb = e.rb * abs(5.0 * e.rb - 5.0 * 0.75); - return round(e); -} - -/** - * These functions allows to perform diagonal pattern searches. - */ -float2 SMAASearchDiag1(SMAATexture2D(edgesTex), float2 texcoord, float2 dir, out float2 e) { - dir.y = API_V_DIR(dir.y); - float4 coord = float4(texcoord, -1.0, 1.0); - float3 t = float3(SMAA_RT_METRICS.xy, 1.0); - while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) && - coord.w > 0.9) { - coord.xyz = mad(t, float3(dir, 1.0), coord.xyz); - e = SMAASampleLevelZero(edgesTex, coord.xy).rg; - coord.w = dot(e, float2(0.5, 0.5)); - } - return coord.zw; -} - -float2 SMAASearchDiag2(SMAATexture2D(edgesTex), float2 texcoord, float2 dir, out float2 e) { - dir.y = API_V_DIR(dir.y); - float4 coord = float4(texcoord, -1.0, 1.0); - coord.x += 0.25 * SMAA_RT_METRICS.x; // See @SearchDiag2Optimization - float3 t = float3(SMAA_RT_METRICS.xy, 1.0); - while (coord.z < float(SMAA_MAX_SEARCH_STEPS_DIAG - 1) && - coord.w > 0.9) { - coord.xyz = mad(t, float3(dir, 1.0), coord.xyz); - - // @SearchDiag2Optimization - // Fetch both edges at once using bilinear filtering: - e = SMAASampleLevelZero(edgesTex, coord.xy).rg; - e = SMAADecodeDiagBilinearAccess(e); - - // Non-optimized version: - // e.g = SMAASampleLevelZero(edgesTex, coord.xy).g; - // e.r = SMAASampleLevelZeroOffset(edgesTex, coord.xy, int2(1, 0)).r; - - coord.w = dot(e, float2(0.5, 0.5)); - } - return coord.zw; -} - -/** - * Similar to SMAAArea, this calculates the area corresponding to a certain - * diagonal distance and crossing edges 'e'. - */ -float2 SMAAAreaDiag(SMAATexture2D(areaTex), float2 dist, float2 e, float offset) { - float2 texcoord = mad(float2(SMAA_AREATEX_MAX_DISTANCE_DIAG, SMAA_AREATEX_MAX_DISTANCE_DIAG), e, dist); - - // We do a scale and bias for mapping to texel space: - texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5 * SMAA_AREATEX_PIXEL_SIZE); - - // Diagonal areas are on the second half of the texture: - texcoord.x += 0.5; - - // Move to proper place, according to the subpixel offset: - texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset; - - texcoord.y = API_V_COORD(texcoord.y); - - // Do it! - return SMAA_AREATEX_SELECT(SMAASampleLevelZero(areaTex, texcoord)); -} - -/** - * This searches for diagonal patterns and returns the corresponding weights. - */ -float2 SMAACalculateDiagWeights(SMAATexture2D(edgesTex), SMAATexture2D(areaTex), float2 texcoord, float2 e, float4 subsampleIndices) { - float2 weights = float2(0.0, 0.0); - - // Search for the line ends: - float4 d; - float2 end; - if (e.r > 0.0) { - d.xz = SMAASearchDiag1(SMAATexturePass2D(edgesTex), texcoord, float2(-1.0, 1.0), end); - d.x += float(end.y > 0.9); - } else - d.xz = float2(0.0, 0.0); - d.yw = SMAASearchDiag1(SMAATexturePass2D(edgesTex), texcoord, float2(1.0, -1.0), end); - - SMAA_BRANCH - if (d.x + d.y > 2.0) { // d.x + d.y + 1 > 3 - // Fetch the crossing edges: - float4 coords = mad(float4(-d.x + 0.25, API_V_DIR(d.x), d.y, API_V_DIR(-d.y - 0.25)), SMAA_RT_METRICS.xyxy, texcoord.xyxy); - float4 c; - c.xy = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).rg; - c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).rg; - c.yxwz = SMAADecodeDiagBilinearAccess(c.xyzw); - - // Non-optimized version: - // float4 coords = mad(float4(-d.x, d.x, d.y, -d.y), SMAA_RT_METRICS.xyxy, texcoord.xyxy); - // float4 c; - // c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).g; - // c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2( 0, 0)).r; - // c.z = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).g; - // c.w = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, -1)).r; - - // Merge crossing edges at each side into a single value: - float2 cc = mad(float2(2.0, 2.0), c.xz, c.yw); - - // Remove the crossing edge if we didn't found the end of the line: - SMAAMovc(bool2(step(0.9, d.zw)), cc, float2(0.0, 0.0)); - - // Fetch the areas for this line: - weights += SMAAAreaDiag(SMAATexturePass2D(areaTex), d.xy, cc, subsampleIndices.z); - } - - // Search for the line ends: - d.xz = SMAASearchDiag2(SMAATexturePass2D(edgesTex), texcoord, float2(-1.0, -1.0), end); - if (SMAASampleLevelZeroOffset(edgesTex, texcoord, int2(1, 0)).r > 0.0) { - d.yw = SMAASearchDiag2(SMAATexturePass2D(edgesTex), texcoord, float2(1.0, 1.0), end); - d.y += float(end.y > 0.9); - } else - d.yw = float2(0.0, 0.0); - - SMAA_BRANCH - if (d.x + d.y > 2.0) { // d.x + d.y + 1 > 3 - // Fetch the crossing edges: - float4 coords = mad(float4(-d.x, API_V_DIR(-d.x), d.y, API_V_DIR(d.y)), SMAA_RT_METRICS.xyxy, texcoord.xyxy); - float4 c; - c.x = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2(-1, 0)).g; - c.y = SMAASampleLevelZeroOffset(edgesTex, coords.xy, int2( 0, API_V_DIR(-1))).r; - c.zw = SMAASampleLevelZeroOffset(edgesTex, coords.zw, int2( 1, 0)).gr; - float2 cc = mad(float2(2.0, 2.0), c.xz, c.yw); - - // Remove the crossing edge if we didn't found the end of the line: - SMAAMovc(bool2(step(0.9, d.zw)), cc, float2(0.0, 0.0)); - - // Fetch the areas for this line: - weights += SMAAAreaDiag(SMAATexturePass2D(areaTex), d.xy, cc, subsampleIndices.w).gr; - } - - return weights; -} -#endif - -//----------------------------------------------------------------------------- -// Horizontal/Vertical Search Functions - -/** - * This allows to determine how much length should we add in the last step - * of the searches. It takes the bilinearly interpolated edge (see - * @PSEUDO_GATHER4), and adds 0, 1 or 2, depending on which edges and - * crossing edges are active. - */ -float SMAASearchLength(SMAATexture2D(searchTex), float2 e, float offset) { - // The texture is flipped vertically, with left and right cases taking half - // of the space horizontally: - float2 scale = SMAA_SEARCHTEX_SIZE * float2(0.5, -1.0); - float2 bias = SMAA_SEARCHTEX_SIZE * float2(offset, 1.0); - - // Scale and bias to access texel centers: - scale += float2(-1.0, 1.0); - bias += float2( 0.5, -0.5); - - // Convert from pixel coordinates to texcoords: - // (We use SMAA_SEARCHTEX_PACKED_SIZE because the texture is cropped) - scale *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE; - bias *= 1.0 / SMAA_SEARCHTEX_PACKED_SIZE; - - float2 coord = mad(scale, e, bias); - coord.y = API_V_COORD(coord.y); - - // Lookup the search texture: - return SMAA_SEARCHTEX_SELECT(SMAASampleLevelZero(searchTex, coord)); -} - -/** - * Horizontal/vertical search functions for the 2nd pass. - */ -float SMAASearchXLeft(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) { - /** - * @PSEUDO_GATHER4 - * This texcoord has been offset by (-0.25, -0.125) in the vertex shader to - * sample between edge, thus fetching four edges in a row. - * Sampling with different offsets in each direction allows to disambiguate - * which edges are active from the four fetched ones. - */ - float2 e = float2(0.0, 1.0); - while (texcoord.x > end && - e.g > 0.8281 && // Is there some edge not activated? - e.r == 0.0) { // Or is there a crossing edge that breaks the line? - e = SMAASampleLevelZero(edgesTex, texcoord).rg; - texcoord = mad(-float2(2.0, 0.0), SMAA_RT_METRICS.xy, texcoord); - } - - float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.0), 3.25); - return mad(SMAA_RT_METRICS.x, offset, texcoord.x); - - // Non-optimized version: - // We correct the previous (-0.25, -0.125) offset we applied: - // texcoord.x += 0.25 * SMAA_RT_METRICS.x; - - // The searches are bias by 1, so adjust the coords accordingly: - // texcoord.x += SMAA_RT_METRICS.x; - - // Disambiguate the length added by the last step: - // texcoord.x += 2.0 * SMAA_RT_METRICS.x; // Undo last step - // texcoord.x -= SMAA_RT_METRICS.x * (255.0 / 127.0) * SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.0); - // return mad(SMAA_RT_METRICS.x, offset, texcoord.x); -} - -float SMAASearchXRight(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) { - float2 e = float2(0.0, 1.0); - while (texcoord.x < end && - e.g > 0.8281 && // Is there some edge not activated? - e.r == 0.0) { // Or is there a crossing edge that breaks the line? - e = SMAASampleLevelZero(edgesTex, texcoord).rg; - texcoord = mad(float2(2.0, 0.0), SMAA_RT_METRICS.xy, texcoord); - } - float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e, 0.5), 3.25); - return mad(-SMAA_RT_METRICS.x, offset, texcoord.x); -} - -float SMAASearchYUp(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) { - float2 e = float2(1.0, 0.0); - while (API_V_BELOW(texcoord.y, end) && - e.r > 0.8281 && // Is there some edge not activated? - e.g == 0.0) { // Or is there a crossing edge that breaks the line? - e = SMAASampleLevelZero(edgesTex, texcoord).rg; - texcoord = mad(-float2(0.0, API_V_DIR(2.0)), SMAA_RT_METRICS.xy, texcoord); - } - float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e.gr, 0.0), 3.25); - return mad(SMAA_RT_METRICS.y, API_V_DIR(offset), texcoord.y); -} - -float SMAASearchYDown(SMAATexture2D(edgesTex), SMAATexture2D(searchTex), float2 texcoord, float end) { - float2 e = float2(1.0, 0.0); - while (API_V_ABOVE(texcoord.y, end) && - e.r > 0.8281 && // Is there some edge not activated? - e.g == 0.0) { // Or is there a crossing edge that breaks the line? - e = SMAASampleLevelZero(edgesTex, texcoord).rg; - texcoord = mad(float2(0.0, API_V_DIR(2.0)), SMAA_RT_METRICS.xy, texcoord); - } - float offset = mad(-(255.0 / 127.0), SMAASearchLength(SMAATexturePass2D(searchTex), e.gr, 0.5), 3.25); - return mad(-SMAA_RT_METRICS.y, API_V_DIR(offset), texcoord.y); -} - -/** - * Ok, we have the distance and both crossing edges. So, what are the areas - * at each side of current edge? - */ -float2 SMAAArea(SMAATexture2D(areaTex), float2 dist, float e1, float e2, float offset) { - // Rounding prevents precision errors of bilinear filtering: - float2 texcoord = mad(float2(SMAA_AREATEX_MAX_DISTANCE, SMAA_AREATEX_MAX_DISTANCE), round(4.0 * float2(e1, e2)), dist); - - // We do a scale and bias for mapping to texel space: - texcoord = mad(SMAA_AREATEX_PIXEL_SIZE, texcoord, 0.5 * SMAA_AREATEX_PIXEL_SIZE); - - // Move to proper place, according to the subpixel offset: - texcoord.y = mad(SMAA_AREATEX_SUBTEX_SIZE, offset, texcoord.y); - - texcoord.y = API_V_COORD(texcoord.y); - - // Do it! - return SMAA_AREATEX_SELECT(SMAASampleLevelZero(areaTex, texcoord)); -} - -//----------------------------------------------------------------------------- -// Corner Detection Functions - -void SMAADetectHorizontalCornerPattern(SMAATexture2D(edgesTex), inout float2 weights, float4 texcoord, float2 d) { - #if !defined(SMAA_DISABLE_CORNER_DETECTION) - float2 leftRight = step(d.xy, d.yx); - float2 rounding = (1.0 - SMAA_CORNER_ROUNDING_NORM) * leftRight; - - rounding /= leftRight.x + leftRight.y; // Reduce blending for pixels in the center of a line. - - float2 factor = float2(1.0, 1.0); - factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(0, API_V_DIR(1))).r; - factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(1, API_V_DIR(1))).r; - factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(0, API_V_DIR(-2))).r; - factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(1, API_V_DIR(-2))).r; - - weights *= saturate(factor); - #endif -} - -void SMAADetectVerticalCornerPattern(SMAATexture2D(edgesTex), inout float2 weights, float4 texcoord, float2 d) { - #if !defined(SMAA_DISABLE_CORNER_DETECTION) - float2 leftRight = step(d.xy, d.yx); - float2 rounding = (1.0 - SMAA_CORNER_ROUNDING_NORM) * leftRight; - - rounding /= leftRight.x + leftRight.y; - - float2 factor = float2(1.0, 1.0); - factor.x -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2( 1, 0)).g; - factor.x -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2( 1, API_V_DIR(1))).g; - factor.y -= rounding.x * SMAASampleLevelZeroOffset(edgesTex, texcoord.xy, int2(-2, 0)).g; - factor.y -= rounding.y * SMAASampleLevelZeroOffset(edgesTex, texcoord.zw, int2(-2, API_V_DIR(1))).g; - - weights *= saturate(factor); - #endif -} - -//----------------------------------------------------------------------------- -// Blending Weight Calculation Pixel Shader (Second Pass) - -float4 SMAABlendingWeightCalculationPS(float2 texcoord, - float2 pixcoord, - float4 offset[3], - SMAATexture2D(edgesTex), - SMAATexture2D(areaTex), - SMAATexture2D(searchTex), - float4 subsampleIndices) { // Just pass zero for SMAA 1x, see @SUBSAMPLE_INDICES. - float4 weights = float4(0.0, 0.0, 0.0, 0.0); - - float2 e = SMAASample(edgesTex, texcoord).rg; - - SMAA_BRANCH - if (e.g > 0.0) { // Edge at north - #if !defined(SMAA_DISABLE_DIAG_DETECTION) - // Diagonals have both north and west edges, so searching for them in - // one of the boundaries is enough. - weights.rg = SMAACalculateDiagWeights(SMAATexturePass2D(edgesTex), SMAATexturePass2D(areaTex), texcoord, e, subsampleIndices); - - // We give priority to diagonals, so if we find a diagonal we skip - // horizontal/vertical processing. - SMAA_BRANCH - if (weights.r == -weights.g) { // weights.r + weights.g == 0.0 - #endif - - float2 d; - - // Find the distance to the left: - float3 coords; - coords.x = SMAASearchXLeft(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[0].xy, offset[2].x); - coords.y = offset[1].y; // offset[1].y = texcoord.y - 0.25 * SMAA_RT_METRICS.y (@CROSSING_OFFSET) - d.x = coords.x; - - // Now fetch the left crossing edges, two at a time using bilinear - // filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to - // discern what value each edge has: - float e1 = SMAASampleLevelZero(edgesTex, coords.xy).r; - - // Find the distance to the right: - coords.z = SMAASearchXRight(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[0].zw, offset[2].y); - d.y = coords.z; - - // We want the distances to be in pixel units (doing this here allow to - // better interleave arithmetic and memory accesses): - d = abs(round(mad(SMAA_RT_METRICS.zz, d, -pixcoord.xx))); - - // SMAAArea below needs a sqrt, as the areas texture is compressed - // quadratically: - float2 sqrt_d = sqrt(d); - - // Fetch the right crossing edges: - float e2 = SMAASampleLevelZeroOffset(edgesTex, coords.zy, int2(1, 0)).r; - - // Ok, we know how this pattern looks like, now it is time for getting - // the actual area: - weights.rg = SMAAArea(SMAATexturePass2D(areaTex), sqrt_d, e1, e2, subsampleIndices.y); - - // Fix corners: - coords.y = texcoord.y; - SMAADetectHorizontalCornerPattern(SMAATexturePass2D(edgesTex), weights.rg, coords.xyzy, d); - - #if !defined(SMAA_DISABLE_DIAG_DETECTION) - } else - e.r = 0.0; // Skip vertical processing. - #endif - } - - SMAA_BRANCH - if (e.r > 0.0) { // Edge at west - float2 d; - - // Find the distance to the top: - float3 coords; - coords.y = SMAASearchYUp(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[1].xy, offset[2].z); - coords.x = offset[0].x; // offset[1].x = texcoord.x - 0.25 * SMAA_RT_METRICS.x; - d.x = coords.y; - - // Fetch the top crossing edges: - float e1 = SMAASampleLevelZero(edgesTex, coords.xy).g; - - // Find the distance to the bottom: - coords.z = SMAASearchYDown(SMAATexturePass2D(edgesTex), SMAATexturePass2D(searchTex), offset[1].zw, offset[2].w); - d.y = coords.z; - - // We want the distances to be in pixel units: - d = abs(round(mad(SMAA_RT_METRICS.ww, d, -pixcoord.yy))); - - // SMAAArea below needs a sqrt, as the areas texture is compressed - // quadratically: - float2 sqrt_d = sqrt(d); - - // Fetch the bottom crossing edges: - float e2 = SMAASampleLevelZeroOffset(edgesTex, coords.xz, int2(0, API_V_DIR(1))).g; - - // Get the area for this direction: - weights.ba = SMAAArea(SMAATexturePass2D(areaTex), sqrt_d, e1, e2, subsampleIndices.x); - - // Fix corners: - coords.x = texcoord.x; - SMAADetectVerticalCornerPattern(SMAATexturePass2D(edgesTex), weights.ba, coords.xyxz, d); - } - - return weights; -} - -//----------------------------------------------------------------------------- -// Neighborhood Blending Pixel Shader (Third Pass) - -float4 SMAANeighborhoodBlendingPS(float2 texcoord, - float4 offset, - SMAATexture2D(colorTex), - SMAATexture2D(blendTex) - #if SMAA_REPROJECTION - , SMAATexture2D(velocityTex) - #endif - ) { - // Fetch the blending weights for current pixel: - float4 a; - a.x = SMAASample(blendTex, offset.xy).a; // Right - a.y = SMAASample(blendTex, offset.zw).g; // Top - a.wz = SMAASample(blendTex, texcoord).xz; // Bottom / Left - - // Is there any blending weight with a value greater than 0.0? - SMAA_BRANCH - if (dot(a, float4(1.0, 1.0, 1.0, 1.0)) < 1e-5) { - float4 color = SMAASampleLevelZero(colorTex, texcoord); - - #if SMAA_REPROJECTION - float2 velocity = SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, texcoord)); - - // Pack velocity into the alpha channel: - color.a = sqrt(5.0 * length(velocity)); - #endif - - return color; - } else { - bool h = max(a.x, a.z) > max(a.y, a.w); // max(horizontal) > max(vertical) - - // Calculate the blending offsets: - float4 blendingOffset = float4(0.0, API_V_DIR(a.y), 0.0, API_V_DIR(a.w)); - float2 blendingWeight = a.yw; - SMAAMovc(bool4(h, h, h, h), blendingOffset, float4(a.x, 0.0, a.z, 0.0)); - SMAAMovc(bool2(h, h), blendingWeight, a.xz); - blendingWeight /= dot(blendingWeight, float2(1.0, 1.0)); - - // Calculate the texture coordinates: - float4 blendingCoord = mad(blendingOffset, float4(SMAA_RT_METRICS.xy, -SMAA_RT_METRICS.xy), texcoord.xyxy); - - // We exploit bilinear filtering to mix current pixel with the chosen - // neighbor: - float4 color = blendingWeight.x * SMAASampleLevelZero(colorTex, blendingCoord.xy); - color += blendingWeight.y * SMAASampleLevelZero(colorTex, blendingCoord.zw); - - #if SMAA_REPROJECTION - // Antialias velocity for proper reprojection in a later stage: - float2 velocity = blendingWeight.x * SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, blendingCoord.xy)); - velocity += blendingWeight.y * SMAA_DECODE_VELOCITY(SMAASampleLevelZero(velocityTex, blendingCoord.zw)); - - // Pack velocity into the alpha channel: - color.a = sqrt(5.0 * length(velocity)); - #endif - - return color; - } -} - -//----------------------------------------------------------------------------- -// Temporal Resolve Pixel Shader (Optional Pass) - -float4 SMAAResolvePS(float2 texcoord, - SMAATexture2D(currentColorTex), - SMAATexture2D(previousColorTex) - #if SMAA_REPROJECTION - , SMAATexture2D(velocityTex) - #endif - ) { - #if SMAA_REPROJECTION - // Velocity is assumed to be calculated for motion blur, so we need to - // inverse it for reprojection: - float2 velocity = -SMAA_DECODE_VELOCITY(SMAASamplePoint(velocityTex, texcoord).rg); - - // Fetch current pixel: - float4 current = SMAASamplePoint(currentColorTex, texcoord); - - // Reproject current coordinates and fetch previous pixel: - float4 previous = SMAASamplePoint(previousColorTex, texcoord + velocity); - - // Attenuate the previous pixel if the velocity is different: - float delta = abs(current.a * current.a - previous.a * previous.a) / 5.0; - float weight = 0.5 * saturate(1.0 - sqrt(delta) * SMAA_REPROJECTION_WEIGHT_SCALE); - - // Blend the pixels according to the calculated weight: - return lerp(current, previous, weight); - #else - // Just blend the pixels: - float4 current = SMAASamplePoint(currentColorTex, texcoord); - float4 previous = SMAASamplePoint(previousColorTex, texcoord); - return lerp(current, previous, 0.5); - #endif -} - -//----------------------------------------------------------------------------- -// Separate Multisamples Pixel Shader (Optional Pass) - -#ifdef SMAALoad -void SMAASeparatePS(float4 position, - float2 texcoord, - out float4 target0, - out float4 target1, - SMAATexture2DMS2(colorTexMS)) { - int2 pos = int2(position.xy); - target0 = SMAALoad(colorTexMS, pos, 0); - target1 = SMAALoad(colorTexMS, pos, 1); -} -#endif - -//----------------------------------------------------------------------------- -#endif // SMAA_INCLUDE_PS diff --git a/shaders/smaa_common.glsl b/shaders/smaa_common.glsl deleted file mode 100755 index 46a2fa5..0000000 --- a/shaders/smaa_common.glsl +++ /dev/null @@ -1,12 +0,0 @@ -#define SMAA_RT_METRICS viewport - -#define SMAA_PRESET_ULTRA 1 -#define SMAA_GLSL_4 1 -#define SMAA_PREDICATION 1 - -layout(std430, push_constant, binding = 2) uniform PushConstant { - vec4 viewport; - mat4 correctionMatrix; -}; - -#include "smaa.glsl" diff --git a/shaders/text.frag.glsl b/shaders/text.frag.glsl deleted file mode 100755 index 27a632a..0000000 --- a/shaders/text.frag.glsl +++ /dev/null @@ -1,15 +0,0 @@ -layout(location = 0) in vec2 inUV; - -layout (location = 0) out vec4 outColor; - -layout (binding = 3) uniform sampler2D fontSampler; - -vec4 toSRGB(vec4 v) { - return vec4(pow(v.rgb, vec3(2.2)), v.a); -} - -void main() { - outColor = vec4(vec3(texture(fontSampler, inUV).r), texture(fontSampler, inUV).r); - - outColor = toSRGB(outColor); -} diff --git a/shaders/text.vert.glsl b/shaders/text.vert.glsl deleted file mode 100755 index 2a2ac86..0000000 --- a/shaders/text.vert.glsl +++ /dev/null @@ -1,61 +0,0 @@ -#extension GL_GOOGLE_include_directive : require -#include "font.glsl" - -layout(location = 0) out vec2 outUV; - -struct GlyphInstance { - uint position, index, instance; -}; - -struct StringInstance { - uint xy; -}; - -struct GlyphMetric { - uint x0_y0, x1_y1; - float xoff, yoff; - float xoff2, yoff2; -}; - -layout(std430, binding = 0) buffer readonly InstanceBuffer { - GlyphInstance instances[]; -}; - -layout(std430, binding = 1) buffer readonly MetricBuffer { - GlyphMetric metrics[]; -}; - -layout(std430, binding = 2) buffer readonly StringBuffer { - StringInstance strings[]; -}; - -layout(push_constant, binding = 4) uniform readonly PushConstant{ - vec2 screenSize; - mat4 mvp; -}; - -void main() { - const GlyphInstance instance = instances[gl_InstanceIndex]; - const GlyphMetric metric = metrics[getLower(instance.index)]; - - vec2 p = vec2(gl_VertexIndex % 2, gl_VertexIndex / 2); - - const vec2 p0 = uint_to_vec2(metric.x0_y0); - const vec2 p1 = uint_to_vec2(metric.x1_y1); - - outUV = (p0 + (p1 - p0) * p) / vec2(2048, 1132); - - p *= vec2(metric.xoff2 - metric.xoff, metric.yoff2 - metric.yoff); - p += vec2(metric.xoff, metric.yoff); - p += fixed2_to_vec2(instance.position); - p += vec2(0, 18.2316); - - const StringInstance string = strings[instance.instance]; - - p += fixed2_to_vec2(string.xy); - p *= vec2(1, -1); - p *= 2.0 / screenSize; - p += vec2(-1, 1); - - gl_Position = mvp * vec4(p, 0.0, 1.0); -} diff --git a/shaders/ui.frag.glsl b/shaders/ui.frag.glsl deleted file mode 100755 index bbef2cc..0000000 --- a/shaders/ui.frag.glsl +++ /dev/null @@ -1,22 +0,0 @@ -layout (location = 0) in vec2 inUV; -layout (location = 1) in vec4 inColor; - -layout (location = 0) out vec4 outColor; - -layout (binding = 2) uniform sampler2D colorSampler; - -vec4 toSRGB(vec4 v) { - return vec4(pow(v.rgb, vec3(2.2)), v.a); -} - -void main() { - if(inColor.a == 0.0) - discard; - - if(textureSize(colorSampler, 0).x > 1) - outColor = texture(colorSampler, inUV); - else - outColor = inColor; - - outColor = toSRGB(outColor); -} diff --git a/shaders/ui.vert.glsl b/shaders/ui.vert.glsl deleted file mode 100755 index c88733d..0000000 --- a/shaders/ui.vert.glsl +++ /dev/null @@ -1,38 +0,0 @@ -#extension GL_GOOGLE_include_directive : require -#include "font.glsl" - -layout (location = 0) out vec2 outUV; -layout (location = 1) out vec4 outColor; - -struct ElementInstance { - vec4 color; - uint position, size; - uint padding[2]; -}; - -layout(std430, binding = 0) buffer readonly ElementBuffer { - ElementInstance elements[]; -}; - -layout(push_constant, binding = 1) uniform readonly PushConstant{ - vec2 screenSize; - mat4 mvp; -}; - -void main() { - const ElementInstance instance = elements[gl_InstanceIndex]; - - vec2 p = vec2(gl_VertexIndex % 2, gl_VertexIndex / 2); - outUV = p; - - p *= fixed2_to_vec2(instance.size); - p += fixed2_to_vec2(instance.position); - p *= vec2(1, -1); - p *= 2.0 / screenSize; - p += vec2(-1, 1); - - outColor = instance.color; - - gl_Position = mvp * vec4(p, 0.0, 1.0); -} - diff --git a/tools/common/src/debugpass.cpp b/tools/common/src/debugpass.cpp index 903f704..454c90a 100755 --- a/tools/common/src/debugpass.cpp +++ b/tools/common/src/debugpass.cpp @@ -21,8 +21,8 @@ void DebugPass::initialize() { { GFXGraphicsPipelineCreateInfo createInfo; - createInfo.shaders.vertex_src = file::Path("debug.vert"); - createInfo.shaders.fragment_src = file::Path("debug.frag"); + createInfo.shaders.vertex_src = ShaderSource(file::Path("debug.vert")); + createInfo.shaders.fragment_src = ShaderSource(file::Path("debug.frag")); GFXVertexInput vertexInput = {}; vertexInput.stride = sizeof(Vector3); @@ -69,8 +69,8 @@ void DebugPass::initialize() { // pipeline GFXGraphicsPipelineCreateInfo pipelineInfo = {}; - pipelineInfo.shaders.vertex_src = file::Path("color.vert"); - pipelineInfo.shaders.fragment_src = file::Path("color.frag"); + pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("color.vert")); + pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("color.frag")); GFXVertexInput input; input.stride = sizeof(Vector3); @@ -110,8 +110,8 @@ void DebugPass::initialize() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Sobel"; - pipelineInfo.shaders.vertex_src = file::Path("color.vert"); - pipelineInfo.shaders.fragment_src = file::Path("color.frag"); + pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("color.vert")); + pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("color.frag")); GFXVertexInput input; input.stride = sizeof(Vector3); @@ -142,8 +142,8 @@ void DebugPass::initialize() { GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Billboard"; - pipelineInfo.shaders.vertex_src = file::Path("billboard.vert"); - pipelineInfo.shaders.fragment_src = file::Path("billboard.frag"); + pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("billboard.vert")); + pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("billboard.frag")); pipelineInfo.shader_input.bindings = { {1, GFXBindingType::PushConstant}, diff --git a/tools/shadercompiler/main.cpp b/tools/shadercompiler/main.cpp index ab1ad10..d3ddc12 100755 --- a/tools/shadercompiler/main.cpp +++ b/tools/shadercompiler/main.cpp @@ -27,16 +27,10 @@ int main(int argc, char* argv[]) { buffer << t.rdbuf(); if(has_extension(source_path, "nocompile")) { - std::string outname = argv[2]; - outname = outname.substr(0, outname.length() - 5); // remove .glsl - outname = outname.substr(0, outname.length() - 10); // remove .nocompile - - std::ofstream out(outname + ".glsl"); + destination_path = remove_substring(destination_path.string(), ".nocompile"); // remove extension + + std::ofstream out(destination_path); out << buffer.rdbuf(); - - prism::log::info(System::Core, "Successfully written {} to {}.", source_path, destination_path); - - return 0; } else { ShaderStage stage = ShaderStage::Vertex; if(has_extension(source_path, ".vert")) @@ -52,13 +46,11 @@ int main(int argc, char* argv[]) { options.is_apple_mobile = (bool)argv[3]; language = ShaderLanguage::MSL; - destination_path.replace_extension(".msl"); #else language = ShaderLanguage::SPIRV; - destination_path.replace_extension(".spv"); #endif - const auto compiled_source = shader_compiler.compile(ShaderLanguage::GLSL, stage, buffer.str(), language, options); + const auto compiled_source = shader_compiler.compile(ShaderLanguage::GLSL, stage, ShaderSource(buffer.str()), language, options); if(!compiled_source.has_value()) { prism::log::error(System::Core, "Error when compiling {}!", source_path); return -1; @@ -82,9 +74,10 @@ int main(int argc, char* argv[]) { default: break; } - - prism::log::info(System::Core, "Successfully written shader from {} to {}.", source_path, destination_path); - - return 0; } + + // TODO: output disabled for now, will have to expose in a better arg system + //prism::log::info(System::Core, "Successfully written shader from {} to {}.", source_path, destination_path); + + return 0; }