diff --git a/gfx/water.png b/gfx/water.png new file mode 100644 index 0000000..c61b26b Binary files /dev/null and b/gfx/water.png differ diff --git a/light.lua b/light.lua index ae646fa..648e3fe 100644 --- a/light.lua +++ b/light.lua @@ -7,6 +7,8 @@ LOVE_LIGHT_SHADOW_GEOMETRY = nil LOVE_LIGHT_BLURV = love.graphics.newShader("shader/blurv.glsl") LOVE_LIGHT_BLURH = love.graphics.newShader("shader/blurh.glsl") +LOVE_LIGHT_BLURV:send("screen", {love.window.getWidth(), love.window.getHeight()}) +LOVE_LIGHT_BLURH:send("screen", {love.window.getWidth(), love.window.getHeight()}) LOVE_LIGHT_TRANSLATE_X = 0 LOVE_LIGHT_TRANSLATE_Y = 0 @@ -33,6 +35,8 @@ function love.light.newWorld() o.glowMap2 = love.graphics.newCanvas() o.refractionMap = love.graphics.newCanvas() o.refractionMap2 = love.graphics.newCanvas() + o.reflectionMap = love.graphics.newCanvas() + o.reflectionMap2 = love.graphics.newCanvas() o.glowBlur = 1.0 o.isGlowBlur = false o.refractionStrength = 8.0 @@ -41,6 +45,11 @@ function love.light.newWorld() o.shader = love.graphics.newShader("shader/poly_shadow.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()}) + o.reflectionShader = love.graphics.newShader("shader/reflection.glsl") + o.reflectionShader:send("screen", {love.window.getWidth(), love.window.getHeight()}) + o.reflectionStrength = 16.0 + o.reflectionVisibility = 1.0 o.changed = true o.blur = 2.0 -- update @@ -178,7 +187,6 @@ function love.light.newWorld() end -- update pixel shadow - love.graphics.setColor(255, 255, 255) love.graphics.setBlendMode("alpha") -- create normal map @@ -190,12 +198,10 @@ function love.light.newWorld() if o.img[i].normal then love.graphics.setColor(255, 255, 255) love.graphics.draw(o.img[i].normal, 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, 0) - love.graphics.rectangle("fill", o.img[i].x - o.img[i].ox2 + LOVE_LIGHT_TRANSLATE_X, o.img[i].y - o.img[i].oy2, o.img[i].imgWidth, o.img[i].imgHeight + LOVE_LIGHT_TRANSLATE_Y) end end love.graphics.setColor(255, 255, 255) + love.graphics.setBlendMode("alpha") end o.pixelShadow2:clear() @@ -275,6 +281,35 @@ function love.light.newWorld() love.graphics.rectangle("fill", o.refraction[i].x - o.refraction[i].ox + LOVE_LIGHT_TRANSLATE_X, o.refraction[i].y - o.refraction[i].oy, o.refraction[i].normalWidth, o.refraction[i].normalHeight + LOVE_LIGHT_TRANSLATE_Y) end end + for i = 1, #o.img do + if 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 + end + end + + -- create reflection map + if o.changed then + o.reflectionMap:clear(0, 0, 0) + love.graphics.setCanvas(o.reflectionMap) + for i = 1, #o.refraction do + if o.refraction[i].reflective and o.refraction[i].normal then + love.graphics.setColor(255, 0, 0) + else + love.graphics.setColor(0, 0, 0) + end + o.refraction[i].mesh:setVertices(o.refraction[i].vertices) + love.graphics.draw(o.refraction[i].mesh, o.refraction[i].x - o.refraction[i].ox + LOVE_LIGHT_TRANSLATE_X, o.refraction[i].y - o.refraction[i].oy + LOVE_LIGHT_TRANSLATE_Y) + end + for i = 1, #o.img do + if o.img[i].reflective and o.img[i].img then + love.graphics.setColor(0, 255, 0) + else + 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 end love.graphics.setShader() @@ -386,7 +421,23 @@ function love.light.newWorld() o.refractionShader:send("refractionStrength", o.refractionStrength) love.graphics.setShader(o.refractionShader) love.graphics.draw(o.refractionMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) - --love.graphics.rectangle("fill", LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y, love.graphics.getWidth(), love.graphics.getHeight()) + love.graphics.setShader() + end + end + -- draw reflection + o.drawReflection = function() + LOVE_LIGHT_LAST_BUFFER = love.graphics.getCanvas() + if LOVE_LIGHT_LAST_BUFFER then + love.graphics.setColor(255, 255, 255) + love.graphics.setBlendMode("alpha") + love.graphics.setCanvas(o.reflectionMap2) + love.graphics.draw(LOVE_LIGHT_LAST_BUFFER, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setCanvas(LOVE_LIGHT_LAST_BUFFER) + o.reflectionShader:send("backBuffer", o.reflectionMap2) + o.reflectionShader:send("reflectionStrength", o.reflectionStrength) + o.reflectionShader:send("reflectionVisibility", o.reflectionVisibility) + love.graphics.setShader(o.reflectionShader) + love.graphics.draw(o.reflectionMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) love.graphics.setShader() end end @@ -449,6 +500,14 @@ function love.light.newWorld() o.setRefractionStrength = function(strength) o.refractionStrength = strength end + -- set reflection strength + o.setReflectionStrength = function(strength) + o.reflectionStrength = strength + end + -- set reflection visibility + o.setReflectionVisibility = function(visibility) + o.reflectionVisibility = visibility + end -- new rectangle o.newRectangle = function(x, y, w, h) return love.light.newRectangle(o, x, y, w, h) @@ -986,6 +1045,7 @@ function love.light.newImage(p, img, x, y, width, height, ox, oy) o.glowBlue = 255 o.glowStrength = 0.0 o.refractionStrength = 1.0 + o.reflective = true o.type = "image" p.changed = true o.data = { @@ -1215,6 +1275,7 @@ function love.light.newRefraction(p, normal, x, y) o.normalWidth = normal:getWidth() o.normalHeight = normal:getHeight() o.strength = strength or 1.0 + o.reflective = true o.type = "refraction" p.changed = true -- set position diff --git a/main.lua b/main.lua index c2b0cfc..cec1087 100644 --- a/main.lua +++ b/main.lua @@ -62,6 +62,7 @@ function love.load() tile_normal = love.graphics.newImage("gfx/tile_normal.png") 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") -- light world lightRange = 400 @@ -69,6 +70,7 @@ function love.load() lightWorld = love.light.newWorld() lightWorld.setAmbientColor(15, 15, 31) lightWorld.setRefractionStrength(16.0) + lightWorld.setReflectionVisibility(0.75) mouseLight = lightWorld.newLight(0, 0, 255, 127, 63, lightRange) mouseLight.setGlowStrength(0.3) mouseLight.setSmooth(lightSmooth) @@ -216,6 +218,16 @@ 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) + end + end + end + -- draw lightmap shadows if lightOn and not normalOn then lightWorld.drawShadow() @@ -236,6 +248,7 @@ function love.draw() lightWorld.drawShine() end + love.graphics.setBlendMode("alpha") for i = 1, phyCnt do if phyLight[i].getType() == "image" then if not normalOn then @@ -259,6 +272,9 @@ function love.draw() lightWorld.drawGlow() end + -- draw reflection + lightWorld.drawReflection() + -- draw refraction lightWorld.drawRefraction() @@ -498,6 +514,7 @@ function love.keypressed(k, u) phyLight[phyCnt].setHeightMap(tile_normal, 2.0) phyLight[phyCnt].setGlowMap(tile_glow) phyLight[phyCnt].setShadow(false) + phyLight[phyCnt].reflective = false phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 64, 64) phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) @@ -535,7 +552,7 @@ function love.keypressed(k, u) phyFixture[phyCnt]:setRestitution(0.5) elseif k == "0" then phyCnt = phyCnt + 1 - phyLight[phyCnt] = lightWorld.newRefraction(refraction_normal, mx, my, 1.0) + 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]) diff --git a/shader/reflection.glsl b/shader/reflection.glsl new file mode 100644 index 0000000..edf662f --- /dev/null +++ b/shader/reflection.glsl @@ -0,0 +1,24 @@ +extern Image backBuffer; + +extern vec2 screen = vec2(800.0, 600.0); +extern float reflectionStrength; +extern float reflectionVisibility; + +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 && normal.r > 0.0) { + vec3 pColor = Texel(backBuffer, texture_coords).rgb; + vec4 pColor2; + for(int i = 0; i < reflectionStrength; i++) { + pColor2 = Texel(texture, vec2(texture_coords.x, texture_coords.y + pSize.y * i)); + if(pColor2.a > 0.0 && pColor2.g > 0.0) { + vec3 rColor = Texel(backBuffer, vec2(texture_coords.x, texture_coords.y + pSize.y * i * 2.0)).rgb; + return vec4(rColor, (1.0 - i / reflectionStrength) * reflectionVisibility); + } + } + return vec4(0.0); + } else { + return vec4(0.0); + } +} \ No newline at end of file diff --git a/shader/refraction.glsl b/shader/refraction.glsl index 3e0a52b..c6b4d24 100644 --- a/shader/refraction.glsl +++ b/shader/refraction.glsl @@ -7,7 +7,7 @@ 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.a > 0.0) { + 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); } else { return vec4(0.0);