Shadertone demo screencast

51 views
Skip to first unread message

Roger Allen

unread,
May 2, 2013, 12:55:47 AM5/2/13
to over...@googlegroups.com
I finally got around to creating a demo screencast for Shadertone.


Cheers,

Roger


Sam Aaron

unread,
May 2, 2013, 5:03:16 AM5/2/13
to over...@googlegroups.com
Hey Roger,

On 2 May 2013, at 05:55, Roger Allen <ral...@gmail.com> wrote:

> I finally got around to creating a demo screencast for Shadertone.
>
> Check it out here: http://www.youtube.com/watch?v=_8T15N3ZvYc


This is amazing. Your FFT and wave scope is way better than the one in the overtone.gui namespace. Really great work.

Do you have any recommendations on how I can learn GLSL? It seems like alien tech to me...

Sam

---
http://sam.aaron.name

Roger Allen

unread,
May 2, 2013, 11:09:33 AM5/2/13
to over...@googlegroups.com
Oh, I totally based the FFT example on the overtone.gui scope code.  I'd have been lost without that...  Also, adding "real" oscilloscope features like triggers and grids will be much easier to do in that overtone.gui code.  Mine just makes the FFT a bit easier to understand via a call to pow().  0-1 values are way easier than -infinity to +6 (ish)

Unfortunately, pointers for learning GLSL is a bit hard to explain in this context because most GLSL tutorials assume you are shading 3D models with normals, eye vectors, etc.  The shadertoy model is much more limited than that and the GLSL tutorials could be confusing with a lot of background & explanation you just don't need (like setting up lights, materials, vertex shaders, etc).

I've got a start for trying to explain them in the README:

Writing Fragment Shaders

Fragment Shaders are code that is executed for every pixel displayed in the window. The output is the color of that pixel, which you store in gl_FragColor. To create different imagery, you take the current pixel's position (from gl_FragCoord) and use that as input. To have Overtone affect the color, you'll want to use inputs like iOvertoneVolume. The syntax is C-like and given the math-processing power of modern GPUs, it is somewhat astonishing what you can do in 1/60th of second.

One of the creators of www.shadertoy.com, Iñigo Quílez, has a website that explains a variety of techniques to create interesting Fragment Shaders at http://www.iquilezles.org/www/index.htm. He also has some interesting live coding demos herehttp://www.iquilezles.org/live/index.htm.

If I knew what kinds of questions you had after reading this, I could try to address them--send 'em on.  My problem is that I don't really know what people don't know...I've been doing this as a day job for a long time.

I think I'll go through an example like https://github.com/overtone/shadertone/blob/master/examples/implicit_fn.glsl in my next screencast.  Maybe going through a bit of that here could spark some questions that point out what people want to know...

Since each pixel is running the same code, normally the first thing you need to do in one of these shaders is find out which pixel you are.  To do that you need to read from the gl_FragCoord input and convert it to a range that is better suited for further processing. That's what this line does:

vec2 uv = getScreenUV(gl_FragCoord.xy);

which calls this function and hopefully the comments point out how the value is manipulated.  The gl_FragCoord.x is an integer ranging from 0 to windowWidth-1.  Dividing by iResolution.x will give you a [0,1) range output...  The code below handles keeping your image "square" even when your window is rectangular.

// convert the fragment coordinates (fc.x,fc.y) to a screen u,v space.
vec2 getScreenUV(vec2 fc) {
    vec2 uv = fc/iResolution.xy; // uv = [0,1)
    uv = 2.0*uv-1.0; // uv = [-1,1)
    float aspect_ratio = iResolution.x / iResolution.y;
    if(aspect_ratio < 1.0) {
        uv.x /= aspect_ratio; // u = [-ar,ar), v = [-1,1)
    } else {
        uv.y /= aspect_ratio; // u = [-1,1), v = [-ar,ar)
    }
    return(uv);
}

so each pixel now has a uv.xy vector that is in a known range (-1,1) and is useful for further processing.  One way to see this would be to do

gl_FragColor = vec4(uv.x, uv.y, 0.0, 1.0);

Will just output these linear values uv.x -> a pixel's red color.  uv.y -> a pixel's green color.  (blue gets 0.0).   Note that negative color values are going to be black when you see them on the screen.

I think playing with this very basic code to see how things change on the screen is where folks should start and be sure they understand the basics of what is happening.
Try multiplying uv by a constant.  Try commenting out this line uv = 2.0*uv-1.0; Try doing an abs(uv).  Try different window aspect ratios.  Try removing the aspect ratio code.  Etc...

Cheers,

--Roger

p.s. this might be helpful http://www.khronos.org/files/opengl-quick-reference-card.pdf  (scroll down to the OpenGL Shading Language section)
Reply all
Reply to author
Forward
0 new messages