Я рисую спрайты на экране, используя вершинный шейдер, фрагментный шейдер и небольшое количество текстурного атласа (изображения, которые содержат десятки меньших спрайтов).Я стремлюсь использовать один вызов рисования для всей сцены, поэтому необходимо создать шейдер, который может динамически выбирать текстуру на основе атрибута.Каждый текстурный атлас связывается последовательно, и плоский атрибут textureid
отправляется для определения используемой текстуры, а область этой текстуры отправляется uv
.
В спецификации GLSL 3.30 говорится, что массивы сэмплеровнужно постоянное выражение в качестве индекса, но следующие компиляции и ссылки без ошибок (на последней версии драйвера Nvidia):
#version 330
uniform sampler2D sampler[4];
in vec2 uv;
flat in int textureid;
out vec4 endcolor;
void main() {
endcolor = texture(sampler[textureid], uv);
}
Я не могу гарантировать, что это работает на всех аппаратных средствах, и я не совсем понимаю, почемусвязаны без каких-либо предупреждений.Затем я решил попробовать следующее:
void main() {
if (textureid == 0) {
endcolor = texture(sampler[0], uv);
} else if (textureid == 1) {
endcolor = texture(sampler[1], uv)
} else if (textureid == 2) {
endcolor = texture(sampler[2], uv);
} else if (textureid == 3) {
endcolor = texture(sampler[3], uv);
} else {
endcolor = vec4(1.0, 1.0, 1.0, 1.0);
}
}
Я узнал, что это приведет к неопределенному поведению, так как оно зависит от неравномерного управления потоком.Текстуры, которые он выбирает, зависят от входного атрибута.Затем я обновил его до:
void main() {
vec4 one = texture(sampler[0], uv);
vec4 two = texture(sampler[1], uv);
vec4 three = texture(sampler[2], uv);
vec4 four = texture(sampler[3], uv);
if (textureid == 0) {
endcolor = one;
} else if (textureid == 1) {
endcolor = two;
} else if (textureid == 2) {
endcolor = three;
} else if (textureid == 3) {
endcolor = four;
} else {
endcolor = vec4(1.0, 1.0, 1.0, 1.0);
}
}
Из этих трех методов:
- Какие из них вызывают неопределенное или ошибочное поведение, а какие нет и почему?
- Есть ли другие методы, которые были бы лучше (кроме
sampler2DArray
)? - Почему первый метод продолжал компилировать, связывать и работать без ошибок?
Я понимаю, что могу использовать sampler2DArray
, но мои изображения могут быть разных размеров.