diff --git a/gfx/cone_normal.png b/gfx/cone_normal.png index 879997f..34c5275 100644 Binary files a/gfx/cone_normal.png and b/gfx/cone_normal.png differ diff --git a/gfx/led.png b/gfx/led.png new file mode 100644 index 0000000..d743714 Binary files /dev/null and b/gfx/led.png differ diff --git a/gfx/led2.png b/gfx/led2.png new file mode 100644 index 0000000..9994c85 Binary files /dev/null and b/gfx/led2.png differ diff --git a/gfx/led3.png b/gfx/led3.png new file mode 100644 index 0000000..61dd0b1 Binary files /dev/null and b/gfx/led3.png differ diff --git a/gfx/led_glow.png b/gfx/led_glow.png new file mode 100644 index 0000000..2b22eed Binary files /dev/null and b/gfx/led_glow.png differ diff --git a/gfx/led_glow2.png b/gfx/led_glow2.png new file mode 100644 index 0000000..c18cd92 Binary files /dev/null and b/gfx/led_glow2.png differ diff --git a/gfx/led_glow3.png b/gfx/led_glow3.png new file mode 100644 index 0000000..e025f29 Binary files /dev/null and b/gfx/led_glow3.png differ diff --git a/gfx/led_normal.png b/gfx/led_normal.png new file mode 100644 index 0000000..6890b1f Binary files /dev/null and b/gfx/led_normal.png differ diff --git a/gfx/machine.png b/gfx/machine.png index 6df0cde..ffc30b6 100644 Binary files a/gfx/machine.png and b/gfx/machine.png differ diff --git a/gfx/machine2.png b/gfx/machine2.png index f0f4ec7..956a463 100644 Binary files a/gfx/machine2.png and b/gfx/machine2.png differ diff --git a/gfx/machine2_glow.png b/gfx/machine2_glow.png index 030c494..67cd80e 100644 Binary files a/gfx/machine2_glow.png and b/gfx/machine2_glow.png differ diff --git a/gfx/machine_glow.png b/gfx/machine_glow.png index 897c0da..4cb1f4e 100644 Binary files a/gfx/machine_glow.png and b/gfx/machine_glow.png differ diff --git a/gfx/water.png b/gfx/water.png index c61b26b..f033295 100644 Binary files a/gfx/water.png and b/gfx/water.png differ diff --git a/light.lua b/light.lua index 648e3fe..82b12bf 100644 --- a/light.lua +++ b/light.lua @@ -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 diff --git a/main.lua b/main.lua index cec1087..04436ac 100644 --- a/main.lua +++ b/main.lua @@ -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 \ No newline at end of file diff --git a/postshader.lua b/postshader.lua index e96e7ed..28aaa3d 100644 --- a/postshader.lua +++ b/postshader.lua @@ -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 \ No newline at end of file diff --git a/shader/chromatic_aberration.glsl b/shader/chromatic_aberration.glsl new file mode 100644 index 0000000..6d6909c --- /dev/null +++ b/shader/chromatic_aberration.glsl @@ -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); +} \ No newline at end of file diff --git a/shader/glow.glsl b/shader/glow.glsl new file mode 100644 index 0000000..2b5d456 --- /dev/null +++ b/shader/glow.glsl @@ -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); +} \ No newline at end of file