2016-02-23 8 views
1

Простой вопрос, я только что получил свой первый зеркальный шейдер, и, изучая математику, я не могу помочь подумать, что угол между каждым краем должен вызывать «зеркальность», чтобы вспять/стать зубчатым. Но его полностью жидкость/сферическая.Почему основная зеркальная затеняющая жидкость, а не зубчатая?

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

Я не могу видеть, как gpu знает угол фрагмента, основанный только на одной вершине.

enter image description here

редактировать: верт шейдер

#version 400 core 

layout (location = 0) in vec3 vertex_position; 
layout (location = 2) in vec2 tex_cord; 
layout (location = 3) in vec3 vertex_normal; 

uniform mat4 transform; //identity matrix 
uniform mat3 lmodelmat; //inverse rotation 

out vec2 UV; 
out vec3 normal; 

void main() 
{ 
    UV=tex_cord; 
    normal=normalize(vertex_normal*lmodelmat); //normalize to keep brightness 

    gl_Position=transform*vec4(vertex_position,1.0); 
} 

и осколочной

#version 400 core 

in vec2 UV; 
in vec3 normal; 

uniform sampler2D mysampler; 
uniform vec3 lightpos; //lights direction 

out vec4 frag_colour; 

in vec3 vert2cam; //specular test 

void main() 
{ 
    //skip invis frags 
    vec4 alphatest=texture(mysampler,UV); 
    if(alphatest.a<0.00001)discard; 

    //diffuse'ing fragment 
    float diffuse=max(0.1,dot(normal,lightpos)); 

    //specular'izing fragment 
    vec3 lpnorm=normalize(lightpos); //vector from fragment to light 
    vec3 reflection=normalize(reflect(-lpnorm,normal)); //reflection vector 
    float specularity=max(0,dot(lpnorm,reflection)); 
    specularity=pow(specularity,50); 

    frag_colour=alphatest*diffuse+specularity; 
} 

// Редактировать

Я нашел ответ на это кстати (год спустя): Вертикальные нормали (vn) являются комбинированным значением для каждого из f асы/треугольники, соединенные с ним. То есть, одна вершина, соединенная с несколькими гранями, будет иметь граничные нормали, объединенные при нормализации. Это значение vn, рассчитывается как среднее из соседних граничных нормалей. Когда значение рассчитано для указания яркости, графический процессор будет обеспечивать «затенение», которое является нормализованным кросс-продуктом каждой из соседних сторон.

Я понял это, когда перерасчет лица нормалей для проекта им делать:

псевдокода пересчитывать Vertice нормалей:

for (for each face/triangle, find face-normal and add to adjacent vn's) 
vec3 face_normal=cross(face[1]-face[0],face[2]-face[0]); 
vn[0]+=face_normal; //notice += 
vn[1]+=face_normal; 
vn[2]+=face_normal; 

//then just normalize them to get the weighted average 
for(auto&x:vn)x=normalize(x); 

Это будет, для визуализатора, приравнивает как усредненные кривой, и не зазубренный край (плоское затенение)

+0

Вы используете Gouraud или Phong shading? –

+2

Я бы предположил, что происходит какая-то интерполяция. Но без какого-либо кода трудно сказать, что происходит. –

+0

вы бы назвали это phong shading? его в основном cosA между отражением света и вершиной нормали добавляется к цвету. Я просто не могу видеть, как glsl читает его как четную кривую, когда im вводит только несколько значений – Charlie

ответ

2

Без кода .etc. Трудно точно ответить на ваш вопрос, но предполагая простой векторный шейдер -> фрагмент шейдерного конвейера. Вектор-шейдер будет запущен для каждой вершины. Он будет устанавливать типично заданные параметры с пометкой «изменяться» (например, координаты текстуры).

Каждые 3 вершины будут сгруппированы, чтобы сформировать многоугольник, а фрагментарный шейдер - для определения цвета каждой точки в полигоне. «Измененные» параметры, заданные вершинным шейдером, будут интерполированы на основе расстояния фрагмента от трех ребер многоугольника (см. Barycentric интерполяция).

Следовательно, например:

gl_FragColor = texture2D(myUniformSampler, vec2(myTextureCoord.s,myTextureCoord.t)); 

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

Edit (на основе коды вы добавили):

out vec2 UV; 
out vec3 normal; 
out vec3 color; 

Устанавливается на вершину в вашем вершинном шейдере. Каждые три вершины определяют многоугольник. Затем фрагментарный шейдер запускается для каждой точки (например, пикселя) внутри многоугольника для определения цвета .etc. каждой точки.

Значения этих параметров:

in vec3 color; /// <<-- You don't seem to be actually using this 
in vec2 UV; 
in vec3 normal; 

в пиксельный шейдер интерполируют на основе расстояния от точки на полигоне быть «нарисованной» из каждой вершины (см: барицентрических интерполяции). Следовательно, нормаль изменяется между вершинами, определенными вашим вершинным шейдером.

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

+0

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

+0

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

+0

, но как gpu знает, какое значение это? для всего, что он заботится, я просто кладу случайные vec3s в стек. значения, которые даже модифицированы, возможно, он читает команду как освещенный круг? и рисует это так, а не зубчатым по краям? возможно, его лишний вопрос – Charlie

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

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