From 7e5a387eb85b4cfee9b414cfec78619e5f9d121a Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 10 May 2025 13:58:14 +0200 Subject: [PATCH] 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