From 74e66c6b485c02f2e5280407c1d981a621b8c395 Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 26 Apr 2025 17:07:33 +0200 Subject: [PATCH] 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