Cách tạo hiệu ứng dấu vết giống như neon 2D trong Unity


7

Gần đây tôi đã chơi đùa với các hiệu ứng neon-ish cho một trò chơi tôi đang thực hiện và muốn chia sẻ kết quả của tôi với bạn.

Nếu các bạn có bất kỳ phương pháp nào khác để đạt được kết quả này, hãy chắc chắn chia sẻ.

Câu trả lời:


10

Để đạt được hiệu ứng này, bạn tôi đã tạo ra một sprite tùy chỉnh, chúng tôi đã chơi xung quanh với tất cả các loại họa tiết và bạn có thể tùy chỉnh phần này theo ý thích của mình. Trình tạo bóng mà tôi đã viết cho hiệu ứng này, lấy sprite, tạo màu xám cho sprite, sử dụng màu để tạo phiên bản màu và sử dụng phiên bản thang độ xám cùng với phiên bản màu để tô màu cho các phần có màu xám.

Trước hết, sprite của bạn không thực sự cần phải có thang độ xám, nhưng có lẽ sẽ tốt hơn cho các sprite thang độ xám. Hiệu ứng đường mòn mà tôi đã sử dụng kéo dài sprite theo chiều ngang, do đó, làm cho sprite nằm ngang là khá cần thiết.

Đây là sprite chúng tôi đã sử dụng trong trò chơi (nó được tích hợp sẵn trong alpha cần thiết cho hiệu ứng phát sáng): nhập mô tả hình ảnh ở đây

Đây là shader tôi đã tạo cho hiệu ứng:

