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);
}