Skip to content

Commit 516c137

Browse files
[Rendering] Added Instancing support;
1 parent c8bd395 commit 516c137

File tree

22 files changed

+582
-43
lines changed

22 files changed

+582
-43
lines changed

Builtin Resources/Hidden/Shaders/Debug/NormalDebug.shader

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,23 @@ varying vec3 v_normal : NORMAL
88

99
End Parameters
1010

11+
Begin Instancing
12+
End Instancing
13+
1114
Begin Vertex
1215

1316
$input a_position, a_normal
1417
$output v_normal
1518

1619
void main()
1720
{
18-
mat4 projViewWorld = mul(mul(u_proj, u_view), u_model[0]);
21+
mat4 model = StapleModelMatrix;
22+
23+
#ifdef SKINNING
24+
model = StapleGetSkinningMatrix(model, a_indices, a_weight);
25+
#endif
26+
27+
mat4 projViewWorld = mul(mul(u_proj, u_view), model);
1928
vec4 v_pos = mul(projViewWorld, vec4(a_position, 1.0));
2029

2130
v_normal = a_normal;

Builtin Resources/Hidden/Shaders/Default/SolidColor.shader

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,21 @@ uniform color mainColor
77

88
End Parameters
99

10+
Begin Instancing
11+
End Instancing
12+
1013
Begin Vertex
1114
$input a_position
1215

1316
void main()
1417
{
15-
mat4 projViewWorld = mul(mul(u_proj, u_view), u_model[0]);
18+
mat4 model = StapleModelMatrix;
19+
20+
#ifdef SKINNING
21+
model = StapleGetSkinningMatrix(model, a_indices, a_weight);
22+
#endif
23+
24+
mat4 projViewWorld = mul(mul(u_proj, u_view), model);
1625

1726
vec4 v_pos = mul(projViewWorld, vec4(a_position, 1.0));
1827

Builtin Resources/Hidden/Shaders/Default/Standard.shader

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ uniform texture specularTexture
2828

2929
End Parameters
3030

31+
Begin Instancing
32+
End Instancing
33+
3134
Begin Vertex
3235

3336
$input a_position, a_texcoord0, a_normal, a_color0
@@ -37,10 +40,10 @@ $output v_texcoord0, v_fragPos, v_normal, v_color
3740

3841
void main()
3942
{
40-
mat4 model = u_model[0];
43+
mat4 model = StapleModelMatrix;
4144

4245
#ifdef SKINNING
43-
model = StapleGetSkinningMatrix(a_indices, a_weight);
46+
model = StapleGetSkinningMatrix(model, a_indices, a_weight);
4447
#endif
4548

4649
mat4 projViewWorld = mul(mul(u_proj, u_view), model);

Engine/Core/Rendering/Animation/SkinnedMeshRenderSystem.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ public void Submit()
257257

258258
material.EnableShaderKeyword(Shader.SkinningKeyword);
259259

260+
material.DisableShaderKeyword(Shader.InstancingKeyword);
261+
260262
var lightSystem = RenderSystem.Instance.Get<LightSystem>();
261263

262264
lightSystem?.ApplyMaterialLighting(material, pair.renderer.lighting);

Engine/Core/Rendering/Graphics.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ public static void RenderGeometry(VertexBuffer vertex, IndexBuffer index,
7070
material.ApplyProperties(Material.ApplyMode.All);
7171

7272
material.DisableShaderKeyword(Shader.SkinningKeyword);
73+
74+
material.DisableShaderKeyword(Shader.InstancingKeyword);
7375
}
7476

7577
var lightSystem = RenderSystem.Instance.Get<LightSystem>();
@@ -136,6 +138,8 @@ public static void RenderSimple<T>(Span<T> vertices, VertexLayout layout, ushort
136138
material.ApplyProperties(Material.ApplyMode.All);
137139

138140
material.DisableShaderKeyword(Shader.SkinningKeyword);
141+
142+
material.DisableShaderKeyword(Shader.InstancingKeyword);
139143
}
140144

141145
var lightSystem = RenderSystem.Instance.Get<LightSystem>();
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
using Bgfx;
2+
using System;
3+
using System.Runtime.InteropServices;
4+
5+
namespace Staple;
6+
7+
internal class InstanceBuffer
8+
{
9+
internal bgfx.InstanceDataBuffer buffer;
10+
internal readonly int stride;
11+
internal readonly int count;
12+
13+
internal InstanceBuffer(bgfx.InstanceDataBuffer buffer, int stride, int count)
14+
{
15+
this.buffer = buffer;
16+
this.stride = stride;
17+
this.count = count;
18+
}
19+
20+
public void Bind(int start, int count)
21+
{
22+
unsafe
23+
{
24+
fixed(bgfx.InstanceDataBuffer *p = &buffer)
25+
{
26+
bgfx.set_instance_data_buffer(p, (uint)start, (uint)count);
27+
}
28+
}
29+
}
30+
31+
public void SetData(Span<byte> data)
32+
{
33+
if(data.Length != stride * count)
34+
{
35+
return;
36+
}
37+
38+
unsafe
39+
{
40+
Span<byte> p = new Span<byte>(buffer.data, data.Length);
41+
42+
data.CopyTo(p);
43+
}
44+
}
45+
46+
public void SetData<T>(Span<T> data) where T: unmanaged
47+
{
48+
if (data.Length * Marshal.SizeOf<T>() != stride * count)
49+
{
50+
return;
51+
}
52+
53+
unsafe
54+
{
55+
Span<T> p = new Span<T>(buffer.data, data.Length);
56+
57+
data.CopyTo(p);
58+
}
59+
}
60+
61+
public static int AvailableInstances(int requested, int stride)
62+
{
63+
return (int)bgfx.get_avail_instance_data_buffer((uint)requested, (ushort)stride);
64+
}
65+
66+
public static InstanceBuffer Create(int requested, int stride)
67+
{
68+
requested = AvailableInstances(requested, stride);
69+
70+
var buffer = new bgfx.InstanceDataBuffer();
71+
72+
unsafe
73+
{
74+
bgfx.alloc_instance_data_buffer(&buffer, (uint)requested, (ushort)stride);
75+
}
76+
77+
return new InstanceBuffer(buffer, stride, requested);
78+
}
79+
}

Engine/Core/Rendering/Mesh/MeshRenderSystem.cs

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Bgfx;
22
using System;
33
using System.Collections.Generic;
4+
using System.Linq;
45
using System.Numerics;
56

67
namespace Staple.Internal;
@@ -74,6 +75,8 @@ public static void RenderMesh(Mesh mesh, Vector3 position, Quaternion rotation,
7475

7576
material.DisableShaderKeyword(Shader.SkinningKeyword);
7677

78+
material.DisableShaderKeyword(Shader.InstancingKeyword);
79+
7780
var lightSystem = RenderSystem.Instance.Get<LightSystem>();
7881

7982
lightSystem?.ApplyMaterialLighting(material, lighting);
@@ -249,9 +252,9 @@ public void Submit()
249252

250253
foreach(var (viewId, pairs) in instanceCache)
251254
{
252-
foreach(var (_, contents) in pairs)
255+
foreach (var (_, contents) in pairs)
253256
{
254-
if(contents.Length == 0)
257+
if (contents.Length == 0)
255258
{
256259
continue;
257260
}
@@ -281,27 +284,58 @@ public void Submit()
281284
lightSystem?.ApplyLightProperties(contents.Contents[0].position, contents.Contents[0].transform, material,
282285
RenderSystem.CurrentCamera.Item2.Position, contents.Contents[0].lighting);
283286

284-
for(var i = 0; i < contents.Length; i++)
287+
material.EnableShaderKeyword(Shader.InstancingKeyword);
288+
289+
if(material.Keywords.Contains(Shader.InstancingKeyword))
285290
{
286-
var content = contents.Contents[i];
291+
contents.Contents[0].mesh.SetActive(contents.Contents[0].submeshIndex);
287292

288-
unsafe
289-
{
290-
var transform = content.transform;
293+
var program = material.ShaderProgram;
294+
295+
var matrices = new Matrix4x4[contents.Length];
291296

292-
_ = bgfx.set_transform(&transform, 1);
297+
for (var i = 0; i < contents.Length; i++)
298+
{
299+
matrices[i] = contents.Contents[i].transform;
293300
}
294301

295-
content.mesh.SetActive(content.submeshIndex);
302+
var instanceBuffer = InstanceBuffer.Create(contents.Length, 16 * sizeof(float));
296303

297-
var program = material.ShaderProgram;
304+
instanceBuffer.SetData(matrices.AsSpan());
305+
306+
instanceBuffer.Bind(0, instanceBuffer.count);
298307

299308
var flags = bgfx.DiscardFlags.VertexStreams |
300309
bgfx.DiscardFlags.IndexBuffer |
310+
bgfx.DiscardFlags.InstanceData |
301311
bgfx.DiscardFlags.Transform;
302312

303313
bgfx.submit(viewId, program, 0, (byte)flags);
304314
}
315+
else
316+
{
317+
for (var i = 0; i < contents.Length; i++)
318+
{
319+
var content = contents.Contents[i];
320+
321+
unsafe
322+
{
323+
var transform = content.transform;
324+
325+
_ = bgfx.set_transform(&transform, 1);
326+
}
327+
328+
content.mesh.SetActive(content.submeshIndex);
329+
330+
var program = material.ShaderProgram;
331+
332+
var flags = bgfx.DiscardFlags.VertexStreams |
333+
bgfx.DiscardFlags.IndexBuffer |
334+
bgfx.DiscardFlags.Transform;
335+
336+
bgfx.submit(viewId, program, 0, (byte)flags);
337+
}
338+
}
305339

306340
contents.Clear();
307341
}

Engine/Core/Rendering/Shader/Shader.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ internal partial class Shader : IGuidAsset
1515
public static readonly string SkinningKeyword = "SKINNING";
1616
public static readonly string LitKeyword = "LIT";
1717
public static readonly string HalfLambertKeyword = "HALF_LAMBERT";
18+
public static readonly string InstancingKeyword = "INSTANCING";
1819

1920
public static readonly string[] DefaultVariants =
2021
[

Engine/Core/Rendering/Sprites/SpriteRenderSystem.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ public void Submit()
343343
s.material.shader.SetTexture(s.material.GetShaderHandle(Material.MainTextureProperty), s.texture);
344344

345345
s.material.DisableShaderKeyword(Shader.SkinningKeyword);
346+
s.material.DisableShaderKeyword(Shader.InstancingKeyword);
346347

347348
var lightSystem = RenderSystem.Instance.Get<LightSystem>();
348349

Engine/Core/StapleCore.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@
172172
<Compile Include="Rendering\Camera\CameraViewMode.cs" />
173173
<Compile Include="Rendering\CullingMode.cs" />
174174
<Compile Include="Rendering\Graphics.cs" />
175+
<Compile Include="Rendering\Instancing\InstanceBuffer.cs" />
175176
<Compile Include="Rendering\Lighting\Light.cs" />
176177
<Compile Include="Rendering\Lighting\LightSystem.cs" />
177178
<Compile Include="Rendering\Lighting\LightType.cs" />

0 commit comments

Comments
 (0)