- Home /
How do I find the index of a shader pass
I am not sure if I'm missing something obvious, but how do I resolve a shader pass name into an index I can use in Material.SetPass or CommandBuffer.DrawMesh*? The best I found is Material.passCount to get the number of passes. Do I need to manually store the correct pass index for each shader, or is there a Shader.PropertyToID equivalent for passes?
Answer by Jens_Restemeier · Jul 22, 2018 at 10:36 AM
So, to answer my own question from years ago: There is now a function https://docs.unity3d.com/ScriptReference/Material.GetPassName.html
Though I guess the Unity Renderer bases its pass selection on pass tags. So to pick the deferred pass you'll need to look for the tag "LIGHTMODE" "DEFERRED".
I found a lot of information is available through serialisation on the shader object, that doesn't seem to be covered by official API. Some of it is available through https://docs.unity3d.com/ScriptReference/ShaderUtil.GetShaderData.html
I am not sure at what point these values got added, but for example 2017.3 seems to have parsed shader info:
SerializedObject so = new SerializedObject (shader);
SerializedProperty subShaders = so.FindProperty ("m_ParsedForm.m_SubShaders");
for (int k = 0; k < subShaders.arraySize; k++) {
Debug.Log ("SubShader: " + k);
SerializedProperty subShader = subShaders.GetArrayElementAtIndex (k);
SerializedProperty passes = subShader.FindPropertyRelative ("m_Passes");
for (int i = 0; i < passes.arraySize; i++) {
Debug.Log ("Pass: " + i);
SerializedProperty pass = passes.GetArrayElementAtIndex (i);
SerializedProperty name = pass.FindPropertyRelative("m_State.m_Name");
Debug.Log("Name: " + name.stringValue);
SerializedProperty tags = pass.FindPropertyRelative ("m_State.m_Tags.tags");
for (int j = 0; j < tags.arraySize; j++) {
SerializedProperty tag = tags.GetArrayElementAtIndex (j);
SerializedProperty first = tag.FindPropertyRelative ("first");
SerializedProperty second = tag.FindPropertyRelative ("second");
Debug.Log (first.stringValue + ":" + second.stringValue);
}
}
}
Earlier versions of Unity, for example I looked at 5.4, only allow access to shader sourcecode, so getting name and pass info requires a custom parser. Sigh.
Answer by Bunny83 · Mar 17, 2016 at 04:52 PM
The shader pass name is quite irrelevant and i don't think there's any method to convert a pass name to an index. I also don't see the point for that. A shader executes it's passes in the order they appear inside the shader. The passes belong to that shader. So if you manually want to render something with a shader that has multiple passes you simply iterate through them starting at index 0 up to (Material.passCount - 1). If you use passes to combine different shaders into one, you use the pass wrong.
Have a look at Unity's standard shader. Obviously I don't want to execute all passes, but only the pass I'm building the command buffer for. I guess I'll have to hard-code the pass indices and make sure all shaders have the same pass setup.
Your answer
Follow this Question
Related Questions
Does the Web Player support PBR? 0 Answers
Lightweight shader doesn't properly apply to blender imported GameObjects 1 Answer
Using different UV for multiple model copies 2 Answers
Is there an any way to use batching with UV tiling? 1 Answer
Lit, Simple Lit and Complex Lit Shaders are not Avaiable 1 Answer