Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question [URP] Problems using GPU Instancing and UV2 in ParticleSystem

Discussion in 'General Graphics' started by studiobside60, May 2, 2024.

  1. studiobside60


    Nov 27, 2023
    I am currently developing on 2022.3.12f1.

    I discovered a problem while testing UV2 to implement Mesh GPU Instancing of a Particle System.

    What I want is to be able to change the predefined UV channels in the material when using Mesh GPU Instancing. For example, switching between UV and UV2.

    Switching between UV and UV2 works perfectly when not using Mesh GPU Instancing, but switching UV channels does not work when using it.

    In the GIF image below you can see the transition between UV and UV2 when Enable Mesh GPU Instancing is disabled.

    However, channel switching for UV and UV2 does not occur when using Mesh GPU Instancing, as shown in the image below.

    Mesh has 4 UV channels as follows.

    The shader used the basic Particle Unlit built into URP.

    I wonder if there is a problem with my settings or a problem with URP.

    I wrote a custom shader and tested that part, but it didn't solve the problem. Am I missing something?
  2. richardkettlewell


    Unity Technologies

    Sep 9, 2015
    I have a feeling that, because the CPU doesn't write the mesh UVs when using gpu instancing (we just use the mesh data on the GPU exactly as it was imported) that the UV's are always in sequential order, regardless of how you order them in the Custom Vertex Streams UI.

    All 4 UVs are probably available in the shader regardless of whether they even exist in the Custom Vertex Streams UI.

    I've read the code a bit, and I feel that what I'm saying is correct, but, I can't be 100% sure just from reading the code for a few minutes :)

    Technically this is a bug, but to be honest, I don't think you've much chance of seeing a fix, because we aren't assigning much resources to this system anymore. And even if you did see a fix, my guess it would be to limit the UI to prevent you from setting it up like this, rather than a fix to really make the use-case work.

    Thank you for raising it though!
    studiobside60 likes this.
  3. studiobside60


    Nov 27, 2023
    Thank you for answer.

    I found the cause of the problem while writing a custom shader.

    Richard as you said, when GPU Instancing was used, the CPU was not packing the Mesh's UV information into one Texcoord.

    On the other hand, I found that when GPU Instancing is disabled, depending on the layout of the Vertex Streams, the CPU packs the Mesh's UV information into one Texcoord.xyzw and passes it to the shader.

    So, I modified the Attributes structure and the UV distribution logic of the Vertex Shader depending on whether UNITY_PARTICLE_INSTANCING_ENABLED is defined.

    Below is the Attributes structure.

    struct Attributes
    float4 positionOS : POSITION;
    float4 color : COLOR;
    float3 normalOS : NORMAL;
    float4 tangentOS : TANGENT;
    float4 uv : TEXCOORD0;
    float4 uv1 : TEXCOORD1;

    Below is the logic for distributing UVs in the Vertex Shader.

    void InitializeUVChannels(Attributes input)
    UVChannels[0] = input.uv.xy;
    UVChannels[1] = input.uv1.xy;
    UVChannels[1] =;

    I believe that the layout of Vertex Streams relative to UVs can be confusing to users when GPU instancing is enabled.
    I think it would be helpful to have a simple tooltip message or warning text.
    Last edited: May 3, 2024
    richardkettlewell likes this.