From 249fff23ae84080791601b7e6d50aac8a03bf999 Mon Sep 17 00:00:00 2001 From: Marcus Ihde Date: Sat, 8 Mar 2014 20:48:51 +0100 Subject: [PATCH] Add heighmap converter, better normal map shader. --- gfx/blopp.png | Bin 0 -> 1582 bytes gfx/normal_palett.png | Bin 9756 -> 0 bytes gfx/normal_palette.png | Bin 0 -> 2192 bytes gfx/tile.png | Bin 0 -> 1074 bytes gfx/tile_glow.png | Bin 0 -> 1018 bytes gfx/tile_normal.png | Bin 0 -> 1012 bytes light.lua | 271 +++++++++++++++++++++++++--------- main.lua | 65 ++++++-- shader/normal.glsl | 33 +++++ shader/pixel_self_shadow.glsl | 24 --- 10 files changed, 289 insertions(+), 104 deletions(-) create mode 100644 gfx/blopp.png delete mode 100644 gfx/normal_palett.png create mode 100644 gfx/normal_palette.png create mode 100644 gfx/tile.png create mode 100644 gfx/tile_glow.png create mode 100644 gfx/tile_normal.png create mode 100644 shader/normal.glsl delete mode 100644 shader/pixel_self_shadow.glsl diff --git a/gfx/blopp.png b/gfx/blopp.png new file mode 100644 index 0000000000000000000000000000000000000000..b0ac08b53c28366c8316854f0367bda66affe4c3 GIT binary patch literal 1582 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 diff --git a/gfx/normal_palette.png b/gfx/normal_palette.png new file mode 100644 index 0000000000000000000000000000000000000000..5eec06f052d7d8d2db1d2d419a426b45434721cb GIT binary patch literal 2192 zcmeHH|65aK6hH61yKL;j1W`7S+{Kt*&;U~w2FZpp(D?;P3)Em55?MMF zF25wE#O#YvJ&!H9kAfCm%FLxHnKhUqGj$geg2B)LXlRw_ee;=Zu;Q*c>$Q`Q_~j%Y*h)|s{lh@0dE6ri2?Y- z0PtiDfZVt{`+FS#32BR#C#zIgt+vT@SfOY23RbV@1*5j9^}HT1mfn_Gu@J&WBsmKRd=Hk%q_FK%)-VK>Y2 z!WO%mn%tNb${mge-oG5rvJSy_V4KY*T;t(-ID!9X0-4Nku5glXerjd`06q4BqDvhW z_l00cVRA;{)5hGw;x(JsLE4%ZHx@=MNnXwr&5DYRihCj+KL;SXwP3z>c}Z4JTjsMt z+JJ3qCheY2idv{i$3D!<==WCE{@M{+``NW4>yOliT|Cg-UotRv=+Yi|MR~RK^%r*4 z-fJ0}5ua@;Xt_|FP}$u+0o@>O5Id;Jd%ifqy`=nsVnhY8NL1(LdG z?qsNSz27KY`Kky(Tv9ajoU0?Q6n&z^x2A|YbNE9Z|HA`BLgJhNl4$wthJ90OFESAB zi{#IDo}H1O)uxfAdTtq8O0|sWqv1$R5gEd?+tFqskZGm z?73qn9>1r7vxEESoQ-SanJacO{hnpKxwjZ1L>q9K_vX!KivH|%hfX%GrI`Zn((ZQ# zjlDe!5^1@7o#yw!Q^zMd$G6<5M`7m1t?0z72Tb%1Tz;He)@uKnnwanXQMCW#&bOyI zyXr%o`^GNBqmMyj@?chLyH+UsQ;*Ix=}Uk|+V{XW~erABeV};O>fv3~eLs8AE0K0CuGxm<-6Slv!oa zrVOyU=$&{|)qlmCQx)Id{`ZE{qjcqzmnvdco%(R}KwnT;ruR=IOZNEG9DhoRwX=6* zfwGs-%qxb^i!-#WnMnD)-E#x>Kj zSy*QwKN>kG9~aTQQ`P|E>fyj#IK=p95>G(Ic z#3oP5rh#vcp$dI)iA>)16z98brE^Y};T}v^O8V_yl^ z9Jm>51>EB4SgHU?I-Hxuy#*Q(a(b2(ndX*CEuGEW%hT)qW6FIwI+A=jTa+i-f{sR$ z7E2_IB;laTqS@usIB6tNmhBf~+KM-1%Rn0ox2HqHdT`hwcVDofe7s?zB&Y85u9g({ ziZR@wpp$U)=rB@f$KWy}gy$i3Hgftt39iq5yp#2IQfeV>wMoGjfqDXa9sr@SC}$^4^92Gc*{c#%&4 literal 0 HcmV?d00001 diff --git a/gfx/tile.png b/gfx/tile.png new file mode 100644 index 0000000000000000000000000000000000000000..1624730ee7e946d66d35cfe0ea33fe0295605831 GIT binary patch literal 1074 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!SkfJR9T^zbpD<_bdda}R%n;xc z;;L59P|v_nUtiDgUy)(vOolUO82zV3Vm|Hi*0u?Rx zba4!caDN*X&2>P5r|g#pmH}q=Y`HAm5iio6gnC{nS@s=qS7uRMvpQ|^-{Vbe za||XYq$RwOF_>x=lzxk8O7N>SM;2=y+{Re>pT&~>$zP2HoFRrLXCDZhU;A^dLyx^y z(?7|Ik0D}5D)RN3V{N9g8rGRlKUm3B`QPv9CWcD;*ae)w${T|n>~)w0UeujZoZ?+7 kbi~3~LaCYY)tQJL3@kG$In9h5#X-^N>FVdQ&MBb@06V34n*aa+ literal 0 HcmV?d00001 diff --git a/gfx/tile_glow.png b/gfx/tile_glow.png new file mode 100644 index 0000000000000000000000000000000000000000..362af4a6aa8269920f5fe59370ecce6be282ba16 GIT binary patch literal 1018 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!SkfJR9T^zbpD<_bdda}R%n;xc z;tCX3t7oVOQvVehX3k_dbB5vn|NlVlC>RZa5fB1FQcLCly~$bN5n0T@z_$;C8DBYV zJOC7wEOCt}3C>R|DNig)We7;j%q!9Ja}7}_GuAWJvoN=Ahy^Oj_H=O!iEw{A!J6xU z0grRMo$tH)$9{5;6dx>m5TtS;jr(Pz3X_rolhOxgrnQZg=Icca^vjPk{tR%BSXca` z{z-os@45~5_)fTAI$SjO@PFI-E!hU@Gs>T4v3@Qpm-%3+q6O97a)9@j3|r+Hrv56R OwG5uFelF{r5}E)(B`cTA-k0iEBhjaDG}z zd16s2LqK9?UWuNcYluRbv7V`(g}HS@EKpIZr;B4qg!|iRfm{p<9L|@2%Udme!Qf}` z=Ba6#RpHm7ALW-8{-?*3%@%S-BT>E>G&{#*(Soe zMaJf-n7V&5NtnXs}tAe7()78&qol`;+05g(O AJpcdz literal 0 HcmV?d00001 diff --git a/light.lua b/light.lua index 6db3fc3..8ab5551 100644 --- a/light.lua +++ b/light.lua @@ -7,6 +7,11 @@ LOVE_LIGHT_LAST_BUFFER = nil LOVE_LIGHT_BLURV = love.graphics.newShader("shader/blurv.glsl") LOVE_LIGHT_BLURH = love.graphics.newShader("shader/blurh.glsl") +LOVE_LIGHT_TRANSLATE_X = 0 +LOVE_LIGHT_TRANSLATE_Y = 0 +LOVE_LIGHT_TRANSLATE_X_OLD = 0 +LOVE_LIGHT_TRANSLATE_Y_OLD = 0 + love.light = {} -- light world @@ -27,19 +32,26 @@ function love.light.newWorld() o.pixelShadow = love.graphics.newCanvas() o.pixelShadow2 = love.graphics.newCanvas() o.shader = love.graphics.newShader("shader/poly_shadow.glsl") - o.shader2 = love.graphics.newShader("shader/pixel_self_shadow.glsl") + o.normalShader = love.graphics.newShader("shader/normal.glsl") o.changed = true o.blur = 2.0 -- update o.update = function() LOVE_LIGHT_LAST_BUFFER = love.graphics.getCanvas() love.graphics.setShader(o.shader) + + if LOVE_LIGHT_TRANSLATE_X ~= LOVE_LIGHT_TRANSLATE_X_OLD or LOVE_LIGHT_TRANSLATE_Y ~= LOVE_LIGHT_TRANSLATE_Y_OLD then + LOVE_LIGHT_TRANSLATE_X_OLD = LOVE_LIGHT_TRANSLATE_X + LOVE_LIGHT_TRANSLATE_Y_OLD = LOVE_LIGHT_TRANSLATE_Y + o.changed = true + end + if o.changed then love.graphics.setCanvas(o.shadow) o.shadow:clear(unpack(o.ambient)) love.graphics.setBlendMode("additive") else - love.graphics.setColor(255,255,255) + love.graphics.setColor(255, 255, 255) love.graphics.setBlendMode("alpha") end @@ -49,29 +61,15 @@ function love.light.newWorld() LOVE_LIGHT_IMAGE = o.img for i = 1, #o.lights do if o.lights[i].changed or o.changed then - local curLightX = o.lights[i].x - local curLightY = o.lights[i].y - local curLightRange = o.lights[i].range - local curLightColor = { - o.lights[i].red / 255.0, - o.lights[i].green / 255.0, - o.lights[i].blue / 255.0 - } - local curLightSmooth = o.lights[i].smooth - local curLightGlow = { - 1.0 - o.lights[i].glowSize, - o.lights[i].glowStrength - } - - if curLightX + curLightRange > 0 and curLightX - curLightRange < love.graphics.getWidth() - and curLightY + curLightRange > 0 and curLightY - curLightRange < love.graphics.getHeight() + if o.lights[i].x + o.lights[i].range > LOVE_LIGHT_TRANSLATE_X and o.lights[i].x - o.lights[i].range < love.graphics.getWidth() + LOVE_LIGHT_TRANSLATE_X + and o.lights[i].y + o.lights[i].range > LOVE_LIGHT_TRANSLATE_Y and o.lights[i].y - o.lights[i].range < love.graphics.getHeight() + LOVE_LIGHT_TRANSLATE_Y then - local lightposrange = {curLightX, love.graphics.getHeight() - curLightY, curLightRange} + local lightposrange = {o.lights[i].x, love.graphics.getHeight() - o.lights[i].y, o.lights[i].range} LOVE_LIGHT_CURRENT = o.lights[i] - o.shader:send("lightPositionRange", lightposrange) - o.shader:send("lightColor", curLightColor) - o.shader:send("smooth", curLightSmooth) - o.shader:send("glow", curLightGlow) + o.shader:send("lightPositionRange", {o.lights[i].x - LOVE_LIGHT_TRANSLATE_X, love.graphics.getHeight() - (o.lights[i].y - LOVE_LIGHT_TRANSLATE_Y), 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("smooth", o.lights[i].smooth) + o.shader:send("glow", {1.0 - o.lights[i].glowSize, o.lights[i].glowStrength}) if o.changed then love.graphics.setCanvas(o.shadow) @@ -83,14 +81,14 @@ function love.light.newWorld() -- draw shadow love.graphics.setInvertedStencil(shadowStencil) love.graphics.setBlendMode("additive") - love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) + love.graphics.rectangle("fill", LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y, love.graphics.getWidth(), love.graphics.getHeight()) -- draw shine love.graphics.setCanvas(o.lights[i].shine) o.lights[i].shine:clear(255, 255, 255) love.graphics.setBlendMode("alpha") love.graphics.setStencil(polyStencil) - love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) + love.graphics.rectangle("fill", LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y, love.graphics.getWidth(), love.graphics.getHeight()) lightsOnScreen = lightsOnScreen + 1 @@ -110,12 +108,12 @@ function love.light.newWorld() love.graphics.setStencil() love.graphics.setColor(unpack(o.ambient)) love.graphics.setBlendMode("alpha") - love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) + love.graphics.rectangle("fill", LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y, love.graphics.getWidth(), love.graphics.getHeight()) love.graphics.setColor(255, 255, 255) love.graphics.setBlendMode("additive") for i = 1, #o.lights do if o.lights[i].visible then - love.graphics.draw(o.lights[i].shadow) + love.graphics.draw(o.lights[i].shadow, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) end end o.isShadowBlur = false @@ -130,7 +128,7 @@ function love.light.newWorld() love.graphics.setBlendMode("additive") for i = 1, #o.lights do if o.lights[i].visible then - love.graphics.draw(o.lights[i].shine) + love.graphics.draw(o.lights[i].shine, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) end end @@ -148,10 +146,11 @@ function love.light.newWorld() love.graphics.setColor(255, 255, 255) love.graphics.draw(o.img[i].normal, o.img[i].x - o.img[i].ox2, o.img[i].y - o.img[i].oy2) else - love.graphics.setColor(127, 127, 255) + love.graphics.setColor(0, 0, 0, 0) love.graphics.rectangle("fill", o.img[i].x - o.img[i].ox2, o.img[i].y - o.img[i].oy2, o.img[i].imgWidth, o.img[i].imgHeight) end end + love.graphics.setColor(255, 255, 255) end o.pixelShadow2:clear() @@ -159,24 +158,15 @@ function love.light.newWorld() love.graphics.setBlendMode("additive") love.graphics.setShader(o.shader2) - local curLightAmbient = { - o.ambient[1] / 255.0, - o.ambient[2] / 255.0, - o.ambient[3] / 255.0 - } for i = 1, #o.lights do if o.lights[i].visible then - local curLightColor = { - o.lights[i].red / 255.0, - o.lights[i].green / 255.0, - o.lights[i].blue / 255.0 - } - o.shader2:send("lightPosition", {o.lights[i].x, love.graphics.getHeight() - o.lights[i].y, 16}) - o.shader2:send("lightRange", {o.lights[i].range}) - o.shader2:send("lightColor", curLightColor) - o.shader2:send("lightAmbient", curLightAmbient) - o.shader2:send("lightSmooth", {o.lights[i].smooth}) - love.graphics.draw(o.normalMap) + o.normalShader:send('screenResolution', {love.graphics.getWidth(), love.graphics.getHeight()}) + o.normalShader:send('lightColor', {o.lights[i].red / 255.0, o.lights[i].green / 255.0, o.lights[i].blue / 255.0}) + o.normalShader:send('lightPosition',{o.lights[i].x, love.graphics.getHeight() - o.lights[i].y, o.lights[i].z / 255.0}) + o.normalShader:send('lightRange',{o.lights[i].range}) + o.normalShader:send("lightSmooth", o.lights[i].smooth) + love.graphics.setShader(o.normalShader) + love.graphics.draw(o.normalMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) end end @@ -184,7 +174,11 @@ function love.light.newWorld() o.pixelShadow:clear(255, 255, 255) love.graphics.setCanvas(o.pixelShadow) love.graphics.setBlendMode("alpha") - love.graphics.draw(o.pixelShadow2) + love.graphics.draw(o.pixelShadow2, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) + love.graphics.setBlendMode("additive") + love.graphics.setColor({o.ambient[1], o.ambient[2], o.ambient[3]}) + love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) + love.graphics.setBlendMode("alpha") -- create glow map if o.changed then @@ -192,7 +186,11 @@ function love.light.newWorld() love.graphics.setCanvas(o.glowMap) for i = 1, #o.img do if o.img[i].glow then + love.graphics.setColor(255, 255, 255) love.graphics.draw(o.img[i].glow, o.img[i].x - o.img[i].ox2, o.img[i].y - o.img[i].oy2) + else + love.graphics.setColor(0, 0, 0) + love.graphics.draw(o.img[i].img, o.img[i].x - o.img[i].ox2, o.img[i].y - o.img[i].oy2) end end o.isGlowBlur = false @@ -215,19 +213,19 @@ function love.light.newWorld() love.graphics.setBlendMode("alpha") love.graphics.setCanvas(o.shadow2) love.graphics.setShader(LOVE_LIGHT_BLURV) - love.graphics.draw(o.shadow) + love.graphics.draw(o.shadow, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) love.graphics.setCanvas(o.shadow) love.graphics.setShader(LOVE_LIGHT_BLURH) - love.graphics.draw(o.shadow2) + love.graphics.draw(o.shadow2, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) love.graphics.setCanvas(LOVE_LIGHT_LAST_BUFFER) love.graphics.setBlendMode("multiplicative") love.graphics.setShader() - love.graphics.draw(o.shadow) + love.graphics.draw(o.shadow, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) love.graphics.setBlendMode("alpha") else love.graphics.setBlendMode("multiplicative") love.graphics.setShader() - love.graphics.draw(o.shadow) + love.graphics.draw(o.shadow, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) love.graphics.setBlendMode("alpha") end end @@ -236,7 +234,7 @@ function love.light.newWorld() love.graphics.setColor(255, 255, 255) love.graphics.setBlendMode("multiplicative") love.graphics.setShader() - love.graphics.draw(o.shine) + love.graphics.draw(o.shine, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) love.graphics.setBlendMode("alpha") end -- draw pixel shadow @@ -244,7 +242,7 @@ function love.light.newWorld() love.graphics.setColor(255, 255, 255) love.graphics.setBlendMode("multiplicative") love.graphics.setShader() - love.graphics.draw(o.pixelShadow) + love.graphics.draw(o.pixelShadow, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) love.graphics.setBlendMode("alpha") end -- draw glow @@ -253,7 +251,7 @@ function love.light.newWorld() if o.isGlowBlur then love.graphics.setBlendMode("additive") love.graphics.setShader() - love.graphics.draw(o.glowMap) + love.graphics.draw(o.glowMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) love.graphics.setBlendMode("alpha") else LOVE_LIGHT_BLURV:send("steps", 1.0) @@ -262,14 +260,14 @@ function love.light.newWorld() love.graphics.setBlendMode("alpha") love.graphics.setCanvas(o.glowMap2) love.graphics.setShader(LOVE_LIGHT_BLURV) - love.graphics.draw(o.glowMap) + love.graphics.draw(o.glowMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) love.graphics.setCanvas(o.glowMap) love.graphics.setShader(LOVE_LIGHT_BLURH) - love.graphics.draw(o.glowMap2) + love.graphics.draw(o.glowMap2, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) love.graphics.setCanvas(LOVE_LIGHT_LAST_BUFFER) love.graphics.setBlendMode("additive") love.graphics.setShader() - love.graphics.draw(o.glowMap) + love.graphics.draw(o.glowMap, LOVE_LIGHT_TRANSLATE_X, LOVE_LIGHT_TRANSLATE_Y) love.graphics.setBlendMode("alpha") o.isGlowBlur = true @@ -293,6 +291,11 @@ function love.light.newWorld() o.img = {} o.changed = true end + -- set offset + o.setTranslation = function(translateX, translateY) + LOVE_LIGHT_TRANSLATE_X = translateX + LOVE_LIGHT_TRANSLATE_Y = translateY + end -- set ambient color o.setAmbientColor = function(red, green, blue) o.ambient = {red, green, blue} @@ -389,7 +392,7 @@ function love.light.newLight(p, x, y, red, green, blue, range) o.shine = love.graphics.newCanvas() o.x = x o.y = y - o.z = 1 + o.z = 15 o.red = red o.green = green o.blue = blue @@ -478,6 +481,7 @@ function love.light.newRectangle(p, x, y, width, height) o.ox = o.width / 2 o.oy = o.height / 2 o.shine = true + o.type = "rectangle" p.changed = true o.data = { o.x - o.ox, @@ -564,7 +568,7 @@ function love.light.newRectangle(p, x, y, width, height) end -- get type o.getType = function() - return "rectangle" + return o.type end return o @@ -579,6 +583,7 @@ function love.light.newCircle(p, x, y, radius) o.y = y or 0 o.radius = radius or 200 o.shine = true + o.type = "circle" p.changed = true -- set position o.setPosition = function(x, y) @@ -633,7 +638,7 @@ function love.light.newCircle(p, x, y, radius) end -- get type o.getType = function() - return "circle" + return o.type end return o @@ -645,11 +650,12 @@ function love.light.newPolygon(p, ...) p.poly[#p.poly + 1] = o o.id = #p.poly o.shine = true + o.type = "polygon" p.changed = true if ... then o.data = {...} else - o.data = {0,0,0,0,0,0} + o.data = {0, 0, 0, 0, 0, 0} end -- set polygon data o.setPoints = function(...) @@ -672,7 +678,7 @@ function love.light.newPolygon(p, ...) end -- get type o.getType = function() - return "polygon" + return o.type end return o @@ -698,6 +704,7 @@ function love.light.newImage(p, img, x, y, width, height, ox, oy) o.imgWidth = img:getWidth() o.imgHeight = img:getHeight() o.shine = true + o.type = "image" p.changed = true o.data = { o.x - o.ox, @@ -786,13 +793,90 @@ function love.light.newImage(p, img, x, y, width, height, ox, oy) o.setNormalMap = function(normal) o.normal = normal end + -- set height map + o.setHeightMap = function(heightMap, strength) + o.normal = HeightMapToNormalMap(heightMap, strength) + end + -- generate flat normal map + o.generateNormalMapFlat = function(mode) + local imgData = o.img:getData() + local imgNormalData = love.image.newImageData(o.imgWidth, o.imgHeight) + local color + + if mode == "top" then + color = {127, 127, 255} + elseif mode == "front" then + color = {127, 255, 127} + elseif mode == "back" then + color = {127, 0, 127} + elseif mode == "left" then + color = {31, 255, 223} + elseif mode == "right" then + color = {223, 223, 127} + end + + for i = 0, o.imgHeight - 1 do + for k = 0, o.imgWidth - 1 do + local r, g, b, a = imgData:getPixel(k, i) + if a > 0 then + imgNormalData:setPixel(k, i, color[1], color[2], color[3], 255) + end + end + end + + o.normal = love.graphics.newImage(imgNormalData) + end + -- generate faded normal map + o.generateNormalMapFade = function(horizontalFade, verticalFade) + local imgData = o.img:getData() + local imgNormalData = love.image.newImageData(o.imgWidth, o.imgHeight) + local dx = 255.0 / o.imgWidth + local dy = 255.0 / o.imgHeight + local nx + local ny + local nz + + for i = 0, o.imgWidth - 1 do + for k = 0, o.imgHeight - 1 do + local r, g, b, a = imgData:getPixel(i, k) + if a > 0 then + if horizontalFade == "fade" then + nx = i * dx + elseif horizontalFade == "inverse" then + nx = 255 - i * dx + else + nx = 127 + end + + if verticalFade == "fade" then + ny = 127 + k * dy * 0.5 + nz = 255 - k * dy * 0.5 + elseif verticalFade == "inverse" then + ny = 127 - k * dy * 0.5 + nz = 127 - k * dy * 0.25 + else + ny = 255 + nz = 127 + end + + imgNormalData:setPixel(i, k, nx, ny, nz, 255) + end + end + end + + o.normal = love.graphics.newImage(imgNormalData) + end + -- generate normal map + o.generateNormalMap = function(strength) + o.normal = HeightMapToNormalMap(o.img, strength) + end -- set normal o.setGlowMap = function(glow) o.glow = glow end -- get type o.getType = function() - return "image" + return o.type end return o @@ -854,8 +938,8 @@ function calculateShadows(lightsource, geometry, circle, image) curShadowGeometry[8] = curPolygon[nextIndex*2] local lightVecBackFront = normalize({curPolygon[nextIndex*2-1] - lightsource.x, curPolygon[nextIndex*2] - lightsource.y}) - curShadowGeometry[5] = curShadowGeometry[7] + lightVecBackFront[1]*shadowLength - curShadowGeometry[6] = curShadowGeometry[8] + lightVecBackFront[2]*shadowLength + curShadowGeometry[5] = curShadowGeometry[7] + lightVecBackFront[1] * shadowLength + curShadowGeometry[6] = curShadowGeometry[8] + lightVecBackFront[2] * shadowLength end end if curShadowGeometry[1] @@ -875,10 +959,10 @@ function calculateShadows(lightsource, geometry, circle, image) for i, v in pairs(circle) do local curShadowGeometry = {} local angle = math.atan2(lightsource.x - v.x, v.y - lightsource.y) + math.pi / 2 - local x2 = v.x + math.sin(angle) * v.radius - local y2 = v.y - math.cos(angle) * v.radius - local x3 = v.x - math.sin(angle) * v.radius - local y3 = v.y + math.cos(angle) * v.radius + local x2 = (v.x + math.sin(angle) * v.radius) + local y2 = (v.y - math.cos(angle) * v.radius) + local x3 = (v.x - math.sin(angle) * v.radius) + local y3 = (v.y + math.cos(angle) * v.radius) curShadowGeometry[1] = x2 curShadowGeometry[2] = y2 @@ -904,7 +988,7 @@ shadowStencil = function() love.graphics.polygon("fill", unpack(LOVE_LIGHT_POLY[i].data)) end for i = 1, #LOVE_LIGHT_CIRCLE do - love.graphics.circle("fill", LOVE_LIGHT_CIRCLE[i].getX(), LOVE_LIGHT_CIRCLE[i].getY(), LOVE_LIGHT_CIRCLE[i].getRadius()) + love.graphics.circle("fill", LOVE_LIGHT_CIRCLE[i].x, LOVE_LIGHT_CIRCLE[i].y, LOVE_LIGHT_CIRCLE[i].radius) end for i = 1, #LOVE_LIGHT_IMAGE do --love.graphics.rectangle("fill", LOVE_LIGHT_IMAGE[i].x, LOVE_LIGHT_IMAGE[i].y, LOVE_LIGHT_IMAGE[i].width, LOVE_LIGHT_IMAGE[i].height) @@ -914,7 +998,7 @@ end polyStencil = function() for i = 1, #LOVE_LIGHT_CIRCLE do if LOVE_LIGHT_CIRCLE[i].shine then - love.graphics.circle("fill", LOVE_LIGHT_CIRCLE[i].getX(), LOVE_LIGHT_CIRCLE[i].getY(), LOVE_LIGHT_CIRCLE[i].getRadius()) + love.graphics.circle("fill", LOVE_LIGHT_CIRCLE[i].x, LOVE_LIGHT_CIRCLE[i].y, LOVE_LIGHT_CIRCLE[i].radius) end end for i = 1, #LOVE_LIGHT_POLY do @@ -927,4 +1011,51 @@ polyStencil = function() --love.graphics.rectangle("fill", LOVE_LIGHT_IMAGE[i].x, LOVE_LIGHT_IMAGE[i].y, LOVE_LIGHT_IMAGE[i].width, LOVE_LIGHT_IMAGE[i].height) end end +end + +function HeightMapToNormalMap(heightMap, strength) + local imgData = heightMap:getData() + local imgData2 = love.image.newImageData(heightMap:getWidth(), heightMap:getHeight()) + local red, green, blue, alpha + local x, y + local matrix = {} + matrix[1] = {} + matrix[2] = {} + matrix[3] = {} + strength = strength or 1.0 + + for i = 0, heightMap:getHeight() - 1 do + for k = 0, heightMap:getWidth() - 1 do + for l = 1, 3 do + for m = 1, 3 do + if k + (l - 1) < 1 then + x = heightMap:getWidth() - 1 + elseif k + (l - 1) > heightMap:getWidth() - 1 then + x = 1 + else + x = k + l - 1 + end + + if i + (m - 1) < 1 then + y = heightMap:getHeight() - 1 + elseif i + (m - 1) > heightMap:getHeight() - 1 then + y = 1 + else + y = i + m - 1 + end + + local red, green, blue, alpha = imgData:getPixel(x, y) + matrix[l][m] = red + end + end + + red = (255 + ((matrix[1][2] - matrix[2][2]) + (matrix[2][2] - matrix[3][2])) * strength) / 2.0 + green = (255 - ((matrix[2][2] - matrix[1][1]) + (matrix[2][3] - matrix[2][2])) * strength) / 2.0 + blue = 192 + + imgData2:setPixel(k, i, red, green, blue) + end + end + + return love.graphics.newImage(imgData2) end \ No newline at end of file diff --git a/main.lua b/main.lua index 5699501..8dc5a56 100644 --- a/main.lua +++ b/main.lua @@ -57,6 +57,10 @@ function love.load() machine2 = love.graphics.newImage "gfx/machine2.png" machine2_normal = love.graphics.newImage "gfx/machine2_normal.png" machine2_glow = love.graphics.newImage "gfx/machine2_glow.png" + blopp = love.graphics.newImage "gfx/blopp.png" + tile = love.graphics.newImage "gfx/tile.png" + tile_normal = love.graphics.newImage "gfx/tile_normal.png" + tile_glow = love.graphics.newImage "gfx/tile_glow.png" -- light world lightRange = 300 @@ -77,6 +81,7 @@ function love.load() shadowBlur = 2.0 bloomOn = true textureOn = true + normalOn = false offsetX = 0.0 offsetY = 0.0 @@ -168,14 +173,19 @@ function love.draw() end love.graphics.setBlendMode("alpha") - love.graphics.setColor(255, 255, 255) - if textureOn then - love.graphics.draw(imgFloor, quadScreen, offsetX % 32 - 32, offsetY % 24 - 24) - else + if normalOn then + love.graphics.setColor(127, 127, 255) love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) + else + love.graphics.setColor(255, 255, 255) + if textureOn then + love.graphics.draw(imgFloor, quadScreen, offsetX % 32 - 32, offsetY % 24 - 24) + else + love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) + end end -- draw lightmap shadows - if lightOn then + if lightOn and not normalOn then lightWorld.drawShadow() end @@ -189,24 +199,30 @@ function love.draw() end -- draw lightmap shine - if lightOn then + if lightOn and not normalOn then lightWorld.drawShine() end for i = 1, phyCnt do if phyLight[i].getType() == "image" then - love.graphics.setColor(223 + math.sin(i) * 31, 223 + math.cos(i) * 31, 223 + math.tan(i) * 31) - love.graphics.draw(phyLight[i].img, phyLight[i].x - phyLight[i].ox2, phyLight[i].y - phyLight[i].oy2) + if not normalOn then + --love.graphics.setColor(255, 255, 255) + love.graphics.setColor(127 + math.sin(i) * 127, 127 + math.cos(i) * 127, 127 + math.tan(i) * 127) + love.graphics.draw(phyLight[i].img, phyLight[i].x - phyLight[i].ox2, phyLight[i].y - phyLight[i].oy2) + elseif phyLight[i].normal then + love.graphics.setColor(255, 255, 255) + love.graphics.draw(phyLight[i].normal, phyLight[i].x - phyLight[i].ox2, phyLight[i].y - phyLight[i].oy2) + end end end -- draw pixel shadow - if lightOn then + if lightOn and not normalOn then lightWorld.drawPixelShadow() end -- draw glow - if lightOn then + if lightOn and not normalOn then lightWorld.drawGlow() end @@ -261,6 +277,13 @@ function love.draw() love.graphics.setColor(255, 0, 0) love.graphics.print("F7: Texture off", 4 + 152 * 1, 4 + 20 * 1) end + if normalOn then + love.graphics.setColor(0, 255, 0) + love.graphics.print("F8: Normal on", 4 + 152 * 2, 4 + 20 * 1) + else + love.graphics.setColor(255, 0, 0) + love.graphics.print("F8: Normal off", 4 + 152 * 2, 4 + 20 * 1) + end love.graphics.setColor(255, 0, 255) love.graphics.print("F11: Clear obj.", 4 + 152 * 3, 4 + 20 * 1) love.graphics.print("F12: Clear lights", 4 + 152 * 4, 4 + 20 * 1) @@ -351,6 +374,8 @@ function love.keypressed(k, u) bloomOn = not bloomOn elseif k == "f7" then textureOn = not textureOn + elseif k == "f8" then + normalOn = not normalOn elseif k == "f11" then physicWorld:destroy() lightWorld.clearObjects() @@ -407,5 +432,25 @@ function love.keypressed(k, u) phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 24, 32) phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) phyFixture[phyCnt]:setRestitution(0.5) + elseif k == "6" then + -- add image + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newImage(blopp, mx, my, 42, 16, 21, 20) + phyLight[phyCnt].generateNormalMapFade("fade", "fade") + phyBody[phyCnt] = love.physics.newBody(physicWorld, mx, my, "dynamic") + phyShape[phyCnt] = love.physics.newRectangleShape(0, 0, 42, 29) + phyFixture[phyCnt] = love.physics.newFixture(phyBody[phyCnt], phyShape[phyCnt]) + phyFixture[phyCnt]:setRestitution(0.5) + elseif k == "7" then + -- add image + phyCnt = phyCnt + 1 + phyLight[phyCnt] = lightWorld.newImage(tile, mx, my) + phyLight[phyCnt].setHeightMap(tile_normal, 2.0) + phyLight[phyCnt].setGlowMap(tile_glow) + phyLight[phyCnt].setShadow(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]) + phyFixture[phyCnt]:setRestitution(0.5) end end \ No newline at end of file diff --git a/shader/normal.glsl b/shader/normal.glsl new file mode 100644 index 0000000..c35cfc5 --- /dev/null +++ b/shader/normal.glsl @@ -0,0 +1,33 @@ +extern vec2 screenResolution; +extern vec3 lightPosition; +extern vec3 lightColor; +extern float lightRange; +extern float lightSmooth; + +vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords) { + vec4 pixelColor = Texel(texture, texture_coords); + + if(pixelColor.a > 0.0) { + vec3 normal = vec3(pixelColor.r, 1 - pixelColor.g, pixelColor.b); + float dist = distance(lightPosition, vec3(screen_coords, normal.b)); + + if(dist < lightRange) { + vec3 dir = vec3((lightPosition.xy - screen_coords.xy) / screenResolution.xy, lightPosition.z); + + dir.x *= screenResolution.x / screenResolution.y; + + vec3 N = normalize(normal * 2.0 - 1.0); + vec3 L = normalize(dir); + + vec3 diff = lightColor * max(dot(N, L), 0.0); + + float att = clamp((1.0 - dist / lightRange) / lightSmooth, 0.0, 1.0); + + return vec4(diff * att, 1.0); + } else { + return vec4(0.0, 0.0, 0.0, 1.0); + } + } else { + return vec4(0.0); + } +} \ No newline at end of file diff --git a/shader/pixel_self_shadow.glsl b/shader/pixel_self_shadow.glsl deleted file mode 100644 index 61d4603..0000000 --- a/shader/pixel_self_shadow.glsl +++ /dev/null @@ -1,24 +0,0 @@ -extern vec3 lightPosition; -extern float lightRange; -extern vec3 lightColor; -extern vec3 lightAmbient; -extern float lightSmooth; - -vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) { - vec3 lightDirection = vec3(pixel_coords.xy, 0) - lightPosition.xyz; - float distance = length(lightDirection); - - vec4 pixel = Texel(texture, texture_coords); - vec3 normal = vec3(pixel.x, 1 - pixel.y, pixel.z); - normal = mix(vec3(-1), vec3(1), normal); - - float att = 1 - distance / lightRange; - - if(pixel.a > 0.0 && distance < lightRange) { - return vec4(vec3(clamp((1 - dot(normal, lightDirection)) * pow(att, lightSmooth * 4.0), 0.0, 1.0)) * lightColor + lightAmbient, 1.0); - } else if(pixel.a == 0.0) { - return vec4(0.0); - } else { - return vec4(0.0, 0.0, 0.0, 1.0); - } -} \ No newline at end of file