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