Archived
1
Fork 0

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.
This commit is contained in:
redstrate 2021-05-09 19:10:23 -04:00
parent 7b23fdfa09
commit 87f15b2007
60 changed files with 281 additions and 3428 deletions

View file

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.17) cmake_minimum_required(VERSION 3.20)
project(PrismEngine) project(PrismEngine)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)

View file

@ -1,47 +1,56 @@
macro(compile_shader src) # add custom command to output compiled shader
string(REGEX REPLACE "\\.[^.]*$" "" MYFILE_WITHOUT_EXT ${src}) function(add_shader_command)
cmake_parse_arguments(ARGS "" "FILENAME;OUT" "" ${ARGN})
set(SHADER_COMPILER_COMMAND $<TARGET_FILE:ShaderCompilerTool>) cmake_path(REMOVE_EXTENSION ARGS_FILENAME LAST_ONLY OUTPUT_VARIABLE FILENAME_WITHOUT_EXT)
set(SHADER_COMPILER_COMMAND $<TARGET_FILE:ShaderCompilerTool>)
set(EXTRA_PLATFORM_ARG "0")
# if targeting ios, we want to use the host's shader compiler
if(ENABLE_IOS) 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() endif()
set(EXTRA_PLATFORM_ARG "0") set(SRC_FILENAME ${CMAKE_CURRENT_SOURCE_DIR}/${ARGS_FILENAME})
if(ENABLE_IOS) set(OUTPUT_FILENAME ${CMAKE_BINARY_DIR}/${FILENAME_WITHOUT_EXT})
set(EXTRA_PLATFORM_ARG "1")
# 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() endif()
add_custom_command( add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/${MYFILE_WITHOUT_EXT}.glsl OUTPUT ${OUTPUT_FILENAME}
COMMAND ${SHADER_COMPILER_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/../../${src} ${CMAKE_BINARY_DIR}/${src} ${EXTRA_PLATFORM_ARG} COMMAND ${SHADER_COMPILER_COMMAND} ${SRC_FILENAME} ${OUTPUT_FILENAME} ${EXTRA_PLATFORM_ARG}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../../${src} DEPENDS ${SRC_FILENAME}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../shaders WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/shaders)
)
endmacro()
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) if(NOT ENABLE_IOS)
set(options OPTIONAL FAST) cmake_parse_arguments(ARGS "" "TARGET" "SHADERS" ${ARGN})
set(oneValueArgs TARGET)
set(multiValueArgs SHADERS)
cmake_parse_arguments(add_shader "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
foreach(shader ${add_shader_SHADERS}) foreach(SHADER_FILENAME ${ARGS_SHADERS})
string(REGEX REPLACE "\\.[^.]*$" "" MYFILE_WITHOUT_EXT ${shader}) 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_FILENAME})
list(APPEND SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../${shader}) list(APPEND DST_FILES ${DST_FILENAME})
endforeach() endforeach()
add_custom_target(Shaders SOURCES ${SRC_FILES}) add_custom_target(BuildShaders DEPENDS ShaderCompilerTool ${DST_FILES})
add_dependencies(${ARGS_TARGET} BuildShaders)
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)
endif() endif()
endfunction() endfunction()
# make the shader directory if it doesnt exist already
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/shaders)

View file

@ -13,4 +13,48 @@ add_subdirectory(platform)
if(NOT ENABLE_IOS AND NOT ENABLE_TVOS) if(NOT ENABLE_IOS AND NOT ENABLE_TVOS)
add_subdirectory(audio) add_subdirectory(audio)
add_subdirectory(tests) add_subdirectory(tests)
endif() 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)

View file

@ -35,48 +35,4 @@ target_link_libraries(Renderer
ShaderCompiler ShaderCompiler
Core) Core)
target_include_directories(Renderer PUBLIC include) target_include_directories(Renderer PUBLIC include)
set_engine_properties(Renderer) 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)

View file

