From 6912366c4512ab4d369927df4a14947bbe4d730f Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 9 Feb 2025 19:16:56 +0100 Subject: [PATCH 01/73] Add slang compilation script --- shaders/slang/compileshaders.py | 47 +++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 shaders/slang/compileshaders.py diff --git a/shaders/slang/compileshaders.py b/shaders/slang/compileshaders.py new file mode 100644 index 00000000..8c0784bb --- /dev/null +++ b/shaders/slang/compileshaders.py @@ -0,0 +1,47 @@ +# Copyright (C) 2025 by Sascha Willems - www.saschawillems.de +# This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +import argparse +import fileinput +import os +import subprocess +import sys + +parser = argparse.ArgumentParser(description='Compile all slang shaders') +parser.add_argument('--slangc', type=str, help='path to slangc executable') +args = parser.parse_args() + +def findCompiler(): + def isExe(path): + return os.path.isfile(path) and os.access(path, os.X_OK) + + if args.slangc != None and isExe(args.slangc): + return args.slangc + + exe_name = "slangc" + if os.name == "nt": + exe_name += ".exe" + + for exe_dir in os.environ["PATH"].split(os.pathsep): + full_path = os.path.join(exe_dir, exe_name) + if isExe(full_path): + return full_path + + sys.exit("Could not find slangc executable on PATH, and was not specified with --slangc") + +file_extensions = tuple([".vert", ".frag", ".comp", ".geom", ".tesc", ".tese", ".rgen", ".rchit", ".rmiss", ".mesh", ".task"]) + +compiler_path = findCompiler() + +print("Found slang compiler at %s", compiler_path) + +dir_path = os.path.dirname(os.path.realpath(__file__)) +dir_path = dir_path.replace('\\', '/') +for root, dirs, files in os.walk(dir_path): + for file in files: + if file.endswith(".slang"): + input_file = os.path.join(root, file) + output_file = input_file + ".spv" + res = subprocess.call("%s %s -profile glsl_460 -target spirv -o %s -entry %s" % (compiler_path, input_file, output_file, "main"), shell=True) + if res != 0: + sys.exit(res) \ No newline at end of file From e9673f1ac37e427845146daa38d7edc95eeee72b Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 9 Feb 2025 19:17:10 +0100 Subject: [PATCH 02/73] Add slang shaders for UI overlay --- shaders/slang/base/uioverlay.frag.slang | 20 +++++++++++++ shaders/slang/base/uioverlay.vert.slang | 38 +++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 shaders/slang/base/uioverlay.frag.slang create mode 100644 shaders/slang/base/uioverlay.vert.slang diff --git a/shaders/slang/base/uioverlay.frag.slang b/shaders/slang/base/uioverlay.frag.slang new file mode 100644 index 00000000..4559309a --- /dev/null +++ b/shaders/slang/base/uioverlay.frag.slang @@ -0,0 +1,20 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +[[vk::binding(0, 0)]] +Sampler2D fontTexture; + +struct VSOutput +{ + [[vk::location(0)]]float2 UV : TEXCOORD0; + [[vk::location(1)]]float4 Color : COLOR0; +}; + +[shader("fragment")] +float4 main(VSOutput input) : SV_TARGET +{ + return input.Color * fontTexture.Sample(input.UV); +} \ No newline at end of file diff --git a/shaders/slang/base/uioverlay.vert.slang b/shaders/slang/base/uioverlay.vert.slang new file mode 100644 index 00000000..80ddf5f0 --- /dev/null +++ b/shaders/slang/base/uioverlay.vert.slang @@ -0,0 +1,38 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + [[vk::location(0)]]float2 Pos : POSITION0; + [[vk::location(1)]]float2 UV : TEXCOORD0; + [[vk::location(2)]]float4 Color : COLOR0; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + [[vk::location(0)]]float2 UV : TEXCOORD0; + [[vk::location(1)]]float4 Color : COLOR0; +}; + +struct PushConstants +{ + float2 scale; + float2 translate; +}; + +[[vk::push_constant]] +PushConstants pushConstants; + +[shader("fragment")] +VSOutput main(VSInput input) +{ + VSOutput output; + output.Pos = float4(input.Pos * pushConstants.scale + pushConstants.translate, 0.0, 1.0); + output.UV = input.UV; + output.Color = input.Color; + return output; +} \ No newline at end of file From 9f38b820ccae959910a17dbc7fb7eb4efe2fe6bc Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 9 Feb 2025 19:59:27 +0100 Subject: [PATCH 03/73] Adjust compiled spv file name --- shaders/slang/compileshaders.py | 1 + 1 file changed, 1 insertion(+) diff --git a/shaders/slang/compileshaders.py b/shaders/slang/compileshaders.py index 8c0784bb..303b40bf 100644 --- a/shaders/slang/compileshaders.py +++ b/shaders/slang/compileshaders.py @@ -42,6 +42,7 @@ for root, dirs, files in os.walk(dir_path): if file.endswith(".slang"): input_file = os.path.join(root, file) output_file = input_file + ".spv" + output_file = output_file.replace(".slang", "") res = subprocess.call("%s %s -profile glsl_460 -target spirv -o %s -entry %s" % (compiler_path, input_file, output_file, "main"), shell=True) if res != 0: sys.exit(res) \ No newline at end of file From d8edd9203458f2f97899f1f07f5b3f6401801f19 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 9 Feb 2025 20:00:44 +0100 Subject: [PATCH 04/73] Fix shader type --- shaders/slang/base/uioverlay.vert.slang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shaders/slang/base/uioverlay.vert.slang b/shaders/slang/base/uioverlay.vert.slang index 80ddf5f0..8fe08df1 100644 --- a/shaders/slang/base/uioverlay.vert.slang +++ b/shaders/slang/base/uioverlay.vert.slang @@ -27,7 +27,7 @@ struct PushConstants [[vk::push_constant]] PushConstants pushConstants; -[shader("fragment")] +[shader("vertex")] VSOutput main(VSInput input) { VSOutput output; From 2846c73db02c043ed16b4c5bba33e4f1ed29d755 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Mon, 10 Feb 2025 19:09:19 +0100 Subject: [PATCH 05/73] Add slang shaders for triangle samples --- shaders/slang/triangle/triangle.frag.slang | 11 +++++++ shaders/slang/triangle/triangle.vert.slang | 35 ++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 shaders/slang/triangle/triangle.frag.slang create mode 100644 shaders/slang/triangle/triangle.vert.slang diff --git a/shaders/slang/triangle/triangle.frag.slang b/shaders/slang/triangle/triangle.frag.slang new file mode 100644 index 00000000..7ae7fa20 --- /dev/null +++ b/shaders/slang/triangle/triangle.frag.slang @@ -0,0 +1,11 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +[shader("fragment")] +float4 main([[vk::location(0)]] float3 Color) +{ + return float4(Color, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/triangle/triangle.vert.slang b/shaders/slang/triangle/triangle.vert.slang new file mode 100644 index 00000000..d8305fa5 --- /dev/null +++ b/shaders/slang/triangle/triangle.vert.slang @@ -0,0 +1,35 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct UBO +{ + float4x4 projectionMatrix; + float4x4 modelMatrix; + float4x4 viewMatrix; +}; +[[vk::binding(0, 0)]] +ConstantBuffer ubo; + +struct VSInput +{ + [[vk::location(0)]] float3 Pos; + [[vk::location(1)]] float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + [[vk::location(0)]] float3 Color; +}; + +[shader("vertex")] +VSOutput main(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.Pos = mul(ubo.projectionMatrix, mul(ubo.viewMatrix, mul(ubo.modelMatrix, float4(input.Pos.xyz, 1.0)))); + return output; +} From 2593d707943e7c3c8418c77dea3da38a73d010c3 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Wed, 19 Mar 2025 21:36:06 +0100 Subject: [PATCH 06/73] Use SPIR-V profile --- shaders/slang/compileshaders.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/shaders/slang/compileshaders.py b/shaders/slang/compileshaders.py index 303b40bf..2f5e2e83 100644 --- a/shaders/slang/compileshaders.py +++ b/shaders/slang/compileshaders.py @@ -29,8 +29,6 @@ def findCompiler(): sys.exit("Could not find slangc executable on PATH, and was not specified with --slangc") -file_extensions = tuple([".vert", ".frag", ".comp", ".geom", ".tesc", ".tese", ".rgen", ".rchit", ".rmiss", ".mesh", ".task"]) - compiler_path = findCompiler() print("Found slang compiler at %s", compiler_path) @@ -43,6 +41,6 @@ for root, dirs, files in os.walk(dir_path): input_file = os.path.join(root, file) output_file = input_file + ".spv" output_file = output_file.replace(".slang", "") - res = subprocess.call("%s %s -profile glsl_460 -target spirv -o %s -entry %s" % (compiler_path, input_file, output_file, "main"), shell=True) + res = subprocess.call("%s %s -profile spirv_1_4 -target spirv -o %s -entry %s" % (compiler_path, input_file, output_file, "main"), shell=True) if res != 0: sys.exit(res) \ No newline at end of file From bc3c41e89a7062f98a7c191adc6763214471e0ab Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 23 Mar 2025 18:52:23 +0100 Subject: [PATCH 07/73] Add notes on slang support --- README.md | 4 ++-- shaders/README.md | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1a11894c..c2355f24 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ Once built, examples can be run from the bin directory. The list of available co -vs, --vsync: Enable V-Sync -f, --fullscreen: Start in fullscreen mode -w, --width: Set window width - -s, --shaders: Select shader type to use (glsl or hlsl) + -s, --shaders: Select shader type to use (glsl, hlsl, slang) -g, --gpu: Select GPU to run on -gl, --listgpus: Display a list of available Vulkan devices -b, --benchmark: Run example in benchmark mode @@ -83,7 +83,7 @@ Note that some examples require specific device features, and if you are on a mu ## Shaders -Vulkan consumes shaders in an intermediate representation called SPIR-V. This makes it possible to use different shader languages by compiling them to that bytecode format. The primary shader language used here is [GLSL](shaders/glsl) but most samples also come with [HLSL](shaders/hlsl) shader sources. +Vulkan consumes shaders in an intermediate representation called SPIR-V. This makes it possible to use different shader languages by compiling them to that bytecode format. The primary shader language used here is [GLSL](shaders/glsl), most samples also come with [HLSL](shaders/hlsl) and [slang](shaders/slang/) shader sources ## A note on synchronization diff --git a/shaders/README.md b/shaders/README.md index 3787f3d8..e8b75831 100644 --- a/shaders/README.md +++ b/shaders/README.md @@ -1,3 +1,5 @@ # Shaders -This folder contains the shaders used by the samples. Source files are available as GLSL and HLSL and also come with precompiled SPIR-V files that are consumed by the samples. To recompile shaders you can use the `compileshaders.py` scripts in the respective folders or any other means that can generate Vulkan SPIR-V from GLSL or HLSL. One such option is [this extension for Visual Studio](https://github.com/SaschaWillems/SPIRV-VSExtension). \ No newline at end of file +This folder contains the shaders used by the samples. Source files are available in GLSL, HLSL and [slang](https://shader-slang.org/) and also come with precompiled SPIR-V files that are consumed by the samples. To recompile shaders you can use the `compileshaders.py` scripts in the respective folders or any other means that can generate Vulkan SPIR-V from GLSL, HLSL or slang. One such option is [this extension for Visual Studio](https://github.com/SaschaWillems/SPIRV-VSExtension). + +Note that not all samples may come with all shading language variants. So some samples that have GLSL source files might not come with HLSL and/or slang source files. \ No newline at end of file From 880b48485f797439a3c098582bb207b8d0fe3afc Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Fri, 28 Mar 2025 15:16:45 +0100 Subject: [PATCH 08/73] Slang shaders for buffer device address example --- .../slang/bufferdeviceaddress/cube.frag.slang | 20 ++++++++ .../slang/bufferdeviceaddress/cube.vert.slang | 47 +++++++++++++++++++ shaders/slang/compileshaders.py | 2 +- 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 shaders/slang/bufferdeviceaddress/cube.frag.slang create mode 100644 shaders/slang/bufferdeviceaddress/cube.vert.slang diff --git a/shaders/slang/bufferdeviceaddress/cube.frag.slang b/shaders/slang/bufferdeviceaddress/cube.frag.slang new file mode 100644 index 00000000..05b8e1d0 --- /dev/null +++ b/shaders/slang/bufferdeviceaddress/cube.frag.slang @@ -0,0 +1,20 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + + [[vk::binding(0, 0)]] +Sampler2D samplerColorMap; + +struct VSInput +{ + [[vk::location(1)]] float3 Color; + [[vk::location(2)]] float2 UV; +}; + +[shader("fragment")] +float4 main(VSInput input) +{ + return samplerColorMap.Sample(input.UV) * float4(input.Color, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/bufferdeviceaddress/cube.vert.slang b/shaders/slang/bufferdeviceaddress/cube.vert.slang new file mode 100644 index 00000000..2d419f5a --- /dev/null +++ b/shaders/slang/bufferdeviceaddress/cube.vert.slang @@ -0,0 +1,47 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + [[vk::location(0)]] float3 Pos; + [[vk::location(1)]] float3 Normal; + [[vk::location(2)]] float2 UV; + [[vk::location(3)]] float3 Color; +}; + +struct MatrixReference { + float4x4 matrix; +}; + +struct PushConsts { + // Pointer to the buffer with the scene's MVP matrix + ConstBufferPointer sceneDataReference; + // Pointer to the buffer for the data for each model + ConstBufferPointer modelDataReference; +}; +[[vk::push_constant]] PushConsts pushConstants; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + [[vk::location(0)]] float3 Normal; + [[vk::location(1)]] float3 Color; + [[vk::location(2)]] float2 UV; +}; + +[shader("vertex")] +VSOutput main(VSInput input) +{ + MatrixReference sceneData = pushConstants.sceneDataReference.get(); + MatrixReference modelData = pushConstants.modelDataReference.get(); + + VSOutput output; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(sceneData.matrix, mul(modelData.matrix, float4(input.Pos.xyz, 1.0))); + return output; +} \ No newline at end of file diff --git a/shaders/slang/compileshaders.py b/shaders/slang/compileshaders.py index 2f5e2e83..cd3f54c1 100644 --- a/shaders/slang/compileshaders.py +++ b/shaders/slang/compileshaders.py @@ -41,6 +41,6 @@ for root, dirs, files in os.walk(dir_path): input_file = os.path.join(root, file) output_file = input_file + ".spv" output_file = output_file.replace(".slang", "") - res = subprocess.call("%s %s -profile spirv_1_4 -target spirv -o %s -entry %s" % (compiler_path, input_file, output_file, "main"), shell=True) + res = subprocess.call("%s %s -profile spirv_1_4 -matrix-layout-column-major -target spirv -o %s -entry %s" % (compiler_path, input_file, output_file, "main"), shell=True) if res != 0: sys.exit(res) \ No newline at end of file From 22ae3726e62adf3fe35aa600da489fb5f19c644a Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Fri, 28 Mar 2025 17:43:10 +0100 Subject: [PATCH 09/73] Slang shaders for push constants sample --- .../pushconstants/pushconstants.frag.slang | 16 ++++++++ .../pushconstants/pushconstants.vert.slang | 38 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 shaders/slang/pushconstants/pushconstants.frag.slang create mode 100644 shaders/slang/pushconstants/pushconstants.vert.slang diff --git a/shaders/slang/pushconstants/pushconstants.frag.slang b/shaders/slang/pushconstants/pushconstants.frag.slang new file mode 100644 index 00000000..a2646791 --- /dev/null +++ b/shaders/slang/pushconstants/pushconstants.frag.slang @@ -0,0 +1,16 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSOutput +{ + float3 Color; +}; + +[shader("fragment")] +float4 main(VSOutput input) : SV_TARGET +{ + return float4(input.Color, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/pushconstants/pushconstants.vert.slang b/shaders/slang/pushconstants/pushconstants.vert.slang new file mode 100644 index 00000000..538ea288 --- /dev/null +++ b/shaders/slang/pushconstants/pushconstants.vert.slang @@ -0,0 +1,38 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos : POSITION0; + float3 Normal : NORMAL0; + float3 Color : COLOR0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; +}; +ConstantBuffer ubo; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Color; +}; + +// Uniform entry-point parameters are automatically bound to push constants by slang +[shader("vertex")] +VSOutput main(VSInput input, uniform float4 pushColor, uniform float4 pushPosition) +{ + VSOutput output; + output.Color = input.Color * pushColor.rgb; + float3 locPos = float3(mul(ubo.model, float4(input.Pos.xyz, 1.0)).xyz); + float3 worldPos = locPos + pushPosition.xyz; + output.Pos = mul(ubo.projection, mul(ubo.view, float4(worldPos.xyz, 1.0))); + return output; +} \ No newline at end of file From 7327a9f4abc1a431c751f725b32a6f8880457ceb Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 29 Mar 2025 09:52:21 +0100 Subject: [PATCH 10/73] Slang shader compilation script can now handle multiple stages in one file --- shaders/slang/compileshaders.py | 38 ++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/shaders/slang/compileshaders.py b/shaders/slang/compileshaders.py index cd3f54c1..f2a29c77 100644 --- a/shaders/slang/compileshaders.py +++ b/shaders/slang/compileshaders.py @@ -29,6 +29,17 @@ def findCompiler(): sys.exit("Could not find slangc executable on PATH, and was not specified with --slangc") +def getShaderStages(filename): + stages = [] + with open(filename) as f: + filecontent = f.read() + if '[shader("vertex")]' in filecontent: + stages.append("vertex") + if '[shader("fragment")]' in filecontent: + stages.append("fragment") + f.close() + return stages + compiler_path = findCompiler() print("Found slang compiler at %s", compiler_path) @@ -39,8 +50,25 @@ for root, dirs, files in os.walk(dir_path): for file in files: if file.endswith(".slang"): input_file = os.path.join(root, file) - output_file = input_file + ".spv" - output_file = output_file.replace(".slang", "") - res = subprocess.call("%s %s -profile spirv_1_4 -matrix-layout-column-major -target spirv -o %s -entry %s" % (compiler_path, input_file, output_file, "main"), shell=True) - if res != 0: - sys.exit(res) \ No newline at end of file + # Slang can store multiple shader stages in a single file, we need to split into separate SPIR-V files for the sample framework + stages = getShaderStages(input_file) + print("Compiling %s" % input_file) + for stage in stages: + if (len(stages) > 1): + entry_point = stage + "main" + else: + entry_point = "main" + output_ext = "" + match stage: + case "vertex": + output_ext = ".vert" + case "fragment": + output_ext = ".frag" + output_file = input_file + output_ext + ".spv" + output_file = output_file.replace(".slang", "") + res = subprocess.call("%s %s -profile spirv_1_4 -matrix-layout-column-major -target spirv -o %s -entry %s -stage %s" % (compiler_path, input_file, output_file, entry_point, stage), shell=True) + print(output_file) + + # res = subprocess.call("%s %s -profile spirv_1_4 -matrix-layout-column-major -target spirv -o %s -entry %s" % (compiler_path, input_file, output_file, "main"), shell=True) + # if res != 0: + # sys.exit(res) \ No newline at end of file From cf3700cb2f4916dfa8cf10eead0e703a26d2f69e Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 29 Mar 2025 09:56:42 +0100 Subject: [PATCH 11/73] Support for multiple shader stages --- shaders/slang/compileshaders.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/shaders/slang/compileshaders.py b/shaders/slang/compileshaders.py index f2a29c77..61a36529 100644 --- a/shaders/slang/compileshaders.py +++ b/shaders/slang/compileshaders.py @@ -55,7 +55,7 @@ for root, dirs, files in os.walk(dir_path): print("Compiling %s" % input_file) for stage in stages: if (len(stages) > 1): - entry_point = stage + "main" + entry_point = stage + "Main" else: entry_point = "main" output_ext = "" @@ -67,8 +67,5 @@ for root, dirs, files in os.walk(dir_path): output_file = input_file + output_ext + ".spv" output_file = output_file.replace(".slang", "") res = subprocess.call("%s %s -profile spirv_1_4 -matrix-layout-column-major -target spirv -o %s -entry %s -stage %s" % (compiler_path, input_file, output_file, entry_point, stage), shell=True) - print(output_file) - - # res = subprocess.call("%s %s -profile spirv_1_4 -matrix-layout-column-major -target spirv -o %s -entry %s" % (compiler_path, input_file, output_file, "main"), shell=True) - # if res != 0: - # sys.exit(res) \ No newline at end of file + if res != 0: + sys.exit(res) \ No newline at end of file From c4556374c3eec6824da9deb4e7d2c0cc8ee76b2a Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 29 Mar 2025 10:31:46 +0100 Subject: [PATCH 12/73] Replace separate slang files per stage with single slang files containing multiple stages --- shaders/slang/base/uioverlay.frag.slang | 20 --------------- .../{uioverlay.vert.slang => uioverlay.slang} | 23 ++++++++++------- .../slang/bufferdeviceaddress/cube.frag.slang | 20 --------------- .../{cube.vert.slang => cube.slang} | 25 ++++++++++++------- .../pushconstants/pushconstants.frag.slang | 16 ------------ ...nstants.vert.slang => pushconstants.slang} | 8 +++++- shaders/slang/triangle/triangle.frag.slang | 11 -------- .../{triangle.vert.slang => triangle.slang} | 8 +++++- 8 files changed, 44 insertions(+), 87 deletions(-) delete mode 100644 shaders/slang/base/uioverlay.frag.slang rename shaders/slang/base/{uioverlay.vert.slang => uioverlay.slang} (58%) delete mode 100644 shaders/slang/bufferdeviceaddress/cube.frag.slang rename shaders/slang/bufferdeviceaddress/{cube.vert.slang => cube.slang} (70%) delete mode 100644 shaders/slang/pushconstants/pushconstants.frag.slang rename shaders/slang/pushconstants/{pushconstants.vert.slang => pushconstants.slang} (78%) delete mode 100644 shaders/slang/triangle/triangle.frag.slang rename shaders/slang/triangle/{triangle.vert.slang => triangle.slang} (81%) diff --git a/shaders/slang/base/uioverlay.frag.slang b/shaders/slang/base/uioverlay.frag.slang deleted file mode 100644 index 4559309a..00000000 --- a/shaders/slang/base/uioverlay.frag.slang +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2025, Sascha Willems - * - * SPDX-License-Identifier: MIT - * - */ - -[[vk::binding(0, 0)]] -Sampler2D fontTexture; - -struct VSOutput -{ - [[vk::location(0)]]float2 UV : TEXCOORD0; - [[vk::location(1)]]float4 Color : COLOR0; -}; - -[shader("fragment")] -float4 main(VSOutput input) : SV_TARGET -{ - return input.Color * fontTexture.Sample(input.UV); -} \ No newline at end of file diff --git a/shaders/slang/base/uioverlay.vert.slang b/shaders/slang/base/uioverlay.slang similarity index 58% rename from shaders/slang/base/uioverlay.vert.slang rename to shaders/slang/base/uioverlay.slang index 8fe08df1..d59b67b6 100644 --- a/shaders/slang/base/uioverlay.vert.slang +++ b/shaders/slang/base/uioverlay.slang @@ -4,18 +4,20 @@ * */ +Sampler2D fontTexture; + struct VSInput { - [[vk::location(0)]]float2 Pos : POSITION0; - [[vk::location(1)]]float2 UV : TEXCOORD0; - [[vk::location(2)]]float4 Color : COLOR0; + float2 Pos : POSITION0; + float2 UV; + float4 Color; }; struct VSOutput { float4 Pos : SV_POSITION; - [[vk::location(0)]]float2 UV : TEXCOORD0; - [[vk::location(1)]]float4 Color : COLOR0; + float2 UV; + float4 Color; }; struct PushConstants @@ -24,15 +26,18 @@ struct PushConstants float2 translate; }; -[[vk::push_constant]] -PushConstants pushConstants; - [shader("vertex")] -VSOutput main(VSInput input) +VSOutput vertexMain(VSInput input, uniform PushConstants pushConstants) { VSOutput output; output.Pos = float4(input.Pos * pushConstants.scale + pushConstants.translate, 0.0, 1.0); output.UV = input.UV; output.Color = input.Color; return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return input.Color * fontTexture.Sample(input.UV); } \ No newline at end of file diff --git a/shaders/slang/bufferdeviceaddress/cube.frag.slang b/shaders/slang/bufferdeviceaddress/cube.frag.slang deleted file mode 100644 index 05b8e1d0..00000000 --- a/shaders/slang/bufferdeviceaddress/cube.frag.slang +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (c) 2025, Sascha Willems - * - * SPDX-License-Identifier: MIT - * - */ - - [[vk::binding(0, 0)]] -Sampler2D samplerColorMap; - -struct VSInput -{ - [[vk::location(1)]] float3 Color; - [[vk::location(2)]] float2 UV; -}; - -[shader("fragment")] -float4 main(VSInput input) -{ - return samplerColorMap.Sample(input.UV) * float4(input.Color, 1.0); -} \ No newline at end of file diff --git a/shaders/slang/bufferdeviceaddress/cube.vert.slang b/shaders/slang/bufferdeviceaddress/cube.slang similarity index 70% rename from shaders/slang/bufferdeviceaddress/cube.vert.slang rename to shaders/slang/bufferdeviceaddress/cube.slang index 2d419f5a..4e86556a 100644 --- a/shaders/slang/bufferdeviceaddress/cube.vert.slang +++ b/shaders/slang/bufferdeviceaddress/cube.slang @@ -4,12 +4,14 @@ * */ +Sampler2D samplerColorMap; + struct VSInput { - [[vk::location(0)]] float3 Pos; - [[vk::location(1)]] float3 Normal; - [[vk::location(2)]] float2 UV; - [[vk::location(3)]] float3 Color; + float3 Pos; + float3 Normal; + float2 UV; + float3 Color; }; struct MatrixReference { @@ -22,18 +24,17 @@ struct PushConsts { // Pointer to the buffer for the data for each model ConstBufferPointer modelDataReference; }; -[[vk::push_constant]] PushConsts pushConstants; struct VSOutput { float4 Pos : SV_POSITION; - [[vk::location(0)]] float3 Normal; - [[vk::location(1)]] float3 Color; - [[vk::location(2)]] float2 UV; + float3 Normal; + float3 Color; + float2 UV; }; [shader("vertex")] -VSOutput main(VSInput input) +VSOutput vertexMain(VSInput input, uniform PushConsts pushConstants) { MatrixReference sceneData = pushConstants.sceneDataReference.get(); MatrixReference modelData = pushConstants.modelDataReference.get(); @@ -44,4 +45,10 @@ VSOutput main(VSInput input) output.UV = input.UV; output.Pos = mul(sceneData.matrix, mul(modelData.matrix, float4(input.Pos.xyz, 1.0))); return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return samplerColorMap.Sample(input.UV) * float4(input.Color, 1.0); } \ No newline at end of file diff --git a/shaders/slang/pushconstants/pushconstants.frag.slang b/shaders/slang/pushconstants/pushconstants.frag.slang deleted file mode 100644 index a2646791..00000000 --- a/shaders/slang/pushconstants/pushconstants.frag.slang +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright (c) 2025, Sascha Willems - * - * SPDX-License-Identifier: MIT - * - */ - -struct VSOutput -{ - float3 Color; -}; - -[shader("fragment")] -float4 main(VSOutput input) : SV_TARGET -{ - return float4(input.Color, 1.0); -} \ No newline at end of file diff --git a/shaders/slang/pushconstants/pushconstants.vert.slang b/shaders/slang/pushconstants/pushconstants.slang similarity index 78% rename from shaders/slang/pushconstants/pushconstants.vert.slang rename to shaders/slang/pushconstants/pushconstants.slang index 538ea288..9f3e4288 100644 --- a/shaders/slang/pushconstants/pushconstants.vert.slang +++ b/shaders/slang/pushconstants/pushconstants.slang @@ -27,7 +27,7 @@ struct VSOutput // Uniform entry-point parameters are automatically bound to push constants by slang [shader("vertex")] -VSOutput main(VSInput input, uniform float4 pushColor, uniform float4 pushPosition) +VSOutput vertexMain(VSInput input, uniform float4 pushColor, uniform float4 pushPosition) { VSOutput output; output.Color = input.Color * pushColor.rgb; @@ -35,4 +35,10 @@ VSOutput main(VSInput input, uniform float4 pushColor, uniform float4 pushPositi float3 worldPos = locPos + pushPosition.xyz; output.Pos = mul(ubo.projection, mul(ubo.view, float4(worldPos.xyz, 1.0))); return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) : SV_TARGET +{ + return float4(input.Color, 1.0); } \ No newline at end of file diff --git a/shaders/slang/triangle/triangle.frag.slang b/shaders/slang/triangle/triangle.frag.slang deleted file mode 100644 index 7ae7fa20..00000000 --- a/shaders/slang/triangle/triangle.frag.slang +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright (c) 2025, Sascha Willems - * - * SPDX-License-Identifier: MIT - * - */ - -[shader("fragment")] -float4 main([[vk::location(0)]] float3 Color) -{ - return float4(Color, 1.0); -} \ No newline at end of file diff --git a/shaders/slang/triangle/triangle.vert.slang b/shaders/slang/triangle/triangle.slang similarity index 81% rename from shaders/slang/triangle/triangle.vert.slang rename to shaders/slang/triangle/triangle.slang index d8305fa5..b403786f 100644 --- a/shaders/slang/triangle/triangle.vert.slang +++ b/shaders/slang/triangle/triangle.slang @@ -26,10 +26,16 @@ struct VSOutput }; [shader("vertex")] -VSOutput main(VSInput input) +VSOutput vertexMain(VSInput input) { VSOutput output; output.Color = input.Color; output.Pos = mul(ubo.projectionMatrix, mul(ubo.viewMatrix, mul(ubo.modelMatrix, float4(input.Pos.xyz, 1.0)))); return output; } + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return float4(input.Color, 1.0); +} From 9b25dbce531bf92096978402c2b804e7ecd8c7fd Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 29 Mar 2025 12:50:05 +0100 Subject: [PATCH 13/73] Cleen up shader --- shaders/slang/pushconstants/pushconstants.slang | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shaders/slang/pushconstants/pushconstants.slang b/shaders/slang/pushconstants/pushconstants.slang index 9f3e4288..45fb2960 100644 --- a/shaders/slang/pushconstants/pushconstants.slang +++ b/shaders/slang/pushconstants/pushconstants.slang @@ -7,8 +7,8 @@ struct VSInput { float3 Pos : POSITION0; - float3 Normal : NORMAL0; - float3 Color : COLOR0; + float3 Normal; + float3 Color; }; struct UBO From c1200518140338d3784fe73331a277e97bb73aff Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 29 Mar 2025 13:22:09 +0100 Subject: [PATCH 14/73] Slang shaders for descriptor indexing sample --- .../descriptorindexing.slang | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 shaders/slang/descriptorindexing/descriptorindexing.slang diff --git a/shaders/slang/descriptorindexing/descriptorindexing.slang b/shaders/slang/descriptorindexing/descriptorindexing.slang new file mode 100644 index 00000000..c647a2cd --- /dev/null +++ b/shaders/slang/descriptorindexing/descriptorindexing.slang @@ -0,0 +1,43 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos : POSITION0; + float2 UV; + int TextureIndex; +}; + +struct Matrices { + float4x4 projection; + float4x4 view; + float4x4 model; +}; +ConstantBuffer matrices; +Sampler2D textures[]; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + int TextureIndex; + float2 UV; +}; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UV = input.UV; + output.TextureIndex = input.TextureIndex; + output.Pos = mul(matrices.projection, mul(matrices.view, mul(matrices.model, float4(input.Pos.xyz, 1.0)))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) : SV_TARGET +{ + return textures[NonUniformResourceIndex(input.TextureIndex)].Sample(input.UV); +} \ No newline at end of file From 2285f6905583f0e5ec09e5395d4c716f5d71478f Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 30 Mar 2025 15:24:07 +0200 Subject: [PATCH 15/73] Add ray tracing stages --- shaders/slang/compileshaders.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/shaders/slang/compileshaders.py b/shaders/slang/compileshaders.py index 61a36529..012c810e 100644 --- a/shaders/slang/compileshaders.py +++ b/shaders/slang/compileshaders.py @@ -37,6 +37,14 @@ def getShaderStages(filename): stages.append("vertex") if '[shader("fragment")]' in filecontent: stages.append("fragment") + if '[shader("raygeneration")]' in filecontent: + stages.append("raygeneration") + if '[shader("miss")]' in filecontent: + stages.append("miss") + if '[shader("closesthit")]' in filecontent: + stages.append("closesthit") + if '[shader("callable")]' in filecontent: + stages.append("callable") f.close() return stages @@ -64,6 +72,14 @@ for root, dirs, files in os.walk(dir_path): output_ext = ".vert" case "fragment": output_ext = ".frag" + case "raygeneration": + output_ext = ".rgen" + case "miss": + output_ext = ".rmiss" + case "closesthit": + output_ext = ".rchit" + case "callable": + output_ext = ".rcall" output_file = input_file + output_ext + ".spv" output_file = output_file.replace(".slang", "") res = subprocess.call("%s %s -profile spirv_1_4 -matrix-layout-column-major -target spirv -o %s -entry %s -stage %s" % (compiler_path, input_file, output_file, entry_point, stage), shell=True) From 702066e8af705867054067e51e5700b8bbe16c20 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Wed, 23 Apr 2025 19:20:48 +0200 Subject: [PATCH 16/73] Add slang shader for compute particles sample --- shaders/slang/compileshaders.py | 10 +- shaders/slang/computeparticles/particle.slang | 120 ++++++++++++++++++ 2 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 shaders/slang/computeparticles/particle.slang diff --git a/shaders/slang/compileshaders.py b/shaders/slang/compileshaders.py index 012c810e..0008835a 100644 --- a/shaders/slang/compileshaders.py +++ b/shaders/slang/compileshaders.py @@ -45,6 +45,8 @@ def getShaderStages(filename): stages.append("closesthit") if '[shader("callable")]' in filecontent: stages.append("callable") + if '[shader("compute")]' in filecontent: + stages.append("compute") f.close() return stages @@ -52,10 +54,14 @@ compiler_path = findCompiler() print("Found slang compiler at %s", compiler_path) +compile_single_sample = "computeparticles" + dir_path = os.path.dirname(os.path.realpath(__file__)) dir_path = dir_path.replace('\\', '/') for root, dirs, files in os.walk(dir_path): for file in files: + if (compile_single_sample != "" and os.path.basename(root) != compile_single_sample): + continue if file.endswith(".slang"): input_file = os.path.join(root, file) # Slang can store multiple shader stages in a single file, we need to split into separate SPIR-V files for the sample framework @@ -80,8 +86,10 @@ for root, dirs, files in os.walk(dir_path): output_ext = ".rchit" case "callable": output_ext = ".rcall" + case "compute": + output_ext = ".comp" output_file = input_file + output_ext + ".spv" output_file = output_file.replace(".slang", "") - res = subprocess.call("%s %s -profile spirv_1_4 -matrix-layout-column-major -target spirv -o %s -entry %s -stage %s" % (compiler_path, input_file, output_file, entry_point, stage), shell=True) + res = subprocess.call("%s %s -profile spirv_1_4 -matrix-layout-column-major -target spirv -o %s -entry %s -stage %s -warnings-disable 39001" % (compiler_path, input_file, output_file, entry_point, stage), shell=True) if res != 0: sys.exit(res) \ No newline at end of file diff --git a/shaders/slang/computeparticles/particle.slang b/shaders/slang/computeparticles/particle.slang new file mode 100644 index 00000000..c5959164 --- /dev/null +++ b/shaders/slang/computeparticles/particle.slang @@ -0,0 +1,120 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +[[vk::binding(0, 0)]] Sampler2D samplerColorMap; +[[vk::binding(1, 0)]] Sampler2D samplerGradientRamp; + +struct VSInput +{ + float2 Pos : POSITION0; + float4 GradientPos : POSITION1; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float PointSize : SV_PointSize; + float4 Color : COLOR0; + float GradientPos : POSITION0; +}; + +struct Particle +{ + float2 pos; + float2 vel; + float4 gradientPos; +}; +// Binding 0 : Position storage buffer +[[vk::binding(0, 0)]] RWStructuredBuffer particles; + +struct UBO +{ + float deltaT; + float destX; + float destY; + int particleCount; +}; +[[vk::binding(1, 0)]] ConstantBuffer ubo; + +struct PushConsts +{ + float2 screendim; +}; + +float2 attraction(float2 pos, float2 attractPos) +{ + float2 delta = attractPos - pos; + const float damp = 0.5; + float dDampedDot = dot(delta, delta) + damp; + float invDist = 1.0f / sqrt(dDampedDot); + float invDistCubed = invDist*invDist*invDist; + return delta * invDistCubed * 0.0035; +} + +float2 repulsion(float2 pos, float2 attractPos) +{ + float2 delta = attractPos - pos; + float targetDistance = sqrt(dot(delta, delta)); + return delta * (1.0 / (targetDistance * targetDistance * targetDistance)) * -0.000035; +} + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.PointSize = 8.0; + output.Color = float4(0.035, 0.035, 0.035, 0.035); + output.GradientPos = input.GradientPos.x; + output.Pos = float4(input.Pos.xy, 1.0, 1.0); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input, float2 pointCoord: SV_PointCoord) : SV_TARGET +{ + float3 color = samplerGradientRamp.Sample(float2(input.GradientPos, 0.0)).rgb; + return float4(samplerColorMap.Sample(pointCoord).rgb * color, 1.0); +} + +[shader("compute")] +[numthreads(256, 1, 1)] +void computeMain(uint3 GlobalInvocationID : SV_DispatchThreadID) +{ + // Current SSBO index + uint index = GlobalInvocationID.x; + // Don't try to write beyond particle count + if (index >= ubo.particleCount) { + return; + } + + // Read position and velocity + float2 vVel = particles[index].vel.xy; + float2 vPos = particles[index].pos.xy; + + float2 destPos = float2(ubo.destX, ubo.destY); + + float2 delta = destPos - vPos; + float targetDistance = sqrt(dot(delta, delta)); + vVel += repulsion(vPos, destPos.xy) * 0.05; + + // Move by velocity + vPos += vVel * ubo.deltaT; + + // collide with boundary + if ((vPos.x < -1.0) || (vPos.x > 1.0) || (vPos.y < -1.0) || (vPos.y > 1.0)) { + vVel = (-vVel * 0.1) + attraction(vPos, destPos) * 12; + } else { + particles[index].pos.xy = vPos; + } + + // Write back + particles[index].vel.xy = vVel; + particles[index].gradientPos.x += 0.02 * ubo.deltaT; + if (particles[index].gradientPos.x > 1.0) { + particles[index].gradientPos.x -= 1.0; + } +} + From f441a3e0b38b95640ef7be415deb3ae1ab4e3474 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Wed, 23 Apr 2025 19:32:14 +0200 Subject: [PATCH 17/73] Set api base line to 1.1 when using slang and enable SPIRV 1.4 --- base/vulkanexamplebase.cpp | 9 +++++++++ shaders/README.md | 4 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/base/vulkanexamplebase.cpp b/base/vulkanexamplebase.cpp index 5ac19bb5..f5fa1c36 100644 --- a/base/vulkanexamplebase.cpp +++ b/base/vulkanexamplebase.cpp @@ -89,6 +89,15 @@ VkResult VulkanExampleBase::createInstance() } } + // Shaders generated by Slang require a certain SPIR-V environment that can't be satisfied by Vulkan 1.0, so we need to expliclity up that to at least 1.1 and enable some required extensions + if (shaderDir == "slang") { + if (apiVersion < VK_API_VERSION_1_1) { + apiVersion = VK_API_VERSION_1_1; + } + enabledDeviceExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME); + enabledDeviceExtensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME); + } + VkApplicationInfo appInfo{}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pApplicationName = name.c_str(); diff --git a/shaders/README.md b/shaders/README.md index e8b75831..4ddffc4a 100644 --- a/shaders/README.md +++ b/shaders/README.md @@ -2,4 +2,6 @@ This folder contains the shaders used by the samples. Source files are available in GLSL, HLSL and [slang](https://shader-slang.org/) and also come with precompiled SPIR-V files that are consumed by the samples. To recompile shaders you can use the `compileshaders.py` scripts in the respective folders or any other means that can generate Vulkan SPIR-V from GLSL, HLSL or slang. One such option is [this extension for Visual Studio](https://github.com/SaschaWillems/SPIRV-VSExtension). -Note that not all samples may come with all shading language variants. So some samples that have GLSL source files might not come with HLSL and/or slang source files. \ No newline at end of file +Note that not all samples may come with all shading language variants. So some samples that have GLSL source files might not come with HLSL and/or slang source files. + +A note for using **slang** shaders: These require a different SPIR-V environment than glsl/hlsl. When selecting slang shaders, the base requirement for all samples is raised to at least Vulkan 1.1 with the SPIRV 1.4 extension. \ No newline at end of file From 8b405be480664849e4717b5e757755a368e21bd0 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Thu, 24 Apr 2025 20:10:07 +0200 Subject: [PATCH 18/73] Command line argument to explicitly compile slang shaders for a single sample --- shaders/slang/compileshaders.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shaders/slang/compileshaders.py b/shaders/slang/compileshaders.py index 0008835a..2a8feb22 100644 --- a/shaders/slang/compileshaders.py +++ b/shaders/slang/compileshaders.py @@ -9,6 +9,7 @@ import sys parser = argparse.ArgumentParser(description='Compile all slang shaders') parser.add_argument('--slangc', type=str, help='path to slangc executable') +parser.add_argument('--sample', type=str, help='can be used to compile shaders for a single sample only') args = parser.parse_args() def findCompiler(): @@ -54,7 +55,9 @@ compiler_path = findCompiler() print("Found slang compiler at %s", compiler_path) -compile_single_sample = "computeparticles" +compile_single_sample = "" +if args.sample != None: + compile_single_sample = args.sample dir_path = os.path.dirname(os.path.realpath(__file__)) dir_path = dir_path.replace('\\', '/') From d718d271e2baff170bb4776f96581e783ff640b6 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Thu, 24 Apr 2025 20:26:17 +0200 Subject: [PATCH 19/73] Add slang shader for deferred rendering sample --- shaders/slang/deferred/deferred.slang | 110 ++++++++++++++++++++++++++ shaders/slang/deferred/mrt.slang | 83 +++++++++++++++++++ 2 files changed, 193 insertions(+) create mode 100644 shaders/slang/deferred/deferred.slang create mode 100644 shaders/slang/deferred/mrt.slang diff --git a/shaders/slang/deferred/deferred.slang b/shaders/slang/deferred/deferred.slang new file mode 100644 index 00000000..e02ef0d5 --- /dev/null +++ b/shaders/slang/deferred/deferred.slang @@ -0,0 +1,110 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +[[vk::binding(1, 0)]] Sampler2D samplerposition; +[[vk::binding(2, 0)]] Sampler2D samplerNormal; +[[vk::binding(3, 0)]] Sampler2D samplerAlbedo; + +struct Light { + float4 position; + float3 color; + float radius; +}; + +struct UBO +{ + Light lights[6]; + float4 viewPos; + int displayDebugTarget; +}; +[[vk::binding(4, 0)]] ConstantBuffer ubo; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + // Get G-Buffer values + float3 fragPos = samplerposition.Sample(input.UV).rgb; + float3 normal = samplerNormal.Sample(input.UV).rgb; + float4 albedo = samplerAlbedo.Sample(input.UV); + + float3 fragcolor; + + // Debug display + if (ubo.displayDebugTarget > 0) { + switch (ubo.displayDebugTarget) { + case 1: + fragcolor.rgb = fragPos; + break; + case 2: + fragcolor.rgb = normal; + break; + case 3: + fragcolor.rgb = albedo.rgb; + break; + case 4: + fragcolor.rgb = albedo.aaa; + break; + } + return float4(fragcolor, 1.0); + } + + #define lightCount 6 + #define ambient 0.0 + + // Ambient part + fragcolor = albedo.rgb * ambient; + + for(int i = 0; i < lightCount; ++i) + { + // Vector to light + float3 L = ubo.lights[i].position.xyz - fragPos; + // Distance from light to fragment position + float dist = length(L); + + // Viewer to fragment + float3 V = ubo.viewPos.xyz - fragPos; + V = normalize(V); + + //if(dist < ubo.lights[i].radius) + { + // Light to fragment + L = normalize(L); + + // Attenuation + float atten = ubo.lights[i].radius / (pow(dist, 2.0) + 1.0); + + // Diffuse part + float3 N = normalize(normal); + float NdotL = max(0.0, dot(N, L)); + float3 diff = ubo.lights[i].color * albedo.rgb * NdotL * atten; + + // Specular part + // Specular map values are stored in alpha of albedo mrt + float3 R = reflect(-L, N); + float NdotR = max(0.0, dot(R, V)); + float3 spec = ubo.lights[i].color * albedo.a * pow(NdotR, 16.0) * atten; + + fragcolor += diff + spec; + } + } + + return float4(fragcolor, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/deferred/mrt.slang b/shaders/slang/deferred/mrt.slang new file mode 100644 index 00000000..8df7a701 --- /dev/null +++ b/shaders/slang/deferred/mrt.slang @@ -0,0 +1,83 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +[[vk::binding(1, 0)]] Sampler2D samplerColor; +[[vk::binding(2, 0)]] Sampler2D samplerNormalMap; + +struct VSInput +{ + float4 Pos; + float2 UV; + float3 Color; + float3 Normal; + float3 Tangent; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; + float3 Color; + float3 WorldPos; + float3 Tangent; +}; + +struct FSOutput +{ + float4 Position; + float4 Normal; + float4 Albedo; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; + float4 instancePos[3]; +}; +[[vk::binding(0, 0)]] ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uint InstanceIndex: SV_InstanceID) +{ + VSOutput output; + float4 tmpPos = input.Pos + ubo.instancePos[InstanceIndex]; + + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, tmpPos))); + + output.UV = input.UV; + + // Vertex position in world space + output.WorldPos = mul(ubo.model, tmpPos).xyz; + + // Normal in world space + output.Normal = normalize(input.Normal); + output.Tangent = normalize(input.Tangent); + + // Currently just vertex color + output.Color = input.Color; + return output; +} + +[shader("fragment")] +FSOutput fragmentMain(VSOutput input) +{ + FSOutput output; + output.Position = float4(input.WorldPos, 1.0); + + // Calculate normal in tangent space + float3 N = normalize(input.Normal); + float3 T = normalize(input.Tangent); + float3 B = cross(N, T); + float3x3 TBN = float3x3(T, B, N); + float3 tnorm = mul(normalize(samplerNormalMap.Sample(input.UV).xyz * 2.0 - float3(1.0, 1.0, 1.0)), TBN); + output.Normal = float4(tnorm, 1.0); + + output.Albedo = samplerColor.Sample(input.UV); + return output; +} \ No newline at end of file From b8b4c89e04a89b5f501449e8d1a515f368666c01 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 26 Apr 2025 14:50:10 +0200 Subject: [PATCH 20/73] Add slang shader for gltf sample --- shaders/slang/gltfloading/mesh.slang | 64 ++++++++++++++ shaders/slang/gltfscenerendering/scene.slang | 90 ++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 shaders/slang/gltfloading/mesh.slang create mode 100644 shaders/slang/gltfscenerendering/scene.slang diff --git a/shaders/slang/gltfloading/mesh.slang b/shaders/slang/gltfloading/mesh.slang new file mode 100644 index 00000000..7205d38f --- /dev/null +++ b/shaders/slang/gltfloading/mesh.slang @@ -0,0 +1,64 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float2 UV; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4 lightPos; + float4 viewPos; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform float4x4 modelMat) +{ + VSOutput output; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(modelMat, float4(input.Pos.xyz, 1.0)))); + + float4 pos = mul(ubo.view, mul(modelMat, float4(input.Pos.xyz, 1.0))); + output.Normal = mul((float3x3)ubo.view, input.Normal); + output.LightVec = ubo.lightPos.xyz - pos.xyz; + output.ViewVec = ubo.viewPos.xyz - pos.xyz; + return output; +} + +[[vk::binding(0, 1)]] Sampler2D samplerColorMap; + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float4 color = samplerColorMap.Sample(input.UV) * float4(input.Color, 1.0); + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(L, N); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + return float4(diffuse * color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/gltfscenerendering/scene.slang b/shaders/slang/gltfscenerendering/scene.slang new file mode 100644 index 00000000..776d37ef --- /dev/null +++ b/shaders/slang/gltfscenerendering/scene.slang @@ -0,0 +1,90 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; + float3 Color; + float4 Tangent; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float2 UV; + float3 ViewVec; + float3 LightVec; + float4 Tangent; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4 lightPos; + float4 viewPos; +}; +ConstantBuffer ubo; + +struct PushConsts { + float4x4 model; +}; + +[[vk::binding(0, 1)]] Sampler2D samplerColorMap; +[[vk::binding(1, 1)]] Sampler2D samplerNormalMap; + +[SpecializationConstant] const bool ALPHA_MASK = false; +[SpecializationConstant] const float ALPHA_MASK_CUTOFF = 0.0; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform float4x4 modelMat) +{ + VSOutput output; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Tangent = input.Tangent; + + float4x4 modelView = mul(ubo.view, modelMat); + + output.Pos = mul(ubo.projection, mul(modelView, float4(input.Pos.xyz, 1.0))); + + output.Normal = mul((float3x3)modelMat, input.Normal); + float4 pos = mul(modelMat, float4(input.Pos, 1.0)); + output.LightVec = ubo.lightPos.xyz - pos.xyz; + output.ViewVec = ubo.viewPos.xyz - pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float4 color = samplerColorMap.Sample(input.UV) * float4(input.Color, 1.0); + + if (ALPHA_MASK) { + if (color.a < ALPHA_MASK_CUTOFF) { + discard; + } + } + + float3 N = normalize(input.Normal); + float3 T = normalize(input.Tangent.xyz); + float3 B = cross(input.Normal, input.Tangent.xyz) * input.Tangent.w; + float3x3 TBN = float3x3(T, B, N); + N = mul(normalize(samplerNormalMap.Sample(input.UV).xyz * 2.0 - float3(1.0, 1.0, 1.0)), TBN); + + const float ambient = 0.1; + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), ambient).rrr; + float3 specular = pow(max(dot(R, V), 0.0), 32.0); + return float4(diffuse * color.rgb + specular, color.a); +} \ No newline at end of file From 74e66c6b485c02f2e5280407c1d981a621b8c395 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 26 Apr 2025 17:07:33 +0200 Subject: [PATCH 21/73] Add slang shader for gltf skinning sample --- shaders/slang/gltfskinning/skinnedmodel.slang | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 shaders/slang/gltfskinning/skinnedmodel.slang diff --git a/shaders/slang/gltfskinning/skinnedmodel.slang b/shaders/slang/gltfskinning/skinnedmodel.slang new file mode 100644 index 00000000..2d98836d --- /dev/null +++ b/shaders/slang/gltfskinning/skinnedmodel.slang @@ -0,0 +1,78 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; + float3 Color; + float4 JointIndices; + float4 JointWeights; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float2 UV; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4 lightPos; + float4x4 inverse; +}; +ConstantBuffer uboScene; + +[[vk::binding(0, 1)]] StructuredBuffer jointMatrices; + +[[vk::binding(0, 2)]] Sampler2D samplerColorMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform float4x4 modelMat) +{ + VSOutput output; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + + // Calculate skinned matrix from weights and joint indices of the current vertex + float4x4 skinMat = + input.JointWeights.x * jointMatrices[int(input.JointIndices.x)] + + input.JointWeights.y * jointMatrices[int(input.JointIndices.y)] + + input.JointWeights.z * jointMatrices[int(input.JointIndices.z)] + + input.JointWeights.w * jointMatrices[int(input.JointIndices.w)]; + + output.Pos = mul(uboScene.projection, mul(uboScene.view, mul(modelMat, mul(skinMat, float4(input.Pos, 1.0))))); + output.Normal = mul((float3x3)modelMat, mul((float3x3)skinMat, input.Normal)); + + float4 pos = mul(uboScene.view, float4(input.Pos, 1.0)); + float3 lPos = mul(float3x3(uboScene.view), uboScene.lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float4 color = samplerColorMap.Sample(input.UV) * float4(input.Color, 1.0); + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(L, N); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + return float4(diffuse * color.rgb + specular, 1.0); +} \ No newline at end of file From b6b4fccb2ca207f31e45a08c80f9293bc09f9939 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 26 Apr 2025 21:02:45 +0200 Subject: [PATCH 22/73] Add slang shader for instancing sample --- shaders/slang/instancing/instancing.slang | 106 ++++++++++++++++++++++ shaders/slang/instancing/planet.slang | 62 +++++++++++++ shaders/slang/instancing/starfield.slang | 50 ++++++++++ 3 files changed, 218 insertions(+) create mode 100644 shaders/slang/instancing/instancing.slang create mode 100644 shaders/slang/instancing/planet.slang create mode 100644 shaders/slang/instancing/starfield.slang diff --git a/shaders/slang/instancing/instancing.slang b/shaders/slang/instancing/instancing.slang new file mode 100644 index 00000000..8541d187 --- /dev/null +++ b/shaders/slang/instancing/instancing.slang @@ -0,0 +1,106 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos : POSITION0; + float3 Normal : NORMAL0; + float2 UV : TEXCOORD0; + float3 Color : COLOR0; + // Instanced attributes + float3 instancePos : POSITION1; + float3 instanceRot : TEXCOORD1; + float instanceScale : TEXCOORD2; + int instanceTexIndex : TEXCOORD3; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 UV; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 lightPos; + float locSpeed; + float globSpeed; +}; +ConstantBuffer ubo; +Sampler2DArray samplerArray; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.UV = float3(input.UV, input.instanceTexIndex); + + // rotate around x + float s = sin(input.instanceRot.x + ubo.locSpeed); + float c = cos(input.instanceRot.x + ubo.locSpeed); + + float3x3 mx = { c, -s, 0.0, + s, c, 0.0, + 0.0, 0.0, 1.0 }; + + // rotate around y + s = sin(input.instanceRot.y + ubo.locSpeed); + c = cos(input.instanceRot.y + ubo.locSpeed); + + float3x3 my = { c, 0.0, -s, + 0.0, 1.0, 0.0, + s, 0.0, c }; + + // rot around z + s = sin(input.instanceRot.z + ubo.locSpeed); + c = cos(input.instanceRot.z + ubo.locSpeed); + + float3x3 mz = { 1.0, 0.0, 0.0, + 0.0, c, -s, + 0.0, s, c }; + + float3x3 rotMat = mul(mz, mul(my, mx)); + + float4x4 gRotMat; + s = sin(input.instanceRot.y + ubo.globSpeed); + c = cos(input.instanceRot.y + ubo.globSpeed); + gRotMat[0] = float4(c, 0.0, -s, 0.0); + gRotMat[1] = float4(0.0, 1.0, 0.0, 0.0); + gRotMat[2] = float4(s, 0.0, c, 0.0); + gRotMat[3] = float4(0.0, 0.0, 0.0, 1.0); + + float4 locPos = float4(mul(rotMat, input.Pos.xyz), 1.0); + float4 pos = float4((locPos.xyz * input.instanceScale) + input.instancePos, 1.0); + + output.Pos = mul(ubo.projection, mul(ubo.modelview, mul(gRotMat, pos))); + output.Normal = mul((float3x3)mul(ubo.modelview, gRotMat), mul(rotMat, input.Normal)); + + pos = mul(ubo.modelview, float4(input.Pos.xyz + input.instancePos, 1.0)); + float3 lPos = mul((float3x3)ubo.modelview, ubo.lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float4 color = samplerArray.Sample(input.UV) * float4(input.Color, 1.0); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.1) * input.Color; + float3 specular = (dot(N,L) > 0.0) ? pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75) * color.r : float3(0.0, 0.0, 0.0); + return float4(diffuse * color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/instancing/planet.slang b/shaders/slang/instancing/planet.slang new file mode 100644 index 00000000..ca8bb346 --- /dev/null +++ b/shaders/slang/instancing/planet.slang @@ -0,0 +1,62 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float2 UV; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 lightPos; +}; +ConstantBuffer ubo; + +Sampler2D samplerColorMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.modelview, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.modelview, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.modelview, input.Normal); + float3 lPos = mul((float3x3)ubo.modelview, ubo.lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float4 color = samplerColorMap.Sample(input.UV) * float4(input.Color, 1.0) * 1.5; + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 4.0) * float3(0.5, 0.5, 0.5) * color.r; + return float4(diffuse * color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/instancing/starfield.slang b/shaders/slang/instancing/starfield.slang new file mode 100644 index 00000000..2a5fbab5 --- /dev/null +++ b/shaders/slang/instancing/starfield.slang @@ -0,0 +1,50 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +#define HASHSCALE3 float3(443.897, 441.423, 437.195) +#define STARFREQUENCY 0.01 + +// Hash function by Dave Hoskins (https://www.shadertoy.com/view/4djSRW) +float hash33(float3 p3) +{ + p3 = frac(p3 * HASHSCALE3); + p3 += dot(p3, p3.yxz+float3(19.19, 19.19, 19.19)); + return frac((p3.x + p3.y)*p3.z + (p3.x+p3.z)*p3.y + (p3.y+p3.z)*p3.x); +} + +float3 starField(float3 pos) +{ + float3 color = float3(0.0, 0.0, 0.0); + float threshhold = (1.0 - STARFREQUENCY); + float rnd = hash33(pos); + if (rnd >= threshhold) + { + float starCol = pow((rnd - threshhold) / (1.0 - threshhold), 16.0); + color += starCol.xxx; + } + return color; +} + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 UVW; +}; + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UVW = float3((VertexIndex << 1) & 2, VertexIndex & 2, VertexIndex & 2); + output.Pos = float4(output.UVW.xy * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return float4(starField(input.UVW), 1.0); +} \ No newline at end of file From 5484d51bae8ade504e3aa809970ae6b96a2c7d06 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 27 Apr 2025 11:07:30 +0200 Subject: [PATCH 23/73] Add slang shader for texturing samples --- shaders/slang/texture/texture.slang | 68 ++++++++++++++++++ shaders/slang/texture3d/texture3d.slang | 66 +++++++++++++++++ shaders/slang/texturearray/instancing.slang | 49 +++++++++++++ shaders/slang/texturecubemap/reflect.slang | 70 +++++++++++++++++++ shaders/slang/texturecubemap/skybox.slang | 47 +++++++++++++ .../slang/texturecubemaparray/reflect.slang | 68 ++++++++++++++++++ .../slang/texturecubemaparray/skybox.slang | 49 +++++++++++++ shaders/slang/texturemipmapgen/texture.slang | 68 ++++++++++++++++++ 8 files changed, 485 insertions(+) create mode 100644 shaders/slang/texture/texture.slang create mode 100644 shaders/slang/texture3d/texture3d.slang create mode 100644 shaders/slang/texturearray/instancing.slang create mode 100644 shaders/slang/texturecubemap/reflect.slang create mode 100644 shaders/slang/texturecubemap/skybox.slang create mode 100644 shaders/slang/texturecubemaparray/reflect.slang create mode 100644 shaders/slang/texturecubemaparray/skybox.slang create mode 100644 shaders/slang/texturemipmapgen/texture.slang diff --git a/shaders/slang/texture/texture.slang b/shaders/slang/texture/texture.slang new file mode 100644 index 00000000..8c104e10 --- /dev/null +++ b/shaders/slang/texture/texture.slang @@ -0,0 +1,68 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float2 UV; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; + float LodBias; + float3 Normal; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 viewPos; + float lodBias; +}; +ConstantBuffer ubo; + +Sampler2D samplerColor; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UV = input.UV; + output.LodBias = ubo.lodBias; + + float3 worldPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + float3 lightPos = float3(0.0, 0.0, 0.0); + float3 lPos = mul((float3x3)ubo.model, lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = ubo.viewPos.xyz - pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float4 color = samplerColor.SampleLevel(input.UV, input.LodBias); + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float specular = pow(max(dot(R, V), 0.0), 16.0) * color.a; + + return float4(diffuse * color.rgb + specular, 1.0); +} diff --git a/shaders/slang/texture3d/texture3d.slang b/shaders/slang/texture3d/texture3d.slang new file mode 100644 index 00000000..c11208b9 --- /dev/null +++ b/shaders/slang/texture3d/texture3d.slang @@ -0,0 +1,66 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float2 UV; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 UV; + float3 Normal; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 viewPos; + float depth; +}; +ConstantBuffer ubo; + +Sampler3D samplerColor; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UV = float3(input.UV, ubo.depth); + + float3 worldPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + float3 lightPos = float3(0.0, 0.0, 0.0); + float3 lPos = mul((float3x3)ubo.model, lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = ubo.viewPos.xyz - pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float4 color = samplerColor.Sample(input.UV); + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float specular = pow(max(dot(R, V), 0.0), 16.0) * color.r; + + return float4(diffuse * color.r + specular, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/texturearray/instancing.slang b/shaders/slang/texturearray/instancing.slang new file mode 100644 index 00000000..6db77ac9 --- /dev/null +++ b/shaders/slang/texturearray/instancing.slang @@ -0,0 +1,49 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 UV; +}; + +struct Instance +{ + float4x4 model; + float arrayIndex; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + Instance instance[8]; +}; +ConstantBuffer ubo; + +Sampler2DArray samplerArray; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uint InstanceIndex: SV_InstanceID) +{ + VSOutput output; + output.UV = float3(input.UV, ubo.instance[InstanceIndex].arrayIndex); + float4x4 modelView = mul(ubo.view, ubo.instance[InstanceIndex].model); + output.Pos = mul(ubo.projection, mul(modelView, float4(input.Pos, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return samplerArray.Sample(input.UV); +} \ No newline at end of file diff --git a/shaders/slang/texturecubemap/reflect.slang b/shaders/slang/texturecubemap/reflect.slang new file mode 100644 index 00000000..ffeda065 --- /dev/null +++ b/shaders/slang/texturecubemap/reflect.slang @@ -0,0 +1,70 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 WorldPos; + float3 Normal; + float LodBias; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 invModel; + float lodBias; +}; +ConstantBuffer ubo; + +SamplerCube samplerColor; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + output.WorldPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + output.Normal = mul((float3x3)ubo.model, input.Normal); + output.LodBias = ubo.lodBias; + + float3 lightPos = float3(0.0f, -5.0f, 5.0f); + output.LightVec = lightPos.xyz - output.WorldPos.xyz; + output.ViewVec = -output.WorldPos; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) : SV_TARGET +{ + float3 cI = normalize (input.ViewVec); + float3 cR = reflect (cI, normalize(input.Normal)); + + cR = mul(ubo.invModel, float4(cR, 0.0)).xyz; + // Convert cubemap coordinates into Vulkan coordinate space + cR.z *= -1.0; + + float4 color = samplerColor.SampleLevel(cR, input.LodBias); + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 ambient = float3(0.5, 0.5, 0.5) * color.rgb; + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.5, 0.5, 0.5); + return float4(ambient + diffuse * color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/texturecubemap/skybox.slang b/shaders/slang/texturecubemap/skybox.slang new file mode 100644 index 00000000..618fb2f3 --- /dev/null +++ b/shaders/slang/texturecubemap/skybox.slang @@ -0,0 +1,47 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 UVW; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; +ConstantBuffer ubo; + +SamplerCube samplerCubeMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UVW = input.Pos; + // Convert cubemap coordinates into Vulkan coordinate space + output.UVW.xy *= -1.0; + // Remove translation from view matrix + float4x4 viewMat = ubo.model; + viewMat[0][3] = 0.0; + viewMat[1][3] = 0.0; + viewMat[2][3] = 0.0; + output.Pos = mul(ubo.projection, mul(viewMat, float4(input.Pos.xyz, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return samplerCubeMap.Sample(input.UVW); +} \ No newline at end of file diff --git a/shaders/slang/texturecubemaparray/reflect.slang b/shaders/slang/texturecubemaparray/reflect.slang new file mode 100644 index 00000000..1edb34b3 --- /dev/null +++ b/shaders/slang/texturecubemaparray/reflect.slang @@ -0,0 +1,68 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 WorldPos; + float3 Normal; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 invModel; + float lodBias; + int cubeMapIndex; +}; +ConstantBuffer ubo; + +SamplerCubeArray samplerCubeMapArray; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + output.WorldPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + output.Normal = mul((float3x3)ubo.model, input.Normal); + + float3 lightPos = float3(0.0f, -5.0f, 5.0f); + output.LightVec = lightPos.xyz - output.WorldPos.xyz; + output.ViewVec = -output.WorldPos; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 cI = normalize(input.WorldPos.xyz); + float3 cR = reflect(cI, normalize(input.Normal)); + + cR = mul(ubo.invModel, float4(cR, 0.0)).xyz; + cR.yz *= -1.0; + + float4 color = samplerCubeMapArray.SampleLevel(float4(cR, ubo.cubeMapIndex), ubo.lodBias); + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 ambient = float3(0.5, 0.5, 0.5) * color.rgb; + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.5, 0.5, 0.5); + return float4(ambient + diffuse * color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/texturecubemaparray/skybox.slang b/shaders/slang/texturecubemaparray/skybox.slang new file mode 100644 index 00000000..f7686993 --- /dev/null +++ b/shaders/slang/texturecubemaparray/skybox.slang @@ -0,0 +1,49 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 UVW; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 invModel; + float lodBias; + int cubeMapIndex; +}; +ConstantBuffer ubo; + +SamplerCubeArray samplerCubeMapArray; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UVW = input.Pos; + output.UVW.xy *= -1.0; + // Remove translation from view matrix + float4x4 viewMat = ubo.model; + viewMat[0][3] = 0.0; + viewMat[1][3] = 0.0; + viewMat[2][3] = 0.0; + output.Pos = mul(ubo.projection, mul(viewMat, float4(input.Pos.xyz, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return samplerCubeMapArray.SampleLevel(float4(input.UVW, ubo.cubeMapIndex), ubo.lodBias); +} \ No newline at end of file diff --git a/shaders/slang/texturemipmapgen/texture.slang b/shaders/slang/texturemipmapgen/texture.slang new file mode 100644 index 00000000..41aaca50 --- /dev/null +++ b/shaders/slang/texturemipmapgen/texture.slang @@ -0,0 +1,68 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float2 UV; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; + float LodBias; + float3 Normal; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float4 viewPos; + float lodBias; + int samplerIndex; +}; +ConstantBuffer ubo; + +Texture2D textureColor; +SamplerState samplers[3]; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UV = input.UV * float2(2.0, 1.0); + output.LodBias = ubo.lodBias; + + float3 worldPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos.xyz, 1.0)))); + + output.Normal = mul((float3x3)ubo.model, input.Normal); + float3 lightPos = float3(-30.0, 0.0, 0.0); + output.LightVec = worldPos - lightPos; + output.ViewVec = ubo.viewPos.xyz - worldPos; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float4 color = textureColor.Sample(samplers[ubo.samplerIndex], input.UV, int2(0, 0), input.LodBias); + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(L, N); + float3 diffuse = max(dot(N, L), 0.65) * float3(1.0, 1.0, 1.0); + float specular = pow(max(dot(R, V), 0.0), 16.0) * color.a; + return float4(diffuse * color.r + specular, 1.0); +} \ No newline at end of file From 33cab712ca27c06796cbcc2cb3133b1e597a37e7 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 27 Apr 2025 12:41:07 +0200 Subject: [PATCH 24/73] Add slang shader for mesh shader sample --- shaders/slang/compileshaders.py | 11 ++++ shaders/slang/meshshader/meshshader.slang | 71 +++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 shaders/slang/meshshader/meshshader.slang diff --git a/shaders/slang/compileshaders.py b/shaders/slang/compileshaders.py index 2a8feb22..bbd73705 100644 --- a/shaders/slang/compileshaders.py +++ b/shaders/slang/compileshaders.py @@ -48,6 +48,10 @@ def getShaderStages(filename): stages.append("callable") if '[shader("compute")]' in filecontent: stages.append("compute") + if '[shader("amplification")]' in filecontent: + stages.append("amplification") + if '[shader("mesh")]' in filecontent: + stages.append("mesh") f.close() return stages @@ -58,6 +62,9 @@ print("Found slang compiler at %s", compiler_path) compile_single_sample = "" if args.sample != None: compile_single_sample = args.sample + if (not os.path.isdir(compile_single_sample)): + print("ERROR: No directory found with name %s" % compile_single_sample) + exit(-1) dir_path = os.path.dirname(os.path.realpath(__file__)) dir_path = dir_path.replace('\\', '/') @@ -91,6 +98,10 @@ for root, dirs, files in os.walk(dir_path): output_ext = ".rcall" case "compute": output_ext = ".comp" + case "mesh": + output_ext = ".mesh" + case "amplification": + output_ext = ".task" output_file = input_file + output_ext + ".spv" output_file = output_file.replace(".slang", "") res = subprocess.call("%s %s -profile spirv_1_4 -matrix-layout-column-major -target spirv -o %s -entry %s -stage %s -warnings-disable 39001" % (compiler_path, input_file, output_file, entry_point, stage), shell=True) diff --git a/shaders/slang/meshshader/meshshader.slang b/shaders/slang/meshshader/meshshader.slang new file mode 100644 index 00000000..652b3411 --- /dev/null +++ b/shaders/slang/meshshader/meshshader.slang @@ -0,0 +1,71 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VertexOutput +{ + float4 position : SV_Position; + float4 color; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; +}; +ConstantBuffer ubo; + +static const float4 positions[3] = { + float4( 0.0, -1.0, 0.0, 1.0), + float4(-1.0, 1.0, 0.0, 1.0), + float4( 1.0, 1.0, 0.0, 1.0) +}; + +static const float4 colors[3] = { + float4(0.0, 1.0, 0.0, 1.0), + float4(0.0, 0.0, 1.0, 1.0), + float4(1.0, 0.0, 0.0, 1.0) +}; + +struct DummyPayLoad +{ + uint dummyData; +}; + +// We don't use pay loads in this sample, but the fn call requires one +groupshared DummyPayLoad dummyPayLoad; + +[shader("amplification")] +[numthreads(1, 1, 1)] +void amplificationMain() +{ + DispatchMesh(3, 1, 1, dummyPayLoad); +} + +[shader("mesh")] +[outputtopology("triangle")] +[numthreads(1, 1, 1)] +void meshMain(out indices uint3 triangles[1], out vertices VertexOutput vertices[3], uint3 DispatchThreadID : SV_DispatchThreadID) +{ + float4x4 mvp = mul(ubo.projection, mul(ubo.view, ubo.model)); + + float4 offset = float4(0.0, 0.0, float(DispatchThreadID.x), 0.0); + + SetMeshOutputCounts(3, 1); + for (uint i = 0; i < 3; i++) { + vertices[i].position = mul(mvp, positions[i] + offset); + vertices[i].color = colors[i]; + } + + SetMeshOutputCounts(3, 1); + triangles[0] = uint3(0, 1, 2); +} + +[shader("fragment")] +float4 fragmentMain(VertexOutput input) +{ + return input.color; +} From a4354cdb2e627fb286c1e69baf2feecdd298351e Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 27 Apr 2025 17:40:20 +0200 Subject: [PATCH 25/73] Add slang shader for ray tracing basic sample --- .gitignore | 4 +- shaders/slang/_rename.py | 17 ++++++ shaders/slang/compileshaders.py | 10 +++- .../raytracingbasic/raytracingbasic.slang | 60 +++++++++++++++++++ 4 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 shaders/slang/_rename.py create mode 100644 shaders/slang/raytracingbasic/raytracingbasic.slang diff --git a/.gitignore b/.gitignore index c4ab876b..8c318e38 100644 --- a/.gitignore +++ b/.gitignore @@ -240,4 +240,6 @@ android/.idea/** libs/vulkan/*.so -.vscode/* \ No newline at end of file +.vscode/* + +__pycache__** \ No newline at end of file diff --git a/shaders/slang/_rename.py b/shaders/slang/_rename.py new file mode 100644 index 00000000..fe16d519 --- /dev/null +++ b/shaders/slang/_rename.py @@ -0,0 +1,17 @@ +# Copyright (C) 2025 by Sascha Willems - www.saschawillems.de +# This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +from shutil import move + +# To match required file names to fother shading languages that don't support multiple entry points, shader files may need to be renamed for some samples +def checkRenameFiles(samplename): + mappings = {} + match samplename: + case "raytracingbasic": + mappings = { + "raytracingbasic.rchit.spv": "closesthit.rchit.spv", + "raytracingbasic.rmiss.spv": "miss.rmiss.spv", + "raytracingbasic.rgen.spv": "raygen.rgen.spv", + } + for x, y in mappings.items(): + move(samplename + "\\" + x, samplename + "\\" + y) diff --git a/shaders/slang/compileshaders.py b/shaders/slang/compileshaders.py index bbd73705..104ca2ff 100644 --- a/shaders/slang/compileshaders.py +++ b/shaders/slang/compileshaders.py @@ -6,6 +6,7 @@ import fileinput import os import subprocess import sys +from _rename import * parser = argparse.ArgumentParser(description='Compile all slang shaders') parser.add_argument('--slangc', type=str, help='path to slangc executable') @@ -70,13 +71,15 @@ dir_path = os.path.dirname(os.path.realpath(__file__)) dir_path = dir_path.replace('\\', '/') for root, dirs, files in os.walk(dir_path): for file in files: - if (compile_single_sample != "" and os.path.basename(root) != compile_single_sample): + folder_name = os.path.basename(root) + if (compile_single_sample != "" and folder_name != compile_single_sample): continue if file.endswith(".slang"): input_file = os.path.join(root, file) # Slang can store multiple shader stages in a single file, we need to split into separate SPIR-V files for the sample framework stages = getShaderStages(input_file) print("Compiling %s" % input_file) + output_base_file_name = input_file for stage in stages: if (len(stages) > 1): entry_point = stage + "Main" @@ -102,8 +105,9 @@ for root, dirs, files in os.walk(dir_path): output_ext = ".mesh" case "amplification": output_ext = ".task" - output_file = input_file + output_ext + ".spv" + output_file = output_base_file_name + output_ext + ".spv" output_file = output_file.replace(".slang", "") res = subprocess.call("%s %s -profile spirv_1_4 -matrix-layout-column-major -target spirv -o %s -entry %s -stage %s -warnings-disable 39001" % (compiler_path, input_file, output_file, entry_point, stage), shell=True) if res != 0: - sys.exit(res) \ No newline at end of file + sys.exit(res) + checkRenameFiles(folder_name) \ No newline at end of file diff --git a/shaders/slang/raytracingbasic/raytracingbasic.slang b/shaders/slang/raytracingbasic/raytracingbasic.slang new file mode 100644 index 00000000..49d8182d --- /dev/null +++ b/shaders/slang/raytracingbasic/raytracingbasic.slang @@ -0,0 +1,60 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +RaytracingAccelerationStructure accelStruct; +RWTexture2D image; +struct CameraProperties +{ + float4x4 viewInverse; + float4x4 projInverse; +}; +ConstantBuffer cam; + +struct Attributes +{ + float2 bary; +}; + +struct Payload +{ + float3 hitValue; +}; + +[shader("raygeneration")] +void raygenerationMain() +{ + uint3 LaunchID = DispatchRaysIndex(); + uint3 LaunchSize = DispatchRaysDimensions(); + + const float2 pixelCenter = float2(LaunchID.xy) + float2(0.5, 0.5); + const float2 inUV = pixelCenter/float2(LaunchSize.xy); + float2 d = inUV * 2.0 - 1.0; + float4 target = mul(cam.projInverse, float4(d.x, d.y, 1, 1)); + + RayDesc rayDesc; + rayDesc.Origin = mul(cam.viewInverse, float4(0,0,0,1)).xyz; + rayDesc.Direction = mul(cam.viewInverse, float4(normalize(target.xyz), 0)).xyz; + rayDesc.TMin = 0.001; + rayDesc.TMax = 10000.0; + + Payload payload; + TraceRay(accelStruct, RAY_FLAG_FORCE_OPAQUE, 0xff, 0, 0, 0, rayDesc, payload); + + image[int2(LaunchID.xy)] = float4(payload.hitValue, 0.0); +} + +[shader("closesthit")] +void closesthitMain(inout Payload p, in Attributes attribs) +{ + const float3 barycentricCoords = float3(1.0f - attribs.bary.x - attribs.bary.y, attribs.bary.x, attribs.bary.y); + p.hitValue = barycentricCoords; +} + +[shader("miss")] +void missMain(inout Payload p) +{ + p.hitValue = float3(0.0, 0.0, 0.2); +} From 126231756a0003dd1102034b6f72e47540edcd9f Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 27 Apr 2025 20:37:42 +0200 Subject: [PATCH 26/73] Add slang shader for ray tracing reflection sample --- shaders/slang/_rename.py | 6 + shaders/slang/compileshaders.py | 6 +- .../raytracingreflections.slang | 144 ++++++++++++++++++ 3 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 shaders/slang/raytracingreflections/raytracingreflections.slang diff --git a/shaders/slang/_rename.py b/shaders/slang/_rename.py index fe16d519..5b6e61d1 100644 --- a/shaders/slang/_rename.py +++ b/shaders/slang/_rename.py @@ -13,5 +13,11 @@ def checkRenameFiles(samplename): "raytracingbasic.rmiss.spv": "miss.rmiss.spv", "raytracingbasic.rgen.spv": "raygen.rgen.spv", } + case "raytracingreflections": + mappings = { + "raytracingreflections.rchit.spv": "closesthit.rchit.spv", + "raytracingreflections.rmiss.spv": "miss.rmiss.spv", + "raytracingreflections.rgen.spv": "raygen.rgen.spv", + } for x, y in mappings.items(): move(samplename + "\\" + x, samplename + "\\" + y) diff --git a/shaders/slang/compileshaders.py b/shaders/slang/compileshaders.py index 104ca2ff..9582c1a9 100644 --- a/shaders/slang/compileshaders.py +++ b/shaders/slang/compileshaders.py @@ -70,10 +70,10 @@ if args.sample != None: dir_path = os.path.dirname(os.path.realpath(__file__)) dir_path = dir_path.replace('\\', '/') for root, dirs, files in os.walk(dir_path): + folder_name = os.path.basename(root) + if (compile_single_sample != "" and folder_name != compile_single_sample): + continue for file in files: - folder_name = os.path.basename(root) - if (compile_single_sample != "" and folder_name != compile_single_sample): - continue if file.endswith(".slang"): input_file = os.path.join(root, file) # Slang can store multiple shader stages in a single file, we need to split into separate SPIR-V files for the sample framework diff --git a/shaders/slang/raytracingreflections/raytracingreflections.slang b/shaders/slang/raytracingreflections/raytracingreflections.slang new file mode 100644 index 00000000..2e9260a9 --- /dev/null +++ b/shaders/slang/raytracingreflections/raytracingreflections.slang @@ -0,0 +1,144 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +RaytracingAccelerationStructure accelStruct; +RWTexture2D image; +struct CameraProperties +{ + float4x4 viewInverse; + float4x4 projInverse; + float4 lightPos; + int vertexSize; +}; +ConstantBuffer ubo; +StructuredBuffer vertices; +StructuredBuffer indices; + +// Max. number of recursion is passed via a specialization constant +[SpecializationConstant] const int MAX_RECURSION = 0; + +struct Attributes +{ + float2 bary; +}; + +struct RayPayload +{ + float3 color; + float distance; + float3 normal; + float reflector; +}; + +struct Vertex +{ + float3 pos; + float3 normal; + float2 uv; + float4 color; + float4 _pad0; + float4 _pad1; +}; + +Vertex unpack(uint index) +{ + // Unpack the vertices from the SSBO using the glTF vertex structure + // The multiplier is the size of the vertex divided by four float components (=16 bytes) + const int m = ubo.vertexSize / 16; + + float4 d0 = vertices[m * index + 0]; + float4 d1 = vertices[m * index + 1]; + float4 d2 = vertices[m * index + 2]; + + Vertex v; + v.pos = d0.xyz; + v.normal = float3(d0.w, d1.x, d1.y); + v.color = float4(d2.x, d2.y, d2.z, 1.0); + + return v; +} + +[shader("raygeneration")] +void raygenerationMain() +{ + uint3 LaunchID = DispatchRaysIndex(); + uint3 LaunchSize = DispatchRaysDimensions(); + + const float2 pixelCenter = float2(LaunchID.xy) + float2(0.5, 0.5); + const float2 inUV = pixelCenter / float2(LaunchSize.xy); + float2 d = inUV * 2.0 - 1.0; + float4 target = mul(ubo.projInverse, float4(d.x, d.y, 1, 1)); + + RayDesc rayDesc; + rayDesc.Origin = mul(ubo.viewInverse, float4(0, 0, 0, 1)).xyz; + rayDesc.Direction = mul(ubo.viewInverse, float4(normalize(target.xyz), 0)).xyz; + rayDesc.TMin = 0.001; + rayDesc.TMax = 10000.0; + + float3 color = float3(0.0, 0.0, 0.0); + + for (int i = 0; i < MAX_RECURSION; i++) { + RayPayload rayPayload; + TraceRay(accelStruct, RAY_FLAG_FORCE_OPAQUE, 0xff, 0, 0, 0, rayDesc, rayPayload); + float3 hitColor = rayPayload.color; + + if (rayPayload.distance < 0.0f) { + color += hitColor; + break; + } else if (rayPayload.reflector == 1.0f) { + const float3 hitPos = rayDesc.Origin + rayDesc.Direction * rayPayload.distance; + rayDesc.Origin = hitPos + rayPayload.normal * 0.001f; + rayDesc.Direction = reflect(rayDesc.Direction, rayPayload.normal); + } else { + color += hitColor; + break; + } + } + + image[int2(LaunchID.xy)] = float4(color, 0.0); +} + +[shader("closesthit")] +void closesthitMain(inout RayPayload rayPayload, in Attributes attribs) +{ + uint PrimitiveID = PrimitiveIndex(); + int3 index = int3(indices[3 * PrimitiveID], indices[3 * PrimitiveID + 1], indices[3 * PrimitiveID + 2]); + + Vertex v0 = unpack(index.x); + Vertex v1 = unpack(index.y); + Vertex v2 = unpack(index.z); + + // Interpolate normal + const float3 barycentricCoords = float3(1.0f - attribs.bary.x - attribs.bary.y, attribs.bary.x, attribs.bary.y); + float3 normal = normalize(v0.normal * barycentricCoords.x + v1.normal * barycentricCoords.y + v2.normal * barycentricCoords.z); + + // Basic lighting + float3 lightVector = normalize(ubo.lightPos.xyz); + float dot_product = max(dot(lightVector, normal), 0.6); + rayPayload.color.rgb = v0.color.rgb * dot_product; + rayPayload.distance = RayTCurrent(); + rayPayload.normal = normal; + + // Objects with full white vertex color are treated as reflectors + rayPayload.reflector = ((v0.color.r == 1.0f) && (v0.color.g == 1.0f) && (v0.color.b == 1.0f)) ? 1.0f : 0.0f; +} + +[shader("miss")] +void missMain(inout RayPayload rayPayload) +{ + float3 worldRayDirection = WorldRayDirection(); + + // View-independent background gradient to simulate a basic sky background + const float3 gradientStart = float3(0.5, 0.6, 1.0); + const float3 gradientEnd = float3(1.0, 1.0, 1.0); + float3 unitDir = normalize(worldRayDirection); + float t = 0.5 * (unitDir.y + 1.0); + rayPayload.color = (1.0 - t) * gradientStart + t * gradientEnd; + + rayPayload.distance = -1.0f; + rayPayload.normal = float3(0, 0, 0); + rayPayload.reflector = 0.0f; +} \ No newline at end of file From 153aa3b932a76b532caec3581dbd68740e6c9a24 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Mon, 28 Apr 2025 21:03:37 +0200 Subject: [PATCH 27/73] Add slang shader for shadow mapping and shadow mapping cascades sample --- .../shadowmappingcascade.cpp | 14 +- shaders/slang/shadowmapping/offscreen.slang | 23 +++ shaders/slang/shadowmapping/quad.slang | 48 +++++ shaders/slang/shadowmapping/scene.slang | 116 ++++++++++++ .../shadowmappingcascade/debugshadowmap.slang | 29 +++ .../shadowmappingcascade/depthpass.slang | 46 +++++ .../slang/shadowmappingcascade/scene.slang | 168 ++++++++++++++++++ 7 files changed, 436 insertions(+), 8 deletions(-) create mode 100644 shaders/slang/shadowmapping/offscreen.slang create mode 100644 shaders/slang/shadowmapping/quad.slang create mode 100644 shaders/slang/shadowmapping/scene.slang create mode 100644 shaders/slang/shadowmappingcascade/debugshadowmap.slang create mode 100644 shaders/slang/shadowmappingcascade/depthpass.slang create mode 100644 shaders/slang/shadowmappingcascade/scene.slang diff --git a/examples/shadowmappingcascade/shadowmappingcascade.cpp b/examples/shadowmappingcascade/shadowmappingcascade.cpp index 9133a03c..55c6328b 100644 --- a/examples/shadowmappingcascade/shadowmappingcascade.cpp +++ b/examples/shadowmappingcascade/shadowmappingcascade.cpp @@ -1,10 +1,8 @@ /* Vulkan Example - Cascaded shadow mapping for directional light sources - Copyright by Sascha Willems - www.saschawillems.de + Copyright (c) 2016-2025 by Sascha Willems - www.saschawillems.de This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) -*/ -/* This example implements projective cascaded shadow mapping. This technique splits up the camera frustum into multiple frustums with each getting its own full-res shadow map, implemented as a layered depth-only image. The shader then selects the proper shadow map layer depending on what split of the frustum the depth value @@ -175,7 +173,7 @@ public: vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr); // Floor - vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(PushConstBlock), &pushConstBlock); + vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstBlock), &pushConstBlock); models.terrain.draw(commandBuffer, vkglTF::RenderFlags::BindImages, pipelineLayout); // Trees @@ -189,7 +187,7 @@ public: for (auto& position : positions) { pushConstBlock.position = glm::vec4(position, 0.0f); - vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(PushConstBlock), &pushConstBlock); + vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstBlock), &pushConstBlock); // This will also bind the texture images to set 1 models.tree.draw(commandBuffer, vkglTF::RenderFlags::BindImages, pipelineLayout); } @@ -413,7 +411,7 @@ public: vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.debugShadowMap); PushConstBlock pushConstBlock = {}; pushConstBlock.cascadeIndex = displayDepthMapCascadeIndex; - vkCmdPushConstants(drawCmdBuffers[i], pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(PushConstBlock), &pushConstBlock); + vkCmdPushConstants(drawCmdBuffers[i], pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstBlock), &pushConstBlock); vkCmdDraw(drawCmdBuffers[i], 3, 1, 0, 0); } @@ -490,7 +488,7 @@ public: // Shared pipeline layout (scene and depth map debug display) { - VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, sizeof(PushConstBlock), 0); + VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(PushConstBlock), 0); std::array setLayouts = { descriptorSetLayout, vkglTF::descriptorSetLayoutImage }; VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), static_cast(setLayouts.size())); pipelineLayoutCreateInfo.pushConstantRangeCount = 1; @@ -500,7 +498,7 @@ public: // Depth pass pipeline layout { - VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, sizeof(PushConstBlock), 0); + VkPushConstantRange pushConstantRange = vks::initializers::pushConstantRange(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(PushConstBlock), 0); std::array setLayouts = { descriptorSetLayout, vkglTF::descriptorSetLayoutImage }; VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), static_cast(setLayouts.size())); pipelineLayoutCreateInfo.pushConstantRangeCount = 1; diff --git a/shaders/slang/shadowmapping/offscreen.slang b/shaders/slang/shadowmapping/offscreen.slang new file mode 100644 index 00000000..decb80c3 --- /dev/null +++ b/shaders/slang/shadowmapping/offscreen.slang @@ -0,0 +1,23 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct UBO +{ + float4x4 depthMVP; +}; +ConstantBuffer ubo; + +[shader("vertex")] +float4 vertexMain(float3 Pos) : SV_POSITION +{ + return mul(ubo.depthMVP, float4(Pos, 1.0)); +} + +[shader("fragment")] +float4 fragmentMain() +{ + return float4(1.0, 0.0, 0.0, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/shadowmapping/quad.slang b/shaders/slang/shadowmapping/quad.slang new file mode 100644 index 00000000..c6237b1d --- /dev/null +++ b/shaders/slang/shadowmapping/quad.slang @@ -0,0 +1,48 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float4x4 lightSpace; + float4 lightPos; + float zNear; + float zFar; +}; +ConstantBuffer ubo; +Sampler2D samplerColor; + +float LinearizeDepth(float depth) +{ + float n = ubo.zNear; + float f = ubo.zFar; + float z = depth; + return (2.0 * n) / (f + n - z * (f - n)); +} + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float depth = samplerColor.Sample(input.UV).r; + return float4((1.0 - LinearizeDepth(depth)).xxx, 1.0); +} diff --git a/shaders/slang/shadowmapping/scene.slang b/shaders/slang/shadowmapping/scene.slang new file mode 100644 index 00000000..2f9395a6 --- /dev/null +++ b/shaders/slang/shadowmapping/scene.slang @@ -0,0 +1,116 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float2 UV; + float3 Color; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 ViewVec; + float3 LightVec; + float4 ShadowCoord; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float4x4 lightSpace; + float4 lightPos; + float zNear; + float zFar; +}; +ConstantBuffer ubo; +Sampler2D shadowMapSampler; + +[SpecializationConstant] const int enablePCF = 0; + +#define ambient 0.1 + +float textureProj(float4 shadowCoord, float2 off) +{ + float shadow = 1.0; + if ( shadowCoord.z > -1.0 && shadowCoord.z < 1.0 ) + { + float dist = shadowMapSampler.Sample(shadowCoord.xy + off).r; + if ( shadowCoord.w > 0.0 && dist < shadowCoord.z ) + { + shadow = ambient; + } + } + return shadow; +} + +float filterPCF(float4 sc) +{ + int2 texDim; + shadowMapSampler.GetDimensions(texDim.x, texDim.y); + float scale = 1.5; + float dx = scale * 1.0 / float(texDim.x); + float dy = scale * 1.0 / float(texDim.y); + + float shadowFactor = 0.0; + int count = 0; + int range = 1; + + for (int x = -range; x <= range; x++) + { + for (int y = -range; y <= range; y++) + { + shadowFactor += textureProj(sc, float2(dx*x, dy*y)); + count++; + } + + } + return shadowFactor / count; +} + +static const float4x4 biasMat = float4x4( + 0.5, 0.0, 0.0, 0.5, + 0.0, 0.5, 0.0, 0.5, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0); + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Color = input.Color; + output.Normal = input.Normal; + + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos.xyz, 1.0)))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + output.LightVec = normalize(ubo.lightPos.xyz - input.Pos); + output.ViewVec = -pos.xyz; + + output.ShadowCoord = mul(biasMat, mul(ubo.lightSpace, mul(ubo.model, float4(input.Pos, 1.0)))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float shadow = (enablePCF == 1) ? filterPCF(input.ShadowCoord / input.ShadowCoord.w) : textureProj(input.ShadowCoord / input.ShadowCoord.w, float2(0.0, 0.0)); + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = normalize(-reflect(L, N)); + float3 diffuse = max(dot(N, L), ambient) * input.Color; + + return float4(diffuse * shadow, 1.0); +} diff --git a/shaders/slang/shadowmappingcascade/debugshadowmap.slang b/shaders/slang/shadowmappingcascade/debugshadowmap.slang new file mode 100644 index 00000000..925b7d51 --- /dev/null +++ b/shaders/slang/shadowmappingcascade/debugshadowmap.slang @@ -0,0 +1,29 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +[[vk::binding(1,0)]] Sampler2DArray shadowMapSampler; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input, uniform float4 meshPosition, uniform uint cascadeIndex) +{ + float depth = shadowMapSampler.Sample(float3(input.UV, float(cascadeIndex))).r; + return float4(depth.xxx, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/shadowmappingcascade/depthpass.slang b/shaders/slang/shadowmappingcascade/depthpass.slang new file mode 100644 index 00000000..287fe6c8 --- /dev/null +++ b/shaders/slang/shadowmappingcascade/depthpass.slang @@ -0,0 +1,46 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +// todo: pass via specialization constant +#define SHADOW_MAP_CASCADE_COUNT 4 + +struct UBO { + float4x4 cascadeViewProjMat[SHADOW_MAP_CASCADE_COUNT]; +}; +[[vk::binding(3, 0)]] ConstantBuffer ubo; + +[[vk::binding(0, 1)]] Sampler2D colorMapSampler : register(s0, space1); + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform float4 meshPosition, uniform uint cascadeIndex) +{ + VSOutput output; + output.UV = input.UV; + float3 pos = input.Pos + meshPosition.xyz; + output.Pos = mul(ubo.cascadeViewProjMat[cascadeIndex], float4(pos, 1.0)); + return output; +} + +[shader("fragment")] +void fragmentMain(VSOutput input) +{ + float alpha = colorMapSampler.Sample(input.UV).a; + if (alpha < 0.5) { + clip(-1); + } +} \ No newline at end of file diff --git a/shaders/slang/shadowmappingcascade/scene.slang b/shaders/slang/shadowmappingcascade/scene.slang new file mode 100644 index 00000000..8e4bdd56 --- /dev/null +++ b/shaders/slang/shadowmappingcascade/scene.slang @@ -0,0 +1,168 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +#define SHADOW_MAP_CASCADE_COUNT 4 + +struct VSInput +{ + float3 Pos; + float2 UV; + float3 Color; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 ViewPos; + float3 WorldPos; + float2 UV; +}; + +[SpecializationConstant] const int enablePCF = 0; + +#define ambient 0.3 + +struct UBOScene { + float4x4 projection; + float4x4 view; + float4x4 model; +}; +ConstantBuffer uboScene; + +[[vk::binding(1, 0)]] Sampler2DArray shadowMapSampler; + +struct UBOCascades { + float4 cascadeSplits; + float4x4 inverseViewMat; + float3 lightDir; + float _pad; + int colorCascades; +}; +[[vk::binding(2, 0)]] ConstantBuffer uboCascades; + +struct CVPM { + float4x4 matrices[SHADOW_MAP_CASCADE_COUNT]; +}; +[[vk::binding(3, 0)]] ConstantBuffer cascadeViewProjMatrices; + +[[vk::binding(0, 1)]] Sampler2D colorMapSampler; + +static const float4x4 biasMat = float4x4( + 0.5, 0.0, 0.0, 0.5, + 0.0, 0.5, 0.0, 0.5, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 +); + +float textureProj(float4 shadowCoord, float2 offset, uint cascadeIndex) +{ + float shadow = 1.0; + float bias = 0.005; + + if (shadowCoord.z > -1.0 && shadowCoord.z < 1.0) { + float dist = shadowMapSampler.Sample(float3(shadowCoord.xy + offset, cascadeIndex)).r; + if (shadowCoord.w > 0 && dist < shadowCoord.z - bias) { + shadow = ambient; + } + } + return shadow; +} + +float filterPCF(float4 sc, uint cascadeIndex) +{ + int3 texDim; + shadowMapSampler.GetDimensions(texDim.x, texDim.y, texDim.z); + float scale = 0.75; + float dx = scale * 1.0 / float(texDim.x); + float dy = scale * 1.0 / float(texDim.y); + + float shadowFactor = 0.0; + int count = 0; + int range = 1; + + for (int x = -range; x <= range; x++) { + for (int y = -range; y <= range; y++) { + shadowFactor += textureProj(sc, float2(dx*x, dy*y), cascadeIndex); + count++; + } + } + return shadowFactor / count; +} + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform float4 meshPosition) +{ + VSOutput output; + output.Color = input.Color; + output.Normal = input.Normal; + output.UV = input.UV; + float3 pos = input.Pos + meshPosition.xyz; + output.WorldPos = pos; + output.ViewPos = mul(uboScene.view, float4(pos.xyz, 1.0)).xyz; + output.Pos = mul(uboScene.projection, mul(uboScene.view, mul(uboScene.model, float4(pos.xyz, 1.0)))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float4 outFragColor; + float4 color = colorMapSampler.Sample(input.UV); + if (color.a < 0.5) { + clip(-1); + } + + // Get cascade index for the current fragment's view position + uint cascadeIndex = 0; + for (uint i = 0; i < SHADOW_MAP_CASCADE_COUNT - 1; ++i) { + if (input.ViewPos.z < uboCascades.cascadeSplits[i]) { + cascadeIndex = i + 1; + } + } + + // Depth compare for shadowing + float4 shadowCoord = mul(biasMat, mul(cascadeViewProjMatrices.matrices[cascadeIndex], float4(input.WorldPos, 1.0))); + + float shadow = 0; + if (enablePCF == 1) { + shadow = filterPCF(shadowCoord / shadowCoord.w, cascadeIndex); + } else { + shadow = textureProj(shadowCoord / shadowCoord.w, float2(0.0, 0.0), cascadeIndex); + } + + // Directional light + float3 N = normalize(input.Normal); + float3 L = normalize(-uboCascades.lightDir); + float3 H = normalize(L + input.ViewPos); + float diffuse = max(dot(N, L), ambient); + float3 lightColor = float3(1.0, 1.0, 1.0); + outFragColor.rgb = max(lightColor * (diffuse * color.rgb), float3(0.0, 0.0, 0.0)); + outFragColor.rgb *= shadow; + outFragColor.a = color.a; + + // Color cascades (if enabled) + if (uboCascades.colorCascades == 1) { + switch(cascadeIndex) { + case 0 : + outFragColor.rgb *= float3(1.0f, 0.25f, 0.25f); + break; + case 1 : + outFragColor.rgb *= float3(0.25f, 1.0f, 0.25f); + break; + case 2 : + outFragColor.rgb *= float3(0.25f, 0.25f, 1.0f); + break; + case 3 : + outFragColor.rgb *= float3(1.0f, 1.0f, 0.25f); + break; + } + } + + return outFragColor; +} From afd37811ecc217d4f001cb433bab5acb615dd0c2 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Tue, 29 Apr 2025 20:22:19 +0200 Subject: [PATCH 28/73] Add slang shader for omni-directional shadow mapping sample --- .../shadowmappingomni/cubemapdisplay.slang | 80 +++++++++++++++++++ .../slang/shadowmappingomni/offscreen.slang | 45 +++++++++++ shaders/slang/shadowmappingomni/scene.slang | 80 +++++++++++++++++++ 3 files changed, 205 insertions(+) create mode 100644 shaders/slang/shadowmappingomni/cubemapdisplay.slang create mode 100644 shaders/slang/shadowmappingomni/offscreen.slang create mode 100644 shaders/slang/shadowmappingomni/scene.slang diff --git a/shaders/slang/shadowmappingomni/cubemapdisplay.slang b/shaders/slang/shadowmappingomni/cubemapdisplay.slang new file mode 100644 index 00000000..bb4b4a49 --- /dev/null +++ b/shaders/slang/shadowmappingomni/cubemapdisplay.slang @@ -0,0 +1,80 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; +}; +ConstantBuffer ubo; + +SamplerCube shadowCubeMapSampler; + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV.xy * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float4 outFragColor = float4(0, 0, 0, 0); + outFragColor.rgb = float3(0.05, 0.05, 0.05); + + float3 samplePos = float3(0, 0, 0); + + // Crude statement to visualize different cube map faces based on UV coordinates + int x = int(floor(input.UV.x / 0.25f)); + int y = int(floor(input.UV.y / (1.0 / 3.0))); + if (y == 1) { + float2 uv = float2(input.UV.x * 4.0f, (input.UV.y - 1.0/3.0) * 3.0); + uv = 2.0 * float2(uv.x - float(x) * 1.0, uv.y) - 1.0; + switch (x) { + case 0: // NEGATIVE_X + samplePos = float3(-1.0f, uv.y, uv.x); + break; + case 1: // POSITIVE_Z + samplePos = float3(uv.x, uv.y, 1.0f); + break; + case 2: // POSITIVE_X + samplePos = float3(1.0, uv.y, -uv.x); + break; + case 3: // NEGATIVE_Z + samplePos = float3(-uv.x, uv.y, -1.0f); + break; + } + } else { + if (x == 1) { + float2 uv = float2((input.UV.x - 0.25) * 4.0, (input.UV.y - float(y) / 3.0) * 3.0); + uv = 2.0 * uv - 1.0; + switch (y) { + case 0: // NEGATIVE_Y + samplePos = float3(uv.x, -1.0f, uv.y); + break; + case 2: // POSITIVE_Y + samplePos = float3(uv.x, 1.0f, -uv.y); + break; + } + } + } + + if ((samplePos.x != 0.0f) && (samplePos.y != 0.0f)) { + float dist = length(shadowCubeMapSampler.Sample(samplePos).xyz) * 0.005; + outFragColor = float4(dist.xxx, 1.0); + } + return outFragColor; +} \ No newline at end of file diff --git a/shaders/slang/shadowmappingomni/offscreen.slang b/shaders/slang/shadowmappingomni/offscreen.slang new file mode 100644 index 00000000..243447ea --- /dev/null +++ b/shaders/slang/shadowmappingomni/offscreen.slang @@ -0,0 +1,45 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float4 WorldPos; + float3 LightPos; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float4 lightPos; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform float4x4 view) +{ + VSOutput output; + output.Pos = mul(ubo.projection, mul(view, mul(ubo.model, float4(input.Pos, 1.0)))); + + output.WorldPos = float4(input.Pos, 1.0); + output.LightPos = ubo.lightPos.xyz; + return output; +} + +[shader("fragment")] +float fragmentMain(VSOutput input) +{ + // Store distance to light as 32 bit float value + float3 lightVec = input.WorldPos.xyz - input.LightPos; + return length(lightVec); +} \ No newline at end of file diff --git a/shaders/slang/shadowmappingomni/scene.slang b/shaders/slang/shadowmappingomni/scene.slang new file mode 100644 index 00000000..b5296ed7 --- /dev/null +++ b/shaders/slang/shadowmappingomni/scene.slang @@ -0,0 +1,80 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Color; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 EyePos; + float3 LightVec; + float3 WorldPos; + float3 LightPos; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float4 lightPos; +}; +ConstantBuffer ubo; + +SamplerCube shadowCubeMapSampler; + +#define EPSILON 0.15 +#define SHADOW_OPACITY 0.5 + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.Normal = input.Normal; + + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos.xyz, 1.0)))); + output.EyePos = mul(ubo.model, float4(input.Pos, 1.0f)).xyz; + output.LightVec = normalize(ubo.lightPos.xyz - input.Pos.xyz); + output.WorldPos = input.Pos; + + output.LightPos = ubo.lightPos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + // Lighting + float3 N = normalize(input.Normal); + float3 L = normalize(float3(1.0, 1.0, 1.0)); + + float3 Eye = normalize(-input.EyePos); + float3 Reflected = normalize(reflect(-input.LightVec, input.Normal)); + + float4 IAmbient = float4(float3(0.05, 0.05, 0.05), 1.0); + float4 IDiffuse = float4(1.0, 1.0, 1.0, 1.0) * max(dot(input.Normal, input.LightVec), 0.0); + + float4 outFragColor = float4(IAmbient + IDiffuse * float4(input.Color, 1.0)); + + // Shadow + float3 lightVec = input.WorldPos - input.LightPos; + float sampledDist = shadowCubeMapSampler.Sample(lightVec).r; + float dist = length(lightVec); + + // Check if fragment is in shadow + float shadow = (dist <= sampledDist + EPSILON) ? 1.0 : SHADOW_OPACITY; + + outFragColor.rgb *= shadow; + return outFragColor; +} \ No newline at end of file From 2c6f3bf40c17de12bb60c951eb3d1133fa9e6336 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Tue, 29 Apr 2025 20:26:59 +0200 Subject: [PATCH 29/73] Add slang shader for debug printf sample --- shaders/slang/debugprintf/toon.slang | 73 ++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 shaders/slang/debugprintf/toon.slang diff --git a/shaders/slang/debugprintf/toon.slang b/shaders/slang/debugprintf/toon.slang new file mode 100644 index 00000000..1c638bcb --- /dev/null +++ b/shaders/slang/debugprintf/toon.slang @@ -0,0 +1,73 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Normal = input.Normal; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + // Output the vertex position using debug printf + printf("Position = %v4f", pos); + + output.Normal = mul((float4x3)ubo.model, input.Normal).xyz; + float3 lPos = mul((float4x3)ubo.model, ubo.lightPos.xyz).xyz; + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + // Desaturate color + float3 color = float3(lerp(input.Color, dot(float3(0.2126, 0.7152, 0.0722), input.Color).xxx, 0.65)); + + // High ambient colors because mesh materials are pretty dark + float3 ambient = color * float3(1.0, 1.0, 1.0); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * color; + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + + float intensity = dot(N, L); + float shade = 1.0; + shade = intensity < 0.5 ? 0.75 : shade; + shade = intensity < 0.35 ? 0.6 : shade; + shade = intensity < 0.25 ? 0.5 : shade; + shade = intensity < 0.1 ? 0.25 : shade; + + return float4(input.Color * 3.0 * shade, 1); +} \ No newline at end of file From 5758b53a5e7de7dfcb5633bcc2449e21134ab082 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Thu, 1 May 2025 11:34:11 +0200 Subject: [PATCH 30/73] Add slang shader for descriptor sets sample --- shaders/slang/descriptorsets/cube.slang | 51 +++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 shaders/slang/descriptorsets/cube.slang diff --git a/shaders/slang/descriptorsets/cube.slang b/shaders/slang/descriptorsets/cube.slang new file mode 100644 index 00000000..8a8b0ec9 --- /dev/null +++ b/shaders/slang/descriptorsets/cube.slang @@ -0,0 +1,51 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float2 UV; +}; + +// Slang auto generates bindings by order of descriptors +// So the UBO is bound to slot 0, the sampler to slot 1 +// due to their order in the shader + +struct UBOMatrices { + float4x4 projection; + float4x4 view; + float4x4 model; +}; +ConstantBuffer uboMatrices; + +Sampler2D samplerColorMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(uboMatrices.projection, mul(uboMatrices.view, mul(uboMatrices.model, float4(input.Pos.xyz, 1.0)))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return samplerColorMap.Sample(input.UV) * float4(input.Color, 1.0); +} \ No newline at end of file From 52c97db9a4101d2671d19df6bbea27148a8eded7 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Thu, 1 May 2025 11:39:42 +0200 Subject: [PATCH 31/73] Add slang shader for dynamic rendering sample --- shaders/slang/dynamicrendering/texture.slang | 65 ++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 shaders/slang/dynamicrendering/texture.slang diff --git a/shaders/slang/dynamicrendering/texture.slang b/shaders/slang/dynamicrendering/texture.slang new file mode 100644 index 00000000..baed6d6d --- /dev/null +++ b/shaders/slang/dynamicrendering/texture.slang @@ -0,0 +1,65 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; + float3 Normal; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 viewPos; +}; +ConstantBuffer ubo; + +[[vk::binding(0, 1)]] Sampler2D samplerColor; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UV = input.UV; + + float3 worldPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + float3 lightPos = float3(0.0, 0.0, 0.0); + float3 lPos = mul((float3x3)ubo.model, lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = ubo.viewPos.xyz - pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float4 color = samplerColor.Sample(input.UV); + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float specular = pow(max(dot(R, V), 0.0), 16.0) * color.a; + + return float4(diffuse * color.rgb + specular, 1.0); +} \ No newline at end of file From afbc3a5bb7089faf28c4f8f57495e6f0d659fe27 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Thu, 1 May 2025 12:02:19 +0200 Subject: [PATCH 32/73] Add slang shader for vertex attributes sample --- shaders/slang/gltfscenerendering/scene.slang | 4 - shaders/slang/vertexattributes/scene.slang | 86 ++++++++++++++++++++ 2 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 shaders/slang/vertexattributes/scene.slang diff --git a/shaders/slang/gltfscenerendering/scene.slang b/shaders/slang/gltfscenerendering/scene.slang index 776d37ef..b9ed1049 100644 --- a/shaders/slang/gltfscenerendering/scene.slang +++ b/shaders/slang/gltfscenerendering/scene.slang @@ -33,10 +33,6 @@ struct UBO }; ConstantBuffer ubo; -struct PushConsts { - float4x4 model; -}; - [[vk::binding(0, 1)]] Sampler2D samplerColorMap; [[vk::binding(1, 1)]] Sampler2D samplerNormalMap; diff --git a/shaders/slang/vertexattributes/scene.slang b/shaders/slang/vertexattributes/scene.slang new file mode 100644 index 00000000..39223e4e --- /dev/null +++ b/shaders/slang/vertexattributes/scene.slang @@ -0,0 +1,86 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; + float4 Tangent; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; + float3 ViewVec; + float3 LightVec; + float4 Tangent; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4 lightPos; + float4 viewPos; +}; +ConstantBuffer ubo; + +[[vk::binding(0, 1)]] Sampler2D samplerColorMap; +[[vk::binding(1, 1)]] Sampler2D samplerNormalMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform float4x4 modelMat) +{ + VSOutput output; + output.Normal = input.Normal; + output.UV = input.UV; + output.Tangent = input.Tangent; + + float4x4 modelView = mul(ubo.view, modelMat); + + output.Pos = mul(ubo.projection, mul(modelView, float4(input.Pos.xyz, 1.0))); + + output.Normal = mul((float3x3)modelMat, input.Normal); + float4 pos = mul(modelMat, float4(input.Pos, 1.0)); + output.LightVec = ubo.lightPos.xyz - pos.xyz; + output.ViewVec = ubo.viewPos.xyz - pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input, uniform float4x4 modelMat, uniform uint alphaMask, uniform float alphaMaskCutoff) +{ + float4 color = samplerColorMap.Sample(input.UV); + + if (alphaMask == 1) { + if (color.a < alphaMaskCutoff) { + discard; + } + } + + float3 N = normalize(input.Normal); + float3 T = normalize(input.Tangent.xyz); + float3 B = cross(input.Normal, input.Tangent.xyz) * input.Tangent.w; + float3x3 TBN = float3x3(T, B, N); + N = mul(normalize(samplerNormalMap.Sample(input.UV).xyz * 2.0 - float3(1.0, 1.0, 1.0)), TBN); + + const float ambient = 0.1; + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), ambient).rrr; + float3 specular = pow(max(dot(R, V), 0.0), 32.0); + return float4(diffuse * color.rgb + specular, color.a); +} \ No newline at end of file From 4df49dba717f0a1b718092c50323f11351e3cfeb Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 3 May 2025 09:42:32 +0200 Subject: [PATCH 33/73] Add slang shaders for additional samples --- shaders/slang/bloom/colorpass.slang | 45 ++++++++++++ shaders/slang/bloom/gaussblur.slang | 63 +++++++++++++++++ shaders/slang/bloom/phongpass.slang | 70 +++++++++++++++++++ shaders/slang/bloom/skybox.slang | 41 +++++++++++ shaders/slang/dynamicuniformbuffer/base.slang | 47 +++++++++++++ 5 files changed, 266 insertions(+) create mode 100644 shaders/slang/bloom/colorpass.slang create mode 100644 shaders/slang/bloom/gaussblur.slang create mode 100644 shaders/slang/bloom/phongpass.slang create mode 100644 shaders/slang/bloom/skybox.slang create mode 100644 shaders/slang/dynamicuniformbuffer/base.slang diff --git a/shaders/slang/bloom/colorpass.slang b/shaders/slang/bloom/colorpass.slang new file mode 100644 index 00000000..40ada51e --- /dev/null +++ b/shaders/slang/bloom/colorpass.slang @@ -0,0 +1,45 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float2 UV; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Color; + float2 UV; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; +}; +ConstantBuffer ubo; + +Sampler2D colorMapSampler; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UV = input.UV; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, input.Pos))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return float4(input.Color, 1); +} \ No newline at end of file diff --git a/shaders/slang/bloom/gaussblur.slang b/shaders/slang/bloom/gaussblur.slang new file mode 100644 index 00000000..e381a27a --- /dev/null +++ b/shaders/slang/bloom/gaussblur.slang @@ -0,0 +1,63 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +struct UBO +{ + float blurScale; + float blurStrength; +}; +ConstantBuffer ubo; + +Sampler2D samplerColor; + +[[SpecializationConstant]] const int blurdirection = 0; + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float weight[5]; + weight[0] = 0.227027; + weight[1] = 0.1945946; + weight[2] = 0.1216216; + weight[3] = 0.054054; + weight[4] = 0.016216; + + float2 textureSize; + samplerColor.GetDimensions(textureSize.x, textureSize.y); + float2 tex_offset = 1.0 / textureSize * ubo.blurScale; // gets size of single texel + float3 result = samplerColor.Sample(input.UV).rgb * weight[0]; // current fragment's contribution + for(int i = 1; i < 5; ++i) + { + if (blurdirection == 1) + { + // H + result += samplerColor.Sample(input.UV + float2(tex_offset.x * i, 0.0)).rgb * weight[i] * ubo.blurScale; + result += samplerColor.Sample(input.UV - float2(tex_offset.x * i, 0.0)).rgb * weight[i] * ubo.blurScale; + } + else + { + // V + result += samplerColor.Sample(input.UV + float2(0.0, tex_offset.y * i)).rgb * weight[i] * ubo.blurScale; + result += samplerColor.Sample(input.UV - float2(0.0, tex_offset.y * i)).rgb * weight[i] * ubo.blurScale; + } + } + return float4(result, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/bloom/phongpass.slang b/shaders/slang/bloom/phongpass.slang new file mode 100644 index 00000000..8d581753 --- /dev/null +++ b/shaders/slang/bloom/phongpass.slang @@ -0,0 +1,70 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float2 UV; + float3 Color; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; + float3 Color; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; +}; +ConstantBuffer ubo; + +Sampler2D colorMapSampler; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, input.Pos))); + + float3 lightPos = float3(-5.0, -5.0, 0.0); + float4 pos = mul(ubo.view, mul(ubo.model, input.Pos)); + output.Normal = mul((float4x3)mul(ubo.view, ubo.model), input.Normal).xyz; + output.LightVec = lightPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 ambient = float3(0.0f, 0.0f, 0.0f); + + // Adjust light calculations for glow color + if ((input.Color.r >= 0.9) || (input.Color.g >= 0.9) || (input.Color.b >= 0.9)) + { + ambient = input.Color * 0.25; + } + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 8.0) * float3(0.75f, 0.75f, 0.75f); + return float4(ambient + diffuse + specular, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/bloom/skybox.slang b/shaders/slang/bloom/skybox.slang new file mode 100644 index 00000000..3b21695b --- /dev/null +++ b/shaders/slang/bloom/skybox.slang @@ -0,0 +1,41 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; +} + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 UVW; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; +}; +ConstantBuffer ubo; + +SamplerCube samplerCubeMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UVW = input.Pos; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos.xyz, 1.0)))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return samplerCubeMap.Sample(input.UVW); +} \ No newline at end of file diff --git a/shaders/slang/dynamicuniformbuffer/base.slang b/shaders/slang/dynamicuniformbuffer/base.slang new file mode 100644 index 00000000..ec8e444d --- /dev/null +++ b/shaders/slang/dynamicuniformbuffer/base.slang @@ -0,0 +1,47 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Color; +}; + +struct UboView +{ + float4x4 projection; + float4x4 view; +}; +ConstantBuffer uboView; + +struct UboInstance +{ + float4x4 model; +}; +ConstantBuffer uboInstance; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + float4x4 modelView = mul(uboView.view, uboInstance.model); + float3 worldPos = mul(modelView, float4(input.Pos, 1.0)).xyz; + output.Pos = mul(uboView.projection, mul(modelView, float4(input.Pos.xyz, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return float4(input.Color, 1.0); +} \ No newline at end of file From 0a6c03b58cc9e77096c39776173a7ec768e74905 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 3 May 2025 11:11:43 +0200 Subject: [PATCH 34/73] Add slang shaders for additional samples --- shaders/slang/_rename.py | 11 ++- shaders/slang/compileshaders.py | 14 +-- shaders/slang/geometryshader/mesh.slang | 58 ++++++++++++ .../slang/geometryshader/normaldebug.slang | 68 ++++++++++++++ shaders/slang/viewportarray/scene.slang | 90 +++++++++++++++++++ 5 files changed, 235 insertions(+), 6 deletions(-) create mode 100644 shaders/slang/geometryshader/mesh.slang create mode 100644 shaders/slang/geometryshader/normaldebug.slang create mode 100644 shaders/slang/viewportarray/scene.slang diff --git a/shaders/slang/_rename.py b/shaders/slang/_rename.py index 5b6e61d1..f24457fb 100644 --- a/shaders/slang/_rename.py +++ b/shaders/slang/_rename.py @@ -7,6 +7,11 @@ from shutil import move def checkRenameFiles(samplename): mappings = {} match samplename: + case "geometryshader": + mappings = { + "normaldebug.vert.spv": "base.vert.spv", + "normaldebug.frag.spv": "base.frag.spv", + } case "raytracingbasic": mappings = { "raytracingbasic.rchit.spv": "closesthit.rchit.spv", @@ -18,6 +23,10 @@ def checkRenameFiles(samplename): "raytracingreflections.rchit.spv": "closesthit.rchit.spv", "raytracingreflections.rmiss.spv": "miss.rmiss.spv", "raytracingreflections.rgen.spv": "raygen.rgen.spv", - } + } + case "viewportarray": + mappings = { + "scene.geom.spv": "multiview.geom.spv", + } for x, y in mappings.items(): move(samplename + "\\" + x, samplename + "\\" + y) diff --git a/shaders/slang/compileshaders.py b/shaders/slang/compileshaders.py index 9582c1a9..5a6faf94 100644 --- a/shaders/slang/compileshaders.py +++ b/shaders/slang/compileshaders.py @@ -46,13 +46,15 @@ def getShaderStages(filename): if '[shader("closesthit")]' in filecontent: stages.append("closesthit") if '[shader("callable")]' in filecontent: - stages.append("callable") + stages.append("callable") if '[shader("compute")]' in filecontent: - stages.append("compute") + stages.append("compute") if '[shader("amplification")]' in filecontent: - stages.append("amplification") + stages.append("amplification") if '[shader("mesh")]' in filecontent: - stages.append("mesh") + stages.append("mesh") + if '[shader("geometry")]' in filecontent: + stages.append("geometry") f.close() return stages @@ -64,7 +66,7 @@ compile_single_sample = "" if args.sample != None: compile_single_sample = args.sample if (not os.path.isdir(compile_single_sample)): - print("ERROR: No directory found with name %s" % compile_single_sample) + print("ERROR: No directory found with name %s" % compile_single_sample) exit(-1) dir_path = os.path.dirname(os.path.realpath(__file__)) @@ -105,6 +107,8 @@ for root, dirs, files in os.walk(dir_path): output_ext = ".mesh" case "amplification": output_ext = ".task" + case "geometry": + output_ext = ".geom" output_file = output_base_file_name + output_ext + ".spv" output_file = output_file.replace(".slang", "") res = subprocess.call("%s %s -profile spirv_1_4 -matrix-layout-column-major -target spirv -o %s -entry %s -stage %s -warnings-disable 39001" % (compiler_path, input_file, output_file, entry_point, stage), shell=True) diff --git a/shaders/slang/geometryshader/mesh.slang b/shaders/slang/geometryshader/mesh.slang new file mode 100644 index 00000000..fbe1e977 --- /dev/null +++ b/shaders/slang/geometryshader/mesh.slang @@ -0,0 +1,58 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float3 Normal; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Normal = input.Normal; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.model, input.Pos)); + + float4 pos = mul(ubo.model, float4(input.Pos.xyz, 1.0)); + output.Normal = mul((float4x3)ubo.model, input.Normal).xyz; + + float3 lightPos = float3(1.0f, -1.0f, 1.0f); + output.LightVec = lightPos.xyz - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 ambient = float3(0.1, 0.1, 0.1); + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + return float4((ambient + diffuse) * input.Color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/geometryshader/normaldebug.slang b/shaders/slang/geometryshader/normaldebug.slang new file mode 100644 index 00000000..9b244d8d --- /dev/null +++ b/shaders/slang/geometryshader/normaldebug.slang @@ -0,0 +1,68 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : POSITION0; + float3 Normal; +}; + +struct GSOutput +{ + float4 Pos : SV_POSITION; + float3 Color; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Normal = input.Normal; + output.Pos = float4(input.Pos.xyz, 1.0); + return output; +} + +[shader("geometry")] +[maxvertexcount(6)] +void geometryMain(triangle VSOutput input[3], inout LineStream outStream) +{ + float normalLength = 0.02; + for(int i=0; i<3; i++) + { + float3 pos = input[i].Pos.xyz; + float3 normal = input[i].Normal.xyz; + + GSOutput output = (GSOutput)0; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(pos, 1.0))); + output.Color = float3(1.0, 0.0, 0.0); + outStream.Append( output ); + + output.Pos = mul(ubo.projection, mul(ubo.model, float4(pos + normal * normalLength, 1.0))); + output.Color = float3(0.0, 0.0, 1.0); + outStream.Append( output ); + + outStream.RestartStrip(); + } +} + +[shader("fragment")] +float4 fragmentMain(GSOutput input) +{ + return float4(input.Color, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/viewportarray/scene.slang b/shaders/slang/viewportarray/scene.slang new file mode 100644 index 00000000..e6b6eb7e --- /dev/null +++ b/shaders/slang/viewportarray/scene.slang @@ -0,0 +1,90 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; +}; + +struct GSOutput +{ + float4 Pos : SV_POSITION; + uint ViewportIndex : SV_ViewportArrayIndex; + uint PrimitiveID : SV_PrimitiveID; + float3 Normal; + float3 Color; + float3 ViewVec; + float3 LightVec; +} + +struct UBO +{ + float4x4 projection[2]; + float4x4 modelview[2]; + float4 lightPos; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.Normal = input.Normal; + output.Pos = float4(input.Pos.xyz, 1.0); + return output; +} + +[shader("geometry")] +[maxvertexcount(3)] +[instance(2)] +void geometryMain(triangle VSOutput input[3], inout TriangleStream outStream, uint InvocationID: SV_GSInstanceID, uint PrimitiveID: SV_PrimitiveID) +{ + for (int i = 0; i < 3; i++) + { + GSOutput output; + output.Normal = mul((float3x3)ubo.modelview[InvocationID], input[i].Normal); + output.Color = input[i].Color; + + float4 pos = input[i].Pos; + float4 worldPos = mul(ubo.modelview[InvocationID], pos); + + float3 lPos = mul(ubo.modelview[InvocationID], ubo.lightPos).xyz; + output.LightVec = lPos - worldPos.xyz; + output.ViewVec = -worldPos.xyz; + + output.Pos = mul(ubo.projection[InvocationID], worldPos); + + // Set the viewport index that the vertex will be emitted to + output.ViewportIndex = InvocationID; + output.PrimitiveID = PrimitiveID; + outStream.Append(output); + } + + outStream.RestartStrip(); +} + +[shader("fragment")] +float4 fragmentMain(GSOutput input) +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 ambient = float3(0.1, 0.1, 0.1); + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + return float4((ambient + diffuse) * input.Color.rgb + specular, 1.0); +} \ No newline at end of file From e0bff55eab1295926294ea5aea306168a59824f0 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 3 May 2025 11:43:55 +0200 Subject: [PATCH 35/73] Add slang shaders for shader objects sample --- shaders/slang/shaderobjects/phong.slang | 65 +++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 shaders/slang/shaderobjects/phong.slang diff --git a/shaders/slang/shaderobjects/phong.slang b/shaders/slang/shaderobjects/phong.slang new file mode 100644 index 00000000..10e0e0d8 --- /dev/null +++ b/shaders/slang/shaderobjects/phong.slang @@ -0,0 +1,65 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; +ConstantBuffer ubo; + +Sampler2D samplerColor; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float4x3)ubo.model, input.Normal).xyz; + float3 lPos = mul((float4x3)ubo.model, ubo.lightPos.xyz).xyz; + output.LightVec = lPos.xyz - pos.xyz; + output.ViewVec = -pos.xyz; + + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + // Desaturate color + float3 color = float3(lerp(input.Color, float3(dot(float3(0.2126, 0.7152, 0.0722), input.Color)), 0.65)); + + // High ambient colors because mesh materials are pretty dark + float3 ambient = color; + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * color; + float3 specular = pow(max(dot(R, V), 0.0), 32.0) * float3(0.35); + return float4(ambient + diffuse * 1.75 + specular, 1.0); +} \ No newline at end of file From 0e975064d908dbe20f740bc32eb23eda3eea8c80 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 3 May 2025 17:33:16 +0200 Subject: [PATCH 36/73] Add slang shaders for additional samples --- shaders/slang/multisampling/mesh.slang | 63 ++++++++++ shaders/slang/multiview/multiview.slang | 60 ++++++++++ shaders/slang/multiview/viewdisplay.slang | 46 ++++++++ .../slang/negativeviewportheight/quad.slang | 30 +++++ shaders/slang/pushdescriptors/cube.slang | 51 ++++++++ .../slang/specializationconstants/uber.slang | 110 ++++++++++++++++++ shaders/slang/sphericalenvmapping/sem.slang | 58 +++++++++ 7 files changed, 418 insertions(+) create mode 100644 shaders/slang/multisampling/mesh.slang create mode 100644 shaders/slang/multiview/multiview.slang create mode 100644 shaders/slang/multiview/viewdisplay.slang create mode 100644 shaders/slang/negativeviewportheight/quad.slang create mode 100644 shaders/slang/pushdescriptors/cube.slang create mode 100644 shaders/slang/specializationconstants/uber.slang create mode 100644 shaders/slang/sphericalenvmapping/sem.slang diff --git a/shaders/slang/multisampling/mesh.slang b/shaders/slang/multisampling/mesh.slang new file mode 100644 index 00000000..840c1c24 --- /dev/null +++ b/shaders/slang/multisampling/mesh.slang @@ -0,0 +1,63 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float2 UV; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; +ConstantBuffer ubo; + +[[vk::binding(0,1)]] Sampler2D samplerColorMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.model, float4(input.Pos, 0.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + float3 lPos = mul((float3x3)ubo.model, ubo.lightPos.xyz); + output.LightVec = lPos - input.Pos; + output.ViewVec = -input.Pos; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float4 color = samplerColorMap.Sample(input.UV) * float4(input.Color, 1.0); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.15) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + return float4(diffuse * color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/multiview/multiview.slang b/shaders/slang/multiview/multiview.slang new file mode 100644 index 00000000..a4edbfa5 --- /dev/null +++ b/shaders/slang/multiview/multiview.slang @@ -0,0 +1,60 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection[2]; + float4x4 modelview[2]; + float4 lightPos; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uint ViewIndex: SV_ViewID) +{ + VSOutput output; + output.Color = input.Color; + output.Normal = mul((float3x3)ubo.modelview[ViewIndex], input.Normal); + + float4 pos = float4(input.Pos.xyz, 1.0); + float4 worldPos = mul(ubo.modelview[ViewIndex], pos); + + float3 lPos = mul(ubo.modelview[ViewIndex], ubo.lightPos).xyz; + output.LightVec = lPos - worldPos.xyz; + output.ViewVec = -worldPos.xyz; + + output.Pos = mul(ubo.projection[ViewIndex], worldPos); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 ambient = float3(0.1, 0.1, 0.1); + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + return float4((ambient + diffuse) * input.Color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/multiview/viewdisplay.slang b/shaders/slang/multiview/viewdisplay.slang new file mode 100644 index 00000000..4c982738 --- /dev/null +++ b/shaders/slang/multiview/viewdisplay.slang @@ -0,0 +1,46 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +struct UBO +{ + float4x4 projection[2]; + float4x4 modelview[2]; + float4 lightPos; + float distortionAlpha; +}; +ConstantBuffer ubo; + +Sampler2DArray samplerView; + +[[SpecializationConstant]] const float VIEW_LAYER = 0.0f; + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + const float alpha = ubo.distortionAlpha; + + float2 p1 = float2(2.0 * input.UV - 1.0); + float2 p2 = p1 / (1.0 - alpha * length(p1)); + p2 = (p2 + 1.0) * 0.5; + + bool inside = ((p2.x >= 0.0) && (p2.x <= 1.0) && (p2.y >= 0.0) && (p2.y <= 1.0)); + return inside ? samplerView.Sample(float3(p2, VIEW_LAYER)) : float4(0.0, 0.0, 0.0, 0.0); +} \ No newline at end of file diff --git a/shaders/slang/negativeviewportheight/quad.slang b/shaders/slang/negativeviewportheight/quad.slang new file mode 100644 index 00000000..1ea13bb3 --- /dev/null +++ b/shaders/slang/negativeviewportheight/quad.slang @@ -0,0 +1,30 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ + float3 Pos; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +Sampler2D samplerColor; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UV = input.UV; + output.Pos = float4(input.Pos, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return samplerColor.Sample(input.UV); +} \ No newline at end of file diff --git a/shaders/slang/pushdescriptors/cube.slang b/shaders/slang/pushdescriptors/cube.slang new file mode 100644 index 00000000..372c5eaa --- /dev/null +++ b/shaders/slang/pushdescriptors/cube.slang @@ -0,0 +1,51 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float2 UV; +}; + +struct UBOCamera { + float4x4 projection; + float4x4 view; +}; +ConstantBuffer uboCamera; + +struct UBOModel { + float4x4 local; +}; +ConstantBuffer uboModel; + +Sampler2D samplerColorMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(uboCamera.projection, mul(uboCamera.view, mul(uboModel.local, float4(input.Pos.xyz, 1.0)))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return samplerColorMap.Sample(input.UV) * float4(input.Color, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/specializationconstants/uber.slang b/shaders/slang/specializationconstants/uber.slang new file mode 100644 index 00000000..1d7c1c3c --- /dev/null +++ b/shaders/slang/specializationconstants/uber.slang @@ -0,0 +1,110 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float2 UV; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; +ConstantBuffer ubo; + +Sampler2D samplerColormap; +Sampler2D samplerDiscard; + +// We use this constant to control the flow of the shader depending on the +// lighting model selected at pipeline creation time +[[SpecializationConstant]] const int LIGHTING_MODEL = 0; +// Parameter for the toon shading part of the shader +[[SpecializationConstant]] const int PARAM_TOON_DESATURATION = 0; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + float3 lPos = mul((float3x3)ubo.model, ubo.lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) : SV_TARGET +{ + switch (LIGHTING_MODEL) { + case 0: // Phong + { + float3 ambient = input.Color * float3(0.25, 0.25, 0.25); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 32.0) * float3(0.75, 0.75, 0.75); + return float4(ambient + diffuse * 1.75 + specular, 1.0); + } + case 1: // Toon + { + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float intensity = dot(N,L); + float3 color; + if (intensity > 0.98) + color = input.Color * 1.5; + else if (intensity > 0.9) + color = input.Color * 1.0; + else if (intensity > 0.5) + color = input.Color * 0.6; + else if (intensity > 0.25) + color = input.Color * 0.4; + else + color = input.Color * 0.2; + // Desaturate a bit + color = float3(lerp(color, dot(float3(0.2126,0.7152,0.0722), color).xxx, asfloat(PARAM_TOON_DESATURATION))); + return float4(color, 1); + } + case 2: // Textured + { + float4 color = samplerColormap.Sample(input.UV).rrra; + float3 ambient = color.rgb * float3(0.25, 0.25, 0.25) * input.Color; + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * color.rgb; + float specular = pow(max(dot(R, V), 0.0), 32.0) * color.a; + return float4(ambient + diffuse + specular.xxx, 1.0); + } + } + + return float4(0, 0, 0, 0); +} \ No newline at end of file diff --git a/shaders/slang/sphericalenvmapping/sem.slang b/shaders/slang/sphericalenvmapping/sem.slang new file mode 100644 index 00000000..28f75f31 --- /dev/null +++ b/shaders/slang/sphericalenvmapping/sem.slang @@ -0,0 +1,58 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float3 Normal; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Color; + float3 EyePos; + float3 Normal; + int TexIndex; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 normal; + float4x4 view; + int texIndex; +}; +ConstantBuffer ubo; + +Sampler2DArray matCapSampler; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + float4x4 modelView = mul(ubo.view, ubo.model); + output.EyePos = normalize(mul(modelView, input.Pos).xyz); + output.TexIndex = ubo.texIndex; + output.Normal = normalize(mul((float3x3)ubo.normal, input.Normal)); + float3 r = reflect(output.EyePos, output.Normal); + float m = 2.0 * sqrt(pow(r.x, 2.0) + pow(r.y, 2.0) + pow(r.z + 1.0, 2.0)); + output.Pos = mul(ubo.projection, mul(modelView, input.Pos)); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 r = reflect( input.EyePos, input.Normal ); + float3 r2 = float3( r.x, r.y, r.z + 1.0 ); + float m = 2.0 * length( r2 ); + float2 vN = r.xy / m + .5; + return float4(matCapSampler.Sample(float3(vN, input.TexIndex)).rgb * (clamp(input.Color.r * 2, 0.0, 1.0)), 1.0); +} From b3c032ef68f427d8aaea2972be776a4bdab94d28 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 4 May 2025 13:31:14 +0200 Subject: [PATCH 37/73] Add slang shaders for additional samples --- shaders/slang/conditionalrender/model.slang | 66 ++++++ .../slang/conservativeraster/fullscreen.slang | 28 +++ .../slang/conservativeraster/triangle.slang | 38 ++++ .../conservativeraster/triangleoverlay.slang | 11 + shaders/slang/descriptorbuffer/cube.slang | 51 +++++ shaders/slang/pbrbasic/pbr.slang | 138 ++++++++++++ shaders/slang/pbribl/filtercube.slang | 25 +++ shaders/slang/pbribl/genbrdflut.slang | 108 ++++++++++ shaders/slang/pbribl/irradiancecube.slang | 39 ++++ shaders/slang/pbribl/pbribl.slang | 193 +++++++++++++++++ shaders/slang/pbribl/prefilterenvmap.slang | 109 ++++++++++ shaders/slang/pbribl/skybox.slang | 70 +++++++ shaders/slang/pbrtexture/filtercube.slang | 25 +++ shaders/slang/pbrtexture/genbrdflut.slang | 108 ++++++++++ shaders/slang/pbrtexture/irradiancecube.slang | 39 ++++ shaders/slang/pbrtexture/pbrtexture.slang | 198 ++++++++++++++++++ .../slang/pbrtexture/prefilterenvmap.slang | 109 ++++++++++ shaders/slang/pbrtexture/skybox.slang | 70 +++++++ 18 files changed, 1425 insertions(+) create mode 100644 shaders/slang/conditionalrender/model.slang create mode 100644 shaders/slang/conservativeraster/fullscreen.slang create mode 100644 shaders/slang/conservativeraster/triangle.slang create mode 100644 shaders/slang/conservativeraster/triangleoverlay.slang create mode 100644 shaders/slang/descriptorbuffer/cube.slang create mode 100644 shaders/slang/pbrbasic/pbr.slang create mode 100644 shaders/slang/pbribl/filtercube.slang create mode 100644 shaders/slang/pbribl/genbrdflut.slang create mode 100644 shaders/slang/pbribl/irradiancecube.slang create mode 100644 shaders/slang/pbribl/pbribl.slang create mode 100644 shaders/slang/pbribl/prefilterenvmap.slang create mode 100644 shaders/slang/pbribl/skybox.slang create mode 100644 shaders/slang/pbrtexture/filtercube.slang create mode 100644 shaders/slang/pbrtexture/genbrdflut.slang create mode 100644 shaders/slang/pbrtexture/irradiancecube.slang create mode 100644 shaders/slang/pbrtexture/pbrtexture.slang create mode 100644 shaders/slang/pbrtexture/prefilterenvmap.slang create mode 100644 shaders/slang/pbrtexture/skybox.slang diff --git a/shaders/slang/conditionalrender/model.slang b/shaders/slang/conditionalrender/model.slang new file mode 100644 index 00000000..fa4b8f9f --- /dev/null +++ b/shaders/slang/conditionalrender/model.slang @@ -0,0 +1,66 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; +}; +ConstantBuffer ubo; + +struct Node +{ + float4x4 transform; +}; +[[vk::binding(0,1)]] ConstantBuffer node; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform float4 baseColorFactor) +{ + VSOutput output; + output.Normal = input.Normal; + output.Color = baseColorFactor.rgb; + float4 pos = float4(input.Pos, 1.0); + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, mul(node.transform, pos)))); + + output.Normal = mul((float4x3)mul(ubo.view, mul(ubo.model, node.transform)), input.Normal).xyz; + + float4 localpos = mul(ubo.view, mul(ubo.model, mul(node.transform, pos))); + float3 lightPos = float3(10.0f, -10.0f, 10.0f); + output.LightVec = lightPos.xyz - localpos.xyz; + output.ViewVec = -localpos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 ambient = float3(0.1, 0.1, 0.1); + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + return float4((ambient + diffuse) * input.Color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/conservativeraster/fullscreen.slang b/shaders/slang/conservativeraster/fullscreen.slang new file mode 100644 index 00000000..d9705f60 --- /dev/null +++ b/shaders/slang/conservativeraster/fullscreen.slang @@ -0,0 +1,28 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +Sampler2D samplerColor; + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return samplerColor.Sample(input.UV); +} \ No newline at end of file diff --git a/shaders/slang/conservativeraster/triangle.slang b/shaders/slang/conservativeraster/triangle.slang new file mode 100644 index 00000000..bc26b8f7 --- /dev/null +++ b/shaders/slang/conservativeraster/triangle.slang @@ -0,0 +1,38 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ +struct VSInput +{ + float3 Pos; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Color; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return float4(input.Color, 1); +} \ No newline at end of file diff --git a/shaders/slang/conservativeraster/triangleoverlay.slang b/shaders/slang/conservativeraster/triangleoverlay.slang new file mode 100644 index 00000000..6915ce36 --- /dev/null +++ b/shaders/slang/conservativeraster/triangleoverlay.slang @@ -0,0 +1,11 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +[shader("fragment")] +float4 fragmentMain() +{ + return float4(1.0, 1.0, 1.0, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/descriptorbuffer/cube.slang b/shaders/slang/descriptorbuffer/cube.slang new file mode 100644 index 00000000..7d6e3ad3 --- /dev/null +++ b/shaders/slang/descriptorbuffer/cube.slang @@ -0,0 +1,51 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float2 UV; +}; + +struct UBOCamera { + float4x4 projection; + float4x4 view; +}; +ConstantBuffer uboCamera; + +struct UBOModel { + float4x4 local; +}; +[[vk::binding(0, 1)]] ConstantBuffer uboModel; + +[[vk::binding(0, 2)]] Sampler2D samplerColorMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(uboCamera.projection, mul(uboCamera.view, mul(uboModel.local, float4(input.Pos.xyz, 1.0)))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return samplerColorMap.Sample(input.UV) * float4(input.Color, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/pbrbasic/pbr.slang b/shaders/slang/pbrbasic/pbr.slang new file mode 100644 index 00000000..242d0fc9 --- /dev/null +++ b/shaders/slang/pbrbasic/pbr.slang @@ -0,0 +1,138 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 WorldPos; + float3 Normal; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; + float3 camPos; +}; +ConstantBuffer ubo; + +struct UBOParams { + float4 lights[4]; +}; +ConstantBuffer uboParams; + +struct Material { + [[vk::offset(12)]] float roughness; + [[vk::offset(16)]] float metallic; + [[vk::offset(20)]] float r; + [[vk::offset(24)]] float g; + [[vk::offset(28)]] float b; +}; +[[vk::push_constant]] Material material; + +static const float PI = 3.14159265359; + +// Normal Distribution function -------------------------------------- +float D_GGX(float dotNH, float roughness) +{ + float alpha = roughness * roughness; + float alpha2 = alpha * alpha; + float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0; + return (alpha2)/(PI * denom*denom); +} + +// Geometric Shadowing function -------------------------------------- +float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness) +{ + float r = (roughness + 1.0); + float k = (r*r) / 8.0; + float GL = dotNL / (dotNL * (1.0 - k) + k); + float GV = dotNV / (dotNV * (1.0 - k) + k); + return GL * GV; +} + +// Fresnel function ---------------------------------------------------- +float3 F_Schlick(float cosTheta, Material material) +{ + float3 F0 = lerp(float3(0.04, 0.04, 0.04), float3(material.r, material.g, material.b), material.metallic); // * material.specular + float3 F = F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); + return F; +} + +// Specular BRDF composition -------------------------------------------- + +float3 BRDF(float3 L, float3 V, float3 N, Material material) +{ + // Precalculate vectors and dot products + float3 H = normalize (V + L); + float dotNV = clamp(dot(N, V), 0.0, 1.0); + float dotNL = clamp(dot(N, L), 0.0, 1.0); + float dotLH = clamp(dot(L, H), 0.0, 1.0); + float dotNH = clamp(dot(N, H), 0.0, 1.0); + + // Light color fixed + float3 lightColor = float3(1.0, 1.0, 1.0); + + float3 color = float3(0.0, 0.0, 0.0); + + if (dotNL > 0.0) + { + float rroughness = max(0.05, material.roughness); + // D = Normal distribution (Distribution of the microfacets) + float D = D_GGX(dotNH, material.roughness); + // G = Geometric shadowing term (Microfacets shadowing) + float G = G_SchlicksmithGGX(dotNL, dotNV, rroughness); + // F = Fresnel factor (Reflectance depending on angle of incidence) + float3 F = F_Schlick(dotNV, material); + + float3 spec = D * F * G / (4.0 * dotNL * dotNV); + + color += spec * dotNL * lightColor; + } + + return color; +} + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform float3 objPos) +{ + VSOutput output; + float3 locPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + output.WorldPos = locPos + objPos; + output.Normal = mul((float3x3)ubo.model, input.Normal); + output.Pos = mul(ubo.projection, mul(ubo.view, float4(output.WorldPos, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 N = normalize(input.Normal); + float3 V = normalize(ubo.camPos - input.WorldPos); + + // Specular contribution + float3 Lo = float3(0.0, 0.0, 0.0); + for (int i = 0; i < 4; i++) { + float3 L = normalize(uboParams.lights[i].xyz - input.WorldPos); + Lo += BRDF(L, V, N, material); + }; + + // Combine with ambient + float3 color = float3(material.r, material.g, material.b) * 0.02; + color += Lo; + + // Gamma correct + color = pow(color, float3(0.4545, 0.4545, 0.4545)); + + return float4(color, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/pbribl/filtercube.slang b/shaders/slang/pbribl/filtercube.slang new file mode 100644 index 00000000..6c848459 --- /dev/null +++ b/shaders/slang/pbribl/filtercube.slang @@ -0,0 +1,25 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 UVW; +}; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform float4x4 mvp) +{ + VSOutput output; + output.UVW = input.Pos; + output.Pos = mul(mvp, float4(input.Pos.xyz, 1.0)); + return output; +} diff --git a/shaders/slang/pbribl/genbrdflut.slang b/shaders/slang/pbribl/genbrdflut.slang new file mode 100644 index 00000000..b40d7b16 --- /dev/null +++ b/shaders/slang/pbribl/genbrdflut.slang @@ -0,0 +1,108 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + + struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +[[SpecializationConstant]] const uint NUM_SAMPLES = 1024u; + +#define PI 3.1415926536 + +// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ +float random(float2 co) +{ + float a = 12.9898; + float b = 78.233; + float c = 43758.5453; + float dt= dot(co.xy ,float2(a,b)); + float sn= fmod(dt,3.14); + return frac(sin(sn) * c); +} + +float2 hammersley2d(uint i, uint N) +{ + // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html + uint bits = (i << 16u) | (i >> 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); + float rdi = float(bits) * 2.3283064365386963e-10; + return float2(float(i) /float(N), rdi); +} + +// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf +float3 importanceSample_GGX(float2 Xi, float roughness, float3 normal) +{ + // Maps a 2D point to a hemisphere with spread based on roughness + float alpha = roughness * roughness; + float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1; + float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y)); + float sinTheta = sqrt(1.0 - cosTheta * cosTheta); + float3 H = float3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta); + + // Tangent space + float3 up = abs(normal.z) < 0.999 ? float3(0.0, 0.0, 1.0) : float3(1.0, 0.0, 0.0); + float3 tangentX = normalize(cross(up, normal)); + float3 tangentY = normalize(cross(normal, tangentX)); + + // Convert to world Space + return normalize(tangentX * H.x + tangentY * H.y + normal * H.z); +} + +// Geometric Shadowing function +float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness) +{ + float k = (roughness * roughness) / 2.0; + float GL = dotNL / (dotNL * (1.0 - k) + k); + float GV = dotNV / (dotNV * (1.0 - k) + k); + return GL * GV; +} + +float2 BRDF(float NoV, float roughness) +{ + // Normal always points along z-axis for the 2D lookup + const float3 N = float3(0.0, 0.0, 1.0); + float3 V = float3(sqrt(1.0 - NoV*NoV), 0.0, NoV); + + float2 LUT = float2(0.0, 0.0); + for(uint i = 0u; i < NUM_SAMPLES; i++) { + float2 Xi = hammersley2d(i, NUM_SAMPLES); + float3 H = importanceSample_GGX(Xi, roughness, N); + float3 L = 2.0 * dot(V, H) * H - V; + + float dotNL = max(dot(N, L), 0.0); + float dotNV = max(dot(N, V), 0.0); + float dotVH = max(dot(V, H), 0.0); + float dotNH = max(dot(H, N), 0.0); + + if (dotNL > 0.0) { + float G = G_SchlicksmithGGX(dotNL, dotNV, roughness); + float G_Vis = (G * dotVH) / (dotNH * dotNV); + float Fc = pow(1.0 - dotVH, 5.0); + LUT += float2((1.0 - Fc) * G_Vis, Fc * G_Vis); + } + } + return LUT / float(NUM_SAMPLES); +} + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return float4(BRDF(input.UV.x, input.UV.y), 0.0, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/pbribl/irradiancecube.slang b/shaders/slang/pbribl/irradiancecube.slang new file mode 100644 index 00000000..31cc96ea --- /dev/null +++ b/shaders/slang/pbribl/irradiancecube.slang @@ -0,0 +1,39 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +SamplerCube samplerEnv; + +struct PushConsts { + [[vk::offset(64)]] float deltaPhi; + [[vk::offset(68)]] float deltaTheta; +}; +[[vk::push_constant]] PushConsts consts; + +#define PI 3.1415926535897932384626433832795 + +[shader("fragment")] +float4 fragmentMain(float3 inPos) +{ + float3 N = normalize(inPos.xyz); + float3 up = float3(0.0, 1.0, 0.0); + float3 right = normalize(cross(up, N)); + up = cross(N, right); + + const float TWO_PI = PI * 2.0; + const float HALF_PI = PI * 0.5; + + float3 color = float3(0.0, 0.0, 0.0); + uint sampleCount = 0u; + for (float phi = 0.0; phi < TWO_PI; phi += consts.deltaPhi) { + for (float theta = 0.0; theta < HALF_PI; theta += consts.deltaTheta) { + float3 tempVec = cos(phi) * right + sin(phi) * up; + float3 sampleVector = cos(theta) * N + sin(theta) * tempVec; + color += samplerEnv.Sample(sampleVector).rgb * cos(theta) * sin(theta); + sampleCount++; + } + } + return float4(PI * color / float(sampleCount), 1.0); +} diff --git a/shaders/slang/pbribl/pbribl.slang b/shaders/slang/pbribl/pbribl.slang new file mode 100644 index 00000000..6ced37ff --- /dev/null +++ b/shaders/slang/pbribl/pbribl.slang @@ -0,0 +1,193 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 WorldPos; + float3 Normal; + float2 UV; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; + float3 camPos; +}; +ConstantBuffer ubo; + +struct UBOParams { + float4 lights[4]; + float exposure; + float gamma; +}; +ConstantBuffer uboParams; + +SamplerCube samplerIrradiance; +Sampler2D samplerBRDFLUT; +SamplerCube prefilteredMapSampler; + +struct Material { + [[vk::offset(12)]] float roughness; + [[vk::offset(16)]] float metallic; + [[vk::offset(20)]] float specular; + [[vk::offset(24)]] float r; + [[vk::offset(28)]] float g; + [[vk::offset(32)]] float b; +}; +[[vk::push_constant]] Material material; + +#define PI 3.1415926535897932384626433832795 +#define ALBEDO float3(material.r, material.g, material.b) + +// From http://filmicgames.com/archives/75 +float3 Uncharted2Tonemap(float3 x) +{ + float A = 0.15; + float B = 0.50; + float C = 0.10; + float D = 0.20; + float E = 0.02; + float F = 0.30; + return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F; +} + +// Normal Distribution function -------------------------------------- +float D_GGX(float dotNH, float roughness) +{ + float alpha = roughness * roughness; + float alpha2 = alpha * alpha; + float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0; + return (alpha2)/(PI * denom*denom); +} + +// Geometric Shadowing function -------------------------------------- +float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness) +{ + float r = (roughness + 1.0); + float k = (r*r) / 8.0; + float GL = dotNL / (dotNL * (1.0 - k) + k); + float GV = dotNV / (dotNV * (1.0 - k) + k); + return GL * GV; +} + +// Fresnel function ---------------------------------------------------- +float3 F_Schlick(float cosTheta, float3 F0) +{ + return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); +} +float3 F_SchlickR(float cosTheta, float3 F0, float roughness) +{ + return F0 + (max((1.0 - roughness).xxx, F0) - F0) * pow(1.0 - cosTheta, 5.0); +} + +float3 prefilteredReflection(float3 R, float roughness) +{ + const float MAX_REFLECTION_LOD = 9.0; // todo: param/const + float lod = roughness * MAX_REFLECTION_LOD; + float lodf = floor(lod); + float lodc = ceil(lod); + float3 a = prefilteredMapSampler.SampleLevel(R, lodf).rgb; + float3 b = prefilteredMapSampler.SampleLevel(R, lodc).rgb; + return lerp(a, b, lod - lodf); +} + +float3 specularContribution(float3 L, float3 V, float3 N, float3 F0, float metallic, float roughness) +{ + // Precalculate vectors and dot products + float3 H = normalize (V + L); + float dotNH = clamp(dot(N, H), 0.0, 1.0); + float dotNV = clamp(dot(N, V), 0.0, 1.0); + float dotNL = clamp(dot(N, L), 0.0, 1.0); + + // Light color fixed + float3 lightColor = float3(1.0, 1.0, 1.0); + + float3 color = float3(0.0, 0.0, 0.0); + + if (dotNL > 0.0) { + // D = Normal distribution (Distribution of the microfacets) + float D = D_GGX(dotNH, roughness); + // G = Geometric shadowing term (Microfacets shadowing) + float G = G_SchlicksmithGGX(dotNL, dotNV, roughness); + // F = Fresnel factor (Reflectance depending on angle of incidence) + float3 F = F_Schlick(dotNV, F0); + float3 spec = D * F * G / (4.0 * dotNL * dotNV + 0.001); + float3 kD = (float3(1.0, 1.0, 1.0) - F) * (1.0 - metallic); + color += (kD * ALBEDO / PI + spec) * dotNL; + } + + return color; +} + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform float3 objPos) +{ + VSOutput output; + float3 locPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + output.WorldPos = locPos + objPos; + output.Normal = mul((float3x3)ubo.model, input.Normal); + output.UV = input.UV; + output.UV.y = 1.0 - input.UV.y; + output.Pos = mul(ubo.projection, mul(ubo.view, float4(output.WorldPos, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 N = normalize(input.Normal); + float3 V = normalize(ubo.camPos - input.WorldPos); + float3 R = reflect(-V, N); + + float metallic = material.metallic; + float roughness = material.roughness; + + float3 F0 = float3(0.04, 0.04, 0.04); + F0 = lerp(F0, ALBEDO, metallic); + + float3 Lo = float3(0.0, 0.0, 0.0); + for(int i = 0; i < 4; i++) { + float3 L = normalize(uboParams.lights[i].xyz - input.WorldPos); + Lo += specularContribution(L, V, N, F0, metallic, roughness); + } + + float2 brdf = samplerBRDFLUT.Sample(float2(max(dot(N, V), 0.0), roughness)).rg; + float3 reflection = prefilteredReflection(R, roughness).rgb; + float3 irradiance = samplerIrradiance.Sample(N).rgb; + + // Diffuse based on irradiance + float3 diffuse = irradiance * ALBEDO; + + float3 F = F_SchlickR(max(dot(N, V), 0.0), F0, roughness); + + // Specular reflectance + float3 specular = reflection * (F * brdf.x + brdf.y); + + // Ambient part + float3 kD = 1.0 - F; + kD *= 1.0 - metallic; + float3 ambient = (kD * diffuse + specular); + + float3 color = ambient + Lo; + + // Tone mapping + color = Uncharted2Tonemap(color * uboParams.exposure); + color = color * (1.0f / Uncharted2Tonemap((11.2f).xxx)); + // Gamma correction + color = pow(color, (1.0f / uboParams.gamma).xxx); + + return float4(color, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/pbribl/prefilterenvmap.slang b/shaders/slang/pbribl/prefilterenvmap.slang new file mode 100644 index 00000000..d33cd37c --- /dev/null +++ b/shaders/slang/pbribl/prefilterenvmap.slang @@ -0,0 +1,109 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +SamplerCube samplerEnv; + +struct PushConsts { + [[vk::offset(64)]] float roughness; + [[vk::offset(68)]] uint numSamples; +}; +[[vk::push_constant]] PushConsts consts; + +#define PI 3.1415926536 + +// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ +float random(float2 co) +{ + float a = 12.9898; + float b = 78.233; + float c = 43758.5453; + float dt= dot(co.xy ,float2(a,b)); + float sn= fmod(dt,3.14); + return frac(sin(sn) * c); +} + +float2 hammersley2d(uint i, uint N) +{ + // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html + uint bits = (i << 16u) | (i >> 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); + float rdi = float(bits) * 2.3283064365386963e-10; + return float2(float(i) /float(N), rdi); +} + +// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf +float3 importanceSample_GGX(float2 Xi, float roughness, float3 normal) +{ + // Maps a 2D point to a hemisphere with spread based on roughness + float alpha = roughness * roughness; + float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1; + float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y)); + float sinTheta = sqrt(1.0 - cosTheta * cosTheta); + float3 H = float3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta); + + // Tangent space + float3 up = abs(normal.z) < 0.999 ? float3(0.0, 0.0, 1.0) : float3(1.0, 0.0, 0.0); + float3 tangentX = normalize(cross(up, normal)); + float3 tangentY = normalize(cross(normal, tangentX)); + + // Convert to world Space + return normalize(tangentX * H.x + tangentY * H.y + normal * H.z); +} + +// Normal Distribution function +float D_GGX(float dotNH, float roughness) +{ + float alpha = roughness * roughness; + float alpha2 = alpha * alpha; + float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0; + return (alpha2)/(PI * denom*denom); +} + +float3 prefilterEnvMap(float3 R, float roughness) +{ + float3 N = R; + float3 V = R; + float3 color = float3(0.0, 0.0, 0.0); + float totalWeight = 0.0; + int2 envMapDims; + samplerEnv.GetDimensions(envMapDims.x, envMapDims.y); + float envMapDim = float(envMapDims.x); + for(uint i = 0u; i < consts.numSamples; i++) { + float2 Xi = hammersley2d(i, consts.numSamples); + float3 H = importanceSample_GGX(Xi, roughness, N); + float3 L = 2.0 * dot(V, H) * H - V; + float dotNL = clamp(dot(N, L), 0.0, 1.0); + if(dotNL > 0.0) { + // Filtering based on https://placeholderart.wordpress.com/2015/07/28/implementation-notes-runtime-environment-map-filtering-for-image-based-lighting/ + + float dotNH = clamp(dot(N, H), 0.0, 1.0); + float dotVH = clamp(dot(V, H), 0.0, 1.0); + + // Probability Distribution Function + float pdf = D_GGX(dotNH, roughness) * dotNH / (4.0 * dotVH) + 0.0001; + // Slid angle of current smple + float omegaS = 1.0 / (float(consts.numSamples) * pdf); + // Solid angle of 1 pixel across all cube faces + float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim); + // Biased (+1.0) mip level for better result + float mipLevel = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f); + color += samplerEnv.SampleLevel(L, mipLevel).rgb * dotNL; + totalWeight += dotNL; + + } + } + return (color / totalWeight); +} + +[shader("fragment")] +float4 fragmentMain(float3 inPos) +{ + float3 N = normalize(inPos.xyz); + return float4(prefilterEnvMap(N, consts.roughness), 1.0); +} diff --git a/shaders/slang/pbribl/skybox.slang b/shaders/slang/pbribl/skybox.slang new file mode 100644 index 00000000..809fedab --- /dev/null +++ b/shaders/slang/pbribl/skybox.slang @@ -0,0 +1,70 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 UVW; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; +ConstantBuffer ubo; + +struct UBOParams { + float4 lights[4]; + float exposure; + float gamma; +}; +ConstantBuffer uboParams; + +SamplerCube samplerEnv; + +// From http://filmicworlds.com/blog/filmic-tonemapping-operators/ +float3 Uncharted2Tonemap(float3 color) +{ + float A = 0.15; + float B = 0.50; + float C = 0.10; + float D = 0.20; + float E = 0.02; + float F = 0.30; + float W = 11.2; + return ((color*(A*color+C*B)+D*E)/(color*(A*color+B)+D*F))-E/F; +} + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UVW = input.Pos; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 color = samplerEnv.Sample(input.UVW).rgb; + + // Tone mapping + color = Uncharted2Tonemap(color * uboParams.exposure); + color = color * (1.0f / Uncharted2Tonemap((11.2f).xxx)); + // Gamma correction + color = pow(color, (1.0f / uboParams.gamma).xxx); + + return float4(color, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/pbrtexture/filtercube.slang b/shaders/slang/pbrtexture/filtercube.slang new file mode 100644 index 00000000..6c848459 --- /dev/null +++ b/shaders/slang/pbrtexture/filtercube.slang @@ -0,0 +1,25 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 UVW; +}; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform float4x4 mvp) +{ + VSOutput output; + output.UVW = input.Pos; + output.Pos = mul(mvp, float4(input.Pos.xyz, 1.0)); + return output; +} diff --git a/shaders/slang/pbrtexture/genbrdflut.slang b/shaders/slang/pbrtexture/genbrdflut.slang new file mode 100644 index 00000000..b40d7b16 --- /dev/null +++ b/shaders/slang/pbrtexture/genbrdflut.slang @@ -0,0 +1,108 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + + struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +[[SpecializationConstant]] const uint NUM_SAMPLES = 1024u; + +#define PI 3.1415926536 + +// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ +float random(float2 co) +{ + float a = 12.9898; + float b = 78.233; + float c = 43758.5453; + float dt= dot(co.xy ,float2(a,b)); + float sn= fmod(dt,3.14); + return frac(sin(sn) * c); +} + +float2 hammersley2d(uint i, uint N) +{ + // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html + uint bits = (i << 16u) | (i >> 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); + float rdi = float(bits) * 2.3283064365386963e-10; + return float2(float(i) /float(N), rdi); +} + +// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf +float3 importanceSample_GGX(float2 Xi, float roughness, float3 normal) +{ + // Maps a 2D point to a hemisphere with spread based on roughness + float alpha = roughness * roughness; + float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1; + float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y)); + float sinTheta = sqrt(1.0 - cosTheta * cosTheta); + float3 H = float3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta); + + // Tangent space + float3 up = abs(normal.z) < 0.999 ? float3(0.0, 0.0, 1.0) : float3(1.0, 0.0, 0.0); + float3 tangentX = normalize(cross(up, normal)); + float3 tangentY = normalize(cross(normal, tangentX)); + + // Convert to world Space + return normalize(tangentX * H.x + tangentY * H.y + normal * H.z); +} + +// Geometric Shadowing function +float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness) +{ + float k = (roughness * roughness) / 2.0; + float GL = dotNL / (dotNL * (1.0 - k) + k); + float GV = dotNV / (dotNV * (1.0 - k) + k); + return GL * GV; +} + +float2 BRDF(float NoV, float roughness) +{ + // Normal always points along z-axis for the 2D lookup + const float3 N = float3(0.0, 0.0, 1.0); + float3 V = float3(sqrt(1.0 - NoV*NoV), 0.0, NoV); + + float2 LUT = float2(0.0, 0.0); + for(uint i = 0u; i < NUM_SAMPLES; i++) { + float2 Xi = hammersley2d(i, NUM_SAMPLES); + float3 H = importanceSample_GGX(Xi, roughness, N); + float3 L = 2.0 * dot(V, H) * H - V; + + float dotNL = max(dot(N, L), 0.0); + float dotNV = max(dot(N, V), 0.0); + float dotVH = max(dot(V, H), 0.0); + float dotNH = max(dot(H, N), 0.0); + + if (dotNL > 0.0) { + float G = G_SchlicksmithGGX(dotNL, dotNV, roughness); + float G_Vis = (G * dotVH) / (dotNH * dotNV); + float Fc = pow(1.0 - dotVH, 5.0); + LUT += float2((1.0 - Fc) * G_Vis, Fc * G_Vis); + } + } + return LUT / float(NUM_SAMPLES); +} + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return float4(BRDF(input.UV.x, input.UV.y), 0.0, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/pbrtexture/irradiancecube.slang b/shaders/slang/pbrtexture/irradiancecube.slang new file mode 100644 index 00000000..31cc96ea --- /dev/null +++ b/shaders/slang/pbrtexture/irradiancecube.slang @@ -0,0 +1,39 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +SamplerCube samplerEnv; + +struct PushConsts { + [[vk::offset(64)]] float deltaPhi; + [[vk::offset(68)]] float deltaTheta; +}; +[[vk::push_constant]] PushConsts consts; + +#define PI 3.1415926535897932384626433832795 + +[shader("fragment")] +float4 fragmentMain(float3 inPos) +{ + float3 N = normalize(inPos.xyz); + float3 up = float3(0.0, 1.0, 0.0); + float3 right = normalize(cross(up, N)); + up = cross(N, right); + + const float TWO_PI = PI * 2.0; + const float HALF_PI = PI * 0.5; + + float3 color = float3(0.0, 0.0, 0.0); + uint sampleCount = 0u; + for (float phi = 0.0; phi < TWO_PI; phi += consts.deltaPhi) { + for (float theta = 0.0; theta < HALF_PI; theta += consts.deltaTheta) { + float3 tempVec = cos(phi) * right + sin(phi) * up; + float3 sampleVector = cos(theta) * N + sin(theta) * tempVec; + color += samplerEnv.Sample(sampleVector).rgb * cos(theta) * sin(theta); + sampleCount++; + } + } + return float4(PI * color / float(sampleCount), 1.0); +} diff --git a/shaders/slang/pbrtexture/pbrtexture.slang b/shaders/slang/pbrtexture/pbrtexture.slang new file mode 100644 index 00000000..0d7bbef0 --- /dev/null +++ b/shaders/slang/pbrtexture/pbrtexture.slang @@ -0,0 +1,198 @@ +// Copyright 2020 Google LLC + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; + float4 Tangent; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 WorldPos; + float3 Normal; + float2 UV; + float3 Tangent; +}; + +struct UBO { + float4x4 projection; + float4x4 model; + float4x4 view; + float3 camPos; +}; +ConstantBuffer ubo; + +struct UBOParams { + float4 lights[4]; + float exposure; + float gamma; +}; +ConstantBuffer uboParams; + +SamplerCube samplerIrradiance; +Sampler2D samplerBRDFLUT; +SamplerCube prefilteredMapSampler; + +Sampler2D albedoMapSampler; +Sampler2D normalMapSampler; +Sampler2D aoMapSampler; +Sampler2D metallicMapSampler; +Sampler2D roughnessMapSampler; + +#define PI 3.1415926535897932384626433832795 +#define ALBEDO(uv) pow(albedoMapSampler.Sample(uv).rgb, float3(2.2, 2.2, 2.2)) + +// From http://filmicgames.com/archives/75 +float3 Uncharted2Tonemap(float3 x) +{ + float A = 0.15; + float B = 0.50; + float C = 0.10; + float D = 0.20; + float E = 0.02; + float F = 0.30; + return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F; +} + +// Normal Distribution function -------------------------------------- +float D_GGX(float dotNH, float roughness) +{ + float alpha = roughness * roughness; + float alpha2 = alpha * alpha; + float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0; + return (alpha2)/(PI * denom*denom); +} + +// Geometric Shadowing function -------------------------------------- +float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness) +{ + float r = (roughness + 1.0); + float k = (r*r) / 8.0; + float GL = dotNL / (dotNL * (1.0 - k) + k); + float GV = dotNV / (dotNV * (1.0 - k) + k); + return GL * GV; +} + +// Fresnel function ---------------------------------------------------- +float3 F_Schlick(float cosTheta, float3 F0) +{ + return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); +} +float3 F_SchlickR(float cosTheta, float3 F0, float roughness) +{ + return F0 + (max((1.0 - roughness).xxx, F0) - F0) * pow(1.0 - cosTheta, 5.0); +} + +float3 prefilteredReflection(float3 R, float roughness) +{ + const float MAX_REFLECTION_LOD = 9.0; // todo: param/const + float lod = roughness * MAX_REFLECTION_LOD; + float lodf = floor(lod); + float lodc = ceil(lod); + float3 a = prefilteredMapSampler.SampleLevel(R, lodf).rgb; + float3 b = prefilteredMapSampler.SampleLevel(R, lodc).rgb; + return lerp(a, b, lod - lodf); +} + +float3 specularContribution(float2 inUV, float3 L, float3 V, float3 N, float3 F0, float metallic, float roughness) +{ + // Precalculate vectors and dot products + float3 H = normalize (V + L); + float dotNH = clamp(dot(N, H), 0.0, 1.0); + float dotNV = clamp(dot(N, V), 0.0, 1.0); + float dotNL = clamp(dot(N, L), 0.0, 1.0); + + // Light color fixed + float3 lightColor = float3(1.0, 1.0, 1.0); + + float3 color = float3(0.0, 0.0, 0.0); + + if (dotNL > 0.0) { + // D = Normal distribution (Distribution of the microfacets) + float D = D_GGX(dotNH, roughness); + // G = Geometric shadowing term (Microfacets shadowing) + float G = G_SchlicksmithGGX(dotNL, dotNV, roughness); + // F = Fresnel factor (Reflectance depending on angle of incidence) + float3 F = F_Schlick(dotNV, F0); + float3 spec = D * F * G / (4.0 * dotNL * dotNV + 0.001); + float3 kD = (float3(1.0, 1.0, 1.0) - F) * (1.0 - metallic); + color += (kD * ALBEDO(inUV) / PI + spec) * dotNL; + } + + return color; +} + +float3 calculateNormal(VSOutput input) +{ + float3 tangentNormal = normalMapSampler.Sample(input.UV).xyz * 2.0 - 1.0; + + float3 N = normalize(input.Normal); + float3 T = normalize(input.Tangent); + float3 B = normalize(cross(N, T)); + float3x3 TBN = transpose(float3x3(T, B, N)); + + return normalize(mul(TBN, tangentNormal)); +} + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + float3 locPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + output.WorldPos = locPos; + output.Normal = mul((float3x3)ubo.model, input.Normal); + output.Tangent = mul((float3x3)ubo.model, input.Tangent.xyz); + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.view, float4(output.WorldPos, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 N = calculateNormal(input); + float3 V = normalize(ubo.camPos - input.WorldPos); + float3 R = reflect(-V, N); + + float metallic = metallicMapSampler.Sample(input.UV).r; + float roughness = roughnessMapSampler.Sample(input.UV).r; + + float3 F0 = float3(0.04, 0.04, 0.04); + F0 = lerp(F0, ALBEDO(input.UV), metallic); + + float3 Lo = float3(0.0, 0.0, 0.0); + for(int i = 0; i < 4; i++) { + float3 L = normalize(uboParams.lights[i].xyz - input.WorldPos); + Lo += specularContribution(input.UV, L, V, N, F0, metallic, roughness); + } + + float2 brdf = samplerBRDFLUT.Sample(float2(max(dot(N, V), 0.0), roughness)).rg; + float3 reflection = prefilteredReflection(R, roughness).rgb; + float3 irradiance = samplerIrradiance.Sample(N).rgb; + + // Diffuse based on irradiance + float3 diffuse = irradiance * ALBEDO(input.UV); + + float3 F = F_SchlickR(max(dot(N, V), 0.0), F0, roughness); + + // Specular reflectance + float3 specular = reflection * (F * brdf.x + brdf.y); + + // Ambient part + float3 kD = 1.0 - F; + kD *= 1.0 - metallic; + float3 ambient = (kD * diffuse + specular) * aoMapSampler.Sample(input.UV).rrr; + + float3 color = ambient + Lo; + + // Tone mapping + color = Uncharted2Tonemap(color * uboParams.exposure); + color = color * (1.0f / Uncharted2Tonemap((11.2f).xxx)); + // Gamma correction + color = pow(color, (1.0f / uboParams.gamma).xxx); + + return float4(color, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/pbrtexture/prefilterenvmap.slang b/shaders/slang/pbrtexture/prefilterenvmap.slang new file mode 100644 index 00000000..d33cd37c --- /dev/null +++ b/shaders/slang/pbrtexture/prefilterenvmap.slang @@ -0,0 +1,109 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +SamplerCube samplerEnv; + +struct PushConsts { + [[vk::offset(64)]] float roughness; + [[vk::offset(68)]] uint numSamples; +}; +[[vk::push_constant]] PushConsts consts; + +#define PI 3.1415926536 + +// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ +float random(float2 co) +{ + float a = 12.9898; + float b = 78.233; + float c = 43758.5453; + float dt= dot(co.xy ,float2(a,b)); + float sn= fmod(dt,3.14); + return frac(sin(sn) * c); +} + +float2 hammersley2d(uint i, uint N) +{ + // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html + uint bits = (i << 16u) | (i >> 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); + float rdi = float(bits) * 2.3283064365386963e-10; + return float2(float(i) /float(N), rdi); +} + +// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf +float3 importanceSample_GGX(float2 Xi, float roughness, float3 normal) +{ + // Maps a 2D point to a hemisphere with spread based on roughness + float alpha = roughness * roughness; + float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1; + float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y)); + float sinTheta = sqrt(1.0 - cosTheta * cosTheta); + float3 H = float3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta); + + // Tangent space + float3 up = abs(normal.z) < 0.999 ? float3(0.0, 0.0, 1.0) : float3(1.0, 0.0, 0.0); + float3 tangentX = normalize(cross(up, normal)); + float3 tangentY = normalize(cross(normal, tangentX)); + + // Convert to world Space + return normalize(tangentX * H.x + tangentY * H.y + normal * H.z); +} + +// Normal Distribution function +float D_GGX(float dotNH, float roughness) +{ + float alpha = roughness * roughness; + float alpha2 = alpha * alpha; + float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0; + return (alpha2)/(PI * denom*denom); +} + +float3 prefilterEnvMap(float3 R, float roughness) +{ + float3 N = R; + float3 V = R; + float3 color = float3(0.0, 0.0, 0.0); + float totalWeight = 0.0; + int2 envMapDims; + samplerEnv.GetDimensions(envMapDims.x, envMapDims.y); + float envMapDim = float(envMapDims.x); + for(uint i = 0u; i < consts.numSamples; i++) { + float2 Xi = hammersley2d(i, consts.numSamples); + float3 H = importanceSample_GGX(Xi, roughness, N); + float3 L = 2.0 * dot(V, H) * H - V; + float dotNL = clamp(dot(N, L), 0.0, 1.0); + if(dotNL > 0.0) { + // Filtering based on https://placeholderart.wordpress.com/2015/07/28/implementation-notes-runtime-environment-map-filtering-for-image-based-lighting/ + + float dotNH = clamp(dot(N, H), 0.0, 1.0); + float dotVH = clamp(dot(V, H), 0.0, 1.0); + + // Probability Distribution Function + float pdf = D_GGX(dotNH, roughness) * dotNH / (4.0 * dotVH) + 0.0001; + // Slid angle of current smple + float omegaS = 1.0 / (float(consts.numSamples) * pdf); + // Solid angle of 1 pixel across all cube faces + float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim); + // Biased (+1.0) mip level for better result + float mipLevel = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f); + color += samplerEnv.SampleLevel(L, mipLevel).rgb * dotNL; + totalWeight += dotNL; + + } + } + return (color / totalWeight); +} + +[shader("fragment")] +float4 fragmentMain(float3 inPos) +{ + float3 N = normalize(inPos.xyz); + return float4(prefilterEnvMap(N, consts.roughness), 1.0); +} diff --git a/shaders/slang/pbrtexture/skybox.slang b/shaders/slang/pbrtexture/skybox.slang new file mode 100644 index 00000000..809fedab --- /dev/null +++ b/shaders/slang/pbrtexture/skybox.slang @@ -0,0 +1,70 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 UVW; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; +ConstantBuffer ubo; + +struct UBOParams { + float4 lights[4]; + float exposure; + float gamma; +}; +ConstantBuffer uboParams; + +SamplerCube samplerEnv; + +// From http://filmicworlds.com/blog/filmic-tonemapping-operators/ +float3 Uncharted2Tonemap(float3 color) +{ + float A = 0.15; + float B = 0.50; + float C = 0.10; + float D = 0.20; + float E = 0.02; + float F = 0.30; + float W = 11.2; + return ((color*(A*color+C*B)+D*E)/(color*(A*color+B)+D*F))-E/F; +} + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UVW = input.Pos; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 color = samplerEnv.Sample(input.UVW).rgb; + + // Tone mapping + color = Uncharted2Tonemap(color * uboParams.exposure); + color = color * (1.0f / Uncharted2Tonemap((11.2f).xxx)); + // Gamma correction + color = pow(color, (1.0f / uboParams.gamma).xxx); + + return float4(color, 1.0); +} \ No newline at end of file From 7c115af4a33c4649da855519bae08f7bc9412997 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 4 May 2025 17:23:23 +0200 Subject: [PATCH 38/73] Add slang shaders for additional samples --- shaders/slang/imgui/scene.slang | 57 ++++++++ shaders/slang/imgui/ui.slang | 37 +++++ shaders/slang/indirectdraw/ground.slang | 44 ++++++ shaders/slang/indirectdraw/indirectdraw.slang | 104 +++++++++++++ shaders/slang/indirectdraw/skysphere.slang | 42 ++++++ shaders/slang/inlineuniformblocks/pbr.slang | 137 ++++++++++++++++++ .../inputattachments/attachmentread.slang | 52 +++++++ .../inputattachments/attachmentwrite.slang | 56 +++++++ 8 files changed, 529 insertions(+) create mode 100644 shaders/slang/imgui/scene.slang create mode 100644 shaders/slang/imgui/ui.slang create mode 100644 shaders/slang/indirectdraw/ground.slang create mode 100644 shaders/slang/indirectdraw/indirectdraw.slang create mode 100644 shaders/slang/indirectdraw/skysphere.slang create mode 100644 shaders/slang/inlineuniformblocks/pbr.slang create mode 100644 shaders/slang/inputattachments/attachmentread.slang create mode 100644 shaders/slang/inputattachments/attachmentwrite.slang diff --git a/shaders/slang/imgui/scene.slang b/shaders/slang/imgui/scene.slang new file mode 100644 index 00000000..5757b95c --- /dev/null +++ b/shaders/slang/imgui/scene.slang @@ -0,0 +1,57 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Normal = input.Normal; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float4x3)ubo.model, input.Normal).xyz; + float3 lPos = mul((float4x3)ubo.model, ubo.lightPos.xyz).xyz; + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float diffuse = max(dot(N, L), 0.0); + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + return float4(diffuse * input.Color + specular, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/imgui/ui.slang b/shaders/slang/imgui/ui.slang new file mode 100644 index 00000000..603799e4 --- /dev/null +++ b/shaders/slang/imgui/ui.slang @@ -0,0 +1,37 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float2 Pos; + float2 UV; + float4 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; + float4 Color; +}; + +Sampler2D fontSampler; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform float2 scale, uniform float2 translate) +{ + VSOutput output; + output.UV = input.UV; + output.Color = input.Color; + output.Pos = float4(input.Pos * scale + translate, 0.0, 1.0); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return input.Color * fontSampler.Sample(input.UV); +} \ No newline at end of file diff --git a/shaders/slang/indirectdraw/ground.slang b/shaders/slang/indirectdraw/ground.slang new file mode 100644 index 00000000..ac8624ac --- /dev/null +++ b/shaders/slang/indirectdraw/ground.slang @@ -0,0 +1,44 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float3 Normal; + float2 UV; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; +}; +ConstantBuffer ubo; + +[[vk::binding(2,0)]] Sampler2D samplerColor; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UV = input.UV * 32.0; + output.Pos = mul(ubo.projection, mul(ubo.modelview, float4(input.Pos.xyz, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float4 color = samplerColor.Sample(input.UV); + return float4(color.rgb, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/indirectdraw/indirectdraw.slang b/shaders/slang/indirectdraw/indirectdraw.slang new file mode 100644 index 00000000..8c35d5e4 --- /dev/null +++ b/shaders/slang/indirectdraw/indirectdraw.slang @@ -0,0 +1,104 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float3 Normal; + float2 UV; + float3 Color; + float3 instancePos; + float3 instanceRot; + float instanceScale; + int instanceTexIndex; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 UV; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; +}; +ConstantBuffer ubo; + +Sampler2DArray samplerArray; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.UV = float3(input.UV, input.instanceTexIndex); + + float4x4 mx, my, mz; + + // rotate around x + float s = sin(input.instanceRot.x); + float c = cos(input.instanceRot.x); + + mx[0] = float4(c, s, 0.0, 0.0); + mx[1] = float4(-s, c, 0.0, 0.0); + mx[2] = float4(0.0, 0.0, 1.0, 0.0); + mx[3] = float4(0.0, 0.0, 0.0, 1.0); + + // rotate around y + s = sin(input.instanceRot.y); + c = cos(input.instanceRot.y); + + my[0] = float4(c, 0.0, s, 0.0); + my[1] = float4(0.0, 1.0, 0.0, 0.0); + my[2] = float4(-s, 0.0, c, 0.0); + my[3] = float4(0.0, 0.0, 0.0, 1.0); + + // rot around z + s = sin(input.instanceRot.z); + c = cos(input.instanceRot.z); + + mz[0] = float4(1.0, 0.0, 0.0, 0.0); + mz[1] = float4(0.0, c, s, 0.0); + mz[2] = float4(0.0, -s, c, 0.0); + mz[3] = float4(0.0, 0.0, 0.0, 1.0); + + float4x4 rotMat = mul(mz, mul(my, mx)); + + output.Normal = mul((float4x3)rotMat, input.Normal).xyz; + + float4 pos = mul(rotMat, float4((input.Pos.xyz * input.instanceScale) + input.instancePos, 1.0)); + + output.Pos = mul(ubo.projection, mul(ubo.modelview, pos)); + + float4 wPos = mul(ubo.modelview, float4(pos.xyz, 1.0)); + float4 lPos = float4(0.0, -5.0, 0.0, 1.0); + output.LightVec = lPos.xyz - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float4 color = samplerArray.Sample(input.UV); + + if (color.a < 0.5) + { + clip(-1); + } + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 ambient = float3(0.65, 0.65, 0.65); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + return float4((ambient + diffuse) * color.rgb, 1.0); +} diff --git a/shaders/slang/indirectdraw/skysphere.slang b/shaders/slang/indirectdraw/skysphere.slang new file mode 100644 index 00000000..6bf4679e --- /dev/null +++ b/shaders/slang/indirectdraw/skysphere.slang @@ -0,0 +1,42 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UV = input.UV; + // Skysphere always at center, only use rotation part of modelview matrix + output.Pos = mul(ubo.projection, float4(mul((float3x3)ubo.modelview, input.Pos.xyz), 1)); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + const float4 gradientStart = float4(0.93, 0.9, 0.81, 1.0); + const float4 gradientEnd = float4(0.35, 0.5, 1.0, 1.0); + return lerp(gradientStart, gradientEnd, min(0.5 - (input.UV.y + 0.05), 0.5)/0.15 - 0.5); +} \ No newline at end of file diff --git a/shaders/slang/inlineuniformblocks/pbr.slang b/shaders/slang/inlineuniformblocks/pbr.slang new file mode 100644 index 00000000..825d4902 --- /dev/null +++ b/shaders/slang/inlineuniformblocks/pbr.slang @@ -0,0 +1,137 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 WorldPos; + float3 Normal; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; + float3 camPos; +}; +ConstantBuffer ubo; + +// Inline uniform block +struct UniformInline { + float roughness; + float metallic; + float r; + float g; + float b; + float ambient; +}; +[[vk::binding(0,1)]] ConstantBuffer material; + +#define PI 3.14159265359 +#define MATERIALCOLOR float3(material.r, material.g, material.b) + +// Normal Distribution function -------------------------------------- +float D_GGX(float dotNH, float roughness) +{ + float alpha = roughness * roughness; + float alpha2 = alpha * alpha; + float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0; + return (alpha2)/(PI * denom*denom); +} + +// Geometric Shadowing function -------------------------------------- +float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness) +{ + float r = (roughness + 1.0); + float k = (r*r) / 8.0; + float GL = dotNL / (dotNL * (1.0 - k) + k); + float GV = dotNV / (dotNV * (1.0 - k) + k); + return GL * GV; +} + +// Fresnel function ---------------------------------------------------- +float3 F_Schlick(float cosTheta, float metallic) +{ + float3 F0 = lerp(float3(0.04, 0.04, 0.04), MATERIALCOLOR, metallic); // * material.specular + float3 F = F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); + return F; +} + +// Specular BRDF composition -------------------------------------------- + +float3 BRDF(float3 L, float3 V, float3 N, float metallic, float roughness) +{ + // Precalculate vectors and dot products + float3 H = normalize (V + L); + float dotNV = clamp(dot(N, V), 0.0, 1.0); + float dotNL = clamp(dot(N, L), 0.0, 1.0); + float dotLH = clamp(dot(L, H), 0.0, 1.0); + float dotNH = clamp(dot(N, H), 0.0, 1.0); + + // Light color fixed + float3 lightColor = float3(1.0, 1.0, 1.0); + + float3 color = float3(0.0, 0.0, 0.0); + + if (dotNL > 0.0) + { + float rroughness = max(0.05, roughness); + // D = Normal distribution (Distribution of the microfacets) + float D = D_GGX(dotNH, rroughness); + // G = Geometric shadowing term (Microfacets shadowing) + float G = G_SchlicksmithGGX(dotNL, dotNV, rroughness); + // F = Fresnel factor (Reflectance depending on angle of incidence) + float3 F = F_Schlick(dotNV, metallic); + + float3 spec = D * F * G / (4.0 * dotNL * dotNV); + + color += spec * dotNL * lightColor; + } + + return color; +} + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform float3 objPos) +{ + VSOutput output; + float3 locPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + output.WorldPos = locPos + objPos; + output.Normal = mul((float4x3)ubo.model, input.Normal).xyz; + output.Pos = mul(ubo.projection, mul(ubo.view, float4(output.WorldPos, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 N = normalize(input.Normal); + float3 V = normalize(ubo.camPos - input.WorldPos); + + float roughness = material.roughness; + + // Specular contribution + float3 lightPos = float3(0.0f, 0.0f, 10.0f); + float3 Lo = float3(0.0, 0.0, 0.0); + float3 L = normalize(lightPos.xyz - input.WorldPos); + Lo += BRDF(L, V, N, material.metallic, roughness); + + // Combine with ambient + float3 color = MATERIALCOLOR * material.ambient; + color += Lo; + + // Gamma correct + color = pow(color, float3(0.4545, 0.4545, 0.4545)); + + return float4(color, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/inputattachments/attachmentread.slang b/shaders/slang/inputattachments/attachmentread.slang new file mode 100644 index 00000000..3612f1ca --- /dev/null +++ b/shaders/slang/inputattachments/attachmentread.slang @@ -0,0 +1,52 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSOutput +{ + float4 Pos : SV_POSITION; +}; + +[[vk::input_attachment_index(0)]] [[vk::binding(0)]] SubpassInput inputColor; +[[vk::input_attachment_index(1)]] [[vk::binding(1)]] SubpassInput inputDepth; + +struct UBO { + float2 brightnessContrast; + float2 range; + int attachmentIndex; +}; +ConstantBuffer ubo; + +float3 brightnessContrast(float3 color, float brightness, float contrast) { + return (color - 0.5) * contrast + 0.5 + brightness; +} + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.Pos = float4(float2((VertexIndex << 1) & 2, VertexIndex & 2) * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain() +{ + // Apply brightness and contrast filer to color input + if (ubo.attachmentIndex == 0) { + // Read color from previous color input attachment + float3 color = inputColor.SubpassLoad().rgb; + return float4(brightnessContrast(color, ubo.brightnessContrast[0], ubo.brightnessContrast[1]), 1.0); + } + + // Visualize depth input range + if (ubo.attachmentIndex == 1) { + // Read depth from previous depth input attachment + float depth = inputDepth.SubpassLoad().r; + return float4((depth - ubo.range[0]) * 1.0 / (ubo.range[1] - ubo.range[0]).xxx, 1.0); + } + + return float4(1.0); +} \ No newline at end of file diff --git a/shaders/slang/inputattachments/attachmentwrite.slang b/shaders/slang/inputattachments/attachmentwrite.slang new file mode 100644 index 00000000..e27e4e0e --- /dev/null +++ b/shaders/slang/inputattachments/attachmentwrite.slang @@ -0,0 +1,56 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Color; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Color; + float3 Normal; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO { + float4x4 projection; + float4x4 model; + float4x4 view; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos, 1.0)))); + output.Color = input.Color; + output.Normal = input.Normal; + output.LightVec = float3(0.0f, 5.0f, 15.0f) - input.Pos; + output.ViewVec = -input.Pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + // Toon shading color attachment output + float intensity = dot(normalize(input.Normal), normalize(input.LightVec)); + float shade = 1.0; + shade = intensity < 0.5 ? 0.75 : shade; + shade = intensity < 0.35 ? 0.6 : shade; + shade = intensity < 0.25 ? 0.5 : shade; + shade = intensity < 0.1 ? 0.25 : shade; + + return float4(input.Color * 3.0 * shade, 1.0); + + // Depth attachment does not need to be explicitly written +} \ No newline at end of file From dde011039eb0e17781eeb702efae5a53a22d0d22 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Mon, 5 May 2025 21:42:04 +0200 Subject: [PATCH 39/73] Always infer entry point name from list of stages --- shaders/slang/compileshaders.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shaders/slang/compileshaders.py b/shaders/slang/compileshaders.py index 5a6faf94..3f7f39ab 100644 --- a/shaders/slang/compileshaders.py +++ b/shaders/slang/compileshaders.py @@ -83,7 +83,7 @@ for root, dirs, files in os.walk(dir_path): print("Compiling %s" % input_file) output_base_file_name = input_file for stage in stages: - if (len(stages) > 1): + if (len(stages) > 0): entry_point = stage + "Main" else: entry_point = "main" From 150b51086872e992b38d5cdc92988c22500ebec4 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Thu, 8 May 2025 20:08:57 +0200 Subject: [PATCH 40/73] Add slang shaders for ray query sample --- shaders/slang/rayquery/scene.slang | 81 ++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 shaders/slang/rayquery/scene.slang diff --git a/shaders/slang/rayquery/scene.slang b/shaders/slang/rayquery/scene.slang new file mode 100644 index 00000000..5b061c62 --- /dev/null +++ b/shaders/slang/rayquery/scene.slang @@ -0,0 +1,81 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float2 UV; + float3 Color; + float3 Normal; +} + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 ViewVec; + float3 LightVec; + float3 WorldPos; +} + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float3 lightPos; +}; +ConstantBuffer ubo; + +RaytracingAccelerationStructure accelStruct; + +#define ambient 0.1 + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos.xyz, 1.0)))); + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.WorldPos = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + output.Normal = mul((float4x3)ubo.model, input.Normal).xyz; + output.LightVec = normalize(ubo.lightPos - input.Pos); + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = normalize(-reflect(L, N)); + float3 diffuse = max(dot(N, L), ambient) * input.Color; + + float4 color = float4(diffuse, 1.0); + + RayDesc rayDesc; + rayDesc.Origin = input.WorldPos; + rayDesc.Direction = L; + rayDesc.TMin = 0.01; + rayDesc.TMax = 1000.0; + + RayQuery rayQuery; + rayQuery.TraceRayInline(accelStruct, RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH, 0xFF, rayDesc); + + // Traverse the acceleration structure and store information about the first intersection (if any) + rayQuery.Proceed(); + + // If the intersection has hit a triangle, the fragment is shadowed + if (rayQuery.CommittedStatus() == COMMITTED_TRIANGLE_HIT) { + color *= 0.1; + } + + return color; +} From d0a20a693f40a1dc68723b59ca167800952ce009 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Fri, 9 May 2025 19:45:49 +0200 Subject: [PATCH 41/73] Add slang shaders for additional ray tracing samples --- .../raytracingintersection.slang | 96 ++++++++++++++ shaders/slang/raytracingshadows/payload.slang | 13 ++ .../raytracingshadows/raytracingshadows.slang | 117 ++++++++++++++++++ shaders/slang/raytracingshadows/shadow.slang | 14 +++ 4 files changed, 240 insertions(+) create mode 100644 shaders/slang/raytracingintersection/raytracingintersection.slang create mode 100644 shaders/slang/raytracingshadows/payload.slang create mode 100644 shaders/slang/raytracingshadows/raytracingshadows.slang create mode 100644 shaders/slang/raytracingshadows/shadow.slang diff --git a/shaders/slang/raytracingintersection/raytracingintersection.slang b/shaders/slang/raytracingintersection/raytracingintersection.slang new file mode 100644 index 00000000..43251132 --- /dev/null +++ b/shaders/slang/raytracingintersection/raytracingintersection.slang @@ -0,0 +1,96 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct Payload +{ + float3 hitValue; +} + +RaytracingAccelerationStructure accelStruct; +RWTexture2D image; + +struct UBO +{ + float4x4 viewInverse; + float4x4 projInverse; + float4 lightPos; +}; +ConstantBuffer ubo; + +struct Sphere { + float3 center; + float radius; + float4 color; +}; +StructuredBuffer spheres; + +// Ray-sphere intersection +// By Inigo Quilez, from https://iquilezles.org/articles/spherefunctions/ +float sphIntersect(const Sphere s, float3 ro, float3 rd) +{ + float3 oc = ro - s.center; + float b = dot(oc, rd); + float c = dot(oc, oc) - s.radius * s.radius; + float h = b * b - c; + if (h < 0.0) { + return -1.0; + } + h = sqrt(h); + return -b - h; +} + +[shader("intersection")] +void intersectionMain() { + Sphere sphere = spheres[PrimitiveIndex()]; + float hit = sphIntersect(sphere, WorldRayOrigin(), WorldRayDirection()); + + if (hit > 0) { + ReportHit(hit, 0, 0); + } +} + +[shader("raygeneration")] +void raygenerationMain() +{ + uint3 LaunchID = DispatchRaysIndex(); + uint3 LaunchSize = DispatchRaysDimensions(); + + const float2 pixelCenter = float2(LaunchID.xy) + float2(0.5, 0.5); + const float2 inUV = pixelCenter / float2(LaunchSize.xy); + float2 d = inUV * 2.0 - 1.0; + float4 target = mul(ubo.projInverse, float4(d.x, d.y, 1, 1)); + + RayDesc rayDesc; + rayDesc.Origin = mul(ubo.viewInverse, float4(0, 0, 0, 1)).xyz; + rayDesc.Direction = mul(ubo.viewInverse, float4(normalize(target.xyz), 0)).xyz; + rayDesc.TMin = 0.001; + rayDesc.TMax = 10000.0; + + Payload payload; + TraceRay(accelStruct, RAY_FLAG_FORCE_OPAQUE, 0xff, 0, 0, 0, rayDesc, payload); + + image[int2(LaunchID.xy)] = float4(payload.hitValue, 0.0); +} + +[shader("closesthit")] +void closesthitMain(inout Payload payload) +{ + Sphere sphere = spheres[PrimitiveIndex()]; + + float3 worldPos = WorldRayOrigin() + WorldRayDirection() * RayTCurrent(); + float3 worldNormal = normalize(worldPos - sphere.center); + + // Basic lighting + float3 lightVector = normalize(ubo.lightPos.xyz); + float dot_product = max(dot(lightVector, worldNormal), 0.2); + payload.hitValue = sphere.color.rgb * dot_product; +} + +[shader("miss")] +void missMain(inout Payload payload) +{ + payload.hitValue = float3(0.0, 0.0, 0.2); +} \ No newline at end of file diff --git a/shaders/slang/raytracingshadows/payload.slang b/shaders/slang/raytracingshadows/payload.slang new file mode 100644 index 00000000..5391a15b --- /dev/null +++ b/shaders/slang/raytracingshadows/payload.slang @@ -0,0 +1,13 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +module payload; + +public struct Payload +{ + public float3 hitValue; + public bool shadowed; +}; \ No newline at end of file diff --git a/shaders/slang/raytracingshadows/raytracingshadows.slang b/shaders/slang/raytracingshadows/raytracingshadows.slang new file mode 100644 index 00000000..a7bdb4ae --- /dev/null +++ b/shaders/slang/raytracingshadows/raytracingshadows.slang @@ -0,0 +1,117 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +import payload; + +struct Attributes +{ + float2 bary; +}; + +RaytracingAccelerationStructure accelStruct; +RWTexture2D image; + +struct UBO +{ + float4x4 viewInverse; + float4x4 projInverse; + float4 lightPos; + int vertexSize; +}; +ConstantBuffer ubo; + +StructuredBuffer vertices; +StructuredBuffer indices; + +struct Vertex +{ + float3 pos; + float3 normal; + float2 uv; + float4 color; + float4 _pad0; + float4 _pad1; +}; + +Vertex unpack(uint index) +{ + // Unpack the vertices from the SSBO using the glTF vertex structure + // The multiplier is the size of the vertex divided by four float components (=16 bytes) + const int m = ubo.vertexSize / 16; + + float4 d0 = vertices[m * index + 0]; + float4 d1 = vertices[m * index + 1]; + float4 d2 = vertices[m * index + 2]; + + Vertex v; + v.pos = d0.xyz; + v.normal = float3(d0.w, d1.x, d1.y); + v.color = float4(d2.x, d2.y, d2.z, 1.0); + + return v; +} + +[shader("raygeneration")] +void raygenerationMain() +{ + uint3 LaunchID = DispatchRaysIndex(); + uint3 LaunchSize = DispatchRaysDimensions(); + + const float2 pixelCenter = float2(LaunchID.xy) + float2(0.5, 0.5); + const float2 inUV = pixelCenter / float2(LaunchSize.xy); + float2 d = inUV * 2.0 - 1.0; + float4 target = mul(ubo.projInverse, float4(d.x, d.y, 1, 1)); + + RayDesc rayDesc; + rayDesc.Origin = mul(ubo.viewInverse, float4(0, 0, 0, 1)).xyz; + rayDesc.Direction = mul(ubo.viewInverse, float4(normalize(target.xyz), 0)).xyz; + rayDesc.TMin = 0.001; + rayDesc.TMax = 10000.0; + + Payload payload; + TraceRay(accelStruct, RAY_FLAG_FORCE_OPAQUE, 0xff, 0, 0, 0, rayDesc, payload); + + image[int2(LaunchID.xy)] = float4(payload.hitValue, 0.0); +} + +[shader("closesthit")] +void closesthitMain(inout Payload payload, in Attributes attribs) +{ + uint PrimitiveID = PrimitiveIndex(); + int3 index = int3(indices[3 * PrimitiveID], indices[3 * PrimitiveID + 1], indices[3 * PrimitiveID + 2]); + + Vertex v0 = unpack(index.x); + Vertex v1 = unpack(index.y); + Vertex v2 = unpack(index.z); + + // Interpolate normal + const float3 barycentricCoords = float3(1.0f - attribs.bary.x - attribs.bary.y, attribs.bary.x, attribs.bary.y); + float3 normal = normalize(v0.normal * barycentricCoords.x + v1.normal * barycentricCoords.y + v2.normal * barycentricCoords.z); + + // Basic lighting + float3 lightVector = normalize(ubo.lightPos.xyz); + float dot_product = max(dot(lightVector, normal), 0.2); + payload.hitValue = v0.color.rgb * dot_product; + + RayDesc rayDesc; + rayDesc.Origin = WorldRayOrigin() + WorldRayDirection() * RayTCurrent(); + rayDesc.Direction = lightVector; + rayDesc.TMin = 0.001; + rayDesc.TMax = 100.0; + + payload.shadowed = true; + // Offset indices to match shadow hit/miss index + TraceRay(accelStruct, RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH | RAY_FLAG_FORCE_OPAQUE | RAY_FLAG_SKIP_CLOSEST_HIT_SHADER, 0xff, 0, 0, 1, rayDesc, payload); + if (payload.shadowed) { + payload.hitValue *= 0.3; + } +} + +[shader("miss")] +void missMain(inout Payload payload) +{ + payload.hitValue = float3(0.0, 0.0, 0.2); +} \ No newline at end of file diff --git a/shaders/slang/raytracingshadows/shadow.slang b/shaders/slang/raytracingshadows/shadow.slang new file mode 100644 index 00000000..d2149b84 --- /dev/null +++ b/shaders/slang/raytracingshadows/shadow.slang @@ -0,0 +1,14 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +import payload; + +[shader("miss")] +void missMain(inout Payload payload) +{ + payload.shadowed = false; +} + From 7e5a387eb85b4cfee9b414cfec78619e5f9d121a Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 10 May 2025 13:58:14 +0200 Subject: [PATCH 42/73] Add slang shaders for additional samples --- shaders/slang/_rename.py | 13 ++ shaders/slang/variablerateshading/scene.slang | 116 ++++++++++++++++++ shaders/slang/vulkanscene/logo.slang | 60 +++++++++ shaders/slang/vulkanscene/mesh.slang | 85 +++++++++++++ shaders/slang/vulkanscene/skybox.slang | 46 +++++++ 5 files changed, 320 insertions(+) create mode 100644 shaders/slang/variablerateshading/scene.slang create mode 100644 shaders/slang/vulkanscene/logo.slang create mode 100644 shaders/slang/vulkanscene/mesh.slang create mode 100644 shaders/slang/vulkanscene/skybox.slang diff --git a/shaders/slang/_rename.py b/shaders/slang/_rename.py index f24457fb..1a5d3845 100644 --- a/shaders/slang/_rename.py +++ b/shaders/slang/_rename.py @@ -24,6 +24,19 @@ def checkRenameFiles(samplename): "raytracingreflections.rmiss.spv": "miss.rmiss.spv", "raytracingreflections.rgen.spv": "raygen.rgen.spv", } + case "raytracingshadows": + mappings = { + "raytracingshadows.rchit.spv": "closesthit.rchit.spv", + "raytracingshadows.rmiss.spv": "miss.rmiss.spv", + "raytracingshadows.rgen.spv": "raygen.rgen.spv", + } + case "raytracingintersection": + mappings = { + "raytracingintersection.rchit.spv": "closesthit.rchit.spv", + "raytracingintersection.rmiss.spv": "miss.rmiss.spv", + "raytracingintersection.rgen.spv": "raygen.rgen.spv", + "raytracingintersection.rint.spv": "intersection.rint.spv", + } case "viewportarray": mappings = { "scene.geom.spv": "multiview.geom.spv", diff --git a/shaders/slang/variablerateshading/scene.slang b/shaders/slang/variablerateshading/scene.slang new file mode 100644 index 00000000..e5954740 --- /dev/null +++ b/shaders/slang/variablerateshading/scene.slang @@ -0,0 +1,116 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; + float3 Color; + float4 Tangent; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float2 UV; + float3 ViewVec; + float3 LightVec; + float4 Tangent; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float4 lightPos; + float4 viewPos; + int colorShadingRates; +}; +ConstantBuffer ubo; + +[[vk::binding(0, 1)]] Sampler2D samplerColorMap; +[[vk::binding(1, 1)]] Sampler2D samplerNormalMap; + +[[SpecializationConstant]] const bool ALPHA_MASK = false; +[[SpecializationConstant]] const float ALPHA_MASK_CUTOFF = 0.0; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = input.UV; + output.Tangent = input.Tangent; + + float4x4 modelView = mul(ubo.view, ubo.model); + + output.Pos = mul(ubo.projection, mul(modelView, float4(input.Pos.xyz, 1.0))); + + output.Normal = mul((float3x3)ubo.model, input.Normal); + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.LightVec = ubo.lightPos.xyz - pos.xyz; + output.ViewVec = ubo.viewPos.xyz - pos.xyz; + return output; +} + +static const uint SHADING_RATE_PER_PIXEL = 0; +static const uint SHADING_RATE_PER_2X1_PIXELS = 6; +static const uint SHADING_RATE_PER_1X2_PIXELS = 7; +static const uint SHADING_RATE_PER_2X2_PIXELS = 8; +static const uint SHADING_RATE_PER_4X2_PIXELS = 9; +static const uint SHADING_RATE_PER_2X4_PIXELS = 10; + +[shader("fragment")] +float4 fragmentMain(VSOutput input, uint shadingRate : SV_ShadingRate) +{ + float4 color = samplerColorMap.Sample(input.UV) * float4(input.Color, 1.0); + + if (ALPHA_MASK) { + if (color.a < ALPHA_MASK_CUTOFF) { + discard; + } + } + + float3 N = normalize(input.Normal); + float3 T = normalize(input.Tangent.xyz); + float3 B = cross(input.Normal, input.Tangent.xyz) * input.Tangent.w; + float3x3 TBN = float3x3(T, B, N); + N = mul(normalize(samplerNormalMap.Sample(input.UV).xyz * 2.0 - float3(1.0, 1.0, 1.0)), TBN); + + const float ambient = 0.1; + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), ambient).rrr; + float3 specular = pow(max(dot(R, V), 0.0), 32.0); + color = float4(diffuse * color.rgb + specular, color.a); + + if (ubo.colorShadingRates == 1) { + switch (shadingRate) { + case SHADING_RATE_PER_PIXEL: + return color * float4(0.0, 0.8, 0.4, 1.0); + case SHADING_RATE_PER_2X1_PIXELS: + return color * float4(0.2, 0.6, 1.0, 1.0); + case SHADING_RATE_PER_1X2_PIXELS: + return color * float4(0.0, 0.4, 0.8, 1.0); + case SHADING_RATE_PER_2X2_PIXELS: + return color * float4(1.0, 1.0, 0.2, 1.0); + case SHADING_RATE_PER_4X2_PIXELS: + return color * float4(0.8, 0.8, 0.0, 1.0); + case SHADING_RATE_PER_2X4_PIXELS: + return color * float4(1.0, 0.4, 0.2, 1.0); + default: + return color * float4(0.8, 0.0, 0.0, 1.0); + } + } + + return color; +} \ No newline at end of file diff --git a/shaders/slang/vulkanscene/logo.slang b/shaders/slang/vulkanscene/logo.slang new file mode 100644 index 00000000..95974e79 --- /dev/null +++ b/shaders/slang/vulkanscene/logo.slang @@ -0,0 +1,60 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float3 Normal; + float2 TexCoord; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; + float3 Normal; + float3 Color; + float3 EyePos; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 normal; + float4x4 view; + float3 lightpos; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + float4x4 modelView = mul(ubo.view, ubo.model); + float4 pos = mul(modelView, input.Pos); + output.UV = input.TexCoord.xy; + output.Normal = normalize(mul((float3x3)ubo.normal, input.Normal)); + output.Color = input.Color; + output.Pos = mul(ubo.projection, pos); + output.EyePos = mul(modelView, pos).xyz; + float4 lightPos = mul(modelView, float4(1.0, 2.0, 0.0, 1.0)); + output.LightVec = normalize(lightPos.xyz - output.EyePos); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 Eye = normalize(-input.EyePos); + float3 Reflected = normalize(reflect(-input.LightVec, input.Normal)); + float4 diff = float4(input.Color, 1.0) * max(dot(input.Normal, input.LightVec), 0.0); + float shininess = 0.0; + float4 spec = float4(1.0, 1.0, 1.0, 1.0) * pow(max(dot(Reflected, Eye), 0.0), 2.5) * shininess; + return float4((diff + spec).rgb, 1); +} \ No newline at end of file diff --git a/shaders/slang/vulkanscene/mesh.slang b/shaders/slang/vulkanscene/mesh.slang new file mode 100644 index 00000000..61c80c11 --- /dev/null +++ b/shaders/slang/vulkanscene/mesh.slang @@ -0,0 +1,85 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float3 Normal; + float2 TexCoord; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; + float3 Normal; + float3 Color; + float3 EyePos; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 normal; + float4x4 view; + float3 lightpos; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UV = input.TexCoord.xy; + output.Normal = normalize(mul((float3x3)ubo.normal, input.Normal)); + output.Color = input.Color; + float4x4 modelView = mul(ubo.view, ubo.model); + float4 pos = mul(modelView, input.Pos); + output.Pos = mul(ubo.projection, pos); + output.EyePos = mul(modelView, pos).xyz; + float4 lightPos = mul(modelView, float4(ubo.lightpos, 1.0)); + output.LightVec = normalize(lightPos.xyz - output.EyePos); + return output; +} + +float specpart(float3 L, float3 N, float3 H) +{ + if (dot(N, L) > 0.0) + { + return pow(clamp(dot(H, N), 0.0, 1.0), 64.0); + } + return 0.0; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 Eye = normalize(-input.EyePos); + float3 Reflected = normalize(reflect(-input.LightVec, input.Normal)); + + float3 halfVec = normalize(input.LightVec + input.EyePos); + float diff = clamp(dot(input.LightVec, input.Normal), 0.0, 1.0); + float spec = specpart(input.LightVec, input.Normal, halfVec); + float intensity = 0.1 + diff + spec; + + float4 IAmbient = float4(0.2, 0.2, 0.2, 1.0); + float4 IDiffuse = float4(0.5, 0.5, 0.5, 0.5) * max(dot(input.Normal, input.LightVec), 0.0); + float shininess = 0.75; + float4 ISpecular = float4(0.5, 0.5, 0.5, 1.0) * pow(max(dot(Reflected, Eye), 0.0), 2.0) * shininess; + + float4 outFragColor = float4((IAmbient + IDiffuse) * float4(input.Color, 1.0) + ISpecular); + + // Some manual saturation + if (intensity > 0.95) + outFragColor *= 2.25; + if (intensity < 0.15) + outFragColor = float4(0.1, 0.1, 0.1, 0.1); + + return outFragColor; +} \ No newline at end of file diff --git a/shaders/slang/vulkanscene/skybox.slang b/shaders/slang/vulkanscene/skybox.slang new file mode 100644 index 00000000..98d38560 --- /dev/null +++ b/shaders/slang/vulkanscene/skybox.slang @@ -0,0 +1,46 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 UVW; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 normal; + float4x4 view; +}; +ConstantBuffer ubo; +SamplerCube samplerCubeMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + // Remove translation from view matrix + float4x4 viewMat = ubo.view; + viewMat[0][3] = 0.0; + viewMat[1][3] = 0.0; + viewMat[2][3] = 0.0; + output.UVW = input.Pos; + output.Pos = mul(ubo.projection, mul(viewMat, mul(ubo.model, float4(input.Pos.xyz, 1.0)))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return samplerCubeMap.Sample(input.UVW); +} \ No newline at end of file From d6a1f6af06ddf361ddf544756ea1c6d3b0ba3a21 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 10 May 2025 15:20:40 +0200 Subject: [PATCH 43/73] Add slang shaders for additional samples --- shaders/slang/stencilbuffer/outline.slang | 42 +++++++++++++++ shaders/slang/stencilbuffer/toon.slang | 65 +++++++++++++++++++++++ shaders/slang/textoverlay/mesh.slang | 56 +++++++++++++++++++ shaders/slang/textoverlay/text.slang | 35 ++++++++++++ 4 files changed, 198 insertions(+) create mode 100644 shaders/slang/stencilbuffer/outline.slang create mode 100644 shaders/slang/stencilbuffer/toon.slang create mode 100644 shaders/slang/textoverlay/mesh.slang create mode 100644 shaders/slang/textoverlay/text.slang diff --git a/shaders/slang/stencilbuffer/outline.slang b/shaders/slang/stencilbuffer/outline.slang new file mode 100644 index 00000000..332f220d --- /dev/null +++ b/shaders/slang/stencilbuffer/outline.slang @@ -0,0 +1,42 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float3 Color; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +} + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; + float outlineWidth; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + // Extrude along normal + VSOutput output; + float4 pos = float4(input.Pos.xyz + input.Normal * ubo.outlineWidth, input.Pos.w); + output.Pos = mul(ubo.projection, mul(ubo.model, pos)); + return output; +} + +[shader("fragment")] +float4 fragmentMain() +{ + return float4(1.0, 1.0, 1.0, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/stencilbuffer/toon.slang b/shaders/slang/stencilbuffer/toon.slang new file mode 100644 index 00000000..b7bf1314 --- /dev/null +++ b/shaders/slang/stencilbuffer/toon.slang @@ -0,0 +1,65 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Color; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; +ConstantBuffer ubo; + +Sampler2D samplerColorMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = float3(1.0, 0.0, 0.0); + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + output.Normal = mul((float3x3)ubo.model, input.Normal); + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + float3 lPos = mul((float3x3)ubo.model, ubo.lightPos.xyz); + output.LightVec = lPos - pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 color; + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float intensity = dot(N,L); + if (intensity > 0.98) + color = input.Color * 1.5; + else if (intensity > 0.9) + color = input.Color * 1.0; + else if (intensity > 0.5) + color = input.Color * 0.6; + else if (intensity > 0.25) + color = input.Color * 0.4; + else + color = input.Color * 0.2; + // Desaturate a bit + color = lerp(color, dot(float3(0.2126,0.7152,0.0722), color).xxx, 0.1); + return float4(color, 1); +} \ No newline at end of file diff --git a/shaders/slang/textoverlay/mesh.slang b/shaders/slang/textoverlay/mesh.slang new file mode 100644 index 00000000..a7c4d07d --- /dev/null +++ b/shaders/slang/textoverlay/mesh.slang @@ -0,0 +1,56 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Normal = input.Normal; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, normalize(input.Normal)); + float3 lPos = mul((float3x3)ubo.model, ubo.lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float diffuse = max(dot(N, L), 0.0); + float specular = pow(max(dot(R, V), 0.0), 1.0); + return float4(((diffuse + specular) * 0.25).xxx, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/textoverlay/text.slang b/shaders/slang/textoverlay/text.slang new file mode 100644 index 00000000..f4ca9337 --- /dev/null +++ b/shaders/slang/textoverlay/text.slang @@ -0,0 +1,35 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + + struct VSInput +{ + float2 Pos; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +Sampler2D samplerFont; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Pos = float4(input.Pos, 0.0, 1.0); + output.UV = input.UV; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float color = samplerFont.Sample(input.UV).r; + return color.xxxx; +} From 7b88f68bf0a0e0fba70bf8eea63d2aca0f896690 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 11 May 2025 16:33:23 +0200 Subject: [PATCH 44/73] Add slang shaders for gltf ray tracing sample --- shaders/slang/_rename.py | 7 + shaders/slang/compileshaders.py | 23 +- .../slang/raytracinggltf/raytracinggltf.slang | 219 ++++++++++++++++++ shaders/slang/raytracinggltf/shadow.slang | 18 ++ 4 files changed, 263 insertions(+), 4 deletions(-) create mode 100644 shaders/slang/raytracinggltf/raytracinggltf.slang create mode 100644 shaders/slang/raytracinggltf/shadow.slang diff --git a/shaders/slang/_rename.py b/shaders/slang/_rename.py index 1a5d3845..dfd09a4f 100644 --- a/shaders/slang/_rename.py +++ b/shaders/slang/_rename.py @@ -18,6 +18,13 @@ def checkRenameFiles(samplename): "raytracingbasic.rmiss.spv": "miss.rmiss.spv", "raytracingbasic.rgen.spv": "raygen.rgen.spv", } + case "raytracinggltf": + mappings = { + "raytracinggltf.rchit.spv": "closesthit.rchit.spv", + "raytracinggltf.rmiss.spv": "miss.rmiss.spv", + "raytracinggltf.rgen.spv": "raygen.rgen.spv", + "raytracinggltf.rahit.spv": "anyhit.rahit.spv", + } case "raytracingreflections": mappings = { "raytracingreflections.rchit.spv": "closesthit.rchit.spv", diff --git a/shaders/slang/compileshaders.py b/shaders/slang/compileshaders.py index 3f7f39ab..c2e20149 100644 --- a/shaders/slang/compileshaders.py +++ b/shaders/slang/compileshaders.py @@ -47,6 +47,10 @@ def getShaderStages(filename): stages.append("closesthit") if '[shader("callable")]' in filecontent: stages.append("callable") + if '[shader("intersection")]' in filecontent: + stages.append("intersection") + if '[shader("anyhit")]' in filecontent: + stages.append("anyhit") if '[shader("compute")]' in filecontent: stages.append("compute") if '[shader("amplification")]' in filecontent: @@ -55,6 +59,10 @@ def getShaderStages(filename): stages.append("mesh") if '[shader("geometry")]' in filecontent: stages.append("geometry") + if '[shader("hull")]' in filecontent: + stages.append("hull") + if '[shader("domain")]' in filecontent: + stages.append("domain") f.close() return stages @@ -83,10 +91,7 @@ for root, dirs, files in os.walk(dir_path): print("Compiling %s" % input_file) output_base_file_name = input_file for stage in stages: - if (len(stages) > 0): - entry_point = stage + "Main" - else: - entry_point = "main" + entry_point = stage + "Main" output_ext = "" match stage: case "vertex": @@ -101,6 +106,10 @@ for root, dirs, files in os.walk(dir_path): output_ext = ".rchit" case "callable": output_ext = ".rcall" + case "intersection": + output_ext = ".rint" + case "anyhit": + output_ext = ".rahit" case "compute": output_ext = ".comp" case "mesh": @@ -109,9 +118,15 @@ for root, dirs, files in os.walk(dir_path): output_ext = ".task" case "geometry": output_ext = ".geom" + case "hull": + output_ext = ".tesc" + case "domain": + output_ext = ".tese" output_file = output_base_file_name + output_ext + ".spv" output_file = output_file.replace(".slang", "") + print(output_file) res = subprocess.call("%s %s -profile spirv_1_4 -matrix-layout-column-major -target spirv -o %s -entry %s -stage %s -warnings-disable 39001" % (compiler_path, input_file, output_file, entry_point, stage), shell=True) if res != 0: + print("Error %s", res) sys.exit(res) checkRenameFiles(folder_name) \ No newline at end of file diff --git a/shaders/slang/raytracinggltf/raytracinggltf.slang b/shaders/slang/raytracinggltf/raytracinggltf.slang new file mode 100644 index 00000000..76f2a832 --- /dev/null +++ b/shaders/slang/raytracinggltf/raytracinggltf.slang @@ -0,0 +1,219 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct Payload +{ + float3 hitValue; + uint payloadSeed; + bool shadowed; +}; + +struct GeometryNode { + ConstBufferPointer vertices; + ConstBufferPointer indices; + int textureIndexBaseColor; + int textureIndexOcclusion; +}; + +struct UBOCameraProperties { + float4x4 viewInverse; + float4x4 projInverse; + uint frame; +} + +[[vk::binding(0, 0)]] RaytracingAccelerationStructure accelStruct; +[[vk::binding(1, 0)]] RWTexture2D image; +[[vk::binding(2, 0)]] ConstantBuffer cam; +[[vk::binding(4, 0)]] StructuredBuffer geometryNodes; +[[vk::binding(5, 0)]] Sampler2D textures[]; + +struct Vertex +{ + float3 pos; + float3 normal; + float2 uv; +}; + +struct Triangle { + Vertex vertices[3]; + float3 normal; + float2 uv; +}; + +struct Attributes +{ + float2 bary; +}; + +// Tiny Encryption Algorithm +// By Fahad Zafar, Marc Olano and Aaron Curtis, see https://www.highperformancegraphics.org/previous/www_2010/media/GPUAlgorithms/HPG2010_GPUAlgorithms_Zafar.pdf +uint tea(uint val0, uint val1) +{ + uint sum = 0; + uint v0 = val0; + uint v1 = val1; + for (uint n = 0; n < 16; n++) + { + sum += 0x9E3779B9; + v0 += ((v1 << 4) + 0xA341316C) ^ (v1 + sum) ^ ((v1 >> 5) + 0xC8013EA4); + v1 += ((v0 << 4) + 0xAD90777D) ^ (v0 + sum) ^ ((v0 >> 5) + 0x7E95761E); + } + return v0; +} + +// Linear congruential generator based on the previous RNG state +// See https://en.wikipedia.org/wiki/Linear_congruential_generator +uint lcg(inout uint previous) +{ + const uint multiplier = 1664525u; + const uint increment = 1013904223u; + previous = (multiplier * previous + increment); + return previous & 0x00FFFFFF; +} + +// Generate a random float in [0, 1) given the previous RNG state +float rnd(inout uint previous) +{ + return (float(lcg(previous)) / float(0x01000000)); +} + +// This function will unpack our vertex buffer data into a single triangle and calculates uv coordinates +Triangle unpackTriangle(uint index, Attributes attribs) { + Triangle tri; + const uint triIndex = index * 3; + const uint vertexsize = 112; + + GeometryNode geometryNode = geometryNodes[GeometryIndex()]; + + // Indices indices = Indices(geometryNode.indexBufferDeviceAddress); + // Vertices vertices = Vertices(geometryNode.vertexBufferDeviceAddress); + + // Unpack vertices + // Data is packed as float4 so we can map to the glTF vertex structure from the host side + // We match vkglTF::Vertex: pos.xyz+normal.x, normalyz+uv.xy + // glm::float3 pos; + // glm::float3 normal; + // glm::float2 uv; + // ... + for (uint i = 0; i < 3; i++) { + const uint offset = geometryNode.indices[triIndex + i] * 6; + float4 d0 = geometryNode.vertices[offset + 0]; // pos.xyz, n.x + float4 d1 = geometryNode.vertices[offset + 1]; // n.yz, uv.xy + tri.vertices[i].pos = d0.xyz; + tri.vertices[i].normal = float3(d0.w, d1.xy); + tri.vertices[i].uv = float2(d1.z, d1.w); + } + // Calculate values at barycentric coordinates + float3 barycentricCoords = float3(1.0f - attribs.bary.x - attribs.bary.y, attribs.bary.x, attribs.bary.y); + tri.uv = tri.vertices[0].uv * barycentricCoords.x + tri.vertices[1].uv * barycentricCoords.y + tri.vertices[2].uv * barycentricCoords.z; + tri.normal = tri.vertices[0].normal * barycentricCoords.x + tri.vertices[1].normal * barycentricCoords.y + tri.vertices[2].normal * barycentricCoords.z; + return tri; +} + +[shader("raygeneration")] +void raygenerationMain() +{ + uint3 LaunchID = DispatchRaysIndex(); + uint3 LaunchSize = DispatchRaysDimensions(); + + uint seed = tea(LaunchID.y * LaunchSize.x + LaunchID.x, cam.frame); + + float r1 = rnd(seed); + float r2 = rnd(seed); + + // Subpixel jitter: send the ray through a different position inside the pixel + // each time, to provide antialiasing. + float2 subpixel_jitter = cam.frame == 0 ? float2(0.5f, 0.5f) : float2(r1, r2); + const float2 pixelCenter = float2(LaunchID.xy) + subpixel_jitter; + const float2 inUV = pixelCenter / float2(LaunchSize.xy); + float2 d = inUV * 2.0 - 1.0; + + float4 target = mul(cam.projInverse, float4(d.x, d.y, 1, 1)); + + RayDesc rayDesc; + rayDesc.Origin = mul(cam.viewInverse, float4(0, 0, 0, 1)).xyz; + rayDesc.Direction = mul(cam.viewInverse, float4(normalize(target.xyz), 0)).xyz; + rayDesc.TMin = 0.001; + rayDesc.TMax = 10000.0; + + Payload payload; + payload.hitValue = float3(0.0); + float3 hitValues = float3(0); + + const int samples = 4; + + // Trace multiple rays for e.g. transparency + for (int smpl = 0; smpl < samples; smpl++) { + payload.payloadSeed = tea(LaunchID.y * LaunchSize.x + LaunchID.x, cam.frame); + TraceRay(accelStruct, RAY_FLAG_NONE, 0xff, 0, 0, 0, rayDesc, payload); + hitValues += payload.hitValue; + } + + float3 hitVal = hitValues / float(samples); + + if (cam.frame > 0) + { + float a = 1.0f / float(cam.frame + 1); + float3 old_color = image[int2(LaunchID.xy)].xyz; + image[int2(LaunchID.xy)] = float4(lerp(old_color, hitVal, a), 1.0f); + } + else + { + // First frame, replace the value in the buffer + image[int2(LaunchID.xy)] = float4(hitVal, 1.0f); + } +} + +[shader("closesthit")] +void closesthitMain(inout Payload payload, in Attributes attribs) +{ + Triangle tri = unpackTriangle(PrimitiveIndex(), attribs); + payload.hitValue = float3(tri.normal); + + GeometryNode geometryNode = geometryNodes[GeometryIndex()]; + + float3 color = textures[NonUniformResourceIndex(geometryNode.textureIndexBaseColor)].SampleLevel(tri.uv, 0.0).rgb; + if (geometryNode.textureIndexOcclusion > -1) { + float occlusion = textures[NonUniformResourceIndex(geometryNode.textureIndexOcclusion)].SampleLevel(tri.uv, 0.0).r; + color *= occlusion; + } + + payload.hitValue = color; + + // Shadow casting + float tmin = 0.001; + float tmax = 10000.0; + float epsilon = 0.001; + float3 origin = WorldRayOrigin() + WorldRayDirection() * RayTCurrent() + tri.normal * epsilon; + payload.shadowed = true; + float3 lightVector = float3(-5.0, -2.5, -5.0); + // Trace shadow ray and offset indices to match shadow hit/miss shader group indices + // traceRayEXT(topLevelAS, gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT, 0xFF, 0, 0, 1, origin, tmin, lightVector, tmax, 2); + // if (shadowed) { + // hitValue *= 0.7; + // } +} + +[shader("anyhit")] +void anyhitMain(inout Payload payload, in Attributes attribs) +{ + Triangle tri = unpackTriangle(PrimitiveIndex(), attribs); + GeometryNode geometryNode = geometryNodes[GeometryIndex()]; + float4 color = textures[NonUniformResourceIndex(geometryNode.textureIndexBaseColor)].SampleLevel(tri.uv, 0.0); + // If the alpha value of the texture at the current UV coordinates is below a given threshold, we'll ignore this intersection + // That way ray traversal will be stopped and the miss shader will be invoked + if (color.a < 0.9) { + if (rnd(payload.payloadSeed) > color.a) { + IgnoreHit(); + } + } +} + +[shader("miss")] +void missMain(inout Payload payload) +{ + payload.hitValue = float3(1.0); +} \ No newline at end of file diff --git a/shaders/slang/raytracinggltf/shadow.slang b/shaders/slang/raytracinggltf/shadow.slang new file mode 100644 index 00000000..481816ad --- /dev/null +++ b/shaders/slang/raytracinggltf/shadow.slang @@ -0,0 +1,18 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct Payload +{ + float3 hitValue; + uint payloadSeed; + bool shadowed; +}; + +[shader("miss")] +void missMain(inout Payload payload) +{ + payload.shadowed = false; +} \ No newline at end of file From b2272c5719757b61e9e1d2b41f5bba4c88c59c19 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Mon, 12 May 2025 19:11:19 +0200 Subject: [PATCH 45/73] Add slang shaders for gears sample --- shaders/slang/gears/gears.slang | 58 +++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 shaders/slang/gears/gears.slang diff --git a/shaders/slang/gears/gears.slang b/shaders/slang/gears/gears.slang new file mode 100644 index 00000000..5c15ba63 --- /dev/null +++ b/shaders/slang/gears/gears.slang @@ -0,0 +1,58 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 EyePos; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4 lightpos; + float4x4 model[3]; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uint InstanceIndex: SV_StartInstanceLocation) +{ + VSOutput output; + output.Normal = normalize(mul((float3x3)transpose(ubo.model[InstanceIndex]), input.Normal).xyz); + output.Color = input.Color; + float4x4 modelView = mul(ubo.view, ubo.model[InstanceIndex]); + float4 pos = mul(modelView, float4(input.Pos, 1.0)); + output.EyePos = mul(modelView, pos).xyz; + float4 lightPos = mul(float4(ubo.lightpos.xyz, 1.0), modelView); + output.LightVec = normalize(lightPos.xyz - output.EyePos); + output.Pos = mul(ubo.projection, pos); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 eye = normalize(-input.EyePos); + float3 reflected = normalize(reflect(-input.LightVec, input.Normal)); + + float4 ambient = float4(0.2, 0.2, 0.2, 1.0); + float4 diffuse = float4(0.5, 0.5, 0.5, 0.5) * max(dot(input.Normal, input.LightVec), 0.0); + float4 specular = float4(0.5, 0.5, 0.5, 1.0) * pow(max(dot(reflected, eye), 0.0), 0.8) * 0.25; + + return float4((ambient + diffuse) * float4(input.Color, 1.0) + specular); +} \ No newline at end of file From 75f3508a61f3dd4f59bc3617223154fc81dd6722 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Tue, 13 May 2025 19:32:35 +0200 Subject: [PATCH 46/73] Add slang shaders for additional ray tracing samples --- shaders/slang/_rename.py | 14 ++- .../raytracingpositionfetch.slang | 78 ++++++++++++++++ .../raytracingsbtdata/raytracingsbtdata.slang | 88 +++++++++++++++++++ 3 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 shaders/slang/raytracingpositionfetch/raytracingpositionfetch.slang create mode 100644 shaders/slang/raytracingsbtdata/raytracingsbtdata.slang diff --git a/shaders/slang/_rename.py b/shaders/slang/_rename.py index dfd09a4f..802137aa 100644 --- a/shaders/slang/_rename.py +++ b/shaders/slang/_rename.py @@ -24,13 +24,25 @@ def checkRenameFiles(samplename): "raytracinggltf.rmiss.spv": "miss.rmiss.spv", "raytracinggltf.rgen.spv": "raygen.rgen.spv", "raytracinggltf.rahit.spv": "anyhit.rahit.spv", - } + } + case "raytracingpositionfetch": + mappings = { + "raytracingpositionfetch.rchit.spv": "closesthit.rchit.spv", + "raytracingpositionfetch.rmiss.spv": "miss.rmiss.spv", + "raytracingpositionfetch.rgen.spv": "raygen.rgen.spv", + } case "raytracingreflections": mappings = { "raytracingreflections.rchit.spv": "closesthit.rchit.spv", "raytracingreflections.rmiss.spv": "miss.rmiss.spv", "raytracingreflections.rgen.spv": "raygen.rgen.spv", } + case "raytracingsbtdata": + mappings = { + "raytracingsbtdata.rchit.spv": "closesthit.rchit.spv", + "raytracingsbtdata.rmiss.spv": "miss.rmiss.spv", + "raytracingsbtdata.rgen.spv": "raygen.rgen.spv", + } case "raytracingshadows": mappings = { "raytracingshadows.rchit.spv": "closesthit.rchit.spv", diff --git a/shaders/slang/raytracingpositionfetch/raytracingpositionfetch.slang b/shaders/slang/raytracingpositionfetch/raytracingpositionfetch.slang new file mode 100644 index 00000000..96c341e9 --- /dev/null +++ b/shaders/slang/raytracingpositionfetch/raytracingpositionfetch.slang @@ -0,0 +1,78 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct Attributes +{ + float2 bary; +}; + +struct Payload +{ + [[vk::location(0)]] float3 hitValue; +}; + +RaytracingAccelerationStructure accelStruct; +RWTexture2D image; +struct UBO +{ + float4x4 viewInverse; + float4x4 projInverse; + float4 lightPos; +}; +ConstantBuffer ubo; + +[shader("raygeneration")] +void raygenerationMain() +{ + uint3 LaunchID = DispatchRaysIndex(); + uint3 LaunchSize = DispatchRaysDimensions(); + + const float2 pixelCenter = float2(LaunchID.xy) + float2(0.5, 0.5); + const float2 inUV = pixelCenter / float2(LaunchSize.xy); + float2 d = inUV * 2.0 - 1.0; + float4 target = mul(ubo.projInverse, float4(d.x, d.y, 1, 1)); + + RayDesc rayDesc; + rayDesc.Origin = mul(ubo.viewInverse, float4(0, 0, 0, 1)).xyz; + rayDesc.Direction = mul(ubo.viewInverse, float4(normalize(target.xyz), 0)).xyz; + rayDesc.TMin = 0.001; + rayDesc.TMax = 10000.0; + + Payload payload; + TraceRay(accelStruct, RAY_FLAG_FORCE_OPAQUE, 0xff, 0, 0, 0, rayDesc, payload); + + image[int2(LaunchID.xy)] = float4(payload.hitValue, 0.0); +} + +[shader("closesthit")] +void closesthitMain(inout Payload payload, in Attributes attribs) +{ + // We need the barycentric coordinates to calculate data for the current position + const float3 barycentricCoords = float3(1.0f - attribs.bary.x - attribs.bary.y, attribs.bary.x, attribs.bary.y); + + // With VK_KHR_ray_tracing_position_fetch we can access the vertices for the hit triangle in the shader + + float3 vertexPos0 = HitTriangleVertexPosition(0); + float3 vertexPos1 = HitTriangleVertexPosition(1); + float3 vertexPos2 = HitTriangleVertexPosition(2); + float3 currentPos = vertexPos0 * barycentricCoords.x + vertexPos1 * barycentricCoords.y + vertexPos2 * barycentricCoords.z; + + // Calcualte the normal from above values + float3 normal = normalize(cross(vertexPos1 - vertexPos0, vertexPos2 - vertexPos0)); + normal = normalize(mul(float4(normal, 1.0), WorldToObject4x3())); + + // Basic lighting + float3 lightDir = normalize(ubo.lightPos.xyz - currentPos); + float diffuse = max(dot(normal, lightDir), 0.0); + + payload.hitValue.rgb = 0.1 + diffuse; +} + +[shader("miss")] +void missMain(inout Payload payload) +{ + payload.hitValue = float3(0.0, 0.0, 0.2); +} \ No newline at end of file diff --git a/shaders/slang/raytracingsbtdata/raytracingsbtdata.slang b/shaders/slang/raytracingsbtdata/raytracingsbtdata.slang new file mode 100644 index 00000000..5ec0bc13 --- /dev/null +++ b/shaders/slang/raytracingsbtdata/raytracingsbtdata.slang @@ -0,0 +1,88 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct Attributes +{ + float2 bary; +}; + +struct Payload +{ + float3 hitValue; +}; + +RaytracingAccelerationStructure accelStruct; +RWTexture2D image; +struct CameraProperties +{ + float4x4 viewInverse; + float4x4 projInverse; +}; +ConstantBuffer cam; + +struct SBT { + float r; + float g; + float b; +}; +[[vk::shader_record]] ConstantBuffer sbt; + +[shader("raygeneration")] +void raygenerationMain() +{ + uint3 LaunchID = DispatchRaysIndex(); + uint3 LaunchSize = DispatchRaysDimensions(); + + const float2 pixelCenter = float2(LaunchID.xy) + float2(0.5, 0.5); + const float2 inUV = pixelCenter / float2(LaunchSize.xy); + float2 d = inUV * 2.0 - 1.0; + float4 target = mul(cam.projInverse, float4(d.x, d.y, 1, 1)); + + RayDesc rayDesc; + rayDesc.Origin = mul(cam.viewInverse, float4(0, 0, 0, 1)).xyz; + rayDesc.Direction = mul(cam.viewInverse, float4(normalize(target.xyz), 0)).xyz; + rayDesc.TMin = 0.001; + rayDesc.TMax = 10000.0; + + Payload payload; + + // use border to demonstrate raygen record data + if (all(LaunchID.xy > int2(16, 16)) && all(LaunchID.xy < LaunchSize.xy - int2(16, 16))) + { + // Generate a checker board pattern to trace out rays or use hit record data + int2 pos = int2(LaunchID.xy / 16); + if (((pos.x + pos.y % 2) % 2) == 0) { + // This will set hit value to either hit or miss SBT record color + TraceRay(accelStruct, RAY_FLAG_FORCE_OPAQUE, 0xff, 0, 0, 0, rayDesc, payload); + } + else { + // Set the hit value to the raygen SBT data + payload.hitValue = float3(sbt.r, sbt.g, sbt.b); + } + } + else { + // Set hit value to black + payload.hitValue = float3(0.0, 0.0, 0.0); + } + + image[int2(LaunchID.xy)] = float4(payload.hitValue, 0.0); +} + +[shader("closesthit")] +void closesthitMain(inout Payload payload, in Attributes attribs) +{ + // Update the hit value to the hit record SBT data associated with this + // geometry ID and ray ID + payload.hitValue = float3(sbt.r, sbt.g, sbt.g); +} + +[shader("miss")] +void missMain(inout Payload payload) +{ + // Update the hit value to the hit record SBT data associated with this + // miss record + payload.hitValue = float3(sbt.r, sbt.g, sbt.g); +} From a442bdd68309241f3139589ef5835111ec274170 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Tue, 13 May 2025 21:23:54 +0200 Subject: [PATCH 47/73] Add slang shaders for ray tracing texture sample --- shaders/slang/_rename.py | 7 ++ .../raytracingtextures.slang | 114 ++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 shaders/slang/raytracingtextures/raytracingtextures.slang diff --git a/shaders/slang/_rename.py b/shaders/slang/_rename.py index 802137aa..4b23aef0 100644 --- a/shaders/slang/_rename.py +++ b/shaders/slang/_rename.py @@ -49,6 +49,13 @@ def checkRenameFiles(samplename): "raytracingshadows.rmiss.spv": "miss.rmiss.spv", "raytracingshadows.rgen.spv": "raygen.rgen.spv", } + case "raytracingtextures": + mappings = { + "raytracingtextures.rchit.spv": "closesthit.rchit.spv", + "raytracingtextures.rmiss.spv": "miss.rmiss.spv", + "raytracingtextures.rgen.spv": "raygen.rgen.spv", + "raytracingtextures.rahit.spv": "anyhit.rahit.spv", + } case "raytracingintersection": mappings = { "raytracingintersection.rchit.spv": "closesthit.rchit.spv", diff --git a/shaders/slang/raytracingtextures/raytracingtextures.slang b/shaders/slang/raytracingtextures/raytracingtextures.slang new file mode 100644 index 00000000..469a1b5e --- /dev/null +++ b/shaders/slang/raytracingtextures/raytracingtextures.slang @@ -0,0 +1,114 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct Vertex +{ + float3 pos; + float2 uv; +}; + +struct Triangle { + Vertex vertices[3]; + float2 uv; +}; + +struct BufferReferences { + // Pointer to the buffer with the scene's MVP matrix + ConstBufferPointer vertices; + // Pointer to the buffer for the data for each model + ConstBufferPointer indices; +}; +[[vk::push_constant]] BufferReferences bufferReferences; + +struct Payload +{ + float3 hitValue; +}; + +struct UBOCameraProperties { + float4x4 viewInverse; + float4x4 projInverse; +} + +RaytracingAccelerationStructure accelStruct; +RWTexture2D image; +ConstantBuffer cam; +Sampler2D samplerColor; + +struct Attributes +{ + float2 bary; +}; + +Triangle unpackTriangle(uint index, Attributes attribs) { + Triangle tri; + const uint triIndex = index * 3; + const uint vertexSize = 32; + + // Unpack vertices + // Data is packed as float4 so we can map to the glTF vertex structure from the host side + for (uint i = 0; i < 3; i++) { + const uint offset = bufferReferences.indices[triIndex + i] * (vertexSize / 16); + float4 d0 = bufferReferences.vertices[offset + 0]; // pos.xyz, n.x + float4 d1 = bufferReferences.vertices[offset + 1]; // n.yz, uv.xy + tri.vertices[i].pos = d0.xyz; + tri.vertices[i].uv = d1.zw; + } + // Calculate values at barycentric coordinates + float3 barycentricCoords = float3(1.0f - attribs.bary.x - attribs.bary.y, attribs.bary.x, attribs.bary.y); + tri.uv = tri.vertices[0].uv * barycentricCoords.x + tri.vertices[1].uv * barycentricCoords.y + tri.vertices[2].uv * barycentricCoords.z; + return tri; +} + +[shader("raygeneration")] +void raygenerationMain() +{ + uint3 LaunchID = DispatchRaysIndex(); + uint3 LaunchSize = DispatchRaysDimensions(); + + const float2 pixelCenter = float2(LaunchID.xy) + float2(0.5, 0.5); + const float2 inUV = pixelCenter / float2(LaunchSize.xy); + float2 d = inUV * 2.0 - 1.0; + float4 target = mul(cam.projInverse, float4(d.x, d.y, 1, 1)); + + RayDesc rayDesc; + rayDesc.Origin = mul(cam.viewInverse, float4(0, 0, 0, 1)).xyz; + rayDesc.Direction = mul(cam.viewInverse, float4(normalize(target.xyz), 0)).xyz; + rayDesc.TMin = 0.001; + rayDesc.TMax = 10000.0; + + Payload payload; + TraceRay(accelStruct, RAY_FLAG_NONE, 0xff, 0, 0, 0, rayDesc, payload); + + image[int2(LaunchID.xy)] = float4(payload.hitValue, 0.0); +} + +[shader("closesthit")] +void closesthitMain(inout Payload payload, in Attributes attribs) +{ + Triangle tri = unpackTriangle(PrimitiveIndex(), attribs); + // Fetch the color for this ray hit from the texture at the current uv coordinates + float4 color = samplerColor.SampleLevel(tri.uv, 0.0); + payload.hitValue = color.rgb; +} + +[shader("anyhit")] +void anyhitMain(inout Payload payload, in Attributes attribs) +{ + Triangle tri = unpackTriangle(PrimitiveIndex(), attribs); + float4 color = samplerColor.SampleLevel(tri.uv, 0.0); + // If the alpha value of the texture at the current UV coordinates is below a given threshold, we'll ignore this intersection + // That way ray traversal will be stopped and the miss shader will be invoked + if (color.a < 0.9) { + IgnoreHit(); + } +} + +[shader("miss")] +void missMain(inout Payload payload) +{ + payload.hitValue = float3(0.0, 0.0, 0.2); +} \ No newline at end of file From 04ab171247a24cc367a4182540c4d038cf8a4b9e Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Thu, 15 May 2025 19:04:04 +0200 Subject: [PATCH 48/73] Add slang shaders for headless samples --- examples/computeheadless/computeheadless.cpp | 25 ++++++++++---- examples/renderheadless/renderheadless.cpp | 22 +++++++++++-- shaders/slang/computeheadless/headless.slang | 34 ++++++++++++++++++++ shaders/slang/renderheadless/triangle.slang | 32 ++++++++++++++++++ 4 files changed, 104 insertions(+), 9 deletions(-) create mode 100644 shaders/slang/computeheadless/headless.slang create mode 100644 shaders/slang/renderheadless/triangle.slang diff --git a/examples/computeheadless/computeheadless.cpp b/examples/computeheadless/computeheadless.cpp index 334504fd..d0805037 100644 --- a/examples/computeheadless/computeheadless.cpp +++ b/examples/computeheadless/computeheadless.cpp @@ -82,6 +82,8 @@ public: VkDebugReportCallbackEXT debugReportCallback{}; + std::string shaderDir = "glsl"; + VkResult createBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, VkBuffer *buffer, VkDeviceMemory *memory, VkDeviceSize size, void *data = nullptr) { // Create the buffer handle @@ -132,11 +134,19 @@ public: vks::android::loadVulkanLibrary(); #endif + if (commandLineParser.isSet("shaders")) { + shaderDir = commandLineParser.getValueAsString("shaders", "glsl"); + } + VkApplicationInfo appInfo = {}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pApplicationName = "Vulkan headless example"; appInfo.pEngineName = "VulkanExample"; appInfo.apiVersion = VK_API_VERSION_1_0; + // Shaders generated by Slang require a certain SPIR-V environment that can't be satisfied by Vulkan 1.0, so we need to expliclity up that to at least 1.1 and enable some required extensions + if (shaderDir == "slang") { + appInfo.apiVersion = VK_API_VERSION_1_1; + } /* Vulkan instance creation (without surface extensions) @@ -159,7 +169,7 @@ public: bool layersAvailable = true; for (auto layerName : validationLayers) { bool layerAvailable = false; - for (auto instanceLayer : instanceLayers) { + for (auto& instanceLayer : instanceLayers) { if (strcmp(instanceLayer.layerName, layerName) == 0) { layerAvailable = true; break; @@ -260,8 +270,15 @@ public: deviceCreateInfo.queueCreateInfoCount = 1; deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo; std::vector deviceExtensions = {}; + + // Shaders generated by Slang require a certain SPIR-V environment that can't be satisfied by Vulkan 1.0, so we need to expliclity up that to at least 1.1 and enable some required extensions + if (shaderDir == "slang") { + deviceExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME); + deviceExtensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME); + } + #if (defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT)) && defined(VK_KHR_portability_subset) - // SRS - When running on macOS with MoltenVK and VK_KHR_portability_subset is defined and supported by the device, enable the extension + // When running on macOS with MoltenVK and VK_KHR_portability_subset is defined and supported by the device, enable the extension uint32_t deviceExtCount = 0; vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &deviceExtCount, nullptr); if (deviceExtCount > 0) @@ -410,10 +427,6 @@ public: VkSpecializationMapEntry specializationMapEntry = vks::initializers::specializationMapEntry(0, 0, sizeof(uint32_t)); VkSpecializationInfo specializationInfo = vks::initializers::specializationInfo(1, &specializationMapEntry, sizeof(SpecializationData), &specializationData); - std::string shaderDir = "glsl"; - if (commandLineParser.isSet("shaders")) { - shaderDir = commandLineParser.getValueAsString("shaders", "glsl"); - } const std::string shadersPath = getShaderBasePath() + shaderDir + "/computeheadless/"; VkPipelineShaderStageCreateInfo shaderStage = {}; diff --git a/examples/renderheadless/renderheadless.cpp b/examples/renderheadless/renderheadless.cpp index 6b2fa20e..59dbbac1 100644 --- a/examples/renderheadless/renderheadless.cpp +++ b/examples/renderheadless/renderheadless.cpp @@ -97,6 +97,8 @@ public: VkDebugReportCallbackEXT debugReportCallback{}; + std::string shaderDir = "glsl"; + uint32_t getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties) { VkPhysicalDeviceMemoryProperties deviceMemoryProperties; vkGetPhysicalDeviceMemoryProperties(physicalDevice, &deviceMemoryProperties); @@ -163,11 +165,19 @@ public: vks::android::loadVulkanLibrary(); #endif + if (commandLineParser.isSet("shaders")) { + shaderDir = commandLineParser.getValueAsString("shaders", "glsl"); + } + VkApplicationInfo appInfo = {}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pApplicationName = "Vulkan headless example"; appInfo.pEngineName = "VulkanExample"; appInfo.apiVersion = VK_API_VERSION_1_0; + // Shaders generated by Slang require a certain SPIR-V environment that can't be satisfied by Vulkan 1.0, so we need to expliclity up that to at least 1.1 and enable some required extensions + if (shaderDir == "slang") { + appInfo.apiVersion = VK_API_VERSION_1_1; + } /* Vulkan instance creation (without surface extensions) @@ -190,7 +200,7 @@ public: bool layersAvailable = true; for (auto layerName : validationLayers) { bool layerAvailable = false; - for (auto instanceLayer : instanceLayers) { + for (auto& instanceLayer : instanceLayers) { if (strcmp(instanceLayer.layerName, layerName) == 0) { layerAvailable = true; break; @@ -290,8 +300,15 @@ public: deviceCreateInfo.queueCreateInfoCount = 1; deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo; std::vector deviceExtensions = {}; + + // Shaders generated by Slang require a certain SPIR-V environment that can't be satisfied by Vulkan 1.0, so we need to expliclity up that to at least 1.1 and enable some required extensions + if (shaderDir == "slang") { + deviceExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME); + deviceExtensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME); + } + #if (defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT)) && defined(VK_KHR_portability_subset) - // SRS - When running on macOS with MoltenVK and VK_KHR_portability_subset is defined and supported by the device, enable the extension + // When running on macOS with MoltenVK and VK_KHR_portability_subset is defined and supported by the device, enable the extension uint32_t deviceExtCount = 0; vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &deviceExtCount, nullptr); if (deviceExtCount > 0) @@ -643,7 +660,6 @@ public: pipelineCreateInfo.pVertexInputState = &vertexInputState; - std::string shaderDir = "glsl"; if (commandLineParser.isSet("shaders")) { shaderDir = commandLineParser.getValueAsString("shaders", "glsl"); } diff --git a/shaders/slang/computeheadless/headless.slang b/shaders/slang/computeheadless/headless.slang new file mode 100644 index 00000000..7f5db02a --- /dev/null +++ b/shaders/slang/computeheadless/headless.slang @@ -0,0 +1,34 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +RWStructuredBuffer values; + +[[SpecializationConstant]] const uint BUFFER_ELEMENTS = 32; + +uint fibonacci(uint n) { + if(n <= 1){ + return n; + } + uint curr = 1; + uint prev = 1; + for(uint i = 2; i < n; ++i) { + uint temp = curr; + curr += prev; + prev = temp; + } + return curr; +} + +[numthreads(1, 1, 1)] +[shader("compute")] +void computeMain(uint3 GlobalInvocationID : SV_DispatchThreadID) +{ + uint index = GlobalInvocationID.x; + if (index >= BUFFER_ELEMENTS) + return; + values[index] = fibonacci(values[index]); +} + diff --git a/shaders/slang/renderheadless/triangle.slang b/shaders/slang/renderheadless/triangle.slang new file mode 100644 index 00000000..11fc0630 --- /dev/null +++ b/shaders/slang/renderheadless/triangle.slang @@ -0,0 +1,32 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Color; +}; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform float4x4 mvp) +{ + VSOutput output; + output.Color = input.Color; + output.Pos = mul(mvp, float4(input.Pos.xyz, 1.0)); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return float4(input.Color, 1.0); +} \ No newline at end of file From cb1f443160152d1933d57a7c40373909fb01c46b Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Thu, 15 May 2025 19:53:43 +0200 Subject: [PATCH 49/73] Add slang shaders for screenshot sample --- shaders/slang/screenshot/mesh.slang | 60 +++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 shaders/slang/screenshot/mesh.slang diff --git a/shaders/slang/screenshot/mesh.slang b/shaders/slang/screenshot/mesh.slang new file mode 100644 index 00000000..abbc7a36 --- /dev/null +++ b/shaders/slang/screenshot/mesh.slang @@ -0,0 +1,60 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + + struct VSInput + { + float3 Pos; + float3 Normal; + float3 Color; + }; + + struct VSOutput + { + float4 Pos : SV_POSITION; + float3 Color; + float3 Normal; + float3 ViewVec; + float3 LightVec; + }; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Normal = input.Normal; + output.Color = input.Color; + + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos.xyz, 1.0)))); + + output.Normal = mul((float3x3)ubo.model, input.Normal); + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + + const float3 lightPos = float3(1.0, -1.0, 1.0); + output.LightVec = lightPos.xyz - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + const float ambient = 0.1; + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0).rrr; + float3 specular = pow(max(dot(R, V), 0.0), 32.0); + return float4((ambient + diffuse) * input.Color.rgb + specular, 1.0); +} \ No newline at end of file From c2e3b494da34e20b753fe9481f048d882b1b4b8d Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Fri, 16 May 2025 19:15:29 +0200 Subject: [PATCH 50/73] Add slang shaders for additional samples --- shaders/slang/displacement/displacement.slang | 118 ++++++++++++++++++ shaders/slang/occlusionquery/mesh.slang | 67 ++++++++++ shaders/slang/occlusionquery/occluder.slang | 42 +++++++ shaders/slang/occlusionquery/simple.slang | 39 ++++++ 4 files changed, 266 insertions(+) create mode 100644 shaders/slang/displacement/displacement.slang create mode 100644 shaders/slang/occlusionquery/mesh.slang create mode 100644 shaders/slang/occlusionquery/occluder.slang create mode 100644 shaders/slang/occlusionquery/simple.slang diff --git a/shaders/slang/displacement/displacement.slang b/shaders/slang/displacement/displacement.slang new file mode 100644 index 00000000..ec8f171c --- /dev/null +++ b/shaders/slang/displacement/displacement.slang @@ -0,0 +1,118 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; +}; + +struct HSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; +}; + +struct DSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; + float3 EyePos; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; + float tessAlpha; + float tessStrength; + float tessLevel; +}; +ConstantBuffer ubo; + +Sampler2D samplerColorAndDisplacementMap; + +struct ConstantsHSOutput +{ + float TessLevelOuter[3] : SV_TessFactor; + float TessLevelInner[2] : SV_InsideTessFactor; +}; + +ConstantsHSOutput ConstantsHS() +{ + ConstantsHSOutput output; + output.TessLevelInner[0] = ubo.tessLevel; + output.TessLevelInner[1] = ubo.tessLevel; + output.TessLevelOuter[0] = ubo.tessLevel; + output.TessLevelOuter[1] = ubo.tessLevel; + output.TessLevelOuter[2] = ubo.tessLevel; + return output; +} + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Pos = float4(input.Pos.xyz, 1.0); + output.UV = input.UV; + output.Normal = input.Normal; + return output; +} + +[shader("hull")] +[domain("tri")] +[partitioning("integer")] +[outputtopology("triangle_cw")] +[outputcontrolpoints(3)] +[patchconstantfunc("ConstantsHS")] +[maxtessfactor(20.0f)] +HSOutput hullMain(InputPatch patch, uint InvocationID: SV_OutputControlPointID) +{ + HSOutput output; + output.Pos = patch[InvocationID].Pos; + output.Normal = patch[InvocationID].Normal; + output.UV = patch[InvocationID].UV; + return output; +} + +[shader("domain")] +[domain("tri")] +DSOutput domainMain(ConstantsHSOutput input, float3 TessCoord: SV_DomainLocation, const OutputPatch patch) +{ + DSOutput output; + output.Pos = (TessCoord.x * patch[0].Pos) + (TessCoord.y * patch[1].Pos) + (TessCoord.z * patch[2].Pos); + output.UV = (TessCoord.x * patch[0].UV) + (TessCoord.y * patch[1].UV) + (TessCoord.z * patch[2].UV); + output.Normal = TessCoord.x * patch[0].Normal + TessCoord.y * patch[1].Normal + TessCoord.z * patch[2].Normal; + output.Pos.xyz += normalize(output.Normal) * (max(samplerColorAndDisplacementMap.SampleLevel(output.UV.xy, 0).a, 0.0) * ubo.tessStrength); + output.EyePos = output.Pos.xyz; + output.LightVec = normalize(ubo.lightPos.xyz - output.EyePos); + output.Pos = mul(ubo.projection, mul(ubo.model, output.Pos)); + return output; +} + +[shader("fragment")] +float4 fragmentMain(DSOutput input) +{ + float3 N = normalize(input.Normal); + float3 L = normalize(float3(1.0, 1.0, 1.0)); + float3 Eye = normalize(-input.EyePos); + float3 Reflected = normalize(reflect(-input.LightVec, input.Normal)); + float4 IAmbient = float4(0.0, 0.0, 0.0, 1.0); + float4 IDiffuse = float4(1.0, 1.0, 1.0, 1.0) * max(dot(input.Normal, input.LightVec), 0.0); + return float4((IAmbient + IDiffuse) * float4(samplerColorAndDisplacementMap.Sample(input.UV).rgb, 1.0)); +} diff --git a/shaders/slang/occlusionquery/mesh.slang b/shaders/slang/occlusionquery/mesh.slang new file mode 100644 index 00000000..50067670 --- /dev/null +++ b/shaders/slang/occlusionquery/mesh.slang @@ -0,0 +1,67 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float Visible; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float4 color; + float4 lightPos; + float visible; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color * ubo.color.rgb; + output.Visible = ubo.visible; + float4x4 modelView = mul(ubo.view, ubo.model); + output.Pos = mul(ubo.projection, mul(modelView, float4(input.Pos.xyz, 1.0))); + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + output.LightVec = ubo.lightPos.xyz - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + if (input.Visible > 0.0) + { + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.25) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 8.0) * float3(0.75); + return float4(diffuse + specular, 1.0); + } + else + { + return float4(float3(0.1, 0.1, 0.1), 1.0); + } +} \ No newline at end of file diff --git a/shaders/slang/occlusionquery/occluder.slang b/shaders/slang/occlusionquery/occluder.slang new file mode 100644 index 00000000..7fa118d7 --- /dev/null +++ b/shaders/slang/occlusionquery/occluder.slang @@ -0,0 +1,42 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Color; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float4 color; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color * ubo.color.rgb; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos.xyz, 1.0)))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return float4(input.Color, 0.5); +} \ No newline at end of file diff --git a/shaders/slang/occlusionquery/simple.slang b/shaders/slang/occlusionquery/simple.slang new file mode 100644 index 00000000..7cfc4bfd --- /dev/null +++ b/shaders/slang/occlusionquery/simple.slang @@ -0,0 +1,39 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Color; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos.xyz, 1.0)))); + return output; +} + +[shader("fragment")] +float4 fragmentMain() +{ + return float4(1.0, 1.0, 1.0, 1.0); +} \ No newline at end of file From c58fd1844b0ec7177192aef70ae9d2e5afcff6e6 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Fri, 16 May 2025 20:12:30 +0200 Subject: [PATCH 51/73] Add slang shaders for tessellation samples --- .../slang/terraintessellation/skysphere.slang | 42 +++ .../slang/terraintessellation/terrain.slang | 252 ++++++++++++++++++ shaders/slang/tessellation/base.slang | 46 ++++ shaders/slang/tessellation/passthrough.slang | 83 ++++++ shaders/slang/tessellation/pntriangles.slang | 216 +++++++++++++++ 5 files changed, 639 insertions(+) create mode 100644 shaders/slang/terraintessellation/skysphere.slang create mode 100644 shaders/slang/terraintessellation/terrain.slang create mode 100644 shaders/slang/tessellation/base.slang create mode 100644 shaders/slang/tessellation/passthrough.slang create mode 100644 shaders/slang/tessellation/pntriangles.slang diff --git a/shaders/slang/terraintessellation/skysphere.slang b/shaders/slang/terraintessellation/skysphere.slang new file mode 100644 index 00000000..1d11ad44 --- /dev/null +++ b/shaders/slang/terraintessellation/skysphere.slang @@ -0,0 +1,42 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +struct UBO +{ + float4x4 mvp; +}; +ConstantBuffer ubo; + +Sampler2D samplerColorMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Pos = mul(ubo.mvp, float4(input.Pos, 1.0)); + output.UV = input.UV; + return output; +} + + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return samplerColorMap.Sample(input.UV); +} diff --git a/shaders/slang/terraintessellation/terrain.slang b/shaders/slang/terraintessellation/terrain.slang new file mode 100644 index 00000000..ad9d475e --- /dev/null +++ b/shaders/slang/terraintessellation/terrain.slang @@ -0,0 +1,252 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; +}; + +struct DSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; + float3 ViewVec; + float3 LightVec; + float3 EyePos; + float3 WorldPos; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 lightPos; + float4 frustumPlanes[6]; + float displacementFactor; + float tessellationFactor; + float2 viewportDim; + float tessellatedEdgeSize; +}; +ConstantBuffer ubo; + +Sampler2D samplerHeight; +Sampler2DArray samplerLayers; + +struct HSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal : NORMAL0; + float2 UV : TEXCOORD0; +}; + +struct ConstantsHSOutput +{ + float TessLevelOuter[4] : SV_TessFactor; + float TessLevelInner[2] : SV_InsideTessFactor; +}; + +// Calculate the tessellation factor based on screen space +// dimensions of the edge +float screenSpaceTessFactor(float4 p0, float4 p1) +{ + // Calculate edge mid point + float4 midPoint = 0.5 * (p0 + p1); + // Sphere radius as distance between the control points + float radius = distance(p0, p1) / 2.0; + + // View space + float4 v0 = mul(ubo.modelview, midPoint); + + // Project into clip space + float4 clip0 = mul(ubo.projection, (v0 - float4(radius, float3(0.0, 0.0, 0.0)))); + float4 clip1 = mul(ubo.projection, (v0 + float4(radius, float3(0.0, 0.0, 0.0)))); + + // Get normalized device coordinates + clip0 /= clip0.w; + clip1 /= clip1.w; + + // Convert to viewport coordinates + clip0.xy *= ubo.viewportDim; + clip1.xy *= ubo.viewportDim; + + // Return the tessellation factor based on the screen size + // given by the distance of the two edge control points in screen space + // and a reference (min.) tessellation size for the edge set by the application + return clamp(distance(clip0, clip1) / ubo.tessellatedEdgeSize * ubo.tessellationFactor, 1.0, 64.0); +} + +// Checks the current's patch visibility against the frustum using a sphere check +// Sphere radius is given by the patch size +bool frustumCheck(float4 Pos, float2 inUV) +{ + // Fixed radius (increase if patch size is increased in example) + const float radius = 8.0f; + float4 pos = Pos; + pos.y -= samplerHeight.SampleLevel(inUV, 0.0).r * ubo.displacementFactor; + + // Check sphere against frustum planes + for (int i = 0; i < 6; i++) { + if (dot(pos, ubo.frustumPlanes[i]) + radius < 0.0) + { + return false; + } + } + return true; +} + +ConstantsHSOutput ConstantsHS(InputPatch patch) +{ + ConstantsHSOutput output; + + if (!frustumCheck(patch[0].Pos, patch[0].UV)) + { + output.TessLevelInner[0] = 0.0; + output.TessLevelInner[1] = 0.0; + output.TessLevelOuter[0] = 0.0; + output.TessLevelOuter[1] = 0.0; + output.TessLevelOuter[2] = 0.0; + output.TessLevelOuter[3] = 0.0; + } + else + { + if (ubo.tessellationFactor > 0.0) + { + output.TessLevelOuter[0] = screenSpaceTessFactor(patch[3].Pos, patch[0].Pos); + output.TessLevelOuter[1] = screenSpaceTessFactor(patch[0].Pos, patch[1].Pos); + output.TessLevelOuter[2] = screenSpaceTessFactor(patch[1].Pos, patch[2].Pos); + output.TessLevelOuter[3] = screenSpaceTessFactor(patch[2].Pos, patch[3].Pos); + output.TessLevelInner[0] = lerp(output.TessLevelOuter[0], output.TessLevelOuter[3], 0.5); + output.TessLevelInner[1] = lerp(output.TessLevelOuter[2], output.TessLevelOuter[1], 0.5); + } + else + { + // Tessellation factor can be set to zero by example + // to demonstrate a simple passthrough + output.TessLevelInner[0] = 1.0; + output.TessLevelInner[1] = 1.0; + output.TessLevelOuter[0] = 1.0; + output.TessLevelOuter[1] = 1.0; + output.TessLevelOuter[2] = 1.0; + output.TessLevelOuter[3] = 1.0; + } + } + + return output; +} + +float3 sampleTerrainLayer(float2 inUV) +{ + // Define some layer ranges for sampling depending on terrain height + float2 layers[6]; + layers[0] = float2(-10.0, 10.0); + layers[1] = float2(5.0, 45.0); + layers[2] = float2(45.0, 80.0); + layers[3] = float2(75.0, 100.0); + layers[4] = float2(95.0, 140.0); + layers[5] = float2(140.0, 190.0); + + float3 color = float3(0.0, 0.0, 0.0); + + // Get height from displacement map + float height = samplerHeight.SampleLevel(inUV, 0.0).r * 255.0; + + for (int i = 0; i < 6; i++) + { + float range = layers[i].y - layers[i].x; + float weight = (range - abs(height - layers[i].y)) / range; + weight = max(0.0, weight); + color += weight * samplerLayers.Sample(float3(inUV * 16.0, i)).rgb; + } + + return color; +} + +float fog(float density, float4 FragCoord) +{ + const float LOG2 = -1.442695; + float dist = FragCoord.z / FragCoord.w * 0.1; + float d = density * dist; + return 1.0 - clamp(exp2(d * d * LOG2), 0.0, 1.0); +} + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Pos = float4(input.Pos.xyz, 1.0); + output.UV = input.UV; + output.Normal = input.Normal; + return output; +} + +[shader("hull")] +[domain("quad")] +[partitioning("integer")] +[outputtopology("triangle_cw")] +[outputcontrolpoints(4)] +[patchconstantfunc("ConstantsHS")] +[maxtessfactor(20.0f)] +HSOutput hullMain(InputPatch patch, uint InvocationID: SV_OutputControlPointID) +{ + HSOutput output; + output.Pos = patch[InvocationID].Pos; + output.Normal = patch[InvocationID].Normal; + output.UV = patch[InvocationID].UV; + return output; +} + +[shader("domain")] +[domain("quad")] +DSOutput domainMain(ConstantsHSOutput input, float2 TessCoord: SV_DomainLocation, const OutputPatch patch) +{ + // Interpolate UV coordinates + DSOutput output; + float2 uv1 = lerp(patch[0].UV, patch[1].UV, TessCoord.x); + float2 uv2 = lerp(patch[3].UV, patch[2].UV, TessCoord.x); + output.UV = lerp(uv1, uv2, TessCoord.y); + + float3 n1 = lerp(patch[0].Normal, patch[1].Normal, TessCoord.x); + float3 n2 = lerp(patch[3].Normal, patch[2].Normal, TessCoord.x); + output.Normal = lerp(n1, n2, TessCoord.y); + + // Interpolate positions + float4 pos1 = lerp(patch[0].Pos, patch[1].Pos, TessCoord.x); + float4 pos2 = lerp(patch[3].Pos, patch[2].Pos, TessCoord.x); + float4 pos = lerp(pos1, pos2, TessCoord.y); + // Displace + pos.y -= samplerHeight.SampleLevel(output.UV, 0.0).r * ubo.displacementFactor; + // Perspective projection + output.Pos = mul(ubo.projection, mul(ubo.modelview, pos)); + + // Calculate vectors for lighting based on tessellated position + output.ViewVec = -pos.xyz; + output.LightVec = normalize(ubo.lightPos.xyz + output.ViewVec); + output.WorldPos = pos.xyz; + output.EyePos = mul(ubo.modelview, pos).xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(DSOutput input) +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 ambient = float3(0.5, 0.5, 0.5); + float3 diffuse = max(dot(N, L), 0.0) * float3(1.0, 1.0, 1.0); + float4 color = float4((ambient + diffuse) * sampleTerrainLayer(input.UV), 1.0); + const float4 fogColor = float4(0.47, 0.5, 0.67, 0.0); + return lerp(color, fogColor, fog(0.25, input.Pos)); +} diff --git a/shaders/slang/tessellation/base.slang b/shaders/slang/tessellation/base.slang new file mode 100644 index 00000000..e671b8df --- /dev/null +++ b/shaders/slang/tessellation/base.slang @@ -0,0 +1,46 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; +}; + +struct DSOutput +{ + float3 Normal; + float2 UV; +}; + +[[vk::binding(0, 1)]] Sampler2D samplerColorMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Pos = float4(input.Pos.xyz, 1.0); + output.Normal = input.Normal; + output.UV = input.UV; + return output; +} + +[shader("fragment")] +float4 fragmentMain(DSOutput input) +{ + float3 N = normalize(input.Normal); + float3 L = normalize(float3(0.0, -4.0, 4.0)); + float4 color = samplerColorMap.Sample(input.UV); + return float4(clamp(max(dot(N,L), 0.0), 0.2, 1.0) * color.rgb * 1.5, 1); +} diff --git a/shaders/slang/tessellation/passthrough.slang b/shaders/slang/tessellation/passthrough.slang new file mode 100644 index 00000000..b25454e7 --- /dev/null +++ b/shaders/slang/tessellation/passthrough.slang @@ -0,0 +1,83 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; +}; + +struct HSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; +}; + +struct DSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; +}; + +struct ConstantsHSOutput +{ + float TessLevelOuter[3] : SV_TessFactor; + float TessLevelInner[2] : SV_InsideTessFactor; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float tessAlpha; + float tessLevel; +}; +ConstantBuffer ubo; + +ConstantsHSOutput ConstantsHS(InputPatch patch) +{ + ConstantsHSOutput output; + output.TessLevelInner[0] = 1; + output.TessLevelInner[1] = 1; + output.TessLevelOuter[0] = 1; + output.TessLevelOuter[1] = 1; + output.TessLevelOuter[2] = 1; + return output; +} + +[shader("hull")] +[domain("tri")] +[partitioning("integer")] +[outputtopology("triangle_cw")] +[outputcontrolpoints(3)] +[patchconstantfunc("ConstantsHS")] +[maxtessfactor(20.0f)] +HSOutput hullMain(InputPatch patch, uint InvocationID : SV_OutputControlPointID) +{ + HSOutput output; + output.Pos = patch[InvocationID].Pos; + output.Normal = patch[InvocationID].Normal; + output.UV = patch[InvocationID].UV; + return output; +} + +[shader("domain")] +[domain("tri")] +DSOutput domainMain(ConstantsHSOutput input, float3 TessCoord: SV_DomainLocation, const OutputPatch patch) +{ + DSOutput output = (DSOutput)0; + output.Pos = (TessCoord.x * patch[0].Pos) + + (TessCoord.y * patch[1].Pos) + + (TessCoord.z * patch[2].Pos); + output.Pos = mul(ubo.projection, mul(ubo.model, output.Pos)); + + output.Normal = TessCoord.x * patch[0].Normal + TessCoord.y * patch[1].Normal + TessCoord.z * patch[2].Normal; + output.UV = TessCoord.x * patch[0].UV + TessCoord.y * patch[1].UV + TessCoord.z * patch[2].UV; + return output; +} \ No newline at end of file diff --git a/shaders/slang/tessellation/pntriangles.slang b/shaders/slang/tessellation/pntriangles.slang new file mode 100644 index 00000000..f1761ff7 --- /dev/null +++ b/shaders/slang/tessellation/pntriangles.slang @@ -0,0 +1,216 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; +}; + +struct HSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; + float pnPatch[10]; +}; + +struct DSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; +}; + +struct ConstantsHSOutput +{ + float TessLevelOuter[3] : SV_TessFactor; + float TessLevelInner[2] : SV_InsideTessFactor; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float tessAlpha; + float tessLevel; +}; +ConstantBuffer ubo; + +#define uvw TessCoord + +struct PnPatch +{ + float b210; + float b120; + float b021; + float b012; + float b102; + float b201; + float b111; + float n110; + float n011; + float n101; +}; + +PnPatch GetPnPatch(float pnPatch[10]) +{ + PnPatch output; + output.b210 = pnPatch[0]; + output.b120 = pnPatch[1]; + output.b021 = pnPatch[2]; + output.b012 = pnPatch[3]; + output.b102 = pnPatch[4]; + output.b201 = pnPatch[5]; + output.b111 = pnPatch[6]; + output.n110 = pnPatch[7]; + output.n011 = pnPatch[8]; + output.n101 = pnPatch[9]; + return output; +} + +void SetPnPatch(out float output[10], PnPatch patch) +{ + output[0] = patch.b210; + output[1] = patch.b120; + output[2] = patch.b021; + output[3] = patch.b012; + output[4] = patch.b102; + output[5] = patch.b201; + output[6] = patch.b111; + output[7] = patch.n110; + output[8] = patch.n011; + output[9] = patch.n101; +} + +float wij(float4 iPos, float3 iNormal, float4 jPos) +{ + return dot(jPos.xyz - iPos.xyz, iNormal); +} + +float vij(float4 iPos, float3 iNormal, float4 jPos, float3 jNormal) +{ + float3 Pj_minus_Pi = jPos.xyz - iPos.xyz; + float3 Ni_plus_Nj = iNormal + jNormal; + return 2.0 * dot(Pj_minus_Pi, Ni_plus_Nj) / dot(Pj_minus_Pi, Pj_minus_Pi); +} + +ConstantsHSOutput ConstantsHS(InputPatch patch) +{ + ConstantsHSOutput output; + output.TessLevelOuter[0] = ubo.tessLevel; + output.TessLevelOuter[1] = ubo.tessLevel; + output.TessLevelOuter[2] = ubo.tessLevel; + output.TessLevelInner[0] = ubo.tessLevel; + output.TessLevelInner[1] = ubo.tessLevel; + return output; +} + +[shader("domain")] +[domain("tri")] +DSOutput domainMain(ConstantsHSOutput input, float3 TessCoord: SV_DomainLocation, const OutputPatch patch) +{ + PnPatch pnPatch[3]; + pnPatch[0] = GetPnPatch(patch[0].pnPatch); + pnPatch[1] = GetPnPatch(patch[1].pnPatch); + pnPatch[2] = GetPnPatch(patch[2].pnPatch); + + DSOutput output = (DSOutput)0; + float3 uvwSquared = uvw * uvw; + float3 uvwCubed = uvwSquared * uvw; + + // extract control points + float3 b210 = float3(pnPatch[0].b210, pnPatch[1].b210, pnPatch[2].b210); + float3 b120 = float3(pnPatch[0].b120, pnPatch[1].b120, pnPatch[2].b120); + float3 b021 = float3(pnPatch[0].b021, pnPatch[1].b021, pnPatch[2].b021); + float3 b012 = float3(pnPatch[0].b012, pnPatch[1].b012, pnPatch[2].b012); + float3 b102 = float3(pnPatch[0].b102, pnPatch[1].b102, pnPatch[2].b102); + float3 b201 = float3(pnPatch[0].b201, pnPatch[1].b201, pnPatch[2].b201); + float3 b111 = float3(pnPatch[0].b111, pnPatch[1].b111, pnPatch[2].b111); + + // extract control normals + float3 n110 = normalize(float3(pnPatch[0].n110, pnPatch[1].n110, pnPatch[2].n110)); + float3 n011 = normalize(float3(pnPatch[0].n011, pnPatch[1].n011, pnPatch[2].n011)); + float3 n101 = normalize(float3(pnPatch[0].n101, pnPatch[1].n101, pnPatch[2].n101)); + + // compute texcoords + output.UV = TessCoord[2] * patch[0].UV + TessCoord[0] * patch[1].UV + TessCoord[1] * patch[2].UV; + + // normal + // Barycentric normal + float3 barNormal = TessCoord[2] * patch[0].Normal + TessCoord[0] * patch[1].Normal + TessCoord[1] * patch[2].Normal; + float3 pnNormal = patch[0].Normal * uvwSquared[2] + patch[1].Normal * uvwSquared[0] + patch[2].Normal * uvwSquared[1] + + n110 * uvw[2] * uvw[0] + n011 * uvw[0] * uvw[1] + n101 * uvw[2] * uvw[1]; + output.Normal = ubo.tessAlpha * pnNormal + (1.0 - ubo.tessAlpha) * barNormal; + + // compute interpolated pos + float3 barPos = TessCoord[2] * patch[0].Pos.xyz + + TessCoord[0] * patch[1].Pos.xyz + + TessCoord[1] * patch[2].Pos.xyz; + + // save some computations + uvwSquared *= 3.0; + + // compute PN position + float3 pnPos = patch[0].Pos.xyz * uvwCubed[2] + + patch[1].Pos.xyz * uvwCubed[0] + + patch[2].Pos.xyz * uvwCubed[1] + + b210 * uvwSquared[2] * uvw[0] + + b120 * uvwSquared[0] * uvw[2] + + b201 * uvwSquared[2] * uvw[1] + + b021 * uvwSquared[0] * uvw[1] + + b102 * uvwSquared[1] * uvw[2] + + b012 * uvwSquared[1] * uvw[0] + + b111 * 6.0 * uvw[0] * uvw[1] * uvw[2]; + + // final position and normal + float3 finalPos = (1.0 - ubo.tessAlpha) * barPos + ubo.tessAlpha * pnPos; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(finalPos, 1.0))); + return output; +} + +[shader("hull")] +[domain("tri")] +[partitioning("fractional_odd")] +[outputtopology("triangle_cw")] +[outputcontrolpoints(3)] +[patchconstantfunc("ConstantsHS")] +[maxtessfactor(20.0f)] +HSOutput hullMain(InputPatch patch, uint InvocationID : SV_OutputControlPointID) +{ + HSOutput output; + // get data + output.Pos = patch[InvocationID].Pos; + output.Normal = patch[InvocationID].Normal; + output.UV = patch[InvocationID].UV; + + // set base + float P0 = patch[0].Pos[InvocationID]; + float P1 = patch[1].Pos[InvocationID]; + float P2 = patch[2].Pos[InvocationID]; + float N0 = patch[0].Normal[InvocationID]; + float N1 = patch[1].Normal[InvocationID]; + float N2 = patch[2].Normal[InvocationID]; + + // compute control points + PnPatch pnPatch; + pnPatch.b210 = (2.0*P0 + P1 - wij(patch[0].Pos, patch[0].Normal, patch[1].Pos)*N0)/3.0; + pnPatch.b120 = (2.0*P1 + P0 - wij(patch[1].Pos, patch[1].Normal, patch[0].Pos)*N1)/3.0; + pnPatch.b021 = (2.0*P1 + P2 - wij(patch[1].Pos, patch[1].Normal, patch[2].Pos)*N1)/3.0; + pnPatch.b012 = (2.0*P2 + P1 - wij(patch[2].Pos, patch[2].Normal, patch[1].Pos)*N2)/3.0; + pnPatch.b102 = (2.0*P2 + P0 - wij(patch[2].Pos, patch[2].Normal, patch[0].Pos)*N2)/3.0; + pnPatch.b201 = (2.0*P0 + P2 - wij(patch[0].Pos, patch[0].Normal, patch[2].Pos)*N0)/3.0; + float E = ( pnPatch.b210 + pnPatch.b120 + pnPatch.b021 + pnPatch.b012 + pnPatch.b102 + pnPatch.b201 ) / 6.0; + float V = (P0 + P1 + P2)/3.0; + pnPatch.b111 = E + (E - V)*0.5; + pnPatch.n110 = N0+N1-vij(patch[0].Pos, patch[0].Normal, patch[1].Pos, patch[1].Normal)*(P1-P0); + pnPatch.n011 = N1+N2-vij(patch[1].Pos, patch[1].Normal, patch[2].Pos, patch[2].Normal)*(P2-P1); + pnPatch.n101 = N2+N0-vij(patch[2].Pos, patch[2].Normal, patch[0].Pos, patch[0].Normal)*(P0-P2); + SetPnPatch(output.pnPatch, pnPatch); + + return output; +} \ No newline at end of file From e4b7bb1a01b12b322d668d396adde7f38e34cfae Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 17 May 2025 16:42:07 +0200 Subject: [PATCH 52/73] Add slang shaders for compute cloth sample --- shaders/slang/computecloth/cloth.slang | 190 ++++++++++++++++++++++++ shaders/slang/computecloth/sphere.slang | 55 +++++++ 2 files changed, 245 insertions(+) create mode 100644 shaders/slang/computecloth/cloth.slang create mode 100644 shaders/slang/computecloth/sphere.slang diff --git a/shaders/slang/computecloth/cloth.slang b/shaders/slang/computecloth/cloth.slang new file mode 100644 index 00000000..80e53606 --- /dev/null +++ b/shaders/slang/computecloth/cloth.slang @@ -0,0 +1,190 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float2 UV; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; + float3 Normal; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 lightPos; +}; +[[vk::binding(0,0)]] ConstantBuffer ubo; +[[vk::binding(1,0)]] Sampler2D samplerColor; + +struct Particle { + float4 pos; + float4 vel; + float4 uv; + float4 normal; +}; + +[[vk::binding(0,0)]] StructuredBuffer particleIn; +[[vk::binding(1,0)]] RWStructuredBuffer particleOut; + +struct UBOCompute +{ + float deltaT; + float particleMass; + float springStiffness; + float damping; + float restDistH; + float restDistV; + float restDistD; + float sphereRadius; + float4 spherePos; + float4 gravity; + int2 particleCount; +}; +[[vk::binding(2, 0)]] ConstantBuffer params; + +float3 springForce(float3 p0, float3 p1, float restDist) +{ + float3 dist = p0 - p1; + return normalize(dist) * params.springStiffness * (length(dist) - restDist); +} + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UV = input.UV; + output.Normal = input.Normal.xyz; + float4 eyePos = mul(ubo.modelview, float4(input.Pos.x, input.Pos.y, input.Pos.z, 1.0)); + output.Pos = mul(ubo.projection, eyePos); + float4 pos = float4(input.Pos, 1.0); + float3 lPos = ubo.lightPos.xyz; + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 color = samplerColor.Sample(input.UV).rgb; + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.15) * float3(1, 1, 1); + float3 specular = pow(max(dot(R, V), 0.0), 8.0) * float3(0.2, 0.2, 0.2); + return float4(diffuse * color.rgb + specular, 1.0); +} + +[shader("compute")] +[numthreads(10, 10, 1)] +void computeMain(uint3 id: SV_DispatchThreadID, uniform uint calculateNormals) +{ + uint index = id.y * params.particleCount.x + id.x; + if (index > params.particleCount.x * params.particleCount.y) + return; + + // Initial force from gravity + float3 force = params.gravity.xyz * params.particleMass; + + float3 pos = particleIn[index].pos.xyz; + float3 vel = particleIn[index].vel.xyz; + + // Spring forces from neighboring particles + // left + if (id.x > 0) { + force += springForce(particleIn[index-1].pos.xyz, pos, params.restDistH); + } + // right + if (id.x < params.particleCount.x - 1) { + force += springForce(particleIn[index + 1].pos.xyz, pos, params.restDistH); + } + // upper + if (id.y < params.particleCount.y - 1) { + force += springForce(particleIn[index + params.particleCount.x].pos.xyz, pos, params.restDistV); + } + // lower + if (id.y > 0) { + force += springForce(particleIn[index - params.particleCount.x].pos.xyz, pos, params.restDistV); + } + // upper-left + if ((id.x > 0) && (id.y < params.particleCount.y - 1)) { + force += springForce(particleIn[index + params.particleCount.x - 1].pos.xyz, pos, params.restDistD); + } + // lower-left + if ((id.x > 0) && (id.y > 0)) { + force += springForce(particleIn[index - params.particleCount.x - 1].pos.xyz, pos, params.restDistD); + } + // upper-right + if ((id.x < params.particleCount.x - 1) && (id.y < params.particleCount.y - 1)) { + force += springForce(particleIn[index + params.particleCount.x + 1].pos.xyz, pos, params.restDistD); + } + // lower-right + if ((id.x < params.particleCount.x - 1) && (id.y > 0)) { + force += springForce(particleIn[index - params.particleCount.x + 1].pos.xyz, pos, params.restDistD); + } + + force += (-params.damping * vel); + + // Integrate + float3 f = force * (1.0 / params.particleMass); + particleOut[index].pos = float4(pos + vel * params.deltaT + 0.5 * f * params.deltaT * params.deltaT, 1.0); + particleOut[index].vel = float4(vel + f * params.deltaT, 0.0); + + // Sphere collision + float3 sphereDist = particleOut[index].pos.xyz - params.spherePos.xyz; + if (length(sphereDist) < params.sphereRadius + 0.01) { + // If the particle is inside the sphere, push it to the outer radius + particleOut[index].pos.xyz = params.spherePos.xyz + normalize(sphereDist) * (params.sphereRadius + 0.01); + // Cancel out velocity + particleOut[index].vel = float4(0, 0, 0, 0); + } + + // Normals + if (calculateNormals == 1) { + float3 normal = float3(0, 0, 0); + float3 a, b, c; + if (id.y > 0) { + if (id.x > 0) { + a = particleIn[index - 1].pos.xyz - pos; + b = particleIn[index - params.particleCount.x - 1].pos.xyz - pos; + c = particleIn[index - params.particleCount.x].pos.xyz - pos; + normal += cross(a,b) + cross(b,c); + } + if (id.x < params.particleCount.x - 1) { + a = particleIn[index - params.particleCount.x].pos.xyz - pos; + b = particleIn[index - params.particleCount.x + 1].pos.xyz - pos; + c = particleIn[index + 1].pos.xyz - pos; + normal += cross(a,b) + cross(b,c); + } + } + if (id.y < params.particleCount.y - 1) { + if (id.x > 0) { + a = particleIn[index + params.particleCount.x].pos.xyz - pos; + b = particleIn[index + params.particleCount.x - 1].pos.xyz - pos; + c = particleIn[index - 1].pos.xyz - pos; + normal += cross(a,b) + cross(b,c); + } + if (id.x < params.particleCount.x - 1) { + a = particleIn[index + 1].pos.xyz - pos; + b = particleIn[index + params.particleCount.x + 1].pos.xyz - pos; + c = particleIn[index + params.particleCount.x].pos.xyz - pos; + normal += cross(a,b) + cross(b,c); + } + } + particleOut[index].normal = float4(normalize(normal), 0.0f); + } +} \ No newline at end of file diff --git a/shaders/slang/computecloth/sphere.slang b/shaders/slang/computecloth/sphere.slang new file mode 100644 index 00000000..99959727 --- /dev/null +++ b/shaders/slang/computecloth/sphere.slang @@ -0,0 +1,55 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float2 UV; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 lightPos; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + float4 eyePos = mul(ubo.modelview, float4(input.Pos.x, input.Pos.y, input.Pos.z, 1.0)); + output.Pos = mul(ubo.projection, eyePos); + float4 pos = float4(input.Pos, 1.0); + float3 lPos = ubo.lightPos.xyz; + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + output.Normal = input.Normal; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 color = float3(0.5, 0.5, 0.5); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.15); + float3 specular = pow(max(dot(R, V), 0.0), 32.0); + return float4(diffuse * color.rgb + specular, 1.0); +} From ad5b22c5a20b43ee70738ec8fbd198d402881f61 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 17 May 2025 16:52:08 +0200 Subject: [PATCH 53/73] Add slang shaders for parallax mapping sample --- shaders/slang/parallaxmapping/parallax.slang | 150 +++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 shaders/slang/parallaxmapping/parallax.slang diff --git a/shaders/slang/parallaxmapping/parallax.slang b/shaders/slang/parallaxmapping/parallax.slang new file mode 100644 index 00000000..aa0c1048 --- /dev/null +++ b/shaders/slang/parallaxmapping/parallax.slang @@ -0,0 +1,150 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct UBOScene +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float4 lightPos; + float4 cameraPos; +}; +ConstantBuffer uboScene; + +Sampler2D samplerColorMap; +Sampler2D samplerNormalHeightMap; + +struct UBOParams +{ + float heightScale; + float parallaxBias; + float numLayers; + int mappingMode; +}; +ConstantBuffer uboParams; + +struct VSInput +{ + float3 Pos; + float2 UV; + float3 Normal; + float4 Tangent; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; + float3 TangentLightPos; + float3 TangentViewPos; + float3 TangentFragPos; +}; + +float2 parallaxMapping(float2 uv, float3 viewDir) +{ + float height = 1.0 - samplerNormalHeightMap.SampleLevel(uv, 0.0).a; + float2 p = viewDir.xy * (height * (uboParams.heightScale * 0.5) + uboParams.parallaxBias) / viewDir.z; + return uv - p; +} + +float2 steepParallaxMapping(float2 uv, float3 viewDir) +{ + float layerDepth = 1.0 / uboParams.numLayers; + float currLayerDepth = 0.0; + float2 deltaUV = viewDir.xy * uboParams.heightScale / (viewDir.z * uboParams.numLayers); + float2 currUV = uv; + float height = 1.0 - samplerNormalHeightMap.SampleLevel(currUV, 0.0).a; + for (int i = 0; i < uboParams.numLayers; i++) { + currLayerDepth += layerDepth; + currUV -= deltaUV; + height = 1.0 - samplerNormalHeightMap.SampleLevel(currUV, 0.0).a; + if (height < currLayerDepth) { + break; + } + } + return currUV; +} + +float2 parallaxOcclusionMapping(float2 uv, float3 viewDir) +{ + float layerDepth = 1.0 / uboParams.numLayers; + float currLayerDepth = 0.0; + float2 deltaUV = viewDir.xy * uboParams.heightScale / (viewDir.z * uboParams.numLayers); + float2 currUV = uv; + float height = 1.0 - samplerNormalHeightMap.SampleLevel(currUV, 0.0).a; + for (int i = 0; i < uboParams.numLayers; i++) { + currLayerDepth += layerDepth; + currUV -= deltaUV; + height = 1.0 - samplerNormalHeightMap.SampleLevel(currUV, 0.0).a; + if (height < currLayerDepth) { + break; + } + } + float2 prevUV = currUV + deltaUV; + float nextDepth = height - currLayerDepth; + float prevDepth = 1.0 - samplerNormalHeightMap.SampleLevel(prevUV, 0.0).a - currLayerDepth + layerDepth; + return lerp(currUV, prevUV, nextDepth / (nextDepth - prevDepth)); +} + +[shader("vertex")] + +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Pos = mul(uboScene.projection, mul(uboScene.view, mul(uboScene.model, float4(input.Pos, 1.0f)))); + output.UV = input.UV; + + float3 N = normalize(input.Normal); + float3 T = normalize(input.Tangent.xyz); + float3 B = normalize(cross(N, T)); + float3x3 TBN = float3x3(T, B, N); + + output.TangentLightPos = mul(TBN, uboScene.lightPos.xyz); + output.TangentViewPos = mul(TBN, uboScene.cameraPos.xyz); + output.TangentFragPos = mul(TBN, mul(uboScene.model, float4(input.Pos, 1.0)).xyz); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 V = normalize(input.TangentViewPos - input.TangentFragPos); + float2 uv = input.UV; + + if (uboParams.mappingMode == 0) { + // Color only + return samplerColorMap.Sample(input.UV); + } else { + switch (uboParams.mappingMode) { + case 2: + uv = parallaxMapping(input.UV, V); + break; + case 3: + uv = steepParallaxMapping(input.UV, V); + break; + case 4: + uv = parallaxOcclusionMapping(input.UV, V); + break; + } + + // Discard fragments at texture border + if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) { + clip(-1); + } + + float3 N = normalize(samplerNormalHeightMap.SampleLevel(uv, 0.0).rgb * 2.0 - 1.0); + float3 L = normalize(input.TangentLightPos - input.TangentFragPos); + float3 R = reflect(-L, N); + float3 H = normalize(L + V); + + float3 color = samplerColorMap.Sample(uv).rgb; + float3 ambient = 0.2 * color; + float3 diffuse = max(dot(L, N), 0.0) * color; + float3 specular = float3(0.15, 0.15, 0.15) * pow(max(dot(N, H), 0.0), 32.0); + + return float4(ambient + diffuse + specular, 1.0f); + } +} From 8ca12349629be1e67f584e87eb82147ab2b44346 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 17 May 2025 17:03:42 +0200 Subject: [PATCH 54/73] Add slang shaders for distance field fonts sample --- shaders/slang/distancefieldfonts/bitmap.slang | 40 +++++++++++++ shaders/slang/distancefieldfonts/sdf.slang | 56 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 shaders/slang/distancefieldfonts/bitmap.slang create mode 100644 shaders/slang/distancefieldfonts/sdf.slang diff --git a/shaders/slang/distancefieldfonts/bitmap.slang b/shaders/slang/distancefieldfonts/bitmap.slang new file mode 100644 index 00000000..59849e00 --- /dev/null +++ b/shaders/slang/distancefieldfonts/bitmap.slang @@ -0,0 +1,40 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; +ConstantBuffer ubo; +Sampler2D samplerColor; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return samplerColor.Sample(input.UV).aaaa; +} \ No newline at end of file diff --git a/shaders/slang/distancefieldfonts/sdf.slang b/shaders/slang/distancefieldfonts/sdf.slang new file mode 100644 index 00000000..2d3bb235 --- /dev/null +++ b/shaders/slang/distancefieldfonts/sdf.slang @@ -0,0 +1,56 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float2 UV; +}; + + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 outlineColor; + float outlineWidth; + float outline; +}; +ConstantBuffer ubo; +Sampler2D samplerColor; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float dist = samplerColor.Sample(input.UV).a; + float smoothWidth = fwidth(dist); + float alpha = smoothstep(0.5 - smoothWidth, 0.5 + smoothWidth, dist); + float3 rgb = alpha.xxx; + + if (ubo.outline > 0.0) + { + float w = 1.0 - ubo.outlineWidth; + alpha = smoothstep(w - smoothWidth, w + smoothWidth, dist); + rgb += lerp(alpha.xxx, ubo.outlineColor.rgb, alpha); + } + + return float4(rgb, alpha); +} \ No newline at end of file From b102f0bded8bf6f6949439da5a0b73f58a168410 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 17 May 2025 21:11:01 +0200 Subject: [PATCH 55/73] Added shaders for order independent transparency sample --- shaders/slang/oit/color.slang | 75 ++++++++++++++++++++++++++++++++ shaders/slang/oit/geometry.slang | 75 ++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 shaders/slang/oit/color.slang create mode 100644 shaders/slang/oit/geometry.slang diff --git a/shaders/slang/oit/color.slang b/shaders/slang/oit/color.slang new file mode 100644 index 00000000..7cda2767 --- /dev/null +++ b/shaders/slang/oit/color.slang @@ -0,0 +1,75 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +#define MAX_FRAGMENT_COUNT 128 + +struct VSOutput +{ + float4 Pos : SV_POSITION; +}; + +struct Node +{ + float4 color; + float depth; + uint next; +}; +RWTexture2D headIndexImage; + +struct Particle +{ + float2 pos; + float2 vel; + float4 gradientPos; +}; +RWStructuredBuffer nodes; + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + float2 UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + Node fragments[MAX_FRAGMENT_COUNT]; + int count = 0; + + uint nodeIdx = headIndexImage[uint2(input.Pos.xy)].r; + + while (nodeIdx != 0xffffffff && count < MAX_FRAGMENT_COUNT) + { + fragments[count] = nodes[nodeIdx]; + nodeIdx = fragments[count].next; + ++count; + } + + // Do the insertion sort + for (uint i = 1; i < count; ++i) + { + Node insert = fragments[i]; + uint j = i; + while (j > 0 && insert.depth > fragments[j - 1].depth) + { + fragments[j] = fragments[j-1]; + --j; + } + fragments[j] = insert; + } + + // Do blending + float4 color = float4(0.025, 0.025, 0.025, 1.0f); + for (uint f = 0; f < count; ++f) + { + color = lerp(color, fragments[f].color, fragments[f].color.a); + } + + return color; +} \ No newline at end of file diff --git a/shaders/slang/oit/geometry.slang b/shaders/slang/oit/geometry.slang new file mode 100644 index 00000000..1a72580d --- /dev/null +++ b/shaders/slang/oit/geometry.slang @@ -0,0 +1,75 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos : POSITION0; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; +}; + +struct RenderPassUBO +{ + float4x4 projection; + float4x4 view; +}; +ConstantBuffer renderPassUBO; + +struct GeometrySBO +{ + uint count; + uint maxNodeCount; +}; +// Binding 0 : Position storage buffer +RWStructuredBuffer geometrySBO; + +struct Node +{ + float4 color; + float depth; + uint next; +}; +RWTexture2D headIndexImage; + +RWStructuredBuffer nodes; + +struct PushConsts { + float4x4 model; + float4 color; +}; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform PushConsts pushConsts) +{ + VSOutput output; + output.Pos = mul(renderPassUBO.projection, mul(renderPassUBO.view, mul(pushConsts.model, input.Pos))); + return output; +} + +[shader("fragment")] +[earlydepthstencil] +void fragmentMain(VSOutput input, uniform PushConsts pushConsts) +{ + // Increase the node count + uint nodeIdx; + InterlockedAdd(geometrySBO[0].count, 1, nodeIdx); + + // Check LinkedListSBO is full + if (nodeIdx < geometrySBO[0].maxNodeCount) + { + // Exchange new head index and previous head index + uint prevHeadIdx; + InterlockedExchange(headIndexImage[uint2(input.Pos.xy)], nodeIdx, prevHeadIdx); + + // Store node data + nodes[nodeIdx].color = pushConsts.color; + nodes[nodeIdx].depth = input.Pos.z; + nodes[nodeIdx].next = prevHeadIdx; + } +} \ No newline at end of file From 381c6eff039c0e0e957d849f5a65d460d64df493 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 18 May 2025 10:38:49 +0200 Subject: [PATCH 56/73] Added shaders for ray tracing callable sample --- shaders/slang/_rename.py | 11 +++ .../slang/raytracingcallable/callable1.slang | 14 ++++ .../slang/raytracingcallable/callable2.slang | 11 +++ .../slang/raytracingcallable/callable3.slang | 14 ++++ .../raytracingcallable.slang | 68 +++++++++++++++++++ 5 files changed, 118 insertions(+) create mode 100644 shaders/slang/raytracingcallable/callable1.slang create mode 100644 shaders/slang/raytracingcallable/callable2.slang create mode 100644 shaders/slang/raytracingcallable/callable3.slang create mode 100644 shaders/slang/raytracingcallable/raytracingcallable.slang diff --git a/shaders/slang/_rename.py b/shaders/slang/_rename.py index 4b23aef0..375bae93 100644 --- a/shaders/slang/_rename.py +++ b/shaders/slang/_rename.py @@ -7,6 +7,11 @@ from shutil import move def checkRenameFiles(samplename): mappings = {} match samplename: + case "displacement": + mappings = { + "displacement.vert.spv": "base.vert.spv", + "displacement.frag.spv": "base.frag.spv", + } case "geometryshader": mappings = { "normaldebug.vert.spv": "base.vert.spv", @@ -18,6 +23,12 @@ def checkRenameFiles(samplename): "raytracingbasic.rmiss.spv": "miss.rmiss.spv", "raytracingbasic.rgen.spv": "raygen.rgen.spv", } + case "raytracingcallable": + mappings = { + "raytracingcallable.rchit.spv": "closesthit.rchit.spv", + "raytracingcallable.rmiss.spv": "miss.rmiss.spv", + "raytracingcallable.rgen.spv": "raygen.rgen.spv", + } case "raytracinggltf": mappings = { "raytracinggltf.rchit.spv": "closesthit.rchit.spv", diff --git a/shaders/slang/raytracingcallable/callable1.slang b/shaders/slang/raytracingcallable/callable1.slang new file mode 100644 index 00000000..afacce9a --- /dev/null +++ b/shaders/slang/raytracingcallable/callable1.slang @@ -0,0 +1,14 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +[shader("callable")] +void callableMain(inout float3 outColor) +{ + // Generate a checker board pattern + float2 pos = float2(DispatchRaysIndex().x / 8, DispatchRaysIndex().y / 8); + float col = (pos.x + (pos.y % 2.0)) % 2.0; + outColor = float3(col, col, col); +} \ No newline at end of file diff --git a/shaders/slang/raytracingcallable/callable2.slang b/shaders/slang/raytracingcallable/callable2.slang new file mode 100644 index 00000000..de51b24d --- /dev/null +++ b/shaders/slang/raytracingcallable/callable2.slang @@ -0,0 +1,11 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +[shader("callable")] +void callableMain(inout float3 outColor) +{ + outColor = float3(0.0, 1.0, 0.0); +} \ No newline at end of file diff --git a/shaders/slang/raytracingcallable/callable3.slang b/shaders/slang/raytracingcallable/callable3.slang new file mode 100644 index 00000000..75ca336a --- /dev/null +++ b/shaders/slang/raytracingcallable/callable3.slang @@ -0,0 +1,14 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +[shader("callable")] +void callableMain(inout float3 outColor) +{ + // Generate a checker board pattern + float2 pos = float2(DispatchRaysIndex().x / 8, DispatchRaysIndex().y / 8); + float col = pos.y % 2.0; + outColor = float3(col, col, col); +} \ No newline at end of file diff --git a/shaders/slang/raytracingcallable/raytracingcallable.slang b/shaders/slang/raytracingcallable/raytracingcallable.slang new file mode 100644 index 00000000..e125f455 --- /dev/null +++ b/shaders/slang/raytracingcallable/raytracingcallable.slang @@ -0,0 +1,68 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +RaytracingAccelerationStructure accelStruct; +RWTexture2D image; +struct CameraProperties +{ + float4x4 viewInverse; + float4x4 projInverse; +}; +ConstantBuffer cam; + +struct Payload +{ + float3 hitValue; +}; + +struct CallData +{ + float3 outColor; +}; + +struct Attributes +{ + float2 bary; +}; + +[shader("raygeneration")] +void raygenerationMain() +{ + uint3 LaunchID = DispatchRaysIndex(); + uint3 LaunchSize = DispatchRaysDimensions(); + + const float2 pixelCenter = float2(LaunchID.xy) + float2(0.5, 0.5); + const float2 inUV = pixelCenter / float2(LaunchSize.xy); + float2 d = inUV * 2.0 - 1.0; + float4 target = mul(cam.projInverse, float4(d.x, d.y, 1, 1)); + + RayDesc rayDesc; + rayDesc.Origin = mul(cam.viewInverse, float4(0, 0, 0, 1)).xyz; + rayDesc.Direction = mul(cam.viewInverse, float4(normalize(target.xyz), 0)).xyz; + rayDesc.TMin = 0.001; + rayDesc.TMax = 10000.0; + + Payload payload; + TraceRay(accelStruct, RAY_FLAG_FORCE_OPAQUE, 0xff, 0, 0, 0, rayDesc, payload); + + image[int2(LaunchID.xy)] = float4(payload.hitValue, 0.0); +} + +[shader("closesthit")] +void closesthitMain(inout Payload p, in Attributes attribs) +{ + // Execute the callable shader indexed by the current geometry being hit + // For our sample this means that the first callable shader in the SBT is invoked for the first triangle, the second callable shader for the second triangle, etc. + CallData callData; + CallShader(GeometryIndex(), callData); + p.hitValue = callData.outColor; +} + +[shader("miss")] +void missMain(inout Payload p) +{ + p.hitValue = float3(0.0, 0.0, 0.2); +} \ No newline at end of file From b81e9d9654e8040e54954945bcf95aff75599c82 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 18 May 2025 11:21:50 +0200 Subject: [PATCH 57/73] Added slang shaders for hdr and graphics pipeline library samples --- shaders/slang/_rename.py | 6 +- .../slang/graphicspipelinelibrary/uber.slang | 99 +++++++++++++ shaders/slang/hdr/bloom.slang | 80 +++++++++++ shaders/slang/hdr/composition.slang | 28 ++++ shaders/slang/hdr/gbuffer.slang | 135 ++++++++++++++++++ 5 files changed, 347 insertions(+), 1 deletion(-) create mode 100644 shaders/slang/graphicspipelinelibrary/uber.slang create mode 100644 shaders/slang/hdr/bloom.slang create mode 100644 shaders/slang/hdr/composition.slang create mode 100644 shaders/slang/hdr/gbuffer.slang diff --git a/shaders/slang/_rename.py b/shaders/slang/_rename.py index 375bae93..bce6121e 100644 --- a/shaders/slang/_rename.py +++ b/shaders/slang/_rename.py @@ -16,7 +16,11 @@ def checkRenameFiles(samplename): mappings = { "normaldebug.vert.spv": "base.vert.spv", "normaldebug.frag.spv": "base.frag.spv", - } + } + case "graphicspipelinelibrary": + mappings = { + "uber.vert.spv": "shared.vert.spv", + } case "raytracingbasic": mappings = { "raytracingbasic.rchit.spv": "closesthit.rchit.spv", diff --git a/shaders/slang/graphicspipelinelibrary/uber.slang b/shaders/slang/graphicspipelinelibrary/uber.slang new file mode 100644 index 00000000..0b582f54 --- /dev/null +++ b/shaders/slang/graphicspipelinelibrary/uber.slang @@ -0,0 +1,99 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; +ConstantBuffer ubo; + +// We use this constant to control the flow of the shader depending on the +// lighting model selected at pipeline creation time +[[SpecializationConstant]] const int LIGHTING_MODEL = 0; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + float3 lPos = mul((float3x3)ubo.model, ubo.lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 outColor = float3(0.0); + + switch (LIGHTING_MODEL) { + case 0: // Phong + { + float3 ambient = input.Color * float3(0.25, 0.25, 0.25); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 32.0) * float3(0.75); + outColor = ambient + diffuse * 1.75 + specular; + break; + } + case 1: // Toon + { + + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float intensity = dot(N, L); + float3 color; + if (intensity > 0.98) + color = input.Color * 1.5; + else if (intensity > 0.9) + color = input.Color * 1.0; + else if (intensity > 0.5) + color = input.Color * 0.6; + else if (intensity > 0.25) + color = input.Color * 0.4; + else + color = input.Color * 0.2; + outColor = color; + break; + } + case 2: // No shading + { + outColor = input.Color; + break; + } + case 3: // Greyscale + outColor = dot(input.Color, float3(0.299, 0.587, 0.114)); + break; + } + + // The scene itself is a bit dark, so brigthen it up a bit + return float4(outColor * 1.25, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/hdr/bloom.slang b/shaders/slang/hdr/bloom.slang new file mode 100644 index 00000000..41a1ea6e --- /dev/null +++ b/shaders/slang/hdr/bloom.slang @@ -0,0 +1,80 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +Sampler2D samplerColor0; +Sampler2D samplerColor1; + +[[SpecializationConstant]] const int dir = 0; + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + // From the OpenGL Super bible + const float weights[] = { 0.0024499299678342, + 0.0043538453346397, + 0.0073599963704157, + 0.0118349786570722, + 0.0181026699707781, + 0.0263392293891488, + 0.0364543006660986, + 0.0479932050577658, + 0.0601029809166942, + 0.0715974486241365, + 0.0811305381519717, + 0.0874493212267511, + 0.0896631113333857, + 0.0874493212267511, + 0.0811305381519717, + 0.0715974486241365, + 0.0601029809166942, + 0.0479932050577658, + 0.0364543006660986, + 0.0263392293891488, + 0.0181026699707781, + 0.0118349786570722, + 0.0073599963704157, + 0.0043538453346397, + 0.0024499299678342}; + + + const float blurScale = 0.003; + const float blurStrength = 1.0; + + float ar = 1.0; + // Aspect ratio for vertical blur pass + if (dir == 1) + { + float2 ts; + samplerColor1.GetDimensions(ts.x, ts.y); + ar = ts.y / ts.x; + } + + float2 P = input.UV.yx - float2(0, (25 >> 1) * ar * blurScale); + + float4 color = float4(0.0, 0.0, 0.0, 0.0); + for (int i = 0; i < 25; i++) + { + float2 dv = float2(0.0, i * blurScale) * ar; + color += samplerColor1.Sample(P + dv) * weights[i] * blurStrength; + } + + return color; +} \ No newline at end of file diff --git a/shaders/slang/hdr/composition.slang b/shaders/slang/hdr/composition.slang new file mode 100644 index 00000000..d9705f60 --- /dev/null +++ b/shaders/slang/hdr/composition.slang @@ -0,0 +1,28 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +Sampler2D samplerColor; + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return samplerColor.Sample(input.UV); +} \ No newline at end of file diff --git a/shaders/slang/hdr/gbuffer.slang b/shaders/slang/hdr/gbuffer.slang new file mode 100644 index 00000000..7743780d --- /dev/null +++ b/shaders/slang/hdr/gbuffer.slang @@ -0,0 +1,135 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 UVW; + float3 WorldPos; + float3 Normal; + float3 ViewVec; + float3 LightVec; +}; + +struct FSOutput +{ + float4 Color0 : SV_TARGET0; + float4 Color1 : SV_TARGET1; +}; + +struct UBO { + float4x4 projection; + float4x4 modelview; + float4x4 inverseModelview; + float exposure; +}; +ConstantBuffer ubo; + +SamplerCube samplerEnvMap; + +[[SpecializationConstant]] const int objectType = 0; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UVW = input.Pos; + + switch (objectType) { + case 0: // Skybox + output.WorldPos = mul((float4x3)ubo.modelview, input.Pos).xyz; + output.Pos = mul(ubo.projection, float4(output.WorldPos, 1.0)); + break; + case 1: // Object + output.WorldPos = mul(ubo.modelview, float4(input.Pos, 1.0)).xyz; + output.Pos = mul(ubo.projection, mul(ubo.modelview, float4(input.Pos.xyz, 1.0))); + break; + } + output.WorldPos = mul(ubo.modelview, float4(input.Pos, 1.0)).xyz; + output.Normal = mul((float4x3)ubo.modelview, input.Normal).xyz; + float3 lightPos = float3(0.0f, -5.0f, 5.0f); + output.LightVec = lightPos.xyz - output.WorldPos.xyz; + output.ViewVec = -output.WorldPos.xyz; + return output; +} + +[shader("fragment")] +FSOutput fragmentMain(VSOutput input) +{ + FSOutput output; + float4 color; + float3 wcNormal; + + switch (objectType) { + case 0: // Skybox + { + float3 normal = normalize(input.UVW); + color = samplerEnvMap.Sample(normal); + } + break; + + case 1: // Reflect + { + float3 wViewVec = mul((float4x3)ubo.inverseModelview, normalize(input.ViewVec)).xyz; + float3 normal = normalize(input.Normal); + float3 wNormal = mul((float4x3)ubo.inverseModelview, normal).xyz; + + float NdotL = max(dot(normal, input.LightVec), 0.0); + + float3 eyeDir = normalize(input.ViewVec); + float3 halfVec = normalize(input.LightVec + eyeDir); + float NdotH = max(dot(normal, halfVec), 0.0); + float NdotV = max(dot(normal, eyeDir), 0.0); + float VdotH = max(dot(eyeDir, halfVec), 0.0); + + // Geometric attenuation + float NH2 = 2.0 * NdotH; + float g1 = (NH2 * NdotV) / VdotH; + float g2 = (NH2 * NdotL) / VdotH; + float geoAtt = min(1.0, min(g1, g2)); + + const float F0 = 0.6; + const float k = 0.2; + + // Fresnel (schlick approximation) + float fresnel = pow(1.0 - VdotH, 5.0); + fresnel *= (1.0 - F0); + fresnel += F0; + + float spec = (fresnel * geoAtt) / (NdotV * NdotL * 3.14); + + color = samplerEnvMap.Sample(reflect(-wViewVec, wNormal)); + + color = float4(color.rgb * NdotL * (k + spec * (1.0 - k)), 1.0); + } + break; + + case 2: // Refract + { + float3 wViewVec = mul((float4x3)ubo.inverseModelview, normalize(input.ViewVec)).xyz; + float3 wNormal = mul((float4x3)ubo.inverseModelview, input.Normal).xyz; + color = samplerEnvMap.Sample(refract(-wViewVec, wNormal, 1.0/1.6)); + } + break; + } + + + // Color with manual exposure into attachment 0 + output.Color0.rgb = float3(1.0, 1.0, 1.0) - exp(-color.rgb * ubo.exposure); + + // Bright parts for bloom into attachment 1 + float l = dot(output.Color0.rgb, float3(0.2126, 0.7152, 0.0722)); + float threshold = 0.75; + output.Color1.rgb = (l > threshold) ? output.Color0.rgb : float3(0.0, 0.0, 0.0); + output.Color1.a = 1.0; + return output; +} \ No newline at end of file From d8c863065408b3f285025bb3ac9d3472ab294d97 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sun, 18 May 2025 11:38:10 +0200 Subject: [PATCH 58/73] Added slang shaders for pipeline samples --- shaders/slang/pipelines/phong.slang | 62 +++++++++ shaders/slang/pipelines/toon.slang | 70 ++++++++++ shaders/slang/pipelines/wireframe.slang | 40 ++++++ shaders/slang/pipelinestatistics/scene.slang | 127 +++++++++++++++++++ 4 files changed, 299 insertions(+) create mode 100644 shaders/slang/pipelines/phong.slang create mode 100644 shaders/slang/pipelines/toon.slang create mode 100644 shaders/slang/pipelines/wireframe.slang create mode 100644 shaders/slang/pipelinestatistics/scene.slang diff --git a/shaders/slang/pipelines/phong.slang b/shaders/slang/pipelines/phong.slang new file mode 100644 index 00000000..e6e6f172 --- /dev/null +++ b/shaders/slang/pipelines/phong.slang @@ -0,0 +1,62 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; +ConstantBuffer ubo; + +Sampler2D samplerColorMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + float3 lPos = mul((float3x3)ubo.model, ubo.lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + // Desaturate color + float3 color = lerp(input.Color, dot(float3(0.2126,0.7152,0.0722), input.Color).xxx, 0.65); + + // High ambient colors because mesh materials are pretty dark + float3 ambient = color * float3(1.0, 1.0, 1.0); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * color; + float3 specular = pow(max(dot(R, V), 0.0), 32.0) * float3(0.35, 0.35, 0.35); + return float4(ambient + diffuse * 1.75 + specular, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/pipelines/toon.slang b/shaders/slang/pipelines/toon.slang new file mode 100644 index 00000000..14cc13e5 --- /dev/null +++ b/shaders/slang/pipelines/toon.slang @@ -0,0 +1,70 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; +ConstantBuffer ubo; + +Sampler2D samplerColorMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)ubo.model, input.Normal); + float3 lPos = mul((float3x3)ubo.model, ubo.lightPos.xyz); + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + // Desaturate color + float3 color = lerp(input.Color, dot(float3(0.2126,0.7152,0.0722), input.Color).xxx, 0.65); + + // High ambient colors because mesh materials are pretty dark + float3 ambient = color * float3(1.0, 1.0, 1.0); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * color; + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + + float intensity = dot(N,L); + float shade = 1.0; + shade = intensity < 0.5 ? 0.75 : shade; + shade = intensity < 0.35 ? 0.6 : shade; + shade = intensity < 0.25 ? 0.5 : shade; + shade = intensity < 0.1 ? 0.25 : shade; + + return float4(input.Color * 3.0 * shade, 1); +} \ No newline at end of file diff --git a/shaders/slang/pipelines/wireframe.slang b/shaders/slang/pipelines/wireframe.slang new file mode 100644 index 00000000..4482be10 --- /dev/null +++ b/shaders/slang/pipelines/wireframe.slang @@ -0,0 +1,40 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float2 UV; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Color; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.model, input.Pos)); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return float4(input.Color * 1.5, 1); +} \ No newline at end of file diff --git a/shaders/slang/pipelinestatistics/scene.slang b/shaders/slang/pipelinestatistics/scene.slang new file mode 100644 index 00000000..781f7f7f --- /dev/null +++ b/shaders/slang/pipelinestatistics/scene.slang @@ -0,0 +1,127 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 ViewVec; + float3 LightVec; +}; + +struct HSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 ViewVec; + float3 LightVec; +}; + +struct DSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 ViewVec; + float3 LightVec; +}; + +struct ConstantsHSOutput +{ + float TessLevelOuter[3] : SV_TessFactor; + float TessLevelInner[2] : SV_InsideTessFactor; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 lightPos; +}; +ConstantBuffer ubo; + +struct PushConsts { + float3 objPos; +}; +[[vk::push_constant]] PushConsts pushConsts; + +ConstantsHSOutput ConstantsHS(InputPatch patch) +{ + ConstantsHSOutput output; + output.TessLevelInner[0] = 2.0; + output.TessLevelInner[1] = 2.0; + output.TessLevelOuter[0] = 1.0; + output.TessLevelOuter[1] = 1.0; + output.TessLevelOuter[2] = 1.0; + return output; +} + +[shader("hull")] +[domain("tri")] +[partitioning("integer")] +[outputtopology("triangle_ccw")] +[outputcontrolpoints(3)] +[patchconstantfunc("ConstantsHS")] +[maxtessfactor(20.0f)] +HSOutput hullMain(InputPatch patch, uint InvocationID: SV_OutputControlPointID) +{ + HSOutput output; + output.Pos = patch[InvocationID].Pos; + output.Normal = patch[InvocationID].Normal; + output.Color = patch[InvocationID].Color; + output.ViewVec = patch[InvocationID].ViewVec; + output.LightVec = patch[InvocationID].LightVec; + return output; +} + +[shader("domain")] +[domain("tri")] +DSOutput domainMain(ConstantsHSOutput input, float3 TessCoord: SV_DomainLocation, const OutputPatch patch) +{ + DSOutput output; + output.Pos = (TessCoord.x * patch[2].Pos) + (TessCoord.y * patch[1].Pos) + (TessCoord.z * patch[0].Pos); + output.Normal = TessCoord.x * patch[2].Normal + TessCoord.y * patch[1].Normal + TessCoord.z * patch[0].Normal; + output.ViewVec = TessCoord.x * patch[2].ViewVec + TessCoord.y * patch[1].ViewVec + TessCoord.z * patch[0].ViewVec; + output.LightVec = TessCoord.x * patch[2].LightVec + TessCoord.y * patch[1].LightVec + TessCoord.z * patch[0].LightVec; + output.Color = patch[0].Color; + return output; +} + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + float3 locPos = mul(ubo.modelview, float4(input.Pos, 1.0)).xyz; + float3 worldPos = mul(ubo.modelview, float4(input.Pos + pushConsts.objPos, 1.0)).xyz; + output.Pos = mul(ubo.projection, float4(worldPos, 1.0)); + float4 pos = mul(ubo.modelview, float4(worldPos, 1.0)); + output.Normal = mul((float3x3)ubo.modelview, input.Normal); + output.LightVec = ubo.lightPos.xyz - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 8.0) * float3(0.75, 0.75, 0.75); + return float4(diffuse + specular, 0.5); +} \ No newline at end of file From 8d50885e922c9693bd75da0b37cfb7d991f3b4c2 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Mon, 19 May 2025 18:13:34 +0200 Subject: [PATCH 59/73] Added slang shaders for compute cull and lod sample Adjusted vertex bindings --- shaders/glsl/computecullandlod/cull.comp.spv | Bin 5060 -> 5084 bytes .../glsl/computecullandlod/indirectdraw.vert | 4 +- .../computecullandlod/indirectdraw.vert.spv | Bin 2344 -> 2344 bytes .../hlsl/computecullandlod/indirectdraw.vert | 4 +- .../computecullandlod/indirectdraw.vert.spv | Bin 3408 -> 1864 bytes shaders/slang/computecullandlod/cull.slang | 115 ++++++++++++++++++ .../computecullandlod/indirectdraw.slang | 56 +++++++++ 7 files changed, 175 insertions(+), 4 deletions(-) create mode 100644 shaders/slang/computecullandlod/cull.slang create mode 100644 shaders/slang/computecullandlod/indirectdraw.slang diff --git a/shaders/glsl/computecullandlod/cull.comp.spv b/shaders/glsl/computecullandlod/cull.comp.spv index a90380f98bd809212ba6143eb3c67117899925ed..b8b6bb0cb544f54d78bc5c9512639476aeb780f0 100644 GIT binary patch delta 215 zcmX@2en*{?nMs+Qfq{{Mdn2bi3#U5+GlL=n0|V1!Ul#ev4J=%flUPJ1cd$1pf<`UdA3(kYYltOChd)pUGZ1?)u!7k@CWA7F00MUg7KT6|4Kfu3V0@*? zOIfSI_9X*FnJ3G#X|tvRS(1}u*~BM@un9~qVUwA>gNPvIiVP3{lw=T?Jds6y@(~t+$!l0d zCSPGuVq~8Dn?-i=51@zyYY3|c11p37WJfk(MSq}bW*~NFU||RZ(n>%K0x-Vfb`8}wB-I^gszH2^YL?9_*^PMsxfCW! diff --git a/shaders/glsl/computecullandlod/indirectdraw.vert b/shaders/glsl/computecullandlod/indirectdraw.vert index 4087e1bb..4335228b 100644 --- a/shaders/glsl/computecullandlod/indirectdraw.vert +++ b/shaders/glsl/computecullandlod/indirectdraw.vert @@ -6,8 +6,8 @@ layout (location = 1) in vec3 inNormal; layout (location = 2) in vec3 inColor; // Instanced attributes -layout (location = 4) in vec3 instancePos; -layout (location = 5) in float instanceScale; +layout (location = 3) in vec3 instancePos; +layout (location = 4) in float instanceScale; layout (binding = 0) uniform UBO { diff --git a/shaders/glsl/computecullandlod/indirectdraw.vert.spv b/shaders/glsl/computecullandlod/indirectdraw.vert.spv index bcbf69270ca22321dd3f26fad3fb25950ee2e4be..d94a9ed2cd8f063ee9fe3cbb7292d24a56ed4b12 100644 GIT binary patch delta 130 zcmZ1>v_goJnMs+Qfq{{Mdn2belO+oS1A{vQ3xhO}mIGpDFrS%08Avk$u?GVym&zBsx(1TKmgLoFnKSN{NxWz9Fs3FiA)w@7MaY!EU;LE GnGFEZB@LPY delta 106 zcmZ1>v_goJnMs+Qfq{{MeIutglOQVt1A{vQ3xhO}mIGpz$%RbPjLMUHnUq0q|Yhw-OqdN`oT^rR(>TfgGUs}{LrPc~P!R+6EA9F#UqD1JffIJ1~8LIbiw$ zTRi#zTRdt3TRi48F5=)1u6pELQ`y-8PA$8R$ms2?s3||Qqb~EK2K*L!WW9danIC(} zv3$#_6dCo8i02m&i$>)^ZZN*!!GP&)SooaoSVa7(fQNeUd0`HEVhwxr^||2@kN@dM zJ&qfuAM?1mI41uK;;D&xD*EP4kU^Eu2eMeYi@NEF-oTf1Qz!o5%K_69_)5T8|E0e( zH2bU4(>L}*iX7{%N>bGgPYmWvPU?9gObyH%8JHU2`vRs0V&*ZuStn!|WNe zCI<1Tk$uf$_BD^$*F4VtyPTU=WO}QKm?dPwPV5cIh>!T4%lGgG^O7+??7oCqJPP=kCc>@|7oI&~PVnpq TGlFM7@PTJHi1}NY=0$%1wVQ6* literal 3408 zcmZve`Eyi75XT?MZUW&@L?9~04S0hQEk!I9CD9_OirJW8)E}3)rE4YGRM?=XB_Q4h z;(aUL_wncXi&cI;?@gDF)!FJyf4|++-P1GkD!o0s`m=0JmSvl=Kl$s}ob@E8H^*8p z;O9_ZY_yitdk{S;NEPWr2$roy)*%DPdZd@1_9HB)^4o|$H(OurEU$J@Sy#z9_38Fe zaN%RFsrJfZV?m#SGv`=)p}oQ!oHfj~norI(=i&PDSk^SzdhGFzB*VNz%$?)Q&5_k3 zZ8`JGIi#x8c?J4|qxC$Fx?_2z{X}!V(`vJ8$4MwC+bssG2_>VXO<<~RDI_DgOga~tvT^y^~w5-3#xR~-X;FofPJ zSpBT}kL@O?Jf7#!UhU*XL?ZKeHo-?C^LSptMd3U19F0O~4o1Iwl zc-@uQ5oaszK3lo-&$cgLSM=&=r?E8OEY|nue9^0dpPg?kG+FQ7b~7(GRvL@>u3LEx zhp54O=^h+nbH&+<%_FuhvGK+Fi9G|cyx6{r<;C_|>=4^yal{))IO180cJu1*-Pwsa z0uL838z)QL#a;iyxwi|EapHuZb;detaNRv!T=zQtVqNSd@*Sd5IqTns?$@A(Y-hzL zX0dC<)*^OqLv-Hvu8(|KM)1(K8QIFZiivh3vDfiKDNzxGRWTss){%W^zEx`%zZhaHG(^wVa%L1NdKwVQj0zn()a$q*IT zyMn7^m!rEUxf;I1%xe(Wi+3h$uf(2#_M+#N>`HX^6#iEwtp64wU(Gy>$2H9Ao`LU6 z|8oB$-gWTa1$~CecRRD^B5(dXnYGJ_4Bk2(>SixU!Ma+HMe$k_vKqXNVHMr=Me3_(a3co@!@k4>^gmn zA=W4Cr_hbzyN(#oqsxcSX>?=gV+^rA+U@TPh%x*Y7{eaDh{)I3qdj^laqN2clh@-#&5J{2x=! z^YH%Mg2*}a?`M|N?*48?v|E$*wTTP+zGV08w69~93;S)!-ka instances; + +// Same layout as VkDrawIndexedIndirectCommand +struct IndexedIndirectCommand +{ + uint indexCount; + uint instanceCount; + uint firstIndex; + uint vertexOffset; + uint firstInstance; +}; +RWStructuredBuffer indirectDraws; + +// Binding 2: Uniform block object with matrices +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float4 cameraPos; + float4 frustumPlanes[6]; +}; +ConstantBuffer ubo; + +// Binding 3: Indirect draw stats +struct UBOOut +{ + uint drawCount; + uint lodCount[MAX_LOD_LEVEL_COUNT]; +}; +RWStructuredBuffer uboOut; + +// Binding 4: level-of-detail information +struct LOD +{ + uint firstIndex; + uint indexCount; + float distance; + float _pad0; +}; +StructuredBuffer lods; + +bool frustumCheck(float4 pos, float radius) +{ + // Check sphere against frustum planes + for (int i = 0; i < 6; i++) + { + if (dot(pos, ubo.frustumPlanes[i]) + radius < 0.0) + { + return false; + } + } + return true; +} + +[shader("compute")] +[numthreads(16, 1, 1)] +void computeMain(uint3 GlobalInvocationID : SV_DispatchThreadID) +{ + uint idx = GlobalInvocationID.x; + uint temp; + + // Clear stats on first invocation + if (idx == 0) + { + InterlockedExchange(uboOut[0].drawCount, 0, temp); + for (uint i = 0; i < MAX_LOD_LEVEL + 1; i++) + { + InterlockedExchange(uboOut[0].lodCount[i], 0, temp); + } + } + + float4 pos = float4(instances[idx].pos.xyz, 1.0); + + // Check if object is within current viewing frustum + if (frustumCheck(pos, 1.0)) + { + indirectDraws[idx].instanceCount = 1; + + // Increase number of indirect draw counts + InterlockedAdd(uboOut[0].drawCount, 1, temp); + + // Select appropriate LOD level based on distance to camera + uint lodLevel = MAX_LOD_LEVEL; + for (uint i = 0; i < MAX_LOD_LEVEL; i++) + { + if (distance(instances[idx].pos.xyz, ubo.cameraPos.xyz) < lods[i].distance) + { + lodLevel = i; + break; + } + } + indirectDraws[idx].firstIndex = lods[lodLevel].firstIndex; + indirectDraws[idx].indexCount = lods[lodLevel].indexCount; + // Update stats + InterlockedAdd(uboOut[0].lodCount[lodLevel], 1, temp); + } + else + { + indirectDraws[idx].instanceCount = 0; + } +} \ No newline at end of file diff --git a/shaders/slang/computecullandlod/indirectdraw.slang b/shaders/slang/computecullandlod/indirectdraw.slang new file mode 100644 index 00000000..d051bd6c --- /dev/null +++ b/shaders/slang/computecullandlod/indirectdraw.slang @@ -0,0 +1,56 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos : POSITION0; + float3 Normal; + float3 Color; + // Instanced attributes + float3 instancePos; + float instanceScale; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.Normal = input.Normal; + float4 pos = float4((input.Pos.xyz * input.instanceScale) + input.instancePos, 1.0); + output.Pos = mul(ubo.projection, mul(ubo.modelview, pos)); + float4 wPos = mul(ubo.modelview, float4(pos.xyz, 1.0)); + float4 lPos = float4(0.0, 10.0, 50.0, 1.0); + output.LightVec = lPos.xyz - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 ambient = float3(0.25, 0.25, 0.25); + float3 diffuse = max(dot(N, L), 0.0).xxx; + return float4((ambient + diffuse) * input.Color, 1.0); +} \ No newline at end of file From 80ff4a41d2a13bd297743b3134c1c5448783d49b Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Mon, 19 May 2025 18:20:23 +0200 Subject: [PATCH 60/73] Added slang shaders for ssao sample --- shaders/slang/ssao/blur.slang | 30 ++++++++++++ shaders/slang/ssao/composition.slang | 59 ++++++++++++++++++++++ shaders/slang/ssao/fullscreen.slang | 16 ++++++ shaders/slang/ssao/gbuffer.slang | 73 ++++++++++++++++++++++++++++ shaders/slang/ssao/ssao.slang | 70 ++++++++++++++++++++++++++ shaders/slang/ssao/types.slang | 13 +++++ 6 files changed, 261 insertions(+) create mode 100644 shaders/slang/ssao/blur.slang create mode 100644 shaders/slang/ssao/composition.slang create mode 100644 shaders/slang/ssao/fullscreen.slang create mode 100644 shaders/slang/ssao/gbuffer.slang create mode 100644 shaders/slang/ssao/ssao.slang create mode 100644 shaders/slang/ssao/types.slang diff --git a/shaders/slang/ssao/blur.slang b/shaders/slang/ssao/blur.slang new file mode 100644 index 00000000..b35d087d --- /dev/null +++ b/shaders/slang/ssao/blur.slang @@ -0,0 +1,30 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +import types; + +Sampler2D samplerSSAO; + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + const int blurRange = 2; + int n = 0; + int2 texDim; + samplerSSAO.GetDimensions(texDim.x, texDim.y); + float2 texelSize = 1.0 / (float2)texDim; + float result = 0.0; + for (int x = -blurRange; x <= blurRange; x++) + { + for (int y = -blurRange; y <= blurRange; y++) + { + float2 offset = float2(float(x), float(y)) * texelSize; + result += samplerSSAO.Sample(input.UV + offset).r; + n++; + } + } + return result / (float(n)); +} \ No newline at end of file diff --git a/shaders/slang/ssao/composition.slang b/shaders/slang/ssao/composition.slang new file mode 100644 index 00000000..04991a03 --- /dev/null +++ b/shaders/slang/ssao/composition.slang @@ -0,0 +1,59 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +import types; + +Sampler2D samplerposition; +Sampler2D samplerNormal; +Sampler2D samplerAlbedo; +Sampler2D samplerSSAO; +Sampler2D samplerSSAOBlur; + +struct UBO +{ + float4x4 _dummy; + int ssao; + int ssaoOnly; + int ssaoBlur; +}; +ConstantBuffer uboParams; + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 fragPos = samplerposition.Sample(input.UV).rgb; + float3 normal = normalize(samplerNormal.Sample(input.UV).rgb * 2.0 - 1.0); + float4 albedo = samplerAlbedo.Sample(input.UV); + + float ssao = (uboParams.ssaoBlur == 1) ? samplerSSAOBlur.Sample(input.UV).r : samplerSSAO.Sample(input.UV).r; + + float3 lightPos = float3(0.0, 0.0, 0.0); + float3 L = normalize(lightPos - fragPos); + float NdotL = max(0.5, dot(normal, L)); + + float4 outFragColor; + if (uboParams.ssaoOnly == 1) + { + outFragColor.rgb = ssao.rrr; + } + else + { + float3 baseColor = albedo.rgb * NdotL; + + if (uboParams.ssao == 1) + { + outFragColor.rgb = ssao.rrr; + + if (uboParams.ssaoOnly != 1) + outFragColor.rgb *= baseColor; + } + else + { + outFragColor.rgb = baseColor; + } + } + return outFragColor; +} \ No newline at end of file diff --git a/shaders/slang/ssao/fullscreen.slang b/shaders/slang/ssao/fullscreen.slang new file mode 100644 index 00000000..d734ebc5 --- /dev/null +++ b/shaders/slang/ssao/fullscreen.slang @@ -0,0 +1,16 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +import types; + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex : SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} diff --git a/shaders/slang/ssao/gbuffer.slang b/shaders/slang/ssao/gbuffer.slang new file mode 100644 index 00000000..73e4d9dd --- /dev/null +++ b/shaders/slang/ssao/gbuffer.slang @@ -0,0 +1,73 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float2 UV; + float3 Color; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; + float3 Color; + float3 WorldPos; +}; + +struct FSOutput +{ + float4 Position : SV_TARGET0; + float4 Normal : SV_TARGET1; + float4 Albedo : SV_TARGET2; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; + float nearPlane; + float farPlane; +}; +ConstantBuffer ubo; + +[[vk::binding(0, 1)]] Texture2D textureColorMap; +[[vk::binding(0, 1)]] SamplerState samplerColorMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, input.Pos))); + output.UV = input.UV; + // Vertex position in view space + output.WorldPos = mul(ubo.view, mul(ubo.model, input.Pos)).xyz; + // Normal in view space + float3x3 normalMatrix = (float3x3)mul(ubo.view, ubo.model); + output.Normal = mul(normalMatrix, input.Normal); + output.Color = input.Color; + return output; +} + +float linearDepth(float depth) +{ + float z = depth * 2.0f - 1.0f; + return (2.0f * ubo.nearPlane * ubo.farPlane) / (ubo.farPlane + ubo.nearPlane - z * (ubo.farPlane - ubo.nearPlane)); +} + +[shader("fragment")] +FSOutput fragmentMain(VSOutput input) +{ + FSOutput output; + output.Position = float4(input.WorldPos, linearDepth(input.Pos.z)); + output.Normal = float4(normalize(input.Normal) * 0.5 + 0.5, 1.0); + output.Albedo = textureColorMap.Sample(samplerColorMap, input.UV) * float4(input.Color, 1.0); + return output; +} \ No newline at end of file diff --git a/shaders/slang/ssao/ssao.slang b/shaders/slang/ssao/ssao.slang new file mode 100644 index 00000000..624a5f78 --- /dev/null +++ b/shaders/slang/ssao/ssao.slang @@ -0,0 +1,70 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +import types; + +Sampler2D samplerPositionDepth; +Sampler2D samplerNormal; +Sampler2D ssaoNoiseSampler; + +struct UBOSSAOKernel +{ + float4 samples[64]; +}; +ConstantBuffer uboSSAOKernel; + +struct UBO +{ + float4x4 projection; +}; +ConstantBuffer ubo; + +[[SpecializationConstant]] const int SSAO_KERNEL_SIZE = 64; +[[SpecializationConstant]] const float SSAO_RADIUS = 0.5; + +[shader("fragment")] +float fragmentMain(VSOutput input) +{ + // Get G-Buffer values + float3 fragPos = samplerPositionDepth.Sample(input.UV).rgb; + float3 normal = normalize(samplerNormal.Sample(input.UV).rgb * 2.0 - 1.0); + + // Get a random vector using a noise lookup + int2 texDim; + samplerPositionDepth.GetDimensions(texDim.x, texDim.y); + int2 noiseDim; + ssaoNoiseSampler.GetDimensions(noiseDim.x, noiseDim.y); + const float2 noiseUV = float2(float(texDim.x) / float(noiseDim.x), float(texDim.y) / (noiseDim.y)) * input.UV; + float3 randomVec = ssaoNoiseSampler.Sample(noiseUV).xyz * 2.0 - 1.0; + + // Create TBN matrix + float3 tangent = normalize(randomVec - normal * dot(randomVec, normal)); + float3 bitangent = cross(tangent, normal); + float3x3 TBN = transpose(float3x3(tangent, bitangent, normal)); + + // Calculate occlusion value + float occlusion = 0.0f; + for(int i = 0; i < SSAO_KERNEL_SIZE; i++) + { + float3 samplePos = mul(TBN, uboSSAOKernel.samples[i].xyz); + samplePos = fragPos + samplePos * SSAO_RADIUS; + + // project + float4 offset = float4(samplePos, 1.0f); + offset = mul(ubo.projection, offset); + offset.xyz /= offset.w; + offset.xyz = offset.xyz * 0.5f + 0.5f; + + float sampleDepth = -samplerPositionDepth.Sample(offset.xy).w; + + float rangeCheck = smoothstep(0.0f, 1.0f, SSAO_RADIUS / abs(fragPos.z - sampleDepth)); + occlusion += (sampleDepth >= samplePos.z ? 1.0f : 0.0f) * rangeCheck; + } + occlusion = 1.0 - (occlusion / float(SSAO_KERNEL_SIZE)); + + return occlusion; +} + diff --git a/shaders/slang/ssao/types.slang b/shaders/slang/ssao/types.slang new file mode 100644 index 00000000..52f46ab3 --- /dev/null +++ b/shaders/slang/ssao/types.slang @@ -0,0 +1,13 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +module types; + +public struct VSOutput +{ + public float4 Pos : SV_POSITION; + public float2 UV; +}; From 829118736fd9f1f2da1cb55e065c984d1937ff72 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Mon, 19 May 2025 19:51:43 +0200 Subject: [PATCH 61/73] Added slang shaders for additional compute samples --- .../computecullandlod/computecullandlod.cpp | 4 +- .../slang/computeraytracing/raytracing.slang | 258 ++++++++++++++++++ shaders/slang/computeraytracing/texture.slang | 28 ++ shaders/slang/computeshader/edgedetect.slang | 34 +++ shaders/slang/computeshader/emboss.slang | 34 +++ shaders/slang/computeshader/shared.slang | 20 ++ shaders/slang/computeshader/sharpen.slang | 43 +++ shaders/slang/computeshader/texture.slang | 41 +++ 8 files changed, 460 insertions(+), 2 deletions(-) create mode 100644 shaders/slang/computeraytracing/raytracing.slang create mode 100644 shaders/slang/computeraytracing/texture.slang create mode 100644 shaders/slang/computeshader/edgedetect.slang create mode 100644 shaders/slang/computeshader/emboss.slang create mode 100644 shaders/slang/computeshader/shared.slang create mode 100644 shaders/slang/computeshader/sharpen.slang create mode 100644 shaders/slang/computeshader/texture.slang diff --git a/examples/computecullandlod/computecullandlod.cpp b/examples/computecullandlod/computecullandlod.cpp index 0aa566cb..6cb5ae9e 100644 --- a/examples/computecullandlod/computecullandlod.cpp +++ b/examples/computecullandlod/computecullandlod.cpp @@ -391,8 +391,8 @@ public: vks::initializers::vertexInputAttributeDescription(0, 2, VK_FORMAT_R32G32B32_SFLOAT, offsetof(vkglTF::Vertex, color)), // Location 2: Texture coordinates // Per-Instance attributes // These are fetched for each instance rendered - vks::initializers::vertexInputAttributeDescription(1, 4, VK_FORMAT_R32G32B32_SFLOAT, offsetof(InstanceData, pos)), // Location 4: Position - vks::initializers::vertexInputAttributeDescription(1, 5, VK_FORMAT_R32_SFLOAT, offsetof(InstanceData, scale)), // Location 5: Scale + vks::initializers::vertexInputAttributeDescription(1, 3, VK_FORMAT_R32G32B32_SFLOAT, offsetof(InstanceData, pos)), // Location 4: Position + vks::initializers::vertexInputAttributeDescription(1, 4, VK_FORMAT_R32_SFLOAT, offsetof(InstanceData, scale)), // Location 5: Scale }; inputState.pVertexBindingDescriptions = bindingDescriptions.data(); inputState.pVertexAttributeDescriptions = attributeDescriptions.data(); diff --git a/shaders/slang/computeraytracing/raytracing.slang b/shaders/slang/computeraytracing/raytracing.slang new file mode 100644 index 00000000..6e55885c --- /dev/null +++ b/shaders/slang/computeraytracing/raytracing.slang @@ -0,0 +1,258 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +// Shader is looseley based on the ray tracing coding session by Inigo Quilez (www.iquilezles.org) + +#define EPSILON 0.0001 +#define MAXLEN 1000.0 +#define SHADOW 0.5 +#define RAYBOUNCES 2 +#define REFLECTIONS true +#define REFLECTIONSTRENGTH 0.4 +#define REFLECTIONFALLOFF 0.5 + +#define SceneObjectTypeSphere 0 +#define SceneObjectTypePlane 1 + +RWTexture2D resultImage; + +struct Camera +{ + float3 pos; + float3 lookat; + float fov; +}; + +struct UBO +{ + float3 lightPos; + float aspectRatio; + float4 fogColor; + Camera camera; + float4x4 rotMat; +}; +ConstantBuffer ubo; + +struct SceneObject +{ + float4 objectProperties; + float3 diffuse; + float specular; + int id; + int objectType; +}; +StructuredBuffer sceneObjects; + +void reflectRay(inout float3 rayD, in float3 mormal) +{ + rayD = rayD + 2.0 * -dot(mormal, rayD) * mormal; +} + +// Lighting ========================================================= + +float lightDiffuse(float3 normal, float3 lightDir) +{ + return clamp(dot(normal, lightDir), 0.1, 1.0); +} + +float lightSpecular(float3 normal, float3 lightDir, float specularFactor) +{ + float3 viewVec = normalize(ubo.camera.pos); + float3 halfVec = normalize(lightDir + viewVec); + return pow(clamp(dot(normal, halfVec), 0.0, 1.0), specularFactor); +} + +// Sphere =========================================================== + +float sphereIntersect(in float3 rayO, in float3 rayD, in SceneObject sphere) +{ + float3 oc = rayO - sphere.objectProperties.xyz; + float b = 2.0 * dot(oc, rayD); + float c = dot(oc, oc) - sphere.objectProperties.w * sphere.objectProperties.w; + float h = b*b - 4.0*c; + if (h < 0.0) + { + return -1.0; + } + float t = (-b - sqrt(h)) / 2.0; + + return t; +} + +float3 sphereNormal(in float3 pos, in SceneObject sphere) +{ + return (pos - sphere.objectProperties.xyz) / sphere.objectProperties.w; +} + +// Plane =========================================================== + +float planeIntersect(float3 rayO, float3 rayD, SceneObject plane) +{ + float d = dot(rayD, plane.objectProperties.xyz); + + if (d == 0.0) + return 0.0; + + float t = -(plane.objectProperties.w + dot(rayO, plane.objectProperties.xyz)) / d; + + if (t < 0.0) + return 0.0; + + return t; +} + + +int intersect(in float3 rayO, in float3 rayD, inout float resT) +{ + int id = -1; + float t = MAXLEN; + + uint sceneObjectsLength; + uint sceneObjectsStride; + sceneObjects.GetDimensions(sceneObjectsLength, sceneObjectsStride); + + for (int i = 0; i < sceneObjectsLength; i++) { + // Sphere + if (sceneObjects[i].objectType == SceneObjectTypeSphere) { + t = sphereIntersect(rayO, rayD, sceneObjects[i]); + } + // Plane + if (sceneObjects[i].objectType == SceneObjectTypePlane) { + t = planeIntersect(rayO, rayD, sceneObjects[i]); + } + if ((t > EPSILON) && (t < resT)) + { + id = sceneObjects[i].id; + resT = t; + } + } + + return id; +} + +float calcShadow(in float3 rayO, in float3 rayD, in int objectId, inout float t) +{ + uint sceneObjectsLength; + uint sceneObjectsStride; + sceneObjects.GetDimensions(sceneObjectsLength, sceneObjectsStride); + + for (int i = 0; i < sceneObjectsLength; i++) { + if (sceneObjects[i].id == objectId) + continue; + + float tLoc = MAXLEN; + + // Sphere + if (sceneObjects[i].objectType == SceneObjectTypeSphere) + { + tLoc = sphereIntersect(rayO, rayD, sceneObjects[i]); + } + // Plane + if (sceneObjects[i].objectType == SceneObjectTypePlane) + { + tLoc = planeIntersect(rayO, rayD, sceneObjects[i]); + } + if ((tLoc > EPSILON) && (tLoc < t)) + { + t = tLoc; + return SHADOW; + } + } + return 1.0; +} + +float3 fog(in float t, in float3 color) +{ + return lerp(color, ubo.fogColor.rgb, clamp(sqrt(t*t)/20.0, 0.0, 1.0)); +} + +float3 renderScene(inout float3 rayO, inout float3 rayD, inout int id) +{ + float3 color = float3(0, 0, 0); + float t = MAXLEN; + + // Get intersected object ID + int objectID = intersect(rayO, rayD, t); + + if (objectID == -1) + { + return color; + } + + float3 pos = rayO + t * rayD; + float3 lightVec = normalize(ubo.lightPos - pos); + float3 normal; + + uint sceneObjectsLength; + uint sceneObjectsStride; + sceneObjects.GetDimensions(sceneObjectsLength, sceneObjectsStride); + + for (int i = 0; i < sceneObjectsLength; i++) { + if (objectID == sceneObjects[i].id) + { + // Sphere + if (sceneObjects[i].objectType == SceneObjectTypeSphere) { + normal = sphereNormal(pos, sceneObjects[i]); + } + // Plane + if (sceneObjects[i].objectType == SceneObjectTypePlane) { + normal = sceneObjects[i].objectProperties.xyz; + } + // Lighting + float diffuse = lightDiffuse(normal, lightVec); + float specular = lightSpecular(normal, lightVec, sceneObjects[i].specular); + color = diffuse * sceneObjects[i].diffuse + specular; + } + } + + if (id == -1) + return color; + + id = objectID; + + // Shadows + t = length(ubo.lightPos - pos); + color *= calcShadow(pos, lightVec, id, t); + + // Fog + color = fog(t, color); + + // Reflect ray for next render pass + reflectRay(rayD, normal); + rayO = pos; + + return color; +} + +[shader("compute")] +[numthreads(16, 16, 1)] +void computeMain(uint3 GlobalInvocationID : SV_DispatchThreadID) +{ + int2 dim; + resultImage.GetDimensions(dim.x, dim.y); + float2 uv = float2(GlobalInvocationID.xy) / dim; + + float3 rayO = ubo.camera.pos; + float3 rayD = normalize(float3((-1.0 + 2.0 * uv) * float2(ubo.aspectRatio, 1.0), -1.0)); + + // Basic color path + int id = 0; + float3 finalColor = renderScene(rayO, rayD, id); + + // Reflection + if (REFLECTIONS) + { + float reflectionStrength = REFLECTIONSTRENGTH; + for (int i = 0; i < RAYBOUNCES; i++) + { + float3 reflectionColor = renderScene(rayO, rayD, id); + finalColor = (1.0 - reflectionStrength) * finalColor + reflectionStrength * lerp(reflectionColor, finalColor, 1.0 - reflectionStrength); + reflectionStrength *= REFLECTIONFALLOFF; + } + } + + resultImage[int2(GlobalInvocationID.xy)] = float4(finalColor, 0.0); +} \ No newline at end of file diff --git a/shaders/slang/computeraytracing/texture.slang b/shaders/slang/computeraytracing/texture.slang new file mode 100644 index 00000000..0b126565 --- /dev/null +++ b/shaders/slang/computeraytracing/texture.slang @@ -0,0 +1,28 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + + struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +Sampler2D samplerColor; + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f + -1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return samplerColor.Sample(float2(input.UV.x, 1.0 - input.UV.y)); +} \ No newline at end of file diff --git a/shaders/slang/computeshader/edgedetect.slang b/shaders/slang/computeshader/edgedetect.slang new file mode 100644 index 00000000..ecbb5bf3 --- /dev/null +++ b/shaders/slang/computeshader/edgedetect.slang @@ -0,0 +1,34 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +import shared; + +[shader("compute")] +[numthreads(16, 16, 1)] +void computeMain(uint3 GlobalInvocationID : SV_DispatchThreadID) +{ + float imageData[9]; + // Fetch neighbouring texels + int n = -1; + for (int i=-1; i<2; ++i) + { + for(int j=-1; j<2; ++j) + { + n++; + float3 rgb = inputImage[uint2(GlobalInvocationID.x + i, GlobalInvocationID.y + j)].rgb; + imageData[n] = (rgb.r + rgb.g + rgb.b) / 3.0; + } + } + + float kernel[9]; + kernel[0] = -1.0/8.0; kernel[1] = -1.0/8.0; kernel[2] = -1.0/8.0; + kernel[3] = -1.0/8.0; kernel[4] = 1.0; kernel[5] = -1.0/8.0; + kernel[6] = -1.0/8.0; kernel[7] = -1.0/8.0; kernel[8] = -1.0/8.0; + + float4 res = float4(conv(kernel, imageData, 0.1, 0.0).xxx, 1.0); + + resultImage[int2(GlobalInvocationID.xy)] = res; +} diff --git a/shaders/slang/computeshader/emboss.slang b/shaders/slang/computeshader/emboss.slang new file mode 100644 index 00000000..6bd00f63 --- /dev/null +++ b/shaders/slang/computeshader/emboss.slang @@ -0,0 +1,34 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +import shared; + +[shader("compute")] +[numthreads(16, 16, 1)] +void computeMain(uint3 GlobalInvocationID : SV_DispatchThreadID) +{ + float imageData[9]; + // Fetch neighbouring texels + int n = -1; + for (int i=-1; i<2; ++i) + { + for(int j=-1; j<2; ++j) + { + n++; + float3 rgb = inputImage[uint2(GlobalInvocationID.x + i, GlobalInvocationID.y + j)].rgb; + imageData[n] = (rgb.r + rgb.g + rgb.b) / 3.0; + } + } + + float kernel[9]; + kernel[0] = -1.0; kernel[1] = 0.0; kernel[2] = 0.0; + kernel[3] = 0.0; kernel[4] = -1.0; kernel[5] = 0.0; + kernel[6] = 0.0; kernel[7] = 0.0; kernel[8] = 2.0; + + float4 res = float4(conv(kernel, imageData, 1.0, 0.50).xxx, 1.0); + + resultImage[int2(GlobalInvocationID.xy)] = res; +} \ No newline at end of file diff --git a/shaders/slang/computeshader/shared.slang b/shaders/slang/computeshader/shared.slang new file mode 100644 index 00000000..54828404 --- /dev/null +++ b/shaders/slang/computeshader/shared.slang @@ -0,0 +1,20 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +module shared; + +public Texture2D inputImage; +public RWTexture2D resultImage; + +public float conv(in float kernel[9], in float data[9], in float denom, in float offset) +{ + float res = 0.0; + for (int i=0; i<9; ++i) + { + res += kernel[i] * data[i]; + } + return saturate(res/denom + offset); +} \ No newline at end of file diff --git a/shaders/slang/computeshader/sharpen.slang b/shaders/slang/computeshader/sharpen.slang new file mode 100644 index 00000000..0fa15f37 --- /dev/null +++ b/shaders/slang/computeshader/sharpen.slang @@ -0,0 +1,43 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +import shared; + +[shader("compute")] +[numthreads(16, 16, 1)] +void computeMain(uint3 GlobalInvocationID : SV_DispatchThreadID) +{ + float r[9]; + float g[9]; + float b[9]; + + // Fetch neighbouring texels + int n = -1; + for (int i=-1; i<2; ++i) + { + for(int j=-1; j<2; ++j) + { + n++; + float3 rgb = inputImage[uint2(GlobalInvocationID.x + i, GlobalInvocationID.y + j)].rgb; + r[n] = rgb.r; + g[n] = rgb.g; + b[n] = rgb.b; + } + } + + float kernel[9]; + kernel[0] = -1.0; kernel[1] = -1.0; kernel[2] = -1.0; + kernel[3] = -1.0; kernel[4] = 9.0; kernel[5] = -1.0; + kernel[6] = -1.0; kernel[7] = -1.0; kernel[8] = -1.0; + + float4 res = float4( + conv(kernel, r, 1.0, 0.0), + conv(kernel, g, 1.0, 0.0), + conv(kernel, b, 1.0, 0.0), + 1.0); + + resultImage[int2(GlobalInvocationID.xy)] = res; +} \ No newline at end of file diff --git a/shaders/slang/computeshader/texture.slang b/shaders/slang/computeshader/texture.slang new file mode 100644 index 00000000..dceb0669 --- /dev/null +++ b/shaders/slang/computeshader/texture.slang @@ -0,0 +1,41 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; +ConstantBuffer ubo; + +Sampler2D samplerColor; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return samplerColor.Sample(input.UV); +} \ No newline at end of file From 834ee9ed8351bc70b173870d92095365ac0584e9 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Mon, 19 May 2025 21:42:08 +0200 Subject: [PATCH 62/73] Added slang shaders for additional samples --- shaders/slang/multithreading/phong.slang | 54 +++++++++++++++ shaders/slang/multithreading/starsphere.slang | 58 ++++++++++++++++ shaders/slang/offscreen/mirror.slang | 68 +++++++++++++++++++ shaders/slang/offscreen/phong.slang | 63 +++++++++++++++++ shaders/slang/offscreen/quad.slang | 28 ++++++++ 5 files changed, 271 insertions(+) create mode 100644 shaders/slang/multithreading/phong.slang create mode 100644 shaders/slang/multithreading/starsphere.slang create mode 100644 shaders/slang/offscreen/mirror.slang create mode 100644 shaders/slang/offscreen/phong.slang create mode 100644 shaders/slang/offscreen/quad.slang diff --git a/shaders/slang/multithreading/phong.slang b/shaders/slang/multithreading/phong.slang new file mode 100644 index 00000000..ad82f3af --- /dev/null +++ b/shaders/slang/multithreading/phong.slang @@ -0,0 +1,54 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 ViewVec; + float3 LightVec; +}; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform float4x4 mvp, uniform float3 color) +{ + VSOutput output; + if ((input.Color.r == 1.0) && (input.Color.g == 0.0) && (input.Color.b == 0.0)) + { + output.Color = color; + } + else + { + output.Color = input.Color; + } + output.Pos = mul(mvp, float4(input.Pos.xyz, 1.0)); + float4 pos = mul(mvp, float4(input.Pos, 1.0)); + output.Normal = mul((float3x3)mvp, input.Normal); + float3 lPos = float3(0.0, 0.0, 0.0); + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * input.Color; + float3 specular = pow(max(dot(R, V), 0.0), 8.0) * float3(0.75, 0.75, 0.75); + return float4(diffuse + specular, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/multithreading/starsphere.slang b/shaders/slang/multithreading/starsphere.slang new file mode 100644 index 00000000..2d6c492f --- /dev/null +++ b/shaders/slang/multithreading/starsphere.slang @@ -0,0 +1,58 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +#define HASHSCALE3 float3(443.897, 441.423, 437.195) +#define STARFREQUENCY 0.01 + +// Hash function by Dave Hoskins (https://www.shadertoy.com/view/4djSRW) +float hash33(float3 p3) +{ + p3 = frac(p3 * HASHSCALE3); + p3 += dot(p3, p3.yxz+float3(19.19, 19.19, 19.19)); + return frac((p3.x + p3.y)*p3.z + (p3.x+p3.z)*p3.y + (p3.y+p3.z)*p3.x); +} + +float3 starField(float3 pos) +{ + float3 color = float3(0.0, 0.0, 0.0); + float threshhold = (1.0 - STARFREQUENCY); + float rnd = hash33(pos); + if (rnd >= threshhold) + { + float starCol = pow((rnd - threshhold) / (1.0 - threshhold), 16.0); + color += starCol.xxx; + } + return color; +} + +struct VSInput +{ + float3 Pos; +} + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 UVW; +}; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uniform float4x4 mvp) +{ + VSOutput output; + output.UVW = input.Pos; + output.Pos = mul(mvp, float4(input.Pos.xyz, 1.0)); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + // Fake atmosphere at the bottom + float3 atmosphere = clamp(float3(0.1, 0.15, 0.4) * (input.UVW.y + 0.25), 0.0, 1.0); + float3 color = starField(input.UVW) + atmosphere; + return float4(color, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/offscreen/mirror.slang b/shaders/slang/offscreen/mirror.slang new file mode 100644 index 00000000..49cf8791 --- /dev/null +++ b/shaders/slang/offscreen/mirror.slang @@ -0,0 +1,68 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float4 ProjCoord; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; +}; +ConstantBuffer ubo; + +Sampler2D samplerColor; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.ProjCoord = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos.xyz, 1.0)))); + output.Pos = output.ProjCoord; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input, bool FrontFacing : SV_IsFrontFace) +{ + float4 tmp = (1.0 / input.ProjCoord.w).xxxx; + float4 projCoord = input.ProjCoord * tmp; + + // Scale and bias + projCoord += float4(1.0, 1.0, 1.0, 1.0); + projCoord *= float4(0.5, 0.5, 0.5, 0.5); + + // Slow single pass blur + // For demonstration purposes only + const float blurSize = 1.0 / 512.0; + + float4 color = float4(float3(0.0, 0.0, 0.0), 1.); + + if (FrontFacing) + { + // Only render mirrored scene on front facing (upper) side of mirror surface + float4 reflection = float4(0.0, 0.0, 0.0, 0.0); + for (int x = -3; x <= 3; x++) + { + for (int y = -3; y <= 3; y++) + { + reflection += samplerColor.Sample(float2(projCoord.x + x * blurSize, projCoord.y + y * blurSize)) / 49.0; + } + } + color += reflection; + } + + return color; +} \ No newline at end of file diff --git a/shaders/slang/offscreen/phong.slang b/shaders/slang/offscreen/phong.slang new file mode 100644 index 00000000..e8743485 --- /dev/null +++ b/shaders/slang/offscreen/phong.slang @@ -0,0 +1,63 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Color; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float ClipDistance : SV_ClipDistance0; + float3 Normal; + float3 Color; + float3 EyePos; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; + float4x4 model; + float4 lightPos; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Normal = input.Normal; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos, 1.0)))); + output.EyePos = mul(ubo.view, mul(ubo.model, float4(input.Pos, 1.0))).xyz; + output.LightVec = normalize(ubo.lightPos.xyz - output.EyePos); + // Clip against reflection plane + float4 clipPlane = float4(0.0, 0.0, 0.0, 0.0); + output.ClipDistance = dot(float4(input.Pos, 1.0), clipPlane); + return output; +} + + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 Eye = normalize(-input.EyePos); + float3 Reflected = normalize(reflect(-input.LightVec, input.Normal)); + float4 IAmbient = float4(0.1, 0.1, 0.1, 1.0); + float4 IDiffuse = max(dot(input.Normal, input.LightVec), 0.0).xxxx; + float specular = 0.75; + float4 ISpecular = float4(0.0, 0.0, 0.0, 0.0); + if (dot(input.EyePos, input.Normal) < 0.0) + { + ISpecular = float4(0.5, 0.5, 0.5, 1.0) * pow(max(dot(Reflected, Eye), 0.0), 16.0) * specular; + } + return float4((IAmbient + IDiffuse) * float4(input.Color, 1.0) + ISpecular); +} \ No newline at end of file diff --git a/shaders/slang/offscreen/quad.slang b/shaders/slang/offscreen/quad.slang new file mode 100644 index 00000000..49b0ebf7 --- /dev/null +++ b/shaders/slang/offscreen/quad.slang @@ -0,0 +1,28 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +[[vk::binding(1, 0)]] Sampler2D samplerColor; + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return samplerColor.Sample(input.UV); +} \ No newline at end of file From 24bc3e3aa972f5da0a79f01a8f02f3a679810381 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Tue, 20 May 2025 17:37:27 +0200 Subject: [PATCH 63/73] Added slang shaders for additional samples --- shaders/slang/particlesystem/normalmap.slang | 98 ++++++++++++++++++++ shaders/slang/particlesystem/particle.slang | 97 +++++++++++++++++++ shaders/slang/radialblur/colorpass.slang | 51 ++++++++++ shaders/slang/radialblur/phongpass.slang | 67 +++++++++++++ shaders/slang/radialblur/radialblur.slang | 48 ++++++++++ 5 files changed, 361 insertions(+) create mode 100644 shaders/slang/particlesystem/normalmap.slang create mode 100644 shaders/slang/particlesystem/particle.slang create mode 100644 shaders/slang/radialblur/colorpass.slang create mode 100644 shaders/slang/radialblur/phongpass.slang create mode 100644 shaders/slang/radialblur/radialblur.slang diff --git a/shaders/slang/particlesystem/normalmap.slang b/shaders/slang/particlesystem/normalmap.slang new file mode 100644 index 00000000..6b471e4b --- /dev/null +++ b/shaders/slang/particlesystem/normalmap.slang @@ -0,0 +1,98 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float2 UV; + float3 Normal; + float4 Tangent; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; + float3 LightVec; + float3 LightVecB; + float3 LightDir; + float3 ViewVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 normal; + float4 lightPos; +}; +ConstantBuffer ubo; + +Sampler2D samplerColorMap; +Sampler2D samplerNormalHeightMap; + +#define lightRadius 45.0 + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + float3 vertexPosition = mul(ubo.model, float4(input.Pos, 1.0)).xyz; + output.LightDir = normalize(ubo.lightPos.xyz - vertexPosition); + + float3 biTangent = cross(input.Normal, input.Tangent.xyz); + + // Setup (t)angent-(b)inormal-(n)ormal matrix for converting + // object coordinates into tangent space + float3x3 tbnMatrix; + tbnMatrix[0] = mul((float3x3)ubo.normal, input.Tangent.xyz); + tbnMatrix[1] = mul((float3x3)ubo.normal, biTangent); + tbnMatrix[2] = mul((float3x3)ubo.normal, input.Normal); + + output.LightVec.xyz = mul(float3(ubo.lightPos.xyz - vertexPosition), tbnMatrix); + + float3 lightDist = ubo.lightPos.xyz - input.Pos; + output.LightVecB.x = dot(input.Tangent.xyz, lightDist); + output.LightVecB.y = dot(biTangent, lightDist); + output.LightVecB.z = dot(input.Normal, lightDist); + + output.ViewVec.x = dot(input.Tangent.xyz, input.Pos); + output.ViewVec.y = dot(biTangent, input.Pos); + output.ViewVec.z = dot(input.Normal, input.Pos); + + output.UV = input.UV; + + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 specularColor = float3(0.85, 0.5, 0.0); + + float invRadius = 1.0/lightRadius; + float ambient = 0.25; + + float3 rgb, normal; + + rgb = samplerColorMap.Sample(input.UV).rgb; + normal = normalize((samplerNormalHeightMap.Sample(input.UV).rgb - 0.5) * 2.0); + + float distSqr = dot(input.LightVecB, input.LightVecB); + float3 lVec = input.LightVecB * rsqrt(distSqr); + + float atten = max(clamp(1.0 - invRadius * sqrt(distSqr), 0.0, 1.0), ambient); + float diffuse = clamp(dot(lVec, normal), 0.0, 1.0); + + float3 light = normalize(-input.LightVec); + float3 view = normalize(input.ViewVec); + float3 reflectDir = reflect(-light, normal); + + float specular = pow(max(dot(view, reflectDir), 0.0), 4.0); + + return float4((rgb * atten + (diffuse * rgb + 0.5 * specular * specularColor.rgb)) * atten, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/particlesystem/particle.slang b/shaders/slang/particlesystem/particle.slang new file mode 100644 index 00000000..d479260c --- /dev/null +++ b/shaders/slang/particlesystem/particle.slang @@ -0,0 +1,97 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float4 Color; + float Alpha; + float Size; + float Rotation; + int Type; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float PSize : SV_PointSize; + float4 Color; + float Alpha; + int Type; + float Rotation; + float2 CenterPos; + float PointSize; +}; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float2 viewportDim; + float pointSize; +}; +ConstantBuffer ubo; + +Sampler2D samplerSmoke; +Sampler2D samplerFire; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.Alpha = input.Alpha; + output.Type = input.Type; + output.Rotation = input.Rotation; + + output.Pos = mul(ubo.projection, mul(ubo.modelview, float4(input.Pos.xyz, 1.0))); + + // Base size of the point sprites + float spriteSize = 8.0 * input.Size; + + // Scale particle size depending on camera projection + float4 eyePos = mul(ubo.modelview, float4(input.Pos.xyz, 1.0)); + float4 projectedCorner = mul(ubo.projection, float4(0.5 * spriteSize, 0.5 * spriteSize, eyePos.z, eyePos.w)); + output.PointSize = output.PSize = ubo.viewportDim.x * projectedCorner.x / projectedCorner.w; + output.CenterPos = ((output.Pos.xy / output.Pos.w) + 1.0) * 0.5 * ubo.viewportDim; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float4 color; + float alpha = (input.Alpha <= 1.0) ? input.Alpha : 2.0 - input.Alpha; + + // Rotate texture coordinates + // Rotate UV + float rotCenter = 0.5; + float rotCos = cos(input.Rotation); + float rotSin = sin(input.Rotation); + + float2 PointCoord = (input.Pos.xy - input.CenterPos.xy) / input.PointSize + 0.5; + + float2 rotUV = float2( + rotCos * (PointCoord.x - rotCenter) + rotSin * (PointCoord.y - rotCenter) + rotCenter, + rotCos * (PointCoord.y - rotCenter) - rotSin * (PointCoord.x - rotCenter) + rotCenter); + + float4 outFragColor; + if (input.Type == 0) + { + // Flame + color = samplerFire.Sample(rotUV); + outFragColor.a = 0.0; + } + else + { + // Smoke + color = samplerSmoke.Sample(rotUV); + outFragColor.a = color.a * alpha; + } + + outFragColor.rgb = color.rgb * input.Color.rgb * alpha; + return outFragColor; +} \ No newline at end of file diff --git a/shaders/slang/radialblur/colorpass.slang b/shaders/slang/radialblur/colorpass.slang new file mode 100644 index 00000000..c36de69e --- /dev/null +++ b/shaders/slang/radialblur/colorpass.slang @@ -0,0 +1,51 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float2 UV; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Color; + float2 UV; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float gradientPos; +}; +ConstantBuffer ubo; + +Sampler2D samplerGradientRamp; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.UV = float2(ubo.gradientPos, 0.0f); + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + // Use max. color channel value to detect bright glow emitters + if ((input.Color.r >= 0.9) || (input.Color.g >= 0.9) || (input.Color.b >= 0.9)) + { + return float4(samplerGradientRamp.Sample(input.UV).rgb, 1); + } else { + return float4(input.Color, 1); + } +} \ No newline at end of file diff --git a/shaders/slang/radialblur/phongpass.slang b/shaders/slang/radialblur/phongpass.slang new file mode 100644 index 00000000..7569146d --- /dev/null +++ b/shaders/slang/radialblur/phongpass.slang @@ -0,0 +1,67 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float2 UV; + float3 Color; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 EyePos; + float3 LightVec; + float2 UV; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float gradientPos; +}; +ConstantBuffer ubo; + +Sampler2D samplerGradientRamp; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Normal = input.Normal; + output.Color = input.Color; + output.UV = float2(ubo.gradientPos, 0.0); + output.Pos = mul(ubo.projection, mul(ubo.model, input.Pos)); + output.EyePos = mul(ubo.model, input.Pos).xyz; + float4 lightPos = float4(0.0, 0.0, -5.0, 1.0); // * ubo.model; + output.LightVec = normalize(lightPos.xyz - input.Pos.xyz); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + // No light calculations for glow color + // Use max. color channel value + // to detect bright glow emitters + if ((input.Color.r >= 0.9) || (input.Color.g >= 0.9) || (input.Color.b >= 0.9)) + { + return float4(samplerGradientRamp.Sample(input.UV).rgb, 1); + } else { + float3 Eye = normalize(-input.EyePos); + float3 Reflected = normalize(reflect(-input.LightVec, input.Normal)); + float4 IAmbient = float4(0.2, 0.2, 0.2, 1.0); + float4 IDiffuse = float4(0.5, 0.5, 0.5, 0.5) * max(dot(input.Normal, input.LightVec), 0.0); + float specular = 0.25; + float4 ISpecular = float4(0.5, 0.5, 0.5, 1.0) * pow(max(dot(Reflected, Eye), 0.0), 4.0) * specular; + return float4((IAmbient + IDiffuse) * float4(input.Color, 1.0) + ISpecular); + } +} \ No newline at end of file diff --git a/shaders/slang/radialblur/radialblur.slang b/shaders/slang/radialblur/radialblur.slang new file mode 100644 index 00000000..8fefdf16 --- /dev/null +++ b/shaders/slang/radialblur/radialblur.slang @@ -0,0 +1,48 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +struct UBO +{ + float radialBlurScale; + float radialBlurStrength; + float2 radialOrigin; +}; +ConstantBuffer ubo; + +Sampler2D samplerColor; + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + int2 texDim; + samplerColor.GetDimensions(texDim.x, texDim.y); + float2 radialSize = float2(1.0 / texDim.x, 1.0 / texDim.y); + float2 UV = input.UV; + float4 color = float4(0.0, 0.0, 0.0, 0.0); + UV += radialSize * 0.5 - ubo.radialOrigin; + #define samples 32 + for (int i = 0; i < samples; i++) + { + float scale = 1.0 - ubo.radialBlurScale * (float(i) / float(samples - 1)); + color += samplerColor.Sample(UV * scale + ubo.radialOrigin); + } + return (color / samples) * ubo.radialBlurStrength; +} \ No newline at end of file From 00378d97608fe65b79bb3b86b14956cfbd630f8d Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Tue, 20 May 2025 18:04:54 +0200 Subject: [PATCH 64/73] Added slang shaders for debug utils sample --- shaders/slang/debugutils/colorpass.slang | 41 +++++++++++++ shaders/slang/debugutils/postprocess.slang | 55 +++++++++++++++++ shaders/slang/debugutils/toon.slang | 71 ++++++++++++++++++++++ 3 files changed, 167 insertions(+) create mode 100644 shaders/slang/debugutils/colorpass.slang create mode 100644 shaders/slang/debugutils/postprocess.slang create mode 100644 shaders/slang/debugutils/toon.slang diff --git a/shaders/slang/debugutils/colorpass.slang b/shaders/slang/debugutils/colorpass.slang new file mode 100644 index 00000000..7061a628 --- /dev/null +++ b/shaders/slang/debugutils/colorpass.slang @@ -0,0 +1,41 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float3 Normal; + float2 UV; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Color; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.Pos = mul(ubo.projection, mul(ubo.model, input.Pos)); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + return float4(input.Color, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/debugutils/postprocess.slang b/shaders/slang/debugutils/postprocess.slang new file mode 100644 index 00000000..a1bce2f7 --- /dev/null +++ b/shaders/slang/debugutils/postprocess.slang @@ -0,0 +1,55 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +[[vk::binding(1, 0)]] Sampler2D samplerColor; + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * float2(2.0f, 2.0f) + float2(-1.0f, -1.0f), 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + // Single pass gauss blur + + const float2 texOffset = float2(0.01, 0.01); + + float2 tc0 = input.UV + float2(-texOffset.x, -texOffset.y); + float2 tc1 = input.UV + float2( 0.0, -texOffset.y); + float2 tc2 = input.UV + float2(+texOffset.x, -texOffset.y); + float2 tc3 = input.UV + float2(-texOffset.x, 0.0); + float2 tc4 = input.UV + float2( 0.0, 0.0); + float2 tc5 = input.UV + float2(+texOffset.x, 0.0); + float2 tc6 = input.UV + float2(-texOffset.x, +texOffset.y); + float2 tc7 = input.UV + float2( 0.0, +texOffset.y); + float2 tc8 = input.UV + float2(+texOffset.x, +texOffset.y); + + float4 col0 = samplerColor.Sample(tc0); + float4 col1 = samplerColor.Sample(tc1); + float4 col2 = samplerColor.Sample(tc2); + float4 col3 = samplerColor.Sample(tc3); + float4 col4 = samplerColor.Sample(tc4); + float4 col5 = samplerColor.Sample(tc5); + float4 col6 = samplerColor.Sample(tc6); + float4 col7 = samplerColor.Sample(tc7); + float4 col8 = samplerColor.Sample(tc8); + + float4 sum = (1.0 * col0 + 2.0 * col1 + 1.0 * col2 + + 2.0 * col3 + 4.0 * col4 + 2.0 * col5 + + 1.0 * col6 + 2.0 * col7 + 1.0 * col8) / 16.0; + return float4(sum.rgb, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/debugutils/toon.slang b/shaders/slang/debugutils/toon.slang new file mode 100644 index 00000000..8d69bee0 --- /dev/null +++ b/shaders/slang/debugutils/toon.slang @@ -0,0 +1,71 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; + float3 Color; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float2 UV; + float3 ViewVec; + float3 LightVec; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 lightPos; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + float4 pos = mul(ubo.model, float4(input.Pos, 1.0)); + output.Normal = mul((float4x3)ubo.model, input.Normal).xyz; + float3 lPos = mul((float4x3)ubo.model, ubo.lightPos.xyz).xyz; + output.LightVec = lPos - pos.xyz; + output.ViewVec = -pos.xyz; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + // Desaturate color + float3 color = float3(lerp(input.Color, dot(float3(0.2126,0.7152,0.0722), input.Color).xxx, 0.65)); + + // High ambient colors because mesh materials are pretty dark + float3 ambient = color * float3(1.0, 1.0, 1.0); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0) * color; + float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); + + float intensity = dot(N,L); + float shade = 1.0; + shade = intensity < 0.5 ? 0.75 : shade; + shade = intensity < 0.35 ? 0.6 : shade; + shade = intensity < 0.25 ? 0.5 : shade; + shade = intensity < 0.1 ? 0.25 : shade; + + return float4(input.Color * 3.0 * shade, 1); +} \ No newline at end of file From 9ff0f35f24bb171a8c8d68034c0a9887e6ccdcad Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Tue, 20 May 2025 19:42:21 +0200 Subject: [PATCH 65/73] Added slang shaders for compute nbody sample --- shaders/slang/computenbody/particle.slang | 56 ++++++++++++++ .../computenbody/particle_calculate.slang | 77 +++++++++++++++++++ .../computenbody/particle_integrate.slang | 31 ++++++++ 3 files changed, 164 insertions(+) create mode 100644 shaders/slang/computenbody/particle.slang create mode 100644 shaders/slang/computenbody/particle_calculate.slang create mode 100644 shaders/slang/computenbody/particle_integrate.slang diff --git a/shaders/slang/computenbody/particle.slang b/shaders/slang/computenbody/particle.slang new file mode 100644 index 00000000..15724781 --- /dev/null +++ b/shaders/slang/computenbody/particle.slang @@ -0,0 +1,56 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float4 Vel; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float PSize : SV_PointSize; + float GradientPos; + float2 CenterPos; + float PointSize; +}; + +Sampler2D samplerColorMap; +Sampler2D samplerGradientRamp; + +struct UBO +{ + float4x4 projection; + float4x4 modelview; + float2 screendim; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + const float spriteSize = 0.005 * input.Pos.w; // Point size influenced by mass (stored in input.Pos.w); + + float4 eyePos = mul(ubo.modelview, float4(input.Pos.x, input.Pos.y, input.Pos.z, 1.0)); + float4 projectedCorner = mul(ubo.projection, float4(0.5 * spriteSize, 0.5 * spriteSize, eyePos.z, eyePos.w)); + output.PSize = output.PointSize = clamp(ubo.screendim.x * projectedCorner.x / projectedCorner.w, 1.0, 128.0); + + output.Pos = mul(ubo.projection, eyePos); + output.CenterPos = ((output.Pos.xy / output.Pos.w) + 1.0) * 0.5 * ubo.screendim; + + output.GradientPos = input.Vel.w; + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + float3 color = samplerGradientRamp.Sample(float2(input.GradientPos, 0.0)).rgb; + float2 PointCoord = (input.Pos.xy - input.CenterPos.xy) / input.PointSize + 0.5; + return float4(samplerColorMap.Sample(PointCoord).rgb * color, 1); +} diff --git a/shaders/slang/computenbody/particle_calculate.slang b/shaders/slang/computenbody/particle_calculate.slang new file mode 100644 index 00000000..e4ec9499 --- /dev/null +++ b/shaders/slang/computenbody/particle_calculate.slang @@ -0,0 +1,77 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct Particle +{ + float4 pos; + float4 vel; +}; +// Binding 0 : Position storage buffer +RWStructuredBuffer particles; + +struct UBO +{ + float deltaT; + int particleCount; + float gravity; + float power; + float soften; +}; +ConstantBuffer ubo; + +#define MAX_SHARED_DATA_SIZE 1024 +[[SpecializationConstant]] const int SHARED_DATA_SIZE = 512; +[[SpecializationConstant]] const float GRAVITY = 0.002; +[[SpecializationConstant]] const float POWER = 0.75; +[[SpecializationConstant]] const float SOFTEN = 0.0075; + +// Share data between computer shader invocations to speed up caluclations +groupshared float4 sharedData[MAX_SHARED_DATA_SIZE]; + +[shader("compute")] +[numthreads(256, 1, 1)] +void computeMain(uint3 GlobalInvocationID : SV_DispatchThreadID, uint3 LocalInvocationID : SV_GroupThreadID) +{ + // Current SSBO index + uint index = GlobalInvocationID.x; + if (index >= ubo.particleCount) + return; + + float4 position = particles[index].pos; + float4 velocity = particles[index].vel; + float4 acceleration = float4(0, 0, 0, 0); + + for (int i = 0; i < ubo.particleCount; i += SHARED_DATA_SIZE) + { + if (i + LocalInvocationID.x < ubo.particleCount) + { + sharedData[LocalInvocationID.x] = particles[i + LocalInvocationID.x].pos; + } + else + { + sharedData[LocalInvocationID.x] = float4(0, 0, 0, 0); + } + + GroupMemoryBarrierWithGroupSync(); + + for (int j = 0; j < 256; j++) + { + float4 other = sharedData[j]; + float3 len = other.xyz - position.xyz; + acceleration.xyz += ubo.gravity * len * other.w / pow(dot(len, len) + ubo.soften, ubo.power); + } + + GroupMemoryBarrierWithGroupSync(); + } + + particles[index].vel.xyz += ubo.deltaT * acceleration.xyz; + + // Gradient texture position + particles[index].vel.w += 0.1 * ubo.deltaT; + if (particles[index].vel.w > 1.0) { + particles[index].vel.w -= 1.0; + } +} \ No newline at end of file diff --git a/shaders/slang/computenbody/particle_integrate.slang b/shaders/slang/computenbody/particle_integrate.slang new file mode 100644 index 00000000..484fe5d9 --- /dev/null +++ b/shaders/slang/computenbody/particle_integrate.slang @@ -0,0 +1,31 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct Particle +{ + float4 pos; + float4 vel; +}; +// Binding 0 : Position storage buffer +RWStructuredBuffer particles; + +struct UBO +{ + float deltaT; + int particleCount; +}; +ConstantBuffer ubo; + +[shader("compute")] +[numthreads(256, 1, 1)] +void computeMain(uint3 GlobalInvocationID : SV_DispatchThreadID) +{ + int index = int(GlobalInvocationID.x); + float4 position = particles[index].pos; + float4 velocity = particles[index].vel; + position += ubo.deltaT * velocity; + particles[index].pos = position; +} \ No newline at end of file From 6183ad5b8974f5d00dfa0ec47aa1301aacdfac59 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Tue, 20 May 2025 20:11:11 +0200 Subject: [PATCH 66/73] Added slang shaders for deferred shadows sample --- shaders/slang/deferredshadows/deferred.slang | 187 +++++++++++++++++++ shaders/slang/deferredshadows/mrt.slang | 83 ++++++++ shaders/slang/deferredshadows/shadow.slang | 57 ++++++ 3 files changed, 327 insertions(+) create mode 100644 shaders/slang/deferredshadows/deferred.slang create mode 100644 shaders/slang/deferredshadows/mrt.slang create mode 100644 shaders/slang/deferredshadows/shadow.slang diff --git a/shaders/slang/deferredshadows/deferred.slang b/shaders/slang/deferredshadows/deferred.slang new file mode 100644 index 00000000..f7759227 --- /dev/null +++ b/shaders/slang/deferredshadows/deferred.slang @@ -0,0 +1,187 @@ +// Copyright 2020 Google LLC + +#define LIGHT_COUNT 3 +#define SHADOW_FACTOR 0.25 +#define AMBIENT_LIGHT 0.1 +#define USE_PCF + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +[[vk::binding(1, 0)]] Sampler2D samplerPosition; +[[vk::binding(2, 0)]] Sampler2D samplerNormal; +[[vk::binding(3, 0)]] Sampler2D samplerAlbedo; + +struct Light +{ + float4 position; + float4 target; + float4 color; + float4x4 viewMatrix; +}; + +struct UBO +{ + float4 viewPos; + Light lights[LIGHT_COUNT]; + int useShadows; + int displayDebugTarget; +}; +[[vk::binding(4, 0)]] ConstantBuffer ubo; + +// Depth from the light's point of view +// layout (binding = 5) uniform sampler2DShadow samplerShadowMap; +[[vk::binding(5, 0)]] Sampler2DArray samplerShadowMap; + +float textureProj(float4 P, float layer, float2 offset) +{ + float shadow = 1.0; + float4 shadowCoord = P / P.w; + shadowCoord.xy = shadowCoord.xy * 0.5 + 0.5; + + if (shadowCoord.z > -1.0 && shadowCoord.z < 1.0) + { + float dist = samplerShadowMap.Sample(float3(shadowCoord.xy + offset, layer)).r; + if (shadowCoord.w > 0.0 && dist < shadowCoord.z) + { + shadow = SHADOW_FACTOR; + } + } + return shadow; +} + +float filterPCF(float4 sc, float layer) +{ + int2 texDim; int elements; int levels; + samplerShadowMap.GetDimensions(0, texDim.x, texDim.y, elements, levels); + float scale = 1.5; + float dx = scale * 1.0 / float(texDim.x); + float dy = scale * 1.0 / float(texDim.y); + + float shadowFactor = 0.0; + int count = 0; + int range = 1; + + for (int x = -range; x <= range; x++) + { + for (int y = -range; y <= range; y++) + { + shadowFactor += textureProj(sc, layer, float2(dx*x, dy*y)); + count++; + } + + } + return shadowFactor / count; +} + +float3 shadow(float3 fragcolor, float3 fragPos) +{ + for (int i = 0; i < LIGHT_COUNT; ++i) + { + float4 shadowClip = mul(ubo.lights[i].viewMatrix, float4(fragPos.xyz, 1.0)); + + float shadowFactor; + #ifdef USE_PCF + shadowFactor= filterPCF(shadowClip, i); + #else + shadowFactor = textureProj(shadowClip, i, float2(0.0, 0.0)); + #endif + + fragcolor *= shadowFactor; + } + return fragcolor; +} + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + // Get G-Buffer values + float3 fragPos = samplerPosition.Sample(input.UV).rgb; + float3 normal = samplerNormal.Sample(input.UV).rgb; + float4 albedo = samplerAlbedo.Sample(input.UV); + + float3 fragcolor; + + // Debug display + if (ubo.displayDebugTarget > 0) { + switch (ubo.displayDebugTarget) { + case 1: + fragcolor.rgb = shadow(float3(1.0, 1.0, 1.0), fragPos); + break; + case 2: + fragcolor.rgb = fragPos; + break; + case 3: + fragcolor.rgb = normal; + break; + case 4: + fragcolor.rgb = albedo.rgb; + break; + case 5: + fragcolor.rgb = albedo.aaa; + break; + } + return float4(fragcolor, 1.0); + } + + // Ambient part + fragcolor = albedo.rgb * AMBIENT_LIGHT; + + float3 N = normalize(normal); + + for(int i = 0; i < LIGHT_COUNT; ++i) + { + // Vector to light + float3 L = ubo.lights[i].position.xyz - fragPos; + // Distance from light to fragment position + float dist = length(L); + L = normalize(L); + + // Viewer to fragment + float3 V = ubo.viewPos.xyz - fragPos; + V = normalize(V); + + float lightCosInnerAngle = cos(radians(15.0)); + float lightCosOuterAngle = cos(radians(25.0)); + float lightRange = 100.0; + + // Direction vector from source to target + float3 dir = normalize(ubo.lights[i].position.xyz - ubo.lights[i].target.xyz); + + // Dual cone spot light with smooth transition between inner and outer angle + float cosDir = dot(L, dir); + float spotEffect = smoothstep(lightCosOuterAngle, lightCosInnerAngle, cosDir); + float heightAttenuation = smoothstep(lightRange, 0.0f, dist); + + // Diffuse lighting + float NdotL = max(0.0, dot(N, L)); + float3 diff = NdotL.xxx; + + // Specular lighting + float3 R = reflect(-L, N); + float NdotR = max(0.0, dot(R, V)); + float3 spec = (pow(NdotR, 16.0) * albedo.a * 2.5).xxx; + + fragcolor += float3((diff + spec) * spotEffect * heightAttenuation) * ubo.lights[i].color.rgb * albedo.rgb; + } + + // Shadow calculations in a separate pass + if (ubo.useShadows > 0) + { + fragcolor = shadow(fragcolor, fragPos); + } + + return float4(fragcolor, 1); +} \ No newline at end of file diff --git a/shaders/slang/deferredshadows/mrt.slang b/shaders/slang/deferredshadows/mrt.slang new file mode 100644 index 00000000..53b42587 --- /dev/null +++ b/shaders/slang/deferredshadows/mrt.slang @@ -0,0 +1,83 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float2 UV; + float3 Color; + float3 Normal; + float3 Tangent; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; + float3 Color; + float3 WorldPos; + float3 Tangent; +}; + +struct FSOutput +{ + float4 Position : SV_TARGET0; + float4 Normal : SV_TARGET1; + float4 Albedo : SV_TARGET2; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; + float4 instancePos[3]; +}; +ConstantBuffer ubo; + +Sampler2D samplerColor; +Sampler2D samplerNormalMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uint InstanceIndex: SV_InstanceID) +{ + VSOutput output; + float4 tmpPos = input.Pos + ubo.instancePos[InstanceIndex]; + + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, tmpPos))); + + output.UV = input.UV; + + // Vertex position in world space + output.WorldPos = mul(ubo.model, tmpPos).xyz; + + // Normal in world space + output.Normal = normalize(input.Normal); + output.Tangent = normalize(input.Tangent); + + // Currently just vertex color + output.Color = input.Color; + return output; +} + +[shader("fragment")] +FSOutput fragmentMain(VSOutput input) +{ + FSOutput output; + output.Position = float4(input.WorldPos, 1.0); + + // Calculate normal in tangent space + float3 N = normalize(input.Normal); + float3 T = normalize(input.Tangent); + float3 B = cross(N, T); + float3x3 TBN = float3x3(T, B, N); + float3 tnorm = mul(normalize(samplerNormalMap.Sample(input.UV).xyz * 2.0 - float3(1.0, 1.0, 1.0)), TBN); + output.Normal = float4(tnorm, 1.0); + + output.Albedo = samplerColor.Sample(input.UV); + return output; +} \ No newline at end of file diff --git a/shaders/slang/deferredshadows/shadow.slang b/shaders/slang/deferredshadows/shadow.slang new file mode 100644 index 00000000..68ada4a9 --- /dev/null +++ b/shaders/slang/deferredshadows/shadow.slang @@ -0,0 +1,57 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +#define LIGHT_COUNT 3 + +struct VSInput +{ + float4 Pos; +} + +struct VSOutput +{ + float4 Pos : SV_POSITION; + int InstanceIndex; +}; + +struct GSOutput +{ + float4 Pos : SV_POSITION; + int Layer : SV_RenderTargetArrayIndex; +}; + +struct UBO +{ + float4x4 mvp[LIGHT_COUNT]; + float4 instancePos[3]; +}; +ConstantBuffer ubo; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uint InstanceIndex: SV_InstanceID) +{ + VSOutput output; + output.InstanceIndex = InstanceIndex; + output.Pos = input.Pos; + return output; +} + +[shader("geometry")] +[maxvertexcount(3)] +[instance(3)] +void geometryMain(triangle VSOutput input[3], uint InvocationID : SV_GSInstanceID, inout TriangleStream outStream) +{ + float4 instancedPos = ubo.instancePos[input[0].InstanceIndex]; + for (int i = 0; i < 3; i++) + { + float4 tmpPos = input[i].Pos + instancedPos; + GSOutput output; + output.Pos = mul(ubo.mvp[InvocationID], tmpPos); + output.Layer = InvocationID; + outStream.Append( output ); + } + outStream.RestartStrip(); +} \ No newline at end of file From ee535efc2fadeb7e944804339d9bdcb885b2f52c Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Wed, 21 May 2025 08:21:13 +0200 Subject: [PATCH 67/73] Added slang shaders for sparse resident textures sample --- .../sparseresidency.slang | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 shaders/slang/texturesparseresidency/sparseresidency.slang diff --git a/shaders/slang/texturesparseresidency/sparseresidency.slang b/shaders/slang/texturesparseresidency/sparseresidency.slang new file mode 100644 index 00000000..6ad26c8a --- /dev/null +++ b/shaders/slang/texturesparseresidency/sparseresidency.slang @@ -0,0 +1,54 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float3 Pos; + float3 Normal; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; + float LodBias; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 viewPos; + float lodBias; +}; +ConstantBuffer ubo; + +Sampler2D samplerColor; + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.UV = input.UV; + output.LodBias = ubo.lodBias; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + // Check if texel is resident + uint status = 0; + float4 sampledColor = samplerColor.Sample(input.UV, int2(0, 0), input.LodBias, status); + bool texelResident = CheckAccessFullyMapped(status); + if (texelResident) { + return sampledColor; + } else { + return float4(0.0, 0.0, 0.0, 1.0); + } +} \ No newline at end of file From 487fd21d44a2b52782840f7ead5b2dc449894e9c Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 31 May 2025 13:43:45 +0200 Subject: [PATCH 68/73] Added final missing slang shaders Requires a very recent version of slang --- .../deferredmultisampling/deferred.slang | 140 ++++++++++++++++++ shaders/slang/deferredmultisampling/mrt.slang | 83 +++++++++++ shaders/slang/subpasses/composition.slang | 66 +++++++++ shaders/slang/subpasses/gbuffer.slang | 78 ++++++++++ shaders/slang/subpasses/transparent.slang | 64 ++++++++ 5 files changed, 431 insertions(+) create mode 100644 shaders/slang/deferredmultisampling/deferred.slang create mode 100644 shaders/slang/deferredmultisampling/mrt.slang create mode 100644 shaders/slang/subpasses/composition.slang create mode 100644 shaders/slang/subpasses/gbuffer.slang create mode 100644 shaders/slang/subpasses/transparent.slang diff --git a/shaders/slang/deferredmultisampling/deferred.slang b/shaders/slang/deferredmultisampling/deferred.slang new file mode 100644 index 00000000..81d3b3bc --- /dev/null +++ b/shaders/slang/deferredmultisampling/deferred.slang @@ -0,0 +1,140 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +[[vk::binding(1, 0)]] Texture2DMS samplerPosition; +[[vk::binding(2, 0)]] Texture2DMS samplerNormal; +[[vk::binding(3, 0)]] Texture2DMS samplerAlbedo; + +struct Light { + float4 position; + float3 color; + float radius; +}; + +struct UBO +{ + Light lights[6]; + float4 viewPos; + int displayDebugTarget; +}; +[[vk::binding(4, 0)]] ConstantBuffer ubo; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +[[SpecializationConstant]] const int NUM_SAMPLES = 8; +#define NUM_LIGHTS 6 + +// Manual resolve for MSAA samples +float4 resolve(Texture2DMS tex, int2 uv) +{ + float4 result = float4(0.0, 0.0, 0.0, 0.0); + for (int i = 0; i < NUM_SAMPLES; i++) + { + uint status = 0; + float4 val = tex.Load(uv, i, int2(0, 0), status); + result += val; + } + // Average resolved samples + return result / float(NUM_SAMPLES); +} + +float3 calculateLighting(float3 pos, float3 normal, float4 albedo) +{ + float3 result = float3(0.0, 0.0, 0.0); + + for (int i = 0; i < NUM_LIGHTS; ++i) + { + // Vector to light + float3 L = ubo.lights[i].position.xyz - pos; + // Distance from light to fragment position + float dist = length(L); + + // Viewer to fragment + float3 V = ubo.viewPos.xyz - pos; + V = normalize(V); + + // Light to fragment + L = normalize(L); + + // Attenuation + float atten = ubo.lights[i].radius / (pow(dist, 2.0) + 1.0); + + // Diffuse part + float3 N = normalize(normal); + float NdotL = max(0.0, dot(N, L)); + float3 diff = ubo.lights[i].color * albedo.rgb * NdotL * atten; + + // Specular part + float3 R = reflect(-L, N); + float NdotR = max(0.0, dot(R, V)); + float3 spec = ubo.lights[i].color * albedo.a * pow(NdotR, 8.0) * atten; + + result += diff + spec; + } + return result; +} + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain(VSOutput input) +{ + int2 attDim; int sampleCount; + samplerPosition.GetDimensions(attDim.x, attDim.y, sampleCount); + int2 UV = int2(input.UV * attDim); + + float3 fragColor; + uint status = 0; + + // Debug display + if (ubo.displayDebugTarget > 0) { + switch (ubo.displayDebugTarget) { + case 1: + fragColor.rgb = samplerPosition.Load(UV, 0, int2(0, 0), status).rgb; + break; + case 2: + fragColor.rgb = samplerNormal.Load(UV, 0, int2(0, 0), status).rgb; + break; + case 3: + fragColor.rgb = samplerAlbedo.Load(UV, 0, int2(0, 0), status).rgb; + break; + case 4: + fragColor.rgb = samplerAlbedo.Load(UV, 0, int2(0, 0), status).aaa; + break; + } + return float4(fragColor, 1.0); + } + +#define ambient 0.15 + + // Ambient part + float4 alb = resolve(samplerAlbedo, UV); + fragColor = float3(0.0, 0.0, 0.0); + + // Calualte lighting for every MSAA sample + for (int i = 0; i < NUM_SAMPLES; i++) + { + float3 pos = samplerPosition.Load(UV, i, int2(0, 0), status).rgb; + float3 normal = samplerNormal.Load(UV, i, int2(0, 0), status).rgb; + float4 albedo = samplerAlbedo.Load(UV, i, int2(0, 0), status); + fragColor += calculateLighting(pos, normal, albedo); + } + + fragColor = (alb.rgb * ambient) + fragColor / float(NUM_SAMPLES); + + return float4(fragColor, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/deferredmultisampling/mrt.slang b/shaders/slang/deferredmultisampling/mrt.slang new file mode 100644 index 00000000..146c4fd2 --- /dev/null +++ b/shaders/slang/deferredmultisampling/mrt.slang @@ -0,0 +1,83 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float2 UV; + float3 Color; + float3 Normal; + float3 Tangent; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float2 UV; + float3 Color; + float3 WorldPos; + float3 Tangent; +}; + +struct FSOutput +{ + float4 Position; + float4 Normal; + float4 Albedo; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; + float4 instancePos[3]; +}; +ConstantBuffer ubo; + +Sampler2D samplerColor; +Sampler2D samplerNormalMap; + +[shader("vertex")] +VSOutput vertexMain(VSInput input, uint InstanceIndex: SV_InstanceID) +{ + VSOutput output; + float4 tmpPos = input.Pos + ubo.instancePos[InstanceIndex]; + + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, tmpPos))); + + output.UV = input.UV; + + // Vertex position in world space + output.WorldPos = mul(ubo.model, tmpPos).xyz; + + // Normal in world space + output.Normal = normalize(input.Normal); + output.Tangent = normalize(input.Tangent); + + // Currently just vertex color + output.Color = input.Color; + return output; +} + +[shader("fragment")] +FSOutput fragmentMain(VSOutput input) +{ + FSOutput output; + output.Position = float4(input.WorldPos, 1.0); + + // Calculate normal in tangent space + float3 N = normalize(input.Normal); + float3 T = normalize(input.Tangent); + float3 B = cross(N, T); + float3x3 TBN = float3x3(T, B, N); + float3 tnorm = mul(normalize(samplerNormalMap.Sample(input.UV).xyz * 2.0 - float3(1.0, 1.0, 1.0)), TBN); + output.Normal = float4(tnorm, 1.0); + + output.Albedo = samplerColor.Sample(input.UV); + return output; +} \ No newline at end of file diff --git a/shaders/slang/subpasses/composition.slang b/shaders/slang/subpasses/composition.slang new file mode 100644 index 00000000..728f1452 --- /dev/null +++ b/shaders/slang/subpasses/composition.slang @@ -0,0 +1,66 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float2 UV; +}; + +[[vk::input_attachment_index(0)]] SubpassInput inputPosition; +[[vk::input_attachment_index(1)]] SubpassInput inputNormal; +[[vk::input_attachment_index(2)]] SubpassInput inputAlbedo; + +struct Light { + float4 position; + float3 color; + float radius; +}; +RWStructuredBuffer lights; + +[shader("vertex")] +VSOutput vertexMain(uint VertexIndex: SV_VertexID) +{ + VSOutput output; + output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} + +[shader("fragment")] +float4 fragmentMain() +{ + // Read G-Buffer values from previous sub pass + float3 fragPos = inputPosition.SubpassLoad().rgb; + float3 normal = inputNormal.SubpassLoad().rgb; + float4 albedo = inputAlbedo.SubpassLoad(); + + #define ambient 0.05 + + // Ambient part + float3 fragcolor = albedo.rgb * ambient; + + uint lightsLength; + uint lightsStride; + lights.GetDimensions(lightsLength, lightsStride); + + for(int i = 0; i < lightsLength; ++i) + { + float3 L = lights[i].position.xyz - fragPos; + float dist = length(L); + + L = normalize(L); + + float atten = lights[i].radius / (pow(dist, 3.0) + 1.0); + float3 N = normalize(normal); + float NdotL = max(0.0, dot(N, L)); + float3 diff = lights[i].color * albedo.rgb * NdotL * atten; + + fragcolor += diff; + } + + return float4(fragcolor, 1.0); +} \ No newline at end of file diff --git a/shaders/slang/subpasses/gbuffer.slang b/shaders/slang/subpasses/gbuffer.slang new file mode 100644 index 00000000..a648cb31 --- /dev/null +++ b/shaders/slang/subpasses/gbuffer.slang @@ -0,0 +1,78 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float3 Color; + float3 Normal; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Normal; + float3 Color; + float3 WorldPos; + float3 Tangent; +}; + +struct FSOutput +{ + float4 Color : SV_TARGET0; + float4 Position : SV_TARGET1; + float4 Normal : SV_TARGET2; + float4 Albedo : SV_TARGET3; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; +}; +ConstantBuffer ubo; + +[[SpecializationConstant]] const float NEAR_PLANE = 0.1; +[[SpecializationConstant]] const float FAR_PLANE = 256.0; + +float linearDepth(float depth) +{ + float z = depth * 2.0f - 1.0f; + return (2.0f * NEAR_PLANE * FAR_PLANE) / (FAR_PLANE + NEAR_PLANE - z * (FAR_PLANE - NEAR_PLANE)); +} + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, input.Pos))); + // Vertex position in world space + output.WorldPos = mul(ubo.model, input.Pos).xyz; + // GL to Vulkan coord space + output.WorldPos.y = -output.WorldPos.y; + // Normal in world space + output.Normal = mul((float3x3)ubo.model, normalize(input.Normal)); + // Currently just vertex color + output.Color = input.Color; + return output; +} + +[shader("fragment")] +FSOutput fragmentMain(VSOutput input) +{ + FSOutput output; + output.Position = float4(input.WorldPos, 1.0); + float3 N = normalize(input.Normal); + N.y = -N.y; + output.Normal = float4(N, 1.0); + output.Albedo.rgb = input.Color; + // Store linearized depth in alpha component + output.Position.a = linearDepth(input.Pos.z); + // Write color attachments to avoid undefined behaviour (validation error) + output.Color = float4(0.0); + return output; +} \ No newline at end of file diff --git a/shaders/slang/subpasses/transparent.slang b/shaders/slang/subpasses/transparent.slang new file mode 100644 index 00000000..846e5c6d --- /dev/null +++ b/shaders/slang/subpasses/transparent.slang @@ -0,0 +1,64 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +struct VSInput +{ + float4 Pos; + float3 Color; + float3 Normal; + float2 UV; +}; + +struct VSOutput +{ + float4 Pos : SV_POSITION; + float3 Color; + float2 UV; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4x4 view; +}; +ConstantBuffer ubo; + +[[vk::input_attachment_index(0)]] SubpassInput samplerPositionDepth; + +Sampler2D samplerTexture; + +[[SpecializationConstant]] const float NEAR_PLANE = 0.1f; +[[SpecializationConstant]] const float FAR_PLANE = 256.0f; + +float linearDepth(float depth) +{ + float z = depth * 2.0f - 1.0f; + return (2.0f * NEAR_PLANE * FAR_PLANE) / (FAR_PLANE + NEAR_PLANE - z * (FAR_PLANE - NEAR_PLANE)); +} + +[shader("vertex")] +VSOutput vertexMain(VSInput input) +{ + VSOutput output; + output.Color = input.Color; + output.UV = input.UV; + output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, float4(input.Pos.xyz, 1.0)))); + return output; +} + +[shader("fragment")] +float4 fragmentMain (VSOutput input) +{ + // Sample depth from deferred depth buffer and discard if obscured + float depth = samplerPositionDepth.SubpassLoad().a; + if ((depth != 0.0) && (linearDepth(input.Pos.z) > depth)) + { + clip(-1); + }; + + return samplerTexture.Sample(input.UV); +} From aca977186612b4e0dd12e837fb27252391d017aa Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 31 May 2025 13:59:46 +0200 Subject: [PATCH 69/73] Add note on compiling slang shaders --- shaders/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/shaders/README.md b/shaders/README.md index 4ddffc4a..cba13b69 100644 --- a/shaders/README.md +++ b/shaders/README.md @@ -4,4 +4,6 @@ This folder contains the shaders used by the samples. Source files are available Note that not all samples may come with all shading language variants. So some samples that have GLSL source files might not come with HLSL and/or slang source files. -A note for using **slang** shaders: These require a different SPIR-V environment than glsl/hlsl. When selecting slang shaders, the base requirement for all samples is raised to at least Vulkan 1.1 with the SPIRV 1.4 extension. \ No newline at end of file +A note for using **slang** shaders: These require a different SPIR-V environment than glsl/hlsl. When selecting slang shaders, the base requirement for all samples is raised to at least Vulkan 1.1 with the SPIRV 1.4 extension. + +If you want to compile **slang** shaders to SPIR-V, please use the latest release from [here](https://github.com/shader-slang/slang/releases) to get the latest bug fixes and features required for some of the samples. \ No newline at end of file From 5833d766a7217cd395251fa6c1672bc02c7e0612 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 31 May 2025 16:33:19 +0200 Subject: [PATCH 70/73] Clean up --- shaders/slang/computeparticles/particle.slang | 2 +- shaders/slang/descriptorindexing/descriptorindexing.slang | 2 +- shaders/slang/pushconstants/pushconstants.slang | 2 +- shaders/slang/specializationconstants/uber.slang | 2 +- shaders/slang/texturecubemap/reflect.slang | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/shaders/slang/computeparticles/particle.slang b/shaders/slang/computeparticles/particle.slang index c5959164..9eee978a 100644 --- a/shaders/slang/computeparticles/particle.slang +++ b/shaders/slang/computeparticles/particle.slang @@ -73,7 +73,7 @@ VSOutput vertexMain(VSInput input) } [shader("fragment")] -float4 fragmentMain(VSOutput input, float2 pointCoord: SV_PointCoord) : SV_TARGET +float4 fragmentMain(VSOutput input, float2 pointCoord: SV_PointCoord) { float3 color = samplerGradientRamp.Sample(float2(input.GradientPos, 0.0)).rgb; return float4(samplerColorMap.Sample(pointCoord).rgb * color, 1.0); diff --git a/shaders/slang/descriptorindexing/descriptorindexing.slang b/shaders/slang/descriptorindexing/descriptorindexing.slang index c647a2cd..5c25ea88 100644 --- a/shaders/slang/descriptorindexing/descriptorindexing.slang +++ b/shaders/slang/descriptorindexing/descriptorindexing.slang @@ -37,7 +37,7 @@ VSOutput vertexMain(VSInput input) } [shader("fragment")] -float4 fragmentMain(VSOutput input) : SV_TARGET +float4 fragmentMain(VSOutput input) { return textures[NonUniformResourceIndex(input.TextureIndex)].Sample(input.UV); } \ No newline at end of file diff --git a/shaders/slang/pushconstants/pushconstants.slang b/shaders/slang/pushconstants/pushconstants.slang index 45fb2960..8b318b88 100644 --- a/shaders/slang/pushconstants/pushconstants.slang +++ b/shaders/slang/pushconstants/pushconstants.slang @@ -38,7 +38,7 @@ VSOutput vertexMain(VSInput input, uniform float4 pushColor, uniform float4 push } [shader("fragment")] -float4 fragmentMain(VSOutput input) : SV_TARGET +float4 fragmentMain(VSOutput input) { return float4(input.Color, 1.0); } \ No newline at end of file diff --git a/shaders/slang/specializationconstants/uber.slang b/shaders/slang/specializationconstants/uber.slang index 1d7c1c3c..14fc8af5 100644 --- a/shaders/slang/specializationconstants/uber.slang +++ b/shaders/slang/specializationconstants/uber.slang @@ -57,7 +57,7 @@ VSOutput vertexMain(VSInput input) } [shader("fragment")] -float4 fragmentMain(VSOutput input) : SV_TARGET +float4 fragmentMain(VSOutput input) { switch (LIGHTING_MODEL) { case 0: // Phong diff --git a/shaders/slang/texturecubemap/reflect.slang b/shaders/slang/texturecubemap/reflect.slang index ffeda065..f938523b 100644 --- a/shaders/slang/texturecubemap/reflect.slang +++ b/shaders/slang/texturecubemap/reflect.slang @@ -48,7 +48,7 @@ VSOutput vertexMain(VSInput input) } [shader("fragment")] -float4 fragmentMain(VSOutput input) : SV_TARGET +float4 fragmentMain(VSOutput input) { float3 cI = normalize (input.ViewVec); float3 cR = reflect (cI, normalize(input.Normal)); From 09133076465bd29b5f13ef26a86ef6d936d8cc13 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Mon, 2 Jun 2025 12:52:36 +0200 Subject: [PATCH 71/73] Notes on supported shading languages --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c2355f24..85fc514e 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ Once built, examples can be run from the bin directory. The list of available co -vs, --vsync: Enable V-Sync -f, --fullscreen: Start in fullscreen mode -w, --width: Set window width - -s, --shaders: Select shader type to use (glsl, hlsl, slang) + -s, --shaders: Select shader type to use (glsl, slang, hlsl) -g, --gpu: Select GPU to run on -gl, --listgpus: Display a list of available Vulkan devices -b, --benchmark: Run example in benchmark mode @@ -83,7 +83,7 @@ Note that some examples require specific device features, and if you are on a mu ## Shaders -Vulkan consumes shaders in an intermediate representation called SPIR-V. This makes it possible to use different shader languages by compiling them to that bytecode format. The primary shader language used here is [GLSL](shaders/glsl), most samples also come with [HLSL](shaders/hlsl) and [slang](shaders/slang/) shader sources +Vulkan consumes shaders in an intermediate representation called SPIR-V. This makes it possible to use different shader languages by compiling them to that bytecode format. The primary shader language used here is [GLSL](shaders/glsl), most samples also come with [slang](shaders/slang/) and [HLSL](shaders/hlsl) shader sources, making it easy to compare the differences between those shading languages. ## A note on synchronization From 49c783419672e732f81b2e35833292199ae9b1e1 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Mon, 2 Jun 2025 22:09:03 +0200 Subject: [PATCH 72/73] Use slang's stdlib fn --- shaders/slang/hdr/gbuffer.slang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shaders/slang/hdr/gbuffer.slang b/shaders/slang/hdr/gbuffer.slang index 7743780d..ed0017a6 100644 --- a/shaders/slang/hdr/gbuffer.slang +++ b/shaders/slang/hdr/gbuffer.slang @@ -105,7 +105,7 @@ FSOutput fragmentMain(VSOutput input) fresnel *= (1.0 - F0); fresnel += F0; - float spec = (fresnel * geoAtt) / (NdotV * NdotL * 3.14); + float spec = (fresnel * geoAtt) / (NdotV * NdotL * float.getPi()); color = samplerEnvMap.Sample(reflect(-wViewVec, wNormal)); From 8a77f5fd1f063390a10e3868cd69a67dd43c33ae Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Tue, 3 Jun 2025 16:27:20 +0200 Subject: [PATCH 73/73] Added offline compiled slang shaders --- shaders/slang/base/uioverlay.frag.spv | Bin 0 -> 700 bytes shaders/slang/base/uioverlay.vert.spv | Bin 0 -> 1268 bytes shaders/slang/bloom/colorpass.frag.spv | Bin 0 -> 436 bytes shaders/slang/bloom/colorpass.vert.spv | Bin 0 -> 3096 bytes shaders/slang/bloom/gaussblur.frag.spv | Bin 0 -> 3708 bytes shaders/slang/bloom/gaussblur.vert.spv | Bin 0 -> 832 bytes shaders/slang/bloom/phongpass.frag.spv | Bin 0 -> 1752 bytes shaders/slang/bloom/phongpass.vert.spv | Bin 0 -> 6240 bytes shaders/slang/bloom/skybox.frag.spv | Bin 0 -> 596 bytes shaders/slang/bloom/skybox.vert.spv | Bin 0 -> 2864 bytes shaders/slang/bufferdeviceaddress/cube.frag.spv | Bin 0 -> 756 bytes shaders/slang/bufferdeviceaddress/cube.vert.spv | Bin 0 -> 3228 bytes shaders/slang/computecloth/cloth.comp.spv | Bin 0 -> 13140 bytes shaders/slang/computecloth/cloth.frag.spv | Bin 0 -> 1392 bytes shaders/slang/computecloth/cloth.vert.spv | Bin 0 -> 2996 bytes shaders/slang/computecloth/sphere.frag.spv | Bin 0 -> 1068 bytes shaders/slang/computecloth/sphere.vert.spv | Bin 0 -> 2756 bytes shaders/slang/computecullandlod/cull.comp.spv | Bin 0 -> 5992 bytes .../computecullandlod/indirectdraw.frag.spv | Bin 0 -> 828 bytes .../computecullandlod/indirectdraw.vert.spv | Bin 0 -> 3004 bytes shaders/slang/computeheadless/headless.comp.spv | Bin 0 -> 1556 bytes shaders/slang/computenbody/particle.frag.spv | Bin 0 -> 1356 bytes shaders/slang/computenbody/particle.vert.spv | Bin 0 -> 3792 bytes .../computenbody/particle_calculate.comp.spv | Bin 0 -> 4472 bytes .../computenbody/particle_integrate.comp.spv | Bin 0 -> 1320 bytes .../slang/computeparticles/particle.comp.spv | Bin 0 -> 3864 bytes .../slang/computeparticles/particle.frag.spv | Bin 0 -> 996 bytes .../slang/computeparticles/particle.vert.spv | Bin 0 -> 840 bytes .../slang/computeraytracing/raytracing.comp.spv | Bin 0 -> 19032 bytes .../slang/computeraytracing/texture.frag.spv | Bin 0 -> 692 bytes .../slang/computeraytracing/texture.vert.spv | Bin 0 -> 848 bytes shaders/slang/computeshader/edgedetect.comp.spv | Bin 0 -> 2964 bytes shaders/slang/computeshader/emboss.comp.spv | Bin 0 -> 2980 bytes shaders/slang/computeshader/sharpen.comp.spv | Bin 0 -> 4824 bytes shaders/slang/computeshader/texture.frag.spv | Bin 0 -> 596 bytes shaders/slang/computeshader/texture.vert.spv | Bin 0 -> 2292 bytes shaders/slang/conditionalrender/model.frag.spv | Bin 0 -> 1196 bytes shaders/slang/conditionalrender/model.vert.spv | Bin 0 -> 8224 bytes .../conservativeraster/fullscreen.frag.spv | Bin 0 -> 596 bytes .../conservativeraster/fullscreen.vert.spv | Bin 0 -> 832 bytes .../slang/conservativeraster/triangle.frag.spv | Bin 0 -> 436 bytes .../slang/conservativeraster/triangle.vert.spv | Bin 0 -> 2232 bytes .../conservativeraster/triangleoverlay.frag.spv | Bin 0 -> 340 bytes shaders/slang/debugprintf/toon.frag.spv | Bin 0 -> 1332 bytes shaders/slang/debugprintf/toon.vert.spv | Bin 0 -> 5224 bytes shaders/slang/debugutils/colorpass.frag.spv | Bin 0 -> 436 bytes shaders/slang/debugutils/colorpass.vert.spv | Bin 0 -> 2212 bytes shaders/slang/debugutils/postprocess.frag.spv | Bin 0 -> 1960 bytes shaders/slang/debugutils/postprocess.vert.spv | Bin 0 -> 868 bytes shaders/slang/debugutils/toon.frag.spv | Bin 0 -> 1332 bytes shaders/slang/debugutils/toon.vert.spv | Bin 0 -> 5052 bytes shaders/slang/deferred/deferred.frag.spv | Bin 0 -> 4320 bytes shaders/slang/deferred/deferred.vert.spv | Bin 0 -> 832 bytes shaders/slang/deferred/mrt.frag.spv | Bin 0 -> 1548 bytes shaders/slang/deferred/mrt.vert.spv | Bin 0 -> 4752 bytes .../deferredmultisampling/deferred.frag.spv | Bin 0 -> 6864 bytes .../deferredmultisampling/deferred.vert.spv | Bin 0 -> 832 bytes .../slang/deferredmultisampling/mrt.frag.spv | Bin 0 -> 1548 bytes .../slang/deferredmultisampling/mrt.vert.spv | Bin 0 -> 4752 bytes shaders/slang/deferredshadows/deferred.frag.spv | Bin 0 -> 12548 bytes shaders/slang/deferredshadows/deferred.vert.spv | Bin 0 -> 832 bytes shaders/slang/deferredshadows/mrt.frag.spv | Bin 0 -> 1548 bytes shaders/slang/deferredshadows/mrt.vert.spv | Bin 0 -> 4752 bytes shaders/slang/deferredshadows/shadow.geom.spv | Bin 0 -> 3184 bytes shaders/slang/deferredshadows/shadow.vert.spv | Bin 0 -> 656 bytes shaders/slang/descriptorbuffer/cube.frag.spv | Bin 0 -> 756 bytes shaders/slang/descriptorbuffer/cube.vert.spv | Bin 0 -> 3448 bytes .../descriptorindexing.frag.spv | Bin 0 -> 852 bytes .../descriptorindexing.vert.spv | Bin 0 -> 3188 bytes shaders/slang/descriptorsets/cube.frag.spv | Bin 0 -> 756 bytes shaders/slang/descriptorsets/cube.vert.spv | Bin 0 -> 3332 bytes shaders/slang/displacement/base.frag.spv | Bin 0 -> 1048 bytes shaders/slang/displacement/base.vert.spv | Bin 0 -> 804 bytes .../slang/displacement/displacement.tesc.spv | Bin 0 -> 3124 bytes .../slang/displacement/displacement.tese.spv | Bin 0 -> 4472 bytes .../slang/distancefieldfonts/bitmap.frag.spv | Bin 0 -> 632 bytes .../slang/distancefieldfonts/bitmap.vert.spv | Bin 0 -> 2292 bytes shaders/slang/distancefieldfonts/sdf.frag.spv | Bin 0 -> 2080 bytes shaders/slang/distancefieldfonts/sdf.vert.spv | Bin 0 -> 2440 bytes shaders/slang/dynamicrendering/texture.frag.spv | Bin 0 -> 1368 bytes shaders/slang/dynamicrendering/texture.vert.spv | Bin 0 -> 4600 bytes .../slang/dynamicuniformbuffer/base.frag.spv | Bin 0 -> 436 bytes .../slang/dynamicuniformbuffer/base.vert.spv | Bin 0 -> 3068 bytes shaders/slang/gears/gears.frag.spv | Bin 0 -> 1240 bytes shaders/slang/gears/gears.vert.spv | Bin 0 -> 4772 bytes shaders/slang/geometryshader/base.frag.spv | Bin 0 -> 436 bytes shaders/slang/geometryshader/base.vert.spv | Bin 0 -> 636 bytes shaders/slang/geometryshader/mesh.frag.spv | Bin 0 -> 1196 bytes shaders/slang/geometryshader/mesh.vert.spv | Bin 0 -> 4040 bytes .../slang/geometryshader/normaldebug.geom.spv | Bin 0 -> 4768 bytes shaders/slang/gltfloading/mesh.frag.spv | Bin 0 -> 1488 bytes shaders/slang/gltfloading/mesh.vert.spv | Bin 0 -> 5808 bytes shaders/slang/gltfscenerendering/scene.frag.spv | Bin 0 -> 2320 bytes shaders/slang/gltfscenerendering/scene.vert.spv | Bin 0 -> 5648 bytes .../slang/gltfskinning/skinnedmodel.frag.spv | Bin 0 -> 1488 bytes .../slang/gltfskinning/skinnedmodel.vert.spv | Bin 0 -> 9552 bytes .../graphicspipelinelibrary/shared.vert.spv | Bin 0 -> 4516 bytes .../slang/graphicspipelinelibrary/uber.frag.spv | Bin 0 -> 2500 bytes shaders/slang/hdr/bloom.frag.spv | Bin 0 -> 2632 bytes shaders/slang/hdr/bloom.vert.spv | Bin 0 -> 832 bytes shaders/slang/hdr/composition.frag.spv | Bin 0 -> 596 bytes shaders/slang/hdr/composition.vert.spv | Bin 0 -> 832 bytes shaders/slang/hdr/gbuffer.frag.spv | Bin 0 -> 6804 bytes shaders/slang/hdr/gbuffer.vert.spv | Bin 0 -> 5896 bytes shaders/slang/imgui/scene.frag.spv | Bin 0 -> 1080 bytes shaders/slang/imgui/scene.vert.spv | Bin 0 -> 4844 bytes shaders/slang/imgui/ui.frag.spv | Bin 0 -> 700 bytes shaders/slang/imgui/ui.vert.spv | Bin 0 -> 1140 bytes shaders/slang/indirectdraw/ground.frag.spv | Bin 0 -> 680 bytes shaders/slang/indirectdraw/ground.vert.spv | Bin 0 -> 2332 bytes .../slang/indirectdraw/indirectdraw.frag.spv | Bin 0 -> 1348 bytes .../slang/indirectdraw/indirectdraw.vert.spv | Bin 0 -> 4812 bytes shaders/slang/indirectdraw/skysphere.frag.spv | Bin 0 -> 776 bytes shaders/slang/indirectdraw/skysphere.vert.spv | Bin 0 -> 2248 bytes shaders/slang/inlineuniformblocks/pbr.frag.spv | Bin 0 -> 3524 bytes shaders/slang/inlineuniformblocks/pbr.vert.spv | Bin 0 -> 4052 bytes .../inputattachments/attachmentread.frag.spv | Bin 0 -> 2012 bytes .../inputattachments/attachmentread.vert.spv | Bin 0 -> 728 bytes .../inputattachments/attachmentwrite.frag.spv | Bin 0 -> 1332 bytes .../inputattachments/attachmentwrite.vert.spv | Bin 0 -> 3400 bytes shaders/slang/instancing/instancing.frag.spv | Bin 0 -> 1740 bytes shaders/slang/instancing/instancing.vert.spv | Bin 0 -> 7056 bytes shaders/slang/instancing/planet.frag.spv | Bin 0 -> 1580 bytes shaders/slang/instancing/planet.vert.spv | Bin 0 -> 4728 bytes shaders/slang/instancing/starfield.frag.spv | Bin 0 -> 1324 bytes shaders/slang/instancing/starfield.vert.spv | Bin 0 -> 872 bytes shaders/slang/meshshader/meshshader.frag.spv | Bin 0 -> 384 bytes shaders/slang/meshshader/meshshader.mesh.spv | Bin 0 -> 4088 bytes shaders/slang/meshshader/meshshader.task.spv | Bin 0 -> 396 bytes shaders/slang/multisampling/mesh.frag.spv | Bin 0 -> 1520 bytes shaders/slang/multisampling/mesh.vert.spv | Bin 0 -> 4076 bytes shaders/slang/multithreading/phong.frag.spv | Bin 0 -> 1096 bytes shaders/slang/multithreading/phong.vert.spv | Bin 0 -> 4044 bytes .../slang/multithreading/starsphere.frag.spv | Bin 0 -> 1588 bytes .../slang/multithreading/starsphere.vert.spv | Bin 0 -> 1500 bytes shaders/slang/multiview/multiview.frag.spv | Bin 0 -> 1196 bytes shaders/slang/multiview/multiview.vert.spv | Bin 0 -> 4356 bytes shaders/slang/multiview/viewdisplay.frag.spv | Bin 0 -> 2432 bytes shaders/slang/multiview/viewdisplay.vert.spv | Bin 0 -> 832 bytes .../slang/negativeviewportheight/quad.frag.spv | Bin 0 -> 596 bytes .../slang/negativeviewportheight/quad.vert.spv | Bin 0 -> 588 bytes shaders/slang/occlusionquery/mesh.frag.spv | Bin 0 -> 1436 bytes shaders/slang/occlusionquery/mesh.vert.spv | Bin 0 -> 5024 bytes shaders/slang/occlusionquery/occluder.frag.spv | Bin 0 -> 436 bytes shaders/slang/occlusionquery/occluder.vert.spv | Bin 0 -> 3104 bytes shaders/slang/occlusionquery/simple.frag.spv | Bin 0 -> 340 bytes shaders/slang/occlusionquery/simple.vert.spv | Bin 0 -> 2916 bytes shaders/slang/offscreen/mirror.frag.spv | Bin 0 -> 2396 bytes shaders/slang/offscreen/mirror.vert.spv | Bin 0 -> 2856 bytes shaders/slang/offscreen/phong.frag.spv | Bin 0 -> 1440 bytes shaders/slang/offscreen/phong.vert.spv | Bin 0 -> 4848 bytes shaders/slang/offscreen/quad.frag.spv | Bin 0 -> 596 bytes shaders/slang/offscreen/quad.vert.spv | Bin 0 -> 832 bytes shaders/slang/oit/color.frag.spv | Bin 0 -> 4232 bytes shaders/slang/oit/color.vert.spv | Bin 0 -> 740 bytes shaders/slang/oit/geometry.frag.spv | Bin 0 -> 2404 bytes shaders/slang/oit/geometry.vert.spv | Bin 0 -> 3080 bytes shaders/slang/parallaxmapping/parallax.frag.spv | Bin 0 -> 6084 bytes shaders/slang/parallaxmapping/parallax.vert.spv | Bin 0 -> 4592 bytes shaders/slang/particlesystem/normalmap.frag.spv | Bin 0 -> 1936 bytes shaders/slang/particlesystem/normalmap.vert.spv | Bin 0 -> 6304 bytes shaders/slang/particlesystem/particle.frag.spv | Bin 0 -> 2744 bytes shaders/slang/particlesystem/particle.vert.spv | Bin 0 -> 4912 bytes shaders/slang/pbrbasic/pbr.frag.spv | Bin 0 -> 4288 bytes shaders/slang/pbrbasic/pbr.vert.spv | Bin 0 -> 3896 bytes shaders/slang/pbribl/filtercube.vert.spv | Bin 0 -> 1500 bytes shaders/slang/pbribl/genbrdflut.frag.spv | Bin 0 -> 3856 bytes shaders/slang/pbribl/genbrdflut.vert.spv | Bin 0 -> 832 bytes shaders/slang/pbribl/irradiancecube.frag.spv | Bin 0 -> 2820 bytes shaders/slang/pbribl/pbribl.frag.spv | Bin 0 -> 6784 bytes shaders/slang/pbribl/pbribl.vert.spv | Bin 0 -> 4168 bytes shaders/slang/pbribl/prefilterenvmap.frag.spv | Bin 0 -> 5060 bytes shaders/slang/pbribl/skybox.frag.spv | Bin 0 -> 1856 bytes shaders/slang/pbribl/skybox.vert.spv | Bin 0 -> 2188 bytes shaders/slang/pbrtexture/filtercube.vert.spv | Bin 0 -> 1500 bytes shaders/slang/pbrtexture/genbrdflut.frag.spv | Bin 0 -> 3856 bytes shaders/slang/pbrtexture/genbrdflut.vert.spv | Bin 0 -> 832 bytes .../slang/pbrtexture/irradiancecube.frag.spv | Bin 0 -> 2780 bytes shaders/slang/pbrtexture/pbrtexture.frag.spv | Bin 0 -> 7500 bytes shaders/slang/pbrtexture/pbrtexture.vert.spv | Bin 0 -> 4608 bytes .../slang/pbrtexture/prefilterenvmap.frag.spv | Bin 0 -> 5060 bytes shaders/slang/pbrtexture/skybox.frag.spv | Bin 0 -> 1856 bytes shaders/slang/pbrtexture/skybox.vert.spv | Bin 0 -> 2188 bytes shaders/slang/pipelines/phong.frag.spv | Bin 0 -> 1340 bytes shaders/slang/pipelines/phong.vert.spv | Bin 0 -> 4516 bytes shaders/slang/pipelines/toon.frag.spv | Bin 0 -> 1332 bytes shaders/slang/pipelines/toon.vert.spv | Bin 0 -> 4516 bytes shaders/slang/pipelines/wireframe.frag.spv | Bin 0 -> 472 bytes shaders/slang/pipelines/wireframe.vert.spv | Bin 0 -> 2212 bytes shaders/slang/pipelinestatistics/scene.frag.spv | Bin 0 -> 1096 bytes shaders/slang/pipelinestatistics/scene.tesc.spv | Bin 0 -> 3120 bytes shaders/slang/pipelinestatistics/scene.tese.spv | Bin 0 -> 2132 bytes shaders/slang/pipelinestatistics/scene.vert.spv | Bin 0 -> 4240 bytes .../slang/pushconstants/pushconstants.frag.spv | Bin 0 -> 436 bytes .../slang/pushconstants/pushconstants.vert.spv | Bin 0 -> 3468 bytes shaders/slang/pushdescriptors/cube.frag.spv | Bin 0 -> 756 bytes shaders/slang/pushdescriptors/cube.vert.spv | Bin 0 -> 3448 bytes shaders/slang/radialblur/colorpass.frag.spv | Bin 0 -> 1356 bytes shaders/slang/radialblur/colorpass.vert.spv | Bin 0 -> 2504 bytes shaders/slang/radialblur/phongpass.frag.spv | Bin 0 -> 2164 bytes shaders/slang/radialblur/phongpass.vert.spv | Bin 0 -> 3604 bytes shaders/slang/radialblur/radialblur.frag.spv | Bin 0 -> 2596 bytes shaders/slang/radialblur/radialblur.vert.spv | Bin 0 -> 832 bytes shaders/slang/rayquery/scene.frag.spv | Bin 0 -> 1480 bytes shaders/slang/rayquery/scene.vert.spv | Bin 0 -> 5564 bytes .../slang/raytracingbasic/closesthit.rchit.spv | Bin 0 -> 668 bytes shaders/slang/raytracingbasic/miss.rmiss.spv | Bin 0 -> 432 bytes shaders/slang/raytracingbasic/raygen.rgen.spv | Bin 0 -> 3924 bytes .../raytracingcallable/callable1.rcall.spv | Bin 0 -> 616 bytes .../raytracingcallable/callable2.rcall.spv | Bin 0 -> 316 bytes .../raytracingcallable/callable3.rcall.spv | Bin 0 -> 504 bytes .../raytracingcallable/closesthit.rchit.spv | Bin 0 -> 652 bytes shaders/slang/raytracingcallable/miss.rmiss.spv | Bin 0 -> 432 bytes .../slang/raytracingcallable/raygen.rgen.spv | Bin 0 -> 3924 bytes shaders/slang/raytracinggltf/anyhit.rahit.spv | Bin 0 -> 4072 bytes .../slang/raytracinggltf/closesthit.rchit.spv | Bin 0 -> 4460 bytes shaders/slang/raytracinggltf/miss.rmiss.spv | Bin 0 -> 496 bytes shaders/slang/raytracinggltf/raygen.rgen.spv | Bin 0 -> 7932 bytes shaders/slang/raytracinggltf/shadow.rmiss.spv | Bin 0 -> 468 bytes .../raytracingintersection/closesthit.rchit.spv | Bin 0 -> 1996 bytes .../intersection.rint.spv | Bin 0 -> 1656 bytes .../slang/raytracingintersection/miss.rmiss.spv | Bin 0 -> 432 bytes .../raytracingintersection/raygen.rgen.spv | Bin 0 -> 3960 bytes .../closesthit.rchit.spv | Bin 0 -> 2256 bytes .../raytracingpositionfetch/miss.rmiss.spv | Bin 0 -> 432 bytes .../raytracingpositionfetch/raygen.rgen.spv | Bin 0 -> 3960 bytes .../raytracingreflections/closesthit.rchit.spv | Bin 0 -> 4360 bytes .../slang/raytracingreflections/miss.rmiss.spv | Bin 0 -> 1016 bytes .../slang/raytracingreflections/raygen.rgen.spv | Bin 0 -> 5264 bytes .../raytracingsbtdata/closesthit.rchit.spv | Bin 0 -> 732 bytes shaders/slang/raytracingsbtdata/miss.rmiss.spv | Bin 0 -> 728 bytes shaders/slang/raytracingsbtdata/raygen.rgen.spv | Bin 0 -> 5220 bytes .../raytracingshadows/closesthit.rchit.spv | Bin 0 -> 4216 bytes shaders/slang/raytracingshadows/miss.rmiss.spv | Bin 0 -> 468 bytes shaders/slang/raytracingshadows/raygen.rgen.spv | Bin 0 -> 4044 bytes .../slang/raytracingshadows/shadow.rmiss.spv | Bin 0 -> 424 bytes .../slang/raytracingtextures/anyhit.rahit.spv | Bin 0 -> 2888 bytes .../raytracingtextures/closesthit.rchit.spv | Bin 0 -> 2956 bytes shaders/slang/raytracingtextures/miss.rmiss.spv | Bin 0 -> 432 bytes .../slang/raytracingtextures/raygen.rgen.spv | Bin 0 -> 3912 bytes shaders/slang/renderheadless/triangle.frag.spv | Bin 0 -> 436 bytes shaders/slang/renderheadless/triangle.vert.spv | Bin 0 -> 1576 bytes shaders/slang/screenshot/mesh.frag.spv | Bin 0 -> 1160 bytes shaders/slang/screenshot/mesh.vert.spv | Bin 0 -> 4564 bytes shaders/slang/shaderobjects/phong.frag.spv | Bin 0 -> 1340 bytes shaders/slang/shaderobjects/phong.vert.spv | Bin 0 -> 4840 bytes shaders/slang/shadowmapping/offscreen.frag.spv | Bin 0 -> 356 bytes shaders/slang/shadowmapping/offscreen.vert.spv | Bin 0 -> 1368 bytes shaders/slang/shadowmapping/quad.frag.spv | Bin 0 -> 1588 bytes shaders/slang/shadowmapping/quad.vert.spv | Bin 0 -> 832 bytes shaders/slang/shadowmapping/scene.frag.spv | Bin 0 -> 4248 bytes shaders/slang/shadowmapping/scene.vert.spv | Bin 0 -> 6356 bytes .../debugshadowmap.frag.spv | Bin 0 -> 1068 bytes .../debugshadowmap.vert.spv | Bin 0 -> 832 bytes .../shadowmappingcascade/depthpass.frag.spv | Bin 0 -> 716 bytes .../shadowmappingcascade/depthpass.vert.spv | Bin 0 -> 2212 bytes .../slang/shadowmappingcascade/scene.frag.spv | Bin 0 -> 9196 bytes .../slang/shadowmappingcascade/scene.vert.spv | Bin 0 -> 4424 bytes .../shadowmappingomni/cubemapdisplay.frag.spv | Bin 0 -> 3216 bytes .../shadowmappingomni/cubemapdisplay.vert.spv | Bin 0 -> 832 bytes .../slang/shadowmappingomni/offscreen.frag.spv | Bin 0 -> 616 bytes .../slang/shadowmappingomni/offscreen.vert.spv | Bin 0 -> 3336 bytes shaders/slang/shadowmappingomni/scene.frag.spv | Bin 0 -> 1804 bytes shaders/slang/shadowmappingomni/scene.vert.spv | Bin 0 -> 4388 bytes .../slang/specializationconstants/uber.frag.spv | Bin 0 -> 3648 bytes .../slang/specializationconstants/uber.vert.spv | Bin 0 -> 4724 bytes shaders/slang/sphericalenvmapping/sem.frag.spv | Bin 0 -> 1472 bytes shaders/slang/sphericalenvmapping/sem.vert.spv | Bin 0 -> 4088 bytes shaders/slang/ssao/blur.frag.spv | Bin 0 -> 2396 bytes shaders/slang/ssao/composition.frag.spv | Bin 0 -> 3372 bytes shaders/slang/ssao/fullscreen.vert.spv | Bin 0 -> 832 bytes shaders/slang/ssao/gbuffer.frag.spv | Bin 0 -> 2396 bytes shaders/slang/ssao/gbuffer.vert.spv | Bin 0 -> 6064 bytes shaders/slang/ssao/ssao.frag.spv | Bin 0 -> 5644 bytes shaders/slang/stencilbuffer/outline.frag.spv | Bin 0 -> 340 bytes shaders/slang/stencilbuffer/outline.vert.spv | Bin 0 -> 2400 bytes shaders/slang/stencilbuffer/toon.frag.spv | Bin 0 -> 1624 bytes shaders/slang/stencilbuffer/toon.vert.spv | Bin 0 -> 4376 bytes shaders/slang/subpasses/composition.frag.spv | Bin 0 -> 2668 bytes shaders/slang/subpasses/composition.vert.spv | Bin 0 -> 832 bytes shaders/slang/subpasses/gbuffer.frag.spv | Bin 0 -> 1648 bytes shaders/slang/subpasses/gbuffer.vert.spv | Bin 0 -> 4572 bytes shaders/slang/subpasses/transparent.frag.spv | Bin 0 -> 1668 bytes shaders/slang/subpasses/transparent.vert.spv | Bin 0 -> 3164 bytes .../terraintessellation/skysphere.frag.spv | Bin 0 -> 596 bytes .../terraintessellation/skysphere.vert.spv | Bin 0 -> 1576 bytes .../slang/terraintessellation/terrain.frag.spv | Bin 0 -> 3256 bytes .../slang/terraintessellation/terrain.tesc.spv | Bin 0 -> 15940 bytes .../slang/terraintessellation/terrain.tese.spv | Bin 0 -> 5580 bytes .../slang/terraintessellation/terrain.vert.spv | Bin 0 -> 804 bytes shaders/slang/tessellation/base.frag.spv | Bin 0 -> 1068 bytes shaders/slang/tessellation/base.vert.spv | Bin 0 -> 804 bytes shaders/slang/tessellation/passthrough.tesc.spv | Bin 0 -> 2468 bytes shaders/slang/tessellation/passthrough.tese.spv | Bin 0 -> 3396 bytes shaders/slang/tessellation/pntriangles.tesc.spv | Bin 0 -> 6032 bytes shaders/slang/tessellation/pntriangles.tese.spv | Bin 0 -> 6380 bytes shaders/slang/textoverlay/mesh.frag.spv | Bin 0 -> 952 bytes shaders/slang/textoverlay/mesh.vert.spv | Bin 0 -> 4608 bytes shaders/slang/textoverlay/text.frag.spv | Bin 0 -> 656 bytes shaders/slang/textoverlay/text.vert.spv | Bin 0 -> 576 bytes shaders/slang/texture/texture.frag.spv | Bin 0 -> 1464 bytes shaders/slang/texture/texture.vert.spv | Bin 0 -> 4820 bytes shaders/slang/texture3d/texture3d.frag.spv | Bin 0 -> 1304 bytes shaders/slang/texture3d/texture3d.vert.spv | Bin 0 -> 4716 bytes shaders/slang/texturearray/instancing.frag.spv | Bin 0 -> 596 bytes shaders/slang/texturearray/instancing.vert.spv | Bin 0 -> 3556 bytes shaders/slang/texturecubemap/reflect.frag.spv | Bin 0 -> 2704 bytes shaders/slang/texturecubemap/reflect.vert.spv | Bin 0 -> 4148 bytes shaders/slang/texturecubemap/skybox.frag.spv | Bin 0 -> 596 bytes shaders/slang/texturecubemap/skybox.vert.spv | Bin 0 -> 2684 bytes .../slang/texturecubemaparray/reflect.frag.spv | Bin 0 -> 3056 bytes .../slang/texturecubemaparray/reflect.vert.spv | Bin 0 -> 4024 bytes .../slang/texturecubemaparray/skybox.frag.spv | Bin 0 -> 1280 bytes .../slang/texturecubemaparray/skybox.vert.spv | Bin 0 -> 2828 bytes shaders/slang/texturemipmapgen/texture.frag.spv | Bin 0 -> 2384 bytes shaders/slang/texturemipmapgen/texture.vert.spv | Bin 0 -> 5104 bytes .../sparseresidency.frag.spv | Bin 0 -> 1156 bytes .../sparseresidency.vert.spv | Bin 0 -> 2556 bytes shaders/slang/triangle/triangle.frag.spv | Bin 0 -> 436 bytes shaders/slang/triangle/triangle.vert.spv | Bin 0 -> 2956 bytes .../slang/variablerateshading/scene.frag.spv | Bin 0 -> 4148 bytes .../slang/variablerateshading/scene.vert.spv | Bin 0 -> 5236 bytes shaders/slang/vertexattributes/scene.frag.spv | Bin 0 -> 2700 bytes shaders/slang/vertexattributes/scene.vert.spv | Bin 0 -> 5484 bytes shaders/slang/viewportarray/multiview.geom.spv | Bin 0 -> 5644 bytes shaders/slang/viewportarray/scene.frag.spv | Bin 0 -> 1196 bytes shaders/slang/viewportarray/scene.vert.spv | Bin 0 -> 760 bytes shaders/slang/vulkanscene/logo.frag.spv | Bin 0 -> 764 bytes shaders/slang/vulkanscene/logo.vert.spv | Bin 0 -> 4428 bytes shaders/slang/vulkanscene/mesh.frag.spv | Bin 0 -> 2224 bytes shaders/slang/vulkanscene/mesh.vert.spv | Bin 0 -> 4440 bytes shaders/slang/vulkanscene/skybox.frag.spv | Bin 0 -> 596 bytes shaders/slang/vulkanscene/skybox.vert.spv | Bin 0 -> 3220 bytes 333 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 shaders/slang/base/uioverlay.frag.spv create mode 100644 shaders/slang/base/uioverlay.vert.spv create mode 100644 shaders/slang/bloom/colorpass.frag.spv create mode 100644 shaders/slang/bloom/colorpass.vert.spv create mode 100644 shaders/slang/bloom/gaussblur.frag.spv create mode 100644 shaders/slang/bloom/gaussblur.vert.spv create mode 100644 shaders/slang/bloom/phongpass.frag.spv create mode 100644 shaders/slang/bloom/phongpass.vert.spv create mode 100644 shaders/slang/bloom/skybox.frag.spv create mode 100644 shaders/slang/bloom/skybox.vert.spv create mode 100644 shaders/slang/bufferdeviceaddress/cube.frag.spv create mode 100644 shaders/slang/bufferdeviceaddress/cube.vert.spv create mode 100644 shaders/slang/computecloth/cloth.comp.spv create mode 100644 shaders/slang/computecloth/cloth.frag.spv create mode 100644 shaders/slang/computecloth/cloth.vert.spv create mode 100644 shaders/slang/computecloth/sphere.frag.spv create mode 100644 shaders/slang/computecloth/sphere.vert.spv create mode 100644 shaders/slang/computecullandlod/cull.comp.spv create mode 100644 shaders/slang/computecullandlod/indirectdraw.frag.spv create mode 100644 shaders/slang/computecullandlod/indirectdraw.vert.spv create mode 100644 shaders/slang/computeheadless/headless.comp.spv create mode 100644 shaders/slang/computenbody/particle.frag.spv create mode 100644 shaders/slang/computenbody/particle.vert.spv create mode 100644 shaders/slang/computenbody/particle_calculate.comp.spv create mode 100644 shaders/slang/computenbody/particle_integrate.comp.spv create mode 100644 shaders/slang/computeparticles/particle.comp.spv create mode 100644 shaders/slang/computeparticles/particle.frag.spv create mode 100644 shaders/slang/computeparticles/particle.vert.spv create mode 100644 shaders/slang/computeraytracing/raytracing.comp.spv create mode 100644 shaders/slang/computeraytracing/texture.frag.spv create mode 100644 shaders/slang/computeraytracing/texture.vert.spv create mode 100644 shaders/slang/computeshader/edgedetect.comp.spv create mode 100644 shaders/slang/computeshader/emboss.comp.spv create mode 100644 shaders/slang/computeshader/sharpen.comp.spv create mode 100644 shaders/slang/computeshader/texture.frag.spv create mode 100644 shaders/slang/computeshader/texture.vert.spv create mode 100644 shaders/slang/conditionalrender/model.frag.spv create mode 100644 shaders/slang/conditionalrender/model.vert.spv create mode 100644 shaders/slang/conservativeraster/fullscreen.frag.spv create mode 100644 shaders/slang/conservativeraster/fullscreen.vert.spv create mode 100644 shaders/slang/conservativeraster/triangle.frag.spv create mode 100644 shaders/slang/conservativeraster/triangle.vert.spv create mode 100644 shaders/slang/conservativeraster/triangleoverlay.frag.spv create mode 100644 shaders/slang/debugprintf/toon.frag.spv create mode 100644 shaders/slang/debugprintf/toon.vert.spv create mode 100644 shaders/slang/debugutils/colorpass.frag.spv create mode 100644 shaders/slang/debugutils/colorpass.vert.spv create mode 100644 shaders/slang/debugutils/postprocess.frag.spv create mode 100644 shaders/slang/debugutils/postprocess.vert.spv create mode 100644 shaders/slang/debugutils/toon.frag.spv create mode 100644 shaders/slang/debugutils/toon.vert.spv create mode 100644 shaders/slang/deferred/deferred.frag.spv create mode 100644 shaders/slang/deferred/deferred.vert.spv create mode 100644 shaders/slang/deferred/mrt.frag.spv create mode 100644 shaders/slang/deferred/mrt.vert.spv create mode 100644 shaders/slang/deferredmultisampling/deferred.frag.spv create mode 100644 shaders/slang/deferredmultisampling/deferred.vert.spv create mode 100644 shaders/slang/deferredmultisampling/mrt.frag.spv create mode 100644 shaders/slang/deferredmultisampling/mrt.vert.spv create mode 100644 shaders/slang/deferredshadows/deferred.frag.spv create mode 100644 shaders/slang/deferredshadows/deferred.vert.spv create mode 100644 shaders/slang/deferredshadows/mrt.frag.spv create mode 100644 shaders/slang/deferredshadows/mrt.vert.spv create mode 100644 shaders/slang/deferredshadows/shadow.geom.spv create mode 100644 shaders/slang/deferredshadows/shadow.vert.spv create mode 100644 shaders/slang/descriptorbuffer/cube.frag.spv create mode 100644 shaders/slang/descriptorbuffer/cube.vert.spv create mode 100644 shaders/slang/descriptorindexing/descriptorindexing.frag.spv create mode 100644 shaders/slang/descriptorindexing/descriptorindexing.vert.spv create mode 100644 shaders/slang/descriptorsets/cube.frag.spv create mode 100644 shaders/slang/descriptorsets/cube.vert.spv create mode 100644 shaders/slang/displacement/base.frag.spv create mode 100644 shaders/slang/displacement/base.vert.spv create mode 100644 shaders/slang/displacement/displacement.tesc.spv create mode 100644 shaders/slang/displacement/displacement.tese.spv create mode 100644 shaders/slang/distancefieldfonts/bitmap.frag.spv create mode 100644 shaders/slang/distancefieldfonts/bitmap.vert.spv create mode 100644 shaders/slang/distancefieldfonts/sdf.frag.spv create mode 100644 shaders/slang/distancefieldfonts/sdf.vert.spv create mode 100644 shaders/slang/dynamicrendering/texture.frag.spv create mode 100644 shaders/slang/dynamicrendering/texture.vert.spv create mode 100644 shaders/slang/dynamicuniformbuffer/base.frag.spv create mode 100644 shaders/slang/dynamicuniformbuffer/base.vert.spv create mode 100644 shaders/slang/gears/gears.frag.spv create mode 100644 shaders/slang/gears/gears.vert.spv create mode 100644 shaders/slang/geometryshader/base.frag.spv create mode 100644 shaders/slang/geometryshader/base.vert.spv create mode 100644 shaders/slang/geometryshader/mesh.frag.spv create mode 100644 shaders/slang/geometryshader/mesh.vert.spv create mode 100644 shaders/slang/geometryshader/normaldebug.geom.spv create mode 100644 shaders/slang/gltfloading/mesh.frag.spv create mode 100644 shaders/slang/gltfloading/mesh.vert.spv create mode 100644 shaders/slang/gltfscenerendering/scene.frag.spv create mode 100644 shaders/slang/gltfscenerendering/scene.vert.spv create mode 100644 shaders/slang/gltfskinning/skinnedmodel.frag.spv create mode 100644 shaders/slang/gltfskinning/skinnedmodel.vert.spv create mode 100644 shaders/slang/graphicspipelinelibrary/shared.vert.spv create mode 100644 shaders/slang/graphicspipelinelibrary/uber.frag.spv create mode 100644 shaders/slang/hdr/bloom.frag.spv create mode 100644 shaders/slang/hdr/bloom.vert.spv create mode 100644 shaders/slang/hdr/composition.frag.spv create mode 100644 shaders/slang/hdr/composition.vert.spv create mode 100644 shaders/slang/hdr/gbuffer.frag.spv create mode 100644 shaders/slang/hdr/gbuffer.vert.spv create mode 100644 shaders/slang/imgui/scene.frag.spv create mode 100644 shaders/slang/imgui/scene.vert.spv create mode 100644 shaders/slang/imgui/ui.frag.spv create mode 100644 shaders/slang/imgui/ui.vert.spv create mode 100644 shaders/slang/indirectdraw/ground.frag.spv create mode 100644 shaders/slang/indirectdraw/ground.vert.spv create mode 100644 shaders/slang/indirectdraw/indirectdraw.frag.spv create mode 100644 shaders/slang/indirectdraw/indirectdraw.vert.spv create mode 100644 shaders/slang/indirectdraw/skysphere.frag.spv create mode 100644 shaders/slang/indirectdraw/skysphere.vert.spv create mode 100644 shaders/slang/inlineuniformblocks/pbr.frag.spv create mode 100644 shaders/slang/inlineuniformblocks/pbr.vert.spv create mode 100644 shaders/slang/inputattachments/attachmentread.frag.spv create mode 100644 shaders/slang/inputattachments/attachmentread.vert.spv create mode 100644 shaders/slang/inputattachments/attachmentwrite.frag.spv create mode 100644 shaders/slang/inputattachments/attachmentwrite.vert.spv create mode 100644 shaders/slang/instancing/instancing.frag.spv create mode 100644 shaders/slang/instancing/instancing.vert.spv create mode 100644 shaders/slang/instancing/planet.frag.spv create mode 100644 shaders/slang/instancing/planet.vert.spv create mode 100644 shaders/slang/instancing/starfield.frag.spv create mode 100644 shaders/slang/instancing/starfield.vert.spv create mode 100644 shaders/slang/meshshader/meshshader.frag.spv create mode 100644 shaders/slang/meshshader/meshshader.mesh.spv create mode 100644 shaders/slang/meshshader/meshshader.task.spv create mode 100644 shaders/slang/multisampling/mesh.frag.spv create mode 100644 shaders/slang/multisampling/mesh.vert.spv create mode 100644 shaders/slang/multithreading/phong.frag.spv create mode 100644 shaders/slang/multithreading/phong.vert.spv create mode 100644 shaders/slang/multithreading/starsphere.frag.spv create mode 100644 shaders/slang/multithreading/starsphere.vert.spv create mode 100644 shaders/slang/multiview/multiview.frag.spv create mode 100644 shaders/slang/multiview/multiview.vert.spv create mode 100644 shaders/slang/multiview/viewdisplay.frag.spv create mode 100644 shaders/slang/multiview/viewdisplay.vert.spv create mode 100644 shaders/slang/negativeviewportheight/quad.frag.spv create mode 100644 shaders/slang/negativeviewportheight/quad.vert.spv create mode 100644 shaders/slang/occlusionquery/mesh.frag.spv create mode 100644 shaders/slang/occlusionquery/mesh.vert.spv create mode 100644 shaders/slang/occlusionquery/occluder.frag.spv create mode 100644 shaders/slang/occlusionquery/occluder.vert.spv create mode 100644 shaders/slang/occlusionquery/simple.frag.spv create mode 100644 shaders/slang/occlusionquery/simple.vert.spv create mode 100644 shaders/slang/offscreen/mirror.frag.spv create mode 100644 shaders/slang/offscreen/mirror.vert.spv create mode 100644 shaders/slang/offscreen/phong.frag.spv create mode 100644 shaders/slang/offscreen/phong.vert.spv create mode 100644 shaders/slang/offscreen/quad.frag.spv create mode 100644 shaders/slang/offscreen/quad.vert.spv create mode 100644 shaders/slang/oit/color.frag.spv create mode 100644 shaders/slang/oit/color.vert.spv create mode 100644 shaders/slang/oit/geometry.frag.spv create mode 100644 shaders/slang/oit/geometry.vert.spv create mode 100644 shaders/slang/parallaxmapping/parallax.frag.spv create mode 100644 shaders/slang/parallaxmapping/parallax.vert.spv create mode 100644 shaders/slang/particlesystem/normalmap.frag.spv create mode 100644 shaders/slang/particlesystem/normalmap.vert.spv create mode 100644 shaders/slang/particlesystem/particle.frag.spv create mode 100644 shaders/slang/particlesystem/particle.vert.spv create mode 100644 shaders/slang/pbrbasic/pbr.frag.spv create mode 100644 shaders/slang/pbrbasic/pbr.vert.spv create mode 100644 shaders/slang/pbribl/filtercube.vert.spv create mode 100644 shaders/slang/pbribl/genbrdflut.frag.spv create mode 100644 shaders/slang/pbribl/genbrdflut.vert.spv create mode 100644 shaders/slang/pbribl/irradiancecube.frag.spv create mode 100644 shaders/slang/pbribl/pbribl.frag.spv create mode 100644 shaders/slang/pbribl/pbribl.vert.spv create mode 100644 shaders/slang/pbribl/prefilterenvmap.frag.spv create mode 100644 shaders/slang/pbribl/skybox.frag.spv create mode 100644 shaders/slang/pbribl/skybox.vert.spv create mode 100644 shaders/slang/pbrtexture/filtercube.vert.spv create mode 100644 shaders/slang/pbrtexture/genbrdflut.frag.spv create mode 100644 shaders/slang/pbrtexture/genbrdflut.vert.spv create mode 100644 shaders/slang/pbrtexture/irradiancecube.frag.spv create mode 100644 shaders/slang/pbrtexture/pbrtexture.frag.spv create mode 100644 shaders/slang/pbrtexture/pbrtexture.vert.spv create mode 100644 shaders/slang/pbrtexture/prefilterenvmap.frag.spv create mode 100644 shaders/slang/pbrtexture/skybox.frag.spv create mode 100644 shaders/slang/pbrtexture/skybox.vert.spv create mode 100644 shaders/slang/pipelines/phong.frag.spv create mode 100644 shaders/slang/pipelines/phong.vert.spv create mode 100644 shaders/slang/pipelines/toon.frag.spv create mode 100644 shaders/slang/pipelines/toon.vert.spv create mode 100644 shaders/slang/pipelines/wireframe.frag.spv create mode 100644 shaders/slang/pipelines/wireframe.vert.spv create mode 100644 shaders/slang/pipelinestatistics/scene.frag.spv create mode 100644 shaders/slang/pipelinestatistics/scene.tesc.spv create mode 100644 shaders/slang/pipelinestatistics/scene.tese.spv create mode 100644 shaders/slang/pipelinestatistics/scene.vert.spv create mode 100644 shaders/slang/pushconstants/pushconstants.frag.spv create mode 100644 shaders/slang/pushconstants/pushconstants.vert.spv create mode 100644 shaders/slang/pushdescriptors/cube.frag.spv create mode 100644 shaders/slang/pushdescriptors/cube.vert.spv create mode 100644 shaders/slang/radialblur/colorpass.frag.spv create mode 100644 shaders/slang/radialblur/colorpass.vert.spv create mode 100644 shaders/slang/radialblur/phongpass.frag.spv create mode 100644 shaders/slang/radialblur/phongpass.vert.spv create mode 100644 shaders/slang/radialblur/radialblur.frag.spv create mode 100644 shaders/slang/radialblur/radialblur.vert.spv create mode 100644 shaders/slang/rayquery/scene.frag.spv create mode 100644 shaders/slang/rayquery/scene.vert.spv create mode 100644 shaders/slang/raytracingbasic/closesthit.rchit.spv create mode 100644 shaders/slang/raytracingbasic/miss.rmiss.spv create mode 100644 shaders/slang/raytracingbasic/raygen.rgen.spv create mode 100644 shaders/slang/raytracingcallable/callable1.rcall.spv create mode 100644 shaders/slang/raytracingcallable/callable2.rcall.spv create mode 100644 shaders/slang/raytracingcallable/callable3.rcall.spv create mode 100644 shaders/slang/raytracingcallable/closesthit.rchit.spv create mode 100644 shaders/slang/raytracingcallable/miss.rmiss.spv create mode 100644 shaders/slang/raytracingcallable/raygen.rgen.spv create mode 100644 shaders/slang/raytracinggltf/anyhit.rahit.spv create mode 100644 shaders/slang/raytracinggltf/closesthit.rchit.spv create mode 100644 shaders/slang/raytracinggltf/miss.rmiss.spv create mode 100644 shaders/slang/raytracinggltf/raygen.rgen.spv create mode 100644 shaders/slang/raytracinggltf/shadow.rmiss.spv create mode 100644 shaders/slang/raytracingintersection/closesthit.rchit.spv create mode 100644 shaders/slang/raytracingintersection/intersection.rint.spv create mode 100644 shaders/slang/raytracingintersection/miss.rmiss.spv create mode 100644 shaders/slang/raytracingintersection/raygen.rgen.spv create mode 100644 shaders/slang/raytracingpositionfetch/closesthit.rchit.spv create mode 100644 shaders/slang/raytracingpositionfetch/miss.rmiss.spv create mode 100644 shaders/slang/raytracingpositionfetch/raygen.rgen.spv create mode 100644 shaders/slang/raytracingreflections/closesthit.rchit.spv create mode 100644 shaders/slang/raytracingreflections/miss.rmiss.spv create mode 100644 shaders/slang/raytracingreflections/raygen.rgen.spv create mode 100644 shaders/slang/raytracingsbtdata/closesthit.rchit.spv create mode 100644 shaders/slang/raytracingsbtdata/miss.rmiss.spv create mode 100644 shaders/slang/raytracingsbtdata/raygen.rgen.spv create mode 100644 shaders/slang/raytracingshadows/closesthit.rchit.spv create mode 100644 shaders/slang/raytracingshadows/miss.rmiss.spv create mode 100644 shaders/slang/raytracingshadows/raygen.rgen.spv create mode 100644 shaders/slang/raytracingshadows/shadow.rmiss.spv create mode 100644 shaders/slang/raytracingtextures/anyhit.rahit.spv create mode 100644 shaders/slang/raytracingtextures/closesthit.rchit.spv create mode 100644 shaders/slang/raytracingtextures/miss.rmiss.spv create mode 100644 shaders/slang/raytracingtextures/raygen.rgen.spv create mode 100644 shaders/slang/renderheadless/triangle.frag.spv create mode 100644 shaders/slang/renderheadless/triangle.vert.spv create mode 100644 shaders/slang/screenshot/mesh.frag.spv create mode 100644 shaders/slang/screenshot/mesh.vert.spv create mode 100644 shaders/slang/shaderobjects/phong.frag.spv create mode 100644 shaders/slang/shaderobjects/phong.vert.spv create mode 100644 shaders/slang/shadowmapping/offscreen.frag.spv create mode 100644 shaders/slang/shadowmapping/offscreen.vert.spv create mode 100644 shaders/slang/shadowmapping/quad.frag.spv create mode 100644 shaders/slang/shadowmapping/quad.vert.spv create mode 100644 shaders/slang/shadowmapping/scene.frag.spv create mode 100644 shaders/slang/shadowmapping/scene.vert.spv create mode 100644 shaders/slang/shadowmappingcascade/debugshadowmap.frag.spv create mode 100644 shaders/slang/shadowmappingcascade/debugshadowmap.vert.spv create mode 100644 shaders/slang/shadowmappingcascade/depthpass.frag.spv create mode 100644 shaders/slang/shadowmappingcascade/depthpass.vert.spv create mode 100644 shaders/slang/shadowmappingcascade/scene.frag.spv create mode 100644 shaders/slang/shadowmappingcascade/scene.vert.spv create mode 100644 shaders/slang/shadowmappingomni/cubemapdisplay.frag.spv create mode 100644 shaders/slang/shadowmappingomni/cubemapdisplay.vert.spv create mode 100644 shaders/slang/shadowmappingomni/offscreen.frag.spv create mode 100644 shaders/slang/shadowmappingomni/offscreen.vert.spv create mode 100644 shaders/slang/shadowmappingomni/scene.frag.spv create mode 100644 shaders/slang/shadowmappingomni/scene.vert.spv create mode 100644 shaders/slang/specializationconstants/uber.frag.spv create mode 100644 shaders/slang/specializationconstants/uber.vert.spv create mode 100644 shaders/slang/sphericalenvmapping/sem.frag.spv create mode 100644 shaders/slang/sphericalenvmapping/sem.vert.spv create mode 100644 shaders/slang/ssao/blur.frag.spv create mode 100644 shaders/slang/ssao/composition.frag.spv create mode 100644 shaders/slang/ssao/fullscreen.vert.spv create mode 100644 shaders/slang/ssao/gbuffer.frag.spv create mode 100644 shaders/slang/ssao/gbuffer.vert.spv create mode 100644 shaders/slang/ssao/ssao.frag.spv create mode 100644 shaders/slang/stencilbuffer/outline.frag.spv create mode 100644 shaders/slang/stencilbuffer/outline.vert.spv create mode 100644 shaders/slang/stencilbuffer/toon.frag.spv create mode 100644 shaders/slang/stencilbuffer/toon.vert.spv create mode 100644 shaders/slang/subpasses/composition.frag.spv create mode 100644 shaders/slang/subpasses/composition.vert.spv create mode 100644 shaders/slang/subpasses/gbuffer.frag.spv create mode 100644 shaders/slang/subpasses/gbuffer.vert.spv create mode 100644 shaders/slang/subpasses/transparent.frag.spv create mode 100644 shaders/slang/subpasses/transparent.vert.spv create mode 100644 shaders/slang/terraintessellation/skysphere.frag.spv create mode 100644 shaders/slang/terraintessellation/skysphere.vert.spv create mode 100644 shaders/slang/terraintessellation/terrain.frag.spv create mode 100644 shaders/slang/terraintessellation/terrain.tesc.spv create mode 100644 shaders/slang/terraintessellation/terrain.tese.spv create mode 100644 shaders/slang/terraintessellation/terrain.vert.spv create mode 100644 shaders/slang/tessellation/base.frag.spv create mode 100644 shaders/slang/tessellation/base.vert.spv create mode 100644 shaders/slang/tessellation/passthrough.tesc.spv create mode 100644 shaders/slang/tessellation/passthrough.tese.spv create mode 100644 shaders/slang/tessellation/pntriangles.tesc.spv create mode 100644 shaders/slang/tessellation/pntriangles.tese.spv create mode 100644 shaders/slang/textoverlay/mesh.frag.spv create mode 100644 shaders/slang/textoverlay/mesh.vert.spv create mode 100644 shaders/slang/textoverlay/text.frag.spv create mode 100644 shaders/slang/textoverlay/text.vert.spv create mode 100644 shaders/slang/texture/texture.frag.spv create mode 100644 shaders/slang/texture/texture.vert.spv create mode 100644 shaders/slang/texture3d/texture3d.frag.spv create mode 100644 shaders/slang/texture3d/texture3d.vert.spv create mode 100644 shaders/slang/texturearray/instancing.frag.spv create mode 100644 shaders/slang/texturearray/instancing.vert.spv create mode 100644 shaders/slang/texturecubemap/reflect.frag.spv create mode 100644 shaders/slang/texturecubemap/reflect.vert.spv create mode 100644 shaders/slang/texturecubemap/skybox.frag.spv create mode 100644 shaders/slang/texturecubemap/skybox.vert.spv create mode 100644 shaders/slang/texturecubemaparray/reflect.frag.spv create mode 100644 shaders/slang/texturecubemaparray/reflect.vert.spv create mode 100644 shaders/slang/texturecubemaparray/skybox.frag.spv create mode 100644 shaders/slang/texturecubemaparray/skybox.vert.spv create mode 100644 shaders/slang/texturemipmapgen/texture.frag.spv create mode 100644 shaders/slang/texturemipmapgen/texture.vert.spv create mode 100644 shaders/slang/texturesparseresidency/sparseresidency.frag.spv create mode 100644 shaders/slang/texturesparseresidency/sparseresidency.vert.spv create mode 100644 shaders/slang/triangle/triangle.frag.spv create mode 100644 shaders/slang/triangle/triangle.vert.spv create mode 100644 shaders/slang/variablerateshading/scene.frag.spv create mode 100644 shaders/slang/variablerateshading/scene.vert.spv create mode 100644 shaders/slang/vertexattributes/scene.frag.spv create mode 100644 shaders/slang/vertexattributes/scene.vert.spv create mode 100644 shaders/slang/viewportarray/multiview.geom.spv create mode 100644 shaders/slang/viewportarray/scene.frag.spv create mode 100644 shaders/slang/viewportarray/scene.vert.spv create mode 100644 shaders/slang/vulkanscene/logo.frag.spv create mode 100644 shaders/slang/vulkanscene/logo.vert.spv create mode 100644 shaders/slang/vulkanscene/mesh.frag.spv create mode 100644 shaders/slang/vulkanscene/mesh.vert.spv create mode 100644 shaders/slang/vulkanscene/skybox.frag.spv create mode 100644 shaders/slang/vulkanscene/skybox.vert.spv diff --git a/shaders/slang/base/uioverlay.frag.spv b/shaders/slang/base/uioverlay.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..9909fbc8842cee1cf8cd958319ee0e45896f1ecb GIT binary patch literal 700 zcmZ9KOH0F05QWD)T3fXbi>)F^s~cA?MG)P%a3yr%V<`bs2{cKGDd-RIKf4h;-%anv z36se=b7$t+SCs{#aUp|p{1VyJQgM-u#C;_BYMH(Xciqgi zsH?AenHBXssgnG4Q6=xW$cK%#*ji4@fBs(m&~hTjz~}&@6^w?N9P{|Jfey20Uq9NM z)y(a<=`q%KtTj{lMEzQdV9sVLysgMAc=BCE@|-XET}ATnM^f8UBo9XqZ(!_L^ZJUc zqkae}g9DEhxk>t63p1ZHpdQRT&cI{pIRlJ5_3W7*mr}wyuLJH!2<Hj139(iZ#5kaaKBP;CI15`{Vo{* literal 0 HcmV?d00001 diff --git a/shaders/slang/base/uioverlay.vert.spv b/shaders/slang/base/uioverlay.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..6eacc02670b0533f6bffdaf25d7cee58e013475f GIT binary patch literal 1268 zcmaKr%TE+R5XOsrf)CybzSdoqhlvRR6@nTyh8Vn<%tfwb0-LbOGDBt>f;Tz%KYKCZ z`}K6|hJ!t+>H5B|s;>N$&6%PQrB}=JHAaloDH+{3%8l%W#F)_xbKHjy&b+4x1W#lLfoV+i%Txb)BQXv zU7ES_sB|Z9UT@*kk_G3i@;Dt0w72xYaknedtQ@5do>)uTzhtiXk>tb7C25hK{SDW$ zwm+ANosZw=ecQg?!7X2Gn|8|YGC z18ev`cEq#5^bky~VEPBf_v=`1`ogTpVGlPcInb==OY}i!MIYiaXXeQQGxPC0s4M2N z5Wb(D{|c(y9!hV?rYl*Je_K1a5iogx$)PKjuZO8! zU!)W2gCo`>?Nbu!1V0Hlo<9p1-x#|meIj7;T$ivo2XA=v^Aqv5rSs>ID|jbh;=LE9 zHvR|VMa&!{rdH+{G5PYZku&zhXCB-ECO-3sm~-X<-qkli9Qw+F`z=J@Kj=+P%$0m1 zo|aBNU}~6^kk4nuqE}BPMHG!(Ru# mRq0&`e4=iX)0zaHIneu$s*Ik%qtg%SK&Kbf@JF54liUCvGigcy literal 0 HcmV?d00001 diff --git a/shaders/slang/bloom/colorpass.frag.spv b/shaders/slang/bloom/colorpass.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..81761f272281554e48e0a89c3020f6ed5432774d GIT binary patch literal 436 zcmZ9IO-sW-6h)tjX=~ML5$aAVZUn)l6pFfV;Y!FqkStmWm_$NcxbtVb5j-cho6hj& zy?fus+?h1F8pi%!L|n&|(>0AGWG0dJ*!UzU!zWl(l(mToc7UByCqKke_95P$jBUQG zKR&zLr{=wBVa9#ms_xpayeaE0FWRDdUAM(s1^Kd>oyDM^xywJJ!kHJCORSD9KHF%& z?3MiMm=R~x%&~Lo2Y9isn}bJq^~#$c<^-`9`FDF literal 0 HcmV?d00001 diff --git a/shaders/slang/bloom/colorpass.vert.spv b/shaders/slang/bloom/colorpass.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..cf45c930b4907d4605617ab3cd441fbab623bd7f GIT binary patch literal 3096 zcmaKt`%hF?5XY}9qE;%!2b!iK;`%_XD3w}Ut3|ghYDL!v_3d(%)h@zbdb!}*cOpqm zs!9Lc{?f$n=kAQoPaZORWLNiv$e)+cQ+=}914l1drl4j`yuOk#zLaP4%|}HmQ&y~JF6UltHJ>r=tjs-|Yc7bbSAOKb@-UOXxvW96 zUF6T}S*u;t(>z^ltTywa*_l?g#=6Or>pm!J^`5z9F*q}N@AgQNsie28Lpu zUSjG;%v$2A`aao5vh&*0YXhfEDG%~xKI8Z_A9u$7ut}LS*1-Ofp+!A>y~nOc%v<42 z(1>|AF&EyD=dw*FLUW{iN!|R0=iIGXAF5|h))7+^ zV&)NVvzUE$DBe->?wrFG4~em##~;gQ505<`kN0Yf^L?UEYK1mzSh-Le*s#@|*p2h- zQ;gP#jQD`X%-N;5rk?%SpYa#!E5?ZbwwQc~|FM{SPbsDzd@t8oOg(r{9#aqAlgFHg zJLXKRM{iArCNX;4smJJXr^F|eBm1zH2K!GDXFsh^^5~aw9%9ZoAmcp5Pm*rVHuppJl@c!GC0lI5&1CA?QF~#c{n?2jGSO- z=%=XEh-=4j zQL9rjIL$S_mJf>>r;SC8Gsf7ju1Zm>Z)DV;`fz^s_pwR&+yiwY4|II&tbFc+dXW!$ zK6Xw%_d?ys3th%)>c5qtIVocg=K7oZPCjpn@3p_F@8!eEwW@wf2BZ0XpO+7(c}*_J zhtr&0ln;w_`oUPN(Z19c(~bbRa=`P>KfA|Ld8>{t2R3w0webQ!Cu|4oJ_d$R{~|FyUA qyZn9`bDaGlA3ht{pYq}S=ABV>*3`rBU#j0~{wwtZvj0_?ld?CMG15Q) literal 0 HcmV?d00001 diff --git a/shaders/slang/bloom/gaussblur.frag.spv b/shaders/slang/bloom/gaussblur.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..ad8c7f46da8b392103e815ef8a5fca91f423bbf5 GIT binary patch literal 3708 zcmaKu*^g9J5Qi@_J;NqA>>vmYC_w}w1c_1hVKFGou!$z(q?u`ZT4tulriV>bkR{@R z#JHlwjTcGK;G-|T`0k_siHeDd-*@{KTqndsimKnQ>eQ)Ir*1=Q%i^&~VN8-FOOv1Y z+chO=NmgfC&*Y?4I?=vA8J`r;Ey!T0I)q9#AiI%1WD(Lqy#BFBD}N@U-P^{_3FzbH zYNfw%FWi<)!rv&LXpGd$`>LnP?70`$N*zg3O>^e$LNXPuUOqZ9kmdh>+?Li`9U2~K ztUT}>TRE*gz0c9o;P61X-dP){)th`F*@#gcELF;BTp`(lK349{>MSIk;GW~vzDB=! z+LEo{-kxBZ_uXbpf3pF`Y;VS7Omp9}a0j+@^&D;Vty=R~LPhO~oa^wwNPS;#X}}uV z>9D-LP5DN>JXG;?^R%XKGIF?vT}TeVHSg31o{+v(d8ko8*U@8&F|eb3imf6d{V#%bCM)32t<&&2i)MPvr~{HC;xdo;u2u)XU%aNJq02p*4i zkNhmK-=g`vm;U?E`sKxwGc0F(2ikal0rXEn>ysBRM2|sYzrE1!o~Z9(Y?oMm3G(a7 z{te-O1Z=X*vhv1=}wpF$hweb-B}Uz^dJkbJ#6!AWvv<9z(ik>@Gq z+l4k(Ufh*o{pQ<`*0%oXL>@vL*NgVf`d5SPxwGVod)AteTAS~*2s{Q6dk^Q|CAJP{ z)mp^n??XIeIn(3&-bB2MvKG!<#=DIB3uK+{ckU)2)+Kh%Cgrem=5KiTohyH<#p{W0 z&QtT-+00ps;U7ZG={#-VMDY?N{7bR*J5Tz>%aHId$JW0B(JywE!p~1_>UW;>i=CzL zugUz*lYX(YWWCPAx|FwXg>+v0_d>2h{hQHS5IO7L1Gfp?iO9Q#+2>ntMdYIoKVaLt zy?E`*kBBkyuE@0w+g!d&{@4&gYAW=iQlV+Ihp3)!AQZ1>4`!%ajFAvHwb*^C>;E+YEkO<%>%ziAyTXRIsUw1KTp zamAa)_jC--@6o#AosVP7$2*_EHjjM7oWzc~a~4h^#>pEa_Zl)4@gCyS8E5Rd>~61P z7m@tk-T>$C=Ko{ljCIA`&SL9RTyeLk@h!OgJb{6=?fRT^ z?r9(Vvg8)6(=FJ?h5KMT%;_(8O@p%%~2u-Y@7i|-NV;tbz|_(sP0`xC#Za_(P%HlJD? fzpJys(dQDjeRhWSqYoo;I}!8sW!yh>=n3Rsx?xK& literal 0 HcmV?d00001 diff --git a/shaders/slang/bloom/gaussblur.vert.spv b/shaders/slang/bloom/gaussblur.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..ef2e0e8e768ca4ffa3d9dab796da2d49479328dd GIT binary patch literal 832 zcmYk4NlODk5QWPu#x*fUjXR@34H`u+;)2UfL4>*JRpu~<91>+1M8SjT-Crg6m%IqR zucrs?@OtXKuCA(ilVYJ&vC@E{B*4fJ2$s3udJ?Sf4bR)m0Ue)U1}aU zJ>Z)HoZfI2oH>>qGi#_KGpx9YvUz3{4@wJ!rt&L#!b_eHdCn};QmGvX)Ct7LeT>fe zq|>!&ZTb8u#pJ^|pA)DDr&mkRI?wrnO&3=A{3w=gfI5&OCTdzntSy z&bg0A)Zm=^cm(h0>rm%VUAy%3EV^f@Y<@^TYA2G hZCx=s?;olg9&ZTfd;|PAl>_*PPKEv8qSl9l)}fEh`5H!gBRYOR@DBFg zlK&_Q!(qSWb8d_GPg;k=b`Z;ymiOmTZSluuFX|4OK^%16hH-G*k+?fPGkbHsfAzZd zpcmIkrU9ofaN^fyY!thAzHbDHTfd_gg%z0Q4P z+!@($_8~T}nOJoAf@X5VSHx{?7>3nlts>{`gl|nYV^zDd=AM9NupDJ+&V8;JuY2w` zjX(FiR<%4k;%EkH-xH@EdSdIEvX!?=?fbGg7jf(2oQ1w~9^>>q$?1EN(|6UktRLV$?!z>p8uI(^uX!d_$bxoENCa_(j>&WBjsg>M?#*HudalZ_dsAvxf0q z8h3F+KraeERMnJb#&7M3@2pS|sFm4r-I7f%&Sbe3Wuq5`igHmq+ApmoFFD9(KHfpn zM+~)7*RsHRYMRx|peFPgVOk&`v(>aBo0{mc)wC)by(rkeXzWW~a*)q_R+IUdt){!O zt)_X|3~EB36V3_bV$9rZk;_(spRVU;=9}3i47Azhu8PB@H_}f^Q&2Q;bfwy4# zMndP#O|K+$-o_`@%Dz>BH3gjpUK9Lpv}Szl^G!AKW;Vy%;?W)p#4ic>`Bv>rTe3M5 zF_z`4yJU^(!U!+g)iK58beE?E9;**gL;_Re3(rq^G_eQn4_qZZS4Wuvpc XsW`szmjXJ!0ra157445+by@feq0EGG literal 0 HcmV?d00001 diff --git a/shaders/slang/bloom/phongpass.vert.spv b/shaders/slang/bloom/phongpass.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..b606f32cd4a0dfbb8998e64a3c08cda40ce3b358 GIT binary patch literal 6240 zcmaKwcaT&?5Qm=}cc6zH8LG61ReFk|C?bj=LFGikA%fXsfdvkaTU?f80);XM#GEnb zobv(ZoO1+o&SF6QeQ&#uF8*MszSsRt&-`BZ%x+Oz(xgYTr0GUUl2j($d1$mwnk2X_ zlae&XuSi;@eiQwjk*TdG=qYQZ$#$|%vdv_jW!+>gHP>3!PS!zIqJQOjYAPw!Kjv%e zXU;D4s?NS^vh{`h{OVk7eW5y& z&&;Tqlg$^h^G2$xy&4NDO*Tn;x`EuZN$g4AH;`9sT>38M>G^CRcf3j&pPj^em#62r zf!qPV3<~*r+T^&g>ENPmaac6M`G3QH6&xko&V%8FKPl&m7#FcuM$+&q{(%^g< zJ&F(Il%!|CdgeI~hR-`g4>m~Vj5V-@GPF3OZZd|)-HTxwbI-ZI4CcA>u{Q31tS$X4 zC>I^_`CP=>_>2%Ym9JZkSM>!_?|dJ>aQ+}vXFi8rp85o9i!Uhc>LUYT@i)o$Z{6 z-FTm^6|*;INW6{3-9%6dXMn*jzx0g>n zgS9tjw5^PKddSG(yn4ytW0X^==XS>QNEy2N3QoB*&ab!e$aXMB9qdQmj>hPrvp&YC z8-~VCGPL8`zQ*-vT)VTenAgu()Y!#X)Yw%FjhNS8F`VJ=x0`%e)EHnat{rGBYV0nC zhBJCFNCs!P#$frds4>J?)EH`v{i@X|dbNj){?i}ce~`@Q_LR>#&?o9Z$LIEv&w0=< z>Os%vhRNq#=o@vR%UqS7d&|&dZ}uS9@6>Sl+$p|){7&s7A5N{@sSz?5!_Rx9d^p2< zGD<$2;cT>gSnN}^vDl|E#=P(JX+dNgY6XDsH8GZr<*8;ctIi=h$o4p0nd zcpV4IheeHpjK#GF8;cr;h@s((J9VfG&Tx&xIqc z;nd2VnkIuWV4QcY49@VLOqUO5I6GWEEcU6+SnSgbWAw>2>gA&m*X9(%8Llx?J}l-P zVJvFojYW-FVray?f?_zsHD=3)MU6Se;@Y{!qQ*QiG@Nm#=F8v=*Emu>ENUEOENUEW zjQ#xlkC9LR=@0ME{yulCe9nPBQ3pCcw?IDULBFU6J)c`BpL3ya)P*i{ReByLLzBJP zW1(z`-Hqerw~&$JY>|98chT8m`Eb7T{O+9~KYpK`s2IlZdvTI{IKz8)vV1th*(vg2 zv7e_Ji~T&!n4b^#`*ax^aqSt#^=Q;M(^$+~Vk~N$Wh`ne6+NcME_2+yWim9`n?1<&`*Vf-DKhG+)bmOii~-|puadzT zUjNnd;S6Wj$cM$ATx%@$=h(+ynAC5Bfzt==t1(@;Mj!MqTJKSEc7eGBnwnJ;?R%q=)6Vkdfo; z5&7_CGQVe!${#MH{z^R`lff7;?pcEj&hS1hm)`);aJE8zgDm!LrLow%$Bp?}pz(wZ zjkxwn<9ak|JY_8AJ#8#%JYy_sJS&Dq%zI8ToZ)pmFCP{)UN9EdzGy6Jyd;K(voiTF z%is*xctt)eYP@PJYP@EQ{rpb6E`Pa<{_y_n?{ja+Um>GU)PauAy(xdCjDArMdOr7- ze9ncwQ5U+*anIhCp~>FtL9XAQcjQlzQ5W~;T^Wo4<80rP!5Lov`|{xoXCKIi#h!d< zEcWChW8PylK9->o*M4GLk4BAE#$w)TV^QN%V^QNXF*IV{=ZfJBuj32(u&D8+vAFgt zV^QO4F*KZUf4-5y8LsiId|1@@&REp=-WdD&S^prP{?i}cpZ$IANBNw?Dj9X4<8wdB z=R8)+s0Tft`&mBcLf@zhUFNtyzsS&JZ}uQ}sqO}Izsi{Bj!_$D`I`*R7_DC^n(O(y z4306V+v{Y_A2Qa!ea#x<%rVwq^QRbV*vHrWB_ED4)?f3t7;EUKulYwl9Ao$z>R+q) zUm5Su`>;Rx{+;}v{Pr?(d_OjTV+`NV=lMCG?{bXc^NZ9!dQ~b=CL?cw{mxTv@j$&f nzeg=r9zMTCu>n56Lsb~(H>ft|^ZOI)$>Fyr_Ft<-{bc_GeK#bR literal 0 HcmV?d00001 diff --git a/shaders/slang/bloom/skybox.frag.spv b/shaders/slang/bloom/skybox.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..71e6a0358cfe1813db7fd20541dd710b7d722d37 GIT binary patch literal 596 zcmZ9Jy-Nc@5XHy)N{pIBBZ>%;Xk%q5g2cwcDv(A~%8I8Pc;|6m3jcE(!S~zTHqJ3O z`{v`#>}(ue^eovjvr9YFAKACa@C+^XnDfZ`mdHlZ(iIhfp>!hMmX4K6tS622?Z{G> z>LXrM^}4-!d|G*5=4-!PS%2is{rV+exSHHVJZ2mJtMI_{=T+N$FF%W_UAo4V&u@); zFXdcxbEKB}-v9j%;-mMO6ah2yOv-ElpX-c(xlhQSbbFZj8*OTibWW8sl^!cUlLfP> zsc>HwZu}?eK9CJ@_7j90R4!3agRC(?VxsE-R$T&n$Z|kZ6{{e> zAU`)>tjhbG(~Uh_z0>{7<(=*smd=i$1F36YO6gqsN8hw#sUty-q|P$N?@1q&euuu- zvSy3mGud0&uIwXOr#^?&Gk?E6ux4w0vlyx68znoOPO7iZWJSBV{iMj-*{eqVRXL=(b%3*<|A|S z3)MN;<2_GlDs`1P_leVpKUUu@J1U#j?w-$(V%n6nIU{>9j!*M(XXF4IlR0AzY)6I` zISj~X9uHPw8FN?M4~_9%^?uglcIN}-Emk$_mCxDxWhXWNfO_ICiw|1dslH$Iu=;&6 z_zA^FN?x&Hi+gO2$Hx`ZJpM#J`=8P`wL=rur?XHySfAC2*bV(p6;l&xNPNoTYF$^l zrkMTM-}UBg4l%iH%2L|7!}`DFksE7>cPu8qn~KSoH%`vP=yM00ftdBwoIQwl)bCn+ zRXMPZxisedr--xN(l;9175k5CF1ehRu|G9q4ta5Z@W+}%Z9X@qu4L8OEAEUu2W0&K zHP*s-EB!LgFJ_b$e^SG#2NbGZrCcYsBAz+eKzc2 z8Dl@c|HtyF|D=rbv%io1B%gbrPUL}(k3Eq;CZk^DgPxE5EPq@^-N*}F#&}b6GBnwn zJ*v6Y@6>`~-W0#B{-%DB4<}dN)UPra4aR*xmBDFVli%dSY0iF^4~unrW-Qj}xiPOh z8g&^OaqSD^>h?4;V{zW1v8b_RENU!^p%Ldb6vJtr$4mLJsPW2JT>IKs)M$#K;fy!6 zB7@Uh;}7|;sIh7+YOEP!KfnK$eCq!~#`)Rb$8!1H19c(~bbM@GKKHRGBOmm9>`(dJ z%aV+|&}ED_)s~^j-t58LS^XzGsD49s$V^?C59hDh+bQHThyUOI8rzZ&XJ2P;X zmf5-I%*?rS?{2YhQVFGv5W;Eb^VV9S5M=71m}1wBPz@zw0gt2U+{7M!h*$Alyh*+J z3SQ*dCfZx(v1U47eyq;#7PCc?a`t50!y`+$%~bO}ikGuVk`|7lC44FDlh61Ua4p?; zGG8U1ns5L-*0%v+jSQY;p^7=9xG?F?h5RD-jVuZ=kbnmtiE@onYZ6NQR4!2>+(6} zen9Sh&D%5kkEk#9jQ%U?i=DZNtN%o`Gx`1HtkcHqA>YB(@+{wL?tr!R=5CnCx#WJC H>JtA0qoFaZ literal 0 HcmV?d00001 diff --git a/shaders/slang/bufferdeviceaddress/cube.vert.spv b/shaders/slang/bufferdeviceaddress/cube.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..200698c513557f83129c2d5512ca73390ee2a0bd GIT binary patch literal 3228 zcmaKu{ZmwB6vrP~b^)V^e65TYsn9I4B(qFKQK1Z7A?dyK3YVmTUFPmx!^xR;hMDL` z|HtZo=$B^te(pVop5X@{=kT2KJ?A;^d&f%O#6ajj5JET={?K2}Xy^-n9xiV*2g6WU zYAiQz%`Y~$9zO1@uOu7IPTtOvpVH=o?%GV^`hvI=!mGIf6wX0M^*pOueY|k`BbCbDX>~$Ut+i0*=DjKxUj`XiQijx44)-7 z+umqrvKtD=h0V5Go%~vnccZ=D%F|5MtWKXhD_u=i*l?O#dB$B01L2tNMz`~@c-x8X z2MZl`ot3neUQhC5F;z>_)=G-MQcq2r?bUQ+pS~*nQR!~9^6YVuO(V&Y&AkXU#YWHB z^7u(BFZ(f2^flf07TanV4sYphE+l!jzP)7ATH9zR`SkX5Qyp1Ier{*2B=2TwBXwiX zSyc(#RZXL(d!PU2qcqFY?FCJCYHtYGGS_F=mP07~9xUen4BKLe>;OCTe>`#;3@-~S z%i3#nGp++YXR|0hgt^dP?9x~X7czT?%v{j3Kgh&GW_OS)CcmP)CYlk=D+}L|3CSEV zc7(GZBL>)@XigrPCvkY=v-LN`o|MjGA)hvxoO$DOir?_t;Odc|sTI;fUUN=6mLw?C*>?ZY! z9{;Ux$e4Kgi##Sf`icypqi10FcvUy=!H!6Nt-#ATXH51!VE?+=`}=W|@r|DP@keZO zVix4&zTTEhy(jedv~GF;MqbPX?6`C{bfd%8-_D6YU^0E`ibCjJA?~l@=o@d4e>2&8 z^}EUBMl9wN-xPuKjy|3;thA{WJw0PMHIUa`*)sQcMCdqR%<^3k zI0vkzdrAb(aqKj?t@2B5;n!xGWwlj&a4XIL3@&_-m+B z^y;dJ{?i}w$G_{YiDwS@negMLvD@mzOZJaeIM)HNeQ$2Z`nh?w}s2e!VG z^Wy8GIm0G&e^7FVi^8>e;$aZ|MZ9a@$b5of)9Z{ zQ3r8cwlv5}eWNboqGKo5M8w25KCr!`FE8KTj%e6OS5Xi7H|$%J vi^rxbdTQ7s@!=*Ii?EhtT?}=_O_@3?&<9Bo)Hhx$4sOVosy&(DzwN4g$ literal 0 HcmV?d00001 diff --git a/shaders/slang/computecloth/cloth.comp.spv b/shaders/slang/computecloth/cloth.comp.spv new file mode 100644 index 0000000000000000000000000000000000000000..5f66899043a5302916a208821f55aab81ac5f7b8 GIT binary patch literal 13140 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/computecloth/cloth.frag.spv b/shaders/slang/computecloth/cloth.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..0cf50a1cf411174e8cbe9ffb44e81a0c0161485c GIT binary patch literal 1392 zcmZ9MNpBND5QRJ50*T2&AR&asPFS)r?2CjjLMY0`B$gt~5si`|8OdW?lZg-~;J}p= z7x+!^f4Cs=zL_p$(bjYKd$n{`ciZLC%DAhHIpf z;K9Q?*r!~XDfgL{S4HcRkc4p`eO|aPoEFXq)55GUqd5G=g|a@An%SqS5594Kc#;LL zyIM-A<*|jfGf0!LXFB-`y&FgGyV1V)XOBW}$A?E*ZXgf!9EZuU7o{%;y+JCf{1tcM zpMH?nunr$a`zO87`%L70MExxN&>6)2tP`eT^7dUC9wriB`F`1hzW&#@wFiA&5g2gJ z15V#?dVv!Urw2GE45#*{VE*uBfq|WKw)}I-f?qQ~-6CdQ>#DSdups}MW;pvb#7}7^ z1|9o^X6)>by{;KM`l7lys~I~QIc&fgONyM+j34pm5jD`rzo40T-pq!+S+58`zAv_n z-xOyUUn}Sfg&D~HpoIbgmQO@0r za_+`BeQ_5I;>pilut%V8>Uxx;n#b5#VgId@qyK06=G^%`Pz#(meizhYd`fF-F+QU; zwZJ*oa{{%zQ8xPHU89kgQTOMxq&2_iErC5uzdWLo+jQQQ`BTG3U*A=&iK%M`>TL-5 z|Ac02?DI`G%iT6TH-9wVFaE0ncJ9C9YrLj4c7x@)F0CO@6Z?|qhG2QH^KQ&WZfq9? z{CGoO6-B-40&fPNUA+XfTLS0CoiWA)?(Bqz75`GZ8~?X~m{ McoS%Ul<|r17sEYT1^@s6 literal 0 HcmV?d00001 diff --git a/shaders/slang/computecloth/cloth.vert.spv b/shaders/slang/computecloth/cloth.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..38bd3b7871e79fa68646363975602f8fb49b8659 GIT binary patch literal 2996 zcmaKu?N3xk6vjuE#agXst+ggZ7uQ;=Ev=RMQr}QiNGh_{f_-1FaK($eT(Vv*BpM+l zp&$F_`lX4_@7{B8;s<7PcFyz6ne)s!Gg+whHFt*o9U+91;a`0-_J_Uzvp3XAj6W#E z=#zDmYze<9Ta~?%t;;rKn=&Hz%MQqD`s~(Bj=DaqWlPJ?i;-6T%s65zZe~`lq6W&n z6?Zr9b(2oT?+Hicw5O7ym#y3{@?Nr#wjX!$q!?WpZI9=jsbn$lJuBwVjD8!GrC!Ff zcRneSDn~sWku!5+y8SM0pyXIz?&XW=T#@Cfa6lhoIeRysPdhKN^l$mj(~C~F@T90p zky@?n$@52f>1SGBR+aV8AG*YD#eG=zEL|#ktF1g+Dq2Y|>9${_y&_$iQg=tnM%2|g z`npZrR&$7@|J%gQ>h!be9R1y0-qSX*cPNWs?udA~99)wfP=&+|3xV-Jl}D`&*&)U6)C}%7{DEQ4&H66G>~9Evq?tVM zV0s2--$CI|O1|Pw8$M_;jt>iy-|?_~^oR7_(9D_Oj_9o1MWghqzJoDh(5H9gqGs@M z!^C_hJf@jg@}ozsw`C!$U32}(5?A{d<&)3zugIr%$1e?2FM4Z+>Bl8u`osI%VVM5# z{v5N;`*Y0sn=&-nj~;ITO)z@A0mp0d*Wbe%@8M0u=k!+5Avc2@Z-nT@6@7E&Ju=P< zrlvs|=k@iE<#XO?tr9;ZgTok}|GKn}3x6)79`2kR+`|bO{5{1qG=Cw3W5ChdlQMV) z9QX9444&cKDfw{dI(OPQ>U8caV~sP$#Tws< zLnDqmD-6%@^Nq@fi#5JCF5Y|2xLD)7I5eE2R~KaP4A;0QA1>DT!MIrCl5yl~sZ;do zvW))IAI?vHU%Miod!SF$fsU_TmCt?9FX}IR8FfP{kQyd!3@qYi3!82T=Egvq{cxYU#kr+ol zzxPM-=|BD9{N(qwxzgAFS(>Q>9bcQ5&wbD@>Uk*hwNyU$Lf@zhUDn1lKbE0MZgLRo z?`%OnZ;hCiy_ZZr@0a(;+vD%fQ(04XSjOAqU3Fye{`=cC4xT}8=!LK6^2v=ceElD3 v>=IsztTKt{<`KN^EWiJhnP*xm8 literal 0 HcmV?d00001 diff --git a/shaders/slang/computecloth/sphere.frag.spv b/shaders/slang/computecloth/sphere.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..c06d4608b6f3d88255ccfab3de90bf69d26cee3e GIT binary patch literal 1068 zcmZ9K%S#(k7{#xNF+SqECO%q?MkU1(y3kS(6$Eh;OF(d2hB(my6T@VJxUw$#A9U0H zrQHag-^~3$yy4{DbH3-?@8)y0q8lA?&eh##{j=s>&Y?`XF*mFIym{Gd43g`{{=rx5 zGcM1T`pmisH>z_^=mt>_eOH(eri5u>PX5@7LS8>~@)wjJzo^$ACXFBWaW}XVO?7-S z{VEC{uEMt0$(QNP=;k&_4Fz>jk$xR@I>SMz_=5W+KIn(-;aw2xC}lG3E9@olW9vTZ zC9NP1x<5N{aMP7|;d`eidVQ~-s|LNUlS~Uvk8r*PPH%AH;oO7yFG|I4GrfT*7?1taU#&_@r fsn6`6y|(FfVp`IeZB0OD_Q#qGGedjP#J&r!i3~-h literal 0 HcmV?d00001 diff --git a/shaders/slang/computecloth/sphere.vert.spv b/shaders/slang/computecloth/sphere.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..377fb43397b6bc67bbc91812193411ae2ef959f4 GIT binary patch literal 2756 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/computecullandlod/indirectdraw.vert.spv b/shaders/slang/computecullandlod/indirectdraw.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..795c4dcb0f34cef89cba0a50b0423a03eb3abd4f GIT binary patch literal 3004 zcmaKu?N3x!5XO&yiwPD>tuG%cS;Qv36}6?-)~bMQK`XMBO6}`;4&XiME9s_mOS&!Hk-j0t`z`6)(i75t{S9d))eOW7-owAm7 zvv&PO-YxTud3Akaw=wwA^L>1K&5AjO;@j-wyQJGJ4fsYu*4}9D(F^&nJjC}9R1;eMz2aMktX$ZgH^8I%s z4#DvSVea#eet8FS!;R|hyaU{*_UJhnQ%x8+3Psj9_`E*R3 z%n`K`pZv@XcL0-ra}VCygSYqK9m7{O%j6+8Ld<`J=-CbZQX}(8Jz#1amQs)75!uw^ z_^52^0r%#lSI>e@bG|AiCW?6ezjPP&$D~#1G3l0Zr)9$vyC#l%jZ5LrNT(iP*hM2=YROW_gxxc3KAc*MC$*>K$1xetw_ht6F!j()XBn?oWK*o0ZKw&?o93kMGUN<~`^a^^ni^ z?#Sj{=-ZT(yzKFv_)DhQZ>bb3B#}m*&WfOLIIij(Gn5jcDutQd+q`@qKSu zHt#^6sN=EJ_j1|12mPWR^7-CV*}MyVqb~BY$4sqA$w_Qt;QP0I3!cdym*V4GQ#L%a z=-xOTto3CUO7kg9du-RK$N6g;V${Boiv=Z}Q IWx6K)53#ZFPyhe` literal 0 HcmV?d00001 diff --git a/shaders/slang/computeheadless/headless.comp.spv b/shaders/slang/computeheadless/headless.comp.spv new file mode 100644 index 0000000000000000000000000000000000000000..83f37309c9045a02c926f04fca3d22f4db4a83b3 GIT binary patch literal 1556 zcmZ9MTWeEM5QTS>w9!^uYg4PDlG+!+Cq+aM1q-PKP1VK=cp;|gX^rMmbE);sUnJs> z^NQg2ot`a{E#sOsduGk-InjJ>r5FkmA%sieBY%75LoOJZ4l|+l@M-SJU|pHSD?HXpa&m zoaB%5G<%)B(J-kx)?ND8Q#*&r?c)p{`6+M;E2KQ1_ETpaJ$rjr4k69A=kgf8nDK>d zugkpEZP{lL>R9XX z%|Br7+uAbt9J6QSFUI)GG5#v!-%+dLdw%2Fa|2UfyoJ6yJ&HN+BWAIWa~kt}Cg#3p zG2`xAU4P%6UubyeZ^W3|`aeN?%Z=Y5>i$cZyYRcH7vpEf;?CwQXEE>W`2qCAx4gzz zU;LWQ*}%8P?_*69^f;$?TbMEH^ly{neywq4dw6G#ckWs(efR8l)_2Fot=R^x5x>!A z1P(Ee_X+5|DBsDrDBsPv7~lN{-+o`RceU`1Ij8S>2YP&$ck;KGeMEJgL+)MFZR7i< z$UFGH@OB9iWdL? literal 0 HcmV?d00001 diff --git a/shaders/slang/computenbody/particle.frag.spv b/shaders/slang/computenbody/particle.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..f55ec7bb4bea3f6d8d81428e5dea2c1eec2a6514 GIT binary patch literal 1356 zcmZ9LOHUL*6ot!qDk6v|h|d`nC4!h}LP!X*m<21sL>Dei#~Dp0%rt4ng|0Nl#GmZO z#P6%_@^vR?s?NQ)Zk@VS-E7?NhSs?d!bW(`zqS+_LC->HM(%tu%!d|Z15C1fYG4gK z0#CsOFb^(+D{*Yb+%EGbzl)64X@_pi%crLwX4{8lHp<7-*|0c^u})lH#RmAtrIB{% z#F~|VSme{$tNhbA)>6Y+HaR^Rm#NrGD6v+!@jEt({5Je;aZ;3VuXb2xjMWB3QI6Es ziRY>74NN`Cs#+WW)S8QDMqv3d78qt_HhJ@|%-&CM9@YJ^p8fjYe~32wWlt7?+}_;* zn%q9h?U~%3%B?5&+^&0n_=Ih^t8@md$HM(()QJ*=kNha5BqGyHCJnLQ8iRn|{ zEk@V-VpIJG%&~*SpG5lk!1deA%~k&%-1B%R?kD#=-bv!>_f8Tw?wusA9`8VNz1%y{ z&qu9Y`t#o$te!%SaKL6_UTT-Lkv(5oE%B{Bm)R^K+%+)xo_giM} z8vAZe)w@dfYj$uCznN8Fu69gk?5*F9F`*@`$Eb2|-;(--W<162GFO|>jD4*&^_aWX zoTRhQT=mj_Fed_zk>Rs>)N{L?_ literal 0 HcmV?d00001 diff --git a/shaders/slang/computenbody/particle.vert.spv b/shaders/slang/computenbody/particle.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..6c1653475803272b4570126ec29483ba1692e919 GIT binary patch literal 3792 zcmaKu+j3M@5QevzBv=vy7IIKACK(TCFoF&TjX)r3Koc_09AyryMl~nNr;6wN--dN@T?cF_DS1hV$b^qO~|JA*E1BJHYs;K?8D2ld3 zf9scZSJW1Ptd2UPRQu@I*ttff=Q>|!-JCEaoAoj=h?lKND&CcQ&7QTM{Tsr0U_?xfyqoGz!;db1oi;#y@f zX*83iadl~Mv=L8L<&m;;{e1~2%idOjbrcry= z_Z|YYu<1EAHDj;W-YHotIj9`o&!TMBsA{H10>30(B9PXg|C zzjPKh^Tf=su$e8NA#CO>tc8Atwa_nY@~_h`ck0U~F|T)nbZYIDY*fBg+OgZszTIrj z_X_ROP7dPM%ifUTIW}PSMq!-atY3ObELe}Y=p|T>^$i<=hy0tg=XZ@F&v&mdIPu?S ze$H%?y-Pd!;Uk{A?~z2&@;*PmFSA$t$8x*nXIQ+xY16rn=bOvpN8tZmdO-pw_8(^F zJ#3HuGMn>5^3yNAbMEgp^X4}7G6V4ACqHiv2R8Y6^U&ta-G+}hcbj{Z7t3|!??T0^&3Vljuj2#ZeVacDDiK^;~p|x zTkGt@hJ_rD7#4DDF)ZYGRG5Ev&heNqaF$~O(!oNGt%ijhj~ffs@?iAlB=6S~_#aa_kxDU}0@ThEbbyJ}aH`#N+2%xM=gRS2}*UeSU|f zGr#=Z;q$v+`mh9U=J$XEj0Hx&MkL@YzvFY#!C8(yFC8qr_X~z`Z;u-_tY8=%2PJTX zXAc>!t#$TA!@{_i3=28N3=28Ng~1WVy(}A?<@cMA4i<8h4GYg6HZ0_LMHn28F~5@% zaF%ntDjh83IAU1HanvyK`MbX+o&M7w?oWRAy)K=1pik5RkNe(`&U?@=>VeOFZ%XG~ z=o@vxi;wwzO9Cgk$wBNn%?7o-EmCgkubyN%s>o_iq^9W~%@%fFVAD6(* z{7!2>DPevS3G>Up1Mf+|ox5t7wiY%coqR06_xsX`#ph>dr4z>;&s%*p>BQpe5+gO& zC8=aUf}ihhF5B~e6BeWoOUTPNwI~5&fidr=B;YLPUy=^aa_qEpuy9V!7#8;T1H-tx zb9^Wrj_~Y9vcXx-@v(HUFzyq>LXKs_LXNY-;0WVBl?~2vj?bing&dz77M?w4Sjh2( zFgP6J4Zf6svz+6+bg+=)E5kyLuMH!g&;K{l=|BD9{^WPxx6*kB`a~V@xbHjZya)ZF z9{AjMK|1fUETJxV@$J(7y#!8jlY>~F{fpB1eu$Y+Jahho1RP<7HU20YJg+DJ|IsDc z;0Uu!j-Mpt!FSfMpAEmE{eoe?NC!VA@$c+c>3nB=KjivNLL9jF|FZOM3HR8m-z(bl eS_;|!_xNtWuWG++`Zew30>7@EnEzDWZpr_rULjEc literal 0 HcmV?d00001 diff --git a/shaders/slang/computenbody/particle_calculate.comp.spv b/shaders/slang/computenbody/particle_calculate.comp.spv new file mode 100644 index 0000000000000000000000000000000000000000..8df61f019c85a91553d0875da1241edfe84bec97 GIT binary patch literal 4472 zcmZ{l*>6=<6o(Jowp5A?GAWY`iXihS1{qpFP#|E-pg5FEdke+Ft?ezKqCpWQDwrrH zlBkc0q6p4{ni%7Q2GJ*D^u@ozF(!WB=~?B5)J=Y@wSH^ZYp=b}ZLaU6en~~2BuS7Udj4I8&Ku3b~#*jXxeJA74rYSE)G}rWFwtH_j(;_oUP(+f zdcLWt&{pWkms*Qyz5nOCb6d%&%<6A%^dbo#kO6|q{g^seg z3iQrmOR2!g?Acj$?I@yGCAXn(%<9|F{CTrsD^ea8wK{ujd)ZfLBd=ew484A9L#d;y zsnpd`Xs%1|)B2U^Jw(r5s`2ZP4Qp!aSFLPZS-YvWvEhzwtDx}ZlC{Y08CItE*SRZC z#g+L|UVlY$3V*S*D?O9(r?J~OjC(nQrsAIVu2NyWPhmCj-oN)d259>hv`43QE}g4+ zYsinePr`Nu=UL^PU2x{e`Cfu^-g4e|aOTJj2JY{?Cje`PJrUhyj(6ZP#}!=k5OtR0 zs{-S}YUbb_#5vSmQNw-eu-(@ccI>O|ow$cf`&p#*-ESzB^-W-(98!G*n%~`cFp_v< zwLR~6{_lqr^24#OO8M?w{rxk)y#6VfACcCZij;FdZrSx*E8qa~ApAfm}J}5^Im%jSV~J&8X(bT()+*QqH}$W4pI8ai$h@&l`3dy7|#d z5&ip%7ng+XZ&Q*SS{CuoX>ze+_%GgtoclfB?Miv=D+n;|2tmk>$|3~0j$ds&OuFIMH zi4}YMeyf4fTE5wuD{S}C{|DKZkgk8w-Qx#fJ>?Sery_3#o+s=X=$_{;da*bEJ{aSw zh4Za00G`n|Y@TmoA&@_aZQd;zcZM9_^R2*I^7eK$()Bm-`fdVp_NV?A(*CvOYk8Hv z_ocvj`dwJho>m}N0)6uKQ`zH z&TOT&f4}uBV-|O!yT>7Vb2e*%+&U03>(QOpxokcg(2bFIJ|mDW=c7;i8sJ_^_qJDU zeNp#GboY*XIE*eA_xTk14B)aq@9GFJPG8h{8om5JpTU+poArAX-8^~wy$L`C3dnEZtJsWuE92x{@f#HW zx8eMjge&}qxl{8`18W!;d%S~Q4Wh=o=yJjpHSBXM_8Bl2v;b>VBHsh@$FqITqPv&8 z@7b7hz`k=J;@(F$R^N#%?gMmlMeO+zx_kQj9(#U_F8@T9_X)bW@{#u`x_NCN@;*bC zAHc7#eVqpvfN#bc`ZqFt=k+>e{1?F9^}D~^m%!QSi!*hxt#eXARljhOUB8&oUJp9cXKzo@5b8kZtg*skDA-i%fFj@ zvE_s-YQ|f?56&3t#GAPv-Cp#?xgJ38?OcuU`aG9?Zb#;UynV*o*nw_cmvc2nE^?aC z&9P48G^3ki&*m5-7dZuVb6P;;>_j)mxtU{(T%4m7y|;7hhSyhqjt8;j%fHh-*v|V1 zXRSo;1w|kqchZh-uJbhJAs}b0J?WE+o;uNc>!}2<&z|CbyU^w1y!+7Qa^O6>Ekf=G z@&|x_3x*?I{w>fq49NL*)uWF`(0l9SQFwjjvpI+@Up|}1u;u+-_uP*IIs5S3`sDm} SVt=LfC8Yf*|K-LPf&T!IQJ1p- literal 0 HcmV?d00001 diff --git a/shaders/slang/computenbody/particle_integrate.comp.spv b/shaders/slang/computenbody/particle_integrate.comp.spv new file mode 100644 index 0000000000000000000000000000000000000000..eb5178ea3a1894e0dcea1a678fdf5b138d3d2441 GIT binary patch literal 1320 zcmZvbTWb?h6oq#)Gfi!^7i(K@jgz)s(3gru1W{;xupnY>t3HNwGL?Ze6EZWR;ER92 z-|LIu`p(P=2t8qE@4e2xuABs|?Y4z8X7zlJ;Ed!ai1v@$V+IDId2L&jef;I5oK#6!P13=E z+ku*qn`_+EWD&4ib*-$-ayL8JW?e5&vhs&a7uS*gbnt;up6>0MdPfGv8KlFqe+t%i z81wi(Z}MtX%8#^fEM1-DuHJoO^5Va~aG2y5^F>A`0#}aBh7dymZbKvQZJa&AgZ+L1;sP|E^a5>*#Qub3Z%tdYR zePzJIbqPJ;lDmCnvgb_+ci_}#XZ}OrKKHil%W`?c+`)~{<-Z0_eR$w~#1da0PIzbF pzZFBj9SM2hzZ#7H6LWCq=XfCdvN;|K=Z+q)#TY*Mf5qer$v>qXT+09e literal 0 HcmV?d00001 diff --git a/shaders/slang/computeparticles/particle.comp.spv b/shaders/slang/computeparticles/particle.comp.spv new file mode 100644 index 0000000000000000000000000000000000000000..739f548d1ccf3e2674c66cd3425aaae75377fcc4 GIT binary patch literal 3864 zcmZve*>99(6o`Q)}bAD%e&%1ro>M?WclA5X{Nfso( z^S@(CGA5B3pVTL9tvlN9*|NQTpw!o2*jsGhGuYKt>@S-gJ%xb*bLx}YWE*nx*0!yS z2TGlbn^r89pO{oD(t4AUu}Kbn4A@ub?v=jbM)zY2KV%#*Cvb6TeBD^Z(6<-wkG9qCHwmZ%C_?! zU`e%Eo^$T)FLZVndrPgv<&wJOcDU^iww3w^J4%E7#m<)WESxu&?qT%ffw(VsS+ioF z)@fTT^KU}Bu95mR$s_tJ;&*A6<8$fRboA}pKUgZ>>+x-7jyy4*%?)5P>vv!6eG46^ zJLZmvGUr<5YCy!9BR95!bC2aF0OxXV8-e*@#~jviza8c{f{Xd0wsA4vWOQpSN7jOT zYFDRwZHzVCcSqDU-aBhAj9_saMikySw6czezRxdvvoN9zYh{58qVaL%cJQIHgt!5EJ0e+Gi}Ju!k&dbd-H?fS-SsosO+ArH=w)6+Qu~@jgyPHR-(HG{dXYs zTU&cQ(%zjv;#)FKTfPk>$zFb2P)vM=k*NJP(-X9a;$F4`Q2lYsQ@;$NgRetR-(RuFvro@%m;1 zIr~vIvl{Q$GT?rAH_f*P@5?Hn&wFGK-km#v{5Dps?e|hnII2L@U5!3k-8Jy~oGymlb(I1iUY z?gsJ&;C-8fba>x(BPW7ufcH&#A1qx@+-H#aepMQ8phr)!PyT%*-v(k{IeW6MHLMrD=qY^4=;N?hds&90yBa2l<|I_ zMqdHEKaD9r@?AKHu20^(b_n?lke7=!9Y&8kV~@tjMa~eqIlkk_If5ShV9pS>oO(Ud zyXyK~gZI&HsWfFM|6OJ^1MHGMw}33+^{``4bh~OX%_^LA=wK(Osjy*dMvd{c)e- zJYPW{?L1$F*XKESU);-6!2OQ1dJWyU%JY34`xJ0EzcF%=a~j>8%JY2#`xK}G<`^Rv zJ-&&4b&qG@-U9mko=5$+Gv1!;+jDyd>;$pr@1md0_=tHA+g$h2oO3|VSbNeZ7d^d? zK3Y#7!0U_Om?h{R0{OVlA7vb({QdhFUEVw6ck6nj!}qA~Iw0r$R*ybDK_9J;PvP}d t?#+2@`O3Zd3|ro};JPmWIs0(k`sBPnF~3s#BGP_lUuDbx!)dMp{{l2zU?Ttk literal 0 HcmV?d00001 diff --git a/shaders/slang/computeparticles/particle.frag.spv b/shaders/slang/computeparticles/particle.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..0a5b51c511ece740ae7ce0535475069715555171 GIT binary patch literal 996 zcmZ9KJ5K^Z6op4vKv8*!ib&L5X-rHkjfqhU3o0V9u{0Y&vkA+R1q(YH|FeyW=No2> zddb;)Z5lcJnsVDcAQt^>xH@-^L|5oq#HKk zF2#8x?38+N`emn{Q;!`Y*x~FDfs>D&k@H-g5a;JW_bEniSNhUtS)d-Aom2(t4P}LI z3iz-ie3-K-(8Gf)^vzpDhc9xcjLglO#0C)Gi_g=Mj^2G9-X=PFKzyD9-LV10=lM{N b)Zu;LLp}PYry~J;&DHqA!GR&^1G? literal 0 HcmV?d00001 diff --git a/shaders/slang/computeparticles/particle.vert.spv b/shaders/slang/computeparticles/particle.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..e77a6d94fd0e2325150e5494932b5ce14a8f67c1 GIT binary patch literal 840 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/computeraytracing/texture.frag.spv b/shaders/slang/computeraytracing/texture.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..2aab8ce9bb1924c08ae3d089af0f63f87c49b3db GIT binary patch literal 692 zcmZ9JOH0F05QWDieOR>*tJWe&s~bUZDT1gA7p{c3P?vJSDuE^`F)rK*{%JRY=gULI zDU+EwbLQ3Sd;2X5mdxzH#`+=y^9-bGei7sMtZjj;CyiZ{kQhq0rOVR3xa3+=U%wSu z>KgiykCMe}esp^$S4gv{eR1((KFcoCd771YV4HGE{87A4(SMfY*;|-KNgle)#Sc%J zdyWNOS9{Qp+5hn?ZOrUlnoEe;d0Irj@!p@9dusl$`X8pnMddwP@*Cnzq$Blf$`Uhw zqPQ)~-Qb6c$*oDv-Y>@5rY8>!4mGt9BRlHfmxV{abwCLi^EPCu=Pk&OWO*g!id~T%XSe@Y2dw_i^qW77;+`xO%??znab}CHf2ji{b(d(n)t;*+aa-lGK hb*0pkqdzwdr0jPu1~>5jU~rLhZOXpjUz%_t{RV0uD);~Z literal 0 HcmV?d00001 diff --git a/shaders/slang/computeraytracing/texture.vert.spv b/shaders/slang/computeraytracing/texture.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..3ca929ccb101cb506147815e436f8039cdc2e326 GIT binary patch literal 848 zcmYk4$w~u36h)sIjALSq8fQ8NHBJFth!`Ap3L^AIw~|E`StLr+h=L3C1Nb7s+^qM6fNs??2?T-JEOhV?)D)~;Xs%Y zib7Vuah>?*ZOq+u`f>Ce-gor(x| zsR7>>;M9h*;PkQTm{~;`>7nL2O8S|TJuEE{s`4-Bgy%dT@tj^}rII@k$P2zm?pdQGZW1uR-7Neb4E;B~E|5 z0rgYP%u-G~Gb0E0#4|Jau3n2g#{xZpLutg)KMTJfG3IrmojFVh)J%CvHZ|WB%e|gX z|C_|`MKR2z;`J~2z^h(kcHdr`_d4@?P#m*c6wp(jCE4Wq@3Sn99x4ytvmy|O{^7MX nuh(_Hd2K^BI^Q3v8Z+J$(0LQy;Zze~e(2cDj{Lux(vk27c+oAR literal 0 HcmV?d00001 diff --git a/shaders/slang/computeshader/edgedetect.comp.spv b/shaders/slang/computeshader/edgedetect.comp.spv new file mode 100644 index 0000000000000000000000000000000000000000..5ee96ec406a91399a2989cabb3cd3527f9e1f54e GIT binary patch literal 2964 zcmZ{lTZ@%t7=~YGW{s0tYHmi$a*d`b))XwVx$?1g9U=YIC@=3CR;Gwt6^ z*@Y}XCQ(D*@|vkJKI;`Kj6)w7ti9go??3Vq4M?{6n?D^=tcA z7rCe4jh>a_99F$CNJ9V19@TQowto6(1ATGIQt=|syq08~OvtEO^YPtqRv}j&`}T$`$K9QP}yzYKPAQwb|eJ zCqa8@kA4f$|6xsK-lt3UXV85+<~;}6!`UOR3*9Bx-d(VCGW@<}dxgKZ@NZfc+cMl(Aqp{{31n-w)4VO7zHq;{a zdAR528!<+1P2Yq|ZoF^875f}1ShY9!DEz?i@Y2QHVtHQoKFaj&*;?N9X~ca7KU3n~ z{n--tj?R_1`Qu95c)#DMC-++|bH7XZ3-tGm%tzesQf|gv--^0<>UWvf-xTK-?~peQ zoQ=5j``e>mls}xgD4&wKXkYt3h1l;XXXKmg%r@WT2>qvnuD^)aC!dPgN3^bU$n`n1 zdyARdvrlwpzxTO_%iI~DxuSe#=A!(O%*B}bLv(w@%)8OG#mrT7mow|DB99{W5v}VS z@+ug0_n~{Y*4W2YD5n-^E9Wcjbz_kI_BDjr23-6GWSJ(qgtb25( zR`6@YSXbDNp=)!_w{qNZbYt~J+zE8!{2hq6Z_tg^_jbqHBwHp--FlV=sGH%k#IkD33exOk%!2(9MZG{E4n@ z1ew4|dlt8mI?{1@Z3Ev$=4Szl@7~{|?dUrY c{c>a9%Qk1-iT*ya3t0tM*Kd!%snUb|3l0t}i2wiq literal 0 HcmV?d00001 diff --git a/shaders/slang/computeshader/emboss.comp.spv b/shaders/slang/computeshader/emboss.comp.spv new file mode 100644 index 0000000000000000000000000000000000000000..7f4bf29e57a9a86c13d683ca6919a913527a2a46 GIT binary patch literal 2980 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 XWV4Q4;D?dj$V#|aziXW*%N*oy9i6(- literal 0 HcmV?d00001 diff --git a/shaders/slang/computeshader/texture.frag.spv b/shaders/slang/computeshader/texture.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..a08f8ff1dd70ff717b7f1d8f675a509c3c54f402 GIT binary patch literal 596 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/conservativeraster/fullscreen.frag.spv b/shaders/slang/conservativeraster/fullscreen.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..a96badf39f10358d0a845e9e8d9827238c17066b GIT binary patch literal 596 zcmZ9J%}c{T5XHwN{jh3VttcW$s~1l_7NO|HgD0UE^(YHg2{cJrN%Z9-`L2AZT5=tEtZz?| zzLq}nX}%fOs@63`#M+``P$)Q{?Wn1qR{c}}!$sb(xcm0nvB%>HBH zt|D{8pK14=B6&D!8UthJ^<7a%|3P3a+#mV_Vfwjy@<)oi3jAD{{g@FwF#XJkfvIOE tdS+6ht~m$Xj}Y3o`g3O94?Qq%xGzWVMOpUbec-6W?xc)9{6^|G@?RIoCsqIe literal 0 HcmV?d00001 diff --git a/shaders/slang/conservativeraster/fullscreen.vert.spv b/shaders/slang/conservativeraster/fullscreen.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..ef2e0e8e768ca4ffa3d9dab796da2d49479328dd GIT binary patch literal 832 zcmYk4NlODk5QWPu#x*fUjXR@34H`u+;)2UfL4>*JRpu~<91>+1M8SjT-Crg6m%IqR zucrs?@OtXKuCA(ilVYJ&vC@E{B*4fJ2$s3udJ?Sf4bR)m0Ue)U1}aU zJ>Z)HoZfI2oH>>qGi#_KGpx9YvUz3{4@wJ!rt&L#!b_eHdCn};QmGvX)Ct7LeT>fe zq|>!&ZTb8u#pJ^|pA)DDr&mkRI?wrnO&3=A{3w=gfI5&OCTdzntSy z&bg0A)Zm=^cm(h0>rm%VUAy%3EV^f@Y<@^TYA2G hZCx=s?;olg9&ZTfd;|PAl>_*PPK0AGWG0dJ*!UzU!zWl(l(mToc7UByCqKke_95P$jBUQG zKR&zLr{=wBVa9#ms_xpayeaE0FWRDdUAM(s1^Kd>oyDM^xywJJ!kHJCORSD9KHF%& z?3MiMm=R~x%&~Lo2Y9isn}bJq^~#$c<^-`9`FDF literal 0 HcmV?d00001 diff --git a/shaders/slang/conservativeraster/triangle.vert.spv b/shaders/slang/conservativeraster/triangle.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..7a9b3bbe41212268ee5cfa4ce907324e825463c2 GIT binary patch literal 2232 zcmZ9MTT>H35QRs=#S%m*3q?f?#0!d|XhambtKcOPM7%yED~VPp$WqH<;hR6fpX-ZN zo^LY^Q#RE*-KTr{O!o}QwH3Nt`!VO-sH^LX^tm<%((7`WkA2FW$m}+KccMlU=aRH4 ztw~QxPf2t7>(y>ZY zag-JhiWOy*qOCaDOKTIwyUulL2l+@XN+VXd2DEN0u2zonIx~#;ZW3?RH`7L}le3>( z&bSlT>f2g7bZ+|D{~F8g&U&gh)8uD4ZZy+!ltep~AN3@yAC%PncxxuckK z%dS1^dq_BfPtW*p;$P6(DLpM+5u^1}kdG|uJe-l*#IX^J8%8~_c`0@2VOWZoKhknD zzbc#iL5OpAcFr^Y-iNbWY@PM2Y|fdNo>P98R{VDFANPJvYhGxNR?Y<8FQ5MMQm`@a z_x4ml$!X|W8V0ax>NR%i-7%+$Ju7| zg_C=N&-`B5@GWRBy3$jNV41;0PFVC`iE(!>-5%a3F(C{N!KoYbZUx%Q@>$mUJ)KWcAkMm9LT@}_39 zm_8D_?>X7vh|OePHaKF~f^4vGPKzE3=d|Q8n>%xQDupB5`^@874mqBCEX-T>Sje&B zv5@11FgU`zm-4|8>*JMdu#n@m$HKiOkA)m>gu!7LZ)#Nvju=N-Hdx59=CP3Dt;eWm z_rETCUdntpKlLs4PWFP7Inf6^7Tb`$C}m#s1E0m-%U+T)H~NB?7;ox>6i#YWgWR(J pE%+$ATgq?kZ;ySJ4bDEpzQ_jWea>n+RjpvyHLbnUznaFB^dAgWhl~IK literal 0 HcmV?d00001 diff --git a/shaders/slang/conservativeraster/triangleoverlay.frag.spv b/shaders/slang/conservativeraster/triangleoverlay.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..5cbccf9c6e86485c1493c06ec2588400e2dfd7a9 GIT binary patch literal 340 zcmZ8dy9&ZU5FGQ=h%W@~Bw{0IErMW5DfepKT*Jb4ej?nA_Xg*+e_s_L)D5s?Loy z<>hA0y(D>VdxY$(`hWh!Y3jcqWYc!1rJK^snDHJmmlAX8BYMT!Gv(Rr1jla}E0++! nE88+FeUA|Li$hzh`FepJEA>y>Qzq`sNOO*iq*I>{ReRzKs@oW| literal 0 HcmV?d00001 diff --git a/shaders/slang/debugprintf/toon.frag.spv b/shaders/slang/debugprintf/toon.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..d23672926df12e95225cf4cb86a9865823b481e5 GIT binary patch literal 1332 zcmb`G+e%we5QbNC@_atmLk%rdlx|9+t=1++M7)V5Q0T2}G}VAf%65CNX8xJ=&+M6%bn0c7%RF<=ExB#|=Zv_N1L<=)_gs3f@}&}- z#Ye&F+FRm-E{*azL$1eVWTzyJu-*hONya6Ul4;4X@`-mz()#O@hCi#DU}q=cQSC|m zoUdDNem{?c&#kBto{Cm=vc8uD-)Wt;A|W~7TY^>U$0zaE+9A2UzW-V?jxMULdNZzu zQP?>67KO(Rf%}i&$bG))e|%5h#J4X{SO=du;PcJ+%mkk);xjMHAA6jA-cKsIGbuZ( zoJB7gRZeCJHl_O`(%A4V${&-a7WlaM=A~DJlk-BNvt@qXyFc3gEAN-v{*wGc;ihEy z%kr%}x!;Z#l%{9!P5JcA?C9NmX4mO6JM+2E z?BIAWW^i`G0lSw+Ex2rEytkr!W-}_Gp7|59sb~I_Z0hyvHu*CWeh<46?ixPZfph0l zz3`oL67CSc6~Z3aGdO$rtuA||Ie*j>u^vgcgx=95<->|{g2JT2#=Z1TXX%HS=2l7KUF O>hQ+E{_2ITOa1}#RBWUG literal 0 HcmV?d00001 diff --git a/shaders/slang/debugprintf/toon.vert.spv b/shaders/slang/debugprintf/toon.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..dda273ae986be3e12d6a975cdd8e2ebf4b8e1500 GIT binary patch literal 5224 zcmaKvS!~o*6vqE_qp=7gD#iucB8s9_v?7Wu1r!tt1C_cv4DGZGw)4m7zfjyDfcu8) zi%UX`5jF1n`r?upV-y#n4?fUD5)u*;Hc^A|`_0@_PWr%UzTR`bbMF1_J@?K~%FD(L zjVgvjQ8Xd?PrtE|QCS3YOjI4Uq*~MS=PgO+<9xa&+nvcLxwdpJ-w`Wcqx=Sq3*&rC zNHxsKF7NG36>|BcBN`r+D;pKp8lea)6S_0GJbt~9lyGOv3j1$6f)iE)!9Ol?Q2$-8wL(usV>svqtup~p&Dwri=))G z=CW&Avu&kX?(8VF3pftN^oa8v*z^xb1s@GU2U>3t+#Qhq1pBOQ3+4e(B&;42Gt3M09 zBQ6(4>4fa5P7yKwN%A;rtuR{a4b@0o5#s6)Q(r4~m`3KopQ!lwB46SrhImw{q5cH< ztVzA)N6V)V7M~&?qyAKl)C0@c%4a{P={I*nu2vYMy>m9WG2tGFL8+#q*ju!?Bi5() z#MGRuc!ox5Ssy*lo))5L{S5M3<*|42%-^Pw`L_NJ`Six(KSRu%sj8=6yuTqX=KcAY z_h)gP{CWWm=I_whFQ7rp`n&-j^9Fp(8}Ko2fOv?0bH2mEWc3S8bTIOV6md>;xVM7> z=d$>~pm_hFc%O^8$Gst*ruFCt@0ea#%r`c@u$a#qy_l}uuoiiIbjUSn&*LLcEU2=TRX9{StHfvC8Z>mXty)a6!H#Mu6FP)V)HCuqg?7rv7hsUfZSICFQ zjJr}kobS`zz?HeWd4aRO)2FKhH2mDF1FvB~V}9U#-Gab*jpo34jfLXS@O6t6!((=i zlzcd^u{dyk?vlWHjTUie7{{BsMu5jmW2t;NuhAMfuW@bQSkLbNI{EaU{;+@6x7_ve zxd-~hInc4(4f44U`o($Bv)qmHxflAzxzHuYo4QFrleJlc+C}=dtJZk4P!ph`cpmnj z3f~pC$fqVPY!2Kq`S7f3Tt@yfVWzmtN@Q$pF8Bk zW5#vLhx5H(5jfxbT;S-vX{?lwhM#+@VtC9ny5z(8y6(VvjeOv|Ml22uU$;szJZ2iV z$%peAg~0i_J%RHYi8wTjj@R(_=mJjDO)&$OL^aYOf>`kqePygu;`)7U2-7cSd zpii6w9n0MzpZlO+oCiJ2-6@}Yp>LcEU2?qBy96{@n>DDlcX+pa-l>0w>lDK?Za z@vwk~pZiGQH4JDx8aQ9~Sm3N4$Hk%H>z+^ykJ&k%ln>`Mo(i0w`*h&E#xvs3 zfV2C3RzCgWJm?)3Eccvz`o_7?^||L2(?8CKzR$g&m_Bk&_Ce0RzqZIn6JVT!eOvxT z`RD>{aQ-E6Xaj6;{$+9K1I+TAX{+K_ge?L(tVO+jC%!6wxIm5V=Qa880JHV%?@99Z zUSF5rByd-}*Ea+>434+-rT~xGoxUX>9y9K3`EckN_fFvaJ--_`f6woUL&MK~Uokvp z>wO>}&eweyIIrHh(zLHPhI2XD;_qAgB$NA9rxo;HHN6yJU$l3jWD<4gOaSrxv`S0YT3$VfY@5P}F zu)+Bs#Gwx`%iDYXQ5<_fhqb8Z@5^l(e-i42(E@Lf_w};?Z~OZtaPXL|Z*Trranzt= zbGFNe2bj&V{BPp;o(7oZH)>ziihmbagE~GZ2Lrb*{GaU)mpdSznEf;NUx9jy|B+9P v#ed7+@8U!9_l21A|0V1d(CrT~{!aPS;_uSPI{3RaqJh6hBl?GRqA9}v6}8rA literal 0 HcmV?d00001 diff --git a/shaders/slang/debugutils/colorpass.frag.spv b/shaders/slang/debugutils/colorpass.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..81761f272281554e48e0a89c3020f6ed5432774d GIT binary patch literal 436 zcmZ9IO-sW-6h)tjX=~ML5$aAVZUn)l6pFfV;Y!FqkStmWm_$NcxbtVb5j-cho6hj& zy?fus+?h1F8pi%!L|n&|(>0AGWG0dJ*!UzU!zWl(l(mToc7UByCqKke_95P$jBUQG zKR&zLr{=wBVa9#ms_xpayeaE0FWRDdUAM(s1^Kd>oyDM^xywJJ!kHJCORSD9KHF%& z?3MiMm=R~x%&~Lo2Y9isn}bJq^~#$c<^-`9`FDF literal 0 HcmV?d00001 diff --git a/shaders/slang/debugutils/colorpass.vert.spv b/shaders/slang/debugutils/colorpass.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..d74fcd9e1f649e51d8126262172915ab87e9d9bf GIT binary patch literal 2212 zcmYk6TT>H35QPWA#S#S35^snJctKGFjff%`Km{+6AmZ)8)RIIi6lAGovG8B`bA7SO z^KGVOI@LSfr+fNL_YCAZ$9r8@hjVVi)%8V&T&DvWaJkIK9&{%&yHnr2sM*39l~$!S z=_%=HX->aBt?cR654_phKTM}8@qx$4Yhx?%Zk#Bq-(3<`Ek|k6Jlag-B>K^)e&3Cw zw0KmkDytmr#K}QgpD9i|*P|WeBlReaSmC;;b!&OOdYspjVZ`^7c&AZIo3T#LesVeE zUR-bNYVFp!>F01emfe^2)M%y2uS(o(rIjd&_NqS{N!mCntNW?;!LxncnwE3NG3QoY zSJpT65PW*ZXQKF*wf0EC*TiW3jLSz>mB|^YO&lAsxMB1FR+3T|j)D|1f2{3hKKI4_ zAjE50?VM-*y%)rt6He`6S)4O3J+J&;t@vHuKjD4y^FsTzvX4CcLGP1yPX17aw{s@F zf5zvSKP(?He?&HXBl5cc?;eC4J{>+DuS;9#^^_Vv`@u^qy{;ckledHqK{E^357WCx|+!K8G zoMAu;-;(yyOI`{e^CE}73evoELpjW4ObUj8QFmMlj(~BW*QDTxVb^7Ybp+TAk8y6x zyXi4{Fpde?aD;nr$p=Sl?`_#&Vcw+2LXJBg3pwrzgCoqFk`Im;$359#A;+}G!o4#d z3pwr!gTpXp^*{=a7)MbySjh3vV2q~V-aJQmLBxyNko%;|*`j&Scwk8AnQvFfofZ_Q&N$19J89Iu7J z5$3&-4~|$LZ)Jmp9A%G%d*691?b$p8QV literal 0 HcmV?d00001 diff --git a/shaders/slang/debugutils/postprocess.frag.spv b/shaders/slang/debugutils/postprocess.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..59b020b264f32d9adbd6cefe98d50d09c51e010c GIT binary patch literal 1960 zcmZ9MTTfF#6orSDn^n1pf{2&aMuMRMsUnS7sG{N}LcL#JOrvO;(3aHl;2S>p>M!zt z_*Z-}aecdIC*#@8?yR+D&GgKk?vu?FN5bGh2w@?-*Eca4G67{QWQ~Kz!)O@Pm{GPG z%{CJS zb;D;2uNs~)eADo(;Wfi^hAYCu_H17pt%Lo&?p9~N)76yp!BEuL*FPDbPw}fMUP|%h z6fdXvYKm7y5H)ZX1iB!bQ`S?pSz7OEs0N)nsYYloYuE> zHtKv)Nx-=ul6!D|S(t!xckZ7`?z~{P*IzR&JS0zEIV1nDMmWEp7a!Hg-sp?s%$-o? zeiwh0#L)R4ppotw7be^@CX5z)PKj%u+wPeZN5kXV>4dY^wP|5|v354`p}X%~;)%8M z(%|H*s(C>pXX1>U*#l0@sXo*XAN9ycNx<=Q$MJq|nG8qOk~)=r-YL=Iq_f!5&&>KiVw|I@ zZ|;>o=eNJh3#XsaxNq0!Yc%fHHToNk`*e*yN8>(SqudIoP}`Tf^h8Py@AI02=^@t$G(y{8fPZl zwx-J#s`EsmEtU;9uPof`StN5a%1Ui(-aFLS>3i7-0#_>r75(EGfEcOWhq_RDOkqo#6=r)aiqDOv^tO-VNVzn z3PMJ|VXfrnY{>03JH75xeAnvq;-s6jZy%c7Ui0xv6&lw!E-$BB&Hi+=bIZDV)VfeV zaPEL_3UKa*GvM^G=$Khq73pEgb(HoqrMO>ORj4RGuN9v4e86*hnUqTHsz9Bp_^6N3 z*&lbhCXFqhKcSd>IQugK_2AsKB50g#%N_2k31}eXtSdHq`3N~{VrU@bY$#>~jwd>E zN}mlyyc*vJ-}RjPj>P#6-ikg0$J@X;kGIrdpYwPNKTzM~@l6c0Z!tVP){HkJ0`&tg zDyIIM&a$uP)PE_>d)66zDtrA?Iq-_t@bk-S(_Y8Zd!572Sphxd%qgbU|D1Vo^jLN9 uU_sy<`n%Vbya|tH==dM&HvFs$==hK4CvpI<(24Ph`ag2%Q1}Ik+%6{o literal 0 HcmV?d00001 diff --git a/shaders/slang/debugutils/toon.frag.spv b/shaders/slang/debugutils/toon.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..669f325da035b6bc1dc8a6f7299f67fa5ab3a0e0 GIT binary patch literal 1332 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/deferred/deferred.vert.spv b/shaders/slang/deferred/deferred.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..ef2e0e8e768ca4ffa3d9dab796da2d49479328dd GIT binary patch literal 832 zcmYk4NlODk5QWPu#x*fUjXR@34H`u+;)2UfL4>*JRpu~<91>+1M8SjT-Crg6m%IqR zucrs?@OtXKuCA(ilVYJ&vC@E{B*4fJ2$s3udJ?Sf4bR)m0Ue)U1}aU zJ>Z)HoZfI2oH>>qGi#_KGpx9YvUz3{4@wJ!rt&L#!b_eHdCn};QmGvX)Ct7LeT>fe zq|>!&ZTb8u#pJ^|pA)DDr&mkRI?wrnO&3=A{3w=gfI5&OCTdzntSy z&bg0A)Zm=^cm(h0>rm%VUAy%3EV^f@Y<@^TYA2G hZCx=s?;olg9&ZTfd;|PAl>_*PPK~O#7?xa;FcN_rkNy^ zg2emUF62`>DtEtEB(Ah4F@ylI_{eGo!t++!K@euj~+k3 zKku4sK4w9vrE^1;gi#8ATed0NmJMZZWoKkdvSrzM*`hRfrz>mfZ%#Wo+sa97luo}D z!G4w}VJs-V?cXo?kDp4e2h1Y1hRqY4EeW`VQowG2R z#*@5Ev=>fG-IluHTQA5wqaw;^R9m;EKgY&bEg+UY9vk~A{xTV7zFvA;&nxJ5G%0$^Oj%%N0;cz1<^yKJ zVEPDV#$aYUkfCpwp0dF73BT!q>wdn8dj4UBEuK5#M}JvQ_<{dIO3e#8cf|E&7nP6i z2TXn7(-o%vzHm=F8u0k%wG)p%{zdKh;n#)nt;n4Fv3*H+pcC(+ciEkCYubt79W-o# zSu2XXp`AGNZ$WConf``n+{+Cqp&iJ`X~uh7!sO(B&xN@Mvm+0fx|y9}{LHS7nVn(k zV0J9t2QwQMn0(BJoQ9cA9Wxv76MbRm+Wq1F2r+{fdU7ZJpQ#s2Zx>|LYyPu3Q?KE3 zI#cgR+T8hyj2L>-tNL_RXTA;UK;QW5H6ERw6sVzJ@o%*AE^#Ai4YaRTxUU@_bugow zGWv9=IO^bc0FL@u@7+nSeOG6E7|Z(cOZAg`T}BME{#kMNDxP^;?e}%IJK_Ib#qvW- tjrgr64|Rs8CsyxMotdN6%kL4K)w`vMF<1J@nVF))nLZN#SJiLI{s9Pdg3|y1 literal 0 HcmV?d00001 diff --git a/shaders/slang/deferred/mrt.vert.spv b/shaders/slang/deferred/mrt.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..92230a266397e3e5b3f4ddb9320d9a0fa54d991f GIT binary patch literal 4752 zcmaKu*>hA?5XLWr3@8XfWKj_VK}E#~5)oyQMFfOEkj;I#kO2pixnVLuP?W`e=gnPl z-}fqc@I_K(s-%i4s_>8T#VWtwo$jH_ha9TsbbqH$f2Wrj(loMdbTVp0k|cAIzxBzQ zn2b!;Ppt2pj7U+Zq~xP2aeORkU9XKz}rVB91blnhDE zO3q2nOD;&pOGJ@eA(FVce}_+qO&1{fJe^ zR%Ja|Raha9UB@iE{QvbR*JE2RtPfwQC zItDt5irSg(%c?5D{0>#1AO`$d-DxdlZ%!^vuGd~%QLUzji*?uH!P0I8Tarhb+p%mx z{Vsm2i+7uoS+cjS++-K=E94k{ebsEA0+lmW7jAs1QE%2=A~DD4!NGFrkhaEsI#sUp z*V4-F5>;$gjp@&UU77SziJp|ydi(MMH>>*eOjW5K?#jxQT31?4dzD4CRvPG3ciS7q zBwuCN;N1q~%nzc%%%4@WCZ2Ymun2kU7C1%6dD*H0+ z#Ni$`wa3N}yTxqcOqP9Rj@NxSzuL~hId8RdZR%^?|2pZsXSzOTYljPLhTh($9n5{_ zNawBi(rbLd@TJ#aGn64U=dKH9yyr&k5fbj7(M~=d?@zO-C+B~eO}!V(rXPIoxQ|Ug_};lqKlt87 zo9|t;`QEurfB4=-+vkt?)Qg$s{n%%;4@!75Ht!t@Ht%JI<2f@NZDu&y%rN#seII!T zTr9AEWKqkd`lLqVB;=1xO(salADfy@l90dKlckft+f${JKQ=RYm4y7=zD7FvpU_)4 zzg7Z<-x1wu)jm@KzCu3C&s+&LVh+KWnOh~`%n}%LGhYJEefY@dHVOD~`Cu=QkRv$v zn6En|#3vT_+O#i{fNz!$-;X;D)0Shzx=RAi!mprxu>_pu*b?br)ZVeBhS3YhmKjE0 zz~H!B0!O^N+;DA;yDJQfek%=&9IFhA9QO!=Bl@kD4bJlS-76g|a;z~d-d$^0a?<7Zvc>BmY5 z`M~FAo2Ap2RTA=omot8cwn*S4HZkz^nc60unc}y}XKK52aB^j)c1XZj-tPybgR{IQ z4@w7TIrflruvn*u4U2Vp#4xWrb$V0+N4)!(;o2G;MZ==sPQxNcYFOmhB@B+}w_7$i z%k$`#4i-5|hQ+&k42v9lg~8z%GxfLxoaG#4>0ps#pJ9>X3B!oz{qK=Z{izS{C%&Kc zN~aIhi9F!(vx;>3u~R}m@cCILoxV^v@`9H$W~xsDC$Wivug_FfIy1Fj;xpAR9h_X5 zshR|g1xCLQNWfWMlY`R1S&ki&4i@V)U|6ivVZ*%ca6Bo2Bi?<=aBU5aBZfu4rwxl7 z&lnatjtYY#`W=%E&hk8tO9zV_Ck%^spEWFUJSPke$C#<-CEzUQctJW?sOpJNi@``Ihf=>v5l4|x3SRq6DDdXW!&e)gJl`a<2v3trBcsn;cN5}O$K zp0wF`LpuK_;^Wwx(!rTU$4*KI=Qq!1?=9(Z_TH8a#-dKl#XAykme=lG>EJBK-jfa% z>-oN6v7R3o=KX==LkS%5?nj1eYjB)0Ec$(HSmgM`u*mVLFgT*$XR^Urp2z3X!6L^O zhQ+&I8WuUe5(bB3%-+`$aF%m?BONSqd}~L@~>GXqokq>-+_LFq_LfyypKb0iP;;nW{Lbow-FH(#~D}#K*|(m37Tm@X z5|dK!CDg z{$%X>?3jGM4|?C+F z1%1DmryM&?%+v3Qd8svQ%&z1?P8VZ={8V0-j?sFN7)w4tjO7=JvGN1NSbLEe>)#Wj zF~4sv+$SA83-6;Qx=rk1Y@suJ3b&%$Hu3c0j4qy}ra1lOE-(0bHslu3jlCY(NN=Va zE6!uY>R`{cV{@E#bz9hji@9FI7F^8rI-GNDLblNB3%C{Crrq;s9GlqtS^v5MF8X_S z7uRVb`8%)U#o<4n3XI)CG~=l+z^4J(obWYZ*Fw%1&0yaL_Q^G>&pwo}K35aT_e3+@ zv2&4P<2&{vNXN=M*SwtPe>DAz)^Ux9A}ocqgn zc@x)+HxhQe#cw9;T;jJ9c5NcJx6x^9wZDU6d}|B)d30KPti${n z#at)XX7M!KifOp^0`~>xb5DDpL1$w3WBzfGuzSIK!JNYGxwna3OV7FM8TJWu+bW)$ zaUE;Z=Rcr&q`scj`*3j2h&_*E1+4wc1?>L1r+^*jekqRkTQ9KV{iYNDo7uY=YkL>n zGqoLTKFZsfe+k?t>8^*^^Shkxdh7;!Hg8Vc7pcwt>Gz$S?S6b3kbdLI8^eA3YvP;d z-5~LA!1~DBBGxK&V@XFWzXj!E>~As38AHF-)M9M;A?CA&+Y)|=Y{a+ItxJ9|<+M8S z?fBe@eiwZceRIxF*3p^xSMc$SZ>7t5PF&CVNZWsjsm;4y&NWrHe%E6jxf$Ov*CB21 zay!T`Mz@Yuy8EPs?mlUzyH7qrH=Z({$rTJ30e^1B?EIea+eFTqtRc>a>$(x_H;O*| z^0oHtT?>$RF5`OMeg}5{xYpv|gY}cQ8PBncz%e#_{{ScN7=BZ}O@Ir1{|G1V7;E+! zI^GG@{HAib9w2Xvn*RhY*8Cb+KY3f!d;{3A z(oyrD0rHNK58oRB`dVA~o&n1{rdYFlvE~-WM9nv0n*hgi_S;V`YL5FYYW5pYAAVE0 z+zODlMa_Q!7i<12SU-7N)bV++W2K{xzX9YOBOkuE0rV}_{CBXtV~RD)7i(@MPSm^x zoA*uBycR4MHOKuOHT%t~55K8gIso#vsQDk@V$Em4`pMg(j?G}lN=MD-0P>EJ58t~0 z`W9<`9W3vdV$Jf!nmzYL?4FNYx8ZB9UFrOGf#rOMdsckk$T{9S-LvAoqs{k)_mlcP z=)LIreI@xR|HXM9L00KD?LEn^6n`~grMQ%^(mcJ_cA`7qt03>kUFdQZbnm({y3PAh zo4A*5zDnbohge(efqT(C>oHFs*m+`4>_*oo_QYO%^@%<4HFSOWr?CpQ!RVp_1DL_-8%>9>c0Qo56*iP(ma&zfrZGA({0)pAhj#S zS0}6#Uz4yh*5qMy=ZHOU5M3_zz_sW$_kcF>N9oR^G_HAwwHep%j-zz%ftcqxbmxgZ z;NM5+6MMk#SAAj+97ETKCCRq&h2Z;aoGx#-Y4eQ6oG+ml@7v>Gxr@zl0-HX?IZlG* z?Y0Z&cp0wv9y>~(zxa!*5QhU6<@J-ywK&Z=;*1^BsnhkNF-$m$Tax#rYnG&}SUp`OM)7u=5#Dd+<*d zc=I%mxA6Hsx^-_xHxF|@0+yf4ogsb--I$&$>vajV*VeX zM_%sjBgyw!cx~nv^BqmTOYtky^)cUf(4Rv$-&i+mejY3z>-GY=``vB>=IiEny#6mj zI7Yw2i93ca@7%%t5MADS9$;-8JB}W?ieCa-S4Xm0OVl=juH9!6wfzWP|ENtL*WFmh z(XGR~$94QMx;6N19XXwV(@$H({0VwIALE}d_@4wjMxTiBGP=BV`5c}5r|8zJE%G^q z?%fbRub|86>zO=_^h_$nKTB9?j0WQV9Nn`Q@48pf<=U{tJtU{@T+U%E?;K+*#c?lr z4@7>yLU&ByM)b>w8~M%x%jsu)ZF0u*-&~BZ6fa6x8M)8F*LOwaJ{K$(xoeYiyzf8b zDaG-QTnLVR`3So2Si4Q(d5-7uD7rp}=uy*Qbn}k)`(x<76T8xRe;i#dx@XYm`2^ju l+G9PQM0XBtu^w{qeRu?2T>L(ivz~5}wLazl$oy9N{{cOa$X);d literal 0 HcmV?d00001 diff --git a/shaders/slang/deferredmultisampling/deferred.vert.spv b/shaders/slang/deferredmultisampling/deferred.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..ef2e0e8e768ca4ffa3d9dab796da2d49479328dd GIT binary patch literal 832 zcmYk4NlODk5QWPu#x*fUjXR@34H`u+;)2UfL4>*JRpu~<91>+1M8SjT-Crg6m%IqR zucrs?@OtXKuCA(ilVYJ&vC@E{B*4fJ2$s3udJ?Sf4bR)m0Ue)U1}aU zJ>Z)HoZfI2oH>>qGi#_KGpx9YvUz3{4@wJ!rt&L#!b_eHdCn};QmGvX)Ct7LeT>fe zq|>!&ZTb8u#pJ^|pA)DDr&mkRI?wrnO&3=A{3w=gfI5&OCTdzntSy z&bg0A)Zm=^cm(h0>rm%VUAy%3EV^f@Y<@^TYA2G hZCx=s?;olg9&ZTfd;|PAl>_*PPK~O#7?xa;FcN_rkNy^ zg2emUF62`>DtEtEB(Ah4F@ylI_{eGo!t++!K@euj~+k3 zKku4sK4w9vrE^1;gi#8ATed0NmJMZZWoKkdvSrzM*`hRfrz>mfZ%#Wo+sa97luo}D z!G4w}VJs-V?cXo?kDp4e2h1Y1hRqY4EeW`VQowG2R z#*@5Ev=>fG-IluHTQA5wqaw;^R9m;EKgY&bEg+UY9vk~A{xTV7zFvA;&nxJ5G%0$^Oj%%N0;cz1<^yKJ zVEPDV#$aYUkfCpwp0dF73BT!q>wdn8dj4UBEuK5#M}JvQ_<{dIO3e#8cf|E&7nP6i z2TXn7(-o%vzHm=F8u0k%wG)p%{zdKh;n#)nt;n4Fv3*H+pcC(+ciEkCYubt79W-o# zSu2XXp`AGNZ$WConf``n+{+Cqp&iJ`X~uh7!sO(B&xN@Mvm+0fx|y9}{LHS7nVn(k zV0J9t2QwQMn0(BJoQ9cA9Wxv76MbRm+Wq1F2r+{fdU7ZJpQ#s2Zx>|LYyPu3Q?KE3 zI#cgR+T8hyj2L>-tNL_RXTA;UK;QW5H6ERw6sVzJ@o%*AE^#Ai4YaRTxUU@_bugow zGWv9=IO^bc0FL@u@7+nSeOG6E7|Z(cOZAg`T}BME{#kMNDxP^;?e}%IJK_Ib#qvW- tjrgr64|Rs8CsyxMotdN6%kL4K)w`vMF<1J@nVF))nLZN#SJiLI{s9Pdg3|y1 literal 0 HcmV?d00001 diff --git a/shaders/slang/deferredmultisampling/mrt.vert.spv b/shaders/slang/deferredmultisampling/mrt.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..92230a266397e3e5b3f4ddb9320d9a0fa54d991f GIT binary patch literal 4752 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 IgB+Lse+wSZCjbBd literal 0 HcmV?d00001 diff --git a/shaders/slang/deferredshadows/deferred.vert.spv b/shaders/slang/deferredshadows/deferred.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..ef2e0e8e768ca4ffa3d9dab796da2d49479328dd GIT binary patch literal 832 zcmYk4NlODk5QWPu#x*fUjXR@34H`u+;)2UfL4>*JRpu~<91>+1M8SjT-Crg6m%IqR zucrs?@OtXKuCA(ilVYJ&vC@E{B*4fJ2$s3udJ?Sf4bR)m0Ue)U1}aU zJ>Z)HoZfI2oH>>qGi#_KGpx9YvUz3{4@wJ!rt&L#!b_eHdCn};QmGvX)Ct7LeT>fe zq|>!&ZTb8u#pJ^|pA)DDr&mkRI?wrnO&3=A{3w=gfI5&OCTdzntSy z&bg0A)Zm=^cm(h0>rm%VUAy%3EV^f@Y<@^TYA2G hZCx=s?;olg9&ZTfd;|PAl>_*PPK~O#7?xa;FcN_rkNy^ zg2emUF62`>DtEtEB(Ah4F@ylI_{eGo!t++!K@euj~+k3 zKku4sK4w9vrE^1;gi#8ATed0NmJMZZWoKkdvSrzM*`hRfrz>mfZ%#Wo+sa97luo}D z!G4w}VJs-V?cXo?kDp4e2h1Y1hRqY4EeW`VQowG2R z#*@5Ev=>fG-IluHTQA5wqaw;^R9m;EKgY&bEg+UY9vk~A{xTV7zFvA;&nxJ5G%0$^Oj%%N0;cz1<^yKJ zVEPDV#$aYUkfCpwp0dF73BT!q>wdn8dj4UBEuK5#M}JvQ_<{dIO3e#8cf|E&7nP6i z2TXn7(-o%vzHm=F8u0k%wG)p%{zdKh;n#)nt;n4Fv3*H+pcC(+ciEkCYubt79W-o# zSu2XXp`AGNZ$WConf``n+{+Cqp&iJ`X~uh7!sO(B&xN@Mvm+0fx|y9}{LHS7nVn(k zV0J9t2QwQMn0(BJoQ9cA9Wxv76MbRm+Wq1F2r+{fdU7ZJpQ#s2Zx>|LYyPu3Q?KE3 zI#cgR+T8hyj2L>-tNL_RXTA;UK;QW5H6ERw6sVzJ@o%*AE^#Ai4YaRTxUU@_bugow zGWv9=IO^bc0FL@u@7+nSeOG6E7|Z(cOZAg`T}BME{#kMNDxP^;?e}%IJK_Ib#qvW- tjrgr64|Rs8CsyxMotdN6%kL4K)w`vMF<1J@nVF))nLZN#SJiLI{s9Pdg3|y1 literal 0 HcmV?d00001 diff --git a/shaders/slang/deferredshadows/mrt.vert.spv b/shaders/slang/deferredshadows/mrt.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..92230a266397e3e5b3f4ddb9320d9a0fa54d991f GIT binary patch literal 4752 zcmaKu*>hA?5XLWr3@8XfWKj_VK}E#~5)oyQMFfOEkj;I#kO2pixnVLuP?W`e=gnPl z-}fqc@I_K(s-%i4s_>8T#VWtwo$jH_ha9TsbbqH$f2Wrj(loMdbTVp0k|cAIzxBzQ zn2b!;Ppt2pj7U+Zq~xP2aeORkU9XKz}rVB91blnhDE zO3q2nOD;&pOGJ@eA(FVce}_+qO&1{fJe^ zR%Ja|Raha9UB@iE{QvbR*JE2RtPfwQC zItDt5irSg(%c?5D{0>#1AO`$d-DxdlZ%!^vuGd~%QLUzji*?uH!P0I8Tarhb+p%mx z{Vsm2i+7uoS+cjS++-K=E94k{ebsEA0+lmW7jAs1QE%2=A~DD4!NGFrkhaEsI#sUp z*V4-F5>;$gjp@&UU77SziJp|ydi(MMH>>*eOjW5K?#jxQT31?4dzD4CRvPG3ciS7q zBwuCN;N1q~%nzc%%%4@WCZ2Ymun2kU7C1%6dD*H0+ z#Ni$`wa3N}yTxqcOqP9Rj@NxSzuL~hId8RdZR%^?|2pZsXSzOTYljPLhTh($9n5{_ zNawBi(rbLd@TJ#aGn64U=dKH9yyr&k5fbj7(M~=d?@zO-C+B~eO}!V(rXPIoxQ|Ug_};lqKlt87 zo9|t;`QEurfB4=-+vkt?)Qg$s{n%%;4@!75Ht!t@Ht%JI<2f@NZDu&y%rN#seII!T zTr9AEWKqkd`lLqVB;=1xO(salADfy@l90dKlckft+f${JKQ=RYm4y7=zD7FvpU_)4 zzg7Z<-x1wu)jm@KzCu3C&s+&LVh+KWnOh~`%n}%LGhYJEefY@dHVOD~`Cu=QkRv$v zn6En|#3vT_+O#i{fNz!$-;X;D)0Shzx=RAi!mprxu>_pu*b?br)ZVeBhS3YhmKjE0 zz~H!B0!O^N+;DA;yDJQfek%=&9IFhA9QO!=Bl@kD4bJlS-76g|a;z~d-d$^0a?<7Zvc>BmY5 z`M~FAo2Ap2RTA=omot8cwn*S4HZkz^nc60unc}y}XKK52aB^j)c1XZj-tPybgR{IQ z4@w7TIrflruvn*u4U2Vp#4xWrb$V0+N4)!(;o2G;MZ==sPQxNcYFOmhB@B+}w_7$i z%k$`#4i-5|hQ+&k42v9lg~8z%GxfLxoaG#4>0ps#pJ9>X3B!oz{qK=Z{izS{C%&Kc zN~aIhi9F!(vx;>3u~R}m@cCILoxV^v@`9H$W~xsDC$Wivug_FfIy1Fj;xpAR9h_X5 zshR|g1xCLQNWfWMlY`R1S&ki&4i@V)U|6ivVZ*%ca6Bo2Bi?<=aBU5aBZfu4rwxl7 z&lnatjtYY#`W=%E&hk8tO9zV_Ck%^spEWFUJSPke$C#<-CEzUQctJW?sOpJNi@``Ihf=>v5l4|x3SRq6DDdXW!&e)gJl`a<2v3trBcsn;cN5}O$K zp0wF`LpuK_;^Wwx(!rTU$4*KI=Qq!1?=9(Z_TH8a#-dKl#XAykme=lG>EJBK-jfa% z>-oN6v7R3o=KX==LkS%5?nj1eYjB)0Ec$(HSmgM`u*mVLFgT*$XR^Urp2z3X!6L^O zhQ+&I8WuUe5(bB3%-+`$aF%m?BONSqd}~L@~>GXqokq>-+_LFq_LfyypKb0iP;;nW{Lbow-FH(#~D%|fJeTfpQ+DdiIq%zN=|0_kNuhJFC+X@)lH_#q3%`!1lFsBx z(49f+u`em`n72Hjyo4Kc4y>&g`ztK8kI&ICmm9hndY4 z_}znTy(0g*(Q`LuR@3Fx6cgN)aoV%373`izc&fRQR-5y+spdj$o%tfU_Mz+lvwO1j z)|(_f^LSJ-*_*tLe`UIww(ILR(pI~=SgYJwYE{$ndbu*uTAHrjZM9d@g|p>XT~9Id zCnQ;@rd4&39b7_J#@g-bMrGTz(#R5C%rXs^hsz_c>ubEej-B}4WE}i>{90|E#l(1{ zjn&Vw6I)C!f^Uw`gu>fBlXEoImWk`meC%;O^vqt`FVA!Jb_=^J`4~HGEIS46&dzYL z)@sz!_QrHL|7-Xa@$;MxBI4r#?+@7f;h8#|e-^EOSHRvKeH_kvkM!Ra@F-e;^G#CC z^KlGrt1M;&Tc1%xpV-s9&qVNvd1CK&dFIr}E}8{&HH*#P2**gZPL zzKQ()w*uacK0sH^H$d+TXzjyTJ?IkBN4$Ly+pk0X8dpN}?FYMWedLG2d@r{7j)UX* z$d$mZ#eDMOCjvHJf6vc+(cgD!EqVP<2CPr4H-POh-o2YE#@j37<&A$X;QV@r0vGe0 z1$z$e_bqe@am4vCZ2MuoQM7B3>u1;Ak5R-q?}ga4IOn~Pb8Z41_vzd?Sk9h$&icx^ z=F8|#L|%L~;5a`Su<_1c57_(%iJS@i9NOM{X8L`CHm|kBm4IENxEio~I0F6#ZBF;@ z{7>jY;KcU>wzn6+C(!*!N5F&VQ#tHe_}=2Y`@Dj^7_Wy zWo-Ro?l-XYk)LHJMf5qu{aDxe5jtxhW9?rLmxvN&L2QKuNM3FK&%!Y3RoTY@gBA{ zer4Uhky%8p7x|O=N6?OcsOOy6|5KP(ZC=+Qb}r_!*mljeYdZ-a_OfSH-@K+(JAXYx;)g5qWElq8AW3M_fk@ zTizk(d%1(iJ0iD;E!UCbJ`0?0GWyj6R|uSYy^B~QANzUWQIBGm0+;t|1TJ5r8Mu6n z7MwNme#>BaM_k_**mC(A?ZD+@R|1!>k-}Lca`tK!k$1!zYuIx68eax3Ut>LR=9{JS z_G$yM|MtiAn?KHdh3z@mC--5UIQKQS=V8CxkM-i*J#5d#zPT^!I_LNOTf~~?Hiy0s z!hQS>+dHX`Z+|!XN5nhkd)-9qqrHW8?ss!)T&G*zZ_s@vj b5E8!!a>gG+n@=r{--kZ%AJqI8Igk7Yxp(S) literal 0 HcmV?d00001 diff --git a/shaders/slang/deferredshadows/shadow.vert.spv b/shaders/slang/deferredshadows/shadow.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..eed17f3eb8db72555f19c69bd8689c05c30c1888 GIT binary patch literal 656 zcmYk2OH0E*6os!%w4%1P)+%l!Dn3ByQUuYh1QGHNBxn{{bSi0-3a->PsH=}`R)#vut9<(OUQ~6lcvR#`8s>E#o{KcR6brd{9P<8Y z%-` Of8Nx^-;b)g7JdQm7b%Va literal 0 HcmV?d00001 diff --git a/shaders/slang/descriptorbuffer/cube.frag.spv b/shaders/slang/descriptorbuffer/cube.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..1e7ca802907b045bd08b6b81802de91e0b99eebe GIT binary patch literal 756 zcmZ9K%}WAN6vbbDWLo)=p_vd`n;>WzK~#$ttpqpKG6u2`oKYrQv}@D<+$QMv8=Xy8 z?%a3Iz3!y`+$%}nz>iWjp(=+=YQD5vC{jaDm)^n3o|A}cm`TgabGse6_zC)_zS-#iY0c+>&-QY-Ha=*B` GB>w=XDKV}9 literal 0 HcmV?d00001 diff --git a/shaders/slang/descriptorbuffer/cube.vert.spv b/shaders/slang/descriptorbuffer/cube.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..bbc25b87d1cff6e515190c168358df535aa85098 GIT binary patch literal 3448 zcmaKu+jCS!5XOgGHeMnax%ptFAe00}BWOevfk4y*b;%;eyDo=hi5oY2;>k$}UgHh* zK}xBj3j9lbvC8jvwmbF{lj@!BZ+iNh`FgTRf8U{@G_WJ3bR_+)PsT{WB4qcXhp-Xyj`ZR;%)R z*u}h9$vT3oTx#_2`S%>7W)GXrJ9(kJ;dEG7v!0bjd-HOc7uiy)d99OY<>cmMQ(5(F zIWN}A#p9F5QmSbO`HaP^%$Nt$PEg|eMX0qU@a zdu_B^*IDO&=(2t_@71ZWT54%l?Rvi0>Ue4PgEKn$LUn2Oqp9{+xvULJJ@jpL%i=~O zZ+FW^R%9#9jaE^%HtXuf#I|VU(ue!x_C%}dK2-JVKDm|XoQb~w&zI6n8mRg>Dx5(~ z&xz54nBEbymzcg0^Qwr)HP>Y9n-z!mMgM~`hR0*Q zu&RmXUeopWn&hK@+)vDYzZdVF_sk%l-b5YHKkC5mgzK%wqEPD&AM&y_};K@3$O}T_2B+XdV71^huvM z6WFNEN}s?+wMI{fF}R=7%(=jck6O(7<)v&ntv|*9sj4(JH zL#wkgaE5bC$p?!Z=M0M+=MAG?LrS65v<&^xhx1e4*ItuPAJB<=Ov!xhb@}uIy|@p2 zzV?QE`hsrU3trY{G|$T5q&79k^*41vK5vTe4}Vi{$_MAJhGp;GYmUV&40T!5My! z59EVIjt>osdp|NPa(pZd4##*?pUA)&&he>yu*mV5VUeS081=mWSLCBV`fz^g`&uTS zKA;o#fXCOa%BLUb#eLxOwS~&p|2dku7rd;0(uBx`suaa>LNcIacMv5%+$n7@Xl8g?zA>w`N%6 zC=H7o>%!oOc^its8P0KCK3L?~G%W7DVOZq&N*ElD@ut3(fis-r8~I?7<6FZb$9INN z&-?$qeDp^j&QE<`+mcTo(20A%<7+?2ryuCWec)7w|!DnS>r06ZpVEDH+ V?=t_6<~`=$(>x;kS0_0s`wuLf2mt^9 literal 0 HcmV?d00001 diff --git a/shaders/slang/descriptorindexing/descriptorindexing.frag.spv b/shaders/slang/descriptorindexing/descriptorindexing.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..5f2ad97cf8165ba9ad4936996375c0f0456dc168 GIT binary patch literal 852 zcmZ9K-Ae*N6vZc9KPx{n6_Y~irKcVvh=LwMdI*HfdRvyYpEo027>FS?RHyQJ_pXAR?Mo~6J^DrE{x6dPY;xAvKU=hzF zHwY*GItZtxVzPEU+NvoTM>(UIc|k~FPjR3qDs~k$>8TeKS^c(^S(_7sCI}a+_-y2_ z<5lF}u?w}FU7OS%$C6o&-f^N_CY)p1nk>E9;?18(Q?`5iVH~{==Rp_`y~vxnuaP&M ziM-!<%$dCP^q(K-GB z>v>P~IM->>rJmuwh1ly#|J+6TJ;0oo_eTF4Rq@IGHF literal 0 HcmV?d00001 diff --git a/shaders/slang/descriptorindexing/descriptorindexing.vert.spv b/shaders/slang/descriptorindexing/descriptorindexing.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..1e80db21890aa3f750266f669487e54a6961b000 GIT binary patch literal 3188 zcmaKu>vL2^5XHxA9zMd$NVF^~mADEh8bu?b2m}`iD3L|Lw=UQ01ve&p`FeUHp={bznc%38&A)xrn8t;Wp8k~D$49e-nqU~WYyeYuG1=37PIA|T(7!E=3Y-} zR4b@wbh9eMj|iQSueVsr*E?1`YB)7(WwD$uRlPzTvIq6_u-VIRGVfTeL($DwgwY>b zta3E%OC9G$m%LwAMA3l1!ElX+Z6!mu$(JM9Ne_Fny({TFB za{4{4dGz4-mww36gZJe*dhotH=X?iboRNC?wqy9c1XZZQvRty$7ju{r$zGGPAcvl!4j-l0Y892i^-ct+~IZhZBIZhhJer+j*R;Og> zk3O8A{e5m;G53H@^Z}30omR|!pcnnX=X38X=3dZ^zTjo9C4WW+=e&$PsP#AXfnwei zzvup@&MF3{*QWe}42yA!~GC1Pej}4c5 z$Z^rISl2cza$GVja(p5Tj#zhDIXJ`nxS|*=a$GemuH`=f)J2ZZl*8c|Z|ZXyIKw%< zPz)A1zBDXyd}SE>`Tc*b82!3yf_Mq0^RHm3WH7WBq^_^mHdTq)t$-o$3+;>+7&Tvg~#o!Fbt}6zMI^8fV z>h!%~4SDD2DTX7iT~-dxaE>1ogT=ZP!y?D3VUeRR431b=C z=a$Z^v!_VfE6C`Nzu;r#6HbGH<859mZ6@c7(Min$N; zq96Et?q|i^3%b!4yv()af04n--t0l`Mg2=SF8`}+mziAM59e>&+xbl~HMeE=4ck%- p&c2TQu6Rp!P3G7iiowswPD;^jc`)L;@)H){liw@*TkOYV{{YXn;cfr` literal 0 HcmV?d00001 diff --git a/shaders/slang/descriptorsets/cube.frag.spv b/shaders/slang/descriptorsets/cube.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..2aaac7d787d7081a0d609b6f60489b83519e20c9 GIT binary patch literal 756 zcmZ9KJ4*vm5QVRK7!x%QBZ)B}i8g{@DT1hlg;gMpTFQb^0@+PiV_|3Gf3^|)zD>4q zmf5*;=FHr4?{2YhQVFGv5W;Eb^VV9S5Jc*snB}e;p&ClW0v<=x#KInah*$Alyb0fW z1uyb!6YVYY$eAXKkLCH@d^S%r%$^nY@W>KuGn@Gy#f#Y_&4{CD0bUCG)K~Zmc`e&_ zk}T8D@qC&r$59%^&#!6p76Xpf`kbep|M)%g)N_QZ&s;6$^36Tl5YOx8$GB$QbIaG- zbjcfLr(X4RSeL;Dco+UA(cBvykZ%#~5w~6=T6cfzJ4EZ^J=E5T*2U!HX0G*_+#t%c zza@x?IloP`-*0%v+jSQY;pflX ze#qSWnzv{6A9239XY^ljzPXy4xbvT2tI6*#CQlo)hj<5fmS_21V+X9|Tf0G#y2O4_ Hb&3B0rFAi_ literal 0 HcmV?d00001 diff --git a/shaders/slang/descriptorsets/cube.vert.spv b/shaders/slang/descriptorsets/cube.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..398cf230a562c626949edd858236577ad0f0f9e3 GIT binary patch literal 3332 zcmaKu>vI%U5XG-a*q}sX&olnv@IcGoXgMVZ~m+t(M1teRY(Y%6LeTPVtv zs&jPmNJ(Jb>NDb&%VHs)ueyb*ClB9H*IGBf z$+>fNkBUxCA=FHtR<9MFTgoTQ`zBamNRGDK*njJ)3dyEHHBfQzMvpfcX~8EWo@H@Imbj8Q)Dy!~48n znAKDyJ>z@M@mYTE9C~n5GUxaPZbOC^J>4f`IexYeYs|ak-LW|5jmFyOX{?R6>$Ppy z4Y|X<`t|nf-zA^g_R4lE->`P@km0R{2Ms@Jn0xP4)Z^O8NgVho!^G_r-c|Gcn8Sv5 zTa4p9!sK)8^*TPJGw$<@elrX12sf^~GYhzJ>pR$u`#dj9Ze{{LY?zp*g`3*RM}G7g z+HcEJ+Bi-8AM&W381SElz23hKQ|}3#(+~a@&=beJ8^`pA_vV;*-kW3Y%NyX%e2+de z=MG@>nR&#_+%flI=HO%M330gR=R4$c-!sZh zFJF{#UuH%OeSJv=e@QXSX2LjaHAgRBmcg@#qwhy#@GR$!%7>#4=Uy?6x}1B}IBJAL zV^W4j{Ps2DwQYWT%(xi$x^YqCxN%YA4RL71xHpC2S$@A0^5LS!TgJt2PZ}3BPKiUq zIeK+k2G4ShDfw_wYR-J(;x0nem^@epE=Mc>X?%G+1v7&2mPWR z^!)4{`OJmBQ5U+LHMLL6&?GlGi1jyhK|XJazZ3qZ-jxqetp~NgCxc`8yx*4(&+?wk z$cJY+cTqlE?9;4qu}>}Iyzlhsk_?Ub?FYtd+tj#hT#WnBxTrB_T-3NC4viT1kuW^V z>-bncT-5l)xcKd-#zl?K#G&CFZ|ZXyJj*q{kPjC%zBDdsw2dR5&;P1?`cHqjKl%ME zlg}LJ6Lp~DXV>I25Bfzt==s@v?d$(E+Nld&&UjND*;N_2$w92Ysa!s9YLCp{)OGpr z)XJN>A%kPVG4HQr@GS31S3W$;xdr)fu}@zc7yGnm9DQ<)CHZK?Z+pVi)@AT4*SIAgE^2&hT-5l^ zIP&@Yzn4${=@0iOzn}depE=Mc>OjZOew5EV=oj^%=Vw33XD;-Oy3pmUseMC+Cb`K$ z?5zIf+^YR&*@&68x*qP|vbXb#d}40P{xa@Y`S2To`%ON4Cvd;Zho6?6Qb+G-hr_?C VeboGW+IN_LU;CKsKi%ZG?0?S|`a1vs literal 0 HcmV?d00001 diff --git a/shaders/slang/displacement/base.frag.spv b/shaders/slang/displacement/base.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..128751c6eb34699abc8c703aa403c91b6585d5a3 GIT binary patch literal 1048 zcmZ9L%P#{_6vnT

-Ut-f5Mj327`4i6BB^Q#27QWujG+bf(R8EbLhL5B#w<65nrT zZX&LHJ@>rN`Q}QeYNIAIVvMPqE&Xz4P0C=IFgY_PdD*;eHilulvA4gAf7+xGQB1+) zO-A>W;5n|3eNEUD#)T=NAj~L-m{B3EzX?ftWYvQ>*B`uwjq85kIX$VeXQSNMes>?+ za#5|=)^xis;eF?c*nHG;=y-!(Cpho-`oWpszHoiFT;>ePcz4)N53Pih`$GUDu9*uJH)=dpg_i?>NXbok+o($D&*b*JB#YO&{x zKo0gv-LTCH{Lj<{{BYDtcw5jN|6hD4i+xK1yb?n{I9Unj-L2V#1K4T`w>fr!Y`IoNM8T| literal 0 HcmV?d00001 diff --git a/shaders/slang/displacement/base.vert.spv b/shaders/slang/displacement/base.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..b50c5a1ecbf079cd8be4cc5eda2d61ef35c18e61 GIT binary patch literal 804 zcmaKp%`e1I6veOUd|;R{Ch@h95eZ_FVI>m5(hA+Ml`gtyqODX3JAbx~#QD9xhn3fy z_MZFhJ@=zgYqw|ZIWs%3W4$>eYZ;z_MUG<+t?%rX-g%N0kbPk)90>zqMHmZ_9-_(X z=;1Cao?hx%Ts}Kr*Tpuzo3hH2N4Z@r`HlbXzVY>4jkKt%_qfc8I!>x2e|Sx+I(@rV zC$k@cjxD-g{)u&>^u!#$8fI74c71MBR0qyHaOQy18=PD?^EX>*IJ@|p&t5|Q*za`5 zZKu&(ligL!L|B(zPhWW3^Lfwt3*0YwPW_4avcB|29DLPt;-=zgZ3$){m)!5kLW?@^ zL(fD0%yaV3bdNs&jv9fplfbFRP69`tolt{#^w~+^=(7{}iT(k3%)-IfgnvZ)WJ$B{t&TSXJUA&>(&K|fY4X5JKtVJ8==NU!*?=@WfydPMt63a7$1+FCqP literal 0 HcmV?d00001 diff --git a/shaders/slang/displacement/displacement.tesc.spv b/shaders/slang/displacement/displacement.tesc.spv new file mode 100644 index 0000000000000000000000000000000000000000..593d7b1801529e16f5cddaa2a8f542bddffa23c4 GIT binary patch literal 3124 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/distancefieldfonts/bitmap.frag.spv b/shaders/slang/distancefieldfonts/bitmap.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..da5638c3a7bc8a162f1efde02bd0e4b6d09d2527 GIT binary patch literal 632 zcmZ9JOH0E*6os!z`mk!N)(0X;tDCM|iXe8=g{#tT)TInqCD0^gj0^v{8^QBU5)f}V zxpU5a%$=Dyy6RZ6Wo8pQ)*m~t$WZzg2hMt6T}$L6A#-U?pf4N=+rqwbiFJfn-;O+W zEq%n(eDhgeKR#(Gr5$QNT(()S{H$0PzS0x*F{|`f<@G}URbKk9Ws&CP(s`G?ym|MY zNu1Yn(2u?U>kpcky)S4kgERA3V77)|YK_4;Pm@2a?_nHHRMnhl-BQj-I8}aI9?t$F z@vc0*(a*GdPo6j$IgP=w^ZKsHqkb=_7VeM!199rPd*VZRUIqP5oc%Z>{ovGdMhs3q zXQJjtoycqEK>HS>_r3ni%=^&~&KvFu^m|s6J$WBA^00-n(GLY;fWCh*6=Mc+el)?Y F@C%Y5CH35QPWA#R3G8QY=Lb-~~ldG$M*X1Qom>LBzYJ76>sEuvAzqeDf#xbA7SO z^X>M)G}W2zGd+E}dnO^*IMnKz8k}>(?uR~+ZrA8QI$bXHvAbMbYB%b0C#vn@T#~L! ztI|$sw=}1}cCDOg)*pCnckdt>EyeqW5tm`B?`0~g!(Gr?UW}4@?QkWD>ru5*-rSC( zq;Oa$&&At|(Nd8vOuigDkKOq|dV^W5XJu1oUfQepR;~C==ASU1I@u>T`#EV|{z#~Z`KvrC4B93^2zsmFLz%TjQ}bG(%e z7ILf@7IM5ZjC}t7S7pyinGf}6`Lp-NKjb+nbE1!oC)@iVpZj25^po*rdmrUeUc9+xyeE7l76+?wSJa%m}*J;q5hKnR(z3748O&H4ErV98#qVd?0m|oLq+NHNi8h+3OAC}}KWl6uJPx1IWB%XfV+R2~MNie_O+V}r! zd!|cxw6~+!w4O=w2F=z{oZCv;&Zt-F9{P<|y%w#8^)Ql|)VO?xR}=fH>}qfrpZYyB zCFQh6kGUhgQu5;{INprI$lt3~cI%-Z=a2IhB`x^}VI(T%@?s*ZY{avwe#{kwWW=N~ zTPqutzj4_F!{3U+gW9_|2*niViG_?&5r~Z++WAHQtwb zmWx?fpR#+&9FBIvM1L;ddkOfO_R~9eC3C7Z z7d1m>JSt&fGly{r_j2}xbQbnq?O92mWKG>T4ku-^it5jCfFGUZ{0<{OSV7`2dIUR3 zVV=c4r!aUT?u&$;c(3%#a(23B-m<&nfS926xcVeF`mnT&_OV3Tll$?u!A6w-yw!;x zlijHuKREu2+KHuq{BT2F@GFYGq#ZvPF>YbAuBrZjcH%fc1gHf@{t@k*=ibx$N9X=p zOGC1!rHo0)hadZ%g!t?FXJ+I88&xf41~zKnD>mZlke@#8Yo}jkh&^L%{Dbm5(C+%l zOJ}+IPo=|`^Dp2uCri%1BFpi$YIW*UXG1$@vFByOC-0Q|VZ#sal!Z;7yaDoIbDo)# z5~@!Xt5h9tVgemb2lY?&*vnZA%;9<^}suvk`Uu$S*K=X&r0Bi z+0#F{$N~OU7BhTkF=qH(-Coen`lWb$JrchA@W#HV82F(UI($+8r~I5Hjx(-@XVU3` zH{p7imk#cD;QPiK0e9GfWnFa9+N+z{t@D_9-g@TYl$KgZF!^bTv2t0dt} VS-I);wZ(`dH*X&7x4L{H`2!}qnJ@qV literal 0 HcmV?d00001 diff --git a/shaders/slang/distancefieldfonts/sdf.vert.spv b/shaders/slang/distancefieldfonts/sdf.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..931059c77b292858f9d03887c9e342d4b0aaa965 GIT binary patch literal 2440 zcmYk8TTc{05QSS7!2p6t6r+e-yr3w8BBBT^pn?}<5fSg30Tx^WJ7gIQzVQ=y@W=XM z;`wH(p_|lpozvBQs;YZ8Yfb(N6JKshX4y=GDo8vrgva+2X|<$lbw^z z=?veOUSYM*aLSMa5>|S0*=~=`y(SK-bJ^J;c-s}Q@kdh zH^N|@_v349v$xlszNDbP=M!5Hm@tThJ_8S+*-8C-MxMy6bF(3|& zFz&uEJj3TVC?77=7&0#0`@pzR^lDT_ z|LG6;bG~1DBAZ0(aU z_d?&OE7Q&1)MsHdIh!+xUC^&qqvkKNCNoWGJ>*}o--@sDiQ%{S$hhzF;W^iHKjg#n VekatuHO+ANo0?l>|8)AO>_3w9)B#6KNNP@Fi;;}z3IXKr{{YW`D*RsHX(+@c3 zhI1A;`{A4cPKV*tUK1F`pJ;9S>9fV3QWW%B*4^A^R_j4&Rbfu?%9`QitBT*#%pP>? z!&KY(THIK&REdSDb4t?e+E$ljren#+0UI>*PAuxVHkgru|FS- zZ{&QRcw9hgBhHRE_0wbW!>N}Z_j7vO&*`yo>Z8XD_7k6;l4DEN;b-SWyA`AMUA^fU zcbWWfdc>V3zwt4x$!~l@Yx2YC$+STJZ;Hm5xRYqaWmKdScV6IMJQT=b`eL6>Y}1$e zbZYqR>*KDlr=kqReJo`ExMpnRxzV}#E>+LXAFU?fzbaG(zFpJTxS}<7gT;9&jXcyu zUgA6xEDm9C)5XQf*h*WDuToSA;bwR-jS`kG`0kx=<9>mt2a%d0b)V8Odo|fVQ1YF`0 z#dxD$7$O?ixWpyis29el7`?#dLJ~=ALejqgZcKcBUuWusi%#?Ooq67QXXc%E`lS`+ zO>>gUvLs0sC#UoqsY}Wen6s0L)JCtBg_H|J+59kiqi{?(E=&q1ged{fbAJ$K?o1&+T*_pN*`c2C zT(Oj!=uqdH)5}z;EA(s@znNy>OK)fK?N%w>xnAx!FMWeqd^hI%cb0Ib7wJ7_YD<## zq%wV@dgVi~c}r~ifX%yLa~2!DTEK6EVtUV;WFzhB4}HX+eRRb4og+S6o8TO0;PwgR zqR#+vd(pI++RP*KhOp0U#=A_K?RTNC@h;3Sc7-rs730?^3mg4>Y239zxIppeXvMBH z`wX+GoBg?FbG||LSz3t$kA1G$oLeCKyp*5zSz`7A^Kttk*@)YhNGJb7{ib$mf~!}p zyaimn^&K1FL;eP>)XJM+(@Si8E|lG>6<^|$kGpOal4Rc+&%aj|XYfC)mAi3Y_y1Ws zvQ($pJ0ie2$a_>aF}$w7q!YvKzs;sk`2S-z@m9&EuY6m|g3Ua-O`n-tw;QB43gqNG z`IsGYVv~>AahrUTr`gO-+@CVLOe}pmDXdW6$w?jr|5LK)=W6|?{u+VW-L92R?bzJ6 zPN4R+inT~KOnjf*+%5=Rc_n5iuSJmNX-mJSzlbQu?O@J|tb#Pj#R zM>_qdKh#fr-@8{j??9ip2YGz&KIyy%{o+34^S%3}^Dgv_dy$ttX6gZfoWv#uzMcAN z&DHv#P-D=N-iP`#_N{nGIzC&4gU0nphbOLc+oZ!YzdoDWrMC(6jM?lJ;1D?ezWM}s z#Cw~Q4v#puLpogScfWDe>wY_p^YIFqiX)zLyzNT@JmU2olnxi;y=$2$qb(4!d|9-q7owxv@F6!|8L(+*2kkj|y6i0l3_HE^*5$8UT4j23Up>f>L<9#HZc+u}; z+3<+R`$Rfi^!wDf81FN2#B+{0_*{TTJl+@5;bOcmjq|hI_bY*TaSpzg&7G-}*zv8u zkbZ9e0>gn zl72*B-*f#UeUCxQOsoSoJHLwK9De+7byVwbLZh%(V4mpR?*hEX{lhqT#B21pe~QD0 kxUK5=F|FH7Kd!aT^hvGEFFq%me*gdg literal 0 HcmV?d00001 diff --git a/shaders/slang/dynamicuniformbuffer/base.frag.spv b/shaders/slang/dynamicuniformbuffer/base.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..81761f272281554e48e0a89c3020f6ed5432774d GIT binary patch literal 436 zcmZ9IO-sW-6h)tjX=~ML5$aAVZUn)l6pFfV;Y!FqkStmWm_$NcxbtVb5j-cho6hj& zy?fus+?h1F8pi%!L|n&|(>0AGWG0dJ*!UzU!zWl(l(mToc7UByCqKke_95P$jBUQG zKR&zLr{=wBVa9#ms_xpayeaE0FWRDdUAM(s1^Kd>oyDM^xywJJ!kHJCORSD9KHF%& z?3MiMm=R~x%&~Lo2Y9isn}bJq^~#$c<^-`9`FDF literal 0 HcmV?d00001 diff --git a/shaders/slang/dynamicuniformbuffer/base.vert.spv b/shaders/slang/dynamicuniformbuffer/base.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..dceceb819e89708601e0999eb24a71f4ed9e5708 GIT binary patch literal 3068 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/geometryshader/base.vert.spv b/shaders/slang/geometryshader/base.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..9f78b1f8546041bd275417d9a0b5798d34686846 GIT binary patch literal 636 zcmaKpPfNo<5XHwNZT;I)3Ti!QZ9NErM=6N)=*c$UpyZH4z$6k=(VHLJi{Sfhvg*kV zv%7ER&6}A`7|ePWZJF7nU1(tjnIA7QC8sD<4^5jWwF?XF-TGZ8hTxLZbCsmTKU(>2i-yT)15$H&rdjIf# zM5#}&zZzx_7P+2IDXImgZ!kTBndxtwdOkjC-{ss*+THc8ht* ziM;zdsfGVa819M8?Bkv|wcw%yp0*hNtuXn#D;gd%gU94E0~*B1X9n<%-UJ@+!ov3{ wM6Y++sloq4-{ZdS=&uwdek_B7vAkX^ZF(Nd;4srd73c*Yclto@OIdT-H#2iJ82|tP literal 0 HcmV?d00001 diff --git a/shaders/slang/geometryshader/mesh.frag.spv b/shaders/slang/geometryshader/mesh.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..6cbde14f0730b6638a4f3556ce7209ba60435a58 GIT binary patch literal 1196 zcmZ9L+b?5L7{#|%i>kX}1~Y2hFKIj=lZZh?ymUqrNnhoJ4kzhFjw9j;4_@cVpT+;< zMPmJS&zCf|te$VJ@47G2so5^q+2Nd9az*{JhFr>_^t!BU=Z;DzrQ&sbUfkGR$KUVL ze0 z(hr)oX5?e3*U~Cs^|n$y^RZdqqotR^i_6$MsPRMo>#OS7O)ZFIO3C^8s*O0hD>uVN zTn?h3e)=y8F6t8hBzs^k=KZW6X}8QvT^5|Zz}XL+8R6u^**~09gL6KXKcXn|X8ftN zYK+OwNGk~AiqGl`C%+)xtuHy~tK#^+3M}K_J$u+UUhsTxcTHL3O$%rSi<_19`tq`4 zaX-b;49v4APEYRL@|I;g_pr-+E3%lCxNULf<;%Olnem%!{06HtA&oxFL|^Jm3RVX{ zb<8)F_|S>t-TYS;^YTV{C&WA^+Kg=81pSY7v&78_oH1b8{X8W(^U}y8&gv}4MyE$v Wal94wiOyU4t()b}(cV?@m+%1u;1*5XRrOOCc$O6}%)G+)^(nSV1eI2((2lDy54^y}Mc3rEG2c*6mv;Ua(s6 ze!(wZ5@U#{iQ)%8NFoVIll}$x-}uGE=lAYRne;=anLRVl%$euRoU;op&7G^0LQ|3? zTathDiL@up3COynCHJw{%R`!_6P4N|cBk}`^s@AdbV0f(y-s?)^ag2*{@S!sW0n4h z)h4HAvaV7(onx(eZUZ}%)+Z|Cg7aMVH}L)Gcv=^>Ho09`d7zTjYqLkPv|bslmXD98 zm8^TVyR58%%2-;T&PH~0Z%>j|?I0f+sbm#a&ag@A(Z0d*wY=6GBR*A6$Ew3wEmeo? zCzrENq$5=hwo3ib_sp?Wc3a+ibuz1;E~T}}tW>F2CdwzP^{hHOpec1NHAF5mS|PX5 zWX{o+&vJ#_p<4CSP<5E|wB<8jA@^Wy^h8E7y>oxp&X*+pNg=-z`b6-#JMSBxd%$Ne zeo9*-w4$9S(fzbMMjT-lM;;%wIIWNm=xLRk~B}5>9v!_Wvu7 z{`csUet2t~9iM*q1?24Rx69`2y{g5$@04~*xl?kO{asSYFOmhZ5Z`RniR8oOv?P3 z59g=8$M(qP9+(q-z~iyKvbhiDML+O)Y@clIg}Koeyu^C6_DbQTHZ{ogH`OP*Q@T;= zZ)(46aC$9jeOwBL_?PUU19PGecs%y9Z0>`3(GPqcdqp<)!rbT!USd63 zUzNg1ZEBEv&VCDCliemI$FZ_(@Ls9Evx@9KDg76<9+QG0V0>4GrQnFqX+$bDWS3N8DSJ4~{s;m~60^_qt(`W8ARFF(C|&m^UdO9C40RHdy4C zGA!J}L7lYJE>SCq=+`hwn?l5uf9{Y;eS}4`hRJ7RSyS)*P@84fDH# z<0B~?aqq{5YgwxIiD5DCQ^O+1XNE{2&`n6rm5!?eQOF z!;2!zZL4srjFnc1iyS D{g*;G literal 0 HcmV?d00001 diff --git a/shaders/slang/geometryshader/normaldebug.geom.spv b/shaders/slang/geometryshader/normaldebug.geom.spv new file mode 100644 index 0000000000000000000000000000000000000000..dd1ba7a6fe4ff69befadc03a2380a990b998f860 GIT binary patch literal 4768 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/gltfscenerendering/scene.frag.spv b/shaders/slang/gltfscenerendering/scene.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..e36d3923c42128c6578b4a24ceb6664366726f9b GIT binary patch literal 2320 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/graphicspipelinelibrary/shared.vert.spv b/shaders/slang/graphicspipelinelibrary/shared.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..c5f078105afa293b0bf5372c0a2775e4bbd6b254 GIT binary patch literal 4516 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/hdr/bloom.frag.spv b/shaders/slang/hdr/bloom.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..d94bf4b813dca84e6532bde7eae79b935c71791f GIT binary patch literal 2632 zcmZXV&2N-d6o=n_mjW$N3TRQM#o7j&2C7!HR8mEaP|_BIP5ht?ouM7=bm}k^{8$Vs z#>4~@!p>DUEZ7*Mi5s{44gLwP-T0N5_&o32`#QnfoSyUh-E+@5_uPBmX=^>wm9)1c zNivq);=f~W(wa;L?M!ddCY@;aCEZCox)mwsOB<->5x>%f-F zSO0JKz}K!e_-1=Id?~E`&u%A2lB`tLD}*BM!?+`@qqMPktu}GtEnL#vqv%4Zirtyk zdo^F)TrXB%G0gE0=Q(t#oL?;ld;+~yTzRwfaWT#F0(kj)sZd)pW=HZOcx5>KY;4?5GHKOEzA{PyD4iFjsW&**W)A+|4`k3;NP4k2<84`VyTo^xE^Pgebg z(vxniIe^^(mrJER&F#6%9b|oXu)QNW@D8-|@&jP+OAaxv^SjW_%e%f8Z7lcWd>`6* z`KQ79?L!_x4ujpl{&M>FqxF{;A3?Vu=HJhLM$nTX&M3Ac#vQ}fS8U9qNRre~#rcU8 zn|nuc3|k-l-D@0T#~^+3-sxu@&qy-l?86i~hdA8#^JqC^#r$Wm?|plEI^sF7W1Jn@ zk9kC{ST9>t$-<;+#w(*Ri7Rx)YpZ>0My>X0ZT;osEPw$ZL%Ci-FmcAp0 z*nazN?0MXO9sB26|I8G(#C7qG=<_GY`|VoaZdVYo@1>^+@51)msE_k~=siu?`@TQm z8RomOhY{<&Pwo-)Q^+VXhWtU52hond@ptY3GJsf@`XzkKcNF;xPJie0GskiCBw`N= z;A3dNt#Yg6^e+2tm772o;ik}jU*#Q}tn*&_jg^nJ-^6zR=jn`l`3%uV-VtN@9X6J| zjj{X|%g41}V9OapKlf#9dE=P>RKU(hZZ>eJd#Y6&Vg< zY=?U^=WB@ly%l1=5x6>f0nYVjkvYV<&jWW3+qlkIgZIMzYI`T<5$idG_Po@;lk+k3 z5aMv&Z>RHW@uLB&#e)H>t$8PU5i#HQ)G~rTAGm#J?^OKF@J=}=K8%=0ZCvXRI~U`= zjcwdY=*>IWaV#}RDVsGBVwl~hjo?gVZr?*3|{B6}w{$}7VVcSFJT<1N`Bi`dB z?prVVa^NnZ9ro7uRYYcq<9n?ka@HC1UkkkXjkARqOI{zj>xk!MJ>naI)7Snyfwn(t zaV}uBF+7J)5c^dphWOLK`L^Sokc)T19LDnejja~PJK~wd`YvEwpKF)U;(vHKCy;*u D*cjK` literal 0 HcmV?d00001 diff --git a/shaders/slang/hdr/bloom.vert.spv b/shaders/slang/hdr/bloom.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..ef2e0e8e768ca4ffa3d9dab796da2d49479328dd GIT binary patch literal 832 zcmYk4NlODk5QWPu#x*fUjXR@34H`u+;)2UfL4>*JRpu~<91>+1M8SjT-Crg6m%IqR zucrs?@OtXKuCA(ilVYJ&vC@E{B*4fJ2$s3udJ?Sf4bR)m0Ue)U1}aU zJ>Z)HoZfI2oH>>qGi#_KGpx9YvUz3{4@wJ!rt&L#!b_eHdCn};QmGvX)Ct7LeT>fe zq|>!&ZTb8u#pJ^|pA)DDr&mkRI?wrnO&3=A{3w=gfI5&OCTdzntSy z&bg0A)Zm=^cm(h0>rm%VUAy%3EV^f@Y<@^TYA2G hZCx=s?;olg9&ZTfd;|PAl>_*PPKN%Z9-`L2AZT5=tEtZz?| zzLq}nX}%fOs@63`#M+``P$)Q{?Wn1qR{c}}!$sb(xcm0nvB%>HBH zt|D{8pK14=B6&D!8UthJ^<7a%|3P3a+#mV_Vfwjy@<)oi3jAD{{g@FwF#XJkfvIOE tdS+6ht~m$Xj}Y3o`g3O94?Qq%xGzWVMOpUbec-6W?xc)9{6^|G@?RIoCsqIe literal 0 HcmV?d00001 diff --git a/shaders/slang/hdr/composition.vert.spv b/shaders/slang/hdr/composition.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..ef2e0e8e768ca4ffa3d9dab796da2d49479328dd GIT binary patch literal 832 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/imgui/scene.frag.spv b/shaders/slang/imgui/scene.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..4704b77eb741f593009fe7cdba71334b904d7568 GIT binary patch literal 1080 zcmZ9LNlODk5QW>sM2&IZ_qd`c!Gnq*Zisk^5)g8gL8A_2k#R&kseizeKh}%j`#Mt) z9C?{~uhy;})2Zby*V*BmTX!4!4dOY`zE11{$} zWv7IC5H`@)gdU++=o1EnLFEwBC8YI-j~*HIAU13~y~M?gPqqS7-yrlp@XYt6{V zQm>^|!s=_Kdh27ezDG+hg%6LhcTi(a{^zIa?Mp3)WJ<~T`KpaLdMh`>MqCb}pnh{7 z1rK$Jm&qBJi+TU+7dkET&QnYeoU_0=51bj{$*%@gC zVM6g)z2W2+#Jlw-2Ypi<-=x4}eAcs%Q{xMspB!%~i#+XO!_i;?$ zRawkH+<`cAunT4}Zue@OU9|hzg>mY!3u^AEGdertLHiM7mP7qAGv5yVjOS$2&v;%o z{fzg^re8ie^Pp_L=W~HtrVqF22H)(6vkiLQb>v{62%y;ZE-=-Dq0ampar$46b2F89maMjgKghB3{c#tg8PPF zToPl5sBz!dFN%pVMsXqf!4HzqgoK2@06&=c{N6dIoYbUe^2|Nwx#!;Jo^x*}P+K#5 zQc^b|Ns>9qKl;XIBsB@l)TB0x@uw-mYJ~nmX#l@PI4Fz=hlL};QQ-t(nlMAC)u%xt zdrZ`axzfPkmP%_b-JEgtS#FhEnU?zteWJ5m)>rvuX0)d2^*_UfV@UQm+-{V?BjRfsr$uu5snjRmggBIeUNFQ{-Uv`oPhLzEbbTO0^7S)@J?Ka#t$9E;+#b=v+hAqvAlNygiqe z1}eEixzL~AS}a$JLtW}->uBK<)h&8CPHwds$|0AYkCVHuRNS_%*j>%#ZpO)7K{+JT zBkDVTz9i{XP28RLlbAaura#2o7cpyz&(K&eOc$1GPhUG*G1jS`c`upA$9_J?a1 zoI?X{SU{^qW3zyH42KaP)W|!;h(|Q~d5GzGtcAYDTId~dtuRv+a;9cQ#P}!6qt+&2 zmiC*Zk+{y{$rh8}BzB5M*1?~o_{5B_a&s-7X*nLxQcT?*pDG{oxJf>Gr|FyCbA~3N zQD@`qaE;byVo=Sg%X-J&+yUpKx5VU}qIii$a@ij}YRd~rGQ5QOz4EAqdDidO$a>%Z zZ~4^j@ga*@vrzf;gZD*GJm!7HnD^yzv-}nT4f5HaJ4S=}kj9ZQ@!>J?kufoM%=!uX zroLmseDw=WbTH)xb_0$HH@xpH7@2| zXk66L&v3S9)R-p@jhJ__VtCBYcZqzssL^IzTzjc;QDeS1G@PSXmkIEgYb=lt7d0+7 zE^1t19Q)Os%v7R%>e=o@vR%N&1y z?E;$Y%^u|Xo9d9?BJi8xZ)#~aU#*olwM>A+{JyV}5080Iu9gpvId_eGxY(yo<7z_Q za^t-3^yyjwjkxwY<28(GTyI>=TVY((=rS&9tQ3bv%v+@x9`ibK^5LS!YUASC8;pw@ zYs8`99B=AI0UmRWwesPj#yaDo#!betpWpw@^65YQ;r#6HbGOLn9_SNwpyPA5%I7}l z7xkd$bGOOoUg#Tjq01a^>UIH5_GS-qSLs)6vc@}v27`vI9?qY$--;kfWzQ;H$?#+^WJWd505$5D<3ZQd!uo&-zDSdw`**Y zk49X3w_%=k7xkd$bN9>V zUg#Tjq01a^^8o=(_GS-q{p~#{pSKy`-VVj^tn+s^EWbmbe%{$b!mxnB@y;F=;4$yh zPWkYdbGzij#oj$)TH538b&pqFfQgjX1p5V#-S=-UDu2FLq(M}Wut9^aJ@k2&|Ad^j|md*8Tt zw;vc6@AgA+XvDQ2DTc>f{{E`JI0+A5DN! z2j}+rALOG8u(9($irZ(<@W1(=#Gwx`U+-`9XK|bX9rhxhe=F|S_>0gY%o2Emysuvc zct787#=&F0zrXX}#gT)KuQ?ze9$>!4=l>A5!w~0p>RgjW{3)tlK;& fzaZd`Xyoq-|FFjC<{#0>8u+6c+4EnWWP$J>J`$M~ literal 0 HcmV?d00001 diff --git a/shaders/slang/imgui/ui.frag.spv b/shaders/slang/imgui/ui.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..f00548567b31c7cd83fb7954300920588be06255 GIT binary patch literal 700 zcmZ9K%}c{T5XHxQw6q&Cbl*-NeyZ+mbCaJGVoq$Sr+x9%h#&~Tw)_}A0EF6cm2#oQCDB{ zGAru2t6cuNtlWDp@?oPbwU*cNpTAc>w4BH>Fgn0!1*2gm#{xcWpvUYv)Q>i2HS;@e zdW`j*YRyzWQNNZVn6sG*Z!0njo_tr4Jm*V(SCKsYk<|7S$-~hj7#KU&yuKpqs2@Vg z;J{-=Zjyf2!p!Fks0TBTGYFV^&Hy7%J$t6drIfHP=z#kXLi>&0?1}rQKbV>P2lNM{ iX&|Tni&m58e&MLYzBL2>Ku#_BTTMp;+^-Z|$^QWB7cKk% literal 0 HcmV?d00001 diff --git a/shaders/slang/imgui/ui.vert.spv b/shaders/slang/imgui/ui.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..d93356a3fa42f933867b65ff5536bfa15f993a49 GIT binary patch literal 1140 zcmaKq%}?7v5XGnYrXQgpExlB!L;8^xDWIlGD^-9{RnbeOT*@`FAcsi7u55$a8yxtb zxghoZ*1IC&(6z>%_hx7I&8(}HLDOmv%xq|%^=5UfVlZv1I*h+=kDXu9`z&50fJn9@ z8_OoLC$e?fhODaRk-p^C^$=Smzt4-&G|fH7-je%uEZ6NLx8%O1%QO?$vYxo_Ns;}X zri-MQ##wxp&+_8*(|Fe!+CiL^pTx_#z70KaoLyvbk}u-|zHUvYd48{!LW(_fecX%9 zF6LP=|MOEFkDSQ5x}w+r>??)4nsrUm?5>8{k=5KRf@Uyt2ztTH08H+Y<{11RE4>aB zV+D?0;aW0ka4*cC1?G-c&!mTNX4l_$-`!d{w@vvC?TKVBl;6}BT=ST7z-Wxb@^_#C z9^CPmyywDQ$CrDyJ$~l*1pHE%)l(d8)C%=p$zOA^vVPxV;^d>{y^Iy`2Zt^X&@+DvW;qQF;iNdkL6+xR-#@6UorTe(E!G&Hz)NnFmaqnS&>~N9r&;7Tk>x zv)$7hP23%N0&dGk511aF%FuJDT77-DWRZ*+hMa+X_-pN<=4%;s;X~dV`H_sf2zhVi p!(aKlck;=FpK8*aKa{~UbLPCSF6bW~pWe}oPv7XhRo7o+{{VzoT3-MF literal 0 HcmV?d00001 diff --git a/shaders/slang/indirectdraw/ground.frag.spv b/shaders/slang/indirectdraw/ground.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..e7f31fa712d166b503c7e23c675e71dd90e33cb6 GIT binary patch literal 680 zcmZ9JOH0E*6os!z`mk!NR$E1o)@}sBr3j)fT(}amQI|4cl|Yk}7#HsR*=_{SH%UOe z;bi8V`<$6Dm~|{#F|%Xa(;wTiz)<=Ydd_}eU5m5^Lh6zXM_(8VtHP#Y@pXhy-#;$Pb^K0SW zQi*r<9Mq%tfBjYy)BBL(GB`6&1>zfiq&)`bJWc#iQJi7wPgI>}qMc+trbqa ziFj8lIq3W9-qVU7jhM#Z*g<_)#F4+@RrB{p{ed|7+&z4|=Df^_IKExM?CYBRk#_jV zyAWp{?tp%9>T?GeoOsSm&Y7zHofGX_Q`7rWf6m1FQV-4>uM5K4424@jw7jE*S|#El-cdwd5k>AQ-jG$qyDpQcZ^>wx&?FR=W%zF6h? zW)o<$l}U0sos&+_PHRi=j?lI(gm5k_>WOrOmH@IZv=%Y`{;;d?Tl8E`>MH~#X)3Kt z_eu{)TlL#5%bxA}f!9}7*Yf^K_RTQzn%MjcxysrTx@4;}N#3Y$%;i}l`I1&YFJ(zy z-Y8e6vZa}1F>8FwYgftxA+&1;`A99v6D(ZEWalSmt6O>P1;+YnBU?;A<@HRRx9dkP zJuYXpbZNbwewV*py_aOyK4$WF73WG<^2U!!R$s|0Nh4XVuBVMW-I&n?`ith_WhPsA z2-BghICr;jgqSlElS_PDwp|K-Up4$Zy^4`(^+J#2vyPAWx?`LHY+Op+l5CF@@%Usj zEMo49`$1Ue?!3=KVxwM9af{9Q9F|X?CFv36?~o;Kvv{Y)^jQ+RN0u7o5%0H{yiUa( z1>Vf*v-qIp5L5fGR5I!7N1Ji*n112!(vvyD1=g)znIl-Y)|eSFN-rm5=@Xo|$70rx zDjt!gmY?mdeEQ*E;Jtm2AHvTu_SfXG=4btCF=rjtIybSvElHU%`{{U5%2Gce6X0~s$ucoYlg)fWnpkQ#;mSO!4c;eln)kj z+%PQW7&44{6-|m+-IOwa=0pF~_qAK{xd-ONIpFcNVfow#^Wr@4`Pyyy+zWH#T=25S z|727OC$*_TuD?@b@=H?w*Zxk8%LnJIyi*g>aVg^WJt-d?@tI7?2S*&cBOffD(_O<_ zqP%;C`P`Y)v=okb?|s8%HaQ*`7Uw-QEarG*Sj_QQ7#wlljAC%a&+$Y)Sj;hNSiHAl zSj_QM7#xoAPCb)?BhE2b`2TY}H!S9uH;j6I|1acENtqA*Q{UHK%I6-K6X$@(*Ivoz zKA0EhfzQ`o%jaI08|Q+THQuQ=QaGti4RUAo<>EX1PP*GvrkEN1SL|EyUOqW|pMM)x el@Cr`#}?#+^Zt%%da3M!`E}V&>0ebJlKumma*Wvk literal 0 HcmV?d00001 diff --git a/shaders/slang/indirectdraw/indirectdraw.frag.spv b/shaders/slang/indirectdraw/indirectdraw.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..48fdacc84080affadfbd932c17b678277851be80 GIT binary patch literal 1348 zcmZ9MOHWim5QST221G_4f}o;CG%*;>_yR-`iK4O@b&L_0=Ej-9N#;Q=!-AbI+`96| z_|JSq6TffnZ9;5vZuL1;U0qc)6o#&hgyOLf!eZFs>zWEfL1ioqhg;aK>YHk1uV1e$ zElb0AC};*T6GRo+4}nh7>Z;Fzbub1_f(bAMCOK!^2q^HQ-+M~jz$ zhN71S=QDk?*Y2eQ&3u{mb~}q39^}uoYHR0Xf4lJ^%WExrNoTj+NFS$Za*)Lr!Un17lq#w`q{nw^4zIpU9Fv$?Ak=`f2^ zKO08FsoZZKYtp)+ohRQk+&Isl*2z*c{~Xr*);~jrdF*wV+6BPchw_Gq!Fq#-uFr_||qEl17T)+FW`2t`> zvR`sQa!_(ea#(Uia*AY{CelQe!+y4T}vYrC_(ImN6_dvLt%>fF#3g`Qm6gW70VF}m8a zNijdPHi?Vb4Y{uCd*f`tg9O={e^LNpWj?oG&Ep*ERHQyETqqr>gGEbyIgudI!hxU76po zF~ONWai_=jp?45XNbgaDcm|le45mk5?lqXTVD1f=7X#+LgC`i~?t?20^A5ln!@LP_ zmErB0u}zk&(5hk0jM=40IV#dKBR_V|kKuObs26UDgt|sFH%S;!`j7I?dSO!A*wonI=r{8jZt#w(0Qan!Qyz1I)UG zDH^jc5+;Y+m!|d|m&{d_)VV~$8U!1&+m;y)?QUx`o39Dit&=U}vC+SxW_m&Yy#5`A z>&0^Ks0pq?XEUrBu0b~L7#N`!J2lfsc^#JrOb^G-s{I{~-qEmIe{7;t|IabD!&zVls4uN?Ee7-GH;!Heb3 z%x4Jw1Jl!~68Z<`-p`QGKex}6PX8R&OQ(O18>G`eF!#MtLjSG+f3exmGp=2G zBY(4mobao~5o4Z&xQtpcaPuV#BN!x7hGdW@gNVJ8-6=KL?xmq@U4j?VuoeVGJ1=X$YzQxm-R z;d1Hpfq1^(<Mzc19s=HF`gLke&+v3 z=Ph_WN2RZmz%zUg*Gi{H#32W|ulZLxcGiY{=n}@)W2~3XI(XuQG0L=Xy*OfpeW(ym zAFz8Ls26^(-Uat`gM|A*Z=Bm`Jbv`6N_dk5p0P@=tXlI85_p6m_cXt+=@n)Tyszn# z4v#QSTvHIo8usC9V(IV*o!fr4p}aoAK;%sr+_n zzC|)3X_asvhc(|Sfv5l5HQ#2Oreo)LyYbFtq}(BaXZZWLQ#u^`bnY(WI2-5gHjduI zv4?vkhwhx&={wkM@?4)lqAkjHILN#{K1 z7yBWf+n$!rxzIQEMP6(*nxB!7li0+-*YDJ*^byG-iQlPbrH@M3D|hNS2^_=E`+4c` z4DZPc(%~7-y(k?n?9)reg?)P2IQrx{UXf0YaP6zY@C?uKnsm6(?{(wC9B&vG=6F*a zIYPg;gy9*U<8A41VUBl<3)jADT$tlMapZ80JN3QGYreP(ShA_K9@Pfj+Sh^0@6&>6{1sVn5__+h@`_7y8D&$cv3T^|^$c#3ly5{@L|~ z^lcJ+ocmHbJa^GQKfjiaAHrbY>~ojyUA5+KB>N=z@wWopcZT^pXTNmfq94#aX!=3T ZGfh9Fx!Lr?npuzk5zWLus;mno{{cX7%cKAR literal 0 HcmV?d00001 diff --git a/shaders/slang/indirectdraw/skysphere.frag.spv b/shaders/slang/indirectdraw/skysphere.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..626d22b4d83d1292cfabff3915667c47237a44a8 GIT binary patch literal 776 zcmZ9K-%0{e5XMiMT5A45)Ba~!P!vmGMG$Fs-WVCNT?MgF8(z4DZ5Po^5Is@P(kt`~ z-2{C<+au9gX3u;x-+a!@8jsaeW_-*Tvtics<`hlL5XqRNDd=u@&O6RSc>Hmp@)1gxPJ^C_d>2B>0#YX5DuQYcfBC& zdIPV24oIh*OhQ#ZT%6qhAxA z&`rO@w}i>%WI8SQWjVx{-{xoJKbM1+#k0b`?~m}D@aE;|2+s=}^U~VZme8xp(4Y=3 zd8@T3ztMPaTJC}{F?xcB(Kj>mh0r?`W)614EMW5N29DKUmGAqXO^fTouKRJkuL-GR zCmd?NgqZnAZ+64?MgL4(_K}Wa)V)TrDf#>cxvVPSn>5{Tw{pL^b=laFO z_t~D26Q_B5X5N`IGiT23wzZCSy7m_5+?Z?VAL)0k4yM<&Wj1=B>&o<2{U1iv8pe>Y zFC@Zw;eybnU$<8Fbm#|PtsR}D6Q$(XbHp{djZLYF>T%b#mWxqZuQooWNj>@&mv;}6 zC@nM!<(1^180{tXn2MfK>gd>Yr&xKY#uCbH(K%S_IA z=T=>Nc5ZSZ*qj-gn%FnA<^=dP<*@UN%0^bz3q6t>KRRN5{+ekva@`a z&e?eC@o#B`!=@K}vEba#1@i4l!)IsZrNHK_v+^?wo`2?n%`CWYv+0l7(<6TJaX;k1 zCLi~M-J*Z$^PEoWc_0V-5d6PoagI6t(+_t{ZEX7K6{x+Wz04smP@7p3!%T*SyzoIW z%ydM6L*U3eD!?Of^mJQ*M~u589j+zd?s|^CE$*J@ID^#~lTM9r?|s?ui0yqK9WIO; z_gq-xq36OHkHk?UjGK@Rk64Yz(&54ylb#FrPI)e@@kAUojAK?$1$e}26r{t2HJ*7c ztTF95@|AQO+{bf)`72Oz3Dh7Dv6gpRdbfv`fBSyvdqH120x|3_`R_`_^L$^4V@|sQJkQ*`rnT=mbiRvx K)BY&?jPMuA?TI}A literal 0 HcmV?d00001 diff --git a/shaders/slang/inlineuniformblocks/pbr.frag.spv b/shaders/slang/inlineuniformblocks/pbr.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..d5587b1246519f14bdff51fc6bdb5b14c53e1741 GIT binary patch literal 3524 zcmZvdS!`5g6vwZWDOf6tY%W*}6-6(65ikUsfHon7$7W~;95OSP3{%A?YYd4G z#3y%ADk=$yyQqmP>Vq3-;)aTexbNtjOJd^hH*-(D5^wYGch3K;_nhyxZIgPYB$H1_ zl4MEp8^3*KC6f}FX-Ru>66fkQ>(=ycYmD^vU37u==}DVM(`QD~kxWLO1ggbyO@1!u z0(-%UU>cZ7j6PF98$WW^C{RP6a&7Bqqjy7EuZ#?)+giLnE&i&sUM*Ho@$XD#a1O04 zHtOZ=>l$gjxVbd6sgf2OecStnu1G6ui(Aq<4Oy^v`^6H^~ z{o0$H_O11FOKG@KPI(*S^|jY(I#RNU;C!EJ%cbi$CO9WET&!mA(AJ#A=*E;RQ9Qt+b6XOz_S6rADz*DG%$@&eY9k5A~dG{mnVu z-E3^?g{FT2xmev;F4Y>%Ik=~4u~Dj*W4?uC5nR590=0I-4X2gVTI%Ef(L0*ECTIQn z!L(d!3>NFf>d+=uQ-xfc-3xbZzsK{d$>$xg7aw(ZukL%R&*W?eo>$UA?6e2nXEk@q zJ(*v-vQOB9GoRdY5S%e`V>zxZ;|_3I-#fh!_=LWwr8aBFF3hRyldmlowcSbhMeV6M zE^2q?IAhEg?{7YLDK`h$lk>{=sBVwe)$aEgGoH<)eKKb^&}V6;&qmh1fZz6Rj9eF4-Jx6;8Qqt9z#7){-JFs3$T<%= zdYYfv_3z5QF?;$ynD30t-}yzpGm(9?cXL|LcL6AE$r&^p8CK$VoDG`5Y>)M2dW?kRzXG_zxf-I=H4k^bP1oW(+KkdZXy}9`-Th zj>A3uk@p64xj^{sfJ>6`W}X7l&Za&#k#`rmeE2_reChu0mqp$^=yCzy_aSt5pue%cD)7mVYPPm3s{6yA)_&4BSn`JdW)ATKQWsPoPJP_Tyuo%wp^#>O7T; z(H=3+(Zx#i{lL8Pzq9pMIeq?Oj@q69PXq6Q=Q4b}2dluJaQbW0uaoH(IG+Xf>HG$O zyV!w6+v`BP2=0xH*B0EH$o4MWp|NiPeVtSIy^XA|Hg}`nK_H*^JA}R=vqkJX=<@pC zoW;J2Yz=LZ?>%Ju&F6a`U0y`K50K^krlRK$k&V+9ejgz_b8S)MFtWUU(aXok`e}>U zPmsMk`Pfg<<@2#eGCyq*`x&x1wXNWNyE#7x-t|!scl{``eE58Utj|0UK3^ishtF5Y z`pgF5^EI;kVD|Um8|0(FSZ%?7i|qFm@b3CI;5*IMEiHeTQOrhh;_2K0-0|A_3o zol)G!pODSt-wf?Lz%9JLHGT%>(Z^lL{Q}IXE&QI(c<)DWFCfc1*O>8($UA|13+^Rk zd3%a?ei>Ol;Lfdm0GL;M)OiK@05E5Ke{%Wn&+pK=o8vXG55#V6Lv}a$9p8>FA3k?v zKKUKr2`3*ucV#~L9p4QnAMbS!vbl}b7P0pt+rusp_v1cf`FPLW$i~axn9XAxS>AVY ipT6JyAoe+qyax>8Ka2B0puHbBtGyZbH~-x(0sjCo`c26I literal 0 HcmV?d00001 diff --git a/shaders/slang/inlineuniformblocks/pbr.vert.spv b/shaders/slang/inlineuniformblocks/pbr.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..a5d0dc60de90d2619703413812504d73b0097afe GIT binary patch literal 4052 zcmaKtS#y*{6o$X-SRx2WK*gBF1w~_!5wMgHNu`2I$RHx#=rANBHRDV^oJ>M+4X(K3 zzANsQdSR-hic1Usls8uSK3~omPvyc+o#}I))7@|P>7Gej>p)l1-jXEA*5ogJ($*!d z31m&umc{sMlhv8us?S=nJVVee8^UXU52%sHc_ERHK~g6wGHV`>dtYB{t!Vv(A@GC)G6> z6`3m5vO{#}jMQN6SgKXplRM>C(<#fXO72!XHq)q|%BSU-M!r}t)@IpIZpToz9(h`N ztYUMzvU-+Q%wbH2s!5GkO{O=eW#4t?bjN92Lp;}TJTLY0^KQ^e?6WU>)yp;Lme2WnWt%j=OFePB z#j7l4-@T%IdsqX$QSpY1FSBhHUm?c)E&8OstO@Ip7WIYoNQGJwyRjx38`X1W^1kLK z`RJ10te!mcHY?7lM*~g9v;SSPBw5^xCUx_*_sG9Q2J^M|%BQjRh{555VQW03=Lw|=Z<5{9TT_c zle1rx?bKUEgLP@-|5n7l_vn-T@ow0g$7|%Xw|g{~8eb`6Z`7VK)cYzK{Gi5gk5?O0 zmoe(FMFyuajy+u?gVUVxE@AA`*|o;lx3gYjoB@VLpA3ySx8JzB=G*~eaolyrqQ>>c zqQ(tkXvA?hDu&a1e_Q3lqQ*_e;@q2!MU8D@XgH%*x5(f$*SJ+aENToIiyF5XW4*j8 zMXiQp)W2WG{#oC1+vRf)12WEmj^}Qd&wWrY&V!!kcF6CQQ8&(oE;+u7cgWCWZPs9H z-tKLueBK@3&$GsM%ZD>>QZJLY$^RfYM&sO^leamN^~>KAzPtW@_ZdH}F|08vV;#7^ z-*Nfz{q9!`qxsvqS3aEP^}kO(oaXF)`LK8=4;W*wK5oL8-!XS`K!!$~J84{9b8g;P z9Cy%I)OgTX)Ho!DMjZE$VmQtBcUV3wYCLQ#&OKr*YCIx_2F%~aqw=X2=RxnH%yW;) zr*51J-IyyVrhc3c{g^wdm^yM!_Ce0y%9MOGF&gJ+m3h7-A6<;LGJjkQZH%@uUlu!R zrmmUiOcljX$k+oqti^bL+g17et}@2=QaxvMx6VUadpkPPaBKlo-r0Ro;4OV zo)beOj(c7)oaXymln;vfe;1$=a;JSbtM* z$>&Xt$^5tQZTWD{%A0ye2BZ0XpOp`%c}?Dx52rbMPd+Tx>3w6dP9GTay7Q(!l%Wyl zeq>x-Q{!V}aoi`yqQ?q z5dT4MG4cDIvlCAkGM$-kznPt#-IiSUOs~s#Ip=P>cltzzUALmtKJgaDd6(0tbNGX< z-{obyrAI+4l+n6#Po+1cSEWPZv)(Js>Fqeq}%F=Sx-s9EuNN-5HtVDBuZn> z1)tii6PHfK*?jI1J_4T@K4P))N7My%r;=Mv_qZs3Kv+>au6*vEn106;pOr02$(!`E zfP=(@L9Vi zb?#GnPHzmHS%PJCLY*-K_ysAwn3zxf>mG#5{o>6jUWm#t)#B)Ao zFKR5v;?uX)Se0)z>>RtoB;{r0Fi+kMb%{AQ?}Qq}^vSzGEau)3?(CIpkw8Ly;@3$; z4~3+sw~E=*bW!K)Qp}zRd;L_z?0+bF0Vw$+pIR@atYg=e%N-9(>6^P>Q6{syAO-&} z4);FlG0soj9$DnK_^k0=0;4w8>Ws_J*14n@jQ2tv?iHa9Yy6ghQ3ty!j(yjD3FADh z!DEkU*%>Kwt!ii9(oK(X=g)<4kNn1fBb<9ywj|};^a92kxGM$coYW`xo)r9xuXSHO z^}sDpKe0(3wJdL5KDfmXjrjQ75$n`NJ}6dXnD&Dkv1gfUCzW;0orzveNU!A7$F zpR?&X*|}{A183gsU6ZmuZ~vRe>K=#t*<%g);P7m2P5JC;YTTAE_^jL9_T__T=LVLY M8}IM0PQN7m2NmIlk^lez literal 0 HcmV?d00001 diff --git a/shaders/slang/inputattachments/attachmentread.vert.spv b/shaders/slang/inputattachments/attachmentread.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..36b0be4db436f365694877857bfac1b26854f5c9 GIT binary patch literal 728 zcmYk2xk^Jp7=_21s}YyPC?@V+je=XDjR@k>DTt6)ut;H{h=^ENi1t2};49e(e&1vU zyq7ccpELh5b81Dm9?GE*!d5t7^=pM9T(t(fCyh{xx^Xj%#<*a;yScrW?0_bi1U3F~ zc5{dM&3o=YKJ{O&WA;TTW1cye%#d3vw~yRi?l(gRd#%OJgT8Iz5wr?)$gi`@OEAki z#$EyID)>Z-)jelyJZB5LDZfK(zTES9;N9)N%x-_V=Xo~tJo9x(2ybVZZ$>_tzfG)z z-t(Ax@1s}F%UlmKH(w8|*~3HU?*nIuLo{=}kDqxzFyDW|>O1w%8JRbTo$*es=Tkt< zyjN;`^E6QZB1hg%n%;aTZ7%8h^FWEQ-Y*JJ%S#R2_N|HYXj@CPHR9mfCw literal 0 HcmV?d00001 diff --git a/shaders/slang/inputattachments/attachmentwrite.frag.spv b/shaders/slang/inputattachments/attachmentwrite.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..14f4a4f6de07991acc4bc97112ac88e3864485bf GIT binary patch literal 1332 zcmb`G+e%we5QdjIn0lzjLp}6pP%v2BNTaRRCQT9XCYC^f?j!J zU&9+8LZ7Dx5d6Qjoe+B6CF9KeGwYw(Gb`!TV$Nj-oO4C@LH{`uF6BT*+@O0by;u8G z3r^#MV0~ka_?Szhe9pKVav9kvNjq$Iz$=nz$&6%9l2<k zFbdmW4x{j>EpY$-8{y@f{>At7O?>-v2?w7!;PcJ+)Wv6t_{_`lr|xH8@RLgJ%*f6v zXTeKGm6KV5&FcPyG&Xz-@~5P!1wJjlXVNc)lk-BN^WOY|ch7qMlJ~1UzbL;{x~y3K ziu|7!^SyYG-0#Ip@^7xM%a*_C`seh<46at(jdhjZs# zz3`n+CEOu?C4@b&XK?oLOI;32bN;F)VndP#5_(5hlta%2$sb|l6C=-J?5saVj@4V1 zO+EHVy-{fn^@#CX1cMXXIN39t7DF57s%$vfJ)C3G95{(Rlz_pBZJc~FoEAeH=PTK8 z@_yjVOLO2PHZB2!6Wcfg*>GA6{X?^6UvDJrm^a8y*~ylKd0Ng}+2n!OmBCwlCjn>X O)ZvYR-RgyHO6~vw^K7I5 literal 0 HcmV?d00001 diff --git a/shaders/slang/inputattachments/attachmentwrite.vert.spv b/shaders/slang/inputattachments/attachmentwrite.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..804cdd5ce699fafde2f1b901ab8ba2a072caa4d5 GIT binary patch literal 3400 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 f1%Gei{Xe(4iC?3A;@83Jul)vglV literal 0 HcmV?d00001 diff --git a/shaders/slang/instancing/planet.frag.spv b/shaders/slang/instancing/planet.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..d0d62b0ec648bc1691157bce9c163f02d58e0f16 GIT binary patch literal 1580 zcmZ9M%TE(g6vnT8p-_2n^ralC1vF6DzM+*hjs=cvN}Y zkGnxfP<-CoB>d}sryqL`p9%NAk=PY{jD%}M;pax!^!E!sZo=21qfaBRARc)RgYKXc z#@_LMFp%$@yL7_0Jiad6^pVLY=k5x(qIP>c41F$-u^)uZaVLm%6gTbb4|}8dOT8cU zM)e>Lx*ywdaMTsKpZ19y=*9nhRWazrHJoXI=@Xb5Y=K#q<@thk?6|)SsRf7s746)oz773yzAACrG(D;^)eGW&;# zes5D%PzR44&V)R6g{hhN&xNU*S&_G4d(&X*W>%AWW;KbKm0{{+HZ1NFkJ%7&M^$2H z{et@~L=Rr*mz?>o$j9)s&g288_h%*KWBPfW$;a?HoyiAGua_j`^FiLJnQsFQKdicP zg1;gm7Bl#sa=a(((fvp{z9smQq?q=(tTS)%jfDJ-Uz^~`%lI1;Jo$f3Yrm;8cZ%{t zFK$WjTa}_WcbCBlvNN4)RGCTg)V2kdZULUz_Nw70pdn3#N{kDYsvHO;CJ1LJp Wo8c3k;hEt}y*S<-+#kKVUCCdo2WhAP literal 0 HcmV?d00001 diff --git a/shaders/slang/instancing/planet.vert.spv b/shaders/slang/instancing/planet.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..cb3103bad6224fcdabea0b43138ed671135054dd GIT binary patch literal 4728 zcmaKuS!|V65XV2-QqWdvWvLIQ0<9KBD`-U&fdWcVDO|+X-EwI!^R-`ANk;i1#~duIM;&dixP(+?^u znx-XHQ<5ZEkR&XU`lKRLXC#%G4PBRJVYCRN!kBPWI3^qyP6#suPRtZ$ z3zhn*(MqhT`eDB~v}0GfHJ9$pxa!P*oZFC=2J-`=Ghbqi^IhG}5p$edlMbXM`PC*( z;(9vsl*8Z6*A98|7My1v9r1nV$OqRhIL8^d5rJIH^gID^+v8!6if4`y>@ls}6~X4M zu)Q|^Ca}rFK7GfoG@HK_>?&cVyf`;cyX>RSkw)!vg$8*|(~6Bh_H?uH$3DYs^39cf zmR926hkcIO_|29*C*#L`7Mk54j`MDxFCB6F0_o&GPrsYBawoV(-IZR#HQGC11ANGT zp;ltgH(Otw%*N+j?O&%AU*dbdwbH2po7xLPl8mgx|By6ls}zWTSS#^8-`}?9_7Sta zAODz5KbGk{{o>n1KDU`Wx9K1A>Nft&tJ~DqB5()JlYdm;e%ME}j-6&RGrrG#m>IY6 zXJ(?!%wSK^Z~AdkSfYM&2l689|0|0=F4u4Btre)v?KE^<#E~QVT_qbH@%t^64i|G=ZCpHijd3x@GI8W^ zj$U0Wz$2bxxpcUgV})@s$4cXfms6+cRl7j{=@0iOzVEG)&O6X2>L8Ert(MMv&@bvC zpYN@a&b!bz>LM?D{5@YUvl|kD3Bwb%^9y{BF84*%B^w^` zI=ZF9#T>U97th{iT+DI1IC410Ox+>CBc9_<>2NW}UB<;6cN<4MfB$==(|`KI{fX~; zJ<@px`a~V%@x3k5c@O$UJ>>Jfyma1$zEKx>*<+@*3gjgA76IRl`pWU0>lJDZTC#e$ zf6l%YebVva-;smHZIcd9T<7|w!!y4=n?>nyHn+=$L+B%ObDsc@cy9-!!z0cON{5U6 z9x^WWJ2j4edyXB_$q~=qFB=~593|;+(Ql`5F-O_Bm}8eXazww~vf&ZWu}3;w%rR_S zJiFJpnBxI)8^L>=Vu zy+@_<9`uWP$me^HN#|YY8+DPFJ!W&iK+X|?82I|^9gxm!#@TyZHazEi&YqAS=j=(@ zaEQ;qQ_|rP@6*%L;SuMakq#Go_pEW=JLdK|fq2pHdE>QA#5-tQ^n1a$81F@K#B+|f zeMx{v{C+P>hl}xEG0x9&zgGp~#kYM;HZ^lkVxJWJjb4{d?cA3faqkV;^niPli#`8- zyeXZy0O4NT!}s5kPHcdjzW=s3;seC@bNZjpA=&Q;}eOIUx*!MYjPkM(y zubQ>KFTf#i^yLEq9`T-jC>K9`SfzNr#K^zBbO!Qtvkc@!}kOE1R0RC$V`?pM&qDQ#g()$JUF|Eui c`cbX3Oh2Zz-t^;IIgif?t;GLNS(gg`1HlEHe*gdg literal 0 HcmV?d00001 diff --git a/shaders/slang/instancing/starfield.frag.spv b/shaders/slang/instancing/starfield.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..846472b6126ba000453f56f081855fcb883b591c GIT binary patch literal 1324 zcmZ9MO>fLm6vnR^)6$j_LgKBZkx0nIqMC}(R+A3W##FUf&<=eunCTc}VId*XZ(zaR zXRx%kwH3aEg||fF_Z$BslitZQ_nhZE=iYPAy)*gTPEe^ta&h>~Y2!On-l?tWPo!h#K&?`(%U=Q8!7g<2-5}4Wm)Ug-e2iD?ji;^R z{KAbk*VE2hskfTX%Inp7t6XVTYKyDQ%32L_CR@8eO|H3_FHwbS9sv%0>j-~OcBZ54 zO8(Wc54(V75bQ_a#jNk?2JyEsTd%x+KeK1iKZ&pQAo%p{>ty(c@Q=U$^4~v<|NYJ9 z$x~#RcL129&RFCPVGnG)oe14Ae7V40>L2dVk6^!RJRghvv-pn4AH|jngl-%zr56*P zcM8ihcz+SUgiUOZAz}}HQUL0X%b>5Xj%}+e{GS^S3^=19LgYBE_0miRVmD)vMOt`PZyW!&;m7V)Kw)?qeoN*po-uKkU%dn;eU`@UUL4>)eN14MMa!8aAM8SjT-Crg6m%IqR zuhWfoc-{40*EZG3W@-h?4VYQojY|gVG|QD*u8`c+T@7&-vnMspO6X@DHZ!H}kEVAh`~r@YE)D2JjseEc5!;VxcHh%JXE~{Ym`0z^}VK`=R{z^x$nn^)$Fr!lJ6WNode}e zg|YG*@^IcWm2Jv1FFL#}&&%PPD$bqcz=?AwIV*KS=lv|Sml(abvh?6zsNX3{9sI4T GweSI}jvYq; literal 0 HcmV?d00001 diff --git a/shaders/slang/meshshader/meshshader.mesh.spv b/shaders/slang/meshshader/meshshader.mesh.spv new file mode 100644 index 0000000000000000000000000000000000000000..582ac173835d5a4c82b35c08bc2d1b3e18e55447 GIT binary patch literal 4088 zcmZ9OS#y;|5Qe`H5)=`FghfF-5Kt6E(1<7^1VnI&fGpyAI3x!MCLBz{;vSZw#0zDy zRIpG~T&l1DmkagAU*%e5mCtiBjf0bV)7@|PbWiupS4rcDwo%2%hN39u6uHNF^8 ze9<~A^^7i>iw)~Gmsf4sSnjJ1>?{xLtaMlVi?KyxJ>HmcME%B|5$JuDp4~dyz;SRI zTmUzNmSSW*<|cG^hy4M2&C^0HbBqVtffl0WzbCGdpX-vZ34IiL54c(%Q``bq?yL;< z_Z-+TSnIFssFt_))+&ST2inUkYrUP7UA6v!!S03a3ks?>)#KSxbXNu|$|ioMBR8#B zTmCPuxz6d|(_h8cLQ@2d6I`iJY*=g6!((=1mrw`=M-ol#L}J5T2@E!ibxGtj?=?Dp^S9$c%b?HSFj zU)>e{;Os$eIS9@@aznt{>N9{V?3u%6-F_F{vy4f8-+^bn%>5bfo6vS?UqHrrCU8Q} zFoW|pBGo4n(}XMmR|(tv-o5-JBCoCUMKKxQXmst7z`fQg0dvhwwr4Z{G;C+<9yxPg zk2JTu`FyX|FD#bo%-U`~lEMSc9_ckEEo|qDH4v=%nIoI2P zyi3mezXQm-f}4vjXCJ}MOPqZLcW2`4QO+9kfi?2IcO@QiW$%K-<#7uWm)E#Eae0k< z;H;6ywPVY>;(Yg_%jGo|B`)84U*hr_i{Y#hoU^(g$h)G(1L$&jjU|c8Ydn}Z^Q}wY z)>3rm?|eMJ`NQ`Ry7%Cm?87?YTZZm^I4}FLUig-ydoRw-zO1XS1GxfN)7<7*4&qHc zjNS%Tf_PJ_(B*LXH@=8OA(4&C`XAJ1?8@I8<2Jvb-(uuk}1K=(eJm;G2Td@rJV zFV4-rtgEjBSq9cLw>gZBH&sDz16x77scq=;_F6)A0XdhP_uUQTT``j?y1Xm6?dWn1 z8Mh;G`J8qpt}(?~qX$?c-@7aEh$}T-N?ab-o4CA2U*hr_yWy;n$JMaqUD3xLbh*67 z%ZbbP_9rf{F#uHTESgudzRI=8OA3fbRUAkLNdk_+CNx9-NbX zSSNh1qI)0C%YLjEzSq#b7w2YQ*45X6d>vTR+~zR$ByU6C8$iGBF1R-nzXEB$O~|*v zRN&gf-$>^&1mxok2hk5D3?+G~wXyy`+!5@DnCd9xQScYH*n;$Lx$<{%PDI`aT>8f& z^((b+NVZaYLb8>951#XFV2#UI$B^$N?lAHX>Q6$t{w7|Zb}O)s(!8ESTVLe;5Z%0f zi)WA@gVR9XzQ!WY0{!QaUjjM(<`|9q3dkQMM*Hi;Ik)49`zG<;fqAVX7j?fyzW}1{ zIP{CjZ`~h&TweFb#GB9k+V(jaX`f2%Dalqw-#?+-_YmiEzCQ!G{66K}@74qX5FGPis)9CDFFi=bOToJcUelWep{4W|9*xC-FDZT;{5{_NbsjuAlV_j{ z`*wDA_T%~9I6}|>@QMy!Squ-SzKg1~(Zt8{D}DR^Ozmp7PIqgQt+wdGuk_ONsJXDm zBeo_lRA|#5$%~8W($(&>SNoKQ)I2aI2WyW@b6k`rV@lTX!kKD`*&AZ%HM`>e=|e=- zE@S^T`EUMX_IX*nyJMbM(XJ8q>T2Nu0?q@SMfFk6J1C|ixh(`7}jO0yYTZj|kz?Bmh z_@!Kscwf&HM0E7r{a#hq(%qB%%=)Y=ZFYv==5?N}KcjM}tZ7sX2@X zlV+HN{rBA@JnTz6$j*rxIE(-Fx^i$9chUE89RDK-JQ{l z9St8FaK;5iKC2l&_OBsopb@{Knf>&)pY=!Mz+ z<95&YHq`}v+!N3Y)Uhp2&*Xn9PT$-WbsM)g4X1DJ>bRY|I?lN(JmRYFSK7`oWV2wQZwHb^%$SintI@z{V9QZ%)X>G^%y^`HTA$b>s5hz-YGgg^KGCJ zhtX6`=obZYaR*;BjrW8$ve@=(wqK!^Ugc-&b-rYn;JJP zO`02$B-xn!qfewgX-r_2B~7`F-j>{w>y7#xD_6%c?iOZ*Sz%7NEL;(;3d;meEEiS^ zP5NokN~|UNVZS;)F_m={)5)AGo0FuV6Zj*;<*dxgz3$LDu&2Lt z&99Ji>`&Cv2QV17W4y0k4CE_$Fh29@@&d`HFYGF-jesLGM?2= z7Srl@RxH=bW2M(CwX8DTr_OdQ6pt@`UBtIuynL1J?@nVD!aGuRFKq#yIb zR`r)VkQZV9Us?2Rhd!ydRiHMv+oV$)Hubj))aLsuq*L2&#pYe^5vXmwfDdnUuK<5g zKAl>-jMI{H^!+{o9>I@0Zx-MY=e9_PqYmfpH;%fTd%!qqgd<0{K#q9!LF2V7oZV_% z^n1v-m}8r9F~`H=$PxV>kqwXd{kBVoi#Z-OE}q?CT+Fdk966k$SGxpw#B=mWhl@FO z8y9ozF^+geb&6i?73e?x;r_(;y~m{U4)lpSdIaBlTsrSTzo>_NzW0Q5-i5wV7kSz1 z)w)k0C$Wivug}zz(wQl~b9|TRG7_Vg^$06gQ-?PTW90SJ19Q-pwj_CKCYAVAdq7L%--Vy1% z2mPWR^7-CSuIqm>t<*(c_L!+*;jln#V&L1aZ#ll_DnhG4OI{E6FWPs-QR(=M2Z^xy>BhIDL;bOlhjPrgIuO<*L`b`?I zWg%W>T=bhVF2*|{j(E;757PoX;`ci#9WKUu!#F?7{oWLa7w6$^+0@KEi9Ij)yS^ix z+PN<|;@)Z5^niPli#>nWccl{-Al$1_@cs9s6B{7c@4qjO_yFb%z91pZd75tsvN{#}6g+QlA;)Q(uZz;*TZOmmf3-i&-l=ZRNUsX$ gvs#%)^f|37OuwwP-SjJ3Igig(t;GLNH`ylq4_#$hG5`Po literal 0 HcmV?d00001 diff --git a/shaders/slang/multithreading/phong.frag.spv b/shaders/slang/multithreading/phong.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..eefb9ff79e0b82fb48abe88d024914563162288c GIT binary patch literal 1096 zcmZ9LTWb?h6orquYMM5w(X{rWiM0|@f)6S}sck8xFKG!B@>+&=5(jcAlL_LJ`UiaS z$NExmeP?DvaKfJ1YwhdV`y`*+E4#u2=Um6V(VJ)8&Xe2jhmY^E zuem%Q?^AOXSCF2QOoC_%|61}$vLacP)FgGq;8T|5^}|MuqH5q9P45;-_i`3bg0Z0Z zqW4Mp)7f|ydtdUU+#m|S4Z<7mTk+J4F%q zLIP((otMJoV!symO1g7DkEpvZjUMnj5T*}iK`(}F&xV=BvYlBNCLgmP=OX{LMLP8iSEWC~VfYLa7HVmYvr u!)!a54IV%4g5~Glv3q=eWi{KIj{WXQ;MxBdZG%0*-D^vqCI0|?^+{_0 literal 0 HcmV?d00001 diff --git a/shaders/slang/multithreading/phong.vert.spv b/shaders/slang/multithreading/phong.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..452997835a94044030120c7434c3678b338b041b GIT binary patch literal 4044 zcmaKuOKj9t6o>z`(AHQ)731Koi}#kVImYNc_H;d*Frzr}_1s^SkGs*S#}sd)v~^ zV*0eAC~hcbx*)TQwnFu?qP=OW&%#pLz-YNTrrr-ufzx0LoB?OSm0&Tr3bgZcDXTGN z@Z(-}Y<#U&)Ekw_K_<82T$B1b zw~P3;8c%VZ??rsKS1Sj$S9Z2)@E$JWyQ#WoxS_Lm;+>wauP6qXf%nt{6m9QQ+c{`^ zH`<=nUc=e}E(doKGv>Y&TN&UTI7j{6S65;`IOEIp1LOL>d_Rh|v(4*retBKaD6i{m zvfEkbklpy#G+$+_m-*<{-3t~Fzmrvada}Ec?fJQ!x0YUZyIJ)Odm*~9^}mt*h*=be z*DX(p|q&fbM>tYXDpE{3cfSjkyqenAP0YqJ5Ipv(88VKa;MH_Fu`?XBD<{@@-Aa z?8O(@zOC4|{(jKvp%vdZVLsy--#3xlzKPuSP2{$3LVFs&y{B%Ht>jIbvkfTjPhr`o zdAyT$9PCTm`=1H4*I?V<0$^`pFG9Dsu$Q3Q+g5U!w+F~6pThZ;t_JeG;BTt%^Q8Ps z4)*7S{oT`VJ+t4yx)Jm@?elkbd*b7~c7EPCTeyAi|1RJg5Q_7*zY_6%CwBvVdVx9p zYz=~bFaYdpHS1;|@2vb>Z%G_WlQUKc$SX0^t?2SfaQC3gSxa!+5@&6}-J3Yyy_`Aj z1LnxjZcjYRxwH2tF86yNae0mh6PM?B2+kb2-^1AQO4RoVx?G;)(ZuCvA4^=GV+hV1 z!TH(S0pyj)QAU@`b3C57Jjc$&8Lz~ooYgMi{GE^W?*Oq^LH8b z@=DBU99>=s?g@0ce0KH3<+GbeoU@A@4RmwlXZK;tE0JSAx?JveAaQw)$;9P34#Jru z_j?jsUWpt}q08kto=#kT_L;=xIi7_xM{vHgLqJ}M9EZ{6@*K}4F3<6N;*1w>;stc) z?|iJ^__6mQy7%Cm?Bg(qy_e9v59eh+=8L_T(Y+VvW?$xY&v*6;FsHGNp>MpiBj~;> zed0~Mik`oz*RbW3xbN4|<&~JpQFM7F{N6;@FQ3y}*z!vFy^XG4KD&3Y<(2Sz7hS)6 zp2x7wZCuazzd(GSAICnHz|yS49MS80=y|X2W6LR#^8<8wMb0;M1& literal 0 HcmV?d00001 diff --git a/shaders/slang/multithreading/starsphere.frag.spv b/shaders/slang/multithreading/starsphere.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..332a5b654fb5afbfec75d90c62cbbee962fbd5a2 GIT binary patch literal 1588 zcmZ9M%}Z2a6vl6UmX2R(NVk;A_xr=abq-T8ZF8uwU}~78^_8@Fv4xC7TLPL zp=Ik9wrCsmPqgR@f_}g89vQmB<9p6?o^$Sb-}hW=YmPQ1b-R)z=}Xr5>(i0cBr?rO zL(<7QHa}iY)7L9pT{6KsyST7es`yQnI`hSHX*Ii;FP5{pQm!y_x0JhAfV`Z(tDYWx$N&5o zUHOhfz(?P{!tYG?c%;(Vc3<7t^=NuQ5BdgHeRtc7znj(m<@@oCWk8aw4~5@`_i1Zu zF#LA>x10NS;vL)Zp_5dxPAf1+ow3NlZ`UjVBkd?}PZ>L3Q89 z@jrk6HWGDC;2(Scb;s|=|MBL_NYw4aH%FbZ$a5eLZ)^^S?i9XUpo?=JuF{WSzgt?{ z>30-A_T(CM$FbShu=g;Dt8c?&>|ck(*zvw*GMST?QiM=KwQ z{6#pm#$)eG*z!KXJ;au)J`cZPwZ=lXjIGWd-LGd^25ODPS*~E4D;K&)*z(p3-D7O? zjRp4vTTONDD!#lmL-!Qhd}E%oy*vY*pa~fN06WZj6Bu)Le=;$1tUiC34`Van7I2PS zhtN1fqu@83dSmKdru)8)9W`T*IXHP|HNzCx(;Z+>2Y_+Ei@3L0Y~z7=uYC1;eSggI iJhr`g4$jB~kaI4xaFeXpfV}@htm(HT_m>+!5B>pLMSp<+ literal 0 HcmV?d00001 diff --git a/shaders/slang/multithreading/starsphere.vert.spv b/shaders/slang/multithreading/starsphere.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..5d02106a42ec1bc4a34241222cf35ccf54903e19 GIT binary patch literal 1500 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/multiview/viewdisplay.frag.spv b/shaders/slang/multiview/viewdisplay.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..59f7d45fc153c0de40687b7ab5a3b7e736051730 GIT binary patch literal 2432 zcmZvd?Qc|75Qh)lZfl`JkvFkeTM^}@R>2j~3bqhZjBQwLTEw^Q)!o8vcK2>}FACo< z#>7wlMaF;2m&C;9xqA=Y7!R4w%x``(XU?2+m&(}L$uNE(gm6CW@z-@Uj0KTHVIsVZ zUR&Q>UmE1irP{l?;c%#^3eJ%*6~?j0kWP|z#m^xPWEYu5X5bs2L@N9{gtmT_OtG{( zNSm$y^Q%RE+U-5cm$tT{k~1A%K{qy%yq`Ya%(H&-pw-xIXGvarTx;CQ+8fDU)~DUe zHM*T3L%yq-YPoTP|&rb<}C?_D0+HEm8H{@ydY8ot2Z{`mI2#`^00+n*V)7I!sB zI=yzQzioHc-hns7n)nBcyKHsy{*!u^cJq4DPdbfVM&AM4DDS;W_nzm!_!{+m2Xlx^ ze;z%7%piBzA>Pqhe3u;ga#j#I@gDX$m10)zY1}(;#dyS=z1UMEV&)V)f)T5f*bJEa z`;He7SM*;Ux`pp7t?e@Io0l&Z{ZYQ(L!7}eCM9oy`*C0G<6u?vJheQx--iB47|#`W z2&afmVe9+d$vudcD{lNnv~ka9{3W#Y#ZTZb6!;LkRQmR5y)*osM_Ws5j=jB`c_eb3 zo3-V79^+ziy(6(XPT+m$E3s$$c@2M&efQbKE_HYr~yi3SWCFXCDxcyDD zvw3eJ{s(dsG5#}LaelIjn#Ro+^T*dS8LO8y-zjlpzm%B2bJjBUV~JhG7I*L1qrZXT zzLQVOJ>JI_cl{1lMSp;ZFC%|2!NX|R-<;jp^T;&fT-7(=4CfcZUtsc$$@{IWxq@v? z&lCA#qkQw6uRYvCtm*zo(JuEF_xJJ$;vVW)&-ZOT`NrhMbFN`~PTxj6=N)Wu&lzio zjn=SM?CBHi*wb-rmpzFeLta4KR~_rcp5z;o7kj#k9eav%s)LD-&PmLkVhwfdX%jp4 zbPC&LPvR$$6Nvk&?a8<9w{Jc9#^m|F{Pyo7_T)G39)7o9BYuPTc*9fZ9Yjp7E7sk? X9<6JAYnanS+*_{Sul_&W#x>+$an8nr literal 0 HcmV?d00001 diff --git a/shaders/slang/multiview/viewdisplay.vert.spv b/shaders/slang/multiview/viewdisplay.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..ef2e0e8e768ca4ffa3d9dab796da2d49479328dd GIT binary patch literal 832 zcmYk4NlODk5QWPu#x*fUjXR@34H`u+;)2UfL4>*JRpu~<91>+1M8SjT-Crg6m%IqR zucrs?@OtXKuCA(ilVYJ&vC@E{B*4fJ2$s3udJ?Sf4bR)m0Ue)U1}aU zJ>Z)HoZfI2oH>>qGi#_KGpx9YvUz3{4@wJ!rt&L#!b_eHdCn};QmGvX)Ct7LeT>fe zq|>!&ZTb8u#pJ^|pA)DDr&mkRI?wrnO&3=A{3w=gfI5&OCTdzntSy z&bg0A)Zm=^cm(h0>rm%VUAy%3EV^f@Y<@^TYA2G hZCx=s?;olg9&ZTfd;|PAl>_*PPKN%Z9-`L2AZT5=tEtZz?| zzLq}nX}%fOs@63`#M+``P$)Q{?Wn1qR{c}}!$sb(xcm0nvB%>HBH zt|D{8pK14=B6&D!8UthJ^<7a%|3P3a+#mV_Vfwjy@<)oi3jAD{{g@FwF#XJkfvIOE tdS+6ht~m$Xj}Y3o`g3O94?Qq%xGzWVMOpUbec-6W?xc)9{6^|G@?RIoCsqIe literal 0 HcmV?d00001 diff --git a/shaders/slang/negativeviewportheight/quad.vert.spv b/shaders/slang/negativeviewportheight/quad.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..74ba57ca8a6b1ca522bca61e8dcd26479fb091b5 GIT binary patch literal 588 zcmYL_K}*9x5QWDiwbp8D5EK;bN-GFLk0OYA^d#hBuaZL!IV6>smiFe)_EPBkwp-lr zvh!x&yqVoN8h0%@FtdBR)1Q@EWMl>wdrmyGo{uB_tGuisPM8P-Ar)eMeeLKw`pB2{ z_oAI<^PiAIx66Ib6iRjMJ&L+**4ezQ+bnPL>T6jvZL#`Lr>Pg>NALf<*}Ema#|=hW zaQxxS0C(D%i3Mlgz5YDh^VUzktGQ5oD2)>?rSEEoCxIUY&Mchc%{edS#80);n>_q1 zaOxh!(OwH?zi*t66j4hb_&9L%&*J#;j(EcH8S4ITY~ERLe|P0vcw1m4nkxj+j2^H|p{vYyn;bB}o7P literal 0 HcmV?d00001 diff --git a/shaders/slang/occlusionquery/mesh.frag.spv b/shaders/slang/occlusionquery/mesh.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..e430e888e7a06b7975f9ef13ad2c7c832284e139 GIT binary patch literal 1436 zcmZ9L*=`d-5Jek1<3M7vkPU$VgINMGW(z0~C2@ozzZhf*DX(Zq#$hBc(byK^iSPqF z@ilxy_#QSPaZk^bG@_%Mu3J@8U3I%%EL11m#2M$@s@v6n*1Rh?Jkze^s@j{aH?8_` zbXZ@1`jGgHE3)~VS!GSgE(pCa?&H5El!X~#URV&8ggJdj-lR~}-?Vnl33LwmasPNc zs=pp2y|61Pf8cAR{+EO9Ao01>Onv+DFn-sKd~V5~WB%yFesqxeIXm^Y;-mK?9|+u( z?=$L;l8@~{+#j{WB<#KIB;ip{&R5wifu>v2_lI$(Gag31Cqx(?M+f6>n8@@!G1vd! zHuWuYT_s5ijwW#ChBFJC@8M_#M`1X z@duu}UE_~EZ|v0c9_a6pfX}e0y7Z5x^lThWjWZ9L8Ydr3^Bhf$(M3B~$>t3D;Y@1W7pw+xbh21Ii*dK)@m8%qzkl8)IiIsLpUCE1 cVr}_&C+h-!YM8e8^4fAId5-3P^^!J(e;fB|BLDyZ literal 0 HcmV?d00001 diff --git a/shaders/slang/occlusionquery/mesh.vert.spv b/shaders/slang/occlusionquery/mesh.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..7ace38361730f933dedfafc6d94235471b1c896a GIT binary patch literal 5024 zcmaKu>2H-)5XN67TcB_a{6pcPSMSBpyNMFe-trM=+AwlCh^F1S$zMB;|H z@3<1zxWpxX5kD9snuwbCK@u?}l92ER_yH21-+O1uBqp6^dS;%PGtW75=H9ky=(OQU z^^hb4#Xcb5nP@K9_c7SWT8&!B(WDj(oe|ESLQid}-RAmV}K;#tUm{%9l&UzE$P4 zl;2QjS>K-K%ME=EEy`-jZ%j*F<+j-kvy!AnJIF`c^5r}$XBek-^^)e6lX*26MtoB# z-B@TX7gODm{p51?o?@YwxMNu_(zXJJb&QU+W+w%!)T|cPUfghJxpLis++o6die1HZ z?FF$^W&P}4m&zWQ^|a7gE^W@G#m;grU&?p1^b|_vLSK`*Uq8?!a_Rjbxs}E#hg{xh zklZzPoGh2O95lDkyQa`usmq%WlDnMilT7dF+sV5mNn=u-%|xwm1fSW#r|2 zCupsao+e$Un*PSqBvfb|Eg%CLO_<6X%+5HQ{p>~AUO zh|obQ< zs&u@vhHJ$qAAf}Tdcc*Z}~3dJnl31(P!@6rytA{ zJs}@H<_CU!_?VyQGe7Rbe!j43Dy8mpt>;Rq z%N$UbJIs)Rlf#>zFC~XrAcyzAKnlK6Im~ChVOlbb^Ia$fN64f0EGanR*lgKgoY%37 z45NpRU2GWr1cReN3P;>~iQ!rX_RcXZ=3Q!7295L^5`QV73Z=P(h$Z>^X zaqoP?BF6$@a5zS<7D~Yp=U5~gEOIP1EOIO{jCwhBie4?1(trBH`Kj-*D`oQz^oe^c zl6vea*}Mn+;y&}uJ(3w`5W@Dgj(x=acuwW&d_&(t-tnJK;teWtFJ4bEMesq3U* zh`;x8+2Dxxq)9e7;@Aq=V6jilhQ&VR4D-IzrVxvcV$9&4$Ijw-^>VZWRWHW6acTQgFmMZkG)fIqonlad-_**z;3dXPwMo}XsZ9-XcWYjV z6{N(OJD;@6jyTpS8!YxNH7xdSlVSAE zIqsGXN8DSI4~{rTmu#?@S2iqibQ=~qdW69d^LpijBhJw$8!U2cHZ1PF$FRt8uP`_q zW6tiAf+NmxzihC`@ql5GV~b(b^O@+EP54UTwkpO6iXIQFD$u-NZihQ)qAWthJo^S@gPN8J0g;aUbb zo-r)uJ!@Fxc+RlM@w_lNV%`h#!4bd5i?YEY$4iFAy)PRUIbIP4hhxm?Siz1whb9np*+51ej{4f5a zFzTa-@6YK!?EUh8lEOh9a{0a)q4j6!Xen|2K2Fj4i*%B7qLkU74+o^+ex6?q14o?C z3{lwv7i6| literal 0 HcmV?d00001 diff --git a/shaders/slang/occlusionquery/occluder.frag.spv b/shaders/slang/occlusionquery/occluder.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..4fae9ce55ab4137b2ac8b118f22733e7653a3f62 GIT binary patch literal 436 zcmZ9IO-sW-5QfLZv|9UN5%eY%FM{AvgwlHO;7Q0okQ`J3CXo;i{&O!vpC_%C?lL&O=foMD1$F^{fH(Jb3-Tkpdd01e@Ya3rEvNAqV?D~B5ZEhkNp8QIoMCQVO>*w( j7WaQ#V!ve0UU7P-|7L#<*O~sGn0Kz}aF*B~lOC`QU$Gu= literal 0 HcmV?d00001 diff --git a/shaders/slang/occlusionquery/occluder.vert.spv b/shaders/slang/occlusionquery/occluder.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..6797ca69da643a24136472e0689afce71d1d1d19 GIT binary patch literal 3104 zcmZ9NX;)N75QaMpL5~=h3ceBcL+X~Ey>=G%!}D_;>gffDfMUu`Lv0w%;?eDtp4`7vF5wHo{BL( zQ{)HB_aK+wTb;etDT}9#yxl1q zS&>aQ=UYYDS{PN82A2=0`RtFi-;Jd-lDez<^oi4msSPo?#9P(($Tr9>Y7Ia4ZpE|_ z?T53F&p1BK$DMIjSY76fIk3gRYR3Lik3M%iAftJ_YdNf9?w|XnG0t1?^K8g5= z#d5v3%I7@&vTe#=rJlIk;?)+jkABg$>RAK6MKN{gm%$EMyz#wwn_|}6p>OJk2CPro z)DPAtRcb}-Mjo2m)l(bBUE>q^zNb%ZoO~Z2kWXX&9`(#;-R+9&>d9qKo_|k1ImDd* zr7Wezv&{cf9$LPizbvK(r!-DY_`9M89`kNIX8+t9>od-J+!JdOvmW*S+1thv-;hYUSxL=OA@Oa>p*3ar7KfMGP(T+$kh@077Fd91rf z{a%^BKh~w5`;1>#4)?gQ?4{X)NaHC#;$uHI5jI8efZ{5%Z2JhSPk1L-Ju!;~Qgf?lEIg<6AK_oKdUe zGC0jOPRNHvjg!Wr#wla0*HERX)ps)LPkq=w>-*Sg`P>6_;vDGs*ctiU2le7S==s=L z`P>V2<6P)6R#!hPLzA^xgIs@8=j8LI_|5P)bzVN4v+|}c$Y3rS06%g~5(uNYUiqH)z&%o{ZpHLe+p8e?K;#Jq-LIL*&-T|O*o z+%OjB-ZU09Zi%7cj5l>#2B*2kkMdzrKf;ymd2*st=r7wX2j&}FQy{x=z#tj!wa`kQLX=S|&{`J1{gAI@2MQaPy8gcGp+yRoP- zC5A@Kn^p{``8hiBVNoMD7U#|wiyD83q2Y`-Rmk8p*O-+LiyEb|s4-`Z_5A+l<&Vp# z5Bq0*AA2I7d!SC7105e*kk5TkFV2IWk3E&oy-+vKg)U=t_0MEzvNmgw>;EsG%kMQ) zSDlCbH|*`akWbD_*;`|;fepKT*Jb4ej?nA_Xg*+e_s_L)D5s?Loy z<>hA0y(D>VdxY$(`hWh!Y3jcqWYc!1rJK^snDHJmmlAX8BYMT!Gv(Rr1jla}E0++! nE88+FeUA|Li$hzh`FepJEA>y>Qzq`sNOO*iq*I>{ReRzKs@oW| literal 0 HcmV?d00001 diff --git a/shaders/slang/occlusionquery/simple.vert.spv b/shaders/slang/occlusionquery/simple.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..2300613e58e24c1ecc1cdb323eb7677da5d26bb9 GIT binary patch literal 2916 zcmYk7=TlTs48@-;q7L?6P$~9;4ZA3UiVazNcYVsLi?9!u2ZA#?j*foz&-IHlp5G&Z zgvs9I+}xZb_wG_^>ROUCFG`YRU-Da@$eN@n0a=-p3Lkq_vaGP1^f{i^>NuOEU!>op zE2Jg;wQ41PvHrkn^@*vxyPQoH*z#nZ*2++tH)=EY^Q@7+uU6iTWoh0s(^DD9#)i_- ztTCC79P2rnBrVE8JTj8zDJyx`YJJ#0Tv>=~DKPdY8rf*|ZC=Y%A?Jyup6OckGy9Ge zePkomF=2~UH@!@~$z-<{{Z#9DW44^t>UlYBq~n$8Y9p`C45{;Om6}EhIXAbBvZ=jYx=Ha%wBk3LztsGa)^?%GwNfW>8|1Gn@Hy?r)GyzBYX_tGTn(RVro$w!`Ma>|Ej7D4!WHGyKiw6SG-1~ zn8S7{IN}&@1&lf!+i4heJJxO(J%GW{A%!EJ?KE7={MjzUV%#pnBFApSBF7$KaKyO1 z^1%_WZ=Yj8+I2>bEhos<$a~zfp7CE{NiyTJ`BVSpQVpjV3E9T#+ zmHNr=d&gvR4_#9FfXDZa%jQ0q7yZEJdnaVKOPL#e!OI@sk&{w5$xRMo{Y{;g&70zT z<8SJWY;bzzO`Vm3A%5TIWP>98{5yvjb28(m*H7w5QqG3LF=5$F4M?BkSxR!a2 z%ZA0ce#0WifMJp2iZD20+*SGDi1%?#Hdy2sG%TLIZdl~FAq)=3cvCl};D~eFk_{F) zZW|Ukh72R0-~S!i%)d`c{p9z(VcFaRbD|G;e6K8<`{Va(D6u-UxrXI=$r&r$8BPkdH#(h7Qf+IeYC$hm2$DYati*tHrSe(;y z!+h>=ypX~X&%QKV%RI*`!(v>;u*mV+u*i`LgCoYhkq?e|A8%!YMUD}};@PTUk>i~( zI2_|my_bR`&hbGuSmdY~7CA-@BcI>@N7>Au`A|RkeQ!)Q_rRR!10LTSm(6`JFZzMc z_v*5_m)BDIf|otsR3?R!+~gp3SpPkjYMqd_nrbQfq5iVHolmlf;s5&|!zN{elh?6a mHaPFsu_@W${7&*-;rk{1DZQu(f6+<|_BXBU{Zj>Jr2hfF4zL0M literal 0 HcmV?d00001 diff --git a/shaders/slang/offscreen/mirror.frag.spv b/shaders/slang/offscreen/mirror.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..96a3cc8a82957fe2d6249d58ea2dfb6701742703 GIT binary patch literal 2396 zcmZvd=}uHZ5Jp>IK-_Qv_hoS3_o#6tAw(rn$HXP>jxgXLaB&qTu+eDzh;t*Wl>hW55CU7=%M2w`V<%Wv1R&=#~T3GF#o?+M+Z18hU4s`Y6d z6UZ>K9oda6C0>6Q($3F9&~Hn8IUgL!CbPzWc`5fdYGaeNk!C$3dx;;vnQLq1e39pv zt1rU#GTQ&>oq2Ed>6z!v{gp;GF_>kI(LDD7VrPC^TJ;Y8$9DK1TSpke_Gd2(@)^{o zn~j&1tUleWR2$W)2V;%u_!P!VaaN_!na}H4b!uj^))6d=K0j`;ZXco!d(V;}0R)ijrcF zVrTu1Jp$2IloWg1NS55bP9i^NXJ=EL({N*ol41w2`zq}DV$|&|`EQ`Rzf|iUI_s3P z8%1$nzL7Ol9*f*~ZE49}>!>si8fU$_MwYfyaA&z4F<$NrcNe(*4I}oe-|szdSK8|< z^x{69ZR-6sdg;KY(<$~1Tw76&v7=)D*80Y7ydT!=0)5A#-234DEOOtg{0x3)xfO9= z@*Ut##C=_*mh;<#7-OxE(Y6=8)q4mPvYBT;qP-{|h}Y-)H-|Crqs{lP-FueeeE-_L zPhY9n2fBXHn|&=o79;LiJWGuGb*|sB8L!VceeT`+mg2l?#`S>4iC@Uw3vNPO`j>+G zMY-==F3OijE;_ev@GN4z&+N}Ro{P2t(7mh#UG7Dnd<9}&(Y*E{*Jsb3mHq2m6@8*T zuLrjvF8!-PzZKCW6j z_bgqh)@^j>lab4NbqCSr*~{-nn{U`VqU}CnE`2HY19Wry4pQ!i=EHNhV~56=ezY=Z8M1XGu`>8(Ppf( z>j#~kDBm2pnD*90cW>{g<2`$hX!CDhx+B`s9k+(Lyc^~g<>~%-Uh)mmFUtMDWxSYb zUqkoIQtj*L+EQ(O+WdYK==Y+$C-Pn}&0`R~IFBLtD@1$hUz^|ef#ws__ZQIp-q>MK K{*#+<0{I0>JI-YQ literal 0 HcmV?d00001 diff --git a/shaders/slang/offscreen/mirror.vert.spv b/shaders/slang/offscreen/mirror.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..051ae484e39e2ea2fabfce5a2e8414cc49c32c4c GIT binary patch literal 2856 zcmYk7X;)N75QbYojEYO*o+x2a=;~^y4IwW4y9#%(|$}H39>nLRx$pTw7&8?^gWlg+622~ zA7!6pn`E8(Y*f$uwfewX?fJ!WsFp8OtS4<#U!Tg#qP29V%!}+*v;J~6&&uJY;re(! zJC)7k#X{LQHGDFqZtcN*S|ckndiMQE{k^g2`uBO=6=Qt9$Y+`_%2uuuvYxq|=WVO` zj&WyI9(kiVE4EhWCYQzMx%{3gpJux(-q-S0yR2nJHdlY!EXwB6lrkTxNn$+Diw65~ z9`^b^p3+3>s&emTf*SF5_1&_qvPrG+yapB1CUgeQ%3h4)(|p_+xxhwc&R7FmmZ3#1 z{W6-z11n(_b7$NWjdAYJ&$`X-zQ4N7mD=r;&)NHAyEK2Ddg3mNH(1=MzE8AAJ?Dh) zP`tU~E9|JnTWpTUI~23uUVT$5G+@2brdF_Cs|&FkdOHlWG4Y6UU>$R5 zurG=@%SC-tGwz1{uV^l3|5?WVs5WPOiME zKV>kQ-}gEBaGKZTynHy#*#-HqSf`7|Vx2A-^SV=~%Q7_L+EL@`RyD2|i}S{eMU8P| zQR6Q$G~&Fgis3ZR>u>6= zeBKnlrT(Vw$%m6GZ|c4bMuTzR4`gtf*W{smIL+B3`LI~0$Hrovo*47Gqw!RRMqK-^ zadoR2{~3$(>c*nRGhXi&mbB)*X zVNs)HENaXcV?V$DH}a`J_2K;N?_;y_xd-Y*9_aYkoP6$sdXW!$KGv4cy*!hV7rKn` zrg9mY?9Cp`olZYg{|o2kZ!}X^<-_@F_ICc4&m8_=e>S!tAI`qcO8Ic!ud_w@@DbT1 RRrI5J82%^oze@3}>>KU^t*-z8 literal 0 HcmV?d00001 diff --git a/shaders/slang/offscreen/phong.frag.spv b/shaders/slang/offscreen/phong.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..ee0318fed5ffda1d27d4e709582e6f9d55e8bac4 GIT binary patch literal 1440 zcmZ{j+fEZv6o$7g3|cA&LGWw~CZJ$75fCMS#t=eM%_Jn=k_l93(ssx&TyUjcc8p&kX#bFNxKKXCX5Q>!h~>D7*h;BLqb`w!^XS;WNnm690SvTp()yGq(;9sSkG!qy3x&^m&){4`U!Z-4FDfnjl@F;)V z+9yZF-?`Pxv$HsD_wqQ&lJ4HSEII6od>#5CFFpLrZ)*bddxs)=(76*jJ)$!QbmGyO z2|ANRXJ!^ZAur5am^X}K1q<72>XzJ8h9i@&kUvVA*0U$@vL z>2L;O>E*dj`r@u@p*QAFf2K44ex3RE>&)MD@-csMu4ppwyeA&GAJUjJxtTHh%DFC` zd0rN%Z~B;I>YIK=GWAWLluZ5iA%03SK2>!@zG;E)ZcD&se%B=vTUB-ZZV3MS)QOFI zSdN>)Mh^VGs4w36Edf8v19w{>&%A)0cOHjbxGNcZKP*>GJohHwS7op3oDpgQIlgOp zeCIsB)GM}%a7kdMoE!3Cp6uLDark4y&+5!crXS`)@7$TY+MTge&usUDjlS_?XFn^7 zeOVCLNqmfZ6nOU0?gQ6P-DEa#;8rB_-r3PlfqN<$Uu?X4>aPm)Yq_3D Q#t)v_>>=E5ZQ-i$2d~9qa{vGU literal 0 HcmV?d00001 diff --git a/shaders/slang/offscreen/phong.vert.spv b/shaders/slang/offscreen/phong.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..5c92cb423e0d3c9e89f683c07e24248d7906c28b GIT binary patch literal 4848 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/oit/color.vert.spv b/shaders/slang/oit/color.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..1c5bdbdc385b4f6a4709ffcf23b27e78974e633b GIT binary patch literal 740 zcmYk4IZH!P5QWDqMqCnOOyW}bGzxBoHX?{iryxQa?JZJRC?X;$EJS;MmEd2p5&XWF z`@k3G&YUyby@!-by;@YpB4RW4IsKYZip%E6o2f@R=ZzaNk;f&@``fz*!8X>wX0S59 zDZI5+;${5xjd7K!5if(M=fUtQ?>vu6-edg*`^3%>J5#I|`?Z+h+|_)`Xh(;594^DU z)YtIh3fAVF#Ald&8F)Iy^5$8a=W(%<>gS2A7n|>3-rf02c;}1F7rTLH1zrP0yqy+! zBgdotTg0mAJ&)-3KI-Pa0;@rRtycqkcG1xNdzd@412}8FkDqlvAm4w?={wcW9R;ov zyW^c+^Rt+ob+7dJ<~dCMiyCn&acc9OxOU>z=aD|O=wk9k%>uEr{?{ym<@?O>J^n}R mlmATIO5!v8N8)%HZ@$wllWFAuh literal 0 HcmV?d00001 diff --git a/shaders/slang/oit/geometry.frag.spv b/shaders/slang/oit/geometry.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..4a6c62d398cba8e136de86270d7aa73823360afd GIT binary patch literal 2404 zcmZvdX-^bE5Qba!KomK=5EWd&8xxtnfPznp&8;XqEflWt@EL;20}`*I^o(r7y_ ze`;=R#p%AfS&bSE?)11E%-`$P&Aj9eQ7zi7gP#-K7CjWrh)#<7bO)c#19F$-oc>{_ zhJvg;;!AN-i?j6W#{8O+SEeTKJ6Dty8)q|V)-&;9@aJwVYQ0S=@j@{9Sf_=*|G1H* z&CRTt#+7;B4|xi{#_j)kgyh{t`PUU>rP7jK^gZmvQDvoGiCZf*jih~dTz-3L{AC%N z_bs?P!YIHBrd}}4W>QU3al@#$67OX@2QX$+k6W~*o1Jb#{OH>Aey-HXV-#Gsdn{gF zjk0vNwGp0ftC~dFRBNidkW^Qr&q;c4j`(vbQ5M0;H!Z&2Z0sx~^+wjPF4{F?f z!+tI4t=Ji;SF|io+l?{l9K)y)j2-3P8S$d%xYu)z9U%w)$Q+A-Kf634B97^!k~!$? zId)>0ZgyhY4p>aXtgb%YGmIGcoeiX+@WG$`;8omfD!kZIDhBC&}V~g_UA$8F7^d+>SA_Q$FgMRFe5vA!rYDpo%iD#VWnGbE19J16;(IY9P+A2>hFJv0o(-vB7_8-h9)XKk_e$7erw6 zg1n}BM#cF)=?CJ_drf!P&1)j;v%1M{-ViZIaC-V4dK#CE&3d8^db%rqPsFV8Z{r2O zS5v_T&b-)xIT7z*7<=#{;MP0ye;M%S>XSI=mTzA2;e71RYY{f$yi-1QX;DPq9U@}k h17@+7Bp;5&yRL|^v4h-0X9m9&$z}}yt7$$F{R1iuzkvV% literal 0 HcmV?d00001 diff --git a/shaders/slang/oit/geometry.vert.spv b/shaders/slang/oit/geometry.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..7a55884309682a730810f64b1629d6ac7d3a0042 GIT binary patch literal 3080 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/parallaxmapping/parallax.vert.spv b/shaders/slang/parallaxmapping/parallax.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..3999403a4a26fb3b05337fd3473c171a6139a42f GIT binary patch literal 4592 zcmai$*>9Cq6vaPiDIzVEnMAC&;DDkPv>=K=83fc07YjI{<)gini|xI5xs-yE5OIJ6 z6cdNU5y5$$eUQW^l91qwe~vFEuHSd}t~)%)A**NYb@n;yoPEyMQa5qo=GV0Da%DIja-B76 z`qs2GSSVGq{KjOy`o6BTS}Bh9R?C%iu+X=AsGL^YN89_>mxsF2z2%CIx3pcSYmfu^ zw1Kpm(&Krp`fcladix8dLZ2l!m`={VN_lUgzgjG-0<1wk=Nc&%4l?dqR;Thnfld2- zsyS2~+*7R`dt9%V-k%N^D(Qdq$Voe}tDNmaR8Dot3H4job&Fq})m$g99LkrArD{H{ zq{Dq9g-W$B+NIlR%ZfNDY0B>9fAXw=o#VS=4)=KFIoow&-)~cP?^m9)QJ3O#Ch7I5 zZsU8_`%CJxx6vYK$OHIZubw@VL)>aHx$_jS zQco^E?z={OLWp;Wvj*eTa|G^1G1z5K~v)yT^?4-aV$yymyZ|e@n}+tcB5JuxKRH9A!2XFjBYz>-zmLxlXaB_1WR}4G*J|xn^$UcYz}p~)ds`@= zZ&40!;0DvwWg6?;D4^5GNm<9=8g3#JP)2S2sTQ zHq&C>?WRSKHq)ZV9n$cKc}oK=jmQy=!v`aX8AIQKxEI0rsHwo;t?pkAB@KOehKoO_{eoC{yZ z_@-A2c(OKYkn3-%Lp&$&o%@?wE8Zb+R^HS)0gdMOyLJY3^V^$O@T_t+|q7Cp9^7Cp9`#(IALkBC!$>cjq7-^U&m=N_mN=fKCu9uwz2 zs2AtK&&M7Y=U%8A=famU-qaHUo~+FpQamT@5d2L&C63Nnc~gA?8V!x_VyA#k z^O~gMI}y}e+a#ie^opcs1N&R zeIGj@zDuA^oC6;p8xijps2AtK&&Ljmb1&45bK%PvZ)#M)leJlc+`PSwL*k9XVd1oC z&x)fn&$Z{o(RrV)9T7+8_h6&``b|;)yl_n5yO<&L=r1z*3&Jdex~y*0$>+T&?(@iP z)ZUr*lIa`Nvo?7?=Vcqii@dz{a9sTffjq{U!}oJa{VPIFI4Su51zr_L_kErgM*}qO zmwj?(_VZfCYaYJt>(X*Ui{R_NA&&0rzA26dXqT`1mNatMyMNnni^p&K9mQxg|L)!u zN2mGQd`}#m=Gyz>X!yGJfoYu2wKJyiUePA2|4_gq&OK|oy79T^OpAFRnHD`hHZ6L5 zA`Oq2_o-rZn(yy3akS|1xoL6k7p6szFQwt(T7&pk0y@n-z7|J|9^aT2J-#)K_53^h zPMrFm71%%P``Gv5+`~D6bKv7+KZtW5)Qj`r=VL#LpAo1V=fanxqYSp literal 0 HcmV?d00001 diff --git a/shaders/slang/particlesystem/normalmap.frag.spv b/shaders/slang/particlesystem/normalmap.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..9be8968171a7c2c482876db132babb3b4923d8bf GIT binary patch literal 1936 zcmZ9MTTfF_5QR5wDM%|9QBYB7K@Lc^;y;m3qa!me;iI4ukbBf_v^@$D1h`b%l&tX}=$TWhvI zbaF2$62&Bg*pMsL4&HYv)wdx}zT^Bx;LjN$U#V3;2JQh*O^05iU9b9^t$NGf^V;GQ z?)(wIFFo!qO7{=mNbV1Mh+>|${DxQGsZs->LG0yYu?aUPy&fJZ`#{itwb}7Mm0PuD zr|kJ&XzCAedvYu%Yu5bk82NpaW! z%kq3vubeX_;KM9_MBH@5^G?#y9nMJR|KOH@{il3+Th|482Kd6w3ixIO?3Q;4= k%{XSjIoK@riDY=rEi0BcPp|OYQ(j*r-zD5Xz0MWkKTvLfxc~qF literal 0 HcmV?d00001 diff --git a/shaders/slang/particlesystem/normalmap.vert.spv b/shaders/slang/particlesystem/normalmap.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..9bc1b06a2a08ab87a8d5ac818732209ed8bf581d GIT binary patch literal 6304 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 HaS8kx0C?wX literal 0 HcmV?d00001 diff --git a/shaders/slang/particlesystem/particle.frag.spv b/shaders/slang/particlesystem/particle.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..e0988cb669353682fa3d0dbb1c48632fba4c3a17 GIT binary patch literal 2744 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 HZK3=Rkjq38 literal 0 HcmV?d00001 diff --git a/shaders/slang/pbribl/genbrdflut.vert.spv b/shaders/slang/pbribl/genbrdflut.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..ef2e0e8e768ca4ffa3d9dab796da2d49479328dd GIT binary patch literal 832 zcmYk4NlODk5QWPu#x*fUjXR@34H`u+;)2UfL4>*JRpu~<91>+1M8SjT-Crg6m%IqR zucrs?@OtXKuCA(ilVYJ&vC@E{B*4fJ2$s3udJ?Sf4bR)m0Ue)U1}aU zJ>Z)HoZfI2oH>>qGi#_KGpx9YvUz3{4@wJ!rt&L#!b_eHdCn};QmGvX)Ct7LeT>fe zq|>!&ZTb8u#pJ^|pA)DDr&mkRI?wrnO&3=A{3w=gfI5&OCTdzntSy z&bg0A)Zm=^cm(h0>rm%VUAy%3EV^f@Y<@^TYA2G hZCx=s?;olg9&ZTfd;|PAl>_*PPK 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 HZK3=Rkjq38 literal 0 HcmV?d00001 diff --git a/shaders/slang/pbrtexture/genbrdflut.vert.spv b/shaders/slang/pbrtexture/genbrdflut.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..ef2e0e8e768ca4ffa3d9dab796da2d49479328dd GIT binary patch literal 832 zcmYk4NlODk5QWPu#x*fUjXR@34H`u+;)2UfL4>*JRpu~<91>+1M8SjT-Crg6m%IqR zucrs?@OtXKuCA(ilVYJ&vC@E{B*4fJ2$s3udJ?Sf4bR)m0Ue)U1}aU zJ>Z)HoZfI2oH>>qGi#_KGpx9YvUz3{4@wJ!rt&L#!b_eHdCn};QmGvX)Ct7LeT>fe zq|>!&ZTb8u#pJ^|pA)DDr&mkRI?wrnO&3=A{3w=gfI5&OCTdzntSy z&bg0A)Zm=^cm(h0>rm%VUAy%3EV^f@Y<@^TYA2G hZCx=s?;olg9&ZTfd;|PAl>_*PPKFG1eK>zffRO?GAolHOQuVa7ePcoxv z2sWjwH}Bq@=@qLpvuEGb|7;pil`-RKZ>nMUBdx}ITfT+dLEcABAp3~dzXuuMZxrqN zgV=JLYwNr0S{i|0>1=emW!!(^!SoDqy+&(uqq*4GY8R~cf4LgxNvT+C7LB~uZtNM> z+x1Sb^pBM1YPO5+SM|<%yQnw1jn?wRZsSo4@>Z_FASb&`e0{68w%BR+irz96oPFB@ z4)LeYvD(}y8g&Z52;SP1{8E+FAQiTrE9E*>-97?Wb*m-wE}E^)d(9P2J(SkKRV`qO zvV>(lyqAjaUTHsZom%q3DsHvJ1$bxOzXxyEW~jW!-DkbZI@ahI;t+fH+jyWnuRU;$ zUE=K1;Q1Y#=azG>Ynbm8;s|`ag6RO67(Z2ZRMk(1u?OKMOQ}(bs^{d6u--6Q+wPqN z??u~x@`u3o8B@d1HgO55(J2 z?f({>;~?idi;i{Q!TxRh*ZIH~N_>6Zb1h(-OARsaMYLy>kN6wd%%3}k-})P`7+*(Q z3wi7CLCIHVb-ws6;xK**ZM^f3V%faf?&%%J=*z|gp2yh6Ie#Pba;`s${t_`h_WL^H z^Z2d%i5=MU*(2_!-~9bP%t`F}_KxEmnYnJ{<(xl3*2>uE5${>-8Y4*HF>K$Kz{dMN zh%XZF9Zw_XcN-*rHFNTg*nced#A|RTkt>L?W31-9*AaQob_y{r=DdL&bBv2QGnsde z@y1=EGUjJ*X?q^~P202BV}DVDakRBi|IS$sqT`#@zc2gM;{6$`#m{A|wifolEaKk3 zfb8FMnX`ZYVE;pC$KS;36CXg#L+!feA=YQk*4wk_JDh!LbDluQo1p(l_N&FuXRH<< z%~%~dU&D5f$oV?9+zrH>Uq(C3S)cd?#2nSGYaU{KvF^v%*1|iqHlHBgp?m538Fm=` zDdN59kJx2wW4*7Pu@AuBx&9yX{06pbJV0Xa&#>Jm)?2}jz4gW3tJwC9{)l~u9eeML zeFX1b`eW}kY}e4|-jC6rBQ4}U=Uza!GiR(LzLQOCeTpN#lgRB0IAhE$xGuK5Ik?|2 z+TUe+JaQ^BXRI;4FI$MUd`iv4PcrAb|1a`9c7YkZgHvJh{ o_53!@WlmoCi73~eM_f;T9c}@A8JS1?Z8cxtK)HYDq<4{j0lc&C$N&HU literal 0 HcmV?d00001 diff --git a/shaders/slang/pbrtexture/pbrtexture.frag.spv b/shaders/slang/pbrtexture/pbrtexture.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..7c56a77a5b3aed6415644dbaa2853edc96e65546 GIT binary patch literal 7500 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 ZdiwdU9}9mO(rzrjBL_3=bvpS>=zsBdD7OFr literal 0 HcmV?d00001 diff --git a/shaders/slang/pbrtexture/pbrtexture.vert.spv b/shaders/slang/pbrtexture/pbrtexture.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..b56bda1c71906a08e4fdd9668f0fffe45787f4cc GIT binary patch literal 4608 zcmaKu*>9C)5XQf*pdg5>D%6&`plAiHh$2vxSk#mr1>{C;4)jnDY5UdF(^@npM7=OZ z#TycL5#0BEUvS?w>V-`tA+ZU60Vdv<`24;zbDVI|Ay2=VXXc%GXWpSuSKB%zsjo?r zWJ&V3ej>Ay+5~1sQkU82GxZ0l6$bLfLG(q!xNuN7Buog0g&D%}!faulP^UlB^d(P& z{@^bT4vm!Ca_Ml!HD>V@ZbMoc$oGrRV#!hAH(yub8nc`gZc~1+uP|87Vy7ny^zG@& zmrKR5jpekI?<@3d?@#mP_ObS!%hUd@{EoCVT<%@ozAQ-^m7RE`H($>45rJcF7I9Sf*OZkDG(L$+Q80*sH+qR^o{$7F`G*#w4No;kP4au?D z`%Ds>4Vav~;Usa@p);?n*XrGpq*MLyzD)vx%`RXwD{S5ro3q&L2sSgqK2hIBfphCs z!{4b@Hqxm`X3u&2=!pBBqaIv`;2dY*b_K4^xC8o9pSNid5Vsds%*cGZ=Ii~=Ru|l}MLls3^m)?gzgd{C_$m5g*PA`nY~t}BV>bDlWgn+6d5FV4 z!EEBN=bBC4xw22n_{y23W}hsMdJFZF_aGLoNq6Ht;F@$RW{>UgnhV8oAN-!vXTlv$ zF@NP;eX>e6HK<8E{jL#`WY=0hzfKl87s%hIFSVF~`}ask$p44F_{fR}^f3**~|LA$#jKGh}bwreF4k`;m|O;{tcUrapTTZT7@%?lTc=;@K1YHTuas zjtDEX@6@CYg8v^`%x$%P(%*D}Ufkw4H@#rf?<|2{u$j*sfnF|EZr-I?pcmeY7~ZHw zXcn$f3~#?!fJ5NO(<;CtaNPM+0UmMgH0f|Pfjiwe`trCljH5@du|zsG;@LB0!y|t7 zEa`ADZmDsx#@WWj8s~_kMvQBd4Uc$@bEU(@8q17}XO|lnYn&&J8qP7R^96XsYqU#; zi#0AVF4kCK9Qks34c_BIf%!8Z?oWRAt(49?Femz;j{7c>&U-K~`k|itE|$)_FgN<5 zE9(D?F z2poN{7vK?}1_bo!kI9+P_^K`2phooPJaE$-YUT26>2OPp0Zy6lMzeeGmGjHw(;)Js1$+ z5IE*CD8M5=(^NV<;@psQIPT-z&Bnz!4~rvTj4R8ANBr!FbhsEdYFx}WCXRg0u?IT^ zc*OJFDjhE7yUjR1OTV`ZNeE!aNOD8Wt zxEJ?u|2@*l4UnV#_lhGwK-}+paGyA8kcU{$d%yHK27RjMd{1_ZBZl+-Z`p&=7YTa= z-<^k~!!uuY=V1X3fn%1B2=Iu%!=uvS5$7J04j13%apRbY$30;jZ{s!gN~cCV`=o4m z#Lw=NzE_BG`;Ch=o-!`hcv>7aV%#&b;SsO#taP|o<2mEv+2@UmHC_-$4d>Y77X^64 zYrG^KF4lP2xLD&ANr6X=6F?t5K2@3CK?AL_a94e7iK zbE7Zn;#;Nfn*ue-O%7sxr{0pzPOTGsr{0zhPp|CMI|3X6$4G46BO@QC;Eg><-B z<4fb>*{_U?HNF-{4d>XYZv=S6YkVsmF4p+YxLD(RnsP?Ox`AlCnX^sDp^VU6JbKl)8NJm;MI nT{=Abxkl3&*B1``puQcZAJVsI`h>o-Oh2seZsA`|Y^CrYS5b>g literal 0 HcmV?d00001 diff --git a/shaders/slang/pbrtexture/prefilterenvmap.frag.spv b/shaders/slang/pbrtexture/prefilterenvmap.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..1fc90a6860e5247942fffcdd14cbf419bb348efc GIT binary patch literal 5060 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 O>hQ+E{_2ITOa1}#RBWUG literal 0 HcmV?d00001 diff --git a/shaders/slang/pipelines/toon.vert.spv b/shaders/slang/pipelines/toon.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..c5f078105afa293b0bf5372c0a2775e4bbd6b254 GIT binary patch literal 4516 zcmaKu*>9C)5XL{+TACDDY!stdTIzzLRkR|CtW}Fj=|QCKo*ddkIkoMFhf^pn;Rwbh zF5yPKFh(SzI)JN=-( zu48V}Fegcp<;marjVwy)5|H^xedc2?kcZSsM+>Df?4{C^(n;wl>6CO@daiVVbdj`P zKh0XnagKi2D~;_LuXN_py&2Y+#n!N`X?e6TA~=iXd=2kTN7AyedCA4X^1X#hxiqo8 zl9mfY#r&?3v{31q=*laqw=kTR_f`g1c3qbwjXFU*GFYe-SgGM6tvfdL< z%IR=%pi)Y8L(UUR?W5^nk-{4F14bW4N<+IVwQDG{KI_N$&Qx}D)|28`rFnlD=4E+91^c=rUD_q1}DF0Ti#FF3n*2$)3eD3y$G)b!Ki9affyZHT1$R?lj{b_sd z|7AXB*62L_;9Ed`_nEKgGhgmgKW`2P@#N=?;m0RGZybHzIQmnw{Au&&D2n@?mabC& z;DiU^{6F&O%Ub=We&&kW-RH|l?d~)G)V@)<+O)Pysh#&EhMq5zf^Sm{@77_MmJFkB zmrB7A;;8X5DLCTT<+8!3+p#MQ;~tJJH;g-h!EvP&j(GMe!?nzuU13;^yV|hGagAY- zqf;0hG45LV;E30!Pj-eyj+KVRv)3CIIc^XJhhy}rOA3xS$BnYVBF8GjBF9aJkuRrC z(W})``cHqTpZvaevuxghK5-9teD4<7ya)Z_KJfY88ri%HedAv6vd7=!S}C05CI_)T zQ|o0jQ~ZtkOl^=2&RvzPM>Y3$K8fSjxECAh;hC0!4bd5R@q>YqtCE-HfLDm*d`1P$C#;m zq~M5iY|rffbKGlKt`TYI+Wp_*I5A~DZ_wJL;JJ2WY0gvz9FPrzEU)%>i-+Mqd z??T_W7rg8-Qx8hvBsV#T?bBDSN$W$>W>YO$&!|6V--?H26T`m)M+|#ZHaK}5%gY95 zetk9zvg2&-ln;i`N9JZg3XXVh2W5jJjumBt#W&q$SnT(ZVf9*_W4CNL;@OgXaKt%= zWrM}I#|(=cBZfteQDJbzxH0+Qh;yW}!6L^V!{XV;4T~IQVQ@IcZ0?nUBhFEg4Hh}Z z4T~K63?rY<(SF(VpZ-uk`F(FfHt#^6xCcDGcR)7pLBF^Ue7^UDY~F>waW8n;V>X|Z z!bxs&5bLw|lx$`*&fe4V!8zx1c2IVlv#NYB#Ao0c*;N3E_vw&qaKy30vcY2So;A#S z$J{tA_bm>N_H>O5@wU zCjXF>I>~)n>TmSAZ0=6IaKybgubrm$L73@UHAQ2k*%TLwpY2mko}1Pd|_ijyU$AY%uC^ z>?6ZspFb8xz8Lq3d~n3iekvO*#(id3%=fu4@;SyFd?5u#Jl~hH!D7Cz4D++h!Pipq z#X0y!K6j>0a>uv+Rz7#9UO3|3ck<~0b;HG;zw>d~5QWFY_}A7S1l@_H8==r;DTumo;Y!FGNERvqlSoJx?tB8D$;Wb2==rX3 z;|+6X&Y8I<=U(6Ys9UvSW)tgcXZ6f8n6~*2Q+G^b%AO*L;*>^L(RA5&d|kD#??st2 zfj;_idi*WEmf0c8#kAbHZCd1~FpJY7jPfYi?DA-zh+LQ2fz_PmGry7xG)D>+7#|PZ zFTKAzCwCtM)q!TlilOFf%3y9c7H%lx7yeV29(ORiE|`B+1;_m#{kCee^MdmoRcJ9c z6-Ez_XoBhEk(qBP!SjwRxSJ5#Gwpcb9XWr|EVxy2cnZbwpSP07$6PAt!~IG9NAVAy CNg)IP literal 0 HcmV?d00001 diff --git a/shaders/slang/pipelines/wireframe.vert.spv b/shaders/slang/pipelines/wireframe.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..4232d9ddb4b68fbbfaf4707fee7acb4e2ed94717 GIT binary patch literal 2212 zcmYk6TT>H35QPWA#S#S35^snByr3w8Mnn+|pn{i35b^fl)n;h4Dsh%JjyAF+jepdm@4HEy zm5xf0qAKxDk{)EW>C%*QT{=NLQj4>g6|Rd~H<#9;Fe(w`^PX0iSw_+x| zf5yj{KPVqDe@HfbL;5l|a)S-4Hs%I4tUYFgkHURLEAs=#zv_MVFUX(MN-lD<|4l1> zSnXThr}jDR(;M%(&HMDm{h1G+-7)dxW8UP%Cm-|1pV6Iij`|R=Kk}$$USDe9p5Vi$ zhCV5Li#kg$MJasDix~PEkrt)vieWCJQZNLJykk;u1dRKMgjJhrE zrpM^PIL2ke5uUvz9~`l>w`GHcaT6X3IqrBY;BVSdw!F@cEGJobn{p7d3S=rnJbD|G;Z11sb z?t^*J4}7-wL^k)r+~^Bl_IUG8rErp)9K_n2nwQO+;&0O4)Ix5zdgV<$lY$|3-(}h0 zh|OeCb{Rlo*plqBG@R42$HF;1_n6I{IlYj=5uSbNaV`HjRy-EQt$Hlvc;&H>^qNz9BabhFpM`L`j5T&N7l=!l4$C;`E(G}_UIJfzb>T#0|cl|R;v zFz3771!1mKy3VQRt-9uO>qBmEz&W?&w)M;T?s5)h#1*AGcTu~pRlCW3b^l-w`94pE(>>`!nC`h^mQFpxW74Tt&h9)Ro%ek%A(!z#`gmfDpX}qw{hIYLC7qbEve4JG z#Q)#ui;X%Tx(~CQ$*}pu%}Vg!l3-_d@A4)W@0WYwV>#xfQ-gk}Nsa}H<-kr3vn^&e pc>H(^mY;XW?(uocYOYGBF1ETj_PZ{DXaC3A277}0(w2Tp{sD95Nb3Lq literal 0 HcmV?d00001 diff --git a/shaders/slang/pipelinestatistics/scene.tesc.spv b/shaders/slang/pipelinestatistics/scene.tesc.spv new file mode 100644 index 0000000000000000000000000000000000000000..321b6d58e4560ba884bdc6a617bb4590b7b1912c GIT binary patch literal 3120 zcmZ{l+j3Mz6oz*)GoYXn&ZvkR@W4S3PlzHAP!pBYMkJm1rZFy~Ow ztnp)D*NwSWhBwu7jbb&UF)jYBU>rMtcA-1B&;`PqwI;4QUx9l*@-vA z>CQZJxi&U6@%7lmIGX=@->IoDCcBD!MqAHZyE{I)KeG1rV~st%ms#KPe=Rcia@dES z?^5;_`#%vnW2;zI_j6*lJO549nVRiZ?fLf1<;jKV>C^N+me2H9A7M2A1BrV-^Yy%|`upi`5A*!?N*?*W&w2h^aQEB9j9={Iz6;mW zM%k5oO^uuNdr|Mz+Nim6>sihEw&QOd;!U8Hj3u_2b*xA3y7C7T*MA!`?nxi@+&1F7 z3a!M?!0Gc?wH>IHkZ2ozEinAk$(%=&v?(+Jw?24UVnAt zwi8%4t}Sm-yPF`5v-4E$Nb%T zzPHbx!Pcpt`~D?y*EtOLoP2KsiQ9MISI*<^>+gKoH@_p}_I)Jd_SyI49*noIRUh|# z<@3I;ocq3lTaWK0xb^sdjQk+C(S6%o~sN$<3Jcdl%KbXHQ`E zAlIIR+lO4+4lnz(opAf1-x1dIK0SrGj@`!L2FR_QT6Q?RmI0>F1uT=>X%uNuTRu;5Nu7pi>T=k*qU%uNKa5qJVvF$v=2=?1zDK#S-cNON`rGvu z=6m`UKFat`((J)W@F~pqr5-V-!FkLXxSBEkj=hih2Gt|xJUEZ}0In7>W8e#zdc=GP z&SO4;t3}KwVBfNO#C!_QV=ltgBIYyjB}_eHE`#%!D{wVq#u=|-_U#I0%nHT{O#K`_ zp6%yJW2iOX;g?Ap$h4WH4QAS0(i)l8OwI zjMuRnSk(MIIIsB!xY|$DbCdB$Ol=GHC;8Sf`u#&b=hk9s{{D$8;%+hij@?dH@k_V} f{uR5E*gO}@zM_%FY>hp_(uiu>)V literal 0 HcmV?d00001 diff --git a/shaders/slang/pipelinestatistics/scene.tese.spv b/shaders/slang/pipelinestatistics/scene.tese.spv new file mode 100644 index 0000000000000000000000000000000000000000..06ca6acfa12de4461fe64302ba9e0f3f1170feee GIT binary patch literal 2132 zcmaKrSx;0!5Jp>86O=^+Tu=vbK~da^ilD{?69F+QK8YD{;!Ie^5EA2~f56}Ci;3sl zxdj~)xuodttG%mw+S|svQ^%o{(nQ+izu!P=OYP;UrMF-yiThGN)>Oz=wXqFMtH>Hs zL+Z!|GL7^hL&yo_6f%nRlgoH>1s(>s^Vd`AJ5yH?_pQ3SUY}ZO?rc?y);d#Xk*lSD z*4%9Fpy?`dw{$Cw+V_>(I(gJvuccpTe68;mhEA#!y>9RB{8(-_ws)7SJJqevUz*-# z5!o-OuXn2b-?!C7QLm@C`vJat&6(F39pJmyuy=M|`~9UfpE`*kbql>BhXjUPhmJu8TLCQELw+DGB`ZVq)7crT~E>gCQ+ zu1~}t1N#~8Jgph=$HDrmH{Lfa*C*mHl)B*8;oe{WPn`BxpO>+SR;4^Z2sV5U~>mQ4>oV~ zJPx*J_ZU521lx12y9BqtTz466f9lL{e-nr~quv#;`GQ{sn=AMv*gVnCHL(5oj-sC_ zu>It^8*ux{bvNPmqb~Zn1vY2YyA3v9@H=301-}b6Pw;zS-_%?7>2LD^qR#IZI`8}t zv5vOzn*r-cq2DV+Uv1&{8tmNi8VhiDo7Y%`>#Hqdm%zTsyv7^2zS_d? z9oSvuHQvL0FL{j*aDBB!>b%7 literal 0 HcmV?d00001 diff --git a/shaders/slang/pipelinestatistics/scene.vert.spv b/shaders/slang/pipelinestatistics/scene.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..019aef4279dddc53a1230933b8f9c2a364b7178e GIT binary patch literal 4240 zcmaKu+iz4=6vj_43>dJ2je=TAOTD0I6{(0KrBbyMgCsU-Lejqg{}x|N{C;QlDl2{HYF77J-&%Wpd#}A_+NQ>?wNZ0J z6h%9tfAkyK6g5U5Em2eEV_&Bqq)|E4J1odRe+8y;jPOP0}X)tk+7N zHToe|s!UC%-T9=JVYw`~jvY>_lW|#amdpM+-k+3{s;~{w7GZ_KIIWiEj;2X99xoP7 zl#@8^nd>PiYcQTjsP>l+zCKk+C?9SvkXIt;Y@y6|UyxGK~0CHJK=mrlmx; z%;|?*&OVup70WZF;;d}L=|{OVelo3JMU|VfzD$oKve!nBD4w6Lo$OC4wX_CZ&u$$n zI~Oq|8JWm-b1wQhwVYo+>wvJ?q*@+Z=2)NgyI4u9r}9aulIG)TJXx42R@36#pkAkY zxruAkdERA}+jv!Dn9Z z=`}uYkI!EGo3!Sn8>LUGroC&Id}Khq=dH*mj*VE{FzSQ#NeyEU*t`@jX1i00n7_U5 zW<0!|@z^^W5BYp1n0W+$L94$jZ{qJt-~C*uhoj* z9Q<{`C%;4J2CeJ^zd`=>8D7VB2ESDpcQXHG+0<*(Z+Z_0Si89CJy?6_Gd@ZVe79(& z7H?qnw#w!V#O<#2ea+Fs!r2QS_30^RC3nBpYouUS>ws*8c%N3{teVf=+oW)i&-r_$oDm;B=7aO# z!?&=)UtHlcA3lF6_zgn2?-l7Dy#;507a{*&dGvI@esdpYlDnASBAdII&u5FfJgQo} z(Kab}*(xQ6_v(;>A5ji7&?)VZB4G4!yA&J&tFzV&?8ob9IX_u7#aDM7r>_OSQ1AXEi@K|iGY~F)@ zaUb|B_KAXOrXCA8 zpY8JjdqOrid_&sF-T^5%iqJ3mV>A7fY-ZZ{ndzsc;PjfAJ`^x58AcBWrQnFY$zj>x zh+#vr!TdYr1I9Tl??}Mx-Qjpf3Wwi&G~im6_dXjipLZ-^o?|#*p5r-TaQM9E<%1)3 zz87SJd5#wY=J&o7FwgO_FgOg$$$mu&ju^+QvcWt@Az+^4c)+M<^B2pe|MZ9RQ{Q4E zvUvyk#694#*l1?!|39tV2R@69$>v??8}~XcCB{q_rEpT48syq+o{-Jl`Pm$o56(XO z?kvgPCguLj*@P4f0b>SUlY%4Gr?PBt#IQ-(V7_;ifcf4f0i$=uF(n%gzxQ?d;D~Wl zWrO*=TEIL<8Zgf>EesByHzOY$F^*Z;V4hY$i_2rvLPZ^Hbkq^Rjsd`oulpvDg{eya)Z_KJZ!WtZd$ezHu*ji7{vA zq;SqlsX?xN-@PlFnIgw#>OI+hrrwtihS+<5AR8R9o_r`995L)8*wOk5pLafBzTW4;sAm}O_=OZ4vGaW?8_d`HDqyyk^L;I)o`1)0vZ;+CE8{;3qdtmQJg@(l zF3A5$3I}z_We(P9{aM-~CC=Zqi&}q?wn;0AGWG0dJ*!UzU!zWl(l(mToc7UByCqKke_95P$jBUQG zKR&zLr{=wBVa9#ms_xpayeaE0FWRDdUAM(s1^Kd>oyDM^xywJJ!kHJCORSD9KHF%& z?3MiMm=R~x%&~Lo2Y9isn}bJq^~#$c<^-`9`FDF literal 0 HcmV?d00001 diff --git a/shaders/slang/pushconstants/pushconstants.vert.spv b/shaders/slang/pushconstants/pushconstants.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..cebd2a2ffbf24e98830ac66ce9ced8eea77947f6 GIT binary patch literal 3468 zcmZ9N>2s7t5QkrKkXRr{DTkVh8{>hZ5hNmtKsbX|#VjJ;x-7{88#j65W^>>f6g)mi zDgLv5vC8M!olZ?Lsov>+W~P5LJ+qtszVV@AU|UfX2aA9BwCySS3dydbzZ>iCE_QVN zK0X)g%_W0zY#(+Xdw@NP?Z*1~bGGXS`I9%7mRCCy)p8{<=k?gRvQ@U3HC#LayRg)0 z->#O;rB1cpt}m|CRyy;OM-La<`E%U1yt;C$x2k{+b-7w{6q=o8+1=kDWA3l6U z7CVb)=xa0ePP@5rrBk-+HygDZt+L*k+?cG9f2O`rwvj(Fd03sn?tItI*E@B4&o)Yb z_3W(MO!KyPnd8gta-lKT+l}j;>pmCD`9_OAm^EE%HrDBw)!(h_>h%(TptuNYm2=&~ zsrMf7df9Hx_eu%b(XIVMXRNI?+MUM63^z3qrDEevAi;yi=?V=3bn)iK(SOhS?&1 zwik9|-)Haj_Qrjyq4#)t>tpPvAFkd$JojF~_LF~z-gqFz!zp%t1-g^ob@IK$)}VsP z4yAZcibsj9p*c0z@1=hPlgIr1_%_E6&^zw@7$3uTKO=lr=pB=dvUh7;>H5988i$$B z+E_ztVEkN)opXSAir#$YSI@Jb$BJU}bm%vU%;EY!>8(Ya=kF9-j}werAK%!vEcT5> z?D_qkdPe8FKkwB1#^(19)i5@{cW8W!w__gX+GPI{x%ZQNx(DxG{fKwrtAB>I*7iwE zeQWL<&+!x{pCyAio=!||3(b4vaC`(auk*}nO`pd+hj(vY>-z#Gzs#Hp{fn5)CR6($ zCb!9~|4W$M7VKqwnR^L#C^731?3Ki%iC-SxS~k;HP1 z*I{bp^NteBZLz;ed|9sXMq>HeV~OP&Z^G0FX0486a$9J;g)hrB-cBsnIFXq7s#MBa zy@OeQ>*M~-A7dx+y$9>$In;@M~kH{Rh{ zeBZNX^E~dqn(p-+zH|J({*~ATe7Sie&qaK>W{W)WotTFCort$<9WG(=$nkDsa$DrM zgYGb~|Ett-UVJBJ@W-+EuKAsKACr4m75Z6BW{dY)#h2USPA}ujZNWakm${ca+gkf^V)?vJ63aC{O)S^=45mgt?{i|gE%x^XzAV@HGO>K^ zSBd2sHJBQ~{7ziMxtzWbBUQR-tRoV^|wCm{~8u!4SesxI(ZItV(bRK z_hG#}k9sk76W@EWZk|hB$EN6SVQQM&9L|k5wSYg4HL>`e{Tg5HSu6A{OlFJwUc{H% zq9#lDa$B$xUzXQtIkCJ>-y~+8LZgkZM!t51SZ)iA4!$g(x0+b4v6fh_u?|xspSM9Q zw}r-Sd|9sXZDRS_?-I*3zK5w1%s2G|CbxygkNC1&my@9&pp^E~c9 perJEfcg}e%erJEjmzy`(ANX?L?{{fLE@l5~# literal 0 HcmV?d00001 diff --git a/shaders/slang/pushdescriptors/cube.frag.spv b/shaders/slang/pushdescriptors/cube.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..26d7f3dce6893889f9d1c61f659dc1e70a2e7c09 GIT binary patch literal 756 zcmZ9KJ4*vm5QVRKny7ggNsIwWv=IbL5kxI4tO9A&QWlI7$ZocpOa<6Z`lPUcvY92KDC4 zc%Em6Xm63nnn^PMTwL7Grn5BT>{)V;Pb}d|ndV0n&!^)wD;!31_(C`!zvN%R)okB! zvPi#1vq`cTMQIejyrt253^`oQr=Ig{@(<`a&oSneZ+@3(UcSq;HKKVrYt|;#dMMY4*4f{b z#N^a(5$*RIp7VCy!9)1Iv%bs9*{r(;JD+!?zSw!Zqcv9FJJQVC@13Y|iMn;`Ipuyq z?tR1CGy9LIFZPW7E9#4#xq++yOtmxl{pGCFM(iQq#?|sHKP&E#we{w1naH{1{+Q|t F{|Bc@F|Ggr literal 0 HcmV?d00001 diff --git a/shaders/slang/pushdescriptors/cube.vert.spv b/shaders/slang/pushdescriptors/cube.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..fe201558478354889e248ecb025d980ae8b5b244 GIT binary patch literal 3448 zcmaKu+jA6E5XOgGHeMnax%ptFAe00}BWOevfk4DWbjc#dyDmdA#ErWE9tn&NKc87lAqv-IMKgd z?_rnnqLa1-SGm;a;q&i1M$H~JowxHsdBe$JVaXE z>2hAImW#(Hk0nV>JIH4&re(@Jm<%OPYo0$pH=TB}B5is$`L$||yp{osstzECyIel*qoDwnlEsfWHaKOq($0ku4hG=ZPaxe6WgMZ%RM|Gwv!&>oLvLB#-zBi^4%V#eb=csAEB}L(4l)(}AzHGRr?Y$=qi+QgY7CBBD7CBxO21m?$O))sb&v!~bSmb!!u(9P!txc6PdHEnZTF)Zf2XISKzH!O1SPY4__?*ql) z4DaJZ`CyUbBg5j}j}40)p9q7)G2YatGH`}-d?p_(a(r%B; z!ReJZwJZZ;fN|en%D@?}Nn1WR!?BKhu&7hlu&7gR7&Q{UG%<#P|{L?7_@+K=+N5A>oR_V-(HFd|@uq&3!MQ1; z2Dx+k%gNu)Uu45(nyP*{f5YC+uky*cCHu>;-{gZ+*RkK_gY$kJ`$InXtn7>w-O>z( Ye_Qh|^Y3WhWBxtOBeMT=l9RIk0W7Qt0RR91 literal 0 HcmV?d00001 diff --git a/shaders/slang/radialblur/colorpass.frag.spv b/shaders/slang/radialblur/colorpass.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..137bb8aa11a97efddba1aababd754634a59a58e1 GIT binary patch literal 1356 zcmZ9LYfDs76o$8Ranel3yro8YAu^)Ugt9~hwfq#0g8ESo=){0CBd6&@-}+_#Ej1B* zp5yE|xMaDm`(5u|`%JMgUkRn25W+(E&VOY%6oQ$-P|RZeq0kpf*aF&28Z8T7(PeZD zokXkjTd$x+{vKmJTjtN6M(g}{=lxdutes{#&)nw@4spr#XLzTrPWq?TZnQeJBu$#f z^)&g}B>AH|x6A}*|4N$YXQ$~-nw&H!?-PPi3akHXC&axOr-v9j^vUT3su;`1SkA`Y zEnj!$Y_4uRhbkl8oy}%9zsDFQSEe=tRxj4Q7?0C4oaIB9p!O8s*lpW8ij{+T>*HAK z?$-J-GA^8&I4fFVB9!TKDZ@?-G6pe>cSXi054UCVAseSo_6yUKC?x zn(oh7`#k@}Bw}urSnlrCeq*`1*BCp`y*ksn=iQ?+M!b!kF+k*N{4I-|SD|PNJ9f{POxWz6yTKP@3$a<6r;VImP{75@#lkm#fP+{Uo;lrTCh2G&?h2*05W+~<&^Mzmv2i=JMV)SuKntOd9ZjXE$pCtdKr)% z5?_~Q;*!NXEbg#)r^VDcpsd}RIg`8tiu($@g^gOg&vHCIsF?j8AD0i`aebpLHGuW2 zHnaunHyw$wR?VewLOy4qG4-6Zn03x)cHN!tlrRSQBbwRInTHiW&IEXo)JN20Jxl`f^X~H?| zWq|!wMD4fqO-(&A_&x5G5C2{5MXLcB{M-pS=rt%CkX4mKA44**VHx|-?6i!1XvseG zJ0k<1RStJHYM7=1L$k9oa0Yqsos)qx92=7l))rys4WnPryI>f-gTZl821mU2lHr>E z?Y(SRoHuS*%yGrAm}5d19C6-N#o!FDZ&E&3%yG@Ic<*(?VvZZa;BXABZpy$J&T&gV zSj=(Tu$beHVVqZ$QfM_LLx1$4e$Mx`yYjgQbfOPiBFQ0osH~NB? zHGW$UWm7WF<_vQEO+Av&o8te%-_*2xaC+rUJ(htn{Jx*a2WPk@PvwI%9D61oEY|6{ zVeL^~#W2?$onFY`i1*GIuIV2~)v!2k*07l4rC~A0oG>`zyjP0B8Q#ade6W~f!LWGm zYr|rWH^Sg>j5qaG2F`Gfck;nvj`xPe93KqhJiq^s^3flCsGswF?UQ`&0iEar9$%}; z=RVMje&F-9&+@q!bfYhLS>sJ5GB`P#Gd|1s@8aIR$a-XpvR{VP4QHQY4f)`_&)ZUm V|6nluHO;-|XPSp(f27Q$>@T5Sr)2;D literal 0 HcmV?d00001 diff --git a/shaders/slang/radialblur/phongpass.frag.spv b/shaders/slang/radialblur/phongpass.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..d975a832646df4fff28757918c5bcbd514d43ad7 GIT binary patch literal 2164 zcmZ9N+fGwa5QZ0}1%b*z4vKgvs0jvbOq7En1qCcOlFwG_L2R3UPGHXz58pR-^9Ml=&JOH5 zyFqNs%}ZHbDi#XIb-#7aTE(_~ls`Bwc{S-V*Xj3?uQX~W*=n)U$a*!e{I*c@4$CsG zg+0gA5q;Oa@=+;YOV_+yQSL2K<%qidQ(w-npF234Bds{@;F`dKbANE|2u|N{_QSbX zI1_=>C!CqUnFE{!r^Zpi^1;UhR)0A6QGYT)%z$h$`4ZaOCdu63LyGD1?aVmpE=Y${ z2eAW^oPizx6-oTmjh~wEW1kSmM;(PiVg9zVaK?C(Z%#UkTq#N7>CyH+k*+m=M-}2< z5U@4FVwYui?&E^-m4Kh_O^Y}0!*8+AgV>buHSr(cGbuYaBaY3$Ui#gXb!IoHDQknd^5?1w3_Zp zr>2NtH6^8EZ>|X&HIbJbyPW{A~jsIJ)^9}hF*6~6*-wf)> zhPHL-%yLEe9NIRd6N}IGW~E~%FEiYd#KwF*N#?<9nBlJEp1^N z?2_!3?3EPs>6eD9Pak5fg~jEpQcIQ$Be#p4Oy-kRS;c&B7dxAz?RZ`(!god`>H0*R zrLC2zEJ@?JX8q!P5@*$wYF)c0;>$^@G7eN#MNvD*XEow1MstTJq^D0z*6-yNbBy?6 znp|$qX01e3vY%Y;-cA}#E>YA6j9$#8aii5-$f%@Gb<&gN3yJLhye|r+tF@%1j5v+k z^()OZYpzVFgO$yq$fbW<v5y|4ZGdu(y;cx&!bHq)Hdx%cPqwngsr zOwQkz*L|-J%}vyszv+?LW|a91g(u-Rkc^qb{z z$9Na8QHf)4f~`s5;!WUVx&LI>&3$H=`D77ip2J#r8+^Ekcg*+N*3B_#fAIS(>xKhIH4GG}w^613uENp*Qa}XYoed=P7A?;+&6uR>E?={arWD zugE69BzaW%Z%M&$J;zFVIObC zzLK}v~7$y~galaQO;4CosUXp;b9IMI(qh7}j8bC?LsIKsWthD&X7%orBty=Pd+@xEap#|OgT2=hLa56<#BK9UU< za(rx9xc3voLXJ;`!QmJ)RhNLXoa4M~u#h7*EabRg80Y!>&*rxNmXhZFobR!QY~F!B zQO9|S$C|Qv5Bfzt@OkW_Y~F>wQ5U?#n5j7loSe-Wi#jucLRTvy$-WT%0S z$=RGiuFurZvY9h-CiOq>4(VSc;0TKvsmbHlWwQridHky8js3q$Zb-U$-M?{e%D*KU plMp|q4&Rn$rm^ox?=kzX^nlqNY3@VLx-{otZ%B_w{uTRS$$!`pCkFrk literal 0 HcmV?d00001 diff --git a/shaders/slang/radialblur/radialblur.frag.spv b/shaders/slang/radialblur/radialblur.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..26486d4aaf3b2b17298fba4bf49c17a48ed86f70 GIT binary patch literal 2596 zcmZvc`)^cL5XVouyM6cqQ32!-dGTybvnF zLHSUa4psO#)XVZcSeSzrp)KfD=rI1;C!q>|&%(W1?;mSBo0XV9$G5ryXOx4u8;Y zZsb3-3;P@B+u!G{(XMf7VIIA?oshEb1$}ngd1rT2_`F&AM5MfT32czH@~m5gF8nTo zZLZwj9*$b)-+en!$b5?6*hZ!z&0AR_d3>=?%M0petVF2%9+&Y zyEECp*C%f!tRmZ)8Xa~{?Y+_9(ON&>8?9x7thc>0$T~g1&*Ds-RfgZNsHA-Jj(XA0 z7ICV@oSw{NqL}&9ajxU%PMn53>h4Pe@?A-vLH1myR{PzC7Vcr#U7Zc_k zF?YN%RS1F>}??-Em1=eLCv;oFJ0B zUx&Q=99-R+^?e@hU2*L%!?mZ_r;x`W@pa}59W0j++Df4yX5yU z>F$f)LG?xK_UskNx2Vs+XCdFxLT|v&M65$@=jpdj%ssjTb{6jUPTcb&_uR92NZhy+ z@O{YI*3r}-K>CP#Qmh4JWBJY$%WtE2y894W%ozGzp%cayH;(!FG!{B6^r^vFo`=ML z#Y6o9N4bRxWj1% zSCN;YpX0q1Wbcaq6tPugXQj>eI#*|)>`bpgf3pjR;O>O{58izY{u1QTei*J@u6`uy za`hLZF1J2=c>^-v?`SvSpGNE!{7>>9hkO3PUz_?-$UJi6T8Fwed$A7x3bGfz!(7hf zYpBG_+~1&^JI&%-WU*g}q5pS~n7@&P-9A#5#Ps#(C%y|g8)K>G5!2tEoPgUCx%$bd%Z*|0yO8gHjHcd; zSRJ1BKrHQnIgI7ZjV)JCd*K{XeV-#+pMA5wJCN8AN;BF(c1HDrmoxeTS=>H)Zxiya PxOHqr>|cIGm!SUuI*iTv literal 0 HcmV?d00001 diff --git a/shaders/slang/radialblur/radialblur.vert.spv b/shaders/slang/radialblur/radialblur.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..ef2e0e8e768ca4ffa3d9dab796da2d49479328dd GIT binary patch literal 832 zcmYk4NlODk5QWPu#x*fUjXR@34H`u+;)2UfL4>*JRpu~<91>+1M8SjT-Crg6m%IqR zucrs?@OtXKuCA(ilVYJ&vC@E{B*4fJ2$s3udJ?Sf4bR)m0Ue)U1}aU zJ>Z)HoZfI2oH>>qGi#_KGpx9YvUz3{4@wJ!rt&L#!b_eHdCn};QmGvX)Ct7LeT>fe zq|>!&ZTb8u#pJ^|pA)DDr&mkRI?wrnO&3=A{3w=gfI5&OCTdzntSy z&bg0A)Zm=^cm(h0>rm%VUAy%3EV^f@Y<@^TYA2G hZCx=s?;olg9&ZTfd;|PAl>_*PPK|7*?6nzd#p9xKk9#GEl^%^d1KBWq&jBpX>gX_GQ_ z@2Ii&8ilRW`u%&NX3@kkhP4+Im5_}IeZM=9F%`iR zmW5T}if~Q1sCC563vvA|$g)RLe;HYweKTcu}Y5U#dm*G*nNo>mI8tE^FL9gWvN9YN2Tk)-Kr!yY4Eia1y z%_V8??Khk4UOf!P&Ctf|{S%Y6b!iX6VB!tCgV6H>zu)Kt{&8R8(`o(4fjXVlYs!I| z-V_*c?ggigaP9=BLvZR2r$_LLY(a4GaPGyxPv3}VEGY}(3btF(nib7c((=Np;^`%v z^G>ocy(N4J+gp5a;?BzwM;`bWW$~lKbFy<&?XEbn1>y7QY1#2R;>Nt+a-7GQ{!-j@ zeBJur?0(I~%!cOdTeh09d|7XFDg__jb^j_+vxTgd7D)fxS<=H$q}&t$nX`EQ7m zKfS^4IK7$W^k$aR8^_6$UNBhC{`7(~9_S?z$D3fFeHSBVV)>5veyAs$+VY*i%i`E2 zf&3g_(VYAozpOd=Iet}h^2?|btiLYsTkuF=FQ@ZXoX#E}l`FlwC9np6MmwP81!C6( z`~~5I;@O`!NKSddlSW;O0y=#sFM7HuP^U@uoV_!ATi6lEnK!|iyoI;fgzew1=G5n1 zHfj6K9pLoylg_Hj)&z94Z>sPmS;kMDi%&n7`u&RPj;$z$8k6G>^@4bMLL7G@f4+VE b+|$LQ&Bn8iyAgjNuqUzf9{x+6e<=I`aAtoL literal 0 HcmV?d00001 diff --git a/shaders/slang/rayquery/scene.vert.spv b/shaders/slang/rayquery/scene.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..86b91b8757baa4036abe5c37b1205f6ee60ce73f GIT binary patch literal 5564 zcmaKwX>8PG5XS$sSV)Q-B4QMwfCq|J(Sj&)i=ehpM8LZ&bb-aTi^~Ewie$IeskO6etC!^)t7}G{M7(EG&Qi$fmGmmuW%}Nn%Cz7NlJ1f2 zmF|f{6!sRe>DgR! zs!1urdnAWzZKzA-bD7pz`D`w=DBZBIDVxgIwAM6ecU@{pHm5R1)ToLI?I0g%OyyIo z+~F{-vnS1H*q>KXz=$u+WtXHES}eVP;%*MC%MH&DTiEo z-%0KqU42e^K{1y%>Lj<8>yym6yk#f3bF;aoMoOip^kaW5nx~{|;jIS>NAP)Pd~)%b z4}AKDKR|1Rw6}Dc&h)n%Dj%7uO!~}z;@F7C9pk;gCP*D)4_I5k$_?A96@F%VuoQ8B zNYO3$%saD;5NGydeY_by{KVVMhZ~>X$9m~6ephKR7v|QtD9DQ z^6|TyPkxpB9$MK4-cSBP1-yt2H@~ki?&E%c*@*i`$maY3`p$d62{ur7;XS|x+Pvet z!pR+|hx2(G{3`RwJ5>G|S~(LA=Nu=Sd*f5zDru6mjVFJ*EY6PkJLP-LyJW-X{C`^v z4*35upZFO0^oY+O_}phMqt9HrPd&^99OQF8a{xa+=Q9V<-`Bx!@8B~BF`qfW@1pP2 zf3W;fns4p^FG75;Jo+$J->HXLq!#yk%BB|g`8lGNi8`xF>tHFh@aE+3CPSp)GnK>J z4mC_m0i%ycO2HBGxZ_b$aKy2rWrJ~V$Br?KIvg8j7&U>xajX=Mxc4~2wUqV_H!S8I zZ&>6w!LZ0tEewvBccOf7#P7#1K(NR$!mzmaWWyrIDZ=1zj9%49!4c;eDH|+uj4~{8 zoN5^7)vHtVYP6L8(;x27`5rq>Ht#^6r~@94oi3aApkLGjpU1|?=3VF;b-_!FpVzTc zI60d$$n}{TFPoX-XV_g0nXUdMFVV3A{nVR3K0VUc5| zFgP4zrp}XsBhE3aVE>=ve8VEgY{NLu-+zwm$x`~m{W;%bb7k`m^ocs)@z@2jc@O$U zJ@9$#LfO0veWNaTi7`_bN#W#d&LG!k>SEcd)(IM3fdC!7A$AMVfj9$O}R zo|HaO2Rt6j%T7t@7xlpBvE{PoOX(YR!Ap#pS|Np#vpIv@8Tw7xUF%9|rKy%eJ>0+E zW~Ws)Ijf`_47*Y`IOjTcm27b4*Rj>I!N(S~_PUi$Ol8{Ewj`n1xLK!Yh||q zNE}-yyGO z{B!Xk*>TPumJf!|6K3EMDLCSN+9(?wacq-pu-LoJhQ;1(G0firjz^_%#J!IhuBF8B zxM4Bx3Bw}ClZHi(r-Z=~^PZLuj(8o<$OelX&l(o@K4)0ucwQJBjxlF1NWl^3cu_W3 z-(#=J-Xx_@)B%sjUX#69O24QFK99XFdyAC5Q5U?# zn6o#eaB?~d?1A*?)}hkEhUbR42yXm8x}b}F)VU?Dh!U8_nCZf#OwH6 zHdy5N!mzmaOT!|^SHj=`^Y{E(HvOU=`1qU9W8cW%Dy1%XW9(b`+oaS7e~f)6pFUD2 z_aNqP{=IxSQG`0Ux5s~w4KIpxjQ=PMZWQSl|4A79DB^Ky+Ae>Glsmw~S>*eS{w%w< zbcfXM^NVb76!G);H{>q)ze)#5cS@Pt?plA7g0EK&{_loWYVD!FYQg@H?v_rG5_i5o zW%K!qBF?wQ&i+dnIpg$-d$g`Ld#_gR3cgQkPqW*#vIm_14}ce&{|n&f?_V*Dmi`CS C4CGz_ literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingbasic/closesthit.rchit.spv b/shaders/slang/raytracingbasic/closesthit.rchit.spv new file mode 100644 index 0000000000000000000000000000000000000000..dbc3087bb1ec57ac32c818e925b4259c00c38b1f GIT binary patch literal 668 zcmXw$PfNo<5XGnewQ6gvZ52c+UIgzVh)VGyh)@-JE!#9`pf-@Chn^JtYJLmB&*4Sz z{Wf;P?CiXGGkLRHDjwIYTrjf}JJ8N*S<&8FxhGS%syz)ybE0L9E5X` zgPS-`rlKoXwzmAxEoZTts=n%DLG}`5BR5-woGZf76U^c?Of#kKy|T7Yv>bV5xvs9x zRbhQuPyK81#MB=uhd!{ra_jP6nicF+F}#M%?ERWrU7g3c9cs}EMy<;1TN_wMao6Ly z26_?qWGwi5^6;s@P|Ux%Q~pm(KkgaMnG_XtMl*~5|0pWUUusA1nvD7fMa;vyfU&@s zWm5*u`uNATbY@0!D_&FQ)w`~E+rr?I8>$<+c}H++!3XNeT>CP#Gw+qu62tw~6z8%( D>+Ur2 literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingbasic/miss.rmiss.spv b/shaders/slang/raytracingbasic/miss.rmiss.spv new file mode 100644 index 0000000000000000000000000000000000000000..8d1e7b12271f2e3b529b66aee07e6e77c26413be GIT binary patch literal 432 zcmXw#%}N775QNL@W)q_(hWK-nh!-I_iy#EN2^t6rxh{i>F2o4=IppNi<)*LTb9fP~ zZ#MQ&)6?D6)xDck&T2}xB%Q0{8*8hgk9O&)G?eLKG|q2t?(hf`H*NTaZtyoV=uWHEM1uf<{v7M zPNQO}cjR~GT-P|ZcFmrctxkM1i(J>Wy8XBJBX{Vy5%Z-^Zxgd827lKcKK<0uZ5h~q zyzlqd=iQ+1D!irv2T;3mA9MK+XkBHFO5GF C6Cd#a literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingbasic/raygen.rgen.spv b/shaders/slang/raytracingbasic/raygen.rgen.spv new file mode 100644 index 0000000000000000000000000000000000000000..84a72044139a88e511fd59612b9d9ab15ea4510c GIT binary patch literal 3924 zcmYk8+jdk%5QaOMNum(Ja7I};Au1>_f(Aqo2}TJ=6N$tlPPUUxm^hhOaE_Am#d5Qr>g#{uIjGtnIYHM(cU5k;#$xMygZPQ0 zHfB8g<9wxPT(z6Bb4I07Tp3K0sZuH?@2)965FOPvN3uHj$l-E26ji2TZ0azxiOkNs z8`ypgHJDv_T*uAgE!nJfPor^F$4JYy>c0Bm`;^Pfnep$s6MXIg{}1o4lHDx8?^Ne@ zX{4jBv?iC$fcqp~@Vv#1V-|2d0)3bRwOD69y%2of0CB|pFwXf`X3=__Gm}pr^6@Qy zp}N4gYp*$DhNxJ-y)4qe6jpF(ggt_&P?El7v$e3O-*>>`nY6q&V#>DntJ$a z11olBb{v!hM75dBhSp&CH zJ8zeUTd7z<8Xs_;N2S?oL9kkDWH)47-aRHwocv|Ve@U9!^s@XtvJu;RrS7^;O_$vF z1ULg{v)psCYYR?oHvhbQ*Rx{BUyB;u1)1#eBAn!cKpyvTSzwRmUy=Q9;9r%EaDF~Z z+%vU)kp5F|9FE!ElxBXMak;zK-I8Y3)P^%Ln;O4)lH4uwc@un|SYtk)8}pg*YJnQW zFG^n$5PbH;yJlbb)aM-|_Ga$LW^Q1k-ch)}oVdSLojcj8zr4*>fjyZ&Up9N{*Ccqe z3j}fiLcIyC<$Y=!S^R{5uYCW)@osJXGTGDwNVtBveB!75dcLcv0e{AG56Xt;-JkLt z-{J6ggze&ZdyfmujyK6!+NIYD@UJLmm2{`)q%w{-_k;kCkjI^N3Gj$yvszsc~3?eAIHaAA+l zo(tD*@m$#BIdSwbj#+IL;1TQbyll9z$2QM}J$gJxy#fCnuw6FuXFlwo`WAaZHuu1s zI0tTmUB`Mg!W5ACh?%Z8`VD(L|M4uR{)be%Vj`S169$PIcfod2ty zYs_^0ogeTV^S2&DvgsYJeN8?*Vsm(1He8tZhUdZ_Z+b55@s>Dxgn4hvhexc(LD_I& zk9Ry5t}S{l>@h5k9>y`NNEj9n>+!DaVIk~M@?6+s#Brs9y7A(5w1NdA0DwD zAIOFa^FH)k*yEVz!X6)qqeqzcv3z*MdK{Mx7xtL-T)6gx=fWN*#nHn!-rOkx9^$thRllOVzi)&y0(Hn8@ZV$K$|hD3?ERjV4NpI- z|6LX*r!LHk`n=x@(%%c0goACZnSELI72#?CJ_F|jYMmFZ3#`8;eZ%|5V@~)+%8D literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingcallable/callable1.rcall.spv b/shaders/slang/raytracingcallable/callable1.rcall.spv new file mode 100644 index 0000000000000000000000000000000000000000..c9709d8f602086abd2fff0aca7616f67dc6f8909 GIT binary patch literal 616 zcmYk3Jxc>o5Jks)YShFSlc*p>Yy^7|M6pv4Au8C0HHZXalwe~eHdg*Ft^GGPg6FKe zkhjdv%$+;;&3ms{*r`ToE+Tegi@&QGg?MfLdn>i5#C88>aDH|*m?kfS=V>w=P41%} z#gs3n5!Luy3pyhnlF`J%0=9`2`4;i=%ETS~@NrCBN%_NMJWg)McNbaTX_V4ld%ndp`Bet$S8E`%EG3UAWZvAuHjJ_&ZM(v;PvVGuJW<7w;M7`Nf_2i9YA4W8%3^ zgLqbFg!;?vptHa5yRX58t%JNMk* z{o^`AAEp9egeG5E2nYADh^hprV!u5^>(wsG?Jc_IHcqlLdH2VQX_0w$z)s*|lT3vg z-R0L{6yuRmJ+^6TkLhVsa&4-r4}NsPcKPp7>(hHM>{P$zNi*;nU)(2s%v`mAF8k-& p3p|z+QsU}#G13+1JgD+c$G>H>vG6BVCDzgBY;8x>1Yw?jm~9ibmXy?#7oFH{*H!Hh!Jwlj-a++L4rc zHJxb2*G|wG@sv+z9;|^rNch%?>gwcM#L06(-YE5xyeRVf;^C_5JCC&Nwdb3eJyiDY zm6H~8`e^EK8F1}VH;8h&%BWX~_Q@Ys`b~2A0jf4J1D=_4W!IUrwn^lcv#=3AZ1Tfu zw)b73E3#l?eao_4=l!`WoLp^4LJmKl72VwD6Z}|x z%y|iZtUYFfe|@o)ZBx0PoBP~7ggL~>)2Qe>KO5r5s=#gF^XYI}sB|4zUZ@|AaQhU0 zV)nJANL^iU-VHZc@NWncE7y@C9mN${aO9i9)JL|F?DSHlnW0iw2t050O{l|*o#NEIXvx~d2kC^$q4Lyfq4vv3>!1YT} wS@uLH_e!M9yHBIwGm9GBc^Bd{A>q-KG8=w3%E7561&5q!0~m7O+I%Ga0ai^hJpcdz literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingcallable/miss.rmiss.spv b/shaders/slang/raytracingcallable/miss.rmiss.spv new file mode 100644 index 0000000000000000000000000000000000000000..8d1e7b12271f2e3b529b66aee07e6e77c26413be GIT binary patch literal 432 zcmXw#%}N775QNL@W)q_(hWK-nh!-I_iy#EN2^t6rxh{i>F2o4=IppNi<)*LTb9fP~ zZ#MQ&)6?D6)xDck&T2}xB%Q0{8*8hgk9O&)G?eLKG|q2t?(hf`H*NTaZtyoV=uWHEM1uf<{v7M zPNQO}cjR~GT-P|ZcFmrctxkM1i(J>Wy8XBJBX{Vy5%Z-^Zxgd827lKcKK<0uZ5h~q zyzlqd=iQ+1D!irv2T;3mA9MK+XkBHFO5GF C6Cd#a literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingcallable/raygen.rgen.spv b/shaders/slang/raytracingcallable/raygen.rgen.spv new file mode 100644 index 0000000000000000000000000000000000000000..84a72044139a88e511fd59612b9d9ab15ea4510c GIT binary patch literal 3924 zcmYk8+jdk%5QaOMNum(Ja7I};Au1>_f(Aqo2}TJ=6N$tlPPUUxm^hhOaE_Am#d5Qr>g#{uIjGtnIYHM(cU5k;#$xMygZPQ0 zHfB8g<9wxPT(z6Bb4I07Tp3K0sZuH?@2)965FOPvN3uHj$l-E26ji2TZ0azxiOkNs z8`ypgHJDv_T*uAgE!nJfPor^F$4JYy>c0Bm`;^Pfnep$s6MXIg{}1o4lHDx8?^Ne@ zX{4jBv?iC$fcqp~@Vv#1V-|2d0)3bRwOD69y%2of0CB|pFwXf`X3=__Gm}pr^6@Qy zp}N4gYp*$DhNxJ-y)4qe6jpF(ggt_&P?El7v$e3O-*>>`nY6q&V#>DntJ$a z11olBb{v!hM75dBhSp&CH zJ8zeUTd7z<8Xs_;N2S?oL9kkDWH)47-aRHwocv|Ve@U9!^s@XtvJu;RrS7^;O_$vF z1ULg{v)psCYYR?oHvhbQ*Rx{BUyB;u1)1#eBAn!cKpyvTSzwRmUy=Q9;9r%EaDF~Z z+%vU)kp5F|9FE!ElxBXMak;zK-I8Y3)P^%Ln;O4)lH4uwc@un|SYtk)8}pg*YJnQW zFG^n$5PbH;yJlbb)aM-|_Ga$LW^Q1k-ch)}oVdSLojcj8zr4*>fjyZ&Up9N{*Ccqe z3j}fiLcIyC<$Y=!S^R{5uYCW)@osJXGTGDwNVtBveB!75dcLcv0e{AG56Xt;-JkLt z-{J6ggze&ZdyfmujyK6!+NIYD@UJLmm2{`)q%w{-_k;kCkjI^N3Gj$yvszsc~3?eAIHaAA+l zo(tD*@m$#BIdSwbj#+IL;1TQbyll9z$2QM}J$gJxy#fCnuw6FuXFlwo`WAaZHuu1s zI0tTmUB`Mg!W5ACh?%Z8`VD(L|M4uR{)be%Vj`S169$PIcfod2ty zYs_^0ogeTV^S2&DvgsYJeN8?*Vsm(1He8tZhUdZ_Z+b55@s>Dxgn4hvhexc(LD_I& zk9Ry5t}S{l>@h5k9>y`NNEj9n>+!DaVIk~M@?6+s#Brs9y7A(5w1NdA0DwD zAIOFa^FH)k*yEVz!X6)qqeqzcv3z*MdK{Mx7xtL-T)6gx=fWN*#nHn!-rOkx9^$thRllOVzi)&y0(Hn8@ZV$K$|hD3?ERjV4NpI- z|6LX*r!LHk`n=x@(%%c0goACZnSELI72#?CJ_F|jYMmFZ3#`8;eZ%|5V@~)+%8D literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracinggltf/anyhit.rahit.spv b/shaders/slang/raytracinggltf/anyhit.rahit.spv new file mode 100644 index 0000000000000000000000000000000000000000..1d38b30b5a53f646e23d58a0f7c5ed8b08dad4e2 GIT binary patch literal 4072 zcmai$*^g9J5XMi_Jv|G{unfpL4xq-w2NxD0GBYy70Fhw^F~D1Ur~3|c($n3!-3?5l z0iuRC{|Ch#0t68UeDuK>5*~dqAyGhaUr;th{C@YI8e3jGNu}!hs!mm%?RKZ9EN^w0 zlymN3w-u!^%S~~Yx)OcH>kqv?Fe~8+?Qm1w_Te45XE!~UtJNz}ush6+G)70mXcFd2 zL9Is44%a>zTir8WE9QgJWK=RqF>P_oGrOM86~bCRDpr*>S1cF8{l)Tb`LmNbqF_8% zkAgh>43~D7)gL`|s;5t6Pmw(q6wB0pTq4T#N#2)CNVE*iN-H{<*Wy~-G}-Ix^{6<~ zsE6u0>p9VGB#6e*EiU8klim?V^>9Bi3C35g)Z#h#8Rbee7L@)Q)7VRncDGXg4V7}O zJ`iu%aHUwT$NN@Tx#BVTs7(wbSFJ~A<~=F>fAff8{5!AJtq|TAR>s15G`_V`2(|Zd zrK~F9W9-$Mig{L^)Q4wJbpSD)Red=2R*SDUqHr^3GZ56m4V6-bCM_m?Ps~t0Uux8f z6%M4uwYsOIx7VXao-BoA6GX|Ejn8R!Q?E3{`EYi=ZrmehaY9@z7^{}Tf+8~RjPP(U zUaABIWy;1_l-pCR?+8kb5WAVLCb8Q?&2Q#wdxAn`pGXaAv*w^Yt~7)3t=gzs+$ru) zs{}kxIxFe%n0tr+ssiz^mW_X=WRr5*`7Re`5VJ;_n2dxNJ4=g!;|v)0a-0=ho5bSi z8_sGnH|;t4r{+3oYR->wIzAibk%Mz$SS{jtM@uF2Xn2`y#ztkwpXAE8w`G%?o`~fP zncLEYo97-Ae>&c;v^(zYIof^JwlsdR$(@|5T;%AHFnWZk!&$)3Q|$DZcY3cGeIs0q zSy#7wymdI{u{U3+CLDNx$&x~6u zoAu&fqB-0FZ02+3U~>0L69;E~_seE<>0Ab+;pufVq&wJe>)9g2ev@ZVnzOMzAM%)e z!N1L8_Q>Y%l%4Ya5$|WuiEl{L7wZD=^O$v8pD)SgPT)V_{p< zpX^z?dqG!Ow|Aw9V?Vj~U~0W5&42?RjZxyKHhE8a&hTmB(b3UgWl z()5MCt~#^S(@YxIz<)&=KN|eC$7t|39;2;?tFozaQeASE-%8-<^M>kwFU`2EdicQK zNvMM+FMWXVS>7LHllP!s|BtfS1Naw}i+lW&1b)3@ct1Z&*n^#(;|={HfoD(1&3pP) z0>44?z`uEpe7)LB_WPRWIaAKj&f$0O<1Jbrf5?WX58mZ<34Kr#?vV5i3B2{eJH6?7 z`T*bZ9Qo*DmGo`TTOYO`e~PE(VTtwemuz^;cSklg;4R@VC1 zF~aclJfvT|`O;}&dO{e2aW3u}@%U{%f5Vy2d2CZoz6&kF%;k*?=>_op%!;EggdymL z6;HiZ0p<`x4RXR!V^ID!+0@t~+iJ86lZ!PP*Wo$plAF3y#Sx2-+~k7ePEM2NPNKon zJx1Fdogw?8^4OVl3d3Kt++&lqd@!2^qkj**U-DD3J3d6I9tc_k43B$kUds{3Uj+~ZjiEMJ&dm~r3 zFnn{a`-R~xSC4Es`ak6JFO^LVe3pNiZ1R%}j{M7o;hXb6APjH$ACwKpx-I`hvZ;a3 z&hK^QYyN(|A>1cnZ}3s`i1eEhd{&ch&s&}+=BVsr5`Hh>$lnkFe?Gtn@j_goJakwSMe*`;PUh z2YyfC?f&+OgFi3sQ|012*e?u!L3UMjxqoYf;a^n*c&%(Weh<0#)Mw5)`B}&3K8Cfh hjt*%C>%iA8fny!mFX&NV!|_&Zjp#crrEhl1{R1Ett}6fl literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracinggltf/closesthit.rchit.spv b/shaders/slang/raytracinggltf/closesthit.rchit.spv new file mode 100644 index 0000000000000000000000000000000000000000..9499a6ed811f850c73f9223dc207e85de4a0e75d GIT binary patch literal 4460 zcmai%*^g9J5Qi_*Gd(N{BFLhGBe-kC1r?(}7-G;U0%DN2Nz>CpC(ZPvy9b$sC`RL> ze*>b48z34WZVzZM@mYN^QE>qj_Z|1;`);4Y9%JGmm8$wxo!ZVhx0yoM{NAj4T$W`Q zWea4isaaQcWO|z)NPK_d_f2i%x=zd{WouWj8@To6I|iDqdZVxoQ2K1A~=jxltV^>Ogg9u(Gu}v=MvpWQ;~> zbfDEJmBlA#h3qKxS<@71I)vPXytz~zGWV4bP__ix3+;qXg9`kc1b1Ig)=l;-E7xoF z#((NP*(u=5TCGNP!$_+_S4DP-xi*vb>j0xF7?91yz%~pRt(AD+oP%EG7;KHk~z-DfJTm!=`OV0OQ2mil)`ndkt*PC69 zzM@j!Txm5%Z?6wlIGa3EkxbfLTj;4;w)1v=ac9Q?<#3U@#hg9Ow?-P3TRgk|QnRu= z%{6=q|MFQ?F4sny)w&1Pll5jdz}L1KBW0ruwubZL)v zin$JyZK}4`m1-jud&Kh z-kn#+*n6@===Cu@c4x1R*;CBtR<6~Xm1c{QSLU~O1+l%m-qT)4eFnS;^(Ec=t^GKT z+OI{{?j66G>f)ZvM|bJ72(C{zq)*(5@DcMYUH`^Bb1~mb_<81Hk<-0}gjv5iZ-kq3 zR<0NFGj^XbJa1Rz(%<)bE@X|N&qH>tAiDN;tnO?Vvazj6U(d|FJso=I-siyg&J>9dio=WKNEjQhmQ=`5_znEJ~X zK>El2tB_sRe+}IFJq!1H$Bt36xcw}Ii)r(2X=~S8$nTceTq^cn=<9v6=62oP+4acw zuYC^jyerDa_HL*fdof%;v8a0~vTHii?T3q7>n(!W_NCF!ZD`KlI4j}yA7`*C>CQ>} znxs3k*nb!DxMXj^t;0U_-;#9ujJmcVdq&#tO?G=%-=1`57XA+*8{aeD0e7!6v?upG z0zb@LcO?DMq(_b?(XGju&gNUZ8}1y8Y2UHbU1u@dJ#hV;`7XG+xt@W$#MGb7wYJ@Q zje8(rF`t*w|6=L?2C}tU`^ChTzXjcZ&HL_m!aJ|-{YK2|4E@Ru-81*C+ne@B;5#AX zt6Qt@-E}RM*WOMAL&VKk2NX$BaBL6YC>sRt=Q$GrsM{Zo}P}df5KSnn0_SF9;$j(4~ z8?k1=k3-_i@M*z6g`9zJNX+;086@sZjJ*i{IV8RuAN4O1X1vAB(s_TG@GiLL8t3p; zvia_!j<1o$&3P~U8^}7$DYhN{EhHXw_$I$gxOJ$1pD^QDhu^&)5*~HLJbnZ>=R;7` zaROO9;{Akd4)KWhGqQNZv%WRxzd_zv=PTyj{5|2;yowuJg#Q6qljLGc9?QF?zxLSw zC$e!pk2S>fJ^ux{*Eh3@EPfjeVqKEUn5*$N-#8Ta2%5u~V&+(h+=Xn8+n~r%05g_7 z2Iik1V&*lrd3(V0)n;sCiFqfBaPOpCy*KIdxTE8d-zH9+$pmyU&m`WSnEQQa#*?f2 z2Gza$)@VJaAp0F~Mct=@iMt-a&lyfe_jgBI_)STEx`y9rDEexPbDoCmIeVrt!|CYa z&d}bhf|Yz}P^|7>LA z8!Kv^gD&0~e=fRs#6JgF%)TRjAF?^L8O!@U581x0-@d(X^U=kPrG6f=SoH0_^U>|G zbKeE%;<4{SWU=VcSQnuiPg~S*F|z%1#<~PuJYrpnEEfG3>oRoXX*1TNV2?pNAO2e=nZM{o4N8jN|Y7Q;@cp@hs%06Ryv*$j?Fk9*P@(4}2dazMkp&?b@F( zXYX4)0L6FY`DE9}g-h-eHN1ds4gO!!_}1_uB)*#(`r$7n>}9yWHU53#^0!9YL}&u! zJCi$;@o;nd2KCS1Bs}^$h-_cxioRY!J_to$uOf?e_7(5&5V&?%oZoB6=F}E7h;`Or hE#~uVUx%zS&QRU@-hjUe?SwoV?doqqe=xyC(BCuu-K_us literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracinggltf/miss.rmiss.spv b/shaders/slang/raytracinggltf/miss.rmiss.spv new file mode 100644 index 0000000000000000000000000000000000000000..d35423b7e9894d2beddcb9437d2e26bc1e58ab00 GIT binary patch literal 496 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 YNZz-jz|l8t*J@neH~aS?tC)uTA9n#yQvd(} literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracinggltf/shadow.rmiss.spv b/shaders/slang/raytracinggltf/shadow.rmiss.spv new file mode 100644 index 0000000000000000000000000000000000000000..fdd345dece131afc638bb6151f0ced6329b58c66 GIT binary patch literal 468 zcmY+AOH0F05QV2rnrf?k(5gF$xDnlpAPC(RL?{-z4Hp}1pbu#((p7(*f5YG5M({f~ zS+sMRoI7XEJZ^&Ob=|^>ncY~AudHiT+jR?6reTqdN0a1v_?oQUHrcG*Tef_+mIYof zO&iU3->5WOxNNCJ6Aw5-X=)bYW+S(quiTW1$j4AN%Qh1?|4en?=RXSVI86`r`OHmM zUyxXhmWiS0Bh(wE1O5;1^(BP> literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingintersection/closesthit.rchit.spv b/shaders/slang/raytracingintersection/closesthit.rchit.spv new file mode 100644 index 0000000000000000000000000000000000000000..7cec8e574c014ac43c17fac21448fc152cf7df6e GIT binary patch literal 1996 zcmZ9N+fEZv6oxnSfIV@78DoacygoUdrrEsjY}{yCO`9pMZkTtiYUs@@yj7D)~v@kh_ zeY;6<8RB%9ocVg$D7rE4yy_l!pXjQnS9DG!wYe{v5~cLlrkl4J`G+s=@A#pwyefqW z0%WBD=al`u*bh%J-i2PJT36=Ij@ad(7RXF5Tht5rjKg|4u7`eQ(N--;y0pzDvhgCx z88aaKFbHdv^}zNbqk8TLE3JBQSUoBxt=p;vUR*dTlwJh2Rc|*4mF##y$&v&1oQfBF z-1xn%`|aWyMJ0Awi=jWL`iHOf4*W3k^}c~q*M1o6{*O~zt-8GvpX8Uay{vBrijp=3 z>DRqurB|`OkU2Zmc*CpJeR%q8dsGV|KZ>PVwUb)Xd*(y0TSUvUbbTL^%yAg`f#uF% z_yoHs!q+9;SyA4~DLV&j@WD(t&M)@t#h@r9a`H{_oF$>?uUI~9cZuA-3B;EDLjIn} z>>Tp1M7}GYT*!_1Zbql^Q+6IMKjy`8dftG!y643^%+>ut7`d?9)B)~fS4Wpnd<@#n zZ}{uhn~bo$h?AF0|FHu{f8OE^Y$TCeg>ic1i#g;)z0zIKjZ7br+Y>phdq5uPi?cyT zypF^MUB6y3JNN7PpG zJ-%k7XC{012AtUOJgt*cIyGJ^ApPNKR9#A3Jm$X8A`F zeVf%Mdyy59&w@DS$8M7kdw~u+YUvh{my`Jpkry)cT@#VlXL-fGUxW?##{}bd5kKe_ zgfZ8=h?vB4z6ZtUMW2#)>^*P6bIJ<;e5d$7@=}Bzf6VQnh<-3n{L%MO5%`)a>hgdgk0EzX%VxaHZXSKnTUGN<~Nhz dF2CoJ!61&y&-Hdz7&gS7(^QEA_E(nEqJP=&n)d(z literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingintersection/intersection.rint.spv b/shaders/slang/raytracingintersection/intersection.rint.spv new file mode 100644 index 0000000000000000000000000000000000000000..d06139f7ae82ff537e52fe3d3f16b52ef8692779 GIT binary patch literal 1656 zcmZ9L+iDY06oz*@X`*Rttxa1`t*P};5Q<)SX(BU|3$H4O zZ{Wj-H-dNi0N(f@o)G-Mo!K?G%incg>)&g3ywRnC$&DCemQ7dxIa6lT98L`+k)jzl z^_|C!t=gkTlJ;W19X9s*tyUNxnL)=-5^9Skf0P^huNrCW2T`}J4tcY#cy+tJy^^HO zmDQWq$)7MD!Z2r2)t|~n(~UXsBTMIj^kw0SP!whbPk-Z*)QqX`3Ca4){V)#2r@4BA z#(72XbAqs&hVefib+O-!`eN+zm>KjsJ*BC#V5TMOY1|LeejGOM+1tvcSk7`t?7T#_ zXW;1DSiy3S7?*@W8uhvlvwKuk2Y+}MgxV0lCD|P3gCD-qkPm+NP73tWn#A3hinTq< zmmGS)o#XnF&)yaVPjL1{>71&(#7|p2XLk+H&l*B5`^Wwwds;Vy-=b>hg+8Mk?o<&t z71_rniQy+seMP``Ewi~FXI7miBrC$4Vv~~C^vCAT*g0V#+ndWF#ymY&yDz@^yeiob z`hs-!flc0wBy;g$&t*3K9Ivy|N3!_2EI#0uGnca%`DN|mjwE%&*94BUH?8&hBXerf zzlj8UAkJR4ZQQ8GU|+ls=3>K>Zvt0r=JFeGacsVev+2(}WCrtgq%#9vx3n|zcpn`0 z`a>4`q&K-w1oGEpBaaF2+0ZLvx2FWhhuDUCvOC@kF?dqTUd{;k$zgxz1#;LcIdGa6 z@VlBz(z&0ruS(~B-^I2g$@wjvojn!ck9?yU%zP%$gW2!oV@5;3PcP@&&3yRZW_f$k z;REPLZ6NFl#9UreIz55Q3#H>H|GjE?4=n*d?*aa8NzO0bo!AQjA9p~Ov}0!O3+uuK zf%?O2SCRDLna^e8Bmb`Y^X>5cR6lk_UuL-2=6^AA+;=#TPW^|B`+e#79QV9*4%~^2 g3HX?S&J5mNN%&eG+F2o4=IppNi<)*LTb9fP~ zZ#MQ&)6?D6)xDck&T2}xB%Q0{8*8hgk9O&)G?eLKG|q2t?(hf`H*NTaZtyoV=uWHEM1uf<{v7M zPNQO}cjR~GT-P|ZcFmrctxkM1i(J>Wy8XBJBX{Vy5%Z-^Zxgd827lKcKK<0uZ5h~q zyzlqd=iQ+1D!irv2T;3mA9MK+XkBHFO5GF C6Cd#a literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingintersection/raygen.rgen.spv b/shaders/slang/raytracingintersection/raygen.rgen.spv new file mode 100644 index 0000000000000000000000000000000000000000..a49cf0da81e54a7646a568439cd750adc32e00a0 GIT binary patch literal 3960 zcmZ9O>sORj6vht>K`CkAy;w9rr6rLTnrS9V30?@2psNk9Fv8F{L&FO~Sz>gt8`%dx z_>II%F70CZ2k58z8(ORXqc5#`e(#)JXSH1qd+%rOv-dgsoS89I*;3=GDx7nh+#UTz z>RhEeU02pmdw+-5WG-{nuD@?EbEx}BrWDO);!-r6D~!73;ujR}I^2J_Z89EdYu~m- zu3O(MtUMQlg)Q#3vsq2 zrpnzfE>{>Bl#-uv4@!?DcCBlY&h$iaDL2y}7faD-Hgh~*jNR2)9!)`;;P(LaedLOwmg#5$4AC;@nDpn%3@Q8`AsBt zmAj7Z*HD8w=1%D7NxUYRyY6f>TgaB8I9Dw6lrN!6xy+w=|El}J=T7i{^M14JY5~4m zotvbQma@{CR5BaRN<8g(iyOy`;5r23SOYgF(3{y%AKv_C*$DoUG;zfIFwRUGlV~~4 z9LT3P`S_N9l|lXHIa$)AH|?rY1abeVmdw z=fPhkO+Eb0^0C(ml0B`O9r3jS9I%`Q*^&r0(&(7vh2SD z|B7sc8Sok7uBr8%^zVB6aLo6HG&AIk8{9qarZn@WHk^ss)cD1dtC zWW)3J=RL>wJp658uQ=Y`V*<0|O>&kd>CFQCOUh}MZuOj0!tv%F7vK@{xYITP9x?6- z*>LRNxGkRJzKq-IIc5z8y>O! zJtG?~?6K2x;o4oE3wt~(jvmG_tK9-TVm+Rd4Hx#<k(8pq(vbhiD#d+vwvFBxTFU*Z|bqK`xj@mEKliJiE*Ur%;o41A-*DV{4 zvswKEvdJZ8pS^Sb?hlG1UhY$Vt1rsut@3?nZ?#u8Jbjv_`vf=yt|ifB-Z@TzRMFz+?bg*{&PT-f6car6lD-jolI zSdXK!;ldtoc`jU=@m$zrNE|(kV^)zcBp}w~nCu}T>@n=Qu*Zn!sAu<{mCgK_5BsOS z#g5D79+(s7ppV5yWpf|Qi}TRWVq>zo7v{#f=u3>ZniJ?rZEBEf?`&K)zn|pvy1TVP z|Hl^K0m2zMlfAijWQT9ABp(j3_b@3N9 zn-|~_>+z9nxUk2^o(p??;yLQs`}kBg^JhNnpZXR%E1P>@PMm{27W+&#_rbj81o~O* zbJ^SrbK_j}CB~ckLZBzLsX?y2uP~u6LvEk{9{XB0vAkgK z_nd5a`dR&Nk~leKVP4ed{Vqy>D=Y~|>uMAGlI+XEl>mGO&I{DKAY2nze^vUr_fN^c wA^UrwUcj%D{=swH8|V2^U=3nt`AIfBXQA#*>7RvL!mxa7>X7%BCbUEN2il`4kpKVy literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingpositionfetch/closesthit.rchit.spv b/shaders/slang/raytracingpositionfetch/closesthit.rchit.spv new file mode 100644 index 0000000000000000000000000000000000000000..273d9ef931afd3e3935557342326e469fff9ebaa GIT binary patch literal 2256 zcmb7_O>bLO5Qb0VxPdgZl+q8NgrtE|C?QV402w&a7<)FIIA)lKXsu8bXBUx#Kz z5ql&geiF;FVgV8ozk>}D&vSi`S`Z63(fG`~^Uj<(bH+|(WM(Xk9tt5`2%q!mIvz&C z*T;wZug?#68ROw_*lgTQ)>l7Evh*Oyvvj-N-2or}H$2(v_1k&7*G=xV^6lLaju8JQ zc~)+3-k$B}&Dq-JcRlZDsJI2sI7Y4?IdcU4%e37UpF_?dA0W%fI8x#72)i-W;xB}y zJkQ!&gS^!boFqD2TWNNnRt;m}Ird~P&yuz7-XKr*FWu|((p=wYIDs#1Hnac2J^Men zul$W$4d=192U*tY=8Yb;R>MTN43^YWF7RM8?`7#uD=8|gJ*Xu&d!2fEzn9Unxf&hw zZt`8tG*8{VZH@hl8+Ve&yu$^if4|-OYOTB9%K9zhhq%4l%X;_!iQD^5duMl8ow+MT z?+05w^wDq&eG$A$Z6uo*tLzH#ODl(P2qc*{WtC;b`e|NQ6z+i*Nx>XS6~%( z`Od26iJ!ziS>Qv=c{?r}Og^;&~fb&X?a8 zF_)NiP9Wm0Z%gbMbZ1UqV*Gh-e0>Lo-xa{OJC;~YiK zB)WLy_ z@0FO`nC}vL%%|U;&9i@mI4{n>`8;C*5x>LBTg$Z)6L%d#oS}HP>*#XqMLcg2J)Wok z2hMYLmJn-MMC^mu4MeW@*Y9`D`c~Q3kY&X0ls%XK39^nDC$G-_DI!F2o4=IppNi<)*LTb9fP~ zZ#MQ&)6?D6)xDck&T2}xB%Q0{8*8hgk9O&)G?eLKG|q2t?(hf`H*NTaZtyoV=uWHEM1uf<{v7M zPNQO}cjR~GT-P|ZcFmrctxkM1i(J>Wy8XBJBX{Vy5%Z-^Zxgd827lKcKK<0uZ5h~q zyzlqd=iQ+1D!irv2T;3mA9MK+XkBHFO5GF C6Cd#a literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingpositionfetch/raygen.rgen.spv b/shaders/slang/raytracingpositionfetch/raygen.rgen.spv new file mode 100644 index 0000000000000000000000000000000000000000..a49cf0da81e54a7646a568439cd750adc32e00a0 GIT binary patch literal 3960 zcmZ9O>sORj6vht>K`CkAy;w9rr6rLTnrS9V30?@2psNk9Fv8F{L&FO~Sz>gt8`%dx z_>II%F70CZ2k58z8(ORXqc5#`e(#)JXSH1qd+%rOv-dgsoS89I*;3=GDx7nh+#UTz z>RhEeU02pmdw+-5WG-{nuD@?EbEx}BrWDO);!-r6D~!73;ujR}I^2J_Z89EdYu~m- zu3O(MtUMQlg)Q#3vsq2 zrpnzfE>{>Bl#-uv4@!?DcCBlY&h$iaDL2y}7faD-Hgh~*jNR2)9!)`;;P(LaedLOwmg#5$4AC;@nDpn%3@Q8`AsBt zmAj7Z*HD8w=1%D7NxUYRyY6f>TgaB8I9Dw6lrN!6xy+w=|El}J=T7i{^M14JY5~4m zotvbQma@{CR5BaRN<8g(iyOy`;5r23SOYgF(3{y%AKv_C*$DoUG;zfIFwRUGlV~~4 z9LT3P`S_N9l|lXHIa$)AH|?rY1abeVmdw z=fPhkO+Eb0^0C(ml0B`O9r3jS9I%`Q*^&r0(&(7vh2SD z|B7sc8Sok7uBr8%^zVB6aLo6HG&AIk8{9qarZn@WHk^ss)cD1dtC zWW)3J=RL>wJp658uQ=Y`V*<0|O>&kd>CFQCOUh}MZuOj0!tv%F7vK@{xYITP9x?6- z*>LRNxGkRJzKq-IIc5z8y>O! zJtG?~?6K2x;o4oE3wt~(jvmG_tK9-TVm+Rd4Hx#<k(8pq(vbhiD#d+vwvFBxTFU*Z|bqK`xj@mEKliJiE*Ur%;o41A-*DV{4 zvswKEvdJZ8pS^Sb?hlG1UhY$Vt1rsut@3?nZ?#u8Jbjv_`vf=yt|ifB-Z@TzRMFz+?bg*{&PT-f6car6lD-jolI zSdXK!;ldtoc`jU=@m$zrNE|(kV^)zcBp}w~nCu}T>@n=Qu*Zn!sAu<{mCgK_5BsOS z#g5D79+(s7ppV5yWpf|Qi}TRWVq>zo7v{#f=u3>ZniJ?rZEBEf?`&K)zn|pvy1TVP z|Hl^K0m2zMlfAijWQT9ABp(j3_b@3N9 zn-|~_>+z9nxUk2^o(p??;yLQs`}kBg^JhNnpZXR%E1P>@PMm{27W+&#_rbj81o~O* zbJ^SrbK_j}CB~ckLZBzLsX?y2uP~u6LvEk{9{XB0vAkgK z_nd5a`dR&Nk~leKVP4ed{Vqy>D=Y~|>uMAGlI+XEl>mGO&I{DKAY2nze^vUr_fN^c wA^UrwUcj%D{=swH8|V2^U=3nt`AIfBXQA#*>7RvL!mxa7>X7%BCbUEN2il`4kpKVy literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingreflections/closesthit.rchit.spv b/shaders/slang/raytracingreflections/closesthit.rchit.spv new file mode 100644 index 0000000000000000000000000000000000000000..af12d5569a7209751d67601357158ce55f8e4899 GIT binary patch literal 4360 zcmZvfS&UWn9moH}okd|}se)P+2h>WzQf<*RX_RF&NCX|7q;F<&n7QC3!(4Li846bG z;J%=7--%IUqKOZh7+-vHt$U(vs>TGj*1mOl>Y}#&e9k$)@k;!YFTZ{L{}0SG=A1N; zdV5kzE7Af9XHlAyu3A)4Rddt4G&=IDu?x<>WUN!P^K5%_Z0q#4ZOwdE9G}cO9b@OF z{#oBV+dEd|*?4PeI~n@Z4EBwiM>ntT6cel0oO!zb^HW2Ttg|2urdN(iR8MJV)|yg( z02~i~1ct%IU_UqpH25Nzl9BMTbU54D%(Icay{nlQt!9VKl|lVPY4_}IHGjQnYIig5G|^UiXWNyx zcO0sBN0Y7XmlY%Ja_`~qHpx&l_l&kKZ(6@m?rnN&8-5^Ni2eI#?<;p}Y&krB?(}Bp zCE4DQY%fz!R5PmcjJGG-In>&rn`m{4Y-*g!-}Rkp=R32>@A~G=ZIjJ$wu)~bIh<*H zvfXKRipyHXmhuH`Ougm(d(Q(v`DAE6=q=?&d7s9fPZsai6I6fS&N5K>SMqY5I2+lI zcHfh}>!9Xd2+SAv`E9;Nd0$a4?k?=csPo>`tplMmM%_%8u2Ji5hgyFaYOnf+yd2)6 zd=WJIvv==PUu(#Ftl`n$@5Ox93HjT6jnW>o`>na>clnTxB&#zlBhpy;qtNw1hsbLW z-iPuMJPs@MmF@7_rtWBb7enRkb1A-lr|QgeH1uN>m994(Tk83%q`m1lsI}Fv!e6=+ z*wbR<6QM&uAMGI{mid=K2Z3=X5arvca#Zg|**;Ez>gVpF&Pw>mYs^o9GdR3Vd{2?{TzG5R^LbG1`iFfJ zyl+?gW~ein)7gDH^49mQDC;)@)lXgIxfH&qmYs74NNHwm*!Lk>+xV+%-rU;tzX?3} zz_DwW@>2Y_A@&v2xLeR4fNhfPsU}?<-i$+zzHB?PleZZ1-X11 zD}cJ0I@gck^~j z*%^Nh>~%eT`nF#L-idGC9M19*P=5nH$}iWtP0+~mO0AFGy^5^P{PwsR`Wo)u>0)M8 z_dc+OCv?AuSJwkZn9XnJ55Rc+wTJH?;jQBd-3RdMj1S$1wa)iE!Yg$z9|7a_*S-V9 zzNg@Q7jbU~;SasHPtd84d;1h#UH83xhO9pB?Q?i_=8t>(0zUSqJ@)q}cx|!!Kf`NZ z2_p7O_=wdWv44TDY}KCsifq2_-Tw_)KTquG@9^rncmEG$BdygG`1%K#{ zzDB1$cJvLry6zqQ7g>Gm=zs9)%pY^wP|T@4=IpUi5IdR!uf2OmjjmYj5$mrAm95&* zJY@5A?`ROY{8fUSv7;ku9c1=>&POm_f9?7%#-4*Ez!UKuc=euZ>hGX{_x))LziD{= zNH^=Z8(v>+w-M{Nu?P5lXbaut@ZOvG_SJsBf!9}C_+1Ha@8%1?-@@ywZLt3Su7aNd z=K<~B`PI;CfOozR#9pth^%wDl+uwCSo$xr%91yv$ho1rF*7xpuCpW-rv-Tk0tp8rz z2xh_z zib>8&QtK}trI!ab>}dbv)k9xz&iG{5bCif^$Wm!U|nhCi=On? zreE~*47@$L|LEyic=g>qsk5iZA&s7%gO8q$g!kB!`X7Krz`9ayJbs;la++kdJ%*1eRnc$b;|v~9gP!`5y8hC7-_+LBhx|1F*VDU^J# zT?%}!Tx(oepYT4#PtJ;G*;Y`=?(XeSKVUJGQ9EcUdl@rzG`sd{4e(ycs3fL`dh!yo z2c?71PKbk9!E5KecD?CUOp`j8U@JH4O_)o;iq&aR2$^Bq34fnSnOEZsnF literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingreflections/raygen.rgen.spv b/shaders/slang/raytracingreflections/raygen.rgen.spv new file mode 100644 index 0000000000000000000000000000000000000000..7712636de3fbffdaf01d7f88d36cc863759d447a GIT binary patch literal 5264 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 Pe0S=I`tX11^ji1_HoPw3 literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingsbtdata/miss.rmiss.spv b/shaders/slang/raytracingsbtdata/miss.rmiss.spv new file mode 100644 index 0000000000000000000000000000000000000000..4c386b791c872c1ed86ad7606fb0d8b34b5d5ca5 GIT binary patch literal 728 zcmYk3QA+|r6os$3YFTM!Y7mIwOVCR}L=Xk_k`RGp_`0kawqOSC_TW>$uD?-#qnDub zjXU5hXJ+oXXU@Gdn_ugeEXbMJksWAe)NIW@Ys-~P*@`yk55xQ3V>pi%VLFeVoRG0 z4u7~{h2sp|x=@z`nnQQf#yc^>%O##bw7YeU7u3 z_hX>n(u$t*?W}LSJg@`6z+FjA?YaQ(H4W|2(2LhJwTJg{D~tPb;LiI3KIq6@t0U^e J|Ebdp;U5d%EL#8o literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingsbtdata/raygen.rgen.spv b/shaders/slang/raytracingsbtdata/raygen.rgen.spv new file mode 100644 index 0000000000000000000000000000000000000000..c215bd7bcd5996adf7ea5cd04c346a47757dcadf GIT binary patch literal 5220 zcmYk8YmA*$6^1`Lw+e-}P;OGn4CN-2A~4)99Xdb@v~*xfl@gqOogRi$XXcD&PD={} z3Pt38RX_nHgdYS55)w5r;YYoJiGqUqLog=DE&RYJinf6GJm2h9_HN!;YrSjjwf0_n z@2{tA+WfAfeV3vrjwq%p7_*CM#r3nN-VebiF#w_+I+7yLzXBIPxZF34L6vbFsAD4dv90U#oCxW-Z z%itr>#=qT=&h04Lsa+HU<>t{wxsGa`l?_!~S#PZ>M>o{eJNS19a-zPeHrihsZ`GRB z+%Lh^$1hnm71LHML|F$qSd$AKT3)uA^-Y7VMzb8L4P8NzR_~_Xq5j6`@^XEn$(D}o zC9snj)yAA(wn_xd^x_y~e>qlbmIKYkM6KDX*CvP3B-g6nv9Vse>b&udwdQ24+Jn6N zn`k!H2j9WI?Zt38M(&Q{H|T?lS4KMKwO1T;(F9?eXC$-j^IBj&dpfzcRq6J8qT)NM zewV|;wb8*=bHlLy_Nw>wG1^eYbXDiYS&!7l*R@w7s9!b%gzS-KpN`H@AN8arpOQMe;qYuPw#wgJyra!M?u9+dQY4q=f1rsa`W(c zC$xq8IRWWfah4oqIKq3%J+F zbsf6(%=I`j&M#1QsiCy%~J=Z=xjcPBPul+32bJaeQKBzwr7SK)ez5rqk zN^^Ra+rTU^FWqB%A8=j2#r`XA(mSsGO0td7ejWK|{NA^}%$ZianfSMm4(+J*4*D*c z{Vw`vnf)HRWB=j{#fM0181J59gl_GBC(_u{u)VK-SDX{J-<7aEf8W13^t(5|Z|+aq zz4&h3kG6a8-8!_b=eu;o{q7|B(bz(+8`%Z74Jl59!`!(C-`0Pzyi?}9OdkQBk@n-r zPe9oEKhA9ZJ2G4U_RRK;&rJ3iSdoXf7(0@aE z&xa(=cOCN&M>l7D@ACOa!0W#y&G-LPbI9M7xFgZ!{Vr@x+(LAD`+F9gZ}Sx3`T1tu zi|_PQAb$}tzWdV>hp0H;;ORi#VVw8s3?T0a?o4z!*B{)X#Cd0e>r0$xDQAtdfHm^D zixZF7Ik!J?dED8F%WIsIxV*->aMsA}Vtq@|5m89`?)qSTB5o z=zYMxxi9PLTZz1+(p`H|n8VoE$0~I1nj^Tcpv$?p$p2MzWA(**zbBpjrEvPK6LhrE{0@gIQIgE{awi*3uV9W}BX?7v61@gk-9^KQKbY(kIf84(<==uG-0b9-y zcjHEMc}MhbE4sWRxSP=BtQXuj6KDP4ZcbdBk$3!Cz#947TN01hIrrAY<#D$qF0XNW z;_@1Iz*!@YyAxa95$n4PT`sS2cjEH7_arW_aW9-Tg7f~}2jm@5<9>9xyvDZ^m)H1C z;>;I!xJ*T=$?yxb6?ig=l%O0u%@}q zVQk#BhtV%hKves2{WH>U%tz241?K=`2hum~`{??v0dbdqfG%&n$p09+yl~hr^Lv*+ zMn0DG9mpq={t5C)@C>z{Mg9=<0Dpr$%x{F<(Vt8Ff5@{Zx?=}E`PpC=@Hd&#S~HQ) zgY9s}>oe{~YIGxi1P%w*crMlbF}8K}MctpE%STS_Jg2#Ro38Pvz`Cw+KcvGo%Fh9N z0oS24pT8MjKsTT9`i#3dt?_5*uE#ZAOP;6Ee-7lmm&YT2kvPOo?w5&U8h2+Z?pNsY z*MTjGdlB9F`XcTnba~^RBF=sN8py8(?rmSB!@cR-2kZ@8ztaCdUqSv3ybPRYk9=Fd z2l5f~D!MTzfrxnxT|Q#|fNqRyikLs5%MYY``zLgBJ6B)ySKj`*X4mIhBZrsMyQkfS z{0w+U!~Z|@9m&@JDe!w7@omia3~e-ll%j c{1aQw_ixOH$bW&4z%aJDIgI<1#h(oR4_p7ypa1{> literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingshadows/closesthit.rchit.spv b/shaders/slang/raytracingshadows/closesthit.rchit.spv new file mode 100644 index 0000000000000000000000000000000000000000..d3e84f32876d286856541aa246e03c544d2f2af8 GIT binary patch literal 4216 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingshadows/shadow.rmiss.spv b/shaders/slang/raytracingshadows/shadow.rmiss.spv new file mode 100644 index 0000000000000000000000000000000000000000..1f99cf016604dc32c2895507a42367525e242d28 GIT binary patch literal 424 zcmYk1K}*9>5QN7jO|@!EwdzeGUPSLw5Cm_9A{2#Q!^0FCs4X-V>B(Q`-|%;M5&S02 z!S|T#o88&jP1Lw-Dc+HEr6ayRJvH>%+eTN~O7uLQWTW9zwhEhUy$UbI;#D0*mEM{z zny)n5iyJHvJ)n5L8*KcvOhj;h!9zU>{_(07*9bmov?@^fB>zB>}_yf*%AgTZW literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingtextures/anyhit.rahit.spv b/shaders/slang/raytracingtextures/anyhit.rahit.spv new file mode 100644 index 0000000000000000000000000000000000000000..021186f134aa0b91097570636c728ee1b83e0c24 GIT binary patch literal 2888 zcmai!*>BWU6vuBnZK0@WEntiWi@ca9NfV8jHf6C7k~9Vctf&vuX**NKl$puQl+eUP zj7Ag)@@66~xG%Wi8ux{|CGNX{NA+KDOHBNHesiy_Pu}MAobx^Bp6#CBdh*n!N1Ner)E^$CIx$>vHd12mil&`grE=Ee_kzTdB4dnOCtgQEa4aU1Zbl z*-Z~+Y|7Rk?kvic$qcr8=hYhfd@LZmyRtbp3cG64#rkk{x*F^52nVpY@JakSvo|PI zW_OmGS7$GA6*KcKoV_zwKO5c!@no4k8g>0P5hKlKHM++;JK)~wfb>bTnD@zLJ-Gwg zQ{Ty+FnbnT3>nw`SOw)4=ocb;dg(_0RoV8m=CuOZyM53(-0y~~n|CEPdlc)#X3wW+ zQfxW;85z#MjCZiNt(fA*avsLAmX+wea53X~e>uDlvZjlpz5-eQ^Ufi z*I#}Kq<_-aAbXb4f%_?L4QmC%-t{TZ0GfG?I|xsGCi@VWNBcUscI#2!5Or%y{v*iF z%)YOMo71<|-+lO%#>JiKcDR@}_duJyXmbz5oR@E|ub95q!=0VD`i)Uf_OYmY-@1%h zf~-sbDY*BIseV(`ttI)_klUht58S>fFPzKGJK*-E-I(d9d(NZ&eQ^DZf0rOf%=q3t zD8NbjVdPS&w0;n~`{i$&JErbF`3)Ig-TwWi?Lpo6?z`u5zLAA>xf6d-rEj3GZ+H^2 zA9Z)>o~RF@i!Xu9ukP%YLgv4n*y{I2%$-|Duijq+{Yjo9aP!H3^B9qQUP633l+1agi8 zP|EcvvbpxgULQlYU-6rX@3;CmByOBB_!E$^{8o(P-aQG4596c$RK&bH#4nz6d^+Oo zaNj4*_gJ)*;O3ZuKLc5-IZ_?ZBI~Pem>&Xp?*AK-n9PWr6 z2yXlulybg=EN-91dl@osivLQ)^h@zyMHWx-t#(EKa*^2p{y#a~a!)Cq|zqvOd zYm_``zui6kwR?XM{ubo@0cbPZ>^Jf@WDSxv>T~dGsMWeYfc(}xV*W0C2#I@ci`YlVYawmP?_*^BoJI2c z1X*8gX~v%-J7edWX7m}dxHGahYxx`!KNM^GB4Wl&vA#q$miJPuuaLzT#`+pvJjMD3 zS>f_wbk(bfrx`R>YNJ#CpR_BSte1@sRX CkT`(= literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingtextures/closesthit.rchit.spv b/shaders/slang/raytracingtextures/closesthit.rchit.spv new file mode 100644 index 0000000000000000000000000000000000000000..fcd3ddbb98f2bfa3d27112072da00fe0f9bdadd0 GIT binary patch literal 2956 zcmai!*=yWY6vuCpNz&9cwko2Q)V_#;B4{P0Hd6Coi%8Q{V|{U$WPWW1rZZt?5)24d zY_%<#>Vsfi<8EE+0`6M13huj91YgvD!3_jIpP74`@yR=!oO8Zsz2}}^x;j_&hFnJo z;r#F;e?9%7GyJl=#c%3waXprXzOZ$4Jb&fJvHbMZT)i||DCg^qYOSy%%TLT~-=5X* z={fFGE6n8^wZdenvLl=vy27vIG|wq`9YyX$-dQMBVAw<02JMCBp`}n4zZ2lbbT@w? zY-luUrHPqFRu5DXZJmiiZBD5>faZ}u#HqJ^~UAR zJB(IKl}1+MX2pvyx)7Un^zr1U8#TFc*TDZTP9M)=+>)>by;W)~V`f=pGOMR*Jyg@~ zndJ^8Y|8c^?kq}`ViWETz0H}mM!%R#|863jWxcR-x}4QUs^x0zI~VpH$BX#o!tLmz zg}HLIP$a6SsRMA$kM zX|36wfovZG(3!-0Cw1$tz~;V*4Pfho|HLK5PDghJ1CU4iN$?Ix++3%@&1Eku(EH(H z<}-d7d;l_LFzU`w|8vltpD|+QKNoJS`Sq7y0O_CfL1fQzZm=3IZVzh&!>-Fxogp;q zns+VSyi&5SL-uID6t2yF)Q6*PZ^?fXvNQAETjAF9ZS{8_e&Z72&eVMn)8-y%^Df%l z12O02o9ip4@3nB>KwSO0s3-gNQ8(Vc%vpr&OMe&Jcyp>xMcrPKe+9WC+GpY3+c!Il z$lY-7rQMwAsC&+)|2=U1%zv98N6h@j?ib*ASHDAZ>w5?MXXYTLejw`F*P+|D|0CT$ zb$8A0(Aw(G#{Z}KsaxA`!J}^edB_@`rgMN@2>9N-5vGy={yXvS!H+;5?f1g9%hm6Tx?KJKsLNCR z2av6CnEI>X4?<$r|AYDqaL?b=)3yLT1X)LJUi(mAfNvm=`}Hv7T!)}k>k(vY?TUAO z6xsWV-$;JH>&GB*^SGCfL+0|kGLJj@1SCF!kNT4lGj=`O;vAofxNqhAr1>6-wj$gb z8T@I;UagV(cm`QtecbnFA^lPx?*4NTw-5E_BWA39_}#t`@zh7U`(beNSD;k$MPzaB zX}*^r>!$oKM@+wz{}p8Ml;3`b(O-p*LC#jpZ}K%r+&gS$6a7YBhwM@EbU@~E_w?6p z{95=Mknuy%X13fte-p9?$vD3WWA)YMe!K;DKji9fM_rzF;~nJo-FO#W%=x76K+O0f zaP!I44@TWR+(NJR^*-dc<`L_Ge*lSlZi(1YkDM@_FP}0i>F*)A&c4n%`yMi$kx!7 z@_&PD{!J0{J->y-+w*@H@s$62bTRLp^8bKr4Q<|W5ByeWFSLytyZ8GdrmuUkAF`JN a@H?S-sC^IbLN`Y8wC|z*+W!F^g8l_ZI6#E} literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingtextures/miss.rmiss.spv b/shaders/slang/raytracingtextures/miss.rmiss.spv new file mode 100644 index 0000000000000000000000000000000000000000..8d1e7b12271f2e3b529b66aee07e6e77c26413be GIT binary patch literal 432 zcmXw#%}N775QNL@W)q_(hWK-nh!-I_iy#EN2^t6rxh{i>F2o4=IppNi<)*LTb9fP~ zZ#MQ&)6?D6)xDck&T2}xB%Q0{8*8hgk9O&)G?eLKG|q2t?(hf`H*NTaZtyoV=uWHEM1uf<{v7M zPNQO}cjR~GT-P|ZcFmrctxkM1i(J>Wy8XBJBX{Vy5%Z-^Zxgd827lKcKK<0uZ5h~q zyzlqd=iQ+1D!irv2T;3mA9MK+XkBHFO5GF C6Cd#a literal 0 HcmV?d00001 diff --git a/shaders/slang/raytracingtextures/raygen.rgen.spv b/shaders/slang/raytracingtextures/raygen.rgen.spv new file mode 100644 index 0000000000000000000000000000000000000000..9073f791709b79c61de161c20946b33b0a8eb514 GIT binary patch literal 3912 zcmYk8Ygd(35XUzhE~TX5-E!GMx>%BFp_yi&l%PnE1YPa;ba=$0hjZxRQL!vBy4cO^ zg)e+(qU6#pmLH&cRiB}?`X0S$)&KXLJ++55%*=mg&+M5!=RmH$z1cO?Ip@~9U-TPl zb@lE{YfV1s?QLEXxxh8K;i1t&f8T*Z5}hifNmMLV#@#~U=jHF+KfHhAR64e?bIT@~ zZjs9&9A_6R>eppX6`Y%hN)_plN`(R7S|?O7>LrOG(DVFlW06H94=R*v~#+%&{HiBL`SQMuDQ8W zw`|gB;-Rr9jgXD*PM4P)**(}3O~gqwlvF3!de{ z!TVIXO%iIa37yGhGvH0}=RIzI!$PF)O6eS6;kQ@y(Lh_?OFGAek3K_?Zb9{=DqFB*_VmUmuywPe0g8 zCCP`qK{onIv8by!sIaSc7|55{Om1cJMy!1<^*rm-h}td3HwXgd4rw$%`Ucxxs%z8rE{l2O@bX= zA|?ig$Tz98?4z!c`Oo_O~ed!t<+T<3H!m^ZiT?@bezKS2{R*KI<{Q zx54RkmoRqi5izr42kE6va)TKB1;wnB?C_XGhOuLhioqe`c+-tyaLBO7q=RvP!!~)0 z_cCm=$Cx!3H69mJBRuzo(>wg*CQ& zEIhlzV_}V_g;B#WX0=lc4q1(7q=SVux;z%v==K=-hWuxKmvrXOe7HaP&9_@R@4%es zgF5ExkK5bUJ86%Yn&c)2vDQbgbao9gtWP=^y;=Uf(uu`q zpS=tI?e_`8U#nBw)#qiitNmiz)j{dt)LADvBnE@P+A~?h4P*WXJRV}h9t-FHqQ~kp zS=;jwk1>C%F)E$f;n|mDgF`llm!*S+aj$qRtnsSH!Wyp$qed9_x@>UBY8;df7S?#f zW8v9?$HE$igi*sVW)+DKi6N`;ru0MNutw2iVU015kemd^Z{5BDd(`3_6x9heh+ zP{(}Z(s>W&ML*Ot-x2A&3v;6{>f&QpOJZu0n;gX2o*k8bOiaw6yF(}RKeHGdhUk%= zZ0FvR9`0Ns8w|32n34_-+00Vu;E-X*rGtfYJmIl$jwe0F9IeK*bZUfWPss*{tj62Y z!NRzAJQmhC?Xj@NyTYgu#=R#S9I_f`q=SVuW;_<2J?pWs#{0skVHi6%D+Y(G#s|{D z!WtiXEUfX7$H-^<@v(H~&wRK)`OSAuI`6=o=z}`u`$RhL!MtX~)HC0w(s>u=Mqkv$ z$Ig8wrY5<`L9Ff9=hF9imdN_y{w?||%Km*JJ})K@u|xiQ>`UqR%3|B!3(~=@pUoh=Ou4=`?Tzv(!Uii5o5PX oe&;dXjefota|W_revl4MFXX)?`J?!@xF{Q)JjDI232hVq3tkl}H~;_u literal 0 HcmV?d00001 diff --git a/shaders/slang/renderheadless/triangle.frag.spv b/shaders/slang/renderheadless/triangle.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..81761f272281554e48e0a89c3020f6ed5432774d GIT binary patch literal 436 zcmZ9IO-sW-6h)tjX=~ML5$aAVZUn)l6pFfV;Y!FqkStmWm_$NcxbtVb5j-cho6hj& zy?fus+?h1F8pi%!L|n&|(>0AGWG0dJ*!UzU!zWl(l(mToc7UByCqKke_95P$jBUQG zKR&zLr{=wBVa9#ms_xpayeaE0FWRDdUAM(s1^Kd>oyDM^xywJJ!kHJCORSD9KHF%& z?3MiMm=R~x%&~Lo2Y9isn}bJq^~#$c<^-`9`FDF literal 0 HcmV?d00001 diff --git a/shaders/slang/renderheadless/triangle.vert.spv b/shaders/slang/renderheadless/triangle.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..1459c82a5bfc35ca896497b2dd854ebedbfde42e GIT binary patch literal 1576 zcmZ9MT~8BH5QY!^L`BdT6cur6QBkyhP!UBS21x5gLybS6*@S9pXqRkPQt$i;{#iiLXBm1dlCYwnYtoa?UOK;~UB_puk;<=iglIgAG*oJevY zX-lq379>Ueu1NDvSwHZ>==4X{=q6*s$eUvO$w`tbYtAhT>viHR9ZbGtNg99a_r9Ja zan_tPd&=s>-;;El9XB^#I#A1U5NG0`f1jmbku!gdhtBBtZ6xS9&@fGF8W@PaPa9FpSj@Q zldedvN!md_b@`l@=14!(CXUTHkC*b)i`+_gZ=dO_iY~B1t*&KXo-O0UQdp^#6sK2ZyJ;MpMqPws|Fl_q6hxfkp zB?%aQ&3xiZ@^_@ELtWzg(%cygzhyr6-j+`v>|-YI*@ySxizIN8Pd&bCYT{Fm+2U_% z7re(_IADL|ahDxE;bbT9d4FCud`F5BUy_jHcjxPMRhu4eTMo1QD6A&^KoUuqH+7js zT>}1DIm~g@FsU4))`LIIHZ{ooZF}33&9_F*uDU*u2E%Sk^WFYcms^s5&vt4e literal 0 HcmV?d00001 diff --git a/shaders/slang/screenshot/mesh.frag.spv b/shaders/slang/screenshot/mesh.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..37a0b45e1e3bf7075bff8a6537bec2a55c886aef GIT binary patch literal 1160 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/shadowmapping/offscreen.frag.spv b/shaders/slang/shadowmapping/offscreen.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..bd595cd466530f96cb8c7791af22d50ea73a4c62 GIT binary patch literal 356 zcmZ8dy9&ZU5FGQ=2vHHVlZcI=wFrWisf7H2T%nR85keX}Kifud=5jV}nA_dix!ukA z-YQ1W1F%NQQ#OGIF)4hTD;^<2K<^QiDQgw_#F!d!G2!zY(n}vAvGr@+HqYWw)@@-L zQ(bP2xmP65u1Cney8qAToTmN@LN;|fE$x(U#*A^uT1L#NkLZ uuhTErzOpUVx<4SK5ick{xL(>vFS27N{iF7liF-5C+#@sT)aOIhp7;V91sL@J literal 0 HcmV?d00001 diff --git a/shaders/slang/shadowmapping/offscreen.vert.spv b/shaders/slang/shadowmapping/offscreen.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..a9c7c1db7e937f368bdedf230a8d43bcf4618613 GIT binary patch literal 1368 zcmYk4NpBND5JnqsVF?K#WC233W0pWz5-=zd0t6hw#li@|)f!|2L4iTefPCa9@N>B! z@!rr)rbabg^;LC!)zw|Eb!S53SO{S=?DAI@LM@2Qg?j00&xhlsUE}{H+yAPwfIdJ^ zpmn}etmZbc#RmBy_H2m{`&lvBpS~&bN%nC({BV$GMQ_?0zQ_;y+2?$6Sd4ah+aa{r zVI5_Z6`5<3?x=z@cEn_uV z+vo~C*^j>QHont0Pu%!vR^ttHiT@mH8#QMu`t#Vv*Z6xz_lT`i)n3H3J&(RT&cJhu zr8;M^72}Jn#?4>FzsqV}dCa$`duRwhpPJvp@(kuY!uK4$4g1uW&skYh-+X7~o`+O3 z&zK_i8&9ss{GG)NYQ1OV+S@tQdiHFNeJ-KmugUSu%MoKKF?(A<#TD~B$0{nWBkCBUWz!&|GmCVbE|omBUa^TN36=x0h6Pew}CINr2e|t zVpWbS5v%UK8nG(JH8436=B%!x;!5J!#1^Y^+=y6}<7ULHH{eE{)fVdfosa!nKgDig zdk@aZbI6lox3Rqs=jD0iOR+oH-b)+xT=E+84R51zTH6}t4&uG-VEfK|*S{imA6wjg PPnd*nR_qU_-9`TbpV~t! literal 0 HcmV?d00001 diff --git a/shaders/slang/shadowmapping/quad.frag.spv b/shaders/slang/shadowmapping/quad.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..893e62cdd3e7f529776faa80d8eca8695ae47494 GIT binary patch literal 1588 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/shadowmappingcascade/debugshadowmap.vert.spv b/shaders/slang/shadowmappingcascade/debugshadowmap.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..ef2e0e8e768ca4ffa3d9dab796da2d49479328dd GIT binary patch literal 832 zcmYk4NlODk5QWPu#x*fUjXR@34H`u+;)2UfL4>*JRpu~<91>+1M8SjT-Crg6m%IqR zucrs?@OtXKuCA(ilVYJ&vC@E{B*4fJ2$s3udJ?Sf4bR)m0Ue)U1}aU zJ>Z)HoZfI2oH>>qGi#_KGpx9YvUz3{4@wJ!rt&L#!b_eHdCn};QmGvX)Ct7LeT>fe zq|>!&ZTb8u#pJ^|pA)DDr&mkRI?wrnO&3=A{3w=gfI5&OCTdzntSy z&bg0A)Zm=^cm(h0>rm%VUAy%3EV^f@Y<@^TYA2G hZCx=s?;olg9&ZTfd;|PAl>_*PPKBg`jv5iHJu}eGtL(grZ3=ldAvbpSgs@_l;@TlRay% zwJ&GSnQUgO7;-Zqgza#|TdRglP$`FO!i_6|GBAS=qTbNN5_U*8a-6q3HXQGYbT97C7C`fA)=W*V ztut>Cw9fvDBBtj2Drmp=S!2Q~xC>Kj;Mn;o+;gXQDR++FrtNTseTVolxAlJ)|Jplq zoqxvLy-T>WhAhRrT}W6%r=+D)!f0@ lntf2S#+~dpGD29+A%q2z|- zgJf6IF6oq{^uZdxj6U#{+Tl?=S_tco!>++???{zZtLfIhQj4RLLRhKAg&+#5^P~Qtm<@H*re2i^Ie$-e#6Sr}eGFd5ysw!jJ z%%JpQK8T~r@%uQ8g0JP`mxC~fbH};ja(Ivr_QOc!jOWIT>d9Dp;*^3oV9)5*ceNK6 zqbN9`a+wyZHsFknG?E+1&E>GgA6wR`f5r?5Z!c{+XY5)nhn>6IPNn>#5QY1yl$ z%Qv`Thr65&=RNLRo9ay4ep5q(Pn+w~&r6tt_rEEfMZR9`oa5uqhon<~ufCZJXK;P0 zdQdwYXUqfa&zJ`scJv%fjtAPgKOA`2VSoNem>PV|`q@}}VqyQpVRH2dZ)m3`YNTfR zxg{~?=REfOQP5v(z#ko^r_;jpod238hv_+Q*kgLee*raNPyM_b?f@n}?}Qv+;`2_x zlX{oL!IlO0M~GTy_062yB;*HEQ-_57i}Gb2wk0tQfFpF^szTS^{OgJ7}{Fn`YSnyl&~@U?&Z1Xj-$7pd*L|x3`dS>2|1F!Gmh8x-*?t=NxM16 zC3DO>E}3IN966G9i^A|MU*D4S1xYf;vg4AzFCCZ6u_BHfo}*W(PGY|U3eaPp}^3s_LedAu_GM_4t-a9hvctrJ|+1FJL{oT literal 0 HcmV?d00001 diff --git a/shaders/slang/shadowmappingcascade/scene.frag.spv b/shaders/slang/shadowmappingcascade/scene.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..3bf839625ea1cf19faaa30467c66850b2f872195 GIT binary patch literal 9196 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 YreDzBZ~CnEji%3OZg|yH543cK=Kufz literal 0 HcmV?d00001 diff --git a/shaders/slang/shadowmappingomni/cubemapdisplay.frag.spv b/shaders/slang/shadowmappingomni/cubemapdisplay.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..7942cd24988184e197941c00b2fb0f6a5d6b2e2e GIT binary patch literal 3216 zcmb`JTTh);5Qab4KoKZy?a6wC)b>^X)a{3m0CwnwOb*XV$D)Gi&eNQvHrKSwmfx zWjnK<`Rm${)n_uTSyR@F+&45j)IDDv?|$&1`}DVGB}E>yE^E#j(Cfi;d2&Yn99RZ- zf%U}dTLVh`Yeky7k=)J5%0hMTT=|v3%2Z_z^FR2;eD8dDdUk4Jq%xn!{{NgcPtMFP zRJ+HXsnt`;`cU4;&nsnv$dgGQMJ^n-=2G@-LH8mxzB%v3{Hx{h%89{+qZ7mB+0pz0 z>8=gg1!8M=8YfRfb_siYa=wbdZpr&NF;ks8IZ~ONsg9KA%F{2sOv9!jhf}}pr9EEF z?<1f0xz%JWZD-R7oI%*z(OufkE#fz(chH$nuC`|jdLuC%U@P%WNNwLh2Y;Qjkk@}5 zQok=oe+yE-{3i0ZC4Oz8I_=6>Fl+P(w73&LKD z-k$7U{N}#{Skob@w9X%Zb92tF;D1Dy*KZBM|CD(B*40P#)*ye7dhO??bTDjnj_{w;s%hB>ma&4(HC)t(B*qjU^itklT8n3ScH}*RzWS_k;yf#IA4NX`jsg9VTfUgv`-LxN80RXBGj+Dw zz9sAO4aE#zLyxx~vw9uQSq&88rqJb`Rm^=F-8UEe{Lg^-8ADE~3Z1f_pD< z#e2LDXRJQYh}`nU-1ao`oI+oHj}H@vSgHFXbbDjG{>Uv~%&x7NNZKS7uGciHcNPNd84JbfMDHsGw3*3phU13cGweI3X+_fz!Z zxu0Rn)qyzob98ynjhu4DoaQ!X8}bX_xz@M?>9R)o?Lf{t)ZKFy`4u>qZ2NH@Sl8k7 z+js%pnDfAOfL|)(E&_eRRR`)p{0@DC-V62sW8-_^61u+2Al~M;=<)$S(@ogl0e$hN aniJ>!<1R|?V*C|gjJ;Y;_CHki2>2IK*&W0H literal 0 HcmV?d00001 diff --git a/shaders/slang/shadowmappingomni/cubemapdisplay.vert.spv b/shaders/slang/shadowmappingomni/cubemapdisplay.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..ef2e0e8e768ca4ffa3d9dab796da2d49479328dd GIT binary patch literal 832 zcmYk4NlODk5QWPu#x*fUjXR@34H`u+;)2UfL4>*JRpu~<91>+1M8SjT-Crg6m%IqR zucrs?@OtXKuCA(ilVYJ&vC@E{B*4fJ2$s3udJ?Sf4bR)m0Ue)U1}aU zJ>Z)HoZfI2oH>>qGi#_KGpx9YvUz3{4@wJ!rt&L#!b_eHdCn};QmGvX)Ct7LeT>fe zq|>!&ZTb8u#pJ^|pA)DDr&mkRI?wrnO&3=A{3w=gfI5&OCTdzntSy z&bg0A)Zm=^cm(h0>rm%VUAy%3EV^f@Y<@^TYA2G hZCx=s?;olg9&ZTfd;|PAl>_*PPKHW5XHxq0s;a`f;WTl;;HeV#>B|M3zr(3nCQ_og4l$%rqqLH|7kBKzF$8s zESa61H*ep*?&3OU9c%5G*||+MGY-u$kiNCGHd_Qwfxj)5{^ivL{h_&}k~6ZdwX}8= zNff8x6UDybKrt4VUPs~T*H=c{lQx_<{roEYmn`2b!)#mO?5pq~UVjud?%7EA2IP75 zrlmA`vL2^5XFaVUKWw42tmb|hYu8uA^}kZLIMVrm_@({K9(DH2^%-LadQ*mC!&6k zDyo1#$v?|4R&joJyOSF%VHk*xm%sW<|C$BeJCDvKbsawsZyG3WaT3sp6y0Mrm9!LwC{~vpw zJZ^iZp0T_4{`8&li>pQZw`$&8Evi{NTUqBIEMjlWGkm{2sjt+!@yr@(dZae`KQmX` zY_yBU)|_r@Vj*w0>Kun!?&&{jFZrx)|Y44-$5`vIGhImQ~W?SNGb`&%A<-r=Z>;rUo6E&I6s&c}Yx*Z1RE@6LCZ zZ@Tm1J3Y}io*50v+4FvN!jGyidm}!m2u((0L)v4XJbAa}{gzWdB6L8Wb>Ih-?&%vw!;g+%d)6!?=udz~gftE9O4Xi}S$e zbH^2r$k2^*!OI-qwG%Qp=}ix6{Y`zMm^a1u&)?K3#o(NkH}$CujN$kFnPPB;YjRpK zIK#2e6@x{c&KMSTI%}Bgj!x%faKyD!hRf}6oHs1iO&bnXZSh3 zPz)A1W(|vLFBuj&z7z(BW4x)aWZ(?v_*yYou^-h%v(GH^8E?fqn!T#4~6ewKkVT)UcLaE4>I6oW-QGsB{ui-!6A zz;Rm!M_gMsTyBS>VOXrYV_4)^GAwf36$VGFYbpn4_&JspgGG*C42x@9hDDAQVQ@Ic z+gp`^Gn^w=3>G=o42vAU8b&{VCvC;(k3Q_5{yw*^_?8TvI0rmFS18V8=*4;9^SKSh zi!yZMT<|i-+uM}ENpE^k>+kHIV%{1xj%_IhKOy7oZOi{I8 h|EFQ#475Ruvr_YcJbj5D%Ja5~AIr1uUsa!yJp~Rb_74C6 literal 0 HcmV?d00001 diff --git a/shaders/slang/shadowmappingomni/scene.frag.spv b/shaders/slang/shadowmappingomni/scene.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..d03d764caa7bd6af862b89435f5f55c627a9790f GIT binary patch literal 1804 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 JQT83ue*q|WcY*)_ literal 0 HcmV?d00001 diff --git a/shaders/slang/specializationconstants/uber.frag.spv b/shaders/slang/specializationconstants/uber.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..b8c081d72af514144c30b7b284faed8dd38fddd3 GIT binary patch literal 3648 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 SpOWM}F{dTT|DUQZ6aNo3OqSCC literal 0 HcmV?d00001 diff --git a/shaders/slang/sphericalenvmapping/sem.frag.spv b/shaders/slang/sphericalenvmapping/sem.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..a210331f862c0b5e15c18f27a946c3a4b7867385 GIT binary patch literal 1472 zcmZ9M+fP$L5QkSQw$o~#>R$>=@Y%*tUPexVe2x9v!7!&a zr^#S9=^Z6$@1&jOKIO2^-p`p9F%x-T?am-OYj%%2gJzN?>8HNd;)$K{$i8uIFpUUNOKIawW7;6u=fXi6#Af7cxM*UXEVJ_tb zq*3-NSj2yfU0r(>{XDyV^7H7PTLp63X9`(<4c*u)AcXHbQNNb!;kEg%BkN;t(O%TM zv&3ZX7IyRNrKYtNVdTS)e%-wSm6^FGWU_4p>E z?tMhN{W|}sd%iPw>2H2#?iuS;V!zLTJ&J8OW9`kQ-ybyVeaWwL_S>+gs81kUQ`9TS z)}-#-r-3z9h&28Z$iG>3WA%T}xz6P>(C&)dJhGg1MQ)+stn)_^yNE3B{Wdwtv;3~i zX%6ibSkJi%tleHBbf4 zy31Uw;WltK=Cam1KtFkB=bKpt-rq+&d=q}_a{9Usc_GHufi~facNpjO5YBsZ#a{hK tDQ~|O@>tVj;9NXQ`v!2Hzl$25AbXa6)~(+rkk{`OFUI#J_m?W3f`3T;S>6Bu literal 0 HcmV?d00001 diff --git a/shaders/slang/sphericalenvmapping/sem.vert.spv b/shaders/slang/sphericalenvmapping/sem.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..e1356455b981a6fc7f4d6ea3df187939dc9b97bc GIT binary patch literal 4088 zcmaKtYj4z55Qn$46iBNGctKHY#S4m7(Sj&~rHFu1C>FdBb+fjsF1EY4EKqzSzA#4A zVDNs&``s6kNJ2tFKLLIm-WRqL(h;n7B|-WshmD^ulz)h1U)=<-0j@Zw%i(c_EwZaQ3zp7s>8xQOrh zM*9Y5b`jrQ@qBw{-51`+&Xl@}nJxvF)SbP$eN%Ui>fTkqhO-;K4BkS_n9(wHX)`^t z@A_+3mckyG@x_MVz`P@NB*Qurb~eMDOA(JCzR8*N!&2xswADgCiR>Or+THoQX7@j@ z*}sLn=9#4XmPJ(N+xv^Zj&`4}M7Ae=@Kwa0!>R5&)#oPN`&XdP&pJJAW5<+jG(<;##-w^c~kHyLT6( zujMq4dBcAXvUAgaJjuq_|0t(57%%*fAxrxI$*C>s{wwL;(SA1R##@VSpZo@OB;7u_ zuet8NhHicChVS#f`P>C_s+-SU$aQxi*WHEC&mzwxy#v%4pMzJk=jJqzr2ju?_Gulz zt*;mM?dsMyANK8`FGTk38;E7!`(WShJoIq}{cs<=6Cda6j*CfR=2-@dOJct9Mp#@5 z>?UNfjtsjwVb&3Tw1ZJ=9fyJfBF^DXd=UA1nJjd#U8E=$nIFEZ_`)_}I zzwyJi2H82-C+jdz*zQAi9`?(6%on!%k)4Zuvo7;$^Y8Nk*qp{ThQ6^=>yX_kza_C# z>kGMEt2^}|EGEUghmggk=*b4;Apt0`VdNn=@6*PF<$Zc6VbOQ{v#igiY8?soQVbL;>!M_}&MC@d~Tj-AM2 zd5*^tmgg8tnDJu%yO1})_Q&@dKWw{^hhh6<9p(w!UO&c(i2mwC0h zQ%}O?G`2DHJF4SE{67uL3euiaeEXJBzzvTp0_M)mtb)z<}!&aE(JD)ESArz zp0Jpe@%F*S%l%$XILG;T&4lHC`xBPOI{;?9z}%&Su(%ZOJA^Ej$D2-A-1U90z{bmW z=~Z-V_MOH)2ggnvLAG|^YmVIZ8oE93-R9C3vwj`fxU%HCd`H;dKt7U~)yFTZ^QFp?Xg$yAje*5kDWP=?9Lp6V`tt&7PqhN%=@sIBxVmk zfW@Wg|A)xpQeYn;i~07zK2BK7#Cd*_FlQ1uK1DW1e)ltUaVg?`jx3h@eUY#{$CnAq zb9@D6j@<7Ay0{cMzD5?yb9|Gq{O-32%X54OW{$wD_j_1eiX1;6i{&|fOjw@dr-T_V zcJyat`)_|vz{U^TFUZcpK3Ru(!uBh&^RQpmW4^HchU{GIn{}C2o8PXV#e%BMINCiyg{-#hU$obIUd3}+SomrksK{{tRMMhgG{ literal 0 HcmV?d00001 diff --git a/shaders/slang/ssao/blur.frag.spv b/shaders/slang/ssao/blur.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..7a867756d08a863b26f2d88a57099b732ebf44b0 GIT binary patch literal 2396 zcmaKtX-`v85QY!51;hRC-&k(t@R|`T;+f_<#Iw zZi(Xi+@1-z#AAk;_nkR&=FXf`W3|2YE?(oDyXxNRFRR(ry4zmkIpt!|4*RrgaB=Bc zNiiFiq})x(oTOjUq*#3Ql9>J-mu6o=yBee`!Om1z{1=Y7M)`N5*xzk(a8SbM``eDI zM(4`G#^!3Jn*0AartffW*XKO66VW$>rS;9q(88kJIx`V{-$u5$z8aM0=O<^QZ@DF3 zSj-lJC?@XiN^b?r^Wk0)`R@s5w!>UyrJ7?{csXNCwZ{9ztOQ|Ur4pSpQjPHpF^y4Q zgHolun_de`m2|e8EoSoNY@sM}+V`K{=CpS$pWg`l_ZNh#HRqywUJD=gr!Jb&pLtTs z!wfG0d1Pm;pi6$Bo9%wuBO zmFq;rSA8eF4~|@yrLis771^8vKOjFju1Q#i2V@h|sgnk!*$*a%EikJ~=UWaM|QRl6R@wz!mR@{o5%nq0g+ z>PSoTD&a?k`EF)c<1uwII~IQ8nH75m)fM`)C80KCSR8w;2gH39;ym^&(3dF* zXMYmno;~zjO8SdxX_sbwS3Ev&tAumVi95i{U1Duq$ycyZ_f|>EImLzcI&&uXp z^S_i0m-aJVmc1l_|KPctYu|(c?W?l6OZ$pRNEan=0}}etEloer;2w|BmSbHu-)}kI$c7__%^l9} zFm+&aF6WWASDJIsV7nj81AM{z(O~``As%gYJeSR!td1A5;j9jPaO~%OupbTP?SQ$n vmhX{lYP7jNmJNrWem;@VU*0Zw+H=IE_3OpFW<8J3gm0hoz90H!7?Jz}nQX@2 literal 0 HcmV?d00001 diff --git a/shaders/slang/ssao/composition.frag.spv b/shaders/slang/ssao/composition.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..7f5330c727d00a5d08846f564cb445a94918312d GIT binary patch literal 3372 zcmZ{l|8Ep!5Qo>ccc>I7Qi=#-OCe%_DzPAl(1RjHp|)B9HR`dXtyb^4k!uquBMyw9{Hxp6O&sCe!z_7HvN?N+YXeFkYHX zJE^k5&(p|@r>E-WI5DX{yVPu6UpXsgkE6F$GKx6|v8lxdk;bmzPFVbOW2xwIC78on|Jt*wfF>gxNpu|(pDeJt$%IjEa`V|_1mkk%YJuSzxV0a zF8dE-SK&VR9Iua=4P#3a?0fWGzq%Cuz`S3q1_$PyV)i$%?gBf9w4P%~>#LOPa(&~4 z-*d)mm;HXLp6@CA+GW4YUieLmZ6oXbg>L>q><5tg z#q|#$jrFbiA4YnI_;#WnLFyMXCP-V_!Tmds#(DlxK}gK}LrBm2{{7hMPry(u?ESg< z@z_@UN6-gh^Xu1s2Dbj4{C3{fF1CxT&Rc93FL$=uo(Z<5quAE2KXN{cZcX}+BlUZx zAMGSE;%ewoi?v^Zp|S8^#)#g1j&4rtJ5FAE>G$AyZF>{540{il6t?>t0%WETb9@ZaqJc;fcq7MI$h(#Tz$mz~J2Rk2k$+Pay30VABV%(## z0;?f^r`sEl(qF{u>xI|D&OjM8oJJpqqlPo+Vo}4(*JRpu~<91>+1M8SjT-Crg6m%IqR zucrs?@OtXKuCA(ilVYJ&vC@E{B*4fJ2$s3udJ?Sf4bR)m0Ue)U1}aU zJ>Z)HoZfI2oH>>qGi#_KGpx9YvUz3{4@wJ!rt&L#!b_eHdCn};QmGvX)Ct7LeT>fe zq|>!&ZTb8u#pJ^|pA)DDr&mkRI?wrnO&3=A{3w=gfI5&OCTdzntSy z&bg0A)Zm=^cm(h0>rm%VUAy%3EV^f@Y<@^TYA2G hZCx=s?;olg9&ZTfd;|PAl>_*PPK6NfD3DMsA`pGB+1kZa+iqPJ1%1(|iBJAb zKKMuZV&eBZdnT+taLn|~_syI+GjnFK&~>gi=-w9u!KL7$Mv+7|QvXjF_?W^}6S9kr2 zj>Fzb;@8p3v=OTtoX3}%T5&z12;=D4yGHb0o4D*eooz>9QfY>5dS*O5-q@uTwcz@^ zRg0w;UBA<4JKahm*MM@^aXfFZ8MZpjDEWt{aT#AaR^jfJ!8)_Yf(L`k6z{P6%6K;FEho= z40+7Vj7nJ8nKdx|2Qw#N;(?hFFntGK)?SnlXF(O&+n*C=&C8Sbz6ks7r0U7&Ktvxise1QCd5X_E#klu##_Sve%3PO~4CPMwC2OQ+6d z-Nn0{kr0zRzj^MB=b5iBo@+{nzaW_r$Gf*A^yr#|_{7tnf5%&_SeQ8QcCI6xbIhWh zdn+B@&Lz@03vWJ~((y5zN+*ZUKF2NT_`sXbJL&l|{Kvx?t7}_2KJa$;j&$n9W_}-} z6Cc}mf8R&x{YF2Nt$JxwjMO>OAR QH94U()A;_;4UvT5@zWDMIg8bvy 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 Z6fepKT*Jb4ej?nA_Xg*+e_s_L)D5s?Loy z<>hA0y(D>VdxY$(`hWh!Y3jcqWYc!1rJK^snDHJmmlAX8BYMT!Gv(Rr1jla}E0++! nE88+FeUA|Li$hzh`FepJEA>y>Qzq`sNOO*iq*I>{ReRzKs@oW| literal 0 HcmV?d00001 diff --git a/shaders/slang/stencilbuffer/outline.vert.spv b/shaders/slang/stencilbuffer/outline.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..a34b5835f841e73dccc8afe2a40f311e11df648c GIT binary patch literal 2400 zcmYk6>rxXz5QSHQ!7GT!MMVsPilPV_5k)Y73SI(1M7)R91PB#aDl8U1^#v>**FRQy zzRfhwP@U=idZy1z&uXfnuPJCe5(L3Ou%=%|YtRrtnuAml#n&;)) z87{ay=eB&Wdsn3~g{j_}U!TOSBYO`isF+Jel1$kob%zInR`FIC3 z$g`imQ)5(b&N^}o*dIk`Pv{qo6Ef-()5m5R^%sI;N!%)*H5kL{O{q3_zbHeWo=}56 zbj#qswT7CPWYmTKa*Xeo+T<3+*mqfm4(BY0alVX2U8I$NY7}j`Ny^U2-|iQ!+HEO%2xC zH#H-lZ)#d*-_%q2aPG=C^-Kn1*n2;h4`*0UX63^f#^&V1{64*K%6Hu( zfA4F@H63c?9rM@CJLYRFIOb~<#L)29Eh>gH>>h9A!+eb;$Nar-9rHDo#n3RuH}y^i zXPCx{e3-BC-Z5X}gJaaQ_x~uL{?i}MPkqaMlFvKPC+>lcjJ?IzrLCE~ojc3{7fNgS7|l|AM0YjEptLR^`K|WRvPdS@WvwuWmag`v;u!iYfpA literal 0 HcmV?d00001 diff --git a/shaders/slang/stencilbuffer/toon.frag.spv b/shaders/slang/stencilbuffer/toon.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..355dcc22ab887341f1434a9178b7fe8a1969d71d GIT binary patch literal 1624 zcmb`H%T7~K6o!vLK`wF;q~f)xL?YU#Q7|#kL{JD8ESi`wG7VB}LR(YoKu0`*6CJ3p z;mnZ_P!eCjfluKjG4cBj-6xG>H~G8PzxMj~W$kt7>^R>ObsdVLXgYexuVWY|{ z-O*|6a{f_1`=aqQd*kL+=Le%sO`J0n^+sLz9iUPySB-CgG?)MOe_kdLum20KGs%{j30{dF$zDR`+=O87LK zk?@(A?k$A;EPTJ2Px$qiHxoVw|M+1d(dT0QmxSMifBm$X9wxNq0a zeY?Qb`*yA|%TC69Q-`siF!y#X-^X6p&cnUiG2niIAIEpUz)#@2-$1Jtr||tAt%uqW zw|7EZ%{$KGz0U$Q&VMG7!A=6>_Q4NMIfixo=1k6wf?nX+wLy0QU)>Z?cNFVT=iCVB z1M0LvcM)HmeWh*~>rm(15b*zjI&IKh!dGYisT;&P)H!zq3;=c7H{8#fUIEt8K3za( z&5ivc&o#_f8}hH=n{OY7d}HnT>g1kXy=M;kS$y^Oeb5_g&sQh6X6mg~$W_}uXO7%= zG1vD9doAFbp94W}tUX^{=$||I-aquiBK{IEUTF2y3cm4x0TkA871&eO(R}m##tPJV U4Z9A^@q6+t8?D$MzJgoeFMc?T#Q*>R literal 0 HcmV?d00001 diff --git a/shaders/slang/stencilbuffer/toon.vert.spv b/shaders/slang/stencilbuffer/toon.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..aa676e9b6533562134c463d6198c8ddf11b7f425 GIT binary patch literal 4376 zcmaKu*>BWU6vuy1C?rLY2uLF06kJdcMJu8R6kI^1P(*OI8R&q;wu8f9iVvm{iM!&y zEAASXxWpIrff&Ul(FaK+A>j|ezrYt0Kc8Rkfg2t;&3EoO-+S)a?wx^_(X+=DV@4H4 zF{k*4Pi1m3x{#Szw3N2`q+&v;kLGir+Bc|C0SCb$a2Ol`r+`VIg}*jd&yM9!zHe~* z&gT5?`i_!oE&WEgHTA|owI3SK3B?T7o~~-M(KocdS#MOg)_S(|*Q?Erp^l!b>-}BT zZS}^EX77TIi;JR_6Z$K?)n?Vzd}pw3Sh2R}xL<3@xxc+p-&Wh)?5op-=k>MDfqHMv zB3k*Av)BHw@5gtdxbIuaYjtmLF^^s2Oac1Hi-bbO#vBfy8!zJjmG;8^JK3ID%z5YLciMPi`_96)z6vm= z`^NLG&8KZV?>e`=>)iIPwMX&k+>e5V%)=bURowp<%RZOzX??yYYYTfKy0tCmY&+{L zPyybDKF(}5kY9(7b3Z$AEG6e0&H?g@e%5p@kXM2`4_(eWgPW5$>kjVx#My(KIW7R^ z$j{DAJj=1O^AeZ)U6{B$$Na?QIWB@TNAAZ@X(6vfeGAa#@*I~WE4QY8*i!;y#oA>#hY4=-U;m0H?;!DDRJLdqsuEXlWWlB zmEf*Lm&@mLUE=aNtxTMAiX5xZ&5@tI9$Q|C95o?tM5f`!Qea-Hz_PI5+z;uY10!JAgTjZ471z*6>O z{oU!e;x2T3rh>hRyBl5JxWV90`p}J+`)$LPS0diM=yJJVf8z3ZgK)+R&i7CU@=Cx1aV6^eCPN9+%y8(SzR?mq-) ze4)gCH~%8-#(o%>V;Jb`JMca20TY4y@eUqA?*z`uckn2XQ{vtpLzh=#rjMh`E5SX1 zE|<^w$;8=T_&t?4=NvhnMmI-(_8Dw>CC=_em&^U0O?)L(=yb?KH zM3>8Ryp*{7?8}MEbG!m)j^KQguL5}`a=eBvm*;prae0n65@)=4cWZ559eh+=8L_3=-!KSvoG_yw}kZ_U`}HjV;_j$pm)*RK>i!_9=5#a z;+?&Z-U;mAclH60Q{?>qeF)^0nA1n-@=9){{&}zp~Qat-uw)=9~ehp|4(#)^%qb9 zlY#HRo__`Mk^8sA$tw{%ezSgu)5jcf<_~n=m{8)(Zt{-D{u6jkzoks~AglidsvlzA Tlk~%^Q<8p!)pP$5Z4vk%0=`^} literal 0 HcmV?d00001 diff --git a/shaders/slang/subpasses/composition.frag.spv b/shaders/slang/subpasses/composition.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..e5068101807866d40ac4187ed87ddddc8b506db8 GIT binary patch literal 2668 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/subpasses/transparent.frag.spv b/shaders/slang/subpasses/transparent.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..d9fbe6c324e636affb1f5c8c1d13702365a2964e GIT binary patch literal 1668 zcmZ9MTThcg5QbOI-~kX25f31VQBet+sL`MjMQ;=fh~B7Bq+*p8Qc9wC7-Ql;GVwRy z@9_{#e4g*yjSbsOXWn;aXJ=-&ZEhNC4=wvb2xr4O->%-!1j_ZbsEs%jn)wbvyE}A+ z7IYI*DVD3KFoet_Pmx|^0O?_mG3`h*pZ#d}xAM_nu5NDEFD<$SrX$O-Rjh2TmuiKL zt#ZA*QN35%tiQ?qE#VZ#Y9!1t37(yqo?j|FoSvP@^In0w|DPhNEvqZ$eNuW~->#L6 zZ3zp+=KLzSE33U!t=B#jHpMtdcLcVDEEzKH<9P)hiio!VQ(AS zdlDZZ=3vH$Fo^FEw%9v2wg+u4dHsjc`mIBMKU%;1Q0OFI?)MC1(n_{_jz-eh0q`(- z1Tl|i97oH!XFU2-Zx^Uq{|Q7+F~*uk5!ZQovbQlL`7Y`R;ZDL68Qi&jIqr4--*D{^lfEa^gj_zbI#T6YNZVKjsrVL*Gxr&d2xT z(r-TR+a)%i_ifH|vDbIlSLxausYd-jLEfeN(!G24Q()`y{aTCIJM2TOMeO|yBG$4( zZsU(d&iT*5ITwGc@}BnW&eJSo0 z_A;XHOU$>5?K%3s!8w~7h`e)4eakiWZU5eZ@l%MiagGPjF6Suke~_HB(l#dh6U8>h zcd>@Z8KeD&SE4QFndRtHi{D197N`7bYw}$e5Z~l8UX|}+A#%PSmwow0<^OWtb>ts^ Cs(u3i literal 0 HcmV?d00001 diff --git a/shaders/slang/subpasses/transparent.vert.spv b/shaders/slang/subpasses/transparent.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..aea9ddf82729becf4d438f2dda6bcee11bb78309 GIT binary patch literal 3164 zcmaKt-E&k$5XHxA2q=LFNU$s`MOXzCh@t^Oz5#I2C=Zk!%eWUE;s*3gGa_+f&x;-oJ9JMcX+IQuYRjcY>yq+uGT=k&c zEsJ~2ywfe4S&_}PmfA(xUY=05M%D_f*1c8r>NUAl;heeBTi+w4@zh)OafkzGfaxKa z^MdIgn41IF<@;oB%Pwe7?+rX-T$$917W2dmpLdS^;l^anu?B8Mh8FL^*E@DSFmHu7 z!2t7aVlBKOuVsh5!C{@RCLaAkMbxrewoB_b%7c3iZ!%0i^KTmFoV$g$$g>aY!1M&n zI`9s|tlKHPv*Oos4j3M^9LMhov%h1n$MFZ6<9zSyn_i&}H>6tV4cw6R9qh(=J``r} zVHtRzVRGITZpgDA`=duM9?4Q#IYa(aMfAe!{l~D^`>$c@J)wO1!`~@A0n;Demt*?F z`*O_r_R2UT`RJ|6&;+B$9Xm#kI|d(B&FsTk2Hbx_)N)GSoSFYPoCnOA2V|TF%$c{# zIL}$_wNHM(jPq~@78t9yVTXeeGw)#k|jriyEWGMU5lks3Ybb6^3W{`MyvL7d4I<7uOy) zE^2%!4h`q%)d?9q!!=GShKm}fjEfqljbp#2Iz_L}$ml=);r#6Hb7P9R2l_-E==j`O z#oPz|q8{{o?wn%og}zZ2y394?&&$vpld%W6{-(ZC%$wrx+~3sKis7lXEFtL9V~4Ofhe2 zQ08yyx?*^0t;^q#!7<>t?`au4!+X+J49{@xree6*r(4FwKHWC1Chr;@#c0H}Gs5r; z*Z5O0T+Ev_E^5pf7d5)#(1>}tFg(LG<`u(5jXTE0wS{p}V?i7m&he&789c)^78S!q zjV0rv#$Dss&+mU(G5x1MoS*%D?w(@qfj&_OIzD$_G50~gs0Tft`%5wRLf@zhUFI6{ zf6LHhZ}uQ}QooFwc?dN12P-eL;wH) literal 0 HcmV?d00001 diff --git a/shaders/slang/terraintessellation/skysphere.frag.spv b/shaders/slang/terraintessellation/skysphere.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..2cfde97d8c88e6d8d306b5c64ea9a2015fa6062a GIT binary patch literal 596 zcmZ9JJ4*vm5QWFx&BLfkG@^(gi8fX#LqKAaB2^%bTFM2ZEMy;C*TR2pBY3`>-NspF z=bke&XYM18?mCtnnAyFZ>yMpUWH5b;17 literal 0 HcmV?d00001 diff --git a/shaders/slang/terraintessellation/skysphere.vert.spv b/shaders/slang/terraintessellation/skysphere.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..982ccc80e061b1d67c059214b1355d8a08770b8c GIT binary patch literal 1576 zcmYk6YflqF6o!X(1%e175xgMw;sr&DXhjq+5jCJm;~E2BH*2V-hIYxakowJ^;Lr7o ziSIKzW9N{wbKZB(oZC#PR+{&Bq?TWtrv^M};m%f*N zkj_Zwq*eW$*UFi5`h)Kcj!%nLoSirhzmnTOkSVWev#2%cq($Bvekrm%{oYN!9c5|J z9=4OW*-w}F;YRzRG2=RcKXRBBDJ!`awC?YGN=AN><=F3^9m}I?Yd-y&$)2)x zcLzoOGtPR0B2M$PpPY5`qC4!U!f1@daPeIxf8^-BS!- zZ&MiARV~zuKl|9oXg{*G)=S#PWZsPcGka!@kdu4xHO;#_tlJwY?_)tWHPxhx@}JNO zjvStJn3~upHv7DSn(zg!V^Vl9y@5G*S@@FWOK#QSd2xuxS7noLNnd6}4RFiK!i?as znFp9W*R)a-9C*p$(myg=!o(pid8m0?YRs?K_`j1y5BPxh9H#DVVfx~o(hHcrxKEGC z&+Mszec~~DVuFds?7^G5OU~ho!2J=TwwL-cyJ;!;z|=4+CEpvJrMDYW@-aJn=#zVe z|12M7bklKKELZkc@}6T3b!iPk!dbY6v?ira&ov!K-JZMUIC_91$89OO!?SlBujT*Q zyN(O}RvZ`RxaYVq$9-|+2>n)t;Spco1KDt4jy1=HXIqX7bF7Oahv%4!{B@%O_6`RnO9O?xLiESu} zS6&G5+Jq}XB`%4$A-JM~yJB1-uIPokQZzB~dH(ZFbHdlWXXc%mZ)U#jZ{6rQjagw- zmSyv^GyFOxW}`DLW3z^A3UXD)tsTwV`a7E!U2(boaao-rj~Sm8vjX~P&{OX2)xHr7 zfdk-Na2}WlCV>geHMSAd@i!J}t$J!1*WJ7I-u~vB`zk%6z$pT;c#j_C8soHZQ@-csf53t5%( zmI7n6M~|)O(X(q`2D0qoWs##j=Zls{jyCu*pgnS|KzBc5&b8>|7@4yYX1w;8b3M9e z6mxDw&$5S>2k*%F(UBZCz>U!!IaZ?=61Vp?Aj=Mo^t~U@JHb%_Wsry{4w~& zyB2W&8}s|TA8w5IU!Q$j>v5!K>YZ%@x$p0(8t(ghI`OOVyC!2@ zkKA|ZchvRBeP4c4T~GMWM|VBNbk38}{eQI*I5+H5YwXV1L+_sPG~gWlMXGDN0GPvm z^}F|_l>b6>{eeMd*yjx3H%oszHoqm$0N3v~q?H|%F9qR0h_2u7gMPVhKm5<4>t6x% z%UxIapF`L0JJ&Dw4Tt}Ebp5_z{c_)D_+LQR@B7p*_bs}&8;~yo@5XKEP991&&%iTx zU)Hcz_v|px@7R@WN6-%g-=g_F``8Q5y%YRHrk9c48|7(g|A;&V9Qt2D>Q~BNOTwmmU3*Ef2hi{|1huV$t zjvfQrV{eWpn{Opz-Z?AgUAQ*K&a{8;p*vS!%zGcbHunc`ZRU=7AELYW`n><1&qu&J zT>$zc_G5JG=)XVJ{RBPi@g`1SbN+nbxf}BU@viq%;GNh3`lw*N&wzVUf{j6b4vf?8 zS_Y9{fFZD+9)0^?CY!O2)qLHY`xVe99In;-XMO!Afid=IZf#!!@7Q39`6k&;B0bx0 zk)Ewm{$1iqbIe744?ODua>##3ws^1lw0XC!WeszkLYiAC_g>4rPto5`=+5!2*zbd2 z2GH)FxgWcM_B|l(($DCP!1agimt?C$#u@&KZmhm|kH4d9AFi?efv#Od+@I*$_ky@T zf1!K+vw;30XX82l4YV%+#&|dEH}2Qz#EmPZ@5m$Q+G}Ax*SrsyuNk=h{lIwl_yAJ> Jf82m2;D1&rI(Ps8 literal 0 HcmV?d00001 diff --git a/shaders/slang/terraintessellation/terrain.tesc.spv b/shaders/slang/terraintessellation/terrain.tesc.spv new file mode 100644 index 0000000000000000000000000000000000000000..e51394a56565de5ad08664df2df65adacc49db09 GIT binary patch literal 15940 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/terraintessellation/terrain.tese.spv b/shaders/slang/terraintessellation/terrain.tese.spv new file mode 100644 index 0000000000000000000000000000000000000000..490be63b11bf5cbcdf08d138b7247d9a02b7b5ef GIT binary patch literal 5580 zcmaKwX>3$g6vv-TThLZTaYvB?ii%djsu;9xY>7oih=2lVUptTK;7q4Zr$}+b1y@wu zcg0%oIX2wh%8`bR; zMbTkV6Pwl^(U>S>J5*!T5VdJv(7v?2rN5eMX+7>3snKq!R}|s1d$gybq71Kj9!@ymFFs8@Mq=XYAV)8yF}g6J5H-q;=zuZYsb2zTggsJ zGacF5c6==sKh{WWebg!aoYNOuAbt%ghhJZ%yjF<{W!qSz6eT==L({Yz%ajB{!z?p|X|1Y`M@| z&Bm3u)R8MQNsEM$N9K;1qfva*hbJeqHj3XewYx0oW^NkOnHm5a zav-zZ?i@Y9ohmp-4BW@Vze4GXD?|@@w;kX3O!*5tKx|Zux zYHF$vNe|`tB6adrZd?eJ*cJlF_*tcmX9uECy?U_LT#dO{S z`>&?c!yM_nKfgmena+FiyW=|V#qW&kyf42qu5+LKuCU0*dGZ21q0`ThKu_rOvpvx1 zhi@vh^G$_1-&CmcO@;an(~s9zMPJlr;q$jN?&>tznC-m;&dW^0ah?MN&g>jBd9c8_ z;Z9bD+Wpqz(YeoNfmn3zbBaKm*P1GsTGNc9)*%A5oTJvE0=3}0)^y3ld#%GH6YI4O zmrR`3IzlqF_*VQ}M@puabJRLYpcb6hYLQI5*E(7BPBxwq)k*Y`s;3_BjF^D=UtBKS_WGO?nx)lZ7^c zv+*w67k+L(MY7we$r-VGozo>#hk5ckXGn$zo@cIP&qGb};+Ivo%*cGfd-ML_7YH85 z9Pz&Rk{A0z!R_1;Z-U+Po+;UT@qUPF7d(y{Vh8+_*6I3gf~WSBj&CbG+?U0zAuW zY?2HY*0|cZu*NmUk#Ip0jpo-(sA$l;gc`5#U*VC$~z5XE}G9 zWVrC2ZZ|Hxr#p=Ed#A>o0yVA3v1kKTv+2ianuO??w1bF@^d^O z87{2xpmAaBL&k+Qwu+;MbIjDk!d8LhH6D??RS0W5YFt?3G2_VR@Bg@D?w|XifAYKS z3CX+z_ry7<bUJY$-D>m#d)abw(lkLF5DaEqAoVRlOF_XlA9d(`Zw{TWabMWpShnT!vhv) xm5(hA+Ml`gtyqODX3JAbx~#QD9xhn3fy z_MZFhJ@=zgYqw|ZIWs%3W4$>eYZ;z_MUG<+t?%rX-g%N0kbPk)90>zqMHmZ_9-_(X z=;1Cao?hx%Ts}Kr*Tpuzo3hH2N4Z@r`HlbXzVY>4jkKt%_qfc8I!>x2e|Sx+I(@rV zC$k@cjxD-g{)u&>^u!#$8fI74c71MBR0qyHaOQy18=PD?^EX>*IJ@|p&t5|Q*za`5 zZKu&(ligL!L|B(zPhWW3^Lfwt3*0YwPW_4avcB|29DLPt;-=zgZ3$){m)!5kLW?@^ zL(fD0%yaV3bdNs&jv9fplfbFRP69`tolt{#^w~+^=(7{}iT(k3%)-IfgnvZ)WJ$B{t&TSXJUA&>(&K|fY4X5JKtVJ8==NU!*?=@WfydPMt63a7$1+FCqP literal 0 HcmV?d00001 diff --git a/shaders/slang/tessellation/base.frag.spv b/shaders/slang/tessellation/base.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..19395722d56d479dd9c6383ee11fed2b4bf4b659 GIT binary patch literal 1068 zcmZ9K-A+?c5QVq>L!k06h(v8g1OjQiP-9{Q5@NV1+Qa~t<|LqL($hAFdchq};FS-= z1Hk)uW8(Ln)14TnS)ILRX0JVa&MueMCqm_32w^L1^RLZ^QZOnm= zOTMQBkH`ki}x`08)k1G_;&`rNA=~-(s!wTeLSNX*1rFb zz}gs}`zP)k-CxY0=;w_6-obad0@T%h(UbFe0@PNgjm5(hA+Ml`gtyqODX3JAbx~#QD9xhn3fy z_MZFhJ@=zgYqw|ZIWs%3W4$>eYZ;z_MUG<+t?%rX-g%N0kbPk)90>zqMHmZ_9-_(X z=;1Cao?hx%Ts}Kr*Tpuzo3hH2N4Z@r`HlbXzVY>4jkKt%_qfc8I!>x2e|Sx+I(@rV zC$k@cjxD-g{)u&>^u!#$8fI74c71MBR0qyHaOQy18=PD?^EX>*IJ@|p&t5|Q*za`5 zZKu&(ligL!L|B(zPhWW3^Lfwt3*0YwPW_4avcB|29DLPt;-=zgZ3$){m)!5kLW?@^ zL(fD0%yaV3bdNs&jv9fplfbFRP69`tolt{#^w~+^=(7{}iT(k3%)-IfgnvZ)WJ$B{t&TSXJUA&>(&K|fY4X5JKtVJ8==NU!*?=@WfydPMt63a7$1+FCqP literal 0 HcmV?d00001 diff --git a/shaders/slang/tessellation/passthrough.tesc.spv b/shaders/slang/tessellation/passthrough.tesc.spv new file mode 100644 index 0000000000000000000000000000000000000000..8c59ad09a93c7637b899429c58a51067e46624e2 GIT binary patch literal 2468 zcmZ{l*-lhJ5QZBVL~sE&+)xMiecvLY;D)6l`3s1rS0h}zx|e^_SBKJk;Mf{NxK)MZbzo- zlhdg50r`ZCAQzCUNIx=w3?e6yK6+SVZC|Ps_8M&0iCCp%Ti?OY0<<-q{LDj--?}l^ zd^*>}1Xl{5c5UVvb}L7GeP(v5-uOG`&bWQ%6}+C-n-3=TMpmo8Tw8uK^;OdG@D;eH z*x$qH=Io2w%;a>lR-dg;-Jh6iG_Em=XxEv#iy8bkkM{1zc|Co%wpi&-ezk@%b6MN8`@axMyR(h>v89D&iN=<$j)Rx&ArW{+^xv z-u#2T8}?VmI8SkJVONSfqrb(yqrk?NF&X&{7B`^9wI90+Ulm!&I`S2}uDCm6?~}ME zV`sdcsm2Vp*RCS2wJT$}*kb@3XQ8hOUW9f{{l+~Tc|?2#w!QS5zcOQUqW@}a zKkGd^`9%F%Z0q$~zb<2Q%=awi9{E*l^Yxp*F=KOLy&c&X_yE|Mm_L+b&cS&M7k+*f zx{^+#oki?tG-LN;{rQZ8?^wq2HGU=I;CC%!`5C{3cAlP%{9OMLBEP^B*q(9VNo>F6 zWHr#v#XD#p_hz2W}%z8SGz>^W~itQC8%TM_GOoT}%# z4Y9^NW5HoNwj8{l!C@!19Kt7uU5Fg?1&7_()(3|@*wzMzz1Y?Thke-Am}e|F?8laa z_a-F-4Q|HT=}(VSD9py#FE zUf$gki1+6u*f(-2`{X=|eFhmp^heEE>~hUHus&r<6g6o=nDfSUKrOJ&HV)H1DRm?k3$fr3gDGwj~+2uFc{Lx-bbSFC2b&6L%L zoXMH!zwAphJ^V7Ab*i=-KHnOwy zib8u=v4dz)%0g{+5wjRY?jU!OHRKs&H?kjjq_it#zV*A=%X(uKKHJdZ?L|k4E!A36 zGbhhAnhUjgVDR>Gk9B6->@!DLY zx!jt5wvWSfu!s4s=~}C%cHbfNE&A4&k&QJVo{YIJJPOr}C`jrN|Z7XM0Uu-pRPBdm0TNAZrZJ|2daH8YL z#sJ!j`^%aBPi{FB`|&Irdw4Hx#rE<{>-VAWy*P81{)6Za#5{fPr4w=KKZG{ECHdZ` zac5!NyLP`F$sa+RFV7ffin;gVyGEHq%+0vAE8>BZW>_U*-=aN_Gww!Q z;rFb&rSCh<`}fV}{jMcn{=H08-Ce%a^`7@*+g}%Q0KUy={kG&gCw#|T!~I9lo>i=qE{D-#olI#6t*Mt!*>S0^YERS?>v0Z zH;Q;h>*e=dc?Ny?eOKYjzn1*xc=PUKt;?K$@a*LbG4J;Q#PfNtV)7qEJY!(q%cF?r z6g$lh&cwHDy}tb)My%Dh|1QM3;OfSft0!S{^&)ZwCf8$#Tw=lXIJWh{bp+em;5v$J zU2q-4mdp1NeLaaSS734-N8}OH=6Oev_ae5v8oQNhPh(qeENTa^t@UoB_9bl3ZY*jCv8^}e9LCVEBEG4( z%VF%-67K#Z*smuHRdU+HSw!3w=NQKpcLjD1Tg<)!JD)Jm8`wm`e3xQ!TtMW=Yu`vX z>R#=|gynf}CM@TeOjyow2~3VW?=5_BSDf!{Y_Xi$ z_yAih=lC#TIY%{N?l-}toYiH-`8yxa@BR_1VS5kG$v)(X*cEK=!+F_{d=Z-}ZT?q5 z+n2n?rqOleGUDFuVQ##stJuD&9>m{^Ve~ab++KZCGYLbLm_5uQ;;xv<9JaVCu#d3C z@;S{XET7Xt!YXKM3(wuYWJKfvY*n@~UfqjE5?pySGZwvZ6 z~M{So^FGJr(hPuS)fGjA*U7o-ab4zb(FQ6xCTenreR m7PY@&`!^#v%=;ZN*Vq6zdIxQ9+IP{OL3<5t?!VmT^T>ZY67To` literal 0 HcmV?d00001 diff --git a/shaders/slang/tessellation/pntriangles.tesc.spv b/shaders/slang/tessellation/pntriangles.tesc.spv new file mode 100644 index 0000000000000000000000000000000000000000..21b7dd7e2e7edf4f8392767c1b1782b4b7d1d6bb GIT binary patch literal 6032 zcmaKv?UU7I8OMLHyC_P!1fn(#gMvzu&xj}qq8O4adp1JUwDkbH?ryt#*5#~iina(U zIFmM$R+gG+rckD4j`gBZUpP&Z4>2h^<4n^(puTWQ&GF&$`JMZ+Tjsbw=HkA--|OMN z?(2S-vn^BSA5^qXDT-oYarsmRzL~|;q9u)54l7Yns2^Umm!qyj)&60IVjYG7WEj~1 z{x(uY`jF$0MaZd07t&5HW6j@Qw3hmpKE(}NYvwnnw6zq6GLpV%ct9MaB!0 zzK_uY+lm>*#Wbh8qgo&BA75XujaIMj>Fyn@RqKn#7k6J!qpX42=+^p{(-yNh`=h_# zmTKLtf@v$h0k`4&&hG#FO)EL=Bcru}p3U|C8ar;hzNQ$eZRw%Ca1CGgw%)UK>&n5A zJ`)G;e#@`zxwiCoEuNdPO|^1vVfSq3`90@(KG&Pa_kzv85HX*dsNJ=SS22V9DlPFn6fBsgQ_CNi!iaXT5U$Ne}4-7oO54Orq{ z?0LNdVEdt1oA~e)>suh-=zUB1HfWng^_ZBag@27+&p~TLpNAYt9nK-PFZ1~SAVx)A z`*cR_#%n)>QM7jc(2_gWUt;wj9p`ow(aBrfnOuszeil5FE88;_DK2Ph6klZiMf=Snrbn&sf;^ zYb}ZuV%K}-ltw=SF9Cb}oAmvwz~KZ6&(-qPFu( zTf;|N)OG>7wRv}1P~3`Vjeu`7U}MGYFP5#`m^{*aLZE zW-^W-@?H3Np07z9L&;5NtS8QUtDon0JaJs>GXHgq*CXD6$lr#(E%DZ%&ke{7B=@;7 z@!|6WuxBFonE=a&&vx`fk=*AduzdLJK=*9tK0Cqk;d3*(XDs)*1uTCvHM@pg$Zo{7 zY){;6iMRGnR&AfgXi(#h0r>2f{R#WE5Z-acFYG(WY5eyf%%R_%X`XR(dEbSo=cnlM zuGd&={25|R+QRSd#QPQpcQ2f4vF=#QedzM8FKWG>{LN|&`!?*&)*5TM0lPW$i?!T{ zF290#qMrNFxJ*t+wx^Fwk?c6M&ZK3Uy& zU^j<;QTLC~<@36qW?uQc?mxjM3?tBTll>Uc8~LS;~!x82_$0oq03uyoTXR5=F}E`ucFKEM`DiG z(Dl<6+#Bfj$$J+2a5uf1>|XpF`(*p{3+(35&v~Yk`yO=n$U7c;cQ2g2+M@3J(0Ajb zE&P6ouAj0iy~p>X>#HsL@FsEg&pt-Jx6t*~7JhG|yKZgKhj-BJfoDDX@E~!Mo!4Ju zZ`P+cuMc52hkntA-=N!rHAt-QVK{xYMct2}+Xrpow+CH6CHk-zU0-dnzW)$6f!K@4 z_g{2uf`tUfqJ@8D#`ksK( zS6kHm2XyAd&AQbbYmj-^b{#TU&)+G)FORwfCv-RiWB>pF literal 0 HcmV?d00001 diff --git a/shaders/slang/tessellation/pntriangles.tese.spv b/shaders/slang/tessellation/pntriangles.tese.spv new file mode 100644 index 0000000000000000000000000000000000000000..7322860d420735600f55d84236090e5e447e6d2b GIT binary patch literal 6380 zcmaKwYi!nc703UBwrt!t#$_90g>DSSR@<&zHU^a8WGakKWZtb0w2Wfu1ErntVgz*< zW5}||8$*l{V+`@lj4_iKqeNe5;(hTl@AK{wLFR2UI`#8;dd|bonfPx{e&>A8{rt}J ze+pBlbWE#SuBfVNMfGJ5o~x@V)zmnJW>js}InJ%yc5drDJU-ajySfXpn%%IfDsAQ< zP2rRd)P_ens!PxzloQZVs1NyC=z8cTXgM^O82T6^`33M(`I!-TEBW;~SR3E7uk(TW z*n!#zV%5rzaVGIy4^3iijkuH8!O?zw!uCy!#2DaD6$A*vW9Iubn9v&LlJ5sNW_a5mT*is+aUfW+E<9fP#sk99b z?R^Go<26s?{(*DXy*maj+qE??^#{l5`-k?757)Up{k8R84%7#S9C#Z)V&2#I(BZ?I zM-J{YaN_Qa__m=(8uqQ+p*t|KyH2#0Y6`*Vv%h|LvX-gH|9u}V)vaLMnkJ2U??B!= zJX#x>gurGr_GxHzeC%j{eRy=dzcyAoFfdqm>$XFe7o@eC-q^eUW7}97=VDKnW3cPg zdkt6{G#65Kcil-JwiPY+Gy`SSVP)p z@8a6GbLy{6=DQhwI;4LGr~Qd3J8Q9wcMH7!;>No*WNk8DXJ9F>MRp!3`x142#=ppE z?_x`s@&!(@C2XC$q%2vJWX?Zw8c)6Q^C7D@hvy4WRUO}ya^vf#>g!9n!zQZpefoF7 z8_zt8khdYvg11KX2a&yBG3D`)ow@Rnke%szWbfF|F>pin&ive_?49^IP1%|HIZW9* z?JH#a^>bj2#EHGC#v8@?P3>_sGd+lhYiJ+FYQ zC$V<;F35TkvmU?jtVb;C@k`Q}S;wo;fk-R(*25b!>$wNscv;T|cw=Qf8{v(U_M71Qpa;1tcl|gQ>lYzAr*yDj&SNc8?nD5raJ{XwqmBc;-=InhE zI~^ED6Z>#rWgj02tnA~Xft7uHEU>bVj|W!v@rl67KF$VK_VLNU%04~?=AHRuAD<44 zqltYcu(FS*0xSDC7g*WH=K?GH_lsC&ArA@6i4eKLzeCdXLT^@zdb$qj%{X5h1Oq+7<|3)^Jx{RaadSuDRdoOce zApn(goPumDb=j-`c64uAICGa;;g7v6UK^Obs7t$PVF%odcO{thtIOG41+Txl^qmfG z4vwbp3t4M_*vVnRjzwrSH9g zl{vP6nIkdZ(XT`n_sMwo1ty%>s{$)?Yz@qK{k-v=)%{@3-}zX-@l*F|c<;eE*@t;j z_ZoQb!+F_{`BL{a#n2(q} zJcumrll{LAS-iw{1}2<#uMe!8)2_gB?&f$1%pCkSecyl}?vwG}7+7idrohS^Zw{=? z@fI+1ly+}L7B6$WEimEC`}V*}-+{o&9Pa=#M`G?&4O!eLFh9Pqr+ZfvR$8PM0 s_xT_AD`zxy#(#6$#m>KiiSF#NFR8^*TL{M z*2x#?J#X|7gn_ilhc$s@ugIkp4_oceJ5 zaO%S898QncUz3Y|nqhZQZ*{HH(j1{7e?~K${f_v&X7-@(ixaC049nL-_Hl0cX2d(> z+t!*r+&%f4n#qlRDo%cSqK4)6-Yusm8)rW~k>gmI(dnIm_9I5EGyQXB-je*5=d~uk z-^l!Qp~L% zZCSwI5{Pr>*5A;YeAFgC{uROciQ~7i)i}mG;bZ=cYp-ifEj(YbwxKmT@7Ry;g>MMm YqAxFR=m^Bf+0hH|HjePCmpKvs06z6QVE_OC literal 0 HcmV?d00001 diff --git a/shaders/slang/textoverlay/mesh.vert.spv b/shaders/slang/textoverlay/mesh.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..dce7a3919c6f5088d9f6431720554a13be4296a8 GIT binary patch literal 4608 zcmaKu+i#R*5XQfx#(2rKhEJ;e5`|PBMtpXSytCl6W9r97LZZ zJ}Mp)9}^!JpAh4Dj(CPRqfebAd8X*YS#fY^xYCjRZLumC6J8e!;0P_pA7( z%~fn#(j=v;GhZneM>bYU<$Q0UYg>OQUuhj_?OIvt@67j=%4%Ujt2)Rk3jR<}zLG~$ zL!;!T_Vrz-{IV&=`B1skSJ+x9mee8l@vRXLlzIvjmemK0IrJBMw^yod$TO49W4OB{ zy)K51Y-WMY+hB7SyIC?T#&4}+Hc3LWt3p1R z@wsu{Xt+ZRiR+-6?XbCJH84K;!_sP-mFum*bvY#1NvxkR#BYt_EgY3F^Tn-&nB8cP!YPA3x1zC%9juZ~8qcUZnYvlROaTCuK30rTV6yX<}-3d%ARL z$ELq}F}1HyEarTfnA&+ye3~TZiorL?r&;oH!z5CyR`LolID{WH&J%+}j$J7ojJh4W z$}swHti>>T0wc%OVsga0^9`36zq`P&=y#1_F~_xr#T>1|$PxV($_9tLzD3f(Vvg$! zi+2|r7IR!Lj2wnvk(aY}$(3Sq61z=|ukX|<>FgB0A-+?qrGwLJv*b-; zFv#C~jdXCxXR=m0ION#P(!t`KZZRy*=~lyh?#!t}OpbWB({PFL9P12=e(Md3IdX=@ z92{I? z5A_q@&mNV|J1{5uAdjCtCY|?SUi3pgKieancVTYyMPAO@B}c{NBsMYd_1$}1I(ykI z_C4Dx9eh;md$vz{+_U|%!64s(C!~WzKBp(8gF}uzB^@lz?rFn(cD1sf5fd-^J!`nc zc)aHfi+;}=7UR7jjChXmwg<%Ekk|L3bg&rjCBytK^}Q@6UVPhEWYaTs68ogs-{@88 z^iI9xh-a_KW(L$vF3$Y-<8|r8g(2#q4nKcGIEMuKA4&(K zPRBknEYAO9VZ@7mpU4J>{O+gH!J^-1hQ)ZF3nQLm?8g^kaLD6*DIF}v`^qrCOTS-> zi5K_duxxs!PGZL$_(nFpQ!hE<*|)Np0di(%l9$M#+NRTw_x@H@Xr-)k%} zerKQU-|xb>huXw70 literal 0 HcmV?d00001 diff --git a/shaders/slang/textoverlay/text.frag.spv b/shaders/slang/textoverlay/text.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..c1aa8731ec4954986e5ca05deda6ecce8f2c3f7d GIT binary patch literal 656 zcmZ9J%}c{T5XHxQw6$uhRx2V%s~1lmMG!seNr(saC_$?PnoU{b!T;Qg;QOr!7AH(* z-g$t|cpGc4A}wku8f1W?*r^oQKx4L^hI^dEsyjq`T5p>84`wb)~VsHCggf zefSHv_^40sA9M^Hx$k+on9uxmYP8%-z}v#l)x7c{ryuT`x!QkbRpII^_j&pB z>hrf!fBr`G>Elp}fazfx&>ucp!pzpjkD51`hUtE18|$1ZW+L5Fy^buH zcbEwGWO)Plecj%d#SceJD`4cHc{k$7-w3RQx1|11n0)qte@B)L!Cwe-A2U)9Og=Lr zVB(pHoHJD-uI&TvONiQ+`qMMJq#l@ku1l%+C@*)iFF4|mJJqB=_J$A1uHDI(MP|m zKfl^}w%+(2yhHEpU8PuOPNS&XW}mIgy3O(?uRgX#(-yl|O`1C*dd&Xso4r`#W?Unr z0HY7a0~n8ZBEa|!{IS31t#f`jld3)zXQI3kzpEXbczoh9UMA}HwKI$UgD~7nB@uAy z(DyTZX7j4(f~OvH{>kg{ZfFL~odV`OcS3{zoaav9h297r-Uxa>LU>R3L;Tk5Jl073dY2!QDgd2w8q%@W;S%iO}gD?yTtgUKKKp% zu)dghezSA6ameY+Irq-}H%qm$IqPaCoO9c5U%#v+S8*uwuI?^t?{wdG+mm9@-rL{B zzTm2C-e=J@TutYSkVeS}eNEUCP6-X+jBr*s=g(E|JF9b5fAiYOHKRZLlhOFNXus?0 zD5dW2ms&R)JWrxY(1}^H}ZfE%-P-JRU~DXU_K+kBa2N+lkIS&)O-{I7SE zgMOJW3(lTp4W~YjhMFJtaaU7(T*SYFCc26 zQO`x~+^63i{c_$CSjKO9_U)PRdnJELy!$#+8*v_q(+_VzemMQ`2F9tMH<;$U!8GR$ zj8iW&XAzHl%$%GLR4sniH`*^TdU>p0X3GBr^}y+EPM{t*Gh7g;$M}-Y)MI>EXX=5M zGb`(PugLVwH@zy5hdRpmbszhZIN!!gfjkXWM9wRM>BKj^Ii*v_*HB|iXYMqVh5H)< z_d5bM^88eH^tTzf`J-JG@ZT1&Zwb9n%Qc;`8!XOsY2;}N|#nC(WeF%$gw zX5NIFc64S=yw8uI@xRX^8f$< literal 0 HcmV?d00001 diff --git a/shaders/slang/texture/texture.vert.spv b/shaders/slang/texture/texture.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..b58e6baac960c0206312c60f2e3244c4dce961b5 GIT binary patch literal 4820 zcmaKuS!|VM5QcwRT0js4L?yx6MWPWz(26Jmr6{0MIEbygs2VB5c*9-z2ZK@!)X z#wFf}7siOjH7;?9H|m8kDkhrXazPWDNFoUd7v7loKL44i6HPkJ^qYBSzS+Jxr>(AP znvjeimn6ygNezc+dQz1jPED#a9eJ95pek{1zSxJ{ARZQvh>wYni%*D8il>UFi)V_f z^)p!~accB~t=QMUv%Dae4j6`S1#9n+D6iV=ZUtMPmU{C&6?{r^wuH{Me7RH{+*D3W z`E7;H?w&MXZXRszT$T2;<#(i|fpXWP=7ou()MWnL?aG()l^8Y290~2M8#@2>tIaU% z{iSqAVQaaVs!Q(UOYOaBSAilNV-~xLh23=F7!&JByIPC+0o|<5X0&rlD*2RbPKCa5 zX-_UK_LXz_QogrySD{oc47O>a3$n&*G%02|hTl31ub7jwnUCQ+IyiiJn=yPl)JjKT zE3==Rz2O+X>x$d9mvQDjvpJ0RktA!9@!1>KDIbK+`=T>PboK(ByXeTZ;?u-y6_YoH znkt8Us8I)> z4mdh8EFS1)FF3Ec0=FwshjVevV}F&(UvcrzWsE)yjK;)u~F}1|9agsi9sv z@vwW$M#)}tliBIh?dM5`xPO68?i2Sc>8o`TpPKOJUbi?&hE`xdB#His@Ae-gL-Xa0 z?XVcknLJ0NlZV*oM|Bdz_1{frme~I=o&4y3noj(s(s>KM^TwIZTkv^s9Xp=~*Xt!W zh^c}5M|BR1sR5n*BS9xW`{#D@vwu-%|Dw+Rp^wvV>gG?tVtuZtfxHm*zoaqWW%^A& zQ^fRwPXGK>pcl8#kW4Qt6{|_-xng>06yrm#xngj9c++`ee0Xboc;ESA@Qw0euP!u9 zM~3kh3&h|Me#E{=3=TQAP%;?3Ikw0!dUfn#!{{4~9G8g65$`q|u4DA>rG`bn#fHTk zml+mwED=VI=y$nvaLDVsLNZv)vDC15_e#TJj%C8g;TW@8E(V7@#|p_{F-MDGF~>^7 zh?mo(m{qHo`7L!6Bc?I?3RWV{MYb;+)nS7U#6VFrPbf z%8AJl?`||)$7qi04U2x842wB#Ff8V17ehYkt6!;mJSYijzP&_F~=Um;@!Iqi#hHQMh?f=&3nb*kmtBh zGFZ%UzhN=Q1BMaL_h?8m^JhNPPkgsMD4BO)PV_+@w>>18_h4T1Lq50dmCU;^H~Jzk zHgEPV+J$poQ+_OiegF(Ink4XlHd`^!`28SGbLNZvK z-IIp-?AY4_V&X-=rwrFI8t-YtqTe%y#dyyOBc5Zt?Q>#q$m@GvGFXiFf?wK&Bide;&J3uVT-Y|~Kcz{MUl9`*hNz1=-2STMgT^}k zXMar?@nOjC=k%Y?A?dG+$w3@^`Mx3V8{!#a?7jzYN{)N*mUJ-4_uy^G;E>Ps9m(L3 zWA91^qaMfJGc3;eePP6leji8&hy3n`lEI?iM~20C9}6R%W9-2vVsOageJU9&#{0}L zzsnwcE+$^wgD<4hGj$R>zV(;V>79DX5p7>dX9m@q$lbP@ykq)zJm JTUnNf{{gIpoc{m- literal 0 HcmV?d00001 diff --git a/shaders/slang/texture3d/texture3d.frag.spv b/shaders/slang/texture3d/texture3d.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..74241b5744c825532cb388b92c0fc06f8f2f7e33 GIT binary patch literal 1304 zcmZ9L%TE(g6vnS@DG24QAo8%~C5jdnXiSJ2LI|5;Y7AvbCNRJxowgZ<7+31TttTR*GGU!T=oO2s)OW&+XS8ymJuI%QtA2z-<>euOcedpaa z_Aysv%Y4S=Rnoa2#6i?SeHNpJh%K{5KbGG=?ih^G)n{Iw*M&|)(Rbf{CW$kd{SH*|4a|eA+)lO)~ zPCdXDKCF4&oYamV_oorH(1`z3JNJ1LoBFogqW63a;(qO!{Y}n46Ys6g)JB|Laq44+ zkCp!_WFe`!7cAAN9>lc&p?$KCCnOjaPIgzwt4h z$q#2HQv&%<6pfyEb7;h6Riu;WnZSSTKp=9C)5XL{~LSs<`tfB&zVgd?Q(26LsRt1&PgGk*ihxQ1kwmtRqD-_oX#5F2$ zi8tznF`{veOI+fOdSQ%;(FB(Zo7jY;3IBkYnE3p@GgBwMV4CN=GtbOB^S<*=Pg^y0 z;k2ZBN|GdtlYjJy%uJ>xFsCI|nTuhd=O5YEwuJ;lOaZs8o=>MjhVyS3Kn-t=c^XG!`gS&s_+X?b6+ zRP0Z4`EtImb5Eh17KYo@&F1XlHR=?7JW1R{Gl-?%CyDLQ@j41!oTWZ{my^V9F7Dc$ z63iQAcbhm{l59+>vv-@XdI&aehD~p{K3QnNZaES-MPBai<{IW=k2rU|bhy~38;py6+H9Qnoj$b*)QEex7_VibM!Rt_E@xb;yxLD(6+0<~3nYu-QN4&zk`i zYhI`~Xvyxw`T1_+U3Ut^bP0!y>o$Hz;0n^=nO~pHUDD%h?v@RQ&`0tY1$e}J+anzw zaqb@JaIxRL#>Ia38ArdpM!$4w#Jwfi@QBwKkPa8)?lmsfC>s}R42q*hj7w$1BVJ=j zI$W%=$GEt6uW_-)usCWs$87Es;1REJpLDob<9_2}jR%Y)pU=^Q(&<0_;r!%x-$T-Q z2l~W4sN=qerSl&2i~CT|eIwF&7y8D%sEe;v>mvd+$xV(C!Dny3bY`c9iDwY zXOBvcbM}~QIK*e*ap~}g_vs1g@Q8CyN{5TRd&)TP9drA%K)x9FjPY6~@;z%@j5}mp z%=er)@;S%bJ}%w(a-R_Vjb4$?-8nBcqVHAN z^ni0y3!i^~ye6Hz0O4Gm!~L&ICpSPQ``-{pet@_?r~iBo%YIX!26>2O4(hbNCCn1= z`y9M2J9vf&V)gLkFFBi_^Zq{Ac5y)PXu_W1+jVxK=0N4^;Mk!*Ox^L;EGF2;Rg zT+H{WIPy8i9DF9gBcAVb>2NXM7smNs=HN?#d~puGlFgktC%NNWe=VE4b6#ph-#4=9 z0q3R`K7Z$LrIQyRoQrd~|2ygA2FPUp_u|M85cm5W{2-1RXXytF zS|)NGu-W-V9Q%mlf2*Tfe--8l2LTJG&c4*KJE0X11`g{@AHS2Gh4VVAcccSfUuoGneKh`tp&yD<7(sTw5ONJ5r>t zsgHb`?|zEq^NW^ZTA}ybWxLOffAHSzOFof~S;@bvt{3z-dExi#uQV^#&b#bw>)l5t z@~N5wJ@)?3KWbw3zC>IGX6Ct^*=l^HH3sH9b^WNihj}kRSQ#CXBMD;C2FgG<5 z?kJ)SKh^F%Me=aWNW|)RQQZ}F^q+*Rh5JK)AWT1ZPyS4iz2NVJ*^e`#2d1AhVqoey u6FoOlqK-K*xL+Z(SNbzE?}r|kH$0Z3_o^&=@;-3XVfRu&AO0ZqTlpUw6DL^! literal 0 HcmV?d00001 diff --git a/shaders/slang/texturearray/instancing.vert.spv b/shaders/slang/texturearray/instancing.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..1488037336bce55d8a69ba6cf72c69b45b377214 GIT binary patch literal 3556 zcmZ9N`*RdU5XXlkmr#HpA`c%GFMv)2t%PO5LZzuhz6p6*`g?%LTGde(#xc89<9%i0{e!pY5@9nZ$l zUE=7Q!iG}s((gjjY+(#a?nxd<9+T*3*e=;B>DJ$R?VPRX4}Y_DX{i{hWs8Op-@#_i zNLAE^@SOJgR8r*4_UR(alZ$En!hDt#!|mbv(QJMynalFUqOo`Q^$>b>f_PRVDH8UI z&|TUmTZ=`~noa8#Oe{ESA#0@b+IuaQ9FsgxRwi4Gw9OrB!}G%GV}N!;-ESNzdGWIz z@m4~=?3wXXPFda$#=4YebLni+%v3pY0f%?FnO??EE@0HRX}N<}R7dK(bUu^5uB>(1 zD)N{lX?6Kl_4oa^);_q^Dq2npM0_Rn@tWoWKV17t-PK4iMuTcVf6^{e@UY+#9-eyoA(}+O|SU3 zYK__ShVR5}dck)R+k7W(^Zr2zZ{R-om@hc7;bXqA52%KmBbEjBk1TROq+fDkF3AU* z`Pd{OA8h7fi-dgK-X@)VuIg_5J0xJlUC|k4=V=M}m}2P1%Mx;?Phj-mRS7t~0izGE zNx(S|MlbeCz?naCpx$ptz-x-(4f`bI4bHj!+7C$J^mFv@O~a=ZQx=c#ISC~V4kU#gk?`!GwfjaRHc-%KHoqkX+-UFZe7NpY` z>c+d^#m7vwBye&!cM$uhW&>X)!Oz_JoaNF7CGngs$_D5CRqcfYj0MIFEJ?swUZ-X0 z;4H^3O9zW<*ETG!-HKt}3pl=!z!9JQ)^KePIj$HM$9-p5%<;WpF~<+W;E3Z^WrMT) z9Y0D3i#e_u7N5OlSj_R0FgP4z&VH7Fvz+6)bg-D?hG8+sO~bg)XW|#>)SvpSO1R&B zze=YM)QNY%m&|;$xQnkif~^+(9h=N7A=jlJ%0?k~@ao eF`OB6>~5)d?mDdM+>;H4{y_Ua$-k<`h~z&q-t~Y0 literal 0 HcmV?d00001 diff --git a/shaders/slang/texturecubemap/reflect.frag.spv b/shaders/slang/texturecubemap/reflect.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..203a318c0a668d66c94f547fbca25f72c5682137 GIT binary patch literal 2704 zcmZ9M+jCP@6vnqrlL|x-E6B~7QZFc2K?9-)P3vfxF`+Qw;qQBU@eii@mP(j3)6QLfarB4aNBpboMBCH9!!ZG2v@VxLsl$97eBfX*zesWcn z3q2d{9TbcA^6@Yk$c#MuCwx2auVl%-@tir~H?s7njda_1@>qPf`$G{ORn>V`e6N!f z!+50#jbdpE;SZ!Wws>_-(6VK`=MS`sAb4K#P%3ANgxLV}! z?~U_E>2{IjngaWYrMF?;Pidy64;-_~Mn86pej3YE2i9R#vtf=0Te(iE#d+>0!@WT| zR;l?|F7eZ$D>>o&(cX}q47aj$RLHJ|P5gW5_Q4>rJxAlc$UpwMn`fhBYV%2T|N#e+N4^j)x&wCh|uyjRzFsm;GIETmeV%*`f+v&t!;@lnS)IjaGWHWo- zFLhuud)}|x_<5IQoA>KB_s;vFC-ze}?}LR+KHdj8Z)gJS^Zw!fk;M#e>zkgA2-Jhk zyy^n=xc`K7>T&y|bn29fM+@PhIBY);@l}s}BU`&wQw#^WFEMbnbyU(Fb|lcS}0=!Mx~)eD3>5 zI`_id=!?Ag_+Pjqkdw1HgV?U!+mdwNTub=FxMk_^>{|=Z#&@|Q9UidgyWHoevWbEF zP3JH--Y`7>JNNDPFfiU@dB<&W9brv)Xfx^>M?7cNBPRbd_oe%9ir?EW_FG+-j?aHf zUsxP<;N!RC{XCFP4#4t$sJ$k8L*W06xIe9*ucUK^=b*>01#015@VA7n_4F}F^ WzlXkb_*A%~U%{><+!IacrtmNAdAkPy literal 0 HcmV?d00001 diff --git a/shaders/slang/texturecubemap/reflect.vert.spv b/shaders/slang/texturecubemap/reflect.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..e915ac45731a8d01f014bb03cf032aeacec47c2e GIT binary patch literal 4148 zcmaKu+iz7>5XLucElr9bQErO07cVGSK`WvNlvXWj3kQ)R4_bEHLpk-dyPlqw;)4{3 zmw1Ujs1L?S4GH?9s1H6!BBY5;Nca=*|M11c@3%WsCO&kU@2r_`&6=4tYtDh%nzofm z-HIehwj_V+6Iq+oBrvO!+T2E8BMYe!#?sO_`X=G3a7~yO7K9tZP2o;qjZmwL@EyGrS#PS@uBm>SHaH|9Mlj#n#Z3R!8qT1YGD*uZqL zQZ3H(seA3mvPyZF4&Y1gmhoL`3cmDs8Q)$jCy&cpEaTf>DxU5y4$-H^{LPl}?JbR* zs^Uyf>BsH6BuP(Fm%nS1cm$ib$EKgy>$TPkcL@g+!{4e+HqxX1d9T?=M||Ho;=y$a z&QTBCY~X5*yRMb|%xa5(xZS#F<~DQ8oFeQq)A2s@X8V132lmO0KfT5#FE-x+>^k9Y zd2y~qyX>Q{mqtIDg$?prsTCW4>;|*(ZICgL0ul4N!t{uiZD zKX-EfOJ)=QvUKusj(yf&1jOxMb8GIp+rKT^o!jJ1>?;Ci@MDj-e`qBqwPOEiHvZUu znN7akvgtLyQ{2OC=Gkrf!aPwc`^0B{$bn6K<|o?o!6x5Au<>VpqCfM4y+WVVbxYW( z?*%oG7h(S&S@eI8KDiGwOzm#-t4;0ub(Z(LPoQ>Y1s~pWvjBfsKFq}Z#%akp`o=87 zBluC%0|GqaT(fjI>U6HfIO=w;)i~||M~*gu9P#Xf#%ozR`;c+b?_uL&jz^4(Ikt!+ zNA!DCHaz0>JtiG4=GbanJiE=fnB#GAL`%FD29iF=~Q@aH?#NYdQ>F|j6WRG-s#JRoF;bNcm85jH1X`J_+KJ6FC5zlrR zuVpDmw{g+$1><6l7mbTKUJ^%+=+`3~9`Sn|kPa7fylh-N`-*Wf$E)JV;at7+UI8BQ z9DUN^Vvd8x#TBc8v1K|1~K5~!c}zIRwU@6au95AyilYtnfS`o(?7=X*z_cM9~4 zdy$ttX6p4^r}iWv2EK>%E7qX(sL*K8lHZ5=3-(*lFC8ELefh$;H>AT8*SX`;;hA5b z%{QgT*?dbj96}$Nn*jkH@!p=04v#pON{5U69yE@6-EYV^e?M{z3*?Ari^gkNI(yQ% z=r>|q%yG)Nn4=_)9MNx7Haz0>y)7Ls<|rE%&yE=vbBv24hjYwkCcq<}V?sJy%<+zK zF-OHX;`tm+N4O6O;y&c_y=mz~0)69NTu_Wzz%dCKr4DHs44mEBI)e z|M$NWM|^-WNHVNT%R&&yhW5H<;y1ZIOC{wTnEJwHij zo&e(cE?C^3#a$8bJF6Jv`dz?(uey0v>v7Ys1%6&SHQ}?MmAvRTv~nK(rdHzrtE{_( F{{UqpQVswB literal 0 HcmV?d00001 diff --git a/shaders/slang/texturecubemap/skybox.frag.spv b/shaders/slang/texturecubemap/skybox.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..71e6a0358cfe1813db7fd20541dd710b7d722d37 GIT binary patch literal 596 zcmZ9Jy-Nc@5XHy)N{pIBBZ>%;Xk%q5g2cwcDv(A~%8I8Pc;|6m3jcE(!S~zTHqJ3O z`{v`#>}(ue^eovjvr9YFAKACa@C+^XnDfZ`mdHlZ(iIhfp>!hMmX4K6tS622?Z{G> z>LXrM^}4-!d|G*5=4-!PS%2is{rV+exSHHVJZ2mJtMI_{=T+N$FF%W_UAo4V&u@); zFXdcxbEKB}-v9j%;-mMO6ah2yOv-ElpX-c(xlhQSbbFZj8*OTibWW8sl^!cUlLfP> zsc>HwZu}?eK9CJ@_7j900qA`eOV?{w-fj zJl~xv=?9zCbk(WlbXWCEXlm?f3(XB7gahHbK3SVWV*qInO@)oVA*?R+Mt#mF)fz^x zWJ&TxvQg5czqQ(lZwbv|z4njQ%BP7W|Bu~LLnoE;>U~!;)C7qi{X4C9_K67H=cnGbkN<3>O$rJV#{dH@f8l5b!#I+U}{)H@^ ztxV_DR5u`>Sk612&Q#{Kx9ASs>%+@b`kLZym0F%HmC|Z0FC|$rU;bFh^2*|by3jv$ z|3RITzO3LOjOqULq*KDe?$O>V0UuX&KRY;UOx&D@TKLgf?stsyf{jS1%XvN4ZLf{Z zjF<}xn|b-Uw%Dw@i|N&Su}wPX?2>F(e4BRcX0unB-K2eoP-+u{ze}I%%m&BapuIst z-d5S03cQXTHhZ(hz_(30eDnc7`c6p*%fG0%OPZg_^E(QEJ)ZjeB%G&1pY)1&uuk2L z-hg$=*R35Jq4s|5@PcFaneG0ovZ;kQ_qcR=;b*-ro#p;X>C|+8hBGV=Q-4t!xzxk{ zY&N|bluhq=FAZjMzFrCS@RQGcsew&C^Tj@+H$)z>EU@3Q=nJvTiSH=fL$cv)m%ukE zlsRlS44g&1AF7LQhXg;fxh;%2?UsPE?g*jgR|&Y+@Yp@Vh^3~-ev=MP4)|r&?bCih z!o7JXoRxVTlz>yONBbeev=vx=Ms?gV&Ui#}7(mOB|c zk#kc5?m5_T&Mn#G@SET{CF$UvgY7we((g)oC7jLQ{yoE)Nssg?2^h=Y<$dYkET7#2 z>EJBK9!dv`=lRI6c%F|9W1i0OL^>RC?o-*|Ea!M89W0J}ZdlAwHZ10NAq literal 0 HcmV?d00001 diff --git a/shaders/slang/texturecubemaparray/reflect.frag.spv b/shaders/slang/texturecubemaparray/reflect.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..84d4c6b81fcb28eb236cef3998f76316e950d964 GIT binary patch literal 3056 zcmZ9N+jmn{5XQGnlL}NWauKA|lzKtIC>jt&Xj;JPvax~Mf)_|nlhbl)k`qr(YP(!& zeel)gga3~{_(%D|T718gJ$RP8>&u?`X7uq!ZSK1bZ78<#vLbc3h||BCQX*bxp1F9=73W5Q9b#dks| z=np%&ipqr?_4>oKaz9Qw?M6Hp@vI;5U&Ki_=t#}{i8v5VH zimLOB_+~vwlW2D(jgw$2Y;JbqAg%6Jo44XlJ=l&DZS!(fyDTXK{)~2z2FykMoz}d% zu-yF5uat4v`$@bVw$dn87g&!kd+WySkfKZagJb_uZ>R3*XTEf`6So(lU?6TH^QE_~ z;YL^w`k(dM;jUCgE@V9(Zp4x&vR)5@Zod;Iw??k>NfPYIHtrtDe`ITCdMG{UZbV@( zm0ol)_I}tJc7jBrn1k85$)4;r;;5H4f+XlRH`T7L$htpc&WnBgpI=l?&T*Px8t9xK zI=w*W+|XH%&UvA;fAp6%mxQCjr>e-#VOBb0QJ&UE?8pqW8%I94nqV9`;r4S}!E=A- zIQov?KLRyzr)LC)>E}mkrgPu1+aA&LcHV;Zwir}RrtSpzq%sPq(W+TSyD193<3#D`VW;C3TnnZVGS)^UFSNZhzkNG+VbnN8F)g zYGCizrE^~PZ8M#BKwYNu4)Qwhz;x~kcaA;bPu<)p20Hn;Q{=4Zm%8_atLg?ZSjWKr zuQbl%hJNuoAW)m>lai^;^uv;=&2-)&wJp2nv-K}ZCI(@WyQ^s)yuL9Bjqts^EAU3n3A~Xh&G!WOSUTsq;yLTVm(qy`Pn**mjz6*9XZOP;Y4D0`Is+w4#uqoj8r#SZVSRlr_Kn}P_AP090drfHgv)Pu6-C%LP z6Gv_A!{T%#TO91QoUQ9^e5>&53EUIvj0Nh%$7=6OCO5VJ>ixc#%$~3rmq>;uhMns` TGJGoB)QjHH4EIDGx+XjYi!Ip` literal 0 HcmV?d00001 diff --git a/shaders/slang/texturecubemaparray/reflect.vert.spv b/shaders/slang/texturecubemaparray/reflect.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..807b6cf91ab8545177092969f2b234cd869dccf7 GIT binary patch literal 4024 zcmaKu-&2)k5XWDHfEf&P${&>xNIxvivdAn`5h}Dqj+vMjg)f{V9y*+t4hO_85_S49 zR#O+%Mbji*l+{faF_SaSFf!A<{W;w<)A#eTi#uJo%=bLI-)EoQefHS{G_L7xNtzmx zB-xhytxsfqvL=CPPa1O@eO+>QuCLMOWLmCb+%GH&*M%FxlCUh`xlU-*Pn%ZG-=!b; za&>B^zO#@`=Uj8{x56FGYLjV2v^>`)8?=rLruABR?sz?`rQ@ZMGnFi@_ssQ-^k?^0!;#zXwCUIjkqou)g>TtDKnvjd`DDMllK`%9=Q3yH5zv_aJ&V6e+ksYtab^A+gn%6++LKd#%<60e*vQdf6$!Z8v+pbj0mV z(uuc4pS%G%;5w9>H-PJ~S;cnvTakCOc<#iTU_W3szMEz5)=FIRc-}qIy)I&%6q02A z0RC5{aR=^&Kl{H3h}*yB*1}DI^A9v0vc=Q^dsQKxfV z#!heVvg;` z#j`t%i#eVWM-J!c)lLB(@f=S}hl@G%Cn)D)j$OtPub@uRt7irJPk*SN_`dg?^iF|3 zaS!tNUXS!Hfqrox^7-EL(zgoqjeC)oJ-(+e2;?L-G4S=7dQmzv#dp_d>Luy$+?AQy zE5ITC-Y-jsN4zKdq{Ac5?UxQ0`*gs#*r#6Oyzlhspg@jzw$FGit2z3Oi+-;d7jwL7 zT+H#BIC4b40om|~-{X*UxR~Rxaq;Zy#>E_Oh$Dw{&C-tu@QCLalnxhj95pWH7&4A{ z{{98&^uJG_e&YMyG3mTRzra1n<9lyP=RN2b_aUF}9hcrK&^PWyUiO%&w{o4@lY|)f z4(Yd8tJV`jn?Xx{AL=jI?}}mR`0)4PE92gl4o_U?PDzJnetkCIksfFBUD0<(Y<6h)tkJ&sYkdxTNz}IJQPCBz0XYagh zc+U9@e;^$mAl#dK`W${JJDIwV@Bo$c*Og7QTjZD#JNk-=Y`nY%f@+ciT9B} zyy*9_@mf~nePUen`_#A??}|9$Img?7Ccq|Gji#1LXhvKZqkfKzzTT|BSB6 zUJ%GZ9DMnG)T;GIpV^y`7Y WA)S2qENSHo`m$DH{;N!Tg#Q3ye>^|{ literal 0 HcmV?d00001 diff --git a/shaders/slang/texturecubemaparray/skybox.frag.spv b/shaders/slang/texturecubemaparray/skybox.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..b03c534bef141c6a61d1be5a91bf4780bce836aa GIT binary patch literal 1280 zcmZ9LOK;Oa6orR44+^CZN?S@xa48EUBm`1~kPwKri^3uz5-PB>rnQS)C7#G}P`cx% zvEWCsLE?N94@69KeCM9~@SWpH)Hvvv<~3u?WAjK)*1BmJm=zOwpZ%&?GELcrFtT|; zU|o1190*Ion(~Qvgh;=evedTpBc2!IY4!B<(`U~u`*_l~RhiE|R<5*Pv*cpvY}K3f zl4CdQ+e=qYs`Pp9nK5nkpdTx>mBrHchV1FlhvZ*g+jGRnrMt||tK4Z?>d9rEkxR3o zY+FA#X3mRm{hI!p%jt(MJ<9DwT*v34!TIzo>)Y}BBF$!U)j9H7OwXM59k0p6j>f~R zJf5c>mZiN?tZ8E9&ts{d2<@_>Dz64EFRFnp?I^jB6eE%STIZJD&W!)_C+df;U4eza zEZY{=gm-#F(2V!6PBd#cGjaB;5Dy$W!Mzm%#|&`a7r3bAek^ckMBYz}C%&gAno(+MyKY+gTeog-k&o`4j z^ksKt!#Sv9K31^1s@#)L9{qzxaQJ9QZ)SfbA04d0lm{gQ`9uk}P*{`d4hR4!-T5a^F?1p2_!2TgVa`k)nk ksJkb?<8$8o0<(WnHGN_Mj(*Hc{u@ord1B$WPV-Xu1GZ;hng9R* literal 0 HcmV?d00001 diff --git a/shaders/slang/texturecubemaparray/skybox.vert.spv b/shaders/slang/texturecubemaparray/skybox.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..e5c3dd2be931645729dd0f1a6491d46961bc268a GIT binary patch literal 2828 zcmZve*;8Ca6o(szC1wGmWws(1L?IeOHnMMoltM~JMk9$!lF5a+NiG@YlFJ35%2e@W z#TU!}$UOK*`C^s7@6I_%KiJfnKIiMRbf4~-qSiY;82Wlb2*<5YL$&X z9Nww)UVW}6SqEc6vMqTjc~?@?-yY5Q_lLf)PxEG${!&lM|FQe4n5?t5QBF1T^(tm> z_(*e80Y$cTx6F&=Y1(|!&XaO_Yr1(mZ`YHRyjU+=XQoewFrcjXGg?WRF!$?kO!MOG zLi4TPK*d;JEAo|exy*8%fOve_?`qyk+nNXT2jiSsXR~hjjV~Q(=dIZ+Sr;3ueEYKGNG!l4@X&YaWom=at=i0B6jpwx5A@bcU}xxSVe?LS8w_mTjGyU!dv9aa3+mp-0qLCanB<`R2Q_0;7kii4?Cp?ja^u7L zF@5ee8;(7!xkp0W2eS89yvt6Q{hs-d|A2Jr(GS+q4@*MW`HOr=q}ljlf1#PYi0@-wI(_kd-;vJn z^#$qV^!0+puyd1qJYHhShyAPB^zEu_`pCQMF`NBONXW-J@!T~zu!-lcu`lQ?5{EAX z_Kz%jgfDl-Zw9rm%cka#gnA32+{r;>a0dDQP+ry!Nm%Eez7?a7M)aB0D^|D2sNMlWI1I4z-e9DByNrZ=%?jm3WFjKwvkjm0(2i%}!?yC56R@cmts z4vTACG8V^PHWt^oB1R2o^y;bv&hQ%7q{HGG*Nw$BZWtq9L!F{mHzo9+{;+@Y``V0j z?twmW4(j;YE$Q3`{o*{-^R-#&+zWl!J?1Ov#PB9z#C$D*dkl6Q^Nnm`_)YMbhIF{cV0+A@^t+M?348Om z|GjbUWL)~91jg`pc~3f=;dggmI-KF`2kEf*K7TY8-{()pxKFR~vvg|2u@7X!8D8U| zbXe^7$XHyXX)LbsSd1F6Um_dM@ES|fA4}pI%f{l^ma(`-Dn<=wy!|H!_d&ln5A}R)RXX=V-#8a_S>x?@ zB-A7~Iq>EEu$D`@?{HW38@(ob$V5|hKF-sy-?$gj@hK#K8smRRIJuma(&5zRJF~4B PhW=9XE6Kmgeo68l{#3ZE literal 0 HcmV?d00001 diff --git a/shaders/slang/texturemipmapgen/texture.frag.spv b/shaders/slang/texturemipmapgen/texture.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..14c85ad7d61778c4854a908668871d03ae2cffea GIT binary patch literal 2384 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/texturesparseresidency/sparseresidency.vert.spv b/shaders/slang/texturesparseresidency/sparseresidency.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..784b20ddaabf35f599d13f828efbccdd9f484174 GIT binary patch literal 2556 zcmaKtSyNL%5QT??#S#ROaw$a&q^v?w1Vu!VT?G{+h`4LGkYI)FQsIL5#!ukq`eK#m zyP3v$a;Q#spXuq--7^W^9e&+8KTBM3r5f8|uSzb>nv8v}h zvDCN|m&)7HhSB3;rTmj>4Pz49acQ~|?dxPV?fqaamVGwuzr34Ne-+}&Zc>P<(N6KO zTusVH3z}4a+F*kwLht{HoA>FJvq3kY8cuUKH|y%tId%zW;WI;gV(~kr8ztu@bIM`! z$;)TWs&0BFo_%bV?Hk5Sz$PVzaR%%-z_K1Yk%pi5&@Ew^-&1o_pSMzbMYVn2P1q0f z!H2&?RieAo*HptU$)>-Y8Icai&<1;6G&Rvv$A;oK0 zpZ7a_jQQ8)!`G=#=1mP?U1DM0U|nKmw)lwE38&o``<62&+iL8VP5snu`!{8?INvMH zK6$Ume4M zlb?GfCqDVPSM$lwz2Xn+&5?(*EU@45sC`VI+)IlDetc?dlfXZvv)$4?68LixVyHVW z0Vjs}+>#K(+=yXTwJSLT5%;$~-oJAbD?@GW~hV{z^qZh;Od5qo+8}Jx? zg26E;fg?P7-{VrJXCHVhj2rS;$nnr)A;+*VIKsF`^1)eF--v9mkmIq(!n0327IKUV zgTpXp^;81RGLA9XU?Io2$3l(?kCCsSNinNQ3G-(@)K7lfo082vFemze$M&XWb05r$ ze&Dmc8QI(mbE7YK+2eckTrw#kH#vy4H}yg`Z;IaodsDNr!ReJZH75aM*?qs14bHNe zypj#hGVHZ%uy9WE9?JxA3m&t%Gp9EaIKs1w9+x`hD0nQ4Tk=@Q@z!G@$FeXu!nk+x z!CBVFifpiugMaW~;n@!!3pqXtgTpZ1)F%lz%Q!yE1`9d9cr4`j>M`=!{eP3q{Fx8+ zli&8f%jO=K6MevAdqvsY2lJvI_-t=gHuu8Z=nG!)m(_}_|k*~IXBe&VsRY;f`#wjmpw_dBlXZApV+$I@-y-j~ix{)lNr@)v{Lsqz2- literal 0 HcmV?d00001 diff --git a/shaders/slang/triangle/triangle.frag.spv b/shaders/slang/triangle/triangle.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..81761f272281554e48e0a89c3020f6ed5432774d GIT binary patch literal 436 zcmZ9IO-sW-6h)tjX=~ML5$aAVZUn)l6pFfV;Y!FqkStmWm_$NcxbtVb5j-cho6hj& zy?fus+?h1F8pi%!L|n&|(>0AGWG0dJ*!UzU!zWl(l(mToc7UByCqKke_95P$jBUQG zKR&zLr{=wBVa9#ms_xpayeaE0FWRDdUAM(s1^Kd>oyDM^xywJJ!kHJCORSD9KHF%& z?3MiMm=R~x%&~Lo2Y9isn}bJq^~#$c<^-`9`FDF literal 0 HcmV?d00001 diff --git a/shaders/slang/triangle/triangle.vert.spv b/shaders/slang/triangle/triangle.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..b3fefe85a3e9e83ae9e9dffefba478502edfac03 GIT binary patch literal 2956 zcmZ9NYg1fB5Qa|zA(TWSWksV#gy1C_MWYy_n1qW;ydWE6yz6FxOP^sy*u6S^vpZmGYbR9r%o1w$BLr3Q2fcaHdY)jWJZgDI@Uj3JW~6| z`QB=Ex(3gJ2jCDq3QmIoJ|m2-Il)K1)7{>!rW@r>;>_!Fi{)n7BkNT06kKz;RrNXt zx2m$&y4P;r-7H(x%)v~PtmW25+1shsFU`DB6ho{qUt4cgEl0J^GTvTTY5tctTyxHE z_sWg-TGc7LeG$1KKCbbsTjhEi74?sJYu)R#_hZEgYP06u)e^Oly6$$j>fLXYoo>}= z^;%oay>_o^A1u?M>3(tKd$xM7qq(A3DhBJ`j5Dtp+ZSWcWBfGZ5O@sSV2`MIidb9X zJf7dZo!8f5J~;Q2n*+hQM(!a{%ep3k7V-IhSjXP8_o_L6$QWmTJiV96`u6+he*)jL zPk<-MKgno3nBw6S4=_%^o?`Tz@@I&xc>>5?O!3(N;xoir%s+$g{^$6%cWTOwa~69i zH=g=r98mupu|2Ve#@1$R&ROF37~RkPL+^cjbBwKR9~8yI>#qMD&)QsL{6~tdZnFH@82%+=)nCi1LT`Bu}rQ!nCCeD&s8Ypu@# z_3WuR);$5_Z<1s0Ccy;IK3Ru4F?R*u`>b*=XMwfd&6134}3dk$Y-i=NEm&q-jx zE#S|AyibdX%lq^};-c^N=|iAKzV@TUGaP9wB`(jqk+@vrcrev_=~`PS&w=#_cgxvV&AMwUFUpL-vBk;+da&UH}x&PZ)yz0oB9r4-dcTA z-vc>K&inoW$ZOG)AMxe2;C{lF%lp(!T;8WUiHp9g(E@7ZYgZG`aHO%8xIAw?ak)l2 zak<7_I5qOTd&Kfu)bTUET&~ecT)uWAak<7XaB2iMgue;owb0nYm&-M}iOV(0#JOMG z|2Dq;Uj?4u{bTM|eD7fmScf_>*TeTd?3eYZ7jrxKcYuAfE_I#rO;tcm_jV6+SNP93 z%(x3i5*X@wJbxp-ojrVW_Q79?JHVHB-{9`!%lm$V`wd@y7F?sF4;bb24;e?nKPX-S F{{mM7zexZ9 literal 0 HcmV?d00001 diff --git a/shaders/slang/variablerateshading/scene.frag.spv b/shaders/slang/variablerateshading/scene.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..8d3b3031934ee8718cb41f831bc8530757f0d91c GIT binary patch literal 4148 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 F@E=;c)-(VB literal 0 HcmV?d00001 diff --git a/shaders/slang/vertexattributes/scene.vert.spv b/shaders/slang/vertexattributes/scene.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..4ed62fbba21ca4150844562a3df316d2dbfa1376 GIT binary patch literal 5484 zcma)=S!|VM5QcxcoEBQyx5Ngk1*D<~QjtX#K`1DNB2ahBfgZ{sZ4aIvptx3XMWSe; z7kc51S1vIzCdR}oZ(I^%VoZ#8T!_YfS6oov=RY&2qZf@srr*pv^UwRueBXcCLv>Y4 zT~ae9Ns@WVau&&?q$2zte{xxV-D5=#y;`xCC2TKb&3xg?^N%PCtmO`;V+b1~9rA8Uw*;U3eY0WaWBRkNW z8z`l@jmaFX-5uFdF+a4uR48V9bKQIU3fWTIP+Rx9LSILAf1x;7>RHsbFiA41PCn9; zEoE8R+ia~n*KX||$;+e|@dL%e{@k8YzMv`aJh}9AD4#n_JfnYL%&ITnyRTGkuae7D z$px;}Oqk=r-38f=$tKzVWAAN?ZSUkGBYUq;Hp*W=P%0kjEaV4Do!Mfxe~?Cah`kX< z`U^cdO@pzCyDmLTP4QpPm17O*`Ti%?eJEEf<%T+R8x~X!t2P;z-h)wc(*vy4P2jGK zlGmjXb>;T3w}$jijgq^WF_TO#cW;#3%4Ol4Iirz2lB7MUN$=$>8kgX6hw(XMeC{GX z&*F2p@i|xgxmq()p4%u6zh5o#k#=SJ{UDBwc-%4gz}83|gA;5xVAY15&0Bw| z{&{6Lt>bsb`PdJ4g4*!-{TPYYr0+QIE<#P-_c$Zo{Wv4eHqMC8gg7J42){-;Ma*)w zXFegybDl1X88%C2D638@KKc0d=97;<)_i(smVcI3YLbUP*?jWwr-=LLT zIH<|Fm1~yI3!mq%(n?>Po9}J2Y=n4+R^sFn&uBd+O_Jf&@SKvxoR}r~bz{o=g4^qj z7v}L9W_urJoA0we$9yp(J#MuygvKk zcM$s{&VIO`?z5lf;1lP5dK{no=|1(ipZH_+lX)$ZzeMkbmUJIl()ek4oX<-Ar2j@K zy}Ca^HofArUw(_yD?am^Dy7#eRGagkFQr%R9y#2F3#H)Ol*9R7WSEu|qs{^;I6@wK zzE}#5IJQtW7=1Xl$S~&X*d>NB128xiOW}ymwi&La^6aIC#k?hkMUKl1iyTXZ!4dP8 z$p=S#f6HZqMUEAQ#b+-!EOM+A28UzJYLyfmagNop!6L^R!y?BOhEcCmlVVnDrOcoC zuz%`%Y@KY*fjQ9!JRZAJHs`^-=x2@8W9wyeF3gR-;3c*}Yr7OqYEy$;?o@}?EmGbW zJ`=c8o3w6~g3~K^s?#tnDMk<5q~M6p$M(tQT$meu z!Ap!gm6yUvZEBGFgzgKm{ZiuXQvdAglg($B-?KTg`=#K1&jt+Bl49I}f)pI_IUSG< zjyQI!Y_K@HqG54%gN89Xo`s_%g(E(D&~PmkjzfmUyu*e?jv>P$#}Q$0#Jt<&gCpL@ z?Xtll#~p^nXYVvDa@-{h4#zUG@0Nli&M_<-EOOjqSme0ZFzWf8I4Ya@GavR(eUIHI zn{!}J^f4^;*!{9O59UQb@OkV3*_;b=qc3=gahD#H!bxpvkh@jCP5FKLkhIZMOWF_n z@3eD$ST;HQJ#)gaM`VL@M;$vZ8yqhG4184f7AZ5EtMxG{7~=QlglurcXZyHpaK!VT zlucfo_fzu05zl*CHhJ+3o{fDFUXF) zz9=6Ian6@ygCk%WtuIT#y)WLSSES@QM&7H2J4W7XQu1Q2uNxlo-mtvb>zl&hrY_IK zUf+^W97U)Fhxhun?AYr&^1%@A^t#1{bX3=_}Q??@ry7xV&1Rv!4c;;EgLLy{AO5u_IJY~#~;GraEyNcl!7D9 zaYi;+zWP5*mPacWb8T>o6HmCd~(hra{(?pQBv71ku>o^kKT8t$K0l9 zQN-g%?S3~3payx)J5e^gd{=eeNwUGc?qu0uD8d4-*PSAO9O|ypDe}GYxZ>D+r{ulD dZk9dC>=xNP2hR6M_J+-O$f?RXBbKGoe*lv$(@p>Y literal 0 HcmV?d00001 diff --git a/shaders/slang/viewportarray/multiview.geom.spv b/shaders/slang/viewportarray/multiview.geom.spv new file mode 100644 index 0000000000000000000000000000000000000000..b980b0f628b800101942c4b0f6a3fe9959dcc118 GIT binary patch literal 5644 zcmZXXd63*y5yxkDvbzK@As7OQBurQhK>`A<7zH9Bm%aDv=Q@fcsOdzDR zKoFHG3Q;*!JOYXbDu}m&%Au%K!5{wN0iNJ}U*%Or%FpLF-Mi2Ds809y+x@!x^?Sb| zsrL^L)n@e7YPF@cV^yp|2AKK7*b`H6 zL)E>vcXl^)JFVvA|IBT$dJogSoZV3MMyB~uni*|vuIdg|Z)e)~GP|mr-lTnQZM7#` z-Ogoe<4vxirvZ51$5KSRDDXjn8))B>OaC*`#vd4X3EDj_{oc3Od5L|??%yx)>cB&R zN73f9-b?5v?|K;QGRG^?#+-&2llM6tQ?KsMGwSzlUFlEGp5(4Tl5VLiWpaUFR&ERcTuqI)x)hh^>t zawzf6RXii`%)rJkViwNL76cf$@;_CF8BM!>^1j43)}tj?msH9F}a_giYg}Ya8nCY-eX(-=aOqEn*tJMLB)GL9u!D`3B{jvF}Z+xZj$uMq6K>_?*DTh|djd z4)OVct#KH5H`-kGCcYBwdA%d!uSR<(-mmx}wDq$7Q`p8P?(gg2-re&C0-N(>_IpPS z1iHe`e91oe=mI;_Rr}!81@`=YOZH@b``L@wlep?9dPwZIlYaa2+bOZ%PKo_?O6<2I z?&D8qvkZI^_k*hXKvn*Kft;&#ecMk%j2HX1{ePTzC3_d6k3<^CFd}ypdMV<3O77WU zXC!wjxt#qmi2KFPdKu#0#K&U0Z#_3Th&~Q+k8%34hv#575Z`(Ba00eHl-!A6dyvZ> zo{R1NtT}@1-o($tc3<{z61IDc)0aIwAG?A04P*~5z_y2ydm-2!+HP~|I z^6tIAfAdD>qJ1mse~@cFdLiP{e+XK?T0AeXT6}0=b=E!;+ZuOsnzPU^MdbXg`zQ4m zpk4o=o<8wmh;`KFwGXjA@8KNuYmiMyz6F0@&I>-@sJ}5|!8;Rs+K9dYk$*Y4M$t{= z0>mZfJH8N+cggvEY)0f=$!)=w>npfcaQ(rVZ!2QHGVY?_QB(QGgDc~<1y|;qfHPlm z_BV;hyRyIS*m7mQc5u1Z{$7Weua2zev~rgqp4mRl?e9zaE(Lpb`?W^t+XZ$8_H8YF z>&Q40`wfVB6__$F-Mq3`Ev^qUdC zBY9&6(QiTIot?eDH8^WrAKW#;TPNeLjkt22*9C`~dUtQbF5lhtU^$n$ocY@kc~{=y zJFw+l$-NU>&fb!{A-L?rH*sTd-fPyl3ELXw-kZVluFUr?Y`HS--NBVL-V^H88t)IT-1~vx${Ks%tdX4Oy%pJmxU$A=*n5z&#s`BdYkVj;^W{6g z9ozXkANx0d`aX>9Jvb-NVV(4S1l#*?UY^H#>H8?Q_u||F(fi?)LU+#2V$^ z&jgQ}s`1(2%DB%3SJwD^aAl1zz*(b=`yyE0mFM^pwp>}`%fXdg;Xh$Jf9GTW=1wNph_-{JDjmMavfA@U`wtx3kiw_U1_O08?eD=&nU%|T;F96FOk8MtU Xa_(PkX}1~Y2hFKIj=lZZh?ymUqrNnhoJ4kzhFjw9j;4_@cVpT+;< zMPmJS&zCf|te$VJ@47G2so5^q+2Nd9az*{JhFr>_^t!BU=Z;DzrQ&sbUfkGR$KUVL ze0 z(hr)oX5?e3*U~Cs^|n$y^RZdqqotR^i_6$MsPRMo>#OS7O)ZFIO3C^8s*O0hD>uVN zTn?h3e)=y8F6t8hBzs^k=KZW6X}8QvT^5|Zz}XL+8R6u^**~09gL6KXKcXn|X8ftN zYK+OwNGk~AiqGl`C%+)xtuHy~tK#^+3M}K_J$u+UUhsTxcTHL3O$%rSi<_19`tq`4 zaX-b;49v4APEYRL@|I;g_pr-+E3%lCxNULf<;%Olnem%!{06HtA&oxFL|^Jm3RVX{ zb<8)F_|S>t-TYS;^YTV{C&WA^+Kg=81pSY7v&78_oH1b8{X8W(^U}y8&gv}4MyE$v Wal94wiOyU4t()b}(cV?@m+%1w!() zrXKzk<@0N^NUIkY>p8BEJyi8NTPf_g&oY literal 0 HcmV?d00001 diff --git a/shaders/slang/vulkanscene/logo.frag.spv b/shaders/slang/vulkanscene/logo.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..ea6e69d855c8fe80770b6ef05560b3729ebbbe6f GIT binary patch literal 764 zcmZ9KOH0E*6os#S+E!X0(E36uK0ydBR0L5MF1o2&5Zp?z4+BjiF)rNs3tahQ-3Xp9 z>1<3mnK@_9oVhniv9MFM(wvzc>dvnvD;P?{Dz>b#*MI1HZ|TrGIX%YFv?4?1X<5xm zniqu74s6ts8=d^J^6>@H>wD_m#YyN-MWvTBPp;p@(>TezWaU~v zn7pKqqi4J&+mt>G#^Zc%Jv)CCrOC%24x)76Cw}-ePW(wI@pe`tXH(OEy{9~C+7hS{ zPQ7saaO!~5H=KUqTq|<1Z#(NW&uD92mev(I@>ev%d5c}~d5!ErXT7bFb@Gq&WWFkx zeO^1hk@0;0zUE}H??Qg^=z&bf-8*-j9^5+n>4A(horX@YTxdUH)N-jOHS!(Fcf77S z`HnX=Cx4(UYU&7h=;2!${j3S(;9bxRZC&7h<3D7b9=~Q8d}DI(+^a+C*cH$Lm#f>I TyC)3~=U%B3dPMt`^IZ4?Zgn<` literal 0 HcmV?d00001 diff --git a/shaders/slang/vulkanscene/logo.vert.spv b/shaders/slang/vulkanscene/logo.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..c804643c767dbd95e0e04f6fc5d1543b036284f7 GIT binary patch literal 4428 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 literal 0 HcmV?d00001 diff --git a/shaders/slang/vulkanscene/mesh.vert.spv b/shaders/slang/vulkanscene/mesh.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..962fd3c4b296771d25b3c8edac0b6a4ef495a1ad GIT binary patch literal 4440 zcmaKu>u;1*5XRr$7O@pXmKJf5I;&KEHQo>VywH&9gJ}%$%8X=FGNjYFsiSX>Lf8 zWLfgJK3Q{;#ssD{$t9a4H}-7l>D*Hr=y|vClx+mjuS$v(_lvamJL!uR#%W~BD zt>y9cX<8kq=OAyLU!M-8RmHX?d2z+wQmtAU-%?AfrNMG>=TKUzb&Yow71dkXomO?l zm0h}FPCJNa4U}pnBxh@v?CaiK{68+2arj58>F)B5S|wEn*iUSOFq{sQIk0o|X~b^f z9NiqNl=n#}uAZ}5`cP$XS8X(FgEBT{ecih~m40E?+ww@Qy1$TCMrwspwKQBDD_3jf z@m{?`XJ5bex2Uu9f10?dh7!v=O%q#hrsd^5r-|LLzwGbVn!Wopu{~U~zq~`|ZPDbZ z7gP7p>?O_FOe_}9!e)N3=`S|3gw0-T-XEL3Vs}X91Sa)%)yPY-mehq}nzHv|KmK;( z-R~Ur;MNJwu?KD*Q#CIewu-xXHEbK{1z85TPzDuzOyldV#6g5KGtFjyyX=c3$-_QudW}sS z_FS{cGf(z{jIYNmH+!MQxP7^7>bXt-IL~GJq*v5}TdcF^CE*r}ZI{H3@N--to}BF& znv9qcls9EJ1jL$X=i^Oz+0*+V=%JT4^3#9I6(q>;<}^rzYM z1^-`Wv;P*^^p)R<4QA6<=HG4l%KW>HpZRy2`!Z{siF_v{Ck4)cO?_s|ZR(#o&t|rw zpV^8wvxVKDPwsn8Sgr37XP_<%|39+m>#h3a{%rzx!{)xT1@4ATKQ0ltoBQWU=Wd&| z8~-AK7{H?5ZK}Ie@+yIQGehjpOD+@O?^aBQtxdd&P^?RoApvNB{vA<1uV|RIo!WdI=KPs zeE%Kd))^$G`~|%b-_g4SYLJK6!|FeEdj#eRf16_AdWB5_@%Vjawn%4Y3WCqfR_XBc zwL`K`fMfX^_e+OodH?T`4$pG#Ug>c0P3|*}UU=O7#_=Xz;{oZ^h zCDbH0If(U{N~JSX{B84@8kG*uT{|Qn72sHKGbF15Jj;8sM>;&qxtesi*r&b5#XgN0 z=Y6NfK7kr>@3`?2Q#JM*7vml?F4lP5xLD%}any)$Ps)a8`8}SJ4i{@YZCuE<68b>~#ldq)HfBM7u$?v|erSlH-iF;7TecwpuJ?Pg_fqL%yRyyxO-?$fb z@pVgnCs32zvjOf6srE4i8w|n|m^w$0UCen9U^uvpG}pX92!o zbNGvK$0fbiuhQXTt>0wB1D4l1pgiRLT_A=t`TqcaNcaB%@UPJePD*k=^plc{Og|;b Z{|xY_CFhxbMv|QHXC=w`ud3f9{0A5sf?xmu literal 0 HcmV?d00001 diff --git a/shaders/slang/vulkanscene/skybox.frag.spv b/shaders/slang/vulkanscene/skybox.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..71e6a0358cfe1813db7fd20541dd710b7d722d37 GIT binary patch literal 596 zcmZ9Jy-Nc@5XHy)N{pIBBZ>%;Xk%q5g2cwcDv(A~%8I8Pc;|6m3jcE(!S~zTHqJ3O z`{v`#>}(ue^eovjvr9YFAKACa@C+^XnDfZ`mdHlZ(iIhfp>!hMmX4K6tS622?Z{G> z>LXrM^}4-!d|G*5=4-!PS%2is{rV+exSHHVJZ2mJtMI_{=T+N$FF%W_UAo4V&u@); zFXdcxbEKB}-v9j%;-mMO6ah2yOv-ElpX-c(xlhQSbbFZj8*OTibWW8sl^!cUlLfP> zsc>HwZu}?eK9CJ@_7j90(lDW z@6u;GYjp^=%AU!VWUtF=`dO=<`8}ySy{3M?)qF6PmH!j>RBKwDnYnVfp3hcm)}=Sp zH?*K=EnF`1BD>dY+?~#|a%5qoF`7@0Wm9=ETTUJtIhazfc4aVW!F|+eWv#mZ-0fWcnkom) zPFXyx=dDgz&x)+wm~R$kb74%`8lJd%ZTW2M`--P@R(T?K{cNg6yit9x4E}|7_d5>;JhgHm*^UgHJm(=_DH(Kos zR@Jba+b#0B&wy;J=C4#w+->nHi#f+OQTApI;{*C!XEB_3z4{e0)@@e2sp89QpT(QS zSieJ`HR8e7E37303=Hu;>9@$KpvXC3h;>e0Y_{-^S3jDMz{ zG49Pc{V^HM=bw{nN&$kibk`5%&Te)jjV59RX?A56H+D_d(CcM&u95$Q$=UmodKIAIZ>U zZ}wpBaov!5V~qOZyLLnd<2wf9`*l~5a-!orxQa;?*5XUvA6|-hk z=4;N#hx;00UqkJmlTrJe&1?U>ao&X5zaWFrye`M&!)g9@7v;lg&c@}#;(OMO#rM2q z%55BbdD|B&a#{*(`AUuRF`!>L(kPvyg@aeg;HQxC&mQjhMxQamF24{}e< AvH$=8 literal 0 HcmV?d00001