• Unity
  • Post Processing with URP not working with Spine Assets

Related Discussions
...

Thanks for getting back to me, Harald! Unfortunately, I still couldn't figure this out. Toggling Advanced - Add Normals or Advanced - Solve Tangents along with Fixed Normals did not manage to solve the issue of the lighting only effecting assets focused around where the X-axis equals 0.

I'm going to try attaching a normal map to my assets and configuring it from there to see if they function as intended then. I'll edit this post once I have updated the scene.


Actually... 😐 are there resources for where I can find how to attach Normals and Emission Maps?

I just created a simple modification to the URP 3D SkeletonLit shader with a toggle to enable Lit From Behind. It's rather simple, as it's just the absolute value of the dot product abs(dot(lightdir, normal)) is used instead of the dot product.

half3 LightingLambertLitFromBehind(half3 lightColor, half3 lightDir, half3 normal)
{
   half NdotL = saturate(abs(dot(normal, lightDir)));
   return lightColor * NdotL;
}

#ifdef _LIT_FROM_BEHIND
#define LightingLambert LightingLambertLitFromBehind
#else
#define LightingLambert LightingLambert
#endif

com.esotericsoftware.spine.urp-shaders-SkeletonLitFromBehind.zip

It's just a simple solution here.
While editing the Sprite shader as well I noticed that the result is rather unintuitive since a normalmap would then be strangely lit here. Anyway, I included it in the zip package below with the required file-overrides. For the Sprite shader you will need to switch Inspector to debug mode and add _LIT_FROM_BEHIND to the shader keywords to enable it, since the GUI code would otherwise need to be modified as well.


Harald написав

Toggling Advanced - Add Normals or Advanced - Solve Tangents along with Fixed Normals did not manage to solve the issue of the lighting only effecting assets focused around where the X-axis equals 0.

Do you still need this given the lit-from-behind functionality?
If yes, please post a screenshot of the problem.

Harald написав

Actually... 😐 are there resources for where I can find how to attach Normals and Emission Maps?

What exactly do you have problems with? You create normal and emission maps in the editor of your choice based on the normal atlas texture (with Photoshop, Substance Alchemist, etc.) and assign the textures to the slot in the Material Inspector.


I forgot to mention this above: I decided against adding the Lit From Behind feature officially since it's a very narrow use case. What will be added is an option for lighting the back-face at the SkeletonLit shader, a parameter Double Sided Lighting.


Harald написав

What will be added is an option for lighting the back-face at the SkeletonLit shader, a parameter Double Sided Lighting.

This feature has just been completed, all SkeletonLit shaders now provide a Double Sided Lighting parameter to properly light the back-face as well.
New 3.8 spine-unity, URP and LWRP packages are available for download here as usual:
Spine Unity Download: Download

Harald написав

What exactly do you have problems with? You create normal and emission maps in the editor of your choice based on the normal atlas texture (with Photoshop, Substance Alchemist, etc.) and assign the textures to the slot in the Material Inspector.

Okay, I'll give this a try soon. The main problem is simply that I don't know how to attach those maps to my Spine assets, but truthfully, I haven't done the research on it yet. I'll try attaching them and reading some tutorials on it and then maybe get back to you when I succeed/fail. That might be a post for another problem later down the line.

Harald написав

This feature has just been completed, all SkeletonLit shaders now provide a Double Sided Lighting parameter to properly light the back-face as well.

I downloaded the new version and reinstalled the URP/LWRP packages and gave it a try. Awesome work! Again, I super appreciate you doing all of this to help me out. However... tragically, I think we miscommunicated. The Lit From Behind functionality I poorly described aimed to light the front of the asset where the light was behind it.

In this first image, the asset is lit as intended with the light in front of the asset.

In this second image, the asset is unlit with the light behind the asset.

