Search Unity

Question How to Set MaterialPropertyAuthoring for float[] ?

Discussion in 'Graphics for ECS' started by Wayne-wyj, Jun 7, 2023.

  1. Wayne-wyj

    Wayne-wyj

    Joined:
    Dec 16, 2020
    Posts:
    41
    I know how to set MaterialPropertyAuthoring for single type property ,just like below:

    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.Mathematics;
    3. using Unity.Rendering;
    4.  
    5. [MaterialProperty("_Length")]
    6. public struct CustomMaterialPropertyLength : IComponentData
    7. {
    8.     public float LengthValue;
    9. }
    10.  
    11. [UnityEngine.DisallowMultipleComponent]
    12. public class CustomMaterialPropertyLengthAuthoring : UnityEngine.MonoBehaviour
    13. {
    14.     [Unity.Entities.RegisterBinding(typeof(CustomMaterialPropertyLength), nameof(CustomMaterialPropertyLength.LengthValue))]
    15.     public float Length=5;
    16.  
    17.     class CustomMaterialPropertyLengthBaker : Unity.Entities.Baker<CustomMaterialPropertyLengthAuthoring>
    18.     {
    19.         public override void Bake(CustomMaterialPropertyLengthAuthoring authoring)
    20.         {
    21.             CustomMaterialPropertyLength component = default(CustomMaterialPropertyLength);
    22.             component.LengthValue = authoring.Length;
    23.             var entity = GetEntity(TransformUsageFlags.Renderable);
    24.             AddComponent(entity, component);
    25.         }
    26.     }
    27. }
    But, when it turns to be float[] , it can't work anymore,because it is managed type;
    Code (CSharp):
    1. [MaterialProperty("_LengthArray")]
    2. public struct MaterialPropertyLengthArray : IComponentData
    3. {
    4.     public float[] LengthArray;
    5. }
    upload_2023-6-8_0-0-11.png

    Then, I tried to change it into NativeArray
    Code (CSharp):
    1. [MaterialProperty("_LengthArray")]
    2. public struct MaterialPropertyLengthArray : IComponentData
    3. {
    4.     public NativeArray<float> LengthArray;
    5. }
    6.  
    7. [UnityEngine.DisallowMultipleComponent]
    8. public class MaterialPropertyLengthArrayAuthoring : UnityEngine.MonoBehaviour
    9. {
    10.     [Unity.Entities.RegisterBinding(typeof(MaterialPropertyLengthArray), nameof(MaterialPropertyLengthArray.LengthArray))]
    11.     public float[] LengthArray = new float[]{1,1,1,1,1,1,1,1};
    12.  
    13.     class MaterialPropertyLengthArrayBaker : Unity.Entities.Baker<MaterialPropertyLengthArrayAuthoring>
    14.     {
    15.         public override void Bake(MaterialPropertyLengthArrayAuthoring authoring)
    16.         {
    17.              MaterialPropertyLengthArray component;
    18.              component.LengthArray = new NativeArray<float>(authoring.LengthArray,Allocator.Persistent);
    19.              var entity = GetEntity(TransformUsageFlags.Renderable);
    20.              AddComponent(entity, component);
    21.         }
    22.     }
    23. }
    But there is error like this .
    upload_2023-6-8_0-1-49.png

    I want to change this componentData in runtime (PerInstance) , so BlobAsset doesn't work for this.
    ISharedComponent is not for AddComponent(xxxx).

    Is there anyone who knows about this?
     
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,255
    ECS Material Property Overrides have to be fixed sized. For dynamic sized stuff, you need a separate graphics buffer and set that as a global shader buffer, than have normal ECS material property overrides index into it.
     
  3. Wayne-wyj

    Wayne-wyj

    Joined:
    Dec 16, 2020
    Posts:
    41
    It is ok to be fixed size array,like float[8] .And I hope it works as perInstance property , not global float array.
    But I don't know how to declare it in IComponentData. Could you please give some samples?
     
  4. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,255
    Yes. Though Shader Graph won't know how to generate it so you'll have to make the shader yourself (or inject custom code into Shader Graph).
    It just gets raw MemCpy-ed, so you could have 8 individual floats in your struct, or two float4s, or a float2x4. Totally up to you.

    I don't have any examples for fixed sized arrays yet, but I do have some real-world examples of indexing into separate buffers, which I use for skinned mesh animation rendering. Is that something you'd be interested in?
     
  5. Wayne-wyj

    Wayne-wyj

    Joined:
    Dec 16, 2020
    Posts:
    41
    OK , I know it. Actually, they are totally certain fields in struct, not like float[8] in shader.There will be many propertys in shader to fit feild in struct , but it can work. It seems that there is no better solution.