rxmarcus

Hello,
I'm trying to find a way that I can add an outline to my spine characters while using the Unity URP. I realize that the core issue is that URP only supports single pass shaders, so I'm looking for any other possible solutions / hacks to make this happen.

One option I'm attempting is to add a 2nd material to the Mesh Renderer of the skeleton and have this 2nd material render the skeleton as a solid color that is slightly larger than the 1st, creating an outline. The problem I'm facing is that when I try to add a 2nd material, it forcefully reverts to just 1. Is this a script somewhere forcing only 1 material?

Do you think this idea has potential? Is it possible to add outlines by creating a "Renderer Feature" in URP in some fashion? Any other ideas?

Thanks
rxmarcus
  • Messages: 76

Harald

Is this a script somewhere forcing only 1 material?
The materials and submeshes arrays at the MeshRenderer component are populated every frame by the SkeletonRenderer. This is necessary to mirror the currently active attachments. E.g. when in the first frame of the current animation all attachments come from a single atlas page texture, everything can be rendered as a single submesh with a single material. When another frame suddenly has attachments active from two atlas pages, it suddenly requires e.g. three submeshes (atlasA, atlasB, atlasA) with the respective materials shown in the array (materialA, materialB, materialA).
rxmarcus a écrit:Do you think this idea has potential? Is it possible to add outlines by creating a "Renderer Feature" in URP in some fashion? Any other ideas?
The general idea is good, unfortunately Unity's MeshRenderer design is flawed in this regard:

From https://docs.unity3d.com/Manual/class-MeshRenderer.html:
If a Mesh contains more Materials than sub-Meshes, Unity renders the last sub-Mesh with each of the remaining Materials, one on top of the next. This allows you to set up multi-pass rendering
on that sub-Mesh.
It is only the last submesh that is repeatedly drawn (instead of iterating over the whole array multiple times via [index % count]). :rolleyes: Unfortunately, your solution would then only work when a single atlas page texture is used.

Since Unity also still does not allow multiple MeshRenderer components at the same GameObject, the best scalable workaround that comes to my mind is to create a second GameObject as child fo the skeleton GameObject with it's own MeshRenderer (and MeshFilter). This MeshFilter would then have the same mesh assigned, but different materials.

I just created a component to render the same mesh with replacement materials, please find the zip package attached below.
.. as a solid color that is slightly larger than the 1st, creating an outline.
As outline-only shader, I would recommend to not scale the mesh but use the original outline shader code and remove the other render passes from the shader. I will later create a clean official release of the component and outline-only shader.
Vous ne pouvez pas consulter les fichiers insérés à ce message.
Avatar de l’utilisateur
Harald

Harri
  • Messages: 2272

rxmarcus

Thank you for the explanation and script!
I was able to get up and running with this script and look forward to a clean official release.

Thank you again!
rxmarcus
  • Messages: 76

Harald

Glad to hear, thanks for getting back to us!

---

The necessary updates have been officially added to the spine-unity runtime and the LWRP and URP extension packages.

From the changelog:
---
  • Added Skeleton-OutlineOnly single pass shader to LWRP and URP extension modules. It can be assigned to materials as Universal Render Pipeline/Spine/Outline/Skeleton-OutlineOnly. This allows for separate outline child GameObjects that reference the existing Mesh of their parent, and re-draw the mesh using this outline shader.
  • Added example component RenderExistingMesh to render a mesh again with different materials, as required by the new Skeleton-OutlineOnly shaders.
    In URP the outline has to be rendered via a separate GameObject as URP does not allow multiple render passes. To add an outline to your SkeletenRenderer:
    1. Add a child GameObject and move it a bit back (e.g. position Z = 0.01).
    2. Add a RenderExistingMesh component, provided in the Spine Examples/Scripts/Sample Components directory.
    3. Copy the original material, add _Outline to its name and set the shader to Universal Render Pipeline/Spine/Outline/Skeleton-OutlineOnly.
    4. Assign this _Outline material at the RenderExistingMesh component under Replacement Materials.
  • Added Outline Shaders URP example scene to URP extension module to demonstrate the above additions.
---

The new packages can be downloaded here as usual:
Spine Unity Download
Please let us know if the new component and shader are working for you as well.
Avatar de l’utilisateur
Harald

Harri
  • Messages: 2272

RemDust

Thank you Harald !
I don't know how many of these small add or features you make but it's a shame that some of them go unnoticed !
:)
RemDust
  • Messages: 195

Harald

Thanks for the kind words! :)

We try to post the major parts on the blog, but some minor improvements might indeed not make it there. However, even small additions will be listed in the changelog here: spine-runtimes/CHANGELOG.md at 3.8
Avatar de l’utilisateur
Harald

Harri
  • Messages: 2272


Revenir vers Unity