#ifndef SPLAT_PASS_META_DEFINED
#define SPLAT_PASS_META_DEFINED

#include "UnityMetaPass.cginc"

v2f_meta vert (appdata v){
    v2f_meta o = (v2f_meta)0;

    o.pos = UnityMetaVertexPosition(v.vertex, v.uv1.xy, v.uv2.xy, unity_LightmapST, unity_DynamicLightmapST);
    o.color = v.color;
    o.rawUV = v.uv;
    
    o.uv0 = TRANSFORM_TEX(SelectUVSet(v, _Layer0UVSet), _BaseColor0);
    #if defined(_LAYER_1_ON)
        o.uv1 = TRANSFORM_TEX(SelectUVSet(v, _Layer1UVSet), _BaseColor1);
    #endif
    #if defined(_LAYER_2_ON)
        o.uv2 = TRANSFORM_TEX(SelectUVSet(v, _Layer2UVSet), _BaseColor2);
    #endif
    #if defined(_LAYER_3_ON)
        o.uv3 = TRANSFORM_TEX(SelectUVSet(v, _Layer3UVSet), _BaseColor3);
    #endif

    o.worldPos = mul(unity_ObjectToWorld, v.vertex);
    o.normal = UnityObjectToWorldNormal(v.normal);
    o.tangent.xyz = UnityObjectToWorldDir(v.tangent.xyz);
    o.tangent.w = v.tangent.w;

	#ifdef EDITOR_VISUALIZATION
		o.vizUV = 0;
		o.lightCoord = 0;
		if (unity_VisualizationMode == EDITORVIZ_TEXTURE)
			o.vizUV = UnityMetaVizUV(unity_EditorViz_UVIndex, v.uv.xy, v.uv1.xy, v.uv2.xy, unity_EditorViz_Texture_ST);
		else if (unity_VisualizationMode == EDITORVIZ_SHOWLIGHTMASK)
		{
			o.vizUV = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
			o.lightCoord = mul(unity_EditorViz_WorldToLight, mul(unity_ObjectToWorld, float4(v.vertex.xyz, 1)));
		}
	#endif
    return o;
}

