206 lines
6.6 KiB
HLSL
206 lines
6.6 KiB
HLSL
|
|
|
|||
|
|
// Vertex Functions
|
|||
|
|
|
|||
|
|
float2 _WindMultiplier;
|
|||
|
|
half2 _MinMaxScales;
|
|||
|
|
fixed4 _HealthyColor;
|
|||
|
|
fixed4 _DryColor;
|
|||
|
|
half _NormalBend;
|
|||
|
|
half _WindLOD;
|
|||
|
|
|
|||
|
|
CBUFFER_START(AtgGrass)
|
|||
|
|
float4 _AtgWindDirSize;
|
|||
|
|
float4 _AtgWindStrengthMultipliers;
|
|||
|
|
float2 _AtgSinTime;
|
|||
|
|
float4 _AtgGrassFadeProps;
|
|||
|
|
float4 _AtgGrassShadowFadeProps;
|
|||
|
|
|
|||
|
|
float3 _AtgSurfaceCameraPosition;
|
|||
|
|
CBUFFER_END
|
|||
|
|
sampler2D _AtgWindRT;
|
|||
|
|
float4 _AtgTerrainShiftSurface;
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
#if !defined(DEPTHNORMAL)
|
|||
|
|
struct Input {
|
|||
|
|
float2 uv_MainTex;
|
|||
|
|
float facingSign : VFACE;
|
|||
|
|
fixed3 color;
|
|||
|
|
float3 worldNormal;
|
|||
|
|
INTERNAL_DATA
|
|||
|
|
};
|
|||
|
|
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
|
|||
|
|
StructuredBuffer<float4x4> GrassMatrixBuffer;
|
|||
|
|
#endif
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
// Simple random function
|
|||
|
|
inline float nrand(float2 pos) {
|
|||
|
|
//return frac(sin(dot(pos, half2(12.9898f, 78.233f))) * 43758.5453f);
|
|||
|
|
return frac((dot(pos, half2(12.9898f, 78.233f))) );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Our vertex function which handles wind and culling
|
|||
|
|
#if !defined(DEPTHNORMAL)
|
|||
|
|
void vertfoliage(inout appdata_full v, out Input o) {
|
|||
|
|
UNITY_INITIALIZE_OUTPUT(Input, o);
|
|||
|
|
#else
|
|||
|
|
void vertfoliage(inout appdata_full v, in float InstanceScale) {
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
// Scale contains some perlin noise – so we use it to add any perlin noise based variation
|
|||
|
|
//float3 unitvec = mul( (float3x3 )unity_ObjectToWorld, float3(1,0,0)); // float4 would be 0,1,0, 0 !!!!!
|
|||
|
|
//float scale = length( unitvec );
|
|||
|
|
float scale = InstanceScale;
|
|||
|
|
|
|||
|
|
float3 pivot = float3(unity_ObjectToWorld[0].w, unity_ObjectToWorld[1].w, unity_ObjectToWorld[2].w);
|
|||
|
|
float3 dist = pivot
|
|||
|
|
//+ scale.xxx * 4 /* lets break up the boring distance*/
|
|||
|
|
#if defined(DONOTUSE_ATGSETUP)
|
|||
|
|
- _WorldSpaceCameraPos.xyz; // vs shader version
|
|||
|
|
#elif !defined(UNITY_PROCEDURAL_INSTANCING_ENABLED)
|
|||
|
|
- _WorldSpaceCameraPos.xyz; // for wind setup
|
|||
|
|
#else
|
|||
|
|
- _AtgSurfaceCameraPosition.xyz; // atg original shader: we have to use a custom cam pos to make it match compute.
|
|||
|
|
#endif
|
|||
|
|
float SqrDist = dot(dist, dist);
|
|||
|
|
|
|||
|
|
// Calculate far fade factor
|
|||
|
|
#if defined (UNITY_PASS_SHADOWCASTER)
|
|||
|
|
float fade = 1;
|
|||
|
|
// Depth Pass
|
|||
|
|
if (unity_LightShadowBias.z == 0.0) {
|
|||
|
|
fade = saturate((_AtgGrassFadeProps.x - SqrDist) * _AtgGrassFadeProps.y);
|
|||
|
|
}
|
|||
|
|
// Shadow Pass
|
|||
|
|
else {
|
|||
|
|
fade = saturate((_AtgGrassShadowFadeProps.z - SqrDist) * _AtgGrassShadowFadeProps.w);
|
|||
|
|
}
|
|||
|
|
#else
|
|||
|
|
float fade = saturate((_AtgGrassFadeProps.x - SqrDist) * _AtgGrassFadeProps.y);
|
|||
|
|
#endif
|
|||
|
|
// Cull based on far culling distance
|
|||
|
|
if (fade == 0.0f) {
|
|||
|
|
v.vertex.xyz = 0;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
// Apply fading
|
|||
|
|
v.vertex.xyz = lerp(v.vertex.xyz, float3(0,0,0), (1.0 - fade).xxx); // PS4 lerp
|
|||
|
|
|
|||
|
|
// Instance Color
|
|||
|
|
fixed4 instanceColor = lerp(_HealthyColor, _DryColor, ((scale - _MinMaxScales.x) * _MinMaxScales.y).xxxx ); // PS4 lerp
|
|||
|
|
#if !defined(DEPTHNORMAL)
|
|||
|
|
o.color.rgb = instanceColor.rgb;
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
|
|||
|
|
// Wind
|
|||
|
|
|
|||
|
|
float originalLength = length(v.vertex.xyz);
|
|||
|
|
|
|||
|
|
float3 windDir = UnityWorldToObjectDir(_AtgWindDirSize.xyz);
|
|||
|
|
float4 wind = tex2Dlod(_AtgWindRT, float4(
|
|||
|
|
(
|
|||
|
|
#if defined(_METALLICGLOSSMAP)
|
|||
|
|
pivot.xz
|
|||
|
|
#else
|
|||
|
|
mul(unity_ObjectToWorld, v.vertex).xz
|
|||
|
|
#endif
|
|||
|
|
- instanceColor.a * windDir.xz
|
|||
|
|
)
|
|||
|
|
* _AtgWindDirSize.w + scale * 0.025,
|
|||
|
|
0, _WindLOD ) // _WindLOD lets us smooth the sampling
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
wind.r = wind.r * (wind.g * 2.0f - 0.24376f); // Not a "real" normal as we want to keep the base direction
|
|||
|
|
wind.r *= _AtgWindStrengthMultipliers.y * instanceColor.a;
|
|||
|
|
|
|||
|
|
// If not procedural instanced drawn swap direction?
|
|||
|
|
#if !defined (UNITY_PROCEDURAL_INSTANCING_ENABLED)
|
|||
|
|
wind.r *= -1;
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
const float fDetailAmp = 0.1;
|
|||
|
|
const float fBranchAmp = 0.3;
|
|||
|
|
|
|||
|
|
//float3 variations = abs( frac( pivot.xyz * 3) - 0.5 );
|
|||
|
|
float2 variations = abs(frac( float2(unity_ObjectToWorld[0].x, unity_ObjectToWorld[1].y)));
|
|||
|
|
float fObjPhase = dot(variations, float2(1,1) );
|
|||
|
|
|
|||
|
|
float3 offset = 0;
|
|||
|
|
|
|||
|
|
// Primary bending
|
|||
|
|
offset = v.color.a * windDir * (wind.r * _WindMultiplier.x);
|
|||
|
|
|
|||
|
|
float2 vWavesIn = _Time.yy + float2(0, fObjPhase + (v.color.r + instanceColor.a) );
|
|||
|
|
float4 vWaves = frac( vWavesIn.xxyy * float4(1.975, 0.793, 0.375, 0.193) ) * 2.0 - 1.0;
|
|||
|
|
vWaves = SmoothTriangleWave( vWaves );
|
|||
|
|
float2 vWavesSum = vWaves.xz + vWaves.yw;
|
|||
|
|
// Edge Flutter
|
|||
|
|
float3 bend = v.color.g * fDetailAmp * v.normal.xyz;
|
|||
|
|
// Secondary bending
|
|||
|
|
//bend.y = v.color.b * fBranchAmp;
|
|||
|
|
//bend *= vWavesSum.y * wind.r * _WindMultiplier.y;
|
|||
|
|
//offset += bend;
|
|||
|
|
|
|||
|
|
offset += ((vWavesSum.xyx * bend) + (v.color.b * fBranchAmp * windDir * vWavesSum.y * _WindMultiplier.y)) * wind.r;
|
|||
|
|
|
|||
|
|
// Apply Wind Animation
|
|||
|
|
#if !defined(DEPTHNORMAL)
|
|||
|
|
v.vertex.xyz -= offset;
|
|||
|
|
// Per pixel normalize is applied in lighting function
|
|||
|
|
v.normal.xz -= offset * _NormalBend * UNITY_PI;
|
|||
|
|
#else
|
|||
|
|
v.vertex.xyz += offset;
|
|||
|
|
v.normal.xz += offset * _NormalBend * UNITY_PI;
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
// Non directional "jitter"
|
|||
|
|
float rand = nrand(float2(scale, 1.0 - scale)); // pivot.xz);
|
|||
|
|
#if !defined(DEPTHNORMAL)
|
|||
|
|
v.vertex.xz += lerp(_AtgSinTime.x, _AtgSinTime.y, /*scale*/ rand) * 0.25 * v.color.b * _WindMultiplier.y * saturate(wind.r);
|
|||
|
|
#else
|
|||
|
|
v.vertex.xz -= lerp(_AtgSinTime.x, _AtgSinTime.y, /*scale*/ rand) * 0.25 * v.color.b * _WindMultiplier.y * saturate(wind.r);
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
// Preserve length
|
|||
|
|
v.vertex.xyz = normalize(v.vertex.xyz) * originalLength;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ----------------------------------------------
|
|||
|
|
// Currently unsused functions
|
|||
|
|
|
|||
|
|
void rotate2D(inout float2 v, float r) {
|
|||
|
|
float s, c;
|
|||
|
|
sincos(r, s, c);
|
|||
|
|
v = float2(v.x * c - v.y * s, v.x * s + v.y * c);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// http://answers.unity3d.com/questions/218333/shader-inversefloat4x4-function.html
|
|||
|
|
inline float4x4 inverseMat(float4x4 input) {
|
|||
|
|
#define minor(a,b,c) determinant(float3x3(input.a, input.b, input.c))
|
|||
|
|
float4x4 cofactors = float4x4(
|
|||
|
|
minor(_22_23_24, _32_33_34, _42_43_44),
|
|||
|
|
-minor(_21_23_24, _31_33_34, _41_43_44),
|
|||
|
|
minor(_21_22_24, _31_32_34, _41_42_44),
|
|||
|
|
-minor(_21_22_23, _31_32_33, _41_42_43),
|
|||
|
|
|
|||
|
|
-minor(_12_13_14, _32_33_34, _42_43_44),
|
|||
|
|
minor(_11_13_14, _31_33_34, _41_43_44),
|
|||
|
|
-minor(_11_12_14, _31_32_34, _41_42_44),
|
|||
|
|
minor(_11_12_13, _31_32_33, _41_42_43),
|
|||
|
|
|
|||
|
|
minor(_12_13_14, _22_23_24, _42_43_44),
|
|||
|
|
-minor(_11_13_14, _21_23_24, _41_43_44),
|
|||
|
|
minor(_11_12_14, _21_22_24, _41_42_44),
|
|||
|
|
-minor(_11_12_13, _21_22_23, _41_42_43),
|
|||
|
|
|
|||
|
|
-minor(_12_13_14, _22_23_24, _32_33_34),
|
|||
|
|
minor(_11_13_14, _21_23_24, _31_33_34),
|
|||
|
|
-minor(_11_12_14, _21_22_24, _31_32_34),
|
|||
|
|
minor(_11_12_13, _21_22_23, _31_32_33)
|
|||
|
|
);
|
|||
|
|
#undef minor
|
|||
|
|
return transpose(cofactors) / determinant(input);
|
|||
|
|
}
|