Як я можу повторити ефект частинок спотворення Quantum Break?


68

Quantum Break має цей фантастичний ефект частинок, це ефект спотворення, як розбите скло. Я хочу знати, як я можу повторити цей ефект? Ви можете переглянути його нижче, а повне відео доступне на YouTube :

запис_2018_02_05_16_34_26_307

запис_2018_02_01_22_27_44_971


4
"Це питання не приділяло достатньої уваги." ?
Олександр Вейланкорт

@AlexandreVaillancourt я просто придавити це питання більше переглядів і звернути увагу , тому що я думаю , що це useful.I не міг знайти кращу причину , з причин баунти Якщо є проблема , я міняю reason.thanks
Сейєд Morteza Kamali

2
Мета натхнення насправді не просто "пришпилювати" питання; Ваша викладена аргументація дещо непокірна. Мета приємності - привернути увагу до питань, на які потрібні відповіді, або нагородити існуючі відповіді, що не робить ваш. Вже є механізми (HNQ, на які потрапляють багато ваших публікацій), щоб нагороджувати теми, які, як вважає громада, корисні та цікаві.
Джош

2
Не будь жадібним. Ви вже отримали достатньо переглядів і голосів
Казанова

@JoshPetrie ти маєш рацію, вибачте, що не повторюю цього стану. Мені соромно, що ви можете видалити моє запитання з особливостей, не повертаючи репутацію. Я просто це роблю, бо думав, що, можливо, я допоможу іншим.
Сеєд Мортеза Камалі

Відповіді:


101

Частинка піраміди

Форма частинок за замовчуванням єдністю є квадратна. спочатку вам потрібно змінити цю форму на піраміду, використовуючи об’єкт піраміди або перетворить квадратики на піраміди з шейдером геометрії .

зображення

awd

Заломлення

Для виготовлення ефекту розбитого скла ( Заломлення ) ви можете скористатися GrabPass { "TextureName" }вмістом екрану текстурою.

GrabPass - це спеціальний тип передачі - він захоплює вміст екрана, де об'єкт збирається втягнути в текстуру. Ця текстура може бути використана в наступних пропусках для створення розширених ефектів на основі зображення.

https://docs.unity3d.com/Manual/SL-GrabPass.html

record_2018_02_03_23_09_06_370

Shader "Smkgames/GlassRefraction"
{
    Properties{
        _Refraction("Refraction",Float) = 0.05
        _Alpha("Alpha",Range(0,1)) = 1
    }
    SubShader
    {
Tags {"Queue"="Transparent" "RenderType"="Transparent"}

        Blend SrcAlpha OneMinusSrcAlpha

        GrabPass
        {
            "_GrabTexture"
        }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 grabPos : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };
            sampler2D _MainTex;
            float _Alpha,_Refraction;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.grabPos = ComputeGrabScreenPos(o.vertex);
                return o;
            }

            sampler2D _GrabTexture;

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2Dproj(_GrabTexture, i.grabPos+_Refraction);
                return float4(col.rgb,_Alpha);

            }
            ENDCG
        }
    }
}

Використання сітчастих норм

Давайте продовжимо з шейдера, який відображає сіткові нормали у світовому просторі. Я використовував це, бо хотів виглядати тривимірну ламану форму.

нормали

запис_2018_02_05_18_06_09_41

запис_2018_02_03_23_19_06_705

    Shader "Smkgames/BrokenGlass3D"
{
    Properties{
        _MainTex("MainTex",2D) = "white"{}
        _Alpha("Alpha",Float) = 1
    }
    SubShader
    {
Tags {"Queue"="Transparent" "RenderType"="Transparent"}
 Blend SrcAlpha OneMinusSrcAlpha 


        GrabPass
        {
            "_GrabTexture"
        }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 grabPos : TEXCOORD0;
                float3 normal :NORMAL;
            };

            struct v2f
            {
                float4 grabPos : TEXCOORD0;
                float4 vertex : SV_POSITION;
                half3 worldNormal :TEXCOORD1;

            };
            sampler2D _MainTex;
            float _Intensity,_Alpha;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.grabPos = ComputeGrabScreenPos(o.vertex);
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                return o;
            }

            sampler2D _GrabTexture;

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 c = 0;
                c.rgb = i.worldNormal*0.5+0.5;
                float4 distortion = tex2D(_MainTex,i.grabPos)+_Intensity;
                fixed4 col = tex2Dproj(_GrabTexture, i.grabPos+c.r);
                return float4(col.rgb,_Alpha);
            }
            ENDCG
        }
    }
}

Спотворення тепла

Для створення спотворень тепла можна використовувати мапу потоку

Мапа потоку - це текстура, яка зберігає 2d спрямовану інформацію в текстуру. Колір пікселя визначає, у якому напрямку він використовує текстуру uv-координат як основу. Чим більше кольорів, тим швидше пропорційна швидкість. Приклад зеленого кольору говорить про те, що йде вгору-вліво, центр нейтрально, а червоний - вниз праворуч. Це корисна техніка для рідких матеріалів, як вода, і корисна альтернатива просто панерному вузлу.

поточна карта

