Search Unity

Question How to preload shader in VFX graph?

Discussion in 'Visual Effect Graph' started by bitinn, Jan 10, 2022.

  1. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    Hi,

    Let's say I have complex vfx graph asset that have around 15 material shader and 30 compute shader generated.

    At runtime this is creating a performance problem for us as the "CreateGPUProgram" (aka shader upload task) is taking a lot of time on the render thread.

    - Is there a way to preload/prewarm these shaders within VFX Graph?

    - If not, how can we reduce these costs?

    - I see these CreateGPUProgram are under the RenderShadowMaps call, but none of these particles cast shadows, and I have use SimpleLit as shader and disable shadow receive. Can anyone suggest what other settings could help reduce render thread cost?

    We are on Unity 2020 LTS with VFX Graph 10.

    Thx!
     
    ABCptt likes this.
  2. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    I have tested on 2 different machine, one with highend AMD CPU + GTX 3080, and another with Intel i7 + GTX 1660, and it appears the CreateGPUProgram is much slower on latter machine.

    But what affects the shader upload time more, CPU or GPU?? Processor or Bandwidth??

    Another problem is, I have already added my VFX's shaders to a Shader Variant Collection, and with Shader compilation log enabled, it shows that my shader is compiled on game launch.

    But still these shaders are not uploaded until VFX is enabled and played
    .

    Can anyone advise me on how to reduce this overhead so my main thread is not stalled due to Shader upload??

    (PS: 3080 takes 2ms to upload all shaders for this VFX, while 1660 takes 20~30ms; in addition I can see the upload always stall on the last few shaders, but the order of shader upload isn't deterministic, which suggest the cause of problem is 1660 are at its capacity.)
     
  3. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    Furthermore, I think I need a bit help understanding if putting ShaderVariantCollection in the preload list actually warmup these shaders (aka push these shaders onto GPU) or not.
     
  4. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    I tried externalizing these VFX graph shaders and then put them in shader variant collection.

    Still no luck, VFX graph shaders are still uploaded to GPU only when it becomes active.
     
  5. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    961
    I tried added the VFX graph asset to preloaded asset list, again no luck, still see the CreateGpuProgram when vfx play.

    Then I tried to create a monobehaviour script, reference the shader variant collection, then warm up manually before VFX play. Still the CreateGpuProgram is there.

    Note to Unity team: perhaps this shouldn't happen? Why is most CreateGpuProgram on a single job when it comes to VFX graph??

    (it's a mere 2ms on my 3080, but on 1660 it's 20~30ms)

    Screenshot 2022-01-10 211456.jpg
     
    fxlange and ABCptt like this.
  6. maxxa05

    maxxa05

    Joined:
    Nov 17, 2012
    Posts:
    186
    I have a similar issue, did you find a solution?
     
  7. peeweekVFX

    peeweekVFX

    Joined:
    Oct 19, 2015
    Posts:
    14
    Got something interesting about ShaderVariantCollections and VFX Graph, from what I understood, the warmUp only seem to work when it is done after loading the scene where the VFX are located. I haven't tested yet effects that are spawned from code though.

    My first tests were to preload everything at game's startup, but I still got the Shader.CreateGpuProgram in my main scene.

    However, the stalls involved by the WarmUp of the ShaderVariantCollections are a mess, and it even softlocks my game if I attach my profiler :(
     
  8. Caparrini

    Caparrini

    Joined:
    Jun 21, 2017
    Posts:
    63
    Same is happening to me and I tried all the before mentioned approaches before finding this post. Has anyone find a solution for this?