diff --git a/Body.lua b/Body.lua index 38f5dec..cbce2dc 100644 --- a/Body.lua +++ b/Body.lua @@ -3,8 +3,8 @@ module("shadows.Body", package.seeall) Object = require("shadows.Object") PriorityQueue = require("shadows.PriorityQueue") -Shadows = require("shadows") -Transform = require("shadows.Transform") +Shadows = require("shadows") +Transform = require("shadows.Transform") CircleShadow = require("shadows.ShadowShapes.CircleShadow") PolygonShadow = require("shadows.ShadowShapes.PolygonShadow") diff --git a/Functions.lua b/Functions.lua index 4b0469f..9b7a6d2 100644 --- a/Functions.lua +++ b/Functions.lua @@ -1,6 +1,7 @@ module("shadows.Functions", package.seeall) Shadows = require("shadows") +Shaders = require("shadows.Shaders") local sqrt = math.sqrt local min = math.min @@ -83,4 +84,33 @@ function Shadows.Insert(Table, Index, Value) end +end + +function Shadows.newDropshadowsFromImageData(ImageData, LightX, LightY, LightZ, LightRadius, TextureZ, LightRadiusMult) + + local width, height = ImageData:getDimensions() + local scale = LightZ / ( LightZ - TextureZ ) + local canvasWidth = math.ceil( width * scale ) + local canvasHeight = math.ceil( height * scale ) + local canvas = love.graphics.newCanvas( canvasWidth, canvasHeight ) + + Shaders.DropShadows:send("lightPosition", { LightX, LightY, LightZ }) + Shaders.DropShadows:send("lightRadius", LightRadius) + Shaders.DropShadows:send("lightRadiusMult", LightRadiusMult or 2) + Shaders.DropShadows:send("texure", love.graphics.newImage(ImageData)) + Shaders.DropShadows:send("textureSize", { width - 0.5, height - 0.5 }) + Shaders.DropShadows:send("textureZ", TextureZ) + + love.graphics.setCanvas(canvas) + love.graphics.clear(0, 0, 0, 0) + + love.graphics.setColor(1, 1, 1, 1) + love.graphics.setShader(Shaders.DropShadows) + love.graphics.rectangle("fill", 0, 0, canvasWidth, canvasHeight) + + love.graphics.setCanvas() + love.graphics.setShader() + + return canvas + end \ No newline at end of file diff --git a/Light.lua b/Light.lua index fe305e7..a548001 100644 --- a/Light.lua +++ b/Light.lua @@ -1,9 +1,9 @@ module("shadows.Light", package.seeall) -Object = require("shadows.Object") +Object = require("shadows.Object") -Shadows = require("shadows") -Transform = require("shadows.Transform") +Shadows = require("shadows") +Transform = require("shadows.Transform") Light = setmetatable( {}, Object ) Light.__index = Light diff --git a/Shaders.lua b/Shaders.lua index a595290..7681227 100644 --- a/Shaders.lua +++ b/Shaders.lua @@ -331,4 +331,69 @@ Shadows.HeightShader = love.graphics.newShader [[ ]] +Shadows.DropShadows = love.graphics.newShader [[ + extern vec3 lightPosition; + extern number lightRadius; + extern number lightRadiusMult; + + extern Image texure; + extern vec2 textureSize; + extern number textureZ; + + vec4 effect(vec4 color, Image _t, vec2 texture_coords, vec2 screen_coords) { + // Calculate offset on canvas + number scale = lightPosition.z / ( lightPosition.z - textureZ ); + number textureOffset = ( scale - 1.0 ) * 0.5; + + // Inverse of the texture size + vec2 iTextureSize = 1.0 / textureSize; + + // Position of the pixel + vec3 textureCoord3 = vec3(screen_coords * iTextureSize, 0.0); + + // Alpha of the shadow + number pointDarken = 0.0; + number pointCount = 0.0; + + // Inverse of the light radius + number iLightRadius = 1.0 / lightRadius; + + // For each pixel offset on the light's position + for (number x = -lightRadius; x < lightRadius; x++) { + for (number y = -lightRadius; y < lightRadius; y++) { + + vec2 vec = vec2(x, y); + number vecLength = length(vec); + + if ( vecLength <= lightRadius ) { + + // Which position on the light source + vec3 position = lightPosition + textureOffset + vec3(vec * lightRadiusMult * iTextureSize, 0.0); + + // Direction from the pixel position, to the light position + vec3 direction = normalize(position - textureCoord3); + + // Position on the texture's layer + vec3 point = textureCoord3 + ( direction / direction.z ) * textureZ; + + // Color on the texture + vec4 pixelColor = Texel(texure, point.xy - textureOffset); + + // Is it not a color? + if (pixelColor.r > 0.0 || pixelColor.g > 0.0 || pixelColor.b > 0.0 || pixelColor.a > 0.0) { + // Make the pixel darker + pointDarken += vecLength * iLightRadius; + } + + // Increment the number of pixels used + pointCount++; + } + } + } + + return vec4(0.0, 0.0, 0.0, pointDarken / pointCount); + + } +]] + return Shadows \ No newline at end of file diff --git a/Star.lua b/Star.lua index a92d506..6bf31fd 100644 --- a/Star.lua +++ b/Star.lua @@ -1,7 +1,7 @@ module("shadows.Star", package.seeall) Shadows = require("shadows") -Light = require("shadows.Light") +Light = require("shadows.Light") Transform = require("shadows.Transform") Star = setmetatable( {}, Light )