2015-03-24 4 views
0

Итак, я беру курс графики, и я программирую шейдеры. В ходе курса нам предоставляется доступ к сервису webgl, а также к набору кода на C++ для компиляции, чтобы получить среду с несколькими моделями. Однако, неважно, компиляция этого кода на Windows или Linux не имеет значения, я не получаю результат, который я должен.Это работа перепутанных нормалей или что это может быть?

Sphere with a light orbiting it

Так это результат я получаю, используя один и тот же код GLSL, как с этим результатом:

WebGL version, slightly moved

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

Я предполагаю, что это связано с нормалями, но я не совсем уверен, как только начал с графики, и это было два года назад, я правильно занимался линейной алгеброй. И поскольку я не знаю источник C++ (я анализирую его прямо сейчас, чтобы понять поток), я не знаю, где отлаживать.

Vertex Shader:

.... 
attribute vec3 VertexPosition 
attribute vec2 VertexST 
attribute vec3 VertexNormal 
.... 
void main(void) { 
    Position = ProjectionMatrix * ViewMatrix * WorldMatrix * vec4 (VertexPosition, 1); 
    Normal = normalize ((ViewMatrix * WorldMatrix * vec4 (VertexNormal, 0)).xyz); 
    EyeSpaceLightPosition = ViewMatrix * LightPosition; 
    EyeSpaceVertexPosition = ViewMatrix * WorldMatrix * vec4 (VertexPosition, 1); 
    EyeSpaceObjectPosition = ViewMatrix * WorldMatrix * vec4 (0, 0, 0, 1); 
    STCoords = VertexST; 
    gl_Position = Position; 

}

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

void main(void) { 
    fragColor = vec4 (Normal, 1.0); 
    gl_FragColor = fragColor; 
} 

Этот код является то, что на самом деле работает. Есть декларации и прочее раньше, но да. В фактических файлах больше кода, но они комментируются, поэтому эти строки не запускаются.

+0

Обычно, когда вы визуализируете нормали, вы конвертируете их в диапазон от 0 до 1, иначе все компоненты, которые меньше нуля, будут равны нулю. Вы можете сделать Normal = 0.5 * (Normal + vec3 (1)), чтобы преобразовать его из -1 в 1 в диапазон от 0 до 1, чтобы вы могли нормально видеть нормали. – user3256930

+0

Проблема оказалась связанной с порядком деклараций Позиций, Нормалей и ST в вершинном шейдере, поэтому для STALS и Norma Verca потребовались ST. – Simon

ответ

-1

Итак, проблема решена, и причина в том, что в вершинном шейдере есть три объявления, которые указывают шейдеру, как в массиве упорядочивается информация. Он сказал:

attribute vec3 VertexPosition; 
attribute vec2 VertexST; 
attribute vec3 VertexNormal; 

Это неправильно, так как информация, которая дается на GPU от CPU фактически упорядочено Position, Normal, ST.

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

Это сделал модель не оказывать должным образом, как и в первой картине в вопросе, но после включения этих линий:

attribute vec3 VertexPosition; 
attribute vec3 VertexNormal; // Switched these two 
attribute vec2 VertexST;  // 

Теперь шейдер интерпретирует информацию, данную ему правильно и результат то, что, как ожидается, ,

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

+0

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

+0

@RetoKoradi В случае с кодом C++, который мне был дан, и поскольку я не писал его, я не хочу проходить. Но да, я понимаю, что вы говорите, но случай, который у меня был в моей ошибке, заключался в том, что они были определены в другом порядке, чем то, что интерпретировал фактический шейдер, что было ошибкой оригинального автора. Поэтому я понимаю, что вы говорите. – Simon