当前位置: 首页 > article >正文

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" 
    }
}

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


http://www.kler.cn/a/560778.html

相关文章:

  • Linux | UDP Socket 编程(C++ 基础demo)
  • Java 集合框架大师课:集合流式编程革命(三)
  • C++双指针:算法优化的“左右互搏术”与高效问题破解全指南
  • 【HeadFirst系列之HeadFirst设计模式】第8天之适配器模式与外观模式:让不兼容的接口和谐共处!
  • 服务器租用的价格受哪些因素影响?
  • Kafka面试题----如何保证Kafka消费者在消费过程中不丢失消息
  • 深入理解 Kafka 主题分区机制
  • 基于 Python 和 Django 的文本情感分析系统设计与实现
  • 计算机毕业设计SpringBoot+Vue.js网上租赁系统(源码+文档+PPT+讲解)
  • 微相E316实现FM电台监听
  • DirectX12(D3D12)基础教程三 线性代数与3D世界空间
  • istio介绍补充以及使用篇
  • Python常见面试题的详解21
  • 【前端开发】能不能用Vue+Bootstrap进行项目开发?有什么需求场景需要用到的地方
  • 一周学会Flask3 Python Web开发-Jinja2模板访问对象
  • 云原生时代的分布式文件系统设计与实现
  • 如何查看PostgreSQL的版本
  • Macos ./ollama目录说明
  • overflow-x: auto 使用鼠标实现横向滚动,区分触摸板和鼠标滚动事件的方法
  • angular简易计算器