Tôi có thể đạt được hiệu ứng đèn pin (vùng sáng hơn xung quanh nguồn sáng) trong trò chơi 2D không?


16

Tôi đang nghĩ về việc viết cho mình một trò chơi 2D đơn giản. Ban đầu nó không tỏa sáng với đồ họa hay lối chơi hoàn hảo, nhưng tôi coi đó là bước đầu tiên của tôi trong phát triển trò chơi trên PC. Vì vậy, hãy tưởng tượng trò chơi 2D dựa trên sprite đơn giản như vậy (như Heroes IV hoặc Startcraft BroodWar).

Tôi muốn trò chơi hỗ trợ ngày / đêm với sự thay đổi ánh sáng theo thời gian và đồng thời sẽ thật điên rồ khi phải tạo ra các họa tiết cho mọi sắc thái ánh sáng. Vì vậy, tôi quyết định thêm một lớp bán trong suốt lên trên các vật thể khác là đủ.

Vấn đề với giải pháp này là nếu tôi có một vật thể nguồn sáng trong trò chơi (như anh hùng đeo đèn pin, hoặc một tòa nhà đang cháy), thì phải có một khu vực nhẹ hơn xung quanh nó, phải không? Vì tôi đang đặt lớp bán trong suốt của mình lên tất cả mọi thứ, làm thế nào bạn có thể đề nghị đạt được hiệu ứng hình ảnh ngọn đuốc tôi muốn? Có thể vẽ lại lớp đó thêm 'khoảng trống' hoặc các khu vực có màu khác nhau dựa trên hiệu ứng ánh sáng?


2
Mặt nạ có thể là con đường để đi
Gustavo Maciel

5
"Torchlight" trong tiêu đề có thể gây nhầm lẫn do trò chơi có tên Torchlight.
Tết

4
@Tetrad Nên ok miễn là không viết hoa. Đối với tôi, Torchlight hoàn toàn không xuất hiện cho đến khi đọc bình luận của bạn.
famousgarkin

Tuy nhiên, tôi đề nghị một chỉnh sửa để làm cho tiêu đề cụ thể hơn.
famousgarkin

Câu trả lời:


12

Tôi không biết bạn đang lập trình cái gì, nhưng đây là cách tôi xử lý nó trong XNA:

  1. Trên lệnh vẽ, một List<Light>đối tượng được tạo / xóa.
  2. Trong vòng lặp vẽ ngói, mỗi ô được kiểm tra để xem liệu nó có bất kỳ Đèn nào được liên kết với nó không. Nếu có, các Lightđối tượng được gắn vào List<Light>.
  3. Các gạch được vẽ lên của riêng mình RenderTarget2D.
  4. Sau vòng lặp gạch, danh sách Lights được lặp đi lặp lại và tự vẽ RenderTarget2Dbằng cách sử dụng một kết cấu mà tôi đã tạo như sau:
    Kết cấu nhẹ(Lưu ý: Tôi đã sử dụng các giá trị R, G và B ở đây nhưng có lẽ bạn nên sử dụng kênh alpha trong kết cấu thực tế.)
  5. Sử dụng trình đổ bóng tùy chỉnh, tôi hiển thị bề mặt ô vuông cho màn hình và chuyển vào bề mặt chiếu sáng dưới dạng tham số được lấy mẫu cho giá trị "bóng tối" ở mỗi pixel.


Bây giờ, có một vài điều cần lưu ý:

Về điểm 4:

Tôi thực sự có hai shader tùy chỉnh, một để vẽ đèn cho mục tiêu kết xuất ánh sáng (bước 4) và một để vẽ mục tiêu kết xuất gạch lên màn hình bằng cách sử dụng mục tiêu kết xuất ánh sáng (bước 5).
Trình tạo bóng được sử dụng tại điểm 4 cho phép tôi thêm (giá trị mà tôi gọi) vào giá trị "độ sáng". Giá trị này là một giá trị floatđược nhân với mỗi pixel trong kết cấu trước khi nó được thêm vào mục tiêu kết xuất để tôi có thể làm cho đèn sáng hơn hoặc tối hơn.
Tại thời điểm này, tôi cũng tính đến giá trị "tỷ lệ" của ánh sáng, điều đó có nghĩa là tôi có thể có đèn lớn hoặc nhỏ chỉ bằng một kết cấu.

Về điểm 5:

Hãy nghĩ về mục tiêu kết xuất ánh sáng về cơ bản là có một giá trị cho mỗi pixel từ 0 (đen) đến 1 (trắng). Shader về cơ bản nhân giá trị đó với giá trị RGB cho một pixel trong mục tiêu kết xuất ô để tạo hình ảnh được vẽ cuối cùng.

Tôi cũng có thêm một số mã ở đây nơi tôi chuyển vào (cho trình đổ bóng) một giá trị được sử dụng làm màu lớp phủ ngày / đêm. Điều này cũng được nhân lên thành các giá trị RGB và được bao gồm trong các tính toán mục tiêu kết xuất ánh sáng.


Bây giờ, điều này sẽ không cho phép bạn làm những việc như chặn ánh sáng đi xung quanh các vật thể và không có gì, nhưng, ít nhất là cho mục đích của tôi, nó đơn giản và hoạt động tốt.

