Почему мой шейдер создает яркую точку в исходном источнике?

#c #glsl #sfml

Вопрос:

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

Примечание: Причина, по которой код шейдера выглядит странно, заключается в том, что я считаю, что SFML использует более старую и нестандартную версию GLSL.

Шейдер

 uniform vec2 size;
uniform vec2 origin;

void main() {


    float light_strength = 100.0;
    vec2 frag_location =  gl_FragCoord.xy;

    // Flip over the x axis
    frag_location.y = size.y - frag_location.y;

    // Get the distance from the fragment to the source
    float abs_distance = length(origin - frag_location);

    // Calculate the attenuation based on the distance
    // 1.0 / (1.0   1.0*d   1.0*d^2)
    float attenuation = 1.0 / (1.0   (1.0 * abs_distance)   (1.0 * pow(abs_distance, 2.0))) * light_strength;

    // Create a base color
    vec4 light_color = vec4(1.0, 1.0, 1.0, 1.0);

    // Change the color based on the attenuation
    vec4 color = vec4(attenuation, attenuation, attenuation, 1.0) * light_color; 

    gl_FragColor = color;
}
 

Пример реализации

 //libs: -lsfml-graphics -lsfml-system -lsfml-window

#include <SFML/Graphics.hpp>

#define width 600
#define height 600

int main() {

    sf::RenderWindow window;
    sf::Shader shader;
    sf::RenderStates states;

    window.create(sf::VideoMode(width, height), "");

    // Create a shape to fill the screen
    sf::RectangleShape fill_color(sf::Vector2f(0, 0));
    fill_color.setSize(sf::Vector2f(width, height));
    fill_color.setFillColor(sf::Color::White);

    // Shader gets compiled by whatever SFML uses for it
    shader.loadFromFile("shaders/lighting.frag", sf::Shader::Fragment);

    // Set some origin point
    shader.setUniform("size", sf::Vector2f(width, height));
    shader.setUniform("origin", sf::Vector2f(300, 300));
    states = amp;shader;


    while (window.isOpen()) {

        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) {
            window.close();
        }

        // Draws
        window.clear();
        window.draw(fill_color, states);
        window.display();
    }
}
 

Результат кода реализации

Комментарии:

1. abs_distance=0 -> attenuation=100*1/(1 0 0)=100 ; abs_distance=1 -> attenuation=100*1/(1 1 1)=33 ; abs_distance=5 -> attenuation=100*1/(1 5 25)=3.23 . Все будет закреплено до 1.0.

2. Да, я понимаю, что ожидаемый результат находится в диапазоне от 0 до 1. Но то, что я вижу, говорит о том, что где-то, будь то в коде шейдера или на самом рисунке, значение цвета пикселя равно 255. Я ценю обратную связь, но все, что вы сделали, это дали мне результат моего собственного уравнения.

3. Все значения >=1.0 в выводе цвета GLSL соответствуют 255 в цветовом буфере без знака (> GL_RGBA8 , который является «нормализованным» форматом). Так что я действительно неправильно понял текущий вопрос…