IndieDoroid

Hi guys,

I can't seem to get this piece of code to work anymore :wounded:

I'm using Unity 2019.3.14f1

Did the Unity Runtime change by any chance?
private SkeletonRenderer _skeletonRenderer;
private Material _materialDefault;
private Material _materialDoor;

void Update()
{
_skeletonRenderer.CustomMaterialOverride[_materialDefault] = _materialDoor;
}
User avatar
IndieDoroid
  • Posts: 162

Harald

We did not change anything in this regard. The right two Spineboys in Spine Examples/Other Examples/Per Instance Material Properties still work as intended.

Which version of the spine-unity runtime are you using?
User avatar
Harald

Harri
  • Posts: 2076

IndieDoroid

Harald wrote:We did not change anything in this regard. The right two Spineboys in Spine Examples/Other Examples/Per Instance Material Properties still work as intended.

Which version of the spine-unity runtime are you using?
Hi Harld,

Dang.. I suck. Ok I think figured out what I did wrong.. I had to drag in the default material instead of call it from Resources at Start()

I looked at the spine example and noticed there was no start() call for the materials.


I have another question, which ties into the Custom Material Override... is there a way to adjust the EMISSION settings on the spine shader without creating a new instance of the material? :)

I'd like to swap different materials and affect the emission power for all the materials.
User avatar
IndieDoroid
  • Posts: 162

Harald

In theory, you could access the sharedMaterial property, but I don't think you really want to do that.

I assume that you are using materials with different textures (atlas pages) assigned.
You could use the MaterialPropertyBlock approach (as shown in the same example scene, the left two Spineboys) and have one shared MaterialPropertyBlock struct that serves as a parameter set used at all your materials. Nevertheless, you have to apply the block at every SkeletonRenderer to override the default material parameters.
User avatar
Harald

Harri
  • Posts: 2076

IndieDoroid

Harald wrote:In theory, you could access the sharedMaterial property, but I don't think you really want to do that.

I assume that you are using materials with different textures (atlas pages) assigned.
You could use the MaterialPropertyBlock approach (as shown in the same example scene, the left two Spineboys) and have one shared MaterialPropertyBlock struct that serves as a parameter set used at all your materials. Nevertheless, you have to apply the block at every SkeletonRenderer to override the default material parameters.
Thanks for the help Harald!

Yea I heard "sharedMaterial" isn't a good way to go. I'll try out 'MaterialPropertyBlock' as you suggested. Is there anything special about Spine's pixel lit shader that I should pay attention to?

For emission colors & strengths, are these the correct strings for the MaterialPropertyBlock?
_EmissionColor("Color", Color) = (0,0,0,0)
_EmissionPower("Emission Power", Float) = 2.0
I'm a newb on this topic.. so I'll need to do some research. What do you think of this as a starting tutorial?
http://thomasmountainborn.com/2016/05/25/materialpropertyblocks/

Thanks again! :nerd:
User avatar
IndieDoroid
  • Posts: 162

Harald

IndieDoroid wrote:For emission colors & strengths, are these the correct strings for the MaterialPropertyBlock?
_EmissionColor("Color", Color) = (0,0,0,0)
_EmissionPower("Emission Power", Float) = 2.0
Yes, these parameters are what you might be interested in. Note that "_EmissionColor" is what you need as the parameter name in the MaterialPropertyBlock, "Color" is what is displayed in the Inspector. So you can always have a try in the Inspector first and then look up the parameter names in the shader.
IndieDoroid wrote:What do you think of this as a starting tutorial?
http://thomasmountainborn.com/2016/05/25/materialpropertyblocks/
Yes, this blog post looks good! It's also good to see that some people are still able to write programming related blog posts in a world where young game developers tend to create long videos about them typing code instead (the number of illiterates must be on the rise it seems ;) ).
User avatar
Harald

Harri
  • Posts: 2076

IndieDoroid

Harald wrote:
Yes, these parameters are what you might be interested in. Note that "_EmissionColor" is what you need as the parameter name in the MaterialPropertyBlock, "Color" is what is displayed in the Inspector. So you can always have a try in the Inspector first and then look up the parameter names in the shader.
OOhh! I always wondered about that. It's strange that the string name wasn't what was supposed to be used.
Harald wrote:Yes, this blog post looks good! It's also good to see that some people are still able to write programming related blog posts in a world where young game developers tend to create long videos about them typing code instead (the number of illiterates must be on the rise it seems ;) ).
haha well I'm in favor of both. Text is good to be able to easily reference, but vids are good to see exactly what to do in a step by step manner.

Ok I'll get down to work and study!

Thanks for the help :)
User avatar
IndieDoroid
  • Posts: 162

Harald

IndieDoroid wrote:OOhh! I always wondered about that. It's strange that the string name wasn't what was supposed to be used.
That's why I mention this everywhere, but perhaps we should have created a video about it ;). Admittedly, I did not change the example scene scripts, I could add comments there as well.

The first go-to page when something does not work as expected should be the spine-unity documentation page.
IndieDoroid wrote:Thanks for the help :)
You're welcome.
User avatar
Harald

