Add glow animation and chromatic aberration.

This commit is contained in:
Marcus Ihde 2014-03-19 23:22:46 +01:00
parent bae4a0db4d
commit 1df451ec48
18 changed files with 190 additions and 35 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
gfx/led.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
gfx/led2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

BIN
gfx/led3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
gfx/led_glow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
gfx/led_glow2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1019 B

BIN
gfx/led_glow3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
gfx/led_normal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 981 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 988 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 979 B

After

Width:  |  Height:  |  Size: 990 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -39,10 +39,13 @@ function love.light.newWorld()
o.reflectionMap2 = love.graphics.newCanvas()
o.glowBlur = 1.0
o.isGlowBlur = false
o.glowTimer = 0.0
o.glowDown = false
o.refractionStrength = 8.0
o.pixelShadow = love.graphics.newCanvas()
o.pixelShadow2 = love.graphics.newCanvas()
o.shader = love.graphics.newShader("shader/poly_shadow.glsl")
o.glowShader = love.graphics.newShader("shader/glow.glsl")
o.normalShader = love.graphics.newShader("shader/normal.glsl")
o.refractionShader = love.graphics.newShader("shader/refraction.glsl")
o.refractionShader:send("screen", {love.window.getWidth(), love.window.getHeight()})
@ -234,7 +237,7 @@ function love.light.newWorld()
love.graphics.setBlendMode("alpha")
-- create glow map
if o.changed then
--if o.changed then
o.glowMap:clear(0, 0, 0)
love.graphics.setCanvas(o.glowMap)
for i = 1, #o.circle do
@ -255,17 +258,34 @@ function love.light.newWorld()
love.graphics.polygon("fill", unpack(o.poly[i].data))
end
end
for i = 1, #o.img do
if o.img[i].glow then
love.graphics.setColor(o.img[i].glowRed, o.img[i].glowGreen, o.img[i].glowBlue)
love.graphics.draw(o.img[i].glow, o.img[i].x - o.img[i].ox2 + LOVE_LIGHT_TRANSLATE_X, o.img[i].y - o.img[i].oy2 + LOVE_LIGHT_TRANSLATE_Y)
else
love.graphics.setColor(0, 0, 0)
love.graphics.draw(o.img[i].img, o.img[i].x - o.img[i].ox2 + LOVE_LIGHT_TRANSLATE_X, o.img[i].y - o.img[i].oy2 + LOVE_LIGHT_TRANSLATE_Y)
if o.glowDown then
o.glowTimer = math.max(0.0, o.glowTimer - love.timer.getDelta())
if o.glowTimer == 0.0 then
o.glowDown = not o.glowDown
end
else
o.glowTimer = math.min(o.glowTimer + love.timer.getDelta(), 1.0)
if o.glowTimer == 1.0 then
o.glowDown = not o.glowDown
end
end
for i = 1, #o.img do
if o.img[i].glow then
love.graphics.setShader(o.glowShader)
o.glowShader:send("glowImage", o.img[i].glow)
o.glowShader:send("glowTime", love.timer.getTime())
love.graphics.setColor(255, 255, 255)
else
love.graphics.setShader()
love.graphics.setColor(0, 0, 0)
end
love.graphics.draw(o.img[i].img, o.img[i].x - o.img[i].ox2 + LOVE_LIGHT_TRANSLATE_X, o.img[i].y - o.img[i].oy2 + LOVE_LIGHT_TRANSLATE_Y)
end
love.graphics.setShader()
o.isGlowBlur = false
end
--end
-- create refraction map
if o.changed then
@ -282,7 +302,7 @@ function love.light.newWorld()
end
end
for i = 1, #o.img do
if o.img[i].img then
if not o.img[i].refractive and o.img[i].img then
love.graphics.setColor(0, 0, 0)
love.graphics.draw(o.img[i].img, o.img[i].x - o.img[i].ox2 + LOVE_LIGHT_TRANSLATE_X, o.img[i].y - o.img[i].oy2 + LOVE_LIGHT_TRANSLATE_Y)
end
@ -538,7 +558,7 @@ function love.light.newWorld()
end
-- get polygon count
o.getObjectCount = function()
return #o.poly + #o.circle
return #o.poly + #o.circle + #o.img
end
-- get circle count
o.getCircleCount = function()
@ -548,6 +568,10 @@ function love.light.newWorld()
o.getPolygonCount = function()
return #o.poly
end
-- get image count
o.getImageCount = function()
return #o.img
end
-- get polygon
o.getPoints = function(n)
return unpack(o.poly[n].data)
@ -1046,6 +1070,7 @@ function love.light.newImage(p, img, x, y, width, height, ox, oy)
o.glowStrength = 0.0
o.refractionStrength = 1.0
o.reflective = true
o.refractive = false
o.type = "image"
p.changed = true
o.data = {
@ -1147,6 +1172,14 @@ function love.light.newImage(p, img, x, y, width, height, ox, oy)
o.glassAlpha = alpha
p.changed = true
end
-- set reflective on other objects on/off
o.setReflective = function(reflective)
o.reflective = reflective
end
-- set refractive on other objects on/off
o.setRefractive = function(refractive)
o.refractive = refractive
end
-- set image
o.setImage = function(img)
o.img = img

100
main.lua
View File

@ -63,6 +63,13 @@ function love.load()
tile_glow = love.graphics.newImage("gfx/tile_glow.png")
refraction_normal = love.graphics.newImage("gfx/refraction_normal.png")
water = love.graphics.newImage("gfx/water.png")
led = love.graphics.newImage("gfx/led.png")
led2 = love.graphics.newImage("gfx/led2.png")
led3 = love.graphics.newImage("gfx/led3.png")
led_normal = love.graphics.newImage("gfx/led_normal.png")
led_glow = love.graphics.newImage("gfx/led_glow.png")
led_glow2 = love.graphics.newImage("gfx/led_glow2.png")
led_glow3 = love.graphics.newImage("gfx/led_glow3.png")
-- light world
lightRange = 400
@ -75,6 +82,7 @@ function love.load()
mouseLight.setGlowStrength(0.3)
mouseLight.setSmooth(lightSmooth)
lightDirection = 0.0
colorAberration = 0.0
-- init physic world
initScene()
@ -105,6 +113,7 @@ function love.update(dt)
mx = love.mouse.getX()
my = love.mouse.getY()
lightDirection = lightDirection + dt
colorAberration = math.max(0.0, colorAberration - dt * 10.0)
if love.keyboard.isDown("w") then
for i = 1, phyCnt do
@ -179,7 +188,9 @@ function love.update(dt)
end
end
if phyLight[i].getType() == "refraction" then
phyLight[i].setTileOffset(tileX, tileY)
--if math.mod(i, 2) == 0 then
phyLight[i].setTileOffset(tileX, tileY)
--end
if offsetChanged then
phyLight[i].setPosition(phyLight[i].getX() + (offsetX - offsetOldX), phyLight[i].getY() + (offsetY - offsetOldY))
end
@ -218,12 +229,19 @@ function love.draw()
end
end
love.graphics.setBlendMode("multiplicative")
for i = 1, phyCnt do
if phyLight[i].getType() == "refraction" then
if not normalOn then
love.graphics.setColor(255, 255, 255, 127)
love.graphics.draw(water, phyLight[i].x - phyLight[i].ox, phyLight[i].y - phyLight[i].oy)
--if math.mod(i, 2) == 0 then
love.graphics.setBlendMode("alpha")
love.graphics.setColor(255, 255, 255, 191)
love.graphics.draw(water, phyLight[i].x - phyLight[i].ox, phyLight[i].y - phyLight[i].oy)
--else
--love.graphics.setBlendMode("multiplicative")
--math.randomseed(i)
--love.graphics.setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255))
--love.graphics.rectangle("fill", phyLight[i].x - phyLight[i].ox, phyLight[i].y - phyLight[i].oy, 128, 128)
--end
end
end
end
@ -363,7 +381,12 @@ function love.draw()
-- draw shader
if bloomOn then
love.postshader.draw("bloom")
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()
end
end
@ -429,7 +452,7 @@ function love.keypressed(k, u)
shadowBlur = 0.0
end
lightWorld.setBlur(shadowBlur)
elseif k == "f6" then
elseif k == "f6" or k == "b" then
bloomOn = not bloomOn
elseif k == "f7" then
textureOn = not textureOn
@ -478,15 +501,54 @@ function love.keypressed(k, u)
phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt])
phyFixture[phyCnt]:setRestitution(0.5)
elseif k == "4" then
-- add image
phyCnt = phyCnt + 1
phyLight[phyCnt] = lightWorld.newImage(machine, mx, my, 32, 24, 16, 36)
phyLight[phyCnt].setNormalMap(machine_normal)
phyLight[phyCnt].setGlowMap(machine_glow)
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 24)
phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt])
phyFixture[phyCnt]:setRestitution(0.5)
-- add glow image
local r = lightWorld.getImageCount() % 5
if r == 0 then
phyCnt = phyCnt + 1
phyLight[phyCnt] = lightWorld.newImage(machine, mx, my, 32, 24, 16, 36)
phyLight[phyCnt].setNormalMap(machine_normal)
phyLight[phyCnt].setGlowMap(machine_glow)
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 24)
phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt])
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].setNormalMap(machine2_normal)
phyLight[phyCnt].setGlowMap(machine2_glow)
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)
elseif r == 2 then
phyCnt = phyCnt + 1
phyLight[phyCnt] = lightWorld.newImage(led, mx, my, 32, 6, 16, 27)
phyLight[phyCnt].setNormalMap(led_normal)
phyLight[phyCnt].setGlowMap(led_glow)
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 6)
phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt])
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].setNormalMap(led_normal)
phyLight[phyCnt].setGlowMap(led_glow2)
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 6)
phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt])
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].setNormalMap(led_normal)
phyLight[phyCnt].setGlowMap(led_glow3)
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 32, 6)
phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt])
phyFixture[phyCnt]:setRestitution(0.5)
end
elseif k == "5" then
-- add image
phyCnt = phyCnt + 1
@ -553,10 +615,6 @@ function love.keypressed(k, u)
elseif k == "0" then
phyCnt = phyCnt + 1
phyLight[phyCnt] = lightWorld.newRefraction(refraction_normal, mx, my)
--phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
--phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, phyLight[phyCnt].getWidth(), phyLight[phyCnt].getHeight())
--phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt])
--phyFixture[phyCnt]:setRestitution(0.5)
elseif k == "l" then
-- add light
local r = lightWorld.getLightCount() % 3
@ -573,5 +631,9 @@ function love.keypressed(k, u)
light.setGlowStrength(0.3)
math.randomseed(love.timer.getTime())
light.setAngle(math.random(1, 5) * 0.1 * math.pi)
elseif k == "c" then
if colorAberration == 0.0 then
colorAberration = 3.0
end
end
end

