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 - by Hgy29 ===
+
=== Shader 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">
Line 21: Line 21:
 
local coef = lF3(0.2125, 0.7154, 0.0721)
 
local coef = lF3(0.2125, 0.7154, 0.0721)
 
local dp = dot(frag.rgb, coef)
 
local dp = dot(frag.rgb, coef)
if fSwitch == 22 then -- switched via lua code
+
if fSwitch == 22.0 then -- switched via lua code
 
frag.rgb = mix(frag.rgb, frag.rgb / dp, frad)
 
frag.rgb = mix(frag.rgb, frag.rgb / dp, frad)
 
end
 
end
Line 35: Line 35:
 
{name="fTextureInfo", type=Shader.CFLOAT4, sys=Shader.SYS_TEXTUREINFO, 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="fTime", type=Shader.CFLOAT, sys=Shader.SYS_TIMER, vertex=false},
{name="fSwitch", type=Shader.CINT, vertex=false}, -- Uniform value will be changed in lua code
+
{name="fSwitch", type=Shader.CFLOAT, vertex=false}, -- Uniform value will be changed in lua code
 
},
 
},
 
{
 
{
Line 60: Line 60:
 
bmp:setShader(saturate)
 
bmp:setShader(saturate)
 
bmp2:setShader(saturate)
 
bmp2:setShader(saturate)
bmp:setShaderConstant("fSwitch", Shader.CINT, 1, 22) -- switch is on
+
bmp:setShaderConstant("fSwitch", Shader.CFLOAT, 1, 22.0) -- switch is on
bmp2:setShaderConstant("fSwitch", Shader.CINT, 1, -38) -- switch is off
+
bmp2:setShaderConstant("fSwitch", Shader.CFLOAT, 1, -38.0) -- switch is off
 
-- order
 
-- order
 
stage:addChild(bmp)
 
stage:addChild(bmp)

Revision as of 08:07, 7 November 2023

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

Shader 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}, -- Uniform value will be changed in lua code
	},
	{
	{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()
local bmp2 = Bitmap.new(tex, true)
-- 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)