Search Unity

Resolved DrawMeshInstanced allocating like mad?

Discussion in 'General Graphics' started by laurentlavigne, Sep 3, 2020.

  1. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,366
    see those big GC spikes?
    i'm not allocating anything, i think but i might have missed something
    if the code's not wrong then DrawMeshInstanced allocates like crazy
    iznogood

    upload_2020-9-3_3-13-12.png
    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using TreeEditor;
    5. using UnityEngine;
    6. using UnityEngine.Rendering;
    7. using UnityEngine.Serialization;
    8. using Random = UnityEngine.Random;
    9.  
    10. public class ImmediateInstantiator : MonoBehaviour
    11. {
    12.     public Mesh mesh;
    13.     public Material material;
    14.     Vector3[] positions;
    15.     Matrix4x4[] matrices;
    16.     const int MAX = 1022;
    17.     public int howManyMatrices = 10000;
    18.     public Vector2 randomness = Vector2.one * 50;
    19.     MaterialPropertyBlock block;
    20.  
    21.     void OnEnable()
    22.     {
    23.         MakeRandomMatrices();
    24.     }
    25.  
    26.     void MakeLightProbesPropertyBlock()
    27.     {
    28.         // Calculate probes at these positions
    29.         var lightprobes = new UnityEngine.Rendering.SphericalHarmonicsL2[howManyMatrices];
    30.         var occlusionprobes = new Vector4[howManyMatrices];
    31.         LightProbes.CalculateInterpolatedLightAndOcclusionProbes(positions, lightprobes, occlusionprobes);
    32.         // Put them into the MPB
    33.         block = new MaterialPropertyBlock();
    34.         block.CopySHCoefficientArraysFrom(lightprobes);
    35.         block.CopyProbeOcclusionArrayFrom(occlusionprobes);
    36.     }
    37.  
    38.     void MakeRandomMatrices()
    39.     {
    40.         matrices = new Matrix4x4[howManyMatrices];
    41.         positions = new Vector3[howManyMatrices];
    42.         for (int i = 0; i < howManyMatrices; i++)
    43.         {
    44.             positions[i] = Random.insideUnitSphere * randomness.y;
    45.             positions[i].y = 0;
    46.             matrices[i] = Matrix4x4.TRS(positions[i], Quaternion.AngleAxis(positions[i].x, Vector3.up), Vector3.one);
    47.         }
    48.         block = new MaterialPropertyBlock();
    49.         MakeLightProbesPropertyBlock();
    50.     }
    51.  
    52.     void WobbleScale()
    53.     {
    54.         for (int i = 0; i < howManyMatrices; i++)
    55.             matrices[i] = Matrix4x4.TRS(positions[i], Quaternion.AngleAxis(positions[i].x, Vector3.up), (float)(Math.Sin(Time.time + positions[i].x)+2)*Vector3.one);
    56.     }
    57.  
    58.     void Update()
    59.     {
    60.         // if (matrices == null || howManyMatrices != matrices.Length)
    61.         //     MakeRandomMatrices();
    62.         //WobbleScale();
    63.         for (int i = 0; i < howManyMatrices; i += MAX)
    64.         {
    65.             Graphics.DrawMeshInstanced(mesh, 0, material, matrices.SubArray(i, Mathf.Min(matrices.Length - i, MAX)), Mathf.Min(matrices.Length - i, MAX), block, ShadowCastingMode.On, true, 1, Camera.current, LightProbeUsage.CustomProvided); // UseProxyVolume, lppv);
    66.         }
    67.     }
    68. }
    69.  
    70. public static class Extension
    71. {
    72.     public static T[] SubArray<T>(this T[] data, int index, int length)
    73.     {
    74.         T[] result = new T[length];
    75.         System.Array.Copy(data, index, result, 0, length);
    76.         return result;
    77.     }
    78. }
     
  2. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,366
    duh
    the array copy