Skip to content

Instantly share code, notes, and snippets.

@cjacobwade
Last active August 2, 2023 17:08
Show Gist options
  • Save cjacobwade/c0c524af3e29aacb340ace33729043fb to your computer and use it in GitHub Desktop.
Save cjacobwade/c0c524af3e29aacb340ace33729043fb to your computer and use it in GitHub Desktop.
inline float inverselerp(float min, float max, float x)
{
return (x - min) / (max - min);
}
float hash(float n)
{
return frac(sin(n)*43758.5453);
}
float noise(float3 v)
{
// The noise function returns a value in the range -1.0f -> 1.0f
float3 p = floor(v);
float3 f = frac(v);
f = f*f*(3.0 - 2.0*f);
float n = p.x + p.y*57.0 + 113.0*p.z;
return lerp(lerp(lerp(hash(n + 0.0), hash(n + 1.0), f.x),
lerp(hash(n + 57.0), hash(n + 58.0), f.x), f.y),
lerp(lerp(hash(n + 113.0), hash(n + 114.0), f.x),
lerp(hash(n + 170.0), hash(n + 171.0), f.x), f.y), f.z);
}
half4 getSmearedWorldPos(half4 vertPos)
{
half4 worldPos = mul(unity_ObjectToWorld, vertPos);
half3 worldOffset = _SmearPosition.xyz - _PrevSmearPosition.xyz;
half3 localOffset = worldPos.xyz - _SmearPosition.xyz;
// World offset should only be behind swing
half dirDot = dot(normalize(worldOffset), normalize(localOffset));
worldOffset = clamp(worldOffset, -_NoiseHeight, _NoiseHeight);
worldOffset *= -clamp(dirDot, -1, 0) * (1 - step(length(worldOffset), 0));
// World offset is scaled by distance from smearPos
half dist = clamp(length(localOffset), _SmearRange, _SmearRange + _SmearFalloff);
half distAlpha = inverselerp(_SmearRange + _SmearFalloff, _SmearRange, dist);
worldOffset *= distAlpha;
half3 smearOffset = -worldOffset.xyz * lerp(1, cheapVertNoise(worldPos * _NoiseScale), step(0, _NoiseScale));
worldPos.xyz += smearOffset;
return worldPos;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment