diff --git a/engine/asset/src/asset.cpp b/engine/asset/src/asset.cpp index 0f18486..3924e9d 100644 --- a/engine/asset/src/asset.cpp +++ b/engine/asset/src/asset.cpp @@ -18,7 +18,7 @@ std::unique_ptr load_mesh(const file::Path path) { Expects(!path.empty()); - auto file = file::open(path); + auto file = file::open(path, true); if(!file.has_value()) { console::error(System::Renderer, "Failed to load mesh from {}!", path); return nullptr; @@ -193,7 +193,7 @@ std::unique_ptr load_mesh(const file::Path path) { std::unique_ptr load_texture(const file::Path path) { Expects(!path.empty()); - auto file = file::open(path); + auto file = file::open(path, true); if(!file.has_value()) { console::error(System::Renderer, "Failed to load texture from {}!", path); return nullptr; diff --git a/engine/core/src/file.cpp b/engine/core/src/file.cpp index 72e05c7..8bfb351 100755 --- a/engine/core/src/file.cpp +++ b/engine/core/src/file.cpp @@ -18,9 +18,10 @@ file::Path file::root_path(const Path path) { std::optional file::open(const file::Path path, const bool binary_mode) { Expects(!path.empty()); - FILE* file = fopen(get_file_path(path).string().c_str(), binary_mode ? "rb" : "r"); + auto str = get_file_path(path).string(); + FILE* file = fopen(str.c_str(), binary_mode ? "rb" : "r"); if(file == nullptr) { - console::error(System::File, "Failed to open file handle from {}!", path); + console::error(System::File, "Failed to open file handle from {}!", str); return {}; } @@ -29,9 +30,10 @@ std::optional file::open(const file::Path path, const bool binary_mo file::Path file::get_file_path(const file::Path path) { auto fixed_path = path; - if(root_path(path) == app_domain) { + auto root = root_path(path); + if(root == app_domain) { fixed_path = domain_data[static_cast(Domain::App)] / path.lexically_relative(root_path(path)); - } else if(root_path(path) == internal_domain) { + } else if(root == internal_domain) { fixed_path = domain_data[static_cast(Domain::Internal)] / path.lexically_relative(root_path(path)); } diff --git a/engine/gfx/public/gfx.hpp b/engine/gfx/public/gfx.hpp index 346847e..54e1be9 100755 --- a/engine/gfx/public/gfx.hpp +++ b/engine/gfx/public/gfx.hpp @@ -118,6 +118,7 @@ struct GFXPushConstant { enum class GFXBindingType { StorageBuffer, + StorageImage, PushConstant, Texture }; diff --git a/engine/gfx/vulkan/src/gfx_vulkan.cpp b/engine/gfx/vulkan/src/gfx_vulkan.cpp index b0197bf..e97c9ef 100755 --- a/engine/gfx/vulkan/src/gfx_vulkan.cpp +++ b/engine/gfx/vulkan/src/gfx_vulkan.cpp @@ -37,7 +37,7 @@ VkFormat toVkFormat(GFXPixelFormat format) { return VK_FORMAT_R8G8_UNORM; case GFXPixelFormat::R8G8_SFLOAT: - return VK_FORMAT_R8G8_SSCALED; + return VK_FORMAT_R16G16_SFLOAT; case GFXPixelFormat::R8G8B8A8_UNORM: return VK_FORMAT_R8G8B8A8_UNORM; @@ -93,7 +93,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback( const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData) { - console::debug(System::GFX, pCallbackData->pMessage); + console::debug(System::GFX, pCallbackData->pMessage); return VK_FALSE; } @@ -715,6 +715,9 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate case GFXBindingType::Texture: descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; break; + case GFXBindingType::StorageImage: + descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + break; } VkDescriptorSetLayoutBinding layoutBinding = {}; @@ -1115,6 +1118,7 @@ void GFXVulkan::createLogicalDevice(std::vector extensions) { enabledFeatures.fragmentStoresAndAtomics = true; enabledFeatures.samplerAnisotropy = true; enabledFeatures.fillModeNonSolid = true; + enabledFeatures.imageCubeArray = true; createInfo.pEnabledFeatures = &enabledFeatures; diff --git a/engine/renderer/src/dofpass.cpp b/engine/renderer/src/dofpass.cpp index 93d6e08..70c2d88 100755 --- a/engine/renderer/src/dofpass.cpp +++ b/engine/renderer/src/dofpass.cpp @@ -32,8 +32,15 @@ DoFPass::DoFPass(GFX* gfx, Renderer* renderer) : renderer(renderer) { create_info.shaders.fragment_path = "dof.frag"; create_info.shader_input.bindings = { + {0, GFXBindingType::StorageImage}, + {1, GFXBindingType::Texture}, + {3, GFXBindingType::Texture}, {2, GFXBindingType::PushConstant} }; + + create_info.shader_input.push_constants = { + {sizeof(Vector4), 0} + }; create_info.render_pass = renderpass; @@ -86,7 +93,7 @@ void DoFPass::render(GFXCommandBuffer* command_buffer, Scene&) { command_buffer->bind_texture(renderer->offscreenColorTexture, 0); command_buffer->bind_texture(renderer->offscreenDepthTexture, 1); - command_buffer->bind_texture(aperture_texture->handle, 2); + command_buffer->bind_texture(aperture_texture->handle, 3); const auto extent = renderer->get_render_extent(); diff --git a/engine/renderer/src/materialcompiler.cpp b/engine/renderer/src/materialcompiler.cpp index 7e8e0c5..f9ace23 100755 --- a/engine/renderer/src/materialcompiler.cpp +++ b/engine/renderer/src/materialcompiler.cpp @@ -78,6 +78,8 @@ GFXPipeline* MaterialCompiler::create_skinned_pipeline(GFXGraphicsPipelineCreate createInfo.shaders.vertex_src = get_shader(vertex_path, true, false); createInfo.shaders.vertex_path = ""; + + createInfo.shader_input.bindings.push_back({ 14, GFXBindingType::StorageBuffer }); if(positions_only) { createInfo.vertex_input.inputs = { @@ -183,7 +185,6 @@ layout (binding = 5) uniform samplerShadow pcf_sampler;\n \ layout (binding = 6) uniform texture2DArray spot_shadow;\n \ layout(push_constant, binding = 0) uniform PushConstant {\n \ mat4 model;\n \ - int materialOffset;\n \ };\n"; ShaderSource MaterialCompiler::compile_material_fragment(Material& material, bool use_ibl) { diff --git a/engine/renderer/src/renderer.cpp b/engine/renderer/src/renderer.cpp index d4186c3..fac6270 100755 --- a/engine/renderer/src/renderer.cpp +++ b/engine/renderer/src/renderer.cpp @@ -338,16 +338,16 @@ void Renderer::render(Scene* scene, int index) { commandbuffer->bind_texture(smaaPass->blend_texture, 3); if(auto texture = get_requested_texture(PassTextureType::SelectionSobel)) - commandbuffer->bind_texture(texture, 4); + commandbuffer->bind_texture(texture, 5); else - commandbuffer->bind_texture(dummyTexture, 4); + commandbuffer->bind_texture(dummyTexture, 5); - commandbuffer->bind_texture(average_luminance_texture, 5); + commandbuffer->bind_texture(average_luminance_texture, 6); if(render_options.enable_depth_of_field) - commandbuffer->bind_texture(dofPass->far_field, 6); + commandbuffer->bind_texture(dofPass->far_field, 7); else - commandbuffer->bind_texture(dummyTexture, 6); + commandbuffer->bind_texture(dummyTexture, 7); PostPushConstants pc; pc.options.x = render_options.enable_aa; @@ -464,7 +464,6 @@ void Renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Obj struct PushConstant { Matrix4x4 m; - int s; } pc; pc.m = scene.get(obj).model; @@ -508,7 +507,7 @@ void Renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Obj if(!mesh.mesh->bones.empty()) command_buffer->bind_shader_buffer(part.bone_batrix_buffer, 0, 14, sizeof(Matrix4x4) * 128); - pc.s = material_indices[mesh.materials[material_index].handle]; + command_buffer->set_push_constant(&pc, sizeof(PushConstant)); for(const auto& [index, texture] : mesh.materials[material_index]->bound_textures) { @@ -721,13 +720,8 @@ void Renderer::create_mesh_pipeline(Material& material) { 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}; - struct PushConstant { - Matrix4x4 m; - int s; - }; - pipelineInfo.shader_input.push_constants = { - {sizeof(PushConstant), 0} + {sizeof(Matrix4x4), 0} }; pipelineInfo.shader_input.bindings = { @@ -738,7 +732,9 @@ void Renderer::create_mesh_pipeline(Material& material) { {4, GFXBindingType::Texture}, {5, GFXBindingType::Texture}, {6, GFXBindingType::Texture}, - {7, GFXBindingType::Texture} + {7, GFXBindingType::Texture}, + {8, GFXBindingType::Texture}, + {9, GFXBindingType::Texture} }; pipelineInfo.render_pass = offscreenRenderPass; @@ -749,6 +745,14 @@ void Renderer::create_mesh_pipeline(Material& material) { pipelineInfo.shaders.fragment_src = material_compiler.compile_material_fragment(material); pipelineInfo.shaders.fragment_path = ""; + + for (auto [index, texture] : material.bound_textures) { + GFXShaderBinding binding; + binding.binding = index; + binding.type = GFXBindingType::Texture; + + pipelineInfo.shader_input.bindings.push_back(binding); + } auto [static_pipeline, skinned_pipeline] = material_compiler.create_pipeline_permutations(pipelineInfo); @@ -759,6 +763,8 @@ void Renderer::create_mesh_pipeline(Material& material) { pipelineInfo.shaders.fragment_src = material_compiler.compile_material_fragment(material, false); // scene capture does not use IBL + pipelineInfo.shader_input.push_constants[0].size += sizeof(Matrix4x4); + material.capture_pipeline = material_compiler.create_static_pipeline(pipelineInfo, false, true); } @@ -851,7 +857,10 @@ void Renderer::createPostPipeline() { {4, GFXBindingType::PushConstant}, {1, GFXBindingType::Texture}, {2, GFXBindingType::Texture}, - {3, GFXBindingType::Texture} + {3, GFXBindingType::Texture}, + {5, GFXBindingType::Texture}, + {6, GFXBindingType::Texture}, + {7, GFXBindingType::Texture} }; pipelineInfo.shader_input.push_constants = { diff --git a/engine/renderer/src/scenecapture.cpp b/engine/renderer/src/scenecapture.cpp index 3a50f20..2f26196 100755 --- a/engine/renderer/src/scenecapture.cpp +++ b/engine/renderer/src/scenecapture.cpp @@ -13,7 +13,6 @@ struct PushConstant { Matrix4x4 m, v; - int s; }; struct SceneMaterial { @@ -417,18 +416,18 @@ void SceneCapture::createIrradianceResources() { irradianceOffscreenTexture = gfx->create_texture(textureInfo); - GFXFramebufferCreateInfo info; - info.attachments = {irradianceOffscreenTexture}; - info.render_pass = renderPass; - - irradianceFramebuffer = gfx->create_framebuffer(info); - GFXRenderPassCreateInfo renderPassInfo = {}; renderPassInfo.label = "Irradiance"; renderPassInfo.attachments.push_back(GFXPixelFormat::R8G8B8A8_UNORM); - + irradianceRenderPass = gfx->create_render_pass(renderPassInfo); + + GFXFramebufferCreateInfo info; + info.attachments = {irradianceOffscreenTexture}; + info.render_pass = irradianceRenderPass; + irradianceFramebuffer = gfx->create_framebuffer(info); + GFXGraphicsPipelineCreateInfo pipelineInfo = {}; pipelineInfo.label = "Irradiance Convolution"; pipelineInfo.shaders.vertex_path = "irradiance.vert"; diff --git a/engine/renderer/src/shadowpass.cpp b/engine/renderer/src/shadowpass.cpp index 16c088d..ca82d5f 100755 --- a/engine/renderer/src/shadowpass.cpp +++ b/engine/renderer/src/shadowpass.cpp @@ -167,7 +167,7 @@ void ShadowPass::render_meshes(GFXCommandBuffer* command_buffer, Scene& scene, c if(render_options.enable_frustum_culling && !test_aabb_frustum(frustum, get_aabb_for_part(scene.get(obj), part))) continue; - command_buffer->bind_shader_buffer(part.bone_batrix_buffer, 0, 1, sizeof(Matrix4x4) * 128); + command_buffer->bind_shader_buffer(part.bone_batrix_buffer, 0, 14, sizeof(Matrix4x4) * 128); command_buffer->draw_indexed(part.index_count, part.index_offset, part.vertex_offset, base_instance); } } @@ -391,7 +391,7 @@ void ShadowPass::create_offscreen_resources() { GFXFramebufferCreateInfo info; info.attachments = {offscreen_color_texture, offscreen_depth}; - info.render_pass = render_pass; + info.render_pass = cube_render_pass; offscreen_framebuffer = gfx->create_framebuffer(info); diff --git a/platforms/windows/file.cpp b/platforms/windows/file.cpp index fb574ea..da7d475 100755 --- a/platforms/windows/file.cpp +++ b/platforms/windows/file.cpp @@ -3,7 +3,7 @@ #include "string_utils.hpp" void file::set_domain_path(const file::Domain domain, const file::Path path) { - domain_data[(int)domain] = replace_substring(path.string(), "{resource_dir}", "."); + domain_data[(int)domain] = replace_substring(path.string(), "{resource_dir}/", ""); } file::Path file::get_writeable_directory() { diff --git a/shaders/dof.frag.glsl b/shaders/dof.frag.glsl index cfa01f8..e147b5a 100644 --- a/shaders/dof.frag.glsl +++ b/shaders/dof.frag.glsl @@ -5,7 +5,7 @@ layout(location = 2) in float depth; layout(location = 0) out vec4 outColor; layout(rgba32f, binding = 0) uniform image2D color_sampler; -layout(binding = 2) uniform sampler2D aperture_sampler; +layout(binding = 3) uniform sampler2D aperture_sampler; layout(push_constant, binding = 2) uniform readonly PushConstant{ vec4 params; diff --git a/shaders/mesh.vert.nocompile.glsl b/shaders/mesh.vert.nocompile.glsl index d4e22fa..76aa7fc 100755 --- a/shaders/mesh.vert.nocompile.glsl +++ b/shaders/mesh.vert.nocompile.glsl @@ -17,7 +17,6 @@ layout (location = 6) in vec4 inBoneWeight; 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 mat3 outTBN; layout (location = 14) out vec4 fragPostSpotLightSpace[max_spot_lights]; @@ -50,12 +49,10 @@ layout(std430, binding = 1) buffer readonly SceneInformation { #ifdef CUBEMAP layout(push_constant, binding = 0) uniform readonly PushConstant{ mat4 model, view; - int materialOffset; }; #else layout(push_constant, binding = 0) uniform readonly PushConstant{ mat4 model; - int materialOffset; }; #endif @@ -93,7 +90,6 @@ void main() { outFragPos = vec3(model * vec4(inPosition, 1.0)); outNormal = bNor.xyz; outUV = inUV; - outMaterialId = materialOffset; fragPosLightSpace = (biasMat * scene.lightSpace) * bPos; for(int i = 0; i < max_spot_lights; i++) { @@ -105,7 +101,6 @@ void main() { 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++) { @@ -117,7 +112,6 @@ void main() { 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++) { diff --git a/shaders/post.frag.glsl b/shaders/post.frag.glsl index e025bc8..1d5026d 100755 --- a/shaders/post.frag.glsl +++ b/shaders/post.frag.glsl @@ -22,9 +22,9 @@ 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 = 4) uniform sampler2D sobelSampler; -layout (binding = 5) uniform sampler2D averageLuminanceSampler; -layout (binding = 6) uniform sampler2D farFieldSampler; +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; diff --git a/shaders/shadow.vert.nocompile.glsl b/shaders/shadow.vert.nocompile.glsl index bc29e3d..164e28f 100755 --- a/shaders/shadow.vert.nocompile.glsl +++ b/shaders/shadow.vert.nocompile.glsl @@ -15,7 +15,7 @@ layout(push_constant, binding = 0) uniform PushConstant { }; #ifdef BONE -layout(std430, binding = 1) buffer readonly BoneInformation { +layout(std430, binding = 14) buffer readonly BoneInformation { mat4 bones[128]; }; #endif