diff options
Diffstat (limited to 'libs/moonshine/crt.lua')
-rw-r--r-- | libs/moonshine/crt.lua | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/libs/moonshine/crt.lua b/libs/moonshine/crt.lua new file mode 100644 index 0000000..9b73799 --- /dev/null +++ b/libs/moonshine/crt.lua @@ -0,0 +1,79 @@ +--[[ +Public domain: + +Copyright (C) 2017 by Matthias Richter <vrld@vrld.org> + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +]]-- + +return function(moonshine) + -- Barrel distortion adapted from Daniel Oaks (see commit cef01b67fd) + -- Added feather to mask out outside of distorted texture + local distortionFactor + local shader = love.graphics.newShader[[ + extern vec2 distortionFactor; + extern vec2 scaleFactor; + extern number feather; + + vec4 effect(vec4 color, Image tex, vec2 uv, vec2 px) { + // to barrel coordinates + uv = uv * 2.0 - vec2(1.0); + + // distort + uv *= scaleFactor; + uv += (uv.yx*uv.yx) * uv * (distortionFactor - 1.0); + number mask = (1.0 - smoothstep(1.0-feather,1.0,abs(uv.x))) + * (1.0 - smoothstep(1.0-feather,1.0,abs(uv.y))); + + // to cartesian coordinates + uv = (uv + vec2(1.0)) / 2.0; + + return color * Texel(tex, uv) * mask; + } + ]] + + local setters = {} + + setters.distortionFactor = function(v) + assert(type(v) == "table" and #v == 2, "Invalid value for `distortionFactor'") + distortionFactor = {unpack(v)} + shader:send("distortionFactor", v) + end + + setters.x = function(v) setters.distortionFactor{v, distortionFactor[2]} end + setters.y = function(v) setters.distortionFactor{distortionFactor[1], v} end + + setters.scaleFactor = function(v) + if type(v) == "table" and #v == 2 then + shader:send("scaleFactor", v) + elseif type(v) == "number" then + shader:send("scaleFactor", {v,v}) + else + error("Invalid value for `scaleFactor'") + end + end + + setters.feather = function(v) shader:send("feather", v) end + + local defaults = { + distortionFactor = {1.06, 1.065}, + feather = 0.02, + scaleFactor = 1, + } + + return moonshine.Effect{ + name = "crt", + shader = shader, + setters = setters, + defaults = defaults + } +end |