Странная и раздражающая ошибка GLSL
Мой вершинный шейдер выглядит следующим образом:
#version 120
uniform float m_thresh;
varying vec2 texCoord;
void main(void)
{
gl_Position = ftransform();
texCoord = gl_TexCoord[0].xy;
}
и мой фрагментный шейдер:
#version 120
uniform float m_thresh;
uniform sampler2D grabTexture;
varying vec2 texCoord;
void main(void)
{
vec4 grab = vec4(texture2D(grabTexture, texCoord.xy));
vec3 colour = vec3(grab.xyz * m_thresh);
gl_FragColor = vec4( colour, 0.5 );
}
в основном я получаю сообщение об ошибке "Ошибка в шейдере -842150451 - 0<9>: ошибка C7565: назначение переменной 'texCoord'"
Но у меня есть другой шейдер, который делает то же самое, и я не получаю ошибки, когда я компилирую это, и это работает!!!
Есть идеи, что может случиться?
1 ответ
Для начала, нет разумной причины для создания vec4 из texture2D (...)
, Текстурные функции в GLSL всегда возвращают vec4. Точно так же, grab.xyz * m_thresh
всегда является vec3, потому что скаляр, умноженный на вектор, не меняет размеры вектора.
Теперь здесь все становится интереснее... gl_TexCoord [n]
Используемая вами встроенная GLSL - это заранее объявленное изменение. Вы не должны читать из этого в вершинном шейдере, потому что он определяет вывод вершинного шейдера / ввод фрагмента шейдера.
Соответствующая встроенная переменная вершинного шейдера в GLSL 1.2 для получения текстурных координат для текстурного блока N на самом деле gl_MultiTexCoord<N>
Таким образом, ваши вершинные и фрагментные шейдеры должны выглядеть так:
Вершинный шейдер:
#version 120
//varying vec2 texCoord; // You actually do not need this
void main(void)
{
gl_Position = ftransform();
//texCoord = gl_MultiTexCoord0.st; // Same as comment above
gl_TexCoord [0] = gl_MultiTexCoord0;
}
Фрагмент шейдера:
#version 120
uniform float m_thresh;
uniform sampler2D grabTexture;
//varying vec2 texCoord;
void main(void)
{
//vec4 grab = texture2D (grabTexture, texCoord.st);
vec4 grab = texture2D (grabTexture, gl_TexCoord [0].st);
vec3 colour = grab.xyz * m_thresh;
gl_FragColor = vec4( colour, 0.5 );
}
Помнишь, как я сказал gl_TexCoord [n]
это встроенный меняется? Вы можете читать / писать в этом, вместо того, чтобы создавать свои собственные varying vec2 texCoord;
в GLSL 1.2. Я закомментировал строки, в которых использовался нестандартный вариант, чтобы показать вам, что я имел в виду.
Язык затенения OpenGL® (1.2) - 7.6 Различные переменные - стр. 53
Следующие встроенные переменные переменные доступны для записи в вершинный шейдер. Конкретный должен быть записан, если какой-либо функционал в соответствующем фрагментном шейдере или фиксированном конвейере использует его или состояние, полученное из него.
[...]
меняющийся vec4 gl_TexCoord []; // самое большее будет gl_MaxTextureCoords
Язык шейдеров OpenGL® (1.2) - 7.3. Встроенные атрибуты вершинного шейдера - стр. 49
Следующие имена атрибутов встроены в язык вершин OpenGL и могут использоваться из вершинного шейдера для доступа к текущим значениям атрибутов, объявленных OpenGL.
[...]
атрибут vec4 gl_MultiTexCoord0;
Суть в том, что gl_MultiTexCoord<N>
определяет атрибуты вершины (ввод вершинного шейдера), gl_TexCoord [n]
определяет переменную (вывод вершинного шейдера, ввод фрагментного шейдера). Стоит также отметить, что они недоступны в более новых (основных) версиях GLSL.