1 điểm bởi GN⁺ 2024-05-25 | 1 bình luận | Chia sẻ qua WhatsApp
  • Daniel Schroeder đang phát triển một trình kết xuất thời gian thực mở rộng cảm giác bề mặt dạng pixel của game 3D thập niên 90 thành chi tiết bề mặt voxel nhỏ, trong đó tài sản đầu vào sử dụng mesh tam giác low-poly và texture quen thuộc
  • Thay vì biến toàn bộ cảnh thành lưới voxel, anh dùng displacement map để chỉ khiến bề mặt trông như voxel, hướng tới phong cách hình ảnh phù hợp với các môi trường tĩnh kiểu Doom, Quake, Duke Nukem
  • CPU chuyển đổi mesh tam giác và thông tin displacement có giới hạn thành dữ liệu hình học cho GPU, đồng thời tiền xử lý texture; còn việc render từng khung hình gần như do GPU xử lý độc lập
  • Bản demo cho thấy thời gian khung hình 4~9ms ở 1440p trên Radeon RX 5700 XT, và ở 800p trên Steam Deck OLED đạt hơn 60FPS cùng 90FPS khóa cứng ở nhiều đoạn
  • Vì môi trường vẫn có thể được xử lý như mesh tam giác, va chạm, bộ điều khiển nhân vật và tìm đường có thể giải quyết bằng thư viện vật lý hiện có và xử lý dựa trên mesh, chỉ một số hệ thống cần nhận biết hình học chi tiết kiểu voxel

Mở rộng mỹ học 3D thập niên 90 bằng bề mặt voxel

  • Mục tiêu là giữ nguyên hình học môi trường đơn giản và ranh giới texture sắc nét của các game 3D cổ điển thập niên 90, đồng thời thêm chi tiết 3D dạng khối lên bề mặt
  • Các game 3D đầu đến giữa thập niên 90 như Doom, Quake, Duke Nukem đã ảnh hưởng lớn cả về công nghệ lẫn gameplay, và gần đây chính các giới hạn hình ảnh thời đó lại được xem là sức hút retro
  • Điểm khởi đầu là câu hỏi: “Nếu tạo chi tiết bề mặt bằng voxel thay vì pixel thì sao?”
    • Ví dụ, một bức tường đá cuội có thể vẫn giữ cảm giác pixel hóa khi nhìn gần nhưng đồng thời có chiều sâu hình học
  • Kết quả được thiết kế để nằm giữa ngoại hình của game thập niên 90 và cách thể hiện hiện đại hơn

Hạn chế của cách làm voxel thông thường

  • Voxel mesh thông thường là một lưới 3 chiều biểu diễn việc mỗi ô lập phương được lấp đầy hay để trống
    • Có thể áp texture lên các voxel lớn như trong Minecraft
    • Cũng có thể dùng voxel nhỏ và đơn sắc như trong Teardown
  • Để tạo môi trường dựa trên voxel, cần đặt toàn bộ hình học lên một lưới dùng chung hoặc đặt nhiều voxel mesh độc lập trong cùng một không gian
  • Có các công cụ để trực tiếp tạo hình học voxel, nhưng quy trình làm nội dung thường mất nhiều thời gian và trong nhiều trường hợp bị giới hạn ở các mesh nhỏ
  • Có thể tạo các khối xây dựng như tường hay sàn dạng tile để lắp thành cấu trúc lớn, nhưng cách này hợp với công trình thẳng hàng theo lưới hơn là địa hình tự do
  • Sinh thủ tục hữu ích cho môi trường tự nhiên và việc kết hợp các khối xây dựng, nhưng cũng có khó khăn riêng và chỉ phù hợp với một số loại game nhất định
  • Cũng có thể rasterize mesh tam giác hiện có thành lưới voxel, nhưng khi hình học kết quả bị đặt lên một lưới voxel duy nhất, có thể xuất hiện kết quả thẩm mỹ không mong muốn
    • Các mặt thẳng hàng theo trục có thể trông như những tấm voxel phẳng
    • Các mặt nghiêng 45 độ có thể trông như cầu thang
  • Khi biểu diễn chính thức của cảnh là voxel, không chỉ render mà cả logic game như vật lý, bộ điều khiển nhân vật, tìm đường cho NPC cũng có thể phải hoạt động ở cấp độ voxel
  • Đổi lại, voxel mesh có ưu điểm là dễ thêm hoặc xóa hình học, như trong Minecraft và Teardown

