Skip to content
HomeVideosBooks
AllTopicsTrends
BlogsPodcasts
HistoryListsWatch laterLiked videosFollowing

The videos, books, blogs and podcasts Hacker News keeps recommending, all in one place.

VideosBooksBlogsPodcastsAboutPrivacySettings

Data from Hacker News, HackerTube, HackerBooks, HackerBlogs and Open Library. Credits · Not affiliated with Y Combinator.

HomeVideosBooksBlogsPodcasts
Ctrl K
    Cover of Physically Based Rendering

    Physically Based Rendering

    Matt Pharr, Greg Humphreys, Wenzel Jakob · 2004

    This updated edition describes both the mathematical theory behind a modern photorealistic rendering system as well as its practical implementation. Through the ideas and software in this book, designers will learn to design and employ a full-featured rendering system for creating stunning imagery. Includes a companion site complete with source code for the rendering system described in the book, with support for Windows, OS X, and Linux.

    Electronics & HardwareComputer ScienceProgramming
    Open LibraryAmazon
    Stats for nerds
    92recommend
    157mentions
    109people
    2010–2026years
    85% recommend15% neutral1% critical

    Mentions per year

    201020122014201620182020202220242026

    What Hacker News says

    1. AgentlienAug 2026
      Before listing resources, let me state that the single most important thing is to learn by doing. Write a lot of rendering code, experiment a lot with your own ideas and variations on each exercise. Once you move past the basics don't be afraid to spend several evenings in a row failing to fix what in hindsight seems like an embarrassingly simple math error. That is how you go from having read and sort of understood something to really knowing it. Also, the best approach is usually to devour as much content as you can from several sources to get a wider perspective.

      There are a lot of great resources out there. The best modern beginner friendly resource I am aware of is Scratchapixel[0]. Back when I was first learning 3D I used to follow tutorials on places like NeHe Productions[1], which is probably a bit dated these days.

      For more comprehensive information on all kinds of techniques, with examples from big games for each technique, the absolutely best resource is the book Real-Time Rendering[2].

      If you're interested in ray-tracing rather than rasterization (i.e. more film than video games) a lot of people recommend "Ray Tracing in One Weekend"[3]. If you want to learn state of the art ray-tracing in depth, with all the math and and theory, the best resource is "Physically Based Rendering: From Theory to Implementation"[4], which is freely available online.

      [0] https://www.scratchapixel.com/

      [1] https://nehe.gamedev.net/

      [2] https://www.realtimerendering.com/

      [3] https://raytracing.github.io/

      [4] https://www.pbrt.org/

      thread
    2. pixelesqueJun 2026
      And if you've decided you want to take it a bit more seriously, move on to:

      https://www.pbrt.org/

      which is effectively the bible, and has been for years (I wrote mine and moved into the VFX industry when the Second edition was still out! - I feel old now)

      thread
    3. bobajeffFeb 2026
      It's says:

      >the reference implementation from Physically Based Rendering (Pharr, Jakob, Humphreys)

      I'd like to know a little about the process you went through for the port. That book * sounds like an excellent resource to start from but what was it like using it and the code?

      * https://pbrt.org/

      thread
    4. lioetersFeb 2026
      Quoting the list here for visibility and archival purpose.

      * [Euclidean Vector - Properties and Operations](https://en.wikipedia.org/wiki/Euclidean_vector#Properties_an...) - I assume you know all this already since it's pretty fundamental, but just in case, you'll want to be really comfortable with 2D vector math, and the [dot product](https://en.wikipedia.org/wiki/Dot_product) especially. In 2D graphics, I also find uses for the ["perp dot" product](http://cas.xav.free.fr/Graphics%20Gems%204%20-%20Paul%20S.%2...) all the time. (I maintain that in graphics, if you're calling trig functions too much, you're probably doing it wrong!)

      * [W3C HTML5 2D canvas specification](https://www.w3.org/TR/2015/REC-2dcontext-20151119/) - Obviously, this provides the basis that I was trying to adapt closely to a C++ API. There's a lot of detail in here, including some abstract descriptions of how the implementations are supposed to work.

      * [ISO Open Font Format spec](http://wikil.lwwhome.cn:28080/wp-content/uploads/2018/06/ISO...), [Apple TrueType Reference Manual](https://developer.apple.com/fonts/TrueType-Reference-Manual/), [Microsoft OpenType Spec](https://learn.microsoft.com/en-us/typography/opentype/spec/) - These are the references that I consulted when it came to adding font and text support. In particular, the descriptions of the internal tables where useful when I was writing the code to parse TrueType font files.

      * [Circles in Angles](http://eastfarthing.com/blog/2018-12-27-circle/) - This was a blog post that I wrote after working out the math for how to calculate where to put the center of a circle of a given radius that is inscribed in an angle. This is needed for the `arc_to()` method, but also for computing miter joins for lines.

      * [Drawing an Elliptical Arc Using Polylines, Quadratic or Cubic Bezier Curves](https://web.archive.org/web/20210414175418/https://www.space...) - In my implementation, all shapes get lowered to a series of cubic Bezier splines. In most cases the conversion is exact, but in the case of circular arcs it's approximate. I used this reference for the original implementation for `arc()`. I later changed to a slightly simpler home-grown solution that was more accurate for my needs, but this was a good start.

      * [Converting Stroked Primitives to Filled Primitives](https://w3.impa.br/~diego/publications/Neh20.pdf), [Polar Stroking: New Theory and Methods for Stroking Paths](https://developer.download.nvidia.com/video/siggraph/2020/pr...) - This pair of papers dealing with modern stroke expansion were published concurrently at SIGGRAPH 2020 and were very useful background when I was writing the stroke expansion code. They both have some great examples of how naive methods can fail in high-curvature cases, and how it can be done correctly. I didn't use the full-fat version of these, but I did borrow some ideas (especially from Fig. 10 of the first) without trying to be clever about simplify the path. I also borrowed some of the nice test cases to make sure my code handled them correctly. (It's surprising how many browser canvas implementations don't.) It's also worth learning something about Gaussian curvature, if you don't know it already; both papers give some background on that.

      * [De Casteljau's Algorithm](https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm) - I use recursive tesselation for flattening cubic Bezier splines to a series of line segments (forming polygons). De Casteljau's algorithm is the basis of this, where it recursively splits Bezier splines in half by computing series of midpoints.

      * [Adaptive Subdivision of Bezier Curves](https://agg.sourceforge.net/antigrain.com/research/adaptive_...) - This is a nice writeup by the late author of Anti-Grain Geometry that goes into more details of the recursion, with some ideas about choosing where to split. Adaptive subdivision methods choose whether to recurse or stop based on some estimate of error. I don't use the exact approach here, but a conservative estimate of the maximum distance from the curve, plus a maximum angular turn (determined by solving for the [sagitta](https://en.wikipedia.org/wiki/Sagitta_(geometry)) so that stroke expansion from the tessellated line segments is of sufficient quality).

      * [Reentrant Polygon Clipping](https://dl.acm.org/doi/pdf/10.1145/360767.360802) - While I could just rasterize the entire set of polygons and skip over any pixels outside the screen window (and I did exactly this for a large part of the development), it's a lot more efficient to clip the polygons to the screen window first. Then rasterizing only worries about what's visible. I used the classic Sutherland-Hodgman algorithm for this.

      * [How the stb_truetype Anti-Aliased Software Rasterizer v2 Works](https://nothings.org/gamedev/rasterize/) - I drew inspiration for this for rasterization with signed trapezoidal areas, but implemented the trapezoidal area idea rather differently than this. Still, this should give you an idea for at least one way of doing it.

      * [Physically Based Rendering (4th Ed), Chapter 8, Sampling and Reconstruction](https://pbr-book.org/4ed/Sampling_and_Reconstruction) - This is stuff I already knew very well from my day job at the time writing 3D renderers, but the stuff here, especially Section 8.1, is useful background on how to resample an image correctly. I used this kind of approach to do high quality resampling images for pattern fills and for the `draw_image()` method.

      * [Cubic Convolution Interpolation for Digital Image Processing](https://ncorr.com/download/publications/keysbicubic.pdf) - When you hear of "bicubic interpolation" in an image processing or picture editing program, it's usually the kernel from this paper. This is the specific kernel that I used for the resampling code. It smoothly interpolates with less blockiness that bilinear interpolation when magnifying, and it's a piece-wise polynomial approximation to the sinc function so it antialiases well to when minifying.

      * [Theoretical Foundations of Gaussian Convolution by Extended Box Filtering](https://www.mia.uni-saarland.de/Publications/gwosdek-ssvm11....) - Naive Gaussian blurring (for soft drop shadows here) can be slow when the blur radius is large, since each pixel will need to be convolved with a large Gaussian kernel. It's separable, so instead of doing full 2D convolutions, you can do a pass of 1D convolutions on all the rows, then all the columns or vice versa. But that's still slow. However, iterated convolution of a box kernel is a very good approximation (think of summing dice approaching a Gaussian distribution). And box blurring is very fast, regardless of the kernel size since everything has the same weight - you just add to and subtract from a running sum. This paper is about quickly approximating Gaussian blurs with iterated box-like blurs.

      * [Compositing Digital Images](https://graphics.pixar.com/library/Compositing/paper.pdf) - Porter-Duff forms the basis for the core compositing and blend modes in vector graphics, and is referenced directly by the Canvas spec. For my implementation, I break down the choices of the parameters to use into four bits and encode them directly into the enum of the operation. That way I can implement all the Porter-Duff operations in just 7 lines of code. (I'm pretty proud of that!)

      * [sRGB](https://en.wikipedia.org/wiki/SRGB) - The Canvas spec - transitively, via reference to the [CSS color spec](https://www.w3.org/TR/css-color-3/) - defines that input colors are in sRGB. While many vector graphics implementations compute in sRGB directly, operating in linearized RGB is a hill I'll die on. (I don't go crazy about color spaces beyond that, though.) If you don't you'll end up with odd looking gradients, inconsistent appearance of antialiased thin line widths and text weights, different text weights for light-on-dark vs. dark-on-light, color shifts when resizing. [Here are some examples](https://blog.johnnovak.net/2016/09/21/what-every-coder-shoul...). I do all my processing and storage in linear RGB internally and convert to and from sRGB on input and output.

      * [GPUs prefer premultiplication](https://www.realtimerendering.com/blog/gpus-prefer-premultip...) - Premultiplied alpha is also important for correct-looking blending. The Canvas spec actually dictates _non_-premultiplied alpha, so this is another case where I convert to premultiplied alpha on input, do everything with premultiplied alpha internally, and then un-premultiply on output.

      * [Dithering](https://en.wikipedia.org/wiki/Dither) - I use floating point RGB color internally and convert and quantize to 8-bit sRGB on output. That means that the internal image buffer can easily represent subtle gradients, but the output may easily end up banded if there are too few steps in the 8-bit sRGB space. My library applies [ordered dithering](https://en.wikipedia.org/wiki/Ordered_dithering) to its output to prevent the banding.

      thread
    5. PhilpaxJan 2026
      In addition to the other suggestions, see also https://pbr-book.org/4ed/contents
      thread
    6. a_e_kJan 2026
      And once you get beyond the books the sibling comments here have mentioned (I'd suggest starting with the Ray Tracing In One Weekend minibook series first before Physically Based Rendering), there's the Ray Tracing Gems series (https://www.realtimerendering.com/raytracinggems/) which is open access online with print editions for purchase.

      (Disclosure: I contributed a chapter.)

      thread

    Related

    Cover of Real-time rendering
    2008–2026

    Real-time rendering

    Tomas Möller
    34 recommend · 54
    Cover of Realistic Ray Tracing
    2015–2017

    Realistic Ray Tracing

    Peter Shirley
    3 recommend · 5
    Ray Tracing in One WeekendPeter Shirley
    2016–2026

    Ray Tracing in One Weekend

    Peter Shirley
    48 recommend · 84
    Cover of An Introduction to ray tracing
    2016–2025

    An Introduction to ray tracing

    Andrew S. Glassner
    3 recommend · 4
    Cover of Fundamentals of Computer Graphics
    2010–2023

    Fundamentals of Computer Graphics

    Peter Shirley
    5 recommend · 6
    Cover of Computer graphics
    2018–2024

    Computer graphics

    Steven Harrington
    1 recommend · 4
    Cover of Principles of digital image synthesis
    2011–2022

    Principles of digital image synthesis

    Andrew S. Glassner
    2 recommend · 4
    Cover of Graphics gems
    2010–2026

    Graphics gems

    Andrew S. Glassner
    15 recommend · 29