18 ms·
Computer Graphics from Scratch
- kayoone 6y agoCG fundamentals was my favourite course in college. Going from drawing lines with the Bresenham algorithm to drawing polygons, filling polygons with Scanline, implementing ZBuffer, texture mapping and so on. Was a lot of fun even though I never ended up working with CG except for some hobby projects.
- arduinomancer 6y agoAgreed, its one of those areas of software that just feels like magic when you code it from scratch and end up with a 3D object on your screen.
- ggambetta 6y agoEspecially raytracing! What I used to do when teaching was taking a few weeks to develop the rasterizer, and then say "OK, 4 weeks to go, time to present your final project - you're making this <image of a raytraced scene with reflections and shadows>, which I'm going to explain within the next 2 hours". Some groups genuinely thought I was joking. But then every one of them managed to write a raytracer, their minds were blown, and they used their renders as desktop backgrounds. I loved that :)
- seism 6y agoYou had me at "rendering a Swiss landscape" 8-) Seriously, this looks like very good material for my own learning or to bootstrap a graphathon.
- ggambetta 6y agoI have a reasonably clear view of the Uetliberg from my kitchen window, so of course I'm biased :)
- ggambetta 6y agoA long time ago, due to an improbable sequence of events, I found myself teaching Computer Graphics at my alma mater, a year after I took the class myself. Over the following five years or so, my approach to the subject evolved, and I really got the hang of it. After I stopped teaching, I took my notes, handouts and slides, and made them into a series of articles that I put on my website, where they remained in relative obscurity. Hacker News managed to find it every once in a while, and it was generally well received, but nothing came out of this. Until April 2019. It made the HN front page again [0], except this time it caught the attention of an editor in No Starch Press [1]. Long story short, today I’m incredibly grateful and excited to tell you that CGFS is coming out as a real book, with pages and all [2]. The folks at NSP graciously agreed to let me publish the updated contents, the product of almost two years of hard editing and proofreading work, for free on my website [3]. But if you’d like to preorder the printed or ebook version, you can use the coupon code MAKE3DMAGIC to get a 35% discount at https://nostarch.com/computer-graphics-scratch https://nostarch.com/computer-graphics-scratch. I’m still somewhat in disbelief that my work is getting published as a book, and this genuinely wouldn’t have happened without your support. So once again, THANK YOU :) [0] https://news.ycombinator.com/item?id=19584921 https://news.ycombinator.com/item?id=19584921 [1] http://nostarch.com http://nostarch.com [2] https://nostarch.com/computer-graphics-scratch https://nostarch.com/computer-graphics-scratch [3] http://gabrielgambetta.com/computer-graphics-from-scratch http://gabrielgambetta.com/computer-graphics-from-scratch
- sriram_sun 6y agoAwesome! Thanks for sharing!
- gauku 6y agoThis looks great. I have been developing interest in CG recently and this looks like a great way to start. Thank you. And finding your Imdb profile was a nice addition on top ;) All the best.
- ggambetta 6y agoThanks! For better or worse, I'm interested in a lot of different things
- reaperducer 6y agoCoincidentally, just last night I was reading an issue of Byte magazine from 1976. It was telling people how to do just this: Computer graphics from scratch. Except, back then "from scratch" meant soldering together wires and transistors and such. The big prize was displaying a vector Starship Enterprise on an oscilloscope.
- ggambetta 6y agoWow, that sounds pretty hardcore! I suppose what's considered "from scratch" evolves over time. I'm old enough to have written bytes to 0xA000 (and the pain of doing page-switching in VESA modes), so even this "putPixel() on a canvas" is not exactly "from scratch" from that perspective!
- fouric 6y agoOne of the things that I really like about this course is that it teaches both raytracing and rasterization. Usually, computer graphics tutorials are either the practical, higher-level, rasterization-focused kind (oftentimes around half "how do opengl"), or how the business card raytracer works. Having a single course written by a single person that presents both major rendering techniques is amazing.
- OnlyMortal 6y agoCrikey. I had to do a breesnam line drawing and hidden surface removal at Polytechnic back in the late 80s.
- ggambetta 6y agoThanks for the kind words! But I have to say the business card raytracer is amazing <3
- Geminidog 6y agoWeirdly, programming this stuff not from scratch can be harder if you use the apis that will utilize the GPU like vulkan or modern opengl.
- psyc 6y agoI understand that Vulcan adds a lot of complexity, but OpenGL and Direct3D are surprisingly finite. Once you learn the graphics pipeline, it’s not too hard to begin drawing things. Init window and device, fill vertex and index buffers, load textures, load vertex and pixel shaders, set each of these things as the active thing, draw. Of course you can also explore the extents of all these entities until the sun engulfs earth. Even though I’ve been at it for 30 years, I realized long ago I would never keep up with, learn, and implement every notable technique even if I did nothing else for the rest of my life. But drawing nice looking, animated 3D things is very tractable.
- ratww 6y agoThis is true, but DirectX 11, Metal and modern OpenGL (without cutting edge extensions) are still very accessible to novices, not to mention that you can transfer knowledge between the three of them, so there's little cost in learning a second/third API. Vulkan and DX12 however are the work of the devil.
- moonchild 6y agoVulkan is soulless, like uefi: all functions have more-or-less the same interface. But I wouldn't say it's the work of the devil. Its greatest sin is boilerplate.
- bob1029 6y agoI had the same perspective on this. I spent some time building up a 2d graphics library from zero, primarily for drawing very simple UIs on resource-constrained devices. I initially tried using D3D/Win32 APIs to perform the high-level drawing operations for me, but found that for the scope of functionality that I required, these interfaces were far too heavy-handed. These also have lots of platform-specific requirements and mountains of arcane frustrations to fight off. I didn't need to interface with some complex geometry or shader pipeline in hardware. Raytracing is hilariously out of scope. I really just needed a dead simple way to draw basic primitives to a 2d array of RGB bytes and then get that to the display device as quickly as possible. What I ended up with is something that isnt capable of very much, but can run on any platform and without a dedicated GPU. I also feel like this was a much better learning experience than if I had slammed my head into the D3D/opengl/et. al. wall.
- bstahlhood 6y agoInstant buy. This is so awesome. I was just looking into this subject, so this comes at a perfect time for me. Thank you for the coupon :) I got a good chuckle out of your technical reviewer: "Alejandro currently works in the GPU Software group at a leading consumer electronics com- pany based in Cupertino, California." I wonder where he works? ;)
- ggambetta 6y agoI can't confirm nor deny what you're implying.
- jtanderson 6y agoThis looks really great! I'd also highly recommend Ray Tracing in One Weekend[1], which starts you out with literally just a c++ program to dump bytes into a file which can be opened with most standard image/document viewers. Then you don't have to think about or set up any shaders before you can start to experiment with the rendering algorithms. [1] https://raytracing.github.io/books/RayTracingInOneWeekend.html https://raytracing.github.io/books/RayTracingInOneWeekend.ht... Edit: formatting.
- genpfault 6y agoHalf-space rasterization[1] is a neat alternative to the classic scan-line renderer. [1]: https://web.archive.org/web/20120212184251/http://devmaster.net/forums/topic/1145-advanced-rasterization/ https://web.archive.org/web/20120212184251/http://devmaster....
- news_to_me 6y agoYeah I find this method way easier to understand than scan conversion. Fabian Giesen has a great series of articles from 2011 that explains it well[0]. Also the original 1988 paper by Pineda is a surprisingly easy read, and it's only 4 pages![1] [0]: https://fgiesen.wordpress.com/2011/07/06/a-trip-through-the-graphics-pipeline-2011-part-6/ https://fgiesen.wordpress.com/2011/07/06/a-trip-through-the-... [1]: https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.157.4621&rep=rep1&type=pdf https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.15...
- dang 6y agoThis had a sizeable thread two months ago: https://news.ycombinator.com/item?id=25266812 https://news.ycombinator.com/item?id=25266812 Also 2019: https://news.ycombinator.com/item?id=19584921 https://news.ycombinator.com/item?id=19584921 and a bit here: https://news.ycombinator.com/item?id=19096322 https://news.ycombinator.com/item?id=19096322
- ggambetta 6y agoThe 2019 thread is what led No Starch Press to contact me in the first place, so I'm very grateful to the HN community :) Keep up the incredible work, dang!
- dang 6y agoIt's super gratifying when feedback loops that end up producing real-world benefits pass through HN threads. I love hearing about those. Congratulations on the book. To judge by HN's consistent interest in this material, it must be awesome.
- Lichtso 6y agoRendering (forward or backward) of algebraic curves (like bezier and nurbs) never gets mentioned in any such collections, despite being essential to any 2D or GUI framework. And if they are, then only as a short: Just subdivide / tessellate it and then put it through the polygon pipeline! However there are far better ways to handle them, which even people in CG seem to be oblivious of. And of course not to forget all the other approaches to modeling geometry like implicit surfaces, meta-balls, signed distance fields, constructive solid geometry, point clouds, splats, voxels, etc ...
- ggambetta 6y agoCurves I had to leave out, as many other things. I explained my motivations in this other comment: https://news.ycombinator.com/item?id=26020311 https://news.ycombinator.com/item?id=26020311 Constructive solid geometry I do mention as an extension to the raytracer [0], but it doesn't have a dedicated chapter. Perhaps for the 2nd Edition? :P [0] https://gabrielgambetta.com/computer-graphics-from-scratch/05-extending-the-raytracer.html#constructive-solid-geometry https://gabrielgambetta.com/computer-graphics-from-scratch/0...
- Const-me 6y ago> there are far better ways to handle them I did some research a year ago. Found a few alternatives, yet none of them was good enough. Here's the issues I remember. 1. It's complicated. Cubic segments can self-intersect or contain singularities. 2. Stroked curves are used a lot. To build stroke edges from the curve, need to offset the curve by half width of the stroke. When you offset a polyline you gonna get another polyline. Yet the offset of Bezier splines is not generally representable as another Bezier spline. 3. In some use cases, hardware-implemented MSAA is the best way of AA. Polygon pipeline gives you that for free. Producing SV_Coverage in pixel shaders to achieve same effect for mid.points of triangle is hard and inefficient. 4. Games have been pushing GPUs for high polygon count for couple decades now, GPUs became really good at that. Also GPUs have early Z rejection that drops pixels or even larger blocks before pixel shader stage. You can't have that if you sending large primitives and computing curves in pixel shaders. Polygon pipeline is not necessarily slower.
- wilsonfiifi 6y agoHey thanks for the book as well as the discount code. Quick question, do you think this will be beneficial to me if say I want to write a server side charting library?
- ggambetta 6y agoHmmm, probably not. The book doesn't really go much into drawing 2D shapes - just the minimum necessary to be able to draw filled triangles, at which point it jumps into 3D stuff.
- Animats 6y agoNice. There are several ways to approach this subject. This is a bottom-up approach - how do we get pixels on screen? Other approaches start from "how do we represent a scene", in the sense of a scene graph or at least lists of vertices, triangle indices, and textures. That cuts the problem into "represent scene" and "render scene". That's a practical division, because that's the interface between what you put into a renderer and what the renderer does with it. Today, you're either using someone else's rendering system, or you're building the rendering system. Probably not both, except as an exercise. This division is actually a bit above the OpenGL/Vulkan level. Vulkan is complicated because it's mostly about setting up the GPU to run a rendering pipeline, talk to displays, and other housekeeping. And memory management. If you have a library to manage that part, it's not so bad. It's like old computer books, where you started out learning what the arithmetic/logic unit (the ALU) did, how it interacted with memory, what the instruction decoder did, and so on. This prepared you for assembly language programming. Few courses start out there today. Incidentally, the caption for figure 12-1 is missing some symbols. It reads "Using instead of doesn’t produce the results we expect."
- ggambetta 6y agoThanks for bringing up the issue with the caption. This is a bug in my own pipeline to convert the book to website format; it looks just fine in the book itself. It should read "Using DrawFilledTriangle instead of DrawWireframeTriangle doesn't produce the results we expect." Will fix.
- huskyr 6y agoExcellent resource! I really like the fact that everything is centred around the idea of just a single 'PutPixel' function. Makes things much more approachable. I've took the liberty of rewriting the 'Perspective projection' demo (1) in more up-to-date Javascript, using ES6 classes and all the other niceties that modern browsers have. I also used the regular canvas line drawing methods to focus on just the vertex-to-line conversion, and updated the code so that it will work on any resolution. https://codepen.io/hay/pen/gOLazpm https://codepen.io/hay/pen/gOLazpm 1: https://gabrielgambetta.com/computer-graphics-from-scratch/demos/raster-05.html https://gabrielgambetta.com/computer-graphics-from-scratch/d...
- leowoo91 6y agoIf you like the idea, I highly recommend taking a look at "3d math primer for graphics and game development" which is a pretty easy read as well.
- drawkbox 6y agoWhen you get to game networking Gaffer On Games is a must read. Efficient game networking layers are all about that UDP [2] and reliable UDP [3]. When web games were huge it would have been pure gold to have WebRTC with built in UDP, NAT/punchthrough etc. [1] https://gafferongames.com/ https://gafferongames.com/ [2] https://gafferongames.com/post/reliability_ordering_and_congestion_avoidance_over_udp/ https://gafferongames.com/post/reliability_ordering_and_cong... [3] https://gafferongames.com/post/reliable_ordered_messages/ https://gafferongames.com/post/reliable_ordered_messages/
- ggambetta 6y agoI also wrote about client-side prediction and server reconciliation [0], I suppose you're referencing that; but just to be clear, this book is just about graphics, and has nothing to do with that (other than the fact that multiplayer games generally have graphics) [0] https://gabrielgambetta.com/client-server-game-architecture.html https://gabrielgambetta.com/client-server-game-architecture....
- drawkbox 6y agoI was just saying to people interested in games, it is good to get a base level to advanced guide to every part including rendering, networking, gameplay etc that is a good source built from experience and explains things clearly. Yours looks like a great source for networking as well, thanks for adding it. I see you reference Gaffer on Games and the Valve Latency Compensation article, both are great for understanding game networking and helped me greatly in shipped titles especially prior to Unity/Unreal using stuff like enet [2]/RakNet [3]/custom. Lots of networking libs inherited the best from those like reliable UDP, channels and dealing with NAT. Both are excellent libraries to help understand the full picture and get started. Lots of game engines networking libs are based on those. [1] https://developer.valvesoftware.com/wiki/Latency_Compensating_Methods_in_Client/Server_In-game_Protocol_Design_and_Optimization https://developer.valvesoftware.com/wiki/Latency_Compensatin... [2] http://enet.bespin.org/ http://enet.bespin.org/ [3] http://www.jenkinssoftware.com/ http://www.jenkinssoftware.com/ + https://github.com/facebookarchive/RakNet https://github.com/facebookarchive/RakNet
- 6y ago
- keithnz 6y agoI remember as a kid in the 80s trying to do simple things like draw diagonal lines.... painful.... then wanting to draw a circle. That was even more painful. My dad was a physicist and taught me the math needed.... I can remember watching with awe as my circles render slowly. Fun times. I was super impressed when I saw programs draw circles quickly. Now, it's all trivial! But I'm sure many would be lost if the only thing they could do is set a single pixel!
- Const-me 6y ago> Now, it's all trivial It stops being trivial if you want these circles to look nice and render fast. Take a look: https://github.com/Const-me/Vrmac#vector-graphics-engine https://github.com/Const-me/Vrmac#vector-graphics-engine
- ggambetta 6y agoDrawing diagonal lines as a kid in the 80s is exactly how I started :) My very first program (or at least the first one I have evidence of) was about drawing a bunch of lines on a ZX Spectrum [0]. I should make one of these "how it started / how it's going" things. https://gabrielgambetta.com/computer-graphics-from-scratch/dedication.html https://gabrielgambetta.com/computer-graphics-from-scratch/d...
- atum47 6y agoThank you for sharing.
- MisterTea 6y ago> "The choice of axes is arbitrary, so we’ll pick something useful for our purposes. We’ll say that Y is up and X and Z are horizontal, and all three axes are perpendicular to each other. Think of the plane XZ as the “floor,” while XY and YZ are vertical “walls” in a square room." As someone who works with CAD/CNC machines on a daily basis, this is torment. XY is the floor and XZ, YZ are "walls". Same would go for a 3d printer. They're not that arbitrary.
- leloctai 6y agoY up is very common in computer graphic. As for CAD, I know at least Solidworks have the option to use Y up. I think the choice of 3D up axis is related to the expected look direction. 3D printer control software evolved from CNC control software, which is looked at from top down, so up is on the build plate plane. Video game commonly looked at from the side, so up is up. Up is then often associated with Y. And then there the argument about right hand vs left hand coord system...
- ww520 6y agoComputer graphics basically follows what math describes (x,y,z) or what is on the screen or blackboard. On the screen, x-axis is left and right; y-axis is up and down. When z-axis was introduced, it just came in and out of the screen. The convention is negative z values goes into the screen and positive z values out of the screen.
- ggambetta 6y agoI break the negative-Z convention in the book. The math and the diagrams feel a lot more natural to me if Z goes into the screen. I suppose negative-Z comes from measuring Z as "distance from the screen to me", but then you have a bunch of weird negative values in the equations.
- randomswede 6y agoLeft-handed vs right-handed coordinate systems. I prefer right-handed, but for some reason most of computer graphics seem to have adopted left-handed. That was the opposite of fun when I was noodling with writing an OpenGL-based rendering engine for a "fly a spaceship around a 3D maze" game, decade and a half ago. As to why I prefer right-handed? The lin-alg textbook I had at uni uses a right-handed coordinate system for what it calls "the perceivable room" (yes, it is "the book with the cow on", for those in the know).
- davidwf 6y agoI have to say this looks really cool. Maybe this is a really dumb question, but as someone who really knows nothing about computer graphics, how can you actually run these examples? I realize that I could Google and research and find a list of "canvas drawing tools" in a variety of languages that I could then evaluate (despite, again, knowing nothing about graphics), but it'd be SUPER-SUPER-awesome to have a quick note "there are lots of ways to go about making these things happen in the real world, but here's one I recommend if you have no other priors." :-) Really cool book idea, keen to have a go at it!
- aspaceman 6y agoHTML5 Canvas is probably the easiest to get going with some Javascript. Python has PyGame, or you could just plot to PNGs. Java awt has a canvas. C/C++ has SDL/SFML or also plotting to PNGs (or if you want to go wild, embedded GPUs are an option). You could also do all of this in BASIC if you write the canvas commands. All of this is doable on a Commodore in software albeit slowly.
- cravay 6y agoThe demos run live in the browser. You can download and edit them. The code is pretty straightforward and well commented.
- davidwf 6y agoWow thank you! I totally missed the "Source code and live demo" button during my first cursory glance through the chapters, but indeed, there it is. :-)
- ggambetta 6y agoHere's one of the demos, running right inside your browser: https://gabrielgambetta.com/computer-graphics-from-scratch/demos/raster-10.html https://gabrielgambetta.com/computer-graphics-from-scratch/d... If you right-click-view-source, you can see the whole JavaScript implementation right there. This might be the easiest way - make a trivial HTML page with a <canvas> tag and start setting pixel colors in it :)
- signa11 6y agothis approach seems quite similar to the one taken by jamis-buck in “the raytracer challenge” (from pragmatic). if you have not checked it out yet, try it. it is quite enjoyable.
- ggambetta 6y agoWill take a look, thanks!
- wyqydsyq 6y agoI've only had a quick glance but this book looks fantastic, saved for later reading and will definitely consider buying the ebook. I've been teaching myself 3D/CG programming in my spare time using free web resources, I've been trying to learn it "the hard way" by doing everything relatively from scratch, instead of using a high-level engine I'm using low-level libraries writing my own shaders and implementing my own scene graph etc. This book really seems right up my alley and looks like it'll teach me a lot. For anyone else similarly interested in learning to do CG from scratch (particularly on the web), some other great resources I've found are: https://thebookofshaders.com/ https://thebookofshaders.com/ https://webglfundamentals.org/ https://webglfundamentals.org/
- martyvis 6y agoI studied "Computer Graphics" as an elective subject for my Electrical Engineering degree. It was taught by one of the the maths lecturers I think. (Peter Castle at University of Wollongong, maybe 1984). I do remember him playing I guess a VHS of some scenes of what was state of the art, Star Trek Wrath of Khan, I think). Any way it certainly got me interested in ray tracing and DKBtrace and PoVray later.
- wallscratch 6y agoAre there exercises / recommended programming assignments for the book? I didn’t see any when I was just skimming. Thanks.
- ggambetta 6y agoThere's no exercises per se, but the whole book is one big programming assignment (or rather, two) - you build a raytracer and a rasterizer by the end of it.