3 điểm bởi GN⁺ 2023-11-24 | 1 bình luận | Chia sẻ qua WhatsApp
  • Việc nhập môn đồ họa không có một đáp án duy nhất, mà thay đổi tùy theo kiến thức sẵn có, cách học và phần cứng; đội ngũ AMD Game Engineering cho rằng người mới có thể cần một điểm khởi đầu thân thiện hơn
  • Lập trình đồ họa có cấu trúc gồm việc viết đồng thời mã C++ ở phía CPU và mã shader ở phía GPU, rồi kết nối chúng bằng các API đồ họa như DirectX, Vulkan, OpenGL
  • Tính đến năm 2023, các lựa chọn chính được chia thành API legacy như OpenGL, DirectX 11, WebGL và API explicit hiện đại như Vulkan, DirectX 12, Metal, WebGPU
  • API legacy dễ học hơn, nhưng độ phức tạp của driver và runtime đã tăng lên; API hiện đại đòi hỏi nhiều mã hơn và hiểu biết về GPU hơn, đổi lại trao nhiều quyền kiểm soát hơn
  • Ban đầu có thể bắt đầu từ môi trường đơn giản như OpenGL, WebGL, game engine hoặc Shadertoy; nếu đã hiểu đủ về C++ và pipeline GPU, cũng có thể đi thẳng vào Vulkan hoặc DirectX 12

Cấu trúc cơ bản của lập trình đồ họa

  • Câu trả lời ngắn gọn cho ngôn ngữ mà lập trình viên đồ họa chủ yếu dùng là C++
  • Công việc thực tế là viết đồng thời mã host chạy trên CPU và mã shader chạy trên GPU
    • Mã host CPU thường được viết bằng C++
    • Mã GPU được viết bằng ngôn ngữ shading bậc cao như HLSL hoặc GLSL
  • API đồ họa là điểm kết nối cho phép mã CPU yêu cầu GPU thực hiện công việc bằng shader cùng dữ liệu và metadata cần thiết

Nên bắt đầu với API đồ họa nào

  • Tính đến năm 2023, các API thường dùng trong game PC và ứng dụng 3D nhìn chung được chia thành hai nhóm
    • API legacy: OpenGL, DirectX 11, WebGL
    • API explicit hiện đại: Vulkan, DirectX 12, Metal, WebGPU
  • OpenGL, DirectX 11, WebGL dựa trên cách tiếp cận lịch sử để lập trình GPU, và đơn giản hơn, dễ học hơn từ góc nhìn của lập trình viên
  • Sự đơn giản đi kèm chi phí
    • Theo thời gian, phần triển khai bên trong driver và runtime trở nên phức tạp hơn
    • Điều này dẫn đến nút thắt ở phía host và gánh nặng driver phức tạp mà các nhà cung cấp GPU phải viết
  • Mantle của AMD xuất hiện trên PC trong giai đoạn 2013–2016, cung cấp khả năng truy cập GPU ở mức thấp hơn và lớp trừu tượng mỏng hơn thông qua hợp tác giữa GPU AMD và EA DICE
  • Metal xuất hiện trên nền tảng Apple vào năm 2014, còn DirectX 12 và Vulkan xuất hiện vào năm 2016, xử lý việc lập trình GPU theo cách mức thấp hơn và explicit hơn

Đánh đổi trong học tập giữa API dễ và API explicit

  • Vulkan và DirectX 12 tạo gánh nặng ban đầu lớn hơn vì lập trình viên phải chỉ định rõ ràng hơn những việc muốn GPU thực hiện
  • Đổi lại, bạn có nhiều quyền kiểm soát hơn và cũng có nhiều cơ hội hơn để nâng cao hiệu năng và hiệu quả của công việc trên GPU
  • Chỉ nhìn vào ví dụ vẽ tam giác đầu tiên cũng thấy khác biệt giữa các API
    • OpenGL hoặc DirectX 11 có thể vẽ tam giác đầu tiên chỉ với khoảng 10 dòng
    • Vulkan và DirectX 12 cần nhiều mã hơn đáng kể
  • OpenGL và DirectX 11 che giấu nhiều chi tiết, giúp bạn nhanh chóng tiếp cận công việc đồ họa hiệu quả, nhưng hoạt động của GPU có thể trông như một chiếc hộp ma thuật
  • Vulkan và DirectX 12 yêu cầu kiến thức mức thấp và hiểu biết về GPU ngay từ đầu, nhưng đổi lại từng dòng mã thể hiện rõ hơn những gì sẽ xảy ra trên GPU

