What is your Alpha/Opacity Mask/Clip/Erode Animation workflow like?

…to recapitulate
from here

Color Burn 1 - (1-dest) / src
Linear Burn dest + src- 1

target = destination (bottom layer)
blend = source (top layer)

2 Likes

What are your thoughts on remapping with a texture atlas instead of using smoothstep? I get more control, but the setup is annoying and the texture read might be slower than smoothstep.

Do you mean a look up texture when you say “texture atlas”? Like a 2D gradient which remaps the values via gradient mapping?

I’m not sure what you mean with remapping with a texture atlas. Do you have a different texture per step of animation? Do you mean lut?

The reasons why I choose to use smoothstep:

  1. Animating from 0 to 1 just makes sense to me, you can go into a curve editor inside of cascade and just animate the value there and it will make sense inside that editor as well.
  2. Smoothstep is an hlsl command.
    (Unreal does this thing where every node is a variable defined as a combination of other variables and values. adding nodes therefore adds a certain cost and complexity to your shader.)
    So it should in theory be more optimised then combining addition and multiplication to achieve the same result. (Not that addition and multiplication are expensive, but still)
  3. Smoothstep is, well, it’s as smooth function, it doesn’t leave ugly lines and artifacts.

Back to your question,

  • Texture atlases are giant and expensive on memory, so I wouldn’t use them in this case.
  • Luts are a great idea however if you want colours, they are so much easier to use then having to manualy manage colours.

Thing is, even when I use luts for something like this, I tend to remap my values first, before I feed them into the lut.

Adds another texture sampler and it’s not very friendly for tweaking because you have to change, save and reload your LUT all the time but here is an example how you can change remapping and timing with just one small 2D LUT:

12 Likes

Oh boi, I should have used the right Unreal terminology “Curve Atlas”, which would save you guys some trouble writing down arguments :slightly_smiling_face:

That’s correct for colors, but I’m talking about only changing grey values, which works like remapping. Basically, you end up remapping 2048 different ranges with 1 single 2048x2048 texture. With that size most artifacts are gone, but sometimes you mix up the range and can get away with less.

I can’t believe you thought I’m talking about actually importing/exporting single grey scale textures when Curve Atlases exist and Jan was praising them like a messiah a while ago :smiley: Anyway, hopefully with the right term you can share another thought :slightly_smiling_face:

1 Like

This is an excellent description of smoothstep, and is really straightforward and well illustrated!

Wanted to chime in a bit and add a few things that a kind graphics wizard once shared with me.

The output of the hlsl intrinsic smoothstep is actually a curve, which looks sort of like this:
image
This is excellent if you’re wanting this sort of result but if you’re expecting a linear response between your min and max inputs, be prepared for this!

The under the hood code of the smoothstep looks like this (using float as an example, source)

float smoothstep(float a, float b, float x)
{
    float t = saturate((x - a)/(b - a));
    return t*t*(3.0 - (2.0*t));
}

The second line there is the polynomial part that gives you the curve drawn above. If you are arithmetic bound in your shader and want to save instructions, you can cut out that part, and will be left with the linear remapping part of the smoothstep. While it is a hlsl intrinsic, there’s nothing on the gpu hardware that I know of that makes any difference, you’re still paying for all the instructions listed above. Personally, I use this cheaper version 90% of the time, since you can usually not tell the difference and you’re saving instructions on big overdraw heavy particles.

When doing alpha ramps I usually do something like this:

float smoothstep_cheap(float Min, float Max, float A)
{
	return saturate((A - Min) / (Max - Min));
}

float RevealRamp(float alphaMask, float revealValue, float revealWidth)
{
	float widthplusone = revealWidth + 1.0;
	return smoothstep_cheap(1.0f, widthplusone, alphaMask + (revealValue * widthplusone));
}

This allows me to use a single ‘revealValue’ control, where 0 returns a masked out result, and 1 returns the complete alpha. It also allows you to have a consistent or separately controlled width parameter.

One followup note on the texture/curve lookups - this may be totally the way to go, but it all depends on where your shader bottlenecks are - if you are arithmetic bound, or texture bound. Make friends with your local graphics wizards who, in my experience, can generally help you navigate this stuff!

8 Likes

Hermite interpolation? Wah. :dizzy_face:

If I’m looking at this right, all this is doing is averaging (or perhaps you could say… smoothing) out the values, yes? I mean, wouldn’t that be easier to say for all involved. Man… jargon!

That said… cool. Learned something.

I love this. Using the UV Distort strictly as the shape control, and the LUT strictly as the grade. That is some quality out of the box thinking. Even if this is an old trick, I didn’t know it! It’s new to me!

8 Likes

I learned it from Fallout 4 where they use 2D Lut for Color and also for shaping the alpha: Fallout 4 – The Mushroom Case | Simon schreibt.

3 Likes

It is very visual though.
If I think about it, I get how this works, but at the same time my head can’t seem to keep track of what is happening, haha.
I’ll have to try it myself at some point :smiley:

1 Like

Thanks dude, that’s really a new way for me:smiley_cat:

2 Likes

after i saw this viedo https://www.youtube.com/watch?v=yMuDva2Vh9I&t=7s,

i use smooth step too is so good to make dissolve animate

2 Likes

Smoothstep Video by Ben Cloward:

2 Likes

I wanted to extend this topic about a detail. Thanks @Niels for the initial post of the material.

As long as the softness is 0.0 this material works perfect:


UcLL3fGz0n

But as soon as you use a smoothness you see, that at the beginning of the fading, a small portion is never getting white:


uwLPrX6hsO

What I like to do: Instead of adding the edgeHardness (which should be called softness) to the Max, I subtract it from Min. Now we fixed the left side but of course the right side doesn’t fade 100% as we want.


uFgnSX8x3Y

To fix that, I add the edgeSoftness to the incoming Alpha Fade values but multiplied by the Alpha Fade value itself:


Xn6UelEbpV

Now the mask fades in perfectly on both sides and can be as smooth as it wants :smiley:

15 Likes

Great tweet by Matt Ostertag about erosion:
https://twitter.com/matt_ostertag/status/1488489875766661122?s=20&t=Ikl8gRNtEwOylN4ZCHsIVg

QUESTION

Just a small additional question: I’m getting very different results depending if I saturate/clamp fade+smooth or not. Not sure what’s the better solution.

Without the saturate/clamp the shapes during the fadeout stay smoother:

When adding a saturate the shapes stay harder/brighter during the fade out:

What’s your way?

A new tweet showing another option for doing alpha erosion:

https://twitter.com/Tuatara_Games/status/1620101989983227910?t=QCSJIx5Pet20wcVPU7d2cA&s=09

10 Likes