How To Render CIRCLES (OpenGL/Vulkan/DirectX/Metal)

preview_player
Показать описание


Рекомендации по теме
Комментарии
Автор

Hope y’all enjoyed the video! What topic do you want to see me cover next?

TheCherno
Автор

You don't need the square root, sqrt(x^2 + y^2) < 1 is equivalent to x^2 + y^2 < 1, save a few GPU cycles ;)

fmdj
Автор

I learned about such a Soft and Round circle rendering technique, in a book: "The Book of Shaders". Really good book for beginners (and not only) will help you in shader coding and understanding.

faris
Автор

A "non-filled in circle" is called a circle. A filled in one is called a disk (It's actually more complicated than that but that's the simple explanation)

zzedixx
Автор

That's a smooth and soft tutorial

kalakxfif
Автор

As simple as a circle is, it took me a while to even get the concept of how to render one. Thanks for this video.

FerrumMusicVideos
Автор

I just found your channel and it's awesome to finally find some premium quality Aussie content that's actually interesting as Zenva didn't agree with my ADHD.

slowfastdog
Автор

Your channel is highly underrated views wise. That said I like your videos and find them highly useful
Thanks man

aaron
Автор

Something that works even better than a static "fade" amount is to scale it depending on the fragment size. In OpenGL 3, this is surprisingly easy to compute by using derivatives:

const float sqrt2 = sqrt(2.0);
float fade = sqrt2 * length(vec2(dFdx(distance), dFdy(distance)));

This produces a pixel-resolution fade which works even when the quad is distorted.

If you want an even crisper, but still antialiased, edge, you can use a linear smoothstep (which I call "lerpstep"). It is essentially the convolution of step() with a box filter.

float lerpstep(float edge, float delta, float x) {
float edge0 = edge - delta;
float edge1 = edge + delta;
return clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// etc etc
float distance = length(uv);
float fade = length(vec2(dFdx(distance), dFdy(distance)));
float alpha = lerpstep(thickness, fade, distance) - lerpstep(1.0, fade, distance);
// etc etc
}

DeGuerre
Автор

Love the videos man, they're great to send to beginners; make sure you get up and get your steps in; gotta pay attention when you're working from home long term.

microcolonel
Автор

Filled in “circle” = Disc
“Circle” outline = Circle

mickeym.
Автор

the smoothstep function has one draw back, if you increase or decrease the size of the circle you either get antialising again because the smoothstep threshold is to small or you get a blurry edge because the threshold is too big, a somewhat good alternative is to use the fwidth function to calculate the edge smoothing, since it uses derivatives they are "screen size" aware so it doesn't matter which size your circle is in the screen, the draw back is that it's a bit more expensive and derivatives uses 2x2 pixel blocks which in some shapes can be seen, it's not the case with circles tho

not sure how derivatives work with shadertoy but the final code would be: distance / fwidth( distance )

kebrus
Автор

I need more shadertoys series! Thanks, Yan <3

vladprusakov
Автор

i like renderer topic the most, it's your speciality. keep it up please and good luck

MrDimakoles
Автор

Throughout the whole video I was wondering how you were gonna make the edges smooth. I don't know if there are other, more efficient anti aliasing methods, but isn't it weird to have a anti aliasing function (=smoothstep) that depends on the number of pixels of the radius? Like, it you make the circle very small, you have to change the fade value, same if you make the circle very big.

Maybe I don't have the right use cases in mind, but here's what I see:
1- UI: If you use your shader to draw a circle in the UI, then at least you'll always control how big or how small it is, so that's easier. But you still have to manually adjust the fade for each size of circle you have in your UI, and each resolution the game supports. Otherwise, the edge will either look too jagged or too blurry sometimes.
2- Gameplay: If you draw a circle in the 2D/3D world, the problems above are still relevant, but in addition to that, I suppose that the circle could change size dynamically due to gameplay events (distance to camera, growth/shrinking etc)

So there seems to be missing, from this video, a way to make the fade value be proportional to the total screen resolution for each frame.

Altrue
Автор

It depends, I have two different ways. My first method uses triangles, the number of sectors is determined by the camera distance, increasing the closer it gets. The second method uses the Bresenham circle algorithm. I can use this to draw pixels directly to a framebuffer or via a batch renderer where every pixel (for outlines) or every row of pixels (for solid) is a seperate quad. I didn't really have any concerns with the number of quads/triangles I was drawing as my batch renderer can ouput 1.7 million with a single draw call at over 70fps on my laptop and I don't tend to draw circles all that often for pixel games.

NoodleFlame
Автор

It'd be cool if Hazel had full curve support in-runtime. Think of all the animations and blending you could do with them!
There would definitely be some challenges, but if you can do it efficiently and simply, it would be awesome.

SLR
Автор

9:37, I woulda put the x/y center at the top left of the normalised space, done normal caluations then just multiply the results against width and height normalised with the bigger have a smaller normalisation value, so 1 should be 1.0 and the bigger made to be smaller as a result of division, I think bigger divided by smaller would get the right value, this method ensures the dimensions are always as expected, as for x/y being in top left corner it makes it easier to multiply against position to get in right spot, only having to check if the position should be multiplied against positive or negative version of the axis

zxuiji
Автор

Just as I needed to render a bunch of circles, excellent :D

LB
Автор

Thankyou for teaching me something this morning =)

ebkdeviousd