215 lines
6.9 KiB
Plaintext
215 lines
6.9 KiB
Plaintext
Shader "NLD_URP/NLD_Scene_Grass"
|
|
{
|
|
Properties
|
|
{
|
|
[MainTexture]_BaseMap ("主贴图", 2D) = "white" {}
|
|
[MainColor] _BaseColor("基础颜色", Color) = (1, 1, 1, 1)
|
|
_Cutoff("Alpha裁剪", Range(0.0, 1.0)) = 0.5
|
|
|
|
_GroundColorTex ("地面颜色贴图", 2D) = "white" {}
|
|
_GroundSize("地面大小(宽,高,融合高度)", Vector) = (50, 50, 0, 0)
|
|
|
|
_WindNoiseTex ("风噪声贴图", 2D) = "white" {}
|
|
_WindParams("风参数(XUV,YUV,摆动min,摆动max)", Vector) = (0.1, 0.1, 0, 0)
|
|
_WindDirection("风向(风向xyz,风贴图强度缩放)", Vector) = (1, 0, 0, 0)
|
|
|
|
_TimeScale("自然摆动时间缩放", Range(0, 1)) = 1
|
|
|
|
_WindColor("风颜色", Color) = (1, 1, 1, 1)
|
|
_WindColorParams("风颜色参数(压亮,截取min,截取max)", Vector) = (0.8, 0.2, 1, 0)
|
|
|
|
_ShadowIntensity("阴影强度", Range(0, 1)) = 1
|
|
|
|
[Toggle(USE_HALF_PRECISION)] _UseHalfPrecision("使用half", Float) = 0
|
|
}
|
|
SubShader
|
|
{
|
|
Tags {
|
|
"RenderType"="Transparent"
|
|
"RenderPipeline" = "UniversalPipeline"
|
|
}
|
|
LOD 100
|
|
|
|
HLSLINCLUDE
|
|
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
|
|
|
TEXTURE2D(_BaseMap);
|
|
SAMPLER(sampler_BaseMap);
|
|
|
|
TEXTURE2D(_GroundColorTex);
|
|
SAMPLER(sampler_GroundColorTex);
|
|
|
|
sampler2D _WindNoiseTex;
|
|
|
|
|
|
struct Attributes_LT {
|
|
float4 positionOS : POSITION;
|
|
float2 uv : TEXCOORD0;
|
|
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct Varyings_LT {
|
|
float4 positionCS : SV_POSITION;
|
|
|
|
float2 uv : TEXCOORD0;
|
|
|
|
float4 worldPosAndGroundU : TEXCOORD1;
|
|
|
|
float2 windNoiseAndGroundV : TEXCOORD2;
|
|
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
#if !defined(UNITY_INSTANCING_ENABLED)
|
|
CBUFFER_START(UnityPerMaterial)
|
|
#endif
|
|
float _Cutoff;
|
|
float4 _BaseColor;
|
|
float4 _GroundSize;
|
|
float4 _WindParams;
|
|
float4 _WindDirection;
|
|
|
|
float _TimeScale;
|
|
|
|
float4 _BaseMap_ST;
|
|
float4 _GroundColorTex_ST;
|
|
float4 _WindNoiseTex_ST;
|
|
float4 _WindColor;
|
|
float4 _WindColorParams;
|
|
float _ShadowIntensity;
|
|
#if !defined(UNITY_INSTANCING_ENABLED)
|
|
CBUFFER_END
|
|
#endif
|
|
|
|
#ifdef USE_HALF_PRECISION
|
|
#define GRASS_FLOAT half
|
|
#define GRASS_FLOAT2 half2
|
|
#define GRASS_FLOAT3 half3
|
|
#define GRASS_FLOAT4 half4
|
|
#else
|
|
#define GRASS_FLOAT float
|
|
#define GRASS_FLOAT2 float2
|
|
#define GRASS_FLOAT3 float3
|
|
#define GRASS_FLOAT4 float4
|
|
#endif
|
|
|
|
Varyings_LT Vert(Attributes_LT input)
|
|
{
|
|
Varyings_LT output = (Varyings_LT)0;
|
|
UNITY_SETUP_INSTANCE_ID(input);
|
|
UNITY_TRANSFER_INSTANCE_ID(input, output);
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
|
|
|
|
float3 worldPos = TransformObjectToWorld(input.positionOS.xyz);
|
|
|
|
float2 groundStartPos = _GroundSize.xy * -0.5;
|
|
float2 groundUV = (worldPos.xz - groundStartPos) * rcp(_GroundSize.xy);
|
|
|
|
float2 windUv = groundUV + _Time.y * _WindParams.xy;
|
|
float2 windUvWrap = windUv * _WindNoiseTex_ST.xy + _WindNoiseTex_ST.zw;
|
|
|
|
float windNoise = tex2Dlod(_WindNoiseTex, float4(windUvWrap, 0, 0)).r;
|
|
|
|
float lerpProgress = saturate((worldPos.y - _WindParams.z) * rcp(_WindParams.w - _WindParams.z));
|
|
|
|
float windPhase = (windNoise * _WindDirection.w + _TimeScale * _Time.y) * 6.28318530718;
|
|
float3 moveDt = _WindDirection.xyz * (lerpProgress * sin(windPhase));
|
|
worldPos += moveDt;
|
|
|
|
output.positionCS = TransformWorldToHClip(worldPos);
|
|
output.uv = input.uv * _BaseMap_ST.xy + _BaseMap_ST.zw;
|
|
output.worldPosAndGroundU = float4(worldPos, groundUV.x);
|
|
output.windNoiseAndGroundV = float2(windNoise, groundUV.y);
|
|
return output;
|
|
}
|
|
|
|
ENDHLSL
|
|
|
|
Pass
|
|
{
|
|
Cull Off
|
|
Name "ForwardLit"
|
|
Tags {
|
|
"LightMode" = "UniversalForward"
|
|
}
|
|
ZWrite On
|
|
ZTest LEqual
|
|
|
|
HLSLPROGRAM
|
|
#pragma target 3.0
|
|
#pragma vertex Vert
|
|
#pragma fragment Frag
|
|
|
|
#pragma multi_compile_instancing
|
|
|
|
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
|
|
#pragma multi_compile _ _SHADOWS_SOFT
|
|
#pragma shader_feature_local USE_HALF_PRECISION
|
|
|
|
float4 Frag(Varyings_LT input): SV_Target
|
|
{
|
|
|
|
GRASS_FLOAT4 baseColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv);
|
|
clip(baseColor.a - _Cutoff);
|
|
|
|
GRASS_FLOAT2 groundUV = GRASS_FLOAT2(input.worldPosAndGroundU.w, input.windNoiseAndGroundV.y);
|
|
GRASS_FLOAT4 groundColor = SAMPLE_TEXTURE2D(_GroundColorTex, sampler_GroundColorTex, groundUV);
|
|
|
|
GRASS_FLOAT4 grassColor = _BaseColor;
|
|
|
|
GRASS_FLOAT windNoise = input.windNoiseAndGroundV.x;
|
|
GRASS_FLOAT windMask = saturate((windNoise - _WindColorParams.y) * rcp(_WindColorParams.z - _WindColorParams.y));
|
|
GRASS_FLOAT windColorStrength = windNoise * windNoise * _WindColorParams.x;
|
|
grassColor = lerp(grassColor, _WindColor, windMask * windColorStrength);
|
|
|
|
GRASS_FLOAT3 worldPos = input.worldPosAndGroundU.xyz;
|
|
GRASS_FLOAT lerpProgress = saturate(worldPos.y * rcp(_GroundSize.z));
|
|
GRASS_FLOAT4 lerpColor = lerp(groundColor, grassColor, lerpProgress);
|
|
|
|
|
|
float4 shadowCoord = TransformWorldToShadowCoord(worldPos);
|
|
Light mainLight = GetMainLight(shadowCoord);
|
|
GRASS_FLOAT shadowStrength = lerp(1, mainLight.shadowAttenuation, _ShadowIntensity);
|
|
lerpColor.rgb *= shadowStrength;
|
|
|
|
return lerpColor;
|
|
}
|
|
ENDHLSL
|
|
}
|
|
|
|
Pass
|
|
{
|
|
Cull Off
|
|
Name "ShadowCaster"
|
|
Tags
|
|
{
|
|
"LightMode" = "ShadowCaster"
|
|
}
|
|
|
|
HLSLPROGRAM
|
|
#pragma target 3.0
|
|
#pragma vertex Vert
|
|
#pragma fragment Frag
|
|
|
|
#pragma multi_compile_instancing
|
|
|
|
float4 Frag(Varyings_LT input): SV_Target
|
|
{
|
|
|
|
float4 baseColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv);
|
|
clip(baseColor.a - _Cutoff);
|
|
return float4(1, 1, 1, 1);
|
|
}
|
|
|
|
|
|
ENDHLSL
|
|
|
|
}
|
|
|
|
}
|
|
}
|