#include "UnityCG.cginc" #define UNITY_INDIRECT_DRAW_ARGS IndirectDrawIndexedArgs #include "UnityIndirect.cginc" #include "Assets/Pixel3D/Shaders/Random.cginc" #include "Lighting.cginc" #include "AutoLight.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; float2 colorTexUV : TEXCOORD1; uint instanceID : SV_InstanceID; float depth : Depth; float4 worldPosition : POSITION1; SHADOW_COORDS(2) }; struct GrassData { float3 position; float2 colorTexUV; }; sampler2D _MainTex; float4 _MainTex_ST; sampler2D _ColorTex; float _AlphaCutout; float4 _TipColor; float _TipColorShift; float _Scale; float _WindSpeed; float _WindStrength; StructuredBuffer _GrassData; float4 _Rotation; float _MeshHeight; float remap(float value, float low1, float high1, float low2, float high2) { return low2 + (value - low1) * (high2 - low2) / (high1 - low1); } float luma(float3 color) { return dot(color, float3(0.2126729, 0.7151522, 0.0721750)); } // https://gamedev.stackexchange.com/questions/28395/ float3 rotate(float3 v, float4 quaternion) { float3 u = quaternion.xyz; float s = quaternion.w; return 2 * dot(u, v) * u + (s * s - dot(u, u)) * v + 2 * s * cross(u, v); } v2f vert (appdata v, uint svInstanceID : SV_InstanceID) { InitIndirectDrawArgs(0); uint cmdID = GetCommandID(0); uint instanceID = GetIndirectInstanceID(svInstanceID); v2f o; float offset = randValue(instanceID) * 20; float3 localPosition = v.vertex.xyz + float3(0, _MeshHeight / 2, 0); localPosition *= _Scale; localPosition.x += sin((_Time.y + offset) * _WindSpeed + localPosition.y - 0.5) * _WindStrength * pow(v.uv.y, 5); float4 worldPosition = float4(rotate(localPosition, _Rotation) + _GrassData[instanceID].position, 1); o.worldPosition = worldPosition; o.pos = UnityObjectToClipPos(worldPosition); o.uv = v.uv; o.colorTexUV = _GrassData[instanceID].colorTexUV; o.instanceID = instanceID; o.depth = o.pos.z; TRANSFER_SHADOW(o) return o; } float4 frag(v2f i) : SV_Target { float4 tex = tex2D(_MainTex, i.uv); if (tex.a < _AlphaCutout) discard; float shadow = remap(step(0.75, SHADOW_ATTENUATION(i)), 0, 1, 0.5, 1); float4 color = tex2D(_ColorTex, i.colorTexUV) * tex; float lum = luma(color.rgb); float lumTip = luma(_TipColor.rgb); float4 tipColor = lerp(color, _TipColor, _TipColorShift); return float4(lerp(color, tipColor, i.uv.y).rgb * shadow, 1); }