• Шейдер для создания эффекта ветра на листьях, кустах и т.д.

    Первая версия моего шейдера, всё вроде бы хорошо, но в зоне тумана не работает.
    Подсмотрел на https://ru.stackoverflow.com/questions/945023/Деформация-анимация-картинки-на-unity

    Shader "wind"
    {
            Properties
            {
                    [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
                    _Color("Tint", Color) = (1,1,1,1)
                    [MaterialToggle] PixelSnap("Pixel snap", Float) = 0
            }
    
                    SubShader
                    {
                            Tags
                            {
                                    "Queue" = "Transparent"
                                    "IgnoreProjector" = "True"
                                    "RenderType" = "Transparent"
    //                              "RenderType" = "Opaque"
                                    "PreviewType" = "Plane"
                                    "CanUseSpriteAtlas" = "True"
                            }
    
                            Cull Off
                            Lighting Off
                            ZWrite Off
                            Blend One OneMinusSrcAlpha
    
                            Pass
                            {
                            CGPROGRAM
                                    #pragma vertex vert
                                    #pragma fragment frag
                                    #pragma multi_compile _ PIXELSNAP_ON
                                    #pragma multi_compile_fog
                                    #include "UnityCG.cginc"
    
                                    struct appdata_t
                                    {
                                            float4 vertex   : POSITION;
                                            float4 color    : COLOR;
                                            float2 texcoord : TEXCOORD0;
                                    };
    
                                    struct v2f
                                    {
                                            float4 vertex   : SV_POSITION;
                                            fixed4 color : COLOR;
                                            float2 texcoord  : TEXCOORD0;
                                            UNITY_FOG_COORDS(1)
                                    };
    
                                    fixed4 _Color;
    
                                    v2f vert(appdata_t IN)
                                    {
                                            v2f OUT;
                                            OUT.vertex = UnityObjectToClipPos(IN.vertex);
                                            OUT.texcoord = IN.texcoord;
                                            OUT.color = IN.color * _Color;
                                            #ifdef PIXELSNAP_ON
                                            OUT.vertex = UnityPixelSnap(OUT.vertex);
                                            #endif
                                            UNITY_TRANSFER_FOG(OUT, OUT.vertex);
    
                                            return OUT;
                                    }
    
                                    sampler2D _MainTex;
                                    sampler2D _AlphaTex;
                                    float _AlphaSplitEnabled;
    
                                    fixed4 SampleSpriteTexture(float2 uv)
                                    {
                                            uv.x;
                                            fixed4 color = tex2D(_MainTex, uv);
    
            #if UNITY_TEXTURE_ALPHASPLIT_ALLOWED
                                            if (_AlphaSplitEnabled)
                                                    color.a = tex2D(_AlphaTex, uv).r;
            #endif //UNITY_TEXTURE_ALPHASPLIT_ALLOWED
    
                                            return color;
                                    }
    
                                    fixed4 frag(v2f IN) : SV_Target
                                    {
                                            IN.texcoord.x += _SinTime.a * 0.05 * IN.texcoord.y;
                                            fixed4 c = SampleSpriteTexture(IN.texcoord) * IN.color;
    
                                            UNITY_APPLY_FOG(IN.fogCoord, c);
    
                                            c.rgb *= c.a;
    
                                            return c;
                                    }
                            ENDCG
                            }
                    }
    }
     
    

    Еще я нашел подходящий шейдер, который работает, как надо:
    http://josemariaolea.com/create-grass-with-wind-effect-in-unity/

    Shader "Custom/WindGrass" {
    Properties {
    // Surface shader parameters
    _Color ("Color", Color) = (1,1,1,1)
    _MainTex ("Albedo (RGB)", 2D) = "white" {}
    _Glossiness ("Smoothness", Range(0,1)) = 0.5
    _Metallic ("Metallic", Range(0,1)) = 0.0
     
    // Wind effect parameteres
    _WindFrecuency("Wind Frecuency",Range(0.001,100)) = 1
    _WindStrength("Wind Strength", Range( 0, 2 )) = 0.3
    _WindGustDistance("Distance between gusts",Range(0.001,50)) = .25
    _WindDirection("Wind Direction", vector) = (1,0, 1,0)
     
    }
    SubShader {
    Tags { "Queue"="Transparent"
    "RenderType"="TransparentCutout"
    }
    LOD 200
     
    CGPROGRAM
     
    #pragma surface surf Standard vertex:vert alpha:fade
    //#pragma target 3.0
     
    sampler2D _MainTex;
     
    struct Input {
    float2 uv_MainTex;
    };
     
    half _Glossiness;
    half _Metallic;
    fixed4 _Color;
     
    half _WindFrecuency;
    half _WindGustDistance;
    half _WindStrength;
    float3 _WindDirection;
     
    // our vert modification function
    void vert( inout appdata_full v )
    {
    float4 localSpaceVertex = v.vertex;
    // Takes the mesh′s verts and turns it into a point in world space
    // this is the equivalent of Transform.TransformPoint on the scripting side
    float4 worldSpaceVertex = mul( unity_ObjectToWorld, localSpaceVertex );
     
    // Height of the vertex in the range (0,1)
    float height = (localSpaceVertex.y/2 + .5);
     
    worldSpaceVertex.x += sin( _Time.x * _WindFrecuency + worldSpaceVertex.x * _WindGustDistance) * height * _WindStrength * _WindDirection.x;
    worldSpaceVertex.z += sin( _Time.x * _WindFrecuency + worldSpaceVertex.z * _WindGustDistance) * height * _WindStrength * _WindDirection.z;
     
    // takes the new modified position of the vert in world space and then puts it back in local space
    v.vertex = mul( unity_WorldToObject, worldSpaceVertex );
     
    }
     
    void surf (Input IN, inout SurfaceOutputStandard o) {
    // Albedo comes from a texture tinted by color
    fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    o.Albedo = c.rgb;
    // Metallic and smoothness come from slider variables
    o.Metallic = _Metallic;
    o.Smoothness = _Glossiness;
    o.Alpha = c.a;
    }
    ENDCG
     
    }
    FallBack "Diffuse"
    }
    
    

    На всякий случай, выкладываю файлы шейдеров в виде архива:
    https://blackrid.ru/upload/files/29_08_2021/wind.zip



  • Движок Unity. Обучаемся всему заново.

    Если вкратце, то в прошлом году я начал осваивать Unity 3D. Поскольку, в программировании я не новичок, то довольно быстро разобрался, что к чему.

    За основу я взял игру "S.T.A.L.K.E.R. Тени Чернобыля". Почему её? Потому что все доступные ресурсы из неё уже давно выдраны и существует гигантское комьюнити мододелов. Для своего обучения решил попробовать собрать уровень, используя контент из этой игры.

    В общем, дело пошло, я собрал тестовую локацию, было готово следующее:

    1. Инвентарь. Там были только патроны для автомата, но сама система инвентаря работала
    2. Земля была раскрашена тремя текстурами, которые перемешивались по маске, был плавный переход земля-бетон-песок
    3. Система стрельбы, перезарядка, просчет попаданий пули, определение материала, в который попала пуля, вылетающие от попадания куски штукатурки/или дерева
    4. Фонарик
    5. Сидящий у себя в бункере Сидорович. Он здоровался и прощался, когда мы выходили
    6. Открытие-закрытие дверей. Тестировал на двери бункера Сидоровича
    7. Смена дня и ночи, динамический туман, не дефолтный, а самописный, менее ресурсоемкий
    8. Ветер. Опять же не дефолтный, а свой. Трава и листья деревьев плавно колыхались
    9. Предметы, раскиданные по уровню (коробки с патронами, аптечки и т.п.)
    10. Миникарта с позицией игрока
    11. Динамический прицел, который менял форму и цвет, показывал имя NPC при наведении или название предмета
    12. Удобное мобильное управление, кнопки и тач-панель
    13. Определение типа поверхности, по которой мы ходим (для воспроизведения разного звука шагов по металлу, бетону, земле)
    14. Динамическое расставление кустов и травы, настройка плотности растительности

    Еще какие-то фишки были в разработке, но... внезапно умер винт. К сожалению, как это очень часто бывает, никаких бэкапов не осталось, только в моей голове )

    Вот несколько видео, которые я успел сделать перед этим:

    Unity3D. Пробуем сделать FPS на основе ресурсов STALKER

    Unity3D: анимация mesh-травы. Движение от ветра

    Unity3D: триггер на вход-выход

    Unity3D: настроил анимацию и звук двери бункера

    Unity3D: игры с туманом и освещением сцены


    После полугодового перерыва придется вспоминать все заново. Оно, наверное, к лучшему - сейчас я могу более четко просчитать структуру и иерархию кода, более вдумчиво подойти к моментам, которые тогда реализовал не полностью.

    В общем, буду публиковать свои успехи. Ждите обновлений )







Загрузка...

Войти на сайт

Регистрация