Added image shadow.

This commit is contained in:
Marcus Ihde 2014-03-23 19:10:58 +01:00
parent 1df451ec48
commit f40ccd8e4e
8 changed files with 678 additions and 830 deletions

86
example.lua Normal file
View File

@ -0,0 +1,86 @@
require "postshader"
require "light"
function love.load()
-- load images
image = love.graphics.newImage("gfx/machine2.png")
image_normal = love.graphics.newImage("gfx/cone_normal.png")
normal = love.graphics.newImage("gfx/refraction_normal.png")
glow = love.graphics.newImage("gfx/machine2_glow.png")
-- create light world
lightWorld = love.light.newWorld()
lightWorld.setAmbientColor(15, 15, 31)
lightWorld.setRefractionStrength(32.0)
-- create light
lightMouse = lightWorld.newLight(0, 0, 255, 127, 63, 300)
lightMouse.setGlowStrength(0.3)
--lightMouse.setSmooth(0.01)
-- create shadow bodys
circleTest = lightWorld.newCircle(256, 256, 16)
rectangleTest = lightWorld.newRectangle(512, 512, 64, 64)
imageTest = lightWorld.newImage(image, 64, 64, 24, 6)
imageTest.setNormalMap(image_normal)
imageTest.setGlowMap(glow)
imageTest.setOffset(12, -10)
-- create body object
objectTest = lightWorld.newBody("refraction", normal, 64, 64, 128, 128)
--objectTest.setShine(false)
--objectTest.setShadowType("rectangle")
--objectTest.setShadowDimension(64, 64)
objectTest.setReflection(true)
-- set background
quadScreen = love.graphics.newQuad(0, 0, love.window.getWidth(), love.window.getHeight(), 32, 24)
imgFloor = love.graphics.newImage("gfx/floor.png")
imgFloor:setWrap("repeat", "repeat")
end
function love.update(dt)
love.window.setTitle("Light vs. Shadow Engine (FPS:" .. love.timer.getFPS() .. ")")
lightMouse.setPosition(love.mouse.getX(), love.mouse.getY())
end
function love.draw()
-- update lightmap (doesn't need deltatime)
lightWorld.update()
love.postshader.setBuffer("render")
-- draw background
love.graphics.setColor(255, 255, 255)
love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight())
--love.graphics.draw(imgFloor, quadScreen, 0, 0)
-- draw lightmap shadows
lightWorld.drawShadow()
-- draw scene objects
love.graphics.setColor(63, 255, 127)
love.graphics.circle("fill", circleTest.getX(), circleTest.getY(), circleTest.getRadius())
love.graphics.polygon("fill", rectangleTest.getPoints())
love.graphics.setColor(255, 255, 255)
love.graphics.draw(image, 64 - image:getWidth() * 0.5, 64 - image:getHeight() * 0.5)
--love.graphics.rectangle("fill", 128 - 32, 128 - 32, 64, 64)
-- draw lightmap shine
lightWorld.drawShine()
-- draw pixel shadow
lightWorld.drawPixelShadow()
-- draw glow
lightWorld.drawGlow()
-- draw refraction
lightWorld.drawRefraction()
-- draw reflection
lightWorld.drawReflection()
love.postshader.draw()
end

BIN
gfx/cone_large.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
gfx/cone_large_normal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

1302
light.lua

File diff suppressed because it is too large Load Diff

View File

