Skip to content

Instantly share code, notes, and snippets.

@bugshake
Created July 30, 2019 10:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bugshake/707a980069a4c29161bf303529a8c738 to your computer and use it in GitHub Desktop.
Save bugshake/707a980069a4c29161bf303529a8c738 to your computer and use it in GitHub Desktop.
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