Unity - Эффекты частиц: как заставить шейдер воспроизводиться в желаемое время - PullRequest
0 голосов
/ 25 мая 2020

В последнее время я пытался испытать удачу на VFX. Я натолкнулся на эффект, который мне очень нравится, - шейдер прокрутки.

Я основывался на этом посте и смог связаться с его создателем, так что передайте ему привет, и он направил меня в правильном направлении для достижения желаемого эффекта.

Позже я понял, что у меня было несколько ошибок, и если кто-то может мне помочь, я буду очень признателен.

Эффект представляет собой простую прокрутку текстуры через определенный me sh, замаскированный с помощью альфа-текстуры.

Первая проблема: эффект не имеет цвета ... Он вращается, и альфа-маска фиксируется, но цвет остается не показывать.

Вторая проблема: я использую этот шейдер для завершения определенной c части эффекта, используя систему частиц. Я использовал опцию Color Over Lifetime, но она все равно активируется, как только начинается весь эффект. С опцией Start Delay это работает.

В некотором смысле проблема решена таким образом, хотя я хотел бы знать, как я мог это медленно проявляться как Color Over Lifetime.

Final вопрос, как скорее бонус.

Есть ли способ медленно заставить меня sh появляться вместе с эффектом шейдера снизу вверх?

Текущий код шейдера

Shader "Custom/ScrollingShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _AlphaMaskTex ("AlphaMask", 2D) = "white" {}
        _ScrollSpd ("Scroll Speeds", vector) = (-5, -20, 0, 0)
        [HDR] _Color ("Color", Color) = (1, 1, 1, 1)
    }
    SubShader
    {
        Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
        // No culling or depth
        Cull back ZWrite Off ZTest Always Blend SrcAlpha OneMinusSrcAlpha


        Pass
        {
            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float2 alphauv : TEXCOORD1;
                float4 vertex : SV_POSITION;
            };

            float4 _MainTex_ST;
            float4 _AlphaMaskTex_ST;
            float4 _ScrollSpd;

            v2f vert (appdata v)
            {                
                /* v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex).xy + frac(_Time.y * float2(_ScrollSpd.x, _ScrollSpd.y));
                return o; */

                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex).xy + frac(_Time.y * float2(_ScrollSpd.x, _ScrollSpd.y));

                o.alphauv = TRANSFORM_TEX(v.uv, _AlphaMaskTex).xy;

                return o;
            }

            sampler2D _MainTex;
            sampler2D _AlphaMaskTex;
            float4 _Color;

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                fixed4 colA = tex2D(_AlphaMaskTex, i.alphauv);

                col = tex2D(_MainTex, i.uv) * _Color;

                col.a = tex2D(_AlphaMaskTex, i.uv).r;

                col = tex2D(_MainTex, i.uv) * tex2D(_AlphaMaskTex, i.alphauv).r;

                return col;
            }
            ENDCG
        }
    }
}

Me sh используется с нанесенным материалом:

enter image description here

Заранее спасибо, и если вы что-то не понимаете, пожалуйста, принесите его мне, чтобы я мог попытаться объяснить лучше.

Большое спасибо !!

1 Ответ

1 голос
/ 26 мая 2020

относительно вашего первого вопроса: В строке 68

col = tex2D (_MainTex, i.uv) * _Color;

Вы пытаетесь установить цвет с помощью умножая текстуру на свой цвет. В строке 72

col = tex2D (_MainTex, i.uv) * tex2D (_AlphaMaskTex, i.alphauv) .r;

Вы просто перезаписываете существующий цвет ценности. Так что, пока ваша основная текстура в оттенках серого, цвет в эффекте не будет. Я предполагаю, что вам нужно что-то вроде этого:

col = tex2D(_MainTex, i.uv) * _Color;
//col.a = tex2D(_AlphaMaskTex, i.alphauv).r; //<-- Edit1
col.a = tex2D(_AlphaMaskTex, i.alphauv).r * _Color.a; //<-- Edit2 fade in

Относительно вашего второго вопроса: я не совсем понимаю, чего вы пытаетесь достичь. Я также не специалист по системе частиц. Но пока вы рисуете свои частицы, шейдер будет выполняться, и при обращении к _Time он будет анимирован. Цвет за время жизни можно использовать в качестве входных данных для вашего шейдера. Таким образом, вы можете использовать это как значение для изменения поведения шейдера. Вы можете делать всевозможные забавные вещи, например, если вы хотите начать анимацию частицы через некоторое время, вы можете настроить цвет на протяжении всей жизни для смешивания от 0 альфа до 1 альфа, тогда вы проверяете значение альфа в шейдере, и если оно больше чем 0.5 вы начинаете анимировать свой ув. Функция цвета на протяжении всего срока службы кажется хорошим способом передать данные вашему шейдеру.

К сожалению, я не совсем понимаю, чего вы пытаетесь достичь, поэтому я больше ничем не могу помочь. Может быть, вы можете уточнить свой второй вопрос?

Относительно вашего третьего вопроса:

Это вполне возможно. В своем фрагментном шейдере вы можете представить свои uv как градиент снизу вверх и слева направо. Итак, если вы возьмете uv.y и умножите его на свой альфа-цвет, вы будете смешивать свою частицу. Теперь вы можете анимировать это с помощью цвета, который вы получили из функции цвета с течением времени. Я не пробовал, но вы можете сделать что-то вроде этого:

col.a = clamp(col.a * i.uv.y + _Color.a, 0.0f, 1.0f); //<- Edit

Как я уже сказал, я не тестировал это, и вам, скорее всего, понадобится добавить к этому несколько смещений. Если вы испытываете затруднения, я могу дать вам рабочий пример.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...