Difference between revisions of "Writing Lua Shaders"
(2 intermediate revisions by the same user not shown) | |||
Line 3: | Line 3: | ||
== Lua Shaders == | == 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''''' | ||
When you write your shaders in '''Lua''', they will be automatically translated to the relevant shader Language for the platform you are using (eg GLSL, HLSL or MSL). This is the '''recommended''' way to write your shaders in Gideros. | When you write your shaders in '''Lua''', they will be automatically translated to the relevant shader Language for the platform you are using (eg GLSL, HLSL or MSL). This is the '''recommended''' way to write your shaders in Gideros. | ||
Line 117: | Line 120: | ||
=== Lua Shader Examples === | === Lua Shader Examples === | ||
− | '''[[ | + | '''[[Lua Shader Examples]]'''</br> |
=== Further Reading === | === Further Reading === | ||
Line 124: | Line 127: | ||
The Book of Shaders: '''https://thebookofshaders.com/'''</br> | The Book of Shaders: '''https://thebookofshaders.com/'''</br> | ||
ShaderToy: '''https://www.shadertoy.com/'''</br> | ShaderToy: '''https://www.shadertoy.com/'''</br> | ||
+ | GH: '''https://github.com/mattdesl/lwjgl-basics/wiki/Shaders'''</br> | ||
{{SHADERS}} | {{SHADERS}} |
Latest revision as of 10:31, 7 November 2023
Parent: Shaders
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
When you write your shaders in Lua, they will be automatically translated to the relevant shader Language for the platform you are using (eg GLSL, HLSL or MSL). This is the recommended way to write your shaders in Gideros.
The Shader API allows the creation of Shader objects from within Lua. The Shader.lua() constructor takes five arguments:
- the Vertex shader code (a lua function)
- the Fragment shader code (a lua function)
- a set of numerical flags or 0 if none
- an array of uniforms/constants descriptors
- an array of attributes descriptors
With Lua Shaders, it is assumed that the code is within the Vertex and Fragment parameter functions.
A typical Lua Vertex and Fragment shader code looks like:
function vssaturate(vVertex, vColor, vTexCoord) : Shader -- Vertex Shader
local vertex = hF4(vVertex, 0.0, 1.0)
fTexCoord = vTexCoord
return vMatrix * vertex
end
function fssaturate() : Shader -- Fragment Shader
local frad = (1 + sin(fTime)) * 0.5
local frag = lF4(fColor) * texture2D(fTexture, fTexCoord)
local coef = lF3(0.2125, 0.7154, 0.0721)
local dp = dot(frag.rgb, coef)
frag.rgb = mix(frag.rgb, frag.rgb / dp, frad)
if (frag.a == 0.0) then discard() end
return frag
end
Once both functions are created, you pass them in Shader.lua:
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 = "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},
}
)
Changing Uniforms/Constants
In order to change the value of a uniform from Lua, you use the setConstant function on the Shader, it takes four arguments:
- the uniform name
- the type of data to set: one of the Shader.Cxxx constants
- the number of elements of the given type to set (number)
- the actual data to set, either as a table or as multiple arguments
saturate:setConstant("fSwitch", Shader.CINT, 1, 0) -- set fSwitch value to be 0 (off)
This will change the value of a Uniform for the whole Shader.
You can also change the value of a Uniform on a sprite to sprite basis using Sprite:setShaderConstant:
bmp:setShaderConstant("fSwitch", Shader.CINT, 1, 22) -- set fSwitch value to be 0 (on)
Associating a Shader to a Sprite
The Sprite API has a new call to deal with that: Sprite:setShader(shader) tells Gideros to use the specified shader for rendering the sprite. Setting back the shader to nil actually revert to the default shader.
bmp:setShader(saturate)
Lua Shader Functions
(Please note that these functions may or may not be available, the Lua shader is still under development)
Restrictions
Don't rely on anything external, basically no globals except for attributes, uniforms and varying.
- No Do..While
- No Repeat..Until
- No tables. The only allowed form of table lookup is for vector component swizzling and access to uniform arrays
- No strings, userdata, etc. Basically only numbers are supported
- Mind your types! Although lua is not a typed language, shaders need types
- Always check on all platforms: Gideros will translate your lua code to GLSL,HLSL or MSL code, but some platforms are more strict than others about what you can write, or how many arguments a common function is supposed to take
Lua Shader Examples
Further Reading
OpenGL Shading Language: https://www.khronos.org/opengl/wiki/OpenGL_Shading_Language
Common compatibility pitfalls: https://www.opengl.org/wiki/GLSL_:_common_mistakes
The Book of Shaders: https://thebookofshaders.com/
ShaderToy: https://www.shadertoy.com/
GH: https://github.com/mattdesl/lwjgl-basics/wiki/Shaders