Попытка изменить шейдер так, чтобы цвета были вертикальными, а не горизонтальными - PullRequest
0 голосов
/ 10 октября 2019

Этот шейдер (скопированный ниже) делает материал подобным радиальному градиенту. Я пытаюсь изменить его, чтобы эффект шейдера напоминал вертикальный / линейный градиент, например this . Я не верю, что это создает настоящий градиент, а скорее добавляет цвета и добавляет альфа между ними. Он основан на этом удивительном проекте .

Вот изображение эффекта, который у меня есть с этим шейдером и включенным эффектом scanlines: https://imgur.com/a/At0ATB5

А вот изображение того, как мне нужен эффект, чтобы он выглядел: https://imgur.com/a/aTtLhoN

Вот изображение того, как редактирование шейдера выглядит в данный момент: https://imgur.com/a/5hxMZtt (Это выглядит радиально,нет?)

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

Shader "SFHologram/HologramShader"
{
    Properties
    {
        // General
        _TopColor ("Top Color", Color) = (1, 0.3, 0.3, 0)
        _BottomColor ("Bottom Color", Color) = (0.3, 0.3, 1, 0)
        _Up ("Up", Vector) = (0, 1, 0)
        _Exp ("Exp", Range(0, 16)) = 1

        _Brightness("Brightness", Range(0.1, 6.0)) = 3.0
        _Alpha ("Alpha", Range (0.0, 100)) = 1.0
        _Direction ("Direction", Vector) = (0,1,0,0)
        // Main Color
        _MainTex ("MainTexture", 2D) = "white" {}
        _MainColor ("MainColor", Color) = (1,1,1,100)
        // Rim/Fresnel
        _RimColor ("Rim Color", Color) = (1,1,1,1)
        _RimPower ("Rim Power", Range(0.1, 10)) = 5.0
        // Scanline
        _ScanTiling ("Scan Tiling", Range(0.01, 10.0)) = 0.05
        _ScanSpeed ("Scan Speed", Range(-2.0, 2.0)) = 1.0
        _ScanColor ("ScanColor", Color) = (255,1,1,1)
        // Glow
        _GlowTiling ("Glow Tiling", Range(0.01, 1.0)) = 0.05
        _GlowSpeed ("Glow Speed", Range(-10.0, 10.0)) = 1.0
        // Glitch
        _GlitchSpeed ("Glitch Speed", Range(0, 50)) = 1.0
        _GlitchIntensity ("Glitch Intensity", Float) = 0
        // Alpha Flicker
        _FlickerTex ("Flicker Control Texture", 2D) = "white" {}
        _FlickerSpeed ("Flicker Speed", Range(0.01, 100)) = 1.0

        // Settings
        [HideInInspector] _Fold("__fld", Float) = 1.0
    }
    SubShader
    {
        Tags { "Queue"="Transparent" "RenderType"="Transparent" }
        Blend SrcAlpha OneMinusSrcAlpha
        LOD 100
        ColorMask RGB
        Cull Back

        Pass
        {
            CGPROGRAM
            #pragma shader_feature _SCAN_ON
            #pragma shader_feature _GLOW_ON
            #pragma shader_feature _GLITCH_ON
            #pragma vertex vert
            #pragma fragment frag
            fixed3 _TopColor, _BottomColor;
            float3 _Up;
            float _Exp;

            #include "UnityCG.cginc"

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

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
                float4 worldVertex : TEXCOORD1;
                float3 viewDir : TEXCOORD2;
                float3 worldNormal : NORMAL;
            fixed4 col : COLOR;
            };

            sampler2D _MainTex;
            sampler2D _FlickerTex;
            float4 _Direction;
            float4 _MainTex_ST;
            float4 _MainColor;
            float4 _ScanColor;
            float4 _RimColor;
            float _RimPower;
            float _GlitchSpeed;
            float _GlitchIntensity;
            float _Brightness;
            float _Alpha;
            float _ScanTiling;
            float _ScanSpeed;
            float _GlowTiling;
            float _GlowSpeed;
            float _FlickerSpeed;

            v2f vert (appdata v)
            {
                v2f o;

                // Glitches
                #if _GLITCH_ON
                    v.vertex.x += _GlitchIntensity * (step(0.5, sin(_Time.y * 2.0 + v.vertex.y * 1.0)) * step(0.99, sin(_Time.y*_GlitchSpeed * 0.5)));
                #endif

                o.vertex = UnityObjectToClipPos(v.vertex);

                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.worldVertex = mul(unity_ObjectToWorld, v.vertex);
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                o.viewDir = normalize(UnityWorldSpaceViewDir(o.worldVertex.xyz));

                return o;
            }


            fixed4 frag (v2f i) : SV_Target
            {

                fixed4 texColor = tex2D(_MainTex, i.uv);
                fixed4 randomColor = (255,0,0,0);
                half dirVertex = (dot(i.worldVertex, normalize(float4(_Direction.xyz, 1.0))) + 1) / 2;



                // Glow
                float glow = 0.0;
                #ifdef _GLOW_ON
                glow = frac(dirVertex * _GlowTiling - _Time.x * _GlowSpeed);
                #endif

                // Flicker
                fixed4 flicker = tex2D(_FlickerTex, _Time * _FlickerSpeed);

                // Rim Light

                half rim = 1.0-saturate(dot(i.viewDir, i.worldNormal));
                fixed4 rimColor = _RimColor * pow (rim, _RimPower);

                fixed4 col = texColor * _MainColor + (glow * 0.35 * _MainColor) + rimColor;

                // Scanlines
                float scan = 0.0;
                #ifdef _SCAN_ON
                scan = step(frac(dirVertex * _ScanTiling + _Time.w * _ScanSpeed), 0.5) * 0.65;
                #endif


                col.a = texColor.a * _Alpha * (scan);  

                col.rgb *= _Brightness;

                return col;
            }
            ENDCG
        }
    }

    CustomEditor "HologramShaderGUI"
}

