Live data from Hacker News

Interactive intro to shaders

mayerowitz.io

41–50 of 72 posts

Re: Interactive intro to shaders

#41
This is my understanding of shaders:

Drawing a line on the CPU: a function looping through each pixel between point A and B and draw one pixel at a time sequentially. Runs once with exactly as many steps as there are pixels in the line.

Drawing a line on the GPU: a function checking if the pixel is on the line or not and draw if it's a match. Runs on all pixels on the screen at the same time, even ones that are far from the line.

Is this correct?

Re: Interactive intro to shaders

#42
I have never dealt with shaders, so pardon me if it's a very basic question. In a single frame from a game, are shaders essentially all that are being used to draw it?

Or do we have basic shapes like triangles, squares, circles, etc and the shaders go on top of it, drawing shadows, smoothing edges, etc?

From the example, it seems like you can create a shader to draw any object in a scene, and then I imagine you compose other shaders to get shadows and lightning and all of that. In the very limiting experience I had with drawing, I drew shapes but never through shaders. I always thought they didn't draw the objects themselves.

Re: Interactive intro to shaders

#43
post #23

Very nice, I've tried looking at a couple other tutorials in the past but they always assume more prior knowledge than I have. This really hits the sweet spot for me. Would love to see tutorials on more topics. In particular, a very basic lighting model but with a detailed breakdown on how normals and dot product work together. Yes, there's plenty of info out there, but I think your teaching style would still make it…

> a detailed breakdown on how normals and dot product work together

Normals point away from faces, straight out from faces. A surface normal is the direction the surface is facing. The dot product of 2 vectors measures how "aligned" they are, indeed, one definition of the dot product is defined in terms of the angle between the two vectors.

Also, remember that the vector opperation (A - B) results in a vector going from B to A. Thus (light_direction - face_center) is a vector from the face to the light, and (light_direction - face_center).dot(face_normal) gives us a numeric value that is higher when the face is pointing towards the light source.

You'll have to look to linear algebra for a deep understanding: https://youtu.be/LyGKycYT2v0?si=lWr38mH34yGRSJpv

I also recommend an informal (but rigorous enough) textbook called "Linear Algebra: Theory, Intuition, Code" which teaches through conversational written explanations, mathematical notation, and code. GPT4 is also quite competent at teaching linear algebra and, in my experience, is able to distinguish between correct and incorrect mathematical proofs; a good textbook is still a better primary source though.

Re: Interactive intro to shaders

#44
post #16

I finally found the courage to write and expose myself to the internet. I've always wanted to learn shaders so I thought it would be nice to document my learning and share it with others.

You can improve your antialiasing, assuming you're willing to use the well-supported OES_standard_derivatives extension (or WebGL 2). Instead of doing smoothstep(0.0f, 0.01f, dist); with the constants picks sort of at random, instead do smoothstep(fwidth(dist), -fwidth(dist), dist);

Didn't know that, thanks for the tip!

Re: Interactive intro to shaders

#45
post #42

I have never dealt with shaders, so pardon me if it's a very basic question. In a single frame from a game, are shaders essentially all that are being used to draw it? Or do we have basic shapes like triangles, squares, circles, etc and the shaders go on top of it, drawing shadows, smoothing edges, etc? From the example, it seems like you can create a shader to draw any object in a scene, and then I imagine you compo…

Yes, the color of every pixel is ultimately determined by a shader program, but as you might expect it's more complicated then that.

There is what is referred to as a graphics pipeline consisting of a mix of fixed-function hardware stages and programmable stages. At a high level, it does the following: 1) the GPU accepts a set of 3D triangles from the CPU, 2) a 'vertex' shader program transforms (flattens) the 3D triangle vertices into 2D triangle vertices with pixel coordinates, 3) the GPU rasterizes the 2D triangles to determine exactly which pixels the triangles cover, 4) a 'pixel' shader program is run for each covered pixel to determine the color of the pixel, 5) the resulting pixel color is stored in a frame buffer (which may involve blending it with the existing color). This 'pipeline' is then repeated many times (with different triangle meshes and shaders) until the whole frame is drawn.

