UnityURP3D管线自定义功能shader

目录

一、前言

二、代码

Shader:

HLSL:

CustomEditor:


一、前言

其实这个shader是之前写好的2D管线里的,但是项目用到了3D,也就对它进行了一些修改,这里就写一下吧。这个shader包含光照和无光功能,包含了许多可以调节的属性,也包含了面板的扩展,是一个全面的插件。如果不看代码的化也可以下载这个包直接使用Unity2DEffectShader

二、代码

Shader:

复制代码
Shader "2D/BaseShader"
{
    Properties
    {
        [Toggle(_ISUNLIT_ON)]_IsUnlit ("开启无光照模式", float) = 0
        [PerRendererData]_MainTex ("Texture", 2D) = "white" { }
        _NormalMap ("Normal Map", 2D) = "bump" { }


        // [Header(HueShift)]
        // [Space]
        [Toggle(_HUE_SHIFT_ON)]_HueShift ("开启色相调整", float) = 0
        _HsvShift ("色相偏移", Range(0, 360)) = 0
        _HsvSaturation ("饱和度", Range(0, 2)) = 1
        _HsvBright ("亮度", Range(0, 2)) = 1

        // [Header(FishEye)]
        // [Space]
        [Toggle(_FISHEYE_ON)]_FishEye ("开启鱼眼效果", float) = 0
        _FishEyeDistortIntensity ("鱼眼扭曲强度", Range(0, 1)) = 0.0
        _FishEyeScaleIntensity ("鱼眼缩放强度", Range(0, 1)) = 1.0

        // [Header(HandDraw)]
        // [Space]
        [Toggle(_HANDDRAWN_ON)]_HandDrawn ("开启手绘效果", float) = 0
        _HandDrawnAmount ("手绘偏移量", Range(0, 10)) = 1.0
        _HandDrawnSpeed ("手绘变化速度", Range(0, 10)) = 1.0

        // [Header(Wave)]
        // [Space]
        [Toggle(_WAVE_ON)]_Wave ("开启波浪效果", float) = 0
        _WaveAmount ("波浪数量", Range(0, 10)) = 1.0
        _WaveSpeed ("波浪速度", Range(0, 10)) = 1.0
        _WaveStrength ("波浪强度", Range(0, 10)) = 1.0
        _WaveX ("波浪中心X", Range(0, 1)) = 0.5
        _WaveY ("波浪中心Y", Range(0, 1)) = 0.5

        // [Header(Twist)]
        // [Space]
        [Toggle(_TWIST_ON)]_Twist ("开启扭曲效果", float) = 0
        _TwistAmount ("扭曲强度", Range(-1, 1)) = 1.0
        _TwistRadius ("扭曲半径", Range(1, 2)) = 1.0

        // [Header(Pinch)]
        // [Space]
        [Toggle(_PINCH_ON)]_Pinch ("开启挤压效果", float) = 0
        _PinchAmount ("挤压强度", Range(0, 1)) = 1.0

        // [Header(Pixel)]
        // [Space]
        [Toggle(_PIXEL_ON)]_Pixel ("开启像素化效果", float) = 0
        _PixelateSize ("像素化大小", Range(4, 512)) = 32


        // [Header(Distort)]
        // [Space]
        [Toggle(_DISTORT_ON)]_Distort ("开启扰动效果", float) = 0
        _DistortAmount ("扰动强度", Range(0, 1)) = 1.0
        _DistortTexXSpeed ("扰动纹理X速度", Range(-10, 10)) = 1.0
        _DistortTexYSpeed ("扰动纹理Y速度", Range(-10, 10)) = 1.0
        _DistortTex ("扰动纹理", 2D) = "black" { }
        [Toggle(_DISTORT_SIMPLE_NOISE)]_DistortSimpleNoise ("使用简单噪声", float) = 0
        _NoiseScale ("噪声缩放", Range(0, 100)) = 1.0

        
        // [Header(Glitch)]
        // [Space]
        [Toggle(_GLITCH_ON)]_Glitch ("开启扭曲效果", float) = 0
        _GlitchAmount ("扭曲强度", Range(0, 10)) = 1.0
        _GlitchSize ("扭曲大小", Range(0, 10)) = 1.0

        // [Header(TikTok)]
        // [Space]
        [Toggle(_TIKTOK_ON)]_TikTok ("开启TikTok效果", float) = 0
        _TikTokAmount ("TikTok强度", Range(0, 1)) = 0.5
        _TikTokAlpha ("TikTok透明度", Range(0, 1)) = 0.5

        // [Header(Glow)]
        // [Space]
        [Toggle(_GLOW_ON)]_Glow ("开启发光效果", float) = 0
        _GlowColor ("发光颜色", Color) = (1, 1, 1, 1)
        [NoScaleOffset] _GlowTex ("发光纹理", 2D) = "black" { }
        _GlowIntensity ("发光强度", Range(0, 10)) = 2
        _GlowDistortAmount ("发光扭曲强度", Range(0, 2)) = 2
        _GlowDistortTex ("发光扭曲纹理", 2D) = "gray" { }
        _GlowDistortTexXSpeed ("发光扭曲纹理X速度", Range(-5, 5)) = 0
        _GlowDistortTexYSpeed ("发光扭曲纹理Y速度", Range(-5, 5)) = 0
        [Toggle(_GLOW_SIMPLE_NOISE)]_GlowSimpleNoise ("使用简单噪声", float) = 0
        _GlowNoiseScale ("噪声缩放", Range(0, 100)) = 1.0

        // [Header(InnerLine)]
        // [Space]
        [Toggle(_INNERLINE_ON)]_InnerLine ("开启内描边效果", float) = 0
        _InnerLineColor ("内描边颜色", Color) = (1, 1, 1, 1)
        _InnerOutlineWidth ("内描边宽度", Range(0, 10)) = 1.0
        _InnerLineAlpha ("内描边透明度", Range(0, 1)) = 1.0
        _InnerLineGlow ("内描边发光程度", Range(0, 10)) = 1.0

        
        // [Header(Outline)]
        // [Space]
        [Toggle(_OUTLINE_ON)]_Outline ("开启描边效果", float) = 0
        _OutlineColor ("描边颜色", Color) = (1, 1, 1, 1)
        _OutlineWidth ("描边宽度", Range(0, 10)) = 1.0
        _OutlineAlpha ("描边透明度", Range(0, 1)) = 1.0
        _OutlineDistortAmount ("描边扭曲强度", Range(0, 2)) = 0
        _OutlineDistortTex ("描边扭曲纹理", 2D) = "black" { }
        _OutlineDistortTexXSpeed ("描边扭曲纹理X速度", Range(-5, 5)) = 0
        _OutlineDistortTexYSpeed ("描边扭曲纹理Y速度", Range(-5, 5)) = 0
        [Toggle(_OUTLINE_SIMPLE_NOISE)]_OutlineSimpleNoise ("使用简单噪声", float) = 0
        _OutlineNoiseScale ("噪声缩放", Range(0, 100)) = 1.0

        // [Header(Shadow)]
        // [Space]
        [Toggle(_SHADOW_ON)]_Shadow ("开启阴影效果", float) = 0
        _ShadowX ("阴影X偏移", Range(-1, 1)) = 0.0
        _ShadowY ("阴影Y偏移", Range(-1, 1)) = 0.0
        _ShadowAlpha ("阴影透明度", Range(0, 1)) = 0.5

        

        // [Header(Dissolve)]
        // [Space]
        [Toggle(_DISSOLVE_ON)]_Dissolve ("开启溶解效果", float) = 0
        _DissolveAmount ("溶解强度", Range(0, 1)) = 0.5
        _DissolveEdge ("溶解边缘", Range(0, 1)) = 0.1
        _DissolveColor ("溶解颜色", Color) = (1, 1, 1, 1)
        _DissolveTex ("溶解纹理", 2D) = "black" { }
        [Toggle(_DISSOLVE_SIMPLE_NOISE)]_DissolveSimpleNoise ("使用简单噪声", float) = 0
        _DissolveNoiseScale ("噪声缩放", Range(0, 100)) = 1.0

        [HideInInspector]_Cutoff ("Alpha Cutoff", Range(0.0, 1.0)) = 0.5

    }
    SubShader
    {
        Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Lit" }
        LOD 300
 
        Pass
        {
            Name "ForwardLit"
            Tags { "LightMode" = "UniversalForward" }
            Blend One Zero, One Zero
            ZWrite On
            Cull[_Cull]
            AlphaToMask On
 
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma shader_feature_local  _RECEIVESHADOWS_ON
            #pragma shader_feature_local  _ALPHATEST_ON
            #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
            #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
            #pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
            #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH

            #pragma shader_feature_local _ISUNLIT_ON
            #pragma shader_feature_local _HUE_SHIFT_ON
            #pragma shader_feature_local _FISHEYE_ON
            #pragma shader_feature_local _HANDDRAWN_ON
            #pragma shader_feature_local _WAVE_ON
            #pragma shader_feature_local _TWIST_ON
            #pragma shader_feature_local _PINCH_ON
            #pragma shader_feature_local _PIXEL_ON
            #pragma shader_feature_local _DISTORT_ON
            #pragma shader_feature_local _DISTORT_SIMPLE_NOISE
            #pragma shader_feature_local _GLITCH_ON
            #pragma shader_feature_local _GLOW_ON
            #pragma shader_feature_local _GLOW_SIMPLE_NOISE
            #pragma shader_feature_local _INNERLINE_ON
            #pragma shader_feature_local _OUTLINE_ON
            #pragma shader_feature_local _OUTLINE_SIMPLE_NOISE
            #pragma shader_feature_local _DISSOLVE_ON
            #pragma shader_feature_local _TIKTOK_ON
            #pragma shader_feature_local _DISSOLVE_SIMPLE_NOISE
            #pragma shader_feature_local _SHADOW_ON

            #define UNIVERSAL_PIPELINE

            #ifdef _HUE_SHIFT_ON
                #define CustomEffect_HueShift
            #endif

            #ifdef _FISHEYE_ON
                #define CustomEffect_FishEye
            #endif
            #ifdef _HANDDRAWN_ON
                #define CustomEffect_HandDraw
            #endif
            #ifdef _WAVE_ON
                #define CustomEffect_Wave
            #endif
            #ifdef _TWIST_ON
                #define CustomEffect_Twist
            #endif
            #ifdef _PINCH_ON
                #define CustomEffect_Pinch
            #endif

            #ifdef _PIXEL_ON
                #define CustomEffect_Pixel
            #endif
            #ifdef _DISTORT_ON
                #define CustomEffect_Distort
                #ifdef _DISTORT_SIMPLE_NOISE
                    #define Distort_SimpleProcedural_Noise
                #endif
            #endif
            #ifdef _GLITCH_ON
                #define CustomEffect_Glitch
            #endif

            #ifdef _TIKTOK_ON
                #define CustomEffect_TikTok
            #endif

            #ifdef _GLOW_ON
                #define CustomEffect_Glow
                #ifdef _GLOW_SIMPLE_NOISE
                    #define Glow_SimpleProcedural_Noise
                #endif
            #endif

            #ifdef _INNERLINE_ON
                #define CustomEffect_InnerLine
            #endif
            

            #ifdef _OUTLINE_ON
                #define CustomEffect_Outline
                #ifdef _OUTLINE_SIMPLE_NOISE
                    #define Outline_SimpleProcedural_Noise
                #endif
            #endif

            #ifdef _DISSOLVE_ON
                #define CustomEffect_Dissolve
                #ifdef _DISSOLVE_SIMPLE_NOISE
                    #define Dissolve_SimpleProcedural_Noise
                #endif
            #endif
            #ifdef _SHADOW_ON
                #define CustomEffect_Shadow
            #endif


            #ifdef _DISTORT_ON
                #ifndef _DISTORT_SIMPLE_NOISE
                    TEXTURE2D(_DistortTex);
                    SAMPLER(sampler_DistortTex);
                #endif
            #endif

            #ifdef _GLOW_ON
                TEXTURE2D(_GlowTex);
                #ifndef _GLOW_SIMPLE_NOISE
                    TEXTURE2D(_GlowDistortTex);
                    SAMPLER(sampler_GlowDistortTex);
                #endif
            #endif



            #ifdef _OUTLINE_ON
                #ifndef _OUTLINE_SIMPLE_NOISE
                    TEXTURE2D(_OutlineDistortTex);
                    SAMPLER(sampler_OutlineDistortTex);
                #endif
            #endif

            #ifdef _DISSOLVE_ON
                #ifndef _DISSOLVE_SIMPLE_NOISE
                    TEXTURE2D(_DissolveTex);
                    SAMPLER(sampler_DissolveTex);
                #endif
            #endif
 
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"
            #include "Assets/2dshader/Shader/Universal2DCustomEffectFunctions.hlsl"
            
            TEXTURE2D(_MainTex);
            SAMPLER(sampler_MainTex);


            CBUFFER_START(UnityPerMaterial)
                half _Cutoff;
                float4 _MainTex_ST;
                float4 _MainTex_TexelSize;

                float _HsvShift;
                float _HsvSaturation;
                float _HsvBright;

                float _FishEyeDistortIntensity;
                float _FishEyeScaleIntensity;
                
                float _HandDrawnAmount;
                float _HandDrawnSpeed;
                
                float _WaveAmount;
                float _WaveSpeed;
                float _WaveStrength;
                float _WaveX;
                float _WaveY;
                
                float _TwistAmount;
                float _TwistRadius;
                
                float _PinchAmount;

                float _PixelateSize;
                
                float _DistortAmount;
                float _DistortTexXSpeed;
                float _DistortTexYSpeed;
                float4 _DistortTex_ST;
                float _NoiseScale;
                
                float _GlitchAmount;
                float _GlitchSize;
                
                float _TikTokAmount;
                float _TikTokAlpha;
                
                half4 _GlowColor;
                float _GlowIntensity;
                float _GlowDistortAmount;
                float _GlowDistortTexXSpeed;
                float _GlowDistortTexYSpeed;
                float _GlowNoiseScale;
                float4 _GlowDistortTex_ST;
                
                half4 _InnerLineColor;
                float _InnerOutlineWidth;
                float _InnerLineAlpha;
                float _InnerLineGlow;
                
                half4 _OutlineColor;
                float _OutlineWidth;
                float _OutlineAlpha;
                float _OutlineDistortAmount;
                float _OutlineDistortTexXSpeed;
                float _OutlineDistortTexYSpeed;
                float _OutlineNoiseScale;
                float4 _OutlineDistortTex_ST;
                
                half4 _DissolveColor;
                float _DissolveAmount;
                float _DissolveEdge;
                float _DissolveTexXSpeed;
                float _DissolveTexYSpeed;
                
                float _DissolveNoiseScale;
                float4 _DissolveTex_ST;
                
                float _ShadowX;
                float _ShadowY;
                float _ShadowAlpha;
                

            CBUFFER_END
 
            #ifdef UNITY_DOTS_INSTANCING_ENABLED
                UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)
                UNITY_DOTS_INSTANCED_PROP(float4, _MainColor)
                UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
            #endif
 
            struct Attributes
            {
                float4 positionOS : POSITION;
                float2 texcoord : TEXCOORD0;
                float3 normalOS : NORMAL;
                float4 vertexColor : COLOR;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };
 
            struct Varyings
            {
                float4 positionCS : SV_POSITION;
                float2 uv : TEXCOORD0;
                float3 positionWS : TEXCOORD1;
                float3 normalWS : TEXCOORD2;
                half3 lightColor : COLOR;
                #ifndef _ISUNLIT_ON
                    #ifdef _RECEIVESHADOWS_ON
                        float4 shadowCoord : TEXCOORD3;
                        #ifdef  _ADDITIONAL_LIGHTS
                            float4 shadowMask : TEXCOORD4;
                        #endif
                    #endif
                #endif

                #ifdef _DISTORT_ON
                    float2 uvDistort : TEXCOORD5;
                #endif
                #ifdef _GLOW_ON
                    float2 uvGlowDistort : TEXCOORD6;
                #endif
                #ifdef _OUTLINE_ON
                    float2 uvOutlineDistort : TEXCOORD7;
                    float2 uvOutline : TEXCOORD8;
                #endif
                half4 color : TEXCOORD9;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };
 
 
            Varyings vert(Attributes v)
            {
                Varyings o;
                UNITY_SETUP_INSTANCE_ID(v);
                UNITY_TRANSFER_INSTANCE_ID(v, o);
                o.positionCS = TransformObjectToHClip(v.positionOS.xyz);
                o.positionWS = TransformObjectToWorld(v.positionOS.xyz);
                o.normalWS = TransformObjectToWorldNormal(v.normalOS);
                o.uv = v.texcoord;
                o.lightColor = 0.0;
                o.color=v.vertexColor;

                #ifndef _ISUNLIT_ON
                    #ifdef _RECEIVESHADOWS_ON
                        //光照
                        o.shadowCoord = TransformWorldToShadowCoord(o.positionWS);
    
                        //多光源的阴影
                        #if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON)
                            half4 shadowMask = inputData.shadowMask;
                        #elif !defined(LIGHTMAP_ON)
                            half4 shadowMask = unity_ProbesOcclusion;
                        #else
                            half4 shadowMask = 1.0;
                        #endif
    
                        #if _ADDITIONAL_LIGHTS_VERTEX
                            uint pixelLightCount = GetAdditionalLightsCount();
                            for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex)
                            {
                                Light light = GetAdditionalLight(lightIndex, positionWS, shadowMask);
                                half3 attenuatedLightColor = light.color * light.distanceAttenuation * light.shadowAttenuation;
                                o.lightColor += LightingLambert(attenuatedLightColor, light.direction, o.normalWS);
                            }
                        #elif _ADDITIONAL_LIGHTS
                            o.shadowMask = shadowMask;
                        #endif
                    #else
                        #ifdef _ADDITIONAL_LIGHTS_VERTEX
                            for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex)
                            {
                                Light light = GetAdditionalLight(lightIndex, positionWS);
                                half3 attenuatedLightColor = light.color * light.distanceAttenuation * light.shadowAttenuation;
                                o.lightColor += LightingLambert(attenuatedLightColor, light.direction, o.normalWS);
                            }
                        #endif
                    #endif
                #endif

                #ifdef _DISTORT_ON
                    #ifdef _DISTORT_SIMPLE_NOISE
                        o.uvDistort = DistortUV(o.uv, float2(_DistortTexXSpeed, _DistortTexYSpeed));
                    #else
                        o.uvDistort = DistortUV(o.uv, _DistortTex_ST, float2(_DistortTexXSpeed, _DistortTexYSpeed));
                    #endif
                #endif

                #ifdef _GLOW_ON
                    #ifdef _GLOW_SIMPLE_NOISE
                        o.uvGlowDistort = GlowUV(o.uv, float2(_GlowDistortTexXSpeed, _GlowDistortTexYSpeed));
                    #else
                        o.uvGlowDistort = GlowUV(o.uv, _GlowDistortTex_ST, float2(_GlowDistortTexXSpeed, _GlowDistortTexYSpeed));
                    #endif
                #endif
                #ifdef _OUTLINE_ON
                    #ifdef _OUTLINE_SIMPLE_NOISE
                        o.uvOutlineDistort = OutlineUV(o.uv, float2(_OutlineDistortTexXSpeed, _OutlineDistortTexYSpeed), _MainTex_TexelSize, _OutlineWidth, o.uvOutline);
                    #else
                        o.uvOutlineDistort = OutlineUV(o.uv, _OutlineDistortTex_ST, float2(_OutlineDistortTexXSpeed, _OutlineDistortTexYSpeed), _MainTex_TexelSize, _OutlineWidth, o.uvOutline);
                    #endif
                #endif
                
 
                return o;
            }
 
 
            half4 frag(Varyings i) : SV_Target
            {
                UNITY_SETUP_INSTANCE_ID(i);

                #ifdef _PIXEL_ON
                    PixelUV(_PixelateSize, i.uv);
                #endif

                #ifdef _WAVE_ON
                    Wave(_WaveAmount, _WaveSpeed, _WaveStrength, _WaveX, _WaveY, i.uv);
                #endif

                #ifdef _PINCH_ON
                    Pinch(_PinchAmount, i.uv);
                #endif

                #ifdef _HANDDRAWN_ON
                    HandDraw(_HandDrawnAmount, _HandDrawnSpeed, i.uv);
                #endif
                
                #ifdef _FISHEYE_ON
                    FishEye(_FishEyeDistortIntensity, _FishEyeScaleIntensity, i.uv);
                #endif

                #ifdef _TWIST_ON
                    Twist(_TwistAmount, _TwistRadius, i.uv);
                #endif

                #ifdef _DISTORT_ON
                    #ifdef _DISTORT_SIMPLE_NOISE
                        Distort(i.uvDistort, _DistortAmount, _NoiseScale, i.uv);
                    #else
                        Distort(_DistortTex, sampler_DistortTex, i.uvDistort, _DistortAmount, i.uv);
                    #endif
                #endif

                #ifdef _GLITCH_ON
                    Glitch(_GlitchAmount, _GlitchSize, i.uv);
                #endif

                half4 baseColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv)*i.color;

                #ifdef _HUE_SHIFT_ON
                    HueShift(_HsvShift, _HsvSaturation, _HsvBright, baseColor);
                #endif

                #ifdef _TIKTOK_ON
                    TikTok(baseColor, _MainTex, sampler_MainTex, i.uv, _TikTokAmount, _TikTokAlpha, baseColor);
                #endif

                #ifdef _GLOW_ON
                    #ifdef _GLOW_SIMPLE_NOISE
                        Glow(baseColor, sampler_MainTex, _GlowTex, i.uv, i.uvGlowDistort, _GlowNoiseScale, _GlowDistortAmount, _GlowIntensity, _GlowColor, baseColor);
                    #else
                        Glow(baseColor, sampler_MainTex, _GlowTex, _GlowDistortTex, sampler_GlowDistortTex, i.uv, i.uvGlowDistort, _GlowDistortAmount, _GlowIntensity, _GlowColor, baseColor);
                    #endif
                #endif

                #ifdef _INNERLINE_ON
                    InnerLine(baseColor, _MainTex, sampler_MainTex, _MainTex_TexelSize.xy, i.uv, _InnerOutlineWidth, _InnerLineAlpha, _InnerLineGlow, _InnerLineColor, baseColor);
                #endif

                #ifdef _OUTLINE_ON
                    #ifdef _OUTLINE_SIMPLE_NOISE
                        Outline(baseColor, _MainTex, sampler_MainTex, _OutlineNoiseScale, i.uv, i.uvOutlineDistort, i.uvOutline, _OutlineDistortAmount, _OutlineAlpha, _OutlineColor, baseColor);
                    #else
                        Outline(baseColor, _MainTex, sampler_MainTex, _OutlineDistortTex, sampler_OutlineDistortTex, i.uv, i.uvOutlineDistort, i.uvOutline, _OutlineDistortAmount, _OutlineAlpha, _OutlineColor, baseColor);
                    #endif
                #endif

                
                #ifdef _SHADOW_ON
                    Shadow(baseColor, _MainTex, sampler_MainTex, i.uv, float2(_ShadowX, _ShadowY), _ShadowAlpha, baseColor);
                #endif

                #ifdef _DISSOLVE_ON
                    #ifdef _DISSOLVE_SIMPLE_NOISE
                        Dissolve(baseColor, _DissolveNoiseScale, i.uv, _DissolveAmount, _DissolveEdge, _DissolveColor, baseColor);
                    #else
                        Dissolve(baseColor, _DissolveTex, sampler_DissolveTex, i.uv, _DissolveAmount, _DissolveEdge, _DissolveColor, baseColor);
                    #endif
                #endif
                
                #ifndef _ISUNLIT_ON
                        //光照
                        half3 lightColor = i.lightColor;
                        #ifdef _RECEIVESHADOWS_ON
                            Light main_light = GetMainLight(i.shadowCoord);
                            half3 main_attenuatedLightColor = main_light.color * main_light.distanceAttenuation * main_light.shadowAttenuation;
                            lightColor += LightingLambert(main_attenuatedLightColor, main_light.direction, i.normalWS);
                            #ifdef _ADDITIONAL_LIGHTS
                                uint pixelLightCount = GetAdditionalLightsCount();
                                for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex)
                                {
                                    Light light = GetAdditionalLight(lightIndex, i.positionWS.xyz, i.shadowMask);
                                    half3 attenuatedLightColor = light.color * light.distanceAttenuation * light.shadowAttenuation;
                                    lightColor += LightingLambert(attenuatedLightColor, light.direction, i.normalWS);
                                }
                            #endif
                        #else
                            Light main_light = GetMainLight();
                            half3 main_attenuatedLightColor = main_light.color * main_light.distanceAttenuation * main_light.shadowAttenuation;
                            lightColor += LightingLambert(main_attenuatedLightColor, main_light.direction, i.normalWS);
                            #ifdef _ADDITIONAL_LIGHTS
                                uint pixelLightCount = GetAdditionalLightsCount();
                                for (uint lightIndex = 0u; lightIndex < pixelLightCount; ++lightIndex)
                                {
                                    Light light = GetAdditionalLight(lightIndex, i.positionWS.xyz);
                                    half3 attenuatedLightColor = light.color * light.distanceAttenuation * light.shadowAttenuation;
                                    lightColor += LightingLambert(attenuatedLightColor, light.direction, i.normalWS);
                                }
                            #endif
                        #endif
                        //环境光
                        half3 ambient = half3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);

                #endif
                
                #ifndef _ISUNLIT_ON
                baseColor.rgb *= baseColor.rgb * lightColor + ambient;
                #endif

                #ifdef _ALPHATEST_ON
                    baseColor.a = AlphaDiscard(baseColor.a, _Cutoff);
                #endif
 
                return baseColor;
            }
            ENDHLSL
        }
 
        Pass
        {
            Name "ShadowCaster"
            Tags { "LightMode" = "ShadowCaster" }
 
            // -------------------------------------
            // Render State Commands
            ZWrite On
            ZTest LEqual
            ColorMask 0
            Cull[_Cull]
 
            HLSLPROGRAM
            #pragma target 2.0
 
            // -------------------------------------
            // Shader Stages
            #pragma vertex ShadowPassVertex
            #pragma fragment ShadowPassFragment
 
            // -------------------------------------
            // Material Keywords
            #pragma shader_feature_local _ALPHATEST_ON
            #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
 
            //--------------------------------------
            // GPU Instancing
            #pragma multi_compile_instancing
            #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl"
 
            // -------------------------------------
            // Universal Pipeline keywords
 
            // -------------------------------------
            // Unity defined keywords
            #pragma multi_compile_fragment _ LOD_FADE_CROSSFADE
 
            // This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
            #pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW
 
            // -------------------------------------
            // Includes
            #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
            ENDHLSL
        }
       
    }
 
    FallBack "Hidden/Universal Render Pipeline/FallbackError"
    CustomEditor "CustomEffectGUI"
}

