Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
GIDEROS LUA SHADERS DISCOVERY — Gideros Forum

GIDEROS LUA SHADERS DISCOVERY

MoKaLuxMoKaLux Member
edited July 19 in Relax cafe
Ok, time to have some more fun with gideros: GIDEROS LUA SHADERS B)

I am playing around to see what I can understand from the gideros lua shader demo.
I have mixed two shaders wave + bloom and I see that I can get the outline of the character already :smile:
So my goal has become to "code" a shader to have the outline of my character :wink:
Please don't help me yet.
Relax cafe category
my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
+1 -1 (+2 / -0 )Share on Facebook

Comments

  • MoKaLuxMoKaLux Member
    edited April 2021
    still trying to understand shaders :#
    For normal shaders (glsl for example), I need 2 files: 1 for the vertex shader and 1 for the fragment shader. Then we pass them to Shader.new(...).

    For lua shaders, we must include (or link to) Gideros\Library\luashader files in our projects. Then we write our vertex shader and our fragment shader in lua. Then lua shaders calls Shader.new(...).

    Is that correct? I am trying to sort out shaders in the wiki :*

    PS: there is a typo in luashader.lua?
    function Shader.lua(vf,ff,opt,uniforms,attrs,varying,funcs,const,debug)
    	local lang=Shader.getShaderLanguage()
    	local mtd=Shader["lua_"..lang]
    	assert(mtd,"Language not supported: "..lang)
    	local _vshader,_fshader=mtd(vf,ff,opt,uniforms,attrs,varying,funcs or {},const)
    	if funcs then for _,fg in ipairs(funcs) do fg.code=nil end end
    	if debug then print("VSHADER_CODE:\n".._vshader) print("FSHADER_CODE:\n".._fshader) end
    	if not vdebug then return Shader.new(_vshader,_fshader,Shader.FLAG_FROM_CODE|opt,uniforms,attrs) end
    end
    vdebug is never declared?
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • hgy29hgy29 Maintainer
    Oops, a left-over of a debug. The whole condition should be removed.

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • MoKaLuxMoKaLux Member
    edited March 2022
    I need your help guys implementing a shader which draws an outline of a sprite, shader experts to the rescue please o:)

    I have this old outline shader made by great mister rrraptor :)
    --!NEEDS:luashader/luashader.lua
     
    local function makeEffect(name, vshader, fshader)
    ...
    end
     
    Effect={}
     
    -- <a href="http://forum.gideros.rocks/profile/rrraptor" rel="nofollow">@rrraptor</a> V1 -- 1px outline
    Effect.outline = makeEffect(
    	"Outline",
    	function (vVertex, vColor, vTexCoord)
    		local vertex = hF4(vVertex, 0.0, 1.0)
    		fTexCoord = vTexCoord
    		return vMatrix*vertex
    	end,
    	function ()
    		local outlinesize = 1
    		local tc = fTexCoord - fTextureInfo.zw
    		local original = lF4(fColor) * texture2D(fTexture, tc)
    		if original.a == 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 frag.a ~= 0 then
    					original = lF4(0, 0, 0, frag.a) -- change outline color here
    				end
    			end
    		end
    		return original
    	end
    )
    It works great prior gideros 2022.1. My problem is I still don't understand nothing about shaders and I would like to port it to newer gideros version 2022.3.1 :s

    This is my attempt but gideros doesn't like it and throws errors:
    local Outline1Effect=Core.class(ShaderEffect)
    ShaderEffect.Outline1=Outline1Effect
     
    makeEffect("Outline1", vertexShader,
    	function (vVertex, vColor, vTexCoord): Shader
    		local vertex = hF4(vVertex, 0.0, 1.0)
    		fTexCoord = vTexCoord
    		return vMatrix*vertex
     
    THIS HAS BEEN REMOVED, NSFW ;-)
    I tried to understand the other shaders as an example but I couldn't wrap my head around those, somebody please help me ;)

    Likes: SinisterSoft

    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
    +1 -1 (+1 / -0 )Share on Facebook
  • MoKaLuxMoKaLux Member
    edited March 2022
    oh that works :o and it was easier than I thought ;)

    hgy29 you are so kind to us, I knew it since day 1 but this shader thing, you gave everything to make our lifes simpler. I trully respect the LOVE you put in gideros and its users (us). So thank you, thank you, thank you.

    After starting afresh I realised I had everything at my disposal in the gideros samples ;)

    So I picked the shader example and it was using the same logic as previous gideros (which I was more used to) with minor tweaks. And, to my surprise, I had clear explanations of what was not working!!! (hgy29 super kindness in action):

    1st attempt:
    FragmentShader:
    0(28) : error C0000: syntax error, unexpected '~', expecting ',' or ')' at token "~"
    0(34) : error C1503: undefined variable "original"
    0(36) : error C0000: syntax error, unexpected '}' at token "}"

    2nd attempt:
    FragmentShader:
    0(28) : error C7011: implicit cast from "float" to "bool"
    0(28) : error C1020: invalid operands to "=="

    And the working result:
    Effect={}
     
    -- <a href="http://forum.gideros.rocks/profile/hgy29" rel="nofollow">@hgy29</a>
    Effect.none=makeEffect("None",
    	function (vVertex,vColor,vTexCoord) : Shader
    		local vertex = hF4(vVertex,0.0,1.0)
    		fTexCoord=vTexCoord
    		return vMatrix*vertex
    	end,
    	function () : Shader
    		local frag=lF4(fColor)*texture2D(fTexture, fTexCoord)
    		if (frag.a==0.0) then discard() end
    		return frag
    	end)	
     
    -- <a href="http://forum.gideros.rocks/profile/rrraptor" rel="nofollow">@rrraptor</a> 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
    		local tc=fTexCoord-fTextureInfo.zw
    		local original=lF4(fColor)*texture2D(fTexture, tc)
    		if (original.a==0) then
    			local step = 1.57079632679 -- math.pi/2 -- perfect for 1 to 2 pixels outline
    --			local step = 0.78539816339 -- math.pi/4 -- perfect for 3 to 4 pixels outline
    --			local step = 0.39269908169 -- PI/8 -- ok for 4+ 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 frag.a ~= 0 then
    --				if (not frag.a == 0) then
    				if frag.a==0 then --discard()
    				else original=lF4(0,0,0, frag.a) -- change outline color here
    				end
    			end
    		end
    		return original
    	end)
    I will let you do the cleaning :p

    I wish you all the best, a special thought for our friend Oleg and his people, and my best wishes to you Nicolas (alias hgy29) o:)

    PS: this outline shader is the work of genius mister RRRAPTOR, THANK YOU!

    Viva Gideros Luau, Peace & <3

    Likes: SinisterSoft

    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
    +1 -1 (+1 / -0 )Share on Facebook
  • and here is a sample use case:
    function TheStage:xRenderTarget()
    	-- first render target so we can apply shaders
    	local rt = RenderTarget.new(self.canvasw or 8, self.canvash or 8)
    	local rbmp = Bitmap.new(rt)
    	rt:clear(0x0, 0)
    	rt:draw(self.camera.view)
    	if self.outline then rbmp:setShader(Effect.outline) end
    	-- then the actual output image
    	self.rt2:clear(0x0, 0)
    	self.rt2:draw(rbmp)
    	self.bmprt:setTexture(self.rt2) -- to show actual frame in the app (not needed for the output image)
    end
    ...

    Likes: SinisterSoft

    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
    +1 -1 (+1 / -0 )Share on Facebook
  • hgy29hgy29 Maintainer
    Accepted Answer
    I think there is a bug in the luau shader compiler, it doesn’t seem to translate properly the ~= operator into != in C
  • YanYan Member
    Accepted Answer
    spriteOutline = {}
     
    spriteOutline.VS_GL = [[
     
    	uniform highp mat4 vMatrix;
     
    	attribute highp vec3 vVertex;
    	attribute mediump vec2 vTexCoord;
     
    	varying mediump vec2 fTexCoord;
     
    	void main() {
    		vec4 vertex = vec4(vVertex, 1.0);
    		gl_Position = vMatrix*vertex;
    		fTexCoord = vTexCoord;
    	}
    ]]
     
    spriteOutline.FS_GL = [[
     
    	#ifdef GL_ES
    		precision highp float;
    	#endif
     
    	const float offseta = 0.010;
     
    	uniform lowp vec4 fColor;
    	uniform mediump vec4 fTexSize;
    	uniform lowp sampler2D fTexture;
     
    	uniform lowp int fSwitch;
     
    	varying mediump vec2 fTexCoord;
     
    	vec4 getSample(float x, float y, float offset, float num)
    	{
    		vec4 result = vec4(0);
    		float size = 360.0 / num;
     
    		for (float a; a <= 360.0; a += size)
    		{
    			vec2 coord = vec2(cos(a) * offset + x, sin(a) * offset + y);
     
    			result += texture2D(fTexture, coord);
    		}
     
    		return result;
    	}
     
    	void main()
    	{
    		vec4 col = texture2D(fTexture, fTexCoord);
     
    		float nums = 32.0;
     
    		if (fSwitch == 1)
    		{
    			vec4 nb = getSample(fTexCoord.x, fTexCoord.y, 0.020, nums);
     
    			if (col.a > 0. && nb.a < nums)
    			{
    				col.a = nb.a / nums;
    				col.r = nb.a / nums;
    				col.g = 0.0;
    				col.b = 0.0;
    			}
    		}
     
    		gl_FragColor = col;
    	}
    ]]
     
    spriteOutline.Shader=Shader.new(spriteOutline.VS_GL,spriteOutline.FS_GL,Shader.FLAG_FROM_CODE, {
    	{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="fSwitch",type=Shader.CINT,vertex=false},
    },
    {
    	{name="vVertex",type=Shader.DFLOAT,mult=3,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},
    });
    Thats all.

    Likes: MoKaLux, talis, hito9

    vk.com/yan_alex
    +1 -1 (+3 / -0 )Share on Facebook
  • MoKaLuxMoKaLux Member
    edited June 2022
    dear gideros people, do you know if it is possible to change the lighting color in the 3dbase shader (3DLighting.lua)?
    There are those values
    	local color0 = lF4(g_Color)
    local LightingShaderConstants={ -- I can add my own variables here (for example specular...) XXX
    {name="g_MVPMatrix",type=Shader.CMATRIX,sys=Shader.SYS_WVP, vertex=true},
    {name="g_MVMatrix",type=Shader.CMATRIX,sys=Shader.SYS_WORLD, vertex=true},
    {name="g_NMatrix",type=Shader.CMATRIX,sys=Shader.SYS_WIT3, vertex=true},
    {name="g_LMatrix",type=Shader.CMATRIX, vertex=true},
    {name="g_Color",type=Shader.CFLOAT4,mult=1,sys=Shader.SYS_COLOR},
    ...
    	if OPT_TEXTURED then color0 = color0*texture2D(g_Texture,texCoord) end
    	local color1 = lF3(0.5, 0.5, 0.5)
    	local normal = normalize(normalCoord)
     
    	local diff = max(0.0, dot(normal, lightDir))
    	local spec =0.0 -- specular XXX
        -- calculate shadow
    	local shadow=1.0
    	if OPT_SHADOWS then shadow = ShadowCalculation(lightSpace,FragCoord) end
    	if (diff>=1) then -- 0 = ugly light halo!, >=1 = no ugly light halo! new 20220629 XXX
    		local nh = max(0.0, dot(reflect(-lightDir,normal),viewDir))
    		spec = pow(nh, 32.0)*shadow -- specular default = 32 (good value)
    	end
     
    	diff=max(diff*shadow,ambient);
    	local frag = lF4(color0.rgb * diff + color1 * spec, color0.a)
    	return frag
    I believe the light color is WHITE but I don't see anywhere in the shader files where the color is set :| (3DShaders.lua, luashader.lua, ... ?)

    Can somebody point me in the right direction? Thank you for your help :)
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • MoKaLuxMoKaLux Member
    edited January 2023
    MoKaLux said:

    dear gideros people, do you know if it is possible to change the lighting color in the 3dbase shader (3DLighting.lua)?

    A beginning of an answer :) it seems to be in 3DShaders.lua
    	local color0 = lF4(g_Color)
    	local mycolor = lF4(1.0,0.0,0.0,1.0) --< here?
    --	if OPT_TEXTURED then color0 = color0*texture2D(g_Texture,texCoord) end
    	if OPT_TEXTURED then color0 = color0*texture2D(g_Texture,texCoord)*mycolor end
    to be continued...
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • MoKaLuxMoKaLux Member
    edited January 2023
    How could I pass some external values (parameters) to work in this lua shader please?
    3DShaders.lua
    function D3._FLUA_Shader() : Shader
    	--mat3 cotangent_frame(vec3 N, vec3 p, vec2 uv)
    	function cotangent_frame(N,p,uv)
    		--// récupère les vecteurs du triangle composant le pixel
    		local dp1 = dFdx( p )
    ...
    	end
     
    	--vec3 perturb_normal( vec3 N, vec3 V, vec2 texcoord )
    	function perturb_normal( N, V, texcoord )
    		--// N, la normale interpolée et
    		--// V, le vecteur vue (vertex dirigé vers l'œil)
    		local ret=hF3(0,0,0)
    ...
    	end
    ...
    	if OPT_NORMMAP then normal=perturb_normal(normal, viewDir, texCoord) end
     
    	local diff = max(0.0, dot(normal, lightDir)) -- 0.0 => CHANGE THIS ONE?
    	local spec = 0.0 --			=> MAYBE THIS ONE TOO?
        -- calculate shadow
    	local shadow=1.0 -- 1.0, 0.5, -- this seems to control the shadow width, in practice this blows the light!
    	if (diff>=1) then
    		local nh = max(0.0, dot(reflect(-lightDir,normal),viewDir))
    		spec = pow(nh, 64.0)*shadow --  => 64.0 AND MAYBE THIS ONE TOO?
    	end
    	diff=max(diff*shadow,ambient);
     
    	local frag = lF4(color0.rgb * diff + color1 * spec, color0.a)
     
    	return frag
    end
    Some pointers please :) Thank you o:)

    EDIT: https://wiki.gideros.rocks/index.php/Shader:setConstant :D

    Likes: pie

    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
    +1 -1 (+1 / -0 )Share on Facebook
  • hgy29hgy29 Maintainer
    Accepted Answer
    Yes, you can use Shader.setConstant if you want to set a property on a shader for all sprites that use this shader, or Sprite:setShaderConstant if you want to set a constant specifically for a given Sprite

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • MoKaLuxMoKaLux Member
    edited July 19
    in Lua Shader, how can I use round, trunc, ..?

    round round(x) Returns a value equal to the nearest integer to x.
    https://wiki.gideros.rocks/index.php/Lua_Shader_Common_Functions

    Some functions seem not implemented?

    I tried with this code:
    frag.r += (round(frag.r * colors - dither) / colors) * c
    frag.g += (round(frag.g * colors - dither) / colors) * c
    frag.b += (round(frag.b * colors - dither) / colors) * c
    --frag.r += (floor(frag.r * colors - dither) / colors) * c -- this works
    Error: luashader/luau_codegen.lua:54: Unknown global round

    I tried with math.round but not working :p

    Is there a work around please?

    EDIT: looking into luashader.lua
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • hgy29hgy29 Maintainer
    @MoKaLux,

    Shaders have floor() and ceil(), so trunc(n)=floor(n) if n is positive or ceil(n) otherwise.
    round(n) is same as floor(n+0.5) for n positive and ceil(n+0.5) for n negative.

    But you can add bindings for trunc and floor in luashader.lua, for all three languages (GLSL,HLSL and MSL)

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • MoKaLuxMoKaLux Member
    edited July 19
    thank you hgy29, I almost got this cc0 godot shader working in Gideros :)
    https://godotshaders.com/shader/color-reduction-and-dither/#comment-1927

    Gideros:
    -- attempted gideros
    Effect.emphasize = makeEffect("emphasize",
    	function (vVertex, vColor, vTexCoord) : Shader
    		local vertex = hF4(vVertex, 0.0, 1.0)
    		fTexCoord = vTexCoord
    		fVertex=vVertex.xy
    		return vMatrix * vertex
    	end,
    	function () : Shader
    --		local colors = lF2(1.0, 16.0)
    --		local dither = lF2(0.0, 0.5)
    		local colors = lF1(8.0) -- 8.0
    		local dither = lF1(0.5) -- 0.25
    		local frag = lF4(fColor) * texture2D(fTexture, fTexCoord)
    --		local a = floor(mod(UV.x / TEXTURE_PIXEL_SIZE.x, 2.0))
    --		local b = floor(mod(UV.y / TEXTURE_PIXEL_SIZE.y, 2.0))
    --		local a = floor(mod(fVertex.x / fTextureInfo.x, 2.0))
    --		local b = floor(mod(fVertex.y / fTextureInfo.y, 2.0))
    		local a = floor(mod(fVertex.x / fTextureInfo.x, 2.0))
    		local b = floor(mod(fVertex.y / fTextureInfo.y, 2.0))
    		local c = mod(a + b, 2.0) -- 2.0
     
    --		frag.r = (round(frag.r * colors + dither) / colors) * c
    --		frag.g = (round(frag.g * colors + dither) / colors) * c
    --		frag.b = (round(frag.b * colors + dither) / colors) * c
    		frag.r = ((floor(frag.r * colors + dither)+0.5) / colors) * c
    		frag.g = ((floor(frag.g * colors + dither)+0.5) / colors) * c
    		frag.b = ((floor(frag.b * colors + dither)+0.5) / colors) * c
    		c = 1.0 - c
    		if c < 0 then
    --			frag.r += (round(frag.r * colors - dither) / colors) * c
    --			frag.g += (round(frag.g * colors - dither) / colors) * c
    --			frag.b += (round(frag.b * colors - dither) / colors) * c
    			frag.r += ((ceil(frag.r * colors - dither)+0.5) / colors) * c
    			frag.g += ((ceil(frag.g * colors - dither)+0.5) / colors) * c
    --			frag.b += (floor(fColor.b * colors - dither) / colors) * c
    			frag.b += ((ceil(frag.b * colors - dither)+0.5) / colors) * c
    		else
    --			frag.r += (round(frag.r * colors - dither) / colors) * c
    --			frag.g += (round(frag.g * colors - dither) / colors) * c
    --			frag.b += (round(frag.b * colors - dither) / colors) * c
    			frag.r += ((floor(frag.r * colors - dither)+0.5) / colors) * c
    			frag.g += ((floor(frag.g * colors - dither)+0.5) / colors) * c
    --			frag.b += (floor(fColor.b * colors - dither) / colors) * c
    			frag.b += ((floor(frag.b * colors - dither)+0.5) / colors) * c
    		end
     
    		if (frag.a == 0.0) then discard() end
    		return frag
    	end)


    I think I got this cc0 one working as expected?
    https://godotshaders.com/shader/256-colour-pixelation/
    Gideros:
    Effect.colour_pixelation2 = makeEffect("colour_pixelation2",
    	function (vVertex, vColor, vTexCoord) : Shader
    		local vertex = hF4(vVertex, 0.0, 1.0)
    		fTexCoord = vTexCoord
    		return vMatrix * vertex
    	end,
    	function () : Shader
    		local resX = 128.0 -- 32
    		local resY = 128.0 -- 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 = lF1(1.15)
    		frag.rgb = lF3(frag.r^e, frag.g^e, frag.b^e)
    		if (frag.a == 0.0) then discard() end
     
    		return frag
    	end)


    Viva Gideros <3
    Oil_0026.png
    78 x 180 - 5K
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
Sign In or Register to comment.