Khám phá tiềm năng của WebGL qua khung cảnh vô tận được tạo ra theo quy trình trong trò chơi lái xe thông thường này.
Đường chậm là một trò chơi lái xe phổ thông tập trung vào các phong cảnh được tạo theo quy trình liên tục, tất cả đều được lưu trữ trong trình duyệt dưới dạng ứng dụng WebGL. Đối với nhiều người, trải nghiệm chuyên sâu như vậy có vẻ như không phù hợp trong bối cảnh hạn chế của trình duyệt — và thực sự, việc điều chỉnh thái độ đó là một trong những mục tiêu của tôi với dự án này. Trong bài viết này, tôi sẽ phân tích một số kỹ thuật mà tôi đã sử dụng để xử lý rào cản hiệu suất trong sứ mệnh của mình nhằm làm nổi bật tiềm năng 3D bị bỏ qua trên web.
Phát triển 3D trong trình duyệt
Sau khi phát hành Đường chậm, tôi đã thấy một nhận xét lặp lại trong phản hồi: "Tôi không biết điều này là có thể thực hiện trong trình duyệt". Nếu bạn chia sẻ quan điểm này, chắc chắn bạn không phải là nhóm thiểu số. Theo khảo sát Trạng thái JS năm 2022, có khoảng 80% nhà phát triển chưa thử nghiệm WebGL. Đối với tôi, tôi cảm thấy thật đáng xấu hổ khi có thể bỏ lỡ rất nhiều tiềm năng, đặc biệt là khi nói đến trò chơi dựa trên trình duyệt. Với đường đi chậm, tôi hy vọng sẽ đưa WebGL được nhiều sự chú ý hơn nữa, và có thể làm giảm số lượng nhà phát triển chần chừ khi sử dụng cụm từ "công cụ phát triển trò chơi JavaScript hiệu suất cao".
WebGL có vẻ bí ẩn và phức tạp đối với nhiều người, nhưng trong những năm gần đây, hệ sinh thái phát triển của WebGL đã hoàn thiện đáng kể thành các công cụ và thư viện có khả năng cao và tiện lợi. Giờ đây, các nhà phát triển giao diện người dùng có thể tích hợp trải nghiệm người dùng 3D vào công việc của mình dễ dàng hơn bao giờ hết, ngay cả khi họ không có kinh nghiệm về đồ hoạ máy tính. Three.js, thư viện WebGL hàng đầu, đóng vai trò là nền tảng cho nhiều nội dung mở rộng, bao gồm cả react-3-fiber giúp đưa các thành phần 3D vào khung React. Hiện cũng có các trình chỉnh sửa trò chơi toàn diện dựa trên nền tảng web, chẳng hạn như Babylon.js hoặc PlayCanvas cung cấp một giao diện quen thuộc và các chuỗi công cụ tích hợp.
Tuy nhiên, dù những thư viện này có lợi ích to lớn nhưng sau cùng, các dự án đầy tham vọng vẫn bị ràng buộc bởi những hạn chế về mặt kỹ thuật. Những người hoài nghi về ý tưởng chơi trò chơi dựa trên trình duyệt có thể nhấn mạnh rằng JavaScript là JavaScript đơn luồng và bị hạn chế về tài nguyên. Tuy nhiên, việc điều hướng đến các giới hạn này sẽ mở ra giá trị ẩn: không có nền tảng nào khác cung cấp khả năng hỗ trợ tiếp cận tức thì cũng như khả năng tương thích hàng loạt mà trình duyệt hỗ trợ. Người dùng trên bất kỳ hệ thống nào hỗ trợ trình duyệt đều có thể bắt đầu chơi chỉ với một cú nhấp chuột mà không cần cài đặt ứng dụng cũng như không cần đăng nhập vào dịch vụ. Đó là chưa kể rằng nhà phát triển tận hưởng sự tiện lợi thanh lịch khi có sẵn khung giao diện người dùng mạnh mẽ để xây dựng giao diện người dùng hoặc xử lý mạng cho chế độ nhiều người chơi. Theo tôi, những giá trị này là yếu tố khiến trình duyệt trở thành một nền tảng tuyệt vời cho cả người chơi lẫn nhà phát triển, và như được minh hoạ bằng đường chậm, các giới hạn về mặt kỹ thuật thường có thể được rút gọn cho sự cố thiết kế.
Đạt được hiệu suất mượt mà trên đường chậm
Vì các yếu tố cốt lõi của Đường chậm liên quan đến chuyển động tốc độ cao và tạo cảnh quan tốn kém, nên nhu cầu về hiệu suất mượt mà càng nhấn mạnh mọi quyết định thiết kế của tôi. Chiến lược chính của tôi là bắt đầu bằng thiết kế lối chơi đơn giản cho phép lấy các đoạn cắt ngắn theo ngữ cảnh trong cấu trúc của công cụ. Nhược điểm, điều này có nghĩa là đánh đổi một số tính năng phải có để phù hợp với chủ nghĩa tối giản nhưng dẫn đến một hệ thống được tối ưu hoá, riêng biệt và hoạt động mượt mà trên nhiều trình duyệt và thiết bị.
Dưới đây là bảng chi tiết các thành phần chính giúp giữ cho Đường chậm nghiêng.
Xây dựng công cụ môi trường xung quanh lối chơi
Là thành phần chính của trò chơi, công cụ tạo môi trường rất tốn kém, có thể chiếm phần lớn ngân sách cho bộ nhớ và điện toán. Bí quyết được áp dụng ở đây là lên lịch và phân phối phép tính phức tạp trong một khoảng thời gian, để không làm gián đoạn tốc độ khung hình khi hiệu suất tăng đột biến.
Môi trường bao gồm các thẻ thông tin có hình dạng khác nhau, có kích thước và độ phân giải khác nhau (được phân loại là "mức độ chi tiết" hoặc LoD) tuỳ thuộc vào mức độ hiển thị của chúng với máy ảnh. Trong các trò chơi thông thường có máy ảnh chuyển động tự do, các LoD khác nhau phải liên tục được tải và huỷ tải để chi tiết hoá môi trường xung quanh người chơi ở bất cứ nơi nào họ có thể đến. Đây có thể là một thao tác tốn kém và lãng phí, đặc biệt là khi môi trường được tạo động. May mắn là quy ước này có thể bị thay đổi hoàn toàn trên Đường chậm nhờ vào kỳ vọng bối cảnh rằng người dùng sẽ ở lại trên đường. Thay vào đó, hình dạng chi tiết cao có thể được dành riêng cho hành lang hẹp ngay bên cạnh tuyến đường.