HLSL:

复制代码
#ifndef UNIVERSAL2D_CUSTOMEFFECT_FUNCTIONS_INCLUDED
#define UNIVERSAL2D_CUSTOMEFFECT_FUNCTIONS_INCLUDED

#ifdef UNIVERSAL_PIPELINE
    #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#else
    #include "UnityCG.cginc"
#endif

#if defined(Distort_SimpleProcedural_Noise) || defined(Glow_SimpleProcedural_Noise) || defined(Outline_SimpleProcedural_Noise) || defined(Dissolve_SimpleProcedural_Noise)
    #ifndef Procedural_Noise
        #define Procedural_Noise
    #endif
#endif

//程序化噪声
#ifdef Procedural_Noise
    inline float unity_noise_randomValue(float2 uv)
    {
        return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453);
    }

    inline float unity_noise_interpolate(float a, float b, float t)
    {
        return (1.0 - t) * a + (t * b);
    }

    inline float unity_valueNoise(float2 uv)
    {
        float2 i = floor(uv);
        float2 f = frac(uv);
        f = f * f * (3.0 - 2.0 * f);

        uv = abs(frac(uv) - 0.5);
        float2 c0 = i + float2(0.0, 0.0);
        float2 c1 = i + float2(1.0, 0.0);
        float2 c2 = i + float2(0.0, 1.0);
        float2 c3 = i + float2(1.0, 1.0);
        float r0 = unity_noise_randomValue(c0);
        float r1 = unity_noise_randomValue(c1);
        float r2 = unity_noise_randomValue(c2);
        float r3 = unity_noise_randomValue(c3);

        float bottomOfGrid = unity_noise_interpolate(r0, r1, f.x);
        float topOfGrid = unity_noise_interpolate(r2, r3, f.x);
        float t = unity_noise_interpolate(bottomOfGrid, topOfGrid, f.y);
        return t;
    }
    
    void Unity_SimpleNoise_float(float2 UV, float Scale, out float Out)
    {
        float t = 0.0;

        float freq = pow(2.0, float(0));
        float amp = pow(0.5, float(3 - 0));
        t += unity_valueNoise(float2(UV.x * Scale / freq, UV.y * Scale / freq)) * amp;
        freq = pow(2.0, float(1));
        amp = pow(0.5, float(3 - 1));
        t += unity_valueNoise(float2(UV.x * Scale / freq, UV.y * Scale / freq)) * amp;
        freq = pow(2.0, float(2));
        amp = pow(0.5, float(3 - 2));
        t += unity_valueNoise(float2(UV.x * Scale / freq, UV.y * Scale / freq)) * amp;
        Out = saturate(t);
    }
