Shader graph, trouble with two sided faces and alpha transparency

GasOrb_Preview

Hi all! I’m a beginner to VFX art and I’m making some basic effects for a game I’m making with a team. Tried to create this acid fog effect but came across problems with having alpha and two sided faces. I’ve just applied the shader to a Unity 3D Sphere: Alpha clipping

If I set the effect to additive it fixes the strange clipping, but makes the colors washed out: Additive Effect

Here’s my graph and inspector if that helps:


Any idea how to solve this?

1 Like

The way you fix this is … you kind of can’t. At least not with Shader Graph alone.

I posted an in depth explanation of the problem here:

Unfortunately several of the options listed in that post aren’t possible with Shader Graph.

Sorting the individual triangles won’t help here unless you’re doing it in real time which is expensive, so don’t do that. There’s no one triangle order that’ll work from all camera angles when using a two sided material.

Pre-pass depth write is sort of possible, but not possible with Shader Graph. It doesn’t expose enough controls to let you have an invisible pass that also writes to depth, and can’t do multi-pass rendering. So you’d have to write a vertex fragment shader by hand.

You can’t use any OIT techniques because, again, the URP doesn’t expose enough controls anywhere for that. You’d have to rewrite parts of the URP’s underlying code to support it.

And you can’t use Alpha to Coverage because, though the URP is designed around using MSAA, they don’t let you enable A2C on Shader Graph shaders. So you’d again have to resort to hand written shaders.

The only option to fix this that uses only Shader Graph is to use the additive blend, or make it opaque with alpha clip. You can use dithered alpha to get something kind-of semi transparent looking so it’s not quite as harsh an edge. And additive works because the order doesn’t matter for additive blending; a + b = b + a. But those are the only option that 100% fixes the sorting problem, as ugly as they are compared to the nicer look of alpha blending.

But, all hope is not lost. There is one more option.

Don’t use the default sphere, and don’t use a two sided shader.

The trick is to use a sphere mesh of your own making with an interior and exterior, and setup the mesh so that the interior sphere renders first. This is easier to do than it sounds. Make a sphere mesh with the UVs you want, duplicate it, invert the faces so they’re visible on the interior, then add the “exterior” mesh to the first mesh so it’s one mesh. Don’t use any csg / boolean operations, any 3D modelling tool is going to have some way of just adding another mesh’s triangles to an exist mesh, and if you add the exterior mesh to the interior mesh the interior mesh’s triangles should be “first”.

And you’re done.

The big caveat being this only works because this is a convex shape. Any shape that is at all concave and the sorting issue can end up being visible again.

8 Likes

Hey,

I’m sorry but I don’t understand what the problem is, could you provide some more details?
Is the gif what you currently have or the goal you want to achieve?

The problem is that the shader doesn’t know which fragments are closer to the camera and which are further, which can cause certain fragments which are further from the camera to nonetheless be drawn as if they are closer.

Aha! I tried your trick and it seems to work! Thanks so much.
AcidOrb_Fixed
AcidOrb_FixedRotate

1 Like

Ah!

I think I got it now!

My personal way of dealing with this is to have 2 spheres, with the normals in one of them flipped. Then I use soring fudges to make sure the back always is on the back!

Thankfully your problem seems to be sorted, looks good! :smiley:

2 Likes