Chính đường giữa được tạo ra trước khi người chơi đến, cho phép dự đoán chính xác thời điểm và vị trí cần có thông tin chi tiết về môi trường. Kết quả là một hệ thống tinh gọn có thể chủ động lên lịch cho công việc tốn kém, chỉ tạo số tiền tối thiểu cần thiết tại mỗi thời điểm mà không lãng phí công sức vào những chi tiết không xem được. Kỹ thuật này chỉ có thể thực hiện được vì đường là một đường dẫn duy nhất, không phân nhánh. Một ví dụ điển hình về việc đánh đổi lối chơi sao cho phù hợp với các lối cắt ngắn trong cấu trúc.

Khéo léo với các định luật vật lý
Thứ hai sau nhu cầu tính toán của công cụ môi trường là mô phỏng vật lý. Đường chậm sử dụng một công cụ vật lý tối thiểu, tuỳ chỉnh sử dụng mọi đoạn cắt ngắn có sẵn.
Điểm chính ở đây là tránh mô phỏng quá nhiều đối tượng ngay từ đầu — dựa vào ngữ cảnh zen tối thiểu bằng cách giảm giá những thứ như va chạm động và đối tượng phá huỷ. Giả định rằng xe sẽ ở nguyên trên đường có nghĩa là bạn có thể bỏ qua việc va chạm với các vật thể trên đường một cách hợp lý. Ngoài ra, việc mã hoá đường dưới dạng đường giữa thưa thớt cho phép các thủ thuật tinh tế để phát hiện va chạm nhanh với mặt đường và rào chắn, tất cả đều dựa trên việc kiểm tra khoảng cách đến tâm đường. Việc lái xe địa hình sẽ tốn kém hơn, nhưng đây là một ví dụ khác về sự đánh đổi hợp lý phù hợp với bối cảnh của lối chơi.
Quản lý mức sử dụng bộ nhớ
Là một tài nguyên khác do trình duyệt hạn chế, điều quan trọng là bạn phải quản lý bộ nhớ cẩn thận, mặc dù trên thực tế, JavaScript là nguồn thu gom rác. Bạn có thể dễ dàng bỏ qua, nhưng việc khai báo ngay cả một lượng nhỏ bộ nhớ mới trong một vòng lặp trò chơi cũng có thể dẫn đến vấn đề nghiêm trọng khi chạy ở tần số 60 Hz. Không chỉ tiêu tốn tài nguyên của người dùng trong bối cảnh họ có khả năng làm nhiều việc cùng lúc, các bộ sưu tập rác lớn có thể mất một vài khung hình để hoàn thành và gây ra tình trạng gián đoạn đáng kể. Để tránh điều này, bộ nhớ lặp có thể được phân bổ trước trong các biến lớp khi khởi động và tái chế trong mỗi khung.

