NinjaDog

i wondering to enable the depth writing at same time when it's rendering
so i added the "Depth" pass into Spine-Skeleton.shader
it works when the mesh render always working with a single material
BUT it doesn't work right when the mesh render working with multi-materials
material rendering orders were randomly changing, and i don't know why,it's confusing me.
Shader "Spine/Skeleton" {
Properties {
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.01
_Color ("Color", Color) = (1.000000,1.000000,1.000000,1.000000)
_Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1
_GrayLerp ("GrayLerp",Range(0,1)) = 1
[NoScaleOffset] _MainTex ("Main Texture", 2D) = "black" {}
[Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0
[HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0
[HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default

// Outline properties are drawn via custom editor.
[HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0
[HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1)
[HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024
[HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25
[HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0
[HideInInspector][MaterialToggle(_USE8NEIGHBOURHOOD_ON)] _Use8Neighbourhood("Sample 8 Neighbours", Float) = 1
[HideInInspector] _OutlineMipLevel("Outline Mip Level", Range(0,3)) = 0
}

SubShader {
Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" }

Fog { Mode Off }
Cull Off
ZWrite Off
Lighting Off



Blend One OneMinusSrcAlpha

Stencil {
Ref[_StencilRef]
Comp[_StencilComp]
Pass Keep
}

Pass {
Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" }
Name "Normal"
ColorMask RGBA
CGPROGRAM
#pragma shader_feature _ _STRAIGHT_ALPHA_INPUT
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
fixed _Cutoff;
float _GrayLerp;
float4 _Color;

struct VertexInput {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float4 vertexColor : COLOR;
};

struct VertexOutput {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float4 vertexColor : COLOR;
};

VertexOutput vert (VertexInput v) {
VertexOutput o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.vertexColor = v.vertexColor;
return o;
}

float4 frag (VertexOutput i) : SV_Target {
float4 texColor = tex2D(_MainTex, i.uv);

#if defined(_STRAIGHT_ALPHA_INPUT)
texColor.rgb *= texColor.a;
#endif
float4 allColor = texColor * i.vertexColor * _Color;
fixed gray = 0.30 * allColor.r + 0.59 * allColor.g + 0.11 * allColor.b;
fixed3 finalColor = lerp(gray, allColor, _GrayLerp);

return fixed4(finalColor.r, finalColor.g, finalColor.b,allColor.a);
}
ENDCG
}

Pass {
Tags { "LightMode"="Vertex" "Queue"="Transparent" "IgnoreProjector"="true" "RenderType"="Transparent" }

Name "Depth"
ColorMask 0
ZWrite On

CGPROGRAM
#pragma target 2.0
#pragma shader_feature _ _STRAIGHT_ALPHA_INPUT
#pragma vertex vert
#pragma fragment frag
#define _ALPHA_CLIP
#include "UnityCG.cginc"
sampler2D _MainTex;
fixed _Cutoff;

struct VertexInput {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float4 vertexColor : COLOR;
};

struct VertexOutput {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float4 vertexColor : COLOR;
};

VertexOutput vert (VertexInput v) {
VertexOutput o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.vertexColor = v.vertexColor;
return o;
}

float4 frag (VertexOutput i) : SV_Target {
float4 texColor = tex2D(_MainTex, i.uv);

#if defined(_STRAIGHT_ALPHA_INPUT)
texColor.rgb *= texColor.a;
#endif
texColor = texColor * i.vertexColor;
clip(texColor.a - _Cutoff);
clip(-1.0);
return texColor;
}
ENDCG
}

Pass {
Name "Caster"
Tags { "LightMode"="ShadowCaster" }
Offset 1, 1
ZWrite On
ZTest LEqual

Fog { Mode Off }
Cull Off
Lighting Off

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_shadowcaster
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
sampler2D _MainTex;
fixed _Cutoff;

struct VertexOutput {
V2F_SHADOW_CASTER;
float4 uvAndAlpha : TEXCOORD1;
};

VertexOutput vert (appdata_base v, float4 vertexColor : COLOR) {
VertexOutput o;
o.uvAndAlpha = v.texcoord;
o.uvAndAlpha.a = vertexColor.a;
TRANSFER_SHADOW_CASTER(o)
return o;
}

float4 frag (VertexOutput i) : SV_Target {
fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy);
clip(texcol.a * i.uvAndAlpha.a - _Cutoff);
SHADOW_CASTER_FRAGMENT(i)
}
ENDCG
}
}
CustomEditor "SpineShaderWithOutlineGUI"
}
could you please tell me how to solve it,thanks!
NinjaDog
  • Posts: 23

Harald

Most likely you don't need a separate Depth pass, instead you can just change ZWrite Off to ZWrite On. Then you need to set Advanced - Z-Spacing at your SkeletonRenderer component, otherwise you will receive z-fighting problems.

In general it is advisable to copy any thirdparty shader and then modify the copied version instead of modifying the original, because e.g. when updating the spine-unity runtime you might accidentally overwrite your changes. In the case of the shader, you should then also change the name of the shader in code from Spine/Skeleton to e.g. Spine/Skeleton ZWrite so that you can select it separately in the Material's Shader property.
User avatar
Harald

Harri
  • Posts: 3469

NinjaDog

Thanks for your advice
i just got a wrong rendering if i just change ZWrite off to ZWrite on - some slots with sub-materials were DISAPPEAR when rendering
and i don't get the 'Advanced Z-Spacing' what it is exactly
its range seems from 0 to -1 in the inspector
i NEED set the Z as the world-space Z

---

It still doesn't work with a separate Z-Write pass or just turn ZWrite On
some slots with sub-materials are random changes in the order of the layers
e.g some times material A in top of the layers,and some times material B in top of the layers
NinjaDog
  • Posts: 23

Harald

NinjaDog wrote:and i don't get the 'Advanced Z-Spacing' what it is exactly
Please always have a look at the spine-unity documentation pages first if anything is unclear:
spine-unity Runtime Documentation: Setting Advanced Parameters
NinjaDog wrote:i just got a wrong rendering if i just change ZWrite off to ZWrite on - some slots with sub-materials were DISAPPEAR when rendering
It could be that you need to have ZWrite enabled on all your submaterials, not only on some of them. Unfortunately we don't know enough about your setup without any screenshots provided. In general please always provide some screenshots (of the scene view and of the active Materials at your SkeletonRenderer) that show the issues you are having, then we can help much more efficiently.
User avatar
Harald

Harri
  • Posts: 3469

NinjaDog

there are 8 same spines on the screen,and some quads with textures for background
it's the correct rendering BUT without the zwrite,the beam of lighting and mountain are really a spine same as other characters,just playing a different animation
right.jpg

with a separated z writing,keep eye on the beam of lighting,it's behind the mountain,it's wrong
separated-z.png

with the 'ZWrite On',it's completely wrong,mountains are DISAPPEAR
enable-z.png


---

let's say the Spine named as A
if there is just one 'A',it works with separated Zwriting
but it doesn't works if there are 8(multiple) 'A'
weird
You do not have the required permissions to view the files attached to this post.
NinjaDog
  • Posts: 23

Harald

NinjaDog wrote:let's say the Spine named as A
if there is just one 'A',it works with separated Zwriting
but it doesn't works if there are 8(multiple) 'A'
weird
If it works correctly with only one instance, but the order is getting wrong with multiple instances, it's most likely due to too aggressive batching behaviour by Unity, grouping things incorrectly (e.g. batching all of your _anan materials to one draw call and all _anan2 materials to another, messing with the layer order). Please see this forum thread here for solutions (most likely a SortingGroup component should help):
multiple characters on scene issue

We also cover this in the documentation page:
spine-unity Runtime Documentation: Transparency and Draw Order

In general it is advisable to use as few switches between atlas pages as possible, and group your attachments accordingly (or even better, make sure they fit on a single atlas texture). In your case you have 8 draw calls per skeleton, which could potentially be reduced to 3 via proper grouping, as described here on the documentation pages:
spine-unity Runtime Documentation: Material Switching and Draw Calls
User avatar
Harald

Harri
  • Posts: 3469

NinjaDog

Cool,i've been use
Render.sortingOrder
instead of SortingGroup before.
Every instance have correct layer orders with 'Fix Draw Order' right now.
Thanks for you advice!
NinjaDog
  • Posts: 23

Harald

Glad to hear, thanks for getting back to us!
User avatar
Harald

Harri
  • Posts: 3469

NinjaDog

Hi,We found same issues with some specified spine files,not same one as previous.and 5% of our spine files has same issues.
I tried to upgrade to Spine 4.0 to see if it is fixed,but we found two problem:
1) Some spine animation is displayed in WRONG position/scale in 4.0 and they both fine in 3.8(Unity),so i've post it in this thread:
Spine animation displayed WRONG in Unity Spine 4.0
2) With 5% spine files still has wrong orders in layers with 'Fixed Draw Order',I found it can be correctly if the 'Visible Outside Mask' is enabled in Spine Unity 4.0 - i noticed the fps is slow down if i turned 'VisibleOutMask' on. BUT i think it is still a bug unfixed.

---

AND Sorry for my describe was wrong as "Order in layers error with depth writing",it actually independent to depth writing.
It occurred in original unity spine 3.8/4.0 package with specified spine files.

---

and I will provide a test case (included specified spine files)as soon as possible , for help you to figure it out

---

I can't post the attachment because '413 Request Entity Too Large' (It's 19MB)
NinjaDog
  • Posts: 23

Harald

Please send your package via email to contact@esotericsoftware.com. Then we can have a look at it.
User avatar
Harald

Harri
  • Posts: 3469

NinjaDog

The test case has been sent to your email,thanks a lot!
NinjaDog
  • Posts: 23

Harald

Thanks for sending the reproduction assets, we just had a look at it. You are not using the SortingGroup component that we suggested to use some postings above. If I add a SortingGroup at each SkeletonAnimation GameObject in your provided scene, everything is rendered in the correct order. You can also disable Advanced - Fix Draw Order which is intended for use with Universal Render Pipeline.

This is under the assumption that you are using the normal render pipeline and not Universal Render Pipeline (URP) in your project.
User avatar
Harald

Harri
  • Posts: 3469

NinjaDog

Sorry,I forgot to provide the script about the SortingOrder

In practice, our scene would add an automatic sorting component to set the order for each SkeletonAnimation
and this component automatically computes the order based on Z,
so gameObjects of the same Z will be under the same order value

So this still exists in our scene
Is that means can't use the same value of order even if they're in the same z-plane, right?

---

and yes,we're using normal render pipeline,not URP
NinjaDog
  • Posts: 23

Harald

NinjaDog wrote:Is that means can't use the same value of order even if they're in the same z-plane, right?
No. I just added a SortingGroup component to each SkeletonAnimation GameObject and left it at the default values (Order in Layer set to 0). This solved the problem already.
User avatar
Harald

Harri
  • Posts: 3469

NinjaDog

Thanks a lot. but sounds it works different to my project.
I will try it again and back.
What Unity version I use is 2018.4.14.f1.
AND my script is using the 'Order' of 'Render' component,to avoid an extra 'SortingOrder',for make it as simple as I can.
NinjaDog
  • Posts: 23

Harald

NinjaDog wrote:AND my script is using the 'Order' of 'Render' component,to avoid an extra 'SortingOrder'
I assume you mean SortingGroup instead of SortingOrder component, sortingOrder instead of Order and Renderer instead of Render component.

That will not work (unless you assign different sortingOrder values at every skeleton MeshRenderer), you need to prevent Unity's batching mechanisms from re-grouping (reordering) triangles across two equal skeletons at the same depth.
NinjaDog wrote:..for make it as simple as I can.
I could imagine even simpler solutions that don't work :P.

Joking aside: solving the reordering problem by setting a slightly different Renderer.sortingOrder parameter at each Skeleton's MeshRenderer could work as well. However, I would call this solution more complicated and not very clean, given that the SortingGroup component was designed for exactly this purpose. See the official SortingGroup documentation here.
User avatar
Harald

Harri
  • Posts: 3469

NinjaDog

I'm really appreciate for your explain and help!
NinjaDog
  • Posts: 23

Harald

Thanks for your kind words, glad that it helped!
User avatar
Harald

Harri
  • Posts: 3469

NinjaDog

Yes,this problem has been resolved in Unity Spine 3.8!
NinjaDog
  • Posts: 23


Return to 中国Spine用户