Share your Shaders

Thanks StarCrunch, for the above comment and your help to the community so far on shaders (an other stuff). A few more concepts and higher order mathematics are starting to click :slight_smile:

For those of you who want to play around with the moon texture i found modifying the time steps variable allows you to slow the changes in the shader down. Making it less jittery. Then varying the CoronaSampler0 options you start getting a feel for how that changes the shader output

P\_DEFAULT float time = 11.0 + (CoronaTotalTime + 0.8\*sin(CoronaTotalTime)) / 1.8;

becomes

P\_DEFAULT float time = 11.0 + (CoronaTotalTime + 0.8\*sin(CoronaTotalTime)) / 11.8;

@ online2

No problem, and you’re very welcome.

I was curious since generator.random’s preview image looked pretty similar to the Shadertoy noise texture, so I gave it a go. This is the original for the most part, albeit with P_DEFAULT in most places and fwidth() when available:

do local kernel = { category = "filter", name = "circles" } kernel.isTimeDependent = true kernel.fragment = [[#define NUM 9.0 P\_DEFAULT float noise( in P\_DEFAULT vec2 x ) { P\_DEFAULT vec2 p = floor(x); P\_DEFAULT vec2 f = fract(x); P\_DEFAULT vec2 uv = p.xy + f.xy\*f.xy\*(3.0-2.0\*f.xy); return texture2D( CoronaSampler0, (uv+118.4)/256.0, -100.0).x; } P\_DEFAULT float map( in P\_DEFAULT vec2 x, P\_DEFAULT float t ) { return noise( 2.5\*x - 1.5\*t\*vec2(1.0,0.0) ); } P\_DEFAULT float shapes( in P\_DEFAULT vec2 uv, in P\_DEFAULT float r, in P\_DEFAULT float e ) { #ifdef GL\_OES\_standard\_derivatives #extension GL\_OES\_standard\_derivatives : enable #endif P\_DEFAULT float p = pow( 32.0, r - 0.5 ); P\_DEFAULT float l = pow( pow(abs(uv.x),p) + pow(abs(uv.y),p), 1.0/p ); P\_DEFAULT float d = l - pow(r,0.6) - e\*0.2 + 0.05; #ifdef GL\_OES\_standard\_derivatives P\_DEFAULT float fw = fwidth(d) \* .5; #else P\_DEFAULT float fw = CoronaTexelSize.x; #endif fw \*= 1.0 + 10.0\*e; return (r)\*smoothstep( fw, -fw, d ) \* (1.0-0.2\*e)\*(0.4 + 0.6\*smoothstep( -fw, fw, abs(l-r\*0.8+0.05)-0.1 )); } P\_COLOR vec4 FragmentKernel( P\_UV vec2 fragCoord ) { P\_DEFAULT vec2 qq = fragCoord.xy / CoronaContentScale.xy; P\_DEFAULT vec2 uv = fragCoord.xy / CoronaContentScale.xx; P\_DEFAULT float time = 11.0 + (CoronaTotalTime + 0.8\*sin(CoronaTotalTime)) / 1.8; uv += 0.01\*noise( 2.0\*uv + 0.2\*time ); P\_DEFAULT vec3 col = 0.0\*vec3(1.0) \* 0.15 \* abs(qq.y-0.5); P\_DEFAULT vec2 pq, st; P\_DEFAULT float f; P\_DEFAULT vec3 coo; // grey pq = floor( uv\*NUM ) / NUM; st = fract( uv\*NUM )\*2.0 - 1.0; coo = (vec3(0.5,0.7,0.7) + 0.3\*sin(10.0\*pq.x)\*sin(13.0\*pq.y))\*0.6; col += 1.0\*coo\*shapes( st, map(pq, time), 0.0 ); col += 0.6\*coo\*shapes( st, map(pq, time), 1.0 ); // orange pq = floor( uv\*NUM+0.5 ) / NUM; st = fract( uv\*NUM+0.5 )\*2.0 - 1.0; coo = (vec3(1.0,0.5,0.3) + 0.3\*sin(10.0\*pq.y)\*cos(11.0\*pq.x))\*1.0; col += 1.0\*coo\*shapes( st, 1.0-map(pq, time), 0.0 ); col += 0.4\*coo\*shapes( st, 1.0-map(pq, time), 1.0 ); col \*= pow( 16.0\*qq.x\*qq.y\*(1.0-qq.x)\*(1.0-qq.y), 0.05 ); P\_COLOR vec4 fragColor = vec4( col, 1.0 ); return CoronaColorScale(fragColor); }]] graphics.defineEffect(kernel) end local snapshot = display.newSnapshot(display.contentWidth, display.contentHeight) local r = display.newRect(snapshot.group, 0, 0, snapshot.width / 2, snapshot.height / 2) snapshot:translate(display.contentCenterX, display.contentCenterY) r.fill.effect = "generator.random" snapshot.fill.effect = "filter.custom.circles"

Not all the way there, but looks pretty close!

@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.

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

Sunset
Original: https://www.shadertoy.com/view/XssSRX
Solar2d Shader: https://f25j6.app.goo.gl/qv3H