Spine tint, change color? (SOLVED)


#1

Hi!

How do I change tint on a Spine object?

I want to do this:
sprite.set_constant("#sprite", “tint”, color)

but with Spine

I was thinking giving it own material and changing the FP, but I can’t figure out where you set the material for a spine object.


#2

I don’t think this is possible. @sicher do you know if this can be achieved?


#3

This can be achieved by creating your own material.

In Blossom Blast Saga we created a new fragmentshader like this:

varying mediump vec4 position;
varying mediump vec2 var_texcoord0;

uniform lowp sampler2D DIFFUSE_TEXTURE;
uniform lowp vec4 tint;
uniform lowp vec4 saturation;
uniform lowp float desat;

void main()
{
	
    // Pre-multiply alpha since all runtime textures already are
    lowp vec4 tint_pm = vec4(tint.xyz * tint.w, tint.w);
    lowp vec4 color = texture2D(DIFFUSE_TEXTURE, var_texcoord0.xy);
    if (saturation.x < 1.0) {
    	lowp float desat = (color.x + color.y + color.z) / 3.0;
    	color.x = ((desat-color.x)*saturation.x)+color.x;
    	color.y = ((desat-color.y)*saturation.x)+color.y;
    	color.z = ((desat-color.z)*saturation.x)+color.z;
    }    
    gl_FragColor = color * tint_pm;
} 

Then you can send in tint value just like any other go.property.

You set the material in the Spinemodel (where you set scene and default animation as well)

/A


Big List of Defold Pro Tips!
#4

Can you please clarify this.
I have a spine model with this special FP. If I manually change the tint constant in the .material file it changes color - so the shader works.

I don’t really get how I can update the tint variable though.

I tried writing

go.propery("tint", vmath.vector4(1,0,0,1))

at the top of the GO that holds the spine-model but it didn’t work.

I’ve updated shader constants with Sprites using sprite.set_constant, but there is no spine.set_constant?


#5

No. spine.set_constant() is missing. It’s in the backlog.

DEF-1556


#6

Aight, but you still can do as @Andreas_Jirenius described earlier with go.property somehow?
What’s unclear to me is how I change the “tint” property.


#7

Yeah, you can set the constants buffer in the render script. See http://www.defold.com/ref/render#render.constant_buffer

Probably best to feed the values through messages though.


#8

Wouldn’t this approach result in that all Spines with the same tag in the material would change color at once?

Do you think it’s possible to somehow just change the tint of one specific Spine?


#9

Yes, it would. The workaround is to create a separate material for the spines you want to tint (with a unique tag) and draw that separately, but if you need to dynamically choose which spine to tint, it’s gonna be hairy.


#10

OMG I’m so sorry about this one.

I thought I remembered how I did it previously but I was obviously wrong.
Now I know you’ve already shipped your game but here’s the CORRECT solution anyway :stuck_out_tongue:

use go.set ! Nothing else.
Tint is already in the material and should be set if using go.set
In shame I created a full tutorial video about how you can do this (that might help others as well with the first steps in Spine handling)

https://www.livecoding.tv/video/defold-spine-and-materialsshaders/

Hope that will help some more :smile:


#11

Don’t worry @Andreas_Jirenius :smiley:
Thank you for the clarification!!


#12

Hi, thanks for “saturation shader” example.

My question touch this example not a topic starter theme. I think better continue thread here without start new topic.

You example works perfect! But only for sprite component. If i try do same with tilemap - nothing changed.

  1. i copy material, vp, fp from buitins
  2. extend fp with you code
  3. change tilemap material on my custom material

But this dont work ( I use tilemape as mask for level with background, background affected saturation (with another custome material) but tilemap - no. I check changes several tries i dont foun error. Maybe i do something else wrong?

Thanks.


#13

i use “in material” saturation constant, but now change to right way throught message like

go.set("/background#sprite", "saturation", vmath.vector4(1, 0, 0, 0))

All good, saturation applyed.

But for tilemap with modified tile map material

go.set("/background_mask#tilemap", "saturation", vmath.vector4(1, 0, 0, 0))

i catch error "’/background_mask#tilemap’ does not have any property called ‘saturation’"
of cause i setup “saturation” constant in material definition.

Is material not properly applyed to tilemap ?
I test “tint.w” and see that this property appllyed properly

go.set("/background_mask#tilemap", "tint.w", 0.1)

all is good, tint works perfectly.

Maybe tilemap material defold user cannot change and used old “buildins” material in all cases (even if change it)?


#14

You are probably not using your custom material properly. I tried adding saturation to a copy of the tilemap material from builtins and it worked like a charm. Double check that you aren’t accidentally using the wrong material or that the material is referencing the fragment shader from builtins.


#15

Thkx for investigation, this is helpfull. Ok i tripple check this stuff tomorrow. Sorry for trouble (


#16

Sorry, i found missprint in multi layer scene (
Yes, all working good, thanks.