Shader "Instanced/BushShader" { | |
Properties{ | |
_MainTex("Albedo (RGB)", 2D) = "white" {} | |
_Color0("Color0", Color) = (0,0,0,1) | |
_Color1("Color1", Color) = (1,1,1,1) | |
_Cutoff("Alpha cutoff", Range(0,1)) = 0.5 | |
_FadeStart("Fade start", Float) = 10000.0 | |
_FadeEnd("Fade end", Float) = 11000.0 | |
_WaveAmount("Wave Amount", Float) = 0.1 | |
_WaveSpeed("Wave Speed", Float) = 1.0 | |
} | |
SubShader{ | |
Tags{ "Queue" = "AlphaTest" "IgnoreProjector" = "True" "RenderType" = "TransparentCutout" } | |
LOD 200 | |
Cull Off | |
CGPROGRAM | |
#pragma surface surf Lambert addshadow fullforwardshadows alphatest:_Cutoff vertex:vert | |
#pragma multi_compile_instancing | |
#pragma instancing_options procedural:setup | |
static const float PI = 3.14159265f; | |
sampler2D _MainTex; | |
float4 offset; // VirtualPositionSnapper (vpos) | |
fixed4 _Color0; | |
fixed4 _Color1; | |
float _FadeStart; | |
float _FadeEnd; | |
float _WaveAmount; | |
float _WaveSpeed; | |
struct GrassInfo { | |
float3 pos; | |
float scale; | |
float rotationX; | |
float rotationY; | |
float color; | |
}; | |
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED | |
StructuredBuffer<GrassInfo> positionBuffer; | |
#endif | |
struct Input { | |
float2 uv_MainTex; | |
float3 worldPos; | |
}; | |
void rotate2D(inout float2 v, float r) | |
{ | |
float s, c; | |
sincos(r, s, c); | |
v = float2(v.x * c - v.y * s, v.x * s + v.y * c); | |
} | |
float4x4 mat_inverse(float4x4 input) | |
{ | |
#define minor(a,b,c) determinant(float3x3(input.a, input.b, input.c)) | |
float4x4 cofactors = float4x4( | |
minor(_22_23_24, _32_33_34, _42_43_44), | |
-minor(_21_23_24, _31_33_34, _41_43_44), | |
minor(_21_22_24, _31_32_34, _41_42_44), | |
-minor(_21_22_23, _31_32_33, _41_42_43), | |
-minor(_12_13_14, _32_33_34, _42_43_44), | |
minor(_11_13_14, _31_33_34, _41_43_44), | |
-minor(_11_12_14, _31_32_34, _41_42_44), | |
minor(_11_12_13, _31_32_33, _41_42_43), | |
minor(_12_13_14, _22_23_24, _42_43_44), | |
-minor(_11_13_14, _21_23_24, _41_43_44), | |
minor(_11_12_14, _21_22_24, _41_42_44), | |
-minor(_11_12_13, _21_22_23, _41_42_43), | |
-minor(_12_13_14, _22_23_24, _32_33_34), | |
minor(_11_13_14, _21_23_24, _31_33_34), | |
-minor(_11_12_14, _21_22_24, _31_32_34), | |
minor(_11_12_13, _21_22_23, _31_32_33) | |
); | |
#undef minor | |
return transpose(cofactors) / determinant(input); | |
} | |
float4x4 mat_rotateX(float rot) | |
{ | |
float s, c; | |
sincos(rot, s, c); | |
float4x4 result = float4x4( | |
1, 0, 0, 0, | |
0, c, -s, 0, | |
0, s, c, 0, | |
0, 0, 0, 1 | |
); | |
return result; | |
} | |
float4x4 mat_rotateY(float rot) | |
{ | |
float s, c; | |
sincos(rot, s, c); | |
float4x4 result = float4x4( | |
c, 0, s, 0, | |
0, 1, 0, 0, | |
-s, 0, c, 0, | |
0, 0, 0, 1 | |
); | |
return result; | |
} | |
float4x4 mat_rotateZ(float rot) | |
{ | |
float s, c; | |
sincos(rot, s, c); | |
float4x4 result = float4x4( | |
c, -s, 0, 0, | |
s, c, 0, 0, | |
0, 0, 1, 0, | |
0, 0, 0, 1 | |
); | |
return result; | |
} | |
void setup() | |
{ | |
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED | |
float3 pos = positionBuffer[unity_InstanceID].pos + offset.xyz; | |
float scale = positionBuffer[unity_InstanceID].scale; | |
float rotX = positionBuffer[unity_InstanceID].rotationX; | |
float rotY = positionBuffer[unity_InstanceID].rotationY; | |
unity_ObjectToWorld._11_21_31_41 = float4(scale, 0, 0, 0); | |
unity_ObjectToWorld._12_22_32_42 = float4(0, scale, 0, 0); | |
unity_ObjectToWorld._13_23_33_43 = float4(0, 0, scale, 0); | |
unity_ObjectToWorld._14_24_34_44 = float4(pos, 1); | |
unity_ObjectToWorld = mul(mul( | |
unity_ObjectToWorld, | |
mat_rotateY(rotY)), | |
mat_rotateX( - 0.5f * PI));//rotX | |
unity_WorldToObject = mat_inverse(unity_ObjectToWorld); | |
#endif | |
} | |
half4 LightingWrapLambert(SurfaceOutput s, half3 lightDir, half atten) { | |
half NdotL = dot(s.Normal, lightDir); | |
half diff = NdotL * 0.5 + 0.5; | |
half4 c; | |
c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten); | |
c.a = s.Alpha; | |
return c; | |
} | |
void vert(inout appdata_full v) { | |
v.vertex.x += _WaveAmount * v.vertex.y * cos(_Time.x * _WaveSpeed + v.vertex.z + v.vertex.y); | |
} | |
void surf(Input IN, inout SurfaceOutput o) { | |
fixed4 c = tex2D(_MainTex, IN.uv_MainTex); | |
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED | |
c *= lerp(_Color0, _Color1, positionBuffer[unity_InstanceID].color); | |
float3 pos = positionBuffer[unity_InstanceID].pos + offset.xyz; | |
float dist = distance(pos, _WorldSpaceCameraPos); | |
float visibility = dist >= _FadeEnd ? 0.0 : smoothstep(dist, _FadeEnd, _FadeStart); | |
c.a *= visibility; | |
#else | |
#endif | |
o.Albedo = c.rgb; | |
o.Alpha = c.a; | |
o.Emission = 0; | |
} | |
ENDCG | |
} | |
FallBack "Transparent/Cutout/VertexLit" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment