| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- #pragma multi_compile_vertex LOD_FADE_PERCENTAGE
- float4 _CTI_SRP_Wind;
- float _CTI_SRP_Turbulence;
- float4 SmoothCurve( float4 x ) {
- return x * x *( 3.0 - 2.0 * x );
- }
- float4 TriangleWave( float4 x ) {
- return abs( frac( x + 0.5 ) * 2.0 - 1.0 );
- }
- float4 SmoothTriangleWave( float4 x ) {
- return SmoothCurve( TriangleWave( x ) );
- }
- // Overlaods for single float
- float SmoothCurve( float x ) {
- return x * x *( 3.0 - 2.0 * x );
- }
- float TriangleWave( float x ) {
- return abs( frac( x + 0.5 ) * 2.0 - 1.0 );
- }
- float SmoothTriangleWave( float x ) {
- return SmoothCurve( TriangleWave( x ) );
- }
- half3 CTI_UnpackScaleNormal(half4 packednormal, half bumpScale)
- {
- half3 normal;
- normal.xy = (packednormal.wy * 2 - 1);
- #if (SHADER_TARGET >= 30)
- // SM2.0: instruction count limitation
- // SM2.0: normal scaler is not supported
- normal.xy *= bumpScale;
- #endif
- normal.z = sqrt(1.0f - saturate(dot(normal.xy, normal.xy)));
- return normal;
- }
- float4 AfsSmoothTriangleWave( float4 x ) {
- return (SmoothCurve( TriangleWave( x )) - 0.5f) * 2.0f;
- }
- // see http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/
- // 13fps
- float3x3 AfsRotationMatrix(float3 axis, float angle)
- {
- //axis = normalize(axis); // moved to calling function
- float s = sin(angle);
- float c = cos(angle);
- float oc = 1.0f - c;
- return float3x3 ( oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,
- oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,
- oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c);
- }
- void CTI_AnimateVertexSG_float(
- float3 positionOS,
- half3 normalOS,
- half4 vertexColors,
- float2 UV2,
- float3 UV3,
-
- float3 baseWindMultipliers,
- bool IsLeaves,
- out half3 o_positionOS,
- out half3 o_normalOS,
- out half2 o_colorVariationAmbient
- ) {
- // animParams.x = branch phase
- // animParams.y = edge flutter factor
- // animParams.z = primary factor UV2.x
- // animParams.w = secondary factor UV2.y
- float4 animParams = float4(vertexColors.rg, UV2.xy);
- o_positionOS = positionOS;
- o_normalOS = normalOS;
- o_colorVariationAmbient = 0;
-
- float fDetailAmp = 0.1f;
- float fBranchAmp = 0.3f;
- // float3 TreeWorldPos = float3(unity_ObjectToWorld[0].w, unity_ObjectToWorld[1].w, unity_ObjectToWorld[2].w);
- float3 TreeWorldPos = UNITY_MATRIX_M._m03_m13_m23; //SHADERGRAPH_OBJECT_POSITION; //float3(UNITY_MATRIX_M[0].w, UNITY_MATRIX_M[1].w, UNITY_MATRIX_M[2].w);
-
- TreeWorldPos.xyz = abs(TreeWorldPos.xyz * 0.125f);
- float sinuswave = _SinTime.z;
- //#if defined (_LEAFTUMBLING)
- // float shiftedsinuswave = sin(_Time.y * 0.5 + _TimeOffset);
- // float4 vOscillations = AfsSmoothTriangleWave(float4(TreeWorldPos.x + sinuswave, TreeWorldPos.z + sinuswave * 0.7, TreeWorldPos.x + shiftedsinuswave, TreeWorldPos.z + shiftedsinuswave * 0.8));
- //#else
- float4 vOscillations = AfsSmoothTriangleWave(float4(TreeWorldPos.x + sinuswave, TreeWorldPos.z + sinuswave * 0.7, 0.0, 0.0));
- //#endif
- // x used for main wind bending / y used for tumbling
- float2 fOsc = vOscillations.xz + (vOscillations.yw * vOscillations.yw);
- fOsc = 0.75 + (fOsc + 3.33) * 0.33;
- // cti: float fObjPhase = abs ( frac( (TreeWorldPos.x + TreeWorldPos.z) * 0.5 ) * 2 - 1 );
- float fObjPhase = dot(TreeWorldPos, 1);
- float fBranchPhase = fObjPhase + animParams.x; // * 3.3;
- float fVtxPhase = dot(o_positionOS.xyz, animParams.y + fBranchPhase);
-
- // x is used for edges; y is used for branches
- float2 vWavesIn = _Time.yy + float2(fVtxPhase, fBranchPhase );
-
- // 1.975, 0.793, 0.375, 0.193 are good frequencies
- 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;
- // --------------
- // Get local Wind
- float4 xWind = _CTI_SRP_Wind;
- xWind.xyz = mul(GetWorldToObjectMatrix(), float4(xWind.xyz, 0)).xyz;
- // Animate Wind
- xWind.w *= fOsc.x;
- animParams.zwy *= baseWindMultipliers.xyz;
- // --------------
- float3 pivot = 0;
- if (IsLeaves)
- {
- // Decode UV3
- // 15bit compression 2 components only, important: sign of y
- pivot.xz = (frac(float2(1.0f, 32768.0f) * UV3.xx) * 2) - 1;
- pivot.y = sqrt(1 - saturate(dot(pivot.xz, pivot.xz)));
- pivot *= UV3.y;
- // Move point to 0,0,0
- o_positionOS.xyz -= pivot;
- // Tumbling
- #if defined(_LEAFTUMBLING) || defined (_LEAFTURBULENCE)
- real3 fracs = frac( pivot * 33.3 ); //fBranchPhase * 0.1); // + pos.w
- real offset = fracs.x + fracs.y + fracs.z;
- real tFrequency = _TumbleFrequency * (_Time.y + fObjPhase * 10.0 );
- real4 vWaves1 = SmoothTriangleWave( real4( (tFrequency + offset) * (1.0 + offset * 0.25), tFrequency * 0.75 + offset, tFrequency * 0.5 + offset, tFrequency * 1.5 + offset));
- #define packedBranchAxis UV3.z
- #define windDir xWind.xyz
- #define absWindStrength xWind.w
- //#if defined (_EMISSION)
- // This was the root of the fern issue: branchAxes slightly varied on different LODs!
- real3 branchAxis = frac( packedBranchAxis * float3(1.0f, 256.0f, 65536.0f) );
- branchAxis = branchAxis * 2.0 - 1.0;
- branchAxis = normalize(branchAxis);
- // we can do better in case we have the baked branch main axis
- real facingWind = (dot(branchAxis, windDir));
- //#else
- // half facingWind = (dot(normalize(float3(v.positionOS.x, 0, v.positionOS.z)), windDir)); //saturate
- //#endif
- real3 windTangent = real3(-windDir.z, windDir.y, windDir.x);
- real twigPhase = vWaves1.x + vWaves1.y + (vWaves1.z * vWaves1.z);
- //float windStrength = dot(abs(xWind.xyz), 1) * tumbleInfluence * (1.35 - facingWind) * xWind.w + absWindStrength; // Use abs(_Wind)!!!!!!
- half tumbleInfluence = frac(vertexColors.b * 2.0h);
- half windStrength = (1.35h - facingWind) * tumbleInfluence * xWind.w;
- // turbulence
- #if defined (_LEAFTURBULENCE)
- float angleTurbulence =
- // center rotation so the leaves rotate leftwards as well as rightwards according to the incoming waves
- // ((twigPhase + vWaves1.w + fBranchPhase) * 0.2 - 0.5) // not so good to add fBranchPhase here...
- ((twigPhase + vWaves1.w ) * 0.25 - 0.5)
- // make rotation strength depend on absWindStrength and all other inputs
- * 4.0 * absWindStrength * _LeafTurbulence * tumbleInfluence * (0.5 + animParams.w) * saturate(lerp(1.0, animParams.y * 8, _EdgeFlutterInfluence))
- ;
- float3x3 turbulenceRot = AfsRotationMatrix( -branchAxis, angleTurbulence);
- o_positionOS.xyz = mul( turbulenceRot, o_positionOS.xyz);
- #if defined(_NORMALROTATION)
- o_normalOS = mul(turbulenceRot, normalOS);
- #endif
- #endif
- // tumbling
- #if defined(_LEAFTUMBLING)
- //float angleTumble = ( windStrength * (twigPhase + fBranchPhase * 0.25) * _TumbleStrength * tumbleInfluence); // * fOsc.y );
- float angleTumble = _TumbleStrength * tumbleInfluence * windStrength * (twigPhase) ;
- float3x3 tumbleRot = AfsRotationMatrix( windTangent, angleTumble);
- o_positionOS.xyz = mul(tumbleRot, o_positionOS.xyz);
- #if defined(_NORMALROTATION)
- o_normalOS = mul(tumbleRot, o_normalOS);
- #endif
- #endif
- #endif
- // fade in/out leave planes
- #if defined(LOD_FADE_PERCENTAGE)
- real lodfade = (vertexColors.b > 0.5) ? 1 : 0;
- if (lodfade) {
- o_positionOS.xyz *= 1.0 - unity_LODFade.x;
- }
- #endif
- // Move point back to origin
- o_positionOS.xyz += pivot;
- // Advanced edge fluttering (has to be outside preserve length)
- #if defined(_ADVANCEDFLUTTER)
- o_positionOS.xyz += o_normalOS.xyz * SmoothTriangleWave( tumbleInfluence * _Time.y * _AdvancedEdgeBending.y + animParams.x ) * _AdvancedEdgeBending.x * animParams.y * absWindStrength;
- #endif
- }
- // --------------
- // Preserve Length
- float origLength = length(o_positionOS.xyz);
- // Primary bending / Displace position
- o_positionOS.xyz += animParams.z * xWind.xyz * xWind.w ;
- #if defined(_NORMALIZEBRANCH)
- // Preserve Length - good here but stretches real branches
- o_positionOS.xyz = normalize(o_positionOS.xyz) * origLength;
- #endif
- float3 bend = animParams.y * fDetailAmp * abs(o_normalOS.xyz);
- bend.y = animParams.w * fBranchAmp;
- // Apply secondary bending and edge flutter
- o_positionOS.xyz += ((vWavesSum.xyx * bend) + (xWind.xyz * vWavesSum.y * animParams.w)) * xWind.w * _CTI_SRP_Turbulence;
- #if !defined(_NORMALIZEBRANCH)
- // Preserve Length - good here but stretches real branches
- o_positionOS.xyz = normalize(o_positionOS.xyz) * origLength;
- #endif
- // Store Variation
- #if !defined(UNITY_PASS_SHADOWCASTER) && !defined(DEPTHONLYPASS)
- o_colorVariationAmbient.x = saturate ( ( frac(TreeWorldPos.x + TreeWorldPos.y + TreeWorldPos.z) + frac( (TreeWorldPos.x + TreeWorldPos.y + TreeWorldPos.z) * 3.3 ) ) * 0.5 );
- o_colorVariationAmbient.y = vertexColors.a;
- #endif
- }
|