Help with normal mapping

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Arônimo
Prole
Posts: 5
Joined: Tue Jul 04, 2023 4:18 pm

Help with normal mapping

Post by Arônimo »

I looked through some code and examples posted in the forums about dinamyc lighting and normal mapping, although i could not replicate it myself. The only thing that makes the effect not work with me, is because the nearest the top of the screen the light is, it seems like the code thinks it is behind, and near the bottom it seems like its going further from it, towards the camera screen or something:
Image
Image


this is the code (lua and glsl):

Code: Select all

local image
local normal_map

local shader
local shader_code
function love.load()
    image = love.graphics.newImage("brick.jpg")
    normal_map = love.graphics.newImage("brick_normal.jpg")

    local f = assert(io.open('shader.glsl', "r"))
    shader_code = f:read("*all")
    f:close()

    shader = love.graphics.newShader(shader_code)
end

function love.draw()
    love.graphics.setShader(shader)

    shader:send("screen", {
        love.graphics.getWidth(),
        love.graphics.getHeight()
    })

    shader:send("num_lights", 1)

    shader:send("lights[0].position", {
        love.mouse.getPosition()
    })

    shader:send("lights[0].diffuse", {
        10, 10, 10
    })

    shader:send("lights[0].power", 26)

    shader:send("normal_map", normal_map)

    love.graphics.draw(image, 0, 0)
    love.graphics.setShader()
end

function love.keypressed(k)
    if k == 'r' then
        love.event.quit('restart')
    end
end

Code: Select all

#define NUM_LIGHTS 32

struct Light
{
    vec2 position;
    vec3 diffuse;
    float power;
};

extern Light lights[NUM_LIGHTS];
extern int num_lights;
extern vec2 screen;
extern Image normal_map;

const float constant = 1.0;
const float linear = 0.09;
const float quadratic = 0.032;

vec4 effect(vec4 color, Image image, vec2 uv, vec2 screen_coords)
{
    vec4 pixel =  Texel(image, uv);
    vec3 normal = normalize(Texel(normal_map, uv).xyz * 2.0 - 1.0);

    vec2 norm_screen = screen_coords / screen;
    vec3 diffuse = vec3(0);

    for(int i = 0; i < num_lights; i++)
    {
        Light light = lights[i];
        vec2 norm_pos = light.position / screen;
        float dist = length(norm_pos - norm_screen) * light.power;
        float attenuation = 1.0 /
            (constant + linear * dist + quadratic * (dist * dist));
        
        float diff = max(dot(norm_pos, normal.zx), 0.0);

        diffuse += diff * (light.diffuse * attenuation);
    }

    diffuse = clamp(diffuse, 0.0, 1.0);

    return pixel * vec4(diffuse, 1.0);
}
Any help is appreciated!
Arônimo
Prole
Posts: 5
Joined: Tue Jul 04, 2023 4:18 pm

Re: Help with normal mapping

Post by Arônimo »

A z axis was missing for the normal calculations, i did just that:

Code: Select all

    vec4 pixel =  Texel(image, uv);
    vec3 normal = normalize(vec3(Texel(normal_map, uv).xy * 2.0 - 1.0, 1));

    vec2 norm_screen = screen_coords / screen;
    vec3 diffuse = vec3(0);

    for(int i = 0; i < num_lights; i++)
    {
        Light light = lights[i];
        vec2 norm_pos = light.position / screen;
        float dist = length(norm_pos - norm_screen) * light.power;
        float attenuation = 1.0 /
            (constant + linear * dist + quadratic * (dist * dist));
        
        float diff = max(dot(normalize(vec3(norm_pos, 1)), normal.xyz), 0.0);

        diffuse += diff * (light.diffuse * attenuation);
    }
But still, doesnt look quite good:
Image
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 8 guests