fix #451: stabilize portal seam rendering
This commit is contained in:
parent
f6fe0f2a4f
commit
1d2f2f738f
29 changed files with 1650 additions and 239 deletions
|
|
@ -71,10 +71,8 @@ public sealed unsafe partial class ParticleRenderer
|
|||
|
||||
private const uint QuadStrideBytes = 4 * sizeof(float);
|
||||
|
||||
/// <summary>Floats per mesh-particle instance: a <c>mat4</c> plus an RGBA colour.</summary>
|
||||
internal const int MeshInstanceFloats = 20;
|
||||
|
||||
private const uint MeshInstanceStrideBytes = MeshInstanceFloats * sizeof(float);
|
||||
private static readonly uint MeshInstanceStrideBytes =
|
||||
(uint)sizeof(MeshParticleGpuInstance);
|
||||
|
||||
/// <summary>
|
||||
/// The billboard layout: the shared unit quad at vertex rate, and one
|
||||
|
|
@ -103,7 +101,8 @@ public sealed unsafe partial class ParticleRenderer
|
|||
// Location 6 is `in uint aTextureIndex` — an INTEGER shader input,
|
||||
// so R8G8B8A8's normalized cousin would be wrong in kind. It is one
|
||||
// 32-bit unsigned value; Float1 would reinterpret its bits.
|
||||
new GpuVertexAttribute(6, GpuVertexFormat.UInt1, 64, Binding: 1)));
|
||||
new GpuVertexAttribute(6, GpuVertexFormat.UInt1, 64, Binding: 1),
|
||||
new GpuVertexAttribute(7, GpuVertexFormat.UInt1, 68, Binding: 1)));
|
||||
|
||||
/// <summary>
|
||||
/// The mesh-particle layout: the shared world-mesh vertex at vertex rate,
|
||||
|
|
@ -126,7 +125,8 @@ public sealed unsafe partial class ParticleRenderer
|
|||
new GpuVertexAttribute(4, GpuVertexFormat.Float4, 16, Binding: 1),
|
||||
new GpuVertexAttribute(5, GpuVertexFormat.Float4, 32, Binding: 1),
|
||||
new GpuVertexAttribute(6, GpuVertexFormat.Float4, 48, Binding: 1),
|
||||
new GpuVertexAttribute(7, GpuVertexFormat.Float4, 64, Binding: 1)));
|
||||
new GpuVertexAttribute(7, GpuVertexFormat.Float4, 64, Binding: 1),
|
||||
new GpuVertexAttribute(8, GpuVertexFormat.UInt1, 80, Binding: 1)));
|
||||
|
||||
/// <summary>
|
||||
/// The RHI arm's constructor. No GL context, no <c>Shader</c>, no
|
||||
|
|
@ -340,22 +340,22 @@ public sealed unsafe partial class ParticleRenderer
|
|||
while (submission.Kind == ParticleSubmissionKind.Mesh
|
||||
&& _meshDrawListScratch[submission.DrawIndex].Key == meshKey);
|
||||
|
||||
int neededFloats = _meshRunScratch.Count * MeshInstanceFloats;
|
||||
if (_meshInstanceScratch.Length < neededFloats)
|
||||
_meshInstanceScratch = new float[neededFloats + 256 * MeshInstanceFloats];
|
||||
int neededInstances = _meshRunScratch.Count;
|
||||
if (_meshInstanceScratch.Length < neededInstances)
|
||||
_meshInstanceScratch = new MeshParticleGpuInstance[neededInstances + 256];
|
||||
for (int instance = 0; instance < _meshRunScratch.Count; instance++)
|
||||
{
|
||||
WriteMeshGpuInstance(
|
||||
_meshInstanceScratch,
|
||||
instance * MeshInstanceFloats,
|
||||
ref _meshInstanceScratch[instance],
|
||||
_meshRunScratch[instance]);
|
||||
}
|
||||
|
||||
GpuRingAllocation instances = WriteVertexRing<float>(
|
||||
GpuRingAllocation instances = WriteVertexRing<MeshParticleGpuInstance>(
|
||||
frame,
|
||||
_meshInstanceScratch.AsSpan(0, neededFloats));
|
||||
_meshInstanceScratch.AsSpan(0, neededInstances));
|
||||
DrawMeshBatchRhi(
|
||||
encoder,
|
||||
frame,
|
||||
global,
|
||||
batch,
|
||||
viewProjection,
|
||||
|
|
@ -384,7 +384,13 @@ public sealed unsafe partial class ParticleRenderer
|
|||
GpuRingAllocation ring = WriteVertexRing<BillboardGpuInstance>(
|
||||
frame,
|
||||
_instanceScratch.AsSpan(0, instances.Count));
|
||||
BindBillboardPipeline(encoder, viewProjection, additive, ring.Buffer, ring.OffsetBytes);
|
||||
BindBillboardPipeline(
|
||||
encoder,
|
||||
frame,
|
||||
viewProjection,
|
||||
additive,
|
||||
ring.Buffer,
|
||||
ring.OffsetBytes);
|
||||
encoder.DrawIndexed(
|
||||
(uint)QuadIndices.Length,
|
||||
(uint)instances.Count,
|
||||
|
|
@ -401,6 +407,7 @@ public sealed unsafe partial class ParticleRenderer
|
|||
/// </summary>
|
||||
private void BindBillboardPipeline(
|
||||
IGpuPassEncoder encoder,
|
||||
IGpuFrame frame,
|
||||
Matrix4x4 viewProjection,
|
||||
bool additive,
|
||||
IGpuBuffer instanceBuffer,
|
||||
|
|
@ -426,10 +433,15 @@ public sealed unsafe partial class ParticleRenderer
|
|||
encoder.BindVertexBuffer(0, _quadVertexBuffer!, 0);
|
||||
encoder.BindVertexBuffer(1, instanceBuffer, instanceOffsetBytes);
|
||||
encoder.BindIndexBuffer(_quadIndexBuffer!, 0, GpuIndexType.UInt32);
|
||||
WorldFrameSectionBinding.BindClipRegions(
|
||||
encoder,
|
||||
_scope!.Sections,
|
||||
frame);
|
||||
}
|
||||
|
||||
private void DrawMeshBatchRhi(
|
||||
IGpuPassEncoder encoder,
|
||||
IGpuFrame frame,
|
||||
GlobalMeshBuffer global,
|
||||
ObjectRenderBatch batch,
|
||||
Matrix4x4 viewProjection,
|
||||
|
|
@ -472,6 +484,10 @@ public sealed unsafe partial class ParticleRenderer
|
|||
"The shared mesh arena has no index store."),
|
||||
0,
|
||||
GpuIndexType.UInt16);
|
||||
WorldFrameSectionBinding.BindClipRegions(
|
||||
encoder,
|
||||
_scope!.Sections,
|
||||
frame);
|
||||
encoder.DrawIndexed(
|
||||
(uint)batch.IndexCount,
|
||||
instanceCount,
|
||||
|
|
@ -520,9 +536,8 @@ public sealed unsafe partial class ParticleRenderer
|
|||
Array.Resize(ref _preparedInstanceOffsets, count + 256);
|
||||
if (_instanceScratch.Length < count)
|
||||
Array.Resize(ref _instanceScratch, count + 256);
|
||||
int neededMeshFloats = count * MeshInstanceFloats;
|
||||
if (_meshInstanceScratch.Length < neededMeshFloats)
|
||||
_meshInstanceScratch = new float[neededMeshFloats + 256 * MeshInstanceFloats];
|
||||
if (_meshInstanceScratch.Length < count)
|
||||
_meshInstanceScratch = new MeshParticleGpuInstance[count + 256];
|
||||
|
||||
int billboardCount = 0;
|
||||
int meshCount = 0;
|
||||
|
|
@ -541,8 +556,7 @@ public sealed unsafe partial class ParticleRenderer
|
|||
{
|
||||
_preparedInstanceOffsets[i] = (uint)meshCount;
|
||||
WriteMeshGpuInstance(
|
||||
_meshInstanceScratch,
|
||||
meshCount++ * MeshInstanceFloats,
|
||||
ref _meshInstanceScratch[meshCount++],
|
||||
deferred.Mesh.Instance);
|
||||
}
|
||||
}
|
||||
|
|
@ -553,9 +567,9 @@ public sealed unsafe partial class ParticleRenderer
|
|||
_instanceScratch.AsSpan(0, billboardCount)))
|
||||
: default;
|
||||
_preparedMeshInstances = meshCount > 0
|
||||
? SectionOf(WriteVertexRing<float>(
|
||||
? SectionOf(WriteVertexRing<MeshParticleGpuInstance>(
|
||||
frame,
|
||||
_meshInstanceScratch.AsSpan(0, meshCount * MeshInstanceFloats)))
|
||||
_meshInstanceScratch.AsSpan(0, meshCount)))
|
||||
: default;
|
||||
_preparedAlphaCount = count;
|
||||
}
|
||||
|
|
@ -591,6 +605,7 @@ public sealed unsafe partial class ParticleRenderer
|
|||
{
|
||||
BindBillboardPipeline(
|
||||
encoder,
|
||||
RequireRhiFrame(),
|
||||
viewProjection,
|
||||
key.Additive,
|
||||
billboards,
|
||||
|
|
@ -632,6 +647,7 @@ public sealed unsafe partial class ParticleRenderer
|
|||
{
|
||||
DrawMeshBatchRhi(
|
||||
encoder,
|
||||
RequireRhiFrame(),
|
||||
global,
|
||||
batch,
|
||||
meshViewProjection,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue