Skip to content

Commit b6b4fcc

Browse files
committed
Add slang shader for instancing sample
1 parent 74e66c6 commit b6b4fcc

3 files changed

Lines changed: 218 additions & 0 deletions

File tree

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/* Copyright (c) 2025, Sascha Willems
2+
*
3+
* SPDX-License-Identifier: MIT
4+
*
5+
*/
6+
7+
struct VSInput
8+
{
9+
float3 Pos : POSITION0;
10+
float3 Normal : NORMAL0;
11+
float2 UV : TEXCOORD0;
12+
float3 Color : COLOR0;
13+
// Instanced attributes
14+
float3 instancePos : POSITION1;
15+
float3 instanceRot : TEXCOORD1;
16+
float instanceScale : TEXCOORD2;
17+
int instanceTexIndex : TEXCOORD3;
18+
};
19+
20+
struct VSOutput
21+
{
22+
float4 Pos : SV_POSITION;
23+
float3 Normal;
24+
float3 Color;
25+
float3 UV;
26+
float3 ViewVec;
27+
float3 LightVec;
28+
};
29+
30+
struct UBO
31+
{
32+
float4x4 projection;
33+
float4x4 modelview;
34+
float4 lightPos;
35+
float locSpeed;
36+
float globSpeed;
37+
};
38+
ConstantBuffer<UBO> ubo;
39+
Sampler2DArray samplerArray;
40+
41+
[shader("vertex")]
42+
VSOutput vertexMain(VSInput input)
43+
{
44+
VSOutput output;
45+
output.Color = input.Color;
46+
output.UV = float3(input.UV, input.instanceTexIndex);
47+
48+
// rotate around x
49+
float s = sin(input.instanceRot.x + ubo.locSpeed);
50+
float c = cos(input.instanceRot.x + ubo.locSpeed);
51+
52+
float3x3 mx = { c, -s, 0.0,
53+
s, c, 0.0,
54+
0.0, 0.0, 1.0 };
55+
56+
// rotate around y
57+
s = sin(input.instanceRot.y + ubo.locSpeed);
58+
c = cos(input.instanceRot.y + ubo.locSpeed);
59+
60+
float3x3 my = { c, 0.0, -s,
61+
0.0, 1.0, 0.0,
62+
s, 0.0, c };
63+
64+
// rot around z
65+
s = sin(input.instanceRot.z + ubo.locSpeed);
66+
c = cos(input.instanceRot.z + ubo.locSpeed);
67+
68+
float3x3 mz = { 1.0, 0.0, 0.0,
69+
0.0, c, -s,
70+
0.0, s, c };
71+
72+
float3x3 rotMat = mul(mz, mul(my, mx));
73+
74+
float4x4 gRotMat;
75+
s = sin(input.instanceRot.y + ubo.globSpeed);
76+
c = cos(input.instanceRot.y + ubo.globSpeed);
77+
gRotMat[0] = float4(c, 0.0, -s, 0.0);
78+
gRotMat[1] = float4(0.0, 1.0, 0.0, 0.0);
79+
gRotMat[2] = float4(s, 0.0, c, 0.0);
80+
gRotMat[3] = float4(0.0, 0.0, 0.0, 1.0);
81+
82+
float4 locPos = float4(mul(rotMat, input.Pos.xyz), 1.0);
83+
float4 pos = float4((locPos.xyz * input.instanceScale) + input.instancePos, 1.0);
84+
85+
output.Pos = mul(ubo.projection, mul(ubo.modelview, mul(gRotMat, pos)));
86+
output.Normal = mul((float3x3)mul(ubo.modelview, gRotMat), mul(rotMat, input.Normal));
87+
88+
pos = mul(ubo.modelview, float4(input.Pos.xyz + input.instancePos, 1.0));
89+
float3 lPos = mul((float3x3)ubo.modelview, ubo.lightPos.xyz);
90+
output.LightVec = lPos - pos.xyz;
91+
output.ViewVec = -pos.xyz;
92+
return output;
93+
}
94+
95+
[shader("fragment")]
96+
float4 fragmentMain(VSOutput input)
97+
{
98+
float4 color = samplerArray.Sample(input.UV) * float4(input.Color, 1.0);
99+
float3 N = normalize(input.Normal);
100+
float3 L = normalize(input.LightVec);
101+
float3 V = normalize(input.ViewVec);
102+
float3 R = reflect(-L, N);
103+
float3 diffuse = max(dot(N, L), 0.1) * input.Color;
104+
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);
105+
return float4(diffuse * color.rgb + specular, 1.0);
106+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/* Copyright (c) 2025, Sascha Willems
2+
*
3+
* SPDX-License-Identifier: MIT
4+
*
5+
*/
6+
7+
struct VSInput
8+
{
9+
float3 Pos;
10+
float3 Normal;
11+
float2 UV;
12+
float3 Color;
13+
};
14+
15+
struct VSOutput
16+
{
17+
float4 Pos : SV_POSITION;
18+
float3 Normal;
19+
float3 Color;
20+
float2 UV;
21+
float3 ViewVec;
22+
float3 LightVec;
23+
};
24+
25+
struct UBO
26+
{
27+
float4x4 projection;
28+
float4x4 modelview;
29+
float4 lightPos;
30+
};
31+
ConstantBuffer<UBO> ubo;
32+
33+
Sampler2D samplerColorMap;
34+
35+
[shader("vertex")]
36+
VSOutput vertexMain(VSInput input)
37+
{
38+
VSOutput output;
39+
output.Color = input.Color;
40+
output.UV = input.UV;
41+
output.Pos = mul(ubo.projection, mul(ubo.modelview, float4(input.Pos.xyz, 1.0)));
42+
43+
float4 pos = mul(ubo.modelview, float4(input.Pos, 1.0));
44+
output.Normal = mul((float3x3)ubo.modelview, input.Normal);
45+
float3 lPos = mul((float3x3)ubo.modelview, ubo.lightPos.xyz);
46+
output.LightVec = lPos - pos.xyz;
47+
output.ViewVec = -pos.xyz;
48+
return output;
49+
}
50+
51+
[shader("fragment")]
52+
float4 fragmentMain(VSOutput input)
53+
{
54+
float4 color = samplerColorMap.Sample(input.UV) * float4(input.Color, 1.0) * 1.5;
55+
float3 N = normalize(input.Normal);
56+
float3 L = normalize(input.LightVec);
57+
float3 V = normalize(input.ViewVec);
58+
float3 R = reflect(-L, N);
59+
float3 diffuse = max(dot(N, L), 0.0) * input.Color;
60+
float3 specular = pow(max(dot(R, V), 0.0), 4.0) * float3(0.5, 0.5, 0.5) * color.r;
61+
return float4(diffuse * color.rgb + specular, 1.0);
62+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/* Copyright (c) 2025, Sascha Willems
2+
*
3+
* SPDX-License-Identifier: MIT
4+
*
5+
*/
6+
7+
#define HASHSCALE3 float3(443.897, 441.423, 437.195)
8+
#define STARFREQUENCY 0.01
9+
10+
// Hash function by Dave Hoskins (https://www.shadertoy.com/view/4djSRW)
11+
float hash33(float3 p3)
12+
{
13+
p3 = frac(p3 * HASHSCALE3);
14+
p3 += dot(p3, p3.yxz+float3(19.19, 19.19, 19.19));
15+
return frac((p3.x + p3.y)*p3.z + (p3.x+p3.z)*p3.y + (p3.y+p3.z)*p3.x);
16+
}
17+
18+
float3 starField(float3 pos)
19+
{
20+
float3 color = float3(0.0, 0.0, 0.0);
21+
float threshhold = (1.0 - STARFREQUENCY);
22+
float rnd = hash33(pos);
23+
if (rnd >= threshhold)
24+
{
25+
float starCol = pow((rnd - threshhold) / (1.0 - threshhold), 16.0);
26+
color += starCol.xxx;
27+
}
28+
return color;
29+
}
30+
31+
struct VSOutput
32+
{
33+
float4 Pos : SV_POSITION;
34+
float3 UVW;
35+
};
36+
37+
[shader("vertex")]
38+
VSOutput vertexMain(uint VertexIndex: SV_VertexID)
39+
{
40+
VSOutput output;
41+
output.UVW = float3((VertexIndex << 1) & 2, VertexIndex & 2, VertexIndex & 2);
42+
output.Pos = float4(output.UVW.xy * 2.0f - 1.0f, 0.0f, 1.0f);
43+
return output;
44+
}
45+
46+
[shader("fragment")]
47+
float4 fragmentMain(VSOutput input)
48+
{
49+
return float4(starField(input.UVW), 1.0);
50+
}

0 commit comments

Comments
 (0)