Tôi có nên sử dụng spritesheets, vì hoặc mặc dù số lượng lớn hình ảnh của tôi?


13

Tôi đang phát triển một trò chơi 2D, và tôi có rất nhiều họa tiết. Tôi đã sử dụng các mô hình và hoạt hình 3D để kết xuất thành 2D, để cung cấp cho chúng "Fallout" hoặc "Diablo" nhìn vào chúng. Nó cũng dễ hơn vẽ bằng tay, lol.

Tôi đã phải cắt giảm tốc độ khung hình xuống còn 15 khung hình / giây, đây là mức thấp nhất tôi có thể hạ xuống mà không khiến chúng có vẻ ngoài khó chịu với chúng. Tuy nhiên, thật đáng buồn vì 24 khung hình trông cực kỳ mượt mà.

Có hai lý do tôi đã làm điều này:

1) Cắt giảm dung lượng ổ cứng. Hình ảnh càng ít, tổng số trò chơi của tôi sẽ càng nhỏ.

2) Cắt giảm mức tiêu thụ RAM. Càng tải ít hình ảnh, tôi càng có nhiều khả năng tránh các vấn đề làm hạn chế RAM.

Tuy nhiên, nếu có một cách để nén hình ảnh trong cả không gian ổ cứng và RAM, tôi sẽ làm như vậy. Tôi đã thử nghiệm nó trước đây và hầu hết không nhận được bất kỳ thay đổi nào về chất lượng khi cung cấp từ RGBA8888 sang RGBA5555 và chỉ một chút nhấn khi chuyển đổi sang RGBA4444 trong chương trình TexturePacker của tôi. Hiện tại tôi không làm điều này, vì SFML dường như sử dụng cùng một lượng bộ nhớ cho dù đó là loại hình ảnh .PNG nào. Tôi đã nghiên cứu làm thế nào để tải nó khác nhau, nhưng không tìm thấy bất cứ điều gì về chủ đề này.

Tôi đã đọc rất nhiều về cách xử lý các trò chơi video 2D. Sự đồng thuận là rất lớn: Đóng gói Sprites của bạn thành một kết cấu lớn hơn cho hiệu suất tuyệt vời! Vì vậy, tôi gói các sprite nhỏ của mình vào một spritesheet lớn hơn nhiều bằng TexturePacker.

Tuy nhiên, tôi dự định sẽ có 10-15 hình ảnh động cho mỗi nhân vật, 5 hướng để di chuyển và 15-40 khung hình cho mỗi hình ảnh động (có thể là trung bình 24). Với 15 hình động, 5 hướng và trung bình 24 khung hình cho mỗi hình ảnh động; Đó là 1800 khung hình riêng cho mỗi nhân vật. Nếu được đóng gói trong một tấm sprite, đó chỉ là 75 hình ảnh. (Một tờ sprite cho mỗi Hoạt hình, mỗi Hướng. 15 * 5)

Đối với một nhân vật ông chủ khổng lồ trong trò chơi, tôi không thể sử dụng một spritesheet và phải lập trình một cách đơn giản để tải một hình ảnh tại một thời điểm. Tôi không biết nếu tôi có thể làm điều này cho hiệu suất chưa.

Đối với các nhân vật, tôi đã đóng gói chúng trong một spritesheet. Đối với một nhân vật duy nhất đi bộ về, điều này dường như hoạt động hầu hết thời gian, mặc dù đôi khi nó bị trì hoãn. Tuy nhiên, tôi cho rằng mã được hình dung xấu của tôi thay đổi kết cấu thay vì tải trước tất cả các kết cấu cho ký tự đó.

Nếu tôi đã tải trước các kết cấu, nó có ý nghĩa cho các tấm sprite. Tôi chỉ tưởng tượng đó là một ý tưởng tồi để tải trước 1800 hình ảnh nhỏ cho mỗi nhân vật.

