Skip to content

Commit b6f59ea

Browse files
[Rendering] Re-add Instancing support;
1 parent 2b03eda commit b6f59ea

File tree

11 files changed

+240
-130
lines changed

11 files changed

+240
-130
lines changed

BuiltinResources/Hidden/Shaders/Debug/NormalDebug.shader

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ End Parameters
55
Begin Input
66
POSITION
77
NORMAL
8+
variant: SKINNING BLENDINDICES
9+
variant: SKINNING BLENDWEIGHTS
810
End Input
911

1012
Begin Instancing
@@ -26,17 +28,35 @@ struct Input
2628
{
2729
float3 position : POSITION;
2830
float3 normal : NORMAL;
31+
#ifdef SKINNING
32+
float4 indices : BLENDINDICES;
33+
float4 weights : BLENDWEIGHTS;
34+
#endif
2935
};
3036

3137
[shader("vertex")]
32-
VertexOutput VertexMain(Input input)
38+
VertexOutput VertexMain(Input input, uint instanceID : SV_InstanceID)
3339
{
3440
VertexOutput output;
3541

42+
float4x4 model;
43+
44+
#ifdef INSTANCING
45+
model = StapleGetInstancedTransform(instanceID);
46+
#else
47+
model = world;
48+
#endif
49+
50+
#ifdef SKINNING
51+
model = StapleGetSkinningMatrix(model, input.indices, input.weights);
52+
#endif
53+
54+
float4x4 projectionViewWorld = ProjectionViewWorld(model);
55+
3656
float3 position = input.position;
3757

3858
output.normal = input.normal;
39-
output.position = mul(ProjectionViewWorld(world), float4(position, 1.0));
59+
output.position = mul(projectionViewWorld, float4(position, 1.0));
4060

4161
return output;
4262
}

BuiltinResources/Hidden/Shaders/Debug/TangentDebug.shader

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ End Parameters
99
Begin Input
1010
POSITION
1111
TANGENT
12+
variant: SKINNING BLENDINDICES
13+
variant: SKINNING BLENDWEIGHTS
1214
End Input
1315

1416
Begin Instancing
@@ -35,17 +37,35 @@ struct Input
3537
#else
3638
float3 tangent : TANGENT;
3739
#endif
40+
#ifdef SKINNING
41+
float4 indices : BLENDINDICES;
42+
float4 weights : BLENDWEIGHTS;
43+
#endif
3844
};
3945

4046
[shader("vertex")]
41-
VertexOutput VertexMain(Input input)
47+
VertexOutput VertexMain(Input input, uint instanceID : SV_InstanceID)
4248
{
4349
VertexOutput output;
4450

51+
float4x4 model;
52+
53+
#ifdef INSTANCING
54+
model = StapleGetInstancedTransform(instanceID);
55+
#else
56+
model = world;
57+
#endif
58+
59+
#ifdef SKINNING
60+
model = StapleGetSkinningMatrix(model, input.indices, input.weights);
61+
#endif
62+
63+
float4x4 projectionViewWorld = ProjectionViewWorld(model);
64+
4565
float3 position = input.position;
4666

4767
output.tangent = input.tangent;
48-
output.position = mul(ProjectionViewWorld(world), float4(position, 1.0));
68+
output.position = mul(projectionViewWorld, float4(position, 1.0));
4969

5070
return output;
5171
}

BuiltinResources/Hidden/Shaders/Default/SolidColor.shader

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ End Parameters
88

99
Begin Input
1010
POSITION
11+
variant: SKINNING BLENDINDICES
12+
variant: SKINNING BLENDWEIGHTS
1113
End Input
1214

1315
Begin Instancing
@@ -34,18 +36,36 @@ cbuffer Uniforms
3436
struct Input
3537
{
3638
float3 position : POSITION;
39+
#ifdef SKINNING
40+
float4 indices : BLENDINDICES;
41+
float4 weights : BLENDWEIGHTS;
42+
#endif
3743
};
3844

3945
[shader("vertex")]
40-
VertexOutput VertexMain(Input input)
46+
VertexOutput VertexMain(Input input, uint instanceID : SV_InstanceID)
4147
{
4248
VertexOutput output;
4349

4450
float3 position = input.position;
4551
float4 color = mainColor;
4652

53+
float4x4 model;
54+
55+
#ifdef INSTANCING
56+
model = StapleGetInstancedTransform(instanceID);
57+
#else
58+
model = world;
59+
#endif
60+
61+
#ifdef SKINNING
62+
model = StapleGetSkinningMatrix(model, input.indices, input.weights);
63+
#endif
64+
65+
float4x4 projectionViewWorld = ProjectionViewWorld(model);
66+
4767
output.color = color;
48-
output.position = mul(ProjectionViewWorld(world), float4(position, 1.0));
68+
output.position = mul(projectionViewWorld, float4(position, 1.0));
4969

5070
return output;
5171
}

BuiltinResources/Hidden/Shaders/Default/Standard.shader

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,23 @@ struct Input
8686
float4 indices : BLENDINDICES;
8787
float4 weights : BLENDWEIGHTS;
8888
#endif
89-
uint instanceID : SV_InstanceID;
9089
};
9190

