Skip to content

Commit 9ff0f35

Browse files
committed
Added slang shaders for compute nbody sample
1 parent 00378d9 commit 9ff0f35

3 files changed

Lines changed: 164 additions & 0 deletions

File tree

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* Copyright (c) 2025, Sascha Willems
2+
*
3+
* SPDX-License-Identifier: MIT
4+
*
5+
*/
6+
7+
struct VSInput
8+
{
9+
float4 Pos;
10+
float4 Vel;
11+
};
12+
13+
struct VSOutput
14+
{
15+
float4 Pos : SV_POSITION;
16+
float PSize : SV_PointSize;
17+
float GradientPos;
18+
float2 CenterPos;
19+
float PointSize;
20+
};
21+
22+
Sampler2D samplerColorMap;
23+
Sampler2D samplerGradientRamp;
24+
25+
struct UBO
26+
{
27+
float4x4 projection;
28+
float4x4 modelview;
29+
float2 screendim;
30+
};
31+
ConstantBuffer<UBO> ubo;
32+
33+
[shader("vertex")]
34+
VSOutput vertexMain(VSInput input)
35+
{
36+
VSOutput output;
37+
const float spriteSize = 0.005 * input.Pos.w; // Point size influenced by mass (stored in input.Pos.w);
38+
39+
float4 eyePos = mul(ubo.modelview, float4(input.Pos.x, input.Pos.y, input.Pos.z, 1.0));
40+
float4 projectedCorner = mul(ubo.projection, float4(0.5 * spriteSize, 0.5 * spriteSize, eyePos.z, eyePos.w));
41+
output.PSize = output.PointSize = clamp(ubo.screendim.x * projectedCorner.x / projectedCorner.w, 1.0, 128.0);
42+
43+
output.Pos = mul(ubo.projection, eyePos);
44+
output.CenterPos = ((output.Pos.xy / output.Pos.w) + 1.0) * 0.5 * ubo.screendim;
45+
46+
output.GradientPos = input.Vel.w;
47+
return output;
48+
}
49+
50+
[shader("fragment")]
51+
float4 fragmentMain(VSOutput input)
52+
{
53+
float3 color = samplerGradientRamp.Sample(float2(input.GradientPos, 0.0)).rgb;
54+
float2 PointCoord = (input.Pos.xy - input.CenterPos.xy) / input.PointSize + 0.5;
55+
return float4(samplerColorMap.Sample(PointCoord).rgb * color, 1);
56+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/* Copyright (c) 2025, Sascha Willems
2+
*
3+
* SPDX-License-Identifier: MIT
4+
*
5+
*/
6+
7+
struct Particle
8+
{
9+
float4 pos;
10+
float4 vel;
11+
};
12+
// Binding 0 : Position storage buffer
13+
RWStructuredBuffer<Particle> particles;
14+
15+
struct UBO
16+
{
17+
float deltaT;
18+
int particleCount;
19+
float gravity;
20+
float power;
21+
float soften;
22+
};
23+
ConstantBuffer<UBO> ubo;
24+
25+
#define MAX_SHARED_DATA_SIZE 1024
26+
[[SpecializationConstant]] const int SHARED_DATA_SIZE = 512;
27+
[[SpecializationConstant]] const float GRAVITY = 0.002;
28+
[[SpecializationConstant]] const float POWER = 0.75;
29+
[[SpecializationConstant]] const float SOFTEN = 0.0075;
30+
31+
// Share data between computer shader invocations to speed up caluclations
32+
groupshared float4 sharedData[MAX_SHARED_DATA_SIZE];
33+
34+
[shader("compute")]
35+
[numthreads(256, 1, 1)]
36+
void computeMain(uint3 GlobalInvocationID : SV_DispatchThreadID, uint3 LocalInvocationID : SV_GroupThreadID)
37+
{
38+
// Current SSBO index
39+
uint index = GlobalInvocationID.x;
40+
if (index >= ubo.particleCount)
41+
return;
42+
43+
float4 position = particles[index].pos;
44+
float4 velocity = particles[index].vel;
45+
float4 acceleration = float4(0, 0, 0, 0);
46+
47+
for (int i = 0; i < ubo.particleCount; i += SHARED_DATA_SIZE)
48+
{
49+
if (i + LocalInvocationID.x < ubo.particleCount)
50+
{
51+
sharedData[LocalInvocationID.x] = particles[i + LocalInvocationID.x].pos;
52+
}
53+
else
54+
{
55+
sharedData[LocalInvocationID.x] = float4(0, 0, 0, 0);
56+
}
57+
58+
GroupMemoryBarrierWithGroupSync();
59+
60+
for (int j = 0; j < 256; j++)
61+
{
62+
float4 other = sharedData[j];
63+
float3 len = other.xyz - position.xyz;
64+
acceleration.xyz += ubo.gravity * len * other.w / pow(dot(len, len) + ubo.soften, ubo.power);
65+
}
66+
67+
GroupMemoryBarrierWithGroupSync();
68+
}
69+
70+
particles[index].vel.xyz += ubo.deltaT * acceleration.xyz;
71+
72+
// Gradient texture position
73+
particles[index].vel.w += 0.1 * ubo.deltaT;
74+
if (particles[index].vel.w > 1.0) {
75+
particles[index].vel.w -= 1.0;
76+
}
77+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* Copyright (c) 2025, Sascha Willems
2+
*
3+
* SPDX-License-Identifier: MIT
4+
*
5+
*/
6+
7+
struct Particle
8+
{
9+
float4 pos;
10+
float4 vel;
11+
};
12+
// Binding 0 : Position storage buffer
13+
RWStructuredBuffer<Particle> particles;
14+
15+
struct UBO
16+
{
17+
float deltaT;
18+
int particleCount;
19+
};
20+
ConstantBuffer<UBO> ubo;
21+
22+
[shader("compute")]
23+
[numthreads(256, 1, 1)]
24+
void computeMain(uint3 GlobalInvocationID : SV_DispatchThreadID)
25+
{
26+
int index = int(GlobalInvocationID.x);
27+
float4 position = particles[index].pos;
28+
float4 velocity = particles[index].vel;
29+
position += ubo.deltaT * velocity;
30+
particles[index].pos = position;
31+
}

0 commit comments

Comments
 (0)