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:
parent
7b23fdfa09
commit
87f15b2007
60 changed files with 281 additions and 3428 deletions
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
|
|
@ -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},
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
}};
|
}};
|
||||||
|
|
|
@ -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 {};
|
||||||
}
|
}
|
||||||
|
|
4
extern/CMakeLists.txt
vendored
4
extern/CMakeLists.txt
vendored
|
@ -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
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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)); }
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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]);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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]);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
layout (location = 0) in vec3 inPos;
|
|
||||||
layout (location = 1) flat in int index;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
1407
shaders/smaa.glsl
1407
shaders/smaa.glsl
File diff suppressed because it is too large
Load diff
|
@ -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"
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -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},
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue