Почему основная зеркальная жидкость затенения, а не зубчатая?

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

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

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

введите описание изображения здесь

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

#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) — это объединенное значение для каждой из связанных с ним граней / треугольников. То есть 1 норма, соединенная с несколькими гранями, будет иметь нормали лица, объединенные при нормализации. Это значение vn рассчитывается как среднее от смежных нормалей лица. Когда значение вычисляется для указания яркости, графический процессор будет обеспечивать «затенение», которое является нормализованным перекрестным произведением каждой из соседних сторон.

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

псевдокод для пересчета нормалей вершин:

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);

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

1

Решение

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

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

Отсюда например:

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

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

Изменить (на основе кода, который вы добавили):

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

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

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

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

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

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

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]