Một điều quan trọng nữa là các cấu trúc dữ liệu nặng hơn, chẳng hạn như hình học và vùng đệm dữ liệu liên quan, phải được quản lý một cách kinh tế. Trong một trò chơi được tạo vô hạn như Đường chậm, hầu hết các hình học đều tồn tại trên một loại máy chạy bộ - một khi một mảnh ghép cũ rơi vào khoảng cách xa, cấu trúc dữ liệu của nó có thể được lưu trữ và tái chế cho một khu vực sắp tới của thế giới, một mẫu thiết kế được gọi là gộp nhóm đối tượng.
Các phương pháp này giúp ưu tiên thực thi tinh gọn, nhưng vẫn đảm bảo sự đơn giản trong việc sử dụng mã. Trong các ngữ cảnh hiệu suất cao, bạn cần lưu ý đến cách các tính năng tiện lợi đôi khi mượn từ ứng dụng để mang lại lợi ích cho nhà phát triển. Chẳng hạn, các phương thức như Object.keys()
hoặc Array.map()
cực kỳ hữu ích, nhưng dễ bỏ qua rằng mỗi phương thức sẽ tạo một mảng mới cho giá trị trả về của chúng. Việc hiểu được hoạt động bên trong của các hộp đen như vậy có thể giúp bạn thắt chặt mã và tránh các trường hợp truy cập lén lút.
Giảm thời gian tải bằng các thành phần được tạo theo quy trình
Mặc dù hiệu suất thời gian chạy phải là mối quan tâm chính của các nhà phát triển trò chơi, nhưng các tiên đề thông thường liên quan đến thời gian tải trang web ban đầu vẫn đúng. Người dùng có thể dễ chịu trách nhiệm hơn khi cố ý truy cập vào nội dung nặng, nhưng thời gian tải lâu vẫn có thể gây bất lợi cho trải nghiệm, nếu không muốn giữ chân người dùng. Trò chơi thường yêu cầu các thành phần lớn ở dạng hoạ tiết, âm thanh và mô hình 3D và tối thiểu, các thành phần này phải được nén cẩn thận ở bất cứ vị trí nào có thể lưu giữ được chi tiết.
Ngoài ra, việc tạo tài sản trên khách hàng theo quy trình có thể giúp tránh việc chuyển giao mất nhiều thời gian ngay từ đầu. Đây là lợi ích rất lớn cho người dùng trên các kết nối chậm, đồng thời giúp nhà phát triển có nhiều quyền kiểm soát hơn đối với cách tạo trò chơi, không chỉ ở bước tải ban đầu mà còn đối với việc điều chỉnh mức độ chi tiết cho các chế độ cài đặt chất lượng khác nhau.
Hầu hết hình dạng trong Đường chậm được tạo theo quy trình và đơn giản, với các chương trình đổ bóng tùy chỉnh kết hợp nhiều hoạ tiết để mang lại chi tiết. Hạn chế là các hoạ tiết này có thể chứa các thành phần nặng, mặc dù vẫn còn nhiều cơ hội để tiết kiệm hơn ở đây, với các phương thức như tạo hoạ tiết ngẫu nhiên có thể đạt được chi tiết hơn từ các hoạ tiết nguồn nhỏ. Ở cấp độ cao nhất, bạn cũng có thể tạo kết cấu hoàn toàn trên ứng dụng bằng các công cụ như texgen.js. Điều này thậm chí cũng đúng đối với âm thanh, với Web Audio API cho phép tạo âm thanh bằng các nút âm thanh.
Với lợi ích của các thành phần quy trình, việc tạo môi trường ban đầu chỉ mất trung bình 3,2 giây. Để tận dụng tối đa kích thước tải xuống phía trước nhỏ, màn hình chờ đơn giản sẽ chào đón khách truy cập mới và trì hoãn việc khởi chạy cảnh tốn kém cho đến sau khi nhấn nút khẳng định. Điều này cũng đóng vai trò như một vùng đệm thuận tiện cho các phiên bị thoát, giảm thiểu việc chuyển đổi lãng phí tài sản được tải động.
Áp dụng phương pháp linh hoạt đối với trường hợp tối ưu hoá trễ
Tôi luôn coi cơ sở mã của Đường chậm là thử nghiệm và do đó, tôi đã áp dụng một phương pháp phát triển cực kỳ linh hoạt. Khi làm việc với một cấu trúc hệ thống phức tạp và phát triển nhanh chóng, khó có thể dự đoán nơi xảy ra nút thắt cổ chai quan trọng. Tập trung vào việc triển khai các tính năng mong muốn một cách nhanh chóng thay vì chỉn chu, sau đó làm việc ngược lại để tối ưu hoá các hệ thống thực sự quan trọng. Trình phân tích hiệu suất trong Công cụ của Chrome cho nhà phát triển là vô giá đối với bước này và đã giúp tôi chẩn đoán một số vấn đề lớn xảy ra với các phiên bản trò chơi cũ. Với tư cách là nhà phát triển, thời gian của bạn là rất quý giá, vì vậy hãy đảm bảo bạn không dành thời gian suy nghĩ về các vấn đề có thể không quan trọng hoặc dư thừa.
Giám sát trải nghiệm người dùng
Mặc dù triển khai tất cả các thủ thuật này, nhưng điều quan trọng là phải đảm bảo trò chơi hoạt động như mong đợi trong tự nhiên. Việc cung cấp nhiều tính năng phần cứng là một khía cạnh quan trọng trong mọi quá trình phát triển trò chơi. Tuy nhiên, các trò chơi trên web có thể nhắm đến một phạm vi rộng hơn nhiều, bao gồm cả máy tính để bàn cao cấp nhất và các thiết bị di động đã qua sử dụng hàng thập kỷ cùng một lúc. Cách đơn giản nhất để tiếp cận vấn đề này là cung cấp các chế độ cài đặt để điều chỉnh những nút thắt cổ chai có nhiều khả năng xảy ra nhất trong cơ sở mã của bạn (cho cả tác vụ cần nhiều GPU và CPU) theo thông tin mà trình phân tích tài nguyên tiết lộ.
Tuy nhiên, việc phân tích tài nguyên trên máy của riêng bạn chỉ có thể xử lý rất nhiều dữ liệu. Vì vậy, bạn nên khép lại vòng hồi tiếp với người dùng theo cách nào đó. Đối với Đường chậm, tôi chạy các phép phân tích đơn giản để báo cáo về hiệu suất cùng với các yếu tố theo bối cảnh như độ phân giải màn hình. Những số liệu phân tích này được gửi đến một phần phụ trợ Nút cơ bản thông qua socket.io, cùng với mọi phản hồi bằng văn bản mà người dùng gửi qua biểu mẫu trong trò chơi. Trong những ngày đầu, các hoạt động phân tích này đã phát hiện nhiều vấn đề quan trọng có thể giảm thiểu bằng những thay đổi đơn giản đối với trải nghiệm người dùng, chẳng hạn như làm nổi bật trình đơn cài đặt khi phát hiện FPS thấp liên tục, hoặc cảnh báo rằng người dùng có thể cần bật tính năng tăng tốc phần cứng nếu hiệu suất đặc biệt kém.
Con đường chậm phía trước
Ngay cả sau khi áp dụng tất cả những biện pháp này, vẫn có một phần đáng kể cơ sở người chơi cần chơi ở chế độ cài đặt thấp hơn — chủ yếu là những người sử dụng thiết bị nhẹ không có GPU. Mặc dù phạm vi của các chế độ cài đặt chất lượng có sẵn giúp phân bổ hiệu suất khá đồng đều, nhưng chỉ 52% người chơi đạt được trên 55 khung hình/giây.

Thật may là vẫn còn nhiều cơ hội để tiết kiệm hiệu suất. Ngoài việc bổ sung các thủ thuật kết xuất khác để giảm nhu cầu GPU, tôi hy vọng sẽ thử nghiệm song song với trình chạy môi trường trong thời gian tới và cuối cùng có thể thấy cần phải kết hợp WASM hoặc WebGPU vào cơ sở mã. Bất kỳ mức trần nào mà tôi có thể giải phóng sẽ tạo ra môi trường phong phú hơn và đa dạng hơn, đây sẽ là mục tiêu lâu dài cho phần còn lại của dự án.
Khi thực hiện các dự án theo sở thích, Đường chậm đã là một cách hoàn hảo để thể hiện các trò chơi trình duyệt phổ biến, hiệu quả và tinh vi một cách đáng kinh ngạc. Nếu tôi đã thành công trong việc xác định mối quan tâm của bạn về WebGL, hãy biết rằng công nghệ Đường chậm là một ví dụ khá nông về khả năng của WebGL. Tôi đặc biệt khuyến khích độc giả khám phá giới thiệu về Three.js và những người quan tâm đến việc phát triển trò chơi trên web nói riêng sẽ được chào mừng đến với cộng đồng tại webgamedev.com.