Tuy nhiên, tôi tưởng tượng việc truyền chúng vào và ra khỏi bộ nhớ một lần sẽ cực kỳ nhanh, vì vậy tôi chỉ cần có một hình ảnh duy nhất trong bộ nhớ cùng một lúc. Điều này có nghĩa là tại bất kỳ thời điểm nào, tôi sẽ chỉ có mỗi nhân vật tiêu thụ một vài KB thay vì 45 + MB?

Tôi tưởng tượng điều này sẽ giết chết hiệu suất của tôi, vì việc truyền phát cần phải cực kỳ nhanh (15 hình ảnh đi vào và ra khỏi bộ nhớ và kết xuất, mỗi giây) và mặc dù các hình ảnh sẽ rất nhỏ - có thể là một ý tưởng tốt hơn để tải các ký tự viết ký tự vào bộ nhớ thay thế. Nhưng tôi sẽ phải mã hóa một hệ thống kết xuất giống như một luồng hình ảnh cho nhân vật ông chủ lớn hơn của mình.

Tôi đã thử nghiệm, nhưng nó không phải là một quá trình đơn giản. Đặc biệt là với thực tế tôi đang làm việc trên các phần khác của công cụ trò chơi không xử lý đồ họa ngay bây giờ.


1. Bạn đã không chỉ định các ràng buộc RAM hoặc ổ cứng. Có bao nhiêu nhân vật cần được truy cập nhanh? 2. Có một số câu hỏi dọc theo văn bản, có lẽ bạn có thể tập trung chúng với phần in đậm hoặc thậm chí chia các câu hỏi thành nhiều phần?
Kromster nói hỗ trợ Monica

Oh tôi xin lỗi. Không nhiều. Tôi sẽ tưởng tượng rằng số lượng ký tự riêng lẻ tối đa trên màn hình tại một thời điểm sẽ vào khoảng 40. Nếu mọi người cố gắng đánh sập khách hàng của họ, thì ... 130 là mức tối đa tuyệt đối. Thông thường, chỉ cần có 10 cho mức tối đa điển hình và mức tối đa tuyệt đối sẽ không quá <40. Bất cứ điều gì trên 40 sẽ là cực kỳ hiếm, cực kỳ hiếm, với người dùng cố tình nhồi nhét các ký tự mà không có lý do nào khác ngoài ảnh chụp màn hình hoặc cho niềm vui nhồi nhét vào các ký tự. Bất cứ điều gì trên 10 là hiếm, và bất cứ điều gì khoảng 40 là cực kỳ, cực kỳ hiếm.
Carter81

Trò chơi là một rpg 2D chỉ dành cho PC (không có thiết bị di động), tuy nhiên tôi không muốn loại trừ một nền tảng di động trừ khi đơn giản là nó không khả thi. Tôi tưởng tượng rằng không gian RAM tôi có được giới hạn ở bất kỳ RAM nào trên PC của người dùng và VRAM của người dùng. Tôi hoàn toàn nghi ngờ nó sẽ là ổ cứng rất lớn. Chỉ là nó luôn đúng với mức tiêu thụ ổ cứng mà nó càng nhỏ thì càng tốt.
Carter81

Bạn cần bao nhiêu nhân vật ĐỘC ĐÁO trên màn hình?
Kromster nói hỗ trợ Monica

Không quá 20. Bất cứ điều gì ở trên sẽ là không thể trừ khi họ lừa dối. Điển hình là 5-10.
Carter81

Câu trả lời:


16

Chúng tôi có một trường hợp tương tự với RTS Remake của chúng tôi. Tất cả các đơn vị và nhà ở là sprite. Chúng tôi có 18 000 họa tiết cho các đơn vị và nhà ở và địa hình, cộng thêm ~ 6 000 cho màu đội (áp dụng làm mặt nạ). Kéo dài chúng ta cũng có khoảng ~ 30 000 ký tự được sử dụng trong các phông chữ.

