Disabling Parts of VFX based on Texture Maps

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:

This works fine so far (positions are located on a grid for testing):

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:

uint width, height;
attributeMap.t.GetDimensions(width, height);
uint count = width * height;
uint id = particleId % count;
uint y = id / width;
uint x = id - y * width;
float3 value = (float3)attributeMap.t.Load(int3(x, y, 0));
value = (value  + valueBias) * valueScale;
position = value;

So my assumption was that I could use the following for disabling particles for a certain texture index (position):


(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:
6446925--721716--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!)

P.S: I probably have accidentally overlooked that it’s not texture indices, but UVs when Sampling Texture 2D (duh). Trying again…

Ok, that was it!

Now correctly setting the UV sample:

Every second column is now not showing anymore:

There’s probably a better way of “disabling” certain positions than setting the alpha threshold…?

Answering my own question again:

To the devs: Thanks for your work on the VFX graph!

1 Like

Hi @florianhanke ,

Looks like you figured it out on your own in no time! :slight_smile:
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:

6449070--722073--upload_2020-10-23_12-11-8.png

1 Like

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)

Ah, yup, it got added in 10.0.0.
Well, know then that the upgrade future is looking bright!

1 Like

Ha! Thank you – will upgrade as soon as I can :slight_smile: Looking forward to other new blocks in the 10+ version VFX Graph…

1 Like

@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.

Yes to the ySize=1, and I just take the value from half-height. Any other value should work also. I hope that helps!

1 Like

It does yeah, helps simplifying things.

1 Like

Note that I’ve simplified my solution above by combining the EnabledMap into the alpha of the PositionMap, saving one texture.

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.

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:
6626743--755302--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:
https://www.youtube.com/watch?v=VUU4VRKCvV0

1 Like

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
6629938--755854--upload_2020-12-16_11-46-35.png

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.

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?

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?

See https://docs.unity3d.com/Packages/com.unity.visualeffectgraph@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?

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