Shader "Trail/Neon"
{
    Properties
    {
        [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
    _Color("Tint", Color) = (1,1,1,1)
        _MainTexture("Sprite", 2D) = "white" {}
    [MaterialToggle] PixelSnap("Pixel snap", Float) = 0
    }

        SubShader
    {
        Tags
    {
        "Queue" = "Transparent"
        "IgnoreProjector" = "True"
        "RenderType" = "Transparent"
        "PreviewType" = "Plane"
        "CanUseSpriteAtlas" = "True"
    }

        Cull Off
        Lighting Off
        ZWrite Off
        Blend One OneMinusSrcAlpha

        Pass
    {
        CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#pragma multi_compile _ PIXELSNAP_ON
#pragma multi_compile _ ETC1_EXTERNAL_ALPHA
#include "UnityCG.cginc"

        struct appdata_t
    {
        float4 vertex   : POSITION;
        float4 color    : COLOR;
        float2 texcoord : TEXCOORD0;
        UNITY_VERTEX_INPUT_INSTANCE_ID
    };

    struct v2f
    {
        float4 vertex   : SV_POSITION;
        fixed4 color : COLOR;
        float2 texcoord  : TEXCOORD0;
        UNITY_VERTEX_OUTPUT_STEREO
    };

    fixed4 _Color;

    v2f vert(appdata_t IN)
    {
        v2f OUT;
        UNITY_SETUP_INSTANCE_ID(IN);
        UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
        OUT.vertex = UnityObjectToClipPos(IN.vertex);
        OUT.texcoord = IN.texcoord;
        OUT.color = IN.color * _Color;
#ifdef PIXELSNAP_ON
        OUT.vertex = UnityPixelSnap(OUT.vertex);
#endif

        return OUT;
    }

    sampler2D _MainTexture;
    sampler2D _AlphaTex;

    fixed4 SampleSpriteTexture(float2 uv)
    {
        fixed4 color = tex2D(_MainTexture, uv);

#if ETC1_EXTERNAL_ALPHA
        // get the color from an external texture (usecase: Alpha support for ETC1 on android)
        color.a = tex2D(_AlphaTex, uv).r;
#endif //ETC1_EXTERNAL_ALPHA

        return color;
    }

    fixed4 frag(v2f IN) : SV_Target
    {
        //standard sprite shader, only this part is different.
        //takes the sprite in
        fixed4 s = SampleSpriteTexture(IN.texcoord);

        //makes a colored version of the sprite
        fixed4 c = s * IN.color;

        //makes the grayscale version
        fixed n = (s.g + s.r + s.b) / 3;

        //So, I've scrapped the previous calculation in favor of this I'll leave the previous one in too, just for reference
        c = (c*3 + n*c.a)*c.a;
        //Adds the grayscale version on top of the colored version
        //The alpha multiplications give the neon effect feeling
        //c.g = (c.g + n * c.a) * c.a;
        //c.r = (c.r + n * c.a) * c.a;
        //c.b = (c.b + n * c.a) * c.a;
        // You can add c.a multiplications of colors 
        //(i.e. turn  c.g to c.g*c.a) for less color in your effect
        //this saturates the insides a bit too much for my liking

        return c;
    }
        ENDCG
    }
    }
}

Bạn sẽ phải tạo các vật liệu riêng biệt cho từng màu khác nhau vì cách Unity hoạt động với các shader (nếu có cách khắc phục điều này, xin vui lòng cho biết).

Vì vậy, bạn tạo một vật liệu mới, chọn shader cho vật liệu đó, thay đổi màu sắc và đầu vào sprite và bạn đã có cho mình một hiệu ứng giống như neon.

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

Và hiệu quả đạt được trong một gif:

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

Tác dụng trên các sprite khác nhau:

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


Cảm ơn vì đã chia sẻ. Lập trình Shader không phải là lĩnh vực chuyên môn của tôi, nhưng có thực sự cần thiết phải tính toán lại giá trị của nmỗi texel nhiều lần trên mỗi khung không? Sẽ không nhanh hơn nếu bằng cách nào đó chuyển đổi kết cấu thành định dạng một byte cho mỗi pixel khi nó được tải và sử dụng thay thế đó?
Philipp

Tôi đã xem xét vấn đề và không thể tìm ra cách nào tốt hơn để thực hiện điều này. Tôi đã sử dụng các tính toán được tạo sẵn trong shader, chỉ thay đổi một vài số xung quanh, vì vậy nó không có ảnh hưởng lớn hơn đến hiệu suất so với trình đổ bóng tiêu chuẩn. (Tôi vẫn không chắc chắn về đèo nhưng tôi nghĩ bạn nói đúng về phía trước đó, đó là mỗi khung chứ không phải một lần.) Tôi đang xóa bình luận khác của tôi vì đây là nhận được quá gần với một cuộc thảo luận :) @Philipp
John Hamilton

Tôi đã thử sử dụng shader của bạn và có thể khiến nó hoạt động với thành công vừa phải. Khi tôi muốn sử dụng các họa tiết riêng của mình, tôi đã thử nghiệm một số cài đặt khác nhau trong Photoshop, điều này không thực sự hiệu quả. Tôi gặp khó khăn khi hiểu phần này của bài viết của bạn về việc tạo các họa tiết riêng với trình đổ bóng của bạn: "Trước hết, sprite của bạn không thực sự cần phải là thang độ xám ... "bạn có thể giải thích chi tiết hơn về cách sprite nên được chuẩn bị để làm việc với trình đổ bóng này không?
JustIlom

@JustIlom Trình tạo bóng này có khá nhiều màu sắc mà sprite bạn có và cung cấp cho giá trị alpha nhiều sức mạnh hơn so với sprite sẽ trông như thế nào. Hãy thử shader với hiệu ứng chuyển màu từ trắng với toàn alpha sang đen với zero alpha (bạn sẽ cần lưu nó ở định dạng hỗ trợ các giá trị alpha), nó sẽ rõ ràng hơn những gì nó làm. (Ví dụ sprite mà tôi đưa vào ở trên sẽ hoạt động với điều này nhưng tôi không biết nếu imgur đã thay đổi các giá trị alpha.)
John Hamilton

John Hamilton, Trình tạo bóng này có hoạt động trong trình kết xuất dòng không hay chỉ là trong các họa tiết?
Nitecki
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.