From 12b6646642f2256b342f59ac5aebbf0f50a70f08 Mon Sep 17 00:00:00 2001 From: PeaAshMeter Date: Fri, 24 Oct 2025 03:23:49 +0300 Subject: [PATCH] shader outline experiment --- assets/shaders/outline.glsl | 30 ++++++++++++++++++++++++++++++ lib/character/behaviors/sprite.lua | 11 ++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 assets/shaders/outline.glsl diff --git a/assets/shaders/outline.glsl b/assets/shaders/outline.glsl new file mode 100644 index 0000000..af69a43 --- /dev/null +++ b/assets/shaders/outline.glsl @@ -0,0 +1,30 @@ +#pragma language glsl3 + +extern ivec2 texSize; +extern float time; + +vec4 effect(vec4 color, Image tex, vec2 texCoord, vec2 screenCoord) +{ + float modY = (0.75 + sin(time) * 0.25) * (0.5 + cos(texCoord.y + 10 * sin(0.1 * time)) * 0.5); + vec4 outlineColor = vec4(modY, 0.2 * sin(time) + 0.5, 0.5, 1.0); + float outlineSize = 1.0; + + float alpha = Texel(tex, texCoord).a; + if (alpha > 0.0) + return Texel(tex, texCoord) * color; + + // Если среди соседей есть хоть один прозрачный пиксель, то это граница, обводим её + float outline = 0.0; + for (float x = -outlineSize; x <= outlineSize; x++) { + for (float y = -outlineSize; y <= outlineSize; y++) { + vec2 offset = vec2(x, y) / texSize; + float neighborAlpha = Texel(tex, texCoord + offset).a; + outline = max(outline, neighborAlpha); + } + } + + if (outline > 0.0) + return outlineColor; + + return vec4(0.0); +} diff --git a/lib/character/behaviors/sprite.lua b/lib/character/behaviors/sprite.lua index c0db6b6..0922c4d 100644 --- a/lib/character/behaviors/sprite.lua +++ b/lib/character/behaviors/sprite.lua @@ -45,11 +45,20 @@ function sprite:draw() function(map) local ppm = Tree.level.camera.pixelsPerMeter local position = map.displayedPosition - if Tree.level.selector.id == self.owner.id then love.graphics.setColor(0.5, 1, 0.5) end + if Tree.level.selector.id == self.owner.id then + local texW, texH = Tree.assets.files.sprites.character[self.state]:getWidth(), + Tree.assets.files.sprites.character[self.state]:getHeight() + local shader = Tree.assets.files.shaders.outline + shader:send("texSize", { texW, texH }) + shader:send("time", love.timer:getTime()) + love.graphics.setShader(shader) + end + self.animationTable[self.state]:draw(Tree.assets.files.sprites.character[self.state], position.x + 0.5, position.y + 0.5, nil, 1 / ppm * self.side, 1 / ppm, 38, 47) love.graphics.setColor(1, 1, 1) + love.graphics.setShader() end ) end