View File

@ -5,6 +5,7 @@ LOVE_POSTSHADER_LAST_BUFFER = nil
LOVE_POSTSHADER_BLURV = love.graphics.newShader("shader/blurv.glsl")
LOVE_POSTSHADER_BLURH = love.graphics.newShader("shader/blurh.glsl")
LOVE_POSTSHADER_CONTRAST = love.graphics.newShader("shader/contrast.glsl")
LOVE_POSTSHADER_CHROMATIC_ABERRATION = love.graphics.newShader("shader/chromatic_aberration.glsl")
LOVE_POSTSHADER_BLURV:send("screen", {love.window.getWidth(), love.window.getHeight()})
LOVE_POSTSHADER_BLURH:send("screen", {love.window.getWidth(), love.window.getHeight()})
@ -17,9 +18,11 @@ love.postshader.setBuffer = function(path)
else
love.graphics.setCanvas(LOVE_POSTSHADER_BUFFER_RENDER)
end
LOVE_POSTSHADER_LAST_BUFFER = love.graphics.getCanvas()
end
love.postshader.draw = function(shader)
love.postshader.addEffect = function(shader, ...)
args = {...}
LOVE_POSTSHADER_LAST_BUFFER = love.graphics.getCanvas()
if shader == "bloom" then
@ -36,7 +39,7 @@ love.postshader.draw = function(shader)
love.graphics.setShader(LOVE_POSTSHADER_CONTRAST)
love.graphics.draw(LOVE_POSTSHADER_BUFFER_BACK)
love.graphics.setCanvas(LOVE_LIGHTMAP_LAST_BUFFER)
love.graphics.setCanvas(LOVE_POSTSHADER_LAST_BUFFER)
love.graphics.setShader()
love.graphics.setColor(255, 255, 255)
love.graphics.draw(LOVE_POSTSHADER_BUFFER_RENDER)
@ -46,8 +49,8 @@ love.postshader.draw = function(shader)
love.graphics.setBlendMode("alpha")
elseif shader == "blur" then
-- Blur Shader
LOVE_POSTSHADER_BLURV:send("steps", 2.0)
LOVE_POSTSHADER_BLURH:send("steps", 2.0)
LOVE_POSTSHADER_BLURV:send("steps", args[1] or 2.0)
LOVE_POSTSHADER_BLURH:send("steps", args[2] or 2.0)
love.graphics.setCanvas(LOVE_POSTSHADER_BUFFER_BACK)
love.graphics.setBlendMode("alpha")
@ -57,9 +60,33 @@ love.postshader.draw = function(shader)
love.graphics.setShader(LOVE_POSTSHADER_BLURH)
love.graphics.draw(LOVE_POSTSHADER_BUFFER_BACK)
love.graphics.setCanvas(LOVE_LIGHTMAP_LAST_BUFFER)
love.graphics.setCanvas(LOVE_POSTSHADER_LAST_BUFFER)
love.graphics.setShader()
love.graphics.setColor(255, 255, 255)
love.graphics.draw(LOVE_POSTSHADER_BUFFER_BACK)
elseif shader == "chromatic" then
-- Blur Shader
LOVE_POSTSHADER_CHROMATIC_ABERRATION:send("redStrength", {args[1] or 0.0, args[2] or 0.0})
LOVE_POSTSHADER_CHROMATIC_ABERRATION:send("greenStrength", {args[3] or 0.0, args[4] or 0.0})
LOVE_POSTSHADER_CHROMATIC_ABERRATION:send("blueStrength", {args[5] or 0.0, args[6] or 0.0})
love.graphics.setCanvas(LOVE_POSTSHADER_BUFFER_BACK)
love.graphics.setBlendMode("alpha")
love.graphics.setShader(LOVE_POSTSHADER_CHROMATIC_ABERRATION)
love.graphics.draw(LOVE_POSTSHADER_BUFFER_RENDER)
love.graphics.setCanvas(LOVE_POSTSHADER_LAST_BUFFER)
love.graphics.setShader()
love.graphics.setColor(255, 255, 255)
love.graphics.draw(LOVE_POSTSHADER_BUFFER_BACK)
end
end
love.postshader.draw = function()
if LOVE_POSTSHADER_LAST_BUFFER then
love.graphics.setCanvas()
love.graphics.setShader()
love.graphics.setColor(255, 255, 255)
love.graphics.draw(LOVE_POSTSHADER_LAST_BUFFER)
end
end

