Firstborn/Assets/AwesomeTechnologies/VegetationStudioPro/Runtime/BillboardSystem/Resources/Shaders/VSBillboards.cginc

296 lines
7.4 KiB
HLSL
Raw Normal View History

#ifdef USE_HDWIND
#include "HDWind.cginc"
#endif
sampler2D _MainTex;
sampler2D _Bump;
fixed4 _Color;
float _YRotation;
float _XTurnFix;
float _CullDistance;
float _FarCullDistance;
float _Brightness;
float _MipmapBias;
int _InRow;
int _InCol;
int _CameraType;
float4 _CameraPosition;
float _BillboardWindSpeed;
float _Smoothness;
float _Metallic;
float _Specular;
float _Occlusion;
float _NormalStrength;
//float _Cutoff;
#ifdef USE_SNOW
half _SnowAmount;
fixed4 _SnowColor;
half _SnowBlendFactor;
float _SnowBrightness;
#endif
#ifdef AT_HUE_VARIATION_ON
half4 _HueVariation;
#endif
struct Input
{
float2 uv_MainTex;
float4 d;
#ifdef LOD_FADE_CROSSFADE
float3 dc;
float crossfade_value;
#endif
#ifdef USE_SNOW
float3 worldNormal; INTERNAL_DATA
#endif
};
void DitherCrossFade(half3 ditherScreenPos, float crossfadeValue)
{
half2 projUV = ditherScreenPos.xy / ditherScreenPos.z;
projUV.xy = frac(projUV.xy + 0.001) + frac(projUV.xy * 2.0 + 0.001);
half dither = crossfadeValue - (projUV.y + projUV.x) * 0.25;
clip(dither);
}
half3 VS_ComputeDitherScreenPos(float4 clipPos)
{
half3 screenPos = ComputeScreenPos(clipPos).xyw;
screenPos.xy *= _ScreenParams.xy * 0.25;
return screenPos;
}
//#ifdef LOD_FADE_CROSSFADE
//void VS_ApplyDitherCrossFade(half3 ditherScreenPos, float crossfadeValue)
//{
// float fadeValue = ceil(crossfadeValue * 16) / 16.0;
// half2 projUV = ditherScreenPos.xy / ditherScreenPos.z;
// projUV.y = frac(projUV.y) * 0.0625 + fadeValue; // quantized lod fade by 16 levels
// clip(tex2D(_DitherMaskLOD2D, projUV).a - 0.5);
//}
//#endif
UNITY_INSTANCING_BUFFER_START(Props)
UNITY_INSTANCING_BUFFER_END(Props)
void vert(inout appdata_full v, out Input o)
{
UNITY_INITIALIZE_OUTPUT(Input, o);
float4 CENTER = v.vertex;
float3 CORNER = v.normal * v.texcoord2.x;
float3 worldspaceCenter = mul(unity_ObjectToWorld, CENTER);
float3 modifiedCameraPos;
if (_InCol == 1)
{
modifiedCameraPos = _WorldSpaceCameraPos;
modifiedCameraPos.y = worldspaceCenter.y;
}
else
{
modifiedCameraPos = _WorldSpaceCameraPos.xyz;
}
#define cameraPos modifiedCameraPos;
float3 clipVect;
clipVect = (worldspaceCenter + float3(0, v.texcoord3.y, 0)) - _CameraPosition;
#if defined(UNITY_PASS_SHADOWCASTER)
float3 camVect;
if (unity_MatrixVP[3][3] == 1)
camVect = _WorldSpaceLightPos0.w < 0.5 ? _WorldSpaceLightPos0.xyz : worldspaceCenter - _WorldSpaceLightPos0.xyz;
else
camVect = worldspaceCenter - cameraPos;
#define camVectEvenInShadows (worldspaceCenter - cameraPos)
#else
float3 camVect = worldspaceCenter - cameraPos;
#define camVectEvenInShadows camVect
#endif
if (length(clipVect) < _CullDistance || length(clipVect) > _FarCullDistance)
{
CORNER.xyz *= 0;
}
else
{
#ifdef LOD_FADE_CROSSFADE
float distance = length(clipVect) - _CullDistance;
if (distance < 2)
{
o.crossfade_value = 1 - (distance / 2);
}
else
{
o.crossfade_value = 0.98;
}
#endif
// Create LookAt matrix
float3 zaxis = normalize(camVect);
float3 xaxis = normalize(cross(float3(0, 1, 0), zaxis));
float3 yaxis = cross(zaxis, xaxis);
float4x4 lookatMatrix = {
xaxis.x, yaxis.x, zaxis.x, 0,
xaxis.y, yaxis.y, zaxis.y, 0,
xaxis.z, yaxis.z, zaxis.z, 0,
0, 0, 0, 1
};
v.vertex = mul(lookatMatrix, float4(CORNER.x, CORNER.y, (yaxis.y - 1.0) * v.texcoord2.y, 1));
v.vertex.xyz += CENTER.xyz;
v.normal = -zaxis;
v.tangent.xyz = xaxis;
v.tangent.w = -1;
#ifdef USE_SNOW
o.worldNormal = mul((float3x3)unity_ObjectToWorld, v.normal);
#endif
v.texcoord.x /= _InRow;
v.texcoord.y /= _InCol;
float angle;
float step;
float2 atanDir = normalize(float2(-zaxis.z, -zaxis.x));
angle = (atan2(atanDir.y, atanDir.x) / 6.28319) + 0.5; // angle around Y in range 0....1
angle += v.texcoord1.x;
angle -= (int)angle;
step = 1.0 / _InRow;
v.texcoord.x += step * ((int)((angle + step * 0.5) * _InRow));
step = 1.0 / _InCol;
angle = saturate(dot(-zaxis, float3(0, 1, 0)));
angle = clamp(angle, 0, step*(_InCol - 1));
v.texcoord.y += step * ((int)((angle + step * 0.5) * _InCol));
o.d.x = v.texcoord1.y;
#ifdef AT_HUE_VARIATION_ON
float hueVariationAmount = frac(CENTER.x + CENTER.y + CENTER.z);
o.d.y = saturate(hueVariationAmount * _HueVariation.a);
#endif
#ifdef LOD_FADE_CROSSFADE
o.dc = VS_ComputeDitherScreenPos(v.vertex);
#endif
#ifdef USE_HDWIND
#if !defined(UNITY_PASS_SHADOWCASTER)
float initialBend = 1;
float stiffness = 1;
float drag = 0.3;
float shiverDrag = 0;
float shiverDirectionality = 1;
float3 positionWS = TransformObjectToWorld(v.vertex.xyz);
float3 rootWP = TransformObjectToWorld(CENTER.xyz);
if (positionWS.y > rootWP.y)
{
float3 normalWS = TransformObjectToWorldNormal(v.normal);
WindData windData;
ApplyWindDisplacement(positionWS, windData, normalWS, rootWP, stiffness, drag, shiverDrag, shiverDirectionality, initialBend, 20 * _BillboardWindSpeed, _Time);
v.vertex.xyz = TransformWorldToObject(positionWS).xyz;
}
#endif
#endif
}
}
void surf(Input IN, inout SurfaceOutputStandard o)
{
//#ifdef LOD_FADE_CROSSFADE
// //#define unity_LODFade float4(0.5,0.5,0,0)
// if (IN.crossfade_value > 0.99)
// {
// VS_ApplyDitherCrossFade(IN.dc, IN.crossfade_value);
// }
// //DitherCrossFade(IN.dc, IN.crossfade_value);
//#endif
fixed4 c = tex2Dbias(_MainTex, half4(IN.uv_MainTex, 0, _MipmapBias)) * _Color;
#ifdef AT_HUE_VARIATION_ON
half3 shiftedColor = lerp(c.rgb, _HueVariation.rgb, IN.d.y);
half maxBase = max(c.r, max(c.g, c.b));
half newMaxBase = max(shiftedColor.r, max(shiftedColor.g, shiftedColor.b));
maxBase /= newMaxBase;
maxBase = maxBase * 0.5f + 0.5f;
shiftedColor.rgb *= maxBase;
c.rgb = saturate(shiftedColor);
#endif
o.Albedo = c.rgb * IN.d.x *_Color;
o.Albedo = clamp(o.Albedo * _Brightness, 0, 1);
o.Normal = tex2D(_Bump, IN.uv_MainTex).rgb * 2.0 - 1.0;
o.Occlusion = _Occlusion;
o.Smoothness = _Smoothness;
o.Metallic = _Metallic;
#ifdef USE_SNOW
half d = dot(WorldNormalVector(IN, o.Normal), float3(0, -1, 0)) * 0.5 + 0.5;
o.Albedo = lerp(o.Albedo, (_SnowColor.xyz * _SnowBrightness), _SnowAmount * d * _SnowBlendFactor);
#endif
o.Alpha = c.a;
}
void surfSpecular(Input IN, inout SurfaceOutputStandardSpecular o)
{
//#ifdef LOD_FADE_CROSSFADE
// //#define unity_LODFade float4(0.5,0.5,0,0)
// if (IN.crossfade_value > 0.99)
// {
// VS_ApplyDitherCrossFade(IN.dc, IN.crossfade_value);
// }
// //DitherCrossFade(IN.dc, IN.crossfade_value);
//#endif
fixed4 c = tex2Dbias(_MainTex, half4(IN.uv_MainTex, 0, _MipmapBias)) * _Color;
#ifdef AT_HUE_VARIATION_ON
half3 shiftedColor = lerp(c.rgb, _HueVariation.rgb, IN.d.y);
half maxBase = max(c.r, max(c.g, c.b));
half newMaxBase = max(shiftedColor.r, max(shiftedColor.g, shiftedColor.b));
maxBase /= newMaxBase;
maxBase = maxBase * 0.5f + 0.5f;
shiftedColor.rgb *= maxBase;
c.rgb = saturate(shiftedColor);
#endif
o.Albedo = c.rgb * IN.d.x *_Color;
o.Albedo = clamp(o.Albedo * _Brightness, 0, 1);
o.Normal = tex2D(_Bump, IN.uv_MainTex).rgb * 2.0 - 1.0;
o.Normal.xy *= _NormalStrength;
//.Normal = normalize(o.Normal);
o.Occlusion = _Occlusion;
o.Smoothness = _Smoothness;
o.Specular = _Specular;
#ifdef USE_SNOW
half d = dot(WorldNormalVector(IN, o.Normal), float3(0, -1, 0)) * 0.5 + 0.5;
o.Albedo = lerp(o.Albedo, (_SnowColor.xyz * _SnowBrightness), _SnowAmount * d * _SnowBlendFactor);
#endif
o.Alpha = c.a;
//o.Alpha = (o.Alpha - _Cutoff) / max(fwidth(o.Alpha), 0.0001) + 0.5;
}