2013-09-19 2 views
3

Я пытаюсь реализовать очень простой диффузный шейдер в GLSL/openGL. Вот что я получил: Vertex Shader:OpenGL, diffuse shader

#version 130 

in vec3 vertPos3D; 
in vec3 vertNormal3D; 

uniform mat3 transpMatrix; 
uniform mat4 projectionMatrix; 
uniform mat4 viewMatrix; 

uniform vec3 lightPosition; 

varying vec3 vertNormal; 
varying vec3 lightVector; 

void main() 
{ 
    vec4 res_pos = projectionMatrix * viewMatrix * vec4(vertPos3D.xyz, 1.0); 
    gl_Position = res_pos; 
    mat4 pm = projectionMatrix * viewMatrix; 
    vertNormal = (viewMatrix * vec4(vertNormal3D, 0)).xyz; 
    lightVector = (viewMatrix * vec4(lightPosition, 1.0)).xyz - (viewMatrix * vec4(vertPos3D.xyz, 1.0)).xyz; 
} 

пиксельный шейдер:

#version 130 
out vec4 color; 

varying vec3 lightVector; 
varying vec3 vertNormal; 
void main() 
{ 
    float dot_product = max(normalize(dot(lightVector, vertNormal)), 0.0); 
    color = dot_product * vec4(1.0, 1.0, 1.0, 1.0); 
} 

Как только я умножать окончательный цвет с dot_product, ничего не отображается. Я удаляю dot_product, все работает (за исключением диффузной молнии ofc.). Боюсь, что это что-то очевидное, я пропал без вести.

+0

Что-нибудь в шейдере компиляции/журналы ссылок? – genpfault

ответ

3

Проблема:

normalize(dot(lightVector, vertNormal)) 

dot в GLSL 1.3 возвращает поплавок.
normalize принимает вектор, а не поплавок.
documentation for dot
documentation for normalize

решение, по крайней мере, к этой проблеме:

В пиксельный шейдер, замените

float dot_product = max(normalize(dot(lightVector, vertNormal)), 0.0); 

с

float dot_product = clamp(dot(lightVector, vertNormal), 0, 1); 

Похоже, что вы ар e используя max и нормализовать, чтобы избежать отрицательных чисел, возвращаемых с dot. Это именно то, для чего стоит clamp. Вот documentation for clamp

+0

Спасибо за ваш совет, я изменил эту строку кода, но в целом ничего не изменилось. :( – user1760770

+0

О, подождите, пока вы используете GLSL 1.3, поэтому попробуйте переключить 'in' с' атрибутом' в вашем вершинном шейдере и в шейдере фрагмента, удалив 'out vec4 color;' и заменив 'color' на' gl_FragColor' –

+0

Позвольте мне знать если код, который я написал выше, работает ... –

2

Использование

float dot_product = max(dot(normalize(lightVector), normalize(normalVector)), 0.0);

Дилан Холмс ответ немного неправильно:

Еще lightVector должен быть нормирован!

И зажим не нужен. max был верным. Точечный продукт никогда не возвращает значение выше 1,0, если входные векторы нормализованы.

+1

Чтобы быть точным: «Точечный продукт никогда не возвращает значение выше 1,0» только true, если векторы были нормализованы, а vertNormal все еще необходимо нормализовать, потому что это интерполированное значение, а не приложение, представленное как нормальное. – keltar

+0

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

+0

@djmj normalizing провалил мой разум, и спасибо за то, что указали на то, что около clamp/max. –