#endif

//鱼眼
#ifdef CustomEffect_FishEye
    //fishEyeDistortIntensity-鱼眼扭曲强度  default 0.0
    //fishEyeScaleIntensity-鱼眼缩放强度    default 1.0
    //uv-输入UV
    void FishEye(float fishEyeDistortIntensity, float fishEyeScaleIntensity, inout float2 uv)
    {
        float thea = atan2(uv.y - 0.5, uv.x - 0.5);
        float r = length(uv - float2(0.5, 0.5));
        float dis = fishEyeScaleIntensity * r + fishEyeDistortIntensity * pow(r, 3);
        uv.x = 0.5 + dis * cos(thea);
        uv.y = 0.5 + dis * sin(thea);
    }
#endif

//手绘
#ifdef CustomEffect_HandDraw
    //handDrawnAmount-手绘偏移量
    //handDrawnSpeed-手绘变化速度
    //uv-输入UV
    void HandDraw(float handDrawnAmount, float handDrawnSpeed, inout float2 uv)
    {
        float2 tempUV = uv;
        float2 speed = floor(_Time * 20 * handDrawnSpeed);
        tempUV.x = sin((tempUV.x * handDrawnAmount + speed) * 4);
        tempUV.y = cos((tempUV.y * handDrawnAmount + speed) * 4);
        uv = lerp(uv, uv + tempUV, 0.0005 * handDrawnAmount);
    }
#endif

//波浪
#ifdef CustomEffect_Wave
    //waveAmount-波浪数量
    //waveSpeed-波浪速度
    //waveStrength-波浪强度
    //waveX-波浪中心X
    //waveY-波浪中心Y
    //uv-输入UV
    void Wave(float waveAmount, float waveSpeed, float waveStrength, float waveX, float waveY, inout float2 uv)
    {
        float2 uvWave = float2(waveX, waveY) - uv;//得到一个相对于当前像素位置的波浪向量
        uvWave.x *= _ScreenParams.x / _ScreenParams.y;//这里乘以了一个屏幕宽高比的因子,目的是在非方形屏幕上保持波浪的比例
        float angWave = (length(uvWave) * waveAmount) - ((_Time.y * waveSpeed));
        uv = uv + uvWave * sin(angWave) * (waveStrength * 0.001);
    }
#endif

//扭曲
#ifdef CustomEffect_Twist
    //twistAmount-扭曲强度
    //twistRadius-扭曲半径
    //uv-输入UV
    void Twist(float twistAmount, float twistRadius, inout float2 uv)
    {
        float2 tempUv = uv - float2(0.5, 0.5);
        float uv_length = length(tempUv);
        half percent = (twistRadius - uv_length) / (twistRadius + 0.001);//计算每个像素点距离扭曲中心的百分比
        half theta = percent * percent * (2.0 * sin(twistAmount)) * 8;//根据距离百分比计算角度
        half s = sin(theta);//计算出角度对应的正弦值
        half c = cos(theta);//计算出角度对应的余弦值
        half beta = max(sign(twistRadius - uv_length), 0);//根据距离扭曲中心的距离,确定哪些像素点需要进行扭曲
        tempUv = mul(float2x2(c, -s, s, c), tempUv) * beta + float2(0.5, 0.5);
        uv = tempUv;
    }
#endif

//挤压
#ifdef CustomEffect_Pinch
    //pinchAmount-挤压强度
    //uv-输入UV
    void Pinch(float pinchAmount, inout float2 uv)
    {
        half2 centerTiled = half2(0.5, 0.5);
        half2 dP = uv - centerTiled;//计算了当前像素与纹理中心点的向量差
        //length(centerTiled)计算了纹理中心点到原点的距离
        //用π除以这个距离,得到一个比例值,用于控制图像收缩的程度
        //(-_PinchUvAmount + 0.001)是一个用户指定的参数,用于调整收缩的强度
        half pinchInt = (3.141592 / length(centerTiled)) * (-pinchAmount + 0.001);
        //normalize(dP)将向量dP归一化,以确保我们只对方向进行操作,不改变其长度
        //atan(length(dP)*-pinchInt*10.0)计算了每个像素点的角度偏移,这个角度偏移由距离中心点的距离和收缩强度pinchInt决定 atan函数被用于将距离转换为角度
        //* 0.5 / atan(-pinchInt * 5)通过除以另一个arctan函数的结果,来缩放这个角度偏移,以确保在纹理中心点处没有变化
        uv = centerTiled + normalize(dP) * atan(length(dP) * - pinchInt * 10.0) * 0.5 / atan(-pinchInt * 5);
    }
#endif