Các lựa chọn lộ trình nhập môn

  • Ngay trong đội ngũ AMD Game Engineering cũng tồn tại đồng thời ý kiến rằng DX12 hoặc Vulkan là quá khắc nghiệt để thanh thiếu niên hay người mới bắt đầu, và ý kiến rằng vẫn có thể nếu điều kiện phù hợp
  • OpenGL đã giảm tính hiện đại và mức độ liên quan, nhưng vẫn được đánh giá là đủ tốt để học nền tảng
  • WebGL có thể là điểm khởi đầu dễ hiểu cho graphics pipeline
    • Trên web, có thể xử lý đồ họa thời gian thực bằng JavaScript mà không cần C++
    • Dùng WebAssembly cũng có thể chạy đồ họa bằng C++ trong trình duyệt
  • WebGPU cung cấp các khái niệm gần hơn với API đồ họa hiện đại, đồng thời có thể đòi hỏi ít chi tiết mức thấp hơn
    • Khi bắt đầu viết mã phức tạp, bạn vẫn có thể gặp nhiều vấn đề
    • Đây là API hứa hẹn cho prototyping, học tập và giáo dục
  • Cũng có thể bắt đầu trước bằng game engine
    • Unreal Engine chiếm tỷ trọng lớn trong game PC
    • Unity cũng là một lựa chọn thay thế phổ biến
    • Cũng có những engine mã nguồn mở nhỏ và đơn giản hơn như Godot
  • Một số trường dùng Unity cho bài học rendering đầu tiên, nhưng có rủi ro là sinh viên không hiểu vì sao mình cần học kiến thức mức thấp
  • Nếu muốn bắt đầu bằng API explicit, bạn cần hiểu rõ dòng chảy lớn của graphics pipeline hiện đại và cách phần cứng GPU triển khai nó, hoặc có ý chí học sự hiểu biết đó song song

Tài liệu học được khuyến nghị và bước tiếp theo

  • LearnOpenGL: trang dành cho người mới, phù hợp để học lập trình đồ họa bằng API thực tế trong C++
  • Scratchapixel: có thể tập trung vào cách các khái niệm như ray tracing hoạt động mà không cần nhiều mã
  • Udemy: có thể dùng làm nơi tìm các khóa học cho người mới bắt đầu
  • Rastertek: tutorial OpenGL, DirectX 11
  • Ray Tracing in One Weekend: phù hợp với cách học tự xây dựng để hiểu nếu bạn đã có thể viết mã ở mức nào đó
  • A trip through the graphics pipeline: tuy là bài viết năm 2011, trước thời API explicit, nhưng các khái niệm phần cứng và phần mềm từ góc nhìn GPU vẫn còn áp dụng được
  • learn wgpu: trang học WebGPU có phong cách tương tự LearnOpenGL, và vẫn mang tính đang được hoàn thiện
  • Your first WebGPU app: có thể xem là tài liệu nhập môn WebGPU
  • Shadertoy: cho phép viết shader mà không trực tiếp xử lý API đồ họa, nên trở thành điểm khởi đầu đơn giản hơn
  • Vulkan Tutorial: được đề cập trong bối cảnh rằng khi học Vulkan hoặc DirectX 12, điều quan trọng là đừng ngại sao chép và dán
  • Nếu vẫn chưa quyết định hệ sinh thái ngôn ngữ hoặc API, bạn có thể thử nhiều cách tiếp cận và tiếp tục dùng cách phù hợp với mình

