Bạn vừa bỏ ra số tiền vất vả mới kiếm được để mua trò chơi AAA mới nhất để chơi trên chiếc PC chơi game quý giá của mình. Sau một thời gian dài tải xuống, bạn nhảy thẳng vào trò chơi, chỉ để phải chờ đợi lâu ở menu chính trong khi nó sắp xếp chính nó…
Hoặc có thể nó không. Nhưng bạn thấy mình gặp phải nhiều vấn đề về tốc độ khung hình khi chơi trò chơi. Tuyệt vọng tìm ra giải pháp, bạn lùng sục trên mạng để tìm câu trả lời và bắt gặp một cụm từ thường được lặp đi lặp lại: “biên dịch shader.”
Bạn có muốn biết biên dịch shader là gì, tại sao nó lại cần thiết và tại sao nó lại nhận được báo chí tiêu cực như vậy không? Vâng, đây là bài viết hoàn hảo cho bạn.
Được rồi, vậy shader là gì?
Về cơ bản, shader chỉ là các khối mã. Trong thế giới đồ họa và kết xuất 3D, mỗi chương trình là một chương trình nhỏ được thiết kế để tạo ra một đầu ra rất cụ thể. Điều này có thể là chuyển đổi hình dạng hoặc vị trí của hình tam giác, ánh xạ kết cấu thành hình dạng hoặc tính toán một tập hợp các giá trị cần thiết cho các trình đổ bóng khác.
Khi các API như Direct3D và OpenGL hỗ trợ shader lần đầu tiên, kích thước và phạm vi của chúng rất hạn chế. Ví dụ: khi trình đổ bóng pixel lần đầu tiên xuất hiện trên PC hơn 20 năm trước, chỉ có 4 hướng dẫn liên quan đến kết cấu và 8 hướng dẫn để thực hiện các phép tính.
Ngày nay, trong phiên bản mới nhất của tất cả các shader, thực tế không có giới hạn về số lượng hướng dẫn có thể được đưa vào mã…
Mặc dù các API khác nhau được các nhà phát triển sử dụng có thuật ngữ khác nhau, nhưng có bảy loại trình đổ bóng. Các trình tạo bóng đỉnh, hình học, vỏ và miền đều nhằm quản lý các đỉnh của hình tam giác – tạo và định hình thế giới 3D trước khi nó được tô màu.
Nhiệm vụ này được xử lý bởi pixel shader (và gần đây hơn là ray), xử lý các tính toán liên quan đến ánh sáng và kết cấu. Cuối cùng, các shader tính toán đều nhằm thực hiện xử lý logic và số học cho mục đích chung, thay vì bất kỳ thứ gì dành riêng cho đồ họa.
Các game 3D hiện đại sử dụng hàng nghìn shader để tính toán hình ảnh hiển thị trên màn hình. Một số rất ngắn và đơn giản, một số khác có thể cực kỳ dài và rất phức tạp, hấp thụ tất cả các tài nguyên mà GPU có thể cung cấp cho nó.
Và mỗi trong số chúng phải được xử lý trước khi GPU có thể làm bất cứ điều gì với chúng.
Làm thế nào và khi nào để biên dịch shader
Biên dịch phần mềm là quá trình chuyển đổi mã nguồn thành mã máy thực thi được. Mã nguồn có thể được viết bằng bất kỳ ngôn ngữ lập trình nào, sau đó được chuyển thành mã nhị phân để phần cứng máy tính thực thi.
Trình tạo bóng không khác, chúng được viết bằng một ngôn ngữ nhất định, vì vậy việc tạo chúng và hiểu những gì đang diễn ra sẽ dễ dàng hơn. Một ví dụ về điều này có thể được nhìn thấy bằng cách sử dụng ShaderToy. Để sử dụng phiên bản trực tuyến của công cụ này, mã được viết bằng GLSL (OpenGL Shading Language) và API đồ họa WebGL để dựng hình.
bên trong ví dụ bên dưới, mã được hiển thị là một phần của quy trình cần thiết để tạo bề mặt địa hình nhìn thấy trong hình ảnh cuối cùng — bạn có thể theo dõi cách tất cả kết hợp với nhau bằng cách xem Video này.
Ngay cả khi bạn không biết ý nghĩa của một trong những mã này, điều đó cũng không thành vấn đề – chip đồ họa của bạn cũng vậy. Nó có thể thực hiện tất cả các phép tính, nhưng bạn phải cung cấp cho nó các hướng dẫn ở dạng nhị phân. Mã phải được biên dịch từ WebGL thành hướng dẫn GPU – trong trường hợp bất kỳ thứ gì sử dụng GPU để có kết quả cuối cùng, quá trình biên dịch được thực hiện bởi trình điều khiển GPU, với CPU xử lý khối lượng công việc đó.
Ví dụ ShaderToy này chỉ sử dụng một số ít trình tạo bóng và chỉ một trong số chúng có độ dài hợp lý. Mặc dù vậy, chỉ mất một phần giây để CPU máy tính để bàn trung bình biên dịch tất cả chúng, vì vậy quá trình này được thực hiện một lần khi bạn bắt đầu bản demo.
Tuy nhiên, hãy chọn bất kỳ trò chơi 3D hiện đại nào và đó lại là một câu chuyện hoàn toàn khác. Du hành môi trường, lên cấp hoặc chiến đấu với kẻ thù mới yêu cầu trò chơi tải các bộ tạo bóng mới từ ổ lưu trữ rồi biên dịch chúng.
Các trò chơi trên bảng điều khiển, chẳng hạn như PS5 hoặc Xbox Series, thường có tất cả các trình đổ bóng được biên dịch trước, nhưng không phải lúc nào cũng vậy. Thật vậy, cấu hình phần cứng rất tĩnh – các nhà phát triển tạo một tiêu đề mới cho máy của Sony hoặc Microsoft chỉ cần quản lý một loại GPU và hệ điều hành cũng như trình điều khiển của nó hiếm khi thay đổi.
Tuy nhiên, máy tính để bàn gây đau đầu về vấn đề này, vì có hàng nghìn cách kết hợp có thể có giữa hệ điều hành, trình điều khiển và chip đồ họa. Sẽ không thể biên dịch trước các shader cho tất cả chúng, vì vậy các nhà phát triển sử dụng nhiều cách tiếp cận khác nhau để giải câu đố này.
Các vấn đề với việc biên dịch shader
Một cách tiếp cận phổ biến là chuyển đổi tất cả các shader sẽ được trò chơi sử dụng khi tải – đôi khi trong trình tự khởi động chính, đôi khi trong menu chính hoặc khi tải cấp độ ban đầu.
Nếu một trò chơi chứa hàng chục nghìn trình đổ bóng, việc biên dịch tất cả chúng ngay từ đầu có khả năng khiến thời gian tải đó trở nên quá lâu. Việc quản lý sai thư viện shader khi tạo trò chơi sẽ chỉ làm cho vấn đề này trở nên tồi tệ hơn, vì thời gian và dung lượng lưu trữ sẽ bị lãng phí khi biên dịch thứ gì đó sẽ không bao giờ được sử dụng.
Tuy nhiên, điều này ít nhất có nghĩa là mã shader đã sẵn sàng để trình điều khiển sử dụng, thời điểm công cụ kết xuất của trò chơi gửi lệnh đến GPU. Phương pháp ngược lại với tất cả những điều này là tránh chuyển đổi chúng lúc đầu và chỉ làm mọi thứ khi cần thiết, trong trò chơi.
Điều này rõ ràng sẽ tăng tốc độ tải, nhưng việc biên dịch trong thời gian thực có thể gây treo chuỗi xử lý đồ họa trong khi CPU đang thực hiện quá trình chuyển đổi.
Những điều này thường biểu hiện bằng việc tốc độ khung hình trung bình của trò chơi giảm đột ngột, nhưng rất ngắn. nói lắpvấn đề này có thể bao gồm từ một tiếng nấc đơn lẻ, nhất thời đến một mớ hỗn độn khủng khiếp, giật cục thường xuyên.
Nói lắp trong game không phải là chỉ gây ra bởi quá trình biên dịch shader, vì nhiều khía cạnh của kết xuất có thể dẫn đến, nhưng vấn đề cụ thể này đang trở nên phổ biến hơn.
Thật vậy, xu hướng cho các tựa game AAA là có đồ họa chân thực hơn hoặc ấn tượng hơn về mặt hình ảnh, đặc biệt là trong thể loại thế giới mở phổ biến. Vì vậy, các shader ngày càng dài hơn và phức tạp hơn, cũng như ngày càng nhiều hơn và tất cả những thứ này đều mất nhiều thời gian hơn để biên dịch.
Có nhiều trò chơi áp dụng cách tiếp cận trung gian để biên dịch trình đổ bóng, xử lý những trò chơi chính khi tải hoặc từ menu chính và thực hiện phần còn lại nếu cần. Nhưng bản thân việc thực hiện điều đó trên nền tảng PC đã là một thách thức.
Những người chơi đã quen thuộc với các tựa game được tạo bằng Unreal Engine, đặc biệt là phiên bản 4, sẽ biết rất rõ điều này, mặc dù đây không phải là vấn đề dành riêng cho UE4. Sự ra mắt của các cổng PC của Horizon Zero Dawn và Death Stranding, cả hai đều được thực hiện bằng cách sử dụng chủ sở hữu Công cụ Decimađã bị hủy hoại bởi các báo cáo thường xuyên về việc nói lắp không ngừng, phần lớn trong số đó được cho là do các vấn đề về trình biên dịch shader và được giải quyết trong bản sửa lỗi sau khi ra mắt.
Vậy các nhà phát triển và người chơi có thể làm gì để giảm thiểu vấn đề?
Thật không may cho các game thủ, bạn không thể làm gì nhiều với nó. Vì CPU xử lý các tác vụ biên dịch nên việc giảm thiểu số lượng tác vụ nền có thể hữu ích, cũng như làm giảm chất lượng đồ họa của trò chơi, nhưng đó là tất cả những gì người dùng có thể làm.
Rất ít trò chơi cung cấp tùy chọn để sửa đổi việc xử lý quá trình biên dịch shader. Horizon Zero Dawn đã nói ở trên, với bản vá mới nhất, sẽ thực hiện quá trình biên dịch shader trong menu chính, nhưng cho phép bạn bỏ qua nếu mất quá nhiều thời gian, điều này sẽ xảy ra trên phần cứng cấp thấp.
Một cái gì đó như Di sản Hogwarts gần đây không cung cấp cho bạn tùy chọn như vậy và hầu hết quá trình biên dịch được thực hiện khi trò chơi bắt đầu, trước khi đến menu chính. Không có cách tiếp cận nào có vẻ đặc biệt tối ưu vì cả hai tựa game vẫn sẽ xử lý nhiều shader hơn đáng kể khi bạn chơi.
Các nhà sản xuất GPU cũng đóng một vai trò ở đây, vì phần mềm của họ thực hiện việc biên dịch. Trình điều khiển AMD và Nvidia sẽ lưu trữ trình tạo bóng đã biên dịch của các trò chơi thường chơi trong một thư mục trên ổ lưu trữ chính, nhưng ngay sau khi trò chơi hoặc trình điều khiển được cập nhật, quy trình phải được lặp lại.
Bạn có thể nghĩ rằng những nhà cung cấp này có thể làm nhiều hơn nữa để cải thiện hiệu suất của quá trình biên dịch trình đổ bóng, nhưng ngày nay, nó nhanh hết mức có thể.
Tại thời điểm này, bạn cũng có thể nghĩ rằng một số loại dịch vụ trực tuyến lưu trữ các trình tạo bóng đã biên dịch cho mọi trò chơi, phần cứng và cấu hình trình điều khiển, sẽ rất đáng để sở hữu. Valve cung cấp một thứ như vậy, như một dịch vụ bộ nhớ đệm trong Steam, nhưng chỉ dành cho các trò chơi sử dụng OpenGL hoặc Vulkan. Tuy nhiên, thông thường, bộ đệm vẫn xuất hiện trống.
Cuối cùng, chính các nhà phát triển trò chơi chịu trách nhiệm giảm thiểu tác động của quá trình biên dịch shader. Một số rất giỏi về nó và dường như cố gắng hết sức để giảm thiểu tật nói lắp, trong khi những người khác thì kém siêng năng hơn nhiều (hãy nhìn bạn, FromSoftware).
Hầu hết các nhà phát triển hiểu biết (ví dụ: Infinity Ward, người tạo CoD) sẽ biết cách sử dụng mọi thủ thuật trong sách để ngăn việc chuyển đổi mã làm gián đoạn luồng kết xuất, ẩn mã trong menu, đoạn cắt cảnh, giai đoạn tải ở mức trung bình, v.v.
Có nhiều kinh nghiệm và hiểu các chi tiết tốt hơn của động cơ đang được sử dụng cũng rất cần thiết. Ví dụ: khi tạo trò chơi trong UE4, giao diện bề mặt của từng đối tượng và phần của môi trường được tạo bởi các phần tử được gọi là nguyên vật liệu. Theo mặc định, quá trình tạo của chúng lần lượt tạo ra một loạt trình tạo bóng, nhiều trình tạo bóng trong số đó có thể không cần thiết.
Nếu điều này không được xử lý đúng cách thì vấn đề sẽ chỉ xuất hiện trong quá trình kiểm tra chất lượng/hiệu suất. Tất nhiên, các nhà phát triển phân bổ tiền và thời gian cho những việc như vậy, nhưng nó chỉ đi xa đến mức đó và nếu trò chơi gặp phải nhiều vấn đề khác, việc sửa lỗi nói lắp do quá trình biên dịch shader có thể không được quan tâm đúng mức khi ra mắt.
Các bản vá sau khi phát hành thường cố gắng giảm thiểu những vấn đề này, điều này cho thấy rõ ràng rằng các công ty phát triển đơn giản là không cung cấp cho các phiên bản PC của trò chơi của họ đủ thử nghiệm đảm bảo chất lượng. Và vì nó tốn tiền, miễn là hàng triệu người vẫn mua những trò chơi mới nhất với nói lắp, rất nhiều nhà quản lý sẽ không sẵn sàng chi nhiều tiền hơn để tối ưu hóa mọi thứ.
Vì vậy, có lẽ, chỉ có thể thôi, vấn đề Có thể được sửa chữa bởi chúng ta – tất cả thông qua sức mạnh của ví của chúng ta.