//扰动 --先使用扭曲uv函数获取扰动uv,再使用扰动函数
#ifdef CustomEffect_Distort
    //程序化噪声,无预处理关键字则使用的是贴图
    #ifdef Distort_SimpleProcedural_Noise
        #ifndef Procedural_Noise
            #define Procedural_Noise
        #endif
        //uv-输入UV
        //distortTexXYSpeed-噪声水平和垂直移动速度
        float2 DistortUV(float2 uv, float2 distortTexXYSpeed)
        {
            float2 uvDistTex = uv;
            uvDistTex.x += (_Time.y * distortTexXYSpeed.x);
            return uvDistTex;
        }
        //uvDistTex-扰动遮罩图的UV
        // distortAmount-扰动强度
        //noiseScale-噪声缩放
        //uv-输入UV
        void Distort(float2 uvDistTex, float distortAmount, float noiseScale, inout float2 uv)
        {
            //根据从噪声图中r进行扭曲强度的计算 -0.5是要将[0,1]映射到[-0.5, 0.5]
            // * 0.2 是为了将扭曲强度控制在合理的范围内,避免过大或过小的扭曲
            half noise = 0;
            Unity_SimpleNoise_float(uvDistTex, noiseScale, noise);
            half distortAmnt = (noise - 0.5) * 0.2 * distortAmount ;
            uv += distortAmnt;
        }
    #else
        //uv-输入UV
        //distortTex_ST-扰动遮罩图的ST
        //distortTexXYSpeed-噪声水平和垂直移动速度
        float2 DistortUV(float2 uv, float4 distortTex_ST, float2 distortTexXYSpeed)
        {
            float2 uvDistTex = uv * distortTex_ST.xy + distortTex_ST.zw;
            uvDistTex.x += (_Time.y * distortTexXYSpeed.x);
            uvDistTex.y += (_Time.y * distortTexXYSpeed.y);
            return uvDistTex;
        }
        #ifdef UNIVERSAL_PIPELINE
            void Distort(Texture2D distortTex, SamplerState sampler_distortTex, float2 uvDistTex, float distortAmount, inout float2 uv)
            {
                half distortAmnt = (SAMPLE_TEXTURE2D(distortTex, sampler_distortTex, uvDistTex).r - 0.5) * 0.2 * distortAmount;
                uv += distortAmnt;
            }
        #else
            //distortTex-扰动遮罩图
            //uvDistTex-扰动遮罩图的UV
            // distortAmount-扰动强度
            //uv-输入UV
            void Distort(sampler2D distortTex, float2 uvDistTex, float distortAmount, inout float2 uv)
            {
                //根据从噪声图中r进行扭曲强度的计算 -0.5是要将[0,1]映射到[-0.5, 0.5]
                // * 0.2 是为了将扭曲强度控制在合理的范围内,避免过大或过小的扭曲
                half distortAmnt = (tex2D(distortTex, uvDistTex).r - 0.5) * 0.2 * distortAmount;
                uv += distortAmnt;
            }
        #endif
    #endif
#endif

//发光 --先使用发光uv函数获取扰动uv,再使用发光函数
#ifdef CustomEffect_Glow
    #ifdef Glow_SimpleProcedural_Noise
        //uv-输入UV
        //distortXYSpeed-噪声水平和垂直移动速度
        float2 GlowUV(float2 uv, float2 distortXYSpeed)
        {
            float2 uvDistTex = uv;
            uvDistTex.x += (_Time.y * distortXYSpeed.x);
            uvDistTex.y += (_Time.y * distortXYSpeed.y);
            return uvDistTex;
        }
        #ifdef UNIVERSAL_PIPELINE
            void Glow(half4 baseColor, SamplerState sampler_baseTex, Texture2D glowTex, float2 uv, float2 uvDistortTex, float noiseScale, float distortAmount, float glowIntensity, half4 glowColor, inout half4 color)
            {
                half noiseValue = 0;
                Unity_SimpleNoise_float(uvDistortTex, noiseScale, noiseValue);
                noiseValue = saturate(noiseValue * distortAmount);

                half4 emssion = SAMPLE_TEXTURE2D(glowTex, sampler_baseTex, uv);
                emssion.rgb *= glowIntensity * glowColor * baseColor.a;
                color.rgb = baseColor.rgb + emssion.rgb * noiseValue;
                color.a = baseColor.a;
            }
        #else
            //baseTex-基础纹理
            //glowTex-发光纹理
            //uv-基础纹理的UV
            //uvDistortTex-扰动遮罩图的UV
            //noiseScale-噪声缩放
            //distortAmount-扰动强度
            //glowIntensity-发光强度
            //glowColor-发光颜色
            //color-输出颜色
            void Glow(half4 baseColor, sampler2D glowTex, float2 uv, float2 uvDistortTex, float noiseScale, float distortAmount, float glowIntensity, fixed4 glowColor, inout half4 color)
            {
                half noiseValue = 0;
                Unity_SimpleNoise_float(uvDistortTex, noiseScale, noiseValue);
                noiseValue = saturate(noiseValue * distortAmount);

                half4 emssion = tex2D(glowTex, uv);
                emssion.rgb *= glowIntensity * glowColor * baseColor.a;
                color.rgb = baseColor.rgb + emssion.rgb * noiseValue;
                color.a = baseColor.a;
            }
        #endif
    #else
        //uv-输入UV
        //distortTex_ST-扰动遮罩图的ST
        //distortXYSpeed-噪声水平和垂直移动速度
        float2 GlowUV(float2 uv, float4 distortTex_ST, float2 distortXYSpeed)
        {
            float2 uvDistTex = uv * distortTex_ST.xy + distortTex_ST.zw;
            uvDistTex.x += (_Time.y * distortXYSpeed.x);
            uvDistTex.y += (_Time.y * distortXYSpeed.y);
            return uvDistTex;
        }
        //baseTex-基础纹理
        //glowTex-发光纹理
        //distortTex-扰动遮罩图
        //uv-基础纹理的UV
        //uvDistortTex-扰动遮罩图的UV
        //distortAmount-扰动强度
        //glowIntensity-发光强度
        //glowColor-发光颜色
        //color-输出颜色
        #ifdef UNIVERSAL_PIPELINE
            void Glow(half4 baseColor, SamplerState sampler_baseTex, Texture2D glowTex, Texture2D distortTex, SamplerState sampler_distortTex, float2 uv, float2 uvDistortTex, float distortAmount, float glowIntensity, half4 glowColor, inout half4 color)
            {
                half noiseValue = saturate(SAMPLE_TEXTURE2D(distortTex, sampler_distortTex, uvDistortTex).r * distortAmount);

                half4 emssion = SAMPLE_TEXTURE2D(glowTex, sampler_baseTex, uv);
                emssion.rgb *= glowIntensity * glowColor.rgb * baseColor.a;
                color.rgb = baseColor.rgb + emssion.rgb * noiseValue;
                color.a = baseColor.a;
            }
        #else
            void Glow(half4 baseColor sampler2D glowTex, sampler2D distortTex, float2 uv, float2 uvDistortTex, float distortAmount, float glowIntensity, half4 glowColor, inout half4 color)
            {
                half noiseValue = saturate(tex2D(distortTex, uvDistortTex).r * distortAmount);

                half4 emssion = tex2D(glowTex, uv);
                emssion.rgb *= glowIntensity * glowColor.rgb * baseColor.a;
                color.rgb = baseColor.rgb + emssion.rgb * noiseValue;
                color.a = baseColor.a;
            }
        #endif
    #endif
#endif

//描边 --先使用描边uv函数获取扰动uv,再使用描边函数
#ifdef CustomEffect_Outline
    #ifdef Outline_SimpleProcedural_Noise
        //uv-输入UV
        //outlineDistortTexXYSpeed-扰动遮罩图的水平和垂直移动速度
        //baseTex_TexelSize-基础纹理的像素尺寸
        //outlinePiexlWidth-描边像素宽度
        //outlineUV-描边的UV
        float2 OutlineUV(float2 uv, float2 outlineDistortTexXYSpeed, float2 baseTex_TexelSize, float outlinePiexlWidth, inout float2 outlineUV)
        {
            float2 uvOutDistTex = uv;
            uvOutDistTex.x += (_Time.y * outlineDistortTexXYSpeed.x);
            uvOutDistTex.y += (_Time.y * outlineDistortTexXYSpeed.y);
            outlineUV = float2(baseTex_TexelSize.x, baseTex_TexelSize.y) * outlinePiexlWidth;
            return uvOutDistTex;
        }
        //baseTex-基础纹理
        //noiseScale-噪声缩放
        //uv-基础纹理的UV
        //uvOutDistTex-扰动遮罩图的UV
        //uvOutline-描边的UV
        //outlineAmount-描边强度
        //outlineAlpha-描边透明度
        //outlineColor-描边颜色
        //color-输出颜色
        #ifdef UNIVERSAL_PIPELINE
            void Outline(half4 baseColor, Texture2D baseTex, SamplerState sampler_baseTex, float noiseScale, float2 uv, float2 uvOutDistTex, float2 uvOutline, float outlineAmount, float outlineAlpha, half4 outlineColor, inout half4 color)
            {
                half noiseValue = 0;
                Unity_SimpleNoise_float(uvOutDistTex, noiseScale, noiseValue);
                uvOutline += noiseValue * outlineAmount;

                float result = 0;
                // 8个方向的偏移向量
                const half2 offsets[8] = {
                    half2(uvOutline.x, 0), // 右
                    half2(-uvOutline.x, 0), // 左
                    half2(0, uvOutline.y), // 上
                    half2(0, -uvOutline.y), // 下
                    half2(uvOutline.x, uvOutline.y), // 右上
                    half2(-uvOutline.x, uvOutline.y), // 左上
                    half2(uvOutline.x, -uvOutline.y), // 右下
                    half2(-uvOutline.x, -uvOutline.y)  // 左下

                };

                [unroll]
                for (int j = 0; j < 8; j++)
                {
                    result += SAMPLE_TEXTURE2D(baseTex, sampler_baseTex, uv + offsets[j]).a;
                }

                result = step(0.05, saturate(result));//边界判定
                result *= (1 - baseColor.a) * outlineAlpha;//控制描边的alpha值

                half4 outline = outlineColor;//描边的颜色
                color = lerp(baseColor, outline, result);//插值采样得到最后的颜色

            }
        #else
            void Outline(half4 baseColor, sampler2D baseTex, float noiseScale, float2 uv, float2 uvOutDistTex, float2 uvOutline, float outlineAmount, float outlineAlpha, half4 outlineColor, inout half4 color)
            {
                half noiseValue = 0;
                Unity_SimpleNoise_float(uvOutDistTex, noiseScale, noiseValue);
                uvOutline += noiseValue * outlineAmount;

                float result = 0;
                // 8个方向的偏移向量
                const half2 offsets[8] = {
                    half2(uvOutline.x, 0), // 右
                    half2(-uvOutline.x, 0), // 左
                    half2(0, uvOutline.y), // 上
                    half2(0, -uvOutline.y), // 下
                    half2(uvOutline.x, uvOutline.y), // 右上
                    half2(-uvOutline.x, uvOutline.y), // 左上
                    half2(uvOutline.x, -uvOutline.y), // 右下
                    half2(-uvOutline.x, -uvOutline.y)  // 左下

                };

                [unroll]
                for (int j = 0; j < 8; j++)
                {
                    result += tex2D(baseTex, uv + offsets[j]).a;
                }

                result = step(0.05, saturate(result));//边界判定
                result *= (1 - baseColor.a) * outlineAlpha;//控制描边的alpha值

                half4 outline = outlineColor;//描边的颜色
                color = lerp(baseColor, outline, result);//插值采样得到最后的颜色

            }
        #endif
    #else
        //uv-输入UV
        //outlineDistortTex_ST-扰动遮罩图的ST
        //outlineDistortTexXYSpeed-扰动遮罩图的水平和垂直移动速度
        //baseTex_TexelSize-基础纹理的像素尺寸
        //outlinePiexlWidth-描边像素宽度
        //outlineUV-描边的UV
        float2 OutlineUV(float2 uv, float4 outlineDistortTex_ST, float2 outlineDistortTexXYSpeed, float2 baseTex_TexelSize, float outlinePiexlWidth, inout float2 outlineUV)
        {
            float2 uvOutDistTex = uv * outlineDistortTex_ST.xy + outlineDistortTex_ST.zw;
            uvOutDistTex.x += (_Time.y * outlineDistortTexXYSpeed.x);
            uvOutDistTex.y += (_Time.y * outlineDistortTexXYSpeed.y);
            outlineUV = float2(baseTex_TexelSize.x, baseTex_TexelSize.y) * outlinePiexlWidth;
            return uvOutDistTex;
        }
        //baseTex-基础纹理
        //outlineDistortTex-扰动遮罩图
        //uv-基础纹理的UV
        //uvOutDistTex-扰动遮罩图的UV
        //uvOutline-描边的UV
        //outlineAmount-描边强度
        //outlineAlpha-描边透明度
        //outlineColor-描边颜色
        //color-输出颜色
        #ifdef UNIVERSAL_PIPELINE
            void Outline(half4 baseColor, Texture2D baseTex, SamplerState sampler_baseTex, Texture2D outlineDistortTex, SamplerState sampler_outlineDistortTex, float2 uv, float2 uvOutDistTex, float2 uvOutline, float outlineAmount, float outlineAlpha, half4 outlineColor, inout half4 color)
            {
                half noiseValue = SAMPLE_TEXTURE2D(outlineDistortTex, sampler_outlineDistortTex, uvOutDistTex).r * outlineAmount;
                uvOutline += noiseValue;

                float result = 0;
                // 8个方向的偏移向量
                const half2 offsets[8] = {
                    half2(uvOutline.x, 0), // 右
                    half2(-uvOutline.x, 0), // 左
                    half2(0, uvOutline.y), // 上
                    half2(0, -uvOutline.y), // 下
                    half2(uvOutline.x, uvOutline.y), // 右上
                    half2(-uvOutline.x, uvOutline.y), // 左上
                    half2(uvOutline.x, -uvOutline.y), // 右下
                    half2(-uvOutline.x, -uvOutline.y)  // 左下

                };

                [unroll]
                for (int j = 0; j < 8; j++)
                {
                    result += SAMPLE_TEXTURE2D(baseTex, sampler_baseTex, uv + offsets[j]).a;
                }

                result = step(0.05, saturate(result));//边界判定
                result *= (1 - baseColor.a) * outlineAlpha;//控制描边的alpha值

                half4 outline = outlineColor;//描边的颜色
                color = lerp(baseColor, outline, result);//插值采样得到最后的颜色

            }
        #else
            void Outline(half4 baseColor, sampler2D baseTex, sampler2D outlineDistortTex, float2 uv, float2 uvOutDistTex, float2 uvOutline, float outlineAmount, float outlineAlpha, half4 outlineColor, inout half4 color)
            {
                half noiseValue = tex2D(outlineDistortTex, uvOutDistTex).r * outlineAmount;
                uvOutline += noiseValue;

                float result = 0;
                // 8个方向的偏移向量
                const half2 offsets[8] = {
                    half2(uvOutline.x, 0), // 右
                    half2(-uvOutline.x, 0), // 左
                    half2(0, uvOutline.y), // 上
                    half2(0, -uvOutline.y), // 下
                    half2(uvOutline.x, uvOutline.y), // 右上
                    half2(-uvOutline.x, uvOutline.y), // 左上
                    half2(uvOutline.x, -uvOutline.y), // 右下
                    half2(-uvOutline.x, -uvOutline.y)  // 左下

                };

                [unroll]
                for (int j = 0; j < 8; j++)
                {
                    result += tex2D(baseTex, uv + offsets[j]).a;
                }

                result = step(0.05, saturate(result));//边界判定
                result *= (1 - baseColor.a) * outlineAlpha;//控制描边的alpha值

                half4 outline = outlineColor;//描边的颜色
                color = lerp(baseColor, outline, result);//插值采样得到最后的颜色

            }
        #endif
    #endif
