Нормальное отображение работает неправильно, странный эффект полусвета - PullRequest
0 голосов
/ 23 февраля 2020

Мы пытаемся реализовать нормальное отображение в нашем 2D Game Engine и получить странный эффект. Если нормаль установлена ​​вручную таким образом, то vec3 Normal = vec3(0.0, 0.0, 1.0) источник света работает правильно, но мы не получаем "глубокого" эффекта, которого мы хотим достичь путем отображения нормалей: enter image description here Но если мы получим нормаль, используя текстуру карты нормалей: vec3 Normal = texture(NormalMap, TexCoord).rgb это не работает вообще. То, что не должно быть освещено, подсвечивается и наоборот (например, промежутки между кирпичами). И кроме того, темная область находится на нижней (или верхней, в зависимости от положения светлой) стороне текстуры. enter image description here Хотя текстура самой карты нормалей выглядит нормально: enter image description here Это наш фрагментный шейдер:

#version 330 core
layout (location = 0) out vec4 FragColor;

in vec2 TexCoord;
in vec2 FragPos;

uniform sampler2D OurTexture;
uniform sampler2D NormalMap;

struct point_light
{
    vec3 Position;
    vec3 Color;
};

uniform point_light Light;

void main()
{
    vec4 Color = texture(OurTexture, TexCoord);
    vec3 Normal = texture(NormalMap, TexCoord).rgb;

    if (Color.a < 0.1)
        discard;

    vec3 LightDir = vec3(Light.Position.xy - FragPos, Light.Position.z);

    float D = length(LightDir);

    vec3 L = normalize(LightDir);
    Normal = normalize(Normal * 2.0 - 1.0);

    vec3 Diffuse = Light.Color * max(dot(Normal, L), 0);
    vec3 Ambient = vec3(0.3, 0.3, 0.3);

    vec3 Falloff = vec3(1, 0, 0);

    float Attenuation = 1.0 /(Falloff.x + Falloff.y*D + Falloff.z*D*D);
    vec3 Intensity = (Ambient + Diffuse) * Attenuation;

    FragColor = Color * vec4(Intensity, 1);
}

И вершина также:

#version 330 core
layout (location = 0) in vec2 aPosition;
layout (location = 1) in vec2 aTexCoord;

uniform mat4 Transform;
uniform mat4 ViewProjection;

out vec2 FragPos;
out vec2 TexCoord;

void main()
{
    gl_Position = ViewProjection * Transform * vec4(aPosition, 0.0, 1.0);
    TexCoord = aTexCoord;
    FragPos = vec2(Transform * vec4(aPosition, 0.0, 1.0));
}

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

1 Ответ

0 голосов
/ 25 февраля 2020

Какой формат текстуры вы используете для карты нормалей? SRGB, SNORM, et c? Это может быть проблемой. Попробуйте UNORM.

Кроме того, поскольку вы не используете касательное пространство, убедитесь, что ось Z плоскости совпадает с осью Z нормали. Кроме того, OGL читает Y в обратном направлении, поэтому вам нужно перевернуть координаты Y нормалей, которые вы прочитали с карты нормалей. В качестве альтернативы вы можете использовать обратную карту нормалей Y (зелёный, указывающий вниз).

...