Làm thế nào để tôi viết một shader sáng lên khi các vật thể ở gần một bề mặt?


15

Trong video chơi trò chơi Overwatch này , khiên của nhân vật sáng lên màu trắng ở những khu vực gần hình học của các vật thể khác.

Khiên của Reinhart cắt một số hình học cấp

Lưu ý các cạnh màu trắng trên lá chắn màu xanh, gần sàn nhà, tường và cột trụ.

Tôi tin rằng chiếc khiên có mô hình riêng và hiệu ứng được thực hiện với một shader, nhưng tôi đã mất việc cố gắng tìm cách dịch khái niệm "gần" sang lập trình shader.


2
Nếu bạn đang sử dụng Unity, cuộc nói chuyện này có thể được quan tâm . Kiểm tra phần trên "Điểm nổi bật giao nhau" bắt đầu từ slide 26.
DMGregory

Vì vậy, câu trả lời đã được trình bày bên dưới, nhưng đây là một video giải thích nó: youtube.com/watch?v=C6lGEgcHbWc
CobaltHex

Câu trả lời:


28

Một phác thảo chung:

  1. Tạo bản đồ độ sâu của cảnh của bạn mà không có lá chắn. Bạn có thể có được điều này một cách hiệu quả miễn phí, vì các đối tượng trong suốt thường được hiển thị trong một lần sau. Mặt khác, bạn có thể tạo bản đồ độ sâu bằng cách hiển thị cảnh sans khiên lên RTT bằng trình tạo bóng sâu.

  2. Kết xuất cảnh của bạn bình thường, chuyển bản đồ độ sâu cho shader khiên của bạn.

  3. Trong shader, tính toán sự khác biệt về độ sâu của cảnh từ độ sâu của mảnh khiên và sử dụng sự khác biệt đó để sửa đổi màu của mảnh.

Bản giới thiệu

Tôi đã viết một bản demo WebGL đơn giản về điều đó.

ảnh chụp màn hình của bản demo

Từng dòng

Chúng ta hãy đi vào chi tiết mã shader mảnh:

float solidsDepth = texture2D(depthMap, gl_FragCoord.xy / dims).r;

Mẫu bản đồ độ sâu ở mỗi mảnh. Hãy nhớ chia theo kích thước khung nhìn của bạn để chuyển đoạn của bạn từ không gian màn hình [0, chiều rộng / chiều cao] sang tọa độ [0,0, 1.0] được chuẩn hóa. Tại thời điểm này, nếu bạn chỉ cần đặt màu mảnh cho pixel bản đồ độ sâu được lấy mẫu, nó sẽ trông như thế này:

ảnh chụp màn hình của bản đồ độ sâu

Bản đồ độ sâu là thang độ xám, vì vậy bạn có thể nhận giá trị từ bất kỳ kênh nào (tôi đã sử dụng rở đây).

float solidsDiff = 1.0 - smoothstep(
    zNear,
    zFar,
    gl_FragCoord.z / gl_FragCoord.w
  ) - solidsDepth;

Sau đó, bạn có thể sử dụng mẫu độ sâu đó để tìm sự khác biệt giữa độ sâu cảnh và độ sâu của mảnh khiên. Hãy nhớ bình thường hóa độ sâu của bạn, để lấy nó từ [zNear, zFar] (các mặt phẳng gần và xa của máy ảnh của bạn) thành [0.0, 1.0]. smoothsteplàm điều này độc đáo. Là 1.0 -để đảo ngược giá trị sao chosolidsDiff là 1.0 khi sự khác biệt là tối đa (zFar - zNear) và 0.0 ở mức tối thiểu (0,0).

Lưu ý rằng tôi đã giả sử solidsDepthđã được chuẩn hóa trong trình tạo bóng sâu tạo ra bản đồ độ sâu.

float alpha = 0.3 + max(0.0, 1.0 - log(100.0 * (solidsDiff - 0.005) + 1.0));

Sau đó, bạn có thể sửa đổi kênh alpha của khiên tùy thuộc vào độ chênh lệch độ sâu. Ở đây chúng tôi bắt đầu ở mức alpha tối thiểu 0.3, sau đó tạo ra mức tăng mạnh về alpha khi chúng tôi gần đạt được 0.0.

Phần - 0.005bù chỉ cần thêm một viền trắng để làm cho "giao lộ" dày hơn. Hãy thử sửa đổi nó!

gl_FragColor = vec4(vec3(1.0), alpha);