#endif

//溶解
#ifdef CustomEffect_Dissolve
    #ifdef Dissolve_SimpleProcedural_Noise
        #ifdef UNIVERSAL_PIPELINE
            void Dissolve(half4 baseColor, float noiseScale, float2 uv, float dissolveAmount, float dissolveEdge, half4 dissolveColor, inout half4 color)
            {
                half noise_mask = 0;
                Unity_SimpleNoise_float(uv, noiseScale, noise_mask);
                half noiseValue1 = step(dissolveAmount, noise_mask);
                half noiseValue2 = step(dissolveAmount, noise_mask + dissolveEdge);

                half noiseValue = saturate(noiseValue2 - noiseValue1);
                color.rgb = lerp(baseColor.rgb, dissolveColor.rgb, noiseValue);
                color.a = saturate(baseColor.a * noiseValue2);
            }
        #else
            void Dissolve(half4 baseColor, float noiseScale, float2 uv, float dissolveAmount, float dissolveEdge, half4 dissolveColor, inout half4 color)
            {
                half noise_mask = 0;
                Unity_SimpleNoise_float(uv, noiseScale, noise_mask);
                half noiseValue1 = step(dissolveAmount, noise_mask);
                half noiseValue2 = step(dissolveAmount, noise_mask + dissolveEdge);

                half noiseValue = saturate(noiseValue2 - noiseValue1);
                color.rgb = lerp(baseColor.rgb, dissolveColor.rgb, noiseValue);
                color.a = saturate(baseColor.a * noiseValue2);
            }
        #endif
    #else
        #ifdef UNIVERSAL_PIPELINE
            void Dissolve(half4 baseColor, Texture2D dissolveTex, SamplerState sampler_dissolveTex, float2 uv, float dissolveAmount, float dissolveEdge, half4 dissolveColor, inout half4 color)
            {
                half noise_mask = SAMPLE_TEXTURE2D(dissolveTex, sampler_dissolveTex, uv).r;
                half noiseValue1 = step(dissolveAmount, noise_mask);
                half noiseValue2 = step(dissolveAmount, noise_mask + dissolveEdge);

                half noiseValue = saturate(noiseValue2 - noiseValue1);
                color.rgb = lerp(baseColor.rgb, dissolveColor.rgb, noiseValue);
                color.a = saturate(baseColor.a * noiseValue2);
            }
        #else
            void Dissolve(half4 baseColor, sampler2D dissolveTex, float2 uv, float dissolveAmount, float dissolveEdge, half4 dissolveColor, inout half4 color)
            {
                half noise_mask = tex2D(dissolveTex, uv).r;
                half noiseValue1 = step(dissolveAmount, noise_mask);
                half noiseValue2 = step(dissolveAmount, noise_mask + dissolveEdge);

                half noiseValue = saturate(noiseValue2 - noiseValue1);
                color.rgb = lerp(baseColor.rgb, dissolveColor.rgb, noiseValue);
                color.a = saturate(baseColor.a * noiseValue2);
            }
        #endif
    #endif
#endif

//内描边
#ifdef CustomEffect_InnerLine
    #ifdef UNIVERSAL_PIPELINE
        half3 GetPixel(float2 baseTex_TexelSize, int offsetX, int offsetY, half2 uv, Texture2D tex, SamplerState sampler_tex)
        {
            return SAMPLE_TEXTURE2D(tex, sampler_tex, (uv + half2(offsetX * baseTex_TexelSize.x, offsetY * baseTex_TexelSize.y))).rgb;
        }
        void InnerLine(half4 baseColor, Texture2D baseTex, SamplerState sampler_baseTex, float2 baseTex_TexelSize, float2 uv, float innerLineThickness, float innerLineAlpha, float innerLineGlow, half4 innerLineColor, inout half4 color)
        {
            half3 innerT = abs(GetPixel(baseTex_TexelSize, 0, innerLineThickness, uv, baseTex, sampler_baseTex) - GetPixel(baseTex_TexelSize, 0, -innerLineThickness, uv, baseTex, sampler_baseTex));
            innerT += abs(GetPixel(baseTex_TexelSize, innerLineThickness, 0, uv, baseTex, sampler_baseTex) - GetPixel(baseTex_TexelSize, -innerLineThickness, 0, uv, baseTex, sampler_baseTex));
            innerT = innerT * baseColor.a * innerLineAlpha;
            color.rgb = lerp(baseColor.rgb, innerLineColor.rgb * innerLineGlow, saturate(length(innerT)));
            color.a = baseColor.a;
        }
    #else
        half3 GetPixel(float2 baseTex_TexelSize, int offsetX, int offsetY, half2 uv, sampler2D tex)
        {
            return tex2D(tex, (uv + half2(offsetX * baseTex_TexelSize.x, offsetY * baseTex_TexelSize.y))).rgb;
        }

        //baseTex-基础纹理
        //baseTex_TexelSize-基础纹理的像素尺寸
        //uv-基础纹理的UV
        //innerLineThickness-描边线条的偏差值的判定像素大小
        //innerLineAlpha-描边线条透明度
        //innerLineGlow-描边线条发光程度
        //innerLineColor-描边线条颜色
        //color-输出颜色
        void InnerLine(half4 baseColor, sampler2D baseTex, float2 baseTex_TexelSize, float2 uv, float innerLineThickness, float innerLineAlpha, float innerLineGlow, half4 innerLineColor, inout half4 color)
        {
            half3 innerT = abs(GetPixel(baseTex_TexelSize, 0, innerLineThickness, uv, baseTex) - GetPixel(baseTex_TexelSize, 0, -innerLineThickness, uv, baseTex));
            innerT += abs(GetPixel(baseTex_TexelSize, innerLineThickness, 0, uv, baseTex) - GetPixel(baseTex_TexelSize, -innerLineThickness, 0, uv, baseTex));
            innerT = innerT * baseColor.a * innerLineAlpha;
            color.rgb = lerp(baseColor.rgb, innerLineColor.rgb * innerLineGlow, saturate(length(innerT)));
            color.a = baseColor.a;
        }
    #endif
#endif

//故障
#ifdef CustomEffect_Glitch
    half rand(half2 seed, half offset)
    {
        return (frac(sin(dot(seed * floor(50 + (_Time.y % 1.0) * 12), half2(127.1, 311.7))) * 43758.5453123) + offset) % 1.0;
    }

    void Glitch(float glitchAmount, float glitchSize, inout float2 uv)
    {
        half lineNoise = pow(rand(floor(uv * half2(24, 19) * glitchSize) * 4, 1), 3.0) * glitchAmount
        * pow(rand(floor(uv * half2(38, 14) * glitchSize) * 4, 1), 3.0);
        uv += half2(lineNoise * 0.02 * rand(half2(2.0, 1), 1), 0);
    }
#endif

//阴影
#ifdef CustomEffect_Shadow
    #ifdef UNIVERSAL_PIPELINE
        void Shadow(half4 baseColor, Texture2D baseTex, SamplerState sampler_baseTex, float2 uv, float2 shadowOffset, float shadowAlpha, inout half4 color)
        {
            half shadowA = SAMPLE_TEXTURE2D(baseTex, sampler_baseTex, uv + shadowOffset).a;
            color.rgb = baseColor.rgb;
            color.a = saturate(max(shadowA * shadowAlpha, baseColor.a));
        }
    #else
        void Shadow(half4 baseColor, sampler2D baseTex, float2 uv, float2 shadowOffset, float shadowAlpha, inout half4 color)
        {
            half shadowA = tex2D(baseTex, uv + shadowOffset).a;
            color.rgb = baseColor.rgb;
            color.a = saturate(max(shadowA * shadowAlpha, baseColor.a));
        }
    #endif
#endif
#endif

//色相调整
#ifdef CustomEffect_HueShift
    void HueShift(float hsvShift, float hsvSaturation, float hsvBright, inout half4 baseColor)
    {
        half3 resultHsv = 0.0;
        half cosHsv = hsvBright * hsvSaturation * cos(hsvShift * 3.14159265 / 180);
        half sinHsv = hsvBright * hsvSaturation * sin(hsvShift * 3.14159265 / 180);
        //将原始的H、S、V分量与cosine和sine分量的线性组合得到组合后的H(色调)、S(饱和度)和V(明度) 可以理解为固定的算法
        resultHsv.x = (.299 * hsvBright + .701 * cosHsv + .168 * sinHsv) * baseColor.r
        + (.587 * hsvBright - .587 * cosHsv + .330 * sinHsv) * baseColor.g
        + (.114 * hsvBright - .114 * cosHsv - .497 * sinHsv) * baseColor.b;
        resultHsv.y = (.299 * hsvBright - .299 * cosHsv - .328 * sinHsv) * baseColor.r
        + (.587 * hsvBright + .413 * cosHsv + .035 * sinHsv) * baseColor.g
        + (.114 * hsvBright - .114 * cosHsv + .292 * sinHsv) * baseColor.b;
        resultHsv.z = (.299 * hsvBright - .3 * cosHsv + 1.25 * sinHsv) * baseColor.r
        + (.587 * hsvBright - .588 * cosHsv - 1.05 * sinHsv) * baseColor.g
        + (.114 * hsvBright + .886 * cosHsv - .203 * sinHsv) * baseColor.b;
        baseColor.rgb = resultHsv;
    }
