I'm trying to tint to my spine unity skeleton animation with overlay gray scale style color.
I'm using URP/Spine/Sprite shader.
And we want make tint color's alpha variable: alpha value based on different position on each attacment itself (not world position / not whole skeleton, something like Attachment Space reference coordinates)
The current problem is how to get a pixel's (x, y) position relative to its attachment's bounding box in fragment shader.
Is it possile to get this information through mesh data?
Or maybe instead of 2D only 1 dimension is also enough so that we could get a float(01) for lerp(t) .
Thanks for any advice!
How to get a pixel's coordinates relative to attacment's bounding box?
@ara It's not a straightforward task unfortunately. You could use SkeletonRenderer.OnPostProcessVertices
to e.g. encode the location data in the unused vertex normals, and access SkeletonRenderer.Skeleton.DrawOrder
to know which vertex corresponds to which attachment. This will however fail if clipping is active and is removing vertices and adding new ones.
If modifying the spine-unity source code is an option, you could also modify the MeshGenerator
code to directly add location information.
A different solution would be to add a second texture atlas layer (like a normal-map) which contains only the black & white gradient. You could do this either by programmatically packing your attachments in the same layout as normal attachment images (with disabled whitespace stripping, or identical transparent areas). Or alternatively you could draw over the atlas image after it has been exported. You then however need to redo or re-arrange parts of the atlas when added attachments changes the packing layout.
Harald
Thank you for your explanation Harald!
We're planning to tint a mix&matched character with gradient ramp per attachment.
We already have a function to sample a gradient which has a float parameter "t"(a value between 0 and 1 which means color position in ramp texture).
In most cases the "t" can be an worldspace height value or NdotL, but none of them is suited for tint a single attachment. For example, we want a cloth's color is black to white from cloth's bottom to its top instead of character's foot to character's head.
Yes we have considered adding a new atlas solution.However we have more than 400+ individual attachments so we decide to ask you if there is any source code solution before repainting a black & white gradient version for all of them.
ara For example, we want a cloth's color is black to white from cloth's bottom to its top instead of character's foot to character's head.
I see, thanks for the example. Just be aware that this won't look good on anything with large wrinkles, as the gradient will follow just the bone direction and not the cloth. If that's no big issue, that's fine of course. Just consider that you might end up with your artists painting custom maps in the end otherwise.
ara However we have more than 400+ individual attachments so we decide to ask you if there is any source code solution before repainting a black & white gradient version for all of them.
You could programmatically generate simple gradient attachments of the same size and extract the alpha-channel of your main attachment. This would involve some image-generation/manipulation scripting (e.g. using imagemagick), but might be a rather quick, yet flexible solution. Then you could manually edit those gradient attachment images where the linear gradient is not following cloth-wrinkles well enough, achieving both a quick base-line as well as provide full artist-customizability.
@ara Also be aware that if you don't want to setup fully automated atlas texture-export scripts (while we've provided a script which should cover many use-cases here), you could via a simple script copy just the project and replace the main attachment images with their gradient images. Then you can export the same way again without the need for setting up export scripts for atlas export if you want to avoid that for some reason.
ara Do you think it is possible to get/calculate a float t value (y axis per attachment rect) from any existed APIs ?
We can modify the MeshGenerator code then write t value into uv2or3 without caring wrinkles.
It is possible, but rather tedious, and when using clipping it becomes even much more complicated.
In order to get the initial uv coords (from which you need the y coord) before applying the atlas-mapping, you would need to access each MeshAttachment
's regionUVs
array field (containing float u
and v
of each mesh attachment's vertex), or in case of RegionAttachment
you can assume the vertex order being: bottom right, bottom left, upper left, upper right. See RegionAttachment.ComputeWorldVertices and MeshAttachment.
So in order to avoid this, the alternative solution using automatically generated images would be much less effort and more flexible.