From bae4a0db4d8e0e5f0a97a1b10d0ea7578e936f32 Mon Sep 17 00:00:00 2001 From: Marcus Ihde Date: Mon, 17 Mar 2014 04:32:42 +0100 Subject: [PATCH] Add reflection. --- gfx/water.png | Bin 0 -> 11007 bytes light.lua | 71 ++++++++++++++++++++++++++++++++++++++--- main.lua | 19 ++++++++++- shader/reflection.glsl | 24 ++++++++++++++ shader/refraction.glsl | 2 +- 5 files changed, 109 insertions(+), 7 deletions(-) create mode 100644 gfx/water.png create mode 100644 shader/reflection.glsl diff --git a/gfx/water.png b/gfx/water.png new file mode 100644 index 0000000000000000000000000000000000000000..c61b26b938d9594df03961b3762c42ed80bc8803 GIT binary patch literal 11007 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 literal 0 HcmV?d00001 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);