Share your Shaders

@StarCrunch

Yeah that makes it look pretty close. 

I was thinking about how a shader might be great to implement as a background to a side scrolling game. Eg as sunsets or random patterns. Think of games like “Duet” etc which tend to have a repeating pattern in the background. I was thinking of doing this in lua, but a shader may be much better.

How can you get these shader textures to scroll, so that its an endless effect, and that we can vary the speed of control from our main lua code via an input variable/method?  

My searches show its something like this in the vertex kernal? Am i right. Or is it still in the fragment or pixel shader

kernel.vertex = [[P\_POSITION vec2 VertexKernel( P\_POSITION vec2 position ) {      position.x +=  \_Speed;     return position; }]]

Where _Speed is the +/- direction of Scroll

It looks like parallax can also be achieved - but thats another step again.

http://blog.notnowlewis.com/blog/2013/12/18/parallax-background-glsl-shaders/

But i cant seem to get the simple scroll effect that is controllable to work. I am guessing that its something simple. 

@ online2

Ah, cool. Yeah, I definitely have background effect ideas, so I know where you’re coming from.  :slight_smile:

Somewhat related: Earthbound Battle Backgrounds

Depending on just what your effect needs to do, the vertex kernel might be appropriate, or it might not.

The most obvious use for a vertex shader is to shift the position a bit, as your snippet does, which would effectively move your display object (this is after it’s out of Corona’s hands, by the way).

Another is to initialize varyings, to be read back by the fragment shader, e.g. see in the custom effects guide. This way you set up some value for each vertex, then it gets interpolated across the pixels. Usually you’ll do this when it’s just intuitive to do so. It also happens that in the vast majority of cases, your pixels will vastly outnumber your vertices (say, a few ten-thousands to 4  :D), so there can also be optimization opportunities, but your values will either need to be constant (same for all vertices) or amenable to linear interpolation–e.g. angles will usually work, but not calculated sine values.

(Also, if you didn’t see it earlier in this thread, take a look at the second half of the reference card.)

You can read inputs in via CoronaVertexUserData’s components, after setting them Lua-side. The kernel can accept a vertexUserData field to hook these up, cf. the effects guide.

Probably the easiest way to start would be to calculate a float (either as a varying from the vertex kernel or just directly in the fragment shader) as some function of time and the value, e.g.:

P\_UV float delta = CoronaVertexUserData.x \* CoronaTotalTime; // x = speed // Could do stuff with mod() or fract() to keep value of delta sane, if it matters return CoronaColorScale(texture2D(CoronaSampler0, texCoord + vec2(delta, 0.)));

I don’t know if you’ve followed the Corona Geek episodes on shaders, but we talked about how it doesn’t take too long for the time to get out of control. Unfortunately, I still don’t have any great suggestions here, just something to be aware of.

Thanks StarCrunch.  Your comments are a great help. I will have a play around and see what i can achieve. 

I was also interested in creating customised fills, and wondered can this be done within the vertex/fragment shader, or in a more simplified manner Or is it really something that has to happen prior to any shader applications. Cocos 2D has the ability to create custom vertex shaders to create stripes etc in fills using CCRenderTexture.

Seems like there are only these on offer by corona https://docs.coronalabs.com/daily/guide/graphics/effects.html#generator-effects but the stripe effect for instance is very basic, doesn’t allow you to auto generate colours etc.

There a v interesting article here http://www.raywenderlich.com/33266/how-to-create-dynamic-textures-with-ccrendertexture-in-cocos2d-2-x but its unclear just how much of this approach can be replicated in corona. Thoughts?

@ online2

There are a few approaches like CCRenderTexture.

If the texture doesn’t need to be updated frequently, display.save() is available.

If the results are needed immediately and can then be fed into another effect, multi-pass is an option. (This is the first thing I tried, but generator.random was updating too and the circles effect did not appreciate it.  :D)

Last but not least are snapshots, which as you saw I ended up using (never further refreshing it after its initial capture). You can apply a fill to a snapshot, as I did. Unfortunately, these cannot yet be used as inputs to paints, normal or composite.  :( There were some hints from Walter that this would be coming, but I think it’s gotten lost in the shuffle. Once this happens, though, the fancy effect floodgates will be wide open.  :slight_smile:

Stripes shouldn’t be too hard to do. If you saw IcySpark’s fires effect earlier in the thread, for instance, it has this snippet:

P\_UV vec2 q = uv; q.x \*= 5.; // SNIP q.x = mod(q.x,1.)-0.5;

which basically breaks the region horizontally into five unit-width bins, then centers them. It isn’t a huge leap from bins to stripes, e.g. before that final line there could be a test like mod(q.x, 2.) > 1..

Something like that will be straightforward for horizontal or vertical lines. You can move to angled ones by using vectors. Basically, if you have a unit vector (x, y), it will have perpendicular vectors (-y, x) and (y, -x). Then you’d have a set of points going from some origin, (x, y), to each displacement by an integer multiple of one of your perpendiculars, e.g. adapting the above snippet, (x, y) + t * (-y, x) where t goes from 0 to 4. Using vector projection, you’d first find out where your current uv would land on that perpendicular line, and probably snap it to one of the intervals. That would give you a starting point for a parallel (x, y) ray, and you could do another projection to land on that.

(This might make more sense with a picture, but I don’t think I’m up to it just now. I’m not sure if it’s helpful, but if you saw any of those shader shows, this was one of the “rip” effects I demonstrated, and uses an oriented segment; basically, it masks out pixels close to the segment. The other two variants are in that same directory. There’s a link to a mostly up-to-date version zip file of the project earlier in this thread.)

Each projection would give you a distance, as you’ll see if you read the vector projection link. These are basically rotated versions of x and y, and the same technique used by the fires can apply.

Once you’ve established you’re on a stripe you can play with it, of course. Alternatively, you might try to reverse your position and land on a stripe. I’ll leave it there, for now, or I’ll never get this posted.  :smiley:

@StarCrunch

Thanks for all the effort and time in explaining these approaches.  I’ll check out the links and thoughts and have a play around.

Hi there everyone!

 

I have encountered a problem with implementation of a custom shader that for some odd reason, causes my app to crash on an iPhone 5 and iPad mini  but not an iPhone 6 or iPhone 6 plus!   I am getting a segmentation fault 11 error that causes my app to crash immediately after it is opened.  Any help is appreciated!  

 

Below is the code for my custom shader and my implementation of it:

 

  1. –kernel file to make shader

  2. local kernel = {}

  3.  

  4. kernel.language = “glsl”

  5. kernel.category = “generator”

  6. kernel.name = “wheel”

  7. kernel.isTimeDependent = true

  8.  

  9.  

  10. kernel.fragment =

  11. [[

  12. P_COLOR vec4 FragmentKernel( P_UV vec2 texCoord )

  13. {

  14. P_UV vec2 pos = 2. * (texCoord - .5); // Get relative position and normalize it to [-1, 1]

  15.     P_UV float len = length(pos);

  16.  

  17.     if (len > .9) return vec4(0.); // “outside”, use clear color

  18. if (len < .8) return vec4(0., 0., 1., 0.); // inner body, blue

  19.  

  20. P_UV float PI_OVER_TWO = 2. * atan(1.); // arctangent of 1 = pi / 4

  21. P_UV float angle = atan(pos.y, pos.x); // returns value in [-pi / 2, pi / 2]

  22.  

  23. if (angle < -PI_OVER_TWO) return vec4(1., 0., 0., 1.); // red

  24. else if (angle < 0.) return vec4(1., 1., 0., 1.); // yellow

  25. else if (angle < PI_OVER_TWO) return vec4(.5, 0., .5, 1.); // purple;

  26. else return vec4(0., 1., 0., 1.); // green

  27. }

  28.  

  29.  

  30. ]]

  31. return kernel

  32. –place in menu file where shader is implemented 

  33. –create circle to be made into wheel

  34. local wheel = display.newCircle(150, 100, 100)

  35. wheel.x = display.contentCenterX; wheel.y = display.contentCenterY

  36. wheel:scale(1.7, 1.7)

  37. group:insert(wheel)

  38. print(“creating circle”)

  39.  

  40.  

  41. –initialize kernel to create wheel effect

  42. local kernel = require “kernel_generator_custom_wheel”

  43. graphics.defineEffect( kernel )

  44.  

  45. –create wheel using effect on circle

  46. wheel.fill.effect = “generator.custom.wheel”

  47. print(“create wheel effect”)

 
Hey, Mgoldberg62401. I tried for some time to reproduce your crash but I couldn’t do it. May I ask you to see if it happens still on latest daily build. I also compiled minimal sample - https://dl.dropboxusercontent.com/u/2658771/ShaderCrash.zip (with code you posted, and commented out group:insert). It seems it draws 4 segment wheel with blue body. If it still crashes, may I ask to write here and report a bug. I tested it on several devices and it seems to work fine.

Also, what might help - is to gradually simplify your app to pinpoint the issue. Like step replace shader with just solid colour return, etc. If you’ll figure out what was the issue, please share as well.

As a reminder, you can also distribute your shaders as lua plugins.

Starfield

 

Original Shader: https://www.shadertoy.com/view/Md2SR3

Corona Playground: https://goo.gl/Ux9dEo

 

I don’t know if I did this correctly or not…

Atmospheric Scattering

Original Shader: https://www.shadertoy.com/view/lslXDr

Corona Playground: https://goo.gl/bhMXsh

Nice! It reminds me about full lunar eclipse on September 27!

a panorama shader to view an equirectangular photo.  

Github: https://github.com/kwiksher/custom-filter-panorama

Original Shader: https://gist.github.com/fieldOfView/5106319

Pretty simple green glowing line : https://goo.gl/FjUZl9

Good job. Btw, if you would use [lua]finalColor *= abs( CoronaVertexUserData.x / sin( uv.x) );[/lua] instead of [lua]finalColor *= abs( 1.0 / (sin( uv.x) * 40.0) );[/lua] you would be able to change line width with x parameter of CoronaVertexUserData. Also, check out “CoronaColorScale” function, to set color of line dynamically with color setting, for example https://goo.gl/4p6T3n

https://goo.gl/X9yDWu

https://goo.gl/kCeHXa

Very cool, pickerel! The fine details on the little images especially.  :slight_smile:

I don’t know if I already said this earlier, but for many / most of these shaders, especially with some of the craziness ported from Shadertoy, it would be awesome to see some commentary and / or blogs trying to unpack all of the techniques!

Random dark circles: https://goo.gl/W8CJT0

P.S Vlads thanks for your help 

Hi all, 

I had no idea what i was doing but managed to hack and stumble my way through fudging a conversion from shadertoy to corona. Hope others post their own comments and help other shader noobs understand the process. 

Original Author: Urraka

Name of Shader: Stars Background

Link to original shader: https://www.shadertoy.com/view/lsfGWH

 

Corona Shader Playground Link: https://goo.gl/Z2NQeN

 

What i think i had to so was replace the mainImage function 

 

void mainImage( out vec4 fragColor, in vec2 fragCoord )

with

P\_COLOR vec4 FragmentKernel (P\_UV vec2 fragCoord)

and make sure this returns a line of the out vec that was in the mainImage call eg 

return CoronaColorScale(fragColor);

then anywhere that there is a float, vec2 or vec4 as a variable or as part of a funtion that is declared just at P_DEFAULT infront of it.

 

and change any refs of iGlobalTime to  CoronaTotalTime

and change any refs of iResolution to  CoronaVertexUserData  – i think this is wrong but it didnt break the code. 

 

As i said i have no idea if i just fluked it, but perhaps that helps.  See the links and compare.   

 

I notice the larger stars don’t seem to show up

Heres another one that seems to convert well given the above technique from my earlier post. 

Original Author: Iq

Name of Shader: Bubbles

Link to original shader: https://www.shadertoy.com/view/4dl3zn

https://goo.gl/fcVQQH

I tried to get the following more complex shader conversion to work but it didn’t go as well.  Fwidth function wasn’t available so i just replaced with abs (for no particular reason)

I tried using P_COLOR to get the colors right? and played around with different input samples, but couldnt get the exact look. 

Original Author: Iq

Name of Shader: Circle Pattern

Link to original shader: https://www.shadertoy.com/view/lss3Df

https://goo.gl/PglnI2

If anyone has the knowledge, what is going wrong with the conversion. Is there any theory behind these shaders that makes it a bit more obvious what is happening. Thanks

@ online2

P_DEFAULT should generally work well, though on lower-quality devices you’ll need to change it to P_UV or P_POSITION and such (there’s a  GL_FRAGMENT_PRECISION_HIGH define). Some constants will probably also need taming in that situation. Along those same lines, I wouldn’t use P_COLOR for what are basically intermediate values, where a lot of calculations will follow and precision is key. Fetching colors or normals out of a standard texture are fine, though.

The derivatives are an extension. I’ve found CoronaTexelSize.x to be a passable replacement for fwidth(), e.g. see here. I don’t know off-hand if there’s a WebGL variant supported by the playground.

I’m not 100% sure on “Circle Pattern”, but it looks like the main culprit is the underlying texture. “Gray diffuse” seems to be a bit too beige and homogeneous, versus the tinted static used in Shadertoy. I played with the moon texture and a little scaling in the noise shader and it’s a little closer. Every now and then you get waves of orange squircles, though it still doesn’t quite track the example.