@ -48,6 +48,8 @@ function love.load()
circle = love.graphics.newImage("gfx/circle.png")
circle_normal = love.graphics.newImage("gfx/circle_normal.png")
cone = love.graphics.newImage("gfx/cone.png")
cone_large = love.graphics.newImage("gfx/cone_large.png")
cone_large_normal = love.graphics.newImage("gfx/cone_large_normal.png")
cone_normal = love.graphics.newImage("gfx/cone_normal.png")
chest = love.graphics.newImage("gfx/chest.png")
chest_normal = love.graphics.newImage("gfx/chest_normal.png")
@ -92,7 +94,7 @@ function love.load()
lightOn = true
gravityOn = 1
shadowBlur = 2.0
bloomOn = true
bloomOn = 0.25
textureOn = true
normalOn = false
glowBlur = 1.0
@ -189,7 +191,7 @@ function love.update(dt)
end
if phyLight[i].getType() == "refraction" then
--if math.mod(i, 2) == 0 then
phyLight[i].setTileOffset(tileX, tileY)
phyLight[i].setNormalTileOffset(tileX, tileY)
--end
if offsetChanged then
phyLight[i].setPosition(phyLight[i].getX() + (offsetX - offsetOldX), phyLight[i].getY() + (offsetY - offsetOldY))
@ -272,10 +274,10 @@ function love.draw()
if not normalOn then
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)
love.graphics.draw(phyLight[i].img, phyLight[i].x - phyLight[i].ix, phyLight[i].y - phyLight[i].iy)
elseif phyLight[i].normal then
love.graphics.setColor(255, 255, 255)
love.graphics.draw(phyLight[i].normal, phyLight[i].x - phyLight[i].ox2, phyLight[i].y - phyLight[i].oy2)
love.graphics.draw(phyLight[i].normal, phyLight[i].x - phyLight[i].nx, phyLight[i].y - phyLight[i].ny)
end
end
end
@ -333,9 +335,9 @@ function love.draw()
love.graphics.setColor(255, 0, 0)
love.graphics.print("F5: Shadowblur (off)", 4 + 152 * 4, 4)
end
if bloomOn then
if bloomOn > 0.0 then
love.graphics.setColor(0, 255, 0)
love.graphics.print("F6: Bloom (on)", 4 + 152 * 0, 4 + 20 * 1)
love.graphics.print("F6: Bloom (" .. (bloomOn * 4) .. ")", 4 + 152 * 0, 4 + 20 * 1)
else
love.graphics.setColor(255, 0, 0)
love.graphics.print("F6: Bloom (off)", 4 + 152 * 0, 4 + 20 * 1)
@ -380,14 +382,18 @@ function love.draw()
end
-- draw shader
if bloomOn then
if colorAberration > 0.0 then
love.postshader.addEffect("blur", 2.0, 2.0)
love.postshader.addEffect("chromatic", math.sin(lightDirection * 10.0) * colorAberration, math.cos(lightDirection * 10.0) * colorAberration, math.cos(lightDirection * 10.0) * colorAberration, math.sin(lightDirection * 10.0) * -colorAberration, math.sin(lightDirection * 10.0) * colorAberration, math.cos(lightDirection * 10.0) * -colorAberration)
end
love.postshader.addEffect("bloom")
love.postshader.draw()
if colorAberration > 0.0 then
-- vert / horz blur
love.postshader.addEffect("blur", 2.0, 2.0)
love.postshader.addEffect("chromatic", math.sin(lightDirection * 10.0) * colorAberration, math.cos(lightDirection * 10.0) * colorAberration, math.cos(lightDirection * 10.0) * colorAberration, math.sin(lightDirection * 10.0) * -colorAberration, math.sin(lightDirection * 10.0) * colorAberration, math.cos(lightDirection * 10.0) * -colorAberration)
end
if bloomOn > 0.0 then
-- blur, strength
love.postshader.addEffect("bloom", 2.0, bloomOn)
end
love.postshader.draw()
end
function love.mousepressed(x, y, c)
@ -453,7 +459,10 @@ function love.keypressed(k, u)
end
lightWorld.setBlur(shadowBlur)
elseif k == "f6" or k == "b" then
bloomOn = not bloomOn
bloomOn = math.max(0.25, bloomOn * 2.0)
if bloomOn > 1.0 then
bloomOn = 0.0
end
elseif k == "f7" then
textureOn = not textureOn
elseif k == "f8" then
@ -466,7 +475,7 @@ function love.keypressed(k, u)
lightWorld.setGlowStrength(glowBlur)
elseif k == "f11" then
physicWorld:destroy()
lightWorld.clearObjects()
lightWorld.clearBodys()
initScene()
elseif k == "f12" then
lightWorld.clearLights()
@ -478,6 +487,7 @@ function love.keypressed(k, u)
phyCnt = phyCnt + 1
phyLight[phyCnt] = lightWorld.newImage(circle, mx, my)
phyLight[phyCnt].setNormalMap(circle_normal)
phyLight[phyCnt].setShadowType("circle", 16)
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 32)
phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt])
@ -485,8 +495,9 @@ function love.keypressed(k, u)
elseif k == "2" then
-- add image
phyCnt = phyCnt + 1
phyLight[phyCnt] = lightWorld.newImage(cone, mx, my, 24, 12, 12, 28)
phyLight[phyCnt] = lightWorld.newImage(cone, mx, my, 24, 12, 12, 16)
phyLight[phyCnt].setNormalMap(cone_normal)
--phyLight[phyCnt].setShadowType("circle", 12, 0, -8)
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])
@ -494,7 +505,7 @@ function love.keypressed(k, u)
elseif k == "3" then
-- add image
phyCnt = phyCnt + 1
phyLight[phyCnt] = lightWorld.newImage(chest, mx, my, 32, 24, 16, 36)
phyLight[phyCnt] = lightWorld.newImage(chest, mx, my, 32, 24, 16, 0)
phyLight[phyCnt].setNormalMap(chest_normal)
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 24)
@ -502,10 +513,10 @@ function love.keypressed(k, u)
phyFixture[phyCnt]:setRestitution(0.5)
elseif k == "4" then
-- add glow image
local r = lightWorld.getImageCount() % 5
local r = lightWorld.getBodyCount() % 5
if r == 0 then
phyCnt = phyCnt + 1
phyLight[phyCnt] = lightWorld.newImage(machine, mx, my, 32, 24, 16, 36)
phyLight[phyCnt] = lightWorld.newImage(machine, mx, my, 32, 24, 16, 0)
phyLight[phyCnt].setNormalMap(machine_normal)
phyLight[phyCnt].setGlowMap(machine_glow)
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
@ -514,7 +525,7 @@ function love.keypressed(k, u)
phyFixture[phyCnt]:setRestitution(0.5)
elseif r == 1 then
phyCnt = phyCnt + 1
phyLight[phyCnt] = lightWorld.newImage(machine2, mx, my, 24, 12, 12, 28)
phyLight[phyCnt] = lightWorld.newImage(machine2, mx, my, 24, 12, 12, -4)
phyLight[phyCnt].setNormalMap(machine2_normal)
phyLight[phyCnt].setGlowMap(machine2_glow)
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
@ -523,7 +534,7 @@ function love.keypressed(k, u)
phyFixture[phyCnt]:setRestitution(0.5)
elseif r == 2 then
phyCnt = phyCnt + 1
phyLight[phyCnt] = lightWorld.newImage(led, mx, my, 32, 6, 16, 27)
phyLight[phyCnt] = lightWorld.newImage(led, mx, my, 32, 6, 16, -8)
phyLight[phyCnt].setNormalMap(led_normal)
phyLight[phyCnt].setGlowMap(led_glow)
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
@ -532,7 +543,7 @@ function love.keypressed(k, u)
phyFixture[phyCnt]:setRestitution(0.5)
elseif r == 3 then
phyCnt = phyCnt + 1
phyLight[phyCnt] = lightWorld.newImage(led2, mx, my, 32, 6, 16, 27)
phyLight[phyCnt] = lightWorld.newImage(led2, mx, my, 32, 6, 16, -8)
phyLight[phyCnt].setNormalMap(led_normal)
phyLight[phyCnt].setGlowMap(led_glow2)
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
@ -541,7 +552,7 @@ function love.keypressed(k, u)
phyFixture[phyCnt]:setRestitution(0.5)
elseif r == 4 then
phyCnt = phyCnt + 1
phyLight[phyCnt] = lightWorld.newImage(led3, mx, my, 32, 6, 16, 27)
phyLight[phyCnt] = lightWorld.newImage(led3, mx, my, 32, 6, 16, -8)
phyLight[phyCnt].setNormalMap(led_normal)
phyLight[phyCnt].setGlowMap(led_glow3)
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
@ -552,9 +563,9 @@ function love.keypressed(k, u)
elseif k == "5" then
-- add image
phyCnt = phyCnt + 1
phyLight[phyCnt] = lightWorld.newImage(machine2, mx, my, 24, 12, 12, 28)
phyLight[phyCnt].setNormalMap(machine2_normal)
phyLight[phyCnt].setGlowMap(machine2_glow)
phyLight[phyCnt] = lightWorld.newImage(cone_large, mx, my, 24, 128, 12, 64)
phyLight[phyCnt].setNormalMap(cone_large_normal)
phyLight[phyCnt].setShadowType("image", 0, -6, 0.0)
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])
@ -562,7 +573,7 @@ function love.keypressed(k, u)
elseif k == "6" then
-- add image
phyCnt = phyCnt + 1
phyLight[phyCnt] = lightWorld.newImage(blopp, mx, my, 42, 16, 21, 20)
phyLight[phyCnt] = lightWorld.newImage(blopp, mx, my, 42, 16, 21, 0)
phyLight[phyCnt].generateNormalMapGradient("gradient", "gradient")
phyLight[phyCnt].setAlpha(0.5)
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
@ -615,6 +626,7 @@ function love.keypressed(k, u)
elseif k == "0" then
phyCnt = phyCnt + 1
phyLight[phyCnt] = lightWorld.newRefraction(refraction_normal, mx, my)
phyLight[phyCnt].setReflection(true)
elseif k == "l" then
-- add light
local r = lightWorld.getLightCount() % 3