Tôi đã viết bài viết chi tiết hơn trên blog ở đâyở đây có thể giúp bạn. Tôi không có thời gian ngay bây giờ, nhưng nếu bạn muốn tôi có thể đi vào chi tiết hơn ở đây trên gamedev.

Ồ, và đây là một cái nhìn về nó trong trình chỉnh sửa bản đồ của tôi:nhập mô tả hình ảnh ở đây


Tạo và xóa một danh sách mỗi khung hình có thể không quá tốn kém?
Gustavo Maciel

@Gtoknu Không tạo ra bất kỳ sự khác biệt đáng chú ý nào trong trò chơi của tôi. Danh sách này chỉ chứa các tham chiếu đến các đối tượng đã tồn tại trong bộ nhớ nên không giống như mọi ánh sáng đang được tạo lại hoặc bất cứ thứ gì, chỉ là một danh sách.
Richard Marskell - Drackir

bạn có thể đúng, không hoàn toàn, nhưng bạn Tất nhiên, bạn không tạo đối tượng đầy đủ, nhưng bạn đang thêm con trỏ vào tài liệu tham khảo, vẫn sử dụng thấp, nhưng vẫn tiêu thụ. Bạn đang làm theo cách tốt, nhưng tôi nghĩ có thể tốt hơn nếu bạn đưa danh sách ra ngoài phương thức rút thăm, vì logic trong cập nhật nhanh hơn nhiều so với rút thăm
Gustavo Maciel

@Gtoknu Chắc chắn, bạn có thể khai báo danh sách bất cứ nơi nào bạn muốn nhưng điểm quan trọng là đèn được liên kết với gạch. DrawPhương pháp gạch là nơi bạn tìm hiểu xem một lát có đèn hay không. Tôi không lặp qua tất cả các ô được vẽ trong Updatephương thức vì vậy tôi sẽ thêm chi phí cho việc đó. Ngoài ra, XNA cố gắng đảm bảo rằng Updatesẽ được gọi 60 lần mỗi giây để có thể hy sinh Drawcác cuộc gọi cho việc này, điều đó có nghĩa là mã này thực sự sẽ được gọi ít thường xuyên hơn.
Richard Marskell - Drackir

Tất cả những gì đã nói, đó là một điểm cần thiết bởi vì cuối cùng tôi đã chuyển đèn vào danh sách của riêng họ dựa trên phân vùng không gian và chỉ thu hút tất cả các đèn trong các phần giao nhau với màn hình. Tôi đã không nói về điều đó trong bài viết của mình vì thiếu thời gian, nhưng nó được đề cập trong bài đăng blog thứ hai mà tôi liên kết.
Richard Marskell - Drackir

9

Thông thường, ánh sáng trong các trò chơi 2D được thực hiện bằng cách có Bản đồ bình thường cho tất cả các họa tiết của bạn, sau đó tính toán hiệu ứng ánh sáng 3D trên các họa tiết 2D của bạn. Điều này được gọi một cách lỏng lẻo là "2.5D". Tuy nhiên tôi không khuyên bạn nên làm điều này trong trò chơi đầu tiên của bạn vì nó phức tạp.

Đây là một video tuyệt vời về một người đã làm điều này trong XNA: http://www.youtube.com/watch?v=-Q6ISVaM5Ww

Điều đó nói rằng, có lẽ có nhiều cách để gian lận và có được một hệ thống chiếu sáng giả có thể hoạt động với nhiều giả định khác nhau.


Đã xem video này trước đây, +1 để đề cập đến kỹ thuật đáng kinh ngạc như vậy.
Gustavo Maciel

Cảm ơn bạn đã cho lời khuyên và các liên kết video. Quả thực một bản đồ dường như là một giải pháp. Bản thân tôi sẽ cố gắng sử dụng bản đồ trên lớp trên cùng của mình để tạo ra một 'khoảng trống' hoặc để thay đổi hiệu ứng của nó đối với các đối tượng bên dưới.
Ivaylo Slavov

5

Thật khó để đề xuất một cách tiếp cận nếu bạn không hoàn toàn cụ thể về hiệu quả mà bạn đang cố gắng đạt được. Các chi tiết như đèn có bị cản trở bởi môi trường hay không, quan điểm của trò chơi của bạn là gì, ánh sáng sẽ tương tác với môi trường ở mức độ nào, v.v.

Tôi sẽ bỏ hai xu của tôi mặc dù. Xem hướng dẫn này của Catalin Zima có tên Dynamic 2D Shadows có phù hợp với hóa đơn của bạn không. Như bạn có thể thấy, ánh sáng có bán kính và không đi qua chướng ngại vật. Bạn có thể làm động bán kính và màu sắc một chút để làm cho nó trông gần hơn với một ngọn đuốc thực sự.

nhập mô tả hình ảnh ở đây

Trong trường hợp này, ánh sáng đóng vai trò là lớp phủ trên đỉnh của cảnh của bạn, nhưng không tương tác với nó ở cùng mức độ như trong ví dụ của John, mặc dù điều này có thể gây trở ngại.

Biên tập

Catalin liên kết đến một bài viết khác, ông đã sử dụng làm tài liệu tham khảo, nhưng liên kết bị hỏng. Đây là một liên kết được cập nhật .


Cảm ơn, tôi nghĩ rằng đây không phải là hiệu ứng tôi đang theo đuổi, nhưng vẫn cảm ơn vì đã chia sẻ :)
Ivaylo Slavov
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.