Vì vậy, lý do chính đằng sau atlours là:

  • RAM ít lãng phí hơn (trong những ngày xưa khi bạn tải NPOT lên GPU, nó được kéo dài / đệm nó lên POT, tôi đọc nó vẫn giống với iOS và một số khung công tác. Bạn nên kiểm tra phạm vi phần cứng bạn nhắm mục tiêu)
  • công tắc ít kết cấu
  • tải nhanh hơn mọi thứ trong khối nhỏ hơn

Những gì đã không làm việc cho chúng tôi:

  • kết cấu paletted. Tính năng này chỉ tồn tại trong OpenGL 1.x 2.x và thậm chí sau đó hầu hết đã bị các nhà sản xuất GPU bỏ. Tuy nhiên, nếu bạn nhắm vào OpenGL + Shader, bạn có thể tự mình làm điều đó trong shader.
  • Kết cấu NPOT, chúng tôi đã có vấn đề với các đường viền sai và các họa tiết bị mờ, điều không thể chấp nhận được trong nghệ thuật pixel. Sử dụng RAM cũng cao hơn nhiều.

Bây giờ chúng tôi có tất cả mọi thứ được đóng gói trong vài chục bản 1024x1024 (GPU hiện đại hỗ trợ kích thước thậm chí còn lớn hơn) và nó chỉ hoạt động tốt khi chỉ ăn ~ 300mb bộ nhớ, khá tốt cho trò chơi trên PC. Một số tối ưu hóa chúng tôi đã có:

  • thêm tùy chọn người dùng để sử dụng RGB5_A1 thay vì RGBA8 (bóng kiểm tra)
  • tránh Alpha 8 bit khi có thể và sử dụng định dạng RGB5_A1
  • đóng gói chặt các sprite vào atlours (xem thuật toán đóng gói Bin)
  • lưu trữ và tải mọi thứ trong một đoạn từ ổ cứng (tệp tài nguyên nên được tạo ngoại tuyến)
  • bạn cũng có thể thử các định dạng nén phần cứng (DXT, S3TC, v.v.)

Khi bạn nghiêm túc xem xét việc chuyển sang thiết bị di động, bạn sẽ lo lắng về các ràng buộc. Bây giờ chỉ cần làm cho trò chơi hoạt động và thu hút người chơi! ;)


Đây là giải pháp tốt nhất cho đến nay! Các họa tiết của tôi thậm chí không trông khác nhau trong RGB5_A1 hoặc RGBA4444, nhưng nó tiết kiệm bộ nhớ. Một đề xuất của bạn trong trò chuyện để tải trước tất cả tài sản của tôi trong RAM và VRAM là hoàn hảo. Hơn nữa, bạn đề nghị có các mức đồ họa tùy chọn, chẳng hạn như máy khách độ nét cao cho những người có RAM, hoặc tùy chọn để giảm tốc độ khung hình xuống một nửa, v.v. Những gợi ý tuyệt vời xung quanh, và chính xác những gì tôi cần!
Carter81

5

Tôi có một câu trả lời liên quan ở đây , nhưng ý tưởng chung là, nếu bạn đang tải và vẽ họa tiết vào các thời điểm khác nhau (bạn không tải thêm họa tiết trong khi bạn kết xuất), thì có hai nơi bạn làm sẽ ảnh hưởng đến hiệu suất của bạn:

Thời gian tải:

Đây là thời điểm mà bạn tải lên kết cấu của mình vào bộ nhớ. Các toàn bộ lượng dữ liệu bạn đang gửi đến VRAM là những gì hầu hết sẽ xác định bao lâu thời gian tải của bạn sẽ được. Làm cho kết cấu của bạn có các định dạng nhỏ hơn, như RGBA4444, sẽ giúp việc này nhanh hơn. Tuy nhiên, trừ khi bạn tải lên kết cấu trong hàng trăm megabyte lên VRAM, bạn có thể sẽ không gặp phải nút cổ chai ở đây. Nếu bạn làm như vậy, một màn hình tải đẹp có thể dễ dàng chờ đợi.