1 Ответ

0 голосов
/ 10 октября 2019

Таким образом, часть, которую вы хотите изменить, представляет собой секцию, включающую rim:

half rim = 1.0-saturate(dot(i.viewDir, i.worldNormal));
fixed4 rimColor = _RimColor * pow (rim, _RimPower);

В настоящее время она сравнивает нормаль каждого пикселя с направлением обзора, и чем больше они похожи,Чем меньше применяется RimColor.


Вот попытка заставить эту логику работать, но с "вверх" и направлением обзора, так что чем больше они похожи, тем больше _TopColor входит в rimColorи чем противоположнее, тем больше _BottomColor входит в rimColor:

Shader "SFHologram/HologramShader"
{
    Properties
    {
        // General
        _TopColor("Top Color", Color) = (1, 0.3, 0.3, 0)
        _BottomColor("Bottom Color", Color) = (0.3, 0.3, 1, 0)
        _Up("Up", Vector) = (0, 1, 0)
        _Exp("Exp", Range(0, 16)) = 1

        _Brightness("Brightness", Range(0.1, 6.0)) = 1.0
        _Alpha("Alpha", Range(0.0, 100)) = 1.0
        _Direction("Direction", Vector) = (0,1,0,0)
        // Main Color
        _MainTex("MainTexture", 2D) = "white" {}
        _MainColor("MainColor", Color) = (1,1,1,100)
            // Rim/Fresnel
            _RimColor("Rim Color", Color) = (1,1,1,1)
            _RimPower("Rim Power", Range(0.1, 10)) = 5.0
            _RimGap("Rim Gap", Range(0,1)) = 0.75
            _RimChangeRate("Rim Change Rate", Range(0,5)) = 1.0
            // Scanline
            _ScanTiling("Scan Tiling", Range(0.01, 10.0)) = 0.05
            _ScanSpeed("Scan Speed", Range(-2.0, 2.0)) = 1.0
            _ScanColor("ScanColor", Color) = (255,1,1,1)
            // Glow
            _GlowTiling("Glow Tiling", Range(0.01, 1.0)) = 0.05
            _GlowSpeed("Glow Speed", Range(-10.0, 10.0)) = 1.0
            // Glitch
            _GlitchSpeed("Glitch Speed", Range(0, 50)) = 1.0
            _GlitchIntensity("Glitch Intensity", Float) = 0
            // Alpha Flicker
            _FlickerTex("Flicker Control Texture", 2D) = "white" {}
            _FlickerSpeed("Flicker Speed", Range(0.01, 100)) = 1.0

                // Settings
                [HideInInspector] _Fold("__fld", Float) = 1.0
    }
        SubShader
            {
                Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
                Blend SrcAlpha OneMinusSrcAlpha
                LOD 100
                ColorMask RGB
                Cull Back

                Pass
                {
                    CGPROGRAM
                    #pragma shader_feature _SCAN_ON
                    #pragma shader_feature _GLOW_ON
                    #pragma shader_feature _GLITCH_ON
                    #pragma vertex vert
                    #pragma fragment frag
                    float _Exp;

                    #include "UnityCG.cginc"

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

                    struct v2f
                    {
                        float4 vertex : SV_POSITION;
                        float2 uv : TEXCOORD0;
                        float4 worldVertex : TEXCOORD1;
                        float3 viewDir : TEXCOORD2;
                        float3 worldNormal : NORMAL;
                    };

                    sampler2D _MainTex;
                    sampler2D _FlickerTex;
                    float4 _Direction;
                    float4 _MainTex_ST;
                    float4 _MainColor;
                    float4 _ScanColor;
                    float _RimPower;
                    float _RimGap;
                    float _RimChangeRate;
                    float _GlitchSpeed;
                    float _GlitchIntensity;
                    float _Brightness;
                    float _Alpha;
                    float _ScanTiling;
                    float _ScanSpeed;
                    float _GlowTiling;
                    float _GlowSpeed;
                    float _FlickerSpeed;

                    fixed4 _TopColor;
                    fixed4 _BottomColor;

                    v2f vert(appdata v)
                    {
                        v2f o;

                        // Glitches
                        #if _GLITCH_ON
                            v.vertex.x += _GlitchIntensity * (step(0.5, sin(_Time.y * 2.0 + v.vertex.y * 1.0)) * step(0.99, sin(_Time.y*_GlitchSpeed * 0.5)));
                        #endif

                        o.vertex = UnityObjectToClipPos(v.vertex);

                        o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                        o.worldVertex = mul(unity_ObjectToWorld, v.vertex);
                        o.worldNormal = UnityObjectToWorldNormal(v.normal);
                        o.viewDir = normalize(WorldSpaceViewDir(v.vertex));

                        return o;
                    }


                    fixed4 frag(v2f i) : SV_Target
                    {

                        fixed4 texColor = tex2D(_MainTex, i.uv);
                        fixed4 randomColor = fixed4(255,0,0,0);
                        half dirVertex = (dot(i.worldVertex, normalize(float4(_Direction.xyz, 1.0))) + 1) / 2;

                        // Glow
                        float glow = 0.0;
                        #ifdef _GLOW_ON
                        glow = frac(dirVertex * _GlowTiling - _Time.x * _GlowSpeed);
                        #endif

                        // Flicker
                        fixed4 flicker = tex2D(_FlickerTex, _Time * _FlickerSpeed);

                        half rim = dot(i.viewDir, half3(0, 1, 0));
                        half topRim = saturate(smoothstep(-0.5*_RimGap, -1., rim)*_RimChangeRate);
                        half bottomRim = saturate(smoothstep( 0.5*_RimGap, 1., rim)*_RimChangeRate);

                        fixed4 rimColor = _TopColor * topRim +  _BottomColor * bottomRim;

                        fixed4 col = texColor * _MainColor + (glow * 0.35 * _MainColor) + rimColor;

                        // Scanlines
                        float scan = 1.0;
                        #ifdef _SCAN_ON
                        scan = step(frac(dirVertex * _ScanTiling + _Time.w * _ScanSpeed), 0.5) * 0.65;
                        #endif

                        col.a = texColor.a * _Alpha * (scan);

                        col.rgb *= _Brightness;

                        return col;
                    }
                    ENDCG
                }
            }
    CustomEditor "HologramShaderGUI"
}