Giới hạn của displacement thông thường

  • Displacement mapping dùng displacement map cùng với texture để xác định mỗi pixel của texture sẽ dịch chuyển bao nhiêu vào trong hoặc ra ngoài so với bề mặt mesh
  • Phần mềm dựng hình 3D có thể chia nhỏ mesh rồi di chuyển các đỉnh mới để biến displacement thành hình học thật
    • Cách này cũng ảnh hưởng đến silhouette của vật thể
    • Số polygon của mesh kết quả tăng mạnh
    • Mesh đầu vào có cạnh hoặc góc cứng cần được chỉnh sửa để cho kết quả tốt
  • Trong đồ họa thời gian thực, các hiệu ứng đổ bóng bề mặt như parallax occlusion mapping có thể khiến bề mặt trông như có hình học chi tiết mà không thực sự thay đổi hình dạng
    • Có thể trông rất tốt trên sàn và tường lớn
    • Nhưng ở rìa vật thể, hình học vẫn phẳng nên ảo giác bị phá vỡ
  • shell mapping là một cách tiếp cận trung gian, cho phép thấy displacement ở silhouette của vật thể mà không cần mesh chia cực nhỏ
    • Khó xử lý ở các vùng mà mesh đầu vào có độ cong cao
    • Cũng không dễ để điều chỉnh mesh đầu vào có cạnh hoặc góc cứng cho phù hợp với kỹ thuật này

Cách triển khai: kết hợp voxel và displacement mapping

  • Trình kết xuất này tạo môi trường kiểu game 3D cổ điển bằng mesh tam giác low-poly, định nghĩa chi tiết bề mặt ở cấp voxel bằng displacement map, rồi render sao cho trông như được lắp từ voxel thật
  • Do nhắm tới các môi trường có nhiều cạnh sắc như góc công trình, nên cần kết quả giống voxel cả ở những vùng mà displacement mapping thông thường xử lý kém
  • Bản triển khai hiện tại là một dự án độc lập bằng C++ / Vulkan
  • Hạ tầng thực hiện ba công việc chính
    • Nhận mesh tam giác và lượng thông tin displacement map có giới hạn, rồi chuyển thành dữ liệu hình học để GPU dùng khi vẽ mesh đã biến dạng
      • Quá trình này chạy trên CPU trước khi render từng khung hình
      • Trong game phát hành, có thể bake kết quả ra đĩa
      • Việc chuyển đổi toàn bộ môi trường demo trong video mất 0,5 giây trên một luồng đơn
    • Tiền xử lý texture để tạo thông tin như normal map cần cho lúc render
      • Bản thân công việc này cơ bản nhưng chậm, nên phù hợp để bake
    • Dùng mesh và trạng thái texture đã tạo để vẽ hình học voxel displacement trên GPU
      • CPU hầu như không tham gia theo từng khung hình
  • Hiệu năng đã ở mức đủ thực tế để sử dụng
    • Trên Radeon RX 5700 XT, chuỗi demo được render với thời gian khung hình 4~9ms ở 1440p
    • Tương đương khoảng 250~110FPS
    • Ở độ phân giải gốc 800p của Steam Deck OLED, hệ thống giữ trên 60FPS và nhiều đoạn khóa ở 90FPS

Cách tạo tài sản đồ họa

  • Việc tạo nội dung cần hai loại tài sản: texture và mesh
  • Mỗi texture được xây dựng với albedo map và displacement map
    • Albedo nếu mô phỏng bảng màu giới hạn của game retro sẽ giúp phong cách hình ảnh trở nên thuyết phục hơn
    • Displacement map cung cấp các giá trị độ cao chi tiết, và có thể điều chỉnh tỉ lệ trong trình kết xuất để thay đổi cường độ
    • Sau khi chỉnh tỉ lệ, đơn vị độ cao là bề mặt sẽ dịch chuyển vào trong hay ra ngoài bao nhiêu voxel
  • Trình kết xuất chỉ dịch chuyển theo đơn vị voxel nguyên gần nhất, nhưng giá trị độ cao chính xác vẫn được dùng để tính normal map
    • Các đặc trưng thấp hơn một voxel vẫn có thể ảnh hưởng đến ánh sáng
  • Mesh là mesh tam giác texture mapping low-poly thông thường có shading normal
    • Normal cho biết phần nào là bề mặt cong mượt và phần nào là cạnh sắc
    • Trình kết xuất thực hiện thêm một số xử lý để tạo kết quả tốt ở các cạnh sắc
  • Vì phong cách hình ảnh, hệ thống cố giữ kích thước voxel nhất quán khi texture mapping, nhưng đây không phải điều kiện bắt buộc
  • Có các hạn chế với cấu trúc mesh và texture mapping
    • Một số hạn chế có thể được gỡ bỏ trong tương lai
    • Một số hạn chế không thể tránh do cách trình kết xuất hoạt động
  • Vì tài sản là mesh tam giác chứ không phải biểu diễn voxel chuyên dụng, có thể tạo chúng bằng nhiều công cụ khác nhau
    • Môi trường demo được dựng bằng Blender
    • Định dạng hiện dùng để xuất từ Blender sang demo là file OBJ