Việc kết hợp họa tiết của bạn vào các bản đồ sẽ ít có tác dụng, vì toàn bộ lượng thông tin bạn gửi vào VRAM sẽ giống nhau. Trên thực tế, nếu bạn đang sử dụng họa tiết của mình và bạn phải để trống các khoảng trống trong bản đồ của mình, thì bạn sẽ thực sự gửi thêm dữ liệu vào VRAM, và do đó phần này sẽ chậm hơn!

Hiệu suất kết xuất:

Khi tất cả các kết cấu của bạn nằm trong VRAM, số lượng kết cấu bạn có sẽ không ảnh hưởng đến hiệu suất kết xuất. Có bốn yếu tố ảnh hưởng đến hiệu suất kết xuất của bạn:

  1. Thay đổi trạng thái kết xuất : Mỗi lần bạn thay đổi hình ảnh bạn muốn kết xuất, sẽ làm tăng nghiêm trọng thời gian cần thiết để hiển thị nó. Nói chung, bạn muốn giảm thiểu số lượng thay đổi trạng thái và bạn có thể giảm số lượng thay đổi trạng thái bằng cách nhóm một số hình ảnh mà bạn sẽ vẽ liên tiếp vào một tập bản đồ kết cấu.

    Chỉ cần atlasing là không đủ. Bạn phải tập bản đồ theo cách giảm các thay đổi trạng thái, để có được hiệu suất. Ví dụ, người ta có thể nghĩ rằng có nhân vật chính của bạn trong một bảng sprite sẽ giúp bạn đạt được hiệu suất, nhưng nếu bạn chỉ vẽ một sprite từ bảng sprite đó trên mỗi khung, bạn sẽ không nhận được bất kỳ hiệu suất nào so với việc có mỗi sprite trong một tập tin riêng biệt.

    Việc tập trung đúng cách không phải là chuyện nhỏ, nhưng nói chung, bạn có thể nhóm các sprite từ cùng một lớp một cách an toàn. Ví dụ, có tất cả các mục GUI trong một bảng sprite là một ý tưởng rất hứa hẹn, trong khi nhóm các quái vật theo thứ tự bảng chữ cái có thể không.

  2. Cuộc gọi rút thăm: Nói chung, bạn có thể muốn giữ cuộc gọi rút thăm của mình ở mức tối thiểu. Một nguyên tắc nhỏ là nếu không có thay đổi trạng thái kết xuất giữa hai lệnh gọi rút thăm, bạn có thể nối chúng thành một lệnh rút thăm duy nhất. Để tăng hiệu suất nâng cao hơn, bạn có thể sử dụng 8 bộ lấy mẫu kết cấu và các cuộc gọi vẽ nhóm cho mỗi 8 kết cấu, do đó bạn chỉ phải thay đổi kết cấu sau mỗi 8 kết cấu.

  3. Đếm hình tam giác: Trên thực tế, bạn vẽ càng nhiều hình tam giác thì sẽ mất nhiều thời gian hơn để vẽ chúng. Tuy nhiên, trong các máy tính hiện đại và đối với hầu hết các trò chơi 2D, bạn sẽ ở rất xa để tối đa hóa điều này. Bạn có thể vẽ một cách an toàn hàng trăm ngàn họa tiết trên mỗi khung hình mà vẫn có được tốc độ khung hình cực kỳ tốt. Bạn có thể sẽ bị ràng buộc nhiều CPU hơn nếu bạn đang vẽ một số lượng cực lớn các họa tiết trước khi bạn gặp vấn đề với GPU của mình.

  4. Cài đặt API: Nếu bạn đang làm mọi thứ đúng, và bạn vẫn nhận được tốc độ khung hình thấp một cách kỳ lạ, hãy kiểm tra các cài đặt mà bạn đang vẽ các họa tiết của mình. Tôi không biết SFML, nhưng ví dụ, trong Direct3D 9, việc tạo bộ đệm đỉnh bằng D3DUSAGE_DYNAMIChoặc trong D3DPOOL_MANAGEDcó thể dễ dàng tăng gấp 10 lần thời gian kết xuất của bạn. Tất nhiên, sử dụng vSync sẽ giới hạn tốc độ khung hình của bạn ở tốc độ làm mới màn hình của bạn. Ngoài ra, sử dụng FVF không liên kết có thể làm giảm hiệu suất trong một số GPU. Điều này cũng vậy, là dành cho Direct3D 9.

    Trong trường hợp của bạn, hãy kiểm tra tài liệu về API mà bạn đang sử dụng.

