• Unity
  • 2D URP Lit shader with Outline?

  • Изменено
Related Discussions
...

How can I have an outline on a lit spine character? I'm using outlines to interact with npcs/items.
I'm using the URP/2D/Spine/Sprite shader from the Shader package.

In the unity shader graph i made for that, it copies the image in 4 directions, different depending on it's size in pixels as the outline, and keep the original in the middle.

Is it possible to use shader graph for Spine, and how would I create such shader? 🙂

Oh, and I want one solid outline outside of everything, so items overlapping shouldn't case additional outlines.

Thanks!

Was talking with Nic about this in discord - hoping to see what Harald thinks :grinteeth:

Would it be possible to use the URP/2D/Spine/Sprite shader to render his character normally, but then additionally add an outline either as another Pass in the shader, or by rendering the character's mesh again with a separate shader just for the outline?

I'm curious how the spine "Outline" shader works - does it do edge sampling on the mesh or something? Or does it draw an outline around all of the pieces, but then render the actual character on top (so you only see the outline around the entire character's silhouette?)

Thanks for helping out again Jamez0r!

Jamez0r написал

How can I have an outline on a lit spine character? I'm using outlines to interact with npcs/items.
I'm using the URP/2D/Spine/Sprite shader from the Shader package.

For this purpose we added the outline-only shader for URP. You would then render the same existing skeleton mesh again using the the RenderExistingMesh example component. This is demonstrated in the Outline Shaders URP that comes with the Spine Universal RP package.

The best way would be to use a single shader with a second pass, which I admittedly didn't know was supported in URP, hence the workaround with the separate shader. We've got an issue ticket here to add outline support to all URP shaders using the second pass:
https://github.com/EsotericSoftware/spine-runtimes/issues/1824

Jamez0r написал

I'm curious how the spine "Outline" shader works - does it do edge sampling on the mesh or something?

This question was asked some time ago on this thread here:
Outline Shader Reproduction In Shader Graph

In short: it samples the texture's alpha value at 4 or 8 neighbour texels, offsetting the sample position by outline width. Depending on how many opaque texels there are (actually it's using the sum of alpha values of these neighbours), it will draw a more transparent or more opaque outline. When using 8-neighbourhood, e.g. 1 opaque texel (at a corner) will result in a rather transparent outline pixel, 3 opaque texels (at a straight line) will result in fully opaque outline pixel.

Jamez0r написал

Or does it draw an outline around all of the pieces, but then render the actual character on top (so you only see the outline around the entire character's silhouette?)

The normal outline shaders use render order to draw the outline behind the normal skeleton mesh.

In the two pass non-URP shader Spine/Outline/OutlineOnly-ZWrite, a first DepthOnly z-write pass is used to "mask" inner regions, and then the normal outline pass is drawn, failing z-test at these inner pixels and thus only rendering the outer outline.

Thanks a lot for the explanation!

In the two pass non-URP shader Spine/Outline/OutlineOnly-ZWrite, a first DepthOnly z-write pass is used to "mask" inner regions, and then the normal outline pass is drawn, failing z-test at these inner pixels and thus only rendering the outer outline.

Ahh, very cool!

We've got an issue ticket here to add outline support to all URP shaders using the second pass:
https://github.com/EsotericSoftware/spine-runtimes/issues/1824

https://youtu.be/TcWPiHjIExA?t=70

Thanks, that’s great. I’ll look into the curreny solution. Would that mean twice the draw calls for an outlined object?

I’d like to add a visual white semi transparent thing ”flying over” the item to show that it’s interactable too for some items. I know how to do that in shader graph but I don’t know if i can combine it with another shader, but i guess i wont need the outline at the same time so I could probably just switch materials.

Thanks again and to jamezor too!

Jamez0r написал

XD. Understood 🙂.

nicmar написал

Would that mean twice the draw calls for an outlined object?

Basically a second render pass is also a draw call, it does not matter too much in regards to the render context if it's a single shader with two completely different passes, or two separate shaders. So yes, the outline will almost always require an additional draw call (though 10 outlined objects of the same type might again be batched, depending on the circumstances).

23 дня спустя

Forgive me, but I've always been terrible with shaders. I see that there's been an Outline-only shader added for URP. Is this to be used in conjunction with the normal shaders in order to add an outline, or am I going down the wrong path here?

Yes, this is the way to go currently (until we get to implement the single-shader version for URP as well).

You can use a RenderExistingMesh component to render the same skeleton again, the second time with the outline-only shader. This is shown in the Spine Universal RP Shaders/Examples/Outline Shaders URP example scene that is included in the Spine URP shaders UPM package.

6 месяцев спустя

Hello,

Sorry to necro but I had a problem with the sorting layers and wanted to post here the little fix it involves. For people who have something like the attachment (ie. all the outlines on top of the Spine when changing layer), you can do this :

ownRenderer.sortingLayerID = referenceRenderer.sortingLayerID;
ownRenderer.sortingLayerName = referenceRenderer.sortingLayerName;
ownRenderer.sortingOrder = referenceRenderer.sortingOrder;

in the Awake() or UpdateMaterials() depending on if you change of layer during runtime.

Voilà,

Thanks for sharing @Angurvadal, very much appreciated!

5 месяцев спустя
Harald написал

Yes, this is the way to go currently (until we get to implement the single-shader version for URP as well).

Hi Harald

Have you had time to update the URP single-shader version to support outlines? :o

I'd like to use the outline on all characters in the game. I was wondering if it's performant to have multiple shaders per character. (1 for outline, 1 for the default URP shader)

Thanks for your help
🙂

I should have posted the link to the issue ticket in my previous posting:
https://github.com/EsotericSoftware/spine-runtimes/issues/1824
Unfortunately I didn't get to it yet, but you can subscribe to this issue ticket above to receive notifications upon any updates.

Harald написал

I should have posted the link to the issue ticket in my previous posting:
https://github.com/EsotericSoftware/spine-runtimes/issues/1824
Unfortunately I didn't get to it yet, but you can subscribe to this issue ticket above to receive notifications upon any updates.

No worries. I know you're super busy.

Regarding my question, off the top of your head, do you think it'll be a significant performance issue if all the characters used double skinned meshes? (outline x 1, actual character sprite x1)

Thanks! 🙂

Do you really need outlines active at all characters? Usually it's only some that will be selected and thus outlines added around them.

The question about how significant the performance hit will be is hard to answer with anything other than "you need to measure it on the target device". In this case I would guess that the performance difference is not too high between having two passes on a single mesh vs. two identical meshes drawn separately, where it depends on how Unity would handle this second identical mesh render call vs. a second pass. At least in regards to overdraw and the fragment shader stage there should be no difference at all, it might only transfer the meshes vertex attributes unnecessarily twice.

Harald написал

Do you really need outlines active at all characters? Usually it's only some that will be selected and thus outlines added around them.

The question about how significant the performance hit will be is hard to answer with anything other than "you need to measure it on the target device". In this case I would guess that the performance difference is not too high between having two passes on a single mesh vs. two identical meshes drawn separately, where it depends on how Unity would handle this second identical mesh render call vs. a second pass. At least in regards to overdraw and the fragment shader stage there should be no difference at all, it might only transfer the meshes vertex attributes unnecessarily twice.

Ah ok ok I get it.

Alright thanks for explaining how the process works and the potential performance impacts.

I'll let you know once I start water falling all the art assets and see how it goes with the current method available to us. 🙂

Thanks. We're always curious to see real-world benchmarks, so looking forward to seeing how it performs 🙂.