I löve when there is a happy open-source forkPriorBlue wrote:I watched the last days over your code and i was surprised how much work do you put in the changes, i think the new direction of your system is very good, you have even added new postshader and improved the others like the scanline shader, awesome! I don't know, if you really need my help in the future, your changes look really great.
Oh and by the way, you can add your name in all files of the project or you can remove/change the MIT licence, if you want. The project is now officially yours .
Löve "Light vs. Shadow" Engine v2
Re: Löve "Light vs. Shadow" Engine v2
Re: Löve "Light vs. Shadow" Engine v2
Just a PSA to anyone who intends to use this library and is using STI, the v2 of Shadow vs light changed the way it uses canvases and does not like STI for that reason. After struggling for a long time with trying to implement this updated version to my current project, I spoke to "drunken_thor" (Who manages the library) and he confirmed that it is not compatible with STI.
The old Shadow vs Light does not have this issue however, so If you intend to use STI then I would recommend using it. A few major improvements made in this version are missing though, but I have managed to fix most of them (Such as scaling and translation, removal of shadow and light bodies etc). So if you intend to do like me and use the older version, feel free to ask for help in case you run into any issues.
The old Shadow vs Light does not have this issue however, so If you intend to use STI then I would recommend using it. A few major improvements made in this version are missing though, but I have managed to fix most of them (Such as scaling and translation, removal of shadow and light bodies etc). So if you intend to do like me and use the older version, feel free to ask for help in case you run into any issues.
Re: Löve "Light vs. Shadow" Engine v2
@drunken_thor : think you can post some info on the math used to calculate the shadows, per body? Specifically I am talking about body:calculatePolyShadow(). I'm looking at it and scratching my head and it's kinda hard to understand what it's doing with no comments and especially without being able to visualize what's happening.
I'm asking because I'm trying to reverse-engineer that part of the engine so that I can use it for other stuff, apart from lighting.
And of course, thanks a lot for your work on this.
I'm asking because I'm trying to reverse-engineer that part of the engine so that I can use it for other stuff, apart from lighting.
And of course, thanks a lot for your work on this.
- drunken_thor
- Citizen
- Posts: 75
- Joined: Wed Oct 01, 2014 12:14 am
- Location: Toronto, Canada
- Contact:
Re: Löve "Light vs. Shadow" Engine v2
Yeah sure just give me a a little while because I was just working on that specific part to make the shadows actually end somewhere and have more of a 3D quality to them.nfey wrote:@drunken_thor : think you can post some info on the math used to calculate the shadows, per body? Specifically I am talking about body:calculatePolyShadow(). I'm looking at it and scratching my head and it's kinda hard to understand what it's doing with no comments and especially without being able to visualize what's happening.
I'm asking because I'm trying to reverse-engineer that part of the engine so that I can use it for other stuff, apart from lighting.
And of course, thanks a lot for your work on this.
I can get you started on it though.
Code: Select all
function body:calculatePolyShadow(light)
if self.castsNoShadow then
return nil
end
local curPolygon = self.data
local edgeFacingTo = {}
-- for each edge check if the light strikes it
for k = 1, #curPolygon, 2 do
local indexOfNextVertex = (k + 2) % #curPolygon
-- get the unit vector of the edge
local normal = {-curPolygon[indexOfNextVertex+1] + curPolygon[k + 1], curPolygon[indexOfNextVertex] - curPolygon[k]}
normal = vector.normalize(normal)
-- get the unit vector of the light pointing at the current point we are examing
-- [hint] we are looking for the outter most edges of the polygon that the light hits
local lightToPoint = {curPolygon[k] - light.x, curPolygon[k + 1] - light.y}
lightToPoint = vector.normalize(lightToPoint)
--get the dot product of the two vectors to see if it faces the light
local dotProduct = vector.dot(normal, lightToPoint)
-- if the dot product is greater than 0 it faces the light
if dotProduct > 0 then
table.insert(edgeFacingTo, true)
-- if the dot product is 0 it is perpendicular
-- if it is less than 0 it faces away from the light
else
table.insert(edgeFacingTo, false)
end
end
--now we have a table that tells us which edges are hit by the light
local curShadowGeometry = {}
-- for each point in the polygon again but referencing the edges
for k = 1, #edgeFacingTo do
local nextIndex = (k + 1) % #edgeFacingTo
if nextIndex == 0 then nextIndex = #edgeFacingTo end
-- if this edge is in the light but not the next
-- create the first 2 points of the polygon we have found an edge of the shadow
if edgeFacingTo[k] and not edgeFacingTo[nextIndex] then
curShadowGeometry[1] = curPolygon[nextIndex*2-1]
curShadowGeometry[2] = curPolygon[nextIndex*2]
--cast the edge beyond the shape in the direction of the vector from the light to the point
local lightVecFrontBack = vector.normalize({curPolygon[nextIndex*2-1] - light.x, curPolygon[nextIndex*2] - light.y})
curShadowGeometry[3] = curShadowGeometry[1] + lightVecFrontBack[1] * shadowLength
curShadowGeometry[4] = curShadowGeometry[2] + lightVecFrontBack[2] * shadowLength
-- if this edfe is not in the light but the next one is the we found the last 2 points of the shadow
elseif not edgeFacingTo[k] and edgeFacingTo[nextIndex] then
curShadowGeometry[7] = curPolygon[nextIndex*2-1]
curShadowGeometry[8] = curPolygon[nextIndex*2]
--cast the edge beyond the shape in the direction of the vector from the light to the point
local lightVecBackFront = vector.normalize({curPolygon[nextIndex*2-1] - light.x, curPolygon[nextIndex*2] - light.y})
curShadowGeometry[5] = curShadowGeometry[7] + lightVecBackFront[1] * shadowLength
curShadowGeometry[6] = curShadowGeometry[8] + lightVecBackFront[2] * shadowLength
end
end
--we only draw long rectangular shadows
--so they must have 4 points
if curShadowGeometry[1]
and curShadowGeometry[2]
and curShadowGeometry[3]
and curShadowGeometry[4]
and curShadowGeometry[5]
and curShadowGeometry[6]
and curShadowGeometry[7]
and curShadowGeometry[8]
then
curShadowGeometry.alpha = self.alpha
curShadowGeometry.red = self.red
curShadowGeometry.green = self.green
curShadowGeometry.blue = self.blue
return curShadowGeometry
else
return nil
end
end
- drunken_thor
- Citizen
- Posts: 75
- Joined: Wed Oct 01, 2014 12:14 am
- Location: Toronto, Canada
- Contact:
Re: Löve "Light vs. Shadow" Engine v2
@nfey okay so I improved the shadow body calculations in the library and really found this paper helpful when doing so http://web.cs.wpi.edu/~matt/courses/cs5 ... hadow.htmlnfey wrote:@drunken_thor : think you can post some info on the math used to calculate the shadows, per body? Specifically I am talking about body:calculatePolyShadow(). I'm looking at it and scratching my head and it's kinda hard to understand what it's doing with no comments and especially without being able to visualize what's happening.
I'm asking because I'm trying to reverse-engineer that part of the engine so that I can use it for other stuff, apart from lighting.
And of course, thanks a lot for your work on this.
Re: Löve "Light vs. Shadow" Engine v2
@drunken_thor - thanks a lot, this really helps with understanding what's going on.
Re: Löve "Light vs. Shadow" Engine v2
Is there a way to make this work with Hump camera? I can't set the translation right. I can attach a light to the mouse co-ordinates on the camera but it fails when I want to set a fixed location for a shadow body on world co-ordinates. I tried to :setPosition() within camera attach and detach functions but it didn't make any difference.
- drunken_thor
- Citizen
- Posts: 75
- Joined: Wed Oct 01, 2014 12:14 am
- Location: Toronto, Canada
- Contact:
Re: Löve "Light vs. Shadow" Engine v2
It should work with all translations done with love, are you passing in your translation and scale on the lightworld:draw() call? can I see your code?Relazy wrote:Is there a way to make this work with Hump camera? I can't set the translation right. I can attach a light to the mouse co-ordinates on the camera but it fails when I want to set a fixed location for a shadow body on world co-ordinates. I tried to :setPosition() within camera attach and detach functions but it didn't make any difference.
Re: Löve "Light vs. Shadow" Engine v2
I am not sure what translation to use because hump handles the camera with two sets of co-ordinates: one for camera:worldCoords() and one for camera:cameraCoords(), heres an example(use WSAD to move camera. up key + enter for selection of the translation):drunken_thor wrote:It should work with all translations done with love, are you passing in your translation and scale on the lightworld:draw() call? can I see your code?Relazy wrote:Is there a way to make this work with Hump camera? I can't set the translation right. I can attach a light to the mouse co-ordinates on the camera but it fails when I want to set a fixed location for a shadow body on world co-ordinates. I tried to :setPosition() within camera attach and detach functions but it didn't make any difference.
Code: Select all
local LightWorld = require "lib"
local lightworld = LightWorld({
drawBackground = drawBackground,
drawForeground = drawForeground,
ambient = {50,50,50},
})
Camera = require "hump.camera"
function love.load()
fthis = 0
this2 = 0
cx = 360
cy = 350
px = 400
py = 300
camera = Camera(0,0)
a = lightworld:newLight(love.mouse.getX(),love.mouse.getY(),155,155,20,200)
b = lightworld:newRectangle(px,py,200,200)
end
function love.draw()
if this2 == 1 then
x,y = camera:worldCoords(10,10)
elseif this2 == 2 then
x,y = camera:cameraCoords(10,10)
elseif this2 == 3 then
local tx,ty = love.graphics.getWidth()/(2*camera.scale), love.graphics.getHeight()/(2*camera.scale)
--the previous method from old light v shadow
x = tx-10
y = ty-10
else
x = 0
y = 0
end
love.graphics.push()
love.graphics.translate(x,y)
-- I am currently on default scale which is 1 so I assume there isn't a need to translate by love.graphics.scale().
lightworld:draw(x,y,1)
love.graphics.pop()
love.graphics.setColor(126,85,98)
love.graphics.rectangle("fill",0,100,300,20)
if fthis == 1 then
love.graphics.setColor(240,200,200)
end
love.graphics.rectangle("fill",0,120,300,20)
love.graphics.setColor(126,85,98)
if fthis == 2 then
love.graphics.setColor(240,200,200)
end
love.graphics.rectangle("fill",0,140,300,20)
love.graphics.setColor(126,85,98)
if fthis == 3 then
love.graphics.setColor(240,200,200)
end
love.graphics.rectangle("fill",0,160,300,20)
love.graphics.setColor(126,85,98)
love.graphics.setColor(255,255,255)
love.graphics.print("The current translation is: "..this2,0,100)
love.graphics.print("1:Set translation to camera:worldCoords()",0,120)
love.graphics.print("2:Set translation to camera:camCoords()",0,140)
love.graphics.print("3:Set translation to light v shadow v1",0,160)
love.graphics.print("camera x:"..camera.x,0,180)
love.graphics.print("camera y:"..camera.y,0,190)
end
function love.keypressed(key)
-- movement and selection of translation
if key == "a" then
px = px + 40
elseif key == "d" then
px = px - 40
end
if key == "w" then
py = py + 40
elseif key == "s" then
py = py - 40
end
if fthis < 4 and fthis > 0 then
if key == "up" then
fthis = fthis + 1
end
if key == "return" then
this2 = fthis
end
else
fthis = 1
end
end
function love.update(dt)
a:setPosition(love.mouse.getX(),love.mouse.getY())
love.window.setTitle(""..love.timer.getFPS())
camera:lookAt(px,py)
end
function lightworld:drawBackground()
love.graphics.setColor(152,150,97)
love.graphics.rectangle("fill",0,0,800,600)
love.graphics.setColor(255,255,255)
camera:attach()
camera:detach()
end
function lightworld:drawForeground()
camera:attach()
--cx2,cy2 = camera:worldCoords(cx,cy)
--b:setPosition(cx2,cy2)
b:setPosition(cx,cy)
love.graphics.setColor(100,100,190)
love.graphics.rectangle("fill",cx,cy,200,200)
love.graphics.setColor(200,200,200)
love.graphics.rectangle("fill",px,py,20,20) -- illustrated the point at which camera looks at
love.graphics.setColor(255,255,255)
camera:detach()
end
- Attachments
-
- this.love
- (45.14 KiB) Downloaded 213 times
- drunken_thor
- Citizen
- Posts: 75
- Joined: Wed Oct 01, 2014 12:14 am
- Location: Toronto, Canada
- Contact:
Re: Löve "Light vs. Shadow" Engine v2
@relazy I will be releasing a new, simpler, faster version of this library within a week. I will add example of both hump and gamera. I will let you know when I release it.
small teasers of what is to come to hopefully help the wait:
- much faster drawing (took out 3 separate shaders and integrated them all into one draw)
- single callback draw call (like gamera's draw call) to simplify use
- integrated animation using normal maps :O
- [and now] example for most used cameras
small teasers of what is to come to hopefully help the wait:
- much faster drawing (took out 3 separate shaders and integrated them all into one draw)
- single callback draw call (like gamera's draw call) to simplify use
- integrated animation using normal maps :O
- [and now] example for most used cameras
Who is online
Users browsing this forum: No registered users and 2 guests