959e80cf72
assets upload description.
181 lines
5.5 KiB
Plaintext
181 lines
5.5 KiB
Plaintext
BEGIN_OPTIONS
|
|
ShaderName "AwesomeTechnologies/Development/Trees/VertexWind"
|
|
Stackable "True"
|
|
END_OPTIONS
|
|
|
|
BEGIN_PROPERTIES
|
|
_InitialBend("Wind Initial Bend", Float) = 1
|
|
_Stiffness("Wind Stiffness", Float) = 1
|
|
_Drag("Wind Drag", Float) = 1
|
|
_ShiverDrag("Wind Shiver Drag", Float) = 0.05
|
|
_WindNormalInfluence("Wind Normal Influence", Float) = 0
|
|
END_PROPERTIES
|
|
|
|
BEGIN_DEFINES
|
|
#define FLT_EPSILON 1.192092896e-07
|
|
END_DEFINES
|
|
|
|
BEGIN_CODE
|
|
|
|
sampler2D WIND_SETTINGS_TexNoise;
|
|
sampler2D WIND_SETTINGS_TexGust;
|
|
|
|
float _InitialBend;
|
|
float _Stiffness;
|
|
float _Drag;
|
|
float _ShiverDrag;
|
|
float _ShiverDirectionality;
|
|
float _WindNormalInfluence;
|
|
float4 _NewNormal;
|
|
|
|
float4 WIND_SETTINGS_WorldDirectionAndSpeed;
|
|
float WIND_SETTINGS_FlexNoiseScale;
|
|
float WIND_SETTINGS_ShiverNoiseScale;
|
|
float WIND_SETTINGS_Turbulence;
|
|
float WIND_SETTINGS_GustSpeed;
|
|
float WIND_SETTINGS_GustScale;
|
|
float WIND_SETTINGS_GustWorldScale;
|
|
|
|
float PositivePow_(float base, float power)
|
|
{
|
|
return pow(max(abs(base), float(FLT_EPSILON)), power);
|
|
}
|
|
|
|
float AttenuateTrunk_(float x, float s)
|
|
{
|
|
float r = (x / s);
|
|
return PositivePow_(r,1/s);
|
|
}
|
|
|
|
float3 Rotate_(float3 pivot, float3 position, float3 rotationAxis, float angle)
|
|
{
|
|
rotationAxis = normalize(rotationAxis);
|
|
float3 cpa = pivot + rotationAxis * dot(rotationAxis, position - pivot);
|
|
return cpa + ((position - cpa) * cos(angle) + cross(rotationAxis, (position - cpa)) * sin(angle));
|
|
}
|
|
|
|
struct WindData_
|
|
{
|
|
float3 Direction;
|
|
float Strength;
|
|
float3 ShiverStrength;
|
|
float3 ShiverDirection;
|
|
float Gust;
|
|
};
|
|
|
|
float3 texNoise_(float3 worldPos, float LOD)
|
|
{
|
|
return tex2Dlod(WIND_SETTINGS_TexNoise,float4(worldPos.xz,0,LOD)).xyz -0.5;
|
|
}
|
|
|
|
float texGust_(float3 worldPos, float LOD)
|
|
{
|
|
return tex2Dlod(WIND_SETTINGS_TexGust, float4(worldPos.xz,0, LOD)).x;
|
|
}
|
|
|
|
WindData_ GetAnalyticalWind(float3 WorldPosition, float3 PivotPosition, float drag, float shiverDrag, float initialBend, float4 time)
|
|
{
|
|
WindData_ result;
|
|
float3 normalizedDir = normalize(WIND_SETTINGS_WorldDirectionAndSpeed.xyz);
|
|
|
|
float3 worldOffset = normalizedDir * WIND_SETTINGS_WorldDirectionAndSpeed.w * time.y;
|
|
float3 gustWorldOffset = normalizedDir * WIND_SETTINGS_GustSpeed * time.y;
|
|
|
|
// Trunk noise is base wind + gusts + noise
|
|
|
|
float3 trunk = float3(0,0,0);
|
|
|
|
if(WIND_SETTINGS_WorldDirectionAndSpeed.w > 0.0 || WIND_SETTINGS_Turbulence > 0.0)
|
|
{
|
|
trunk = texNoise_((PivotPosition - worldOffset)*WIND_SETTINGS_FlexNoiseScale,3);
|
|
}
|
|
|
|
float gust = 0.0;
|
|
|
|
if(WIND_SETTINGS_GustSpeed > 0.0)
|
|
{
|
|
gust = texGust_((PivotPosition - gustWorldOffset)*WIND_SETTINGS_GustWorldScale,3);
|
|
gust = pow(gust, 2) * WIND_SETTINGS_GustScale;
|
|
}
|
|
|
|
float3 trunkNoise =
|
|
(
|
|
(normalizedDir * WIND_SETTINGS_WorldDirectionAndSpeed.w)
|
|
+ (gust * normalizedDir * WIND_SETTINGS_GustSpeed)
|
|
+ (trunk * WIND_SETTINGS_Turbulence)
|
|
) * drag;
|
|
|
|
// Shiver Noise
|
|
float3 shiverNoise = texNoise_((WorldPosition - worldOffset)*WIND_SETTINGS_ShiverNoiseScale,0) * shiverDrag * WIND_SETTINGS_Turbulence;
|
|
|
|
float3 dir = trunkNoise;
|
|
float flex = length(trunkNoise) + initialBend;
|
|
float shiver = length(shiverNoise);
|
|
|
|
result.Direction = dir;
|
|
result.ShiverDirection = shiverNoise;
|
|
result.Strength = flex;
|
|
result.ShiverStrength = shiver + shiver * gust;
|
|
result.Gust = (gust * normalizedDir * WIND_SETTINGS_GustSpeed)
|
|
+ (trunk * WIND_SETTINGS_Turbulence);
|
|
|
|
return result;
|
|
}
|
|
|
|
void ApplyWindDisplacement_( inout float3 positionWS,
|
|
inout WindData_ windData,
|
|
float3 normalWS,
|
|
float3 rootWP,
|
|
float stiffness,
|
|
float drag,
|
|
float shiverDrag,
|
|
float shiverDirectionality,
|
|
float initialBend,
|
|
float shiverMask,
|
|
float4 time)
|
|
{
|
|
WindData_ wind = GetAnalyticalWind(positionWS, rootWP, drag, shiverDrag, initialBend, time);
|
|
|
|
if (wind.Strength > 0.0)
|
|
{
|
|
float att = AttenuateTrunk_(distance(positionWS, rootWP), stiffness);
|
|
float3 rotAxis = cross(float3(0, 1, 0), wind.Direction);
|
|
|
|
positionWS = Rotate_(rootWP, positionWS, rotAxis, (wind.Strength) * 0.001 * att);
|
|
|
|
float3 shiverDirection = normalize(lerp(normalWS, normalize(wind.Direction + wind.ShiverDirection), shiverDirectionality));
|
|
positionWS += wind.ShiverStrength * shiverDirection * shiverMask;
|
|
}
|
|
windData = wind;
|
|
|
|
}
|
|
|
|
float3 TransformObjectToWorldNormal_(float3 normalOS)
|
|
{
|
|
#ifdef UNITY_ASSUME_UNIFORM_SCALING
|
|
return UnityObjectToWorldDir(normalOS);
|
|
#else
|
|
return normalize(mul(normalOS, (float3x3)GetWorldToObjectMatrix()));
|
|
#endif
|
|
}
|
|
void ModifyVertex(inout VertexData v, inout ExtraV2F d)
|
|
{
|
|
float3 positionWS = TransformObjectToWorld(v.vertex.xyz);
|
|
float3 rootWP = TransformObjectToWorld(float3(0,0,0));
|
|
if (positionWS.y > rootWP.y)
|
|
{
|
|
float3 normalWS = TransformObjectToWorldNormal_(v.normal);
|
|
WindData_ windData;
|
|
ApplyWindDisplacement_(positionWS, windData, normalWS, rootWP, _Stiffness, _Drag, _ShiverDrag, _ShiverDirectionality, _InitialBend, v.vertexColor.a, _Time);
|
|
v.vertex.xyz = TransformWorldToObject(positionWS).xyz;
|
|
}
|
|
}
|
|
|
|
void SurfaceFunction(inout Surface o, ShaderData d)
|
|
{
|
|
|
|
}
|
|
|
|
END_CODE
|
|
|