Glsl Shader Top Help

Hi Guys,

So after figuring out the OSC stuff, I’m trying my hand at shaders… I’m feeling completely lost on this one.

I found a simple shader on shadertoy to try and replicate:
shadertoy.com/view/XsjGDt

Seems simple enough?

Can anyone help me figure this out? I feel lost understanding the differences between vUV.st, fragcoord.xy, TDTexInfo, etc. when to use which one and what they actually represent. If there is a better guideline / howto on the wiki somewhere, please feel free to refer me…

anyway, here is my attempt at translating from shadertoy to TD. it basically just makes a red screen…not much else.

/Variable declarations

out vec4 fragColor;

vec3 rgb(float r, float g, float b) {
return vec3(r / 255.0, g / 255.0, b / 255.0);
}

vec4 circle(vec2 uv, vec2 pos, float rad, vec3 color) {
float d = length(pos - uv) - rad;
float t = clamp(d, 0.0, 1.0);
return vec4(color, 1.0 - t);
}

void main()
{

vec2 uv = gl_FragCoord.xy;
vec2 center = vUV.st*0.5;
float radius = vUV.t*0.25;

// Circle
vec3 red = rgb(225.0, 95.0, 60.0);
vec4 layer2 = circle(vUV.st, center, radius, red);

fragColor = layer2;

}

success! - if any other newbies see this and are lost… hope it helps.

//Variable declarations

out vec4 fragColor;

vec3 rgb(float r, float g, float b) {
return vec3(r / 255.0, g / 255.0, b / 255.0);
}

vec4 circle(vec2 uv, vec2 pos, float rad, vec3 color) {
float d = length(pos - uv) - rad;
float t = clamp(d, 0.0, 1.0);
return vec4(color, 1.0 - t);
}

void main()
{

vec2 uv = gl_FragCoord.xy;
//vec2 center = vec2(100,100);
vec2 center = vec2(uTDOutputInfo.res.ab)*0.5 ;
//float radius = 25;
float radius = 0.25*uTDOutputInfo.res.b;

/// Background layer
vec4 layer1 = vec4(rgb(210.0, 222.0, 228.0), 1.0);

// Circle
vec3 red = rgb(225.0, 95.0, 60.0);
vec4 layer2 = circle(uv, center, radius, red);

// Blend the two
fragColor = mix(layer1, layer2, layer2.a);

}

Wow what a coincidence. This was one of the first shaders I picked to study to learn GLSL over a year ago.

I think it’s a very instructive shader, but I developed a slightly different style over time. The big picture is that you might want to separate your “shaping” functions (circles, squares, and lines) from your “color” functions (the “mix” function). That means “circle” should return a float–not a color–and you use that value in a separate function for coloring. Over time you can collect or create lots of handy functions–some for shaping–and some for coloring.

Here’s a slightly revised shader

[code]
/**

  • Convert r, g, b to normalized vec3
    */
    vec3 rgb(float r, float g, float b) {
    return vec3(r / 255.0, g / 255.0, b / 255.0);
    }

float circle(vec2 uv, vec2 pos, float rad) {
float d = length(pos - uv) - rad;
return 1.0-clamp(d, 0.0, 1.0);
}

void mainImage( out vec4 fragColor, in vec2 fragCoord ) {

vec2 uv = fragCoord.xy;
vec2 center = iResolution.xy * 0.5;
float radius = 0.25 * iResolution.y;

// Circle
vec3 red = rgb(225.0, 95.0, 60.0);
vec3 background_color = rgb(210.0, 222.0, 228.0);

float circleFactor = circle(uv, center, radius);

// Blend the two
fragColor = vec4(mix(background_color, red, circleFactor), 1.0);

}[/code]

Thanks!

One concept I am struggling with -

Built in Uniforms
The GLSL TOP has built-in uniforms that may come in useful depending on the shader you are writing. You do not need to declare this uniforms, they are declared for you.
There are many arrays of this structure that gives information about input/output textures. The structure is defined as:
struct TDTexInfo
{
vec4 res; // contains (1.0 / width, 1.0 / height, width, height)
vec4 depth; // contains (1.0 / depth, depth, depthOffset, undefined)
};

if I want to access this data…

res.x = 1.0 / width
res.y = 1.0 / height

I would have thought

res.a = width
res.b = height

but it seems

res.b = width and
res.a = height

this seems counter intuitive? am i missing something?

You can access the components of a vector (in your case: vec4 res) with a technique called swizzling. See nice explanation here: [url=https://www.opengl.org/wiki/Data_Type_(GLSL)#Swizzling]Data Type (GLSL) - OpenGL Wiki

You can use x, y, z, or w, referring to the first, second, third, and fourth components, respectively.

Additionally, there are 3 sets of swizzle masks. You can use xyzw, rgba (for colors), or stpq (for texture coordinates). These three sets have no actual difference; they’re just syntactic sugar. You cannot combine names from different sets in a single swizzle operation. So “.xrs” is not a valid swizzle mask.

so in your case, res.a uses the rgba mask, so it gives you the fourth component of the vector, height.

amazing, thanks for the explanation!

I am reading a great tutorial on lighthouse3d - lighthouse3d.com/tutorials/g … nt-shader/

IN regards to the fragment shader, it has the following paragraphs:

and

what is the difference between fragment and pixel?

I don’t think the difference is very important. Some people say fragment shader and some people say pixel shader. I guess pixel refers to a fragment shader without depth. In the second paragraph you posted, pixel refers to the first two values in the set of four.

You could say a fragment is a potential pixel that has to pass several tests before becoming an actual pixel on your screen.

Because the RGBA value which is outputted from the fragment shader, isn’t necessarily the RGB value that will show up on your screen as a pixel. For instance, that fragment also has depth information and it has to pass the depth test, as other stuff can be drawn on top, in which case that first fragment will be hidden, so it doesn’t become an actual pixel.

Also, the fragments from several triangles might contribute to the end value of a given pixel on your screen.

Other stages the fragment can pass before becoming an actual pixel are the scissor test, stencil test, blending. See all those tests here, and in the menu on the right the complete OpenGL pipeline from beginning (top) to end (bottom): opengl.org/wiki/Per-Sample_Processing

But you don’t really need to worry about this advanced fragment vs pixel stuff when you’re just writing a GLSL TOP.

As a shader written for the GLSL TOP is generally a image based operation. It does essentially no geometry based work. So a GLSL TOP is simply a shader applied to a single quad that is drawn to cover up the entire viewport (also known as a full-screen-aligned quad).

So for a GLSL TOP, every fragment which is outputted is drawn as a pixel in the output of the GLSL TOP.

Thanks guys.

Learning some of this has been equally interesting, and brain twisting at times :slight_smile: