My name is Ben, and I teach you
how to write Unity shaders from scratch. In today's video,
we're going to go through this effect where you can see
the objects behind it in this, you know, one colored or two colored
format, right? This object can be scaled. It can be moved. It can also you can also change the colors
if you want, you know, on the fly. Right. So, yeah, let's jump right into it. So in this particular lesson,
there will be some techniques that are a little bit more advanced
than what I've shown you so far. But do bear with me. Try to go through them
and I will try to cover them more in depth in a future video. But also briefly
explain what each one does. So the unity setup we have today
is very simple. It's a game camera and a scene camera. The reason why I've separated these two
showing you both is so that you can see the difference between the two,
because especially when it comes to using depth textures,
it looks a little different in both. The shader setup is very simple. Black is what we're outputting, and this shader is attached to this black sphere behind. We have all these objects that we can use
that will show up in the depth texture. So this shader will take advantage
of the depth texture. The depth texture is actually given to us
by unity. When we sample it, it's actually free to sample
because it's already created by unity. So we just need to grab it from unity
and sample it as simple as that. Now in order to sample this depth texture,
we need something called screen space uvs because the depth texture
encompasses the entire screen. Okay. So let me show you
how to get a screen space uvs float4 in the v2f we'll call it screen space. We'll put it in texcoord1 The math can be done here and the vertex and then we'll pass it
over into the fragment. So we'll do o.screenspace Unity has a function
for us already. Called Compute. ComputeScreenPos And what we need to do
is pass in the vertex. We have to pass in the one
that's already in clip position. Now, in order for us to view the screen space uvs, we'll do float float3 (float2) not 3, screen space uv. And what we need is i. i.screenSpace.xy which is the computed space for us. Divided by W So you can do your own research
on why it's using divide by W. I believe it's to fix up the projection,
especially when it comes to this camera. It's a projected camera. Yeah, perspective camera. So it does,
I believe, some math to kind of fix it up. So let's display the UV here cool. So as you can see, it's, it's worked out. When we bring the circle to the bottom
right here, you can see that it's getting to read to the top
it's becoming yellow in this corner, green and the other corner. Oops, green in this corner
and probably black at this bottom corner. Right. Can't quite see it very black here. So we can see that this sphere or the UVs
is encompassing the entire screen. It's not based on the sphere itself. But it's based on the screen itself. So the screen space texture is sorry,
the texture is already given to us. That's given to us by UnityCG.cginc So all we need to do is declare here
and we should be able to access it. To declare it, it's
sampler2D _CamperaDepthTexture Now, sampling this thing is a little bit
different than sampling the texture. We cannot just use a tex 2D sample. Unity
has its own way of sampling. It has another it's a kind of like
transformed text has its own way to sample it because depending
on the version of device you're using, it could be a projection sample
you could sample only in the red channel. There's a bunch of different ways
to do it. And so I always use
the one that Unity gives us. So the one unit gives us
is called Sample Depth Texture. I think it's as simple as that, actually. So we'll do for depth as equal to sample going depth. SAMPLE_DEPTH_TEXTURE right? And what we need is the depth texture given to us by unity,
and we need the screen space. Let's put that to see what it looks like. Well, I'll put it
just in the Red Oak Okay. So I think this has worked
and there's no errors. So I believe this has worked,
but we need to decode this. This is given this is coming to us
in a way where we cannot even see the red. There might be a reddish tinge here, as you can kind of see a little bit
right here, but it's quite invisible. So we need to decode it
there's two ways to decode it. I think I remember it It's called LinearEyeDepth let's save that off. Yeah. So this is the first way to Decoded. And right now we're seeing just red and I think Unity actually uses this one
to determine if objects should draw behind
or in front of each other. But from our perspective, from our eye,
we cannot see it. I think there are differences in this
red up close and further away, right? You can kind of see it,
but it's not it's not linear. So I guess it's kind of a naming issue. But if you want it to be linear
between zero and one that is zero and one based on this camera instead of "eye" we put the 01 that that is probably
what you guys were more expecting. Now you can see all of the objects
behind it with this depth going on. And you can also see that
it doesn't actually work in the scene. Scene camera doesn't does, but it's doesn't look
the same as what is in the game camera. So you got to make sure the game camera
is there for this to work. Now, keep in mind, linear,
because this is a depth texture. It is based off of the camera
is based off of the near and far plane. So if I change just one or I change the forward to say 100 will actually change this,
the look of this, right? So I brought it to 15
wherever it is close to just enough to see this blue box
so we can see the full effect here. Right. So make sure that when you are doing this
effect, your near and far plane are set properly. So now that this is done. There's a couple of things
we can do to make this more advanced. We can do two colors and lerp
between the two. So let's go ahead and do that. Right. So create color one, color two, no errors. I'm good. So let's do a mixed version. Let's just do a new color float and what we'll do, floats, for now
and maybe convert it to a fix later onto the mixed color will lerp between the first one, color one and color two lerp it based on the depth So now when we select this object, we can select different types of colors. Let's just say we want, oh, I don't know what the objects near us to be dark. And we want the further ones to be
kind of this reddish tinge or even purple or blue so we can kind of, you know,
we can do to do what we want here. So I think I'll leave it into this,
this type of color. Cool. So as I was doing this object (shader), I thought, you know what, it would be really cool
if we can make a drawn edge around it, right? And we're in 3D space. We have this sphere in 3D. So why don't we want to add
a quick fresnel to this? For those of you that don't fresnel is a product
between the normal and the view direction. So that means as as we see
the grazing angles like of the edge of the sphere,
it becomes white or it becomes hotter. And as the sphere is directly
reflecting back at us or the normals of the sphere is looking
back at us, we see this texture. So why don't we quickly add that I think I'll do a separate video on
exactly how fresnel works, if this is a little bit confusing,
but we'll just quickly put it in for now for that to work. We need the normal from the app data
and from here we need to pass in two things. We need a view direction
and we need the normal this will be texcoord2 texcoord3 for the view direction to get the normal from the
from the vertex. It's o.normal to it's always in local space. So we need to make sure
it is in world space. I think it's UnityObjectToWorldNormal I think that's it. If not, I'll Google it after and we need the v.normal save that off. See if it works. Yes. Okay. And the view direction is quite simple
to, viewDir WorldSpaceViewDirection we just need the vertex position I believe of the V of the objects. So and because we are converting it
to world space V direction, I think these are not normalized
so we need to normalize it okay. Let's quickly display our fresnel, we'll do a separate value,
we'll call it float fresnel. I know it looks like "Fresnel",
but it's not. Let's do a quick dot product of i.viewdir and i.normal so see that quickly works yes it does cool to get the edges. We need to do a one minus on it. All right. And if we took our fresnel and we've
multiplied it with our mixed color should get the effect we're looking for. Not quite. We don't need the one minus there. Okay. So now what if you wanted this edge
to have, like, a bit of a color, right? So why don't we
quickly do that or do maybe, you know what? We'll put the main texture We do that instead. So if we look at our for now, again, it's going from white or red to the edge dark. So what we want is
we do want the one minus actually and so now the edges are white or red and if we want to use our col,
what we can do is we can do a final color. float 3 final color to go to lerp between our mixed color,
which is going to be the black to our col, which is the red times, you know lerp bit by Fresnel Cool. So now that is working
and it's using this texture. So whenever you do frenels right some people like to do ramps
to kind of make the edge brighter, right? So ramps, especially on the frensel
itself, will cause it to brighten at the edges like kind of a
like a multiplier but exponentially. So let's do a ramp on that fresnel So I'll call it ramp it's going to be a float default to one because it's a power and our fresnel can now have a power powered by the ramp and that should be it actually. Right. Going to make sure we use the ramp here
so we can use it cool. Now a ramp is one if we set it to say, ten
now that is too much Yeah, we can start to push it
against this edge right and we can also have a multiplier we'll multiply it onto this fresnel yeah. We can also, you know, animate this
if we want it to just quickly add it here. So yeah, in order for us to see this,
I think we would have to play because it doesn't it doesn't properly animate here. (In the game camera) Yeah. And there you go. That's, that's the effect
we were aiming for. So now you have this effect that can scale up looks like this. I don't know if this water texture
is really the right type of texture for this, but yeah, you can do all sorts of cool things with this can change out this green, you can change out yeah. You can have a lot of fun with this one. So I went ahead and also did this
a little bit more advanced version. It's called the Advanced Depth
as opposed to the test that's that we were I was showing you guys earlier,
but this advanced one, all it did is change the way I'm sampling
the UVs to this rotational type effect. I just thought it would be pretty cool,
especially with this sphere that we have. I don't think it'll work
very well on all types of objects though, but it probably won't work well on cubes. And stuff like that. But it works well on, you know,
spheres, mostly spheres, rounded objects, things like that as it relies on,
the fresnel to work, right? So I'll post this in the description
if you guys want, and if you really want an in-depth version
of how this one works, I'm more than happy to do that, but it's
just an adaptation of what we have here. I just change the way
I was sampling the texture. So yeah, so if you guys like what you see, please,
like subscribe and support my channel. I hope you guys learn something
and I'll see you next time, bye now.