#endif

//TikTok
#ifdef CustomEffect_TikTok
    #ifdef UNIVERSAL_PIPELINE
        void TikTok(half4 baseColor, Texture2D baseTex, SamplerState sampler_baseTex, float2 uv, float tikTokAmount, float tikTokAlpha, inout half4 color)
        {
            half4 r = SAMPLE_TEXTURE2D(baseTex, sampler_baseTex, uv + half2(tikTokAmount * 0.1, 0));
            half4 b = SAMPLE_TEXTURE2D(baseTex, sampler_baseTex, uv + half2(-tikTokAmount * 0.1, 0));
            color = half4(r.r, baseColor.g, b.b, max(max(r.a, b.a) * tikTokAlpha, baseColor.a));
        }
    #else
        void TikTok(half4 baseColor, sampler2D baseTex, float2 uv, float tikTokAmount, float tikTokAlpha, inout half4 color)
        {
            half4 r = tex2D(baseTex, uv + half2(tikTokAmount * 0.1, 0));
            half4 b = tex2D(baseTex, uv + half2(-tikTokAmount * 0.1, 0));
            color = half4(r.r, baseColor.g, b.b, max(max(r.a, b.a) * tikTokAlpha, baseColor.a));
        }
    #endif
#endif

//像素化
#ifdef CustomEffect_Pixel
    void PixelUV(float pixelateSize, inout float2 uv)
    {
        uv = round(uv * pixelateSize) / pixelateSize;
    }
#endif

CustomEditor:

复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class CustomEffectGUI : ShaderGUI
{
    public enum ShaderType
    {
        Lit,
        Unlit
    }
    ShaderType shaderType = ShaderType.Lit;
    [System.Flags]
    public enum EffectType
    {
        None = 0,
        色相调整 = 1 << 0,
        鱼眼 = 1 << 1,
        手绘 = 1 << 2,
        波纹 = 1 << 3,
        扭曲 = 1 << 4,
        挤压 = 1 << 5,
        像素化 = 1 << 6,
        扰动 = 1 << 7,
        故障 = 1 << 8,
        TikTok = 1 << 9,
        发光 = 1 << 10,
        内描边 = 1 << 11,
        外描边 = 1 << 12,
        溶解 = 1 << 13,
        阴影 = 1 << 14
    }

    private EffectType effectType;
    #region UI
    public GUIStyle style = new GUIStyle();
    static bool Foldout(bool display, string title)
    {
        var style = new GUIStyle("ShurikenModuleTitle");
        style.font = new GUIStyle(EditorStyles.boldLabel).font;
        style.border = new RectOffset(15, 7, 4, 4);
        style.fixedHeight = 22;
        style.contentOffset = new Vector2(20f, -2f);
        style.fontSize = 11;
        style.normal.textColor = new Color(0.7f, 0.8f, 0.9f);
        var rect = GUILayoutUtility.GetRect(16f, 25f, style);
        GUI.Box(rect, title, style);

        var e = Event.current;
        var toggleRect = new Rect(rect.x + 4f, rect.y + 2f, 13f, 13f);
        if (e.type == EventType.Repaint)
        {
            EditorStyles.foldout.Draw(toggleRect, false, false, display, false);
        }
        if (e.type == EventType.MouseDown && rect.Contains(e.mousePosition))
        {
            display = !display;
            e.Use();
        }

        return display;
    }
    MaterialEditor m_MaterialEditor;

    // Helpers to sync shader keywords when we toggle effect flags via enum
    private static void SetKeyword(Material mat, string keyword, bool enabled)
    {
        if (enabled) mat.EnableKeyword(keyword);
        else mat.DisableKeyword(keyword);
    }

    private void ApplyTopLevelEffectKeywordsToTargets()
    {
        if (m_MaterialEditor == null || m_MaterialEditor.targets == null) return;
        foreach (var t in m_MaterialEditor.targets)
        {
            var mat = t as Material;
            if (mat == null) continue;

            SetKeyword(mat, "_HUE_SHIFT_ON", mat.GetFloat("_HueShift") > 0.5f);
            SetKeyword(mat, "_FISHEYE_ON", mat.GetFloat("_FishEye") > 0.5f);
            SetKeyword(mat, "_HANDDRAWN_ON", mat.GetFloat("_HandDrawn") > 0.5f);
            SetKeyword(mat, "_WAVE_ON", mat.GetFloat("_Wave") > 0.5f);
            SetKeyword(mat, "_TWIST_ON", mat.GetFloat("_Twist") > 0.5f);
            SetKeyword(mat, "_PINCH_ON", mat.GetFloat("_Pinch") > 0.5f);
            SetKeyword(mat, "_PIXEL_ON", mat.GetFloat("_Pixel") > 0.5f);
            SetKeyword(mat, "_DISTORT_ON", mat.GetFloat("_Distort") > 0.5f);
            SetKeyword(mat, "_GLITCH_ON", mat.GetFloat("_Glitch") > 0.5f);
            SetKeyword(mat, "_TIKTOK_ON", mat.GetFloat("_TikTok") > 0.5f);
            SetKeyword(mat, "_GLOW_ON", mat.GetFloat("_Glow") > 0.5f);
            SetKeyword(mat, "_INNERLINE_ON", mat.GetFloat("_InnerLine") > 0.5f);
            SetKeyword(mat, "_OUTLINE_ON", mat.GetFloat("_Outline") > 0.5f);
            SetKeyword(mat, "_DISSOLVE_ON", mat.GetFloat("_Dissolve") > 0.5f);
            SetKeyword(mat, "_SHADOW_ON", mat.GetFloat("_Shadow") > 0.5f);
        }
    }

    #endregion
    #region  Properties
    MaterialProperty _IsUnlit;
    MaterialProperty _MainTex;
    MaterialProperty _NormalMap;
    MaterialProperty _HueShift;
    MaterialProperty _HsvShift;
    MaterialProperty _HsvSaturation;
    MaterialProperty _HsvBright;
    MaterialProperty _FishEye;
    MaterialProperty _FishEyeDistortIntensity;
    MaterialProperty _FishEyeScaleIntensity;
    MaterialProperty _HandDrawn;
    MaterialProperty _HandDrawnAmount;
    MaterialProperty _HandDrawnSpeed;
    MaterialProperty _Wave;
    MaterialProperty _WaveAmount;
    MaterialProperty _WaveSpeed;
    MaterialProperty _WaveStrength;
    MaterialProperty _WaveX;
    MaterialProperty _WaveY;
    MaterialProperty _Twist;
    MaterialProperty _TwistAmount;
    MaterialProperty _TwistRadius;
    MaterialProperty _Pinch;
    MaterialProperty _PinchAmount;
    MaterialProperty _Pixel;
    MaterialProperty _PixelateSize;
    MaterialProperty _Distort;
    MaterialProperty _DistortAmount;
    MaterialProperty _DistortTexXSpeed;
    MaterialProperty _DistortTexYSpeed;
    MaterialProperty _DistortTex;
    MaterialProperty _DistortSimpleNoise;
    MaterialProperty _NoiseScale;
    MaterialProperty _Glitch;
    MaterialProperty _GlitchAmount;
    MaterialProperty _GlitchSize;
    MaterialProperty _TikTok;
    MaterialProperty _TikTokAmount;
    MaterialProperty _TikTokAlpha;
    MaterialProperty _Glow;
    MaterialProperty _GlowColor;
    MaterialProperty _GlowTex;
    MaterialProperty _GlowIntensity;
    MaterialProperty _GlowDistortAmount;
    MaterialProperty _GlowDistortTex;
    MaterialProperty _GlowDistortTexXSpeed;
    MaterialProperty _GlowDistortTexYSpeed;
    MaterialProperty _GlowSimpleNoise;
    MaterialProperty _GlowNoiseScale;
    MaterialProperty _InnerLine;
    MaterialProperty _InnerLineColor;
    MaterialProperty _InnerOutlineWidth;
    MaterialProperty _InnerLineAlpha;
    MaterialProperty _InnerLineGlow;
    MaterialProperty _Outline;
    MaterialProperty _OutlineColor;
    MaterialProperty _OutlineWidth;
    MaterialProperty _OutlineAlpha;
    MaterialProperty _OutlineDistortAmount;
    MaterialProperty _OutlineDistortTex;
    MaterialProperty _OutlineDistortTexXSpeed;
    MaterialProperty _OutlineDistortTexYSpeed;
    MaterialProperty _OutlineSimpleNoise;
    MaterialProperty _OutlineNoiseScale;
    MaterialProperty _Dissolve;
    MaterialProperty _DissolveAmount;
    MaterialProperty _DissolveEdge;
    MaterialProperty _DissolveColor;
    MaterialProperty _DissolveTex;
    MaterialProperty _DissolveSimpleNoise;
    MaterialProperty _DissolveNoiseScale;
    MaterialProperty _Shadow;
    MaterialProperty _ShadowX;
    MaterialProperty _ShadowY;
    MaterialProperty _ShadowAlpha;

    public bool HueShiftFoldout { get; private set; } = false;
    public bool FishEyeFoldout { get; private set; } = false;
    public bool HandDrawnFoldout { get; private set; } = false;
    public bool WaveFoldout { get; private set; } = false;
    public bool TwistFoldout { get; private set; } = false;
    public bool PinchFoldout { get; private set; } = false;
    public bool PixelFoldout { get; private set; } = false;
    public bool DistortFoldout { get; private set; } = false;
    public bool GlitchFoldout { get; private set; } = false;
    public bool TikTokFoldout { get; private set; } = false;
    public bool GlowFoldout { get; private set; } = false;
    public bool InnerLineFoldout { get; private set; } = false;
    public bool OutlineFoldout { get; private set; } = false;
    public bool DissolveFoldout { get; private set; } = false;
    public bool ShadowFoldout { get; private set; } = false;

    #endregion

    #region FindProperties
    private void Find_HueShiftProperties(MaterialProperty[] properties)
    {
        _HueShift = FindProperty("_HueShift", properties, false);
        _HsvShift = FindProperty("_HsvShift", properties, false);
        _HsvSaturation = FindProperty("_HsvSaturation", properties, false);
        _HsvBright = FindProperty("_HsvBright", properties, false);
    }
    private void Find_FishEyeProperties(MaterialProperty[] properties)
    {
        _FishEye = FindProperty("_FishEye", properties, false);
        _FishEyeDistortIntensity = FindProperty("_FishEyeDistortIntensity", properties, false);
        _FishEyeScaleIntensity = FindProperty("_FishEyeScaleIntensity", properties, false);
    }

    private void Find_HandDrawnProperties(MaterialProperty[] properties)
    {
        _HandDrawn = FindProperty("_HandDrawn", properties, false);
        _HandDrawnAmount = FindProperty("_HandDrawnAmount", properties, false);
        _HandDrawnSpeed = FindProperty("_HandDrawnSpeed", properties, false);
    }

    private void Find_WaveProperties(MaterialProperty[] properties)
    {
        _Wave = FindProperty("_Wave", properties, false);
        _WaveAmount = FindProperty("_WaveAmount", properties, false);
        _WaveSpeed = FindProperty("_WaveSpeed", properties, false);
        _WaveStrength = FindProperty("_WaveStrength", properties, false);
        _WaveX = FindProperty("_WaveX", properties, false);
        _WaveY = FindProperty("_WaveY", properties, false);
    }

    private void Find_TwistProperties(MaterialProperty[] properties)
    {
        _Twist = FindProperty("_Twist", properties, false);
        _TwistAmount = FindProperty("_TwistAmount", properties, false);
        _TwistRadius = FindProperty("_TwistRadius", properties, false);
    }

    private void Find_PinchProperties(MaterialProperty[] properties)
    {
        _Pinch = FindProperty("_Pinch", properties, false);
        _PinchAmount = FindProperty("_PinchAmount", properties, false);
    }
    private void Find_PixelProperties(MaterialProperty[] properties)
    {
        _Pixel = FindProperty("_Pixel", properties, false);
        _PixelateSize = FindProperty("_PixelateSize", properties, false);
    }
    private void Find_DistortProperties(MaterialProperty[] properties)
    {
        _Distort = FindProperty("_Distort", properties, false);
        _DistortAmount = FindProperty("_DistortAmount", properties, false);
        _DistortTexXSpeed = FindProperty("_DistortTexXSpeed", properties, false);
        _DistortTexYSpeed = FindProperty("_DistortTexYSpeed", properties, false);
        _DistortTex = FindProperty("_DistortTex", properties, false);
        _DistortSimpleNoise = FindProperty("_DistortSimpleNoise", properties, false);
        _NoiseScale = FindProperty("_NoiseScale", properties, false);
    }
    private void Find_GlitchProperties(MaterialProperty[] properties)
    {
        _Glitch = FindProperty("_Glitch", properties, false);
        _GlitchAmount = FindProperty("_GlitchAmount", properties, false);
        _GlitchSize = FindProperty("_GlitchSize", properties, false);
    }
    private void Find_TikTokProperties(MaterialProperty[] properties)
    {
        _TikTok = FindProperty("_TikTok", properties, false);
        _TikTokAmount = FindProperty("_TikTokAmount", properties, false);
        _TikTokAlpha = FindProperty("_TikTokAlpha", properties, false);
    }
    private void Find_GlowProperties(MaterialProperty[] properties)
    {
        _Glow = FindProperty("_Glow", properties, false);
        _GlowTex = FindProperty("_GlowTex", properties, false);
        _GlowColor = FindProperty("_GlowColor", properties, false);
        _GlowIntensity = FindProperty("_GlowIntensity", properties, false);
        _GlowDistortAmount = FindProperty("_GlowDistortAmount", properties, false);
        _GlowDistortTex = FindProperty("_GlowDistortTex", properties, false);
        _GlowDistortTexXSpeed = FindProperty("_GlowDistortTexXSpeed", properties, false);
        _GlowDistortTexYSpeed = FindProperty("_GlowDistortTexYSpeed", properties, false);
        _GlowSimpleNoise = FindProperty("_GlowSimpleNoise", properties, false);
        _GlowNoiseScale = FindProperty("_GlowNoiseScale", properties, false);
    }
    private void Find_InnerLineProperties(MaterialProperty[] properties)
    {
        _InnerLine = FindProperty("_InnerLine", properties, false);
        _InnerLineColor = FindProperty("_InnerLineColor", properties, false);
        _InnerOutlineWidth = FindProperty("_InnerOutlineWidth", properties, false);
        _InnerLineAlpha = FindProperty("_InnerLineAlpha", properties, false);
        _InnerLineGlow = FindProperty("_InnerLineGlow", properties, false);
    }

    private void Find_OutlineProperties(MaterialProperty[] properties)
    {
        _Outline = FindProperty("_Outline", properties, false);
        _OutlineColor = FindProperty("_OutlineColor", properties, false);
        _OutlineWidth = FindProperty("_OutlineWidth", properties, false);
        _OutlineAlpha = FindProperty("_OutlineAlpha", properties, false);
        _OutlineDistortAmount = FindProperty("_OutlineDistortAmount", properties, false);
        _OutlineDistortTex = FindProperty("_OutlineDistortTex", properties, false);
        _OutlineDistortTexXSpeed = FindProperty("_OutlineDistortTexXSpeed", properties, false);
        _OutlineDistortTexYSpeed = FindProperty("_OutlineDistortTexYSpeed", properties, false);
        _OutlineSimpleNoise = FindProperty("_OutlineSimpleNoise", properties, false);
        _OutlineNoiseScale = FindProperty("_OutlineNoiseScale", properties, false);
    }
    private void Find_DissolveProperties(MaterialProperty[] properties)
    {
        _Dissolve = FindProperty("_Dissolve", properties, false);
        _DissolveAmount = FindProperty("_DissolveAmount", properties, false);
        _DissolveEdge = FindProperty("_DissolveEdge", properties, false);
        _DissolveColor = FindProperty("_DissolveColor", properties, false);
        _DissolveTex = FindProperty("_DissolveTex", properties, false);
        _DissolveSimpleNoise = FindProperty("_DissolveSimpleNoise", properties, false);
        _DissolveNoiseScale = FindProperty("_DissolveNoiseScale", properties, false);
    }
    private void Find_ShadowProperties(MaterialProperty[] properties)
    {
        _Shadow = FindProperty("_Shadow", properties, false);
        _ShadowX = FindProperty("_ShadowX", properties, false);
        _ShadowY = FindProperty("_ShadowY", properties, false);
        _ShadowAlpha = FindProperty("_ShadowAlpha", properties, false);
    }
    #endregion

    public void FindProperties(MaterialProperty[] properties)
    {
        _IsUnlit = FindProperty("_IsUnlit", properties, false);
        _MainTex = FindProperty("_MainTex", properties, false);
        _NormalMap = FindProperty("_NormalMap", properties, false);

        Find_HueShiftProperties(properties);
        Find_FishEyeProperties(properties);
        Find_HandDrawnProperties(properties);
        Find_WaveProperties(properties);
        Find_TwistProperties(properties);
        Find_PinchProperties(properties);
        Find_PixelProperties(properties);
        Find_DistortProperties(properties);
        Find_GlitchProperties(properties);
        Find_TikTokProperties(properties);
        Find_GlowProperties(properties);
        Find_InnerLineProperties(properties);
        Find_OutlineProperties(properties);
        Find_DissolveProperties(properties);
        Find_ShadowProperties(properties);


    }

    public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
    {
        m_MaterialEditor = materialEditor;
        FindProperties(properties);

        shaderType = _IsUnlit.floatValue > 0.5f ? ShaderType.Unlit : ShaderType.Lit;
        EditorGUI.BeginChangeCheck();
        shaderType = (ShaderType)EditorGUILayout.EnumPopup("光照类型", shaderType);
        if (EditorGUI.EndChangeCheck())
        {
            m_MaterialEditor.RegisterPropertyChangeUndo("Shader Type");
            _IsUnlit.floatValue = shaderType == ShaderType.Unlit ? 1 : 0;

            if (m_MaterialEditor == null || m_MaterialEditor.targets == null) return;
            foreach (var t in m_MaterialEditor.targets)
            {
                var mat = t as Material;
                if (mat == null) continue;
                SetKeyword(mat, "_ISUNLIT_ON", mat.GetFloat("_IsUnlit") > 0.5f);
            }

            m_MaterialEditor.PropertiesChanged();
            m_MaterialEditor.Repaint();
        }



        materialEditor.ShaderProperty(_MainTex, _MainTex.displayName);
        if (shaderType == ShaderType.Lit)
        {
            materialEditor.ShaderProperty(_NormalMap, _NormalMap.displayName);
        }

        EffectType_GUI();
        GUILayout.Space(5);

        if ((effectType & EffectType.色相调整) != 0)
            HueShift_GUI();
        if ((effectType & EffectType.鱼眼) != 0)
            FishEye_GUI();
        if ((effectType & EffectType.手绘) != 0)
            HandDrawn_GUI();
        if ((effectType & EffectType.波纹) != 0)
            Wave_GUI();
        if ((effectType & EffectType.扭曲) != 0)
            Twist_GUI();
        if ((effectType & EffectType.挤压) != 0)
            Pinch_GUI();
        if ((effectType & EffectType.像素化) != 0)
            Pixel_GUI();
        if ((effectType & EffectType.扰动) != 0)
            Distort_GUI();
        if ((effectType & EffectType.故障) != 0)
            Glitch_GUI();
        if ((effectType & EffectType.TikTok) != 0)
            TikTok_GUI();
        if ((effectType & EffectType.发光) != 0)
            Glow_GUI();
        if ((effectType & EffectType.内描边) != 0)
            InnerLine_GUI();
        if ((effectType & EffectType.外描边) != 0)
            Outline_GUI();
        if ((effectType & EffectType.溶解) != 0)
            Dissolve_GUI();
        if ((effectType & EffectType.阴影) != 0)
            Shadow_GUI();
    }

    #region  GUI

    private void EffectType_GUI()
    {
        effectType = EffectType.None;
        if (_HueShift.floatValue > 0) effectType |= EffectType.色相调整;
        if (_FishEye.floatValue > 0) effectType |= EffectType.鱼眼;
        if (_HandDrawn.floatValue > 0) effectType |= EffectType.手绘;
        if (_Wave.floatValue > 0) effectType |= EffectType.波纹;
        if (_Twist.floatValue > 0) effectType |= EffectType.扭曲;
        if (_Pinch.floatValue > 0) effectType |= EffectType.挤压;
        if (_Pixel.floatValue > 0) effectType |= EffectType.像素化;
        if (_Distort.floatValue > 0) effectType |= EffectType.扰动;
        if (_Glitch.floatValue > 0) effectType |= EffectType.故障;
        if (_TikTok.floatValue > 0) effectType |= EffectType.TikTok;
        if (_Glow.floatValue > 0) effectType |= EffectType.发光;
        if (_InnerLine.floatValue > 0) effectType |= EffectType.内描边;
        if (_Outline.floatValue > 0) effectType |= EffectType.外描边;
        if (_Dissolve.floatValue > 0) effectType |= EffectType.溶解;
        if (_Shadow.floatValue > 0) effectType |= EffectType.阴影;

        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
        EditorGUI.BeginChangeCheck();
        effectType = (EffectType)EditorGUILayout.EnumFlagsField("效果类型", effectType);
        if (EditorGUI.EndChangeCheck())
        {
            m_MaterialEditor.RegisterPropertyChangeUndo("Effect Type");
            _HueShift.floatValue = (effectType & EffectType.色相调整) != 0 ? 1 : 0;
            _FishEye.floatValue = (effectType & EffectType.鱼眼) != 0 ? 1 : 0;
            _HandDrawn.floatValue = (effectType & EffectType.手绘) != 0 ? 1 : 0;
            _Wave.floatValue = (effectType & EffectType.波纹) != 0 ? 1 : 0;
            _Twist.floatValue = (effectType & EffectType.扭曲) != 0 ? 1 : 0;
            _Pinch.floatValue = (effectType & EffectType.挤压) != 0 ? 1 : 0;
            _Pixel.floatValue = (effectType & EffectType.像素化) != 0 ? 1 : 0;
            _Distort.floatValue = (effectType & EffectType.扰动) != 0 ? 1 : 0;
            _Glitch.floatValue = (effectType & EffectType.故障) != 0 ? 1 : 0;
            _TikTok.floatValue = (effectType & EffectType.TikTok) != 0 ? 1 : 0;
            _Glow.floatValue = (effectType & EffectType.发光) != 0 ? 1 : 0;
            _InnerLine.floatValue = (effectType & EffectType.内描边) != 0 ? 1 : 0;
            _Outline.floatValue = (effectType & EffectType.外描边) != 0 ? 1 : 0;
            _Dissolve.floatValue = (effectType & EffectType.溶解) != 0 ? 1 : 0;
            _Shadow.floatValue = (effectType & EffectType.阴影) != 0 ? 1 : 0;

            ApplyTopLevelEffectKeywordsToTargets();

            m_MaterialEditor.PropertiesChanged();
            m_MaterialEditor.Repaint();
        }
        EditorGUILayout.EndVertical();
    }

    private void HueShift_GUI()
    {
        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
        HueShiftFoldout = Foldout(HueShiftFoldout, "色相调整");
        if (HueShiftFoldout)
        {
            EditorGUI.indentLevel++;
            m_MaterialEditor.ShaderProperty(_HsvShift, _HsvShift.displayName);
            m_MaterialEditor.ShaderProperty(_HsvSaturation, _HsvSaturation.displayName);
            m_MaterialEditor.ShaderProperty(_HsvBright, _HsvBright.displayName);
            EditorGUI.indentLevel--;
        }
        EditorGUILayout.EndVertical();
    }

    private void FishEye_GUI()
    {
        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
        FishEyeFoldout = Foldout(FishEyeFoldout, "鱼眼效果");
        if (FishEyeFoldout)
        {
            EditorGUI.indentLevel++;
            m_MaterialEditor.ShaderProperty(_FishEyeDistortIntensity, _FishEyeDistortIntensity.displayName);
            m_MaterialEditor.ShaderProperty(_FishEyeScaleIntensity, _FishEyeScaleIntensity.displayName);
            EditorGUI.indentLevel--;
        }
        EditorGUILayout.EndVertical();
    }

    private void HandDrawn_GUI()
    {
        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
        HandDrawnFoldout = Foldout(HandDrawnFoldout, "手绘效果");
        if (HandDrawnFoldout)
        {
            EditorGUI.indentLevel++;
            m_MaterialEditor.ShaderProperty(_HandDrawnAmount, _HandDrawnAmount.displayName);
            m_MaterialEditor.ShaderProperty(_HandDrawnSpeed, _HandDrawnSpeed.displayName);
            EditorGUI.indentLevel--;
        }
        EditorGUILayout.EndVertical();
    }

    private void Wave_GUI()
    {
        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
        WaveFoldout = Foldout(WaveFoldout, "波浪效果");
        if (WaveFoldout)
        {
            EditorGUI.indentLevel++;
            m_MaterialEditor.ShaderProperty(_WaveAmount, _WaveAmount.displayName);
            m_MaterialEditor.ShaderProperty(_WaveSpeed, _WaveSpeed.displayName);
            m_MaterialEditor.ShaderProperty(_WaveStrength, _WaveStrength.displayName);
            m_MaterialEditor.ShaderProperty(_WaveX, _WaveX.displayName);
            m_MaterialEditor.ShaderProperty(_WaveY, _WaveY.displayName);
            EditorGUI.indentLevel--;
        }
        EditorGUILayout.EndVertical();
    }

    private void Twist_GUI()
    {
        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
        TwistFoldout = Foldout(TwistFoldout, "扭曲效果");
        if (TwistFoldout)
        {
            EditorGUI.indentLevel++;
            m_MaterialEditor.ShaderProperty(_TwistAmount, _TwistAmount.displayName);
            m_MaterialEditor.ShaderProperty(_TwistRadius, _TwistRadius.displayName);
            EditorGUI.indentLevel--;
        }
        EditorGUILayout.EndVertical();
    }
    private void Pinch_GUI()
    {
        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
        PinchFoldout = Foldout(PinchFoldout, "挤压效果");
        if (PinchFoldout)
        {
            EditorGUI.indentLevel++;
            m_MaterialEditor.ShaderProperty(_PinchAmount, _PinchAmount.displayName);
            EditorGUI.indentLevel--;
        }
        EditorGUILayout.EndVertical();
    }

    private void Pixel_GUI()
    {
        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
        PixelFoldout = Foldout(PixelFoldout, "像素化效果");
        if (PixelFoldout)
        {
            EditorGUI.indentLevel++;
            m_MaterialEditor.ShaderProperty(_PixelateSize, _PixelateSize.displayName);
            EditorGUI.indentLevel--;
        }
        EditorGUILayout.EndVertical();
    }
    private void Distort_GUI()
    {
        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
        DistortFoldout = Foldout(DistortFoldout, "扰动效果");
        if (DistortFoldout)
        {
            EditorGUI.indentLevel++;
            m_MaterialEditor.ShaderProperty(_DistortSimpleNoise, _DistortSimpleNoise.displayName);
            if (_DistortSimpleNoise.floatValue == 0)
            {
                m_MaterialEditor.ShaderProperty(_DistortTex, _DistortTex.displayName);
            }
            else
            {
                m_MaterialEditor.ShaderProperty(_NoiseScale, _NoiseScale.displayName);
            }
            m_MaterialEditor.ShaderProperty(_DistortAmount, _DistortAmount.displayName);
            m_MaterialEditor.ShaderProperty(_DistortTexXSpeed, _DistortTexXSpeed.displayName);
            m_MaterialEditor.ShaderProperty(_DistortTexYSpeed, _DistortTexYSpeed.displayName);
            EditorGUI.indentLevel--;
        }
        EditorGUILayout.EndVertical();
    }

    private void Glitch_GUI()
    {
        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
        GlitchFoldout = Foldout(GlitchFoldout, "故障效果");
        if (GlitchFoldout)
        {
            EditorGUI.indentLevel++;
            m_MaterialEditor.ShaderProperty(_GlitchAmount, _GlitchAmount.displayName);
            m_MaterialEditor.ShaderProperty(_GlitchSize, _GlitchSize.displayName);
            EditorGUI.indentLevel--;
        }
        EditorGUILayout.EndVertical();
    }
    private void TikTok_GUI()
    {
        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
        TikTokFoldout = Foldout(TikTokFoldout, "TikTok效果");
        if (TikTokFoldout)
        {
            EditorGUI.indentLevel++;
            m_MaterialEditor.ShaderProperty(_TikTokAmount, _TikTokAmount.displayName);
            m_MaterialEditor.ShaderProperty(_TikTokAlpha, _TikTokAlpha.displayName);
            EditorGUI.indentLevel--;
        }
        EditorGUILayout.EndVertical();
    }
    private void Glow_GUI()
    {
        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
        GlowFoldout = Foldout(GlowFoldout, "发光效果");
        if (GlowFoldout)
        {
            EditorGUI.indentLevel++;
            m_MaterialEditor.ShaderProperty(_GlowSimpleNoise, _GlowSimpleNoise.displayName);
            m_MaterialEditor.ShaderProperty(_GlowTex, _GlowTex.displayName);
            if (_GlowSimpleNoise.floatValue == 0)
            {
                m_MaterialEditor.ShaderProperty(_GlowDistortTex, _GlowDistortTex.displayName);
            }
            else
            {
                m_MaterialEditor.ShaderProperty(_GlowNoiseScale, _GlowNoiseScale.displayName);
            }
            m_MaterialEditor.ShaderProperty(_GlowColor, _GlowColor.displayName);
            m_MaterialEditor.ShaderProperty(_GlowIntensity, _GlowIntensity.displayName);
            m_MaterialEditor.ShaderProperty(_GlowDistortAmount, _GlowDistortAmount.displayName);
            m_MaterialEditor.ShaderProperty(_GlowDistortTexXSpeed, _GlowDistortTexXSpeed.displayName);
            m_MaterialEditor.ShaderProperty(_GlowDistortTexYSpeed, _GlowDistortTexYSpeed.displayName);
            EditorGUI.indentLevel--;
        }
        EditorGUILayout.EndVertical();
    }
    private void InnerLine_GUI()
    {
        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
        InnerLineFoldout = Foldout(InnerLineFoldout, "内描边效果");
        if (InnerLineFoldout)
        {
            EditorGUI.indentLevel++;
            m_MaterialEditor.ShaderProperty(_InnerLineColor, _InnerLineColor.displayName);
            m_MaterialEditor.ShaderProperty(_InnerOutlineWidth, _InnerOutlineWidth.displayName);
            m_MaterialEditor.ShaderProperty(_InnerLineAlpha, _InnerLineAlpha.displayName);
            m_MaterialEditor.ShaderProperty(_InnerLineGlow, _InnerLineGlow.displayName);
            EditorGUI.indentLevel--;
        }
        EditorGUILayout.EndVertical();
    }
    private void Outline_GUI()
    {
        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
        OutlineFoldout = Foldout(OutlineFoldout, "描边效果");
        if (OutlineFoldout)
        {
            EditorGUI.indentLevel++;
            m_MaterialEditor.ShaderProperty(_OutlineSimpleNoise, _OutlineSimpleNoise.displayName);
            if (_OutlineSimpleNoise.floatValue == 0)
            {
                m_MaterialEditor.ShaderProperty(_OutlineDistortTex, _OutlineDistortTex.displayName);
            }
            else
            {
                m_MaterialEditor.ShaderProperty(_OutlineNoiseScale, _OutlineNoiseScale.displayName);
            }
            m_MaterialEditor.ShaderProperty(_OutlineColor, _OutlineColor.displayName);
            m_MaterialEditor.ShaderProperty(_OutlineWidth, _OutlineWidth.displayName);
            m_MaterialEditor.ShaderProperty(_OutlineAlpha, _OutlineAlpha.displayName);
            m_MaterialEditor.ShaderProperty(_OutlineDistortAmount, _OutlineDistortAmount.displayName);
            m_MaterialEditor.ShaderProperty(_OutlineDistortTexXSpeed, _OutlineDistortTexXSpeed.displayName);
            m_MaterialEditor.ShaderProperty(_OutlineDistortTexYSpeed, _OutlineDistortTexYSpeed.displayName);
            EditorGUI.indentLevel--;
        }
        EditorGUILayout.EndVertical();
    }
    private void Dissolve_GUI()
    {
        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
        DissolveFoldout = Foldout(DissolveFoldout, "溶解效果");
        if (DissolveFoldout)
        {
            EditorGUI.indentLevel++;
            m_MaterialEditor.ShaderProperty(_DissolveSimpleNoise, _DissolveSimpleNoise.displayName);
            if (_DissolveSimpleNoise.floatValue == 0)
            {
                m_MaterialEditor.ShaderProperty(_DissolveTex, _DissolveTex.displayName);
            }
            else
            {
                m_MaterialEditor.ShaderProperty(_DissolveNoiseScale, _DissolveNoiseScale.displayName);
            }
            m_MaterialEditor.ShaderProperty(_DissolveColor, _DissolveColor.displayName);
            m_MaterialEditor.ShaderProperty(_DissolveAmount, _DissolveAmount.displayName);
            m_MaterialEditor.ShaderProperty(_DissolveEdge, _DissolveEdge.displayName);
            EditorGUI.indentLevel--;
        }
        EditorGUILayout.EndVertical();
    }
    private void Shadow_GUI()
    {
        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
        ShadowFoldout = Foldout(ShadowFoldout, "阴影效果");
        if (ShadowFoldout)
        {
            EditorGUI.indentLevel++;
            m_MaterialEditor.ShaderProperty(_ShadowX, _ShadowX.displayName);
            m_MaterialEditor.ShaderProperty(_ShadowY, _ShadowY.displayName);
            m_MaterialEditor.ShaderProperty(_ShadowAlpha, _ShadowAlpha.displayName);
            EditorGUI.indentLevel--;
        }
        EditorGUILayout.EndVertical();
    }
    #endregion
}
相关推荐
璞瑜无文3 小时前
Unity 游戏开发之方块随机生成(三)
java·unity·游戏引擎
联系QQ 19226384 小时前
PEM电解槽Simulink模型,得出I-V曲线图,通过调参可以分析各参数对电解电压的影响。 ...
着色器
uuleaf4 小时前
26键打字训练小游戏:键盘练习游戏合集
游戏·计算机外设·编程打字
wanhengidc4 小时前
云计算环境中的数据安全防护策略
运维·服务器·科技·游戏·智能手机·云计算
NueXini4 小时前
Unity 3D MMO RPG手游征服2GB设备之历程
3d·unity·性能优化·游戏引擎·优化·rpg·mmo
煮粥侠_995 小时前
做RPG游戏时在对话的excel配置表中使用富文本
游戏·unity
_Cherry|18 小时前
Unity按钮动态效果
unity·游戏引擎
_Cherry|19 小时前
Unity读取文件夹内容
unity·c#
lrh302520 小时前
Custom SRP - 15 Particles
unity·渲染管线·粒子·srp·扰动效果