1 bình luận

 
GN⁺ 2023-11-24
Ý kiến trên Hacker News
  • Người mới nên lùi lại một bước và hỏi trước “mình muốn tạo ra thứ gì”, thay vì bắt đầu bằng “mình sẽ dùng công cụ nào”
    Ngay cả khi mới học, cũng không được đánh mất kết quả cuối cùng. Đồ họa máy tính ngày nay có quá nhiều công cụ trừu tượng hóa các bước vẽ pixel lên màn hình, nên bạn có thể vật lộn với code cấp thấp ngay từ đầu, rồi về sau mới nhận ra lĩnh vực mình muốn theo đuổi chỉ dùng Unity, TouchDesigner, threejs, After Effects, còn C++ thì hầu như không dùng
    Tất nhiên, học cách mọi thứ vận hành từ tầng nền là cực kỳ giá trị, nhưng tôi cho rằng làm việc đó đầu tiên là một cách tiếp cận chậm. Việc học sẽ nhanh hơn khi bạn bước vào ngành, dùng các công cụ trừu tượng như game engine hoặc lập trình trực quan để nắm khái niệm về cơ chế bên trong
    Tôi nói điều này từ vị trí của một người đã mất vài năm học C++ và OpenGL một cách vất vả, và từng đấu tranh rất lâu với chi phí chìm khiến mình không chấp nhận được cách tiếp cận no-code. Cuối cùng, nếu con đường đó không giúp bạn tạo ra thứ mình muốn tạo, thì tốt nhất đừng lãng phí thời gian vào nó

    • Nên nghe lời khuyên này. Đầu sự nghiệp, tôi đã quyết tâm trở thành chuyên gia OpenGL, và tôi nghĩ ở một mức độ nào đó mình đã làm được
      Tôi không viết sách giáo khoa như Mark Kilgard, nhưng đã đào sâu nhiều tầng của API, từ cấp driver đến kiểm thử tính tương thích, tinh chỉnh hiệu năng, code game và ứng dụng, cũng như các nền tảng desktop và mobile lớn
      Nhưng rồi nó dẫn đến đâu? Thật ra là chẳng đi được xa lắm. Giờ gần như không còn nơi nào quan tâm đến OpenGL, và khi hai nhà cung cấp OS lớn cuối cùng cũng bỏ nó, nó gần như đã trở thành một công nghệ đã chết. Cứ thử tìm OpenGL trên “HN Who's Hiring” là biết
      Tôi có thể học lại các API đồ họa khác như Direct3D, Vulkan, Metal, nhưng code đồ họa cấp thấp giờ đã được engine trừu tượng hóa, nên không có nhiều nơi cần người như vậy. Các công ty cần nhân sự driver đồ họa cấp thấp trên toàn thế giới nhiều lắm cũng chỉ 5–6 nơi, vì vậy nó trở thành một ngách giới hạn sự nghiệp
      Bạn càng tập trung vào một phần nhỏ hơn của cỗ máy, thì để biến nó thành toàn bộ sự nghiệp, bạn càng phải trở thành chuyên gia tầm thế giới. Nếu kế hoạch của bạn không phải là trở thành John Carmack tiếp theo, tôi khuyên nên đi rộng thay vì đào quá sâu
    • Đây là cái bẫy kinh điển mà các lập trình viên mới luôn mắc phải. Nó cũng không chỉ áp dụng cho lập trình đồ họa
      YouTube đầy rẫy video lập trình cho người mới bắt học hết chuỗi tech stack này đến tech stack khác, thay vì tập trung tạo ra thứ gì đó thú vị. Kết quả là, chỉ để làm đẹp CV, họ tạo ra những cỗ máy Rube Goldberg phức tạp kiểu sùng bái hàng hóa chỉ để render vài dòng chữ trên trang web
      Hồi đại học tôi từng học một chút lập trình đồ họa trong một học kỳ, và nó đủ phức tạp để câu trả lời hợp lý cho “mình muốn tạo ra thứ gì” chỉ là “render một tam giác xanh trên nền đen”. Từ đó tiến lên hình vuông, khối lập phương, hình cầu, hình cầu có animation, rồi quả bóng nảy là một tiến trình tự nhiên và giúp bạn tập trung vào mục tiêu. Vì vậy cũng nên tránh sai lầm trả lời câu hỏi trên bằng “một game bắn súng góc nhìn thứ nhất có chiếu sáng ray tracing và tán xạ dưới bề mặt”
      Code phiên bản đầu tiên của quả bóng nảy chắc chắn sẽ rất tệ. Nhưng không sao. Theo thời gian bạn sẽ biết cách tối ưu và cải thiện. Và không có gì phấn khích bằng việc tự mình khám phá ra design pattern. Khi đọc sách về một chủ đề mới, bạn sẽ có cảm giác “ơ, cái này mình đã làm rồi mà!”
    • Với tư cách là người đang muốn bước vào lĩnh vực này, tôi hơi khó đồng ý. Rất nhiều, thậm chí có thể là tất cả, tin tuyển dụng lập trình đồ họa đều yêu cầu trước kiến thức C++
      Tất nhiên bạn cũng có thể vào bằng vai trò khác như gameplay programmer rồi dần chuyển sang đồ họa, và cách đó có thể dễ hơn. Nhưng cuối cùng, vai trò graphics programmer vẫn cần C++
      Điều nói ở trên giống dành cho người muốn nhanh chóng làm việc hiệu quả với các tác vụ liên quan đến đồ họa hơn, chứ không hẳn là lập trình đồ họa tự thân
    • Lời khuyên hay. Đây cũng là cái bẫy thường gặp trong các câu hỏi kiểu “nên học ngôn ngữ nào / ngôn ngữ nào là tốt nhất”, vì người ta bỏ qua câu hỏi “mình muốn tạo ra thứ gì”
      Công cụ sẽ thay đổi theo thời gian, và theo kinh nghiệm của tôi, các kỹ sư giỏi thường biết dùng nhiều công cụ ở nhiều mức độ thành thạo khác nhau, thay vì chỉ đào sâu một công cụ
    • Tôi vẫn cho rằng kiểu lập trình cấp thấp như vậy có giá trị để dạy ở đại học, giống như thuật toán sắp xếp
      Ngay cả nếu sau này bạn không làm việc đó trong công việc thực tế, bạn vẫn có thể thu được nhiều kiến thức lý thuyết và rèn luyện với các thuật toán phức tạp
      Đồ họa cũng mang lại nhiều trải nghiệm toán ứng dụng. Có rất nhiều lĩnh vực đang rất cần người biết làm toán. Ở công ty trước của tôi về phần mềm máy CNC, chúng tôi cần người lập trình phần toán để điều khiển mũi khoan tạo ra hình dạng cụ thể trên khối kim loại, nhưng thật sự rất khó tìm. Trong khi đó, kỹ sư cloud DevOps tuy đắt nhưng tương đối dễ tuyển hơn
  • Tôi nghĩ một graphics programmer nên có hiểu biết cân bằng, tổng quát về cách đồ họa vận hành. Vượt ra ngoài lập trình đơn thuần và kiến thức API, một graphics programmer giỏi nên biết ma trận xoay·view·projection, toán vector cơ bản, lập trình shader, các primitive thủ tục như Voronoi·SDF·Perlin, tổng hợp ảnh, forward rendering và deferred rendering, nhiều kỹ thuật lấy mẫu khác nhau, kỹ thuật đổ bóng và chiếu sáng
    Ngoài ra cũng cần hiểu art pipeline vận hành như thế nào và cách lấy dữ liệu ra khỏi ứng dụng 3D, sử dụng profiler và debugger một cách thoải mái, có khả năng đọc paper SIGGRAPH, các kỹ thuật phân chia không gian và phân cấp thể tích, triển khai ray tracer đơn giản, hiểu các primitive như sprite·tam giác·đa giác n cạnh, cũng như có kinh nghiệm với particle và simulation

    • Tôi muốn biết liệu bạn có thể giải thích thêm một chút về “art pipeline vận hành như thế nào và cách lấy dữ liệu ra khỏi ứng dụng 3D” không
      Tôi biết luồng rất cơ bản để tạo ra một model, tức modeling → skin/rigging → animation → texturing, và đại khái cách ghi nó vào file. Nhưng phần này đặc biệt khó có được kinh nghiệm thực chiến đúng nghĩa nếu không làm cùng artist
    • Tôi muốn biết nếu đã biết phần lớn những thứ trong danh sách này thì làm thế nào để xin được việc làm graphics developer
      Tôi đang lập trình đồ họa như một sở thích và đã học nhiều thứ được nhắc ở đây, nhưng vì không có kinh nghiệm công việc, tôi gần như không có cơ hội phỏng vấn
    • Có thể học những thứ này ở đâu?
  • Khuyến nghị khóa học Graphics From Scratch của Pikuma. Việc đầu tiên là viết hàm set_pixel bằng SDL, và các bước sau đó đều tự triển khai trực tiếp bằng code
    Tự viết toàn bộ phép toán ma trận, mọi phép biến đổi đỉnh, đến toàn bộ raster hóa tam giác, rồi tính xem mỗi pixel nên có màu gì
    https://pikuma.com/courses/learn-3d-computer-graphics-progra...

    • Website/sách/khóa học của tôi cũng đi theo cách đó, và miễn phí
      https://www.gabrielgambetta.com/computer-graphics-from-scrat...
    • Thêm một phiếu ủng hộ đề xuất này. Vài tháng trước, khi gần như không biết gì về lập trình đồ họa, tôi đã học khóa này; dù chỉ có vài năm kinh nghiệm làm kỹ sư phần mềm nói chung, tôi vẫn hiểu khá rõ quá trình một hình dạng 3D được vẽ lên màn hình
      Sau đó tôi có thể học WebGPU chỉ trong vài ngày; nếu không có sự hiểu biết từ khóa học, chắc tôi đã không làm được
      Nếu cần động lực, tôi đã thử làm một demo biên dịch renderer được xây dựng ở cuối khóa học sang Wasm: https://rmshin.github.io/3d-renderer-wasm
    • Đây là một điểm thú vị. Tôi đã suy nghĩ nếu tự thiết kế một khóa nhập môn đồ họa thì sẽ làm thế nào
      Nên bắt đầu bằng code SDL kiểu putpixel như thập niên 90, hay bắt đầu với Shadertoy? Toán ma trận cơ bản tất nhiên luôn quan trọng. Nhưng nên dạy raster hóa tam giác ra sao? Có thể bỏ qua scanline mà chuyển thẳng sang tọa độ đồng nhất và quadtree không?
      Có thật sự nên dạy tô bóng Phong, hay có thể đi thẳng vào BRDF? Một số phần có thể thành ra dạy “mẹo cũ” hơn là kỹ thuật hữu ích
      Ngày nay, thống kê và lấy mẫu quan trọng hơn nhiều. Tôi tin rằng đồ họa đang ngày càng trở nên toán học hơn qua từng năm. Vì vậy hãy học toán, và hãy dạy toán
    • Có vài tài liệu tốt để triển khai 3D rendering từ con số không
      Trong số đó, tôi thật sự rất khuyến nghị repository GitHub này: https://github.com/ssloy/tinyrenderer/wiki/Lesson-0:-getting...
      Nếu bạn học tốt hơn bằng hình ảnh, kênh này cũng là một kho báu: https://www.youtube.com/watch?v=ih20l3pJoeU
    • “Không GPU, không OpenGL, không DirectX!” là hướng hoàn toàn trái ngược với điều người ta kỳ vọng khi muốn học lập trình đồ họa
  • Có thể học đồ họa bằng cách viết shader trên Shadertoy. Nhiều lập trình viên đồ họa bắt đầu ở đó
    Tự quảng bá một chút: tôi đã làm hơn 10 tutorial về viết shader trong VS Code, SDF, ray marching, hàm noise, fractal Brownian motion, v.v.
    https://github.com/suboptimaleng/shader-tutorials
    Tất nhiên là đang đứng trên vai những người khổng lồ như Inigo Quilez, The Art of Code, SimonDev, Acerola

  • Có rất nhiều con đường để trở thành lập trình viên đồ họa mà không cần bắt đầu bằng DX/VK/OGL. Cũng không nhất thiết phải dùng C++. Chỉ cần xem các đồ họa 3D đáng kinh ngạc mà 3Blue1Brown làm bằng Python
    Nếu muốn dùng game engine thì học DirectX hoặc Vulkan; nếu muốn làm ứng dụng trình duyệt thì học WebGL
    Tuy nhiên các API đó nặng nề, và bản thân chúng cũng không dạy cho bạn quá nhiều về đồ họa. Nếu muốn học các khái niệm đồ họa, tốt nhất là tự làm cả rasterizer và ray tracer bằng ngôn ngữ bạn thích
    Có nhiều thư viện đồ họa và môi trường lập trình thú vị hơn nhiều so với việc vất vả đào sâu Vulkan hay DirectX. Processing rất tuyệt; cũng đáng xem PlotDevice.io dựa trên Python, hoặc các tiền thân của nó là NodeBox và DrawBot. ShaderToy là một nơi khác để học nhiều về viết shader hoặc rendering, và cũng dễ bắt đầu. JavaScript cũng có nhiều lựa chọn và thư viện. Những thứ này dễ tiếp cận và tạo động lực hơn nhiều cho người mới, đồng thời vẫn đủ sức mạnh và linh hoạt để người học tò mò có thể đào sâu đến mức họ muốn

  • Vì bài này đã lên trang nhất, tôi xin đăng một tài liệu thực sự được dùng trong ngành lập trình đồ họa. Nhân tiện, tôi là một trong các tác giả: https://raytracing.github.io/
    Nó cũng có trong mục “Useful Websites” của bài trên
    Đồ họa giờ đã quá rộng, nên một cách học phù hợp cho tất cả mọi người không còn tồn tại nữa. Nếu muốn học đồ họa, tôi khuyên nên tìm một mentor

    • Tài liệu tốt. Tôi đặc biệt đồng ý với cách dạy toán trước thông qua ray tracing thay vì API
  • Tôi là nhà phát triển game nhưng không phải lập trình viên đồ họa chuyên nghiệp. Trong công việc tôi dùng API đồ họa hiện đại và shader GLSL, nhưng gần đây khi một đứa trẻ 13 tuổi muốn chuyển từ Scratch hay Python sang học C++, tôi quyết định cách tốt nhất là lôi ra DLL OpenGL 1.2 cũ vẫn nằm trên máy tính từ năm 1999, rồi cho bắt đầu với code immediate mode kiểu glutglbegin/glvertex/glend
    Cách này vui hơn nhiều so với việc chịu đựng đủ loại thiết lập mà API hiện đại đòi hỏi. Đứa trẻ quan tâm nhiều hơn đến hình học tính toán như biểu đồ Voronoi, nên API đồ họa chỉ là phương tiện để đạt mục đích; shader lộng lẫy hay ánh sáng hiện chưa quan trọng. Hiệu năng của C++ và OpenGL cũ nhanh hơn Scratch khoảng một nghìn lần, nên có vẻ chúng tôi đã tìm được điểm cân bằng phù hợp với giai đoạn học hiện tại
    Ngay cả khi dùng API OpenGL 1.2 đã được đơn giản hóa, việc cố hiểu đồng thời C++ và OpenGL vẫn là một lượng kiến thức khá tham vọng, nên sự đơn giản giúp nó có thể chịu được về mặt tinh thần. Hiện mọi việc đang tiến triển tốt; đứa trẻ đã làm được một demo marching squares khá ổn, và tôi đã giúp gắn thêm menu IMgui để có thể điều chỉnh tham số lúc runtime. Khá vui

  • Tôi không rõ trang web này đang hỏi chính xác điều gì. Muốn làm rigging? Texturing? Modeling? Viết driver? Làm GUI? Animation cho website? Công cụ đồ họa? Shader? Engine ảnh 2D? Game 2D? Game 3D? Script procedural? Tối ưu hóa code đồ họa?
    Dưới cái ô “đồ họa máy tính” có hàng trăm lĩnh vực. Nhưng trang web này lại tập trung vào một góc rất nhỏ trong số đó: lập trình SDK đồ họa

    • Lập trình viên đồ họa là một nhóm lập trình viên được định nghĩa khá rõ. Nhiều thứ trong các ví dụ nêu ở trên như rigging, texturing, modeling không phải là lập trình đồ họa
      Người ta kỳ vọng một lập trình viên đồ họa có thể xử lý tổng thể game, 3D, 2D, công cụ, shader và tối ưu hóa
    • Dù có thể gây nhầm lẫn, nhưng thông thường “lập trình viên đồ họa” chỉ người làm việc trên engine render đồ họa, dù là thời gian thực hay render offline
  • Tôi cũng đang trên hành trình đó. Hai năm trước, tôi đã làm engine 3D đầu tiên của mình bằng cách làm theo nhiều tutorial và video YouTube
    Nó rất đơn giản, nhưng tôi thích những thứ đơn giản. Hiện tôi đang dùng engine này để làm một game xây dựng thành phố. Việc học cách thao tác các phần tử bằng ma trận và tích có hướng thật sự rất thú vị
    https://www.youtube.com/watch?v=cvyrfPUpyp0