- Edited
multi-dim-material order in layers error with depth writing
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!
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.
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 wroteand 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 wrotei 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.
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
with a separated z writing,keep eye on the beam of lighting,it's behind the mountain,it's wrong
with the 'ZWrite On',it's completely wrong,mountains are DISAPPEAR
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
NinjaDog wrotelet'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
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!
Glad to hear, thanks for getting back to us!
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)
Please send your package via email to contact@esotericsoftware.com. Then we can have a look at it.
The test case has been sent to your email,thanks a lot!
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.
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 wroteIs 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.
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 wroteAND 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 .
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.
I'm really appreciate for your explain and help!
Thanks for your kind words, glad that it helped!
Yes,this problem has been resolved in Unity Spine 3.8!