mirror of
https://github.com/tanema/light_world.lua.git
synced 2024-12-24 20:24:19 +00:00
added stencils
This commit is contained in:
parent
f934d621f5
commit
98ee7b3f91
20
lib/init.lua
20
lib/init.lua
@ -78,6 +78,10 @@ function light_world:refreshScreenSize(w, h)
|
|||||||
self.refractionMap = love.graphics.newCanvas(w, h)
|
self.refractionMap = love.graphics.newCanvas(w, h)
|
||||||
self.reflectionMap = love.graphics.newCanvas(w, h)
|
self.reflectionMap = love.graphics.newCanvas(w, h)
|
||||||
|
|
||||||
|
for i = 1, #self.lights do
|
||||||
|
self.lights[i]:refresh()
|
||||||
|
end
|
||||||
|
|
||||||
self.post_shader:refreshScreenSize(w, h)
|
self.post_shader:refreshScreenSize(w, h)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -149,26 +153,18 @@ function light_world:drawShadows(l,t,w,h,s)
|
|||||||
for i = 1, #self.lights do
|
for i = 1, #self.lights do
|
||||||
local light = self.lights[i]
|
local light = self.lights[i]
|
||||||
if light:isVisible() then
|
if light:isVisible() then
|
||||||
|
light:updateShadowMap(l, t, s, self.bodies)
|
||||||
self.shineShader:send('lightColor', {light.red / 255.0, light.green / 255.0, light.blue / 255.0})
|
self.shineShader:send('lightColor', {light.red / 255.0, light.green / 255.0, light.blue / 255.0})
|
||||||
self.shineShader:send("lightPosition", {(light.x + l/s) * s, (h/s - (light.y + t/s)) * s, (light.z * 10) / 255.0})
|
self.shineShader:send("lightPosition", {(light.x + l/s) * s, (h/s - (light.y + t/s)) * s, (light.z * 10) / 255.0})
|
||||||
self.shineShader:send('lightRange', light.range * s)
|
self.shineShader:send('lightRange', light.range * s)
|
||||||
self.shineShader:send("lightSmooth", light.smooth)
|
self.shineShader:send("lightSmooth", light.smooth)
|
||||||
self.shineShader:send("lightGlow", {1.0 - light.glowSize, light.glowStrength})
|
self.shineShader:send("lightGlow", {1.0 - light.glowSize, light.glowStrength})
|
||||||
self.shineShader:send('AmbientColor',{self.ambient[1] / 255, self.ambient[2] / 255, self.ambient[3] / 255, 0.2})
|
self.shineShader:send('AmbientColor',{self.ambient[1] / 255, self.ambient[2] / 255, self.ambient[3] / 255, 0.2})
|
||||||
util.process(self.shadowMap, {
|
util.drawCanvasToCanvas(light.shadowMap, self.shadowMap, {
|
||||||
blendmode = 'additive',
|
blendmode = 'additive',
|
||||||
shader = self.shineShader,
|
shader = self.shineShader,
|
||||||
istencil = function()
|
stencil = function()
|
||||||
love.graphics.translate(l, t)
|
love.graphics.circle("fill", light.x, light.y, light.range)
|
||||||
love.graphics.scale(s)
|
|
||||||
for k = 1, #self.bodies do
|
|
||||||
if self.bodies[k]:isInLightRange(light) and self.bodies[k]:isVisible() then
|
|
||||||
self.bodies[k]:drawShadow(light)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local angle = math.pi - light.angle / 2.0
|
|
||||||
love.graphics.setColor(0, 0, 0)
|
|
||||||
love.graphics.arc("fill", light.x, light.y, light.range, light.direction - angle, light.direction + angle)
|
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
local _PACKAGE = (...):match("^(.+)[%./][^%./]+") or ""
|
local _PACKAGE = (...):match("^(.+)[%./][^%./]+") or ""
|
||||||
local class = require(_PACKAGE.."/class")
|
local class = require(_PACKAGE.."/class")
|
||||||
|
local util = require(_PACKAGE.."/util")
|
||||||
|
|
||||||
local light = class()
|
local light = class()
|
||||||
|
|
||||||
@ -18,6 +19,11 @@ function light:init(x, y, r, g, b, range)
|
|||||||
self.glowStrength = 0.0
|
self.glowStrength = 0.0
|
||||||
self.visible = true
|
self.visible = true
|
||||||
self.is_on_screen = true
|
self.is_on_screen = true
|
||||||
|
self:refresh(love.window.getWidth(), love.window.getHeight())
|
||||||
|
end
|
||||||
|
|
||||||
|
function light:refresh(w, h)
|
||||||
|
self.shadowMap = love.graphics.newCanvas(w, h)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- set position
|
-- set position
|
||||||
@ -117,4 +123,18 @@ function light:isVisible()
|
|||||||
return self.visible and self.is_on_screen
|
return self.visible and self.is_on_screen
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function light:updateShadowMap(l, t, s, bodies)
|
||||||
|
self.shadowMap:clear()
|
||||||
|
util.drawto(self.shadowMap, l, t, s, function()
|
||||||
|
for k = 1, #bodies do
|
||||||
|
if bodies[k]:isInLightRange(self) and bodies[k]:isVisible() then
|
||||||
|
bodies[k]:drawShadow(self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local angle = math.pi - self.angle / 2.0
|
||||||
|
love.graphics.setColor(0, 0, 0)
|
||||||
|
love.graphics.arc("fill", self.x, self.y, self.range, self.direction - angle, self.direction + angle)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
return light
|
return light
|
||||||
|
@ -9,13 +9,18 @@ extern vec2 lightGlow = vec2(0.5, 0.5); //how brightly the light bulb part
|
|||||||
extern vec4 AmbientColor; //ambient RGBA -- alpha is intensity
|
extern vec4 AmbientColor; //ambient RGBA -- alpha is intensity
|
||||||
|
|
||||||
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {
|
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {
|
||||||
float dist = distance(lightPosition, vec3(pixel_coords, 1.0));
|
vec4 pixelColor = Texel(texture, texture_coords);
|
||||||
//if the pixel is within this lights range
|
if(pixelColor.a > 0){
|
||||||
//calculater attenuation of light based on the distance
|
return pixelColor;
|
||||||
float att = clamp((1.0 - dist / lightRange) / lightSmooth, 0.0, 1.0);
|
} else {
|
||||||
// if not on the normal map draw attenuated shadows
|
float dist = distance(lightPosition, vec3(pixel_coords, 1.0));
|
||||||
vec3 Ambient = AmbientColor.rgb * AmbientColor.a;
|
//if the pixel is within this lights range
|
||||||
vec3 pixel = lightColor * pow(att, lightSmooth) + pow(smoothstep(lightGlow.x, 1.0, att), lightSmooth) * lightGlow.y;
|
//calculater attenuation of light based on the distance
|
||||||
return vec4(Ambient + pixel, 1.0);
|
float att = clamp((1.0 - dist / lightRange) / lightSmooth, 0.0, 1.0);
|
||||||
|
// if not on the normal map draw attenuated shadows
|
||||||
|
vec3 Ambient = AmbientColor.rgb * AmbientColor.a;
|
||||||
|
vec3 pixel = lightColor * pow(att, lightSmooth) + pow(smoothstep(lightGlow.x, 1.0, att), lightSmooth) * lightGlow.y;
|
||||||
|
return vec4(Ambient + pixel, 1.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ function util.drawCanvasToCanvas(canvas, other_canvas, options)
|
|||||||
love.graphics.setShader(options["shader"])
|
love.graphics.setShader(options["shader"])
|
||||||
end
|
end
|
||||||
if options["stencil"] then
|
if options["stencil"] then
|
||||||
love.graphics.setInvertedStencil(options["stencil"])
|
love.graphics.setStencil(options["stencil"])
|
||||||
end
|
end
|
||||||
if options["istencil"] then
|
if options["istencil"] then
|
||||||
love.graphics.setInvertedStencil(options["istencil"])
|
love.graphics.setInvertedStencil(options["istencil"])
|
||||||
@ -33,7 +33,7 @@ function util.drawCanvasToCanvas(canvas, other_canvas, options)
|
|||||||
love.graphics.setShader()
|
love.graphics.setShader()
|
||||||
end
|
end
|
||||||
if options["stencil"] then
|
if options["stencil"] then
|
||||||
love.graphics.setInvertedStencil()
|
love.graphics.setStencil()
|
||||||
end
|
end
|
||||||
if options["istencil"] then
|
if options["istencil"] then
|
||||||
love.graphics.setInvertedStencil()
|
love.graphics.setInvertedStencil()
|
||||||
|
Loading…
Reference in New Issue
Block a user