Tìm hiểu công nghệ đồ hoạ RTX Neural Rendering của NVIDIA (P.1)
Một ngày nào đó GPU sẽ không "vẽ" ra frame nữa, mà chúng sẽ "mơ thấy" frame...
Nội dung bài viết
Bạn đang dùng GPU gì?
Mọi khi đây có thể là câu hỏi đùa. Vì bình thường mọi người thường nghĩ GPU như card đồ hoạ rời, chip rời (DGP), do không phải ai cũng "may mắn" có điều kiện để sắm thứ như vậy. Nhưng hôm nay, đó là câu hỏi nghiêm túc - bạn đang dùng GPU gì?
Những gì bạn đang đọc thấy là kết quả làm việc của GPU
Dù ít ai để ý tới, nhưng thực tế mọi thiết bị công nghệ có-dính-tới-màn-hình-hiển-thị hôm nay, từ PC cho tới tablet, smartphone, wearable... đều có GPU. Đơn giản thôi, không có GPU thì chả có cả con chữ đang chình ình trước mắt cho bạn đọc. IGP dù "cùi bắp" tới mức nào thì nó vẫn là GPU. Tất nhiên từng có giai đoạn trong quá khứ việc hiển thị hình ảnh, con chữ không do GPU đảm nhiệm (Direct2D đời đầu) nhưng đó là thời Napoleon rồi. Nên những gì bạn đang thấy trên một màn hình hôm nay (không tính TV hay điện tử gia dụng) dù là 1 inch, 2 inch hay 5.5 inch hay 32 inch, đều là kết quả làm việc của GPU.
Uh thì ai cũng đang dùng GPU để đọc bài viết này. Nhưng nó có can hệ gì tới RTX Neural Rendering (tạm gọi NR) của NVIDIA?
Can hệ ở chỗ kể cả bạn có đang dùng GPU rời xịn xò để đọc bài này thì tương lai chưa chắc nó đã chơi được một số game 3D. Và đừng nghĩ chỉ có game PC mới ảnh hưởng. Game console hay mobile đều có thể bị "liên đới" nếu NR trở thành tiêu chuẩn chính thức để render hình ảnh 3D. Chiếc Nintendo, PlayStation hay Xbox mới sắm của bạn rất có thể sẽ "bó tay" với NR.
Theo NVIDIA, đồ hoạ tương lai là Neural Rendering chứ không phải rasterization truyền thống
Vậy NR là gì? Nói cho gọn đây là phương pháp render hình ảnh mới dựa trên Cooperative Vector (CoopVec) vốn là thành phần mới trong bộ DirectX (DX) 12 mà Microsoft (MS) vừa công bố hồi đầu năm nay. Về mặt chính thức cả AMD và Intel cũng hỗ trợ CoopVec/NR, nhưng thực tế NVIDIA là đơn vị đề xuất ra bộ API này và họ đã "xúi giục" MS "chuẩn hoá" phương pháp trên. Do vậy bài viết này sẽ chủ yếu nói về NR của NVIDIA và những thay đổi nó có thể dẫn đến.
* PS : đợt ra mắt dòng card Blackwell RTX 50 mới đây của NVIDIA bị xem là "thảm hoạ" do hàng loạt sự cố xảy ra. Nó đã dẫn tới một tâm lý tương đối tiêu cực với công ty này lẫn các công nghệ của họ. Cá nhân mình cũng không ưa cái cách NVIDIA đang "đối xử" với PC gamer nhưng "ignorance is bliss". Nếu cứ tâm lý anti mãi đôi khi chúng ta sẽ bỏ lỡ những điều thực sự hay ho. Nên trong bài viết này, mình sẽ cố giữ quan điểm trung lập về NR nói riêng và đồ hoạ 3D nói chung *
Cơ bản về render hình ảnh và rasterization
Trước khi nói về NR và tại sao nó có thể thay đổi cách game 3D làm việc, chúng ta cần nắm rõ một vài vấn đề cơ bản, cụ thể là cách GPU làm việc bao lâu nay và rasterization. Bởi vì theo NVIDIA, game của tương lai sẽ không cần rasterization nữa, tất cả có thể thay bằng ray tracing (thậm chí là path tracing) để tạo ra hình ảnh.
Vậy rasterization là gì? Nói cho nhanh, đó là quá trình biến dữ liệu vector thành bitmap.
Việc chụp hình cũng là 1 thao tác "đạo hàm" vật thể 3D thành ảnh 2D
Nhưng cái gì là vector, cái gì là bitmap? Thực tế khi bạn dùng một camera kỹ thuật số (số, không phải phim nhé) để lưu giữ một khoảnh khắc nào đó trong đời sống, là bạn đang thực hiện raster-hoá một chủ thể vector. Bạn biến thứ không-có-độ-phân-giải thành dữ liệu có-độ-phân-giải. Những tấm ảnh 2 MP, 5 MP, 10 MP hoặc hơn đều là dữ liệu bitmap. Chúng có giới hạn về chiều rộng, chiều dài, mỗi chiều có bao nhiêu pixel. Ngoài ra, chủ thể vector ban đầu là chủ thể 3D. Nhưng khi bị raster-hoá, chúng trở thành đối tượng nằm trong mặt phẳng 2D, cụ thể chính là cái màn hình bạn đang đọc chữ/xem ảnh.
Quay lại GPU, mọi hình ảnh mà bạn đang thấy thực chất là ảnh 2D, bất kể bạn đang mở desktop, xem youtube hay chơi game 3D. Cái font chữ mà bạn dùng trong file Word hay HTML ban đầu đều là dữ liệu vector, nhưng khi bạn chọn một màn hình có một độ phân giải cụ thể, thì những gì bạn thấy trên màn hình chính là dạng bitmap của nó. Nói cách khác, mọi thứ được raster-hoá để chuyển thành ảnh 2D có kích thước cụ thể.
Chủ thể vector không có độ phân giải. Khi bị raster hoá sẽ thành các pixel có độ phân giải cụ thể
Dĩ nhiên, những dữ liệu đã là bitmap sẵn (ảnh chụp camera, màn hình...) thì chúng không cần raster-hoá nữa. Trừ phi bạn thay đổi tỷ lệ thể hiện trên màn ảnh (phóng to, thu nhỏ), thay đổi thuộc tính của chúng (biên tập, chỉnh sửa) thì xuất hiện thêm quá trình raster-hoá thứ cấp. Ở đây, do bản chất hiển thị dữ liệu 2D không phải chủ đề chính, nên mình sẽ tập trung vào hình ảnh/đồ hoạ 3D.
Ống lệnh đồ hoạ 3D
Về khái quát, để tạo ra một ảnh đồ hoạ 3D cơ bản có 3 bước - (1) ứng dụng gửi yêu cầu, (2) lập mô hình 3D (dạng vector), (3) raster-hoá mô hình 3D thành ảnh 2D. Ngoài ra có thể tính thêm bước (4) nữa là xuất ảnh ra màn hình nhưng thường sau rasterization là hình ảnh đã tạo ra xong nên bước này thường không được nhắc tới.
Tổng quan các bước để tạo ảnh raster đồ hoạ
Trong đó bước (1) thực hiện trên CPU nên mình bỏ qua. Chỉ bước (2) và (3) là quan trọng.
Cơ bản mà nói, bước (3) y hệt cách chúng ta dùng camera để chụp hình một chủ thể nào đó đã nêu ở trên. Nhưng trước khi "chụp hình" thì phải tồn tại chủ thể. Bước (2) chính là quá trình tạo ra chủ thể.
Đầu tiên GPU sẽ vẽ ra các điểm (vertex). Bạn có thể mở lại SGK môn Hình học để hình dung rõ hơn. Từ các điểm này, GPU nối chúng lại thành đoạn/đường thẳng (line). Nối nhiều đường lại, chúng ta có mặt phẳng (plane). Trên mặt phẳng sẽ có đa giác (polygon). Số lượng đa giác càng nhiều thì mô hình sẽ càng chi tiết cũng như sẽ tốn nhiều công sức để vẽ hơn. Đây là lý do tại sao có meme về Lara Croft đời đầu có những khu vực mà-ai-cũng-biết đều là khối tam giác thô kệch, trong khi phiên bản sau này tròn-đều hơn rất nhiều. Đó chính là sự khác biệt giữa số lượng đa giác dùng để tạo mô hình 3D (dĩ nhiên còn vì GPU ngày xưa yếu hơn rất nhiều).
Điểm, đường, mặt, đa giác là khởi đầu cho mọi ảnh 3D
Số lượng đa giác càng nhiều thì độ chi tiết chủ thể càng cao
Nói thêm trong quá trình vẽ đa giác, bắt đầu từ DX 11 trở đi bổ sung thêm một thành phần gọi là tessellator. Bạn có thể đọc là bộ rạn hoá (tessellate) hoặc bộ tăng cường đa giác cũng được. Mục đích là GPU sẽ tự động vẽ thêm đa giác vào mô hình gốc mà designer tạo ra từ trước, thông qua hệ số TessFactor. Lý do chủ yếu để tiết kiệm thời gian mà designer cần bỏ ra cho một chủ thể nào đó. Nếu game có vài chục ngàn vật thể thì thiết kế chi tiết toàn bộ rất tốn công. Với tessellator, những chủ thể vô định hình như hòn đá, cành cây... có thể được vẽ chi tiết hơn một cách tự động.
Tessellator là công cụ cho phép chủ thể có thêm nhiều đa giác mà từ đầu không có sẵn
Sau giai đoạn dựng hình khối (geometry) sẽ là giai đoạn chuyển đổi góc camera. Nó tương ứng như khi chụp ảnh ngoài đời, bạn di chuyển camera đến vị trí nào đó để có góc nhìn (viewport) ưng ý nhất. Ở đây, ngoài yếu tố chiều rộng (x), chiều cao (y) vốn có trên một ảnh 2D ra thì còn chiều sâu (z) tuy chúng ta không thấy được nhưng nó sẽ đóng vai trò quan trọng trong việc thể hiện độ xa gần của chủ thể cũng như dùng trong xử lý hậu kỳ. Mục đích của giai đoạn này là định hình những yếu tố nào sẽ được render tiếp ở các bước sau (thứ không có trong khung hình không cần render).
Vị trí góc nhìn quyết định chủ thể nào sẽ được render, chiều sâu phối cảnh xa gần
Giai đoạn tiếp theo là chiếu sáng (lightning). Bản chất các đa giác vốn dĩ không có màu sắc hay ánh sáng. Chỉ tới khi được chiếu sáng thì chúng mới "hiện nguyên hình". Khu vực bề mặt nào gần nguồn sáng hơn thì nó... sáng lên và khu vực bề mặt xa hơn (nếu không có nguồn sáng khác) sẽ tối đi. Ở đây cần phân biệt thuật toán chiếu sáng này không phải là dò tia (raytrace/pathtrace). Chúng ta sẽ nói rõ hơn ở khúc sau.
Cùng 1 chủ thể nhưng cách chiếu sáng khác nhau sẽ cho kết quả hiển thị khác nhau
Sau khi các chủ thể đã "hiện hình" rồi thì cần làm gì? Vì bản chất khung hình là 2D, sẽ có những chi tiết bị che khuất. Chủ thể nào "đứng sau" (dựa trên thông số chiều sâu Z) sẽ bị "cắt" (clipping/culling) khỏi khung hình. Chỉ phần nào "thấy được" thì dữ liệu của nó mới được gửi tiếp qua công đoạn sau.
Cái gì bị khuất mặt khuất mày thì không cần render ra
Sau công đoạn loại bỏ chi tiết thừa là công đoạn đổ nền vật liệu (texturing). Về bản chất khi dựng mô hình chủ thể, GPU hoàn toàn không có khái niệm cái gì là ngôi nhà, cái gì là tấm vải, cái gì gạch bông hay ván nhựa hay cục gỗ... Với GPU tất cả là mô hình. Chỉ khi thông số vật liệu (texture) được nạp vào thì chủ thể lúc này mới được gán thuộc tính bằng gỗ hay bằng cement hay bằng nhựa, vải... Cần nói thêm thuộc tính này chỉ "đắp" vô bên ngoài chủ thể, chứ không phải "bộ đồ lòng", nên vật liệu đôi khi còn được gọi là vân bề mặt. Đến đây, về cơ bản là ống lệnh đồ hoạ đã hoàn tất việc dựng hình.
Cùng chủ thể, cách chiếu sáng nhưng vật liệu khác nhau cũng cho kết quả đồ hoạ khác nhau
Nếu bỏ qua các khâu xử lý hậu kỳ (post-processing), thì đây sẽ là bước cuối cùng - tạo pixel cho từng hình. Với các dữ liệu hình học, ánh sáng và vật liệu đã có từ các công đoạn trên, cái cần để xuất ra màn hình chính là dữ liệu từng pixel của khung hình đó. Ở đây, thông tin quan trọng chính là độ phân giải - 480p, 720p, 1080p, 1440p, 2560p hoặc bất kỳ con số dài x rộng nào khác.
Răng cưa là bệnh cố hữu của ảnh raster và luôn cần khử răng cưa để nhìn đỡ... ngứa mắt hơn
Thực tế mà nói, chúng ta vẫn còn phát sinh nhiều cái khác nhưng để giữ cho mọi thứ đơn giản nhất có thể, bạn chỉ cần nhớ một ống lệnh đồ hoạ 3D gồm các bước dựng mô hình - chiếu sáng - đổ vật liệu - dựng pixel. Và từ các bước này hình thành ra các đơn vị chức năng như vertex shader, geometry shader, pixel shader, texture mapping unit (TMU)...
GPU ngày nay cấu tạo như thế nào?
Trước khi vào chi tiết, cần nói trước chúng ta chỉ bàn tới GPU RỜI của AMD, NVIDIA và Intel. GPU tích hợp (IGP) đi kèm các chip SoC tuy bản chất cũng có các thành phần tương tự nhưng sức mạnh thường không cao nên tạm bỏ qua.
Sơ đồ khối GPU Radeon R300 (DX 9). Đáng tiếc mình không tìm được bản vẽ nào cụ thể hơn về các khối chuyên môn 🙁
Ở phía trên chúng ta đã thấy các công đoạn cơ bản để tạo ra một ảnh 3D (thành 2D) như thế nào. Có thể thấy toàn bộ quá trình này dù đã được đơn giản hoá vẫn có rất nhiều bước và mỗi bước cần một đơn vị chuyên trách để xử lý. Nên GPU nhìn chung là một thiết kế ASIC và từng thành phần trong GPU tự nó cũng là ASIC riêng. Đây là đặc trưng của GPU thời kỳ trước DX 10.
Việc mỗi công đoạn cần một đơn vị chuyên môn dẫn tới một bất cập là khi tăng sức mạnh xử lý hoặc vertex, hoặc geometry, hoặc texture, hoặc pixel đều dẫn tới tình trạng các công đoạn sau đó bị nghẽn cổ chai. Và khi đơn vị đó thảnh thơi nhàn rỗi thì các đơn vị khác phải cong đít lên chạy cho kịp. Kết quả là nhà sản xuất GPU bị kẹt ở cái thế rất khó tăng sức mạnh xử lý đồ hoạ vì để giữ được tính cân bằng thì khi tăng năng lực công đoạn A, họ phải tăng luôn các công đoạn còn lại để "bù đắp". Nhìn chung rất khó để con chip đời sau mạnh hơn đời trước vì có quá nhiều thứ phải làm chỉ để tăng sức mạnh một cách nhỏ giọt.
Từ DX 11 trở đi, những thành phần có thể thay đổi cách làm việc (programmable) gọi chung là shader
Nhận ra sự bất cập này, ATI (trước khi AMD mua lại) đã đề xuất một hướng thiết kế GPU mới. Đó là những công đoạn nào có tính đơn giản và có thể thay đổi qua lại thì gom chung lại để xử lý trong cùng một đơn vị, gọi là unified shader. Từ đây khái niệm vertex shader, geometry shader, pixel shader đều được xem như nhau. Từ đó dẫn tới GPU sau này khi nói về sức mạnh xử lý, chúng ta sẽ hỏi nó có bao nhiêu nhân shader (hoặc SP, hoặc CUDA, hoặc ALU, tuỳ theo hãng, nhưng bản chất là một). Và đây chính là định nghĩa của GPU DX 10 - chúng phải có unified shader.
Sơ đồ khối Radeon HD 4870 và 5870 đều có unified shader (SP). Hãy chú ý phần vertex, geometry, pixel phía trên là nơi quản lý công việc. SP mới là nơi công việc được tiến hành
Tất nhiên không phải thành phần nào cũng có thể unified. Vẫn có những bộ phận phải đứng riêng vì tính chất của chúng khác hẳn nhau. Ví như tessellator trên DX 11, ray tracing trên DX 12, hoặc TMU, ROP, Display Engine. Chính vì thế mà kích thước GPU "phình to" lên cực nhanh so với CPU. Những con chip lớn nhất hiện nay phần lớn là GPU.
Sơ đồ khối GeForce GTX 480 với shader core chiếm phần lớn diện tích. Các thành phần chuyên môn vẫn có vị trí riêng trong toàn bộ cấu trúc
Và DX 11 cũng có thể xem là giai đoạn GPU của AMD và NVIDIA vẫn có những thành phần tương tự nhau - shader, tessellator, TMU, ROP. Nhưng từ đó trở về sau, nhiều thứ đã khác...

2 thoughts on “Tìm hiểu công nghệ đồ hoạ RTX Neural Rendering của NVIDIA (P.1)”