From 378586c406707a2988c42420e935cd100c0ce27d Mon Sep 17 00:00:00 2001 From: SpaVec Date: Mon, 17 Jul 2017 23:01:13 +0200 Subject: [PATCH] Added compatibility with android Added util.loadShader - loads shaders and sets uniform variables Fixed implicit type conversions in shaders --- lib/init.lua | 22 +++++------ lib/postshader.lua | 14 +++---- lib/shaders/postshaders/black_and_white.glsl | 6 +-- lib/shaders/postshaders/blurh.glsl | 6 +-- lib/shaders/postshaders/blurv.glsl | 6 +-- lib/shaders/postshaders/four_colors.glsl | 4 +- lib/shaders/postshaders/monochrome.glsl | 2 +- lib/shaders/postshaders/phosphor.glsl | 26 ++++++------- lib/shaders/postshaders/phosphorish.glsl | 27 +++++++------- lib/shaders/postshaders/radialblur.glsl | 10 ++--- lib/shaders/reflection.glsl | 8 ++-- lib/shaders/shadow.glsl | 3 +- lib/util.lua | 39 +++++++++++++++++++- 13 files changed, 104 insertions(+), 69 deletions(-) diff --git a/lib/init.lua b/lib/init.lua index 19c862a..2067d54 100644 --- a/lib/init.lua +++ b/lib/init.lua @@ -31,18 +31,18 @@ local PostShader = require(_PACKAGE..'postshader') local light_world = {} light_world.__index = light_world -light_world.image_mask = love.graphics.newShader(_PACKAGE.."/shaders/image_mask.glsl") -light_world.shadowShader = love.graphics.newShader(_PACKAGE.."/shaders/shadow.glsl") -light_world.refractionShader = love.graphics.newShader(_PACKAGE.."shaders/refraction.glsl") -light_world.reflectionShader = love.graphics.newShader(_PACKAGE.."shaders/reflection.glsl") +light_world.image_mask = util.loadShader(_PACKAGE.."/shaders/image_mask.glsl") +light_world.shadowShader = util.loadShader(_PACKAGE.."/shaders/shadow.glsl") +light_world.refractionShader = util.loadShader(_PACKAGE.."/shaders/refraction.glsl") +light_world.reflectionShader = util.loadShader(_PACKAGE.."/shaders/reflection.glsl") local function new(options) local obj = {} obj.lights = {} obj.bodies = {} obj.post_shader = PostShader() - - obj.l, obj.t, obj.s = 0, 0, 1 + + obj.l, obj.t, obj.s = 0, 0, 1 obj.ambient = {0, 0, 0} obj.refractionStrength = 8.0 obj.reflectionStrength = 16.0 @@ -273,7 +273,7 @@ function light_world:clear() light_world:clearBodies() end -function light_world:setTranslation(l, t, s) +function light_world:setTranslation(l, t, s) self.l, self.t, self.s = l or self.l, t or self.t, s or self.s end @@ -296,13 +296,13 @@ function light_world:newCircle(...) return self:newBody("circle", ...) end function light_world:newPolygon(...) return self:newBody("polygon", ...) end function light_world:newImage(...) return self:newBody("image", ...) end -function light_world:newRefraction(...) +function light_world:newRefraction(...) self.disableRefraction = false - return self:newBody("refraction", ...) + return self:newBody("refraction", ...) end -function light_world:newReflection(normal, ...) +function light_world:newReflection(normal, ...) self.disableReflection = false - return self:newBody("reflection", ...) + return self:newBody("reflection", ...) end -- new body diff --git a/lib/postshader.lua b/lib/postshader.lua index efcc6d5..2541e8c 100644 --- a/lib/postshader.lua +++ b/lib/postshader.lua @@ -29,12 +29,12 @@ post_shader.__index = post_shader local files = love.filesystem.getDirectoryItems(_PACKAGE.."/shaders/postshaders") local shaders = {} - + for i,v in ipairs(files) do local name = _PACKAGE.."/shaders/postshaders".."/"..v if love.filesystem.isFile(name) then local str = love.filesystem.read(name) - local effect = love.graphics.newShader(name) + local effect = util.loadShader(name) local defs = {} for vtype, extern in str:gmatch("extern (%w+) (%w+)") do defs[extern] = true @@ -73,14 +73,14 @@ function post_shader:toggleEffect(shaderName, ...) end function post_shader:drawWith(canvas) - for shader, args in pairs(self.effects) do + for shader, args in pairs(self.effects) do if shader == "bloom" then self:drawBloom(canvas, args) elseif shader == "blur" then self:drawBlur(canvas, args) elseif shader == "tilt_shift" then self:drawTiltShift(canvas, args) - else + else self:drawShader(shader, canvas, args) end end @@ -126,9 +126,9 @@ function post_shader:drawShader(shaderName, canvas, args) effect[1]:send("time", love.timer.getTime()) elseif def == "palette" then effect[1]:send("palette", unpack(process_palette({ - args[current_arg], - args[current_arg + 1], - args[current_arg + 2], + args[current_arg], + args[current_arg + 1], + args[current_arg + 2], args[current_arg + 3] }))) current_arg = current_arg + 4 diff --git a/lib/shaders/postshaders/black_and_white.glsl b/lib/shaders/postshaders/black_and_white.glsl index cf90ee8..53d16f2 100644 --- a/lib/shaders/postshaders/black_and_white.glsl +++ b/lib/shaders/postshaders/black_and_white.glsl @@ -1,13 +1,13 @@ -extern float exposure = 0.7; +extern float exposure=0.7; extern float brightness = 1.0; extern vec3 lumacomponents = vec3(1.0, 1.0, 1.0); const vec3 lumcoeff = vec3(0.212671, 0.715160, 0.072169); -vec4 effect(vec4 vcolor, Image texture, vec2 texcoord, vec2 pixel_coords) { +vec4 effect(vec4 vcolor, Image texture, vec2 texcoord, vec2 pixel_coords) { vec4 input0 = Texel(texture, texcoord); input0 *= (exp2(input0)*vec4(exposure)); vec4 lumacomponents = vec4(lumcoeff * lumacomponents, 0.0 ); float luminance = dot(input0,lumacomponents); vec4 luma = vec4(luminance); return vec4(luma.rgb * brightness, 1.0); -} +} diff --git a/lib/shaders/postshaders/blurh.glsl b/lib/shaders/postshaders/blurh.glsl index ae58eff..be82cd5 100644 --- a/lib/shaders/postshaders/blurh.glsl +++ b/lib/shaders/postshaders/blurh.glsl @@ -3,9 +3,9 @@ extern float steps = 2.0; vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) { vec2 pSize = vec2(1.0 / love_ScreenSize.x, 1.0 / love_ScreenSize.y); vec4 col = Texel(texture, texture_coords); - for(int i = 1; i <= steps; i++) { - col = col + Texel(texture, vec2(texture_coords.x, texture_coords.y - pSize.y * i)); - col = col + Texel(texture, vec2(texture_coords.x, texture_coords.y + pSize.y * i)); + for(int i = 1; i <= int(steps); i++) { + col = col + Texel(texture, vec2(texture_coords.x, texture_coords.y - pSize.y * float(i))); + col = col + Texel(texture, vec2(texture_coords.x, texture_coords.y + pSize.y * float(i))); } col = col / (steps * 2.0 + 1.0); return vec4(col.r, col.g, col.b, 1.0); diff --git a/lib/shaders/postshaders/blurv.glsl b/lib/shaders/postshaders/blurv.glsl index 00b929e..e79a40a 100644 --- a/lib/shaders/postshaders/blurv.glsl +++ b/lib/shaders/postshaders/blurv.glsl @@ -3,9 +3,9 @@ extern float steps = 2.0; vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) { vec2 pSize = vec2(1.0 / love_ScreenSize.x, 1.0 / love_ScreenSize.y); vec4 col = Texel(texture, texture_coords); - for(int i = 1; i <= steps; i++) { - col = col + Texel(texture, vec2(texture_coords.x - pSize.x * i, texture_coords.y)); - col = col + Texel(texture, vec2(texture_coords.x + pSize.x * i, texture_coords.y)); + for(int i = 1; i <= int(steps); i++) { + col = col + Texel(texture, vec2(texture_coords.x - pSize.x * float(i), texture_coords.y)); + col = col + Texel(texture, vec2(texture_coords.x + pSize.x * float(i), texture_coords.y)); } col = col / (steps * 2.0 + 1.0); return vec4(col.r, col.g, col.b, 1.0); diff --git a/lib/shaders/postshaders/four_colors.glsl b/lib/shaders/postshaders/four_colors.glsl index c68b1cf..96c2e63 100644 --- a/lib/shaders/postshaders/four_colors.glsl +++ b/lib/shaders/postshaders/four_colors.glsl @@ -2,7 +2,7 @@ extern vec3 palette[4]; vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords){ vec4 pixel = Texel(texture, texture_coords); - int index = int(min(0.9999, max(0.0001,(pixel.r + pixel.g + pixel.b) / 3.0)) * 4); + int index = int(min(0.9999, max(0.0001,(pixel.r + pixel.g + pixel.b) / 3.0)) * 4.0); return vec4(palette[index], 1.0); -} \ No newline at end of file +} diff --git a/lib/shaders/postshaders/monochrome.glsl b/lib/shaders/postshaders/monochrome.glsl index d4bc55b..9b60f1e 100644 --- a/lib/shaders/postshaders/monochrome.glsl +++ b/lib/shaders/postshaders/monochrome.glsl @@ -10,4 +10,4 @@ vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords){ vec4 pixel = Texel(texture, texture_coords); float intensity = (pixel.r + pixel.g + pixel.b) / 3.0 + (rand(texture_coords, time) - 0.5) * fudge; return vec4(intensity * tint.r, intensity * tint.g, intensity * tint.b, 1.0); -} \ No newline at end of file +} diff --git a/lib/shaders/postshaders/phosphor.glsl b/lib/shaders/postshaders/phosphor.glsl index cf58451..b799f9c 100644 --- a/lib/shaders/postshaders/phosphor.glsl +++ b/lib/shaders/postshaders/phosphor.glsl @@ -94,22 +94,22 @@ vec4 grid_color( vec2 coords ) vec2 onex = vec2( 1.0/love_ScreenSize.x, 0.0 ); vec2 oney = vec2( 0.0, 1.0/love_ScreenSize.y ); -vec4 effect(vec4 vcolor, Image texture, vec2 texCoord, vec2 pixel_coords) +vec4 effect(vec4 vcolor, Image texture, highp vec2 texCoord, vec2 pixel_coords) { - vec2 coords = (texCoord * love_ScreenSize.xy); - vec2 pixel_start = floor(coords); + highp vec2 coords = (texCoord * love_ScreenSize.xy); + highp vec2 pixel_start = floor(coords); coords -= pixel_start; - vec2 pixel_center = pixel_start + vec2(0.5); - vec2 texture_coords = pixel_center / love_ScreenSize.xy; + highp vec2 pixel_center = pixel_start + vec2(0.5); + highp vec2 texture_coords = pixel_center / love_ScreenSize.xy; - vec4 color = vec4(0.0); - vec4 pixel; - vec3 centers = vec3(-0.25,-0.5,-0.75); - vec3 posx = vec3(coords.x); - vec3 hweight; - float vweight; - float dx,dy; - float w; + highp vec4 color = vec4(0.0); + highp vec4 pixel; + highp vec3 centers = vec3(-0.25,-0.5,-0.75); + highp vec3 posx = vec3(coords.x); + highp vec3 hweight; + highp float vweight; + highp float dx,dy; + highp float w; float i,j; diff --git a/lib/shaders/postshaders/phosphorish.glsl b/lib/shaders/postshaders/phosphorish.glsl index 5449cbd..29bbd5a 100644 --- a/lib/shaders/postshaders/phosphorish.glsl +++ b/lib/shaders/postshaders/phosphorish.glsl @@ -5,7 +5,7 @@ */ // modified by slime73 for use with love pixeleffects -vec3 to_focus(float pixel) +vec3 to_focus(highp float pixel) { pixel = mod(pixel + 3.0, 3.0); if (pixel >= 2.0) // Blue @@ -16,24 +16,24 @@ vec3 to_focus(float pixel) return vec3(1.0 - pixel, pixel, 0.0); } -vec4 effect(vec4 vcolor, Image texture, vec2 texture_coords, vec2 pixel_coords) +vec4 effect(vec4 vcolor, Image texture, highp vec2 texture_coords, vec2 pixel_coords) { - float y = mod(texture_coords.y * love_ScreenSize.y, 1.0); - float intensity = exp(-0.2 * y); + highp float y = mod(texture_coords.y * love_ScreenSize.y, 1.0); + highp float intensity = exp(-0.2 * y); - vec2 one_x = vec2(1.0 / (3.0 * love_ScreenSize.x), 0.0); + highp vec2 one_x = vec2(1.0 / (3.0 * love_ScreenSize.x), 0.0); - vec3 color = Texel(texture, texture_coords - 0.0 * one_x).rgb; - vec3 color_prev = Texel(texture, texture_coords - 1.0 * one_x).rgb; - vec3 color_prev_prev = Texel(texture, texture_coords - 2.0 * one_x).rgb; + highp vec3 color = Texel(texture, texture_coords - 0.0 * one_x).rgb; + highp vec3 color_prev = Texel(texture, texture_coords - 1.0 * one_x).rgb; + highp vec3 color_prev_prev = Texel(texture, texture_coords - 2.0 * one_x).rgb; - float pixel_x = 3.0 * texture_coords.x * love_ScreenSize.x; + highp float pixel_x = 3.0 * texture_coords.x * love_ScreenSize.x; - vec3 focus = to_focus(pixel_x - 0.0); - vec3 focus_prev = to_focus(pixel_x - 1.0); - vec3 focus_prev_prev = to_focus(pixel_x - 2.0); + highp vec3 focus = to_focus(pixel_x - 0.0); + highp vec3 focus_prev = to_focus(pixel_x - 1.0); + highp vec3 focus_prev_prev = to_focus(pixel_x - 2.0); - vec3 result = + highp vec3 result = 0.8 * color * focus + 0.6 * color_prev * focus_prev + 0.3 * color_prev_prev * focus_prev_prev; @@ -42,4 +42,3 @@ vec4 effect(vec4 vcolor, Image texture, vec2 texture_coords, vec2 pixel_coords) return vec4(intensity * result, 1.0); } - diff --git a/lib/shaders/postshaders/radialblur.glsl b/lib/shaders/postshaders/radialblur.glsl index 5c2a032..371be6b 100644 --- a/lib/shaders/postshaders/radialblur.glsl +++ b/lib/shaders/postshaders/radialblur.glsl @@ -6,15 +6,15 @@ extern number blurwidth = -0.02; // -1 to 1 vec4 effect(vec4 vcolor, Image texture, vec2 texture_coords, vec2 pixel_coords) { vec4 c = vec4(0.0, 0.0, 0.0, 1.0); - + int i; for (i = 0; i < nsamples; i++) { - number scale = blurstart + blurwidth * (i / float(nsamples-1)); + number scale = blurstart + blurwidth * (float(i) / float(nsamples-1)); c.rgb += Texel(texture, texture_coords * scale).rgb; } - - c.rgb /= nsamples; - + + c.rgb /= float(nsamples); + return c; } diff --git a/lib/shaders/reflection.glsl b/lib/shaders/reflection.glsl index 16c14e9..90753da 100644 --- a/lib/shaders/reflection.glsl +++ b/lib/shaders/reflection.glsl @@ -9,11 +9,11 @@ vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) { if(normal.a > 0.0 && normal.r > 0.0) { vec3 pColor = Texel(backBuffer, texture_coords).rgb; vec4 pColor2; - for(int i = 0; i < reflectionStrength; i++) { - pColor2 = Texel(texture, vec2(texture_coords.x, texture_coords.y + pSize.y * i)); + for(int i = 0; i < int(reflectionStrength); i++) { + pColor2 = Texel(texture, vec2(texture_coords.x, texture_coords.y + pSize.y * float(i))); if(pColor2.a > 0.0 && pColor2.g > 0.0) { - vec3 rColor = Texel(backBuffer, vec2(texture_coords.x, texture_coords.y + pSize.y * i * 2.0)).rgb; - return vec4(rColor, (1.0 - i / reflectionStrength) * reflectionVisibility); + vec3 rColor = Texel(backBuffer, vec2(texture_coords.x, texture_coords.y + pSize.y * float(i) * 2.0)).rgb; + return vec4(rColor, (1.0 - float(i) / reflectionStrength) * reflectionVisibility); } } return vec4(0.0); diff --git a/lib/shaders/shadow.glsl b/lib/shaders/shadow.glsl index 5bae828..81b17b7 100644 --- a/lib/shaders/shadow.glsl +++ b/lib/shaders/shadow.glsl @@ -32,7 +32,7 @@ vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) { pixel.rgb = lightColor * pow(att, lightSmooth); } } else { - vec3 normal = normalize(vec3(normalColor.r,invert_normal ? 1 - normalColor.g : normalColor.g, normalColor.b) * 2.0 - 1.0); + vec3 normal = normalize(vec3(normalColor.r,invert_normal ? 1.0 - normalColor.g : normalColor.g, normalColor.b) * 2.0 - 1.0); //on the normal map, draw normal shadows vec3 dir = vec3((lightPosition.xy - pixel_coords.xy) / love_ScreenSize.xy, lightPosition.z); dir.x *= love_ScreenSize.x / love_ScreenSize.y; @@ -47,4 +47,3 @@ vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) { return pixel; } } - diff --git a/lib/util.lua b/lib/util.lua index 7da2d50..d2c7d71 100644 --- a/lib/util.lua +++ b/lib/util.lua @@ -2,7 +2,7 @@ local util = {} --TODO: the whole stencil/canvas system should be reviewed since it has been changed in a naive way function util.process(canvas, options) - --TODO: now you cannot draw a canvas to itself + --TODO: now you cannot draw a canvas to itself temp = love.graphics.newCanvas() util.drawCanvasToCanvas(canvas, temp, options) util.drawCanvasToCanvas(temp, canvas, options) @@ -59,4 +59,41 @@ function util.drawto(canvas, x, y, scale, cb) love.graphics.pop() end +function util.loadShader(name) + local shader = "" + local externInit = {} + for line in love.filesystem.lines(name) do + + if line:sub(1,6) == "extern" then + local type, name = line:match("extern (%w+) (%w+)") + local value = line:match("=(.*);") + if value then + externInit[name] = {type=type, val=value} + line = line:match("extern %w+ %w+")..";" + end + end + shader = shader.."\n"..line + end + + local effect = love.graphics.newShader(shader) + for k, v in pairs(externInit) do + if v.type == "bool" then + effect:send(k, v.val) + elseif v.type == "int" or v.type == "uint" then + effect:sendInt(k, tonumber(v.val)) + elseif v.type == "float" or v.type == "double" or v.type == "number" then + effect:send(k, tonumber(v.val)) + elseif v.type:sub(1,3) == "vec" then + v.val = v.val:gsub(" ", ""):sub(6):sub(1, -2) + local next = v.val:gmatch("([^,]+)") + local values = {} + for n in next do + table.insert(values, tonumber(n)) + end + effect:send(k, values) + end + end + return effect +end + return util