셰이더 바인딩 비용은 사소한 것이 아니지만 동일한 셰이더를 사용하는 모든 객체를 일괄 처리하지 않고 수천 개의 항목을 렌더링하지 않으면 병목 현상이 발생하지 않습니다.
이것이 이것이 모바일 장치에 적용되는지 확실하지 않지만 조건이 일정하고 균일 한 경우 GPU가 끔찍하게 느리지 않습니다. 둘 다 유효합니다. 둘 다 과거에 사용되었으며 앞으로도 계속 사용됩니다. 귀하의 경우에 더 깨끗하다고 생각되는 것을 선택하십시오.
또한 이것을 달성하는 몇 가지 다른 방법이 있습니다 : "Uber-shaders"와 OpenGL 쉐이더 프로그램이 연결되는 방식에 대한 약간의 속임수.
"우버 셰이더"는 기본적으로 분기를 제외한 첫 번째 선택이지만 여러 셰이더가 있습니다. 대신 사용하는 if
- 문을, 당신은 전처리 사용 #define
, #ifdef
, #else
, #endif
, 적절한 등 다양한 버전, 컴파일 #define
당신이 필요에들.
vec4 color;
#ifdef PER_VERTEX_COLOR
color = in_color;
#else
color = obj_color;
#endif
셰이더를 별도의 기능으로 나눌 수도 있습니다. 모든 함수에 대한 프로토 타입을 정의하고 호출하는 하나의 셰이더를 만들고 적절한 구현을 포함하는 추가 셰이더를 연결하십시오. 모든 셰이더를 수정하지 않고도 모든 객체에서 필터링이 수행되는 방식을 쉽게 교체 할 수 있도록 섀도 매핑에이 트릭을 사용했습니다.
//ins, outs, uniforms
float getShadowCoefficient();
void main()
{
//shading stuff goes here
gl_FragColor = color * getShadowCoefficient();
}
그런 다음, getShadowCoefficient()
필요한 유니폼 등 을 정의하는 다른 여러 셰이더 파일을 가질 수 있습니다 . 예를 들어, 다음을 shadow_none.glsl
포함합니다.
float getShadowCoefficient()
{
return 1;
}
그리고 shadow_simple.glsl
포함합니다 (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;
}
다른 shadow_*
셰이더 를 연결하여 음영을 원하는지 여부를 간단히 선택할 수 있습니다 . 이 솔루션에는 더 많은 오버 헤드가있을 수 있지만 GLSL 컴파일러는이를 수행하는 다른 방법과 비교하여 추가 오버 헤드를 최적화하기에 충분하다고 생각하고 싶습니다. 나는 이것에 대한 테스트를 실행하지 않았지만 그것이 내가 좋아하는 방법입니다.