diff --git a/projects/bloom/CMakeLists.txt b/projects/bloom/CMakeLists.txt index bcd8827f98b479d7444eaa9f0628e8de569f7a8d..cdb30af05794ed4a1ef838b8d7c8071e1d943aba 100644 --- a/projects/bloom/CMakeLists.txt +++ b/projects/bloom/CMakeLists.txt @@ -22,7 +22,7 @@ if(MSVC) endif() # including headers of dependencies and the VkCV framework -target_include_directories(bloom SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_asset_loader_include} ${vkcv_camera_include}) +target_include_directories(bloom SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_asset_loader_include} ${vkcv_camera_include} ${vkcv_shader_compiler_include}) # linking with libraries from all dependencies and the VkCV framework -target_link_libraries(bloom vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera) +target_link_libraries(bloom vkcv ${vkcv_libraries} vkcv_asset_loader ${vkcv_asset_loader_libraries} vkcv_camera vkcv_shader_compiler) diff --git a/projects/bloom/resources/Sponza/Sponza.bin b/projects/bloom/resources/Sponza/Sponza.bin new file mode 100644 index 0000000000000000000000000000000000000000..cfedd26ca5a67b6d0a47d44d13a75e14a141717a --- /dev/null +++ b/projects/bloom/resources/Sponza/Sponza.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b809f7a17687dc99e6f41ca1ea32c06eded8779bf34d16f1f565d750b0ffd68 +size 6347696 diff --git a/projects/bloom/resources/Sponza/Sponza.gltf b/projects/bloom/resources/Sponza/Sponza.gltf new file mode 100644 index 0000000000000000000000000000000000000000..172ea07e21c94465211c860cd805355704cef230 --- /dev/null +++ b/projects/bloom/resources/Sponza/Sponza.gltf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5cc0ecad5c4694088ff820e663619c370421afc1323ac487406e8e9b4735d787 +size 713962 diff --git a/projects/bloom/resources/Sponza/background.png b/projects/bloom/resources/Sponza/background.png new file mode 100644 index 0000000000000000000000000000000000000000..b64def129da38f4e23d89e21b4af1039008a4327 --- /dev/null +++ b/projects/bloom/resources/Sponza/background.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5b5f900ff8ed83a31750ec8e428b5b91273794ddcbfc4e4b8a6a7e781f8c686 +size 1417666 diff --git a/projects/bloom/resources/Sponza/chain_texture.png b/projects/bloom/resources/Sponza/chain_texture.png new file mode 100644 index 0000000000000000000000000000000000000000..c1e1768cff78e0614ad707eca8602a4c4edab5e5 --- /dev/null +++ b/projects/bloom/resources/Sponza/chain_texture.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8362cfd472880daeaea37439326a4651d1338680ae69bb2513fc6b17c8de7d4 +size 490895 diff --git a/projects/bloom/resources/Sponza/lion.png b/projects/bloom/resources/Sponza/lion.png new file mode 100644 index 0000000000000000000000000000000000000000..c49c7f0ed31e762e19284d0d3624fbc47664e56b --- /dev/null +++ b/projects/bloom/resources/Sponza/lion.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9f882f746c3a9cd51a9c6eedc1189b97668721d91a3fe49232036e789912c652 +size 2088728 diff --git a/projects/bloom/resources/Sponza/spnza_bricks_a_diff.png b/projects/bloom/resources/Sponza/spnza_bricks_a_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..cde4c7a6511e9a5f03c63ad996437fcdba3ce2df --- /dev/null +++ b/projects/bloom/resources/Sponza/spnza_bricks_a_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b94219c2f5f943f3f4715c74e7d1038bf0ab3b3b3216a758eaee67f875df0851 +size 1928829 diff --git a/projects/bloom/resources/Sponza/sponza_arch_diff.png b/projects/bloom/resources/Sponza/sponza_arch_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..bcd9bda2918d226039f9e2d03902d377b706fab6 --- /dev/null +++ b/projects/bloom/resources/Sponza/sponza_arch_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0df2c8a01b2843b1c792b494f7173cdbc4f834840fc2177af3e5d690fceda57 +size 1596151 diff --git a/projects/bloom/resources/Sponza/sponza_ceiling_a_diff.png b/projects/bloom/resources/Sponza/sponza_ceiling_a_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..59de631ffac4414cabf69b2dc794c46fc187d6cb --- /dev/null +++ b/projects/bloom/resources/Sponza/sponza_ceiling_a_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab6c187a81aa68f4eba30119e17fce2e4882a9ec320f70c90482dbe9da82b1c6 +size 1872074 diff --git a/projects/bloom/resources/Sponza/sponza_column_a_diff.png b/projects/bloom/resources/Sponza/sponza_column_a_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..01a82432d3f9939bbefe850bdb900f1ff9a3f6db --- /dev/null +++ b/projects/bloom/resources/Sponza/sponza_column_a_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c291507e2808bb83e160ab4b020689817df273baad3713a9ad19ac15fac6826 +size 1840992 diff --git a/projects/bloom/resources/Sponza/sponza_column_b_diff.png b/projects/bloom/resources/Sponza/sponza_column_b_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..10a660cce2a5a9b8997772c746058ce23e7d45d7 --- /dev/null +++ b/projects/bloom/resources/Sponza/sponza_column_b_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2820b0267c4289c6cedbb42721792a57ef244ec2d0935941011c2a7d3fe88a9b +size 2170433 diff --git a/projects/bloom/resources/Sponza/sponza_column_c_diff.png b/projects/bloom/resources/Sponza/sponza_column_c_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..bc46fd979044a938d3adca7601689e71504e48bf --- /dev/null +++ b/projects/bloom/resources/Sponza/sponza_column_c_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0bc993ff59865468ef4530798930c7dfefb07482d71db45bc2a520986b27735 +size 2066950 diff --git a/projects/bloom/resources/Sponza/sponza_curtain_blue_diff.png b/projects/bloom/resources/Sponza/sponza_curtain_blue_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..384c8c2c051160d530eb3ac8b05c9c60752a2d2b --- /dev/null +++ b/projects/bloom/resources/Sponza/sponza_curtain_blue_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b85c6bb3cd5105f48d3812ec8e7a1068521ce69e917300d79e136e19d45422fb +size 9510905 diff --git a/projects/bloom/resources/Sponza/sponza_curtain_diff.png b/projects/bloom/resources/Sponza/sponza_curtain_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..af842e9f5fe18c1f609875e00899a6770fa4488b --- /dev/null +++ b/projects/bloom/resources/Sponza/sponza_curtain_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:563c56bdbbee395a6ef7f0c51c8ac9223c162e517b4cdba0d4654e8de27c98d8 +size 9189263 diff --git a/projects/bloom/resources/Sponza/sponza_curtain_green_diff.png b/projects/bloom/resources/Sponza/sponza_curtain_green_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..6c9b6391a199407637fa71033d79fb58b8b4f0d7 --- /dev/null +++ b/projects/bloom/resources/Sponza/sponza_curtain_green_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:238fe1c7f481388d1c1d578c2da8d411b99e8f0030ab62060a306db333124476 +size 8785458 diff --git a/projects/bloom/resources/Sponza/sponza_details_diff.png b/projects/bloom/resources/Sponza/sponza_details_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..12656686362c3e0a297e060491f33bd7351551f9 --- /dev/null +++ b/projects/bloom/resources/Sponza/sponza_details_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb1223b3bb82f8757e7df25a6891f1239cdd7ec59990340e952fb2d6b7ea570c +size 1522643 diff --git a/projects/bloom/resources/Sponza/sponza_fabric_blue_diff.png b/projects/bloom/resources/Sponza/sponza_fabric_blue_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..879d16ef84722a4fc13e83a771778de326e4bc54 --- /dev/null +++ b/projects/bloom/resources/Sponza/sponza_fabric_blue_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:467d290bf5d4b2a017da140ba9e244ed8a8a9be5418a9ac9bcb4ad572ae2d7ab +size 2229440 diff --git a/projects/bloom/resources/Sponza/sponza_fabric_diff.png b/projects/bloom/resources/Sponza/sponza_fabric_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..3311287a219d2148620b87fe428fea071688d051 --- /dev/null +++ b/projects/bloom/resources/Sponza/sponza_fabric_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1594f59cc2848db26add47361f4e665e3d8afa147760ed915d839fea42b20287 +size 2267382 diff --git a/projects/bloom/resources/Sponza/sponza_fabric_green_diff.png b/projects/bloom/resources/Sponza/sponza_fabric_green_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..de110f369004388dae4cd5067c63428db3a07834 --- /dev/null +++ b/projects/bloom/resources/Sponza/sponza_fabric_green_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:902b87faab221173bf370cea7c74cb9060b4d870ac6316b190dafded1cb12993 +size 2258220 diff --git a/projects/bloom/resources/Sponza/sponza_flagpole_diff.png b/projects/bloom/resources/Sponza/sponza_flagpole_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..5f6e0812a0df80346318baa3cb50a6888afc58f8 --- /dev/null +++ b/projects/bloom/resources/Sponza/sponza_flagpole_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfffb62e770959c725d0f3db6dc7dbdd46a380ec55ef884dab94d44ca017b438 +size 1425673 diff --git a/projects/bloom/resources/Sponza/sponza_floor_a_diff.png b/projects/bloom/resources/Sponza/sponza_floor_a_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..788ed764f79ba724f04a2d603076a5b85013e188 --- /dev/null +++ b/projects/bloom/resources/Sponza/sponza_floor_a_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a16f9230fa91f9f31dfca6216ce205f1ef132d44f3b012fbf6efc0fba69770ab +size 1996838 diff --git a/projects/bloom/resources/Sponza/sponza_roof_diff.png b/projects/bloom/resources/Sponza/sponza_roof_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..c5b84261fdd1cc776a94b3ce398c7806b895f9a3 --- /dev/null +++ b/projects/bloom/resources/Sponza/sponza_roof_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7fc412138c20da19f8173e53545e771f4652558dff624d4dc67143e40efe562b +size 2320533 diff --git a/projects/bloom/resources/Sponza/sponza_thorn_diff.png b/projects/bloom/resources/Sponza/sponza_thorn_diff.png new file mode 100644 index 0000000000000000000000000000000000000000..7a9142674a7d4a6f94a48c5152cf0300743b597a --- /dev/null +++ b/projects/bloom/resources/Sponza/sponza_thorn_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a73a17c883cd0d0d67cfda2dc4118400a916366c05b9a5ac465f0c8b30fd9c8e +size 635001 diff --git a/projects/bloom/resources/Sponza/vase_dif.png b/projects/bloom/resources/Sponza/vase_dif.png new file mode 100644 index 0000000000000000000000000000000000000000..61236a81cb324af8797b05099cd264cefe189e56 --- /dev/null +++ b/projects/bloom/resources/Sponza/vase_dif.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53d06f52bf9e59df4cf00237707cca76c4f692bda61a62b06a30d321311d6dd9 +size 1842101 diff --git a/projects/bloom/resources/Sponza/vase_hanging.png b/projects/bloom/resources/Sponza/vase_hanging.png new file mode 100644 index 0000000000000000000000000000000000000000..36a3cee71d8213225090c74f8c0dce33b9d44378 --- /dev/null +++ b/projects/bloom/resources/Sponza/vase_hanging.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a9d10b4f27a3c9a78d5bac882fdd4b6a6987c262f48fa490670fe5e235951e31 +size 1432804 diff --git a/projects/bloom/resources/Sponza/vase_plant.png b/projects/bloom/resources/Sponza/vase_plant.png new file mode 100644 index 0000000000000000000000000000000000000000..7ad95e702e229f1ebd803e5203a266d15f2c07b9 --- /dev/null +++ b/projects/bloom/resources/Sponza/vase_plant.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2087371ff02212fb7014b6daefa191cf5676d2227193fff261a5d02f554cb8e +size 998089 diff --git a/projects/bloom/resources/Sponza/vase_round.png b/projects/bloom/resources/Sponza/vase_round.png new file mode 100644 index 0000000000000000000000000000000000000000..c17953abc000c44b8991e23c136c2b67348f3d1b --- /dev/null +++ b/projects/bloom/resources/Sponza/vase_round.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa23d48d492d5d4ada2ddb27d1ef22952b214e6eb3b301c65f9d88442723d20a +size 1871399 diff --git a/projects/bloom/resources/cube/boards2_vcyc_jpg.jpg b/projects/bloom/resources/cube/boards2_vcyc_jpg.jpg deleted file mode 100644 index 2636039e272289c0fba3fa2d88a060b857501248..0000000000000000000000000000000000000000 --- a/projects/bloom/resources/cube/boards2_vcyc_jpg.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cca33a6e58ddd1b37a6e6853a9aa0e7b15ca678937119194752393dd2a0a0564 -size 1192476 diff --git a/projects/bloom/resources/cube/cube.bin b/projects/bloom/resources/cube/cube.bin deleted file mode 100644 index 3303cd8635848bee18e10ab8754d5e4e7218db92..0000000000000000000000000000000000000000 --- a/projects/bloom/resources/cube/cube.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9bb9b6b8bbe50a0aaa517057f245ee844f80afa7426dacb2aed4128f71629ce4 -size 840 diff --git a/projects/bloom/resources/cube/cube.blend b/projects/bloom/resources/cube/cube.blend deleted file mode 100644 index 62ccb2c742094bcfb5ed194ab905bffae86bfd65..0000000000000000000000000000000000000000 --- a/projects/bloom/resources/cube/cube.blend +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a6c1e245f259c610528c9485db6688928faac0ab2addee9e3c2dde7740e4dd09 -size 774920 diff --git a/projects/bloom/resources/cube/cube.blend1 b/projects/bloom/resources/cube/cube.blend1 deleted file mode 100644 index 13f21dcca218d7bc7a07a8a9682b5e1d9e607736..0000000000000000000000000000000000000000 --- a/projects/bloom/resources/cube/cube.blend1 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f4496f423569b8ca81f3b3a55fad00f925557e0193fb9dbe6cdce7e71fb48f7b -size 774920 diff --git a/projects/bloom/resources/cube/cube.glb b/projects/bloom/resources/cube/cube.glb deleted file mode 100644 index 66a42c65e71dcf375e04cc378256024dd3c7834d..0000000000000000000000000000000000000000 --- a/projects/bloom/resources/cube/cube.glb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:198568b715f397d78f7c358c0f709a419e7fd677e54cdec7c19f71b5ed264897 -size 1194508 diff --git a/projects/bloom/resources/cube/cube.gltf b/projects/bloom/resources/cube/cube.gltf deleted file mode 100644 index 428176144843dd06c78fe1d11a6392a0ea02b22d..0000000000000000000000000000000000000000 --- a/projects/bloom/resources/cube/cube.gltf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f82f455647a84ca6242882ae26a79a499d3ce594f8de317ab89488c5b79721ac -size 2823 diff --git a/projects/bloom/resources/shaders/blur.comp b/projects/bloom/resources/shaders/blur.comp index d7fcfb3c21f2f545c90f65d3a22e66362ab6dab9..9fd2ccbf933abd34457a4685149dfae7c2f611a4 100644 --- a/projects/bloom/resources/shaders/blur.comp +++ b/projects/bloom/resources/shaders/blur.comp @@ -1,17 +1,37 @@ -# version 450 -layout(local_size_x = 8, local_size_y = 8) in; +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(set=0, binding=0) uniform texture2D inImage; +layout(set=0, binding=1) uniform sampler inImageSampler; +layout(set=0, binding=2, r11f_g11f_b10f) uniform writeonly image2D outImage; + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -layout(set=0, binding=0) uniform texture2D offscreenAttachment; -layout(set=0, binding=1) uniform sampler offscreenSampler; -layout(r11f_g11f_b10f, set=0, binding=2) uniform writeonly image2D blurAttachment; void main() { - ivec2 pixel_coords = ivec2(gl_GlobalInvocationID.xy); - vec2 uv = vec2(pixel_coords) / imageSize(blurAttachment); + if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(outImage)))){ + return; + } + + const int kernel_size = 10; + const float kernel_weight = (2 * kernel_size + 1) * (2 * kernel_size + 1); + + ivec2 pixel_coord = ivec2(gl_GlobalInvocationID.xy); + vec2 pixel_size = vec2(1.0f) / textureSize(sampler2D(inImage, inImageSampler), 0); + vec2 UV = pixel_coord.xy * pixel_size; - // TODO: BLUR + vec4 sampled_color = vec4(0.0f); + for(int i = -kernel_size; i <= kernel_size; i++) + { + for(int j = -kernel_size; j <= kernel_size; j++) + { + vec2 sample_coord = UV + vec2(j, i) * pixel_size + 0.5f * pixel_size * sign(vec2(j, i)); + sampled_color.rgb += texture(sampler2D(inImage, inImageSampler), sample_coord).rgb; + } + } + sampled_color /= kernel_weight; - imageStore(blurAttachment, pixel_coords, vec4(1.0, 0.0 ,0.0, 0.0)); + imageStore(outImage, pixel_coord, sampled_color); } \ No newline at end of file diff --git a/projects/bloom/resources/shaders/blur_comp.spv b/projects/bloom/resources/shaders/blur_comp.spv deleted file mode 100644 index 565eab96c0b2c554556077dee67d21ed92f42764..0000000000000000000000000000000000000000 Binary files a/projects/bloom/resources/shaders/blur_comp.spv and /dev/null differ diff --git a/projects/bloom/resources/shaders/comp.spv b/projects/bloom/resources/shaders/comp.spv new file mode 100644 index 0000000000000000000000000000000000000000..e0112a50deceb3b818434636e194d4a2f169184b Binary files /dev/null and b/projects/bloom/resources/shaders/comp.spv differ diff --git a/projects/bloom/resources/shaders/compile.bat b/projects/bloom/resources/shaders/compile.bat deleted file mode 100644 index 5fecf915079df6cf230254ef2c1755c953d826b1..0000000000000000000000000000000000000000 --- a/projects/bloom/resources/shaders/compile.bat +++ /dev/null @@ -1,11 +0,0 @@ -%VULKAN_SDK%\Bin32\glslc.exe shader.vert -o vert.spv -%VULKAN_SDK%\Bin32\glslc.exe shader.frag -o frag.spv - -%VULKAN_SDK%\Bin32\glslc.exe shadow.vert -o shadow_vert.spv -%VULKAN_SDK%\Bin32\glslc.exe shadow.frag -o shadow_frag.spv - -%VULKAN_SDK%\Bin32\glslc.exe quad.vert -o quad_vert.spv -%VULKAN_SDK%\Bin32\glslc.exe quad.frag -o quad_frag.spv - -%VULKAN_SDK%\Bin32\glslc.exe blur.comp -o blur_comp.spv -pause \ No newline at end of file diff --git a/projects/bloom/resources/shaders/compositeBloom.comp b/projects/bloom/resources/shaders/compositeBloom.comp new file mode 100644 index 0000000000000000000000000000000000000000..d01e758254de37d315d678fe32292260da7579db --- /dev/null +++ b/projects/bloom/resources/shaders/compositeBloom.comp @@ -0,0 +1,29 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(set=0, binding=0) uniform texture2D blurImage; +layout(set=0, binding=1) uniform sampler linearSampler; +layout(set=0, binding=2, r11f_g11f_b10f) uniform image2D colorBuffer; + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; + + +void main() +{ + if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(colorBuffer)))){ + return; + } + + ivec2 pixel_coord = ivec2(gl_GlobalInvocationID.xy); + vec2 pixel_size = vec2(1.0f) / textureSize(sampler2D(blurImage, linearSampler), 0); + vec2 UV = pixel_coord.xy * pixel_size; + + vec4 composite_color = vec4(0.0f); + + vec3 blur_color = texture(sampler2D(blurImage, linearSampler), UV).rgb; + vec3 main_color = imageLoad(colorBuffer, pixel_coord).rgb; + + composite_color.rgb = mix(main_color, blur_color, 0.1f); + + imageStore(colorBuffer, pixel_coord, composite_color); +} \ No newline at end of file diff --git a/projects/bloom/resources/shaders/frag.spv b/projects/bloom/resources/shaders/frag.spv deleted file mode 100644 index ba47f91cdfcd1ecd824614f23d424b0a510ac1c7..0000000000000000000000000000000000000000 Binary files a/projects/bloom/resources/shaders/frag.spv and /dev/null differ diff --git a/projects/bloom/resources/shaders/gammaCorrection.comp b/projects/bloom/resources/shaders/gammaCorrection.comp new file mode 100644 index 0000000000000000000000000000000000000000..f89ad167c846cca8e80f69d33eda83bd6ed00d46 --- /dev/null +++ b/projects/bloom/resources/shaders/gammaCorrection.comp @@ -0,0 +1,20 @@ +#version 440 + +layout(set=0, binding=0, r11f_g11f_b10f) uniform image2D inImage; +layout(set=0, binding=1, rgba8) uniform image2D outImage; + + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; + +void main(){ + + if(any(greaterThanEqual(gl_GlobalInvocationID.xy, imageSize(inImage)))){ + return; + } + ivec2 uv = ivec2(gl_GlobalInvocationID.xy); + vec3 linearColor = imageLoad(inImage, uv).rgb; + // cheap Reinhard tone mapping + linearColor = linearColor/(linearColor + 1.0f); + vec3 gammaCorrected = pow(linearColor, vec3(1.f / 2.2f)); + imageStore(outImage, uv, vec4(gammaCorrected, 0.f)); +} \ No newline at end of file diff --git a/projects/bloom/resources/shaders/perMeshResources.inc b/projects/bloom/resources/shaders/perMeshResources.inc new file mode 100644 index 0000000000000000000000000000000000000000..95e4fb7c27009965659d14a9c72acfec950c37e3 --- /dev/null +++ b/projects/bloom/resources/shaders/perMeshResources.inc @@ -0,0 +1,2 @@ +layout(set=1, binding=0) uniform texture2D albedoTexture; +layout(set=1, binding=1) uniform sampler textureSampler; \ No newline at end of file diff --git a/projects/bloom/resources/shaders/quad.frag b/projects/bloom/resources/shaders/quad.frag deleted file mode 100644 index 14bacc9508c783b9d336c1ebc720cdafd5e044b7..0000000000000000000000000000000000000000 --- a/projects/bloom/resources/shaders/quad.frag +++ /dev/null @@ -1,15 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec2 inUV; - -layout(location = 0) out vec3 outColor; - -layout(set=0, binding=0) uniform texture2D renderAttachment; -layout(set=0, binding=1) uniform texture2D blurAttachment; -layout(set=0, binding=2) uniform sampler samp; - -void main() -{ - outColor = texture(sampler2D(renderAttachment, samp), inUV).rgb; -} \ No newline at end of file diff --git a/projects/bloom/resources/shaders/quad.vert b/projects/bloom/resources/shaders/quad.vert deleted file mode 100644 index a5d520084e8afd1110f6b4535754a0988dfc7cee..0000000000000000000000000000000000000000 --- a/projects/bloom/resources/shaders/quad.vert +++ /dev/null @@ -1,12 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable - -layout(location = 0) in vec3 inPosition; - -layout(location = 0) out vec2 outUV; - -void main() -{ - outUV = inPosition.xy; - gl_Position = vec4(inPosition, 1.0); -} \ No newline at end of file diff --git a/projects/bloom/resources/shaders/quad_frag.spv b/projects/bloom/resources/shaders/quad_frag.spv deleted file mode 100644 index 86f9763845401abb1f01879b58b234ffb5904efc..0000000000000000000000000000000000000000 Binary files a/projects/bloom/resources/shaders/quad_frag.spv and /dev/null differ diff --git a/projects/bloom/resources/shaders/quad_vert.spv b/projects/bloom/resources/shaders/quad_vert.spv deleted file mode 100644 index c9c7a116497ce2098b9854b538d07fd99a77e383..0000000000000000000000000000000000000000 Binary files a/projects/bloom/resources/shaders/quad_vert.spv and /dev/null differ diff --git a/projects/bloom/resources/shaders/shader.frag b/projects/bloom/resources/shaders/shader.frag index 1c97a68808af11765fa6bf8a535218a8a2b14a77..3e95b4508f112c1ed9aa4a7050a98fa789dccd09 100644 --- a/projects/bloom/resources/shaders/shader.frag +++ b/projects/bloom/resources/shaders/shader.frag @@ -1,5 +1,8 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable +#extension GL_GOOGLE_include_directive : enable + +#include "perMeshResources.inc" layout(location = 0) in vec3 passNormal; layout(location = 1) in vec2 passUV; @@ -7,14 +10,12 @@ layout(location = 2) in vec3 passPos; layout(location = 0) out vec3 outColor; -layout(set=0, binding=0) uniform texture2D meshTexture; -layout(set=0, binding=1) uniform sampler textureSampler; -layout(set=0, binding=2) uniform sunBuffer { +layout(set=0, binding=0) uniform sunBuffer { vec3 L; float padding; mat4 lightMatrix; }; -layout(set=0, binding=3) uniform texture2D shadowMap; -layout(set=0, binding=4) uniform sampler shadowMapSampler; +layout(set=0, binding=1) uniform texture2D shadowMap; +layout(set=0, binding=2) uniform sampler shadowMapSampler; float shadowTest(vec3 worldPos){ vec4 lightPos = lightMatrix * vec4(worldPos, 1); @@ -34,13 +35,11 @@ float shadowTest(vec3 worldPos){ } void main() { - /* vec3 N = normalize(passNormal); - vec3 sunColor = vec3(1); + vec3 sunColor = vec3(10); vec3 sun = sunColor * clamp(dot(N, L), 0, 1); sun *= shadowTest(passPos); - vec3 ambient = vec3(0.1); - vec3 albedo = texture(sampler2D(meshTexture, textureSampler), passUV).rgb; - */ - outColor = passNormal; + vec3 ambient = vec3(0.05); + vec3 albedo = texture(sampler2D(albedoTexture, textureSampler), passUV).rgb; + outColor = albedo * (sun + ambient); } \ No newline at end of file diff --git a/projects/bloom/resources/shaders/shader.vert b/projects/bloom/resources/shaders/shader.vert index 0ab82c203806356d0f35dc52c0a6988b286d90d1..926f86af2860cb57c44d2d5ee78712b6ae155e5c 100644 --- a/projects/bloom/resources/shaders/shader.vert +++ b/projects/bloom/resources/shaders/shader.vert @@ -16,7 +16,7 @@ layout( push_constant ) uniform constants{ void main() { gl_Position = mvp * vec4(inPosition, 1.0); - passNormal = inNormal; + passNormal = mat3(model) * inNormal; // assuming no weird stuff like shearing or non-uniform scaling passUV = inUV; passPos = (model * vec4(inPosition, 1)).xyz; } \ No newline at end of file diff --git a/projects/bloom/resources/shaders/shadow_frag.spv b/projects/bloom/resources/shaders/shadow_frag.spv deleted file mode 100644 index 6be3bd2518a3b1f234e39aea2503ba86cfb3314b..0000000000000000000000000000000000000000 Binary files a/projects/bloom/resources/shaders/shadow_frag.spv and /dev/null differ diff --git a/projects/bloom/resources/shaders/shadow_vert.spv b/projects/bloom/resources/shaders/shadow_vert.spv deleted file mode 100644 index afaa0824ee9be2c22209d611943c6512587dce24..0000000000000000000000000000000000000000 Binary files a/projects/bloom/resources/shaders/shadow_vert.spv and /dev/null differ diff --git a/projects/bloom/resources/shaders/vert.spv b/projects/bloom/resources/shaders/vert.spv deleted file mode 100644 index 5e514eef5983927316465679af5461f507497130..0000000000000000000000000000000000000000 Binary files a/projects/bloom/resources/shaders/vert.spv and /dev/null differ diff --git a/projects/bloom/src/main.cpp b/projects/bloom/src/main.cpp index e33f603bb92fc58a5ebff6fb042a8ab6a9a7d59f..3b738a4c18295a56e7b0d1d2bc99e26d23c5aff5 100644 --- a/projects/bloom/src/main.cpp +++ b/projects/bloom/src/main.cpp @@ -4,13 +4,16 @@ #include <vkcv/camera/CameraManager.hpp> #include <chrono> #include <vkcv/asset/asset_loader.hpp> +#include <vkcv/shader/GLSLCompiler.hpp> +#include <vkcv/Logger.hpp> +#include <glm/glm.hpp> int main(int argc, const char** argv) { - const char* applicationName = "First Mesh"; - - uint32_t windowWidth = 800; - uint32_t windowHeight = 600; + const char* applicationName = "Bloom"; + uint32_t windowWidth = 1920; + uint32_t windowHeight = 1080; + vkcv::Window window = vkcv::Window::create( applicationName, windowWidth, @@ -18,9 +21,15 @@ int main(int argc, const char** argv) { true ); - vkcv::CameraManager cameraManager(window, windowWidth, windowHeight); - cameraManager.getCamera().setPosition(glm::vec3(0.f, 0.f, 3.f)); - cameraManager.getCamera().setNearFar(0.1, 30); + vkcv::camera::CameraManager cameraManager(window); + uint32_t camIndex = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); + uint32_t camIndex2 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); + + cameraManager.getCamera(camIndex).setPosition(glm::vec3(0.f, 0.f, 3.f)); + cameraManager.getCamera(camIndex).setNearFar(0.1f, 30.0f); + cameraManager.getCamera(camIndex).setYaw(180.0f); + + cameraManager.getCamera(camIndex2).setNearFar(0.1f, 30.0f); window.initEvents(); @@ -33,300 +42,303 @@ int main(int argc, const char** argv) { { "VK_KHR_swapchain" } ); + const char* path = argc > 1 ? argv[1] : "resources/Sponza/Sponza.gltf"; + vkcv::asset::Scene scene; + int result = vkcv::asset::loadScene(path, scene); - // ATTACHMENTS - const vkcv::AttachmentDescription offscreenAttachment( - vkcv::AttachmentOperation::STORE, - vkcv::AttachmentOperation::CLEAR, - vk::Format::eB10G11R11UfloatPack32 - ); - - const vkcv::AttachmentDescription shadowAttachment( - vkcv::AttachmentOperation::STORE, - vkcv::AttachmentOperation::CLEAR, - vk::Format::eD16Unorm - ); + if (result == 1) { + std::cout << "Scene loading successful!" << std::endl; + } + else { + std::cout << "Scene loading failed: " << result << std::endl; + return 1; + } - const vkcv::AttachmentDescription depthAttachment( - vkcv::AttachmentOperation::STORE, - vkcv::AttachmentOperation::CLEAR, - vk::Format::eD32Sfloat - ); + // build index and vertex buffers + assert(!scene.vertexGroups.empty()); + std::vector<std::vector<uint8_t>> vBuffers; + std::vector<std::vector<uint8_t>> iBuffers; - const vkcv::AttachmentDescription presentAttachment( - vkcv::AttachmentOperation::STORE, - vkcv::AttachmentOperation::CLEAR, - core.getSwapchainImageFormat() - ); + std::vector<vkcv::VertexBufferBinding> vBufferBindings; + std::vector<std::vector<vkcv::VertexBufferBinding>> vertexBufferBindings; + std::vector<vkcv::asset::VertexAttribute> vAttributes; - // RENDER PASSES - const vkcv::PassConfig shadowPassConfig({shadowAttachment}); - const vkcv::PassHandle shadowPassHandle = core.createPass(shadowPassConfig); + for (int i = 0; i < scene.vertexGroups.size(); i++) { - const vkcv::PassConfig meshPassDefinition({ offscreenAttachment, depthAttachment }); - const vkcv::PassHandle meshPassHandle = core.createPass(meshPassDefinition); + vBuffers.push_back(scene.vertexGroups[i].vertexBuffer.data); + iBuffers.push_back(scene.vertexGroups[i].indexBuffer.data); - const vkcv::PassConfig screenQuadPassConfig({presentAttachment}); - const vkcv::PassHandle screenQuadPassHandle = core.createPass(screenQuadPassConfig); + auto& attributes = scene.vertexGroups[i].vertexBuffer.attributes; - if (!shadowPassHandle || !meshPassHandle || !screenQuadPassHandle) - { - std::cout << "Error. Could not create render passes. Exiting." << std::endl; - return EXIT_FAILURE; - } + std::sort(attributes.begin(), attributes.end(), [](const vkcv::asset::VertexAttribute& x, const vkcv::asset::VertexAttribute& y) { + return static_cast<uint32_t>(x.type) < static_cast<uint32_t>(y.type); + }); + } + std::vector<vkcv::Buffer<uint8_t>> vertexBuffers; + for (const vkcv::asset::VertexGroup& group : scene.vertexGroups) { + vertexBuffers.push_back(core.createBuffer<uint8_t>( + vkcv::BufferType::VERTEX, + group.vertexBuffer.data.size())); + vertexBuffers.back().fill(group.vertexBuffer.data); + } - // SHADERS - vkcv::ShaderProgram shadowProgram; - shadowProgram.addShader(vkcv::ShaderStage::VERTEX, "resources/shaders/shadow_vert.spv"); - shadowProgram.addShader(vkcv::ShaderStage::FRAGMENT, "resources/shaders/shadow_frag.spv"); + std::vector<vkcv::Buffer<uint8_t>> indexBuffers; + for (const auto& dataBuffer : iBuffers) { + indexBuffers.push_back(core.createBuffer<uint8_t>( + vkcv::BufferType::INDEX, + dataBuffer.size())); + indexBuffers.back().fill(dataBuffer); + } - vkcv::ShaderProgram meshProgram{}; - meshProgram.addShader(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/vert.spv")); - meshProgram.addShader(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/frag.spv")); + int vertexBufferIndex = 0; + for (const auto& vertexGroup : scene.vertexGroups) { + for (const auto& attribute : vertexGroup.vertexBuffer.attributes) { + vAttributes.push_back(attribute); + vBufferBindings.push_back(vkcv::VertexBufferBinding(attribute.offset, vertexBuffers[vertexBufferIndex].getVulkanHandle())); + } + vertexBufferBindings.push_back(vBufferBindings); + vBufferBindings.clear(); + vertexBufferIndex++; + } - vkcv::ShaderProgram bloomComputeProgram{}; - bloomComputeProgram.addShader(vkcv::ShaderStage::COMPUTE, std::filesystem::path("resources/shaders/blur_comp.spv")); + const vk::Format colorBufferFormat = vk::Format::eB10G11R11UfloatPack32; + const vkcv::AttachmentDescription color_attachment( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::CLEAR, + colorBufferFormat + ); + + const vk::Format depthBufferFormat = vk::Format::eD32Sfloat; + const vkcv::AttachmentDescription depth_attachment( + vkcv::AttachmentOperation::STORE, + vkcv::AttachmentOperation::CLEAR, + depthBufferFormat + ); - vkcv::ShaderProgram screenQuadProgram{}; - screenQuadProgram.addShader(vkcv::ShaderStage::VERTEX, "resources/shaders/quad_vert.spv"); - screenQuadProgram.addShader(vkcv::ShaderStage::FRAGMENT, "resources/shaders/quad_frag.spv"); + vkcv::PassConfig forwardPassDefinition({ color_attachment, depth_attachment }); + vkcv::PassHandle forwardPass = core.createPass(forwardPassDefinition); + vkcv::shader::GLSLCompiler compiler; - vkcv::asset::Mesh mesh; + vkcv::ShaderProgram forwardProgram; + compiler.compile(vkcv::ShaderStage::VERTEX, std::filesystem::path("resources/shaders/shader.vert"), + [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + forwardProgram.addShader(shaderStage, path); + }); + compiler.compile(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("resources/shaders/shader.frag"), + [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + forwardProgram.addShader(shaderStage, path); + }); - const char* path = argc > 1 ? argv[1] : "resources/cube/cube.gltf"; - int result = vkcv::asset::loadMesh(path, mesh); + const std::vector<vkcv::VertexAttachment> vertexAttachments = forwardProgram.getVertexAttachments(); - if (result == 1) { - std::cout << "Mesh loading successful!" << std::endl; - } - else { - std::cout << "Mesh loading failed: " << result << std::endl; - return 1; + std::vector<vkcv::VertexBinding> vertexBindings; + for (size_t i = 0; i < vertexAttachments.size(); i++) { + vertexBindings.push_back(vkcv::VertexBinding(i, { vertexAttachments[i] })); } - assert(mesh.vertexGroups.size() > 0); + const vkcv::VertexLayout vertexLayout (vertexBindings); + + // shadow map + vkcv::SamplerHandle shadowSampler = core.createSampler( + vkcv::SamplerFilterType::NEAREST, + vkcv::SamplerFilterType::NEAREST, + vkcv::SamplerMipmapMode::NEAREST, + vkcv::SamplerAddressMode::CLAMP_TO_EDGE + ); + const vk::Format shadowMapFormat = vk::Format::eD16Unorm; + const uint32_t shadowMapResolution = 1024; + const vkcv::Image shadowMap = core.createImage(shadowMapFormat, shadowMapResolution, shadowMapResolution, 1); + + // light info buffer + struct LightInfo { + glm::vec3 direction; + float padding; + glm::mat4 lightMatrix; + }; + LightInfo lightInfo; + vkcv::Buffer lightBuffer = core.createBuffer<LightInfo>(vkcv::BufferType::UNIFORM, sizeof(glm::vec3)); + + vkcv::DescriptorSetHandle forwardShadingDescriptorSet = + core.createDescriptorSet({ forwardProgram.getReflectedDescriptors()[0] }); + + vkcv::DescriptorWrites forwardDescriptorWrites; + forwardDescriptorWrites.uniformBufferWrites = { vkcv::UniformBufferDescriptorWrite(0, lightBuffer.getHandle()) }; + forwardDescriptorWrites.sampledImageWrites = { vkcv::SampledImageDescriptorWrite(1, shadowMap.getHandle()) }; + forwardDescriptorWrites.samplerWrites = { vkcv::SamplerDescriptorWrite(2, shadowSampler) }; + core.writeDescriptorSet(forwardShadingDescriptorSet, forwardDescriptorWrites); + + vkcv::SamplerHandle colorSampler = core.createSampler( + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerMipmapMode::LINEAR, + vkcv::SamplerAddressMode::REPEAT + ); - auto& attributes = mesh.vertexGroups[0].vertexBuffer.attributes; + // prepare per mesh descriptor sets + std::vector<vkcv::DescriptorSetHandle> perMeshDescriptorSets; + std::vector<vkcv::Image> sceneImages; + for (const auto& vertexGroup : scene.vertexGroups) { + perMeshDescriptorSets.push_back(core.createDescriptorSet(forwardProgram.getReflectedDescriptors()[1])); - std::sort(attributes.begin(), attributes.end(), [](const vkcv::asset::VertexAttribute& x, const vkcv::asset::VertexAttribute& y) { - return static_cast<uint32_t>(x.type) < static_cast<uint32_t>(y.type); - }); + const auto& material = scene.materials[vertexGroup.materialIndex]; - // MESH INDEX/VERTEX BUFFER - auto meshVertexBuffer = core.createBuffer<uint8_t>( - vkcv::BufferType::VERTEX, - mesh.vertexGroups[0].vertexBuffer.data.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL - ); - meshVertexBuffer.fill(mesh.vertexGroups[0].vertexBuffer.data); + int baseColorIndex = material.baseColor; + if (baseColorIndex < 0) { + vkcv_log(vkcv::LogLevel::WARNING, "Material lacks base color"); + baseColorIndex = 0; + } - auto meshIndexBuffer = core.createBuffer<uint8_t>( - vkcv::BufferType::INDEX, - mesh.vertexGroups[0].indexBuffer.data.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL - ); - meshIndexBuffer.fill(mesh.vertexGroups[0].indexBuffer.data); - - // MESH VERTEX LAYOUT - const std::vector<vkcv::VertexBufferBinding> meshVertexBufferBindings = { - vkcv::VertexBufferBinding(attributes[0].offset, meshVertexBuffer.getVulkanHandle()), - vkcv::VertexBufferBinding(attributes[1].offset, meshVertexBuffer.getVulkanHandle()), - vkcv::VertexBufferBinding(attributes[2].offset, meshVertexBuffer.getVulkanHandle()) }; - - const std::vector<vkcv::VertexAttachment> meshVertexAttachments = meshProgram.getVertexAttachments(); - std::vector<vkcv::VertexBinding> meshBindings; - for (size_t i = 0; i < meshVertexAttachments.size(); i++) { - meshBindings.push_back(vkcv::VertexBinding(i, { meshVertexAttachments[i] })); - } - const vkcv::VertexLayout meshVertexLayout(meshBindings); - - const vkcv::Mesh loadedMesh(meshVertexBufferBindings, meshIndexBuffer.getVulkanHandle(), mesh.vertexGroups[0].numIndices); - - // QUAD INDEX/VERTEX BUFFER - const std::vector<float> quadFloats = {-1.0f, 1.0f, 0.0f, // Left Bottom - 1.0f, 1.0f, 0.0f, // Right Bottom - -1.0f, -1.0f, 0.0f, // Left Top - 1.0f, -1.0f, 0.0f}; // Right Top - - const std::vector<uint8_t> quadIndices = {0, 1, 2, - 2, 1, 3}; - - auto quadVertexBuffer = core.createBuffer<float>( - vkcv::BufferType::VERTEX, - quadFloats.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL); - quadVertexBuffer.fill(quadFloats); - - auto quadIndexBuffer = core.createBuffer<uint8_t>( - vkcv::BufferType::INDEX, - quadIndices.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL); - quadIndexBuffer.fill(quadIndices); - - // SCREEN QUAD VERTEX LAYOUT - const std::vector<vkcv::VertexBufferBinding> quadVertexBufferBindings = { - vkcv::VertexBufferBinding(0, quadVertexBuffer.getVulkanHandle()) - }; - const vkcv::VertexBinding quadBinding(0, screenQuadProgram.getVertexAttachments()); - const vkcv::VertexLayout quadLayout({quadBinding}); - - const vkcv::Mesh loadedQuad(quadVertexBufferBindings, quadIndexBuffer.getVulkanHandle(), quadIndices.size()); - - // RESOURCES - vkcv::Image meshTexture = core.createImage(vk::Format::eR8G8B8A8Srgb, mesh.texture_hack.w, mesh.texture_hack.h); - meshTexture.fill(mesh.texture_hack.img); - const vkcv::ImageHandle meshTextureHandle = meshTexture.getHandle(); - - vkcv::ImageHandle depthBufferHandle = core.createImage(vk::Format::eD32Sfloat, windowWidth, windowHeight).getHandle(); - - vkcv::Image offscreenImage = core.createImage(vk::Format::eB10G11R11UfloatPack32, windowWidth, windowHeight, 1); - vkcv::ImageHandle bloomImageHandle = core.createImage(vk::Format::eB10G11R11UfloatPack32, windowWidth, windowHeight, 1).getHandle(); - - const vkcv::ImageHandle swapchainHandle = vkcv::ImageHandle::createSwapchainImageHandle(); - - - const vkcv::ImageHandle shadowMapHandle = core.createImage(vk::Format::eD16Unorm, 1024, 1024, 1).getHandle(); - - const vkcv::SamplerHandle linearSampler = core.createSampler( - vkcv::SamplerFilterType::LINEAR, - vkcv::SamplerFilterType::LINEAR, - vkcv::SamplerMipmapMode::LINEAR, - vkcv::SamplerAddressMode::REPEAT - ); - - const vkcv::SamplerHandle shadowSampler = core.createSampler( - vkcv::SamplerFilterType::NEAREST, - vkcv::SamplerFilterType::NEAREST, - vkcv::SamplerMipmapMode::NEAREST, - vkcv::SamplerAddressMode::CLAMP_TO_EDGE - ); - - - struct LightInfo { - glm::vec3 direction; - float padding; - glm::mat4 lightMatrix; - }; - LightInfo lightInfo{}; - vkcv::Buffer lightBuffer = core.createBuffer<LightInfo>(vkcv::BufferType::UNIFORM, sizeof(glm::vec3)); - - // PIPELINES & DESCRIPTOR STUFF - const std::vector<vkcv::DescriptorBinding> meshDescriptorBindings = { meshProgram.getReflectedDescriptors()[0] }; - const vkcv::DescriptorSetHandle meshDescriptorSet = core.createDescriptorSet(meshDescriptorBindings); - const vkcv::DescriptorSetUsage meshDescriptorUsage(0, core.getDescriptorSet(meshDescriptorSet).vulkanHandle); - - vkcv::DescriptorWrites meshDescriptorWrites; - meshDescriptorWrites.sampledImageWrites = { - vkcv::SampledImageDescriptorWrite(0, meshTextureHandle), - vkcv::SampledImageDescriptorWrite(3, shadowMapHandle) }; - meshDescriptorWrites.samplerWrites = { - vkcv::SamplerDescriptorWrite(1, linearSampler), - vkcv::SamplerDescriptorWrite(4, shadowSampler) }; - meshDescriptorWrites.uniformBufferWrites = { vkcv::UniformBufferDescriptorWrite(2, lightBuffer.getHandle()) }; - core.writeDescriptorSet(meshDescriptorSet, meshDescriptorWrites); - - const vkcv::PipelineConfig meshPipelineConfig( - meshProgram, + vkcv::asset::Texture& sceneTexture = scene.textures[baseColorIndex]; + + sceneImages.push_back(core.createImage(vk::Format::eR8G8B8A8Srgb, sceneTexture.w, sceneTexture.h)); + sceneImages.back().fill(sceneTexture.data.data()); + + vkcv::DescriptorWrites setWrites; + setWrites.sampledImageWrites = { + vkcv::SampledImageDescriptorWrite(0, sceneImages.back().getHandle()) + }; + setWrites.samplerWrites = { + vkcv::SamplerDescriptorWrite(1, colorSampler), + }; + core.writeDescriptorSet(perMeshDescriptorSets.back(), setWrites); + } + + const vkcv::PipelineConfig forwardPipelineConfig { + forwardProgram, windowWidth, windowHeight, - meshPassHandle, - {meshVertexLayout}, - { core.getDescriptorSet(meshDescriptorSet).layout }, - true); - vkcv::PipelineHandle meshPipelineHandle = core.createGraphicsPipeline(meshPipelineConfig); - - // -- - - const vkcv::PipelineConfig shadowPipeConfig( - shadowProgram, - 1024, - 1024, - shadowPassHandle, - {meshVertexLayout}, - {}, - false); - const vkcv::PipelineHandle shadowPipelineHandle = core.createGraphicsPipeline(shadowPipeConfig); - - // -- - - const std::vector<vkcv::DescriptorBinding> bloomSetBindings = bloomComputeProgram.getReflectedDescriptors()[0]; - const vkcv::DescriptorSetHandle bloomSetHandle = core.createDescriptorSet(bloomSetBindings); - const vkcv::DescriptorSetUsage bloomSetUsage(0, core.getDescriptorSet(bloomSetHandle).vulkanHandle); - - vkcv::DescriptorWrites bloomSetWrites; - bloomSetWrites.sampledImageWrites = {vkcv::SampledImageDescriptorWrite(0, offscreenImage.getHandle())}; - bloomSetWrites.samplerWrites = {vkcv::SamplerDescriptorWrite(1, linearSampler)}; - bloomSetWrites.storageImageWrites = {vkcv::StorageImageDescriptorWrite(2, bloomImageHandle)}; - core.writeDescriptorSet(bloomSetHandle, bloomSetWrites); - vkcv::PipelineHandle bloomComputePipelineHandle = core.createComputePipeline(bloomComputeProgram, {core.getDescriptorSet(bloomSetHandle).layout}); - - // -- - const std::vector<vkcv::DescriptorBinding> screenQuadBindings = { screenQuadProgram.getReflectedDescriptors()[0] }; - const vkcv::DescriptorSetHandle screenQuadSet = core.createDescriptorSet(screenQuadBindings); - const vkcv::DescriptorSetUsage screenQuadDescriptorUsage(0, core.getDescriptorSet(screenQuadSet).vulkanHandle); - - vkcv::DescriptorWrites screenQuadSetDescriptorWrites; - screenQuadSetDescriptorWrites.sampledImageWrites = { - vkcv::SampledImageDescriptorWrite(0, offscreenImage.getHandle()), - vkcv::SampledImageDescriptorWrite(1, bloomImageHandle) }; - screenQuadSetDescriptorWrites.samplerWrites = { - vkcv::SamplerDescriptorWrite(2, linearSampler) }; - core.writeDescriptorSet(screenQuadSet, screenQuadSetDescriptorWrites); - - const vkcv::PipelineConfig screenQuadConfig( - screenQuadProgram, - windowWidth, - windowHeight, - screenQuadPassHandle, - {quadLayout}, - { core.getDescriptorSet(meshDescriptorSet).layout }, - true); - vkcv::PipelineHandle screenQuadPipelineHandle = core.createGraphicsPipeline(screenQuadConfig); - - if (!meshPipelineHandle || !shadowPipelineHandle || !bloomComputePipelineHandle) { - std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl; - return EXIT_FAILURE; - } - - // DRAWCALLS AND MVP STUFF - - const std::vector<glm::vec3> cubeTranslations = { - glm::vec3( 0.f, -2.f, 0.f), - glm::vec3( 3.f, 0.f, 0.f), - glm::vec3(-3.f, 0.f, 0.f), - glm::vec3( 0.f, 2.f, 0.f), - glm::vec3( 0.f, -5.f, 0.f) + forwardPass, + vertexLayout, + { core.getDescriptorSet(forwardShadingDescriptorSet).layout, + core.getDescriptorSet(perMeshDescriptorSets[0]).layout }, + true }; - - std::vector<glm::mat4> modelMatrices; - std::vector<vkcv::DrawcallInfo> meshDrawcalls; - std::vector<vkcv::DrawcallInfo> shadowDrawcalls; - for (const auto& translationVec : cubeTranslations) { - modelMatrices.push_back(glm::translate(glm::mat4(1.f), translationVec)); - meshDrawcalls.push_back(vkcv::DrawcallInfo(loadedMesh, { meshDescriptorUsage })); - shadowDrawcalls.push_back(vkcv::DrawcallInfo(loadedMesh, {})); + + vkcv::PipelineHandle forwardPipeline = core.createGraphicsPipeline(forwardPipelineConfig); + + if (!forwardPipeline) { + std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl; + return EXIT_FAILURE; } - vkcv::DrawcallInfo quadDrawcall(loadedQuad, {screenQuadDescriptorUsage}); - - modelMatrices.back() *= glm::scale(glm::mat4(1.f), glm::vec3(10.f, 1.f, 10.f)); + vkcv::ImageHandle depthBuffer = core.createImage(depthBufferFormat, windowWidth, windowHeight).getHandle(); + vkcv::ImageHandle colorBuffer = core.createImage(colorBufferFormat, windowWidth, windowHeight, 1, true, true).getHandle(); + vkcv::ImageHandle blurBuffer = core.createImage(colorBufferFormat, windowWidth, windowHeight, 1, true, false).getHandle(); + vkcv::SamplerHandle linearSampler = core.createSampler(vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerFilterType::LINEAR, + vkcv::SamplerMipmapMode::LINEAR, + vkcv::SamplerAddressMode::CLAMP_TO_EDGE); + + const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); + + vkcv::ShaderProgram shadowShader; + compiler.compile(vkcv::ShaderStage::VERTEX, "resources/shaders/shadow.vert", + [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + shadowShader.addShader(shaderStage, path); + }); + compiler.compile(vkcv::ShaderStage::FRAGMENT, "resources/shaders/shadow.frag", + [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + shadowShader.addShader(shaderStage, path); + }); + + const std::vector<vkcv::AttachmentDescription> shadowAttachments = { + vkcv::AttachmentDescription(vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, shadowMapFormat) + }; + const vkcv::PassConfig shadowPassConfig(shadowAttachments); + const vkcv::PassHandle shadowPass = core.createPass(shadowPassConfig); + const vkcv::PipelineConfig shadowPipeConfig{ + shadowShader, + shadowMapResolution, + shadowMapResolution, + shadowPass, + vertexLayout, + {}, + false + }; + const vkcv::PipelineHandle shadowPipe = core.createGraphicsPipeline(shadowPipeConfig); std::vector<std::array<glm::mat4, 2>> mainPassMatrices; std::vector<glm::mat4> mvpLight; + // gamma correction compute shader + vkcv::ShaderProgram gammaCorrectionProgram; + compiler.compile(vkcv::ShaderStage::COMPUTE, "resources/shaders/gammaCorrection.comp", + [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) { + gammaCorrectionProgram.addShader(shaderStage, path); + }); + vkcv::DescriptorSetHandle gammaCorrectionDescriptorSet = core.createDescriptorSet(gammaCorrectionProgram.getReflectedDescriptors()[0]); + vkcv::PipelineHandle gammaCorrectionPipeline = core.createComputePipeline(gammaCorrectionProgram, + { core.getDescriptorSet(gammaCorrectionDescriptorSet).layout }); + + // blur compute shader + vkcv::ShaderProgram blurProgram; + compiler.compile(vkcv::ShaderStage::COMPUTE, + "resources/shaders/blur.comp", + [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) + { + blurProgram.addShader(shaderStage, path); + }); + vkcv::DescriptorSetHandle blurDescriptorSet = core.createDescriptorSet(blurProgram.getReflectedDescriptors()[0]); + vkcv::PipelineHandle blurPipeline = core.createComputePipeline(blurProgram, + { core.getDescriptorSet(blurDescriptorSet).layout }); + + // bloom composite shader + vkcv::ShaderProgram compositeBloomProgram; + compiler.compile(vkcv::ShaderStage::COMPUTE, + "resources/shaders/compositeBloom.comp", + [&](vkcv::ShaderStage shaderStage, const std::filesystem::path& path) + { + compositeBloomProgram.addShader(shaderStage, path); + }); + vkcv::DescriptorSetHandle compositeBloomDescriptorSet = core.createDescriptorSet(compositeBloomProgram.getReflectedDescriptors()[0]); + vkcv::PipelineHandle compositeBloomPipeline = core.createComputePipeline(compositeBloomProgram, + { core.getDescriptorSet(compositeBloomDescriptorSet).layout }); + + // model matrices per mesh + std::vector<glm::mat4> modelMatrices; + modelMatrices.resize(scene.vertexGroups.size(), glm::mat4(1.f)); + for (const auto& mesh : scene.meshes) { + const glm::mat4 m = *reinterpret_cast<const glm::mat4*>(&mesh.modelMatrix[0]); + for (const auto& vertexGroupIndex : mesh.vertexGroups) { + modelMatrices[vertexGroupIndex] = m; + } + } + + // prepare drawcalls + std::vector<vkcv::Mesh> meshes; + for (int i = 0; i < scene.vertexGroups.size(); i++) { + vkcv::Mesh mesh( + vertexBufferBindings[i], + indexBuffers[i].getVulkanHandle(), + scene.vertexGroups[i].numIndices); + meshes.push_back(mesh); + } + + std::vector<vkcv::DrawcallInfo> drawcalls; + std::vector<vkcv::DrawcallInfo> shadowDrawcalls; + for (int i = 0; i < meshes.size(); i++) { + + drawcalls.push_back(vkcv::DrawcallInfo(meshes[i], { + vkcv::DescriptorSetUsage(0, core.getDescriptorSet(forwardShadingDescriptorSet).vulkanHandle), + vkcv::DescriptorSetUsage(1, core.getDescriptorSet(perMeshDescriptorSets[i]).vulkanHandle) })); + shadowDrawcalls.push_back(vkcv::DrawcallInfo(meshes[i], {})); + } auto start = std::chrono::system_clock::now(); const auto appStartTime = start; - while (window.isWindowOpen()) { + while (window.isWindowOpen()) { vkcv::Window::pollEvents(); uint32_t swapchainWidth, swapchainHeight; if (!core.beginFrame(swapchainWidth, swapchainHeight)) { continue; } + if ((swapchainWidth != windowWidth) || ((swapchainHeight != windowHeight))) { - depthBufferHandle = core.createImage(vk::Format::eD32Sfloat, swapchainWidth, swapchainHeight).getHandle(); + depthBuffer = core.createImage(depthBufferFormat, swapchainWidth, swapchainHeight).getHandle(); + colorBuffer = core.createImage(colorBufferFormat, swapchainWidth, swapchainHeight, 1, true, true).getHandle(); + blurBuffer = core.createImage(colorBufferFormat, windowWidth, windowHeight, 1, true, false).getHandle(); windowWidth = swapchainWidth; windowHeight = swapchainHeight; @@ -334,13 +346,38 @@ int main(int argc, const char** argv) { auto end = std::chrono::system_clock::now(); auto deltatime = std::chrono::duration_cast<std::chrono::microseconds>(end - start); + + // update descriptor sets which use swapchain image + // blur + vkcv::DescriptorWrites blurDescriptorWrites; + blurDescriptorWrites.sampledImageWrites = {vkcv::SampledImageDescriptorWrite(0, colorBuffer)}; + blurDescriptorWrites.samplerWrites = {vkcv::SamplerDescriptorWrite(1, linearSampler)}; + blurDescriptorWrites.storageImageWrites = {vkcv::StorageImageDescriptorWrite(2, blurBuffer) }; + core.writeDescriptorSet(blurDescriptorSet, blurDescriptorWrites); + + // composite bloom + vkcv::DescriptorWrites compositeBloomDescriptorWrites; + compositeBloomDescriptorWrites.sampledImageWrites = {vkcv::SampledImageDescriptorWrite(0, blurBuffer)}; + compositeBloomDescriptorWrites.samplerWrites = {vkcv::SamplerDescriptorWrite(1, linearSampler)}; + compositeBloomDescriptorWrites.storageImageWrites = {vkcv::StorageImageDescriptorWrite(2, colorBuffer)}; + core.writeDescriptorSet(compositeBloomDescriptorSet, compositeBloomDescriptorWrites); + + // gamma correction + vkcv::DescriptorWrites gammaCorrectionDescriptorWrites; + gammaCorrectionDescriptorWrites.storageImageWrites = { + vkcv::StorageImageDescriptorWrite(0, colorBuffer), + vkcv::StorageImageDescriptorWrite(1, swapchainInput) }; + core.writeDescriptorSet(gammaCorrectionDescriptorSet, gammaCorrectionDescriptorWrites); + start = end; - cameraManager.getCamera().updateView(deltatime.count() * 0.000001); + cameraManager.update(0.000001 * static_cast<double>(deltatime.count())); - const float sunTheta = std::chrono::duration_cast<std::chrono::milliseconds>(end - appStartTime).count() * 0.001f; + auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - appStartTime); + + const float sunTheta = 0.0001f * static_cast<float>(duration.count()); lightInfo.direction = glm::normalize(glm::vec3(std::cos(sunTheta), 1, std::sin(sunTheta))); - const float shadowProjectionSize = 5.f; + const float shadowProjectionSize = 20.f; glm::mat4 projectionLight = glm::ortho( -shadowProjectionSize, shadowProjectionSize, @@ -359,70 +396,85 @@ int main(int argc, const char** argv) { lightInfo.lightMatrix = projectionLight * viewLight; lightBuffer.fill({ lightInfo }); - const glm::mat4 viewProjectionCamera = cameraManager.getCamera().getProjection() * cameraManager.getCamera().getView(); + const glm::mat4 viewProjectionCamera = cameraManager.getActiveCamera().getMVP(); mainPassMatrices.clear(); mvpLight.clear(); for (const auto& m : modelMatrices) { mainPassMatrices.push_back({ viewProjectionCamera * m, m }); - mvpLight.push_back(lightInfo.lightMatrix* m); + mvpLight.push_back(lightInfo.lightMatrix * m); } vkcv::PushConstantData pushConstantData((void*)mainPassMatrices.data(), 2 * sizeof(glm::mat4)); + const std::vector<vkcv::ImageHandle> renderTargets = { colorBuffer, depthBuffer }; - vkcv::PushConstantData shadowPushConstantData((void*)mvpLight.data(), sizeof(glm::mat4)); + const vkcv::PushConstantData shadowPushConstantData((void*)mvpLight.data(), sizeof(glm::mat4)); auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); - // shadow map pass + // shadow map core.recordDrawcallsToCmdStream( cmdStream, - shadowPassHandle, - shadowPipelineHandle, + shadowPass, + shadowPipe, shadowPushConstantData, shadowDrawcalls, - { shadowMapHandle }); + { shadowMap.getHandle() }); + core.prepareImageForSampling(cmdStream, shadowMap.getHandle()); - core.prepareImageForSampling(cmdStream, shadowMapHandle); - - // offscreen render pass + // main pass core.recordDrawcallsToCmdStream( cmdStream, - meshPassHandle, - meshPipelineHandle, + forwardPass, + forwardPipeline, pushConstantData, - meshDrawcalls, - {offscreenImage.getHandle(), depthBufferHandle}); + drawcalls, + renderTargets); + const uint32_t gammaCorrectionLocalGroupSize = 8; + const uint32_t gammaCorrectionDispatchCount[3] = { + static_cast<uint32_t>(glm::ceil(windowWidth / static_cast<float>(gammaCorrectionLocalGroupSize))), + static_cast<uint32_t>(glm::ceil(windowHeight / static_cast<float>(gammaCorrectionLocalGroupSize))), + 1 + }; - core.prepareImageForSampling(cmdStream, offscreenImage.getHandle()); - //core.prepareImageForStorage(cmdStream, bloomAttachment.getHandle()); + core.prepareImageForSampling(cmdStream, colorBuffer); + core.prepareImageForStorage(cmdStream, blurBuffer); - // compute blur pass - const std::array<uint32_t, 3> dispatchCount = {windowWidth, windowHeight, 0}; - /* + // blur dispatch core.recordComputeDispatchToCmdStream( cmdStream, - bloomComputePipeline, - dispatchCount.data(), - {bloomSetUsage}, + blurPipeline, + gammaCorrectionDispatchCount, + {vkcv::DescriptorSetUsage(0, core.getDescriptorSet(blurDescriptorSet).vulkanHandle)}, vkcv::PushConstantData(nullptr, 0)); - */ - // final compositing screen quad pass - core.recordDrawcallsToCmdStream( - cmdStream, - screenQuadPassHandle, - screenQuadPipelineHandle, - vkcv::PushConstantData(nullptr, 0), - {quadDrawcall}, - {swapchainHandle} - ); + core.prepareImageForStorage(cmdStream, colorBuffer); + core.prepareImageForSampling(cmdStream, blurBuffer); + + // bloom composite dispatch + core.recordComputeDispatchToCmdStream(cmdStream, + compositeBloomPipeline, + gammaCorrectionDispatchCount, + {vkcv::DescriptorSetUsage(0, core.getDescriptorSet(compositeBloomDescriptorSet).vulkanHandle)}, + vkcv::PushConstantData(nullptr, 0)); + + core.prepareImageForStorage(cmdStream, swapchainInput); + + // gamma correction dispatch + core.recordComputeDispatchToCmdStream( + cmdStream, + gammaCorrectionPipeline, + gammaCorrectionDispatchCount, + { vkcv::DescriptorSetUsage(0, core.getDescriptorSet(gammaCorrectionDescriptorSet).vulkanHandle) }, + vkcv::PushConstantData(nullptr, 0)); + + // present and end core.prepareSwapchainImageForPresent(cmdStream); core.submitCommandStream(cmdStream); core.endFrame(); } - + return 0; }