Как улучшить внешний вид 2d света?

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

То, что я имею в виду под хорошим, похоже на эту сцену:

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

Похоже, что свет имеет некоторую площадь и где-то заканчивается.

Что я пытался сделать, так это рассчитать расстояние от текущего пикселя до положения источника света и использовать это расстояние в качестве источника света, но это выглядит не очень хорошо.

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

Моим последним шансом было попробовать методы 3D-молнии. Я определил нормаль для сцены, которая равна vec3(0.0f, 0.0f, 1.0f), и рассчитал точечный источник света.

struct PointLight
{
    vec3 position;

    float constant;
    float linear;
    float quadratic;  

    vec3 ambient;
    vec3 diffuse;
};

vec3 CalcPointLight(PointLight light, vec3 fragPos)
{
    vec3 normal = normalize(vec3(0.0f, 0.0f, 1.0f));

    vec3 lightDir = normalize(light.position - fragPos);
    float diff = max(dot(normal, lightDir), 0.0);

    float distance = length(light.position - fragPos);
    float attenuation = 1.0 / (light.constant + light.linear * distance + 
                 light.quadratic * (distance * distance));    

    vec3 ambient = light.ambient;
    vec3 diffuse = light.diffuse * diff;

    ambient *= attenuation;
    diffuse *= attenuation;

    return ambient + diffuse;
} 

делаю свет так:

    PointLight light;
    light.position = vec3(0.0f, 0.0f, 0.005f);
    light.constant = 0.5f;
    light.linear = 0.09f;
    light.quadratic = 0.032f;
    light.ambient = vec3(0.1f);
    light.diffuse = vec3(0.8f);

    vec3 result = CalcPointLight(light, vec3(v_position, 0.0f));

    f_color = vec4(result, 1.0) * texture(u_texture, v_uv);

у него есть точка посреди света, который Я НЕНАВИЖУ! (точка исчезает, когда z положение источника света равно 0 [тоже не всегда, иногда свет просто не работает], хотя это выглядит странно), моя сцена становится все темнее и темнее, когда на первом скриншоте это «максимальное» значение темноты и в целом мой свет выглядит совсем не так круто, как на скрине выше.

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

весь шейдер

#version 460 core

out vec2 v_uv;
out vec2 v_position;

vec4 position[4] = {
    vec4(-1.0f, 1.0f, 0.0f, 1.0f),
    vec4(-1.0f, -1.0f, 0.0f, 0.0f),
    vec4(1.0f, -1.0f, 1.0f, 0.0f),
    vec4(1.0f, 1.0f, 1.0f, 1.0f)
};

void main()
{
    v_uv = position[gl_VertexID].zw;
    v_position = position[gl_VertexID].xy;
    gl_Position = vec4(position[gl_VertexID].xy, 0.0f, 1.0f);
}
#version 460 core

layout (location = 0) out vec4 f_color;

in vec2 v_uv;
in vec2 v_position;

uniform sampler2D u_texture;

struct PointLight
{
    vec3 position;

    float constant;
    float linear;
    float quadratic;  

    vec3 ambient;
    vec3 diffuse;
};

PointLight pointLights[4];

vec3 CalcPointLight(PointLight light, vec3 fragPos)
{
    vec3 normal = normalize(vec3(0.0f, 0.0f, 1.0f));

    vec3 lightDir = normalize(light.position - fragPos);
    float diff = max(dot(normal, lightDir), 0.0);

    float distance = length(light.position - fragPos);
    float attenuation = 1.0 / (light.constant + light.linear * distance + 
                 light.quadratic * (distance * distance));    

    vec3 ambient = light.ambient;
    vec3 diffuse = light.diffuse * diff;

    ambient *= attenuation;
    diffuse *= attenuation;

    return ambient + diffuse;
} 

void main()
{        
    PointLight light;
    light.position = vec3(0.0f, 0.0f, 0.005f);
    light.constant = 1.0f;
    light.linear = 0.09f;
    light.quadratic = 0.032f;
    light.ambient = vec3(0.1f);
    light.diffuse = vec3(0.8f);

    vec3 result = CalcPointLight(light, vec3(v_position, 0.0f));

    light.position = vec3(-0.5f, 0.7f, 0.005f);
    light.constant = 0.5f;
    light.linear = 0.09f;
    light.quadratic = 0.032f;
    light.ambient = vec3(0.1f);
    light.diffuse = vec3(0.8f);

   // result += CalcPointLight(light, vec3(v_position, 0.0f));

    light.position = vec3(0.5f, 0.5f, 0.00f);
    light.constant = 1.0f;
    light.linear = 0.09f;
    light.quadratic = 0.032f;
    light.ambient = vec3(0.1f);
    light.diffuse = vec3(0.8f);

   // result += CalcPointLight(light, vec3(v_position, 0.0f));

    f_color = vec4(result, 1.0) * texture(u_texture, v_uv);
}

Как добиться эффекта, показанного на первом фото?


person BrodaJarek3    schedule 24.12.2019    source источник
comment
Можете ли вы объяснить, что вы имеете в виду под это совсем не выглядит хорошо? Что с этим не так?   -  person Rabbid76    schedule 25.12.2019
comment
Я объяснил. Просто посмотрите на первое фото и мои фото. Это первый пункт. Вторая точка — ТОЧКА!, третья точка, мой свет становится все темнее и темнее, на первом фото какой-то максимальный диапазон. На первый взгляд свет первой сцены выглядит намного лучше.   -  person BrodaJarek3    schedule 25.12.2019


Ответы (1)


Вы можете сделать smoothstep, что-то вроде:

gl_FragColor = smoothstep( yourFinalColour, vec3( 0 ), length( yourLight, uv );
person Felipe Gutierrez    schedule 24.12.2019