Không đổi viền màn hình không gian rộng


7

Gần đây, tôi đã nghiên cứu một chút về shader (trong Unity) và đang cố gắng tạo lại "nội tuyến dựa trên ánh sáng" có thể được quan sát trong Legend of Zelda mới nhất. Nhưng có lẽ nhiệm vụ là một chút trên kiến ​​thức của tôi, bây giờ.

Hình ảnh tham khảo chú thích

Theo như những gì tôi có thể phân tích, nó dường như hành xử (khi di chuyển) tương tự như những gì "viền bóng" làm, ngoại trừ nó có một đường cắt sắc nét (đơn giản để làm) và - phần tôi đang vật lộn - dường như có chiều rộng không đổi độc lập với độ cong cục bộ của lưới và khoảng cách với camera, về cơ bản có "chiều rộng" không đổi so với màn hình. (tốt, nó thực sự thay đổi một chút với khoảng cách máy ảnh, nhưng chủ yếu là không nên giả sử nó không)

Hơi khó để hiển thị trong một ảnh tĩnh, nhưng bạn có thể tìm thấy nhiều video trên trò chơi và hiệu ứng có thể nhìn thấy ở mọi nơi.

Tôi đã quản lý để làm phần đơn giản hơn, bóng râm cắt ra. Nhưng điều này mang lại hiệu ứng khó xử, tùy thuộc vào hướng máy ảnh và độ cong hình học, "nội tuyến" chiếm diện tích màn hình nhiều hay ít. Dưới đây là hình ảnh về kết quả hiện tại tôi nhận được trên các góc máy ảnh khác nhau, với mũi tên màu xanh lá cây hiển thị các khu vực tốt / chấp nhận được và mũi tên màu đỏ biểu thị độ lệch so với hiệu ứng dự định.

Đầu ra hiện tại với chú thích tốt / xấu

Đây là triển khai hiện tại của tôi để tham khảo, với tư cách là Mô hình ánh sáng bề mặt Unity:

half4 LightingToonPoster(SurfaceOutputStandard surf, float3 viewDir, UnityGI gi) {
    // Material properties
    half3 specular;
    half oneMinusReflectivity;
    DiffuseAndSpecularFromMetallic(surf.Albedo, surf.Metallic, /*out*/ specular, /*out*/ oneMinusReflectivity);
    float3 reflected = normalize(-reflect(gi.light.dir, surf.Normal));
    float specularity = dot(viewDir, reflected) * _Specularity;

    // Light setup
    float ndotl = dot(surf.Normal, gi.light.dir) * 0.5 + 0.5;
    float lightIncidence = gi.light.color * ndotl;
    float3 ramp = tex2D(_Ramp, lightIncidence.xx).rgb;
    float3 specularRamp = tex2D(_Ramp, specularity.xx).rgb;
    gi.light.color = ramp * _LightColor0.rgb;

    // Rim and camera-light convergence
    float rim = 1 - saturate(dot(surf.Normal, viewDir));
    float facing = -dot(viewDir, gi.light.dir) * 0.5 + 0.25;

    // sigmoid of rim for smooth falloff centered at _EdgeBias
    float outline = 1 / (1 + exp(-100 * (rim - _EdgeBias)));
    float highlight = _HighlightStrength * outline * facing * outline;

    float4 std = LightingStandard(surf, viewDir, gi);

    float3 toonDiffuse = surf.Albedo * (gi.light.color / 2 + ShadeSH9(float4(viewDir, 1)));
    float3 toonSpecular = specular * gi.indirect.specular * specularRamp;
    float4 toon = half4(toonDiffuse + toonSpecular, surf.Alpha);
    return lerp(std, toon, _UnshadeFactor) * half4(1 + highlight.xxx, 1);
}

Hoặc kiểm tra Gist này để biết tập tin shader đầy đủ

Câu hỏi bây giờ là, tôi có thể sử dụng cái gì thay vì tạo bóng râm để có được hiệu ứng tương tự, trong đó độ cong không được tính đến và tôi có được một "hình nhỏ" không đổi?


Thành thật mà nói, tôi thích cái nhìn bạn đạt được tốt hơn!
dùng1118321

@ user1118321 Tôi cũng sẽ hài lòng, nếu không thực tế là nó hoàn toàn phù hợp với mọi vấn đề nhỏ với các mô hình mà nó được áp dụng.
Kroltan

Câu trả lời:


3

Câu hỏi hay! Tôi đã không nhìn thấy trò chơi một mình nhưng câu hỏi này đã khiến tôi quan tâm vì vậy tôi đã xem một số cảnh quay trên Youtube.

Ví dụ này cung cấp một cái nhìn tốt về nó: https://youtu.be/Ktjdg3zgRzk?t=15m46s nhập mô tả hình ảnh ở đây

Một vài điều tôi nhận thấy:

  • Tóc và chân phải: lưu ý làm thế nào chỉ phần ánh sáng khuếch tán có ánh sáng viền.
  • Cổ tay trái: lưu ý làm thế nào chiều rộng trở nên mỏng hơn ở góc với bàn tay.
  • Trên một số phần khác, bạn cũng có thể thấy ánh sáng viền cũng bị ảnh hưởng bởi bóng đổ.

Từ những quan sát này, tôi nghĩ có hai hiệu ứng được sử dụng:

  1. Một bóng mờ khuếch tán với sự chuyển tiếp sắc nét giữa một ánh sáng không sáng, xảy ra ở đâu đó dưới 0 nên ánh sáng bị rò rỉ phía sau một chút.
  2. Ánh sáng viền, như bạn đề cập, có chiều rộng không gian màn hình gần như không đổi.

    Từ cái nhìn của nó và một số đồ tạo tác, tôi đoán tốt nhất là nó thực sự là một bộ lọc phát hiện cạnh dựa trên độ sâu, sau đó được sử dụng kết hợp với ánh sáng khuếch tán để ánh sáng viền không ảnh hưởng đến các phần không sáng.

Đó là một hiệu ứng khá tuyệt, cảm ơn bạn đã chỉ ra!


Tôi đã nghĩ đến việc phát hiện cạnh, nhưng khi quan sát cùng một hiệu ứng ingame trong địa hình (có hình tam giác khá lớn), có thể thấy sự chuyển tiếp giống nhau giữa vành "rộng" và chiều rộng không đổi khi máy quay chuyển sang hẹp hơn góc. Ngoài ra, loại phát hiện cạnh có thể được sử dụng ở đây? Tôi thực sự đã thử sử dụng Sobel theo chiều sâu, nhưng sau đó tôi không biết làm thế nào để điều chỉnh "chiều rộng" mà không làm mờ các đường bên trong. (Mặc dù tôi tưởng tượng đây nên là một câu hỏi riêng biệt)
Kroltan

Họ có thể phân biệt các nhân vật và địa hình (tôi nghĩ rằng hiệu ứng không có trên địa hình, nhưng có lẽ tôi chỉ bỏ lỡ nó). Đối với Sobel, chỉ cần chia tỷ lệ hạt nhân theo độ dày bạn muốn: thay vì so sánh các pixel liền kề, hãy so sánh các pixel một chút nữa.
Julien Guertault

Hmm, tôi sẽ lấy một
miếng
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.