hey everyone I thought I'd make an
absolute beginners tutorial on shader
programming with shader toy yeah like
there are some really cool effects that
people that people make on this website
called shader toy and the cool thing
about it is that you can look at the
shader and you can see the code at the
same time so you can kind of see how it
was done but yeah like often times it's
very hard to understand what is actually
going on if you don't know much yet
about shader programming so that's why I
thought I'd make I'd make just a
beginners tutorial so yeah if you look
at if you look at all the code over here
and you haven't seen stuff like that
before it's really quite opaque and hard
to understand so that's why I thought
let's just start with something
completely from scratch and go very slow
and explain everything along the way so
what we'll make is just a circle but you
know you've got to start somewhere and
hopefully it will help somebody so I
just clicked on create a new shader
obviously that you like you need to have
an account you need to be signed in for
for that to be there and also what I'm
going to do is I'm going to go on full
screen so that we don't have any of the
extra stuff there so now the first thing
to ask yourself or the first thing I
should explain maybe is like what a
shader is so a shader is basically a
little program that takes some inputs
and it outputs just a pixel color it's
called frag color your frag central
fragment and a pixel color consists of
three things and are a G and a B a red a
green and a blue channel that are
between 0 & 1 generally so 0 meaning
there is no there's no contribution on
the channel and 1 meaning there is full
contribution on that channel
and then often there is also like a
fourth component which is called the
alpha channel which which shade Ettore
has here but I don't think it's used for
anything but we do need it so first of
all let's just get rid of what we have
here and let's let's just make a black
screen first so black would be zero red
contribution zero green contribution and
zero blue contribution okay
did I forget it now to come us there
okay and then I could just press play
here and now it makes a black screen to
just play with this a little bit more
like well if we wanted to make for
instance a red screen we could just say
okay it's one for the red zero for the
green and zero for the blue and see what
that does it makes a red screen okay if
I add a full contribution on the green
channel as well then I have red and
green which makes yellow okay so that's
just to kind of you know get a feel for
for like how DS pixel colors work so a
full contribution and everything makes
white okay now this is not extremely
exciting so to make stuff that is a
little bit more exciting we need
something that that changes across that
changes across the screen and we have
that which is like that's my UV here
that just came standard with my shader
my UV coordinate that's that's a value
that's a vector - meaning it has an x
and a y component that changes across
the screen and we can use that as an
input for for our shader to make
something a little bit more interesting
so let's have a look and see what that
looks like so first let me set this all
back to white start to black so that's
zero zero zero
there we have black and now let's see
what kind of values are coming from from
this UV thing so I can do you V dot X
which is the X component of my UV
coordinate and I said now we see on the
screen that it's black and left it's
it's red on the right and that is
because my UV coordinate my X component
is zero on the left of the screen and
into one on the right of the screen
[Music]
similarly I can look at what my Y
component holds my Y component holds
something that is zero on the bottom of
the screen and is this one on the top of
the screen so yeah so let me put them
both here to kind of see what that gives
us so now we get something that is black
in the bottom left because both channels
are zero and then as both channels
increase and the diagonal you guys
yellow and on the top right because
yellow is full green plus full red so
now one thing I didn't explain here is
is this because UV is not actually an
input that is giving to us it's
something that we had to calculate and
what this is here is that like what we
actually get as an input is the pixel
coordinate of the pick of the pixel that
we're looking at and the pixel
coordinate depends on the size of the
screen right you could imagine that
right now the size of the screen
depending on my resolution so let's say
600 pixels wide and 250 pixels high but
if I go on full screen like now it's
2,000 pixels wide and and a thousand
pixels high so if we would be using this
here which we could but like then if we
change the resolution afterwards our
effect is going to be different which is
which we don't want so we have to
normalize these coordinates so that's
like
when when people talk about normalizing
something that you'd like usually like
it means that like you be you you bring
an input value to to arrange that you
that you know and arrange that is like
the same in all circumstances so the way
we do that is by dividing the pixel
coordinate by the full resolution of the
viewport so if we had a pixel like say
over here that is at frag coordinate 300
sorry yeah it's 300 from the left and
let's say 200 from the bottom is at 300
200 and after it to be divided by the
full resolution which is 600 400 then we
get 0.5 0.5 so basically what this UV
does is and I'll put it here it's always
good to kind of like know what what your
coordinates are what your parameters are
and in what range they are so sorry so
this one is in the range of 0 to 1 okay
all right so now we could use that to to
start drawing a circle now the first
thing like is well how would we draw a
circle well we could figure out we could
take a point somewhere let's say in the
middle and then we could for every pixel
on the screen we kind of calculate the
distance to that point and if the
distance is larger than the radius of
the circle then the pixel is not part of
the circle if it is smaller than it is
part of the circle so that's one thing
that we could do so we could make a
variable here float D and float a float
stands for a floating point number which
is a basically a real number so it could
be 1 point 2 or minus 2 point 75 or
whatever have you it's but it's one
number
so I can say it's the length of the UV
coordinate and the length of the UK
length of the UV coordinates basically
just the distance the distance from from
the origin from 0 0 0 and the origin is
right here so let's see what that does
and before I do that so over here I have
all my red green and blue channels here
and sometimes it gets a little bit
cumbersome if you only want to work with
black and white or we only want to draw
something simple so I'm just going to go
here and I'm going to say Vic 3c and
[Music]
then I'm going to make a float value
which is a single number call it C and
I'm going to just initialize that to 1
and basically what that does is so now I
only have to deal with one number as
opposed to changing three members all
the time so here I have one number then
over here I I say okay give me a give me
three numbers based on that one number
which like basically if I if I use c1
then basically what this does is it
makes one comma 1 comma 1 alright so now
I would expect to see a wide stream okay
so there's my wide screen so now let's
let's see if we 4.0 you would just take
the distance what we get so now we get
something a little bit more interesting
we get we get a black screen here
because the distance over here is very
close to zero and all the way in the
corner all the way in the corner it is
zero and the distance increases as we go
diagonally across the screen or in any
direction really and over here you can
kind of see already a little bit that we
have a curved line here which which is
where it goes to white and and this is a
distance 1 from the origin all around
here and one thing to notice is it okay
goes from black to gray to white and
then after a while it doesn't change any
but obviously the length the distance
does change because over here the
distance would be the square root of two
right it would be 1 squared plus 1
squared the square root of that that is
the distance from there to there but
it's still just white well that's
because white is the brightest color
that we can make and so whether we set
something to 2 1 which is just white or
we set it to 10 there's no difference
you don't see any difference because it
kind of is outside of the range of what
the monitor can display if we did 0.5
like then we get something that's closer
to black all right so let's just get
back to this so now one thing is if we
want our circle in the middle of the
screen and we need to change something
here and how we can do that is well
again let's just think about it for one
second and so our coordinates right now
they go from 0 to 1 from 0 to 1 okay
but if we want our our circle to be over
here which is at 0.5 0.5 right because
that's zero point 5 in X Direction zero
point five in y direction then we need
to remap that number two to zero so like
if we if if I go here and I go uv- it
equals 0.5 then basically what it does
is it it remaps the range from 0 to 1/2
minus 0.5 to 0.5 right because if I had
0.5 as an input and I subtract 0.5 then
I get 0 which is what I get in the
middle here right so now it's zero here
zero point five zero point five here
minus 0.5 minus 0.5 here all right so
now we have something that's already
quite close to a circle so now what we
could do I mean the simplest way to make
a circle it's not the nicest way but the
simplest way is to just say okay for
every pixel okay if the
we already calculate the distance right
and then we say okay well if the
distance is smaller than a certain value
so if the distance is smaller than let's
say well the radius of our circle so
let's say the radius of the circle is
0.3 then we can set C to white just 0.1
or it's actually three times 0.1 that's
point or it's 1 so it's 1 comma 1 comma
1
otherwise it's 0 which is black right I
forgot of equals all right so and now we
have something that's already almost a
circle so the lips and why is this an
ellipse well it's an ellipse because my
view port isn't square so so over here
we calculate a UV that goes from 0 to 1
both in X and in Y Direction even though
the screen is wider than it is high so
we need to we need to compensate for
that and the way to do that is by
multiplying one of the axes by the
aspect ratio of the screen so what I'm
going to do here is I'm going to UV x x
equals i resolution dot X which is the
width of the viewport divided by I
resolution dot Y which is the height so
so this value here is just the aspect
ratio of the screen okay so let's see
and that got rid of the distortion for
us and now we have a perfect circle very
good now the only problem here is well
problem like there are discontinuities
in our shader meaning that there are
values that are that are one plateau and
then instantly from from one pixel to
the next face snap to another plateau
and generally you don't want
discontinuity
in your in your shader so let's try to
get rid of that so let me just show here
like what else we can do your so let me
open this okay so basically what we have
is we have our circle right okay there's
a circle and this is the center of the
screen right here in the middle okay
it's not exactly but you get the point
and this is our radius right here right
from from here to here so a radius R and
and right now we have values that are
pure white here and like they snap the
black outside outside of the screen so
now if we look at our circle from like
from the side let's say if we just take
this and we look at it from the side
okay I'm just draw I'm just drawing
extending the edges so basically this is
our circle here
inside this is our cent the center of
our circle this is the same R as we have
over here and and the outside let me
just make it in our color so this is the
outside of the circle right and now what
we have and like if we if we look at the
brightness of the pixel so outside of
the circle is black so let's say so so
outside circle my brightness is black
black black black black black black and
then here it snaps the light right and
wife is let's say o it let the
brightness levels over here and then
outside snaps back to zero okay so now
the discontinuity let you have any edge
like it that's what we want to get rid
of so now ideally what we would want is
is something that is is one or it's
white right like in the in in the middle
here and then it goes from white and I'm
gonna exaggerated a little bit
it's goes from white and it goes like
this and it goes down and then it goes
like that and now this this could be a
very short distance but we write D but
but we want it to be like that because
now we don't have any discontinuities
right we don't like our our brightness
level
doesn't have any discontinuities and
even our change in brightness level
doesn't have any discontinuities because
because it goes smooth like this right
so this is what we want and now there is
something like this exact function and
it's called smooth step smooth step all
right down here smooth step and and what
smooth step does is it it steps from one
value to another value let me draw it
again here so it's it go it sits on one
value and as steps to another value but
in a smooth way from here to here okay
and that's very handy and we can use
that in many different places so let me
just get back to the shader and so what
we can do what we can do is let's see
here so it's our C value that we're
using right so I can give it at this for
one second and I can use my smooth step
value so there's it a function called
smooth step and before I do that also
let's let's make a variable just for the
radius of the circle I call it R 0.3
okay
and now my smooth like the smooth step
function has three inputs if I if I go
back real quick to here it has three
inputs what like the first input is the
is the lower the lower threshold and
we'll call it t1 and the second one is
the higher quality too and the and the
third one is our input so so like if our
input is smaller than T 1 it will output
0 if it's larger than T 2 it will output
1 and anywhere in between it will do
that nice smooth step for us so ok so um
let's see here so let's start our t1 is
as R is the radius we wanted to start
stepping at the radius and our t2
we want our - some small value ok 0 1
let's say and then as an input we have
the distance right so let's see what
this does like it might have been subtle
on the screen but it made this softer
and that's and the reason why it's all
is because this is a small value so if I
make this larger you will see that it
makes a blurrier circle so basically all
that does is it makes the smooth step
wider and the reason why this value is
larger than this value so it's it's
actually the opposite as what I showed
on the other on here is because we're
not going from we don't want to go from
low to high we want to go from high to
low right like overeat because like our
distance here and this is confusing I
should that's not our distance and yeah
so when we're when we're close we want
it to be high and over far we want to be
low so we want it to be the opposite of
disc and that's why the values are are
changed around so yeah so this was in a
nutshell well not in a nutshell it was a
very elaborate way of showing you how to
make a circle I hope it helps somebody
and see you next time