У меня есть простое приложение, которое рисует сферу с одним направленным светом. Я создаю сферу, начиная с октаэдра и разбивая каждый треугольник на 4 меньших треугольника.Почему мои зеркальные блики так сильно проявляются на краях многоугольника?
С просто рассеянным освещением шар выглядит очень гладким. Однако, когда я добавляю зеркальные блики, края треугольников проявляются довольно сильно. Вот некоторые примеры:
Диффузный только:
Диффузный и Отраженный:
Я считаю, что нормалей подвергаются интерполяции правильно. Глядя только нормали, я получаю это:
В самом деле, если я переключаюсь на затенение, где нормали за полигон вместо за вершины, я получаю это:
В моем вершинном шейдере, я умножая нормали модели матрицы транспонированного обратный видовой:
#version 330 core
layout (location = 0) in vec4 vPosition;
layout (location = 1) in vec3 vNormal;
layout (location = 2) in vec2 vTexCoord;
out vec3 fNormal;
out vec2 fTexCoord;
uniform mat4 transInvModelView;
uniform mat4 ModelViewMatrix;
uniform mat4 ProjectionMatrix;
void main()
{
fNormal = vec3(transInvModelView * vec4(vNormal, 0.0));
fTexCoord = vTexCoord;
gl_Position = ProjectionMatrix * ModelViewMatrix * vPosition;
}
и в пиксельный шейдер, я вычисляя блики следующим образом:
#version 330 core
in vec3 fNormal;
in vec2 fTexCoord;
out vec4 color;
uniform sampler2D tex;
uniform vec4 lightColor; // RGB, assumes multiplied by light intensity
uniform vec3 lightDirection; // normalized, assumes directional light, lambertian lighting
uniform float specularIntensity;
uniform float specularShininess;
uniform vec3 halfVector; // Halfway between eye and light
uniform vec4 objectColor;
void main()
{
vec4 texColor = objectColor;
float specular = max(dot(halfVector, fNormal), 0.0);
float diffuse = max(dot(lightDirection, fNormal), 0.0);
if (diffuse == 0.0)
{
specular = 0.0;
}
else
{
specular = pow(specular, specularShininess) * specularIntensity;
}
color = texColor * diffuse * lightColor + min(specular * lightColor, vec4(1.0));
}
Я был немного смущен о том, как рассчитать halfVector
. Я делаю это на процессоре и передаю его как униформу. Он рассчитывается следующим образом:
vec3 lightDirection(1.0, 1.0, 1.0);
lightDirection = normalize(lightDirection);
vec3 eyeDirection(0.0, 0.0, 1.0);
eyeDirection = normalize(eyeDirection);
vec3 halfVector = lightDirection + eyeDirection;
halfVector = normalize(halfVector);
glUniform3fv(halfVectorLoc, 1, &halfVector [ 0 ]);
Это правильная формулировка для halfVector
? Или это нужно делать в шейдерах?
Спасибо! Это объясняет некоторые вещи, о которых мне было интересно. – user1118321
Для записи 'fNormal = normalize (fNormal);' фактически не будет работать, потому что 'fNormal' является входной переменной. Мне пришлось создать новую переменную, например 'vec3 normal = normalize (fNormal);'. – user1118321