Nick

I want to perform whole character tint to make it match the stage color.
e.g. brighter character on desert area.

Some of my characters require multiply blend mode for shadows.
The shaders used is auto picked when I dynamically compose the SkeletonAnimation GameObject from code.

When I do
MaterialPropertyBlock mpb = new MaterialPropertyBlock();
mpb.SetColor("_Black", mEditor_TintColor);

skeletonAnimation.GetComponent<MeshRenderer>()?.SetPropertyBlock(mpb);
Most part of the character tint correctly except some shadow parts that use multiply.
It seems to be the shader (Spine/BlendMode/SkeletonPMAMultiply) that don't support tint black.

Any hint how I could to get this to work?
Thanks
Nick
  • Сообщения: 242

Harald

Nick писал(а):It seems to be the shader (Spine/BlendMode/SkeletonPMAMultiply) that don't support tint black.
Your observations are correct, only the two shaders Skeleton Tint and Skeleton Tint Black support tinting the black value.
Nick писал(а):Any hint how I could to get this to work?
You can quite easily create your own modified copy (or replacement) of the Skeleton PMA Multiply shader. You just have to add the relevant parts from the Skeleton Tint shader:
https://github.com/EsotericSoftware/spine-runtimes/blob/3.8/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Tint.shader#L10
https://github.com/EsotericSoftware/spine-runtimes/blob/3.8/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Tint.shader#L54
And make sure the black color is applied:
https://github.com/EsotericSoftware/spine-runtimes/blob/3.8/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Tint.shader#L80

Another question though is why you want to tint the black value of a multiply shader used for shadows. You could quite easily use e.g. a white base (texture) color and use the normal color material parameter to tint it in any color you want.
Аватара пользователя
Harald

Harri
  • Сообщения: 2761

Nick

Another question though is why you want to tint the black value of a multiply shader used for shadows. You could quite easily use e.g. a white base (texture) color and use the normal color material parameter to tint it in any color you want.
Can you elaborate more on this? I am not familiar with visual stuff in Unity. I only know how to adjust the "_Color" and the R,G,B,A of the Skeleton class which seems can't make character brighter because the color is already white.
Nick
  • Сообщения: 242

Harald

The above text was describing a setup where you use separate Attachment images for the shadow and don't share them with the main part of the character. If you are re-using colored body parts of the character, then this will not be applicable.

If you have a separate shadow Attachment image which is black before tinting, then the above solution can be used to replace yours.
You could then usa a white texture in the same shape as before for the shadow, you can then set the color tint to either RGB (0, 0, 0) black, or a slightly blue dark gray RGB (0.1, 0.1, 0.2f) or any custom color that you want.

So in other words:
A white base texture allows for more tinting flexibility than a gray or black one.
Аватара пользователя
Harald

Harri
  • Сообщения: 2761

Nick

Oh I see. I understand what you mean white base texture now. Unfortunately the shadow I am talking about is not really the shadow of the whole character but an attachment image used within the character. e.g. shadow of cloth on the skin exported from multiply layers of PSD.

In this case I think I may need to try something else.
Do you suggest me to to take the Tint Black route? or is there other better options ?
Nick
  • Сообщения: 242

Harald

Nick писал(а):Oh I see. I understand what you mean white base texture now. Unfortunately the shadow I am talking about is not really the shadow of the whole character but an attachment image used within the character. e.g. shadow of cloth on the skin exported from multiply layers of PSD.
In general I see no technical problem here, you could still make the Attachment image white. I assume that you mean that you don't want to mess up the displayed version in Photoshop, which would then have a white shadow Attachment image (having no effect), right? An admittedly not very clean workaround would be to use a preview (black) and an export version (white) at these shadow layers, e.g. with layer style Color Overlay with white or black color.
Nick писал(а):Do you suggest me to to take the Tint Black route? or is there other better options ?
I'm not completely sure which way you intended to utilize the Tint Black feature. One that would work is to create a modified Multiply Tint Black copy of the Spine/Skeleton Tint Black shader and change the blend mode statements to Blend DstColor OneMinusSrcAlpha.

In general the Tint Black route is a bit of an overkill here, as you only want to override the color on these shadow attachments to black or another fixed color. I would rather suggest using a custom shader here, you could even write one where you ignore the texture color RGB values entirely (you need the Alpha value though) and overwrite it in the shader with the color value, if you need just a single-color RGB result with varying transparency values.
Аватара пользователя
Harald

Harri
  • Сообщения: 2761

Nick

Thanks
I will do some test and see which option is best for my need.

---

Harald писал(а):You can quite easily create your own modified copy (or replacement) of the Skeleton PMA Multiply shader. You just have to add the relevant parts from the Skeleton Tint shader
I finally tried the tint black approach recently. I modified the mentioned 3 lines in the shader but the sprites which use multiply blend mode display pure purple color. Is there something else I need to do to make it work?

