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

Единственный переменный фактор - нормали вершин, которые, несомненно, вызывают резкое изменение цвета. Что можно сделать, чтобы осветить комнату более реалистично?

enter image description here

Вершинный шейдер

#version 330

precision highp float;

uniform mat4 projection_matrix;
uniform mat4 model_matrix;
uniform mat4 view_matrix;

in vec3 vert_position;
in vec2 vert_texcoord;
in vec3 vert_normal;

out vec3 frag_normal;
out vec2 frag_texcoord;

uniform vec3 LightPosition;

out vec3 toLightVector;

void main(void)
{
    vec4 world_position = model_matrix * vec4(vert_position, 1);
    frag_texcoord = vert_texcoord;

    frag_normal = (model_matrix * vec4(vert_normal, 0)).xyz;
    toLightVector = LightPosition - world_position.xyz;

    gl_Position = projection_matrix * view_matrix * world_position;
}

Фрагментный шейдер

#version 330

precision highp float;

in vec3 frag_normal;
in vec2 frag_texcoord;
in vec3 toLightVector;

uniform sampler2D MyTexture0;
uniform vec3 LightColour;
uniform vec3 LightAttenuation;

out vec4 finalColor;

void main(void)
{
        float distance = length(toLightVector);
        float attFactor = LightAttenuation.x + (LightAttenuation.y * distance) + (LightAttenuation.z * distance * distance);

        vec3 unitNormal = normalize(frag_normal);
        vec3 unitLightVector = normalize(toLightVector);

        float nDot1 = dot(unitNormal, unitLightVector);
        float brightness = max(nDot1, 0);

        vec3 diffuse = (brightness * LightColour) / attFactor;

        finalColor = vec4(diffuse, 1.0) * texture(MyTexture0, frag_texcoord);
}
0
livin_amuk 15 Апр 2016 в 18:14

3 ответа

Лучший ответ

Вам не понравится этот Николь Болас, но упрощение расчетов до зависимости исключительно от расстояния при условии, что именно тот эффект, который я получил.

Недооценка дизайна и эстетики разрушит любое произведение искусства, но, говоря, что я не пишу здесь Doom 4, я один человек нападает на ренту, пишущий мошенника.

enter image description here

enter image description here

Фрагментный шейдер

#version 330

precision highp float;

in vec2 frag_texcoord;
in vec3 toLightVector;

uniform sampler2D MyTexture0;
uniform vec3 LightColour;
uniform vec3 LightAttenuation;

out vec4 finalColor;

void main(void)
{
        float distance = length(toLightVector);
        float attFactor = LightAttenuation.x + (LightAttenuation.y * distance) + (LightAttenuation.z * distance * distance);
        vec3 diffuse = (LightColour) / attFactor;

        finalColor = vec4(diffuse, 1.0) * texture(MyTexture0, frag_texcoord);
}
1
livin_amuk 15 Апр 2016 в 23:47

Ваша проблема - это ваши ожидания от вашей модели освещения.

Ваша модель освещения ведет себя именно так, как и следовало ожидать. Но это всего лишь модель реальности, приблизительная.

Реальное освещение намного сложнее, чем простое скалярное произведение и затухание. Это очень сложное взаимодействие между множеством маленьких источников света и тому подобным. Это объясняет, почему вы (обычно) не видите таких разрывов в освещении в реальной жизни.

Правильный способ решить эту проблему - не менять затухание или нормали. Это для исследования более точных моделей освещения.

0
Nicol Bolas 15 Апр 2016 в 16:09

Просто положите больше веса на расстояние и меньше на нормали. Сделайте LightAttenuation более похожим на (0,0,1).

-1
Sorin 15 Апр 2016 в 15:54