9291
[shader("vertex")]
93-
VertexOutput VertexMain(Input input)
92+
VertexOutput VertexMain(Input input, uint instanceID : SV_InstanceID)
9493
{
9594
VertexOutput output;
9695

97-
#ifdef SKINNING
98-
float4x4 model = StapleGetSkinningMatrix(world, input.indices, input.weights);
96+
float4x4 model;
97+
98+
#ifdef INSTANCING
99+
model = StapleGetInstancedTransform(instanceID);
99100
#else
100-
float4x4 model = world;
101+
model = world;
102+
#endif
103+
104+
#ifdef SKINNING
105+
model = StapleGetSkinningMatrix(model, input.indices, input.weights);
101106
#endif
102107

103108
float4x4 projectionViewWorld = ProjectionViewWorld(model);
@@ -121,7 +126,7 @@ VertexOutput VertexMain(Input input)
121126
output.lightNormal = StapleLightNormal(input.normal, model);
122127
#endif
123128

124-
output.instanceID = input.instanceID;
129+
output.instanceID = instanceID;
125130

126131
#if defined(LIT) && defined(PER_VERTEX_LIGHTING)
127132
output.color = float4(diffuseColor.rgb * StapleProcessLights(output.worldPosition, output.lightNormal), diffuseColor.a);

Engine/Staple.Core/Rendering/Mesh/MeshRenderSystem.cs

Lines changed: 44 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,21 @@ private class InstanceData
2727
{
2828
public ExpandableContainer<InstanceInfo> instanceInfos = new();
2929
public Matrix4x4[] transformMatrices = [];
30+
public VertexBuffer instanceBuffer;
3031
}
3132

3233
private readonly Dictionary<int, InstanceData> instanceCache = [];
3334

35+
private readonly Lazy<VertexLayout> instanceLayout = new(() =>
36+
{
37+
return VertexLayoutBuilder.CreateNew()
38+
.Add(VertexAttribute.TexCoord0, VertexAttributeType.Float4)
39+
.Add(VertexAttribute.TexCoord1, VertexAttributeType.Float4)
40+
.Add(VertexAttribute.TexCoord2, VertexAttributeType.Float4)
41+
.Add(VertexAttribute.TexCoord3, VertexAttributeType.Float4)
42+
.Build();
43+
});
44+
3445
public bool UsesOwnRenderProcess => false;
3546

3647
public Type RelatedComponent => typeof(MeshRenderer);
@@ -238,11 +249,6 @@ void Add(Material material, int submeshIndex)
238249

239250
public void Submit()
240251
{
241-
Material lastMaterial = null;
242-
MaterialLighting lastLighting = MaterialLighting.Unlit;
243-
var lastInstances = 0;
244-
var forceDiscard = false;
245-
246252
var renderState = new RenderState()
247253
{
248254
depthWrite = true,
@@ -256,38 +262,17 @@ public void Submit()
256262
continue;
257263
}
258264

259-
var renderData = contents.instanceInfos.Contents[0];
265+
renderState.ClearStorageBuffers();
260266

261-
var needsDiscard = forceDiscard ||
262-
lastMaterial != renderData.material ||
263-
lastLighting != renderData.lighting ||
264-
(contents.instanceInfos.Contents.Length == 1) != (lastInstances == 1);
267+
var renderData = contents.instanceInfos.Contents[0];
265268

266269
var material = renderData.material;
267270

268271
var lightSystem = RenderSystem.Instance.Get<LightSystem>();
269272

270-
if (needsDiscard)
271-
{
272-
lastMaterial = material;
273-
lastLighting = renderData.lighting;
274-
lastInstances = contents.instanceInfos.Contents.Length;
275-
forceDiscard = false;
276-
277-
material.DisableShaderKeyword(Shader.SkinningKeyword);
278-
279-
lightSystem?.ApplyMaterialLighting(material, contents.instanceInfos.Contents[0].lighting);
273+
material.DisableShaderKeyword(Shader.SkinningKeyword);
280274

281-
if (material.ShaderProgram == null)
282-
{
283-
continue;
284-
}
285-
286-
material.ApplyProperties(Material.ApplyMode.All, ref renderState);
287-
288-
lightSystem?.ApplyLightProperties(material, RenderSystem.CurrentCamera.Item2.Position,
289-
contents.instanceInfos.Contents[0].lighting, ref renderState);
290-
}
275+
lightSystem?.ApplyMaterialLighting(material, contents.instanceInfos.Contents[0].lighting);
291276

292277
if (contents.instanceInfos.Contents.Length > 1)
293278
{
@@ -298,45 +283,54 @@ public void Submit()
298283
material.DisableShaderKeyword(Shader.InstancingKeyword);
299284
}
300285

301-
if (material.IsShaderKeywordEnabled(Shader.InstancingKeyword) && false)
286+
if (material.ShaderProgram == null)
302287
{
303-
/*
304-
bgfx.set_state((ulong)(material.shader.StateFlags |
305-
contents.instanceInfos.Contents[0].mesh.PrimitiveFlag() |
306-
material.CullingFlag), 0);
288+
continue;
289+
}
307290

308-
contents.instanceInfos.Contents[0].mesh.SetActive(contents.instanceInfos.Contents[0].submeshIndex);
291+
material.ApplyProperties(Material.ApplyMode.All, ref renderState);
309292

293+
lightSystem?.ApplyLightProperties(material, RenderSystem.CurrentCamera.Item2.Position,
294+
contents.instanceInfos.Contents[0].lighting, ref renderState);
295+
296+
if (material.IsShaderKeywordEnabled(Shader.InstancingKeyword))
297+
{
310298
var program = material.ShaderProgram;
311299

300+
if(program == null)
301+
{
302+
continue;
303+
}
304+
305+
contents.instanceInfos.Contents[0].mesh.SetActive(ref renderState, contents.instanceInfos.Contents[0].submeshIndex);
306+
312307
for (var i = 0; i < contents.instanceInfos.Length; i++)
313308
{
314309
contents.transformMatrices[i] = contents.instanceInfos.Contents[i].transform.Matrix;
315310
}
316311

317-
var instanceBuffer = InstanceBuffer.Create(contents.transformMatrices.Length, Marshal.SizeOf<Matrix4x4>());
318-
319-
if (instanceBuffer != null)
312+
if(contents.instanceBuffer == null)
320313
{
321-
instanceBuffer.SetData(contents.transformMatrices.AsSpan());
314+
contents.instanceBuffer = VertexBuffer.Create(contents.transformMatrices, instanceLayout.Value, RenderBufferFlags.GraphicsRead);
315+
}
316+
else
317+
{
318+
contents.instanceBuffer.Update(contents.transformMatrices);
319+
}
322320

323-
instanceBuffer.Bind(0, instanceBuffer.count);
321+
if (contents.instanceBuffer != null)
322+
{
323+
renderState.instanceCount = contents.transformMatrices.Length;
324324

325-
var flags = bgfx.DiscardFlags.State;
325+
renderState.ApplyStorageBufferIfNeeded("StapleInstancingTransforms", contents.instanceBuffer);
326326

327-
RenderSystem.Submit(viewID, program, flags,
328-
renderData.mesh.SubmeshTriangleCount(contents.instanceInfos.Contents[0].submeshIndex),
329-
instanceBuffer.count);
327+
RenderSystem.Submit(renderState, renderData.mesh.SubmeshTriangleCount(contents.instanceInfos.Contents[0].submeshIndex),
328+
contents.instanceInfos.Length);
330329
}
331330
else
332331
{
333332
Log.Error($"[MeshRenderSystem] Failed to render {contents.instanceInfos.Contents[0].mesh.Guid}: Instance buffer creation failed");
334-
335-
forceDiscard = true;
336-
337-
bgfx.discard((byte)bgfx.DiscardFlags.All);
338333
}
339-
*/
340334
}
341335
else
342336
{

Engine/Staple.Core/Rendering/RenderSystem/Backend/Impls/SDLGPU/Commands/SDLGPURenderCommand.cs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,6 @@ pair.Value is not SDLGPUVertexBuffer v ||
7373

7474
SDL.BindGPUGraphicsPipeline(renderPass, pipeline);
7575

76-
var vertexBinding = new SDL.GPUBufferBinding()
77-
{
78-
Buffer = vertexBuffer.buffer,
79-
};
80-
81-
var indexBinding = new SDL.GPUBufferBinding()
82-
{
83-
Buffer = indexBuffer.buffer,
84-
};
85-
8676
if (state.scissor != default)
8777
{
8878
var scissor = new SDL.Rect()
@@ -96,6 +86,16 @@ pair.Value is not SDLGPUVertexBuffer v ||
9686
SDL.SetGPUScissor(renderPass, in scissor);
9787
}
9888

89+
var vertexBinding = new SDL.GPUBufferBinding()
90+
{
91+
Buffer = vertexBuffer.buffer,
92+
};
93+
94+
var indexBinding = new SDL.GPUBufferBinding()
95+
{
96+
Buffer = indexBuffer.buffer,
97+
};
98+
9999
SDL.BindGPUVertexBuffers(renderPass, 0, [vertexBinding], 1);
100100

101101
SDL.BindGPUIndexBuffer(renderPass, in indexBinding, index.Is32Bit ?
@@ -170,6 +170,7 @@ pair.Value is not SDLGPUVertexBuffer v ||
170170
}
171171
}
172172

173-
SDL.DrawGPUIndexedPrimitives(renderPass, (uint)state.indexCount, 1, (uint)state.startIndex, state.startVertex, 0);
173+
SDL.DrawGPUIndexedPrimitives(renderPass, (uint)state.indexCount, (uint)(state.instanceCount > 1 ? state.instanceCount : 1),
174+
(uint)state.startIndex, state.startVertex, 0);
174175
}
175176
}

0 commit comments

Comments
 (0)