Created
July 30, 2019 10:07
-
-
Save bugshake/707a980069a4c29161bf303529a8c738 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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