float4 frag (v2f_meta i) : SV_Target {

    InputData id = (InputData)0;
    SampleData sd = (SampleData)0;

    if (_LayerBlendSource == 1){
        if (_LayerBlendMaskBicubic == 1){
            float width, height;
            _LayerBlendMask.GetDimensions(width, height);
            float4 blendMaskTexelSize = float4(width, height, 1.0/width, 1.0/height);
            i.color = SampleTexture2DBicubicFilter(TEXTURE2D_PARAM(_LayerBlendMask, sampler_LayerBlendMask), TRANSFORM_TEX(i.rawUV, _LayerBlendMask), blendMaskTexelSize);
        }
        else {
            i.color = _LayerBlendMask.Sample(sampler_LayerBlendMask, TRANSFORM_TEX(i.rawUV, _LayerBlendMask));
        }
    }

    i.normal = normalize(i.normal);
    float crossSign = (i.tangent.w > 0.0 ? 1.0 : -1.0) * unity_WorldTransformParams.w;
    float3 binormal = cross(i.normal.xyz, i.tangent.xyz) * crossSign;

    float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos);
    float3x3 tangentToWorld = float3x3(i.tangent.xyz, binormal, i.normal.xyz);
    float3 tangentViewDir = normalize(mul(tangentToWorld, viewDir));
    tangentViewDir.xy /= (tangentViewDir.z + 0.42);

    float4 baseColor = 0;
    float3 normalMap = i.normal;
    #if defined(_STOCHASTIC_0_ON)
        StochasticUV(sd, i.uv0);
        baseColor = StochasticSample(_BaseColor0, sd) * _Color0;
        float4 packed0 = StochasticSample(_PackedMap0, sd);
    #else
        baseColor = tex2D(_BaseColor0, i.uv0) * _Color0;
        float4 packed0 = tex2D(_PackedMap0, i.uv0);
    #endif
    id.occlusion = lerp(1, packed0[_OcclusionChannel0], _Occlusion0);
    id.roughness = packed0[_RoughnessChannel0] * _Roughness0;
    id.metallic = packed0[_MetallicChannel0] * _Metallic0;
    if (_SmoothnessMode0 == 1) id.roughness = 1-id.roughness;
    #if defined(_PARALLAX_0_ON) && !defined(_STOCHASTIC_0_ON)
        id.height = packed0[_HeightChannel0];
    #endif

    #if defined(_LAYER_1_ON)
        i.color.r = linearstep(_BlendThresholdMin1, _BlendThresholdMax1, i.color.r);
        if (i.color.r > 0){
            #if defined(_STOCHASTIC_1_ON)
                StochasticUV(sd, i.uv1);
                float4 baseColor1 = StochasticSample(_BaseColor1, sd) * _Color1;
                float4 packed1 = StochasticSample(_PackedMap1, sd);
            #else
                float4 baseColor1 = tex2D(_BaseColor1, i.uv1) * _Color1;
                float4 packed1 = tex2D(_PackedMap1, i.uv1);
            #endif
            float packed1Rough = packed1[_RoughnessChannel1] * _Roughness1;
            if (_SmoothnessMode1 == 1) packed1Rough = 1-packed1Rough;
            #if defined(_PARALLAX_1_ON) && !defined(_STOCHASTIC_1_ON)
                id.height = lerp(id.height, packed1[_HeightChannel1], i.color.r);
                if (_HeightBlend1 == 1){
                    i.color.r *= linearstep(_HeightBlendMin1, _HeightBlendMax1, id.height);
                }
            #endif
            baseColor = lerp(baseColor, baseColor1, i.color.r);
            id.occlusion = lerp(id.occlusion, lerp(1, packed1[_OcclusionChannel1], _Occlusion1), i.color.r);
            id.roughness = lerp(id.roughness, packed1Rough, i.color.r);
            id.metallic = lerp(id.metallic, packed1[_MetallicChannel1] * _Metallic1, i.color.r);
        }
    #endif

    #if defined(_LAYER_2_ON)
        i.color.g = linearstep(_BlendThresholdMin2, _BlendThresholdMax2, i.color.g);
        if (i.color.g > 0){
            #if defined(_STOCHASTIC_2_ON)
                StochasticUV(sd, i.uv2);
                float4 baseColor2 = StochasticSample(_BaseColor2, sd) * _Color2;
                float4 packed2 = StochasticSample(_PackedMap2, sd);
            #else
                float4 baseColor2 = tex2D(_BaseColor2, i.uv2) * _Color2;
                float4 packed2 = tex2D(_PackedMap2, i.uv2);
            #endif
            float packed2Rough = packed2[_RoughnessChannel2] * _Roughness2;
            if (_SmoothnessMode2 == 1) packed2Rough = 1-packed2Rough;
            #if defined(_PARALLAX_2_ON) && !defined(_STOCHASTIC_2_ON)
                id.height = lerp(id.height, packed2[_HeightChannel2], i.color.g);
                if (_HeightBlend2 == 1){
                    i.color.g *= linearstep(_HeightBlendMin2, _HeightBlendMax2, id.height);
                }
            #endif
            baseColor = lerp(baseColor, baseColor2, i.color.g);
            id.occlusion = lerp(id.occlusion, lerp(1, packed2[_OcclusionChannel2], _Occlusion2), i.color.g);
            id.roughness = lerp(id.roughness, packed2Rough, i.color.g);
            id.metallic = lerp(id.metallic, packed2[_MetallicChannel2] * _Metallic2, i.color.g);
        }
    #endif

    #if defined(_LAYER_3_ON)
        i.color.b = linearstep(_BlendThresholdMin3, _BlendThresholdMax3, i.color.b);
        if (i.color.b > 0){
            #if defined(_STOCHASTIC_3_ON)
                StochasticUV(sd, i.uv3);
                float4 baseColor3 = StochasticSample(_BaseColor3, sd) * _Color3;
                float4 packed3 = StochasticSample(_PackedMap3, sd);
            #else
                float4 baseColor3 = tex2D(_BaseColor3, i.uv3) * _Color3;
                float4 packed3 = tex2D(_PackedMap3, i.uv3);
            #endif
            float packed3Rough = packed3[_RoughnessChannel3] * _Roughness3;
            if (_SmoothnessMode3 == 1) packed3Rough = 1-packed3Rough;
            #if defined(_PARALLAX_3_ON) && !defined(_STOCHASTIC_3_ON)
                id.height = lerp(id.height, packed3[_HeightChannel3], i.color.b);
                if (_HeightBlend3 == 1){
                    i.color.b *= linearstep(_HeightBlendMin3, _HeightBlendMax3, id.height);
                }
            #endif
            baseColor = lerp(baseColor, baseColor3, i.color.b);
            id.occlusion = lerp(id.occlusion, lerp(1, packed3[_OcclusionChannel3], _Occlusion3), i.color.b);
            id.roughness = lerp(id.roughness, packed3Rough, i.color.b);
            id.metallic = lerp(id.metallic, packed3[_MetallicChannel3] * _Metallic3, i.color.b);
        }
    #endif

    float3 specularColor = lerp(unity_ColorSpaceDielectricSpec.rgb, id.albedo, id.metallic);

    UnityMetaInput o = (UnityMetaInput)0;
    #ifdef EDITOR_VISUALIZATION
        o.Albedo = baseColor;
        o.VizUV = i.vizUV;
        o.LightCoord = i.lightCoord;
    #else
        o.Albedo = baseColor + specularColor * ((id.roughness * id.roughness) * 0.5);
    #endif
    o.SpecularColor = specularColor;
 
    return UnityMetaFragment(o);
}

#endif