【问题标题】:Is there a way to get an array of values from an array of blittable structs?有没有办法从 blittable 结构数组中获取值数组?
【发布时间】:2020-10-24 01:27:50
【问题描述】:

我有一个 blittable 结构数组,所以每个结构在内存中都是固定大小和顺序的。我希望从这个单一的结构数组中创建多个数组。这是结构:

[Serializable]
public struct SpriteRenderInstruction : IComparable<SpriteRenderInstruction>
{
    public int SpriteAtlas;
    public float4 Transform;
    public float2 SpriteSize;
    public float4 Uv;
    public float4 Color;
    public int SortingLayer;
    public int SortingOrder;

    public int CompareTo(SpriteRenderInstruction other)
    {
        if (this.SortingLayer != other.SortingLayer)
        {
            return this.SortingLayer - other.SortingLayer;
        }
        else if (this.SortingOrder != other.SortingOrder)
        {
            return this.SortingOrder - other.SortingOrder;
        }
        else
        {
            return this.SpriteAtlas - other.SpriteAtlas;
        }
    }
}

对SpriteRenderInstructions数组进行排序,然后我需要将它们变成Transforms数组、SpriteSizes数组、Uvs数组和Colors数组。由于这发生在每一帧,而且我正在处理固定大小的结构,我希望有一种方法可以在不创建副本的情况下获取这 4 个数组。我知道有使用 Linq 获取这些数组的方法:

float4[] transforms = spriteRenderers.Select(p => p.Transform).ToArray();
float4[] spriteSizes = spriteRenderers.Select(p => p.SpriteSize ).ToArray();
float4[] uvs = spriteRenderers.Select(p => p.Uv).ToArray();
float4[] colors = spriteRenderers.Select(p => p.Color).ToArray();

但是这些都创建了新的数组,我想避免为此分配内存。

【问题讨论】:

  • 会分配这么多内存吗?
  • 这是针对 Unity 中的渲染系统的,我正在尝试使用他们新的 DrawMeshIndirectProcedural API 和 ECS 框架的组合来查看一次可以在屏幕上绘制多少个精灵。我目前的目标是推送 10 万个精灵,并且每帧分配 4 个 10 万个元素的数组会大大降低性能。

标签: c# arrays struct


【解决方案1】:

不,您不能在不复制的情况下创建(例如)变换的数组(或跨度),因为数组(或跨度)的定义特征是同质值必须是连续的,但在这种情况下:值将连续 - 它们将分布在 SpriteRenderInstruction 的所有其他部分中。

如果您绝对需要它们作为数组,则需要复制;但是,您应该能够在帧之间重用现有缓冲区,并且只覆盖活动部分(并跟踪它!) - 即

float4[] transforms = Array.Empty<float4>();
// ^^^ retain these buffers between frames, presumably in a field

// etc
var len = spriteRenderers.Length;
if (len > transforms.Length)
{
    transforms = new float4[len]; // todo: possibly add padding
    // etc
}
for (int i = 0 ; i < spriteRenderers.Length; i++)
{
    var renderer = spriteRenderers[i];
    transforms[i] = renderer.Transform;
    // etc
}

记住不要看过去len(以防数字变小)

【讨论】:

  • 一个很好的解决方案,因为它解决了我不断分配的问题。
猜你喜欢
  • 2020-04-09
  • 1970-01-01
  • 1970-01-01
  • 2020-08-03
  • 1970-01-01
  • 2016-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多