@ -28,9 +28,9 @@ DoFPass::DoFPass(GFX* gfx, prism::renderer* renderer) : renderer(renderer) {
height_constant.value = extent.height; height_constant.value = extent.height;
GFXGraphicsPipelineCreateInfo create_info = {}; 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.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 = { create_info.shader_input.bindings = {
{0, GFXBindingType::StorageImage}, {0, GFXBindingType::StorageImage},

View file

@ -23,8 +23,8 @@ void ImGuiPass::create_render_target_resources(RenderTarget& target) {
if(pipeline == nullptr) { if(pipeline == nullptr) {
GFXGraphicsPipelineCreateInfo createInfo; GFXGraphicsPipelineCreateInfo createInfo;
createInfo.label = "ImGui"; createInfo.label = "ImGui";
createInfo.shaders.vertex_src = file::Path("imgui.vert"); createInfo.shaders.vertex_src = ShaderSource(file::Path("imgui.vert"));
createInfo.shaders.fragment_src = file::Path("imgui.frag"); createInfo.shaders.fragment_src = ShaderSource(file::Path("imgui.frag"));
GFXVertexInput vertexInput = {}; GFXVertexInput vertexInput = {};
vertexInput.stride = sizeof(ImDrawVert); vertexInput.stride = sizeof(ImDrawVert);

View file

@ -31,7 +31,7 @@ ShaderSource get_shader(std::string filename, bool skinned, bool cubemap) {
if(cubemap) if(cubemap)
options.add_definition("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) { 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"; 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());
} }

View file

@ -144,8 +144,8 @@ void renderer::resize_render_target(RenderTarget& target, const prism::Extent ex
GFXGraphicsPipelineCreateInfo pipelineInfo = {}; GFXGraphicsPipelineCreateInfo pipelineInfo = {};
pipelineInfo.label = "Text"; pipelineInfo.label = "Text";
pipelineInfo.shaders.vertex_src = file::Path("text.vert"); pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("text.vert"));
pipelineInfo.shaders.fragment_src = file::Path("text.frag"); pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("text.frag"));
pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip; pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip;
@ -713,8 +713,8 @@ void renderer::create_mesh_pipeline(Material& material) const {
GFXGraphicsPipelineCreateInfo pipelineInfo = {}; GFXGraphicsPipelineCreateInfo pipelineInfo = {};
pipelineInfo.label = "Mesh"; pipelineInfo.label = "Mesh";
pipelineInfo.shaders.vertex_src = file::Path("mesh.vert"); pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("mesh.vert"));
pipelineInfo.shaders.fragment_src = file::Path("mesh.frag"); pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("mesh.frag"));
pipelineInfo.shaders.vertex_constants = {materials_constant, lights_constant, spot_lights_constant, probes_constant}; 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}; 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 = {}; GFXGraphicsPipelineCreateInfo pipelineInfo = {};
pipelineInfo.label = "Post"; pipelineInfo.label = "Post";
pipelineInfo.shaders.vertex_src = file::Path("post.vert"); pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("post.vert"));
pipelineInfo.shaders.fragment_src = file::Path("post.frag"); pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("post.frag"));
pipelineInfo.shader_input.bindings = { pipelineInfo.shader_input.bindings = {
{4, GFXBindingType::PushConstant}, {4, GFXBindingType::PushConstant},
@ -835,8 +835,8 @@ void renderer::create_post_pipelines() {
GFXGraphicsPipelineCreateInfo pipelineInfo = {}; GFXGraphicsPipelineCreateInfo pipelineInfo = {};
pipelineInfo.label = "Post"; pipelineInfo.label = "Post";
pipelineInfo.shaders.vertex_src = file::Path("post.vert"); pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("post.vert"));
pipelineInfo.shaders.fragment_src = file::Path("post.frag"); pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("post.frag"));
pipelineInfo.shader_input.bindings = { pipelineInfo.shader_input.bindings = {
{4, GFXBindingType::PushConstant}, {4, GFXBindingType::PushConstant},
@ -914,8 +914,8 @@ void renderer::create_ui_pipelines() {
GFXGraphicsPipelineCreateInfo pipelineInfo = {}; GFXGraphicsPipelineCreateInfo pipelineInfo = {};
pipelineInfo.label = "UI"; pipelineInfo.label = "UI";
pipelineInfo.shaders.vertex_src = file::Path("ui.vert"); pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("ui.vert"));
pipelineInfo.shaders.fragment_src = file::Path("ui.frag"); pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("ui.frag"));
pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip; pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip;
@ -953,8 +953,8 @@ void renderer::generate_brdf() {
GFXGraphicsPipelineCreateInfo pipelineInfo = {}; GFXGraphicsPipelineCreateInfo pipelineInfo = {};
pipelineInfo.label = "BRDF"; pipelineInfo.label = "BRDF";
pipelineInfo.shaders.vertex_src = file::Path("brdf.vert"); pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("brdf.vert"));
pipelineInfo.shaders.fragment_src = file::Path("brdf.frag"); pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("brdf.frag"));
pipelineInfo.render_pass = brdf_render_pass; 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 shader editor system is not initialized, use prebuilt shaders
if(base_shader_path.empty()) 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()); 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()) { if(found_shader_source.empty()) {
auto file = file::open(base_shader_path / shader_path.replace_extension(shader_path.extension().string() + ".glsl")); 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 { } 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();
} }
} }