Và cuối cùng, áp dụng alpha đó cho màu mảnh của bạn.


Cải tiến

Bạn có thể tạo khiên cong, thêm plasma để có giao diện "khiên năng lượng" (bản demo) hoặc khám phá các hiệu ứng chỉ bằng các giao điểm hiển thị (bản demo) .

Bầu trời Thẻ đồ họa của bạn là giới hạn!


Oh. Của tôi Tin tốt. Ty cho hướng dẫn tuyệt vời.
Lỗi xanh

5

Nó chỉ sử dụng bản đồ độ sâu. Nó tái hiện thế giới sau đó kết xuất khiên và lấy sự khác biệt giữa giá trị z được hiển thị của khiên và giá trị z của bộ đệm độ sâu để tô màu cho pixel nhiều màu trắng hơn.


3

Tôi không biết Engine nào, nếu có, bạn đang sử dụng. Hoặc ngôn ngữ bạn đang làm việc với. Tuy nhiên, hầu hết những gì bạn có thể tìm thấy trực tuyến không khó để chuyển từ môi trường này sang môi trường khác để đạt được những gì bạn đang tìm kiếm.

Và chắc chắn có tài liệu trực tuyến có thể giúp bạn. Xem cuộc thảo luận này liên quan đến Unity: http://www.superspacetrooper.com/2012/06/tutorial-force-field-weapon-impact-energy-dispersion/ và câu hỏi này liên quan đến UE4: https: //answers.unrealengine. com / câu hỏi / 74858 / động-lực lượng-shader.html . Đối với một ví dụ đổ bóng hoàn chỉnh, thực hiện mà hiệu quả khiên, từ một cuộc tranh luận khá gần đây ở Reddit, bạn có thể thấy: https://www.reddit.com/r/Unity3D/comments/3edi0n/does_any_one_knows_how_to_make_this_shield_effect/ Và đối với một hướng dẫn mà không phải là chính xác về điều đó nhưng có liên quan đủ để quan tâm: http://www.nightbox-studios.com/2015/09/05/assets-shield-effect-scripts-for-texture3d-perlin-noise-shader/

Ngoài ra, đây là các liên kết cho 3 câu hỏi liên quan được thực hiện trước đây trong chính trang web này, có khả năng giúp ích rất nhiều để nắm bắt các khái niệm đằng sau những gì bạn muốn đạt được:

Tàu vũ trụ khiên lửa

Cách thực hiện lá chắn năng lượng starwar trong game

Hiệu ứng lá chắn XNA với một vấn đề hình cầu nguyên thủy

Cuối cùng, có khá nhiều triển khai tốt đẹp cho các shader khiên cả trong Unity và Unreal Engine trong cửa hàng ảo tương ứng của chúng, nếu bạn tình cờ sử dụng bất kỳ công cụ nào trong số đó. Tất nhiên chúng thường là các tài sản được trả tiền, nhưng hầu như luôn là nguồn mở sau khi mua - và thường rẻ. Ngay cả khi bạn không sử dụng các công cụ này, những tài sản đó có thể giúp ích để chơi và học hỏi.

Hy vọng nó giúp.


Mặc dù các liên kết này rất hữu ích, nhưng câu trả lời này về cơ bản chỉ là các liên kết và không thực sự giải quyết câu hỏi trực tiếp. Sẽ là tốt hơn để trích xuất nội dung có liên quan của các liên kết vào một lời giải thích thực tế.
Anko

Mặc dù liên kết này có thể trả lời câu hỏi, tốt hơn là bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở nên không hợp lệ nếu trang được liên kết thay đổi. - Từ đánh giá
Vaillancourt

@Anko Chắc chắn, xấu của tôi. Tôi thường bao gồm một lời giải thích và một bộ sưu tập các liên kết, nhưng lần này bạn đúng, lời giải thích thực sự đã bị thiếu. Tôi có thể sẽ xóa câu trả lời, sau đó.
MA

@AlexandreVaillancourt Tôi không thích ý tưởng chỉ sao chép-dán từ một liên kết khác thay vì chuyển hướng OP về nguồn ban đầu. Sau đó, những gì tôi nghĩ là tốt nhất là đưa ra các liên kết trong các ý kiến ​​cho câu hỏi. Vấn đề với như vậy là khi bạn biết nhiều tài liệu có thể giúp ích nhưng nó quá lớn cho các bình luận. Tuy nhiên, vì một câu trả lời giải thích tốt đã được đăng ở đây, tôi sẽ chỉ xóa câu trả lời này
MA
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.