Difference between revisions of "Lua Shader Examples"
From GiderosMobile
Line 8: | Line 8: | ||
'''''luashader'' standard library is available in your Gideros installation folder under ''Library''''' | '''''luashader'' standard library is available in your Gideros installation folder under ''Library''''' | ||
− | === Shader Saturate === | + | == Gideros Effects Shaders == |
+ | You can add these Effects Shader after those available in Gideros Lua Shader Examples ([[Lua Shader Gideros Examples]]). | ||
+ | |||
+ | To use them, simply add a Shader to a Sprite, for example: | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | local s = Pixel.new(256, 128, Texture.new("texture.jpg", false)) | ||
+ | s:setShader(Effect.palette) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Effect.palette === | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | -- cc0 @ https://godotshaders.com/shader/256-colour-pixelation/ | ||
+ | Effect.palette = makeEffect("palette", | ||
+ | function (vVertex, vColor, vTexCoord) : Shader | ||
+ | local vertex = hF4(vVertex, 0.0, 1.0) | ||
+ | fTexCoord = vTexCoord | ||
+ | return vMatrix * vertex | ||
+ | end, | ||
+ | function () : Shader | ||
+ | -- 0.100392156862 is the cube root of 255 | ||
+ | local rgb255 = lF3(0.100392156862, 0.100392156862, 0.100392156862) | ||
+ | local tc = fTexCoord - fTextureInfo.zw | ||
+ | local frag = lF4(fColor) * texture2D(fTexture, tc) | ||
+ | if(frag.r < 1.0 and frag.g < 1.0 and frag.b < 1.0) then | ||
+ | local remainder = mod(frag.rgb, rgb255) | ||
+ | frag.rgb = frag.rgb - remainder | ||
+ | end | ||
+ | -- emphasize | ||
+ | local e = 1.5 -- xemphasize | ||
+ | frag.rgb = lF3(frag.r^e, frag.g^e, frag.b^e) | ||
+ | if (frag.a == 0.0) then discard() end | ||
+ | return frag | ||
+ | end) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Effect.colour_pixelation === | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | Effect.colour_pixelation = makeEffect("colour_pixelation", | ||
+ | function (vVertex, vColor, vTexCoord) : Shader | ||
+ | local vertex = hF4(vVertex, 0.0, 1.0) | ||
+ | fTexCoord = vTexCoord | ||
+ | return vMatrix * vertex | ||
+ | end, | ||
+ | function () : Shader | ||
+ | local resX = 8*32 -- 8*32, 6*32, ... | ||
+ | local resY = 8*32 -- 8*32, 6*32, ... | ||
+ | -- 0.100392156862 is the cube root of 255 | ||
+ | local rgb255 = lF3(0.100392156862, 0.100392156862, 0.100392156862) | ||
+ | local uvX = fTexCoord.x - mod(fTexCoord.x * resX, 1) / resX | ||
+ | local uvY = fTexCoord.y - mod(fTexCoord.y * resY, 1) / resY | ||
+ | local grid_uv = lF2(uvX, uvY) | ||
+ | local frag = lF4(fColor) * texture2D(fTexture, grid_uv) | ||
+ | if(frag.r < 1.0 and frag.g < 1.0 and frag.b < 1.0) then | ||
+ | local remainder = mod(frag.rgb, rgb255) | ||
+ | frag.rgb = frag.rgb - remainder | ||
+ | end | ||
+ | -- emphasize | ||
+ | -- local e = 0.7 -- xemphasize, 0.8, 1 | ||
+ | -- frag.rgb = lF3(frag.r^e, frag.g^e, frag.b^e) | ||
+ | -- if (frag.a == 0.0) then discard() end | ||
+ | |||
+ | return frag | ||
+ | end) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Effect.outline === | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | -- @rrraptor V1 luau -- 1px outline | ||
+ | Effect.outline = makeEffect("outline", | ||
+ | function (vVertex, vColor, vTexCoord) : Shader | ||
+ | local vertex = hF4(vVertex, 0.0, 1.0) | ||
+ | fTexCoord = vTexCoord | ||
+ | return vMatrix * vertex | ||
+ | end, | ||
+ | function () : Shader | ||
+ | local outlinesize = 1.0 -- 1.0, 2.0 | ||
+ | local tc = fTexCoord - fTextureInfo.zw | ||
+ | local original = lF4(fColor) * texture2D(fTexture, tc) | ||
+ | if original.a == 0.0 then | ||
+ | local step = 1.57079632679 -- math.pi/2 -- perfect for 1 to 2 pixels outline | ||
+ | for theta = 0, 6.28318530718, step do -- 2 PI | ||
+ | local offset = lF2(fTextureInfo.z * cos(theta) * outlinesize, fTextureInfo.w * sin(theta) * outlinesize) | ||
+ | local frag = lF4(fColor) * texture2D(fTexture, tc+offset) | ||
+ | if not (frag.a == 0.0) then original = lF4(0.0, 0.0, 0.0, frag.a) end -- change outline color here | ||
+ | end | ||
+ | end | ||
+ | -- emphasize | ||
+ | local e = 1 | ||
+ | original.rgb = lF3(original.r^e, original.g^e, original.b^e) | ||
+ | if (original.a == 0.0) then discard() end | ||
+ | |||
+ | return original | ||
+ | end) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Effect.outline2 === | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | -- @rrraptor V1 -- thick pixel outline | ||
+ | Effect.outline2 = makeEffect("outline2", | ||
+ | function (vVertex, vColor, vTexCoord) : Shader | ||
+ | local vertex = hF4(vVertex, 0.0, 1.0) | ||
+ | fTexCoord = vTexCoord | ||
+ | return vMatrix * vertex | ||
+ | end, | ||
+ | function () : Shader | ||
+ | local outlinesize = 1.0 -- 1.0, 2.0 | ||
+ | local tc = fTexCoord - fTextureInfo.zw | ||
+ | local original = lF4(fColor) * texture2D(fTexture, tc) | ||
+ | if original.a == 0.0 then | ||
+ | for y = -1, 1 do | ||
+ | for x = -1, 1 do | ||
+ | local offset = lF2(fTextureInfo.z * x * outlinesize, fTextureInfo.w * y * outlinesize) | ||
+ | local frag = lF4(fColor) * texture2D(fTexture, tc+offset) | ||
+ | if not (frag.a == 0.0) then original = lF4(0.0, 0.0, 0.0, frag.a) end -- change outline color here | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | -- emphasize | ||
+ | local e = 1 | ||
+ | original.rgb = lF3(original.r^e, original.g^e, original.b^e) | ||
+ | if (original.a == 0.0) then discard() end | ||
+ | |||
+ | return original | ||
+ | end) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Effect.outline3 Colored === | ||
+ | <syntaxhighlight lang="lua"> | ||
+ | -- @rrraptor V1 -- thick pixel colored outline | ||
+ | Effect.outline3 = makeEffect("outline3", | ||
+ | function (vVertex, vColor, vTexCoord) : Shader | ||
+ | local vertex = hF4(vVertex, 0.0, 1.0) | ||
+ | fTexCoord = vTexCoord | ||
+ | return vMatrix * vertex | ||
+ | end, | ||
+ | function () : Shader | ||
+ | local outlinesize = 1.0 -- 1.0, 2.0 | ||
+ | local tc = fTexCoord - fTextureInfo.zw | ||
+ | local original = lF4(fColor) * texture2D(fTexture, tc) | ||
+ | if original.a == 0.0 then | ||
+ | local step = 1.57079632679 -- math.pi/2 -- perfect for 1 to 2 pixels outline | ||
+ | for theta = 0, 6.28318530718, step do -- 2 PI | ||
+ | local offset = lF2(fTextureInfo.z * cos(theta) * outlinesize, fTextureInfo.w * sin(theta) * outlinesize) | ||
+ | local frag = lF4(fColor) * texture2D(fTexture, tc+offset) | ||
+ | if not (frag.a == 0.0) then original = lF4(1.0, 1.0, 1.0, frag.a) end -- change outline color here | ||
+ | end | ||
+ | end | ||
+ | -- emphasize | ||
+ | local e = 1 | ||
+ | original.rgb = lF3(original.r^e, original.g^e, original.b^e) | ||
+ | if (original.a == 0.0) then discard() end | ||
+ | |||
+ | return original | ||
+ | end) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == Individual Shaders == | ||
+ | === Saturate === | ||
{{#widget:GApp|app=Playground_ShaderSaturate.GApp|width=480|height=320|auto=1}} | {{#widget:GApp|app=Playground_ShaderSaturate.GApp|width=480|height=320|auto=1}} | ||
<syntaxhighlight lang="lua"> | <syntaxhighlight lang="lua"> |
Latest revision as of 02:32, 27 March 2025
Parent: Writing Lua Shaders
Requirements: In order to use Lua Shaders you need to include luashader standard library in your projects luashader standard library is available in your Gideros installation folder under Library
Gideros Effects Shaders
You can add these Effects Shader after those available in Gideros Lua Shader Examples (Lua Shader Gideros Examples).
To use them, simply add a Shader to a Sprite, for example:
local s = Pixel.new(256, 128, Texture.new("texture.jpg", false))
s:setShader(Effect.palette)
Effect.palette
-- cc0 @ https://godotshaders.com/shader/256-colour-pixelation/
Effect.palette = makeEffect("palette",
function (vVertex, vColor, vTexCoord) : Shader
local vertex = hF4(vVertex, 0.0, 1.0)
fTexCoord = vTexCoord
return vMatrix * vertex
end,
function () : Shader
-- 0.100392156862 is the cube root of 255
local rgb255 = lF3(0.100392156862, 0.100392156862, 0.100392156862)
local tc = fTexCoord - fTextureInfo.zw
local frag = lF4(fColor) * texture2D(fTexture, tc)
if(frag.r < 1.0 and frag.g < 1.0 and frag.b < 1.0) then
local remainder = mod(frag.rgb, rgb255)
frag.rgb = frag.rgb - remainder
end
-- emphasize
local e = 1.5 -- xemphasize
frag.rgb = lF3(frag.r^e, frag.g^e, frag.b^e)
if (frag.a == 0.0) then discard() end
return frag
end)
Effect.colour_pixelation
Effect.colour_pixelation = makeEffect("colour_pixelation",
function (vVertex, vColor, vTexCoord) : Shader
local vertex = hF4(vVertex, 0.0, 1.0)
fTexCoord = vTexCoord
return vMatrix * vertex
end,
function () : Shader
local resX = 8*32 -- 8*32, 6*32, ...
local resY = 8*32 -- 8*32, 6*32, ...
-- 0.100392156862 is the cube root of 255
local rgb255 = lF3(0.100392156862, 0.100392156862, 0.100392156862)
local uvX = fTexCoord.x - mod(fTexCoord.x * resX, 1) / resX
local uvY = fTexCoord.y - mod(fTexCoord.y * resY, 1) / resY
local grid_uv = lF2(uvX, uvY)
local frag = lF4(fColor) * texture2D(fTexture, grid_uv)
if(frag.r < 1.0 and frag.g < 1.0 and frag.b < 1.0) then
local remainder = mod(frag.rgb, rgb255)
frag.rgb = frag.rgb - remainder
end
-- emphasize
-- local e = 0.7 -- xemphasize, 0.8, 1
-- frag.rgb = lF3(frag.r^e, frag.g^e, frag.b^e)
-- if (frag.a == 0.0) then discard() end
return frag
end)
Effect.outline
-- @rrraptor V1 luau -- 1px outline
Effect.outline = makeEffect("outline",
function (vVertex, vColor, vTexCoord) : Shader
local vertex = hF4(vVertex, 0.0, 1.0)
fTexCoord = vTexCoord
return vMatrix * vertex
end,
function () : Shader
local outlinesize = 1.0 -- 1.0, 2.0
local tc = fTexCoord - fTextureInfo.zw
local original = lF4(fColor) * texture2D(fTexture, tc)
if original.a == 0.0 then
local step = 1.57079632679 -- math.pi/2 -- perfect for 1 to 2 pixels outline
for theta = 0, 6.28318530718, step do -- 2 PI
local offset = lF2(fTextureInfo.z * cos(theta) * outlinesize, fTextureInfo.w * sin(theta) * outlinesize)
local frag = lF4(fColor) * texture2D(fTexture, tc+offset)
if not (frag.a == 0.0) then original = lF4(0.0, 0.0, 0.0, frag.a) end -- change outline color here
end
end
-- emphasize
local e = 1
original.rgb = lF3(original.r^e, original.g^e, original.b^e)
if (original.a == 0.0) then discard() end
return original
end)
Effect.outline2
-- @rrraptor V1 -- thick pixel outline
Effect.outline2 = makeEffect("outline2",
function (vVertex, vColor, vTexCoord) : Shader
local vertex = hF4(vVertex, 0.0, 1.0)
fTexCoord = vTexCoord
return vMatrix * vertex
end,
function () : Shader
local outlinesize = 1.0 -- 1.0, 2.0
local tc = fTexCoord - fTextureInfo.zw
local original = lF4(fColor) * texture2D(fTexture, tc)
if original.a == 0.0 then
for y = -1, 1 do
for x = -1, 1 do
local offset = lF2(fTextureInfo.z * x * outlinesize, fTextureInfo.w * y * outlinesize)
local frag = lF4(fColor) * texture2D(fTexture, tc+offset)
if not (frag.a == 0.0) then original = lF4(0.0, 0.0, 0.0, frag.a) end -- change outline color here
end
end
end
-- emphasize
local e = 1
original.rgb = lF3(original.r^e, original.g^e, original.b^e)
if (original.a == 0.0) then discard() end
return original
end)
Effect.outline3 Colored
-- @rrraptor V1 -- thick pixel colored outline
Effect.outline3 = makeEffect("outline3",
function (vVertex, vColor, vTexCoord) : Shader
local vertex = hF4(vVertex, 0.0, 1.0)
fTexCoord = vTexCoord
return vMatrix * vertex
end,
function () : Shader
local outlinesize = 1.0 -- 1.0, 2.0
local tc = fTexCoord - fTextureInfo.zw
local original = lF4(fColor) * texture2D(fTexture, tc)
if original.a == 0.0 then
local step = 1.57079632679 -- math.pi/2 -- perfect for 1 to 2 pixels outline
for theta = 0, 6.28318530718, step do -- 2 PI
local offset = lF2(fTextureInfo.z * cos(theta) * outlinesize, fTextureInfo.w * sin(theta) * outlinesize)
local frag = lF4(fColor) * texture2D(fTexture, tc+offset)
if not (frag.a == 0.0) then original = lF4(1.0, 1.0, 1.0, frag.a) end -- change outline color here
end
end
-- emphasize
local e = 1
original.rgb = lF3(original.r^e, original.g^e, original.b^e)
if (original.a == 0.0) then discard() end
return original
end)
Individual Shaders
Saturate
function vssaturate(vVertex, vColor, vTexCoord) : Shader
local vertex = hF4(vVertex, 0.0, 1.0)
fTexCoord = vTexCoord
return vMatrix * vertex
end
function fssaturate() : Shader
local frad = (1 + sin(fTime*7)) * 0.5
local frag = lF4(fColor) * texture2D(fTexture, fTexCoord)
local coef = lF3(0.2125, 0.7154, 0.0721)
local dp = dot(frag.rgb, coef)
if fSwitch == 22.0 then -- switched via lua code
frag.rgb = mix(frag.rgb, frag.rgb / dp, frad)
end
if (frag.a == 0.0) then discard() end
return frag
end
local saturate = Shader.lua(vssaturate, fssaturate, 0,
{
{name="vMatrix", type=Shader.CMATRIX, sys=Shader.SYS_WVP, vertex=true},
{name="fColor", type=Shader.CFLOAT4, sys=Shader.SYS_COLOR, vertex=false},
{name="fTexture", type=Shader.CTEXTURE, vertex=false},
{name="fTextureInfo", type=Shader.CFLOAT4, sys=Shader.SYS_TEXTUREINFO, vertex=false},
{name="fTime", type=Shader.CFLOAT, sys=Shader.SYS_TIMER, vertex=false},
{name="fSwitch", type=Shader.CFLOAT, vertex=false}, -- CFLOAT type to be more platforms compliant
},
{
{name="vVertex", type=Shader.DFLOAT, mult=2, slot=0, offset=0},
{name="vColor", type=Shader.DUBYTE, mult=4, slot=1, offset=0},
{name="vTexCoord", type=Shader.DFLOAT, mult=2, slot=2, offset=0},
},
{
{name="fTexCoord", type=Shader.CFLOAT2},
}
)
-- bg color
application:setBackgroundColor(0x909090)
-- a texture and a bitmap
local tex = Texture.new("gfx/test.png")
local bmp = Bitmap.new(tex, true)
local bmp2 = bmp:clone()
-- position
bmp:setPosition(32*4, 32*4)
bmp2:setPosition(32*4, 32*8)
-- lua shader
bmp:setShader(saturate)
bmp2:setShader(saturate)
bmp:setShaderConstant("fSwitch", Shader.CFLOAT, 1, 22.0) -- switch is on
bmp2:setShaderConstant("fSwitch", Shader.CFLOAT, 1, -38.0) -- switch is off
-- order
stage:addChild(bmp)
stage:addChild(bmp2)
-- loop
stage:addEventListener(Event.ENTER_FRAME, function(e)
bmp:setX(bmp:getX() + 0.5)
if bmp:getX() > 400 then bmp:setX(-80) end
end)
Rain drops demo - by Hgy29
Rain drops shader effect
-- Custom shader for a plain colored pixel (BASIC PROGRAM)
local shader=StandardShaders:getShaderSpecification(Shader.SHADER_PROGRAM_BASIC)
-- We will need vertex position in fragment shader
function shader:vertexShader(vVertex,vColor,vTexCoord) : Shader
local vertex = hF4(vVertex,0.0,1.0)
fVertex=vVertex.xy
return vMatrix*vertex
end
-- Fragment shader will compute caustics and ripples
function shader:fragmentShader() : Shader
local tp = hF2(1.0/32.0,1.0/16.0)
local mt = fVertex/1024.0
local p = mod(mt*6.28, 6.28)-360.0
local i = p
local c = 1.0
local inten = .005
for n=1,3 do
local t = fTime*0.5 * (1.0 - (3.0 / hF1(n)))
i = p + hF2(cos(t - i.x) + sin(t + i.y), sin(t - i.y) + cos(t + i.x))
c += 1.0/length(hF2(p.x / (sin(i.x+t)/inten),p.y / (cos(i.y+t)/inten)))
end
for n=1,32 do
local fr=fRippleT[n]
if (fr>0.0) then
local pd=length(fVertex-fRippleC[n])
local rd=1.0-smoothstep(0.0,128.0,pd)
if (rd>0.0) then
local td=(fTime-fr)*10.0
local dr=min(1.0,max(0.0,1.0-abs(td-(1.0-rd)*20.0)/10.0))
c+=sin(rd*20.0+td)*rd*dr
end
end
end
c /= 3
c = (1.5-c^.5)^4
return lF4((hF4(c,c,c,1.0) + hF4(0.0, 0.3, 0.5, 1.0))*fColor)
end
-- Add our custom constants and inter-stage varibale
local NDROPS=32
table.insert(shader.uniforms,{name="fRippleC",type=Shader.CFLOAT2,vertex=false,mult=NDROPS})
table.insert(shader.uniforms,{name="fTime",type=Shader.CFLOAT,sys=Shader.SYS_TIMER,vertex=false})
table.insert(shader.uniforms,{name="fRippleT",type=Shader.CFLOAT,vertex=false,mult=NDROPS})
table.insert(shader.varying,{name="fVertex",type=Shader.CFLOAT2})
-- A plain blue screen wide Pixel with our shader
local ax,ay,aw,ah=application:getLogicalBounds()
local p=Pixel.new(0x5678CD,1,aw-ax,ah-ay) p:setPosition(ax,ay)
p:setShader(shader:build())
stage:addChild(p)
-- Main loop: create random rain drops
local drop=0
local dropsP,dropsT={},{}
for i=1,NDROPS do dropsP[i*2-1]=0 dropsP[i*2]=0 dropsT[i]=0 end
Core.asyncCall(function()
while true do
Core.yield(.05)
drop+=1
if drop==(NDROPS+1) then drop=1 end
dropsP[drop*2-1]=math.random(aw-ax)
dropsP[drop*2]=math.random(ah-ay)
dropsT[drop]=os:timer()
p:setShaderConstant("fRippleC",Shader.CFLOAT2,NDROPS,dropsP)
p:setShaderConstant("fRippleT",Shader.CFLOAT,NDROPS,dropsT)
end
end)