Странная и раздражающая ошибка 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.

Другие вопросы по тегам