View File

@ -1,40 +0,0 @@
require "light"
function love.load()
-- create light world
lightWorld = love.light.newWorld()
lightWorld.setAmbientColor(15, 15, 31)
-- create light
lightMouse = lightWorld.newLight(0, 0, 255, 127, 63, 300)
lightMouse.setGlowStrength(0.3)
-- create shadow bodys
circleTest = lightWorld.newCircle(256, 256, 32)
rectangleTest = lightWorld.newRectangle(512, 512, 64, 64)
end
function love.update(dt)
love.window.setTitle("Light vs. Shadow Engine (FPS:" .. love.timer.getFPS() .. ")")
lightMouse.setPosition(love.mouse.getX(), love.mouse.getY())
end
function love.draw()
-- update lightmap (doesn't need deltatime)
lightWorld.update()
-- draw background
love.graphics.setColor(255, 255, 255)
love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight())
-- draw lightmap shadows
lightWorld.drawShadow()
-- draw scene objects
love.graphics.setColor(63, 255, 127)
love.graphics.circle("fill", circleTest.getX(), circleTest.getY(), circleTest.getRadius())
love.graphics.polygon("fill", rectangleTest.getPoints())
-- draw lightmap shine
lightWorld.drawShine()
end

View File

@ -27,6 +27,8 @@ love.postshader.addEffect = function(shader, ...)
if shader == "bloom" then
-- Bloom Shader
LOVE_POSTSHADER_BLURV:send("steps", args[1] or 2.0)
LOVE_POSTSHADER_BLURH:send("steps", args[1] or 2.0)
love.graphics.setCanvas(LOVE_POSTSHADER_BUFFER_BACK)
love.graphics.setBlendMode("alpha")
@ -44,7 +46,7 @@ love.postshader.addEffect = function(shader, ...)
love.graphics.setColor(255, 255, 255)
love.graphics.draw(LOVE_POSTSHADER_BUFFER_RENDER)
love.graphics.setBlendMode("additive")
love.graphics.setColor(255, 255, 255, 63)
love.graphics.setColor(255, 255, 255, (args[2] or 0.25) * 255)
love.graphics.draw(LOVE_POSTSHADER_BUFFER_BACK)
love.graphics.setBlendMode("alpha")
elseif shader == "blur" then

