I’ve used go.animate("#sprite", "tint", ...
) to change the tint of a sprite. But when I set the color to vmath.vector4(1,1,1,1)
it appears the same as the normal sprite. Is there a way to make tint a sprite white, or another way to increase the brightness or gamma of a sprite?
You would need to write a custom shader. It’s not difficult! Look in the builtins folder you will see a sprite material and a vp and fp. You will want a copy of the material and the fp. Then open the copy of the material and direct its fp to the new location of your new fp. Then edit the fp which stands for fragment program. Next you can search google for a term such as “brightness fragment shader” and get some ideas on how to modify the fp file to suit your needs. Remember to apply the new material to the sprites you want to modify. If you want multiple effects possible you need to include all code in the single material you’re using.
Tinting to 1,1,1,1 means that all color components are exactly as in the original image. Tinting to 0, 1,1,1 would remove the red color component of the image. Tinting to 1,1,1,2 would make it look brighter (or maybe not exactly brighter but perhaps lighter). I guess for best effect you’d need a custom shader, just as Pkeod suggests.
Thank you both for the insight. I’ll definitely dig into the custom shaders, but to me this seems like a feature a lot of people would want to change. Perhaps the base shader can be modified to easily toggle the brightness, or another shader could be packaged with the default project that includes a brightness toggle?
If you make a nice shader it can be added to one of the community bundles. Community assets are an important part of Defold development as well as minimal shipping sizes so it’s doubtful that the builtins would be added to.
I think you’ll get good results just by increasing alpha to above 1.0. I made an example with different kinds of sprite tint:
CODE: https://github.com/britzl/publicexamples/tree/master/examples/sprite_tinting
HTML5: http://britzl.github.io/publicexamples/sprite_tinting/index.html
sprite_color_add.zip (763 Bytes)
Here is a sprite material shader which can place a color layer above your sprite. To make fading effects or flash to solid white when taking damage.
go.animate("#sprite", "color_add.w", go.PLAYBACK_LOOP_PINGPONG, 1, go.EASING_OUTINQUAD, 2)
I added the custom material to my example. What I noticed though was that even when color_add was [1.0, 1.0, 1.0, 0.0] it gave a different result than with the default sprite material. The semi transparent edges of the Defold logo became sharper. I made a modification of the shader in my example to prevent this from happening.
@britzl Your example works great for my case trying to make a sprite brighter, thank you!
Is it possible to adapt this to not add brightness, but still add a color overlay? The problem with the default tinting is that changing the alpha makes the entire sprite opaque, not just the color overlay.
What I’d like to achieve is to add a red overlay to a sprite, and be able to independently set JUST the overlay opacity, not the opacity of the entire sprite. Do you think this is achievable with your example?
Isn’t this exactly what’s happening in three of the sprites in the top row? Their red, green and blue color components are increased. In my example quite much, but you could use lower values and the others removed. With less extreme values you’d get what you want, won’t you?
I’ve attached 3 images: The first is my original sprite, the second is my desired effect, and the third is my result when I call: go.animate(self.sprite_id, "color_add", go.PLAYBACK_ONCE_FORWARD, vmath.vector4(color.rgb(100,0,0, 1)), go.EASING_INOUTSINE, 0.1)
I’m trying to get a darker red overlay on the sprite, but when I increase the red value of color_add
, it always appears brighter.
Can you give a raw sprite to test with?
That’s exactly what the default “tint” does.
With tint: (0.87, 0.48, 0.48, 1)
It’s similar but I think there is still a difference in what he wants. I’m going to make another test shader soon which behaves more like photoshop layers.
New test in editor with color
at 50% opacity
and at 90% opacity
So instead of making the original sprite brighter it will simply layer a color on top with normal blending like photoshop layer withing any special blending mode set.
Here’s the shader code right now but it can still be modified more
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D DIFFUSE_TEXTURE;
uniform lowp vec4 blend_normal;
void main()
{
vec4 texColor = texture2D(DIFFUSE_TEXTURE, var_texcoord0.xy);
vec4 color = vec4(blend_normal.rgb * blend_normal.a + texColor.rgb * (1.0 - blend_normal.a), texColor.w);
texColor.rgba = color * texColor.w;
gl_FragColor = texColor;
}
Try it out and see if it gets you the result you want? You’ll need to add blend_normal in the material, this version also deletes the tint and color add for now. Then you set the xyz of the blend_normal to the rgb of the color you want, and w to the opacity.
sprite_blend_normal.zip (1.3 KB)
I think you will get very close to what you want by tinting it like this:
go.set("wrestler#sprite3", "tint", vmath.vector4(0.95, 0.7, 0.70, 1))
Or doing a color_add like this (will be a bit too red):
go.set("wrestler#sprite2", "color_add", vmath.vector4(0.1, -0.2, -0.2, 1))
I’m working on a set of shaders to duplicate all of the blending modes from most image editors like Photoshop so artists can have more control over effects like these how they might be used to doing them in image editors.