mirror of
https://github.com/tanema/light_world.lua.git
synced 2024-12-24 20:24:19 +00:00
Add colored/alpha shadow
This commit is contained in:
parent
827394c87b
commit
3a3512083c
Binary file not shown.
Before Width: | Height: | Size: 1012 B After Width: | Height: | Size: 1012 B |
151
light.lua
151
light.lua
@ -3,6 +3,7 @@ LOVE_LIGHT_CIRCLE = nil
|
||||
LOVE_LIGHT_POLY = nil
|
||||
LOVE_LIGHT_IMAGE = nil
|
||||
LOVE_LIGHT_LAST_BUFFER = nil
|
||||
LOVE_LIGHT_SHADOW_GEOMETRY = nil
|
||||
|
||||
LOVE_LIGHT_BLURV = love.graphics.newShader("shader/blurv.glsl")
|
||||
LOVE_LIGHT_BLURH = love.graphics.newShader("shader/blurh.glsl")
|
||||
@ -46,14 +47,14 @@ function love.light.newWorld()
|
||||
o.changed = true
|
||||
end
|
||||
|
||||
if o.changed then
|
||||
love.graphics.setCanvas(o.shadow)
|
||||
o.shadow:clear(unpack(o.ambient))
|
||||
love.graphics.setBlendMode("additive")
|
||||
else
|
||||
--if o.changed then
|
||||
--love.graphics.setCanvas(o.shadow)
|
||||
--o.shadow:clear()
|
||||
--love.graphics.setBlendMode("additive")
|
||||
--else
|
||||
love.graphics.setColor(255, 255, 255)
|
||||
love.graphics.setBlendMode("alpha")
|
||||
end
|
||||
--end
|
||||
|
||||
local lightsOnScreen = 0
|
||||
LOVE_LIGHT_CIRCLE = o.circle
|
||||
@ -68,21 +69,54 @@ function love.light.newWorld()
|
||||
LOVE_LIGHT_CURRENT = o.lights[i]
|
||||
o.shader:send("lightPositionRange", {o.lights[i].x - LOVE_LIGHT_TRANSLATE_X, love.graphics.getHeight() - (o.lights[i].y - LOVE_LIGHT_TRANSLATE_Y), o.lights[i].range})
|
||||
o.shader:send("lightColor", {o.lights[i].red / 255.0, o.lights[i].green / 255.0, o.lights[i].blue / 255.0})
|
||||
o.shader:send("smooth", o.lights[i].smooth)
|
||||
o.shader:send("glow", {1.0 - o.lights[i].glowSize, o.lights[i].glowStrength})
|
||||
o.shader:send("lightSmooth", o.lights[i].smooth)
|
||||
o.shader:send("lightGlow", {1.0 - o.lights[i].glowSize, o.lights[i].glowStrength})
|
||||
|
||||
if o.changed then
|
||||
love.graphics.setCanvas(o.shadow)
|
||||
else
|
||||
--if o.changed then
|
||||
--love.graphics.setCanvas(o.shadow)
|
||||
--else
|
||||
love.graphics.setCanvas(o.lights[i].shadow)
|
||||
love.graphics.clear()
|
||||
end
|
||||
--end
|
||||
|
||||
-- calculate shadows
|
||||
LOVE_LIGHT_SHADOW_GEOMETRY = calculateShadows(LOVE_LIGHT_CURRENT, LOVE_LIGHT_POLY, LOVE_LIGHT_CIRCLE)
|
||||
|
||||
-- draw shadow
|
||||
love.graphics.setInvertedStencil(shadowStencil)
|
||||
love.graphics.setBlendMode("additive")
|
||||
love.graphics.rectangle("fill", LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y, love.graphics.getWidth(), love.graphics.getHeight())
|
||||
|
||||
-- draw color shadows
|
||||
love.graphics.setBlendMode("multiplicative")
|
||||
love.graphics.setShader()
|
||||
for i = 1,#LOVE_LIGHT_SHADOW_GEOMETRY do
|
||||
if LOVE_LIGHT_SHADOW_GEOMETRY[i].alpha < 1.0 then
|
||||
love.graphics.setColor(
|
||||
LOVE_LIGHT_SHADOW_GEOMETRY[i].red * (1.0 - LOVE_LIGHT_SHADOW_GEOMETRY[i].alpha),
|
||||
LOVE_LIGHT_SHADOW_GEOMETRY[i].green * (1.0 - LOVE_LIGHT_SHADOW_GEOMETRY[i].alpha),
|
||||
LOVE_LIGHT_SHADOW_GEOMETRY[i].blue * (1.0 - LOVE_LIGHT_SHADOW_GEOMETRY[i].alpha)
|
||||
)
|
||||
love.graphics.polygon("fill", unpack(LOVE_LIGHT_SHADOW_GEOMETRY[i]))
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, #LOVE_LIGHT_CIRCLE do
|
||||
if LOVE_LIGHT_CIRCLE[i].glassAlpha < 1.0 then
|
||||
love.graphics.setColor(LOVE_LIGHT_CIRCLE[i].red, LOVE_LIGHT_CIRCLE[i].green, LOVE_LIGHT_CIRCLE[i].blue)
|
||||
love.graphics.circle("fill", LOVE_LIGHT_CIRCLE[i].x, LOVE_LIGHT_CIRCLE[i].y, LOVE_LIGHT_CIRCLE[i].radius)
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, #LOVE_LIGHT_POLY do
|
||||
if LOVE_LIGHT_POLY[i].glassAlpha < 1.0 then
|
||||
love.graphics.setColor(LOVE_LIGHT_POLY[i].red, LOVE_LIGHT_POLY[i].green, LOVE_LIGHT_POLY[i].blue)
|
||||
love.graphics.polygon("fill", unpack(LOVE_LIGHT_POLY[i].data))
|
||||
end
|
||||
end
|
||||
|
||||
love.graphics.setShader(o.shader)
|
||||
|
||||
-- draw shine
|
||||
love.graphics.setCanvas(o.lights[i].shine)
|
||||
o.lights[i].shine:clear(255, 255, 255)
|
||||
@ -103,7 +137,7 @@ function love.light.newWorld()
|
||||
|
||||
-- update shadow
|
||||
love.graphics.setShader()
|
||||
if not o.changed then
|
||||
--if not o.changed then
|
||||
love.graphics.setCanvas(o.shadow)
|
||||
love.graphics.setStencil()
|
||||
love.graphics.setColor(unpack(o.ambient))
|
||||
@ -117,7 +151,7 @@ function love.light.newWorld()
|
||||
end
|
||||
end
|
||||
o.isShadowBlur = false
|
||||
end
|
||||
--end
|
||||
|
||||
-- update shine
|
||||
love.graphics.setCanvas(o.shine)
|
||||
@ -481,6 +515,10 @@ function love.light.newRectangle(p, x, y, width, height)
|
||||
o.ox = o.width / 2
|
||||
o.oy = o.height / 2
|
||||
o.shine = true
|
||||
o.red = 255
|
||||
o.green = 255
|
||||
o.blue = 255
|
||||
o.glassAlpha = 1.0
|
||||
o.type = "rectangle"
|
||||
p.changed = true
|
||||
o.data = {
|
||||
@ -546,6 +584,18 @@ function love.light.newRectangle(p, x, y, width, height)
|
||||
o.shine = b
|
||||
p.changed = true
|
||||
end
|
||||
-- set glass color
|
||||
o.setColor = function(red, green, blue)
|
||||
o.red = red
|
||||
o.green = green
|
||||
o.blue = blue
|
||||
p.changed = true
|
||||
end
|
||||
-- set glass alpha
|
||||
o.setAlpha = function(alpha)
|
||||
o.glassAlpha = alpha
|
||||
p.changed = true
|
||||
end
|
||||
-- get x
|
||||
o.getX = function()
|
||||
return o.x
|
||||
@ -583,6 +633,10 @@ function love.light.newCircle(p, x, y, radius)
|
||||
o.y = y or 0
|
||||
o.radius = radius or 200
|
||||
o.shine = true
|
||||
o.red = 255
|
||||
o.green = 255
|
||||
o.blue = 255
|
||||
o.glassAlpha = 1.0
|
||||
o.type = "circle"
|
||||
p.changed = true
|
||||
-- set position
|
||||
@ -624,6 +678,18 @@ function love.light.newCircle(p, x, y, radius)
|
||||
o.shine = b
|
||||
p.changed = true
|
||||
end
|
||||
-- set glass color
|
||||
o.setColor = function(red, green, blue)
|
||||
o.red = red
|
||||
o.green = green
|
||||
o.blue = blue
|
||||
p.changed = true
|
||||
end
|
||||
-- set glass alpha
|
||||
o.setAlpha = function(alpha)
|
||||
o.glassAlpha = alpha
|
||||
p.changed = true
|
||||
end
|
||||
-- get x
|
||||
o.getX = function()
|
||||
return o.x
|
||||
@ -650,6 +716,10 @@ function love.light.newPolygon(p, ...)
|
||||
p.poly[#p.poly + 1] = o
|
||||
o.id = #p.poly
|
||||
o.shine = true
|
||||
o.red = 255
|
||||
o.green = 255
|
||||
o.blue = 255
|
||||
o.glassAlpha = 1.0
|
||||
o.type = "polygon"
|
||||
p.changed = true
|
||||
if ... then
|
||||
@ -672,6 +742,18 @@ function love.light.newPolygon(p, ...)
|
||||
o.shine = b
|
||||
p.changed = true
|
||||
end
|
||||
-- set glass color
|
||||
o.setColor = function(red, green, blue)
|
||||
o.red = red
|
||||
o.green = green
|
||||
o.blue = blue
|
||||
p.changed = true
|
||||
end
|
||||
-- set glass alpha
|
||||
o.setAlpha = function(alpha)
|
||||
o.glassAlpha = alpha
|
||||
p.changed = true
|
||||
end
|
||||
-- get polygon data
|
||||
o.getPoints = function()
|
||||
return unpack(o.data)
|
||||
@ -704,6 +786,10 @@ function love.light.newImage(p, img, x, y, width, height, ox, oy)
|
||||
o.imgWidth = img:getWidth()
|
||||
o.imgHeight = img:getHeight()
|
||||
o.shine = true
|
||||
o.red = 255
|
||||
o.green = 255
|
||||
o.blue = 255
|
||||
o.glassAlpha = 1.0
|
||||
o.type = "image"
|
||||
p.changed = true
|
||||
o.data = {
|
||||
@ -785,6 +871,18 @@ function love.light.newImage(p, img, x, y, width, height, ox, oy)
|
||||
o.shine = b
|
||||
p.changed = true
|
||||
end
|
||||
-- set glass color
|
||||
o.setColor = function(red, green, blue)
|
||||
o.red = red
|
||||
o.green = green
|
||||
o.blue = blue
|
||||
p.changed = true
|
||||
end
|
||||
-- set glass alpha
|
||||
o.setAlpha = function(alpha)
|
||||
o.glassAlpha = alpha
|
||||
p.changed = true
|
||||
end
|
||||
-- set image
|
||||
o.setImage = function(img)
|
||||
o.img = img
|
||||
@ -951,6 +1049,10 @@ function calculateShadows(lightsource, geometry, circle, image)
|
||||
and curShadowGeometry[7]
|
||||
and curShadowGeometry[8]
|
||||
then
|
||||
curShadowGeometry.alpha = v.glassAlpha
|
||||
curShadowGeometry.red = v.red
|
||||
curShadowGeometry.green = v.green
|
||||
curShadowGeometry.blue = v.blue
|
||||
shadowGeometry[#shadowGeometry + 1] = curShadowGeometry
|
||||
end
|
||||
end
|
||||
@ -973,6 +1075,10 @@ function calculateShadows(lightsource, geometry, circle, image)
|
||||
curShadowGeometry[6] = y3 - (lightsource.y - y3) * shadowLength
|
||||
curShadowGeometry[7] = x2 - (lightsource.x - x2) * shadowLength
|
||||
curShadowGeometry[8] = y2 - (lightsource.y - y2) * shadowLength
|
||||
curShadowGeometry.alpha = v.glassAlpha
|
||||
curShadowGeometry.red = v.red
|
||||
curShadowGeometry.green = v.green
|
||||
curShadowGeometry.blue = v.blue
|
||||
shadowGeometry[#shadowGeometry + 1] = curShadowGeometry
|
||||
end
|
||||
|
||||
@ -980,13 +1086,16 @@ function calculateShadows(lightsource, geometry, circle, image)
|
||||
end
|
||||
|
||||
shadowStencil = function()
|
||||
local shadowGeometry = calculateShadows(LOVE_LIGHT_CURRENT, LOVE_LIGHT_POLY, LOVE_LIGHT_CIRCLE)
|
||||
for i = 1,#shadowGeometry do
|
||||
love.graphics.polygon("fill", unpack(shadowGeometry[i]))
|
||||
for i = 1,#LOVE_LIGHT_SHADOW_GEOMETRY do
|
||||
if LOVE_LIGHT_SHADOW_GEOMETRY[i].alpha == 1.0 then
|
||||
love.graphics.polygon("fill", unpack(LOVE_LIGHT_SHADOW_GEOMETRY[i]))
|
||||
end
|
||||
end
|
||||
for i = 1, #LOVE_LIGHT_POLY do
|
||||
if LOVE_LIGHT_POLY[i].glassAlpha == 1.0 then
|
||||
love.graphics.polygon("fill", unpack(LOVE_LIGHT_POLY[i].data))
|
||||
end
|
||||
end
|
||||
for i = 1, #LOVE_LIGHT_CIRCLE do
|
||||
love.graphics.circle("fill", LOVE_LIGHT_CIRCLE[i].x, LOVE_LIGHT_CIRCLE[i].y, LOVE_LIGHT_CIRCLE[i].radius)
|
||||
end
|
||||
@ -997,14 +1106,14 @@ end
|
||||
|
||||
polyStencil = function()
|
||||
for i = 1, #LOVE_LIGHT_CIRCLE do
|
||||
if LOVE_LIGHT_CIRCLE[i].shine then
|
||||
--if LOVE_LIGHT_CIRCLE[i].shine and LOVE_LIGHT_CIRCLE[i].glassAlpha == 1.0 then
|
||||
love.graphics.circle("fill", LOVE_LIGHT_CIRCLE[i].x, LOVE_LIGHT_CIRCLE[i].y, LOVE_LIGHT_CIRCLE[i].radius)
|
||||
end
|
||||
--end
|
||||
end
|
||||
for i = 1, #LOVE_LIGHT_POLY do
|
||||
if LOVE_LIGHT_POLY[i].shine then
|
||||
--if LOVE_LIGHT_POLY[i].shine and LOVE_LIGHT_POLY[i].glassAlpha == 1.0 then
|
||||
love.graphics.polygon("fill", unpack(LOVE_LIGHT_POLY[i].data))
|
||||
end
|
||||
--end
|
||||
end
|
||||
for i = 1, #LOVE_LIGHT_IMAGE do
|
||||
if LOVE_LIGHT_IMAGE[i].shine then
|
||||
|
46
main.lua
46
main.lua
@ -63,11 +63,11 @@ function love.load()
|
||||
tile_glow = love.graphics.newImage "gfx/tile_glow.png"
|
||||
|
||||
-- light world
|
||||
lightRange = 300
|
||||
lightRange = 400
|
||||
lightSmooth = 1.0
|
||||
lightWorld = love.light.newWorld()
|
||||
lightWorld.setAmbientColor(15, 15, 31)
|
||||
mouseLight = lightWorld.newLight(0, 0, 255, 127, 63, lightRange)
|
||||
mouseLight = lightWorld.newLight(0, 0, 255, 191, 127, lightRange)
|
||||
mouseLight.setGlowStrength(0.3)
|
||||
mouseLight.setSmooth(lightSmooth)
|
||||
|
||||
@ -190,7 +190,8 @@ function love.draw()
|
||||
end
|
||||
|
||||
for i = 1, phyCnt do
|
||||
love.graphics.setColor(math.sin(i) * 255, math.cos(i) * 255, math.tan(i) * 255)
|
||||
math.randomseed(i)
|
||||
love.graphics.setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255))
|
||||
if phyLight[i].getType() == "polygon" then
|
||||
love.graphics.polygon("fill", phyLight[i].getPoints())
|
||||
elseif phyLight[i].getType() == "circle" then
|
||||
@ -207,7 +208,8 @@ function love.draw()
|
||||
if phyLight[i].getType() == "image" then
|
||||
if not normalOn then
|
||||
--love.graphics.setColor(255, 255, 255)
|
||||
love.graphics.setColor(127 + math.sin(i) * 127, 127 + math.cos(i) * 127, 127 + math.tan(i) * 127)
|
||||
math.randomseed(i)
|
||||
love.graphics.setColor(math.random(127, 255), math.random(127, 255), math.random(127, 255))
|
||||
love.graphics.draw(phyLight[i].img, phyLight[i].x - phyLight[i].ox2, phyLight[i].y - phyLight[i].oy2)
|
||||
elseif phyLight[i].normal then
|
||||
love.graphics.setColor(255, 255, 255)
|
||||
@ -437,6 +439,7 @@ function love.keypressed(k, u)
|
||||
phyCnt = phyCnt + 1
|
||||
phyLight[phyCnt] = lightWorld.newImage(blopp, mx, my, 42, 16, 21, 20)
|
||||
phyLight[phyCnt].generateNormalMapGradient("gradient", "gradient")
|
||||
phyLight[phyCnt].setAlpha(0.5)
|
||||
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
|
||||
phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 42, 29)
|
||||
phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt])
|
||||
@ -452,5 +455,40 @@ function love.keypressed(k, u)
|
||||
phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 64, 64)
|
||||
phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt])
|
||||
phyFixture[phyCnt]:setRestitution(0.5)
|
||||
elseif k == "8" then
|
||||
-- add rectangle
|
||||
phyCnt = phyCnt + 1
|
||||
phyLight[phyCnt] = lightWorld.newPolygon()
|
||||
phyLight[phyCnt].setAlpha(0.5)
|
||||
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
|
||||
phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, math.random(32, 64), math.random(32, 64))
|
||||
phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt])
|
||||
phyFixture[phyCnt]:setRestitution(0.5)
|
||||
math.randomseed(phyCnt)
|
||||
phyLight[phyCnt].setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255))
|
||||
elseif k == "9" then
|
||||
-- add circle
|
||||
cRadius = math.random(8, 32)
|
||||
phyCnt = phyCnt + 1
|
||||
phyLight[phyCnt] = lightWorld.newCircle(mx, my, cRadius)
|
||||
phyLight[phyCnt].setAlpha(0.5)
|
||||
math.randomseed(phyCnt)
|
||||
phyLight[phyCnt].setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255))
|
||||
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
|
||||
phyShape[phyCnt] = love.physics.newCircleShape(0, 0, cRadius)
|
||||
phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt])
|
||||
phyFixture[phyCnt]:setRestitution(0.5)
|
||||
elseif k == "0" then
|
||||
-- add image
|
||||
phyCnt = phyCnt + 1
|
||||
phyLight[phyCnt] = lightWorld.newImage(cone, mx, my, 24, 12, 12, 28)
|
||||
phyLight[phyCnt].setNormalMap(cone_normal)
|
||||
phyLight[phyCnt].setAlpha(0.0)
|
||||
math.randomseed(phyCnt)
|
||||
phyLight[phyCnt].setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255))
|
||||
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
|
||||
phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 24, 32)
|
||||
phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt])
|
||||
phyFixture[phyCnt]:setRestitution(0.5)
|
||||
end
|
||||
end
|
@ -1,7 +1,7 @@
|
||||
extern vec3 lightPositionRange;
|
||||
extern vec3 lightColor;
|
||||
extern float smooth;
|
||||
extern vec2 glow;
|
||||
extern float lightSmooth;
|
||||
extern vec2 lightGlow;
|
||||
|
||||
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords){
|
||||
vec4 pixel = Texel(texture, texture_coords);
|
||||
@ -10,10 +10,10 @@ vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords){
|
||||
float att = 1 - distance / lightPositionRange.z;
|
||||
|
||||
if (distance <= lightPositionRange.z) {
|
||||
if (glow.x < 1.0 && glow.y > 0.0) {
|
||||
pixel.rgb = clamp(lightColor * pow(att, smooth) + pow(smoothstep(glow.x, 1.0, att), smooth) * glow.y, 0.0, 1.0);
|
||||
if (lightGlow.x < 1.0 && lightGlow.y > 0.0) {
|
||||
pixel.rgb = clamp(lightColor * pow(att, lightSmooth) + pow(smoothstep(lightGlow.x, 1.0, att), lightSmooth) * lightGlow.y, 0.0, 1.0);
|
||||
} else {
|
||||
pixel.rgb = lightColor * pow(att, smooth);
|
||||
pixel.rgb = lightColor * pow(att, lightSmooth);
|
||||
}
|
||||
} else {
|
||||
pixel.rgb = vec3(0, 0, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user