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

Patreon ► / thecherno
Instagram ► / thecherno
Twitter ► / thecherno
Discord ► / discord
Code ► www.shadertoy.com/view/ssdSD2

Пікірлер: 262

  • @TheCherno
    @TheCherno2 жыл бұрын

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

  • @antontheyeeter

    @antontheyeeter

    2 жыл бұрын

    Maybe spheres

  • @alexisloic21

    @alexisloic21

    2 жыл бұрын

    Torus

  • @ChlorieHCl

    @ChlorieHCl

    2 жыл бұрын

    SDF font rendering

  • @70elysium

    @70elysium

    2 жыл бұрын

    Hierarchical transforms in ECS would be great.

  • @TheBigWazowski

    @TheBigWazowski

    2 жыл бұрын

    Network code would be interesting to learn about

  • @fmdj
    @fmdj2 жыл бұрын

    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 ;)

  • @Rust_Rust_Rust

    @Rust_Rust_Rust

    2 жыл бұрын

    Yeah square both sides and you still get 1.

  • @rutvikpanchal5726

    @rutvikpanchal5726

    2 жыл бұрын

    Only if your radius is 1, does not work with radius != 1

  • @fmdj

    @fmdj

    2 жыл бұрын

    @@rutvikpanchal5726 well in that case you can square the radius instead of square-rooting the x^2 + y^2, this is beneficial cuz square (simple multiplication, one instruction) is way cheaper than square root computationally

  • @utkarshgupta4041

    @utkarshgupta4041

    2 жыл бұрын

    what if I tell you I have a circuit that can calculate square root in one CPU cycle.

  • @chicomferreira

    @chicomferreira

    2 жыл бұрын

    @@rutvikpanchal5726 you can just compare it with radius^2

  • @fari7s
    @fari7s2 жыл бұрын

    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.

  • @regbot4432

    @regbot4432

    2 жыл бұрын

    Thanks for recommendation

  • @fari7s

    @fari7s

    2 жыл бұрын

    @@regbot4432 Glad to help)

  • @gldev8191

    @gldev8191

    2 жыл бұрын

    nice, will add it to my library!

  • @Brahvim

    @Brahvim

    2 жыл бұрын

    Sadly the online version was incomplete...

  • @danifeldman8884

    @danifeldman8884

    28 күн бұрын

    Thank you very much, I have downloaded the book. Happy to find your comment. :)

  • @kalakxfif9473
    @kalakxfif94732 жыл бұрын

    That's a smooth and soft tutorial

  • @zzedixx
    @zzedixx2 жыл бұрын

    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)

  • @King0Mir

    @King0Mir

    2 жыл бұрын

    A useful vocab, but still one that requires you to define your terms at the beginning, so it doesn't save you much.

  • @DeGuerre

    @DeGuerre

    2 жыл бұрын

    ...and the difference of two discs is called an annulus.

  • @prashanthkumar0

    @prashanthkumar0

    2 жыл бұрын

    what about soft circle then?

  • @cogwheel42

    @cogwheel42

    2 жыл бұрын

    a non-filled-in circle you can actually _see_ would be an annulus

  • @AlFredo-sx2yy

    @AlFredo-sx2yy

    Жыл бұрын

    what happened to the simple days of circle vs circumference

  • @FerrumMusicVideos
    @FerrumMusicVideos2 жыл бұрын

    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.

  • @slowfastdog9693
    @slowfastdog96932 жыл бұрын

    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.

  • @aaron6807
    @aaron68072 жыл бұрын

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

  • @microcolonel
    @microcolonel2 жыл бұрын

    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.

  • @vladprusakov
    @vladprusakov2 жыл бұрын

    I need more shadertoys series! Thanks, Yan

  • @MrDimakoles
    @MrDimakoles2 жыл бұрын

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

  • @mickeym.9721
    @mickeym.97212 жыл бұрын

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

  • @LB767
    @LB7672 жыл бұрын

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

  • @ebkdeviousd3392
    @ebkdeviousd33922 жыл бұрын

    Thankyou for teaching me something this morning =)

  • @kebrus
    @kebrus2 жыл бұрын

    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 )

  • @dave_s_vids
    @dave_s_vids2 жыл бұрын

    Really interesting, despite me having zero use for what you just showed us :D Thanks!

  • @stefanarctic1966
    @stefanarctic19662 жыл бұрын

    Yes I would be interested in a video of an implementation

  • @S41L0R
    @S41L0R2 жыл бұрын

    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.

  • @Altrue
    @Altrue2 жыл бұрын

    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.

  • @perfectionbox
    @perfectionbox2 жыл бұрын

    the video is... well rounded

  • @NoodleFlame
    @NoodleFlame2 жыл бұрын

    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.

  • @DeGuerre
    @DeGuerre2 жыл бұрын

    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 }

  • @bobsmithy3103

    @bobsmithy3103

    2 жыл бұрын

    Thanks for the code example! I never knew that dFdx and dFdy even existed before now. In case anyone was like myself and was quite confused about dFdx and dFdy, here's how I understand it: dFdx allows you to compare a variable of the current pixel being rendered to that same variable of the neighboring pixel to the left. Essentially the function returns the DIFFERENCE of a variable between two pixels that are horizontally right next to each other. This is useful because it tells us how much our variable changes per pixel which when rephrased, tells us how much we need to change our variable to get a pixel worth of width. dFdy is the same as dFdx except it compares pixels vertically instead of horizontally, so when a pixel is being rendered it'll look to the pixel above it to get the difference in their variable. Note this variable can be anything from user supplied varyings like uv coordinates, or variables like gl_PointCoord. Though you could supply a constant value like `1` to dFdx or dFdy but it would just return `0` as all pixels would just have the same value (as 1-1=0). Because we now know how much we need to change our variable to get a pixel worth of distance both horizontally and vertically, we can use it produce 1 pixel's worth of anti-aliasing which Pseudonym73 has shown above.

  • @DeGuerre

    @DeGuerre

    2 жыл бұрын

    @@bobsmithy3103 This is exactly right, except for one quibble: you should think of dFdx and dFdy not as differences, but as derivatives. They are indeed implemented as differences (which means they are not magic, in that they don't give you an analytic derivative), but semantically they are derivatives. These may be the most useful operators that nobody (except those who came to OpenGL shaders from RenderMan) seems to know about, because they give you the information you need for shaders to antialias themselves.

  • @KebunH
    @KebunH2 жыл бұрын

    I think to get consistent smoothness with smoothstep the step size should depend on the resolution, as the goal is to for example stretch the step over 2 pixels (in which the smooth step size would be 2 divided by the total amount of pixels)

  • @zxuiji
    @zxuiji2 жыл бұрын

    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

  • @antontheyeeter
    @antontheyeeter2 жыл бұрын

    Finally what i need

  • @maksymiliank5135
    @maksymiliank5135 Жыл бұрын

    you could also create a geometry shader which is going to take point primitive as an input and turn those points into quads and then render the circles that way. If you use this you can then define the color and radius of the circle as a parameter in the vertex buffer

  • @rigbyb
    @rigbyb Жыл бұрын

    Amazing tutorial, thank you

  • @Test-iv4pm
    @Test-iv4pm2 жыл бұрын

    I would love to see a shader series.

  • @Bonfra04
    @Bonfra042 жыл бұрын

    love this kind of video! can you make one about a way to fill a shape described by a series of point?

  • @RadicDotkey
    @RadicDotkey2 жыл бұрын

    You should have used a linear interpolation for antialiasing instead of a smoothstep otherwise you get some weird two edged gamma "correction" I know as I compared both methods with Photoshop's antialiasing pixel by pixel. Additionally the fade variable needs to be calculated from texel size. When it's a constant you will get different smoothing for different circle sizes.

  • @CoDEmanX47

    @CoDEmanX47

    2 жыл бұрын

    Do you have a Shadertoy example of that?

  • @realedna

    @realedna

    2 жыл бұрын

    So you have to calculate, if a pixel is part of the circle and to what amount. That means, if a pixel is less than ~1 pixel away from the edge, then color it partially according to the amount of overlap. You could just use the floating point fraction from the distance (when it's

  • @md2perpe
    @md2perpe2 жыл бұрын

    In mathematics, at least, the "outline of a circle" *is* the circle. A circle plus the region inside it is called a disk or a (2-dimensional) ball.

  • @retroryuu7254
    @retroryuu72542 жыл бұрын

    Very well explained :D

  • @danielsliberatingstructure6539
    @danielsliberatingstructure65392 жыл бұрын

    I was wondering: regarding the thickness - wouldn’t you have to take into account the transformation applied (or the distance to the camera) within the shader function, so that a circle with a thin line (aka a donut of ‘tiny’ thickness) stays thin no matter the draw distance - or maybe even more relevant: the aliasing created by smoothstep() is working regardless of draw distance(? Proximity to the object ? Closeness to the camera?) . I guess I am throwing a lot different concepts together - my apologies for that - the last time I wrote code for an 3D engine is 15 years ago, I never worked with shaders, and I forgot about all the terminology and how different concepts play together.

  • @erich1394

    @erich1394

    2 жыл бұрын

    @The Cherno Brilliant tutorial - I'm an audio DSP programmer and it's quite wild to experience the same sort of geometric thought process but in higher dimensions. (Audio is 2D, time and amplitude). @Daniels Liberating Structures-Kanal - I have the same question as you, but for ellipses with a high fade value. I wanted to ask specifically what local variable can we use to figure out the transform applied to the shader? If we had access to the "aspect ratio" of the ellipsoid, we'd be able to easily compensate for this stretched-fade / stretched-thickness effect, but being a complete newbie to openGL, I know that this problem would probably require a good day of plinking around and I'd really like to hear a professional chime in on this!

  • @SirusStarTV

    @SirusStarTV

    2 жыл бұрын

    If you don't get transform matrix through Uniform and apply it to vertex shader then it would be just circle in 2D screen space.

  • @SimonBuchanNz

    @SimonBuchanNz

    2 жыл бұрын

    The correct approach to anti-alias an edge is to use the pixel width, which I believe you can get pretty easily in a shader with the derivative function on the UV (which just compares the passed value to what it is in neighboring pixels).

  • @DFPercush

    @DFPercush

    2 жыл бұрын

    Pretty sure that will just come out in the wash when you project UV coordinates into world space. The rasterizer will calculate how the distance and perspective (applied in the vertex shader) affects each pixel. The fragment shader is only working with a sample point, usually the center of the pixel, but it could be multiple points if multisample shading is enabled. If you need a flat, constant width circle, you can either omit the transformation matrix from the pipeline, or you could use a "look at" function to render the quad and point it straight at the camera.

  • @redox5373
    @redox53732 жыл бұрын

    i was just wondering how to render circles, and my saviour came

  • @HumanGamer
    @HumanGamer2 жыл бұрын

    I would be interested in a video where you implement it into the batch renderer. Please make it :P

  • @nicobugs

    @nicobugs

    2 жыл бұрын

    Yes please

  • @playerzero5388
    @playerzero5388 Жыл бұрын

    "Meet my cousin, Smooothstep. Some say he's a smooth kinda guy."

  • 2 жыл бұрын

    You could also use the derivative functions available in GLSL (such as fwidth) to make the smoothstep range one pixel in size, regardless of the scaling of the object or screen resolution. Would be pretty interesting to see that implemented!

  • @JoneKone
    @JoneKone2 жыл бұрын

    Smoooth =)

  • @yassin_eldeeb
    @yassin_eldeeb2 жыл бұрын

    Thank you for the amazing tutorial, I now appreciate the abstraction done in some higher level languages for rendering graphics 😅

  • @RenkoGSL
    @RenkoGSL2 жыл бұрын

    It was nice to see you avoid the branch call. And add fade to thickness. Good job Cherno! Keep up the good work!

  • @zoltankurti

    @zoltankurti

    2 жыл бұрын

    Does it avoid the branch call? Depends on how step is implemented.

  • @OutlawJackC
    @OutlawJackC2 жыл бұрын

    Just wanna point out, that pc looks gucci :)

  • @theoathman8188
    @theoathman81882 жыл бұрын

    you can apply these techniques in SDF type rendering as well.

  • @notarandom7
    @notarandom7 Жыл бұрын

    My Ray Caster: I'm 6 Parallel Universes ahead of you

  • @Mempler
    @Mempler2 жыл бұрын

    You missed an meme opportunity when you said "smooth soft circles"

  • @joshuaalan7580
    @joshuaalan75802 жыл бұрын

    When you pulled up the printed circle I was fully expecting you to go "...can't believe I wasted a sheet of paper on this"

  • @dragonalias
    @dragonalias2 жыл бұрын

    i enjoyed the video :)

  • @nitricswight
    @nitricswight2 жыл бұрын

    Ooh I want that t-shirt

  • @Zekronz
    @Zekronz2 жыл бұрын

    I recommend using fwidth over smoothstep for anti aliasing as it won't be resolution dependent.

  • @realedna

    @realedna

    2 жыл бұрын

    Partial derivatives of what function? A hard step?

  • @AltamishM
    @AltamishM2 жыл бұрын

    If we smoothstep this way, aren't we then losing the fade where the outer edge of the circle touches the four sides of the canvas? Could look a little chopped off if the fade is large. Might be worth subtracting the fade from the distance.

  • @ADEPS.
    @ADEPS.4 ай бұрын

    I haven't even created a window yet. 10/10.

  • @brunomarques5258
    @brunomarques52582 жыл бұрын

    Hi @thecherno, Do You have plans to port Hazel to directx 11 and/or 12?

  • @ScienceAlliance
    @ScienceAlliance2 жыл бұрын

    Interesting!

  • @snapi
    @snapi2 жыл бұрын

    love you

  • @vikinggeorge7007
    @vikinggeorge70072 жыл бұрын

    1m side square would produce a circle of 1m diameter. The 0.5m you're talking about is the radius. Just clarifying to make things easier to understand.

  • @robertmoats1890
    @robertmoats1890 Жыл бұрын

    Thanks for the great video! The first time I implemented an SDF circle, it was a piece of cake until I got to the point where I needed to define a falloff for smoothstep(). Technically, the thickness of a circle outline should be oriented so that the middle of the thickness falls exactly on the radius of the circle, right? So half thickness on both sides of the radius edge. But this means the quad needs to be expanded (in clip space) by thickness*0.5 + falloff in every direction. Since my quads were sized in world space, trying to figure out how much to push them outward for this using a clip-space distance was not very much fun. I think I spent around 3 days on it.

  • @ericmasson7462
    @ericmasson74622 жыл бұрын

    thanks mate! I am down for a GL specific vid. cheers

  • @Will-Eves
    @Will-Eves2 жыл бұрын

    Thank you

  • @DFPercush
    @DFPercush2 жыл бұрын

    Cherno, you know how Unity optimizes sprites by "cutting off" the edges of the quad and tracing the outline? What if you do that here? Render a hollow octagon, or some n-gon, with a triangle strip topology, wide enough for the circle to lie within it. That would cut down on the number of fragments you have to calculate. I think there's a formula for the inner and outer radius of a regular polygon... somewhere lol

  • @fredg8328
    @fredg83282 жыл бұрын

    To render a circle in a texture there are techniques like the Bresenham circle algorithm but it doesn't really apply to a shader as you treat the pixels independently. For antialiasing there a techniques like the Wu algorithm which is a simplified version of multi-sampling, but again i don't know if it would be really faster in a shader.

  • @Test-iv4pm
    @Test-iv4pm2 жыл бұрын

    There is a little twinkle in your eye each time you describe a circle as "soft"

  • @DejaimeNeto
    @DejaimeNeto2 жыл бұрын

    I always wanted to render me some beautifully soft circles.

  • @filiformis
    @filiformis11 ай бұрын

    Google recommended me this video after watching Casey Muratori's video on rendering a circle. As if anything could top that. I mean I'm still going to watch this video and give it my engagement, obviously, but still.

  • @videojeroki
    @videojeroki2 жыл бұрын

    Interesting topic. Since I would like to display points (millions of points from laser scanning) I'm wondering if I could display those points as small circles using shaders. To be fair, the points could also be represented as square, triangle etc with different size and colours.

  • @philippk736
    @philippk7362 жыл бұрын

    Just to clear up the nomenclature: A circle refers to the outer perimeter, the inside area of the circle is a disk.

  • @Destroyer19941995

    @Destroyer19941995

    2 жыл бұрын

    😬

  • @sebastianzander87

    @sebastianzander87

    2 жыл бұрын

    And the word Chemo was looking for earlier is a ring (i.e. a circle with a thickness, a flat donut so to speak) 😉

  • @GorBer84
    @GorBer842 жыл бұрын

    Great videos thank you! could you please make videos about navigation mesh generation for AI and voxelization ?

  • @ebkdeviousd3392
    @ebkdeviousd33922 жыл бұрын

    Is this what games remasterers are doing for old games etc this kind of similar shading to make things more smooth? So potentially if I wanted to and could see game code I could smoothstep every step they have to remaster circles wheels etc myself?

  • @bernard3690
    @bernard36902 жыл бұрын

    Greetings Kind Regards How the heck does your computer compute those shaded circles immediately upon change of your program or are you editing the video to make it appear so Thank You Kindly

  • @fluffy537
    @fluffy537 Жыл бұрын

    Thanks Cherno, interesting video, but what if I want to draw a circle in 3D space, viewed from any angle? Your method seems to only work if you are drawing a circle in 2D space, viewed from above and with the circle in the centre of the screen.

  • @liamandersson5462
    @liamandersson54622 жыл бұрын

    How do you make it scaleable in GLSL? I have Matrices up and running, however it only scales the background of the "circle shader". Not the actual circle.

  • @zxuiji
    @zxuiji2 жыл бұрын

    Looking at that code make me think of lights, perhaps there's a cheat method of lighting objects by simply going over the entire rendered buffer with similar math

  • @quickstergamestutorialsgam3899
    @quickstergamestutorialsgam38992 жыл бұрын

    I bet if you covered c++ 3D games, like not writing a whole 3D game engine, but just coding a game like you would do with your old java series. That would be great.

  • @human-ft3wk

    @human-ft3wk

    2 жыл бұрын

    I think he mentioned a game is coming up! But for the most part, it seems like he's interested in engines more than games.

  • @qvindicator

    @qvindicator

    2 жыл бұрын

    That would be amazingly helpful to watch. I hope he considers it

  • @NaokiWatanabe
    @NaokiWatanabe2 жыл бұрын

    "Since we have an absolute unit range.." Me: "Yeah, that range is an absolute unit.

  • @flat9safety
    @flat9safety2 жыл бұрын

    @32:50 nice edit!

  • @CoDEmanX47
    @CoDEmanX472 жыл бұрын

    If the triangle count is important, then just use a single, large enough triangle per circle instead of a quad. I can't recall how to calculate the exact size, however.

  • @Erlisch1337

    @Erlisch1337

    2 жыл бұрын

    just put the circle on a texture for that quad...hehe....

  • @tenpham1127
    @tenpham11272 жыл бұрын

    In my exp, 5 degrees for each triangle is good enough. If you're lazy, leave it to the system by using MaskOpacity on a Rectangle - very flex.

  • @S41L0R
    @S41L0R2 жыл бұрын

    Hey I have a question: What stops one from putting *everything* into one draw call? Like having a mega shader and then either: *A*. Pushing geometry on the CPU to a giant vertex buffer you push to the GPU each frame, or *B*. Using vertex and geometry shaders as well as some persistent buffer on the GPU and just having simple uniforms/imports you can modify for stuff to add/subtract/change

  • @Drillgon

    @Drillgon

    2 жыл бұрын

    You absolutely can do extreme draw call batching (though typically not in the way you've described with pushing stuff to giant vertex buffer each frame) and a lot of games do it (not quite to the degree of everything in the same draw in any game I've seen, but it would be possible). Pushing your mesh data to the GPU each frame would be really slow because that can end up with an absolute ton of data you're trying to send over every frame. You should look into indirect draws though, they can handle this quite elegantly. Doom Eternal, for example, stores all its geometry data in a single large buffer, with even skinning being done in a compute shader and stored into the same buffer before rendering anything. This allows it to merge completely unrelated meshes into the same draw, and I believe it did something like 256 meshes per draw (I don't see why you couldn't do more if you wanted to, but there likely wouldn't be much of a performance increase at that point and it may need more data). Typically the buffer used for indirect draws would also be created on the GPU and not the CPU because it's much faster (at the very least after some coarse culling by the CPU). Doom Eternal also generates a big index buffer every frame on the GPU (so instances are unwound into real indices), which allows it to do per triangle culling. Having one big shader is a common thing used in many games, typically called an uber shader. There are examples on the internet where whole game worlds are rendered in one draw with indirect buffers, so really go research that.

  • @S41L0R

    @S41L0R

    2 жыл бұрын

    @@Drillgon Wow, what a great response.. I do have one leftover question though: can you have like a persistent buffer on the GPU that survives multiple draw calls? That way you could just modify it instead of pushing every frame.

  • @Drillgon

    @Drillgon

    2 жыл бұрын

    @@S41L0R Of course. In fact, you basically never want to be creating a new buffer every frame. Uploading data to the GPU that doesn't need to be updated should be avoided in most cases (some exceptions might be streaming assets into and out of memory, but that's not quite the same thing as uploading all the geometry every frame). Like I talked about before, you'll typically store meshes inside buffers on the gpu and not touch them unless the vertices need to be updated (which is the case if you're doing GPU skinning in a compute shader, but even then nothing is being uploaded because the GPU is just writing into it's own buffer). If you want to draw the mesh more than once, you instance it. You can make allocations into that buffer for completely dynamic meshes as well using any of the many allocation algorithms.

  • @SimonBuchanNz

    @SimonBuchanNz

    2 жыл бұрын

    This is roughly what you are doing with ray tracing, as well! The entire geometry and material information is pushed into the GPU memory, then the shader can throw whatever rays it likes and put whatever output it likes out, all in one CPU side call. (You don't actually do this in one pass, in general, as you want to do clever things like aggregate lighting information over multiple frames and combine them, but that's the idea) RTX means you have explicit support, but since 2006 or so you could do basically ray tracing in pixel shaders: that's what parallax occlusion mapping and screen space reflections are, just in simplified cases that you can do quickly enough to be useful without acceleration.

  • @S41L0R

    @S41L0R

    2 жыл бұрын

    @@Drillgon Awesome, thanks for all the info!

  • @joysaha3927
    @joysaha39272 жыл бұрын

    I would love to see how to integrate this on batch renderer series. :)

  • @LimitedWard
    @LimitedWard2 жыл бұрын

    I ran into this EXACT issue the other day. For my 3D app, I wanted to add a circle around my mouse cursor similar to the paintbrush tool in photoshop, but I couldn't for the life of me figure out how to do it.

  • @ahsanullah6810
    @ahsanullah68102 жыл бұрын

    Damn i am here fast

  • @jamesmnguyen
    @jamesmnguyen2 жыл бұрын

    Wow, young me was so naive. In the past, I always rendered 2d circles using a triangle fan. When I could've used a shader.

  • @m4rt_
    @m4rt_ Жыл бұрын

    so many triangles!

  • @siman211
    @siman2112 жыл бұрын

    So i watch all the videos i try to code at the same time with you do a different version of that code and when i think that i learn something i just don't I try to do some problems on code wars and even the easy ones are to hard for me any advace? Sorry for my english

  • @AndrewHelgeCox
    @AndrewHelgeCox2 жыл бұрын

    02:00 you call it a circle. It's the filled-in shape that you need a different word for.

  • @ymi_yugy3133
    @ymi_yugy31332 жыл бұрын

    There was a paper about parallelizing Bresenham's circle rasterization algorithm. It's unclear though it's suitable for the gpu.

  • @DFPercush

    @DFPercush

    2 жыл бұрын

    The rasterizer in a GPU is kind of baked into the hardware, you can't really have a parametric function that chooses which pixels to sample. You could generate a point list of every pixel, perhaps with a compute shader. Not sure it would be any faster than this though. Listing every point is a lot of memory. You might get this one faster if you render over an actual mesh that doesn't process so many pixels.

  • @_lod

    @_lod

    2 жыл бұрын

    The gpu already does things in parallel.

  • @ymi_yugy3133

    @ymi_yugy3133

    2 жыл бұрын

    @@DFPercush The GPU rasterizer can only rasterize points, lines, triangles and maybe rectangles. So this algorithm would need to be implemented as a compute shader. I don't understand your concern about memory. Whether you use the final image as a render attachment or storage texture shouldn't make much difference in terms of memory size.

  • @ymi_yugy3133

    @ymi_yugy3133

    2 жыл бұрын

    @@_lod Yes, but the process shown in the video has a fair amount of overhead, because it has to run through the entire render pipeline, because the pixel shader is run for every sample.

  • @DFPercush

    @DFPercush

    2 жыл бұрын

    @@ymi_yugy3133 Memory access time is what I'm thinking about, more so than size. Not sure what kind of cache a GPU has or what it has to share it with. Actually a tessellation or geometry shader might be better because it can just stuff vertices into the rasterizer pipeline and not have to allocate a buffer at all.

  • @cadfoot568
    @cadfoot5682 жыл бұрын

    rip printer ink at the beginning

  • @gusterugamer
    @gusterugamer2 жыл бұрын

    2:00 i think the non filled is a circle, and the fill one is a disk

  • @X_Daniel466
    @X_Daniel4662 жыл бұрын

    Yes I did print that lol, Made me laugh.

  • @tristunalekzander5608
    @tristunalekzander56082 жыл бұрын

    I would just use circle texture on a quad with transparent blending.

  • @williankoessler5935
    @williankoessler59352 жыл бұрын

    distance = (float)(distance innerCircle); Without inverting distance (or just invert the logic)

  • @phlfm
    @phlfm2 жыл бұрын

    "A non filled circle" ahh yes.. a ring?

  • @jlewwis1995
    @jlewwis19952 жыл бұрын

    I haven't watched the video yet but my guess is for rendering a circle you want to just take a quad and render it as a circle with a shader taking the center of the quad as the center of the circle and comparing the distance of the UV from the center and if it's greater than the radius you render nothing and if it's less you render the circle

  • @jlewwis1995

    @jlewwis1995

    2 жыл бұрын

    Lol I was right after less than a minute 🤣

  • @ChrisM541

    @ChrisM541

    2 жыл бұрын

    @@jlewwis1995 I'm not sure you realise how both your posts read! "I haven't watched the video yet but" --> good grief !!

  • @rodion988
    @rodion9882 жыл бұрын

    I would call a "non-filled in circle": 1. circle perimeter 2. circle boundary 3. circle outline

  • @perfectionbox
    @perfectionbox2 жыл бұрын

    Just draw a letter O from an SDF font (or a circle emoji)

  • @igorthelight

    @igorthelight

    2 жыл бұрын

    Good as a joke :-) But for those who would try it "for real" - make sure that your engine/framework supports font rendering in the first place. Not sure that speed will be great tho (rendering a letter vs rendering the circle)

  • @King0Mir
    @King0Mir2 жыл бұрын

    One thing that immediately came to mind when you started showing the fade effect, is what about anti-aliasing? It seem like the purpose of your fade is actually to avoid anti-aliasing while still making it look somewhat good. Why not apply proper anti-aliasing instead?

  • @igorthelight

    @igorthelight

    2 жыл бұрын

    What form of an AA tho? You would have to compare the speed of different methods.

  • @karelhofman9848
    @karelhofman98482 жыл бұрын

    create video, another easy technic is to just draw a quad with a texture of a white circle on it. to color the circle just shade the texture and scale the quad to create an ellipse. the smooth shading isn't needed anymore if linear filtering is enabled. it is not possible to create donuts with this technic though.

  • @jouniosmala9921
    @jouniosmala99212 жыл бұрын

    After looking at this code I start to understand why rendering 8M pixels 100 times per seconds often needs more than 10Tflops compute.

  • @oblivion_2852
    @oblivion_28522 жыл бұрын

    Why wouldn't you want to write the shader to work for ellipses too?

  • @peezieforestem5078
    @peezieforestem50782 жыл бұрын

    One way to do this would be to transform the UVs to polar coordinates, it is useful if you're doing other stuff within those coordinates. Also, I personally do branchless "if"/"step" with metaprogramming, but that might be a bit too advanced. And of course the other comments mentioned that you do not need a square root if you're comparing to 1, but once again, this is an optimization technique and so I understand why you wouldn't mention it.

  • @Drillgon

    @Drillgon

    2 жыл бұрын

    Do you think the shader compiler might optimize the sqrt? It might be interesting to see the gpu assembly output.

  • @peezieforestem5078

    @peezieforestem5078

    2 жыл бұрын

    @@Drillgon it might, but we really need to see assembly output. Personally, I think, why take the chance if you can just guarantee this?

  • @razorstone3088
    @razorstone30882 жыл бұрын

    A circle that's not filled in. A Ring

  • @AkamiChannel

    @AkamiChannel

    2 жыл бұрын

    Technically I think it's just a circle. And the filled in one is a disc. But for colloquial terms, I think your way is better.

  • @GaxelOT
    @GaxelOT2 жыл бұрын

    Welcome to osu!