--~~~~~~~~~~~~~~~~~~~~~~~~~software shading~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~---- 'render' is RenderTarget instance-- 'shader' is a soft-shader function (r, g, b, a, x, y, ...) -> r, g, b, a-- '...' is for constants which will be passed to 'shader' function-- NOTE: each color component should be an integer in 0..255 rangelocalfunction applyShader(render, shader, ...)local w, h = render:getWidth(), render:getHeight()local pixels = render:getPixels(1, 1, w, h)for i =1, #pixels, 4dolocal n =(i - 1)/4local y =math.floor(n / w) + 1local x =(n - y * w + w) + 1local r, g, b, a = pixels:byte(i, i+3)
r, g, b, a = shader(r, g, b, a, x, y, ...)
render:clear(r *65536 + g *256 + b, a /255, x, y, 1, 1)endend--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--local texture = Texture.new "sample.png"local w, h = texture:getWidth(), texture:getHeight()local image = Bitmap.new(texture)local render = RenderTarget.new(w, h)
render:draw(image)local bitmap = Bitmap.new(render)
stage:addChild(bitmap)localfunction grayscale(r, g, b, a, x, y)local avr =math.floor((r + g + b)/3)return avr, avr, avr, a
end
applyShader(render, grayscale)
However `RenderTarget.clear` method is not effective (8 seconds to process 512x512 pixels image). Gideros needs C++ implementation of above applyShader method because Lua strings and tables have much slower access.
Desaturation = reduction of colorfulness. Real shader is hard to write for beginners and it constantly consumes videocard resources. This one-shot soft-shader is useful for image processing and you can later save the result because I don't think `getPixel` will return modified texture if you apply real shader to it (need to check). If Lua-C API supports effective iteration over arrays with Lua function application (i.e. "map") this can be very fast processing too.
... and it constantly consumes videocard resources.
No it doesn't, you can apply it once and release it afterwards, and yes getPixel() will return processed pixels, since applying a shader is the exact purpose of a RenderTarget, wether the shader aims is create graphics or image processing.
However I agree on the fact that shaders are less easy to deal with than lua functions, but on all aother points they are more effective, because the GPU is designed to do just that task.
@hgy29, that's awesome! Then we only need additional simplified API for pixel shaders. Nothing special, just a template with predefined `ps.glsl`, `vs.glsl` and `Shader.new`. String with pixel shader code could be inserted into `void main() {...}`. In the end a user should be able to write something like this:
@hgy29, I checked and it doesn't work works. You cannot get modified pixels from rendertargets because each time pixel shader applies to source texture (not previously modified one).
Gah! I knew I had posted something similar before, but couldn't find it in the forum search.
Would it be counterintuitive to create an abstracted Lua class with common uses, such as blur and desaturation? Shaders still scare me, so for me that would be very useful. I am working on a Sprite:setBlur method, but it's still a way off working as it should.
I don't really understand what you mean. If you want to keep your rendertarget's unmodified after the first draw call, then just don't draw on it again ? And you can use the rendertarget as source texture for subsequent calls without applying the shader again.
@totebo, yes that's a good idea. We plan to allow shader's to be loaded from lua string instead of files, that way we will be able to hide shader stuff inside .lua libraries, plus shader's could be customised at run time for even better efficiency.
@hgy29, I mean with `getPixels` function you can't get pixels of rendertarget modified by `setShader` effect. I can't load images from disk, apply shader effect (like grayscale) and then save the result (grayscaled image) to disk.
Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!). https://deluxepixel.com
Open "Normal mapping" example and replace `ps.glsl` "void main {...}"-part with:
void main(){
highp vec4 color = texture2D(g_Texture, texCoord).rgba;
highp float m =(color.r + color.g + color.b)/3;
gl_FragColor = vec4(m, m, m, color.a);}
First line gives you 4 color components as vector (vec4). It also sets precision as 'high' for it (this affects performance). Second line does some maths to get greyscaled color. Third line creates new color vector and assigns it to texture coordinate.
This template just returns unmodified color if you want to experiment further:
Will make one once I get this working. First attempt of plugging it into my game removed the sprite instead of making it grey scale, so next step is to make a minimal project and take it from there.
Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!). https://deluxepixel.com
Hey guys! I was looking for a desaturation shader Do you know why @totebo 's example (attached above) doesn't work in Gideros 2018.6.2?
FragmentShader:
ERROR: 0:5: 'float' : syntax error syntax error
stack traceback:
main.lua:1: in main chunk
> Newcomers roadmap: from where to start learning Gideros "What one programmer can do in one month, two programmers can do in two months." - Fred Brooks “The more you do coding stuff, the better you get at it.” - Aristotle (322 BC)
Comments
Likes: pie, totebo, MoKaLux
Real shader is hard to write for beginners and it constantly consumes videocard resources. This one-shot soft-shader is useful for image processing and you can later save the result because I don't think `getPixel` will return modified texture if you apply real shader to it (need to check).
If Lua-C API supports effective iteration over arrays with Lua function application (i.e. "map") this can be very fast processing too.
However I agree on the fact that shaders are less easy to deal with than lua functions, but on all aother points they are more effective, because the GPU is designed to do just that task.
Then we only need additional simplified API for pixel shaders.
Nothing special, just a template with predefined `ps.glsl`, `vs.glsl` and `Shader.new`. String with pixel shader code could be inserted into `void main() {...}`.
In the end a user should be able to write something like this:
Likes: totebo
doesn't workworks.You cannot get modified pixels from rendertargets because each time pixel shader applies to source texture (not previously modified one).Would it be counterintuitive to create an abstracted Lua class with common uses, such as blur and desaturation? Shaders still scare me, so for me that would be very useful. I am working on a Sprite:setBlur method, but it's still a way off working as it should.
Likes: n1cke, SinisterSoft, totebo
In your example you miss the
Likes: SinisterSoft, n1cke
1. load your source image texture, point a bitmap to it, apply the shader to the bitmap.
2. make a rendertarget. draw the bitmap to the rendertarget (once)
3. read the pixels from the rendertarget.
Likes: antix
https://deluxepixel.com
Likes: MoKaLux
Could someone post actual code to make a sprite greyscale with shaders? I'm missing something and and actual compilable example would help a lot.
Second line does some maths to get greyscaled color.
Third line creates new color vector and assigns it to texture coordinate.
This template just returns unmodified color if you want to experiment further:
Likes: chuz0
Likes: vitalitymobile
Likes: pie, vitalitymobile, SinisterSoft, antix
Likes: totebo
https://deluxepixel.com
Likes: SinisterSoft, totebo, snooks, MoKaLux
Still, shaders are a twilight zone of mystery, magic and infinite pain and suffering. So I'm not there often.
Do you know why @totebo 's example (attached above) doesn't work in Gideros 2018.6.2?
"What one programmer can do in one month, two programmers can do in two months." - Fred Brooks
“The more you do coding stuff, the better you get at it.” - Aristotle (322 BC)
Likes: Apollo14, totebo, MoKaLux