View file

@ -399,8 +399,8 @@ void SceneCapture::createSkyResources() {
pipelineInfo.label = "Sky Scene Capture"; pipelineInfo.label = "Sky Scene Capture";
pipelineInfo.render_pass = renderPass; pipelineInfo.render_pass = renderPass;
pipelineInfo.shaders.vertex_src = file::Path("sky.vert"); pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("sky.vert"));
pipelineInfo.shaders.fragment_src = file::Path("sky.frag"); pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("sky.frag"));
pipelineInfo.shader_input.bindings = { pipelineInfo.shader_input.bindings = {
{1, GFXBindingType::PushConstant} {1, GFXBindingType::PushConstant}
@ -443,8 +443,8 @@ void SceneCapture::createIrradianceResources() {
GFXGraphicsPipelineCreateInfo pipelineInfo = {}; GFXGraphicsPipelineCreateInfo pipelineInfo = {};
pipelineInfo.label = "Irradiance Convolution"; pipelineInfo.label = "Irradiance Convolution";
pipelineInfo.shaders.vertex_src = file::Path("irradiance.vert"); pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("irradiance.vert"));
pipelineInfo.shaders.fragment_src = file::Path("irradiance.frag"); pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("irradiance.frag"));
GFXVertexInput input; GFXVertexInput input;
input.stride = sizeof(Vector3); input.stride = sizeof(Vector3);
@ -495,8 +495,8 @@ void SceneCapture::createPrefilterResources() {
GFXGraphicsPipelineCreateInfo pipelineInfo = {}; GFXGraphicsPipelineCreateInfo pipelineInfo = {};
pipelineInfo.label = "Prefilter"; pipelineInfo.label = "Prefilter";
pipelineInfo.shaders.vertex_src = file::Path("filter.vert"); pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("filter.vert"));
pipelineInfo.shaders.fragment_src = file::Path("filter.frag"); pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("filter.frag"));
pipelineInfo.shaders.fragment_constants = {size_constant}; pipelineInfo.shaders.fragment_constants = {size_constant};

View file

@ -320,11 +320,10 @@ void ShadowPass::create_pipelines() {
GFXGraphicsPipelineCreateInfo pipelineInfo = {}; GFXGraphicsPipelineCreateInfo pipelineInfo = {};
pipelineInfo.shaders.vertex_constants = {point_light_max_constant}; 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_constants = { point_light_max_constant };
//pipelineInfo.shaders.fragment_path = "shadow.frag";
pipelineInfo.shader_input.bindings = { pipelineInfo.shader_input.bindings = {
{0, GFXBindingType::PushConstant}, {0, GFXBindingType::PushConstant},
{1, GFXBindingType::StorageBuffer}, {1, GFXBindingType::StorageBuffer},
@ -365,7 +364,7 @@ void ShadowPass::create_pipelines() {
{ {
pipelineInfo.label = "Point Shadow"; 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); auto [static_pipeline, skinned_pipeline] = material_compiler.create_pipeline_permutations(pipelineInfo, true);

View file

@ -137,8 +137,8 @@ void SMAAPass::create_pipelines() {
GFXGraphicsPipelineCreateInfo createInfo = {}; GFXGraphicsPipelineCreateInfo createInfo = {};
createInfo.label = "SMAA Edge"; createInfo.label = "SMAA Edge";
createInfo.shaders.vertex_src = file::Path("edge.vert"); createInfo.shaders.vertex_src = ShaderSource(file::Path("edge.vert"));
createInfo.shaders.fragment_src = file::Path("edge.frag"); createInfo.shaders.fragment_src = ShaderSource(file::Path("edge.frag"));
createInfo.render_pass = render_pass; createInfo.render_pass = render_pass;
@ -155,8 +155,8 @@ void SMAAPass::create_pipelines() {
edge_pipeline = gfx->create_graphics_pipeline(createInfo); edge_pipeline = gfx->create_graphics_pipeline(createInfo);
createInfo.label = "SMAA Blend"; createInfo.label = "SMAA Blend";
createInfo.shaders.vertex_src = file::Path("blend.vert"); createInfo.shaders.vertex_src = ShaderSource(file::Path("blend.vert"));
createInfo.shaders.fragment_src = file::Path("blend.frag"); createInfo.shaders.fragment_src = ShaderSource(file::Path("blend.frag"));
createInfo.shader_input.bindings.push_back({3, GFXBindingType::Texture}); createInfo.shader_input.bindings.push_back({3, GFXBindingType::Texture});
blend_pipeline = gfx->create_graphics_pipeline(createInfo); blend_pipeline = gfx->create_graphics_pipeline(createInfo);

View file

@ -41,36 +41,36 @@ class ShaderSource {
public: public:
ShaderSource() : source(std::monostate()) {} ShaderSource() : source(std::monostate()) {}
ShaderSource(const ShaderSource& rhs) : source (rhs.source) {} ShaderSource(const ShaderSource& rhs) : source (rhs.source) {}
ShaderSource(const std::string source_string) : source(source_string) {} explicit ShaderSource(const std::string& source_string) : source(source_string) {}
ShaderSource(const std::vector<uint32_t> source_bytecode) : source(source_bytecode) {} explicit ShaderSource(const std::vector<uint32_t>& source_bytecode) : source(source_bytecode) {}
ShaderSource(const file::Path shader_path) : source(shader_path) {} explicit ShaderSource(const file::Path& shader_path) : source(shader_path) {}
std::variant<std::monostate, file::Path, std::string, std::vector<uint32_t>> source; std::variant<std::monostate, file::Path, std::string, std::vector<uint32_t>> source;
/// Returns a view of the shader source as a path. /// Returns a view of the shader source as a path.
file::Path as_path() const { [[nodiscard]] file::Path as_path() const {
return std::get<file::Path>(source); return std::get<file::Path>(source);
} }
/// Returns a view of the shader source as plaintext. /// 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<std::string>(source); return std::get<std::string>(source);
} }
/// Returns a copy of the shader source as bytecode. /// Returns a copy of the shader source as bytecode.
std::vector<uint32_t> as_bytecode() const { [[nodiscard]] std::vector<uint32_t> as_bytecode() const {
return std::get<std::vector<uint32_t>>(source); return std::get<std::vector<uint32_t>>(source);
} }
bool empty() const { [[nodiscard]] bool empty() const {
return std::holds_alternative<std::monostate>(source); return std::holds_alternative<std::monostate>(source);
} }
bool is_path() const { [[nodiscard]] bool is_path() const {
return std::holds_alternative<file::Path>(source); return std::holds_alternative<file::Path>(source);
} }
bool is_string() const { [[nodiscard]] bool is_string() const {
return std::holds_alternative<std::string>(source); return std::holds_alternative<std::string>(source);
} }
}; };
@ -81,7 +81,7 @@ public:
ShaderCompiler(); ShaderCompiler();
/// Sets the include directory used to search for files inside of #include directives. /// 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. Compiles from one shader language to another shader language.
@ -92,7 +92,7 @@ public:
@param options Optional compilation parameters. @param options Optional compilation parameters.
@note Right now, only GLSL is supported as a source shader language. @note Right now, only GLSL is supported as a source shader language.
*/ */
std::optional<ShaderSource> compile(const ShaderLanguage from_language, const ShaderStage shader_stage, const ShaderSource& shader_source, const ShaderLanguage to_language, const CompileOptions& options = CompileOptions()); std::optional<ShaderSource> compile(ShaderLanguage from_language, ShaderStage shader_stage, const ShaderSource& shader_source, ShaderLanguage to_language, const CompileOptions& options = CompileOptions());
}; };
static inline ShaderCompiler shader_compiler; static inline ShaderCompiler shader_compiler;

View file

@ -1,108 +1,109 @@
#pragma once #pragma once
const TBuiltInResource DefaultTBuiltInResource = { const TBuiltInResource DefaultTBuiltInResource = {
/* .MaxLights = */ 32, /* .MaxLights = */ 32,
/* .MaxClipPlanes = */ 6, /* .MaxClipPlanes = */ 6,
/* .MaxTextureUnits = */ 32, /* .MaxTextureUnits = */ 32,
/* .MaxTextureCoords = */ 32, /* .MaxTextureCoords = */ 32,
/* .MaxVertexAttribs = */ 64, /* .MaxVertexAttribs = */ 64,
/* .MaxVertexUniformComponents = */ 4096, /* .MaxVertexUniformComponents = */ 4096,
/* .MaxVaryingFloats = */ 64, /* .MaxVaryingFloats = */ 64,
/* .MaxVertexTextureImageUnits = */ 32, /* .MaxVertexTextureImageUnits = */ 32,
/* .MaxCombinedTextureImageUnits = */ 80, /* .MaxCombinedTextureImageUnits = */ 80,
/* .MaxTextureImageUnits = */ 32, /* .MaxTextureImageUnits = */ 32,
/* .MaxFragmentUniformComponents = */ 4096, /* .MaxFragmentUniformComponents = */ 4096,
/* .MaxDrawBuffers = */ 32, /* .MaxDrawBuffers = */ 32,
/* .MaxVertexUniformVectors = */ 128, /* .MaxVertexUniformVectors = */ 128,
/* .MaxVaryingVectors = */ 8, /* .MaxVaryingVectors = */ 8,
/* .MaxFragmentUniformVectors = */ 16, /* .MaxFragmentUniformVectors = */ 16,
/* .MaxVertexOutputVectors = */ 16, /* .MaxVertexOutputVectors = */ 16,
/* .MaxFragmentInputVectors = */ 15, /* .MaxFragmentInputVectors = */ 15,
/* .MinProgramTexelOffset = */ -8, /* .MinProgramTexelOffset = */ -8,
/* .MaxProgramTexelOffset = */ 7, /* .MaxProgramTexelOffset = */ 7,
/* .MaxClipDistances = */ 8, /* .MaxClipDistances = */ 8,
/* .MaxComputeWorkGroupCountX = */ 65535, /* .MaxComputeWorkGroupCountX = */ 65535,
/* .MaxComputeWorkGroupCountY = */ 65535, /* .MaxComputeWorkGroupCountY = */ 65535,
/* .MaxComputeWorkGroupCountZ = */ 65535, /* .MaxComputeWorkGroupCountZ = */ 65535,
/* .MaxComputeWorkGroupSizeX = */ 1024, /* .MaxComputeWorkGroupSizeX = */ 1024,
/* .MaxComputeWorkGroupSizeY = */ 1024, /* .MaxComputeWorkGroupSizeY = */ 1024,
/* .MaxComputeWorkGroupSizeZ = */ 64, /* .MaxComputeWorkGroupSizeZ = */ 64,
/* .MaxComputeUniformComponents = */ 1024, /* .MaxComputeUniformComponents = */ 1024,
/* .MaxComputeTextureImageUnits = */ 16, /* .MaxComputeTextureImageUnits = */ 16,
/* .MaxComputeImageUniforms = */ 8, /* .MaxComputeImageUniforms = */ 8,
/* .MaxComputeAtomicCounters = */ 8, /* .MaxComputeAtomicCounters = */ 8,
/* .MaxComputeAtomicCounterBuffers = */ 1, /* .MaxComputeAtomicCounterBuffers = */ 1,
/* .MaxVaryingComponents = */ 60, /* .MaxVaryingComponents = */ 60,
/* .MaxVertexOutputComponents = */ 64, /* .MaxVertexOutputComponents = */ 64,
/* .MaxGeometryInputComponents = */ 64, /* .MaxGeometryInputComponents = */ 64,
/* .MaxGeometryOutputComponents = */ 128, /* .MaxGeometryOutputComponents = */ 128,
/* .MaxFragmentInputComponents = */ 128, /* .MaxFragmentInputComponents = */ 128,
/* .MaxImageUnits = */ 8, /* .MaxImageUnits = */ 8,
/* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8, /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8,
/* .MaxCombinedShaderOutputResources = */ 8, /* .MaxCombinedShaderOutputResources = */ 8,
/* .MaxImageSamples = */ 0, /* .MaxImageSamples = */ 0,
/* .MaxVertexImageUniforms = */ 0, /* .MaxVertexImageUniforms = */ 0,
/* .MaxTessControlImageUniforms = */ 0, /* .MaxTessControlImageUniforms = */ 0,
/* .MaxTessEvaluationImageUniforms = */ 0, /* .MaxTessEvaluationImageUniforms = */ 0,
/* .MaxGeometryImageUniforms = */ 0, /* .MaxGeometryImageUniforms = */ 0,
/* .MaxFragmentImageUniforms = */ 8, /* .MaxFragmentImageUniforms = */ 8,
/* .MaxCombinedImageUniforms = */ 8, /* .MaxCombinedImageUniforms = */ 8,
/* .MaxGeometryTextureImageUnits = */ 16, /* .MaxGeometryTextureImageUnits = */ 16,
/* .MaxGeometryOutputVertices = */ 256, /* .MaxGeometryOutputVertices = */ 256,
/* .MaxGeometryTotalOutputComponents = */ 1024, /* .MaxGeometryTotalOutputComponents = */ 1024,
/* .MaxGeometryUniformComponents = */ 1024, /* .MaxGeometryUniformComponents = */ 1024,
/* .MaxGeometryVaryingComponents = */ 64, /* .MaxGeometryVaryingComponents = */ 64,
/* .MaxTessControlInputComponents = */ 128, /* .MaxTessControlInputComponents = */ 128,
/* .MaxTessControlOutputComponents = */ 128, /* .MaxTessControlOutputComponents = */ 128,
/* .MaxTessControlTextureImageUnits = */ 16, /* .MaxTessControlTextureImageUnits = */ 16,
/* .MaxTessControlUniformComponents = */ 1024, /* .MaxTessControlUniformComponents = */ 1024,
/* .MaxTessControlTotalOutputComponents = */ 4096, /* .MaxTessControlTotalOutputComponents = */ 4096,
/* .MaxTessEvaluationInputComponents = */ 128, /* .MaxTessEvaluationInputComponents = */ 128,
/* .MaxTessEvaluationOutputComponents = */ 128, /* .MaxTessEvaluationOutputComponents = */ 128,
/* .MaxTessEvaluationTextureImageUnits = */ 16, /* .MaxTessEvaluationTextureImageUnits = */ 16,
/* .MaxTessEvaluationUniformComponents = */ 1024, /* .MaxTessEvaluationUniformComponents = */ 1024,
/* .MaxTessPatchComponents = */ 120, /* .MaxTessPatchComponents = */ 120,
/* .MaxPatchVertices = */ 32, /* .MaxPatchVertices = */ 32,
/* .MaxTessGenLevel = */ 64, /* .MaxTessGenLevel = */ 64,
/* .MaxViewports = */ 16, /* .MaxViewports = */ 16,
/* .MaxVertexAtomicCounters = */ 0, /* .MaxVertexAtomicCounters = */ 0,
/* .MaxTessControlAtomicCounters = */ 0, /* .MaxTessControlAtomicCounters = */ 0,
/* .MaxTessEvaluationAtomicCounters = */ 0, /* .MaxTessEvaluationAtomicCounters = */ 0,
/* .MaxGeometryAtomicCounters = */ 0, /* .MaxGeometryAtomicCounters = */ 0,
/* .MaxFragmentAtomicCounters = */ 8, /* .MaxFragmentAtomicCounters = */ 8,
/* .MaxCombinedAtomicCounters = */ 8, /* .MaxCombinedAtomicCounters = */ 8,
/* .MaxAtomicCounterBindings = */ 1, /* .MaxAtomicCounterBindings = */ 1,
/* .MaxVertexAtomicCounterBuffers = */ 0, /* .MaxVertexAtomicCounterBuffers = */ 0,
/* .MaxTessControlAtomicCounterBuffers = */ 0, /* .MaxTessControlAtomicCounterBuffers = */ 0,
/* .MaxTessEvaluationAtomicCounterBuffers = */ 0, /* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
/* .MaxGeometryAtomicCounterBuffers = */ 0, /* .MaxGeometryAtomicCounterBuffers = */ 0,
/* .MaxFragmentAtomicCounterBuffers = */ 1, /* .MaxFragmentAtomicCounterBuffers = */ 1,
/* .MaxCombinedAtomicCounterBuffers = */ 1, /* .MaxCombinedAtomicCounterBuffers = */ 1,
/* .MaxAtomicCounterBufferSize = */ 16384, /* .MaxAtomicCounterBufferSize = */ 16384,
/* .MaxTransformFeedbackBuffers = */ 4, /* .MaxTransformFeedbackBuffers = */ 4,
/* .MaxTransformFeedbackInterleavedComponents = */ 64, /* .MaxTransformFeedbackInterleavedComponents = */ 64,
/* .MaxCullDistances = */ 8, /* .MaxCullDistances = */ 8,
/* .MaxCombinedClipAndCullDistances = */ 8, /* .MaxCombinedClipAndCullDistances = */ 8,
/* .MaxSamples = */ 4, /* .MaxSamples = */ 4,
/* .maxMeshOutputVerticesNV = */ 256, /* .maxMeshOutputVerticesNV = */ 256,
/* .maxMeshOutputPrimitivesNV = */ 512, /* .maxMeshOutputPrimitivesNV = */ 512,
/* .maxMeshWorkGroupSizeX_NV = */ 32, /* .maxMeshWorkGroupSizeX_NV = */ 32,
/* .maxMeshWorkGroupSizeY_NV = */ 1, /* .maxMeshWorkGroupSizeY_NV = */ 1,
/* .maxMeshWorkGroupSizeZ_NV = */ 1, /* .maxMeshWorkGroupSizeZ_NV = */ 1,
/* .maxTaskWorkGroupSizeX_NV = */ 32, /* .maxTaskWorkGroupSizeX_NV = */ 32,
/* .maxTaskWorkGroupSizeY_NV = */ 1, /* .maxTaskWorkGroupSizeY_NV = */ 1,
/* .maxTaskWorkGroupSizeZ_NV = */ 1, /* .maxTaskWorkGroupSizeZ_NV = */ 1,
/* .maxMeshViewCountNV = */ 4, /* .maxMeshViewCountNV = */ 4,
/* .maxDualSourceDrawBuffersEXT = */ 4, /* .maxDualSourceDrawBuffersEXT = */ 1,
/* .limits = */ TLimits{ /* .limits = */ {
/* .nonInductiveForLoops = */ true, /* .nonInductiveForLoops = */ 1,
/* .whileLoops = */ true, /* .whileLoops = */ 1,
/* .doWhileLoops = */ true, /* .doWhileLoops = */ 1,
/* .generalUniformIndexing = */ true, /* .generalUniformIndexing = */ 1,
/* .generalAttributeMatrixVectorIndexing = */ true, /* .generalAttributeMatrixVectorIndexing = */ 1,
/* .generalVaryingIndexing = */ true, /* .generalVaryingIndexing = */ 1,
/* .generalSamplerIndexing = */ true, /* .generalSamplerIndexing = */ 1,
/* .generalVariableIndexing = */ true, /* .generalVariableIndexing = */ 1,
/* .generalConstantMatrixVectorIndexing = */ true, /* .generalConstantMatrixVectorIndexing = */ 1,
}}; }};

View file

@ -16,10 +16,10 @@ ShaderCompiler::ShaderCompiler() {
} }
void ShaderCompiler::set_include_path(const std::string_view path) { 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<uint32_t> compile_glsl_to_spv(const std::string_view source_string, const EShLanguage shader_language, const CompileOptions& options) { std::vector<uint32_t> compile_glsl_to_spv(const std::string_view source_string, const EShLanguage shader_language, const CompileOptions& options) {
std::string newString = "#version 460 core\n"; std::string newString = "#version 460 core\n";
newString += "#extension GL_GOOGLE_include_directive : enable\n"; newString += "#extension GL_GOOGLE_include_directive : enable\n";
@ -34,36 +34,35 @@ const std::vector<uint32_t> compile_glsl_to_spv(const std::string_view source_st
const char* InputCString = newString.c_str(); const char* InputCString = newString.c_str();
glslang::TShader Shader(shader_language); glslang::TShader shader(shader_language);
shader.setStrings(&InputCString, 1);
Shader.setStrings(&InputCString, 1);
int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100 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)) { shader.setEnvInput(glslang::EShSourceGlsl,
prism::log::error(System::Renderer, "{}", Shader.getInfoLog()); 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 {}; return {};
} }
glslang::TProgram Program; glslang::TProgram Program;
Program.addShader(&Shader); Program.addShader(&shader);
if(!Program.link(messages)) { if(!Program.link(EShMsgDefault)) {
prism::log::error(System::None, "Failed to link shader: {} {} {}", source_string.data(), Shader.getInfoLog(), Shader.getInfoDebugLog()); prism::log::error(System::None, "Failed to link shader: {} {} {}", source_string.data(), shader.getInfoLog(), shader.getInfoDebugLog());
return {}; return {};
} }
@ -116,10 +115,10 @@ std::optional<ShaderSource> ShaderCompiler::compile(const ShaderLanguage from_la
msl.set_msl_options(opts); msl.set_msl_options(opts);
return msl.compile(); return ShaderSource(msl.compile());
} }
case ShaderLanguage::SPIRV: case ShaderLanguage::SPIRV:
return spirv; return ShaderSource(spirv);
default: default:
return {}; return {};
} }

