[HN Gopher] So you think you know box shadows?
       ___________________________________________________________________
        
       So you think you know box shadows?
        
       Author : yohannesk
       Score  : 731 points
       Date   : 2024-07-21 12:38 UTC (1 days ago)
        
 (HTM) web link (dgerrells.com)
 (TXT) w3m dump (dgerrells.com)
        
       | paulirish wrote:
       | Seriously fun exploration.
       | 
       | > Layering. That is an important word.
       | 
       | Layering is also the key to the (silly but also sometimes good-
       | looking) effects from my text shadow project from 14yrs ago:
       | https://paulirish.github.io/mothereffingtextshadow/
        
         | rustystump wrote:
         | <3
        
           | sufehmi wrote:
           | Was confused because everything moved in 2 seconds per frame
           | on M2 Firefox.
           | 
           | Switched to Chrome - suddenly everything is butter smooth.
           | 
           | Congrats on an article very well done!
        
         | breck wrote:
         | > Layering. That is an important word.
         | 
         | It's almost like this post has many layers to it, and that it's
         | not really about box shadows.
        
       | cchance wrote:
       | He said it might melt your processor... but on a macbook m3 in
       | arc runs great, like every one of those was amazing.
        
         | chuckadams wrote:
         | It's butter on my M1 Air too, in Chrome and Firefox.
         | Surprisingly, it's a slideshow on Safari.
        
         | dahart wrote:
         | On Safari iPad, I lose the ability to scroll or do anything
         | somewhere in the middle of the article.
        
           | labster wrote:
           | Huh, I read the whole article and interacted with all the
           | inline examples on my iPhone SE/2.
        
         | tux3 wrote:
         | Even on a 7 year old first gen AMD, it's smooth as butter.
         | Looks like Stylo and Webrender doing a great job?
        
         | magnio wrote:
         | Maybe the author tests it on some old device with outdated
         | graphics driver, because they all run smoothly on my 5 yo
         | Android.
        
           | tetris11 wrote:
           | Chiming in with my Samsung J3 2016, it ran pretty well here
           | too
        
         | layer8 wrote:
         | M4 iPad Pro here started to freeze up on the Starry Night
         | animation.
        
           | qingcharles wrote:
           | Weird. I'm on a 2011 Lenovo desktop with an i5 and it ran
           | smooth as butter.
        
             | layer8 wrote:
             | Probably Safari is at fault.
        
               | kalleboo wrote:
               | Yeah it was a slideshow in Safari on Mac, butter smooth
               | in Chrome
        
         | jimmaswell wrote:
         | All the examples were good on my Samsung S22 Ultra too, really
         | cool.
        
         | sweca wrote:
         | Worked very well on my Pixel 7 in Chrome too
        
         | callwhendone wrote:
         | M1 Pro here and it ran completely fine.
        
           | llama_drama wrote:
           | That's weird because it completely freezes m2 ipad
        
         | mavamaarten wrote:
         | I ran it on my Pixel 7A and even the ray tracing demos ran
         | insanely quickly. I seriously did not expect that.
        
         | sorrythanks wrote:
         | Firefox on an m2 has taken the news of these bouncing balls
         | extremely poorly
        
       | adrianpluis wrote:
       | Well done with writing your experience.
        
       | merceranthony78 wrote:
       | Amazing. Is it possible to tell how much lag these would cause if
       | used on a production website?
        
         | notpushkin wrote:
         | A lot. Please don't do this in production.
        
       | ctippett wrote:
       | I'm embarrassed to admit it took until the final paragraph before
       | realising that 'gypity' is a reference to Chat GPT.
        
         | noqc wrote:
         | I took until here.
        
           | fitsumbelay wrote:
           | same
        
             | p0seidon wrote:
             | same
        
         | zarathustreal wrote:
         | Hmm.. I must be even further out of the loop than you, why
         | would that be embarrassing?
        
           | hnbad wrote:
           | It isn't. They were being self-deprecating.
        
         | jbritton wrote:
         | Primeagen YouTube channel lingo.
        
         | krsdcbl wrote:
         | fun fact, this had me realise the term isn't some kind of in
         | joke spawned of a colleague's mind, but actually a meme in the
         | progess of becoming one
        
         | gs17 wrote:
         | Same, I thought it was some sort of tool related to gyp but for
         | client side.
        
         | tracker1 wrote:
         | Chad Gipity is a good guy... ;-)
        
           | tracker1 wrote:
           | His significant other (Elle Elim) is pretty nice too.
        
       | sunnyps wrote:
       | > However, using a transparent color significantly slowed down
       | the number that can be drawn too which doesn't make as much sense
       | to me. I'd imagine that with hardware today transparency should
       | be somewhat free.
       | 
       | That's because transparency limits how you can batch draws on the
       | GPU. With opaque draws, you can use the depth buffer and draw in
       | any order you like e.g. maximizing batching. With transparency,
       | you need to draw things in the right order for blending to work
       | (painters order).
        
         | amelius wrote:
         | Can't you mathematically work out how to change the
         | colors/opacity to rearrange the job?
        
           | Rapzid wrote:
           | Having that knowledge sounds just as expensive if the
           | operations aren't commutative.
        
             | amelius wrote:
             | Yeah, somehow between comments I forgot this was about
             | shadows and I was thinking more about drawing polygons. In
             | that case, you can break up the polygons and work out the
             | colors for each of the (theoretically 2^N) regions of
             | overlap.
        
           | klysm wrote:
           | I think there's still a dependency graph
        
         | Cloudef wrote:
         | GPUs also do not like overdraw, so it's generally good idea to
         | avoid having many transparent elements on top of each other,
         | its also the reason why drawing more triangles vs. transparent
         | texture is generally better.
        
           | DaoVeles wrote:
           | My big take away with the whole City Skylines 2 performance
           | issue and the lack of LOD was that geometry processing is so
           | cheap nowadays. So long as you aren't too reckless with
           | geometry in terms of sub-pixel rendering, you don't really
           | have to worry about it too much any more.
           | 
           | It isn't like the Ps2 era when geometry time was a real
           | concern on render times. Even a modern low end GPU could
           | process a few hundred million polygons a second without
           | sweating it, now getting the result son screen is a very
           | different issue.
        
             | Cloudef wrote:
             | PS2 is kind of exception as it was a fill rate monster, and
             | still even to this day is pretty impressive piece of
             | engineering. (Mesh shaders say hi)
        
               | spookie wrote:
               | Yeah, PS2's Graphics Synthesizer had a fill rate of 1.2
               | GB/s. For comparison, the OG Xbox had 0.932 GB/s, and the
               | GameCube had 0.648GB/s. Assuming only 1 texture here.
               | 
               | The Xbox was released 1 year later, for context.
               | 
               | Sony also demo'd the GSCube once, it had 16 Graphics
               | Synthesizers, achieving a fill rate of 37.7 GB/s (no
               | textures, half that with 1... I think). Eventually they
               | ditched the idea in favour of Nvidia's solution.
        
         | delusional wrote:
         | The "Ordering" step doesn't really matter that much. You're
         | usually doing a sort anyway prior to submitting the drawcall.
         | What hurts is the overdraw. If you're doing opaque rendering,
         | you get to render front to back, rendering only what actually
         | appears on the final framebuffer. The number of pixels (after
         | the depth pass) is proportional to the framebuffer. When you're
         | doing transparent rendering you render back to front, and you
         | have to render a tonne of the scene that will eventually be
         | (partially) obscured by other random polys. We call that
         | overdraw. The amount of pixels through the shader pipeline
         | balloons to be proportional to the size of your mesh.
         | 
         | If you're doing non-overlapping stuff, you'd actually expect
         | (almost) no slowdown from transparency, since you'd have to
         | touch every pixel once anyway, and the only thing that changed
         | is the shader formula.
        
         | o11c wrote:
         | Reverse-painter's-order beats painter's-order since it lets you
         | skip fully-occluded objects:                 Start with a
         | buffer that's fully transparent (a=0.0)       for each face
         | from front to back:         for each pixel of the face:
         | draw the pixel, blending 1.0-buffer.a of the new pixel into
         | whatever's already in the buffer           (if buffer.a == 1.0
         | you can just skip it entirely, just like for depth buffering)
         | go back and double check your math relating to transparent
         | objects behind other transparent objects
         | 
         | The tricky part is if you have faces that overlap in a cycle
         | (can happen legitimately), or that penetrate each other (often
         | avoidable if you think about it).
        
           | mabster wrote:
           | The game engines I've dealt with separate opaque and
           | transparent geometry.
           | 
           | It is generally good to render opaque geometry back to front
           | to reduce overdraw, but not going so far as sorting the
           | objects. We would do stuff like render the hands first in an
           | FPS or render the skybox last in most games.
           | 
           | Now for the transparent layer: First occlusion is handled by
           | the z-buffer as usual. If you render from front to back I
           | assume you render to another buffer first and then composite
           | to the framebuffer? If you render from back to front you
           | don't need alpha in your framebuffer and can assume each
           | rendered pixel is opaque, not needing that composite.
           | 
           | There's also order independent transparency stuff though
           | which IIRC does need another buffer, which requires a
           | composite but then saves you having to sort the objects.
        
             | DaoVeles wrote:
             | I could be wrong, but I remember folks that worked on
             | Dreamcast games that loved how you could just throw the
             | geometry at it in any old fashion you liked and the GPU
             | would just sort it all out as needed. Transparencies and
             | all.
        
               | mabster wrote:
               | I missed that generation of consoles, so no hands on
               | experience, but yeah it looks like they did the sorting
               | for you on the GPU end. Nice!
        
         | dmazzoni wrote:
         | I think it's more complex than that. While web browsers do use
         | GPU rendering, they're not game engines. They don't draw every
         | single object on the screen every frame, that could easily
         | cause lag on a large complex page.
         | 
         | Chromium in particular tries to minimize the total number of
         | layers. It renders each layer into a pixel map, then for each
         | frame it composites all of the visible layers into the final
         | image.
         | 
         | That works really well in practice because you often have lots
         | of layers that move around but don't actually change their
         | pixels. So those don't need to be rendered (rasterized) every
         | frame, just composited.
         | 
         | If you have a bunch of box shadows without transparency,
         | Chromium will rasterize the whole thing once as a single layer.
         | 
         | If you have a bunch of box shadows with transparency, Chromium
         | might create a separate layer for each one. That's probably
         | suboptimal in this particular case, but imagine if your
         | partially transparent box shadows had to also slide around the
         | page independently.
        
           | forrestthewoods wrote:
           | > They don't draw every single object on the screen every
           | frame, that could easily cause lag on a large complex page.
           | 
           | Games draw every single object on the screen every frame.
           | They don't lag, quite the opposite in fact!
        
             | eru wrote:
             | In fact that exact line of thinking was behind an effort to
             | rewrite Firefox's rendering to be more like a game engine,
             | a few years ago.
             | 
             | Not sure where that went in the end.
        
               | DaoVeles wrote:
               | That sounds like something from the shuttered Servo team.
               | At least they rose like a phoenix - https://servo.org/
        
               | eru wrote:
               | Yes, that sounds about right! I remember a series of very
               | interesting blog posts by them.
        
               | TazeTSchnitzel wrote:
               | It's called WebRender and it shipped in Firefox.
        
             | DaoVeles wrote:
             | I think the above was a simplification. GUI rendering is a
             | good example of jack of all trades, master of none. It
             | doesn't use tight render loops like game engines but it
             | much more flexible in terms of UI possibilities.
             | 
             | There is also the issue that GPU's are oddly terrible at
             | generating 2D elements of which a desktop has thousands of
             | them. There are things like Glyph caching but they can only
             | go so far.
             | 
             | Having the CPU doing the majority of the work with a few
             | rasterization tasks to the GPU makes sense.
        
             | kalleboo wrote:
             | Games are expected to have sole access to your machine, so
             | if they use all the CPU/GPU resources, nobody cares. If my
             | web browser was burning up my battery re-rendering the page
             | 90 times a second, I'd be livid.
        
               | forrestthewoods wrote:
               | I think "consumes too much resources" is a valid concern.
               | But I think "could cause lag because too many objects" is
               | totally bogus. Rendering a web page isn't _that_
               | complicated.
        
               | eru wrote:
               | > Games are expected to have sole access to your machine,
               | so if they use all the CPU/GPU resources, nobody cares.
               | If my web browser was burning up my battery re-rendering
               | the page 90 times a second, I'd be livid.
               | 
               | Games 20 years ago had sole access to machines that were
               | much less powerful than even partial access to today's
               | machines.
               | 
               | And eg Nintendo Switch games (or games on the Steam deck,
               | or just mobile phone games) still deal with power
               | limitations; people are very aware when their games burn
               | through their batteries.
        
         | p_l wrote:
         | One more thing to consider is memory bandwidth, which can be
         | limiting factor especially on mobile devices.
         | 
         | A non-transparent draw over another draw allows in best case to
         | cull all overlapping drawing operations, in worst case means
         | you only have to use as much bandwidth as the individual draws.
         | 
         | With transparency, especially if you can't somehow combine the
         | operations together (from my understanding, very hard problem),
         | it means you also need to read back the entire region you're
         | overlapping with transparency - so every transparent draw
         | involves at least twice the final framebuffer size bitmap
         | going-over memory bus.
         | 
         | Now consider that many mobile devices had not enough memory
         | bandwidth to do a full redraw (i.e. blit the full framebuffer
         | image twice) of the screen in time to maintain 60fps and it
         | becomes a considerable problem.
        
       | yesimahuman wrote:
       | > It also turns out that some smart people figured out maths
       | hacks to draw rounded boxes for super cheap which UI peeps love
       | because with this hack boxes can be so round as to appear as
       | circles
       | 
       | Any references to learn more about these hacks?
        
         | pmhpereira wrote:
         | Probably signed distance fields (SDF).
        
         | leecommamichael wrote:
         | Some historic articles on software rendering (the original Bill
         | Atkinson stuff)
         | https://www.folklore.org/Round_Rects_Are_Everywhere.html
         | http://wg20.criticalcodestudies.com/index.php?p=/discussion/...
         | 
         | A modern 3D accelerated article (using SDF as another commenter
         | suspected) https://mortoray.com/quickly-drawing-a-rounded-
         | rectangle-wit...
        
           | rustystump wrote:
           | I was thinking SDFs and the Bill stuff at time of writing.
           | Read my mind.
           | 
           | Have to add work by Evan Wallace here too as he is a legend.
           | 
           | https://madebyevan.com/shaders/fast-rounded-rectangle-
           | shadow... https://madebyevan.com/webgl-path-tracing/
        
       | recursive wrote:
       | I'm totally down for some good old fashioned impractical hacking.
       | But just remember, we already have canvas, which can do all this
       | easier, faster, and better.
        
         | egypturnash wrote:
         | But with less comedic value. Doing this with nothing but box-
         | shadow is _funny_ , mostly _because_ it is so impractical.
        
         | klysm wrote:
         | Canvas throws away a lot though, especially w accessibility
        
           | recursive wrote:
           | Really? I would have guessed that canvas provides pretty much
           | exactly the same accessibility as a UI rendered entirely out
           | of box shadows.
        
           | tkzed49 wrote:
           | now I'm imagining a screen reader reading off the coordinates
           | of 1000 box shadows
        
             | recursive wrote:
             | You could probably get it to png encode a canvas and then
             | read it in hex too.
        
         | dmazzoni wrote:
         | Canvas is better...if you're trying to do something that stays
         | within a fixed-size box.
        
           | kroltan wrote:
           | Canvas would still be faster even if you used a full-screen
           | box. Just the string concatenation overhead of doing this
           | with box-shadows is insanely wasteful.
           | 
           | Which isn't to demerit the hackish creativity of taking one
           | thing and running with it! But if you wanted to do a ball
           | painting effect like that outside this "what if" context, it
           | would be technically irresponsible to do it with box-shadows.
        
         | hnbad wrote:
         | Sure, and we already have keyboards, so there's no need to use
         | floppy drives or rubber chickens to make music either.
        
       | butz wrote:
       | But at the end of the day Firefox and Chrome are still rendering
       | 1px box-shadow differently at 150% browser zoom. Best hopes for
       | Baseline 2025.
        
       | ulf-77723 wrote:
       | Really great work, especially the music synced animation - could
       | as well also be projected in an electro club
        
       | winrid wrote:
       | This discussion around adding shadows to window boarders in imgui
       | is also interesting: https://github.com/ocornut/imgui/issues/1329
        
       | nimish wrote:
       | Full color RGB flip dot display!
        
       | develatio wrote:
       | dgerrells, please add RSS support to your blog!
        
         | rustystump wrote:
         | Done. Let me know if it works.
        
           | develatio wrote:
           | Sorry for the late reply. I just tried and it works
           | perfectly! Thank you so much!
        
       | kristopolous wrote:
       | For the past 30 years I got good at programming but never really
       | did graphics because I didn't like games. I now view it as a
       | massive oversight and have been trying to catch up for over a
       | year.
       | 
       | So hard.
        
         | hackit2 wrote:
         | I did games first, then switched over to crud or simple oracle
         | form programming. I tripled my original game programmer wage
         | overnight.
        
           | eru wrote:
           | Well, games are seen as fun, so they can attract programmers
           | even with low salaries.
           | 
           | Basically the same reason pet veterinaries and teachers and
           | nurses and musicians and artists still attract plenty of
           | candidates despite a comparatively low pay.
           | 
           | (Playing games is more fun than working with CRUD apps. But
           | writing games and writing CRUD apps seem about equal in their
           | probability distributions of fun.)
        
           | kristopolous wrote:
           | Most of this is about the not-so-much-anymore-exotic art of
           | GPU programming. It's becoming important in so many fields.
           | The last thing I want to be is some foot-dragging old windbag
           | who forgot to stay up to date.
        
       | fitsumbelay wrote:
       | My kind of hackin' Almost like an antichrist to the Josh Comeau
       | posts I've read on the topic
       | https://www.google.com/search?q=josh+comeau+shadows
        
       | pfannkuchen wrote:
       | Solid watch for rolling rocks energy.
        
       | efilife wrote:
       | A great, possibly the greatest article I read this year ended
       | with "your welcome" instead of "you're". Fix asap! Or maybe I
       | didn't get the joke, that's a possibility
        
         | rustystump wrote:
         | nothing to see here...
        
           | efilife wrote:
           | I'm honored
        
       | coding123 wrote:
       | As usual, when will we get Quake or Doom ray-trace rendered using
       | box shadow?
        
       | akira2501 wrote:
       | Instead of animating the color balls to music, it'd be nice if my
       | manipulations of the color balls _created_ music.
        
       | tompetry wrote:
       | This was awesome
        
       | theturtle32 wrote:
       | THIS IS ABSOLUTELY EPIC, AND MY FAVORITE KIND OF WEB TECH DEEP
       | DIVE! <3 <3 <3
        
       | anymouse123456 wrote:
       | I love this kind of content. It reminds me of the early aughts
       | when folks were doing a lot more of this stuff for fun.
        
       | SuaveSteve wrote:
       | >So you think you know ((CSS FEATURE))?
       | 
       | Why would I know it? It's CSS!
        
       | tracker1 wrote:
       | Looking at the music visualizations was definitely cool. Really
       | miss the old winamp days when you could play music and just run
       | the visualizer full screen. I wish that streaming audio players
       | did this today.
        
         | valbu wrote:
         | Still use Winamp (actually WACUP) with Milkdrop visualizations
         | almost every day. But true that streaming audio players are so
         | basic featureless pieces of software.
        
           | moritzwarhier wrote:
           | Yes it's enraging and really telling.
           | 
           | AVS and Milkdrop could probably run on a toaster today, I'd
           | guess even WebGL would be enough on a smartphone, laptop or
           | similar device with some kind of GPU.
           | 
           | Meanwhile, YTM costs 13EUR a month, doesn't have an
           | equalizer, no cross-device sync despite cloud everything...
           | no nothing. Not even gapless album playback.
           | 
           | Once upon a time, I signed up to Spotify in order to have a
           | good conscience, because I grew old and didn't want to keep
           | collecting audio files...
           | 
           | Then Spotify became worse and worse.
           | 
           | For now YTM seems like a better deal, but I still can't even
           | find a free solution to migrate my playlists.
           | 
           | Basically, everything went to shit. The only advantage is not
           | having to illegaly download new music after browsing Discogs.
           | 
           | The disadvantage is, apart from the odd good recommendation,
           | my interest in discovering new music has vanished.
           | 
           | Even new music found on Discogs.
           | 
           | But why bother saving songs to playlists when it's all
           | transient anyway?
           | 
           | That was my main last straw with Spotify -- too many good
           | music disappearing from playlists, and steadily worsening
           | recommendations. With rabbit-holes of totally trash AI-
           | generated "music" in between, that didn't stop unless
           | actively skipping.
           | 
           | And YTMs not gonna end any better, I feel.
           | 
           | Just a reminder that all music is transient. And maybe to
           | seek regaining enthusiasm by playing music myself, or going
           | out.
           | 
           | Streaming really has killed "listening to music" and being
           | excited about it for me, and I don't feel it's purely because
           | of old age.
           | 
           | Going to revive my Mp3 collection soon from a backup and
           | download my ~25 records worth listening since 2012 then from
           | Bandcamp instead.
        
             | tracker1 wrote:
             | I feel very similarly... I have YTM mostly because I don't
             | like ads on Youtube and found out creators get more from YT
             | subscribers than from the ads.
             | 
             | I have the UX of the player though... the android TV
             | experience is even worse, it's nearly impossible to use
             | effectively now.
             | 
             | I miss DJs, at least I miss _good_ DJs... there are a few
             | stations locally that I like what the DJs will mix and
             | play, but there 's sooo many commercials now. I'd happily
             | pay $10/month for an ad-free DJ run experience. I mean, why
             | the likes of XM, etc don't just have 50-100 DJs actually
             | curate the music for the live experience.
        
               | moritzwarhier wrote:
               | Thinking about that, I was happy about Rinse.fm still
               | existing and a couple of other stations still playing
               | live sets - not that I like everything, but when a DJ
               | hits the spot, it's really satisfying.
               | 
               | Live sets generally are an antidote to this kind of music
               | fatigue for me.
               | 
               | Of course there are other remedies, e.g. timeless albums
               | and live music, I also a deep love for Bach's keyboard
               | music, and some of that proved to me how much context
               | matters for enjoyment.
               | 
               | And ditto about Youtube, it's not a bad offer in itself
               | but the music app really sucks, many parts of Google TV
               | are mediocre, too. In the latter case, I appreciate their
               | effort in that case though (gtv in general), and the p/v
               | I get from that 40EUR hdmi+usb stick is not too bad
               | either since i use a cheap chromecast.
               | 
               | That's a thing I still like Google for, at least in my
               | case Chromecast makes it possible to reuse a cheap ~10y
               | old LED tv for purely internet tv, with a functional
               | remote, etc.
               | 
               | It's not new, but Google's TV sticks are pretty decent
               | imo
        
       | mediumsmart wrote:
       | I know not to use them without much thinking involved.
        
       ___________________________________________________________________
       (page generated 2024-07-22 23:13 UTC)