Sadly, lighting the asset from the other side isn't the desired effect, instead I wanted the asset to be lit as if the light was cast in the front of the asset as seen in the first picture. The reason behind this is that the world is 3D with the characters being 2D. The characters can traverse the X and Z axis but their Spine's are always orthogonal to the Camera View. As a result, I wanted to implement a lighting system that applied in a unique way for these characters.

You've been such an amazing help, Harald, I completely understand if this exceeds the scope of the original post, and I will do my best to solve this problem on my own after I acquire further shader knowledge. Either way, again huge thanks.

buddhamon написав

Okay, I'll give this a try soon. The main problem is simply that I don't know how to attach those maps to my Spine assets, but truthfully, I haven't done the research on it yet. I'll try attaching them and reading some tutorials on it and then maybe get back to you when I succeed/fail. That might be a post for another problem later down the line.

Ah, sorry, I think I misunderstood your question. You have to use a shader which provides the Normal Map parameter at the Material Inspector. The Spine/Sprite/Vertex Lit and Spine/Sprite/Pixel Lit shaders provides this for the normal pipeline, the shaders Universal Render Pipeline/2D/Spine/Sprite and Universal Render Pipeline/Spine/Sprite for URP.
And in case you mean that: You currently cannot assign a normalmap attachment image in the Spine Editor. This is only done in the spine-unity runtime side.

It's best if you take a look at Stretchyman's Material in the URP 3D Shaders example scene that comes with the Spine URP extension package. This shows a normalmap assigned. For the normal render pipeline, it's shown in the Sprite Shaders example scene.


Harald написав

Sadly, lighting the asset from the other side isn't the desired effect, instead I wanted the asset to be lit as if the light was cast in the front of the asset as seen in the first picture

Hm, this is strange, I implemented it in a way which should light it as your first image shows, even when the light is placed behind (which was the whole point).

Which of the two shaders are you using? If you are using the Sprite shader: did you add _LIT_FROM_BEHIND to the shader keywords as described above to enable it?

Thanks for your kind words!

Harald написав

And in case you mean that: You currently cannot assign a normalmap attachment image in the Spine Editor. This is only done in the spine-unity runtime side.

Oh! Okay, this is very interesting. I will try to figure out how to create correct maps for my Spine assets using the Universal Render Pipeline/Spine/Sprite shader. Thanks for the clarification! I've looked at the Stretchyman Material a few times in the past, but I struggled a little on how to generate the .png file for each map. I'll look into it again though with my fingers crossed.

Harald написав

Hmm, this is strange, I implemented it in a way which should light it as your first image shows, even when the light is placed behind (which was the whole point).

Ah. Sorry, I completely misread what you said in your previous post! My apologies! Yes, after I implemented what you suggested it worked fine for Skeleton Lit. HUGE thanks! There was one hiccup with the dot product getting zeroed out when the normal and lightDir were on the same Z-Axis, which made the object black/unlit. Since I will probably be only using point lights in my project, I changed the function to:

half3 LightingLambertLitFromBehind(half3 lightColor, half3 lightDir, half3 normal)
{
   half mag1 = length(normal);
   half mag2 = length(lightDir);

   return lightColor * saturate(mag1 * mag2);
}

... which produced the desired effect. I'm not entirely sure what each variable does nor have I ever worked in HLSL, but it seemed to work for the time being. Hoping this code doesn't cause the world to catch on fire! :grinteeth:

Using specifically the Stretchyman's Material in the URP 3D Shaders example scene along with the Sprite shader, I see what you mean with the asset looking a little strange while Lit From Behind is enabled. The normalmap and its lighting definitely seems a little off when the light is behind the asset. For the time being I think I will stick with the Skeleton Lit shader in the URP/Spine package without using a normal or an emission map. Once I figure out how to incorporate the Sprite shader with the attached maps/textures, I will revisit the Sprite shader you have provided and see if there is an alternative solution to the lighting that yields a symmetrical result if the asset has Lit From Behind enabled.


