Unable to sample custom struct in visual effects graph.

When using a custom struct comprised of different variable types (even when setting the stride to 4 bytes and calculating the stride and count in the graph manually) I’m unable to sample my graphics buffer in my visual effect graph.

It keeps throwing

Exception while compiling expression graph: System.InvalidOperationException: Diverging type usage for GraphicsBuffer : System.UInt32, System.Single

Is there a reason this isn’t possible?
Is the only workaround really to create a buffer for each type and feed those to the graph?

Hi @svenneve ,

You should be able to do something like this:

[VFXType(VFXTypeAttribute.Usage.GraphicsBuffer)]
struct CustomData
{
public bool someToggle;
public float size;
public Vector3 position;
}

You can find the supported types and check out some of the limitations by going to the VFX manual.
If you’ve looked at all of this and are still getting errors, please log an issue or share more info and we’ll take a look.

Actually… bool is not supported :(. Documentation is being updated but the change has not landed yet.

1 Like

Hi Vlad,

I’ve read that part of the manual, and I keep getting this error

ChargeCapTest : Exception while compiling expression graph: System.InvalidOperationException: Diverging type usage for GraphicsBuffer : System.UInt32, UnityEngine.Vector3
  at UnityEditor.VFX.VFXExpression+Context.PatchVFXExpression (UnityEditor.VFX.VFXExpression input, UnityEditor.VFX.VFXExpression targetExpression, System.Boolean insertGPUTransformation, System.Boolean patchReadAttributeForSpawn, System.Collections.Generic.IEnumerable`1[T] globalEventAttribute) [0x0021b] in C:\workspace\blitz_gt_unity_urp\Library\PackageCache\com.unity.visualeffectgraph@12.1.0\Editor\Expressions\VFXExpressionContext.cs:182 
  at UnityEditor.VFX.VFXExpression+Context+<>c__DisplayClass9_0.<Compile>b__0 (UnityEditor.VFX.VFXExpression e) [0x00034] in C:\workspace\blitz_gt_unity_urp\Library\PackageCache\com.unity.visualeffectgraph@12.1.0\Editor\Expressions\VFXExpressionContext.cs:235 
  at System.Linq.Enumerable+SelectArrayIterator`2[TSource,TResult].ToArray () [0x00012] in <d7943eff065e45feae53e008e0feacbe>:0 
  at System.Linq.Enumerable.ToArray[TSource] (System.Collections.Generic.IEnumerable`1[T] source) [0x0001f] in <d7943eff065e45feae53e008e0feacbe>:0 
  at UnityEditor.VFX.VFXExpression+Context.Compile (UnityEditor.VFX.VFXExpression expression) [0x0004e] in C:\workspace\blitz_gt_unity_urp\Library\PackageCache\com.unity.visualeffectgraph@12.1.0\Editor\Expressions\VFXExpressionContext.cs:229 
  at UnityEditor.VFX.VFXExpression+Context.Compile () [0x00024] in C:\workspace\blitz_gt_unity_urp\Library\PackageCache\com.unity.visualeffectgraph@12.1.0\Editor\Expressions\VFXExpressionContext.cs:63 
  at UnityEditor.VFX.VFXExpressionGraph.CompileExpressionContext (System.Collections.Generic.IEnumerable`1[T] contexts, UnityEditor.VFX.VFXExpressionContextOption options, UnityEditor.VFX.VFXDeviceTarget target, UnityEditor.VFX.VFXExpression+Flags forbiddenFlags) [0x000bf] in C:\workspace\blitz_gt_unity_urp\Library\PackageCache\com.unity.visualeffectgraph@12.1.0\Editor\Compiler\VFXExpressionGraph.cs:65 
  at UnityEditor.VFX.VFXExpressionGraph.CompileExpressions (System.Collections.Generic.IEnumerable`1[T] contexts, UnityEditor.VFX.VFXExpressionContextOption options) [0x000df] in C:\workspace\blitz_gt_unity_urp\Library\PackageCache\com.unity.visualeffectgraph@12.1.0\Editor\Compiler\VFXExpressionGraph.cs:188 
  at UnityEditor.VFX.VFXGraphCompiledData.Compile (UnityEditor.VFX.VFXCompilationMode compilationMode, System.Boolean forceShaderValidation) [0x002ef] in C:\workspace\blitz_gt_unity_urp\Library\PackageCache\com.unity.visualeffectgraph@12.1.0\Editor\Compiler\VFXGraphCompiledData.cs:1067 :

using this struct

        [VFXType(VFXTypeAttribute.Usage.GraphicsBuffer)]
        public struct ChargeFXData {
            public ChargeFXData(uint index, Vector3 v1, float lifetime) {
                CapIndex = index;
                StartPosition = v1;
                Lifetime = lifetime;
            }
            public uint CapIndex;
            public Vector3 StartPosition;
            public float Lifetime;
        }

with a buffer declared like so

buffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, chargeData.Length, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ChargeFXData)));

Thanks @gabriel-delacruz , I wasn’t aware! :slight_smile:

It’s a bit hard to tell; I don’t see anything obviously wrong with the code (haven’t tried with a constructor in the struct, but should be fine).

I’m shooting from the hip here, but a few things to check:

  • you are also setting your ChargeFXData struct data to the buffer GraphicsBuffer. i.e. something like:
    buffer.SetData(new ChargeFXData[desiredSize]);- you are linking your graphics buffer to the VFX instance, i.e. something like:
    vfx.SetGraphicsBuffer(m_ChargeFXDataID, buffer);- you don’t have multiple scripts with the same ChargeFXData struct in different namespaces (only 1 will be visible)
  • you have tried in your graph some really simple use case (i.e. just connecting your Lifetime data to particle life to confirm it’s not some unexpected use within the vfx graph)
  • you have switched scenes and the issue persists (if you modify a script with a graphics buffer you have already hooked to the VFX graph you may lose your binding, want to confirm this issue is persistant)
  • make sure the buffer type in your Sample Graphics Buffer operator (the one you can set by clicking no the gear icon) is the type you intended to use.

If all of these are fine and no one else has any ideas, if you could share a min repo we can take a look.

Hi Vlad,

The problem at this point doesn’t seem to be at the script level, but rather the vfx compiler (I think).
Just trying to compile the attached vfx graph already errors out.

7661137–956101–GBufferTestVFX.zip (4.6 KB)

Hi @svenneve ,

The struct you made should be just another type which should appear in your Sample Graphics Buffer operator. Can you confirm that you’ve set the operator type to your ChargeFXData struct?

You should be able to set the type to ChargeFXData via the gear icon and directly access all 3 properties. Currently, it looks like you are casting the Graphics buffer to a uint, Vector3 and float.

7661626--956182--zpc46wJcig.gif

2 Likes

You sir, are a life saver. I can’t believe that even after reading the manual entry so many times I just read over the actual entry in the sampler it self.

That fixed it.

On a side note, my workaround was splitting the 3 variable types over 3 buffers, is there a down or upside to either of the methods used? Performance wise?

1 Like

Glad it works! :slight_smile:

I checked with @PaulDemeulenaere and he shared the following:

2 Likes