suanLoBeach Therefore, I wanted to use ZWrite to make the frontmost object block the transparent objects behind it while remaining transparent to other non-transparent objects
Note that ZWrite alone is not sufficient when the triangles of a Spine Skeleton are rendered back to front (as is needed for normal transparency). If frontmost attachments in your skeleton shall block attachments behind it, you need to render the frontmost first, or ensure that the zbuffer is already set to the frontmost z value. Note that inverting the triangle vertex z position of a Mesh does not change the order in which the triangles are rendered.
You have two options here:
- a ) You need to ensure either by modifying the draw order (
Skeleton.DrawOrder
) of the skeleton's attachments to the reverse, or modify the source code to reverse draw order in MeshGenerator
. This would allow transparency to other objects while occluding triangles in the same Mesh (in the same skeleton).
- b) You can use a depth pre pass as suggested above to render the skeleton to the ZBuffer first and then only draw the front-most object. From your second paragraph, that seems to be what you want. If however you want to blend between multiple semi-transparent skeleton objects normally, you would need to add a
SortingGroup
component (or perhaps it works also by using different Sorting Layers) to group pass1 and pass2 of the same skeleton together. Otherwise only the top-most skeleton's topmost attachment will "win".
From your text I assume that you want the frontmost attachments of all skeleton objects to block transparent attachments behind them. So a depth-pre pass should do what you need, as described. Note that all depth-pre-passes need to be executed before all normal skeleton passes:
skel1.depthPre
skel2.depthPre
skel3.depthPre
skel1.normal
skel2.normal
skel3.normal
And not
skel1.depthPre
skel1.normal
skel2.depthPre
skel2.normal
skel3.depthPre
skel3.normal
So you should not add e.g. a SortingGroup
component then or do anything else that groups render passes of a single object. If you set a Sorting Layer, that should perhaps not affect the grouping, but you should not need Sorting Layer anyway. In any case, test the actual order in which things are drawn with the frame debugger to see if what happens is what you want.
suanLoBeach However, what I really wanted to achieve was for one to completely block the other. I discovered that implementing this effect required a strange combination: Spine Boy (background) needed to be closer to the camera than the raptor (foreground), meaning Spine Boy's Z-axis had to be closer to the camera. This gave me the effect I needed. But obviously, this is incorrect, because Spine Boy is in the background and shouldn't be closer to the camera - it should be further away than the raptor. This is the problem I'm currently facing.
Your desired effect is incorrect ordering, so it's logical that the means seem incorrect. Normally no-one wants transparent objects block transparent objects behind them.
Also another way to change the ordering of objects is to change the render queue of your shader or material. Render Queue
Transparent
orders your objects back to front and other queues front to back.
Queue Typical Shader Type Sorting Behavior
Opaque (<= 2500) Opaque Surfaces Front-to-Back
AlphaTest (Cutout) (2450) Cutout Shaders Front-to-Back
Transparent (>= 3000) Blended/Transparent Back-to-Front (Manual Sorting)
Overlay (4000+) UI, Effects Always on top
All you should need is a depth pre pass though.
If you are not yet skilled with what you want to do, you need to learn it. Learn how render pipelines work, what the depth buffer does, etc. Or choose an easier task which you can accomplish with your skills.
suanLoBeach so I'm not sure if this is a Unity issue or a problem with the Spine shader.
This is neither an issue with Unity nor with Spine shaders. You want special behaviour which is considered incorrect rendering. Both Unity and the spine-unity shaders do what they are expected to do.