Unity中一个节点实现植物动态(Shader)

1 . 核心思路就操作顶点作往复运动;

核心代码:

half  stage1 = dot(positionOS, float3(0, 1, 0)) * _Strength;
half  stage2 = sin(dot(positionOS, float3(1, 0, 0)) * _Strength + _Time.y * _Speed);
half  stage3 = stage1 * stage2 * float3(0.001, 0, 0.001);

PositionVar  = stage3 + positionOS;

至于下面的贴图采样这些不重要,除非你需要特别指定顶点哪部分动,哪部分不需要动,你可以采样一个贴图和顶点作Mask操作;

以前在URP管线中也写过,一并发出来:

Shader "Common/Tree_Simple"
{
    Properties
    {   
        [MaterialEnum(Off,0,Front,1,Back,2)] _Cull("Cull", Int) = 2
        _BaseColor("Base Color",color) = (1,1,1,1)
        _MainTex("Base (RGB) Trans (A)", 2D) = "white" {}
        [Normal]_BumpMap("Normal Map", 2D) = "bump" {}
        _NormalScale("NormalPow", Range(0,2)) = 1.0

        _Metallic("Metallic", Range(0.0, 1.0)) = 0.0
        _Roughness("Roughness", Range(0.0, 1.0)) = 0.0

        [Header(Mask)]
        [KeywordEnum(CLIP,ALPHA_TO_MASK)]ClipSwitch("Clip / AlphaToMask)",Float) = 0
        _Cutoff("Alpha Cutoff", Range(0,1)) = 0.333

        [Header(Y_Color)]       //对顶点进行X轴和Y轴上的偏移
        [KeywordEnum(YES,NO)]LEAF("是否树叶(渐变色开关)?",Float) = 1
        _Strength("摇摆幅度", Float) = 1
        _Speed("摇摆速度", Float) = 3
        _BaseColorMaskHeight("BaseColorMaskHeight",Range(0,1)) = 0.5 
        _BaseColorTop("BaseColorTop",Color) = (1,1,1,1)
        _BaseColorBottom("BaseColorBottom",Color) = (0,0,0,1)

        [Header(Shadow)]
        _ShadowMainColor("接受阴影颜色", color) = (0.25,0.25,0.25,1)

        [Toggle(_KALOS_G_FACTOR_ON)] _Kalos_G_Factor ("Optimize with Kalos G Factor", Int) = 1 

    }
 
    SubShader
    {
        Tags {"LightMode" = "UniversalForward" "RenderPipeline" = "UniversalPipeline" }
        LOD 100
        Cull [_Cull]
        AlphaToMask On
 
        Pass
        {
            Name "Unlit"
            HLSLPROGRAM
            // Required to compile gles 2.0 with standard srp library
            #pragma prefer_hlslcc gles
            #pragma exclude_renderers d3d11_9x
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog

            #pragma shader_feature _ _KALOS_G_FACTOR_ON

            #pragma multi_compile CLIPSWITCH_CLIP CLIPSWITCH_ALPHA_TO_MASK
            #pragma multi_compile LEAF_YES LEAF_NO

            //光照贴图这一坨别丢了,不然移动端不显示
            #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
            #pragma multi_compile _ SHADOWS_SHADOWMASK
            #pragma multi_compile _ DIRLIGHTMAP_COMBINED
            #pragma multi_compile _ LIGHTMAP_ON
            #pragma multi_compile _ DYNAMICLIGHTMAP_ON	

            // URP 软阴影
            #pragma multi_compile_fragment _ _SHADOWS_SOFT
            // URP 主光阴影、联机阴影、屏幕空间阴影//
            #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN

            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
            #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.core/ShaderLibrary/UnityInstancing.hlsl"

            #include "PBRMath.hlsl"

            CBUFFER_START(UnityPerMaterial)
            half4  _BaseColor; half _NormalScale , _Metallic,_Roughness;
            float4 _MainTex_ST,_BumpMap_ST;
            float  _bakedGIBlend,_bakedGIPow,_Cutoff;
            half4  _ShadowMainColor;     half4 _BaseColorBottom,_BaseColorTop;
            half  _BaseColorMaskHeight , _Speed , _Strength;
            CBUFFER_END
            TEXTURE2D (_MainTex);SAMPLER(sampler_MainTex);
            TEXTURE2D (_BumpMap);SAMPLER(sampler_BumpMap);
 
            struct VertexInput
            {
                float4 positionOS       : POSITION;
                float2 uv               : TEXCOORD0;
				float4 normalOS         : NORMAL;
				float4 tangentOS        : TANGENT;
                float2 uvLM             : TEXCOORD1;        //光照贴图三件套
                float4 color            : COLOR0;
            };
 
            struct VertexOutput
            {
                float4 position       : SV_POSITION;
                float4 uv               : TEXCOORD0;
				float3 positionWS       :  TEXCOORD1;
				float3 normalWS         : TEXCOORD2;
				float3 tangentWS        : TEXCOORD3;
				float3 bitangentWS      : TEXCOORD4;
                float  fogCoord         : TEXCOORD5;
                float2 uvLM             : TEXCOORD6;        //光照贴图三件套
                float3 vertexSH         : TEXCOORD7;        //光照贴图三件套
                float4 color            : TEXCOORD8;
            };
            
            half3 Saturation(half3 finalCol, half Saturation)
            {
                half   gray        = 0.2125 * finalCol.r + 0.7154 * finalCol.g + 0.0721 * finalCol.b;
                half3  grayColor   = half3(gray, gray, gray);
                return lerp(grayColor, finalCol, Saturation);
            }
 
            VertexOutput vert(VertexInput v)
            {
                VertexOutput o = (VertexOutput)0;

                //--------------树叶飘动------------------------
                half  stage1 = dot(v.positionOS.xyz, float3(0, 1, 0)) * _Strength;
                half  stage2 = sin(dot(v.positionOS.xyz, float3(1, 0, 0)) * _Strength + _Time.y * _Speed);
                half3 stage3 = stage1 * stage2 * float3(0.001, 0, 0.001) * v.color.a; 
                //------------------End---------------------------- 

				VertexPositionInputs positionInputs = GetVertexPositionInputs(v.positionOS.xyz + stage3);
                o.position = positionInputs.positionCS;
				o.positionWS = positionInputs.positionWS; 

				VertexNormalInputs normalInputs = GetVertexNormalInputs(v.normalOS.xyz,v.tangentOS);
				o.normalWS = normalInputs.normalWS;
				o.tangentWS = normalInputs.tangentWS;
				o.bitangentWS = normalInputs.bitangentWS;

                o.uv.xy = TRANSFORM_TEX(v.uv, _MainTex);
                o.uv.zw = TRANSFORM_TEX(v.uv, _BumpMap);

                OUTPUT_LIGHTMAP_UV(v.uvLM, unity_LightmapST, o.uvLM);         //光照贴图三件套  
                //o.position = TransformObjectToHClip(v.positionOS.xyz);
                o.fogCoord = ComputeFogFactor(o.position.z);
 
                return o;
            }
 
            half4 frag(VertexOutput i) : SV_Target
            {
                //阴影
				float4 SHADOW_COORDS = TransformWorldToShadowCoord(i.positionWS.xyz);
				Light  lightDirectional     = GetMainLight(SHADOW_COORDS);
				half   shadow        = lightDirectional.shadowAttenuation;

                //贴图采样
                float4 MainTex      = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv.xy);
                half4  normalTXS    = SAMPLE_TEXTURE2D(_BumpMap,sampler_BumpMap,i.uv.xy);

                float3 normalMap    = UnpackNormalScale(normalTXS,_NormalScale);
                real3x3 TBN         = real3x3(i.tangentWS, i.bitangentWS, i.normalWS);    //追求高精度
                half3 normalWS      = TransformTangentToWorld(normalMap,TBN);

                //向量准备
                half3 N = normalWS;
                half3 L = normalize(lightDirectional.direction);
                half3 V = SafeNormalize(_WorldSpaceCameraPos - i.positionWS);
                half3 H = normalize(L + V);

                //点积
                half  HdotL = max(dot(H, L), 1e-5);
                half  NdotV = max(dot(N, V), 1e-5);         
                half  HdotN = max(dot(H, N), 1e-5);
                half  NdotL = dot(N,L);

                half3 R     = reflect( -L , N );
                half  VdotR = dot ( V , R );

                NdotL = lerp(NdotL*0.5+0.5,max(dot(N, L), 1e-5),0.75);  //这个是我个人喜好!

                //PBR参数准备 
                half3 Albedo        = MainTex.rgb; 
                half  occlusion     = MainTex.g;

                half  roughness     = normalTXS.a;
                half  smoothness    = (1 - roughness/_Roughness);      //计算待定

                half  metallic      = normalTXS.a * _Metallic;
                half3 F0            = Direct_F0_Function(Albedo, metallic);
                half3 Direct_F      = Direct_F_Function(HdotL, F0);

                //----// 直线光漫反射
                half3 KS = Direct_F;
                half3 KD = (1 - KS) * (1 - metallic);
                half3 DirectDiffColor = KD * Albedo * lightDirectional.color * NdotL;

                // 镜面反射
                half Direct_D = Direct_D_Function(HdotN, roughness);

                //----// BRDF
                #if defined(_KALOS_G_FACTOR_ON)
                        half Direct_G = Direct_G_Function_Kalos(HdotL, roughness);
                #else
                        half Direct_G = Direct_G_Function(NdotL, NdotV, roughness);
                #endif

                #if defined(_KALOS_G_FACTOR_ON)
                        half3 BRDFSpecSection = (Direct_D * Direct_G) * Direct_F / (4 * HdotL);
                #else
                        half3 BRDFSpecSection = (Direct_D * Direct_G) * Direct_F / (4 * NdotL * NdotV);
                #endif

                half3 DirectSpeColor = BRDFSpecSection * lightDirectional.color * (NdotL * PI * occlusion);

                // 第一部分(直线光照结果):实时或者烘焙
                //-------光照贴图-------------//
                #ifdef LIGHTMAP_ON
                half3 bakedGI = SAMPLE_GI(i.uvLM, i.vertexSH, N);        //光照贴图三件套
                      bakedGI = lerp(half3(1,1,1),pow( abs(bakedGI),_bakedGIPow),_bakedGIBlend);
                      half3 DirectColor = bakedGI*Albedo;
                #else
                half3 DirectColor = DirectDiffColor + DirectSpeColor;
                #endif
            
                // 第二部分:间接漫反射
                half3 shColor       = SH_IndirectionDiff(N) * occlusion;
                half3 Indirect_KS   = Indirect_F_Function(NdotV, F0, roughness);
                half3 Indirect_KD   = (1 - Indirect_KS) * (1 - metallic);
                half3 IndirectDiffColor = shColor * Indirect_KD * Albedo;
                
                // 间接反射
                //----// 反射探针的间接光
                half3 IndirectSpeCubeColor  = IndirectSpeCube(N, V, roughness, occlusion); 
                half3 IndirectSpeCubeFactor = IndirectSpeFactor(roughness, smoothness, BRDFSpecSection, F0, NdotV); 
                half3 IndirectSpeColor      = IndirectSpeCubeColor *IndirectSpeCubeFactor; 

                //----//间接漫反射 + 间接反射
                    //魔改金属表现
                    half  k = 1;  //探针强度
                    IndirectSpeColor = IndirectSpeColor * k; 
                    //-------//魔改金属表现
                    IndirectSpeColor.rgb = Saturation(IndirectSpeColor, k*metallic);
                    IndirectSpeColor.rgb = IndirectSpeColor.rgb + IndirectSpeColor.rgb*metallic*(k);
                half3 IndirectColor = IndirectDiffColor + IndirectSpeColor; 
                           

                //----//

                //----------------直接光漫射 + 间接光漫射(间接光反射) ------------------------------------
                half3 Col       = DirectColor + IndirectColor;      
                //-------------------------------------------------------------------------------------
                //--树叶Y方向颜色渐变(球形法线特性)--//LEAF_YES LEAF_NO
                #ifdef LEAF_YES
                float3 albedoMask = i.normalWS.y;
                albedoMask = albedoMask/2+0.5;
                albedoMask*=_BaseColorMaskHeight;
                albedoMask= smoothstep(0,1,albedoMask);
                half3 albedoMaskCol = lerp(_BaseColorBottom.rgb,_BaseColorTop.rgb,albedoMask);
                
                Col *= albedoMaskCol;
                #elif LEAF_NO

                #endif       

                      Col       = Col * _BaseColor.rgb;
                      Col       = MixFog(Col.rgb, i.fogCoord);

                      Col       = lerp(_ShadowMainColor.rgb * Col, Col, shadow); 

                #ifdef CLIPSWITCH_CLIP
                half  Alpha     = 1;
                clip(MainTex.a-_Cutoff);
                #elif  CLIPSWITCH_ALPHA_TO_MASK
                half  Alpha     = MainTex.a;
                #endif
                
                half4 finalCol  = half4(Col,Alpha);
                return finalCol;
            }
            ENDHLSL
        }

        UsePass "Universal Render Pipeline/Lit/ShadowCaster"

        UsePass "Universal Render Pipeline/Lit/Meta"

        UsePass "Universal Render Pipeline/Lit/DepthOnly" 
    }
}

静态图没这么丑..不知道咋压缩的..

相关推荐
软件黑马王子1 小时前
Unity游戏制作中的C#基础(6)方法和类的知识点深度剖析
开发语言·游戏·unity·c#
虾球xz7 小时前
游戏引擎学习第117天
学习·游戏引擎
程序猿多布7 小时前
Unity 位图字体
unity
千年奇葩9 小时前
Unity shader glsl着色器特效之 模拟海面海浪效果
unity·游戏引擎·着色器
太妃糖耶11 小时前
Unity摄像机与灯光相关知识
unity·游戏引擎
007_rbq11 小时前
XUnity.AutoTranslator-Gemini——调用Google的Gemini API, 实现Unity游戏中日文文本的自动翻译
人工智能·python·游戏·机器学习·unity·github·机器翻译
万兴丶12 小时前
Unity 适用于单机游戏的红点系统(前缀树 | 数据结构 | 设计模式 | 算法 | 含源码)
数据结构·unity·设计模式·c#
软件黑马王子20 小时前
Unity游戏制作中的C#基础(5)条件语句和循环语句知识点全解析
游戏·unity·c#
程序趣谈1 天前
UE5中按钮圆角,设置边框
ue5·游戏引擎