Một phác thảo chung:
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.
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.
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 đó.
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:
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]. smoothstep
là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.005
bù 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!