2026-01-14 21:00:17 +03:00

95 lines
3.2 KiB
Lua

--- @class Render
--- @field shadowLayer love.Canvas
--- @field spriteLayer love.Canvas
--- @field spriteLightLayer love.Canvas
--- @field floorLayer love.Canvas
--- @field lightLayer love.Canvas
--- @field overlayLayer love.Canvas
local render = {}
render.__index = render
function render:clear()
local weather = Tree.level.weather
love.graphics.setCanvas(self.shadowLayer)
love.graphics.clear()
love.graphics.setCanvas(self.spriteLayer)
love.graphics.clear()
love.graphics.setCanvas(self.spriteLightLayer)
love.graphics.clear(weather.skyLight.x, weather.skyLight.y, weather.skyLight.z)
love.graphics.setCanvas(self.floorLayer)
love.graphics.clear()
love.graphics.setCanvas(self.lightLayer)
love.graphics.clear(weather.skyLight.x, weather.skyLight.y, weather.skyLight.z)
love.graphics.setCanvas(self.overlayLayer)
love.graphics.clear()
end
--- TODO: это используется для блюра, должно кэшироваться и поддерживать ресайз
local tmp1 = love.graphics.newCanvas(1280, 720)
local tmp2 = love.graphics.newCanvas(1280, 720)
local function applyBlur(input, radius)
local blurShader = Tree.assets.files.shaders.blur
-- Горизонтальный проход
blurShader:send("direction", { 1.0, 0.0 })
blurShader:send("radius", radius)
tmp1:renderTo(function()
love.graphics.clear()
love.graphics.setShader(blurShader)
love.graphics.draw(input)
love.graphics.setShader()
end)
-- Вертикальный проход
tmp2:renderTo(
function()
love.graphics.clear()
love.graphics.setShader(blurShader)
blurShader:send("direction", { 0.0, 1.0 })
love.graphics.draw(tmp1)
love.graphics.setShader()
end
)
return tmp2
end
function render:draw()
-- пол -> тени -> спрайты -> свет -> оверлей
local weather = Tree.level.weather
love.graphics.setCanvas(self.lightLayer)
love.graphics.draw(applyBlur(self.shadowLayer, 4 * Tree.level.camera.scale))
love.graphics.setCanvas()
-- self.lightLayer:newImageData():encode("png", "lightLayer.png")
-- os.exit(0)
local lightShader = Tree.assets.files.shaders.light_postprocess
lightShader:send("scene", self.floorLayer)
lightShader:send("light", self.lightLayer)
lightShader:send("ambient", { weather.ambientLight.x, weather.ambientLight.y, weather.ambientLight.z })
love.graphics.setShader(lightShader)
love.graphics.draw(self.floorLayer)
lightShader:send("scene", self.spriteLayer)
lightShader:send("light", self.spriteLightLayer)
love.graphics.draw(self.spriteLayer)
love.graphics.setShader()
love.graphics.draw(self.overlayLayer)
end
local function new()
return setmetatable({
shadowLayer = love.graphics.newCanvas(1280, 720),
spriteLayer = love.graphics.newCanvas(1280, 720),
spriteLightLayer = love.graphics.newCanvas(1280, 720),
floorLayer = love.graphics.newCanvas(1280, 720),
overlayLayer = love.graphics.newCanvas(1280, 720),
lightLayer = love.graphics.newCanvas(1280, 720)
}, render)
end
return { new = new }