ToriaAssets/Sources/Shaders/VertexLit_InstancedIndirect.shader

129 lines
3.9 KiB
Plaintext
Raw Permalink Normal View History

2026-05-19 12:20:15 +02:00
Shader "AdvancedTerrainGrass/VertexLit Shader" {
Properties {
[NoScaleOffset] _MainTex ("Albedo (RGB) Smoothness (A)", 2D) = "white" {}
[HideInInspector] _MinMaxScales ("MinMaxScale Factors", Vector) = (1,1,1,1)
_HealthyColor ("Healthy Color", Color) = (1,1,1,1)
_DryColor ("Dry Color", Color) = (1,1,1,1)
[Space(6)]
_SpecularReflectivity ("Specular Reflectivity", Color) = (0.2,0.2,0.2)
[Space(6)]
[Toggle(_NORMALMAP)] _EnableNormal ("Enable Normal Map ", Float) = 0
[NoScaleOffset] _BumpMap (" Normal Map", 2D) = "bump" {}
}
SubShader {
Tags {
"RenderType"="ATGVertexLit"
"IgnoreProjector"="True"
}
LOD 200
CGPROGRAM
// noshadowmask does not fix the problem with baked shadows in deferred
// removing nolightmap does
#pragma surface surf StandardSpecular vertex:vert fullforwardshadows addshadow nodynlightmap nolppv nometa
// nolightmap
#pragma target 3.0
#pragma multi_compile_instancing
// assumeuniformscaling --> so we do not need the WorldToObject matrix!!!!! for the normals
#pragma instancing_options assumeuniformscaling procedural:setup
#pragma shader_feature _NORMALMAP
sampler2D _MainTex;
float InstanceScale;
struct Input {
float2 uv_MainTex;
fixed3 instanceColor;
};
// Define AtgGrass CBUFFER as we might use FadeProps in the future
CBUFFER_START(AtgGrass)
float4 _AtgWindDirSize;
float4 _AtgWindStrength;
float _AtgSinTime;
float _AtgSinTime1;
float4 _AtgGrassFadeProps;
float4 _AtgGrassShadowFadeProps;
float3 _AtgSurfaceCameraPosition;
CBUFFER_END
//sampler2D _AtgWindRT;
float4 _AtgTerrainShiftSurface;
fixed4 _HealthyColor;
fixed4 _DryColor;
float2 _MinMaxScales;
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
StructuredBuffer<float4x4> GrassMatrixBuffer;
#endif
void setup() {
#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
float4x4 data = GrassMatrixBuffer[unity_InstanceID];
unity_ObjectToWorld = data;
// Handle Floating Origin
float3 shift = _AtgTerrainShiftSurface.xyz * _AtgTerrainShiftSurface.w;
unity_ObjectToWorld[0].w -= shift.x;
unity_ObjectToWorld[1].w -= shift.y;
unity_ObjectToWorld[2].w -= shift.z;
// Restore matrix as it could contain layer data here!
InstanceScale = frac(unity_ObjectToWorld[3].w);
InstanceScale *= 100.0f;
unity_ObjectToWorld[3] = float4(0, 0, 0, 1.0f);
// Bullshit!
// unity_WorldToObject = unity_ObjectToWorld;
// unity_WorldToObject._14_24_34 *= -1;
// unity_WorldToObject._11_22_33 = 1.0f / unity_WorldToObject._11_22_33;
// Not entirely correct but good enough? to get the wind direction in objectspace
// Not needed here
/* unity_WorldToObject = unity_ObjectToWorld;
unity_WorldToObject._14_24_34 = 1.0f / unity_WorldToObject._14_24_34;
unity_WorldToObject._11_22_33 *= -1; */
// Seems to be rather cheap - on: 34 / off 36fps
//unity_WorldToObject = inverseMat(unity_ObjectToWorld); //inverspositionBuffer[unity_InstanceID];
#endif
}
void vert(inout appdata_tan v, out Input o) {
UNITY_INITIALIZE_OUTPUT(Input, o);
// Scale contains some perlin noise
//float3 unitvec = mul( (float3x3 )unity_ObjectToWorld, float3(1,0,0)); // float4 would be 0,1,0, 0 !!!!!
//float scale = length( unitvec );
float scale = InstanceScale;
// Lerp instanceColor according to scale (which has to be normalized)
o.instanceColor = lerp(_HealthyColor, _DryColor, (scale - _MinMaxScales.x) * _MinMaxScales.y);
}
#if defined(_NORMALMAP)
sampler2D _BumpMap;
#endif
half3 _SpecularReflectivity;
void surf (Input IN, inout SurfaceOutputStandardSpecular o) {
fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb * IN.instanceColor;
#if defined(_NORMALMAP)
o.Normal = UnpackNormal( tex2D(_BumpMap, IN.uv_MainTex));
#endif
o.Specular = _SpecularReflectivity;
o.Smoothness = c.a;
o.Alpha = 1;
}
ENDCG
}
}