Nếu bạn chỉ có số lượng họa tiết từ thấp đến trung bình (dưới 1 GB) và bạn đang vẽ số lượng họa tiết thấp (dưới một triệu mỗi khung hình), thì điều đầu tiên tôi sẽ nhìn là thay đổi cài đặt API và sau đó giảm số lượng trạng thái kết xuất và vẽ các cuộc gọi.


Nếu tôi không quan tâm đến thời gian tải, tôi có cho rằng trừ khi tôi hết RAM hoặc VRAM, tôi chỉ nên tải mọi thứ vào bộ nhớ trước?
Carter81

Tôi chỉ quan tâm đến mọi thứ BECAUSE Tôi sợ sắp hết RAM / VRAM. Tôi không biết tại sao, nhưng điều đó làm tôi bực mình rằng người dùng chơi trò chơi của tôi sẽ gặp sự cố bất cứ khi nào họ cố tải vào một khu vực có quá nhiều họa tiết độc đáo hoặc sẽ gặp sự cố mỗi khi có quá nhiều nhân vật bước lên màn hình của họ. Nếu tôi không nhầm và mỗi sprite riêng lẻ tiêu thụ 96KB, thì nếu mỗi nhân vật duy nhất có 15 hình động, 5 hướng và trung bình 24 khung hình cho mỗi hình ảnh động - mỗi nhân vật được tải đầy đủ là 173 MB. Có thể có 10, thậm chí nhiều hơn, các ký tự duy nhất trên màn hình cùng một lúc.
Carter81

@KromStern: Nếu bạn tập bản đồ và bạn phải để khoảng trống (phần đệm), thì dữ liệu sẽ lớn hơn và do đó thời gian tải sẽ lâu hơn. Rõ ràng rằng nguyên nhân của thời gian tải lâu hơn là không gian trống và tổng thời gian tải có liên quan đến tổng lượng dữ liệu chứ không phải số lượng kết cấu. Tôi không thấy bất cứ điều gì sai lệch trong đó, và tôi nghĩ rằng một người có đủ kiến ​​thức để hiểu câu hỏi ban đầu, sẽ có thể tham gia các dấu chấm và đưa ra kết luận của riêng mình cho tất cả các trường hợp khi kết cấu và atlours là PoT và nPoT.
Panda Pyjama

1
@ Carter81: Bạn cần chọn cấu hình phần cứng mục tiêu của mình, như "i5, RAM 1gb, NVidia GT260, 400mb hdd" và làm việc từ đó. Luôn có những PC yếu hơn và có ít RAM hơn.
Kromster nói hỗ trợ Monica

Rõ ràng, họ không cần tất cả 15 hình động tại bất kỳ thời điểm nào. Tuy nhiên, điều gì sẽ xảy ra nếu cả 10 nhân vật duy nhất đi vào "Chế độ chiến đấu" cùng một lúc, và do đó yêu cầu 5 bộ hoạt hình (đi bộ, chạy, nhàn rỗi, không chiến đấu, v.v.) để được hoán đổi thêm 5 lần nữa (đi bộ chiến đấu, chiến đấu nhàn rỗi, chiến đấu vv)? Tôi sợ hoán đổi kết cấu bởi vì khi tôi thử làm điều đó với SFML, nó đã tạo ra sự đóng băng hoặc tạm dừng đáng chú ý của máy khách khi chuyển đổi kết cấu. Tôi không biết nút cổ chai của mình sẽ là gì với các chiến lược khác nhau để xử lý nhiều họa tiết.
Carter81
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.