2015-05-10 1 views
1

Я пытаюсь реализовать некоторое базовое освещение и затенение после учебника над here и here.Простой шейдер GLSL (светлый) вызывает мерцание

Все работает более или менее, но из-за затенения я получаю какое-то странное мерцание на объектных поверхностях.

У меня есть два изображения, чтобы показать вам, как выглядит эта проблема.

Flickering on surface

Another example

Я думаю, что проблема связана с тем, что я передаю координаты вершин из вершинного шейдера в пиксельный шейдер, чтобы вычислить некоторые световые переменные, как указано в приведенных выше связанных учебники.

Вот несколько исходных кодов (вырезанный несвязанный код).

Vertex Shader:

#version 150 core 

in vec4 pos; 
in vec4 in_col; 
in vec2 in_uv; 
in vec4 in_norm; 

uniform mat4 model_view_projection; 


out vec4 out_col; 
out vec2 passed_uv; 
out vec4 out_vert; 
out vec4 out_norm; 


void main(void) { 
    gl_Position = model_view_projection * pos; 

    out_col = in_col; 
    out_vert = pos; 
    out_norm = in_norm; 
    passed_uv = in_uv; 
} 

и фрагмент Shader:

#version 150 core 

uniform sampler2D tex; 

uniform mat4 model_mat; 

in vec4 in_col; 
in vec2 passed_uv; 
in vec4 vert_pos; 
in vec4 in_norm; 

out vec4 col; 

void main(void) { 

    mat3 norm_mat = mat3(transpose(inverse(model_mat))); 
    vec3 norm = normalize(norm_mat * vec3(in_norm)); 

    vec3 light_pos = vec3(0.0, 6.0, 0.0); 
    vec4 light_col = vec4(1.0, 0.8, 0.8, 1.0); 

    vec3 col_pos = vec3(model_mat * vert_pos); 

    vec3 s_to_f = light_pos - col_pos; 

    float brightness = dot(norm, normalize(s_to_f)); 
    brightness = clamp(brightness, 0, 1); 

    gl_FragColor = out_col; 

    gl_FragColor = vec4(brightness * light_col.rgb * gl_FragColor.rgb, 1.0); 
} 

Как я уже говорил ранее, я предполагаю, что проблема связана с тем, как позиция вершина передается в пиксельный шейдер. Если я изменю значения позиции на что-то статическое, не будет больше мерцания. Я тоже изменил все остальные значения на статику. Это тот же результат - не мерцает, если я не использую данные позиции вершин, переданные из вершинного шейдера.

Итак, если есть кто-то с какой-то GL-мудростью ..;) Любая помощь будет оценена. Боковое примечание: запуск всего этого на Intel HD 4000, если это может предоставить дополнительную информацию.

Заранее благодарен! Ivan

+0

Каковы значения ближней и дальней плоскости? – legends2k

+0

рядом установлено 0,1 и далеко до 1000 – insaneivan

+0

Можете ли вы попробовать увеличить примерно, скажем, до 10 или 50? – legends2k

ответ

3

Имена переменных out в вершинном шейдере и переменные in в шейдере фрагмента должны совпадать. У вас есть это в вершинном шейдере:

out vec4 out_col; 
out vec2 passed_uv; 
out vec4 out_vert; 
out vec4 out_norm; 

и это в пиксельный шейдер:

in vec4 in_col; 
in vec2 passed_uv; 
in vec4 vert_pos; 
in vec4 in_norm; 

Эти переменные связаны по имени, а не по порядку. За исключением passed_uv, имена здесь не совпадают. Например, вы могли бы использовать эти объявления в вершинном шейдере:

out vec4 passed_col; 
out vec2 passed_uv; 
out vec4 passed_vert; 
out vec4 passed_norm; 

и это в пиксельный шейдер:

in vec4 passed_col; 
in vec2 passed_uv; 
in vec4 passed_vert; 
in vec4 passed_norm; 

Основываясь на том, как я прочитал спецификацию, ваш шейдер программа должна реально не в состоянии ссылка. По крайней мере, в спецификации GLSL 4.50 в таблице на стр. 43 в этой ситуации отображается «Ошибка времени связи». Однако правила были несколько неоднозначными в более ранних спецификациях.

+0

Спасибо за ваш ответ. Действительно аккуратный совет, но на самом деле не решает мерцание. Я использовал ваши имена переменных. Угадайте, что программа связана с моей спецификацией GL3.2. – insaneivan

+0

Вы, сэр, правы. Я был слишком слеп, чтобы снова перепутал переменные. Большое вам спасибо, что, наконец, сработало! – insaneivan

 Смежные вопросы

  • Нет связанных вопросов^_^