Ưu điểm và phạm vi áp dụng trong phát triển game

  • Cách làm này cho phép tạo nội dung bằng workflow quen thuộc thay vì công cụ chỉnh sửa voxel chuyên biệt
  • Việc tạo texture tốt có thể khó, nhưng một khi đã làm xong thì rất dễ tái sử dụng trên nhiều hình học
    • Phần lớn hình học trong demo video dùng một texture khối đá duy nhất với ba màu
  • Môi trường được tạo bằng mesh tam giác và các đặc trưng voxel chỉ là trang trí bề mặt, nên khi thuận tiện vẫn có thể xử lý môi trường như hình học polygon
  • Ứng dụng demo hỗ trợ di chuyển góc nhìn thứ nhất, va chạm, leo cầu thang và va chạm tường
    • Không tự viết engine vật lý hay bộ điều khiển nhân vật
    • Tích hợp Jolt Physics mã nguồn mở
    • Dùng mesh tam giác gốc làm hình học va chạm
  • Di chuyển của kẻ địch và tìm đường cũng có thể được giải quyết dựa trên cùng mesh đó
  • Chỉ một số hệ thống gameplay cần nhận biết voxel
    • Ví dụ, trong game bắn súng góc nhìn thứ nhất, có thể triển khai hàm raycast nhận biết displacement để đạn đi theo đúng hình dạng của hình học đã bị dịch chuyển
  • Nhiều game dựa trên voxel dùng engine riêng vì phải tùy biến nhiều hệ thống game, nhưng với cách tiếp cận này, phần lớn logic ngoài render không cần biết đến chi tiết cấp voxel
  • Hướng đi thực tế nhất là tích hợp kỹ thuật render này vào các engine hiện có

Các bài toán còn lại và bước tiếp theo

  • Bản triển khai hiện tại phù hợp để tạo hình học cấp độ màn chơi, nhưng môi trường game còn cần các yếu tố động như vật thể nhỏ, vật trang trí và kẻ địch
  • Trong tương lai, tác giả dự định bổ sung cách tích hợp các vật thể nhỏ hoặc vật thể có hoạt ảnh vào phong cách đồ họa này
  • Ánh sáng trong demo đã trông khá tốt, nhưng bản triển khai hiện tại vẫn có hạn chế
    • Chỉ hỗ trợ số lượng nhỏ nguồn sáng
    • Chưa có bóng đổ, ambient occlusion hay các tính năng nâng cao hơn
  • Trình kết xuất này nhắm tới môi trường phần lớn tĩnh của đa số game, hơn là hình học cực kỳ động như các game voxel thông thường
    • Tùy nhu cầu của từng ứng dụng cụ thể, vẫn còn nhiều khả năng xử lý ánh sáng khác nhau, bao gồm cả các cách bake
  • Hiện chưa có anti-aliasing, điều này đặc biệt dễ nhận thấy ở các mặt sàn xa
  • Kế hoạch tương lai của dự án và thảo luận dành cho nhà phát triển, studio được tiếp tục trong bài viết thứ hai

1 bình luận

 
GN⁺ 2024-05-25
Ý kiến trên Hacker News
  • Có lẽ vì tôi đủ lớn để còn nhớ thời tải game bằng modem 2400 baud, nên thẩm mỹ này thực sự rất cuốn hút
    Video cũng rất xuất sắc, và cá nhân tôi thấy nó gợi không khí cực mạnh
    Ở những đoạn mái quá thấp, tôi thậm chí còn thấy ngột ngạt và bí bách, còn các hang động nền đá và cát, hay hang có đá, thì thật sự rất đẹp, đến mức khiến tôi muốn chơi một game phiêu lưu kiểu Myst hoặc LucasArts được làm bằng renderer này
    Có vẻ sẽ rất hợp với các chủ đề như thám hiểm hang động hay khai quật khảo cổ

    • Đồng ý. Cá nhân tôi thấy nó gợi cảm giác pixel art/retro còn mạnh hơn cả phong cách Doom/Wolfenstein low-poly
    • Nó khiến tôi tưởng tượng ra một Noita 3D được làm theo thẩm mỹ này
      Để mở rộng engine cát rơi sang 3D, có lẽ cũng có thể dùng thứ gì đó như động lực học hạt mượt
    • Tôi hoàn toàn đồng ý về mặt thẩm mỹ, nhưng so với vẻ ngoài quá ngầu của nó thì cấu trúc kiến trúc lại có phần kỳ cục
      Ở các đoạn trần thấp, những khối treo từ mái xuống trông như đang thách thức các định luật vật lý
  • https://web.archive.org/web/20240524065427/https://blog.dani...
    https://www.youtube.com/watch?v=1xFEbXWstCM

  • Có một hướng tiếp cận khác là Deep Bump. Nó xử lý cùng một vấn đề nhưng theo cách hoàn toàn khác
    Deep Bump là một công cụ học máy tạo ra normal map trông hợp lý từ ảnh texture
    Nó đặc biệt hợp với các texture đá hoặc gạch như loại mà renderer dịch chuyển voxel này dùng, và với texture vải nó cũng nhận diện được ở mức nào đó các nếp gấp, túi và cổ áo để tạo ra các pháp tuyến thể hiện độ sâu
    Với vỏ cây thì tạm ổn, còn với thực vật thì không tốt lắm, có lẽ do ảnh hưởng từ tập dữ liệu huấn luyện
    Nếu muốn hiện đại hóa các game kiểu Doom/Wolfenstein thì đã có sẵn một công cụ mã nguồn mở khá hữu ích
    [1] https://github.com/HugoTini/DeepBump

    • Nếu đọc kỹ bài blog thì đó là một mô hình suy luận normal map từ texture, chứ không phải một cách mới để render hình học
      Bài này gần hơn với việc xử lý displacement map dưới dạng biểu diễn nhỏ dựa trên voxel, còn các công cụ như Deep Bump có lẽ chỉ có thể dùng bổ trợ để tạo texture asset cho hệ thống đang được nói tới ở đây
    • Như bài viết cũng nói, normal map không phải lúc nào cũng “hoạt động”
      Vì nó không thực sự thay đổi hình học mà chỉ thay đổi ảo giác về ánh sáng và khối, nên khi nhìn ở mép mesh thì displacement vẫn là lựa chọn chất lượng cao hơn
      Dù vậy, có thể DeepBump dùng được để trích xuất height map một chiều cho displacement truyền thống, tức là map chỉ có độ cao thay vì displacement vector 3D đầy đủ
  • Trông rất hay, nhưng tôi tò mò không biết cách tiếp cận này hợp với mô hình 3D có hoạt ảnh đến mức nào
    Dù tốt thì có lẽ nó cũng sẽ trông giống kiểu mod “Voxel Doom” của Doom
    [1] https://media.moddb.com/cache/images/mods/1/55/54112/thumb_6...
    [2] https://media.moddb.com/cache/images/mods/1/55/54112/thumb_6...

    • Bài viết có chú thích về Voxel Doom, nhưng nội dung là về cách Voxel Doom xử lý môi trường hơn là quái vật
      “Giờ khi đã giải thích toàn bộ bối cảnh này, tôi muốn gửi lời tán dương tới mod Voxel Doom cho Doom cổ điển. Tác giả mod đã thay thế quái vật và các sprite khác trong game bằng voxel mesh để tăng chiều sâu, và đó thực sự là một công việc rất ấn tượng. Sau đó, vào cuối năm 2022, anh ấy bắt đầu thử nghiệm parallax mapping để thêm chi tiết voxel cho hình học của màn chơi. Theo tôi phần này trông không được đẹp lắm, không phải vì artwork của tác giả mà vì các giới hạn căn bản nảy sinh khi render bằng parallax mapping. Mod đó không phải nguồn cảm hứng cho dự án của tôi. Tôi đã làm việc này từ trước rồi. Nhưng việc thấy mod đó nhận được phản hồi tốt trên mạng đã tiếp thêm rất nhiều động lực để tôi tiếp tục công việc của mình. ↩”
      Cách tiếp cận này dường như cũng hỗ trợ cả những thứ như cửa có hoạt ảnh, nên nếu kết hợp mesh với texture flipbook thì có lẽ cũng dùng được cho các quái vật trông giống Doom gốc
      Tuy vậy, các vùng có độ cong sắc có lẽ sẽ là nơi shell mapping xuất hiện artifact nặng nhất, và bài viết cũng nhắc tới giới hạn của việc mesh hóa level nên cũng chưa chắc
  • Nó trông khá giống thứ Notch đang làm. Xem feed Twitter của anh ấy thì thấy anh ấy cũng đang làm một kiểu render voxel khác
    Tuy nhiên, cái này dùng C++/Vulkan và trông thực sự rất ấn tượng

  • Tôi tò mò cách tiếp cận này so với Unreal Engine 5 Nanite như thế nào. Có lẽ Unreal Engine cũng đang làm điều gì đó tương tự
    Tôi nhớ một trong những động cơ dùng voxel trong các game cũ, ví dụ như Comanche[1], là vì nó cho phép tạo ra địa hình phức tạp trông khá ổn, vốn sẽ tốn kém hơn trên phần cứng tương tự nếu dựng bằng mesh tam giác
    Tác giả bài viết nhắc tới 110FPS trên RX 5700 XT, nhưng tôi không rõ mức đó tương quan ra sao khi so với các cách tiếp cận khác
    [1] https://en.wikipedia.org/wiki/Comanche_(video_game_series)

    • Bài gốc không giải thích chi tiết mesh dùng lúc chạy nên khó khẳng định, nhưng tôi đoán nó sẽ khá khác Nanite
      Nanite giả định các đối tượng được tạo với số đa giác rất cao, rồi stream các chunk đã được đơn giản hóa để các tam giác được render không nhỏ hơn pixel
      Vì nó cho phép hình học trở nên cực kỳ chi tiết một cách tự nhiên, displacement map phần nào trở nên dư thừa, và không có nhiều lý do để phải xử lý nó bằng texture map
      Tất nhiên địa hình là một trường hợp riêng, nhưng đó là ca đặc biệt
      Cách trong bài này có vẻ dùng displacement và mesh low-poly để tạo ra hình học high-poly nhưng đã được “voxel hóa” khi nạp dữ liệu
  • Theo tôi nhớ thì Comanche đã dùng cách tiếp cận kiểu ray tracing cho việc kết xuất địa hình[1]
    Không phải voxel thật sự mà là một height map 2D được lấy mẫu
    Nó được gọi là “VoxelSpace” nên cũng dễ gây nhầm lẫn
    [1] https://github.com/s-macke/VoxelSpace

    • Tôi đoán đây либо chính xác là kỹ thuật đã dùng trong game Comanche, hoặc ít nhất là một cách có thể cho ra cùng kết quả
      Trái với niềm tin phổ biến, các game đó không dùng voxel 3D thật sự mà vẽ height map lưu giá trị màu và độ cao trong texture địa hình bằng ray marching
      Nếu ray march từ shader vào texture thì có thể tái hiện cùng diện mạo đó, và có lẽ sẽ trông rất giống kết quả trong bài blog
    • Về cơ bản thì gần như không liên quan. Ở đây có vẻ là đang tạo chi tiết mesh voxel bằng geometry shader, và có lẽ còn tối ưu thêm vài bước chi tiết
      Trong khi đó, Nanite là kỹ thuật kết xuất do GPU điều phối để điều chỉnh mật độ tam giác theo chất lượng mục tiêu
      Nanite cũng có thể dùng displacement map và tessellation, nhưng nó đi theo một hướng riêng, không nhất thiết hiệu quả hơn việc đưa thẳng tài sản đa giác cao vào để render
  • Lúc nào cũng tốt khi thấy những phương pháp mới trong lĩnh vực voxel
    Tuy vậy, hơi tiếc là bài viết đang nói lẫn lộn giữa voxel và một kỹ thuật kết xuất cụ thể
    Voxel đơn giản chỉ là việc dùng một lưới 3D, nhưng ở phần giữa có vẻ tác giả đang đồng nhất việc dùng voxel với kiểu render dạng khối lập phương, thường được gọi là blocky renderer kiểu Minecraft
    Tác giả cũng nói rằng có thể mang hình học tam giác vào và dùng trực tiếp trong engine, nhưng dường như quên mất rằng với blocky hoặc thực ra gần như bất kỳ quy trình render nào cũng có thể làm tương tự
    Đây cũng chính là cách các plugin kết xuất voxel thông thường dùng phong cách khác nhận được hỗ trợ hạng nhất trong các engine hiện có

  • Giá như cái này là mã nguồn mở. Thật sự rất mong là vậy

  • Thích thật sự. Nó làm tôi nhớ đến Ultima Underworld

  • Đây nên là tương lai của việc hiện đại hóa game 3D retro. Thực sự rất đẹp