Search Unity

How to correctly use BatchRendererGroup.GetBatchScalarArray

Discussion in 'General Graphics' started by Baggers_, Aug 6, 2020.

  1. Baggers_

    Baggers_

    Joined:
    Sep 10, 2017
    Posts:
    98
    Unity 2019.4 - Using Unity's existing rendering architecture (not SRP)

    Hi folks, I've been able to use BatchRendererGroups succesfully with MaterialPropertyBlocks to set values on a per-instance shader property. However it looks like I should be able to do the same using GetBatchScalarArray and so far I've not been able to get it to work. My test is below.

    The test is very simple. We expose a float property called _BRG_TestVal which controls an x offset applied to verts in the vertex stage.

    On the cpu side I have working code that shows that the approach using MaterialPropertyBlocks works. The issue is that if I comment out this bit:

    Code (CSharp):
    1.    _matBlockForBatch.SetFloatArray(_shaderPropId, new float[] { wobble });
    2.    _brg.SetInstancingData(_batch, 1, _matBlockForBatch);
    and uncomment this bit

    Code (CSharp):
    1.    // var instVals = _brg.GetBatchScalarArray(_batch, _shaderPropId);
    2.    // instVals[0] = wobble;
    I no longer see the horizontal translation (and so we know the property is not being set correctly)

    Any clues you can give me as to how to correctly use GetBatchScalarArray would be very much appreciated.

    Cheers

    Shader:
    Code (CSharp):
    1. // Made with Amplify Shader Editor
    2. Shader "BatchRenderGroupTest"
    3. {
    4.    Properties
    5.    {
    6.        _BRG_TestVal("_BRG_TestVal", Float) = 0
    7.        [HideInInspector] __dirty( "", Int ) = 1
    8.    }
    9.  
    10.    SubShader
    11.    {
    12.        Tags{ "RenderType" = "Opaque"  "Queue" = "Geometry+0" }
    13.        Cull Back
    14.        CGPROGRAM
    15.        #pragma target 3.0
    16.        #pragma multi_compile_instancing
    17.        #pragma surface surf Standard keepalpha addshadow fullforwardshadows vertex:vertexDataFunc
    18.        struct Input
    19.        {
    20.            half filler;
    21.        };
    22.  
    23.        UNITY_INSTANCING_BUFFER_START(BatchRenderGroupTest)
    24.            UNITY_DEFINE_INSTANCED_PROP(float, _BRG_TestVal)
    25. #define _BRG_TestVal_arr BatchRenderGroupTest
    26.        UNITY_INSTANCING_BUFFER_END(BatchRenderGroupTest)
    27.  
    28.        void vertexDataFunc( inout appdata_full v, out Input o )
    29.        {
    30.            UNITY_INITIALIZE_OUTPUT( Input, o );
    31.            float _BRG_TestVal_Instance = UNITY_ACCESS_INSTANCED_PROP(_BRG_TestVal_arr, _BRG_TestVal);
    32.            float4 appendResult7 = (float4(_BRG_TestVal_Instance , 0.0 , 0.0 , 0.0));
    33.            v.vertex.xyz += appendResult7.xyz;
    34.        }
    35.  
    36.        void surf( Input i , inout SurfaceOutputStandard o )
    37.        {
    38.            float4 color1 = IsGammaSpace() ? float4(1,0,0,0) : float4(1,0,0,0);
    39.            o.Albedo = color1.rgb;
    40.            o.Alpha = 1;
    41.        }
    42.  
    43.        ENDCG
    44.    }
    45.    Fallback "Diffuse"
    46.    CustomEditor "ASEMaterialInspector"
    47. }
    Cpu-side
    Code (CSharp):
    1.  
    2. using UnityEngine;  
    3. using UnityEngine.Rendering;
    4. using Unity.Jobs;
    5.  
    6. public class BatchRendererGroupTest : MonoBehaviour
    7. {
    8.     public GameObject ExampleObject; // an object that is my sanity check that the shader works without using BatchRendererGroup
    9.     BatchRendererGroup _brg;
    10.     int _batch;
    11.     int _shaderPropId;
    12.  
    13.     MaterialPropertyBlock _matBlockForExampleObj;
    14.     MaterialPropertyBlock _matBlockForBatch;
    15.  
    16.     void OnEnable()
    17.     {
    18.         _brg = new BatchRendererGroup(CullingCallback);
    19.  
    20.         var mat = ExampleObject.GetComponent<MeshRenderer>().sharedMaterial;
    21.         var mesh = ExampleObject.GetComponent<MeshFilter>().sharedMesh;
    22.  
    23.         _matBlockForExampleObj = new MaterialPropertyBlock();
    24.         _matBlockForBatch = new MaterialPropertyBlock();
    25.  
    26.         ExampleObject.GetComponent<MeshRenderer>().GetPropertyBlock(_matBlockForExampleObj);
    27.  
    28.         _matBlockForBatch.SetFloatArray(_shaderPropId, new float[] { 0 });
    29.         _batch = _brg.AddBatch(mesh, 0, mat, 0, castShadows: ShadowCastingMode.On, receiveShadows: true, invertCulling: false,
    30.                                bounds: new Bounds(Vector3.one * 20, Vector3.one * 20), instanceCount: 1, customProps: _matBlockForBatch,
    31.                                associatedSceneObject: null);
    32.  
    33.         _shaderPropId = Shader.PropertyToID("_BRG_TestVal");
    34.     }
    35.  
    36.     void OnDisable()
    37.     {
    38.         _brg.Dispose();
    39.     }
    40.  
    41.     void Update()
    42.     {
    43.         var wobble = Mathf.Sin(Time.time * 6);
    44.  
    45.         // Showing that instancing with the MaterialPropertyBlock works
    46.         _matBlockForBatch.SetFloatArray(_shaderPropId, new float[] { wobble });
    47.         _brg.SetInstancingData(_batch, 1, _matBlockForBatch);
    48.  
    49.         var transforms = _brg.GetBatchMatrices(_batch);
    50.         transforms[0] = Matrix4x4.Translate(new Vector3(0, wobble, 0));
    51.  
    52.         // - This didnt work
    53.         // var instVals = _brg.GetBatchScalarArray(_batch, _shaderPropId);
    54.         // instVals[0] = wobble;
    55.  
    56.         // Just to prove to myself that the instance property is working when not using BatchRendererGroup
    57.         _matBlockForExampleObj.SetFloat(_shaderPropId, wobble);
    58.         ExampleObject.GetComponent<MeshRenderer>().SetPropertyBlock(_matBlockForExampleObj);
    59.     }
    60.  
    61.     // Not relevent, just dummy culling
    62.     JobHandle CullingCallback(BatchRendererGroup rendererGroup, BatchCullingContext cullingContext)
    63.     {
    64.         for (var batchIndex = 0; batchIndex < cullingContext.batchVisibility.Length; ++batchIndex)
    65.         {
    66.             var batchVisibility = cullingContext.batchVisibility[batchIndex];
    67.  
    68.             for (var i = 0; i < batchVisibility.instancesCount; ++i)
    69.             {
    70.                 cullingContext.visibleIndices[batchVisibility.offset + i] = i;
    71.             }
    72.  
    73.             batchVisibility.visibleCount = batchVisibility.instancesCount;
    74.             cullingContext.batchVisibility[batchIndex] = batchVisibility;
    75.         }
    76.         return default;
    77.     }
    78. }
    79. }
     
  2. Baggers_

    Baggers_

    Joined:
    Sep 10, 2017
    Posts:
    98