I just tested it all out, depth of field, 3D lighting with 2D assets, URP and Spine, bam! It really works wonderfully for the time being. Thank you so, so much again, Harald, I really, really am grateful for all your help. If you are ever in Los Angeles, let me know and I will gladly buy you dinner! :grinteeth:

buddhamon написав

There was one hiccup with the dot product getting zeroed out when the normal and lightDir were on the same Z-Axis, which made the object black/unlit. Since I will probably be only using point lights in my project, I changed the function to:

No, the dot product is zero when the angle is 90 degrees. This is intended, this is how lighting flat surfaces works with Lambert shading (and also with more complex models) - light is dimmed to black when the light angle gets parallel to the surface.

That's why I asked why you want the light to affect the sprite from the back. Now I guess what you want is that light affects the model depending on distance and independent of the angle?

buddhamon написав

half mag1 = length(normal);
half mag2 = length(lightDir);
return lightColor * saturate(mag1 * mag2);

That code does not make a lot of sense. The lenght of the normal is definitely 1, length of lightDir could be non-normalized at point lights and therefore return the distance. At directional lights this returns 1, which is unlikly that what you want. Note that with your code changes, your Skeleton is now lit respecting the angle from the front, and completly differently, ignoring the angle, from behind.

Perhaps you should think about what you really want your light to behave like, how your light should affect your Skeleton.
.. or not, if it looks good, it's good 🙂.

buddhamon написав

I just tested it all out, depth of field, 3D lighting with 2D assets, URP and Spine, bam! It really works wonderfully for the time being. Thank you so, so much again, Harald, I really, really am grateful for all your help. If you are ever in Los Angeles, let me know and I will gladly buy you dinner!

Very glad to hear that you're happy with the results, thanks for your kind words and the offer! :grinteeth: No need to buy me anything, we're here to help.

5 днів пізніше
Harald написав

No, the dot product is zero when the angle is 90 degrees. This is intended, this is how lighting flat surfaces works with Lambert shading (and also with more complex models) - light is dimmed to black when the light angle gets parallel to the surface.

That's why I asked why you want the light to affect the sprite from the back. Now I guess what you want is that light affects the model depending on distance and independent of the angle?

[...]

Perhaps you should think about what you really want your light to behave like, how your light should affect your Skeleton.
.. or not, if it looks good, it's good 🙂.

Yea, I think you might be right that I need to do some more thinking about what effect I'm looking for. At the moment I think I want to do a hybrid of Lambert shading and radial distance influencing the lighting (independent of the angle). Of course it sounds odd, but I definitely want the asset to be still lit when it is orthogonal to the light source while additionally it would still be nice to have the normals be influenced by the light's angle. Perhaps some weighted addition could solve this in the future, but I definitely will need to do some experimenting first.

However, regardless of lighting, an issue popped up today when I added opacity to my URP/Spine/Sprite shaded asset. Essentially the 3D background behind the Sprite background became visible through the asset, seen here:
The asset also has Write to Depth enabled with a Z Spacing of -0.001 (I wanted to create a Depth of Field effect in the scene as well). Not quite sure what logical errors I might be making to make the renderer skip the sprite background, but maybe I need to enable the ZWrite on all my Sprites in the scene? I'll look into it over the weekend, but either way, sorry for the hassle again.. :tear:

buddhamon написав

Essentially the 3D background behind the Sprite background became visible through the asset, seen here:

It's a bit hard to see here what the expected result would be: What is the Sprite background here? Is it the purple are behind the skeletons?
Could you provide a comparison shot of what it should look like?

Harald написав

Could you provide a comparison shot of what it should look like?

Of course! The following is a better image with labels. Here the 3D background is getting rendered through the Spine assets, ignoring the purple Sprite background that lies between them.
The next image is a more expected result. Despite the Spine assets still not rendering the purple Sprite background behind them, it is nonetheless more true to what the expected result ought to be, as the 3D world is isn't seen behind them (even though it has been removed in this image to yield a more accurate result).

Unfortunately, I tried removing the opacity on each Spine and using another technique for highlighting a Spine Skeleton, but upon closer inspection, the 3D world is still rendered behind the assets on other points where opacity is present, again ignoring the purple Sprite background.In this last image you can see a vague green outline of the 3D world behind the asset even though the Spine's opacity is set to 1.

I have some ideas how to 'band-aid' the problem, but I would love some pointers if I am missing something simple.

Thanks for posting the additional screenshots, now I know what you mean. This seems to be a problem with render order. The Spine skeletons (with ZWrite enabled) are drawn directly after your 3D background, then after that the transparent Sprite mid-background is drawn, failing Z-test at the semi-transparent (half-green) pixels.

So the solution would be to adjust the render queue to draw the Skeletons later, or to draw the Sprite mid-background earlier. Could you show screenshots of your current Material settings at both the Sprite mid-background and the Spine skeletons?

buddhamon написав

In this last image you can see a vague green outline of the 3D world behind the asset even though the Spine's opacity is set to 1..

The skeleton's alpha value if only half of the equation, the other half comes from the texture alpha, which is semi-transparent at your border (as on any typical border).

Harald написав

Could you show screenshots of your current Material settings at both the Sprite mid-background and the Spine skeletons?

Definitely, the first image is my material for my Spine skeletons, I am using the most recent Spine-Unity and URP Shaders packages:
The Sprite background is currently Unity's Sprites-Default Material. To err on the side that this is still useful information, here are the material and shader files respectively: I might soon be updating the background to a new Sprite shader (or to a Spine asset) so that my background can have normals that better interact with the scene's lighting. Either way, these are my current settings.

This is most likely overkill, but here is also my MeshRenderer and SkeletonAnimation settings:

Harald написав

So the solution would be to adjust the render queue to draw the Skeletons later, or to draw the Sprite mid-background earlier.

Okay, gotcha. I will most likely look into this today.

I just had a look at it and it is indeed due to the render queue value being set to the default AlphaTest queue value 2450 when ZWrite is enabled. Unfortunately the Render Queue (offset) material parameter allowed too narrow changes via the range slider 0-49. We just released a fix for the Sprite shader GUI changing it to an int value, you can then set it to 550 to get the desired render queue 3000. We have also added a preview line below showing your what the current value is set to.

The new 3.8 spine-unity package can be downloaded here as usual (it affects all Sprite shaders, including URP and LWRP packages):
Spine Unity Download

Harald написав

We just released a fix for the Sprite shader GUI changing it to an int value, you can then set it to 550 to get the desired render queue 3000. We have also added a preview line below showing your what the current value is set to.

Awesome, this is definitely what I was looking for. I really struggled to find information on rendering queues yesterday after looking into it for about an hour, so your help was perfectly on time!

Thanks a ton, as always, you're my hero. Hopefully this will be my last problem with my URP and Spine environment 😢 Definitely looking forward to being less of a bother for you guys! Thanks again!


Nooo, spoke too soon. Changing the render queue offset broke my Depth of Field effect, which makes sense. I'll play around with the offset to find a threshold that allows for both this effect and lets objects be rendered as intended. In the event that this doesn't work, I may just have to give my Sprite assets a ZWrite feature or change their render queue values.


Okay, I found that adding the asset to the Background queue (setting the offset below -450), seemed to work. The asset is still able to go behind other Sprite and 3D GameObjects in the World Space and the Depth of Field effect still works without needing to be adjusted. I'm not sure how fragile this setup is, but at least it's working for the moment.


If you are curious, this is a dropbox link to a GIF that is a proof of concept of what I was trying to make: https://www.dropbox.com/s/qbvut4n0bi9vt5n/movie.gif?dl=0

...Maybe that might help put my madness into perspective? Hmm... Doubtful.

Glad to hear you found a solution! Alpha testing combined with alpha blending can produce a lot of headaches unfortunately..

Your game already looks cool, the DOF effect and all the effort seems to pay off! 🙂