2012-01-09 4 views
6

Я пытаюсь написать простой геометрический шейдер, который просто проходит через вершины, прежде чем пытаться модифицировать материал.GLSL 1.5 Simple Geometry shader

Моей вершина затенение

#version 150 core 
in vec3 inPosition; 
in vec4 inColor; 

out vec4 vertexColor; 

void main() { 
    vertexColor = inColor; 
    gl_Position = vec4(inPosition, 1.0); 
} 

Моя геометрия затенение

#version 150 core 
layout (triangles) in; 
layout (triangle_strip, max_vertices=3) out; 

void main() { 
    gl_Position = gl_in[0].gl_Position; 
    EmitVertex(); 

    gl_Position = gl_in[1].gl_Position; 
    EmitVertex(); 

    gl_Position = gl_in[2].gl_Position; 
    EmitVertex(); 
    EndPrimitive(); 
} 

И мой фрагмент затенение

#version 150 core 
in vec4 vertexColor; 
out vec4 fragColor; 

void main() { 
    fragColor = vertexColor; 
} 

Без геометрии шейдеров, связанных с, все работает отлично. Однако, когда я связываюсь в геометрическом шейдере, он перестает работать. Что мне не хватает? Мне нужен мой шейдер Geometry для ввода vertexColor из моего вершинного шейдера, и если да, то как это делается?

+0

http://en.wikipedia.org/wiki/GLSL#A_sample_trivial_GLSL_geometry_shader? – n0rd

+0

Это не отвечает на мой вопрос. Мой геометрический шейдер точно такой же, как тот, который указан на этой странице, за исключением удаляемого цикла for. Однако это не сработает. Ничто не нарисовано. Также вершинные и фрагментарные шейдеры, показанные на этой странице, предназначены для glsl 1.20 Существует проблема, связывающая все это вместе, что я не понимаю, и не могу найти какую-либо информацию о том, как ее исправить. – user1139069

ответ

7

Моей геометрия шейдер точно так же, как и перечисленные на этой странице

Да, но ваш бесплатный вершинный и фрагмент шейдеры не.

Информация проходит через конвейер OpenGL следующим образом: во-первых, вершинный шейдер получает материал. Он передает свои результаты в геометрический шейдер, если он присутствует. Геометрический шейдер передает свои выходы в шейдер фрагмента (конечно, из-за обычного раскодирования треугольника). И шейдер фрагмента передает свои выходы на этап смешивания.

Ваш вершинный шейдер имеет два выхода: gl_Position и vertexColor. Однако ваш шейдер геометрии принимает только один вход: gl_in[0].gl_Position. Это не является законным в GLSL: если один этап выдает значение, следующий этап должен ввести его. Исключение составляют только значения GLSL, такие как gl_Position, который потребляется растеризатором.

Ваш передающий GS должен фактически передать данные через, если вы хотите, чтобы это проходило. Вам необходимо принять правильный ввод в GS:

in vec4 vertexColor[]; 

Однако глобальные переменные в GLSL нельзя назвать одинаковыми. Поэтому вы не можете взять vertexColor в качестве входа и в качестве выхода. Поэтому вместо того, вы должны изменить имя выхода (или использовать interface blocks): Теперь

out vec4 gsColor; 

Ваш пиксельный шейдер должен принимать in vec4 gsColor; и работать с этим.

Когда вы попытались связать эти шейдеры, ваш компилятор должен был предоставить вам соответствующий информационный журнал, объясняющий несоответствие. Получаете ли вы свои информационные журналы, когда ваши шейдеры не соединяются? Если нет, вы должны.

+0

Нужно ли gsColor быть массивом, и если бы я был добавлен вершин, как бы выход gsColor соответствовал добавленным вершинам? Если gsColor должен быть массивом, как я предполагаю, он должен быть, будут ли индексы этого массива соответствовать порядку вершин, которые я испускаю? – user1139069

+0

'gl_Position' в геометрическом шейдере также не является массивом. Вы пишете каждый вывод, а затем вызываете 'EmitVertex' для создания всех этих выходов. Вы устанавливаете 'gsColor' для каждой вершины, которую вы испускаете, точно так же, как вы устанавливаете' gl_Position' для каждой испущенной вершины. –

+0

Так что-то вроде 'gl_Position = gl_in [0] .gl_Position; gsColor = vertexColor [0] EmitVertex(); gl_Position = gl_in [1] .gl_Position; gsColor = vertexColor [1] EmitVertex(); '? – user1139069