Here is the modified shader:
// Spine/Skeleton PMA Multiply
// - single color multiply tint
// - unlit
// - Premultiplied alpha Multiply blending
// - No depth, no backface culling, no fog.
// - ShadowCaster pass

Shader "Spine/Blend Modes/Skeleton PMA Multiply" {
Properties {
_Color ("Tint Color", Color) = (1,1,1,1)
_Black("Dark Color", Color) = (0,0,0,0)
[NoScaleOffset] _MainTex ("MainTex", 2D) = "black" {}
[Toggle(_STRAIGHT_ALPHA_INPUT)] _StraightAlphaInput("Straight Alpha Texture", Int) = 0
_Cutoff ("Shadow alpha cutoff", Range(0,1)) = 0.1
[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" }
LOD 100

Fog { Mode Off }
Cull Off
ZWrite Off
Blend DstColor OneMinusSrcAlpha
Lighting Off

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

Pass {
Name "Normal"

CGPROGRAM
#pragma shader_feature _ _STRAIGHT_ALPHA_INPUT
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float4 _Color;
uniform float4 _Black;

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 * float4(_Color.rgb * _Color.a, _Color.a); // Combine a PMA version of _Color with 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

return fragTintedColor(texColor, _Black.rgb, i.vertexColor, _Color.a, _Black.a);
//return (texColor * i.vertexColor);
}
ENDCG
}

Pass {
Name "Caster"
Tags { "LightMode"="ShadowCaster" }
Offset 1, 1

ZWrite On
ZTest LEqual

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_shadowcaster
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
struct v2f {
V2F_SHADOW_CASTER;
float4 uvAndAlpha : TEXCOORD1;
};

uniform float4 _MainTex_ST;

v2f vert (appdata_base v, float4 vertexColor : COLOR) {
v2f o;
TRANSFER_SHADOW_CASTER(o)
o.uvAndAlpha.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
o.uvAndAlpha.z = 0;
o.uvAndAlpha.a = vertexColor.a;
return o;
}

uniform sampler2D _MainTex;
uniform fixed _Cutoff;

float4 frag (v2f i) : SV_Target {
fixed4 texcol = tex2D(_MainTex, i.uvAndAlpha.xy);
clip(texcol.a * i.uvAndAlpha.a - _Cutoff);
SHADOW_CASTER_FRAGMENT(i)
}
ENDCG
}
}
CustomEditor "SpineShaderWithOutlineGUI"
}
Nick
  • Сообщения: 242

Harald

Nick писал(а): I modified the mentioned 3 lines in the shader but the sprites which use multiply blend mode display pure purple color. Is there something else I need to do to make it work?
This means that your shader code does not compile because it has compile errors. Please modify the shader code (e.g. add a space somewhere and save the file) so that it's compiled again, then you should receive the error messages in the console, telling you what the problem is.
Аватара пользователя
Harald

Harri
  • Сообщения: 2761

Nick

Problem solved.

The include statement was missing causing fragTintedColor() not compiling.
#include "../CGIncludes/Spine-Skeleton-Tint-Common.cginc"
It is now working correctly.
Thank you~
Nick
  • Сообщения: 242

Harald

Very glad to hear you've figured it out, thanks for letting us know!
Аватара пользователя
Harald

Harri
  • Сообщения: 2761

Nick

I am getting a warning saying that 'Advanced - Tint Black' is not checked in the setting but the warning is originated from
SkeletonAnimation.NewSkeletonAnimationGameObject()
My guess is it is caused by adding the TintBlack support to the multiply blend mode shader.

Anyway, if tint black is detected inside NewSkeletonAnimationGameObject(), can it automatically enable 'Advanced - Tint Black' so that I don't get this warning? The problem is, I don't even get a chance to set the bool on this simple function call.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Nick
  • Сообщения: 242

Harald

This is a valid point. We have added an optional quiet parameter to NewSkeletonAnimationGameObject and Initialize() methods to skip any material checks and warning output.

The issue was tracked under this ticket:
https://github.com/EsotericSoftware/spine-runtimes/issues/1852
This 3.8 commit will be merged to the 4.0-beta branch soon and released alongside the next unitypackage release.
Thanks for reporting!
Аватара пользователя
Harald

Harri
  • Сообщения: 2761

Nick

The quiet is set, it will always show the warning...Not quiet at all.
#if UNITY_EDITOR
if (!Application.isPlaying) {
string errorMessage = null;
if (quiet || MaterialChecks.IsMaterialSetupProblematic(this, ref errorMessage))
Debug.LogWarningFormat(this, "Problematic material setup at {0}: {1}", this.name, errorMessage);
}
#endif
Nick
  • Сообщения: 242

Harald

Oh dear, this if condition was nonsense, thanks for reporting! A bugfix has been pushed to the 3.8 branch, a new 3.8 spine-unity unitypackage is available for download here as usual:
Spine Unity Download
The updates will be pushed to the 4.0-beta branch soon.
Аватара пользователя
Harald

Harri
  • Сообщения: 2761


Вернуться в Unity