recreate GLSL shader effect with Vectors

lucy's picture

hallo :)

i am trying to recreate a patch 'circles.qtz' using a 1024_gl_circle inside a GSLS shader, using the kineme2d plugins.

basically i want to get the same form, controllable in the same way, but with vector - as for large projection the gl stipple is just not acceptable.

Important for me is the behaviour from the circle.qtz patch as the value 'sides' is changed from a low number to a high number - from straight edges to a curved effect.

My maths skills are really lame, so im hoping someone can give me a point in the right direction how to get the maths from the shader replicated in my Vector 2d patch (built from a hacked example patch from kineme).

my attempts at adding noise and distortion has not really had the right results :(

Thanks! any advice is welcome.

PreviewAttachmentSize
circles.qtz8.53 KB
Vector2d-javascriptDeform.qtz35.63 KB

jersmi's picture
Re: recreate GLSL shader effect with Vectors

I like franz's circle demo. He used the Apple dev example "vertex noise" for the GLSL shader. Where did your javascript come from? Nice example for the vector commands.

You could maybe add a js variable input for random/noise or code in Math.random() to the formula. for the offset var, perhaps?

lucy's picture
Re: recreate GLSL shader effect with Vectors

hey thanks for your reply,

yeh first thing i tried was adding random to the offset, with some interesting results, but it's nothing like this shader distortion maths. The way it functions is completely diff but i cant seem to get my head around how to manipulate it.

yep franz's circle is cool and the behaviour is a great foundation for something i want to build. the js example is from the kind people of kineme.

jersmi's picture
Re: recreate GLSL shader effect with Vectors

It's a good question. I use that vertex noise shader often -- nothing else behaves quite like it. I would love to know how to translate the GLSL noise to js. I don't get how GLSL operates on vertices vs. how the js example is summing the array items. How does this translate to the js example:

vec3 vertex = gl_Vertex.xyz + noise3(offset + gl_Vertex.xyz * scaleIn) * scaleOut;

smokris's picture
Re: recreate GLSL shader effect with Vectors

From the text "The OpenGL Shading Language", section 8.9:

Quote:
Noise functions are available to both fragment and vertex shaders. They are stochastic functions that can be used to increase visual complexity. Values returned by the following noise functions give the appearance of randomness, but are not truly random. The noise functions below are defined to have the following characteristics:

  • The return value(s) are always in the range [-1.0,1.0], and cover at least the range [-0.6, 0.6], with a gaussian-like distribution.
  • The return value(s) have an overall average of 0.0
  • They are repeatable, in that a particular input value will always produce the same return value
  • They are statistically invariant under rotation (i.e., no matter how the domain is rotated, it has the same statistical character)
  • They have a statistical invariance under translation (i.e., no matter how the domain is translated, it has the same statistical character)
  • They typically give different results under translation.
  • The spatial frequency is narrowly concentrated, centered somewhere between 0.5 to 1.0.
  • They are C^1 continuous everywhere (i.e., the first derivative is continuous)

--- that is, Gradient Noise. One example of Gradient Noise is Perlin Noise. The reference implementation is in Java, but shouldn't be too difficult to translate into JavaScript.

gtoledo3's picture
Re: recreate GLSL shader effect with Vectors

jersmi wrote:
It's a good question. I use that vertex noise shader often -- nothing else behaves quite like it. I would love to know how to translate the GLSL noise to js. I don't get how GLSL operates on vertices vs. how the js example is summing the array items. How does this translate to the js example:

vec3 vertex = gl_Vertex.xyz + noise3(offset + gl_Vertex.xyz * scaleIn) * scaleOut;

The GLSL noise function is something that can be implemented totally differently on different cards, or maybe not at all, so it can be hard to count on a really consistent result. Support seems to be generally better than it was even a couple of years ago though.

This usually works one of two ways (I'm being sort of simplistic here) - the noise is generated from texture lookups (there is a tileable noise texture, like the Random Generator in QC, that gets used as a texture reference for creating pseudo random noise), or there's a big table of numbers that get drawn from (a good example where you can see this technique in action, is the mesh noise openCL kernel).

You could probably take the time to do perlin or simplex noise in javascript, and it might be pretty useful for you.

All of the above said, when working in javascript (boo) I usually do something like:

cool.variable= Math.random()*whatever

...and the results are usually very expected and random enough to look ok to my eye.

vade's picture
Re: recreate GLSL shader effect with Vectors

Avoid noise3() and friends, they run in software fallback and will greatly reduce throughput of your rendering, even if you run above 60Hz or use it sparingly, it will greatly reduce throughput of other passes or phases you do earlier or later in your renderer. Switching between software and hardware is not fast - and the performance characteristics of programmable shaders in Mac profiling app's is sort of 'hidden' from you - there is no obvious way to point to a line of code in a shader and look at how many ms it takes to run - its hidden via other functions.

Typically only workstation class cards tend to have noise() implemented in real hardware, and I've yet to come across a Mac config that runs it in hardware.

OpenGL Profiler -> Break on renderer change

Run a qtz with noise3() and you will watch the host app (QC Editor, VDMX, etc) switch renderers to software for the vertex stage.

Use a pseudo-random texture + lookup based on passed in time base, it will be faster, and actually deterministic/repeatable. On most modern hardware you can do a "vertex texture fetch" which is a texture2D lookup in the vertex shader (as opposed to more commonly sampling in a fragment shader)

lucy's picture
Re: recreate GLSL shader effect with Vectors

gtoledo3 wrote:
All of the above said, when working in javascript (boo) I usually do something like: cool.variable= Math.random()*whatever ...and the results are usually very expected and random enough to look ok to my eye.

because the animation is being done with += applying Math.random() to the offset results in that point jumping around continuously, rather than animating smoothly from one position to another.. sorry if im overlooking something easy, but i cant think how to write that. cheers for all the infos!

jersmi's picture
Re: recreate GLSL shader effect with Vectors

Yes, I appreciate the info, too.

I believe Lucy and I both have the same point of confusion, which I think is more of a basic programming problem. I believe we both get that the Math.random() could probably do the job well enough.

In the GLSL vertex noise formula, the noise function operates on gl_Vertex.xyz and the effect can be smooth animation, especially with scale in/out. (The effect is pleasing to the eye, as it were.) What would be the method in javascript to create the same effect using, for ex., Math.random() (and create the equivalent of scale in/out as vertex noise)?

vade's picture
Re: recreate GLSL shader effect with Vectors

You want to implement perlin noise or another "smooth" noise algorithm. Wikipedia has plenty of code.

gtoledo3's picture
Re: recreate GLSL shader effect with Vectors

vade wrote:
You want to implement perlin noise or another "smooth" noise algorithm. Wikipedia has plenty of code.

Yeah. As Vade states - perlin noise is higher quality (and as I stated above as well, look into simplex). Math.random is a kind of crappy implementation of random...

That said, I think it may be the way it's being used, because it's not that crappy? I saw some of the code above, but didn't see anything where anyone is actually using Math.random. Zuga's "javascript objects" or "alphabet particle" (google search is your friend) do a better job of demonstrating smooth looking use than I could whip up here quickly for the sake of example.

jersmi's picture
Re: recreate GLSL shader effect with Vectors

I'm thinking the noise could be outside the js. This example uses the built-in Random patch (perlin noise, after all). I think this could work if the math is set up correctly in js. Here's where I falter. Any advice how to customize the js here is appreciated.

PreviewAttachmentSize
Vector2d-javascriptDeform2.qtz41.47 KB