You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
3.5 KiB
HLSL

#ifndef PW_GENERALWINDHDRP
#define PW_GENERALWINDHDRP
inline void WindCalculations_float ( in float3 i_vertexPos, in float2 i_widthHeight, in float3 i_flex, in float3 i_frequency, out float3 o_vertexPos )
{
#ifdef _PW_SF_WIND_ON
// early out test
float3 worldOffset = UNITY_MATRIX_M._m03_m13_m23 + _WorldSpaceCameraPos; // grab pos from matrix translation
// cheeky normalised square dist
float3 nrmObjDistVector = (worldOffset - _WorldSpaceCameraPos) / _PW_WindGlobalsB.x;
float nrmSqrdDist = 1 - saturate(dot(nrmObjDistVector,nrmObjDistVector));
nrmSqrdDist *= nrmSqrdDist;
o_vertexPos = i_vertexPos; // prime out with pre wind data
if(nrmSqrdDist > 0.0f)
{
// Just for clarity
float3 windDir = _PW_WindGlobals.xyz;
float windMain = _PW_WindGlobals.w;
// curves for mixing flex by wind main
float3 flex = i_flex * float3(saturate(windMain * 3),saturate(windMain * 2),1-windMain * windMain * 0.5) * windMain * nrmSqrdDist;
// normalize effects by height scale and reduce effects when object is on its side.
float3 up = float3(0,1,0);
float3 zScaleRotVec = mul((float3x3)UNITY_MATRIX_M,up);
float3 zScaleRotVecNrm = normalize(zScaleRotVec);
float xDot = max(dot(zScaleRotVec,zScaleRotVecNrm),0.4f); // clamp to 0.4 so really small scales dont become overly flexible
float upDot = saturate(dot(zScaleRotVecNrm,up));
i_widthHeight.xy = lerp(i_widthHeight.yy * float2(2,2),i_widthHeight.xy,upDot*upDot) * xDot;
flex *= xDot;
i_frequency *= xDot;
// split translation from scale and rotation for later use
float3 localWorldPos = mul((float3x3)UNITY_MATRIX_M,i_vertexPos.xyz);
float3 worldPos = localWorldPos + worldOffset;
float windTime = -frac(_PW_WindGlobalsB.y * 6.0f) * 6.283185f;
float3 normLocalWorldPos = localWorldPos / float3(i_widthHeight.x,i_widthHeight.y,i_widthHeight.x);
float branchdist = dot(normLocalWorldPos.xz , normLocalWorldPos.xz);
float stemheight = normLocalWorldPos.y;
// approximate length before flex
float lengthA = dot(localWorldPos,localWorldPos);
// Main wind force
float gust = ((sin(windTime + dot(i_frequency.xxx,worldOffset)) * 0.3 + windMain * 0.5) + (_SinTime.y * 0.4 + windMain) * windMain) * (_SinTime.w * 0.3 + 0.7);
// trunk flex
float3 flexTally = 0;
flexTally.xz = windDir.xz * (stemheight * stemheight * gust * flex.x);
// scale gust for branch and leaf
gust = gust * 0.7 + 0.3;
// branch flex
#ifndef _PW_SF_BILLBOARD_ON
flexTally.xyz += windDir.xyz * stemheight * stemheight * (sin(windTime * 2 + dot(worldPos + flexTally * 0.25,float3(1,1,1)) * i_frequency.y) * branchdist * 0.7 + 0.3) * gust * flex.y; // - flextally adds more noise when stem flex's
#endif
//normalize flex to maintain tree volume
float3 vertOffset = localWorldPos + flexTally;
float flexNorm = saturate(lengthA/dot(vertOffset,vertOffset));
flexTally = vertOffset * flexNorm;
// add to tree
localWorldPos = flexTally;
// leaf flex
#ifndef _PW_SF_BILLBOARD_ON
#ifdef _ALPHATEST_ON
float leafTime = windTime * 5;
float3 frequencyOffests = (worldPos + flexTally) * i_frequency.z;
float3 leafBranchdist = float3(branchdist,branchdist * 0.75f,branchdist);
float3 leafFlex = (sin(leafTime.xxx + frequencyOffests) * windDir.xyz + windDir.xyz) * leafBranchdist;
localWorldPos += leafFlex * (stemheight * gust * flex.z) * (flexNorm + 0.5f);
#endif
#endif
o_vertexPos = mul((float3x3)UNITY_MATRIX_I_M,localWorldPos.xyz);
}
#else
o_vertexPos = i_vertexPos;
#endif
}
#endif // PW_GENERALFUNCS