Harri
  • Posts: 2076

IndieDoroid

Harald wrote:That's why I mention this everywhere, but perhaps we should have created a video about it ;). Admittedly, I did not change the example scene scripts, I could add comments there as well.
Ahh there it is. But I think for non-coders like myself.. this would be hard to understand. At least until I've banged my head on the wall long enough. :grinteeth:

Note: Parameter names used at a MaterialPropertyBlock, such as _FillColor or _FillPhase, have to match the name of the respective shader variable. This will differ from the names displayed in the Inspector, such as Fill Color and Fill Phase. To view the shader parameter names, you can open the .shader file (via the Material's gear icon menu, select Edit Shader) and have a look at the top-most secion called Properties { .. }. There you will find a listing of all names, starting with an _ character in Spine shaders.
Harald wrote:The first go-to page when something does not work as expected should be the spine-unity documentation page.
Yea I go there often, quite useful! Answered many questions I had before :)


I guess another question that pops up is ... Why use custom material overrides when material property blocks are much better on performance? :think: I was using overrides to have one version of the shader with Overlay enabled and another version without. Would property blocks be a better alternative to control the Overlay bool's enable\disable?
User avatar
IndieDoroid
  • Posts: 162

Harald

IndieDoroid wrote:Ahh there it is. But I think for non-coders like myself.. this would be hard to understand. At least until I've banged my head on the wall long enough.
Thanks for the input. I have now made the text more easily understandable, could you please have a look at it, whether it's clear at first sight now?
IndieDoroid wrote:Why use custom material overrides when material property blocks are much better on performance? :think: I was using overrides to have one version of the shader with Overlay enabled and another version without. Would property blocks be a better alternative to control the Overlay bool's enable\disable?
Do you see dramatic performance differences? It should not matter much in your typical Spine skeleton case. CustomMaterialOverride is a bit easier to work with than the MaterialPropertyBlocks.
User avatar
Harald

Harri
  • Posts: 2076

IndieDoroid

Harald wrote:Thanks for the input. I have now made the text more easily understandable, could you please have a look at it, whether it's clear at first sight now?
Thanks for the updated documentation. I need to actually code it out myself to see if I can follow along. but I think it's more clear. :)

I have a question though. I don't quite understand >PropertyToID.
When you need to set a property frequently, you can use the static method: Shader.PropertyToID(string) to cache the int ID of that property instead of using the string overload of MaterialPropertyBlock's setters.
int[] additionalTexturePropertyIDsToCopy = new int[] { Shader.PropertyToID("_BumpMap") };
Are those just values that affect the _BumpMap's strength or it's actually the only way to reference the Bump Map? And how come it's an array? :bigeye:
Harald wrote:Do you see dramatic performance differences? It should not matter much in your typical Spine skeleton case. CustomMaterialOverride is a bit easier to work with than the MaterialPropertyBlocks.
I haven't gotten to the phase of optimization to be able to answer it haha. I'll let you know. I wanted to be able to adjust the outline and emission power without creating new material instances. But I notice CustomMaterialOverride creates new material instances.. unless I'm doing something incorrect. :wounded:

Thanks for the help! :nerd:
User avatar
IndieDoroid
  • Posts: 162

Harald

IndieDoroid wrote:Thanks for the updated documentation. I need to actually code it out myself to see if I can follow along. but I think it's more clear.
Thanks for the feedback. :)
IndieDoroid wrote:I have a question though. I don't quite understand >PropertyToID.
https://docs.unity3d.com/ScriptReference/Shader.PropertyToID.html
Are those just values that affect the _BumpMap's strength or it's actually the only way to reference the Bump Map? And how come it's an array?
It's an integer-based way of addressing a shader parameter, rather than using strings.
It's an array since this way you can use multiple layers and not only one (normalmap and emission map for example). Here it's only one.
User avatar
Harald

Harri
  • Posts: 2076

IndieDoroid

Thanks!
Harald wrote:It's an integer-based way of addressing a shader parameter, rather than using strings.
It's an array since this way you can use multiple layers and not only one (normalmap and emission map for example). Here it's only one.
Hmm ok I guess I need to play around with it via code to truly understand it. Thanks!
User avatar
IndieDoroid
  • Posts: 162

Harald

You're welcome. Sorry that it's still not completely clear according to your reply. Perhaps this example makes more sense:
// lets assume the _BumpMap param ID is 111, and _EmissionMap ID is 222.
int[] additionalTexturePropertyIDsToCopy = new int[] { Shader.PropertyToID("_BumpMap") };
// additionalTexturePropertyIDsToCopy is of size 1 and contains one int { 111 }

int[] additionalTexturePropertyIDsToCopy = new int[] {
Shader.PropertyToID("_BumpMap"),
Shader.PropertyToID("_EmissionMap")
};
// additionalTexturePropertyIDsToCopy is of size 2 and contains the ints { 111, 222 }
User avatar
Harald

Harri
  • Posts: 2076


Return to Unity