View File

@ -0,0 +1,13 @@
extern vec2 screen = vec2(800.0, 600.0);
extern vec2 redStrength = vec2(4.0, 3.0);
extern vec2 greenStrength = vec2(-2.0, -1.0);
extern vec2 blueStrength = vec2(1.0, -3.0);
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {
vec2 pSize = vec2(1.0 / screen.x, 1.0 / screen.y);
float colRed = Texel(texture, vec2(texture_coords.x + pSize.x * redStrength.x, texture_coords.y - pSize.y * redStrength.y)).r;
float colGreen = Texel(texture, vec2(texture_coords.x + pSize.x * greenStrength.x, texture_coords.y - pSize.y * greenStrength.y)).g;
float colBlue = Texel(texture, vec2(texture_coords.x + pSize.x * blueStrength.x, texture_coords.y - pSize.y * blueStrength.y)).b;
return vec4(colRed, colGreen, colBlue, 1.0);
}

20
shader/glow.glsl Normal file
View File

@ -0,0 +1,20 @@
extern Image glowImage;
extern float glowTime;
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {
vec3 glowInfo = Texel(glowImage, texture_coords).rgb;
if(glowInfo.r != glowInfo.g) {
float glowStrength = glowTime + glowInfo.b;
if(mod(glowStrength, 2.0) < 1.0) {
glowInfo.b = mod(glowStrength, 1.0);
} else {
glowInfo.b = 1.0 - mod(glowStrength, 1.0);
}
return Texel(texture, texture_coords) * (glowInfo.g + glowInfo.b * (glowInfo.r - glowInfo.g));
}
return vec4(Texel(texture, texture_coords).rgb * glowInfo.r, 1.0);
}