Hope that helps!

Re: Interactive intro to shaders

#46
In case anyone else was seeing the images as flickering noise, my fix was to copy the image from the browser and paste those somewhere else. You can view the images correctly.

Link to imgur. The first image is screenshot of what I see in the browser. The rest are actual images after pasting to imgur.

https://imgur.com/a/F4203rz

Re: Interactive intro to shaders

#47
post #42

I have never dealt with shaders, so pardon me if it's a very basic question. In a single frame from a game, are shaders essentially all that are being used to draw it? Or do we have basic shapes like triangles, squares, circles, etc and the shaders go on top of it, drawing shadows, smoothing edges, etc? From the example, it seems like you can create a shader to draw any object in a scene, and then I imagine you compo…

Shaders do all the drawing, but it does so in different stages. I won't explain the entire graphics pipline[1], but a lot (some 90%+) of what people casually think of as "shaders" for doing lighting effects are the fragment/pixel shader stage of the renderer.

there are other stages (vertex, tesselation) that draw those basic shapes before the fragment shader draws "on top" of the scene.

(there is also a lot more to what I described for fragment shaders. e.g. deferred rendering[2]. But that's an equally large topic to get into).

1: https://vulkan-tutorial.com/Drawing_a_triangle/Graphics_pipe...

2: https://learnopengl.com/Advanced-Lighting/Deferred-Shading

Re: Interactive intro to shaders

#48
post #46

In case anyone else was seeing the images as flickering noise, my fix was to copy the image from the browser and paste those somewhere else. You can view the images correctly. Link to imgur. The first image is screenshot of what I see in the browser. The rest are actual images after pasting to imgur. https://imgur.com/a/F4203rz

That's strange, what browser are you using?

Re: Interactive intro to shaders

#49
post #15

The article is quite nice. However, it glosses over the primary problem with shaders. A shader is a pain in the ass that most programs and applications don't want. 3D stuff likes triangles and the GPUs are happy to slot into that abstraction. Shaders are useful to interpolate over those triangles. Triangles are mostly garbage for everybody else. 2D rendering wants paths. Font rendering wants paths or pixmaps. GUI's w…

>A shader is a pain in the ass that most programs and applications don't want.

As a devil's advocate: most programs don't necessarily require the GPU to achieve what they want. 3d stuff nigh requires such parallelism once you go past a very small scale.

That was the mindset in the 00's at least. Software has gotten more complex to the point where the GPU may be a desired optimization to make, but the GPU pipeline has always been strict and closed down, and the paradigms from single to multi-core programming often require different algorithms. GPGPU programming can liberate you from the need to work in triangles, but you still need to take a completely different approach if you want to enjoy that parallelism.

Re: Interactive intro to shaders

#50
post #41

This is my understanding of shaders: Drawing a line on the CPU: a function looping through each pixel between point A and B and draw one pixel at a time sequentially. Runs once with exactly as many steps as there are pixels in the line. Drawing a line on the GPU: a function checking if the pixel is on the line or not and draw if it's a match. Runs on all pixels on the screen at the same time, even ones that are far f…

Not exactly. First, a GPU can't run a pixel shader against EVERY pixel simultaneously. A typical screen might have about two million pixels, while GPUs max out at a few thousand concurrent 'threads of execution' i.e. it effectively draws in chunks of a few thousand pixels at a time. Second, the GPU doesn't need to run pixel shaders against a whole screen, it's capable of running shaders against any arbitrary shape you like using triangles. So the efficient way to draw a line is to send the GPU two triangles that match the line geometry that you want, and then only run the pixel shader on the pixels that the triangles overlap. Much more efficient.
Post reply on HN