- Will the shader class restore a global dictionary from fetching all the names in the shaders in the project?
- What if 2 shader has 2 fields of the same name, like shader1’s “_Color”, shader2’s “_Color”? Will they two use the same ID?
- And when it comes to SetColor, because you can specify the shader object it will still work?
It’s generating a hash, not sure which method, maybe CRC32 as Animator StringToHash is using?
Yes. Shader.PropertyToID isn’t specific to a shader, it only cares about the string you pass to is.
You specify the material, or the material property block, yes.
really quick and thanks!!
If I may continue, why are some Properties seemingly controllable by AnimationClips and some are not?
You mean maybe the ID changed between your play but the animation clip still held the old ones?
No he means how the Legacy Animation is somehow unable to animate some material properties for seemingly no reason. It’s an old issue and it started happening when the Animator was introduced.
Wow. This is much more helpful than you can imagine.
Cheers!
I didn’t know the history of Animator’s introduction doing this, nor that Animator might not have this problem.
Have pretty much stopped using Animator, and definitely don’t use it for simple things like changing a property of a Shader in a Material.
One odd thing, just about every property in provided/packaged TextMeshPro shaders is animatable with Animation Legacy. But when making a new shader and inspector, with what I think are correct means of serialising and surfacing properties, in custom shaders and inspectors for TextMeshPro… nothing seems to work with Animation Legacy.
Not a hash… for most properties it’s a shockingly simple system. Each project has an internal list of shader property names. When it sees a new one, it gets added to the list. Shader.PropertyToID()
is probably close to:
int PropertyToID(string propertyName)
{
int index = ListOfShaderProperties.IndexOf(propertyName);
if (index == -1)
{
index = ListOfShaderProperties.Count;
ListOfShaderProperties.Add(propertyName);
}
return index;
}
The list gets created and added to when shaders are loaded, but also if you call that function with a property name it’s never seen before and doesn’t exist in any shader. Because it’s per-project, the ID for a particular property name might not be the same between projects, which is why the documentation says:
However for basically every Unity project the ID for _MainTex
is 1, _Color
is 9, etc. just because that’s the order it sees properties in from the built in shaders that load by default. Not sure what 0 is.
However there are also a lot of shader uniforms that are either hard coded, or at least have a hard coded offset. Any of the default engine uniforms set by native code appear to have IDs that are far outside the usual range.
-2147483648 glstate_matrix_projection
-2147483647 unity_MatrixV
-2147483646 unity_MatrixInvV
1073741862 _ProjectionParams
1073741863 _ScreenParams
1073741864 _ZBufferParams
The above uniforms are all in UnityShaderVariables.cginc in the order they appear in the file (with a gap between the matrices and the non-matrix values). You’ll notice the property ID numbers are sequential for these examples, but the matrices seem to start with an offset that is around -2147483648 (-2^31) and non-matrices seem to start with an offset around 1073741824 (2^30). Probably arbitrarily chosen.
edit: To clarify, these offsets are only for those built in uniforms. Matrix uniforms that aren’t part of the built in values are in the same numerical range “pool” as any other user defined uniform. I have a shader with a c# set matrix uniform, and that property ID is just right in the middle of all the other custom shader uniforms the project has. I don’t have any idea why these engine set matrix uniforms got special treatment.
By complete random chance, I found out the first non-matrix value appears to be unity_LightColor
as it has an ID of 1073741824, and I’ve not seen another built in uniform with a value lower than that. I have no idea why it’s that particular uniform, since it’s certainly no where near the top of the file. But other values in that file are also not entirely sequential, even though most are, which makes me think it’s just hardcoded somewhere in the native code.
Thank you so much, bgolus!