Skip to content

Commit 487fd21

Browse files
committed
Added final missing slang shaders
Requires a very recent version of slang
1 parent 0d5becd commit 487fd21

5 files changed

Lines changed: 431 additions & 0 deletions

File tree

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/* Copyright (c) 2025, Sascha Willems
2+
*
3+
* SPDX-License-Identifier: MIT
4+
*
5+
*/
6+
7+
[[vk::binding(1, 0)]] Texture2DMS samplerPosition;
8+
[[vk::binding(2, 0)]] Texture2DMS samplerNormal;
9+
[[vk::binding(3, 0)]] Texture2DMS samplerAlbedo;
10+
11+
struct Light {
12+
float4 position;
13+
float3 color;
14+
float radius;
15+
};
16+
17+
struct UBO
18+
{
19+
Light lights[6];
20+
float4 viewPos;
21+
int displayDebugTarget;
22+
};
23+
[[vk::binding(4, 0)]] ConstantBuffer<UBO> ubo;
24+
25+
struct VSOutput
26+
{
27+
float4 Pos : SV_POSITION;
28+
float2 UV;
29+
};
30+
31+
[[SpecializationConstant]] const int NUM_SAMPLES = 8;
32+
#define NUM_LIGHTS 6
33+
34+
// Manual resolve for MSAA samples
35+
float4 resolve(Texture2DMS<float4> tex, int2 uv)
36+
{
37+
float4 result = float4(0.0, 0.0, 0.0, 0.0);
38+
for (int i = 0; i < NUM_SAMPLES; i++)
39+
{
40+
uint status = 0;
41+
float4 val = tex.Load(uv, i, int2(0, 0), status);
42+
result += val;
43+
}
44+
// Average resolved samples
45+
return result / float(NUM_SAMPLES);
46+
}
47+
48+
float3 calculateLighting(float3 pos, float3 normal, float4 albedo)
49+
{
50+
float3 result = float3(0.0, 0.0, 0.0);
51+
52+
for (int i = 0; i < NUM_LIGHTS; ++i)
53+
{
54+
// Vector to light
55+
float3 L = ubo.lights[i].position.xyz - pos;
56+
// Distance from light to fragment position
57+
float dist = length(L);
58+
59+
// Viewer to fragment
60+
float3 V = ubo.viewPos.xyz - pos;
61+
V = normalize(V);
62+
63+
// Light to fragment
64+
L = normalize(L);
65+
66+
// Attenuation
67+
float atten = ubo.lights[i].radius / (pow(dist, 2.0) + 1.0);
68+
69+
// Diffuse part
70+
float3 N = normalize(normal);
71+
float NdotL = max(0.0, dot(N, L));
72+
float3 diff = ubo.lights[i].color * albedo.rgb * NdotL * atten;
73+
74+
// Specular part
75+
float3 R = reflect(-L, N);
76+
float NdotR = max(0.0, dot(R, V));
77+
float3 spec = ubo.lights[i].color * albedo.a * pow(NdotR, 8.0) * atten;
78+
79+
result += diff + spec;
80+
}
81+
return result;
82+
}
83+
84+
[shader("vertex")]
85+
VSOutput vertexMain(uint VertexIndex: SV_VertexID)
86+
{
87+
VSOutput output;
88+
output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2);
89+
output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f);
90+
return output;
91+
}
92+
93+
[shader("fragment")]
94+
float4 fragmentMain(VSOutput input)
95+
{
96+
int2 attDim; int sampleCount;
97+
samplerPosition.GetDimensions(attDim.x, attDim.y, sampleCount);
98+
int2 UV = int2(input.UV * attDim);
99+
100+
float3 fragColor;
101+
uint status = 0;
102+
103+
// Debug display
104+
if (ubo.displayDebugTarget > 0) {
105+
switch (ubo.displayDebugTarget) {
106+
case 1:
107+
fragColor.rgb = samplerPosition.Load(UV, 0, int2(0, 0), status).rgb;
108+
break;
109+
case 2:
110+
fragColor.rgb = samplerNormal.Load(UV, 0, int2(0, 0), status).rgb;
111+
break;
112+
case 3:
113+
fragColor.rgb = samplerAlbedo.Load(UV, 0, int2(0, 0), status).rgb;
114+
break;
115+
case 4:
116+
fragColor.rgb = samplerAlbedo.Load(UV, 0, int2(0, 0), status).aaa;
117+
break;
118+
}
119+
return float4(fragColor, 1.0);
120+
}
121+
122+
#define ambient 0.15
123+
124+
// Ambient part
125+
float4 alb = resolve(samplerAlbedo, UV);
126+
fragColor = float3(0.0, 0.0, 0.0);
127+
128+
// Calualte lighting for every MSAA sample
129+
for (int i = 0; i < NUM_SAMPLES; i++)
130+
{
131+
float3 pos = samplerPosition.Load(UV, i, int2(0, 0), status).rgb;
132+
float3 normal = samplerNormal.Load(UV, i, int2(0, 0), status).rgb;
133+
float4 albedo = samplerAlbedo.Load(UV, i, int2(0, 0), status);
134+
fragColor += calculateLighting(pos, normal, albedo);
135+
}
136+
137+
fragColor = (alb.rgb * ambient) + fragColor / float(NUM_SAMPLES);
138+
139+
return float4(fragColor, 1.0);
140+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/* Copyright (c) 2025, Sascha Willems
2+
*
3+
* SPDX-License-Identifier: MIT
4+
*
5+
*/
6+
7+
struct VSInput
8+
{
9+
float4 Pos;
10+
float2 UV;
11+
float3 Color;
12+
float3 Normal;
13+
float3 Tangent;
14+
};
15+
16+
struct VSOutput
17+
{
18+
float4 Pos : SV_POSITION;
19+
float3 Normal;
20+
float2 UV;
21+
float3 Color;
22+
float3 WorldPos;
23+
float3 Tangent;
24+
};
25+
26+
struct FSOutput
27+
{
28+
float4 Position;
29+
float4 Normal;
30+
float4 Albedo;
31+
};
32+
33+
struct UBO
34+
{
35+
float4x4 projection;
36+
float4x4 model;
37+
float4x4 view;
38+
float4 instancePos[3];
39+
};
40+
ConstantBuffer<UBO> ubo;
41+
42+
Sampler2D samplerColor;
43+
Sampler2D samplerNormalMap;
44+
45+
[shader("vertex")]
46+
VSOutput vertexMain(VSInput input, uint InstanceIndex: SV_InstanceID)
47+
{
48+
VSOutput output;
49+
float4 tmpPos = input.Pos + ubo.instancePos[InstanceIndex];
50+
51+
output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, tmpPos)));
52+
53+
output.UV = input.UV;
54+
55+
// Vertex position in world space
56+
output.WorldPos = mul(ubo.model, tmpPos).xyz;
57+
58+
// Normal in world space
59+
output.Normal = normalize(input.Normal);
60+
output.Tangent = normalize(input.Tangent);
61+
62+
// Currently just vertex color
63+
output.Color = input.Color;
64+
return output;
65+
}
66+
67+
[shader("fragment")]
68+
FSOutput fragmentMain(VSOutput input)
69+
{
70+
FSOutput output;
71+
output.Position = float4(input.WorldPos, 1.0);
72+
73+
// Calculate normal in tangent space
74+
float3 N = normalize(input.Normal);
75+
float3 T = normalize(input.Tangent);
76+
float3 B = cross(N, T);
77+
float3x3 TBN = float3x3(T, B, N);
78+
float3 tnorm = mul(normalize(samplerNormalMap.Sample(input.UV).xyz * 2.0 - float3(1.0, 1.0, 1.0)), TBN);
79+
output.Normal = float4(tnorm, 1.0);
80+
81+
output.Albedo = samplerColor.Sample(input.UV);
82+
return output;
83+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/* Copyright (c) 2025, Sascha Willems
2+
*
3+
* SPDX-License-Identifier: MIT
4+
*
5+
*/
6+
7+
struct VSOutput
8+
{
9+
float4 Pos : SV_POSITION;
10+
float2 UV;
11+
};
12+
13+
[[vk::input_attachment_index(0)]] SubpassInput inputPosition;
14+
[[vk::input_attachment_index(1)]] SubpassInput inputNormal;
15+
[[vk::input_attachment_index(2)]] SubpassInput inputAlbedo;
16+
17+
struct Light {
18+
float4 position;
19+
float3 color;
20+
float radius;
21+
};
22+
RWStructuredBuffer<Light> lights;
23+
24+
[shader("vertex")]
25+
VSOutput vertexMain(uint VertexIndex: SV_VertexID)
26+
{
27+
VSOutput output;
28+
output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2);
29+
output.Pos = float4(output.UV * 2.0f - 1.0f, 0.0f, 1.0f);
30+
return output;
31+
}
32+
33+
[shader("fragment")]
34+
float4 fragmentMain()
35+
{
36+
// Read G-Buffer values from previous sub pass
37+
float3 fragPos = inputPosition.SubpassLoad().rgb;
38+
float3 normal = inputNormal.SubpassLoad().rgb;
39+
float4 albedo = inputAlbedo.SubpassLoad();
40+
41+
#define ambient 0.05
42+
43+
// Ambient part
44+
float3 fragcolor = albedo.rgb * ambient;
45+
46+
uint lightsLength;
47+
uint lightsStride;
48+
lights.GetDimensions(lightsLength, lightsStride);
49+
50+
for(int i = 0; i < lightsLength; ++i)
51+
{
52+
float3 L = lights[i].position.xyz - fragPos;
53+
float dist = length(L);
54+
55+
L = normalize(L);
56+
57+
float atten = lights[i].radius / (pow(dist, 3.0) + 1.0);
58+
float3 N = normalize(normal);
59+
float NdotL = max(0.0, dot(N, L));
60+
float3 diff = lights[i].color * albedo.rgb * NdotL * atten;
61+
62+
fragcolor += diff;
63+
}
64+
65+
return float4(fragcolor, 1.0);
66+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/* Copyright (c) 2025, Sascha Willems
2+
*
3+
* SPDX-License-Identifier: MIT
4+
*
5+
*/
6+
7+
struct VSInput
8+
{
9+
float4 Pos;
10+
float3 Color;
11+
float3 Normal;
12+
};
13+
14+
struct VSOutput
15+
{
16+
float4 Pos : SV_POSITION;
17+
float3 Normal;
18+
float3 Color;
19+
float3 WorldPos;
20+
float3 Tangent;
21+
};
22+
23+
struct FSOutput
24+
{
25+
float4 Color : SV_TARGET0;
26+
float4 Position : SV_TARGET1;
27+
float4 Normal : SV_TARGET2;
28+
float4 Albedo : SV_TARGET3;
29+
};
30+
31+
struct UBO
32+
{
33+
float4x4 projection;
34+
float4x4 model;
35+
float4x4 view;
36+
};
37+
ConstantBuffer<UBO> ubo;
38+
39+
[[SpecializationConstant]] const float NEAR_PLANE = 0.1;
40+
[[SpecializationConstant]] const float FAR_PLANE = 256.0;
41+
42+
float linearDepth(float depth)
43+
{
44+
float z = depth * 2.0f - 1.0f;
45+
return (2.0f * NEAR_PLANE * FAR_PLANE) / (FAR_PLANE + NEAR_PLANE - z * (FAR_PLANE - NEAR_PLANE));
46+
}
47+
48+
[shader("vertex")]
49+
VSOutput vertexMain(VSInput input)
50+
{
51+
VSOutput output;
52+
output.Pos = mul(ubo.projection, mul(ubo.view, mul(ubo.model, input.Pos)));
53+
// Vertex position in world space
54+
output.WorldPos = mul(ubo.model, input.Pos).xyz;
55+
// GL to Vulkan coord space
56+
output.WorldPos.y = -output.WorldPos.y;
57+
// Normal in world space
58+
output.Normal = mul((float3x3)ubo.model, normalize(input.Normal));
59+
// Currently just vertex color
60+
output.Color = input.Color;
61+
return output;
62+
}
63+
64+
[shader("fragment")]
65+
FSOutput fragmentMain(VSOutput input)
66+
{
67+
FSOutput output;
68+
output.Position = float4(input.WorldPos, 1.0);
69+
float3 N = normalize(input.Normal);
70+
N.y = -N.y;
71+
output.Normal = float4(N, 1.0);
72+
output.Albedo.rgb = input.Color;
73+
// Store linearized depth in alpha component
74+
output.Position.a = linearDepth(input.Pos.z);
75+
// Write color attachments to avoid undefined behaviour (validation error)
76+
output.Color = float4(0.0);
77+
return output;
78+
}

0 commit comments

Comments
 (0)