A whispering voice in my ear says I'm not allowed to tell.Gunroar:Cannon() wrote: ↑Sat Sep 24, 2022 9:46 pm Wondering how you got the eldritch blood (asking for a friend)...
A way to do simple shadows
Re: A way to do simple shadows
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
"If each mistake being made is a new one, then progress is being made."
-
- Party member
- Posts: 356
- Joined: Wed Jul 03, 2013 4:06 am
Re: A way to do simple shadows
These are really cool!
Re: A way to do simple shadows
Can you please explain how the first version works? It looks simple, but I cannot get it.
Code: Select all
--
-- Example program: Render sprites with simple shadows from a light source.
--
local LG = love.graphics
local images = {
sprites = LG.newImage("sprites.png"),
light = LG.newImage("light.png"),
}
images.sprites:setFilter("nearest")
local quads = {
player = LG.newQuad(00,00, 32,32, images.sprites),
tree = LG.newQuad(32,00, 32,32, images.sprites),
sign = LG.newQuad(00,32, 32,32, images.sprites),
}
local entities = {}
local player = {id=#entities, quad=quads.player, x=220,y=200, flip=false}
table.insert(entities, player)
local rand = love.math.random
for i = 1, 30 do table.insert(entities, {id=#entities, quad=quads.tree, x=rand(400),y=rand(300), flip=false}) end
for i = 1, 4 do table.insert(entities, {id=#entities, quad=quads.sign, x=rand(400),y=rand(300), flip=false}) end
local lightSource = {x=0, y=0}
function love.update(dt)
local moveX = 0
local moveY = 0
if love.keyboard.isDown"left" then moveX = moveX - 1 end
if love.keyboard.isDown"right" then moveX = moveX + 1 end
if love.keyboard.isDown"up" then moveY = moveY - 1 end
if love.keyboard.isDown"down" then moveY = moveY + 1 end
player.x = player.x + 1.5*50*moveX*dt
player.y = player.y + 50*moveY*dt
if moveX ~= 0 then player.flip = (moveX < 0) end
local rotation = .3 * love.timer.getTime()
lightSource.x = 200 + 1.5*60*math.cos(rotation)
lightSource.y = 150 + 60*math.sin(rotation)
end
local function clamp(v, min, max)
return math.max(math.min(v, max), min)
end
local function drawEntity(e, shearing, scaleY)
local scaleX = e.flip and -1 or 1
local _,_, w,h = e.quad:getViewport()
LG.draw(images.sprites, e.quad, e.x,e.y, 0, scaleX,scaleY, w/2,h, shearing*scaleX,0)
end
function love.draw()
table.sort(entities, function(a, b)
if a.y ~= b.y then return a.y < b.y end
return a.id < b.id
end)
LG.scale(2)
-- Ground.
LG.clear(0, 0, 0)
-- Light (on ground).
local w,h = images.light:getDimensions()
LG.setColor(.3, .6, .3) ; LG.draw(images.light, lightSource.x,lightSource.y, 0, 1.5*15,15, w/2,h/2)
LG.setColor(1, 1, 1) ; LG.draw(images.light, lightSource.x,lightSource.y, 0, 1.5*1,1, w/2,h/2)
-- Entity shadows.
for _, e in ipairs(entities) do
local dx = lightSource.x - e.x
local dy = lightSource.y - e.y
local distance = math.sqrt(dx^2 + dy^2) / 50
local angle = math.atan2(dy, dx)
local shearing = distance * math.cos(angle)
local scaleY = distance * math.sin(angle)
LG.setColor(0, 0, 0)
drawEntity(e, shearing, scaleY)
end
-- Entities.
for _, e in ipairs(entities) do
local dx = lightSource.x - e.x
local dy = lightSource.y - e.y
local distance = math.sqrt((dx/1.5)^2 + (dy)^2)
local lightDistance = clamp(1 - distance / 400, 0, 1) -- Darker if farther away.
local lightFacing = clamp(1 + dy / 20 , 0, 1) -- Darker if facing away.
local light = lightDistance * lightFacing
LG.setColor(light, light, light)
drawEntity(e, 0, 1)
end
-- Info.
LG.origin()
LG.setColor(1, 1, 1)
LG.print("Press arrow keys to move", 3,1)
end
function love.keypressed(key)
if key == "escape" then love.event.quit() end
end
Re: A way to do simple shadows
Sure. The important parts are the drawEntity() function and how we calculate shearing and y-scaling.
Code: Select all
local function drawEntity(e, shearingX, scaleY)
local scaleX = e.flip and -1 or 1 -- We just use x-scaling to flip the sprite.
local _,_, w,h = e.quad:getViewport() -- The size of the sprite.
LG.draw(
images.sprites, e.quad,
e.x, e.y, -- Position of the feet.
0, -- No rotation.
scaleX, scaleY, -- Scale the sprite.
w/2, h, -- Place the origin right between the feet so that scaling and shearing happens around that point.
shearingX*scaleX, 0 -- Tilt the sprite.
)
end
Code: Select all
-- Entity shadows.
for _, e in ipairs(entities) do
-- Get the difference between the entity and light's x and y positions.
local dx = lightSource.x - e.x
local dy = lightSource.y - e.y
-- Get the straight distance from the entity to the light. This will
-- represent the relative length (i.e. scale) of the shadow, and we
-- divide it by 50 to simply make the shadow a bit shorter. Without
-- the division the shadow scale would increase by one when for every
-- pixel of distance (i.e. the shadow would get really long very quickly).
local distance = math.sqrt(dx^2 + dy^2) / 50
-- Get the angle from the entity to the light.
local angle = math.atan2(dy, dx)
-- X-shearing makes the sprite tilt to the left/right. (It's similar
-- to rotation but the corners keep their y-positions.) Note that
-- shearing is a relative value just like with scaling.
-- If angle is up/down: the cosine is 0 and we get no tilt.
-- If angle is left/right: the cosine is 1 and we get maximum tilt.
local shearingX = distance * math.cos(angle)
-- The y-scale is the vertical length of the shadow.
-- If angle is up/down: the sine is 1/-1 and we get the longest shadow up/down.
-- If angle is left/right: the sine is 0 and we get a zero length shadow.
local scaleY = distance * math.sin(angle)
LG.setColor(0, 0, 0)
drawEntity(e, shearingX, scaleY)
end
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
"If each mistake being made is a new one, then progress is being made."
-
- Party member
- Posts: 356
- Joined: Wed Jul 03, 2013 4:06 am
Re: A way to do simple shadows
oooh...working on a sprite stacked voxel tile engine, and was thinking about how to do decent lights and shadows with it...and I think this might work very well...
-
- Prole
- Posts: 1
- Joined: Wed Oct 26, 2022 9:27 am
- Contact:
Re: A way to do simple shadows
That's what I need!
Who is online
Users browsing this forum: Ahrefs [Bot] and 4 guests