View File

@ -2,13 +2,17 @@ extern Image backBuffer;
extern vec2 screen = vec2(800.0, 600.0);
extern float refractionStrength = 1.0;
extern vec3 refractionColor = vec3(1.0, 1.0, 1.0);
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {
vec2 pSize = vec2(1.0 / screen.x, 1.0 / screen.y);
vec4 normal = Texel(texture, texture_coords);
if(normal.b > 0.0) {
return vec4(Texel(backBuffer, vec2(texture_coords.x + (normal.x - 0.5) * pSize.x * refractionStrength, texture_coords.y + (normal.y - 0.5) * pSize.y * refractionStrength)).rgb * refractionColor, 1.0);
if(normal.a > 0.0) {
vec4 normalOffset = Texel(texture, vec2(texture_coords.x + (normal.x - 0.5) * pSize.x * refractionStrength, texture_coords.y + (normal.y - 0.5) * pSize.y * refractionStrength));
if(normalOffset.a > 0.0) {
return Texel(backBuffer, vec2(texture_coords.x + (normal.x - 0.5) * pSize.x * refractionStrength, texture_coords.y + (normal.y - 0.5) * pSize.y * refractionStrength));
} else {
return Texel(backBuffer, texture_coords);
}
} else {
return vec4(0.0);
}