тепловиділення

    Shader "Smkgames/HeatDistortion"
{
    Properties{
        _DistortionMap("DistortionMap",2D) = "white"{}
        _Intensity("Intensity",Float) = 50
        _Mask("Mask",2D) = "white"{}
        _Alpha("Alpha",Range(0,1)) = 1
    }
    SubShader
    {
Tags {"Queue"="Transparent" "RenderType"="Transparent"}

        GrabPass
        {
            "_GrabTexture"
        }

        Blend SrcAlpha OneMinusSrcAlpha

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 grabPos : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };
            sampler2D _Mask,_DistortionMap;
            float _Alpha,_Refraction;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.grabPos = ComputeGrabScreenPos(o.vertex);
                return o;
            }

            sampler2D _GrabTexture;
            float _Intensity;

            fixed4 frag (v2f i) : SV_Target
            {
                float mask = tex2D(_Mask,i.grabPos);
                mask = step(mask,0.5);
                //mask = smoothstep(mask,0,0.4);
                float4 distortion = tex2D(_DistortionMap,i.grabPos+_Time.y)+_Intensity;
                fixed4 col = tex2Dproj(_GrabTexture, i.grabPos*distortion);
                return float4(col.rgb,mask*_Alpha);

            }
            ENDCG
        }
    }
}

ще один приклад, використовуючи звичайний:

вирізати

нормальна карта

dimtile_normal 1

Shader "Smkgames/HeatDistortion2" {
Properties {
        _CutOut ("CutOut (A)", 2D) = "black" {}
        _BumpMap ("Normalmap", 2D) = "bump" {}
        _BumpAmt ("Distortion", Float) = 10
}

Category {

    Tags { "Queue"="Transparent"  "IgnoreProjector"="True"  "RenderType"="Opaque" }
    Blend SrcAlpha OneMinusSrcAlpha
    Cull Off 
    Lighting Off 
    ZWrite Off 
    Fog { Mode Off}

    SubShader {
        GrabPass {                          
            "_GrabTexture"
        }
        Pass {

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#pragma multi_compile_particles
#include "UnityCG.cginc"

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

struct v2f {
    float4 vertex : POSITION;
    float4 uvgrab : TEXCOORD0;
    float2 uvbump : TEXCOORD1;
    float2 uvcutout : TEXCOORD2;
};

sampler2D _BumpMap,_CutOut,_GrabTexture;
float _BumpAmt;
float4 _GrabTexture_TexelSize;
float4 _BumpMap_ST,_CutOut_ST;

v2f vert (appdata_t v)
{
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex);
    o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*-1) + o.vertex.w) * 0.5;
    o.uvgrab.zw = o.vertex.zw;
    o.uvbump = TRANSFORM_TEX( v.texcoord, _BumpMap );
    o.uvcutout = TRANSFORM_TEX( v.texcoord, _CutOut );
    return o;
}



half4 frag( v2f i ) : COLOR
{
    half2 bump = UnpackNormal(tex2D( _BumpMap, i.uvbump )).rg;
    float2 offset = bump * _BumpAmt * _GrabTexture_TexelSize.xy;
    i.uvgrab.xy = offset * i.uvgrab.z + i.uvgrab.xy;

    half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
    fixed4 cut = tex2D(_CutOut, i.uvcutout);
    fixed4 emission = col;
    emission.a = (cut.a);
    return emission;
}
ENDCG
        }
    }

  }
}

RGB Split

Якщо ви звернете увагу на свій перший gif, ви можете побачити невеликий RGB розкол.

u_rgb_seperation_ar

Shader "Hidden/RgbSplit"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _NoiseTex1 ("Noise Texture A", 2D) = "white" {}
        _NoiseTex2 ("Noise Texture B", 2D) = "white" {}
    }
    SubShader
    {

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

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

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

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            sampler2D _MainTex,_NoiseTex1,_NoiseTex2;
            float3 colorSplit(float2 uv, float2 s)
{
    float3 color;
    color.r = tex2D(_MainTex, uv - s).r;
    color.g = tex2D(_MainTex, uv    ).g;
    color.b = tex2D(_MainTex, uv + s).b;
    return color;
}

float2 interlace(float2 uv, float s)
{
    uv.x += s * (4.0 * frac((uv.y) / 2.0) - 1.0);
    return uv;
}

    fixed4 frag (v2f i) : SV_Target
    {

    float t = _Time.y;

    float s = tex2D(_NoiseTex1, float2(t * 0.2, 0.5)).r;

    i.uv = interlace(i.uv, s * 0.005);
    float r = tex2D(_NoiseTex2, float2(t, 0.0)).x;

    float3 color = colorSplit(i.uv, float2(s * 0.02, 0.0));

    return float4(color, 1.0);

            }
            ENDCG
        }
    }
}

корисні посилання

https://www.fxguide.com/featured/time-for-destruction-the-tech-of-quantum-break/

Джерело на Github


47
Мені цікаво, чи ви розглядали можливість створити блог для розробників, щоб поділитися такими методами? Я б підписався на такий ресурс. :)
DMGregory

7
Я друге пропозиція! Я щодня стежу за веб-сайтом за вашими відповідями, оскільки ваш підхід завжди креативний, детальний і при цьому простий для розуміння. Наведені вами приклади також дуже допомагають.
altskop

4
Що стосується вашого ефекту розбиття RGB: я ношу окуляри і завжди відчуваю подібний ефект, що виникає в природі, викликаний хроматичною аберацією, що залежить від відстані очей до екрана. Так само, як 3D-окуляри викликають невідповідність між різними сигналами того, як далеко щось знаходиться, ваш ефект перешкоджає деталізації, яку інтерпретує мій мозок, щоб оцінити, наскільки далеко від мого ока екран. Це вкрай неприємно, аж до нудоти. Будь ласка, зробіть це необов’язковим, якщо ви вирішили ним користуватися!
Aoeuid

1
@Aoeuid FWIW, це дуже неприємно навіть для людей без корекційного зору :)
Макс

@DMGregory так: У DI немає свого сайту, тому я ділюсь своїми методами тут, мені потрібна ваша підтримка в розробці блогу чи сайту. Якщо ви мене підтримуєте, я буду корисним https://www.patreon.com/SeyedMortezaKamaly
Seyed Morteza Kamali
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.