@Drake Lionel yea it works 100% guys. just give your social security bank account and credit card/paypal password. remember to sell your house and car or whatever else you have and deposit money to your bank account. it works better this way. only con is that you go bankrupt or homeless but hey you gotta compromise something too , right
"... on the fly shader generation..." As if my mind weren't blown enough already. I'm loving these videos! You are an amazing teacher! You go in depth but always remain within the scope of the discussion. Excellent.
Thank you for this video. It has helped me clarify a few things in my mind. I'm going to go back and look at my own shader code now that you pointed out how many times the fragment shader is run in comparison to the vertex shader (I have a nasty feeling that my code will need a rewrite). It just those simple obvious pieces of information that can make such a difference. Also, I can't wait for when you show us more complex shaders.
Beautifully explained. As somebody who has worked with shaders for the past 7 years, I am glad more light and accessible information is being tread on this amazing world of technology. I will be recommending this video to people for sure!
there are SO many cuts in Cherno videos xD he very often only says one sentence per cut but he cuts cleverly to not disturb the audio too much so it seems like he's talking in one stream
@@TinoBurset Just noticed one at 2:36, but there are more. I guess one way round it is to use multiple cameras and switch between them but the actual content is the important thing.
@6:24 ;) The beautifull thing for me is to see people making great tutorials and videos, helping other to improve their own skills. Thank you for that man! It is a pleasure to listen to your videos.
I just stumbled upon this video by chanse, and I love your teaching style. You're extremely pedagogic in the way you teach. You repeat yourself with different wording and examples so we get different types of understandings for the same issue you're trying to teach, and it works tremendously! Great video!
I spent a semester on a GPU programming course at my university and didn't get a word of what our "experienced" professor said! Even until the end of the semester, I didn't know what shader or even OpenGL is. I hated that course. But now with only 6 short videos, BANG, everything makes sense and is easy to understand. Come to Switzerland and become a university professor Cherno. You're just fantastic.
So in summary. - Vertex shader is called for each vertex. (used just for position) - Fragment shader (pixel shader) runs for each pixel that has to be rasterised.
@@shashanktambe6341 Basically a vector function like you have in math. For example y = 2x where x = {1..10} all the pixels from (1,2) to (10, 20) will be rasterized.
Great explanation. I think its a great idea to give examples with modern game engines as well, in Unity or Unreal (in Unity->Shadergraph, in Unreal->Material Editor) you are actually making fragment shaders. There is also a part where you can also specify vertex positions as well, thats the vertex shader. In Unreal thats World Offset in the Material Editor. In Unity, if you are writing a shader completely in HLSL, you can also access the vertex shader, and you can see that all it does is get the world positions and then multiply them by the MVP matrix (model view projection matrix) to get the position it needs to have on the screen. For me it clicked when I saw these things in the programs I use everyday. I hope it helps someone trying to understand them as well.
In the beginning you were explaining that glDrawArrays draws the currently bound VertexBuffer, but just above the while loop you've bound it to 0. How is it still drawing the triangle in this case?
This got me thinking. I found this in the docs: Buffer object names are unsigned integers. The value zero is reserved, but there is no default buffer object for each buffer object target. Instead, buffer set to zero effectively unbinds any buffer object previously bound, and restores client memory usage for that buffer object target (if supported for that target). Buffer object names and the corresponding buffer object contents are local to the shared object space of the current GL rendering context; two rendering contexts share buffer object names only if they explicitly enable sharing between contexts through the appropriate GL windows interfaces functions. But don't exactly know what it means in the last part
Hi I have question here from opengl series video number 5 glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, 6*sizeof(float),position,GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); // Why still we see Triangle rendered even we are unbinding the buffer here? can anyone please help me to understand?
I really love that this does not feels like someone reading a Wikipedia page to me. I really love how you explain the fundamentals and why we use them as well to make sense. Thanks a lot for these videos man!
I had a subject named computer graphics in my post graduate. My teacher didnt teach, but was strict in class, telling to write notes record note so on. Literally saying, you are teaching so good.
I'm trying to get up to speed in OpenGL, and was looking for something on shaders. Found this video, and was so impressed I'm now working through the entire playlist. I'd originally avoided it because I'm actually working in Go -- but I figured, what the heck, apart from a few language-specific differences, it all works basically the same; sure, I can translate from C++ (which I've not used for literally decades) to Go (which I've only just begun tinkering with...) :-) Wrapping my head around three-four languages at once is about par for the course! ;-)
I'm coming to this series in 2024, and the comments all being in agreement that this tutorial is what we all needed to learn this skill is so entertaining to me
I don't really think i can ever find such easy-understandable tutorial about OpenGL and Graphics Programming, which is really complicated by itself. Aah, and of course: drawing the best triangle in my life is priceless :)
I don't think that's possible, as the result of the compilation may be driver-dependant. Plus I don't think OpenGL provides any way to actually copy those compiled shaders to the GPU memory.
You could do that but this will bind the shader to your graphics card as it uses the compiler in the graphics driver to compile your code to the graphics card. And no the program gets only compiled once only if you add glCompileShader to the loop it would do that else you could use the program handle. Also there is a platform independent way to compile you shader the output is then called SpirV shader assembly.
Hii Cherno.. I need to render camera captured images using fragment shaders, the camera inputs and parameters come from a structure in another file, I need to pass them to my shader class and render them. There are 4 cameras. How do I do it please help me. I have seen many tutorials where they are using some functions to load the image, where we specify file path, but that is only for 1 file. I have 4 camera data's. I'm finding it difficult. Can you please help me?
So I was reading this on learnopenLG and did try it that I cannot render the vertex budder object unless I have it binded to an vertex array object, idk if this is specific to a Mac or not. I'd really like to know if it is necessary to use a VAO before using any VBO to render anything at all??? Ahhh.... save me from this confusion.
Question: Do you only have one vertexshader and one fragment shader for all your mesh? Let say you have a 3D mesh shader. Do you need to make a new one for a 2D mesh? What about if you have a shader which handles lighting. Do you use the same shader to handle objects which you don't want to be lighted or do you create new shaders for all the different cases?
One thing I wonder about current GPUs is why they are still reliant on the CPU performing draw calls. Wouldn't it be more efficient to be able to tell the GPU directly via some sort of programmable function when to draw stuff? With how busy the CPU already is it seems like alot of work added to the CPU to constantly have to perform draw calls to make the GPU do its job. Maybe I'm just too much of a newb but it just sounds like alot of work for the CPU that could just be done by a processor within the GPU itself
How come that's happening: Yes, but now shouldn't this fail because the buffer is unbound? Did I really hallucinate that in a previous video it was said that if we unbind the buffer then opengl will not draw anything?
Is the fragment shader run for each pixel of the display, or for each pixel of a triangle/shape? As in, if I have a drawing area that is 1280x720 and 3 triangles all in the same exact spot that cover, say, 50 pixels worth of the display, will the fragment shader be called 921,600 times (1280 times 720), 150 times (because 3 triangles cover 50 pixels each), or just 50 times (because all 3 affect the same pixels)?
150 times. EXCEPT if you have depth buffer enabled. In which case GPU may consider not to call fragment shader for the pixels which have their z-value less than in a buffer. What is z-buffer? Its a thing that OpenGL uses to prevent things behind other things to get drawn. (great explanation)
I had a problem with OpenGL ES1.1 on my tablet. My app wouldn't draw anything. Which lets me to believe that compiling shaders is mandatory. But the shader functions arent in the opengles1.1 header! And my question is, how do I deal with this situation? I was trying to solve this program for around 2 yeras now (not really trying all that time, because I switched to developing the PC game) Any help?
In the plain old architecture we used to provide even the coordinates of vertex in the draw call, now it has been replaced by buffer and shaders. Why???
So, at the simplest level, the vertex buffer details where vertices are in relation to each other, the vertex shaders determine where they are in relation to the screen?
If position is the only data in the buffer, then yes, you could think of them as coordinates in local space. The shader then has transformations to change that to world space, screen space, etc.
How is it possible that it worked in the beginning although we have bound buffer 0 before start of the while loop? I thought (and I think he has even said it in the end of the episode before the previous episode) that it will not work like this because we have to bind the right buffer in order... I am confused, could you please explain it to me?
think of binding the buffer as a rotating bridge. Once the data has been sent to GL_ARRAY_BUFFER(&buffername), the bridge to the &buffername is no longer needed and can be reset or set to another buffer. Setting it to 0 is one way to prevent accidental data transfer to the wrong place.
@@TheKingoftheriff thanks for answer, but how does then opengl know which buffer to use if I uploaded more vertex buffers. I thought it always uses the bound vertex buffer.
@@jakubhorak636 AFAIK, the draw function that outputs all the poly work, will put all the saved buffers on the screen. You only need &buffername while sending data. Currently all of it is stored in GL_ARRAY_BUFFER, which is like an area for all the buffers that belong to that type.
This better be the most beautiful triangle ive ever seen...
it will be, every dumpling it's beautifull for his mum
You havent tried vulkan yet have you?
I drawn a rectangle cause im badass
@@dualperception4296 No, he hasn't
@Drake Lionel yea it works 100% guys. just give your social security bank account and credit card/paypal password.
remember to sell your house and car or whatever else you have and deposit money to your bank account. it works better this way.
only con is that you go bankrupt or homeless but hey you gotta compromise something too , right
Other UA-camrs : Uses Drawings to Explain
The Cherno : Just talk and Draws on Viewer's Mind
Couldn't've said it better
The movement of his hands help with that
Legend of TheCherno
Best C++ and OpenGL tutorials EVER!
"... on the fly shader generation..." As if my mind weren't blown enough already.
I'm loving these videos! You are an amazing teacher! You go in depth but always remain within the scope of the discussion. Excellent.
I'm having a college class on computer graphics and these videos are helping a lot! Please keep up the great work
Same
us
Leiria?
so you graduated?
@@ghw2402 ahah yes I did, and I'm currently working at Envar Studio
OH YEAH TRIANGLE, THE NEXT TIME I WILL SEE YOU !!!
Thank you for this video. It has helped me clarify a few things in my mind. I'm going to go back and look at my own shader code now that you pointed out how many times the fragment shader is run in comparison to the vertex shader (I have a nasty feeling that my code will need a rewrite). It just those simple obvious pieces of information that can make such a difference. Also, I can't wait for when you show us more complex shaders.
Beautifully explained. As somebody who has worked with shaders for the past 7 years, I am glad more light and accessible information is being tread on this amazing world of technology. I will be recommending this video to people for sure!
I'm 10 minutes in and just realized that there were no cuts in the video, with an spectacular and well paced explanation. Simply amazing content man!
there are SO many cuts in Cherno videos xD he very often only says one sentence per cut but he cuts cleverly to not disturb the audio too much so it seems like he's talking in one stream
@@bumpsy You are absolutely right! 😆 I guess that it _felt_ that way at the time.
@@TinoBurset Just noticed one at 2:36, but there are more. I guess one way round it is to use multiple cameras and switch between them but the actual content is the important thing.
there is one two seconds later at 10:02 lmao
I didn't know shaders were generated on the fly. That's pretty cool.
what do you think happens when you go forward holding a flashlight/torch and the intensity of the light on the wall before you increases lol?
@@deletevil That's not generating an entire System-specific shader during runtime. that's just a shader.
@@AmeshaSpentaArmaiti , aah okay, thanks. I am a noob learning.
@@deletevil then why would you say that with such confidence if you're just learning? A little humility goes a long way
@@generichuman_ and what are 'you' gaining from by replaying to a noob like that?
@6:24 ;) The beautifull thing for me is to see people making great tutorials and videos, helping other to improve their own skills. Thank you for that man! It is a pleasure to listen to your videos.
Insane teaching skills, thank you
I just stumbled upon this video by chanse, and I love your teaching style. You're extremely pedagogic in the way you teach. You repeat yourself with different wording and examples so we get different types of understandings for the same issue you're trying to teach, and it works tremendously! Great video!
This is the most detailed explaination! Helps so much on visualising the shader pipeline!
I spent a semester on a GPU programming course at my university and didn't get a word of what our "experienced" professor said! Even until the end of the semester, I didn't know what shader or even OpenGL is. I hated that course. But now with only 6 short videos, BANG, everything makes sense and is easy to understand. Come to Switzerland and become a university professor Cherno. You're just fantastic.
I'd say you forgot a cut at 3:10
ye ye he deffo forgor
So in summary.
- Vertex shader is called for each vertex. (used just for position)
- Fragment shader (pixel shader) runs for each pixel that has to be rasterised.
What is rasterisation?
@@shashanktambe6341 Basically a vector function like you have in math. For example y = 2x where x = {1..10} all the pixels from (1,2) to (10, 20) will be rasterized.
@@RudolfCickoMusic thanks for coming back to comment
"When it comes time to optimize and think about performance, which is really all the time" Thank you for making me feel less crazy.
Great explanation. I think its a great idea to give examples with modern game engines as well, in Unity or Unreal (in Unity->Shadergraph, in Unreal->Material Editor) you are actually making fragment shaders. There is also a part where you can also specify vertex positions as well, thats the vertex shader. In Unreal thats World Offset in the Material Editor.
In Unity, if you are writing a shader completely in HLSL, you can also access the vertex shader, and you can see that all it does is get the world positions and then multiply them by the MVP matrix (model view projection matrix) to get the position it needs to have on the screen.
For me it clicked when I saw these things in the programs I use everyday. I hope it helps someone trying to understand them as well.
In the beginning you were explaining that glDrawArrays draws the currently bound VertexBuffer, but just above the while loop you've bound it to 0. How is it still drawing the triangle in this case?
That's also what I didn't get
the glBindBuffer(0) unbinds the buffer. After this we can write to the buffer
This got me thinking. I found this in the docs:
Buffer object names are unsigned integers. The value zero is reserved, but there is no default buffer object for each buffer object target. Instead, buffer set to zero effectively unbinds any buffer object previously bound, and restores client memory usage for that buffer object target (if supported for that target). Buffer object names and the corresponding buffer object contents are local to the shared object space of the current GL rendering context; two rendering contexts share buffer object names only if they explicitly enable sharing between contexts through the appropriate GL windows interfaces functions.
But don't exactly know what it means in the last part
I have never found such a clear and thorough explanation of this anywhere else. Thank you for making this.
I will soon start working with openGl and your videos are really good to refresh my memory with it. Thank you for the awesome tutorials.
You explain so clearly ❤️
Keep doing this ❤️🙂
Man, the quality of your videos is just amazing. Keep up the good work!
Very good explanation, just subscribed!
And I am your subscriber!!!! lol
Hi
I have question here from opengl series video number 5
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 6*sizeof(float),position,GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0); // Why still we see Triangle rendered even we are unbinding the buffer here? can anyone please help me to understand?
I really love that this does not feels like someone reading a Wikipedia page to me. I really love how you explain the fundamentals and why we use them as well to make sense. Thanks a lot for these videos man!
When I was thinking of OpenGL... THIS came out! Nice!
yep. same dude!
sadly is not everyday
not even drawing or using animations and this still is one of the best explanations
Your explanations are so clear and easy to understand! Thank you so much for this series, it's really awesome. :)
The best explanation in the internet
My man making an OpenGL Tutorial Series
i would have gave up if you didn't make a series
*keep up*
I had a subject named computer graphics in my post graduate. My teacher didnt teach, but was strict in class, telling to write notes record note so on. Literally saying, you are teaching so good.
You made me think now! And visualize without coding or learning anything!
Sunday: (TheCherno && ThinMatrix ) == Kreygasm
@@lufenmartofilia5804 Two best on my option teachers EVER! And also awesome guys! (TheChernoMatrix)
Can't wait to create my first Shader. Thanks!
I'm trying to get up to speed in OpenGL, and was looking for something on shaders. Found this video, and was so impressed I'm now working through the entire playlist. I'd originally avoided it because I'm actually working in Go -- but I figured, what the heck, apart from a few language-specific differences, it all works basically the same; sure, I can translate from C++ (which I've not used for literally decades) to Go (which I've only just begun tinkering with...) :-) Wrapping my head around three-four languages at once is about par for the course! ;-)
he got Electronic Arts team perform every intro
Can you please make a video about unions in your c++ series
Mitesh Sharma he already did in the sparky engine series 5.5
My possibilities are exploding right now. Thanks for the awesome tutorials! :D
your hands are freaking me out but by purely listining to you it's excellent! thanks so much!
These videos, excellent quality.
clean and clear intro for shader. Keep doing
Thank you! Your explanation is very easy to understand.
Thank you so much for the quality content!
Thanks man, you are really good teacher.
This is fantastic! love this explanation!
I'm coming to this series in 2024, and the comments all being in agreement that this tutorial is what we all needed to learn this skill is so entertaining to me
I don't really think i can ever find such easy-understandable tutorial about OpenGL and Graphics Programming, which is really complicated by itself.
Aah, and of course: drawing the best triangle in my life is priceless :)
when i hear "shaders" all that comes to my mind are Minecraft shaders
kek same
and they have to be written in code too
That is because Minecraft uses them, they allow you to do amazing stuff.
Would it be practical to save compiled shaders (programs are saved as .exe) instead of compiling each time the program runs?
I don't think that's possible, as the result of the compilation may be driver-dependant. Plus I don't think OpenGL provides any way to actually copy those compiled shaders to the GPU memory.
You could do that but this will bind the shader to your graphics card as it uses the compiler in the graphics driver to compile your code to the graphics card. And no the program gets only compiled once only if you add glCompileShader to the loop it would do that else you could use the program handle. Also there is a platform independent way to compile you shader the output is then called SpirV shader assembly.
Sos crack, colorado. Gracias!
You are doing something "good" for the society. Appreciate it.
ah yes, an entire video (without coding) just explaining shaders. I love your explanations!!
I love his hoodie
I feel like I'm learning so much!
Hii Cherno.. I need to render camera captured images using fragment shaders, the camera inputs and parameters come from a structure in another file, I need to pass them to my shader class and render them. There are 4 cameras. How do I do it please help me. I have seen many tutorials where they are using some functions to load the image, where we specify file path, but that is only for 1 file. I have 4 camera data's. I'm finding it difficult. Can you please help me?
#Notifacation Squad!!!!
you are my favorite UA-camr ever!!!!
Cherno
So I was reading this on learnopenLG and did try it that I cannot render the vertex budder object unless I have it binded to an vertex array object, idk if this is specific to a Mac or not. I'd really like to know if it is necessary to use a VAO before using any VBO to render anything at all??? Ahhh.... save me from this confusion.
I have a difficult time expressing how much I enjoy these videos. That said it is meant in a strictly non-stocker way... Obviously...
You have a gift for explaining things. Keep up the excellent work, we're tuned in :D
Question: Do you only have one vertexshader and one fragment shader for all your mesh? Let say you have a 3D mesh shader. Do you need to make a new one for a 2D mesh? What about if you have a shader which handles lighting. Do you use the same shader to handle objects which you don't want to be lighted or do you create new shaders for all the different cases?
Greatt, thanks. You should write the opengl documentation
great video again
Other tutorials just assume this will work -- so that I took it that the default shader was a universal hold-over from the pre-shader era.
Sooooooooo much information!
i love cherno video thanks
I always watch through all the ads so he can get his money
One thing I wonder about current GPUs is why they are still reliant on the CPU performing draw calls. Wouldn't it be more efficient to be able to tell the GPU directly via some sort of programmable function when to draw stuff? With how busy the CPU already is it seems like alot of work added to the CPU to constantly have to perform draw calls to make the GPU do its job.
Maybe I'm just too much of a newb but it just sounds like alot of work for the CPU that could just be done by a processor within the GPU itself
yo i am eating a cadbury egg while watchin this. this is awesome
Love your videos
Watching that "glBindBuffer(GL_ARRAY_BUFFER, 0);" line is just killing me
Consider that line as a function to unbind the buffer. You are just telling OpenGL that your bound buffer is 0, so nothing
Thank you.
The fragment shader only does one thing, decide what colour each pixel will be. That's all it does... That one simple task........
I drew a quad on a screen without help... It means I understood your lessons well.
ARE YOU SURE??? IT'S ACTUALLY NOT A TRIANGLE?
Why is the Triangle Rendering? The buffer ist not bound because of the glBindBuffer(GL_ARRAY_BUFFER, 0);
How come that's happening:
Yes, but now shouldn't this fail because the buffer is unbound? Did I really hallucinate that in a previous video it was said that if we unbind the buffer then opengl will not draw anything?
Is the fragment shader run for each pixel of the display, or for each pixel of a triangle/shape? As in, if I have a drawing area that is 1280x720 and 3 triangles all in the same exact spot that cover, say, 50 pixels worth of the display, will the fragment shader be called 921,600 times (1280 times 720), 150 times (because 3 triangles cover 50 pixels each), or just 50 times (because all 3 affect the same pixels)?
150 times.
EXCEPT if you have depth buffer enabled. In which case GPU may consider not to call fragment shader for the pixels which have their z-value less than in a buffer.
What is z-buffer? Its a thing that OpenGL uses to prevent things behind other things to get drawn. (great explanation)
I had a problem with OpenGL ES1.1 on my tablet. My app wouldn't draw anything.
Which lets me to believe that compiling shaders is mandatory.
But the shader functions arent in the opengles1.1 header!
And my question is, how do I deal with this situation?
I was trying to solve this program for around 2 yeras now
(not really trying all that time, because I switched to developing the PC game)
Any help?
OpenGL 1.1 and OpenGL ES 1.1 don't support shaders. You need to use at least GL ES 2.0 I think
Ahaa.
So basically vertex shader = the outline
fragment shader = what comes in.
In the plain old architecture we used to provide even the coordinates of vertex in the draw call, now it has been replaced by buffer and shaders. Why???
The quality is at par with the course I'm taking at edx (Computer Graphics), in fact way better as compared to that course. B-)
where is your say thanks link?
cherno reminds me of that city,chernobil
on NV works too
So, at the simplest level, the vertex buffer details where vertices are in relation to each other, the vertex shaders determine where they are in relation to the screen?
If position is the only data in the buffer, then yes, you could think of them as coordinates in local space. The shader then has transformations to change that to world space, screen space, etc.
Your'e the best!
everytime i hear the word "shader" i instantly think of minecraft
Whats shaders i need to mine with my gpu?
Yea the naming of shading is bit confusing
THX
How is it possible that it worked in the beginning although we have bound buffer 0 before start of the while loop? I thought (and I think he has even said it in the end of the episode before the previous episode) that it will not work like this because we have to bind the right buffer in order... I am confused, could you please explain it to me?
think of binding the buffer as a rotating bridge. Once the data has been sent to GL_ARRAY_BUFFER(&buffername), the bridge to the &buffername is no longer needed and can be reset or set to another buffer. Setting it to 0 is one way to prevent accidental data transfer to the wrong place.
@@TheKingoftheriff thanks for answer, but how does then opengl know which buffer to use if I uploaded more vertex buffers. I thought it always uses the bound vertex buffer.
@@jakubhorak636 AFAIK, the draw function that outputs all the poly work, will put all the saved buffers on the screen. You only need &buffername while sending data. Currently all of it is stored in GL_ARRAY_BUFFER, which is like an area for all the buffers that belong to that type.
3:09 you forgot to cut there, man
program that runs on GPU
what's intro music name?
Is this projekt avaible on github?
What's the language of a shader?
Please make a series on directx
Mine doesn't have a default shader then......
I wrote exactly same code but it crashed.