bottom of cylinder top of cylinder


Во второй версии выполняется переход между цветом цилиндра и цветом импульса в зависимости от времени и величины uv пикселя с использованием усеченной синусоиды:

Shader "SFHologram/HologramShader"
{
    Properties
    {
        // General
        _Exp("Exp", Range(0, 16)) = 1

        _Brightness("Brightness", Range(0.1, 6.0)) = 3.0
        _Alpha("Alpha", Range(0.0, 100)) = 1.0
        _Direction("Direction", Vector) = (0,1,0,0)
        // Main Color
        _MainTex("MainTexture", 2D) = "white" {}
        _MainColor("MainColor", Color) = (1,1,1,100)
            // Pulse
            _PulseColor("Pulse Color", Color) = (1, 0.3, 0.3, 1)
            _PulseLength("Pulse Length", Float) = 0.5
            _PulseFreq("Pulse Frequency",Float) = 20.0
            _PulseSpeed("Pulse Speed", Float) = -4.0
            _PulseGradient("Pulse Gradient", Float) = 0.8
            // Scanline
            _ScanTiling("Scan Tiling", Range(0.01, 10.0)) = 0.05
            _ScanSpeed("Scan Speed", Range(-2.0, 2.0)) = 1.0
            _ScanColor("ScanColor", Color) = (255,1,1,1)
            // Glow
            _GlowTiling("Glow Tiling", Range(0.01, 1.0)) = 0.05
            _GlowSpeed("Glow Speed", Range(-10.0, 10.0)) = 1.0
            // Glitch
            _GlitchSpeed("Glitch Speed", Range(0, 50)) = 1.0
            _GlitchIntensity("Glitch Intensity", Float) = 0
            // Alpha Flicker
            _FlickerTex("Flicker Control Texture", 2D) = "white" {}
            _FlickerSpeed("Flicker Speed", Range(0.01, 100)) = 1.0

                // Settings
                [HideInInspector] _Fold("__fld", Float) = 1.0
    }
        SubShader
            {
                Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
                Blend SrcAlpha OneMinusSrcAlpha
                LOD 100
                ColorMask RGB
                Cull Back

                Pass
                {
                    CGPROGRAM
                    #pragma shader_feature _SCAN_ON
                    #pragma shader_feature _GLOW_ON
                    #pragma shader_feature _GLITCH_ON
                    #pragma vertex vert
                    #pragma fragment frag
                    float _Exp;

                    #include "UnityCG.cginc"

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

                    struct v2f
                    {
                        float4 vertex : SV_POSITION;
                        float2 uv : TEXCOORD0;
                        float4 worldVertex : TEXCOORD1;
                        float3 viewDir : TEXCOORD2;
                        float3 worldNormal : NORMAL;
                    };

                    sampler2D _MainTex;
                    sampler2D _FlickerTex;
                    float4 _Direction;
                    float4 _MainTex_ST;
                    float4 _MainColor;
                    float4 _ScanColor;
                    float4 _PulseColor;
                    float _PulseLength;
                    float _PulseFreq;
                    float _PulseSpeed;
                    float _PulseGradient;
                    float _RimChangeRate;
                    float _GlitchSpeed;
                    float _GlitchIntensity;
                    float _Brightness;
                    float _Alpha;
                    float _ScanTiling;
                    float _ScanSpeed;
                    float _GlowTiling;
                    float _GlowSpeed;
                    float _FlickerSpeed;

                    fixed4 _TopColor;
                    fixed4 _BottomColor;

                    v2f vert(appdata v)
                    {
                        v2f o;

                        // Glitches
                        #if _GLITCH_ON
                            v.vertex.x += _GlitchIntensity * (step(0.5, sin(_Time.y * 2.0 + v.vertex.y * 1.0)) * step(0.99, sin(_Time.y*_GlitchSpeed * 0.5)));
                        #endif

                        o.vertex = UnityObjectToClipPos(v.vertex);

                        o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                        o.worldVertex = mul(unity_ObjectToWorld, v.vertex);
                        o.worldNormal = UnityObjectToWorldNormal(v.normal);
                        o.viewDir = normalize(WorldSpaceViewDir(v.vertex));

                        return o;
                    }


                    fixed4 frag(v2f i) : SV_Target
                    {

                        fixed4 texColor = tex2D(_MainTex, i.uv);
                        fixed4 randomColor = fixed4(255,0,0,0);
                        half dirVertex = (dot(i.worldVertex, normalize(float4(_Direction.xyz, 1.0))) + 1) / 2;

                        // Glow
                        float glow = 0.0;
                        #ifdef _GLOW_ON
                        glow = frac(dirVertex * _GlowTiling - _Time.x * _GlowSpeed);
                        #endif

                        // Flicker
                        fixed4 flicker = tex2D(_FlickerTex, _Time * _FlickerSpeed);

                        float4 col = (texColor * _MainColor + (glow * 0.35 * _MainColor));

                        float pulseIntensity = saturate(sin((i.uv.y / _PulseLength - _Time.x*_PulseSpeed) * _PulseFreq) * _PulseGradient);
                        col = lerp(col, _PulseColor, pulseIntensity);

                        // Scanlines
                        float scan = 1.0;
                        #ifdef _SCAN_ON
                        scan = step(frac(dirVertex * _ScanTiling + _Time.w * _ScanSpeed), 0.5) * 0.65;
                        #endif

                        col.a = texColor.a * _Alpha * (scan);

                        col.rgb *= _Brightness;

                        return col;
                    }
                    ENDCG
                }
            }
    CustomEditor "HologramShaderGUI"
}

demo of animated pulses demo of alternate coloring

Вы можете проверить это, создав новый проект / сцену с этим шейдером, присоединенным к полю holoShader в этом сценарии, размещенном на основной камере, и используя вид сцены для навигацииСцена:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestScript : MonoBehaviour
{
    public Shader holoShader;

    private void Start()
    {

        Material mat = new Material(holoShader);
        mat.SetFloat("_Brightness", 1f);
        mat.SetColor("_MainColor", new Color(0.9f, 1f, 1f));
        mat.SetColor("_PulseColor", new Color(0.9f, .8f, .4f));

        GameObject pillar1 = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
        pillar1.transform.localScale = new Vector3(0.3f, 20.0f, 0.3f);
        pillar1.transform.position = new Vector3(-1f, 5f, 5f);

        pillar1.GetComponent<Renderer>().material = mat;

        GameObject pillar2 = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
        pillar2.transform.localScale = new Vector3(0.5f, 40.0f, 0.5f);
        pillar2.transform.position = new Vector3(2f, 13f, 8f);

        pillar2.GetComponent<Renderer>().material = mat;

    }
}
...