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"
}
}
静态图没这么丑..不知道咋压缩的..