View file

@ -9,13 +9,13 @@ FetchContent_Declare(
FetchContent_Declare( FetchContent_Declare(
spirv-cross spirv-cross
GIT_REPOSITORY https://github.com/KhronosGroup/SPIRV-Cross.git GIT_REPOSITORY https://github.com/KhronosGroup/SPIRV-Cross.git
GIT_TAG 2020-05-19 GIT_TAG 2021-01-15
) )
FetchContent_Declare( FetchContent_Declare(
glslang glslang
GIT_REPOSITORY https://github.com/KhronosGroup/glslang.git 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 # bullet

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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)); }

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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));
}
}

View file

@ -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]);
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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]);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -1,5 +0,0 @@
layout (location = 0) in vec3 inPos;
layout (location = 1) flat in int index;
void main() {
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);
}

File diff suppressed because it is too large Load diff

View file

@ -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"

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -21,8 +21,8 @@ void DebugPass::initialize() {
{ {
GFXGraphicsPipelineCreateInfo createInfo; GFXGraphicsPipelineCreateInfo createInfo;
createInfo.shaders.vertex_src = file::Path("debug.vert"); createInfo.shaders.vertex_src = ShaderSource(file::Path("debug.vert"));
createInfo.shaders.fragment_src = file::Path("debug.frag"); createInfo.shaders.fragment_src = ShaderSource(file::Path("debug.frag"));
GFXVertexInput vertexInput = {}; GFXVertexInput vertexInput = {};
vertexInput.stride = sizeof(Vector3); vertexInput.stride = sizeof(Vector3);
@ -69,8 +69,8 @@ void DebugPass::initialize() {
// pipeline // pipeline
GFXGraphicsPipelineCreateInfo pipelineInfo = {}; GFXGraphicsPipelineCreateInfo pipelineInfo = {};
pipelineInfo.shaders.vertex_src = file::Path("color.vert"); pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("color.vert"));
pipelineInfo.shaders.fragment_src = file::Path("color.frag"); pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("color.frag"));
GFXVertexInput input; GFXVertexInput input;
input.stride = sizeof(Vector3); input.stride = sizeof(Vector3);
@ -110,8 +110,8 @@ void DebugPass::initialize() {
GFXGraphicsPipelineCreateInfo pipelineInfo = {}; GFXGraphicsPipelineCreateInfo pipelineInfo = {};
pipelineInfo.label = "Sobel"; pipelineInfo.label = "Sobel";
pipelineInfo.shaders.vertex_src = file::Path("color.vert"); pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("color.vert"));
pipelineInfo.shaders.fragment_src = file::Path("color.frag"); pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("color.frag"));
GFXVertexInput input; GFXVertexInput input;
input.stride = sizeof(Vector3); input.stride = sizeof(Vector3);
@ -142,8 +142,8 @@ void DebugPass::initialize() {
GFXGraphicsPipelineCreateInfo pipelineInfo = {}; GFXGraphicsPipelineCreateInfo pipelineInfo = {};
pipelineInfo.label = "Billboard"; pipelineInfo.label = "Billboard";
pipelineInfo.shaders.vertex_src = file::Path("billboard.vert"); pipelineInfo.shaders.vertex_src = ShaderSource(file::Path("billboard.vert"));
pipelineInfo.shaders.fragment_src = file::Path("billboard.frag"); pipelineInfo.shaders.fragment_src = ShaderSource(file::Path("billboard.frag"));
pipelineInfo.shader_input.bindings = { pipelineInfo.shader_input.bindings = {
{1, GFXBindingType::PushConstant}, {1, GFXBindingType::PushConstant},

View file

@ -27,16 +27,10 @@ int main(int argc, char* argv[]) {
buffer << t.rdbuf(); buffer << t.rdbuf();
if(has_extension(source_path, "nocompile")) { if(has_extension(source_path, "nocompile")) {
std::string outname = argv[2]; destination_path = remove_substring(destination_path.string(), ".nocompile"); // remove extension
outname = outname.substr(0, outname.length() - 5); // remove .glsl
outname = outname.substr(0, outname.length() - 10); // remove .nocompile std::ofstream out(destination_path);
std::ofstream out(outname + ".glsl");
out << buffer.rdbuf(); out << buffer.rdbuf();
prism::log::info(System::Core, "Successfully written {} to {}.", source_path, destination_path);
return 0;
} else { } else {
ShaderStage stage = ShaderStage::Vertex; ShaderStage stage = ShaderStage::Vertex;
if(has_extension(source_path, ".vert")) if(has_extension(source_path, ".vert"))
@ -52,13 +46,11 @@ int main(int argc, char* argv[]) {
options.is_apple_mobile = (bool)argv[3]; options.is_apple_mobile = (bool)argv[3];
language = ShaderLanguage::MSL; language = ShaderLanguage::MSL;
destination_path.replace_extension(".msl");
#else #else
language = ShaderLanguage::SPIRV; language = ShaderLanguage::SPIRV;
destination_path.replace_extension(".spv");
#endif #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()) { if(!compiled_source.has_value()) {
prism::log::error(System::Core, "Error when compiling {}!", source_path); prism::log::error(System::Core, "Error when compiling {}!", source_path);
return -1; return -1;
@ -82,9 +74,10 @@ int main(int argc, char* argv[]) {
default: default:
break; 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;
} }