diff --git a/gfx/light.png b/gfx/light.png new file mode 100644 index 0000000..e142986 Binary files /dev/null and b/gfx/light.png differ diff --git a/light.lua b/light.lua index d18dc7d..e69beba 100644 --- a/light.lua +++ b/light.lua @@ -87,7 +87,7 @@ function love.light.newWorld() local lightposrange = {o.lights[i].x, love.graphics.getHeight() - o.lights[i].y, o.lights[i].range} LOVE_LIGHT_CURRENT = o.lights[i] LOVE_LIGHT_DIRECTION = LOVE_LIGHT_DIRECTION + 0.002 - o.shader:send("lightPosition", {o.lights[i].x - LOVE_LIGHT_TRANSLATE_X, love.graphics.getHeight() - (o.lights[i].y - LOVE_LIGHT_TRANSLATE_Y)}) + o.shader:send("lightPosition", {o.lights[i].x - LOVE_LIGHT_TRANSLATE_X, love.graphics.getHeight() - (o.lights[i].y - LOVE_LIGHT_TRANSLATE_Y), o.lights[i].z}) o.shader:send("lightRange", 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("lightSmooth", o.lights[i].smooth) @@ -315,9 +315,8 @@ function love.light.newWorld() end end end - - love.graphics.setBlendMode("replace") - love.graphics.setColor(0, 0, 0, 0) + + love.graphics.setColor(0, 0, 0) for i = 1, #o.body do if not o.body[i].refractive then if o.body[i].type == "circle" then @@ -333,7 +332,6 @@ function love.light.newWorld() end -- create reflection map - love.graphics.setBlendMode("alpha") if o.changed then o.reflectionMap:clear(0, 0, 0) love.graphics.setCanvas(o.reflectionMap) @@ -615,8 +613,8 @@ function love.light.newWorld() end end -- set light position - o.setLightPosition = function(n, x, y) - o.lights[n].setPosition(x, y) + o.setLightPosition = function(n, x, y, z) + o.lights[n].setPosition(x, y, z) end -- set light x o.setLightX = function(n, x) @@ -675,10 +673,12 @@ function love.light.newLight(p, x, y, red, green, blue, range) o.changed = true o.visible = true -- set position - o.setPosition = function(x, y) - if x ~= o.x or y ~= o.y then + o.setPosition = function(x, y, z) + o.z = z or o.z + if x ~= o.x or y ~= o.y or z ~= o.z then o.x = x o.y = y + o.z = z o.changed = true end end diff --git a/main.lua b/main.lua index a76ca56..c7f14c2 100644 --- a/main.lua +++ b/main.lua @@ -75,6 +75,7 @@ function love.load() ape = love.graphics.newImage("gfx/ape.png") ape_normal = love.graphics.newImage("gfx/ape_normal.png") ape_glow = love.graphics.newImage("gfx/ape_glow.png") + imgLight = love.graphics.newImage("gfx/light.png") -- materials material = {} @@ -110,6 +111,7 @@ function love.load() textureOn = true normalOn = false glowBlur = 1.0 + effectOn = 0.0 offsetX = 0.0 offsetY = 0.0 @@ -123,7 +125,7 @@ end function love.update(dt) love.window.setTitle("Light vs. Shadow Engine (FPS:" .. love.timer.getFPS() .. ")") - mouseLight.setPosition(love.mouse.getX(), love.mouse.getY()) + mouseLight.setPosition(love.mouse.getX(), love.mouse.getY(), 16.0 + (math.sin(lightDirection) + 1.0) * 64.0) mx = love.mouse.getX() my = love.mouse.getY() lightDirection = lightDirection + dt @@ -282,20 +284,22 @@ function love.draw() love.graphics.setBlendMode("alpha") for i = 1, phyCnt do - if phyLight[i].getType() == "image" and not phyLight[i].material then - if not normalOn then + if phyLight[i].getType() == "image" then + if normalOn and phyLight[i].normal then + love.graphics.setColor(255, 255, 255) + love.graphics.draw(phyLight[i].normal, phyLight[i].x - phyLight[i].nx, phyLight[i].y - phyLight[i].ny) + elseif not phyLight[i].material 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].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].nx, phyLight[i].y - phyLight[i].ny) end end end - lightWorld.drawMaterial() - + if not normalOn then + lightWorld.drawMaterial() + end + -- draw pixel shadow if lightOn and not normalOn then lightWorld.drawPixelShadow() @@ -312,6 +316,8 @@ function love.draw() -- draw refraction lightWorld.drawRefraction() + love.graphics.draw(imgLight, mx - 5, (my - 5) - (16.0 + (math.sin(lightDirection) + 1.0) * 64.0)) + -- draw help if helpOn then love.graphics.setBlendMode("alpha") @@ -377,6 +383,13 @@ function love.draw() love.graphics.setColor(255, 0, 0) love.graphics.print("F9: Glow Blur (off)", 4 + 152 * 3, 4 + 20 * 1) end + if effectOn >= 1.0 then + love.graphics.setColor(0, 255, 0) + love.graphics.print("F10: Effects (" .. effectOn .. ")", 4 + 152 * 4, 4 + 20 * 1) + else + love.graphics.setColor(255, 0, 0) + love.graphics.print("F10: Effects (off)", 4 + 152 * 4, 4 + 20 * 1) + end love.graphics.setColor(255, 0, 255) love.graphics.print("F11: Clear obj.", 4 + 152 * 4, 4 + 20 * 2) love.graphics.print("F12: Clear lights", 4 + 152 * 4, 4 + 20 * 3) @@ -407,6 +420,17 @@ function love.draw() love.postshader.addEffect("bloom", 2.0, bloomOn) end + if effectOn == 1.0 then + love.postshader.addEffect("4colors", {15, 56, 15}, {48, 98, 48}, {139, 172, 15}, {155, 188, 15}) + --love.postshader.addEffect("4colors", {108, 108, 78}, {142, 139, 87}, {195, 196, 165}, {227, 230, 201}) + elseif effectOn == 2.0 then + love.postshader.addEffect("monochrom") + elseif effectOn == 3.0 then + love.postshader.addEffect("scanlines") + elseif effectOn == 4.0 then + love.postshader.addEffect("tiltshift", 4.0) + end + love.postshader.draw() end @@ -427,6 +451,7 @@ function love.mousepressed(x, y, c) light.setGlowStrength(0.3) elseif c == "l" then -- add rectangle + math.randomseed(love.timer.getTime()) phyCnt = phyCnt + 1 phyLight[phyCnt] = lightWorld.newPolygon() phyBody[phyCnt] = love.physics.newBody(physicWorld, x, y, "dynamic") @@ -435,6 +460,7 @@ function love.mousepressed(x, y, c) phyFixture[phyCnt]:setRestitution(0.5) elseif c == "r" then -- add circle + math.randomseed(love.timer.getTime()) cRadius = math.random(8, 32) phyCnt = phyCnt + 1 phyLight[phyCnt] = lightWorld.newCircle(x, y, cRadius) @@ -487,6 +513,11 @@ function love.keypressed(k, u) glowBlur = 0.0 end lightWorld.setGlowStrength(glowBlur) + elseif k == "f10" then + effectOn = effectOn + 1.0 + if effectOn > 4.0 then + effectOn = 0.0 + end elseif k == "f11" then physicWorld:destroy() lightWorld.clearBodys() diff --git a/postshader.lua b/postshader.lua index 81361c3..2a07d97 100644 --- a/postshader.lua +++ b/postshader.lua @@ -6,9 +6,14 @@ 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_FOUR_COLOR = love.graphics.newShader("shader/four_colors.glsl") +LOVE_POSTSHADER_MONOCHROM = love.graphics.newShader("shader/monochrom.glsl") +LOVE_POSTSHADER_SCANLINES = love.graphics.newShader("shader/scanlines.glsl") +LOVE_POSTSHADER_TILT_SHIFT = love.graphics.newShader("shader/tilt_shift.glsl") LOVE_POSTSHADER_BLURV:send("screen", {love.window.getWidth(), love.window.getHeight()}) LOVE_POSTSHADER_BLURH:send("screen", {love.window.getWidth(), love.window.getHeight()}) +LOVE_POSTSHADER_SCANLINES:send("screenHeight", {love.window.getWidth(), love.window.getHeight()}) love.postshader = {} @@ -25,12 +30,13 @@ love.postshader.addEffect = function(shader, ...) args = {...} LOVE_POSTSHADER_LAST_BUFFER = love.graphics.getCanvas() + love.graphics.setCanvas(LOVE_POSTSHADER_BUFFER_BACK) + love.graphics.setBlendMode("alpha") + 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") love.graphics.setShader(LOVE_POSTSHADER_BLURV) love.graphics.draw(LOVE_POSTSHADER_BUFFER_RENDER) @@ -53,8 +59,44 @@ love.postshader.addEffect = function(shader, ...) -- Blur Shader LOVE_POSTSHADER_BLURV:send("steps", args[1] or 2.0) LOVE_POSTSHADER_BLURH:send("steps", args[2] or 2.0) + + love.graphics.setShader(LOVE_POSTSHADER_BLURV) + love.graphics.draw(LOVE_POSTSHADER_BUFFER_RENDER) + + love.graphics.setShader(LOVE_POSTSHADER_BLURH) + love.graphics.draw(LOVE_POSTSHADER_BUFFER_BACK) + elseif shader == "chromatic" then + -- Chromatic 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) + elseif shader == "4colors" then + -- 4 Color Shader + for i = 1, 4 do + for k = 1, 3 do + args[i][k] = args[i][k] / 255.0 + end + end + LOVE_POSTSHADER_FOUR_COLOR:send("palette", args[1], args[2], args[3], args[4]) + love.graphics.setShader(LOVE_POSTSHADER_FOUR_COLOR) + love.graphics.draw(LOVE_POSTSHADER_BUFFER_RENDER) + elseif shader == "monochrom" then + -- Monochrom Shader + LOVE_POSTSHADER_MONOCHROM:send("time", love.timer.getTime()) + love.graphics.setShader(LOVE_POSTSHADER_MONOCHROM) + love.graphics.draw(LOVE_POSTSHADER_BUFFER_RENDER) + elseif shader == "scanlines" then + -- Scanlines Shader + LOVE_POSTSHADER_SCANLINES:send("time", love.timer.getTime()) + love.graphics.setShader(LOVE_POSTSHADER_SCANLINES) + love.graphics.draw(LOVE_POSTSHADER_BUFFER_RENDER) + elseif shader == "tiltshift" then + -- Blur Shader + LOVE_POSTSHADER_BLURV:send("steps", args[1] or 2.0) + LOVE_POSTSHADER_BLURH:send("steps", args[1] or 2.0) love.graphics.setShader(LOVE_POSTSHADER_BLURV) love.graphics.draw(LOVE_POSTSHADER_BUFFER_RENDER) @@ -62,21 +104,13 @@ love.postshader.addEffect = function(shader, ...) love.graphics.setShader(LOVE_POSTSHADER_BLURH) love.graphics.draw(LOVE_POSTSHADER_BUFFER_BACK) - love.graphics.setCanvas(LOVE_POSTSHADER_LAST_BUFFER) - love.graphics.setShader() - love.graphics.setColor(255, 255, 255) + LOVE_POSTSHADER_TILT_SHIFT:send("buffer", LOVE_POSTSHADER_BUFFER_RENDER) + love.graphics.setShader(LOVE_POSTSHADER_TILT_SHIFT) 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) + end + + if shader ~= "bloom" then 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) diff --git a/shader/four_colors.glsl b/shader/four_colors.glsl new file mode 100644 index 0000000..c68b1cf --- /dev/null +++ b/shader/four_colors.glsl @@ -0,0 +1,8 @@ +extern vec3 palette[4]; + +vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords){ + vec4 pixel = Texel(texture, texture_coords); + int index = int(min(0.9999, max(0.0001,(pixel.r + pixel.g + pixel.b) / 3.0)) * 4); + + return vec4(palette[index], 1.0); +} \ No newline at end of file diff --git a/shader/monochrom.glsl b/shader/monochrom.glsl new file mode 100644 index 0000000..43297bd --- /dev/null +++ b/shader/monochrom.glsl @@ -0,0 +1,11 @@ +extern float time = 0.0; + +float rand(vec2 position, float seed) { + return fract(sin(dot(position.xy,vec2(12.9898, 78.233))) * seed); +} + +vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords){ + vec4 pixel = Texel(texture, texture_coords); + + return vec4(vec3((pixel.r + pixel.g + pixel.b) / 3.0) + (rand(texture_coords, time) - 0.5) * 0.1, 1.0); +} \ No newline at end of file diff --git a/shader/poly_shadow.glsl b/shader/poly_shadow.glsl index eb0947e..ba8ae77 100644 --- a/shader/poly_shadow.glsl +++ b/shader/poly_shadow.glsl @@ -1,6 +1,6 @@ #define PI 3.1415926535897932384626433832795 -extern vec2 lightPosition; +extern vec3 lightPosition; extern vec3 lightColor; extern float lightRange; extern float lightSmooth; @@ -10,7 +10,7 @@ extern float lightAngle; vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords){ vec4 pixel = Texel(texture, texture_coords); - vec2 lightToPixel = pixel_coords - lightPosition; + vec3 lightToPixel = vec3(pixel_coords.x, pixel_coords.y, 0.0) - lightPosition; float distance = length(lightToPixel); float att = 1 - distance / lightRange; diff --git a/shader/refraction.glsl b/shader/refraction.glsl index 7dc534f..d9b3d23 100644 --- a/shader/refraction.glsl +++ b/shader/refraction.glsl @@ -6,9 +6,9 @@ extern float refractionStrength = 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.a > 0.0) { + if(normal.b > 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) { + if(normalOffset.b > 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); diff --git a/shader/scanlines.glsl b/shader/scanlines.glsl new file mode 100644 index 0000000..9fa370c --- /dev/null +++ b/shader/scanlines.glsl @@ -0,0 +1,31 @@ +extern vec2 screenHeight = vec2(800.0, 600.0); +extern float time = 0.0; + +vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords){ + vec2 pSize = 1.0 / screenHeight; + float brightness = 1.0; + float offsetX = sin(texture_coords.y * 10.0 + time * 2.0) * pSize.x; + + if(texture_coords.x < 0.5) { + if(texture_coords.y < 0.5) { + brightness = min(texture_coords.x * texture_coords.y * 100.0, 1.0); + } else { + brightness = min(texture_coords.x * (1.0 - texture_coords.y) * 100.0, 1.0); + } + } else { + if(texture_coords.y < 0.5) { + brightness = min((1.0 - texture_coords.x) * texture_coords.y * 100.0, 1.0); + } else { + brightness = min((1.0 - texture_coords.x) * (1.0 - texture_coords.y) * 100.0, 1.0); + } + } + float red = Texel(texture, vec2(texture_coords.x + offsetX, texture_coords.y + pSize.y * 0.5)).r; + float green = Texel(texture, vec2(texture_coords.x + offsetX, texture_coords.y - pSize.y * 0.5)).g; + float blue = Texel(texture, vec2(texture_coords.x + offsetX, texture_coords.y)).b; + + if(mod(texture_coords.y * screenHeight.y, 2.0) > 0.5) { + return vec4(vec3(red, green, blue) * brightness, 1.0); + } else { + return vec4(vec3(red * 0.75, green * 0.75, blue * 0.75) * brightness, 1.0); + } +} \ No newline at end of file diff --git a/shader/tilt_shift.glsl b/shader/tilt_shift.glsl new file mode 100644 index 0000000..d0df84f --- /dev/null +++ b/shader/tilt_shift.glsl @@ -0,0 +1,12 @@ +extern Image buffer; + +vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords){ + vec4 pixel = Texel(texture, texture_coords); + vec4 pixel2 = Texel(buffer, texture_coords); + + if(texture_coords.y > 0.5) { + return vec4(pixel.rgb * (texture_coords.y - 0.5) * 2.0 + pixel2.rgb * (1.0 - texture_coords.y) * 2.0, 1.0); + } else { + return vec4(pixel.rgb * (0.5 - texture_coords.y) * 2.0 + pixel2.rgb * texture_coords.y * 2.0, 1.0); + } +} \ No newline at end of file