• RuntimesUnity
  • Depth of Field in URP with SkeletonLit and Sprites

  • Đã chỉnh sửa

Hello there!

Im trying to use Depth of Field Volume effect on a 3D scene with a character using URP/Spine/SkeletonLit shader and an enviroment using URP/Spine/Sprite shader.

First of all I needed to enable Write to Depth in both shaders. In Sprite shader I enabled it in material, in SkeletonLit shader I changed _ZWriteOff_ to ZWriteOnin code.

To ensure proper draw order I used Z Spacing parameter in Advanced settings of SkeletonAnimation component (changed it to -0.001).

Depth of Field only affects opaque queue range (0 through 2500) so I needed to modify URP/Spine/SkeletonLit shader render queue (changed tag to "Queue"="AlphaTest").

Now depth of field is working correctly, but some parts of characters are still interpreted as not transparent.


To fix that I added alpha clipping in fragment shader to discard pixels that are below alpha cutoff value defined in material.

clip((tex.a) - _ACutoff);

This seems to fix issue with writing correct data to Z.

Sadly there is still an issue with drawing a skeleton itself. You can see that drawing another part of skeleton does not apply correct color on edges where transparency should blend two parts of skeleton seamlesly. Instead we can see the background in the area where edge is transparent.

I could increase alpha cliping value, but this also result in very sharp edges around skeleton, and does not look good.

It seems like MeshRenderer is drawing all parts using materials from list, but does not preserve order.
I made a quick test where I modify material render queue in SkeletonRenderer to force drawing order.

for (var i = 0; i < meshRenderer.sharedMaterials.Length; i++)
{
meshRenderer.materials[i].renderQueue -= i;
}

This seems to solve issue but is of course highly uneffective due to cration of multiple materials. Sadly sorting order cannot be set by PropertyBlock.

Do you have any ideas how to make it work? Is there some other way to preserve proper draw order in skeleton when using AlphaTest render queue in shader?

Spine package version: spine-unity-4.1-2023-06-27.unitypackage
Unity version: 2021.3.22f1

  • Harald đã trả lời bài viết này.
    Related Discussions
    ...

    @tomasz Thanks for the detailed writeup!

    tomasz Sadly sorting order cannot be set by PropertyBlock.

    You could have a try whether enabling Advanced - Fix Draw Order at the SkeletonAnimation component fixes the problem. It uses different MaterialPropertyBlocks for each Material setting just a single different dummy parameter. It has been introduced originally as a workaround against URP batching and reordering too aggressively.

    You could also have a try whether adding a SortingGroup component to the character has any effect in this regard. However, in the respective forum threads incorrect grouping of draw calls of identical skeletons was likely the problem, which might not be the problem with your single unique character.

    If anyone else has any ideas what could be done, please don't hesitate to let us know.

    Thanks for quick response Herald!

    I have already attempted both approaches, adjusting Advanced - Fix Draw Order in SkeletonAnimation and adding a SortingGroup, but none of them resulted in any changes to the character drawing order 🙁

    @tomasz Thanks for the quick feedback, that's indeed unfortunate then 🤕. I'm afraid I'm running out of ideas, at least for now. If anyone else knows any workarounds on how to force the original draw call order, please share your insights below.

    tomasz Depth of Field only affects opaque queue range (0 through 2500) so I needed to modify URP/Spine/SkeletonLit shader render queue (changed tag to "Queue"="AlphaTest").

    Not a solution to the draw call ordering, but you could perhaps modify the order at which the DoF effect is applied in the render queue (or use a different DoF implementation), and apply it after transparent objects instead of after opaque / alpha test. You can see the effect at different position in the render queue in this Unity forum thread:
    https://forum.unity.com/threads/transparency-and-dof-post-process-in-urp.1169716/