16 ms·
Show HN: GPU text rendering with vector textures
- watmough 11y agoExactly what I needed, just as I was about to start screwing with distance fields or the like. THANK-YOU! Edit: I may have spoken slightly too soon, not since the technique isn't awesome, but because this isn't yet usable without an atlas generation tool that I don't know how to build. As far as performance goes, this is rendering a 124-page PDF (I know, just the glyphs...) utterly without lag using the GPU, on a 16 Gbyte quad i7 box that can barely render a couple of pages under OS X Preview without significant pauses. Impressive and Incredible.
- davej 11y agoIt's very laggy and slow on a quad i7 16GB Macbook Pro. Presumably this is because of the retina display.
- watmough 11y agoHere's my experience on my local devices: * Quad i7 16 GBytes GTX 970 OSX FFox - perfectly smooth * iPhone 6s+ - very smooth * Nexus 6p - slightly jumpy / laggy but still impressive * Lumia 640 Windows Phone 10 - dFdx undeclared identifier (120,33) There may be issues with webgl on the MBP if it's using Intel graphics, but I'd be pretty disappointed to get worse performance than an iPhone ... For the curious, the Lumia error appears to stem from this: https://groups.google.com/forum/embed/#!topic/angleproject/-CcKYvupr80 https://groups.google.com/forum/embed/#!topic/angleproject/-...
- davej 11y agoYeah my rMBP uses an embedded Intel graphics card. The performance is horrible, ~2 fps, tried FF and Chrome.
- smskelley 11y agoEven with a discrete card (M370x), the performance is poor on my rMBP. I only tried Chrome, though.
- microcolonel 11y agoPerformance is pretty decent (around 48fps for a full page with lots of glyphs, 1080p) on my Intel HD 4400. This is on linux though. I hear the OS X intel drivers have some shader compiler pitfalls.
- bhauer 11y agoIt's amazingly smooth, I'd say 60+ fps, on my i7-3770K desktop (Geforce GTX970) with Firefox Developer Edition.
- mangecoeur 11y agoGetting perfectly smooth performance on a similar quad i7 16GB Macbook Pro under Firefox 43... perhaps a browser issue?
- green7ea 11y agoI don't think it's because of the retina display. I'm running it very smoothly in Linux at 3200x1800 with an Intel HD4000
- rayiner 11y agoI can scroll that PDF at full speed on my rMBP without significant pauses.
- skybrian 11y agoIt's rather laggy for me. (2011 MacBook Pro.)
- plg 11y agoIt's pretty great on this iPad Air 2
- DonHopkins 11y agoTextMesh Pro comes with an atlas generation tool. See my description above.
- jon-wood 11y agoI find it curious the number of people in this thread being amazed that high end i7 processors and graphics cards designed for gaming can passably render some text. Is there something I'm missing?
- Qantourisc 11y agoIt's not so much they are amazed it capable of doing this. But more of a WOW this is fast compared to rendering theses slow PDF pages on the CPU. It's a bit like saying: wow this rocket propelled car is fast. Are we surprised it is faster ? No. Are we like: "wow we could go faster !"? Yes To be fair, I don't understand why we don't have a lib, or even this stuff build into OpenGL/Direct3D. We are doing raster work CPU's. It's relatively slow.
- corysama 11y agoMicrosoft has Direct2D https://msdn.microsoft.com/en-us/library/windows/desktop/dd370987(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/dd3... Nvidia has it's nvPathRendering extension to OpenGL https://developer.nvidia.com/nv-path-rendering https://developer.nvidia.com/nv-path-rendering I'm not aware of a fully portable equivalent to either of these two libs.
- vidarh 11y agoThe something you're missing is that we're used to see this done on the CPU, and it's not something CPUs are good at: Pages full of text rendered with scalable fonts involves either a huge number of bezier curves etc. or a huge number of small blits, though you can trade some of it off by spending huge amounts of memory pre-rendering and caching (but if you cache bitmaps at the character level, you will find it harder to do really nice typography - ligatures etc.). It's not that it's that amazing that it's possible on a GPU, but that it's amazing to see the difference.
- joosters 11y agoSorry to sound like an old fart, but computers have been doing this for years, and no, caching rendered glyphs does not eat huge amounts of memory. e.g. RiscOS on ancient ARM processors, drawing sub-pixel anti-aliased text on a CPU that had no floating point. Even just 64kb of font cache to store the bitmaps could keep everything running blazingly fast. Of course, the font renderers have gotten smarter, and of course, screen resolutions have increased, but the difficulties inherent in font renderering are all at the small scale, where you want text to remain crisp even when using only a few pixels.
- pshc 11y agoVery clever technique! It seems more true to letterforms than SDF. Seems like it might need more texture bandwidth/dependent reads than SDF, but less texture memory as a whole? I've been looking at different text rendering methods for a VR engine. I wonder if this technique works in 3D space? If so I'll give it a shot, benchmark it against SDF :)
- DonHopkins 11y agoI'm using TextMesh Pro for a VR/AR application in Unity called Pantomime, and it works great for text in the 3d world space, as well as 2d gui dialogs. You can get up really close to the text, and it looks perfect. I posted some links to demos on the TextMesh Pro forum here: http://digitalnativestudios.com/forum/index.php?topic=470.msg3493#msg3493 http://digitalnativestudios.com/forum/index.php?topic=470.ms... Some discussion about text in VR: https://www.reddit.com/r/oculusdev/comments/34d8nm/reading_in_the_dk2/ https://www.reddit.com/r/oculusdev/comments/34d8nm/reading_i... More about Pantomime: http://pantomimecorp.com http://pantomimecorp.com
- sho_hn 11y agoAnother one: https://github.com/behdad/glyphy https://github.com/behdad/glyphy (SDF, but full vector outlines, not texture sampling)
- microcolonel 11y agoI'm actually quite surprised this author didn't mention Glyphy.
- rayiner 11y agoSee also: http://www.msr-waypoint.net/en-us/um/people/cloop/LoopBlinn05.pdf http://www.msr-waypoint.net/en-us/um/people/cloop/LoopBlinn0... (work done on the subject at Microsoft Research, with more of the math described).
- watmough 11y agoJust had a quick read though that paper, and it doesn't really look like the same thing. This technique treats a pixel as a unit circle, coloring it according to its length of intersection, along multiple axes, with a glyph simply described by 3 point beziers, oriented to keep 'inside' on the right. A point fully inside a glyph has a trivial intersection, and is fully shaded. Points on the edge of a glyph intersect a bezier, with shading of the pixel being proportionate to the amount of intersection, giving anti-aliasing. The product I work on in my day job has similar code to handle rendering filled polygons, with similar constraints on widdershins/anti-widdershins to turn off filling for 'holes'. The 'magic' of this technique seems to be applying that technique in a shader, on a per-pixel basis. There's no triangulation that I can see (compare with the elaborate schemes Loop-Blinn paper above), just a decomposition of glyphs to these ordered collections of 3 point bezier curves, and some fiddling to get it all saved in a texture.
- rayiner 11y agoYes, it's a different technique, one that creates a triangle mesh from the curves first. Sorry for the lack of clarity in my original post.
- dman 11y agoYou might not want to read that, afaik that technique is patented. :)
- geofft 11y agoWell now that you said that it's 3x damages, whether or not you read it (at least in the US, the standard is whether there's "an objectively high likelihood" of infringing some patent that is "either known or so obvious that it should have been known" to you, so knowing that a thing's been patented counts even if you don't read the patent). But even 1x damages are pretty high. Read it carefully and do something sufficiently different and avoid infringement in the first place.
- dvt 11y agoAlthough cool, this is not a particularly novel idea. I remember reading a 2007 SIGGRAPH paper about something similar Valve did in HL2 (or maybe it was Orange Box). Either way, it was a similar method of rendering vector textures via distance fields. Here it is: http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_...
- nanodeath 11y ago...did you read the article? This exact paper was referenced in the second section.
- mattzito 11y agoThis isn't my field of expertise, so maybe I'm missing something, but the article cites the paper you describe in literally the second paragraph.
- mattdesl 11y agoSigned-distance field fonts (as described in that paper by Valve) is very different form the OP's approach.
- _ZeD_ 11y agostrange, I only see white rectangles on the demo (using ff 43.0.3)
- kevingadd 11y agoThis is a cool technique. The WebGL demonstration is pretty compelling! It's a little odd to me that they describe distance fields as having an unavoidable problem with sharp corners, though. The Valve paper on signed distance fields for text demonstrates a simple workaround that fixes sharp corners...
- thorp5555 11y agoWhile it seems simple in the paper, it is way more complicated to implement in practice as it comes with all sorts of edge cases. https://lambdacube3d.wordpress.com/2014/11/12/playing-around-with-font-rendering/ https://lambdacube3d.wordpress.com/2014/11/12/playing-around...
- DonHopkins 11y agoSigned Distance Field fonts are wonderful! I've been using a Unity extension called TextMesh Pro, which works very efficiently, and renders beautiful text that you can configure and decorate in many ways. Beyond the obvious benefits of SDF fonts, it also has excellent and extensive layout, formatting and other useful features, like automatically scaling the text to fit in a given area. The source code for the shaders and formatter and ugui integration is included, but not the atlas generator (although you might ask the developer if you need it -- he's engaged and helpful, and provides good support and quick fixes for Unity updates). It includes desktop shaders with many fancy features (outlines, drop shadows, beveling, glow, bump mapping, a surface shader that reacts to lighting and throws shadows into the world), and simplified optimized shaders for mobile. I've used it (and read the source code to see how it works), and can testify that it works great on Unity's desktop, iOS, Android and WebGL backends. The code itself and the way it offloads so much work to the GPU is very beautiful and elegant. TextMesh Pro - Unite 14 Demo: https://www.youtube.com/watch?v=q3ROZmdu65o https://www.youtube.com/watch?v=q3ROZmdu65o Here's a benchmark that compares 5000 crisp TextMesh Pro objects rendering at 70 FPS, versus 5000 fuzzy Unity text objects rendering at 42 FPS: https://www.youtube.com/watch?v=rdc8UkxuSZc https://www.youtube.com/watch?v=rdc8UkxuSZc Here's the same benchmark compiled with Unity's WebGL backend, with the same number of 2500 static and 2500 dynamic text objects. Nowhere near the 70 FPS of native code of course, but not bad for WebGL and so many objects -- zoom in with the mouse wheel to see the text up close: http://donhopkins.com/home/TextMeshProBenchmark/ http://donhopkins.com/home/TextMeshProBenchmark/ TextMesh Pro on the Unity Asset Store: https://www.assetstore.unity3d.com/en/#!/content/17662 https://www.assetstore.unity3d.com/en/#!/content/17662 Digital Native Studios home page: http://digitalnativestudios.com/ http://digitalnativestudios.com/
- thorp5555 11y agoThey are good but they do have their weaknesses: Rounded Corners, Not good with thin lines, time required to generate the SDF
- rasz_pl 11y agono subpixel rendering or hinting. Im confused - is there a problem with cpu rendered fonts that needs fixing? I didnt notice anything wrong last time I was reading schematics and datasheets on 4K monitor.
- ssalazar 11y agoThis is useful for gaming or any other application where text is integrated into a GPU rendered 3D environment and may be subject to affine transformations.
- pcwalton 11y ago> Im confused - is there a problem with cpu rendered fonts that needs fixing? Performance. Even if an inefficient painting algorithm manages to paint at 60 FPS (which is very much not the case in, for example, common Web apps), improving its performance can free up the CPU to do more things and can reduce power consumption. Think about it. If your GPU is sitting there idle, why not use it and free up the CPU to do other things? Today, most apps that aren't games are woefully underutilizing the GPU. Programs ideally should be utilizing all the silicon in your device while working so the work can be done faster and the hardware can enter low-power mode quicker.
- barrkel 11y agoOn a modern PC games use a small fraction of the CPU and the GPU is the bottleneck. The only applications that really strain the CPU (i.e. all cores) are trivially parallelizable ones like transcoding, compilation, test suites, etc. For games specifically I'd prefer more work done on CPU and free up the GPU, provided the communication overhead isn't too much and latency doesn't become a problem. Low power is less of a problem than thermal limiting for compute intensive work. I see about 90% variation in test times on my laptop for unit tests, for example. So overall I see more application for this in apps than games, and only then when the tradeoffs are right. It's not a simple call.
- corysama 11y agoGames graphics engine guy here. I'm very happy to move text rendering from the CPU to the GPU. Done well it moves milliseconds of CPU work to tenths (or less) of milliseconds of GPU work. Also, I care quite a bit about power draw because my customers on laptops and mobile are very sensitive to it. If my game is a battery hog, it doesn't get played as long or as often.
- thorp5555 11y agoThe use of the grid reminds me of Qin 2006's "Real-time texture-mapped vector glyphs": http://dl.acm.org/citation.cfm?id=1111433 http://dl.acm.org/citation.cfm?id=1111433 http://docdro.id/ynU32mg http://docdro.id/ynU32mg (Paper) http://docdro.id/t6XiE97 http://docdro.id/t6XiE97 (Slides)
- pcwalton 11y agoThis is really neat. Though in practice if you are using this kind of thing I'm pretty sure you will want to combine it with atlasing (i.e. construct an atlas of glyphs via render to texture). That's because it's a waste of time to rerasterize glyphs in the FS every frame (which appears to be 200+ lines) instead of caching the results and reducing the per-frame work to a 5-line FS that just blits. In most apps pans are more common than zooms and the same glyphs are used over and over, so this usually ends up being a win. Using atlases also reduces the number of raster operations because the same glyphs tend to appear on the page repeatedly, and by using atlases you rasterize each glyph only once. Even more importantly, though, atlasing gives you the ability to reuse a blitting fragment shader to render other content (images, figures, etc.) as well as glyphs from the atlas in order to reduce state changes.
- baldajan 11y agoThat was my first thought. This is brilliant, but the FS is way overworked, making this less practical and going back to the original solution (because it's fast). It's a trade off between speed and variability, which for games (and most apps) speed trump variability (especially because of consistent design). But given generating a texture atlas is a "1 time task"; and recompiling the curves in the GPU is per frame in the paper, the next best thing I guess is off loading the glyph atlas generator to the GPU, not CPU, since the GPU maybe faster. It's really awesome research!
- carterehsmith 11y agoWait. I guess you did not read the article at all? It is all about atlasing. There are issues with atlas of glyphs; so rather than putting the whole glyphs in atlas, he slices the glyphs in a grid, the grid being defined by the intersection of the underlying Bezier curves. And then he puts the grid pieces in atlas.
- pcwalton 11y ago> Wait. I guess you did not read the article at all? It is all about atlasing. Yes, I understand the technique. Perhaps I should be more clear about my terminology. I'm using "atlas" in the narrow sense of "actual pieces of bitmap data stored in a texture". My point is that this technique should not be a substitute for atlasing in this sense, but could well be combined with it.
- mattdesl 11y agoGreat work! Is there any WebGL source available? The demo runs very poorly on my 15" MBP (late 2013, Intel Iris Pro). I'm not sure if it's just the sheer number of glyphs being rendered at once, or whether it's something specific that this GPU is having trouble with. Some related links for those interested in WebGL text rendering: 1 - https://github.com/Jam3/three-bmfont-text https://github.com/Jam3/three-bmfont-text 2 - http://mattdesl.svbtle.com/material-design-on-the-gpu http://mattdesl.svbtle.com/material-design-on-the-gpu 3 - https://github.com/mattdesl/text-modules https://github.com/mattdesl/text-modules
- monk_e_boy 11y agoWorks fine on my nvidia 620m
- chii 11y agoi too, am interested in the sources. Viewing the source on the page is an OK option too i guess, but it'd be nice to have it as a library that i can examine (and potentially use!)
- microcolonel 11y agoIt's probably Apple's custom intel HD graphics driver. I'm getting 60fps on an intel HD Graphics 4400 on linux.
- spoiler 11y agoWhole PC freezes (except the cursor) with GeForce GT 610 in Chrome (Linux) on the demo. Can't even switch to another tty to kill the process. The PC is average otherwise (AMD FX 8320 with 8GB of RAM).
- rcarmo 11y agoThe demo works surprisingly well on an iPad mini 4. Amazing, really.
- voltagex_ 11y agoThis looks great, but I don't understand much of the article. As a half-decent dev, what do I need to do to write "Hello World" on the screen?
- rphl 11y agohttp://fontstruct.com/fontstructions/show/1054333/4ants-mono http://fontstruct.com/fontstructions/show/1054333/4ants-mono http://fontstruct.com/fontstructions/show/1115871/4ants http://fontstruct.com/fontstructions/show/1115871/4ants My favorite vector fonts.
- deleted 11y ago[deleted]
- jacobolus 11y agoThis paper from 2014 is the best recent work I’ve seen about rendering vector graphics on the GPU: http://w3.impa.br/~diego/projects/GanEtAl14/ http://w3.impa.br/~diego/projects/GanEtAl14/
- monk_e_boy 11y agoWhy don't GPUs have some hardware in them to make rendering text simpler? It seems like a pretty common function that every game has. Have you ever seen a game without any text in it?
- ris 11y agoFixed-function hardware on GPUs is really on the way out.
- a_e_k 11y agoNice work. The subdivision into cells and encoding into GPU textures is strongly reminiscent of the 2008 paper "Random-Access Rendering of General Vector Graphics" by Nehab and Hoppe [1]. Rotating the line samples is a rather interesting idea. Seems like that would converge to the equivalent of a convolution with a radial tent filter. [1] http://w3.impa.br/~diego/publications/NehHop08.pdf http://w3.impa.br/~diego/publications/NehHop08.pdf
- Apanatshka 11y agoSource: MS Paint. haha, that's clever ^^ EDIT: seriously though, those are some Paint skills, I didn't even notice until I saw the "source" text below it.
- e98cuenc 11y agoIt doesn't work here, Nexus 5. That's what I see when I zoom in: https://goo.gl/photos/3EXv2t4YZRxmyNPe8 https://goo.gl/photos/3EXv2t4YZRxmyNPe8
- orangeduck 11y agoI really like this idea, but bezier curves are quite computationally difficult to use. There are many representations of these kind of continuous shapes which are much easier for this kind of processing. For example I would try converting the bezier representation into an implicit HRBF representation (here is a good explaination in 3D http://rodolphe-vaillant.fr/?e=12 http://rodolphe-vaillant.fr/?e=12). This representation should be much easier to process on the GPU - checking how much the point is inside/outside the glyph should only be one matrix multiplication which would make the computation in the actual shader really really fast.
- jvuletich 11y agoI did a simpler, potentially faster approach that also does subpixel AA: https://dl.dropboxusercontent.com/u/13285702/M3.png https://dl.dropboxusercontent.com/u/13285702/M3.png https://dl.dropboxusercontent.com/u/13285702/M3-TTF8.png https://dl.dropboxusercontent.com/u/13285702/M3-TTF8.png https://dl.dropboxusercontent.com/u/13285702/morphic3-jenson.png https://dl.dropboxusercontent.com/u/13285702/morphic3-jenson... https://dl.dropboxusercontent.com/u/13285702/Morphic3-TimesNewRomanSample.png https://dl.dropboxusercontent.com/u/13285702/Morphic3-TimesN... http://www.jvuletich.org/Morphic3/Morphic3-201006.html http://www.jvuletich.org/Morphic3/Morphic3-201006.html http://www.defensivepublications.org/publications/prefiltering-antialiasing-for-general-vector-graphics http://www.defensivepublications.org/publications/prefilteri...
- jepler 11y agoThe method seems to assume the geometric complexity of a glyph is relatively small. I wonder if it will work with CJK glyphs. Possibly the number of tiles per glyph would need to be greater; I'm not sure how badly a couple of doublings would impact performance.