Shaders 102 - Basics of Image Effects
ฝัง
- เผยแพร่เมื่อ 24 ส.ค. 2024
- In this episode, we go over the very basics of Image Effects, and implement a screen displacement filter and a box blur.
Code and Resources:
danjohnmoran.co...
Unity Image Effect Reference:
docs.unity3d.co...
Kenney Assets:
kenney.nl
Intro Music by Tommy Moran
/ tommy-moran
I have extended my knowledge of shader stuff which was none simply by doing and tinkering around, I appreciate your Interactive Component stuffs
i laughed, i cried, i learned. The crying bit may be a personal thing.
it's 2020 and this video is still far more simple and clear than many other tutorial based on shader graph. Thank you so much for making and sharing this!
For those who fail to get the code working, this format is only supported at default 3d rendering. It won't work for URP or HDRP. Went nearly insane because of it.
channel changed my life
Love the DKC music in the background
This is fantastic. Subscribed. You'll go far with this!
+PushyPixels Found this Via your Tweet. Thanks for sharing.
Hope you continue making more unity videos. Very nice tutorials. I'll be looking forward to them.
YOU ARE A GREAT TEACHER! Seriously, funny and clever to show something in a very simple way. I've read a lot about shaders, but I feel like I've learn a lot of more watching your videos just in some minutes. You teach me how to create great shaders FX with just a few lines of code, just being creative using not too many elements. Seriosly, I wish I could explain better, sorry for my english.
Just wanted to say you thank you.
Wow, I feel like i'm in a class. This is great!
Great tutorial series! Love to see what´s next. Searched the internet a long time for some good shader-tutorials but this is by far the best one because you explain it piece by piece and not just skip stuff.
First Time I made Image effects myself and understand behind the scenes of rendering! Your tut contains so much info! Thanks, Dude!
I'm loving this series so far. I've been wanting to get into graphics programming for a while, but haven't taken any classes or found any good beginning material until now.
I love your video format, very informative and entertaining! I love the personified information objects such as the coolboy shader splash
Outstanding video, helped me a lot on understanding shaders as I need them a lot to make my games. Your sense of humor adds the cherry on the cake too, I love it. Keep up the good work!
I've never liked a video and subscribed this quickly before
You've made some of the best and most comprehensive Shader tutorials I've ever seen. I'll be expecting more! xD
Keep up the awesome work, loving this series if that's what you'd call it! One recommendation though (if you still look at these old comments) is that I like the intermission/ do it yourself exercises, cause it really helps me see whats going on.
Hey I love your channel. I enjoy how a lot of the skills taught can be transfered to other languages and not just Unity
jazz punk-esque acid trip deal
This is very good! You keep things interesting and informative and FAST. I want to see more stuff from you.
Great video. I like the dkc music.
Some notable info - The blur effect doesn't blur a UI. It blurred the HUD in that scene since they were just sprites. Useful for pause screens and blurring the background behind the UI.
Really nice videos, you already summed up in two videos what took me days to learn.
These are some excellent tutorials, I look forward to the rest of the series. Keep it up!
Updated link to image effects docs: docs.unity3d.com/Manual/PostProcessingWritingEffects.html
goddammit bro i cant believe i found a vid like this. Its amazing, thank you
The music is lit, and so you are
Great Tutorial
Your stuff is awesome! Very informative and extremely interesting.
Hmm I can't seem to access the Code and Resources. It says "It appears you don't have
permission to access this page.
403 Error. Forbidden." This doesn't seem to be working in my game. Do I need a render image assigned to my camera or something?
Edit: I looked closer and it appears that you don't have a render image assigned either, I'm using the Universal Render Pipeline. Can this mess things up?
This is a very informative video, good job
all i get is an error saying "value cannot be null" and it says that the value name is "mat" but i dont have a value or varible called mat anywhere
You are God!! I've been looking for this since i started with Unity!!!
Its amazing how you describe the concepts :/ Nice.
Thanks for the tutorial
Quick and to the point instant like, especially with the I'm not here to waste your time bit awesome
Thanks for the tutorial! I have an issue, I do exactly like you at the beginning and it just doesn't do anything to the image rendered by the camera, I can't understand why
Woot, go Timmies! Thanks for the video!
Just perfect intro
Really nice video! You've helped me so much.
How can I make the water animation? I'm searching for a long time but I don't found what I was searching
wonderful explanations, subbed!
ag i love all the music you use in your vids. and the contents good too of course :']
I Do Love this tutorial! Thank you!
Amazing tutorial .!!!! Thank you so much ....
Hello sir, first of all thanks for your amazing content !
I have a question, I used your AnimatedDisplacement in a 3D scene on a plane and no problems it works perfectly.
But when I use it in a 2D scene on a plane the shader moves. It's start by working fine but then it moves toward the corner top right of my plane until there is no more effect on the entire plane.
I guess it is because I use a 3D object in a 2D scene but how could I fix That ?
I already have a editor script to unable order in layer on mesh.
Thanks a lot and sorry for my bad english !
I tried to apply this effect to a single sprite and cant get it working. Do you have any tips how to do it, set up?
actually quite informative
awesome vid, loving your style bud. Keep it up :)
Thanks dude! nice work!
Great video.
Could you make a tutorial or something where you can explain heat distortion follow a particle effect.
Love your videos. Why is it that for the first effects that are based on the UV, we get an effect based on float4(i.uv.x, 1 - i.uv.y, 0, 1) instead of float4(i.uv.x, i.uv.y, 0, 1)?
This is great, Thank you so much!!!
It's weird, it works if I put the blur on the camera but at every uneven iteration my screen turns black! How so?
Forget it, it was a typo
haha, you got something going here. like it alot. good explanations and reasonably amount of humour :)
Whats the equivalent of "Down Resing" in pure GLSL ? Thnx
Great vid! Keep it up!
Terrific tutorials, keep it up!
I was wondering whether I can apply a "Blur" or a "Decreased light reflection" shader on a material to a 2D Sprite and still get the effect on that singular sprite, without making a quad and manipulating mesh renderers? I've tried this and the sprite renders fine for the most part (albeit without the desired effect :/), except for the transparent parts, which are filled in with surrounding colors from the sprite.
So I guess my question is can you apply shaders/materials directly to a 2D Sprite and even apply a script to it for on-the-fly variable changing? Does this have to be done through the camera object and only using OnRenderImage()?
Thanks!
Do I hear the soundtrack of a water world from a SNES Donkey Kong game?
Ending Credits!!!!! Kudos for that...I haven't heard that soundtrack in a long time!
Idk why but when i tried the example even when distortion is set 0 i get color where there should be alpha. I've missed something I'm sure
Awesome tutorial, fam! Could you go over what bit-shifting is? I've never understood it :(
There's a great explanation here: www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/bitshift.html
but here goes my whirlwind explanation/way of thinking about it:
You know when you move a number over 1 in regular maths it gets multiplied by 10? so 135 moved over a bit = 1350, a bit more = 13500 etc.
The same thing happens in binary but it gets multiplied by 2, which is because our maths is base 10 and binary is base 2.
so 45 = 101101 in binary,
if you take the binary and move it over one (to the left)...
1011010
you get the binary for 90.
similarly for the other way, if in normal maths you take 10 and move it to the right you get 1, if you're doing integers only (no decimals) and you take 132 and move it to the right you get 13. Similarly in binary you get this rounded division by 2 when you move things to the right.
so 45 = 101101 in binary
if you move it over one (to the right)...
010110
and that's the binary for 22.
So how it's used in the video
Z = X >> Y;
is equivalent to
Z = floor(X / (2^Y));
which means divide X by 2 Y times and then round down your result if there's a decimal.
How would you actually animate it at 5:10? Using sin() or cos() doesn't quite make it like yours; it's pulsating back and forth, and not at all like in your video.
Try this:
Inside float4 frag (v2f i) : SV_Target, put
float2 disp = tex2D(_DisplaceTex, i.uv + _Time.x * _Speed).xy;
Can you only have one pass in this render image effect shader? Because I'm trying to make an outline shader with this but it seems to ignore any other passes I give it
Ahh img src = image source. I knew the img tags but never what src stood for. So dst must be destination?
It's all making sense now..
Hi, great content. Straight to the point, simple and yet extremely helpful. I managed to create a nice image effect following your tutorials but the one I did drops the fps drastically... I wanted to ask you if it's possible to pass a lower resolution RenderTexture to the shader? I couldn't find a way to do it.. I am using a filter on every pixel so it would help if l can process less pixels per frame.
Thanks :)
you can simply ignore some pixels regularly in frag function. For example you could process every second or every tenth pixel or so...
Plz explain zbuffer and zwrite kinda sh*** it would help a lot
Okay. I made the Image Effect script just like in the video, created a ImageEffect Shader and applied that to a material, and added that then to the main camera, but nothings changing
oh uhm
nevermind, got it
I do not understand what "algorithm" you have use to make such a smooth heat animation. Could you explain that? I tried to multiply the dist value by _Time and _SinTime but clearly it did not work. I mean, it has no randomness and just looks so ridicolous :v
Thanks
I modified the texture lookup line for the distortion texture like this. It resulted in a cool effect:
float2 disp = tex2D(_DisplaceTex, float2(i.tex.x + _Time.x, i.tex.y)).xy;
It will move the distortion texture to the right constantly. Remember to set the distortion texture Wrap Mode as "Repeat" for this to work.
Probably meant i.uv
Thank you sir
THANK YOU!
This is great, but I'm unclear on one thing. Where does it tell the shader to use the red pixels to shift horizontally and the green pixels to shift vertically?
th-cam.com/video/kpBnIAPtsj8/w-d-xo.html
At this time, see how on line 48 the Texture is first sampled, then swizzled with ".xy"? The x and y here map to red and green. You could actually replace this swizzle with ".rg" and it would do the exact same thing. Swizzles (".xyzw" and ".rgba") are accessors for vector types (like float4). It's convention to use .xyzw for positions/directions and only us .rgba for colors. This particular case is strange because we are treating color data as a direction, so either one would be appropriate really.
Thanks for the quick reply. Thats really helpful.
I wanted to constrain the shift to x. I thought that this might work...
float2 disp = tex2D(_DisplaceTex,i.uv.x).r;
But it didn't. It just seemed to shift all of the pixels on a horizontal row across uniformly. As if the defomation texture was only one pixel wide across the whole screen. (Does that make sense?)
I think I got it. This seems to get the result I was looking for. It's probably wrong for many reasons I don't understand yet thought and will blow up in my stupid face in due course. :)
float disp = tex2D(_DisplaceTex,i.uv);
disp = ((disp * 2) - 1) * _Magnitude;
i.uv.x += disp;
fixed4 col = tex2D(_MainTex, i.uv);
Hey I have a question. Earlier you mentioned that the camera viewport coordinates is (0, 0) for bottom left and (1, 1) for top right. After you apply the shader to the camera, shouldn't the output color be yellow on the top right of the screen and black on the bottom left? Why is that not the case?
Xenosas3055 whoops don't know how I let this slip. This is a common rendering quirk you can read about here: docs.unity3d.com/Manual/SL-PlatformDifferences.html
Ah~~ Alright. So essentially we have to either flip the UVs, or change the graphics API to OpenGL. docs.unity3d.com/Manual/UsingDX11GL3Features.html
Any reason why I shouldn't just do the latter? It'll be a lot more efficient if I don't have to change the uv.y values for every pixel.
Xenosas3055 you can do the uv flip in the vertex shader, so only for the 4 verts of a Blit().
I'll give that a try! Thanks alot! Your channel's really great m8! :D
Is it possible to distort the screen like with that heat effect, but not to affect the UI elements, like life, score, etc?
Yup, you just have to make sure you draw your UI after. So a camera renders the scene, applies an image effect, then a second camera renders the UI.
Thank you for the tutorial :-)
Good videos! Keep it up :D
What program did you use to créate the displacement image, It is posible doing it with Photoshop or a freeware program? Great Tutorials :)
It was made in GIMP (www.gimp.org/) which is free to use! I used the Generate Solid Noise, with the Tileable option turned on. Then I just additively blended some red noise with some green noise.
what's in that CustomImageEffect.cs script??
Hi , i have a doubt ,for me the animated displacement shader gets over within certain time after the game starts.I tried by changing to _Time.y which gives the current game time as u said .but when i give that it kinda stands as if started , its not animating.i dont understand fully i think.so can u give me some tips on that
F*cking brilliant video!!!!
is it possible to apply the displacement shader but only on a single sprite?
+dworm123 Totally possible! You could almost use this shader exactly, but you won't get proper blending. You could edit the default sprite shader to add this distortion and apply that to your sprite though.
I think I'll be covering editing of the default sprite shader in a future video as well.
Question: If we are creating and releasing rt up to 10 times per frame are we creating a lot of garbage for the gc?
(which will result in game freezes every time gc is performed)
Would it be better to keep rt and simply overwrite it each time?
(similar to how pooling is used to reduce garbage)
+Stevepunk holy comments! You're all over the place haha. I'll reply to this one seeing as it has a question in it.
The documentation for "RenderTexture.GetTemporary()" explains that the temp RT's are actually pooled, and only fully destroyed if a similar size and format RT isn't used for a couple frames (literally says "a couple" in the docs, so not sure exactly how many).
So as long as you use that method and the ReleaseTemporary() method, you're in the clear in terms of GC.
+Makin' Stuff Look Good Makes sense! Thanks!
You said, lets read the pixels from the new texture, red for X axis, and green for Y axis to move our uvs... but you just assigned values to float2 value and never read the colours?
Hahah I'll need to explain swizzling better in a future video it seems. See my reply below to tmcthree.
Makin' Stuff Look Good will do, I finished a course in shaders on udemy and im pretty fresh but yeh some things are still unclear
*IN Unity
cool
I'm back for my daily question. Could you explain why you include .xy on line 48? (4:00)
tex2D returns a 4D vector, but I'm setting the value of a float2, so I use the .xy swizzle to grab only the first 2 components of the vector. Otherwise it would error attempting to implicitly cast 4D down to 2D.
Makin' Stuff Look Good Thanks again!
Hi. I'm trying this out and it works, but there is a problem. When time progresses, the effect starts to get stronger and more distorted to the point where it basically disintegrates the screen and gives you a nightmare. Is there a solution so the distortion doesn't gradually get stronger?
Mega Dragon I probably goofed. You might want to try frac(_Time.x) or use a sin wave or something. A repeating function versus just feeding time in, which would do what you described :P
Thanks for the quick response, but I don't think that's the solution. The distortion following sine wave would just get slower as it peaks then starts to reverse the distortion.
The solution I found was adding _Time instead of multiplying it.
I have another question, can you have a mask so that only a part of the texture gets the displacement effect?
Edit: After so many edits, I figured it out! I based my shader on your Hearthstone tutorial. Thank you so much! Hope you'll make more shaders case study and tutorials!
Oh sorry I answered this early in the morning while still a bit groggy haha. Glad you came to a solution.
As for masking, you could use the alpha channel perhaps? It depends on your particular use case. I don't if this is being used as an image effect or per object or what. But basically, whatever that UV distort value is, you want multiply by zero in some areas (disabling distortion) and one in others (full distorted). A grayscale texture would do this fine.
how come some screen effects u use renderimage rather than a shader? I thought a shader could be used for screen effects
You do! OnRenderImage is just a callback you add to a monobehaviour which gives you the camera's output as a RenderTexture. You then use a blit to pass the contents of the screen through a shader :)
oh ok thanks
How do you come with a displacement map texture thou?
Render clouds in Photoshop on the red and green channels separately is a decent quick solution. There are many more complicated ways though and tools floating around. Google for noise texture generator and you'll find lots of stuff you can use, like this thing: cpetry.github.io/TextureGenerator-Online/
Hi sorry I don't know the usefulness of iteration
Can teaching onece again please.
Great video, the quality is obviously improving! I love the additional reading recommendations.
For some reason the Image effect reference link is truncated to: docs.unity3d.com/Manual/comp-I
This might be a TH-cam error tho
+Adam Whitehurst It seems opening up the inline editor and saving can break longer links. And testing my own links by clicking them in the description also opens the inline editor! Absolute madness, but I've fixed the link now and will try not to break it again. Thanks!
+Dan Moran no prob, I'm excited to see more content and watch your videos continue to improve :) so hopefully I can keep helping.
hardddd
is it possible to down res your game for pixel perfect rendering? with shaders that is.
Yes and no. Yes, you can down-rez with point filtering to get the look of "big" pixels. No because it won't be pixel perfect unless you make some other considerations. If your characters/camera still have sub pixel movement, things will still be sampled in weird ways and not look quite right. You have to make sure that everything stays locked to some sort of grid.
Makin' Stuff Look Good Thanks for the reply! It might be worth making a video on the topic some day. Pushy Pixels has a pretty good video on how to do it with a duel camera set up and render textures but I don't think I've ever seen someone do it with just shaders.
dkc2?
Who does the music for your videos?
Background music is usually a random video game track. This one is a DK track by the legendary David Wise.
Intro jingle was composed by my brother.
damn...i didnt know you could write shaders in unity?!?!!?
its really black magic to an ordinary application programmer xD
here we go, another hour of debugging a small scrip of a language i have no idea of, just to find out i have probably forgotten a ";" or something
What the fuck is going on in the background😂😂😂😂 I mean the music