Add reflection.

This commit is contained in:
Marcus Ihde 2014-03-17 04:32:42 +01:00
parent c8c7ec418a
commit bae4a0db4d
5 changed files with 109 additions and 7 deletions

BIN
gfx/water.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -7,6 +7,8 @@ LOVE_LIGHT_SHADOW_GEOMETRY = nil
LOVE_LIGHT_BLURV = love.graphics.newShader("shader/blurv.glsl") LOVE_LIGHT_BLURV = love.graphics.newShader("shader/blurv.glsl")
LOVE_LIGHT_BLURH = love.graphics.newShader("shader/blurh.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_X = 0
LOVE_LIGHT_TRANSLATE_Y = 0 LOVE_LIGHT_TRANSLATE_Y = 0
@ -33,6 +35,8 @@ function love.light.newWorld()
o.glowMap2 = love.graphics.newCanvas() o.glowMap2 = love.graphics.newCanvas()
o.refractionMap = love.graphics.newCanvas() o.refractionMap = love.graphics.newCanvas()
o.refractionMap2 = love.graphics.newCanvas() o.refractionMap2 = love.graphics.newCanvas()
o.reflectionMap = love.graphics.newCanvas()
o.reflectionMap2 = love.graphics.newCanvas()
o.glowBlur = 1.0 o.glowBlur = 1.0
o.isGlowBlur = false o.isGlowBlur = false
o.refractionStrength = 8.0 o.refractionStrength = 8.0
@ -41,6 +45,11 @@ function love.light.newWorld()
o.shader = love.graphics.newShader("shader/poly_shadow.glsl") o.shader = love.graphics.newShader("shader/poly_shadow.glsl")
o.normalShader = love.graphics.newShader("shader/normal.glsl") o.normalShader = love.graphics.newShader("shader/normal.glsl")
o.refractionShader = love.graphics.newShader("shader/refraction.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.changed = true
o.blur = 2.0 o.blur = 2.0
-- update -- update
@ -178,7 +187,6 @@ function love.light.newWorld()
end end
-- update pixel shadow -- update pixel shadow
love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
-- create normal map -- create normal map
@ -190,12 +198,10 @@ function love.light.newWorld()
if o.img[i].normal then if o.img[i].normal then
love.graphics.setColor(255, 255, 255) 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) 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
end end
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("alpha")
end end
o.pixelShadow2:clear() 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) 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
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 end
love.graphics.setShader() love.graphics.setShader()
@ -386,7 +421,23 @@ function love.light.newWorld()
o.refractionShader:send("refractionStrength", o.refractionStrength) o.refractionShader:send("refractionStrength", o.refractionStrength)
love.graphics.setShader(o.refractionShader) love.graphics.setShader(o.refractionShader)
love.graphics.draw(o.refractionMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) 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() love.graphics.setShader()
end end
end end
@ -449,6 +500,14 @@ function love.light.newWorld()
o.setRefractionStrength = function(strength) o.setRefractionStrength = function(strength)
o.refractionStrength = strength o.refractionStrength = strength
end 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 -- new rectangle
o.newRectangle = function(x, y, w, h) o.newRectangle = function(x, y, w, h)
return love.light.newRectangle(o, 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.glowBlue = 255
o.glowStrength = 0.0 o.glowStrength = 0.0
o.refractionStrength = 1.0 o.refractionStrength = 1.0
o.reflective = true
o.type = "image" o.type = "image"
p.changed = true p.changed = true
o.data = { o.data = {
@ -1215,6 +1275,7 @@ function love.light.newRefraction(p, normal, x, y)
o.normalWidth = normal:getWidth() o.normalWidth = normal:getWidth()
o.normalHeight = normal:getHeight() o.normalHeight = normal:getHeight()
o.strength = strength or 1.0 o.strength = strength or 1.0
o.reflective = true
o.type = "refraction" o.type = "refraction"
p.changed = true p.changed = true
-- set position -- set position

View File

@ -62,6 +62,7 @@ function love.load()
tile_normal = love.graphics.newImage("gfx/tile_normal.png") tile_normal = love.graphics.newImage("gfx/tile_normal.png")
tile_glow = love.graphics.newImage("gfx/tile_glow.png") tile_glow = love.graphics.newImage("gfx/tile_glow.png")
refraction_normal = love.graphics.newImage("gfx/refraction_normal.png") refraction_normal = love.graphics.newImage("gfx/refraction_normal.png")
water = love.graphics.newImage("gfx/water.png")
-- light world -- light world
lightRange = 400 lightRange = 400
@ -69,6 +70,7 @@ function love.load()
lightWorld = love.light.newWorld() lightWorld = love.light.newWorld()
lightWorld.setAmbientColor(15, 15, 31) lightWorld.setAmbientColor(15, 15, 31)
lightWorld.setRefractionStrength(16.0) lightWorld.setRefractionStrength(16.0)
lightWorld.setReflectionVisibility(0.75)
mouseLight = lightWorld.newLight(0, 0, 255, 127, 63, lightRange) mouseLight = lightWorld.newLight(0, 0, 255, 127, 63, lightRange)
mouseLight.setGlowStrength(0.3) mouseLight.setGlowStrength(0.3)
mouseLight.setSmooth(lightSmooth) mouseLight.setSmooth(lightSmooth)
@ -216,6 +218,16 @@ function love.draw()
end end
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 -- draw lightmap shadows
if lightOn and not normalOn then if lightOn and not normalOn then
lightWorld.drawShadow() lightWorld.drawShadow()
@ -236,6 +248,7 @@ function love.draw()
lightWorld.drawShine() lightWorld.drawShine()
end end
love.graphics.setBlendMode("alpha")
for i = 1, phyCnt do for i = 1, phyCnt do
if phyLight[i].getType() == "image" then if phyLight[i].getType() == "image" then
if not normalOn then if not normalOn then
@ -259,6 +272,9 @@ function love.draw()
lightWorld.drawGlow() lightWorld.drawGlow()
end end
-- draw reflection
lightWorld.drawReflection()
-- draw refraction -- draw refraction
lightWorld.drawRefraction() lightWorld.drawRefraction()
@ -498,6 +514,7 @@ function love.keypressed(k, u)
phyLight[phyCnt].setHeightMap(tile_normal, 2.0) phyLight[phyCnt].setHeightMap(tile_normal, 2.0)
phyLight[phyCnt].setGlowMap(tile_glow) phyLight[phyCnt].setGlowMap(tile_glow)
phyLight[phyCnt].setShadow(false) phyLight[phyCnt].setShadow(false)
phyLight[phyCnt].reflective = false
phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 64, 64) phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 64, 64)
phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt])
@ -535,7 +552,7 @@ function love.keypressed(k, u)
phyFixture[phyCnt]:setRestitution(0.5) phyFixture[phyCnt]:setRestitution(0.5)
elseif k == "0" then elseif k == "0" then
phyCnt = phyCnt + 1 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") --phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic")
--phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, phyLight[phyCnt].getWidth(), phyLight[phyCnt].getHeight()) --phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, phyLight[phyCnt].getWidth(), phyLight[phyCnt].getHeight())
--phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) --phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt])

24
shader/reflection.glsl Normal file
View File

@ -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);
}
}

View File

@ -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) { vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {
vec2 pSize = vec2(1.0 / screen.x, 1.0 / screen.y); vec2 pSize = vec2(1.0 / screen.x, 1.0 / screen.y);
vec4 normal = Texel(texture, texture_coords); 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); 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 { } else {
return vec4(0.0); return vec4(0.0);