GLSL игнорирует равномерное сравнение bool в фрагментных шейдерах?
Я пытаюсь сравнить равномерный тип bool (type_2d) в GLSL, чтобы вывести один из двух типов сэмплера - sampler2D и samplerCube. Это используется исключительно для различения кубической карты (скайбокс, отражающие данные кубической карты и т. Д.) И sampler2d (альбедо-карты, карты нормалей и т. Д.).
Я попытался сравнить с целым числом, с плавающей точкой, а также с логическим значением, однако кадровый буфер всегда прибегает к черному экрану.
Принимая во внимание, результаты кубической карты работают отлично, если я жестко закодирую значение bool внутри "main", где, например, "type_2d = false" без равномерного присваивания, в отличие от анализа унифицированного значения из C++.
Вот код "GBuffer.f":
#version 420 core
layout(location = 0) out vec3 gPosition; // Position texel colour
layout(location = 1) out vec3 gNormal; // Normal texel colour
layout(location = 2) out vec4 gAlbedo; // Albedo texel colour
in vec3 _texcoord;
in vec3 _normal;
in vec3 _frag_pos;
uniform bool type_2d;
uniform sampler2D albedo; // Albedo and specular map
uniform samplerCube cubemap; // Skybox cubemap
vec4 final_colour;
void main()
{
gPosition = _frag_pos;
gNormal = normalize(_normal);
if (type_2d)
{
final_colour.rgb = texture(albedo, _texcoord.st).rgb;
final_colour.a = texture(albedo, _texcoord.st).a; // Emission
}
else
{
final_colour.rgb = texture(cubemap, _texcoord).rgb;
final_colour.a = texture(cubemap, _texcoord).a;
}
gAlbedo.rgba = final_colour;
}
Почему сравнения единообразных bool никогда не работают в фрагментном шейдере? Мне даже удалось получить единообразное значение из GLSL, и этап синтаксического анализа, кажется, работает отлично - это почти как если бы GLSL отказывался использовать его для сравнения, и, таким образом, возвращал образец текстуры NULL, создавая эффект черного экрана. Есть идеи?
2 ответа
В OpenGL один текстурный модуль имеет несколько целей привязки для разных типов текстур, например GL_TEXTURE_1D
, GL_TEXTURE_2D
, GL_TEXTURE_BUFFER
, GL_TEXTURE_CUBE_MAP
, Технически, вы можете привязать более одной текстуры к одному юниту.
По умолчанию, GL_TEXTURE0
является активной текстурной единицей, и все формы инициализируются 0
, включая образцы сэмплера. Так что, если вы просто glBindTexture()
2D-текстура и карта куба, вы получите именно это.
Однако, хотя привязка нескольких разных типов текстур к одной единице в одно и то же время в GL вполне допустима, вы можете просто выбрать одну конкретную текстурную цель каждой единицы. Спецификация основного профиля OpenGL 4.6, раздел "Образцы 7.11", стр. 155, прямо заявляет:
Не допускается иметь переменные разных типов сэмплера, указывающие на один и тот же текстурный блок изображения в программном объекте. Эта ситуация может быть обнаружена только при следующей команде рендеринга, которая запускает вызовы шейдеров, и
INVALID_OPERATION
ошибка будет сгенерирована.
Таким образом, даже если вы используете униформу для переключения между обоими путями, в программном объекте технически активны обе формы сэмплера, и, не устанавливая их для выборки из разных текстурных блоков, вы попадаете в запрещенную зону.
По какой-то странной причине мне пришлось установить glActoveTexture(GL_TEXTURE1); и glUniform1i(id, 1); для рендеринга текстуры кубической карты (даже если я не вызываю GL_TEXTURE0 раньше внутри геометрии paas). Я предполагаю, что текстурам кубической карты нужно это дополнительное значение смещения из-за типа сэмплера? Не могу думать ни о какой другой причине.