Search Unity

Resolved Disabling Parts of VFX based on Texture Maps

Discussion in 'Visual Effect Graph' started by florianhanke, Oct 22, 2020.

  1. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    For a propagating fire effect I'm using a visual effect which spawns in positions provided by a 1-D texture, sequentially based on the particleId over the texture index:
    Screenshot 2020-10-22 at 21.14.59.png

    This works fine so far (positions are located on a grid for testing):
    Screenshot 2020-10-22 at 21.14.44.png

    I plan to have fires going out, so I'd like to disable some texture index positions and later re-enable them somewhere else (reusing that index in the texture).
    I don't know how to disable certain spawn locations.

    Since the particles are spawned in each position given by the texture as follows:
    Code (CSharp):
    1. uint width, height;
    2. attributeMap.t.GetDimensions(width, height);
    3. uint count = width * height;
    4. uint id = particleId % count;
    5. uint y = id / width;
    6. uint x = id - y * width;
    7. float3 value = (float3)attributeMap.t.Load(int3(x, y, 0));
    8. value = (value  + valueBias) * valueScale;
    9. position = value;
    So my assumption was that I could use the following for disabling particles for a certain texture index (position):
    Screenshot 2020-10-22 at 21.15.19.png
    (particleId % count) as index for the X coord when sampling a second texture containing just 0 or 1 in the red component, then using that – just for testing – for the alpha cutoff, which does not show the particles if 1, but does if 0.
    This does not work - all particles are still shown, as far as I can see (at least none of the fire columns are removed).

    The textures look as follows:
    Screenshot 2020-10-22 at 21.15.32.png
    So the EnabledMap is just a stripey 0/1 map, and the PositionMap is the positions on a 10x10 grid.

    What's the best way of disabling visual effects parts where the visual effect is distributed over a set of positions given by a texture?
    (A dirty idea is to just move them far out of sight via position map, but I'd rather do a clean solution!)
     
  2. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    P.S: I probably have accidentally overlooked that it's not texture indices, but UVs when Sampling Texture 2D (duh). Trying again…
     
  3. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    Ok, that was it!

    Now correctly setting the UV sample:
    Screenshot 2020-10-23 at 10.41.25.png

    Every second column is now not showing anymore:
    Screenshot 2020-10-23 at 10.41.37.png

    There's probably a better way of "disabling" certain positions than setting the alpha threshold…?
     
  4. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    Answering my own question again:
    Screenshot 2020-10-23 at 11.49.11.png

    To the devs: Thanks for your work on the VFX graph!
     
    VladVNeykov likes this.
  5. VladVNeykov

    VladVNeykov

    Unity Technologies

    Joined:
    Sep 16, 2016
    Posts:
    550
    Hi @florianhanke ,

    Looks like you figured it out on your own in no time! :)
    Just FYI, we added also a Get Texture2D Dimensions operator, so if your PositionCount == the texture width, you might not need to separately change that value but derive it from here:
     

    Attached Files:

    florianhanke likes this.
  6. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    Oooh, thank you – I was looking for that, but could not find it. I guess that's a version 10+ feature? (I'm still on Version 9.0.0-preview.54, as I'm still on 2020.1)
     
  7. VladVNeykov

    VladVNeykov

    Unity Technologies

    Joined:
    Sep 16, 2016
    Posts:
    550
    Ah, yup, it got added in 10.0.0.
    Well, know then that the upgrade future is looking bright!
     
    florianhanke likes this.
  8. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    Ha! Thank you – will upgrade as soon as I can :) Looking forward to other new blocks in the 10+ version VFX Graph…
     
    VladVNeykov likes this.
  9. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,325
    @florianhanke how do you create a 1D texture? 2D render texture with ySize=1? And why the 0.5 in V?
    I'm currently unpacking particle id as uv and the op takes 4 modulos and 2 divs, that's a bit much.
     
  10. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    Yes to the ySize=1, and I just take the value from half-height. Any other value should work also. I hope that helps!
     
    laurentlavigne likes this.
  11. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,325
    It does yeah, helps simplifying things.
     
    florianhanke likes this.
  12. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    Note that I’ve simplified my solution above by combining the EnabledMap into the alpha of the PositionMap, saving one texture.
     
  13. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,325
    I was thinking about combining occupancy and gameplay map together like you but since this is only one vfx graph asset containing many graphs I'm sure the value from the texture sampling is cached for all graphs.
    What do you use this for by the way? I'm trying to replicate the good old shuriken effect I had with Emit() on c# with a gpu only thing, so far it's a big fail as I am unable to get a value from a texture map with particle index. I might stick to shuriken, or maybe there is a way to emit particles from c#, maybe with vfx events.
     
  14. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    I'm not sure I understand what you are saying. I do it to halve the amount of data that is pushed to and stored in the graphics memory.
    I have never worked with Shuriken, so I don't know what the effect is you mention, I'm afraid. I'm using it to simulate a spreading fire. Here it is when in almost full swing:
    fire2.gif
    To add/remove fire emitters end I have a system that maps fire entities to texture indices and increases/reduces texture sizes when it must/can. Whenever a fire is added/removed, I apply the texture. I just use a single instance of the VFX effect for now.

    I did the above after seeing @LudiKha's impressive fire simulation:
     
    Last edited: Dec 16, 2020
    laurentlavigne likes this.
  15. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,325
    Gorgeous effect.
    Do you know how the value bias in set alive from map works?
    I tried that to tell the map block to read only the alpha channel and it's not doing a thing
    upload_2020-12-16_11-46-35.png
     
  16. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    It’s either alive = map value * scale + bias or alive = (map value + bias) * scale (can’t check my laptop right now to confirm). Either way, input the vector into the value scale instead of the bias.
     
  17. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    P.S: Assuming you intend to do a similar thing as I did above, why do you use a Random Constant for the sample mode and not e.g. Sequential?
     
  18. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,325
    ah yeah that makes sense, I connect 0,0,0,1 to scale and that doesn't work either
    i use random constant because i don't want to spawn a particle at each point of the map, they're lava bubbles which i spawn when the position is valid (alpha =1) and the blissmap is = 0
    @VladVNeykov, any google doc with more documentation on these types of blocks and use case?
     
  19. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    See https://docs.unity3d.com/Packages/c...ph@10.2/manual/Block-SetAttributeFromMap.html (see Sampling Mode)
    Using random means you’re randomly pulling values from the map. You probably want the alive value for a given position, right, not a random alive value?
     
  20. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,325
    very cool, I see that v10 is getting a lot of love, v8.3 doc is empty, as soon as 2020.2 is stable enough I'll have to move over.

    yeah that's right, that's why I keep the seed=0 for both the position block and the alive block
     
  21. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    Got it! That should be fine.

    I compare the value for alive against 1 to ensure I input true or false. Unsure what counts as true/false for the alive input when a number is provided. 0 is probably false. Are you providing 0s and 1s in the alive map?

    I’d start inputting fixed values to alive, or hooking up your alive input to a size multiplier or some other block that modifies the output to see the value that is input to debug. Or even use a texture with numbers on it to see the exact number that is input.
    Anyway, good luck!