Koszt wiązania shaderów może nie być trywialny, ale nie będzie twoim wąskim gardłem, chyba że renderujesz tysiące przedmiotów bez grupowania wszystkich obiektów, które używają tych samych shaderów.
Chociaż nie jestem pewien, czy dotyczy to urządzeń mobilnych, ale procesory graficzne nie są strasznie powolne z oddziałami, jeśli warunek jest między stałą a jednolitą. Oba są ważne, oba były używane w przeszłości i będą nadal używane w przyszłości, wybierz ten, który Twoim zdaniem byłby czystszy w twoim przypadku.
Dodatkowo istnieje kilka innych sposobów na osiągnięcie tego: „Uber-shadery” i trochę sztuczki ze sposobem łączenia programów cieniujących OpenGL.
„Uber-shadery” są zasadniczo pierwszym wyborem, pomijając rozgałęzienia, ale będziesz mieć wiele shaderów. Zamiast używać ifstwierdzeń, należy użyć preprocesor - #define, #ifdef, #else, #endif, i skompilować różne wersje, w tym prawidłowego #defines dla co trzeba.
vec4 color;
#ifdef PER_VERTEX_COLOR
color = in_color;
#else
color = obj_color;
#endif
Możesz także podzielić moduł cieniujący na osobne funkcje. Posiadaj jeden moduł cieniujący, który definiuje prototypy dla wszystkich funkcji i wywołuje je, połącz kilka dodatkowych modułów cieniujących, które zawierają odpowiednie implementacje. Użyłem tej sztuczki do mapowania cieni, aby ułatwić wymianę sposobu filtrowania na wszystkich obiektach bez konieczności modyfikowania wszystkich shaderów.
//ins, outs, uniforms
float getShadowCoefficient();
void main()
{
//shading stuff goes here
gl_FragColor = color * getShadowCoefficient();
}
Następnie mógłbym mieć wiele innych plików cieniujących, które definiują getShadowCoefficient(), niezbędne mundury i nic więcej. Na przykład shadow_none.glslzawiera:
float getShadowCoefficient()
{
return 1;
}
I shadow_simple.glslzawiera (uproszczony z mojego modułu cieniującego, który implementuje CSM):
in vec4 eye_position;
uniform sampler2DShadow shad_tex;
uniform mat4 shad_mat;
float getShadowCoefficient()
{
vec4 shad_coord = shad_mat * eye_position;
return texture(shad_tex, shad_coord).x;
}
Możesz po prostu wybrać, czy chcesz cieniować, czy nie, łącząc inny shadow_*moduł cieniujący. To rozwiązanie może mieć znacznie większy narzut, ale chciałbym myśleć, że kompilator GLSL jest wystarczająco dobry, aby zoptymalizować wszelkie dodatkowe koszty w porównaniu z innymi sposobami na to. Nie przeprowadziłem na tym żadnych testów, ale lubię to robić.