Công nghệ UE5 Nanite trên WebGPU
(github.com/Scthe)- Nanite WebGPU là dự án triển khai kiểu render Nanite của UE5 ngay trong trình duyệt bằng WebGPU, bao gồm phân cấp meshlet LOD, software rasterizer, billboard impostor, và culling theo đơn vị instance/meshlet
- Việc triển khai đặt mục tiêu chính là sự đơn giản khi tiền xử lý đầu vào OBJ trong trình duyệt, và thử nghiệm thay đổi hiệu năng bằng cách đổi thiết lập qua checkbox và slider
- Demo cung cấp cảnh Jinx 640M triangles, Lucy/Dragons và các cảnh lên tới 1.7B triangles; các tam giác màu trắng của Jinx là kết quả software rasterize được nén và xử lý ở 32-bit do giới hạn của WebGPU
- WebGPU không có
atomic<u64>, nên khó triển khai nguyên dạng một software rasterizer hiệu quả dựa trên visibility buffer; triển khai hiện tại chấp nhận artifact về độ chính xác bằng cách nhét depthu16và octahedron normal2*u8vào 32-bit - Trong một triển khai kiểu Nanite thực tế, vấn đề cốt lõi không phải số lượng tam giác đơn thuần mà là mesh simplification và error metric; tác giả nêu rõ triển khai của mình, khác với UE5, không có simplification, streaming, compression, visibility buffer, 2-pass occlusion culling, v.v.
Tổng quan dự án
- Nanite WebGPU là dự án triển khai render kiểu Nanite trong trình duyệt web bằng WebGPU
- Các thành phần chính được đưa vào gồm meshlet LOD hierarchy, software rasterizer, billboard impostor, culling theo đơn vị instance và meshlet
- Hỗ trợ texture model và per-vertex normal, đồng thời cung cấp slider hoặc checkbox cho từng thiết lập
- WebGPU chỉ có thể sử dụng trên Chrome
- Toàn bộ ứng dụng có thể chạy offline bằng Deno, và các unit test cho shader cũng được viết theo cách này
Cảnh demo và quy mô
- Demo Jinx có 120×120 instance, quy mô 640M triangles
- Một model Jinx đơn lẻ được đơn giản hóa từ 44k triangles xuống 3k triangles, với 59 root meshlets
- Các tam giác màu trắng là những tam giác software rasterize nằm giữa vùng hardware rasterize và impostor ở nền xa
- Lucy and dragons bố trí hai object, mỗi object 70×70 instance, tạo thành 1.7B triangles
- Trong cảnh mẫu, gần 98% tam giác được software rasterize, và tác giả cho biết đường xử lý này nhanh hơn phần cứng rất nhiều
- Lucy là cảnh 110×110 instance, 1.2B triangles
- Một tượng Lucy đơn lẻ được đơn giản hóa từ 100k triangles xuống một root meshlet duy nhất gồm 86 triangles
- Dragons là cảnh 70×70 instance, 1.2B triangles
- Một dragon đơn lẻ được đơn giản hóa từ 250k triangles xuống một root meshlet duy nhất gồm 102 triangles
- Bunnies là cảnh 500×500 instance, 1.2B triangles
- Một bunny đơn lẻ được đơn giản hóa từ 5k triangles xuống một root meshlet duy nhất gồm 96 triangles
- Do bunny có kích thước nhỏ, phần lớn bị frustum culling
Tính năng đã triển khai
-
Meshlet LOD hierarchy
- mesh preprocessing chạy trong trình duyệt
- Sử dụng meshoptimizer và METIS qua WebAssembly
- Cũng cung cấp file exporter để không phải chờ tiền xử lý giữa các lần refresh trang
-
Software rasterizer
- WebGPU không có
atomic<u64>cần thiết cho triển khai hiệu quả - Triển khai hiện tại pack depth
u16và octahedron-encoded normals2*u8vào 32-bit - Do giới hạn 32-bit, độ chính xác bị hy sinh đáng kể; mục tiêu là cho thấy rasterizer có hoạt động
- Giới hạn này cũng ảnh hưởng tới depth pyramid dùng cho occlusion culling
- WebGPU không có
-
Billboard impostors
- Sử dụng 12 ảnh quanh trục UP và blend bằng dithering tùy theo vị trí camera
- Không xử lý góc nhìn từ trên/dưới
- Bao gồm cả diffuse và normal để thực hiện shading ở runtime
- Impostors preview là demo tăng kích thước impostor texture
Culling và đường render
- Culling gồm nhiều giai đoạn
- Per-instance: frustum culling và occlusion culling
- Per-meshlet: frustum culling và occlusion culling
- Per-triangle: hardware backface culling và z-buffer
- WebGPU không có early-z
- Occlusion culling chỉ sử dụng depth pyramid được tạo từ depth buffer của frame trước
- Không có reprojection hay cơ chế two-pass
- Tác giả cho rằng chỉ riêng triển khai hiện tại cũng đủ để culling nhiều tam giác và đánh giá cải thiện hiệu năng
- Có thể chuyển đổi giữa GPU-driven rendering và triển khai CPU đơn giản
- Bản CPU không được tối ưu nhiều, nhưng có thể chạy từng bước bằng debugger
- Tính năng “Freeze culling” cho phép di chuyển camera trong khi chỉ kiểm tra những thứ đã được vẽ ở frame cuối cùng
Khả năng sử dụng và debug
- Di chuyển dùng
[W, S, A, D], lên/xuống dùng[Z, SPACEBAR], di chuyển nhanh dùng[Shift] - Nếu thấy kết quả bất thường, có thể kiểm tra bằng cách bật/tắt các tùy chọn culling
- Trong triển khai có một số bug nhỏ
- Các tam giác màu trắng là tam giác được software rasterize
- Do WebGPU thiếu
atomic<u64>, depth và normal được nén vào 32-bit - 16-bit depth có thể tạo ra nhiều artifact như z-fighting hoặc leak
- Tắt software rasterizer sẽ giúp dễ xem raw Nanite meshlets hơn, nhưng có thể làm hiệu năng giảm mạnh
- Do WebGPU thiếu
- FPS có thể dao động do trình duyệt cưỡng bức VSync; để kiểm tra timing, hãy dùng nút “Profile”
Mục tiêu thiết kế
- Mục tiêu đầu tiên của dự án là tính đơn giản
- Bắt đầu từ tệp OBJ và thực hiện toàn bộ xử lý bên trong ứng dụng
- Không yêu cầu bước tiền xử lý riêng như export từ Blender
- Hướng tới luồng cho phép đặt breakpoint tại
loadObjFile()rồi theo dõi cho đến khi frame đầu tiên kết thúc
- Mục tiêu thứ hai là tính thử nghiệm
- Vì được làm dưới dạng trang web thay vì Rust và Vulkan, bạn có thể nhấp vào liên kết, thay đổi checkbox hoặc slider và xem biến động hiệu năng
- Có thể trực tiếp kiểm chứng tùy chọn nào quan trọng, chẳng hạn FPS giảm mạnh khi đổi một thiết lập
- Nhiều đoạn code có thể được tối ưu hóa, nhưng cho đến khi vấn đề simplification được giải quyết, các tối ưu đó được xem là chưa quan trọng
Khác biệt so với UE5 Nanite
- Error metric sử dụng projected simplification error đơn giản
- Meshlet simplification dùng cách đơn giản
- Không có two-pass occlusion culling
- Việc thêm vào không khó, nhưng debug phiền phức và phát sinh tương tác với các thiết lập GUI
- Không phù hợp với mục tiêu vì làm giảm tính dễ đọc của code
- Không có visibility buffer
- Không thể triển khai do giới hạn
atomic<u64>
- Không thể triển khai do giới hạn
- Không có built-in shadows và multiview
- Không có work queue bên trong shader
- Với meshlet culling và LOD selection, dispatch một thread cho mỗi meshlet
- Không có VRAM eviction và streaming cho các LOD không dùng
- Không có compression
- Khả năng mở rộng thấp với nhiều đối tượng khác nhau
- Tập trung vào lượng bộ nhớ sử dụng có thể dự đoán trong các case demo
- Cần biết trước giới hạn trên của drawn meshlets cho buffer chứa dữ liệu giữa các stage
- Không có BVH hay triển khai phân cấp cho instance
- Thực hiện frustum và occlusion culling trên toàn bộ instance
Điều kiện ẩn sau số lượng tam giác
- Khó đánh giá hiệu năng chỉ bằng con số “hàng chục tỷ triangles”; hiệu năng phụ thuộc vào nhiều yếu tố
-
Dense meshes
- Nếu có nhiều dense mesh ở gần, hiệu năng có thể bị ảnh hưởng tiêu cực
- Tuy nhiên, nếu ở gần đến mức che phủ nhiều màn hình, occlusion culling sẽ hoạt động
- Dense geometry có meshlet nhỏ, chiếm ít không gian trên màn hình và dễ bị occlusion/cone culling
-
Số lượng instance
- Mỗi instance có ma trận transform
mat4x3, tiêu thụ VRAM - Trong frame cũng cần lưu danh sách các mục sẽ render
- Trường hợp xấu nhất là mỗi instance render các meshlet dense nhất
- Theo triển khai, cấp phát
instanceCount * bottomLevelMeshletsCount * sizeof(vec2u)byte - Giới hạn mặc định của WebGPU storage buffer trên Chrome là 128MB, và cảnh demo được điều chỉnh theo điều này
- Mỗi instance có ma trận transform
-
Bố trí scene
- Scene của ứng dụng bố trí đối tượng thành hình vuông
- Các đối tượng ở xa chỉ hiện một phần, nhưng coarse meshlet LOD bao phủ vùng rộng hơn nên gây overdraw
- Dense grid placement render nhiều tam giác ở gần hơn, nhưng chênh lệch độ sâu nhỏ nên thuận lợi cho occlusion culling
- Các đối tượng ở xa có thể khiến một pixel xa bất kỳ làm nhiễm depth pyramid
Vì sao cảnh Jinx khó xử lý
- Nhân vật Jinx mảnh, có khoảng trống giữa tay và thân, khiến occlusion culling khó hơn
- Mô hình không được đơn giản hóa tốt, nên ngay cả coarse LOD nhất cũng có 3k triangles
- Dẫn đến tình huống tích lũy nhiều tam giác kích thước 1 pixel
- Software rasterizer giúp ích đáng kể, nhưng do cách bố trí scene, phần lớn instance được render bằng impostor
- Ở vùng gần, hardware rasterizer đảm nhiệm; hardware rasterizer, software rasterizer và impostor mỗi loại có thế mạnh riêng
Những điểm đáng ngạc nhiên trong triển khai Nanite
- Mục tiêu của DAG không chỉ là dùng ít tam giác cho đối tượng ở xa, mà là duy trì tính nhất quán trên toàn màn hình gần với 1 pixel == 1 triangle
- Với discrete LOD mesh, mỗi LOD là geometry riêng, nên khó đáp ứng khi cần mức trung gian; vì vậy cần continuous LOD
- Meshlet hierarchy cho phép sampling geometry ở mức chi tiết đã chọn
- Thời gian dành cho culling và xử lý meshlet nhiều hơn bản thân Nanite
- Làm cho meshlet LOD hierarchy chạy được thì dễ, nhưng làm cho nó hiệu quả thì khó
- Nếu mesh không được đơn giản hóa gọn gàng, sẽ xuất hiện tình huống như Jinx: khoảng 3.000 triangles cùng phủ một pixel đơn lẻ
- Nếu muốn pixel-sized triangles, cần software rasterizer; billboard impostor cũng hữu ích như một fallback thiên về ổn định
Vấn đề mesh simplification
- Simplification không phải là bài toán “nhận mesh rồi giảm xuống X% triangles”, mà là bài toán được thực hiện trong ngữ cảnh meshlet và METIS
- UE5 dùng code mesh simplification riêng làm bước đầu tiên trong asset pipeline
- Chi phí giảm được ở đây mang lại lợi ích dây chuyền cho toàn bộ hệ thống phía sau
- Trong tài liệu SIGGRAPH của Brian Karis, LOD graph kết thúc bằng một root cluster duy nhất, và cho biết bất kỳ model nào cũng có thể được đơn giản hóa xuống 128 triangles
- Mô hình Jinx gặp vấn đề simplification bị dừng ở một điểm nhất định
- Có tình huống đưa vào X triangles nhưng nhận lại đúng X triangles
- Thuật toán crash vì assertion
- Sau đó, các phần mesh không giảm đủ được chuyển sang cho phép nhiều root trong DAG
- Mô hình bunny ban đầu được đơn giản hóa thành một meshlet 128 tris duy nhất, nhưng khi đổi điều kiện thì lộ ra vấn đề không đi về một root duy nhất
- Nhiều meshlet không giảm đủ số triangle, và cũng có nhiều meshlet “chưa đầy” với ít hơn 128 triangles
- Thảo luận liên quan:
Chỉ số lỗi
- Khi render một mesh 20.000.000 tam giác bằng hệ phân cấp meshlet, cần chọn meshlet nào là meshlet “đúng”
- Bài toán lựa chọn này là cốt lõi của Nanite, còn simplification, meshlet DAG và software rasterizer gần như là các điều kiện tiên quyết để xử lý nó
- Phần triển khai sử dụng projected simplification error do meshoptimizer cung cấp
- Tác giả cho rằng metric này không phải là metric tốt cho Nanite, và các vertex attribute khác cũng nên được đưa vào hàm
- Cần có thể gán weight cho từng attribute
- Normal trên khuôn mặt Jinx là vấn đề lớn
- Tài liệu tham khảo:
Vì sao software rasterizer không xuất texture
- Trong hardware rasterizer, có thể ghi đồng thời depth texture, color và normal tùy theo kết quả depth test
- Trong software rasterizer, nếu nhiều thread ghi vào cùng một pixel sẽ phát sinh race condition
- Cách giải quyết phổ biến là visibility buffer
- Xuất
sceneUniqueTriangleIdcủa tam giác gần nhất cho mỗi pixel - Kết hợp nó với depth 32-bit để tạo thành giá trị 64-bit và dùng atomic operation 64-bit
- Ở một pass riêng, rasterize lại tam giác, tính barycentric coordinates rồi thực hiện shading
- Xuất
- WebGPU không có 64-bit atomics nên không thể dùng cách này
- Mục tiêu của dự án này là cho thấy software rasterization hoạt động được; vì vậy mô hình được software rasterize ở nền có màu trắng và chỉ cung cấp shading ở mức hợp lý
Nhận định về việc tự triển khai Nanite
- Câu trả lời đơn giản nhất là dùng UE5
- Nếu muốn đưa công nghệ này vào một engine hiện có, trước hết cần triển khai graphics pipeline dựa trên compute và GPU-driven rendering pipeline
- Các vấn đề như multi-step culling, quản lý scene/world chunk và animated meshes sẽ xuất hiện trước
- Trình tự được đề xuất là ổn định các bước này, sau đó thử software rasterizer, rồi mới thêm công nghệ kiểu Nanite
- Trong toy renderer, meshlet hierarchy cơ bản có thể là dự án cuối tuần, nhưng triển khai thực tế phải xử lý các vấn đề về simplification và error metric
Công cụ và tài liệu tham khảo đã dùng
- meshoptimizer là nền tảng cốt lõi của phần triển khai dự án
- Các phiên bản meshoptimizer mới hơn có
meshopt_SimplifySparsedành cho clone Nanite - Dự án không cập nhật lên phiên bản đó để giữ nguyên trạng thái đã thử nghiệm trong quá trình phát triển
- Các phiên bản meshoptimizer mới hơn có
- Đã sử dụng METIS
- Emscripten được dùng để chạy meshoptimizer và METIS trong trình duyệt
- Mô hình Jinx dùng Arcane - Jinx trên Sketchfab, đồng thời đã thực hiện gộp texture, điều chỉnh UV và loại bỏ vũ khí
1 bình luận
Ý kiến Hacker News
Ồ, hay đấy. Xem như đã có một triển khai bên thứ ba cho việc phát lại Nanite.
Nanite biểu diễn mesh đồ họa rất thông minh. Nó không phải cây mà là đồ thị có hướng không chu trình nên phần lặp lại không bị sao chép mà trở thành liên kết, mesh có thể chia sẻ submesh và các submesh đó cũng có thể tiếp tục được chia sẻ. Nó cũng hỗ trợ mức độ chi tiết (LOD) bên trong mesh, nên khi submesh đủ nhỏ thì sẽ bị lược bỏ.
Nhờ vậy có thể xử lý lượng nội dung lặp lại rất lớn với dữ liệu hữu hạn và thời gian render nhanh. Ý tưởng cốt lõi là số pixel trên màn hình là hữu hạn, nên khối lượng công việc render thực sự cần thiết cũng có một giới hạn trên.
Video SIGGRAPH do một người bên Epic giải thích rất hay. Thiết kế GPU hiện tại không thực sự phù hợp với Nanite, nên nếu muốn chuyển thêm nhiều xử lý sang GPU thì sẽ cần các phép toán phần cứng mới. Trong bối cảnh Nvidia đang mải mê với thị trường AI, khó nói liệu thay đổi đó có xảy ra hay không.
Cách này chỉ phát huy hiệu quả khi cảnh có nhiều instancing. Nó rất hợp với các game AAA tạo nội dung rộng lớn bằng cách tái sử dụng một số lượng đối tượng hạn chế, như sảnh tượng giống hệt nhau trong demo Unreal Engine. Nếu xem video Cyberpunk 2077 và để ý lan can cùng các đống rác, bạn sẽ thấy cùng một số thứ cứ lặp đi lặp lại trong những ngữ cảnh hoàn toàn khác nhau.
Việc tạo mesh Nanite khá phức tạp vì có nhiều offset liên kết nội bộ, và từ trước đến nay chỉ Unreal Engine editor mới xử lý được. Giờ phần phát lại đã thành mã nguồn mở, có khả năng sẽ có ai đó làm luôn công cụ tạo nội dung.
Tuy vậy, các offset nội bộ của định dạng này có thể trở thành bề mặt tấn công, và có vẻ cũng có thể bị lợi dụng bằng nội dung bị chỉnh sửa như các file Microsoft Word .doc được tạo ác ý.
DAG được tạo động dựa trên dữ liệu đỉnh, không liên quan tới cách nghệ sĩ cấu trúc submesh. Nó cũng không phải kiểu “phần lặp lại trở thành liên kết”.
Ngoài ra, kết quả cắt đồ thị khác nhau theo từng instance của đối tượng nên không thể dùng instancing truyền thống, vì vậy tôi không hiểu tại sao lại cho rằng phải có nhiều instancing trong cảnh thì mới hiệu quả.
Khi ấy tôi đã tiến khá xa với một thứ tương tự Nanite, gọi là compressed meshes. Đó đúng kiểu sự tự phụ kỹ thuật đi sai hướng.
Công việc ban đầu trông rất hứa hẹn, nhưng càng đào sâu thì toàn bộ hệ thống càng trở nên phức tạp. Phải xây cả pipeline tạo asset, và quy mô đó quá lớn để có thể hoàn thành đúng thời gian mà vẫn cho ra kết quả đẹp mắt mà không làm nổ bộ nhớ.
Tôi đã làm được tới mức nhìn như đang render các mesh rất lớn với mức độ chi tiết phân tầng, nhưng nó cực chậm và còn ép GPU làm việc quá sức; nếu không đạt được độ chính xác subpixel thì hình ảnh trông rất tệ. Đây là một thử nghiệm thú vị, nhưng phần cứng lúc đó quá đuối và với một người làm thì bài toán cũng quá lớn.
Khi Epic công bố Nanite, tôi thực sự kinh ngạc. Họ đã làm được điều mà tôi không làm nổi, theo cách còn vượt xa mức tốt nhất tôi từng hình dung. Đây là một trong số ít công nghệ mà khi ra mắt không phải cường điệu mà là lời giải thực sự, một viên ngọc kỹ thuật của thế giới đồ họa hiện đại. Nếu Epic là công ty niêm yết, tôi thậm chí đã nghĩ tới việc rót một khoản tiền khá lớn chỉ vì công nghệ Nanite.
Một video giới thiệu ngắn ở mức khái quát cũng khá ổn: "What is virtualized micropolygon geometry? An explainer on Nanite": https://www.youtube.com/watch?v=-50MJf7hyOw
Cũng có một bài viết đào sâu kỹ thuật do một trong những tác giả của tính năng này viết: https://jms55.github.io/posts/2024-06-09-virtual-geometry-be...
Theo cách tôi hiểu, logic của Nanite là giữ độ chính xác của mesh vào khoảng mức chính xác 1 pixel. Ví dụ, nếu sai số sau phép chiếu phối cảnh chỉ khoảng nửa pixel, thì có thể dùng một mesh ít chi tiết hơn với tọa độ đã được làm tròn xuống cỡ 10 bit.
Tôi nhớ mang máng lượng tử hóa đóng hai vai trò. Nó không chỉ giảm kích thước lưu trữ dữ liệu mà còn giúp tạo mức độ chi tiết bằng cách snap các đỉnh về cùng một vị trí trong không gian, rồi sau đó có thể loại bỏ phần trùng lặp.
Đã được nhắc vài lần trong thread này, nhưng Bevy cũng có một triển khai ý tưởng Nanite. Đôi khi nó được gọi là virtual geometry. Tôi là tác giả của nó nên có thể trả lời câu hỏi :)
Scthe đã làm rất tốt với dự án này. Chúng tôi đã cùng trao đổi về nhiều phần trong quá trình thực hiện, và dựa trên kinh nghiệm đó, mã Bevy cũng đã được cải thiện: https://github.com/bevyengine/bevy/pull/15023
Luôn vui khi thấy có thêm nhiều người bước vào lĩnh vực này. Nanite thực sự có rất nhiều ý tưởng hay.
Bản demo có dùng chuỗi user agent để xác định khả năng tương thích không? Điều đó không ổn. Tính tương thích tính năng nên được đánh giá theo từng trường hợp bằng cách trực tiếp phát hiện hoặc thử sử dụng chính tính năng đó
Tôi dùng Chromium chứ không phải Chrome, và cũng luôn dùng WebGPU, nhưng bản demo lại bảo tôi dùng Chrome. Về mặt đạo đức tôi không thể làm thế được. Tôi rất muốn thử bản demo này, trông như một dự án đã được đầu tư rất nhiều công sức
Khi tự xây dựng framework component cho trình duyệt, tôi thường phải dựa vào browser sniffing vì nhiều khi không thể phát hiện được. Trong mã của Modernizr có rất nhiều mẹo rất thông minh để phát hiện tính năng, đôi khi cũng là những mẹo cực kỳ lộn xộn. Đã có một khối lượng công việc khổng lồ để tạo ra mã phát hiện đáng tin cậy, và việc phát hiện thường cũng được thực hiện thông qua các tác dụng phụ
Tôi đoán rằng việc phát hiện tính năng Web3D không hề đơn giản. Tìm nhanh cũng không thấy thư viện phát hiện tính năng Web3D nào thật sự rõ ràng
Một phần mã phát hiện hỗ trợ
:checkedcủa Modernizr trông như thế này:Modernizr.addTest('checked', function(){
return Modernizr.testStyles('#modernizr input {width:100px} #modernizr :checked {width:200px;display:block}', function(elem, rule){
Bạn đã bật quyền WebGL cho trang đó trong phần cài đặt trang web chưa? Hình như ở chỗ tôi nó mặc định bị tắt
WebGPU error [frame][validation]: Fill size (7160950) is not a multiple of 4 bytes.
Đây là luận án tiến sĩ năm 2009 khá ít được biết đến của Federico Ponchio, người đã phát minh ra thuật toán đơn giản hóa mesh động làm nền tảng cho Nanite. Cũng có rất nhiều hình minh họa
https://vcg.isti.cnr.it/~ponchio/download/ponchio_phd.pdf dài 107 trang
Việc nó hoạt động được ở một mức độ nào đó là rất ấn tượng, nhưng vì WebGPU không có atomic 64-bit nên đã phải chấp nhận những đánh đổi khá thô
Hy vọng một ngày nào đó nó sẽ được bổ sung dưới dạng extension tùy chọn. Ít nhất trên phần cứng cấp desktop thì hỗ trợ phần cứng gần như đã phổ biến. AMD và Nvidia đã có từ lâu, còn Apple hỗ trợ từ M3
Nó báo iPhone 12 Pro Max không có WebGPU, nhưng khi tôi bật trong tính năng thử nghiệm thì trang demo WebGPU khác[1] lại chạy được. Có ai chạy cái này thành công trên iPhone chưa? Sẽ tốt hơn nếu ứng dụng web cho biết chi tiết hơn là phần nào đã thất bại
[1] https://webgpu.github.io/webgpu-samples/?sample=texturedCube
WebGPU error [init][validation]: 6 errors generated while compiling the shader: 50:22: unresolved call target 'pack4x8snorm' 50:9: cannot bitcast from 'â¥' to 'f32' 54:10: unresolved call target 'unpack4x8snorm' 59:22: unresolved call target 'pack4x8unorm' 59:9: cannot bitcast from 'â¥' to 'f32' 63:9: unresolved call target 'unpack4x8unorm'
Tên gọi và mô tả rất dễ gây nhầm lẫn, và còn có vẻ có nguy cơ xâm phạm nhãn hiệu. Trái với tuyên bố, nó hoàn toàn không liên quan đến Nanite thật của UE5, mà có vẻ chỉ là một người không liên quan tới UE5 đã tự triển khai thứ gì đó tương tự
Bevy Virtual Geometry cũng cung cấp tính năng tương tự. Nó được viết bằng Rust và tích hợp vào game engine nên có khả năng hữu ích hơn nhiều: https://jms55.github.io/posts/2024-06-09-virtual-geometry-be...
Nếu tôi nói mình đã “triển khai GPT-3 của OpenAI bằng JS”, bạn sẽ hiểu là tôi lấy kiến trúc trong whitepaper và triển khai lại nó
Đây thực ra không phải là UE5 Nanite chạy trên WebGPU. Đây là một bản triển khai độc lập các ý tưởng tương tự Nanite
Kỹ thuật này đang bắt đầu xuất hiện ở nhiều nơi. Đúng là Nanite đã khiến ý tưởng đó trở nên nổi tiếng, nhưng Nanite không phải tên của kỹ thuật, mà là tên của một bản triển khai cụ thể
Tôi tò mò không biết các engine khác đang ở mức nào về hệ thống mức độ chi tiết và các hệ thống tương tự
Godot có tính năng mức độ chi tiết tự động, và bản thân nó trông khá ổn: https://docs.godotengine.org/en/stable/tutorials/3d/mesh_lod...
Unity cũng có hệ thống mức độ chi tiết, nhưng so với độ phổ biến của engine thì bạn vẫn phải tự tạo các model mức độ chi tiết, trừ khi tìm plugin trên asset store: https://docs.unity3d.com/Manual/LevelOfDetail.html
Tôi cũng đã thấy một cách tiếp cận thú vị ở một engine ít được biết đến hơn là NeoAxis: https://www.neoaxis.com/docs/html/NeoAxis_Levels.htm tuy nhiên trên chiếc RX580 cũ của tôi thì hiệu năng rất tệ, còn trên A580 hiện tại thì tôi vẫn chưa thử
Theo tôi thấy, về khả năng đưa nhiều thứ lên màn hình thì Unreal đang vượt khá xa các đối thủ. Nhược điểm là các artist sẽ muốn đưa asset chất lượng cao hơn vào game, nên dung lượng cài đặt có thể phình ra rất nhiều
Chi phí hiệu năng cũng lớn. Nanite hay virtual geometry không thực sự hợp với GPU hiện đại. Nếu tôi nhớ không nhầm thì tốc độ fillrate tối đa chỉ khoảng 1/4. Lý do là rasterization trên GPU không hoạt động theo từng pixel như shader, mà theo từng quad 2x2
Mỗi khi nhìn thấy một cảnh render có quá nhiều hình học tĩnh lặp đi lặp lại như thế này, tôi lại nhớ đến giọng nói khó chịu trong mấy video vaporware ngày xưa từng thao thao về “chi tiết không giới hạn”
Nanite, không giống thứ cũ kỹ đó, có vẻ như thực sự đã giải quyết được vấn đề ấy. Tôi nhớ mang máng là bên đó từng nói họ dùng thứ gì đó như octree
Có tin đồn trên mạng nói họ dùng octree, nhưng các video sau này của Euclidean đã thẳng thừng phủ nhận điều đó