I am looking into outlining sprites using a shader - I am not an expert on shaders at all.
I looked around a bit (googlefu) but did not find any already existing solution.
And here are the problems I am looking for input on
“0.001” is a magic value that works for texture lookup on 1024 x 1024 textures.
Found it just by trying - there should be a way to get the texture size and calculate this value.
The color & alpha are hard coded into the shader - I guess I should have a look on how the tint pipline get’s the values into the shader
When looking up the pixels, at the border we look up pixels of other sprites - for that reason there needs to be padding (at least 1 pixel) on the sprite sheet, I don’t know if this could be restricted to only lookup within the sprite itself.
For this to work a 1 pixel transparent border around the picture as part of the sprite is needed. (though I think this is ok and kind of expected)
With some tinkering I guess with this method a glow is possible (lookup further out, different alphas)
Feedback or tips on any of the points is very welcome.
q1: #extension GL_OES_standard_derivatives : enable
then
replace your magic 0.001 with dFdx(outTexCoord) dFdy(outTexCoord)
BTW: gl_FragColor = color.a * colurU.a * colorD.a * ..... colorR.a == 0. ? color : vec4(1., 0., 0., .2);
ternery condition is faster then IF.
q2:
suggest that use 3.17.0, there is native Shader gameobject to use, so no need to deal with the renderer.
q3:
texturepacker provides such functionality for you, why not use it? shader is still a resource we need to save… if you mean your texture is an atlas, then
outTexCoord *= frameSize / resolution
outTexCoord += framePosition / resolution
q4:
of course, OpenGL even renders gaps if you donot pad some transparent pixels between image blocks.
// in preload method
this.load.glsl("myGlsl", "external_glsl_file.glsl");
// then in create method
const obj = this.add.shader("myGlsl");
obj.setSampler2D(...); // or shortcut methods: setChannel0 / setChannel1 ... setChannel3
obj.setUniform(...);
// and then just treat this obj as an image to use, even add it into a container...
interesting … shader objects native, i blink and it gets 20 more options. Not up to me to tell people how to do what as for one im just a rank amateur hobbyist. Ever since ive seen the shadertoy website coming up on pouet.net glsl has been winking but far from there. In this case, phaser being pretty hungry already i think id just add an extra frame to the spritesheet which (i think) would in the end take up less resources than a ‘subroutine’ (pardon my archaic) calculating one.
ofcourse i do agree : doing it with a shader is lot more pretty (code-wise) but the client/player/user in the end will notice nothing but maybe the amount of cpu used on the device it runs on … mighty interesting though …
This is what I ended up using, be aware that this was for phaser 3.16.2 and used some magic numbers as you can see. I think shader pipelines have changed since then.