Shader ".poiyomi/Poiyomi Toon Two Pass"
{
	Properties
	{
		[HideInInspector] shader_master_label ("<color=#E75898ff>Poiyomi 9.0.57</color>", Float) = 0
		[HideInInspector] shader_is_using_thry_editor ("", Float) = 0
		[HideInInspector] shader_locale ("0db0b86376c3dca4b9a6828ef8615fe0", Float) = 0
		[HideInInspector] footer_youtube ("{texture:{name:icon-youtube,height:16},action:{type:URL,data:https://www.youtube.com/poiyomi},hover:YOUTUBE}", Float) = 0
		[HideInInspector] footer_twitter ("{texture:{name:icon-twitter,height:16},action:{type:URL,data:https://twitter.com/poiyomi},hover:TWITTER}", Float) = 0
		[HideInInspector] footer_patreon ("{texture:{name:icon-patreon,height:16},action:{type:URL,data:https://www.patreon.com/poiyomi},hover:PATREON}", Float) = 0
		[HideInInspector] footer_discord ("{texture:{name:icon-discord,height:16},action:{type:URL,data:https://discord.gg/Ays52PY},hover:DISCORD}", Float) = 0
		[HideInInspector] footer_github ("{texture:{name:icon-github,height:16},action:{type:URL,data:https://github.com/poiyomi/PoiyomiToonShader},hover:GITHUB}", Float) = 0
		
		// Warning that only shows up when ThryEditor hasn't loaded
		[Header(POIYOMI SHADER UI FAILED TO LOAD)]
		[Header(.    This is caused by scripts failing to compile. It can be fixed.)]
		[Header(.          The inspector will look broken and will not work properly until fixed.)]
		[Header(.    Please check your console for script errors.)]
		[Header(.          You can filter by errors in the console window.)]
		[Header(.          Often the topmost error points to the erroring script.)]
		[Space(30)][Header(Common Error Causes)]
		[Header(.    Installing multiple Poiyomi Shader packages)]
		[Header(.          Make sure to delete the Poiyomi shader folder before you update Poiyomi.)]
		[Header(.          If a package came with Poiyomi this is bad practice and can cause issues.)]
		[Header(.          Delete the package and import it without any Poiyomi components.)]
		[Header(.    Bad VRCSDK installation (e.g. Both VCC and Standalone))]
		[Header(.          Delete the VRCSDK Folder in Assets if you are using the VCC.)]
		[Header(.          Avoid using third party SDKs. They can cause incompatibility.)]
		[Header(.    Script Errors in other scripts)]
		[Header(.          Outdated tools or prefabs can cause this.)]
		[Header(.          Update things that are throwing errors or move them outside the project.)]
		[Space(30)][Header(Visit Our Discord to Ask For Help)]
		[Space(5)]_ShaderUIWarning0 (" → discord.gg/poiyomi ←    We can help you get it fixed!                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         --{condition_showS:(0==1)}", Int) = -0
		[Space(1400)][Header(POIYOMI SHADER UI FAILED TO LOAD)]
		_ShaderUIWarning1 ("Please scroll up for more information!                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     --{condition_showS:(0==1)}", Int) = -0
		
		// Keyword to remind users in the VRChat SDK that this material hasn't been locked.  Inelegant but it works.
		[HideInInspector] _ForgotToLockMaterial (";;YOU_FORGOT_TO_LOCK_THIS_MATERIAL;", Int) = 1
		[ThryShaderOptimizerLockButton] _ShaderOptimizerEnabled ("", Int) = 0
		[HideInInspector] GeometryShader_Enabled("GEOMETRY SHADER ENABLED", Float) = 1
		[HideInInspector] Tessellation_Enabled("TESSELLATION ENABLED", Float) = 1
		//[ThryCustomGUI(Poi.Tools.ModularShaderSystem.ModularShadersForThryEditor,Poi.Tools,GUICustomPoiMSS)] _CustomShaderButton("CustomShaderButton", Float) = 0
		[ThryWideEnum(Opaque, 0, Cutout, 1, TransClipping, 9, Fade, 2, Transparent, 3, Additive, 4, Soft Additive, 5, Multiplicative, 6, 2x Multiplicative, 7)]_Mode("Rendering Preset--{on_value_actions:[
		{value:0,actions:[{type:SET_PROPERTY,data:render_queue=2000},{type:SET_PROPERTY,data:_AlphaForceOpaque=1}, {type:SET_PROPERTY,data:render_type=Opaque},            {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=0},  {type:SET_PROPERTY,data:_SrcBlend=1}, {type:SET_PROPERTY,data:_DstBlend=0},  {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1},  {type:SET_PROPERTY,data:_AddSrcBlend=1}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0},  {type:SET_PROPERTY,data:_ZWrite=1}, {type:SET_PROPERTY,data:_ZTest=4},   {type:SET_PROPERTY,data:_AlphaPremultiply=0}, {type:SET_PROPERTY,data:_OutlineSrcBlend=1}, {type:SET_PROPERTY,data:_OutlineDstBlend=0},  {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=0}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]},
		{value:1,actions:[{type:SET_PROPERTY,data:render_queue=2450},{type:SET_PROPERTY,data:_AlphaForceOpaque=0}, {type:SET_PROPERTY,data:render_type=TransparentCutout}, {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=.5}, {type:SET_PROPERTY,data:_SrcBlend=1}, {type:SET_PROPERTY,data:_DstBlend=0},  {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1},  {type:SET_PROPERTY,data:_AddSrcBlend=1}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0},  {type:SET_PROPERTY,data:_ZWrite=1}, {type:SET_PROPERTY,data:_ZTest=4},   {type:SET_PROPERTY,data:_AlphaPremultiply=0}, {type:SET_PROPERTY,data:_OutlineSrcBlend=1}, {type:SET_PROPERTY,data:_OutlineDstBlend=0},  {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]},
		{value:9,actions:[{type:SET_PROPERTY,data:render_queue=2460},{type:SET_PROPERTY,data:_AlphaForceOpaque=0}, {type:SET_PROPERTY,data:render_type=TransparentCutout}, {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=0.01},  {type:SET_PROPERTY,data:_SrcBlend=5}, {type:SET_PROPERTY,data:_DstBlend=10}, {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1},  {type:SET_PROPERTY,data:_AddSrcBlend=5}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0},  {type:SET_PROPERTY,data:_ZWrite=1}, {type:SET_PROPERTY,data:_ZTest=4},   {type:SET_PROPERTY,data:_AlphaPremultiply=0}, {type:SET_PROPERTY,data:_OutlineSrcBlend=5}, {type:SET_PROPERTY,data:_OutlineDstBlend=10}, {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]},
		{value:2,actions:[{type:SET_PROPERTY,data:render_queue=3000},{type:SET_PROPERTY,data:_AlphaForceOpaque=0}, {type:SET_PROPERTY,data:render_type=Transparent},       {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=0.002},  {type:SET_PROPERTY,data:_SrcBlend=5}, {type:SET_PROPERTY,data:_DstBlend=10}, {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1},  {type:SET_PROPERTY,data:_AddSrcBlend=5}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0},  {type:SET_PROPERTY,data:_ZWrite=0}, {type:SET_PROPERTY,data:_ZTest=4},   {type:SET_PROPERTY,data:_AlphaPremultiply=0}, {type:SET_PROPERTY,data:_OutlineSrcBlend=5}, {type:SET_PROPERTY,data:_OutlineDstBlend=10}, {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]},
		{value:3,actions:[{type:SET_PROPERTY,data:render_queue=3000},{type:SET_PROPERTY,data:_AlphaForceOpaque=0}, {type:SET_PROPERTY,data:render_type=Transparent},       {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=0},  {type:SET_PROPERTY,data:_SrcBlend=1}, {type:SET_PROPERTY,data:_DstBlend=10}, {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1},  {type:SET_PROPERTY,data:_AddSrcBlend=1}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0},  {type:SET_PROPERTY,data:_ZWrite=0}, {type:SET_PROPERTY,data:_ZTest=4},   {type:SET_PROPERTY,data:_AlphaPremultiply=1}, {type:SET_PROPERTY,data:_OutlineSrcBlend=1}, {type:SET_PROPERTY,data:_OutlineDstBlend=10}, {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]},
		{value:4,actions:[{type:SET_PROPERTY,data:render_queue=3000},{type:SET_PROPERTY,data:_AlphaForceOpaque=0}, {type:SET_PROPERTY,data:render_type=Transparent},       {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=0},  {type:SET_PROPERTY,data:_SrcBlend=1}, {type:SET_PROPERTY,data:_DstBlend=1},  {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1},  {type:SET_PROPERTY,data:_AddSrcBlend=1}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0},  {type:SET_PROPERTY,data:_ZWrite=0}, {type:SET_PROPERTY,data:_ZTest=4},   {type:SET_PROPERTY,data:_AlphaPremultiply=0}, {type:SET_PROPERTY,data:_OutlineSrcBlend=1}, {type:SET_PROPERTY,data:_OutlineDstBlend=1},  {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]},
		{value:5,actions:[{type:SET_PROPERTY,data:render_queue=3000},{type:SET_PROPERTY,data:_AlphaForceOpaque=0}, {type:SET_PROPERTY,data:render_type=Transparent},       {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=0},  {type:SET_PROPERTY,data:_SrcBlend=4}, {type:SET_PROPERTY,data:_DstBlend=1},  {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1},  {type:SET_PROPERTY,data:_AddSrcBlend=4}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0},  {type:SET_PROPERTY,data:_ZWrite=0}, {type:SET_PROPERTY,data:_ZTest=4},   {type:SET_PROPERTY,data:_AlphaPremultiply=0}, {type:SET_PROPERTY,data:_OutlineSrcBlend=4}, {type:SET_PROPERTY,data:_OutlineDstBlend=1},  {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]},
		{value:6,actions:[{type:SET_PROPERTY,data:render_queue=3000},{type:SET_PROPERTY,data:_AlphaForceOpaque=0}, {type:SET_PROPERTY,data:render_type=Transparent},       {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=0},  {type:SET_PROPERTY,data:_SrcBlend=2}, {type:SET_PROPERTY,data:_DstBlend=0},  {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1},  {type:SET_PROPERTY,data:_AddSrcBlend=2}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0},  {type:SET_PROPERTY,data:_ZWrite=0}, {type:SET_PROPERTY,data:_ZTest=4},   {type:SET_PROPERTY,data:_AlphaPremultiply=0}, {type:SET_PROPERTY,data:_OutlineSrcBlend=2}, {type:SET_PROPERTY,data:_OutlineDstBlend=0},  {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]},
		{value:7,actions:[{type:SET_PROPERTY,data:render_queue=3000},{type:SET_PROPERTY,data:_AlphaForceOpaque=0}, {type:SET_PROPERTY,data:render_type=Transparent},       {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=0},  {type:SET_PROPERTY,data:_SrcBlend=2}, {type:SET_PROPERTY,data:_DstBlend=3},  {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1},  {type:SET_PROPERTY,data:_AddSrcBlend=2}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0},  {type:SET_PROPERTY,data:_ZWrite=0}, {type:SET_PROPERTY,data:_ZTest=4},   {type:SET_PROPERTY,data:_AlphaPremultiply=0}, {type:SET_PROPERTY,data:_OutlineSrcBlend=2}, {type:SET_PROPERTY,data:_OutlineDstBlend=3},  {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]}
		}]}]}", Int) = 0
		
		[HideInInspector] m_mainCategory ("Color & Normals--{button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/color-and-normals/main},hover:Documentation}}", Float) = 0
		//Main-main
		_Color ("Color & Alpha--{reference_property:_ColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _ColorThemeIndex ("", Int) = 0
		[sRGBWarning(true)]_MainTex ("Texture--{reference_properties:[_MainTexPan, _MainTexUV, _MainPixelMode, _MainTexStochastic]}", 2D) = "white" { }
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _MainTexUV ("UV", Int) = 0
		[HideInInspector][Vector2]_MainTexPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ToggleUI]_MainPixelMode ("Pixel Mode", Float) = 0
		[HideInInspector][ToggleUI]_MainTexStochastic ("Stochastic Sampling", Float) = 0
		[Normal]_BumpMap ("Normal Map--{reference_properties:[_BumpMapPan, _BumpMapUV, _BumpScale, _BumpMapStochastic]}", 2D) = "bump" { }
		[HideInInspector][Vector2]_BumpMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _BumpMapUV ("UV", Int) = 0
		[HideInInspector]_BumpScale ("Intensity", Range(0, 10)) = 1
		[HideInInspector][ToggleUI]_BumpMapStochastic ("Stochastic Sampling", Float) = 0
		[sRGBWarning]_AlphaMask ("Alpha Map--{reference_properties:[_AlphaMaskPan, _AlphaMaskUV, _AlphaMaskInvert, _MainAlphaMaskMode, _AlphaMaskScale, _AlphaMaskValue], alts:[_AlphaMap]}", 2D) = "white" { }
		[HideInInspector][Vector2]_AlphaMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _AlphaMaskUV ("UV", Int) = 0
		[HideInInspector][ThryWideEnum(Off, 0, Replace, 1, Multiply, 2, Add, 3, Subtract, 4)]_MainAlphaMaskMode ("Blend Mode", Int) = 2
		[HideInInspector]_AlphaMaskScale ("Blend Strength", Float) = 1
		[HideInInspector]_AlphaMaskValue ("Blend Offset", Float) = 0
		[HideInInspector][ToggleUI]_AlphaMaskInvert ("Invert", Float) = 0
		_Cutoff ("Alpha Cutoff", Range(0, 1.001)) = 0.5
		
		//ifex _MainColorAdjustToggle==0
		[HideInInspector] m_start_ColorAdjust ("Color Adjust--{reference_property:_MainColorAdjustToggle,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/color-and-normals/color-adjust},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(COLOR_GRADING_HDR)] _MainColorAdjustToggle ("Adjust Colors", Float) = 0
		[sRGBWarning][ThryRGBAPacker(R Hue Mask, G Brightness Mask, B Saturation Mask, , linear, false)]_MainColorAdjustTexture ("Mask (Expand)--{reference_properties:[_MainColorAdjustTexturePan, _MainColorAdjustTextureUV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_MainColorAdjustTexturePan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _MainColorAdjustTextureUV ("UV", Int) = 0
		_Saturation ("Saturation", Range(-1, 10)) = 0
		_MainBrightness ("Brightness", Range(-1, 1)) = 0
		
		[HideInInspector] s_start_MainHueShift ("Hue Shift--{reference_property:_MainHueShiftToggle,persistent_expand:true,default_expand:true}", Float) = 1
		[HideInInspector][ThryToggleUI(true)] _MainHueShiftToggle ("<size=13><b>  Hue Shift</b></size>", Float) = 0
		[ToggleUI]_MainHueShiftReplace ("Hue Replace?", Float) = 1
		_MainHueShift ("Hue Shift", Range(0, 1)) = 0
		_MainHueShiftSpeed ("Hue Shift Speed", Float) = 0
		
		[HideInInspector] s_start_MainHueShiftAL ("Hue Shift Audio Link--{reference_property:_MainHueALCTEnabled,persistent_expand:true,default_expand:false, condition_showS:(_EnableAudioLink==1)}", Float) = 0
		[HideInInspector][ThryToggleUI(true)]_MainHueALCTEnabled ("Hue Shift Audio Link", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)]_MainALHueShiftBand ("Band", Int) = 0
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_MainALHueShiftCTIndex ("Motion Type", Int) = 0
		_MainHueALMotionSpeed ("Motion Speed", Float) = 1
		[HideInInspector] s_end_MainHueShiftAL ("Audio Link", Float) = 0
		[HideInInspector] s_end_MainHueShift ("Name Motion", Float) = 0
		
		[HideInInspector] s_start_ColorAdjustColorGrading ("Color Grading--{reference_property:_ColorGradingToggle, persistent_expand:true}", Float) = 0
		[HideInInspector][ToggleUI] _ColorGradingToggle ("Color Grading", Float) = 0
		[NoScaleOffset] _MainGradationTex ("Gradation Map", 2D) = "white" { }
		_MainGradationStrength ("Gradation Strength", Range(0, 1)) = 0
		[HideInInspector] s_end_ColorAdjustColorGrading ("Color Grading", Float) = 0
		
		[HideInInspector] s_start_MainHueShiftGlobalMask ("Global Mask--{persistent_expand:true}", Float) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _MainHueGlobalMask ("Hue--{reference_property:_MainHueGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _MainHueGlobalMaskBlendType ("Blending", Int) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _MainSaturationGlobalMask ("Saturation--{reference_property:_MainSaturationGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _MainSaturationGlobalMaskBlendType ("Blending", Int) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _MainBrightnessGlobalMask ("Brightness--{reference_property:_MainBrightnessGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _MainBrightnessGlobalMaskBlendType ("Blending", Int) = 2
		[HideInInspector] s_end_MainHueShiftGlobalMask ("Global Mask", Float) = 0
		[HideInInspector] m_end_ColorAdjust ("Color Adjust", Float) = 0
		//endex
		
		[HideInInspector] m_start_Alpha ("Alpha Options--{button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/color-and-normals/alpha-options},hover:Documentation}}", Float) = 0
		[ToggleUI]_AlphaForceOpaque ("Force Opaque", Float) = 1
		_AlphaMod ("Alpha Mod", Range(-1, 1)) = 0.0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _AlphaGlobalMask ("Global Mask--{reference_property:_AlphaGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _AlphaGlobalMaskBlendType ("Blending", Int) = 2
		
		//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
		[HideInInspector] s_start_AlphaToCoverage ("Alpha To Coverage--{reference_property:_AlphaToCoverage,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI] _AlphaToCoverage ("A2CToggle", Float) = 0
		[ToggleUI]_AlphaSharpenedA2C ("Sharpened  A2C", Float) = 0
		_AlphaMipScale ("Mip Level Alpha Scale", Range(0, 1)) = 0.25
		[HideInInspector] s_end_AlphaToCoverage ("Alpha To Coverage", Float) = 0
		//endex
		
		//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
		[HideInInspector] s_start_AlphaDithering ("Dithering--{reference_property:_AlphaDithering,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI] _AlphaDithering ("Dithering", Float) = 0
		_AlphaDitherGradient ("Dither Gradient", Range(0, 1)) = .1
		_AlphaDitherBias ("Dither Bias", Range(0, 1)) = 0
		[HideInInspector] s_end_AlphaDithering ("Alpha To Coverage", Float) = 0
		//endex
		
		//ifex _AlphaDistanceFade==0 && isNotAnimated(_AlphaDistanceFade)
		[HideInInspector] s_start_AlphaDistanceFade ("Distance Alpha / Distance Fade--{reference_property:_AlphaDistanceFade,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI] _AlphaDistanceFade ("Distance Alpha", Float) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _AlphaDistanceFadeType ("Pos To Use", Int) = 1
		_AlphaDistanceFadeMinAlpha ("Min Distance Alpha", Range(0, 1)) = 0
		_AlphaDistanceFadeMaxAlpha ("Max Distance Alpha", Range(0, 1)) = 1
		_AlphaDistanceFadeMin ("Min Distance", Float) = 0
		_AlphaDistanceFadeMax ("Max Distance", Float) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _AlphaDistanceFadeGlobalMask ("Global Mask", Int) = 0
		[HideInInspector] s_end_AlphaDistanceFade ("Distance Alpha / Distance Fade", Float) = 0
		//endex
		
		//ifex _AlphaFresnel==0 && isNotAnimated(_AlphaFresnel)
		[HideInInspector] s_start_AlphaFresnel ("Fresnel Alpha--{reference_property:_AlphaFresnel,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI] _AlphaFresnel ("Fresnel Alpha", Float) = 0
		_AlphaFresnelAlpha ("Intensity", Range(0, 1)) = 0
		_AlphaFresnelSharpness ("Sharpness", Range(0, 1)) = .5
		_AlphaFresnelWidth ("Width", Range(0, 1)) = .5
		[ToggleUI]_AlphaFresnelInvert ("Invert", Float) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _AlphaFresnelGlobalMask ("Global Mask", Int) = 0
		[HideInInspector] s_end_AlphaFresnel ("Fresnel Alpha", Float) = 0
		//endex
		
		//ifex _AlphaAngular==0 && isNotAnimated(_AlphaAngular)
		[HideInInspector] s_start_AlphaAngular ("Angular Alpha--{reference_property:_AlphaAngular,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI] _AlphaAngular ("Angular Alpha", Float) = 0
		[Enum(Camera Face Model, 0, Model Face Camera, 1, Face Each Other, 2)] _AngleType ("Angle Type", Int) = 0
		[Enum(Model, 0, Vertex, 1)] _AngleCompareTo ("Model or Vert Positon", Int) = 0
		[Vector3]_AngleForwardDirection ("Forward Direction", Vector) = (0, 0, 1)
		_CameraAngleMin ("Camera Angle Min", Range(0, 180)) = 45
		_CameraAngleMax ("Camera Angle Max", Range(0, 180)) = 90
		_ModelAngleMin ("Model Angle Min", Range(0, 180)) = 45
		_ModelAngleMax ("Model Angle Max", Range(0, 180)) = 90
		_AngleMinAlpha ("Min Alpha", Range(0, 1)) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _AlphaAngularGlobalMask ("Global Mask", Int) = 0
		[HideInInspector] s_end_AlphaAngular ("Name", Float) = 0
		//endex
		
		//ifex _AlphaAudioLinkEnabled==0 && isNotAnimated(_AlphaAudioLinkEnabled)
		[HideInInspector] s_start_ALAlpha ("Alpha Audio Link--{reference_property:_AlphaAudioLinkEnabled,persistent_expand:true,default_expand:false, condition_showS:(_EnableAudioLink==1)}", Float) = 0
		[HideInInspector][ToggleUI]_AlphaAudioLinkEnabled ("Alpha Audio Link", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AlphaAudioLinkAddBand ("Add Band", Int) = 0
		[VectorLabel(Min, Max)]_AlphaAudioLinkAddRange ("Add Range", Vector) = (0, 0, 0)
		[HideInInspector] s_end_ALAlpha ("Alpha Audio Link", Float) = 0
		
		[HideInInspector] s_start_AlphaAdvanced ("Advanced--{persistent_expand:true,default_expand:false}", Float) = 0
		[ToggleUI]_AlphaPremultiply ("Alpha Premultiply", Float) = 0
		_AlphaBoostFA ("Boost Transparency in ForwardAdd--{condition_showS:(_AddBlendOp==4)}", Range(1, 100)) = 10
		[HideInInspector] s_end_AlphaAdvanced ("Advanced", Float) = 0
		//endex
		[HideInInspector] m_end_Alpha ("Alpha Options", Float) = 0
		
		//ifex _DetailEnabled==0
		[HideInInspector] m_start_DetailOptions ("Details--{reference_property:_DetailEnabled,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/color-and-normals/details},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(FINALPASS)]_DetailEnabled ("Enable", Float) = 0
		[sRGBWarning][ThryRGBAPacker(R Texture Mask, G Normal Mask, B Nothing, A Nothing, linear, false)]_DetailMask ("Detail Mask (Expand)--{reference_properties:[_DetailMaskPan, _DetailMaskUV, _DetailMaskStochastic]}", 2D) = "white" { }
		[HideInInspector][Vector2]_DetailMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _DetailMaskUV ("UV", Int) = 0
		[HideInInspector][ToggleUI]_DetailMaskStochastic ("Stochastic Sampling", Float) = 0
		
		[HideInInspector] s_start_DetailTexture ("Detail Texture--{persistent_expand:false,default_expand:true}", Float) = 0
		_DetailTint ("Tint--{reference_property:_DetailTintThemeIndex}", Color) = (1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _DetailTintThemeIndex ("", Int) = 0
		[sRGBWarning(true)]_DetailTex ("Detail Texture--{reference_properties:[_DetailTexPan, _DetailTexUV, _DetailTexStochastic]}", 2D) = "gray" { }
		[HideInInspector][Vector2]_DetailTexPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _DetailTexUV ("UV", Int) = 0
		[HideInInspector][ToggleUI]_DetailTexStochastic ("Stochastic Sampling", Float) = 0
		_DetailTexIntensity ("Intensity", Range(0, 10)) = 1
		_DetailBrightness ("Brightness", Range(0, 2)) = 1
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _DetailTexGlobalMask ("Global Mask--{reference_property:_DetailTexGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6 , Replace, 0)]_DetailTexGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		[HideInInspector] s_end_DetailTexture ("Detail Texture", Float) = 0
		
		[HideInInspector] s_start_DetailNormal ("Detail Normal--{persistent_expand:false,default_expand:true}", Float) = 0
		[Normal]_DetailNormalMap ("Detail Normal--{reference_properties:[_DetailNormalMapPan, _DetailNormalMapUV, _DetailNormalMapScale, _DetailNormalMapStochastic]}", 2D) = "bump" { }
		[HideInInspector]_DetailNormalMapScale ("Intensity", Range(0, 10)) = 1
		[HideInInspector][Vector2]_DetailNormalMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _DetailNormalMapUV ("UV", Int) = 0
		[HideInInspector][ToggleUI]_DetailNormalMapStochastic ("Stochastic Sampling", Float) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _DetailNormalGlobalMask ("Global Mask--{reference_property:_DetailNormalGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6 , Replace, 0)]_DetailNormalGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		[HideInInspector] s_end_DetailNormal ("Detail Normal", Float) = 0
		[HideInInspector] m_end_DetailOptions ("Details", Float) = 0
		//endex
		
		//ifex _VertexManipulationsEnabled==0
		[HideInInspector] m_start_vertexManipulation ("Vertex Options--{reference_property:_VertexManipulationsEnabled, button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/color-and-normals/vertex-options},hover:YouTube}}", Float) = 0
		[HideInInspector][ThryToggle(AUTO_EXPOSURE)]_VertexManipulationsEnabled ("Enabled", Float) = 0
		[Vector3]_VertexManipulationLocalTranslation ("Local Translation", Vector) = (0, 0, 0, 1)
		[Vector3]_VertexManipulationWorldTranslation ("World Translation", Vector) = (0, 0, 0, 1)
		_VertexManipulationLocalScale ("Scale", Vector) = (1, 1, 1, 1)
		[Vector3]_VertexManipulationLocalRotation ("Rotation", Vector) = (0, 0, 0, 1)
		[Vector3]_VertexManipulationLocalRotationSpeed ("Rotation Speed", Vector) = (0, 0, 0, 1)
		
		[HideInInspector] s_start_VertexManipulationHeight ("Height Map--{persistent_expand:true,default_expand:true}", Float) = 1
		[sRGBWarning]_VertexManipulationHeightMask ("Height Map--{reference_properties:[_VertexManipulationHeightMaskPan, _VertexManipulationHeightMaskUV, _VertexManipulationHeightMaskChannel]}", 2D) = "white" { }
		[HideInInspector][Vector2]_VertexManipulationHeightMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)] _VertexManipulationHeightMaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_VertexManipulationHeightMaskChannel ("Channel", Float) = 0
		_VertexManipulationHeight ("Height", Float) = 0
		_VertexManipulationHeightBias ("Map Bias", Range(0, 1)) = 0
		[HideInInspector] s_end_VertexManipulationHeight ("Height Map", Float) = 0
		
		[HideInInspector] s_start_vertexRounding ("Vertex Rounding (Blocky/PS1)--{reference_property:_VertexRoundingEnabled,persistent_expand:true,default_expand:true}", Float) = 0
		[HideInInspector][ToggleUI]_VertexRoundingEnabled ("Rounding Enabled", Float) = 0
		[Enum(World, 0, Local, 1)]_VertexRoundingSpace ("Rounding Space", Int) = 0
		_VertexRoundingDivision ("Rounding Interval", Float) = 0.02
		[HideInInspector] s_end_vertexRounding ("Vertex Rounding (Blocky/PS1)", Float) = 0
		
		[HideInInspector] s_start_VertexBarrelMode ("Barrel Distortion--{reference_property:_VertexBarrelMode,persistent_expand:true}", Float) = 0
		[HideInInspector][ThryToggleUI(true)]_VertexBarrelMode ("<size=13><b>  Barrel Mode</b></size>", Float) = 0
		_VertexBarrelWidth ("Barrel Width", Float) = 0.2
		_VertexBarrelAlpha ("Barrel Alpha", Range(0, 1)) = 0
		_VertexBarrelHeight ("Barrel Height", Range(0, 1)) = 0
		[HideInInspector] s_end_VertexBarrelMode ("Barrel Distortion", Float) = 0
		
		[HideInInspector] s_start_VertexSphereMode ("Sphere Distortion--{reference_property:_VertexSphereMode,persistent_expand:true}", Float) = 0
		[HideInInspector][ThryToggleUI(true)]_VertexSphereMode ("<size=13><b>  Sphere Mode</b></size>", Float) = 0
		_VertexSphereRadius ("Sphere Radius", Range(0, 1)) = 1
		_VertexSphereHeight ("Sphere Height", Range(0, 1)) = 1
		_VertexSphereAlpha ("Sphere Alpha", Range(0, 1)) = 0
		[Vector3]_VertexSphereCenter ("Sphere Center", Vector) = (0, 0, 0, 1)
		[HideInInspector] s_end_VertexSphereMode ("Sphere Distortion", Float) = 0
		
		[HideInInspector] s_start_VertexTornadoMode ("Tornado--{reference_property:_VertexTornadoMode,persistent_expand:true}", Float) = 0
		[HideInInspector][ThryToggleUI(true)]_VertexTornadoMode ("<size=13><b>  Tornado</b></size>", Float) = 0
		_VertexTornadoRadius ("Radius", Float) = .2
		_VertexTornadoIntensity ("Spiral Intensity", Float) = 100
		_VertexTornadoSpeed ("Rotation Speed", Float) = 5
		_VertexTornadoTopHeight ("Top Height", Float) = 1
		_VertexTornadoBaseHeight ("Bottom Height", Float) = 0
		[HideInInspector] s_end_VertexTornadoMode ("Tornado", Float) = 0
		
		[HideInInspector] s_start_VertAL ("Audio Link--{reference_property:_VertexAudioLinkEnabled,persistent_expand:true,default_expand:true,condition_showS:(_EnableAudioLink==1)}", Float) = 0
		[HideInInspector][ThryToggleUI(true)]_VertexAudioLinkEnabled ("Audio Link", Float) = 0
		
		[HideInInspector] s_start_LocalTranslation ("Local Translation--{persistent_expand:true,default_expand:true}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _VertexLocalTranslationALBand ("Band", Int) = 0
		[Vector3]_VertexLocalTranslationALMin ("Translation Min", Vector) = (0, 0, 0)
		[Vector3]_VertexLocalTranslationALMax ("Translation Max", Vector) = (0, 0, 0)
		[HideInInspector] s_end_LocalTranslation ("Local Translation", Float) = 0
		
		[HideInInspector] s_start_LocalRotation ("Local Rotation--{persistent_expand:true,default_expand:true}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _VertexLocalRotationALBandX ("Band X", Int) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _VertexLocalRotationALBandY ("Band Y", Int) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _VertexLocalRotationALBandZ ("Band Z", Int) = 0
		[Vector3]_VertexLocalRotationAL ("Rotation", Vector) = (0, 0, 0)
		[HideInInspector] s_end_LocalRotation ("Local Rotation", Float) = 0
		
		[HideInInspector] s_start_ContinuousRotation ("Continuous Rotation--{persistent_expand:true,default_expand:true}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _VertexLocalRotationCTALBandX ("Band X", Int) = 0
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_VertexLocalRotationCTALTypeX ("Motion Type X", Int) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _VertexLocalRotationCTALBandY ("Band Y", Int) = 0
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_VertexLocalRotationCTALTypeY ("Motion Type Y", Int) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _VertexLocalRotationCTALBandZ ("Band Z", Int) = 0
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_VertexLocalRotationCTALTypeZ ("Motion Type Z", Int) = 0
		[Vector3]_VertexLocalRotationCTALSpeed ("Speed", Vector) = (0, 0, 0)
		[HideInInspector] s_end_ContinuousRotation ("Continuous Rotation", Float) = 0
		
		[HideInInspector] s_start_VertexScale ("Vertex Scale--{persistent_expand:true,default_expand:true}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _VertexLocalScaleALBand ("Band", Int) = 0
		_VertexLocalScaleALMin ("Scale Min", Vector) = (0, 0, 0, 0)
		_VertexLocalScaleALMax ("Scale Max", Vector) = (0, 0, 0, 0)
		[HideInInspector] s_end_VertexScale ("Vertex Scale", Float) = 0
		
		[HideInInspector] s_start_WorldTranslation ("World Translation--{persistent_expand:true,default_expand:true}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _VertexWorldTranslationALBand ("Band", Int) = 0
		[Vector3]_VertexWorldTranslationALMin ("World Translation Min", Vector) = (0, 0, 0)
		[Vector3]_VertexWorldTranslationALMax ("World Translation Max", Vector) = (0, 0, 0)
		[HideInInspector] s_end_WorldTranslation ("World Translation", Float) = 0
		
		[HideInInspector] s_start_ALVertexHeight ("Vertex Height--{persistent_expand:true,default_expand:true}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _VertexManipulationHeightBand ("Band", Int) = 0
		[VectorLabel(Min, Max)]_VertexManipulationHeightAL ("Height", Vector) = (0, 0, 0)
		[HideInInspector] s_end_ALVertexHeight ("Vertex Height", Float) = 0
		
		[HideInInspector] s_start_vertexRoundingAL ("Vertex Rounding--{persistent_expand:true,default_expand:true}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _VertexRoundingRangeBand ("Band", Int) = 0
		[VectorLabel(Min, Max)]_VertexRoundingRangeAL ("Range", Vector) = (0, 0, 0)
		[HideInInspector] s_end_VertexRoundingAL ("Vertex Rounding", Float) = 0
		
		[HideInInspector] s_start_ALSpectrumMotion ("Spectrum Motion--{reference_property:_VertexSpectrumMotion,persistent_expand:true,default_expand:true}", Float) = 0
		[HideInInspector][ThryToggleUI(true)]_VertexSpectrumMotion ("Spectrum Motion", Float) = 0
		[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)] _VertexSpectrumUV ("UV", Int) = 0
		[Enum(X, 0, Y, 1)] _VertexSpectrumUVDirection ("UV Direction", Int) = 0
		_VertexSpectrumOffsetMin ("Offset Min", Vector) = (0, 0, 0)
		_VertexSpectrumOffsetMax ("Offset Max", Vector) = (0, .1, 0)
		[HideInInspector] s_end_ALSpectrumMotion ("Spectrum Motion", Float) = 0
		
		[HideInInspector] s_end_VertAL ("Audio Link", Float) = 0
		
		[HideInInspector] m_end_vertexManipulation ("Vertex Options", Float) = 0
		//endex
		
		//ifex _VertexGlitchingEnabled==0
		[HideInInspector] m_start_vertexGlitching ("Vertex Glitching--{reference_property:_VertexGlitchingEnabled}", Float) = 0
		[HideInInspector][ThryToggle(POI_VERTEX_GLITCHING)]_VertexGlitchingEnabled ("Enabled", Float) = 0
		// _VertexGlitchMap ("Glitch Map", 2D) = "white" { }
		_VertexGlitchFrequency ("Glitch Interval", Float) = 1
		_VertexGlitchThreshold ("Glitch Threshold", Range(0, 1)) = 1
		_VertexGlitchStrength ("Glitch Strength", Range(0, 10)) = 1
		[HideInInspector] s_start_VertexGlitchTexture ("Glitch Texture--{reference_property:_VertexGlitchingUseTexture,persistent_expand:true,default_expand:true}", Float) = 1
		[HideInInspector][ThryToggle(POI_VERTEX_GLITCHING_TEXTURE, true)]_VertexGlitchingUseTexture ("Use Texture", Float) = 0
		[sRGBWarning][ThryRGBAPacker(R Both, G Right, B Left, A unused, linear, false)]_VertexGlitchMap ("Glitch Map [Expand]", 2D) = "white" { }
		_VertexGlitchDensity ("Glitch Density", Range(0, 50)) = 10
		_VertexGlitchMapPanSpeed ("Glitch Map Pan Speed", Range(0, 100)) = 10
		[HideInInspector] s_end_VertexGlitchTexture ("Glitch Texture", Float) = 0
		
		[HideInInspector] s_start_VertexGlitchMirror ("Mirror--{reference_property:_VertexGlitchMirrorEnable,persistent_expand:true}", Float) = 0
		[HideInInspector][ThryToggleUI(true)]_VertexGlitchMirrorEnable ("Mirror", Float) = 0
		[ThryWideEnum(Show In Both, 0, Show Only In Mirror, 1, Dont Show In Mirror, 2)] _VertexGlitchMirror ("Show in mirror", Int) = 0
		[HideInInspector] s_end_VertexGlitchMirror ("Mirror", Float) = 0
		
		[HideInInspector] s_start_ALVertexGlitching ("Audio Link--{reference_property:_VertexGlitchingAudioLinkEnabled,persistent_expand:true,default_expand:false, condition_showS:(_EnableAudioLink==1)}", Float) = 0
		[ThryToggleUI(true)]_VertexGlitchingAudioLinkEnabled ("Audio Link", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, VU Intensity, 4)] _VertexGlitchingAudioLinkBand ("Glitch Band", Int) = 0
		[ThryToggleUI(true)]_VertexGlitchingAudiolinkOverride ("Override Glitch Intensity with Audiolink", Float) = 1
		[HideInInspector] s_end_ALVertexGlitching ("Audio Link", Float) = 0
		[HideInInspector] m_end_vertexGlitching ("Vertex Glitching", Float) = 0
		//endex
		
		//ifex _MainVertexColoringEnabled==0
		[HideInInspector] m_start_MainVertexColors ("Vertex Colors--{reference_property:_MainVertexColoringEnabled,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/color-and-normals/vertex-colors},hover:Documentation}}", Float) = 0
		[HideInInspector][ToggleUI]_MainVertexColoringEnabled ("Enable", Float) = 0
		[ToggleUI]_MainVertexColoringLinearSpace ("Linear Colors", Float) = 1
		_MainVertexColoring ("Use Vertex Color", Range(0, 1)) = 0
		_MainUseVertexColorAlpha ("Use Vertex Color Alpha", Range(0, 1)) = 0
		[HideInInspector] m_end_MainVertexColors ("Vertex Colors", Float) = 0
		//endex
		
		//ifex _BackFaceEnabled!=1
		// Back Face Textures and Emission
		[HideInInspector] m_start_backFace ("Back Face--{reference_property:_BackFaceEnabled,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/color-and-normals/back-face},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(POI_BACKFACE)]_BackFaceEnabled ("Backface Enabled", Float) = 0
		_BackFaceColor ("Color--{reference_property:_BackFaceColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _BackFaceColorThemeIndex ("", Int) = 0
		[sRGBWarning(true)]_BackFaceTexture ("Texture--{reference_properties:[_BackFaceTexturePan, _BackFaceTextureUV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_BackFaceTexturePan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_BackFaceTextureUV ("UV#", Int) = 0
		[sRGBWarning]_BackFaceMask ("Mask--{reference_properties:[_BackFaceMaskPan, _BackFaceMaskUV, _BackFaceMaskChannel]}", 2D) = "white" { }
		[HideInInspector][Vector2]_BackFaceMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_BackFaceMaskUV ("UV#", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_BackFaceMaskChannel ("Channel", Float) = 0
		_BackFaceEmissionStrength ("Emission Strength", Range(0, 20)) = 0
		
		[HideInInspector] s_start_BackFaceHueShift ("Hue Shift--{reference_property:_BackFaceHueShiftEnabled,persistent_expand:true}", Float) = 0
		[HideInInspector][ToggleUI]_BackFaceHueShiftEnabled ("Hue Shift", Float) = 0
		_BackFaceHueShift ("Shift", Range(0, 1)) = 0
		_BackFaceHueShiftSpeed ("Shift Speed", Float) = 0
		[HideInInspector] s_end_BackFaceHueShift ("Hue Shift", Float) = 0
		
		[HideInInspector] s_start_BackfaceMods ("Backface Mods--{persistent_expand:true,default_expand:false}", Float) = 0
		_BackFaceDetailIntensity ("Detail Intensity", Range(0, 5)) = 1
		[ToggleUI]_BackFaceReplaceAlpha ("Replace Alpha", Float) = 0
		_BackFaceEmissionLimiter ("Global Emission Multiplier", Float) = 1
		[HideInInspector] s_end_BackfaceMods ("Backface Mods", Float) = 0
		[HideInInspector] m_end_backFace ("Back Face", Float) = 0
		//endex
		
		//ifex _RGBMaskEnabled==0
		[HideInInspector] m_start_RGBMask ("RGBA Color Masking--{reference_property:_RGBMaskEnabled,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/color-and-normals/rgba-color-masking},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(VIGNETTE)]_RGBMaskEnabled ("RGB Mask Enabled", Float) = 0
		[ThryWideEnum(Texture, 0, Vertex Color, 1)]_RGBMaskType ("Mask Type", int) = 0
		
		[sRGBWarning][ThryRGBAPacker(R Mask, G Mask, B Mask, A Mask, Linear, false)]_RGBMask ("Masks [Expand]--{reference_properties:[_RGBMaskPan, _RGBMaskUV], condition_showS:_RGBMaskType==0}", 2D) = "white" { }
		[HideInInspector][Vector2]_RGBMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_RGBMaskUV ("UV", int) = 0
		
		[sRGBWarning][ThryRGBAPacker(Red Metallic, Green Metallic, Blue Metallic, Alpha Metallic, Linear, false)]_RGBAMetallicMaps ("Metallic Maps [Expand]--{reference_properties:[_RGBAMetallicMapsPan, _RGBAMetallicMapsUV, _RGBAMetallicMapsStochastic, _RGBARedMetallicInvert, _RGBAGreenMetallicInvert, _RGBABlueMetallicInvert, _RGBAAlphaMetallicInvert]}", 2D) = "white" { }
		[HideInInspector][Vector2]_RGBAMetallicMapsPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_RGBAMetallicMapsUV ("UV", Int) = 0
		[HideInInspector][ToggleUI]_RGBAMetallicMapsStochastic ("Stochastic Sampling", Float) = 0
		[HideInInspector][ToggleUI]_RGBARedMetallicInvert ("Invert R", Float) = 0
		[HideInInspector][ToggleUI]_RGBAGreenMetallicInvert ("Invert G", Float) = 0
		[HideInInspector][ToggleUI]_RGBABlueMetallicInvert ("Invert B", Float) = 0
		[HideInInspector][ToggleUI]_RGBAAlphaMetallicInvert ("Invert A", Float) = 0
		
		[sRGBWarning][ThryRGBAPacker(Red Smoothness, Green Smoothness, Blue Smoothness, Alpha Smoothness, Linear, false)]_RGBASmoothnessMaps ("Smoothness Maps [Expand]--{reference_properties:[_RGBASmoothnessMapsPan, _RGBASmoothnessMapsUV, _RGBASmoothnessMapsStochastic, _RGBARedSmoothnessInvert, _RGBAGreenSmoothnessInvert, _RGBABlueSmoothnessInvert, _RGBAAlphaSmoothnessInvert]}", 2D) = "white" { }
		[HideInInspector][Vector2]_RGBASmoothnessMapsPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_RGBASmoothnessMapsUV ("UV", Int) = 0
		[HideInInspector][ToggleUI]_RGBASmoothnessMapsStochastic ("Stochastic Sampling", Float) = 0
		[HideInInspector][ToggleUI]_RGBARedSmoothnessInvert ("Invert R", Float) = 0
		[HideInInspector][ToggleUI]_RGBAGreenSmoothnessInvert ("Invert G", Float) = 0
		[HideInInspector][ToggleUI]_RGBABlueSmoothnessInvert ("Invert B", Float) = 0
		[HideInInspector][ToggleUI]_RGBAAlphaSmoothnessInvert ("Invert A", Float) = 0
		
		[HideInInspector] s_start_RGBRed ("Red--{reference_property:_RGBARedEnable,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_RGBARedEnable ("Enable Red", Float) = 0
		[ThryWideEnum(Replace, 0, Darken, 1, Multiply, 2, Lighten, 5, Screen, 6, Subtract, 7, Add, 8, Overlay, 9, Mixed, 20)]_RGBARedBlendType ("Blend Mode", Range(0, 1)) = 0
		_RedColor ("Color--{reference_property:_RedColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _RedColorThemeIndex ("", Int) = 0
		[sRGBWarning(true)]_RedTexture ("Texture--{reference_properties:[_RedTexturePan, _RedTextureUV, _RedTextureStochastic, _RedAlphaAdd, _RgbRedMaskChannel, _RgbRedGlobalMaskChannel]}", 2D) = "white" { }
		[HideInInspector][Vector2]_RedTexturePan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_RedTextureUV ("UV", int) = 0
		[HideInInspector][ToggleUI]_RedTextureStochastic ("Stochastic Sampling", Float) = 0
		[HideInInspector]_RedAlphaAdd ("Alpha Add", Range(-1, 1)) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_RgbRedMaskChannel ("Mask Channel", Int) = 0
		[HideInInspector][ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _RgbRedGlobalMaskChannel ("Global Mask--{reference_property:_RgbRedGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _RgbRedGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		
		[Normal]_RgbNormalR ("Normal--{reference_properties:[_RgbNormalRPan, _RgbNormalRUV, _RgbNormalRStochastic, _RgbNormalRedBlendMode, _RgbNormalRMaskChannel, _RgbNormalRGlobalMaskChannel]}", 2D) = "bump" { }
		[HideInInspector][Vector2]_RgbNormalRPan ("Pan", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_RgbNormalRUV ("UV", int) = 0
		[HideInInspector][ToggleUI]_RgbNormalRStochastic ("Stochastic Sampling", Float) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_RgbNormalRMaskChannel ("Mask Channel", Int) = 0
		[HideInInspector][Enum(Replace, 0, Blend, 1)]_RgbNormalRedBlendMode ("Blend Mode", Int) = 0
		[HideInInspector][ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _RgbNormalRGlobalMaskChannel ("Global Mask--{reference_property:_RgbNormalRGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _RgbNormalRGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		_RgbNormalRScale ("Normal Intensity", Range(0, 10)) = 0
		_RGBARedEmissionStrength ("Emission Strength", Range(0, 20)) = 0
		
		[ToggleUI]_RGBAPBRRedEnabled ("Metallics & Smoothness", Float) = 0
		[ThryToggleUI(true)]_RGBARedPBRSplitMaskSample ("Custom Sampling--{condition_showS:(_RGBAPBRRedEnabled==1)}", Float) = 0
		[VectorLabel(tX, tY, oX, oY)]_RGBARedPBRMaskScaleTiling ("Tiling/Offset--{condition_showS:(_RGBARedPBRSplitMaskSample==1&&_RGBAPBRRedEnabled==1)}", Vector) = (1, 1, 0, 0)
		[ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_RGBARedPBRUV ("UV--{condition_showS:(_RGBARedPBRSplitMaskSample==1&&_RGBAPBRRedEnabled==1)}", Int) = 0
		[ToggleUI]_RGBARedPBRSplitMaskStochastic ("Stochastic Sampling--{condition_showS:(_RGBARedPBRSplitMaskSample==1&&_RGBAPBRRedEnabled==1)}", Float) = 0
		[Vector2]_RGBARedPBRMasksPan ("Panning--{condition_showS:(_RGBARedPBRSplitMaskSample==1&&_RGBAPBRRedEnabled==1)}", Vector) = (0, 0, 0, 0)
		[HideInInspector] s_end_RGBRed ("Red", Float) = 0
		
		[HideInInspector] s_start_RGBGreen ("Green--{reference_property:_RGBAGreenEnable,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_RGBAGreenEnable ("Enable Green", Float) = 0
		[ThryWideEnum(Replace, 0, Darken, 1, Multiply, 2, Lighten, 5, Screen, 6, Subtract, 7, Add, 8, Overlay, 9, Mixed, 20)]_RGBAGreenBlendType ("Blend Mode", Range(0, 1)) = 0
		_GreenColor ("Color--{reference_property:_GreenColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _GreenColorThemeIndex ("", Int) = 0
		[sRGBWarning(true)]_GreenTexture ("Texture--{reference_properties:[_GreenTexturePan, _GreenTextureUV, _GreenTextureStochastic, _GreenAlphaAdd, _RgbGreenMaskChannel, _RgbGreenGlobalMaskChannel]}", 2D) = "white" { }
		[HideInInspector][Vector2]_GreenTexturePan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_GreenTextureUV ("UV", int) = 0
		[HideInInspector][ToggleUI]_GreenTextureStochastic ("Stochastic Sampling", Float) = 0
		[HideInInspector]_GreenAlphaAdd ("Alpha Add", Range(-1, 1)) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_RgbGreenMaskChannel ("Mask Channel", Int) = 1
		[HideInInspector][ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _RgbGreenGlobalMaskChannel ("Global Mask--{reference_property:_RgbGreenGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _RgbGreenGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		
		[Normal]_RgbNormalG ("Normal--{reference_properties:[_RgbNormalGPan, _RgbNormalGUV, _RgbNormalGStochastic, _RgbNormalGreenBlendMode, _RgbNormalGMaskChannel, _RgbNormalGGlobalMaskChannel]}", 2D) = "bump" { }
		[HideInInspector][Vector2]_RgbNormalGPan ("Pan", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_RgbNormalGUV ("UV", int) = 0
		[HideInInspector][ToggleUI]_RgbNormalGStochastic ("Stochastic Sampling", Float) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_RgbNormalGMaskChannel ("Mask Channel", Int) = 1
		[HideInInspector][Enum(Replace, 0, Blend, 1)]_RgbNormalGreenBlendMode ("Blend Mode", Int) = 0
		[HideInInspector][ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _RgbNormalGGlobalMaskChannel ("Global Mask--{reference_property:_RgbNormalGGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _RgbNormalGGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		_RgbNormalGScale ("Normal Intensity", Range(0, 10)) = 0
		_RGBAGreenEmissionStrength ("Emission Strength", Range(0, 20)) = 0
		
		[ToggleUI]_RGBAPBRGreenEnabled ("Metallics & Smoothness", Float) = 0
		[ThryToggleUI(true)]_RGBAGreenPBRSplitMaskSample ("Custom Sampling--{condition_showS:(_RGBAPBRGreenEnabled==1)}", Float) = 0
		[VectorLabel(tX, tY, oX, oY)]_RGBAGreenPBRMaskScaleTiling ("Tiling/Offset--{condition_showS:(_RGBAGreenPBRSplitMaskSample==1&&_RGBAPBRGreenEnabled==1)}", Vector) = (1, 1, 0, 0)
		[ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_RGBAGreenPBRUV ("UV--{condition_showS:(_RGBAGreenPBRSplitMaskSample==1&&_RGBAPBRGreenEnabled==1)}", Int) = 0
		[ToggleUI]_RGBAGreenPBRSplitMaskStochastic ("Stochastic Sampling--{condition_showS:(_RGBAGreenPBRSplitMaskSample==1&&_RGBAPBRGreenEnabled==1)}", Float) = 0
		[Vector2]_RGBAGreenPBRMasksPan ("Panning--{condition_showS:(_RGBAGreenPBRSplitMaskSample==1&&_RGBAPBRGreenEnabled==1)}", Vector) = (0, 0, 0, 0)
		[HideInInspector] s_end_RGBGreen ("Green", Float) = 0
		
		[HideInInspector] s_start_RGBBlue ("Blue--{reference_property:_RGBABlueEnable,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_RGBABlueEnable ("Enable Blue", Float) = 0
		[ThryWideEnum(Replace, 0, Darken, 1, Multiply, 2, Lighten, 5, Screen, 6, Subtract, 7, Add, 8, Overlay, 9, Mixed, 20)]_RGBABlueBlendType ("Blend Mode", Range(0, 1)) = 0
		_BlueColor ("Color--{reference_property:_BlueColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _BlueColorThemeIndex ("", Int) = 0
		[sRGBWarning(true)]_BlueTexture ("Texture--{reference_properties:[_BlueTexturePan, _BlueTextureUV, _BlueTextureStochastic, _BlueAlphaAdd, _RgbBlueMaskChannel, _RgbBlueGlobalMaskChannel]}", 2D) = "white" { }
		[HideInInspector][Vector2]_BlueTexturePan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_BlueTextureUV ("UV", int) = 0
		[HideInInspector][ToggleUI]_BlueTextureStochastic ("Stochastic Sampling", Float) = 0
		[HideInInspector]_BlueAlphaAdd ("Alpha Add", Range(-1, 1)) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_RgbBlueMaskChannel ("Mask Channel", Int) = 2
		[HideInInspector][ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _RgbBlueGlobalMaskChannel ("Global Mask--{reference_property:_RgbBlueGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _RgbBlueGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		
		[Normal]_RgbNormalB ("Normal--{reference_properties:[_RgbNormalBPan, _RgbNormalBUV, _RgbNormalBStochastic, _RgbNormalBlueBlendMode, _RgbNormalBMaskChannel, _RgbNormalBGlobalMaskChannel]}", 2D) = "bump" { }
		[HideInInspector][Vector2]_RgbNormalBPan ("Pan", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_RgbNormalBUV ("UV", int) = 0
		[HideInInspector][ToggleUI]_RgbNormalBStochastic ("Stochastic Sampling", Float) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_RgbNormalBMaskChannel ("Mask Channel", Int) = 2
		[HideInInspector][Enum(Replace, 0, Blend, 1)]_RgbNormalBlueBlendMode ("Blend Mode", Int) = 0
		[HideInInspector][ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _RgbNormalBGlobalMaskChannel ("Global Mask--{reference_property:_RgbNormalBGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _RgbNormalBGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		_RgbNormalBScale ("Normal Intensity", Range(0, 10)) = 0
		_RGBABlueEmissionStrength ("Emission Strength", Range(0, 20)) = 0
		
		[ToggleUI]_RGBAPBRBlueEnabled ("Metallics & Smoothness", Float) = 0
		[ThryToggleUI(true)]_RGBABluePBRSplitMaskSample ("Custom Sampling--{condition_showS:(_RGBAPBRBlueEnabled==1)}", Float) = 0
		[VectorLabel(tX, tY, oX, oY)]_RGBABluePBRMaskScaleTiling ("Tiling/Offset--{condition_showS:(_RGBABluePBRSplitMaskSample==1&&_RGBAPBRBlueEnabled==1)}", Vector) = (1, 1, 0, 0)
		[ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_RGBABluePBRUV ("UV--{condition_showS:(_RGBABluePBRSplitMaskSample==1&&_RGBAPBRBlueEnabled==1)}", Int) = 0
		[ToggleUI]_RGBABluePBRSplitMaskStochastic ("Stochastic Sampling--{condition_showS:(_RGBABluePBRSplitMaskSample==1&&_RGBAPBRBlueEnabled==1)}", Float) = 0
		[Vector2]_RGBABluePBRMasksPan ("Panning--{condition_showS:(_RGBABluePBRSplitMaskSample==1&&_RGBAPBRBlueEnabled==1)}", Vector) = (0, 0, 0, 0)
		[HideInInspector] s_end_RGBBlue ("Blue", Float) = 0
		
		[HideInInspector] s_start_RGBAlpha ("Alpha--{reference_property:_RGBAAlphaEnable,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_RGBAAlphaEnable ("Enable Alpha", Float) = 0
		[ThryWideEnum(Replace, 0, Darken, 1, Multiply, 2, Lighten, 5, Screen, 6, Subtract, 7, Add, 8, Overlay, 9, Mixed, 20)]_RGBAAlphaBlendType ("Blend Mode", Range(0, 1)) = 0
		_AlphaColor ("Color--{reference_property:_AlphaColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _AlphaColorThemeIndex ("", Int) = 0
		[sRGBWarning(true)]_AlphaTexture ("Texture--{reference_properties:[_AlphaTexturePan, _AlphaTextureUV, _AlphaTextureStochastic, _AlphaAlphaAdd, _RgbAlphaMaskChannel, _RgbAlphaGlobalMaskChannel]}", 2D) = "white" { }
		[HideInInspector][Vector2]_AlphaTexturePan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_AlphaTextureUV ("UV", int) = 0
		[HideInInspector][ToggleUI]_AlphaTextureStochastic ("Stochastic Sampling", Float) = 0
		[HideInInspector]_AlphaAlphaAdd ("Alpha Add", Range(-1, 1)) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_RgbAlphaMaskChannel ("Mask Channel", Int) = 3
		[HideInInspector][ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _RgbAlphaGlobalMaskChannel ("Global Mask--{reference_property:_RgbAlphaGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _RgbAlphaGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		
		[Normal]_RgbNormalA ("Normal--{reference_properties:[_RgbNormalAPan, _RgbNormalAUV, _RgbNormalAStochastic, _RgbNormalAlphaBlendMode,_RgbNormalAMaskChannel, _RgbNormalAGlobalMaskChannel]}", 2D) = "bump" { }
		[HideInInspector][Vector2]_RgbNormalAPan ("Pan", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_RgbNormalAUV ("UV", int) = 0
		[HideInInspector][ToggleUI]_RgbNormalAStochastic ("Stochastic Sampling", Float) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_RgbNormalAMaskChannel ("Mask Channel", Int) = 3
		[HideInInspector][Enum(Replace, 0, Blend, 1)]_RgbNormalAlphaBlendMode ("Blend Mode", Int) = 0
		[HideInInspector][ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _RgbNormalAGlobalMaskChannel ("Global Mask--{reference_property:_RgbNormalAGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _RgbNormalAGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		_RgbNormalAScale ("Normal Intensity", Range(0, 10)) = 0
		_RGBAAlphaEmissionStrength ("Emission Strength", Range(0, 20)) = 0
		
		[ToggleUI]_RGBAPBRAlphaEnabled ("Metallics & Smoothness", Float) = 0
		[ThryToggleUI(true)]_RGBAAlphaPBRSplitMaskSample ("Custom Sampling--{condition_showS:(_RGBAPBRAlphaEnabled==1)}", Float) = 0
		[VectorLabel(tX, tY, oX, oY)]_RGBAAlphaPBRMaskScaleTiling ("Tiling/Offset--{condition_showS:(_RGBAAlphaPBRSplitMaskSample==1&&_RGBAPBRAlphaEnabled==1)}", Vector) = (1, 1, 0, 0)
		[ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_RGBAAlphaPBRUV ("UV--{condition_showS:(_RGBAAlphaPBRSplitMaskSample==1&&_RGBAPBRAlphaEnabled==1)}", Int) = 0
		[ToggleUI]_RGBAAlphaPBRSplitMaskStochastic ("Stochastic Sampling--{condition_showS:(_RGBAAlphaPBRSplitMaskSample==1&&_RGBAPBRAlphaEnabled==1)}", Float) = 0
		[Vector2]_RGBAAlphaPBRMasksPan ("Panning--{condition_showS:(_RGBAAlphaPBRSplitMaskSample==1&&_RGBAPBRAlphaEnabled==1)}", Vector) = (0, 0, 0, 0)
		[HideInInspector] s_end_RGBAlpha ("Alpha", Float) = 0
		[HideInInspector] m_end_RGBMask ("RGB Color Masking", Float) = 0
		//endex
		
		//ifex _DecalEnabled==0 && _DecalEnabled1==0 && _DecalEnabled2==0 && _DecalEnabled3==0
		// Decal Texture
		[HideInInspector] m_start_DecalSection ("Decals--{button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/color-and-normals/decals},hover:YouTube}}", Float) = 0
		[sRGBWarning][ThryRGBAPacker(Decal 0 Mask, Decal 1 Mask, Decal 2 Mask, Decal 3 Mask, Linear, false)]_DecalMask ("Decal RGBA Mask--{reference_properties:[_DecalMaskPan, _DecalMaskUV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_DecalMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _DecalMaskUV ("UV", Int) = 0
		//ifex 0==0
		//_Udon_VideoTex ("Video Debug Texture", 2D) = "white" { }
		//endex
		
		[HideInInspector] s_start_DecalTPSMaskGroup ("--{condition_showS:(_TPSPenetratorEnabled==1)}", Float) = 0
		[ThryToggleUI(true)] _DecalTPSDepthMaskEnabled ("<size=13><b>  TPS Depth Enabled</b></size>", Float) = 0
		_Decal0TPSMaskStrength ("Mask r Strength--{condition_showS:(_DecalTPSDepthMaskEnabled==1)}", Range(0, 1)) = 1
		_Decal1TPSMaskStrength ("Mask g Strength--{condition_showS:(_DecalTPSDepthMaskEnabled==1)}", Range(0, 1)) = 1
		_Decal2TPSMaskStrength ("Mask b Strength--{condition_showS:(_DecalTPSDepthMaskEnabled==1)}", Range(0, 1)) = 1
		_Decal3TPSMaskStrength ("Mask a Strength--{condition_showS:(_DecalTPSDepthMaskEnabled==1)}", Range(0, 1)) = 1
		[HideInInspector] s_end_DecalTPSMaskGroup ("", Float) = 0
		//ifex _DecalEnabled==0
		// Decal 0
		[HideInInspector] m_start_Decal0 ("Decal 0--{reference_property:_DecalEnabled}", Float) = 0
		[HideInInspector][ThryToggle(GEOM_TYPE_BRANCH)]_DecalEnabled ("Enable", Float) = 0
		[HideInInspector] s_start_decal_position ("Positioning--{persistent_expand:true,default_expand:true}", Float) = 1
		[ThryDecalPositioning(_DecalTexture, _DecalTextureUV, _DecalPosition, _DecalRotation, _DecalScale, _DecalSideOffset)]
		[Vector2]_DecalPosition ("Position", Vector) = (.5, .5, 0, 0)
		_DecalRotation ("Rotation", Range(0, 360)) = 0
		_DecalRotationSpeed ("Rotation Speed", Float) = 0
		[VectorLabel(X, Y)]_DecalScale ("Scale", Vector) = (1, 1, 1, 0)
		[VectorLabel(L, R, D, U)]_DecalSideOffset ("Side Offset", Vector) = (0, 0, 0, 0)
		[ToggleUI]_DecalTiled ("Tiled", Float) = 0
		[HideInInspector] s_end_decal_position ("Positioning", Float) = 0
		
		_DecalColor ("Color--{reference_property:_DecalColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _DecalColorThemeIndex ("", Int) = 0
		[sRGBWarning(true)]_DecalTexture ("Decal--{reference_properties:[_DecalTexturePan, _DecalTextureUV, _Decal0MaskChannel]}", 2D) = "white" { }
		[HideInInspector][Vector2]_DecalTexturePan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _DecalTextureUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)] _Decal0MaskChannel ("Mask Channel", Int) = 0
		
		_DecalEmissionStrength ("Emission Strength", Range(0, 20)) = 0
		[ThryWideEnum(Replace, 0, Darken, 1, Multiply, 2, Lighten, 5, Screen, 6, Subtract, 7, Add, 8, Overlay, 9, Mixed, 20)]_DecalBlendType ("Color Blend Mode", Range(0, 1)) = 0
		[ThryWideEnum(Off, 0, Replace, 1, Multiply, 2, Add, 3, Subtract, 4, Min, 5, Max, 6)]_DecalOverrideAlpha ("Alpha Blend Mode--{reference_property:_Decal0OverrideAlphaMode}", Float) = 0
		[HideInInspector][Enum(Everywhere, 0, Decal Bounds, 1)] _Decal0OverrideAlphaMode ("Mode", Int) = 0
		_DecalBlendAlpha ("Alpha", Range(0, 1)) = 1
		_Decal0Depth ("Depth", Range(-0.5, 2)) = 0
		
		[HideInInspector] s_start_Decal0HueShift ("Hue Shift--{reference_property:_DecalHueShiftEnabled, persistent_expand:true, default_expand:false}", Float) = 0
		[HideInInspector][ThryToggleUI(true)]_DecalHueShiftEnabled ("Hue Shift", Float) = 0
		_DecalHueShiftSpeed ("Shift Speed", Float) = 0
		_DecalHueShift ("Hue Shift", Range(0, 1)) = 0
		_Decal0HueAngleStrength ("Hue Angle Power", Float) = 0
		[HideInInspector] s_end_Decal0HueShift ("Hue Shift", Float) = 0
		
		[HideInInspector] s_start_Decal0Video ("Video Texture--{reference_property:_Decal0VideoEnabled, persistent_expand:true, default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI] _Decal0VideoEnabled ("Video Texture", Float) = 0
		[ThryWideEnum(Shrink2Fit, 0, Grow2Fit, 1, Off, 2)] _Decal0VideoAspectFix ("Aspect Ratio", Int) = 0
		[ToggleUI] _Decal0VideoFitToScale ("Fit To Scale--{condition_showS:(_Decal0VideoAspectFix==0||_Decal0VideoAspectFix==1)}", Float) = 1
		[ToggleUI] _Decal0UseDecalAlpha ("Use Decal Alpha", Float) = 0
		[ToggleUI] _Decal0OnlyVideo ("Only Show Video", Float) = 0
		_Decal0VideoEmissionStrength ("Emission", Range(0, 20)) = 0
		[HideInInspector] s_end_Decal0Video ("Video Texture", Float) = 0
		
		[HideInInspector] s_start_Decal0ChannelSeparation ("Chromatic Aberration--{reference_property:_Decal0ChannelSeparationEnable, persistent_expand:true, default_expand:false}", Int) = 0
		[HideInInspector][NoAnimate][ThryToggle(true)]_Decal0ChannelSeparationEnable ("Chromatic Aberration", Float) = 0
		_Decal0ChannelSeparation ("Intensity", Float) = 0
		_Decal0ChannelSeparationAngleStrength ("Surface Angle Intensity", Float) = 0
		_Decal0ChannelSeparationHue ("Hue", Range(-1, 1)) = 0
		_Decal0ChannelSeparationVertical ("Direction", Range(-3.142, 3.142)) = 0
		[ToggleUI]_Decal0ChannelSeparationPremultiply ("Premultiply Alpha--{tooltip:''Fixes Chromatic Aberration issues on some decal textures''}", Float) = 0
		[HideInInspector] s_end_Decal0ChannelSeparation ("", Int) = 0
		
		[HideInInspector] s_start_Decal0GlobalMasking ("Masking--{persistent_expand:false, default_expand:false}", Float) = 0
		[ThryWideEnum(Off, 0, Front Only, 1, Back Only, 2)] _Decal0FaceMask ("Face Mask", Int) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _Decal0GlobalMask (" Apply From Global Mask--{reference_property:_Decal0GlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_Decal0GlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _Decal0ApplyGlobalMaskIndex (" Apply to Global Mask--{reference_property:_Decal0ApplyGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _Decal0ApplyGlobalMaskBlendType ("Blending", Int) = 0
		[HideInInspector] s_end_Decal0GlobalMasking ("Masking", Float) = 0
		// Decal 0 Audio Link
		[HideInInspector] m_start_Decal0AudioLink ("Audio Link ♫--{ condition_showS:_EnableAudioLink==1}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal0ScaleBand ("Scale Band", Int) = 0
		[VectorLabel(Xmin, Ymin, Xmax, Ymax)]_AudioLinkDecal0Scale ("Scale Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal0SideBand ("Side Band", Int) = 0
		[VectorLabel(L, R, D, U)]_AudioLinkDecal0SideMin ("Side Mod Min", Vector) = (0, 0, 0, 0)
		[VectorLabel(L, R, D, U)]_AudioLinkDecal0SideMax ("Side Mod Max", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal0RotationBand ("Rotation Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDecal0Rotation ("Rotation Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal0AlphaBand ("Alpha Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDecal0Alpha ("Alpha Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal0EmissionBand ("Emission Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDecal0Emission ("Emission Mod", Vector) = (0, 0, 0, 0)
		[ToggleUI]_AudioLinkDecalCC0 ("CC Strip", Float) = 0
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _DecalRotationCTALBand0 ("Chrono Rotation Band", Int) = 0
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_DecalRotationCTALType0 ("Chrono Motion Type", Int) = 0
		_DecalRotationCTALSpeed0 ("Chrono Rotation Speed", Float) = 0
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal0ChannelSeparationBand ("Chromatic Aberration Band--{condition_showS:(_Decal0ChannelSeparationEnable==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDecal0ChannelSeparation ("Chromatic Aberration--{condition_showS:(_Decal0ChannelSeparationEnable==1)}", Vector) = (0, 0, 0, 0)
		[HideInInspector] m_end_Decal0AudioLink ("Audio Link", Float) = 0
		[HideInInspector] m_end_Decal0 ("Decal 0", Float) = 0
		//endex
		//ifex _DecalEnabled1==0
		// Decal 1
		[HideInInspector] m_start_Decal1 ("Decal 1--{reference_property:_DecalEnabled1}", Float) = 0
		[HideInInspector][ThryToggle(GEOM_TYPE_BRANCH_DETAIL)]_DecalEnabled1 ("Enable", Float) = 0
		[HideInInspector] s_start_decal1_position ("Positioning--{persistent_expand:true,default_expand:true}", Float) = 1
		[ThryDecalPositioning(_DecalTexture1, _DecalTexture1UV, _DecalPosition1, _DecalRotation1, _DecalScale1, _DecalSideOffset1)]
		[Vector2]_DecalPosition1 ("Position", Vector) = (.5, .5, 0, 0)
		_DecalRotation1 ("Rotation", Range(0, 360)) = 0
		_DecalRotationSpeed1 ("Rotation Speed", Float) = 0
		[VectorLabel(X, Y)]_DecalScale1 ("Scale", Vector) = (1, 1, 1, 0)
		[VectorLabel(L, R, D, U)]_DecalSideOffset1 ("Side Offset", Vector) = (0, 0, 0, 0)
		[ToggleUI]_DecalTiled1 ("Tiled", Float) = 0
		[HideInInspector] s_end_decal1_position ("Positioning", Float) = 0
		
		_DecalColor1 ("Color--{reference_property:_DecalColor1ThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _DecalColor1ThemeIndex ("", Int) = 0
		[sRGBWarning(true)]_DecalTexture1 ("Decal--{reference_properties:[_DecalTexture1Pan, _DecalTexture1UV, _Decal1MaskChannel]}", 2D) = "white" { }
		[HideInInspector][Vector2]_DecalTexture1Pan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _DecalTexture1UV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)] _Decal1MaskChannel ("Mask Channel", Int) = 1
		
		_DecalEmissionStrength1 ("Emission Strength", Range(0, 20)) = 0
		[ThryWideEnum(Replace, 0, Darken, 1, Multiply, 2, Lighten, 5, Screen, 6, Subtract, 7, Add, 8, Overlay, 9, Mixed, 20)]_DecalBlendType1 ("Color Blend Mode", Range(0, 1)) = 0
		[ThryWideEnum(Off, 0, Replace, 1, Multiply, 2, Add, 3, Subtract, 4, Min, 5, Max, 6)]_DecalOverrideAlpha1 ("Alpha Blend Mode--{reference_property:_Decal1OverrideAlphaMode}", Float) = 0
		[HideInInspector][Enum(Everywhere, 0, Decal Bounds, 1)] _Decal1OverrideAlphaMode ("Mode", Int) = 0
		_DecalBlendAlpha1 ("Alpha", Range(0, 1)) = 1
		_Decal1Depth ("Depth", Range(-0.5, 2)) = 0
		
		[HideInInspector] s_start_Decal1HueShift ("Hue Shift--{reference_property:_DecalHueShiftEnabled1, persistent_expand:true, default_expand:false}", Float) = 0
		[HideInInspector][ThryToggleUI(true)]_DecalHueShiftEnabled1 ("Hue Shift", Float) = 0
		_DecalHueShiftSpeed1 ("Shift Speed", Float) = 0
		_DecalHueShift1 ("Hue Shift", Range(0, 1)) = 0
		_Decal1HueAngleStrength ("Hue Angle Power", Float) = 0
		[HideInInspector] s_end_Decal1HueShift ("Hue Shift", Float) = 0
		
		[HideInInspector] s_start_Decal1Video ("Video Texture--{reference_property:_Decal1VideoEnabled, persistent_expand:true, default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI] _Decal1VideoEnabled ("Video Texture", Float) = 0
		[ThryWideEnum(Shrink2Fit, 0, Grow2Fit, 1, Off, 2)] _Decal1VideoAspectFix ("Aspect Ratio", Int) = 0
		[ToggleUI] _Decal1VideoFitToScale ("Fit To Scale--{condition_showS:(_Decal1VideoAspectFix==0||_Decal1VideoAspectFix==1)}", Float) = 1
		[ToggleUI] _Decal1UseDecalAlpha ("Use Decal Alpha", Float) = 0
		[ToggleUI] _Decal1OnlyVideo ("Only Show Video", Float) = 0
		_Decal1VideoEmissionStrength ("Emission", Range(0, 20)) = 0
		[HideInInspector] s_end_Decal1Video ("Video Texture", Float) = 0
		
		[HideInInspector] s_start_Decal1ChannelSeparation ("Chromatic Aberration--{reference_property:_Decal1ChannelSeparationEnable, persistent_expand:true, default_expand:false}", Int) = 0
		[HideInInspector][NoAnimate][ThryToggle(true)]_Decal1ChannelSeparationEnable ("Chromatic Aberration", Float) = 0
		_Decal1ChannelSeparation ("Intensity", Float) = 0
		_Decal1ChannelSeparationAngleStrength ("Surface Angle Intensity", Float) = 0
		_Decal1ChannelSeparationHue ("Hue", Range(-1, 1)) = 0
		_Decal1ChannelSeparationVertical ("Direction", Range(-3.142, 3.142)) = 0
		[ToggleUI]_Decal1ChannelSeparationPremultiply ("Premultiply Alpha--{tooltip:''Fixes Chromatic Aberration issues on some decal textures''}", Float) = 0
		[HideInInspector] s_end_Decal1ChannelSeparation ("", Int) = 0
		
		[HideInInspector] s_start_Decal1GlobalMasking ("Masking--{persistent_expand:false, default_expand:false}", Float) = 0
		[ThryWideEnum(Off, 0, Front Only, 1, Back Only, 2)] _Decal1FaceMask ("Face Mask", Int) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _Decal1GlobalMask ("Apply From Global Mask--{reference_property:_Decal1GlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_Decal1GlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _Decal1ApplyGlobalMaskIndex ("Apply to Global Mask--{reference_property:_Decal1ApplyGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _Decal1ApplyGlobalMaskBlendType ("Blending", Int) = 0
		[HideInInspector] s_end_Decal1GlobalMasking ("Masking", Float) = 0
		// Decal 1 Audio Link
		[HideInInspector] m_start_Decal1AudioLink ("Audio Link ♫--{ condition_showS:_EnableAudioLink==1}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal1ScaleBand ("Scale Band", Int) = 0
		[VectorLabel(Xmin, Ymin, Xmax, Ymax)]_AudioLinkDecal1Scale ("Scale Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal1SideBand ("Side Band", Int) = 0
		[VectorLabel(L, R, D, U)]_AudioLinkDecal1SideMin ("Side Mod Min", Vector) = (0, 0, 0, 0)
		[VectorLabel(L, R, D, U)]_AudioLinkDecal1SideMax ("Side Mod Max", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal1RotationBand ("Rotation Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDecal1Rotation ("Rotation Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal1AlphaBand ("Alpha Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDecal1Alpha ("Alpha Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal1EmissionBand ("Emission Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDecal1Emission ("Emission Mod", Vector) = (0, 0, 0, 0)
		[ToggleUI]_AudioLinkDecalCC1 ("CC Strip", Float) = 0
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _DecalRotationCTALBand1 ("Chrono Rotation Band", Int) = 0
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_DecalRotationCTALType1 ("Chrono Motion Type", Int) = 0
		_DecalRotationCTALSpeed1 ("Chrono Rotation Speed", Float) = 0
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal1ChannelSeparationBand ("Chromatic Aberration Band--{condition_showS:(_Decal1ChannelSeparationEnable==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDecal1ChannelSeparation ("Chromatic Aberration--{condition_showS:(_Decal1ChannelSeparationEnable==1)}", Vector) = (0, 0, 0, 0)
		[HideInInspector] m_end_Decal1AudioLink ("Audio Link", Float) = 0
		[HideInInspector] m_end_Decal1 ("Decal 0", Float) = 0
		//endex
		//ifex _DecalEnabled2==0
		// Decal 2
		[HideInInspector] m_start_Decal2 ("Decal 2--{reference_property:_DecalEnabled2}", Float) = 0
		[HideInInspector][ThryToggle(GEOM_TYPE_FROND)]_DecalEnabled2 ("Enable", Float) = 0
		[HideInInspector] s_start_decal2_position ("Positioning--{persistent_expand:true,default_expand:true}", Float) = 1
		[ThryDecalPositioning(_DecalTexture2, _DecalTexture2UV, _DecalPosition2, _DecalRotation2, _DecalScale2, _DecalSideOffset2)]
		[Vector2]_DecalPosition2 ("Position", Vector) = (.5, .5, 0, 0)
		_DecalRotation2 ("Rotation", Range(0, 360)) = 0
		_DecalRotationSpeed2 ("Rotation Speed", Float) = 0
		[VectorLabel(X, Y)]_DecalScale2 ("Scale", Vector) = (1, 1, 1, 0)
		[VectorLabel(L, R, D, U)]_DecalSideOffset2 ("Side Offset", Vector) = (0, 0, 0, 0)
		[ToggleUI]_DecalTiled2 ("Tiled", Float) = 0
		[HideInInspector] s_end_decal2_position ("Positioning", Float) = 0
		
		_DecalColor2 ("Color--{reference_property:_DecalColor2ThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _DecalColor2ThemeIndex ("", Int) = 0
		[sRGBWarning(true)]_DecalTexture2 ("Decal--{reference_properties:[_DecalTexture2Pan, _DecalTexture2UV, _Decal2MaskChannel]}", 2D) = "white" { }
		[HideInInspector][Vector2]_DecalTexture2Pan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _DecalTexture2UV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)] _Decal2MaskChannel ("Mask Channel", Int) = 2
		
		_DecalEmissionStrength2 ("Emission Strength", Range(0, 20)) = 0
		[ThryWideEnum(Replace, 0, Darken, 1, Multiply, 2, Lighten, 5, Screen, 6, Subtract, 7, Add, 8, Overlay, 9, Mixed, 20)]_DecalBlendType2 ("Color Blend Mode", Range(0, 1)) = 0
		[ThryWideEnum(Off, 0, Replace, 1, Multiply, 2, Add, 3, Subtract, 4, Min, 5, Max, 6)]_DecalOverrideAlpha2 ("Alpha Blend Mode--{reference_property:_Decal2OverrideAlphaMode}", Float) = 0
		[HideInInspector][Enum(Everywhere, 0, Decal Bounds, 1)] _Decal2OverrideAlphaMode ("Mode", Int) = 0
		_DecalBlendAlpha2 ("Alpha", Range(0, 1)) = 1
		_Decal2Depth ("Depth", Range(-0.5, 2)) = 0
		
		[HideInInspector] s_start_Decal2HueShift ("Hue Shift--{reference_property:_DecalHueShiftEnabled2, persistent_expand:true, default_expand:false}", Float) = 0
		[HideInInspector][ThryToggleUI(true)]_DecalHueShiftEnabled2 ("Hue Shift", Float) = 0
		_DecalHueShiftSpeed2 ("Shift Speed", Float) = 0
		_DecalHueShift2 ("Hue Shift", Range(0, 1)) = 0
		_Decal2HueAngleStrength ("Hue Angle Power", Float) = 0
		[HideInInspector] s_end_Decal2HueShift ("Hue Shift", Float) = 0
		
		[HideInInspector] s_start_Decal2Video ("Video Texture--{reference_property:_Decal2VideoEnabled, persistent_expand:true, default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI] _Decal2VideoEnabled ("Video Texture", Float) = 0
		[ThryWideEnum(Shrink2Fit, 0, Grow2Fit, 1, Off, 2)] _Decal2VideoAspectFix ("Aspect Ratio", Int) = 0
		[ToggleUI] _Decal2VideoFitToScale ("Fit To Scale--{condition_showS:(_Decal2VideoAspectFix==0||_Decal2VideoAspectFix==1)}", Float) = 1
		[ToggleUI] _Decal2UseDecalAlpha ("Use Decal Alpha", Float) = 0
		[ToggleUI] _Decal2OnlyVideo ("Only Show Video", Float) = 0
		_Decal2VideoEmissionStrength ("Emission", Range(0, 20)) = 0
		[HideInInspector] s_end_Decal2Video ("Video Texture", Float) = 0
		
		[HideInInspector] s_start_Decal2ChannelSeparation ("Chromatic Aberration--{reference_property:_Decal2ChannelSeparationEnable, persistent_expand:true, default_expand:false}", Int) = 0
		[HideInInspector][NoAnimate][ThryToggle(true)]_Decal2ChannelSeparationEnable ("Chromatic Aberration", Float) = 0
		_Decal2ChannelSeparation ("Intensity", Float) = 0
		_Decal2ChannelSeparationAngleStrength ("Surface Angle Intensity", Float) = 0
		_Decal2ChannelSeparationHue ("Hue", Range(-1, 1)) = 0
		_Decal2ChannelSeparationVertical ("Direction", Range(-3.142, 3.142)) = 0
		[ToggleUI]_Decal2ChannelSeparationPremultiply ("Premultiply Alpha--{tooltip:''Fixes Chromatic Aberration issues on some decal textures''}", Float) = 0
		[HideInInspector] s_end_Decal2ChannelSeparation ("", Int) = 0
		
		[HideInInspector] s_start_Decal2GlobalMasking ("Masking--{persistent_expand:false, default_expand:false}", Float) = 0
		[ThryWideEnum(Off, 0, Front Only, 1, Back Only, 2)] _Decal2FaceMask ("Face Mask", Int) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _Decal2GlobalMask ("Apply From Global Mask--{reference_property:_Decal2GlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_Decal2GlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _Decal2ApplyGlobalMaskIndex ("Apply to Global Mask--{reference_property:_Decal2ApplyGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _Decal2ApplyGlobalMaskBlendType ("Blending", Int) = 0
		[HideInInspector] s_end_Decal2GlobalMasking ("Masking", Float) = 0
		// Decal 2 Audio Link
		[HideInInspector] m_start_Decal2AudioLink ("Audio Link ♫--{ condition_showS:_EnableAudioLink==1}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal2ScaleBand ("Scale Band", Int) = 0
		[VectorLabel(Xmin, Ymin, Xmax, Ymax)]_AudioLinkDecal2Scale ("Scale Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal2SideBand ("Side Band", Int) = 0
		[VectorLabel(L, R, U, D)]_AudioLinkDecal2SideMin ("Side Mod Min", Vector) = (0, 0, 0, 0)
		[VectorLabel(L, R, U, D)]_AudioLinkDecal2SideMax ("Side Mod Max", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal2RotationBand ("Rotation Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDecal2Rotation ("Rotation Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal2AlphaBand ("Alpha Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDecal2Alpha ("Alpha Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal2EmissionBand ("Emission Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDecal2Emission ("Emission Mod", Vector) = (0, 0, 0, 0)
		[ToggleUI]_AudioLinkDecalCC2 ("CC Strip", Float) = 0
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _DecalRotationCTALBand2 ("Chrono Rotation Band", Int) = 0
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_DecalRotationCTALType2 ("Chrono Motion Type", Int) = 0
		_DecalRotationCTALSpeed2 ("Chrono Rotation Speed", Float) = 0
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal2ChannelSeparationBand ("Chromatic Aberration Band--{condition_showS:(_Decal2ChannelSeparationEnable==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDecal2ChannelSeparation ("Chromatic Aberration--{condition_showS:(_Decal2ChannelSeparationEnable==1)}", Vector) = (0, 0, 0, 0)
		[HideInInspector] m_end_Decal2AudioLink ("Audio Link", Float) = 0
		[HideInInspector] m_end_Decal2 ("Decal 0", Float) = 0
		//endex
		//ifex _DecalEnabled3==0
		// Decal 3
		[HideInInspector] m_start_Decal3 ("Decal 3--{reference_property:_DecalEnabled3}", Float) = 0
		[HideInInspector][ThryToggle(DEPTH_OF_FIELD_COC_VIEW)]_DecalEnabled3 ("Enable", Float) = 0
		[HideInInspector] s_start_decal3_position ("Positioning--{persistent_expand:true,default_expand:true}", Float) = 1
		[ThryDecalPositioning(_DecalTexture3, _DecalTexture3UV, _DecalPosition3, _DecalRotation3, _DecalScale3, _DecalSideOffset3)]
		[Vector3]_DecalPosition3 ("Position", Vector) = (.5, .5, 0, 0)
		_DecalRotation3 ("Rotation", Range(0, 360)) = 0
		_DecalRotationSpeed3 ("Rotation Speed", Float) = 0
		[VectorLabel(X, Y)]_DecalScale3 ("Scale", Vector) = (1, 1, 1, 0)
		[VectorLabel(L, R, D, U)]_DecalSideOffset3 ("Side Offset", Vector) = (0, 0, 0, 0)
		[ToggleUI]_DecalTiled3 ("Tiled", Float) = 0
		[HideInInspector] s_end_decal3_position ("Positioning", Float) = 0
		
		[ThryWideEnum(Default, 0, Video Texture, 1)]_Decal3TextureToUse ("Texture Swap", Int) = 0
		_DecalColor3 ("Color--{reference_property:_DecalColor3ThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _DecalColor3ThemeIndex ("", Int) = 0
		[sRGBWarning(true)]_DecalTexture3 ("Decal--{reference_properties:[_DecalTexture3Pan, _DecalTexture3UV, _Decal3MaskChannel, _DecalOverrideAlpha3]}", 2D) = "white" { }
		[HideInInspector][Vector2]_DecalTexture3Pan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _DecalTexture3UV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)] _Decal3MaskChannel ("Mask Channel", Int) = 3
		
		_DecalEmissionStrength3 ("Emission Strength", Range(0, 20)) = 0
		[ThryWideEnum(Replace, 0, Darken, 1, Multiply, 2, Lighten, 5, Screen, 6, Subtract, 7, Add, 8, Overlay, 9, Mixed, 20)]_DecalBlendType3 ("Color Blend Mode", Range(0, 1)) = 0
		[ThryWideEnum(Off, 0, Replace, 1, Multiply, 2, Add, 3, Subtract, 4, Min, 5, Max, 6)]_DecalOverrideAlpha3 ("Alpha Blend Mode--{reference_property:_Decal3OverrideAlphaMode}", Float) = 0
		[HideInInspector][Enum(Everywhere, 0, Decal Bounds, 1)] _Decal3OverrideAlphaMode ("Mode", Int) = 0
		_DecalBlendAlpha3 ("Alpha", Range(0, 1)) = 1
		_Decal3Depth ("Depth", Range(-0.5, 2)) = 0
		
		[HideInInspector] s_start_Decal3HueShift ("Hue Shift--{reference_property:_DecalHueShiftEnabled3, persistent_expand:true, default_expand:false}", Float) = 0
		[HideInInspector][ThryToggleUI(true)]_DecalHueShiftEnabled3 ("Hue Shift", Float) = 0
		_DecalHueShiftSpeed3 ("Shift Speed", Float) = 0
		_DecalHueShift3 ("Hue Shift", Range(0, 1)) = 0
		_Decal3HueAngleStrength ("Hue Angle Power", Float) = 0
		[HideInInspector] s_end_Decal3HueShift ("Hue Shift", Float) = 0
		
		[HideInInspector] s_start_Decal3Video ("Video Texture--{reference_property:_Decal3VideoEnabled, persistent_expand:true, default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI] _Decal3VideoEnabled ("Video Texture", Float) = 0
		[ThryWideEnum(Shrink2Fit, 0, Grow2Fit, 1, Off, 2)] _Decal3VideoAspectFix ("Aspect Ratio", Int) = 0
		[ToggleUI] _Decal3VideoFitToScale ("Fit To Scale--{condition_showS:(_Decal3VideoAspectFix==0||_Decal3VideoAspectFix==1)}", Float) = 1
		[ToggleUI] _Decal3UseDecalAlpha ("Use Decal Alpha", Float) = 0
		[ToggleUI] _Decal3OnlyVideo ("Only Show Video", Float) = 0
		_Decal3VideoEmissionStrength ("Emission", Range(0, 20)) = 0
		[HideInInspector] s_end_Decal3Video ("Video Texture", Float) = 0
		
		[HideInInspector] s_start_Decal3ChannelSeparation ("Chromatic Aberration--{reference_property:_Decal3ChannelSeparationEnable, persistent_expand:true, default_expand:false}", Int) = 0
		[HideInInspector][NoAnimate][ThryToggle(true)]_Decal3ChannelSeparationEnable ("Chromatic Aberration", Float) = 0
		_Decal3ChannelSeparation ("Intensity", Float) = 0
		_Decal3ChannelSeparationAngleStrength ("Surface Angle Intensity", Float) = 0
		_Decal3ChannelSeparationHue ("Hue", Range(-1, 1)) = 0
		_Decal3ChannelSeparationVertical ("Direction", Range(-3.142, 3.142)) = 0
		[ToggleUI]_Decal3ChannelSeparationPremultiply ("Premultiply Alpha--{tooltip:''Fixes Chromatic Aberration issues on some decal textures''}", Float) = 0
		[HideInInspector] s_end_Decal3ChannelSeparation ("", Int) = 0
		
		[HideInInspector] s_start_Decal3GlobalMasking ("Masking--{persistent_expand:false, default_expand:false}", Float) = 0
		[ThryWideEnum(Off, 0, Front Only, 1, Back Only, 2)] _Decal3FaceMask ("Face Mask", Int) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _Decal3GlobalMask ("Apply From Global Mask--{reference_property:_Decal3GlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_Decal3GlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _Decal3ApplyGlobalMaskIndex ("Apply to Global Mask--{reference_property:_Decal3ApplyGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _Decal3ApplyGlobalMaskBlendType ("Blending", Int) = 0
		[HideInInspector] s_end_Decal3GlobalMasking ("Masking", Float) = 0
		// Decal 3 Audio Link
		[HideInInspector] m_start_Decal3AudioLink ("Audio Link ♫--{ condition_showS:_EnableAudioLink==1}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal3ScaleBand ("Scale Band", Int) = 0
		[VectorLabel(Xmin, Ymin, Xmax, Ymax)]_AudioLinkDecal3Scale ("Scale Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal3SideBand ("Side Band", Int) = 0
		[VectorLabel(L, R, U, D)]_AudioLinkDecal3SideMin ("Side Mod Min", Vector) = (0, 0, 0, 0)
		[VectorLabel(L, R, U, D)]_AudioLinkDecal3SideMax ("Side Mod Max", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal3RotationBand ("Rotation Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDecal3Rotation ("Rotation Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal3AlphaBand ("Alpha Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDecal3Alpha ("Alpha Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal3EmissionBand ("Emission Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDecal3Emission ("Emission Mod", Vector) = (0, 0, 0, 0)
		[ToggleUI]_AudioLinkDecalCC3 ("CC Strip", Float) = 0
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _DecalRotationCTALBand3 ("Chrono Rotation Band", Int) = 0
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_DecalRotationCTALType3 ("Chrono Motion Type", Int) = 0
		_DecalRotationCTALSpeed3 ("Chrono Rotation Speed", Float) = 0
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDecal3ChannelSeparationBand ("Chromatic Aberration Band--{condition_showS:(_Decal3ChannelSeparationEnable==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDecal3ChannelSeparation ("Chromatic Aberration--{condition_showS:(_Decal3ChannelSeparationEnable==1)}", Vector) = (0, 0, 0, 0)
		[HideInInspector] m_end_Decal3AudioLink ("Audio Link", Float) = 0
		[HideInInspector] m_end_Decal3 ("Decal 0", Float) = 0
		//endex
		[HideInInspector] m_end_DecalSection ("Decal", Float) = 0
		//endex
		
		//ifex _NormalCorrect==0
		[HideInInspector] m_start_normalCorrect (" Normal Correct--{reference_property:_NormalCorrect}}", Float) = 0
		[HideInInspector][ThryToggle(POI_NORMALCORRECT)]_NormalCorrect ("Enable", Float) = 0
		_NormalCorrectAmount ("Normal Correct Amount", Range(0,1)) = 0.9
		[Vector3]_NormalCorrectOrigin ("Origin", Vector) = (0,0.4,-0.025)
		[HideInInspector] m_end_normalCorrect ("", Float) = 0
		//endex
		
		[HideInInspector] m_lightingCategory ("Shading", Float) = 0
		
		[HideInInspector] m_start_PoiLightData ("Light Data--{button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/shading/light-data},hover:Documentation}}", Float) = 0
		// Lighting Data
		[sRGBWarning][ThryRGBAPacker(R, G, B, A, Linear, false)]_LightingAOMaps ("AO Maps (expand)--{reference_properties:[_LightingAOMapsPan, _LightingAOMapsUV,_LightDataAOStrengthR,_LightDataAOStrengthG,_LightDataAOStrengthB,_LightDataAOStrengthA, _LightDataAOGlobalMaskR]}", 2D) = "white" { }
		[HideInInspector][Vector2]_LightingAOMapsPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _LightingAOMapsUV ("UV", Int) = 0
		[HideInInspector]_LightDataAOStrengthR ("R Strength", Range(0, 1)) = 1
		[HideInInspector]_LightDataAOStrengthG ("G Strength", Range(0, 1)) = 0
		[HideInInspector]_LightDataAOStrengthB ("B Strength", Range(0, 1)) = 0
		[HideInInspector]_LightDataAOStrengthA ("A Strength", Range(0, 1)) = 0
		[HideInInspector][ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _LightDataAOGlobalMaskR ("Global Mask--{reference_property:_LightDataAOGlobalMaskBlendTypeR}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _LightDataAOGlobalMaskBlendTypeR ("Blending", Range(0, 1)) = 2
		[sRGBWarning][ThryRGBAPacker(R, G, B, A, Linear, false)]_LightingDetailShadowMaps ("Shadow Map (expand)--{reference_properties:[_LightingDetailShadowMapsPan, _LightingDetailShadowMapsUV,_LightingDetailShadowStrengthR,_LightingDetailShadowStrengthG,_LightingDetailShadowStrengthB,_LightingDetailShadowStrengthA,_LightingAddDetailShadowStrengthR,_LightingAddDetailShadowStrengthG,_LightingAddDetailShadowStrengthB,_LightingAddDetailShadowStrengthA, _LightDataDetailShadowGlobalMaskR]}", 2D) = "white" { }
		[HideInInspector][Vector2]_LightingDetailShadowMapsPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _LightingDetailShadowMapsUV ("UV", Int) = 0
		[HideInInspector]_LightingDetailShadowStrengthR ("R Strength", Range(0, 1)) = 1
		[HideInInspector]_LightingDetailShadowStrengthG ("G Strength", Range(0, 1)) = 0
		[HideInInspector]_LightingDetailShadowStrengthB ("B Strength", Range(0, 1)) = 0
		[HideInInspector]_LightingDetailShadowStrengthA ("A Strength", Range(0, 1)) = 0
		[HideInInspector]_LightingAddDetailShadowStrengthR ("Additive R Strength", Range(0, 1)) = 1
		[HideInInspector]_LightingAddDetailShadowStrengthG ("Additive G Strength", Range(0, 1)) = 0
		[HideInInspector]_LightingAddDetailShadowStrengthB ("Additive B Strength", Range(0, 1)) = 0
		[HideInInspector]_LightingAddDetailShadowStrengthA ("Additive A Strength", Range(0, 1)) = 0
		[HideInInspector][ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _LightDataDetailShadowGlobalMaskR ("Global Mask--{reference_property:_LightDataDetailShadowGlobalMaskBlendTypeR}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _LightDataDetailShadowGlobalMaskBlendTypeR ("Blending", Range(0, 1)) = 2
		[sRGBWarning][ThryRGBAPacker(R, G, B, A, Linear, false)]_LightingShadowMasks ("Shadow Masks (expand)--{reference_properties:[_LightingShadowMasksPan, _LightingShadowMasksUV,_LightingShadowMaskStrengthR,_LightingShadowMaskStrengthG,_LightingShadowMaskStrengthB,_LightingShadowMaskStrengthA, _LightDataShadowMaskGlobalMaskR]}", 2D) = "white" { }
		[HideInInspector][Vector2]_LightingShadowMasksPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _LightingShadowMasksUV ("UV", Int) = 0
		[HideInInspector]_LightingShadowMaskStrengthR ("R Strength", Range(0, 1)) = 1
		[HideInInspector]_LightingShadowMaskStrengthG ("G Strength", Range(0, 1)) = 0
		[HideInInspector]_LightingShadowMaskStrengthB ("B Strength", Range(0, 1)) = 0
		[HideInInspector]_LightingShadowMaskStrengthA ("A Strength", Range(0, 1)) = 0
		[HideInInspector][ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _LightDataShadowMaskGlobalMaskR ("Global Mask--{reference_property:_LightDataShadowMaskGlobalMaskBlendTypeR}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _LightDataShadowMaskGlobalMaskBlendTypeR ("Blending", Range(0, 1)) = 2
		// Base Pass
		[HideInInspector] s_start_LightDataBasePass ("Base Pass (Directional & Baked Lights)--{persistent_expand:true,default_expand:true}", Float) = 1
		[Enum(Poi Custom, 0, Standard, 1, UTS2, 2, OpenLit(lil toon), 3)] _LightingColorMode ("Light Color Mode", Int) = 0
		[Enum(Poi Custom, 0, Normalized NDotL, 1, Saturated NDotL, 2, Casted Shadows Only, 3)] _LightingMapMode ("Light Map Mode", Int) = 0
		[Enum(Poi Custom, 0, Forced Local Direction, 1, Forced World Direction, 2, UTS2, 3, OpenLit(lil toon), 4, View Direction, 5)] _LightingDirectionMode ("Light Direction Mode", Int) = 0
		[Vector3]_LightngForcedDirection ("Forced Direction--{condition_showS:(_LightingDirectionMode==1 || _LightingDirectionMode==2)}", Vector) = (0, 0, 0)
		_LightingViewDirOffsetPitch ("View Dir Offset Pitch--{condition_showS:_LightingDirectionMode==5}", Range(-90, 90)) = 0
		_LightingViewDirOffsetYaw ("View Dir Offset Yaw--{condition_showS:_LightingDirectionMode==5}", Range(-90, 90)) = 0
		[ToggleUI]_LightingForceColorEnabled ("Force Light Color", Float) = 0
		_LightingForcedColor ("Forced Color--{condition_showS:(_LightingForceColorEnabled==1), reference_property:_LightingForcedColorThemeIndex}", Color) = (1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _LightingForcedColorThemeIndex ("", Int) = 0
		_Unlit_Intensity ("Unlit_Intensity--{condition_showS:(_LightingColorMode==2)}", Range(0.001, 4)) = 1
		[ToggleUI]_LightingCapEnabled ("Limit Brightness", Float) = 1
		_LightingCap ("Max Brightness--{condition_showS:(_LightingCapEnabled==1)}", Range(0, 10)) = 1
		_LightingMinLightBrightness ("Min Brightness", Range(0, 1)) = 0
		_LightingIndirectUsesNormals ("Indirect Uses Normals--{condition_showS:(_LightingColorMode==0)}", Range(0, 1)) = 0
		_LightingCastedShadows ("Receive Casted Shadows", Range(0, 1)) = 0
		_LightingMonochromatic ("Grayscale Lighting", Range(0, 1)) = 0
		[ToggleUI]_LightingVertexLightingEnabled ("Vertex lights (Non-Important)", Float) = 1
		[ToggleUI]_LightingMirrorVertexLightingEnabled ("Mirror Vertex lights (Non-Important)", Float) = 1
		[HideInInspector] s_end_LightDataBasePass ("Base Pass", Float) = 1
		// Lighting Additive
		[HideInInspector] s_start_LightDataAddPass ("Add Pass (Point & Spot lights)--{persistent_expand:true,default_expand:true}", Float) = 1
		[ToggleUI]_LightingAdditiveEnable ("Pixel lights (Important)", Float) = 1
		[ToggleUI]_DisableDirectionalInAdd ("Ignore Directional--{condition_showS:(_LightingAdditiveEnable==1)}", Float) = 1
		[ToggleUI]_LightingAdditiveLimited ("Limit Brightness", Float) = 1
		_LightingAdditiveLimit ("Max Brightness--{condition_showS:(_LightingAdditiveLimited==1)}", Range(0, 10)) = 1
		_LightingAdditiveCastedShadows ("Receive Casted Shadows", Range(0, 1)) = 1
		_LightingAdditiveMonochromatic ("Grayscale Lighting", Range(0, 1)) = 0
		_LightingAdditivePassthrough ("Point Light Passthrough--{condition_showS:(_LightingAdditiveEnable==1)}", Range(0, 1)) = .5
		[HideInInspector] s_end_LightDataAddPass ("Add Pass", Float) = 1
		// Lighting Data Debug
		[HideInInspector] s_start_LightDataDebug ("Debug / Data Visualizations--{reference_property:_LightDataDebugEnabled,persistent_expand:true}", Float) = 0
		[HideInInspector][NoAnimate][ThryToggleUI(false)]_LightDataDebugEnabled ("Debug", Float) = 0
		[ThryWideEnum(Direct Color, 0, Indirect Color, 1, Light Map, 2, Attenuation, 3, N Dot L, 4, Half Dir, 5, Direction, 6, Add Color, 7, Add Attenuation, 8, Add Shadow, 9, Add N Dot L, 10)] _LightingDebugVisualize ("Visualize", Int) = 0
		[HideInInspector] s_end_LightDataDebug ("Debug", Float) = 0
		[HideInInspector] m_end_PoiLightData ("Light Data", Float) = 0
		
		//ifex _ShadingEnabled==0
		[HideInInspector] m_start_PoiShading (" Shading--{reference_property:_ShadingEnabled,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/shading/main},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(VIGNETTE_MASKED)]_ShadingEnabled ("Enable Shading", Float) = 1
		[KeywordEnum(TextureRamp, Multilayer Math, Wrapped, Skin, ShadeMap, Flat, Realistic, Cloth, SDF)] _LightingMode ("Lighting Type", Float) = 5
		
		_LightingShadowColor ("Shadow Tint--{condition_showS:(_LightingMode!=4 && _LightingMode!=1 && _LightingMode!=5)}", Color) = (1, 1, 1)
		
		//ifex _LightingMode!=0
		// Texture Ramp
		[NoScaleOffset][sRGBWarning(true)][Gradient]_ToonRamp ("Lighting Ramp--{texture:{width:512,height:4,filterMode:Bilinear,wrapMode:Clamp},force_texture_options:true,condition_showS:(_LightingMode==0)}", 2D) = "white" { }
		_ShadowOffset ("Ramp Offset--{condition_showS:(_LightingMode==0)}", Range(-1, 1)) = 0
		_ToonRampCount ("Ramp Count--{condition_showS:(_LightingMode==0)}", Int) = 1
		[ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)]_ToonRampUVSelector ("Ramp Selector UV--{condition_showS:(_LightingMode==0)}", Int) = 1
		//endex
		
		//ifex _LightingMode!=1
		// Multilayer Math
		[sRGBWarning]_MultilayerMathBlurMap ("Blur Map--{reference_properties:[_MultilayerMathBlurMapPan, _MultilayerMathBlurMapUV], condition_showS:(_LightingMode==1)}", 2D) = "white" { }
		[HideInInspector] s_start_MultilayerMath1stLayer ("Shadow Layer 1--{persistent_expand:true,default_expand:true, condition_showS:(_LightingMode==1)}", Float) = 1
		[sRGBWarning(true)]_ShadowColorTex ("Color Tex--{reference_properties:[_ShadowColorTexPan, _ShadowColorTexUV], condition_showS:(_LightingMode==1)}", 2D) = "black" { }
		[HideInInspector][Vector2]_ShadowColorTexPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _ShadowColorTexUV ("UV", Int) = 0
		_ShadowColor ("Color--{condition_showS:(_LightingMode==1)}", Color) = (0.7, 0.75, 0.85, 1.0)
		[HideInInspector][Vector2]_MultilayerMathBlurMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _MultilayerMathBlurMapUV ("UV", Int) = 0
		_ShadowBorder ("Border--{condition_showS:(_LightingMode==1)}", Range(0, 1)) = 0.5
		_ShadowBlur ("Blur--{condition_showS:(_LightingMode==1)}", Range(0, 1)) = 0.1
		_ShadowReceive ("Receive Shadow--{condition_showS:(_LightingMode==1)}", Range(0, 1)) = 0
		[HideInInspector] s_end_MultilayerMath1stLayer ("Shadow Layer 1}", Float) = 1
		
		[HideInInspector] s_start_MultilayerMath2ndLayer ("Shadow Layer 2--{persistent_expand:true,default_expand:false, condition_showS:(_LightingMode==1)}", Float) = 0
		[sRGBWarning(true)]_Shadow2ndColorTex ("Color Tex--{reference_properties:[_Shadow2ndColorTexPan, _Shadow2ndColorTexUV], condition_showS:(_LightingMode==1)}", 2D) = "black" { }
		[HideInInspector][Vector2]_Shadow2ndColorTexPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _Shadow2ndColorTexUV ("UV", Int) = 0
		_Shadow2ndColor ("Color--{condition_showS:(_LightingMode==1)}", Color) = (0, 0, 0, 0)
		_Shadow2ndBorder ("Border--{condition_showS:(_LightingMode==1)}", Range(0, 1)) = 0.5
		_Shadow2ndBlur ("Blur--{condition_showS:(_LightingMode==1)}", Range(0, 1)) = 0.3
		_Shadow2ndReceive ("Receive Shadow--{condition_showS:(_LightingMode==1)}", Range(0, 1)) = 0
		[HideInInspector] s_end_MultilayerMath2ndLayer ("Shadow Layer 2", Float) = 0
		
		[HideInInspector] s_start_MultilayerMath3rdLayer ("Shadow Layer 3--{persistent_expand:true,default_expand:false, condition_showS:(_LightingMode==1)}", Float) = 0
		[sRGBWarning(true)]_Shadow3rdColorTex ("Color Tex--{reference_properties:[_Shadow3rdColorTexPan, _Shadow3rdColorTexUV], condition_showS:(_LightingMode==1)}", 2D) = "black" { }
		[HideInInspector][Vector2]_Shadow3rdColorTexPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _Shadow3rdColorTexUV ("UV", Int) = 0
		_Shadow3rdColor ("Color--{condition_showS:(_LightingMode==1)}", Color) = (0, 0, 0, 0)
		_Shadow3rdBorder ("Border--{condition_showS:(_LightingMode==1)}", Range(0, 1)) = 0.25
		_Shadow3rdBlur ("Blur--{condition_showS:(_LightingMode==1)}", Range(0, 1)) = 0.1
		_Shadow3rdReceive ("Receive Shadow--{condition_showS:(_LightingMode==1)}", Range(0, 1)) = 0
		[HideInInspector] s_end_MultilayerMath3rdLayer ("Shadow Layer 3", Float) = 0
		
		[HideInInspector] s_start_MultilayerMathBorder ("Border--{persistent_expand:true,default_expand:true, condition_showS:(_LightingMode==1)}", Float) = 1
		_ShadowBorderColor ("Color--{condition_showS:(_LightingMode==1)}", Color) = (1, 0, 0, 1)
		_ShadowBorderRange ("Border Range--{condition_showS:(_LightingMode==1)}", Range(0, 1)) = 0
		[HideInInspector] s_end_MultilayerMathBorder ("Border", Float) = 1
		
		[HideInInspector] s_start_MultilayerMathBorderMap ("Shadow Border Map--{reference_property:_ShadowBorderMapToggle, persistent_expand:true,default_expand:false, condition_showS:(_LightingMode==1)}", Float) = 0
		[HideInInspector][ToggleUI] _ShadowBorderMapToggle ("Shadow Border Map Toggle", Float) = 0
		_ShadowBorderMask ("Shadow Border Map--{reference_properties:[_ShadowBorderMaskPan, _ShadowBorderMaskUV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_ShadowBorderMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _ShadowBorderMaskUV ("UV", Int) = 0
		[ToggleUI]_ShadowPostAO ("Post AO", Float) = 0
		_ShadowBorderMaskLOD ("Border Map LOD", Range(0, 1)) = 0
		[VectorToSliders(1st Min, n0.01, p1.01, 1st Max, n0.01, p1.01, 2nd Min, n0.01, p1.01, 2nd Max, n0.01, p1.01)]_ShadowAOShift ("Shadow AO Shift", Vector) = (0, 1, 0, 1)
		[VectorToSliders(3rd Min, n0.01, p1.01, 3rd Max, n0.01, p1.01)]_ShadowAOShift2 ("Shadow AO Shift", Vector) = (0, 1, 0, 1)
		[HideInInspector] s_end_MultilayerMathBorderMap ("Shadow Border Map", Float) = 1
		
		[ToggleUI]_LightingMulitlayerNonLinear ("Non Linear Lightmap--{condition_showS:(_LightingMode==1)}", Float) = 1
		_ShadowMainStrength ("Base Color Blend--{condition_showS:(_LightingMode==1)}", Range(0, 1)) = 0
		//endex
		
		//ifex _LightingMode!=2
		// Wrapped
		_LightingWrappedColor ("LightSide Color--{condition_showS:(_LightingMode==2)}", Color) = (1, 1, 1, 1)
		_LightingWrappedWrap ("Wrap--{condition_showS:(_LightingMode==2)}", Range(0, 2)) = 0
		_LightingWrappedNormalization ("Normalization--{condition_showS:(_LightingMode==2)}", Range(0, 1)) = 0
		_LightingGradientStart ("Gradient Start--{condition_showS:(_LightingMode==2)}", Range(0, 1)) = 0
		_LightingGradientEnd ("Gradient End--{condition_showS:(_LightingMode==2)}", Range(0, 1)) = .5
		//endex
		
		// Shade Maps
		//ifex _LightingMode!=4
		_1st_ShadeColor ("1st ShadeColor--{condition_showS:(_LightingMode==4)}", Color) = (1, 1, 1)
		[sRGBWarning(true)]_1st_ShadeMap ("1st ShadeMap--{reference_properties:[_1st_ShadeMapPan, _1st_ShadeMapUV, _Use_1stShadeMapAlpha_As_ShadowMask, _1stShadeMapMask_Inverse],condition_showS:(_LightingMode==4)}", 2D) = "white" { }
		[HideInInspector][Vector2]_1st_ShadeMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _1st_ShadeMapUV ("UV", Int) = 0
		[HideInInspector][ToggleUI]_Use_1stShadeMapAlpha_As_ShadowMask ("1st ShadeMap.a As ShadowMask", Float) = 0
		[HideInInspector][ToggleUI]_1stShadeMapMask_Inverse ("1st ShadeMapMask Inverse", Float) = 0
		[ToggleUI] _Use_BaseAs1st ("Use BaseMap as 1st ShadeMap--{condition_showS:(_LightingMode==4)}", Float) = 0
		_2nd_ShadeColor ("2nd ShadeColor--{condition_showS:(_LightingMode==4)}", Color) = (1, 1, 1, 1)
		[sRGBWarning(true)]_2nd_ShadeMap ("2nd ShadeMap--{reference_properties:[_2nd_ShadeMapPan, _2nd_ShadeMapUV, _Use_2ndShadeMapAlpha_As_ShadowMask, _2ndShadeMapMask_Inverse],condition_showS:(_LightingMode==4)}", 2D) = "white" { }
		[HideInInspector][Vector2]_2nd_ShadeMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _2nd_ShadeMapUV ("UV", Int) = 0
		[HideInInspector][ToggleUI]_Use_2ndShadeMapAlpha_As_ShadowMask ("2nd ShadeMap.a As ShadowMask", Float) = 0
		[HideInInspector][ToggleUI]_2ndShadeMapMask_Inverse ("2nd ShadeMapMask Inverse", Float) = 0
		[ToggleUI] _Use_1stAs2nd ("Use 1st ShadeMap as 2nd_ShadeMap--{condition_showS:(_LightingMode==4)}", Float) = 0
		_BaseColor_Step ("BaseColor_Step--{condition_showS:(_LightingMode==4)}", Range(0.01, 1)) = 0.5
		_BaseShade_Feather ("Base/Shade_Feather--{condition_showS:(_LightingMode==4)}", Range(0.0001, 1)) = 0.0001
		_ShadeColor_Step ("ShadeColor_Step--{condition_showS:(_LightingMode==4)}", Range(0, 1)) = 0
		_1st2nd_Shades_Feather ("1st/2nd_Shades_Feather--{condition_showS:(_LightingMode==4)}", Range(0.0001, 1)) = 0.0001
		[Enum(Replace, 0, Multiply, 1)]_ShadingShadeMapBlendType ("Blend Mode--{condition_showS:(_LightingMode==4)}", Int) = 0
		//endex
		
		// Skin Shading
		//ifex _LightingMode!=3
		[sRGBWarning]_SkinLUT ("LUT--{condition_showS:(_LightingMode==3)}", 2D) = "white" { }
		_SssScale ("Scale--{condition_showS:(_LightingMode==3)}", Range(0, 1)) = 1
		_SkinThicknessMap ("Thickness Map--{reference_properties:[_SkinThicknessMapPan, _SkinThicknessMapUV, _SkinThicknessMapInvert],condition_showS:(_LightingMode==3)}", 2D) = "black" { }
		[HideInInspector][Vector2]_SkinThicknessMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _SkinThicknessMapUV ("UV", Int) = 0
		[HideInInspector][ToggleUI]_SkinThicknessMapInvert ("Invert", Float) = 0
		_SkinThicknessPower ("Thickness Power--{condition_showS:(_LightingMode==3)}", Range(0, 3)) = 1
		_SssBumpBlur ("Bump Blur--{condition_showS:(_LightingMode==3)}", Range(0, 1)) = 0.7
		[HideInInspector][Vector3]_SssTransmissionAbsorption ("Absorption--{condition_showS:(_LightingMode==3)}", Vector) = (-8, -40, -64, 0)
		[HideInInspector][Vector3]_SssColorBleedAoWeights ("AO Color Bleed--{condition_showS:(_LightingMode==3)}", Vector) = (0.4, 0.15, 0.13, 0)
		//endex
		
		//ifex _LightingMode!=5
		// Flat
		[ToggleUI]_ForceFlatRampedLightmap ("Force Ramped Lightmap--{condition_showS:(_LightingMode==5)}", Range(0, 1)) = 1
		//endex
		
		//ifex _LightingMode!=7
		// Cloth
		[NonModifiableTextureData] [NoScaleOffset] _ClothDFG ("MultiScatter Cloth DFG--{condition_showS:(_LightingMode==7)}", 2D) = "black" { }
		[sRGBWarning][ThryRGBAPacker(Metallic Map, Cloth Mask, Reflectance, Smoothness, linear, false)]_ClothMetallicSmoothnessMap ("Maps (Expand)--{reference_properties:[_ClothMetallicSmoothnessMapPan, _ClothMetallicSmoothnessMapUV, _ClothMetallicSmoothnessMapInvert],condition_showS:(_LightingMode==7)}", 2D) = "white" { }
		[HideInInspector][Vector2] _ClothMetallicSmoothnessMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ToggleUI] _ClothMetallicSmoothnessMapInvert ("Invert Smoothness", Float) = 0
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _ClothMetallicSmoothnessMapUV ("UV", Int) = 0
		[NoAnimate][ThryToggleUI(false)] _ClothLerp ("Clothmask Lerp--{condition_showS:(_LightingMode==7)}", Float) = 0
		//[Gamma] _ClothMetallic ("Metallic--{condition_showS:(_LightingMode==7)}", Range(0, 1)) = 0
		_ClothReflectance ("Reflectance--{condition_showS:(_LightingMode==7)}", Range(0.35, 1)) = 0.5
		_ClothSmoothness ("Smoothness--{condition_showS:(_LightingMode==7)}", Range(0, 1)) = 0.5
		//endex
		
		//ifex _LightingMode!=8
		// SDF
		[sRGBWarning]_SDFShadingTexture ("SDF--{reference_properties:[_SDFShadingTexturePan, _SDFShadingTextureUV],condition_showS:(_LightingMode==8)}", 2D) = "white" { }
		[HideInInspector][Vector2]_SDFShadingTexturePan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _SDFShadingTextureUV ("UV", Int) = 0
		_SDFBlur ("Blur--{condition_showS:(_LightingMode==8)}", Range(0, 1)) = 0.1
		[Vector3]_SDFForward ("Forward Direction--{condition_showS:(_LightingMode==8)}", Vector) = (0, 0, 1, 0)
		[Vector3]_SDFLeft ("Left Direction--{condition_showS:(_LightingMode==8)}", Vector) = (-1, 0, 0, 0)
		//endex
		
		// Generic
		_ShadowStrength ("Shadow Strength--{condition_showS:(_LightingMode<=4 || _LightingMode==8)}", Range(0, 1)) = 1
		_LightingIgnoreAmbientColor ("Ignore Indirect Shadow Color--{condition_showS:(_LightingMode<=3 || _LightingMode==8)}", Range(0, 1)) = 1
		
		// Additive
		[Space(15)]
		[HideInInspector] s_start_ShadingAddPass ("Add Pass (Point & Spot Lights)--{persistent_expand:true,default_expand:false}", Float) = 0
		[Enum(Realistic, 0, Toon, 1, Same as Base Pass, 3)] _LightingAdditiveType ("Lighting Type", Int) = 3
		_LightingAdditiveGradientStart ("Gradient Start--{condition_showS:(_LightingAdditiveType==1)}", Range(0, 1)) = 0
		_LightingAdditiveGradientEnd ("Gradient End--{condition_showS:(_LightingAdditiveType==1)}", Range(0, 1)) = .5
		[HideInInspector] s_end_ShadingAddPass ("Add Pass", Float) = 0
		//_LightingAdditiveDetailStrength ("Detail Shadow Strength", Range(0, 1)) = 1 //TODO-implement this
		
		[HideInInspector] s_start_ShadingGlobalMask ("Global Masks--{persistent_expand:true,default_expand:false}", Float) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _ShadingRampedLightMapApplyGlobalMaskIndex ("LightMap to Global Mask--{reference_property:_ShadingRampedLightMapApplyGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _ShadingRampedLightMapApplyGlobalMaskBlendType ("Blending", Int) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _ShadingRampedLightMapInverseApplyGlobalMaskIndex ("Inversed LightMap to Global Mask--{reference_property:_ShadingRampedLightMapInverseApplyGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _ShadingRampedLightMapInverseApplyGlobalMaskBlendType ("Blending", Int) = 2
		[HideInInspector] s_end_ShadingGlobalMask ("Global Masks", Float) = 0
		
		[HideInInspector] m_end_PoiShading ("Shading", Float) = 0
		//endex
		
		//ifex _EnableAniso==0
		
		[HideInInspector] m_start_Aniso (" Anisotropics--{reference_property:_EnableAniso}", Float) = 0
		[HideInInspector][ThryToggle(POI_ANISOTROPICS)]_EnableAniso ("Enable Aniso", Float) = 0
		[sRGBWarning(true)][ThryRGBAPacker(RGB Color, A Offset, linear, false)]_AnisoColorMap ("Color & Offset--{reference_properties:[_AnisoColorMapPan, _AnisoColorMapUV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_AnisoColorMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _AnisoColorMapUV ("UV", Int) = 0
		/*
		[sRGBWarning]_AnisoNoiseMap ("Noise Map--{reference_properties:[_AnisoNoiseMapPan, _AnisoNoiseMapUV]}", 2D) = "black" { }
		[HideInInspector][Vector2]_AnisoNoiseMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _AnisoNoiseMapUV ("UV", Int) = 0
		*/
		
		_AnisoReplace ("Replace Blending", Range(0, 1)) = 0
		_AnisoAdd ("Add Blending", Range(0, 1)) = 1
		[Space(6)]
		_AnisoHideInShadow ("Hide In Shadow", Range(0, 1)) = 1
		_AnisoUseLightColor ("Mix Light Color", Range(0, 1)) = 1
		_AnisoUseBaseColor ("Mix Base Color", Range(0, 1)) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _AnisoGlobalMask ("Global Mask--{reference_property:_AnisoGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _AnisoGlobalMaskBlendType ("Blending", Int) = 2
		
		[HideInInspector] s_start_AnisoTopLayer ("Top Layer--{persistent_expand:true,default_expand:true}", Float) = 1
		_Aniso0Power ("Power", Range(0, 1)) = 0
		_Aniso0Strength ("Strength", Range(0, 1)) = 1
		_Aniso0Offset ("Offset", Range(-10, 10)) = 0
		_Aniso0OffsetMapStrength ("Map Offset Strength", Range(0, 1)) = 0
		_Aniso0Tint ("Tint--{reference_property:_Aniso0TintIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _Aniso0TintIndex ("", Int) = 0
		[ToggleUI]_Aniso0SwitchDirection ("Switch Direction", Int) = 0
		[ThryToggleUI(true)] _Aniso0ToonMode ("Stylized Mode", Float) = 0
		_Aniso0Edge ("Edge--{condition_showS:(_Aniso0ToonMode==1)}", Range(0, 1)) = .5
		_Aniso0Blur ("Blur--{condition_showS:(_Aniso0ToonMode==1)}", Range(0, 1)) = 0
		[HideInInspector] s_end_AnisoTopLayer ("Top Layer", Float) = 1
		
		[HideInInspector] s_start_AnisoBottomLayer ("Bottom Layer--{persistent_expand:true,default_expand:false}", Float) = 0
		_Aniso1Power ("Power", Range(0, 1)) = .1
		_Aniso1Strength ("Strength", Range(0, 1)) = 1
		_Aniso1Offset ("Offset", Range(-1, 1)) = 0
		_Aniso1OffsetMapStrength ("Map Offset Strength", Range(0, 1)) = 0
		_Aniso1Tint ("Tint--{reference_property:_Aniso1TintIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _Aniso1TintIndex ("", Int) = 0
		[ToggleUI]_Aniso1SwitchDirection ("Switch Direction", Int) = 0
		[ThryToggleUI(true)] _Aniso1ToonMode ("Stylized Mode", Float) = 0
		_Aniso1Edge ("Edge--{condition_showS:(_Aniso1ToonMode==1)}", Range(0, 1)) = .5
		_Aniso1Blur ("Blur--{condition_showS:(_Aniso1ToonMode==1)}", Range(0, 1)) = 0
		[HideInInspector] s_end_AnisoBottomLayer ("Bottom Layer", Float) = 0
		
		[HideInInspector] m_end_Ansio ("Anisotropics", Float) = 0
		//endex
		
		// First Matcap
		//ifex _MatcapEnable==0
		[HideInInspector] m_start_matcap ("Matcap 0--{reference_property:_MatcapEnable,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/shading/matcap},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(POI_MATCAP0)]_MatcapEnable ("Enable Matcap}", Float) = 0
		[ThryWideEnum(UTS Style, 0, Top Pinch, 1, Double Sided, 2, Gradient, 3)] _MatcapUVMode ("UV Mode", Int) = 1
		_MatcapColor ("Color--{reference_property:_MatcapColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _MatcapColorThemeIndex ("", Int) = 0
		[sRGBWarning(true)][Gradient]_Matcap ("Matcap--{reference_properties:[_MatcapUVToBlend, _MatCapBlendUV1, _MatcapPan, _MatcapBorder, _MatcapRotation]}", 2D) = "white" { }
		[HideInInspector][Vector2]_MatcapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _MatcapUVToBlend ("UV To Blend", Int) = 1
		[HideInInspector][VectorToSliders(Blend UV X, 0.0, 1.0, Blend UV Y, 0.0, 1.0)]_MatCapBlendUV1 ("UV Blend", Vector) = (0, 0, 0, 0)
		[HideInInspector]_MatcapBorder ("Border", Range(0, 5)) = 0.43
		[HideInInspector]_MatcapRotation ("Rotation", Range(-1, 1)) = 0
		_MatcapIntensity ("Intensity", Range(0, 5)) = 1
		_MatcapEmissionStrength ("Emission Strength", Range(0, 20)) = 0
		_MatcapBaseColorMix ("Base Color Mix", Range(0, 1)) = 0
		_MatcapNormal ("Normal Strength", Range(0, 1)) = 1
		
		[HideInInspector] s_start_Matcap0Masking ("Masking--{persistent_expand:true,default_expand:true}", Float) = 1
		[sRGBWarning][ThryRGBAPacker(R Mask, G Nothing, B Nothing, A Smoothness, linear, false)]_MatcapMask ("Mask--{reference_properties:[_MatcapMaskPan, _MatcapMaskUV, _MatcapMaskChannel, _MatcapMaskInvert]}", 2D) = "white" { }
		[HideInInspector][Vector2]_MatcapMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _MatcapMaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_MatcapMaskChannel ("Channel", Float) = 0
		[HideInInspector][ToggleUI]_MatcapMaskInvert ("Invert", Float) = 0
		_MatcapLightMask ("Hide in Shadow", Range(0, 1)) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _MatcapMaskGlobalMask (" Global Mask--{reference_property:_MatcapMaskGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_MatcapMaskGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		[HideInInspector] s_end_Matcap0Masking ("Masking", Float) = 0
		
		[HideInInspector] s_start_Matcap0Blending ("Blending--{persistent_expand:true,default_expand:true}", Float) = 1
		_MatcapReplace ("Replace", Range(0, 1)) = 1
		_MatcapMultiply ("Multiply", Range(0, 1)) = 0
		_MatcapAdd ("Add", Range(0, 1)) = 0
		_MatcapMixed ("Mixed", Range(0, 1)) = 0
		_MatcapScreen ("Screen", Range(0, 1)) = 0
		_MatcapAddToLight ("Unlit Add", Range(0, 1)) = 0
		[HideInInspector] s_end_Matcap0Blending ("Blending", Float) = 0
		
		[HideInInspector] s_start_MatcapNormal ("Custom Normal Map--{reference_property:_Matcap0CustomNormal,persistent_expand:true}", Float) = 0
		[HideInInspector][ThryToggle(POI_MATCAP0_CUSTOM_NORMAL, true)] _Matcap0CustomNormal ("Custom Normal", Float) = 0
		[Normal]_Matcap0NormalMap ("Normal Map--{reference_properties:[_Matcap0NormalMapPan, _Matcap0NormalMapUV, _Matcap0NormalMapScale]}", 2D) = "bump" { }
		[HideInInspector][Vector2]_Matcap0NormalMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _Matcap0NormalMapUV ("UV", Int) = 0
		[HideInInspector]_Matcap0NormalMapScale ("Intensity", Range(0, 10)) = 1
		[HideInInspector] s_end_MatcapNormal ("", Float) = 0
		
		[HideInInspector] s_start_MatcapHueShift ("Hue Shift--{reference_property:_MatcapHueShiftEnabled,persistent_expand:true}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _MatcapHueShiftEnabled ("Hue Shift", Float) = 0
		_MatcapHueShiftSpeed ("Shift Speed", Float) = 0
		_MatcapHueShift ("Hue Shift", Range(0, 1)) = 0
		[HideInInspector] s_end_MatcapHueShift ("", Float) = 0
		
		[HideInInspector] s_start_MatcapSmoothness ("Blur / Smoothness--{reference_property:_MatcapSmoothnessEnabled,persistent_expand:true}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _MatcapSmoothnessEnabled ("Blur", Float) = 0
		_MatcapSmoothness ("Smoothness", Range(0, 1)) = 1
		[ToggleUI]_MatcapMaskSmoothnessApply ("Apply Mask for Smoothness", Float) = 0
		[Enum(R, 0, G, 1, B, 2, A, 3)]_MatcapMaskSmoothnessChannel ("Mask Channel for Smoothness", Int) = 3
		[HideInInspector] s_end_MatcapSmoothness ("", Float) = 0
		
		[HideInInspector] s_start_matcapApplyToAlpha ("Alpha Options--{persistent_expand:true,default_expand:false}", Float) = 0
		_MatcapAlphaOverride ("Override Alpha", Range(0, 1)) = 0
		[ToggleUI] _MatcapApplyToAlphaEnabled ("Intensity To Alpha", Float) = 0
		[ThryWideEnum(Greyscale, 0, Max, 1)] _MatcapApplyToAlphaSourceBlend ("Source Blend--{condition_showS:(_MatcapApplyToAlphaEnabled==1)}", Int) = 0
		[ThryWideEnum(Add, 0, Multiply, 1)] _MatcapApplyToAlphaBlendType ("Blend Type--{condition_showS:(_MatcapApplyToAlphaEnabled==1)}", Int) = 0
		_MatcapApplyToAlphaBlending ("Blending--{condition_showS:(_MatcapApplyToAlphaEnabled==1)}", Range(0, 1)) = 1.0
		[HideInInspector] s_end_matcapApplyToAlpha ("", Float) = 0
		
		[HideInInspector] s_start_MatcapTPSMaskGroup ("Matcap TPS Mask--{reference_property:_MatcapTPSDepthEnabled,persistent_expand:true,default_expand:false, condition_showS:(_TPSPenetratorEnabled==1)}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _MatcapTPSDepthEnabled ("TPS Depth Mask Enabled", Float) = 0
		_MatcapTPSMaskStrength ("TPS Mask Strength", Range(0, 1)) = 1
		[HideInInspector] s_end_MatcapTPSMaskGroup ("", Float) = 0
		
		[HideInInspector] s_start_Matcap0AudioLink ("Audio Link ♫--{reference_property:_Matcap0ALEnabled,persistent_expand:true,default_expand:false, condition_showS:(_EnableAudioLink==1)}", Float) = 0
		[HideInInspector][ToggleUI] _Matcap0ALEnabled ("Enable Audio Link", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _Matcap0ALAlphaAddBand ("Alpha Band", Int) = 0
		[VectorLabel(Min, Max)]_Matcap0ALAlphaAdd ("Alpha Mod", Vector) = (0, 0, 0, 0)
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _Matcap0ALEmissionAddBand ("Emission Band", Int) = 0
		[VectorLabel(Min, Max)]_Matcap0ALEmissionAdd ("Emission Mod", Vector) = (0, 0, 0, 0)
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _Matcap0ALIntensityAddBand ("Intensity Band", Int) = 0
		[VectorLabel(Min, Max)]_Matcap0ALIntensityAdd ("Intensity Mod", Vector) = (0, 0, 0, 0)
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_Matcap0ALChronoPanType ("Chrono Pan Type--{condition_showS:(_MatcapUVMode==3)}", Int) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _Matcap0ALChronoPanBand ("Chrono Pan Band--{condition_showS:(_MatcapUVMode==3)}", Int) = 0
		_Matcap0ALChronoPanSpeed ("Chrono Pan Speed--{condition_showS:(_MatcapUVMode==3)}", Float) = 0
		[HideInInspector] s_end_Matcap0AudioLink ("Audio Link", Float) = 0
		[HideInInspector] m_end_matcap ("Matcap", Float) = 0
		//endex
		
		// Second Matcap
		//ifex _Matcap2Enable==0
		[HideInInspector] m_start_Matcap2 ("Matcap 1--{reference_property:_Matcap2Enable,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/shading/matcap},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(COLOR_GRADING_HDR_3D)]_Matcap2Enable ("Enable Matcap 2", Float) = 0
		[ThryWideEnum(UTS Style, 0, Top Pinch, 1, Double Sided, 2, Gradient, 3)] _Matcap2UVMode ("UV Mode", Int) = 1
		_Matcap2Color ("Color--{reference_property:_Matcap2ColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _Matcap2ColorThemeIndex ("", Int) = 0
		[sRGBWarning(true)][Gradient]_Matcap2 ("Matcap--{reference_properties:[_Matcap2UVToBlend,_MatCap2ndBlendUV1, _Matcap2Pan,_Matcap2Border,_Matcap2Rotation]}", 2D) = "white" { }
		[HideInInspector][Vector2]_Matcap2Pan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _Matcap2UVToBlend ("UV To Blend", Int) = 1
		[HideInInspector][VectorToSliders(Blend UV X, 0.0, 1.0, Blend UV Y, 0.0, 1.0)]_MatCap2ndBlendUV1 ("UV Blend", Vector) = (0, 0, 0, 0)
		[HideInInspector]_Matcap2Border ("Border", Range(0, 5)) = 0.43
		[HideInInspector]_Matcap2Rotation ("Rotation", Range(-1, 1)) = 0
		_Matcap2Intensity ("Intensity", Range(0, 5)) = 1
		_Matcap2EmissionStrength ("Emission Strength", Range(0, 20)) = 0
		_Matcap2BaseColorMix ("Base Color Mix", Range(0, 1)) = 0
		_Matcap2Normal ("Normal Strength", Range(0, 1)) = 1
		
		[HideInInspector] s_start_Matcap1Masking ("Masking--{persistent_expand:true,default_expand:true}", Float) = 1
		[sRGBWarning][ThryRGBAPacker(R Mask, G Nothing, B Nothing, A Smoothness, linear, false)]_Matcap2Mask ("Mask--{reference_properties:[_Matcap2MaskPan, _Matcap2MaskUV, _Matcap2MaskChannel, _Matcap2MaskInvert]}", 2D) = "white" { }
		[HideInInspector][Vector2]_Matcap2MaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _Matcap2MaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_Matcap2MaskChannel ("Channel", Float) = 0
		[HideInInspector][ToggleUI]_Matcap2MaskInvert ("Invert", Float) = 0
		_Matcap2LightMask ("Hide in Shadow", Range(0, 1)) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _Matcap2MaskGlobalMask ("Global Mask--{reference_property:_Matcap2MaskGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_Matcap2MaskGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		[HideInInspector] s_end_Matcap1Masking ("Masking", Float) = 0
		
		[HideInInspector] s_start_Matcap1Blending ("Blending--{persistent_expand:true,default_expand:true}", Float) = 1
		_Matcap2Replace ("Replace", Range(0, 1)) = 0
		_Matcap2Multiply ("Multiply", Range(0, 1)) = 0
		_Matcap2Add ("Add", Range(0, 1)) = 0
		_Matcap2Mixed ("Mixed", Range(0, 1)) = 0
		_Matcap2Screen ("Screen", Range(0, 1)) = 0
		_Matcap2AddToLight ("Unlit Add", Range(0, 1)) = 0
		[HideInInspector] s_end_Matcap1Blending ("Blending", Float) = 0
		
		[HideInInspector] s_start_Matcap1Normal ("Custom Normal Map--{reference_property:_Matcap1CustomNormal,persistent_expand:true}", Float) = 0
		[HideInInspector][ThryToggle(POI_MATCAP1_CUSTOM_NORMAL, true)] _Matcap1CustomNormal ("Custom Normal", Float) = 0
		[Normal]_Matcap1NormalMap ("Normal Map--{reference_properties:[_Matcap1NormalMapPan, _Matcap1NormalMapUV, _Matcap1NormalMapScale]}", 2D) = "bump" { }
		[HideInInspector][Vector2]_Matcap1NormalMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _Matcap1NormalMapUV ("UV", Int) = 0
		[HideInInspector]_Matcap1NormalMapScale ("Intensity", Range(0, 10)) = 1
		[HideInInspector] s_end_Matcap1Normal ("", Float) = 0
		
		[HideInInspector] s_start_Matcap1HueShift ("Hue Shift--{reference_property:_Matcap2HueShiftEnabled,persistent_expand:true}", Float) = 0
		[HideInInspector][ToggleUI] _Matcap2HueShiftEnabled ("Hue Shift", Float) = 0
		_Matcap2HueShiftSpeed ("Shift Speed", Float) = 0
		_Matcap2HueShift ("Hue Shift", Range(0, 1)) = 0
		[HideInInspector] s_end_Matcap1HueShift ("", Float) = 0
		
		[HideInInspector] s_start_Matcap1Smoothness ("Blur / Smoothness--{reference_property:_Matcap2SmoothnessEnabled,persistent_expand:true}", Float) = 0
		[HideInInspector][ToggleUI] _Matcap2SmoothnessEnabled ("Blur / Smoothness", Float) = 0
		_Matcap2Smoothness ("Smoothness", Range(0, 1)) = 1
		[ToggleUI]_Matcap2MaskSmoothnessApply ("Apply Mask for Smoothness", Float) = 0
		[Enum(R, 0, G, 1, B, 2, A, 3)]_Matcap2MaskSmoothnessChannel ("Mask Channel for Smoothness", Int) = 3
		[HideInInspector] s_end_Matcap1Smoothness ("", Float) = 0
		
		[HideInInspector] s_start_matcap1ApplyToAlpha ("Alpha Options--{persistent_expand:true,default_expand:false}", Float) = 0
		_Matcap2AlphaOverride ("Override Alpha", Range(0, 1)) = 0
		[ToggleUI] _Matcap2ApplyToAlphaEnabled ("Intensity To Alpha", Float) = 0
		[ThryWideEnum(Greyscale, 0, Max, 1)] _Matcap2ApplyToAlphaSourceBlend ("Source Blend--{condition_showS:(_Matcap2ApplyToAlphaEnabled==1)}", Int) = 0
		[ThryWideEnum(Add, 0, Multiply, 1)] _Matcap2ApplyToAlphaBlendType ("Blend Type--{condition_showS:(_Matcap2ApplyToAlphaEnabled==1)}", Int) = 0
		_Matcap2ApplyToAlphaBlending ("Blending--{condition_showS:(_Matcap2ApplyToAlphaEnabled==1)}", Range(0, 1)) = 1.0
		[HideInInspector] s_end_matcap1ApplyToAlpha ("", Float) = 0
		
		[HideInInspector] s_start_Matcap2TPSMaskGroup ("Matcap TPS Mask--{reference_property:_Matcap2TPSDepthEnabled,persistent_expand:true,default_expand:false, condition_showS:(_TPSPenetratorEnabled==1)}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _Matcap2TPSDepthEnabled ("TPS Depth Mask Enabled", Float) = 0
		_Matcap2TPSMaskStrength ("TPS Mask Strength", Range(0, 1)) = 1
		[HideInInspector] s_end_Matcap2TPSMaskGroup ("", Float) = 0
		
		[HideInInspector] s_start_Matcap1AudioLink ("Audio Link ♫--{reference_property:_Matcap1ALEnabled,persistent_expand:true,default_expand:false, condition_showS:(_EnableAudioLink==1)}", Float) = 0
		[HideInInspector][ToggleUI] _Matcap1ALEnabled ("Enable Audio Link", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _Matcap1ALAlphaAddBand ("Alpha Band", Int) = 0
		[VectorLabel(Min, Max)]_Matcap1ALAlphaAdd ("Alpha Mod", Vector) = (0, 0, 0, 0)
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _Matcap1ALEmissionAddBand ("Emission Band", Int) = 0
		[VectorLabel(Min, Max)]_Matcap1ALEmissionAdd ("Emission Mod", Vector) = (0, 0, 0, 0)
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _Matcap1ALIntensityAddBand ("Intensity Band", Int) = 0
		[VectorLabel(Min, Max)]_Matcap1ALIntensityAdd ("Intensity Mod", Vector) = (0, 0, 0, 0)
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_Matcap1ALChronoPanType ("Chrono Pan Type--{condition_showS:(_Matcap2UVMode==3)}", Int) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _Matcap1ALChronoPanBand ("Chrono Pan Band--{condition_showS:(_Matcap2UVMode==3)}", Int) = 0
		_Matcap1ALChronoPanSpeed ("Chrono Pan Speed--{condition_showS:(_Matcap2UVMode==3)}", Float) = 0
		[HideInInspector] s_end_Matcap1AudioLink ("Audio Link", Float) = 0
		[HideInInspector] m_end_Matcap2 ("Matcap 1", Float) = 0
		//endex
		
		// Third Matcap
		//ifex _Matcap3Enable==0
		[HideInInspector] m_start_Matcap3 ("Matcap 2--{reference_property:_Matcap3Enable,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/shading/matcap},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(POI_MATCAP2)]_Matcap3Enable ("Enable Matcap 2", Float) = 0
		[ThryWideEnum(UTS Style, 0, Top Pinch, 1, Double Sided, 2, Gradient, 3)] _Matcap3UVMode ("UV Mode", Int) = 1
		_Matcap3Color ("Color--{reference_property:_Matcap3ColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _Matcap3ColorThemeIndex ("", Int) = 0
		[sRGBWarning(true)][Gradient]_Matcap3 ("Matcap--{reference_properties:[_Matcap3UVToBlend,_MatCap3rdBlendUV1,_Matcap3Pan,_Matcap3Border,_Matcap3Rotation]}", 2D) = "white" { }
		[HideInInspector][Vector2]_Matcap3Pan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _Matcap3UVToBlend ("UV To Blend", Int) = 1
		[HideInInspector][VectorToSliders(Blend UV X, 0.0, 1.0, Blend UV Y, 0.0, 1.0)]_MatCap3rdBlendUV1 ("UV Blend", Vector) = (0, 0, 0, 0)
		[HideInInspector]_Matcap3Border ("Border", Range(0, 5)) = 0.43
		[HideInInspector]_Matcap3Rotation ("Rotation", Range(-1, 1)) = 0
		_Matcap3Intensity ("Intensity", Range(0, 5)) = 1
		_Matcap3EmissionStrength ("Emission Strength", Range(0, 20)) = 0
		_Matcap3BaseColorMix ("Base Color Mix", Range(0, 1)) = 0
		_Matcap3Normal ("Normal Strength", Range(0, 1)) = 1
		
		[HideInInspector] s_start_Matcap2Masking ("Masking--{persistent_expand:true,default_expand:true}", Float) = 1
		[sRGBWarning][ThryRGBAPacker(R Mask, G Nothing, B Nothing, A Smoothness, linear, false)]_Matcap3Mask ("Mask--{reference_properties:[_Matcap3MaskPan, _Matcap3MaskUV, _Matcap3MaskChannel, _Matcap3MaskInvert]}", 2D) = "white" { }
		[HideInInspector][Vector2]_Matcap3MaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _Matcap3MaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_Matcap3MaskChannel ("Channel", Float) = 0
		[HideInInspector][ToggleUI]_Matcap3MaskInvert ("Invert", Float) = 0
		_Matcap3LightMask ("Hide in Shadow", Range(0, 1)) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _Matcap3MaskGlobalMask ("Global Mask--{reference_property:_Matcap3MaskGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_Matcap3MaskGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		[HideInInspector] s_end_Matcap2Masking ("Masking", Float) = 0
		
		[HideInInspector] s_start_Matcap2Blending ("Blending--{persistent_expand:true,default_expand:true}", Float) = 1
		_Matcap3Replace ("Replace", Range(0, 1)) = 0
		_Matcap3Multiply ("Multiply", Range(0, 1)) = 0
		_Matcap3Add ("Add", Range(0, 1)) = 0
		_Matcap3Mixed ("Mixed", Range(0, 1)) = 0
		_Matcap3Screen ("Screen", Range(0, 1)) = 0
		_Matcap3AddToLight ("Unlit Add", Range(0, 1)) = 0
		[HideInInspector] s_end_Matcap2Blending ("Blending", Float) = 0
		
		[HideInInspector] s_start_Matcap2Normal ("Custom Normal Map--{reference_property:_Matcap2CustomNormal,persistent_expand:true}", Float) = 0
		[HideInInspector][ThryToggle(POI_MATCAP2_CUSTOM_NORMAL, true)] _Matcap2CustomNormal ("Custom Normal", Float) = 0
		[Normal]_Matcap2NormalMap ("Normal Map--{reference_properties:[_Matcap2NormalMapPan, _Matcap2NormalMapUV, _Matcap2NormalMapScale]}", 2D) = "bump" { }
		[HideInInspector][Vector2]_Matcap2NormalMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _Matcap2NormalMapUV ("UV", Int) = 0
		[HideInInspector]_Matcap2NormalMapScale ("Intensity", Range(0, 10)) = 1
		[HideInInspector] s_end_Matcap2Normal ("", Float) = 0
		
		[HideInInspector] s_start_Matcap2HueShift ("Hue Shift--{reference_property:_Matcap3HueShiftEnabled,persistent_expand:true}", Float) = 0
		[HideInInspector][ToggleUI] _Matcap3HueShiftEnabled ("Hue Shift", Float) = 0
		_Matcap3HueShiftSpeed ("Shift Speed", Float) = 0
		_Matcap3HueShift ("Hue Shift", Range(0, 1)) = 0
		[HideInInspector] s_end_Matcap2HueShift ("", Float) = 0
		
		[HideInInspector] s_start_Matcap2Smoothness ("Blur / Smoothness--{reference_property:_Matcap3SmoothnessEnabled,persistent_expand:true}", Float) = 0
		[HideInInspector][ToggleUI] _Matcap3SmoothnessEnabled ("Blur / Smoothness", Float) = 0
		_Matcap3Smoothness ("Smoothness", Range(0, 1)) = 1
		[ToggleUI]_Matcap3MaskSmoothnessApply ("Apply Mask for Smoothness", Float) = 0
		[Enum(R, 0, G, 1, B, 2, A, 3)]_Matcap3MaskSmoothnessChannel ("Mask Channel for Smoothness", Int) = 3
		[HideInInspector] s_end_Matcap2Smoothness ("", Float) = 0
		
		[HideInInspector] s_start_matcap2ApplyToAlpha ("Alpha Options--{persistent_expand:true,default_expand:false}", Float) = 0
		_Matcap3AlphaOverride ("Override Alpha", Range(0, 1)) = 0
		[ToggleUI] _Matcap3ApplyToAlphaEnabled ("Intensity To Alpha", Float) = 0
		[ThryWideEnum(Greyscale, 0, Max, 1)] _Matcap3ApplyToAlphaSourceBlend ("Source Blend--{condition_showS:(_Matcap3ApplyToAlphaEnabled==1)}", Int) = 0
		[ThryWideEnum(Add, 0, Multiply, 1)] _Matcap3ApplyToAlphaBlendType ("Blend Type--{condition_showS:(_Matcap3ApplyToAlphaEnabled==1)}", Int) = 0
		_Matcap3ApplyToAlphaBlending ("Blending--{condition_showS:(_Matcap3ApplyToAlphaEnabled==1)}", Range(0, 1)) = 1.0
		[HideInInspector] s_end_matcap2ApplyToAlpha ("", Float) = 0
		
		[HideInInspector] s_start_Matcap3TPSMaskGroup ("Matcap TPS Mask--{reference_property:_Matcap3TPSDepthEnabled,persistent_expand:true,default_expand:false, condition_showS:(_TPSPenetratorEnabled==1)}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _Matcap3TPSDepthEnabled ("TPS Depth Mask Enabled", Float) = 0
		_Matcap3TPSMaskStrength ("TPS Mask Strength", Range(0, 1)) = 1
		[HideInInspector] s_end_Matcap3TPSMaskGroup ("", Float) = 0
		
		[HideInInspector] s_start_Matcap2AudioLink ("Audio Link ♫--{reference_property:_Matcap2ALEnabled,persistent_expand:true,default_expand:false, condition_showS:(_EnableAudioLink==1)}", Float) = 0
		[HideInInspector][ToggleUI] _Matcap2ALEnabled ("Enable Audio Link", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _Matcap2ALAlphaAddBand ("Alpha Band", Int) = 0
		[VectorLabel(Min, Max)]_Matcap2ALAlphaAdd ("Alpha Mod", Vector) = (0, 0, 0, 0)
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _Matcap2ALEmissionAddBand ("Emission Band", Int) = 0
		[VectorLabel(Min, Max)]_Matcap2ALEmissionAdd ("Emission Mod", Vector) = (0, 0, 0, 0)
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _Matcap2ALIntensityAddBand ("Intensity Band", Int) = 0
		[VectorLabel(Min, Max)]_Matcap2ALIntensityAdd ("Intensity Mod", Vector) = (0, 0, 0, 0)
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_Matcap2ALChronoPanType ("Chrono Pan Type--{condition_showS:(_Matcap3UVMode==3)}", Int) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _Matcap2ALChronoPanBand ("Chrono Pan Band--{condition_showS:(_Matcap3UVMode==3)}", Int) = 0
		_Matcap2ALChronoPanSpeed ("Chrono Pan Speed--{condition_showS:(_Matcap3UVMode==3)}", Float) = 0
		[HideInInspector] s_end_Matcap2AudioLink ("Audio Link", Float) = 0
		[HideInInspector] m_end_Matcap3 ("Matcap 3", Float) = 0
		//endex
		
		// Fourth Matcap
		//ifex _Matcap4Enable==0
		[HideInInspector] m_start_Matcap4 ("Matcap 3--{reference_property:_Matcap4Enable,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/shading/matcap},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(POI_MATCAP3)]_Matcap4Enable ("Enable Matcap 3", Float) = 0
		[ThryWideEnum(UTS Style, 0, Top Pinch, 1, Double Sided, 2, Gradient, 3)] _Matcap4UVMode ("UV Mode", Int) = 1
		_Matcap4Color ("Color--{reference_property:_Matcap4ColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _Matcap4ColorThemeIndex ("", Int) = 0
		[sRGBWarning(true)][Gradient]_Matcap4 ("Matcap--{reference_properties:[_Matcap4UVToBlend,_MatCap4thBlendUV1,_Matcap4Pan,_Matcap4Border,_Matcap4Rotation]}", 2D) = "white" { }
		[HideInInspector][Vector2]_Matcap4Pan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _Matcap4UVToBlend ("UV To Blend", Int) = 1
		[HideInInspector][VectorToSliders(Blend UV X, 0.0, 1.0, Blend UV Y, 0.0, 1.0)]_MatCap4thBlendUV1 ("UV Blend", Vector) = (0, 0, 0, 0)
		[HideInInspector]_Matcap4Border ("Border", Range(0, 5)) = 0.43
		[HideInInspector]_Matcap4Rotation ("Rotation", Range(-1, 1)) = 0
		_Matcap4Intensity ("Intensity", Range(0, 5)) = 1
		_Matcap4EmissionStrength ("Emission Strength", Range(0, 20)) = 0
		_Matcap4BaseColorMix ("Base Color Mix", Range(0, 1)) = 0
		_Matcap4Normal ("Normal Strength", Range(0, 1)) = 1
		
		[HideInInspector] s_start_Matcap3Masking ("Masking--{persistent_expand:true,default_expand:true}", Float) = 1
		[sRGBWarning][ThryRGBAPacker(R Mask, G Nothing, B Nothing, A Smoothness, linear, false)]_Matcap4Mask ("Mask--{reference_properties:[_Matcap4MaskPan, _Matcap4MaskUV, _Matcap4MaskChannel, _Matcap4MaskInvert]}", 2D) = "white" { }
		[HideInInspector][Vector2]_Matcap4MaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _Matcap4MaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_Matcap4MaskChannel ("Channel", Float) = 0
		[HideInInspector][ToggleUI]_Matcap4MaskInvert ("Invert", Float) = 0
		_Matcap4LightMask ("Hide in Shadow", Range(0, 1)) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _Matcap4MaskGlobalMask ("Global Mask--{reference_property:_Matcap4MaskGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_Matcap4MaskGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		[HideInInspector] s_end_Matcap3Masking ("Masking", Float) = 0
		
		[HideInInspector] s_start_Matcap3Blending ("Blending--{persistent_expand:true,default_expand:true}", Float) = 1
		_Matcap4Replace ("Replace", Range(0, 1)) = 0
		_Matcap4Multiply ("Multiply", Range(0, 1)) = 0
		_Matcap4Add ("Add", Range(0, 1)) = 0
		_Matcap4Mixed ("Mixed", Range(0, 1)) = 0
		_Matcap4Screen ("Screen", Range(0, 1)) = 0
		_Matcap4AddToLight ("Unlit Add", Range(0, 1)) = 0
		[HideInInspector] s_end_Matcap3Blending ("Blending", Float) = 0
		
		[HideInInspector] s_start_Matcap3Normal ("Custom Normal Map--{reference_property:_Matcap3CustomNormal,persistent_expand:true}", Float) = 0
		[HideInInspector][ThryToggle(POI_MATCAP3_CUSTOM_NORMAL, true)] _Matcap3CustomNormal ("Custom Normal", Float) = 0
		[Normal]_Matcap3NormalMap ("Normal Map--{reference_properties:[_Matcap3NormalMapPan, _Matcap3NormalMapUV, _Matcap3NormalMapScale]}", 2D) = "bump" { }
		[HideInInspector][Vector2]_Matcap3NormalMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _Matcap3NormalMapUV ("UV", Int) = 0
		[HideInInspector]_Matcap3NormalMapScale ("Intensity", Range(0, 10)) = 1
		[HideInInspector] s_end_Matcap3Normal ("", Float) = 0
		
		[HideInInspector] s_start_Matcap3HueShift ("Hue Shift--{reference_property:_Matcap4HueShiftEnabled,persistent_expand:true}", Float) = 0
		[HideInInspector][ToggleUI] _Matcap4HueShiftEnabled ("Hue Shift", Float) = 0
		_Matcap4HueShiftSpeed ("Shift Speed", Float) = 0
		_Matcap4HueShift ("Hue Shift", Range(0, 1)) = 0
		[HideInInspector] s_end_Matcap3HueShift ("", Float) = 0
		
		[HideInInspector] s_start_Matcap3Smoothness ("Blur / Smoothness--{reference_property:_Matcap4SmoothnessEnabled,persistent_expand:true}", Float) = 0
		[HideInInspector][ToggleUI] _Matcap4SmoothnessEnabled ("Blur / Smoothness", Float) = 0
		_Matcap4Smoothness ("Smoothness", Range(0, 1)) = 1
		[ToggleUI]_Matcap4MaskSmoothnessApply ("Apply Mask for Smoothness", Float) = 0
		[Enum(R, 0, G, 1, B, 2, A, 3)]_Matcap4MaskSmoothnessChannel ("Mask Channel for Smoothness", Int) = 3
		[HideInInspector] s_end_Matcap3Smoothness ("", Float) = 0
		
		[HideInInspector] s_start_matcap3ApplyToAlpha ("Alpha Options--{persistent_expand:true,default_expand:false}", Float) = 0
		_Matcap4AlphaOverride ("Override Alpha", Range(0, 1)) = 0
		[ToggleUI] _Matcap4ApplyToAlphaEnabled ("Intensity To Alpha", Float) = 0
		[ThryWideEnum(Greyscale, 0, Max, 1)] _Matcap4ApplyToAlphaSourceBlend ("Source Blend--{condition_showS:(_Matcap4ApplyToAlphaEnabled==1)}", Int) = 0
		[ThryWideEnum(Add, 0, Multiply, 1)] _Matcap4ApplyToAlphaBlendType ("Blend Type--{condition_showS:(_Matcap4ApplyToAlphaEnabled==1)}", Int) = 0
		_Matcap4ApplyToAlphaBlending ("Blending--{condition_showS:(_Matcap4ApplyToAlphaEnabled==1)}", Range(0, 1)) = 1.0
		[HideInInspector] s_end_matcap3ApplyToAlpha ("", Float) = 0
		
		[HideInInspector] s_start_Matcap4TPSMaskGroup ("Matcap TPS Mask--{reference_property:_Matcap4TPSDepthEnabled,persistent_expand:true,default_expand:false, condition_showS:(_TPSPenetratorEnabled==1)}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _Matcap4TPSDepthEnabled ("TPS Depth Mask Enabled", Float) = 0
		_Matcap4TPSMaskStrength ("TPS Mask Strength", Range(0, 1)) = 1
		[HideInInspector] s_end_Matcap4TPSMaskGroup ("", Float) = 0
		
		[HideInInspector] s_start_Matcap3AudioLink ("Audio Link ♫--{reference_property:_Matcap3ALEnabled,persistent_expand:true,default_expand:false, condition_showS:(_EnableAudioLink==1)}", Float) = 0
		[HideInInspector][ToggleUI] _Matcap3ALEnabled ("Enable Audio Link", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _Matcap3ALAlphaAddBand ("Alpha Band", Int) = 0
		[VectorLabel(Min, Max)]_Matcap3ALAlphaAdd ("Alpha Mod", Vector) = (0, 0, 0, 0)
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _Matcap3ALEmissionAddBand ("Emission Band", Int) = 0
		[VectorLabel(Min, Max)]_Matcap3ALEmissionAdd ("Emission Mod", Vector) = (0, 0, 0, 0)
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _Matcap3ALIntensityAddBand ("Intensity Band", Int) = 0
		[VectorLabel(Min, Max)]_Matcap3ALIntensityAdd ("Intensity Mod", Vector) = (0, 0, 0, 0)
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_Matcap3ALChronoPanType ("Chrono Pan Type--{condition_showS:(_Matcap4UVMode==3)}", Int) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _Matcap3ALChronoPanBand ("Chrono Pan Band--{condition_showS:(_Matcap4UVMode==3)}", Int) = 0
		_Matcap3ALChronoPanSpeed ("Chrono Pan Speed--{condition_showS:(_Matcap4UVMode==3)}", Float) = 0
		[HideInInspector] s_end_Matcap3AudioLink ("Audio Link", Float) = 0
		[HideInInspector] m_end_Matcap4 ("Matcap 4", Float) = 0
		//endex
		
		//ifex _CubeMapEnabled==0
		[HideInInspector] m_start_CubeMap ("CubeMap--{reference_property:_CubeMapEnabled,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/shading/cubemap},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(_CUBEMAP)]_CubeMapEnabled ("Enable CubeMap", Float) = 0
		[ThryWideEnum(Skybox, 0, Reflection, 1, World Normal Direction, 2, Local Normal Direction, 3)] _CubeMapUVMode ("UV Mode", Int) = 1
		_CubeMapWorldNormalsStrength ("Normals Strength--{condition_showS:(_CubeMapUVMode==2)}", Range(0, 1)) = 1
		_CubeMapColor ("Color--{reference_property:_CubeMapColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _CubeMapColorThemeIndex ("", Int) = 0
		[NoScaleOffset]_CubeMap ("CubeMap--{reference_properties:[_CubeMapRotation, _CubeMapRotationPan]}", Cube) = "" { }
		[HideInInspector][Vector3]_CubeMapRotation ("Rotation in Degrees", Vector) = (0, 0, 0, 0)
		[HideInInspector][Vector3]_CubeMapRotationPan ("Panning in Degrees", Vector) = (0, 0, 0, 0)
		[ThryWideEnum(Replace, 0, Multiply, 1, Add, 2)]_CubemapBlendType ("Blending", Float) = 0
		_CubeMapBlendAmount ("Blend Alpha", Range(0, 1)) = 1
		
		_CubeMapIntensity ("Brightness", Range(0, 5)) = 1
		_CubeMapEmissionStrength ("Emission Strength", Range(0, 20)) = 0
		_CubeMapSmoothness ("Smoothness", Range(0, 1)) = 1
		[Enum(Vertex, 0, Pixel, 1)] _CubeMapNormal ("Normal to use", Int) = 1
		
		[HideInInspector] s_start_CubeMapMasking ("Masking--{persistent_expand:true,default_expand:true}", Float) = 1
		[sRGBWarning]_CubeMapMask ("Mask--{reference_properties:[_CubeMapMaskPan, _CubeMapMaskUV, _CubeMapMaskChannel, _CubeMapMaskInvert]}", 2D) = "white" { }
		[HideInInspector][Vector2]_CubeMapMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _CubeMapMaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_CubeMapMaskChannel ("Channel", Float) = 0
		[HideInInspector][ToggleUI]_CubeMapMaskInvert ("Invert", Float) = 0
		_CubeMapLightMask ("Hide in Shadow", Range(0, 1)) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _CubeMapMaskGlobalMask ("Global Mask--{reference_property:_CubeMapMaskGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_CubeMapMaskGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		[HideInInspector] s_end_CubeMapMasking ("Masking", Float) = 0
		
		[HideInInspector] s_start_CubeMapColorAdjust ("Color Adjust--{reference_property:_CubeMapHueShiftEnabled,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_CubeMapHueShiftEnabled ("Enabled", Float) = 0
		_CubeMapHueShiftSpeed ("Hue Shift Speed", Float) = 0
		_CubeMapHueShift ("Hue Shift", Range(0, 1)) = 0
		_CubeMapBrightness ("Brightness", Range(-1, 1)) = 0
		_CubeMapContrast ("Contrast", Range(-1, 10)) = 1
		_CubeMapSaturation ("Saturation", Range(-1, 10)) = 1
		[HideInInspector] s_end_CubeMapColorAdjust ("", Float) = 0
		
		[HideInInspector] m_end_CubeMap ("CubeMap", Float) = 0
		//endex
		
		//ifex _EnableRimLighting==0
		[HideInInspector] m_start_rimLight1Options ("Rim Lighting 0--{reference_property:_EnableRimLighting,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/shading/rim-lighting},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(_GLOSSYREFLECTIONS_OFF)]_EnableRimLighting ("Enable Rim Lighting", Float) = 0
		[KeywordEnum(Poiyomi, UTS2, LilToon)] _RimStyle ("Style", Float) = 0
		
		[sRGBWarning]_Set_RimLightMask ("Set_RimLightMask--{reference_properties:[_Set_RimLightMaskPan, _Set_RimLightMaskUV, _Set_RimLightMaskChannel], condition_showS:_RimStyle==1}", 2D) = "white" { }
		[HideInInspector][Vector2]_Set_RimLightMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _Set_RimLightMaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_Set_RimLightMaskChannel ("Channel", Float) = 1
		[sRGBWarning][ThryRGBAPacker(Mask, Bias, linear, false)]_RimMask ("Mask & Bias--{reference_properties:[_RimMaskPan, _RimMaskUV, _RimMaskChannel, _RimMaskInvert, _RimBiasIntensity], condition_showS:_RimStyle==0}", 2D) = "white" { }
		[HideInInspector][Vector2]_RimMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _RimMaskUV ("UV", Int) = 0
		[HideInInspector][ToggleUI]_RimMaskInvert ("Invert Mask", Float) = 0
		[HideInInspector]_RimBiasIntensity ("Bias Intensity", Range(0, 1)) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_RimMaskChannel ("Channel", Float) = 0
		
		[HideInInspector] s_start_RimLight0Color ("Color & Blending--{persistent_expand:true,default_expand:true, condition_showS:_RimStyle==0||_RimStyle==1}", Float) = 1
		[sRGBWarning(true)]_RimTex ("Rim Texture--{reference_properties:[_RimTexPan, _RimTexUV], condition_showS:_RimStyle==0}", 2D) = "white" { }
		[HideInInspector][Vector2]_RimTexPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _RimTexUV ("UV", Int) = 0
		_RimLightColor (" Color--{condition_showS:_RimStyle==0||_RimStyle==1,reference_property:_RimLightColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _RimLightColorThemeIndex ("", Int) = 0
		[ThryWideEnum(Add, 0, Replace, 1, Multiply, 2, Mixed, 3, Screen, 4)] _RimPoiBlendMode ("Blend Mode--{ condition_showS:_RimStyle==0}", Int) = 0
		_RimBlendStrength ("Blend Alpha--{ condition_showS:_RimStyle==0}", Range(0, 1)) = 1
		_RimBaseColorMix ("Mix Base Color--{ condition_showS:_RimStyle==0}", Range(0, 1)) = 0
		_RimBrightness ("Brightness--{ condition_showS:_RimStyle==0}", Range(0, 10)) = 1
		_RimStrength ("Emission--{ condition_showS:_RimStyle==0}", Range(0, 20)) = 0
		_Tweak_RimLightMaskLevel ("Tweak_RimLightMaskLevel--{ condition_showS:_RimStyle==1}", Range(-1, 1)) = 0
		_Is_LightColor_RimLight ("Mix Light Color--{ condition_showS:_RimStyle==1}", Range(0, 1)) = 1
		[HideInInspector] s_end_RimLight0Color ("Color & Brightness", Float) = 0
		
		[HideInInspector] s_start_RimLight0ShapeControls ("Shape Controls--{persistent_expand:true,default_expand:true, condition_showS:_RimStyle==0||_RimStyle==1}", Float) = 1
		_RimWidth ("Width--{ condition_showS:_RimStyle==0}", Range(0, 1)) = 0.8
		_RimSharpness ("Sharpness--{ condition_showS:_RimStyle==0}", Range(0, 1)) = .25
		_RimPower ("Rim Power--{ condition_showS:_RimStyle==0}", Range(0, 10)) = 1
		_Is_NormalMapToRimLight ("Normal Strength", Range(0, 1)) = 1
		[ToggleUI]_RimLightingInvert ("Invert Rim--{ condition_showS:_RimStyle==0}", Float) = 0
		_RimLight_Power ("Rim Power--{ condition_showS:_RimStyle==1}", Range(0, 1)) = 0.1
		_RimLight_InsideMask ("Inside Mask--{ condition_showS:_RimStyle==1}", Range(0.0001, 1)) = 0.0001
		[Toggle(_)] _RimLight_FeatherOff ("Feather Off--{ condition_showS:_RimStyle==1}", Float) = 0
		[HideInInspector] s_end_RimLight0ShapeControls ("Shape Controls", Float) = 0
		
		[HideInInspector] s_start_RimLight0LightDirMask ("Light Direction Mask--{reference_property:_RimShadowToggle,persistent_expand:true,default_expand:false, condition_showS:_RimStyle==0}", Float) = 0
		[HideInInspector][ToggleUI] _RimShadowToggle ("Light Direction Mask}", Float) = 0
		[Enum(Shadow Map, 0, Custom, 1)]_RimShadowMaskRampType ("Light Falloff Type", Int) = 0
		[ToggleUI]_RimShadowMaskInvert ("Invert Shadow Mask", Float) = 0
		_RimShadowMaskStrength ("Shadow Mask Strength", Range(0, 1)) = 1
		[MultiSlider]_RimShadowAlpha ("Hide In Shadow--{ condition_showS:_RimShadowMaskRampType==1}", Vector) = (0.0, 0.0, 0, 1)
		_RimShadowWidth ("Shrink In Shadow", Range(0, 1)) = 0
		[HideInInspector] s_end_RimLight0LightDirMask ("Light Direction Mask", Float) = 0
		
		// UTS2
		[HideInInspector] s_start_RimLightDirectionMask ("Light Direction Mask--{persistent_expand:true,default_expand:false, condition_showS:_RimStyle==1}", Float) = 0
		[ToggleUI] _LightDirection_MaskOn ("Light Direction Mask--{ condition_showS:_RimStyle==1}", Float) = 0
		_Tweak_LightDirection_MaskLevel ("Light Dir Mask Level--{ condition_showS:_RimStyle==1}", Range(0, 0.5)) = 0
		[ThryToggleUI(true)] _Add_Antipodean_RimLight ("<size=13><b>  Antipodean(Ap) Rim</b></size>--{ condition_showS:_RimStyle==1}", Float) = 0
		_Is_LightColor_Ap_RimLight ("Ap Light Color Mix--{ condition_showS:_Add_Antipodean_RimLight==1&&_RimStyle==1}", Range(0, 1)) = 1
		_Ap_RimLightColor ("Ap Color--{reference_property:_RimApColorThemeIndex, condition_showS:_Add_Antipodean_RimLight==1&&_RimStyle==1}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _RimApColorThemeIndex ("", Int) = 0
		_Ap_RimLight_Power ("Ap Power--{ condition_showS:_Add_Antipodean_RimLight==1&&_RimStyle==1}", Range(0, 1)) = 0.1
		[Toggle(_)] _Ap_RimLight_FeatherOff ("Ap Feather Off--{ condition_showS:_Add_Antipodean_RimLight==1&&_RimStyle==1}", Float) = 0
		[HideInInspector] s_end_RimLightDirectionMask ("Light Direction Mask", Float) = 0
		// Liltoon
		[HDR][Gamma]_RimColor ("Rim Color--{condition_showS:_RimStyle==2,reference_property:_RimLightColorThemeIndex}", Color) = (0.66, 0.5, 0.48, 1)
		[sRGBWarning(true)] _RimColorTex ("Color / Mask--{condition_showS:_RimStyle==2,reference_properties:[_RimColorTexPan, _RimColorTexUV]}", 2D) = "white" { }
		[HideInInspector][Vector2] _RimColorTexPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _RimColorTexUV ("UV", Int) = 0
		_RimMainStrength ("Main Color Blend--{condition_showS:_RimStyle==2}", Range(0, 1)) = 0
		_RimNormalStrength ("Normal Strength--{condition_showS:_RimStyle==2}", Range(0, 1)) = 1.0
		_RimBorder ("Border--{condition_showS:_RimStyle==2}", Range(0, 1)) = 0.5
		_RimBlur ("Blur--{condition_showS:_RimStyle==2}", Range(0, 1)) = 0.65
		[PowerSlider(3.0)]_RimFresnelPower ("Fresnel Power--{condition_showS:_RimStyle==2}", Range(0.01, 50)) = 3.5
		_RimEnableLighting ("Enable Lighting--{condition_showS:_RimStyle==2}", Range(0, 1)) = 1
		_RimShadowMask ("Shadow Mask--{condition_showS:_RimStyle==2}", Range(0, 1)) = 0.5
		[ToggleUI]_RimBackfaceMask ("Backface Mask--{condition_showS:_RimStyle==2}", Int) = 1
		_RimVRParallaxStrength ("VR Parallax Strength--{condition_showS:_RimStyle==2}", Range(0, 1)) = 1
		// [ToggleUI]_RimApplyTransparency ("Apply Transparency--{condition_showS:_RimStyle==2}", Int) = 1
		[ThryWideEnum(Replace, 0, Add, 1, Screen, 2, Multiply, 3)]_RimBlendMode ("Blend Mode--{condition_showS:_RimStyle==2}", Int) = 1
		
		[HideInInspector] s_start_liltoon_rim_lightdir ("Light Direction--{persistent_expand:true,default_expand:false, condition_showS:_RimStyle==2}", Float) = 0
		_RimDirStrength ("Light direction strength", Range(0, 1)) = 0
		_RimDirRange ("Direction Light Width", Range(-1, 1)) = 0
		_RimIndirRange ("Indirection Light Width", Range(-1, 1)) = 0
		[HDR][Gamma]_RimIndirColor ("Indirection Color", Color) = (1, 1, 1, 1)
		_RimIndirBorder ("Indirection Border", Range(0, 1)) = 0.5
		_RimIndirBlur ("Indirection Blur", Range(0, 1)) = 0.1
		[HideInInspector] s_end_liltoon_rim_lightdir ("", Float) = 0
		
		[HideInInspector] s_start_RimLight0HueShift ("Hue Shift--{reference_property:_RimHueShiftEnabled,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI] _RimHueShiftEnabled ("Hue Shift", Float) = 0
		_RimHueShiftSpeed ("Shift Speed", Float) = 0
		_RimHueShift ("Hue Shift", Range(0, 1)) = 0
		[HideInInspector] s_end_RimLight0HueShift ("Hue Shift", Float) = 0
		
		[HideInInspector] s_start_RimLight0GlobalMasking ("Alpha & Global Masking--{persistent_expand:true,default_expand:false}", Float) = 0
		[ThryWideEnum(Off, 0, Add, 1, Multiply, 2)]_RimApplyAlpha ("Apply to Alpha--{ condition_showS:_Rim2Style==0}", Int) = 0
		_RimApplyAlphaBlend ("Apply to Alpha Blend--{ condition_showS:_Rim2Style==0}", Range(0, 1)) = 1.0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _RimGlobalMask (" Global Mask--{reference_property:_RimGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _RimGlobalMaskBlendType ("Blending", Int) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _RimApplyGlobalMaskIndex (" Apply to Global Mask--{reference_property:_RimApplyGlobalMaskBlendType,condition_showS:_RimStyle==0}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _RimApplyGlobalMaskBlendType ("Blending", Int) = 2
		[HideInInspector] s_end_RimLight0GlobalMasking ("Alpha & Global Masking", Float) = 0
		
		[HideInInspector] m_start_RimAudioLink ("Audio Link ♫--{ condition_showS:_EnableAudioLink==1&&_RimStyle==0}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkRimWidthBand ("Width Add Band", Int) = 0
		[VectorLabel(Min, Max)] _AudioLinkRimWidthAdd ("Width Add", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkRimEmissionBand ("Emission Add Band", Int) = 0
		[VectorLabel(Min, Max)] _AudioLinkRimEmissionAdd ("Emission Add", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkRimBrightnessBand ("Brightness Band", Int) = 0
		[VectorLabel(Min, Max)] _AudioLinkRimBrightnessAdd ("Brightness Add", Vector) = (0, 0, 0, 0)
		[HideInInspector] m_end_RimAudioLink ("Audio Link", Float) = 0
		[HideInInspector] m_end_rim1LightOptions ("Rim Lighting", Float) = 0
		//endex
		
		// Second Rim Lighting
		//ifex _EnableRim2Lighting==0
		[HideInInspector] m_start_rim2LightOptions ("Rim Lighting 1--{reference_property:_EnableRim2Lighting,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/shading/rim-lighting},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(POI_RIM2)]_EnableRim2Lighting ("Enable Rim2 Lighting", Float) = 0
		[KeywordEnum(Poiyomi, UTS2, LilToon)] _Rim2Style ("Style", Float) = 0
		
		[sRGBWarning]_Set_Rim2LightMask ("Set_RimLightMask--{reference_properties:[_Set_Rim2LightMaskPan, _Set_Rim2LightMaskUV, _Set_Rim2LightMaskChannel], condition_showS:_Rim2Style==1}", 2D) = "white" { }
		[HideInInspector][Vector2]_Set_Rim2LightMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _Set_Rim2LightMaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_Set_Rim2LightMaskChannel ("Channel", Float) = 1
		[sRGBWarning][ThryRGBAPacker(Mask, Bias, linear, false)]_Rim2Mask ("Mask & Bias--{reference_properties:[_Rim2MaskPan, _Rim2MaskUV, _Rim2MaskChannel, _Rim2MaskInvert, _Rim2BiasIntensity], condition_showS:_Rim2Style==0}", 2D) = "white" { }
		[HideInInspector][Vector2]_Rim2MaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _Rim2MaskUV ("UV", Int) = 0
		[HideInInspector][ToggleUI]_Rim2MaskInvert ("Invert Mask", Float) = 0
		[HideInInspector]_Rim2BiasIntensity ("Bias Intensity", Range(0, 1)) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_Rim2MaskChannel ("Channel", Float) = 0
		
		[HideInInspector] s_start_RimLight1Color ("Color & Blending--{persistent_expand:true,default_expand:true, condition_showS:_Rim2Style==0||_Rim2Style==1}", Float) = 1
		[sRGBWarning(true)]_Rim2Tex ("Rim Texture--{reference_properties:[_Rim2TexPan, _Rim2TexUV], condition_showS:_Rim2Style==0}", 2D) = "white" { }
		[HideInInspector][Vector2]_Rim2TexPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _Rim2TexUV ("UV", Int) = 0
		_Rim2LightColor (" Color--{condition_showS:_Rim2Style==0||_Rim2Style==1,reference_property:_Rim2LightColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _Rim2LightColorThemeIndex ("", Int) = 0
		[ThryWideEnum(Add, 0, Replace, 1, Multiply, 2, Mixed, 3, Screen, 4)] _RimPoi2BlendMode ("Blend Mode--{ condition_showS:_Rim2Style==0}", Int) = 0
		_Rim2BlendStrength ("Blend Alpha--{ condition_showS:_Rim2Style==0}", Range(0, 1)) = 1
		_Rim2BaseColorMix ("Mix Base Color--{ condition_showS:_Rim2Style==0}", Range(0, 1)) = 0
		_Rim2Brightness ("Brightness--{ condition_showS:_Rim2Style==0}", Range(0, 10)) = 1
		_Rim2Strength ("Rim Emission--{ condition_showS:_Rim2Style==0}", Range(0, 20)) = 0
		_Tweak_Rim2LightMaskLevel ("Tweak_RimLightMaskLevel--{ condition_showS:_Rim2Style==1}", Range(-1, 1)) = 0
		_Is_LightColor_Rim2Light ("Mix Light Color--{ condition_showS:_Rim2Style==1}", Range(0, 1)) = 1
		[HideInInspector] s_end_RimLight1Color ("Color & Brightness", Float) = 0
		
		[HideInInspector] s_start_RimLight1ShapeControls ("Shape Controls--{persistent_expand:true,default_expand:true, condition_showS:_Rim2Style==0||_Rim2Style==1}", Float) = 1
		_Rim2Width ("Width--{ condition_showS:_Rim2Style==0}", Range(0, 1)) = 0.8
		_Rim2Sharpness ("Sharpness--{ condition_showS:_Rim2Style==0}", Range(0, 1)) = .25
		_Rim2Power ("Rim Power--{ condition_showS:_Rim2Style==0}", Range(0, 10)) = 1
		_Is_NormalMapToRim2Light ("Normal Strength", Range(0, 1)) = 1
		[ToggleUI]_Rim2LightingInvert ("Invert Rim Lighting--{ condition_showS:_Rim2Style==0}", Float) = 0
		_Rim2Light_Power ("Rim Power--{ condition_showS:_Rim2Style==1}", Range(0, 1)) = 0.1
		_Rim2Light_InsideMask ("Inside Mask--{ condition_showS:_Rim2Style==1}", Range(0.0001, 1)) = 0.0001
		[Toggle(_)] _Rim2Light_FeatherOff ("Feather Off--{ condition_showS:_Rim2Style==1}", Float) = 0
		[HideInInspector] s_end_RimLight1ShapeControls ("Shape Controls", Float) = 0
		
		[HideInInspector] s_start_RimLight1LightDirMask ("Light Direction Mask--{reference_property:_Rim2ShadowToggle,persistent_expand:true,default_expand:false, condition_showS:_Rim2Style==0}", Float) = 0
		[HideInInspector][ToggleUI] _Rim2ShadowToggle ("Light Direction Mask", Float) = 0
		[Enum(Shadow Map, 0, Custom, 1)]_Rim2ShadowMaskRampType ("Light Falloff Type", Int) = 0
		[ToggleUI]_Rim2ShadowMaskInvert ("Invert Shadow Mask", Float) = 0
		_Rim2ShadowMaskStrength ("Shadow Mask Strength", Range(0, 1)) = 1
		[MultiSlider]_Rim2ShadowAlpha ("Hide In Shadow--{ condition_showS:_Rim2ShadowMaskRampType==1}", Vector) = (0.0, 0.0, 0, 1)
		_Rim2ShadowWidth ("Shrink In Shadow", Range(0, 1)) = 0
		[HideInInspector] s_end_RimLight1LightDirMask ("Light Direction Mask", Float) = 0
		
		// UTS2
		[HideInInspector] s_start_RimLight2DirectionMask ("Light Direction Mask--{persistent_expand:true,default_expand:false, condition_showS:_Rim2Style==1}", Float) = 0
		[HideInInspector][ToggleUI] _LightDirection_MaskOn2 ("Light Direction Mask--{ condition_showS:_Rim2Style==1}", Float) = 0
		_Tweak_LightDirection_MaskLevel2 ("Light Dir Mask Level--{ condition_showS:_Rim2Style==1}", Range(0, 0.5)) = 0
		[ThryToggleUI(true)] _Add_Antipodean_Rim2Light ("<size=13><b>  Antipodean(Ap) Rim</b></size>--{ condition_showS:_Rim2Style==1}", Float) = 0
		_Is_LightColor_Ap_Rim2Light ("Ap Light Color Mix--{ condition_showS:_Add_Antipodean_Rim2Light==1&&_Rim2Style==1}", Range(0, 1)) = 1
		_Ap_Rim2LightColor ("Ap Color--{reference_property:_Rim2ApColorThemeIndex, condition_showS:_Add_Antipodean_Rim2Light==1&&_Rim2Style==1}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _Rim2ApColorThemeIndex ("", Int) = 0
		_Ap_Rim2Light_Power ("Ap Power--{ condition_showS:_Add_Antipodean_Rim2Light==1&&_Rim2Style==1}", Range(0, 1)) = 0.1
		[Toggle(_)] _Ap_Rim2Light_FeatherOff ("Ap Feather Off--{ condition_showS:_Add_Antipodean_Rim2Light==1&&_Rim2Style==1}", Float) = 0
		[HideInInspector] s_end_RimLight2DirectionMask ("Light Direction Mask", Float) = 0
		
		// Liltoon
		[HDR][Gamma]_Rim2Color ("Rim Color--{condition_showS:_Rim2Style==2,reference_property:_Rim2LightColorThemeIndex}", Color) = (0.66, 0.5, 0.48, 1)
		[sRGBWarning(true)] _Rim2ColorTex ("Color / Mask--{condition_showS:_Rim2Style==2,reference_properties:[_Rim2ColorTexPan, _Rim2ColorTexUV]}", 2D) = "white" { }
		[HideInInspector][Vector2] _Rim2ColorTexPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _Rim2ColorTexUV ("UV", Int) = 0
		_Rim2MainStrength ("Main Color Blend--{condition_showS:_Rim2Style==2}", Range(0, 1)) = 0
		_Rim2NormalStrength ("Normal Strength--{condition_showS:_Rim2Style==2}", Range(0, 1)) = 1.0
		_Rim2Border ("Border--{condition_showS:_Rim2Style==2}", Range(0, 1)) = 0.5
		_Rim2Blur ("Blur--{condition_showS:_Rim2Style==2}", Range(0, 1)) = 0.65
		[PowerSlider(3.0)]_Rim2FresnelPower ("Fresnel Power--{condition_showS:_Rim2Style==2}", Range(0.01, 50)) = 3.5
		_Rim2EnableLighting ("Enable Lighting--{condition_showS:_Rim2Style==2}", Range(0, 1)) = 1
		_Rim2ShadowMask ("Shadow Mask--{condition_showS:_Rim2Style==2}", Range(0, 1)) = 0.5
		[ToggleUI]_Rim2BackfaceMask ("Backface Mask--{condition_showS:_Rim2Style==2}", Int) = 1
		_Rim2VRParallaxStrength ("VR Parallax Strength--{condition_showS:_Rim2Style==2}", Range(0, 1)) = 1
		// [ToggleUI]_Rim2ApplyTransparency ("Apply Transparency--{condition_showS:_Rim2Style==2}", Int) = 1
		[ThryWideEnum(Normal, 0, Add, 1, Screen, 2, Multiply, 3)]_Rim2BlendMode ("Blend Mode--{condition_showS:_Rim2Style==2}", Int) = 1
		[HideInInspector] s_start_liltoon_rim2_lightdir ("Light Direction--{persistent_expand:true,default_expand:false, condition_showS:_Rim2Style==2}", Float) = 0
		_Rim2DirStrength ("Light direction strength", Range(0, 1)) = 0
		_Rim2DirRange ("Direction Light Width", Range(-1, 1)) = 0
		_Rim2IndirRange ("Indirection Light Width", Range(-1, 1)) = 0
		[HDR][Gamma]_Rim2IndirColor ("Indirection Color", Color) = (1, 1, 1, 1)
		_Rim2IndirBorder ("Indirection Border", Range(0, 1)) = 0.5
		_Rim2IndirBlur ("Indirection Blur", Range(0, 1)) = 0.1
		[HideInInspector] s_end_liltoon_rim2_lightdir ("", Float) = 0
		
		[HideInInspector] s_start_RimLight1HueShift ("Hue Shift--{reference_property:_Rim2HueShiftEnabled,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI] _Rim2HueShiftEnabled ("Hue Shift", Float) = 0
		_Rim2HueShiftSpeed ("Shift Speed", Float) = 0
		_Rim2HueShift ("Hue Shift", Range(0, 1)) = 0
		[HideInInspector] s_end_RimLight1HueShift ("Hue Shift", Float) = 0
		
		[HideInInspector] s_start_RimLight1GlobalMasking ("Alpha & Global Masking--{persistent_expand:true,default_expand:false}", Float) = 0
		[ThryWideEnum(Off, 0, Add, 1, Multiply, 2)]_Rim2ApplyAlpha ("Intensity to Alpha--{ condition_showS:_Rim2Style==0}", Int) = 0
		_Rim2ApplyAlphaBlend ("Intensity to Alpha Blend--{ condition_showS:_Rim2Style==0}", Range(0, 1)) = 1.0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _Rim2GlobalMask ("Global Mask--{reference_property:_Rim2GlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _Rim2GlobalMaskBlendType ("Blending", Int) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _Rim2ApplyGlobalMaskIndex ("Apply to Global Mask--{reference_property:_Rim2ApplyGlobalMaskBlendType,condition_showS:_Rim2Style==0}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _Rim2ApplyGlobalMaskBlendType ("Blending", Int) = 2
		[HideInInspector] s_end_RimLight1GlobalMasking ("Alpha & Global Masking", Float) = 0
		
		[HideInInspector] m_start_Rim2AudioLink ("Audio Link ♫--{ condition_showS:_EnableAudioLink==1&&_Rim2Style==0}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkRim2WidthBand ("Width Add Band", Int) = 0
		[VectorLabel(Min, Max)] _AudioLinkRim2WidthAdd ("Width Add", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkRim2EmissionBand ("Emission Add Band", Int) = 0
		[VectorLabel(Min, Max)] _AudioLinkRim2EmissionAdd ("Emission Add", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkRim2BrightnessBand ("Brightness Band", Int) = 0
		[VectorLabel(Min, Max)] _AudioLinkRim2BrightnessAdd ("Brightness Add", Vector) = (0, 0, 0, 0)
		[HideInInspector] m_end_Rim2AudioLink ("Audio Link", Float) = 0
		[HideInInspector] m_end_rim2LightOptions ("Rim2 Lighting", Float) = 0
		//endex
		
		//ifex _EnableDepthRimLighting==0
		[HideInInspector] m_start_depthRimLightOptions ("Depth Rim Lighting--{reference_property:_EnableDepthRimLighting,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/shading/depth-rim-lighting},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(_POI_DEPTH_RIMLIGHT)]_EnableDepthRimLighting ("", Float) = 0
		[Enum(vertex, 0, pixel, 1)] _DepthRimNormalToUse ("Normal To Use", Int) = 1
		[ThryWideEnum(Two Samples, 0, Ten Samples, 1)] _DepthRimType ("Rim Type", Int) = 0
		
		[HideInInspector] s_start_FixedRimShapeControl ("Shape Control--{persistent_expand:true,default_expand:true}", Float) = 1
		_DepthRimWidth ("Width", Range(0, 1)) = .2
		_DepthRimSharpness ("Depth", Range(0, 1)) = .2
		[ToggleUI]_DepthRimHideInShadow ("Hide In Shadow", Float) = 0
		[HideInInspector] s_end_FixedRimShapeControl ("Shape Control", Float) = 0
		
		[HideInInspector] s_start_FixedRimColor ("Color--{persistent_expand:true,default_expand:true}", Float) = 1
		_DepthRimMixBaseColor ("Use Base Color", Range(0, 1)) = 0
		_DepthRimMixLightColor ("Light Color Mix", Range(0, 1)) = 0
		_DepthRimColor ("Rim Color--{reference_property:_DepthRimColorThemeIndex}", Color) = (1, 1, 1, 1)
		_DepthRimBrightness ("Color Brightness", Range(0, 10)) = 1
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _DepthRimColorThemeIndex ("", Int) = 0
		_DepthRimEmission ("Emission", Range(0, 20)) = 0
		[HideInInspector] s_end_FixedRimColor ("Color", Float) = 0
		[HideInInspector] s_start_FixedRimBlending ("Blending--{persistent_expand:true,default_expand:true}", Float) = 1
		_DepthRimReplace ("Replace", Range(0, 1)) = 0
		_DepthRimAdd ("Add", Range(0, 1)) = 0
		_DepthRimMultiply ("Multiply", Range(0, 1)) = 0
		_DepthRimAdditiveLighting ("Unlit Add", Range(0, 1)) = 0
		[HideInInspector] s_end_FixedRimBlending ("Blending", Float) = 0
		[HideInInspector] m_end_depthRimLightOptions ("Rim Lighting", Float) = 0
		//endex
		
		//ifex _SubsurfaceScattering==0
		[HideInInspector] m_start_subsurfaceScattering ("Subsurface Scattering--{reference_property:_SubsurfaceScattering}}", Float) = 0
		[HideInInspector][ThryToggle(POI_SUBSURFACESCATTERING)]_SubsurfaceScattering ("Enable", Float) = 0
		
		_SSSColor ("Subsurface Color", Color) = (1, 0, 0, 1)
		[sRGBWarning(true)][ThryRGBAPacker(RGB Color, A Thickness, linear, false)]_SSSThicknessMap ("Color & Thickness--{reference_properties:[_SSSThicknessMapPan, _SSSThicknessMapUV, _SSSThicknessMapChannel]}", 2D) = "white" { }
		[HideInInspector][Vector2]_SSSThicknessMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, DistortedUV1, 4)] _SSSThicknessMapUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)] _SSSThicknessMapChannel ("Channel", Int) = 0
		_SSSThicknessMod ("Thickness mod", Range(-1, 1)) = -1
		_SSSStrength ("Light Strength", Range(0, 1)) = 0.25
		_SSSSpread ("Light Spread", Range(1, 100)) = 5
		_SSSDistortion ("Light Distortion", Range(0, 1)) = 1
		_SSSBaseColorMix ("Base Color Mix", Range(0, 1)) = 0
		
		[HideInInspector] m_end_subsurfaceScattering ("", Float) = 0
		//endex
		
		//ifex _MochieBRDF==0
		[HideInInspector] m_start_brdf ("Reflections & Specular--{reference_property:_MochieBRDF,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/shading/reflections-and-specular},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(MOCHIE_PBR)]_MochieBRDF ("Enable", Float) = 0
		_MochieMetallicMultiplier ("Metallic", Range(0, 1)) = 0
		_MochieRoughnessMultiplier ("Smoothness", Range(0, 1)) = 1
		_MochieReflectionTint ("Reflection Tint--{reference_property:_MochieReflectionTintThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _MochieReflectionTintThemeIndex ("", Int) = 0
		_MochieSpecularTint ("Specular Tint--{reference_property:_MochieSpecularTintThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _MochieSpecularTintThemeIndex ("", Int) = 0
		
		[sRGBWarning][ThryRGBAPacker(R Metallic Map, G Smoothness Map, B Reflection Mask, A Specular Mask, linear, false)]_MochieMetallicMaps ("Packed Maps [Expand]--{reference_properties:[_MochieMetallicMapsPan, _MochieMetallicMapsUV, _MochieMetallicMapsStochastic, _MochieMetallicMapsMetallicChannel, _MochieMetallicMapsRoughnessChannel, _MochieMetallicMapsReflectionMaskChannel, _MochieMetallicMapsSpecularMaskChannel, _MochieMetallicMapInvert, _MochieRoughnessMapInvert, _MochieReflectionMaskInvert, _MochieSpecularMaskInvert]}", 2D) = "white" { }
		[HideInInspector][Vector2]_MochieMetallicMapsPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_MochieMetallicMapsUV ("UV", Int) = 0
		[HideInInspector][ToggleUI]_MochieMetallicMapsStochastic ("Stochastic Sampling", Float) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3, White, 4)]_MochieMetallicMapsMetallicChannel ("Metallic Channel", Float) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3, White, 4)]_MochieMetallicMapsRoughnessChannel ("Smoothness Channel", Float) = 1
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3, White, 4)]_MochieMetallicMapsReflectionMaskChannel ("Reflection Mask Channel", Float) = 2
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3, White, 4)]_MochieMetallicMapsSpecularMaskChannel ("Specular Mask Channel", Float) = 3
		[HideInInspector][ToggleUI]_MochieMetallicMapInvert ("Invert Metallic", Float) = 0
		[HideInInspector][ToggleUI]_MochieRoughnessMapInvert ("Invert Smoothness", Float) = 0
		[HideInInspector][ToggleUI]_MochieReflectionMaskInvert ("Invert Reflection Mask", Float) = 0
		[HideInInspector][ToggleUI]_MochieSpecularMaskInvert ("Invert Specular Mask", Float) = 0
		[Space(10)]
		_MochieReflectionStrength ("Reflection Visibility", Range(0, 1)) = 1
		_MochieSpecularStrength ("Specular Visibility", Range(0, 5)) = 1
		[Space(10)]
		[ThryTexture][NoScaleOffset]_MochieReflCube ("Cubemap", Cube) = "" { }
		[ToggleUI]_MochieForceFallback ("Force Fallback", Int) = 0
		[HideInInspector] s_start_BRDFTPSMaskGroup ("TPS--{condition_showS:(_TPSPenetratorEnabled==1)}", Float) = 0
		[ThryToggleUI(true)] _BRDFTPSDepthEnabled ("<size=13><b>  TPS Depth Enabled</b></size>", Float) = 0
		_BRDFTPSReflectionMaskStrength ("Reflection Mask Strength--{condition_showS:(_BRDFTPSDepthEnabled==1)}", Range(0, 1)) = 1
		_BRDFTPSSpecularMaskStrength ("Specular Mask Strength--{condition_showS:(_BRDFTPSDepthEnabled==1)}", Range(0, 1)) = 1
		[HideInInspector] s_end_BRDFTPSMaskGroup ("", Float) = 0
		
		[HideInInspector] s_start_PBRSecondSpecular ("2nd Specular--{reference_property:_Specular2ndLayer,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_Specular2ndLayer ("2nd Specular", Float) = 0
		_MochieSpecularStrength2 ("Visibility", Range(0, 5)) = 1
		_MochieRoughnessMultiplier2 ("Smoothness", Range(0, 1)) = 1
		[HideInInspector] s_end_PBRSecondSpecular ("Name", Float) = 0
		
		[HideInInspector] s_start_PBRSplitMaskSample ("Split Mask Sampling--{reference_property:_PBRSplitMaskSample,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_PBRSplitMaskSample ("Split Mask Sampling", Float) = 0
		[VectorLabel(tX, tY, oX, oY)]_PBRMaskScaleTiling ("Tiling/Offset", Vector) = (1, 1, 0, 0)
		[ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_MochieMetallicMasksUV ("UV", Int) = 0
		[ToggleUI]_PBRSplitMaskStochastic ("Stochastic Sampling", Float) = 0
		[Vector2]_MochieMetallicMasksPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector] s_end_PBRSplitMaskSample ("Split Mask Sampling", Float) = 0
		
		[HideInInspector] s_start_brdfadvanced ("GSAA & Advanced Controls--{persistent_expand:true,default_expand:false}", Float) = 0
		[ToggleUI]_MochieLitFallback ("Lit Fallback", Float) = 1
		[ToggleUI]_IgnoreCastedShadows ("Ignore Casted Shadows", Float) = 0
		_PBRNormalSelect ("Pixel Normal Mix", Range(0, 1)) = 1
		[PowerSlider(.2)]_RefSpecFresnel ("Fresnel Reflection", Range(0, 1)) = 1
		[PowerSlider(.2)]_RefSpecFresnelBack ("Backface Fresnel Reflection", Range(0, 1)) = 1
		[ThryToggleUI(true)]_MochieGSAAEnabled ("<size=13><b>  GSAA</b></size>", Float) = 1
		_PoiGSAAVariance ("GSAA Variance--{condition_showS:(_MochieGSAAEnabled==1)}", Range(0, 1)) = 0.15
		_PoiGSAAThreshold ("GSAA Threshold--{condition_showS:(_MochieGSAAEnabled==1)}", Range(0, 1)) = 0.1
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _MochieMetallicGlobalMask ("Metallic--{reference_property:_MochieMetallicGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _MochieMetallicGlobalMaskBlendType ("Blending", Int) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _MochieSmoothnessGlobalMask ("Smoothness--{reference_property:_MochieSmoothnessGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _MochieSmoothnessGlobalMaskBlendType ("Blending", Int) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _MochieReflectionStrengthGlobalMask ("Reflection Strength--{reference_property:_MochieReflectionStrengthGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _MochieReflectionStrengthGlobalMaskBlendType ("Blending", Int) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _MochieSpecularStrengthGlobalMask ("Specular Strength--{reference_property:_MochieSpecularStrengthGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _MochieSpecularStrengthGlobalMaskBlendType ("Blending", Int) = 2
		[HideInInspector] s_end_brdfadvanced ("", Float) = 0
		
		[HideInInspector] m_end_brdf ("", Float) = 0
		//endex
		
		//ifex _ClearCoatBRDF==0
		[HideInInspector] m_start_clearCoat ("Clear Coat--{reference_property:_ClearCoatBRDF,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/shading/clear-coat},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(POI_CLEARCOAT)]_ClearCoatBRDF ("Enable", Float) = 0
		_ClearCoatStrength ("ClearCoat Visibility", Range(0, 1)) = 1
		_ClearCoatSmoothness ("Smoothness", Range(0, 1)) = 1
		_ClearCoatReflectionStrength ("Reflections Visibility", Range(0, 1)) = 1
		_ClearCoatSpecularStrength ("Specular Visibility", Range(0, 1)) = 1
		_ClearCoatReflectionTint ("Reflection Tint--{reference_property:_ClearCoatReflectionTintThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _ClearCoatReflectionTintThemeIndex ("", Int) = 0
		_ClearCoatSpecularTint ("Specular Tint--{reference_property:_ClearCoatSpecularTintThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _ClearCoatSpecularTintThemeIndex ("", Int) = 0
		[Space(8)]
		[sRGBWarning][ThryRGBAPacker(ClearCoat Mask, Smoothness Map, Reflection Mask, Specular Mask, linear, false)]_ClearCoatMaps ("Packed Maps [Expand]--{reference_properties:[_ClearCoatMapsPan, _ClearCoatMapsUV, _ClearCoatMapsStochastic, _ClearCoatMapsClearCoatMaskChannel, _ClearCoatMapsRoughnessChannel, _ClearCoatMapsReflectionMaskChannel, _ClearCoatMapsSpecularMaskChannel, _ClearCoatMaskInvert, _ClearCoatSmoothnessMapInvert, _ClearCoatReflectionMaskInvert, _ClearCoatSpecularMaskInvert]}", 2D) = "white" { }
		[HideInInspector][Vector2]_ClearCoatMapsPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_ClearCoatMapsUV ("UV", Int) = 0
		[HideInInspector][ToggleUI]_ClearCoatMapsStochastic ("Stochastic Sampling", Float) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3, White, 4)]_ClearCoatMapsClearCoatMaskChannel ("ClearCoat Mask Channel", Float) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3, White, 4)]_ClearCoatMapsRoughnessChannel ("Smoothness Channel", Float) = 1
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3, White, 4)]_ClearCoatMapsReflectionMaskChannel ("Reflection Mask Channel", Float) = 2
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3, White, 4)]_ClearCoatMapsSpecularMaskChannel ("Specular Mask Channel", Float) = 3
		[HideInInspector][ToggleUI]_ClearCoatMaskInvert ("Invert ClearCoat Mask", Float) = 0
		[HideInInspector][ToggleUI]_ClearCoatSmoothnessMapInvert ("Invert Smoothness", Float) = 0
		[HideInInspector][ToggleUI]_ClearCoatReflectionMaskInvert ("Invert Reflection Mask", Float) = 0
		[HideInInspector][ToggleUI]_ClearCoatSpecularMaskInvert ("Invert Specular Mask", Float) = 0
		[Space(4)]
		[ThryTexture][NoScaleOffset]_ClearCoatFallback ("Fallback Cubemap", Cube) = "" { }
		[ToggleUI]_ClearCoatForceFallback ("Force Fallback", Int) = 0
		
		[HideInInspector] m_start_clearcoatadvanced ("Advanced", Float) = 0
		[ToggleUI]_ClearCoatLitFallback ("Lit Fallback", Float) = 1
		[ToggleUI]_CCIgnoreCastedShadows ("Ignore Casted Shadows", Float) = 0
		_ClearCoatNormalSelect ("Pixel Normal Mix", Range(0, 1)) = 0
		[PowerSlider(.2)]_ClearcoatFresnel ("Fresnel Reflection", Range(0, 1)) = 1
		[ThryToggleUI(true)]_ClearCoatGSAAEnabled ("<size=13><b>  GSAA</b></size>", Float) = 1
		_ClearCoatGSAAVariance ("GSAA Variance", Range(0, 1)) = 0.15
		_ClearCoatGSAAThreshold ("GSAA Threshold", Range(0, 1)) = 0.1
		
		[HideInInspector] s_start_ClearCoatTPSMaskGroup ("TPS Mask--{reference_property:_ClearCoatTPSDepthMaskEnabled, persistent_expand:true,default_expand:false,condition_showS:(_TPSPenetratorEnabled==1)}", Float) = 0
		[HideInInspector][ToggleUI] _ClearCoatTPSDepthMaskEnabled ("TPS Depth Enabled", Float) = 0
		_ClearCoatTPSMaskStrength ("Mask Strength}", Range(0, 1)) = 1
		[HideInInspector] s_end_ClearCoatTPSMaskGroup ("", Float) = 0
		
		[HideInInspector] m_end_clearcoatadvanced ("", Float) = 0
		
		[HideInInspector] m_start_clearcoatglobalmask ("Global Mask", Float) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _ClearCoatGlobalMask ("ClearCoat--{reference_property:_ClearCoatGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _ClearCoatGlobalMaskBlendType ("Blending", Int) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _ClearCoatSmoothnessGlobalMask ("Smoothness--{reference_property:_ClearCoatSmoothnessGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _ClearCoatSmoothnessGlobalMaskBlendType ("Blending", Int) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _ClearCoatReflectionStrengthGlobalMask ("Reflection Strength--{reference_property:_ClearCoatReflectionStrengthGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _ClearCoatReflectionStrengthGlobalMaskBlendType ("Blending", Int) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _ClearCoatSpecularStrengthGlobalMask ("Specular Strength--{reference_property:_ClearCoatSpecularStrengthGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _ClearCoatSpecularStrengthGlobalMaskBlendType ("Blending", Int) = 2
		[HideInInspector] m_end_clearcoatglobalmask ("", Float) = 0
		
		[HideInInspector] m_end_clearCoat ("", Float) = 0
		//endex
		
		//ifex _EnableEnvironmentalRim==0
		[HideInInspector] m_start_reflectionRim ("Environmental Rim--{reference_property:_EnableEnvironmentalRim,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/shading/environmental-rim},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(POI_ENVIRORIM)]_EnableEnvironmentalRim ("Enable", Float) = 0
		[sRGBWarning]_RimEnviroMask ("Mask--{reference_properties:[_RimEnviroMaskPan, _RimEnviroMaskUV, _RimEnviroChannel]}", 2D) = "white" { }
		[HideInInspector][Vector2]_RimEnviroMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_RimEnviroMaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_RimEnviroChannel ("Channel", Float) = 0
		_RimEnviroBlur ("Blur", Range(0, 1)) = 0.7
		_RimEnviroWidth ("Rim Width", Range(0, 1)) = 0.45
		_RimEnviroSharpness ("Rim Sharpness", Range(0, 1)) = 0
		_RimEnviroMinBrightness ("Min Brightness Threshold", Range(0, 2)) = 0
		_RimEnviroIntensity ("Intensity", Range(0, 1)) = 1
		[HideInInspector] m_end_reflectionRim ("", Float) = 0
		//endex
		
		//ifex _StylizedSpecular==0
		[HideInInspector] m_start_stylizedSpec (" Stylized Specular--{reference_property:_StylizedSpecular,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/shading/stylized-specular},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(POI_STYLIZED_StylizedSpecular)]_StylizedSpecular ("Enable", Float) = 0
		
		[sRGBWarning(true)][ThryTexture]_HighColor_Tex ("Specular Map--{reference_properties:[_HighColor_TexPan, _HighColor_TexUV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_HighColor_TexPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_HighColor_TexUV ("UV", Int) = 0
		_HighColor ("Tint--{reference_property:_HighColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _HighColorThemeIndex ("", Int) = 0
		[sRGBWarning]_Set_HighColorMask ("Mask--{reference_properties:[_Set_HighColorMaskPan, _Set_HighColorMaskUV, _Set_HighColorMaskChannel, _Tweak_HighColorMaskLevel]}", 2D) = "white" { }
		[HideInInspector][Vector2]_Set_HighColorMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_Set_HighColorMaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_Set_HighColorMaskChannel ("Channel", Float) = 1
		[HideInInspector]_Tweak_HighColorMaskLevel ("Mask Level", Range(-1, 1)) = 0
		[ThryWideEnum(Toon, 0, Realistic, 1)]_Is_SpecularToHighColor ("Specular Mode", Float) = 0
		[ThryWideEnum(Replace, 0, Add, 1, Screen, 2, Multiply, 3)]_Is_BlendAddToHiColor ("Color Blend Mode", Int) = 0
		_StylizedSpecularStrength ("Strength", Float) = 1
		[ToggleUI] _UseLightColor ("Use Light Color", Float) = 1
		
		[HideInInspector] s_start_StylizedSpecularLayer0 ("Layer 1--{persistent_expand:true,default_expand:true}", Float) = 1
		_HighColor_Power ("Size", Range(0, 1)) = 0.2
		_StylizedSpecularFeather ("Feather--{condition_showS:(_Is_SpecularToHighColor==0)}", Range(0, 1)) = 0
		_Layer1Strength ("Strength", Range(0, 1)) = 1
		[HideInInspector] s_end_StylizedSpecularLayer0 ("Layer 1", Float) = 0
		
		[HideInInspector] s_start_StylizedSpecularLayer1 ("Layer 2--{persistent_expand:true,default_expand:true}", Float) = 1
		_Layer2Size ("Size", Range(0, 1)) = 0
		_StylizedSpecular2Feather ("Feather--{condition_showS:(_Is_SpecularToHighColor==0)}", Range(0, 1)) = 0
		_Layer2Strength ("Strength", Range(0, 1)) = 0
		[HideInInspector] s_end_StylizedSpecularLayer1 ("Layer 2", Float) = 0
		
		[HideInInspector] s_start_StylizedSpecularAdvanced ("Advanced--{persistent_expand:true,default_expand:false}", Float) = 0
		[ToggleUI] _StylizedSpecularIgnoreNormal ("Ignore Normal", Float) = 0
		[ToggleUI] _StylizedSpecularIgnoreShadow ("Ignore Shadow", Float) = 0
		[ToggleUI]_SSIgnoreCastedShadows ("Ignore Casted Shadows", Float) = 0
		[HideInInspector] s_end_StylizedSpecularAdvanced ("Advanced", Float) = 0
		[HideInInspector] m_end_stylizedSpec ("", Float) = 0
		//endex
		
		//ifex _BacklightEnabled!=1
		[HideInInspector] m_start_backlight ("Backlight--{reference_property:_BacklightEnabled}", Float) = 0
		[HideInInspector][ThryToggle(POI_BACKLIGHT)]_BacklightEnabled ("Backlight Enabled", Float) = 0
		[HDR][Gamma] _BacklightColor ("Color", Color) = (0.85, 0.8, 0.7, 1.0)
		[sRGBWarning(true)] _BacklightColorTex ("Texture--{reference_properties:[_BacklightColorTexPan, _BacklightColorTexUV]}", 2D) = "white" { }
		[HideInInspector][Vector2] _BacklightColorTexPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _BacklightColorTexUV ("UV", Int) = 0
		_BacklightMainStrength ("Main Color Blend", Range(0, 1)) = 0
		_BacklightNormalStrength ("Normal Strength", Range(0, 1)) = 1.0
		_BacklightBorder ("Border", Range(0, 1)) = 0.35
		_BacklightBlur ("Blur", Range(0, 1)) = 0.05
		_BacklightDirectivity ("Directivity", Float) = 5.0
		_BacklightViewStrength ("View direction strength", Range(0, 1)) = 1
		[ToggleUI] _BacklightReceiveShadow ("Receive Shadow", Int) = 1
		[ToggleUI] _BacklightBackfaceMask ("Backface Mask", Int) = 1
		[HideInInspector] m_end_backlight ("Backlight", Float) = 0
		//endex
		
		//ifex _LTCGIEnabled!=1
		[HideInInspector] m_start_LTCGI ("LTCGI (REWORK SOON)--{reference_property:_LTCGIEnabled}", Float) = 0
		[HideInInspector] [ThryToggle(POI_LTCGI)]_LTCGIEnabled ("LTCGI Enabled", Float) = 0
		[Helpbox(1)] _LTCGI_Attribution ("This section uses LTCGI by _pi_, click for 'github.com/pimaker/ltcgi'--{onClick:{type:URL,data:https://github.com/pimaker/ltcgi}}", Float) = 0
		[ToggleUI] _LTCGI_AnimToggle ("Anim Toggle", Int) = 1
		_LTCGI_DiffuseColor ("Diffuse Tint--{reference_property:_LTCGI_DiffuseColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _LTCGI_DiffuseColorThemeIndex ("", Int) = 0
		_LTCGI_SpecularColor ("Specular Tint--{reference_property:_LTCGI_SpecularColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _LTCGI_SpecularColorThemeIndex ("", Int) = 0
		[ToggleUI] _LTCGI_UsePBR ("Use Reflection and Specular's Settings", Int) = 1
		_LTCGI_Smoothness ("Smoothness--{condition_showS:(_LTCGI_UsePBR==0 || _MochieBRDF==0)}", Range(0, 1)) = 0.0
		_LTCGI_Metallic ("Metallic--{condition_showS:(_LTCGI_UsePBR==0 || _MochieBRDF==0)}", Range(0, 1)) = 0.0
		[HideInInspector] m_end_LTCGI ("LTCGI", Float) = 0
		//endex
		
		[HideInInspector] m_OutlineCategory (" Outlines--{reference_property:_EnableOutlines,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/outlines/main},hover:Documentation}}", Float) = 0
		//ifex _EnableOutlines!=1
		// Outline Vertex
		[HideInInspector][ToggleUI]_EnableOutlines ("Enable Outlines", float) = 0
		[Enum(Basic, 1, Rim Light, 2, Directional, 3, DropShadow, 4)]_OutlineExpansionMode ("Mode", Int) = 1
		[Enum(Local, 0, World, 1)]_OutlineSpace ("Space", Int) = 0
		
		_LineWidth ("Outline Size", Float) = 1
		[sRGBWarning]_OutlineMask ("Outline Size Mask--{reference_properties:[_OutlineMaskPan, _OutlineMaskUV, _OutlineMaskChannel]}", 2D) = "white" { }
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _LineColorThemeIndex ("", Int) = 0
		[HideInInspector][Vector2]_OutlineMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)] _OutlineMaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_OutlineMaskChannel ("Channel", Float) = 0
		
		[sRGBWarning(true)]_OutlineTexture ("Outline Texture--{reference_properties:[_OutlineTexturePan, _OutlineTextureUV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_OutlineTexturePan ("Outline Texture Pan", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _OutlineTextureUV ("UV", Int) = 0
		_LineColor ("Color--{reference_property:_LineColorThemeIndex}", Color) = (1, 1, 1, 1)
		_OutlineRimLightBlend ("Rim Light Blend--{condition_show:{type:PROPERTY_BOOL,data:_OutlineExpansionMode==2}}", Range(0, 1)) = 0
		[Vector2]_OutlinePersonaDirection ("Directional Offset--{condition_show:{type:PROPERTY_BOOL,data:_OutlineExpansionMode==3}}", Vector) = (1, 0, 0, 0)
		[Vector3]_OutlineDropShadowOffset ("Drop Direction--{condition_show:{type:PROPERTY_BOOL,data:_OutlineExpansionMode==4}}", Vector) = (1, 0, 0, 0)
		_OutlineEmission ("Outline Emission", Range(0, 20)) = 0
		_OutlineTintMix ("MainTex blend", Range(0, 1)) = 0
		[ToggleUI]_PoiUTSStyleOutlineBlend ("UTS2 style Blend", Float) = 0
		
		[HideInInspector] s_start_OutlineColorAdjust ("Color Adjust--{reference_property:_OutlineHueShift,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ThryToggleUI(true)]_OutlineHueShift ("Color Adjust", Float) = 0
		[VectorToSliders(Hue, 0, 1, Saturation, 0, 2, Value, 0, 2, Gamma, 0.01, 2)]_OutlineTexHSVG ("HSVG", Vector) = (0, 1, 1, 1)
		_OutlineHueOffsetSpeed ("Shift Speed", Float) = 0
		[HideInInspector] s_end_OutlineColorAdjust ("Color Adjust", Float) = 0
		
		[HideInInspector] s_start_OutlineAlphaDistanceFade ("Distance Alpha--{reference_property:_OutlineAlphaDistanceFade,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _OutlineAlphaDistanceFade ("Distance Alpha", Float) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _OutlineAlphaDistanceFadeType ("Pos To Use", Int) = 1
		_OutlineAlphaDistanceFadeMinAlpha ("Min Distance Alpha", Range(0, 1)) = 0
		_OutlineAlphaDistanceFadeMaxAlpha ("Max Distance Alpha", Range(0, 1)) = 1
		_OutlineAlphaDistanceFadeMin ("Min Distance", Float) = 0
		_OutlineAlphaDistanceFadeMax ("Max Distance", Float) = 0
		[HideInInspector] s_end_OutlineAlphaDistanceFade ("Distance Alpha", Float) = 0
		
		[HideInInspector] s_start_OutlineFixedSize ("Fixed Size Over Distance--{reference_property:_OutlineFixedSize,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ThryToggleUI(true)]_OutlineFixedSize ("Fixed Size", Float) = 1
		_OutlineFixWidth ("Fixed Width ", Range(0, 1)) = .5
		_OutlinesMaxDistance ("Fixed Size Max Distance", Float) = 1
		[HideInInspector] s_end_OutlineFixedSize ("Color Adjust", Float) = 0
		
		[HideInInspector] s_start_OutlineLighting ("Lighting--{reference_property:_OutlineLit,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_OutlineLit ("Enable Lighting", Float) = 1
		_OutlineShadowStrength ("Shadow Strength", Range(0, 1)) = 0
		[HideInInspector] s_end_OutlineLighting ("Lighting", Float) = 0
		
		[HideInInspector] s_start_VertexColors ("Vertex Colors--{persistent_expand:true,default_expand:false}", Float) = 0
		[ToggleUI]_OutlineUseVertexColorNormals ("Vertex Color Normals", Float) = 0
		[Enum(Off, 0, R, 1, G, 2, B, 3, A, 4)]_OutlineVertexColorMask ("Vertex Color Mask", Float) = 0
		_OutlineVertexColorMaskStrength ("VC Mask Strength--{condition_showS:(_OutlineVertexColorMask!=0)}", Range(0, 1)) = 1
		[HideInInspector] s_end_VertexColors ("Vertex Colors", Float) = 0
		
		[HideInInspector] s_start_OutlineRenderingOptions ("Rendering Options--{persistent_expand:true,default_expand:false}", Float) = 0
		[ToggleUI]_OutlineClipAtZeroWidth ("Clip 0 Width", Float) = 0
		[ToggleUI]_OutlineOverrideAlpha ("Override Base Alpha", Float) = 0
		_Offset_Z ("Cam Z Offset", Float) = 0
		[Enum(UnityEngine.Rendering.CullMode)] _OutlineCull ("Cull", Float) = 1
		[Enum(UnityEngine.Rendering.CompareFunction)] _OutlineZTest ("ZTest", Float) = 4
		[HideInInspector] s_end_OutlineRenderingOptions ("Rendering Options", Float) = 0
		
		[HideInInspector] m_start_OutlineAudioLink ("Audio Link ♫--{ condition_showS:_EnableAudioLink==1}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkOutlineSizeBand ("Size Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkOutlineSize ("Size Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkOutlineEmissionBand ("Emission Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkOutlineEmission ("Emission Mod", Vector) = (0, 0, 0, 0)
		
		[HideInInspector] s_start_outline_al_color ("Color--{reference_property:_OutlineALColorEnabled,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_OutlineALColorEnabled ("Enable", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkOutlineColorBand ("Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkOutlineColorMod ("Replace", Vector) = (0, 1, 0, 0)
		_AudioLinkOutlineColor ("Color", Color) = (1, 1, 1, 1)
		[HideInInspector] s_end_outline_al_color ("Color--{draw_border:true}", Float) = 0
		
		[HideInInspector] m_end_OutlineAudioLink ("Audio Link", Float) = 0
		//endex
		
		[HideInInspector] m_specialFXCategory ("Special FX", Float) = 0
		//ifex _EnableUDIMDiscardOptions==0
		// SPECIALFX_PROPERTIES
		// UDIM Discard
		[HideInInspector] m_start_udimdiscardOptions ("UV Tile Discard--{reference_property:_EnableUDIMDiscardOptions,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/special-fx/udim-discard},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(POI_UDIMDISCARD)]_EnableUDIMDiscardOptions ("Enable UDIM Discard Options", Float) = 0
		[Helpbox(1)]_UDIMDiscardHelpbox ("UV Tile Discard requires special model setup. Place object UVs on different UV Tiles.", Int) = 0
		[ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)]_UDIMDiscardUV ("Discard UV", Int) = 0
		[Enum(Vertex (Faster), 0, Pixel (Slower), 1)] _UDIMDiscardMode ("Discard Mode", Int) = 0
		
		[ThryMultiFloats(true, _UDIMDiscardRow3_1, _UDIMDiscardRow3_2, _UDIMDiscardRow3_3)] _UDIMDiscardRow3_0("v = 3", Float) = 0
		[HideInInspector] _UDIMDiscardRow3_1("", Float) = 0
		[HideInInspector] _UDIMDiscardRow3_2("", Float) = 0
		[HideInInspector] _UDIMDiscardRow3_3("", Float) = 0
		
		[ThryMultiFloats(true, _UDIMDiscardRow2_1, _UDIMDiscardRow2_2, _UDIMDiscardRow2_3)] _UDIMDiscardRow2_0("v = 2", Float) = 0
		[HideInInspector] _UDIMDiscardRow2_1("", Float) = 0
		[HideInInspector] _UDIMDiscardRow2_2("", Float) = 0
		[HideInInspector] _UDIMDiscardRow2_3("", Float) = 0
		
		[ThryMultiFloats(true, _UDIMDiscardRow1_1, _UDIMDiscardRow1_2, _UDIMDiscardRow1_3)] _UDIMDiscardRow1_0("v = 1", Float) = 0
		[HideInInspector] _UDIMDiscardRow1_1("", Float) = 0
		[HideInInspector] _UDIMDiscardRow1_2("", Float) = 0
		[HideInInspector] _UDIMDiscardRow1_3("", Float) = 0
		
		[ThryMultiFloats(true, _UDIMDiscardRow0_1, _UDIMDiscardRow0_2, _UDIMDiscardRow0_3)] _UDIMDiscardRow0_0("v = 0", Float) = 0
		[HideInInspector] _UDIMDiscardRow0_1("", Float) = 0
		[HideInInspector] _UDIMDiscardRow0_2("", Float) = 0
		[HideInInspector] _UDIMDiscardRow0_3("", Float) = 0
		
		[HideInInspector] m_end_udimdiscardOptions ("UV Tile Discard", Float) = 0
		//endex
		
		//ifex _EnableDepthBulge==0
		[HideInInspector] m_start_DepthBulge ("Depth Bulge--{reference_property:_EnableDepthBulge}", Float) = 0
		[HideInInspector][ThryToggle(POI_DEPTHBULGE)] _EnableDepthBulge ("Bulge", Float) = 0
		[Helpbox(1)]_DepthBulgeWarning ("Depth Bulge doesn't write to depth, which can break certain transparent effects like custom fog and raymarching", Int) = 0
		_DepthBulgeMask ("Bulge Mask--{reference_properties:[_DepthBulgeMaskUV, _DepthBulgeMaskChannel]}", 2D) = "white" { }
		[HideInInspector][Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)] _DepthBulgeMaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)] _DepthBulgeMaskChannel ("Channel", Float) = 0
		_DepthBulgeFadeLength ("Touch Distance", Range(0, 1.0)) = 0.02
		_DepthBulgeHeight ("Bulge Height", Range(-0.2, 0.2)) = 0.02
		[HideInInspector] m_end_DepthBulge ("Depth Bulge", Float) = 0
		//endex
		
		//ifex _EnableDissolve==0
		[HideInInspector] m_start_dissolve ("Dissolve--{reference_property:_EnableDissolve,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/special-fx/dissolve},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(DISTORT)]_EnableDissolve ("Enable Dissolve", Float) = 0
		[Enum(Basic, 1, Point2Point, 2, Spherical, 3, CenterOut, 4)] _DissolveType ("Dissolve Type", Int) = 1
		_DissolveEdgeWidth ("Edge Width--{condition_show:_DissolveType!=2}", Range(0, .5)) = 0.025
		_DissolveEdgeHardness ("Edge Hardness", Range(0, 1)) = 0.5
		_DissolveEdgeColor ("Edge Color--{reference_property:_DissolveEdgeColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _DissolveEdgeColorThemeIndex ("", Int) = 0
		[sRGBWarning][Gradient]_DissolveEdgeGradient ("Edge Gradient", 2D) = "white" { }
		_DissolveEdgeEmission ("Edge Emission", Range(0, 20)) = 0
		_DissolveTextureColor ("Dissolved Color--{reference_property:_DissolveTextureColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _DissolveTextureColorThemeIndex ("", Int) = 0
		[sRGBWarning(true)]_DissolveToTexture ("Dissolved Texture--{reference_properties:[_DissolveToTexturePan, _DissolveToTextureUV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_DissolveToTexturePan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _DissolveToTextureUV ("UV", Int) = 0
		_DissolveToEmissionStrength ("Dissolved Emission Strength", Range(0, 20)) = 0
		[sRGBWarning]_DissolveNoiseTexture ("Dissolve Gradient--{condition_show:_DissolveType==1,reference_properties:[_DissolveNoiseTexturePan, _DissolveNoiseTextureUV, _DissolveInvertNoise]}", 2D) = "white" { }
		[HideInInspector][Vector2]_DissolveNoiseTexturePan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _DissolveNoiseTextureUV ("UV", Int) = 0
		[HideInInspector][ToggleUI]_DissolveInvertNoise ("Invert", Float) = 0
		[sRGBWarning]_DissolveDetailNoise ("Dissolve Noise--{reference_properties:[_DissolveDetailNoisePan, _DissolveDetailNoiseUV, _DissolveInvertDetailNoise]}", 2D) = "black" { }
		[HideInInspector][Vector2]_DissolveDetailNoisePan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _DissolveDetailNoiseUV ("UV", Int) = 0
		[HideInInspector][ToggleUI]_DissolveInvertDetailNoise ("Invert", Float) = 0
		_DissolveDetailEdgeSmoothing ("Detail Noise Smoothing", Range(0, 1)) = 0
		_DissolveDetailStrength ("Dissolve Detail Strength", Range(0, 1)) = 0.1
		_DissolveAlpha ("Dissolve Alpha", Range(0, 1)) = 0
		[sRGBWarning]_DissolveMask ("Dissolve Mask--{reference_properties:[_DissolveMaskPan, _DissolveMaskUV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_DissolveMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _DissolveMaskUV ("UV", Int) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _DissolveMaskGlobalMask ("Global Mask--{reference_property:_DissolveMaskGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_DissolveMaskGlobalMaskBlendType ("Blending", Int) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _DissolveApplyGlobalMaskIndex ("Dissolved to Global Mask--{reference_property:_DissolveApplyGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _DissolveApplyGlobalMaskBlendType ("Blending", Int) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _DissolveInverseApplyGlobalMaskIndex ("Undissolved to Global Mask--{reference_property:_DissolveInverseApplyGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _DissolveInverseApplyGlobalMaskBlendType ("Blending", Int) = 0
		[Enum(Off, 0, Red, 1, Green, 2, Blue, 3, Alpha, 4)]_DissolveUseVertexColors ("VertexColor Mask", Int) = 0
		[HideInInspector][ToggleUI]_DissolveMaskInvert ("Invert", Float) = 0
		_ContinuousDissolve ("Continuous Dissolve Speed", Float) = 0
		
		[Space(10)]
		[ThryToggleUI(true)] _EnableDissolveAudioLink ("<size=13><b>  Audio Link</b></size>--{ condition_showS:_EnableAudioLink==1}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDissolveAlphaBand ("Dissolve Alpha Band--{ condition_showS:(_EnableDissolveAudioLink==1 && _EnableAudioLink==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDissolveAlpha ("Dissolve Alpha Mod--{ condition_showS:(_EnableDissolveAudioLink==1 && _EnableAudioLink==1)}", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkDissolveDetailBand ("Dissolve Detail Band--{ condition_showS:(_EnableDissolveAudioLink==1 && _EnableAudioLink==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkDissolveDetail ("Dissolve Detail Mod--{ condition_showS:(_EnableDissolveAudioLink==1 && _EnableAudioLink==1)}", Vector) = (0, 0, 0, 0)
		
		// Spherical Dissolve
		[HideInInspector] m_start_SphericalDissolve ("Spherical--{condition_showS:(_DissolveType==3)}", Float) = 0
		[Vector3] 	_SphericalDissolveCenter ("Center Point", Vector) = (0, 0, 0)
		_SphericalDissolveRadius ("Radius", Float) = 1.5
		[ToggleUI] 	_SphericalDissolveInvert ("Invert", Float) = 0
		[ToggleUI] 	_SphericalDissolveClamp ("Clamp Dissolve", Float) = 0
		[HideInInspector] m_end_SphericalDissolve ("Spherical", Float) = 0
		
		// Point to Point Dissolve
		[HideInInspector] m_start_pointToPoint ("Point to Point--{condition_showS:(_DissolveType==2)}", Float) = 0
		[Enum(Local, 0, World, 1, Vertex Colors, 2)] _DissolveP2PWorldLocal ("World/Local", Int) = 0
		_DissolveP2PEdgeLength ("Edge Length", Float) = 0.1
		[Vector3]_DissolveStartPoint ("Start Point", Vector) = (0, -1, 0, 0)
		[Vector3]_DissolveEndPoint ("End Point", Vector) = (0, 1, 0, 0)
		[ToggleUI]_DissolveP2PClamp ("Clamp Dissolve", Float) = 0
		[HideInInspector] m_end_pointToPoint ("Point To Point", Float) = 0
		
		// CenterOut Dissolve
		[HideInInspector] m_start_CenterOutDissolve ("CenterOut--{condition_showS:(_DissolveType==4)}", Float) = 0
		[Enum(View Direction, 1, Custom Direction, 2, Light Direction, 3)] 	_CenterOutDissolveMode ("CenterOut Mode", Int) = 1
		[Vector3] 	_CenterOutDissolveDirection ("Custom Direction--{condition_showS:(_CenterOutDissolveMode==2)}", Vector) = (0, 0, 1, 0)
		[ToggleUI] 	_CenterOutDissolveInvert ("Invert", Float) = 0
		_CenterOutDissolveNormals ("Use Pixel Normals", Range(0, 1)) = 0
		_CenterOutDissolvePower ("Power", Range(.1, 5)) = 1
		[HideInInspector] m_end_CenterOutDissolve ("CenterOut", Float) = 0
		
		[HideInInspector] m_start_dissolveHueShift ("Hue Shift--{reference_property:_DissolveHueShiftEnabled}", Float) = 0
		[HideInInspector][ToggleUI]_DissolveHueShiftEnabled ("Dissolved Enabled", Float) = 0
		_DissolveHueShiftSpeed ("Dissolved Speed", Float) = 0
		_DissolveHueShift ("Dissolved Shift", Range(0, 1)) = 0
		[ToggleUI]_DissolveEdgeHueShiftEnabled ("Edge Enabled", Float) = 0
		_DissolveEdgeHueShiftSpeed ("Edge Speed", Float) = 0
		_DissolveEdgeHueShift ("Edge Shift", Range(0, 1)) = 0
		[HideInInspector] m_end_dissolveHueShift ("Hue Shift", Float) = 0
		
		[HideInInspector] m_start_UVTileDissolve ("UV Tile Dissolve--{reference_property:_UVTileDissolveEnabled}", Float) = 0
		[HideInInspector][ToggleUI]_UVTileDissolveEnabled ("Enabled", Float) = 0
		[ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)]_UVTileDissolveUV ("UV Tile UV", Int) = 0
		[ToggleUI]_UVTileDissolveDiscardAtMax ("Discard Tiles at Max", Float) = 1
		[HideInInspector] m_start_UVTileDissolveRow3 ("Row 3 Alpha", Float) = 0
		_UVTileDissolveAlpha_Row3_0 ("Row 3 Column 0", Range(-1, 1)) = 0
		_UVTileDissolveAlpha_Row3_1 ("Row 3 Column 1", Range(-1, 1)) = 0
		_UVTileDissolveAlpha_Row3_2 ("Row 3 Column 2", Range(-1, 1)) = 0
		_UVTileDissolveAlpha_Row3_3 ("Row 3 Column 3", Range(-1, 1)) = 0
		[HideInInspector] m_end_UVTileDissolveRow3 ("Row 3", Float) = 0
		
		[HideInInspector] m_start_UVTileDissolveRow2 ("Row 2 Alpha", Float) = 0
		_UVTileDissolveAlpha_Row2_0 ("Row 2 Column 0", Range(-1, 1)) = 0
		_UVTileDissolveAlpha_Row2_1 ("Row 2 Column 1", Range(-1, 1)) = 0
		_UVTileDissolveAlpha_Row2_2 ("Row 2 Column 2", Range(-1, 1)) = 0
		_UVTileDissolveAlpha_Row2_3 ("Row 2 Column 3", Range(-1, 1)) = 0
		[HideInInspector] m_end_UVTileDissolveRow2 ("Row 2", Float) = 0
		
		[HideInInspector] m_start_UVTileDissolveRow1 ("Row 1 Alpha", Float) = 0
		_UVTileDissolveAlpha_Row1_0 ("Row 1 Column 0", Range(-1, 1)) = 0
		_UVTileDissolveAlpha_Row1_1 ("Row 1 Column 1", Range(-1, 1)) = 0
		_UVTileDissolveAlpha_Row1_2 ("Row 1 Column 2", Range(-1, 1)) = 0
		_UVTileDissolveAlpha_Row1_3 ("Row 1 Column 3", Range(-1, 1)) = 0
		[HideInInspector] m_end_UVTileDissolveRow1 ("Row 1", Float) = 0
		
		[HideInInspector] m_start_UVTileDissolveRow0 ("Row 0 Alpha", Float) = 0
		_UVTileDissolveAlpha_Row0_0 ("Row 0 Column 0", Range(-1, 1)) = 0
		_UVTileDissolveAlpha_Row0_1 ("Row 0 Column 1", Range(-1, 1)) = 0
		_UVTileDissolveAlpha_Row0_2 ("Row 0 Column 2", Range(-1, 1)) = 0
		_UVTileDissolveAlpha_Row0_3 ("Row 0 Column 3", Range(-1, 1)) = 0
		[HideInInspector] m_end_UVTileDissolveRow0 ("Row 0", Float) = 0
		[HideInInspector] m_end_UVTileDissolve ("UV Tile Dissolve", Float) = 0
		
		// Locked in anim sldiers
		[HideInInspector] m_start_BonusSliders ("Locked In Anim Sliders", Float) = 0
		_DissolveAlpha0 ("Dissolve Alpha 0", Range(-1, 1)) = 0
		_DissolveAlpha1 ("Dissolve Alpha 1", Range(-1, 1)) = 0
		_DissolveAlpha2 ("Dissolve Alpha 2", Range(-1, 1)) = 0
		_DissolveAlpha3 ("Dissolve Alpha 3", Range(-1, 1)) = 0
		_DissolveAlpha4 ("Dissolve Alpha 4", Range(-1, 1)) = 0
		_DissolveAlpha5 ("Dissolve Alpha 5", Range(-1, 1)) = 0
		_DissolveAlpha6 ("Dissolve Alpha 6", Range(-1, 1)) = 0
		_DissolveAlpha7 ("Dissolve Alpha 7", Range(-1, 1)) = 0
		_DissolveAlpha8 ("Dissolve Alpha 8", Range(-1, 1)) = 0
		_DissolveAlpha9 ("Dissolve Alpha 9", Range(-1, 1)) = 0
		[HideInInspector] m_end_BonusSliders ("Locked In Sliders", Float) = 0
		[HideInInspector] m_end_dissolve ("Dissolve", Float) = 0
		//endex
		
		//ifex _EnableFlipbook==0
		[HideInInspector] m_start_flipBook ("Flipbook--{reference_property:_EnableFlipbook,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/special-fx/flipbook},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(_SUNDISK_HIGH_QUALITY)]_EnableFlipbook ("Enable Flipbook", Float) = 0
		
		_FlipbookColor ("Color & alpha--{reference_property:_FlipbookColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _FlipbookColorThemeIndex ("", Int) = 0
		[TextureArray]_FlipbookTexArray ("Texture Array--{reference_properties:[_FlipbookTexArrayPan, _FlipbookTexArrayUV, _FlipbookTiled, _FlipbookColorReplaces]}", 2DArray) = "" { }
		[HideInInspector][Vector2]_FlipbookTexArrayPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _FlipbookTexArrayUV ("UV", Int) = 0
		[HideInInspector][ToggleUI]_FlipbookTiled ("Tiled", Float) = 0
		[HideInInspector][ToggleUI]_FlipbookColorReplaces ("Flipbook as Color Mask", Float) = 0
		[sRGBWarning]_FlipbookMask ("Mask--{reference_properties:[_FlipbookMaskPan, _FlipbookMaskUV, _FlipbookMaskChannel, _FlipbookMaskGlobalMask]}", 2D) = "white" { }
		[HideInInspector][Vector2]_FlipbookMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _FlipbookMaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_FlipbookMaskChannel ("Channel", Float) = 0
		[HideInInspector][ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _FlipbookMaskGlobalMask (" Global Mask--{reference_property:_FlipbookMaskGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6 , Replace, 0)]_FlipbookMaskGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		[ThryWideEnum(Replace, 0, Darken, 1, Multiply, 2, Lighten, 5, Screen, 6, Subtract, 7, Add, 8, Overlay, 9, Mixed, 20)]_FlipbookBlendType ("Blending", Range(0, 1)) = 0
		_FlipbookReplace ("Replace", Range(0, 1)) = 1
		_FlipbookEmissionStrength ("Emission Strength", Range(0, 20)) = 0
		_FlipbookFPS ("FPS", Float) = 30.0
		_FlipbookFrameOffset("Frame Offset", Float) = 0
		
		[HideInInspector] s_start_Positioning ("Positioning--{persistent_expand:true,default_expand:true}", Float) = 1
		[VectorLabel(sX, sY, oX, oY)]_FlipbookScaleOffset ("Scale | Offset", Vector) = (1, 1, 0, 0)
		[VectorLabel(L, R, D, U)]_FlipbookSideOffset ("Side Offset", Vector) = (0, 0, 0, 0)
		_FlipbookRotation ("Rotation", Range(0, 360)) = 0
		_FlipbookRotationSpeed ("Rotation Speed", Float) = 0
		[HideInInspector] s_end_Positioning ("", Float) = 0
		
		[HideInInspector] s_start_FlipbookManualFrameControl ("Manual Frame Control--{reference_property:_FlipbookManualFrameControl,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ThryToggleUI(true)]_FlipbookManualFrameControl ("Manual Frame Control", Float) = 0
		_FlipbookCurrentFrame ("Current Frame", Float) = 0
		[HideInInspector] s_end_FlipbookManualFrameControl ("", Float) = 0
		
		[HideInInspector] s_start_FlipbookStartAndEnd ("Start/End Frame Loop--{reference_property:_FlipbookStartAndEnd,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ThryToggleUI(true)]_FlipbookStartAndEnd ("Start and End Frames", Float) = 0
		_FlipbookStartFrame ("Start Frame", Float) = 0
		_FlipbookEndFrame ("End Frame", Float) = 0
		[HideInInspector] s_end_FlipbookStartAndEnd ("", Float) = 0
		
		[HideInInspector] s_start_FlipbookCrossfade ("Frame Crossfade--{reference_property:_FlipbookCrossfadeEnabled,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ThryToggleUI(true)]_FlipbookCrossfadeEnabled ("Crossfade</b></size>", Float) = 0
		[MultiSlider]_FlipbookCrossfadeRange ("Fade Range", Vector) = (0.75, 1, 0, 1)
		[HideInInspector] s_end_FlipbookCrossfade ("", Float) = 0
		
		[HideInInspector] s_start_FlipbookHueShift ("Hue Shift--{reference_property:_FlipbookHueShiftEnabled,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ThryToggleUI(true)]_FlipbookHueShiftEnabled ("Hue Shift", Float) = 0
		_FlipbookHueShiftSpeed ("Shift Speed", Float) = 0
		_FlipbookHueShift ("", Range(0, 1)) = 0
		[HideInInspector] s_end_FlipbookHueShift ("Hue Shift", Float) = 0
		
		[HideInInspector] s_start_FlipBookAdvanced ("Advanced--{persistent_expand:true,default_expand:false}", Float) = 0
		[ToggleUI]_FlipbookIntensityControlsAlpha ("Color Intensity To Alpha", Float) = 0
		[ToggleUI]_FlipbookAlphaControlsFinalAlpha ("Overide Material Alpha", Float) = 0
		[HideInInspector] s_end_FlipBookAdvanced ("", Float) = 0
		
		//Flipbook audio link
		[HideInInspector] m_start_FlipbookAudioLink ("Audio Link ♫--{ condition_showS:_EnableAudioLink==1}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkFlipbookScaleBand ("Scale Band", Int) = 0
		_AudioLinkFlipbookScale ("Scale Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkFlipbookAlphaBand ("Alpha Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkFlipbookAlpha ("Alpha Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkFlipbookEmissionBand ("Emission Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkFlipbookEmission ("Emission Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkFlipbookFrameBand ("Frame Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkFlipbookFrame ("Frame control", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[ToggleUI]_FlipbookChronotensityEnabled ("Chronotensity", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _FlipbookChronotensityBand ("Chrono Band--{ condition_showS:_FlipbookChronotensityEnabled==1}", Int) = 0
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_FlipbookChronoType ("Chrono Type--{ condition_showS:_FlipbookChronotensityEnabled==1}", Int) = 0
		_FlipbookChronotensitySpeed ("Chrono Speed--{ condition_showS:_FlipbookChronotensityEnabled==1}", Float) = 0
		[HideInInspector] m_end_FlipbookAudioLink ("Audio Link", Float) = 0
		[HideInInspector] m_end_flipBook ("Flipbook", Float) = 0
		//endex
		
		//ifex _EnableEmission==0
		//Emission 1
		[HideInInspector] m_start_emissionOptions ("Emission 0--{reference_property:_EnableEmission,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/special-fx/emission},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(_EMISSION)]_EnableEmission ("Enable Emission", Float) = 0
		[sRGBWarning]_EmissionMask ("Emission Mask--{reference_properties:[_EmissionMaskPan, _EmissionMaskUV, _EmissionMaskChannel, _EmissionMaskInvert, _EmissionMask0GlobalMask]}", 2D) = "white" { }
		[HideInInspector][Vector2]_EmissionMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _EmissionMaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_EmissionMaskChannel ("Channel", Float) = 0
		[HideInInspector][ToggleUI]_EmissionMaskInvert ("Invert", Float) = 0
		[HideInInspector][ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _EmissionMask0GlobalMask ("Global Mask--{reference_property:_EmissionMask0GlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_EmissionMask0GlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		
		[HDR]_EmissionColor ("Emission Color--{reference_property:_EmissionColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _EmissionColorThemeIndex ("", Int) = 0
		[sRGBWarning(true)][Gradient]_EmissionMap ("Emission Map--{reference_properties:[_EmissionMapPan, _EmissionMapUV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_EmissionMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _EmissionMapUV ("UV", Int) = 0
		_EmissionStrength ("Emission Strength", Range(0, 20)) = 0
		[ToggleUI]_EmissionBaseColorAsMap ("Use Base Colors", Float) = 0
		[ToggleUI]_EmissionReplace0 ("Override Base Color", Float) = 0
		
		[HideInInspector] s_start_EmissionHueShift0 ("Color Adjust--{reference_property:_EmissionHueShiftEnabled,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_EmissionHueShiftEnabled ("Hue Shift", Float) = 0
		_EmissionSaturation("Saturation", Range(-1, 10)) = 0
		_EmissionHueShift ("Hue Shift", Range(0, 1)) = 0
		_EmissionHueShiftSpeed ("Hue Shift Speed", Float) = 0
		[HideInInspector] s_end_EmissionHueShift0 ("", Float) = 0
		
		// Center out emission
		[HideInInspector] s_start_EmissionCenterOut0 ("Center Out--{reference_property:_EmissionCenterOutEnabled,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_EmissionCenterOutEnabled ("Center Out", Float) = 0
		_EmissionCenterOutSpeed ("Flow Speed", Float) = 5
		[HideInInspector] s_end_EmissionCenterOut0 ("", Float) = 0
		
		// Glow in the dark Emission
		[HideInInspector] s_start_EmissionLightBased0 ("Light Based--{reference_property:_EnableGITDEmission,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_EnableGITDEmission ("Light Based", Float) = 0
		[Enum(World, 0, Mesh, 1)] _GITDEWorldOrMesh ("Lighting Type", Int) = 0
		_GITDEMinEmissionMultiplier ("Min Emission Multiplier", Range(0, 1)) = 1
		_GITDEMaxEmissionMultiplier ("Max Emission Multiplier", Range(0, 1)) = 0
		_GITDEMinLight ("Min Lighting", Range(0, 1)) = 0
		_GITDEMaxLight ("Max Lighting", Range(0, 1)) = 1
		[HideInInspector] s_end_EmissionLightBased0 ("", Float) = 0
		
		// Blinking Emission
		[HideInInspector] s_start_EmissionBlinking0 ("Blinking--{reference_property:_EmissionBlinkingEnabled,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_EmissionBlinkingEnabled ("Blinking", Float) = 0
		_EmissiveBlink_Min ("Emissive Blink Min", Float) = 0
		_EmissiveBlink_Max ("Emissive Blink Max", Float) = 1
		_EmissiveBlink_Velocity ("Emissive Blink Velocity", Float) = 4
		_EmissionBlinkingOffset ("Offset", Float) = 0
		[HideInInspector] s_end_EmissionBlinking0 ("", Float) = 0
		
		// Scrolling Emission
		[HideInInspector] s_start_ScrollingEmission0 ("Scrolling--{reference_property:_ScrollingEmission,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI] _ScrollingEmission ("Scrolling", Float) = 0
		[ToggleUI]_EmissionScrollingUseCurve ("Use Curve", float) = 0
		[Curve]_EmissionScrollingCurve ("Curve--{condition_showS:(_EmissionScrollingUseCurve==1)}", 2D) = "white" { }
		[ToggleUI]_EmissionScrollingVertexColor ("VColor as position", float) = 0
		_EmissiveScroll_Direction ("Direction", Vector) = (0, -10, 0, 0)
		_EmissiveScroll_Width ("Width", Float) = 10
		_EmissiveScroll_Velocity ("Velocity", Float) = 10
		_EmissiveScroll_Interval ("Interval", Float) = 20
		_EmissionScrollingOffset ("Offset", Float) = 0
		[HideInInspector] s_end_ScrollingEmission0 ("", Float) = 0
		
		[Space(4)]
		[ThryToggleUI(true)] _EmissionAL0Enabled ("<size=13><b>  Audio Link</b></size>--{ condition_showS:_EnableAudioLink==1}", Float) = 0
		[HideInInspector] s_start_EmissionAL0Multiply ("Strength Multiply--{persistent_expand:true,default_expand:false, condition_showS:(_EmissionAL0Enabled==1 && _EnableAudioLink==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _EmissionAL0MultipliersBand ("Band", Int) = 0
		[VectorLabel(Min, Max)]_EmissionAL0Multipliers ("Multiplier", Vector) = (1, 1, 0, 0)
		[HideInInspector] s_end_EmissionAL0Multiply ("Strength Multiply", Float) = 0
		
		[HideInInspector] s_start_EmissionAL0Add ("Strength Add--{persistent_expand:true,default_expand:false, condition_showS:(_EmissionAL0Enabled==1 && _EnableAudioLink==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _EmissionAL0StrengthBand ("Band", Int) = 0
		[VectorLabel(Min, Max)]_EmissionAL0StrengthMod ("Strength", Vector) = (0, 0, 0, 0)
		[HideInInspector] s_end_EmissionAL0Add ("Strength Add", Float) = 0
		
		[HideInInspector] s_start_EmissionAL0COut ("Center Out--{persistent_expand:true,default_expand:false, condition_showS:(_EmissionAL0Enabled==1 && _EnableAudioLink==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkEmission0CenterOutBand ("Band", Int) = 0
		[VectorLabel(Min, Max)] _AudioLinkEmission0CenterOut ("Strength", Vector) = (0, 0, 0, 0)
		_AudioLinkEmission0CenterOutSize ("Intensity Threshold", Range(0, 1)) = 0
		_AudioLinkEmission0CenterOutDuration ("Duration", Range(-1, 1)) = 1
		[HideInInspector] s_end_EmissionAL0COut ("Center Out", Float) = 0
		[HideInInspector] m_end_emissionOptions ("", Float) = 0
		//endex
		//ifex _EnableEmission1==0
		// Second Emission
		[HideInInspector] m_start_emission1Options ("Emission 1--{reference_property:_EnableEmission1,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/special-fx/emission},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(POI_EMISSION_1)]_EnableEmission1 ("Enable Emission 2", Float) = 0
		[sRGBWarning]_EmissionMask1 ("Emission Mask--{reference_properties:[_EmissionMask1Pan, _EmissionMask1UV, _EmissionMask1Channel, _EmissionMaskInvert1, _EmissionMask1GlobalMask]}", 2D) = "white" { }
		[HideInInspector][Vector2]_EmissionMask1Pan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _EmissionMask1UV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_EmissionMask1Channel ("Channel", Float) = 0
		[HideInInspector][ToggleUI]_EmissionMaskInvert1 ("Invert", Float) = 0
		[HideInInspector][ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _EmissionMask1GlobalMask ("Global Mask--{reference_property:_EmissionMask1GlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_EmissionMask1GlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		[HDR]_EmissionColor1 ("Emission Color--{reference_property:_EmissionColor1ThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _EmissionColor1ThemeIndex ("", Int) = 0
		[sRGBWarning(true)][Gradient]_EmissionMap1 ("Emission Map--{reference_properties:[_EmissionMap1Pan, _EmissionMap1UV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_EmissionMap1Pan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _EmissionMap1UV ("UV", Int) = 0
		_EmissionStrength1 ("Emission Strength", Range(0, 20)) = 0
		[ToggleUI]_EmissionBaseColorAsMap1 ("Use Base Colors", Float) = 0
		[ToggleUI]_EmissionReplace1 ("Override Base Color", Float) = 0
		
		[HideInInspector] s_start_EmissionHueShift1 ("Color Adjust--{reference_property:_EmissionHueShiftEnabled1,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_EmissionHueShiftEnabled1 ("Hue Shift", Float) = 0
		_EmissionSaturation1("Saturation", Range(-1, 10)) = 0
		_EmissionHueShift1 ("Hue Shift", Range(0, 1)) = 0
		_EmissionHueShiftSpeed1 ("Hue Shift Speed", Float) = 0
		[HideInInspector] s_end_EmissionHueShift1 ("", Float) = 0
		
		// Second Center Out Enission
		[HideInInspector] s_start_EmissionCenterOutEnabled1 ("Center Out--{reference_property:_EmissionCenterOutEnabled1,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_EmissionCenterOutEnabled1 ("Center Out", Float) = 0
		_EmissionCenterOutSpeed1 ("Flow Speed", Float) = 5
		[HideInInspector] s_end_EmissionCenterOutEnabled1 ("", Float) = 0
		
		// Second Glow In The Dark Emission
		[HideInInspector] s_start_EmissionLightBased1 ("Light Based--{reference_property:_EnableGITDEmission1,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_EnableGITDEmission1 ("Light Based", Float) = 0
		[Enum(World, 0, Mesh, 1)] _GITDEWorldOrMesh1 ("Lighting Type", Int) = 0
		_GITDEMinEmissionMultiplier1 ("Min Emission Multiplier", Range(0, 1)) = 1
		_GITDEMaxEmissionMultiplier1 ("Max Emission Multiplier", Range(0, 1)) = 0
		_GITDEMinLight1 ("Min Lighting", Range(0, 1)) = 0
		_GITDEMaxLight1 ("Max Lighting", Range(0, 1)) = 1
		[HideInInspector] s_end_EmissionLightBased1 ("", Float) = 0
		
		// Second Blinking Emission
		[HideInInspector] s_start_EmissionBlinking1 ("Blinking--{reference_property:_EmissionBlinkingEnabled1,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_EmissionBlinkingEnabled1 ("Blinking", Float) = 0
		_EmissiveBlink_Min1 ("Emissive Blink Min", Float) = 0
		_EmissiveBlink_Max1 ("Emissive Blink Max", Float) = 1
		_EmissiveBlink_Velocity1 ("Emissive Blink Velocity", Float) = 4
		_EmissionBlinkingOffset1 ("Offset", Float) = 0
		[HideInInspector] s_end_EmissionBlinking1 ("", Float) = 0
		
		// Second Scrolling Emission
		[HideInInspector] s_start_EmissionScrolling1 ("Scrolling--{reference_property:_ScrollingEmission1,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI] _ScrollingEmission1 ("Scrolling", Float) = 0
		[ToggleUI]_EmissionScrollingUseCurve1 ("Use Curve", float) = 0
		[Curve]_EmissionScrollingCurve1 ("Curve--{condition_showS:(_EmissionScrollingUseCurve1==1)}", 2D) = "white" { }
		[ToggleUI]_EmissionScrollingVertexColor1 ("VColor as position", float) = 0
		_EmissiveScroll_Direction1 ("Direction", Vector) = (0, -10, 0, 0)
		_EmissiveScroll_Width1 ("Width", Float) = 10
		_EmissiveScroll_Velocity1 ("Velocity", Float) = 10
		_EmissiveScroll_Interval1 ("Interval", Float) = 20
		_EmissionScrollingOffset1 ("Offset", Float) = 0
		[HideInInspector] s_end_EmissionScrolling1 ("", Float) = 0
		
		[Space(4)]
		[ThryToggleUI(true)] _EmissionAL1Enabled ("<size=13><b>  Audio Link</b></size>--{ condition_showS:_EnableAudioLink==1}", Float) = 0
		[HideInInspector] s_start_EmissionAL1Multiply ("Strength Multiply--{persistent_expand:true,default_expand:false, condition_showS:(_EmissionAL1Enabled==1 && _EnableAudioLink==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _EmissionAL1MultipliersBand ("Band", Int) = 0
		[VectorLabel(Min, Max)]_EmissionAL1Multipliers ("Multiplier", Vector) = (1, 1, 0, 0)
		[HideInInspector] s_end_EmissionAL1Multiply ("Strength Multiply", Float) = 0
		
		[HideInInspector] s_start_EmissionAL1Add ("Strength Add--{persistent_expand:true,default_expand:false, condition_showS:(_EmissionAL1Enabled==1 && _EnableAudioLink==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _EmissionAL1StrengthBand ("Band", Int) = 0
		[VectorLabel(Min, Max)]_EmissionAL1StrengthMod ("Strength Add", Vector) = (0, 0, 0, 0)
		[HideInInspector] s_end_EmissionAL1Add ("Strength Add", Float) = 0
		
		[HideInInspector] s_start_EmissionAL1COut ("Center Out--{persistent_expand:true,default_expand:false, condition_showS:(_EmissionAL1Enabled==1 && _EnableAudioLink==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkEmission1CenterOutBand ("Band", Int) = 0
		[VectorLabel(Min, Max)] _AudioLinkEmission1CenterOut ("Strength", Vector) = (0, 0, 0, 0)
		_AudioLinkEmission1CenterOutSize ("Intensity Threshold", Range(0, 1)) = 0
		_AudioLinkEmission1CenterOutDuration ("Duration--{tooltip:''How much AL history is used. Negative values reverse direction'', condition_showS:(_EmissionAL1Enabled==1 && _EnableAudioLink==1)}", Range(-1, 1)) = 1
		[HideInInspector] s_end_EmissionAL1COut ("Center Out", Float) = 0
		
		[HideInInspector] m_end_emission1Options ("", Float) = 0
		//endex
		//ifex _EnableEmission2==0
		// Third Emission
		[HideInInspector] m_start_emission2Options ("Emission 2--{reference_property:_EnableEmission2,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/special-fx/emission},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(POI_EMISSION_2)]_EnableEmission2 ("Enable Emission 2", Float) = 0
		[sRGBWarning]_EmissionMask2 ("Emission Mask--{reference_properties:[_EmissionMask2Pan, _EmissionMask2UV, _EmissionMask2Channel, _EmissionMaskInvert2, _EmissionMask2GlobalMask]}", 2D) = "white" { }
		[HideInInspector][Vector2]_EmissionMask2Pan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _EmissionMask2UV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_EmissionMask2Channel ("Channel", Float) = 0
		[HideInInspector][ToggleUI]_EmissionMaskInvert2 ("Invert", Float) = 0
		[HideInInspector][ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _EmissionMask2GlobalMask ("Global Mask--{reference_property:_EmissionMask2GlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_EmissionMask2GlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		[HDR]_EmissionColor2 ("Emission Color--{reference_property:_EmissionColor2ThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _EmissionColor2ThemeIndex ("", Int) = 0
		[Gradient]_EmissionMap2 ("Emission Map--{reference_properties:[_EmissionMap2Pan, _EmissionMap2UV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_EmissionMap2Pan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _EmissionMap2UV ("UV", Int) = 0
		_EmissionStrength2 ("Emission Strength", Range(0, 20)) = 0
		[ToggleUI]_EmissionBaseColorAsMap2 ("Use Base Colors", Float) = 0
		[ToggleUI]_EmissionReplace2 ("Override Base Color", Float) = 0
		
		[HideInInspector] s_start_EmissionHueShift2 ("Color Adjust--{reference_property:_EmissionHueShiftEnabled2,persistent_expand:true,default_expand:false}", Float) = 0
		[ToggleUI]_EmissionHueShiftEnabled2 ("Hue Shift", Float) = 0
		_EmissionSaturation2("Saturation", Range(-1, 10)) = 0
		_EmissionHueShift2 ("Hue Shift", Range(0, 1)) = 0
		_EmissionHueShiftSpeed2 ("Hue Shift Speed", Float) = 0
		[HideInInspector] s_end_EmissionHueShift2 ("", Float) = 0
		
		// Third Center Out Enission
		[HideInInspector] s_start_EmissionCenterOut2 ("Center Out--{reference_property:_EmissionCenterOutEnabled2,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_EmissionCenterOutEnabled2 ("Center Out", Float) = 0
		_EmissionCenterOutSpeed2 ("Flow Speed", Float) = 5
		[HideInInspector] s_end_EmissionCenterOutEnabled2 ("", Float) = 0
		
		// Third Glow In The Dark Emission
		[HideInInspector] s_start_EmissionLightBased2 ("Light Based--{reference_property:_EnableGITDEmission2,persistent_expand:true,default_expand:false}", Float) = 0
		[ToggleUI]_EnableGITDEmission2 ("Light Based", Float) = 0
		[Enum(World, 0, Mesh, 1)] _GITDEWorldOrMesh2 ("Lighting Type", Int) = 0
		_GITDEMinEmissionMultiplier2 ("Min Emission Multiplier", Range(0, 1)) = 1
		_GITDEMaxEmissionMultiplier2 ("Max Emission Multiplier", Range(0, 1)) = 0
		_GITDEMinLight2 ("Min Lighting", Range(0, 1)) = 0
		_GITDEMaxLight2 ("Max Lighting", Range(0, 1)) = 1
		[HideInInspector] s_end_EmissionLightBased2 ("", Float) = 0
		
		// Third Blinking Emission
		[HideInInspector] s_start_EmissionBlinking2 ("Blinking--{reference_property:_EmissionBlinkingEnabled2,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_EmissionBlinkingEnabled2 ("Blinking", Float) = 0
		_EmissiveBlink_Min2 ("Emissive Blink Min", Float) = 0
		_EmissiveBlink_Max2 ("Emissive Blink Max", Float) = 1
		_EmissiveBlink_Velocity2 ("Emissive Blink Velocity", Float) = 4
		_EmissionBlinkingOffset2 ("Offset", Float) = 0
		[HideInInspector] s_end_EmissionBlinking2 ("", Float) = 0
		
		// Third Scrolling Emission
		[HideInInspector] s_start_EmissionScrolling2 ("Scrolling--{reference_property:_ScrollingEmission2,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI] _ScrollingEmission2 ("Scrolling", Float) = 0
		[ToggleUI]_EmissionScrollingUseCurve2 ("Use Curve", float) = 0
		[Curve]_EmissionScrollingCurve2 ("Curve--{condition_showS:(_EmissionScrollingUseCurve2==1)}", 2D) = "white" { }
		[ToggleUI]_EmissionScrollingVertexColor2 ("VColor as position", float) = 0
		_EmissiveScroll_Direction2 ("Direction", Vector) = (0, -10, 0, 0)
		_EmissiveScroll_Width2 ("Width", Float) = 10
		_EmissiveScroll_Velocity2 ("Velocity", Float) = 10
		_EmissiveScroll_Interval2 ("Interval", Float) = 20
		_EmissionScrollingOffset2 ("Offset", Float) = 0
		[HideInInspector] s_end_EmissionScrolling2 ("", Float) = 0
		
		[Space(4)]
		[ThryToggleUI(true)] _EmissionAL2Enabled ("<size=13><b>  Audio Link</b></size>--{ condition_showS:_EnableAudioLink==1}", Float) = 0
		[HideInInspector]s_start_EmissionAL2Multiply ("Strength Multiply--{persistent_expand:true,default_expand:false, condition_showS:(_EmissionAL2Enabled==1 && _EnableAudioLink==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _EmissionAL2MultipliersBand ("Emission Multiplier Band", Int) = 0
		[VectorLabel(Min, Max)]_EmissionAL2Multipliers ("Emission Multiplier", Vector) = (1, 1, 0, 0)
		[HideInInspector]s_end_EmissionAL2Multiply ("Strength Multiply", Float) = 0
		
		[HideInInspector]s_start_EmissionAL2Add ("Strength Add--{persistent_expand:true,default_expand:false, condition_showS:(_EmissionAL2Enabled==1 && _EnableAudioLink==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _EmissionAL2StrengthBand ("Band", Int) = 0
		[VectorLabel(Min, Max)]_EmissionAL2StrengthMod ("Strength Add", Vector) = (0, 0, 0, 0)
		[HideInInspector]s_end_EmissionAL2Add ("Strength Add", Float) = 0
		
		[HideInInspector]s_start_EmissionAL2COut ("Center Out--{persistent_expand:true,default_expand:false, condition_showS:(_EmissionAL2Enabled==1 && _EnableAudioLink==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkEmission2CenterOutBand ("Band", Int) = 0[VectorLabel(Min, Max)]
		_AudioLinkEmission2CenterOut ("Strength", Vector) = (0, 0, 0, 0)
		_AudioLinkEmission2CenterOutSize ("Intensity Threshold", Range(0, 1)) = 0
		_AudioLinkEmission2CenterOutDuration ("Duration--{tooltip:''How much AL history is used. Negative values reverse direction''}", Range(-1, 1)) = 1
		[HideInInspector]s_end_EmissionAL2COut ("Center Out", Float) = 0
		[HideInInspector] m_end_emission2Options ("", Float) = 0
		//endex
		
		//ifex _EnableEmission3==0
		// Fourth Emission
		[HideInInspector] m_start_emission3Options ("Emission 3--{reference_property:_EnableEmission3,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/special-fx/emission},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(POI_EMISSION_3)]_EnableEmission3 ("Enable Emission 3", Float) = 0
		[sRGBWarning]_EmissionMask3 ("Emission Mask--{reference_properties:[_EmissionMask3Pan, _EmissionMask3UV, _EmissionMask3Channel, _EmissionMaskInvert3, _EmissionMask3GlobalMask]}", 2D) = "white" { }
		[HideInInspector][Vector2]_EmissionMask3Pan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _EmissionMask3UV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_EmissionMask3Channel ("Channel", Float) = 0
		[HideInInspector][ToggleUI]_EmissionMaskInvert3 ("Invert", Float) = 0
		[HideInInspector][ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _EmissionMask3GlobalMask ("Global Mask--{reference_property:_EmissionMask3GlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_EmissionMask3GlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		[HDR]_EmissionColor3 ("Emission Color--{reference_property:_EmissionColor3ThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _EmissionColor3ThemeIndex ("", Int) = 0
		[sRGBWarning(true)][Gradient]_EmissionMap3 ("Emission Map--{reference_properties:[_EmissionMap3Pan, _EmissionMap3UV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_EmissionMap3Pan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _EmissionMap3UV ("UV", Int) = 0
		_EmissionStrength3 ("Emission Strength", Range(0, 20)) = 0
		[ToggleUI]_EmissionBaseColorAsMap3 ("Use Base Colors", Float) = 0
		[ToggleUI]_EmissionReplace3 ("Override Base Color", Float) = 0
		
		[HideInInspector] s_start_EmissionHueShift3 ("Color Adjust--{reference_property:_EmissionHueShiftEnabled3,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_EmissionHueShiftEnabled3 ("Hue Shift", Float) = 0
		_EmissionSaturation3("Saturation", Range(-1, 10)) = 0
		_EmissionHueShift3 ("Hue Shift", Range(0, 1)) = 0
		_EmissionHueShiftSpeed3 ("Hue Shift Speed", Float) = 0
		[HideInInspector] s_end_EmissionHueShift3 ("", Float) = 0
		
		// Fourth Center Out Enission
		[HideInInspector] s_start_EmissionCenterOutEnabled3 ("Center Out--{reference_property:_EmissionCenterOutEnabled3,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_EmissionCenterOutEnabled3 ("Center Out", Float) = 0
		_EmissionCenterOutSpeed3 ("Flow Speed", Float) = 5
		[HideInInspector] s_end_EmissionCenterOutEnabled3 ("", Float) = 0
		
		// Fourth Glow In The Dark Emission
		[HideInInspector] s_start_EmissionLightBased3 ("Light Based--{reference_property:_EnableGITDEmission3,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_EnableGITDEmission3 ("Light Based", Float) = 0
		[Enum(World, 0, Mesh, 1)] _GITDEWorldOrMesh3 ("Lighting Type", Int) = 0
		_GITDEMinEmissionMultiplier3 ("Min Emission Multiplier", Range(0, 1)) = 1
		_GITDEMaxEmissionMultiplier3 ("Max Emission Multiplier", Range(0, 1)) = 0
		_GITDEMinLight3 ("Min Lighting", Range(0, 1)) = 0
		_GITDEMaxLight3 ("Max Lighting", Range(0, 1)) = 1
		[HideInInspector] s_end_EmissionLightBased3 ("", Float) = 0
		
		// Fourth Blinking Emission
		[HideInInspector] s_start_EmissionBlinking3 ("Blinking--{reference_property:_EmissionBlinkingEnabled3,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_EmissionBlinkingEnabled3 ("Blinking", Float) = 0
		_EmissiveBlink_Min3 ("Emissive Blink Min", Float) = 0
		_EmissiveBlink_Max3 ("Emissive Blink Max", Float) = 1
		_EmissiveBlink_Velocity3 ("Emissive Blink Velocity", Float) = 4
		_EmissionBlinkingOffset3 ("Offset", Float) = 0
		[HideInInspector] s_end_EmissionBlinking3 ("", Float) = 0
		
		// Fourth Scrolling Emission
		[HideInInspector] s_start_EmissionScrolling3 ("Scrolling--{reference_property:_ScrollingEmission3,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI] _ScrollingEmission3 ("Scrolling", Float) = 0
		[ToggleUI]_EmissionScrollingUseCurve3 ("Use Curve", float) = 0
		[Curve]_EmissionScrollingCurve3 ("Curve--{condition_showS:(_EmissionScrollingUseCurve3==1)}", 2D) = "white" { }
		[ToggleUI]_EmissionScrollingVertexColor3 ("VColor as position", float) = 0
		_EmissiveScroll_Direction3 ("Direction", Vector) = (0, -10, 0, 0)
		_EmissiveScroll_Width3 ("Width", Float) = 10
		_EmissiveScroll_Velocity3 ("Velocity", Float) = 10
		_EmissiveScroll_Interval3 ("Interval", Float) = 20
		_EmissionScrollingOffset3 ("Offset", Float) = 0
		[HideInInspector] s_end_EmissionScrolling3 ("", Float) = 0
		
		[Space(4)]
		[ThryToggleUI(true)] _EmissionAL3Enabled ("<size=13><b>  Audio Link</b></size>--{ condition_showS:_EnableAudioLink==1}", Float) = 0
		
		[HideInInspector] s_start_EmissionAL3Multiply ("Strength Multiply--{persistent_expand:true,default_expand:false, condition_showS:(_EmissionAL3Enabled==1 && _EnableAudioLink==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _EmissionAL3MultipliersBand ("Bands", Int) = 0
		[VectorLabel(Min, Max)]_EmissionAL3Multipliers ("Multipliers", Vector) = (1, 1, 0, 0)
		[HideInInspector] s_end_EmissionAL3Multiply ("Strength Multiply", Float) = 0
		
		[HideInInspector] s_start_EmissionAL3Add ("Strength Add--{persistent_expand:true,default_expand:false, condition_showS:(_EmissionAL3Enabled==1 && _EnableAudioLink==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _EmissionAL3StrengthBand ("Strength Add Bands", Int) = 0
		[VectorLabel(Min, Max)]_EmissionAL3StrengthMod ("Strength Adds", Vector) = (0, 0, 0, 0)
		[HideInInspector] s_end_EmissionAL3Add ("Strength Add", Float) = 0
		
		[HideInInspector] s_start_EmissionAL3COut ("Center Out--{persistent_expand:true,default_expand:false, condition_showS:(_EmissionAL3Enabled==1 && _EnableAudioLink==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkEmission3CenterOutBand ("Bands", Int) = 0
		[VectorLabel(Min, Max)] _AudioLinkEmission3CenterOut ("Strengths", Vector) = (0, 0, 0, 0)
		_AudioLinkEmission3CenterOutSize ("Intensity Thresholds", Range(0, 1)) = 0
		_AudioLinkEmission3CenterOutDuration ("Duration", Range(-1, 1)) = 1
		[HideInInspector] s_end_EmissionAL3COut ("Center Out", Float) = 0
		
		[HideInInspector] m_end_emission3Options ("", Float) = 0
		//endex
		
		// Glitter
		//ifex _GlitterEnable==0
		[HideInInspector] m_start_glitter ("Glitter / Sparkle--{reference_property:_GlitterEnable,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/special-fx/glitter},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(_SUNDISK_SIMPLE)]_GlitterEnable ("Enable Glitter", Float) = 0
		[ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _GlitterUV ("UV", Int) = 0
		[Enum(Angle, 0, Linear Emission, 1, Light Reflections, 2)]_GlitterMode ("Mode", Int) = 0
		[Enum(Circle, 0, Square, 1)]_GlitterShape ("Shape", Int) = 0
		[Enum(Add, 0, Replace, 1)] _GlitterBlendType ("Blend Mode", Int) = 0
		_GlitterUseNormals ("Use Normals", Range(0, 1)) = 0
		[IntRange]_GlitterLayers ("Layers", Range(1, 4)) = 2
		
		[HideInInspector] s_start_GlitterColorAndShape ("Shape & Color--{persistent_expand:true,default_expand:true}", Float) = 1
		_GlitterTexture ("Shape Texture", 2D) = "white" { }
		[sRGBWarning(true)]_GlitterColorMap ("Color Map--{reference_properties:[_GlitterColorMapPan, _GlitterColorMapUV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_GlitterColorMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _GlitterColorMapUV ("UV", Int) = 0
		[HDR]_GlitterColor ("Color--{reference_property:_GlitterColorThemeIndex}", Color) = (1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _GlitterColorThemeIndex ("", Int) = 0
		_GlitterUseSurfaceColor ("Use Base Color", Range(0, 1)) = 0
		[ToggleUI]_GlitterRandomColors ("Random Colors", Float) = 0
		[MultiSlider]_GlitterMinMaxSaturation ("Saturation Range--{condition_showS:(_GlitterRandomColors==1)}", Vector) = (0.8, 1, 0, 1)
		[MultiSlider]_GlitterMinMaxBrightness ("Brightness Range--{condition_showS:(_GlitterRandomColors==1)}", Vector) = (0.8, 1, 0, 1)
		[HideInInspector] s_end_GlitterColorAndShape ("Color", Float) = 0
		
		[HideInInspector] s_start_GlitterPositionSize ("Position & Size--{persistent_expand:true,default_expand:true}", Float) = 01
		_GlitterFrequency ("Glitter Density", Float) = 300.0
		_GlitterSize ("Glitter Size--{condition_show:(_GlitterRandomSize==0)}", Range(0, 1)) = .3
		[Vector2]_GlitterUVPanning ("Panning", Vector) = (0, 0, 0, 0)
		[ToggleUI]_GlitterRandomLocation ("Random Position", Float) = 1.0
		[ToggleUI]_GlitterRandomSize ("Random Size", Float) = 0
		[MultiSlider]_GlitterMinMaxSize ("Size Range--{condition_show:(_GlitterRandomSize==1)}", Vector) = (0.1, 0.5, 0, 1)
		[HideInInspector] s_end_GlitterPositionSize ("Position & Size", Float) = 0
		
		[HideInInspector] s_start_GlitterSparkleControl ("Sparkle Control--{persistent_expand:true,default_expand:true}", Float) = 1
		_GlitterMinBrightness ("Glitter Min Brightness", Range(0, 1)) = 0
		_GlitterBrightness ("Glitter Max Brightness", Range(0, 40)) = 3
		_GlitterSpeed ("Speed", Float) = 10.0
		_GlitterAngleRange ("Glitter Angle Range--{condition_showS:(_GlitterMode==0||_GlitterMode==2)}", Range(0, 90)) = 90
		_GlitterBias ("Glitter Bias--{condition_show:(_GlitterMode==0)}", Range(0, 1)) = .8
		_GlitterCenterSize ("dim light--{condition_show:{type:AND,condition1:{type:PROPERTY_BOOL,data:_GlitterMode==1},condition2:{type:PROPERTY_BOOL,data:_GlitterShape==1}}}", Range(0, 1)) = .08
		_GlitterContrast ("Post Contrast--{condition_showS:(_GlitterMode==0||_GlitterMode==2)}", Range(1, 1000)) = 300
		_GlitterJaggyFix ("Distant Jaggy Fix--{condition_show:{type:PROPERTY_BOOL,data:_GlitterShape==1}}", Range(0, .1)) = .0
		[HideInInspector] s_end_GlitterSparkleControl ("Sparkle Control", Float) = 0
		
		[HideInInspector] s_start_GlitterRotationSection ("Rotations--{persistent_expand:true,default_expand:false}", Float) = 0
		[ToggleUI]_GlitterRandomRotation ("Random Offset", Float) = 0
		_GlitterTextureRotation ("Constant Speed", Float) = 0
		[VectorLabel(Min, Max)]_GlitterRandomRotationSpeed ("Random Speed Range", Vector) = (0, 0, 0, 0)
		[HideInInspector] s_end_GlitterRotationSection ("Rotations", Float) = 0
		
		[HideInInspector] s_start_GlitterMask ("Masking & Light Masking--{persistent_expand:true,default_expand:false}", Float) = 0
		[sRGBWarning]_GlitterMask ("Glitter Mask--{reference_properties:[_GlitterMaskPan, _GlitterMaskUV, _GlitterMaskChannel, _GlitterMaskInvert]}", 2D) = "white" { }
		[HideInInspector][Vector2]_GlitterMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _GlitterMaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_GlitterMaskChannel ("Channel", Float) = 0
		[HideInInspector][ToggleUI]_GlitterMaskInvert ("Invert", Float) = 0
		_GlitterHideInShadow ("Hide in shadow", Range(0, 1)) = 0
		_GlitterScaleWithLighting ("Scale With Lighting", Range(0, 1)) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _GlitterMaskGlobalMask ("Global Mask--{reference_property:_GlitterMaskGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_GlitterMaskGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		[HideInInspector] s_end_GlitterMask ("Masking", Float) = 0
		
		[HideInInspector] s_start_GlitterHueShiftSection ("Hue Shift--{reference_property:_GlitterHueShiftEnabled, persistent_expand:true,default_expand:false)}", Float) = 0
		[HideInInspector][ToggleUI]_GlitterHueShiftEnabled ("Enable Hue Shift", Float) = 0
		_GlitterHueShiftSpeed ("Shift Speed", Float) = 0
		_GlitterHueShift ("Hue Shift", Range(0, 1)) = 0
		[HideInInspector] s_end_GlitterHueShiftSection ("Hue Shift--{reference_property:_ShadowBorderMapToggle, persistent_expand:true,default_expand:false)}", Float) = 0
		
		[HideInInspector] s_start_GlitterAudioLink ("Audio Link ♫--{reference_property:_GlitterALEnabled,persistent_expand:true,default_expand:false, condition_showS:(_EnableAudioLink==1)}", Float) = 0
		[HideInInspector][ToggleUI] _GlitterALEnabled ("Enable Audio Link", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _GlitterALAlphaAddBand ("Alpha Band", Int) = 0
		[VectorLabel(Min, Max)]_GlitterALAlphaAdd ("Alpha Mod", Vector) = (0, 0, 0, 0)
		
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _GlitterALMaxBrightnessBand ("Max Brightness Band", Int) = 0
		[VectorLabel(Min, Max)]_GlitterALMaxBrightnessAdd ("Max Brightness Mod", Vector) = (0, 0, 0, 0)
		
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _GlitterALSizeAddBand ("Size Band", Int) = 0
		[VectorLabel(Min, Max)]_GlitterALSizeAdd ("Size Mod", Vector) = (0, 0, 0, 0)
		
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_GlitterALChronoSparkleSpeedType ("Chrono Sparkle Type", Int) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _GlitterALChronoSparkleSpeedBand ("Chrono Sparkle Band", Int) = 0
		_GlitterALChronoSparkleSpeed ("Chrono Sparkle Speed", Float) = 0
		
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_GlitterALChronoRotationSpeedType ("Chrono Rotation Type", Int) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _GlitterALChronoRotationSpeedBand ("Chrono Rotation Band", Int) = 0
		_GlitterALChronoRotationSpeed ("Chrono Rotation Speed", Float) = 0
		[HideInInspector] s_end_GlitterAudioLink ("Audio Link", Float) = 0
		[HideInInspector] m_end_glitter ("Glitter / Sparkle", Float) = 0
		//endex
		
		//ifex _EnablePathing==0
		[HideInInspector] m_start_pathing ("Pathing--{reference_property: _EnablePathing,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/special-fx/pathing},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(POI_PATHING)] _EnablePathing ("Enable Pathing", Float) = 0
		[Enum(Split Channels, 0, Merged Channels, 1)]_PathGradientType ("Gradient Type", Float) = 0
		[ToggleUI]_PathingOverrideAlpha ("Override alpha", Float) = 0
		//[ThryExternalTextureToolDrawer(Flood Tool, DreadScripts.GradientFlood)]
		[sRGBWarning][ThryRGBAPacker(R Path, G Path, B Path, A Path, linear, false)]_PathingMap ("RGBA Path Map--{reference_properties:[_PathingMapPan, _PathingMapUV]}", 2D) = "white" { }
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_PathingMapUV ("UV", Int) = 0
		[HideInInspector][Vector2]_PathingMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[sRGBWarning(true)][ThryRGBAPacker(RGB Color, A Mask, sRGB, false)]_PathingColorMap ("Color & Mask (Expand)--{reference_properties:[_PathingColorMapPan, _PathingColorMapUV]}", 2D) = "white" { }
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_PathingColorMapUV ("UV", Int) = 0
		[HideInInspector][Vector2]_PathingColorMapPan ("Panning", Vector) = (0, 0, 0, 0)
		
		[Enum(Fill, 0, Path, 1, Loop, 2)]_PathTypeR ("R Path Type", Float) = 0
		[Enum(Fill, 0, Path, 1, Loop, 2)]_PathTypeG ("G Path Type", Float) = 0
		[Enum(Fill, 0, Path, 1, Loop, 2)]_PathTypeB ("B Path Type", Float) = 0
		[Enum(Fill, 0, Path, 1, Loop, 2)]_PathTypeA ("A Path Type", Float) = 0
		
		[HDR]_PathColorR ("R Color--{reference_property:_PathColorRThemeIndex}", Color) = (1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _PathColorRThemeIndex ("", Int) = 0
		[HDR]_PathColorG ("G Color--{reference_property:_PathColorGThemeIndex}", Color) = (1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _PathColorGThemeIndex ("", Int) = 0
		[HDR]_PathColorB ("B Color--{reference_property:_PathColorBThemeIndex}", Color) = (1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _PathColorBThemeIndex ("", Int) = 0
		[HDR]_PathColorA ("A Color--{reference_property:_PathColorAThemeIndex}", Color) = (1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _PathColorAThemeIndex ("", Int) = 0
		
		[VectorLabel(R,G,B,A)]_PathEmissionStrength ("Emission Strength", Vector) = (0.0, 0.0, 0.0, 0.0)
		[VectorLabel(R,G,B,A)]_PathSoftness ("Softness", Vector) = (1, 1, 1, 1)
		[VectorLabel(R,G,B,A)]_PathSpeed ("Speed", Vector) = (1.0, 1.0, 1.0, 1.0)
		[VectorLabel(R,G,B,A)]_PathWidth ("Length", Vector) = (0.03, 0.03, 0.03, 0.03)
		
		[Header(Timing Options)]
		[VectorLabel(R,G,B,A)]_PathTime ("Manual Timing", Vector) = (-999.0, -999.0, -999.0, -999.0)
		[VectorLabel(R,G,B,A)]_PathOffset ("Timing Offset", Vector) = (0.0, 0.0, 0.0, 0.0)
		[VectorLabel(R,G,B,A)]_PathSegments ("Path Segments", Vector) = (0.0, 0.0, 0.0, 0.0)
		
		[HideInInspector] m_start_PathAudioLink ("Audio Link ♫--{ condition_showS:_EnableAudioLink==1}", Float) = 0
		// Time Offsets
		[ThryToggleUI(true)]_PathALTimeOffset ("<size=13><b>  Time Offset</b></size>", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkPathTimeOffsetBandR ("Band	R--{condition_showS:(_PathALTimeOffset==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkPathTimeOffsetR ("Offset	R--{condition_showS:(_PathALTimeOffset==1)}", Vector) = (0, 0, 0)
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkPathTimeOffsetBandG ("Band	G--{condition_showS:(_PathALTimeOffset==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkPathTimeOffsetG ("Offset	G--{condition_showS:(_PathALTimeOffset==1)}", Vector) = (0, 0, 0)
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkPathTimeOffsetBandB ("Band	B--{condition_showS:(_PathALTimeOffset==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkPathTimeOffsetB ("Offset	B--{condition_showS:(_PathALTimeOffset==1)}", Vector) = (0, 0, 0)
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkPathTimeOffsetBandA ("Band	A--{condition_showS:(_PathALTimeOffset==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkPathTimeOffsetA ("Offset	A--{condition_showS:(_PathALTimeOffset==1)}", Vector) = (0, 0, 0)
		[Space(4)]
		[ThryToggleUI(true)]_PathALEmissionOffset ("<size=13><b>  Emission Offset</b></size>", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkPathEmissionAddBandR ("Band	R--{condition_showS:(_PathALEmissionOffset==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkPathEmissionAddR ("Offset	R--{condition_showS:(_PathALEmissionOffset==1)}", Vector) = (0, 0, 0)
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkPathEmissionAddBandG ("Band	G--{condition_showS:(_PathALEmissionOffset==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkPathEmissionAddG ("Offset	G--{condition_showS:(_PathALEmissionOffset==1)}", Vector) = (0, 0, 0)
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkPathEmissionAddBandB ("Band	B--{condition_showS:(_PathALEmissionOffset==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkPathEmissionAddB ("Offset	B--{condition_showS:(_PathALEmissionOffset==1)}", Vector) = (0, 0, 0)
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkPathEmissionAddBandA ("Band	A--{condition_showS:(_PathALEmissionOffset==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkPathEmissionAddA ("Offset	A--{condition_showS:(_PathALEmissionOffset==1)}", Vector) = (0, 0, 0)
		[Space(4)]
		[ThryToggleUI(true)]_PathALWidthOffset ("<size=13><b>  Width Offset</b></size>", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkPathWidthOffsetBandR ("Band	R--{condition_showS:(_PathALWidthOffset==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkPathWidthOffsetR ("Offset	R--{condition_showS:(_PathALWidthOffset==1)}", Vector) = (0, 0, 0)
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkPathWidthOffsetBandG ("Band	G--{condition_showS:(_PathALWidthOffset==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkPathWidthOffsetG ("Offset	G--{condition_showS:(_PathALWidthOffset==1)}", Vector) = (0, 0, 0)
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkPathWidthOffsetBandB ("Band	B--{condition_showS:(_PathALWidthOffset==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkPathWidthOffsetB ("Offset	B--{condition_showS:(_PathALWidthOffset==1)}", Vector) = (0, 0, 0)
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkPathWidthOffsetBandA ("Band	A--{condition_showS:(_PathALWidthOffset==1)}", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkPathWidthOffsetA ("Offset	A--{condition_showS:(_PathALWidthOffset==1)}", Vector) = (0, 0, 0)
		[Space(4)]
		[ThryToggleUI(true)]_PathALHistory ("<size=13><b>  History</b></size>", Float) = 0
		[Enum(Mask, 0, Override, 1)] _PathALHistoryMode ("History Mode--{condition_showS:(_PathALHistory==1)}", Float) = 0
		
		[ToggleUI]_PathALHistoryR ("R History--{condition_showS:(_PathALHistory==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _PathALHistoryBandR ("R Band--{condition_showS:(_PathALHistory==1 && _PathALHistoryR==1)}", Int) = 0
		[MultiSlider]_PathALHistoryRangeR ("R Range--{condition_showS:(_PathALHistory==1 && _PathALHistoryR==1)}", Vector) = (0, 1, 0, 1)
		
		[ToggleUI]_PathALHistoryG ("G History--{condition_showS:(_PathALHistory==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _PathALHistoryBandG ("G Band--{condition_showS:(_PathALHistory==1 && _PathALHistoryG==1)}", Int) = 0
		[MultiSlider]_PathALHistoryRangeG ("G Range--{condition_showS:(_PathALHistory==1 && _PathALHistoryG==1)}", Vector) = (0, 1, 0, 1)
		
		[ToggleUI]_PathALHistoryB ("B History--{condition_showS:(_PathALHistory==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _PathALHistoryBandB ("B Band--{condition_showS:(_PathALHistory==1 && _PathALHistoryB==1)}", Int) = 0
		[MultiSlider]_PathALHistoryRangeB ("B Range--{condition_showS:(_PathALHistory==1 && _PathALHistoryB==1)}", Vector) = (0, 1, 0, 1)
		
		[ToggleUI]_PathALHistoryA ("A History--{condition_showS:(_PathALHistory==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _PathALHistoryBandA ("A Band--{condition_showS:(_PathALHistory==1 && _PathALHistoryA==1)}", Int) = 0
		[MultiSlider]_PathALHistoryRangeA ("A Range--{condition_showS:(_PathALHistory==1 && _PathALHistoryA==1)}", Vector) = (0, 1, 0, 1)
		[Space(4)]
		[ThryToggleUI(true)]_PathALChrono ("<size=13><b>  Chrono Time</b></size>", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _PathChronoBandR ("R Band--{condition_showS:(_PathALChrono==1)}", Int) = 0
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_PathChronoTypeR ("R Motion Type--{condition_showS:(_PathALChrono==1)}", Int) = 0
		_PathChronoSpeedR ("R Speed--{condition_showS:(_PathALChrono==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _PathChronoBandG ("G Band--{condition_showS:(_PathALChrono==1)}", Int) = 0
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_PathChronoTypeG ("G Motion Type--{condition_showS:(_PathALChrono==1)}", Int) = 0
		_PathChronoSpeedG ("G Speed--{condition_showS:(_PathALChrono==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _PathChronoBandB ("B Band--{condition_showS:(_PathALChrono==1)}", Int) = 0
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_PathChronoTypeB ("B Motion Type--{condition_showS:(_PathALChrono==1)}", Int) = 0
		_PathChronoSpeedB ("B Speed--{condition_showS:(_PathALChrono==1)}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _PathChronoBandA ("A Band--{condition_showS:(_PathALChrono==1)}", Int) = 0
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_PathChronoTypeA ("A Motion Type--{condition_showS:(_PathALChrono==1)}", Int) = 0
		_PathChronoSpeedA ("A Speed--{condition_showS:(_PathALChrono==1)}", Float) = 0
		[Space(4)]
		[ThryToggleUI(true)]_PathALAutoCorrelator ("<size=13><b>  Auto Correlator</b></size>", Float) = 0
		[Enum(Mask, 0, Override, 1)] _PathALAutoCorrelatorMode ("Autocorrelator Mode--{condition_showS:(_PathALAutoCorrelator==1)}", Float) = 0
		[Enum(Off, 0, On, 1, Mirrored, 2)]_PathALAutoCorrelatorR ("R Type--{condition_showS:(_PathALAutoCorrelator==1)}", Int) = 0
		[MultiSlider]_PathALAutoCorrelatorRangeR ("R Range--{condition_showS:(_PathALAutoCorrelator==1 && _PathALAutoCorrelatorR > 0)}", Vector) = (0.1, .9, 0, 1)
		[Enum(Off, 0, On, 1, Mirrored, 2)]_PathALAutoCorrelatorG ("G Type--{condition_showS:(_PathALAutoCorrelator==1)}", Int) = 0
		[MultiSlider]_PathALAutoCorrelatorRangeG ("G Range--{condition_showS:(_PathALAutoCorrelator==1 && _PathALAutoCorrelatorG > 0)}", Vector) = (0.1, .9, 0, 1)
		[Enum(Off, 0, On, 1, Mirrored, 2)]_PathALAutoCorrelatorB ("B Type--{condition_showS:(_PathALAutoCorrelator==1)}", Int) = 0
		[MultiSlider]_PathALAutoCorrelatorRangeB ("B Range--{condition_showS:(_PathALAutoCorrelator==1 && _PathALAutoCorrelatorB > 0)}", Vector) = (0.1, 0.9, 0, 1)
		[Enum(Off, 0, On, 1, Mirrored, 2)]_PathALAutoCorrelatorA ("A Type--{condition_showS:(_PathALAutoCorrelator==1)}", Int) = 0
		[MultiSlider]_PathALAutoCorrelatorRangeA ("A Range--{condition_showS:(_PathALAutoCorrelator==1 && _PathALAutoCorrelatorA > 0)}", Vector) = (0.1, 0.9, 0, 1)
		[Space(4)]
		[ThryToggleUI(true)]_PathALColorChord ("<size=13><b>  Color Chord</b></size>", Float) = 0
		[ToggleUI]_PathALCCR ("R Color Chord Strip--{condition_showS:(_PathALColorChord==1)}", Float) = 0
		[ToggleUI]_PathALCCG ("G Color Chord Strip--{condition_showS:(_PathALColorChord==1)}", Float) = 0
		[ToggleUI]_PathALCCB ("B Color Chord Strip--{condition_showS:(_PathALColorChord==1)}", Float) = 0
		[ToggleUI]_PathALCCA ("A Color Chord Strip--{condition_showS:(_PathALColorChord==1)}", Float) = 0
		[HideInInspector] m_end_PathAudioLink ("", Float) = 0
		[HideInInspector] m_end_pathing ("", Float) = 0
		//endex
		
		//ifex _EnableMirrorOptions==0
		[HideInInspector] m_start_mirrorOptions ("Mirror/Camera Visibility--{reference_property:_EnableMirrorOptions,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/special-fx/mirror},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(POI_MIRROR)]_EnableMirrorOptions ("Enable Mirror Options", Float) = 0
		[ThryWideEnum(Generic, 0, VRC, 1)] _VisibilityMode ("Mode", Int) = 1
		[ThryWideEnum(Show In Both, 0, Show Only In Mirror, 1, Dont Show In Mirror, 2)] _Mirror ("Mirror Visibility--{condition_showS:(_VisibilityMode==0)}", Int) = 0
		[ThryToggleUI(True)]_VisibilityVRCRegular ("Normal (Outside Mirror/Camera)--{condition_showS:(_VisibilityMode==1)}", Int) = 1
		[ThryToggleUI(True)]_VisibilityVRCMirrorVR ("Mirror (VR)--{condition_showS:(_VisibilityMode==1)}", Int) = 1
		[ThryToggleUI(True)]_VisibilityVRCMirrorDesktop ("Mirror (Desktop)--{condition_showS:(_VisibilityMode==1)}", Int) = 1
		[ThryToggleUI(True)]_VisibilityVRCCameraVR ("Camera (VR)--{condition_showS:(_VisibilityMode==1)}", Int) = 1
		[ThryToggleUI(True)]_VisibilityVRCCameraDesktop ("Camera (Desktop)--{condition_showS:(_VisibilityMode==1)}", Int) = 1
		[ThryToggleUI(True)]_VisibilityVRCCameraScreenshot ("Screenshot--{condition_showS:(_VisibilityMode==1)}", Int) = 1
		
		[HideInInspector] s_start_MirrorTexture ("Mirror Texture & Color--{reference_property:_MirrorTextureEnabled,persistent_expand:true,default_expand:true}", Float) = 1
		[ThryWideEnum(Replace, 0, Darken, 1, Multiply, 2, Lighten, 5, Screen, 6, Subtract, 7, Add, 8, Overlay, 9, Mixed, 20)]_MirrorTextureBlendType ("Blending", Range(0, 1)) = 0
		_MirrorColor ("Color--{reference_property:_MirrorColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _MirrorColorThemeIndex ("", Int) = 0
		[HideInInspector][ThryToggleUI(True)]_MirrorTextureEnabled ("Enable", Float) = 0
		[sRGBWarning(true)]_MirrorTexture ("Texture--{reference_properties:[_MirrorTexturePan, _MirrorTextureUV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_MirrorTexturePan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _MirrorTextureUV ("UV", Int) = 0
		[ThryToggleUI(True)]_MirrorTextureForceEnabled ("Test", Float) = 0
		[HideInInspector] s_end_MirrorTexture ("", Float) = 0
		
		[HideInInspector] m_end_mirrorOptions ("Mirror", Float) = 0
		//endex
		
		//ifex _EnableTouchGlow==0
		[HideInInspector] m_start_depthFX ("Depth FX--{reference_property:_EnableTouchGlow}", Float) = 0
		[HideInInspector][ThryToggle(GRAIN)]_EnableTouchGlow ("Enable Depth FX", Float) = 0
		[Helpbox(1)]_DepthFXWarning ("Depth FX doesn't write to depth, which can break certain transparent effects like custom fog and raymarching", Int) = 0
		[sRGBWarning]_DepthMask ("Mask--{reference_properties:[_DepthMaskPan, _DepthMaskUV, _DepthMaskChannel, _DepthMaskGlobalMask]}", 2D) = "white" { }
		[HideInInspector][Vector2]_DepthMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _DepthMaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_DepthMaskChannel ("Channel", Float) = 0
		[HideInInspector][ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _DepthMaskGlobalMask ("Global Mask--{reference_property:_DepthMaskGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_DepthMaskGlobalMaskBlendType ("Blending", Range(0, 1)) = 2
		
		[HideInInspector] s_start_DepthFXColorEmission ("Color & Emission--{reference_property:_DepthColorToggle,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_DepthColorToggle ("Color & Emission", Float) = 0
		[ThryWideEnum(Replace, 0, Multiply, 1, Add, 2)] _DepthColorBlendMode ("Blend Type", Int) = 0
		[sRGBWarning(true)]_DepthTexture ("Depth Texture--{reference_properties:[_DepthTexturePan, _DepthTextureUV], condition_showS:(_DepthColorToggle==1)}", 2D) = "white" { }
		[HideInInspector][Vector2]_DepthTexturePan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos XZ, 5, Polar UV, 6, Distorted UV, 7, Depth Gradient, 8)] _DepthTextureUV ("UV", Int) = 0
		_DepthColor ("Color--{condition_showS:(_DepthColorToggle==1), reference_property:_DepthColorThemeIndex}", Color) = (1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _DepthColorThemeIndex ("", Int) = 0
		_DepthEmissionStrength ("Emission Strength", Range(0, 20)) = 0
		_DepthColorMinDepth ("Min Depth", Float) = 0
		_DepthColorMaxDepth ("Max Depth", Float) = 1
		_DepthColorMinValue ("Min Color Blend", Range(0, 1)) = 1
		_DepthColorMaxValue ("Max Color Blend", Range(0, 1)) = 0
		[HideInInspector] s_end_DepthFXColorEmission ("", Float) = 0
		
		[HideInInspector] s_start_DepthAlpha ("Alpha--{reference_property:_DepthAlphaToggle,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_DepthAlphaToggle ("Alpha", Float) = 0
		_DepthAlphaMinDepth ("Min Depth", Float) = 0
		_DepthAlphaMaxDepth ("Max Depth", Float) = 1
		_DepthAlphaMinValue ("Min Alpha", Range(0, 1)) = 1
		_DepthAlphaMaxValue ("Max Alpha", Range(0, 1)) = 0
		[HideInInspector] s_end_DepthAlpha ("", Float) = 0
		[HideInInspector] m_end_depthFX ("Depth FX", Float) = 0
		//endex
		
		//ifex _TextEnabled==0
		// MSDF OVERLAY
		[HideInInspector] m_start_Text ("Stats Overlay--{reference_property:_TextEnabled,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/special-fx/stats-overlay},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(EFFECT_BUMP)]_TextEnabled ("Text", Float) = 0
		[sRGBWarning]_TextGlyphs ("Font Array", 2D) = "black" { }
		_TextPixelRange ("Pixel Range", Float) = 4.0
		
		// FPS
		[HideInInspector] m_start_TextFPS ("FPS--{reference_property:_TextFPSEnabled}", Float) = 0
		[HideInInspector][ToggleUI]_TextFPSEnabled ("FPS Text", Float) = 0
		[ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _TextFPSUV ("FPS UV", Int) = 0
		_TextFPSColor ("Color--{reference_property:_TextFPSColorThemeIndex}", Color) = (1, 1, 1, 1)
		_TextFPSOutlineColor ("Outline Color--{reference_property:_TextFPSColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _TextFPSColorThemeIndex ("", Int) = 0
		_TextFPSEmissionStrength ("Emission Strength", Range(0, 20)) = 0
		[Vector2]_TextFPSOffset ("Offset", Vector) = (0, 0, 0, 0)
		_TextFPSRotation ("Rotation", Range(0, 360)) = 0
		[Vector2]_TextFPSScale ("Scale", Vector) = (1, 1, 1, 1)
		[VectorLabel(L, D, R, U)]_TextFPSPadding ("Padding Reduction", Vector) = (0, 0, 0, 0)
		[HideInInspector] m_end_TextFPS ("FPS", Float) = 0
		
		// POSITION
		[HideInInspector] m_start_TextPosition ("Position--{reference_property:_TextPositionEnabled}", Float) = 0
		[HideInInspector][ToggleUI]_TextPositionEnabled ("Position Text", Float) = 0
		[ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _TextPositionUV ("Position UV", Int) = 0
		//[ToggleUI]_TextPositionVertical ("Vertical", Float) = 0
		_TextPositionColor ("Color--{reference_property:_TextPositionColorThemeIndex}", Color) = (1, 0, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _TextPositionColorThemeIndex ("", Int) = 0
		_TextPositionEmissionStrength ("Emission Strength", Range(0, 20)) = 0
		[Vector2]_TextPositionOffset ("Offset", Vector) = (0, 0, 0, 0)
		_TextPositionRotation ("Rotation", Range(0, 360)) = 0
		[Vector2]_TextPositionScale ("Scale", Vector) = (1, 1, 1, 1)
		[VectorLabel(L, D, R, U)]_TextPositionPadding ("Padding Reduction", Vector) = (0, 0, 0, 0)
		[HideInInspector] m_end_TextPosition ("Position", Float) = 0
		
		// INSTANCE TIME
		[HideInInspector] m_start_TextInstanceTime ("Instance Time--{reference_property:_TextTimeEnabled}", Float) = 0
		[HideInInspector][ToggleUI]_TextTimeEnabled ("Time Text", Float) = 0
		[ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _TextTimeUV ("Time UV", Int) = 0
		_TextTimeColor ("Color--{reference_property:_TextTimeColorThemeIndex}", Color) = (1, 0, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _TextTimeColorThemeIndex ("", Int) = 0
		_TextTimeEmissionStrength ("Emission Strength", Range(0, 20)) = 0
		[Vector2]_TextTimeOffset ("Offset", Vector) = (0, 0, 0, 0)
		_TextTimeRotation ("Rotation", Range(0, 360)) = 0
		[Vector2]_TextTimeScale ("Scale", Vector) = (1, 1, 1, 1)
		[VectorLabel(L, D, R, U)]_TextTimePadding ("Padding Reduction", Vector) = (0, 0, 0, 0)
		[HideInInspector] m_end_TextInstanceTime ("Instance Time", Float) = 0
		
		// NUMERIC OVERLAY
		[HideInInspector] m_start_TextNumeric ("Numeric (WIP)--{reference_property:_TextNumericEnabled}", Float) = 0
		[HideInInspector][ToggleUI]_TextNumericEnabled ("Numeric Text", Float) = 0
		[ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _TextNumericUV ("Numeric UV", Int) = 0
		_TextNumericColor ("Color--{reference_property:_TextNumericColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _TextNumericColorThemeIndex ("", Int) = 0
		_TextNumericValue ("Display Value", Float) = 0
		[IntRange]_TextNumericWholeDigits ("Whole Digits", Range(0, 4)) = 4
		[IntRange]_TextNumericDecimalDigits ("Decimal Digits", Range(0, 4)) = 0
		[ToggleUI]_TextNumericTrimZeroes ("Trim Leading Zeroes", Float) = 0
		_TextNumericEmissionStrength ("Emission Strength", Range(0, 20)) = 0
		[Vector2]_TextNumericOffset ("Offset", Vector) = (0, 0, 0, 0)
		_TextNumericRotation ("Rotation", Range(0, 360)) = 0
		[Vector2]_TextNumericScale ("Scale", Vector) = (1, 1, 1, 1)
		[VectorLabel(L, D, R, U)]_TextNumericPadding ("Padding Reduction", Vector) = (0, 0, 0, 0)
		[HideInInspector] m_end_TextNumeric ("Numeric", Float) = 0
		
		[HideInInspector] m_end_Text ("MSDF Text Overlay", Float) = 0
		//endex
		
		//ifex _FXProximityColor==0
		[HideInInspector] m_start_FXProximityColor ("Proximity Color--{reference_property:_FXProximityColor,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/special-fx/proximity-color},hover:Documentation}}", Float) = 0
		[HideInInspector][ToggleUI]_FXProximityColor ("Enable", Float) = 0
		[Enum(Object Position, 0, Pixel Position, 1)]_FXProximityColorType ("Pos To Use", Int) = 1
		_FXProximityColorMinColor ("Min Color", Color) = (0, 0, 0)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _FXProximityColorMinColorThemeIndex ("", Int) = 0
		_FXProximityColorMaxColor ("Max Color", Color) = (1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _FXProximityColorMaxColorThemeIndex ("", Int) = 0
		_FXProximityColorMinDistance ("Min Distance", Float) = 0
		_FXProximityColorMaxDistance ("Max Distance", Float) = 1
		[ToggleUI]_FXProximityColorBackFace ("Force BackFace Color", Float) = 0
		[HideInInspector] m_end_FXProximityColor ("", Float) = 0
		//endex
		
		//ifex _PoiInternalParallax==0
		[HideInInspector] m_start_internalparallax (" Internal Parallax--{reference_property:_PoiInternalParallax}", Float) = 0
		[HideInInspector][ThryToggle(POI_INTERNALPARALLAX)]_PoiInternalParallax ("Enable", Float) = 0
		
		[Enum(Basic, 0, HeightMap, 1)] _ParallaxInternalHeightmapMode ("Parallax Mode", Int) = 0
		
		[ThryRGBAPacker(RGB Color, A Height, sRGB, false)][sRGBWarning(true)]_ParallaxInternalMap ("Internal Map--{reference_properties:[_ParallaxInternalMapPan, _ParallaxInternalPanDepthSpeed, _ParallaxInternalHeightFromAlpha]}", 2D) = "black" { }
		[HideInInspector][Vector2]_ParallaxInternalMapPan ("Panning", Vector) = (0, 0, 1, 1)
		[HideInInspector][Vector2]_ParallaxInternalPanDepthSpeed ("Per Level Pan Multiplier", Vector) = (0, 0, 1, 1)
		[HideInInspector][ToggleUI]_ParallaxInternalHeightFromAlpha ("Height From Alpha", Float) = 0
		
		[sRGBWarning][ThryTexture]_ParallaxInternalMapMask ("Mask--{reference_properties:[_ParallaxInternalMapMaskPan, _ParallaxInternalMapMaskUV, _ParallaxInternalMapMaskChannel]}", 2D) = "white" { }
		[HideInInspector][Vector2]_ParallaxInternalMapMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, distorteduv0, 4)] _ParallaxInternalMapMaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_ParallaxInternalMapMaskChannel ("Channel", Float) = 0
		
		[HideInInspector] s_start_ParallaxInternalLayerControls ("Layer Controls--{persistent_expand:true,default_expand:true}", Float) = 1
		[IntRange]_ParallaxInternalIterations ("Parallax Internal Iterations", Range(1, 50)) = 4
		_ParallaxInternalMinDepth ("Min Depth", Float) = 0
		_ParallaxInternalMaxDepth ("Max Depth", Float) = 0.1
		[HideInInspector] s_end_ParallaxInternalLayerControls ("", Float) = 0
		
		[HideInInspector] s_start_ParallaxInternalLayerColoring ("Layer Colors--{persistent_expand:true,default_expand:true}", Float) = 1
		_ParallaxInternalMinFade ("Min Depth Brightness", Range(0, 5)) = 1.0
		_ParallaxInternalMaxFade ("Max Depth Brightness", Range(0, 5)) = 0.1
		_ParallaxInternalMinColor ("Min Depth Color--{reference_property:_ParallaxInternalMinColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _ParallaxInternalMinColorThemeIndex ("", Int) = 0
		_ParallaxInternalMaxColor ("Max Depth Color--{reference_property:_ParallaxInternalMaxColorThemeIndex}", Color) = (1, 1, 1, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _ParallaxInternalMaxColorThemeIndex ("", Int) = 0
		[Enum(Add, 0, Max, 1)] _ParallaxInternalBlendMode ("Internal Blend Mode", Int) = 0
		[ThryWideEnum(Replace, 0, Darken, 1, Multiply, 2, Lighten, 5, Screen, 6, Subtract, 7, Add, 8, Overlay, 9, Mixed, 20)] _ParallaxInternalSurfaceBlendMode ("Surface Blend Mode", Int) = 8
		[HideInInspector] s_end_ParallaxInternalLayerColoring ("", Float) = 0
		// [Vector2]_ParallaxInternalPanSpeed ("Pan Speed", Vector) = (0, 0, 0, 0)
		
		[HideInInspector] s_start_ParallaxInternalHueShift ("Hue Shift--{reference_property:_ParallaxInternalHueShiftEnabled,persistent_expand:true,default_expand:false}", Float) = 0
		[HideInInspector][ToggleUI]_ParallaxInternalHueShiftEnabled ("Hue Shift", Float) = 0
		_ParallaxInternalHueShift ("Hue Shift", Range(0, 1)) = 0
		_ParallaxInternalHueShiftSpeed ("Hue Shift Speed", Float) = 0
		_ParallaxInternalHueShiftPerLevel ("Hue Shift Per Level", Float) = 0
		[HideInInspector] s_end_ParallaxInternalHueShift ("", Float) = 0
		// _ParallaxInternalHueShiftPerLevelSpeed ("Hue Shift Per Level Speed", Float) = 0
		
		[HideInInspector] m_end_internalparallax ("Internal Parallax", Float) = 0
		//endex
		
		//ifex _VideoEffectsEnable==0
		[HideInInspector] m_start_videoEffects ("Video Effects--{reference_property:_VideoEffectsEnable}", Float) = 0
		[HideInInspector][ThryToggle(POI_VIDEO_EFFECTS)]_VideoEffectsEnable ("Enable VideoEffects", Float) = 0
		[Enum(LCD, 0, TN, 1, CRT, 2, OLED, 3, Gameboy, 4, Projector, 5)] _VideoType ("Screen Type", Int) = 3
		_VideoBacklight ("Brightness", Range(0, 100)) = 1
		[ToggleUI]_VideoEmissionEnabled ("Emission Enabled", Float) = 1
		_VideoPixelTexture ("Pixel Texture--{reference_properties:[_VideoPixelTextureUV]}", 2D) = "white" { }
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)]_VideoPixelTextureUV ("UV", Int) = 0
		[sRGBWarning]_VideoMaskTexture ("Mask--{reference_properties:[_VideoMaskTexturePan, _VideoMaskTextureUV, _VideoMaskTextureChannel]}", 2D) = "white" { }
		[HideInInspector][Vector2]_VideoMaskTexturePan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_VideoMaskTextureUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_VideoMaskTextureChannel ("Channel", Float) = 0
		[HideInInspector] m_start_VideoSettings ("Video Texture Settings", Float) = 0
		[Vector2]_VideoResolution ("Resolution", Vector) = (1280, 720, 0, 0)
		[ToggleUI]_VideoPixelateToResolution ("Pixelate To Resolution", Float) = 0
		// [ToggleUI]_VideoRepeatVideoTexture ("Clamp To UV", Float) = 0
		_VideoSaturation ("Saturation", Range(-1, 3)) = 0
		_VideoContrast ("Contrast boost", Range(0, 3)) = 0
		
		[HideInInspector] m_end_VideoSettings ("Video Texture Settings", Float) = 0
		
		[HideInInspector] m_start_CRT ("CRT Options--{condition_showS:(_VideoType==2)}", Float) = 0
		_VideoCRTRefreshRate ("Refresh Rate", Float) = 24
		_VideoCRTPixelEnergizedTime ("Pixel Fade Time", Float) = 1.9
		[HideInInspector] m_end_CRT ("CRT Options", Float) = 0
		
		[HideInInspector] m_start_Gameboy ("Gameboy Options--{condition_showS:(_VideoType==4)}", Float) = 0
		[sRGBWarning(true)][Gradient]_VideoGameboyRamp ("Color Ramp", 2D) = "white" { }
		[HideInInspector] m_end_Gameboy ("Gameboy Options", Float) = 0
		
		[HideInInspector] m_end_videoEffects ("Video Effects", Float) = 0
		//endex
		
		//ifex _VoronoiEnabled!=1
		[HideInInspector] m_start_voronoi ("Voronoi--{reference_property:_VoronoiEnabled}", Int) = 0
		[HideInInspector][ThryToggle(POI_VORONOI)]_VoronoiEnabled ("Voronoi Enabled", Int) = 0
		[Enum(2D(Fast), 0, 3D(Fast with color bugs), 1, 3D(slow but no bugs), 2)] _VoronoiType ("Type", Int) = 1
		[Enum(Local, 0, World, 1, UV, 2)] _VoronoiSpace ("Space", Int) = 0
		[Enum(Color and Emission, 0, Just Emission, 1)] _VoronoiBlend ("Blend", Int) = 0
		[ToggleUI]_VoronoiAffectsMaterialAlpha ("Affects Material Alpha", Int) = 0
		
		[sRGBWarning] _VoronoiMask ("Mask--{reference_properties:[_VoronoiMaskPan, _VoronoiMaskUV, _VoronoiMaskChannel]}", 2D) = "white" { }
		[HideInInspector][Vector2] _VoronoiMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _VoronoiMaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)] _VoronoiMaskChannel ("Channel", Int) = 0
		
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _VoronoiGlobalMask ("Global Mask--{reference_property:_VoronoiGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _VoronoiGlobalMaskBlendType ("Blending", Int) = 2
		
		[sRGBWarning] _VoronoiNoise ("Noise--{reference_properties:[_VoronoiNoisePan, _VoronoiNoiseUV, _VoronoiNoiseChannel]}", 2D) = "black" { }
		[HideInInspector][Vector2] _VoronoiNoisePan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _VoronoiNoiseUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)] _VoronoiNoiseChannel ("Channel", Int) = 0
		
		_VoronoiNoiseIntensity ("Noise Intensity", Range(0, 1)) = .1
		_VoronoiOuterColor ("Outer Color", Color) = (0, 0, 0, 1)
		_VoronoiOuterEmissionStrength ("Outer Emission", Range(0, 20)) = 0
		_VoronoiInnerColor ("Inner Color", Color) = (1, 1, 1, 1)
		_VoronoiInnerEmissionStrength ("Inner Emission", Range(0, 20)) = 0
		[Vector2]_VoronoiGradient ("Gradient", Vector) = (0, 0.5, 0, 0)
		_VoronoiPower ("Power", Float) = 0.45454545
		_VoronoiScale ("Scale", Float) = 5.0
		[Vector3]_VoronoiSpeed ("Speed", Vector) = (1.0, 1.0, 1.0)
		
		[HideInInspector] m_start_voronoiRandom ("Voronoi Random Cell Color--{reference_property:_VoronoiEnableRandomCellColor}", Int) = 0
		[HideInInspector][ToggleUI]_VoronoiEnableRandomCellColor ("Rando Cell Col", Int) = 0
		[MultiSlider]_VoronoiRandomMinMaxSaturation ("Saturation Range", Vector) = (0.8, 1, 0, 1)
		[MultiSlider]_VoronoiRandomMinMaxBrightness ("Brightness Range", Vector) = (0.8, 1, 0, 1)
		[HideInInspector] m_end_voronoiRandom ("Voronoi Random Cell Color", Float) = 0
		
		[HideInInspector] m_start_VoronoiAudioLink ("Audio Link ♫--{condition_showS:_EnableAudioLink==1}", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkVoronoiInnerEmissionBand ("Inner Emission Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkVoronoiInnerEmission ("Inner Emission Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkVoronoiOuterEmissionBand ("Outer Emission Band", Int) = 0
		[VectorLabel(Min, Max)]_AudioLinkVoronoiOuterEmission ("Outer Emission Mod", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkVoronoiGradientMinAddBand ("Gradient Min Band", Int) = 0
		_AudioLinkVoronoiGradientMinAdd ("Gradient Min Add", Float) = 0
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkVoronoiGradientMaxAddBand ("Gradient Max Band", Int) = 0
		_AudioLinkVoronoiGradientMaxAdd ("Gradient Max Add", Float) = 0
		[Space(7)]
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_AudioLinkVoronoiChronoSpeedXType ("Speed X Motion Type", Int) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkVoronoiChronoSpeedXBand ("Speed X Band", Int) = 0
		_AudioLinkVoronoiChronoSpeedXSpeed ("Speed X", Float) = 0
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_AudioLinkVoronoiChronoSpeedYType ("Speed Y Motion Type", Int) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkVoronoiChronoSpeedYBand ("Speed Y Band", Int) = 0
		_AudioLinkVoronoiChronoSpeedYSpeed ("Speed Y", Float) = 0
		[ThryWideEnum(Motion increases as intensity of band increases, 0, Above but Smooth, 1, Motion moves back and forth as a function of intensity, 2, Above but Smoooth, 3, Fixed speed increase when the band is dark Stationary when light, 4, Above but Smooooth, 5, Fixed speed increase when the band is dark Fixed speed decrease when light, 6, Above but Smoooooth, 7)]_AudioLinkVoronoiChronoSpeedZType ("Speed Z Motion Type", Int) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _AudioLinkVoronoiChronoSpeedZBand ("Speed Z Band", Int) = 0
		_AudioLinkVoronoiChronoSpeedZSpeed ("Speed Z", Float) = 0
		[HideInInspector] m_end_VoronoiAudioLink ("Audio Link", Float) = 0
		
		[HideInInspector] m_end_voronoi ("Voronoi", Float) = 0
		//endex
		
		//ifex _EnableAudioLink==0
		[HideInInspector] m_AudioLinkCategory (" Audio Link--{reference_property:_EnableAudioLink}", Float) = 0
		[HideInInspector] m_start_audioLink ("Audio Link", Float) = 0
		[HideInInspector][ThryToggle(POI_AUDIOLINK)] _EnableAudioLink ("Enabled", Float) = 0
		[Helpbox(1)] _AudioLinkHelp ("This section houses the global controls for audio link. Controls for individual features are in their respective sections. (Emission, Dissolve, etc...)", Int) = 0
		[ToggleUI] _AudioLinkAnimToggle ("Anim Toggle", Float) = 1
		/*
		_AudioLinkDelay ("Delay", Range(0, 1)) = 0
		[ToggleUI]_AudioLinkCCStripY ("CC Strip Y UV", Float) = 0
		*/
		[ThryHeaderLabel(Smoothing)]
		_AudioLinkSmoothingBass ("Bass", Range(0, 1)) = 0
		_AudioLinkSmoothingLowMid ("Low Mid", Range(0, 1)) = 0
		_AudioLinkSmoothingHighMid ("High Mid", Range(0, 1)) = 0
		_AudioLinkSmoothingTreble ("Treble", Range(0, 1)) = 0
		[HideInInspector] m_end_audioLink ("Audio Link", Float) = 0
		
		[HideInInspector] m_start_audioLinkOverrides ("Overrides", Float) = 0
		[HideInInspector] s_start_AudioLinkBandOverrides ("Band Overrides--{reference_property:_AudioLinkBandOverridesEnabled,persistent_expand:true,default_expand:true}", Float) = 1
		[HideInInspector][ToggleUI] _AudioLinkBandOverridesEnabled ("Band Overrides", Float) = 0
		[VectorToSliders(Bass, 0, 1, Low Mid, 0, 1, High Mid, 0, 1, Treble, 0, 1)]_AudioLinkBandOverrideSliders ("Band Override Sliders", Vector) = (0, 0, 0, 0)
		[HideInInspector] s_end_AudioLinkBandOverrides ("Audio Link", Float) = 0
		[HideInInspector] m_end_audioLinkOverrides ("Overrides", Float) = 0
		//endex
		//ifex _EnableALDecal==0
		[HideInInspector] m_start_ALDecalSpectrum ("AL ♫ Spectrum--{  reference_property:_EnableALDecal}", Float) = 0
		[HideInInspector][ThryToggle(POI_AL_DECAL)]_EnableALDecal ("Enable AL Decal", Float) = 0
		[HideInInspector][ThryWideEnum(lil Spectrum, 0)] _ALDecalType ("AL Type--{ condition_showS:_EnableAudioLink==1}", Int) = 0
		
		[ThryHeaderLabel(Transform, 13)]
		[Space(4)]
		[Enum(Normal, 0, Circle, 1)] _ALDecalUVMode ("UV Mode", Float) = 0
		[ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _ALDecalUV ("UV", Int) = 0
		[Vector2]_ALUVPosition ("Position", Vector) = (.5, .5, 1)
		_ALUVScale ("Scale", Vector) = (1, 1, 1, 1)
		_ALUVRotation ("Rotation", Range(0, 360)) = 0
		_ALUVRotationSpeed ("Rotation Speed", Float) = 0
		_ALDecalLineWidth ("Line Width", Range(0, 1)) = 1.0
		_ALDecaldCircleDimensions ("Cirlce Dimensions--{ condition_showS:_ALDecalUVMode==1}", Vector) = (0, 1, 0, 1)
		
		[Space][ThryHeaderLabel(Volume, 13)]
		[Space(4)]
		_ALDecalVolumeStep ("Volume Step Num (0 = Off)", Float) = 0.0
		_ALDecalVolumeClipMin ("Volume Clip Min", Range(0, 1)) = 0.0
		_ALDecalVolumeClipMax ("Volume Clip Max", Range(0, 1)) = 1.0
		
		[Space][ThryHeaderLabel(Band, 13)]
		[Space(4)]
		_ALDecalBandStep ("Band Step Num (0 = Off)", Float) = 0.0
		_ALDecalBandClipMin ("Band Clip Min", Range(0, 1)) = 0.0
		_ALDecalBandClipMax ("Band Clip Max", Range(0, 1)) = 1.0
		
		[Space][ThryToggleUI(true)]_ALDecalShapeClip ("<size=13><b>  Shape Clip</b></size>", Float) = 0
		_ALDecalShapeClipVolumeWidth ("Volume Width--{ condition_showS:_ALDecalShapeClip==1}", Range(0, 1)) = 0.5
		_ALDecalShapeClipBandWidth ("Band Width--{ condition_showS:_ALDecalShapeClip==1}", Range(0, 1)) = 0.5
		
		[Space][ThryHeaderLabel(Audio Mods, 13)]
		[Space(4)]
		_ALDecalVolume ("Volume", Int) = 0.5
		_ALDecalBaseBoost ("Bass Boost", Float) = 5.0
		_ALDecalTrebleBoost ("Treble Boost", Float) = 1.0
		
		[Space][ThryHeaderLabel(Colors and Blending, 13)]
		[Space(4)]
		[sRGBWarning(true)][ThryRGBAPacker(RGB Color, A Mask, sRGB, false)]_ALDecalColorMask ("Color & Mask--{reference_properties:[_ALDecalColorMaskPan, _ALDecalColorMaskUV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_ALDecalColorMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)] _ALDecalColorMaskUV ("UV", Int) = 0
		[Enum(UVX, 0, UVY, 1, Volume, 2)] _ALDecalVolumeColorSource ("Source", Int) = 1
		_ALDecalVolumeColorLow ("Volume Color Low--{reference_property:_ALDecalVolumeColorLowThemeIndex}", Color) = (0, 0, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _ALDecalVolumeColorLowThemeIndex ("", Int) = 0
		_ALDecalLowEmission ("Low Emission", Range(0, 20)) = 0
		_ALDecalVolumeColorMid ("Volume Color Mid--{reference_property:_ALDecalVolumeColorMidThemeIndex}", Color) = (0, 1, 0)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _ALDecalVolumeColorMidThemeIndex ("", Int) = 0
		_ALDecalMidEmission ("Mid Emission", Range(0, 20)) = 0
		_ALDecalVolumeColorHigh ("Volume Color High--{reference_property:_ALDecalVolumeColorHighThemeIndex}", Color) = (1, 0, 0)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _ALDecalVolumeColorHighThemeIndex ("", Int) = 0
		_ALDecalHighEmission ("High Emission", Range(0, 20)) = 0
		[ThryWideEnum(Replace, 0, Darken, 1, Multiply, 2, Lighten, 5, Screen, 6, Subtract, 7, Add, 8, Overlay, 9, Mixed, 20)]_ALDecalBlendType ("Blend Type", Range(0, 1)) = 0
		_ALDecalBlendAlpha ("Alpha", Range(0, 1)) = 1
		_ALDecalControlsAlpha ("Override Alpha", Range(0, 1)) = 0
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _ALDecalGlobalMask ("Global Mask--{reference_property:_ALDecalGlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _ALDecalGlobalMaskBlendType ("Blending", Int) = 2
		[HideInInspector] m_end_ALDecalSpectrum ("AL ♫ Spectrum", Float) = 0
		//endex
		
		//ifex _EnableVolumeColor==0
		[HideInInspector] m_start_ALVolumeColor ("AL ♫ Volume Color--{  reference_property:_EnableVolumeColor}", Float) = 0
		[HideInInspector][ThryToggle(POI_AL_VOLUMECOLOR)]_EnableVolumeColor ("Enable AL Volume Color", Float) = 0
		[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)] _ALVolumeColorUV ("UV", Int) = 0
		[Enum(X, 0, Y, 1)] _ALVolumeColorDirection ("UV Direction", Int) = 0
		[ThryWideEnum(Replace, 0, Darken, 1, Multiply, 2, Lighten, 5, Screen, 6, Subtract, 7, Add, 8, Overlay, 9, Mixed, 20)]_ALVolumeColorBlendType ("Blend Type", Range(0, 1)) = 0
		
		_ALVolumeColorBlendAlpha ("Alpha", Range(0,1)) = 1
		_ALVolumeColorLow ("Volume Color Low--{reference_property:_ALVolumeColorLowThemeIndex}", Color) = (0, 0, 1)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _ALVolumeColorLowThemeIndex ("", Int) = 0
		_ALLowEmission ("Low Emission", Range(0, 20)) = 0
		_ALVolumeColorMid ("Volume Color Mid--{reference_property:_ALVolumeColorMidThemeIndex}", Color) = (0, 1, 0)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _ALVolumeColorMidThemeIndex ("", Int) = 0
		_ALMidEmission ("Mid Emission", Range(0, 20)) = 0
		_ALVolumeColorHigh ("Volume Color High--{reference_property:_ALVolumeColorHighThemeIndex}", Color) = (1, 0, 0)
		[HideInInspector][ThryWideEnum(Off, 0, Theme Color 0, 1, Theme Color 1, 2, Theme Color 2, 3, Theme Color 3, 4, ColorChord 0, 5, ColorChord 1, 6, ColorChord 2, 7, ColorChord 3, 8, AL Theme 0, 9, AL Theme 1, 10, AL Theme 2, 11, AL Theme 3, 12)] _ALVolumeColorHighThemeIndex ("", Int) = 0
		_ALHighEmission ("High Emission", Range(0, 20)) = 0
		
		[HideInInspector] m_end_ALVolumeColor ("AL ♫ Volume Color", Float) = 0
		//endex
		
		[HideInInspector] m_modifierCategory ("Global Modifiers & Data", Float) = 0
		[HideInInspector] m_start_PoiGlobalCategory ("Global Data and Masks", Float) = 0
		//ifex _BlackLightMaskingEnabled==0
		[HideInInspector] m_start_BlackLightMasking ("BlackLight Masking--{reference_property:_BlackLightMaskingEnabled}", Float) = 0
		[HideInInspector][ThryToggle(POI_BLACKLIGHTMASKING)] _BlackLightMaskingEnabled ("BlackLight Masking Enabled", Float) = 0
		
		[ThryHeaderLabel(One, 13)]
		_BlackLightMasking0Key ("Key", Float) = 1
		[Vector2] _BlackLightMasking0Range ("Range", Vector) = (0.1, 0.5, 0, 0)
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _BlackLightMasking0GlobalMaskIndex ("Apply to Global Mask--{reference_property:_BlackLightMasking0GlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_BlackLightMasking0GlobalMaskBlendType ("Blending", Range(0, 1)) = 0
		[Space(4)]
		[ThryHeaderLabel(Two, 13)]
		_BlackLightMasking1Key ("Key", Float) = 2
		[Vector2] _BlackLightMasking1Range ("Range", Vector) = (0.1, 0.5, 0, 0)
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _BlackLightMasking1GlobalMaskIndex ("Apply to Global Mask--{reference_property:_BlackLightMasking1GlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_BlackLightMasking1GlobalMaskBlendType ("Blending", Range(0, 1)) = 0
		[Space(4)]
		[ThryHeaderLabel(Three, 13)]
		_BlackLightMasking2Key ("Key", Float) = 3
		[Vector2] _BlackLightMasking2Range ("Range", Vector) = (0.1, 0.5, 0, 0)
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _BlackLightMasking2GlobalMaskIndex ("Apply to Global Mask--{reference_property:_BlackLightMasking2GlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_BlackLightMasking2GlobalMaskBlendType ("Blending", Range(0, 1)) = 0
		[Space(4)]
		[ThryHeaderLabel(Four, 13)]
		_BlackLightMasking3Key ("Key", Float) = 4
		[Vector2] _BlackLightMasking3Range ("Range", Vector) = (0.1, 0.5, 0, 0)
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _BlackLightMasking3GlobalMaskIndex ("Apply to Global Mask--{reference_property:_BlackLightMasking3GlobalMaskBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)]_BlackLightMasking3GlobalMaskBlendType ("Blending", Range(0, 1)) = 0
		
		[HideInInspector] m_end_BlackLightMasking ("BlackLight Masking", Float) = 0
		//endex
		
		[HideInInspector] m_start_GlobalThemes ("Global Themes--{button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/color-and-normals/global-themes},hover:Documentation}}", Float) = 0
		[HideInInspector] m_start_GlobalThemeColor0 ("Theme Color 0", Float) = 0
		[HDR]_GlobalThemeColor0 ("Theme Color 0",       Color       ) = (1, 1, 1, 1)
		_GlobalThemeHue0        ("Hue Adjust",          Range( 0, 1)) = 0
		_GlobalThemeHueSpeed0   ("Hue Adjust Speed",    Float       ) = 0
		_GlobalThemeSaturation0 ("Saturation Adjust",   Range(-1, 1)) = 0
		_GlobalThemeValue0      ("Value Adjust",        Range(-1, 1)) = 0
		[HideInInspector] m_end_GlobalThemeColor0   ("Theme Color 0", Float) = 0
		[HideInInspector] m_start_GlobalThemeColor1 ("Theme Color 1", Float) = 0
		[HDR]_GlobalThemeColor1 ("Theme Color 1",       Color       ) = (1, 1, 1, 1)
		_GlobalThemeHue1        ("Hue Adjust",          Range( 0, 1)) = 0
		_GlobalThemeHueSpeed1   ("Hue Adjust Speed",    Float       ) = 0
		_GlobalThemeSaturation1 ("Saturation Adjust",   Range(-1, 1)) = 0
		_GlobalThemeValue1      ("Value Adjust",        Range(-1, 1)) = 0
		[HideInInspector] m_end_GlobalThemeColor1   ("Theme Color 1", Float) = 0
		[HideInInspector] m_start_GlobalThemeColor2 ("Theme Color 2", Float) = 0
		[HDR]_GlobalThemeColor2 ("Theme Color 2",       Color       ) = (1, 1, 1, 1)
		_GlobalThemeHue2        ("Hue Adjust",          Range( 0, 1)) = 0
		_GlobalThemeHueSpeed2   ("Hue Adjust Speed",    Float       ) = 0
		_GlobalThemeSaturation2 ("Saturation Adjust",   Range(-1, 1)) = 0
		_GlobalThemeValue2      ("Value Adjust",        Range(-1, 1)) = 0
		[HideInInspector] m_end_GlobalThemeColor2   ("Theme Color 2", Float) = 0
		[HideInInspector] m_start_GlobalThemeColor3 ("Theme Color 3", Float) = 0
		[HDR]_GlobalThemeColor3 ("Theme Color 3",       Color       ) = (1, 1, 1, 1)
		_GlobalThemeHue3        ("Hue Adjust",          Range( 0, 1)) = 0
		_GlobalThemeHueSpeed3   ("Hue Adjust Speed",    Float       ) = 0
		_GlobalThemeSaturation3 ("Saturation Adjust",   Range(-1, 1)) = 0
		_GlobalThemeValue3      ("Value Adjust",        Range(-1, 1)) = 0
		[HideInInspector] m_end_GlobalThemeColor3   ("Theme Color 3", Float) = 0
		[HideInInspector] m_end_GlobalThemes ("Global Themes", Float ) = 0
		
		[HideInInspector] m_start_GlobalMask ("Global Mask", Float) = 0
		
		//ifex _GlobalMaskTexturesEnable==0
		[HideInInspector] m_start_GlobalMaskTextures ("Textures--{reference_property:_GlobalMaskTexturesEnable}", Float) = 0
		[HideInInspector][ThryToggle(POI_GLOBALMASK_TEXTURES)] _GlobalMaskTexturesEnable ("Global Mask Textures Enable", Float) = 0
		
		[sRGBWarning][ThryRGBAPacker(R, G, B, A, linear, false)]_GlobalMaskTexture0 ("Global Mask Texture 1--{reference_properties:[_GlobalMaskTexture0Pan, _GlobalMaskTexture0SplitTilingOffset_G, _GlobalMaskTexture0SplitPan_G, _GlobalMaskTexture0SplitTilingOffset_B, _GlobalMaskTexture0SplitPan_B, _GlobalMaskTexture0SplitTilingOffset_A, _GlobalMaskTexture0SplitPan_A, _GlobalMaskTexture0Split, _GlobalMaskTexture0UV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_GlobalMaskTexture0Pan ("Panning", Vector) = (0, 0, 0, 0)
		[ThryHeaderLabel(G Channel)]
		[HideInInspector][VectorLabel(tX, tY, oX, oY)]_GlobalMaskTexture0SplitTilingOffset_G ("Tiling/Offset--{condition_showS:(_GlobalMaskTexture0Split==1)}", Vector) = (1, 1, 0, 0)
		[HideInInspector][Vector2]_GlobalMaskTexture0SplitPan_G ("Panning--{condition_showS:(_GlobalMaskTexture0Split==1)}", Vector) = (0, 0, 0, 0)
		[ThryHeaderLabel(B Channel)]
		[HideInInspector][VectorLabel(tX, tY, oX, oY)]_GlobalMaskTexture0SplitTilingOffset_B ("Tiling/Offset--{condition_showS:(_GlobalMaskTexture0Split==1)}", Vector) = (1, 1, 0, 0)
		[HideInInspector][Vector2]_GlobalMaskTexture0SplitPan_B ("Panning--{condition_showS:(_GlobalMaskTexture0Split==1)}", Vector) = (0, 0, 0, 0)
		[ThryHeaderLabel(A Channel)]
		[HideInInspector][VectorLabel(tX, tY, oX, oY)]_GlobalMaskTexture0SplitTilingOffset_A ("Tiling/Offset--{condition_showS:(_GlobalMaskTexture0Split==1)}", Vector) = (1, 1, 0, 0)
		[HideInInspector][Vector2]_GlobalMaskTexture0SplitPan_A ("Panning--{condition_showS:(_GlobalMaskTexture0Split==1)}", Vector) = (0, 0, 0, 0)
		[HideInInspector][ToggleUI] _GlobalMaskTexture0Split ("Split Sampling", Int) = 0
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_GlobalMaskTexture0UV ("UV", Int) = 0
		
		[sRGBWarning][ThryRGBAPacker(R, G, B, A, linear, false)]_GlobalMaskTexture1 ("Global Mask Texture 2--{reference_properties:[_GlobalMaskTexture1Pan, _GlobalMaskTexture1SplitTilingOffset_G, _GlobalMaskTexture1SplitPan_G, _GlobalMaskTexture1SplitTilingOffset_B, _GlobalMaskTexture1SplitPan_B, _GlobalMaskTexture1SplitTilingOffset_A, _GlobalMaskTexture1SplitPan_A, _GlobalMaskTexture1Split, _GlobalMaskTexture1UV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_GlobalMaskTexture1Pan ("Panning", Vector) = (0, 0, 0, 0)
		[ThryHeaderLabel(G Channel)]
		[HideInInspector][VectorLabel(tX, tY, oX, oY)]_GlobalMaskTexture1SplitTilingOffset_G ("Tiling/Offset--{condition_showS:(_GlobalMaskTexture1Split==1)}", Vector) = (1, 1, 0, 0)
		[HideInInspector][Vector2]_GlobalMaskTexture1SplitPan_G ("Panning--{condition_showS:(_GlobalMaskTexture1Split==1)}", Vector) = (0, 0, 0, 0)
		[ThryHeaderLabel(B Channel)]
		[HideInInspector][VectorLabel(tX, tY, oX, oY)]_GlobalMaskTexture1SplitTilingOffset_B ("Tiling/Offset--{condition_showS:(_GlobalMaskTexture1Split==1)}", Vector) = (1, 1, 0, 0)
		[HideInInspector][Vector2]_GlobalMaskTexture1SplitPan_B ("Panning--{condition_showS:(_GlobalMaskTexture1Split==1)}", Vector) = (0, 0, 0, 0)
		[ThryHeaderLabel(A Channel)]
		[HideInInspector][VectorLabel(tX, tY, oX, oY)]_GlobalMaskTexture1SplitTilingOffset_A ("Tiling/Offset--{condition_showS:(_GlobalMaskTexture1Split==1)}", Vector) = (1, 1, 0, 0)
		[HideInInspector][Vector2]_GlobalMaskTexture1SplitPan_A ("Panning--{condition_showS:(_GlobalMaskTexture1Split==1)}", Vector) = (0, 0, 0, 0)
		[HideInInspector][ToggleUI] _GlobalMaskTexture1Split ("Split Sampling", Int) = 0
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_GlobalMaskTexture1UV ("UV", Int) = 0
		
		[sRGBWarning][ThryRGBAPacker(R, G, B, A, linear, false)]_GlobalMaskTexture2 ("Global Mask Texture 3--{reference_properties:[_GlobalMaskTexture2Pan, _GlobalMaskTexture2SplitTilingOffset_G, _GlobalMaskTexture2SplitPan_G, _GlobalMaskTexture2SplitTilingOffset_B, _GlobalMaskTexture2SplitPan_B, _GlobalMaskTexture2SplitTilingOffset_A, _GlobalMaskTexture2SplitPan_A, _GlobalMaskTexture2Split, _GlobalMaskTexture2UV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_GlobalMaskTexture2Pan ("Panning", Vector) = (0, 0, 0, 0)
		[ThryHeaderLabel(G Channel)]
		[HideInInspector][VectorLabel(tX, tY, oX, oY)]_GlobalMaskTexture2SplitTilingOffset_G ("Tiling/Offset--{condition_showS:(_GlobalMaskTexture2Split==1)}", Vector) = (1, 1, 0, 0)
		[HideInInspector][Vector2]_GlobalMaskTexture2SplitPan_G ("Panning--{condition_showS:(_GlobalMaskTexture2Split==1)}", Vector) = (0, 0, 0, 0)
		[ThryHeaderLabel(B Channel)]
		[HideInInspector][VectorLabel(tX, tY, oX, oY)]_GlobalMaskTexture2SplitTilingOffset_B ("Tiling/Offset--{condition_showS:(_GlobalMaskTexture2Split==1)}", Vector) = (1, 1, 0, 0)
		[HideInInspector][Vector2]_GlobalMaskTexture2SplitPan_B ("Panning--{condition_showS:(_GlobalMaskTexture2Split==1)}", Vector) = (0, 0, 0, 0)
		[ThryHeaderLabel(A Channel)]
		[HideInInspector][VectorLabel(tX, tY, oX, oY)]_GlobalMaskTexture2SplitTilingOffset_A ("Tiling/Offset--{condition_showS:(_GlobalMaskTexture2Split==1)}", Vector) = (1, 1, 0, 0)
		[HideInInspector][Vector2]_GlobalMaskTexture2SplitPan_A ("Panning--{condition_showS:(_GlobalMaskTexture2Split==1)}", Vector) = (0, 0, 0, 0)
		[HideInInspector][ToggleUI] _GlobalMaskTexture2Split ("Split Sampling", Int) = 0
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_GlobalMaskTexture2UV ("UV", Int) = 0
		
		[sRGBWarning][ThryRGBAPacker(R, G, B, A, linear, false)]_GlobalMaskTexture3 ("Global Mask Texture 4--{reference_properties:[_GlobalMaskTexture3Pan, _GlobalMaskTexture3SplitTilingOffset_G, _GlobalMaskTexture3SplitPan_G, _GlobalMaskTexture3SplitTilingOffset_B, _GlobalMaskTexture3SplitPan_B, _GlobalMaskTexture3SplitTilingOffset_A, _GlobalMaskTexture3SplitPan_A, _GlobalMaskTexture3Split, _GlobalMaskTexture3UV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_GlobalMaskTexture3Pan ("Panning", Vector) = (0, 0, 0, 0)
		[ThryHeaderLabel(G Channel)]
		[HideInInspector][VectorLabel(tX, tY, oX, oY)]_GlobalMaskTexture3SplitTilingOffset_G ("Tiling/Offset--{condition_showS:(_GlobalMaskTexture3Split==1)}", Vector) = (1, 1, 0, 0)
		[HideInInspector][Vector2]_GlobalMaskTexture3SplitPan_G ("Panning--{condition_showS:(_GlobalMaskTexture3Split==1)}", Vector) = (0, 0, 0, 0)
		[ThryHeaderLabel(B Channel)]
		[HideInInspector][VectorLabel(tX, tY, oX, oY)]_GlobalMaskTexture3SplitTilingOffset_B ("Tiling/Offset--{condition_showS:(_GlobalMaskTexture3Split==1)}", Vector) = (1, 1, 0, 0)
		[HideInInspector][Vector2]_GlobalMaskTexture3SplitPan_B ("Panning--{condition_showS:(_GlobalMaskTexture3Split==1)}", Vector) = (0, 0, 0, 0)
		[ThryHeaderLabel(A Channel)]
		[HideInInspector][VectorLabel(tX, tY, oX, oY)]_GlobalMaskTexture3SplitTilingOffset_A ("Tiling/Offset--{condition_showS:(_GlobalMaskTexture3Split==1)}", Vector) = (1, 1, 0, 0)
		[HideInInspector][Vector2]_GlobalMaskTexture3SplitPan_A ("Panning--{condition_showS:(_GlobalMaskTexture3Split==1)}", Vector) = (0, 0, 0, 0)
		[HideInInspector][ToggleUI] _GlobalMaskTexture3Split ("Split Sampling", Int) = 0
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_GlobalMaskTexture3UV ("UV", Int) = 0
		
		[HideInInspector] m_end_GlobalMaskTextures ("Global Mask Textures", Float) = 0
		//endex
		
		//ifex _GlobalMaskVertexColorRed==0 && _GlobalMaskVertexColorGreen==0 && _GlobalMaskVertexColorBlue==0 && _GlobalMaskVertexColorAlpha==0
		[HideInInspector] m_start_GlobalMaskVertexColors ("Vertex Colors", Int) = 0
		[ToggleUI] _GlobalMaskVertexColorLinearSpace ("Linear Colors", Float) = 1
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _GlobalMaskVertexColorRed ("Red--{reference_property:_GlobalMaskVertexColorRedBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _GlobalMaskVertexColorRedBlendType ("Blending", Int) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _GlobalMaskVertexColorGreen ("Green--{reference_property:_GlobalMaskVertexColorGreenBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _GlobalMaskVertexColorGreenBlendType ("Blending", Int) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _GlobalMaskVertexColorBlue ("Blue--{reference_property:_GlobalMaskVertexColorBlueBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _GlobalMaskVertexColorBlueBlendType ("Blending", Int) = 2
		[ThryWideEnum(Off, 0, 1R, 1, 1G, 2, 1B, 3, 1A, 4, 2R, 5, 2G, 6, 2B, 7, 2A, 8, 3R, 9, 3G, 10, 3B, 11, 3A, 12, 4R, 13, 4G, 14, 4B, 15, 4A, 16)] _GlobalMaskVertexColorAlpha ("Alpha--{reference_property:_GlobalMaskVertexColorAlphaBlendType}", Int) = 0
		[HideInInspector][ThryWideEnum(Add, 7, Subtract, 1, Multiply, 2, Divide, 3, Min, 4, Max, 5, Average, 6, Replace, 0)] _GlobalMaskVertexColorAlphaBlendType ("Blending", Int) = 2
		[HideInInspector] m_end_GlobalMaskVertexColors ("Vertex Colors", Int) = 0
		//endex
		
		[HideInInspector] m_start_GlobalMaskModifiers ("Modifiers", Float) = 0
		
		//ifex _GlobalMaskModifiersBackfaceEnable==0
		[HideInInspector] m_start_GlobalMaskModifiersBackface ("Backface Masking--{reference_property:_GlobalMaskModifiersBackfaceEnable}", Float) = 0
		[HideInInspector][NoAnimate][ThryToggleUI(true)] _GlobalMaskModifiersBackfaceEnable ("Global Mask Backface Enable", Float) = 0
		[Enum(Both, 0, Back Only, 1, Front Only, 2)] _GlobalMaskBackface_0 ("1R", Int) = 0
		[Enum(Both, 0, Back Only, 1, Front Only, 2)] _GlobalMaskBackface_1 ("1G", Int) = 0
		[Enum(Both, 0, Back Only, 1, Front Only, 2)] _GlobalMaskBackface_2 ("1B", Int) = 0
		[Enum(Both, 0, Back Only, 1, Front Only, 2)] _GlobalMaskBackface_3 ("1A", Int) = 0
		[Enum(Both, 0, Back Only, 1, Front Only, 2)] _GlobalMaskBackface_4 ("2R", Int) = 0
		[Enum(Both, 0, Back Only, 1, Front Only, 2)] _GlobalMaskBackface_5 ("2G", Int) = 0
		[Enum(Both, 0, Back Only, 1, Front Only, 2)] _GlobalMaskBackface_6 ("2B", Int) = 0
		[Enum(Both, 0, Back Only, 1, Front Only, 2)] _GlobalMaskBackface_7 ("2A", Int) = 0
		[Enum(Both, 0, Back Only, 1, Front Only, 2)] _GlobalMaskBackface_8 ("3R", Int) = 0
		[Enum(Both, 0, Back Only, 1, Front Only, 2)] _GlobalMaskBackface_9 ("3G", Int) = 0
		[Enum(Both, 0, Back Only, 1, Front Only, 2)] _GlobalMaskBackface_10 ("3B", Int) = 0
		[Enum(Both, 0, Back Only, 1, Front Only, 2)] _GlobalMaskBackface_11 ("3A", Int) = 0
		[Enum(Both, 0, Back Only, 1, Front Only, 2)] _GlobalMaskBackface_12 ("4R", Int) = 0
		[Enum(Both, 0, Back Only, 1, Front Only, 2)] _GlobalMaskBackface_13 ("4G", Int) = 0
		[Enum(Both, 0, Back Only, 1, Front Only, 2)] _GlobalMaskBackface_14 ("4B", Int) = 0
		[Enum(Both, 0, Back Only, 1, Front Only, 2)] _GlobalMaskBackface_15 ("4A", Int) = 0
		[HideInInspector] m_end_GlobalMaskModifiersBackface ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskModifiersMirrorEnable==0
		[HideInInspector] m_start_GlobalMaskModifiersMirror ("Mirror Masking--{reference_property:_GlobalMaskModifiersMirrorEnable}", Float) = 0
		[HideInInspector][NoAnimate][ThryToggleUI(true)] _GlobalMaskModifiersMirrorEnable ("Global Mask Mirror Enable", Float) = 0
		[Enum(Generic, 0, VRC, 1)] _GlobalMaskMirrorVisibilityMode ("Mirror Detection Mode", Int) = 1
		[Enum(Both, 0, Only Outside Mirror, 1, Only In Mirror, 2)] _GlobalMaskMirror_0 ("1R", Int) = 0
		[Enum(Both, 0, Only Outside Mirror, 1, Only In Mirror, 2)] _GlobalMaskMirror_1 ("1G", Int) = 0
		[Enum(Both, 0, Only Outside Mirror, 1, Only In Mirror, 2)] _GlobalMaskMirror_2 ("1B", Int) = 0
		[Enum(Both, 0, Only Outside Mirror, 1, Only In Mirror, 2)] _GlobalMaskMirror_3 ("1A", Int) = 0
		[Enum(Both, 0, Only Outside Mirror, 1, Only In Mirror, 2)] _GlobalMaskMirror_4 ("2R", Int) = 0
		[Enum(Both, 0, Only Outside Mirror, 1, Only In Mirror, 2)] _GlobalMaskMirror_5 ("2G", Int) = 0
		[Enum(Both, 0, Only Outside Mirror, 1, Only In Mirror, 2)] _GlobalMaskMirror_6 ("2B", Int) = 0
		[Enum(Both, 0, Only Outside Mirror, 1, Only In Mirror, 2)] _GlobalMaskMirror_7 ("2A", Int) = 0
		[Enum(Both, 0, Only Outside Mirror, 1, Only In Mirror, 2)] _GlobalMaskMirror_8 ("3R", Int) = 0
		[Enum(Both, 0, Only Outside Mirror, 1, Only In Mirror, 2)] _GlobalMaskMirror_9 ("3G", Int) = 0
		[Enum(Both, 0, Only Outside Mirror, 1, Only In Mirror, 2)] _GlobalMaskMirror_10 ("3B", Int) = 0
		[Enum(Both, 0, Only Outside Mirror, 1, Only In Mirror, 2)] _GlobalMaskMirror_11 ("3A", Int) = 0
		[Enum(Both, 0, Only Outside Mirror, 1, Only In Mirror, 2)] _GlobalMaskMirror_12 ("4R", Int) = 0
		[Enum(Both, 0, Only Outside Mirror, 1, Only In Mirror, 2)] _GlobalMaskMirror_13 ("4G", Int) = 0
		[Enum(Both, 0, Only Outside Mirror, 1, Only In Mirror, 2)] _GlobalMaskMirror_14 ("4B", Int) = 0
		[Enum(Both, 0, Only Outside Mirror, 1, Only In Mirror, 2)] _GlobalMaskMirror_15 ("4A", Int) = 0
		[HideInInspector] m_end_GlobalMaskModifiersMirror ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskModifiersCameraEnable==0
		[HideInInspector] m_start_GlobalMaskModifiersCamera ("Camera Masking--{reference_property:_GlobalMaskModifiersCameraEnable}", Float) = 0
		[HideInInspector][NoAnimate][ThryToggleUI(true)] _GlobalMaskModifiersCameraEnable ("Global Mask Camera Enable", Float) = 0
		[Helpbox(1)] _GlobalMaskModifiersCameraInfo ("Camera Masking only works in VRChat.", Int) = 0
		[Enum(Both, 0, Only Outside Camera, 1, Only In Camera, 2)] _GlobalMaskCamera_0 ("1R", Int) = 0
		[Enum(Both, 0, Only Outside Camera, 1, Only In Camera, 2)] _GlobalMaskCamera_1 ("1G", Int) = 0
		[Enum(Both, 0, Only Outside Camera, 1, Only In Camera, 2)] _GlobalMaskCamera_2 ("1B", Int) = 0
		[Enum(Both, 0, Only Outside Camera, 1, Only In Camera, 2)] _GlobalMaskCamera_3 ("1A", Int) = 0
		[Enum(Both, 0, Only Outside Camera, 1, Only In Camera, 2)] _GlobalMaskCamera_4 ("2R", Int) = 0
		[Enum(Both, 0, Only Outside Camera, 1, Only In Camera, 2)] _GlobalMaskCamera_5 ("2G", Int) = 0
		[Enum(Both, 0, Only Outside Camera, 1, Only In Camera, 2)] _GlobalMaskCamera_6 ("2B", Int) = 0
		[Enum(Both, 0, Only Outside Camera, 1, Only In Camera, 2)] _GlobalMaskCamera_7 ("2A", Int) = 0
		[Enum(Both, 0, Only Outside Camera, 1, Only In Camera, 2)] _GlobalMaskCamera_8 ("3R", Int) = 0
		[Enum(Both, 0, Only Outside Camera, 1, Only In Camera, 2)] _GlobalMaskCamera_9 ("3G", Int) = 0
		[Enum(Both, 0, Only Outside Camera, 1, Only In Camera, 2)] _GlobalMaskCamera_10 ("3B", Int) = 0
		[Enum(Both, 0, Only Outside Camera, 1, Only In Camera, 2)] _GlobalMaskCamera_11 ("3A", Int) = 0
		[Enum(Both, 0, Only Outside Camera, 1, Only In Camera, 2)] _GlobalMaskCamera_12 ("4R", Int) = 0
		[Enum(Both, 0, Only Outside Camera, 1, Only In Camera, 2)] _GlobalMaskCamera_13 ("4G", Int) = 0
		[Enum(Both, 0, Only Outside Camera, 1, Only In Camera, 2)] _GlobalMaskCamera_14 ("4B", Int) = 0
		[Enum(Both, 0, Only Outside Camera, 1, Only In Camera, 2)] _GlobalMaskCamera_15 ("4A", Int) = 0
		[HideInInspector] m_end_GlobalMaskModifiersCamera ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskModifiersDistanceEnable==0
		[HideInInspector] m_start_GlobalMaskModifiersDistance ("Distance Masking--{reference_property:_GlobalMaskModifiersDistanceEnable}", Float) = 0
		[HideInInspector][NoAnimate][ThryToggleUI(true)] _GlobalMaskModifiersDistanceEnable ("Global Mask Camera Enable", Float) = 0
		
		//ifex _GlobalMaskDistanceEnable_0==0// [Vector2] _GlobalMaskDistance_0 ("1R", Vector) = (1,2,0,0)
		[HideInInspector] m_start_GlobalMaskDistanceM_0 ("1R--{reference_property:_GlobalMaskDistanceEnable_0}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _GlobalMaskDistanceEnable_0 ("", Int) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _GlobalMaskDistanceType_0 ("Pos To Use", Int) = 1
		_GlobalMaskDistanceMin_0 ("Min Distance", Float) = 1
		_GlobalMaskDistanceMax_0 ("Max Distance", Float) = 2
		_GlobalMaskDistanceMinAlpha_0 ("Min Distance Alpha", Range(0, 1)) = 0
		_GlobalMaskDistanceMaxAlpha_0 ("Max Distance Alpha", Range(0, 1)) = 1
		[ThryWideEnum(Replace, 0, Multiply, 2)] _GlobalMaskDistanceBlendType_0 ("Blending", Int) = 0
		[HideInInspector] m_end_GlobalMaskDistanceM_0 ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskDistanceEnable_1==0
		[HideInInspector] m_start_GlobalMaskDistanceM_1 ("1G--{reference_property:_GlobalMaskDistanceEnable_1}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _GlobalMaskDistanceEnable_1 ("", Int) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _GlobalMaskDistanceType_1 ("Pos To Use", Int) = 1
		_GlobalMaskDistanceMin_1 ("Min Distance", Float) = 1
		_GlobalMaskDistanceMax_1 ("Max Distance", Float) = 2
		_GlobalMaskDistanceMinAlpha_1 ("Min Distance Alpha", Range(0, 1)) = 0
		_GlobalMaskDistanceMaxAlpha_1 ("Max Distance Alpha", Range(0, 1)) = 1
		[ThryWideEnum(Replace, 0, Multiply, 2)] _GlobalMaskDistanceBlendType_1 ("Blending", Int) = 0
		[HideInInspector] m_end_GlobalMaskDistanceM_1 ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskDistanceEnable_2==0
		[HideInInspector] m_start_GlobalMaskDistanceM_2 ("1B--{reference_property:_GlobalMaskDistanceEnable_2}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _GlobalMaskDistanceEnable_2 ("", Int) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _GlobalMaskDistanceType_2 ("Pos To Use", Int) = 1
		_GlobalMaskDistanceMin_2 ("Min Distance", Float) = 1
		_GlobalMaskDistanceMax_2 ("Max Distance", Float) = 2
		_GlobalMaskDistanceMinAlpha_2 ("Min Distance Alpha", Range(0, 1)) = 0
		_GlobalMaskDistanceMaxAlpha_2 ("Max Distance Alpha", Range(0, 1)) = 1
		[ThryWideEnum(Replace, 0, Multiply, 2)] _GlobalMaskDistanceBlendType_2 ("Blending", Int) = 0
		[HideInInspector] m_end_GlobalMaskDistanceM_2 ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskDistanceEnable_3==0
		[HideInInspector] m_start_GlobalMaskDistanceM_3 ("1A--{reference_property:_GlobalMaskDistanceEnable_3}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _GlobalMaskDistanceEnable_3 ("", Int) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _GlobalMaskDistanceType_3 ("Pos To Use", Int) = 1
		_GlobalMaskDistanceMin_3 ("Min Distance", Float) = 1
		_GlobalMaskDistanceMax_3 ("Max Distance", Float) = 2
		_GlobalMaskDistanceMinAlpha_3 ("Min Distance Alpha", Range(0, 1)) = 0
		_GlobalMaskDistanceMaxAlpha_3 ("Max Distance Alpha", Range(0, 1)) = 1
		[ThryWideEnum(Replace, 0, Multiply, 2)] _GlobalMaskDistanceBlendType_3 ("Blending", Int) = 0
		[HideInInspector] m_end_GlobalMaskDistanceM_3 ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskDistanceEnable_4==0
		[HideInInspector] m_start_GlobalMaskDistanceM_4 ("2R--{reference_property:_GlobalMaskDistanceEnable_4}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _GlobalMaskDistanceEnable_4 ("", Int) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _GlobalMaskDistanceType_4 ("Pos To Use", Int) = 1
		_GlobalMaskDistanceMin_4 ("Min Distance", Float) = 1
		_GlobalMaskDistanceMax_4 ("Max Distance", Float) = 2
		_GlobalMaskDistanceMinAlpha_4 ("Min Distance Alpha", Range(0, 1)) = 0
		_GlobalMaskDistanceMaxAlpha_4 ("Max Distance Alpha", Range(0, 1)) = 1
		[ThryWideEnum(Replace, 0, Multiply, 2)] _GlobalMaskDistanceBlendType_4 ("Blending", Int) = 0
		[HideInInspector] m_end_GlobalMaskDistanceM_4 ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskDistanceEnable_5==0
		[HideInInspector] m_start_GlobalMaskDistanceM_5 ("2G--{reference_property:_GlobalMaskDistanceEnable_5}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _GlobalMaskDistanceEnable_5 ("", Int) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _GlobalMaskDistanceType_5 ("Pos To Use", Int) = 1
		_GlobalMaskDistanceMin_5 ("Min Distance", Float) = 1
		_GlobalMaskDistanceMax_5 ("Max Distance", Float) = 2
		_GlobalMaskDistanceMinAlpha_5 ("Min Distance Alpha", Range(0, 1)) = 0
		_GlobalMaskDistanceMaxAlpha_5 ("Max Distance Alpha", Range(0, 1)) = 1
		[ThryWideEnum(Replace, 0, Multiply, 2)] _GlobalMaskDistanceBlendType_5 ("Blending", Int) = 0
		[HideInInspector] m_end_GlobalMaskDistanceM_5 ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskDistanceEnable_6==0
		[HideInInspector] m_start_GlobalMaskDistanceM_6 ("2B--{reference_property:_GlobalMaskDistanceEnable_6}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _GlobalMaskDistanceEnable_6 ("", Int) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _GlobalMaskDistanceType_6 ("Pos To Use", Int) = 1
		_GlobalMaskDistanceMin_6 ("Min Distance", Float) = 1
		_GlobalMaskDistanceMax_6 ("Max Distance", Float) = 2
		_GlobalMaskDistanceMinAlpha_6 ("Min Distance Alpha", Range(0, 1)) = 0
		_GlobalMaskDistanceMaxAlpha_6 ("Max Distance Alpha", Range(0, 1)) = 1
		[ThryWideEnum(Replace, 0, Multiply, 2)] _GlobalMaskDistanceBlendType_6 ("Blending", Int) = 0
		[HideInInspector] m_end_GlobalMaskDistanceM_6 ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskDistanceEnable_7==0
		[HideInInspector] m_start_GlobalMaskDistanceM_7 ("2A--{reference_property:_GlobalMaskDistanceEnable_7}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _GlobalMaskDistanceEnable_7 ("", Int) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _GlobalMaskDistanceType_7 ("Pos To Use", Int) = 1
		_GlobalMaskDistanceMin_7 ("Min Distance", Float) = 1
		_GlobalMaskDistanceMax_7 ("Max Distance", Float) = 2
		_GlobalMaskDistanceMinAlpha_7 ("Min Distance Alpha", Range(0, 1)) = 0
		_GlobalMaskDistanceMaxAlpha_7 ("Max Distance Alpha", Range(0, 1)) = 1
		[ThryWideEnum(Replace, 0, Multiply, 2)] _GlobalMaskDistanceBlendType_7 ("Blending", Int) = 0
		[HideInInspector] m_end_GlobalMaskDistanceM_7 ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskDistanceEnable_8==0
		[HideInInspector] m_start_GlobalMaskDistanceM_8 ("3R--{reference_property:_GlobalMaskDistanceEnable_8}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _GlobalMaskDistanceEnable_8 ("", Int) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _GlobalMaskDistanceType_8 ("Pos To Use", Int) = 1
		_GlobalMaskDistanceMin_8 ("Min Distance", Float) = 1
		_GlobalMaskDistanceMax_8 ("Max Distance", Float) = 2
		_GlobalMaskDistanceMinAlpha_8 ("Min Distance Alpha", Range(0, 1)) = 0
		_GlobalMaskDistanceMaxAlpha_8 ("Max Distance Alpha", Range(0, 1)) = 1
		[ThryWideEnum(Replace, 0, Multiply, 2)] _GlobalMaskDistanceBlendType_8 ("Blending", Int) = 0
		[HideInInspector] m_end_GlobalMaskDistanceM_8 ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskDistanceEnable_9==0
		[HideInInspector] m_start_GlobalMaskDistanceM_9 ("3G--{reference_property:_GlobalMaskDistanceEnable_9}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _GlobalMaskDistanceEnable_9 ("", Int) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _GlobalMaskDistanceType_9 ("Pos To Use", Int) = 1
		_GlobalMaskDistanceMin_9 ("Min Distance", Float) = 1
		_GlobalMaskDistanceMax_9 ("Max Distance", Float) = 2
		_GlobalMaskDistanceMinAlpha_9 ("Min Distance Alpha", Range(0, 1)) = 0
		_GlobalMaskDistanceMaxAlpha_9 ("Max Distance Alpha", Range(0, 1)) = 1
		[ThryWideEnum(Replace, 0, Multiply, 2)] _GlobalMaskDistanceBlendType_9 ("Blending", Int) = 0
		[HideInInspector] m_end_GlobalMaskDistanceM_9 ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskDistanceEnable_10==0
		[HideInInspector] m_start_GlobalMaskDistanceM_10 ("3B--{reference_property:_GlobalMaskDistanceEnable_10}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _GlobalMaskDistanceEnable_10 ("", Int) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _GlobalMaskDistanceType_10 ("Pos To Use", Int) = 1
		_GlobalMaskDistanceMin_10 ("Min Distance", Float) = 1
		_GlobalMaskDistanceMax_10 ("Max Distance", Float) = 2
		_GlobalMaskDistanceMinAlpha_10 ("Min Distance Alpha", Range(0, 1)) = 0
		_GlobalMaskDistanceMaxAlpha_10 ("Max Distance Alpha", Range(0, 1)) = 1
		[ThryWideEnum(Replace, 0, Multiply, 2)] _GlobalMaskDistanceBlendType_10 ("Blending", Int) = 0
		[HideInInspector] m_end_GlobalMaskDistanceM_10 ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskDistanceEnable_11==0
		[HideInInspector] m_start_GlobalMaskDistanceM_11 ("3A--{reference_property:_GlobalMaskDistanceEnable_11}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _GlobalMaskDistanceEnable_11 ("", Int) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _GlobalMaskDistanceType_11 ("Pos To Use", Int) = 1
		_GlobalMaskDistanceMin_11 ("Min Distance", Float) = 1
		_GlobalMaskDistanceMax_11 ("Max Distance", Float) = 2
		_GlobalMaskDistanceMinAlpha_11 ("Min Distance Alpha", Range(0, 1)) = 0
		_GlobalMaskDistanceMaxAlpha_11 ("Max Distance Alpha", Range(0, 1)) = 1
		[ThryWideEnum(Replace, 0, Multiply, 2)] _GlobalMaskDistanceBlendType_11 ("Blending", Int) = 0
		[HideInInspector] m_end_GlobalMaskDistanceM_11 ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskDistanceEnable_12==0
		[HideInInspector] m_start_GlobalMaskDistanceM_12 ("4R--{reference_property:_GlobalMaskDistanceEnable_12}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _GlobalMaskDistanceEnable_12 ("", Int) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _GlobalMaskDistanceType_12 ("Pos To Use", Int) = 1
		_GlobalMaskDistanceMin_12 ("Min Distance", Float) = 1
		_GlobalMaskDistanceMax_12 ("Max Distance", Float) = 2
		_GlobalMaskDistanceMinAlpha_12 ("Min Distance Alpha", Range(0, 1)) = 0
		_GlobalMaskDistanceMaxAlpha_12 ("Max Distance Alpha", Range(0, 1)) = 1
		[ThryWideEnum(Replace, 0, Multiply, 2)] _GlobalMaskDistanceBlendType_12 ("Blending", Int) = 0
		[HideInInspector] m_end_GlobalMaskDistanceM_12 ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskDistanceEnable_13==0
		[HideInInspector] m_start_GlobalMaskDistanceM_13 ("4G--{reference_property:_GlobalMaskDistanceEnable_13}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _GlobalMaskDistanceEnable_13 ("", Int) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _GlobalMaskDistanceType_13 ("Pos To Use", Int) = 1
		_GlobalMaskDistanceMin_13 ("Min Distance", Float) = 1
		_GlobalMaskDistanceMax_13 ("Max Distance", Float) = 2
		_GlobalMaskDistanceMinAlpha_13 ("Min Distance Alpha", Range(0, 1)) = 0
		_GlobalMaskDistanceMaxAlpha_13 ("Max Distance Alpha", Range(0, 1)) = 1
		[ThryWideEnum(Replace, 0, Multiply, 2)] _GlobalMaskDistanceBlendType_13 ("Blending", Int) = 0
		[HideInInspector] m_end_GlobalMaskDistanceM_13 ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskDistanceEnable_14==0
		[HideInInspector] m_start_GlobalMaskDistanceM_14 ("4B--{reference_property:_GlobalMaskDistanceEnable_14}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _GlobalMaskDistanceEnable_14 ("", Int) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _GlobalMaskDistanceType_14 ("Pos To Use", Int) = 1
		_GlobalMaskDistanceMin_14 ("Min Distance", Float) = 1
		_GlobalMaskDistanceMax_14 ("Max Distance", Float) = 2
		_GlobalMaskDistanceMinAlpha_14 ("Min Distance Alpha", Range(0, 1)) = 0
		_GlobalMaskDistanceMaxAlpha_14 ("Max Distance Alpha", Range(0, 1)) = 1
		[ThryWideEnum(Replace, 0, Multiply, 2)] _GlobalMaskDistanceBlendType_14 ("Blending", Int) = 0
		[HideInInspector] m_end_GlobalMaskDistanceM_14 ("", Float) = 0
		//endex
		
		//ifex _GlobalMaskDistanceEnable_15==0
		[HideInInspector] m_start_GlobalMaskDistanceM_15 ("4A--{reference_property:_GlobalMaskDistanceEnable_15}", Float) = 0
		[HideInInspector][ThryToggleUI(true)] _GlobalMaskDistanceEnable_15 ("", Int) = 0
		[Enum(Object Position, 0, Pixel Position, 1)] _GlobalMaskDistanceType_15 ("Pos To Use", Int) = 1
		_GlobalMaskDistanceMin_15 ("Min Distance", Float) = 1
		_GlobalMaskDistanceMax_15 ("Max Distance", Float) = 2
		_GlobalMaskDistanceMinAlpha_15 ("Min Distance Alpha", Range(0, 1)) = 0
		_GlobalMaskDistanceMaxAlpha_15 ("Max Distance Alpha", Range(0, 1)) = 1
		[ThryWideEnum(Replace, 0, Multiply, 2)] _GlobalMaskDistanceBlendType_15 ("Blending", Int) = 0
		[HideInInspector] m_end_GlobalMaskDistanceM_15 ("", Float) = 0
		//endex
		
		[HideInInspector] m_end_GlobalMaskModifiersDistance ("", Float) = 0
		//endex
		
		[HideInInspector] m_end_GlobalMaskModifiers ("", Float) = 0
		
		//ifex _GlobalMaskOptionsEnable==0
		[HideInInspector] m_start_GlobalMaskOptions ("Options--{reference_property:_GlobalMaskOptionsEnable}", Float) = 0
		[HideInInspector][NoAnimate][ThryToggleUI(true)] _GlobalMaskOptionsEnable ("Global Mask Options Enable", Float) = 0
		[Enum(Sliders, 0, Min Max Sliders, 1, Force Toggles, 2)] _GlobalMaskOptionsType ("Type", Int) = 0
		
		//ifex _GlobalMaskOptionsType!=0
		[HideInInspector] s_start_GlobalMaskOptionsSliders ("Options--{persistent_expand:true,default_expand:false,condition_showS:_GlobalMaskOptionsType==0}", Int) = 0
		_GlobalMaskSlider_0 ("1R", Range(-1, 1)) = 0
		_GlobalMaskSlider_1 ("1G", Range(-1, 1)) = 0
		_GlobalMaskSlider_2 ("1B", Range(-1, 1)) = 0
		_GlobalMaskSlider_3 ("1A", Range(-1, 1)) = 0
		_GlobalMaskSlider_4 ("2R", Range(-1, 1)) = 0
		_GlobalMaskSlider_5 ("2G", Range(-1, 1)) = 0
		_GlobalMaskSlider_6 ("2B", Range(-1, 1)) = 0
		_GlobalMaskSlider_7 ("2A", Range(-1, 1)) = 0
		_GlobalMaskSlider_8 ("3R", Range(-1, 1)) = 0
		_GlobalMaskSlider_9 ("3G", Range(-1, 1)) = 0
		_GlobalMaskSlider_10 ("3B", Range(-1, 1)) = 0
		_GlobalMaskSlider_11 ("3A", Range(-1, 1)) = 0
		_GlobalMaskSlider_12 ("4R", Range(-1, 1)) = 0
		_GlobalMaskSlider_13 ("4G", Range(-1, 1)) = 0
		_GlobalMaskSlider_14 ("4B", Range(-1, 1)) = 0
		_GlobalMaskSlider_15 ("4A", Range(-1, 1)) = 0
		[HideInInspector] s_end_GlobalMaskOptionsSliders ("", Int) = 0
		//endex
		
		//ifex _GlobalMaskOptionsType!=1
		[HideInInspector] s_start_GlobalMaskOptionsMinMaxSliders ("Options--{persistent_expand:true,default_expand:false,condition_showS:_GlobalMaskOptionsType==1}", Int) = 0
		[MultiSlider] _GlobalMaskMinMaxSlider_0 ("1R", Vector) = (0, 1, 0, 1)
		[MultiSlider] _GlobalMaskMinMaxSlider_1 ("1G", Vector) = (0, 1, 0, 1)
		[MultiSlider] _GlobalMaskMinMaxSlider_2 ("1B", Vector) = (0, 1, 0, 1)
		[MultiSlider] _GlobalMaskMinMaxSlider_3 ("1A", Vector) = (0, 1, 0, 1)
		[MultiSlider] _GlobalMaskMinMaxSlider_4 ("2R", Vector) = (0, 1, 0, 1)
		[MultiSlider] _GlobalMaskMinMaxSlider_5 ("2G", Vector) = (0, 1, 0, 1)
		[MultiSlider] _GlobalMaskMinMaxSlider_6 ("2B", Vector) = (0, 1, 0, 1)
		[MultiSlider] _GlobalMaskMinMaxSlider_7 ("2A", Vector) = (0, 1, 0, 1)
		[MultiSlider] _GlobalMaskMinMaxSlider_8 ("3R", Vector) = (0, 1, 0, 1)
		[MultiSlider] _GlobalMaskMinMaxSlider_9 ("3G", Vector) = (0, 1, 0, 1)
		[MultiSlider] _GlobalMaskMinMaxSlider_10 ("3B", Vector) = (0, 1, 0, 1)
		[MultiSlider] _GlobalMaskMinMaxSlider_11 ("3A", Vector) = (0, 1, 0, 1)
		[MultiSlider] _GlobalMaskMinMaxSlider_12 ("4R", Vector) = (0, 1, 0, 1)
		[MultiSlider] _GlobalMaskMinMaxSlider_13 ("4G", Vector) = (0, 1, 0, 1)
		[MultiSlider] _GlobalMaskMinMaxSlider_14 ("4B", Vector) = (0, 1, 0, 1)
		[MultiSlider] _GlobalMaskMinMaxSlider_15 ("4A", Vector) = (0, 1, 0, 1)
		[HideInInspector] s_end_GlobalMaskOptionsMinMaxSliders ("", Int) = 0
		//endex
		
		//ifex _GlobalMaskOptionsType!=2
		[HideInInspector] s_start_GlobalMaskOptionsForceToggles ("Options--{persistent_expand:true,default_expand:false,condition_showS:_GlobalMaskOptionsType==2}", Int) = 0
		[ThryHeaderLabel(Force On)]
		[ToggleUI] _GlobalMaskToggleOn_0 ("1R", Int) = 0
		[ToggleUI] _GlobalMaskToggleOn_1 ("1G", Int) = 0
		[ToggleUI] _GlobalMaskToggleOn_2 ("1B", Int) = 0
		[ToggleUI] _GlobalMaskToggleOn_3 ("1A", Int) = 0
		[ToggleUI] _GlobalMaskToggleOn_4 ("2R", Int) = 0
		[ToggleUI] _GlobalMaskToggleOn_5 ("2G", Int) = 0
		[ToggleUI] _GlobalMaskToggleOn_6 ("2B", Int) = 0
		[ToggleUI] _GlobalMaskToggleOn_7 ("2A", Int) = 0
		[ToggleUI] _GlobalMaskToggleOn_8 ("3R", Int) = 0
		[ToggleUI] _GlobalMaskToggleOn_9 ("3G", Int) = 0
		[ToggleUI] _GlobalMaskToggleOn_10 ("3B", Int) = 0
		[ToggleUI] _GlobalMaskToggleOn_11 ("3A", Int) = 0
		[ToggleUI] _GlobalMaskToggleOn_12 ("4R", Int) = 0
		[ToggleUI] _GlobalMaskToggleOn_13 ("4G", Int) = 0
		[ToggleUI] _GlobalMaskToggleOn_14 ("4B", Int) = 0
		[ToggleUI] _GlobalMaskToggleOn_15 ("4A", Int) = 0
		[Space(8)]
		[ThryHeaderLabel(Force Off)]
		[ToggleUI] _GlobalMaskToggleOff_0 ("1R", Int) = 0
		[ToggleUI] _GlobalMaskToggleOff_1 ("1G", Int) = 0
		[ToggleUI] _GlobalMaskToggleOff_2 ("1B", Int) = 0
		[ToggleUI] _GlobalMaskToggleOff_3 ("1A", Int) = 0
		[ToggleUI] _GlobalMaskToggleOff_4 ("2R", Int) = 0
		[ToggleUI] _GlobalMaskToggleOff_5 ("2G", Int) = 0
		[ToggleUI] _GlobalMaskToggleOff_6 ("2B", Int) = 0
		[ToggleUI] _GlobalMaskToggleOff_7 ("2A", Int) = 0
		[ToggleUI] _GlobalMaskToggleOff_8 ("3R", Int) = 0
		[ToggleUI] _GlobalMaskToggleOff_9 ("3G", Int) = 0
		[ToggleUI] _GlobalMaskToggleOff_10 ("3B", Int) = 0
		[ToggleUI] _GlobalMaskToggleOff_11 ("3A", Int) = 0
		[ToggleUI] _GlobalMaskToggleOff_12 ("4R", Int) = 0
		[ToggleUI] _GlobalMaskToggleOff_13 ("4G", Int) = 0
		[ToggleUI] _GlobalMaskToggleOff_14 ("4B", Int) = 0
		[ToggleUI] _GlobalMaskToggleOff_15 ("4A", Int) = 0
		[HideInInspector] s_end_GlobalMaskOptionsForceToggles ("", Int) = 0
		//endex
		
		[HideInInspector] m_end_GlobalMaskOptions ("Global Mask Options", Float) = 0
		//endex
		
		[HideInInspector] m_end_GlobalMask ("Global Mask", Float) = 0
		
		[HideInInspector] m_end_PoiGlobalCategory ("Global Data and Masks ", Float) = 0
		[HideInInspector] m_start_PoiUVCategory ("UVs", Float) = 0
		[HideInInspector] m_start_Stochastic ("Stochastic Sampling", Float) = 0
		[KeywordEnum(Deliot Heitz, Hextile, None)] _StochasticMode ("Sampling Mode", Float) = 0
		[HideInInspector] s_start_deliot ("Deliot Heitz--{persistent_expand:true,default_expand:false,condition_show:{type:PROPERTY_BOOL,data:_StochasticMode==0}}", Float) = 0
		_StochasticDeliotHeitzDensity ("Detiling Density", Range(0.1, 10)) = 1
		[HideInInspector] s_end_deliot ("Deliot Heitz", Float) = 0
		[HideInInspector] s_start_hextile ("Hextile--{persistent_expand:true,default_expand:false,condition_show:{type:PROPERTY_BOOL,data:_StochasticMode==1}}", Float) = 0
		_StochasticHexGridDensity ("Hex Grid Density", Range(0.1, 10)) = 1
		_StochasticHexRotationStrength ("Rotation Strength", Range(0, 2)) = 0
		_StochasticHexFallOffContrast("Falloff Contrast", Range(0.01, 0.99)) = 0.6
		_StochasticHexFallOffPower("Falloff Power", Range(0, 20)) = 7
		[HideInInspector] s_end_hextile ("Hextile", Float) = 0
		[HideInInspector] m_end_Stochastic ("Stochastic Sampling", Float) = 0
		
		//ifex _EnableDistortion==0
		[HideInInspector] m_start_uvDistortion (" Distortion UV--{reference_property:_EnableDistortion}", Float) = 0
		[HideInInspector][ThryToggle(USER_LUT)] _EnableDistortion ("Enabled", Float) = 0
		[ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos XZ, 5, Local Pos, 8, Polar UV, 6)] _DistortionUvToDistort ("Distorted UV", Int) = 0
		[sRGBWarning]_DistortionMask ("Mask--{reference_properties:[_DistortionMaskPan, _DistortionMaskUV, _DistortionMaskChannel]}", 2D) = "white" { }
		[HideInInspector][Vector2]_DistortionMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos XZ, 5, Local Pos, 8, Polar UV, 6)] _DistortionMaskUV ("UV", Int) = 0
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_DistortionMaskChannel ("Channel", Float) = 0
		[sRGBWarning]_DistortionFlowTexture ("Distortion Texture 1--{reference_properties:[_DistortionFlowTexturePan, _DistortionFlowTextureUV]}", 2D) = "black" { }
		[HideInInspector][Vector2]_DistortionFlowTexturePan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos XZ, 5, Local Pos, 8, Polar UV, 6)] _DistortionFlowTextureUV ("UV", Int) = 0
		[sRGBWarning]_DistortionFlowTexture1 ("Distortion Texture 2--{reference_properties:[_DistortionFlowTexture1Pan, _DistortionFlowTexture1UV]}", 2D) = "black" { }
		[HideInInspector][Vector2]_DistortionFlowTexture1Pan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos XZ, 5, Local Pos, 8, Polar UV, 6)] _DistortionFlowTexture1UV ("UV", Int) = 0
		_DistortionStrength ("Strength1", Float) = 0.03
		_DistortionStrength1 ("Strength2", Float) = 0.01
		[HideInInspector] m_start_DistortionAudioLink ("Audio Link ♫--{reference_property:_EnableDistortionAudioLink, condition_showS:_EnableAudioLink==1}", Float) = 0
		[HideInInspector][ToggleUI] _EnableDistortionAudioLink ("Enabled", Float) = 0
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _DistortionStrengthAudioLinkBand ("Strength 1 Band", Int) = 0
		[VectorLabel(Min, Max)]_DistortionStrengthAudioLink ("Strength 1 Offset Range", Vector) = (0, 0, 0, 0)
		[Space(7)]
		[Enum(Bass, 0, Low Mid, 1, High Mid, 2, Treble, 3, Volume, 4)] _DistortionStrength1AudioLinkBand ("Strength 2 Band", Int) = 0
		[VectorLabel(Min, Max)]_DistortionStrength1AudioLink ("Strength 2 Offset Range", Vector) = (0, 0, 0, 0)
		[HideInInspector] m_end_DistortionAudioLink ("Audio Link", Float) = 0
		[HideInInspector] m_end_uvDistortion ("Distortion UV", Float) = 0
		//endex
		
		[HideInInspector] m_start_uvLocalWorld ("Local World UV", Float) = 0
		[ThryWideEnum(X, 0, Y, 1, Z, 2, Zero, 3, VColor R, 4, VColor G, 5, VColor B, 6, VColor A, 7)] _UVModLocalPos0 ("Local X", Int) = 0
		[ThryWideEnum(X, 0, Y, 1, Z, 2, Zero, 3, VColor R, 4, VColor G, 5, VColor B, 6, VColor A, 7)] _UVModLocalPos1 ("Local Y", Int) = 1
		[Space(10)]
		[ThryWideEnum(X, 0, Y, 1, Z, 2, Zero, 3)] _UVModWorldPos0 ("World X", Int) = 0
		[ThryWideEnum(X, 0, Y, 1, Z, 2, Zero, 3)] _UVModWorldPos1 ("World Y", Int) = 2
		[HideInInspector] m_end_uvLocalWorld ("Local World UV", Float) = 0
		
		[HideInInspector] m_start_uvPanosphere ("Panosphere UV", Float) = 0
		[ToggleUI] _StereoEnabled ("Stereo Enabled", Float) = 0
		[ToggleUI] _PanoUseBothEyes ("Perspective Correct (VR)", Float) = 1
		[HideInInspector] m_end_uvPanosphere ("Panosphere UV", Float) = 0
		
		[HideInInspector] m_start_uvPolar ("Polar UV", Float) = 0
		[ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8)] _PolarUV ("UV", Int) = 0
		[Vector2]_PolarCenter ("Center Coordinate", Vector) = (.5, .5, 0, 0)
		_PolarRadialScale ("Radial Scale", Float) = 1
		_PolarLengthScale ("Length Scale", Float) = 1
		_PolarSpiralPower ("Spiral Power", Float) = 0
		[HideInInspector] m_end_uvPolar ("Polar UV", Float) = 0
		
		//ifex _PoiParallax==0
		[HideInInspector] m_start_parallax (" Parallax Heightmapping--{reference_property:_PoiParallax}", Float) = 0
		[HideInInspector][ThryToggle(POI_PARALLAX)]_PoiParallax ("Enable", Float) = 0
		[ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_ParallaxUV ("Applies To: ", Int) = 0
		
		[sRGBWarning][ThryTexture]_HeightMap ("Heightmap--{reference_properties:[_HeightMapPan, _HeightMapUV]}", 2D) = "white" { }
		[HideInInspector][Vector2]_HeightMapPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_HeightMapUV ("UV", Int) = 0
		
		[sRGBWarning][ThryTexture]_Heightmask ("Mask--{reference_properties:[_HeightmaskPan, _HeightmaskUV, _HeightmaskChannel, _HeightmaskInvert]}", 2D) = "white" { }
		[HideInInspector][Vector2]_HeightmaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_HeightmaskChannel ("Channel", Float) = 0
		[HideInInspector][ToggleUI]_HeightmaskInvert ("Invert", Float) = 0
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_HeightmaskUV ("UV", Int) = 0
		_HeightStrength ("Strength", Range(0, 1)) = 0.4247461
		//_HeightOffset ("Offset", Range(-1, 1)) = 0
		_CurvatureU ("Curvature U", Range(0, 100)) = 0
		_CurvatureV ("Curvature V", Range(0, 30)) = 0
		[IntRange]_HeightStepsMin ("Steps Min", Range(0, 128)) = 10
		[IntRange]_HeightStepsMax ("Steps Max", Range(0, 128)) = 128
		_CurvFix ("Curvature Bias", Range(0, 1)) = 1
		// [ThryToggle]_ParallaxUV0 ("UV0", Float) = 0
		// [ThryToggle]_ParallaxUV1 ("UV1", Float) = 0
		// [ThryToggle]_ParallaxUV2 ("UV2", Float) = 0
		// [ThryToggle]_ParallaxUV3 ("UV3", Float) = 0
		// [ThryToggle]_ParallaxPano ("Panosphere", Float) = 0
		// [ThryToggle]_ParallaxWorldPos ("World Pos", Float) = 0
		// [ThryToggle]_ParallaxPolar ("Polar", Float) = 0
		// [ThryToggle]_ParallaxDist ("Distorted UV", Float) = 0
		
		[HideInInspector] m_end_parallax ("Parallax Heightmapping", Float) = 0
		//endex
		
		[HideInInspector] m_end_PoiUVCategory ("UVs ", Float) = 0
		[HideInInspector] m_start_PoiPostProcessingCategory ("Post Processing", Float) = 0
		[HideInInspector] m_start_PPAnimations ("PP Animations--{button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/post-processing/pp-animations},hover:Documentation}}", Float) = 0
		[Helpbox(1)] _PPHelp ("This section meant for real time adjustments through animations and not to be changed in unity", Int) = 0
		_PPLightingMultiplier ("Lighting Mulitplier", Float) = 1
		_PPLightingAddition ("Lighting Add", Float) = 0
		_PPEmissionMultiplier ("Emission Multiplier", Float) = 1
		_PPFinalColorMultiplier ("Final Color Multiplier", Float) = 1
		[HideInInspector] m_end_PPAnimations ("PP Animations ", Float) = 0
		
		//ifex _PostProcess==0
		[HideInInspector] m_start_postprocess ("Post Processing--{reference_property:_PostProcess,button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/post-processing/main},hover:Documentation}}", Float) = 0
		[HideInInspector][ThryToggle(POSTPROCESS)]_PostProcess ("Enable", Float) = 0
		[sRGBWarning][ThryTexture] _PPMask ("Mask--{reference_properties:[_PPMaskPan, _PPMaskUV, _PPMaskChannel, _PPMaskInvert]}", 2D) = "white" { }
		[HideInInspector][Vector2]_PPMaskPan ("Panning", Vector) = (0, 0, 0, 0)
		[HideInInspector][Enum(R, 0, G, 1, B, 2, A, 3)]_PPMaskChannel ("Channel", Float) = 0
		[HideInInspector][ToggleUI]_PPMaskInvert ("Invert", Float) = 0
		[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos, 5, Local Pos, 8, Polar UV, 6, Distorted UV, 7)]_PPMaskUV ("UV", Int) = 0
		
		_PPHue ("Hue", Range(0, 1)) = 0
		[HDR]_PPTint ("Tint", Color) = (1, 1, 1, 1)
		[VectorLabel(R,G,B)]_PPRGB ("RGB", Vector) = (1, 1, 1, 1)
		_PPContrast ("Contrast", Float) = 1
		_PPSaturation ("Saturation", Float) = 1
		_PPBrightness ("Brightness", Float) = 1
		_PPLightness ("Lightness", Float) = 0
		_PPHDR ("HDR", Float) = 0
		
		[ThryToggleUI(true)]_PPPosterization ("<size=13><b>  Posterization</b></size>", Float) = 0
		_PPPosterizationAmount ("Steps--{condition_showS:(_PPPosterization==1)}", Range(1, 30)) = 4
		
		[HideInInspector] m_end_postprocess ("", Float) = 0
		//endex
		
		[HideInInspector] m_end_PoiPostProcessingCategory ("Post Processing ", Float) = 0
		
		[HideInInspector] m_thirdpartyCategory ("Third Party", Float) = 0
		//ifex _BSSEnabled!=1
		[HideInInspector] m_start_BeatsaberOptions ("Beatsaber support--{reference_property:_BSSEnabled}", int) = 0
		[ThryToggle(POIBS_ENABLE)][HideInInspector] _BSSEnabled ("Enable BeatSaber Module--{on_value_actions:[{value:1,actions:[{type:SET_PROPERTY,data:_BlendOpAlpha=0},{type:SET_PROPERTY,data:_SrcBlendAlpha=1},{type:SET_PROPERTY,data:_DstBlendAlpha=0}]}]}", int) = 0
		[ThryRichLabel] _BSSSpacer1 ("<color=#ff0000ff>―――――――[IMPORTANT]―――――――</color>", int) = 0
		[Helpbox] _BSSHelpBox1("Toggling on BeatSaber support will set (Rendering > Blending > Advanced Alpha) to ''Add, One, Zero,'' as alpha blending operations cause visual issues.", int) = 0
		[Helpbox] _BSSHelpBox2 ("Glow is handled through the various emission options found in the shader!", int) = 0
		[ThryRichLabel] _BSSSpacer2 ("<color=#ff0000ff>―――――――[IMPORTANT]―――――――</color>", int) = 0
		[ThryRichLabel] _BSSSpacer3 ("", int) = 0
		
		[HideInInspector]s_start_CCopt("Custom Colors:--{reference_property:_CustomColors}", int) = 1
		[HideInInspector][MaterialToggle] _CustomColors ("", Float) = 0
		[Helpbox] _BSSHelpBox3 ("To properly support custom colors on assets like sabers when material locking. you MUST right click the ''Color & Alpha'' property at the top and set it to ''Animated.''", int) = 0
		[HideInInspector]s_end_CCopt("Custom Color Toggle:", int) = 1
		
		//ifex _BSSBloomfog!=1
		[HideInInspector] m_start_BeatsaberBloomFog ("Bloom & Height fog--{reference_property:_BSSBloomfog}", int) = 0
		[ThryToggle(POIBS_BLOOMFOG)][HideInInspector] _BSSBloomfog ("Enable Bloomfog", int) = 0
		[HideInInspector]s_start_fogOpt("Bloom fog settings:", int) = 1
		_FogStartOffset ("Fog Start Offset:", Float) = 0
		_FogScale ("Fog Scale:", Float) = 1
		[HideInInspector]s_end_fogOpt("", int) = 1
		[ThryToggle(BSSBLOOMFOGTYPE_HEIGHT)][HideInInspector] _BSSBloomfogType ("", int) = 1
		[HideInInspector]s_start_heightFogOpt("Height fog settings:--{reference_property:_BSSBloomfogType}", int) = 1
		_FogHeightOffset ("Height start offset:--{condition_enable:{type:PROPERTY_BOOL,data:_BSSBloomfogType==1}}", Float) = 0
		_FogHeightScale ("Height Scale:--{condition_enable:{type:PROPERTY_BOOL,data:_BSSBloomfogType==1}}", Float) = 1
		[HideInInspector]s_end_heightFogOpt("", int) = 1
		[HideInInspector] m_end_BeatsaberBloomFog ("", int) = 0
		//endex
		
		[HideInInspector] m_end_BeatsaberOptions ("", Float) = 0
		//endex
		
		[HideInInspector] m_renderingCategory ("Rendering--{button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/rendering/main},hover:Documentation}}", Float) = 0
		[Enum(UnityEngine.Rendering.CullMode)] _Cull ("Cull", Float) = 2
		[Enum(UnityEngine.Rendering.CompareFunction)] _ZTest ("ZTest", Float) = 4
		[Enum(Off, 0, On, 1)] _ZWrite ("ZWrite", Int) = 1
		[Enum(Thry.ColorMask)] _ColorMask ("Color Mask", Int) = 15
		_OffsetFactor ("Offset Factor", Float) = 0.0
		_OffsetUnits ("Offset Units", Float) = 0.0
		[ToggleUI]_RenderingReduceClipDistance ("Reduce Clip Distance", Float) = 0
		[ToggleUI]_IgnoreFog ("Ignore Fog", Float) = 0
		[ToggleUI]_FlipBackfaceNormals ("Flip Backface Normals", Int) = 1
		[HideInInspector] Instancing ("Instancing", Float) = 0 //add this property for instancing variants settings to be shown
		[ToggleUI] _RenderingEarlyZEnabled ("Early Z", Float) = 0
		
		// Blending Options
		[HideInInspector] m_start_blending ("Blending--{button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/rendering/blending},hover:Documentation}}", Float) = 0
		[Enum(Thry.BlendOp)]_BlendOp ("RGB Blend Op", Int) = 0
		[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend ("RGB Source Blend", Int) = 1
		[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend ("RGB Destination Blend", Int) = 0
		[Space][ThryHeaderLabel(Additive Blending, 13)]
		[Enum(Thry.BlendOp)]_AddBlendOp ("RGB Blend Op", Int) = 4
		[Enum(UnityEngine.Rendering.BlendMode)] _AddSrcBlend ("RGB Source Blend", Int) = 1
		[Enum(UnityEngine.Rendering.BlendMode)] _AddDstBlend ("RGB Destination Blend", Int) = 1
		
		[HideInInspector] m_start_alphaBlending ("Advanced Alpha Blending", Float) = 0
		[Enum(Thry.BlendOp)]_BlendOpAlpha ("Alpha Blend Op", Int) = 0
		[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlendAlpha ("Alpha Source Blend", Int) = 1
		[Enum(UnityEngine.Rendering.BlendMode)] _DstBlendAlpha ("Alpha Destination Blend", Int) = 10
		[Space][ThryHeaderLabel(Additive Blending, 13)]
		[Enum(Thry.BlendOp)]_AddBlendOpAlpha ("Alpha Blend Op", Int) = 4
		[Enum(UnityEngine.Rendering.BlendMode)] _AddSrcBlendAlpha ("Alpha Source Blend", Int) = 0
		[Enum(UnityEngine.Rendering.BlendMode)] _AddDstBlendAlpha ("Alpha Destination Blend", Int) = 1
		[HideInInspector] m_end_alphaBlending ("Advanced Alpha Blending", Float) = 0
		
		[HideInInspector] m_end_blending ("Blending", Float) = 0
		
		//ifex _EnableOutlines!=1
		// Outline Blending Options
		[HideInInspector] m_start_outlineBlending ("Outline Blending", Float) = 0
		[Enum(Thry.BlendOp)]_OutlineBlendOp ("RGB Blend Op", Int) = 0
		[Enum(UnityEngine.Rendering.BlendMode)] _OutlineSrcBlend ("RGB Source Blend", Int) = 1
		[Enum(UnityEngine.Rendering.BlendMode)] _OutlineDstBlend ("RGB Destination Blend", Int) = 0
		[HideInInspector] m_start_outlineAlphaBlending ("Advanced Alpha Blending", Float) = 0
		[Enum(Thry.BlendOp)]_OutlineBlendOpAlpha ("Alpha Blend Op", Int) = 4
		[Enum(UnityEngine.Rendering.BlendMode)] _OutlineSrcBlendAlpha ("Alpha Source Blend", Int) = 1
		[Enum(UnityEngine.Rendering.BlendMode)] _OutlineDstBlendAlpha ("Alpha Destination Blend", Int) = 0
		[HideInInspector] m_end_outlineAlphaBlending ("Advanced Alpha Blending", Float) = 0
		[HideInInspector] m_end_outlineBlending ("Outline Blending", Float) = 0
		//endex
		
		// Stencils
		[HideInInspector] m_start_StencilPassOptions ("Stencil--{button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/rendering/stencil},hover:Documentation}}", Float) = 0
		[ThryWideEnum(Simple, 0, Front Face vs Back Face, 1)] _StencilType ("Stencil Type", Float) = 0
		[IntRange] _StencilRef ("Stencil Reference Value", Range(0, 255)) = 0
		[IntRange] _StencilReadMask ("Stencil ReadMask Value", Range(0, 255)) = 255
		[IntRange] _StencilWriteMask ("Stencil WriteMask Value", Range(0, 255)) = 255
		[Enum(UnityEngine.Rendering.StencilOp)] _StencilPassOp ("Stencil Pass Op--{condition_showS:(_StencilType==0)}", Float) = 0
		[Enum(UnityEngine.Rendering.StencilOp)] _StencilFailOp ("Stencil Fail Op--{condition_showS:(_StencilType==0)}", Float) = 0
		[Enum(UnityEngine.Rendering.StencilOp)] _StencilZFailOp ("Stencil ZFail Op--{condition_showS:(_StencilType==0)}", Float) = 0
		[Enum(UnityEngine.Rendering.CompareFunction)] _StencilCompareFunction ("Stencil Compare Function--{condition_showS:(_StencilType==0)}", Float) = 8
		
		[HideInInspector] m_start_StencilPassBackOptions("Back--{condition_showS:(_StencilType==1)}", Float) = 0
		[Helpbox(1)] _FFBFStencilHelp0 ("Front Face and Back Face Stencils only work when locked in due to Unity's Stencil managment", Int) = 0
		[Enum(UnityEngine.Rendering.StencilOp)] _StencilBackPassOp ("Back Pass Op", Float) = 0
		[Enum(UnityEngine.Rendering.StencilOp)] _StencilBackFailOp ("Back Fail Op", Float) = 0
		[Enum(UnityEngine.Rendering.StencilOp)] _StencilBackZFailOp ("Back ZFail Op", Float) = 0
		[Enum(UnityEngine.Rendering.CompareFunction)] _StencilBackCompareFunction ("Back Compare Function", Float) = 8
		[HideInInspector] m_end_StencilPassBackOptions("Back", Float) = 0
		
		[HideInInspector] m_start_StencilPassFrontOptions("Front--{condition_showS:(_StencilType==1)}", Float) = 0
		[Helpbox(1)] _FFBFStencilHelp1 ("Front Face and Back Face Stencils only work when locked in due to Unity's Stencil managment", Int) = 0
		[Enum(UnityEngine.Rendering.StencilOp)] _StencilFrontPassOp ("Front Pass Op", Float) = 0
		[Enum(UnityEngine.Rendering.StencilOp)] _StencilFrontFailOp ("Front Fail Op", Float) = 0
		[Enum(UnityEngine.Rendering.StencilOp)] _StencilFrontZFailOp ("Front ZFail Op", Float) = 0
		[Enum(UnityEngine.Rendering.CompareFunction)] _StencilFrontCompareFunction ("Front Compare Function", Float) = 8
		[HideInInspector] m_end_StencilPassFrontOptions("Front", Float) = 0
		
		[HideInInspector] m_end_StencilPassOptions ("Stencil", Float) = 0
		
		//ifex _EnableOutlines!=1
		// Outline Stencil
		[HideInInspector] m_start_OutlineStencil ("Outline Stencil", Float) = 0
		
		[ThryWideEnum(Simple, 0, Front Face vs Back Face, 1)] _OutlineStencilType ("Stencil Type", Float) = 0
		[IntRange] _OutlineStencilRef ("Stencil Reference Value", Range(0, 255)) = 0
		[IntRange] _OutlineStencilReadMask ("Stencil ReadMask Value", Range(0, 255)) = 255
		[IntRange] _OutlineStencilWriteMask ("Stencil WriteMask Value", Range(0, 255)) = 255
		[Enum(UnityEngine.Rendering.StencilOp)] _OutlineStencilPassOp ("Stencil Pass Op--{condition_showS:(_OutlineStencilType==0)}", Float) = 0
		[Enum(UnityEngine.Rendering.StencilOp)] _OutlineStencilFailOp ("Stencil Fail Op--{condition_showS:(_OutlineStencilType==0)}", Float) = 0
		[Enum(UnityEngine.Rendering.StencilOp)] _OutlineStencilZFailOp ("Stencil ZFail Op--{condition_showS:(_OutlineStencilType==0)}", Float) = 0
		[Enum(UnityEngine.Rendering.CompareFunction)] _OutlineStencilCompareFunction ("Stencil Compare Function--{condition_showS:(_OutlineStencilType==0)}", Float) = 8
		
		[HideInInspector] m_start_OutlineStencilPassBackOptions ("Back--{condition_showS:(_OutlineStencilType==1)}", Float) = 0
		[Helpbox(1)] _FFBFOutlineStencilHelp0 ("Front Face and Back Face Stencils only work when locked in due to Unity's Stencil managment", Int) = 0
		[Enum(UnityEngine.Rendering.StencilOp)] _OutlineStencilBackPassOp ("Back Pass Op", Float) = 0
		[Enum(UnityEngine.Rendering.StencilOp)] _OutlineStencilBackFailOp ("Back Fail Op", Float) = 0
		[Enum(UnityEngine.Rendering.StencilOp)] _OutlineStencilBackZFailOp ("Back ZFail Op", Float) = 0
		[Enum(UnityEngine.Rendering.CompareFunction)] _OutlineStencilBackCompareFunction ("Back Compare Function", Float) = 8
		[HideInInspector] m_end_OutlineStencilPassBackOptions ("Back", Float) = 0
		
		[HideInInspector] m_start_OutlineStencilPassFrontOptions ("Front--{condition_showS:(_OutlineStencilType==1)}", Float) = 0
		[Helpbox(1)] _FFBFOutlineStencilHelp1 ("Front Face and Back Face Stencils only work when locked in due to Unity's Stencil managment", Int) = 0
		[Enum(UnityEngine.Rendering.StencilOp)] _OutlineStencilFrontPassOp ("Front Pass Op", Float) = 0
		[Enum(UnityEngine.Rendering.StencilOp)] _OutlineStencilFrontFailOp ("Front Fail Op", Float) = 0
		[Enum(UnityEngine.Rendering.StencilOp)] _OutlineStencilFrontZFailOp ("Front ZFail Op", Float) = 0
		[Enum(UnityEngine.Rendering.CompareFunction)] _OutlineStencilFrontCompareFunction ("Front Compare Function", Float) = 8
		[HideInInspector] m_end_OutlineStencilPassFrontOptions ("Front", Float) = 0
		
		[HideInInspector] m_end_OutlineStencil ("Outline Stencil", Float) = 0
		//endex
		
	}
	SubShader
	{
		Tags { "RenderType" = "Opaque" "Queue" = "Geometry" "VRCFallback" = "Standard" }
		
		//ifex _RenderingEarlyZEnabled==0
		
		Pass
		{
			Name "EarlyZ"
			Tags { "LightMode" = "ForwardBase" }
			
			ZWrite On
			Cull [_Cull]
			ColorMask 0
			
			CGPROGRAM
			/*
			// Disable warnings we aren't interested in
			#if defined(UNITY_COMPILER_HLSL)
			#pragma warning(disable : 3205) // conversion of larger type to smaller
			#pragma warning(disable : 3568) // unknown pragma ignored
			#pragma warning(disable : 3571) // "pow(f,e) will not work for negative f"; however in majority of our calls to pow we know f is not negative
			#pragma warning(disable : 3206) // implicit truncation of vector type
			#endif
			*/
			#pragma target 5.0
			//ifex 0==0
			#pragma skip_optimizations d3d11
			//endex
			
			#pragma shader_feature_local _STOCHASTICMODE_DELIOT_HEITZ _STOCHASTICMODE_HEXTILE _STOCHASTICMODE_NONE
			
			//ifex _MainColorAdjustToggle==0
			#pragma shader_feature COLOR_GRADING_HDR
			//endex
			
			//#pragma shader_feature KEYWORD
			
			#pragma skip_variants LIGHTMAP_ON DYNAMICLIGHTMAP_ON LIGHTMAP_SHADOW_MIXING SHADOWS_SHADOWMASK DIRLIGHTMAP_COMBINED _MIXED_LIGHTING_SUBTRACTIVE
			#pragma skip_variants DECALS_OFF DECALS_3RT DECALS_4RT DECAL_SURFACE_GRADIENT _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3
			#pragma skip_variants _ADDITIONAL_LIGHT_SHADOWS
			#pragma skip_variants PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2
			#pragma skip_variants _SCREEN_SPACE_OCCLUSION
			
			//ifex _GlobalMaskTexturesEnable==0
			#pragma shader_feature_local POI_GLOBALMASK_TEXTURES
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#pragma shader_feature_local POI_UDIMDISCARD
			//endex
			
			//ifex _EnableDistortion==0
			#pragma shader_feature USER_LUT
			//endex
			
			//ifex _PoiParallax==0
			#pragma shader_feature_local POI_PARALLAX
			//endex
			
			//ifex _EnableAudioLink==0
			#pragma shader_feature_local POI_AUDIOLINK
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#pragma shader_feature_local POI_BLACKLIGHTMASKING
			//endex
			
			//ifex _DetailEnabled==0
			#pragma shader_feature FINALPASS
			//endex
			
			//ifex _VertexManipulationsEnabled==0
			#pragma shader_feature AUTO_EXPOSURE
			//endex
			
			//ifex _VertexGlitchingEnabled==0
			#pragma shader_feature_local POI_VERTEX_GLITCHING
			#pragma shader_feature_local POI_VERTEX_GLITCHING_TEXTURE
			//endex
			
			//ifex _EnableDepthBulge==0
			#pragma shader_feature_local POI_DEPTHBULGE
			//endex
			
			//ifex _BackFaceEnabled!=1
			#pragma shader_feature_local POI_BACKFACE
			//endex
			
			//ifex _RGBMaskEnabled==0
			#pragma shader_feature VIGNETTE
			#pragma shader_feature GEOM_TYPE_MESH
			//endex
			
			//ifex _LTCGIEnabled!=1
			#pragma shader_feature_local POI_LTCGI
			//endex
			
			//ifex _ShadingEnabled==0
			#pragma shader_feature_local VIGNETTE_MASKED
			#pragma shader_feature_local _LIGHTINGMODE_TEXTURERAMP _LIGHTINGMODE_MULTILAYER_MATH _LIGHTINGMODE_SHADEMAP _LIGHTINGMODE_REALISTIC _LIGHTINGMODE_WRAPPED _LIGHTINGMODE_SKIN _LIGHTINGMODE_FLAT _LIGHTINGMODE_CLOTH _LIGHTINGMODE_SDF
			//endex
			
			//ifex _DecalEnabled==0
			#pragma shader_feature GEOM_TYPE_BRANCH
			//endex
			//ifex _DecalEnabled1==0
			#pragma shader_feature GEOM_TYPE_BRANCH_DETAIL
			//endex
			//ifex _DecalEnabled2==0
			#pragma shader_feature GEOM_TYPE_FROND
			//endex
			//ifex _DecalEnabled3==0
			#pragma shader_feature DEPTH_OF_FIELD_COC_VIEW
			//endex
			
			//ifex _EnableDissolve==0
			#pragma shader_feature DISTORT
			//endex
			
			//ifex _EnableAniso==0
			#pragma shader_feature_local POI_ANISOTROPICS
			//endex
			
			//ifex _MatcapEnable==0
			#pragma shader_feature_local POI_MATCAP0
			#pragma shader_feature_local POI_MATCAP0_CUSTOM_NORMAL
			//endex
			//ifex _Matcap2Enable==0
			#pragma shader_feature COLOR_GRADING_HDR_3D
			#pragma shader_feature_local POI_MATCAP1_CUSTOM_NORMAL
			//endex
			//ifex _Matcap3Enable==0
			#pragma shader_feature_local POI_MATCAP2
			#pragma shader_feature_local POI_MATCAP2_CUSTOM_NORMAL
			//endex
			//ifex _Matcap4Enable==0
			#pragma shader_feature_local POI_MATCAP3
			#pragma shader_feature_local POI_MATCAP3_CUSTOM_NORMAL
			//endex
			
			//ifex _CubeMapEnabled==0
			#pragma shader_feature_local _CUBEMAP
			//endex
			
			//ifex _EnableALDecal==0
			#pragma shader_feature_local POI_AL_DECAL
			//endex
			
			//ifex _EnableVolumeColor==0
			#pragma shader_feature_local POI_AL_VOLUMECOLOR
			//endex
			
			//ifex _EnableFlipbook==0
			#pragma shader_feature _SUNDISK_HIGH_QUALITY
			//endex
			
			//ifex _EnableEmission==0
			#pragma shader_feature _EMISSION
			//endex
			//ifex _EnableEmission1==0
			#pragma shader_feature_local POI_EMISSION_1
			//endex
			//ifex _EnableEmission2==0
			#pragma shader_feature_local POI_EMISSION_2
			//endex
			//ifex _EnableEmission3==0
			#pragma shader_feature_local POI_EMISSION_3
			//endex
			
			//ifex _EnableRimLighting==0
			#pragma shader_feature_local _GLOSSYREFLECTIONS_OFF
			#pragma shader_feature_local _RIMSTYLE_POIYOMI _RIMSTYLE_UTS2 _RIMSTYLE_LILTOON
			//endex
			//ifex _EnableRim2Lighting==0
			#pragma shader_feature_local POI_RIM2
			#pragma shader_feature_local _RIM2STYLE_POIYOMI _RIM2STYLE_UTS2 _RIM2STYLE_LILTOON
			//endex
			
			//ifex _EnableDepthRimLighting==0
			#pragma shader_feature_local _POI_DEPTH_RIMLIGHT
			//endex
			
			//ifex _GlitterEnable==0
			#pragma shader_feature _SUNDISK_SIMPLE
			//endex
			
			//ifex _SubsurfaceScattering==0
			#pragma shader_feature_local POI_SUBSURFACESCATTERING
			//endex
			
			//ifex _MochieBRDF==0
			#pragma shader_feature_local MOCHIE_PBR
			//endex
			//ifex _ClearCoatBRDF==0
			#pragma shader_feature_local POI_CLEARCOAT
			//endex
			
			//ifex _EnableEnvironmentalRim==0
			#pragma shader_feature_local POI_ENVIRORIM
			//endex
			
			//ifex _StylizedSpecular==0
			#pragma shader_feature_local POI_STYLIZED_StylizedSpecular
			//endex
			
			//ifex _EnablePathing==0
			#pragma shader_feature_local POI_PATHING
			//endex
			
			//ifex _EnableMirrorOptions==0
			#pragma shader_feature_local POI_MIRROR
			//endex
			
			//ifex _EnableTouchGlow==0
			#pragma shader_feature GRAIN
			//endex
			
			//ifex _TextEnabled==0
			#pragma shader_feature EFFECT_BUMP
			//endex
			
			//ifex _PostProcess==0
			#pragma shader_feature_local POSTPROCESS
			//endex
			
			//ifex _PoiInternalParallax==0
			#pragma shader_feature_local POI_INTERNALPARALLAX
			//endex
			
			//ifex _NormalCorrect==0
			#pragma shader_feature_local POI_NORMALCORRECT
			//endex
			
			//ifex _VideoEffectsEnable==0
			#pragma shader_feature_local POI_VIDEO_EFFECTS
			//endex
			
			//ifex _BacklightEnabled!=1
			#pragma shader_feature_local POI_BACKLIGHT
			//endex
			
			//ifex _BSSEnabled!=1
			#pragma shader_feature_local POIBS_ENABLE
			//ifex _BSSBloomfog!=1
			#pragma shader_feature_local POIBS_BLOOMFOG
			#pragma shader_feature_local BSSBLOOMFOGTYPE_HEIGHT
			//endex
			//endex
			
			//ifex _VoronoiEnabled!=1
			#pragma shader_feature_local POI_VORONOI
			//endex
			
			#pragma multi_compile_instancing
			#pragma multi_compile_fog
			#define POI_PASS_EARLYZ
			
			// UNITY Includes
			#include "UnityCG.cginc"
			#include "UnityStandardUtils.cginc"
			#include "AutoLight.cginc"
			#include "UnityLightingCommon.cginc"
			#include "UnityPBSLighting.cginc"
			#ifdef POI_PASS_META
			#include "UnityMetaPass.cginc"
			#endif
			#pragma vertex vert
			
			#pragma fragment frag
			
			#define DielectricSpec float4(0.04, 0.04, 0.04, 1.0 - 0.04)
			#define PI float(3.14159265359)
			#define Epsilon float(1e-10)
			
			#define POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, samplertex, coord, dx, dy) tex.SampleGrad(sampler##samplertex, coord, dx, dy)
			#define POI2D_SAMPLE_TEX2D_SAMPLERGRADD(tex, samp, uv, pan, dx, dy) tex.SampleGrad(samp, POI_PAN_UV(uv, pan), dx, dy)
			
			#define POI_PAN_UV(uv, pan) (uv + _Time.x * pan)
			#define POI2D_SAMPLER_PAN(tex, texSampler, uv, pan) (UNITY_SAMPLE_TEX2D_SAMPLER(tex, texSampler, POI_PAN_UV(uv, pan)))
			#define POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy) (POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, texSampler, POI_PAN_UV(uv, pan), dx, dy))
			#define POI2D_SAMPLER(tex, texSampler, uv) (UNITY_SAMPLE_TEX2D_SAMPLER(tex, texSampler, uv))
			#define POI_SAMPLE_1D_X(tex, samp, uv) tex.Sample(samp, float2(uv, 0.5))
			#define POI2D_SAMPLER_GRAD(tex, texSampler, uv, dx, dy) (POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, texSampler, uv, dx, dy))
			#define POI2D_SAMPLER_GRADD(tex, texSampler, uv, dx, dy) tex.SampleGrad(texSampler, uv, dx, dy)
			#define POI2D_PAN(tex, uv, pan) (tex2D(tex, POI_PAN_UV(uv, pan)))
			#define POI2D(tex, uv) (tex2D(tex, uv))
			#define POI_SAMPLE_TEX2D(tex, uv) (UNITY_SAMPLE_TEX2D(tex, uv))
			#define POI_SAMPLE_TEX2D_PAN(tex, uv, pan) (UNITY_SAMPLE_TEX2D(tex, POI_PAN_UV(uv, pan)))
			#define POI_SAMPLE_CUBE_LOD(tex, samp, uv, lod) texCUBElod(tex, float4(uv, 0, lod))
			
			#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
			#define POI_SAMPLE_SCREEN(tex, samp, uv)          tex.Sample(samp, float3(uv, unity_StereoEyeIndex))
			#else
			#define POI_SAMPLE_SCREEN(tex, samp, uv)          tex.Sample(samp, uv)
			#endif
			
			// When using, properties won't properly lock at optimize time; needs macro evaluation implemented
			// #define POI2D_MAINTEX_SAMPLER_PAN_INLINED(tex, poiMesh) (POI2D_SAMPLER_PAN(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan))
			
			#define POI_SAFE_RGB0 float4(mainTexture.rgb * .0001, 0)
			#define POI_SAFE_RGB1 float4(mainTexture.rgb * .0001, 1)
			#define POI_SAFE_RGBA mainTexture
			
			#if defined(UNITY_COMPILER_HLSL)
			#define PoiInitStruct(type, name) name = (type)0;
			#else
			#define PoiInitStruct(type, name)
			#endif
			
			#define POI_ERROR(poiMesh, gridSize) lerp(float3(1, 0, 1), float3(0, 0, 0), fmod(floor((poiMesh.worldPos.x) * gridSize) + floor((poiMesh.worldPos.y) * gridSize) + floor((poiMesh.worldPos.z) * gridSize), 2) == 0)
			#define POI_NAN (asfloat(-1))
			
			#define POI_MODE_OPAQUE 0
			#define POI_MODE_CUTOUT 1
			#define POI_MODE_FADE 2
			#define POI_MODE_TRANSPARENT 3
			#define POI_MODE_ADDITIVE 4
			#define POI_MODE_SOFTADDITIVE 5
			#define POI_MODE_MULTIPLICATIVE 6
			#define POI_MODE_2XMULTIPLICATIVE 7
			#define POI_MODE_TRANSCLIPPING 9
			
			/*
			Texture2D ;
			float4 _ST;
			float2 Pan;
			float UV;
			float Stochastic;
			
			[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos XZ, 5, Polar UV, 6, Distorted UV, 7 )]
			*/
			
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			// Map of where features in AudioLink are.
			#define ALPASS_DFT                      uint2(0, 4)   //Size: 128, 2
			#define ALPASS_WAVEFORM                 uint2(0, 6)   //Size: 128, 16
			#define ALPASS_AUDIOLINK                uint2(0, 0)   //Size: 128, 4
			#define ALPASS_AUDIOBASS                uint2(0, 0)   //Size: 128, 1
			#define ALPASS_AUDIOLOWMIDS             uint2(0, 1)   //Size: 128, 1
			#define ALPASS_AUDIOHIGHMIDS            uint2(0, 2)   //Size: 128, 1
			#define ALPASS_AUDIOTREBLE              uint2(0, 3)   //Size: 128, 1
			#define ALPASS_AUDIOLINKHISTORY         uint2(1, 0)   //Size: 127, 4
			#define ALPASS_GENERALVU                uint2(0, 22)  //Size: 12, 1
			#define ALPASS_CCINTERNAL               uint2(12, 22) //Size: 12, 2
			#define ALPASS_CCCOLORS                 uint2(25, 22) //Size: 11, 1
			#define ALPASS_CCSTRIP                  uint2(0, 24)  //Size: 128, 1
			#define ALPASS_CCLIGHTS                 uint2(0, 25)  //Size: 128, 2
			#define ALPASS_AUTOCORRELATOR           uint2(0, 27)  //Size: 128, 1
			#define ALPASS_GENERALVU_INSTANCE_TIME  uint2(2, 22)
			#define ALPASS_GENERALVU_LOCAL_TIME     uint2(3, 22)
			#define ALPASS_GENERALVU_NETWORK_TIME   uint2(4, 22)
			#define ALPASS_GENERALVU_PLAYERINFO     uint2(6, 22)
			// Added in version 2.5
			#define ALPASS_FILTEREDAUDIOLINK        uint2(0, 28)  //Size: 16, 4
			// Added in version 2.6
			#define ALPASS_CHRONOTENSITY            uint2(16, 28) //Size: 8, 4
			#define ALPASS_THEME_COLOR0             uint2(0, 23)
			#define ALPASS_THEME_COLOR1             uint2(1, 23)
			#define ALPASS_THEME_COLOR2             uint2(2, 23)
			#define ALPASS_THEME_COLOR3             uint2(3, 23)
			#define ALPASS_FILTEREDVU               uint2(24, 28) //Size: 4, 4
			#define ALPASS_FILTEREDVU_INTENSITY     uint2(24, 28) //Size: 4, 1
			#define ALPASS_FILTEREDVU_MARKER        uint2(24, 29) //Size: 4, 1
			
			// Some basic constants to use (Note, these should be compatible with
			// future version of AudioLink, but may change.
			#define AUDIOLINK_SAMPHIST              3069        // Internal use for algos, do not change.
			#define AUDIOLINK_SAMPLEDATA24          2046
			#define AUDIOLINK_EXPBINS               24
			#define AUDIOLINK_EXPOCT                10
			#define AUDIOLINK_ETOTALBINS (AUDIOLINK_EXPBINS * AUDIOLINK_EXPOCT)
			#define AUDIOLINK_WIDTH                 128
			#define AUDIOLINK_SPS                   48000       // Samples per second
			#define AUDIOLINK_ROOTNOTE              0
			#define AUDIOLINK_4BAND_FREQFLOOR       0.123
			#define AUDIOLINK_4BAND_FREQCEILING     1
			#define AUDIOLINK_BOTTOM_FREQUENCY      13.75
			#define AUDIOLINK_BASE_AMPLITUDE        2.5
			#define AUDIOLINK_DELAY_COEFFICIENT_MIN 0.3
			#define AUDIOLINK_DELAY_COEFFICIENT_MAX 0.9
			#define AUDIOLINK_DFT_Q                 4.0
			#define AUDIOLINK_TREBLE_CORRECTION     5.0
			
			// ColorChord constants
			#define COLORCHORD_EMAXBIN              192
			#define COLORCHORD_IIR_DECAY_1          0.90
			#define COLORCHORD_IIR_DECAY_2          0.85
			#define COLORCHORD_CONSTANT_DECAY_1     0.01
			#define COLORCHORD_CONSTANT_DECAY_2     0.0
			#define COLORCHORD_NOTE_CLOSEST         3.0
			#define COLORCHORD_NEW_NOTE_GAIN        8.0
			#define COLORCHORD_MAX_NOTES            10
			
			uniform float4               _AudioTexture_TexelSize;
			
			#ifdef SHADER_TARGET_SURFACE_ANALYSIS
			#define AUDIOLINK_STANDARD_INDEXING
			#endif
			
			// Mechanism to index into texture.
			#ifdef AUDIOLINK_STANDARD_INDEXING
			sampler2D _AudioTexture;
			#define AudioLinkData(xycoord) tex2Dlod(_AudioTexture, float4(uint2(xycoord) * _AudioTexture_TexelSize.xy, 0, 0))
			#else
			uniform Texture2D<float4> _AudioTexture;
			SamplerState sampler_AudioTexture;
			#define AudioLinkData(xycoord) _AudioTexture[uint2(xycoord)]
			#endif
			uniform sampler2D _Stored;
			uniform float4 _Stored_TexelSize;
			#endif
			//endex
			
			float _RenderingEarlyZEnabled;
			
			float _IgnoreFog;
			float _RenderingReduceClipDistance;
			int _FlipBackfaceNormals;
			float _AddBlendOp;
			float _Cull;
			
			float4 _Color;
			float _ColorThemeIndex;
			UNITY_DECLARE_TEX2D(_MainTex);
			UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
			float _MainPixelMode;
			float4 _MainTex_ST;
			float2 _MainTexPan;
			float _MainTexUV;
			float4 _MainTex_TexelSize;
			float _MainTexStochastic;
			#if defined(PROP_BUMPMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BumpMap;
			#endif
			float4 _BumpMap_ST;
			float2 _BumpMapPan;
			float _BumpMapUV;
			float _BumpScale;
			float _BumpMapStochastic;
			#if defined(PROP_ALPHAMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AlphaMask;
			float4 _AlphaMask_ST;
			float2 _AlphaMaskPan;
			float _AlphaMaskUV;
			float _AlphaMaskInvert;
			float _MainAlphaMaskMode;
			float _AlphaMaskScale;
			float _AlphaMaskValue;
			#endif
			float _Cutoff;
			//ifex _MainColorAdjustToggle==0
			#ifdef COLOR_GRADING_HDR
			float _MainColorAdjustToggle;
			#if defined(PROP_MAINCOLORADJUSTTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MainColorAdjustTexture;
			#endif
			float4 _MainColorAdjustTexture_ST;
			float2 _MainColorAdjustTexturePan;
			float _MainColorAdjustTextureUV;
			float _MainHueShiftToggle;
			float _MainHueShiftReplace;
			float _MainHueShift;
			float _MainHueShiftSpeed;
			float _Saturation;
			float _MainBrightness;
			
			float _MainHueALCTEnabled;
			float _MainALHueShiftBand;
			float _MainALHueShiftCTIndex;
			float _MainHueALMotionSpeed;
			
			float _MainHueGlobalMask;
			float _MainHueGlobalMaskBlendType;
			float _MainSaturationGlobalMask;
			float _MainSaturationGlobalMaskBlendType;
			float _MainBrightnessGlobalMask;
			float _MainBrightnessGlobalMaskBlendType;
			
			#if defined(PROP_MAINGRADATIONTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MainGradationTex;
			#endif
			float _ColorGradingToggle;
			float _MainGradationStrength;
			#endif
			//endex
			
			SamplerState sampler_linear_clamp;
			SamplerState sampler_linear_repeat;
			SamplerState sampler_trilinear_repeat;
			
			//ifex _GlobalMaskTexturesEnable==0
			#ifdef POI_GLOBALMASK_TEXTURES
			#if defined(PROP_GLOBALMASKTEXTURE0) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture0;
			#endif
			float4 _GlobalMaskTexture0_ST;
			float2 _GlobalMaskTexture0Pan;
			float _GlobalMaskTexture0UV;
			int _GlobalMaskTexture0Split;
			float4 _GlobalMaskTexture0SplitTilingOffset_G;
			float4 _GlobalMaskTexture0SplitPan_G;
			float4 _GlobalMaskTexture0SplitTilingOffset_B;
			float4 _GlobalMaskTexture0SplitPan_B;
			float4 _GlobalMaskTexture0SplitTilingOffset_A;
			float4 _GlobalMaskTexture0SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture1;
			#endif
			float4 _GlobalMaskTexture1_ST;
			float2 _GlobalMaskTexture1Pan;
			float _GlobalMaskTexture1UV;
			int _GlobalMaskTexture1Split;
			float4 _GlobalMaskTexture1SplitTilingOffset_G;
			float4 _GlobalMaskTexture1SplitPan_G;
			float4 _GlobalMaskTexture1SplitTilingOffset_B;
			float4 _GlobalMaskTexture1SplitPan_B;
			float4 _GlobalMaskTexture1SplitTilingOffset_A;
			float4 _GlobalMaskTexture1SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture2;
			#endif
			float4 _GlobalMaskTexture2_ST;
			float2 _GlobalMaskTexture2Pan;
			float _GlobalMaskTexture2UV;
			int _GlobalMaskTexture2Split;
			float4 _GlobalMaskTexture2SplitTilingOffset_G;
			float4 _GlobalMaskTexture2SplitPan_G;
			float4 _GlobalMaskTexture2SplitTilingOffset_B;
			float4 _GlobalMaskTexture2SplitPan_B;
			float4 _GlobalMaskTexture2SplitTilingOffset_A;
			float4 _GlobalMaskTexture2SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE3) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture3;
			#endif
			float4 _GlobalMaskTexture3_ST;
			float2 _GlobalMaskTexture3Pan;
			float _GlobalMaskTexture3UV;
			int _GlobalMaskTexture3Split;
			float4 _GlobalMaskTexture3SplitTilingOffset_G;
			float4 _GlobalMaskTexture3SplitPan_G;
			float4 _GlobalMaskTexture3SplitTilingOffset_B;
			float4 _GlobalMaskTexture3SplitPan_B;
			float4 _GlobalMaskTexture3SplitTilingOffset_A;
			float4 _GlobalMaskTexture3SplitPan_A;
			#endif
			//endex
			//ifex _GlobalMaskOptionsEnable==0
			float _GlobalMaskOptionsEnable;
			int _GlobalMaskOptionsType;
			
			//ifex _GlobalMaskOptionsType!=0
			float _GlobalMaskSlider_0;
			float _GlobalMaskSlider_1;
			float _GlobalMaskSlider_2;
			float _GlobalMaskSlider_3;
			float _GlobalMaskSlider_4;
			float _GlobalMaskSlider_5;
			float _GlobalMaskSlider_6;
			float _GlobalMaskSlider_7;
			float _GlobalMaskSlider_8;
			float _GlobalMaskSlider_9;
			float _GlobalMaskSlider_10;
			float _GlobalMaskSlider_11;
			float _GlobalMaskSlider_12;
			float _GlobalMaskSlider_13;
			float _GlobalMaskSlider_14;
			float _GlobalMaskSlider_15;
			//endex
			
			//ifex _GlobalMaskOptionsType!=1
			float2 _GlobalMaskMinMaxSlider_0;
			float2 _GlobalMaskMinMaxSlider_1;
			float2 _GlobalMaskMinMaxSlider_2;
			float2 _GlobalMaskMinMaxSlider_3;
			float2 _GlobalMaskMinMaxSlider_4;
			float2 _GlobalMaskMinMaxSlider_5;
			float2 _GlobalMaskMinMaxSlider_6;
			float2 _GlobalMaskMinMaxSlider_7;
			float2 _GlobalMaskMinMaxSlider_8;
			float2 _GlobalMaskMinMaxSlider_9;
			float2 _GlobalMaskMinMaxSlider_10;
			float2 _GlobalMaskMinMaxSlider_11;
			float2 _GlobalMaskMinMaxSlider_12;
			float2 _GlobalMaskMinMaxSlider_13;
			float2 _GlobalMaskMinMaxSlider_14;
			float2 _GlobalMaskMinMaxSlider_15;
			//endex
			
			//ifex _GlobalMaskOptionsType!=2
			int _GlobalMaskToggleOn_0;
			int _GlobalMaskToggleOff_0;
			int _GlobalMaskToggleOn_1;
			int _GlobalMaskToggleOff_1;
			int _GlobalMaskToggleOn_2;
			int _GlobalMaskToggleOff_2;
			int _GlobalMaskToggleOn_3;
			int _GlobalMaskToggleOff_3;
			int _GlobalMaskToggleOn_4;
			int _GlobalMaskToggleOff_4;
			int _GlobalMaskToggleOn_5;
			int _GlobalMaskToggleOff_5;
			int _GlobalMaskToggleOn_6;
			int _GlobalMaskToggleOff_6;
			int _GlobalMaskToggleOn_7;
			int _GlobalMaskToggleOff_7;
			int _GlobalMaskToggleOn_8;
			int _GlobalMaskToggleOff_8;
			int _GlobalMaskToggleOn_9;
			int _GlobalMaskToggleOff_9;
			int _GlobalMaskToggleOn_10;
			int _GlobalMaskToggleOff_10;
			int _GlobalMaskToggleOn_11;
			int _GlobalMaskToggleOff_11;
			int _GlobalMaskToggleOn_12;
			int _GlobalMaskToggleOff_12;
			int _GlobalMaskToggleOn_13;
			int _GlobalMaskToggleOff_13;
			int _GlobalMaskToggleOn_14;
			int _GlobalMaskToggleOff_14;
			int _GlobalMaskToggleOn_15;
			int _GlobalMaskToggleOff_15;
			//endex
			//endex
			//ifex _GlobalMaskModifiersBackfaceEnable==0
			float _GlobalMaskModifiersBackfaceEnable;
			float _GlobalMaskBackface_0;
			float _GlobalMaskBackface_1;
			float _GlobalMaskBackface_2;
			float _GlobalMaskBackface_3;
			float _GlobalMaskBackface_4;
			float _GlobalMaskBackface_5;
			float _GlobalMaskBackface_6;
			float _GlobalMaskBackface_7;
			float _GlobalMaskBackface_8;
			float _GlobalMaskBackface_9;
			float _GlobalMaskBackface_10;
			float _GlobalMaskBackface_11;
			float _GlobalMaskBackface_12;
			float _GlobalMaskBackface_13;
			float _GlobalMaskBackface_14;
			float _GlobalMaskBackface_15;
			//endex
			
			//ifex _GlobalMaskModifiersMirrorEnable==0
			float _GlobalMaskModifiersMirrorEnable;
			float _GlobalMaskMirrorVisibilityMode;
			float _GlobalMaskMirror_0;
			float _GlobalMaskMirror_1;
			float _GlobalMaskMirror_2;
			float _GlobalMaskMirror_3;
			float _GlobalMaskMirror_4;
			float _GlobalMaskMirror_5;
			float _GlobalMaskMirror_6;
			float _GlobalMaskMirror_7;
			float _GlobalMaskMirror_8;
			float _GlobalMaskMirror_9;
			float _GlobalMaskMirror_10;
			float _GlobalMaskMirror_11;
			float _GlobalMaskMirror_12;
			float _GlobalMaskMirror_13;
			float _GlobalMaskMirror_14;
			float _GlobalMaskMirror_15;
			//endex
			
			//ifex _GlobalMaskModifiersCameraEnable==0
			float _GlobalMaskModifiersCameraEnable;
			float _GlobalMaskCamera_0;
			float _GlobalMaskCamera_1;
			float _GlobalMaskCamera_2;
			float _GlobalMaskCamera_3;
			float _GlobalMaskCamera_4;
			float _GlobalMaskCamera_5;
			float _GlobalMaskCamera_6;
			float _GlobalMaskCamera_7;
			float _GlobalMaskCamera_8;
			float _GlobalMaskCamera_9;
			float _GlobalMaskCamera_10;
			float _GlobalMaskCamera_11;
			float _GlobalMaskCamera_12;
			float _GlobalMaskCamera_13;
			float _GlobalMaskCamera_14;
			float _GlobalMaskCamera_15;
			//endex
			
			//ifex _GlobalMaskModifiersDistanceEnable==0
			int _GlobalMaskModifiersDistanceEnable;
			
			//ifex _GlobalMaskDistanceEnable_0==0
			int _GlobalMaskDistanceEnable_0;
			int _GlobalMaskDistanceType_0;
			float _GlobalMaskDistanceMin_0;
			float _GlobalMaskDistanceMax_0;
			float _GlobalMaskDistanceMinAlpha_0;
			float _GlobalMaskDistanceMaxAlpha_0;
			int _GlobalMaskDistanceBlendType_0;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_1==0
			int _GlobalMaskDistanceEnable_1;
			int _GlobalMaskDistanceType_1;
			float _GlobalMaskDistanceMin_1;
			float _GlobalMaskDistanceMax_1;
			float _GlobalMaskDistanceMinAlpha_1;
			float _GlobalMaskDistanceMaxAlpha_1;
			int _GlobalMaskDistanceBlendType_1;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_2==0
			int _GlobalMaskDistanceEnable_2;
			int _GlobalMaskDistanceType_2;
			float _GlobalMaskDistanceMin_2;
			float _GlobalMaskDistanceMax_2;
			float _GlobalMaskDistanceMinAlpha_2;
			float _GlobalMaskDistanceMaxAlpha_2;
			int _GlobalMaskDistanceBlendType_2;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_3==0
			int _GlobalMaskDistanceEnable_3;
			int _GlobalMaskDistanceType_3;
			float _GlobalMaskDistanceMin_3;
			float _GlobalMaskDistanceMax_3;
			float _GlobalMaskDistanceMinAlpha_3;
			float _GlobalMaskDistanceMaxAlpha_3;
			int _GlobalMaskDistanceBlendType_3;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_4==0
			int _GlobalMaskDistanceEnable_4;
			int _GlobalMaskDistanceType_4;
			float _GlobalMaskDistanceMin_4;
			float _GlobalMaskDistanceMax_4;
			float _GlobalMaskDistanceMinAlpha_4;
			float _GlobalMaskDistanceMaxAlpha_4;
			int _GlobalMaskDistanceBlendType_4;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_5==0
			int _GlobalMaskDistanceEnable_5;
			int _GlobalMaskDistanceType_5;
			float _GlobalMaskDistanceMin_5;
			float _GlobalMaskDistanceMax_5;
			float _GlobalMaskDistanceMinAlpha_5;
			float _GlobalMaskDistanceMaxAlpha_5;
			int _GlobalMaskDistanceBlendType_5;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_6==0
			int _GlobalMaskDistanceEnable_6;
			int _GlobalMaskDistanceType_6;
			float _GlobalMaskDistanceMin_6;
			float _GlobalMaskDistanceMax_6;
			float _GlobalMaskDistanceMinAlpha_6;
			float _GlobalMaskDistanceMaxAlpha_6;
			int _GlobalMaskDistanceBlendType_6;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_7==0
			int _GlobalMaskDistanceEnable_7;
			int _GlobalMaskDistanceType_7;
			float _GlobalMaskDistanceMin_7;
			float _GlobalMaskDistanceMax_7;
			float _GlobalMaskDistanceMinAlpha_7;
			float _GlobalMaskDistanceMaxAlpha_7;
			int _GlobalMaskDistanceBlendType_7;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_8==0
			int _GlobalMaskDistanceEnable_8;
			int _GlobalMaskDistanceType_8;
			float _GlobalMaskDistanceMin_8;
			float _GlobalMaskDistanceMax_8;
			float _GlobalMaskDistanceMinAlpha_8;
			float _GlobalMaskDistanceMaxAlpha_8;
			int _GlobalMaskDistanceBlendType_8;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_9==0
			int _GlobalMaskDistanceEnable_9;
			int _GlobalMaskDistanceType_9;
			float _GlobalMaskDistanceMin_9;
			float _GlobalMaskDistanceMax_9;
			float _GlobalMaskDistanceMinAlpha_9;
			float _GlobalMaskDistanceMaxAlpha_9;
			int _GlobalMaskDistanceBlendType_9;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_10==0
			int _GlobalMaskDistanceEnable_10;
			int _GlobalMaskDistanceType_10;
			float _GlobalMaskDistanceMin_10;
			float _GlobalMaskDistanceMax_10;
			float _GlobalMaskDistanceMinAlpha_10;
			float _GlobalMaskDistanceMaxAlpha_10;
			int _GlobalMaskDistanceBlendType_10;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_11==0
			int _GlobalMaskDistanceEnable_11;
			int _GlobalMaskDistanceType_11;
			float _GlobalMaskDistanceMin_11;
			float _GlobalMaskDistanceMax_11;
			float _GlobalMaskDistanceMinAlpha_11;
			float _GlobalMaskDistanceMaxAlpha_11;
			int _GlobalMaskDistanceBlendType_11;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_12==0
			int _GlobalMaskDistanceEnable_12;
			int _GlobalMaskDistanceType_12;
			float _GlobalMaskDistanceMin_12;
			float _GlobalMaskDistanceMax_12;
			float _GlobalMaskDistanceMinAlpha_12;
			float _GlobalMaskDistanceMaxAlpha_12;
			int _GlobalMaskDistanceBlendType_12;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_13==0
			int _GlobalMaskDistanceEnable_13;
			int _GlobalMaskDistanceType_13;
			float _GlobalMaskDistanceMin_13;
			float _GlobalMaskDistanceMax_13;
			float _GlobalMaskDistanceMinAlpha_13;
			float _GlobalMaskDistanceMaxAlpha_13;
			int _GlobalMaskDistanceBlendType_13;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_14==0
			int _GlobalMaskDistanceEnable_14;
			int _GlobalMaskDistanceType_14;
			float _GlobalMaskDistanceMin_14;
			float _GlobalMaskDistanceMax_14;
			float _GlobalMaskDistanceMinAlpha_14;
			float _GlobalMaskDistanceMaxAlpha_14;
			int _GlobalMaskDistanceBlendType_14;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_15==0
			int _GlobalMaskDistanceEnable_15;
			int _GlobalMaskDistanceType_15;
			float _GlobalMaskDistanceMin_15;
			float _GlobalMaskDistanceMax_15;
			float _GlobalMaskDistanceMinAlpha_15;
			float _GlobalMaskDistanceMaxAlpha_15;
			int _GlobalMaskDistanceBlendType_15;
			//endex
			//endex
			
			int _GlobalMaskVertexColorLinearSpace;
			//ifex _GlobalMaskVertexColorRed==0
			int _GlobalMaskVertexColorRed;
			int _GlobalMaskVertexColorRedBlendType;
			//endex
			//ifex _GlobalMaskVertexColorGreen==0
			int _GlobalMaskVertexColorGreen;
			int _GlobalMaskVertexColorGreenBlendType;
			//endex
			//ifex _GlobalMaskVertexColorBlue==0
			int _GlobalMaskVertexColorBlue;
			int _GlobalMaskVertexColorBlueBlendType;
			//endex
			//ifex _GlobalMaskVertexColorAlpha==0
			int _GlobalMaskVertexColorAlpha;
			int _GlobalMaskVertexColorAlphaBlendType;
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#ifdef POI_UDIMDISCARD
			float _UDIMDiscardMode;
			float _UDIMDiscardUV;
			float _UDIMDiscardRow3_0;
			float _UDIMDiscardRow3_1;
			float _UDIMDiscardRow3_2;
			float _UDIMDiscardRow3_3;
			float _UDIMDiscardRow2_0;
			float _UDIMDiscardRow2_1;
			float _UDIMDiscardRow2_2;
			float _UDIMDiscardRow2_3;
			float _UDIMDiscardRow1_0;
			float _UDIMDiscardRow1_1;
			float _UDIMDiscardRow1_2;
			float _UDIMDiscardRow1_3;
			float _UDIMDiscardRow0_0;
			float _UDIMDiscardRow0_1;
			float _UDIMDiscardRow0_2;
			float _UDIMDiscardRow0_3;
			#endif
			//endex
			
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			float _AudioLinkDelay;
			float _AudioLinkAnimToggle;
			
			float _AudioLinkSmoothingBass;
			float _AudioLinkSmoothingLowMid;
			float _AudioLinkSmoothingHighMid;
			float _AudioLinkSmoothingTreble;
			
			float _DebugWaveform;
			float _DebugDFT;
			float _DebugBass;
			float _DebugLowMids;
			float _DebugHighMids;
			float _DebugTreble;
			float _DebugCCColors;
			float _DebugCCStrip;
			float _DebugCCLights;
			float _DebugAutocorrelator;
			float _DebugChronotensity;
			float _AudioLinkCCStripY;
			
			float _AudioLinkBandOverridesEnabled;
			float4 _AudioLinkBandOverrideSliders;
			#endif
			//endex
			
			//ifex _VertexManipulationsEnabled==0
			#ifdef AUTO_EXPOSURE
			float4 _VertexManipulationLocalTranslation;
			float4 _VertexManipulationLocalRotation;
			float3 _VertexManipulationLocalRotationSpeed;
			float4 _VertexManipulationLocalScale;
			float4 _VertexManipulationWorldTranslation;
			float _VertexManipulationHeight;
			sampler2D _VertexManipulationHeightMask;
			float4 _VertexManipulationHeightMask_ST;
			float2 _VertexManipulationHeightMaskPan;
			float _VertexManipulationHeightMaskUV;
			float _VertexManipulationHeightMaskChannel;
			float _VertexManipulationHeightBias;
			float _VertexRoundingEnabled;
			int _VertexRoundingSpace;
			float _VertexRoundingDivision;
			
			//AL
			float _VertexAudioLinkEnabled;
			float3 _VertexLocalTranslationALMin;
			float3 _VertexLocalTranslationALMax;
			float _VertexLocalTranslationALBand;
			
			float3 _VertexLocalRotationAL;
			float _VertexLocalRotationALBand;
			
			float3 _VertexLocalRotationCTALSpeed;
			float _VertexLocalRotationCTALBandX;
			float _VertexLocalRotationCTALBandY;
			float _VertexLocalRotationCTALBandZ;
			float _VertexLocalRotationCTALTypeX;
			float _VertexLocalRotationCTALTypeY;
			float _VertexLocalRotationCTALTypeZ;
			
			float4 _VertexLocalScaleALMin;
			float4 _VertexLocalScaleALMax;
			float _VertexLocalScaleALBand;
			
			float3 _VertexWorldTranslationALMin;
			float3 _VertexWorldTranslationALMax;
			float _VertexWorldTranslationALBand;
			
			float2 _VertexManipulationHeightAL;
			float _VertexManipulationHeightBand;
			
			float2 _VertexRoundingRangeAL;
			float _VertexRoundingRangeBand;
			
			float _VertexBarrelMode;
			float _VertexBarrelWidth;
			float _VertexBarrelAlpha;
			float _VertexBarrelHeight;
			
			float _VertexSphereMode;
			float _VertexSphereRadius;
			float _VertexSphereHeight;
			float _VertexSphereAlpha;
			float4 _VertexSphereCenter;
			
			float _VertexTornadoMode;
			float _VertexTornadoRadius;
			float _VertexTornadoSpeed;
			float _VertexTornadoIntensity;
			float _VertexTornadoBaseHeight;
			float _VertexTornadoTopHeight;
			
			float _VertexSpectrumMotion;
			float3 _VertexSpectrumOffsetMin;
			float3 _VertexSpectrumOffsetMax;
			float _VertexSpectrumUV;
			float _VertexSpectrumUVDirection;
			#endif
			//endex
			
			//ifex _VertexGlitchingEnabled==0
			#ifdef POI_VERTEX_GLITCHING
			//Vertex Glitching
			#if defined(POI_VERTEX_GLITCHING_TEXTURE)
			float _VertexGlitchingUseTexture;
			sampler2D _VertexGlitchMap;
			float4 _VertexGlitchMap_ST;
			#endif
			float _VertexGlitchThreshold;
			float _VertexGlitchFrequency;
			float _VertexGlitchStrength;
			float _VertexGlitchDensity;
			
			float _VertexGlitchMirrorEnable;
			float _VertexGlitchMirror;
			
			float _VertexGlitchMapPanSpeed;
			float _VertexGlitchingAudioLinkEnabled;
			float _VertexGlitchingAudioLinkBand;
			float _VertexGlitchingAudiolinkOverride;
			#endif
			//endex
			
			//ifex _EnableDissolve==0
			#ifdef DISTORT
			float _DissolveType;
			float _DissolveEdgeWidth;
			float4 _DissolveEdgeColor;
			sampler2D _DissolveEdgeGradient;
			float4 _DissolveEdgeGradient_ST;
			float2 _DissolveEdgeGradientPan;
			float _DissolveEdgeGradientUV;
			float _DissolveEdgeEmission;
			float4 _DissolveTextureColor;
			float _DissolveEdgeColorThemeIndex;
			float _DissolveTextureColorThemeIndex;
			
			#if defined(PROP_DISSOLVETOTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveToTexture;
			#endif
			float4 _DissolveToTexture_ST;
			float2 _DissolveToTexturePan;
			float _DissolveToTextureUV;
			
			#if defined(PROP_DISSOLVENOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveNoiseTexture;
			#endif
			float4 _DissolveNoiseTexture_ST;
			float2 _DissolveNoiseTexturePan;
			float _DissolveNoiseTextureUV;
			
			#if defined(PROP_DISSOLVEDETAILNOISE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveDetailNoise;
			#endif
			float4 _DissolveDetailNoise_ST;
			float2 _DissolveDetailNoisePan;
			float _DissolveDetailNoiseUV;
			
			#if defined(PROP_DISSOLVEMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveMask;
			#endif
			float4 _DissolveMask_ST;
			float2 _DissolveMaskPan;
			float _DissolveMaskUV;
			
			float _DissolveMaskGlobalMask;
			float _DissolveMaskGlobalMaskBlendType;
			float _DissolveApplyGlobalMaskIndex;
			float _DissolveApplyGlobalMaskBlendType;
			float _DissolveInverseApplyGlobalMaskBlendType;
			float _DissolveInverseApplyGlobalMaskIndex;
			float _DissolveMaskInvert;
			float _DissolveAlpha;
			float _ContinuousDissolve;
			float _DissolveDetailStrength;
			float _DissolveDetailEdgeSmoothing;
			float _DissolveEdgeHardness;
			float _DissolveInvertNoise;
			float _DissolveInvertDetailNoise;
			float _DissolveToEmissionStrength;
			
			// Point to Point
			float _DissolveP2PWorldLocal;
			float _DissolveP2PEdgeLength;
			float _DissolveP2PClamp;
			float4 _DissolveStartPoint;
			float4 _DissolveEndPoint;
			
			// Spherical
			float3 _SphericalDissolveCenter;
			float _SphericalDissolveRadius;
			float _SphericalDissolveInvert;
			float _SphericalDissolveClamp;
			
			// CenterOut
			float _CenterOutDissolveMode;
			float3 _CenterOutDissolveDirection;
			float _CenterOutDissolveInvert;
			float _CenterOutDissolveNormals;
			float _CenterOutDissolvePower;
			
			// World Dissolve
			float _DissolveWorldShape;
			float4 _DissolveShapePosition;
			float4 _DissolveShapeRotation;
			float _DissolveShapeScale;
			float _DissolveInvertShape;
			float _DissolveShapeEdgeLength;
			
			// UV Tile Dissolve
			float _UVTileDissolveEnabled;
			float _UVTileDissolveDiscardAtMax;
			float _UVTileDissolveUV;
			
			float _UVTileDissolveAlpha_Row3_0;
			float _UVTileDissolveAlpha_Row3_1;
			float _UVTileDissolveAlpha_Row3_2;
			float _UVTileDissolveAlpha_Row3_3;
			float _UVTileDissolveAlpha_Row2_0;
			float _UVTileDissolveAlpha_Row2_1;
			float _UVTileDissolveAlpha_Row2_2;
			float _UVTileDissolveAlpha_Row2_3;
			float _UVTileDissolveAlpha_Row1_0;
			float _UVTileDissolveAlpha_Row1_1;
			float _UVTileDissolveAlpha_Row1_2;
			float _UVTileDissolveAlpha_Row1_3;
			float _UVTileDissolveAlpha_Row0_0;
			float _UVTileDissolveAlpha_Row0_1;
			float _UVTileDissolveAlpha_Row0_2;
			float _UVTileDissolveAlpha_Row0_3;
			
			float _DissolveAlpha0;
			float _DissolveAlpha1;
			float _DissolveAlpha2;
			float _DissolveAlpha3;
			float _DissolveAlpha4;
			float _DissolveAlpha5;
			float _DissolveAlpha6;
			float _DissolveAlpha7;
			float _DissolveAlpha8;
			float _DissolveAlpha9;
			// Masking
			float _DissolveEmissionSide;
			float _DissolveEmission1Side;
			float _DissolveUseVertexColors;
			
			float4 edgeColor;
			float edgeAlpha;
			float dissolveAlpha;
			float4 dissolveToTexture;
			
			float _DissolveHueShiftEnabled;
			float _DissolveHueShiftSpeed;
			float _DissolveHueShift;
			float _DissolveEdgeHueShiftEnabled;
			float _DissolveEdgeHueShiftSpeed;
			float _DissolveEdgeHueShift;
			
			// Audio Link
			#ifdef POI_AUDIOLINK
			fixed _EnableDissolveAudioLink;
			half _AudioLinkDissolveAlphaBand;
			float2 _AudioLinkDissolveAlpha;
			half _AudioLinkDissolveDetailBand;
			float2 _AudioLinkDissolveDetail;
			#endif
			#endif
			//endex
			
			//ifex _EnableMirrorOptions==0
			#ifdef POI_MIRROR
			float _VisibilityMode;
			float _Mirror;
			#if defined(PROP_MIRRORTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MirrorTexture;
			#endif
			float4 _MirrorColor;
			float _MirrorColorThemeIndex;
			float _MirrorTextureBlendType;
			float4 _MirrorTexture_ST;
			float2 _MirrorTexturePan;
			float _MirrorTextureUV;
			float _MirrorTextureEnabled;
			float _MirrorTextureForceEnabled;
			float _VisibilityVRCRegular;
			float _VisibilityVRCMirrorVR;
			float _VisibilityVRCMirrorDesktop;
			float _VisibilityVRCCameraVR;
			float _VisibilityVRCCameraDesktop;
			float _VisibilityVRCCameraScreenshot;
			#endif
			//endex
			
			//ifex _BSSEnabled!=1
			#ifdef POIBS_ENABLE
			float _CustomColors;
			//ifex _BSSBloomfog!=1
			#ifdef POIBS_BLOOMFOG
			float _FogStartOffset;
			float _FogScale;
			float _FogHeightOffset;
			float _FogHeightScale;
			
			uniform float2 _CustomFogTextureToScreenRatio;
			uniform float _StereoCameraEyeOffset;
			
			uniform float _CustomFogOffset;
			uniform float _CustomFogAttenuation;
			uniform float _CustomFogHeightFogStartY;
			uniform float _CustomFogHeightFogHeight;
			uniform sampler2D _BloomPrePassTexture;
			#endif
			//endex
			#endif
			//endex
			
			struct appdata
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 tangent : TANGENT;
				float4 color : COLOR;
				float2 uv0 : TEXCOORD0;
				float2 uv1 : TEXCOORD1;
				float2 uv2 : TEXCOORD2;
				float2 uv3 : TEXCOORD3;
				uint vertexId : SV_VertexID;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};
			
			struct VertexOut
			{
				float4 pos : SV_POSITION;
				float4 uv[2] : TEXCOORD0;
				float3 normal : TEXCOORD2;
				float4 tangent : TEXCOORD3;
				float4 worldPos : TEXCOORD4;
				float4 localPos : TEXCOORD5;
				float4 vertexColor : TEXCOORD6;
				float4 lightmapUV : TEXCOORD7;
				float2 fogCoord: TEXCOORD10;
				UNITY_SHADOW_COORDS(11)
				
				UNITY_VERTEX_INPUT_INSTANCE_ID
				UNITY_VERTEX_OUTPUT_STEREO
			};
			
			struct PoiMesh
			{
				
				// 0 Vertex normal
				// 1 Fragment normal
				float3 normals[2];
				float3 objNormal;
				float3 tangentSpaceNormal;
				float3 binormal[2];
				float3 tangent[2];
				float3 worldPos;
				float3 localPos;
				float3 objectPosition;
				float isFrontFace;
				float4 vertexColor;
				float4 lightmapUV;
				// 0-3 UV0-UV3
				// 4 Panosphere UV
				// 5 world pos xz
				// 6 Polar UV
				// 7 Distorted UV
				float2 uv[9];
				float2 parallaxUV;
				float2 dx;
				float2 dy;
			};
			
			struct PoiCam
			{
				float3 viewDir;
				float3 forwardDir;
				float3 worldPos;
				float distanceToVert;
				float4 clipPos;
				float4 screenSpacePosition;
				float3 reflectionDir;
				float3 vertexReflectionDir;
				float3 tangentViewDir;
				float4 posScreenSpace;
				float2 posScreenPixels;
				float2 screenUV;
				float vDotN;
				float4 worldDirection;
				
			};
			
			struct PoiMods
			{
				float4 Mask;
				float audioLink[5];
				float audioLinkAvailable;
				float audioLinkVersion;
				float4 audioLinkTexture;
				float2 detailMask;
				float2 backFaceDetailIntensity;
				float globalEmission;
				float4 globalColorTheme[12];
				float globalMask[16];
				float ALTime[8];
			};
			
			struct PoiLight
			{
				
				float3 direction;
				float attenuation;
				float attenuationStrength;
				float3 directColor;
				float3 indirectColor;
				float occlusion;
				float shadowMask;
				float detailShadow;
				float3 halfDir;
				float lightMap;
				float lightMapNoAttenuation;
				float3 rampedLightMap;
				float vertexNDotL;
				float nDotL;
				float nDotV;
				float vertexNDotV;
				float nDotH;
				float vertexNDotH;
				float lDotv;
				float lDotH;
				float nDotLSaturated;
				float nDotLNormalized;
				#ifdef POI_PASS_ADD
				float additiveShadow;
				#endif
				float3 finalLighting;
				float3 finalLightAdd;
				float3 LTCGISpecular;
				float3 LTCGIDiffuse;
				float directLuminance;
				float indirectLuminance;
				float finalLuminance;
				
				#if defined(VERTEXLIGHT_ON)
				// Non Important Lights
				float4 vDotNL;
				float4 vertexVDotNL;
				float3 vColor[4];
				float4 vCorrectedDotNL;
				float4 vAttenuation;
				float4 vSaturatedDotNL;
				float3 vPosition[4];
				float3 vDirection[4];
				float3 vFinalLighting;
				float3 vHalfDir[4];
				half4 vDotNH;
				half4 vertexVDotNH;
				half4 vDotLH;
				#endif
				
			};
			
			struct PoiVertexLights
			{
				
				float3 direction;
				float3 color;
				float attenuation;
			};
			
			struct PoiFragData
			{
				float smoothness;
				float smoothness2;
				float metallic;
				float specularMask;
				float reflectionMask;
				
				float3 baseColor;
				float3 finalColor;
				float alpha;
				float3 emission;
				float toggleVertexLights;
			};
			
			float4 poiTransformClipSpacetoScreenSpaceFrag(float4 clipPos)
			{
				float4 positionSS = float4(clipPos.xyz * clipPos.w, clipPos.w);
				positionSS.xy = positionSS.xy / _ScreenParams.xy;
				return positionSS;
			}
			
			// glsl_mod behaves better on negative numbers, and
			// in some situations actually outperforms HLSL's fmod()
			#ifndef glsl_mod
			#define glsl_mod(x, y) (((x) - (y) * floor((x) / (y))))
			#endif
			
			uniform float random_uniform_float_only_used_to_stop_compiler_warnings = 0.0f;
			
			float2 poiUV(float2 uv, float4 tex_st)
			{
				return uv * tex_st.xy + tex_st.zw;
			}
			
			float2 vertexUV(in VertexOut o, int index)
			{
				switch(index)
				{
					case 0:
					return o.uv[0].xy;
					case 1:
					return o.uv[0].zw;
					case 2:
					return o.uv[1].xy;
					case 3:
					return o.uv[1].zw;
					default:
					return o.uv[0].xy;
				}
			}
			
			float2 vertexUV(in appdata v, int index)
			{
				switch(index)
				{
					case 0:
					return v.uv0.xy;
					case 1:
					return v.uv1.xy;
					case 2:
					return v.uv2.xy;
					case 3:
					return v.uv3.xy;
					default:
					return v.uv0.xy;
				}
			}
			
			//Lighting Helpers
			float calculateluminance(float3 color)
			{
				return color.r * 0.299 + color.g * 0.587 + color.b * 0.114;
			}
			
			// Set by VRChat (as of open beta 1245)
			// _VRChatCameraMode: 0 => Normal, 1 => VR HandCam, 2 => Desktop Handcam, 3 => Screenshot/Photo
			// _VRChatMirrorMode: 0 => Normal, 1 => Mirror (VR), 2 => Mirror (Deskie)
			float _VRChatCameraMode;
			float _VRChatMirrorMode;
			
			float VRCCameraMode()
			{
				return _VRChatCameraMode;
			}
			
			float VRCMirrorMode()
			{
				return _VRChatMirrorMode;
			}
			
			bool IsInMirror()
			{
				return unity_CameraProjection[2][0] != 0.f || unity_CameraProjection[2][1] != 0.f;
			}
			
			bool IsOrthographicCamera()
			{
				return unity_OrthoParams.w == 1 || UNITY_MATRIX_P[3][3] == 1;
			}
			
			float shEvaluateDiffuseL1Geomerics_local(float L0, float3 L1, float3 n)
			{
				// average energy
				float R0 = max(0, L0);
				
				// avg direction of incoming light
				float3 R1 = 0.5f * L1;
				
				// directional brightness
				float lenR1 = length(R1);
				
				// linear angle between normal and direction 0-1
				//float q = 0.5f * (1.0f + dot(R1 / lenR1, n));
				//float q = dot(R1 / lenR1, n) * 0.5 + 0.5;
				float q = dot(normalize(R1), n) * 0.5 + 0.5;
				q = saturate(q); // Thanks to ScruffyRuffles for the bug identity.
				
				// power for q
				// lerps from 1 (linear) to 3 (cubic) based on directionality
				float p = 1.0f + 2.0f * lenR1 / R0;
				
				// dynamic range constant
				// should vary between 4 (highly directional) and 0 (ambient)
				float a = (1.0f - lenR1 / R0) / (1.0f + lenR1 / R0);
				
				return R0 * (a + (1.0f - a) * (p + 1.0f) * pow(q, p));
			}
			
			half3 BetterSH9(half4 normal)
			{
				float3 indirect;
				float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) + float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0;
				indirect.r = shEvaluateDiffuseL1Geomerics_local(L0.r, unity_SHAr.xyz, normal.xyz);
				indirect.g = shEvaluateDiffuseL1Geomerics_local(L0.g, unity_SHAg.xyz, normal.xyz);
				indirect.b = shEvaluateDiffuseL1Geomerics_local(L0.b, unity_SHAb.xyz, normal.xyz);
				indirect = max(0, indirect);
				indirect += SHEvalLinearL2(normal);
				return indirect;
			}
			
			// Silent's code ends here
			
			float3 getCameraForward()
			{
				#if UNITY_SINGLE_PASS_STEREO
				float3 p1 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 1, 1));
				float3 p2 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 0, 1));
				#else
				float3 p1 = mul(unity_CameraToWorld, float4(0, 0, 1, 1)).xyz;
				float3 p2 = mul(unity_CameraToWorld, float4(0, 0, 0, 1)).xyz;
				#endif
				return normalize(p2 - p1);
			}
			
			half3 GetSHLength()
			{
				half3 x, x1;
				x.r = length(unity_SHAr);
				x.g = length(unity_SHAg);
				x.b = length(unity_SHAb);
				x1.r = length(unity_SHBr);
				x1.g = length(unity_SHBg);
				x1.b = length(unity_SHBb);
				return x + x1;
			}
			
			float3 BoxProjection(float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax)
			{
				#if UNITY_SPECCUBE_BOX_PROJECTION
				//UNITY_BRANCH
				if (cubemapPosition.w > 0)
				{
					float3 factors = ((direction > 0 ? boxMax : boxMin) - position) / direction;
					float scalar = min(min(factors.x, factors.y), factors.z);
					direction = direction * scalar + (position - cubemapPosition.xyz);
				}
				#endif
				return direction;
			}
			
			float poiMax(float2 i)
			{
				return max(i.x, i.y);
			}
			
			float poiMax(float3 i)
			{
				return max(max(i.x, i.y), i.z);
			}
			
			float poiMax(float4 i)
			{
				return max(max(max(i.x, i.y), i.z), i.w);
			}
			
			float3 calculateNormal(in float3 baseNormal, in PoiMesh poiMesh, in Texture2D normalTexture, in float4 normal_ST, in float2 normalPan, in float normalUV, in float normalIntensity)
			{
				float3 normal = UnpackScaleNormal(POI2D_SAMPLER_PAN(normalTexture, _MainTex, poiUV(poiMesh.uv[normalUV], normal_ST), normalPan), normalIntensity);
				return normalize(
				normal.x * poiMesh.tangent[0] +
				normal.y * poiMesh.binormal[0] +
				normal.z * baseNormal
				);
			}
			
			float remap(float x, float minOld, float maxOld, float minNew = 0, float maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float2 remap(float2 x, float2 minOld, float2 maxOld, float2 minNew = 0, float2 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float3 remap(float3 x, float3 minOld, float3 maxOld, float3 minNew = 0, float3 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float4 remap(float4 x, float4 minOld, float4 maxOld, float4 minNew = 0, float4 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float remapClamped(float minOld, float maxOld, float x, float minNew = 0, float maxNew = 1)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float2 remapClamped(float2 minOld, float2 maxOld, float2 x, float2 minNew, float2 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float3 remapClamped(float3 minOld, float3 maxOld, float3 x, float3 minNew, float3 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float4 remapClamped(float4 minOld, float4 maxOld, float4 x, float4 minNew, float4 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			float2 calcParallax(in float height, in PoiCam poiCam)
			{
				return ((height * - 1) + 1) * (poiCam.tangentViewDir.xy / poiCam.tangentViewDir.z);
			}
			
			/*
			0: Zero	                float4(0.0, 0.0, 0.0, 0.0),
			1: One	                float4(1.0, 1.0, 1.0, 1.0),
			2: DstColor	            destinationColor,
			3: SrcColor	            sourceColor,
			4: OneMinusDstColor	    float4(1.0, 1.0, 1.0, 1.0) - destinationColor,
			5: SrcAlpha	            sourceColor.aaaa,
			6: OneMinusSrcColor	    float4(1.0, 1.0, 1.0, 1.0) - sourceColor,
			7: DstAlpha	            destinationColor.aaaa,
			8: OneMinusDstAlpha	    float4(1.0, 1.0, 1.0, 1.0) - destinationColor.,
			9: SrcAlphaSaturate     saturate(sourceColor.aaaa),
			10: OneMinusSrcAlpha	float4(1.0, 1.0, 1.0, 1.0) - sourceColor.aaaa,
			*/
			
			float4 poiBlend(const float sourceFactor, const  float4 sourceColor, const  float destinationFactor, const  float4 destinationColor, const float4 blendFactor)
			{
				float4 sA = 1 - blendFactor;
				const float4 blendData[11] = {
					float4(0.0, 0.0, 0.0, 0.0),
					float4(1.0, 1.0, 1.0, 1.0),
					destinationColor,
					sourceColor,
					float4(1.0, 1.0, 1.0, 1.0) - destinationColor,
					sA,
					float4(1.0, 1.0, 1.0, 1.0) - sourceColor,
					sA,
					float4(1.0, 1.0, 1.0, 1.0) - sA,
					saturate(sourceColor.aaaa),
					1 - sA,
				};
				
				return lerp(blendData[sourceFactor] * sourceColor + blendData[destinationFactor] * destinationColor, sourceColor, sA);
			}
			
			// Average
			float blendAverage(float base, float blend)
			{
				return (base + blend) / 2.0;
			}
			float3 blendAverage(float3 base, float3 blend)
			{
				return (base + blend) / 2.0;
			}
			
			// Color burn
			float blendColorBurn(float base, float blend)
			{
				return (blend == 0.0) ? blend : max((1.0 - ((1.0 - base) * rcp(random_uniform_float_only_used_to_stop_compiler_warnings + blend))), 0.0);
			}
			
			float3 blendColorBurn(float3 base, float3 blend)
			{
				return float3(blendColorBurn(base.r, blend.r), blendColorBurn(base.g, blend.g), blendColorBurn(base.b, blend.b));
			}
			
			// Color Dodge
			float blendColorDodge(float base, float blend)
			{
				return (blend == 1.0) ? blend : min(base / (1.0 - blend), 1.0);
			}
			
			float3 blendColorDodge(float3 base, float3 blend)
			{
				return float3(blendColorDodge(base.r, blend.r), blendColorDodge(base.g, blend.g), blendColorDodge(base.b, blend.b));
			}
			
			// Darken
			float blendDarken(float base, float blend)
			{
				return min(blend, base);
			}
			
			float3 blendDarken(float3 base, float3 blend)
			{
				return float3(blendDarken(base.r, blend.r), blendDarken(base.g, blend.g), blendDarken(base.b, blend.b));
			}
			
			// Exclusion
			float blendExclusion(float base, float blend)
			{
				return base + blend - 2.0 * base * blend;
			}
			float3 blendExclusion(float3 base, float3 blend)
			{
				return base + blend - 2.0 * base * blend;
			}
			
			// Reflect
			float blendReflect(float base, float blend)
			{
				return (blend == 1.0) ? blend : min(base * base / (1.0 - blend), 1.0);
			}
			
			float3 blendReflect(float3 base, float3 blend)
			{
				return float3(blendReflect(base.r, blend.r), blendReflect(base.g, blend.g), blendReflect(base.b, blend.b));
			}
			
			// Glow
			float blendGlow(float base, float blend)
			{
				return blendReflect(blend, base);
			}
			float3 blendGlow(float3 base, float3 blend)
			{
				return blendReflect(blend, base);
			}
			
			// Overlay
			float blendOverlay(float base, float blend)
			{
				return base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend));
			}
			
			float3 blendOverlay(float3 base, float3 blend)
			{
				return float3(blendOverlay(base.r, blend.r), blendOverlay(base.g, blend.g), blendOverlay(base.b, blend.b));
			}
			
			// Hard Light
			float blendHardLight(float base, float blend)
			{
				return blendOverlay(blend, base);
			}
			float3 blendHardLight(float3 base, float3 blend)
			{
				return blendOverlay(blend, base);
			}
			
			// Vivid light
			float blendVividLight(float base, float blend)
			{
				return (blend < 0.5) ? blendColorBurn(base, (2.0 * blend)) : blendColorDodge(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendVividLight(float3 base, float3 blend)
			{
				return float3(blendVividLight(base.r, blend.r), blendVividLight(base.g, blend.g), blendVividLight(base.b, blend.b));
			}
			
			// Hard mix
			float blendHardMix(float base, float blend)
			{
				return (blendVividLight(base, blend) < 0.5) ? 0.0 : 1.0;
			}
			
			float3 blendHardMix(float3 base, float3 blend)
			{
				return float3(blendHardMix(base.r, blend.r), blendHardMix(base.g, blend.g), blendHardMix(base.b, blend.b));
			}
			
			// Lighten
			float blendLighten(float base, float blend)
			{
				return max(blend, base);
			}
			
			float3 blendLighten(float3 base, float3 blend)
			{
				return float3(blendLighten(base.r, blend.r), blendLighten(base.g, blend.g), blendLighten(base.b, blend.b));
			}
			
			// Linear Burn
			float blendLinearBurn(float base, float blend)
			{
				// Note : Same implementation as BlendSubtractf
				return max(base + blend - 1.0, 0.0);
			}
			
			float3 blendLinearBurn(float3 base, float3 blend)
			{
				// Note : Same implementation as BlendSubtract
				return max(base + blend - float3(1.0, 1.0, 1.0), float3(0.0, 0.0, 0.0));
			}
			
			// Linear Dodge
			float blendLinearDodge(float base, float blend)
			{
				// Note : Same implementation as BlendAddf
				return min(base + blend, 1.0);
			}
			
			float3 blendLinearDodge(float3 base, float3 blend)
			{
				// Note : Same implementation as BlendAdd
				return base + blend;
			}
			
			// Linear light
			float blendLinearLight(float base, float blend)
			{
				return blend < 0.5 ? blendLinearBurn(base, (2.0 * blend)) : blendLinearDodge(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendLinearLight(float3 base, float3 blend)
			{
				return float3(blendLinearLight(base.r, blend.r), blendLinearLight(base.g, blend.g), blendLinearLight(base.b, blend.b));
			}
			
			// Multiply
			float blendMultiply(float base, float blend)
			{
				return base * blend;
			}
			float3 blendMultiply(float3 base, float3 blend)
			{
				return base * blend;
			}
			
			// Negation
			float blendNegation(float base, float blend)
			{
				return 1.0 - abs(1.0 - base - blend);
			}
			float3 blendNegation(float3 base, float3 blend)
			{
				return float3(1.0, 1.0, 1.0) - abs(float3(1.0, 1.0, 1.0) - base - blend);
			}
			
			// Normal
			float blendNormal(float base, float blend)
			{
				return blend;
			}
			float3 blendNormal(float3 base, float3 blend)
			{
				return blend;
			}
			
			// Phoenix
			float blendPhoenix(float base, float blend)
			{
				return min(base, blend) - max(base, blend) + 1.0;
			}
			float3 blendPhoenix(float3 base, float3 blend)
			{
				return min(base, blend) - max(base, blend) + float3(1.0, 1.0, 1.0);
			}
			
			// Pin light
			float blendPinLight(float base, float blend)
			{
				return (blend < 0.5) ? blendDarken(base, (2.0 * blend)) : blendLighten(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendPinLight(float3 base, float3 blend)
			{
				return float3(blendPinLight(base.r, blend.r), blendPinLight(base.g, blend.g), blendPinLight(base.b, blend.b));
			}
			
			// Screen
			float blendScreen(float base, float blend)
			{
				return 1.0 - ((1.0 - base) * (1.0 - blend));
			}
			
			float3 blendScreen(float3 base, float3 blend)
			{
				return float3(blendScreen(base.r, blend.r), blendScreen(base.g, blend.g), blendScreen(base.b, blend.b));
			}
			
			// Soft Light
			float blendSoftLight(float base, float blend)
			{
				return (blend < 0.5) ? (2.0 * base * blend + base * base * (1.0 - 2.0 * blend)) : (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend));
			}
			
			float3 blendSoftLight(float3 base, float3 blend)
			{
				return float3(blendSoftLight(base.r, blend.r), blendSoftLight(base.g, blend.g), blendSoftLight(base.b, blend.b));
			}
			
			// Subtract
			float blendSubtract(float base, float blend)
			{
				return max(base - blend, 0.0);
			}
			
			float3 blendSubtract(float3 base, float3 blend)
			{
				return max(base - blend, 0.0);
			}
			
			// Difference
			float blendDifference(float base, float blend)
			{
				return abs(base - blend);
			}
			
			float3 blendDifference(float3 base, float3 blend)
			{
				return abs(base - blend);
			}
			
			// Divide
			float blendDivide(float base, float blend)
			{
				return base / max(blend, 0.0001);
			}
			
			float3 blendDivide(float3 base, float3 blend)
			{
				return base / max(blend, 0.0001);
			}
			
			float blendMixed(float base, float blend)
			{
				return base + base * blend;
			}
			
			float3 blendMixed(float3 base, float3 blend)
			{
				return base + base * blend;
			}
			
			float3 customBlend(float3 base, float3 blend, float blendType, float alpha = 1)
			{
				float3 output = base;
				switch(blendType)
				{
					case 0: output = lerp(base, blend, alpha); break;
					case 1: output = lerp(base, blendDarken(base, blend), alpha); break;
					case 2: output = base * lerp(1, blend, alpha); break;
					case 5: output = lerp(base, blendLighten(base, blend), alpha); break;
					case 6: output = lerp(base, blendScreen(base, blend), alpha); break;
					case 7: output = blendSubtract(base, blend * alpha); break;
					case 8: output = lerp(base, blendLinearDodge(base, blend), alpha); break;
					case 9: output = lerp(base, blendOverlay(base, blend), alpha); break;
					case 20: output = lerp(base, blendMixed(base, blend), alpha); break;
					default: output = 0; break;
				}
				return output;
			}
			
			float3 customBlend(float base, float blend, float blendType, float alpha = 1)
			{
				float3 output = base;
				switch(blendType)
				{
					case 0: output = lerp(base, blend, alpha); break;
					case 2: output = base * lerp(1, blend, alpha); break;
					case 5: output = lerp(base, blendLighten(base, blend), alpha); break;
					case 6: output = lerp(base, blendScreen(base, blend), alpha); break;
					case 7: output = blendSubtract(base, blend * alpha); break;
					case 8: output = lerp(base, blendLinearDodge(base, blend), alpha); break;
					case 9: output = lerp(base, blendOverlay(base, blend), alpha); break;
					case 20: output = lerp(base, blendMixed(base, blend), alpha); break;
					default: output = 0; break;
				}
				return output;
			}
			
			#define REPLACE 0
			#define SUBSTRACT 1
			#define MULTIPLY 2
			#define DIVIDE 3
			#define MIN 4
			#define MAX 5
			#define AVERAGE 6
			#define ADD 7
			
			float maskBlend(float baseMask, float blendMask, float blendType)
			{
				float output = 0;
				switch(blendType)
				{
					case REPLACE: output = blendMask; break;
					case SUBSTRACT: output = baseMask - blendMask; break;
					case MULTIPLY: output = baseMask * blendMask; break;
					case DIVIDE: output = baseMask / blendMask; break;
					case MIN: output = min(baseMask, blendMask); break;
					case MAX: output = max(baseMask, blendMask); break;
					case AVERAGE: output = (baseMask + blendMask) * 0.5; break;
					case ADD: output = baseMask + blendMask; break;
				}
				return saturate(output);
			}
			
			float globalMaskBlend(float baseMask, float globalMaskIndex, float blendType, PoiMods poiMods)
			{
				if (globalMaskIndex == 0)
				{
					return baseMask;
				}
				else
				{
					return maskBlend(baseMask, poiMods.globalMask[globalMaskIndex - 1], blendType);
				}
			}
			
			float random(float2 p)
			{
				return frac(sin(dot(p, float2(12.9898, 78.2383))) * 43758.5453123);
			}
			
			float2 random2(float2 p)
			{
				return frac(sin(float2(dot(p, float2(127.1, 311.7)), dot(p, float2(269.5, 183.3)))) * 43758.5453);
			}
			
			float3 random3(float2 p)
			{
				return frac(sin(float3(dot(p, float2(127.1, 311.7)), dot(p, float2(269.5, 183.3)), dot(p, float2(248.3, 315.9)))) * 43758.5453);
			}
			
			float3 random3(float3 p)
			{
				return frac(sin(float3(dot(p, float3(127.1, 311.7, 248.6)), dot(p, float3(269.5, 183.3, 423.3)), dot(p, float3(248.3, 315.9, 184.2)))) * 43758.5453);
			}
			
			float3 randomFloat3(float2 Seed, float maximum)
			{
				return (.5 + float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed), float2(12.9898, 78.233))) * 43758.5453)
				) * .5) * (maximum);
			}
			
			float3 randomFloat3Range(float2 Seed, float Range)
			{
				return (float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed.x * Seed.y, Seed.y + Seed.x), float2(12.9898, 78.233))) * 43758.5453)
				) * 2 - 1) * Range;
			}
			
			float3 randomFloat3WiggleRange(float2 Seed, float Range, float wiggleSpeed, float timeOffset)
			{
				float3 rando = (float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed.x * Seed.y, Seed.y + Seed.x), float2(12.9898, 78.233))) * 43758.5453)
				) * 2 - 1);
				float speed = 1 + wiggleSpeed;
				return float3(sin(((_Time.x + timeOffset) + rando.x * PI) * speed), sin(((_Time.x + timeOffset) + rando.y * PI) * speed), sin(((_Time.x + timeOffset) + rando.z * PI) * speed)) * Range;
			}
			
			void poiDither(float4 In, float4 ScreenPosition, out float4 Out)
			{
				float2 uv = ScreenPosition.xy * _ScreenParams.xy;
				float DITHER_THRESHOLDS[16] = {
					1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0,
					13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0,
					4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0,
					16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0
				};
				uint index = (uint(uv.x) % 4) * 4 + uint(uv.y) % 4;
				Out = In - DITHER_THRESHOLDS[index];
			}
			// The weights of RGB contributions to luminance.
			// Should sum to unity.
			static const float3 HCYwts = float3(0.299, 0.587, 0.114);
			static const float HCLgamma = 3;
			static const float HCLy0 = 100;
			static const float HCLmaxL = 0.530454533953517; // == exp(HCLgamma / HCLy0) - 0.5
			static const float3 wref = float3(1.0, 1.0, 1.0);
			#define TAU 6.28318531
			
			float3 HUEtoRGB(in float H)
			{
				float R = abs(H * 6 - 3) - 1;
				float G = 2 - abs(H * 6 - 2);
				float B = 2 - abs(H * 6 - 4);
				return saturate(float3(R, G, B));
			}
			
			float3 RGBtoHCV(in float3 RGB)
			{
				// Based on work by Sam Hocevar and Emil Persson
				float4 P = (RGB.g < RGB.b) ? float4(RGB.bg, -1.0, 2.0 / 3.0) : float4(RGB.gb, 0.0, -1.0 / 3.0);
				float4 Q = (RGB.r < P.x) ? float4(P.xyw, RGB.r) : float4(RGB.r, P.yzx);
				float C = Q.x - min(Q.w, Q.y);
				float H = abs((Q.w - Q.y) / (6 * C + Epsilon) + Q.z);
				return float3(H, C, Q.x);
			}
			
			float3 HSVtoRGB(in float3 HSV)
			{
				float3 RGB = HUEtoRGB(HSV.x);
				return ((RGB - 1) * HSV.y + 1) * HSV.z;
			}
			
			float3 RGBtoHSV(in float3 RGB)
			{
				float3 HCV = RGBtoHCV(RGB);
				float S = HCV.y / (HCV.z + Epsilon);
				return float3(HCV.x, S, HCV.z);
			}
			
			float3 HSLtoRGB(in float3 HSL)
			{
				float3 RGB = HUEtoRGB(HSL.x);
				float C = (1 - abs(2 * HSL.z - 1)) * HSL.y;
				return (RGB - 0.5) * C + HSL.z;
			}
			
			float3 RGBtoHSL(in float3 RGB)
			{
				float3 HCV = RGBtoHCV(RGB);
				float L = HCV.z - HCV.y * 0.5;
				float S = HCV.y / (1 - abs(L * 2 - 1) + Epsilon);
				return float3(HCV.x, S, L);
			}
			
			void DecomposeHDRColor(in float3 linearColorHDR, out float3 baseLinearColor, out float exposure)
			{
				// Optimization/adaptation of https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/GUI/ColorMutator.cs#L23 but skips weird photoshop stuff
				float maxColorComponent = max(linearColorHDR.r, max(linearColorHDR.g, linearColorHDR.b));
				bool isSDR = maxColorComponent <= 1.0;
				
				float scaleFactor = isSDR ? 1.0 : (1.0 / maxColorComponent);
				exposure = isSDR ? 0.0 : log(maxColorComponent) * 1.44269504089; // ln(2)
				
				baseLinearColor = scaleFactor * linearColorHDR;
			}
			
			float3 ApplyHDRExposure(float3 linearColor, float exposure)
			{
				return linearColor * pow(2, exposure);
			}
			
			// Transforms an RGB color using a matrix. Note that S and V are absolute values here
			float3 ModifyViaHSV(float3 color, float h, float s, float v)
			{
				float3 colorHSV = RGBtoHSV(color);
				colorHSV.x = frac(colorHSV.x + h);
				colorHSV.y = saturate(colorHSV.y + s);
				colorHSV.z = saturate(colorHSV.z + v);
				return HSVtoRGB(colorHSV);
			}
			
			float3 ModifyViaHSV(float3 color, float3 HSVMod)
			{
				return ModifyViaHSV(color, HSVMod.x, HSVMod.y, HSVMod.z);
			}
			
			float4x4 brightnessMatrix(float brightness)
			{
				return float4x4(
				1, 0, 0, 0,
				0, 1, 0, 0,
				0, 0, 1, 0,
				brightness, brightness, brightness, 1
				);
			}
			
			float4x4 contrastMatrix(float contrast)
			{
				float t = (1.0 - contrast) / 2.0;
				
				return float4x4(
				contrast, 0, 0, 0,
				0, contrast, 0, 0,
				0, 0, contrast, 0,
				t, t, t, 1
				);
			}
			
			float4x4 saturationMatrix(float saturation)
			{
				float3 luminance = float3(0.3086, 0.6094, 0.0820);
				
				float oneMinusSat = 1.0 - saturation;
				
				float3 red = luminance.x * oneMinusSat;
				red += float3(saturation, 0, 0);
				
				float3 green = luminance.y * oneMinusSat;
				green += float3(0, saturation, 0);
				
				float3 blue = luminance.z * oneMinusSat;
				blue += float3(0, 0, saturation);
				
				return float4x4(
				red, 0,
				green, 0,
				blue, 0,
				0, 0, 0, 1
				);
			}
			
			float4 PoiColorBCS(float4 color, float brightness, float contrast, float saturation)
			{
				return mul(color, mul(brightnessMatrix(brightness), mul(contrastMatrix(contrast), saturationMatrix(saturation))));
			}
			float3 PoiColorBCS(float3 color, float brightness, float contrast, float saturation)
			{
				return mul(float4(color, 1), mul(brightnessMatrix(brightness), mul(contrastMatrix(contrast), saturationMatrix(saturation)))).rgb;
			}
			
			float3 linear_srgb_to_oklab(float3 c)
			{
				float l = 0.4122214708 * c.x + 0.5363325363 * c.y + 0.0514459929 * c.z;
				float m = 0.2119034982 * c.x + 0.6806995451 * c.y + 0.1073969566 * c.z;
				float s = 0.0883024619 * c.x + 0.2817188376 * c.y + 0.6299787005 * c.z;
				
				float l_ = pow(l, 1.0 / 3.0);
				float m_ = pow(m, 1.0 / 3.0);
				float s_ = pow(s, 1.0 / 3.0);
				
				return float3(
				0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_,
				1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_,
				0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_
				);
			}
			
			float3 oklab_to_linear_srgb(float3 c)
			{
				float l_ = c.x + 0.3963377774 * c.y + 0.2158037573 * c.z;
				float m_ = c.x - 0.1055613458 * c.y - 0.0638541728 * c.z;
				float s_ = c.x - 0.0894841775 * c.y - 1.2914855480 * c.z;
				
				float l = l_ * l_ * l_;
				float m = m_ * m_ * m_;
				float s = s_ * s_ * s_;
				
				return float3(
				+ 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
				- 1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
				- 0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s
				);
			}
			
			float3 hueShift(float3 color, float shift)
			{
				float3 oklab = linear_srgb_to_oklab(max(color, 0.0000000001));
				float hue = atan2(oklab.z, oklab.y);
				hue += shift * PI * 2;  // Add the hue shift
				
				float chroma = length(oklab.yz);
				oklab.y = cos(hue) * chroma;
				oklab.z = sin(hue) * chroma;
				
				return oklab_to_linear_srgb(oklab);
			}
			
			float3 hueShift(float4 color, float shift)
			{
				return hueShift(color.rgb, shift);
			}
			
			/*
			float3 hueShift(float3 color, float hueOffset)
			{
				color = RGBtoHSV(color);
				color.x = frac(hueOffset +color.x);
				return HSVtoRGB(color);
			}
			*/
			
			// LCH
			float xyzF(float t)
			{
				return lerp(pow(t, 1. / 3.), 7.787037 * t + 0.139731, step(t, 0.00885645));
			}
			float xyzR(float t)
			{
				return lerp(t * t * t, 0.1284185 * (t - 0.139731), step(t, 0.20689655));
			}
			
			float4x4 poiRotationMatrixFromAngles(float x, float y, float z)
			{
				float angleX = radians(x);
				float c = cos(angleX);
				float s = sin(angleX);
				float4x4 rotateXMatrix = float4x4(1, 0, 0, 0,
				0, c, -s, 0,
				0, s, c, 0,
				0, 0, 0, 1);
				
				float angleY = radians(y);
				c = cos(angleY);
				s = sin(angleY);
				float4x4 rotateYMatrix = float4x4(c, 0, s, 0,
				0, 1, 0, 0,
				- s, 0, c, 0,
				0, 0, 0, 1);
				
				float angleZ = radians(z);
				c = cos(angleZ);
				s = sin(angleZ);
				float4x4 rotateZMatrix = float4x4(c, -s, 0, 0,
				s, c, 0, 0,
				0, 0, 1, 0,
				0, 0, 0, 1);
				
				return mul(mul(rotateXMatrix, rotateYMatrix), rotateZMatrix);
			}
			
			float4x4 poiRotationMatrixFromAngles(float3 angles)
			{
				float angleX = radians(angles.x);
				float c = cos(angleX);
				float s = sin(angleX);
				float4x4 rotateXMatrix = float4x4(1, 0, 0, 0,
				0, c, -s, 0,
				0, s, c, 0,
				0, 0, 0, 1);
				
				float angleY = radians(angles.y);
				c = cos(angleY);
				s = sin(angleY);
				float4x4 rotateYMatrix = float4x4(c, 0, s, 0,
				0, 1, 0, 0,
				- s, 0, c, 0,
				0, 0, 0, 1);
				
				float angleZ = radians(angles.z);
				c = cos(angleZ);
				s = sin(angleZ);
				float4x4 rotateZMatrix = float4x4(c, -s, 0, 0,
				s, c, 0, 0,
				0, 0, 1, 0,
				0, 0, 0, 1);
				
				return mul(mul(rotateXMatrix, rotateYMatrix), rotateZMatrix);
			}
			
			float3 getCameraPosition()
			{
				#ifdef USING_STEREO_MATRICES
				return lerp(unity_StereoWorldSpaceCameraPos[0], unity_StereoWorldSpaceCameraPos[1], 0.5);
				#endif
				return _WorldSpaceCameraPos;
			}
			
			float2 calcPixelScreenUVs(half4 grabPos)
			{
				half2 uv = grabPos.xy / (grabPos.w + 0.0000000001);
				#if UNITY_SINGLE_PASS_STEREO
				uv.xy *= half2(_ScreenParams.x * 2, _ScreenParams.y);
				#else
				uv.xy *= _ScreenParams.xy;
				#endif
				
				return uv;
			}
			
			float CalcMipLevel(float2 texture_coord)
			{
				float2 dx = ddx(texture_coord);
				float2 dy = ddy(texture_coord);
				float delta_max_sqr = max(dot(dx, dx), dot(dy, dy));
				
				return 0.5 * log2(delta_max_sqr);
			}
			
			float inverseLerp(float A, float B, float T)
			{
				return (T - A) / (B - A);
			}
			
			float inverseLerp2(float2 a, float2 b, float2 value)
			{
				float2 AB = b - a;
				float2 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			float inverseLerp3(float3 a, float3 b, float3 value)
			{
				float3 AB = b - a;
				float3 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			float inverseLerp4(float4 a, float4 b, float4 value)
			{
				float4 AB = b - a;
				float4 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			/*
			MIT License
			
			Copyright (c) 2019 wraikny
			
			Permission is hereby granted, free of charge, to any person obtaining a copy
			of this software and associated documentation files (the "Software"), to deal
			in the Software without restriction, including without limitation the rights
			to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
			copies of the Software, and to permit persons to whom the Software is
			furnished to do so, subject to the following conditions:
			
			The above copyright notice and this permission notice shall be included in all
			copies or substantial portions of the Software.
			
			THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
			IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
			FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
			AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
			LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
			OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
			SOFTWARE.
			
			VertexTransformShader is dependent on:
			*/
			
			float4 quaternion_conjugate(float4 v)
			{
				return float4(
				v.x, -v.yzw
				);
			}
			
			float4 quaternion_mul(float4 v1, float4 v2)
			{
				float4 result1 = (v1.x * v2 + v1 * v2.x);
				
				float4 result2 = float4(
				- dot(v1.yzw, v2.yzw),
				cross(v1.yzw, v2.yzw)
				);
				
				return float4(result1 + result2);
			}
			
			// angle : radians
			float4 get_quaternion_from_angle(float3 axis, float angle)
			{
				float sn = sin(angle * 0.5);
				float cs = cos(angle * 0.5);
				return float4(axis * sn, cs);
			}
			
			float4 quaternion_from_vector(float3 inVec)
			{
				return float4(0.0, inVec);
			}
			
			float degree_to_radius(float degree)
			{
				return (
				degree / 180.0 * PI
				);
			}
			
			float3 rotate_with_quaternion(float3 inVec, float3 rotation)
			{
				float4 qx = get_quaternion_from_angle(float3(1, 0, 0), radians(rotation.x));
				float4 qy = get_quaternion_from_angle(float3(0, 1, 0), radians(rotation.y));
				float4 qz = get_quaternion_from_angle(float3(0, 0, 1), radians(rotation.z));
				
				#define MUL3(A, B, C) quaternion_mul(quaternion_mul((A), (B)), (C))
				float4 quaternion = normalize(MUL3(qx, qy, qz));
				float4 conjugate = quaternion_conjugate(quaternion);
				
				float4 inVecQ = quaternion_from_vector(inVec);
				
				float3 rotated = (
				MUL3(quaternion, inVecQ, conjugate)
				).yzw;
				
				return rotated;
			}
			
			float4 transform(float4 input, float4 pos, float4 rotation, float4 scale)
			{
				input.rgb *= (scale.xyz * scale.w);
				input = float4(rotate_with_quaternion(input.xyz, rotation.xyz * rotation.w) + (pos.xyz * pos.w), input.w);
				return input;
			}
			
			float2 RotateUV(float2 _uv, float _radian, float2 _piv, float _time)
			{
				float RotateUV_ang = _radian;
				float RotateUV_cos = cos(_time * RotateUV_ang);
				float RotateUV_sin = sin(_time * RotateUV_ang);
				return (mul(_uv - _piv, float2x2(RotateUV_cos, -RotateUV_sin, RotateUV_sin, RotateUV_cos)) + _piv);
			}
			
			/*
			MIT END
			*/
			
			float3 RotateAroundAxis(float3 original, float3 axis, float radian)
			{
				float s = sin(radian);
				float c = cos(radian);
				float one_minus_c = 1.0 - c;
				
				axis = normalize(axis);
				float3x3 rot_mat = {
					one_minus_c * axis.x * axis.x + c, one_minus_c * axis.x * axis.y - axis.z * s, one_minus_c * axis.z * axis.x + axis.y * s,
					one_minus_c * axis.x * axis.y + axis.z * s, one_minus_c * axis.y * axis.y + c, one_minus_c * axis.y * axis.z - axis.x * s,
					one_minus_c * axis.z * axis.x - axis.y * s, one_minus_c * axis.y * axis.z + axis.x * s, one_minus_c * axis.z * axis.z + c
				};
				return mul(rot_mat, original);
			}
			
			float3 poiThemeColor(in PoiMods poiMods, in float3 srcColor, in float themeIndex)
			{
				float3 outputColor = srcColor;
				if (themeIndex != 0)
				{
					themeIndex = max(themeIndex - 1, 0);
					
					if (themeIndex <= 3)
					{
						outputColor = poiMods.globalColorTheme[themeIndex];
					}
					else
					{
						#ifdef POI_AUDIOLINK
						if (poiMods.audioLinkAvailable)
						{
							outputColor = poiMods.globalColorTheme[themeIndex];
						}
						#endif
					}
				}
				return outputColor;
			}
			
			float3 lilToneCorrection(float3 c, float4 hsvg)
			{
				// gamma
				c = pow(abs(c), hsvg.w);
				// rgb - > hsv
				float4 p = (c.b > c.g) ? float4(c.bg, -1.0, 2.0 / 3.0) : float4(c.gb, 0.0, -1.0 / 3.0);
				float4 q = (p.x > c.r) ? float4(p.xyw, c.r) : float4(c.r, p.yzx);
				float d = q.x - min(q.w, q.y);
				float e = 1.0e-10;
				float3 hsv = float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
				// shift
				hsv = float3(hsv.x + hsvg.x, saturate(hsv.y * hsvg.y), saturate(hsv.z * hsvg.z));
				// hsv - > rgb
				return hsv.z - hsv.z * hsv.y + hsv.z * hsv.y * saturate(abs(frac(hsv.x + float3(1.0, 2.0 / 3.0, 1.0 / 3.0)) * 6.0 - 3.0) - 1.0);
			}
			
			float3 lilBlendColor(float3 dstCol, float3 srcCol, float3 srcA, int blendMode)
			{
				float3 ad = dstCol + srcCol;
				float3 mu = dstCol * srcCol;
				float3 outCol = float3(0, 0, 0);
				if (blendMode == 0) outCol = srcCol; // Normal
				if (blendMode == 1) outCol = ad; // Add
				if (blendMode == 2) outCol = max(ad - mu, dstCol); // Screen
				if (blendMode == 3) outCol = mu; // Multiply
				return lerp(dstCol, outCol, srcA);
			}
			
			float lilIsIn0to1(float f)
			{
				float value = 0.5 - abs(f - 0.5);
				return saturate(value / clamp(fwidth(value), 0.0001, 1.0));
			}
			
			float lilIsIn0to1(float f, float nv)
			{
				float value = 0.5 - abs(f - 0.5);
				return saturate(value / clamp(fwidth(value), 0.0001, nv));
			}
			
			float poiEdgeLinearNoSaturate(float value, float border)
			{
				return (value - border) / clamp(fwidth(value), 0.0001, 1.0);
			}
			
			float3 poiEdgeLinearNoSaturate(float value, float3 border)
			{
				return float3(
				(value - border.x) / clamp(fwidth(value), 0.0001, 1.0),
				(value - border.y) / clamp(fwidth(value), 0.0001, 1.0),
				(value - border.z) / clamp(fwidth(value), 0.0001, 1.0)
				);
			}
			
			float poiEdgeLinearNoSaturate(float value, float border, float blur)
			{
				float borderMin = saturate(border - blur * 0.5);
				float borderMax = saturate(border + blur * 0.5);
				return (value - borderMin) / saturate(borderMax - borderMin + fwidth(value));
			}
			
			float poiEdgeLinearNoSaturate(float value, float border, float blur, float borderRange)
			{
				float borderMin = saturate(border - blur * 0.5 - borderRange);
				float borderMax = saturate(border + blur * 0.5);
				return (value - borderMin) / saturate(borderMax - borderMin + fwidth(value));
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border)
			{
				// return (value - border) / clamp(fwidth(value), 0.0001, 1.0);
				
				float fwidthValue = fwidth(value);
				return smoothstep(border - fwidthValue, border + fwidthValue, value);
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border, float blur)
			{
				float fwidthValue = fwidth(value);
				float borderMin = saturate(border - blur * 0.5);
				float borderMax = saturate(border + blur * 0.5);
				return smoothstep(borderMin - fwidthValue, borderMax + fwidthValue, value);
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border, float blur, float borderRange)
			{
				float fwidthValue = fwidth(value);
				float borderMin = saturate(border - blur * 0.5 - borderRange);
				float borderMax = saturate(border + blur * 0.5);
				return smoothstep(borderMin - fwidthValue, borderMax + fwidthValue, value);
			}
			
			float poiEdgeNonLinear(float value, float border)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border));
			}
			
			float poiEdgeNonLinear(float value, float border, float blur)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border, blur));
			}
			
			float poiEdgeNonLinear(float value, float border, float blur, float borderRange)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border, blur, borderRange));
			}
			
			float poiEdgeLinear(float value, float border)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border));
			}
			
			float poiEdgeLinear(float value, float border, float blur)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border, blur));
			}
			
			float poiEdgeLinear(float value, float border, float blur, float borderRange)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border, blur, borderRange));
			}
			// From https : // github.com / lilxyzw / OpenLit / blob / main / Assets / OpenLit / core.hlsl
			float3 OpenLitLinearToSRGB(float3 col)
			{
				return LinearToGammaSpace(col);
			}
			
			float3 OpenLitSRGBToLinear(float3 col)
			{
				return GammaToLinearSpace(col);
			}
			
			float OpenLitLuminance(float3 rgb)
			{
				#if defined(UNITY_COLORSPACE_GAMMA)
				return dot(rgb, float3(0.22, 0.707, 0.071));
				#else
				return dot(rgb, float3(0.0396819152, 0.458021790, 0.00609653955));
				#endif
			}
			
			float3 AdjustLitLuminance(float3 rgb, float targetLuminance)
			{
				float currentLuminance;
				#if defined(UNITY_COLORSPACE_GAMMA)
				currentLuminance = dot(rgb, float3(0.22, 0.707, 0.071));
				#else
				currentLuminance = dot(rgb, float3(0.0396819152, 0.458021790, 0.00609653955));
				#endif
				
				float luminanceRatio = targetLuminance / currentLuminance;
				return rgb * luminanceRatio;
			}
			
			float3 ClampLuminance(float3 rgb, float minLuminance, float maxLuminance)
			{
				float currentLuminance = dot(rgb, float3(0.299, 0.587, 0.114));
				float minRatio = (currentLuminance != 0) ? minLuminance / currentLuminance : 1.0;
				float maxRatio = (currentLuminance != 0) ? maxLuminance / currentLuminance : 1.0;
				float luminanceRatio = clamp(min(maxRatio, max(minRatio, 1.0)), 0.0, 1.0);
				return lerp(rgb, rgb * luminanceRatio, luminanceRatio < 1.0);
			}
			
			float3 MaxLuminance(float3 rgb, float maxLuminance)
			{
				float currentLuminance = dot(rgb, float3(0.299, 0.587, 0.114));
				float luminanceRatio = (currentLuminance != 0) ? maxLuminance / max(currentLuminance, 0.00001) : 1.0;
				return lerp(rgb, rgb * luminanceRatio, currentLuminance > maxLuminance);
			}
			
			float OpenLitGray(float3 rgb)
			{
				return dot(rgb, float3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0));
			}
			
			void OpenLitShadeSH9ToonDouble(float3 lightDirection, out float3 shMax, out float3 shMin)
			{
				#if !defined(LIGHTMAP_ON)
				float3 N = lightDirection * 0.666666;
				float4 vB = N.xyzz * N.yzzx;
				// L0 L2
				float3 res = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
				res.r += dot(unity_SHBr, vB);
				res.g += dot(unity_SHBg, vB);
				res.b += dot(unity_SHBb, vB);
				res += unity_SHC.rgb * (N.x * N.x - N.y * N.y);
				// L1
				float3 l1;
				l1.r = dot(unity_SHAr.rgb, N);
				l1.g = dot(unity_SHAg.rgb, N);
				l1.b = dot(unity_SHAb.rgb, N);
				shMax = res + l1;
				shMin = res - l1;
				#if defined(UNITY_COLORSPACE_GAMMA)
				shMax = OpenLitLinearToSRGB(shMax);
				shMin = OpenLitLinearToSRGB(shMin);
				#endif
				#else
				shMax = 0.0;
				shMin = 0.0;
				#endif
			}
			
			float3 OpenLitComputeCustomLightDirection(float4 lightDirectionOverride)
			{
				float3 customDir = length(lightDirectionOverride.xyz) * normalize(mul((float3x3)unity_ObjectToWorld, lightDirectionOverride.xyz));
				return lightDirectionOverride.w ? customDir : lightDirectionOverride.xyz; // .w isn't doc'd anywhere and is always 0 unless end user changes it
			}
			
			float3 OpenLitLightingDirectionForSH9()
			{
				float3 mainDir = _WorldSpaceLightPos0.xyz * OpenLitLuminance(_LightColor0.rgb);
				#if !defined(LIGHTMAP_ON)
				float3 sh9Dir = unity_SHAr.xyz * 0.333333 + unity_SHAg.xyz * 0.333333 + unity_SHAb.xyz * 0.333333;
				float3 sh9DirAbs = float3(sh9Dir.x, abs(sh9Dir.y), sh9Dir.z);
				#else
				float3 sh9Dir = 0;
				float3 sh9DirAbs = 0;
				#endif
				
				float3 lightDirectionForSH9 = sh9Dir + mainDir;
				lightDirectionForSH9 = dot(lightDirectionForSH9, lightDirectionForSH9) < 0.000001 ? 0 : normalize(lightDirectionForSH9);
				return lightDirectionForSH9;
			}
			
			float3 OpenLitLightingDirection(float4 lightDirectionOverride)
			{
				float3 mainDir = _WorldSpaceLightPos0.xyz * OpenLitLuminance(_LightColor0.rgb);
				#if !defined(LIGHTMAP_ON) && UNITY_SHOULD_SAMPLE_SH
				float3 sh9Dir = unity_SHAr.xyz * 0.333333 + unity_SHAg.xyz * 0.333333 + unity_SHAb.xyz * 0.333333;
				float3 sh9DirAbs = float3(sh9Dir.x, abs(sh9Dir.y), sh9Dir.z);
				#else
				float3 sh9Dir = 0;
				float3 sh9DirAbs = 0;
				#endif
				float3 customDir = OpenLitComputeCustomLightDirection(lightDirectionOverride);
				
				return normalize(sh9DirAbs + mainDir + customDir);
			}
			
			float3 OpenLitLightingDirection()
			{
				float4 customDir = float4(0.001, 0.002, 0.001, 0.0);
				return OpenLitLightingDirection(customDir);
			}
			
			inline float4 CalculateFrustumCorrection()
			{
				float x1 = -UNITY_MATRIX_P._31 / (UNITY_MATRIX_P._11 * UNITY_MATRIX_P._34);
				float x2 = -UNITY_MATRIX_P._32 / (UNITY_MATRIX_P._22 * UNITY_MATRIX_P._34);
				return float4(x1, x2, 0, UNITY_MATRIX_P._33 / UNITY_MATRIX_P._34 + x1 * UNITY_MATRIX_P._13 + x2 * UNITY_MATRIX_P._23);
			}
			
			inline float CorrectedLinearEyeDepth(float z, float B)
			{
				return 1.0 / (z / UNITY_MATRIX_P._34 + B);
			}
			
			// Silent's code
			float2 sharpSample(float4 texelSize, float2 p)
			{
				p = p * texelSize.zw;
				float2 c = max(0.0, fwidth(p));
				p = floor(p) + saturate(frac(p) / c);
				p = (p - 0.5) * texelSize.xy;
				return p;
			}
			
			void applyToGlobalMask(inout PoiMods poiMods, int index, int blendType, float val)
			{
				float valBlended = saturate(maskBlend(poiMods.globalMask[index], val, blendType));
				switch(index)
				{
					case 0: poiMods.globalMask[0] = valBlended; break;
					case 1: poiMods.globalMask[1] = valBlended; break;
					case 2: poiMods.globalMask[2] = valBlended; break;
					case 3: poiMods.globalMask[3] = valBlended; break;
					case 4: poiMods.globalMask[4] = valBlended; break;
					case 5: poiMods.globalMask[5] = valBlended; break;
					case 6: poiMods.globalMask[6] = valBlended; break;
					case 7: poiMods.globalMask[7] = valBlended; break;
					case 8: poiMods.globalMask[8] = valBlended; break;
					case 9: poiMods.globalMask[9] = valBlended; break;
					case 10: poiMods.globalMask[10] = valBlended; break;
					case 11: poiMods.globalMask[11] = valBlended; break;
					case 12: poiMods.globalMask[12] = valBlended; break;
					case 13: poiMods.globalMask[13] = valBlended; break;
					case 14: poiMods.globalMask[14] = valBlended; break;
					case 15: poiMods.globalMask[15] = valBlended; break;
				}
			}
			
			void assignValueToVectorFromIndex(inout float4 vec, int index, float value)
			{
				switch(index)
				{
					case 0: vec[0] = value; break;
					case 1: vec[1] = value; break;
					case 2: vec[2] = value; break;
					case 3: vec[3] = value; break;
				}
			}
			
			// SNose
			float3 mod289(float3 x)
			{
				return x - floor(x * (1.0 / 289.0)) * 289.0;
			}
			float2 mod289(float2 x)
			{
				return x - floor(x * (1.0 / 289.0)) * 289.0;
			}
			float3 permute(float3 x)
			{
				return mod289(((x * 34.0) + 1.0) * x);
			}
			
			float snoise(float2 v)
			{
				const float4 C = float4(0.211324865405187, // (3.0 - sqrt(3.0)) / 6.0
				0.366025403784439, // 0.5 * (sqrt(3.0) - 1.0)
				- 0.577350269189626, // - 1.0 + 2.0 * C.x
				0.024390243902439); // 1.0 / 41.0
				float2 i = floor(v + dot(v, C.yy));
				float2 x0 = v - i + dot(i, C.xx);
				float2 i1;
				i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0);
				float4 x12 = x0.xyxy + C.xxzz;
				x12.xy -= i1;
				i = mod289(i); // Avoid truncation effects in permutation
				float3 p = permute(permute(i.y + float3(0.0, i1.y, 1.0))
				+ i.x + float3(0.0, i1.x, 1.0));
				
				float3 m = max(0.5 - float3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);
				m = m * m ;
				m = m * m ;
				float3 x = 2.0 * frac(p * C.www) - 1.0;
				float3 h = abs(x) - 0.5;
				float3 ox = floor(x + 0.5);
				float3 a0 = x - ox;
				m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);
				float3 g;
				g.x = a0.x * x0.x + h.x * x0.y;
				g.yz = a0.yz * x12.xz + h.yz * x12.yw;
				return 130.0 * dot(m, g);
			}
			
			float nsqDistance(float2 a, float2 b)
			{
				return dot(a - b, a - b);
			}
			
			float poiInvertToggle(in float value, in float toggle)
			{
				return (toggle == 0 ? value : 1 - value);
			}
			
			float3 PoiBlendNormal(float3 dstNormal, float3 srcNormal)
			{
				return float3(dstNormal.xy + srcNormal.xy, dstNormal.z * srcNormal.z);
			}
			
			float3 lilTransformDirOStoWS(float3 directionOS, bool doNormalize)
			{
				if (doNormalize) return normalize(mul((float3x3)unity_ObjectToWorld, directionOS));
				else            return mul((float3x3)unity_ObjectToWorld, directionOS);
			}
			
			float2 poiGetWidthAndHeight(Texture2D tex)
			{
				uint width, height;
				tex.GetDimensions(width, height);
				return float2(width, height);
			}
			
			float2 poiGetWidthAndHeight(Texture2DArray tex)
			{
				uint width, height, element;
				tex.GetDimensions(width, height, element);
				return float2(width, height);
			}
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			
			// Convenient mechanism to read from the AudioLink texture that handles reading off the end of one line and onto the next above it.
			float4 AudioLinkDataMultiline(uint2 xycoord)
			{
				return AudioLinkData(uint2(xycoord.x % AUDIOLINK_WIDTH, xycoord.y + xycoord.x / AUDIOLINK_WIDTH));
			}
			
			// Mechanism to sample between two adjacent pixels and lerp between them, like "linear" supesampling
			float4 AudioLinkLerp(float2 xy)
			{
				return lerp(AudioLinkData(xy), AudioLinkData(xy + int2(1, 0)), frac(xy.x));
			}
			
			// Same as AudioLinkLerp but properly handles multiline reading.
			float4 AudioLinkLerpMultiline(float2 xy)
			{
				return lerp(AudioLinkDataMultiline(xy), AudioLinkDataMultiline(xy + float2(1, 0)), frac(xy.x));
			}
			
			//Tests to see if Audio Link texture is available
			bool AudioLinkIsAvailable()
			{
				#if !defined(AUDIOLINK_STANDARD_INDEXING)
				int width, height;
				_AudioTexture.GetDimensions(width, height);
				return width > 16;
				#else
				return _AudioTexture_TexelSize.z > 16;
				#endif
			}
			
			//Get version of audiolink present in the world, 0 if no audiolink is present
			float AudioLinkGetVersion()
			{
				int2 dims;
				#if !defined(AUDIOLINK_STANDARD_INDEXING)
				_AudioTexture.GetDimensions(dims.x, dims.y);
				#else
				dims = _AudioTexture_TexelSize.zw;
				#endif
				
				if (dims.x >= 128)
				return AudioLinkData(ALPASS_GENERALVU).x;
				else if (dims.x > 16)
				return 1;
				else
				return 0;
			}
			
			// This pulls data from this texture.
			#define AudioLinkGetSelfPixelData(xy) _SelfTexture2D[xy]
			
			// Extra utility functions for time.
			uint AudioLinkDecodeDataAsUInt(uint2 indexloc)
			{
				uint4 rpx = AudioLinkData(indexloc);
				return rpx.r + rpx.g * 1024 + rpx.b * 1048576 + rpx.a * 1073741824;
			}
			
			//Note: This will truncate time to every 134,217.728 seconds (~1.5 days of an instance being up) to prevent floating point aliasing.
			// if your code will alias sooner, you will need to use a different function.  It should be safe to use this on all times.
			float AudioLinkDecodeDataAsSeconds(uint2 indexloc)
			{
				uint time = AudioLinkDecodeDataAsUInt(indexloc) & 0x7ffffff;
				//Can't just divide by float.  Bug in Unity's HLSL compiler.
				return float(time / 1000) + float(time % 1000) / 1000.;
			}
			
			#define ALDecodeDataAsSeconds(x) AudioLinkDecodeDataAsSeconds(x)
			#define ALDecodeDataAsUInt(x) AudioLinkDecodeDataAsUInt(x)
			
			float AudioLinkRemap(float t, float a, float b, float u, float v)
			{
				return ((t - a) / (b - a)) * (v - u) + u;
			}
			
			float3 AudioLinkHSVtoRGB(float3 HSV)
			{
				float3 RGB = 0;
				float C = HSV.z * HSV.y;
				float H = HSV.x * 6;
				float X = C * (1 - abs(fmod(H, 2) - 1));
				if (HSV.y != 0)
				{
					float I = floor(H);
					if (I == 0)
					{
						RGB = float3(C, X, 0);
					}
					else if (I == 1)
					{
						RGB = float3(X, C, 0);
					}
					else if (I == 2)
					{
						RGB = float3(0, C, X);
					}
					else if (I == 3)
					{
						RGB = float3(0, X, C);
					}
					else if (I == 4)
					{
						RGB = float3(X, 0, C);
					}
					else
					{
						RGB = float3(C, 0, X);
					}
				}
				float M = HSV.z - C;
				return RGB + M;
			}
			
			float3 AudioLinkCCtoRGB(float bin, float intensity, int rootNote)
			{
				float note = bin / AUDIOLINK_EXPBINS;
				
				float hue = 0.0;
				note *= 12.0;
				note = glsl_mod(4. - note + rootNote, 12.0);
				{
					if (note < 4.0)
					{
						//Needs to be YELLOW->RED
						hue = (note) / 24.0;
					}
					else if (note < 8.0)
					{
						//            [4]  [8]
						//Needs to be RED->BLUE
						hue = (note - 2.0) / 12.0;
					}
					else
					{
						//             [8] [12]
						//Needs to be BLUE->YELLOW
						hue = (note - 4.0) / 8.0;
					}
				}
				float val = intensity - 0.1;
				return AudioLinkHSVtoRGB(float3(fmod(hue, 1.0), 1.0, clamp(val, 0.0, 1.0)));
			}
			
			// Sample the amplitude of a given frequency in the DFT, supports frequencies in [13.75; 14080].
			float4 AudioLinkGetAmplitudeAtFrequency(float hertz)
			{
				float note = AUDIOLINK_EXPBINS * log2(hertz / AUDIOLINK_BOTTOM_FREQUENCY);
				return AudioLinkLerpMultiline(ALPASS_DFT + float2(note, 0));
			}
			
			// Sample the amplitude of a given semitone in an octave. Octave is in [0; 9] while note is [0; 11].
			float AudioLinkGetAmplitudeAtNote(float octave, float note)
			{
				float quarter = note * 2.0;
				return AudioLinkLerpMultiline(ALPASS_DFT + float2(octave * AUDIOLINK_EXPBINS + quarter, 0));
			}
			
			// Get a reasonable drop-in replacement time value for _Time.y with the
			// given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTime(uint index, uint band)
			{
				return (AudioLinkDecodeDataAsUInt(ALPASS_CHRONOTENSITY + uint2(index, band))) / 100000.0;
			}
			
			// Get a chronotensity value in the interval [0; 1], modulated by the speed input,
			// with the given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTimeNormalized(uint index, uint band, float speed)
			{
				return frac(AudioLinkGetChronoTime(index, band) * speed);
			}
			
			// Get a chronotensity value in the interval [0; interval], modulated by the speed input,
			// with the given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTimeInterval(uint index, uint band, float speed, float interval)
			{
				return AudioLinkGetChronoTimeNormalized(index, band, speed) * interval;
			}
			
			float getBandAtTime(float band, float time, float size = 1.0f)
			{
				//return remap(UNITY_SAMPLE_TEX2D(_AudioTexture, float2(time * width, band/128.0)).r, min(size,.9999), 1);
				return remapClamped(min(size, .9999), 1, AudioLinkData(ALPASS_AUDIOBASS + uint2(time * AUDIOLINK_WIDTH, band)).r);
			}
			
			fixed3 maximize(fixed3 c)
			{
				if (c.x == 0 && c.y == 0 && c.z == 0)
				return fixed3(1.0, 1.0, 1.0);
				else
				return c / max(c.r, max(c.g, c.b));
			}
			
			void initPoiAudioLink(inout PoiMods poiMods)
			{
				if (!_AudioLinkAnimToggle) return;
				
				if (AudioLinkIsAvailable())
				{
					poiMods.audioLinkAvailable = true;
					poiMods.audioLinkVersion = AudioLinkGetVersion();
					poiMods.audioLink[0] = _AudioLinkSmoothingBass == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 0))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingBass) * 15.95, 0))[0];
					poiMods.audioLink[1] = _AudioLinkSmoothingLowMid == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 1))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingLowMid) * 15.95, 1))[0];
					poiMods.audioLink[2] = _AudioLinkSmoothingHighMid == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 2))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingHighMid) * 15.95, 2))[0];
					poiMods.audioLink[3] = _AudioLinkSmoothingTreble == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 3))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingTreble) * 15.95, 3))[0];
					poiMods.audioLink[4] = AudioLinkData(ALPASS_GENERALVU + float2(8, 0))[0];
					/*
					poiMods.globalColorTheme[4] = AudioLinkData( ALPASS_CCCOLORS + uint2( 0, 0 ) );
					poiMods.globalColorTheme[5] = AudioLinkData( ALPASS_CCCOLORS + uint2( 1, 0 ) );
					poiMods.globalColorTheme[6] = AudioLinkData( ALPASS_CCCOLORS + uint2( 2, 0 ) );
					poiMods.globalColorTheme[7] = AudioLinkData( ALPASS_CCCOLORS + uint2( 3, 0 ) );
					
					poiMods.globalColorTheme[4] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 0, 0 ) )),1.0);
					poiMods.globalColorTheme[5] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 1, 0 ) )),1.0);
					poiMods.globalColorTheme[6] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 2, 0 ) )),1.0);
					poiMods.globalColorTheme[7] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 3, 0 ) )),1.0);
					*/
					
					poiMods.globalColorTheme[4] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(2, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[5] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(3, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[6] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(4, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[7] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(5, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					
					poiMods.globalColorTheme[8] = AudioLinkData(ALPASS_THEME_COLOR0);
					poiMods.globalColorTheme[9] = AudioLinkData(ALPASS_THEME_COLOR1);
					poiMods.globalColorTheme[10] = AudioLinkData(ALPASS_THEME_COLOR2);
					poiMods.globalColorTheme[11] = AudioLinkData(ALPASS_THEME_COLOR3);
					return;
				}
				
				if (_AudioLinkBandOverridesEnabled)
				{
					poiMods.audioLinkAvailable = true;
					poiMods.audioLink[0] = _AudioLinkBandOverrideSliders.x;
					poiMods.audioLink[1] = _AudioLinkBandOverrideSliders.y;
					poiMods.audioLink[2] = _AudioLinkBandOverrideSliders.z;
					poiMods.audioLink[3] = _AudioLinkBandOverrideSliders.w;
				}
			}
			
			void DebugVisualizer(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				if (_DebugWaveform)
				{
					float waveform = AudioLinkLerpMultiline(ALPASS_WAVEFORM + float2(500. * poiMesh.uv[0].x, 0)).r;
					poiFragData.emission += clamp(1 - 50 * abs(waveform - poiMesh.uv[0].y * 2. + 1), 0, 1);
				}
				if (_DebugDFT)
				{
					poiFragData.emission += AudioLinkLerpMultiline(ALPASS_DFT + uint2(poiMesh.uv[0].x * AUDIOLINK_ETOTALBINS, 0)).rrr;
				}
				if (_DebugBass)
				{
					poiFragData.emission += poiMods.audioLink[0];
				}
				if (_DebugLowMids)
				{
					poiFragData.emission += poiMods.audioLink[1];
				}
				if (_DebugHighMids)
				{
					poiFragData.emission += poiMods.audioLink[2];
				}
				if (_DebugTreble)
				{
					poiFragData.emission += poiMods.audioLink[3];
				}
				if (_DebugCCColors)
				{
					poiFragData.emission += AudioLinkData(ALPASS_CCCOLORS + uint2(3 + 1, 0));
				}
				if (_DebugCCStrip)
				{
					poiFragData.emission += AudioLinkLerp(ALPASS_CCSTRIP + float2(poiMesh.uv[0].x * AUDIOLINK_WIDTH, 0));
				}
				if (_DebugCCLights)
				{
					poiFragData.emission += AudioLinkData(ALPASS_CCLIGHTS + uint2(uint(poiMesh.uv[0].x * 8) + uint(poiMesh.uv[0].y * 16) * 8, 0));
				}
				if (_DebugAutocorrelator)
				{
					poiFragData.emission += saturate(AudioLinkLerp(ALPASS_AUTOCORRELATOR + float2((abs(1. - poiMesh.uv[0].x * 2.)) * AUDIOLINK_WIDTH, 0)).rrr);
				}
				if (_DebugChronotensity)
				{
					poiFragData.emission += (AudioLinkDecodeDataAsUInt(ALPASS_CHRONOTENSITY + uint2(1, 0)) % 1000000) / 1000000.0;
				}
			}
			
			void SetupAudioLink(inout PoiFragData poiFragData, inout PoiMods poiMods, in PoiMesh poiMesh)
			{
				initPoiAudioLink(poiMods);
				DebugVisualizer(poiFragData, poiMesh, poiMods);
				
				if (_AudioLinkCCStripY)
				{
					poiFragData.emission += AudioLinkLerp(ALPASS_CCSTRIP + float2(poiMesh.uv[0].y * AUDIOLINK_WIDTH, 0)).rgb * .5;
				}
			}
			
			#endif
			//endex
			
			//ifex _BSSEnabled!=1
			#ifdef POIBS_ENABLE
			//ifex _BSSBloomfog!=1
			#ifdef POIBS_BLOOMFOG
			inline float4 GetFogCoord(float4 clipPos)
			{
				float4 screenPos = ComputeNonStereoScreenPos(clipPos);
				float2 screenPosNormalized = screenPos.xy / screenPos.w;
				float eyeOffset = (unity_StereoEyeIndex * (_StereoCameraEyeOffset * 2)) + - _StereoCameraEyeOffset;
				return float4(
				((eyeOffset +screenPosNormalized.x) + - 0.5) * _CustomFogTextureToScreenRatio.x + 0.5,
				(screenPosNormalized.y + - 0.5) * _CustomFogTextureToScreenRatio.y + 0.5
				,clipPos.z,clipPos.w);
			}
			
			inline float GetHeightFogIntensity(float3 worldPos, float fogHeightOffset, float fogHeightScale)
			{
				float heightFogIntensity = _CustomFogHeightFogHeight + _CustomFogHeightFogStartY;
				heightFogIntensity = ((worldPos.y * fogHeightScale) + fogHeightOffset) + - heightFogIntensity;
				heightFogIntensity = heightFogIntensity / _CustomFogHeightFogHeight;
				heightFogIntensity = clamp(heightFogIntensity, 0, 1);
				return ((-heightFogIntensity * 2) + 3) * (heightFogIntensity * heightFogIntensity);
			}
			
			inline float GetFogIntensity(float3 distance, float fogStartOffset, float fogScale)
			{
				float fogIntensity = max(dot(distance, distance) + - fogStartOffset, 0);
				fogIntensity = max((fogIntensity * fogScale) + - _CustomFogOffset, 0);
				fogIntensity = 1 / ((fogIntensity * _CustomFogAttenuation) + 1);
				return -fogIntensity;
			}
			#endif
			//endex
			#endif
			//endex
			
			VertexOut vert(
			#ifndef POI_TESSELLATED
			appdata v
			#else
			tessAppData v
			#endif
			)
			{
				UNITY_SETUP_INSTANCE_ID(v);
				VertexOut o;
				PoiInitStruct(VertexOut, o);
				UNITY_TRANSFER_INSTANCE_ID(v, o);
				#ifdef POI_TESSELLATED
				UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v);
				#endif
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
				
				//ifex _EnableUDIMDiscardOptions==0
				#ifdef POI_UDIMDISCARD
				UNITY_BRANCH
				if(_UDIMDiscardMode == 0) // Discard Vertices instead of just pixels
				{
					// Branchless (inspired by s-ilent)
					float2 udim = 0;
					// Select UV
					udim += (v.uv0.xy * (_UDIMDiscardUV == 0));
					udim += (v.uv1.xy * (_UDIMDiscardUV == 1));
					udim += (v.uv2.xy * (_UDIMDiscardUV == 2));
					udim += (v.uv3.xy * (_UDIMDiscardUV == 3));
					
					float isDiscarded = 0;
					float4 xMask = float4(  (udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					isDiscarded += (udim.y >= 0 && udim.y < 1) * dot(float4(_UDIMDiscardRow0_0, _UDIMDiscardRow0_1, _UDIMDiscardRow0_2, _UDIMDiscardRow0_3), xMask);
					isDiscarded += (udim.y >= 1 && udim.y < 2) * dot(float4(_UDIMDiscardRow1_0, _UDIMDiscardRow1_1, _UDIMDiscardRow1_2, _UDIMDiscardRow1_3), xMask);
					isDiscarded += (udim.y >= 2 && udim.y < 3) * dot(float4(_UDIMDiscardRow2_0, _UDIMDiscardRow2_1, _UDIMDiscardRow2_2, _UDIMDiscardRow2_3), xMask);
					isDiscarded += (udim.y >= 3 && udim.y < 4) * dot(float4(_UDIMDiscardRow3_0, _UDIMDiscardRow3_1, _UDIMDiscardRow3_2, _UDIMDiscardRow3_3), xMask);
					
					isDiscarded *= any(float4(udim.y >= 0, udim.y < 4, udim.x >= 0, udim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					// Use a threshold so that there's some room for animations to be close to 0, but not exactly 0
					const float threshold = 0.001;
					if(isDiscarded > threshold) // Early Return skips rest of vertex shader
					{
						return (VertexOut)POI_NAN;
					}
				}
				#endif
				//endex
				
				//ifex _VertexManipulationsEnabled==0
				#ifdef AUTO_EXPOSURE
				float4 audioLinkBands = 0;
				float3 ALrotation = 0;
				float3 ALLocalTranslation = 0;
				float3 CTALRotation = 0;
				float3 ALScale = 0;
				float3 ALWorldTranslation = 0;
				float ALHeight = 0;
				float ALRoundingAmount = 0;
				float4 ALSpectrumLocalOffset = float4(0, 0, 0, 0);
				#ifdef POI_AUDIOLINK
				if (AudioLinkIsAvailable() && _VertexAudioLinkEnabled && _AudioLinkAnimToggle)
				{
					audioLinkBands.x = AudioLinkData(ALPASS_AUDIOBASS).r;
					audioLinkBands.y = AudioLinkData(ALPASS_AUDIOLOWMIDS).r;
					audioLinkBands.z = AudioLinkData(ALPASS_AUDIOHIGHMIDS).r;
					audioLinkBands.w = AudioLinkData(ALPASS_AUDIOTREBLE).r;
					
					if (any(_VertexLocalTranslationALMin) || any(_VertexLocalTranslationALMax))
					{
						ALLocalTranslation = lerp(_VertexLocalTranslationALMin, _VertexLocalTranslationALMax, audioLinkBands[_VertexLocalTranslationALBand]);
					}
					if (any(_VertexLocalRotationAL))
					{
						ALrotation = audioLinkBands[_VertexLocalRotationALBand] * _VertexLocalRotationAL;
					}
					if (any(_VertexLocalRotationCTALSpeed))
					{
						CTALRotation.x = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeX, _VertexLocalRotationCTALBandX) * _VertexLocalRotationCTALSpeed.x * 360;
						CTALRotation.y = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeY, _VertexLocalRotationCTALBandY) * _VertexLocalRotationCTALSpeed.y * 360;
						CTALRotation.z = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeZ, _VertexLocalRotationCTALBandZ) * _VertexLocalRotationCTALSpeed.z * 360;
					}
					if (any(_VertexLocalScaleALMin) || any(_VertexLocalScaleALMax))
					{
						ALScale = lerp(_VertexLocalScaleALMin.xyz + _VertexLocalScaleALMin.w, _VertexLocalScaleALMax.xyz + _VertexLocalScaleALMax.w, audioLinkBands[_VertexLocalScaleALBand]);
					}
					if (any(_VertexWorldTranslationALMin) || any(_VertexWorldTranslationALMax))
					{
						ALWorldTranslation = lerp(_VertexWorldTranslationALMin, _VertexWorldTranslationALMax, audioLinkBands[_VertexWorldTranslationALBand]);
					}
					if (any(_VertexManipulationHeightAL))
					{
						ALHeight = lerp(_VertexManipulationHeightAL.x, _VertexManipulationHeightAL.y, audioLinkBands[_VertexManipulationHeightBand]);
					}
					if (any(_VertexRoundingRangeAL))
					{
						ALRoundingAmount = lerp(_VertexRoundingRangeAL.x, _VertexRoundingRangeAL.y, audioLinkBands[_VertexRoundingRangeBand]);
					}
					if (_VertexSpectrumMotion)
					{
						ALSpectrumLocalOffset.xyz = lerp(_VertexSpectrumOffsetMin.xyz, _VertexSpectrumOffsetMax.xyz, AudioLinkLerpMultiline(ALPASS_DFT + float2(vertexUV(v, _VertexSpectrumUV)[_VertexSpectrumUVDirection] * AUDIOLINK_ETOTALBINS, 0.)));
					}
				}
				#endif
				
				// Local Transformation
				float4 rotation = float4(_VertexManipulationLocalRotation.xyz + float3(180, 0, 0) + _VertexManipulationLocalRotationSpeed * _Time.x + ALrotation + CTALRotation, _VertexManipulationLocalRotation.w);
				v.normal = rotate_with_quaternion(v.normal, rotation.xyz);
				v.tangent.xyz = rotate_with_quaternion(v.tangent.xyz, rotation.xyz);
				v.vertex = transform(v.vertex, _VertexManipulationLocalTranslation + float4(ALLocalTranslation, 0) + ALSpectrumLocalOffset, rotation, _VertexManipulationLocalScale + float4(ALScale, 0));
				o.normal = UnityObjectToWorldNormal(v.normal);
				
				#if defined(PROP_VERTEXMANIPULATIONHEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float3 heightOffset = (tex2Dlod(_VertexManipulationHeightMask, float4(poiUV(vertexUV(v, _VertexManipulationHeightMaskUV), _VertexManipulationHeightMask_ST) + _VertexManipulationHeightMaskPan * _Time.x, 0, 0))[_VertexManipulationHeightMaskChannel] - _VertexManipulationHeightBias) * (_VertexManipulationHeight + ALHeight) * o.normal;
				#else
				float3 heightOffset = (_VertexManipulationHeight + ALHeight) * o.normal;
				#endif
				
				if (_VertexBarrelMode)
				{
					v.vertex.xz = lerp(v.vertex.xz, normalize(v.vertex.xz) * _VertexBarrelWidth + v.vertex.xz * _VertexBarrelHeight, _VertexBarrelAlpha);
				}
				
				if (_VertexSphereMode)
				{
					v.vertex.xyz = lerp(v.vertex.xyz, normalize(v.vertex.xyz + _VertexSphereCenter.xyz) * _VertexSphereRadius + v.vertex.xyz * _VertexSphereHeight, _VertexSphereAlpha);
				}
				
				if (_VertexTornadoMode)
				{
					v.vertex.xz = lerp(v.vertex.xz, float3(v.vertex.xz + float2(cos(_Time.y * _VertexTornadoSpeed + v.vertex.y * _VertexTornadoIntensity) * _VertexTornadoRadius, sin(_Time.y * _VertexTornadoSpeed + v.vertex.y * _VertexTornadoIntensity) * _VertexTornadoRadius), v.vertex.y), smoothstep(_VertexTornadoBaseHeight, _VertexTornadoTopHeight, v.vertex.y));
				}
				
				v.vertex.xyz += mul(unity_WorldToObject, _VertexManipulationWorldTranslation.xyz + ALWorldTranslation + heightOffset).xyz;
				
				// rounding
				UNITY_BRANCH
				if (_VertexRoundingEnabled)
				{
					float divisionAmount = max(_VertexRoundingDivision + ALRoundingAmount, 0.0000001);
					if (_VertexRoundingSpace == 0)
					{
						float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
						float3 worldRoundPosition = (ceil(worldPos.xyz / divisionAmount) * divisionAmount) - divisionAmount * .5;
						v.vertex = mul(unity_WorldToObject, float4(worldRoundPosition, worldPos.w));
					}
					else if (_VertexRoundingSpace == 1)
					{
						v.vertex.xyz = (ceil(v.vertex.xyz / divisionAmount) * divisionAmount) - divisionAmount * .5;
					}
				}
				#endif
				//endex
				
				//ifex _EnableDissolve==0
				#ifdef DISTORT
				UNITY_BRANCH
				if (_UVTileDissolveEnabled && _UVTileDissolveDiscardAtMax)
				{
					// Branchless (inspired by s-ilent)
					float2 dissolveUdim = 0;
					// Select UV
					dissolveUdim += (v.uv0.xy * (_UVTileDissolveUV == 0));
					dissolveUdim += (v.uv1.xy * (_UVTileDissolveUV == 1));
					dissolveUdim += (v.uv2.xy * (_UVTileDissolveUV == 2));
					dissolveUdim += (v.uv3.xy * (_UVTileDissolveUV == 3));
					
					float isDiscardedFromDissolve = 0;
					float4 xMaskDissolve = float4((dissolveUdim.x >= 0 && dissolveUdim.x < 1),
					(dissolveUdim.x >= 1 && dissolveUdim.x < 2),
					(dissolveUdim.x >= 2 && dissolveUdim.x < 3),
					(dissolveUdim.x >= 3 && dissolveUdim.x < 4));
					
					isDiscardedFromDissolve += (dissolveUdim.y >= 0 && dissolveUdim.y < 1) * dot(float4(_UVTileDissolveAlpha_Row0_0, _UVTileDissolveAlpha_Row0_1, _UVTileDissolveAlpha_Row0_2, _UVTileDissolveAlpha_Row0_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 1 && dissolveUdim.y < 2) * dot(float4(_UVTileDissolveAlpha_Row1_0, _UVTileDissolveAlpha_Row1_1, _UVTileDissolveAlpha_Row1_2, _UVTileDissolveAlpha_Row1_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 2 && dissolveUdim.y < 3) * dot(float4(_UVTileDissolveAlpha_Row2_0, _UVTileDissolveAlpha_Row2_1, _UVTileDissolveAlpha_Row2_2, _UVTileDissolveAlpha_Row2_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 3 && dissolveUdim.y < 4) * dot(float4(_UVTileDissolveAlpha_Row3_0, _UVTileDissolveAlpha_Row3_1, _UVTileDissolveAlpha_Row3_2, _UVTileDissolveAlpha_Row3_3), xMaskDissolve);
					
					isDiscardedFromDissolve *= any(float4(dissolveUdim.y >= 0, dissolveUdim.y < 4, dissolveUdim.x >= 0, dissolveUdim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					// Use a threshold so that there's some room for animations to be close to 1, but not exactly 1
					const float threshold = 0.999;
					if (isDiscardedFromDissolve > threshold) // Early Return skips rest of vertex shader
					
					{
						return (VertexOut)POI_NAN;
					}
				}
				#endif
				//endex
				
				//ifex _EnableMirrorOptions==0
				#ifdef POI_MIRROR
				float notVisible = 0;
				
				if (_VisibilityMode == 1) // VRC
				
				{
					float mirrorMode = VRCMirrorMode();
					float cameraMode = VRCCameraMode();
					
					notVisible += (!_VisibilityVRCRegular && ((mirrorMode == 0) && (cameraMode == 0)));
					notVisible += (!_VisibilityVRCMirrorVR && (mirrorMode == 1));
					notVisible += (!_VisibilityVRCMirrorDesktop && (mirrorMode == 2));
					notVisible += (!_VisibilityVRCCameraVR && (cameraMode == 1));
					notVisible += (!_VisibilityVRCCameraDesktop && (cameraMode == 2));
					notVisible += (!_VisibilityVRCCameraScreenshot && (cameraMode == 3));
				}
				else if (_Mirror != 0) // Generic (CVR, etc)
				
				{
					notVisible += (_Mirror == 1) ^ IsInMirror();
				}
				
				if (notVisible) // Early Return skips rest of vertex shader
				
				{
					return (VertexOut)POI_NAN;
				}
				#endif
				//endex
				
				o.normal = UnityObjectToWorldNormal(v.normal);
				o.tangent.xyz = UnityObjectToWorldDir(v.tangent);
				o.tangent.w = v.tangent.w;
				o.vertexColor = v.color;
				
				o.uv[0] = float4(v.uv0.xy, v.uv1.xy);
				o.uv[1] = float4(v.uv2.xy, v.uv3.xy);
				
				#if defined(LIGHTMAP_ON)
				o.lightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
				#endif
				#ifdef DYNAMICLIGHTMAP_ON
				o.lightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
				#endif
				
				o.localPos = v.vertex;
				o.worldPos = mul(unity_ObjectToWorld, o.localPos);
				
				float3 localOffset = float3(0, 0, 0);
				float3 worldOffset = float3(0, 0, 0);
				
				//ifex _EnableOutlines!=1
				#ifdef POI_PASS_OUTLINE
				float outlineMask = tex2Dlod(_OutlineMask, float4(poiUV(vertexUV(v, _OutlineMaskUV), _OutlineMask_ST) + _Time.x * _OutlineMaskPan, 0, 0))[_OutlineMaskChannel];
				
				//UNITY_BRANCH
				if (_OutlineVertexColorMask > 0)
				{
					outlineMask *= lerp(1, v.color[_OutlineVertexColorMask - 1], _OutlineVertexColorMaskStrength);
				}
				
				float3 outlineNormal = _OutlineSpace ? o.normal : v.normal;
				//UNITY_BRANCH
				if (_OutlineUseVertexColorNormals)
				{
					float3 outlineTangent;
					float3 outlineBinormal;
					if (_OutlineSpace) // 0 Local, 1 World
					
					{
						outlineTangent = o.tangent;
						outlineBinormal = cross(o.normal, o.tangent) * (v.tangent.w * unity_WorldTransformParams.w);
					}
					else
					{
						outlineTangent = v.tangent.xyz;
						outlineBinormal = normalize(cross(outlineNormal, outlineTangent)) * (v.tangent.w * length(outlineNormal));
					}
					float3 outlineVectorTS = v.color.rgb * 2.0 - 1.0;
					outlineNormal = outlineVectorTS.x * outlineTangent + outlineVectorTS.y * outlineBinormal + outlineVectorTS.z * outlineNormal;
				}
				
				float offsetMultiplier = 1;
				float distanceOffset = 1;
				//UNITY_BRANCH
				if (_OutlineFixedSize)
				{
					distanceOffset *= lerp(1.0, clamp((distance(_WorldSpaceCameraPos, mul(unity_ObjectToWorld, o.localPos).xyz)), 0.0f, _OutlinesMaxDistance), _OutlineFixWidth);
				}
				
				float lineWidth = _LineWidth;
				#ifdef POI_AUDIOLINK
				// Due to PoiMods.audioLink being frag only I'll just
				// recreate what it does here for this vertex function
				//UNITY_BRANCH
				if (_AudioLinkAnimToggle)
				{
					if (AudioLinkIsAvailable())
					{
						lineWidth += lerp(_AudioLinkOutlineSize.x, _AudioLinkOutlineSize.y, AudioLinkData(uint2(0, _AudioLinkOutlineSizeBand)));
					}
				}
				#endif
				
				float3 offset = outlineNormal * (lineWidth * _EnableOutlines / 100) * outlineMask * distanceOffset;
				
				//UNITY_BRANCH
				if (_OutlineExpansionMode == 2)
				{
					float3 lightDirection = normalize(_WorldSpaceLightPos0 + unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz);
					offsetMultiplier = saturate(dot(lightDirection, outlineNormal));
					offset *= offsetMultiplier;
					offset *= distanceOffset;
				}
				else if (_OutlineExpansionMode == 3)
				{
					float3 viewNormal = mul((float3x3)UNITY_MATRIX_V, outlineNormal);
					offsetMultiplier = saturate(dot(viewNormal.xy, normalize(_OutlinePersonaDirection.xy)));
					
					offset *= offsetMultiplier;
					offset *= distanceOffset;
				}
				else if (_OutlineExpansionMode == 4)
				{
					offset = mul((float3x3)transpose(UNITY_MATRIX_V), _OutlineDropShadowOffset);
					offset *= distanceOffset;
				}
				if (_OutlineSpace == 0)
				{
					localOffset += offset;
					worldOffset += mul(unity_ObjectToWorld, offset);
				}
				else
				{
					localOffset += mul(unity_WorldToObject, offset);
					worldOffset += offset;
				}
				#endif
				//endex
				
				//ifex _VertexGlitchingEnabled==0
				#if defined(POI_VERTEX_GLITCHING)
				
				bool canGlitch = true;
				if (_VertexGlitchMirrorEnable && _VertexGlitchMirror > 0)
				{
					bool inMirror = IsInMirror();
					if (_VertexGlitchMirror == 1 && !inMirror)	canGlitch = false;
					if (_VertexGlitchMirror == 2 && inMirror)	canGlitch = false;
				}
				if (canGlitch)
				{
					float3 forward = getCameraPosition() - mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
					forward.y = 0;
					forward = normalize(forward);
					float3 glitchDirection = normalize(cross(float3(0, 1, 0), forward));
					
					float glitchAmount = 0;
					
					#if defined(POI_VERTEX_GLITCHING_TEXTURE)
					// if(_VertexGlitchingUseTexture)
					// {
					float uvl = o.worldPos.y * _VertexGlitchDensity + _Time.x * _VertexGlitchMapPanSpeed;
					float uvr = o.worldPos.y * _VertexGlitchDensity - _Time.x * _VertexGlitchMapPanSpeed;
					
					float3 glitchTextureL = 1;
					float3 glitchTextureR = 1;
					
					#if defined(POI_VERTEX_GLITCHING_TEXTURE) || !defined(OPTIMIZER_ENABLED)
					glitchTextureL = tex2Dlod(_VertexGlitchMap, float4(uvl, uvl, 0, 0)).rgb;
					glitchTextureR = tex2Dlod(_VertexGlitchMap, float4(uvr, uvr, 0, 0)).rgb;
					#endif
					
					glitchAmount += (glitchTextureL.r - 0.5) * 2;
					glitchAmount += - (glitchTextureR.r - 0.5) * 2;
					
					glitchAmount += (glitchTextureL.g - 0.5) * 2;
					glitchAmount += - (glitchTextureR.b - 0.5) * 2;
					// } else {
					#else
					glitchAmount += frac(sin(dot(_Time.xy + o.worldPos.y, float2(12.9898, 78.233))) * 43758.5453123) * 2 - 1;
					// }
					#endif
					
					float time = _Time.y * _VertexGlitchFrequency;
					
					float randomGlitch = (sin(time) + sin(2.2 * time + 5.52) + sin(2.9 * time + 0.93) + sin(4.6 * time + 8.94)) / 4;
					float3 glitchOffset = 0;
					
					#ifdef POI_AUDIOLINK
					if (AudioLinkIsAvailable() && _VertexGlitchingAudioLinkEnabled)
					{
						// float4 audioLinkData = AudioLinkData(ALPASS_AUDIOBASS);
						
						float audioIntensity =
						AudioLinkData(ALPASS_AUDIOBASS).r 		* (_VertexGlitchingAudioLinkBand == 0) +
						AudioLinkData(ALPASS_AUDIOLOWMIDS).r 	* (_VertexGlitchingAudioLinkBand == 1) +
						AudioLinkData(ALPASS_AUDIOHIGHMIDS).r	* (_VertexGlitchingAudioLinkBand == 2) +
						AudioLinkData(ALPASS_AUDIOTREBLE).r 	* (_VertexGlitchingAudioLinkBand == 3) +
						AudioLinkData(ALPASS_FILTEREDVU_INTENSITY).r * (_VertexGlitchingAudioLinkBand == 4);
						
						if(_VertexGlitchingAudiolinkOverride)
						{
							glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
							// glitchOffset += glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
						} else {
							glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
							glitchOffset += glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
						}
					} else {
						glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
					}
					#else
					glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
					#endif
					
					localOffset += glitchOffset;
					worldOffset += mul(unity_ObjectToWorld, glitchOffset);
				}
				#endif
				//endex
				
				o.localPos.rgb += localOffset;
				o.worldPos.rgb += worldOffset;
				
				//ifex _EnableDepthBulge==0
				#if defined(POI_DEPTHBULGE) && (defined(POI_PASS_BASE) || defined(POI_PASS_ADD))
				applyDepthBulgeFX(o);
				#endif
				//endex
				
				//ifex _BSSEnabled!=1
				#ifdef POIBS_ENABLE
				//ifex _BSSBloomfog!=1
				#ifdef POIBS_BLOOMFOG
				o.fogCoord = GetFogCoord(UnityObjectToClipPos(v.vertex));
				o.worldPos = mul(unity_ObjectToWorld, v.vertex);
				#endif
				//endex
				#endif
				//endex
				
				o.pos = UnityObjectToClipPos(o.localPos);
				
				#ifdef POI_PASS_OUTLINE
				#if defined(UNITY_REVERSED_Z)
				//DX
				o.pos.z += _Offset_Z * - 0.01;
				#else
				//OpenGL
				o.pos.z += _Offset_Z * 0.01;
				#endif
				#endif
				//o.grabPos = ComputeGrabScreenPos(o.pos);
				
				#ifndef FORWARD_META_PASS
				#if !defined(UNITY_PASS_SHADOWCASTER)
				UNITY_TRANSFER_SHADOW(o, o.uv[0].xy);
				#else
				v.vertex.xyz = o.localPos.xyz;
				TRANSFER_SHADOW_CASTER_NOPOS(o, o.pos);
				#endif
				#endif
				
				UNITY_TRANSFER_FOG(o, o.pos);
				
				if (_RenderingReduceClipDistance)
				{
					if (o.pos.w < _ProjectionParams.y * 1.01 && o.pos.w > 0)
					{
						#if defined(UNITY_REVERSED_Z) // DirectX
						o.pos.z = o.pos.z * 0.0001 + o.pos.w * 0.999;
						#else // OpenGL
						o.pos.z = o.pos.z * 0.0001 - o.pos.w * 0.999;
						#endif
					}
				}
				
				#ifdef POI_PASS_META
				o.pos = UnityMetaVertexPosition(v.vertex, v.uv1.xy, v.uv2.xy, unity_LightmapST, unity_DynamicLightmapST);
				#endif
				
				return o;
			}
			
			//ifex _GlobalMaskTexturesEnable==0
			#ifdef POI_GLOBALMASK_TEXTURES
			void ApplyGlobalMaskTextures(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				#if defined(PROP_GLOBALMASKTEXTURE0) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol0 = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0_ST), _GlobalMaskTexture0Pan);
				if (_GlobalMaskTexture0Split)
				{
					poiMods.globalMask[0] = gmcol0.r;
					poiMods.globalMask[1] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_G), _GlobalMaskTexture0SplitPan_G).g;
					poiMods.globalMask[2] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_B), _GlobalMaskTexture0SplitPan_B).b;
					poiMods.globalMask[3] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_A), _GlobalMaskTexture0SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[0] = gmcol0[0];
					poiMods.globalMask[1] = gmcol0[1];
					poiMods.globalMask[2] = gmcol0[2];
					poiMods.globalMask[3] = gmcol0[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE1) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol1 = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1_ST), _GlobalMaskTexture1Pan);
				if (_GlobalMaskTexture1Split)
				{
					poiMods.globalMask[4] = gmcol1.r;
					poiMods.globalMask[5] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_G), _GlobalMaskTexture1SplitPan_G).g;
					poiMods.globalMask[6] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_B), _GlobalMaskTexture1SplitPan_B).b;
					poiMods.globalMask[7] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_A), _GlobalMaskTexture1SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[4] = gmcol1[0];
					poiMods.globalMask[5] = gmcol1[1];
					poiMods.globalMask[6] = gmcol1[2];
					poiMods.globalMask[7] = gmcol1[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE2) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol2 = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2_ST), _GlobalMaskTexture2Pan);
				if (_GlobalMaskTexture2Split)
				{
					poiMods.globalMask[8] = gmcol2.r;
					poiMods.globalMask[9] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_G), _GlobalMaskTexture2SplitPan_G).g;
					poiMods.globalMask[10] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_B), _GlobalMaskTexture2SplitPan_B).b;
					poiMods.globalMask[11] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_A), _GlobalMaskTexture2SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[8] = gmcol2[0];
					poiMods.globalMask[9] = gmcol2[1];
					poiMods.globalMask[10] = gmcol2[2];
					poiMods.globalMask[11] = gmcol2[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE3) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol3 = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3_ST), _GlobalMaskTexture3Pan);
				if (_GlobalMaskTexture3Split)
				{
					poiMods.globalMask[12] = gmcol3.r;
					poiMods.globalMask[13] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_G), _GlobalMaskTexture3SplitPan_G).g;
					poiMods.globalMask[14] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_B), _GlobalMaskTexture3SplitPan_B).b;
					poiMods.globalMask[15] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_A), _GlobalMaskTexture3SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[12] = gmcol3[0];
					poiMods.globalMask[13] = gmcol3[1];
					poiMods.globalMask[14] = gmcol3[2];
					poiMods.globalMask[15] = gmcol3[3];
				}
				#endif
			}
			#endif
			//endex
			//ifex _GlobalMaskOptionsEnable==0
			void ApplyGlobalMaskOptions(inout PoiMods poiMods)
			{
				//ifex _GlobalMaskOptionsType!=0
				if (_GlobalMaskOptionsType == 0)
				{
					poiMods.globalMask[0] = saturate(poiMods.globalMask[0] + _GlobalMaskSlider_0);
					poiMods.globalMask[1] = saturate(poiMods.globalMask[1] + _GlobalMaskSlider_1);
					poiMods.globalMask[2] = saturate(poiMods.globalMask[2] + _GlobalMaskSlider_2);
					poiMods.globalMask[3] = saturate(poiMods.globalMask[3] + _GlobalMaskSlider_3);
					poiMods.globalMask[4] = saturate(poiMods.globalMask[4] + _GlobalMaskSlider_4);
					poiMods.globalMask[5] = saturate(poiMods.globalMask[5] + _GlobalMaskSlider_5);
					poiMods.globalMask[6] = saturate(poiMods.globalMask[6] + _GlobalMaskSlider_6);
					poiMods.globalMask[7] = saturate(poiMods.globalMask[7] + _GlobalMaskSlider_7);
					poiMods.globalMask[8] = saturate(poiMods.globalMask[8] + _GlobalMaskSlider_8);
					poiMods.globalMask[9] = saturate(poiMods.globalMask[9] + _GlobalMaskSlider_9);
					poiMods.globalMask[10] = saturate(poiMods.globalMask[10] + _GlobalMaskSlider_10);
					poiMods.globalMask[11] = saturate(poiMods.globalMask[11] + _GlobalMaskSlider_11);
					poiMods.globalMask[12] = saturate(poiMods.globalMask[12] + _GlobalMaskSlider_12);
					poiMods.globalMask[13] = saturate(poiMods.globalMask[13] + _GlobalMaskSlider_13);
					poiMods.globalMask[14] = saturate(poiMods.globalMask[14] + _GlobalMaskSlider_14);
					poiMods.globalMask[15] = saturate(poiMods.globalMask[15] + _GlobalMaskSlider_15);
				}
				//endex
				//ifex _GlobalMaskOptionsType!=1
				if (_GlobalMaskOptionsType == 1)
				{
					poiMods.globalMask[0] = lerp(_GlobalMaskMinMaxSlider_0.x, _GlobalMaskMinMaxSlider_0.y, poiMods.globalMask[0]);
					poiMods.globalMask[1] = lerp(_GlobalMaskMinMaxSlider_1.x, _GlobalMaskMinMaxSlider_1.y, poiMods.globalMask[1]);
					poiMods.globalMask[2] = lerp(_GlobalMaskMinMaxSlider_2.x, _GlobalMaskMinMaxSlider_2.y, poiMods.globalMask[2]);
					poiMods.globalMask[3] = lerp(_GlobalMaskMinMaxSlider_3.x, _GlobalMaskMinMaxSlider_3.y, poiMods.globalMask[3]);
					poiMods.globalMask[4] = lerp(_GlobalMaskMinMaxSlider_4.x, _GlobalMaskMinMaxSlider_4.y, poiMods.globalMask[4]);
					poiMods.globalMask[5] = lerp(_GlobalMaskMinMaxSlider_5.x, _GlobalMaskMinMaxSlider_5.y, poiMods.globalMask[5]);
					poiMods.globalMask[6] = lerp(_GlobalMaskMinMaxSlider_6.x, _GlobalMaskMinMaxSlider_6.y, poiMods.globalMask[6]);
					poiMods.globalMask[7] = lerp(_GlobalMaskMinMaxSlider_7.x, _GlobalMaskMinMaxSlider_7.y, poiMods.globalMask[7]);
					poiMods.globalMask[8] = lerp(_GlobalMaskMinMaxSlider_8.x, _GlobalMaskMinMaxSlider_8.y, poiMods.globalMask[8]);
					poiMods.globalMask[9] = lerp(_GlobalMaskMinMaxSlider_9.x, _GlobalMaskMinMaxSlider_9.y, poiMods.globalMask[9]);
					poiMods.globalMask[10] = lerp(_GlobalMaskMinMaxSlider_10.x, _GlobalMaskMinMaxSlider_10.y, poiMods.globalMask[10]);
					poiMods.globalMask[11] = lerp(_GlobalMaskMinMaxSlider_11.x, _GlobalMaskMinMaxSlider_11.y, poiMods.globalMask[11]);
					poiMods.globalMask[12] = lerp(_GlobalMaskMinMaxSlider_12.x, _GlobalMaskMinMaxSlider_12.y, poiMods.globalMask[12]);
					poiMods.globalMask[13] = lerp(_GlobalMaskMinMaxSlider_13.x, _GlobalMaskMinMaxSlider_13.y, poiMods.globalMask[13]);
					poiMods.globalMask[14] = lerp(_GlobalMaskMinMaxSlider_14.x, _GlobalMaskMinMaxSlider_14.y, poiMods.globalMask[14]);
					poiMods.globalMask[15] = lerp(_GlobalMaskMinMaxSlider_15.x, _GlobalMaskMinMaxSlider_15.y, poiMods.globalMask[15]);
				}
				//endex
				//ifex _GlobalMaskOptionsType!=2
				if (_GlobalMaskOptionsType == 2)
				{
					if (_GlobalMaskToggleOn_0)  poiMods.globalMask[0] = 1;
					if (_GlobalMaskToggleOn_1)  poiMods.globalMask[1] = 1;
					if (_GlobalMaskToggleOn_2)  poiMods.globalMask[2] = 1;
					if (_GlobalMaskToggleOn_3)  poiMods.globalMask[3] = 1;
					if (_GlobalMaskToggleOn_4)  poiMods.globalMask[4] = 1;
					if (_GlobalMaskToggleOn_5)  poiMods.globalMask[5] = 1;
					if (_GlobalMaskToggleOn_6)  poiMods.globalMask[6] = 1;
					if (_GlobalMaskToggleOn_7)  poiMods.globalMask[7] = 1;
					if (_GlobalMaskToggleOn_8)  poiMods.globalMask[8] = 1;
					if (_GlobalMaskToggleOn_9)  poiMods.globalMask[9] = 1;
					if (_GlobalMaskToggleOn_10) poiMods.globalMask[10] = 1;
					if (_GlobalMaskToggleOn_11) poiMods.globalMask[11] = 1;
					if (_GlobalMaskToggleOn_12) poiMods.globalMask[12] = 1;
					if (_GlobalMaskToggleOn_13) poiMods.globalMask[13] = 1;
					if (_GlobalMaskToggleOn_14) poiMods.globalMask[14] = 1;
					if (_GlobalMaskToggleOn_15) poiMods.globalMask[15] = 1;
					
					poiMods.globalMask[0] *= (1 - _GlobalMaskToggleOff_0);
					poiMods.globalMask[1] *= (1 - _GlobalMaskToggleOff_1);
					poiMods.globalMask[2] *= (1 - _GlobalMaskToggleOff_2);
					poiMods.globalMask[3] *= (1 - _GlobalMaskToggleOff_3);
					poiMods.globalMask[4] *= (1 - _GlobalMaskToggleOff_4);
					poiMods.globalMask[5] *= (1 - _GlobalMaskToggleOff_5);
					poiMods.globalMask[6] *= (1 - _GlobalMaskToggleOff_6);
					poiMods.globalMask[7] *= (1 - _GlobalMaskToggleOff_7);
					poiMods.globalMask[8] *= (1 - _GlobalMaskToggleOff_8);
					poiMods.globalMask[9] *= (1 - _GlobalMaskToggleOff_9);
					poiMods.globalMask[10] *= (1 - _GlobalMaskToggleOff_10);
					poiMods.globalMask[11] *= (1 - _GlobalMaskToggleOff_11);
					poiMods.globalMask[12] *= (1 - _GlobalMaskToggleOff_12);
					poiMods.globalMask[13] *= (1 - _GlobalMaskToggleOff_13);
					poiMods.globalMask[14] *= (1 - _GlobalMaskToggleOff_14);
					poiMods.globalMask[15] *= (1 - _GlobalMaskToggleOff_15);
				}
				//endex
				
			}
			//endex
			
			float customDistanceBlend(float base, float blend, float blendType)
			{
				switch(blendType)
				{
					case 0: return blendNormal(base, blend); break;
					case 2: return blendMultiply(base, blend); break;
					default: return 0; break;
				}
			}
			
			void handleGlobalMaskDistance(int index, bool enable, bool type, float minAlpha, float maxAlpha, float min, float max, int blendType, in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				if (enable)
				{
					float3 position = type ? poiMesh.worldPos : poiMesh.objectPosition;
					float val = lerp(minAlpha, maxAlpha, smoothstep(min, max, distance(position, _WorldSpaceCameraPos)));
					poiMods.globalMask[index] = saturate(customDistanceBlend(poiMods.globalMask[index], val, blendType));
				}
			}
			
			void ApplyGlobalMaskModifiers(in PoiMesh poiMesh, inout PoiMods poiMods, in PoiCam poiCam)
			{
				//ifex _GlobalMaskModifiersBackfaceEnable==0
				if (_GlobalMaskModifiersBackfaceEnable)
				{
					float facingMode = saturate(poiMesh.isFrontFace) + 1;
					// _GlobalMaskBackface is 0 for ignore, 1 for back only, 2 for front only
					poiMods.globalMask[0] *= _GlobalMaskBackface_0 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_0));
					poiMods.globalMask[1] *= _GlobalMaskBackface_1 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_1));
					poiMods.globalMask[2] *= _GlobalMaskBackface_2 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_2));
					poiMods.globalMask[3] *= _GlobalMaskBackface_3 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_3));
					poiMods.globalMask[4] *= _GlobalMaskBackface_4 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_4));
					poiMods.globalMask[5] *= _GlobalMaskBackface_5 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_5));
					poiMods.globalMask[6] *= _GlobalMaskBackface_6 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_6));
					poiMods.globalMask[7] *= _GlobalMaskBackface_7 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_7));
					poiMods.globalMask[8] *= _GlobalMaskBackface_8 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_8));
					poiMods.globalMask[9] *= _GlobalMaskBackface_9 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_9));
					poiMods.globalMask[10] *= _GlobalMaskBackface_10 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_10));
					poiMods.globalMask[11] *= _GlobalMaskBackface_11 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_11));
					poiMods.globalMask[12] *= _GlobalMaskBackface_12 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_12));
					poiMods.globalMask[13] *= _GlobalMaskBackface_13 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_13));
					poiMods.globalMask[14] *= _GlobalMaskBackface_14 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_14));
					poiMods.globalMask[15] *= _GlobalMaskBackface_15 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_15));
				}
				//endex
				
				//ifex _GlobalMaskModifiersMirrorEnable==0
				if (_GlobalMaskModifiersMirrorEnable)
				{
					float mirrorMode = 0;
					if (_GlobalMaskMirrorVisibilityMode == 1) // VRC
					mirrorMode = VRCMirrorMode() > 0;
					else // Generic (CVR, etc)
					mirrorMode = IsInMirror();
					
					mirrorMode += 1;
					// _GlobalMaskMirror is 0 for ignore, 1 for outside mirror only, 2 for in mirror only
					poiMods.globalMask[0] *= _GlobalMaskMirror_0 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_0));
					poiMods.globalMask[1] *= _GlobalMaskMirror_1 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_1));
					poiMods.globalMask[2] *= _GlobalMaskMirror_2 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_2));
					poiMods.globalMask[3] *= _GlobalMaskMirror_3 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_3));
					poiMods.globalMask[4] *= _GlobalMaskMirror_4 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_4));
					poiMods.globalMask[5] *= _GlobalMaskMirror_5 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_5));
					poiMods.globalMask[6] *= _GlobalMaskMirror_6 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_6));
					poiMods.globalMask[7] *= _GlobalMaskMirror_7 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_7));
					poiMods.globalMask[8] *= _GlobalMaskMirror_8 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_8));
					poiMods.globalMask[9] *= _GlobalMaskMirror_9 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_9));
					poiMods.globalMask[10] *= _GlobalMaskMirror_10 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_10));
					poiMods.globalMask[11] *= _GlobalMaskMirror_11 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_11));
					poiMods.globalMask[12] *= _GlobalMaskMirror_12 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_12));
					poiMods.globalMask[13] *= _GlobalMaskMirror_13 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_13));
					poiMods.globalMask[14] *= _GlobalMaskMirror_14 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_14));
					poiMods.globalMask[15] *= _GlobalMaskMirror_15 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_15));
				}
				//endex
				
				//ifex _GlobalMaskModifiersCameraEnable==0
				if (_GlobalMaskModifiersCameraEnable)
				{
					float isCamera = VRCCameraMode() > 0;
					isCamera += 1;
					// _GlobalMaskCamera is 0 for ignore, 1 for outside camera only, 2 for in camera only
					poiMods.globalMask[0] *= _GlobalMaskCamera_0 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_0));
					poiMods.globalMask[1] *= _GlobalMaskCamera_1 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_1));
					poiMods.globalMask[2] *= _GlobalMaskCamera_2 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_2));
					poiMods.globalMask[3] *= _GlobalMaskCamera_3 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_3));
					poiMods.globalMask[4] *= _GlobalMaskCamera_4 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_4));
					poiMods.globalMask[5] *= _GlobalMaskCamera_5 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_5));
					poiMods.globalMask[6] *= _GlobalMaskCamera_6 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_6));
					poiMods.globalMask[7] *= _GlobalMaskCamera_7 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_7));
					poiMods.globalMask[8] *= _GlobalMaskCamera_8 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_8));
					poiMods.globalMask[9] *= _GlobalMaskCamera_9 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_9));
					poiMods.globalMask[10] *= _GlobalMaskCamera_10 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_10));
					poiMods.globalMask[11] *= _GlobalMaskCamera_11 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_11));
					poiMods.globalMask[12] *= _GlobalMaskCamera_12 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_12));
					poiMods.globalMask[13] *= _GlobalMaskCamera_13 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_13));
					poiMods.globalMask[14] *= _GlobalMaskCamera_14 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_14));
					poiMods.globalMask[15] *= _GlobalMaskCamera_15 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_15));
				}
				//endex
				//ifex _GlobalMaskModifiersDistanceEnable==0
				if (_GlobalMaskModifiersDistanceEnable)
				{
					//ifex _GlobalMaskDistanceEnable_0==0
					handleGlobalMaskDistance(0, _GlobalMaskDistanceEnable_0, _GlobalMaskDistanceType_0, _GlobalMaskDistanceMinAlpha_0, _GlobalMaskDistanceMaxAlpha_0, _GlobalMaskDistanceMin_0, _GlobalMaskDistanceMax_0, _GlobalMaskDistanceBlendType_0, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_1==0
					handleGlobalMaskDistance(1, _GlobalMaskDistanceEnable_1, _GlobalMaskDistanceType_1, _GlobalMaskDistanceMinAlpha_1, _GlobalMaskDistanceMaxAlpha_1, _GlobalMaskDistanceMin_1, _GlobalMaskDistanceMax_1, _GlobalMaskDistanceBlendType_1, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_2==0
					handleGlobalMaskDistance(2, _GlobalMaskDistanceEnable_2, _GlobalMaskDistanceType_2, _GlobalMaskDistanceMinAlpha_2, _GlobalMaskDistanceMaxAlpha_2, _GlobalMaskDistanceMin_2, _GlobalMaskDistanceMax_2, _GlobalMaskDistanceBlendType_2, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_3==0
					handleGlobalMaskDistance(3, _GlobalMaskDistanceEnable_3, _GlobalMaskDistanceType_3, _GlobalMaskDistanceMinAlpha_3, _GlobalMaskDistanceMaxAlpha_3, _GlobalMaskDistanceMin_3, _GlobalMaskDistanceMax_3, _GlobalMaskDistanceBlendType_3, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_4==0
					handleGlobalMaskDistance(4, _GlobalMaskDistanceEnable_4, _GlobalMaskDistanceType_4, _GlobalMaskDistanceMinAlpha_4, _GlobalMaskDistanceMaxAlpha_4, _GlobalMaskDistanceMin_4, _GlobalMaskDistanceMax_4, _GlobalMaskDistanceBlendType_4, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_5==0
					handleGlobalMaskDistance(5, _GlobalMaskDistanceEnable_5, _GlobalMaskDistanceType_5, _GlobalMaskDistanceMinAlpha_5, _GlobalMaskDistanceMaxAlpha_5, _GlobalMaskDistanceMin_5, _GlobalMaskDistanceMax_5, _GlobalMaskDistanceBlendType_5, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_6==0
					handleGlobalMaskDistance(6, _GlobalMaskDistanceEnable_6, _GlobalMaskDistanceType_6, _GlobalMaskDistanceMinAlpha_6, _GlobalMaskDistanceMaxAlpha_6, _GlobalMaskDistanceMin_6, _GlobalMaskDistanceMax_6, _GlobalMaskDistanceBlendType_6, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_7==0
					handleGlobalMaskDistance(7, _GlobalMaskDistanceEnable_7, _GlobalMaskDistanceType_7, _GlobalMaskDistanceMinAlpha_7, _GlobalMaskDistanceMaxAlpha_7, _GlobalMaskDistanceMin_7, _GlobalMaskDistanceMax_7, _GlobalMaskDistanceBlendType_7, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_8==0
					handleGlobalMaskDistance(8, _GlobalMaskDistanceEnable_8, _GlobalMaskDistanceType_8, _GlobalMaskDistanceMinAlpha_8, _GlobalMaskDistanceMaxAlpha_8, _GlobalMaskDistanceMin_8, _GlobalMaskDistanceMax_8, _GlobalMaskDistanceBlendType_8, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_9==0
					handleGlobalMaskDistance(9, _GlobalMaskDistanceEnable_9, _GlobalMaskDistanceType_9, _GlobalMaskDistanceMinAlpha_9, _GlobalMaskDistanceMaxAlpha_9, _GlobalMaskDistanceMin_9, _GlobalMaskDistanceMax_9, _GlobalMaskDistanceBlendType_9, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_10==0
					handleGlobalMaskDistance(10, _GlobalMaskDistanceEnable_10, _GlobalMaskDistanceType_10, _GlobalMaskDistanceMinAlpha_10, _GlobalMaskDistanceMaxAlpha_10, _GlobalMaskDistanceMin_10, _GlobalMaskDistanceMax_10, _GlobalMaskDistanceBlendType_10, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_11==0
					handleGlobalMaskDistance(11, _GlobalMaskDistanceEnable_11, _GlobalMaskDistanceType_11, _GlobalMaskDistanceMinAlpha_11, _GlobalMaskDistanceMaxAlpha_11, _GlobalMaskDistanceMin_11, _GlobalMaskDistanceMax_11, _GlobalMaskDistanceBlendType_11, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_12==0
					handleGlobalMaskDistance(12, _GlobalMaskDistanceEnable_12, _GlobalMaskDistanceType_12, _GlobalMaskDistanceMinAlpha_12, _GlobalMaskDistanceMaxAlpha_12, _GlobalMaskDistanceMin_12, _GlobalMaskDistanceMax_12, _GlobalMaskDistanceBlendType_12, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_13==0
					handleGlobalMaskDistance(13, _GlobalMaskDistanceEnable_13, _GlobalMaskDistanceType_13, _GlobalMaskDistanceMinAlpha_13, _GlobalMaskDistanceMaxAlpha_13, _GlobalMaskDistanceMin_13, _GlobalMaskDistanceMax_13, _GlobalMaskDistanceBlendType_13, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_14==0
					handleGlobalMaskDistance(14, _GlobalMaskDistanceEnable_14, _GlobalMaskDistanceType_14, _GlobalMaskDistanceMinAlpha_14, _GlobalMaskDistanceMaxAlpha_14, _GlobalMaskDistanceMin_14, _GlobalMaskDistanceMax_14, _GlobalMaskDistanceBlendType_14, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_15==0
					handleGlobalMaskDistance(15, _GlobalMaskDistanceEnable_15, _GlobalMaskDistanceType_15, _GlobalMaskDistanceMinAlpha_15, _GlobalMaskDistanceMaxAlpha_15, _GlobalMaskDistanceMin_15, _GlobalMaskDistanceMax_15, _GlobalMaskDistanceBlendType_15, poiMesh, poiMods);
					//endex
					
				}
				//endex
				
			}
			
			//ifex _GlobalMaskVertexColorRed==0 && _GlobalMaskVertexColorGreen==0 && _GlobalMaskVertexColorBlue==0 && _GlobalMaskVertexColorAlpha==0
			void ApplyGlobalMaskVertexColors(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				float4 vcol = poiMesh.vertexColor;
				if (_GlobalMaskVertexColorLinearSpace)
				{
					vcol.rgb = GammaToLinearSpace(vcol.rgb);
				}
				if (_GlobalMaskVertexColorRed > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorRed - 1, _GlobalMaskVertexColorRedBlendType, vcol.r);
				}
				if (_GlobalMaskVertexColorGreen > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorGreen - 1, _GlobalMaskVertexColorGreenBlendType, vcol.g);
				}
				if (_GlobalMaskVertexColorBlue > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorBlue - 1, _GlobalMaskVertexColorBlueBlendType, vcol.b);
				}
				if (_GlobalMaskVertexColorAlpha > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorAlpha - 1, _GlobalMaskVertexColorAlphaBlendType, vcol.a);
				}
			}
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#ifdef POI_UDIMDISCARD
			void applyUDIMDiscard(in VertexOut i)
			{
				if(_UDIMDiscardMode == 1) // Don't run if in vertex mode
				{
					float2 udim = floor(vertexUV(i, _UDIMDiscardUV));
					
					float isDiscarded = 0;
					float4 xMask = float4(  (udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					isDiscarded += (udim.y >= 0 && udim.y < 1) * dot(float4(_UDIMDiscardRow0_0, _UDIMDiscardRow0_1, _UDIMDiscardRow0_2, _UDIMDiscardRow0_3), xMask);
					isDiscarded += (udim.y >= 1 && udim.y < 2) * dot(float4(_UDIMDiscardRow1_0, _UDIMDiscardRow1_1, _UDIMDiscardRow1_2, _UDIMDiscardRow1_3), xMask);
					isDiscarded += (udim.y >= 2 && udim.y < 3) * dot(float4(_UDIMDiscardRow2_0, _UDIMDiscardRow2_1, _UDIMDiscardRow2_2, _UDIMDiscardRow2_3), xMask);
					isDiscarded += (udim.y >= 3 && udim.y < 4) * dot(float4(_UDIMDiscardRow3_0, _UDIMDiscardRow3_1, _UDIMDiscardRow3_2, _UDIMDiscardRow3_3), xMask);
					
					isDiscarded *= any(float4(udim.y >= 0, udim.y < 4, udim.x >= 0, udim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					const float threshold = 0.001;
					clip(threshold - isDiscarded); // Clip if discarded
				}
				
				return;
			}
			#endif
			//endex
			
			//ifex _EnableMirrorOptions==0
			#ifdef POI_MIRROR
			void applyMirror(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float inMirror = 0;
				// VRC
				if (_VisibilityMode == 1)
				{
					inMirror = VRCMirrorMode() > 0;
				}
				// Generic (CVR, etc)
				else
				{
					inMirror = IsInMirror();
				}
				
				#if (defined(POI_PASS_BASE) || defined(POI_PASS_ADD))
				#if defined(PROP_MIRRORTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 mirrorTexture = POI2D_SAMPLER_PAN(_MirrorTexture, _MainTex, poiUV(poiMesh.uv[_MirrorTextureUV], _MirrorTexture_ST), _MirrorTexturePan);
				if (inMirror && _MirrorTextureEnabled || _MirrorTextureForceEnabled)
				{
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, mirrorTexture.rgb, _MirrorTextureBlendType), mirrorTexture.a * _MirrorColor.a);
					poiFragData.baseColor.rgb *= lerp(1, poiThemeColor(poiMods, _MirrorColor.rgb, _MirrorColorThemeIndex), _MirrorColor.a);
				}
				#else
				if (inMirror && _MirrorTextureEnabled || _MirrorTextureForceEnabled)
				{
					poiFragData.baseColor.rgb *= lerp(1, poiThemeColor(poiMods, _MirrorColor.rgb, _MirrorColorThemeIndex), _MirrorColor.a);
				}
				#endif
				#endif
			}
			#endif
			//endex
			
			float4 frag(VertexOut i, uint facing : SV_IsFrontFace) : SV_Target
			/*
			#ifdef
			, out float depth : SV_DEPTH
			#endif
			*/
			{
				clip(_RenderingEarlyZEnabled - 1.0);
				UNITY_SETUP_INSTANCE_ID(i);
				UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
				return float4(1, 1, 1, 1);
			}
			
			ENDCG
		}
		//endex
		
		Pass
		{
			Name "Base"
			Tags { "LightMode" = "ForwardBase" }
			
			Stencil
			{
				Ref [_StencilRef]
				ReadMask [_StencilReadMask]
				WriteMask [_StencilWriteMask]
				//ifex _StencilType==1
				Comp [_StencilCompareFunction]
				Pass [_StencilPassOp]
				Fail [_StencilFailOp]
				ZFail [_StencilZFailOp]
				//endex
				
				//ifex _StencilType==0
				CompBack [_StencilBackCompareFunction]
				PassBack [_StencilBackPassOp]
				FailBack [_StencilBackFailOp]
				ZFailBack [_StencilBackZFailOp]
				
				CompFront [_StencilFrontCompareFunction]
				PassFront [_StencilFrontPassOp]
				FailFront [_StencilFrontFailOp]
				ZFailFront [_StencilFrontZFailOp]
				//endex
			}
			
			ZWrite [_ZWrite]
			Cull [_Cull]
			Cull Front
			
			AlphaToMask [_AlphaToCoverage]
			ZTest [_ZTest]
			ColorMask [_ColorMask]
			Offset [_OffsetFactor], [_OffsetUnits]
			
			BlendOp [_BlendOp], [_BlendOpAlpha]
			Blend [_SrcBlend] [_DstBlend], [_SrcBlendAlpha] [_DstBlendAlpha]
			
			CGPROGRAM
			/*
			// Disable warnings we aren't interested in
			#if defined(UNITY_COMPILER_HLSL)
			#pragma warning(disable : 3205) // conversion of larger type to smaller
			#pragma warning(disable : 3568) // unknown pragma ignored
			#pragma warning(disable : 3571) // "pow(f,e) will not work for negative f"; however in majority of our calls to pow we know f is not negative
			#pragma warning(disable : 3206) // implicit truncation of vector type
			#endif
			*/
			#pragma target 5.0
			//ifex 0==0
			#pragma skip_optimizations d3d11
			//endex
			
			#pragma shader_feature_local _STOCHASTICMODE_DELIOT_HEITZ _STOCHASTICMODE_HEXTILE _STOCHASTICMODE_NONE
			
			//ifex _MainColorAdjustToggle==0
			#pragma shader_feature COLOR_GRADING_HDR
			//endex
			
			//#pragma shader_feature KEYWORD
			
			#pragma skip_variants LIGHTMAP_ON DYNAMICLIGHTMAP_ON LIGHTMAP_SHADOW_MIXING SHADOWS_SHADOWMASK DIRLIGHTMAP_COMBINED _MIXED_LIGHTING_SUBTRACTIVE
			#pragma skip_variants DECALS_OFF DECALS_3RT DECALS_4RT DECAL_SURFACE_GRADIENT _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3
			#pragma skip_variants _ADDITIONAL_LIGHT_SHADOWS
			#pragma skip_variants PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2
			#pragma skip_variants _SCREEN_SPACE_OCCLUSION
			
			//ifex _GlobalMaskTexturesEnable==0
			#pragma shader_feature_local POI_GLOBALMASK_TEXTURES
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#pragma shader_feature_local POI_UDIMDISCARD
			//endex
			
			//ifex _EnableDistortion==0
			#pragma shader_feature USER_LUT
			//endex
			
			//ifex _PoiParallax==0
			#pragma shader_feature_local POI_PARALLAX
			//endex
			
			//ifex _EnableAudioLink==0
			#pragma shader_feature_local POI_AUDIOLINK
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#pragma shader_feature_local POI_BLACKLIGHTMASKING
			//endex
			
			//ifex _DetailEnabled==0
			#pragma shader_feature FINALPASS
			//endex
			
			//ifex _VertexManipulationsEnabled==0
			#pragma shader_feature AUTO_EXPOSURE
			//endex
			
			//ifex _VertexGlitchingEnabled==0
			#pragma shader_feature_local POI_VERTEX_GLITCHING
			#pragma shader_feature_local POI_VERTEX_GLITCHING_TEXTURE
			//endex
			
			//ifex _EnableDepthBulge==0
			#pragma shader_feature_local POI_DEPTHBULGE
			//endex
			
			//ifex _BackFaceEnabled!=1
			#pragma shader_feature_local POI_BACKFACE
			//endex
			
			//ifex _RGBMaskEnabled==0
			#pragma shader_feature VIGNETTE
			#pragma shader_feature GEOM_TYPE_MESH
			//endex
			
			//ifex _LTCGIEnabled!=1
			#pragma shader_feature_local POI_LTCGI
			//endex
			
			//ifex _ShadingEnabled==0
			#pragma shader_feature_local VIGNETTE_MASKED
			#pragma shader_feature_local _LIGHTINGMODE_TEXTURERAMP _LIGHTINGMODE_MULTILAYER_MATH _LIGHTINGMODE_SHADEMAP _LIGHTINGMODE_REALISTIC _LIGHTINGMODE_WRAPPED _LIGHTINGMODE_SKIN _LIGHTINGMODE_FLAT _LIGHTINGMODE_CLOTH _LIGHTINGMODE_SDF
			//endex
			
			//ifex _DecalEnabled==0
			#pragma shader_feature GEOM_TYPE_BRANCH
			//endex
			//ifex _DecalEnabled1==0
			#pragma shader_feature GEOM_TYPE_BRANCH_DETAIL
			//endex
			//ifex _DecalEnabled2==0
			#pragma shader_feature GEOM_TYPE_FROND
			//endex
			//ifex _DecalEnabled3==0
			#pragma shader_feature DEPTH_OF_FIELD_COC_VIEW
			//endex
			
			//ifex _EnableDissolve==0
			#pragma shader_feature DISTORT
			//endex
			
			//ifex _EnableAniso==0
			#pragma shader_feature_local POI_ANISOTROPICS
			//endex
			
			//ifex _MatcapEnable==0
			#pragma shader_feature_local POI_MATCAP0
			#pragma shader_feature_local POI_MATCAP0_CUSTOM_NORMAL
			//endex
			//ifex _Matcap2Enable==0
			#pragma shader_feature COLOR_GRADING_HDR_3D
			#pragma shader_feature_local POI_MATCAP1_CUSTOM_NORMAL
			//endex
			//ifex _Matcap3Enable==0
			#pragma shader_feature_local POI_MATCAP2
			#pragma shader_feature_local POI_MATCAP2_CUSTOM_NORMAL
			//endex
			//ifex _Matcap4Enable==0
			#pragma shader_feature_local POI_MATCAP3
			#pragma shader_feature_local POI_MATCAP3_CUSTOM_NORMAL
			//endex
			
			//ifex _CubeMapEnabled==0
			#pragma shader_feature_local _CUBEMAP
			//endex
			
			//ifex _EnableALDecal==0
			#pragma shader_feature_local POI_AL_DECAL
			//endex
			
			//ifex _EnableVolumeColor==0
			#pragma shader_feature_local POI_AL_VOLUMECOLOR
			//endex
			
			//ifex _EnableFlipbook==0
			#pragma shader_feature _SUNDISK_HIGH_QUALITY
			//endex
			
			//ifex _EnableEmission==0
			#pragma shader_feature _EMISSION
			//endex
			//ifex _EnableEmission1==0
			#pragma shader_feature_local POI_EMISSION_1
			//endex
			//ifex _EnableEmission2==0
			#pragma shader_feature_local POI_EMISSION_2
			//endex
			//ifex _EnableEmission3==0
			#pragma shader_feature_local POI_EMISSION_3
			//endex
			
			//ifex _EnableRimLighting==0
			#pragma shader_feature_local _GLOSSYREFLECTIONS_OFF
			#pragma shader_feature_local _RIMSTYLE_POIYOMI _RIMSTYLE_UTS2 _RIMSTYLE_LILTOON
			//endex
			//ifex _EnableRim2Lighting==0
			#pragma shader_feature_local POI_RIM2
			#pragma shader_feature_local _RIM2STYLE_POIYOMI _RIM2STYLE_UTS2 _RIM2STYLE_LILTOON
			//endex
			
			//ifex _EnableDepthRimLighting==0
			#pragma shader_feature_local _POI_DEPTH_RIMLIGHT
			//endex
			
			//ifex _GlitterEnable==0
			#pragma shader_feature _SUNDISK_SIMPLE
			//endex
			
			//ifex _SubsurfaceScattering==0
			#pragma shader_feature_local POI_SUBSURFACESCATTERING
			//endex
			
			//ifex _MochieBRDF==0
			#pragma shader_feature_local MOCHIE_PBR
			//endex
			//ifex _ClearCoatBRDF==0
			#pragma shader_feature_local POI_CLEARCOAT
			//endex
			
			//ifex _EnableEnvironmentalRim==0
			#pragma shader_feature_local POI_ENVIRORIM
			//endex
			
			//ifex _StylizedSpecular==0
			#pragma shader_feature_local POI_STYLIZED_StylizedSpecular
			//endex
			
			//ifex _EnablePathing==0
			#pragma shader_feature_local POI_PATHING
			//endex
			
			//ifex _EnableMirrorOptions==0
			#pragma shader_feature_local POI_MIRROR
			//endex
			
			//ifex _EnableTouchGlow==0
			#pragma shader_feature GRAIN
			//endex
			
			//ifex _TextEnabled==0
			#pragma shader_feature EFFECT_BUMP
			//endex
			
			//ifex _PostProcess==0
			#pragma shader_feature_local POSTPROCESS
			//endex
			
			//ifex _PoiInternalParallax==0
			#pragma shader_feature_local POI_INTERNALPARALLAX
			//endex
			
			//ifex _NormalCorrect==0
			#pragma shader_feature_local POI_NORMALCORRECT
			//endex
			
			//ifex _VideoEffectsEnable==0
			#pragma shader_feature_local POI_VIDEO_EFFECTS
			//endex
			
			//ifex _BacklightEnabled!=1
			#pragma shader_feature_local POI_BACKLIGHT
			//endex
			
			//ifex _BSSEnabled!=1
			#pragma shader_feature_local POIBS_ENABLE
			//ifex _BSSBloomfog!=1
			#pragma shader_feature_local POIBS_BLOOMFOG
			#pragma shader_feature_local BSSBLOOMFOGTYPE_HEIGHT
			//endex
			//endex
			
			//ifex _VoronoiEnabled!=1
			#pragma shader_feature_local POI_VORONOI
			//endex
			
			#pragma multi_compile_fwdbase
			#pragma multi_compile_instancing
			#pragma multi_compile_fog
			#pragma multi_compile _ VERTEXLIGHT_ON
			#define POI_PASS_BASE
			
			// UNITY Includes
			#include "UnityCG.cginc"
			#include "UnityStandardUtils.cginc"
			#include "AutoLight.cginc"
			#include "UnityLightingCommon.cginc"
			#include "UnityPBSLighting.cginc"
			#ifdef POI_PASS_META
			#include "UnityMetaPass.cginc"
			#endif
			#pragma vertex vert
			
			#pragma fragment frag
			
			#define DielectricSpec float4(0.04, 0.04, 0.04, 1.0 - 0.04)
			#define PI float(3.14159265359)
			#define Epsilon float(1e-10)
			
			#define POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, samplertex, coord, dx, dy) tex.SampleGrad(sampler##samplertex, coord, dx, dy)
			#define POI2D_SAMPLE_TEX2D_SAMPLERGRADD(tex, samp, uv, pan, dx, dy) tex.SampleGrad(samp, POI_PAN_UV(uv, pan), dx, dy)
			
			#define POI_PAN_UV(uv, pan) (uv + _Time.x * pan)
			#define POI2D_SAMPLER_PAN(tex, texSampler, uv, pan) (UNITY_SAMPLE_TEX2D_SAMPLER(tex, texSampler, POI_PAN_UV(uv, pan)))
			#define POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy) (POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, texSampler, POI_PAN_UV(uv, pan), dx, dy))
			#define POI2D_SAMPLER(tex, texSampler, uv) (UNITY_SAMPLE_TEX2D_SAMPLER(tex, texSampler, uv))
			#define POI_SAMPLE_1D_X(tex, samp, uv) tex.Sample(samp, float2(uv, 0.5))
			#define POI2D_SAMPLER_GRAD(tex, texSampler, uv, dx, dy) (POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, texSampler, uv, dx, dy))
			#define POI2D_SAMPLER_GRADD(tex, texSampler, uv, dx, dy) tex.SampleGrad(texSampler, uv, dx, dy)
			#define POI2D_PAN(tex, uv, pan) (tex2D(tex, POI_PAN_UV(uv, pan)))
			#define POI2D(tex, uv) (tex2D(tex, uv))
			#define POI_SAMPLE_TEX2D(tex, uv) (UNITY_SAMPLE_TEX2D(tex, uv))
			#define POI_SAMPLE_TEX2D_PAN(tex, uv, pan) (UNITY_SAMPLE_TEX2D(tex, POI_PAN_UV(uv, pan)))
			#define POI_SAMPLE_CUBE_LOD(tex, samp, uv, lod) texCUBElod(tex, float4(uv, 0, lod))
			
			#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
			#define POI_SAMPLE_SCREEN(tex, samp, uv)          tex.Sample(samp, float3(uv, unity_StereoEyeIndex))
			#else
			#define POI_SAMPLE_SCREEN(tex, samp, uv)          tex.Sample(samp, uv)
			#endif
			
			// When using, properties won't properly lock at optimize time; needs macro evaluation implemented
			// #define POI2D_MAINTEX_SAMPLER_PAN_INLINED(tex, poiMesh) (POI2D_SAMPLER_PAN(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan))
			
			#define POI_SAFE_RGB0 float4(mainTexture.rgb * .0001, 0)
			#define POI_SAFE_RGB1 float4(mainTexture.rgb * .0001, 1)
			#define POI_SAFE_RGBA mainTexture
			
			#if defined(UNITY_COMPILER_HLSL)
			#define PoiInitStruct(type, name) name = (type)0;
			#else
			#define PoiInitStruct(type, name)
			#endif
			
			#define POI_ERROR(poiMesh, gridSize) lerp(float3(1, 0, 1), float3(0, 0, 0), fmod(floor((poiMesh.worldPos.x) * gridSize) + floor((poiMesh.worldPos.y) * gridSize) + floor((poiMesh.worldPos.z) * gridSize), 2) == 0)
			#define POI_NAN (asfloat(-1))
			
			#define POI_MODE_OPAQUE 0
			#define POI_MODE_CUTOUT 1
			#define POI_MODE_FADE 2
			#define POI_MODE_TRANSPARENT 3
			#define POI_MODE_ADDITIVE 4
			#define POI_MODE_SOFTADDITIVE 5
			#define POI_MODE_MULTIPLICATIVE 6
			#define POI_MODE_2XMULTIPLICATIVE 7
			#define POI_MODE_TRANSCLIPPING 9
			
			/*
			Texture2D ;
			float4 _ST;
			float2 Pan;
			float UV;
			float Stochastic;
			
			[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos XZ, 5, Polar UV, 6, Distorted UV, 7 )]
			*/
			
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			// Map of where features in AudioLink are.
			#define ALPASS_DFT                      uint2(0, 4)   //Size: 128, 2
			#define ALPASS_WAVEFORM                 uint2(0, 6)   //Size: 128, 16
			#define ALPASS_AUDIOLINK                uint2(0, 0)   //Size: 128, 4
			#define ALPASS_AUDIOBASS                uint2(0, 0)   //Size: 128, 1
			#define ALPASS_AUDIOLOWMIDS             uint2(0, 1)   //Size: 128, 1
			#define ALPASS_AUDIOHIGHMIDS            uint2(0, 2)   //Size: 128, 1
			#define ALPASS_AUDIOTREBLE              uint2(0, 3)   //Size: 128, 1
			#define ALPASS_AUDIOLINKHISTORY         uint2(1, 0)   //Size: 127, 4
			#define ALPASS_GENERALVU                uint2(0, 22)  //Size: 12, 1
			#define ALPASS_CCINTERNAL               uint2(12, 22) //Size: 12, 2
			#define ALPASS_CCCOLORS                 uint2(25, 22) //Size: 11, 1
			#define ALPASS_CCSTRIP                  uint2(0, 24)  //Size: 128, 1
			#define ALPASS_CCLIGHTS                 uint2(0, 25)  //Size: 128, 2
			#define ALPASS_AUTOCORRELATOR           uint2(0, 27)  //Size: 128, 1
			#define ALPASS_GENERALVU_INSTANCE_TIME  uint2(2, 22)
			#define ALPASS_GENERALVU_LOCAL_TIME     uint2(3, 22)
			#define ALPASS_GENERALVU_NETWORK_TIME   uint2(4, 22)
			#define ALPASS_GENERALVU_PLAYERINFO     uint2(6, 22)
			// Added in version 2.5
			#define ALPASS_FILTEREDAUDIOLINK        uint2(0, 28)  //Size: 16, 4
			// Added in version 2.6
			#define ALPASS_CHRONOTENSITY            uint2(16, 28) //Size: 8, 4
			#define ALPASS_THEME_COLOR0             uint2(0, 23)
			#define ALPASS_THEME_COLOR1             uint2(1, 23)
			#define ALPASS_THEME_COLOR2             uint2(2, 23)
			#define ALPASS_THEME_COLOR3             uint2(3, 23)
			#define ALPASS_FILTEREDVU               uint2(24, 28) //Size: 4, 4
			#define ALPASS_FILTEREDVU_INTENSITY     uint2(24, 28) //Size: 4, 1
			#define ALPASS_FILTEREDVU_MARKER        uint2(24, 29) //Size: 4, 1
			
			// Some basic constants to use (Note, these should be compatible with
			// future version of AudioLink, but may change.
			#define AUDIOLINK_SAMPHIST              3069        // Internal use for algos, do not change.
			#define AUDIOLINK_SAMPLEDATA24          2046
			#define AUDIOLINK_EXPBINS               24
			#define AUDIOLINK_EXPOCT                10
			#define AUDIOLINK_ETOTALBINS (AUDIOLINK_EXPBINS * AUDIOLINK_EXPOCT)
			#define AUDIOLINK_WIDTH                 128
			#define AUDIOLINK_SPS                   48000       // Samples per second
			#define AUDIOLINK_ROOTNOTE              0
			#define AUDIOLINK_4BAND_FREQFLOOR       0.123
			#define AUDIOLINK_4BAND_FREQCEILING     1
			#define AUDIOLINK_BOTTOM_FREQUENCY      13.75
			#define AUDIOLINK_BASE_AMPLITUDE        2.5
			#define AUDIOLINK_DELAY_COEFFICIENT_MIN 0.3
			#define AUDIOLINK_DELAY_COEFFICIENT_MAX 0.9
			#define AUDIOLINK_DFT_Q                 4.0
			#define AUDIOLINK_TREBLE_CORRECTION     5.0
			
			// ColorChord constants
			#define COLORCHORD_EMAXBIN              192
			#define COLORCHORD_IIR_DECAY_1          0.90
			#define COLORCHORD_IIR_DECAY_2          0.85
			#define COLORCHORD_CONSTANT_DECAY_1     0.01
			#define COLORCHORD_CONSTANT_DECAY_2     0.0
			#define COLORCHORD_NOTE_CLOSEST         3.0
			#define COLORCHORD_NEW_NOTE_GAIN        8.0
			#define COLORCHORD_MAX_NOTES            10
			
			uniform float4               _AudioTexture_TexelSize;
			
			#ifdef SHADER_TARGET_SURFACE_ANALYSIS
			#define AUDIOLINK_STANDARD_INDEXING
			#endif
			
			// Mechanism to index into texture.
			#ifdef AUDIOLINK_STANDARD_INDEXING
			sampler2D _AudioTexture;
			#define AudioLinkData(xycoord) tex2Dlod(_AudioTexture, float4(uint2(xycoord) * _AudioTexture_TexelSize.xy, 0, 0))
			#else
			uniform Texture2D<float4> _AudioTexture;
			SamplerState sampler_AudioTexture;
			#define AudioLinkData(xycoord) _AudioTexture[uint2(xycoord)]
			#endif
			uniform sampler2D _Stored;
			uniform float4 _Stored_TexelSize;
			#endif
			//endex
			
			float _GrabMode;
			float _Mode;
			
			float _StochasticDeliotHeitzDensity;
			float _StochasticHexGridDensity;
			float _StochasticHexRotationStrength;
			float _StochasticHexFallOffContrast;
			float _StochasticHexFallOffPower;
			
			#if defined(PROP_LIGHTINGAOMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _LightingAOMaps;
			#endif
			float4 _LightingAOMaps_ST;
			float2 _LightingAOMapsPan;
			float _LightingAOMapsUV;
			float _LightDataAOStrengthR;
			float _LightDataAOStrengthG;
			float _LightDataAOStrengthB;
			float _LightDataAOStrengthA;
			float _LightDataAOGlobalMaskR;
			float _LightDataAOGlobalMaskBlendTypeR;
			
			#if defined(PROP_LIGHTINGDETAILSHADOWMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _LightingDetailShadowMaps;
			#endif
			float4 _LightingDetailShadowMaps_ST;
			float2 _LightingDetailShadowMapsPan;
			float _LightingDetailShadowMapsUV;
			float _LightingDetailShadowStrengthR;
			float _LightingDetailShadowStrengthG;
			float _LightingDetailShadowStrengthB;
			float _LightingDetailShadowStrengthA;
			float _LightingAddDetailShadowStrengthR;
			float _LightingAddDetailShadowStrengthG;
			float _LightingAddDetailShadowStrengthB;
			float _LightingAddDetailShadowStrengthA;
			float _LightDataDetailShadowGlobalMaskR;
			float _LightDataDetailShadowGlobalMaskBlendTypeR;
			
			#if defined(PROP_LIGHTINGSHADOWMASKS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _LightingShadowMasks;
			#endif
			float4 _LightingShadowMasks_ST;
			float2 _LightingShadowMasksPan;
			float _LightingShadowMasksUV;
			float _LightingShadowMaskStrengthR;
			float _LightingShadowMaskStrengthG;
			float _LightingShadowMaskStrengthB;
			float _LightingShadowMaskStrengthA;
			float _LightDataShadowMaskGlobalMaskR;
			float _LightDataShadowMaskGlobalMaskBlendTypeR;
			
			// Lighting Data
			float _Unlit_Intensity;
			float _LightingColorMode;
			float _LightingMapMode;
			float _LightingDirectionMode;
			float3 _LightngForcedDirection;
			float _LightingViewDirOffsetPitch;
			float _LightingViewDirOffsetYaw;
			float _LightingIndirectUsesNormals;
			float _LightingCapEnabled;
			float _LightingCap;
			float _LightingForceColorEnabled;
			float3 _LightingForcedColor;
			float _LightingForcedColorThemeIndex;
			float _LightingCastedShadows;
			float _LightingMonochromatic;
			float _LightingMinLightBrightness;
			// Additive Lighting Data
			float _LightingAdditiveEnable;
			float _LightingAdditiveLimited;
			float _LightingAdditiveLimit;
			float _LightingAdditiveCastedShadows;
			float _LightingAdditiveMonochromatic;
			float _LightingAdditivePassthrough;
			float _DisableDirectionalInAdd;
			float _LightingVertexLightingEnabled;
			float _LightingMirrorVertexLightingEnabled;
			// Lighting Data Debug
			float _LightDataDebugEnabled;
			float _LightingDebugVisualize;
			
			float _IgnoreFog;
			float _RenderingReduceClipDistance;
			int _FlipBackfaceNormals;
			float _AddBlendOp;
			float _Cull;
			
			float4 _Color;
			float _ColorThemeIndex;
			UNITY_DECLARE_TEX2D(_MainTex);
			UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
			float _MainPixelMode;
			float4 _MainTex_ST;
			float2 _MainTexPan;
			float _MainTexUV;
			float4 _MainTex_TexelSize;
			float _MainTexStochastic;
			#if defined(PROP_BUMPMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BumpMap;
			#endif
			float4 _BumpMap_ST;
			float2 _BumpMapPan;
			float _BumpMapUV;
			float _BumpScale;
			float _BumpMapStochastic;
			#if defined(PROP_ALPHAMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AlphaMask;
			float4 _AlphaMask_ST;
			float2 _AlphaMaskPan;
			float _AlphaMaskUV;
			float _AlphaMaskInvert;
			float _MainAlphaMaskMode;
			float _AlphaMaskScale;
			float _AlphaMaskValue;
			#endif
			float _Cutoff;
			//ifex _MainColorAdjustToggle==0
			#ifdef COLOR_GRADING_HDR
			float _MainColorAdjustToggle;
			#if defined(PROP_MAINCOLORADJUSTTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MainColorAdjustTexture;
			#endif
			float4 _MainColorAdjustTexture_ST;
			float2 _MainColorAdjustTexturePan;
			float _MainColorAdjustTextureUV;
			float _MainHueShiftToggle;
			float _MainHueShiftReplace;
			float _MainHueShift;
			float _MainHueShiftSpeed;
			float _Saturation;
			float _MainBrightness;
			
			float _MainHueALCTEnabled;
			float _MainALHueShiftBand;
			float _MainALHueShiftCTIndex;
			float _MainHueALMotionSpeed;
			
			float _MainHueGlobalMask;
			float _MainHueGlobalMaskBlendType;
			float _MainSaturationGlobalMask;
			float _MainSaturationGlobalMaskBlendType;
			float _MainBrightnessGlobalMask;
			float _MainBrightnessGlobalMaskBlendType;
			
			#if defined(PROP_MAINGRADATIONTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MainGradationTex;
			#endif
			float _ColorGradingToggle;
			float _MainGradationStrength;
			#endif
			//endex
			
			SamplerState sampler_linear_clamp;
			SamplerState sampler_linear_repeat;
			SamplerState sampler_trilinear_repeat;
			
			float _AlphaForceOpaque;
			float _AlphaMod;
			float _AlphaPremultiply;
			float _AlphaBoostFA;
			//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
			float _AlphaToCoverage;
			float _AlphaSharpenedA2C;
			float _AlphaMipScale;
			//endex
			
			//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
			float _AlphaDithering;
			float _AlphaDitherGradient;
			float _AlphaDitherBias;
			//endex
			
			//ifex _AlphaDistanceFade==0 && isNotAnimated(_AlphaDistanceFade)
			float _AlphaDistanceFade;
			float _AlphaDistanceFadeType;
			float _AlphaDistanceFadeMinAlpha;
			float _AlphaDistanceFadeMaxAlpha;
			float _AlphaDistanceFadeMin;
			float _AlphaDistanceFadeMax;
			float _AlphaDistanceFadeGlobalMask;
			float _AlphaDistanceFadeGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaFresnel==0 && isNotAnimated(_AlphaFresnel)
			float _AlphaFresnel;
			float _AlphaFresnelAlpha;
			float _AlphaFresnelSharpness;
			float _AlphaFresnelWidth;
			float _AlphaFresnelInvert;
			float _AlphaFresnelGlobalMask;
			float _AlphaFresnelGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaAngular==0 && isNotAnimated(_AlphaAngular)
			float _AlphaAngular;
			float _AngleType;
			float _AngleCompareTo;
			float3 _AngleForwardDirection;
			float _CameraAngleMin;
			float _CameraAngleMax;
			float _ModelAngleMin;
			float _ModelAngleMax;
			float _AngleMinAlpha;
			float _AlphaAngularGlobalMask;
			float _AlphaAngularGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaAudioLinkEnabled==0 && isNotAnimated(_AlphaAudioLinkEnabled)
			float _AlphaAudioLinkEnabled;
			float2 _AlphaAudioLinkAddRange;
			float _AlphaAudioLinkAddBand;
			//endex
			
			float _AlphaGlobalMask;
			float _AlphaGlobalMaskBlendType;
			
			float4 _GlobalThemeColor0;
			float4 _GlobalThemeColor1;
			float4 _GlobalThemeColor2;
			float4 _GlobalThemeColor3;
			float _GlobalThemeHue0;
			float _GlobalThemeHue1;
			float _GlobalThemeHue2;
			float _GlobalThemeHue3;
			float _GlobalThemeHueSpeed0;
			float _GlobalThemeHueSpeed1;
			float _GlobalThemeHueSpeed2;
			float _GlobalThemeHueSpeed3;
			float _GlobalThemeSaturation0;
			float _GlobalThemeSaturation1;
			float _GlobalThemeSaturation2;
			float _GlobalThemeSaturation3;
			float _GlobalThemeValue0;
			float _GlobalThemeValue1;
			float _GlobalThemeValue2;
			float _GlobalThemeValue3;
			
			//ifex _GlobalMaskTexturesEnable==0
			#ifdef POI_GLOBALMASK_TEXTURES
			#if defined(PROP_GLOBALMASKTEXTURE0) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture0;
			#endif
			float4 _GlobalMaskTexture0_ST;
			float2 _GlobalMaskTexture0Pan;
			float _GlobalMaskTexture0UV;
			int _GlobalMaskTexture0Split;
			float4 _GlobalMaskTexture0SplitTilingOffset_G;
			float4 _GlobalMaskTexture0SplitPan_G;
			float4 _GlobalMaskTexture0SplitTilingOffset_B;
			float4 _GlobalMaskTexture0SplitPan_B;
			float4 _GlobalMaskTexture0SplitTilingOffset_A;
			float4 _GlobalMaskTexture0SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture1;
			#endif
			float4 _GlobalMaskTexture1_ST;
			float2 _GlobalMaskTexture1Pan;
			float _GlobalMaskTexture1UV;
			int _GlobalMaskTexture1Split;
			float4 _GlobalMaskTexture1SplitTilingOffset_G;
			float4 _GlobalMaskTexture1SplitPan_G;
			float4 _GlobalMaskTexture1SplitTilingOffset_B;
			float4 _GlobalMaskTexture1SplitPan_B;
			float4 _GlobalMaskTexture1SplitTilingOffset_A;
			float4 _GlobalMaskTexture1SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture2;
			#endif
			float4 _GlobalMaskTexture2_ST;
			float2 _GlobalMaskTexture2Pan;
			float _GlobalMaskTexture2UV;
			int _GlobalMaskTexture2Split;
			float4 _GlobalMaskTexture2SplitTilingOffset_G;
			float4 _GlobalMaskTexture2SplitPan_G;
			float4 _GlobalMaskTexture2SplitTilingOffset_B;
			float4 _GlobalMaskTexture2SplitPan_B;
			float4 _GlobalMaskTexture2SplitTilingOffset_A;
			float4 _GlobalMaskTexture2SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE3) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture3;
			#endif
			float4 _GlobalMaskTexture3_ST;
			float2 _GlobalMaskTexture3Pan;
			float _GlobalMaskTexture3UV;
			int _GlobalMaskTexture3Split;
			float4 _GlobalMaskTexture3SplitTilingOffset_G;
			float4 _GlobalMaskTexture3SplitPan_G;
			float4 _GlobalMaskTexture3SplitTilingOffset_B;
			float4 _GlobalMaskTexture3SplitPan_B;
			float4 _GlobalMaskTexture3SplitTilingOffset_A;
			float4 _GlobalMaskTexture3SplitPan_A;
			#endif
			//endex
			//ifex _GlobalMaskOptionsEnable==0
			float _GlobalMaskOptionsEnable;
			int _GlobalMaskOptionsType;
			
			//ifex _GlobalMaskOptionsType!=0
			float _GlobalMaskSlider_0;
			float _GlobalMaskSlider_1;
			float _GlobalMaskSlider_2;
			float _GlobalMaskSlider_3;
			float _GlobalMaskSlider_4;
			float _GlobalMaskSlider_5;
			float _GlobalMaskSlider_6;
			float _GlobalMaskSlider_7;
			float _GlobalMaskSlider_8;
			float _GlobalMaskSlider_9;
			float _GlobalMaskSlider_10;
			float _GlobalMaskSlider_11;
			float _GlobalMaskSlider_12;
			float _GlobalMaskSlider_13;
			float _GlobalMaskSlider_14;
			float _GlobalMaskSlider_15;
			//endex
			
			//ifex _GlobalMaskOptionsType!=1
			float2 _GlobalMaskMinMaxSlider_0;
			float2 _GlobalMaskMinMaxSlider_1;
			float2 _GlobalMaskMinMaxSlider_2;
			float2 _GlobalMaskMinMaxSlider_3;
			float2 _GlobalMaskMinMaxSlider_4;
			float2 _GlobalMaskMinMaxSlider_5;
			float2 _GlobalMaskMinMaxSlider_6;
			float2 _GlobalMaskMinMaxSlider_7;
			float2 _GlobalMaskMinMaxSlider_8;
			float2 _GlobalMaskMinMaxSlider_9;
			float2 _GlobalMaskMinMaxSlider_10;
			float2 _GlobalMaskMinMaxSlider_11;
			float2 _GlobalMaskMinMaxSlider_12;
			float2 _GlobalMaskMinMaxSlider_13;
			float2 _GlobalMaskMinMaxSlider_14;
			float2 _GlobalMaskMinMaxSlider_15;
			//endex
			
			//ifex _GlobalMaskOptionsType!=2
			int _GlobalMaskToggleOn_0;
			int _GlobalMaskToggleOff_0;
			int _GlobalMaskToggleOn_1;
			int _GlobalMaskToggleOff_1;
			int _GlobalMaskToggleOn_2;
			int _GlobalMaskToggleOff_2;
			int _GlobalMaskToggleOn_3;
			int _GlobalMaskToggleOff_3;
			int _GlobalMaskToggleOn_4;
			int _GlobalMaskToggleOff_4;
			int _GlobalMaskToggleOn_5;
			int _GlobalMaskToggleOff_5;
			int _GlobalMaskToggleOn_6;
			int _GlobalMaskToggleOff_6;
			int _GlobalMaskToggleOn_7;
			int _GlobalMaskToggleOff_7;
			int _GlobalMaskToggleOn_8;
			int _GlobalMaskToggleOff_8;
			int _GlobalMaskToggleOn_9;
			int _GlobalMaskToggleOff_9;
			int _GlobalMaskToggleOn_10;
			int _GlobalMaskToggleOff_10;
			int _GlobalMaskToggleOn_11;
			int _GlobalMaskToggleOff_11;
			int _GlobalMaskToggleOn_12;
			int _GlobalMaskToggleOff_12;
			int _GlobalMaskToggleOn_13;
			int _GlobalMaskToggleOff_13;
			int _GlobalMaskToggleOn_14;
			int _GlobalMaskToggleOff_14;
			int _GlobalMaskToggleOn_15;
			int _GlobalMaskToggleOff_15;
			//endex
			//endex
			//ifex _GlobalMaskModifiersBackfaceEnable==0
			float _GlobalMaskModifiersBackfaceEnable;
			float _GlobalMaskBackface_0;
			float _GlobalMaskBackface_1;
			float _GlobalMaskBackface_2;
			float _GlobalMaskBackface_3;
			float _GlobalMaskBackface_4;
			float _GlobalMaskBackface_5;
			float _GlobalMaskBackface_6;
			float _GlobalMaskBackface_7;
			float _GlobalMaskBackface_8;
			float _GlobalMaskBackface_9;
			float _GlobalMaskBackface_10;
			float _GlobalMaskBackface_11;
			float _GlobalMaskBackface_12;
			float _GlobalMaskBackface_13;
			float _GlobalMaskBackface_14;
			float _GlobalMaskBackface_15;
			//endex
			
			//ifex _GlobalMaskModifiersMirrorEnable==0
			float _GlobalMaskModifiersMirrorEnable;
			float _GlobalMaskMirrorVisibilityMode;
			float _GlobalMaskMirror_0;
			float _GlobalMaskMirror_1;
			float _GlobalMaskMirror_2;
			float _GlobalMaskMirror_3;
			float _GlobalMaskMirror_4;
			float _GlobalMaskMirror_5;
			float _GlobalMaskMirror_6;
			float _GlobalMaskMirror_7;
			float _GlobalMaskMirror_8;
			float _GlobalMaskMirror_9;
			float _GlobalMaskMirror_10;
			float _GlobalMaskMirror_11;
			float _GlobalMaskMirror_12;
			float _GlobalMaskMirror_13;
			float _GlobalMaskMirror_14;
			float _GlobalMaskMirror_15;
			//endex
			
			//ifex _GlobalMaskModifiersCameraEnable==0
			float _GlobalMaskModifiersCameraEnable;
			float _GlobalMaskCamera_0;
			float _GlobalMaskCamera_1;
			float _GlobalMaskCamera_2;
			float _GlobalMaskCamera_3;
			float _GlobalMaskCamera_4;
			float _GlobalMaskCamera_5;
			float _GlobalMaskCamera_6;
			float _GlobalMaskCamera_7;
			float _GlobalMaskCamera_8;
			float _GlobalMaskCamera_9;
			float _GlobalMaskCamera_10;
			float _GlobalMaskCamera_11;
			float _GlobalMaskCamera_12;
			float _GlobalMaskCamera_13;
			float _GlobalMaskCamera_14;
			float _GlobalMaskCamera_15;
			//endex
			
			//ifex _GlobalMaskModifiersDistanceEnable==0
			int _GlobalMaskModifiersDistanceEnable;
			
			//ifex _GlobalMaskDistanceEnable_0==0
			int _GlobalMaskDistanceEnable_0;
			int _GlobalMaskDistanceType_0;
			float _GlobalMaskDistanceMin_0;
			float _GlobalMaskDistanceMax_0;
			float _GlobalMaskDistanceMinAlpha_0;
			float _GlobalMaskDistanceMaxAlpha_0;
			int _GlobalMaskDistanceBlendType_0;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_1==0
			int _GlobalMaskDistanceEnable_1;
			int _GlobalMaskDistanceType_1;
			float _GlobalMaskDistanceMin_1;
			float _GlobalMaskDistanceMax_1;
			float _GlobalMaskDistanceMinAlpha_1;
			float _GlobalMaskDistanceMaxAlpha_1;
			int _GlobalMaskDistanceBlendType_1;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_2==0
			int _GlobalMaskDistanceEnable_2;
			int _GlobalMaskDistanceType_2;
			float _GlobalMaskDistanceMin_2;
			float _GlobalMaskDistanceMax_2;
			float _GlobalMaskDistanceMinAlpha_2;
			float _GlobalMaskDistanceMaxAlpha_2;
			int _GlobalMaskDistanceBlendType_2;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_3==0
			int _GlobalMaskDistanceEnable_3;
			int _GlobalMaskDistanceType_3;
			float _GlobalMaskDistanceMin_3;
			float _GlobalMaskDistanceMax_3;
			float _GlobalMaskDistanceMinAlpha_3;
			float _GlobalMaskDistanceMaxAlpha_3;
			int _GlobalMaskDistanceBlendType_3;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_4==0
			int _GlobalMaskDistanceEnable_4;
			int _GlobalMaskDistanceType_4;
			float _GlobalMaskDistanceMin_4;
			float _GlobalMaskDistanceMax_4;
			float _GlobalMaskDistanceMinAlpha_4;
			float _GlobalMaskDistanceMaxAlpha_4;
			int _GlobalMaskDistanceBlendType_4;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_5==0
			int _GlobalMaskDistanceEnable_5;
			int _GlobalMaskDistanceType_5;
			float _GlobalMaskDistanceMin_5;
			float _GlobalMaskDistanceMax_5;
			float _GlobalMaskDistanceMinAlpha_5;
			float _GlobalMaskDistanceMaxAlpha_5;
			int _GlobalMaskDistanceBlendType_5;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_6==0
			int _GlobalMaskDistanceEnable_6;
			int _GlobalMaskDistanceType_6;
			float _GlobalMaskDistanceMin_6;
			float _GlobalMaskDistanceMax_6;
			float _GlobalMaskDistanceMinAlpha_6;
			float _GlobalMaskDistanceMaxAlpha_6;
			int _GlobalMaskDistanceBlendType_6;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_7==0
			int _GlobalMaskDistanceEnable_7;
			int _GlobalMaskDistanceType_7;
			float _GlobalMaskDistanceMin_7;
			float _GlobalMaskDistanceMax_7;
			float _GlobalMaskDistanceMinAlpha_7;
			float _GlobalMaskDistanceMaxAlpha_7;
			int _GlobalMaskDistanceBlendType_7;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_8==0
			int _GlobalMaskDistanceEnable_8;
			int _GlobalMaskDistanceType_8;
			float _GlobalMaskDistanceMin_8;
			float _GlobalMaskDistanceMax_8;
			float _GlobalMaskDistanceMinAlpha_8;
			float _GlobalMaskDistanceMaxAlpha_8;
			int _GlobalMaskDistanceBlendType_8;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_9==0
			int _GlobalMaskDistanceEnable_9;
			int _GlobalMaskDistanceType_9;
			float _GlobalMaskDistanceMin_9;
			float _GlobalMaskDistanceMax_9;
			float _GlobalMaskDistanceMinAlpha_9;
			float _GlobalMaskDistanceMaxAlpha_9;
			int _GlobalMaskDistanceBlendType_9;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_10==0
			int _GlobalMaskDistanceEnable_10;
			int _GlobalMaskDistanceType_10;
			float _GlobalMaskDistanceMin_10;
			float _GlobalMaskDistanceMax_10;
			float _GlobalMaskDistanceMinAlpha_10;
			float _GlobalMaskDistanceMaxAlpha_10;
			int _GlobalMaskDistanceBlendType_10;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_11==0
			int _GlobalMaskDistanceEnable_11;
			int _GlobalMaskDistanceType_11;
			float _GlobalMaskDistanceMin_11;
			float _GlobalMaskDistanceMax_11;
			float _GlobalMaskDistanceMinAlpha_11;
			float _GlobalMaskDistanceMaxAlpha_11;
			int _GlobalMaskDistanceBlendType_11;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_12==0
			int _GlobalMaskDistanceEnable_12;
			int _GlobalMaskDistanceType_12;
			float _GlobalMaskDistanceMin_12;
			float _GlobalMaskDistanceMax_12;
			float _GlobalMaskDistanceMinAlpha_12;
			float _GlobalMaskDistanceMaxAlpha_12;
			int _GlobalMaskDistanceBlendType_12;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_13==0
			int _GlobalMaskDistanceEnable_13;
			int _GlobalMaskDistanceType_13;
			float _GlobalMaskDistanceMin_13;
			float _GlobalMaskDistanceMax_13;
			float _GlobalMaskDistanceMinAlpha_13;
			float _GlobalMaskDistanceMaxAlpha_13;
			int _GlobalMaskDistanceBlendType_13;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_14==0
			int _GlobalMaskDistanceEnable_14;
			int _GlobalMaskDistanceType_14;
			float _GlobalMaskDistanceMin_14;
			float _GlobalMaskDistanceMax_14;
			float _GlobalMaskDistanceMinAlpha_14;
			float _GlobalMaskDistanceMaxAlpha_14;
			int _GlobalMaskDistanceBlendType_14;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_15==0
			int _GlobalMaskDistanceEnable_15;
			int _GlobalMaskDistanceType_15;
			float _GlobalMaskDistanceMin_15;
			float _GlobalMaskDistanceMax_15;
			float _GlobalMaskDistanceMinAlpha_15;
			float _GlobalMaskDistanceMaxAlpha_15;
			int _GlobalMaskDistanceBlendType_15;
			//endex
			//endex
			
			int _GlobalMaskVertexColorLinearSpace;
			//ifex _GlobalMaskVertexColorRed==0
			int _GlobalMaskVertexColorRed;
			int _GlobalMaskVertexColorRedBlendType;
			//endex
			//ifex _GlobalMaskVertexColorGreen==0
			int _GlobalMaskVertexColorGreen;
			int _GlobalMaskVertexColorGreenBlendType;
			//endex
			//ifex _GlobalMaskVertexColorBlue==0
			int _GlobalMaskVertexColorBlue;
			int _GlobalMaskVertexColorBlueBlendType;
			//endex
			//ifex _GlobalMaskVertexColorAlpha==0
			int _GlobalMaskVertexColorAlpha;
			int _GlobalMaskVertexColorAlphaBlendType;
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#ifdef POI_UDIMDISCARD
			float _UDIMDiscardMode;
			float _UDIMDiscardUV;
			float _UDIMDiscardRow3_0;
			float _UDIMDiscardRow3_1;
			float _UDIMDiscardRow3_2;
			float _UDIMDiscardRow3_3;
			float _UDIMDiscardRow2_0;
			float _UDIMDiscardRow2_1;
			float _UDIMDiscardRow2_2;
			float _UDIMDiscardRow2_3;
			float _UDIMDiscardRow1_0;
			float _UDIMDiscardRow1_1;
			float _UDIMDiscardRow1_2;
			float _UDIMDiscardRow1_3;
			float _UDIMDiscardRow0_0;
			float _UDIMDiscardRow0_1;
			float _UDIMDiscardRow0_2;
			float _UDIMDiscardRow0_3;
			#endif
			//endex
			
			//ifex _EnableDistortion==0
			#ifdef USER_LUT
			#if defined(PROP_DISTORTIONFLOWTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionFlowTexture;
			float4 _DistortionFlowTexture_ST;
			float2 _DistortionFlowTexturePan;
			float _DistortionFlowTextureUV;
			#endif
			
			#if defined(PROP_DISTORTIONFLOWTEXTURE1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionFlowTexture1;
			float4 _DistortionFlowTexture1_ST;
			float2 _DistortionFlowTexture1Pan;
			float _DistortionFlowTexture1UV;
			#endif
			
			#if defined(PROP_DISTORTIONMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionMask;
			float4 _DistortionMask_ST;
			float2 _DistortionMaskPan;
			float _DistortionMaskUV;
			float _DistortionMaskChannel;
			#endif
			
			float _DistortionUvToDistort;
			float _DistortionStrength;
			float _DistortionStrength1;
			
			#ifdef POI_AUDIOLINK
			half _EnableDistortionAudioLink;
			half2 _DistortionStrengthAudioLink;
			half _DistortionStrengthAudioLinkBand;
			half2 _DistortionStrength1AudioLink;
			half _DistortionStrength1AudioLinkBand;
			#endif
			#endif
			//endex
			float _StereoEnabled;
			float _PolarUV;
			float2 _PolarCenter;
			float _PolarRadialScale;
			float _PolarLengthScale;
			float _PolarSpiralPower;
			float _PanoUseBothEyes;
			
			float _UVModWorldPos0;
			float _UVModWorldPos1;
			float _UVModLocalPos0;
			float _UVModLocalPos1;
			
			//ifex _PoiParallax==0
			#ifdef POI_PARALLAX
			
			sampler2D _HeightMap;
			float4 _HeightMap_ST;
			float2 _HeightMapPan;
			float _HeightMapUV;
			
			#if defined(PROP_HEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Heightmask;
			float4 _Heightmask_ST;
			float2 _HeightmaskPan;
			float _HeightmaskUV;
			float _HeightmaskChannel;
			float _HeightmaskInvert;
			SamplerState _linear_repeat;
			#endif
			
			float _ParallaxUV;
			float _HeightStrength;
			float _HeightOffset;
			float _HeightStepsMin;
			float _HeightStepsMax;
			
			float _CurvatureU;
			float _CurvatureV;
			float _CurvFix;
			#endif
			//endex
			
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			float _AudioLinkDelay;
			float _AudioLinkAnimToggle;
			
			float _AudioLinkSmoothingBass;
			float _AudioLinkSmoothingLowMid;
			float _AudioLinkSmoothingHighMid;
			float _AudioLinkSmoothingTreble;
			
			float _DebugWaveform;
			float _DebugDFT;
			float _DebugBass;
			float _DebugLowMids;
			float _DebugHighMids;
			float _DebugTreble;
			float _DebugCCColors;
			float _DebugCCStrip;
			float _DebugCCLights;
			float _DebugAutocorrelator;
			float _DebugChronotensity;
			float _AudioLinkCCStripY;
			
			float _AudioLinkBandOverridesEnabled;
			float4 _AudioLinkBandOverrideSliders;
			#endif
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#ifdef POI_BLACKLIGHTMASKING
			float _BlackLightMasking0Key;
			float2 _BlackLightMasking0Range;
			float _BlackLightMasking0GlobalMaskIndex;
			float _BlackLightMasking0GlobalMaskBlendType;
			
			float _BlackLightMasking1Key;
			float2 _BlackLightMasking1Range;
			float _BlackLightMasking1GlobalMaskIndex;
			float _BlackLightMasking1GlobalMaskBlendType;
			
			float _BlackLightMasking2Key;
			float2 _BlackLightMasking2Range;
			float _BlackLightMasking2GlobalMaskIndex;
			float _BlackLightMasking2GlobalMaskBlendType;
			
			float _BlackLightMasking3Key;
			float2 _BlackLightMasking3Range;
			float _BlackLightMasking3GlobalMaskIndex;
			float _BlackLightMasking3GlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _DetailEnabled==0
			#ifdef FINALPASS
			#if defined(PROP_DETAILMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DetailMask;
			#endif
			float4 _DetailMask_ST;
			float2 _DetailMaskPan;
			float _DetailMaskUV;
			float _DetailMaskStochastic;
			
			#if defined(PROP_DETAILNORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DetailNormalMap;
			#endif
			float4 _DetailNormalMap_ST;
			float2 _DetailNormalMapPan;
			float _DetailNormalMapUV;
			float _DetailNormalMapScale;
			float _DetailNormalMapStochastic;
			float _DetailNormalGlobalMask;
			float _DetailNormalGlobalMaskBlendType;
			
			#if defined(PROP_DETAILTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DetailTex;
			#endif
			float4 _DetailTex_ST;
			float2 _DetailTexPan;
			float _DetailTexUV;
			float _DetailTexStochastic;
			
			float3 _DetailTint;
			float _DetailTintThemeIndex;
			float _DetailTexIntensity;
			float _DetailBrightness;
			float _DetailTexGlobalMask;
			float _DetailTexGlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _VertexManipulationsEnabled==0
			#ifdef AUTO_EXPOSURE
			float4 _VertexManipulationLocalTranslation;
			float4 _VertexManipulationLocalRotation;
			float3 _VertexManipulationLocalRotationSpeed;
			float4 _VertexManipulationLocalScale;
			float4 _VertexManipulationWorldTranslation;
			float _VertexManipulationHeight;
			sampler2D _VertexManipulationHeightMask;
			float4 _VertexManipulationHeightMask_ST;
			float2 _VertexManipulationHeightMaskPan;
			float _VertexManipulationHeightMaskUV;
			float _VertexManipulationHeightMaskChannel;
			float _VertexManipulationHeightBias;
			float _VertexRoundingEnabled;
			int _VertexRoundingSpace;
			float _VertexRoundingDivision;
			
			//AL
			float _VertexAudioLinkEnabled;
			float3 _VertexLocalTranslationALMin;
			float3 _VertexLocalTranslationALMax;
			float _VertexLocalTranslationALBand;
			
			float3 _VertexLocalRotationAL;
			float _VertexLocalRotationALBand;
			
			float3 _VertexLocalRotationCTALSpeed;
			float _VertexLocalRotationCTALBandX;
			float _VertexLocalRotationCTALBandY;
			float _VertexLocalRotationCTALBandZ;
			float _VertexLocalRotationCTALTypeX;
			float _VertexLocalRotationCTALTypeY;
			float _VertexLocalRotationCTALTypeZ;
			
			float4 _VertexLocalScaleALMin;
			float4 _VertexLocalScaleALMax;
			float _VertexLocalScaleALBand;
			
			float3 _VertexWorldTranslationALMin;
			float3 _VertexWorldTranslationALMax;
			float _VertexWorldTranslationALBand;
			
			float2 _VertexManipulationHeightAL;
			float _VertexManipulationHeightBand;
			
			float2 _VertexRoundingRangeAL;
			float _VertexRoundingRangeBand;
			
			float _VertexBarrelMode;
			float _VertexBarrelWidth;
			float _VertexBarrelAlpha;
			float _VertexBarrelHeight;
			
			float _VertexSphereMode;
			float _VertexSphereRadius;
			float _VertexSphereHeight;
			float _VertexSphereAlpha;
			float4 _VertexSphereCenter;
			
			float _VertexTornadoMode;
			float _VertexTornadoRadius;
			float _VertexTornadoSpeed;
			float _VertexTornadoIntensity;
			float _VertexTornadoBaseHeight;
			float _VertexTornadoTopHeight;
			
			float _VertexSpectrumMotion;
			float3 _VertexSpectrumOffsetMin;
			float3 _VertexSpectrumOffsetMax;
			float _VertexSpectrumUV;
			float _VertexSpectrumUVDirection;
			#endif
			//endex
			
			//ifex _VertexGlitchingEnabled==0
			#ifdef POI_VERTEX_GLITCHING
			//Vertex Glitching
			#if defined(POI_VERTEX_GLITCHING_TEXTURE)
			float _VertexGlitchingUseTexture;
			sampler2D _VertexGlitchMap;
			float4 _VertexGlitchMap_ST;
			#endif
			float _VertexGlitchThreshold;
			float _VertexGlitchFrequency;
			float _VertexGlitchStrength;
			float _VertexGlitchDensity;
			
			float _VertexGlitchMirrorEnable;
			float _VertexGlitchMirror;
			
			float _VertexGlitchMapPanSpeed;
			float _VertexGlitchingAudioLinkEnabled;
			float _VertexGlitchingAudioLinkBand;
			float _VertexGlitchingAudiolinkOverride;
			#endif
			//endex
			
			//ifex _EnableDepthBulge==0
			#ifdef POI_DEPTHBULGE
			float _DepthBulgeFadeLength;
			float _DepthBulgeHeight;
			
			#if defined(PROP_DEPTHBULGEMASK) || !defined(OPTIMIZER_ENABLED)
			sampler2D _DepthBulgeMask;
			#endif
			float _DepthBulgeMaskUV;
			float4 _DepthBulgeMask_ST;
			float _DepthBulgeMaskChannel;
			#endif
			//endex
			
			//ifex _MainVertexColoringEnabled==0
			float _MainVertexColoringEnabled;
			float _MainVertexColoringLinearSpace;
			float _MainVertexColoring;
			float _MainUseVertexColorAlpha;
			//endex
			
			//ifex _BackFaceEnabled!=1
			#ifdef POI_BACKFACE
			float _BackFaceEnabled;
			float _BackFaceDetailIntensity;
			float _BackFaceEmissionStrength;
			float2 _BackFacePanning;
			float4 _BackFaceColor;
			float _BackFaceColorThemeIndex;
			float _BackFaceReplaceAlpha;
			
			#if defined(PROP_BACKFACETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BackFaceTexture;
			#endif
			float4 _BackFaceTexture_ST;
			float2 _BackFaceTexturePan;
			float _BackFaceTextureUV;
			
			#if defined(PROP_BACKFACEMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BackFaceMask;
			#endif
			float4 _BackFaceMask_ST;
			float2 _BackFaceMaskPan;
			float _BackFaceMaskUV;
			float _BackFaceMaskChannel;
			
			float _BackFaceHueShiftEnabled;
			float _BackFaceHueShift;
			float _BackFaceHueShiftSpeed;
			float _BackFaceEmissionLimiter;
			#endif
			
			//TODO detail strength stuff
			//endex
			
			//ifex _RGBMaskEnabled==0
			#ifdef VIGNETTE
			#if defined(PROP_RGBMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RGBMask;
			#endif
			float4 _RGBMask_ST;
			float2 _RGBMaskPan;
			float _RGBMaskUV;
			
			#if defined(PROP_RGBAMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RGBAMetallicMaps;
			float4 _RGBAMetallicMaps_ST;
			float2 _RGBAMetallicMapsPan;
			float _RGBAMetallicMapsUV;
			float _RGBAMetallicMapsStochastic;
			#endif
			float _RGBARedMetallicInvert;
			float _RGBAGreenMetallicInvert;
			float _RGBABlueMetallicInvert;
			float _RGBAAlphaMetallicInvert;
			float _RGBAMetallicRedEnabled;
			float _RGBAMetallicGreenEnabled;
			float _RGBAMetallicBlueEnabled;
			float _RGBAMetallicAlphaEnabled;
			
			float _RGBARedPBRSplitMaskSample;
			float4 _RGBARedPBRMaskScaleTiling;
			float2 _RGBARedPBRMasksPan;
			float _RGBARedPBRUV;
			float _RGBARedPBRSplitMaskStochastic;
			
			float _RGBAGreenPBRSplitMaskSample;
			float4 _RGBAGreenPBRMaskScaleTiling;
			float2 _RGBAGreenPBRMasksPan;
			float _RGBAGreenPBRUV;
			float _RGBAGreenPBRSplitMaskStochastic;
			
			float _RGBABluePBRSplitMaskSample;
			float4 _RGBABluePBRMaskScaleTiling;
			float2 _RGBABluePBRMasksPan;
			float _RGBABluePBRUV;
			float _RGBABluePBRSplitMaskStochastic;
			
			float _RGBAAlphaPBRSplitMaskSample;
			float4 _RGBAAlphaPBRMaskScaleTiling;
			float2 _RGBAAlphaPBRMasksPan;
			float _RGBAAlphaPBRUV;
			float _RGBAAlphaPBRSplitMaskStochastic;
			
			float _RGBAPBRRedEnabled;
			float _RGBAPBRGreenEnabled;
			float _RGBAPBRBlueEnabled;
			float _RGBAPBRAlphaEnabled;
			
			#if defined(PROP_RGBASMOOTHNESSMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RGBASmoothnessMaps;
			float4 _RGBASmoothnessMaps_ST;
			float4 _RGBASmoothnessMapsPan;
			float _RGBASmoothnessMapsUV;
			float _RGBASmoothnessMapsStochastic;
			#endif
			float _RGBARedSmoothnessInvert;
			float _RGBAGreenSmoothnessInvert;
			float _RGBABlueSmoothnessInvert;
			float _RGBAAlphaSmoothnessInvert;
			
			float _RGBARedEnable;
			#if defined(PROP_REDTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RedTexture;
			#endif
			float4 _RedTexture_ST;
			float2 _RedTexturePan;
			float _RedTextureUV;
			float _RedAlphaAdd;
			float _RedTextureStochastic;
			float _RgbRedMaskChannel;
			float _RgbRedGlobalMaskChannel;
			float _RgbRedGlobalMaskBlendType;
			float _RGBARedBlendType;
			float4 _RedColor;
			float _RedColorThemeIndex;
			float _RGBARedEmissionStrength;
			
			#if defined(PROP_RGBNORMALR) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RgbNormalR;
			#endif
			float4 _RgbNormalR_ST;
			float2 _RgbNormalRPan;
			float _RgbNormalRUV;
			float _RgbNormalRScale;
			float _RgbNormalRStochastic;
			float _RgbNormalRMaskChannel;
			float _RgbNormalRGlobalMaskChannel;
			float _RgbNormalRGlobalMaskBlendType;
			float _RgbNormalRedBlendMode;
			
			float _RGBAGreenEnable;
			#if defined(PROP_GREENTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GreenTexture;
			#endif
			float4 _GreenTexture_ST;
			float2 _GreenTexturePan;
			float _GreenTextureUV;
			float _GreenAlphaAdd;
			float _GreenTextureStochastic;
			float _RgbGreenMaskChannel;
			float _RgbGreenGlobalMaskChannel;
			float _RgbGreenGlobalMaskBlendType;
			float _RGBAGreenBlendType;
			float4 _GreenColor;
			float _GreenColorThemeIndex;
			float _RGBAGreenEmissionStrength;
			
			#if defined(PROP_RGBNORMALG) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RgbNormalG;
			#endif
			float4 _RgbNormalG_ST;
			float2 _RgbNormalGPan;
			float _RgbNormalGUV;
			float _RgbNormalGScale;
			float _RgbNormalGStochastic;
			float _RgbNormalGMaskChannel;
			float _RgbNormalGGlobalMaskChannel;
			float _RgbNormalGGlobalMaskBlendType;
			float _RgbNormalGreenBlendMode;
			
			float _RGBABlueEnable;
			#if defined(PROP_BLUETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BlueTexture;
			#endif
			float4 _BlueTexture_ST;
			float2 _BlueTexturePan;
			float _BlueTextureUV;
			float _BlueAlphaAdd;
			float _BlueTextureStochastic;
			float _RgbBlueMaskChannel;
			float _RgbBlueGlobalMaskChannel;
			float _RgbBlueGlobalMaskBlendType;
			float _RGBABlueBlendType;
			float4 _BlueColor;
			float _BlueColorThemeIndex;
			float _RGBABlueEmissionStrength;
			
			#if defined(PROP_RGBNORMALB) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RgbNormalB;
			#endif
			float4 _RgbNormalB_ST;
			float2 _RgbNormalBPan;
			float _RgbNormalBUV;
			float _RgbNormalBScale;
			float _RgbNormalBStochastic;
			float _RgbNormalBMaskChannel;
			float _RgbNormalBGlobalMaskChannel;
			float _RgbNormalBGlobalMaskBlendType;
			float _RgbNormalBlueBlendMode;
			
			float _RGBAAlphaEnable;
			#if defined(PROP_ALPHATEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AlphaTexture;
			#endif
			float4 _AlphaTexture_ST;
			float2 _AlphaTexturePan;
			float _AlphaTextureUV;
			float _AlphaAlphaAdd;
			float _AlphaTextureStochastic;
			float _RgbAlphaMaskChannel;
			float _RgbAlphaGlobalMaskChannel;
			float _RgbAlphaGlobalMaskBlendType;
			float _RGBAAlphaBlendType;
			float4 _AlphaColor;
			float _AlphaColorThemeIndex;
			float _RGBAAlphaEmissionStrength;
			
			#if defined(PROP_RGBNORMALA) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RgbNormalA;
			#endif
			float4 _RgbNormalA_ST;
			float2 _RgbNormalAPan;
			float _RgbNormalAUV;
			float _RgbNormalAScale;
			float _RgbNormalAStochastic;
			float _RgbNormalAMaskChannel;
			float _RgbNormalAGlobalMaskChannel;
			float _RgbNormalAGlobalMaskBlendType;
			float _RgbNormalAlphaBlendMode;
			
			float _RGBMaskType;
			
			#endif
			//endex
			
			//ifex _LTCGIEnabled!=1
			#ifdef POI_LTCGI
			float4 _LTCGI_DiffuseColor;
			int _LTCGI_DiffuseColorThemeIndex;
			float4 _LTCGI_SpecularColor;
			int _LTCGI_SpecularColorThemeIndex;
			float _LTCGI_Smoothness;
			float _LTCGI_Metallic;
			int _LTCGI_UsePBR;
			int _LTCGI_AnimToggle;
			#endif
			//endex
			
			//ifex _ShadingEnabled==0
			float _ShadowStrength;
			float _LightingIgnoreAmbientColor;
			float3 _LightingShadowColor;
			
			float _ShadingRampedLightMapApplyGlobalMaskIndex;
			float _ShadingRampedLightMapApplyGlobalMaskBlendType;
			
			float _ShadingRampedLightMapInverseApplyGlobalMaskIndex;
			float _ShadingRampedLightMapInverseApplyGlobalMaskBlendType;
			
			// Toon Lighting
			#ifdef _LIGHTINGMODE_TEXTURERAMP
			UNITY_DECLARE_TEX2D(_ToonRamp);
			float _ShadowOffset;
			int _ToonRampCount;
			int _ToonRampUVSelector;
			#endif
			
			#ifdef _LIGHTINGMODE_WRAPPED
			float4 _LightingWrappedColor;
			float _LightingWrappedWrap;
			float _LightingWrappedNormalization;
			float _LightingGradientStart;
			float _LightingGradientEnd;
			#endif
			
			#ifdef _LIGHTINGMODE_SHADEMAP
			float3 _1st_ShadeColor;
			#if defined(PROP_1ST_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _1st_ShadeMap;
			#endif
			float4 _1st_ShadeMap_ST;
			float2 _1st_ShadeMapPan;
			float _1st_ShadeMapUV;
			float _Use_1stShadeMapAlpha_As_ShadowMask;
			float _1stShadeMapMask_Inverse;
			float _Use_BaseAs1st;
			float3 _2nd_ShadeColor;
			#if defined(PROP_2ND_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _2nd_ShadeMap;
			#endif
			float4 _2nd_ShadeMap_ST;
			float2 _2nd_ShadeMapPan;
			float _2nd_ShadeMapUV;
			float _Use_2ndShadeMapAlpha_As_ShadowMask;
			float _2ndShadeMapMask_Inverse;
			float _Use_1stAs2nd;
			float _BaseColor_Step;
			float _BaseShade_Feather;
			float _ShadeColor_Step;
			float _1st2nd_Shades_Feather;
			float _ShadingShadeMapBlendType;
			#endif
			
			#ifdef _LIGHTINGMODE_SKIN
			sampler2D _SkinLUT;
			float _SssScale;
			#if defined(PROP_SKINTHICKNESS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _SkinThicknessMap;
			#endif
			float4 _SkinThicknessMap_ST;
			float2 _SkinThicknessMapPan;
			float _SkinThicknessMapUV;
			float _SkinThicknessMapInvert;
			float _SkinThicknessPower;
			float _SssBumpBlur;
			float3 _SssTransmissionAbsorption;
			float3 _SssColorBleedAoWeights;
			#endif
			
			#ifdef _LIGHTINGMODE_MULTILAYER_MATH
			float _ShadowBorderMapToggle;
			#if defined(PROP_SHADOWBORDERMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ShadowBorderMask;
			float4 _ShadowBorderMask_ST;
			float2 _ShadowBorderMaskPan;
			float _ShadowBorderMaskUV;
			#endif
			float _ShadowPostAO;
			float _ShadowBorderMaskLOD;
			float4 _ShadowAOShift;
			float4 _ShadowAOShift2;
			
			float4 _ShadowColor;
			float _LightingMulitlayerNonLinear;
			#if defined(PROP_SHADOWCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ShadowColorTex;
			float4 _ShadowColorTex_ST;
			float2 _ShadowColorTexPan;
			float _ShadowColorTexUV;
			#endif
			#if defined(PROP_MULTILAYERMATHBLURMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MultilayerMathBlurMap;
			float4 _MultilayerMathBlurMap_ST;
			float2 _MultilayerMathBlurMapPan;
			float _MultilayerMathBlurMapUV;
			#endif
			float _ShadowBorder;
			float _ShadowBlur;
			float _ShadowReceive;
			float4 _Shadow2ndColor;
			#if defined(PROP_SHADOW2NDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Shadow2ndColorTex;
			float4 _Shadow2ndColorTex_ST;
			float2 _Shadow2ndColorTexPan;
			float _Shadow2ndColorTexUV;
			#endif
			float _Shadow2ndBorder;
			float _Shadow2ndBlur;
			float _Shadow2ndReceive;
			float4 _Shadow3rdColor;
			#if defined(PROP_SHADOW3RDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Shadow3rdColorTex;
			float4 _Shadow3rdColorTex_ST;
			float2 _Shadow3rdColorTexPan;
			float _Shadow3rdColorTexUV;
			#endif
			float _Shadow3rdBorder;
			float _Shadow3rdBlur;
			float _Shadow3rdReceive;
			float4 _ShadowBorderColor;
			float _ShadowBorderRange;
			float _ShadowMainStrength;
			#endif
			
			#ifdef _LIGHTINGMODE_FLAT
			float _ForceFlatRampedLightmap;
			#endif
			
			#ifdef _LIGHTINGMODE_CLOTH
			Texture2D_float _ClothDFG;
			SamplerState sampler_ClothDFG;
			
			#if defined(PROP_CLOTHMETALLICSMOOTHNESSMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ClothMetallicSmoothnessMap;
			#endif
			
			float4 _ClothMetallicSmoothnessMap_ST;
			float2 _ClothMetallicSmoothnessMapPan;
			float _ClothMetallicSmoothnessMapUV;
			float _ClothMetallicSmoothnessMapInvert;
			
			float _ClothLerp;
			float _ClothMetallic;
			float _ClothReflectance;
			float _ClothSmoothness;
			#endif
			
			#ifdef _LIGHTINGMODE_SDF
			#if defined(PROP_SDFSHADINGTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _SDFShadingTexture;
			float _SDFShadingTextureUV;
			float2 _SDFShadingTexturePan;
			float4 _SDFShadingTexture_ST;
			float _SDFBlur;
			float4 _SDFForward;
			float4 _SDFLeft;
			#endif
			#endif
			
			// Additive
			float _LightingAdditiveType;
			float _LightingAdditiveGradientStart;
			float _LightingAdditiveGradientEnd;
			float _LightingAdditiveDetailStrength;
			//endex
			
			//ifex _DecalEnabled==0 && _DecalEnabled1==0 && _DecalEnabled2==0 && _DecalEnabled3==0
			
			#if defined(PROP_DECALMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DecalMask;
			float4 _DecalMask_ST;
			float2 _DecalMaskPan;
			float _DecalMaskUV;
			#endif
			float _DecalTPSDepthMaskEnabled;
			float _Decal0TPSMaskStrength;
			float _Decal1TPSMaskStrength;
			float _Decal2TPSMaskStrength;
			float _Decal3TPSMaskStrength;
			
			sampler2D _Udon_VideoTex;
			float4 _Udon_VideoTex_TexelSize;
			
			#ifdef POI_AUDIOLINK
			//ifex _DecalEnabled==0
			#ifdef GEOM_TYPE_BRANCH
			// Audio Link
			half _AudioLinkDecal0ScaleBand;
			float4 _AudioLinkDecal0Scale;
			half _AudioLinkDecal0RotationBand;
			float2 _AudioLinkDecal0Rotation;
			half _AudioLinkDecal0AlphaBand;
			float2 _AudioLinkDecal0Alpha;
			half _AudioLinkDecal0EmissionBand;
			float2 _AudioLinkDecal0Emission;
			float _DecalRotationCTALBand0;
			float _DecalRotationCTALSpeed0;
			float _DecalRotationCTALType0;
			float _AudioLinkDecalCC0;
			float _AudioLinkDecal0SideBand;
			float4 _AudioLinkDecal0SideMin;
			float4 _AudioLinkDecal0SideMax;
			float2 _AudioLinkDecal0ChannelSeparation;
			float _AudioLinkDecal0ChannelSeparationBand;
			#endif //GEOM_TYPE_BRANCH
			//endex
			//ifex _DecalEnabled1==0
			#ifdef GEOM_TYPE_BRANCH_DETAIL
			half _AudioLinkDecal1ScaleBand;
			float4 _AudioLinkDecal1Scale;
			half _AudioLinkDecal1RotationBand;
			float2 _AudioLinkDecal1Rotation;
			half _AudioLinkDecal1AlphaBand;
			float2 _AudioLinkDecal1Alpha;
			half _AudioLinkDecal1EmissionBand;
			float2 _AudioLinkDecal1Emission;
			float _DecalRotationCTALBand1;
			float _DecalRotationCTALSpeed1;
			float _DecalRotationCTALType1;
			float _AudioLinkDecalCC1;
			float _AudioLinkDecal1SideBand;
			float4 _AudioLinkDecal1SideMin;
			float4 _AudioLinkDecal1SideMax;
			float2 _AudioLinkDecal1ChannelSeparation;
			float _AudioLinkDecal1ChannelSeparationBand;
			#endif //GEOM_TYPE_BRANCH_DETAIL
			//endex
			//ifex _DecalEnabled2==0
			#ifdef GEOM_TYPE_FROND
			half _AudioLinkDecal2ScaleBand;
			float4 _AudioLinkDecal2Scale;
			half _AudioLinkDecal2RotationBand;
			float2 _AudioLinkDecal2Rotation;
			half _AudioLinkDecal2AlphaBand;
			float2 _AudioLinkDecal2Alpha;
			half _AudioLinkDecal2EmissionBand;
			float2 _AudioLinkDecal2Emission;
			float _DecalRotationCTALBand2;
			float _DecalRotationCTALSpeed2;
			float _DecalRotationCTALType2;
			float _AudioLinkDecalCC2;
			float _AudioLinkDecal2SideBand;
			float4 _AudioLinkDecal2SideMin;
			float4 _AudioLinkDecal2SideMax;
			float2 _AudioLinkDecal2ChannelSeparation;
			float _AudioLinkDecal2ChannelSeparationBand;
			#endif //GEOM_TYPE_FROND
			//endex
			//ifex _DecalEnabled3==0
			#ifdef DEPTH_OF_FIELD_COC_VIEW
			half _AudioLinkDecal3ScaleBand;
			float4 _AudioLinkDecal3Scale;
			half _AudioLinkDecal3RotationBand;
			float2 _AudioLinkDecal3Rotation;
			half _AudioLinkDecal3AlphaBand;
			float2 _AudioLinkDecal3Alpha;
			half _AudioLinkDecal3EmissionBand;
			float2 _AudioLinkDecal3Emission;
			float _DecalRotationCTALBand3;
			float _DecalRotationCTALSpeed3;
			float _DecalRotationCTALType3;
			float _AudioLinkDecalCC3;
			float _AudioLinkDecal3SideBand;
			float4 _AudioLinkDecal3SideMin;
			float4 _AudioLinkDecal3SideMax;
			float2 _AudioLinkDecal3ChannelSeparation;
			float _AudioLinkDecal3ChannelSeparationBand;
			#endif //DEPTH_OF_FIELD_COC_VIEW
			//endex
			#endif
			//endex
			//ifex _DecalEnabled==0
			#ifdef GEOM_TYPE_BRANCH
			float _Decal0VideoFitToScale;
			float _Decal0VideoAspectFix;
			float _Decal0VideoEmissionStrength;
			float _Decal0VideoEnabled;
			float _Decal0UseDecalAlpha;
			float _Decal0OnlyVideo;
			sampler2D _DecalTexture;
			float _Decal0FaceMask;
			float _Decal0MaskChannel;
			float _Decal0GlobalMask;
			float _Decal0GlobalMaskBlendType;
			float _Decal0ApplyGlobalMaskIndex;
			float _Decal0ApplyGlobalMaskBlendType;
			float4 _DecalTexture_ST;
			float2 _DecalTexturePan;
			float _DecalTextureUV;
			float4 _DecalColor;
			float _DecalColorThemeIndex;
			float _DecalTiled;
			float _DecalBlendType;
			half _DecalRotation;
			half3 _DecalScale;
			float4 _DecalSideOffset;
			half2 _DecalPosition;
			half _DecalRotationSpeed;
			float _DecalEmissionStrength;
			float _DecalBlendAlpha;
			float _DecalOverrideAlpha;
			float _DecalHueShiftEnabled;
			float _DecalHueShift;
			float _DecalHueShiftSpeed;
			float _Decal0Depth;
			float _Decal0HueAngleStrength;
			float _Decal0ChannelSeparationEnable;
			float _Decal0ChannelSeparation;
			float _Decal0ChannelSeparationPremultiply;
			float _Decal0ChannelSeparationHue;
			float _Decal0ChannelSeparationVertical;
			float _Decal0ChannelSeparationAngleStrength;
			float _Decal0OverrideAlphaMode;
			#endif
			//endex
			
			//ifex _DecalEnabled1==0
			#ifdef GEOM_TYPE_BRANCH_DETAIL
			float _Decal1VideoAspectFix;
			float _Decal1VideoFitToScale;
			float _Decal1VideoEmissionStrength;
			float _Decal1VideoEnabled;
			float _Decal1UseDecalAlpha;
			float _Decal1OnlyVideo;
			float _Decal1TextureToUse;
			sampler2D _DecalTexture1;
			float _Decal1FaceMask;
			float _Decal1MaskChannel;
			float _Decal1GlobalMask;
			float _Decal1GlobalMaskBlendType;
			float _Decal1ApplyGlobalMaskIndex;
			float _Decal1ApplyGlobalMaskBlendType;
			float4 _DecalTexture1_ST;
			float2 _DecalTexture1Pan;
			float _DecalTexture1UV;
			float4 _DecalColor1;
			float _DecalColor1ThemeIndex;
			fixed _DecalTiled1;
			float _DecalBlendType1;
			half _DecalRotation1;
			half3 _DecalScale1;
			float4 _DecalSideOffset1;
			half2 _DecalPosition1;
			half _DecalRotationSpeed1;
			float _DecalEmissionStrength1;
			float _DecalBlendAlpha1;
			float _DecalOverrideAlpha1;
			float _DecalHueShiftEnabled1;
			float _DecalHueShift1;
			float _DecalHueShiftSpeed1;
			float _Decal1Depth;
			float _Decal1HueAngleStrength;
			float _Decal1ChannelSeparationEnable;
			float _Decal1ChannelSeparation;
			float _Decal1ChannelSeparationPremultiply;
			float _Decal1ChannelSeparationHue;
			float _Decal1ChannelSeparationVertical;
			float _Decal1ChannelSeparationAngleStrength;
			float _Decal1OverrideAlphaMode;
			#endif
			//endex
			
			//ifex _DecalEnabled2==0
			#ifdef GEOM_TYPE_FROND
			float _Decal2VideoAspectFix;
			float _Decal2VideoFitToScale;
			float _Decal2VideoEmissionStrength;
			float _Decal2VideoEnabled;
			float _Decal2UseDecalAlpha;
			float _Decal2OnlyVideo;
			float _Decal2TextureToUse;
			sampler2D _DecalTexture2;
			float _Decal2FaceMask;
			float _Decal2MaskChannel;
			float _Decal2GlobalMask;
			float _Decal2GlobalMaskBlendType;
			float _Decal2ApplyGlobalMaskIndex;
			float _Decal2ApplyGlobalMaskBlendType;
			float4 _DecalTexture2_ST;
			float2 _DecalTexture2Pan;
			float _DecalTexture2UV;
			float4 _DecalColor2;
			float _DecalColor2ThemeIndex;
			fixed _DecalTiled2;
			float _DecalBlendType2;
			half _DecalRotation2;
			half3 _DecalScale2;
			float4 _DecalSideOffset2;
			half2 _DecalPosition2;
			half _DecalRotationSpeed2;
			float _DecalEmissionStrength2;
			float _DecalBlendAlpha2;
			float _DecalOverrideAlpha2;
			float _DecalHueShiftEnabled2;
			float _DecalHueShift2;
			float _DecalHueShiftSpeed2;
			float _Decal2Depth;
			float _Decal2HueAngleStrength;
			float _Decal2ChannelSeparationEnable;
			float _Decal2ChannelSeparation;
			float _Decal2ChannelSeparationPremultiply;
			float _Decal2ChannelSeparationHue;
			float _Decal2ChannelSeparationVertical;
			float _Decal2ChannelSeparationAngleStrength;
			float _Decal2OverrideAlphaMode;
			#endif
			//endex
			
			//ifex _DecalEnabled3==0
			#ifdef DEPTH_OF_FIELD_COC_VIEW
			float _Decal3VideoAspectFix;
			float _Decal3VideoFitToScale;
			float _Decal3VideoEmissionStrength;
			float _Decal3VideoEnabled;
			float _Decal3UseDecalAlpha;
			float _Decal3OnlyVideo;
			float _Decal3TextureToUse;
			sampler2D _DecalTexture3;
			float _Decal3FaceMask;
			float _Decal3MaskChannel;
			float _Decal3GlobalMask;
			float _Decal3GlobalMaskBlendType;
			float _Decal3ApplyGlobalMaskIndex;
			float _Decal3ApplyGlobalMaskBlendType;
			float4 _DecalTexture3_ST;
			float2 _DecalTexture3Pan;
			float _DecalTexture3UV;
			float4 _DecalColor3;
			float _DecalColor3ThemeIndex;
			fixed _DecalTiled3;
			float _DecalBlendType3;
			half _DecalRotation3;
			half3 _DecalScale3;
			float4 _DecalSideOffset3;
			half2 _DecalPosition3;
			half _DecalRotationSpeed3;
			float _DecalEmissionStrength3;
			float _DecalBlendAlpha3;
			float _DecalOverrideAlpha3;
			float _DecalHueShiftEnabled3;
			float _DecalHueShift3;
			float _DecalHueShiftSpeed3;
			float _Decal3Depth;
			float _Decal3HueAngleStrength;
			float _Decal3ChannelSeparationEnable;
			float _Decal3ChannelSeparation;
			float _Decal3ChannelSeparationPremultiply;
			float _Decal3ChannelSeparationHue;
			float _Decal3ChannelSeparationVertical;
			float _Decal3ChannelSeparationAngleStrength;
			float _Decal3OverrideAlphaMode;
			#endif
			//endex
			
			//ifex _EnableDissolve==0
			#ifdef DISTORT
			float _DissolveType;
			float _DissolveEdgeWidth;
			float4 _DissolveEdgeColor;
			sampler2D _DissolveEdgeGradient;
			float4 _DissolveEdgeGradient_ST;
			float2 _DissolveEdgeGradientPan;
			float _DissolveEdgeGradientUV;
			float _DissolveEdgeEmission;
			float4 _DissolveTextureColor;
			float _DissolveEdgeColorThemeIndex;
			float _DissolveTextureColorThemeIndex;
			
			#if defined(PROP_DISSOLVETOTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveToTexture;
			#endif
			float4 _DissolveToTexture_ST;
			float2 _DissolveToTexturePan;
			float _DissolveToTextureUV;
			
			#if defined(PROP_DISSOLVENOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveNoiseTexture;
			#endif
			float4 _DissolveNoiseTexture_ST;
			float2 _DissolveNoiseTexturePan;
			float _DissolveNoiseTextureUV;
			
			#if defined(PROP_DISSOLVEDETAILNOISE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveDetailNoise;
			#endif
			float4 _DissolveDetailNoise_ST;
			float2 _DissolveDetailNoisePan;
			float _DissolveDetailNoiseUV;
			
			#if defined(PROP_DISSOLVEMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveMask;
			#endif
			float4 _DissolveMask_ST;
			float2 _DissolveMaskPan;
			float _DissolveMaskUV;
			
			float _DissolveMaskGlobalMask;
			float _DissolveMaskGlobalMaskBlendType;
			float _DissolveApplyGlobalMaskIndex;
			float _DissolveApplyGlobalMaskBlendType;
			float _DissolveInverseApplyGlobalMaskBlendType;
			float _DissolveInverseApplyGlobalMaskIndex;
			float _DissolveMaskInvert;
			float _DissolveAlpha;
			float _ContinuousDissolve;
			float _DissolveDetailStrength;
			float _DissolveDetailEdgeSmoothing;
			float _DissolveEdgeHardness;
			float _DissolveInvertNoise;
			float _DissolveInvertDetailNoise;
			float _DissolveToEmissionStrength;
			
			// Point to Point
			float _DissolveP2PWorldLocal;
			float _DissolveP2PEdgeLength;
			float _DissolveP2PClamp;
			float4 _DissolveStartPoint;
			float4 _DissolveEndPoint;
			
			// Spherical
			float3 _SphericalDissolveCenter;
			float _SphericalDissolveRadius;
			float _SphericalDissolveInvert;
			float _SphericalDissolveClamp;
			
			// CenterOut
			float _CenterOutDissolveMode;
			float3 _CenterOutDissolveDirection;
			float _CenterOutDissolveInvert;
			float _CenterOutDissolveNormals;
			float _CenterOutDissolvePower;
			
			// World Dissolve
			float _DissolveWorldShape;
			float4 _DissolveShapePosition;
			float4 _DissolveShapeRotation;
			float _DissolveShapeScale;
			float _DissolveInvertShape;
			float _DissolveShapeEdgeLength;
			
			// UV Tile Dissolve
			float _UVTileDissolveEnabled;
			float _UVTileDissolveDiscardAtMax;
			float _UVTileDissolveUV;
			
			float _UVTileDissolveAlpha_Row3_0;
			float _UVTileDissolveAlpha_Row3_1;
			float _UVTileDissolveAlpha_Row3_2;
			float _UVTileDissolveAlpha_Row3_3;
			float _UVTileDissolveAlpha_Row2_0;
			float _UVTileDissolveAlpha_Row2_1;
			float _UVTileDissolveAlpha_Row2_2;
			float _UVTileDissolveAlpha_Row2_3;
			float _UVTileDissolveAlpha_Row1_0;
			float _UVTileDissolveAlpha_Row1_1;
			float _UVTileDissolveAlpha_Row1_2;
			float _UVTileDissolveAlpha_Row1_3;
			float _UVTileDissolveAlpha_Row0_0;
			float _UVTileDissolveAlpha_Row0_1;
			float _UVTileDissolveAlpha_Row0_2;
			float _UVTileDissolveAlpha_Row0_3;
			
			float _DissolveAlpha0;
			float _DissolveAlpha1;
			float _DissolveAlpha2;
			float _DissolveAlpha3;
			float _DissolveAlpha4;
			float _DissolveAlpha5;
			float _DissolveAlpha6;
			float _DissolveAlpha7;
			float _DissolveAlpha8;
			float _DissolveAlpha9;
			// Masking
			float _DissolveEmissionSide;
			float _DissolveEmission1Side;
			float _DissolveUseVertexColors;
			
			float4 edgeColor;
			float edgeAlpha;
			float dissolveAlpha;
			float4 dissolveToTexture;
			
			float _DissolveHueShiftEnabled;
			float _DissolveHueShiftSpeed;
			float _DissolveHueShift;
			float _DissolveEdgeHueShiftEnabled;
			float _DissolveEdgeHueShiftSpeed;
			float _DissolveEdgeHueShift;
			
			// Audio Link
			#ifdef POI_AUDIOLINK
			fixed _EnableDissolveAudioLink;
			half _AudioLinkDissolveAlphaBand;
			float2 _AudioLinkDissolveAlpha;
			half _AudioLinkDissolveDetailBand;
			float2 _AudioLinkDissolveDetail;
			#endif
			#endif
			//endex
			
			//ifex _EnableAniso==0
			#ifdef POI_ANISOTROPICS
			
			#if defined(PROP_ANISOCOLORMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AnisoColorMap;
			float4 _AnisoColorMap_ST;
			float2 _AnisoColorMapPan;
			float _AnisoColorMapUV;
			#endif
			/*
			#if defined(PROP_ANISONOISEMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AnisoNoiseMap;
			float4 _AnisoNoiseMap_ST;
			float2 _AnisoNoiseMapPan;
			float _AnisoNoiseMapUV;
			#endif
			*/
			float _AnisoHideInShadow;
			float _AnisoReplace;
			float _AnisoAdd;
			float _AnisoUseBaseColor;
			float _AnisoUseLightColor;
			
			float _AnisoGlobalMask;
			float _AnisoGlobalMaskBlendType;
			
			float _Aniso0Strength;
			float _Aniso0Power;
			float _Aniso0Offset;
			float _Aniso0SwitchDirection;
			float4 _Aniso0Tint;
			float _Aniso0TintIndex;
			float _Aniso0OffsetMapStrength;
			float _Aniso0ToonMode;
			float _Aniso0Edge;
			float _Aniso0Blur;
			
			float _Aniso1Strength;
			float _Aniso1Power;
			float _Aniso1Offset;
			float _Aniso1SwitchDirection;
			float4 _Aniso1Tint;
			float _Aniso1TintIndex;
			float _Aniso1OffsetMapStrength;
			float _Aniso1ToonMode;
			float _Aniso1Edge;
			float _Aniso1Blur;
			#endif
			//endex
			
			//ifex _MatcapEnable==0
			#ifdef POI_MATCAP0
			#if defined(PROP_MATCAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap;
			float4 _Matcap_ST;
			float4 _Matcap_TexelSize;
			float2 _MatcapPan;
			float _MatcapUV;
			#endif
			#if defined(PROP_MATCAPMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MatcapMask;
			float4 _MatcapMask_ST;
			float2 _MatcapMaskPan;
			float _MatcapMaskUV;
			float _MatcapMaskChannel;
			#endif
			#ifdef POI_MATCAP0_CUSTOM_NORMAL
			#if defined(PROP_MATCAP0NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap0NormalMap;
			#endif
			float4 _Matcap0NormalMap_ST;
			float2 _Matcap0NormalMapPan;
			float _Matcap0NormalMapUV;
			float _Matcap0NormalMapScale;
			#endif
			float _MatcapUVToBlend;
			float4 _MatCapBlendUV1;
			float _MatcapUVMode;
			float _MatcapMaskInvert;
			float _MatcapMaskGlobalMask;
			float _MatcapMaskGlobalMaskBlendType;
			float _MatcapBorder;
			float _MatcapRotation;
			float _MatcapSmoothnessEnabled;
			float _MatcapSmoothness;
			float _MatcapMaskSmoothnessChannel;
			float _MatcapMaskSmoothnessApply;
			float4 _MatcapColor;
			float _MatcapBaseColorMix;
			float _MatcapColorThemeIndex;
			float _MatcapIntensity;
			float _MatcapReplace;
			float _MatcapMultiply;
			float _MatcapAdd;
			float _MatcapAddToLight;
			float _MatcapMixed;
			float _MatcapScreen;
			float _MatcapAlphaOverride;
			float _MatcapEnable;
			float _MatcapLightMask;
			float _MatcapEmissionStrength;
			float _MatcapNormal;
			float _MatcapHueShiftEnabled;
			float _MatcapHueShiftSpeed;
			float _MatcapHueShift;
			int _MatcapApplyToAlphaEnabled;
			int _MatcapApplyToAlphaSourceBlend;
			int _MatcapApplyToAlphaBlendType;
			float _MatcapApplyToAlphaBlending;
			float _MatcapTPSDepthEnabled;
			float _MatcapTPSMaskStrength;
			
			float _Matcap0ALEnabled;
			float _Matcap0ALAlphaAddBand;
			float4 _Matcap0ALAlphaAdd;
			float _Matcap0ALEmissionAddBand;
			float4 _Matcap0ALEmissionAdd;
			float _Matcap0ALIntensityAddBand;
			float4 _Matcap0ALIntensityAdd;
			float _Matcap0ALChronoPanType;
			float _Matcap0ALChronoPanBand;
			float _Matcap0ALChronoPanSpeed;
			#endif
			//endex
			//ifex _Matcap2Enable==0
			#ifdef COLOR_GRADING_HDR_3D
			#if defined(PROP_MATCAP2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap2;
			float4 _Matcap2_ST;
			float4 _Matcap2_TexelSize;
			float2 _Matcap2Pan;
			float _Matcap2UV;
			#endif
			#if defined(PROP_MATCAP2MASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap2Mask;
			float4 _Matcap2Mask_ST;
			float2 _Matcap2MaskPan;
			float _Matcap2MaskUV;
			float _Matcap2MaskChannel;
			#endif
			#ifdef POI_MATCAP1_CUSTOM_NORMAL
			#if defined(PROP_MATCAP1NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap1NormalMap;
			#endif
			float4 _Matcap1NormalMap_ST;
			float2 _Matcap1NormalMapPan;
			float _Matcap1NormalMapUV;
			float _Matcap1NormalMapScale;
			#endif
			float _Matcap2UVToBlend;
			float4 _MatCap2ndBlendUV1;
			float _Matcap2UVMode;
			float _Matcap2MaskInvert;
			float _Matcap2MaskGlobalMask;
			float _Matcap2MaskGlobalMaskBlendType;
			float _Matcap2Border;
			float _Matcap2Rotation;
			float _Matcap2SmoothnessEnabled;
			float _Matcap2Smoothness;
			float _Matcap2MaskSmoothnessChannel;
			float _Matcap2MaskSmoothnessApply;
			float4 _Matcap2Color;
			float _Matcap2BaseColorMix;
			float _Matcap2ColorThemeIndex;
			float _Matcap2Intensity;
			float _Matcap2Replace;
			float _Matcap2Multiply;
			float _Matcap2Add;
			float _Matcap2AddToLight;
			float _Matcap2Mixed;
			float _Matcap2Screen;
			float _Matcap2AlphaOverride;
			float _Matcap2Enable;
			float _Matcap2LightMask;
			float _Matcap2EmissionStrength;
			float _Matcap2Normal;
			float _Matcap2HueShiftEnabled;
			float _Matcap2HueShiftSpeed;
			float _Matcap2HueShift;
			int _Matcap2ApplyToAlphaEnabled;
			int _Matcap2ApplyToAlphaSourceBlend;
			int _Matcap2ApplyToAlphaBlendType;
			float _Matcap2ApplyToAlphaBlending;
			float _Matcap2TPSDepthEnabled;
			float _Matcap2TPSMaskStrength;
			
			float _Matcap1ALEnabled;
			float _Matcap1ALAlphaAddBand;
			float4 _Matcap1ALAlphaAdd;
			float _Matcap1ALEmissionAddBand;
			float4 _Matcap1ALEmissionAdd;
			float _Matcap1ALIntensityAddBand;
			float4 _Matcap1ALIntensityAdd;
			float _Matcap1ALChronoPanType;
			float _Matcap1ALChronoPanBand;
			float _Matcap1ALChronoPanSpeed;
			#endif
			//endex
			
			//ifex _Matcap3Enable==0
			#ifdef POI_MATCAP2
			#if defined(PROP_MATCAP3) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap3;
			float4 _Matcap3_ST;
			float4 _Matcap3_TexelSize;
			float2 _Matcap3Pan;
			float _Matcap3UV;
			#endif
			#if defined(PROP_MATCAP3MASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap3Mask;
			float4 _Matcap3Mask_ST;
			float2 _Matcap3MaskPan;
			float _Matcap3MaskUV;
			float _Matcap3MaskChannel;
			#endif
			#ifdef POI_MATCAP2_CUSTOM_NORMAL
			#if defined(PROP_MATCAP2NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap2NormalMap;
			#endif
			float4 _Matcap2NormalMap_ST;
			float2 _Matcap2NormalMapPan;
			float _Matcap2NormalMapUV;
			float _Matcap2NormalMapScale;
			#endif
			float _Matcap3UVToBlend;
			float4 _MatCap3rdBlendUV1;
			float _Matcap3UVMode;
			float _Matcap3MaskInvert;
			float _Matcap3MaskGlobalMask;
			float _Matcap3MaskGlobalMaskBlendType;
			float _Matcap3Border;
			float _Matcap3Rotation;
			float _Matcap3SmoothnessEnabled;
			float _Matcap3Smoothness;
			float _Matcap3MaskSmoothnessChannel;
			float _Matcap3MaskSmoothnessApply;
			float4 _Matcap3Color;
			float _Matcap3BaseColorMix;
			float _Matcap3ColorThemeIndex;
			float _Matcap3Intensity;
			float _Matcap3Replace;
			float _Matcap3Multiply;
			float _Matcap3Add;
			float _Matcap3AddToLight;
			float _Matcap3Mixed;
			float _Matcap3Screen;
			float _Matcap3AlphaOverride;
			float _Matcap3Enable;
			float _Matcap3LightMask;
			float _Matcap3EmissionStrength;
			float _Matcap3Normal;
			float _Matcap3HueShiftEnabled;
			float _Matcap3HueShiftSpeed;
			float _Matcap3HueShift;
			int _Matcap3ApplyToAlphaEnabled;
			int _Matcap3ApplyToAlphaSourceBlend;
			int _Matcap3ApplyToAlphaBlendType;
			float _Matcap3ApplyToAlphaBlending;
			float _Matcap3TPSDepthEnabled;
			float _Matcap3TPSMaskStrength;
			
			float _Matcap2ALEnabled;
			float _Matcap2ALAlphaAddBand;
			float4 _Matcap2ALAlphaAdd;
			float _Matcap2ALEmissionAddBand;
			float4 _Matcap2ALEmissionAdd;
			float _Matcap2ALIntensityAddBand;
			float4 _Matcap2ALIntensityAdd;
			float _Matcap2ALChronoPanType;
			float _Matcap2ALChronoPanBand;
			float _Matcap2ALChronoPanSpeed;
			#endif
			//endex
			
			//ifex _Matcap4Enable==0
			#ifdef POI_MATCAP3
			#if defined(PROP_MATCAP4) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap4;
			float4 _Matcap4_ST;
			float4 _Matcap4_TexelSize;
			float2 _Matcap4Pan;
			float _Matcap4UV;
			#endif
			#if defined(PROP_MATCAP4MASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap4Mask;
			float4 _Matcap4Mask_ST;
			float2 _Matcap4MaskPan;
			float _Matcap4MaskUV;
			float _Matcap4MaskChannel;
			#endif
			#ifdef POI_MATCAP3_CUSTOM_NORMAL
			#if defined(PROP_MATCAP3NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap3NormalMap;
			#endif
			float4 _Matcap3NormalMap_ST;
			float2 _Matcap3NormalMapPan;
			float _Matcap3NormalMapUV;
			float _Matcap3NormalMapScale;
			#endif
			float _Matcap4UVToBlend;
			float4 _MatCap4thBlendUV1;
			float _Matcap4UVMode;
			float _Matcap4MaskInvert;
			float _Matcap4MaskGlobalMask;
			float _Matcap4MaskGlobalMaskBlendType;
			float _Matcap4Border;
			float _Matcap4Rotation;
			float _Matcap4SmoothnessEnabled;
			float _Matcap4Smoothness;
			float _Matcap4MaskSmoothnessChannel;
			float _Matcap4MaskSmoothnessApply;
			float4 _Matcap4Color;
			float _Matcap4BaseColorMix;
			float _Matcap4ColorThemeIndex;
			float _Matcap4Intensity;
			float _Matcap4Replace;
			float _Matcap4Multiply;
			float _Matcap4Add;
			float _Matcap4AddToLight;
			float _Matcap4Mixed;
			float _Matcap4Screen;
			float _Matcap4AlphaOverride;
			float _Matcap4Enable;
			float _Matcap4LightMask;
			float _Matcap4EmissionStrength;
			float _Matcap4Normal;
			float _Matcap4HueShiftEnabled;
			float _Matcap4HueShiftSpeed;
			float _Matcap4HueShift;
			int _Matcap4ApplyToAlphaEnabled;
			int _Matcap4ApplyToAlphaSourceBlend;
			int _Matcap4ApplyToAlphaBlendType;
			float _Matcap4ApplyToAlphaBlending;
			float _Matcap4TPSDepthEnabled;
			float _Matcap4TPSMaskStrength;
			
			float _Matcap3ALEnabled;
			float _Matcap3ALAlphaAddBand;
			float4 _Matcap3ALAlphaAdd;
			float _Matcap3ALEmissionAddBand;
			float4 _Matcap3ALEmissionAdd;
			float _Matcap3ALIntensityAddBand;
			float4 _Matcap3ALIntensityAdd;
			float _Matcap3ALChronoPanType;
			float _Matcap3ALChronoPanBand;
			float _Matcap3ALChronoPanSpeed;
			#endif
			//endex
			struct MatcapAudioLinkData
			{
				float matcapALEnabled;
				float matcapALAlphaAddBand;
				float4 matcapALAlphaAdd;
				float matcapALEmissionAddBand;
				float4 matcapALEmissionAdd;
				float matcapALIntensityAddBand;
				float4 matcapALIntensityAdd;
				float matcapALChronoPanType;
				float matcapALChronoPanBand;
				float matcapALChronoPanSpeed;
			};
			
			//ifex _CubeMapEnabled==0
			#ifdef _CUBEMAP
			#if defined(PROP_CUBEMAP) || !defined(OPTIMIZER_ENABLED)
			samplerCUBE _CubeMap;
			float3 _CubeMapRotation;
			float3 _CubeMapRotationPan;
			#endif
			#if defined(PROP_CUBEMAPMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _CubeMapMask;
			float4 _CubeMapMask_ST;
			float2 _CubeMapMaskPan;
			float _CubeMapMaskUV;
			float _CubeMapMaskChannel;
			#endif
			float _CubeMapUVMode;
			float _CubeMapWorldNormalsStrength;
			float _CubeMapMaskInvert;
			float _CubeMapMaskGlobalMask;
			float _CubeMapMaskGlobalMaskBlendType;
			float4 _CubeMapColor;
			float _CubeMapColorThemeIndex;
			float _CubeMapIntensity;
			float _CubemapBlendType;
			float _CubeMapBlendAmount;
			float _CubeMapEnable;
			float _CubeMapLightMask;
			float _CubeMapEmissionStrength;
			float _CubeMapNormal;
			float _CubeMapHueShiftEnabled;
			float _CubeMapHueShiftSpeed;
			float _CubeMapHueShift;
			float _CubeMapSaturation;
			float _CubeMapBrightness;
			float _CubeMapContrast;
			float _CubeMapSmoothness;
			#endif
			//endex
			
			//ifex _EnableALDecal==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_DECAL
			float _ALDecalUV;
			float4 _ALUVScale;
			float2 _ALUVPosition;
			float _ALUVRotation;
			float _ALUVRotationSpeed;
			float4 _ALDecaldCircleDimensions;
			
			float _ALDecalUVMode;
			
			float _ALDecalVolumeStep;
			float _ALDecalVolumeClipMin;
			float _ALDecalVolumeClipMax;
			
			float _ALDecalBandStep;
			float _ALDecalBandClipMin;
			float _ALDecalBandClipMax;
			
			float _ALDecalShapeClip;
			float _ALDecalShapeClipVolumeWidth;
			float _ALDecalShapeClipBandWidth;
			
			#if defined(PROP_ALDECALCOLORMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ALDecalColorMask;
			float4 _ALDecalColorMask_ST;
			float2 _ALDecalColorMaskPan;
			float _ALDecalColorMaskUV;
			#endif
			
			float _ALDecalVolume;
			float _ALDecalBaseBoost;
			float _ALDecalTrebleBoost;
			float _ALDecalLineWidth;
			float _ALDecalVolumeColorSource;
			float3 _ALDecalVolumeColorLow;
			float _ALDecalVolumeColorLowThemeIndex;
			float3 _ALDecalVolumeColorMid;
			float _ALDecalVolumeColorMidThemeIndex;
			float3 _ALDecalVolumeColorHigh;
			float _ALDecalVolumeColorHighThemeIndex;
			float _ALDecalLowEmission;
			float _ALDecalMidEmission;
			float _ALDecalHighEmission;
			float _ALDecalBlendType;
			float _ALDecalBlendAlpha;
			float _ALDecalControlsAlpha;
			float _ALDecalGlobalMask;
			float _ALDecalGlobalMaskBlendType;
			#endif
			#endif
			//endex
			
			//ifex _EnableVolumeColor==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_VOLUMECOLOR
			float _ALVolumeColorUV;
			float _ALVolumeColorDirection;
			float _ALVolumeColorBlendType;
			float _ALVolumeColorBlendAlpha;
			float3 _ALVolumeColorLow;
			float _ALVolumeColorLowThemeIndex;
			float3 _ALVolumeColorMid;
			float _ALVolumeColorMidThemeIndex;
			float3 _ALVolumeColorHigh;
			float _ALVolumeColorHighThemeIndex;
			float _ALLowEmission;
			float _ALMidEmission;
			float _ALHighEmission;
			#endif
			#endif
			//endex
			
			//ifex _EnableFlipbook==0
			#ifdef _SUNDISK_HIGH_QUALITY
			
			UNITY_DECLARE_TEX2DARRAY(_FlipbookTexArray);
			float4 _FlipbookTexArray_ST;
			
			float4 _FlipbookColor;
			float _FlipbookColorThemeIndex;
			float _FlipbookFPS;
			// float _FlipbookTotalFrames;
			float4 _FlipbookScaleOffset;
			float4 _FlipbookSideOffset;
			float _FlipbookTiled;
			float _FlipbookManualFrameControl;
			float _FlipbookCurrentFrame;
			float _FlipbookStartAndEnd;
			float _FlipbookStartFrame;
			float _FlipbookEndFrame;
			float _FlipbookEmissionStrength;
			float _FlipbookRotation;
			float _EnableFlipbook;
			float _FlipbookTexArrayUV;
			float _FlipbookAlphaControlsFinalAlpha;
			float _FlipbookRotationSpeed;
			float _FlipbookIntensityControlsAlpha;
			float _FlipbookColorReplaces;
			float2 _FlipbookTexArrayPan;
			float _FlipbookFrameOffset;
			// blending
			float _FlipbookReplace;
			float _FlipbookMultiply;
			float _FlipbookAdd;
			float _FlipbookBlendType;
			
			#if defined(PROP_FLIPBOOKMASSK) || !defined(OPTIMIZED_ENABLED)
			Texture2D _FlipbookMask;
			#endif
			float4 _FlipbookMask_ST;
			float2 _FlipbookMaskPan;
			float _FlipbookMaskUV;
			float _FlipbookMaskChannel;
			float _FlipbookMaskGlobalMask;
			float _FlipbookMaskGlobalMaskBlendType;
			
			// anim
			float _FlipbookMovementType;
			float4 _FlipbookStartEndOffset;
			float _FlipbookMovementSpeed;
			
			// Crossfade
			float _FlipbookCrossfadeEnabled;
			float2 _FlipbookCrossfadeRange;
			
			// Hueshift
			float _FlipbookHueShiftEnabled;
			float _FlipbookHueShiftSpeed;
			float _FlipbookHueShift;
			
			#ifdef POI_AUDIOLINK
			float _FlipbookChronotensityEnabled;
			float _FlipbookChronotensityBand;
			float _FlipbookChronotensitySpeed;
			float _FlipbookChronoType;
			half _AudioLinkFlipbookScaleBand;
			half4 _AudioLinkFlipbookScale;
			half _AudioLinkFlipbookAlphaBand;
			half2 _AudioLinkFlipbookAlpha;
			half _AudioLinkFlipbookEmissionBand;
			half2 _AudioLinkFlipbookEmission;
			half _AudioLinkFlipbookFrameBand;
			half2 _AudioLinkFlipbookFrame;
			#endif
			#endif
			//endex
			
			//ifex _EnableEmission==0
			#ifdef _EMISSION
			#if defined(PROP_EMISSIONMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionMap;
			#endif
			float4 _EmissionMap_ST;
			float2 _EmissionMapPan;
			float _EmissionMapUV;
			#if defined(PROP_EMISSIONMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionMask;
			#endif
			float4 _EmissionMask_ST;
			float2 _EmissionMaskPan;
			float _EmissionMaskUV;
			float _EmissionMaskInvert;
			float _EmissionMaskChannel;
			float _EmissionMask0GlobalMask;
			float _EmissionMask0GlobalMaskBlendType;
			#if defined(PROP_EMISSIONSCROLLINGCURVE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionScrollingCurve;
			#endif
			float4 _EmissionScrollingCurve_ST;
			
			float4 _EmissionColor;
			float _EmissionBaseColorAsMap;
			float _EmissionStrength;
			float _EmissionHueShiftEnabled;
			float _EmissionSaturation;
			float _EmissionHueShift;
			float _EmissionHueShiftSpeed;
			float _EmissionCenterOutEnabled;
			float _EmissionCenterOutSpeed;
			float _EnableGITDEmission;
			float _GITDEWorldOrMesh;
			float _GITDEMinEmissionMultiplier;
			float _GITDEMaxEmissionMultiplier;
			float _GITDEMinLight;
			float _GITDEMaxLight;
			float _EmissionBlinkingEnabled;
			float _EmissiveBlink_Min;
			float _EmissiveBlink_Max;
			float _EmissiveBlink_Velocity;
			float _EmissionBlinkingOffset;
			float _ScrollingEmission;
			float4 _EmissiveScroll_Direction;
			float _EmissiveScroll_Width;
			float _EmissiveScroll_Velocity;
			float _EmissiveScroll_Interval;
			float _EmissionScrollingOffset;
			
			float _EmissionReplace0;
			float _EmissionScrollingVertexColor;
			float _EmissionScrollingUseCurve;
			float _EmissionColorThemeIndex;
			
			// Audio Link
			float _EmissionAL0Enabled;
			float2 _EmissionAL0StrengthMod;
			float _EmissionAL0StrengthBand;
			float _EmissionAL0StrengthBandSmoothing;
			float2 _AudioLinkEmission0CenterOut;
			float _AudioLinkEmission0CenterOutSize;
			float _AudioLinkEmission0CenterOutBand;
			float _AudioLinkEmission0CenterOutDuration;
			float2 _EmissionAL0Multipliers;
			float _EmissionAL0MultipliersBand;
			#endif
			//endex
			//ifex _EnableEmission1==0
			#ifdef POI_EMISSION_1
			
			#if defined(PROP_EMISSIONMAP1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionMap1;
			#endif
			float4 _EmissionMap1_ST;
			float2 _EmissionMap1Pan;
			float _EmissionMap1UV;
			#if defined(PROP_EMISSIONMASK1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionMask1;
			#endif
			float4 _EmissionMask1_ST;
			float2 _EmissionMask1Pan;
			float _EmissionMask1UV;
			float _EmissionMask1Channel;
			float _EmissionMaskInvert1;
			float _EmissionMask1GlobalMask;
			float _EmissionMask1GlobalMaskBlendType;
			#if defined(PROP_EMISSIONSCROLLINGCURVE1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionScrollingCurve1;
			#endif
			float4 _EmissionScrollingCurve1_ST;
			
			float4 _EmissionColor1;
			float _EmissionBaseColorAsMap1;
			float _EmissionStrength1;
			float _EnableEmission1;
			float _EmissionHueShift1;
			float _EmissionHueShiftSpeed1;
			float4 _EmissiveScroll_Direction1;
			float _EmissiveScroll_Width1;
			float _EmissiveScroll_Velocity1;
			float _EmissiveScroll_Interval1;
			float _EmissionBlinkingEnabled1;
			float _EmissiveBlink_Min1;
			float _EmissiveBlink_Max1;
			float _EmissiveBlink_Velocity1;
			float _ScrollingEmission1;
			float _EnableGITDEmission1;
			float _GITDEMinEmissionMultiplier1;
			float _GITDEMaxEmissionMultiplier1;
			float _GITDEMinLight1;
			float _GITDEMaxLight1;
			float _GITDEWorldOrMesh1;
			float _EmissionCenterOutEnabled1;
			float _EmissionCenterOutSpeed1;
			float _EmissionHueShiftEnabled1;
			float _EmissionSaturation1;
			float _EmissionBlinkingOffset1;
			float _EmissionScrollingOffset1;
			float _EmissionScrollingVertexColor1;
			float _EmissionScrollingUseCurve1;
			float _EmissionReplace1;
			float _EmissionColor1ThemeIndex;
			
			// Audio Link
			float _EmissionAL1Enabled;
			float2 _EmissionAL1StrengthMod;
			float _EmissionAL1StrengthBand;
			float2 _AudioLinkEmission1CenterOut;
			float _AudioLinkEmission1CenterOutSize;
			float _AudioLinkEmission1CenterOutBand;
			float _AudioLinkEmission1CenterOutDuration;
			float2 _EmissionAL1Multipliers;
			float _EmissionAL1MultipliersBand;
			#endif
			//endex
			//ifex _EnableEmission2==0
			#ifdef POI_EMISSION_2
			
			#if defined(PROP_EMISSIONMAP2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionMap2;
			#endif
			float4 _EmissionMap2_ST;
			float2 _EmissionMap2Pan;
			float _EmissionMap2UV;
			#if defined(PROP_EMISSIONMASK2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionMask2;
			#endif
			float4 _EmissionMask2_ST;
			float2 _EmissionMask2Pan;
			float _EmissionMask2UV;
			float _EmissionMask2Channel;
			float _EmissionMaskInvert2;
			float _EmissionMask2GlobalMask;
			float _EmissionMask2GlobalMaskBlendType;
			#if defined(PROP_EMISSIONSCROLLINGCURVE2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionScrollingCurve2;
			#endif
			float4 _EmissionScrollingCurve2_ST;
			
			float4 _EmissionColor2;
			float _EmissionBaseColorAsMap2;
			float _EmissionStrength2;
			float _EnableEmission2;
			float _EmissionHueShift2;
			float _EmissionHueShiftSpeed2;
			float4 _EmissiveScroll_Direction2;
			float _EmissiveScroll_Width2;
			float _EmissiveScroll_Velocity2;
			float _EmissiveScroll_Interval2;
			float _EmissionBlinkingEnabled2;
			float _EmissiveBlink_Min2;
			float _EmissiveBlink_Max2;
			float _EmissiveBlink_Velocity2;
			float _ScrollingEmission2;
			float _EnableGITDEmission2;
			float _GITDEMinEmissionMultiplier2;
			float _GITDEMaxEmissionMultiplier2;
			float _GITDEMinLight2;
			float _GITDEMaxLight2;
			float _GITDEWorldOrMesh2;
			float _EmissionCenterOutEnabled2;
			float _EmissionCenterOutSpeed2;
			float _EmissionHueShiftEnabled2;
			float _EmissionSaturation2;
			float _EmissionBlinkingOffset2;
			float _EmissionScrollingOffset2;
			float _EmissionScrollingVertexColor2;
			float _EmissionScrollingUseCurve2;
			float _EmissionReplace2;
			float _EmissionColor2ThemeIndex;
			
			// Audio Link
			float _EmissionAL2Enabled;
			float2 _EmissionAL2StrengthMod;
			float _EmissionAL2StrengthBand;
			float2 _AudioLinkEmission2CenterOut;
			float _AudioLinkEmission2CenterOutSize;
			float _AudioLinkEmission2CenterOutBand;
			float _AudioLinkEmission2CenterOutDuration;
			float2 _EmissionAL2Multipliers;
			float _EmissionAL2MultipliersBand;
			#endif
			//endex
			//ifex _EnableEmission3==0
			#ifdef POI_EMISSION_3
			#if defined(PROP_EMISSIONMAP3) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionMap3;
			#endif
			float4 _EmissionMap3_ST;
			float2 _EmissionMap3Pan;
			float _EmissionMap3UV;
			#if defined(PROP_EMISSIONMASK3) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionMask3;
			#endif
			float4 _EmissionMask3_ST;
			float2 _EmissionMask3Pan;
			float _EmissionMask3UV;
			float _EmissionMask3Channel;
			float _EmissionMaskInvert3;
			float _EmissionMask3GlobalMask;
			float _EmissionMask3GlobalMaskBlendType;
			#if defined(PROP_EMISSIONSCROLLINGCURVE3) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionScrollingCurve3;
			#endif
			float4 _EmissionScrollingCurve3_ST;
			
			float4 _EmissionColor3;
			float _EmissionBaseColorAsMap3;
			float _EmissionStrength3;
			float _EnableEmission3;
			float _EmissionHueShift3;
			float _EmissionHueShiftSpeed3;
			float4 _EmissiveScroll_Direction3;
			float _EmissiveScroll_Width3;
			float _EmissiveScroll_Velocity3;
			float _EmissiveScroll_Interval3;
			float _EmissionBlinkingEnabled3;
			float _EmissiveBlink_Min3;
			float _EmissiveBlink_Max3;
			float _EmissiveBlink_Velocity3;
			float _ScrollingEmission3;
			float _EnableGITDEmission3;
			float _GITDEMinEmissionMultiplier3;
			float _GITDEMaxEmissionMultiplier3;
			float _GITDEMinLight3;
			float _GITDEMaxLight3;
			float _GITDEWorldOrMesh3;
			float _EmissionCenterOutEnabled3;
			float _EmissionCenterOutSpeed3;
			float _EmissionHueShiftEnabled3;
			float _EmissionSaturation3;
			float _EmissionBlinkingOffset3;
			float _EmissionScrollingOffset3;
			float _EmissionScrollingVertexColor3;
			float _EmissionScrollingUseCurve3;
			float _EmissionReplace3;
			float _EmissionColor3ThemeIndex;
			
			// Audio Link
			float _EmissionAL3Enabled;
			float2 _EmissionAL3StrengthMod;
			float _EmissionAL3StrengthBand;
			float2 _AudioLinkEmission3CenterOut;
			float _AudioLinkEmission3CenterOutSize;
			float _AudioLinkEmission3CenterOutBand;
			float _AudioLinkEmission3CenterOutDuration;
			float2 _EmissionAL3Multipliers;
			float _EmissionAL3MultipliersBand;
			#endif
			//endex
			
			//ifex _EnableRimLighting==0
			#ifdef _GLOSSYREFLECTIONS_OFF
			float _Is_NormalMapToRimLight;
			float4 _RimLightColor;
			float _RimLightColorThemeIndex;
			#ifdef _RIMSTYLE_POIYOMI
			float _RimLightingInvert;
			float _RimWidth;
			float _RimStrength;
			float _RimSharpness;
			float _RimBaseColorMix;
			float _EnableRimLighting;
			float _RimWidthNoiseStrength;
			float4 _RimShadowAlpha;
			float _RimShadowWidth;
			float _RimBlendStrength;
			float _RimPoiBlendMode;
			float _RimShadowToggle;
			float _RimPower;
			float _RimShadowMaskStrength;
			float _RimShadowMaskRampType;
			float _RimShadowMaskInvert;
			float _RimBrightness;
			#if defined(PROP_RIMTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RimTex;
			#endif
			float4 _RimTex_ST;
			float2 _RimTexPan;
			float _RimTexUV;
			#if defined(PROP_RIMMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RimMask;
			#endif
			float4 _RimMask_ST;
			float2 _RimMaskPan;
			float _RimMaskUV;
			float _RimMaskChannel;
			float _RimMaskInvert;
			float _RimBiasIntensity;
			int _RimApplyAlpha;
			float _RimApplyAlphaBlend;
			#ifdef POI_AUDIOLINK
			half _AudioLinkRimWidthBand;
			float2 _AudioLinkRimWidthAdd;
			half _AudioLinkRimEmissionBand;
			float2 _AudioLinkRimEmissionAdd;
			half _AudioLinkRimBrightnessBand;
			float2 _AudioLinkRimBrightnessAdd;
			#endif
			#endif
			
			#ifdef _RIMSTYLE_UTS2
			float _RimLight;
			float _Is_LightColor_RimLight;
			float _RimLight_Power;
			float _RimLight_InsideMask;
			float _RimLight_FeatherOff;
			float _LightDirection_MaskOn;
			float _Tweak_LightDirection_MaskLevel;
			float _Add_Antipodean_RimLight;
			float4 _Ap_RimLightColor;
			float _RimApColorThemeIndex;
			float _Is_LightColor_Ap_RimLight;
			float _Ap_RimLight_Power;
			float _Ap_RimLight_FeatherOff;
			#if defined(PROP_SET_RIMLIGHTMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Set_RimLightMask;
			float4 _Set_RimLightMask_ST;
			float2 _Set_RimLightMaskPan;
			float _Set_RimLightMaskUV;
			float _Set_RimLightMaskChannel;
			#endif
			float _Tweak_RimLightMaskLevel;
			#endif
			
			#ifdef _RIMSTYLE_LILTOON
			float4 _RimColor;
			#if defined(PROP_RIMCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RimColorTex;
			float4 _RimColorTex_ST;
			float2 _RimColorTexPan;
			float _RimColorTexUV;
			#endif
			float _RimMainStrength;
			float _RimNormalStrength;
			float _RimBorder;
			float _RimBlur;
			float _RimFresnelPower;
			float _RimEnableLighting;
			float _RimShadowMask;
			int _RimBackfaceMask;
			float _RimVRParallaxStrength;
			float _RimDirStrength;
			float _RimDirRange;
			float _RimIndirRange;
			float4 _RimIndirColor;
			float _RimIndirBorder;
			float _RimIndirBlur;
			int _RimBlendMode;
			#endif
			
			float _RimGlobalMask;
			float _RimGlobalMaskBlendType;
			float _RimApplyGlobalMaskIndex;
			float _RimApplyGlobalMaskBlendType;
			
			float _RimHueShiftEnabled;
			float _RimHueShiftSpeed;
			float _RimHueShift;
			#endif
			//endex
			//ifex _EnableRim2Lighting==0
			#ifdef POI_RIM2
			float _Is_NormalMapToRim2Light;
			float4 _Rim2LightColor;
			float _Rim2LightColorThemeIndex;
			
			#ifdef _RIM2STYLE_POIYOMI
			float _Rim2LightingInvert;
			float _Rim2Width;
			float _Rim2Strength;
			float _Rim2Sharpness;
			float _Rim2BaseColorMix;
			float _EnableRim2Lighting;
			float _Rim2WidthNoiseStrength;
			float4 _Rim2ShadowAlpha;
			float _Rim2ShadowWidth;
			float _Rim2BlendStrength;
			float _RimPoi2BlendMode;
			float _Rim2ShadowToggle;
			float _Rim2Power;
			float _Rim2ShadowMaskStrength;
			float _Rim2ShadowMaskRampType;
			float _Rim2ShadowMaskInvert;
			float _Rim2Brightness;
			#if defined(PROP_RIM2TEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Rim2Tex;
			#endif
			float4 _Rim2Tex_ST;
			float2 _Rim2TexPan;
			float _Rim2TexUV;
			#if defined(PROP_RIM2MASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Rim2Mask;
			#endif
			float4 _Rim2Mask_ST;
			float2 _Rim2MaskPan;
			float _Rim2MaskUV;
			float _Rim2MaskChannel;
			float _Rim2MaskInvert;
			float _Rim2BiasIntensity;
			int _Rim2ApplyAlpha;
			float _Rim2ApplyAlphaBlend;
			#if defined(PROP_RIM2WIDTHNOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Rim2WidthNoiseTexture;
			#endif
			#ifdef POI_AUDIOLINK
			half _AudioLinkRim2WidthBand;
			float2 _AudioLinkRim2WidthAdd;
			half _AudioLinkRim2EmissionBand;
			float2 _AudioLinkRim2EmissionAdd;
			half _AudioLinkRim2BrightnessBand;
			float2 _AudioLinkRim2BrightnessAdd;
			#endif
			#endif
			
			#ifdef _RIM2STYLE_UTS2
			float _Rim2Light;
			float _Is_LightColor_Rim2Light;
			float _Rim2Light_Power;
			float _Rim2Light_InsideMask;
			float _Rim2Light_FeatherOff;
			float _LightDirection_MaskOn2;
			float _Tweak_LightDirection_MaskLevel2;
			float _Add_Antipodean_Rim2Light;
			float4 _Ap_Rim2LightColor;
			float _Rim2ApColorThemeIndex;
			float _Is_LightColor_Ap_Rim2Light;
			float _Ap_Rim2Light_Power;
			float _Ap_Rim2Light_FeatherOff;
			#if defined(PROP_SET_RIM2LIGHTMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Set_Rim2LightMask;
			float4 _Set_Rim2LightMask_ST;
			float2 _Set_Rim2LightMaskPan;
			float _Set_Rim2LightMaskUV;
			float _Set_Rim2LightMaskChannel;
			#endif
			float _Tweak_Rim2LightMaskLevel;
			#endif
			
			#ifdef _RIM2STYLE_LILTOON
			float4 _Rim2Color;
			#if defined(PROP_RIM2COLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Rim2ColorTex;
			float4 _Rim2ColorTex_ST;
			float2 _Rim2ColorTexPan;
			float _Rim2ColorTexUV;
			#endif
			float _Rim2MainStrength;
			float _Rim2NormalStrength;
			float _Rim2Border;
			float _Rim2Blur;
			float _Rim2FresnelPower;
			float _Rim2EnableLighting;
			float _Rim2ShadowMask;
			int _Rim2BackfaceMask;
			float _Rim2VRParallaxStrength;
			// int _Rim2ApplyTransparency;
			float _Rim2DirStrength;
			float _Rim2DirRange;
			float _Rim2IndirRange;
			float4 _Rim2IndirColor;
			float _Rim2IndirBorder;
			float _Rim2IndirBlur;
			int _Rim2BlendMode;
			#endif
			
			float _Rim2GlobalMask;
			float _Rim2GlobalMaskBlendType;
			float _Rim2ApplyGlobalMaskIndex;
			float _Rim2ApplyGlobalMaskBlendType;
			
			float _Rim2HueShiftEnabled;
			float _Rim2HueShiftSpeed;
			float _Rim2HueShift;
			#endif
			//endex
			
			//ifex _EnableDepthRimLighting==0
			#ifdef _POI_DEPTH_RIMLIGHT
			float _DepthRimNormalToUse;
			float _DepthRimWidth;
			float _DepthRimSharpness;
			float _DepthRimHideInShadow;
			float4 _DepthRimColor;
			float _DepthRimColorThemeIndex;
			float _DepthRimMixBaseColor;
			float _DepthRimEmission;
			float _DepthRimReplace;
			float _DepthRimAdd;
			float _DepthRimMultiply;
			float _DepthRimAdditiveLighting;
			float _DepthRimMixLightColor;
			float _DepthRimType;
			float _DepthRimBrightness;
			
			static float2 sobelSamplePoints[9] = {
				float2(-1, 1), float2(0, 1), float2(1, 1),
				float2(-1, 0), float2(0, 0), float2(1, 01),
				float2(-1, -1), float2(0, -1), float2(1, -1)
			};
			
			static float sobelXMatrix[9] = {
				1, 0, -1,
				2, 0, -2,
				1, 0, -1
			};
			static float sobelYMatrix[9] = {
				1, 2, 1,
				0, 0, 0,
				- 1, -2, -1
			};
			#endif
			//endex
			
			//ifex _GlitterEnable==0
			#ifdef _SUNDISK_SIMPLE
			float4 _GlitterRandomRotationSpeed;
			float _GlitterLayers;
			float _GlitterUseNormals;
			float _GlitterUV;
			float4 _GlitterColor;
			float _GlitterColorThemeIndex;
			float2 _GlitterPan;
			half _GlitterSpeed;
			half _GlitterBrightness;
			float _GlitterFrequency;
			float _GlitterRandomLocation;
			half _GlitterSize;
			half _GlitterContrast;
			half _GlitterAngleRange;
			half _GlitterMinBrightness;
			half _GlitterBias;
			fixed _GlitterUseSurfaceColor;
			float _GlitterBlendType;
			float _GlitterMode;
			float _GlitterShape;
			float _GlitterCenterSize;
			float _GlitterJaggyFix;
			float _GlitterTextureRotation;
			float2 _GlitterUVPanning;
			
			float _GlitterHueShiftEnabled;
			float _GlitterHueShiftSpeed;
			float _GlitterHueShift;
			float _GlitterHideInShadow;
			float _GlitterScaleWithLighting;
			
			float _GlitterRandomColors;
			float2 _GlitterMinMaxSaturation;
			float2 _GlitterMinMaxBrightness;
			float _GlitterRandomSize;
			float4 _GlitterMinMaxSize;
			float _GlitterRandomRotation;
			
			#if defined(PROP_GLITTERMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlitterMask;
			#endif
			float4 _GlitterMask_ST;
			float2 _GlitterMaskPan;
			float _GlitterMaskUV;
			float _GlitterMaskChannel;
			float _GlitterMaskInvert;
			float _GlitterMaskGlobalMask;
			float _GlitterMaskGlobalMaskBlendType;
			#if defined(PROP_GLITTERCOLORMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlitterColorMap;
			#endif
			float4 _GlitterColorMap_ST;
			float2 _GlitterColorMapPan;
			float _GlitterColorMapUV;
			#if defined(PROP_GLITTERTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlitterTexture;
			#endif
			float4 _GlitterTexture_ST;
			float2 _GlitterTexturePan;
			float _GlitterTextureUV;
			
			float _GlitterALEnabled;
			float _GlitterALAlphaAddBand;
			float4 _GlitterALAlphaAdd;
			float _GlitterALMinBrightnessBand;
			float4 _GlitterALMinBrightnessAdd;
			float _GlitterALMaxBrightnessBand;
			float4 _GlitterALMaxBrightnessAdd;
			float _GlitterALSizeAddBand;
			float4 _GlitterALSizeAdd;
			float _GlitterALChronoSparkleSpeedType;
			float _GlitterALChronoSparkleSpeedBand;
			float _GlitterALChronoSparkleSpeed;
			float _GlitterALChronoRotationSpeedType;
			float _GlitterALChronoRotationSpeedBand;
			float _GlitterALChronoRotationSpeed;
			#endif
			//endex
			
			//ifex _SubsurfaceScattering==0
			#ifdef POI_SUBSURFACESCATTERING
			float4 _SSSColor;
			#if defined(PROP_SSSTHICKNESSMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _SSSThicknessMap;
			#endif
			float4 _SSSThicknessMap_ST;
			float2 _SSSThicknessMapPan;
			float _SSSThicknessMapUV;
			float _SSSThicknessMapChannel;
			
			float _SSSThicknessMod;
			float _SSSStrength;
			float _SSSSpread;
			float _SSSDistortion;
			float _SSSBaseColorMix;
			#endif
			//endex
			
			//ifex _MochieBRDF==0
			#ifdef MOCHIE_PBR
			#if defined(PROP_MOCHIEMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MochieMetallicMaps;
			float _PBRMapsStochastic;
			#endif
			float4 _MochieMetallicMaps_ST;
			float2 _MochieMetallicMapsPan;
			float _MochieMetallicMapsUV;
			float _MochieMetallicMapsStochastic;
			float _MochieMetallicMapInvert;
			float _MochieRoughnessMapInvert;
			float _MochieReflectionMaskInvert;
			float _MochieSpecularMaskInvert;
			float _MochieMetallicMapsMetallicChannel;
			float _MochieMetallicMapsRoughnessChannel;
			float _MochieMetallicMapsReflectionMaskChannel;
			float _MochieMetallicMapsSpecularMaskChannel;
			float _PBRNormalSelect;
			
			float _MochieReflectionTintThemeIndex;
			float _MochieSpecularTintThemeIndex;
			
			float _MochieRoughnessMultiplier;
			float _MochieMetallicMultiplier;
			float _MochieReflectionStrength;
			float _MochieSpecularStrength;
			float4 _MochieSpecularTint;
			float4 _MochieReflectionTint;
			float _MochieLitFallback;
			float _IgnoreCastedShadows;
			float _PBRSplitMaskSample;
			float _PBRSplitMaskStochastic;
			float4 _PBRMaskScaleTiling;
			float _MochieMetallicMasksUV;
			float4 _MochieMetallicMasksPan;
			
			float _Specular2ndLayer;
			float _MochieSpecularStrength2;
			float _MochieRoughnessMultiplier2;
			float _RefSpecFresnel;
			float _RefSpecFresnelBack;
			samplerCUBE _MochieReflCube;
			float4 _MochieReflCube_HDR;
			float _MochieForceFallback;
			float _MochieGSAAEnabled;
			float _PoiGSAAVariance;
			float _PoiGSAAThreshold;
			float _BRDFTPSReflectionMaskStrength;
			float _BRDFTPSSpecularMaskStrength;
			float _BRDFTPSDepthEnabled;
			
			float _MochieMetallicGlobalMask;
			float _MochieMetallicGlobalMaskBlendType;
			float _MochieSmoothnessGlobalMask;
			float _MochieSmoothnessGlobalMaskBlendType;
			float _MochieReflectionStrengthGlobalMask;
			float _MochieReflectionStrengthGlobalMaskBlendType;
			float _MochieSpecularStrengthGlobalMask;
			float _MochieSpecularStrengthGlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _ClearCoatBRDF==0
			#ifdef POI_CLEARCOAT
			#if defined(PROP_CLEARCOATMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ClearCoatMaps;
			float4 _ClearCoatMaps_ST;
			float2 _ClearCoatMapsPan;
			float _ClearCoatMapsUV;
			float _ClearCoatMapsStochastic;
			#endif
			float _ClearCoatMapsClearCoatMaskChannel;
			float _ClearCoatMapsRoughnessChannel;
			float _ClearCoatMapsReflectionMaskChannel;
			float _ClearCoatMapsSpecularMaskChannel;
			float _ClearCoatBRDF;
			float _ClearCoatReflectionStrength;
			float _ClearCoatSpecularStrength;
			float _ClearCoatStrength;
			float _ClearCoatSmoothness;
			float4 _ClearCoatReflectionTint;
			float _ClearCoatReflectionTintThemeIndex;
			float4 _ClearCoatSpecularTint;
			float _ClearCoatSpecularTintThemeIndex;
			float _ClearCoatSmoothnessMapInvert;
			float _ClearCoatMaskInvert;
			float _ClearCoatReflectionMaskInvert;
			float _ClearCoatSpecularMaskInvert;
			float _ClearCoatTPSMaskStrength;
			float _ClearCoatTPSDepthMaskEnabled;
			float _ClearCoatNormalSelect;
			
			samplerCUBE _ClearCoatFallback;
			float4 _ClearCoatFallback_HDR;
			float _ClearCoatForceFallback;
			float _ClearCoatLitFallback;
			float _CCIgnoreCastedShadows;
			float _ClearCoatGSAAEnabled;
			float _ClearCoatGSAAVariance;
			float _ClearCoatGSAAThreshold;
			float _ClearcoatFresnel;
			
			float _ClearCoatGlobalMask;
			float _ClearCoatGlobalMaskBlendType;
			float _ClearCoatSmoothnessGlobalMask;
			float _ClearCoatSmoothnessGlobalMaskBlendType;
			float _ClearCoatReflectionStrengthGlobalMask;
			float _ClearCoatReflectionStrengthGlobalMaskBlendType;
			float _ClearCoatSpecularStrengthGlobalMask;
			float _ClearCoatSpecularStrengthGlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _EnableEnvironmentalRim==0
			#ifdef POI_ENVIRORIM
			#if defined(PROP_RIMENVIROMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RimEnviroMask;
			#endif
			float4 _RimEnviroMask_ST;
			float2 _RimEnviroMaskPan;
			float _RimEnviroMaskUV;
			float _RimEnviroChannel;
			
			float _RimEnviroBlur;
			float _RimEnviroMinBrightness;
			float _RimEnviroWidth;
			float _RimEnviroSharpness;
			float _RimEnviroIntensity;
			#endif
			//endex
			
			//ifex _StylizedSpecular==0
			#ifdef POI_STYLIZED_StylizedSpecular
			#if defined(PROP_HIGHCOLOR_TEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _HighColor_Tex;
			#endif
			float4 _HighColor_Tex_ST;
			float2 _HighColor_TexPan;
			float _HighColor_TexUV;
			
			#if defined(PROP_SET_HIGHCOLORMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Set_HighColorMask;
			#endif
			float4 _Set_HighColorMask_ST;
			float2 _Set_HighColorMaskPan;
			float _Set_HighColorMaskUV;
			float _Set_HighColorMaskChannel;
			float _Tweak_HighColorMaskLevel;
			
			/*
			#if defined(PROP_StylizedSpecularOPTMAP1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _StylizedSpecularOptMap1;
			#endif
			float4 _StylizedSpecularOptMap1_ST;
			float2 _StylizedSpecularOptMap1Pan;
			float _StylizedSpecularOptMap1UV;
			
			#if defined(PROP_StylizedSpecularOPTMAP2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _StylizedSpecularOptMap2;
			#endif
			float4 _StylizedSpecularOptMap2_ST;
			float2 _StylizedSpecularOptMap2Pan;
			float _StylizedSpecularOptMap2UV;
			*/
			
			float4 _HighColor;
			float _UseLightColor;
			
			float _HighColor_Power;
			float _StylizedSpecularFeather;
			float _Layer1Strength;
			
			float _StylizedSpecularIgnoreNormal;
			float _StylizedSpecularIgnoreShadow;
			
			float _Layer2Size;
			float _StylizedSpecular2Feather;
			float _Layer2Strength;
			float _SSIgnoreCastedShadows;
			float _StylizedSpecularStrength;
			float _UseSpecularOptMap2;
			float _HighColorThemeIndex;
			float _Is_BlendAddToHiColor;
			float _Is_SpecularToHighColor;
			#endif
			//endex
			
			//ifex _EnablePathing==0
			#ifdef POI_PATHING
			
			#if defined(PROP_PATHINGMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _PathingMap;
			SamplerState SmpRepeatPoint;
			#endif
			float4 _PathingMap_ST;
			float2 _PathingMapPan;
			float _PathingMapUV;
			
			#if defined(PROP_PATHINGCOLORMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _PathingColorMap;
			#endif
			float4 _PathingColorMap_ST;
			float2 _PathingColorMapPan;
			float _PathingColorMapUV;
			float _PathingOverrideAlpha;
			// Fill, 0, Path, 1, Loop, 2
			float _PathTypeR;
			float _PathTypeG;
			float _PathTypeB;
			float _PathTypeA;
			float _PathGradientType;
			half4 _PathWidth;
			float4 _PathTime;
			float4 _PathOffset;
			float4 _PathSpeed;
			float4 _PathColorR;
			float4 _PathColorG;
			float4 _PathColorB;
			float4 _PathColorA;
			float4 _PathEmissionStrength;
			float4 _PathSoftness;
			float4 _PathSegments;
			
			float _PathColorRThemeIndex;
			float _PathColorGThemeIndex;
			float _PathColorBThemeIndex;
			float _PathColorAThemeIndex;
			
			#ifdef POI_AUDIOLINK
			float _PathALAutoCorrelator;
			float _PathALAutoCorrelatorMode;
			float _PathALAutoCorrelatorR;
			float2 _PathALAutoCorrelatorRangeR;
			float _PathALAutoCorrelatorG;
			float2 _PathALAutoCorrelatorRangeG;
			float _PathALAutoCorrelatorB;
			float2 _PathALAutoCorrelatorRangeB;
			float _PathALAutoCorrelatorA;
			float2 _PathALAutoCorrelatorRangeA;
			
			float _PathALHistory;
			float _PathALHistoryMode;
			float _PathALHistoryBandR;
			float2 _PathALHistoryRangeR;
			float _PathALHistoryR;
			float _PathALHistoryBandG;
			float2 _PathALHistoryRangeG;
			float _PathALHistoryG;
			float _PathALHistoryBandB;
			float2 _PathALHistoryRangeB;
			float _PathALHistoryB;
			float _PathALHistoryBandA;
			float2 _PathALHistoryRangeA;
			float _PathALHistoryA;
			
			float _PathALColorChord;
			float _PathALCCR;
			float _PathALCCG;
			float _PathALCCB;
			float _PathALCCA;
			
			// Time Offset
			float _PathALTimeOffset;
			half _AudioLinkPathTimeOffsetBandR;
			half2 _AudioLinkPathTimeOffsetR;
			half _AudioLinkPathTimeOffsetBandG;
			half2 _AudioLinkPathTimeOffsetG;
			half _AudioLinkPathTimeOffsetBandB;
			half2 _AudioLinkPathTimeOffsetB;
			half _AudioLinkPathTimeOffsetBandA;
			half2 _AudioLinkPathTimeOffsetA;
			
			// Emission Offset
			float _PathALEmissionOffset;
			half _AudioLinkPathEmissionAddBandR;
			half2 _AudioLinkPathEmissionAddR;
			half _AudioLinkPathEmissionAddBandG;
			half2 _AudioLinkPathEmissionAddG;
			half _AudioLinkPathEmissionAddBandB;
			half2 _AudioLinkPathEmissionAddB;
			half _AudioLinkPathEmissionAddBandA;
			half2 _AudioLinkPathEmissionAddA;
			
			// Length Offset
			float _PathALWidthOffset;
			half _AudioLinkPathWidthOffsetBandR;
			half2 _AudioLinkPathWidthOffsetR;
			half _AudioLinkPathWidthOffsetBandG;
			half2 _AudioLinkPathWidthOffsetG;
			half _AudioLinkPathWidthOffsetBandB;
			half2 _AudioLinkPathWidthOffsetB;
			half _AudioLinkPathWidthOffsetBandA;
			half2 _AudioLinkPathWidthOffsetA;
			
			// Chrono Time
			float _PathALChrono;
			float _PathChronoBandR;
			float _PathChronoTypeR;
			float _PathChronoSpeedR;
			float _PathChronoBandG;
			float _PathChronoTypeG;
			float _PathChronoSpeedG;
			float _PathChronoBandB;
			float _PathChronoTypeB;
			float _PathChronoSpeedB;
			float _PathChronoBandA;
			float _PathChronoTypeA;
			float _PathChronoSpeedA;
			#endif
			#endif
			//endex
			
			//ifex _EnableMirrorOptions==0
			#ifdef POI_MIRROR
			float _VisibilityMode;
			float _Mirror;
			#if defined(PROP_MIRRORTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MirrorTexture;
			#endif
			float4 _MirrorColor;
			float _MirrorColorThemeIndex;
			float _MirrorTextureBlendType;
			float4 _MirrorTexture_ST;
			float2 _MirrorTexturePan;
			float _MirrorTextureUV;
			float _MirrorTextureEnabled;
			float _MirrorTextureForceEnabled;
			float _VisibilityVRCRegular;
			float _VisibilityVRCMirrorVR;
			float _VisibilityVRCMirrorDesktop;
			float _VisibilityVRCCameraVR;
			float _VisibilityVRCCameraDesktop;
			float _VisibilityVRCCameraScreenshot;
			#endif
			//endex
			
			//ifex _EnableTouchGlow==0
			#ifdef GRAIN
			#if defined(PROP_DEPTHMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DepthMask;
			#endif
			float4 _DepthMask_ST;
			float2 _DepthMaskPan;
			float _DepthMaskUV;
			float _DepthMaskChannel;
			float _DepthMaskGlobalMask;
			float _DepthMaskGlobalMaskBlendType;
			
			// Color
			float _DepthColorToggle;
			float _DepthColorBlendMode;
			#if defined(PROP_DEPTHTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DepthTexture;
			#endif
			float4 _DepthTexture_ST;
			float2 _DepthTexturePan;
			float _DepthTextureUV;
			
			float3 _DepthColor;
			float _DepthColorThemeIndex;
			float _DepthColorMinDepth;
			float _DepthColorMaxDepth;
			float _DepthColorMinValue;
			float _DepthColorMaxValue;
			float _DepthEmissionStrength;
			
			// Emission
			
			// Alpha
			float _DepthAlphaToggle;
			float _DepthAlphaMinValue;
			float _DepthAlphaMaxValue;
			float _DepthAlphaMinDepth;
			float _DepthAlphaMaxDepth;
			#endif
			//endex
			
			float _PPLightingMultiplier;
			float _PPLightingAddition;
			float _PPEmissionMultiplier;
			float _PPFinalColorMultiplier;
			
			//ifex _TextEnabled==0
			#ifdef EFFECT_BUMP
			sampler2D _TextGlyphs;
			float4 _TextGlyphs_ST;
			float4 _TextGlyphs_TexelSize;
			float _TextFPSUV;
			float _TextTimeUV;
			float _TextPositionUV;
			float _TextNumericUV;
			float _TextPixelRange;
			
			float _TextFPSEnabled;
			float _TextPositionEnabled;
			float _TextTimeEnabled;
			float _TextNumericEnabled;
			
			float4 _TextFPSColor;
			float _TextFPSEmissionStrength;
			fixed4 _TextFPSPadding;
			float2 _TextFPSOffset;
			float2 _TextFPSScale;
			float _TextFPSRotation;
			float _TextFPSOutlineColor;
			
			fixed _TextPositionVertical;
			float4 _TextPositionColor;
			float _TextPositionEmissionStrength;
			fixed4 _TextPositionPadding;
			float2 _TextPositionOffset;
			float2 _TextPositionScale;
			float _TextPositionRotation;
			
			float4 _TextTimeColor;
			float _TextTimeEmissionStrength;
			fixed4 _TextTimePadding;
			float2 _TextTimeOffset;
			float2 _TextTimeScale;
			float _TextTimeRotation;
			
			float4 _TextNumericColor;
			float _TextNumericEmissionStrength;
			fixed4 _TextNumericPadding;
			float2 _TextNumericOffset;
			float2 _TextNumericScale;
			float _TextNumericRotation;
			float _TextNumericValue;
			float _TextNumericWholeDigits;
			float _TextNumericDecimalDigits;
			float _TextNumericTrimZeroes;
			
			float _TextFPSColorThemeIndex;
			float _TextPositionColorThemeIndex;
			float _TextTimeColorThemeIndex;
			float _TextNumericColorThemeIndex;
			
			float3 globalTextEmission;
			
			#define ASCII_SPACE 32
			#define ASCII_LEFT_PARENTHESIS 40
			#define ASCII_RIGHT_PARENTHESIS 41
			#define ASCII_POSITIVE 43
			#define ASCII_PERIOD 46
			#define ASCII_NEGATIVE 45
			#define ASCII_COMMA 44
			#define ASCII_E 69
			#define ASCII_F 70
			#define ASCII_I 73
			#define ASCII_M 77
			#define ASCII_O 79
			#define ASCII_P 80
			#define ASCII_R 82
			#define ASCII_S 83
			#define ASCII_T 84
			#define ASCII_SEMICOLON 58
			#define glyphWidth 0.0625
			
			#endif
			//endex
			
			//ifex _FXProximityColor==0
			float _FXProximityColor;
			float _FXProximityColorType;
			float3 _FXProximityColorMinColor;
			float3 _FXProximityColorMaxColor;
			float _FXProximityColorMinColorThemeIndex;
			float _FXProximityColorMaxColorThemeIndex;
			float _FXProximityColorMinDistance;
			float _FXProximityColorMaxDistance;
			float _FXProximityColorBackFace;
			//endex
			
			//ifex _PostProcess==0
			#ifdef POSTPROCESS
			#if defined(PROP_PPMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _PPMask;
			#endif
			float4 _PPMask_ST;
			float2 _PPMaskPan;
			float _PPMaskUV;
			float _PPMaskChannel;
			float _PPMaskInvert;
			
			float3 _PPTint;
			float3 _PPRGB;
			float _PPHue;
			float _PPContrast;
			float _PPSaturation;
			float _PPBrightness;
			float _PPLightness;
			float _PPHDR;
			
			float _PPPosterization;
			float _PPPosterizationAmount;
			const static float COLORS = 32;
			
			#endif
			//endex
			
			//ifex _PoiInternalParallax==0
			#ifdef POI_INTERNALPARALLAX
			#if defined(PROP_PARALLAXINTERNALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ParallaxInternalMap;
			#endif
			float4 _ParallaxInternalMap_ST;
			float2 _ParallaxInternalMapPan;
			
			#if defined(PROP_PARALLAXINTERNALMAPMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ParallaxInternalMapMask;
			#endif
			float4 _ParallaxInternalMapMask_ST;
			float2 _ParallaxInternalMapMaskPan;
			float _ParallaxInternalMapMaskUV;
			float _ParallaxInternalMapMaskChannel;
			
			float _ParallaxInternalIterations;
			float _ParallaxInternalMinDepth;
			float _ParallaxInternalMaxDepth;
			float _ParallaxInternalMinFade;
			float _ParallaxInternalMaxFade;
			float4 _ParallaxInternalMinColor;
			float4 _ParallaxInternalMaxColor;
			float _ParallaxInternalMinColorThemeIndex;
			float _ParallaxInternalMaxColorThemeIndex;
			// float4 _ParallaxInternalPanSpeed;
			float4 _ParallaxInternalPanDepthSpeed;
			float _ParallaxInternalHeightmapMode;
			float _ParallaxInternalHeightFromAlpha;
			
			float _ParallaxInternalHueShiftEnabled;
			float _ParallaxInternalHueShift;
			float _ParallaxInternalHueShiftSpeed;
			float _ParallaxInternalHueShiftPerLevel;
			float _ParallaxInternalSurfaceBlendMode;
			float _ParallaxInternalBlendMode;
			// float _ParallaxInternalHueShiftPerLevelSpeed;
			#endif
			//endex
			
			//ifex _NormalCorrect==0
			#ifdef POI_NORMALCORRECT
			float _NormalCorrectAmount;
			float3 _NormalCorrectOrigin;
			#endif
			//endex
			
			//ifex _VideoEffectsEnable==0
			#ifdef POI_VIDEO_EFFECTS
			float _VideoEffectsEnable;
			#if defined(PROP_VIDEOPIXELTEXTURE) || !defined(OPTIMIZER_ENABLED)
			sampler2D _VideoPixelTexture;
			float4 _VideoPixelTexture_ST;
			float _VideoPixelTextureUV;
			#endif
			#if defined(PROP_VIDEOMASKTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VideoMaskTexture;
			float4 _VideoMaskTexture_ST;
			float2 _VideoMaskTexturePan;
			float _VideoMaskTextureUV;
			float _VideoMaskTextureChannel;
			#endif
			
			float _VideoType;
			float2 _VideoResolution;
			sampler2D _VideoGameboyRamp;
			float _VideoBacklight;
			float _VideoCRTRefreshRate;
			float _VideoCRTPixelEnergizedTime;
			float _VideoRepeatVideoTexture;
			float _VideoPixelateToResolution;
			float2 _VideoMaskPanning;
			
			float _VideoSaturation;
			float _VideoContrast;
			float _VideoEmissionEnabled;
			#endif
			//endex
			
			//ifex _BacklightEnabled!=1
			#ifdef POI_BACKLIGHT
			float4 _BacklightColor;
			#if defined(PROP_BACKLIGHTCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BacklightColorTex;
			float4 _BacklightColorTex_ST;
			float2 _BacklightColorTexPan;
			float _BacklightColorTexUV;
			#endif
			float _BacklightMainStrength;
			float _BacklightNormalStrength;
			float _BacklightBorder;
			float _BacklightBlur;
			float _BacklightDirectivity;
			float _BacklightViewStrength;
			int _BacklightReceiveShadow;
			int _BacklightBackfaceMask;
			#endif
			//endex
			
			//ifex _BSSEnabled!=1
			#ifdef POIBS_ENABLE
			float _CustomColors;
			//ifex _BSSBloomfog!=1
			#ifdef POIBS_BLOOMFOG
			float _FogStartOffset;
			float _FogScale;
			float _FogHeightOffset;
			float _FogHeightScale;
			
			uniform float2 _CustomFogTextureToScreenRatio;
			uniform float _StereoCameraEyeOffset;
			
			uniform float _CustomFogOffset;
			uniform float _CustomFogAttenuation;
			uniform float _CustomFogHeightFogStartY;
			uniform float _CustomFogHeightFogHeight;
			uniform sampler2D _BloomPrePassTexture;
			#endif
			//endex
			#endif
			//endex
			
			//ifex _VoronoiEnabled!=1
			#ifdef POI_VORONOI
			#if defined(PROP_VORONOIMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VoronoiMask;
			float4 _VoronoiMask_ST;
			float2 _VoronoiMaskPan;
			float _VoronoiMaskUV;
			int _VoronoiMaskChannel;
			#endif
			#if defined(PROP_VORONOINOISE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VoronoiNoise;
			float4 _VoronoiNoise_ST;
			float2 _VoronoiNoisePan;
			float _VoronoiNoiseUV;
			int _VoronoiNoiseChannel;
			#endif
			int _VoronoiSpace;
			int _VoronoiBlend;
			int _VoronoiType;
			float4 _VoronoiOuterColor;
			float _VoronoiOuterEmissionStrength;
			float4 _VoronoiInnerColor;
			float _VoronoiInnerEmissionStrength;
			float _VoronoiPower;
			float2 _VoronoiGradient;
			float _VoronoiScale;
			float3 _VoronoiSpeed;
			float _VoronoiEnableRandomCellColor;
			float2 _VoronoiRandomMinMaxSaturation;
			float2 _VoronoiRandomMinMaxBrightness;
			float _VoronoiNoiseIntensity;
			int _VoronoiAffectsMaterialAlpha;
			float _VoronoiGlobalMask;
			float _VoronoiGlobalMaskBlendType;
			
			// AudioLink
			int _AudioLinkVoronoiInnerEmissionBand;
			float2 _AudioLinkVoronoiInnerEmission;
			int _AudioLinkVoronoiOuterEmissionBand;
			float2 _AudioLinkVoronoiOuterEmission;
			
			int _AudioLinkVoronoiGradientMinAddBand;
			float _AudioLinkVoronoiGradientMinAdd;
			int _AudioLinkVoronoiGradientMaxAddBand;
			float _AudioLinkVoronoiGradientMaxAdd;
			
			int _AudioLinkVoronoiChronoSpeedXType;
			int _AudioLinkVoronoiChronoSpeedXBand;
			float _AudioLinkVoronoiChronoSpeedXSpeed;
			int _AudioLinkVoronoiChronoSpeedYType;
			int _AudioLinkVoronoiChronoSpeedYBand;
			float _AudioLinkVoronoiChronoSpeedYSpeed;
			int _AudioLinkVoronoiChronoSpeedZType;
			int _AudioLinkVoronoiChronoSpeedZBand;
			float _AudioLinkVoronoiChronoSpeedZSpeed;
			#endif
			//endex
			
			struct appdata
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 tangent : TANGENT;
				float4 color : COLOR;
				float2 uv0 : TEXCOORD0;
				float2 uv1 : TEXCOORD1;
				float2 uv2 : TEXCOORD2;
				float2 uv3 : TEXCOORD3;
				uint vertexId : SV_VertexID;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};
			
			struct VertexOut
			{
				float4 pos : SV_POSITION;
				float4 uv[2] : TEXCOORD0;
				float3 normal : TEXCOORD2;
				float4 tangent : TEXCOORD3;
				float4 worldPos : TEXCOORD4;
				float4 localPos : TEXCOORD5;
				float4 vertexColor : TEXCOORD6;
				float4 lightmapUV : TEXCOORD7;
				float2 fogCoord: TEXCOORD10;
				UNITY_SHADOW_COORDS(11)
				
				UNITY_VERTEX_INPUT_INSTANCE_ID
				UNITY_VERTEX_OUTPUT_STEREO
			};
			
			struct PoiMesh
			{
				
				// 0 Vertex normal
				// 1 Fragment normal
				float3 normals[2];
				float3 objNormal;
				float3 tangentSpaceNormal;
				float3 binormal[2];
				float3 tangent[2];
				float3 worldPos;
				float3 localPos;
				float3 objectPosition;
				float isFrontFace;
				float4 vertexColor;
				float4 lightmapUV;
				// 0-3 UV0-UV3
				// 4 Panosphere UV
				// 5 world pos xz
				// 6 Polar UV
				// 7 Distorted UV
				float2 uv[9];
				float2 parallaxUV;
				float2 dx;
				float2 dy;
			};
			
			struct PoiCam
			{
				float3 viewDir;
				float3 forwardDir;
				float3 worldPos;
				float distanceToVert;
				float4 clipPos;
				float4 screenSpacePosition;
				float3 reflectionDir;
				float3 vertexReflectionDir;
				float3 tangentViewDir;
				float4 posScreenSpace;
				float2 posScreenPixels;
				float2 screenUV;
				float vDotN;
				float4 worldDirection;
				
			};
			
			struct PoiMods
			{
				float4 Mask;
				float audioLink[5];
				float audioLinkAvailable;
				float audioLinkVersion;
				float4 audioLinkTexture;
				float2 detailMask;
				float2 backFaceDetailIntensity;
				float globalEmission;
				float4 globalColorTheme[12];
				float globalMask[16];
				float ALTime[8];
			};
			
			struct PoiLight
			{
				
				float3 direction;
				float attenuation;
				float attenuationStrength;
				float3 directColor;
				float3 indirectColor;
				float occlusion;
				float shadowMask;
				float detailShadow;
				float3 halfDir;
				float lightMap;
				float lightMapNoAttenuation;
				float3 rampedLightMap;
				float vertexNDotL;
				float nDotL;
				float nDotV;
				float vertexNDotV;
				float nDotH;
				float vertexNDotH;
				float lDotv;
				float lDotH;
				float nDotLSaturated;
				float nDotLNormalized;
				#ifdef POI_PASS_ADD
				float additiveShadow;
				#endif
				float3 finalLighting;
				float3 finalLightAdd;
				float3 LTCGISpecular;
				float3 LTCGIDiffuse;
				float directLuminance;
				float indirectLuminance;
				float finalLuminance;
				
				#if defined(VERTEXLIGHT_ON)
				// Non Important Lights
				float4 vDotNL;
				float4 vertexVDotNL;
				float3 vColor[4];
				float4 vCorrectedDotNL;
				float4 vAttenuation;
				float4 vSaturatedDotNL;
				float3 vPosition[4];
				float3 vDirection[4];
				float3 vFinalLighting;
				float3 vHalfDir[4];
				half4 vDotNH;
				half4 vertexVDotNH;
				half4 vDotLH;
				#endif
				
			};
			
			struct PoiVertexLights
			{
				
				float3 direction;
				float3 color;
				float attenuation;
			};
			
			struct PoiFragData
			{
				float smoothness;
				float smoothness2;
				float metallic;
				float specularMask;
				float reflectionMask;
				
				float3 baseColor;
				float3 finalColor;
				float alpha;
				float3 emission;
				float toggleVertexLights;
			};
			
			float4 poiTransformClipSpacetoScreenSpaceFrag(float4 clipPos)
			{
				float4 positionSS = float4(clipPos.xyz * clipPos.w, clipPos.w);
				positionSS.xy = positionSS.xy / _ScreenParams.xy;
				return positionSS;
			}
			
			// glsl_mod behaves better on negative numbers, and
			// in some situations actually outperforms HLSL's fmod()
			#ifndef glsl_mod
			#define glsl_mod(x, y) (((x) - (y) * floor((x) / (y))))
			#endif
			
			uniform float random_uniform_float_only_used_to_stop_compiler_warnings = 0.0f;
			
			float2 poiUV(float2 uv, float4 tex_st)
			{
				return uv * tex_st.xy + tex_st.zw;
			}
			
			float2 vertexUV(in VertexOut o, int index)
			{
				switch(index)
				{
					case 0:
					return o.uv[0].xy;
					case 1:
					return o.uv[0].zw;
					case 2:
					return o.uv[1].xy;
					case 3:
					return o.uv[1].zw;
					default:
					return o.uv[0].xy;
				}
			}
			
			float2 vertexUV(in appdata v, int index)
			{
				switch(index)
				{
					case 0:
					return v.uv0.xy;
					case 1:
					return v.uv1.xy;
					case 2:
					return v.uv2.xy;
					case 3:
					return v.uv3.xy;
					default:
					return v.uv0.xy;
				}
			}
			
			//Lighting Helpers
			float calculateluminance(float3 color)
			{
				return color.r * 0.299 + color.g * 0.587 + color.b * 0.114;
			}
			
			// Set by VRChat (as of open beta 1245)
			// _VRChatCameraMode: 0 => Normal, 1 => VR HandCam, 2 => Desktop Handcam, 3 => Screenshot/Photo
			// _VRChatMirrorMode: 0 => Normal, 1 => Mirror (VR), 2 => Mirror (Deskie)
			float _VRChatCameraMode;
			float _VRChatMirrorMode;
			
			float VRCCameraMode()
			{
				return _VRChatCameraMode;
			}
			
			float VRCMirrorMode()
			{
				return _VRChatMirrorMode;
			}
			
			bool IsInMirror()
			{
				return unity_CameraProjection[2][0] != 0.f || unity_CameraProjection[2][1] != 0.f;
			}
			
			bool IsOrthographicCamera()
			{
				return unity_OrthoParams.w == 1 || UNITY_MATRIX_P[3][3] == 1;
			}
			
			float shEvaluateDiffuseL1Geomerics_local(float L0, float3 L1, float3 n)
			{
				// average energy
				float R0 = max(0, L0);
				
				// avg direction of incoming light
				float3 R1 = 0.5f * L1;
				
				// directional brightness
				float lenR1 = length(R1);
				
				// linear angle between normal and direction 0-1
				//float q = 0.5f * (1.0f + dot(R1 / lenR1, n));
				//float q = dot(R1 / lenR1, n) * 0.5 + 0.5;
				float q = dot(normalize(R1), n) * 0.5 + 0.5;
				q = saturate(q); // Thanks to ScruffyRuffles for the bug identity.
				
				// power for q
				// lerps from 1 (linear) to 3 (cubic) based on directionality
				float p = 1.0f + 2.0f * lenR1 / R0;
				
				// dynamic range constant
				// should vary between 4 (highly directional) and 0 (ambient)
				float a = (1.0f - lenR1 / R0) / (1.0f + lenR1 / R0);
				
				return R0 * (a + (1.0f - a) * (p + 1.0f) * pow(q, p));
			}
			
			half3 BetterSH9(half4 normal)
			{
				float3 indirect;
				float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) + float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0;
				indirect.r = shEvaluateDiffuseL1Geomerics_local(L0.r, unity_SHAr.xyz, normal.xyz);
				indirect.g = shEvaluateDiffuseL1Geomerics_local(L0.g, unity_SHAg.xyz, normal.xyz);
				indirect.b = shEvaluateDiffuseL1Geomerics_local(L0.b, unity_SHAb.xyz, normal.xyz);
				indirect = max(0, indirect);
				indirect += SHEvalLinearL2(normal);
				return indirect;
			}
			
			// Silent's code ends here
			
			float3 getCameraForward()
			{
				#if UNITY_SINGLE_PASS_STEREO
				float3 p1 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 1, 1));
				float3 p2 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 0, 1));
				#else
				float3 p1 = mul(unity_CameraToWorld, float4(0, 0, 1, 1)).xyz;
				float3 p2 = mul(unity_CameraToWorld, float4(0, 0, 0, 1)).xyz;
				#endif
				return normalize(p2 - p1);
			}
			
			half3 GetSHLength()
			{
				half3 x, x1;
				x.r = length(unity_SHAr);
				x.g = length(unity_SHAg);
				x.b = length(unity_SHAb);
				x1.r = length(unity_SHBr);
				x1.g = length(unity_SHBg);
				x1.b = length(unity_SHBb);
				return x + x1;
			}
			
			float3 BoxProjection(float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax)
			{
				#if UNITY_SPECCUBE_BOX_PROJECTION
				//UNITY_BRANCH
				if (cubemapPosition.w > 0)
				{
					float3 factors = ((direction > 0 ? boxMax : boxMin) - position) / direction;
					float scalar = min(min(factors.x, factors.y), factors.z);
					direction = direction * scalar + (position - cubemapPosition.xyz);
				}
				#endif
				return direction;
			}
			
			float poiMax(float2 i)
			{
				return max(i.x, i.y);
			}
			
			float poiMax(float3 i)
			{
				return max(max(i.x, i.y), i.z);
			}
			
			float poiMax(float4 i)
			{
				return max(max(max(i.x, i.y), i.z), i.w);
			}
			
			float3 calculateNormal(in float3 baseNormal, in PoiMesh poiMesh, in Texture2D normalTexture, in float4 normal_ST, in float2 normalPan, in float normalUV, in float normalIntensity)
			{
				float3 normal = UnpackScaleNormal(POI2D_SAMPLER_PAN(normalTexture, _MainTex, poiUV(poiMesh.uv[normalUV], normal_ST), normalPan), normalIntensity);
				return normalize(
				normal.x * poiMesh.tangent[0] +
				normal.y * poiMesh.binormal[0] +
				normal.z * baseNormal
				);
			}
			
			float remap(float x, float minOld, float maxOld, float minNew = 0, float maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float2 remap(float2 x, float2 minOld, float2 maxOld, float2 minNew = 0, float2 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float3 remap(float3 x, float3 minOld, float3 maxOld, float3 minNew = 0, float3 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float4 remap(float4 x, float4 minOld, float4 maxOld, float4 minNew = 0, float4 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float remapClamped(float minOld, float maxOld, float x, float minNew = 0, float maxNew = 1)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float2 remapClamped(float2 minOld, float2 maxOld, float2 x, float2 minNew, float2 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float3 remapClamped(float3 minOld, float3 maxOld, float3 x, float3 minNew, float3 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float4 remapClamped(float4 minOld, float4 maxOld, float4 x, float4 minNew, float4 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			float2 calcParallax(in float height, in PoiCam poiCam)
			{
				return ((height * - 1) + 1) * (poiCam.tangentViewDir.xy / poiCam.tangentViewDir.z);
			}
			
			/*
			0: Zero	                float4(0.0, 0.0, 0.0, 0.0),
			1: One	                float4(1.0, 1.0, 1.0, 1.0),
			2: DstColor	            destinationColor,
			3: SrcColor	            sourceColor,
			4: OneMinusDstColor	    float4(1.0, 1.0, 1.0, 1.0) - destinationColor,
			5: SrcAlpha	            sourceColor.aaaa,
			6: OneMinusSrcColor	    float4(1.0, 1.0, 1.0, 1.0) - sourceColor,
			7: DstAlpha	            destinationColor.aaaa,
			8: OneMinusDstAlpha	    float4(1.0, 1.0, 1.0, 1.0) - destinationColor.,
			9: SrcAlphaSaturate     saturate(sourceColor.aaaa),
			10: OneMinusSrcAlpha	float4(1.0, 1.0, 1.0, 1.0) - sourceColor.aaaa,
			*/
			
			float4 poiBlend(const float sourceFactor, const  float4 sourceColor, const  float destinationFactor, const  float4 destinationColor, const float4 blendFactor)
			{
				float4 sA = 1 - blendFactor;
				const float4 blendData[11] = {
					float4(0.0, 0.0, 0.0, 0.0),
					float4(1.0, 1.0, 1.0, 1.0),
					destinationColor,
					sourceColor,
					float4(1.0, 1.0, 1.0, 1.0) - destinationColor,
					sA,
					float4(1.0, 1.0, 1.0, 1.0) - sourceColor,
					sA,
					float4(1.0, 1.0, 1.0, 1.0) - sA,
					saturate(sourceColor.aaaa),
					1 - sA,
				};
				
				return lerp(blendData[sourceFactor] * sourceColor + blendData[destinationFactor] * destinationColor, sourceColor, sA);
			}
			
			// Average
			float blendAverage(float base, float blend)
			{
				return (base + blend) / 2.0;
			}
			float3 blendAverage(float3 base, float3 blend)
			{
				return (base + blend) / 2.0;
			}
			
			// Color burn
			float blendColorBurn(float base, float blend)
			{
				return (blend == 0.0) ? blend : max((1.0 - ((1.0 - base) * rcp(random_uniform_float_only_used_to_stop_compiler_warnings + blend))), 0.0);
			}
			
			float3 blendColorBurn(float3 base, float3 blend)
			{
				return float3(blendColorBurn(base.r, blend.r), blendColorBurn(base.g, blend.g), blendColorBurn(base.b, blend.b));
			}
			
			// Color Dodge
			float blendColorDodge(float base, float blend)
			{
				return (blend == 1.0) ? blend : min(base / (1.0 - blend), 1.0);
			}
			
			float3 blendColorDodge(float3 base, float3 blend)
			{
				return float3(blendColorDodge(base.r, blend.r), blendColorDodge(base.g, blend.g), blendColorDodge(base.b, blend.b));
			}
			
			// Darken
			float blendDarken(float base, float blend)
			{
				return min(blend, base);
			}
			
			float3 blendDarken(float3 base, float3 blend)
			{
				return float3(blendDarken(base.r, blend.r), blendDarken(base.g, blend.g), blendDarken(base.b, blend.b));
			}
			
			// Exclusion
			float blendExclusion(float base, float blend)
			{
				return base + blend - 2.0 * base * blend;
			}
			float3 blendExclusion(float3 base, float3 blend)
			{
				return base + blend - 2.0 * base * blend;
			}
			
			// Reflect
			float blendReflect(float base, float blend)
			{
				return (blend == 1.0) ? blend : min(base * base / (1.0 - blend), 1.0);
			}
			
			float3 blendReflect(float3 base, float3 blend)
			{
				return float3(blendReflect(base.r, blend.r), blendReflect(base.g, blend.g), blendReflect(base.b, blend.b));
			}
			
			// Glow
			float blendGlow(float base, float blend)
			{
				return blendReflect(blend, base);
			}
			float3 blendGlow(float3 base, float3 blend)
			{
				return blendReflect(blend, base);
			}
			
			// Overlay
			float blendOverlay(float base, float blend)
			{
				return base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend));
			}
			
			float3 blendOverlay(float3 base, float3 blend)
			{
				return float3(blendOverlay(base.r, blend.r), blendOverlay(base.g, blend.g), blendOverlay(base.b, blend.b));
			}
			
			// Hard Light
			float blendHardLight(float base, float blend)
			{
				return blendOverlay(blend, base);
			}
			float3 blendHardLight(float3 base, float3 blend)
			{
				return blendOverlay(blend, base);
			}
			
			// Vivid light
			float blendVividLight(float base, float blend)
			{
				return (blend < 0.5) ? blendColorBurn(base, (2.0 * blend)) : blendColorDodge(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendVividLight(float3 base, float3 blend)
			{
				return float3(blendVividLight(base.r, blend.r), blendVividLight(base.g, blend.g), blendVividLight(base.b, blend.b));
			}
			
			// Hard mix
			float blendHardMix(float base, float blend)
			{
				return (blendVividLight(base, blend) < 0.5) ? 0.0 : 1.0;
			}
			
			float3 blendHardMix(float3 base, float3 blend)
			{
				return float3(blendHardMix(base.r, blend.r), blendHardMix(base.g, blend.g), blendHardMix(base.b, blend.b));
			}
			
			// Lighten
			float blendLighten(float base, float blend)
			{
				return max(blend, base);
			}
			
			float3 blendLighten(float3 base, float3 blend)
			{
				return float3(blendLighten(base.r, blend.r), blendLighten(base.g, blend.g), blendLighten(base.b, blend.b));
			}
			
			// Linear Burn
			float blendLinearBurn(float base, float blend)
			{
				// Note : Same implementation as BlendSubtractf
				return max(base + blend - 1.0, 0.0);
			}
			
			float3 blendLinearBurn(float3 base, float3 blend)
			{
				// Note : Same implementation as BlendSubtract
				return max(base + blend - float3(1.0, 1.0, 1.0), float3(0.0, 0.0, 0.0));
			}
			
			// Linear Dodge
			float blendLinearDodge(float base, float blend)
			{
				// Note : Same implementation as BlendAddf
				return min(base + blend, 1.0);
			}
			
			float3 blendLinearDodge(float3 base, float3 blend)
			{
				// Note : Same implementation as BlendAdd
				return base + blend;
			}
			
			// Linear light
			float blendLinearLight(float base, float blend)
			{
				return blend < 0.5 ? blendLinearBurn(base, (2.0 * blend)) : blendLinearDodge(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendLinearLight(float3 base, float3 blend)
			{
				return float3(blendLinearLight(base.r, blend.r), blendLinearLight(base.g, blend.g), blendLinearLight(base.b, blend.b));
			}
			
			// Multiply
			float blendMultiply(float base, float blend)
			{
				return base * blend;
			}
			float3 blendMultiply(float3 base, float3 blend)
			{
				return base * blend;
			}
			
			// Negation
			float blendNegation(float base, float blend)
			{
				return 1.0 - abs(1.0 - base - blend);
			}
			float3 blendNegation(float3 base, float3 blend)
			{
				return float3(1.0, 1.0, 1.0) - abs(float3(1.0, 1.0, 1.0) - base - blend);
			}
			
			// Normal
			float blendNormal(float base, float blend)
			{
				return blend;
			}
			float3 blendNormal(float3 base, float3 blend)
			{
				return blend;
			}
			
			// Phoenix
			float blendPhoenix(float base, float blend)
			{
				return min(base, blend) - max(base, blend) + 1.0;
			}
			float3 blendPhoenix(float3 base, float3 blend)
			{
				return min(base, blend) - max(base, blend) + float3(1.0, 1.0, 1.0);
			}
			
			// Pin light
			float blendPinLight(float base, float blend)
			{
				return (blend < 0.5) ? blendDarken(base, (2.0 * blend)) : blendLighten(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendPinLight(float3 base, float3 blend)
			{
				return float3(blendPinLight(base.r, blend.r), blendPinLight(base.g, blend.g), blendPinLight(base.b, blend.b));
			}
			
			// Screen
			float blendScreen(float base, float blend)
			{
				return 1.0 - ((1.0 - base) * (1.0 - blend));
			}
			
			float3 blendScreen(float3 base, float3 blend)
			{
				return float3(blendScreen(base.r, blend.r), blendScreen(base.g, blend.g), blendScreen(base.b, blend.b));
			}
			
			// Soft Light
			float blendSoftLight(float base, float blend)
			{
				return (blend < 0.5) ? (2.0 * base * blend + base * base * (1.0 - 2.0 * blend)) : (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend));
			}
			
			float3 blendSoftLight(float3 base, float3 blend)
			{
				return float3(blendSoftLight(base.r, blend.r), blendSoftLight(base.g, blend.g), blendSoftLight(base.b, blend.b));
			}
			
			// Subtract
			float blendSubtract(float base, float blend)
			{
				return max(base - blend, 0.0);
			}
			
			float3 blendSubtract(float3 base, float3 blend)
			{
				return max(base - blend, 0.0);
			}
			
			// Difference
			float blendDifference(float base, float blend)
			{
				return abs(base - blend);
			}
			
			float3 blendDifference(float3 base, float3 blend)
			{
				return abs(base - blend);
			}
			
			// Divide
			float blendDivide(float base, float blend)
			{
				return base / max(blend, 0.0001);
			}
			
			float3 blendDivide(float3 base, float3 blend)
			{
				return base / max(blend, 0.0001);
			}
			
			float blendMixed(float base, float blend)
			{
				return base + base * blend;
			}
			
			float3 blendMixed(float3 base, float3 blend)
			{
				return base + base * blend;
			}
			
			float3 customBlend(float3 base, float3 blend, float blendType, float alpha = 1)
			{
				float3 output = base;
				switch(blendType)
				{
					case 0: output = lerp(base, blend, alpha); break;
					case 1: output = lerp(base, blendDarken(base, blend), alpha); break;
					case 2: output = base * lerp(1, blend, alpha); break;
					case 5: output = lerp(base, blendLighten(base, blend), alpha); break;
					case 6: output = lerp(base, blendScreen(base, blend), alpha); break;
					case 7: output = blendSubtract(base, blend * alpha); break;
					case 8: output = lerp(base, blendLinearDodge(base, blend), alpha); break;
					case 9: output = lerp(base, blendOverlay(base, blend), alpha); break;
					case 20: output = lerp(base, blendMixed(base, blend), alpha); break;
					default: output = 0; break;
				}
				return output;
			}
			
			float3 customBlend(float base, float blend, float blendType, float alpha = 1)
			{
				float3 output = base;
				switch(blendType)
				{
					case 0: output = lerp(base, blend, alpha); break;
					case 2: output = base * lerp(1, blend, alpha); break;
					case 5: output = lerp(base, blendLighten(base, blend), alpha); break;
					case 6: output = lerp(base, blendScreen(base, blend), alpha); break;
					case 7: output = blendSubtract(base, blend * alpha); break;
					case 8: output = lerp(base, blendLinearDodge(base, blend), alpha); break;
					case 9: output = lerp(base, blendOverlay(base, blend), alpha); break;
					case 20: output = lerp(base, blendMixed(base, blend), alpha); break;
					default: output = 0; break;
				}
				return output;
			}
			
			#define REPLACE 0
			#define SUBSTRACT 1
			#define MULTIPLY 2
			#define DIVIDE 3
			#define MIN 4
			#define MAX 5
			#define AVERAGE 6
			#define ADD 7
			
			float maskBlend(float baseMask, float blendMask, float blendType)
			{
				float output = 0;
				switch(blendType)
				{
					case REPLACE: output = blendMask; break;
					case SUBSTRACT: output = baseMask - blendMask; break;
					case MULTIPLY: output = baseMask * blendMask; break;
					case DIVIDE: output = baseMask / blendMask; break;
					case MIN: output = min(baseMask, blendMask); break;
					case MAX: output = max(baseMask, blendMask); break;
					case AVERAGE: output = (baseMask + blendMask) * 0.5; break;
					case ADD: output = baseMask + blendMask; break;
				}
				return saturate(output);
			}
			
			float globalMaskBlend(float baseMask, float globalMaskIndex, float blendType, PoiMods poiMods)
			{
				if (globalMaskIndex == 0)
				{
					return baseMask;
				}
				else
				{
					return maskBlend(baseMask, poiMods.globalMask[globalMaskIndex - 1], blendType);
				}
			}
			
			float random(float2 p)
			{
				return frac(sin(dot(p, float2(12.9898, 78.2383))) * 43758.5453123);
			}
			
			float2 random2(float2 p)
			{
				return frac(sin(float2(dot(p, float2(127.1, 311.7)), dot(p, float2(269.5, 183.3)))) * 43758.5453);
			}
			
			float3 random3(float2 p)
			{
				return frac(sin(float3(dot(p, float2(127.1, 311.7)), dot(p, float2(269.5, 183.3)), dot(p, float2(248.3, 315.9)))) * 43758.5453);
			}
			
			float3 random3(float3 p)
			{
				return frac(sin(float3(dot(p, float3(127.1, 311.7, 248.6)), dot(p, float3(269.5, 183.3, 423.3)), dot(p, float3(248.3, 315.9, 184.2)))) * 43758.5453);
			}
			
			float3 randomFloat3(float2 Seed, float maximum)
			{
				return (.5 + float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed), float2(12.9898, 78.233))) * 43758.5453)
				) * .5) * (maximum);
			}
			
			float3 randomFloat3Range(float2 Seed, float Range)
			{
				return (float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed.x * Seed.y, Seed.y + Seed.x), float2(12.9898, 78.233))) * 43758.5453)
				) * 2 - 1) * Range;
			}
			
			float3 randomFloat3WiggleRange(float2 Seed, float Range, float wiggleSpeed, float timeOffset)
			{
				float3 rando = (float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed.x * Seed.y, Seed.y + Seed.x), float2(12.9898, 78.233))) * 43758.5453)
				) * 2 - 1);
				float speed = 1 + wiggleSpeed;
				return float3(sin(((_Time.x + timeOffset) + rando.x * PI) * speed), sin(((_Time.x + timeOffset) + rando.y * PI) * speed), sin(((_Time.x + timeOffset) + rando.z * PI) * speed)) * Range;
			}
			
			void poiDither(float4 In, float4 ScreenPosition, out float4 Out)
			{
				float2 uv = ScreenPosition.xy * _ScreenParams.xy;
				float DITHER_THRESHOLDS[16] = {
					1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0,
					13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0,
					4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0,
					16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0
				};
				uint index = (uint(uv.x) % 4) * 4 + uint(uv.y) % 4;
				Out = In - DITHER_THRESHOLDS[index];
			}
			// The weights of RGB contributions to luminance.
			// Should sum to unity.
			static const float3 HCYwts = float3(0.299, 0.587, 0.114);
			static const float HCLgamma = 3;
			static const float HCLy0 = 100;
			static const float HCLmaxL = 0.530454533953517; // == exp(HCLgamma / HCLy0) - 0.5
			static const float3 wref = float3(1.0, 1.0, 1.0);
			#define TAU 6.28318531
			
			float3 HUEtoRGB(in float H)
			{
				float R = abs(H * 6 - 3) - 1;
				float G = 2 - abs(H * 6 - 2);
				float B = 2 - abs(H * 6 - 4);
				return saturate(float3(R, G, B));
			}
			
			float3 RGBtoHCV(in float3 RGB)
			{
				// Based on work by Sam Hocevar and Emil Persson
				float4 P = (RGB.g < RGB.b) ? float4(RGB.bg, -1.0, 2.0 / 3.0) : float4(RGB.gb, 0.0, -1.0 / 3.0);
				float4 Q = (RGB.r < P.x) ? float4(P.xyw, RGB.r) : float4(RGB.r, P.yzx);
				float C = Q.x - min(Q.w, Q.y);
				float H = abs((Q.w - Q.y) / (6 * C + Epsilon) + Q.z);
				return float3(H, C, Q.x);
			}
			
			float3 HSVtoRGB(in float3 HSV)
			{
				float3 RGB = HUEtoRGB(HSV.x);
				return ((RGB - 1) * HSV.y + 1) * HSV.z;
			}
			
			float3 RGBtoHSV(in float3 RGB)
			{
				float3 HCV = RGBtoHCV(RGB);
				float S = HCV.y / (HCV.z + Epsilon);
				return float3(HCV.x, S, HCV.z);
			}
			
			float3 HSLtoRGB(in float3 HSL)
			{
				float3 RGB = HUEtoRGB(HSL.x);
				float C = (1 - abs(2 * HSL.z - 1)) * HSL.y;
				return (RGB - 0.5) * C + HSL.z;
			}
			
			float3 RGBtoHSL(in float3 RGB)
			{
				float3 HCV = RGBtoHCV(RGB);
				float L = HCV.z - HCV.y * 0.5;
				float S = HCV.y / (1 - abs(L * 2 - 1) + Epsilon);
				return float3(HCV.x, S, L);
			}
			
			void DecomposeHDRColor(in float3 linearColorHDR, out float3 baseLinearColor, out float exposure)
			{
				// Optimization/adaptation of https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/GUI/ColorMutator.cs#L23 but skips weird photoshop stuff
				float maxColorComponent = max(linearColorHDR.r, max(linearColorHDR.g, linearColorHDR.b));
				bool isSDR = maxColorComponent <= 1.0;
				
				float scaleFactor = isSDR ? 1.0 : (1.0 / maxColorComponent);
				exposure = isSDR ? 0.0 : log(maxColorComponent) * 1.44269504089; // ln(2)
				
				baseLinearColor = scaleFactor * linearColorHDR;
			}
			
			float3 ApplyHDRExposure(float3 linearColor, float exposure)
			{
				return linearColor * pow(2, exposure);
			}
			
			// Transforms an RGB color using a matrix. Note that S and V are absolute values here
			float3 ModifyViaHSV(float3 color, float h, float s, float v)
			{
				float3 colorHSV = RGBtoHSV(color);
				colorHSV.x = frac(colorHSV.x + h);
				colorHSV.y = saturate(colorHSV.y + s);
				colorHSV.z = saturate(colorHSV.z + v);
				return HSVtoRGB(colorHSV);
			}
			
			float3 ModifyViaHSV(float3 color, float3 HSVMod)
			{
				return ModifyViaHSV(color, HSVMod.x, HSVMod.y, HSVMod.z);
			}
			
			float4x4 brightnessMatrix(float brightness)
			{
				return float4x4(
				1, 0, 0, 0,
				0, 1, 0, 0,
				0, 0, 1, 0,
				brightness, brightness, brightness, 1
				);
			}
			
			float4x4 contrastMatrix(float contrast)
			{
				float t = (1.0 - contrast) / 2.0;
				
				return float4x4(
				contrast, 0, 0, 0,
				0, contrast, 0, 0,
				0, 0, contrast, 0,
				t, t, t, 1
				);
			}
			
			float4x4 saturationMatrix(float saturation)
			{
				float3 luminance = float3(0.3086, 0.6094, 0.0820);
				
				float oneMinusSat = 1.0 - saturation;
				
				float3 red = luminance.x * oneMinusSat;
				red += float3(saturation, 0, 0);
				
				float3 green = luminance.y * oneMinusSat;
				green += float3(0, saturation, 0);
				
				float3 blue = luminance.z * oneMinusSat;
				blue += float3(0, 0, saturation);
				
				return float4x4(
				red, 0,
				green, 0,
				blue, 0,
				0, 0, 0, 1
				);
			}
			
			float4 PoiColorBCS(float4 color, float brightness, float contrast, float saturation)
			{
				return mul(color, mul(brightnessMatrix(brightness), mul(contrastMatrix(contrast), saturationMatrix(saturation))));
			}
			float3 PoiColorBCS(float3 color, float brightness, float contrast, float saturation)
			{
				return mul(float4(color, 1), mul(brightnessMatrix(brightness), mul(contrastMatrix(contrast), saturationMatrix(saturation)))).rgb;
			}
			
			float3 linear_srgb_to_oklab(float3 c)
			{
				float l = 0.4122214708 * c.x + 0.5363325363 * c.y + 0.0514459929 * c.z;
				float m = 0.2119034982 * c.x + 0.6806995451 * c.y + 0.1073969566 * c.z;
				float s = 0.0883024619 * c.x + 0.2817188376 * c.y + 0.6299787005 * c.z;
				
				float l_ = pow(l, 1.0 / 3.0);
				float m_ = pow(m, 1.0 / 3.0);
				float s_ = pow(s, 1.0 / 3.0);
				
				return float3(
				0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_,
				1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_,
				0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_
				);
			}
			
			float3 oklab_to_linear_srgb(float3 c)
			{
				float l_ = c.x + 0.3963377774 * c.y + 0.2158037573 * c.z;
				float m_ = c.x - 0.1055613458 * c.y - 0.0638541728 * c.z;
				float s_ = c.x - 0.0894841775 * c.y - 1.2914855480 * c.z;
				
				float l = l_ * l_ * l_;
				float m = m_ * m_ * m_;
				float s = s_ * s_ * s_;
				
				return float3(
				+ 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
				- 1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
				- 0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s
				);
			}
			
			float3 hueShift(float3 color, float shift)
			{
				float3 oklab = linear_srgb_to_oklab(max(color, 0.0000000001));
				float hue = atan2(oklab.z, oklab.y);
				hue += shift * PI * 2;  // Add the hue shift
				
				float chroma = length(oklab.yz);
				oklab.y = cos(hue) * chroma;
				oklab.z = sin(hue) * chroma;
				
				return oklab_to_linear_srgb(oklab);
			}
			
			float3 hueShift(float4 color, float shift)
			{
				return hueShift(color.rgb, shift);
			}
			
			/*
			float3 hueShift(float3 color, float hueOffset)
			{
				color = RGBtoHSV(color);
				color.x = frac(hueOffset +color.x);
				return HSVtoRGB(color);
			}
			*/
			
			// LCH
			float xyzF(float t)
			{
				return lerp(pow(t, 1. / 3.), 7.787037 * t + 0.139731, step(t, 0.00885645));
			}
			float xyzR(float t)
			{
				return lerp(t * t * t, 0.1284185 * (t - 0.139731), step(t, 0.20689655));
			}
			
			float4x4 poiRotationMatrixFromAngles(float x, float y, float z)
			{
				float angleX = radians(x);
				float c = cos(angleX);
				float s = sin(angleX);
				float4x4 rotateXMatrix = float4x4(1, 0, 0, 0,
				0, c, -s, 0,
				0, s, c, 0,
				0, 0, 0, 1);
				
				float angleY = radians(y);
				c = cos(angleY);
				s = sin(angleY);
				float4x4 rotateYMatrix = float4x4(c, 0, s, 0,
				0, 1, 0, 0,
				- s, 0, c, 0,
				0, 0, 0, 1);
				
				float angleZ = radians(z);
				c = cos(angleZ);
				s = sin(angleZ);
				float4x4 rotateZMatrix = float4x4(c, -s, 0, 0,
				s, c, 0, 0,
				0, 0, 1, 0,
				0, 0, 0, 1);
				
				return mul(mul(rotateXMatrix, rotateYMatrix), rotateZMatrix);
			}
			
			float4x4 poiRotationMatrixFromAngles(float3 angles)
			{
				float angleX = radians(angles.x);
				float c = cos(angleX);
				float s = sin(angleX);
				float4x4 rotateXMatrix = float4x4(1, 0, 0, 0,
				0, c, -s, 0,
				0, s, c, 0,
				0, 0, 0, 1);
				
				float angleY = radians(angles.y);
				c = cos(angleY);
				s = sin(angleY);
				float4x4 rotateYMatrix = float4x4(c, 0, s, 0,
				0, 1, 0, 0,
				- s, 0, c, 0,
				0, 0, 0, 1);
				
				float angleZ = radians(angles.z);
				c = cos(angleZ);
				s = sin(angleZ);
				float4x4 rotateZMatrix = float4x4(c, -s, 0, 0,
				s, c, 0, 0,
				0, 0, 1, 0,
				0, 0, 0, 1);
				
				return mul(mul(rotateXMatrix, rotateYMatrix), rotateZMatrix);
			}
			
			float3 getCameraPosition()
			{
				#ifdef USING_STEREO_MATRICES
				return lerp(unity_StereoWorldSpaceCameraPos[0], unity_StereoWorldSpaceCameraPos[1], 0.5);
				#endif
				return _WorldSpaceCameraPos;
			}
			
			float2 calcPixelScreenUVs(half4 grabPos)
			{
				half2 uv = grabPos.xy / (grabPos.w + 0.0000000001);
				#if UNITY_SINGLE_PASS_STEREO
				uv.xy *= half2(_ScreenParams.x * 2, _ScreenParams.y);
				#else
				uv.xy *= _ScreenParams.xy;
				#endif
				
				return uv;
			}
			
			float CalcMipLevel(float2 texture_coord)
			{
				float2 dx = ddx(texture_coord);
				float2 dy = ddy(texture_coord);
				float delta_max_sqr = max(dot(dx, dx), dot(dy, dy));
				
				return 0.5 * log2(delta_max_sqr);
			}
			
			float inverseLerp(float A, float B, float T)
			{
				return (T - A) / (B - A);
			}
			
			float inverseLerp2(float2 a, float2 b, float2 value)
			{
				float2 AB = b - a;
				float2 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			float inverseLerp3(float3 a, float3 b, float3 value)
			{
				float3 AB = b - a;
				float3 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			float inverseLerp4(float4 a, float4 b, float4 value)
			{
				float4 AB = b - a;
				float4 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			/*
			MIT License
			
			Copyright (c) 2019 wraikny
			
			Permission is hereby granted, free of charge, to any person obtaining a copy
			of this software and associated documentation files (the "Software"), to deal
			in the Software without restriction, including without limitation the rights
			to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
			copies of the Software, and to permit persons to whom the Software is
			furnished to do so, subject to the following conditions:
			
			The above copyright notice and this permission notice shall be included in all
			copies or substantial portions of the Software.
			
			THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
			IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
			FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
			AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
			LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
			OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
			SOFTWARE.
			
			VertexTransformShader is dependent on:
			*/
			
			float4 quaternion_conjugate(float4 v)
			{
				return float4(
				v.x, -v.yzw
				);
			}
			
			float4 quaternion_mul(float4 v1, float4 v2)
			{
				float4 result1 = (v1.x * v2 + v1 * v2.x);
				
				float4 result2 = float4(
				- dot(v1.yzw, v2.yzw),
				cross(v1.yzw, v2.yzw)
				);
				
				return float4(result1 + result2);
			}
			
			// angle : radians
			float4 get_quaternion_from_angle(float3 axis, float angle)
			{
				float sn = sin(angle * 0.5);
				float cs = cos(angle * 0.5);
				return float4(axis * sn, cs);
			}
			
			float4 quaternion_from_vector(float3 inVec)
			{
				return float4(0.0, inVec);
			}
			
			float degree_to_radius(float degree)
			{
				return (
				degree / 180.0 * PI
				);
			}
			
			float3 rotate_with_quaternion(float3 inVec, float3 rotation)
			{
				float4 qx = get_quaternion_from_angle(float3(1, 0, 0), radians(rotation.x));
				float4 qy = get_quaternion_from_angle(float3(0, 1, 0), radians(rotation.y));
				float4 qz = get_quaternion_from_angle(float3(0, 0, 1), radians(rotation.z));
				
				#define MUL3(A, B, C) quaternion_mul(quaternion_mul((A), (B)), (C))
				float4 quaternion = normalize(MUL3(qx, qy, qz));
				float4 conjugate = quaternion_conjugate(quaternion);
				
				float4 inVecQ = quaternion_from_vector(inVec);
				
				float3 rotated = (
				MUL3(quaternion, inVecQ, conjugate)
				).yzw;
				
				return rotated;
			}
			
			float4 transform(float4 input, float4 pos, float4 rotation, float4 scale)
			{
				input.rgb *= (scale.xyz * scale.w);
				input = float4(rotate_with_quaternion(input.xyz, rotation.xyz * rotation.w) + (pos.xyz * pos.w), input.w);
				return input;
			}
			
			float2 RotateUV(float2 _uv, float _radian, float2 _piv, float _time)
			{
				float RotateUV_ang = _radian;
				float RotateUV_cos = cos(_time * RotateUV_ang);
				float RotateUV_sin = sin(_time * RotateUV_ang);
				return (mul(_uv - _piv, float2x2(RotateUV_cos, -RotateUV_sin, RotateUV_sin, RotateUV_cos)) + _piv);
			}
			
			/*
			MIT END
			*/
			
			float3 RotateAroundAxis(float3 original, float3 axis, float radian)
			{
				float s = sin(radian);
				float c = cos(radian);
				float one_minus_c = 1.0 - c;
				
				axis = normalize(axis);
				float3x3 rot_mat = {
					one_minus_c * axis.x * axis.x + c, one_minus_c * axis.x * axis.y - axis.z * s, one_minus_c * axis.z * axis.x + axis.y * s,
					one_minus_c * axis.x * axis.y + axis.z * s, one_minus_c * axis.y * axis.y + c, one_minus_c * axis.y * axis.z - axis.x * s,
					one_minus_c * axis.z * axis.x - axis.y * s, one_minus_c * axis.y * axis.z + axis.x * s, one_minus_c * axis.z * axis.z + c
				};
				return mul(rot_mat, original);
			}
			
			float3 poiThemeColor(in PoiMods poiMods, in float3 srcColor, in float themeIndex)
			{
				float3 outputColor = srcColor;
				if (themeIndex != 0)
				{
					themeIndex = max(themeIndex - 1, 0);
					
					if (themeIndex <= 3)
					{
						outputColor = poiMods.globalColorTheme[themeIndex];
					}
					else
					{
						#ifdef POI_AUDIOLINK
						if (poiMods.audioLinkAvailable)
						{
							outputColor = poiMods.globalColorTheme[themeIndex];
						}
						#endif
					}
				}
				return outputColor;
			}
			
			float3 lilToneCorrection(float3 c, float4 hsvg)
			{
				// gamma
				c = pow(abs(c), hsvg.w);
				// rgb - > hsv
				float4 p = (c.b > c.g) ? float4(c.bg, -1.0, 2.0 / 3.0) : float4(c.gb, 0.0, -1.0 / 3.0);
				float4 q = (p.x > c.r) ? float4(p.xyw, c.r) : float4(c.r, p.yzx);
				float d = q.x - min(q.w, q.y);
				float e = 1.0e-10;
				float3 hsv = float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
				// shift
				hsv = float3(hsv.x + hsvg.x, saturate(hsv.y * hsvg.y), saturate(hsv.z * hsvg.z));
				// hsv - > rgb
				return hsv.z - hsv.z * hsv.y + hsv.z * hsv.y * saturate(abs(frac(hsv.x + float3(1.0, 2.0 / 3.0, 1.0 / 3.0)) * 6.0 - 3.0) - 1.0);
			}
			
			float3 lilBlendColor(float3 dstCol, float3 srcCol, float3 srcA, int blendMode)
			{
				float3 ad = dstCol + srcCol;
				float3 mu = dstCol * srcCol;
				float3 outCol = float3(0, 0, 0);
				if (blendMode == 0) outCol = srcCol; // Normal
				if (blendMode == 1) outCol = ad; // Add
				if (blendMode == 2) outCol = max(ad - mu, dstCol); // Screen
				if (blendMode == 3) outCol = mu; // Multiply
				return lerp(dstCol, outCol, srcA);
			}
			
			float lilIsIn0to1(float f)
			{
				float value = 0.5 - abs(f - 0.5);
				return saturate(value / clamp(fwidth(value), 0.0001, 1.0));
			}
			
			float lilIsIn0to1(float f, float nv)
			{
				float value = 0.5 - abs(f - 0.5);
				return saturate(value / clamp(fwidth(value), 0.0001, nv));
			}
			
			float poiEdgeLinearNoSaturate(float value, float border)
			{
				return (value - border) / clamp(fwidth(value), 0.0001, 1.0);
			}
			
			float3 poiEdgeLinearNoSaturate(float value, float3 border)
			{
				return float3(
				(value - border.x) / clamp(fwidth(value), 0.0001, 1.0),
				(value - border.y) / clamp(fwidth(value), 0.0001, 1.0),
				(value - border.z) / clamp(fwidth(value), 0.0001, 1.0)
				);
			}
			
			float poiEdgeLinearNoSaturate(float value, float border, float blur)
			{
				float borderMin = saturate(border - blur * 0.5);
				float borderMax = saturate(border + blur * 0.5);
				return (value - borderMin) / saturate(borderMax - borderMin + fwidth(value));
			}
			
			float poiEdgeLinearNoSaturate(float value, float border, float blur, float borderRange)
			{
				float borderMin = saturate(border - blur * 0.5 - borderRange);
				float borderMax = saturate(border + blur * 0.5);
				return (value - borderMin) / saturate(borderMax - borderMin + fwidth(value));
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border)
			{
				// return (value - border) / clamp(fwidth(value), 0.0001, 1.0);
				
				float fwidthValue = fwidth(value);
				return smoothstep(border - fwidthValue, border + fwidthValue, value);
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border, float blur)
			{
				float fwidthValue = fwidth(value);
				float borderMin = saturate(border - blur * 0.5);
				float borderMax = saturate(border + blur * 0.5);
				return smoothstep(borderMin - fwidthValue, borderMax + fwidthValue, value);
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border, float blur, float borderRange)
			{
				float fwidthValue = fwidth(value);
				float borderMin = saturate(border - blur * 0.5 - borderRange);
				float borderMax = saturate(border + blur * 0.5);
				return smoothstep(borderMin - fwidthValue, borderMax + fwidthValue, value);
			}
			
			float poiEdgeNonLinear(float value, float border)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border));
			}
			
			float poiEdgeNonLinear(float value, float border, float blur)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border, blur));
			}
			
			float poiEdgeNonLinear(float value, float border, float blur, float borderRange)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border, blur, borderRange));
			}
			
			float poiEdgeLinear(float value, float border)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border));
			}
			
			float poiEdgeLinear(float value, float border, float blur)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border, blur));
			}
			
			float poiEdgeLinear(float value, float border, float blur, float borderRange)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border, blur, borderRange));
			}
			// From https : // github.com / lilxyzw / OpenLit / blob / main / Assets / OpenLit / core.hlsl
			float3 OpenLitLinearToSRGB(float3 col)
			{
				return LinearToGammaSpace(col);
			}
			
			float3 OpenLitSRGBToLinear(float3 col)
			{
				return GammaToLinearSpace(col);
			}
			
			float OpenLitLuminance(float3 rgb)
			{
				#if defined(UNITY_COLORSPACE_GAMMA)
				return dot(rgb, float3(0.22, 0.707, 0.071));
				#else
				return dot(rgb, float3(0.0396819152, 0.458021790, 0.00609653955));
				#endif
			}
			
			float3 AdjustLitLuminance(float3 rgb, float targetLuminance)
			{
				float currentLuminance;
				#if defined(UNITY_COLORSPACE_GAMMA)
				currentLuminance = dot(rgb, float3(0.22, 0.707, 0.071));
				#else
				currentLuminance = dot(rgb, float3(0.0396819152, 0.458021790, 0.00609653955));
				#endif
				
				float luminanceRatio = targetLuminance / currentLuminance;
				return rgb * luminanceRatio;
			}
			
			float3 ClampLuminance(float3 rgb, float minLuminance, float maxLuminance)
			{
				float currentLuminance = dot(rgb, float3(0.299, 0.587, 0.114));
				float minRatio = (currentLuminance != 0) ? minLuminance / currentLuminance : 1.0;
				float maxRatio = (currentLuminance != 0) ? maxLuminance / currentLuminance : 1.0;
				float luminanceRatio = clamp(min(maxRatio, max(minRatio, 1.0)), 0.0, 1.0);
				return lerp(rgb, rgb * luminanceRatio, luminanceRatio < 1.0);
			}
			
			float3 MaxLuminance(float3 rgb, float maxLuminance)
			{
				float currentLuminance = dot(rgb, float3(0.299, 0.587, 0.114));
				float luminanceRatio = (currentLuminance != 0) ? maxLuminance / max(currentLuminance, 0.00001) : 1.0;
				return lerp(rgb, rgb * luminanceRatio, currentLuminance > maxLuminance);
			}
			
			float OpenLitGray(float3 rgb)
			{
				return dot(rgb, float3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0));
			}
			
			void OpenLitShadeSH9ToonDouble(float3 lightDirection, out float3 shMax, out float3 shMin)
			{
				#if !defined(LIGHTMAP_ON)
				float3 N = lightDirection * 0.666666;
				float4 vB = N.xyzz * N.yzzx;
				// L0 L2
				float3 res = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
				res.r += dot(unity_SHBr, vB);
				res.g += dot(unity_SHBg, vB);
				res.b += dot(unity_SHBb, vB);
				res += unity_SHC.rgb * (N.x * N.x - N.y * N.y);
				// L1
				float3 l1;
				l1.r = dot(unity_SHAr.rgb, N);
				l1.g = dot(unity_SHAg.rgb, N);
				l1.b = dot(unity_SHAb.rgb, N);
				shMax = res + l1;
				shMin = res - l1;
				#if defined(UNITY_COLORSPACE_GAMMA)
				shMax = OpenLitLinearToSRGB(shMax);
				shMin = OpenLitLinearToSRGB(shMin);
				#endif
				#else
				shMax = 0.0;
				shMin = 0.0;
				#endif
			}
			
			float3 OpenLitComputeCustomLightDirection(float4 lightDirectionOverride)
			{
				float3 customDir = length(lightDirectionOverride.xyz) * normalize(mul((float3x3)unity_ObjectToWorld, lightDirectionOverride.xyz));
				return lightDirectionOverride.w ? customDir : lightDirectionOverride.xyz; // .w isn't doc'd anywhere and is always 0 unless end user changes it
			}
			
			float3 OpenLitLightingDirectionForSH9()
			{
				float3 mainDir = _WorldSpaceLightPos0.xyz * OpenLitLuminance(_LightColor0.rgb);
				#if !defined(LIGHTMAP_ON)
				float3 sh9Dir = unity_SHAr.xyz * 0.333333 + unity_SHAg.xyz * 0.333333 + unity_SHAb.xyz * 0.333333;
				float3 sh9DirAbs = float3(sh9Dir.x, abs(sh9Dir.y), sh9Dir.z);
				#else
				float3 sh9Dir = 0;
				float3 sh9DirAbs = 0;
				#endif
				
				float3 lightDirectionForSH9 = sh9Dir + mainDir;
				lightDirectionForSH9 = dot(lightDirectionForSH9, lightDirectionForSH9) < 0.000001 ? 0 : normalize(lightDirectionForSH9);
				return lightDirectionForSH9;
			}
			
			float3 OpenLitLightingDirection(float4 lightDirectionOverride)
			{
				float3 mainDir = _WorldSpaceLightPos0.xyz * OpenLitLuminance(_LightColor0.rgb);
				#if !defined(LIGHTMAP_ON) && UNITY_SHOULD_SAMPLE_SH
				float3 sh9Dir = unity_SHAr.xyz * 0.333333 + unity_SHAg.xyz * 0.333333 + unity_SHAb.xyz * 0.333333;
				float3 sh9DirAbs = float3(sh9Dir.x, abs(sh9Dir.y), sh9Dir.z);
				#else
				float3 sh9Dir = 0;
				float3 sh9DirAbs = 0;
				#endif
				float3 customDir = OpenLitComputeCustomLightDirection(lightDirectionOverride);
				
				return normalize(sh9DirAbs + mainDir + customDir);
			}
			
			float3 OpenLitLightingDirection()
			{
				float4 customDir = float4(0.001, 0.002, 0.001, 0.0);
				return OpenLitLightingDirection(customDir);
			}
			
			inline float4 CalculateFrustumCorrection()
			{
				float x1 = -UNITY_MATRIX_P._31 / (UNITY_MATRIX_P._11 * UNITY_MATRIX_P._34);
				float x2 = -UNITY_MATRIX_P._32 / (UNITY_MATRIX_P._22 * UNITY_MATRIX_P._34);
				return float4(x1, x2, 0, UNITY_MATRIX_P._33 / UNITY_MATRIX_P._34 + x1 * UNITY_MATRIX_P._13 + x2 * UNITY_MATRIX_P._23);
			}
			
			inline float CorrectedLinearEyeDepth(float z, float B)
			{
				return 1.0 / (z / UNITY_MATRIX_P._34 + B);
			}
			
			// Silent's code
			float2 sharpSample(float4 texelSize, float2 p)
			{
				p = p * texelSize.zw;
				float2 c = max(0.0, fwidth(p));
				p = floor(p) + saturate(frac(p) / c);
				p = (p - 0.5) * texelSize.xy;
				return p;
			}
			
			void applyToGlobalMask(inout PoiMods poiMods, int index, int blendType, float val)
			{
				float valBlended = saturate(maskBlend(poiMods.globalMask[index], val, blendType));
				switch(index)
				{
					case 0: poiMods.globalMask[0] = valBlended; break;
					case 1: poiMods.globalMask[1] = valBlended; break;
					case 2: poiMods.globalMask[2] = valBlended; break;
					case 3: poiMods.globalMask[3] = valBlended; break;
					case 4: poiMods.globalMask[4] = valBlended; break;
					case 5: poiMods.globalMask[5] = valBlended; break;
					case 6: poiMods.globalMask[6] = valBlended; break;
					case 7: poiMods.globalMask[7] = valBlended; break;
					case 8: poiMods.globalMask[8] = valBlended; break;
					case 9: poiMods.globalMask[9] = valBlended; break;
					case 10: poiMods.globalMask[10] = valBlended; break;
					case 11: poiMods.globalMask[11] = valBlended; break;
					case 12: poiMods.globalMask[12] = valBlended; break;
					case 13: poiMods.globalMask[13] = valBlended; break;
					case 14: poiMods.globalMask[14] = valBlended; break;
					case 15: poiMods.globalMask[15] = valBlended; break;
				}
			}
			
			void assignValueToVectorFromIndex(inout float4 vec, int index, float value)
			{
				switch(index)
				{
					case 0: vec[0] = value; break;
					case 1: vec[1] = value; break;
					case 2: vec[2] = value; break;
					case 3: vec[3] = value; break;
				}
			}
			
			// SNose
			float3 mod289(float3 x)
			{
				return x - floor(x * (1.0 / 289.0)) * 289.0;
			}
			float2 mod289(float2 x)
			{
				return x - floor(x * (1.0 / 289.0)) * 289.0;
			}
			float3 permute(float3 x)
			{
				return mod289(((x * 34.0) + 1.0) * x);
			}
			
			float snoise(float2 v)
			{
				const float4 C = float4(0.211324865405187, // (3.0 - sqrt(3.0)) / 6.0
				0.366025403784439, // 0.5 * (sqrt(3.0) - 1.0)
				- 0.577350269189626, // - 1.0 + 2.0 * C.x
				0.024390243902439); // 1.0 / 41.0
				float2 i = floor(v + dot(v, C.yy));
				float2 x0 = v - i + dot(i, C.xx);
				float2 i1;
				i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0);
				float4 x12 = x0.xyxy + C.xxzz;
				x12.xy -= i1;
				i = mod289(i); // Avoid truncation effects in permutation
				float3 p = permute(permute(i.y + float3(0.0, i1.y, 1.0))
				+ i.x + float3(0.0, i1.x, 1.0));
				
				float3 m = max(0.5 - float3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);
				m = m * m ;
				m = m * m ;
				float3 x = 2.0 * frac(p * C.www) - 1.0;
				float3 h = abs(x) - 0.5;
				float3 ox = floor(x + 0.5);
				float3 a0 = x - ox;
				m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);
				float3 g;
				g.x = a0.x * x0.x + h.x * x0.y;
				g.yz = a0.yz * x12.xz + h.yz * x12.yw;
				return 130.0 * dot(m, g);
			}
			
			float nsqDistance(float2 a, float2 b)
			{
				return dot(a - b, a - b);
			}
			
			float poiInvertToggle(in float value, in float toggle)
			{
				return (toggle == 0 ? value : 1 - value);
			}
			
			float3 PoiBlendNormal(float3 dstNormal, float3 srcNormal)
			{
				return float3(dstNormal.xy + srcNormal.xy, dstNormal.z * srcNormal.z);
			}
			
			float3 lilTransformDirOStoWS(float3 directionOS, bool doNormalize)
			{
				if (doNormalize) return normalize(mul((float3x3)unity_ObjectToWorld, directionOS));
				else            return mul((float3x3)unity_ObjectToWorld, directionOS);
			}
			
			float2 poiGetWidthAndHeight(Texture2D tex)
			{
				uint width, height;
				tex.GetDimensions(width, height);
				return float2(width, height);
			}
			
			float2 poiGetWidthAndHeight(Texture2DArray tex)
			{
				uint width, height, element;
				tex.GetDimensions(width, height, element);
				return float2(width, height);
			}
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			
			// Convenient mechanism to read from the AudioLink texture that handles reading off the end of one line and onto the next above it.
			float4 AudioLinkDataMultiline(uint2 xycoord)
			{
				return AudioLinkData(uint2(xycoord.x % AUDIOLINK_WIDTH, xycoord.y + xycoord.x / AUDIOLINK_WIDTH));
			}
			
			// Mechanism to sample between two adjacent pixels and lerp between them, like "linear" supesampling
			float4 AudioLinkLerp(float2 xy)
			{
				return lerp(AudioLinkData(xy), AudioLinkData(xy + int2(1, 0)), frac(xy.x));
			}
			
			// Same as AudioLinkLerp but properly handles multiline reading.
			float4 AudioLinkLerpMultiline(float2 xy)
			{
				return lerp(AudioLinkDataMultiline(xy), AudioLinkDataMultiline(xy + float2(1, 0)), frac(xy.x));
			}
			
			//Tests to see if Audio Link texture is available
			bool AudioLinkIsAvailable()
			{
				#if !defined(AUDIOLINK_STANDARD_INDEXING)
				int width, height;
				_AudioTexture.GetDimensions(width, height);
				return width > 16;
				#else
				return _AudioTexture_TexelSize.z > 16;
				#endif
			}
			
			//Get version of audiolink present in the world, 0 if no audiolink is present
			float AudioLinkGetVersion()
			{
				int2 dims;
				#if !defined(AUDIOLINK_STANDARD_INDEXING)
				_AudioTexture.GetDimensions(dims.x, dims.y);
				#else
				dims = _AudioTexture_TexelSize.zw;
				#endif
				
				if (dims.x >= 128)
				return AudioLinkData(ALPASS_GENERALVU).x;
				else if (dims.x > 16)
				return 1;
				else
				return 0;
			}
			
			// This pulls data from this texture.
			#define AudioLinkGetSelfPixelData(xy) _SelfTexture2D[xy]
			
			// Extra utility functions for time.
			uint AudioLinkDecodeDataAsUInt(uint2 indexloc)
			{
				uint4 rpx = AudioLinkData(indexloc);
				return rpx.r + rpx.g * 1024 + rpx.b * 1048576 + rpx.a * 1073741824;
			}
			
			//Note: This will truncate time to every 134,217.728 seconds (~1.5 days of an instance being up) to prevent floating point aliasing.
			// if your code will alias sooner, you will need to use a different function.  It should be safe to use this on all times.
			float AudioLinkDecodeDataAsSeconds(uint2 indexloc)
			{
				uint time = AudioLinkDecodeDataAsUInt(indexloc) & 0x7ffffff;
				//Can't just divide by float.  Bug in Unity's HLSL compiler.
				return float(time / 1000) + float(time % 1000) / 1000.;
			}
			
			#define ALDecodeDataAsSeconds(x) AudioLinkDecodeDataAsSeconds(x)
			#define ALDecodeDataAsUInt(x) AudioLinkDecodeDataAsUInt(x)
			
			float AudioLinkRemap(float t, float a, float b, float u, float v)
			{
				return ((t - a) / (b - a)) * (v - u) + u;
			}
			
			float3 AudioLinkHSVtoRGB(float3 HSV)
			{
				float3 RGB = 0;
				float C = HSV.z * HSV.y;
				float H = HSV.x * 6;
				float X = C * (1 - abs(fmod(H, 2) - 1));
				if (HSV.y != 0)
				{
					float I = floor(H);
					if (I == 0)
					{
						RGB = float3(C, X, 0);
					}
					else if (I == 1)
					{
						RGB = float3(X, C, 0);
					}
					else if (I == 2)
					{
						RGB = float3(0, C, X);
					}
					else if (I == 3)
					{
						RGB = float3(0, X, C);
					}
					else if (I == 4)
					{
						RGB = float3(X, 0, C);
					}
					else
					{
						RGB = float3(C, 0, X);
					}
				}
				float M = HSV.z - C;
				return RGB + M;
			}
			
			float3 AudioLinkCCtoRGB(float bin, float intensity, int rootNote)
			{
				float note = bin / AUDIOLINK_EXPBINS;
				
				float hue = 0.0;
				note *= 12.0;
				note = glsl_mod(4. - note + rootNote, 12.0);
				{
					if (note < 4.0)
					{
						//Needs to be YELLOW->RED
						hue = (note) / 24.0;
					}
					else if (note < 8.0)
					{
						//            [4]  [8]
						//Needs to be RED->BLUE
						hue = (note - 2.0) / 12.0;
					}
					else
					{
						//             [8] [12]
						//Needs to be BLUE->YELLOW
						hue = (note - 4.0) / 8.0;
					}
				}
				float val = intensity - 0.1;
				return AudioLinkHSVtoRGB(float3(fmod(hue, 1.0), 1.0, clamp(val, 0.0, 1.0)));
			}
			
			// Sample the amplitude of a given frequency in the DFT, supports frequencies in [13.75; 14080].
			float4 AudioLinkGetAmplitudeAtFrequency(float hertz)
			{
				float note = AUDIOLINK_EXPBINS * log2(hertz / AUDIOLINK_BOTTOM_FREQUENCY);
				return AudioLinkLerpMultiline(ALPASS_DFT + float2(note, 0));
			}
			
			// Sample the amplitude of a given semitone in an octave. Octave is in [0; 9] while note is [0; 11].
			float AudioLinkGetAmplitudeAtNote(float octave, float note)
			{
				float quarter = note * 2.0;
				return AudioLinkLerpMultiline(ALPASS_DFT + float2(octave * AUDIOLINK_EXPBINS + quarter, 0));
			}
			
			// Get a reasonable drop-in replacement time value for _Time.y with the
			// given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTime(uint index, uint band)
			{
				return (AudioLinkDecodeDataAsUInt(ALPASS_CHRONOTENSITY + uint2(index, band))) / 100000.0;
			}
			
			// Get a chronotensity value in the interval [0; 1], modulated by the speed input,
			// with the given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTimeNormalized(uint index, uint band, float speed)
			{
				return frac(AudioLinkGetChronoTime(index, band) * speed);
			}
			
			// Get a chronotensity value in the interval [0; interval], modulated by the speed input,
			// with the given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTimeInterval(uint index, uint band, float speed, float interval)
			{
				return AudioLinkGetChronoTimeNormalized(index, band, speed) * interval;
			}
			
			float getBandAtTime(float band, float time, float size = 1.0f)
			{
				//return remap(UNITY_SAMPLE_TEX2D(_AudioTexture, float2(time * width, band/128.0)).r, min(size,.9999), 1);
				return remapClamped(min(size, .9999), 1, AudioLinkData(ALPASS_AUDIOBASS + uint2(time * AUDIOLINK_WIDTH, band)).r);
			}
			
			fixed3 maximize(fixed3 c)
			{
				if (c.x == 0 && c.y == 0 && c.z == 0)
				return fixed3(1.0, 1.0, 1.0);
				else
				return c / max(c.r, max(c.g, c.b));
			}
			
			void initPoiAudioLink(inout PoiMods poiMods)
			{
				if (!_AudioLinkAnimToggle) return;
				
				if (AudioLinkIsAvailable())
				{
					poiMods.audioLinkAvailable = true;
					poiMods.audioLinkVersion = AudioLinkGetVersion();
					poiMods.audioLink[0] = _AudioLinkSmoothingBass == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 0))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingBass) * 15.95, 0))[0];
					poiMods.audioLink[1] = _AudioLinkSmoothingLowMid == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 1))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingLowMid) * 15.95, 1))[0];
					poiMods.audioLink[2] = _AudioLinkSmoothingHighMid == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 2))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingHighMid) * 15.95, 2))[0];
					poiMods.audioLink[3] = _AudioLinkSmoothingTreble == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 3))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingTreble) * 15.95, 3))[0];
					poiMods.audioLink[4] = AudioLinkData(ALPASS_GENERALVU + float2(8, 0))[0];
					/*
					poiMods.globalColorTheme[4] = AudioLinkData( ALPASS_CCCOLORS + uint2( 0, 0 ) );
					poiMods.globalColorTheme[5] = AudioLinkData( ALPASS_CCCOLORS + uint2( 1, 0 ) );
					poiMods.globalColorTheme[6] = AudioLinkData( ALPASS_CCCOLORS + uint2( 2, 0 ) );
					poiMods.globalColorTheme[7] = AudioLinkData( ALPASS_CCCOLORS + uint2( 3, 0 ) );
					
					poiMods.globalColorTheme[4] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 0, 0 ) )),1.0);
					poiMods.globalColorTheme[5] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 1, 0 ) )),1.0);
					poiMods.globalColorTheme[6] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 2, 0 ) )),1.0);
					poiMods.globalColorTheme[7] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 3, 0 ) )),1.0);
					*/
					
					poiMods.globalColorTheme[4] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(2, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[5] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(3, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[6] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(4, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[7] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(5, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					
					poiMods.globalColorTheme[8] = AudioLinkData(ALPASS_THEME_COLOR0);
					poiMods.globalColorTheme[9] = AudioLinkData(ALPASS_THEME_COLOR1);
					poiMods.globalColorTheme[10] = AudioLinkData(ALPASS_THEME_COLOR2);
					poiMods.globalColorTheme[11] = AudioLinkData(ALPASS_THEME_COLOR3);
					return;
				}
				
				if (_AudioLinkBandOverridesEnabled)
				{
					poiMods.audioLinkAvailable = true;
					poiMods.audioLink[0] = _AudioLinkBandOverrideSliders.x;
					poiMods.audioLink[1] = _AudioLinkBandOverrideSliders.y;
					poiMods.audioLink[2] = _AudioLinkBandOverrideSliders.z;
					poiMods.audioLink[3] = _AudioLinkBandOverrideSliders.w;
				}
			}
			
			void DebugVisualizer(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				if (_DebugWaveform)
				{
					float waveform = AudioLinkLerpMultiline(ALPASS_WAVEFORM + float2(500. * poiMesh.uv[0].x, 0)).r;
					poiFragData.emission += clamp(1 - 50 * abs(waveform - poiMesh.uv[0].y * 2. + 1), 0, 1);
				}
				if (_DebugDFT)
				{
					poiFragData.emission += AudioLinkLerpMultiline(ALPASS_DFT + uint2(poiMesh.uv[0].x * AUDIOLINK_ETOTALBINS, 0)).rrr;
				}
				if (_DebugBass)
				{
					poiFragData.emission += poiMods.audioLink[0];
				}
				if (_DebugLowMids)
				{
					poiFragData.emission += poiMods.audioLink[1];
				}
				if (_DebugHighMids)
				{
					poiFragData.emission += poiMods.audioLink[2];
				}
				if (_DebugTreble)
				{
					poiFragData.emission += poiMods.audioLink[3];
				}
				if (_DebugCCColors)
				{
					poiFragData.emission += AudioLinkData(ALPASS_CCCOLORS + uint2(3 + 1, 0));
				}
				if (_DebugCCStrip)
				{
					poiFragData.emission += AudioLinkLerp(ALPASS_CCSTRIP + float2(poiMesh.uv[0].x * AUDIOLINK_WIDTH, 0));
				}
				if (_DebugCCLights)
				{
					poiFragData.emission += AudioLinkData(ALPASS_CCLIGHTS + uint2(uint(poiMesh.uv[0].x * 8) + uint(poiMesh.uv[0].y * 16) * 8, 0));
				}
				if (_DebugAutocorrelator)
				{
					poiFragData.emission += saturate(AudioLinkLerp(ALPASS_AUTOCORRELATOR + float2((abs(1. - poiMesh.uv[0].x * 2.)) * AUDIOLINK_WIDTH, 0)).rrr);
				}
				if (_DebugChronotensity)
				{
					poiFragData.emission += (AudioLinkDecodeDataAsUInt(ALPASS_CHRONOTENSITY + uint2(1, 0)) % 1000000) / 1000000.0;
				}
			}
			
			void SetupAudioLink(inout PoiFragData poiFragData, inout PoiMods poiMods, in PoiMesh poiMesh)
			{
				initPoiAudioLink(poiMods);
				DebugVisualizer(poiFragData, poiMesh, poiMods);
				
				if (_AudioLinkCCStripY)
				{
					poiFragData.emission += AudioLinkLerp(ALPASS_CCSTRIP + float2(poiMesh.uv[0].y * AUDIOLINK_WIDTH, 0)).rgb * .5;
				}
			}
			
			#endif
			//endex
			
			//ifex _BSSEnabled!=1
			#ifdef POIBS_ENABLE
			//ifex _BSSBloomfog!=1
			#ifdef POIBS_BLOOMFOG
			inline float4 GetFogCoord(float4 clipPos)
			{
				float4 screenPos = ComputeNonStereoScreenPos(clipPos);
				float2 screenPosNormalized = screenPos.xy / screenPos.w;
				float eyeOffset = (unity_StereoEyeIndex * (_StereoCameraEyeOffset * 2)) + - _StereoCameraEyeOffset;
				return float4(
				((eyeOffset +screenPosNormalized.x) + - 0.5) * _CustomFogTextureToScreenRatio.x + 0.5,
				(screenPosNormalized.y + - 0.5) * _CustomFogTextureToScreenRatio.y + 0.5
				,clipPos.z,clipPos.w);
			}
			
			inline float GetHeightFogIntensity(float3 worldPos, float fogHeightOffset, float fogHeightScale)
			{
				float heightFogIntensity = _CustomFogHeightFogHeight + _CustomFogHeightFogStartY;
				heightFogIntensity = ((worldPos.y * fogHeightScale) + fogHeightOffset) + - heightFogIntensity;
				heightFogIntensity = heightFogIntensity / _CustomFogHeightFogHeight;
				heightFogIntensity = clamp(heightFogIntensity, 0, 1);
				return ((-heightFogIntensity * 2) + 3) * (heightFogIntensity * heightFogIntensity);
			}
			
			inline float GetFogIntensity(float3 distance, float fogStartOffset, float fogScale)
			{
				float fogIntensity = max(dot(distance, distance) + - fogStartOffset, 0);
				fogIntensity = max((fogIntensity * fogScale) + - _CustomFogOffset, 0);
				fogIntensity = 1 / ((fogIntensity * _CustomFogAttenuation) + 1);
				return -fogIntensity;
			}
			#endif
			//endex
			#endif
			//endex
			
			//ifex _EnableDepthBulge==0
			#if defined(POI_DEPTHBULGE)
			void applyDepthBulgeFX(inout VertexOut o)
			{
				float4 pos = UnityObjectToClipPos(o.localPos);
				float4 grabPos = ComputeGrabScreenPos(pos);
				float depth = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(grabPos.xy / grabPos.w, 0, 0));
				
				#if defined(PROP_DEPTHBULGEMASK) || !defined(OPTIMIZER_ENABLED)
				float depthBulgeMask = tex2Dlod(_DepthBulgeMask, float4(poiUV(vertexUV(o, _DepthBulgeMaskUV), _DepthBulgeMask_ST), 0, 0))[_DepthBulgeMaskChannel];
				#else
				float depthBulgeMask = 1.0;
				#endif
				
				depth = Linear01Depth(depth);
				
				float intersect = 0;
				if (depth != 1)
				{
					float diff = distance(depth, Linear01Depth(pos.z / pos.w));
					if (diff > 0)
					{
						intersect = 1 - smoothstep(0, _ProjectionParams.w * _DepthBulgeFadeLength, diff);
					}
				}
				float4 offset = intersect * _DepthBulgeHeight * float4(o.normal, 0);
				
				offset = IsInMirror() ? 0 : offset;
				offset *= depthBulgeMask;
				
				o.worldPos.xyz += offset.xyz;
				o.localPos.xyz += mul(unity_WorldToObject, float4(offset.xyz, 0)).xyz;
			}
			#endif
			//endex
			
			VertexOut vert(
			#ifndef POI_TESSELLATED
			appdata v
			#else
			tessAppData v
			#endif
			)
			{
				UNITY_SETUP_INSTANCE_ID(v);
				VertexOut o;
				PoiInitStruct(VertexOut, o);
				UNITY_TRANSFER_INSTANCE_ID(v, o);
				#ifdef POI_TESSELLATED
				UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v);
				#endif
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
				
				//ifex _EnableUDIMDiscardOptions==0
				#ifdef POI_UDIMDISCARD
				UNITY_BRANCH
				if(_UDIMDiscardMode == 0) // Discard Vertices instead of just pixels
				{
					// Branchless (inspired by s-ilent)
					float2 udim = 0;
					// Select UV
					udim += (v.uv0.xy * (_UDIMDiscardUV == 0));
					udim += (v.uv1.xy * (_UDIMDiscardUV == 1));
					udim += (v.uv2.xy * (_UDIMDiscardUV == 2));
					udim += (v.uv3.xy * (_UDIMDiscardUV == 3));
					
					float isDiscarded = 0;
					float4 xMask = float4(  (udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					isDiscarded += (udim.y >= 0 && udim.y < 1) * dot(float4(_UDIMDiscardRow0_0, _UDIMDiscardRow0_1, _UDIMDiscardRow0_2, _UDIMDiscardRow0_3), xMask);
					isDiscarded += (udim.y >= 1 && udim.y < 2) * dot(float4(_UDIMDiscardRow1_0, _UDIMDiscardRow1_1, _UDIMDiscardRow1_2, _UDIMDiscardRow1_3), xMask);
					isDiscarded += (udim.y >= 2 && udim.y < 3) * dot(float4(_UDIMDiscardRow2_0, _UDIMDiscardRow2_1, _UDIMDiscardRow2_2, _UDIMDiscardRow2_3), xMask);
					isDiscarded += (udim.y >= 3 && udim.y < 4) * dot(float4(_UDIMDiscardRow3_0, _UDIMDiscardRow3_1, _UDIMDiscardRow3_2, _UDIMDiscardRow3_3), xMask);
					
					isDiscarded *= any(float4(udim.y >= 0, udim.y < 4, udim.x >= 0, udim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					// Use a threshold so that there's some room for animations to be close to 0, but not exactly 0
					const float threshold = 0.001;
					if(isDiscarded > threshold) // Early Return skips rest of vertex shader
					{
						return (VertexOut)POI_NAN;
					}
				}
				#endif
				//endex
				
				//ifex _VertexManipulationsEnabled==0
				#ifdef AUTO_EXPOSURE
				float4 audioLinkBands = 0;
				float3 ALrotation = 0;
				float3 ALLocalTranslation = 0;
				float3 CTALRotation = 0;
				float3 ALScale = 0;
				float3 ALWorldTranslation = 0;
				float ALHeight = 0;
				float ALRoundingAmount = 0;
				float4 ALSpectrumLocalOffset = float4(0, 0, 0, 0);
				#ifdef POI_AUDIOLINK
				if (AudioLinkIsAvailable() && _VertexAudioLinkEnabled && _AudioLinkAnimToggle)
				{
					audioLinkBands.x = AudioLinkData(ALPASS_AUDIOBASS).r;
					audioLinkBands.y = AudioLinkData(ALPASS_AUDIOLOWMIDS).r;
					audioLinkBands.z = AudioLinkData(ALPASS_AUDIOHIGHMIDS).r;
					audioLinkBands.w = AudioLinkData(ALPASS_AUDIOTREBLE).r;
					
					if (any(_VertexLocalTranslationALMin) || any(_VertexLocalTranslationALMax))
					{
						ALLocalTranslation = lerp(_VertexLocalTranslationALMin, _VertexLocalTranslationALMax, audioLinkBands[_VertexLocalTranslationALBand]);
					}
					if (any(_VertexLocalRotationAL))
					{
						ALrotation = audioLinkBands[_VertexLocalRotationALBand] * _VertexLocalRotationAL;
					}
					if (any(_VertexLocalRotationCTALSpeed))
					{
						CTALRotation.x = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeX, _VertexLocalRotationCTALBandX) * _VertexLocalRotationCTALSpeed.x * 360;
						CTALRotation.y = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeY, _VertexLocalRotationCTALBandY) * _VertexLocalRotationCTALSpeed.y * 360;
						CTALRotation.z = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeZ, _VertexLocalRotationCTALBandZ) * _VertexLocalRotationCTALSpeed.z * 360;
					}
					if (any(_VertexLocalScaleALMin) || any(_VertexLocalScaleALMax))
					{
						ALScale = lerp(_VertexLocalScaleALMin.xyz + _VertexLocalScaleALMin.w, _VertexLocalScaleALMax.xyz + _VertexLocalScaleALMax.w, audioLinkBands[_VertexLocalScaleALBand]);
					}
					if (any(_VertexWorldTranslationALMin) || any(_VertexWorldTranslationALMax))
					{
						ALWorldTranslation = lerp(_VertexWorldTranslationALMin, _VertexWorldTranslationALMax, audioLinkBands[_VertexWorldTranslationALBand]);
					}
					if (any(_VertexManipulationHeightAL))
					{
						ALHeight = lerp(_VertexManipulationHeightAL.x, _VertexManipulationHeightAL.y, audioLinkBands[_VertexManipulationHeightBand]);
					}
					if (any(_VertexRoundingRangeAL))
					{
						ALRoundingAmount = lerp(_VertexRoundingRangeAL.x, _VertexRoundingRangeAL.y, audioLinkBands[_VertexRoundingRangeBand]);
					}
					if (_VertexSpectrumMotion)
					{
						ALSpectrumLocalOffset.xyz = lerp(_VertexSpectrumOffsetMin.xyz, _VertexSpectrumOffsetMax.xyz, AudioLinkLerpMultiline(ALPASS_DFT + float2(vertexUV(v, _VertexSpectrumUV)[_VertexSpectrumUVDirection] * AUDIOLINK_ETOTALBINS, 0.)));
					}
				}
				#endif
				
				// Local Transformation
				float4 rotation = float4(_VertexManipulationLocalRotation.xyz + float3(180, 0, 0) + _VertexManipulationLocalRotationSpeed * _Time.x + ALrotation + CTALRotation, _VertexManipulationLocalRotation.w);
				v.normal = rotate_with_quaternion(v.normal, rotation.xyz);
				v.tangent.xyz = rotate_with_quaternion(v.tangent.xyz, rotation.xyz);
				v.vertex = transform(v.vertex, _VertexManipulationLocalTranslation + float4(ALLocalTranslation, 0) + ALSpectrumLocalOffset, rotation, _VertexManipulationLocalScale + float4(ALScale, 0));
				o.normal = UnityObjectToWorldNormal(v.normal);
				
				#if defined(PROP_VERTEXMANIPULATIONHEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float3 heightOffset = (tex2Dlod(_VertexManipulationHeightMask, float4(poiUV(vertexUV(v, _VertexManipulationHeightMaskUV), _VertexManipulationHeightMask_ST) + _VertexManipulationHeightMaskPan * _Time.x, 0, 0))[_VertexManipulationHeightMaskChannel] - _VertexManipulationHeightBias) * (_VertexManipulationHeight + ALHeight) * o.normal;
				#else
				float3 heightOffset = (_VertexManipulationHeight + ALHeight) * o.normal;
				#endif
				
				if (_VertexBarrelMode)
				{
					v.vertex.xz = lerp(v.vertex.xz, normalize(v.vertex.xz) * _VertexBarrelWidth + v.vertex.xz * _VertexBarrelHeight, _VertexBarrelAlpha);
				}
				
				if (_VertexSphereMode)
				{
					v.vertex.xyz = lerp(v.vertex.xyz, normalize(v.vertex.xyz + _VertexSphereCenter.xyz) * _VertexSphereRadius + v.vertex.xyz * _VertexSphereHeight, _VertexSphereAlpha);
				}
				
				if (_VertexTornadoMode)
				{
					v.vertex.xz = lerp(v.vertex.xz, float3(v.vertex.xz + float2(cos(_Time.y * _VertexTornadoSpeed + v.vertex.y * _VertexTornadoIntensity) * _VertexTornadoRadius, sin(_Time.y * _VertexTornadoSpeed + v.vertex.y * _VertexTornadoIntensity) * _VertexTornadoRadius), v.vertex.y), smoothstep(_VertexTornadoBaseHeight, _VertexTornadoTopHeight, v.vertex.y));
				}
				
				v.vertex.xyz += mul(unity_WorldToObject, _VertexManipulationWorldTranslation.xyz + ALWorldTranslation + heightOffset).xyz;
				
				// rounding
				UNITY_BRANCH
				if (_VertexRoundingEnabled)
				{
					float divisionAmount = max(_VertexRoundingDivision + ALRoundingAmount, 0.0000001);
					if (_VertexRoundingSpace == 0)
					{
						float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
						float3 worldRoundPosition = (ceil(worldPos.xyz / divisionAmount) * divisionAmount) - divisionAmount * .5;
						v.vertex = mul(unity_WorldToObject, float4(worldRoundPosition, worldPos.w));
					}
					else if (_VertexRoundingSpace == 1)
					{
						v.vertex.xyz = (ceil(v.vertex.xyz / divisionAmount) * divisionAmount) - divisionAmount * .5;
					}
				}
				#endif
				//endex
				
				//ifex _EnableDissolve==0
				#ifdef DISTORT
				UNITY_BRANCH
				if (_UVTileDissolveEnabled && _UVTileDissolveDiscardAtMax)
				{
					// Branchless (inspired by s-ilent)
					float2 dissolveUdim = 0;
					// Select UV
					dissolveUdim += (v.uv0.xy * (_UVTileDissolveUV == 0));
					dissolveUdim += (v.uv1.xy * (_UVTileDissolveUV == 1));
					dissolveUdim += (v.uv2.xy * (_UVTileDissolveUV == 2));
					dissolveUdim += (v.uv3.xy * (_UVTileDissolveUV == 3));
					
					float isDiscardedFromDissolve = 0;
					float4 xMaskDissolve = float4((dissolveUdim.x >= 0 && dissolveUdim.x < 1),
					(dissolveUdim.x >= 1 && dissolveUdim.x < 2),
					(dissolveUdim.x >= 2 && dissolveUdim.x < 3),
					(dissolveUdim.x >= 3 && dissolveUdim.x < 4));
					
					isDiscardedFromDissolve += (dissolveUdim.y >= 0 && dissolveUdim.y < 1) * dot(float4(_UVTileDissolveAlpha_Row0_0, _UVTileDissolveAlpha_Row0_1, _UVTileDissolveAlpha_Row0_2, _UVTileDissolveAlpha_Row0_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 1 && dissolveUdim.y < 2) * dot(float4(_UVTileDissolveAlpha_Row1_0, _UVTileDissolveAlpha_Row1_1, _UVTileDissolveAlpha_Row1_2, _UVTileDissolveAlpha_Row1_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 2 && dissolveUdim.y < 3) * dot(float4(_UVTileDissolveAlpha_Row2_0, _UVTileDissolveAlpha_Row2_1, _UVTileDissolveAlpha_Row2_2, _UVTileDissolveAlpha_Row2_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 3 && dissolveUdim.y < 4) * dot(float4(_UVTileDissolveAlpha_Row3_0, _UVTileDissolveAlpha_Row3_1, _UVTileDissolveAlpha_Row3_2, _UVTileDissolveAlpha_Row3_3), xMaskDissolve);
					
					isDiscardedFromDissolve *= any(float4(dissolveUdim.y >= 0, dissolveUdim.y < 4, dissolveUdim.x >= 0, dissolveUdim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					// Use a threshold so that there's some room for animations to be close to 1, but not exactly 1
					const float threshold = 0.999;
					if (isDiscardedFromDissolve > threshold) // Early Return skips rest of vertex shader
					
					{
						return (VertexOut)POI_NAN;
					}
				}
				#endif
				//endex
				
				//ifex _EnableMirrorOptions==0
				#ifdef POI_MIRROR
				float notVisible = 0;
				
				if (_VisibilityMode == 1) // VRC
				
				{
					float mirrorMode = VRCMirrorMode();
					float cameraMode = VRCCameraMode();
					
					notVisible += (!_VisibilityVRCRegular && ((mirrorMode == 0) && (cameraMode == 0)));
					notVisible += (!_VisibilityVRCMirrorVR && (mirrorMode == 1));
					notVisible += (!_VisibilityVRCMirrorDesktop && (mirrorMode == 2));
					notVisible += (!_VisibilityVRCCameraVR && (cameraMode == 1));
					notVisible += (!_VisibilityVRCCameraDesktop && (cameraMode == 2));
					notVisible += (!_VisibilityVRCCameraScreenshot && (cameraMode == 3));
				}
				else if (_Mirror != 0) // Generic (CVR, etc)
				
				{
					notVisible += (_Mirror == 1) ^ IsInMirror();
				}
				
				if (notVisible) // Early Return skips rest of vertex shader
				
				{
					return (VertexOut)POI_NAN;
				}
				#endif
				//endex
				
				o.normal = UnityObjectToWorldNormal(v.normal);
				o.tangent.xyz = UnityObjectToWorldDir(v.tangent);
				o.tangent.w = v.tangent.w;
				o.vertexColor = v.color;
				
				o.uv[0] = float4(v.uv0.xy, v.uv1.xy);
				o.uv[1] = float4(v.uv2.xy, v.uv3.xy);
				
				#if defined(LIGHTMAP_ON)
				o.lightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
				#endif
				#ifdef DYNAMICLIGHTMAP_ON
				o.lightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
				#endif
				
				o.localPos = v.vertex;
				o.worldPos = mul(unity_ObjectToWorld, o.localPos);
				
				float3 localOffset = float3(0, 0, 0);
				float3 worldOffset = float3(0, 0, 0);
				
				//ifex _EnableOutlines!=1
				#ifdef POI_PASS_OUTLINE
				float outlineMask = tex2Dlod(_OutlineMask, float4(poiUV(vertexUV(v, _OutlineMaskUV), _OutlineMask_ST) + _Time.x * _OutlineMaskPan, 0, 0))[_OutlineMaskChannel];
				
				//UNITY_BRANCH
				if (_OutlineVertexColorMask > 0)
				{
					outlineMask *= lerp(1, v.color[_OutlineVertexColorMask - 1], _OutlineVertexColorMaskStrength);
				}
				
				float3 outlineNormal = _OutlineSpace ? o.normal : v.normal;
				//UNITY_BRANCH
				if (_OutlineUseVertexColorNormals)
				{
					float3 outlineTangent;
					float3 outlineBinormal;
					if (_OutlineSpace) // 0 Local, 1 World
					
					{
						outlineTangent = o.tangent;
						outlineBinormal = cross(o.normal, o.tangent) * (v.tangent.w * unity_WorldTransformParams.w);
					}
					else
					{
						outlineTangent = v.tangent.xyz;
						outlineBinormal = normalize(cross(outlineNormal, outlineTangent)) * (v.tangent.w * length(outlineNormal));
					}
					float3 outlineVectorTS = v.color.rgb * 2.0 - 1.0;
					outlineNormal = outlineVectorTS.x * outlineTangent + outlineVectorTS.y * outlineBinormal + outlineVectorTS.z * outlineNormal;
				}
				
				float offsetMultiplier = 1;
				float distanceOffset = 1;
				//UNITY_BRANCH
				if (_OutlineFixedSize)
				{
					distanceOffset *= lerp(1.0, clamp((distance(_WorldSpaceCameraPos, mul(unity_ObjectToWorld, o.localPos).xyz)), 0.0f, _OutlinesMaxDistance), _OutlineFixWidth);
				}
				
				float lineWidth = _LineWidth;
				#ifdef POI_AUDIOLINK
				// Due to PoiMods.audioLink being frag only I'll just
				// recreate what it does here for this vertex function
				//UNITY_BRANCH
				if (_AudioLinkAnimToggle)
				{
					if (AudioLinkIsAvailable())
					{
						lineWidth += lerp(_AudioLinkOutlineSize.x, _AudioLinkOutlineSize.y, AudioLinkData(uint2(0, _AudioLinkOutlineSizeBand)));
					}
				}
				#endif
				
				float3 offset = outlineNormal * (lineWidth * _EnableOutlines / 100) * outlineMask * distanceOffset;
				
				//UNITY_BRANCH
				if (_OutlineExpansionMode == 2)
				{
					float3 lightDirection = normalize(_WorldSpaceLightPos0 + unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz);
					offsetMultiplier = saturate(dot(lightDirection, outlineNormal));
					offset *= offsetMultiplier;
					offset *= distanceOffset;
				}
				else if (_OutlineExpansionMode == 3)
				{
					float3 viewNormal = mul((float3x3)UNITY_MATRIX_V, outlineNormal);
					offsetMultiplier = saturate(dot(viewNormal.xy, normalize(_OutlinePersonaDirection.xy)));
					
					offset *= offsetMultiplier;
					offset *= distanceOffset;
				}
				else if (_OutlineExpansionMode == 4)
				{
					offset = mul((float3x3)transpose(UNITY_MATRIX_V), _OutlineDropShadowOffset);
					offset *= distanceOffset;
				}
				if (_OutlineSpace == 0)
				{
					localOffset += offset;
					worldOffset += mul(unity_ObjectToWorld, offset);
				}
				else
				{
					localOffset += mul(unity_WorldToObject, offset);
					worldOffset += offset;
				}
				#endif
				//endex
				
				//ifex _VertexGlitchingEnabled==0
				#if defined(POI_VERTEX_GLITCHING)
				
				bool canGlitch = true;
				if (_VertexGlitchMirrorEnable && _VertexGlitchMirror > 0)
				{
					bool inMirror = IsInMirror();
					if (_VertexGlitchMirror == 1 && !inMirror)	canGlitch = false;
					if (_VertexGlitchMirror == 2 && inMirror)	canGlitch = false;
				}
				if (canGlitch)
				{
					float3 forward = getCameraPosition() - mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
					forward.y = 0;
					forward = normalize(forward);
					float3 glitchDirection = normalize(cross(float3(0, 1, 0), forward));
					
					float glitchAmount = 0;
					
					#if defined(POI_VERTEX_GLITCHING_TEXTURE)
					// if(_VertexGlitchingUseTexture)
					// {
					float uvl = o.worldPos.y * _VertexGlitchDensity + _Time.x * _VertexGlitchMapPanSpeed;
					float uvr = o.worldPos.y * _VertexGlitchDensity - _Time.x * _VertexGlitchMapPanSpeed;
					
					float3 glitchTextureL = 1;
					float3 glitchTextureR = 1;
					
					#if defined(POI_VERTEX_GLITCHING_TEXTURE) || !defined(OPTIMIZER_ENABLED)
					glitchTextureL = tex2Dlod(_VertexGlitchMap, float4(uvl, uvl, 0, 0)).rgb;
					glitchTextureR = tex2Dlod(_VertexGlitchMap, float4(uvr, uvr, 0, 0)).rgb;
					#endif
					
					glitchAmount += (glitchTextureL.r - 0.5) * 2;
					glitchAmount += - (glitchTextureR.r - 0.5) * 2;
					
					glitchAmount += (glitchTextureL.g - 0.5) * 2;
					glitchAmount += - (glitchTextureR.b - 0.5) * 2;
					// } else {
					#else
					glitchAmount += frac(sin(dot(_Time.xy + o.worldPos.y, float2(12.9898, 78.233))) * 43758.5453123) * 2 - 1;
					// }
					#endif
					
					float time = _Time.y * _VertexGlitchFrequency;
					
					float randomGlitch = (sin(time) + sin(2.2 * time + 5.52) + sin(2.9 * time + 0.93) + sin(4.6 * time + 8.94)) / 4;
					float3 glitchOffset = 0;
					
					#ifdef POI_AUDIOLINK
					if (AudioLinkIsAvailable() && _VertexGlitchingAudioLinkEnabled)
					{
						// float4 audioLinkData = AudioLinkData(ALPASS_AUDIOBASS);
						
						float audioIntensity =
						AudioLinkData(ALPASS_AUDIOBASS).r 		* (_VertexGlitchingAudioLinkBand == 0) +
						AudioLinkData(ALPASS_AUDIOLOWMIDS).r 	* (_VertexGlitchingAudioLinkBand == 1) +
						AudioLinkData(ALPASS_AUDIOHIGHMIDS).r	* (_VertexGlitchingAudioLinkBand == 2) +
						AudioLinkData(ALPASS_AUDIOTREBLE).r 	* (_VertexGlitchingAudioLinkBand == 3) +
						AudioLinkData(ALPASS_FILTEREDVU_INTENSITY).r * (_VertexGlitchingAudioLinkBand == 4);
						
						if(_VertexGlitchingAudiolinkOverride)
						{
							glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
							// glitchOffset += glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
						} else {
							glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
							glitchOffset += glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
						}
					} else {
						glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
					}
					#else
					glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
					#endif
					
					localOffset += glitchOffset;
					worldOffset += mul(unity_ObjectToWorld, glitchOffset);
				}
				#endif
				//endex
				
				o.localPos.rgb += localOffset;
				o.worldPos.rgb += worldOffset;
				
				//ifex _EnableDepthBulge==0
				#if defined(POI_DEPTHBULGE) && (defined(POI_PASS_BASE) || defined(POI_PASS_ADD))
				applyDepthBulgeFX(o);
				#endif
				//endex
				
				//ifex _BSSEnabled!=1
				#ifdef POIBS_ENABLE
				//ifex _BSSBloomfog!=1
				#ifdef POIBS_BLOOMFOG
				o.fogCoord = GetFogCoord(UnityObjectToClipPos(v.vertex));
				o.worldPos = mul(unity_ObjectToWorld, v.vertex);
				#endif
				//endex
				#endif
				//endex
				
				o.pos = UnityObjectToClipPos(o.localPos);
				
				#ifdef POI_PASS_OUTLINE
				#if defined(UNITY_REVERSED_Z)
				//DX
				o.pos.z += _Offset_Z * - 0.01;
				#else
				//OpenGL
				o.pos.z += _Offset_Z * 0.01;
				#endif
				#endif
				//o.grabPos = ComputeGrabScreenPos(o.pos);
				
				#ifndef FORWARD_META_PASS
				#if !defined(UNITY_PASS_SHADOWCASTER)
				UNITY_TRANSFER_SHADOW(o, o.uv[0].xy);
				#else
				v.vertex.xyz = o.localPos.xyz;
				TRANSFER_SHADOW_CASTER_NOPOS(o, o.pos);
				#endif
				#endif
				
				UNITY_TRANSFER_FOG(o, o.pos);
				
				if (_RenderingReduceClipDistance)
				{
					if (o.pos.w < _ProjectionParams.y * 1.01 && o.pos.w > 0)
					{
						#if defined(UNITY_REVERSED_Z) // DirectX
						o.pos.z = o.pos.z * 0.0001 + o.pos.w * 0.999;
						#else // OpenGL
						o.pos.z = o.pos.z * 0.0001 - o.pos.w * 0.999;
						#endif
					}
				}
				
				#ifdef POI_PASS_META
				o.pos = UnityMetaVertexPosition(v.vertex, v.uv1.xy, v.uv2.xy, unity_LightmapST, unity_DynamicLightmapST);
				#endif
				
				return o;
			}
			
			#if defined(_STOCHASTICMODE_DELIOT_HEITZ)
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, uv) : POI2D_SAMPLER(tex, texSampler, uv))
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan)) : POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), dx, dy) : POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			#if defined(_STOCHASTICMODE_HEXTILE)
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, uv, false) : POI2D_SAMPLER(tex, texSampler, uv))
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), false) : POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), false, dx, dy) : POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			
			#ifndef POI2D_SAMPLER_STOCHASTIC
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (POI2D_SAMPLER(tex, texSampler, uv))
			#endif
			#ifndef POI2D_SAMPLER_PAN_STOCHASTIC
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#endif
			#ifndef POI2D_SAMPLER_PANGRAD_STOCHASTIC
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			
			// When using, properties won't properly lock at optimize time; needs macro evaluation implemented
			// #define POI2D_SAMPLER_STOCHASTIC_INLINED(tex, texSampler) (POI2D_SAMPLER_STOCHASTIC(tex, texSampler, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Stochastic))
			// #define POI2D_SAMPLER_PAN_STOCHASTIC_INLINED(tex, texSampler) (POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan, tex##Stochastic))
			
			// #define POI2D_MAINTEX_SAMPLER_STOCHASTIC_INLINED(tex) (POI2D_SAMPLER_STOCHASTIC(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Stochastic))
			// #define POI2D_MAINTEX_SAMPLER_PAN_STOCHASTIC_INLINED(tex) (POI2D_SAMPLER_PAN_STOCHASTIC(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan, tex##Stochastic))
			
			// Deliot, Heitz 2019 - Fast, but non-histogram-preserving (ends up looking a bit blurry and lower contrast)
			// https://eheitzresearch.wordpress.com/738-2/
			
			// Classic Magic Numbers fracsin
			#if !defined(_STOCHASTICMODE_NONE)
			float2 StochasticHash2D2D (float2 s)
			{
				return frac(sin(glsl_mod(float2(dot(s, float2(127.1,311.7)), dot(s, float2(269.5,183.3))), 3.14159)) * 43758.5453);
			}
			#endif
			
			#if defined(_STOCHASTICMODE_DELIOT_HEITZ)
			// UV Offsets and blend weights
			// UVBW[0...2].xy = UV Offsets
			// UVBW[0...2].z = Blend Weights
			float3x3 DeliotHeitzStochasticUVBW(float2 uv)
			{
				// UV transformed into triangular grid space with UV scaled by approximation of 2*sqrt(3)
				const float2x2 stochasticSkewedGrid = float2x2(1.0, -0.57735027, 0.0, 1.15470054);
				float2 skewUV = mul(stochasticSkewedGrid, uv * 3.4641 * _StochasticDeliotHeitzDensity);
				
				// Vertex IDs and barycentric coords
				float2 vxID = floor(skewUV);
				float3 bary = float3(frac(skewUV), 0);
				bary.z = 1.0 - bary.x - bary.y;
				
				float3x3 pos = float3x3(
				float3(vxID, 				bary.z),
				float3(vxID + float2(0, 1), bary.y),
				float3(vxID + float2(1, 0), bary.x)
				);
				
				float3x3 neg = float3x3(
				float3(vxID + float2(1, 1), 	 -bary.z),
				float3(vxID + float2(1, 0), 1.0 - bary.y),
				float3(vxID + float2(0, 1), 1.0 - bary.x)
				);
				
				return (bary.z > 0) ? pos : neg;
			}
			
			float4 DeliotHeitzSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, float2 dx, float2 dy)
			{
				// UVBW[0...2].xy = UV Offsets
				// UVBW[0...2].z = Blend Weights
				float3x3 UVBW = DeliotHeitzStochasticUVBW(uv);
				
				//blend samples with calculated weights
				return 	mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[0].xy), dx, dy), UVBW[0].z) +
				mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[1].xy), dx, dy), UVBW[1].z) +
				mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[2].xy), dx, dy), UVBW[2].z) ;
			}
			
			float4 DeliotHeitzSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv)
			{
				float2 dx = ddx(uv), dy = ddy(uv);
				return DeliotHeitzSampleTexture(tex, texSampler, uv, dx, dy);
			}
			#endif // defined(_STOCHASTICMODE_DELIOT_HEITZ)
			
			#if defined(_STOCHASTICMODE_HEXTILE)
			// HexTiling: Slower, but histogram-preserving
			// SPDX-License-Idenfitier: MIT
			// Copyright (c) 2022 mmikk
			// https://github.com/mmikk/hextile-demo
			float2 HextileMakeCenUV(float2 vertex)
			{
				// 0.288675 ~= 1/(2*sqrt(3))
				const float2x2 stochasticInverseSkewedGrid = float2x2(1.0, 0.5, 0.0, 1.0/1.15470054);
				return mul(stochasticInverseSkewedGrid, vertex) * 0.288675;
			}
			
			float2x2 HextileLoadRot2x2(float2 idx, float rotStrength)
			{
				float angle = abs(idx.x * idx.y) + abs(idx.x + idx.y) + PI;
				
				// remap to +/-pi
				angle = glsl_mod(angle, 2 * PI);
				if(angle < 0)  angle += 2 * PI;
				if(angle > PI) angle -= 2 * PI;
				
				angle *= rotStrength;
				
				float cs = cos(angle), si = sin(angle);
				return float2x2(cs, -si, si, cs);
			}
			
			// UV Offsets and base blend weights
			// UVBWR[0...2].xy = UV Offsets
			// UVBWR[0...2].zw = rotation costh/sinth -> reconstruct rotation matrix with float2x2(UVBWR[n].z, -UVBWR[n].w, UVBWR[n].w, UVBWR[n].z)
			// UVBWR[3].xyz = Blend Weights (w unused) - needs luminance weighting
			float4x4 HextileUVBWR(float2 uv)
			{
				// Create Triangle Grid
				// Skew input space into simplex triangle grid (3.4641 ~= 2*sqrt(3))
				const float2x2 stochasticSkewedGrid = float2x2(1.0, -0.57735027, 0.0, 1.15470054);
				float2 skewedCoord = mul(stochasticSkewedGrid, uv * 3.4641 * _StochasticHexGridDensity);
				
				float2 baseId = float2(floor(skewedCoord));
				float3 temp = float3(frac(skewedCoord), 0);
				temp.z = 1 - temp.x - temp.y;
				
				float s = step(0.0, -temp.z);
				float s2 = 2 * s - 1;
				
				float3 weights = float3(-temp.z * s2, s - temp.y * s2, s - temp.x * s2);
				
				float2 vertex0 = baseId + float2(s, s);
				float2 vertex1 = baseId + float2(s, 1 - s);
				float2 vertex2 = baseId + float2(1 - s, s);
				
				float2 cen0 = HextileMakeCenUV(vertex0), cen1 = HextileMakeCenUV(vertex1), cen2 = HextileMakeCenUV(vertex2);
				float2x2 rot0 = float2x2(1, 0, 0, 1), rot1 = float2x2(1, 0, 0, 1), rot2 = float2x2(1, 0, 0, 1);
				
				if(_StochasticHexRotationStrength > 0)
				{
					rot0 = HextileLoadRot2x2(vertex0, _StochasticHexRotationStrength);
					rot1 = HextileLoadRot2x2(vertex1, _StochasticHexRotationStrength);
					rot2 = HextileLoadRot2x2(vertex2, _StochasticHexRotationStrength);
				}
				
				return float4x4(
				float4(mul(uv - cen0, rot0) + cen0 + StochasticHash2D2D(vertex0), rot0[0].x, -rot0[0].y),
				float4(mul(uv - cen1, rot1) + cen1 + StochasticHash2D2D(vertex1), rot1[0].x, -rot1[0].y),
				float4(mul(uv - cen2, rot2) + cen2 + StochasticHash2D2D(vertex2), rot2[0].x, -rot2[0].y),
				float4(weights, 0)
				);
			}
			
			float4 HextileSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, bool isNormalMap, float2 dUVdx, float2 dUVdy)
			{
				// For some reason doing this instead of just calculating it directly prevents it from \
				// breaking after a certain number of textures use it. I don't understand why yet
				float4x4 UVBWR = HextileUVBWR(uv);
				
				// 2D Rotation Matrices for dUVdx/dy
				// Not sure if this constant folds during compiling when rot is locked at 0, so force it
				float2x2 rot0 = float2x2(1, 0, 0, 1), rot1 = float2x2(1, 0, 0, 1), rot2 = float2x2(1, 0, 0, 1);
				
				if(_StochasticHexRotationStrength > 0)
				{
					rot0 = float2x2(UVBWR[0].z, -UVBWR[0].w, UVBWR[0].w, UVBWR[0].z);
					rot1 = float2x2(UVBWR[1].z, -UVBWR[1].w, UVBWR[1].w, UVBWR[1].z);
					rot2 = float2x2(UVBWR[2].z, -UVBWR[2].w, UVBWR[2].w, UVBWR[2].z);
				}
				
				// Weights
				float3 W = UVBWR[3].xyz;
				
				// Sample texture
				// float3x4 c = float3x4(
				// 	tex.SampleGrad(texSampler, UVBWR[0].xy, mul(dUVdx, rot0), mul(dUVdy, rot0)),
				// 	tex.SampleGrad(texSampler, UVBWR[1].xy, mul(dUVdx, rot1), mul(dUVdy, rot1)),
				// 	tex.SampleGrad(texSampler, UVBWR[2].xy, mul(dUVdx, rot2), mul(dUVdy, rot2))
				// );
				
				float4 c0 = tex.SampleGrad(texSampler, UVBWR[0].xy, mul(dUVdx, rot0), mul(dUVdy, rot0));
				float4 c1 = tex.SampleGrad(texSampler, UVBWR[1].xy, mul(dUVdx, rot1), mul(dUVdy, rot1));
				float4 c2 = tex.SampleGrad(texSampler, UVBWR[2].xy, mul(dUVdx, rot2), mul(dUVdy, rot2));
				
				// Blend samples using luminance
				// This is technically incorrect for normal maps, but produces very similar
				// results to blending using normal map gradients (steepness)
				const float3 Lw = float3(0.299, 0.587, 0.114);
				float3 Dw = float3(dot(c0.xyz, Lw), dot(c1.xyz, Lw), dot(c2.xyz, Lw));
				
				Dw = lerp(1.0, Dw, _StochasticHexFallOffContrast);
				W = Dw * pow(W, _StochasticHexFallOffPower);
				// In the original hextiling there's a Gain3 step here, but it seems to slow things down \
				// and cause the UVs to break, so I've omitted it. Looks fine without
				
				W /= (W.x + W.y + W.z);
				return W.x * c0 + W.y * c1 + W.z * c2;
			}
			
			float4 HextileSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, bool isNormalMap)
			{
				return HextileSampleTexture(tex, texSampler, uv, isNormalMap, ddx(uv), ddy(uv));
			}
			#endif // defined(_STOCHASTICMODE_HEXTILE)
			
			void applyAlphaOptions(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiMods poiMods)
			{
				poiFragData.alpha = saturate(poiFragData.alpha + _AlphaMod);
				
				if (_AlphaGlobalMask > 0)
				{
					poiFragData.alpha = maskBlend(poiFragData.alpha, poiMods.globalMask[_AlphaGlobalMask - 1], _AlphaGlobalMaskBlendType);
				}
				
				//ifex _AlphaDistanceFade==0 && isNotAnimated(_AlphaDistanceFade)
				if (_AlphaDistanceFade)
				{
					float3 position = _AlphaDistanceFadeType ? poiMesh.worldPos : poiMesh.objectPosition;
					float distanceFadeMultiplier = lerp(_AlphaDistanceFadeMinAlpha, _AlphaDistanceFadeMaxAlpha, smoothstep(_AlphaDistanceFadeMin, _AlphaDistanceFadeMax, distance(position, poiCam.worldPos)));
					if (_AlphaDistanceFadeGlobalMask > 0)
					{
						distanceFadeMultiplier = lerp(1, distanceFadeMultiplier, poiMods.globalMask[_AlphaDistanceFadeGlobalMask - 1]);
					}
					poiFragData.alpha *= distanceFadeMultiplier;
				}
				//endex
				
				//ifex _AlphaFresnel==0 && isNotAnimated(_AlphaFresnel)
				if (_AlphaFresnel)
				{
					float holoRim = saturate(1 - smoothstep(min(_AlphaFresnelSharpness, _AlphaFresnelWidth), _AlphaFresnelWidth, (poiCam.vDotN)));
					holoRim = abs(lerp(1, holoRim, _AlphaFresnelAlpha));
					holoRim = _AlphaFresnelInvert ? 1 - holoRim : holoRim;
					if (_AlphaFresnelGlobalMask > 0)
					{
						holoRim = lerp(1, holoRim, poiMods.globalMask[_AlphaFresnelGlobalMask - 1]);
					}
					poiFragData.alpha *= holoRim;
				}
				//endex
				
				//ifex _AlphaAngular==0 && isNotAnimated(_AlphaAngular)
				if (_AlphaAngular)
				{
					half cameraAngleMin = _CameraAngleMin / 180;
					half cameraAngleMax = _CameraAngleMax / 180;
					half modelAngleMin = _ModelAngleMin / 180;
					half modelAngleMax = _ModelAngleMax / 180;
					float3 pos = _AngleCompareTo == 0 ? poiMesh.objectPosition : poiMesh.worldPos;
					half3 cameraToModelDirection = normalize(pos - getCameraPosition());
					half3 modelForwardDirection = normalize(mul(unity_ObjectToWorld, normalize(_AngleForwardDirection.rgb)));
					half cameraLookAtModel = remapClamped(cameraAngleMax, cameraAngleMin, .5 * dot(cameraToModelDirection, getCameraForward()) + .5);
					half modelLookAtCamera = remapClamped(modelAngleMax, modelAngleMin, .5 * dot(-cameraToModelDirection, modelForwardDirection) + .5);
					float angularAlphaMod = 1;
					if (_AngleType == 0)
					{
						angularAlphaMod = max(cameraLookAtModel, _AngleMinAlpha);
					}
					else if (_AngleType == 1)
					{
						angularAlphaMod = max(modelLookAtCamera, _AngleMinAlpha);
					}
					else if (_AngleType == 2)
					{
						angularAlphaMod = max(cameraLookAtModel * modelLookAtCamera, _AngleMinAlpha);
					}
					if (_AlphaAngularGlobalMask > 0)
					{
						angularAlphaMod = lerp(1, angularAlphaMod, poiMods.globalMask[_AlphaAngularGlobalMask - 1]);
					}
					poiFragData.alpha *= angularAlphaMod;
				}
				//endex
				
				//ifex _AlphaAudioLinkEnabled==0 && isNotAnimated(_AlphaAudioLinkEnabled)
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable && _AlphaAudioLinkEnabled)
				{
					poiFragData.alpha = saturate(poiFragData.alpha + lerp(_AlphaAudioLinkAddRange.x, _AlphaAudioLinkAddRange.y, poiMods.audioLink[_AlphaAudioLinkAddBand]));
				}
				#endif
				//endex
				
			}
			
			//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
			inline half Dither8x8Bayer(int x, int y)
			{
				// Premultiplied by 1/64
				const half dither[ 64 ] = {
					0.015625, 0.765625, 0.203125, 0.953125, 0.06250, 0.81250, 0.25000, 1.00000,
					0.515625, 0.265625, 0.703125, 0.453125, 0.56250, 0.31250, 0.75000, 0.50000,
					0.140625, 0.890625, 0.078125, 0.828125, 0.18750, 0.93750, 0.12500, 0.87500,
					0.640625, 0.390625, 0.578125, 0.328125, 0.68750, 0.43750, 0.62500, 0.37500,
					0.046875, 0.796875, 0.234375, 0.984375, 0.03125, 0.78125, 0.21875, 0.96875,
					0.546875, 0.296875, 0.734375, 0.484375, 0.53125, 0.28125, 0.71875, 0.46875,
					0.171875, 0.921875, 0.109375, 0.859375, 0.15625, 0.90625, 0.09375, 0.84375,
					0.671875, 0.421875, 0.609375, 0.359375, 0.65625, 0.40625, 0.59375, 0.34375
				};
				int r = y * 8 + x;
				return dither[r];
			}
			
			half calcDither(half2 grabPos)
			{
				return Dither8x8Bayer(glsl_mod(grabPos.x, 8), glsl_mod(grabPos.y, 8));
			}
			
			void applyDithering(inout PoiFragData poiFragData, in PoiCam poiCam)
			{
				if (_AlphaDithering)
				{
					float dither = calcDither(poiCam.posScreenPixels) - _AlphaDitherBias;
					poiFragData.alpha = saturate(poiFragData.alpha - (dither * (1 - poiFragData.alpha) * _AlphaDitherGradient));
				}
			}
			//endex
			
			//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
			void ApplyAlphaToCoverage(inout PoiFragData poiFragData, in PoiMesh poiMesh)
			{
				// Force Model Opacity to 1 if desired
				UNITY_BRANCH
				if (_Mode == 1)
				{
					UNITY_BRANCH
					if (_AlphaSharpenedA2C && _AlphaToCoverage)
					{
						// rescale alpha by mip level
						poiFragData.alpha *= 1 + max(0, CalcMipLevel(poiMesh.uv[0] * _MainTex_TexelSize.zw)) * _AlphaMipScale;
						// rescale alpha by partial derivative
						poiFragData.alpha = (poiFragData.alpha - _Cutoff) / max(fwidth(poiFragData.alpha), 0.0001) + _Cutoff;
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
				}
			}
			//endex
			
			void calculateGlobalThemes(inout PoiMods poiMods)
			{
				// Theme colors are defined as HDR; convert to SDR and do the HSV adjustment, then re-apply exposure
				float4 themeColorExposures = 0;
				float4 themeColor0, themeColor1, themeColor2, themeColor3 = 0;
				
				DecomposeHDRColor(_GlobalThemeColor0.rgb, themeColor0.rgb, themeColorExposures.x);
				DecomposeHDRColor(_GlobalThemeColor1.rgb, themeColor1.rgb, themeColorExposures.y);
				DecomposeHDRColor(_GlobalThemeColor2.rgb, themeColor2.rgb, themeColorExposures.z);
				DecomposeHDRColor(_GlobalThemeColor3.rgb, themeColor3.rgb, themeColorExposures.w);
				
				poiMods.globalColorTheme[0] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor0.rgb, frac(_GlobalThemeHue0 + _GlobalThemeHueSpeed0 * _Time.x), _GlobalThemeSaturation0, _GlobalThemeValue0), themeColorExposures.x), _GlobalThemeColor0.a);
				poiMods.globalColorTheme[1] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor1.rgb, frac(_GlobalThemeHue1 + _GlobalThemeHueSpeed1 * _Time.x), _GlobalThemeSaturation1, _GlobalThemeValue1), themeColorExposures.y), _GlobalThemeColor1.a);
				poiMods.globalColorTheme[2] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor2.rgb, frac(_GlobalThemeHue2 + _GlobalThemeHueSpeed2 * _Time.x), _GlobalThemeSaturation2, _GlobalThemeValue2), themeColorExposures.z), _GlobalThemeColor2.a);
				poiMods.globalColorTheme[3] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor3.rgb, frac(_GlobalThemeHue3 + _GlobalThemeHueSpeed3 * _Time.x), _GlobalThemeSaturation3, _GlobalThemeValue3), themeColorExposures.w), _GlobalThemeColor3.a);
			}
			
			//ifex _GlobalMaskTexturesEnable==0
			#ifdef POI_GLOBALMASK_TEXTURES
			void ApplyGlobalMaskTextures(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				#if defined(PROP_GLOBALMASKTEXTURE0) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol0 = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0_ST), _GlobalMaskTexture0Pan);
				if (_GlobalMaskTexture0Split)
				{
					poiMods.globalMask[0] = gmcol0.r;
					poiMods.globalMask[1] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_G), _GlobalMaskTexture0SplitPan_G).g;
					poiMods.globalMask[2] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_B), _GlobalMaskTexture0SplitPan_B).b;
					poiMods.globalMask[3] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_A), _GlobalMaskTexture0SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[0] = gmcol0[0];
					poiMods.globalMask[1] = gmcol0[1];
					poiMods.globalMask[2] = gmcol0[2];
					poiMods.globalMask[3] = gmcol0[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE1) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol1 = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1_ST), _GlobalMaskTexture1Pan);
				if (_GlobalMaskTexture1Split)
				{
					poiMods.globalMask[4] = gmcol1.r;
					poiMods.globalMask[5] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_G), _GlobalMaskTexture1SplitPan_G).g;
					poiMods.globalMask[6] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_B), _GlobalMaskTexture1SplitPan_B).b;
					poiMods.globalMask[7] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_A), _GlobalMaskTexture1SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[4] = gmcol1[0];
					poiMods.globalMask[5] = gmcol1[1];
					poiMods.globalMask[6] = gmcol1[2];
					poiMods.globalMask[7] = gmcol1[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE2) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol2 = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2_ST), _GlobalMaskTexture2Pan);
				if (_GlobalMaskTexture2Split)
				{
					poiMods.globalMask[8] = gmcol2.r;
					poiMods.globalMask[9] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_G), _GlobalMaskTexture2SplitPan_G).g;
					poiMods.globalMask[10] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_B), _GlobalMaskTexture2SplitPan_B).b;
					poiMods.globalMask[11] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_A), _GlobalMaskTexture2SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[8] = gmcol2[0];
					poiMods.globalMask[9] = gmcol2[1];
					poiMods.globalMask[10] = gmcol2[2];
					poiMods.globalMask[11] = gmcol2[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE3) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol3 = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3_ST), _GlobalMaskTexture3Pan);
				if (_GlobalMaskTexture3Split)
				{
					poiMods.globalMask[12] = gmcol3.r;
					poiMods.globalMask[13] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_G), _GlobalMaskTexture3SplitPan_G).g;
					poiMods.globalMask[14] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_B), _GlobalMaskTexture3SplitPan_B).b;
					poiMods.globalMask[15] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_A), _GlobalMaskTexture3SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[12] = gmcol3[0];
					poiMods.globalMask[13] = gmcol3[1];
					poiMods.globalMask[14] = gmcol3[2];
					poiMods.globalMask[15] = gmcol3[3];
				}
				#endif
			}
			#endif
			//endex
			//ifex _GlobalMaskOptionsEnable==0
			void ApplyGlobalMaskOptions(inout PoiMods poiMods)
			{
				//ifex _GlobalMaskOptionsType!=0
				if (_GlobalMaskOptionsType == 0)
				{
					poiMods.globalMask[0] = saturate(poiMods.globalMask[0] + _GlobalMaskSlider_0);
					poiMods.globalMask[1] = saturate(poiMods.globalMask[1] + _GlobalMaskSlider_1);
					poiMods.globalMask[2] = saturate(poiMods.globalMask[2] + _GlobalMaskSlider_2);
					poiMods.globalMask[3] = saturate(poiMods.globalMask[3] + _GlobalMaskSlider_3);
					poiMods.globalMask[4] = saturate(poiMods.globalMask[4] + _GlobalMaskSlider_4);
					poiMods.globalMask[5] = saturate(poiMods.globalMask[5] + _GlobalMaskSlider_5);
					poiMods.globalMask[6] = saturate(poiMods.globalMask[6] + _GlobalMaskSlider_6);
					poiMods.globalMask[7] = saturate(poiMods.globalMask[7] + _GlobalMaskSlider_7);
					poiMods.globalMask[8] = saturate(poiMods.globalMask[8] + _GlobalMaskSlider_8);
					poiMods.globalMask[9] = saturate(poiMods.globalMask[9] + _GlobalMaskSlider_9);
					poiMods.globalMask[10] = saturate(poiMods.globalMask[10] + _GlobalMaskSlider_10);
					poiMods.globalMask[11] = saturate(poiMods.globalMask[11] + _GlobalMaskSlider_11);
					poiMods.globalMask[12] = saturate(poiMods.globalMask[12] + _GlobalMaskSlider_12);
					poiMods.globalMask[13] = saturate(poiMods.globalMask[13] + _GlobalMaskSlider_13);
					poiMods.globalMask[14] = saturate(poiMods.globalMask[14] + _GlobalMaskSlider_14);
					poiMods.globalMask[15] = saturate(poiMods.globalMask[15] + _GlobalMaskSlider_15);
				}
				//endex
				//ifex _GlobalMaskOptionsType!=1
				if (_GlobalMaskOptionsType == 1)
				{
					poiMods.globalMask[0] = lerp(_GlobalMaskMinMaxSlider_0.x, _GlobalMaskMinMaxSlider_0.y, poiMods.globalMask[0]);
					poiMods.globalMask[1] = lerp(_GlobalMaskMinMaxSlider_1.x, _GlobalMaskMinMaxSlider_1.y, poiMods.globalMask[1]);
					poiMods.globalMask[2] = lerp(_GlobalMaskMinMaxSlider_2.x, _GlobalMaskMinMaxSlider_2.y, poiMods.globalMask[2]);
					poiMods.globalMask[3] = lerp(_GlobalMaskMinMaxSlider_3.x, _GlobalMaskMinMaxSlider_3.y, poiMods.globalMask[3]);
					poiMods.globalMask[4] = lerp(_GlobalMaskMinMaxSlider_4.x, _GlobalMaskMinMaxSlider_4.y, poiMods.globalMask[4]);
					poiMods.globalMask[5] = lerp(_GlobalMaskMinMaxSlider_5.x, _GlobalMaskMinMaxSlider_5.y, poiMods.globalMask[5]);
					poiMods.globalMask[6] = lerp(_GlobalMaskMinMaxSlider_6.x, _GlobalMaskMinMaxSlider_6.y, poiMods.globalMask[6]);
					poiMods.globalMask[7] = lerp(_GlobalMaskMinMaxSlider_7.x, _GlobalMaskMinMaxSlider_7.y, poiMods.globalMask[7]);
					poiMods.globalMask[8] = lerp(_GlobalMaskMinMaxSlider_8.x, _GlobalMaskMinMaxSlider_8.y, poiMods.globalMask[8]);
					poiMods.globalMask[9] = lerp(_GlobalMaskMinMaxSlider_9.x, _GlobalMaskMinMaxSlider_9.y, poiMods.globalMask[9]);
					poiMods.globalMask[10] = lerp(_GlobalMaskMinMaxSlider_10.x, _GlobalMaskMinMaxSlider_10.y, poiMods.globalMask[10]);
					poiMods.globalMask[11] = lerp(_GlobalMaskMinMaxSlider_11.x, _GlobalMaskMinMaxSlider_11.y, poiMods.globalMask[11]);
					poiMods.globalMask[12] = lerp(_GlobalMaskMinMaxSlider_12.x, _GlobalMaskMinMaxSlider_12.y, poiMods.globalMask[12]);
					poiMods.globalMask[13] = lerp(_GlobalMaskMinMaxSlider_13.x, _GlobalMaskMinMaxSlider_13.y, poiMods.globalMask[13]);
					poiMods.globalMask[14] = lerp(_GlobalMaskMinMaxSlider_14.x, _GlobalMaskMinMaxSlider_14.y, poiMods.globalMask[14]);
					poiMods.globalMask[15] = lerp(_GlobalMaskMinMaxSlider_15.x, _GlobalMaskMinMaxSlider_15.y, poiMods.globalMask[15]);
				}
				//endex
				//ifex _GlobalMaskOptionsType!=2
				if (_GlobalMaskOptionsType == 2)
				{
					if (_GlobalMaskToggleOn_0)  poiMods.globalMask[0] = 1;
					if (_GlobalMaskToggleOn_1)  poiMods.globalMask[1] = 1;
					if (_GlobalMaskToggleOn_2)  poiMods.globalMask[2] = 1;
					if (_GlobalMaskToggleOn_3)  poiMods.globalMask[3] = 1;
					if (_GlobalMaskToggleOn_4)  poiMods.globalMask[4] = 1;
					if (_GlobalMaskToggleOn_5)  poiMods.globalMask[5] = 1;
					if (_GlobalMaskToggleOn_6)  poiMods.globalMask[6] = 1;
					if (_GlobalMaskToggleOn_7)  poiMods.globalMask[7] = 1;
					if (_GlobalMaskToggleOn_8)  poiMods.globalMask[8] = 1;
					if (_GlobalMaskToggleOn_9)  poiMods.globalMask[9] = 1;
					if (_GlobalMaskToggleOn_10) poiMods.globalMask[10] = 1;
					if (_GlobalMaskToggleOn_11) poiMods.globalMask[11] = 1;
					if (_GlobalMaskToggleOn_12) poiMods.globalMask[12] = 1;
					if (_GlobalMaskToggleOn_13) poiMods.globalMask[13] = 1;
					if (_GlobalMaskToggleOn_14) poiMods.globalMask[14] = 1;
					if (_GlobalMaskToggleOn_15) poiMods.globalMask[15] = 1;
					
					poiMods.globalMask[0] *= (1 - _GlobalMaskToggleOff_0);
					poiMods.globalMask[1] *= (1 - _GlobalMaskToggleOff_1);
					poiMods.globalMask[2] *= (1 - _GlobalMaskToggleOff_2);
					poiMods.globalMask[3] *= (1 - _GlobalMaskToggleOff_3);
					poiMods.globalMask[4] *= (1 - _GlobalMaskToggleOff_4);
					poiMods.globalMask[5] *= (1 - _GlobalMaskToggleOff_5);
					poiMods.globalMask[6] *= (1 - _GlobalMaskToggleOff_6);
					poiMods.globalMask[7] *= (1 - _GlobalMaskToggleOff_7);
					poiMods.globalMask[8] *= (1 - _GlobalMaskToggleOff_8);
					poiMods.globalMask[9] *= (1 - _GlobalMaskToggleOff_9);
					poiMods.globalMask[10] *= (1 - _GlobalMaskToggleOff_10);
					poiMods.globalMask[11] *= (1 - _GlobalMaskToggleOff_11);
					poiMods.globalMask[12] *= (1 - _GlobalMaskToggleOff_12);
					poiMods.globalMask[13] *= (1 - _GlobalMaskToggleOff_13);
					poiMods.globalMask[14] *= (1 - _GlobalMaskToggleOff_14);
					poiMods.globalMask[15] *= (1 - _GlobalMaskToggleOff_15);
				}
				//endex
				
			}
			//endex
			
			float customDistanceBlend(float base, float blend, float blendType)
			{
				switch(blendType)
				{
					case 0: return blendNormal(base, blend); break;
					case 2: return blendMultiply(base, blend); break;
					default: return 0; break;
				}
			}
			
			void handleGlobalMaskDistance(int index, bool enable, bool type, float minAlpha, float maxAlpha, float min, float max, int blendType, in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				if (enable)
				{
					float3 position = type ? poiMesh.worldPos : poiMesh.objectPosition;
					float val = lerp(minAlpha, maxAlpha, smoothstep(min, max, distance(position, _WorldSpaceCameraPos)));
					poiMods.globalMask[index] = saturate(customDistanceBlend(poiMods.globalMask[index], val, blendType));
				}
			}
			
			void ApplyGlobalMaskModifiers(in PoiMesh poiMesh, inout PoiMods poiMods, in PoiCam poiCam)
			{
				//ifex _GlobalMaskModifiersBackfaceEnable==0
				if (_GlobalMaskModifiersBackfaceEnable)
				{
					float facingMode = saturate(poiMesh.isFrontFace) + 1;
					// _GlobalMaskBackface is 0 for ignore, 1 for back only, 2 for front only
					poiMods.globalMask[0] *= _GlobalMaskBackface_0 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_0));
					poiMods.globalMask[1] *= _GlobalMaskBackface_1 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_1));
					poiMods.globalMask[2] *= _GlobalMaskBackface_2 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_2));
					poiMods.globalMask[3] *= _GlobalMaskBackface_3 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_3));
					poiMods.globalMask[4] *= _GlobalMaskBackface_4 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_4));
					poiMods.globalMask[5] *= _GlobalMaskBackface_5 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_5));
					poiMods.globalMask[6] *= _GlobalMaskBackface_6 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_6));
					poiMods.globalMask[7] *= _GlobalMaskBackface_7 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_7));
					poiMods.globalMask[8] *= _GlobalMaskBackface_8 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_8));
					poiMods.globalMask[9] *= _GlobalMaskBackface_9 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_9));
					poiMods.globalMask[10] *= _GlobalMaskBackface_10 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_10));
					poiMods.globalMask[11] *= _GlobalMaskBackface_11 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_11));
					poiMods.globalMask[12] *= _GlobalMaskBackface_12 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_12));
					poiMods.globalMask[13] *= _GlobalMaskBackface_13 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_13));
					poiMods.globalMask[14] *= _GlobalMaskBackface_14 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_14));
					poiMods.globalMask[15] *= _GlobalMaskBackface_15 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_15));
				}
				//endex
				
				//ifex _GlobalMaskModifiersMirrorEnable==0
				if (_GlobalMaskModifiersMirrorEnable)
				{
					float mirrorMode = 0;
					if (_GlobalMaskMirrorVisibilityMode == 1) // VRC
					mirrorMode = VRCMirrorMode() > 0;
					else // Generic (CVR, etc)
					mirrorMode = IsInMirror();
					
					mirrorMode += 1;
					// _GlobalMaskMirror is 0 for ignore, 1 for outside mirror only, 2 for in mirror only
					poiMods.globalMask[0] *= _GlobalMaskMirror_0 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_0));
					poiMods.globalMask[1] *= _GlobalMaskMirror_1 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_1));
					poiMods.globalMask[2] *= _GlobalMaskMirror_2 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_2));
					poiMods.globalMask[3] *= _GlobalMaskMirror_3 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_3));
					poiMods.globalMask[4] *= _GlobalMaskMirror_4 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_4));
					poiMods.globalMask[5] *= _GlobalMaskMirror_5 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_5));
					poiMods.globalMask[6] *= _GlobalMaskMirror_6 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_6));
					poiMods.globalMask[7] *= _GlobalMaskMirror_7 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_7));
					poiMods.globalMask[8] *= _GlobalMaskMirror_8 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_8));
					poiMods.globalMask[9] *= _GlobalMaskMirror_9 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_9));
					poiMods.globalMask[10] *= _GlobalMaskMirror_10 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_10));
					poiMods.globalMask[11] *= _GlobalMaskMirror_11 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_11));
					poiMods.globalMask[12] *= _GlobalMaskMirror_12 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_12));
					poiMods.globalMask[13] *= _GlobalMaskMirror_13 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_13));
					poiMods.globalMask[14] *= _GlobalMaskMirror_14 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_14));
					poiMods.globalMask[15] *= _GlobalMaskMirror_15 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_15));
				}
				//endex
				
				//ifex _GlobalMaskModifiersCameraEnable==0
				if (_GlobalMaskModifiersCameraEnable)
				{
					float isCamera = VRCCameraMode() > 0;
					isCamera += 1;
					// _GlobalMaskCamera is 0 for ignore, 1 for outside camera only, 2 for in camera only
					poiMods.globalMask[0] *= _GlobalMaskCamera_0 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_0));
					poiMods.globalMask[1] *= _GlobalMaskCamera_1 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_1));
					poiMods.globalMask[2] *= _GlobalMaskCamera_2 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_2));
					poiMods.globalMask[3] *= _GlobalMaskCamera_3 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_3));
					poiMods.globalMask[4] *= _GlobalMaskCamera_4 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_4));
					poiMods.globalMask[5] *= _GlobalMaskCamera_5 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_5));
					poiMods.globalMask[6] *= _GlobalMaskCamera_6 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_6));
					poiMods.globalMask[7] *= _GlobalMaskCamera_7 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_7));
					poiMods.globalMask[8] *= _GlobalMaskCamera_8 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_8));
					poiMods.globalMask[9] *= _GlobalMaskCamera_9 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_9));
					poiMods.globalMask[10] *= _GlobalMaskCamera_10 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_10));
					poiMods.globalMask[11] *= _GlobalMaskCamera_11 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_11));
					poiMods.globalMask[12] *= _GlobalMaskCamera_12 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_12));
					poiMods.globalMask[13] *= _GlobalMaskCamera_13 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_13));
					poiMods.globalMask[14] *= _GlobalMaskCamera_14 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_14));
					poiMods.globalMask[15] *= _GlobalMaskCamera_15 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_15));
				}
				//endex
				//ifex _GlobalMaskModifiersDistanceEnable==0
				if (_GlobalMaskModifiersDistanceEnable)
				{
					//ifex _GlobalMaskDistanceEnable_0==0
					handleGlobalMaskDistance(0, _GlobalMaskDistanceEnable_0, _GlobalMaskDistanceType_0, _GlobalMaskDistanceMinAlpha_0, _GlobalMaskDistanceMaxAlpha_0, _GlobalMaskDistanceMin_0, _GlobalMaskDistanceMax_0, _GlobalMaskDistanceBlendType_0, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_1==0
					handleGlobalMaskDistance(1, _GlobalMaskDistanceEnable_1, _GlobalMaskDistanceType_1, _GlobalMaskDistanceMinAlpha_1, _GlobalMaskDistanceMaxAlpha_1, _GlobalMaskDistanceMin_1, _GlobalMaskDistanceMax_1, _GlobalMaskDistanceBlendType_1, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_2==0
					handleGlobalMaskDistance(2, _GlobalMaskDistanceEnable_2, _GlobalMaskDistanceType_2, _GlobalMaskDistanceMinAlpha_2, _GlobalMaskDistanceMaxAlpha_2, _GlobalMaskDistanceMin_2, _GlobalMaskDistanceMax_2, _GlobalMaskDistanceBlendType_2, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_3==0
					handleGlobalMaskDistance(3, _GlobalMaskDistanceEnable_3, _GlobalMaskDistanceType_3, _GlobalMaskDistanceMinAlpha_3, _GlobalMaskDistanceMaxAlpha_3, _GlobalMaskDistanceMin_3, _GlobalMaskDistanceMax_3, _GlobalMaskDistanceBlendType_3, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_4==0
					handleGlobalMaskDistance(4, _GlobalMaskDistanceEnable_4, _GlobalMaskDistanceType_4, _GlobalMaskDistanceMinAlpha_4, _GlobalMaskDistanceMaxAlpha_4, _GlobalMaskDistanceMin_4, _GlobalMaskDistanceMax_4, _GlobalMaskDistanceBlendType_4, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_5==0
					handleGlobalMaskDistance(5, _GlobalMaskDistanceEnable_5, _GlobalMaskDistanceType_5, _GlobalMaskDistanceMinAlpha_5, _GlobalMaskDistanceMaxAlpha_5, _GlobalMaskDistanceMin_5, _GlobalMaskDistanceMax_5, _GlobalMaskDistanceBlendType_5, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_6==0
					handleGlobalMaskDistance(6, _GlobalMaskDistanceEnable_6, _GlobalMaskDistanceType_6, _GlobalMaskDistanceMinAlpha_6, _GlobalMaskDistanceMaxAlpha_6, _GlobalMaskDistanceMin_6, _GlobalMaskDistanceMax_6, _GlobalMaskDistanceBlendType_6, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_7==0
					handleGlobalMaskDistance(7, _GlobalMaskDistanceEnable_7, _GlobalMaskDistanceType_7, _GlobalMaskDistanceMinAlpha_7, _GlobalMaskDistanceMaxAlpha_7, _GlobalMaskDistanceMin_7, _GlobalMaskDistanceMax_7, _GlobalMaskDistanceBlendType_7, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_8==0
					handleGlobalMaskDistance(8, _GlobalMaskDistanceEnable_8, _GlobalMaskDistanceType_8, _GlobalMaskDistanceMinAlpha_8, _GlobalMaskDistanceMaxAlpha_8, _GlobalMaskDistanceMin_8, _GlobalMaskDistanceMax_8, _GlobalMaskDistanceBlendType_8, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_9==0
					handleGlobalMaskDistance(9, _GlobalMaskDistanceEnable_9, _GlobalMaskDistanceType_9, _GlobalMaskDistanceMinAlpha_9, _GlobalMaskDistanceMaxAlpha_9, _GlobalMaskDistanceMin_9, _GlobalMaskDistanceMax_9, _GlobalMaskDistanceBlendType_9, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_10==0
					handleGlobalMaskDistance(10, _GlobalMaskDistanceEnable_10, _GlobalMaskDistanceType_10, _GlobalMaskDistanceMinAlpha_10, _GlobalMaskDistanceMaxAlpha_10, _GlobalMaskDistanceMin_10, _GlobalMaskDistanceMax_10, _GlobalMaskDistanceBlendType_10, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_11==0
					handleGlobalMaskDistance(11, _GlobalMaskDistanceEnable_11, _GlobalMaskDistanceType_11, _GlobalMaskDistanceMinAlpha_11, _GlobalMaskDistanceMaxAlpha_11, _GlobalMaskDistanceMin_11, _GlobalMaskDistanceMax_11, _GlobalMaskDistanceBlendType_11, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_12==0
					handleGlobalMaskDistance(12, _GlobalMaskDistanceEnable_12, _GlobalMaskDistanceType_12, _GlobalMaskDistanceMinAlpha_12, _GlobalMaskDistanceMaxAlpha_12, _GlobalMaskDistanceMin_12, _GlobalMaskDistanceMax_12, _GlobalMaskDistanceBlendType_12, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_13==0
					handleGlobalMaskDistance(13, _GlobalMaskDistanceEnable_13, _GlobalMaskDistanceType_13, _GlobalMaskDistanceMinAlpha_13, _GlobalMaskDistanceMaxAlpha_13, _GlobalMaskDistanceMin_13, _GlobalMaskDistanceMax_13, _GlobalMaskDistanceBlendType_13, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_14==0
					handleGlobalMaskDistance(14, _GlobalMaskDistanceEnable_14, _GlobalMaskDistanceType_14, _GlobalMaskDistanceMinAlpha_14, _GlobalMaskDistanceMaxAlpha_14, _GlobalMaskDistanceMin_14, _GlobalMaskDistanceMax_14, _GlobalMaskDistanceBlendType_14, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_15==0
					handleGlobalMaskDistance(15, _GlobalMaskDistanceEnable_15, _GlobalMaskDistanceType_15, _GlobalMaskDistanceMinAlpha_15, _GlobalMaskDistanceMaxAlpha_15, _GlobalMaskDistanceMin_15, _GlobalMaskDistanceMax_15, _GlobalMaskDistanceBlendType_15, poiMesh, poiMods);
					//endex
					
				}
				//endex
				
			}
			
			//ifex _GlobalMaskVertexColorRed==0 && _GlobalMaskVertexColorGreen==0 && _GlobalMaskVertexColorBlue==0 && _GlobalMaskVertexColorAlpha==0
			void ApplyGlobalMaskVertexColors(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				float4 vcol = poiMesh.vertexColor;
				if (_GlobalMaskVertexColorLinearSpace)
				{
					vcol.rgb = GammaToLinearSpace(vcol.rgb);
				}
				if (_GlobalMaskVertexColorRed > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorRed - 1, _GlobalMaskVertexColorRedBlendType, vcol.r);
				}
				if (_GlobalMaskVertexColorGreen > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorGreen - 1, _GlobalMaskVertexColorGreenBlendType, vcol.g);
				}
				if (_GlobalMaskVertexColorBlue > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorBlue - 1, _GlobalMaskVertexColorBlueBlendType, vcol.b);
				}
				if (_GlobalMaskVertexColorAlpha > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorAlpha - 1, _GlobalMaskVertexColorAlphaBlendType, vcol.a);
				}
			}
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#ifdef POI_UDIMDISCARD
			void applyUDIMDiscard(in VertexOut i)
			{
				if(_UDIMDiscardMode == 1) // Don't run if in vertex mode
				{
					float2 udim = floor(vertexUV(i, _UDIMDiscardUV));
					
					float isDiscarded = 0;
					float4 xMask = float4(  (udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					isDiscarded += (udim.y >= 0 && udim.y < 1) * dot(float4(_UDIMDiscardRow0_0, _UDIMDiscardRow0_1, _UDIMDiscardRow0_2, _UDIMDiscardRow0_3), xMask);
					isDiscarded += (udim.y >= 1 && udim.y < 2) * dot(float4(_UDIMDiscardRow1_0, _UDIMDiscardRow1_1, _UDIMDiscardRow1_2, _UDIMDiscardRow1_3), xMask);
					isDiscarded += (udim.y >= 2 && udim.y < 3) * dot(float4(_UDIMDiscardRow2_0, _UDIMDiscardRow2_1, _UDIMDiscardRow2_2, _UDIMDiscardRow2_3), xMask);
					isDiscarded += (udim.y >= 3 && udim.y < 4) * dot(float4(_UDIMDiscardRow3_0, _UDIMDiscardRow3_1, _UDIMDiscardRow3_2, _UDIMDiscardRow3_3), xMask);
					
					isDiscarded *= any(float4(udim.y >= 0, udim.y < 4, udim.x >= 0, udim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					const float threshold = 0.001;
					clip(threshold - isDiscarded); // Clip if discarded
				}
				
				return;
			}
			#endif
			//endex
			
			float2 calculatePolarCoordinate(in PoiMesh poiMesh)
			{
				float2 delta = poiMesh.uv[_PolarUV] - _PolarCenter;
				float radius = length(delta) * 2 * _PolarRadialScale;
				float angle = atan2(delta.x, delta.y);
				float phi = angle / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				angle = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				angle *= _PolarLengthScale;
				
				return float2(radius, angle + distance(poiMesh.uv[_PolarUV], _PolarCenter) * _PolarSpiralPower);
			}
			
			float2 MonoPanoProjection(float3 coords)
			{
				float3 normalizedCoords = normalize(coords);
				float latitude = acos(normalizedCoords.y);
				float longitude = atan2(normalizedCoords.z, normalizedCoords.x);
				float phi = longitude / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				longitude = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				longitude *= 2;
				float2 sphereCoords = float2(longitude, latitude) * float2(1.0, 1.0 / UNITY_PI);
				sphereCoords = float2(1.0, 1.0) - sphereCoords;
				return (sphereCoords + float4(0, 1 - unity_StereoEyeIndex, 1, 1.0).xy) * float4(0, 1 - unity_StereoEyeIndex, 1, 1.0).zw;
			}
			
			float2 StereoPanoProjection(float3 coords)
			{
				float3 normalizedCoords = normalize(coords);
				float latitude = acos(normalizedCoords.y);
				float longitude = atan2(normalizedCoords.z, normalizedCoords.x);
				float phi = longitude / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				longitude = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				longitude *= 2;
				float2 sphereCoords = float2(longitude, latitude) * float2(0.5, 1.0 / UNITY_PI);
				sphereCoords = float2(0.5, 1.0) - sphereCoords;
				return (sphereCoords + float4(0, 1 - unity_StereoEyeIndex, 1, 0.5).xy) * float4(0, 1 - unity_StereoEyeIndex, 1, 0.5).zw;
			}
			
			float2 calculateWorldUV(in PoiMesh poiMesh)
			{
				return float2(_UVModWorldPos0 != 3 ? poiMesh.worldPos[ _UVModWorldPos0] : 0.0f, _UVModWorldPos1 != 3 ? poiMesh.worldPos[_UVModWorldPos1] : 0.0f);
			}
			
			float2 calculatelocalUV(in PoiMesh poiMesh)
			{
				float localUVs[8];
				localUVs[0] = poiMesh.localPos.x;
				localUVs[1] = poiMesh.localPos.y;
				localUVs[2] = poiMesh.localPos.z;
				localUVs[3] = 0;
				localUVs[4] = poiMesh.vertexColor.r;
				localUVs[5] = poiMesh.vertexColor.g;
				localUVs[6] = poiMesh.vertexColor.b;
				localUVs[7] = poiMesh.vertexColor.a;
				
				return float2(localUVs[_UVModLocalPos0],localUVs[_UVModLocalPos1]);
			}
			
			float2 calculatePanosphereUV(in PoiMesh poiMesh)
			{
				float3 viewDirection = normalize(lerp(getCameraPosition().xyz, _WorldSpaceCameraPos.xyz, _PanoUseBothEyes) - poiMesh.worldPos.xyz) * - 1;
				return lerp(MonoPanoProjection(viewDirection), StereoPanoProjection(viewDirection), _StereoEnabled);
			}
			//ifex _EnableDistortion==0
			#ifdef USER_LUT
			float2 distortedUV(in PoiMesh poiMesh)
			{
				#if defined(PROP_DISTORTIONFLOWTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 flowVector = POI2D_SAMPLER_PAN(_DistortionFlowTexture, _MainTex, poiUV(poiMesh.uv[_DistortionFlowTextureUV], _DistortionFlowTexture_ST), _DistortionFlowTexturePan) * 2 - 1;
				#else
				float4 flowVector = -1;
				#endif
				
				#if defined(PROP_DISTORTIONFLOWTEXTURE1) || !defined(OPTIMIZER_ENABLED)
				float4 flowVector1 = POI2D_SAMPLER_PAN(_DistortionFlowTexture1, _MainTex, poiUV(poiMesh.uv[_DistortionFlowTexture1UV], _DistortionFlowTexture1_ST), _DistortionFlowTexture1Pan) * 2 - 1;
				#else
				float4 flowVector1 = -1;
				#endif
				
				#if defined(PROP_DISTORTIONMASK) || !defined(OPTIMIZER_ENABLED)
				half distortionMask = POI2D_SAMPLER_PAN(_DistortionMask, _MainTex, poiMesh.uv[_DistortionMaskUV], _DistortionMaskPan)[_DistortionMaskChannel];
				#else
				half distortionMask = 1;
				#endif
				
				half distortionStrength = _DistortionStrength;
				half distortionStrength1 = _DistortionStrength1;
				
				#ifdef POI_AUDIOLINK
				UNITY_BRANCH
				if (AudioLinkIsAvailable() && _EnableDistortionAudioLink && _AudioLinkAnimToggle)
				{
					distortionStrength += lerp(_DistortionStrengthAudioLink.x, _DistortionStrengthAudioLink.y, AudioLinkData(uint2(0, uint(_DistortionStrengthAudioLinkBand))).r);
					distortionStrength1 += lerp(_DistortionStrength1AudioLink.x, _DistortionStrength1AudioLink.y, AudioLinkData(uint2(0, uint(_DistortionStrength1AudioLinkBand))).r);
				}
				#endif
				
				flowVector *= distortionStrength;
				flowVector1 *= distortionStrength1;
				return poiMesh.uv[_DistortionUvToDistort] + ((flowVector.xy + flowVector1.xy) / 2) * distortionMask;
			}
			#endif
			//endex
			
			//ifex _PoiParallax==0
			#ifdef POI_PARALLAX
			inline float2 POM(in PoiLight poiLight, sampler2D heightMap, in PoiMesh poiMesh, float3 worldViewDir, float3 viewDirTan, int minSamples, int maxSamples, float parallax, float refPlane, float2 tilling, float2 curv)
			{
				#if defined(PROP_HEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float heightMask = POI2D_SAMPLER_PAN(_Heightmask, _linear_repeat, poiUV(poiMesh.uv[_HeightmaskUV], _Heightmask_ST), _HeightmaskPan)[_HeightmaskChannel];
				if (_HeightmaskInvert)
				{
					heightMask = 1 - heightMask;
				}
				#else
				float heightMask = 1;
				#endif
				
				float2 uvs = poiUV(poiMesh.uv[_HeightMapUV], _HeightMap_ST);
				float2 dx = ddx(uvs);
				float2 dy = ddy(uvs);
				float3 result = 0;
				int stepIndex = 0;
				int numSteps = (int)lerp(maxSamples, minSamples, saturate(dot(poiMesh.normals[0], worldViewDir)));
				float layerHeight = 1.0 / numSteps;
				float2 plane = parallax * heightMask * (viewDirTan.xy / viewDirTan.z);
				uvs += refPlane * plane;
				float2 deltaTex = -plane * layerHeight;
				float2 prevTexOffset = 0;
				float prevRayZ = 1.0f;
				float prevHeight = 0.0f;
				float2 currTexOffset = deltaTex;
				float currRayZ = 1.0f - layerHeight;
				float currHeight = 0.0f;
				float intersection = 0;
				float2 finalTexOffset = 0;
				while (stepIndex < numSteps + 1)
				{
					result.z = dot(curv, currTexOffset * currTexOffset);
					currHeight = tex2Dgrad(heightMap, uvs + currTexOffset, dx, dy).r * (1 - result.z);
					if (currHeight > currRayZ)
					{
						stepIndex = numSteps + 1;
					}
					else
					{
						stepIndex++;
						prevTexOffset = currTexOffset;
						prevRayZ = currRayZ;
						prevHeight = currHeight;
						currTexOffset += deltaTex;
						currRayZ -= layerHeight * (1 - result.z) * (1 + _CurvFix);
					}
				}
				int sectionSteps = 10;
				int sectionIndex = 0;
				float newZ = 0;
				float newHeight = 0;
				while (sectionIndex < sectionSteps)
				{
					intersection = (prevHeight - prevRayZ) / (prevHeight - currHeight + currRayZ - prevRayZ);
					finalTexOffset = prevTexOffset +intersection * deltaTex;
					newZ = prevRayZ - intersection * layerHeight;
					newHeight = tex2Dgrad(heightMap, uvs + finalTexOffset, dx, dy).r;
					if (newHeight > newZ)
					{
						currTexOffset = finalTexOffset;
						currHeight = newHeight;
						currRayZ = newZ;
						deltaTex = intersection * deltaTex;
						layerHeight = intersection * layerHeight;
					}
					else
					{
						prevTexOffset = finalTexOffset;
						prevHeight = newHeight;
						prevRayZ = newZ;
						deltaTex = (1 - intersection) * deltaTex;
						layerHeight = (1 - intersection) * layerHeight;
					}
					sectionIndex++;
				}
				#ifdef UNITY_PASS_SHADOWCASTER
				if (unity_LightShadowBias.z == 0.0)
				{
					#endif
					if (result.z > 1)
					clip(-1);
					#ifdef UNITY_PASS_SHADOWCASTER
				}
				#endif
				
				return uvs + finalTexOffset;
			}
			/*
			float2 ParallaxOffsetMultiStep(float surfaceHeight, float strength, float2 uv, float3 tangentViewDir)
			{
				float2 uvOffset = 0;
				float2 prevUVOffset = 0;
				float stepSize = 1.0 / _HeightSteps;
				float stepHeight = 1;
				float2 uvDelta = tangentViewDir.xy * (stepSize * strength);
				float prevStepHeight = stepHeight;
				float prevSurfaceHeight = surfaceHeight;
				
				[unroll(20)]
				for (int j = 1; j <= _HeightSteps && stepHeight > surfaceHeight; j++)
				{
					prevUVOffset = uvOffset;
					prevStepHeight = stepHeight;
					prevSurfaceHeight = surfaceHeight;
					uvOffset -= uvDelta;
					stepHeight -= stepSize;
					surfaceHeight = POI2D_SAMPLER_PAN(_Heightmap, _MainTex, poiUV(uv + uvOffset, _Heightmap_ST), _HeightmapPan) + _HeightOffset;
				}
				
				[unroll(3)]
				for (int k = 0; k < 3; k++)
				{
					uvDelta *= 0.5;
					stepSize *= 0.5;
					
					if (stepHeight < surfaceHeight)
					{
						uvOffset += uvDelta;
						stepHeight += stepSize;
					}
					else
					{
						uvOffset -= uvDelta;
						stepHeight -= stepSize;
					}
					surfaceHeight = POI2D_SAMPLER_PAN(_Heightmap, _MainTex, poiUV(uv + uvOffset, _Heightmap_ST), _HeightmapPan) + _HeightOffset;
				}
				return uvOffset;
			}
			*/
			void applyParallax(inout PoiMesh poiMesh, in PoiLight poiLight, in PoiCam poiCam)
			{
				/*
				half h = POI2D_SAMPLER_PAN(_Heightmap, _linear_repeat, poiUV(poiMesh.uv[_HeightmaskUV], _Heightmap_ST), _HeightmapPan).r + _HeightOffset;
				#if defined(PROP_HEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				half m = POI2D_SAMPLER_PAN(_Heightmask, _linear_repeat, poiUV(poiMesh.uv[_HeightmaskUV], _Heightmask_ST), _HeightmaskPan).r + _HeightOffset;
				#else
				half m = 1 + _HeightOffset;
				#endif
				h = clamp(h, 0, 0.999);
				m = lerp(m, 1 - m, _HeightmaskInvert);
				#if defined(OPTIMIZER_ENABLED)das
				poiMesh.uv[_ParallaxUV] += ParallaxOffsetMultiStep(h, _HeightStrength * m, poiMesh.uv[_HeightmapUV], tangentViewDir / tangentViewDir.z);
				#else
				float2 offset = ParallaxOffsetMultiStep(h, _HeightStrength * m, poiMesh.uv[_HeightmapUV], tangentViewDir / tangentViewDir.z);
				if (_ParallaxUV == 0)       poiMesh.uv[0] += offset;
				if (_ParallaxUV == 1)       poiMesh.uv[1] += offset;
				if (_ParallaxUV == 2)       poiMesh.uv[2] += offset;
				if (_ParallaxUV == 3)       poiMesh.uv[3] += offset;
				if (_ParallaxUV == 4)       poiMesh.uv[4] += offset;
				if (_ParallaxUV == 5)       poiMesh.uv[5] += offset;
				if (_ParallaxUV == 6)       poiMesh.uv[6] += offset;
				if (_ParallaxUV == 7)       poiMesh.uv[7] += offset;
				#endif
				*/
				
				#if defined(OPTIMIZER_ENABLED)
				poiMesh.uv[_ParallaxUV] = POM(poiLight, _HeightMap, poiMesh, poiCam.viewDir, poiCam.tangentViewDir, _HeightStepsMin, _HeightStepsMax, _HeightStrength, 0, _HeightMap_ST.xy, float2(_CurvatureU, _CurvatureV));
				#else
				float2 offset = POM(poiLight, _HeightMap, poiMesh, poiCam.viewDir, poiCam.tangentViewDir, _HeightStepsMin, _HeightStepsMax, _HeightStrength, 0, _HeightMap_ST.xy, float2(_CurvatureU, _CurvatureV));
				if (_ParallaxUV == 0)       poiMesh.uv[0] = offset;
				if (_ParallaxUV == 1)       poiMesh.uv[1] = offset;
				if (_ParallaxUV == 2)       poiMesh.uv[2] = offset;
				if (_ParallaxUV == 3)       poiMesh.uv[3] = offset;
				if (_ParallaxUV == 4)       poiMesh.uv[4] = offset;
				if (_ParallaxUV == 5)       poiMesh.uv[5] = offset;
				if (_ParallaxUV == 6)       poiMesh.uv[6] = offset;
				if (_ParallaxUV == 7)       poiMesh.uv[7] = offset;
				#endif
			}
			#endif
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#ifdef POI_BLACKLIGHTMASKING
			void calculateBlackLightMasks(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				#ifdef VERTEXLIGHT_ON
				for (int lightIndex = 0; lightIndex < 4; lightIndex++)
				{
					float3 lightPos = float3(unity_4LightPosX0[lightIndex], unity_4LightPosY0[lightIndex], unity_4LightPosZ0[lightIndex]);
					if (!distance(unity_LightColor[lightIndex].rgb, float3(0, 0, 0)))
					{
						if (_BlackLightMasking0GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking0Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking0GlobalMaskIndex - 1, _BlackLightMasking0GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking1GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking1Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking1GlobalMaskIndex - 1, _BlackLightMasking1GlobalMaskBlendType, smoothstep(_BlackLightMasking1Range.y, _BlackLightMasking1Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking2GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking2Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking2GlobalMaskIndex - 1, _BlackLightMasking2GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking3GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking3Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking3GlobalMaskIndex - 1, _BlackLightMasking3GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
					}
				}
				#else
				if (_BlackLightMasking0GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking0GlobalMaskIndex - 1, _BlackLightMasking0GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking1GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking1GlobalMaskIndex - 1, _BlackLightMasking1GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking2GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking2GlobalMaskIndex - 1, _BlackLightMasking2GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking3GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking3GlobalMaskIndex - 1, _BlackLightMasking3GlobalMaskBlendType, 0);
				}
				#endif
			}
			#endif
			//endex
			
			//ifex _DetailEnabled==0
			#ifdef FINALPASS
			void ApplyDetailColor(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				#if defined(PROP_DETAILTEX) || !defined(OPTIMIZER_ENABLED)
				half3 detailTexture = POI2D_SAMPLER_PAN_STOCHASTIC(_DetailTex, _MainTex, poiUV(poiMesh.uv[_DetailTexUV], _DetailTex_ST), _DetailTexPan, _DetailTexStochastic).rgb * poiThemeColor(poiMods, _DetailTint, _DetailTintThemeIndex);
				#else
				half3 detailTexture = 0.21763764082 * poiThemeColor(poiMods, _DetailTint, _DetailTintThemeIndex);
				#endif
				
				poiFragData.baseColor.rgb *= LerpWhiteTo(detailTexture * _DetailBrightness * unity_ColorSpaceDouble.rgb, poiMods.detailMask.r * _DetailTexIntensity);
			}
			
			void ApplyDetailNormal(inout PoiMods poiMods, inout PoiMesh poiMesh)
			{
				#if defined(PROP_DETAILMASK) || !defined(OPTIMIZER_ENABLED)
				poiMods.detailMask = POI2D_SAMPLER_PAN_STOCHASTIC(_DetailMask, _MainTex, poiUV(poiMesh.uv[_DetailMaskUV], _DetailMask_ST), _DetailMaskPan, _DetailMaskStochastic).rg;
				#else
				poiMods.detailMask = 1;
				#endif
				
				#ifdef POI_BACKFACE
				if (!poiMesh.isFrontFace)
				{
					poiMods.detailMask.rg *= _BackFaceDetailIntensity;
				}
				#endif
				
				if (_DetailTexGlobalMask > 0)
				{
					poiMods.detailMask.r = maskBlend(poiMods.detailMask.r, poiMods.globalMask[_DetailTexGlobalMask-1], _DetailTexGlobalMaskBlendType);
				}
				if (_DetailNormalGlobalMask > 0)
				{
					poiMods.detailMask.g = maskBlend(poiMods.detailMask.g, poiMods.globalMask[_DetailNormalGlobalMask-1], _DetailNormalGlobalMaskBlendType);
				}
				
				#if defined(PROP_DETAILNORMALMAP) || !defined(OPTIMIZER_ENABLED)
				half3 detailNormal = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_DetailNormalMap, _MainTex, poiUV(poiMesh.uv[_DetailNormalMapUV], _DetailNormalMap_ST), _DetailNormalMapPan, _DetailNormalMapStochastic), _DetailNormalMapScale * poiMods.detailMask.g);
				poiMesh.tangentSpaceNormal = BlendNormals(detailNormal, poiMesh.tangentSpaceNormal);
				#endif
			}
			#endif
			//endex
			
			//ifex _MainVertexColoringEnabled==0
			void applyVertexColor(inout PoiFragData poiFragData, PoiMesh poiMesh)
			{
				if (_MainVertexColoringEnabled)
				{
					#ifndef POI_PASS_OUTLINE
					float3 vertCol = lerp(poiMesh.vertexColor.rgb, GammaToLinearSpace(poiMesh.vertexColor.rgb), _MainVertexColoringLinearSpace);
					poiFragData.baseColor *= lerp(1, vertCol, _MainVertexColoring);
					#endif
					poiFragData.alpha *= lerp(1, poiMesh.vertexColor.a, _MainUseVertexColorAlpha);
				}
			}
			//endex
			
			//ifex _BackFaceEnabled!=1
			#ifdef POI_BACKFACE
			void ApplyBackFaceColor(inout PoiFragData poiFragData, in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				if (!poiMesh.isFrontFace)
				{
					float4 backFaceColor = _BackFaceColor;
					backFaceColor.rgb = poiThemeColor(poiMods, backFaceColor.rgb, _BackFaceColorThemeIndex);
					#if defined(PROP_BACKFACETEXTURE) || !defined(OPTIMIZER_ENABLED)
					backFaceColor *= POI2D_SAMPLER_PAN(_BackFaceTexture, _MainTex, poiUV(poiMesh.uv[_BackFaceTextureUV], _BackFaceTexture_ST), _BackFaceTexturePan);
					#endif
					backFaceColor.rgb = hueShift(backFaceColor.rgb, frac(_BackFaceHueShift + _BackFaceHueShiftSpeed * _Time.x) * _BackFaceHueShiftEnabled);
					
					float backFaceMask = 1;
					#if defined(PROP_BACKFACEMASK) || !defined(OPTIMIZER_ENABLED)
					backFaceMask *= POI2D_SAMPLER_PAN(_BackFaceMask, _MainTex, poiUV(poiMesh.uv[_BackFaceMaskUV], _BackFaceMask_ST), _BackFaceMaskPan)[_BackFaceMaskChannel];
					#endif
					if (!_BackFaceReplaceAlpha)
					{
						backFaceMask *= backFaceColor.a;
					}
					
					poiFragData.baseColor = lerp(poiFragData.baseColor, backFaceColor.rgb, backFaceMask);
					
					UNITY_BRANCH
					if (_BackFaceReplaceAlpha)
					{
						poiFragData.alpha = backFaceColor.a;
					}
					
					poiFragData.emission += backFaceColor.rgb * _BackFaceEmissionStrength * backFaceMask;
					poiMods.globalEmission = poiMods.globalEmission * _BackFaceEmissionLimiter;
				}
			}
			#endif
			//endex
			
			//ifex _RGBMaskEnabled==0
			
			void RGBABlendColor(inout PoiFragData poiFragData, in float mask, in float4 color, float emissionStrength, in float blendType, in float blendAdd, in float enabled)
			{
				if (!enabled) return;
				float alpha = mask * saturate(color.a + blendAdd);
				poiFragData.baseColor = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, color.rgb, blendType), alpha);
				poiFragData.emission += color.rgb * emissionStrength * alpha;
			}
			
			void RGBABlendNormals(inout float3 tangentSpaceNormal, float3 normalToBlendWith, float maskValue, int blendMode)
			{
				if (blendMode == 0)
				{
					tangentSpaceNormal = lerp(tangentSpaceNormal, normalToBlendWith, maskValue);
				}
				else
				{
					tangentSpaceNormal = BlendNormals(tangentSpaceNormal, normalToBlendWith);
				}
			}
			
			#ifdef VIGNETTE
			#if !defined(UNITY_PASS_SHADOWCASTER) && !defined(POI_PASS_OUTLINE)
			void calculateRGBNormals(inout PoiMesh poiMesh, inout PoiMods poiMods)
			{
				// Only define this if we actually have any normal map textures. Can't do the same in color textures because users can tint
				#if defined(PROP_RGBNORMALR) || defined(PROP_RGBNORMALG) || defined(PROP_RGBNORMALB) || defined(PROP_RGBNORMALA) || !defined(OPTIMIZER_ENABLED)
				float4 rgbMask = 1;
				
				#if defined(PROP_RGBMASK) || !defined(OPTIMIZER_ENABLED)
				if (_RGBMaskType == 0)
				{
					rgbMask = POI2D_SAMPLER_PAN(_RGBMask, _trilinear_repeat, poiUV(poiMesh.uv[_RGBMaskUV], _RGBMask_ST), _RGBMaskPan);
				}
				#endif
				
				if (_RGBMaskType == 1)
				{
					rgbMask = poiMesh.vertexColor;
				}
				
				float4 maskFinal = 1;
				maskFinal.r = rgbMask[_RgbNormalRMaskChannel];
				maskFinal.g = rgbMask[_RgbNormalGMaskChannel];
				maskFinal.b = rgbMask[_RgbNormalBMaskChannel];
				maskFinal.a = rgbMask[_RgbNormalAMaskChannel];
				
				if (_RgbNormalRGlobalMaskChannel > 0) maskFinal.r = customBlend(maskFinal.r, poiMods.globalMask[_RgbNormalRGlobalMaskChannel - 1], _RgbNormalRGlobalMaskBlendType);
				if (_RgbNormalGGlobalMaskChannel > 0) maskFinal.g = customBlend(maskFinal.g, poiMods.globalMask[_RgbNormalGGlobalMaskChannel - 1], _RgbNormalGGlobalMaskBlendType);
				if (_RgbNormalBGlobalMaskChannel > 0) maskFinal.b = customBlend(maskFinal.b, poiMods.globalMask[_RgbNormalBGlobalMaskChannel - 1], _RgbNormalBGlobalMaskBlendType);
				if (_RgbNormalAGlobalMaskChannel > 0) maskFinal.a = customBlend(maskFinal.a, poiMods.globalMask[_RgbNormalAGlobalMaskChannel - 1], _RgbNormalAGlobalMaskBlendType);
				
				#if defined(PROP_RGBNORMALR) || !defined(OPTIMIZER_ENABLED)
				if (_RgbNormalRScale > 0 && _RGBARedEnable)
				{
					float3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_RgbNormalR, _trilinear_repeat, poiUV(poiMesh.uv[_RgbNormalRUV], _RgbNormalR_ST), _RgbNormalRPan, _RgbNormalRStochastic), _RgbNormalRedBlendMode == 0 ? _RgbNormalRScale : _RgbNormalRScale * maskFinal.r);
					RGBABlendNormals(poiMesh.tangentSpaceNormal, normalToBlendWith, maskFinal.r, _RgbNormalRedBlendMode);
				}
				#endif
				#if defined(PROP_RGBNORMALG) || !defined(OPTIMIZER_ENABLED)
				if (_RgbNormalGScale > 0 && _RGBAGreenEnable)
				{
					float3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_RgbNormalG, _trilinear_repeat, poiUV(poiMesh.uv[_RgbNormalGUV], _RgbNormalG_ST), _RgbNormalGPan, _RgbNormalGStochastic), _RgbNormalGreenBlendMode == 0 ? _RgbNormalGScale : _RgbNormalGScale * maskFinal.g);
					RGBABlendNormals(poiMesh.tangentSpaceNormal, normalToBlendWith, maskFinal.g, _RgbNormalGreenBlendMode);
				}
				#endif
				#if defined(PROP_RGBNORMALB) || !defined(OPTIMIZER_ENABLED)
				if (_RgbNormalBScale > 0 && _RGBABlueEnable)
				{
					float3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_RgbNormalB, _trilinear_repeat, poiUV(poiMesh.uv[_RgbNormalBUV], _RgbNormalB_ST), _RgbNormalBPan, _RgbNormalBStochastic), _RgbNormalBlueBlendMode == 0 ? _RgbNormalBScale : _RgbNormalBScale * maskFinal.b);
					RGBABlendNormals(poiMesh.tangentSpaceNormal, normalToBlendWith, maskFinal.b, _RgbNormalBlueBlendMode);
				}
				#endif
				#if defined(PROP_RGBNORMALA) || !defined(OPTIMIZER_ENABLED)
				if (_RgbNormalAScale > 0 && _RGBAAlphaEnable)
				{
					float3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_RgbNormalA, _trilinear_repeat, poiUV(poiMesh.uv[_RgbNormalAUV], _RgbNormalA_ST), _RgbNormalAPan, _RgbNormalAStochastic), _RgbNormalAlphaBlendMode == 0 ? _RgbNormalAScale : _RgbNormalAScale * maskFinal.a);
					RGBABlendNormals(poiMesh.tangentSpaceNormal, normalToBlendWith, maskFinal.a, _RgbNormalAlphaBlendMode);
				}
				#endif
				#endif
			}
			#endif
			
			void calculateRGBMask(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float4 rgbMask = float4(1, 1, 1, 1);
				float4 red = float4(poiThemeColor(poiMods, _RedColor.rgb, _RedColorThemeIndex), _RedColor.a);
				float4 green = float4(poiThemeColor(poiMods, _GreenColor.rgb, _GreenColorThemeIndex), _GreenColor.a);
				float4 blue = float4(poiThemeColor(poiMods, _BlueColor.rgb, _BlueColorThemeIndex), _BlueColor.a);
				float4 alpha = float4(poiThemeColor(poiMods, _AlphaColor.rgb, _AlphaColorThemeIndex), _AlphaColor.a);
				
				#if defined(PROP_RGBMASK) || !defined(OPTIMIZER_ENABLED)
				if (_RGBMaskType == 0)
				{
					rgbMask = POI2D_SAMPLER_PAN(_RGBMask, _trilinear_repeat, poiUV(poiMesh.uv[_RGBMaskUV], _RGBMask_ST), _RGBMaskPan);
				}
				#endif
				
				if (_RGBMaskType == 1)
				{
					rgbMask = poiMesh.vertexColor;
				}
				
				#if defined(PROP_REDTEXTURE) || !defined(OPTIMIZER_ENABLED)
				red *= POI2D_SAMPLER_PAN_STOCHASTIC(_RedTexture, _trilinear_repeat, poiUV(poiMesh.uv[_RedTextureUV], _RedTexture_ST), _RedTexturePan.xy, _RedTextureStochastic);
				#endif
				#if defined(PROP_GREENTEXTURE) || !defined(OPTIMIZER_ENABLED)
				green *= POI2D_SAMPLER_PAN_STOCHASTIC(_GreenTexture, _trilinear_repeat, poiUV(poiMesh.uv[_GreenTextureUV], _GreenTexture_ST), _GreenTexturePan.xy, _GreenTextureStochastic);
				#endif
				#if defined(PROP_BLUETEXTURE) || !defined(OPTIMIZER_ENABLED)
				blue *= POI2D_SAMPLER_PAN_STOCHASTIC(_BlueTexture, _trilinear_repeat, poiUV(poiMesh.uv[_BlueTextureUV], _BlueTexture_ST), _BlueTexturePan.xy, _BlueTextureStochastic);
				#endif
				#if defined(PROP_ALPHATEXTURE) || !defined(OPTIMIZER_ENABLED)
				alpha *= POI2D_SAMPLER_PAN_STOCHASTIC(_AlphaTexture, _trilinear_repeat, poiUV(poiMesh.uv[_AlphaTextureUV], _AlphaTexture_ST), _AlphaTexturePan.xy, _AlphaTextureStochastic);
				#endif
				
				RGBABlendColor(poiFragData, globalMaskBlend(rgbMask[_RgbRedMaskChannel], _RgbRedGlobalMaskChannel, _RgbRedGlobalMaskBlendType, poiMods), red, _RGBARedEmissionStrength, _RGBARedBlendType, _RedAlphaAdd, _RGBARedEnable);
				RGBABlendColor(poiFragData, globalMaskBlend(rgbMask[_RgbGreenMaskChannel], _RgbGreenGlobalMaskChannel, _RgbGreenGlobalMaskBlendType, poiMods), green, _RGBAGreenEmissionStrength, _RGBAGreenBlendType, _GreenAlphaAdd, _RGBAGreenEnable);
				RGBABlendColor(poiFragData, globalMaskBlend(rgbMask[_RgbBlueMaskChannel], _RgbBlueGlobalMaskChannel, _RgbBlueGlobalMaskBlendType, poiMods), blue, _RGBABlueEmissionStrength, _RGBABlueBlendType, _BlueAlphaAdd, _RGBABlueEnable);
				RGBABlendColor(poiFragData, globalMaskBlend(rgbMask[_RgbAlphaMaskChannel], _RgbAlphaGlobalMaskChannel, _RgbAlphaGlobalMaskBlendType, poiMods), alpha, _RGBAAlphaEmissionStrength, _RGBAAlphaBlendType, _AlphaAlphaAdd, _RGBAAlphaEnable);
				
				if (_RGBAPBRRedEnabled || _RGBAPBRGreenEnabled || _RGBAPBRBlueEnabled || _RGBAPBRAlphaEnabled)
				{
					#if defined(PROP_RGBASMOOTHNESSMAPS) || !defined(OPTIMIZER_ENABLED)
					float4 smoothnessMaps = 1;
					if (!_RGBARedPBRSplitMaskSample || !_RGBAGreenPBRSplitMaskSample || !_RGBABluePBRSplitMaskSample || !_RGBAAlphaPBRSplitMaskSample)
					{
						smoothnessMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBASmoothnessMapsUV], _RGBASmoothnessMaps_ST), _RGBASmoothnessMapsPan.xy, _RGBASmoothnessMapsStochastic);
					}
					
					if (_RGBARedPBRSplitMaskSample && _RGBAPBRRedEnabled && _RGBARedEnable)
					{
						smoothnessMaps.r = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBARedPBRUV], _RGBARedPBRMaskScaleTiling), _RGBARedPBRMasksPan.xy, _RGBARedPBRSplitMaskStochastic).r;
					}
					if (_RGBAGreenPBRSplitMaskSample && _RGBAPBRGreenEnabled && _RGBAGreenEnable)
					{
						smoothnessMaps.g = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAGreenPBRUV], _RGBAGreenPBRMaskScaleTiling), _RGBAGreenPBRMasksPan.xy, _RGBAGreenPBRSplitMaskStochastic).g;
					}
					if (_RGBABluePBRSplitMaskSample && _RGBAPBRBlueEnabled && _RGBABlueEnable)
					{
						smoothnessMaps.b = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBABluePBRUV], _RGBABluePBRMaskScaleTiling), _RGBABluePBRMasksPan.xy, _RGBABluePBRSplitMaskStochastic).b;
					}
					if (_RGBAAlphaPBRSplitMaskSample && _RGBAPBRAlphaEnabled && _RGBAAlphaEnable)
					{
						smoothnessMaps.a = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAAlphaPBRUV], _RGBAAlphaPBRMaskScaleTiling), _RGBAAlphaPBRMasksPan.xy, _RGBAAlphaPBRSplitMaskStochastic).a;
					}
					
					poiFragData.smoothness = lerp(poiFragData.smoothness, poiInvertToggle(smoothnessMaps.r, _RGBARedSmoothnessInvert), rgbMask[_RgbRedMaskChannel] * (_RGBAPBRRedEnabled && _RGBARedEnable));
					poiFragData.smoothness = lerp(poiFragData.smoothness, poiInvertToggle(smoothnessMaps.g, _RGBAGreenSmoothnessInvert), rgbMask[_RgbGreenMaskChannel] * (_RGBAPBRGreenEnabled && _RGBAGreenEnable));
					poiFragData.smoothness = lerp(poiFragData.smoothness, poiInvertToggle(smoothnessMaps.b, _RGBABlueSmoothnessInvert), rgbMask[_RgbBlueMaskChannel] * (_RGBAPBRBlueEnabled && _RGBABlueEnable));
					poiFragData.smoothness = lerp(poiFragData.smoothness, poiInvertToggle(smoothnessMaps.a, _RGBAAlphaSmoothnessInvert), rgbMask[_RgbAlphaMaskChannel] * (_RGBAPBRAlphaEnabled && _RGBAAlphaEnable));
					#endif
					
					#if defined(PROP_RGBAMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
					float4 metallicMaps = 1;
					if (!_RGBARedPBRSplitMaskSample || !_RGBAGreenPBRSplitMaskSample || !_RGBABluePBRSplitMaskSample || !_RGBAAlphaPBRSplitMaskSample)
					{
						metallicMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAMetallicMapsUV], _RGBAMetallicMaps_ST), _RGBAMetallicMapsPan.xy, _RGBAMetallicMapsStochastic);
					}
					
					if (_RGBARedPBRSplitMaskSample && _RGBAPBRRedEnabled && _RGBARedEnable)
					{
						metallicMaps.r = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBARedPBRUV], _RGBARedPBRMaskScaleTiling), _RGBARedPBRMasksPan.xy, _RGBARedPBRSplitMaskStochastic).r;
					}
					if (_RGBAGreenPBRSplitMaskSample && _RGBAPBRGreenEnabled && _RGBAGreenEnable)
					{
						metallicMaps.g = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAGreenPBRUV], _RGBAGreenPBRMaskScaleTiling), _RGBAGreenPBRMasksPan.xy, _RGBAGreenPBRSplitMaskStochastic).g;
					}
					if (_RGBABluePBRSplitMaskSample && _RGBAPBRBlueEnabled && _RGBABlueEnable)
					{
						metallicMaps.b = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBABluePBRUV], _RGBABluePBRMaskScaleTiling), _RGBABluePBRMasksPan.xy, _RGBABluePBRSplitMaskStochastic).b;
					}
					if (_RGBAAlphaPBRSplitMaskSample && _RGBAPBRAlphaEnabled && _RGBAAlphaEnable)
					{
						metallicMaps.a = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAAlphaPBRUV], _RGBAAlphaPBRMaskScaleTiling), _RGBAAlphaPBRMasksPan.xy, _RGBAAlphaPBRSplitMaskStochastic).a;
					}
					
					poiFragData.metallic = lerp(poiFragData.metallic, poiInvertToggle(metallicMaps.r, _RGBARedMetallicInvert), rgbMask[_RgbRedMaskChannel] * (_RGBAPBRRedEnabled && _RGBARedEnable));
					poiFragData.metallic = lerp(poiFragData.metallic, poiInvertToggle(metallicMaps.g, _RGBAGreenMetallicInvert), rgbMask[_RgbGreenMaskChannel] * (_RGBAPBRGreenEnabled && _RGBAGreenEnable));
					poiFragData.metallic = lerp(poiFragData.metallic, poiInvertToggle(metallicMaps.b, _RGBABlueMetallicInvert), rgbMask[_RgbBlueMaskChannel] * (_RGBAPBRBlueEnabled && _RGBABlueEnable));
					poiFragData.metallic = lerp(poiFragData.metallic, poiInvertToggle(metallicMaps.a, _RGBAAlphaMetallicInvert), rgbMask[_RgbAlphaMaskChannel] * (_RGBAPBRAlphaEnabled && _RGBAAlphaEnable));
					#endif
				}
			}
			#endif
			//endex
			
			//ifex _LTCGIEnabled!=1
			#ifdef POI_LTCGI
			// #include "../../ThirdParty/LTCGI/LTCGI_structs.cginc"
			// LTCGI_structs.cginc
			#define LTCGI_COLORMODE_STATIC 0
			#define LTCGI_COLORMODE_TEXTURE 1
			#define LTCGI_COLORMODE_SINGLEUV 2
			#define LTCGI_COLORMODE_AUDIOLINK 3
			
			struct ltcgi_flags
			{
				bool doublesided; // if the light is doublesided or only illuminates the front face
				bool diffFromLm; // diffuse lighting intensity will not be calculated via LTC but taken directly from the lightmap
				bool specular; // if the light has a specular component
				bool diffuse; // if the light has a diffuse component
				uint colormode; // colormode, see above
				uint texindex; // index of the texture to shade with, if colormode == LTCGI_COLORMODE_TEXTURE
				uint lmch, lmidx; // lightmap channel and index
				bool cylinder; // is this light a cylinder
				uint alBand; // audiolink band if colormode == LTCGI_COLORMODE_AUDIOLINK
				bool lmdOnly; // if this light is lightmap-diffuse _only_, that is, no LTC will be run (Lw will be all 0 in that case) - this will never be true on avatars (with LTCGI_ALWAYS_LTC_DIFFUSE)
				
			};
			
			struct ltcgi_input
			{
				uint i; // light number
				float3 Lw[4]; // world space area light vertices, Lw[1] == Lw[3] for triangle lights, shifted by input worldPos (i.e. world space position as seen from (0, 0, 0))
				bool isTri; // if this is a triangle light, quad if false
				float2 uvStart; //
				float2 uvEnd; // defines the UV layout of the area, top left to bottom right
				float3 rawColor; // the raw light color, unaffected by any colormode calculations (i.e. exactly what's given as "color" in editor)
				float3 screenNormal; // world space normal direction of area light
				ltcgi_flags flags; // flags, see above
				
			};
			
			struct ltcgi_output
			{
				ltcgi_input input; // input data that resulted in this output
				
				float intensity; // intensity output by LTC calculation
				float3 color; // color output by LTCGI colormode calculation
				
			};
			// LTCGI_structs.cginc END
			
			struct accumulator_struct
			{
				float3 diffuse;
				float3 specular;
			};
			
			void callback_diffuse(inout accumulator_struct acc, in ltcgi_output output);
			void callback_specular(inout accumulator_struct acc, in ltcgi_output output);
			
			#define LTCGI_V2_CUSTOM_INPUT accumulator_struct
			#define LTCGI_V2_DIFFUSE_CALLBACK callback_diffuse
			#define LTCGI_V2_SPECULAR_CALLBACK callback_specular
			
			// #include "../../ThirdParty/LTCGI/LTCGI.cginc"
			// LTCGI.cginc
			// #include "LTCGI_config.cginc"
			// LTCGI_config.cginc
			
			// Feel free to enable or disable (//) the options here.
			// They will apply to all LTCGI materials in the project.
			// Most of these can be changed in the LTCGI_Controller editor as well.
			
			/// No specular at all.
			//#define LTCGI_SPECULAR_OFF
			/// No diffuse at all.
			//#define LTCGI_DIFFUSE_OFF
			/// Disable the ability to toggle specular/diffuse on or off per screen.
			//#define LTCGI_TOGGLEABLE_SPEC_DIFF_OFF
			
			/// Only use LTC diffuse mode, never lightmapped diffuse.
			/// This disables lightmaps entirely.
			//#define LTCGI_ALWAYS_LTC_DIFFUSE
			
			/// Use bicubic filtering for LTCGI lightmap. Recommended on.
			#define LTCGI_BICUBIC_LIGHTMAP
			
			/// Lightmap values below this will be treated as black for specular/LTC diffuse.
			#define LTCGI_LIGHTMAP_CUTOFF 0.1
			/// Lightmap values above this (plus cutoff) will be treated as white.
			#define LTCGI_SPECULAR_LIGHTMAP_STEP 0.3
			
			/// Distance multiplier for calculating blur amount.
			/// Increase to make reflections blurrier faster as distance increases.
			#define LTCGI_UV_BLUR_DISTANCE 333
			
			/// Fall back to LTC diffuse (from LM diffuse) on objects that are not marked static.
			#define LTCGI_LTC_DIFFUSE_FALLBACK
			
			/// Approximation to ignore diffuse light for far away
			/// lights, increase MULT or disable if you notice artifacting
			#define LTCGI_DISTANCE_FADE_APPROX
			/// Distance at which diffuse from screens will be ignored.
			#define LTCGI_DISTANCE_FADE_APPROX_MULT 50
			
			// disabled editor from here on out
			///
			
			// Allow statically textured lights.
			// (deprecated: doesn't really cause any improvement when disabled...)
			#define LTCGI_STATIC_TEXTURES
			
			// keep in sync with LTCGI_Controller.cs
			#define MAX_SOURCES 16
			
			// set according to the LUT specified on CONTROLLER
			#define LUT_SIZE 256
			static float LUT_SCALE = (LUT_SIZE - 1.0) / LUT_SIZE;
			const float LUT_BIAS = 0.5 / LUT_SIZE;
			
			// will be set automatically if audiolink is available
			#ifdef POI_AUDIOLINK
			#define LTCGI_AUDIOLINK
			#endif
			
			// #ifdef LTCGI_AUDIOLINK
			// #ifndef AUDIOLINK_WIDTH
			// #ifndef AUDIOLINK_CGINC_INCLUDED
			// #include "Packages/com.llealloo.audiolink/Runtime/Shaders/AudioLink.cginc"
			// #define AUDIOLINK_CGINC_INCLUDED
			// #endif
			// #endif
			// #endif
			
			// Bake screen data into texture for better performance. Disables moveable screens.
			#define LTCGI_STATIC_UNIFORMS
			
			// Enable support for cylindrical screens.
			#define LTCGI_CYLINDER
			
			// Activate avatar mode, which overrides certain configs from above.
			#define LTCGI_AVATAR_MODE
			
			// LTCGI_config.cginc END
			
			#ifdef LTCGI_AVATAR_MODE
			#undef LTCGI_STATIC_UNIFORMS
			#undef LTCGI_BICUBIC_LIGHTMAP
			#define LTCGI_ALWAYS_LTC_DIFFUSE
			#endif
			
			#ifdef LTCGI_TOGGLEABLE_SPEC_DIFF_OFF
			#undef LTCGI_DIFFUSE_OFF
			#undef LTCGI_SPECULAR_OFF
			#endif
			
			#if defined(LTCGI_V2_CUSTOM_INPUT) || defined(LTCGI_V2_DIFFUSE_CALLBACK) || defined(LTCGI_V2_SPECULAR_CALLBACK)
			#define LTCGI_API_V2
			#endif
			
			// #include "LTCGI_uniform.cginc"
			// global sampler (trilinear)
			#ifndef LTCGI_SAMPLER
			SamplerState sampler_LTCGI_trilinear_clamp_sampler;
			#define LTCGI_SAMPLER sampler_LTCGI_trilinear_clamp_sampler
			#endif
			
			// LUTs
			#ifndef SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER
			uniform Texture2D<float4> _Udon_LTCGI_lut2;
			uniform Texture2D<float4> _Udon_LTCGI_lut1;
			#endif
			
			#ifndef SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER
			uniform Texture2D<float4> _Udon_LTCGI_static_uniforms;
			#endif
			
			#ifdef LTCGI_STATIC_UNIFORMS
			
			float4 _Udon_LTCGI_Vertices_0_get(uint i)
			{
				return _Udon_LTCGI_static_uniforms[uint2(0, i)];
			}
			float4 _Udon_LTCGI_Vertices_1_get(uint i)
			{
				return _Udon_LTCGI_static_uniforms[uint2(1, i)];
			}
			float4 _Udon_LTCGI_Vertices_2_get(uint i)
			{
				return _Udon_LTCGI_static_uniforms[uint2(2, i)];
			}
			float4 _Udon_LTCGI_Vertices_3_get(uint i)
			{
				return _Udon_LTCGI_static_uniforms[uint2(3, i)];
			}
			
			#else
			
			// vertices in object space; w component is UV (legacy)
			uniform float4 _Udon_LTCGI_Vertices_0[MAX_SOURCES];
			uniform float4 _Udon_LTCGI_Vertices_1[MAX_SOURCES];
			uniform float4 _Udon_LTCGI_Vertices_2[MAX_SOURCES];
			uniform float4 _Udon_LTCGI_Vertices_3[MAX_SOURCES];
			
			float4 _Udon_LTCGI_Vertices_0_get(uint i)
			{
				return _Udon_LTCGI_Vertices_0[i];
			}
			float4 _Udon_LTCGI_Vertices_1_get(uint i)
			{
				return _Udon_LTCGI_Vertices_1[i];
			}
			float4 _Udon_LTCGI_Vertices_2_get(uint i)
			{
				return _Udon_LTCGI_Vertices_2[i];
			}
			float4 _Udon_LTCGI_Vertices_3_get(uint i)
			{
				return _Udon_LTCGI_Vertices_3[i];
			}
			
			#endif
			
			// light source count, maximum is MAX_SOURCES
			uniform uint _Udon_LTCGI_ScreenCount;
			
			// per-renderer mask to select sources,
			// for max perf update _Udon_LTCGI_ScreenCount too
			uniform bool _Udon_LTCGI_Mask[MAX_SOURCES];
			
			// extra data per light source, layout:
			//  color.r   color.g   color.b   flags*
			// * b0=double-sided, b1=diffuse-from-lightmap, b2=specular, b3=diffuse,
			//   b4-b7=texture index (0=video, (n>0)=n-1)
			//   b8-b9=color mode
			//   b10-b11=lightmap channel (0=disabled, 1=r, 2=g, 3=b)
			//   b12=cylinder
			//   b13-14=audio link band
			//   b15=lightmap diffuse only
			// (color black = fully disabled)
			uniform float4 _Udon_LTCGI_ExtraData[MAX_SOURCES];
			
			ltcgi_flags ltcgi_parse_flags(uint val, bool noLmDiff)
			{
				ltcgi_flags ret = (ltcgi_flags)0;
				ret.doublesided = (val & 1) == 1;
				
				#ifdef LTCGI_ALWAYS_LTC_DIFFUSE
				ret.diffFromLm = false;
				#else
				ret.diffFromLm = !noLmDiff && (val & 2) == 2;
				#endif
				
				ret.diffuse = (val & 8) == 8;
				
				ret.specular = (val & 4) == 4;
				ret.texindex = (val & 0xf0) >> 4;
				ret.colormode = (val & 0x300) >> 8;
				
				#ifdef LTCGI_ALWAYS_LTC_DIFFUSE
				ret.lmch = 0;
				#else
				ret.lmch = (val & 0xC00) >> 10;
				#endif
				
				ret.cylinder = (val & (1 << 12)) == (1 << 12);
				
				#ifdef LTCGI_AUDIOLINK
				ret.alBand = (val & 0x6000) >> 13;
				#endif
				
				ret.lmdOnly = (val & (1 << 15)) == (1 << 15);
				
				return ret;
			}
			
			// video input
			#ifndef SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER
			uniform Texture2D<float4> _Udon_LTCGI_Texture_LOD0;
			uniform Texture2D<float4> _Udon_LTCGI_Texture_LOD1;
			uniform Texture2D<float4> _Udon_LTCGI_Texture_LOD2;
			uniform Texture2D<float4> _Udon_LTCGI_Texture_LOD3;
			#endif
			
			// static textures
			UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(_Udon_LTCGI_Texture_LOD0_arr);
			UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(_Udon_LTCGI_Texture_LOD1_arr);
			UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(_Udon_LTCGI_Texture_LOD2_arr);
			UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(_Udon_LTCGI_Texture_LOD3_arr);
			
			// lightmap
			#ifndef SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER
			#ifndef LTCGI_ALWAYS_LTC_DIFFUSE
			uniform Texture2D<float4> _Udon_LTCGI_Lightmap;
			#endif
			#endif
			uniform float3 _Udon_LTCGI_LightmapMult;
			uniform float4 _Udon_LTCGI_LightmapST;
			
			// global toggle
			uniform float _Udon_LTCGI_GlobalEnable;
			
			// #include "LTCGI_uniform.cginc" END
			// #include "LTCGI_functions.cginc"
			
			/*
			LTC HELPERS
			*/
			
			float3 LTCGI_IntegrateEdge(float3 v1, float3 v2)
			{
				float x = dot(v1, v2);
				float y = abs(x);
				
				float a = 0.8543985 + (0.4965155 + 0.0145206 * y) * y;
				float b = 3.4175940 + (4.1616724 + y) * y;
				float v = a / b;
				float theta_sintheta = (x > 0.0) ? v : 0.5 * rsqrt(max(1.0 - x * x, 1e-7)) - v;
				
				return cross(v1, v2) * theta_sintheta;
			}
			
			void LTCGI_ClipQuadToHorizon(inout float3 L[5], out int n)
			{
				// detect clipping config
				uint config = 0;
				if (L[0].z > 0.0) config += 1;
				if (L[1].z > 0.0) config += 2;
				if (L[2].z > 0.0) config += 4;
				if (L[3].z > 0.0) config += 8;
				
				n = 0;
				
				// This [forcecase] only works when the cases are ordered in a specific manner.
				// It gives like 10%-20% performance boost, so *make sure to leave it on*!
				// If it breaks however, see if [branch] fixes it, and if it does, start
				// reordering cases at random until it works again.
				// It seems the compiler somehow optimizes away anything but setting 'n' in
				// some orderings, including the ascending and descending ones.
				// I wish I was joking.
				[forcecase]
				switch(config)
				{
					case 13: // V1 V3 V4 clip V2 <- tl;dr: this fecker has to be first or shader go boom
					n = 5;
					L[4] = L[3];
					L[3] = L[2];
					L[2] = -L[1].z * L[2] + L[2].z * L[1];
					L[1] = -L[1].z * L[0] + L[0].z * L[1];
					break;
					case 15: // V1 V2 V3 V4 - most common
					n = 4;
					break;
					case 9: // V1 V4 clip V2 V3
					n = 4;
					L[1] = -L[1].z * L[0] + L[0].z * L[1];
					L[2] = -L[2].z * L[3] + L[3].z * L[2];
					break;
					case 0: // clip all
					break;
					case 1: // V1 clip V2 V3 V4
					n = 3;
					L[1] = -L[1].z * L[0] + L[0].z * L[1];
					L[2] = -L[3].z * L[0] + L[0].z * L[3];
					L[3] = L[0];
					break;
					case 2: // V2 clip V1 V3 V4
					n = 3;
					L[0] = -L[0].z * L[1] + L[1].z * L[0];
					L[2] = -L[2].z * L[1] + L[1].z * L[2];
					L[3] = L[0];
					break;
					case 3: // V1 V2 clip V3 V4
					n = 4;
					L[2] = -L[2].z * L[1] + L[1].z * L[2];
					L[3] = -L[3].z * L[0] + L[0].z * L[3];
					break;
					case 4: // V3 clip V1 V2 V4
					n = 3;
					L[0] = -L[3].z * L[2] + L[2].z * L[3];
					L[1] = -L[1].z * L[2] + L[2].z * L[1];
					L[3] = L[0];
					break;
					case 5: // V1 V3 clip V2 V4) impossible
					break;
					case 6: // V2 V3 clip V1 V4
					n = 4;
					L[0] = -L[0].z * L[1] + L[1].z * L[0];
					L[3] = -L[3].z * L[2] + L[2].z * L[3];
					break;
					case 7: // V1 V2 V3 clip V4
					n = 5;
					L[4] = -L[3].z * L[0] + L[0].z * L[3];
					L[3] = -L[3].z * L[2] + L[2].z * L[3];
					break;
					case 8: // V4 clip V1 V2 V3
					n = 3;
					L[0] = -L[0].z * L[3] + L[3].z * L[0];
					L[1] = -L[2].z * L[3] + L[3].z * L[2];
					L[2] = L[3];
					break;
					case 10: // V2 V4 clip V1 V3) impossible
					break;
					case 11: // V1 V2 V4 clip V3
					n = 5;
					L[4] = L[3];
					L[3] = -L[2].z * L[3] + L[3].z * L[2];
					L[2] = -L[2].z * L[1] + L[1].z * L[2];
					break;
					case 12: // V3 V4 clip V1 V2
					n = 4;
					L[1] = -L[1].z * L[2] + L[2].z * L[1];
					L[0] = -L[0].z * L[3] + L[3].z * L[0];
					break;
					case 14: // V2 V3 V4 clip V1
					n = 5;
					L[4] = -L[0].z * L[3] + L[3].z * L[0];
					L[0] = -L[0].z * L[1] + L[1].z * L[0];
					break;
				}
				
				// inlining these branches *unconditionally* breaks the [forcecase] above
				// ...yeah I know
				if (n == 3)
				L[3] = L[0];
				if (n == 4)
				L[4] = L[0];
			}
			
			/*
			TEXTURE SAMPLING
			*/
			
			float2 LTCGI_inset_uv(float2 uv)
			{
				return uv * 0.75 + float2(0.125, 0.125);
			}
			
			half3 premul_alpha(half4 i)
			{
				return i.rgb * i.a;
			}
			
			void LTCGI_sample(float2 uv, uint lod, uint idx, float blend, out float3 result)
			{
				result = 0;
				#ifndef LTCGI_STATIC_TEXTURES
				idx = 0; // optimize away the branches below
				#endif
				
				[branch]
				if (lod == 0)
				{
					// if we're outside of the 0-1 UV space we must sample a prefiltered texture
					[branch]
					if (any(saturate(abs(uv - 0.5) - 0.5)))
					{
						lod = 1;
					}
					else
					{
						// LOD0 is the original texture itself, so not prefiltered, but we can
						// approximate it a bit with trilinear lod
						float lod = (1 - blend) * 1.5;
						[branch]
						if (idx == 0)
						{
							#ifndef SHADER_TARGET_SURFACE_ANALYSIS
							result = premul_alpha(_Udon_LTCGI_Texture_LOD0.SampleLevel(LTCGI_SAMPLER, uv, lod));
							return;
							#else
							result = 0;
							return;
							#endif
						}
						else
						{
							result = premul_alpha(UNITY_SAMPLE_TEX2DARRAY_SAMPLER_LOD(
							_Udon_LTCGI_Texture_LOD0_arr,
							_LTCGI_trilinear_clamp_sampler,
							float3(uv, idx - 1),
							lod
							));
							return;
						}
					}
				}
				
				float2 ruv = LTCGI_inset_uv(uv);
				
				[branch]
				if (idx == 0)
				{
					#ifndef SHADER_TARGET_SURFACE_ANALYSIS
					switch(lod)
					{
						case 1:
						result = _Udon_LTCGI_Texture_LOD1.SampleLevel(LTCGI_SAMPLER, ruv, 0).rgb;
						return;
						case 2:
						result = _Udon_LTCGI_Texture_LOD2.SampleLevel(LTCGI_SAMPLER, ruv, 0).rgb;
						return;
						default:
						result = _Udon_LTCGI_Texture_LOD3.SampleLevel(LTCGI_SAMPLER, ruv, blend * 0.72).rgb;
						return;
					}
					#else
					result = 0;
					return;
					#endif
				}
				else
				{
					[forcecase]
					switch(lod)
					{
						case 1:
						result = UNITY_SAMPLE_TEX2DARRAY_SAMPLER_LOD(
						_Udon_LTCGI_Texture_LOD1_arr,
						_LTCGI_trilinear_clamp_sampler,
						float3(ruv, idx - 1),
						0
						).rgb;
						return;
						case 2:
						result = UNITY_SAMPLE_TEX2DARRAY_SAMPLER_LOD(
						_Udon_LTCGI_Texture_LOD2_arr,
						_LTCGI_trilinear_clamp_sampler,
						float3(ruv, idx - 1),
						0
						).rgb;
						return;
						default:
						result = UNITY_SAMPLE_TEX2DARRAY_SAMPLER_LOD(
						_Udon_LTCGI_Texture_LOD3_arr,
						_LTCGI_trilinear_clamp_sampler,
						float3(ruv, idx - 1),
						blend
						).rgb;
						return;
					}
				}
			}
			
			void LTCGI_trilinear(float2 uv, float d, uint idx, out float3 result)
			{
				uint low = (uint)d;
				uint high = low + 1;
				
				// DEBUG: colorize d/lod
				//return float3(low == 0, low == 1, low == 2);
				
				if (low >= 3)
				{
					LTCGI_sample(uv, 3, idx, d - 3, result);
				}
				else
				{
					float amount = saturate(high - d);
					float3 low_sample;
					LTCGI_sample(uv, low, idx, amount, low_sample);
					float3 high_sample;
					LTCGI_sample(uv, high, idx, 0, high_sample);
					
					result = lerp(high_sample, low_sample, amount);
				}
			}
			
			/*
			GENERIC HELPERS
			*/
			
			bool LTCGI_tri_ray(float3 orig, float3 dir, float3 v0, float3 v1, float3 v2, out float2 bary)
			{
				float3 v0v1 = v1 - v0;
				float3 v0v2 = v2 - v0;
				float3 pvec = cross(dir, v0v2);
				float det = dot(v0v1, pvec);
				float invDet = 1 / det;
				
				float3 tvec = orig - v0;
				bary.x = dot(tvec, pvec) * invDet;
				
				float3 qvec = cross(tvec, v0v1);
				bary.y = dot(dir, qvec) * invDet;
				
				// return false when other triangle of quad should be sampled,
				// i.e. we went over the diagonal line
				return bary.x >= 0;
			}
			
			float2 LTCGI_rotateVector(float2 x, float angle)
			{
				float c = cos(angle);
				float s = sin(angle);
				return mul(float2x2(c, s, -s, c), x);
			}
			
			float2 LTCGI_calculateUV(uint i, ltcgi_flags flags, float3 L[5], bool isTri, float2 uvStart, float2 uvEnd, out float3 ray)
			{
				// calculate perpendicular vector to plane defined by area light
				float3 E1 = L[1] - L[0];
				float3 E2 = L[3] - L[0];
				ray = cross(E1, E2);
				
				// raycast it against the two triangles formed by the quad
				float2 bary;
				bool hit0 = LTCGI_tri_ray(0, ray, L[0], L[2], L[3], bary) || isTri;
				if (!hit0)
				{
					LTCGI_tri_ray(0, ray, L[0], L[1], L[2], bary);
				}
				
				float2 uvs[4];
				#ifdef LTCGI_CYLINDER
				if (flags.cylinder)
				{
					uvs[0] = uvStart;
					uvs[1] = float2(uvStart.x, uvEnd.y);
					uvs[2] = float2(uvEnd.x, uvStart.y);
					uvs[3] = uvEnd;
				}
				else
				#endif
				{
					uvs[0] = uvStart; // == _Udon_LTCGI_static_uniforms[uint2(4, i)].xy;
					uvs[1] = _Udon_LTCGI_static_uniforms[uint2(4, i)].zw;
					uvs[2] = _Udon_LTCGI_static_uniforms[uint2(5, i)].xy;
					uvs[3] = uvEnd; // == _Udon_LTCGI_static_uniforms[uint2(5, i)].zw;
					
				}
				
				// map barycentric triangle coordinates to the according object UVs
				float3 bary3 = float3(bary, 1 - bary.x - bary.y);
				float2 uv = uvs[1 + hit0 * 2] * bary3.x + uvs[3 - hit0] * bary3.y + uvs[0] * bary3.z;
				
				return uv;
			}
			
			/*
			EXPERIMENTAL: CYLINDER HELPER
			*/
			
			void LTCGI_GetLw(uint i, ltcgi_flags flags, float3 worldPos, out float3 Lw[4], out float2 uvStart, out float2 uvEnd, out bool isTri)
			{
				bool cylinder = false;
				#ifdef LTCGI_CYLINDER
				// statically optimize out branch below in case disabled
				cylinder = flags.cylinder;
				#endif
				
				float4 v0 = _Udon_LTCGI_Vertices_0_get(i);
				float4 v1 = _Udon_LTCGI_Vertices_1_get(i);
				float4 v2 = _Udon_LTCGI_Vertices_2_get(i);
				float4 v3 = _Udon_LTCGI_Vertices_3_get(i);
				
				[branch]
				if (cylinder)
				{
					// construct data according to worldPos to create aligned
					// rectangle tangent to the cylinder
					
					float3 in_base = v0.xyz;
					float in_height = v0.w;
					float in_radius = v1.w;
					float in_size = v2.w;
					float in_angle = v3.w;
					
					// get angle between 2D unit plane and vector pointing from cylinder to shade point
					float2 towardsCylinder = LTCGI_rotateVector((in_base - worldPos).xz, -in_angle);
					float angle = atan2(towardsCylinder.x, towardsCylinder.y);
					// clamp angle to size parameter, i.e. "width" of lit surface area
					float angleClamped = clamp(angle, -in_size, in_size) + in_angle;
					// construct vector that *most* faces shade point
					float2 facing = float2(sin(angleClamped), cos(angleClamped));
					// tangent of rectangular screen on cylinder surface used for calculating lighting for shade point
					float2 tangent = float2(facing.y, -facing.x);
					float2 onCylinderFacing = facing * in_radius;
					
					// clip ends, approximately
					float rclip = saturate(lerp(1, 0, (angleClamped - in_angle) - (in_size - UNITY_HALF_PI * 0.5f)));
					float lclip = saturate(lerp(1, 0, - (angleClamped - in_angle) - (in_size - UNITY_HALF_PI * 0.5f)));
					
					float2 p1 = in_base.xz - onCylinderFacing + tangent * in_radius * lclip;
					float2 p2 = in_base.xz - onCylinderFacing - tangent * in_radius * rclip;
					
					Lw[0] = float3(p1.x, in_base.y, p1.y) - worldPos;
					Lw[1] = float3(p1.x, in_base.y + in_height, p1.y) - worldPos;
					Lw[2] = float3(p2.x, in_base.y, p2.y) - worldPos;
					Lw[3] = float3(p2.x, in_base.y + in_height, p2.y) - worldPos;
					
					isTri = false;
					
					// UV depends on "viewing" angle of the shade point towards the cylinder
					float2 viewDir = normalize((in_base - worldPos).xz);
					// forwardAngle == atan2(cos(in_angle), sin(in_angle)); but only negative
					float forwardAngle = -in_angle + UNITY_HALF_PI;
					// offset from center of screen forward to the side ends, positive goes left/ccw fpv top,
					// sine to account for the fact we're rotating around a cylinder which has depth
					float viewAngle = forwardAngle - atan2(viewDir.y, viewDir.x);
					// prevent rollover, since we need to clamp we must stay withing [-pi, pi]
					if (viewAngle < - UNITY_PI)
					viewAngle += UNITY_TWO_PI;
					if (viewAngle > UNITY_PI)
					viewAngle -= UNITY_TWO_PI;
					viewAngle = clamp(viewAngle * 0.5f, -in_size, in_size);
					viewAngle = sin(viewAngle);
					// full view UVs, but shifted left/right depending on view angle
					uvStart = float2(1 - saturate(viewAngle), 0);
					uvEnd = float2(1 - saturate(viewAngle + 1), 1);
				}
				else
				{
					// use passed in data, offset around worldPos
					Lw[0] = v0.xyz - worldPos;
					Lw[1] = v1.xyz - worldPos;
					Lw[2] = v2.xyz - worldPos;
					Lw[3] = v3.xyz - worldPos;
					#ifndef SHADER_TARGET_SURFACE_ANALYSIS
					uvStart = _Udon_LTCGI_static_uniforms[uint2(4, i)].xy;
					uvEnd = _Udon_LTCGI_static_uniforms[uint2(5, i)].zw;
					#else
					uvStart = float2(0, 0);
					uvEnd = float2(1, 1);
					#endif
					
					// we only detect triangles for "blender" import configuration, as those are the only
					// ones that can actually be triangles (I think?)
					isTri = /*distance(Lw[2], Lw[3]) < 0.001 || */distance(Lw[1], Lw[3]) < 0.001;
				}
			}
			
			/*
			
			Parts of the code in this file are adapted from the example code found here:
			
			https://github.com/selfshadow/ltc_code
			
			Modifications by _pi_ (@pimaker on GitHub), licensed under the terms of the
			MIT license as far as applicable.
			
			Original copyright notice:
			
			Copyright (c) 2017, Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt.
			All rights reserved.
			
			Redistribution and use in source and binary forms, with or without
			modification, are permitted provided that the following conditions are met:
			
			* If you use (or adapt) the source code in your own work, please include a
			reference to the paper:
			
			Real-Time Polygonal-Light Shading with Linearly Transformed Cosines.
			Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt.
			ACM Transactions on Graphics (Proceedings of ACM SIGGRAPH 2016) 35(4), 2016.
			Project page: https://eheitzresearch.wordpress.com/415-2/
			
			* Redistributions of source code must retain the above copyright notice, this
			list of conditions and the following disclaimer.
			
			* Redistributions in binary form must reproduce the above copyright notice,
			this list of conditions and the following disclaimer in the documentation
			and/or other materials provided with the distribution.
			
			THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
			AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
			IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
			DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
			FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
			DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
			SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
			CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
			OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
			OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
			
			*/
			// #include "LTCGI_functions.cginc" END
			// #include "LTCGI_shadowmap.cginc"
			
			// Adapted from: https://gitlab.com/s-ilent/filamented
			// Licensed under the terms of the Apache License 2.0
			// Full text: https://gitlab.com/s-ilent/filamented/-/blob/master/LICENSE
			//
			// Conforming to the terms of the above license, this file is redistributed
			// under the terms of the MIT license as part of the LTCGI shader package,
			// provided this notice is kept.
			
			#ifndef SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER
			
			float4 LTCGI_cubic(float v)
			{
				float4 n = float4(1.0, 2.0, 3.0, 4.0) - v;
				float4 s = n * n * n;
				float x = s.x;
				float y = s.y - 4.0 * s.x;
				float z = s.z - 4.0 * s.y + 6.0 * s.x;
				float w = 6.0 - x - y - z;
				return float4(x, y, z, w);
			}
			
			// Unity's SampleTexture2DBicubic doesn't exist in 2018, which is our target here.
			// So this is a similar function with tweaks to have similar semantics.
			
			float4 LTCGI_SampleTexture2DBicubicFilter(Texture2D tex, SamplerState smp, float2 coord, float4 texSize)
			{
				coord = coord * texSize.xy - 0.5;
				float fx = frac(coord.x);
				float fy = frac(coord.y);
				coord.x -= fx;
				coord.y -= fy;
				
				float4 xcubic = LTCGI_cubic(fx);
				float4 ycubic = LTCGI_cubic(fy);
				
				float4 c = float4(coord.x - 0.5, coord.x + 1.5, coord.y - 0.5, coord.y + 1.5);
				float4 s = float4(xcubic.x + xcubic.y, xcubic.z + xcubic.w, ycubic.x + ycubic.y, ycubic.z + ycubic.w);
				float4 offset = c + float4(xcubic.y, xcubic.w, ycubic.y, ycubic.w) / s;
				
				float4 sample0 = tex.Sample(smp, float2(offset.x, offset.z) * texSize.zw);
				float4 sample1 = tex.Sample(smp, float2(offset.y, offset.z) * texSize.zw);
				float4 sample2 = tex.Sample(smp, float2(offset.x, offset.w) * texSize.zw);
				float4 sample3 = tex.Sample(smp, float2(offset.y, offset.w) * texSize.zw);
				
				float sx = s.x / (s.x + s.y);
				float sy = s.z / (s.z + s.w);
				
				return lerp(
				lerp(sample3, sample2, sx),
				lerp(sample1, sample0, sx), sy);
			}
			
			float4 LTCGI_SampleShadowmap(float2 lmuv)
			{
				#ifdef LTCGI_ALWAYS_LTC_DIFFUSE
				return 1;
				#else
				lmuv = lmuv * _Udon_LTCGI_LightmapST.xy + _Udon_LTCGI_LightmapST.zw;
				
				#ifdef LTCGI_BICUBIC_LIGHTMAP
				float width, height;
				_Udon_LTCGI_Lightmap.GetDimensions(width, height);
				
				float4 _Udon_LTCGI_Lightmap_TexelSize = float4(width, height, 1.0 / width, 1.0 / height);
				
				return LTCGI_SampleTexture2DBicubicFilter(
				_Udon_LTCGI_Lightmap, LTCGI_SAMPLER,
				lmuv, _Udon_LTCGI_Lightmap_TexelSize
				);
				#else
				return _Udon_LTCGI_Lightmap.Sample(LTCGI_SAMPLER, lmuv);
				#endif
				#endif
			}
			
			#else
			// surface shader analysis stub
			float4 LTCGI_SampleShadowmap(float2 lmuv)
			{
				return 1;
			}
			#endif
			
			// #include "LTCGI_shadowmap.cginc" END
			
			#ifdef SHADER_TARGET_SURFACE_ANALYSIS
			#define const
			#endif
			
			// Main function - this calculates the approximated model for one pixel and one light
			void LTCGI_Evaluate(ltcgi_input input, float3 worldNorm, float3 viewDir, float3x3 Minv, float roughness, const bool diffuse, out ltcgi_output output)
			{
				output.input = input;
				output.color = input.rawColor; // copy for colormode static
				output.intensity = 0;
				
				// diffuse distance fade
				#ifdef LTCGI_DISTANCE_FADE_APPROX
				if (diffuse) // static branch, specular does not directly fade with distance
				
				{
					if (!input.flags.lmdOnly)
					{
						// very approximate lol
						float3 ctr = (input.Lw[0] + input.Lw[1]) / 2;
						float dist = length(ctr);
						if (dist > LTCGI_DISTANCE_FADE_APPROX_MULT)
						{
							return;
						}
					}
				}
				#endif
				
				#define RET1_IF_LMDIFF [branch] if (/*const*/ diffuse && input.flags.diffFromLm) \
				{ \
					output.intensity = 1.0f; return; \
				}
				
				if (input.flags.colormode == LTCGI_COLORMODE_SINGLEUV)
				{
					float2 uv = input.uvStart;
					if (uv.x < 0) uv.xy = uv.yx;
					// TODO: make more configurable?
					#ifdef LTCGI_VISUALIZE_SAMPLE_UV
					output.color = float3(uv.xy, 0);
					#else
					float3 sampled;
					LTCGI_sample(LTCGI_inset_uv(uv), 1, input.flags.texindex, 0, sampled);
					output.color *= sampled;
					#endif
					
					RET1_IF_LMDIFF
				}
				
				#ifdef LTCGI_AUDIOLINK
				if (input.flags.colormode == LTCGI_COLORMODE_AUDIOLINK)
				{
					float al = AudioLinkData(ALPASS_AUDIOLINK + uint2(0, input.flags.alBand)).r;
					output.color *= al;
					
					RET1_IF_LMDIFF
				}
				#endif
				
				// create LTC polygon array
				// note the order of source verts (keyword: winding order)
				float3 L[5];
				L[0] = mul(Minv, input.Lw[0]);
				L[1] = mul(Minv, input.Lw[1]);
				L[2] = input.isTri ? L[1] : mul(Minv, input.Lw[3]);
				L[3] = mul(Minv, input.Lw[2]);
				L[4] = 0;
				
				// get texture coords (before clipping!)
				[branch]
				if (input.flags.colormode == LTCGI_COLORMODE_TEXTURE)
				{
					float3 RN;
					float2 uv = LTCGI_calculateUV(input.i, input.flags, L, input.isTri, input.uvStart, input.uvEnd, RN);
					float planeAreaSquared = dot(RN, RN);
					float planeDistxPlaneArea = dot(RN, L[0]);
					
					float3 sampled;
					[branch]
					if (diffuse)
					{
						// static branch
						float3 sampled1;
						LTCGI_sample(uv, 3, input.flags.texindex, 10, sampled1);
						float3 sampled2;
						LTCGI_sample(uv, 3, input.flags.texindex, 100, sampled2);
						sampled =
						sampled1 * 0.75 +
						sampled2 * 0.25;
					}
					else
					{
						float d = abs(planeDistxPlaneArea) / planeAreaSquared;
						d *= LTCGI_UV_BLUR_DISTANCE;
						d = log(d) / log(3.0);
						
						// a rough material must never show a perfect reflection,
						// since our LOD0 texture is not prefiltered (and thus cannot
						// depict any blur correctly) - without this there is artifacting
						// on the border of LOD0 and LOD1
						d = clamp(d, saturate(roughness * 5.75), 1000);
						
						LTCGI_trilinear(uv, d, input.flags.texindex, sampled);
					}
					
					// colorize output
					output.color *= sampled;
				}
				
				RET1_IF_LMDIFF
				#undef RET1_IF_LMDIFF
				
				int n;
				LTCGI_ClipQuadToHorizon(L, n);
				
				// early out if everything was clipped below horizon
				if (n == 0)
				return;
				
				L[0] = normalize(L[0]);
				L[1] = normalize(L[1]);
				L[2] = normalize(L[2]);
				L[3] = normalize(L[3]);
				L[4] = normalize(L[4]);
				
				// integrate (and pray that constant folding works well)
				float sum = 0;
				[unroll(5)]
				for (uint v = 0; v < max(3, (uint)n); v++)
				{
					float3 a = L[v];
					float3 b = L[(v + 1) % 5];
					sum += LTCGI_IntegrateEdge(a, b).z;
				}
				
				// doublesided is accounted for with optimization at the start, so return abs
				output.intensity = abs(sum);
				return;
			}
			
			// Calculate light contribution for all lights,
			// call this from your shader and use the "diffuse" and "specular" outputs
			// lmuv is the raw lightmap UV coordinate (e.g. UV1)
			void LTCGI_Contribution(
			#ifdef LTCGI_API_V2
			inout LTCGI_V2_CUSTOM_INPUT data,
			#endif
			float3 worldPos, float3 worldNorm, float3 viewDir, float roughness, float2 lmuv
			#ifndef LTCGI_API_V2
			, inout half3 diffuse, inout half3 specular, out float totalSpecularIntensity, out float totalDiffuseIntensity
			#endif
			)
			{
				#ifndef LTCGI_API_V2
				totalSpecularIntensity = 0;
				#endif
				if (_Udon_LTCGI_GlobalEnable == 0.0f)
				{
					return;
				}
				
				// sample lookup tables
				float theta = acos(dot(worldNorm, viewDir));
				float2 uv = float2(roughness, theta / (0.5 * UNITY_PI));
				uv = uv * LUT_SCALE + LUT_BIAS;
				
				#ifndef UNITY_UV_STARTS_AT_TOP
				uv.y = 1 - uv.y;
				#endif
				
				// calculate LTCGI custom lightmap UV and sample
				float3 lms = LTCGI_SampleShadowmap(lmuv);
				
				#ifndef SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER
				// sample BDRF approximation from lookup texture
				float4 t = _Udon_LTCGI_lut1.SampleLevel(LTCGI_SAMPLER, uv, 0);
				#endif
				float3x3 Minv = float3x3(
				float3(1, 0, t.w),
				float3(0, t.z, 0),
				float3(t.y, 0, t.x)
				);
				
				// construct orthonormal basis around N
				float3 T1, T2;
				T1 = normalize(viewDir - worldNorm * dot(viewDir, worldNorm));
				T2 = cross(worldNorm, T1);
				
				// for diffuse lighting we assume the identity matrix as BDRF, so the
				// LTC approximation is directly equivalent to the orthonormal rotation matrix
				float3x3 identityBrdf = float3x3(float3(T1), float3(T2), float3(worldNorm));
				// rotate area light in (T1, T2, N) basis for actual BRDF matrix as well
				Minv = mul(Minv, identityBrdf);
				
				// specular brightness
				#ifndef LTCGI_SPECULAR_OFF
				#ifndef SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER
				float spec_amp = _Udon_LTCGI_lut2.SampleLevel(LTCGI_SAMPLER, uv, 0).x;
				#endif
				#endif
				
				bool noLm = false;
				#ifdef LTCGI_LTC_DIFFUSE_FALLBACK
				#ifndef LTCGI_ALWAYS_LTC_DIFFUSE
				#ifndef SHADER_TARGET_SURFACE_ANALYSIS
				float2 lmSize;
				_Udon_LTCGI_Lightmap.GetDimensions(lmSize.x, lmSize.y);
				noLm = lmSize.x == 1;
				#endif
				#endif
				#endif
				#ifdef LTCGI_ALWAYS_LTC_DIFFUSE
				noLm = true;
				#endif
				
				// loop through all lights and add them to the output
				uint count = min(_Udon_LTCGI_ScreenCount, MAX_SOURCES);
				[loop]
				for (uint i = 0; i < count; i++)
				{
					// skip masked and black lights
					if (_Udon_LTCGI_Mask[i]) continue;
					float4 extra = _Udon_LTCGI_ExtraData[i];
					float3 color = extra.rgb;
					if (!any(color)) continue;
					
					ltcgi_flags flags = ltcgi_parse_flags(asuint(extra.w), noLm);
					
					#ifdef LTCGI_ALWAYS_LTC_DIFFUSE
					// can't honor a lightmap-only light in this mode
					if (flags.lmdOnly) continue;
					#endif
					
					#ifdef LTCGI_TOGGLEABLE_SPEC_DIFF_OFF
					// compile branches below away statically
					flags.diffuse = flags.specular = true;
					#endif
					
					// calculate (shifted) world space positions
					float3 Lw[4];
					float2 uvStart = (float2)0, uvEnd = (float2)0;
					bool isTri = false;
					if (flags.lmdOnly)
					{
						Lw[0] = Lw[1] = Lw[2] = Lw[3] = (float3)0;
					}
					else
					{
						LTCGI_GetLw(i, flags, worldPos, Lw, uvStart, uvEnd, isTri);
					}
					
					// skip single-sided lights that face the other way
					float3 screenNorm = cross(Lw[1] - Lw[0], Lw[2] - Lw[0]);
					if (!flags.doublesided)
					{
						if (dot(screenNorm, Lw[0]) < 0)
						continue;
					}
					
					float lm = 1;
					if (flags.lmch)
					{
						lm = lms[flags.lmch - 1];
						if (lm < 0.001) continue;
					}
					
					ltcgi_input input;
					input.i = i;
					input.Lw = Lw;
					input.isTri = isTri;
					input.uvStart = uvStart;
					input.uvEnd = uvEnd;
					input.rawColor = color;
					input.flags = flags;
					input.screenNormal = screenNorm;
					
					// diffuse lighting
					#ifndef LTCGI_DIFFUSE_OFF
					[branch]
					if (flags.diffuse)
					{
						float lmd = lm;
						if (flags.lmch)
						{
							if (flags.diffFromLm)
							lmd *= _Udon_LTCGI_LightmapMult[flags.lmch - 1];
							else
							lmd = smoothstep(0.0, LTCGI_SPECULAR_LIGHTMAP_STEP, saturate(lm - LTCGI_LIGHTMAP_CUTOFF));
						}
						ltcgi_output diff;
						LTCGI_Evaluate(input, worldNorm, viewDir, identityBrdf, roughness, true, diff);
						diff.intensity *= lmd;
						
						#ifdef LTCGI_API_V2
						LTCGI_V2_DIFFUSE_CALLBACK(data, diff);
						#else
						// simply accumulate all lights
						diffuse += (diff.intensity * diff.color);
						totalDiffuseIntensity += diff.intensity;
						#endif
					}
					#endif
					
					// specular lighting
					#ifndef LTCGI_SPECULAR_OFF
					[branch]
					if (flags.specular)
					{
						ltcgi_output spec;
						LTCGI_Evaluate(input, worldNorm, viewDir, Minv, roughness, false, spec);
						spec.intensity *= spec_amp * smoothstep(0.0, LTCGI_SPECULAR_LIGHTMAP_STEP, saturate(lm - LTCGI_LIGHTMAP_CUTOFF));
						
						#ifdef LTCGI_API_V2
						LTCGI_V2_SPECULAR_CALLBACK(data, spec);
						#else
						// simply accumulate all lights
						specular += spec.intensity * spec.color;
						totalSpecularIntensity += spec.intensity;
						#endif
					}
					#endif
				}
			}
			
			// COMPATIBILITY FALLBACKS
			
			#ifndef LTCGI_API_V2
			
			void LTCGI_Contribution(
			float3 worldPos, float3 worldNorm, float3 viewDir, float roughness, float2 lmuv, inout half3 diffuse
			)
			{
				half3 _u1;
				float _u2, _u3;
				LTCGI_Contribution(worldPos, worldNorm, viewDir, roughness, lmuv, diffuse, _u1, _u2, _u3);
			}
			
			void LTCGI_Contribution(
			float3 worldPos, float3 worldNorm, float3 viewDir, float roughness, float2 lmuv, inout half3 diffuse, inout half3 specular
			)
			{
				float _u1, _u2;
				LTCGI_Contribution(worldPos, worldNorm, viewDir, roughness, lmuv, diffuse, specular, _u1, _u2);
			}
			
			void LTCGI_Contribution(
			float3 worldPos, float3 worldNorm, float3 viewDir, float roughness, float2 lmuv, inout half3 diffuse, inout half3 specular, out float totalSpecularIntensity
			)
			{
				float _u1;
				LTCGI_Contribution(worldPos, worldNorm, viewDir, roughness, lmuv, diffuse, specular, totalSpecularIntensity, _u1);
			}
			
			#endif
			
			/*
			
			Parts of the code in this file are adapted from the example code found here:
			
			https://github.com/selfshadow/ltc_code
			
			Modifications by _pi_ (@pimaker on GitHub), licensed under the terms of the
			MIT license as far as applicable.
			
			Original copyright notice:
			
			Copyright (c) 2017, Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt.
			All rights reserved.
			
			Redistribution and use in source and binary forms, with or without
			modification, are permitted provided that the following conditions are met:
			
			* If you use (or adapt) the source code in your own work, please include a
			reference to the paper:
			
			Real-Time Polygonal-Light Shading with Linearly Transformed Cosines.
			Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt.
			ACM Transactions on Graphics (Proceedings of ACM SIGGRAPH 2016) 35(4), 2016.
			Project page: https://eheitzresearch.wordpress.com/415-2/
			
			* Redistributions of source code must retain the above copyright notice, this
			list of conditions and the following disclaimer.
			
			* Redistributions in binary form must reproduce the above copyright notice,
			this list of conditions and the following disclaimer in the documentation
			and/or other materials provided with the distribution.
			
			THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
			AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
			IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
			DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
			FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
			DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
			SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
			CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
			OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
			OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
			
			*/
			
			// LTCGI.cginc END
			
			void callback_diffuse(inout accumulator_struct acc, in ltcgi_output output)
			{
				// you can do whatever here! check out the ltcgi_output struct in
				// "LTCGI_structs.cginc" to see what data you have available
				acc.diffuse += output.intensity * output.color;
			}
			void callback_specular(inout accumulator_struct acc, in ltcgi_output output)
			{
				// same here, this example one is pretty boring though.
				// you could accumulate intensity separately for example,
				// to emulate total{Specular,Diffuse}Intensity from APIv1
				acc.specular += output.intensity * output.color;
			}
			
			#endif
			//endex
			
			//ifex _ShadingEnabled==0
			#ifdef VIGNETTE_MASKED
			
			#ifdef _LIGHTINGMODE_CLOTH
			float V_SmithGGXCorrelated(float roughness, float NoV, float NoL)
			{
				// Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"
				float a2 = roughness * roughness;
				// TODO: lambdaV can be pre-computed for all the lights, it should be moved out of this function
				float lambdaV = NoL * sqrt((NoV - a2 * NoV) * NoV + a2);
				float lambdaL = NoV * sqrt((NoL - a2 * NoL) * NoL + a2);
				float v = 0.5 / (lambdaV + lambdaL);
				// a2=0 => v = 1 / 4*NoL*NoV   => min=1/4, max=+inf
				// a2=1 => v = 1 / 2*(NoL+NoV) => min=1/4, max=+inf
				// clamp to the maximum value representable in mediump
				return v;
			}
			
			float D_GGX(float roughness, float NoH)
			{
				// Walter et al. 2007, "Microfacet Models for Refraction through Rough Surfaces"
				
				// In mediump, there are two problems computing 1.0 - NoH^2
				// 1) 1.0 - NoH^2 suffers floating point cancellation when NoH^2 is close to 1 (highlights)
				// 2) NoH doesn't have enough precision around 1.0
				// Both problem can be fixed by computing 1-NoH^2 in highp and providing NoH in highp as well
				
				// However, we can do better using Lagrange's identity:
				//      ||a x b||^2 = ||a||^2 ||b||^2 - (a . b)^2
				// since N and H are unit vectors: ||N x H||^2 = 1.0 - NoH^2
				// This computes 1.0 - NoH^2 directly (which is close to zero in the highlights and has
				// enough precision).
				// Overall this yields better performance, keeping all computations in mediump
				float oneMinusNoHSquared = 1.0 - NoH * NoH;
				
				float a = NoH * roughness;
				float k = roughness / (oneMinusNoHSquared + a * a);
				float d = k * k * (1.0 / UNITY_PI);
				return d;
			}
			
			// https://github.com/google/filament/blob/main/shaders/src/brdf.fs#L94-L100
			float D_Charlie(float roughness, float NoH)
			{
				// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF"
				float invAlpha = 1.0 / roughness;
				float cos2h = NoH * NoH;
				float sin2h = max(1.0 - cos2h, 0.0078125); // 0.0078125 = 2^(-14/2), so sin2h^2 > 0 in fp16
				return (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * UNITY_PI);
			}
			
			// https://github.com/google/filament/blob/main/shaders/src/brdf.fs#L136-L139
			float V_Neubelt(float NoV, float NoL)
			{
				// Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886"
				return 1.0 / (4.0 * (NoL + NoV - NoL * NoV));
			}
			
			float Distribution(float roughness, float NoH, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(GGXTerm(roughness, NoH), D_Charlie(roughness, NoH), cloth);
				}
				//endex
				return cloth <= 0.5 ? GGXTerm(roughness, NoH) : D_Charlie(roughness, NoH);
			}
			
			float Visibility(float roughness, float NoV, float NoL, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(V_SmithGGXCorrelated(roughness, NoV, NoL), V_Neubelt(NoV, NoL), cloth);
				}
				//endex
				return cloth <= 0.5 ? V_SmithGGXCorrelated(roughness, NoV, NoL) : V_Neubelt(NoV, NoL);
			}
			
			float F_Schlick(float3 f0, float f90, float VoH)
			{
				// Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"
				return f0 + (f90 - f0) * pow(1.0 - VoH, 5);
			}
			
			float F_Schlick(float3 f0, float VoH)
			{
				float f = pow(1.0 - VoH, 5.0);
				return f + f0 * (1.0 - f);
			}
			
			float Fresnel(float3 f0, float LoH)
			{
				float f90 = saturate(dot(f0, float(50.0 * 0.33).xxx));
				return F_Schlick(f0, f90, LoH);
			}
			
			float Fd_Burley(float roughness, float NoV, float NoL, float LoH)
			{
				// Burley 2012, "Physically-Based Shading at Disney"
				float f90 = 0.5 + 2.0 * roughness * LoH * LoH;
				float lightScatter = F_Schlick(1.0, f90, NoL);
				float viewScatter = F_Schlick(1.0, f90, NoV);
				return lightScatter * viewScatter;
			}
			
			// Energy conserving wrap diffuse term, does *not* include the divide by PI
			float Fd_Wrap(float NoL, float w)
			{
				return saturate((NoL + w) / pow(1.0 + w, 2));
			}
			
			float4 SampleDFG(float NoV, float perceptualRoughness)
			{
				return _ClothDFG.Sample(sampler_ClothDFG, float3(NoV, perceptualRoughness, 0));
			}
			
			float3 EnvBRDF(float2 dfg, float3 f0)
			{
				return f0 * dfg.x + dfg.y;
			}
			
			float3 EnvBRDFMultiscatter(float3 dfg, float3 f0, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(lerp(dfg.xxx, dfg.yyy, f0), f0 * dfg.z, cloth);
				}
				//endex
				return cloth <= 0.5 ? lerp(dfg.xxx, dfg.yyy, f0) : f0 * dfg.z;
			}
			
			float3 EnvBRDFEnergyCompensation(float3 dfg, float3 f0, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(1.0 + f0 * (1.0 / dfg.y - 1.0), 1, cloth);
				}
				//endex
				return cloth <= 0.5 ? 1.0 + f0 * (1.0 / dfg.y - 1.0) : 1;
			}
			
			//
			float ClothMetallic(float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return cloth;
				}
				//endex
				return cloth <= 0.5 ? 1 : 0;
			}
			
			float3 Specular(float roughness, PoiLight poiLight, float f0, float3 normal, float cloth)
			{
				float NoL = poiLight.nDotLSaturated;
				float NoH = poiLight.nDotH;
				float LoH = poiLight.lDotH;
				float NoV = poiLight.nDotV;
				
				float D = Distribution(roughness, NoH, cloth);
				float V = Visibility(roughness, NoV, NoL, cloth);
				float3 F = Fresnel(f0, LoH);
				
				return (D * V) * F;
			}
			
			float3 getBoxProjection(float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax)
			{
				#if UNITY_SPECCUBE_BOX_PROJECTION
				if (cubemapPosition.w > 0)
				{
					float3 factors = ((direction > 0 ? boxMax : boxMin) - position) / direction;
					float scalar = min(min(factors.x, factors.y), factors.z);
					direction = direction * scalar + (position - cubemapPosition.xyz);
				}
				#endif
				
				return direction;
			}
			
			float SpecularAO(float NoV, float ao, float roughness)
			{
				return clamp(pow(NoV + ao, exp2(-16.0 * roughness - 1.0)) - 1.0 + ao, 0.0, 1.0);
			}
			
			float3 IndirectSpecular(float3 dfg, float roughness, float occlusion, float energyCompensation, float cloth, float3 indirectDiffuse, float f0, PoiLight poiLight, PoiFragData poiFragData, PoiCam poiCam, PoiMesh poiMesh)
			{
				float3 normal = poiMesh.normals[1];
				
				float3 reflDir = reflect(-poiCam.viewDir, normal);
				
				Unity_GlossyEnvironmentData envData;
				envData.roughness = roughness;
				envData.reflUVW = getBoxProjection(reflDir, poiMesh.worldPos, unity_SpecCube0_ProbePosition,
				unity_SpecCube0_BoxMin.xyz, unity_SpecCube0_BoxMax.xyz);
				
				float3 probe0 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE(unity_SpecCube0), unity_SpecCube0_HDR, envData);
				float3 indirectSpecular = probe0;
				
				#if UNITY_SPECCUBE_BLENDING
				UNITY_BRANCH
				if (unity_SpecCube0_BoxMin.w < 0.99999)
				{
					envData.reflUVW = getBoxProjection(reflDir, poiMesh.worldPos, unity_SpecCube1_ProbePosition, unity_SpecCube1_BoxMin.xyz, unity_SpecCube1_BoxMax.xyz);
					float3 probe1 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1, unity_SpecCube0), unity_SpecCube1_HDR, envData);
					indirectSpecular = lerp(probe1, probe0, unity_SpecCube0_BoxMin.w);
				}
				#endif
				
				float horizon = min(1 + dot(reflDir, normal), 1);
				indirectSpecular = indirectSpecular * horizon * horizon * energyCompensation * EnvBRDFMultiscatter(dfg, f0, cloth);
				
				indirectSpecular *= SpecularAO(poiLight.nDotV, occlusion, roughness);
				return indirectSpecular;
			};
			#endif
			
			#ifdef _LIGHTINGMODE_WRAPPED
			// Wrapped
			// Green’s model with adjustable energy
			// http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/
			// Modified for adjustable conservation ratio and over-wrap to directionless
			float RTWrapFunc(in float dt, in float w, in float norm)
			{
				float cw = saturate(w);
				
				float o = (dt + cw) / ((1.0 + cw) * (1.0 + cw * norm));
				float flt = 1.0 - 0.85 * norm;
				if (w > 1.0)
				{
					o = lerp(o, flt, w - 1.0);
				}
				return o;
			}
			
			float3 GreenWrapSH(float fA) // Greens unoptimized and non-normalized
			
			{
				float fAs = saturate(fA);
				float4 t = float4(fA + 1, fAs - 1, fA - 2, fAs + 1); // DJL edit: allow wrapping to L0-only at w=2
				return float3(t.x, -t.z * t.x / 3, 0.25 * t.y * t.y * t.w);
			}
			float3 GreenWrapSHOpt(float fW) // optimised and normalized https://blog.selfshadow.com/2012/01/07/righting-wrap-part-2/
			
			{
				const float4 t0 = float4(0.0, 1.0 / 4.0, -1.0 / 3.0, -1.0 / 2.0);
				const float4 t1 = float4(1.0, 2.0 / 3.0, 1.0 / 4.0, 0.0);
				float3 fWs = float3(fW, fW, saturate(fW)); // DJL edit: allow wrapping to L0-only at w=2
				
				float3 r;
				r.xyz = t0.xxy * fWs + t0.xzw;
				r.xyz = r.xyz * fWs + t1.xyz;
				return r;
			}
			float3 ShadeSH9_wrapped(float3 normal, float wrap)
			{
				float3 x0, x1, x2;
				float3 conv = lerp(GreenWrapSH(wrap), GreenWrapSHOpt(wrap), _LightingWrappedNormalization); // Should try optimizing this...
				conv *= float3(1, 1.5, 4); // Undo pre-applied cosine convolution by using the inverse
				
				// Constant (L0)
				x0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
				// Remove pre-applied constant part from L(2,0) to apply correct convolution
				float3 L2_0 = float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / - 3.0;
				x0 -= L2_0;
				
				// Linear (L1) polynomial terms
				x1.r = dot(unity_SHAr.xyz, normal);
				x1.g = dot(unity_SHAg.xyz, normal);
				x1.b = dot(unity_SHAb.xyz, normal);
				
				// 4 of the quadratic (L2) polynomials
				float4 vB = normal.xyzz * normal.yzzx;
				x2.r = dot(unity_SHBr, vB);
				x2.g = dot(unity_SHBg, vB);
				x2.b = dot(unity_SHBb, vB);
				
				// Final (5th) quadratic (L2) polynomial
				float vC = normal.x * normal.x - normal.y * normal.y;
				x2 += unity_SHC.rgb * vC;
				// Move back the constant part of L(2,0)
				x2 += L2_0;
				
				return x0 * conv.x + x1 * conv.y + x2 * conv.z;
			}
			
			float3 GetSHDirectionL1()
			{
				// For efficiency, we only get the direction from L1.
				// Because getting it from L2 would be too hard!
				return Unity_SafeNormalize((unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz));
			}
			// Returns the value from SH in the lighting direction with the
			// brightest intensity.
			half3 GetSHMaxL1()
			{
				float3 maxDirection = GetSHDirectionL1();
				return ShadeSH9_wrapped(maxDirection, 0);
			}
			#endif
			
			#ifdef _LIGHTINGMODE_SHADEMAP
			void applyShadeMapping(inout PoiFragData poiFragData, PoiMesh poiMesh, inout PoiLight poiLight)
			{
				float shadowAttenuation = lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				float attenuation = 1;
				#if defined(POINT) || defined(SPOT)
				shadowAttenuation = lerp(1, poiLight.additiveShadow, poiLight.attenuationStrength);
				//attenuation = poiLight.attenuation;
				#endif
				
				float MainColorFeatherStep = _BaseColor_Step - _BaseShade_Feather;
				float firstColorFeatherStep = _ShadeColor_Step - _1st2nd_Shades_Feather;
				
				#if defined(PROP_1ST_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
				float4 firstShadeMap = POI2D_SAMPLER_PAN(_1st_ShadeMap, _MainTex, poiUV(poiMesh.uv[_1st_ShadeMapUV], _1st_ShadeMap_ST), _1st_ShadeMapPan);
				#else
				float4 firstShadeMap = float4(1, 1, 1, 1);
				#endif
				firstShadeMap = lerp(firstShadeMap, float4(poiFragData.baseColor, 1), _Use_BaseAs1st);
				
				#if defined(PROP_2ND_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
				float4 secondShadeMap = POI2D_SAMPLER_PAN(_2nd_ShadeMap, _MainTex, poiUV(poiMesh.uv[_2nd_ShadeMapUV], _2nd_ShadeMap_ST), _2nd_ShadeMapPan);
				#else
				float4 secondShadeMap = float4(1, 1, 1, 1);
				#endif
				secondShadeMap = lerp(secondShadeMap, firstShadeMap, _Use_1stAs2nd);
				
				firstShadeMap.rgb *= _1st_ShadeColor.rgb; //* lighColor
				secondShadeMap.rgb *= _2nd_ShadeColor.rgb; //* LightColor;
				
				float shadowMask = 1;
				shadowMask *= _Use_1stShadeMapAlpha_As_ShadowMask ? (_1stShadeMapMask_Inverse ? (1.0 - firstShadeMap.a) : firstShadeMap.a) : 1;
				shadowMask *= _Use_2ndShadeMapAlpha_As_ShadowMask ? (_2ndShadeMapMask_Inverse ? (1.0 - secondShadeMap.a) : secondShadeMap.a) : 1;
				
				float mainShadowMask = saturate(1 - ((poiLight.lightMap) - MainColorFeatherStep) / (_BaseColor_Step - MainColorFeatherStep) * (shadowMask));
				float firstSecondShadowMask = saturate(1 - ((poiLight.lightMap) - firstColorFeatherStep) / (_ShadeColor_Step - firstColorFeatherStep) * (shadowMask));
				
				mainShadowMask *= poiLight.shadowMask * _ShadowStrength;
				firstSecondShadowMask *= poiLight.shadowMask * _ShadowStrength;
				
				// 0 lerp | 1 multiply
				if (_ShadingShadeMapBlendType == 0)
				{
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, lerp(firstShadeMap.rgb, secondShadeMap.rgb, firstSecondShadowMask), mainShadowMask) * attenuation;
				}
				else
				{
					poiFragData.baseColor.rgb *= lerp(1, lerp(firstShadeMap.rgb, secondShadeMap.rgb, firstSecondShadowMask), mainShadowMask) * attenuation;
				}
				poiLight.rampedLightMap = 1 - mainShadowMask;
			}
			#endif
			
			#ifdef _LIGHTINGMODE_REALISTIC
			// For https://docs.unity3d.com/Manual/LightMode-Mixed-Subtractive.html
			#if defined(LIGHTMAP_ON) && defined(SHADOWS_SCREEN)
			#if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK)
			#define SUBTRACTIVE_LIGHTING 1
			#endif
			#endif
			
			void ApplySubtractiveLighting(inout UnityIndirect indirectLight)
			{
				#if SUBTRACTIVE_LIGHTING
				poiLight.attenuation = FadeShadows(lerp(1, poiLight.attenuation, _AttenuationMultiplier));
				
				float ndotl = saturate(dot(i.normal, _WorldSpaceLightPos0.xyz));
				float3 shadowedLightEstimate = ndotl * (1 - poiLight.attenuation) * _LightColor0.rgb;
				float3 subtractedLight = indirectLight.diffuse - shadowedLightEstimate;
				subtractedLight = max(subtractedLight, unity_ShadowColor.rgb);
				subtractedLight = lerp(subtractedLight, indirectLight.diffuse, _LightShadowData.x);
				indirectLight.diffuse = min(subtractedLight, indirectLight.diffuse);
				#endif
			}
			
			UnityIndirect CreateIndirectLight(in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight)
			{
				UnityIndirect indirectLight;
				indirectLight.diffuse = 0;
				indirectLight.specular = 0;
				
				#if defined(LIGHTMAP_ON)
				indirectLight.diffuse = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, poiMesh.lightmapUV.xy));
				
				#if defined(DIRLIGHTMAP_COMBINED)
				float4 lightmapDirection = UNITY_SAMPLE_TEX2D_SAMPLER(
				unity_LightmapInd, unity_Lightmap, poiMesh.lightmapUV.xy
				);
				indirectLight.diffuse = DecodeDirectionalLightmap(
				indirectLight.diffuse, lightmapDirection, poiMesh.normals[1]
				);
				#endif
				ApplySubtractiveLighting(indirectLight);
				#endif
				
				#if defined(DYNAMICLIGHTMAP_ON)
				float3 dynamicLightDiffuse = DecodeRealtimeLightmap(
				UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, poiMesh.lightmapUV.zw)
				);
				
				#if defined(DIRLIGHTMAP_COMBINED)
				float4 dynamicLightmapDirection = UNITY_SAMPLE_TEX2D_SAMPLER(
				unity_DynamicDirectionality, unity_DynamicLightmap,
				poiMesh.lightmapUV.zw
				);
				indirectLight.diffuse += DecodeDirectionalLightmap(
				dynamicLightDiffuse, dynamicLightmapDirection, poiMesh.normals[1]
				);
				#else
				indirectLight.diffuse += dynamicLightDiffuse;
				#endif
				#endif
				
				#if !defined(LIGHTMAP_ON) && !defined(DYNAMICLIGHTMAP_ON)
				#if UNITY_LIGHT_PROBE_PROXY_VOLUME
				if (unity_ProbeVolumeParams.x == 1)
				{
					indirectLight.diffuse = SHEvalLinearL0L1_SampleProbeVolume(
					float4(poiMesh.normals[1], 1), poiMesh.worldPos
					);
					indirectLight.diffuse = max(0, indirectLight.diffuse);
					#if defined(UNITY_COLORSPACE_GAMMA)
					indirectLight.diffuse = LinearToGammaSpace(indirectLight.diffuse);
					#endif
				}
				else
				{
					indirectLight.diffuse += max(0, ShadeSH9(float4(poiMesh.normals[1], 1)));
				}
				#else
				indirectLight.diffuse += max(0, ShadeSH9(float4(poiMesh.normals[1], 1)));
				#endif
				#endif
				
				indirectLight.diffuse *= poiLight.occlusion;
				
				return indirectLight;
			}
			#endif
			
			float GetRemapMinValue(float scale, float offset)
			{
				return clamp(-offset / scale, -0.01f, 1.01f); // Remap min
				
			}
			float GetRemapMaxValue(float scale, float offset)
			{
				return clamp((1.0f - offset) / scale, -0.01f, 1.01f); // Remap Max
				
			}
			
			void calculateShading(inout PoiLight poiLight, inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam)
			{
				float shadowAttenuation = lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				float attenuation = 1;
				#if defined(POINT) || defined(SPOT)
				shadowAttenuation = lerp(1, poiLight.additiveShadow, poiLight.attenuationStrength);
				//attenuation = poiLight.attenuation;
				#endif
				
				#ifdef POI_PASS_ADD
				if (_LightingAdditiveType == 3)
				{
					#if defined(POINT) || defined(SPOT)
					#if defined(_LIGHTINGMODE_REALISTIC) || defined(_LIGHTINGMODE_CLOTH) || defined(_LIGHTINGMODE_WRAPPED)
					poiLight.rampedLightMap = max(0, poiLight.nDotL);
					poiLight.finalLighting = poiLight.directColor * attenuation * max(0, poiLight.nDotL) * poiLight.detailShadow * shadowAttenuation;
					return;
					#endif
					#endif
				}
				// Realistic
				if (_LightingAdditiveType == 0)
				{
					poiLight.rampedLightMap = max(0, poiLight.nDotL);
					poiLight.finalLighting = poiLight.directColor * attenuation * max(0, poiLight.nDotL) * poiLight.detailShadow * shadowAttenuation;
					return;
				}
				// Toon
				if (_LightingAdditiveType == 1)
				{
					#if defined(POINT_COOKIE) || defined(DIRECTIONAL_COOKIE)
					float passthrough = 0;
					#else
					float passthrough = _LightingAdditivePassthrough;
					#endif
					
					float2 ToonAddGradient = float2(_LightingAdditiveGradientStart, _LightingAdditiveGradientEnd);
					
					if (ToonAddGradient.x == ToonAddGradient.y) ToonAddGradient.y += 0.0001;
					
					poiLight.rampedLightMap = smoothstep(ToonAddGradient.y, ToonAddGradient.x, 1 - (.5 * poiLight.nDotL + .5));
					#if defined(POINT) || defined(SPOT)
					poiLight.finalLighting = lerp(poiLight.directColor * max(min(poiLight.additiveShadow, poiLight.detailShadow), passthrough), poiLight.indirectColor, smoothstep(ToonAddGradient.x, ToonAddGradient.y, 1 - (.5 * poiLight.nDotL + .5)));
					#else
					poiLight.finalLighting = lerp(poiLight.directColor * max(min(poiLight.attenuation, poiLight.detailShadow), passthrough), poiLight.indirectColor, smoothstep(ToonAddGradient.x, ToonAddGradient.y, 1 - (.5 * poiLight.nDotL + .5)));
					#endif
					return;
				}
				#endif
				
				float shadowStrength = _ShadowStrength * poiLight.shadowMask;
				
				#ifdef POI_PASS_OUTLINE
				shadowStrength = lerp(0, shadowStrength, _OutlineShadowStrength);
				#endif
				
				// These blocks shouldn't need ifex, they should be removed on lock when their keywords aren't present
				
				#ifdef _LIGHTINGMODE_FLAT
				poiLight.finalLighting = poiLight.directColor * attenuation * shadowAttenuation;
				if (_ForceFlatRampedLightmap)
				{
					poiLight.rampedLightMap = smoothstep(0.4, 0.6, poiLight.nDotLNormalized);
				}
				else
				{
					poiLight.rampedLightMap = 1;
				}
				#endif
				
				#ifdef _LIGHTINGMODE_TEXTURERAMP
				float2 rampUVs = poiLight.lightMap + _ShadowOffset;
				if (_ToonRampCount > 1)
				{
					rampUVs.y = (floor(poiMesh.uv[_ToonRampUVSelector].y * _ToonRampCount) + 0.5) / _ToonRampCount;
				}
				poiLight.rampedLightMap = lerp(1, UNITY_SAMPLE_TEX2D_SAMPLER(_ToonRamp, _linear_clamp, rampUVs).rgb, shadowStrength);
				poiLight.finalLighting = lerp(_LightingShadowColor * lerp(poiLight.indirectColor, poiLight.rampedLightMap * poiLight.directColor, _LightingIgnoreAmbientColor) * poiLight.occlusion, poiLight.directColor, poiLight.rampedLightMap) * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_MULTILAYER_MATH
				#if defined(PROP_MULTILAYERMATHBLURMAP) || !defined(OPTIMIZER_ENABLED)
				float4 blurMap = POI2D_SAMPLER_PAN(_MultilayerMathBlurMap, _MainTex, poiUV(poiMesh.uv[_MultilayerMathBlurMapUV], _MultilayerMathBlurMap_ST), _MultilayerMathBlurMapPan);
				#else
				float4 blurMap = 1;
				#endif
				
				float4 lns = float4(1, 1, 1, 1);
				
				float shadowAttenuationNoStrength = poiLight.attenuation;
				#if defined(POINT) || defined(SPOT)
				shadowAttenuationNoStrength = poiLight.additiveShadow;
				#endif
				
				float3 lightMap = poiLight.lightMapNoAttenuation.xxx;
				lightMap.x *= lerp(1.0, shadowAttenuationNoStrength, _ShadowReceive);
				lightMap.y *= lerp(1.0, shadowAttenuationNoStrength, _Shadow2ndReceive);
				lightMap.z *= lerp(1.0, shadowAttenuationNoStrength, _Shadow3rdReceive);
				
				float4 shadowBorderMask = 1;
				if (_ShadowBorderMapToggle)
				{
					// This should be moved to ui but honestly if these are locked in the compiler should be able to resolve it at compile time
					float2 shadowShift0 = float2(_ShadowAOShift.x, _ShadowAOShift.y);
					float2 shadowShift1 = float2(_ShadowAOShift.z, _ShadowAOShift.w);
					float2 shadowShift2 = float2(_ShadowAOShift2.x, _ShadowAOShift2.y);
					
					//float2 shadowShift0 = float2(GetRemapMinValue(_ShadowAOShift.x, _ShadowAOShift.y), GetRemapMaxValue(_ShadowAOShift.x, _ShadowAOShift.y));
					//float2 shadowShift1 = float2(GetRemapMinValue(_ShadowAOShift.z, _ShadowAOShift.w), GetRemapMaxValue(_ShadowAOShift.z, _ShadowAOShift.w));
					//float2 shadowShift2 = float2(GetRemapMinValue(_ShadowAOShift2.x, _ShadowAOShift2.y), GetRemapMaxValue(_ShadowAOShift2.x, _ShadowAOShift2.y));
					
					shadowShift0.y = (shadowShift0.x == shadowShift0.y) ? (shadowShift0.y + 0.001f) : shadowShift0.y;
					shadowShift1.y = (shadowShift1.x == shadowShift1.y) ? (shadowShift1.y + 0.001f) : shadowShift1.y;
					shadowShift2.y = (shadowShift2.x == shadowShift2.y) ? (shadowShift2.y + 0.001f) : shadowShift2.y;
					
					shadowShift0 = float2(1.0f / (shadowShift0.y - shadowShift0.x), shadowShift0.x / (shadowShift0.x - shadowShift0.y));
					shadowShift1 = float2(1.0f / (shadowShift1.y - shadowShift1.x), shadowShift1.x / (shadowShift1.x - shadowShift1.y));
					shadowShift2 = float2(1.0f / (shadowShift2.y - shadowShift2.x), shadowShift2.x / (shadowShift2.x - shadowShift2.y));
					
					#if defined(PROP_SHADOWBORDERMASK) || !defined(OPTIMIZER_ENABLED)
					float2 shadowBorderMaskUV = poiUV(poiMesh.uv[_ShadowBorderMaskUV], _ShadowBorderMask_ST);
					if (_ShadowBorderMaskLOD)
					{
						shadowBorderMask = POI2D_SAMPLE_TEX2D_SAMPLERGRADD(_ShadowBorderMask, sampler_trilinear_repeat, shadowBorderMaskUV, _ShadowBorderMaskPan, max(abs(ddx(shadowBorderMaskUV)), pow(_ShadowBorderMaskLOD, 4)), max(abs(ddy(shadowBorderMaskUV)), pow(_ShadowBorderMaskLOD, 4)));
					}
					else
					{
						shadowBorderMask = POI2D_SAMPLER_PAN(_ShadowBorderMask, _linear_repeat, shadowBorderMaskUV, _ShadowBorderMaskPan);
					}
					#endif
					
					shadowBorderMask.r = saturate(shadowBorderMask.r * shadowShift0.x + shadowShift0.y);
					shadowBorderMask.g = saturate(shadowBorderMask.g * shadowShift1.x + shadowShift1.y);
					shadowBorderMask.b = saturate(shadowBorderMask.b * shadowShift2.x + shadowShift2.y);
					
					lightMap.xyz = _ShadowPostAO ? lightMap.xyz : lightMap.xyz * shadowBorderMask.rgb;
				}
				
				if (_LightingMulitlayerNonLinear)
				{
					lns.x = poiEdgeNonLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r);
					lns.y = poiEdgeNonLinearNoSaturate(lightMap.y, _Shadow2ndBorder, _Shadow2ndBlur * blurMap.g);
					lns.z = poiEdgeNonLinearNoSaturate(lightMap.z, _Shadow3rdBorder, _Shadow3rdBlur * blurMap.b);
					lns.w = poiEdgeNonLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r, _ShadowBorderRange);
				}
				else
				{
					lns.x = poiEdgeLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r);
					lns.y = poiEdgeLinearNoSaturate(lightMap.y, _Shadow2ndBorder, _Shadow2ndBlur * blurMap.g);
					lns.z = poiEdgeLinearNoSaturate(lightMap.z, _Shadow3rdBorder, _Shadow3rdBlur * blurMap.b);
					lns.w = poiEdgeLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r, _ShadowBorderRange);
				}
				#if defined(PROP_SHADOWBORDERMASK) || !defined(OPTIMIZER_ENABLED)
				lns = _ShadowPostAO ? lns * shadowBorderMask.rgbr : lns;
				#endif
				lns = saturate(lns);
				//poiLight.finalLighting = lns.rgb;
				//return;
				float3 indirectColor = 1;
				
				if (_ShadowColor.a > 0)
				{
					#if defined(PROP_SHADOWCOLORTEX) || !defined(OPTIMIZER_ENABLED)
					float4 shadowColorTex = POI2D_SAMPLER_PAN(_ShadowColorTex, _MainTex, poiUV(poiMesh.uv[_ShadowColorTexUV], _ShadowColorTex_ST), _ShadowColorTexPan);
					#else
					float4 shadowColorTex = float4(1, 1, 1, 1);
					#endif
					indirectColor = lerp(float3(1, 1, 1), shadowColorTex.rgb, shadowColorTex.a) * _ShadowColor.rgb;
				}
				if (_Shadow2ndColor.a > 0)
				{
					#if defined(PROP_SHADOW2NDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
					float4 shadow2ndColorTex = POI2D_SAMPLER_PAN(_Shadow2ndColorTex, _MainTex, poiUV(poiMesh.uv[_Shadow2ndColorTexUV], _Shadow2ndColorTex_ST), _Shadow2ndColorTexPan);
					#else
					float4 shadow2ndColorTex = float4(1, 1, 1, 1);
					#endif
					shadow2ndColorTex.rgb = lerp(float3(1, 1, 1), shadow2ndColorTex.rgb, shadow2ndColorTex.a) * _Shadow2ndColor.rgb;
					lns.y = _Shadow2ndColor.a - lns.y * _Shadow2ndColor.a;
					indirectColor = lerp(indirectColor, shadow2ndColorTex.rgb, lns.y);
				}
				if (_Shadow3rdColor.a > 0)
				{
					#if defined(PROP_SHADOW3RDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
					float4 shadow3rdColorTex = POI2D_SAMPLER_PAN(_Shadow3rdColorTex, _MainTex, poiUV(poiMesh.uv[_Shadow3rdColorTexUV], _Shadow3rdColorTex_ST), _Shadow3rdColorTexPan);
					#else
					float4 shadow3rdColorTex = float4(1, 1, 1, 1);
					#endif
					shadow3rdColorTex.rgb = lerp(float3(1, 1, 1), shadow3rdColorTex.rgb, shadow3rdColorTex.a) * _Shadow3rdColor.rgb;
					lns.z = _Shadow3rdColor.a - lns.z * _Shadow3rdColor.a;
					indirectColor = lerp(indirectColor, shadow3rdColorTex.rgb, lns.z);
				}
				
				indirectColor = lerp(indirectColor, indirectColor * poiFragData.baseColor, _ShadowMainStrength);
				poiLight.rampedLightMap = lns.x;
				indirectColor = lerp(indirectColor, 1, lns.w * _ShadowBorderColor.rgb * _ShadowBorderColor.a);
				indirectColor = indirectColor * lerp(poiLight.indirectColor, poiLight.directColor, _LightingIgnoreAmbientColor);
				indirectColor = lerp(poiLight.directColor, indirectColor, shadowStrength * poiLight.shadowMask);
				poiLight.finalLighting = lerp(indirectColor, poiLight.directColor, lns.x) * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_SHADEMAP
				poiLight.finalLighting = poiLight.directColor * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_REALISTIC
				UnityLight light;
				light.dir = poiLight.direction;
				light.color = max(0, _LightColor0.rgb) * saturate(shadowAttenuation * attenuation * poiLight.detailShadow);
				light.ndotl = poiLight.nDotLSaturated;
				UnityIndirect indirectLight = (UnityIndirect)0;
				#ifdef UNITY_PASS_FORWARDBASE
				indirectLight = CreateIndirectLight(poiMesh, poiCam, poiLight);
				#endif
				#ifdef UNITY_PASS_FORWARDBASE
				light.color = max(light.color * _PPLightingMultiplier, 0);
				light.color = max(light.color + _PPLightingAddition, 0);
				indirectLight.diffuse = max(indirectLight.diffuse * _PPLightingMultiplier, 0);
				indirectLight.diffuse = max(indirectLight.diffuse + _PPLightingAddition, 0);
				#endif
				
				poiLight.rampedLightMap = poiLight.nDotLSaturated;
				poiLight.finalLighting = max(UNITY_BRDF_PBS(1, 0, 0, 0, poiMesh.normals[1], poiCam.viewDir, light, indirectLight).xyz, _LightingMinLightBrightness);
				#endif
				
				#ifdef _LIGHTINGMODE_CLOTH
				#if defined(PROP_CLOTHMETALLICSMOOTHNESSMAP) || !defined(OPTIMIZER_ENABLED)
				float4 clothmapsample = POI2D_SAMPLER_PAN(_ClothMetallicSmoothnessMap, _MainTex, poiUV(poiMesh.uv[_ClothMetallicSmoothnessMapUV], _ClothMetallicSmoothnessMap_ST), _ClothMetallicSmoothnessMapPan);
				float roughness = 1 - (clothmapsample.a * _ClothSmoothness);
				float reflectance = _ClothReflectance * clothmapsample.b;
				float clothmask = clothmapsample.g;
				float metallic = pow(clothmapsample.r * _ClothMetallic, 2) * ClothMetallic(clothmask);
				roughness = _ClothMetallicSmoothnessMapInvert == 1 ? 1 - roughness : roughness;
				#else
				float roughness = 1 - (_ClothSmoothness);
				float metallic = pow(_ClothMetallic, 2);
				float reflectance = _ClothReflectance;
				float clothmask = 1;
				#endif
				
				float perceptualRoughness = pow(roughness, 2);
				float clampedRoughness = max(0.002, perceptualRoughness);
				
				float f0 = 0.16 * reflectance * reflectance * (1 - metallic) + poiFragData.baseColor * metallic;
				float3 fresnel = Fresnel(f0, poiLight.nDotV);
				
				float3 dfg = SampleDFG(poiLight.nDotV, perceptualRoughness);
				
				float energyCompensation = EnvBRDFEnergyCompensation(dfg, f0, clothmask);
				
				poiLight.finalLighting = Fd_Burley(perceptualRoughness, poiLight.nDotV, poiLight.nDotLSaturated, poiLight.lDotH);
				poiLight.finalLighting *= _LightColor0 * attenuation * shadowAttenuation * poiLight.nDotLSaturated;
				poiLight.rampedLightMap = poiLight.nDotLSaturated;
				float3 specular = max(0, Specular(clampedRoughness, poiLight, f0, poiMesh.normals[1], clothmask) * poiLight.finalLighting * energyCompensation * UNITY_PI); // (D * V) * F
				
				#ifdef UNITY_PASS_FORWARDBASE
				float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
				float3 indirectDiffuse;
				indirectDiffuse.r = shEvaluateDiffuseL1Geomerics_local(L0.r, unity_SHAr.xyz, poiMesh.normals[1]);
				indirectDiffuse.g = shEvaluateDiffuseL1Geomerics_local(L0.g, unity_SHAg.xyz, poiMesh.normals[1]);
				indirectDiffuse.b = shEvaluateDiffuseL1Geomerics_local(L0.b, unity_SHAb.xyz, poiMesh.normals[1]);
				indirectDiffuse = max(0, indirectDiffuse);
				
				float3 indirectSpecular = IndirectSpecular(dfg, roughness, poiLight.occlusion, energyCompensation, clothmask, indirectDiffuse, f0, poiLight, poiFragData, poiCam, poiMesh);
				poiLight.finalLightAdd += max(0, specular + indirectSpecular);
				poiLight.finalLighting += indirectDiffuse * poiLight.occlusion;
				#endif
				
				poiFragData.baseColor.xyz *= (1 - metallic);
				#endif
				
				#ifdef _LIGHTINGMODE_WRAPPED
				#define GREYSCALE_VECTOR float3(.33333, .33333, .33333)
				float3 directColor = _LightColor0.rgb * saturate(RTWrapFunc(poiLight.nDotL, _LightingWrappedWrap, _LightingWrappedNormalization));
				float3 indirectColor = 0;
				#ifdef UNITY_PASS_FORWARDBASE
				indirectColor = ShadeSH9_wrapped(poiMesh.normals[_LightingIndirectUsesNormals], _LightingWrappedWrap) * poiLight.occlusion;
				#endif
				directColor = lerp(directColor, dot(directColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic); // Duplicated from Lightdata due to recreating the light colour
				indirectColor = lerp(indirectColor, dot(indirectColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic); // Ditto^
				
				float3 ShadeSH9Plus_2 = GetSHMaxL1();
				float bw_topDirectLighting_2 = dot(_LightColor0.rgb, GREYSCALE_VECTOR);
				float bw_directLighting = dot(directColor, GREYSCALE_VECTOR);
				float bw_indirectLighting = dot(indirectColor, GREYSCALE_VECTOR);
				float bw_topIndirectLighting = dot(ShadeSH9Plus_2, GREYSCALE_VECTOR);
				
				poiLight.lightMap = smoothstep(0, bw_topIndirectLighting + bw_topDirectLighting_2, bw_indirectLighting + bw_directLighting) * min(poiLight.detailShadow, shadowAttenuation);
				poiLight.rampedLightMap = saturate((poiLight.lightMap - (1 - _LightingGradientEnd)) / saturate((1 - _LightingGradientStart) - (1 - _LightingGradientEnd) + fwidth(poiLight.lightMap)));
				float3 mathRamp = lerp(float3(1, 1, 1), saturate(lerp((_LightingShadowColor * lerp(indirectColor, 1, _LightingIgnoreAmbientColor)), float3(1, 1, 1), saturate(poiLight.rampedLightMap))), _ShadowStrength);
				
				directColor *= saturate(poiLight.rampedLightMap + 1 - _ShadowStrength) * _LightingWrappedColor;
				
				float3 finalWrap = directColor + indirectColor;
				if (_LightingCapEnabled)
				{
					finalWrap = clamp(finalWrap, _LightingMinLightBrightness, _LightingCap);
				}
				else
				{
					finalWrap = max(finalWrap, _LightingMinLightBrightness);
				}
				//finalWrap *= attenuation;
				poiLight.finalLighting = finalWrap * saturate(mathRamp + 1 - _ShadowStrength);
				#endif
				
				#ifdef _LIGHTINGMODE_SKIN
				float3 ambientNormalWorld = poiMesh.normals[1];//aTangentToWorld(s, s.blurredNormalTangent);
				poiLight.rampedLightMap = poiLight.nDotLSaturated;
				
				// Scattering mask.
				#if defined(PROP_SKINTHICKNESS) || !defined(OPTIMIZER_ENABLED)
				float subsurface = 1 - POI2D_SAMPLER_PAN(_SkinThicknessMap, _MainTex, poiUV(poiMesh.uv[_SkinThicknessMapUV], _SkinThicknessMap_ST), _SkinThicknessMapPan).r;
				#else
				float subsurface = 1;
				#endif
				if (_SkinThicknessMapInvert)
				{
					subsurface = 1 - subsurface;
				}
				if (_SkinThicknessPower != 1)
				{
					subsurface = pow(subsurface, _SkinThicknessPower);
				}
				float skinScattering = saturate(subsurface * _SssScale * 2);
				
				// Skin subsurface depth absorption tint.
				// cf http://www.crytek.com/download/2014_03_25_CRYENGINE_GDC_Schultz.pdf pg 35
				// link dead, https://ia600902.us.archive.org/25/items/crytek_presentations/2014_03_25_CRYENGINE_GDC_Schultz.pdf
				half3 absorption = exp((1.0h - subsurface) * _SssTransmissionAbsorption.rgb);
				
				// Albedo scale for absorption assumes ~0.5 luminance for Caucasian skin.
				absorption *= saturate(poiFragData.baseColor * unity_ColorSpaceDouble.rgb);
				
				// Blurred normals for indirect diffuse and direct scattering.
				ambientNormalWorld = normalize(lerp(poiMesh.normals[1], ambientNormalWorld, _SssBumpBlur));
				
				float ndlBlur = dot(poiMesh.normals[1], poiLight.direction) * 0.5h + 0.5h;
				float lumi = dot(poiLight.directColor, half3(0.2126h, 0.7152h, 0.0722h));
				float4 sssLookupUv = float4(ndlBlur, skinScattering * lumi, 0.0f, 0.0f);
				half3 sss = poiLight.lightMap * tex2Dlod(_SkinLUT, sssLookupUv).rgb;
				poiLight.finalLighting = lerp(poiLight.directColor, min(lerp(poiLight.indirectColor * _LightingShadowColor, _LightingShadowColor, _LightingIgnoreAmbientColor) * poiLight.occlusion + (sss * poiLight.directColor), poiLight.directColor), _ShadowStrength * poiLight.shadowMask) * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_SDF
				float3 forward = normalize(UnityObjectToWorldDir(float4(_SDFForward.xyz, 1)));
				float3 left = normalize(UnityObjectToWorldDir(float4(_SDFLeft.xyz, 1)));
				float3 lightDirHorizontal = normalize(float3(poiLight.direction.x, 0, poiLight.direction.z));
				
				float lightAtten = 1 - (dot(lightDirHorizontal, forward) * 0.5 + 0.5);
				float filpU = sign(dot(lightDirHorizontal, left));
				
				#if defined(PROP_SDFSHADINGTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float shadowSDF = POI2D_SAMPLER_PAN(_SDFShadingTexture, _MainTex, poiUV(poiMesh.uv[_SDFShadingTextureUV], _SDFShadingTexture_ST) * float2(filpU, 1), _SDFShadingTexturePan).r;
				#else
				float shadowSDF = float2(1, 1);
				#endif
				float blur = _SDFBlur * 0.1;
				float faceShadow = smoothstep(lightAtten - blur, lightAtten + blur, shadowSDF) * poiLight.detailShadow;
				
				float3 indirectColor = _LightingShadowColor.rgb;
				indirectColor = indirectColor * lerp(poiLight.indirectColor, poiLight.directColor, _LightingIgnoreAmbientColor);
				indirectColor = lerp(poiLight.directColor, indirectColor, _ShadowStrength * poiLight.shadowMask);
				
				poiLight.finalLighting = lerp(indirectColor, poiLight.directColor, faceShadow) * attenuation;
				#endif
				
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					float3 vertexLighting = float3(0, 0, 0);
					for (int index = 0; index < 4; index++)
					{
						float lightingMode = _LightingAdditiveType;
						if (lightingMode == 3)
						{
							//This is a temporary bandaid fix
							#if defined(_LIGHTINGMODE_REALISTIC)
							lightingMode = 0;
							#else
							lightingMode = 1;
							#endif
						}
						//UNITY_BRANCH
						if (lightingMode == 0)
						{
							vertexLighting = max(vertexLighting, poiLight.vColor[index] * poiLight.vSaturatedDotNL[index] * poiLight.detailShadow); // Realistic
							
						}
						//UNITY_BRANCH
						// Toon
						if (lightingMode == 1)
						{
							float2 ToonAddGradient = float2(_LightingAdditiveGradientStart, _LightingAdditiveGradientEnd);
							if (ToonAddGradient.x == ToonAddGradient.y) ToonAddGradient.y += 0.0001;
							vertexLighting = max(vertexLighting, lerp(poiLight.vColor[index], poiLight.vColor[index] * _LightingAdditivePassthrough, smoothstep(ToonAddGradient.x, ToonAddGradient.y, 1 - (.5 * poiLight.vDotNL[index] + .5))) * poiLight.detailShadow);
						}
					}
					float3 mixedLight = poiLight.finalLighting;
					poiLight.finalLighting = max(vertexLighting, poiLight.finalLighting);
					#endif
				}
			}
			#endif
			//endex
			
			#if defined(GEOM_TYPE_BRANCH) || defined(GEOM_TYPE_BRANCH_DETAIL) || defined(GEOM_TYPE_FROND) || defined(DEPTH_OF_FIELD_COC_VIEW)
			float2 decalUV(float uvNumber, float2 position, half rotation, half rotationSpeed, half2 scale, float4 scaleOffset, float depth, in PoiMesh poiMesh, in PoiCam poiCam)
			{
				scaleOffset = float4(-scaleOffset.x, scaleOffset.y, -scaleOffset.z, scaleOffset.w);
				float2 centerOffset = float2((scaleOffset.x + scaleOffset.y) / 2, (scaleOffset.z + scaleOffset.w) / 2);
				float2 uv = poiMesh.uv[uvNumber] + calcParallax(depth + 1, poiCam);
				float2 decalCenter = position + centerOffset;
				float theta = radians(rotation + _Time.z * rotationSpeed);
				float cs = cos(theta);
				float sn = sin(theta);
				uv = float2((uv.x - decalCenter.x) * cs - (uv.y - decalCenter.y) * sn + decalCenter.x, (uv.x - decalCenter.x) * sn + (uv.y - decalCenter.y) * cs + decalCenter.y);
				uv = remap(uv, float2(0, 0) - scale / 2 + position + scaleOffset.xz, scale / 2 + position + scaleOffset.yw, float2(0, 0), float2(1, 1));
				return uv;
			}
			
			inline float3 decalHueShift(float enabled, float3 color, float shift, float shiftSpeed)
			{
				//UNITY_BRANCH
				if (enabled)
				{
					color = hueShift(color, shift + _Time.x * shiftSpeed);
				}
				return color;
			}
			
			inline float applyTilingClipping(float enabled, float2 uv)
			{
				float ret = 1;
				//UNITY_BRANCH
				if (!enabled)
				{
					if (uv.x > 1 || uv.y > 1 || uv.x < 0 || uv.y < 0)
					{
						ret = 0;
					}
				}
				return ret;
			}
			
			struct PoiDecal
			{
				float m_DecalFaceMask;
				float m_DecalMaskChannel;
				float m_DecalGlobalMask;
				float m_DecalGlobalMaskBlendType;
				float m_DecalApplyGlobalMaskIndex;
				float m_DecalApplyGlobalMaskBlendType;
				float4 m_DecalTexture_ST;
				float2 m_DecalTexturePan;
				float m_DecalTextureUV;
				float4 m_DecalColor;
				float m_DecalColorThemeIndex;
				fixed m_DecalTiled;
				float m_DecalBlendType;
				half m_DecalRotation;
				half3 m_DecalScale;
				float4 m_DecalSideOffset;
				half2 m_DecalPosition;
				half m_DecalRotationSpeed;
				float m_DecalEmissionStrength;
				float m_DecalBlendAlpha;
				float m_DecalAlphaBlendMode;
				float m_DecalHueShiftEnabled;
				float m_DecalHueShift;
				float m_DecalHueShiftSpeed;
				float m_DecalDepth;
				float m_DecalHueAngleStrength;
				float m_DecalChannelSeparationEnable;
				float m_DecalChannelSeparation;
				float m_DecalChannelSeparationPremultiply;
				float m_DecalChannelSeparationHue;
				float m_DecalChannelSeparationVertical;
				float m_DecalChannelSeparationAngleStrength;
				float m_DecalOverrideAlphaMode;
				float m_DecalOverrideAlpha;
				
				#if defined(POI_AUDIOLINK)
				half m_AudioLinkDecalScaleBand;
				float4 m_AudioLinkDecalScale;
				half m_AudioLinkDecalRotationBand;
				float2 m_AudioLinkDecalRotation;
				half m_AudioLinkDecalAlphaBand;
				float2 m_AudioLinkDecalAlpha;
				half m_AudioLinkDecalEmissionBand;
				float2 m_AudioLinkDecalEmission;
				float m_DecalRotationCTALBand;
				float m_DecalRotationCTALSpeed;
				float m_DecalRotationCTALType;
				float m_AudioLinkDecalColorChord;
				float m_AudioLinkDecalSideBand;
				float4 m_AudioLinkDecalSideMin;
				float4 m_AudioLinkDecalSideMax;
				float2 m_AudioLinkDecalChannelSeparation;
				float m_AudioLinkDecalChannelSeparationBand;
				#endif
				
				float4 decalColor;
				float2 decalScale;
				float decalRotation;
				float2 uv;
				float4 dduv;
				float4 sideMod;
				float decalChannelOffset;
				float4 decalMask;
				
				void Init(in float4 DecalMask)
				{
					decalMask = DecalMask;
					decalScale = m_DecalScale.xy;// * m_DecalScale.z;
					
				}
				
				void InitAudiolink(in PoiMods poiMods)
				{
					#ifdef POI_AUDIOLINK
					if (poiMods.audioLinkAvailable)
					{
						decalScale += lerp(m_AudioLinkDecalScale.xy, m_AudioLinkDecalScale.zw, poiMods.audioLink[m_AudioLinkDecalScaleBand]);
						sideMod += lerp(m_AudioLinkDecalSideMin, m_AudioLinkDecalSideMax, poiMods.audioLink[m_AudioLinkDecalSideBand]);
						decalRotation += lerp(m_AudioLinkDecalRotation.x, m_AudioLinkDecalRotation.y, poiMods.audioLink[m_AudioLinkDecalRotationBand]);
						decalRotation += AudioLinkGetChronoTime(m_DecalRotationCTALType, m_DecalRotationCTALBand) * m_DecalRotationCTALSpeed * 360;
						decalChannelOffset += lerp(m_AudioLinkDecalChannelSeparation[0], m_AudioLinkDecalChannelSeparation[1], poiMods.audioLink[m_AudioLinkDecalChannelSeparationBand]);
					}
					#endif
				}
				
				void SampleDecalNoTexture(in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam)
				{
					uv = decalUV(m_DecalTextureUV, m_DecalPosition, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					decalColor = float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					decalColor.rgb = decalHueShift(m_DecalHueShiftEnabled, decalColor.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					decalColor.a *= decalMask[m_DecalMaskChannel] * applyTilingClipping(m_DecalTiled, uv);
				}
				
				void SampleDecal(sampler2D decalTexture, in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam, float2 scaleMultiplier = float2(1, 1))
				{
					uv = decalUV(m_DecalTextureUV, m_DecalPosition, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale * scaleMultiplier, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					// Adjust derivatives for _ST of decal texture
					float4 dduv = any(fwidth(uv) > .5) ? 0.001 : float4(ddx(uv) * m_DecalTexture_ST.x, ddy(uv) * m_DecalTexture_ST.y);
					decalColor = tex2D(decalTexture, poiUV(uv, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduv.xy, dduv.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					decalColor.rgb = decalHueShift(m_DecalHueShiftEnabled, decalColor.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					decalColor.a *= decalMask[m_DecalMaskChannel] * applyTilingClipping(m_DecalTiled, uv);
				}
				
				void SampleDecalNoAlpha(sampler2D decalTexture, in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam, float2 scaleMultiplier = float2(1, 1))
				{
					uv = decalUV(m_DecalTextureUV, m_DecalPosition, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale * scaleMultiplier, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					// Adjust derivatives for _ST of decal texture
					float4 dduv = any(fwidth(uv) > .5) ? 0.001 : float4(ddx(uv) * m_DecalTexture_ST.x, ddy(uv) * m_DecalTexture_ST.y);
					decalColor.rgb = tex2D(decalTexture, poiUV(uv, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduv.xy, dduv.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a).rgb;
					decalColor.rgb = decalHueShift(m_DecalHueShiftEnabled, decalColor.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					decalColor.a *= decalMask[m_DecalMaskChannel] * applyTilingClipping(m_DecalTiled, uv);
				}
				
				void SampleDecalAlphaOnly(sampler2D decalTexture, in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam, float2 scaleMultiplier = float2(1, 1))
				{
					uv = decalUV(m_DecalTextureUV, m_DecalPosition, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale * scaleMultiplier, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					// Adjust derivatives for _ST of decal texture
					float4 dduv = any(fwidth(uv) > .5) ? 0.001 : float4(ddx(uv) * m_DecalTexture_ST.x, ddy(uv) * m_DecalTexture_ST.y);
					decalColor = tex2D(decalTexture, poiUV(uv, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduv.xy, dduv.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					decalColor.a *= decalMask[m_DecalMaskChannel] * applyTilingClipping(m_DecalTiled, uv);
				}
				
				void SampleDecalChannelSeparation(sampler2D decalTexture, in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam)
				{
					decalColor = float4(0, 0, 0, 1);
					decalChannelOffset += m_DecalChannelSeparation + m_DecalChannelSeparationAngleStrength * (m_DecalChannelSeparationAngleStrength > 0 ? (1 - poiLight.nDotV) : poiLight.nDotV);
					float2 positionOffset = decalChannelOffset * 0.01 * (decalScale.x + decalScale.y) * float2(cos(m_DecalChannelSeparationVertical), sin(m_DecalChannelSeparationVertical));
					float2 uvSample0 = decalUV(m_DecalTextureUV, m_DecalPosition + positionOffset, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					float2 uvSample1 = decalUV(m_DecalTextureUV, m_DecalPosition - positionOffset, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					
					float4 dduvSample0 = any(fwidth(uvSample0) > .5) ? 0.001 : float4(ddx(uvSample0) * m_DecalTexture_ST.x, ddy(uvSample0) * m_DecalTexture_ST.y);
					float4 dduvSample1 = any(fwidth(uvSample1) > .5) ? 0.001 : float4(ddx(uvSample1) * m_DecalTexture_ST.x, ddy(uvSample1) * m_DecalTexture_ST.y);
					
					float4 sample0 = tex2D(decalTexture, poiUV(uvSample0, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduvSample0.xy, dduvSample0.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					float4 sample1 = tex2D(decalTexture, poiUV(uvSample1, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduvSample1.xy, dduvSample1.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					
					sample0.rgb = decalHueShift(m_DecalHueShiftEnabled, sample0.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					sample1.rgb = decalHueShift(m_DecalHueShiftEnabled, sample1.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					
					float3 channelSeparationColor = HUEtoRGB(frac(m_DecalChannelSeparationHue));
					
					if (m_DecalChannelSeparationPremultiply)
					{
						decalColor.rgb = lerp(sample0 * sample0.a, sample1 * sample1.a, channelSeparationColor);
					}
					else
					{
						decalColor.rgb = lerp(sample0, sample1, channelSeparationColor);
					}
					decalColor.a = 0.5 * (sample0.a + sample1.a);
					decalColor.a *= decalMask[m_DecalMaskChannel] * max(applyTilingClipping(m_DecalTiled, uvSample0), applyTilingClipping(m_DecalTiled, uvSample1));
				}
				
				void Apply(inout float alphaOverride, inout float decalAlpha, inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, inout PoiMods poiMods, in PoiLight poiLight)
				{
					if (m_DecalGlobalMask > 0)
					{
						decalColor.a = maskBlend(decalColor.a, poiMods.globalMask[m_DecalGlobalMask - 1], m_DecalGlobalMaskBlendType);
					}
					
					float audioLinkDecalAlpha = 0;
					float audioLinkDecalEmission = 0;
					#ifdef POI_AUDIOLINK
					audioLinkDecalEmission = lerp(m_AudioLinkDecalEmission.x, m_AudioLinkDecalEmission.y, poiMods.audioLink[m_AudioLinkDecalEmissionBand]) * poiMods.audioLinkAvailable;
					
					if (m_AudioLinkDecalColorChord)
					{
						if (poiMods.audioLinkAvailable)
						{
							decalColor.rgb *= AudioLinkLerp(ALPASS_CCSTRIP + float2(uv.x * AUDIOLINK_WIDTH, 0)).rgb;
						}
						else
						{
							decalAlpha = 0;
						}
					}
					audioLinkDecalAlpha = lerp(m_AudioLinkDecalAlpha.x, m_AudioLinkDecalAlpha.y, poiMods.audioLink[m_AudioLinkDecalAlphaBand]) * poiMods.audioLinkAvailable;
					#endif
					
					if (m_DecalOverrideAlpha)
					{
						float finalAlpha = lerp(1, min(decalAlpha, decalColor.a), decalMask[m_DecalMaskChannel]);
						if (m_DecalOverrideAlphaMode != 0 && !m_DecalTiled)
						{
							if (uv.x > 0 && uv.x < 1 && uv.y > 0 && uv.y < 1)
							{
								//decalAlpha = lerp(decalAlpha, min(decalAlpha, decalColor.a), decalMask[m_DecalMaskChannel]);
								//poiFragData.alpha = saturate(poiFragData.alpha + lerp(1, min(decalAlpha, decalColor.a), decalMask[m_DecalMaskChannel]));
								if (m_DecalOverrideAlpha == 1) poiFragData.alpha = finalAlpha;
								if (m_DecalOverrideAlpha == 2) poiFragData.alpha = saturate(poiFragData.alpha * finalAlpha);
								if (m_DecalOverrideAlpha == 3) poiFragData.alpha = saturate(poiFragData.alpha + finalAlpha);
								if (m_DecalOverrideAlpha == 4) poiFragData.alpha = saturate(poiFragData.alpha - finalAlpha);
								if (m_DecalOverrideAlpha == 5) poiFragData.alpha = min(poiFragData.alpha, finalAlpha);
								if (m_DecalOverrideAlpha == 6) poiFragData.alpha = max(poiFragData.alpha, finalAlpha);
							}
						}
						else
						{
							if (m_DecalOverrideAlpha == 1) poiFragData.alpha = finalAlpha;
							if (m_DecalOverrideAlpha == 2) poiFragData.alpha = saturate(poiFragData.alpha * finalAlpha);
							if (m_DecalOverrideAlpha == 3) poiFragData.alpha = saturate(poiFragData.alpha + finalAlpha);
							if (m_DecalOverrideAlpha == 4) poiFragData.alpha = saturate(poiFragData.alpha - finalAlpha);
							if (m_DecalOverrideAlpha == 5) poiFragData.alpha = min(poiFragData.alpha, finalAlpha);
							if (m_DecalOverrideAlpha == 6) poiFragData.alpha = max(poiFragData.alpha, finalAlpha);
						}
					}
					
					if (m_DecalFaceMask > 0)
					{
						if (m_DecalFaceMask == 1 && !poiMesh.isFrontFace)
						{
							decalColor.a *= 0;
						}
						else if (m_DecalFaceMask == 2 && poiMesh.isFrontFace)
						{
							decalColor.a *= 0;
						}
					}
					
					float decalAlphaMixed = decalColor.a * saturate(m_DecalBlendAlpha + audioLinkDecalAlpha);
					
					if (m_DecalApplyGlobalMaskIndex > 0)
					{
						applyToGlobalMask(poiMods, m_DecalApplyGlobalMaskIndex - 1, m_DecalApplyGlobalMaskBlendType, decalAlphaMixed);
					}
					
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, decalColor.rgb, m_DecalBlendType), decalAlphaMixed);
					poiFragData.emission += decalColor.rgb * decalColor.a * max(m_DecalEmissionStrength + audioLinkDecalEmission, 0);
				}
				float2 GetVideoAspectRatio(float2 videoDimensions, float CorrectionType, float fitToScale)
				{
					float2 AspectRatioMultiplier = float2(1, 1);
					if (fitToScale)
					{
						float2 decalScale = m_DecalScale.xy + float2(m_DecalSideOffset.x + m_DecalSideOffset.y, m_DecalSideOffset.z + m_DecalSideOffset.w);
						if (decalScale.x > decalScale.y)
						{
							videoDimensions.xy *= float2((decalScale.y / decalScale.x), 1);
						}
						else
						{
							videoDimensions.xy *= float2(1, (decalScale.x / decalScale.y));
						}
					}
					
					if (CorrectionType != 2)
					{
						if (CorrectionType == 0)
						{
							if (videoDimensions.x > videoDimensions.y)
							{
								AspectRatioMultiplier = float2(1, videoDimensions.y / videoDimensions.x);
							}
							else
							{
								AspectRatioMultiplier = float2(videoDimensions.x / videoDimensions.y, 1);
							}
						}
						else if (CorrectionType == 1)
						{
							if (videoDimensions.x > videoDimensions.y)
							{
								AspectRatioMultiplier = float2(1 / (videoDimensions.y / videoDimensions.x), 1);
							}
							else
							{
								AspectRatioMultiplier = float2(1, 1 / (videoDimensions.x / videoDimensions.y));
							}
						}
					}
					return AspectRatioMultiplier;
				}
			};
			
			void applyDecals(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, inout PoiMods poiMods, in PoiLight poiLight)
			{
				// check if _Udon_VideoTex is greater than 16 pixels in width
				float udonVideoTexAvailable = 0;
				float2 udonVideoAspectRatio = 1;
				if (_Udon_VideoTex_TexelSize.z > 16)
				{
					udonVideoTexAvailable = 1;
				}
				
				float decalAlpha = 1;
				float alphaOverride = 0;
				#if defined(PROP_DECALMASK) || !defined(OPTIMIZER_ENABLED)
				float4 decalMask = POI2D_SAMPLER_PAN(_DecalMask, _MainTex, poiUV(poiMesh.uv[_DecalMaskUV], _DecalMask_ST), _DecalMaskPan);
				#else
				float4 decalMask = 1;
				#endif
				
				#ifdef TPS_Penetrator
				if (_DecalTPSDepthMaskEnabled)
				{
					decalMask.r = lerp(0, decalMask.r * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Decal0TPSMaskStrength);
					decalMask.g = lerp(0, decalMask.g * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Decal1TPSMaskStrength);
					decalMask.b = lerp(0, decalMask.b * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Decal2TPSMaskStrength);
					decalMask.a = lerp(0, decalMask.a * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Decal3TPSMaskStrength);
				}
				#endif
				
				float4 decalColor = 1;
				float2 uv = 0;
				// yaes
				
				//ifex _DecalEnabled==0
				#ifdef GEOM_TYPE_BRANCH
				PoiDecal Decal0;
				PoiInitStruct(PoiDecal, Decal0)
				Decal0.m_DecalFaceMask = _Decal0FaceMask;
				Decal0.m_DecalMaskChannel = _Decal0MaskChannel;
				Decal0.m_DecalGlobalMask = _Decal0GlobalMask;
				Decal0.m_DecalGlobalMaskBlendType = _Decal0GlobalMaskBlendType;
				Decal0.m_DecalApplyGlobalMaskIndex = _Decal0ApplyGlobalMaskIndex;
				Decal0.m_DecalApplyGlobalMaskBlendType = _Decal0ApplyGlobalMaskBlendType;
				Decal0.m_DecalTexture_ST = _DecalTexture_ST;
				Decal0.m_DecalTexturePan = _DecalTexturePan;
				Decal0.m_DecalTextureUV = _DecalTextureUV;
				Decal0.m_DecalColor = _DecalColor;
				Decal0.m_DecalColorThemeIndex = _DecalColorThemeIndex;
				Decal0.m_DecalTiled = _DecalTiled;
				Decal0.m_DecalBlendType = _DecalBlendType;
				Decal0.m_DecalRotation = _DecalRotation;
				Decal0.m_DecalScale = _DecalScale;
				Decal0.m_DecalSideOffset = _DecalSideOffset;
				Decal0.m_DecalPosition = _DecalPosition;
				Decal0.m_DecalRotationSpeed = _DecalRotationSpeed;
				Decal0.m_DecalEmissionStrength = _DecalEmissionStrength;
				Decal0.m_DecalBlendAlpha = _DecalBlendAlpha;
				Decal0.m_DecalOverrideAlpha = _DecalOverrideAlpha;
				Decal0.m_DecalHueShiftEnabled = _DecalHueShiftEnabled;
				Decal0.m_DecalHueShift = _DecalHueShift;
				Decal0.m_DecalHueShiftSpeed = _DecalHueShiftSpeed;
				Decal0.m_DecalDepth = _Decal0Depth;
				Decal0.m_DecalHueAngleStrength = _Decal0HueAngleStrength;
				Decal0.m_DecalChannelSeparationEnable = _Decal0ChannelSeparationEnable;
				Decal0.m_DecalChannelSeparation = _Decal0ChannelSeparation;
				Decal0.m_DecalChannelSeparationPremultiply = _Decal0ChannelSeparationPremultiply;
				Decal0.m_DecalChannelSeparationHue = _Decal0ChannelSeparationHue;
				Decal0.m_DecalChannelSeparationVertical = _Decal0ChannelSeparationVertical;
				Decal0.m_DecalChannelSeparationAngleStrength = _Decal0ChannelSeparationAngleStrength;
				Decal0.m_DecalOverrideAlphaMode = _Decal0OverrideAlphaMode;
				
				Decal0.Init(decalMask);
				
				#if defined(POI_AUDIOLINK)
				Decal0.m_AudioLinkDecalScaleBand = _AudioLinkDecal0ScaleBand;
				Decal0.m_AudioLinkDecalScale = _AudioLinkDecal0Scale;
				Decal0.m_AudioLinkDecalRotationBand = _AudioLinkDecal0RotationBand;
				Decal0.m_AudioLinkDecalRotation = _AudioLinkDecal0Rotation;
				Decal0.m_AudioLinkDecalAlphaBand = _AudioLinkDecal0AlphaBand;
				Decal0.m_AudioLinkDecalAlpha = _AudioLinkDecal0Alpha;
				Decal0.m_AudioLinkDecalEmissionBand = _AudioLinkDecal0EmissionBand;
				Decal0.m_AudioLinkDecalEmission = _AudioLinkDecal0Emission;
				Decal0.m_DecalRotationCTALBand = _DecalRotationCTALBand0;
				Decal0.m_DecalRotationCTALSpeed = _DecalRotationCTALSpeed0;
				Decal0.m_DecalRotationCTALType = _DecalRotationCTALType0;
				Decal0.m_AudioLinkDecalColorChord = _AudioLinkDecalCC0;
				Decal0.m_AudioLinkDecalSideBand = _AudioLinkDecal0SideBand;
				Decal0.m_AudioLinkDecalSideMin = _AudioLinkDecal0SideMin;
				Decal0.m_AudioLinkDecalSideMax = _AudioLinkDecal0SideMax;
				Decal0.m_AudioLinkDecalChannelSeparation = _AudioLinkDecal0ChannelSeparation;
				Decal0.m_AudioLinkDecalChannelSeparationBand = _AudioLinkDecal0ChannelSeparationBand;
				
				Decal0.InitAudiolink(poiMods);
				#endif
				
				if (!_Decal0VideoEnabled)
				{
					
					#if defined(PROP_DECALTEXTURE) || !defined(OPTIMIZER_ENABLED)
					//ifex _Decal0ChannelSeparationEnable==0
					if (_Decal0ChannelSeparationEnable)
					{
						Decal0.SampleDecalChannelSeparation(_DecalTexture, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					//ifex _Decal0ChannelSeparationEnable==1
					if (!_Decal0ChannelSeparationEnable)
					{
						Decal0.SampleDecal(_DecalTexture, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					#else
					Decal0.SampleDecalNoTexture(poiMods, poiLight, poiMesh, poiCam);
					#endif
					Decal0.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
				}
				else
				{
					udonVideoAspectRatio = Decal0.GetVideoAspectRatio(_Udon_VideoTex_TexelSize.zw, _Decal0VideoAspectFix, _Decal0VideoFitToScale);
					
					if (_Decal0OnlyVideo)
					{
						if (udonVideoTexAvailable)
						{
							Decal0.m_DecalEmissionStrength += _Decal0VideoEmissionStrength;
							if (_Decal0UseDecalAlpha)
							{
								Decal0.SampleDecal(_DecalTexture, poiMods, poiLight, poiMesh, poiCam);
								Decal0.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal0.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							Decal0.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
						}
					}
					else
					{
						Decal0.SampleDecal(_DecalTexture, poiMods, poiLight, poiMesh, poiCam);
						if (udonVideoTexAvailable)
						{
							Decal0.m_DecalEmissionStrength += _Decal0VideoEmissionStrength;
							if (_Decal0UseDecalAlpha)
							{
								Decal0.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal0.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
						}
						Decal0.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
					}
				}
				#endif
				//endex
				
				//ifex _DecalEnabled1==0
				#ifdef GEOM_TYPE_BRANCH_DETAIL
				PoiDecal Decal1;
				PoiInitStruct(PoiDecal, Decal1)
				Decal1.m_DecalFaceMask = _Decal1FaceMask;
				Decal1.m_DecalMaskChannel = _Decal1MaskChannel;
				Decal1.m_DecalGlobalMask = _Decal1GlobalMask;
				Decal1.m_DecalGlobalMaskBlendType = _Decal1GlobalMaskBlendType;
				Decal1.m_DecalApplyGlobalMaskIndex = _Decal1ApplyGlobalMaskIndex;
				Decal1.m_DecalApplyGlobalMaskBlendType = _Decal1ApplyGlobalMaskBlendType;
				Decal1.m_DecalTexture_ST = _DecalTexture1_ST;
				Decal1.m_DecalTexturePan = _DecalTexture1Pan;
				Decal1.m_DecalTextureUV = _DecalTexture1UV;
				Decal1.m_DecalColor = _DecalColor1;
				Decal1.m_DecalColorThemeIndex = _DecalColor1ThemeIndex;
				Decal1.m_DecalTiled = _DecalTiled1;
				Decal1.m_DecalBlendType = _DecalBlendType1;
				Decal1.m_DecalRotation = _DecalRotation1;
				Decal1.m_DecalScale = _DecalScale1;
				Decal1.m_DecalSideOffset = _DecalSideOffset1;
				Decal1.m_DecalPosition = _DecalPosition1;
				Decal1.m_DecalRotationSpeed = _DecalRotationSpeed1;
				Decal1.m_DecalEmissionStrength = _DecalEmissionStrength1;
				Decal1.m_DecalBlendAlpha = _DecalBlendAlpha1;
				Decal1.m_DecalOverrideAlpha = _DecalOverrideAlpha1;
				Decal1.m_DecalHueShiftEnabled = _DecalHueShiftEnabled1;
				Decal1.m_DecalHueShift = _DecalHueShift1;
				Decal1.m_DecalHueShiftSpeed = _DecalHueShiftSpeed1;
				Decal1.m_DecalDepth = _Decal1Depth;
				Decal1.m_DecalHueAngleStrength = _Decal1HueAngleStrength;
				Decal1.m_DecalChannelSeparationEnable = _Decal1ChannelSeparationEnable;
				Decal1.m_DecalChannelSeparation = _Decal1ChannelSeparation;
				Decal1.m_DecalChannelSeparationPremultiply = _Decal1ChannelSeparationPremultiply;
				Decal1.m_DecalChannelSeparationHue = _Decal1ChannelSeparationHue;
				Decal1.m_DecalChannelSeparationVertical = _Decal1ChannelSeparationVertical;
				Decal1.m_DecalChannelSeparationAngleStrength = _Decal1ChannelSeparationAngleStrength;
				Decal1.m_DecalOverrideAlphaMode = _Decal1OverrideAlphaMode;
				Decal1.Init(decalMask);
				
				#if defined(POI_AUDIOLINK)
				Decal1.m_AudioLinkDecalScaleBand = _AudioLinkDecal1ScaleBand;
				Decal1.m_AudioLinkDecalScale = _AudioLinkDecal1Scale;
				Decal1.m_AudioLinkDecalRotationBand = _AudioLinkDecal1RotationBand;
				Decal1.m_AudioLinkDecalRotation = _AudioLinkDecal1Rotation;
				Decal1.m_AudioLinkDecalAlphaBand = _AudioLinkDecal1AlphaBand;
				Decal1.m_AudioLinkDecalAlpha = _AudioLinkDecal1Alpha;
				Decal1.m_AudioLinkDecalEmissionBand = _AudioLinkDecal1EmissionBand;
				Decal1.m_AudioLinkDecalEmission = _AudioLinkDecal1Emission;
				Decal1.m_DecalRotationCTALBand = _DecalRotationCTALBand1;
				Decal1.m_DecalRotationCTALSpeed = _DecalRotationCTALSpeed1;
				Decal1.m_DecalRotationCTALType = _DecalRotationCTALType1;
				Decal1.m_AudioLinkDecalColorChord = _AudioLinkDecalCC1;
				Decal1.m_AudioLinkDecalSideBand = _AudioLinkDecal1SideBand;
				Decal1.m_AudioLinkDecalSideMin = _AudioLinkDecal1SideMin;
				Decal1.m_AudioLinkDecalSideMax = _AudioLinkDecal1SideMax;
				Decal1.m_AudioLinkDecalChannelSeparation = _AudioLinkDecal1ChannelSeparation;
				Decal1.m_AudioLinkDecalChannelSeparationBand = _AudioLinkDecal1ChannelSeparationBand;
				
				Decal1.InitAudiolink(poiMods);
				#endif
				
				if (!_Decal1VideoEnabled)
				{
					#if defined(PROP_DECALTEXTURE1) || !defined(OPTIMIZER_ENABLED)
					//ifex _Decal1ChannelSeparationEnable==0
					if (_Decal1ChannelSeparationEnable)
					{
						Decal1.SampleDecalChannelSeparation(_DecalTexture1, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					//ifex _Decal1ChannelSeparationEnable==1
					if (!_Decal1ChannelSeparationEnable)
					{
						Decal1.SampleDecal(_DecalTexture1, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					#else
					Decal1.SampleDecalNoTexture(poiMods, poiLight, poiMesh, poiCam);
					#endif
					Decal1.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
				}
				else
				{
					udonVideoAspectRatio = Decal1.GetVideoAspectRatio(_Udon_VideoTex_TexelSize.zw, _Decal1VideoAspectFix, _Decal1VideoFitToScale);
					if (_Decal1OnlyVideo)
					{
						if (udonVideoTexAvailable)
						{
							Decal1.m_DecalEmissionStrength += _Decal1VideoEmissionStrength;
							if (_Decal1UseDecalAlpha)
							{
								Decal1.SampleDecal(_DecalTexture1, poiMods, poiLight, poiMesh, poiCam);
								Decal1.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal1.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							Decal1.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
						}
					}
					else
					{
						Decal1.SampleDecal(_DecalTexture1, poiMods, poiLight, poiMesh, poiCam);
						if (udonVideoTexAvailable)
						{
							Decal1.m_DecalEmissionStrength += _Decal1VideoEmissionStrength;
							if (_Decal1UseDecalAlpha)
							{
								Decal1.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal1.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
						}
						Decal1.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
					}
				}
				#endif
				//endex
				
				//ifex _DecalEnabled2==0
				#ifdef GEOM_TYPE_FROND
				PoiDecal Decal2;
				PoiInitStruct(PoiDecal, Decal2)
				Decal2.m_DecalFaceMask = _Decal2FaceMask;
				Decal2.m_DecalMaskChannel = _Decal2MaskChannel;
				Decal2.m_DecalGlobalMask = _Decal2GlobalMask;
				Decal2.m_DecalGlobalMaskBlendType = _Decal2GlobalMaskBlendType;
				Decal2.m_DecalApplyGlobalMaskIndex = _Decal2ApplyGlobalMaskIndex;
				Decal2.m_DecalApplyGlobalMaskBlendType = _Decal2ApplyGlobalMaskBlendType;
				Decal2.m_DecalTexture_ST = _DecalTexture2_ST;
				Decal2.m_DecalTexturePan = _DecalTexture2Pan;
				Decal2.m_DecalTextureUV = _DecalTexture2UV;
				Decal2.m_DecalColor = _DecalColor2;
				Decal2.m_DecalColorThemeIndex = _DecalColor2ThemeIndex;
				Decal2.m_DecalTiled = _DecalTiled2;
				Decal2.m_DecalBlendType = _DecalBlendType2;
				Decal2.m_DecalRotation = _DecalRotation2;
				Decal2.m_DecalScale = _DecalScale2;
				Decal2.m_DecalSideOffset = _DecalSideOffset2;
				Decal2.m_DecalPosition = _DecalPosition2;
				Decal2.m_DecalRotationSpeed = _DecalRotationSpeed2;
				Decal2.m_DecalEmissionStrength = _DecalEmissionStrength2;
				Decal2.m_DecalBlendAlpha = _DecalBlendAlpha2;
				Decal2.m_DecalOverrideAlpha = _DecalOverrideAlpha2;
				Decal2.m_DecalHueShiftEnabled = _DecalHueShiftEnabled2;
				Decal2.m_DecalHueShift = _DecalHueShift2;
				Decal2.m_DecalHueShiftSpeed = _DecalHueShiftSpeed2;
				Decal2.m_DecalDepth = _Decal2Depth;
				Decal2.m_DecalHueAngleStrength = _Decal2HueAngleStrength;
				Decal2.m_DecalChannelSeparationEnable = _Decal2ChannelSeparationEnable;
				Decal2.m_DecalChannelSeparation = _Decal2ChannelSeparation;
				Decal2.m_DecalChannelSeparationPremultiply = _Decal2ChannelSeparationPremultiply;
				Decal2.m_DecalChannelSeparationHue = _Decal2ChannelSeparationHue;
				Decal2.m_DecalChannelSeparationVertical = _Decal2ChannelSeparationVertical;
				Decal2.m_DecalChannelSeparationAngleStrength = _Decal2ChannelSeparationAngleStrength;
				Decal2.m_DecalOverrideAlphaMode = _Decal2OverrideAlphaMode;
				Decal2.Init(decalMask);
				
				#if defined(POI_AUDIOLINK)
				Decal2.m_AudioLinkDecalScaleBand = _AudioLinkDecal2ScaleBand;
				Decal2.m_AudioLinkDecalScale = _AudioLinkDecal2Scale;
				Decal2.m_AudioLinkDecalRotationBand = _AudioLinkDecal2RotationBand;
				Decal2.m_AudioLinkDecalRotation = _AudioLinkDecal2Rotation;
				Decal2.m_AudioLinkDecalAlphaBand = _AudioLinkDecal2AlphaBand;
				Decal2.m_AudioLinkDecalAlpha = _AudioLinkDecal2Alpha;
				Decal2.m_AudioLinkDecalEmissionBand = _AudioLinkDecal2EmissionBand;
				Decal2.m_AudioLinkDecalEmission = _AudioLinkDecal2Emission;
				Decal2.m_DecalRotationCTALBand = _DecalRotationCTALBand2;
				Decal2.m_DecalRotationCTALSpeed = _DecalRotationCTALSpeed2;
				Decal2.m_DecalRotationCTALType = _DecalRotationCTALType2;
				Decal2.m_AudioLinkDecalColorChord = _AudioLinkDecalCC2;
				Decal2.m_AudioLinkDecalSideBand = _AudioLinkDecal2SideBand;
				Decal2.m_AudioLinkDecalSideMin = _AudioLinkDecal2SideMin;
				Decal2.m_AudioLinkDecalSideMax = _AudioLinkDecal2SideMax;
				Decal2.m_AudioLinkDecalChannelSeparation = _AudioLinkDecal2ChannelSeparation;
				Decal2.m_AudioLinkDecalChannelSeparationBand = _AudioLinkDecal2ChannelSeparationBand;
				
				Decal2.InitAudiolink(poiMods);
				#endif
				if (!_Decal2VideoEnabled)
				{
					#if defined(PROP_DECALTEXTURE2) || !defined(OPTIMIZER_ENABLED)
					//ifex _Decal2ChannelSeparationEnable==0
					if (_Decal2ChannelSeparationEnable)
					{
						Decal2.SampleDecalChannelSeparation(_DecalTexture2, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					//ifex _Decal2ChannelSeparationEnable==1
					if (!_Decal2ChannelSeparationEnable)
					{
						Decal2.SampleDecal(_DecalTexture2, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					#else
					Decal2.SampleDecalNoTexture(poiMods, poiLight, poiMesh, poiCam);
					#endif
					Decal2.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
				}
				else
				{
					udonVideoAspectRatio = Decal2.GetVideoAspectRatio(_Udon_VideoTex_TexelSize.zw, _Decal2VideoAspectFix, _Decal2VideoFitToScale);
					if (_Decal2OnlyVideo)
					{
						if (udonVideoTexAvailable)
						{
							Decal2.m_DecalEmissionStrength += _Decal2VideoEmissionStrength;
							if (_Decal2UseDecalAlpha)
							{
								Decal2.SampleDecal(_DecalTexture2, poiMods, poiLight, poiMesh, poiCam);
								Decal2.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal2.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							Decal2.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
						}
					}
					else
					{
						Decal2.SampleDecal(_DecalTexture2, poiMods, poiLight, poiMesh, poiCam);
						if (udonVideoTexAvailable)
						{
							Decal2.m_DecalEmissionStrength += _Decal2VideoEmissionStrength;
							if (_Decal2UseDecalAlpha)
							{
								Decal2.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal2.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
						}
						Decal2.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
					}
				}
				#endif
				//endex
				
				//ifex _DecalEnabled3==0
				#ifdef DEPTH_OF_FIELD_COC_VIEW
				PoiDecal Decal3;
				PoiInitStruct(PoiDecal, Decal3)
				Decal3.m_DecalFaceMask = _Decal3FaceMask;
				Decal3.m_DecalMaskChannel = _Decal3MaskChannel;
				Decal3.m_DecalGlobalMask = _Decal3GlobalMask;
				Decal3.m_DecalGlobalMaskBlendType = _Decal3GlobalMaskBlendType;
				Decal3.m_DecalApplyGlobalMaskIndex = _Decal3ApplyGlobalMaskIndex;
				Decal3.m_DecalApplyGlobalMaskBlendType = _Decal3ApplyGlobalMaskBlendType;
				Decal3.m_DecalTexture_ST = _DecalTexture3_ST;
				Decal3.m_DecalTexturePan = _DecalTexture3Pan;
				Decal3.m_DecalTextureUV = _DecalTexture3UV;
				Decal3.m_DecalColor = _DecalColor3;
				Decal3.m_DecalColorThemeIndex = _DecalColor3ThemeIndex;
				Decal3.m_DecalTiled = _DecalTiled3;
				Decal3.m_DecalBlendType = _DecalBlendType3;
				Decal3.m_DecalRotation = _DecalRotation3;
				Decal3.m_DecalScale = _DecalScale3;
				Decal3.m_DecalSideOffset = _DecalSideOffset3;
				Decal3.m_DecalPosition = _DecalPosition3;
				Decal3.m_DecalRotationSpeed = _DecalRotationSpeed3;
				Decal3.m_DecalEmissionStrength = _DecalEmissionStrength3;
				Decal3.m_DecalBlendAlpha = _DecalBlendAlpha3;
				Decal3.m_DecalOverrideAlpha = _DecalOverrideAlpha3;
				Decal3.m_DecalHueShiftEnabled = _DecalHueShiftEnabled3;
				Decal3.m_DecalHueShift = _DecalHueShift3;
				Decal3.m_DecalHueShiftSpeed = _DecalHueShiftSpeed3;
				Decal3.m_DecalDepth = _Decal3Depth;
				Decal3.m_DecalHueAngleStrength = _Decal3HueAngleStrength;
				Decal3.m_DecalChannelSeparationEnable = _Decal3ChannelSeparationEnable;
				Decal3.m_DecalChannelSeparation = _Decal3ChannelSeparation;
				Decal3.m_DecalChannelSeparationPremultiply = _Decal3ChannelSeparationPremultiply;
				Decal3.m_DecalChannelSeparationHue = _Decal3ChannelSeparationHue;
				Decal3.m_DecalChannelSeparationVertical = _Decal3ChannelSeparationVertical;
				Decal3.m_DecalChannelSeparationAngleStrength = _Decal3ChannelSeparationAngleStrength;
				Decal3.m_DecalOverrideAlphaMode = _Decal3OverrideAlphaMode;
				Decal3.Init(decalMask);
				
				#if defined(POI_AUDIOLINK)
				Decal3.m_AudioLinkDecalScaleBand = _AudioLinkDecal3ScaleBand;
				Decal3.m_AudioLinkDecalScale = _AudioLinkDecal3Scale;
				Decal3.m_AudioLinkDecalRotationBand = _AudioLinkDecal3RotationBand;
				Decal3.m_AudioLinkDecalRotation = _AudioLinkDecal3Rotation;
				Decal3.m_AudioLinkDecalAlphaBand = _AudioLinkDecal3AlphaBand;
				Decal3.m_AudioLinkDecalAlpha = _AudioLinkDecal3Alpha;
				Decal3.m_AudioLinkDecalEmissionBand = _AudioLinkDecal3EmissionBand;
				Decal3.m_AudioLinkDecalEmission = _AudioLinkDecal3Emission;
				Decal3.m_DecalRotationCTALBand = _DecalRotationCTALBand3;
				Decal3.m_DecalRotationCTALSpeed = _DecalRotationCTALSpeed3;
				Decal3.m_DecalRotationCTALType = _DecalRotationCTALType3;
				Decal3.m_AudioLinkDecalColorChord = _AudioLinkDecalCC3;
				Decal3.m_AudioLinkDecalSideBand = _AudioLinkDecal3SideBand;
				Decal3.m_AudioLinkDecalSideMin = _AudioLinkDecal3SideMin;
				Decal3.m_AudioLinkDecalSideMax = _AudioLinkDecal3SideMax;
				Decal3.m_AudioLinkDecalChannelSeparation = _AudioLinkDecal3ChannelSeparation;
				Decal3.m_AudioLinkDecalChannelSeparationBand = _AudioLinkDecal3ChannelSeparationBand;
				
				Decal3.InitAudiolink(poiMods);
				#endif
				if (!_Decal3VideoEnabled)
				{
					#if defined(PROP_DECALTEXTURE3) || !defined(OPTIMIZER_ENABLED)
					//ifex _Decal3ChannelSeparationEnable==0
					if (_Decal3ChannelSeparationEnable)
					{
						Decal3.SampleDecalChannelSeparation(_DecalTexture3, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					//ifex _Decal3ChannelSeparationEnable==1
					if (!_Decal3ChannelSeparationEnable)
					{
						Decal3.SampleDecal(_DecalTexture3, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					#else
					Decal3.SampleDecalNoTexture(poiMods, poiLight, poiMesh, poiCam);
					#endif
					Decal3.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
				}
				else
				{
					udonVideoAspectRatio = Decal3.GetVideoAspectRatio(_Udon_VideoTex_TexelSize.zw, _Decal3VideoAspectFix, _Decal3VideoFitToScale);
					if (_Decal3OnlyVideo)
					{
						if (udonVideoTexAvailable)
						{
							Decal3.m_DecalEmissionStrength += _Decal3VideoEmissionStrength;
							if (_Decal3UseDecalAlpha)
							{
								Decal3.SampleDecal(_DecalTexture3, poiMods, poiLight, poiMesh, poiCam);
								Decal3.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal3.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							Decal3.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
						}
					}
					else
					{
						Decal3.SampleDecal(_DecalTexture3, poiMods, poiLight, poiMesh, poiCam);
						if (udonVideoTexAvailable)
						{
							Decal3.m_DecalEmissionStrength += _Decal3VideoEmissionStrength;
							if (_Decal3UseDecalAlpha)
							{
								Decal3.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal3.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
						}
						Decal3.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
					}
				}
				#endif
				//endex
				//if (alphaOverride)
				//{
				
				//poiFragData.baseColor = decalAlpha;
				//poiFragData.alpha *= decalAlpha;
				
				//}
				//poiFragData.baseColor = saturate(poiFragData.baseColor);
				
			}
			#endif
			
			//ifex _EnableDissolve==0
			#ifdef DISTORT
			void applyDissolve(inout PoiFragData poiFragData, in PoiMesh poiMesh, inout PoiMods poiMods, in PoiCam poiCam, in PoiLight poiLight)
			{
				#if defined(PROP_DISSOLVEMASK) || !defined(OPTIMIZER_ENABLED)
				float dissolveMask = POI2D_SAMPLER_PAN(_DissolveMask, _MainTex, poiUV(poiMesh.uv[_DissolveMaskUV], _DissolveMask_ST), _DissolveMaskPan).r;
				#else
				float dissolveMask = 1;
				#endif
				UNITY_BRANCH
				if (_DissolveUseVertexColors > 0)
				{
					// Vertex Color Imprecision hype
					dissolveMask = ceil(poiMesh.vertexColor[_DissolveUseVertexColors] * 100000) / 100000;
				}
				if (_DissolveMaskGlobalMask > 0)
				{
					dissolveMask = maskBlend(dissolveMask, poiMods.globalMask[_DissolveMaskGlobalMask - 1], _DissolveMaskGlobalMaskBlendType);
				}
				
				#if defined(PROP_DISSOLVETOTEXTURE) || !defined(OPTIMIZER_ENABLED)
				dissolveToTexture = POI2D_SAMPLER_PAN(_DissolveToTexture, _MainTex, poiUV(poiMesh.uv[_DissolveToTextureUV], _DissolveToTexture_ST), _DissolveToTexturePan) * float4(poiThemeColor(poiMods, _DissolveTextureColor.rgb, _DissolveTextureColorThemeIndex), _DissolveTextureColor.a);
				#else
				dissolveToTexture = _DissolveTextureColor;
				#endif
				
				#if defined(PROP_DISSOLVENOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
				float dissolveNoiseTexture = POI2D_SAMPLER_PAN(_DissolveNoiseTexture, _MainTex, poiUV(poiMesh.uv[_DissolveNoiseTextureUV], _DissolveNoiseTexture_ST), _DissolveNoiseTexturePan).r;
				#else
				float dissolveNoiseTexture = 1;
				#endif
				
				float da = _DissolveAlpha
				+ _DissolveAlpha0
				+ _DissolveAlpha1
				+ _DissolveAlpha2
				+ _DissolveAlpha3
				+ _DissolveAlpha4
				+ _DissolveAlpha5
				+ _DissolveAlpha6
				+ _DissolveAlpha7
				+ _DissolveAlpha8
				+ _DissolveAlpha9;
				float dds = _DissolveDetailStrength;
				
				if (_UVTileDissolveEnabled)
				{
					float2 udim = floor(poiMesh.uv[(int)_UVTileDissolveUV]);
					
					float4 xMask = float4((udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					da += (udim.y >= 0 && udim.y < 1) * dot(float4(_UVTileDissolveAlpha_Row0_0, _UVTileDissolveAlpha_Row0_1, _UVTileDissolveAlpha_Row0_2, _UVTileDissolveAlpha_Row0_3), xMask);
					da += (udim.y >= 1 && udim.y < 2) * dot(float4(_UVTileDissolveAlpha_Row1_0, _UVTileDissolveAlpha_Row1_1, _UVTileDissolveAlpha_Row1_2, _UVTileDissolveAlpha_Row1_3), xMask);
					da += (udim.y >= 2 && udim.y < 3) * dot(float4(_UVTileDissolveAlpha_Row2_0, _UVTileDissolveAlpha_Row2_1, _UVTileDissolveAlpha_Row2_2, _UVTileDissolveAlpha_Row2_3), xMask);
					da += (udim.y >= 3 && udim.y < 4) * dot(float4(_UVTileDissolveAlpha_Row3_0, _UVTileDissolveAlpha_Row3_1, _UVTileDissolveAlpha_Row3_2, _UVTileDissolveAlpha_Row3_3), xMask);
				}
				
				#ifdef POI_AUDIOLINK
				UNITY_BRANCH
				if (_EnableDissolveAudioLink && poiMods.audioLinkAvailable)
				{
					da += lerp(_AudioLinkDissolveAlpha.x, _AudioLinkDissolveAlpha.y, poiMods.audioLink[_AudioLinkDissolveAlphaBand]);
					dds += lerp(_AudioLinkDissolveDetail.x, _AudioLinkDissolveDetail.y, poiMods.audioLink[_AudioLinkDissolveDetailBand]);
				}
				#endif
				
				da = saturate(da);
				dds = saturate(dds);
				
				if (_DissolveMaskInvert)
				{
					dissolveMask = 1 - dissolveMask;
				}
				#if defined(PROP_DISSOLVEDETAILNOISE) || !defined(OPTIMIZER_ENABLED)
				float dissolveDetailNoise = POI2D_SAMPLER_PAN(_DissolveDetailNoise, _MainTex, poiUV(poiMesh.uv[_DissolveDetailNoiseUV], _DissolveDetailNoise_ST), _DissolveDetailNoisePan);
				#else
				float dissolveDetailNoise = 0;
				#endif
				if (_DissolveInvertNoise)
				{
					dissolveNoiseTexture = 1 - dissolveNoiseTexture;
				}
				if (_DissolveInvertDetailNoise)
				{
					dissolveDetailNoise = 1 - dissolveDetailNoise;
				}
				if (_ContinuousDissolve != 0)
				{
					da = sin(_Time.x * _ContinuousDissolve) * .5 + .5;
				}
				da *= dissolveMask;
				dissolveAlpha = da;
				edgeAlpha = 0;
				
				[flatten]
				switch(_DissolveType)
				{
					default: // Basic (case 1)
					
					{
						da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						dissolveAlpha = da;
						//Adjust detail strength to avoid artifacts
						dds *= smoothstep(1, 0.99, da) * lerp(1, smoothstep(0, lerp(0.01, 0.1, dds), da), _DissolveDetailEdgeSmoothing);
						float noise = saturate(dissolveNoiseTexture - dissolveDetailNoise * dds);
						
						noise = saturate(noise * 0.998 + 0.001);
						dissolveAlpha = dissolveAlpha >= noise;
						edgeAlpha = remapClamped(da + _DissolveEdgeWidth, da, noise) * (1 - dissolveAlpha);
						break;
					}
					case 2: // Point to Point
					
					{
						float3 direction;
						float3 currentPos;
						float distanceTo = 0;
						direction = normalize(_DissolveEndPoint - _DissolveStartPoint);
						currentPos = lerp(_DissolveStartPoint, _DissolveEndPoint, dissolveAlpha);
						
						UNITY_BRANCH
						if (_DissolveP2PWorldLocal != 1)
						{
							float3 pos = _DissolveP2PWorldLocal == 0 ? poiMesh.localPos.rgb : poiMesh.vertexColor.rgb;
							distanceTo = dot(pos - currentPos, direction) - dissolveDetailNoise * dds;
							edgeAlpha = smoothstep(_DissolveP2PEdgeLength + .00001, 0, distanceTo);
							dissolveAlpha = step(distanceTo, 0);
							edgeAlpha *= 1 - dissolveAlpha;
						}
						else
						{
							distanceTo = dot(poiMesh.worldPos - currentPos, direction) - dissolveDetailNoise * dds;
							edgeAlpha = smoothstep(_DissolveP2PEdgeLength + .00001, 0, distanceTo);
							dissolveAlpha = (distanceTo < 0) ? 1 : 0;
							edgeAlpha *= 1 - dissolveAlpha;
						}
						
						if (_DissolveP2PClamp)
						{
							dissolveAlpha = saturate(dissolveAlpha * smoothstep(0, 0.01, da) + smoothstep(0.99, 1, da));
							edgeAlpha *= smoothstep(0, 0.01, da);
						}
						
						break;
					}
					case 3: // Spherical
					
					{
						if (_SphericalDissolveInvert)
						{
							da = remap(da, 1, 0, -_DissolveEdgeWidth, 1);
						}
						else
						{
							da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						}
						
						dissolveAlpha = da;
						dds *= smoothstep(0, 0.2 * dds + 0.01, dissolveAlpha) * lerp(1, smoothstep(1, 1 - 0.2 * dds - 0.01, dissolveAlpha), _DissolveDetailEdgeSmoothing);
						float currentDistance = lerp(0, _SphericalDissolveRadius, dissolveAlpha);
						float fragDistance = distance(_SphericalDissolveCenter, poiMesh.localPos.xyz);
						float normalizedDistance;
						normalizedDistance = (fragDistance - currentDistance) / (_SphericalDissolveRadius + 0.0001) - dissolveDetailNoise * dds;
						
						if (_SphericalDissolveInvert)
						{
							dissolveAlpha = (normalizedDistance > 0) ? 1 : 0;
							edgeAlpha = smoothstep(_DissolveEdgeWidth + .00001, 0, -normalizedDistance);
						}
						else
						{
							dissolveAlpha = (normalizedDistance < 0) ? 1 : 0;
							edgeAlpha = smoothstep(_DissolveEdgeWidth + .00001, 0, normalizedDistance);
						}
						
						if (_SphericalDissolveClamp)
						{
							da = lerp(da, 1 - da, _SphericalDissolveInvert);
							dissolveAlpha = saturate(dissolveAlpha * smoothstep(0, 0.01, da) + smoothstep(0.99, 1, da));
							edgeAlpha *= smoothstep(0, 0.01, da);
						}
						
						break;
					}
					case 4: // CenterOut
					
					{
						float ramp = 0.5;
						float noise;
						
						[flatten]
						switch(_CenterOutDissolveMode)
						{
							case 1: // View Direction
							
							{
								ramp = saturate(lerp(poiLight.vertexNDotV, poiLight.nDotV, _CenterOutDissolveNormals));
								break;
							}
							case 2: // Custom Direction
							
							{
								ramp = dot(normalize(_CenterOutDissolveDirection), lerp(poiMesh.normals[0], poiMesh.normals[1], _CenterOutDissolveNormals));
								ramp = saturate(ramp * .5 + 0.5);
								break;
							}
							case 3: // Light Direction
							
							{
								ramp = lerp(poiLight.vertexNDotL, poiLight.nDotL, _CenterOutDissolveNormals);
								ramp = saturate(ramp * .5 + 0.5);
								break;
							}
						}
						
						if (_CenterOutDissolvePower != 1)
						{
							ramp = pow(ramp, _CenterOutDissolvePower);
						}
						
						if (!_CenterOutDissolveInvert)
						{
							ramp = 1 - ramp;
						}
						
						da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						dissolveAlpha = da;
						//Adjust detail strength to avoid artifacts
						dds *= smoothstep(1, 0.99, da) * lerp(1, smoothstep(0, lerp(0.01, 0.1, dds), da), _DissolveDetailEdgeSmoothing);
						
						noise = saturate(ramp - dissolveDetailNoise * dds);
						noise = saturate(noise * 0.998 + 0.001);
						dissolveAlpha = dissolveAlpha >= noise;
						edgeAlpha = remapClamped(da + _DissolveEdgeWidth, da, noise) * (1 - dissolveAlpha);
						break;
					}
				}
				
				#ifndef POI_SHADOW
				UNITY_BRANCH
				if (_DissolveHueShiftEnabled)
				{
					dissolveToTexture.rgb = hueShift(dissolveToTexture.rgb, _DissolveHueShift + _Time.x * _DissolveHueShiftSpeed);
				}
				#endif
				
				poiFragData.alpha = lerp(poiFragData.alpha, dissolveToTexture.a, dissolveAlpha * .999999);
				
				#if !defined(POI_PASS_OUTLINE) && !defined(UNITY_PASS_SHADOWCASTER)
				poiFragData.baseColor = lerp(poiFragData.baseColor, dissolveToTexture.rgb, dissolveAlpha * .999999);
				
				if (_DissolveApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _DissolveApplyGlobalMaskIndex - 1, _DissolveApplyGlobalMaskBlendType, dissolveAlpha * .999999);
				}
				if (_DissolveInverseApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _DissolveInverseApplyGlobalMaskIndex - 1, _DissolveInverseApplyGlobalMaskBlendType, 1-(dissolveAlpha * .999999));
				}
				UNITY_BRANCH
				if (_DissolveEdgeWidth || (_DissolveType == 2 && _DissolveP2PEdgeLength != 0))
				{
					edgeColor = tex2D(_DissolveEdgeGradient, poiUV(float2(edgeAlpha, edgeAlpha), _DissolveEdgeGradient_ST)) * float4(poiThemeColor(poiMods, _DissolveEdgeColor.rgb, _DissolveEdgeColorThemeIndex), _DissolveEdgeColor.a);
					#ifndef POI_SHADOW
					UNITY_BRANCH
					if (_DissolveEdgeHueShiftEnabled)
					{
						edgeColor.rgb = hueShift(edgeColor.rgb, _DissolveEdgeHueShift + _Time.x * _DissolveEdgeHueShiftSpeed);
					}
					#endif
					poiFragData.baseColor = lerp(poiFragData.baseColor, edgeColor.rgb, smoothstep(0, 1 - _DissolveEdgeHardness * .99999999999, edgeAlpha));
				}
				
				poiFragData.emission += lerp(0, dissolveToTexture * _DissolveToEmissionStrength, dissolveAlpha) + lerp(0, edgeColor.rgb * _DissolveEdgeEmission, smoothstep(0, 1 - _DissolveEdgeHardness * .99999999999, edgeAlpha));
				#endif
			}
			#endif
			//endex
			
			//ifex _EnableAniso==0
			#ifdef POI_ANISOTROPICS
			/*
			float D_GGX_Anisotropic(float at, float ab, float TdotH, float BdotH, float NdotH)
			{
				// Burley 2012, "Physically-Based Shading at Disney"
				
				// The values at and ab are perceptualRoughness^2, a2 is therefore perceptualRoughness^4
				// The dot product below computes perceptualRoughness^8. We cannot fit in fp16 without clamping
				// the roughness to too high values so we perform the dot product and the division in fp32
				float a2 = at * ab;
				float3 d = float3(ab * TdotH, at * BdotH, a2 * NdotH);
				float d2 = dot(d, d);
				float b2 = a2 / d2;
				return a2 * b2 * b2 * (1.0 / UNITY_PI);
			}
			
			//-------------------------------------GGX Anisotropic visibility function
			float V_SmithGGXCorrelated_Anisotropic(float at, float ab, float TdotV, float BdotV, float TdotL, float BdotL, float NdotV, float NdotL)
			{
				// Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"
				float lambdaV = NdotL * length(float3(at * TdotV, ab * BdotV, NdotV));
				float lambdaL = NdotV * length(float3(at * TdotL, ab * BdotL, NdotL));
				return 0.5 / (lambdaV + lambdaL);
			}
			*/
			
			float calculateAnisotropics(float3 binormal, float offset, float3 normal, float3 viewDir, float3 LightDirection, float exponent, float strength, float shadowMask)
			{
				float3 ShiftedTangent = normalize(binormal + offset * normal);
				float3 H = normalize(LightDirection + viewDir);
				float dotTH = dot(ShiftedTangent, H);
				float sinTH = sqrt(1.0 - dotTH * dotTH);
				float dirAtten = smoothstep(-1.0, 0.0, dotTH);
				return saturate(dirAtten * pow(sinTH, exponent) * strength) * shadowMask;
			}
			
			float aaEdgeFeather(float value, float edge, float feather)
			{
				float edgeMin = saturate(edge - feather * 0.5);
				float edgeMax = saturate(edge + feather * 0.5);
				return saturate((value - edgeMin) / saturate(edgeMax - edgeMin + fwidth(value)));
			}
			
			void applyAnisotropics(inout PoiFragData poiFragData, inout PoiLight poiLight, in PoiCam poiCam, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				#if defined(PROP_ANISOCOLORMAP) || !defined(OPTIMIZER_ENABLED)
				float4 specMap = POI2D_SAMPLER_PAN(_AnisoColorMap, _MainTex, poiUV(poiMesh.uv[_AnisoColorMapUV], _AnisoColorMap_ST), _AnisoColorMapPan);
				#else
				float4 specMap = float4(1, 1, 1, 0);
				#endif
				
				float shadowMask = lerp(1, poiMax(poiLight.rampedLightMap), _AnisoHideInShadow);
				#ifdef POI_PASS_ADD
				shadowMask *= poiLight.additiveShadow;
				#endif
				
				if (_AnisoGlobalMask > 0)
				{
					shadowMask = customBlend(shadowMask, poiMods.globalMask[_AnisoGlobalMask-1], _AnisoGlobalMaskBlendType);
				}
				
				float spec0 = calculateAnisotropics(lerp(poiMesh.binormal[1], poiMesh.tangent[1], _Aniso0SwitchDirection), _Aniso0Offset +_Aniso0OffsetMapStrength * specMap.a, poiMesh.normals[1], poiCam.viewDir, poiLight.direction, _Aniso0Power * 1000, _Aniso0Strength, shadowMask);
				float spec1 = calculateAnisotropics(lerp(poiMesh.binormal[1], poiMesh.tangent[1], _Aniso1SwitchDirection), _Aniso1Offset +_Aniso1OffsetMapStrength * specMap.a, poiMesh.normals[1], poiCam.viewDir, poiLight.direction, _Aniso1Power * 1000, _Aniso1Strength, shadowMask);
				
				spec0 = lerp(spec0, aaEdgeFeather(spec0, _Aniso0Edge, _Aniso0Blur), _Aniso0ToonMode);
				spec1 = lerp(spec1, aaEdgeFeather(spec1, _Aniso1Edge, _Aniso1Blur), _Aniso1ToonMode);
				
				float3 spec0Color = specMap.rgb * poiThemeColor(poiMods, _Aniso0Tint.rgb, _Aniso0TintIndex);
				float3 spec1Color = specMap.rgb * poiThemeColor(poiMods, _Aniso1Tint.rgb, _Aniso1TintIndex);
				
				float3 finalSpec = saturate(saturate(spec0 * spec0Color) + saturate(spec1 * spec1Color)) * lerp(1, poiFragData.baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), poiLight.directColor, _AnisoUseLightColor);
				float3 baseColor = poiFragData.baseColor;
				
				poiFragData.baseColor = lerp(poiFragData.baseColor, spec1Color * lerp(1, baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), poiLight.directColor, _AnisoUseLightColor), _AnisoReplace * spec1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, spec0Color * lerp(1, baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), poiLight.directColor, _AnisoUseLightColor), _AnisoReplace * spec0);
				poiLight.finalLightAdd += max(0, finalSpec * _AnisoAdd);
				
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					for (int index = 0; index < 4; index++)
					{
						float vSpec0 = calculateAnisotropics(lerp(poiMesh.binormal[1], poiMesh.tangent[1], _Aniso0SwitchDirection), _Aniso0Offset +_Aniso0OffsetMapStrength * specMap.a, poiMesh.normals[1], poiCam.viewDir, poiLight.vDirection[index], _Aniso0Power * 1000, _Aniso0Strength, poiLight.vSaturatedDotNL[index]);
						float vSpec1 = calculateAnisotropics(lerp(poiMesh.binormal[1], poiMesh.tangent[1], _Aniso1SwitchDirection), _Aniso1Offset +_Aniso1OffsetMapStrength * specMap.a, poiMesh.normals[1], poiCam.viewDir, poiLight.vDirection[index], _Aniso1Power * 1000, _Aniso1Strength, poiLight.vSaturatedDotNL[index]);
						
						vSpec0 = lerp(vSpec0, aaEdgeFeather(vSpec0, _Aniso0Edge, _Aniso0Blur), _Aniso0ToonMode);
						vSpec1 = lerp(vSpec1, aaEdgeFeather(vSpec1, _Aniso1Edge, _Aniso1Blur), _Aniso1ToonMode);
						
						float3 vSpec0Color = spec0Color;
						float3 vSpec1Color = spec1Color;
						
						poiLight.finalLightAdd += max(0, saturate(saturate(vSpec0 * vSpec0Color) + saturate(vSpec1 * vSpec1Color)) * lerp(1, poiFragData.baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.vColor[index], float3(0.299, 0.587, 0.114)), poiLight.vColor[index], _AnisoUseLightColor) * _AnisoAdd);
						
						poiFragData.baseColor = lerp(poiFragData.baseColor, vSpec1Color * lerp(1, baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.vColor[index], float3(0.299, 0.587, 0.114)), poiLight.vColor[index], _AnisoUseLightColor), _AnisoReplace * vSpec1);
						poiFragData.baseColor = lerp(poiFragData.baseColor, vSpec0Color * lerp(1, baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.vColor[index], float3(0.299, 0.587, 0.114)), poiLight.vColor[index], _AnisoUseLightColor), _AnisoReplace * vSpec0);
					}
					#endif
				}
			}
			#endif
			//endex
			
			//ifex _MatcapEnable==0 && _Matcap2Enable==0 && _Matcap3Enable==0 && _Matcap4Enable==0
			void blendMatcap(inout PoiLight poiLight, inout PoiFragData poiFragData, in PoiMods poiMods, float add, float lightAdd, float multiply, float replace, float mixed, float screen, float4 matcapColor, float matcapMask, float emissionStrength, float matcapLightMask, uint globalMaskIndex, float globalMaskBlendType, in MatcapAudioLinkData matcapALD)
			{
				if (matcapLightMask)
				{
					matcapMask *= lerp(1, poiLight.rampedLightMap, matcapLightMask);
				}
				if (globalMaskIndex > 0)
				{
					matcapMask = maskBlend(matcapMask, poiMods.globalMask[globalMaskIndex - 1], globalMaskBlendType);
				}
				
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapColor.a = saturate(matcapColor.a + lerp(matcapALD.matcapALAlphaAdd.x, matcapALD.matcapALAlphaAdd.y, poiMods.audioLink[matcapALD.matcapALAlphaAddBand]));
					emissionStrength += lerp(matcapALD.matcapALEmissionAdd.x, matcapALD.matcapALEmissionAdd.y, poiMods.audioLink[matcapALD.matcapALEmissionAddBand]);
				}
				#endif
				
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, matcapColor.rgb, replace * matcapMask * matcapColor.a * .999999);
				poiFragData.baseColor.rgb *= lerp(1, matcapColor.rgb, multiply * matcapMask * matcapColor.a);
				poiFragData.baseColor.rgb += matcapColor.rgb * add * matcapMask * matcapColor.a;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, blendScreen(poiFragData.baseColor.rgb, matcapColor.rgb), screen * matcapMask * matcapColor.a);
				#ifdef POI_PASS_BASE
				poiLight.finalLightAdd += matcapColor.rgb * lightAdd * matcapMask * matcapColor.a;
				#endif
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, poiFragData.baseColor.rgb + poiFragData.baseColor.rgb * matcapColor.rgb, mixed * matcapMask * matcapColor.a);
				poiFragData.emission += matcapColor.rgb * emissionStrength * matcapMask * matcapColor.a;
			}
			
			void getMatcapUV(inout float2 matcapUV, in float2 matcapPan, in float matcapUVMode, in float matcapUVToBlend, in float2 matCapBlendUV, in float matcapRotation, in float matcapBorder, in float3 normal, in PoiCam poiCam, in PoiLight poiLight, in PoiMesh poiMesh, in float matcapNormalStrength, in MatcapAudioLinkData matcapALD)
			{
				switch(matcapUVMode)
				{
					// Normal / UTS
					case 0:
					{
						float3 viewNormal = (mul(UNITY_MATRIX_V, float4(normal, 0))).rgb;
						float3 NormalBlend_MatCapUV_Detail = viewNormal.rgb * float3(-1, -1, 1);
						float3 NormalBlend_MatCapUV_Base = (mul(UNITY_MATRIX_V, float4(poiCam.viewDir, 0)).rgb * float3(-1, -1, 1)) + float3(0, 0, 1);
						float3 noSknewViewNormal = NormalBlend_MatCapUV_Base * dot(NormalBlend_MatCapUV_Base, NormalBlend_MatCapUV_Detail) / NormalBlend_MatCapUV_Base.b - NormalBlend_MatCapUV_Detail;
						
						matcapUV = noSknewViewNormal.rg * matcapBorder + 0.5;
						break;
					}
					// Top Pinch
					case 1:
					{
						float3 worldViewUp = normalize(float3(0, 1, 0) - poiCam.viewDir * dot(poiCam.viewDir, float3(0, 1, 0)));
						float3 worldViewRight = normalize(cross(poiCam.viewDir, worldViewUp));
						matcapUV = float2(dot(worldViewRight, normal), dot(worldViewUp, normal)) * matcapBorder + 0.5;
						break;
					}
					// Custom Double Sided
					case 2:
					{
						float3 reflection = reflect(-poiCam.viewDir, normal);
						float2 uv = float2(dot(reflection, float3(1, 0, 0)), dot(reflection, float3(0, 1, 0)));
						matcapUV = uv * matcapBorder + 0.5;
						break;
					}
					// Gradient
					case 3:
					{
						matcapUV = 1 - abs(dot(normal, poiCam.viewDir));
						#ifdef POI_AUDIOLINK
						if (matcapALD.matcapALEnabled)
						{
							matcapUV += AudioLinkGetChronoTime(matcapALD.matcapALChronoPanType, matcapALD.matcapALChronoPanBand) * matcapALD.matcapALChronoPanSpeed;
						}
						#endif
						break;
					}
				}
				matcapUV = lerp(matcapUV, poiMesh.uv[matcapUVToBlend], matCapBlendUV);
				matcapUV += matcapPan * _Time.x;
				matcapUV = RotateUV(matcapUV, matcapRotation * PI, float2(.5, .5), 1.0f);
				
				if (IsInMirror() && matcapUVMode != 3)
				{
					matcapUV.x = 1 - matcapUV.x;
				}
			}
			
			//endex
			//ifex _MatcapEnable==0 && _Matcap2Enable==0 && _Matcap3Enable==0 && _Matcap4Enable==0
			#if defined(POI_MATCAP0) || defined(COLOR_GRADING_HDR_3D) || defined(POI_MATCAP2) || defined(POI_MATCAP3)
			void applyMatcap(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, inout PoiLight poiLight, in PoiMods poiMods)
			{
				float4 matcap = 0;
				float matcapMask = 0;
				float4 matcap2 = 0;
				float matcap2Mask = 0;
				float4 matcap3 = 0;
				float matcap3Mask = 0;
				float4 matcap4 = 0;
				float matcap4Mask = 0;
				float2 matcapUV = 0;
				float matcapIntensity;
				struct MatcapAudioLinkData matcapALD;
				//endex
				
				//ifex _MatcapEnable==0
				// Matcap 1
				#ifdef POI_MATCAP0
				matcapALD.matcapALEnabled = _Matcap0ALEnabled;
				matcapALD.matcapALAlphaAddBand = _Matcap0ALAlphaAddBand;
				matcapALD.matcapALAlphaAdd = _Matcap0ALAlphaAdd;
				matcapALD.matcapALEmissionAddBand = _Matcap0ALEmissionAddBand;
				matcapALD.matcapALEmissionAdd = _Matcap0ALEmissionAdd;
				matcapALD.matcapALIntensityAddBand = _Matcap0ALIntensityAddBand;
				matcapALD.matcapALIntensityAdd = _Matcap0ALIntensityAdd;
				matcapALD.matcapALChronoPanType = _Matcap0ALChronoPanType;
				matcapALD.matcapALChronoPanBand = _Matcap0ALChronoPanBand;
				matcapALD.matcapALChronoPanSpeed = _Matcap0ALChronoPanSpeed;
				
				float3 normal0 = lerp(poiMesh.normals[0], poiMesh.normals[1], _MatcapNormal);
				#ifdef POI_MATCAP0_CUSTOM_NORMAL
				#if defined(PROP_MATCAP0NORMALMAP) || !defined(OPTIMIZER_ENABLED)
				normal0 = calculateNormal(poiMesh.normals[_MatcapNormal], poiMesh, _Matcap0NormalMap, _Matcap0NormalMap_ST, _Matcap0NormalMapPan, _Matcap0NormalMapUV, _Matcap0NormalMapScale);
				#endif
				#endif
				
				#if defined(PROP_MATCAP) || !defined(OPTIMIZER_ENABLED)
				getMatcapUV(matcapUV, _MatcapPan.xy, _MatcapUVMode, _MatcapUVToBlend, _MatCapBlendUV1.xy, _MatcapRotation, _MatcapBorder, normal0, poiCam, poiLight, poiMesh, _MatcapNormal, matcapALD);
				if (_MatcapSmoothnessEnabled)
				{
					float mipCount0 = 9;
					if (_Matcap_TexelSize.z == 8192) mipCount0 = 13;
					if (_Matcap_TexelSize.z == 4096) mipCount0 = 12;
					if (_Matcap_TexelSize.z == 2048) mipCount0 = 11;
					if (_Matcap_TexelSize.z == 1024) mipCount0 = 10;
					if (_Matcap_TexelSize.z == 512) mipCount0 = 9;
					if (_Matcap_TexelSize.z == 256) mipCount0 = 8;
					if (_Matcap_TexelSize.z == 128) mipCount0 = 7;
					if (_Matcap_TexelSize.z == 64) mipCount0 = 6;
					if (_Matcap_TexelSize.z == 32) mipCount0 = 5;
					
					float matcapSmoothness = _MatcapSmoothness;
					
					if (_MatcapMaskSmoothnessApply)
					{
						#if defined(PROP_MATCAPMASK) || !defined(OPTIMIZER_ENABLED)
						matcapSmoothness *= POI2D_SAMPLER_PAN(_MatcapMask, _MainTex, poiUV(poiMesh.uv[_MatcapMaskUV], _MatcapMask_ST), _MatcapMaskPan)[_MatcapMaskSmoothnessChannel];
						#endif
					}
					matcapSmoothness = (1 - matcapSmoothness) * mipCount0;
					matcap = UNITY_SAMPLE_TEX2D_SAMPLER_LOD(_Matcap, _trilinear_repeat, TRANSFORM_TEX(matcapUV, _Matcap), matcapSmoothness) * float4(poiThemeColor(poiMods, _MatcapColor.rgb, _MatcapColorThemeIndex), _MatcapColor.a);
				}
				else
				{
					matcap = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap)) * float4(poiThemeColor(poiMods, _MatcapColor.rgb, _MatcapColorThemeIndex), _MatcapColor.a);
				}
				#else
				matcap = float4(poiThemeColor(poiMods, _MatcapColor.rgb, _MatcapColorThemeIndex), _MatcapColor.a);
				#endif
				
				matcapIntensity = _MatcapIntensity;
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapIntensity += lerp(matcapALD.matcapALIntensityAdd.x, matcapALD.matcapALIntensityAdd.y, poiMods.audioLink[matcapALD.matcapALIntensityAddBand]);
					matcapIntensity = max(0, matcapIntensity);
				}
				#endif
				matcap.rgb *= matcapIntensity;
				matcap.rgb = lerp(matcap.rgb, matcap.rgb * poiFragData.baseColor.rgb, _MatcapBaseColorMix);
				
				#if defined(PROP_MATCAPMASK) || !defined(OPTIMIZER_ENABLED)
				matcapMask = POI2D_SAMPLER_PAN(_MatcapMask, _MainTex, poiUV(poiMesh.uv[_MatcapMaskUV], _MatcapMask_ST), _MatcapMaskPan)[_MatcapMaskChannel];
				#else
				matcapMask = 1;
				#endif
				
				if (_MatcapMaskInvert)
				{
					matcapMask = 1 - matcapMask;
				}
				
				#ifdef TPS_Penetrator
				if (_MatcapTPSDepthEnabled)
				{
					matcapMask = lerp(0, matcapMask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _MatcapTPSMaskStrength);
				}
				#endif
				
				poiFragData.alpha *= lerp(1, matcap.a, matcapMask * _MatcapAlphaOverride);
				
				//UNITY_BRANCH
				if (_MatcapHueShiftEnabled)
				{
					matcap.rgb = hueShift(matcap.rgb, _MatcapHueShift + _Time.x * _MatcapHueShiftSpeed);
				}
				
				if (_MatcapApplyToAlphaEnabled)
				{
					float matcapAlphaApplyValue = dot(matcap.rgb, float3(0.299, 0.587, 0.114)); // Greyscale
					if (_MatcapApplyToAlphaSourceBlend == 1) // Max
					
					{
						matcapAlphaApplyValue = poiMax(matcap.rgb);
					}
					if (_MatcapApplyToAlphaBlendType == 0) // Add
					
					{
						poiFragData.alpha += lerp(0, matcapAlphaApplyValue, _MatcapApplyToAlphaBlending);
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
					if (_MatcapApplyToAlphaBlendType == 1) // Multiply
					
					{
						poiFragData.alpha *= lerp(1, matcapAlphaApplyValue, _MatcapApplyToAlphaBlending);
					}
				}
				
				blendMatcap(poiLight, poiFragData, poiMods, _MatcapAdd, _MatcapAddToLight, _MatcapMultiply, _MatcapReplace, _MatcapMixed, _MatcapScreen, matcap, matcapMask, _MatcapEmissionStrength, _MatcapLightMask, _MatcapMaskGlobalMask, _MatcapMaskGlobalMaskBlendType, matcapALD);
				#endif
				//endex
				//ifex _Matcap2Enable==0
				// Matcap 2
				#ifdef COLOR_GRADING_HDR_3D
				matcapALD.matcapALEnabled = _Matcap1ALEnabled;
				matcapALD.matcapALAlphaAddBand = _Matcap1ALAlphaAddBand;
				matcapALD.matcapALAlphaAdd = _Matcap1ALAlphaAdd;
				matcapALD.matcapALEmissionAddBand = _Matcap1ALEmissionAddBand;
				matcapALD.matcapALEmissionAdd = _Matcap1ALEmissionAdd;
				matcapALD.matcapALIntensityAddBand = _Matcap1ALIntensityAddBand;
				matcapALD.matcapALIntensityAdd = _Matcap1ALIntensityAdd;
				matcapALD.matcapALChronoPanType = _Matcap1ALChronoPanType;
				matcapALD.matcapALChronoPanBand = _Matcap1ALChronoPanBand;
				matcapALD.matcapALChronoPanSpeed = _Matcap1ALChronoPanSpeed;
				
				float3 normal1 = lerp(poiMesh.normals[0], poiMesh.normals[1], _Matcap2Normal);
				#ifdef POI_MATCAP1_CUSTOM_NORMAL
				#if defined(PROP_MATCAP1NORMALMAP) || !defined(OPTIMIZER_ENABLED)
				normal1 = calculateNormal(poiMesh.normals[_Matcap2Normal], poiMesh, _Matcap1NormalMap, _Matcap1NormalMap_ST, _Matcap1NormalMapPan, _Matcap1NormalMapUV, _Matcap1NormalMapScale);
				#endif
				#endif
				
				#if defined(PROP_MATCAP2) || !defined(OPTIMIZER_ENABLED)
				getMatcapUV(matcapUV, _Matcap2Pan.xy, _Matcap2UVMode, _Matcap2UVToBlend, _MatCap2ndBlendUV1.xy, _Matcap2Rotation, _Matcap2Border, normal1, poiCam, poiLight, poiMesh, _Matcap2Normal, matcapALD);
				if (_Matcap2SmoothnessEnabled)
				{
					float mipCount2 = 9;
					if (_Matcap2_TexelSize.z == 8192) mipCount2 = 13;
					if (_Matcap2_TexelSize.z == 4096) mipCount2 = 12;
					if (_Matcap2_TexelSize.z == 2048) mipCount2 = 11;
					if (_Matcap2_TexelSize.z == 1024) mipCount2 = 10;
					if (_Matcap2_TexelSize.z == 512) mipCount2 = 9;
					if (_Matcap2_TexelSize.z == 256) mipCount2 = 8;
					if (_Matcap2_TexelSize.z == 128) mipCount2 = 7;
					if (_Matcap2_TexelSize.z == 64) mipCount2 = 6;
					if (_Matcap2_TexelSize.z == 32) mipCount2 = 5;
					
					float matcap2Smoothness = _Matcap2Smoothness;
					
					if (_Matcap2MaskSmoothnessApply)
					{
						#if defined(PROP_MATCAP2MASK) || !defined(OPTIMIZER_ENABLED)
						matcap2Smoothness *= POI2D_SAMPLER_PAN(_Matcap2Mask, _MainTex, poiUV(poiMesh.uv[_Matcap2MaskUV], _Matcap2Mask_ST), _Matcap2MaskPan)[_Matcap2MaskSmoothnessChannel];
						#endif
					}
					matcap2Smoothness = (1 - matcap2Smoothness) * mipCount2;
					matcap2 = UNITY_SAMPLE_TEX2D_SAMPLER_LOD(_Matcap2, _trilinear_repeat, TRANSFORM_TEX(matcapUV, _Matcap2), matcap2Smoothness) * float4(poiThemeColor(poiMods, _Matcap2Color.rgb, _Matcap2ColorThemeIndex), _Matcap2Color.a);
				}
				else
				{
					matcap2 = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap2, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap2)) * float4(poiThemeColor(poiMods, _Matcap2Color.rgb, _Matcap2ColorThemeIndex), _Matcap2Color.a);
				}
				#else
				matcap2 = float4(poiThemeColor(poiMods, _Matcap2Color.rgb, _Matcap2ColorThemeIndex), _Matcap2Color.a);
				#endif
				
				matcapIntensity = _Matcap2Intensity;
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapIntensity += lerp(matcapALD.matcapALIntensityAdd.x, matcapALD.matcapALIntensityAdd.y, poiMods.audioLink[matcapALD.matcapALIntensityAddBand]);
					matcapIntensity = max(0, matcapIntensity);
				}
				#endif
				matcap2.rgb *= matcapIntensity;
				matcap2.rgb = lerp(matcap2.rgb, matcap2.rgb * poiFragData.baseColor.rgb, _Matcap2BaseColorMix);
				
				#if defined(PROP_MATCAP2MASK) || !defined(OPTIMIZER_ENABLED)
				matcap2Mask = POI2D_SAMPLER_PAN(_Matcap2Mask, _MainTex, poiUV(poiMesh.uv[_Matcap2MaskUV], _Matcap2Mask_ST), _Matcap2MaskPan)[_Matcap2MaskChannel];
				#else
				matcap2Mask = 1;
				#endif
				if (_Matcap2MaskInvert)
				{
					matcap2Mask = 1 - matcap2Mask;
				}
				
				#ifdef TPS_Penetrator
				if (_Matcap2TPSDepthEnabled)
				{
					matcap2Mask = lerp(0, matcap2Mask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Matcap2TPSMaskStrength);
				}
				#endif
				
				poiFragData.alpha *= lerp(1, matcap2.a, matcap2Mask * _Matcap2AlphaOverride);
				
				//UNITY_BRANCH
				if (_Matcap2HueShiftEnabled)
				{
					matcap2.rgb = hueShift(matcap2.rgb, _Matcap2HueShift + _Time.x * _Matcap2HueShiftSpeed);
				}
				
				if (_Matcap2ApplyToAlphaEnabled)
				{
					float matcap2AlphaApplyValue = dot(matcap2.rgb, float3(0.299, 0.587, 0.114)); // Greyscale
					if (_Matcap2ApplyToAlphaSourceBlend == 1) // Max
					
					{
						matcap2AlphaApplyValue = poiMax(matcap2.rgb);
					}
					if (_Matcap2ApplyToAlphaBlendType == 0) // Add
					
					{
						poiFragData.alpha += lerp(0, matcap2AlphaApplyValue, _Matcap2ApplyToAlphaBlending);
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
					if (_Matcap2ApplyToAlphaBlendType == 1) // Multiply
					
					{
						poiFragData.alpha *= lerp(1, matcap2AlphaApplyValue, _Matcap2ApplyToAlphaBlending);
					}
				}
				
				blendMatcap(poiLight, poiFragData, poiMods, _Matcap2Add, _Matcap2AddToLight, _Matcap2Multiply, _Matcap2Replace, _Matcap2Mixed, _Matcap2Screen, matcap2, matcap2Mask, _Matcap2EmissionStrength, _Matcap2LightMask, _Matcap2MaskGlobalMask, _Matcap2MaskGlobalMaskBlendType, matcapALD);
				#endif
				//endex
				//ifex _Matcap3Enable==0
				// Matcap 3
				#ifdef POI_MATCAP2
				
				matcapALD.matcapALEnabled = _Matcap2ALEnabled;
				matcapALD.matcapALAlphaAddBand = _Matcap2ALAlphaAddBand;
				matcapALD.matcapALAlphaAdd = _Matcap2ALAlphaAdd;
				matcapALD.matcapALEmissionAddBand = _Matcap2ALEmissionAddBand;
				matcapALD.matcapALEmissionAdd = _Matcap2ALEmissionAdd;
				matcapALD.matcapALIntensityAddBand = _Matcap2ALIntensityAddBand;
				matcapALD.matcapALIntensityAdd = _Matcap2ALIntensityAdd;
				matcapALD.matcapALChronoPanType = _Matcap2ALChronoPanType;
				matcapALD.matcapALChronoPanBand = _Matcap2ALChronoPanBand;
				matcapALD.matcapALChronoPanSpeed = _Matcap2ALChronoPanSpeed;
				
				float3 normal2 = lerp(poiMesh.normals[0], poiMesh.normals[1], _Matcap3Normal);
				#ifdef POI_MATCAP2_CUSTOM_NORMAL
				#if defined(PROP_MATCAP2NORMALMAP) || !defined(OPTIMIZER_ENABLED)
				normal2 = calculateNormal(poiMesh.normals[_Matcap3Normal], poiMesh, _Matcap2NormalMap, _Matcap2NormalMap_ST, _Matcap2NormalMapPan, _Matcap2NormalMapUV, _Matcap2NormalMapScale);
				#endif
				#endif
				
				#if defined(PROP_MATCAP3) || !defined(OPTIMIZER_ENABLED)
				getMatcapUV(matcapUV, _Matcap3Pan.xy, _Matcap3UVMode, _Matcap3UVToBlend, _MatCap3rdBlendUV1.xy, _Matcap3Rotation, _Matcap3Border, normal2, poiCam, poiLight, poiMesh, _Matcap3Normal, matcapALD);
				if (_Matcap3SmoothnessEnabled)
				{
					float mipCount3 = 9;
					if (_Matcap3_TexelSize.z == 8192) mipCount3 = 13;
					if (_Matcap3_TexelSize.z == 4096) mipCount3 = 12;
					if (_Matcap3_TexelSize.z == 2048) mipCount3 = 11;
					if (_Matcap3_TexelSize.z == 1024) mipCount3 = 10;
					if (_Matcap3_TexelSize.z == 512) mipCount3 = 9;
					if (_Matcap3_TexelSize.z == 256) mipCount3 = 8;
					if (_Matcap3_TexelSize.z == 128) mipCount3 = 7;
					if (_Matcap3_TexelSize.z == 64) mipCount3 = 6;
					if (_Matcap3_TexelSize.z == 32) mipCount3 = 5;
					
					float matcap3Smoothness = _Matcap3Smoothness;
					
					if (_Matcap3MaskSmoothnessApply)
					{
						#if defined(PROP_MATCAP3MASK) || !defined(OPTIMIZER_ENABLED)
						matcap3Smoothness *= POI2D_SAMPLER_PAN(_Matcap3Mask, _MainTex, poiUV(poiMesh.uv[_Matcap3MaskUV], _Matcap3Mask_ST), _Matcap3MaskPan)[_Matcap3MaskSmoothnessChannel];
						#endif
					}
					matcap3Smoothness = (1 - matcap3Smoothness) * mipCount3;
					matcap3 = UNITY_SAMPLE_TEX2D_SAMPLER_LOD(_Matcap3, _trilinear_repeat, TRANSFORM_TEX(matcapUV, _Matcap3), matcap3Smoothness) * float4(poiThemeColor(poiMods, _Matcap3Color.rgb, _Matcap3ColorThemeIndex), _Matcap3Color.a);
				}
				else
				{
					matcap3 = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap3, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap3)) * float4(poiThemeColor(poiMods, _Matcap3Color.rgb, _Matcap3ColorThemeIndex), _Matcap3Color.a);
				}
				#else
				matcap3 = float4(poiThemeColor(poiMods, _Matcap3Color.rgb, _Matcap3ColorThemeIndex), _Matcap3Color.a);
				#endif
				
				matcapIntensity = _Matcap3Intensity;
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapIntensity += lerp(matcapALD.matcapALIntensityAdd.x, matcapALD.matcapALIntensityAdd.y, poiMods.audioLink[matcapALD.matcapALIntensityAddBand]);
					matcapIntensity = max(0, matcapIntensity);
				}
				#endif
				matcap3.rgb *= matcapIntensity;
				matcap3.rgb = lerp(matcap3.rgb, matcap3.rgb * poiFragData.baseColor.rgb, _Matcap3BaseColorMix);
				
				#if defined(PROP_MATCAP3MASK) || !defined(OPTIMIZER_ENABLED)
				matcap3Mask = POI2D_SAMPLER_PAN(_Matcap3Mask, _MainTex, poiUV(poiMesh.uv[_Matcap3MaskUV], _Matcap3Mask_ST), _Matcap3MaskPan)[_Matcap3MaskChannel];
				#else
				matcap3Mask = 1;
				#endif
				if (_Matcap3MaskInvert)
				{
					matcap3Mask = 1 - matcap3Mask;
				}
				
				#ifdef TPS_Penetrator
				if (_Matcap3TPSDepthEnabled)
				{
					matcap3Mask = lerp(0, matcap3Mask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Matcap3TPSMaskStrength);
				}
				#endif
				
				poiFragData.alpha *= lerp(1, matcap3.a, matcap3Mask * _Matcap3AlphaOverride);
				
				//UNITY_BRANCH
				if (_Matcap3HueShiftEnabled)
				{
					matcap3.rgb = hueShift(matcap3.rgb, _Matcap3HueShift + _Time.x * _Matcap3HueShiftSpeed);
				}
				
				if (_Matcap3ApplyToAlphaEnabled)
				{
					float matcap3AlphaApplyValue = dot(matcap3.rgb, float3(0.299, 0.587, 0.114)); // Greyscale
					if (_Matcap3ApplyToAlphaSourceBlend == 1) // Max
					
					{
						matcap3AlphaApplyValue = poiMax(matcap3.rgb);
					}
					if (_Matcap3ApplyToAlphaBlendType == 0) // Add
					
					{
						poiFragData.alpha += lerp(0, matcap3AlphaApplyValue, _Matcap3ApplyToAlphaBlending);
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
					if (_Matcap3ApplyToAlphaBlendType == 1) // Multiply
					
					{
						poiFragData.alpha *= lerp(1, matcap3AlphaApplyValue, _Matcap3ApplyToAlphaBlending);
					}
				}
				
				blendMatcap(poiLight, poiFragData, poiMods, _Matcap3Add, _Matcap3AddToLight, _Matcap3Multiply, _Matcap3Replace, _Matcap3Mixed, _Matcap3Screen, matcap3, matcap3Mask, _Matcap3EmissionStrength, _Matcap3LightMask, _Matcap3MaskGlobalMask, _Matcap3MaskGlobalMaskBlendType, matcapALD);
				#endif
				//endex
				//ifex _Matcap4Enable==0
				// Matcap 4
				#ifdef POI_MATCAP3
				
				matcapALD.matcapALEnabled = _Matcap3ALEnabled;
				matcapALD.matcapALAlphaAddBand = _Matcap3ALAlphaAddBand;
				matcapALD.matcapALAlphaAdd = _Matcap3ALAlphaAdd;
				matcapALD.matcapALEmissionAddBand = _Matcap3ALEmissionAddBand;
				matcapALD.matcapALEmissionAdd = _Matcap3ALEmissionAdd;
				matcapALD.matcapALIntensityAddBand = _Matcap3ALIntensityAddBand;
				matcapALD.matcapALIntensityAdd = _Matcap3ALIntensityAdd;
				matcapALD.matcapALChronoPanType = _Matcap3ALChronoPanType;
				matcapALD.matcapALChronoPanBand = _Matcap3ALChronoPanBand;
				matcapALD.matcapALChronoPanSpeed = _Matcap3ALChronoPanSpeed;
				
				float3 normal3 = lerp(poiMesh.normals[0], poiMesh.normals[1], _Matcap4Normal);
				#ifdef POI_MATCAP3_CUSTOM_NORMAL
				#if defined(PROP_MATCAP3NORMALMAP) || !defined(OPTIMIZER_ENABLED)
				normal3 = calculateNormal(poiMesh.normals[_Matcap4Normal], poiMesh, _Matcap3NormalMap, _Matcap3NormalMap_ST, _Matcap3NormalMapPan, _Matcap3NormalMapUV, _Matcap3NormalMapScale);
				#endif
				#endif
				
				#if defined(PROP_MATCAP4) || !defined(OPTIMIZER_ENABLED)
				getMatcapUV(matcapUV, _Matcap4Pan.xy, _Matcap4UVMode, _Matcap4UVToBlend, _MatCap4thBlendUV1.xy, _Matcap4Rotation, _Matcap4Border, normal3, poiCam, poiLight, poiMesh, _Matcap4Normal, matcapALD);
				if (_Matcap4SmoothnessEnabled)
				{
					float mipCount4 = 9;
					if (_Matcap4_TexelSize.z == 8192) mipCount4 = 13;
					if (_Matcap4_TexelSize.z == 4096) mipCount4 = 12;
					if (_Matcap4_TexelSize.z == 2048) mipCount4 = 11;
					if (_Matcap4_TexelSize.z == 1024) mipCount4 = 10;
					if (_Matcap4_TexelSize.z == 512) mipCount4 = 9;
					if (_Matcap4_TexelSize.z == 256) mipCount4 = 8;
					if (_Matcap4_TexelSize.z == 128) mipCount4 = 7;
					if (_Matcap4_TexelSize.z == 64) mipCount4 = 6;
					if (_Matcap4_TexelSize.z == 32) mipCount4 = 5;
					
					float matcap4Smoothness = _Matcap4Smoothness;
					
					if (_Matcap4MaskSmoothnessApply)
					{
						#if defined(PROP_MATCAP4MASK) || !defined(OPTIMIZER_ENABLED)
						matcap4Smoothness *= POI2D_SAMPLER_PAN(_Matcap4Mask, _MainTex, poiUV(poiMesh.uv[_Matcap4MaskUV], _Matcap4Mask_ST), _Matcap4MaskPan)[_Matcap4MaskSmoothnessChannel];
						#endif
					}
					matcap4Smoothness = (1 - matcap4Smoothness) * mipCount4;
					matcap4 = UNITY_SAMPLE_TEX2D_SAMPLER_LOD(_Matcap4, _trilinear_repeat, TRANSFORM_TEX(matcapUV, _Matcap4), matcap4Smoothness) * float4(poiThemeColor(poiMods, _Matcap4Color.rgb, _Matcap4ColorThemeIndex), _Matcap4Color.a);
				}
				else
				{
					matcap4 = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap4, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap4)) * float4(poiThemeColor(poiMods, _Matcap4Color.rgb, _Matcap4ColorThemeIndex), _Matcap4Color.a);
				}
				#else
				matcap4 = float4(poiThemeColor(poiMods, _Matcap4Color.rgb, _Matcap4ColorThemeIndex), _Matcap4Color.a);
				#endif
				
				matcapIntensity = _Matcap4Intensity;
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapIntensity += lerp(matcapALD.matcapALIntensityAdd.x, matcapALD.matcapALIntensityAdd.y, poiMods.audioLink[matcapALD.matcapALIntensityAddBand]);
					matcapIntensity = max(0, matcapIntensity);
				}
				#endif
				matcap4.rgb *= matcapIntensity;
				matcap4.rgb = lerp(matcap4.rgb, matcap4.rgb * poiFragData.baseColor.rgb, _Matcap4BaseColorMix);
				
				#if defined(PROP_MATCAP4MASK) || !defined(OPTIMIZER_ENABLED)
				matcap4Mask = POI2D_SAMPLER_PAN(_Matcap4Mask, _MainTex, poiUV(poiMesh.uv[_Matcap4MaskUV], _Matcap4Mask_ST), _Matcap4MaskPan)[_Matcap4MaskChannel];
				#else
				matcap4Mask = 1;
				#endif
				if (_Matcap4MaskInvert)
				{
					matcap4Mask = 1 - matcap4Mask;
				}
				
				#ifdef TPS_Penetrator
				if (_Matcap4TPSDepthEnabled)
				{
					matcap4Mask = lerp(0, matcap4Mask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Matcap4TPSMaskStrength);
				}
				#endif
				
				poiFragData.alpha *= lerp(1, matcap4.a, matcap4Mask * _Matcap4AlphaOverride);
				
				//UNITY_BRANCH
				if (_Matcap4HueShiftEnabled)
				{
					matcap4.rgb = hueShift(matcap4.rgb, _Matcap4HueShift + _Time.x * _Matcap4HueShiftSpeed);
				}
				
				if (_Matcap4ApplyToAlphaEnabled)
				{
					float matcap4AlphaApplyValue = dot(matcap4.rgb, float3(0.299, 0.587, 0.114)); // Greyscale
					if (_Matcap4ApplyToAlphaSourceBlend == 1) // Max
					
					{
						matcap4AlphaApplyValue = poiMax(matcap4.rgb);
					}
					if (_Matcap4ApplyToAlphaBlendType == 0) // Add
					
					{
						poiFragData.alpha += lerp(0, matcap4AlphaApplyValue, _Matcap4ApplyToAlphaBlending);
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
					if (_Matcap4ApplyToAlphaBlendType == 1) // Multiply
					
					{
						poiFragData.alpha *= lerp(1, matcap4AlphaApplyValue, _Matcap4ApplyToAlphaBlending);
					}
				}
				
				blendMatcap(poiLight, poiFragData, poiMods, _Matcap4Add, _Matcap4AddToLight, _Matcap4Multiply, _Matcap4Replace, _Matcap4Mixed, _Matcap4Screen, matcap4, matcap4Mask, _Matcap4EmissionStrength, _Matcap4LightMask, _Matcap4MaskGlobalMask, _Matcap4MaskGlobalMaskBlendType, matcapALD);
				#endif
				//endex
				//ifex _MatcapEnable==0 && _Matcap2Enable==0 && _Matcap3Enable==0 && _Matcap4Enable==0
				
			}
			#endif
			//endex
			
			//ifex _CubeMapEnabled==0
			#ifdef _CUBEMAP
			#if defined(PROP_CUBEMAP) || !defined(OPTIMIZER_ENABLED)
			// From Unity's MIT'd Skybox-Cubed.shader
			float3 RotateAroundYInDegrees(float3 dir, float degrees)
			{
				float alpha = degrees * UNITY_PI / 180.0;
				float sina, cosa;
				sincos(alpha, sina, cosa);
				float2x2 m = float2x2(cosa, -sina, sina, cosa);
				return float3(mul(m, dir.xz), dir.y).xzy;
			}
			#endif
			void applyCubemap(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, in PoiLight poiLight, in PoiMods poiMods)
			{
				float3 CubeMapUV = 0;
				
				switch(_CubeMapUVMode)
				{
					case 0: // Skybox
					CubeMapUV = -poiCam.viewDir;
					break;
					case 1: // Reflection
					CubeMapUV = poiCam.reflectionDir;
					break;
					case 2: // World Normal Direction
					CubeMapUV = lerp(poiMesh.normals[0], poiMesh.normals[1], _CubeMapWorldNormalsStrength);
					break;
					case 3: // Local Normal Direction
					CubeMapUV = poiMesh.objNormal;
					break;
				}
				
				#if defined(PROP_CUBEMAP) || !defined(OPTIMIZER_ENABLED)
				if (any(_CubeMapRotation.xyz) || any(_CubeMapRotationPan.xyz))
				{
					// Do funny swizzle so we don't have to make a new function for every direction
					CubeMapUV = RotateAroundYInDegrees(CubeMapUV.yxz, _CubeMapRotation.x + (_CubeMapRotationPan.x * _Time.y)).yxz;
					CubeMapUV = RotateAroundYInDegrees(CubeMapUV.xyz, _CubeMapRotation.y + (_CubeMapRotationPan.y * _Time.y)).xyz;
					CubeMapUV = RotateAroundYInDegrees(CubeMapUV.xzy, _CubeMapRotation.z + (_CubeMapRotationPan.z * _Time.y)).xzy;
				}
				float4 cubeMap = texCUBElod(_CubeMap, float4(CubeMapUV, (1 - _CubeMapSmoothness) * (1 - _CubeMapSmoothness) * 8));
				
				cubeMap.rgb *= poiThemeColor(poiMods, _CubeMapColor, _CubeMapColorThemeIndex);
				#else
				float4 cubeMap = float4(0.21763764082, 0.21763764082, 0.21763764082, .5) * float4(poiThemeColor(poiMods, _CubeMapColor, _CubeMapColorThemeIndex), 1);
				#endif
				
				cubeMap.rgb *= _CubeMapIntensity;
				#if defined(PROP_CUBEMAPMASK) || !defined(OPTIMIZER_ENABLED)
				float CubeMapMask = POI2D_SAMPLER_PAN(_CubeMapMask, _MainTex, poiUV(poiMesh.uv[_CubeMapMaskUV], _CubeMapMask_ST), _CubeMapMaskPan)[_CubeMapMaskChannel];
				#else
				float CubeMapMask = 1;
				#endif
				
				if (_CubeMapMaskGlobalMask > 0)
				{
					CubeMapMask = maskBlend(CubeMapMask, poiMods.globalMask[_CubeMapMaskGlobalMask - 1], _CubeMapMaskGlobalMaskBlendType);
				}
				
				if (_CubeMapMaskInvert)
				{
					CubeMapMask = 1 - CubeMapMask;
				}
				
				//UNITY_BRANCH
				if (_CubeMapHueShiftEnabled)
				{
					cubeMap.rgb = hueShift(cubeMap.rgb, _CubeMapHueShift + _Time.x * _CubeMapHueShiftSpeed);
					cubeMap = PoiColorBCS(cubeMap, _CubeMapBrightness, _CubeMapContrast, _CubeMapSaturation);
					//cubeMap.rgb = ModifyViaHSV(cubeMap.rgb, _CubeMapHueShift + _Time.x * _CubeMapHueShiftSpeed, _CubeMapSaturation, _CubeMapValue);
					
				}
				CubeMapMask = min(CubeMapMask, lerp(1, poiLight.rampedLightMap, _CubeMapLightMask));
				float cubeMapAlpha = CubeMapMask * cubeMap.a * _CubeMapBlendAmount;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, cubeMap.rgb, cubeMapAlpha * (_CubemapBlendType == 0));
				poiFragData.baseColor.rgb *= lerp(1, cubeMap.rgb, cubeMapAlpha * (_CubemapBlendType == 1));
				poiFragData.baseColor.rgb += cubeMap.rgb * cubeMapAlpha * (_CubemapBlendType == 2);
				poiFragData.emission += cubeMap.rgb * _CubeMapEmissionStrength * CubeMapMask * cubeMap.a;
			}
			#endif
			//endex
			
			//ifex _EnableALDecal==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_DECAL
			void ApplyAudioLinkDecal(in PoiMesh poiMesh, inout PoiFragData poiFragData, in PoiMods poiMods)
			{
				float4 colorAndMask = float4(1, 1, 1, 1);
				#if defined(PROP_ALDECALCOLORMASK) || !defined(OPTIMIZER_ENABLED)
				colorAndMask = POI2D_SAMPLER_PAN(_ALDecalColorMask, _MainTex, poiUV(poiMesh.uv[_ALDecalColorMaskUV], _ALDecalColorMask_ST), _ALDecalColorMaskPan);
				#endif
				if (_ALDecalGlobalMask > 0)
				{
					colorAndMask.a = customBlend(colorAndMask.a, poiMods.globalMask[_ALDecalGlobalMask-1], _ALDecalGlobalMaskBlendType);
				}
				
				float2 uv = poiMesh.uv[_ALDecalUV];
				float2 decalCenter = _ALUVPosition;
				float theta = radians(_ALUVRotation + _Time.z * _ALUVRotationSpeed);
				float cs = cos(theta);
				float sn = sin(theta);
				uv = float2((uv.x - decalCenter.x) * cs - (uv.y - decalCenter.y) * sn + decalCenter.x, (uv.x - decalCenter.x) * sn + (uv.y - decalCenter.y) * cs + decalCenter.y);
				uv = remap(uv, float2(0, 0) - _ALUVScale.xz / 2 + _ALUVPosition, _ALUVScale.yw / 2 + _ALUVPosition, float2(0, 0), float2(1, 1));
				
				// Mask
				float4 audioLinkMask = 1.0;
				
				// UV
				float2 aluv = uv;
				if (_ALDecalUVMode == 1)
				{
					float2 uvdir = uv * 2 - 1;
					aluv.x = frac(atan2(uvdir.y, uvdir.x) * UNITY_INV_TWO_PI);
					aluv.y = length(uvdir);
				}
				
				// Scale / Offset / Step
				float maskY = aluv.y;
				if (_ALDecalUVMode == 1)
				{
					maskY = remap(maskY, _ALDecaldCircleDimensions.x, _ALDecaldCircleDimensions.y, 0, 1);
				}
				float maskX = aluv.x;
				if (_ALDecalUVMode == 1)
				{
					maskX = remap(maskX, _ALDecaldCircleDimensions.z, _ALDecaldCircleDimensions.w, 0, 1);
				}
				
				float maskVolume = _ALDecalVolumeStep != 0.0 ? floor(maskY * _ALDecalVolumeStep) / _ALDecalVolumeStep : maskY;
				float maskBand = _ALDecalBandStep != 0.0 ? floor(maskX * _ALDecalBandStep) / _ALDecalBandStep : maskX;
				
				// Copy
				audioLinkMask.r = maskVolume;
				audioLinkMask.g = maskBand;
				
				// Clip
				audioLinkMask.b = maskVolume < _ALDecalVolumeClipMin || maskVolume > _ALDecalVolumeClipMax ? 0.0 : audioLinkMask.b;
				audioLinkMask.b = maskBand < _ALDecalBandClipMin || maskBand > _ALDecalBandClipMax ? 0.0 : audioLinkMask.b;
				
				// Shape Clip
				if (_ALDecalShapeClip)
				{
					float volumeth = _ALDecalShapeClipVolumeWidth;
					if (_ALDecalVolumeStep != 0.0) audioLinkMask.b = frac(maskY * _ALDecalVolumeStep) > volumeth ? 0.0 : audioLinkMask.b;
					
					float bandwidth = _ALDecalUVMode == 1 ? _ALDecalShapeClipBandWidth / aluv.y : _ALDecalShapeClipBandWidth;
					float bandth = 1.0 - bandwidth;
					if (_ALDecalBandStep != 0.0) audioLinkMask.b = frac(maskX * _ALDecalBandStep + bandth * 0.5) < bandth ? 0.0 : audioLinkMask.b;
				}
				
				// AudioLink
				float2 audioLinkUV = float2(frac(audioLinkMask.g * 2.0), 4.5 / 4.0 + floor(audioLinkMask.g * 2.0) / 4.0);
				audioLinkUV.y *= 0.0625;
				float4 audioTexture = _AudioTexture.Sample(sampler_linear_clamp, audioLinkUV);
				float audioVal = audioTexture.b * _ALDecalVolume * lerp(_ALDecalBaseBoost, _ALDecalTrebleBoost, audioLinkMask.g);
				float audioLinkValue = _ALDecalLineWidth < 1.0 ? abs(audioVal - audioLinkMask.r) < _ALDecalLineWidth : audioVal > audioLinkMask.r * 2.0;
				audioLinkValue = saturate(audioLinkValue) * audioLinkMask.b;
				//clip(audioLinkValue - .5);
				audioLinkValue *= colorAndMask.a;
				
				if (!poiMods.audioLinkAvailable)
				{
					audioLinkValue = 0;
				}
				
				float3 alColorChord = _AudioTexture.Sample(sampler_linear_clamp, float2(maskX, 24.5 / 64.0)).rgb;
				float volumeColorSrc = audioLinkMask.g;
				if (_ALDecalVolumeColorSource == 1) volumeColorSrc = audioLinkMask.r;
				if (_ALDecalVolumeColorSource == 2) volumeColorSrc = audioVal;
				
				float3 lowColor = _ALDecalVolumeColorLow.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorLow.rgb, _ALDecalVolumeColorLowThemeIndex);
				float3 midColor = _ALDecalVolumeColorMid.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorMid.rgb, _ALDecalVolumeColorMidThemeIndex);
				float3 highColor = _ALDecalVolumeColorHigh.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorHigh.rgb, _ALDecalVolumeColorHighThemeIndex);
				
				float3 volumeColor = lerp(lowColor, midColor, saturate(volumeColorSrc * 2));
				volumeColor = lerp(volumeColor, highColor, saturate(volumeColorSrc * 2 - 1));
				
				float3 emissionColor = lerp(lowColor * _ALDecalLowEmission, midColor * _ALDecalMidEmission, saturate(volumeColorSrc * 2));
				emissionColor = lerp(emissionColor, highColor * _ALDecalHighEmission, saturate(volumeColorSrc * 2 - 1));
				
				//poiFragData.baseColor = lerp(poiFragData.baseColor, volumeColor, audioLinkValue);
				#if defined(POI_PASS_BASE) || defined(POI_PASS_ADD)
				poiFragData.emission += emissionColor * audioLinkValue;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor, customBlend(poiFragData.baseColor, volumeColor * colorAndMask.rgb, _ALDecalBlendType), saturate(_ALDecalBlendAlpha * audioLinkValue));
				#endif
				poiFragData.alpha = lerp(poiFragData.alpha, poiFragData.alpha * audioLinkValue, _ALDecalControlsAlpha);
			}
			#endif
			#endif
			//endex
			
			//ifex _EnableVolumeColor==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_VOLUMECOLOR
			void ApplyAudioLinkVolumeColor(in PoiMesh poiMesh, inout PoiFragData poiFragData, in PoiMods poiMods)
			{
				float volume = AudioLinkLerpMultiline(ALPASS_DFT + float2(poiMesh.uv[_ALVolumeColorUV][_ALVolumeColorDirection] * AUDIOLINK_ETOTALBINS, 0.0)).b;
				
				float3 lowColor = _ALVolumeColorLow.rgb * poiThemeColor(poiMods, _ALVolumeColorLow.rgb, _ALVolumeColorLowThemeIndex);
				float3 midColor = _ALVolumeColorMid.rgb * poiThemeColor(poiMods, _ALVolumeColorMid.rgb, _ALVolumeColorMidThemeIndex);
				float3 highColor = _ALVolumeColorHigh.rgb * poiThemeColor(poiMods, _ALVolumeColorHigh.rgb, _ALVolumeColorHighThemeIndex);
				
				float3 volumeColor = lerp(lowColor, midColor, saturate(volume * 2));
				volumeColor = lerp(volumeColor, highColor, saturate(volume * 2 - 1));
				
				float3 emissionColor = lerp(lowColor * _ALLowEmission, midColor * _ALMidEmission, saturate(volume * 2));
				emissionColor = lerp(emissionColor, highColor * _ALHighEmission, saturate(volume * 2 - 1));
				
				#if defined(POI_PASS_BASE) || defined(POI_PASS_ADD)
				poiFragData.emission += emissionColor * poiMods.audioLinkAvailable;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor, customBlend(poiFragData.baseColor, volumeColor, _ALVolumeColorBlendType), saturate(_ALVolumeColorBlendAlpha * poiMods.audioLinkAvailable));
				#endif
			}
			#endif
			#endif
			//endex
			
			//ifex _EnableFlipbook==0
			#ifdef _SUNDISK_HIGH_QUALITY
			
			void applyFlipbook(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				#if defined(PROP_FLIPBOOKTEXARRAY) || !defined(OPTIMIZER_ENABLED)
				float4 flipBookPixel = float4(0, 0, 0, 0);
				#if defined(PROP_FLIPBOOKMASK) || !defined(OPTIMIZER_ENABLED)
				float flipBookMask = POI2D_SAMPLER_PAN(_FlipbookMask, _MainTex, poiUV(poiMesh.uv[_FlipbookMaskUV], _FlipbookMask_ST), _FlipbookMaskPan)[_FlipbookMaskChannel];
				#else
				float flipBookMask = 1;
				#endif
				if (_FlipbookMaskGlobalMask > 0)
				{
					flipBookMask = maskBlend(flipBookMask, poiMods.globalMask[_FlipbookMaskGlobalMask-1], _FlipbookMaskGlobalMaskBlendType);
				}
				float4 flipbookScaleOffset = _FlipbookScaleOffset;
				
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookScaleOffset.xy += lerp(_AudioLinkFlipbookScale.xy, _AudioLinkFlipbookScale.zw, poiMods.audioLink[_AudioLinkFlipbookScaleBand]);
				}
				#endif
				
				flipbookScaleOffset.xy = 1 - flipbookScaleOffset.xy;
				float2 uv = frac(poiMesh.uv[_FlipbookTexArrayUV]);
				float theta = radians(_FlipbookRotation + _Time.z * _FlipbookRotationSpeed);
				float cs = cos(theta);
				float sn = sin(theta);
				float2 spriteCenter = flipbookScaleOffset.zw + .5;
				// 2d rotation
				uv = float2((uv.x - spriteCenter.x) * cs - (uv.y - spriteCenter.y) * sn + spriteCenter.x, (uv.x - spriteCenter.x) * sn + (uv.y - spriteCenter.y) * cs + spriteCenter.y);
				float4 sideOffset = float4(-(_FlipbookSideOffset.x), _FlipbookSideOffset.y, -(_FlipbookSideOffset.z), _FlipbookSideOffset.w);
				float2 newUV = remap(uv, float2(0, 0) + flipbookScaleOffset.xy / 2 + flipbookScaleOffset.zw + sideOffset.xz, float2(1, 1) - flipbookScaleOffset.xy / 2 + flipbookScaleOffset.zw + sideOffset.yw, float2(0, 0), float2(1, 1));
				
				UNITY_BRANCH
				if (_FlipbookTiled == 0)
				{
					if (max(newUV.x, newUV.y) > 1 || min(newUV.x, newUV.y) < 0)
					{
						return;
					}
				}
				float currentFrame = 0;
				float width;
				float height;
				float totalFrames;
				_FlipbookTexArray.GetDimensions(width, height, totalFrames);
				
				if (_FlipbookStartAndEnd)
				{
					totalFrames -= (totalFrames - min(max(_FlipbookStartFrame, _FlipbookEndFrame), totalFrames));
					totalFrames -= max(0, _FlipbookStartFrame);
				}
				if (!_FlipbookManualFrameControl)
				{
					if (_FlipbookFPS != 0)
					{
						currentFrame = ((_Time.y / (1 / _FlipbookFPS)) + _FlipbookFrameOffset) % totalFrames;
						if (_FlipbookStartAndEnd)
						{
							currentFrame += _FlipbookStartFrame;
						}
					}
				}
				else
				{
					currentFrame = fmod(_FlipbookCurrentFrame, totalFrames);
				}
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					if (_FlipbookChronotensityEnabled)
					{
						currentFrame += AudioLinkGetChronoTime(_FlipbookChronoType, _FlipbookChronotensityBand) * _FlipbookChronotensitySpeed;
					}
					currentFrame += lerp(_AudioLinkFlipbookFrame.x, _AudioLinkFlipbookFrame.y, poiMods.audioLink[_AudioLinkFlipbookFrameBand]);
					float totalFramesAL = totalFrames;
					if (_FlipbookStartAndEnd)
					{
						totalFramesAL += max(0, _FlipbookStartFrame);
					}
					currentFrame %= totalFramesAL;
				}
				#endif
				flipBookPixel = UNITY_SAMPLE_TEX2DARRAY(_FlipbookTexArray, float3(TRANSFORM_TEX(newUV, _FlipbookTexArray) + _Time.x * _FlipbookTexArrayPan, floor(currentFrame)));
				UNITY_BRANCH
				if (_FlipbookCrossfadeEnabled)
				{
					float totalFramesCF = totalFrames;
					if (_FlipbookStartAndEnd)
					{
						totalFramesCF += max(0, _FlipbookStartFrame);
					}
					float4 flipbookNextPixel = UNITY_SAMPLE_TEX2DARRAY(_FlipbookTexArray, float3(TRANSFORM_TEX(newUV, _FlipbookTexArray) + _Time.x * _FlipbookTexArrayPan, floor((currentFrame + 1) % totalFramesCF)));
					flipBookPixel = lerp(flipBookPixel, flipbookNextPixel, smoothstep(_FlipbookCrossfadeRange.x, _FlipbookCrossfadeRange.y, frac(currentFrame)));
				}
				
				UNITY_BRANCH
				if (_FlipbookIntensityControlsAlpha)
				{
					flipBookPixel.a = poiMax(flipBookPixel.rgb);
				}
				UNITY_BRANCH
				if (_FlipbookColorReplaces)
				{
					flipBookPixel.rgb = poiThemeColor(poiMods, _FlipbookColor.rgb, _FlipbookColorThemeIndex);
				}
				else
				{
					flipBookPixel.rgb *= poiThemeColor(poiMods, _FlipbookColor.rgb, _FlipbookColorThemeIndex);
				}
				
				UNITY_BRANCH
				if (_FlipbookHueShiftEnabled)
				{
					flipBookPixel.rgb = hueShift(flipBookPixel.rgb, _FlipbookHueShift + _Time.x * _FlipbookHueShiftSpeed);
				}
				half flipbookAlpha = 1;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookAlpha += saturate(lerp(_AudioLinkFlipbookAlpha.x, _AudioLinkFlipbookAlpha.y, poiMods.audioLink[_AudioLinkFlipbookAlphaBand]));
				}
				#endif
				
				#if !defined(POI_PASS_OUTLINE) && !defined(UNITY_PASS_SHADOWCASTER)
				
				poiFragData.baseColor = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, flipBookPixel.rgb, _FlipbookBlendType), flipBookPixel.a * _FlipbookColor.a * _FlipbookReplace * flipBookMask * flipbookAlpha);
				
				float flipbookEmissionStrength = _FlipbookEmissionStrength;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookEmissionStrength += max(lerp(_AudioLinkFlipbookEmission.x, _AudioLinkFlipbookEmission.y, poiMods.audioLink[_AudioLinkFlipbookEmissionBand]), 0);
				}
				#endif
				
				poiFragData.emission += lerp(0, flipBookPixel.rgb * flipbookEmissionStrength, flipBookPixel.a * _FlipbookColor.a * flipBookMask * flipbookAlpha);
				
				#endif
				
				UNITY_BRANCH
				if (_FlipbookAlphaControlsFinalAlpha)
				{
					poiFragData.alpha = lerp(poiFragData.alpha, flipBookPixel.a * _FlipbookColor.a, flipBookMask);
				}
				#endif
			}
			
			#endif
			//endex
			
			//ifex _EnableEmission==0 && _EnableEmission1==0 && _EnableEmission2==0 && _EnableEmission3==0
			float calculateGlowInTheDark(in float minLight, in float maxLight, in float minEmissionMultiplier, in float maxEmissionMultiplier, in float enabled, in float worldOrMesh, in PoiLight poiLight)
			{
				float glowInTheDarkMultiplier = 1;
				//UNITY_BRANCH
				if (enabled)
				{
					float3 lightValue = worldOrMesh ? calculateluminance(poiLight.finalLighting.rgb) : calculateluminance(poiLight.directColor.rgb);
					float gitdeAlpha = saturate(inverseLerp(minLight, maxLight, lightValue));
					glowInTheDarkMultiplier = lerp(minEmissionMultiplier, maxEmissionMultiplier, gitdeAlpha);
				}
				return glowInTheDarkMultiplier;
			}
			
			float calculateScrollingEmission(in float3 direction, in float velocity, in float interval, in float scrollWidth, float offset, float3 position)
			{
				scrollWidth = max(scrollWidth, 0);
				float phase = 0;
				phase = dot(position, direction);
				phase -= (_Time.y + offset) * velocity;
				phase /= interval;
				phase -= floor(phase);
				phase = saturate(phase);
				return (pow(phase, scrollWidth) + pow(1 - phase, scrollWidth * 4)) * 0.5;
			}
			
			float calculateBlinkingEmission(in float blinkMin, in float blinkMax, in float blinkVelocity, float offset)
			{
				float amplitude = (blinkMax - blinkMin) * 0.5f;
				float base = blinkMin + amplitude;
				return sin((_Time.y + offset) * blinkVelocity) * amplitude + base;
			}
			
			void applyALEmmissionStrength(in PoiMods poiMods, inout float emissionStrength, in float2 emissionStrengthMod, in float emissionStrengthBand, in float2 _EmissionALMultipliers, in float _EmissionALMultipliersBand, in float enabled)
			{
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable && enabled)
				{
					emissionStrength += lerp(emissionStrengthMod.x, emissionStrengthMod.y, poiMods.audioLink[emissionStrengthBand]);
					emissionStrength *= lerp(_EmissionALMultipliers.x, _EmissionALMultipliers.y, poiMods.audioLink[_EmissionALMultipliersBand]);
				}
				#endif
			}
			
			void applyALCenterOutEmission(in PoiMods poiMods, in float nDotV, inout float emissionStrength, in float size, in float band, in float2 emissionToAdd, in float enabled, in float duration)
			{
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable && enabled)
				{
					float intensity;
					[flatten]
					if (duration >= 0)
					{
						intensity = getBandAtTime(band, saturate(remap(nDotV, 1, 0, 0, duration)), size);
					}
					else
					{
						duration *= -1;
						intensity = getBandAtTime(band, saturate(remap(pow(nDotV, 2), 0, 1 + duration, 0, duration)), size);
					}
					emissionStrength += lerp(emissionToAdd[0], emissionToAdd[1], intensity);
				}
				#endif
			}
			//endex
			
			//ifex _EnableEmission==0
			#ifdef _EMISSION
			float3 applyEmission(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiLight poiLight, in PoiCam poiCam, in PoiMods poiMods)
			{
				
				// First Emission
				float3 emission0 = 0;
				float emissionStrength0 = _EmissionStrength;
				float3 emissionColor0 = 0;
				applyALEmmissionStrength(poiMods, emissionStrength0, _EmissionAL0StrengthMod, _EmissionAL0StrengthBand, _EmissionAL0Multipliers, _EmissionAL0MultipliersBand, _EmissionAL0Enabled);
				applyALCenterOutEmission(poiMods, poiLight.nDotV, emissionStrength0, _AudioLinkEmission0CenterOutSize, _AudioLinkEmission0CenterOutBand, _AudioLinkEmission0CenterOut, _EmissionAL0Enabled, _AudioLinkEmission0CenterOutDuration);
				
				float glowInTheDarkMultiplier0 = calculateGlowInTheDark(_GITDEMinLight, _GITDEMaxLight, _GITDEMinEmissionMultiplier, _GITDEMaxEmissionMultiplier, _EnableGITDEmission, _GITDEWorldOrMesh, poiLight);
				
				#if defined(PROP_EMISSIONMAP) || !defined(OPTIMIZER_ENABLED)
				//UNITY_BRANCH
				if (!_EmissionCenterOutEnabled)
				{
					emissionColor0 = POI2D_SAMPLER_PAN(_EmissionMap, _MainTex, poiUV(poiMesh.uv[_EmissionMapUV], _EmissionMap_ST), _EmissionMapPan).rgb * lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap).rgb * poiThemeColor(poiMods, _EmissionColor.rgb, _EmissionColorThemeIndex);
				}
				else
				{
					emissionColor0 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMap, _MainTex, ((.5 + poiLight.nDotV * .5) * _EmissionMap_ST.xy) + _Time.x * _EmissionCenterOutSpeed).rgb * lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap).rgb * poiThemeColor(poiMods, _EmissionColor.rgb, _EmissionColorThemeIndex);
				}
				#else
				emissionColor0 = lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap).rgb * poiThemeColor(poiMods, _EmissionColor.rgb, _EmissionColorThemeIndex);
				#endif
				
				//UNITY_BRANCH
				if (_ScrollingEmission)
				{
					float3 pos = poiMesh.localPos;
					//UNITY_BRANCH
					if (_EmissionScrollingVertexColor)
					{
						pos = poiMesh.vertexColor.rgb;
					}
					
					//UNITY_BRANCH
					if (_EmissionScrollingUseCurve)
					{
						#if defined(PROP_EMISSIONSCROLLINGCURVE) || !defined(OPTIMIZER_ENABLED)
						emissionStrength0 *= UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionScrollingCurve, _MainTex, poiUV(poiMesh.uv[_EmissionMapUV], _EmissionScrollingCurve_ST) + (dot(pos, _EmissiveScroll_Direction.xyz) * _EmissiveScroll_Interval) + _Time.x * _EmissiveScroll_Velocity).r;
						#endif
					}
					else
					{
						emissionStrength0 *= calculateScrollingEmission(_EmissiveScroll_Direction.xyz, _EmissiveScroll_Velocity, _EmissiveScroll_Interval, _EmissiveScroll_Width, _EmissionScrollingOffset, pos);
					}
				}
				
				//UNITY_BRANCH
				if (_EmissionBlinkingEnabled)
				{
					emissionStrength0 *= calculateBlinkingEmission(_EmissiveBlink_Min, _EmissiveBlink_Max, _EmissiveBlink_Velocity, _EmissionBlinkingOffset);
				}
				emissionColor0 = hueShift(emissionColor0, frac(_EmissionHueShift + _EmissionHueShiftSpeed * _Time.x) * _EmissionHueShiftEnabled);
				emissionColor0 = lerp(emissionColor0, dot(emissionColor0, float3(0.3, 0.59, 0.11)), - (_EmissionSaturation) * _EmissionHueShiftEnabled);
				
				#if defined(PROP_EMISSIONMASK) || !defined(OPTIMIZER_ENABLED)
				float emissionMask0 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMask, _MainTex, poiUV(poiMesh.uv[_EmissionMaskUV], _EmissionMask_ST) + _Time.x * _EmissionMaskPan)[_EmissionMaskChannel];
				#else
				float emissionMask0 = 1;
				#endif
				
				if (_EmissionMaskInvert)
				{
					emissionMask0 = 1 - emissionMask0;
				}
				
				if (_EmissionMask0GlobalMask > 0)
				{
					emissionMask0 = maskBlend(emissionMask0, poiMods.globalMask[_EmissionMask0GlobalMask - 1], _EmissionMask0GlobalMaskBlendType);
				}
				
				emissionStrength0 *= glowInTheDarkMultiplier0 * emissionMask0;
				emission0 = max(emissionStrength0 * emissionColor0, 0);
				
				#ifdef POI_DISSOLVE
				//UNITY_BRANCH
				if (_DissolveEmissionSide != 2)
				{
					emission0 *= lerp(1 - dissolveAlpha, dissolveAlpha, _DissolveEmissionSide);
				}
				#endif
				
				// poiFragData.finalColor.rgb = lerp(poiFragData.finalColor.rgb, saturate(emission0 + emission1), _EmissionReplace * poiMax(emission0 + emission1));
				
				poiFragData.emission += emission0;
				return emission0 * _EmissionReplace0;
			}
			#endif
			//endex
			//ifex _EnableEmission1==0
			#ifdef POI_EMISSION_1
			float3 applyEmission1(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiLight poiLight, in PoiCam poiCam, in PoiMods poiMods)
			{
				
				// Second Emission
				float3 emission1 = 0;
				float emissionStrength1 = 0;
				float3 emissionColor1 = 0;
				
				emissionStrength1 = _EmissionStrength1;
				applyALEmmissionStrength(poiMods, emissionStrength1, _EmissionAL1StrengthMod, _EmissionAL1StrengthBand, _EmissionAL1Multipliers, _EmissionAL1MultipliersBand, _EmissionAL1Enabled);
				applyALCenterOutEmission(poiMods, poiLight.nDotV, emissionStrength1, _AudioLinkEmission1CenterOutSize, _AudioLinkEmission1CenterOutBand, _AudioLinkEmission1CenterOut, _EmissionAL1Enabled, _AudioLinkEmission1CenterOutDuration);
				
				float glowInTheDarkMultiplier1 = calculateGlowInTheDark(_GITDEMinLight1, _GITDEMaxLight1, _GITDEMinEmissionMultiplier1, _GITDEMaxEmissionMultiplier1, _EnableGITDEmission1, _GITDEWorldOrMesh1, poiLight);
				#if defined(PROP_EMISSIONMAP1) || !defined(OPTIMIZER_ENABLED)
				
				//UNITY_BRANCH
				if (!_EmissionCenterOutEnabled1)
				{
					emissionColor1 = POI2D_SAMPLER_PAN(_EmissionMap1, _MainTex, poiUV(poiMesh.uv[_EmissionMap1UV], _EmissionMap1_ST), _EmissionMap1Pan) * lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap1).rgb * poiThemeColor(poiMods, _EmissionColor1.rgb, _EmissionColor1ThemeIndex);
				}
				else
				{
					emissionColor1 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMap1, _MainTex, ((.5 + poiLight.nDotV * .5) * _EmissionMap1_ST.xy) + _Time.x * _EmissionCenterOutSpeed1).rgb * lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap1).rgb * poiThemeColor(poiMods, _EmissionColor1.rgb, _EmissionColor1ThemeIndex);
				}
				#else
				emissionColor1 = lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap1).rgb * poiThemeColor(poiMods, _EmissionColor1.rgb, _EmissionColor1ThemeIndex);
				#endif
				//UNITY_BRANCH
				if (_ScrollingEmission1)
				{
					float3 pos1 = poiMesh.localPos;
					//UNITY_BRANCH
					if (_EmissionScrollingVertexColor1)
					{
						pos1 = poiMesh.vertexColor.rgb;
					}
					
					//UNITY_BRANCH
					if (_EmissionScrollingUseCurve1)
					{
						#if defined(PROP_EMISSIONSCROLLINGCURVE1) || !defined(OPTIMIZER_ENABLED)
						emissionStrength1 *= UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionScrollingCurve1, _MainTex, poiUV(poiMesh.uv[_EmissionMap1UV], _EmissionScrollingCurve1_ST) + (dot(pos1, _EmissiveScroll_Direction1) * _EmissiveScroll_Interval1) + _Time.x * _EmissiveScroll_Velocity1);
						#endif
					}
					else
					{
						emissionStrength1 *= calculateScrollingEmission(_EmissiveScroll_Direction1, _EmissiveScroll_Velocity1, _EmissiveScroll_Interval1, _EmissiveScroll_Width1, _EmissionScrollingOffset1, pos1);
					}
				}
				//UNITY_BRANCH
				if (_EmissionBlinkingEnabled1)
				{
					emissionStrength1 *= calculateBlinkingEmission(_EmissiveBlink_Min1, _EmissiveBlink_Max1, _EmissiveBlink_Velocity1, _EmissionBlinkingOffset1);
				}
				emissionColor1 = hueShift(emissionColor1, frac(_EmissionHueShift1 + _EmissionHueShiftSpeed1 * _Time.x) * _EmissionHueShiftEnabled1);
				emissionColor1 = lerp(emissionColor1, dot(emissionColor1, float3(0.3, 0.59, 0.11)), - (_EmissionSaturation1) * _EmissionHueShiftEnabled1);
				
				#if defined(PROP_EMISSIONMASK1) || !defined(OPTIMIZER_ENABLED)
				float emissionMask1 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMask1, _MainTex, poiUV(poiMesh.uv[_EmissionMask1UV], _EmissionMask1_ST) + _Time.x * _EmissionMask1Pan)[_EmissionMask1Channel];
				#else
				float emissionMask1 = 1;
				#endif
				
				if (_EmissionMaskInvert1)
				{
					emissionMask1 = 1 - emissionMask1;
				}
				
				if (_EmissionMask1GlobalMask > 0)
				{
					emissionMask1 = maskBlend(emissionMask1, poiMods.globalMask[_EmissionMask1GlobalMask - 1], _EmissionMask1GlobalMaskBlendType);
				}
				
				emissionStrength1 *= glowInTheDarkMultiplier1 * emissionMask1;
				emission1 = max(emissionStrength1 * emissionColor1, 0);
				
				poiFragData.emission += emission1;
				return emission1 * _EmissionReplace1;
			}
			#endif
			//endex
			//ifex _EnableEmission2==0
			#ifdef POI_EMISSION_2
			float3 applyEmission2(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiLight poiLight, in PoiCam poiCam, in PoiMods poiMods)
			{
				
				// Second Emission
				float3 emission2 = 0;
				float emissionStrength2 = 0;
				float3 emissionColor2 = 0;
				
				emissionStrength2 = _EmissionStrength2;
				applyALEmmissionStrength(poiMods, emissionStrength2, _EmissionAL2StrengthMod, _EmissionAL2StrengthBand, _EmissionAL2Multipliers, _EmissionAL2MultipliersBand, _EmissionAL2Enabled);
				applyALCenterOutEmission(poiMods, poiLight.nDotV, emissionStrength2, _AudioLinkEmission2CenterOutSize, _AudioLinkEmission2CenterOutBand, _AudioLinkEmission2CenterOut, _EmissionAL2Enabled, _AudioLinkEmission2CenterOutDuration);
				
				float glowInTheDarkMultiplier2 = calculateGlowInTheDark(_GITDEMinLight2, _GITDEMaxLight2, _GITDEMinEmissionMultiplier2, _GITDEMaxEmissionMultiplier2, _EnableGITDEmission2, _GITDEWorldOrMesh2, poiLight);
				#if defined(PROP_EMISSIONMAP2) || !defined(OPTIMIZER_ENABLED)
				
				//UNITY_BRANCH
				if (!_EmissionCenterOutEnabled2)
				{
					emissionColor2 = POI2D_SAMPLER_PAN(_EmissionMap2, _MainTex, poiUV(poiMesh.uv[_EmissionMap2UV], _EmissionMap2_ST), _EmissionMap2Pan) * lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap2).rgb * poiThemeColor(poiMods, _EmissionColor2.rgb, _EmissionColor2ThemeIndex);
				}
				else
				{
					emissionColor2 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMap2, _MainTex, ((.5 + poiLight.nDotV * .5) * _EmissionMap2_ST.xy) + _Time.x * _EmissionCenterOutSpeed2).rgb * lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap2).rgb * poiThemeColor(poiMods, _EmissionColor2.rgb, _EmissionColor2ThemeIndex);
				}
				#else
				emissionColor2 = lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap2).rgb * poiThemeColor(poiMods, _EmissionColor2.rgb, _EmissionColor2ThemeIndex);
				#endif
				//UNITY_BRANCH
				if (_ScrollingEmission2)
				{
					float3 pos2 = poiMesh.localPos;
					//UNITY_BRANCH
					if (_EmissionScrollingVertexColor2)
					{
						pos2 = poiMesh.vertexColor.rgb;
					}
					
					//UNITY_BRANCH
					if (_EmissionScrollingUseCurve2)
					{
						#if defined(PROP_EMISSIONSCROLLINGCURVE2) || !defined(OPTIMIZER_ENABLED)
						emissionStrength2 *= UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionScrollingCurve2, _MainTex, poiUV(poiMesh.uv[_EmissionMap2UV], _EmissionScrollingCurve2_ST) + (dot(pos2, _EmissiveScroll_Direction2) * _EmissiveScroll_Interval2) + _Time.x * _EmissiveScroll_Velocity2);
						#endif
					}
					else
					{
						emissionStrength2 *= calculateScrollingEmission(_EmissiveScroll_Direction2, _EmissiveScroll_Velocity2, _EmissiveScroll_Interval2, _EmissiveScroll_Width2, _EmissionScrollingOffset2, pos2);
					}
				}
				//UNITY_BRANCH
				if (_EmissionBlinkingEnabled2)
				{
					emissionStrength2 *= calculateBlinkingEmission(_EmissiveBlink_Min2, _EmissiveBlink_Max2, _EmissiveBlink_Velocity2, _EmissionBlinkingOffset2);
				}
				emissionColor2 = hueShift(emissionColor2, frac(_EmissionHueShift2 + _EmissionHueShiftSpeed2 * _Time.x) * _EmissionHueShiftEnabled2);
				emissionColor2 = lerp(emissionColor2, dot(emissionColor2, float3(0.3, 0.59, 0.11)), - (_EmissionSaturation2) * _EmissionHueShiftEnabled2);
				
				#if defined(PROP_EMISSIONMASK2) || !defined(OPTIMIZER_ENABLED)
				float emissionMask2 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMask2, _MainTex, poiUV(poiMesh.uv[_EmissionMask2UV], _EmissionMask2_ST) + _Time.x * _EmissionMask2Pan)[_EmissionMask2Channel];
				#else
				float emissionMask2 = 1;
				#endif
				if (_EmissionMaskInvert2)
				{
					emissionMask2 = 1 - emissionMask2;
				}
				
				if (_EmissionMask2GlobalMask > 0)
				{
					emissionMask2 = maskBlend(emissionMask2, poiMods.globalMask[_EmissionMask2GlobalMask - 1], _EmissionMask2GlobalMaskBlendType);
				}
				emissionStrength2 *= glowInTheDarkMultiplier2 * emissionMask2;
				emission2 = max(emissionStrength2 * emissionColor2, 0);
				
				poiFragData.emission += emission2;
				return emission2 * _EmissionReplace2;
			}
			#endif
			//endex
			//ifex _EnableEmission3==0
			#ifdef POI_EMISSION_3
			float3 applyEmission3(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiLight poiLight, in PoiCam poiCam, in PoiMods poiMods)
			{
				
				// Second Emission
				float3 emission3 = 0;
				float emissionStrength3 = 0;
				float3 emissionColor3 = 0;
				
				emissionStrength3 = _EmissionStrength3;
				applyALEmmissionStrength(poiMods, emissionStrength3, _EmissionAL3StrengthMod, _EmissionAL3StrengthBand, _EmissionAL3Multipliers, _EmissionAL3MultipliersBand, _EmissionAL3Enabled);
				applyALCenterOutEmission(poiMods, poiLight.nDotV, emissionStrength3, _AudioLinkEmission3CenterOutSize, _AudioLinkEmission3CenterOutBand, _AudioLinkEmission3CenterOut, _EmissionAL3Enabled, _AudioLinkEmission3CenterOutDuration);
				
				float glowInTheDarkMultiplier3 = calculateGlowInTheDark(_GITDEMinLight3, _GITDEMaxLight3, _GITDEMinEmissionMultiplier3, _GITDEMaxEmissionMultiplier3, _EnableGITDEmission3, _GITDEWorldOrMesh3, poiLight);
				#if defined(PROP_EMISSIONMAP3) || !defined(OPTIMIZER_ENABLED)
				
				//UNITY_BRANCH
				if (!_EmissionCenterOutEnabled3)
				{
					emissionColor3 = POI2D_SAMPLER_PAN(_EmissionMap3, _MainTex, poiUV(poiMesh.uv[_EmissionMap3UV], _EmissionMap3_ST), _EmissionMap3Pan) * lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap3).rgb * poiThemeColor(poiMods, _EmissionColor3.rgb, _EmissionColor3ThemeIndex);
				}
				else
				{
					emissionColor3 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMap3, _MainTex, ((.5 + poiLight.nDotV * .5) * _EmissionMap3_ST.xy) + _Time.x * _EmissionCenterOutSpeed3).rgb * lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap3).rgb * poiThemeColor(poiMods, _EmissionColor3.rgb, _EmissionColor3ThemeIndex);
				}
				#else
				emissionColor3 = lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap3).rgb * poiThemeColor(poiMods, _EmissionColor3.rgb, _EmissionColor3ThemeIndex);
				#endif
				//UNITY_BRANCH
				if (_ScrollingEmission3)
				{
					float3 pos3 = poiMesh.localPos;
					//UNITY_BRANCH
					if (_EmissionScrollingVertexColor3)
					{
						pos3 = poiMesh.vertexColor.rgb;
					}
					
					//UNITY_BRANCH
					if (_EmissionScrollingUseCurve3)
					{
						#if defined(PROP_EMISSIONSCROLLINGCURVE3) || !defined(OPTIMIZER_ENABLED)
						emissionStrength3 *= UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionScrollingCurve3, _MainTex, poiUV(poiMesh.uv[_EmissionMap3UV], _EmissionScrollingCurve3_ST) + (dot(pos3, _EmissiveScroll_Direction3) * _EmissiveScroll_Interval3) + _Time.x * _EmissiveScroll_Velocity3);
						#endif
					}
					else
					{
						emissionStrength3 *= calculateScrollingEmission(_EmissiveScroll_Direction3, _EmissiveScroll_Velocity3, _EmissiveScroll_Interval3, _EmissiveScroll_Width3, _EmissionScrollingOffset3, pos3);
					}
				}
				//UNITY_BRANCH
				if (_EmissionBlinkingEnabled3)
				{
					emissionStrength3 *= calculateBlinkingEmission(_EmissiveBlink_Min3, _EmissiveBlink_Max3, _EmissiveBlink_Velocity3, _EmissionBlinkingOffset3);
				}
				emissionColor3 = hueShift(emissionColor3, frac(_EmissionHueShift3 + _EmissionHueShiftSpeed3 * _Time.x) * _EmissionHueShiftEnabled3);
				emissionColor3 = lerp(emissionColor3, dot(emissionColor3, float3(0.3, 0.59, 0.11)), - (_EmissionSaturation3) * _EmissionHueShiftEnabled3);
				
				#if defined(PROP_EMISSIONMASK3) || !defined(OPTIMIZER_ENABLED)
				float emissionMask3 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMask3, _MainTex, poiUV(poiMesh.uv[_EmissionMask3UV], _EmissionMask3_ST) + _Time.x * _EmissionMask3Pan)[_EmissionMask3Channel];
				#else
				float emissionMask3 = 1;
				#endif
				
				if (_EmissionMaskInvert3)
				{
					emissionMask3 = 1 - emissionMask3;
				}
				
				if (_EmissionMask3GlobalMask > 0)
				{
					emissionMask3 = maskBlend(emissionMask3, poiMods.globalMask[_EmissionMask3GlobalMask - 1], _EmissionMask3GlobalMaskBlendType);
				}
				emissionStrength3 *= glowInTheDarkMultiplier3 * emissionMask3;
				emission3 = max(emissionStrength3 * emissionColor3, 0);
				
				poiFragData.emission += emission3;
				return emission3 * _EmissionReplace3;
			}
			#endif
			//endex
			
			//ifex _EnableRimLighting==0 && _EnableRim2Lighting==0
			#if defined(_GLOSSYREFLECTIONS_OFF) || defined(POI_RIM2)
			#if defined(_RIMSTYLE_POIYOMI) || defined(_RIM2STYLE_POIYOMI)
			void ApplyPoiyomiRimLighting(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight, inout PoiMods poiMods, float Is_NormalMapToRimLight, float RimInvert, float RimPower, float RimStrength, float RimShadowWidth, float RimShadowToggle, float RimWidth, float RimBlendStrength, float RimMask, float RimGlobalMask, float RimGlobalMaskBlendType, float4 RimTex, float4 RimLightColor, float RimLightColorThemeIndex, float RimHueShiftEnabled, float RimHueShift, float RimHueShiftSpeed, float RimSharpness, float RimShadowMaskRampType, float RimShadowMaskInvert, float RimShadowMaskStrength, float2 RimShadowAlpha, float RimApplyGlobalMaskIndex, float RimApplyGlobalMaskBlendType, float RimBaseColorMix, float RimBrightness, float RimBlendMode, half AudioLinkRimWidthBand, float2 AudioLinkRimWidthAdd, half AudioLinkRimEmissionBand, float2 AudioLinkRimEmissionAdd, half AudioLinkRimBrightnessBand, float2 AudioLinkRimBrightnessAdd, float rimBias, float rimBiasIntensity, int RimApplyAlpha, float RimApplyAlphaBlend)
			{
				float viewDotNormal = abs(dot(poiCam.viewDir, lerp(poiMesh.normals[0], poiMesh.normals[1], Is_NormalMapToRimLight)));
				
				UNITY_BRANCH
				if (RimInvert)
				{
					viewDotNormal = 1 - viewDotNormal;
				}
				
				viewDotNormal = pow(viewDotNormal, RimPower);
				
				if (RimShadowWidth && RimShadowToggle)
				{
					viewDotNormal += lerp(0, (1 - poiLight.nDotLNormalized) * 3, RimShadowWidth);
				}
				
				viewDotNormal *= lerp(1, rimBias, rimBiasIntensity);
				
				float rimStrength = RimStrength;
				
				float rimWidth = lerp( - .05, 1, RimWidth);
				
				float blendStrength = RimBlendStrength;
				#ifdef POI_AUDIOLINK
				UNITY_BRANCH
				if (poiMods.audioLinkAvailable)
				{
					rimWidth = clamp(rimWidth + lerp(AudioLinkRimWidthAdd.x, AudioLinkRimWidthAdd.y, poiMods.audioLink[AudioLinkRimWidthBand]), - .05, 1);
					rimStrength += lerp(AudioLinkRimEmissionAdd.x, AudioLinkRimEmissionAdd.y, poiMods.audioLink[AudioLinkRimEmissionBand]);
					RimBrightness += lerp(AudioLinkRimBrightnessAdd.x, AudioLinkRimBrightnessAdd.y, poiMods.audioLink[AudioLinkRimBrightnessBand]);
				}
				#endif
				float rimMask = RimMask;
				
				if (RimGlobalMask > 0)
				{
					rimMask = maskBlend(rimMask, poiMods.globalMask[RimGlobalMask - 1], RimGlobalMaskBlendType);
				}
				
				float4 rimColor = RimTex;
				rimColor *= float4(poiThemeColor(poiMods, RimLightColor.rgb, RimLightColorThemeIndex), RimLightColor.a);
				
				UNITY_BRANCH
				if (RimHueShiftEnabled)
				{
					rimColor.rgb = hueShift(rimColor.rgb, RimHueShift + _Time.x * RimHueShiftSpeed);
				}
				
				float rim = 1 - smoothstep(min(RimSharpness, rimWidth), rimWidth, viewDotNormal);
				rim *= RimLightColor.a * rimColor.a * rimMask;
				
				if (RimShadowToggle)
				{
					switch(RimShadowMaskRampType)
					{
						case 0:
						float rampedLightMap = poiLight.rampedLightMap;
						if (RimShadowMaskInvert) rampedLightMap = 1 - rampedLightMap;
						rim = lerp(rim, rim * rampedLightMap, RimShadowMaskStrength);
						break;
						case 1:
						float nDotLNormalized = poiLight.nDotLNormalized;
						if (RimShadowMaskInvert) nDotLNormalized = 1 - nDotLNormalized;
						rim = lerp(rim, rim * smoothstep(RimShadowAlpha.x, RimShadowAlpha.y, nDotLNormalized), RimShadowMaskStrength);
						break;
					}
				}
				
				if (RimApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, RimApplyGlobalMaskIndex - 1, RimApplyGlobalMaskBlendType, rim * blendStrength);
				}
				
				if (RimApplyAlpha == 1) // Add
				
				{
					poiFragData.alpha += lerp(0, saturate(rim), RimApplyAlphaBlend);
					poiFragData.alpha = saturate(poiFragData.alpha);
				}
				if (RimApplyAlpha == 2) // Multiply
				
				{
					poiFragData.alpha *= lerp(1, saturate(rim), RimApplyAlphaBlend);
				}
				
				float3 finalRimColor = rimColor.rgb * lerp(1, poiFragData.baseColor, RimBaseColorMix);
				finalRimColor *= RimBrightness;
				// Add 0, Replace 1, Multiply 2, Mixed 3
				switch(RimBlendMode)
				{
					case 0: poiFragData.baseColor += finalRimColor * rim * blendStrength; break;
					case 1: poiFragData.baseColor = lerp(poiFragData.baseColor, finalRimColor, rim * blendStrength); break;
					case 2: poiFragData.baseColor = lerp(poiFragData.baseColor, poiFragData.baseColor * finalRimColor, rim * blendStrength); break;
					case 3: poiFragData.baseColor = lerp(poiFragData.baseColor.rgb, poiFragData.baseColor.rgb + poiFragData.baseColor.rgb * finalRimColor, rim * blendStrength); break;
					case 4: poiFragData.baseColor = lerp(poiFragData.baseColor, 1 - (1 - poiFragData.baseColor) * (1 - finalRimColor), rim * blendStrength); break;
				}
				poiFragData.emission += finalRimColor * rim * rimStrength;
			}
			#endif
			#if defined(_RIMSTYLE_UTS2) || defined(_RIM2STYLE_UTS2)
			void ApplyUTS2RimLighting(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight, in PoiMods poiMods, float Set_RimLightMask_var, float RimGlobalMask, float RimGlobalMaskBlendType, float4 RimLightColor, float RimLightColorThemeIndex, float Is_LightColor_RimLight, float Is_NormalMapToRimLight, float RimLight_Power, float RimLight_InsideMask, float RimLight_FeatherOff, float LightDirection_MaskOn, float Tweak_LightDirection_MaskLevel, float Add_Antipodean_RimLight, float4 Ap_RimLightColor, float RimApColorThemeIndex, float Is_LightColor_Ap_RimLight, float Ap_RimLight_Power, float Ap_RimLight_FeatherOff, float Tweak_RimLightMaskLevel, float RimHueShiftEnabled, float RimHueShift, float RimHueShiftSpeed)
			{
				if (RimGlobalMask > 0)
				{
					Set_RimLightMask_var = maskBlend(Set_RimLightMask_var, poiMods.globalMask[RimGlobalMask - 1], RimGlobalMaskBlendType);
				}
				
				float3 rimColor = float3(poiThemeColor(poiMods, RimLightColor.rgb, RimLightColorThemeIndex));
				float3 _Is_LightColor_RimLight_var = lerp(rimColor, (rimColor * poiLight.directColor), Is_LightColor_RimLight);
				float _RimArea_var = (1.0 - dot(lerp(poiMesh.normals[0], poiMesh.normals[1], Is_NormalMapToRimLight), poiCam.viewDir));
				float _RimLightPower_var = pow(_RimArea_var, exp2(lerp(3, 0, RimLight_Power)));
				float _Rimlight_InsideMask_var = saturate(lerp((0.0 + ((_RimLightPower_var - RimLight_InsideMask) * (1.0 - 0.0)) / (1.0 - RimLight_InsideMask)), step(RimLight_InsideMask, _RimLightPower_var), RimLight_FeatherOff));
				float _VertHalfLambert_var = 0.5 * dot(poiMesh.normals[0], poiLight.direction) + 0.5;
				float3 _LightDirection_MaskOn_var = lerp((_Is_LightColor_RimLight_var * _Rimlight_InsideMask_var), (_Is_LightColor_RimLight_var * saturate((_Rimlight_InsideMask_var - ((1.0 - _VertHalfLambert_var) + Tweak_LightDirection_MaskLevel)))), LightDirection_MaskOn);
				float _ApRimLightPower_var = pow(_RimArea_var, exp2(lerp(3, 0, Ap_RimLight_Power)));
				float3 ApRimColor = float3(poiThemeColor(poiMods, Ap_RimLightColor.rgb, RimApColorThemeIndex));
				float3 _RimLight_var = (saturate((Set_RimLightMask_var + Tweak_RimLightMaskLevel)) * lerp(_LightDirection_MaskOn_var, (_LightDirection_MaskOn_var + (lerp(ApRimColor, (ApRimColor * poiLight.directColor), Is_LightColor_Ap_RimLight) * saturate((lerp((0.0 + ((_ApRimLightPower_var - RimLight_InsideMask) * (1.0 - 0.0)) / (1.0 - RimLight_InsideMask)), step(RimLight_InsideMask, _ApRimLightPower_var), Ap_RimLight_FeatherOff) - (saturate(_VertHalfLambert_var) + Tweak_LightDirection_MaskLevel))))), Add_Antipodean_RimLight));
				UNITY_BRANCH
				if (RimHueShiftEnabled)
				{
					_RimLight_var = hueShift(_RimLight_var, RimHueShift + _Time.x * RimHueShiftSpeed);
				}
				poiFragData.baseColor += _RimLight_var;
			}
			#endif
			#if defined(_RIMSTYLE_LILTOON) || defined(_RIM2STYLE_LILTOON)
			void ApplyLiltoonRimLighting(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight, in PoiMods poiMods, float4 RimColor, float4 RimIndirColor, float4 RimColorTex, float RimMainStrength, float RimNormalStrength, float RimDirRange, float RimIndirRange, float RimFresnelPower, float RimBackfaceMask, float RimDirStrength, float RimBorder, float RimBlur, float RimIndirBorder, float RimIndirBlur, float RimShadowMask, float RimEnableLighting, float RimVRParallaxStrength, float RimGlobalMask, float RimGlobalMaskBlendType, float RimHueShiftEnabled, float RimHueShift, float RimHueShiftSpeed, int RimBlendMode)
			{
				if (RimGlobalMask > 0)
				{
					RimColorTex.a = maskBlend(RimColorTex.a, poiMods.globalMask[RimGlobalMask - 1], RimGlobalMaskBlendType);
				}
				float4 rimColor = RimColor;
				float4 rimIndirColor = RimIndirColor;
				rimColor *= RimColorTex;
				rimIndirColor *= RimColorTex;
				
				if (RimHueShiftEnabled)
				{
					rimColor.rgb = hueShift(rimColor.rgb, RimHueShift + _Time.x * RimHueShiftSpeed);
					rimIndirColor.rgb = hueShift(rimIndirColor.rgb, RimHueShift + _Time.x * RimHueShiftSpeed);
				}
				
				rimColor.rgb = lerp(rimColor.rgb, rimColor.rgb * poiFragData.baseColor, RimMainStrength);
				
				// View direction
				float3 centerViewDir = !IsOrthographicCamera() ? normalize(getCameraPosition() - poiMesh.worldPos.xyz) : normalize(UNITY_MATRIX_I_V._m02_m12_m22);
				float3 viewDir = lerp(centerViewDir, poiCam.viewDir, RimVRParallaxStrength);
				
				// Normal
				float3 normal = lerp(poiMesh.normals[0], poiMesh.normals[1], RimNormalStrength);
				float nvabs = abs(dot(normal, viewDir));
				
				// Factor
				float lnRaw = dot(poiLight.direction, normal) * 0.5 + 0.5;
				float lnDir = saturate((lnRaw + RimDirRange) / (1.0 + RimDirRange));
				float lnIndir = saturate((1.0 - lnRaw + RimIndirRange) / (1.0 + RimIndirRange));
				float rim = pow(saturate(1.0 - nvabs), RimFresnelPower);
				rim = !poiMesh.isFrontFace && RimBackfaceMask ? 0.0 : rim;
				float rimDir = lerp(rim, rim * lnDir, RimDirStrength);
				float rimIndir = rim * lnIndir * RimDirStrength;
				
				rimDir = poiEdgeLinear(rimDir, RimBorder, RimBlur);
				rimIndir = poiEdgeLinear(rimIndir, RimIndirBorder, RimIndirBlur);
				
				rimDir = lerp(rimDir, rimDir * poiLight.rampedLightMap, RimShadowMask);
				rimIndir = lerp(rimIndir, rimIndir * poiLight.rampedLightMap, RimShadowMask);
				
				float3 lightCol = poiLight.finalLighting;
				/*
				#if !defined(POI_PASS_ADD)
				rimColor.rgb = lerp(rimColor.rgb, rimColor.rgb * lightCol, RimEnableLighting);
				#else
				if (RimBlendMode < 3) rimColor.rgb *= lightCol * RimEnableLighting;
				#endif
				// Blend
				*/
				#if !defined(POI_PASS_ADD)
				float3 rimLightMul = 1 - RimEnableLighting + lightCol * RimEnableLighting;
				#else
				float3 rimLightMul = RimBlendMode < 3 ? lightCol * RimEnableLighting : 1;
				#endif
				
				poiFragData.finalColor = lilBlendColor(poiFragData.finalColor, rimColor.rgb * rimLightMul, rimDir * rimColor.a, RimBlendMode);
				poiFragData.finalColor = lilBlendColor(poiFragData.finalColor, rimIndirColor.rgb * rimLightMul, rimIndir * rimIndirColor.a, RimBlendMode);
			}
			#endif
			#endif
			//endex
			
			//ifex _EnableDepthRimLighting==0
			#ifdef _POI_DEPTH_RIMLIGHT
			
			float PositivePow(float base, float power)
			{
				return pow(max(abs(base), Epsilon), power);
			}
			
			float GetScaleWithHight()
			{
				return _ScreenParams.y / 1080;
			}
			
			float GetSSRimScale(float z)
			{
				float w = (1.0 / (PositivePow(z + saturate(UNITY_MATRIX_P._m00), 1.5) + 0.75)) * GetScaleWithHight();
				w *= lerp(1, UNITY_MATRIX_P._m00, 0.60 * saturate(0.25 * z * z));
				return w < 0.01 ? 0 : w;
			}
			
			void ApplyDepthRimLighting(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, inout PoiLight poiLight, in PoiMods poiMods)
			{
				float rim = 0;
				float perspectiveDivide = 1.0f / poiCam.clipPos.w;
				float4 direction = poiCam.worldDirection * perspectiveDivide;
				float2 screenPos = poiCam.posScreenSpace.xy * perspectiveDivide;
				float z = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, screenPos);
				
				#if UNITY_REVERSED_Z
				if (z == 0) return;
				#else
				if (z == 1) return;
				#endif
				
				float depth = CorrectedLinearEyeDepth(z, direction.w);
				
				switch(_DepthRimType)
				{
					case 0:
					{
						float3 viewPos = UnityObjectToViewPos(poiMesh.localPos);
						float3 viewDir = normalize(viewPos);
						
						float3 viewNorm = mul((float3x3)UNITY_MATRIX_V, poiMesh.normals[_DepthRimNormalToUse]);
						float3 viewCrossNorm = cross(viewDir, viewNorm);
						float2 N_View = normalize(float2(-viewCrossNorm.y, viewCrossNorm.x));
						
						float3 viewLight = mul((float3x3)UNITY_MATRIX_V, poiLight.direction);
						float3 viewCrossLight = cross(viewDir, viewLight);
						float2 L_View = normalize(float2(-viewCrossLight.y, viewCrossLight.x));
						
						//float lDotN = saturate(poiLight.nDotL + _RimLightLength);
						float scale = _DepthRimWidth * GetSSRimScale(depth);
						float2 ssUV1 = clamp(screenPos + N_View * .1 * scale, 0, _ScreenParams.xy - 1);
						float depthDiff = z - SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, ssUV1) ;
						
						rim = smoothstep(0.24 * _DepthRimSharpness * z, 0.25 * z, depthDiff);
						rim *= lerp(1, (dot(L_View, N_View) > 0), _DepthRimHideInShadow);
					}
					break;
					case 1:
					{
						//float lDotN = saturate(poiLight.nDotL + _RimLightLength);
						float scale = _DepthRimWidth * GetSSRimScale(depth);
						float depthDiff = 0;
						[unroll(9)]
						for (int i = 0; i < 9; i++)
						{
							float2 ssUV1 = clamp(screenPos + sobelSamplePoints[i] * .1 * scale, 0, _ScreenParams.xy - 1);
							depthDiff = max(depthDiff, z - SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, ssUV1));
						}
						rim = smoothstep(0.24 * _DepthRimSharpness * z, 0.25 * z, depthDiff);
						rim *= lerp(1, lerp(poiLight.vertexNDotL > 0, poiLight.nDotL > 0, _DepthRimNormalToUse), _DepthRimHideInShadow);
					}
					break;
				}
				
				float3 rimColor = poiThemeColor(poiMods, _DepthRimColor.rgb, _DepthRimColorThemeIndex).rgb * lerp(1, poiLight.directColor, _DepthRimMixLightColor) * lerp(1, poiFragData.baseColor, _DepthRimMixBaseColor) * _DepthRimBrightness;
				
				#ifdef POI_PASS_BASE
				poiLight.finalLightAdd += rim * rimColor * _DepthRimAdditiveLighting;
				#endif
				poiFragData.emission += rim * rimColor * _DepthRimEmission;
				poiFragData.baseColor = lerp(poiFragData.baseColor, rimColor, rim * _DepthRimReplace);
				poiFragData.baseColor += rim * rimColor * _DepthRimAdd;
				poiFragData.baseColor *= lerp(1, rimColor, rim * _DepthRimMultiply);
			}
			#endif
			//endex
			
			//ifex _GlitterEnable==0
			#ifdef _SUNDISK_SIMPLE
			
			float3 RandomColorFromPoint(float2 rando, PoiMods poiMods)
			{
				fixed hue = random2(rando.x + rando.y).x;
				fixed saturation = lerp(_GlitterMinMaxSaturation.x, _GlitterMinMaxSaturation.y, rando.x);
				fixed value = lerp(_GlitterMinMaxBrightness.x, _GlitterMinMaxBrightness.y, rando.y);
				float3 hsv = float3(hue, saturation, value);
				return HSVtoRGB(hsv);
			}
			
			void applyGlitter(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight, in PoiMods poiMods)
			{
				float glitterRotationTimeOffset = 0;
				#ifdef POI_AUDIOLINK
				if (_GlitterALEnabled)
				{
					glitterRotationTimeOffset += AudioLinkGetChronoTime(_GlitterALChronoRotationSpeedType, _GlitterALChronoRotationSpeedBand) * _GlitterALChronoRotationSpeed;
				}
				#endif
				
				for (int glitterLayer = 0; glitterLayer < _GlitterLayers; glitterLayer++)
				{
					// Scale
					
					float2 st = (poiMesh.uv[_GlitterUV] + _GlitterUVPanning.xy * _Time.x) * _GlitterFrequency;
					
					// Tile the space
					float2 i_st = floor(st);
					float2 f_st = frac(st);
					
					float m_dist = 10.;  // minimun distance
					float2 m_point = 0;        // minimum point
					float2 randoPoint = 0;
					float2 dank = 0;
					for (int j = -1; j <= 1; j++)
					{
						for (int i = -1; i <= 1; i++)
						{
							float2 neighbor = float2(i, j);
							float2 pos = random2(i_st + neighbor + glitterLayer * 0.5141);
							float2 rando = pos;
							pos = pos * _GlitterRandomLocation;
							float2 diff = neighbor + pos - f_st;
							float dist = length(diff);
							
							if (dist < m_dist)
							{
								dank = diff;
								m_dist = dist;
								m_point = pos;
								randoPoint = rando;
							}
						}
					}
					
					float randomFromPoint = random(randoPoint);
					
					float size = _GlitterSize;
					UNITY_BRANCH
					if (_GlitterRandomSize)
					{
						size = lerp(_GlitterMinMaxSize.x, _GlitterMinMaxSize.y, randomFromPoint);
					}
					#ifdef POI_AUDIOLINK
					if (_GlitterALEnabled)
					{
						size = saturate(size + lerp(_GlitterALSizeAdd.x, _GlitterALSizeAdd.y, poiMods.audioLink[_GlitterALSizeAddBand]));
					}
					#endif
					
					// Assign a color using the closest point position
					//color += dot(m_point, float2(.3, .6));
					
					// Add distance field to closest point center
					// color.g = m_dist;
					
					// Show isolines
					//color -= abs(sin(40.0 * m_dist)) * 0.07;
					
					// Draw cell center
					half glitterAlpha = 1;
					switch(_GlitterShape)
					{
						case 0: //circle
						glitterAlpha = saturate((size - m_dist) / clamp(fwidth(m_dist), 0.0001, 1.0));
						break;
						case 1: //sqaure
						float jaggyFix = pow(poiCam.distanceToVert, 2) * _GlitterJaggyFix;
						UNITY_BRANCH
						if (_GlitterRandomRotation == 1 || _GlitterTextureRotation != 0 || _GlitterRandomRotationSpeed.x != 0 || _GlitterRandomRotationSpeed.y != 0 || glitterRotationTimeOffset != 0)
						{
							float2 center = float2(0, 0);
							float2 glitterRandomRotationSpeed = 0;
							float randomBoy = 0;
							UNITY_BRANCH
							if (_GlitterRandomRotation || _GlitterRandomRotationSpeed.x != 0 || _GlitterRandomRotationSpeed.y != 0)
							{
								randomBoy = random(m_point * 200);
								glitterRandomRotationSpeed = lerp(_GlitterRandomRotationSpeed.x, _GlitterRandomRotationSpeed.y, randomBoy);
							}
							if (glitterRandomRotationSpeed.x + glitterRandomRotationSpeed.y + _GlitterTextureRotation == 0 && glitterRotationTimeOffset != 0)
							{
								glitterRandomRotationSpeed = 1;
							}
							float theta = radians((randomBoy + (_Time.x + glitterRotationTimeOffset) * (_GlitterTextureRotation + glitterRandomRotationSpeed)) * 360);
							float cs = cos(theta);
							float sn = sin(theta);
							dank = float2((dank.x - center.x) * cs - (dank.y - center.y) * sn + center.x, (dank.x - center.x) * sn + (dank.y - center.y) * cs + center.y);
							glitterAlpha = (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.x))) * (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.y)));
						}
						else
						{
							glitterAlpha = (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.x))) * (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.y)));
						}
						break;
					}
					
					float3 finalGlitter = 0;
					
					half3 glitterColor = poiThemeColor(poiMods, _GlitterColor.rgb, _GlitterColorThemeIndex);
					
					float3 norm = lerp(poiMesh.normals[0], poiMesh.normals[1], _GlitterUseNormals);
					float3 randomRotation = 0;
					float glitterSpeedOffset = 0;
					#ifdef POI_AUDIOLINK
					if (_GlitterALEnabled)
					{
						glitterSpeedOffset += AudioLinkGetChronoTime(_GlitterALChronoSparkleSpeedType, _GlitterALChronoSparkleSpeedBand) * _GlitterALChronoSparkleSpeed;
					}
					#endif
					switch(_GlitterMode)
					{
						case 0:
						UNITY_BRANCH
						if (_GlitterSpeed + glitterSpeedOffset > 0)
						{
							randomRotation = randomFloat3WiggleRange(randoPoint, _GlitterAngleRange, _GlitterSpeed, glitterSpeedOffset);
						}
						else
						{
							randomRotation = randomFloat3Range(randoPoint, _GlitterAngleRange);
						}
						
						float3 glitterReflectionDirection = normalize(mul(poiRotationMatrixFromAngles(randomRotation), norm));
						finalGlitter = lerp(0, _GlitterMinBrightness * glitterAlpha, glitterAlpha) + max(pow(saturate(dot(lerp(glitterReflectionDirection, poiCam.viewDir, _GlitterBias), poiCam.viewDir)), _GlitterContrast), 0);
						finalGlitter *= glitterAlpha;
						break;
						case 1:
						float randomOffset = random(randoPoint);
						float brightness = (sin((_Time.x * 10 + randomOffset +glitterSpeedOffset) * _GlitterSpeed) * .5 + .5);
						finalGlitter = max(_GlitterMinBrightness * glitterAlpha, brightness * glitterAlpha * smoothstep(0, 1, 1 - m_dist * _GlitterCenterSize * 10));
						break;
						case 2:
						if (_GlitterSpeed + glitterSpeedOffset > 0)
						{
							randomRotation = randomFloat3WiggleRange(randoPoint, _GlitterAngleRange, _GlitterSpeed, glitterSpeedOffset);
						}
						else
						{
							randomRotation = randomFloat3Range(randoPoint, _GlitterAngleRange);
						}
						
						float3 glitterLightReflectionDirection = normalize(mul(poiRotationMatrixFromAngles(randomRotation), norm));
						
						glitterAlpha *= poiLight.nDotLSaturated;
						
						float3 halfDir = normalize(poiLight.direction + poiCam.viewDir);
						float specAngle = max(dot(halfDir, glitterLightReflectionDirection), 0.0);
						
						finalGlitter = lerp(0, _GlitterMinBrightness * glitterAlpha, glitterAlpha) + max(pow(specAngle, _GlitterContrast), 0);
						
						glitterColor *= poiLight.directColor;
						finalGlitter *= glitterAlpha;
						
						break;
					}
					
					glitterColor *= lerp(1, poiFragData.baseColor, _GlitterUseSurfaceColor);
					#if defined(PROP_GLITTERCOLORMAP) || !defined(OPTIMIZER_ENABLED)
					glitterColor *= POI2D_SAMPLER_PAN(_GlitterColorMap, _MainTex, poiUV(poiMesh.uv[_GlitterColorMapUV], _GlitterColorMap_ST), _GlitterColorMapPan).rgb;
					#endif
					float2 uv = remapClamped(-size, size, dank, 0, 1);
					UNITY_BRANCH
					
					if (_GlitterRandomRotation == 1 || _GlitterTextureRotation != 0 || _GlitterRandomRotationSpeed.x != 0 || _GlitterRandomRotationSpeed.y && !_GlitterShape || glitterRotationTimeOffset != 0)
					{
						float2 fakeUVCenter = float2(.5, .5);
						float randomBoy = 0;
						float2 glitterRandomRotationSpeed = 0;
						UNITY_BRANCH
						if (_GlitterRandomRotation || _GlitterRandomRotationSpeed.x != 0 || _GlitterRandomRotationSpeed.y != 0)
						{
							randomBoy = random(randoPoint * 20);
							glitterRandomRotationSpeed = lerp(_GlitterRandomRotationSpeed.x, _GlitterRandomRotationSpeed.y, randomBoy);
						}
						if (glitterRandomRotationSpeed.x + glitterRandomRotationSpeed.y + _GlitterTextureRotation == 0 && glitterRotationTimeOffset != 0)
						{
							glitterRandomRotationSpeed = 1;
						}
						float theta = radians((randomBoy + (_Time.x + glitterRotationTimeOffset) * (_GlitterTextureRotation + glitterRandomRotationSpeed)) * 360);
						float cs = cos(theta);
						float sn = sin(theta);
						uv = float2((uv.x - fakeUVCenter.x) * cs - (uv.y - fakeUVCenter.y) * sn + fakeUVCenter.x, (uv.x - fakeUVCenter.x) * sn + (uv.y - fakeUVCenter.y) * cs + fakeUVCenter.y);
					}
					
					#if defined(PROP_GLITTERTEXTURE) || !defined(OPTIMIZER_ENABLED)
					float4 glitterTexture = POI2D_SAMPLER_PANGRAD(_GlitterTexture, _linear_clamp, poiUV(uv, _GlitterTexture_ST), _GlitterTexturePan, poiMesh.dx, poiMesh.dy);
					#else
					float4 glitterTexture = 1;
					#endif
					//float4 glitterTexture = _GlitterTexture.SampleGrad(sampler_MainTex, frac(uv), ddx(uv), ddy(uv));
					glitterColor *= glitterTexture.rgb;
					#if defined(PROP_GLITTERMASK) || !defined(OPTIMIZER_ENABLED)
					float glitterMask = POI2D_SAMPLER_PAN(_GlitterMask, _MainTex, poiUV(poiMesh.uv[_GlitterMaskUV], _GlitterMask_ST), _GlitterMaskPan)[_GlitterMaskChannel];
					#else
					float glitterMask = 1;
					#endif
					
					#ifdef POI_AUDIOLINK
					if (_GlitterALEnabled)
					{
						glitterMask = clamp(glitterMask + lerp(_GlitterALAlphaAdd.x, _GlitterALAlphaAdd.y, poiMods.audioLink[_GlitterALAlphaAddBand]), 0, glitterMask);
					}
					#endif
					
					if (_GlitterMaskInvert)
					{
						glitterMask = 1 - glitterMask;
					}
					
					glitterMask *= lerp(1, poiLight.rampedLightMap, _GlitterHideInShadow);
					glitterMask *= lerp(1, poiLight.directLuminance, _GlitterScaleWithLighting);
					glitterMask *= _GlitterColor.a;
					
					if (_GlitterMaskGlobalMask > 0)
					{
						glitterMask = maskBlend(glitterMask, poiMods.globalMask[_GlitterMaskGlobalMask - 1], _GlitterMaskGlobalMaskBlendType);
					}
					
					if (_GlitterRandomColors)
					{
						glitterColor *= RandomColorFromPoint(random2(randoPoint.x + randoPoint.y), poiMods);
					}
					
					UNITY_BRANCH
					if (_GlitterHueShiftEnabled)
					{
						glitterColor.rgb = hueShift(glitterColor.rgb, _GlitterHueShift + _Time.x * _GlitterHueShiftSpeed);
					}
					float GlitterbrightnessOffset = 0;
					#ifdef POI_AUDIOLINK
					if (_GlitterALEnabled)
					{
						GlitterbrightnessOffset = max(GlitterbrightnessOffset +lerp(_GlitterALMaxBrightnessAdd.x, _GlitterALMaxBrightnessAdd.y, poiMods.audioLink[_GlitterALMaxBrightnessBand]), 0);
					}
					#endif
					
					UNITY_BRANCH
					if (_GlitterBlendType == 1)
					{
						poiFragData.baseColor = lerp(poiFragData.baseColor, finalGlitter * glitterColor * (_GlitterBrightness + GlitterbrightnessOffset), finalGlitter * glitterTexture.a * glitterMask);
						poiFragData.emission += finalGlitter * glitterColor * max(0, ((_GlitterBrightness + GlitterbrightnessOffset) - 1) * glitterTexture.a) * glitterMask;
					}
					else
					{
						poiFragData.emission += finalGlitter * glitterColor * (_GlitterBrightness + GlitterbrightnessOffset) * glitterTexture.a * glitterMask;
					}
				}
			}
			#endif
			//endex
			
			//ifex _SubsurfaceScattering==0
			#ifdef POI_SUBSURFACESCATTERING
			void applySubsurfaceScattering(in PoiCam poiCam, inout PoiLight poiLight, in PoiMesh poiMesh, in PoiFragData poiFragData)
			{
				float4 SSS = 1;
				#if defined(PROP_SSSTHICKNESSMAP) || !defined(OPTIMIZER_ENABLED)
				SSS = POI2D_SAMPLER_PAN(_SSSThicknessMap, _MainTex, poiUV(poiMesh.uv[_SSSThicknessMapUV], _SSSThicknessMap_ST), _SSSThicknessMapPan);
				SSS.a = 1 - SSS.a;
				#endif
				
				float3 vLTLight = poiLight.direction + poiMesh.normals[0] * _SSSDistortion;
				float flTDot = pow(saturate(dot(poiCam.viewDir, -vLTLight)), _SSSSpread) * _SSSStrength;
				#ifdef UNITY_PASS_FORWARDBASE
				float3 fLT = (flTDot) * saturate(SSS.a + - 1 * _SSSThicknessMod);
				#else
				float3 fLT = poiLight.additiveShadow * (flTDot) * saturate(SSS.a + - 1 * _SSSThicknessMod);
				#endif
				
				#if defined(POINT) || defined(SPOT)
				poiLight.finalLightAdd += fLT * poiLight.directColor * _SSSColor * SSS.rgb * lerp(1, poiFragData.baseColor, _SSSBaseColorMix);
				#endif
				poiLight.finalLightAdd += fLT * poiLight.directColor * _SSSColor * SSS.rgb * poiLight.attenuation * lerp(1, poiFragData.baseColor, _SSSBaseColorMix);
			}
			#endif
			//endex
			
			//ifex _MochieBRDF==0 && _ClearCoatBRDF==0
			#if defined(MOCHIE_PBR) || defined(POI_CLEARCOAT)
			
			/*
			* Copyright 2022 orels1
			*
			* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
			*
			* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
			*
			* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
			*/
			
			// https://github.com/orels1/orels-Unity-Shaders
			
			float GSAA_Filament(float3 worldNormal, float perceptualRoughness, float gsaaVariance, float gsaaThreshold)
			{
				// Kaplanyan 2016, "Stable specular highlights"
				// Tokuyoshi 2017, "Error Reduction and Simplification for Shading Anti-Aliasing"
				// Tokuyoshi and Kaplanyan 2019, "Improved Geometric Specular Antialiasing"
				
				// This implementation is meant for deferred rendering in the original paper but
				// we use it in forward rendering as well (as discussed in Tokuyoshi and Kaplanyan
				// 2019). The main reason is that the forward version requires an expensive transform
				// of the float vector by the tangent frame for every light. This is therefore an
				// approximation but it works well enough for our needs and provides an improvement
				// over our original implementation based on Vlachos 2015, "Advanced VR Rendering".
				
				float3 du = ddx(worldNormal);
				float3 dv = ddy(worldNormal);
				
				float variance = gsaaVariance * (dot(du, du) + dot(dv, dv));
				
				float roughness = perceptualRoughness * perceptualRoughness;
				float kernelRoughness = min(2.0 * variance, gsaaThreshold);
				float squareRoughness = saturate(roughness * roughness + kernelRoughness);
				
				return sqrt(sqrt(squareRoughness));
			}
			
			/*
			MIT END
			*/
			
			bool SceneHasReflections()
			{
				float width, height;
				unity_SpecCube0.GetDimensions(width, height);
				return !(width * height < 2);
			}
			
			float3 GetWorldReflections(float3 reflDir, float3 worldPos, float roughness)
			{
				float3 baseReflDir = reflDir;
				reflDir = BoxProjection(reflDir, worldPos, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax);
				float4 envSample0 = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, reflDir, roughness * UNITY_SPECCUBE_LOD_STEPS);
				float3 p0 = DecodeHDR(envSample0, unity_SpecCube0_HDR);
				float interpolator = unity_SpecCube0_BoxMin.w;
				UNITY_BRANCH
				if (interpolator < 0.99999)
				{
					float3 refDirBlend = BoxProjection(baseReflDir, worldPos, unity_SpecCube1_ProbePosition, unity_SpecCube1_BoxMin, unity_SpecCube1_BoxMax);
					float4 envSample1 = UNITY_SAMPLE_TEXCUBE_SAMPLER_LOD(unity_SpecCube1, unity_SpecCube0, refDirBlend, roughness * UNITY_SPECCUBE_LOD_STEPS);
					float3 p1 = DecodeHDR(envSample1, unity_SpecCube1_HDR);
					p0 = lerp(p1, p0, interpolator);
				}
				return p0;
			}
			
			float3 GetReflections(in PoiCam poiCam, in PoiLight pl, in PoiMesh poiMesh, float roughness, float ForceFallback, float LightFallback, samplerCUBE reflectionCube, float4 hdrData, float3 reflectionDir)
			{
				float3 reflections = 0;
				float3 lighting = pl.finalLighting;
				// This is a separate conditional so it can optimize out when ForceFallback isn't animated
				if (ForceFallback == 0)
				{
					UNITY_BRANCH
					if (SceneHasReflections())
					{
						#ifdef UNITY_PASS_FORWARDBASE
						reflections = GetWorldReflections(reflectionDir, poiMesh.worldPos.xyz, roughness);
						#endif
					}
					else
					{
						#ifdef UNITY_PASS_FORWARDBASE
						reflections = texCUBElod(reflectionCube, float4(reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
						reflections = DecodeHDR(float4(reflections, 1), hdrData) * lerp(1, pl.finalLighting, LightFallback);
						#endif
						#ifdef POI_PASS_ADD
						if (LightFallback)
						{
							reflections = texCUBElod(reflectionCube, float4(reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
							reflections = DecodeHDR(float4(reflections, 1), hdrData) * pl.finalLighting;
						}
						#endif
					}
				}
				else
				{
					#ifdef UNITY_PASS_FORWARDBASE
					reflections = texCUBElod(reflectionCube, float4(reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
					reflections = DecodeHDR(float4(reflections, 1), hdrData) * lerp(1, pl.finalLighting, LightFallback);
					#endif
					#ifdef POI_PASS_ADD
					if (LightFallback)
					{
						reflections = texCUBElod(reflectionCube, float4(reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
						reflections = DecodeHDR(float4(reflections, 1), hdrData) * pl.finalLighting;
					}
					#endif
				}
				reflections *= pl.occlusion;
				return reflections;
			}
			
			float GetGGXTerm(float nDotL, float nDotV, float nDotH, float roughness)
			{
				float visibilityTerm = 0;
				if (nDotL > 0)
				{
					float rough = roughness;
					float rough2 = roughness * roughness;
					
					float lambdaV = nDotL * (nDotV * (1 - rough) + rough);
					float lambdaL = nDotV * (nDotL * (1 - rough) + rough);
					
					visibilityTerm = 0.5f / (lambdaV + lambdaL + 1e-5f);
					float d = (nDotH * rough2 - nDotH) * nDotH + 1.0f;
					float dotTerm = UNITY_INV_PI * rough2 / (d * d + 1e-7f);
					
					visibilityTerm *= dotTerm * UNITY_PI;
				}
				return visibilityTerm;
			}
			
			void GetSpecFresTerm(float nDotL, float nDotV, float nDotH, float lDotH, inout float3 specularTerm, inout float3 fresnelTerm, float3 specCol, float roughness)
			{
				specularTerm = GetGGXTerm(nDotL, nDotV, nDotH, roughness);
				fresnelTerm = FresnelTerm(specCol, lDotH);
				specularTerm = max(0, specularTerm * max(0.00001, nDotL));
			}
			
			float GetRoughness(float smoothness)
			{
				float rough = 1 - smoothness;
				rough *= 1.7 - 0.7 * rough;
				return rough;
			}
			#endif
			//endex
			
			//ifex _MochieBRDF==0
			#ifdef MOCHIE_PBR
			void MetallicAndSpecularFragDataInit(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float smoothness = _MochieRoughnessMultiplier;
				float smoothness2 = _MochieRoughnessMultiplier2;
				float metallic = _MochieMetallicMultiplier;
				float specularMask = 1;
				float reflectionMask = 1;
				
				smoothness *= poiFragData.smoothness;
				smoothness2 *= poiFragData.smoothness2;
				metallic *= poiFragData.metallic;
				specularMask *= poiFragData.specularMask;
				reflectionMask *= poiFragData.reflectionMask;
				
				#if defined(PROP_MOCHIEMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 PBRMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_MochieMetallicMaps, _MainTex, poiUV(poiMesh.uv[_MochieMetallicMapsUV], _MochieMetallicMaps_ST), _MochieMetallicMapsPan, _MochieMetallicMapsStochastic);
				UNITY_BRANCH
				if (_PBRSplitMaskSample)
				{
					float4 PBRSplitMask = POI2D_SAMPLER_PAN_STOCHASTIC(_MochieMetallicMaps, _MainTex, poiUV(poiMesh.uv[_MochieMetallicMasksUV], _PBRMaskScaleTiling), _MochieMetallicMasksPan.xy, _PBRSplitMaskStochastic);
					assignValueToVectorFromIndex(PBRMaps, _MochieMetallicMapsReflectionMaskChannel, PBRSplitMask[_MochieMetallicMapsReflectionMaskChannel]);
					assignValueToVectorFromIndex(PBRMaps, _MochieMetallicMapsSpecularMaskChannel, PBRSplitMask[_MochieMetallicMapsSpecularMaskChannel]);
				}
				
				if (_MochieMetallicMapsMetallicChannel < 4)
				{
					metallic *= PBRMaps[_MochieMetallicMapsMetallicChannel];
				}
				if (_MochieMetallicMapsRoughnessChannel < 4)
				{
					smoothness *= PBRMaps[_MochieMetallicMapsRoughnessChannel];
					smoothness2 *= PBRMaps[_MochieMetallicMapsRoughnessChannel];
				}
				if (_MochieMetallicMapsReflectionMaskChannel < 4)
				{
					reflectionMask *= PBRMaps[_MochieMetallicMapsReflectionMaskChannel];
				}
				if (_MochieMetallicMapsSpecularMaskChannel < 4)
				{
					specularMask *= PBRMaps[_MochieMetallicMapsSpecularMaskChannel];
				}
				#endif
				
				reflectionMask *= _MochieReflectionStrength;
				specularMask *= _MochieSpecularStrength;
				
				if (_MochieMetallicMapInvert)
				{
					metallic = 1 - metallic;
				}
				if (_MochieRoughnessMapInvert)
				{
					smoothness = 1 - smoothness;
					smoothness2 = 1 - smoothness2;
				}
				if (_MochieReflectionMaskInvert)
				{
					reflectionMask = 1 - reflectionMask;
				}
				if (_MochieSpecularMaskInvert)
				{
					specularMask = 1 - specularMask;
				}
				
				poiFragData.smoothness *= smoothness;
				poiFragData.smoothness2 *= smoothness2;
				poiFragData.metallic *= metallic;
				poiFragData.specularMask *= specularMask;
				poiFragData.reflectionMask *= reflectionMask;
			}
			
			void MochieBRDF(inout PoiFragData poiFragData, in PoiCam poiCam, inout PoiLight poiLight, in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				float smoothness = poiFragData.smoothness;
				float smoothness2 = poiFragData.smoothness2;
				float metallic = poiFragData.metallic;
				float specularMask = poiFragData.specularMask;
				float reflectionMask = poiFragData.reflectionMask;
				
				if (_MochieMetallicGlobalMask > 0)
				{
					metallic = customBlend(metallic, poiMods.globalMask[_MochieMetallicGlobalMask - 1], _MochieMetallicGlobalMaskBlendType);
				}
				if (_MochieSmoothnessGlobalMask > 0)
				{
					smoothness = customBlend(smoothness, poiMods.globalMask[_MochieSmoothnessGlobalMask - 1], _MochieSmoothnessGlobalMaskBlendType);
					smoothness2 = customBlend(smoothness2, poiMods.globalMask[_MochieSmoothnessGlobalMask - 1], _MochieSmoothnessGlobalMaskBlendType);
				}
				if (_MochieReflectionStrengthGlobalMask > 0)
				{
					reflectionMask = customBlend(reflectionMask, poiMods.globalMask[_MochieReflectionStrengthGlobalMask - 1], _MochieReflectionStrengthGlobalMaskBlendType);
				}
				if (_MochieSpecularStrengthGlobalMask > 0)
				{
					specularMask = customBlend(specularMask, poiMods.globalMask[_MochieSpecularStrengthGlobalMask - 1], _MochieSpecularStrengthGlobalMaskBlendType);
				}
				
				#ifdef TPS_Penetrator
				if (_BRDFTPSDepthEnabled)
				{
					reflectionMask = lerp(0, reflectionMask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _BRDFTPSReflectionMaskStrength);
					specularMask = lerp(0, specularMask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _BRDFTPSSpecularMaskStrength);
				}
				#endif
				
				float roughness = GetRoughness(smoothness);
				float roughness2 = GetRoughness(smoothness2);
				float3 specCol = lerp(unity_ColorSpaceDielectricSpec.rgb, poiFragData.baseColor, metallic);
				float omr = unity_ColorSpaceDielectricSpec.a - metallic * unity_ColorSpaceDielectricSpec.a;
				float percepRough = 1 - smoothness;
				float percepRough2 = 1 - smoothness2;
				UNITY_BRANCH
				if (_MochieGSAAEnabled)
				{
					percepRough = GSAA_Filament(poiMesh.normals[_PBRNormalSelect], percepRough, _PoiGSAAVariance, _PoiGSAAThreshold);
					if (_Specular2ndLayer == 1 && _MochieSpecularStrength2 > 0)
					{
						percepRough2 = GSAA_Filament(poiMesh.normals[_PBRNormalSelect], percepRough2, _PoiGSAAVariance, _PoiGSAAThreshold);
					}
				}
				float brdfRoughness = percepRough * percepRough;
				brdfRoughness = max(brdfRoughness, 0.002);
				
				float brdfRoughness2 = percepRough2 * percepRough2;
				brdfRoughness2 = max(brdfRoughness2, 0.002);
				
				float3 diffuse = poiFragData.baseColor;
				float3 specular = 0;
				float3 specular2 = 0;
				float3 vSpecular = 0;
				float3 vSpecular2 = 0;
				float3 reflections = 0;
				float3 environment = 0;
				
				#if defined(POINT) || defined(SPOT)
				float attenuation = lerp(poiLight.additiveShadow, 1, _IgnoreCastedShadows);
				#else
				float attenuation = min(poiLight.nDotLSaturated, lerp(poiLight.attenuation, 1, _IgnoreCastedShadows));
				#endif
				
				float3 fresnelTerm = 1;
				float3 specularTerm = 1;
				
				float pbrNDotL = lerp(poiLight.vertexNDotL, poiLight.nDotL, _PBRNormalSelect);
				float pbrNDotV = lerp(poiLight.vertexNDotV, poiLight.nDotV, _PBRNormalSelect);
				float pbrNDotH = lerp(poiLight.vertexNDotH, poiLight.nDotH, _PBRNormalSelect);
				float3 pbrReflectionDir = lerp(poiCam.vertexReflectionDir, poiCam.reflectionDir, _PBRNormalSelect);
				
				GetSpecFresTerm(pbrNDotL, pbrNDotV, pbrNDotH, poiLight.lDotH, specularTerm, fresnelTerm, specCol, brdfRoughness);
				specular = poiLight.directColor * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _MochieSpecularTint, _MochieSpecularTintThemeIndex) * poiLight.occlusion * attenuation;
				
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					for (int index = 0; index < 4; index++)
					{
						fresnelTerm = 1;
						specularTerm = 1;
						float pbrVDotNL = lerp(poiLight.vertexVDotNL[index], poiLight.vDotNL[index], _PBRNormalSelect);
						float pbrVDotNH = lerp(poiLight.vertexVDotNH[index], poiLight.vDotNH[index], _PBRNormalSelect);
						GetSpecFresTerm(pbrVDotNL, pbrNDotV, pbrVDotNH, poiLight.vDotLH[index], specularTerm, fresnelTerm, specCol, brdfRoughness);
						vSpecular += poiLight.vColor[index] * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _MochieSpecularTint, _MochieSpecularTintThemeIndex) * poiLight.occlusion;
					}
					#endif
				}
				
				if (_Specular2ndLayer == 1)
				{
					float3 fresnelTerm = 1;
					float3 specularTerm = 1;
					GetSpecFresTerm(pbrNDotL, pbrNDotV, pbrNDotH, poiLight.lDotH, specularTerm, fresnelTerm, specCol, brdfRoughness2);
					specular2 = poiLight.directColor * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _MochieSpecularTint, _MochieSpecularTintThemeIndex) * poiLight.occlusion * attenuation * _MochieSpecularStrength2;
					
					if (poiFragData.toggleVertexLights)
					{
						#if defined(VERTEXLIGHT_ON)
						for (int index = 0; index < 4; index++)
						{
							fresnelTerm = 1;
							specularTerm = 1;
							float pbrVDotNL = lerp(poiLight.vertexVDotNL[index], poiLight.vDotNL[index], _PBRNormalSelect);
							float pbrVDotNH = lerp(poiLight.vertexVDotNH[index], poiLight.vDotNH[index], _PBRNormalSelect);
							GetSpecFresTerm(pbrVDotNL, pbrNDotV, pbrVDotNH, poiLight.vDotLH[index], specularTerm, fresnelTerm, specCol, brdfRoughness2);
							vSpecular2 += poiLight.vColor[index] * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _MochieSpecularTint, _MochieSpecularTintThemeIndex) * poiLight.occlusion * _MochieSpecularStrength2;
						}
						#endif
					}
				}
				
				float surfaceReduction = (1.0 / (brdfRoughness * brdfRoughness + 1.0));
				float grazingTerm = saturate(smoothness + (1 - omr));
				float3 reflCol = GetReflections(poiCam, poiLight, poiMesh, roughness, _MochieForceFallback, _MochieLitFallback, _MochieReflCube, _MochieReflCube_HDR, pbrReflectionDir);
				if (poiMesh.isFrontFace)
				{
					reflections = surfaceReduction * reflCol * lerp(1, FresnelLerp(specCol, grazingTerm, pbrNDotV), _RefSpecFresnel);
				}
				else
				{
					reflections = surfaceReduction * reflCol * lerp(1, FresnelLerp(specCol, grazingTerm, pbrNDotV), _RefSpecFresnelBack);
				}
				
				reflections *= poiThemeColor(poiMods, _MochieReflectionTint, _MochieReflectionTintThemeIndex);
				reflections *= reflectionMask;
				diffuse = lerp(diffuse, diffuse * omr, reflectionMask);
				
				environment = max(specular + vSpecular, specular2 + vSpecular2);
				environment += reflections;
				diffuse *= poiLight.finalLighting;
				poiFragData.finalColor = diffuse;
				poiLight.finalLightAdd += environment;
			}
			#endif
			//endex
			//ifex _ClearCoatBRDF==0
			#ifdef POI_CLEARCOAT
			void poiClearCoat(inout PoiFragData poiFragData, in PoiCam poiCam, inout PoiLight poiLight, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float clearCoatMask = _ClearCoatStrength;
				float smoothness = _ClearCoatSmoothness;
				float reflectionMask = _ClearCoatReflectionStrength;
				float specularMask = _ClearCoatSpecularStrength;
				
				#if defined(PROP_CLEARCOATMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 PBRMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_ClearCoatMaps, _MainTex, poiUV(poiMesh.uv[_ClearCoatMapsUV], _ClearCoatMaps_ST), _ClearCoatMapsPan, _ClearCoatMapsStochastic);
				
				if (_ClearCoatMapsClearCoatMaskChannel < 4)
				{
					clearCoatMask *= PBRMaps[_ClearCoatMapsClearCoatMaskChannel];
				}
				if (_ClearCoatMapsRoughnessChannel < 4)
				{
					smoothness *= PBRMaps[_ClearCoatMapsRoughnessChannel];
				}
				if (_ClearCoatMapsReflectionMaskChannel < 4)
				{
					reflectionMask *= PBRMaps[_ClearCoatMapsReflectionMaskChannel];
				}
				if (_ClearCoatMapsSpecularMaskChannel < 4)
				{
					specularMask *= PBRMaps[_ClearCoatMapsSpecularMaskChannel];
				}
				#endif
				
				if (_ClearCoatGlobalMask > 0)
				{
					clearCoatMask = customBlend(clearCoatMask, poiMods.globalMask[_ClearCoatGlobalMask - 1], _ClearCoatGlobalMaskBlendType);
				}
				if (_ClearCoatSmoothnessGlobalMask > 0)
				{
					smoothness = customBlend(smoothness, poiMods.globalMask[_ClearCoatSmoothnessGlobalMask - 1], _ClearCoatSmoothnessGlobalMaskBlendType);
				}
				if (_ClearCoatReflectionStrengthGlobalMask > 0)
				{
					reflectionMask = customBlend(reflectionMask, poiMods.globalMask[_ClearCoatReflectionStrengthGlobalMask - 1], _ClearCoatReflectionStrengthGlobalMaskBlendType);
				}
				if (_ClearCoatSpecularStrengthGlobalMask > 0)
				{
					specularMask = customBlend(specularMask, poiMods.globalMask[_ClearCoatSpecularStrengthGlobalMask - 1], _ClearCoatSpecularStrengthGlobalMaskBlendType);
				}
				
				if (_ClearCoatMaskInvert)
				{
					clearCoatMask = 1 - clearCoatMask;
				}
				if (_ClearCoatSmoothnessMapInvert)
				{
					smoothness = 1 - smoothness;
				}
				if (_ClearCoatReflectionMaskInvert)
				{
					reflectionMask = 1 - reflectionMask;
				}
				if (_ClearCoatSpecularMaskInvert)
				{
					specularMask = 1 - specularMask;
				}
				#ifdef TPS_Penetrator
				if (_ClearCoatTPSDepthMaskEnabled)
				{
					clearCoatMask = lerp(0, clearCoatMask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _ClearCoatTPSMaskStrength);
				}
				#endif
				
				float roughness = GetRoughness(smoothness);
				float3 specCol = 0.220916301;
				float omr = unity_ColorSpaceDielectricSpec.a;
				float percepRough = 1 - smoothness;
				UNITY_BRANCH
				if (_ClearCoatGSAAEnabled)
				{
					percepRough = GSAA_Filament(poiMesh.normals[_ClearCoatNormalSelect], percepRough, _ClearCoatGSAAVariance, _ClearCoatGSAAThreshold);
				}
				float brdfRoughness = percepRough * percepRough;
				brdfRoughness = max(brdfRoughness, 0.002);
				
				float3 diffuse = 0;
				float3 specular = 0;
				float3 vSpecular = 0;
				float3 reflections = 0;
				float3 environment = 0;
				float attenuation = min(poiLight.nDotLSaturated, lerp(poiLight.attenuation, 1, _CCIgnoreCastedShadows));
				
				float3 fresnelTerm = 1;
				float3 specularTerm = 1;
				
				float clearcoatNDotL = lerp(poiLight.vertexNDotL, poiLight.nDotL, _ClearCoatNormalSelect);
				float clearcoatNDotV = lerp(poiLight.vertexNDotV, poiLight.nDotV, _ClearCoatNormalSelect);
				float clearcoatNDotH = lerp(poiLight.vertexNDotH, poiLight.nDotH, _ClearCoatNormalSelect);
				float3 clearcoatReflectionDir = lerp(poiCam.vertexReflectionDir, poiCam.reflectionDir, _ClearCoatNormalSelect);
				
				GetSpecFresTerm(clearcoatNDotL, clearcoatNDotV, clearcoatNDotH, poiLight.lDotH, specularTerm, fresnelTerm, specCol, brdfRoughness);
				specular = poiLight.directColor * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _ClearCoatSpecularTint, _ClearCoatSpecularTintThemeIndex) * poiLight.occlusion * attenuation;
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					for (int index = 0; index < 4; index++)
					{
						fresnelTerm = 1;
						specularTerm = 1;
						float clearcoatVDotNL = lerp(poiLight.vertexVDotNL[index], poiLight.vDotNL[index], _ClearCoatNormalSelect);
						float clearcoatVDotNH = lerp(poiLight.vertexVDotNH[index], poiLight.vDotNH[index], _ClearCoatNormalSelect);
						GetSpecFresTerm(clearcoatVDotNL, clearcoatNDotV, clearcoatVDotNH, poiLight.vDotLH[index], specularTerm, fresnelTerm, specCol, brdfRoughness);
						vSpecular += poiLight.vColor[index] * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _ClearCoatSpecularTint, _ClearCoatSpecularTintThemeIndex) * poiLight.occlusion;
					}
					#endif
				}
				
				float surfaceReduction = (1.0 / (brdfRoughness * brdfRoughness + 1.0));
				float grazingTerm = saturate(smoothness + (1 - omr));
				float3 reflCol = GetReflections(poiCam, poiLight, poiMesh, roughness, _ClearCoatForceFallback, _ClearCoatLitFallback, _ClearCoatFallback, _ClearCoatFallback_HDR, clearcoatReflectionDir);
				reflections = surfaceReduction * reflCol * lerp(1, FresnelLerp(specCol, grazingTerm, clearcoatNDotV), _ClearcoatFresnel);
				reflections *= poiThemeColor(poiMods, _ClearCoatReflectionTint, _ClearCoatReflectionTintThemeIndex) * reflectionMask;
				diffuse = lerp(diffuse, diffuse * omr, reflectionMask);
				
				environment = specular + vSpecular;
				#ifdef UNITY_PASS_FORWARDBASE
				environment += reflections;
				#endif
				//diffuse *= poiLight.finalLighting;
				diffuse += environment;
				poiLight.finalLightAdd += saturate(diffuse * clearCoatMask);
			}
			#endif
			//endex
			
			//ifex _EnableEnvironmentalRim==0
			#ifdef POI_ENVIRORIM
			void applyEnvironmentRim(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam)
			{
				float enviroRimAlpha = saturate(1 - smoothstep(min(_RimEnviroSharpness, _RimEnviroWidth), _RimEnviroWidth, poiCam.vDotN));
				_RimEnviroBlur *= 1.7 - 0.7 * _RimEnviroBlur;
				
				float3 enviroRimColor = 0;
				float interpolator = unity_SpecCube0_BoxMin.w;
				UNITY_BRANCH
				if (interpolator < 0.99999)
				{
					//Probe 1
					float4 reflectionData0 = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, poiMesh.normals[1], _RimEnviroBlur * UNITY_SPECCUBE_LOD_STEPS);
					float3 reflectionColor0 = DecodeHDR(reflectionData0, unity_SpecCube0_HDR);
					
					//Probe 2
					float4 reflectionData1 = UNITY_SAMPLE_TEXCUBE_SAMPLER_LOD(unity_SpecCube1, unity_SpecCube0, poiMesh.normals[1], _RimEnviroBlur * UNITY_SPECCUBE_LOD_STEPS);
					float3 reflectionColor1 = DecodeHDR(reflectionData1, unity_SpecCube1_HDR);
					
					enviroRimColor = lerp(reflectionColor1, reflectionColor0, interpolator);
				}
				else
				{
					float4 reflectionData = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, poiMesh.normals[1], _RimEnviroBlur * UNITY_SPECCUBE_LOD_STEPS);
					enviroRimColor = DecodeHDR(reflectionData, unity_SpecCube0_HDR);
				}
				
				half enviroMask = 1;
				#if defined(PROP_RIMENVIROMASK) || !defined(OPTIMIZER_ENABLED)
				enviroMask = POI2D_SAMPLER_PAN(_RimEnviroMask, _MainTex, poiMesh.uv[_RimEnviroMaskUV], _RimEnviroMaskPan)[_RimEnviroChannel];
				#endif
				float3 envRimCol = lerp(0, max(0, (enviroRimColor - _RimEnviroMinBrightness) * poiFragData.baseColor), enviroRimAlpha).rgb * enviroMask * _RimEnviroIntensity;
				poiFragData.finalColor += envRimCol;
			}
			#endif
			//endex
			
			//ifex _StylizedSpecular==0
			#ifdef POI_STYLIZED_StylizedSpecular
			void stylizedSpecular(inout PoiFragData poiFragData, in PoiCam poiCam, inout PoiLight poiLight, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float specArea = 0.5 * poiLight.nDotH + 0.5;
				#if defined(PROP_HIGHCOLOR_TEX) || !defined(OPTIMIZER_ENABLED)
				float3 specularMap = POI2D_SAMPLER_PAN(_HighColor_Tex, _MainTex, poiUV(poiMesh.uv[_HighColor_TexUV], _HighColor_Tex_ST), _HighColor_TexPan);
				#else
				float3 specularMap = 1;
				#endif
				
				// Spec 1
				float specMask1 = 0;
				float specMask2 = 0;
				if (_Is_SpecularToHighColor)
				{
					specMask1 += pow(specArea, exp2(lerp(11, 1, _HighColor_Power))) * _Layer1Strength;
					specMask2 += pow(specArea, exp2(lerp(11, 1, _Layer2Size))) * _Layer2Strength;
				}
				else
				{
					specMask1 += poiEdgeNonLinear(specArea, (1.0 - pow(_HighColor_Power, 5)), _StylizedSpecularFeather) * _Layer1Strength;
					specMask2 += poiEdgeNonLinear(specArea, (1.0 - pow(_Layer2Size, 5)), _StylizedSpecular2Feather) * _Layer2Strength;
				}
				
				#if defined(PROP_SET_HIGHCOLORMASK) || !defined(OPTIMIZER_ENABLED)
				float specularMask = POI2D_SAMPLER_PAN(_Set_HighColorMask, _MainTex, poiUV(poiMesh.uv[_Set_HighColorMaskUV], _Set_HighColorMask_ST), _Set_HighColorMaskPan)[_Set_HighColorMaskChannel];
				#else
				float specularMask = 1;
				#endif
				
				specularMask = saturate(specularMask + _Tweak_HighColorMaskLevel);
				
				float specMask = saturate(specMask1 + specMask2) * specularMask * lerp(poiLight.rampedLightMap, 1, _StylizedSpecularIgnoreShadow);
				float attenuation = min(lerp(poiLight.nDotLSaturated, 1, _StylizedSpecularIgnoreNormal), lerp(lerp(poiLight.attenuation, 1, _SSIgnoreCastedShadows), 1, _StylizedSpecularIgnoreShadow));
				#ifdef POI_PASS_ADD
				attenuation *= lerp(poiLight.additiveShadow, 1, _SSIgnoreCastedShadows);
				#endif
				
				float finalSpecMask = min(min(specMask, poiLight.occlusion), attenuation) * _StylizedSpecularStrength;
				switch(_Is_BlendAddToHiColor)
				{
					case 0:
					// Replace
					poiFragData.baseColor = lerp(poiFragData.baseColor, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.directColor, _UseLightColor), finalSpecMask);
					break;
					case 1:
					// Add
					poiLight.finalLightAdd += max(0, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.directColor, _UseLightColor) * finalSpecMask);
					break;
					case 2:
					// Screen
					poiFragData.baseColor = lerp(poiFragData.baseColor, blendScreen(poiFragData.baseColor, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.directColor, _UseLightColor)), finalSpecMask);
					break;
					case 3:
					// Multiply
					poiFragData.baseColor = lerp(poiFragData.baseColor, poiFragData.baseColor * specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.directColor, _UseLightColor), finalSpecMask);
					break;
				}
				
				//poiFragData.baseColor = _StylizedSpecularStrength;
				
				float3 vSpecMask = 0;
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					for (int index = 0; index < 4; index++)
					{
						if (!any(poiLight.vPosition[index])) continue;
						specArea = 0.5 * poiLight.vDotNH[index] + 0.5;
						if (_Is_SpecularToHighColor)
						{
							vSpecMask = pow(specArea, exp2(lerp(11, 1, _HighColor_Power))) * _Layer1Strength * poiLight.vAttenuation[index];
							vSpecMask = max(vSpecMask, pow(specArea, exp2(lerp(11, 1, _Layer2Size))) * _Layer2Strength * poiLight.vAttenuation[index]);
						}
						else
						{
							vSpecMask = poiEdgeNonLinear(specArea, (1.0 - pow(_HighColor_Power, 5)), _StylizedSpecularFeather) * _Layer1Strength * poiLight.vAttenuation[index];
							vSpecMask = max(vSpecMask, poiEdgeNonLinear(specArea, (1.0 - pow(_Layer2Size, 5)), _StylizedSpecular2Feather) * _Layer2Strength * poiLight.vAttenuation[index]);
						}
						
						vSpecMask *= specularMask;
						float finalSpecMask = min(min(vSpecMask, poiLight.occlusion), attenuation) * _StylizedSpecularStrength;
						switch(_Is_BlendAddToHiColor)
						{
							case 0:
							// Replace
							poiFragData.baseColor = lerp(poiFragData.baseColor, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.vColor[index], _UseLightColor), finalSpecMask);
							break;
							case 1:
							// Add
							poiLight.finalLightAdd += max(0, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.vColor[index], _UseLightColor) * finalSpecMask);
							break;
							case 2:
							// Screen
							poiFragData.baseColor = lerp(poiFragData.baseColor, blendScreen(poiFragData.baseColor, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.vColor[index], _UseLightColor)), finalSpecMask);
							break;
							case 3:
							// Multiply
							poiFragData.baseColor = lerp(poiFragData.baseColor, poiFragData.baseColor * specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.vColor[index], _UseLightColor), finalSpecMask);
							break;
						}
					}
					#endif
				}
			}
			#endif
			//endex
			
			//ifex _EnablePathing==0
			#ifdef POI_PATHING
			void applyPathing(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float3 albedo = poiFragData.baseColor;
				float3 pathEmission;
				#if defined(PROP_PATHINGMAP) || !defined(OPTIMIZER_ENABLED)
				float4 path = _PathingMap.Sample(SmpRepeatPoint, poiUV(poiMesh.uv[_PathingMapUV], _PathingMap_ST) + _PathingMapPan.xy * _Time.x);
				#else
				float4 path = float4(1, 1, 1, 1);
				#endif
				float4 PathColor[4];
				half pathAudioLinkPathTimeOffsetBand[4] = {
					0, 0, 0, 0
				};
				half2 pathAudioLinkTimeOffset[4] = {
					half2(0, 0), half2(0, 0), half2(0, 0), half2(0, 0)
				};
				half pathAudioLinkPathWidthOffsetBand[4] = {
					0, 0, 0, 0
				};
				half2 pathAudioLinkWidthOffset[4] = {
					half2(0, 0), half2(0, 0), half2(0, 0), half2(0, 0)
				};
				PathColor[0] = _PathColorR;
				PathColor[1] = _PathColorG;
				PathColor[2] = _PathColorB;
				PathColor[3] = _PathColorA;
				
				// Combined data
				if (_PathGradientType == 1)
				{
					path = (path.r + path.g + path.b + path.a) * .25;
				}
				
				#if defined(PROP_PATHINGCOLORMAP) || !defined(OPTIMIZER_ENABLED)
				float4 pathColorMap = POI2D_SAMPLER_PAN(_PathingColorMap, _MainTex, poiUV(poiMesh.uv[_PathingColorMapUV], _PathingColorMap_ST), _PathingColorMapPan);
				#else
				float4 pathColorMap = float4(1, 1, 1, 1);
				#endif
				
				float4 pathAudioLinkEmission = 0;
				float4 pathTime = 0;
				float3 pathAlpha[4] = {
					float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0)
				};
				
				#ifdef POI_AUDIOLINK
				float4 chronoType = float4(_PathChronoTypeR, _PathChronoTypeG, _PathChronoTypeB, _PathChronoTypeA);
				float4 chronoBand = float4(_PathChronoBandR, _PathChronoBandG, _PathChronoBandB, _PathChronoBandA);
				float4 chronoSpeed = float4(_PathChronoSpeedR, _PathChronoSpeedG, _PathChronoSpeedB, _PathChronoSpeedA);
				float3 autoCorrelator[4] = {
					float3(_PathALAutoCorrelatorR, _PathALAutoCorrelatorRangeR[0], _PathALAutoCorrelatorRangeR[1]), float3(_PathALAutoCorrelatorG, _PathALAutoCorrelatorRangeG[0], _PathALAutoCorrelatorRangeG[1]),
					float3(_PathALAutoCorrelatorB, _PathALAutoCorrelatorRangeB[0], _PathALAutoCorrelatorRangeB[1]), float3(_PathALAutoCorrelatorA, _PathALAutoCorrelatorRangeA[0], _PathALAutoCorrelatorRangeA[1])
				};
				float4 history[4] = {
					float4(_PathALHistoryR, _PathALHistoryBandR, _PathALHistoryRangeR[0], _PathALHistoryRangeR[1]), float4(_PathALHistoryG, _PathALHistoryBandG, _PathALHistoryRangeG[0], _PathALHistoryRangeG[1]),
					float4(_PathALHistoryB, _PathALHistoryBandB, _PathALHistoryRangeB[0], _PathALHistoryRangeB[1]), float4(_PathALHistoryA, _PathALHistoryBandA, _PathALHistoryRangeA[0], _PathALHistoryRangeA[1])
				};
				
				if (poiMods.audioLinkAvailable)
				{
					if (_PathALTimeOffset)
					{
						pathAudioLinkPathTimeOffsetBand[0] = _AudioLinkPathTimeOffsetBandR;
						pathAudioLinkPathTimeOffsetBand[1] = _AudioLinkPathTimeOffsetBandG;
						pathAudioLinkPathTimeOffsetBand[2] = _AudioLinkPathTimeOffsetBandB;
						pathAudioLinkPathTimeOffsetBand[3] = _AudioLinkPathTimeOffsetBandA;
						pathAudioLinkTimeOffset[0] = _AudioLinkPathTimeOffsetR.xy;
						pathAudioLinkTimeOffset[1] = _AudioLinkPathTimeOffsetG.xy;
						pathAudioLinkTimeOffset[2] = _AudioLinkPathTimeOffsetB.xy;
						pathAudioLinkTimeOffset[3] = _AudioLinkPathTimeOffsetA.xy;
					}
					
					if (_PathALWidthOffset)
					{
						pathAudioLinkPathWidthOffsetBand[0] = _AudioLinkPathWidthOffsetBandR;
						pathAudioLinkPathWidthOffsetBand[1] = _AudioLinkPathWidthOffsetBandG;
						pathAudioLinkPathWidthOffsetBand[2] = _AudioLinkPathWidthOffsetBandB;
						pathAudioLinkPathWidthOffsetBand[3] = _AudioLinkPathWidthOffsetBandA;
						pathAudioLinkWidthOffset[0] = _AudioLinkPathWidthOffsetR.xy;
						pathAudioLinkWidthOffset[1] = _AudioLinkPathWidthOffsetG.xy;
						pathAudioLinkWidthOffset[2] = _AudioLinkPathWidthOffsetB.xy;
						pathAudioLinkWidthOffset[3] = _AudioLinkPathWidthOffsetA.xy;
					}
					// Emission Offset
					if (_PathALEmissionOffset)
					{
						pathAudioLinkEmission.r += lerp(_AudioLinkPathEmissionAddR.x, _AudioLinkPathEmissionAddR.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandR]);
						pathAudioLinkEmission.g += lerp(_AudioLinkPathEmissionAddG.x, _AudioLinkPathEmissionAddG.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandG]);
						pathAudioLinkEmission.b += lerp(_AudioLinkPathEmissionAddB.x, _AudioLinkPathEmissionAddB.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandB]);
						pathAudioLinkEmission.a += lerp(_AudioLinkPathEmissionAddA.x, _AudioLinkPathEmissionAddA.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandA]);
					}
					
					if(_PathALColorChord)
					{
						if (_PathALCCR)
						{
							PathColor[0] *= AudioLinkLerp(ALPASS_CCSTRIP + float2(path[0] * AUDIOLINK_WIDTH, 0));
						}
						if (_PathALCCG)
						{
							PathColor[1] *= AudioLinkLerp(ALPASS_CCSTRIP + float2(path[1] * AUDIOLINK_WIDTH, 0));
						}
						if (_PathALCCB)
						{
							PathColor[2] *= AudioLinkLerp(ALPASS_CCSTRIP + float2(path[2] * AUDIOLINK_WIDTH, 0));
						}
						if (_PathALCCA)
						{
							PathColor[3] *= AudioLinkLerp(ALPASS_CCSTRIP + float2(path[3] * AUDIOLINK_WIDTH, 0));
						}
					}
				}
				#endif
				
				[unroll]
				for (int index = 0; index < 4; index++)
				{
					float timeOffset = 0;
					#ifdef POI_AUDIOLINK
					UNITY_BRANCH
					if (poiMods.audioLinkAvailable)
					{
						if (_PathALTimeOffset)
						{
							timeOffset += lerp(pathAudioLinkTimeOffset[index].x, pathAudioLinkTimeOffset[index].y, poiMods.audioLink[pathAudioLinkPathTimeOffsetBand[index]]);
						}
						
						if (_PathALChrono)
						{
							timeOffset += AudioLinkGetChronoTime(chronoType[index], chronoBand[index]) * chronoSpeed[index];
						}
					}
					#endif
					pathTime[index] = _PathTime[index] != -999.0f ? frac(_PathTime[index] + _PathOffset[index] + timeOffset) : frac(_Time.x * _PathSpeed[index] + _PathOffset[index] + timeOffset);
					
					if (_PathSegments[index])
					{
						float pathSegments = abs(_PathSegments[index]);
						pathTime = (ceil(pathTime * pathSegments) - .5) / pathSegments;
					}
					
					if (path[index])
					{
						// Cutting it in half because it goes out in both directions for now
						half pathWidth = _PathWidth[index] * .5;
						#ifdef POI_AUDIOLINK
						UNITY_BRANCH
						if (poiMods.audioLinkAvailable)
						{
							if (_PathALWidthOffset)
							{
								pathWidth += lerp(pathAudioLinkWidthOffset[index].x, pathAudioLinkWidthOffset[index].y, poiMods.audioLink[pathAudioLinkPathWidthOffsetBand[index]]);
							}
						}
						#endif
						
						//fill
						pathAlpha[index].x = pathTime[index] > path[index];
						//path
						pathAlpha[index].y = saturate((1 - abs(lerp(-pathWidth, 1 + pathWidth, pathTime[index]) - path[index])) - (1 - pathWidth)) * (1 / pathWidth);
						//loop
						pathAlpha[index].z = saturate((1 - distance(pathTime[index], path[index])) - (1 - pathWidth)) * (1 / pathWidth);
						pathAlpha[index].z += saturate(distance(pathTime[index], path[index]) - (1 - pathWidth)) * (1 / pathWidth);
						pathAlpha[index] = smoothstep(0, _PathSoftness[index] + .00001, pathAlpha[index]);
						
						#ifdef POI_AUDIOLINK
						if (poiMods.audioLinkAvailable)
						{
							if (_PathALHistory && history[index][0])
							{
								// history[index]: [0]: on/off, [1]: band, [2]/[3] min/max
								float historyUV = lerp(history[index][2], history[index][3], path[index]);
								
								if (_PathSegments[index])
								{
									float pathSegments = abs(_PathSegments[index]);
									historyUV = (ceil(historyUV * pathSegments) - .5) / pathSegments;
								}
								
								historyUV *= AUDIOLINK_WIDTH;
								
								float historyValue = AudioLinkLerp(ALPASS_AUDIOLINK + float2(historyUV, history[index][1]))[0];
								
								if(_PathALHistoryMode == 0) // Mask
								pathAlpha[index] *= historyValue;
								else // Override
								pathAlpha[index] = historyValue;
							}
							
							if (_PathALAutoCorrelator && autoCorrelator[index][0] != 0)
							{
								// autoCorrelator[index]: [0]: on/off, [1]/[2]: min/max
								// Choose from only part of the autocorrelator
								float autoCorrelatorUV = lerp(autoCorrelator[index][1], autoCorrelator[index][2], path[index]);
								if (autoCorrelator[index][0] == 2) // Mirror
								{
									autoCorrelatorUV = abs(1. - autoCorrelatorUV * 2.);
								}
								
								if (_PathSegments[index])
								{
									float pathSegments = abs(_PathSegments[index]);
									autoCorrelatorUV = (ceil(autoCorrelatorUV * pathSegments) - .5) / pathSegments;
								}
								
								// Normalize Autocorrelator Value
								float autoCorrelatorValue = AudioLinkLerp(ALPASS_AUTOCORRELATOR + float2(autoCorrelatorUV * AUDIOLINK_WIDTH, 0))[0];
								float autoCorrelatorMax = AudioLinkLerp(ALPASS_AUTOCORRELATOR);
								autoCorrelatorValue = saturate(abs(autoCorrelatorValue) * rcp(autoCorrelatorMax));
								
								// Autocorrelator is normalized, so can look weird at lower volume levels. use Filtered VU intensity to make it smoothly fall off at low volume levels.
								float4 vu = AudioLinkData(ALPASS_FILTEREDVU_INTENSITY + uint2(0, 0));
								autoCorrelatorValue *= smoothstep(0.01, 0.2, vu);
								
								if(_PathALAutoCorrelatorMode == 0) // Mask
								pathAlpha[index] *= autoCorrelatorValue;
								else // Override
								pathAlpha[index] = autoCorrelatorValue;
								
							}
						}
						#endif
					}
				}
				
				// Emission
				pathEmission = 0;
				pathEmission += pathAlpha[0][_PathTypeR] * poiThemeColor(poiMods, PathColor[0].rgb, _PathColorRThemeIndex) * (_PathEmissionStrength[0] + pathAudioLinkEmission.r);
				pathEmission += pathAlpha[1][_PathTypeG] * poiThemeColor(poiMods, PathColor[1].rgb, _PathColorGThemeIndex) * (_PathEmissionStrength[1] + pathAudioLinkEmission.g);
				pathEmission += pathAlpha[2][_PathTypeB] * poiThemeColor(poiMods, PathColor[2].rgb, _PathColorBThemeIndex) * (_PathEmissionStrength[2] + pathAudioLinkEmission.b);
				pathEmission += pathAlpha[3][_PathTypeA] * poiThemeColor(poiMods, PathColor[3].rgb, _PathColorAThemeIndex) * (_PathEmissionStrength[3] + pathAudioLinkEmission.a);
				pathEmission *= pathColorMap.rgb * pathColorMap.a;
				
				float3 colorReplace = 0;
				colorReplace = pathAlpha[0][_PathTypeR] * poiThemeColor(poiMods, PathColor[0].rgb, _PathColorRThemeIndex) * pathColorMap.rgb;
				albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * PathColor[0].a * pathAlpha[0][_PathTypeR]);
				colorReplace = pathAlpha[1][_PathTypeG] * poiThemeColor(poiMods, PathColor[1].rgb, _PathColorGThemeIndex) * pathColorMap.rgb;
				albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * PathColor[1].a * pathAlpha[1][_PathTypeG]);
				colorReplace = pathAlpha[2][_PathTypeB] * poiThemeColor(poiMods, PathColor[2].rgb, _PathColorBThemeIndex) * pathColorMap.rgb;
				albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * PathColor[2].a * pathAlpha[2][_PathTypeB]);
				colorReplace = pathAlpha[3][_PathTypeA] * poiThemeColor(poiMods, PathColor[3].rgb, _PathColorAThemeIndex) * pathColorMap.rgb;
				albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * PathColor[3].a * pathAlpha[3][_PathTypeA]);
				
				float alpha = max(max(max(pathAlpha[0][_PathTypeR], pathAlpha[1][_PathTypeG]), pathAlpha[2][_PathTypeB]), pathAlpha[3][_PathTypeA]);
				
				poiFragData.alpha *= lerp(1, alpha, _PathingOverrideAlpha);
				poiFragData.baseColor = albedo.rgb;
				poiFragData.emission += pathEmission;
			}
			#endif
			//endex
			
			//ifex _EnableMirrorOptions==0
			#ifdef POI_MIRROR
			void applyMirror(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float inMirror = 0;
				// VRC
				if (_VisibilityMode == 1)
				{
					inMirror = VRCMirrorMode() > 0;
				}
				// Generic (CVR, etc)
				else
				{
					inMirror = IsInMirror();
				}
				
				#if (defined(POI_PASS_BASE) || defined(POI_PASS_ADD))
				#if defined(PROP_MIRRORTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 mirrorTexture = POI2D_SAMPLER_PAN(_MirrorTexture, _MainTex, poiUV(poiMesh.uv[_MirrorTextureUV], _MirrorTexture_ST), _MirrorTexturePan);
				if (inMirror && _MirrorTextureEnabled || _MirrorTextureForceEnabled)
				{
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, mirrorTexture.rgb, _MirrorTextureBlendType), mirrorTexture.a * _MirrorColor.a);
					poiFragData.baseColor.rgb *= lerp(1, poiThemeColor(poiMods, _MirrorColor.rgb, _MirrorColorThemeIndex), _MirrorColor.a);
				}
				#else
				if (inMirror && _MirrorTextureEnabled || _MirrorTextureForceEnabled)
				{
					poiFragData.baseColor.rgb *= lerp(1, poiThemeColor(poiMods, _MirrorColor.rgb, _MirrorColorThemeIndex), _MirrorColor.a);
				}
				#endif
				#endif
			}
			#endif
			//endex
			
			//ifex _EnableTouchGlow==0
			#ifdef GRAIN
			void applyDepthFX(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float3 touchEmission = 0;
				
				float perspectiveDivide = 1.0f / poiCam.clipPos.w;
				float4 direction = poiCam.worldDirection * perspectiveDivide;
				float2 screenPos = poiCam.posScreenSpace * perspectiveDivide;
				float z = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, screenPos);
				
				#if UNITY_REVERSED_Z
				if (z == 0)
				#else
				if (z == 1)
				#endif
				return;
				
				float depth = CorrectedLinearEyeDepth(z, direction.w);
				float3 worldpos = direction * depth + _WorldSpaceCameraPos.xyz;
				/*
				finalColor.rgb = frac(worldpos);
				return;
				*/
				
				float diff = distance(worldpos, poiMesh.worldPos);
				//poiFragData.finalColor = diff;
				
				#if defined(PROP_DEPTHMASK) || !defined(OPTIMIZER_ENABLED)
				float depthMask = POI2D_SAMPLER_PAN(_DepthMask, _MainTex, poiUV(poiMesh.uv[_DepthMaskUV], _DepthMask_ST), _DepthMaskPan)[_DepthMaskChannel];
				#else
				float depthMask = 1;
				#endif
				
				if (_DepthMaskGlobalMask > 0)
				{
					depthMask = maskBlend(depthMask, poiMods.globalMask[_DepthMaskGlobalMask - 1], _DepthMaskGlobalMaskBlendType);
				}
				
				if (_DepthColorToggle)
				{
					float colorBlendAlpha = lerp(_DepthColorMinValue, _DepthColorMaxValue, remapClamped(_DepthColorMinDepth, _DepthColorMaxDepth, diff));
					
					#if defined(PROP_DEPTHTEXTURE) || !defined(OPTIMIZER_ENABLED)
					float2 depthTextureUV = float2(0, 0);
					if (_DepthTextureUV == 8)
					{
						depthTextureUV = lerp(0, 1, remapClamped(_DepthColorMinDepth, _DepthColorMaxDepth, diff));
					}
					else
					{
						depthTextureUV = poiMesh.uv[_DepthTextureUV];
					}
					float3 depthColor = POI2D_SAMPLER_PAN(_DepthTexture, _MainTex, poiUV(depthTextureUV, _DepthTexture_ST), _DepthTexturePan).rgb * poiThemeColor(poiMods, _DepthColor, _DepthColorThemeIndex);
					#else
					float3 depthColor = poiThemeColor(poiMods, _DepthColor, _DepthColorThemeIndex);
					#endif
					
					switch(_DepthColorBlendMode)
					{
						case 0:
						{
							poiFragData.baseColor = lerp(poiFragData.baseColor, depthColor, colorBlendAlpha * depthMask);
							break;
						}
						case 1:
						{
							poiFragData.baseColor *= lerp(1, depthColor, colorBlendAlpha * depthMask);
							break;
						}
						case 2:
						{
							poiFragData.baseColor = saturate(poiFragData.baseColor + lerp(0, depthColor, colorBlendAlpha * depthMask));
							break;
						}
					}
					poiFragData.emission += depthColor * colorBlendAlpha * _DepthEmissionStrength * depthMask;
				}
				
				if (_DepthAlphaToggle)
				{
					poiFragData.alpha *= lerp(poiFragData.alpha, saturate(lerp(_DepthAlphaMinValue, _DepthAlphaMaxValue, remapClamped(_DepthAlphaMinDepth, _DepthAlphaMaxDepth, diff))), depthMask);
				}
			}
			#endif
			//endex
			
			//ifex _TextEnabled==0
			#ifdef EFFECT_BUMP
			
			float2 TransformUV(float2 offset, float rotation, float2 scale, float2 uv)
			{
				float theta = radians(rotation);
				scale = 1 - scale;
				float cs = cos(theta);
				float sn = sin(theta);
				float2 centerPoint = offset + .5;
				uv = float2((uv.x - centerPoint.x) * cs - (uv.y - centerPoint.y) * sn + centerPoint.x, (uv.x - centerPoint.x) * sn + (uv.y - centerPoint.y) * cs + centerPoint.y);
				
				return remap(uv, float2(0, 0) + offset + (scale * .5), float2(1, 1) + offset - (scale * .5), float2(0, 0), float2(1, 1));
			}
			
			float2 getAsciiCoordinate(float index)
			{
				return float2((index - 1) / 16, 1 - ((floor(index / 16 - glyphWidth)) / 16));
			}
			
			float median(float r, float g, float b)
			{
				return max(min(r, g), min(max(r, g), b));
			}
			
			void ApplyPositionText(inout PoiFragData poiFragData, float2 uv, in PoiMods poiMods)
			{
				float3 cameraPos = clamp(getCameraPosition(), -999, 999);
				float3 absCameraPos = abs(cameraPos);
				float totalCharacters = 20;
				float positionArray[20];
				positionArray[0] = cameraPos.x >= 0 ? ASCII_NEGATIVE : ASCII_POSITIVE;
				positionArray[1] = floor((absCameraPos.x * .01) % 10) + 48;
				positionArray[2] = floor((absCameraPos.x * .1) % 10) + 48;
				positionArray[3] = floor(absCameraPos.x % 10) + 48;
				positionArray[4] = ASCII_PERIOD;
				positionArray[5] = floor((absCameraPos.x * 10) % 10) + 48;
				positionArray[6] = ASCII_COMMA;
				positionArray[7] = cameraPos.y >= 0 ? ASCII_NEGATIVE : ASCII_POSITIVE;
				positionArray[8] = floor((absCameraPos.y * .01) % 10) + 48;
				positionArray[9] = floor((absCameraPos.y * .1) % 10) + 48;
				positionArray[10] = floor(absCameraPos.y % 10) + 48;
				positionArray[11] = ASCII_PERIOD;
				positionArray[12] = floor((absCameraPos.y * 10) % 10) + 48;
				positionArray[13] = ASCII_COMMA;
				positionArray[14] = cameraPos.z >= 0 ? ASCII_NEGATIVE : ASCII_POSITIVE;
				positionArray[15] = floor((absCameraPos.z * .01) % 10) + 48;
				positionArray[16] = floor((absCameraPos.z * .1) % 10) + 48;
				positionArray[17] = floor(absCameraPos.z % 10) + 48;
				positionArray[18] = ASCII_PERIOD;
				positionArray[19] = floor((absCameraPos.z * 10) % 10) + 48;
				
				uv = TransformUV(_TextPositionOffset, _TextPositionRotation, _TextPositionScale, uv);
				
				if (uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
				{
					return;
				}
				
				float currentCharacter = floor(uv.x * totalCharacters);
				float2 glyphPos = getAsciiCoordinate(positionArray[currentCharacter]);
				
				float2 startUV = float2(1 / totalCharacters * currentCharacter, 0);
				float2 endUV = float2(1 / totalCharacters * (currentCharacter + 1), 1);
				
				fixed4 textPositionPadding = _TextPositionPadding;
				textPositionPadding *= 1 / totalCharacters;
				
				uv = remapClamped(startUV, endUV, uv, float2(glyphPos.x + textPositionPadding.x, glyphPos.y - glyphWidth + textPositionPadding.y), float2(glyphPos.x + glyphWidth - textPositionPadding.z, glyphPos.y - textPositionPadding.w));
				
				if (uv.x > glyphPos.x + glyphWidth - textPositionPadding.z - .001 || uv.x < glyphPos.x + textPositionPadding.x + .001 || uv.y > glyphPos.y - textPositionPadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textPositionPadding.y + .001)
				{
					return;
				}
				
				float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
				float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
				float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
				sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
				float opacity = clamp(sigDist + 0.5, 0, 1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, poiThemeColor(poiMods, _TextPositionColor.rgb, _TextPositionColorThemeIndex), opacity * _TextPositionColor.a);
				globalTextEmission += poiThemeColor(poiMods, _TextPositionColor.rgb, _TextPositionColorThemeIndex) * opacity * _TextPositionEmissionStrength;
			}
			
			void ApplyTimeText(inout PoiFragData poiFragData, float2 uv, in PoiMods poiMods)
			{
				float instanceTime = _Time.y;
				float hours = instanceTime / 3600;
				float minutes = (instanceTime / 60) % 60;
				float seconds = instanceTime % 60;
				float totalCharacters = 8;
				float timeArray[8];
				timeArray[0] = floor((hours * .1) % 10) + 48;
				timeArray[1] = floor(hours % 10) + 48;
				timeArray[2] = ASCII_SEMICOLON;
				timeArray[3] = floor((minutes * .1) % 10) + 48;
				timeArray[4] = floor(minutes % 10) + 48;
				timeArray[5] = ASCII_SEMICOLON;
				timeArray[6] = floor((seconds * .1) % 10) + 48;
				timeArray[7] = floor(seconds % 10) + 48;
				
				uv = TransformUV(_TextTimeOffset, _TextTimeRotation, _TextTimeScale, uv);
				
				if (uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
				{
					return;
				}
				
				float currentCharacter = floor(uv.x * totalCharacters);
				float2 glyphPos = getAsciiCoordinate(timeArray[currentCharacter]);
				// 0.1428571 = 1/7 = 1 / totalCharacters
				float startUV = 1 / totalCharacters * currentCharacter;
				float endUV = 1 / totalCharacters * (currentCharacter + 1);
				
				fixed4 textTimePadding = _TextTimePadding;
				textTimePadding *= 1 / totalCharacters;
				
				uv = remapClamped(float2(startUV, 0), float2(endUV, 1), uv, float2(glyphPos.x + textTimePadding.x, glyphPos.y - glyphWidth + textTimePadding.y), float2(glyphPos.x + glyphWidth - textTimePadding.z, glyphPos.y - textTimePadding.w));
				
				if (uv.x > glyphPos.x + glyphWidth - textTimePadding.z - .001 || uv.x < glyphPos.x + textTimePadding.x + .001 || uv.y > glyphPos.y - textTimePadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textTimePadding.y + .001)
				{
					return;
				}
				
				float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
				float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
				float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
				sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
				float opacity = clamp(sigDist + 0.5, 0, 1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, poiThemeColor(poiMods, _TextTimeColor.rgb, _TextTimeColorThemeIndex), opacity * _TextTimeColor.a);
				globalTextEmission += poiThemeColor(poiMods, _TextTimeColor.rgb, _TextTimeColorThemeIndex) * opacity * _TextTimeEmissionStrength;
			}
			
			void ApplyFPSText(inout PoiFragData poiFragData, float2 uv, in PoiMods poiMods)
			{
				float smoothDeltaTime = clamp(unity_DeltaTime.w, 0, 999);
				float totalCharacters = 7;
				float fpsArray[7];
				fpsArray[0] = ASCII_F;
				fpsArray[1] = ASCII_P;
				fpsArray[2] = ASCII_S;
				fpsArray[3] = ASCII_SEMICOLON;
				fpsArray[4] = floor((smoothDeltaTime * .01) % 10) + 48;
				fpsArray[5] = floor((smoothDeltaTime * .1) % 10) + 48;
				fpsArray[6] = floor(smoothDeltaTime % 10) + 48;
				
				uv = TransformUV(_TextFPSOffset, _TextFPSRotation, _TextFPSScale, uv);
				
				if (uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
				{
					return;
				}
				
				float currentCharacter = floor(uv.x * totalCharacters);
				float2 glyphPos = getAsciiCoordinate(fpsArray[currentCharacter]);
				// 0.1428571 = 1/7 = 1 / totalCharacters
				float startUV = 1 / totalCharacters * currentCharacter;
				float endUV = 1 / totalCharacters * (currentCharacter + 1);
				
				float4 textFPSPadding = _TextFPSPadding;
				textFPSPadding *= 1 / totalCharacters;
				
				uv = remapClamped(float2(startUV, 0), float2(endUV, 1), uv, float2(glyphPos.x + textFPSPadding.x, glyphPos.y - glyphWidth + textFPSPadding.y), float2(glyphPos.x + glyphWidth - textFPSPadding.z, glyphPos.y - textFPSPadding.w));
				
				if (uv.x > glyphPos.x + glyphWidth - textFPSPadding.z - .001 || uv.x < glyphPos.x + textFPSPadding.x + .001 || uv.y > glyphPos.y - textFPSPadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textFPSPadding.y + .001)
				{
					return;
				}
				
				float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
				float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
				float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
				sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
				float opacity = clamp(sigDist + 0.5, 0, 1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, poiThemeColor(poiMods, _TextFPSColor.rgb, _TextFPSColorThemeIndex), opacity * _TextFPSColor.a);
				globalTextEmission += poiThemeColor(poiMods, _TextFPSColor.rgb, _TextFPSColorThemeIndex) * opacity * _TextFPSEmissionStrength;
			}
			
			void ApplyNumericText(inout PoiFragData poiFragData, float2 uv, in PoiMods poiMods)
			{
				// If both digits are set to zero: exit.
				if (_TextNumericWholeDigits == 0 && _TextNumericDecimalDigits == 0)
				{
					return;
				}
				
				uint wholeNumber = 0;
				uint decimalNumber = 0;
				uint wholeDigits = _TextNumericWholeDigits;
				uint decimalDigits = _TextNumericDecimalDigits;
				float NumericArray[10];										// 10 is the max amount of characters = 1 sign + 4 max whole digits + 1 decimal mark + 4 max decimal digits
				uint arrayIndex = 0;
				float totalCharacters = 1 + wholeDigits + decimalDigits; 	// Sign Character + Whole Digits + Decimal Digits
				
				//Determine Sign (_TextNumericValue is usually animated)
				float charSign = _TextNumericValue >= 0 ? ASCII_SPACE : ASCII_NEGATIVE;
				
				NumericArray[arrayIndex] = charSign;						//First character is always the sign
				arrayIndex++;
				
				//Isolate whole number and fill array
				if (wholeDigits > 0)
				{
					wholeNumber = uint(glsl_mod(abs(_TextNumericValue), pow(10, wholeDigits)));
					
					int expIndex = -1 * (wholeDigits - 1);  // Exponent Index
					bool leadingZero = true;
					// Pouplate the Array
					while (arrayIndex <= wholeDigits)
					{
						// Grab the corresponding digit from the whole number going from left to right.
						int digit = floor(glsl_mod(wholeNumber * pow(10, expIndex), 10));
						// Take the resulting value and add 48 to get the corresponding location in the font array.
						NumericArray[arrayIndex] = digit + 48;
						
						//Trim Leading Zeroes, but leave at least one.
						if (_TextNumericTrimZeroes == true)
						{
							//If the digit is zero and there hasn't been any digits greater than 0 previously.
							if (digit == 0 && leadingZero == true && arrayIndex != wholeDigits)
							{
								//Overwrite the leading zero.
								NumericArray[arrayIndex] = ASCII_SPACE;
							}
							else
							{
								leadingZero = false;
							}
						}
						expIndex++;
						arrayIndex++;
					}
				}
				
				// Isolate decimal number and fill array
				if (decimalDigits > 0)
				{
					// Add a decimal point
					NumericArray[arrayIndex] = ASCII_PERIOD;
					int decimalPointer = arrayIndex;
					arrayIndex++;
					totalCharacters++;
					
					decimalNumber = uint(frac(abs(_TextNumericValue)) * pow(10.00001, decimalDigits));    // Isolate the decimal number
					
					int expIndex = -1 * (decimalDigits - 1);                                          // Exponent Index
					//Populate the Array with the remaining digits
					while (arrayIndex < (uint)(totalCharacters))
					{
						// Grab the corresponding digit from the whole number going from left to right.
						int digit = floor(glsl_mod(decimalNumber * pow(10, expIndex), 10));
						// Take the resulting value and add 48 to get the corresponding location in the font array.
						NumericArray[arrayIndex] = digit + 48;
						
						expIndex++;
						arrayIndex++;
					}
				}
				
				uv = TransformUV(_TextNumericOffset, _TextNumericRotation, _TextNumericScale, uv);
				
				if (uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
				{
					return;
				}
				
				float currentCharacter = floor(uv.x * totalCharacters);
				float2 glyphPos = getAsciiCoordinate(NumericArray[currentCharacter]);
				float startUV = 1 / totalCharacters * currentCharacter;
				float endUV = 1 / totalCharacters * (currentCharacter + 1);
				
				float4 textNumericPadding = _TextNumericPadding;
				textNumericPadding *= 1 / totalCharacters;
				
				uv = remapClamped(float2(startUV, 0), float2(endUV, 1), uv, float2(glyphPos.x + textNumericPadding.x, glyphPos.y - glyphWidth + textNumericPadding.y), float2(glyphPos.x + glyphWidth - textNumericPadding.z, glyphPos.y - textNumericPadding.w));
				
				if (uv.x > glyphPos.x + glyphWidth - textNumericPadding.z - .001 || uv.x < glyphPos.x + textNumericPadding.x + .001 || uv.y > glyphPos.y - textNumericPadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textNumericPadding.y + .001)
				{
					return;
				}
				
				float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
				float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
				float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
				sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
				float opacity = clamp(sigDist + 0.5, 0, 1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, poiThemeColor(poiMods, _TextNumericColor.rgb, _TextNumericColorThemeIndex), opacity * _TextNumericColor.a);
				globalTextEmission += poiThemeColor(poiMods, _TextNumericColor.rgb, _TextNumericColorThemeIndex) * opacity * _TextNumericEmissionStrength;
			}
			
			void ApplyTextOverlayColor(inout PoiFragData poiFragData, PoiMesh poiMesh, in PoiMods poiMods)
			{
				globalTextEmission = 0;
				float positionalOpacity = 0;
				
				if (_TextFPSEnabled == 1)
				ApplyFPSText(poiFragData, poiMesh.uv[_TextFPSUV], poiMods);
				if (_TextPositionEnabled == 1)
				ApplyPositionText(poiFragData, poiMesh.uv[_TextPositionUV], poiMods);
				if (_TextTimeEnabled == 1)
				ApplyTimeText(poiFragData, poiMesh.uv[_TextTimeUV], poiMods);
				if (_TextNumericEnabled == 1)
				ApplyNumericText(poiFragData, poiMesh.uv[_TextNumericUV], poiMods);
				
				poiFragData.emission += globalTextEmission;
			}
			#endif
			//endex
			
			//ifex _PostProcess==0
			#ifdef POSTPROCESS
			float3 poiPosterize(float3 color, float steps)
			{
				float3 newColor = RGBtoHSV(color);
				steps = floor(steps);
				newColor.r = floor(newColor.r * steps) / steps;
				newColor.g = floor(newColor.g * steps) / steps;
				newColor.b = floor(newColor.b * steps) / steps;
				return HSVtoRGB(newColor);
			}
			
			float oetf_sRGB_scalar(float L)
			{
				float V = 1.055 * (pow(L, 1.0 / 2.4)) - 0.055;
				if (L <= 0.0031308)
				V = L * 12.92;
				return V;
			}
			
			float3 oetf_sRGB(float3 L)
			{
				return float3(oetf_sRGB_scalar(L.r), oetf_sRGB_scalar(L.g), oetf_sRGB_scalar(L.b));
			}
			
			float eotf_sRGB_scalar(float V)
			{
				float L = pow((V + 0.055) / 1.055, 2.4);
				if (V <= oetf_sRGB_scalar(0.0031308))
				L = V / 12.92;
				return L;
			}
			
			float3 GetHDR(float3 rgb)
			{
				return float3(eotf_sRGB_scalar(rgb.r), eotf_sRGB_scalar(rgb.g), eotf_sRGB_scalar(rgb.b));
			}
			
			float3 GetContrast(float3 col, float contrast)
			{
				return lerp(float3(0.5, 0.5, 0.5), col, contrast);
			}
			
			float3 GetSaturation(float3 col, float interpolator)
			{
				return lerp(dot(col, float3(0.3, 0.59, 0.11)), col, interpolator);
			}
			
			void applyPostProcessing(inout PoiFragData poiFragData, in PoiMesh poiMesh)
			{
				float3 col = poiFragData.finalColor;
				col = hueShift(col, _PPHue);
				col *= _PPTint;
				col *= _PPRGB;
				col = GetSaturation(col, _PPSaturation);
				col = lerp(col, GetHDR(col), _PPHDR);
				col = GetContrast(col, _PPContrast);
				col *= _PPBrightness;
				col += _PPLightness;
				
				float ppMask = 1;
				#if defined(PROP_PPMASK) || !defined(OPTIMIZER_ENABLED)
				ppMask = POI2D_SAMPLER_PAN(_PPMask, _MainTex, poiUV(poiMesh.uv[_PPMaskUV], _PPMask_ST), _PPMaskPan)[_PPMaskChannel];
				ppMask = lerp(ppMask, 1 - ppMask, _PPMaskInvert);
				col = lerp(poiFragData.finalColor, col, ppMask);
				#endif
				
				if (_PPPosterization)
				{
					col = lerp(col, poiPosterize(col, _PPPosterizationAmount), ppMask);
				}
				
				poiFragData.finalColor = col;
			}
			#endif
			//endex
			
			//ifex _PoiInternalParallax==0
			#ifdef POI_INTERNALPARALLAX
			void applyInternalParallax(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiMods poiMods)
			{
				float3 parallax = 0;
				
				for (int j = _ParallaxInternalIterations - 1; j >= 0; j--)
				{
					float ratio = saturate((float)j / max(_ParallaxInternalIterations - 1, 1));
					float2 parallaxOffset = _Time.y * (_ParallaxInternalMapPan + ratio * _ParallaxInternalPanDepthSpeed);
					float fade = lerp(_ParallaxInternalMinFade, _ParallaxInternalMaxFade, ratio);
					fade = pow(fade, 2.2);
					#if defined(PROP_PARALLAXINTERNALMAP) || !defined(OPTIMIZER_ENABLED)
					float4 parallaxColor = UNITY_SAMPLE_TEX2D_SAMPLER(_ParallaxInternalMap, _MainTex, TRANSFORM_TEX(poiMesh.uv[0], _ParallaxInternalMap) + (lerp(_ParallaxInternalMinDepth, _ParallaxInternalMaxDepth, ratio)) * - (poiCam.tangentViewDir.xy / (poiCam.tangentViewDir.z)) + parallaxOffset);
					#else
					float4 parallaxColor = 0;
					#endif
					float3 minColor = poiThemeColor(poiMods, _ParallaxInternalMinColor.rgb, _ParallaxInternalMinColorThemeIndex);
					float3 maxColor = poiThemeColor(poiMods, _ParallaxInternalMaxColor.rgb, _ParallaxInternalMaxColorThemeIndex);
					float3 parallaxTint = lerp(minColor, maxColor, ratio);
					float parallaxHeight;
					if (_ParallaxInternalHeightFromAlpha)
					{
						parallaxTint *= parallaxColor.rgb;
						parallaxHeight = parallaxColor.a;
					}
					else
					{
						parallaxHeight = parallaxColor.r;
					}
					// parallaxTint = hueShift(parallaxTint, frac((ratio * _ParallaxInternalHueShiftPerLevel) + (ratio * _ParallaxInternalHueShiftPerLevelSpeed * _Time.x)) * _ParallaxInternalHueShiftEnabled);
					parallaxTint = hueShift(parallaxTint, frac(ratio * _ParallaxInternalHueShiftPerLevel) * _ParallaxInternalHueShiftEnabled);
					//float parallaxColor *= lerp(_ParallaxInternalMinColor, _ParallaxInternalMaxColor, 1 - ratio);
					UNITY_BRANCH
					if (_ParallaxInternalHeightmapMode == 1)
					{
						parallax = lerp(parallax, parallaxTint * fade, parallaxHeight >= 1 - ratio);
					}
					else
					{
						if (_ParallaxInternalBlendMode == 0) parallax += parallaxTint * parallaxHeight * fade;
						if (_ParallaxInternalBlendMode == 1) parallax = max(parallax, parallaxTint * parallaxHeight * fade);
					}
				}
				parallax = hueShift(parallax, frac(_ParallaxInternalHueShift + _ParallaxInternalHueShiftSpeed * _Time.x) * _ParallaxInternalHueShiftEnabled);
				//parallax /= _ParallaxInternalIterations;
				#if defined(PROP_PARALLAXINTERNALMAPMASK) || !defined(OPTIMIZER_ENABLED)
				poiFragData.baseColor.rgb = customBlend(poiFragData.baseColor.rgb, parallax.rgb, _ParallaxInternalSurfaceBlendMode, POI2D_SAMPLER_PAN(_ParallaxInternalMapMask, _MainTex, poiUV(poiMesh.uv[_ParallaxInternalMapMaskUV], _ParallaxInternalMapMask_ST), _ParallaxInternalMapMaskPan)[_ParallaxInternalMapMaskChannel]);
				#else
				poiFragData.baseColor.rgb = customBlend(poiFragData.baseColor.rgb, parallax.rgb, _ParallaxInternalSurfaceBlendMode);
				#endif
			}
			#endif
			//endex
			
			// normal correct code from https://github.com/yoship1639/UniToon (MIT)
			//ifex _NormalCorrect==0
			#ifdef POI_NORMALCORRECT
			void applyNormalCorrect(inout VertexOut i)
			{
				float3 normalCorrectObject = i.localPos.xyz - _NormalCorrectOrigin;
				normalCorrectObject.y = 0;
				normalCorrectObject = normalize(normalCorrectObject);
				float3 normalCorrectWorld = UnityObjectToWorldDir(normalCorrectObject);
				i.normal.xyz = normalize(lerp(i.normal.xyz, normalCorrectWorld, _NormalCorrectAmount));
				//i.objNormal.xyz = normalize(lerp(i.objNormal.xyz, normalCorrectObject, _NormalCorrectAmount));
			}
			#endif
			//endex
			
			//ifex _VideoEffectsEnable==0
			#ifdef POI_VIDEO_EFFECTS
			float3 applyBacklight(float3 videoTexture, half backlightStrength)
			{
				return max(backlightStrength, videoTexture.rgb);
			}
			
			float3 applyViewAngleTN(float3 videoTexture, PoiCam poiCam, PoiMesh poiMesh)
			{
				float3 reflectionVector = normalize(reflect(poiCam.viewDir.rgb, poiMesh.normals[1].rgb));
				float upwardShift = dot(reflectionVector, poiMesh.binormal[0]);
				upwardShift = pow(upwardShift, 1);
				float sideShift = dot(reflectionVector, poiMesh.tangent[0]);
				sideShift *= pow(sideShift, 3);
				#if !UNITY_COLORSPACE_GAMMA
				videoTexture = LinearToGammaSpace(videoTexture);
				#endif
				videoTexture = saturate(lerp(half3(0.5, 0.5, 0.5), videoTexture, upwardShift + 1));
				#if !UNITY_COLORSPACE_GAMMA
				videoTexture = GammaToLinearSpace(videoTexture);
				#endif
				videoTexture = (lerp(videoTexture, videoTexture.gbr, sideShift));
				return videoTexture;
			}
			
			float calculateCRTPixelBrightness(float2 uv)
			{
				float totalPixels = _VideoResolution.x * _VideoResolution.y;
				float2 uvPixel = float2((floor((1 - uv.y) * _VideoResolution.y)) / _VideoResolution.y, (floor(uv.x * _VideoResolution.x)) / _VideoResolution.x);
				float currentPixelNumber = _VideoResolution.x * (_VideoResolution.y * uvPixel.x) + _VideoResolution.y * uvPixel.y;
				float currentPixelAlpha = currentPixelNumber / totalPixels;
				half electronBeamAlpha = frac(_Time.y * _VideoCRTRefreshRate);
				float electronBeamPixelNumber = totalPixels * electronBeamAlpha;
				
				float DistanceInPixelsFromCurrentElectronBeamPixel = 0;
				if (electronBeamPixelNumber >= currentPixelNumber)
				{
					DistanceInPixelsFromCurrentElectronBeamPixel = electronBeamPixelNumber - currentPixelNumber;
				}
				else
				{
					DistanceInPixelsFromCurrentElectronBeamPixel = electronBeamPixelNumber + (totalPixels - currentPixelNumber);
				}
				float CRTFrameTime = 1 / _VideoCRTRefreshRate;
				float timeSincecurrentPixelWasHitByElectronBeam = (DistanceInPixelsFromCurrentElectronBeamPixel / totalPixels);
				
				return saturate(_VideoCRTPixelEnergizedTime - timeSincecurrentPixelWasHitByElectronBeam);
			}
			
			void applyContrastSettings(inout float3 pixel)
			{
				#if !UNITY_COLORSPACE_GAMMA
				pixel = LinearToGammaSpace(pixel);
				#endif
				pixel = saturate(lerp(half3(0.5, 0.5, 0.5), pixel, _VideoContrast + 1));
				#if !UNITY_COLORSPACE_GAMMA
				pixel = GammaToLinearSpace(pixel);
				#endif
			}
			
			void applySaturationSettings(inout float3 pixel)
			{
				pixel = lerp(pixel.rgb, dot(pixel.rgb, float3(0.3, 0.59, 0.11)), - (_VideoSaturation));
			}
			
			void applyVideoSettings(inout float3 pixel)
			{
				applySaturationSettings(pixel);
				applyContrastSettings(pixel);
			}
			
			void calculateLCD(inout float4 videoTexture, float3 pixels)
			{
				videoTexture.rgb = applyBacklight(videoTexture, _VideoBacklight * .01);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateTN(inout float4 videoTexture, float3 pixels, PoiCam poiCam, PoiMesh poiMesh)
			{
				videoTexture.rgb = applyBacklight(videoTexture, _VideoBacklight * .01);
				videoTexture.rgb = applyViewAngleTN(videoTexture, poiCam, poiMesh);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateCRT(inout float4 videoTexture, float3 pixels, float2 uv)
			{
				float brightness = calculateCRTPixelBrightness(uv);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * brightness * _VideoBacklight;
			}
			void calculateOLED(inout float4 videoTexture, float3 pixels)
			{
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateGameboy(inout float4 videoTexture)
			{
				applyVideoSettings(videoTexture.rgb);
				// half brightness = saturate((videoTexture.r + videoTexture.g + videoTexture.b) * .3333333);
				half brightness = LinearRgbToLuminance(LinearToGammaSpace(videoTexture.rgb));
				#if defined(PROP_VIDEOGAMEBOYRAMP) || !defined(OPTIMIZER_ENABLED)
				videoTexture.rgb = tex2Dlod(_VideoGameboyRamp, float4(brightness.xx, 0, 0));
				#else
				float3 dg = float3(0.00392156863, 0.0392156863, 0.00392156863);
				float3 lg = float3(0.333333333, 0.5, 0.00392156863);
				videoTexture.rgb = lerp(dg, lg, brightness);
				#endif
			}
			void calculateProjector(inout float4 videoTexture)
			{
				applyVideoSettings(videoTexture.rgb);
				
				float3 projectorColor = videoTexture * _VideoBacklight;
				videoTexture.r = clamp(projectorColor.r, videoTexture.r, 1000);
				videoTexture.g = clamp(projectorColor.g, videoTexture.g, 1000);
				videoTexture.b = clamp(projectorColor.b, videoTexture.b, 1000);
			}
			
			void applyVideoEffectsMainTex(inout float4 mainTexture, in PoiMesh poiMesh)
			{
				float2 uvs = poiMesh.uv[_MainTexUV];
				if (_VideoPixelateToResolution)
				{
					float2 originalUVs = uvs;
					uvs = sharpSample(float4(1 / _VideoResolution.xy, _VideoResolution.xy), uvs);
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
					mainTexture = _MainTex.SampleGrad(sampler_MainTex, uvs, ddx(originalUVs), ddy(originalUVs));
				}
			}
			void applyVideoEffects(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, in PoiLight poiLight, in PoiMods poiMods)
			{
				#if defined(PROP_VIDEOPIXELTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float3 pixels = tex2D(_VideoPixelTexture, poiUV(poiMesh.uv[_VideoPixelTextureUV], _VideoPixelTexture_ST) * _VideoResolution);
				#else
				float3 pixels = 1;
				#endif
				float2 uvs = poiMesh.uv[_MainTexUV];
				if (_VideoPixelateToResolution)
				{
					uvs = sharpSample(float4(1 / _VideoResolution.xy, _VideoResolution.xy), uvs);
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
				}
				else
				{
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
				}
				float4 modifiedVideoTexture = 0;
				modifiedVideoTexture.rgb = poiFragData.baseColor;
				modifiedVideoTexture.a = poiFragData.alpha;
				
				// UNITY_BRANCH
				// if(_VideoRepeatVideoTexture == 1)
				// {
				// 	if(poiMesh.uv[_VideoUVNumber].x > 1 || poiMesh.uv[_VideoUVNumber].x < 0 || poiMesh.uv[_VideoUVNumber].y > 1 || poiMesh.uv[_VideoUVNumber].y < 0)
				// 	{
				// 		return;
				// 	}
				// }
				
				switch(_VideoType)
				{
					case 0: // LCD
					
					{
						calculateLCD(modifiedVideoTexture, pixels);
						break;
					}
					case 1: // TN
					
					{
						calculateTN(modifiedVideoTexture, pixels, poiCam, poiMesh);
						break;
					}
					case 2: // CRT
					
					{
						calculateCRT(modifiedVideoTexture, pixels, uvs);
						break;
					}
					case 3: // OLED
					
					{
						calculateOLED(modifiedVideoTexture, pixels);
						break;
					}
					case 4: // Gameboy
					
					{
						calculateGameboy(modifiedVideoTexture);
						break;
					}
					case 5: // Projector
					
					{
						calculateProjector(modifiedVideoTexture);
						break;
					}
				}
				#if defined(PROP_VIDEOMASKTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float screenMask = POI2D_SAMPLER_PAN(_VideoMaskTexture, _MainTex, poiUV(poiMesh.uv[_VideoMaskTextureUV], _VideoMaskTexture_ST), _VideoMaskTexturePan)[_VideoMaskTextureChannel];
				#else
				float screenMask = 1;
				#endif
				
				poiFragData.baseColor = lerp(poiFragData.baseColor, modifiedVideoTexture, screenMask);
				// UNITY_BRANCH
				if (_VideoEmissionEnabled)
				{
					poiFragData.emission += modifiedVideoTexture.rgb * screenMask;
				}
			}
			#endif
			//endex
			
			//ifex _BacklightEnabled!=1
			#ifdef POI_BACKLIGHT
			void ApplyBacklight(inout PoiFragData poiFragData, in PoiMesh poiMesh, inout PoiLight poiLight, in PoiCam poiCam, inout PoiMods poiMods)
			{
				
				// Color
				float3 backlightColor = _BacklightColor.rgb;
				#if defined(PROP_BACKLIGHTCOLORTEX) || !defined(OPTIMIZER_ENABLED)
				backlightColor *= POI2D_SAMPLER_PAN(_BacklightColorTex, _MainTex, poiUV(poiMesh.uv[_BacklightColorTexUV], _BacklightColorTex_ST), _BacklightColorTexPan).rgb;
				#endif
				
				float3 normal = lerp(poiMesh.normals[0], poiMesh.normals[1], _BacklightNormalStrength);
				// Factor
				float3 headDir = normalize(getCameraPosition() - poiMesh.worldPos.xyz);
				float headDotLight = dot(headDir, poiLight.direction);
				float backlightFactor = pow(saturate(-headDotLight * 0.5 + 0.5), max(0, _BacklightDirectivity));
				float backlightLN = dot(normalize(-headDir * _BacklightViewStrength + poiLight.direction), normal) * 0.5 + 0.5;
				#if defined(POINT) || defined(SPOT)
				if (_BacklightReceiveShadow) backlightLN *= saturate(poiLight.additiveShadow);
				#else
				if (_BacklightReceiveShadow) backlightLN *= saturate(poiLight.attenuation);
				#endif
				backlightLN = poiEdgeLinear(backlightLN, _BacklightBorder, _BacklightBlur);
				float backlight = saturate(backlightFactor * backlightLN);
				backlight = !poiMesh.isFrontFace && _BacklightBackfaceMask ? 0.0 : backlight;
				
				// Blend
				backlightColor = lerp(backlightColor, backlightColor * poiFragData.baseColor, _BacklightMainStrength);
				poiLight.finalLightAdd += backlight * backlightColor * poiLight.directColor;
			}
			#endif
			//endex
			
			//ifex _VoronoiEnabled!=1
			#ifdef POI_VORONOI
			//1/7
			#define VoronoiK 0.142857142857
			//3/7
			#define VoronoiKo 0.428571428571
			// Permutation polynomial: (34x^2 + x) mod 289
			float3 Permutation(float3 x)
			{
				return glsl_mod((34.0 * x + 1.0) * x, 289.0);
			}
			
			float3 inoise(float3 P, float jitter, out float3 randomPoint)
			{
				P *= 0.7f; // Scale adjustment
				float3 Pi = glsl_mod(floor(P), 289.0);
				float3 Pf = frac(P);
				float3 oi = float3(-1.0, 0.0, 1.0);
				float3 of = float3(-0.5, 0.5, 1.5);
				float3 px = Permutation(Pi.x + oi);
				float3 py = Permutation(Pi.y + oi);
				float3 pz = Permutation(Pi.z + oi);
				
				float3 p, ox, oy, oz, dx, dy, dz;
				float3 F = 1e6;
				
				[unroll(3)]
				for (int i = 0; i < 3; i++)
				{
					[unroll(3)]
					for (int j = 0; j < 3; j++)
					{
						[unroll(3)]
						for (int k = 0; k < 3; k++)
						{
							p = Permutation(px[i] + py[j] + pz[k] + oi); // pij1, pij2, pij3
							float3 ogp = p;
							
							ox = frac(p * VoronoiK) - VoronoiKo;
							oy = glsl_mod(floor(p * VoronoiK), 7.0) * VoronoiK - VoronoiKo;
							
							p = Permutation(p);
							oz = frac(p * VoronoiK) - VoronoiKo;
							
							dx = Pf.x - of[i] + jitter * ox;
							dy = Pf.y - of[j] + jitter * oy;
							dz = Pf.z - of[k] + jitter * oz;
							
							float3 d = dx * dx + dy * dy + dz * dz; // dij1, dij2 and dij3, squared
							
							//Find lowest and second lowest distances
							for (int n = 0; n < 3; n++)
							{
								if (d[n] < F[0])
								{
									F[1] = F[0];
									F[0] = d[n];
									randomPoint = p;
								}
								else if (d[n] < F[1])
								{
									F[1] = d[n];
								}
							}
						}
					}
				}
				
				return F;
			}
			
			float voronoi2D(in float2 x, float scale, float2 speed, out float2 randomPoint)
			{
				x *= scale;
				x += speed * _Time.x;
				float2 n = floor(x);
				float2 f = frac(x);
				
				// first pass: regular voronoi
				float2 mg, mr;
				float md = 8.0;
				for (int j = -1; j <= 1; j++)
				{
					for (int i = -1; i <= 1; i++)
					{
						float2 g = float2(float(i), float(j));
						float2 o = random2(n + g);
						float2 currentPoint = o;
						
						float2 r = g + o - f;
						float d = dot(r, r);
						
						if (d < md)
						{
							md = d;
							mr = r;
							mg = g;
							randomPoint.xy = currentPoint;
						}
					}
				}
				
				// second pass: distance to borders
				md = 8.0;
				for (int r = -2; r <= 2; r++)
				{
					for (int q = -2; q <= 2; q++)
					{
						float2 g = mg + float2(float(q), float(r));
						float2 o = random2(n + g);
						
						float2 r = g + o - f;
						
						if (dot(mr - r, mr - r) > 0.00001)
						{
							md = min(md, dot(0.5 * (mr + r), normalize(r - mr)));
						}
					}
				}
				return md;
			}
			
			float voronoi3D(in float3 x, float scale, float3 speed, out float3 randomPoint)
			{
				x *= scale;
				x += speed * _Time.x;
				float3 n = floor(x);
				float3 f = frac(x);
				
				// first pass: regular voronoi
				float3 mg, mr;
				float md = 8.0;
				for (int j = -1; j <= 1; j++)
				{
					for (int i = -1; i <= 1; i++)
					{
						for (int h = -1; h <= 1; h++)
						{
							float3 g = float3(float(h), float(i), float(j));
							float3 o = random3(n + g);
							float3 currentPoint = o;
							
							float3 r = g + o - f;
							float d = dot(r, r);
							
							if (d < md)
							{
								md = d;
								mr = r;
								mg = g;
								randomPoint = currentPoint;
							}
						}
					}
				}
				
				// second pass: distance to borders
				md = 8.0;
				for (int r = -2; r <= 2; r++)
				{
					for (int q = -2; q <= 2; q++)
					{
						for (int p = -2; p <= 2; p++)
						{
							float3 g = mg + float3(float(p), float(q), float(r));
							float3 o = random3(n + g);
							
							float3 r = g + o - f;
							
							if (dot(mr - r, mr - r) > 0.00001)
							{
								md = min(md, dot(0.5 * (mr + r), normalize(r - mr)));
							}
						}
					}
				}
				return md;
			}
			
			// fracal sum, range -1.0 - 1.0
			float VoronoiNoise_Octaves(float3 p, float scale, float3 speed, int octaveNumber, float octaveScale, float octaveAttenuation, float jitter, float time, out float3 randomPoint)
			{
				float freq = scale;
				float weight = 1.0f;
				float sum = 0;
				// Uncomment when the octave stuff is actually used
				// for (int i = 0; i < octaveNumber; i ++)
				// {
				float3 F = inoise(p * freq + time * speed, jitter, randomPoint) * weight;
				
				sum += sqrt(F[0]);
				
				// 	freq *= octaveScale;
				// 	weight *= 1.0f - octaveAttenuation;
				// }
				return sum;
			}
			
			float VoronoiNoiseDiff_Octaves(float3 p, float scale, float3 speed, int octaveNumber, float octaveScale, float octaveAttenuation, float jitter, float time, out float3 randomPoint)
			{
				float freq = scale;
				float weight = 1.0f;
				float sum = 0;
				// Uncomment when the octave stuff is actually used
				// for (int i = 0; i < octaveNumber; i ++)
				// {
				float3 F = inoise(p * freq + time * speed, jitter, randomPoint) * weight;
				
				sum += sqrt(F[1]) - sqrt(F[0]);
				
				// freq *= octaveScale;
				// weight *= 1.0f - octaveAttenuation;
				// }
				return sum;
			}
			
			void ApplyVoronoi(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float voronoiOctaveNumber = 1;
				float voronoiOctaveScale = 1;
				float voronoiOctaveAttenuation = 1;
				float3 randomPoint = 0;
				
				float voronoi = 0;
				
				float3 position = 0;
				
				UNITY_BRANCH
				if (_VoronoiSpace == 0)
				{
					position = poiMesh.localPos;
				}
				UNITY_BRANCH
				if (_VoronoiSpace == 1)
				{
					position = poiMesh.worldPos;
				}
				UNITY_BRANCH
				if (_VoronoiSpace == 2)
				{
					position = float3(poiMesh.uv[0].x, poiMesh.uv[0].y, 0);
				}
				#if defined(PROP_VORONOIMASK) || !defined(OPTIMIZER_ENABLED)
				float mask = POI2D_SAMPLER_PAN(_VoronoiMask, _MainTex, poiUV(poiMesh.uv[_VoronoiMaskUV], _VoronoiMask_ST), _VoronoiMaskPan)[_VoronoiMaskChannel];
				#else
				float mask = 1;
				#endif
				
				if (_VoronoiGlobalMask > 0)
				{
					mask = maskBlend(mask, poiMods.globalMask[_VoronoiGlobalMask - 1], _VoronoiGlobalMaskBlendType);
				}
				
				#if defined(PROP_VORONOINOISE) || !defined(OPTIMIZER_ENABLED)
				float edgeNoise = POI2D_SAMPLER_PAN(_VoronoiNoise, _MainTex, poiUV(poiMesh.uv[_VoronoiNoiseUV], _VoronoiNoise_ST), _VoronoiNoisePan)[_VoronoiNoiseChannel];
				#else
				float edgeNoise = 0;
				#endif
				edgeNoise *= _VoronoiNoiseIntensity;
				
				float3 voronoiSpeed = _VoronoiSpeed * 10;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					position.x += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedXType, _AudioLinkVoronoiChronoSpeedXBand) * _AudioLinkVoronoiChronoSpeedXSpeed * 0.01;
					position.y += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedYType, _AudioLinkVoronoiChronoSpeedYBand) * _AudioLinkVoronoiChronoSpeedYSpeed * 0.01;
					position.z += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedZType, _AudioLinkVoronoiChronoSpeedZBand) * _AudioLinkVoronoiChronoSpeedZSpeed * 0.01;
				}
				#endif
				
				if (_VoronoiType == 0) // Basic
				
				{
					voronoi = voronoi2D(position.xy, _VoronoiScale, voronoiSpeed, randomPoint.xy);
					voronoi *= 1.55; // Range adjustment
					
				}
				if (_VoronoiType == 1) // Diff
				
				{
					voronoi = VoronoiNoiseDiff_Octaves(position, _VoronoiScale, voronoiSpeed, voronoiOctaveNumber, voronoiOctaveScale, voronoiOctaveAttenuation, 1, _Time.x, randomPoint);
				}
				if (_VoronoiType == 2) // Fixed Border
				
				{
					voronoi = voronoi3D(position, _VoronoiScale, voronoiSpeed, randomPoint);
					voronoi *= 1.8; // Range adjustment
					
				}
				
				float4 outerColor = _VoronoiOuterColor;
				float4 innerColor = _VoronoiInnerColor;
				
				if (_VoronoiEnableRandomCellColor == 1)
				{
					float3 rando = random3(randomPoint);
					fixed hue = rando.x;
					fixed saturation = lerp(_VoronoiRandomMinMaxSaturation.x, _VoronoiRandomMinMaxSaturation.y, rando.y);
					fixed value = lerp(_VoronoiRandomMinMaxBrightness.x, _VoronoiRandomMinMaxBrightness.y, rando.z);
					float3 hsv = float3(hue, saturation, value);
					innerColor.rgb = HSVtoRGB(hsv);
				}
				voronoi = pow(voronoi, _VoronoiPower);
				float2 voronoiGradient = _VoronoiGradient.xy + edgeNoise;
				#ifdef POI_AUDIOLINK
				voronoiGradient.x += _AudioLinkVoronoiGradientMinAdd * poiMods.audioLink[_AudioLinkVoronoiGradientMinAddBand];
				voronoiGradient.y -= _AudioLinkVoronoiGradientMaxAdd * poiMods.audioLink[_AudioLinkVoronoiGradientMaxAddBand];
				#endif
				float ramp = smoothstep(voronoiGradient.x, voronoiGradient.y, voronoi);
				
				if (_VoronoiBlend == 0)
				{
					float4 voronoiColor = lerp(outerColor, innerColor, ramp);
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, voronoiColor, min(mask * voronoiColor.a, 0.99999));
					if (_VoronoiAffectsMaterialAlpha)
					{
						poiFragData.alpha = lerp(poiFragData.alpha, voronoiColor.a, min(mask, 0.99999));
					}
				}
				float outerEmissionStrength = _VoronoiOuterEmissionStrength;
				float innerEmissionStrength = _VoronoiInnerEmissionStrength;
				#ifdef POI_AUDIOLINK
				outerEmissionStrength += lerp(_AudioLinkVoronoiOuterEmission.x, _AudioLinkVoronoiOuterEmission.y, poiMods.audioLink[_AudioLinkVoronoiOuterEmissionBand]);
				innerEmissionStrength += lerp(_AudioLinkVoronoiInnerEmission.x, _AudioLinkVoronoiInnerEmission.y, poiMods.audioLink[_AudioLinkVoronoiInnerEmissionBand]);
				#endif
				float4 voronoiEmissionColor = lerp(outerColor, innerColor, ramp);
				voronoiEmissionColor.rgb *= lerp(outerEmissionStrength, innerEmissionStrength, ramp);
				poiFragData.emission += voronoiEmissionColor.rgb * mask * voronoiEmissionColor.a;
			}
			#endif
			//endex
			
			float4 frag(VertexOut i, uint facing : SV_IsFrontFace) : SV_Target
			/*
			#ifdef
			, out float depth : SV_DEPTH
			#endif
			*/
			{
				UNITY_SETUP_INSTANCE_ID(i);
				UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
				
				PoiMesh poiMesh;
				PoiInitStruct(PoiMesh, poiMesh);
				
				PoiLight poiLight;
				PoiInitStruct(PoiLight, poiLight);
				
				PoiVertexLights poiVertexLights;
				PoiInitStruct(PoiVertexLights, poiVertexLights);
				
				PoiCam poiCam;
				PoiInitStruct(PoiCam, poiCam);
				
				PoiMods poiMods;
				PoiInitStruct(PoiMods, poiMods);
				poiMods.globalEmission = 1;
				
				PoiFragData poiFragData;
				poiFragData.smoothness = 1;
				poiFragData.smoothness2 = 1;
				poiFragData.metallic = 1;
				poiFragData.specularMask = 1;
				poiFragData.reflectionMask = 1;
				poiFragData.emission = 0;
				poiFragData.baseColor = float3(0, 0, 0);
				poiFragData.finalColor = float3(0, 0, 0);
				poiFragData.alpha = 1;
				poiFragData.toggleVertexLights = 0;
				
				#ifdef POI_UDIMDISCARD
				applyUDIMDiscard(i);
				#endif
				
				//ifex _NormalCorrect==0
				#ifdef POI_NORMALCORRECT
				applyNormalCorrect(i);
				#endif
				//endex
				
				// Mesh Data
				//poiMesh.objectPosition = mul(unity_ObjectToWorld, float3(0, 0, 0)).xyz;
				poiMesh.objectPosition = mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
				poiMesh.objNormal = mul(unity_WorldToObject, i.normal);
				poiMesh.normals[0] = i.normal;
				poiMesh.tangent[0] = i.tangent.xyz;
				poiMesh.binormal[0] = cross(i.normal, i.tangent.xyz) * (i.tangent.w * unity_WorldTransformParams.w);
				poiMesh.worldPos = i.worldPos.xyz;
				poiMesh.localPos = i.localPos.xyz;
				poiMesh.vertexColor = i.vertexColor;
				poiMesh.isFrontFace = facing;
				poiMesh.dx = ddx(poiMesh.uv[0]);
				poiMesh.dy = ddy(poiMesh.uv[0]);
				
				#ifndef POI_PASS_OUTLINE
				if (!poiMesh.isFrontFace && _FlipBackfaceNormals)
				{
					poiMesh.normals[0] *= -1;
					poiMesh.tangent[0] *= -1;
					poiMesh.binormal[0] *= -1;
				}
				#endif
				
				poiCam.viewDir = !IsOrthographicCamera() ? normalize(_WorldSpaceCameraPos - i.worldPos.xyz) : normalize(UNITY_MATRIX_I_V._m02_m12_m22);
				float3 tanToWorld0 = float3(poiMesh.tangent[0].x, poiMesh.binormal[0].x, poiMesh.normals[0].x);
				float3 tanToWorld1 = float3(poiMesh.tangent[0].y, poiMesh.binormal[0].y, poiMesh.normals[0].y);
				float3 tanToWorld2 = float3(poiMesh.tangent[0].z, poiMesh.binormal[0].z, poiMesh.normals[0].z);
				float3 ase_tanViewDir = tanToWorld0 * poiCam.viewDir.x + tanToWorld1 * poiCam.viewDir.y + tanToWorld2 * poiCam.viewDir.z;
				poiCam.tangentViewDir = normalize(ase_tanViewDir);
				
				// 0-3 UV0-UV3
				// 4 Panosphere UV
				// 5 world pos xz
				// 6 Polar UV
				// 6 Distorted UV
				#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
				poiMesh.lightmapUV = i.lightmapUV;
				#endif
				poiMesh.parallaxUV = poiCam.tangentViewDir.xy / max(poiCam.tangentViewDir.z, 0.0001);
				poiMesh.uv[0] = i.uv[0].xy;
				poiMesh.uv[1] = i.uv[0].zw;
				poiMesh.uv[2] = i.uv[1].xy;
				poiMesh.uv[3] = i.uv[1].zw;
				poiMesh.uv[4] = poiMesh.uv[0];
				poiMesh.uv[5] = poiMesh.uv[0];
				poiMesh.uv[6] = poiMesh.uv[0];
				poiMesh.uv[7] = poiMesh.uv[0];
				poiMesh.uv[8] = poiMesh.uv[0];
				
				poiMesh.uv[4] = calculatePanosphereUV(poiMesh);
				poiMesh.uv[5] = calculateWorldUV(poiMesh);
				poiMesh.uv[6] = calculatePolarCoordinate(poiMesh);
				poiMesh.uv[8] = calculatelocalUV(poiMesh);
				//ifex _EnableDistortion==0
				#ifdef USER_LUT
				poiMesh.uv[7] = distortedUV(poiMesh);
				#endif
				//endex
				/*
				half3 worldViewUp = normalize(half3(0, 1, 0) - poiCam.viewDir * dot(poiCam.viewDir, half3(0, 1, 0)));
				half3 worldViewRight = normalize(cross(poiCam.viewDir, worldViewUp));
				poiMesh[8] = half2(dot(worldViewRight, poiMesh.normals[_MatcapNormal]), dot(worldViewUp, poiMesh.normals[_MatcapNormal])) * _MatcapBorder + 0.5;
				*/
				
				//ifex _PoiParallax==0
				#ifdef POI_PARALLAX
				#ifndef POI_PASS_OUTLINE
				//return frac(i.tangentViewDir.x);
				//return float4(i.binormal.xyz,1);
				applyParallax(poiMesh, poiLight, poiCam);
				#endif
				#endif
				//endex
				
				poiMods.globalMask[0] = 1;
				poiMods.globalMask[1] = 1;
				poiMods.globalMask[2] = 1;
				poiMods.globalMask[3] = 1;
				poiMods.globalMask[4] = 1;
				poiMods.globalMask[5] = 1;
				poiMods.globalMask[6] = 1;
				poiMods.globalMask[7] = 1;
				poiMods.globalMask[8] = 1;
				poiMods.globalMask[9] = 1;
				poiMods.globalMask[10] = 1;
				poiMods.globalMask[11] = 1;
				poiMods.globalMask[12] = 1;
				poiMods.globalMask[13] = 1;
				poiMods.globalMask[14] = 1;
				poiMods.globalMask[15] = 1;
				//ifex _GlobalMaskTexturesEnable==0
				#ifdef POI_GLOBALMASK_TEXTURES
				ApplyGlobalMaskTextures(poiMesh, poiMods);
				#endif
				//endex
				//ifex _GlobalMaskVertexColorRed==0 && _GlobalMaskVertexColorGreen==0 && _GlobalMaskVertexColorBlue==0 && _GlobalMaskVertexColorAlpha==0
				ApplyGlobalMaskVertexColors(poiMesh, poiMods);
				//endex
				ApplyGlobalMaskModifiers(poiMesh, poiMods, poiCam);
				//ifex _GlobalMaskOptionsEnable==0
				if (_GlobalMaskOptionsEnable)
				{
					ApplyGlobalMaskOptions(poiMods);
				}
				//endex
				
				float2 mainUV = poiUV(poiMesh.uv[_MainTexUV].xy, _MainTex_ST);
				
				if (_MainPixelMode)
				{
					mainUV = sharpSample(_MainTex_TexelSize, mainUV);
				}
				
				float4 mainTexture = POI2D_SAMPLER_PAN_STOCHASTIC(_MainTex, _MainTex, mainUV, _MainTexPan, _MainTexStochastic);
				
				//ifex _VideoEffectsEnable==0
				#ifdef POI_VIDEO_EFFECTS
				if (_VideoEffectsEnable)
				{
					applyVideoEffectsMainTex(mainTexture, poiMesh);
				}
				#endif
				//endex
				
				#if defined(PROP_BUMPMAP) || !defined(OPTIMIZER_ENABLED)
				poiMesh.tangentSpaceNormal = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_BumpMap, _MainTex, poiUV(poiMesh.uv[_BumpMapUV].xy, _BumpMap_ST), _BumpMapPan, _BumpMapStochastic), _BumpScale);
				#else
				poiMesh.tangentSpaceNormal = UnpackNormal(float4(0.5, 0.5, 1, 1));
				#endif
				
				//ifex _DetailEnabled==0
				#if defined(FINALPASS) && !defined(UNITY_PASS_SHADOWCASTER) && !defined(POI_PASS_OUTLINE)
				ApplyDetailNormal(poiMods, poiMesh);
				#endif
				//endex
				
				//ifex _RGBMaskEnabled==0
				#if defined(VIGNETTE) && !defined(UNITY_PASS_SHADOWCASTER) && !defined(POI_PASS_OUTLINE)
				calculateRGBNormals(poiMesh, poiMods);
				#endif
				
				//endex
				
				float3 tangentSpaceNormal = UnpackNormal(float4(0.5, 0.5, 1, 1));
				poiMesh.normals[0] = normalize(
				tangentSpaceNormal.x * poiMesh.tangent[0] +
				tangentSpaceNormal.y * poiMesh.binormal[0] +
				tangentSpaceNormal.z * poiMesh.normals[0]
				);
				
				poiMesh.normals[1] = normalize(
				poiMesh.tangentSpaceNormal.x * poiMesh.tangent[0] +
				poiMesh.tangentSpaceNormal.y * poiMesh.binormal[0] +
				poiMesh.tangentSpaceNormal.z * poiMesh.normals[0]
				);
				
				poiMesh.tangent[1] = cross(poiMesh.binormal[0], -poiMesh.normals[1]);
				poiMesh.binormal[1] = cross(-poiMesh.normals[1], poiMesh.tangent[0]);
				
				//ifex _EnableOutlines!=1
				#ifdef POI_PASS_OUTLINE
				poiMesh.normals[1] = poiMesh.normals[0];
				#endif
				//endex
				
				// Camera data
				poiCam.forwardDir = getCameraForward();
				poiCam.worldPos = _WorldSpaceCameraPos;
				poiCam.reflectionDir = reflect(-poiCam.viewDir, poiMesh.normals[1]);
				poiCam.vertexReflectionDir = reflect(-poiCam.viewDir, poiMesh.normals[0]);
				//poiCam.distanceToModel = distance(poiMesh.modelPos, poiCam.worldPos);
				poiCam.clipPos = i.pos;
				poiCam.distanceToVert = distance(poiMesh.worldPos, poiCam.worldPos);
				poiCam.posScreenSpace = poiTransformClipSpacetoScreenSpaceFrag(poiCam.clipPos);
				#if defined(POI_GRABPASS) && defined(POI_PASS_BASE)
				poiCam.screenUV = poiCam.clipPos.xy / poiGetWidthAndHeight(_PoiGrab2);
				#else
				poiCam.screenUV = poiCam.clipPos.xy / _ScreenParams.xy;
				#endif
				#ifdef UNITY_SINGLE_PASS_STEREO
				poiCam.posScreenSpace.x = poiCam.posScreenSpace.x * 0.5;
				#endif
				poiCam.posScreenPixels = calcPixelScreenUVs(poiCam.posScreenSpace);
				poiCam.vDotN = abs(dot(poiCam.viewDir, poiMesh.normals[1]));
				
				poiCam.worldDirection.xyz = poiMesh.worldPos.xyz - poiCam.worldPos;
				poiCam.worldDirection.w = dot(poiCam.clipPos, CalculateFrustumCorrection());
				
				calculateGlobalThemes(poiMods);
				
				poiLight.finalLightAdd = 0;
				
				// Ambient Occlusion
				#if defined(PROP_LIGHTINGAOMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 AOMaps = POI2D_SAMPLER_PAN(_LightingAOMaps, _MainTex, poiUV(poiMesh.uv[_LightingAOMapsUV], _LightingAOMaps_ST), _LightingAOMapsPan);
				poiLight.occlusion = min(min(min(lerp(1, AOMaps.r, _LightDataAOStrengthR), lerp(1, AOMaps.g, _LightDataAOStrengthG)), lerp(1, AOMaps.b, _LightDataAOStrengthB)), lerp(1, AOMaps.a, _LightDataAOStrengthA));
				#else
				poiLight.occlusion = 1;
				#endif
				
				if (_LightDataAOGlobalMaskR > 0)
				{
					poiLight.occlusion = maskBlend(poiLight.occlusion, poiMods.globalMask[_LightDataAOGlobalMaskR - 1], _LightDataAOGlobalMaskBlendTypeR);
				}
				
				// Detail Shadows
				#if defined(PROP_LIGHTINGDETAILSHADOWMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 DetailShadows = POI2D_SAMPLER_PAN(_LightingDetailShadowMaps, _MainTex, poiUV(poiMesh.uv[_LightingDetailShadowMapsUV], _LightingDetailShadowMaps_ST), _LightingDetailShadowMapsPan);
				#ifndef POI_PASS_ADD
				poiLight.detailShadow = lerp(1, DetailShadows.r, _LightingDetailShadowStrengthR) * lerp(1, DetailShadows.g, _LightingDetailShadowStrengthG) * lerp(1, DetailShadows.b, _LightingDetailShadowStrengthB) * lerp(1, DetailShadows.a, _LightingDetailShadowStrengthA);
				#else
				poiLight.detailShadow = lerp(1, DetailShadows.r, _LightingAddDetailShadowStrengthR) * lerp(1, DetailShadows.g, _LightingAddDetailShadowStrengthG) * lerp(1, DetailShadows.b, _LightingAddDetailShadowStrengthB) * lerp(1, DetailShadows.a, _LightingAddDetailShadowStrengthA);
				#endif
				#else
				poiLight.detailShadow = 1;
				#endif
				
				if (_LightDataDetailShadowGlobalMaskR > 0)
				{
					poiLight.detailShadow = maskBlend(poiLight.detailShadow, poiMods.globalMask[_LightDataDetailShadowGlobalMaskR - 1], _LightDataDetailShadowGlobalMaskBlendTypeR);
				}
				
				// Shadow Masks
				#if defined(PROP_LIGHTINGSHADOWMASKS) || !defined(OPTIMIZER_ENABLED)
				float4 ShadowMasks = POI2D_SAMPLER_PAN(_LightingShadowMasks, _MainTex, poiUV(poiMesh.uv[_LightingShadowMasksUV], _LightingShadowMasks_ST), _LightingShadowMasksPan);
				poiLight.shadowMask = lerp(1, ShadowMasks.r, _LightingShadowMaskStrengthR) * lerp(1, ShadowMasks.g, _LightingShadowMaskStrengthG) * lerp(1, ShadowMasks.b, _LightingShadowMaskStrengthB) * lerp(1, ShadowMasks.a, _LightingShadowMaskStrengthA);
				#else
				poiLight.shadowMask = 1;
				#endif
				if (_LightDataShadowMaskGlobalMaskR > 0)
				{
					poiLight.shadowMask = maskBlend(poiLight.shadowMask, poiMods.globalMask[_LightDataShadowMaskGlobalMaskR - 1], _LightDataShadowMaskGlobalMaskBlendTypeR);
				}
				
				#ifdef UNITY_PASS_FORWARDBASE
				
				bool lightExists = false;
				if (any(_LightColor0.rgb >= 0.002))
				{
					lightExists = true;
				}
				
				if (_LightingVertexLightingEnabled)
				{
					poiFragData.toggleVertexLights = 1;
				}
				if (IsInMirror() && _LightingMirrorVertexLightingEnabled == 0)
				{
					poiFragData.toggleVertexLights = 0;
				}
				
				if (_LightingVertexLightingEnabled)
				{
					#if defined(VERTEXLIGHT_ON)
					float4 toLightX = unity_4LightPosX0 - i.worldPos.x;
					float4 toLightY = unity_4LightPosY0 - i.worldPos.y;
					float4 toLightZ = unity_4LightPosZ0 - i.worldPos.z;
					float4 lengthSq = 0;
					lengthSq += toLightX * toLightX;
					lengthSq += toLightY * toLightY;
					lengthSq += toLightZ * toLightZ;
					
					float4 lightAttenSq = unity_4LightAtten0;
					float4 atten = 1.0 / (1.0 + lengthSq * lightAttenSq);
					float4 vLightWeight = saturate(1 - (lengthSq * lightAttenSq / 25));
					poiLight.vAttenuation = min(atten, vLightWeight * vLightWeight);
					
					poiLight.vDotNL = 0;
					poiLight.vDotNL += toLightX * poiMesh.normals[1].x;
					poiLight.vDotNL += toLightY * poiMesh.normals[1].y;
					poiLight.vDotNL += toLightZ * poiMesh.normals[1].z;
					
					float4 corr = rsqrt(lengthSq);
					poiLight.vertexVDotNL = max(0, poiLight.vDotNL * corr);
					
					poiLight.vertexVDotNL = 0;
					poiLight.vertexVDotNL += toLightX * poiMesh.normals[0].x;
					poiLight.vertexVDotNL += toLightY * poiMesh.normals[0].y;
					poiLight.vertexVDotNL += toLightZ * poiMesh.normals[0].z;
					
					poiLight.vertexVDotNL = max(0, poiLight.vDotNL * corr);
					
					poiLight.vSaturatedDotNL = saturate(poiLight.vDotNL);
					
					[unroll]
					for (int index = 0; index < 4; index++)
					{
						poiLight.vPosition[index] = float3(unity_4LightPosX0[index], unity_4LightPosY0[index], unity_4LightPosZ0[index]);
						
						float3 vertexToLightSource = poiLight.vPosition[index] - poiMesh.worldPos;
						poiLight.vDirection[index] = normalize(vertexToLightSource);
						poiLight.vColor[index] = _LightingAdditiveLimited ? MaxLuminance(unity_LightColor[index].rgb * poiLight.vAttenuation[index], _LightingAdditiveLimit) : unity_LightColor[index].rgb * poiLight.vAttenuation[index];
						poiLight.vColor[index] = lerp(poiLight.vColor[index], dot(poiLight.vColor[index], float3(0.299, 0.587, 0.114)), _LightingAdditiveMonochromatic);
						poiLight.vHalfDir[index] = Unity_SafeNormalize(poiLight.vDirection[index] + poiCam.viewDir);
						poiLight.vDotNL[index] = dot(poiMesh.normals[1], poiLight.vDirection[index]);
						poiLight.vCorrectedDotNL[index] = .5 * (poiLight.vDotNL[index] + 1);
						poiLight.vDotLH[index] = saturate(dot(poiLight.vDirection[index], poiLight.vHalfDir[index]));
						
						poiLight.vDotNH[index] = dot(poiMesh.normals[1], poiLight.vHalfDir[index]);
						poiLight.vertexVDotNH[index] = saturate(dot(poiMesh.normals[0], poiLight.vHalfDir[index]));
					}
					#endif
				}
				
				//UNITY_BRANCH
				if (_LightingColorMode == 0) // Poi Custom Light Color
				
				{
					float3 magic = max(BetterSH9(normalize(unity_SHAr + unity_SHAg + unity_SHAb)), 0);
					float3 normalLight = _LightColor0.rgb + BetterSH9(float4(0, 0, 0, 1));
					
					float magiLumi = calculateluminance(magic);
					float normaLumi = calculateluminance(normalLight);
					float maginormalumi = magiLumi + normaLumi;
					
					float magiratio = magiLumi / maginormalumi;
					float normaRatio = normaLumi / maginormalumi;
					
					float target = calculateluminance(magic * magiratio + normalLight * normaRatio);
					float3 properLightColor = magic + normalLight;
					float properLuminance = calculateluminance(magic + normalLight);
					poiLight.directColor = properLightColor * max(0.0001, (target / properLuminance));
					
					poiLight.indirectColor = BetterSH9(float4(lerp(0, poiMesh.normals[1], _LightingIndirectUsesNormals), 1));
				}
				
				//UNITY_BRANCH
				if (_LightingColorMode == 1) // More standard approach to light color
				
				{
					float3 indirectColor = BetterSH9(float4(poiMesh.normals[1], 1));
					if (lightExists)
					{
						poiLight.directColor = _LightColor0.rgb;
						poiLight.indirectColor = indirectColor;
					}
					else
					{
						poiLight.directColor = indirectColor * 0.6;
						poiLight.indirectColor = indirectColor * 0.5;
					}
				}
				
				if (_LightingColorMode == 2) // UTS style
				
				{
					poiLight.indirectColor = saturate(max(half3(0.05, 0.05, 0.05) * _Unlit_Intensity, max(ShadeSH9(half4(0.0, 0.0, 0.0, 1.0)), ShadeSH9(half4(0.0, -1.0, 0.0, 1.0)).rgb) * _Unlit_Intensity));
					poiLight.directColor = max(poiLight.indirectColor, _LightColor0.rgb);
				}
				
				if (_LightingColorMode == 3) // OpenLit
				
				{
					float3 lightDirectionForSH9 = OpenLitLightingDirectionForSH9();
					OpenLitShadeSH9ToonDouble(lightDirectionForSH9, poiLight.directColor, poiLight.indirectColor);
					poiLight.directColor += _LightColor0.rgb;
					// OpenLit does a few other things by default like clamp direct colour
					// see https://github.com/lilxyzw/OpenLit/blob/main/Assets/OpenLit/core.hlsl#L174
				}
				
				float lightMapMode = _LightingMapMode;
				//UNITY_BRANCH
				if (_LightingDirectionMode == 0)
				{
					poiLight.direction = _WorldSpaceLightPos0.xyz + unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz;
				}
				if (_LightingDirectionMode == 1 || _LightingDirectionMode == 2)
				{
					//UNITY_BRANCH
					if (_LightingDirectionMode == 1)
					{
						poiLight.direction = mul(unity_ObjectToWorld, _LightngForcedDirection).xyz;;
					}
					//UNITY_BRANCH
					if (_LightingDirectionMode == 2)
					{
						poiLight.direction = _LightngForcedDirection;
					}
					if (lightMapMode == 0)
					{
						lightMapMode == 1;
					}
				}
				
				if (_LightingDirectionMode == 3) // UTS
				
				{
					float3 defaultLightDirection = normalize(UNITY_MATRIX_V[2].xyz + UNITY_MATRIX_V[1].xyz);
					float3 lightDirection = normalize(lerp(defaultLightDirection, _WorldSpaceLightPos0.xyz, any(_WorldSpaceLightPos0.xyz)));
					poiLight.direction = lightDirection;
				}
				if (_LightingDirectionMode == 4) // OpenLit
				
				{
					poiLight.direction = OpenLitLightingDirection(); // float4 customDir = 0; // Do we want to give users to alter this (OpenLit always does!)?
					
				}
				
				if (_LightingDirectionMode == 5) // View Direction
				
				{
					float3 upViewDir = normalize(UNITY_MATRIX_V[1].xyz);
					float3 rightViewDir = normalize(UNITY_MATRIX_V[0].xyz);
					float yawOffset_Rads = radians(!IsInMirror() ? - _LightingViewDirOffsetYaw : _LightingViewDirOffsetYaw);
					float3 rotatedViewYaw = normalize(RotateAroundAxis(rightViewDir, upViewDir, yawOffset_Rads));
					float3 rotatedViewCameraMeshOffset = RotateAroundAxis((getCameraPosition() - (poiMesh.worldPos)), upViewDir, yawOffset_Rads);
					float pitchOffset_Rads = radians(!IsInMirror() ? _LightingViewDirOffsetPitch : - _LightingViewDirOffsetPitch);
					float3 rotatedViewPitch = RotateAroundAxis(rotatedViewCameraMeshOffset, rotatedViewYaw, pitchOffset_Rads);
					poiLight.direction = normalize(rotatedViewPitch);
				}
				
				if (!any(poiLight.direction))
				{
					poiLight.direction = float3(.4, 1, .4);
				}
				
				poiLight.direction = normalize(poiLight.direction);
				poiLight.attenuationStrength = _LightingCastedShadows;
				poiLight.attenuation = 1;
				if (!all(_LightColor0.rgb == 0.0))
				{
					UNITY_LIGHT_ATTENUATION(attenuation, i, poiMesh.worldPos)
					poiLight.attenuation *= attenuation;
				}
				
				if (!any(poiLight.directColor) && !any(poiLight.indirectColor) && lightMapMode == 0)
				{
					lightMapMode = 1;
					if (_LightingDirectionMode == 0)
					{
						poiLight.direction = normalize(float3(.4, 1, .4));
					}
				}
				
				poiLight.halfDir = normalize(poiLight.direction + poiCam.viewDir);
				poiLight.vertexNDotL = dot(poiMesh.normals[0], poiLight.direction);
				poiLight.nDotL = dot(poiMesh.normals[1], poiLight.direction);
				poiLight.nDotLSaturated = saturate(poiLight.nDotL);
				poiLight.nDotLNormalized = (poiLight.nDotL + 1) * 0.5;
				poiLight.nDotV = abs(dot(poiMesh.normals[1], poiCam.viewDir));
				poiLight.vertexNDotV = abs(dot(poiMesh.normals[0], poiCam.viewDir));
				poiLight.nDotH = dot(poiMesh.normals[1], poiLight.halfDir);
				poiLight.vertexNDotH = max(0.00001, dot(poiMesh.normals[0], poiLight.halfDir));
				poiLight.lDotv = dot(poiLight.direction, poiCam.viewDir);
				poiLight.lDotH = max(0.00001, dot(poiLight.direction, poiLight.halfDir));
				
				// Poi special light map
				if (lightMapMode == 0)
				{
					float3 ShadeSH9Plus = GetSHLength();
					float3 ShadeSH9Minus = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) + float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0;
					
					float3 greyScaleVector = float3(.33333, .33333, .33333);
					float bw_lightColor = dot(poiLight.directColor, greyScaleVector);
					float bw_directLighting = (((poiLight.nDotL * 0.5 + 0.5) * bw_lightColor * lerp(1, poiLight.attenuation, poiLight.attenuationStrength)) + dot(ShadeSH9(float4(poiMesh.normals[1], 1)), greyScaleVector));
					float bw_directLightingNoAtten = (((poiLight.nDotL * 0.5 + 0.5) * bw_lightColor) + dot(ShadeSH9(float4(poiMesh.normals[1], 1)), greyScaleVector));
					float bw_bottomIndirectLighting = dot(ShadeSH9Minus, greyScaleVector);
					float bw_topIndirectLighting = dot(ShadeSH9Plus, greyScaleVector);
					float lightDifference = ((bw_topIndirectLighting + bw_lightColor) - bw_bottomIndirectLighting);
					
					poiLight.lightMap = smoothstep(0, lightDifference, bw_directLighting - bw_bottomIndirectLighting);
					poiLight.lightMapNoAttenuation = smoothstep(0, lightDifference, bw_directLightingNoAtten - bw_bottomIndirectLighting);
				}
				// Normalized nDotL
				if (lightMapMode == 1)
				{
					poiLight.lightMapNoAttenuation = poiLight.nDotLNormalized;
					poiLight.lightMap = poiLight.nDotLNormalized * lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				}
				// Saturated nDotL
				if (lightMapMode == 2)
				{
					poiLight.lightMapNoAttenuation = poiLight.nDotLSaturated;
					poiLight.lightMap = poiLight.nDotLSaturated * lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				}
				if (lightMapMode == 3)
				{
					poiLight.lightMapNoAttenuation = 1;
					poiLight.lightMap = lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				}
				poiLight.lightMapNoAttenuation *= poiLight.detailShadow;
				poiLight.lightMap *= poiLight.detailShadow;
				
				poiLight.directColor = max(poiLight.directColor, 0.0001);
				poiLight.indirectColor = max(poiLight.indirectColor, 0.0001);
				
				if (_LightingColorMode == 3)
				{
					// OpenLit
					poiLight.directColor = max(poiLight.directColor, _LightingMinLightBrightness);
				}
				else
				{
					poiLight.directColor = max(poiLight.directColor, poiLight.directColor * min(10000, (_LightingMinLightBrightness * rcp(calculateluminance(poiLight.directColor)))));
					poiLight.indirectColor = max(poiLight.indirectColor, poiLight.indirectColor * min(10000, (_LightingMinLightBrightness * rcp(calculateluminance(poiLight.indirectColor)))));
				}
				
				poiLight.directColor = lerp(poiLight.directColor, dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic);
				poiLight.indirectColor = lerp(poiLight.indirectColor, dot(poiLight.indirectColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic);
				
				if (_LightingCapEnabled)
				{
					poiLight.directColor = min(poiLight.directColor, _LightingCap);
					poiLight.indirectColor = min(poiLight.indirectColor, _LightingCap);
				}
				
				if (_LightingForceColorEnabled)
				{
					poiLight.directColor = poiThemeColor(poiMods, _LightingForcedColor, _LightingForcedColorThemeIndex);
				}
				
				#ifdef UNITY_PASS_FORWARDBASE
				poiLight.directColor = max(poiLight.directColor * _PPLightingMultiplier, 0);
				poiLight.directColor = max(poiLight.directColor + _PPLightingAddition, 0);
				poiLight.indirectColor = max(poiLight.indirectColor * _PPLightingMultiplier, 0);
				poiLight.indirectColor = max(poiLight.indirectColor + _PPLightingAddition, 0);
				#endif
				
				#endif
				
				#ifdef POI_PASS_ADD
				if (!_LightingAdditiveEnable)
				{
					return float4(mainTexture.rgb * .0001, 1);
				}
				
				#if defined(DIRECTIONAL)
				if (_DisableDirectionalInAdd)
				{
					return float4(mainTexture.rgb * .0001, 1);
				}
				#endif
				
				poiLight.direction = normalize(_WorldSpaceLightPos0.xyz - i.worldPos.xyz * _WorldSpaceLightPos0.w);
				#if defined(POINT) || defined(SPOT)
				#ifdef POINT
				unityShadowCoord3 lightCoord = mul(unity_WorldToLight, unityShadowCoord4(poiMesh.worldPos, 1)).xyz;
				poiLight.attenuation = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).r;
				#endif
				
				#ifdef SPOT
				unityShadowCoord4 lightCoord = mul(unity_WorldToLight, unityShadowCoord4(poiMesh.worldPos, 1));
				poiLight.attenuation = (lightCoord.z > 0) * UnitySpotCookie(lightCoord) * UnitySpotAttenuate(lightCoord.xyz);
				#endif
				#else
				UNITY_LIGHT_ATTENUATION(attenuation, i, poiMesh.worldPos)
				poiLight.attenuation = attenuation;
				#endif
				poiLight.additiveShadow = UNITY_SHADOW_ATTENUATION(i, poiMesh.worldPos);
				poiLight.attenuationStrength = _LightingAdditiveCastedShadows;
				poiLight.directColor = _LightingAdditiveLimited ? MaxLuminance(_LightColor0.rgb * poiLight.attenuation, _LightingAdditiveLimit) : _LightColor0.rgb  * poiLight.attenuation;
				
				#if defined(POINT_COOKIE) || defined(DIRECTIONAL_COOKIE)
				poiLight.indirectColor = 0;
				#else
				poiLight.indirectColor = lerp(0, poiLight.directColor, _LightingAdditivePassthrough);
				poiLight.indirectColor = _LightingAdditiveLimited ? MaxLuminance(poiLight.indirectColor, _LightingAdditiveLimit) : poiLight.indirectColor;
				#endif
				
				poiLight.directColor = lerp(poiLight.directColor, dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), _LightingAdditiveMonochromatic);
				poiLight.indirectColor = lerp(poiLight.indirectColor, dot(poiLight.indirectColor, float3(0.299, 0.587, 0.114)), _LightingAdditiveMonochromatic);
				
				poiLight.halfDir = normalize(poiLight.direction + poiCam.viewDir);
				poiLight.nDotL = dot(poiMesh.normals[1], poiLight.direction);
				poiLight.nDotLSaturated = saturate(poiLight.nDotL);
				poiLight.nDotLNormalized = (poiLight.nDotL + 1) * 0.5;
				poiLight.nDotV = abs(dot(poiMesh.normals[1], poiCam.viewDir));
				poiLight.nDotH = dot(poiMesh.normals[1], poiLight.halfDir);
				poiLight.lDotv = dot(poiLight.direction, poiCam.viewDir);
				poiLight.lDotH = dot(poiLight.direction, poiLight.halfDir);
				poiLight.vertexNDotL = dot(poiMesh.normals[0], poiLight.direction);
				poiLight.vertexNDotV = abs(dot(poiMesh.normals[0], poiCam.viewDir));
				poiLight.vertexNDotH = max(0.00001, dot(poiMesh.normals[0], poiLight.halfDir));
				
				// Normalized nDotL
				if (_LightingMapMode == 0 || _LightingMapMode == 1 || _LightingMapMode == 2)
				{
					poiLight.lightMap = poiLight.nDotLNormalized;
				}
				if (_LightingMapMode == 3)
				{
					poiLight.lightMap = 1;
				}
				poiLight.lightMap *= poiLight.detailShadow;
				poiLight.lightMapNoAttenuation = poiLight.lightMap;
				poiLight.lightMap *= lerp(1, poiLight.additiveShadow, poiLight.attenuationStrength);
				#endif
				
				//ifex _LightDataDebugEnabled==0
				if (_LightDataDebugEnabled)
				{
					#ifdef UNITY_PASS_FORWARDBASE
					//UNITY_BRANCH
					if (_LightingDebugVisualize <= 6)
					{
						switch(_LightingDebugVisualize)
						{
							case 0: // Direct Light Color
							return float4(poiLight.directColor + mainTexture.rgb * .0001, 1);
							break;
							case 1: // Indirect Light Color
							return float4(poiLight.indirectColor + mainTexture.rgb * .0001, 1);
							break;
							case 2: // Light Map
							return float4(poiLight.lightMap + mainTexture.rgb * .0001, 1);
							break;
							case 3: // Attenuation
							return float4(poiLight.attenuation + mainTexture.rgb * .0001, 1);
							break;
							case 4: // N Dot L
							return float4(poiLight.nDotLNormalized, poiLight.nDotLNormalized, poiLight.nDotLNormalized, 1) + mainTexture * .0001;
							break;
							case 5:
							return float4(poiLight.halfDir, 1) + mainTexture * .0001;
							break;
							case 6:
							return float4(poiLight.direction, 1) + mainTexture * .0001;
							break;
						}
					}
					else
					{
						return POI_SAFE_RGB1;
					}
					#endif
					#ifdef POI_PASS_ADD
					//UNITY_BRANCH
					if (_LightingDebugVisualize < 6)
					{
						return POI_SAFE_RGB1;
					}
					else
					{
						switch(_LightingDebugVisualize)
						{
							case 7:
							return float4(poiLight.directColor * poiLight.attenuation + mainTexture.rgb * .0001, 1);
							break;
							case 8:
							return float4(poiLight.attenuation + mainTexture.rgb * .0001, 1);
							break;
							case 9:
							return float4(poiLight.additiveShadow + mainTexture.rgb * .0001, 1);
							break;
							case 10:
							return float4(poiLight.nDotLNormalized + mainTexture.rgb * .0001, 1);
							break;
							case 11:
							return float4(poiLight.halfDir, 1) + mainTexture * .0001;
							break;
						}
					}
					#endif
				}
				//endex
				
				//ifex _EnableAudioLink==0
				#ifdef POI_AUDIOLINK
				SetupAudioLink(poiFragData, poiMods, poiMesh);
				#endif
				//endex
				
				//ifex _MochieBRDF==0
				#if defined(MOCHIE_PBR)
				MetallicAndSpecularFragDataInit(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _BlackLightMaskingEnabled==0
				#ifdef POI_BLACKLIGHTMASKING
				calculateBlackLightMasks(poiMesh, poiMods);
				#endif
				//endex
				
				poiFragData.baseColor = mainTexture.rgb * poiThemeColor(poiMods, _Color.rgb, _ColorThemeIndex);
				poiFragData.alpha = mainTexture.a * _Color.a;
				
				//ifex _MainColorAdjustToggle==0
				#ifdef COLOR_GRADING_HDR
				#if defined(PROP_MAINCOLORADJUSTTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 hueShiftAlpha = POI2D_SAMPLER_PAN(_MainColorAdjustTexture, _MainTex, poiUV(poiMesh.uv[_MainColorAdjustTextureUV], _MainColorAdjustTexture_ST), _MainColorAdjustTexturePan);
				#else
				float4 hueShiftAlpha = 1;
				#endif
				
				if (_MainHueGlobalMask > 0)
				{
					hueShiftAlpha.r = maskBlend(hueShiftAlpha.r, poiMods.globalMask[_MainHueGlobalMask - 1], _MainHueGlobalMaskBlendType);
				}
				if (_MainSaturationGlobalMask > 0)
				{
					hueShiftAlpha.b = maskBlend(hueShiftAlpha.b, poiMods.globalMask[_MainSaturationGlobalMask - 1], _MainSaturationGlobalMaskBlendType);
				}
				if (_MainBrightnessGlobalMask > 0)
				{
					hueShiftAlpha.g = maskBlend(hueShiftAlpha.g, poiMods.globalMask[_MainBrightnessGlobalMask - 1], _MainBrightnessGlobalMaskBlendType);
				}
				
				if (_MainHueShiftToggle)
				{
					float shift = _MainHueShift;
					#ifdef POI_AUDIOLINK
					//UNITY_BRANCH
					if (poiMods.audioLinkAvailable && _MainHueALCTEnabled)
					{
						shift += AudioLinkGetChronoTime(_MainALHueShiftCTIndex, _MainALHueShiftBand) * _MainHueALMotionSpeed;
					}
					#endif
					if (_MainHueShiftReplace)
					{
						poiFragData.baseColor = lerp(poiFragData.baseColor, hueShift(poiFragData.baseColor, shift + _MainHueShiftSpeed * _Time.x), hueShiftAlpha.r);
					}
					else
					{
						poiFragData.baseColor = hueShift(poiFragData.baseColor, frac((shift - (1 - hueShiftAlpha.r) + _MainHueShiftSpeed * _Time.x)));
					}
				}
				
				if (_MainGradationStrength && _ColorGradingToggle)
				{
					#if !defined(UNITY_COLORSPACE_GAMMA)
					float3 tempColor = OpenLitLinearToSRGB(poiFragData.baseColor);
					#else
					float3 tempColor = poiFragData.baseColor;
					#endif
					#if defined(PROP_MAINGRADATIONTEX) || !defined(OPTIMIZER_ENABLED)
					tempColor.r = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.r).r;
					tempColor.g = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.g).g;
					tempColor.b = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.b).b;
					#else
					tempColor = float3(1, 1, 1);
					#endif
					#if !defined(UNITY_COLORSPACE_GAMMA)
					tempColor = OpenLitSRGBToLinear(tempColor);
					#endif
					poiFragData.baseColor = lerp(poiFragData.baseColor, tempColor, _MainGradationStrength);
				}
				
				poiFragData.baseColor = lerp(poiFragData.baseColor, dot(poiFragData.baseColor, float3(0.3, 0.59, 0.11)), - (_Saturation) * hueShiftAlpha.b);
				poiFragData.baseColor = saturate(lerp(poiFragData.baseColor, poiFragData.baseColor * (_MainBrightness + 1), hueShiftAlpha.g));
				#endif
				//endex
				
				#if defined(PROP_ALPHAMASK) || !defined(OPTIMIZER_ENABLED)
				
				if (_MainAlphaMaskMode)
				{
					float alphaMask = POI2D_SAMPLER_PAN(_AlphaMask, _MainTex, poiUV(poiMesh.uv[_AlphaMaskUV], _AlphaMask_ST), _AlphaMaskPan.xy).r;
					alphaMask = saturate(alphaMask * _AlphaMaskScale + _AlphaMaskValue);
					if (_AlphaMaskInvert) alphaMask = 1 - alphaMask;
					if (_MainAlphaMaskMode == 1) poiFragData.alpha = alphaMask;
					if (_MainAlphaMaskMode == 2) poiFragData.alpha = poiFragData.alpha * alphaMask;
					if (_MainAlphaMaskMode == 3) poiFragData.alpha = saturate(poiFragData.alpha + alphaMask);
					if (_MainAlphaMaskMode == 4) poiFragData.alpha = saturate(poiFragData.alpha - alphaMask);
				}
				#endif
				
				//ifex _VideoEffectsEnable==0
				#ifdef POI_VIDEO_EFFECTS
				if (_VideoEffectsEnable)
				{
					applyVideoEffects(poiFragData, poiCam, poiMesh, poiLight, poiMods);
				}
				#endif
				//endex
				
				applyAlphaOptions(poiFragData, poiMesh, poiCam, poiMods);
				
				//ifex _EnableTouchGlow==0
				#ifdef GRAIN
				applyDepthFX(poiFragData, poiCam, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _DetailEnabled==0
				#ifdef FINALPASS
				ApplyDetailColor(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _MainVertexColoringEnabled==0
				applyVertexColor(poiFragData, poiMesh);
				//endex
				
				//ifex _BackFaceEnabled!=1
				#ifdef POI_BACKFACE
				ApplyBackFaceColor(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _RGBMaskEnabled==0
				#ifdef VIGNETTE
				calculateRGBMask(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _EnableDissolve==0
				#ifdef DISTORT
				applyDissolve(poiFragData, poiMesh, poiMods, poiCam, poiLight);
				#endif
				//endex
				
				//ifex _ShadingEnabled==0
				#if defined(_LIGHTINGMODE_SHADEMAP) && defined(VIGNETTE_MASKED)
				#ifndef POI_PASS_OUTLINE
				#ifdef _LIGHTINGMODE_SHADEMAP
				applyShadeMapping(poiFragData, poiMesh, poiLight);
				#endif
				#endif
				#endif
				//endex
				
				//ifex _ShadingEnabled==0
				#ifdef VIGNETTE_MASKED
				#ifdef POI_PASS_OUTLINE
				//UNITY_BRANCH
				if (_OutlineLit)
				{
					calculateShading(poiLight, poiFragData, poiMesh, poiCam);
				}
				else
				{
					poiLight.finalLighting = 1;
				}
				#else
				calculateShading(poiLight, poiFragData, poiMesh, poiCam);
				#endif
				#else
				//endex
				poiLight.finalLighting = 1;
				poiLight.rampedLightMap = poiEdgeNonLinear(poiLight.nDotL, 0.1, .1);
				//ifex _ShadingEnabled==0
				#endif
				if (_ShadingRampedLightMapApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _ShadingRampedLightMapApplyGlobalMaskIndex - 1, _ShadingRampedLightMapApplyGlobalMaskBlendType, poiLight.rampedLightMap);
				}
				if (_ShadingRampedLightMapInverseApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _ShadingRampedLightMapInverseApplyGlobalMaskIndex - 1, _ShadingRampedLightMapInverseApplyGlobalMaskBlendType, 1 - poiLight.rampedLightMap);
				}
				
				poiLight.directLuminance = dot(poiLight.directColor, float3(0.299, 0.587, 0.114));
				poiLight.indirectLuminance = dot(poiLight.directColor, float3(0.299, 0.587, 0.114));
				poiLight.finalLuminance = dot(poiLight.finalLighting, float3(0.299, 0.587, 0.114));
				//endex
				
				#if defined(GEOM_TYPE_BRANCH) || defined(GEOM_TYPE_BRANCH_DETAIL) || defined(GEOM_TYPE_FROND) || defined(DEPTH_OF_FIELD_COC_VIEW)
				applyDecals(poiFragData, poiMesh, poiCam, poiMods, poiLight);
				#endif
				
				//ifex _EnableAniso==0
				#ifdef POI_ANISOTROPICS
				applyAnisotropics(poiFragData, poiLight, poiCam, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _MatcapEnable==0 && _Matcap2Enable==0 && _Matcap3Enable==0 && _Matcap4Enable==0
				#if defined(POI_MATCAP0) || defined(COLOR_GRADING_HDR_3D) || defined(POI_MATCAP2) || defined(POI_MATCAP3)
				applyMatcap(poiFragData, poiCam, poiMesh, poiLight, poiMods);
				#endif
				//endex
				
				//ifex _CubeMapEnabled==0
				#ifdef _CUBEMAP
				applyCubemap(poiFragData, poiCam, poiMesh, poiLight, poiMods);
				#endif
				//endex
				
				//ifex _EnableALDecal==0
				#ifdef POI_AUDIOLINK
				#ifdef POI_AL_DECAL
				ApplyAudioLinkDecal(poiMesh, poiFragData, poiMods);
				#endif
				#endif
				//endex
				
				//ifex _EnableVolumeColor==0
				#ifdef POI_AUDIOLINK
				#ifdef POI_AL_VOLUMECOLOR
				ApplyAudioLinkVolumeColor(poiMesh, poiFragData, poiMods);
				#endif
				#endif
				//endex
				
				//ifex _EnableFlipbook==0
				#ifdef _SUNDISK_HIGH_QUALITY
				applyFlipbook(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _EnableRimLighting==0
				#ifdef _GLOSSYREFLECTIONS_OFF
				#ifdef _RIMSTYLE_POIYOMI
				#if defined(PROP_RIMMASK) || !defined(OPTIMIZER_ENABLED)
				float4 rimMaskAndBias = POI2D_SAMPLER_PAN(_RimMask, _MainTex, poiUV(poiMesh.uv[_RimMaskUV], _RimMask_ST), _RimMaskPan);
				float rimMask = rimMaskAndBias[_RimMaskChannel];
				float rimBias = rimMaskAndBias.a;
				#else
				float rimMask = 1;
				float rimBias = 0;
				#endif
				
				if (_RimMaskInvert)
				{
					rimMask = 1 - rimMask;
				}
				
				#if defined(PROP_RIMTEX) || !defined(OPTIMIZER_ENABLED)
				float4 rimColor = POI2D_SAMPLER_PAN(_RimTex, _MainTex, poiUV(poiMesh.uv[_RimTexUV], _RimTex_ST), _RimTexPan);
				#else
				float4 rimColor = 1;
				#endif
				half AudioLinkRimWidthBand = 0;
				float2 AudioLinkRimWidthAdd = 0;
				half AudioLinkRimEmissionBand = 0;
				float2 AudioLinkRimEmissionAdd = 0;
				half AudioLinkRimBrightnessBand = 0;
				float2 AudioLinkRimBrightnessAdd = 0;
				#ifdef POI_AUDIOLINK
				AudioLinkRimWidthBand = _AudioLinkRimWidthBand;
				AudioLinkRimWidthAdd = _AudioLinkRimWidthAdd;
				AudioLinkRimEmissionBand = _AudioLinkRimEmissionBand;
				AudioLinkRimEmissionAdd = _AudioLinkRimEmissionAdd;
				AudioLinkRimBrightnessBand = _AudioLinkRimBrightnessBand;
				AudioLinkRimBrightnessAdd = _AudioLinkRimBrightnessAdd;
				#endif
				
				ApplyPoiyomiRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, _Is_NormalMapToRimLight, _RimLightingInvert, _RimPower, _RimStrength, _RimShadowWidth, _RimShadowToggle, _RimWidth, _RimBlendStrength, rimMask, _RimGlobalMask, _RimGlobalMaskBlendType, rimColor, _RimLightColor, _RimLightColorThemeIndex, _RimHueShiftEnabled, _RimHueShift, _RimHueShiftSpeed, _RimSharpness, _RimShadowMaskRampType, _RimShadowMaskInvert, _RimShadowMaskStrength, _RimShadowAlpha, _RimApplyGlobalMaskIndex, _RimApplyGlobalMaskBlendType, _RimBaseColorMix, _RimBrightness, _RimPoiBlendMode, AudioLinkRimWidthBand, AudioLinkRimWidthAdd, AudioLinkRimEmissionBand, AudioLinkRimEmissionAdd, AudioLinkRimBrightnessBand, AudioLinkRimBrightnessAdd, rimBias, _RimBiasIntensity, _RimApplyAlpha, _RimApplyAlphaBlend);
				#endif
				#ifdef _RIMSTYLE_UTS2
				#if defined(PROP_SET_RIMLIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float Set_RimLightMask_var = POI2D_SAMPLER_PAN(_Set_RimLightMask, _MainTex, poiUV(poiMesh.uv[_Set_RimLightMaskUV], _Set_RimLightMask_ST), _Set_RimLightMaskPan)[_Set_RimLightMaskChannel];
				#else
				float Set_RimLightMask_var = 1;
				#endif
				ApplyUTS2RimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, Set_RimLightMask_var, _RimGlobalMask, _RimGlobalMaskBlendType, _RimLightColor, _RimLightColorThemeIndex, _Is_LightColor_RimLight, _Is_NormalMapToRimLight, _RimLight_Power, _RimLight_InsideMask, _RimLight_FeatherOff, _LightDirection_MaskOn, _Tweak_LightDirection_MaskLevel, _Add_Antipodean_RimLight, _Ap_RimLightColor, _RimApColorThemeIndex, _Is_LightColor_Ap_RimLight, _Ap_RimLight_Power, _Ap_RimLight_FeatherOff, _Tweak_RimLightMaskLevel, _RimHueShiftEnabled, _RimHueShift, _RimHueShiftSpeed);
				#endif
				
				#endif
				//endex
				//ifex _EnableRim2Lighting==0
				#ifdef POI_RIM2
				#ifdef _RIM2STYLE_POIYOMI
				#if defined(PROP_RIM2MASK) || !defined(OPTIMIZER_ENABLED)
				float4 rim2MaskAndBias = POI2D_SAMPLER_PAN(_Rim2Mask, _MainTex, poiUV(poiMesh.uv[_Rim2MaskUV], _Rim2Mask_ST), _Rim2MaskPan);
				float rim2Mask = rim2MaskAndBias[_Rim2MaskChannel];
				float rim2Bias = rim2MaskAndBias.a;
				#else
				float rim2Mask = 1;
				float rim2Bias = 0;
				#endif
				
				if (_Rim2MaskInvert)
				{
					rim2Mask = 1 - rim2Mask;
				}
				
				#if defined(PROP_RIM2TEX) || !defined(OPTIMIZER_ENABLED)
				float4 rim2Color = POI2D_SAMPLER_PAN(_Rim2Tex, _MainTex, poiUV(poiMesh.uv[_Rim2TexUV], _Rim2Tex_ST), _Rim2TexPan);
				#else
				float4 rim2Color = 1;
				#endif
				half AudioLinkRim2WidthBand = 0;
				float2 AudioLinkRim2WidthAdd = 0;
				half AudioLinkRim2EmissionBand = 0;
				float2 AudioLinkRim2EmissionAdd = 0;
				half AudioLinkRim2BrightnessBand = 0;
				float2 AudioLinkRim2BrightnessAdd = 0;
				#ifdef POI_AUDIOLINK
				AudioLinkRim2WidthBand = _AudioLinkRim2WidthBand;
				AudioLinkRim2WidthAdd = _AudioLinkRim2WidthAdd;
				AudioLinkRim2EmissionBand = _AudioLinkRim2EmissionBand;
				AudioLinkRim2EmissionAdd = _AudioLinkRim2EmissionAdd;
				AudioLinkRim2BrightnessBand = _AudioLinkRim2BrightnessBand;
				AudioLinkRim2BrightnessAdd = _AudioLinkRim2BrightnessAdd;
				#endif
				ApplyPoiyomiRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, _Is_NormalMapToRim2Light, _Rim2LightingInvert, _Rim2Power, _Rim2Strength, _Rim2ShadowWidth, _Rim2ShadowToggle, _Rim2Width, _Rim2BlendStrength, rim2Mask, _Rim2GlobalMask, _Rim2GlobalMaskBlendType, rim2Color, _Rim2LightColor, _Rim2LightColorThemeIndex, _Rim2HueShiftEnabled, _Rim2HueShift, _Rim2HueShiftSpeed, _Rim2Sharpness, _Rim2ShadowMaskRampType, _Rim2ShadowMaskInvert, _Rim2ShadowMaskStrength, _Rim2ShadowAlpha, _Rim2ApplyGlobalMaskIndex, _Rim2ApplyGlobalMaskBlendType, _Rim2BaseColorMix, _Rim2Brightness, _RimPoi2BlendMode, AudioLinkRim2WidthBand, AudioLinkRim2WidthAdd, AudioLinkRim2EmissionBand, AudioLinkRim2EmissionAdd, AudioLinkRim2BrightnessBand, AudioLinkRim2BrightnessAdd, rim2Bias, _Rim2BiasIntensity, _Rim2ApplyAlpha, _Rim2ApplyAlphaBlend);
				#endif
				#ifdef _RIM2STYLE_UTS2
				#if defined(PROP_SET_RIM2LIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float Set_Rim2LightMask_var = POI2D_SAMPLER_PAN(_Set_Rim2LightMask, _MainTex, poiUV(poiMesh.uv[_Set_Rim2LightMaskUV], _Set_Rim2LightMask_ST), _Set_Rim2LightMaskPan)[_Set_Rim2LightMaskChannel];
				#else
				float Set_Rim2LightMask_var = 1;
				#endif
				ApplyUTS2RimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, Set_Rim2LightMask_var, _Rim2GlobalMask, _Rim2GlobalMaskBlendType, _Rim2LightColor, _Rim2LightColorThemeIndex, _Is_LightColor_Rim2Light, _Is_NormalMapToRim2Light, _Rim2Light_Power, _Rim2Light_InsideMask, _Rim2Light_FeatherOff, _LightDirection_MaskOn2, _Tweak_LightDirection_MaskLevel2, _Add_Antipodean_Rim2Light, _Ap_Rim2LightColor, _Rim2ApColorThemeIndex, _Is_LightColor_Ap_Rim2Light, _Ap_Rim2Light_Power, _Ap_Rim2Light_FeatherOff, _Tweak_Rim2LightMaskLevel, _Rim2HueShiftEnabled, _Rim2HueShift, _Rim2HueShiftSpeed);
				#endif
				
				#endif
				//endex
				
				//ifex _EnableDepthRimLighting==0
				#ifdef _POI_DEPTH_RIMLIGHT
				if (!IsInMirror())
				{
					ApplyDepthRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods);
				}
				#endif
				//endex
				
				//ifex _GlitterEnable==0
				#ifdef _SUNDISK_SIMPLE
				applyGlitter(poiFragData, poiMesh, poiCam, poiLight, poiMods);
				#endif
				//endex
				
				//ifex _StylizedSpecular==0
				#ifdef POI_STYLIZED_StylizedSpecular
				stylizedSpecular(poiFragData, poiCam, poiLight, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _EnablePathing==0
				#ifdef POI_PATHING
				// Only run pathing if a map exists.
				#if defined(PROP_PATHINGMAP) || !defined(OPTIMIZER_ENABLED)
				applyPathing(poiFragData, poiMesh, poiMods);
				#endif
				#endif
				//endex
				
				//ifex _EnableMirrorOptions==0
				#ifdef POI_MIRROR
				applyMirror(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _TextEnabled==0
				#ifdef EFFECT_BUMP
				ApplyTextOverlayColor(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _PoiInternalParallax==0
				#ifdef POI_INTERNALPARALLAX
				applyInternalParallax(poiFragData, poiMesh, poiCam, poiMods);
				#endif
				//endex
				
				//ifex _VoronoiEnabled!=1
				#ifdef POI_VORONOI
				ApplyVoronoi(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				UNITY_BRANCH
				if (_AlphaPremultiply)
				{
					poiFragData.baseColor *= saturate(poiFragData.alpha);
				}
				poiFragData.finalColor = poiFragData.baseColor;
				
				//ifex _LTCGIEnabled!=1
				#ifdef POI_LTCGI
				if (_LTCGI_AnimToggle)
				{
					float LTCGIsmoothness = _LTCGI_Smoothness;
					float LTCGImetalness = _LTCGI_Metallic;
					float LTCGISpecMask = 1;
					
					if (_LTCGI_UsePBR)
					{
						#ifdef MOCHIE_PBR
						float smoothness = _MochieRoughnessMultiplier;
						float metallic = _MochieMetallicMultiplier;
						float specularMask = 1;
						float reflectionMask = 1;
						
						#if defined(PROP_MOCHIEMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
						float4 PBRMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_MochieMetallicMaps, _MainTex, poiUV(poiMesh.uv[_MochieMetallicMapsUV], _MochieMetallicMaps_ST), _MochieMetallicMapsPan, _MochieMetallicMapsStochastic);
						UNITY_BRANCH
						if (_PBRSplitMaskSample)
						{
							float4 PBRSplitMask = POI2D_SAMPLER_PAN_STOCHASTIC(_MochieMetallicMaps, _MainTex, poiUV(poiMesh.uv[_MochieMetallicMasksUV], _PBRMaskScaleTiling), _MochieMetallicMasksPan.xy, _PBRSplitMaskStochastic);
							assignValueToVectorFromIndex(PBRMaps, _MochieMetallicMapsReflectionMaskChannel, PBRSplitMask[_MochieMetallicMapsReflectionMaskChannel]);
							assignValueToVectorFromIndex(PBRMaps, _MochieMetallicMapsSpecularMaskChannel, PBRSplitMask[_MochieMetallicMapsSpecularMaskChannel]);
						}
						
						if (_MochieMetallicMapsMetallicChannel < 4)
						{
							metallic *= PBRMaps[_MochieMetallicMapsMetallicChannel];
						}
						if (_MochieMetallicMapsRoughnessChannel < 4)
						{
							smoothness *= PBRMaps[_MochieMetallicMapsRoughnessChannel];
						}
						if (_MochieMetallicMapsReflectionMaskChannel < 4)
						{
							reflectionMask *= PBRMaps[_MochieMetallicMapsReflectionMaskChannel];
						}
						if (_MochieMetallicMapsSpecularMaskChannel < 4)
						{
							specularMask *= PBRMaps[_MochieMetallicMapsSpecularMaskChannel];
						}
						#endif
						LTCGIsmoothness = smoothness;
						LTCGImetalness = metallic;
						#endif
					}
					accumulator_struct acc = (accumulator_struct)0;
					
					// then we make the LTCGI_Contribution call as usual, but with slightly different params
					LTCGI_Contribution(
					acc, // our accumulator
					poiMesh.worldPos, // world position of the shaded point
					poiMesh.normals[1], // world space normal
					normalize(poiCam.worldPos - poiMesh.worldPos), // view vector to shaded point, normalized
					1.0f - LTCGIsmoothness, // roughness
					poiMesh.uv[1] // shadowmap coordinates (the normal Unity ones, they should be in sync with LTCGI maps)
					);
					acc.specular *= poiThemeColor(poiMods, _LTCGI_SpecularColor.rgb, _LTCGI_SpecularColorThemeIndex);
					acc.diffuse *= poiThemeColor(poiMods, _LTCGI_DiffuseColor.rgb, _LTCGI_DiffuseColorThemeIndex);
					
					poiLight.finalLightAdd += (acc.specular * lerp(unity_ColorSpaceDielectricSpec, poiFragData.baseColor, LTCGImetalness)) * LTCGISpecMask;
					
					poiLight.finalLighting += acc.diffuse;
					if (_LightingCapEnabled)
					{
						poiLight.finalLighting = min(poiLight.finalLighting, _LightingCap);
					}
				}
				#endif
				//endex
				
				poiFragData.finalColor = poiFragData.baseColor * poiLight.finalLighting;
				
				//ifex _SubsurfaceScattering==0
				#ifdef POI_SUBSURFACESCATTERING
				applySubsurfaceScattering(poiCam, poiLight, poiMesh, poiFragData);
				#endif
				//endex
				
				//ifex _MochieBRDF==0
				#ifdef MOCHIE_PBR
				MochieBRDF(poiFragData, poiCam, poiLight, poiMesh, poiMods);
				#endif
				//endex
				//ifex _ClearCoatBRDF==0
				#ifdef POI_CLEARCOAT
				poiClearCoat(poiFragData, poiCam, poiLight, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _EnableEnvironmentalRim==0
				#ifdef POI_ENVIRORIM
				applyEnvironmentRim(poiFragData, poiMesh, poiCam);
				#endif
				//endex
				
				//ifex _BacklightEnabled!=1
				#ifdef POI_BACKLIGHT
				ApplyBacklight(poiFragData, poiMesh, poiLight, poiCam, poiMods);
				#endif
				//endex
				
				//ifex _EnableRimLighting==0
				#ifdef _GLOSSYREFLECTIONS_OFF
				#ifdef _RIMSTYLE_LILTOON
				#if defined(PROP_RIMCOLORTEX) || !defined(OPTIMIZER_ENABLED)
				float4 rimColorTex = POI2D_SAMPLER_PAN(_RimColorTex, _MainTex, poiUV(poiMesh.uv[_RimColorTexUV], _RimColorTex_ST), _RimColorTexPan);
				#else
				float4 rimColorTex = 1;
				#endif
				ApplyLiltoonRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, _RimColor, _RimIndirColor, rimColorTex, _RimMainStrength, _RimNormalStrength, _RimDirRange, _RimIndirRange, _RimFresnelPower, _RimBackfaceMask, _RimDirStrength, _RimBorder, _RimBlur, _RimIndirBorder, _RimIndirBlur, _RimShadowMask, _RimEnableLighting, _RimVRParallaxStrength, _RimGlobalMask, _RimGlobalMaskBlendType, _RimHueShiftEnabled, _RimHueShift, _RimHueShiftSpeed, _RimBlendMode);
				#endif
				#endif
				//endex
				//ifex _EnableRim2Lighting==0
				#ifdef POI_RIM2
				#ifdef _RIM2STYLE_LILTOON
				#if defined(PROP_RIM2COLORTEX) || !defined(OPTIMIZER_ENABLED)
				float4 rim2ColorTex = POI2D_SAMPLER_PAN(_Rim2ColorTex, _MainTex, poiUV(poiMesh.uv[_Rim2ColorTexUV], _Rim2ColorTex_ST), _Rim2ColorTexPan);
				#else
				float4 rim2ColorTex = 1;
				#endif
				ApplyLiltoonRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, _Rim2Color, _Rim2IndirColor, rim2ColorTex, _Rim2MainStrength, _Rim2NormalStrength, _Rim2DirRange, _Rim2IndirRange, _Rim2FresnelPower, _Rim2BackfaceMask, _Rim2DirStrength, _Rim2Border, _Rim2Blur, _Rim2IndirBorder, _Rim2IndirBlur, _Rim2ShadowMask, _Rim2EnableLighting, _Rim2VRParallaxStrength, _Rim2GlobalMask, _Rim2GlobalMaskBlendType, _Rim2HueShiftEnabled, _Rim2HueShift, _Rim2HueShiftSpeed, _Rim2BlendMode);
				#endif
				#endif
				//endex
				
				//ifex _FXProximityColor==0
				if (_FXProximityColor)
				{
					float3 position = _FXProximityColorType ? poiMesh.worldPos : poiMesh.objectPosition;
					poiFragData.finalColor *= lerp(poiThemeColor(poiMods, _FXProximityColorMinColor.rgb, _FXProximityColorMinColorThemeIndex), poiThemeColor(poiMods, _FXProximityColorMaxColor.rgb, _FXProximityColorMaxColorThemeIndex), smoothstep(_FXProximityColorMinDistance, _FXProximityColorMaxDistance, distance(position, poiCam.worldPos)));
					
					if (_FXProximityColorBackFace)
					{
						poiFragData.finalColor = lerp(poiFragData.finalColor * _FXProximityColorMinColor.rgb, poiFragData.finalColor, saturate(poiMesh.isFrontFace));
					}
				}
				//endex
				
				//ifex _EnableEmission==0 && _EnableEmission1==0 && _EnableEmission2==0 && _EnableEmission3==0
				#if defined(_EMISSION) || defined(POI_EMISSION_1) || defined(POI_EMISSION_2) || defined(POI_EMISSION_3)
				float3 emissionBaseReplace = 0;
				#endif
				//endex
				
				//ifex _EnableEmission==0
				#ifdef _EMISSION
				emissionBaseReplace += applyEmission(poiFragData, poiMesh, poiLight, poiCam, poiMods);
				#endif
				//endex
				//ifex _EnableEmission1==0
				#ifdef POI_EMISSION_1
				emissionBaseReplace += applyEmission1(poiFragData, poiMesh, poiLight, poiCam, poiMods);
				#endif
				//endex
				//ifex _EnableEmission2==0
				#ifdef POI_EMISSION_2
				emissionBaseReplace += applyEmission2(poiFragData, poiMesh, poiLight, poiCam, poiMods);
				#endif
				//endex
				//ifex _EnableEmission3==0
				#ifdef POI_EMISSION_3
				emissionBaseReplace += applyEmission3(poiFragData, poiMesh, poiLight, poiCam, poiMods);
				#endif
				//endex
				
				//ifex _EnableEmission==0 && _EnableEmission1==0 && _EnableEmission2==0 && _EnableEmission3==0
				#if defined(_EMISSION) || defined(POI_EMISSION_1) || defined(POI_EMISSION_2) || defined(POI_EMISSION_3)
				poiFragData.finalColor.rgb = lerp(poiFragData.finalColor.rgb, saturate(emissionBaseReplace), poiMax(emissionBaseReplace));
				#endif
				//endex
				
				//UNITY_BRANCH
				if (_IgnoreFog == 0)
				{
					UNITY_APPLY_FOG(i.fogCoord, poiFragData.finalColor);
				}
				
				poiFragData.alpha = _AlphaForceOpaque ? 1 : poiFragData.alpha;
				
				//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
				ApplyAlphaToCoverage(poiFragData, poiMesh);
				//endex
				
				//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
				applyDithering(poiFragData, poiCam);
				//endex
				
				poiFragData.finalColor += poiLight.finalLightAdd;
				
				#ifdef UNITY_PASS_FORWARDBASE
				poiFragData.emission = max(poiFragData.emission * _PPEmissionMultiplier, 0);
				poiFragData.finalColor = max(poiFragData.finalColor * _PPFinalColorMultiplier, 0);
				#endif
				
				//ifex _PostProcess==0
				#ifdef POSTPROCESS
				applyPostProcessing(poiFragData, poiMesh);
				#endif
				//endex
				
				if (_Mode == POI_MODE_OPAQUE)
				{
					//poiFragData.alpha = 1;
				}
				
				clip(poiFragData.alpha - _Cutoff);
				
				if (_Mode == POI_MODE_CUTOUT && !_AlphaToCoverage)
				{
					poiFragData.alpha = 1;
				}
				
				//ifex _BSSEnabled!=1
				#ifdef POIBS_ENABLE
				poiFragData.finalColor += poiFragData.emission * poiMods.globalEmission;
				poiFragData.alpha = poiFragData.alpha * poiFragData.emission.z;
				poiFragData.emission = 0;
				
				//ifex _BSSBloomfog!=1
				#ifdef POIBS_BLOOMFOG
				float3 fogDistance = i.worldPos + - _WorldSpaceCameraPos;
				float4 fogCol = -float4(poiFragData.finalColor, 1) + tex2D(_BloomPrePassTexture, i.fogCoord.xy);
				fogCol.a = -poiFragData.alpha;
				
				#ifdef BSSBLOOMFOGTYPE_HEIGHT
				poiFragData.finalColor = poiFragData.finalColor + (((GetHeightFogIntensity(i.worldPos, _FogHeightOffset, _FogHeightScale) * GetFogIntensity(fogDistance, _FogStartOffset, _FogScale)) + 1) * fogCol.rgb);
				poiFragData.alpha = poiFragData.alpha + (((GetHeightFogIntensity(i.worldPos, _FogHeightOffset, _FogHeightScale) * GetFogIntensity(fogDistance, _FogStartOffset, _FogScale)) + 1) * fogCol.a);
				#else
				poiFragData.finalColor = poiFragData.finalColor + ((GetFogIntensity(fogDistance, _FogStartOffset, _FogScale) + 1) * fogCol.rgb);
				poiFragData.alpha = poiFragData.alpha + ((GetFogIntensity(fogDistance, _FogStartOffset, _FogScale) + 1) * fogCol.a);
				#endif
				#endif
				//endex
				#endif
				//endex
				
				return float4(poiFragData.finalColor + poiFragData.emission * poiMods.globalEmission, poiFragData.alpha) + POI_SAFE_RGB0;
			}
			
			ENDCG
		}
		
		Pass
		{
			Name "Add"
			Tags { "LightMode" = "ForwardAdd" }
			
			Stencil
			{
				Ref [_StencilRef]
				ReadMask [_StencilReadMask]
				WriteMask [_StencilWriteMask]
				//ifex _StencilType==1
				Comp [_StencilCompareFunction]
				Pass [_StencilPassOp]
				Fail [_StencilFailOp]
				ZFail [_StencilZFailOp]
				//endex
				
				//ifex _StencilType==0
				CompBack [_StencilBackCompareFunction]
				PassBack [_StencilBackPassOp]
				FailBack [_StencilBackFailOp]
				ZFailBack [_StencilBackZFailOp]
				
				CompFront [_StencilFrontCompareFunction]
				PassFront [_StencilFrontPassOp]
				FailFront [_StencilFrontFailOp]
				ZFailFront [_StencilFrontZFailOp]
				//endex
			}
			
			ZWrite Off
			Cull [_Cull]
			Cull Front
			
			AlphaToMask [_AlphaToCoverage]
			ZTest [_ZTest]
			ColorMask [_ColorMask]
			Offset [_OffsetFactor], [_OffsetUnits]
			
			BlendOp [_AddBlendOp], [_AddBlendOpAlpha]
			Blend [_AddSrcBlend] [_AddDstBlend], [_AddSrcBlendAlpha] [_AddDstBlendAlpha]
			
			CGPROGRAM
			/*
			// Disable warnings we aren't interested in
			#if defined(UNITY_COMPILER_HLSL)
			#pragma warning(disable : 3205) // conversion of larger type to smaller
			#pragma warning(disable : 3568) // unknown pragma ignored
			#pragma warning(disable : 3571) // "pow(f,e) will not work for negative f"; however in majority of our calls to pow we know f is not negative
			#pragma warning(disable : 3206) // implicit truncation of vector type
			#endif
			*/
			#pragma target 5.0
			//ifex 0==0
			#pragma skip_optimizations d3d11
			//endex
			
			#pragma shader_feature_local _STOCHASTICMODE_DELIOT_HEITZ _STOCHASTICMODE_HEXTILE _STOCHASTICMODE_NONE
			
			//ifex _MainColorAdjustToggle==0
			#pragma shader_feature COLOR_GRADING_HDR
			//endex
			
			//#pragma shader_feature KEYWORD
			
			#pragma skip_variants LIGHTMAP_ON DYNAMICLIGHTMAP_ON LIGHTMAP_SHADOW_MIXING SHADOWS_SHADOWMASK DIRLIGHTMAP_COMBINED _MIXED_LIGHTING_SUBTRACTIVE
			#pragma skip_variants DECALS_OFF DECALS_3RT DECALS_4RT DECAL_SURFACE_GRADIENT _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3
			#pragma skip_variants _ADDITIONAL_LIGHT_SHADOWS
			#pragma skip_variants PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2
			#pragma skip_variants _SCREEN_SPACE_OCCLUSION
			
			//ifex _GlobalMaskTexturesEnable==0
			#pragma shader_feature_local POI_GLOBALMASK_TEXTURES
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#pragma shader_feature_local POI_UDIMDISCARD
			//endex
			
			//ifex _EnableDistortion==0
			#pragma shader_feature USER_LUT
			//endex
			
			//ifex _PoiParallax==0
			#pragma shader_feature_local POI_PARALLAX
			//endex
			
			//ifex _EnableAudioLink==0
			#pragma shader_feature_local POI_AUDIOLINK
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#pragma shader_feature_local POI_BLACKLIGHTMASKING
			//endex
			
			//ifex _DetailEnabled==0
			#pragma shader_feature FINALPASS
			//endex
			
			//ifex _VertexManipulationsEnabled==0
			#pragma shader_feature AUTO_EXPOSURE
			//endex
			
			//ifex _VertexGlitchingEnabled==0
			#pragma shader_feature_local POI_VERTEX_GLITCHING
			#pragma shader_feature_local POI_VERTEX_GLITCHING_TEXTURE
			//endex
			
			//ifex _EnableDepthBulge==0
			#pragma shader_feature_local POI_DEPTHBULGE
			//endex
			
			//ifex _BackFaceEnabled!=1
			#pragma shader_feature_local POI_BACKFACE
			//endex
			
			//ifex _RGBMaskEnabled==0
			#pragma shader_feature VIGNETTE
			#pragma shader_feature GEOM_TYPE_MESH
			//endex
			
			//ifex _LTCGIEnabled!=1
			#pragma shader_feature_local POI_LTCGI
			//endex
			
			//ifex _ShadingEnabled==0
			#pragma shader_feature_local VIGNETTE_MASKED
			#pragma shader_feature_local _LIGHTINGMODE_TEXTURERAMP _LIGHTINGMODE_MULTILAYER_MATH _LIGHTINGMODE_SHADEMAP _LIGHTINGMODE_REALISTIC _LIGHTINGMODE_WRAPPED _LIGHTINGMODE_SKIN _LIGHTINGMODE_FLAT _LIGHTINGMODE_CLOTH _LIGHTINGMODE_SDF
			//endex
			
			//ifex _DecalEnabled==0
			#pragma shader_feature GEOM_TYPE_BRANCH
			//endex
			//ifex _DecalEnabled1==0
			#pragma shader_feature GEOM_TYPE_BRANCH_DETAIL
			//endex
			//ifex _DecalEnabled2==0
			#pragma shader_feature GEOM_TYPE_FROND
			//endex
			//ifex _DecalEnabled3==0
			#pragma shader_feature DEPTH_OF_FIELD_COC_VIEW
			//endex
			
			//ifex _EnableDissolve==0
			#pragma shader_feature DISTORT
			//endex
			
			//ifex _EnableAniso==0
			#pragma shader_feature_local POI_ANISOTROPICS
			//endex
			
			//ifex _MatcapEnable==0
			#pragma shader_feature_local POI_MATCAP0
			#pragma shader_feature_local POI_MATCAP0_CUSTOM_NORMAL
			//endex
			//ifex _Matcap2Enable==0
			#pragma shader_feature COLOR_GRADING_HDR_3D
			#pragma shader_feature_local POI_MATCAP1_CUSTOM_NORMAL
			//endex
			//ifex _Matcap3Enable==0
			#pragma shader_feature_local POI_MATCAP2
			#pragma shader_feature_local POI_MATCAP2_CUSTOM_NORMAL
			//endex
			//ifex _Matcap4Enable==0
			#pragma shader_feature_local POI_MATCAP3
			#pragma shader_feature_local POI_MATCAP3_CUSTOM_NORMAL
			//endex
			
			//ifex _CubeMapEnabled==0
			#pragma shader_feature_local _CUBEMAP
			//endex
			
			//ifex _EnableALDecal==0
			#pragma shader_feature_local POI_AL_DECAL
			//endex
			
			//ifex _EnableVolumeColor==0
			#pragma shader_feature_local POI_AL_VOLUMECOLOR
			//endex
			
			//ifex _EnableFlipbook==0
			#pragma shader_feature _SUNDISK_HIGH_QUALITY
			//endex
			
			//ifex _EnableEmission==0
			#pragma shader_feature _EMISSION
			//endex
			//ifex _EnableEmission1==0
			#pragma shader_feature_local POI_EMISSION_1
			//endex
			//ifex _EnableEmission2==0
			#pragma shader_feature_local POI_EMISSION_2
			//endex
			//ifex _EnableEmission3==0
			#pragma shader_feature_local POI_EMISSION_3
			//endex
			
			//ifex _EnableRimLighting==0
			#pragma shader_feature_local _GLOSSYREFLECTIONS_OFF
			#pragma shader_feature_local _RIMSTYLE_POIYOMI _RIMSTYLE_UTS2 _RIMSTYLE_LILTOON
			//endex
			//ifex _EnableRim2Lighting==0
			#pragma shader_feature_local POI_RIM2
			#pragma shader_feature_local _RIM2STYLE_POIYOMI _RIM2STYLE_UTS2 _RIM2STYLE_LILTOON
			//endex
			
			//ifex _EnableDepthRimLighting==0
			#pragma shader_feature_local _POI_DEPTH_RIMLIGHT
			//endex
			
			//ifex _GlitterEnable==0
			#pragma shader_feature _SUNDISK_SIMPLE
			//endex
			
			//ifex _SubsurfaceScattering==0
			#pragma shader_feature_local POI_SUBSURFACESCATTERING
			//endex
			
			//ifex _MochieBRDF==0
			#pragma shader_feature_local MOCHIE_PBR
			//endex
			//ifex _ClearCoatBRDF==0
			#pragma shader_feature_local POI_CLEARCOAT
			//endex
			
			//ifex _EnableEnvironmentalRim==0
			#pragma shader_feature_local POI_ENVIRORIM
			//endex
			
			//ifex _StylizedSpecular==0
			#pragma shader_feature_local POI_STYLIZED_StylizedSpecular
			//endex
			
			//ifex _EnablePathing==0
			#pragma shader_feature_local POI_PATHING
			//endex
			
			//ifex _EnableMirrorOptions==0
			#pragma shader_feature_local POI_MIRROR
			//endex
			
			//ifex _EnableTouchGlow==0
			#pragma shader_feature GRAIN
			//endex
			
			//ifex _TextEnabled==0
			#pragma shader_feature EFFECT_BUMP
			//endex
			
			//ifex _PostProcess==0
			#pragma shader_feature_local POSTPROCESS
			//endex
			
			//ifex _PoiInternalParallax==0
			#pragma shader_feature_local POI_INTERNALPARALLAX
			//endex
			
			//ifex _NormalCorrect==0
			#pragma shader_feature_local POI_NORMALCORRECT
			//endex
			
			//ifex _VideoEffectsEnable==0
			#pragma shader_feature_local POI_VIDEO_EFFECTS
			//endex
			
			//ifex _BacklightEnabled!=1
			#pragma shader_feature_local POI_BACKLIGHT
			//endex
			
			//ifex _BSSEnabled!=1
			#pragma shader_feature_local POIBS_ENABLE
			//ifex _BSSBloomfog!=1
			#pragma shader_feature_local POIBS_BLOOMFOG
			#pragma shader_feature_local BSSBLOOMFOGTYPE_HEIGHT
			//endex
			//endex
			
			//ifex _VoronoiEnabled!=1
			#pragma shader_feature_local POI_VORONOI
			//endex
			
			#pragma multi_compile_fwdadd_fullshadows
			#pragma multi_compile_instancing
			#pragma multi_compile_fog
			#define POI_PASS_ADD
			
			// UNITY Includes
			#include "UnityCG.cginc"
			#include "UnityStandardUtils.cginc"
			#include "AutoLight.cginc"
			#include "UnityLightingCommon.cginc"
			#include "UnityPBSLighting.cginc"
			#ifdef POI_PASS_META
			#include "UnityMetaPass.cginc"
			#endif
			#pragma vertex vert
			
			#pragma fragment frag
			
			#define DielectricSpec float4(0.04, 0.04, 0.04, 1.0 - 0.04)
			#define PI float(3.14159265359)
			#define Epsilon float(1e-10)
			
			#define POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, samplertex, coord, dx, dy) tex.SampleGrad(sampler##samplertex, coord, dx, dy)
			#define POI2D_SAMPLE_TEX2D_SAMPLERGRADD(tex, samp, uv, pan, dx, dy) tex.SampleGrad(samp, POI_PAN_UV(uv, pan), dx, dy)
			
			#define POI_PAN_UV(uv, pan) (uv + _Time.x * pan)
			#define POI2D_SAMPLER_PAN(tex, texSampler, uv, pan) (UNITY_SAMPLE_TEX2D_SAMPLER(tex, texSampler, POI_PAN_UV(uv, pan)))
			#define POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy) (POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, texSampler, POI_PAN_UV(uv, pan), dx, dy))
			#define POI2D_SAMPLER(tex, texSampler, uv) (UNITY_SAMPLE_TEX2D_SAMPLER(tex, texSampler, uv))
			#define POI_SAMPLE_1D_X(tex, samp, uv) tex.Sample(samp, float2(uv, 0.5))
			#define POI2D_SAMPLER_GRAD(tex, texSampler, uv, dx, dy) (POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, texSampler, uv, dx, dy))
			#define POI2D_SAMPLER_GRADD(tex, texSampler, uv, dx, dy) tex.SampleGrad(texSampler, uv, dx, dy)
			#define POI2D_PAN(tex, uv, pan) (tex2D(tex, POI_PAN_UV(uv, pan)))
			#define POI2D(tex, uv) (tex2D(tex, uv))
			#define POI_SAMPLE_TEX2D(tex, uv) (UNITY_SAMPLE_TEX2D(tex, uv))
			#define POI_SAMPLE_TEX2D_PAN(tex, uv, pan) (UNITY_SAMPLE_TEX2D(tex, POI_PAN_UV(uv, pan)))
			#define POI_SAMPLE_CUBE_LOD(tex, samp, uv, lod) texCUBElod(tex, float4(uv, 0, lod))
			
			#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
			#define POI_SAMPLE_SCREEN(tex, samp, uv)          tex.Sample(samp, float3(uv, unity_StereoEyeIndex))
			#else
			#define POI_SAMPLE_SCREEN(tex, samp, uv)          tex.Sample(samp, uv)
			#endif
			
			// When using, properties won't properly lock at optimize time; needs macro evaluation implemented
			// #define POI2D_MAINTEX_SAMPLER_PAN_INLINED(tex, poiMesh) (POI2D_SAMPLER_PAN(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan))
			
			#define POI_SAFE_RGB0 float4(mainTexture.rgb * .0001, 0)
			#define POI_SAFE_RGB1 float4(mainTexture.rgb * .0001, 1)
			#define POI_SAFE_RGBA mainTexture
			
			#if defined(UNITY_COMPILER_HLSL)
			#define PoiInitStruct(type, name) name = (type)0;
			#else
			#define PoiInitStruct(type, name)
			#endif
			
			#define POI_ERROR(poiMesh, gridSize) lerp(float3(1, 0, 1), float3(0, 0, 0), fmod(floor((poiMesh.worldPos.x) * gridSize) + floor((poiMesh.worldPos.y) * gridSize) + floor((poiMesh.worldPos.z) * gridSize), 2) == 0)
			#define POI_NAN (asfloat(-1))
			
			#define POI_MODE_OPAQUE 0
			#define POI_MODE_CUTOUT 1
			#define POI_MODE_FADE 2
			#define POI_MODE_TRANSPARENT 3
			#define POI_MODE_ADDITIVE 4
			#define POI_MODE_SOFTADDITIVE 5
			#define POI_MODE_MULTIPLICATIVE 6
			#define POI_MODE_2XMULTIPLICATIVE 7
			#define POI_MODE_TRANSCLIPPING 9
			
			/*
			Texture2D ;
			float4 _ST;
			float2 Pan;
			float UV;
			float Stochastic;
			
			[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos XZ, 5, Polar UV, 6, Distorted UV, 7 )]
			*/
			
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			// Map of where features in AudioLink are.
			#define ALPASS_DFT                      uint2(0, 4)   //Size: 128, 2
			#define ALPASS_WAVEFORM                 uint2(0, 6)   //Size: 128, 16
			#define ALPASS_AUDIOLINK                uint2(0, 0)   //Size: 128, 4
			#define ALPASS_AUDIOBASS                uint2(0, 0)   //Size: 128, 1
			#define ALPASS_AUDIOLOWMIDS             uint2(0, 1)   //Size: 128, 1
			#define ALPASS_AUDIOHIGHMIDS            uint2(0, 2)   //Size: 128, 1
			#define ALPASS_AUDIOTREBLE              uint2(0, 3)   //Size: 128, 1
			#define ALPASS_AUDIOLINKHISTORY         uint2(1, 0)   //Size: 127, 4
			#define ALPASS_GENERALVU                uint2(0, 22)  //Size: 12, 1
			#define ALPASS_CCINTERNAL               uint2(12, 22) //Size: 12, 2
			#define ALPASS_CCCOLORS                 uint2(25, 22) //Size: 11, 1
			#define ALPASS_CCSTRIP                  uint2(0, 24)  //Size: 128, 1
			#define ALPASS_CCLIGHTS                 uint2(0, 25)  //Size: 128, 2
			#define ALPASS_AUTOCORRELATOR           uint2(0, 27)  //Size: 128, 1
			#define ALPASS_GENERALVU_INSTANCE_TIME  uint2(2, 22)
			#define ALPASS_GENERALVU_LOCAL_TIME     uint2(3, 22)
			#define ALPASS_GENERALVU_NETWORK_TIME   uint2(4, 22)
			#define ALPASS_GENERALVU_PLAYERINFO     uint2(6, 22)
			// Added in version 2.5
			#define ALPASS_FILTEREDAUDIOLINK        uint2(0, 28)  //Size: 16, 4
			// Added in version 2.6
			#define ALPASS_CHRONOTENSITY            uint2(16, 28) //Size: 8, 4
			#define ALPASS_THEME_COLOR0             uint2(0, 23)
			#define ALPASS_THEME_COLOR1             uint2(1, 23)
			#define ALPASS_THEME_COLOR2             uint2(2, 23)
			#define ALPASS_THEME_COLOR3             uint2(3, 23)
			#define ALPASS_FILTEREDVU               uint2(24, 28) //Size: 4, 4
			#define ALPASS_FILTEREDVU_INTENSITY     uint2(24, 28) //Size: 4, 1
			#define ALPASS_FILTEREDVU_MARKER        uint2(24, 29) //Size: 4, 1
			
			// Some basic constants to use (Note, these should be compatible with
			// future version of AudioLink, but may change.
			#define AUDIOLINK_SAMPHIST              3069        // Internal use for algos, do not change.
			#define AUDIOLINK_SAMPLEDATA24          2046
			#define AUDIOLINK_EXPBINS               24
			#define AUDIOLINK_EXPOCT                10
			#define AUDIOLINK_ETOTALBINS (AUDIOLINK_EXPBINS * AUDIOLINK_EXPOCT)
			#define AUDIOLINK_WIDTH                 128
			#define AUDIOLINK_SPS                   48000       // Samples per second
			#define AUDIOLINK_ROOTNOTE              0
			#define AUDIOLINK_4BAND_FREQFLOOR       0.123
			#define AUDIOLINK_4BAND_FREQCEILING     1
			#define AUDIOLINK_BOTTOM_FREQUENCY      13.75
			#define AUDIOLINK_BASE_AMPLITUDE        2.5
			#define AUDIOLINK_DELAY_COEFFICIENT_MIN 0.3
			#define AUDIOLINK_DELAY_COEFFICIENT_MAX 0.9
			#define AUDIOLINK_DFT_Q                 4.0
			#define AUDIOLINK_TREBLE_CORRECTION     5.0
			
			// ColorChord constants
			#define COLORCHORD_EMAXBIN              192
			#define COLORCHORD_IIR_DECAY_1          0.90
			#define COLORCHORD_IIR_DECAY_2          0.85
			#define COLORCHORD_CONSTANT_DECAY_1     0.01
			#define COLORCHORD_CONSTANT_DECAY_2     0.0
			#define COLORCHORD_NOTE_CLOSEST         3.0
			#define COLORCHORD_NEW_NOTE_GAIN        8.0
			#define COLORCHORD_MAX_NOTES            10
			
			uniform float4               _AudioTexture_TexelSize;
			
			#ifdef SHADER_TARGET_SURFACE_ANALYSIS
			#define AUDIOLINK_STANDARD_INDEXING
			#endif
			
			// Mechanism to index into texture.
			#ifdef AUDIOLINK_STANDARD_INDEXING
			sampler2D _AudioTexture;
			#define AudioLinkData(xycoord) tex2Dlod(_AudioTexture, float4(uint2(xycoord) * _AudioTexture_TexelSize.xy, 0, 0))
			#else
			uniform Texture2D<float4> _AudioTexture;
			SamplerState sampler_AudioTexture;
			#define AudioLinkData(xycoord) _AudioTexture[uint2(xycoord)]
			#endif
			uniform sampler2D _Stored;
			uniform float4 _Stored_TexelSize;
			#endif
			//endex
			
			float _GrabMode;
			float _Mode;
			
			float _StochasticDeliotHeitzDensity;
			float _StochasticHexGridDensity;
			float _StochasticHexRotationStrength;
			float _StochasticHexFallOffContrast;
			float _StochasticHexFallOffPower;
			
			#if defined(PROP_LIGHTINGAOMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _LightingAOMaps;
			#endif
			float4 _LightingAOMaps_ST;
			float2 _LightingAOMapsPan;
			float _LightingAOMapsUV;
			float _LightDataAOStrengthR;
			float _LightDataAOStrengthG;
			float _LightDataAOStrengthB;
			float _LightDataAOStrengthA;
			float _LightDataAOGlobalMaskR;
			float _LightDataAOGlobalMaskBlendTypeR;
			
			#if defined(PROP_LIGHTINGDETAILSHADOWMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _LightingDetailShadowMaps;
			#endif
			float4 _LightingDetailShadowMaps_ST;
			float2 _LightingDetailShadowMapsPan;
			float _LightingDetailShadowMapsUV;
			float _LightingDetailShadowStrengthR;
			float _LightingDetailShadowStrengthG;
			float _LightingDetailShadowStrengthB;
			float _LightingDetailShadowStrengthA;
			float _LightingAddDetailShadowStrengthR;
			float _LightingAddDetailShadowStrengthG;
			float _LightingAddDetailShadowStrengthB;
			float _LightingAddDetailShadowStrengthA;
			float _LightDataDetailShadowGlobalMaskR;
			float _LightDataDetailShadowGlobalMaskBlendTypeR;
			
			#if defined(PROP_LIGHTINGSHADOWMASKS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _LightingShadowMasks;
			#endif
			float4 _LightingShadowMasks_ST;
			float2 _LightingShadowMasksPan;
			float _LightingShadowMasksUV;
			float _LightingShadowMaskStrengthR;
			float _LightingShadowMaskStrengthG;
			float _LightingShadowMaskStrengthB;
			float _LightingShadowMaskStrengthA;
			float _LightDataShadowMaskGlobalMaskR;
			float _LightDataShadowMaskGlobalMaskBlendTypeR;
			
			// Lighting Data
			float _Unlit_Intensity;
			float _LightingColorMode;
			float _LightingMapMode;
			float _LightingDirectionMode;
			float3 _LightngForcedDirection;
			float _LightingViewDirOffsetPitch;
			float _LightingViewDirOffsetYaw;
			float _LightingIndirectUsesNormals;
			float _LightingCapEnabled;
			float _LightingCap;
			float _LightingForceColorEnabled;
			float3 _LightingForcedColor;
			float _LightingForcedColorThemeIndex;
			float _LightingCastedShadows;
			float _LightingMonochromatic;
			float _LightingMinLightBrightness;
			// Additive Lighting Data
			float _LightingAdditiveEnable;
			float _LightingAdditiveLimited;
			float _LightingAdditiveLimit;
			float _LightingAdditiveCastedShadows;
			float _LightingAdditiveMonochromatic;
			float _LightingAdditivePassthrough;
			float _DisableDirectionalInAdd;
			float _LightingVertexLightingEnabled;
			float _LightingMirrorVertexLightingEnabled;
			// Lighting Data Debug
			float _LightDataDebugEnabled;
			float _LightingDebugVisualize;
			
			float _IgnoreFog;
			float _RenderingReduceClipDistance;
			int _FlipBackfaceNormals;
			float _AddBlendOp;
			float _Cull;
			
			float4 _Color;
			float _ColorThemeIndex;
			UNITY_DECLARE_TEX2D(_MainTex);
			UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
			float _MainPixelMode;
			float4 _MainTex_ST;
			float2 _MainTexPan;
			float _MainTexUV;
			float4 _MainTex_TexelSize;
			float _MainTexStochastic;
			#if defined(PROP_BUMPMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BumpMap;
			#endif
			float4 _BumpMap_ST;
			float2 _BumpMapPan;
			float _BumpMapUV;
			float _BumpScale;
			float _BumpMapStochastic;
			#if defined(PROP_ALPHAMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AlphaMask;
			float4 _AlphaMask_ST;
			float2 _AlphaMaskPan;
			float _AlphaMaskUV;
			float _AlphaMaskInvert;
			float _MainAlphaMaskMode;
			float _AlphaMaskScale;
			float _AlphaMaskValue;
			#endif
			float _Cutoff;
			//ifex _MainColorAdjustToggle==0
			#ifdef COLOR_GRADING_HDR
			float _MainColorAdjustToggle;
			#if defined(PROP_MAINCOLORADJUSTTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MainColorAdjustTexture;
			#endif
			float4 _MainColorAdjustTexture_ST;
			float2 _MainColorAdjustTexturePan;
			float _MainColorAdjustTextureUV;
			float _MainHueShiftToggle;
			float _MainHueShiftReplace;
			float _MainHueShift;
			float _MainHueShiftSpeed;
			float _Saturation;
			float _MainBrightness;
			
			float _MainHueALCTEnabled;
			float _MainALHueShiftBand;
			float _MainALHueShiftCTIndex;
			float _MainHueALMotionSpeed;
			
			float _MainHueGlobalMask;
			float _MainHueGlobalMaskBlendType;
			float _MainSaturationGlobalMask;
			float _MainSaturationGlobalMaskBlendType;
			float _MainBrightnessGlobalMask;
			float _MainBrightnessGlobalMaskBlendType;
			
			#if defined(PROP_MAINGRADATIONTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MainGradationTex;
			#endif
			float _ColorGradingToggle;
			float _MainGradationStrength;
			#endif
			//endex
			
			SamplerState sampler_linear_clamp;
			SamplerState sampler_linear_repeat;
			SamplerState sampler_trilinear_repeat;
			
			float _AlphaForceOpaque;
			float _AlphaMod;
			float _AlphaPremultiply;
			float _AlphaBoostFA;
			//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
			float _AlphaToCoverage;
			float _AlphaSharpenedA2C;
			float _AlphaMipScale;
			//endex
			
			//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
			float _AlphaDithering;
			float _AlphaDitherGradient;
			float _AlphaDitherBias;
			//endex
			
			//ifex _AlphaDistanceFade==0 && isNotAnimated(_AlphaDistanceFade)
			float _AlphaDistanceFade;
			float _AlphaDistanceFadeType;
			float _AlphaDistanceFadeMinAlpha;
			float _AlphaDistanceFadeMaxAlpha;
			float _AlphaDistanceFadeMin;
			float _AlphaDistanceFadeMax;
			float _AlphaDistanceFadeGlobalMask;
			float _AlphaDistanceFadeGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaFresnel==0 && isNotAnimated(_AlphaFresnel)
			float _AlphaFresnel;
			float _AlphaFresnelAlpha;
			float _AlphaFresnelSharpness;
			float _AlphaFresnelWidth;
			float _AlphaFresnelInvert;
			float _AlphaFresnelGlobalMask;
			float _AlphaFresnelGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaAngular==0 && isNotAnimated(_AlphaAngular)
			float _AlphaAngular;
			float _AngleType;
			float _AngleCompareTo;
			float3 _AngleForwardDirection;
			float _CameraAngleMin;
			float _CameraAngleMax;
			float _ModelAngleMin;
			float _ModelAngleMax;
			float _AngleMinAlpha;
			float _AlphaAngularGlobalMask;
			float _AlphaAngularGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaAudioLinkEnabled==0 && isNotAnimated(_AlphaAudioLinkEnabled)
			float _AlphaAudioLinkEnabled;
			float2 _AlphaAudioLinkAddRange;
			float _AlphaAudioLinkAddBand;
			//endex
			
			float _AlphaGlobalMask;
			float _AlphaGlobalMaskBlendType;
			
			float4 _GlobalThemeColor0;
			float4 _GlobalThemeColor1;
			float4 _GlobalThemeColor2;
			float4 _GlobalThemeColor3;
			float _GlobalThemeHue0;
			float _GlobalThemeHue1;
			float _GlobalThemeHue2;
			float _GlobalThemeHue3;
			float _GlobalThemeHueSpeed0;
			float _GlobalThemeHueSpeed1;
			float _GlobalThemeHueSpeed2;
			float _GlobalThemeHueSpeed3;
			float _GlobalThemeSaturation0;
			float _GlobalThemeSaturation1;
			float _GlobalThemeSaturation2;
			float _GlobalThemeSaturation3;
			float _GlobalThemeValue0;
			float _GlobalThemeValue1;
			float _GlobalThemeValue2;
			float _GlobalThemeValue3;
			
			//ifex _GlobalMaskTexturesEnable==0
			#ifdef POI_GLOBALMASK_TEXTURES
			#if defined(PROP_GLOBALMASKTEXTURE0) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture0;
			#endif
			float4 _GlobalMaskTexture0_ST;
			float2 _GlobalMaskTexture0Pan;
			float _GlobalMaskTexture0UV;
			int _GlobalMaskTexture0Split;
			float4 _GlobalMaskTexture0SplitTilingOffset_G;
			float4 _GlobalMaskTexture0SplitPan_G;
			float4 _GlobalMaskTexture0SplitTilingOffset_B;
			float4 _GlobalMaskTexture0SplitPan_B;
			float4 _GlobalMaskTexture0SplitTilingOffset_A;
			float4 _GlobalMaskTexture0SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture1;
			#endif
			float4 _GlobalMaskTexture1_ST;
			float2 _GlobalMaskTexture1Pan;
			float _GlobalMaskTexture1UV;
			int _GlobalMaskTexture1Split;
			float4 _GlobalMaskTexture1SplitTilingOffset_G;
			float4 _GlobalMaskTexture1SplitPan_G;
			float4 _GlobalMaskTexture1SplitTilingOffset_B;
			float4 _GlobalMaskTexture1SplitPan_B;
			float4 _GlobalMaskTexture1SplitTilingOffset_A;
			float4 _GlobalMaskTexture1SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture2;
			#endif
			float4 _GlobalMaskTexture2_ST;
			float2 _GlobalMaskTexture2Pan;
			float _GlobalMaskTexture2UV;
			int _GlobalMaskTexture2Split;
			float4 _GlobalMaskTexture2SplitTilingOffset_G;
			float4 _GlobalMaskTexture2SplitPan_G;
			float4 _GlobalMaskTexture2SplitTilingOffset_B;
			float4 _GlobalMaskTexture2SplitPan_B;
			float4 _GlobalMaskTexture2SplitTilingOffset_A;
			float4 _GlobalMaskTexture2SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE3) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture3;
			#endif
			float4 _GlobalMaskTexture3_ST;
			float2 _GlobalMaskTexture3Pan;
			float _GlobalMaskTexture3UV;
			int _GlobalMaskTexture3Split;
			float4 _GlobalMaskTexture3SplitTilingOffset_G;
			float4 _GlobalMaskTexture3SplitPan_G;
			float4 _GlobalMaskTexture3SplitTilingOffset_B;
			float4 _GlobalMaskTexture3SplitPan_B;
			float4 _GlobalMaskTexture3SplitTilingOffset_A;
			float4 _GlobalMaskTexture3SplitPan_A;
			#endif
			//endex
			//ifex _GlobalMaskOptionsEnable==0
			float _GlobalMaskOptionsEnable;
			int _GlobalMaskOptionsType;
			
			//ifex _GlobalMaskOptionsType!=0
			float _GlobalMaskSlider_0;
			float _GlobalMaskSlider_1;
			float _GlobalMaskSlider_2;
			float _GlobalMaskSlider_3;
			float _GlobalMaskSlider_4;
			float _GlobalMaskSlider_5;
			float _GlobalMaskSlider_6;
			float _GlobalMaskSlider_7;
			float _GlobalMaskSlider_8;
			float _GlobalMaskSlider_9;
			float _GlobalMaskSlider_10;
			float _GlobalMaskSlider_11;
			float _GlobalMaskSlider_12;
			float _GlobalMaskSlider_13;
			float _GlobalMaskSlider_14;
			float _GlobalMaskSlider_15;
			//endex
			
			//ifex _GlobalMaskOptionsType!=1
			float2 _GlobalMaskMinMaxSlider_0;
			float2 _GlobalMaskMinMaxSlider_1;
			float2 _GlobalMaskMinMaxSlider_2;
			float2 _GlobalMaskMinMaxSlider_3;
			float2 _GlobalMaskMinMaxSlider_4;
			float2 _GlobalMaskMinMaxSlider_5;
			float2 _GlobalMaskMinMaxSlider_6;
			float2 _GlobalMaskMinMaxSlider_7;
			float2 _GlobalMaskMinMaxSlider_8;
			float2 _GlobalMaskMinMaxSlider_9;
			float2 _GlobalMaskMinMaxSlider_10;
			float2 _GlobalMaskMinMaxSlider_11;
			float2 _GlobalMaskMinMaxSlider_12;
			float2 _GlobalMaskMinMaxSlider_13;
			float2 _GlobalMaskMinMaxSlider_14;
			float2 _GlobalMaskMinMaxSlider_15;
			//endex
			
			//ifex _GlobalMaskOptionsType!=2
			int _GlobalMaskToggleOn_0;
			int _GlobalMaskToggleOff_0;
			int _GlobalMaskToggleOn_1;
			int _GlobalMaskToggleOff_1;
			int _GlobalMaskToggleOn_2;
			int _GlobalMaskToggleOff_2;
			int _GlobalMaskToggleOn_3;
			int _GlobalMaskToggleOff_3;
			int _GlobalMaskToggleOn_4;
			int _GlobalMaskToggleOff_4;
			int _GlobalMaskToggleOn_5;
			int _GlobalMaskToggleOff_5;
			int _GlobalMaskToggleOn_6;
			int _GlobalMaskToggleOff_6;
			int _GlobalMaskToggleOn_7;
			int _GlobalMaskToggleOff_7;
			int _GlobalMaskToggleOn_8;
			int _GlobalMaskToggleOff_8;
			int _GlobalMaskToggleOn_9;
			int _GlobalMaskToggleOff_9;
			int _GlobalMaskToggleOn_10;
			int _GlobalMaskToggleOff_10;
			int _GlobalMaskToggleOn_11;
			int _GlobalMaskToggleOff_11;
			int _GlobalMaskToggleOn_12;
			int _GlobalMaskToggleOff_12;
			int _GlobalMaskToggleOn_13;
			int _GlobalMaskToggleOff_13;
			int _GlobalMaskToggleOn_14;
			int _GlobalMaskToggleOff_14;
			int _GlobalMaskToggleOn_15;
			int _GlobalMaskToggleOff_15;
			//endex
			//endex
			//ifex _GlobalMaskModifiersBackfaceEnable==0
			float _GlobalMaskModifiersBackfaceEnable;
			float _GlobalMaskBackface_0;
			float _GlobalMaskBackface_1;
			float _GlobalMaskBackface_2;
			float _GlobalMaskBackface_3;
			float _GlobalMaskBackface_4;
			float _GlobalMaskBackface_5;
			float _GlobalMaskBackface_6;
			float _GlobalMaskBackface_7;
			float _GlobalMaskBackface_8;
			float _GlobalMaskBackface_9;
			float _GlobalMaskBackface_10;
			float _GlobalMaskBackface_11;
			float _GlobalMaskBackface_12;
			float _GlobalMaskBackface_13;
			float _GlobalMaskBackface_14;
			float _GlobalMaskBackface_15;
			//endex
			
			//ifex _GlobalMaskModifiersMirrorEnable==0
			float _GlobalMaskModifiersMirrorEnable;
			float _GlobalMaskMirrorVisibilityMode;
			float _GlobalMaskMirror_0;
			float _GlobalMaskMirror_1;
			float _GlobalMaskMirror_2;
			float _GlobalMaskMirror_3;
			float _GlobalMaskMirror_4;
			float _GlobalMaskMirror_5;
			float _GlobalMaskMirror_6;
			float _GlobalMaskMirror_7;
			float _GlobalMaskMirror_8;
			float _GlobalMaskMirror_9;
			float _GlobalMaskMirror_10;
			float _GlobalMaskMirror_11;
			float _GlobalMaskMirror_12;
			float _GlobalMaskMirror_13;
			float _GlobalMaskMirror_14;
			float _GlobalMaskMirror_15;
			//endex
			
			//ifex _GlobalMaskModifiersCameraEnable==0
			float _GlobalMaskModifiersCameraEnable;
			float _GlobalMaskCamera_0;
			float _GlobalMaskCamera_1;
			float _GlobalMaskCamera_2;
			float _GlobalMaskCamera_3;
			float _GlobalMaskCamera_4;
			float _GlobalMaskCamera_5;
			float _GlobalMaskCamera_6;
			float _GlobalMaskCamera_7;
			float _GlobalMaskCamera_8;
			float _GlobalMaskCamera_9;
			float _GlobalMaskCamera_10;
			float _GlobalMaskCamera_11;
			float _GlobalMaskCamera_12;
			float _GlobalMaskCamera_13;
			float _GlobalMaskCamera_14;
			float _GlobalMaskCamera_15;
			//endex
			
			//ifex _GlobalMaskModifiersDistanceEnable==0
			int _GlobalMaskModifiersDistanceEnable;
			
			//ifex _GlobalMaskDistanceEnable_0==0
			int _GlobalMaskDistanceEnable_0;
			int _GlobalMaskDistanceType_0;
			float _GlobalMaskDistanceMin_0;
			float _GlobalMaskDistanceMax_0;
			float _GlobalMaskDistanceMinAlpha_0;
			float _GlobalMaskDistanceMaxAlpha_0;
			int _GlobalMaskDistanceBlendType_0;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_1==0
			int _GlobalMaskDistanceEnable_1;
			int _GlobalMaskDistanceType_1;
			float _GlobalMaskDistanceMin_1;
			float _GlobalMaskDistanceMax_1;
			float _GlobalMaskDistanceMinAlpha_1;
			float _GlobalMaskDistanceMaxAlpha_1;
			int _GlobalMaskDistanceBlendType_1;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_2==0
			int _GlobalMaskDistanceEnable_2;
			int _GlobalMaskDistanceType_2;
			float _GlobalMaskDistanceMin_2;
			float _GlobalMaskDistanceMax_2;
			float _GlobalMaskDistanceMinAlpha_2;
			float _GlobalMaskDistanceMaxAlpha_2;
			int _GlobalMaskDistanceBlendType_2;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_3==0
			int _GlobalMaskDistanceEnable_3;
			int _GlobalMaskDistanceType_3;
			float _GlobalMaskDistanceMin_3;
			float _GlobalMaskDistanceMax_3;
			float _GlobalMaskDistanceMinAlpha_3;
			float _GlobalMaskDistanceMaxAlpha_3;
			int _GlobalMaskDistanceBlendType_3;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_4==0
			int _GlobalMaskDistanceEnable_4;
			int _GlobalMaskDistanceType_4;
			float _GlobalMaskDistanceMin_4;
			float _GlobalMaskDistanceMax_4;
			float _GlobalMaskDistanceMinAlpha_4;
			float _GlobalMaskDistanceMaxAlpha_4;
			int _GlobalMaskDistanceBlendType_4;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_5==0
			int _GlobalMaskDistanceEnable_5;
			int _GlobalMaskDistanceType_5;
			float _GlobalMaskDistanceMin_5;
			float _GlobalMaskDistanceMax_5;
			float _GlobalMaskDistanceMinAlpha_5;
			float _GlobalMaskDistanceMaxAlpha_5;
			int _GlobalMaskDistanceBlendType_5;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_6==0
			int _GlobalMaskDistanceEnable_6;
			int _GlobalMaskDistanceType_6;
			float _GlobalMaskDistanceMin_6;
			float _GlobalMaskDistanceMax_6;
			float _GlobalMaskDistanceMinAlpha_6;
			float _GlobalMaskDistanceMaxAlpha_6;
			int _GlobalMaskDistanceBlendType_6;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_7==0
			int _GlobalMaskDistanceEnable_7;
			int _GlobalMaskDistanceType_7;
			float _GlobalMaskDistanceMin_7;
			float _GlobalMaskDistanceMax_7;
			float _GlobalMaskDistanceMinAlpha_7;
			float _GlobalMaskDistanceMaxAlpha_7;
			int _GlobalMaskDistanceBlendType_7;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_8==0
			int _GlobalMaskDistanceEnable_8;
			int _GlobalMaskDistanceType_8;
			float _GlobalMaskDistanceMin_8;
			float _GlobalMaskDistanceMax_8;
			float _GlobalMaskDistanceMinAlpha_8;
			float _GlobalMaskDistanceMaxAlpha_8;
			int _GlobalMaskDistanceBlendType_8;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_9==0
			int _GlobalMaskDistanceEnable_9;
			int _GlobalMaskDistanceType_9;
			float _GlobalMaskDistanceMin_9;
			float _GlobalMaskDistanceMax_9;
			float _GlobalMaskDistanceMinAlpha_9;
			float _GlobalMaskDistanceMaxAlpha_9;
			int _GlobalMaskDistanceBlendType_9;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_10==0
			int _GlobalMaskDistanceEnable_10;
			int _GlobalMaskDistanceType_10;
			float _GlobalMaskDistanceMin_10;
			float _GlobalMaskDistanceMax_10;
			float _GlobalMaskDistanceMinAlpha_10;
			float _GlobalMaskDistanceMaxAlpha_10;
			int _GlobalMaskDistanceBlendType_10;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_11==0
			int _GlobalMaskDistanceEnable_11;
			int _GlobalMaskDistanceType_11;
			float _GlobalMaskDistanceMin_11;
			float _GlobalMaskDistanceMax_11;
			float _GlobalMaskDistanceMinAlpha_11;
			float _GlobalMaskDistanceMaxAlpha_11;
			int _GlobalMaskDistanceBlendType_11;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_12==0
			int _GlobalMaskDistanceEnable_12;
			int _GlobalMaskDistanceType_12;
			float _GlobalMaskDistanceMin_12;
			float _GlobalMaskDistanceMax_12;
			float _GlobalMaskDistanceMinAlpha_12;
			float _GlobalMaskDistanceMaxAlpha_12;
			int _GlobalMaskDistanceBlendType_12;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_13==0
			int _GlobalMaskDistanceEnable_13;
			int _GlobalMaskDistanceType_13;
			float _GlobalMaskDistanceMin_13;
			float _GlobalMaskDistanceMax_13;
			float _GlobalMaskDistanceMinAlpha_13;
			float _GlobalMaskDistanceMaxAlpha_13;
			int _GlobalMaskDistanceBlendType_13;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_14==0
			int _GlobalMaskDistanceEnable_14;
			int _GlobalMaskDistanceType_14;
			float _GlobalMaskDistanceMin_14;
			float _GlobalMaskDistanceMax_14;
			float _GlobalMaskDistanceMinAlpha_14;
			float _GlobalMaskDistanceMaxAlpha_14;
			int _GlobalMaskDistanceBlendType_14;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_15==0
			int _GlobalMaskDistanceEnable_15;
			int _GlobalMaskDistanceType_15;
			float _GlobalMaskDistanceMin_15;
			float _GlobalMaskDistanceMax_15;
			float _GlobalMaskDistanceMinAlpha_15;
			float _GlobalMaskDistanceMaxAlpha_15;
			int _GlobalMaskDistanceBlendType_15;
			//endex
			//endex
			
			int _GlobalMaskVertexColorLinearSpace;
			//ifex _GlobalMaskVertexColorRed==0
			int _GlobalMaskVertexColorRed;
			int _GlobalMaskVertexColorRedBlendType;
			//endex
			//ifex _GlobalMaskVertexColorGreen==0
			int _GlobalMaskVertexColorGreen;
			int _GlobalMaskVertexColorGreenBlendType;
			//endex
			//ifex _GlobalMaskVertexColorBlue==0
			int _GlobalMaskVertexColorBlue;
			int _GlobalMaskVertexColorBlueBlendType;
			//endex
			//ifex _GlobalMaskVertexColorAlpha==0
			int _GlobalMaskVertexColorAlpha;
			int _GlobalMaskVertexColorAlphaBlendType;
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#ifdef POI_UDIMDISCARD
			float _UDIMDiscardMode;
			float _UDIMDiscardUV;
			float _UDIMDiscardRow3_0;
			float _UDIMDiscardRow3_1;
			float _UDIMDiscardRow3_2;
			float _UDIMDiscardRow3_3;
			float _UDIMDiscardRow2_0;
			float _UDIMDiscardRow2_1;
			float _UDIMDiscardRow2_2;
			float _UDIMDiscardRow2_3;
			float _UDIMDiscardRow1_0;
			float _UDIMDiscardRow1_1;
			float _UDIMDiscardRow1_2;
			float _UDIMDiscardRow1_3;
			float _UDIMDiscardRow0_0;
			float _UDIMDiscardRow0_1;
			float _UDIMDiscardRow0_2;
			float _UDIMDiscardRow0_3;
			#endif
			//endex
			
			//ifex _EnableDistortion==0
			#ifdef USER_LUT
			#if defined(PROP_DISTORTIONFLOWTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionFlowTexture;
			float4 _DistortionFlowTexture_ST;
			float2 _DistortionFlowTexturePan;
			float _DistortionFlowTextureUV;
			#endif
			
			#if defined(PROP_DISTORTIONFLOWTEXTURE1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionFlowTexture1;
			float4 _DistortionFlowTexture1_ST;
			float2 _DistortionFlowTexture1Pan;
			float _DistortionFlowTexture1UV;
			#endif
			
			#if defined(PROP_DISTORTIONMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionMask;
			float4 _DistortionMask_ST;
			float2 _DistortionMaskPan;
			float _DistortionMaskUV;
			float _DistortionMaskChannel;
			#endif
			
			float _DistortionUvToDistort;
			float _DistortionStrength;
			float _DistortionStrength1;
			
			#ifdef POI_AUDIOLINK
			half _EnableDistortionAudioLink;
			half2 _DistortionStrengthAudioLink;
			half _DistortionStrengthAudioLinkBand;
			half2 _DistortionStrength1AudioLink;
			half _DistortionStrength1AudioLinkBand;
			#endif
			#endif
			//endex
			float _StereoEnabled;
			float _PolarUV;
			float2 _PolarCenter;
			float _PolarRadialScale;
			float _PolarLengthScale;
			float _PolarSpiralPower;
			float _PanoUseBothEyes;
			
			float _UVModWorldPos0;
			float _UVModWorldPos1;
			float _UVModLocalPos0;
			float _UVModLocalPos1;
			
			//ifex _PoiParallax==0
			#ifdef POI_PARALLAX
			
			sampler2D _HeightMap;
			float4 _HeightMap_ST;
			float2 _HeightMapPan;
			float _HeightMapUV;
			
			#if defined(PROP_HEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Heightmask;
			float4 _Heightmask_ST;
			float2 _HeightmaskPan;
			float _HeightmaskUV;
			float _HeightmaskChannel;
			float _HeightmaskInvert;
			SamplerState _linear_repeat;
			#endif
			
			float _ParallaxUV;
			float _HeightStrength;
			float _HeightOffset;
			float _HeightStepsMin;
			float _HeightStepsMax;
			
			float _CurvatureU;
			float _CurvatureV;
			float _CurvFix;
			#endif
			//endex
			
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			float _AudioLinkDelay;
			float _AudioLinkAnimToggle;
			
			float _AudioLinkSmoothingBass;
			float _AudioLinkSmoothingLowMid;
			float _AudioLinkSmoothingHighMid;
			float _AudioLinkSmoothingTreble;
			
			float _DebugWaveform;
			float _DebugDFT;
			float _DebugBass;
			float _DebugLowMids;
			float _DebugHighMids;
			float _DebugTreble;
			float _DebugCCColors;
			float _DebugCCStrip;
			float _DebugCCLights;
			float _DebugAutocorrelator;
			float _DebugChronotensity;
			float _AudioLinkCCStripY;
			
			float _AudioLinkBandOverridesEnabled;
			float4 _AudioLinkBandOverrideSliders;
			#endif
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#ifdef POI_BLACKLIGHTMASKING
			float _BlackLightMasking0Key;
			float2 _BlackLightMasking0Range;
			float _BlackLightMasking0GlobalMaskIndex;
			float _BlackLightMasking0GlobalMaskBlendType;
			
			float _BlackLightMasking1Key;
			float2 _BlackLightMasking1Range;
			float _BlackLightMasking1GlobalMaskIndex;
			float _BlackLightMasking1GlobalMaskBlendType;
			
			float _BlackLightMasking2Key;
			float2 _BlackLightMasking2Range;
			float _BlackLightMasking2GlobalMaskIndex;
			float _BlackLightMasking2GlobalMaskBlendType;
			
			float _BlackLightMasking3Key;
			float2 _BlackLightMasking3Range;
			float _BlackLightMasking3GlobalMaskIndex;
			float _BlackLightMasking3GlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _DetailEnabled==0
			#ifdef FINALPASS
			#if defined(PROP_DETAILMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DetailMask;
			#endif
			float4 _DetailMask_ST;
			float2 _DetailMaskPan;
			float _DetailMaskUV;
			float _DetailMaskStochastic;
			
			#if defined(PROP_DETAILNORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DetailNormalMap;
			#endif
			float4 _DetailNormalMap_ST;
			float2 _DetailNormalMapPan;
			float _DetailNormalMapUV;
			float _DetailNormalMapScale;
			float _DetailNormalMapStochastic;
			float _DetailNormalGlobalMask;
			float _DetailNormalGlobalMaskBlendType;
			
			#if defined(PROP_DETAILTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DetailTex;
			#endif
			float4 _DetailTex_ST;
			float2 _DetailTexPan;
			float _DetailTexUV;
			float _DetailTexStochastic;
			
			float3 _DetailTint;
			float _DetailTintThemeIndex;
			float _DetailTexIntensity;
			float _DetailBrightness;
			float _DetailTexGlobalMask;
			float _DetailTexGlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _VertexManipulationsEnabled==0
			#ifdef AUTO_EXPOSURE
			float4 _VertexManipulationLocalTranslation;
			float4 _VertexManipulationLocalRotation;
			float3 _VertexManipulationLocalRotationSpeed;
			float4 _VertexManipulationLocalScale;
			float4 _VertexManipulationWorldTranslation;
			float _VertexManipulationHeight;
			sampler2D _VertexManipulationHeightMask;
			float4 _VertexManipulationHeightMask_ST;
			float2 _VertexManipulationHeightMaskPan;
			float _VertexManipulationHeightMaskUV;
			float _VertexManipulationHeightMaskChannel;
			float _VertexManipulationHeightBias;
			float _VertexRoundingEnabled;
			int _VertexRoundingSpace;
			float _VertexRoundingDivision;
			
			//AL
			float _VertexAudioLinkEnabled;
			float3 _VertexLocalTranslationALMin;
			float3 _VertexLocalTranslationALMax;
			float _VertexLocalTranslationALBand;
			
			float3 _VertexLocalRotationAL;
			float _VertexLocalRotationALBand;
			
			float3 _VertexLocalRotationCTALSpeed;
			float _VertexLocalRotationCTALBandX;
			float _VertexLocalRotationCTALBandY;
			float _VertexLocalRotationCTALBandZ;
			float _VertexLocalRotationCTALTypeX;
			float _VertexLocalRotationCTALTypeY;
			float _VertexLocalRotationCTALTypeZ;
			
			float4 _VertexLocalScaleALMin;
			float4 _VertexLocalScaleALMax;
			float _VertexLocalScaleALBand;
			
			float3 _VertexWorldTranslationALMin;
			float3 _VertexWorldTranslationALMax;
			float _VertexWorldTranslationALBand;
			
			float2 _VertexManipulationHeightAL;
			float _VertexManipulationHeightBand;
			
			float2 _VertexRoundingRangeAL;
			float _VertexRoundingRangeBand;
			
			float _VertexBarrelMode;
			float _VertexBarrelWidth;
			float _VertexBarrelAlpha;
			float _VertexBarrelHeight;
			
			float _VertexSphereMode;
			float _VertexSphereRadius;
			float _VertexSphereHeight;
			float _VertexSphereAlpha;
			float4 _VertexSphereCenter;
			
			float _VertexTornadoMode;
			float _VertexTornadoRadius;
			float _VertexTornadoSpeed;
			float _VertexTornadoIntensity;
			float _VertexTornadoBaseHeight;
			float _VertexTornadoTopHeight;
			
			float _VertexSpectrumMotion;
			float3 _VertexSpectrumOffsetMin;
			float3 _VertexSpectrumOffsetMax;
			float _VertexSpectrumUV;
			float _VertexSpectrumUVDirection;
			#endif
			//endex
			
			//ifex _VertexGlitchingEnabled==0
			#ifdef POI_VERTEX_GLITCHING
			//Vertex Glitching
			#if defined(POI_VERTEX_GLITCHING_TEXTURE)
			float _VertexGlitchingUseTexture;
			sampler2D _VertexGlitchMap;
			float4 _VertexGlitchMap_ST;
			#endif
			float _VertexGlitchThreshold;
			float _VertexGlitchFrequency;
			float _VertexGlitchStrength;
			float _VertexGlitchDensity;
			
			float _VertexGlitchMirrorEnable;
			float _VertexGlitchMirror;
			
			float _VertexGlitchMapPanSpeed;
			float _VertexGlitchingAudioLinkEnabled;
			float _VertexGlitchingAudioLinkBand;
			float _VertexGlitchingAudiolinkOverride;
			#endif
			//endex
			
			//ifex _EnableDepthBulge==0
			#ifdef POI_DEPTHBULGE
			float _DepthBulgeFadeLength;
			float _DepthBulgeHeight;
			
			#if defined(PROP_DEPTHBULGEMASK) || !defined(OPTIMIZER_ENABLED)
			sampler2D _DepthBulgeMask;
			#endif
			float _DepthBulgeMaskUV;
			float4 _DepthBulgeMask_ST;
			float _DepthBulgeMaskChannel;
			#endif
			//endex
			
			//ifex _MainVertexColoringEnabled==0
			float _MainVertexColoringEnabled;
			float _MainVertexColoringLinearSpace;
			float _MainVertexColoring;
			float _MainUseVertexColorAlpha;
			//endex
			
			//ifex _BackFaceEnabled!=1
			#ifdef POI_BACKFACE
			float _BackFaceEnabled;
			float _BackFaceDetailIntensity;
			float _BackFaceEmissionStrength;
			float2 _BackFacePanning;
			float4 _BackFaceColor;
			float _BackFaceColorThemeIndex;
			float _BackFaceReplaceAlpha;
			
			#if defined(PROP_BACKFACETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BackFaceTexture;
			#endif
			float4 _BackFaceTexture_ST;
			float2 _BackFaceTexturePan;
			float _BackFaceTextureUV;
			
			#if defined(PROP_BACKFACEMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BackFaceMask;
			#endif
			float4 _BackFaceMask_ST;
			float2 _BackFaceMaskPan;
			float _BackFaceMaskUV;
			float _BackFaceMaskChannel;
			
			float _BackFaceHueShiftEnabled;
			float _BackFaceHueShift;
			float _BackFaceHueShiftSpeed;
			float _BackFaceEmissionLimiter;
			#endif
			
			//TODO detail strength stuff
			//endex
			
			//ifex _RGBMaskEnabled==0
			#ifdef VIGNETTE
			#if defined(PROP_RGBMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RGBMask;
			#endif
			float4 _RGBMask_ST;
			float2 _RGBMaskPan;
			float _RGBMaskUV;
			
			#if defined(PROP_RGBAMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RGBAMetallicMaps;
			float4 _RGBAMetallicMaps_ST;
			float2 _RGBAMetallicMapsPan;
			float _RGBAMetallicMapsUV;
			float _RGBAMetallicMapsStochastic;
			#endif
			float _RGBARedMetallicInvert;
			float _RGBAGreenMetallicInvert;
			float _RGBABlueMetallicInvert;
			float _RGBAAlphaMetallicInvert;
			float _RGBAMetallicRedEnabled;
			float _RGBAMetallicGreenEnabled;
			float _RGBAMetallicBlueEnabled;
			float _RGBAMetallicAlphaEnabled;
			
			float _RGBARedPBRSplitMaskSample;
			float4 _RGBARedPBRMaskScaleTiling;
			float2 _RGBARedPBRMasksPan;
			float _RGBARedPBRUV;
			float _RGBARedPBRSplitMaskStochastic;
			
			float _RGBAGreenPBRSplitMaskSample;
			float4 _RGBAGreenPBRMaskScaleTiling;
			float2 _RGBAGreenPBRMasksPan;
			float _RGBAGreenPBRUV;
			float _RGBAGreenPBRSplitMaskStochastic;
			
			float _RGBABluePBRSplitMaskSample;
			float4 _RGBABluePBRMaskScaleTiling;
			float2 _RGBABluePBRMasksPan;
			float _RGBABluePBRUV;
			float _RGBABluePBRSplitMaskStochastic;
			
			float _RGBAAlphaPBRSplitMaskSample;
			float4 _RGBAAlphaPBRMaskScaleTiling;
			float2 _RGBAAlphaPBRMasksPan;
			float _RGBAAlphaPBRUV;
			float _RGBAAlphaPBRSplitMaskStochastic;
			
			float _RGBAPBRRedEnabled;
			float _RGBAPBRGreenEnabled;
			float _RGBAPBRBlueEnabled;
			float _RGBAPBRAlphaEnabled;
			
			#if defined(PROP_RGBASMOOTHNESSMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RGBASmoothnessMaps;
			float4 _RGBASmoothnessMaps_ST;
			float4 _RGBASmoothnessMapsPan;
			float _RGBASmoothnessMapsUV;
			float _RGBASmoothnessMapsStochastic;
			#endif
			float _RGBARedSmoothnessInvert;
			float _RGBAGreenSmoothnessInvert;
			float _RGBABlueSmoothnessInvert;
			float _RGBAAlphaSmoothnessInvert;
			
			float _RGBARedEnable;
			#if defined(PROP_REDTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RedTexture;
			#endif
			float4 _RedTexture_ST;
			float2 _RedTexturePan;
			float _RedTextureUV;
			float _RedAlphaAdd;
			float _RedTextureStochastic;
			float _RgbRedMaskChannel;
			float _RgbRedGlobalMaskChannel;
			float _RgbRedGlobalMaskBlendType;
			float _RGBARedBlendType;
			float4 _RedColor;
			float _RedColorThemeIndex;
			float _RGBARedEmissionStrength;
			
			#if defined(PROP_RGBNORMALR) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RgbNormalR;
			#endif
			float4 _RgbNormalR_ST;
			float2 _RgbNormalRPan;
			float _RgbNormalRUV;
			float _RgbNormalRScale;
			float _RgbNormalRStochastic;
			float _RgbNormalRMaskChannel;
			float _RgbNormalRGlobalMaskChannel;
			float _RgbNormalRGlobalMaskBlendType;
			float _RgbNormalRedBlendMode;
			
			float _RGBAGreenEnable;
			#if defined(PROP_GREENTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GreenTexture;
			#endif
			float4 _GreenTexture_ST;
			float2 _GreenTexturePan;
			float _GreenTextureUV;
			float _GreenAlphaAdd;
			float _GreenTextureStochastic;
			float _RgbGreenMaskChannel;
			float _RgbGreenGlobalMaskChannel;
			float _RgbGreenGlobalMaskBlendType;
			float _RGBAGreenBlendType;
			float4 _GreenColor;
			float _GreenColorThemeIndex;
			float _RGBAGreenEmissionStrength;
			
			#if defined(PROP_RGBNORMALG) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RgbNormalG;
			#endif
			float4 _RgbNormalG_ST;
			float2 _RgbNormalGPan;
			float _RgbNormalGUV;
			float _RgbNormalGScale;
			float _RgbNormalGStochastic;
			float _RgbNormalGMaskChannel;
			float _RgbNormalGGlobalMaskChannel;
			float _RgbNormalGGlobalMaskBlendType;
			float _RgbNormalGreenBlendMode;
			
			float _RGBABlueEnable;
			#if defined(PROP_BLUETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BlueTexture;
			#endif
			float4 _BlueTexture_ST;
			float2 _BlueTexturePan;
			float _BlueTextureUV;
			float _BlueAlphaAdd;
			float _BlueTextureStochastic;
			float _RgbBlueMaskChannel;
			float _RgbBlueGlobalMaskChannel;
			float _RgbBlueGlobalMaskBlendType;
			float _RGBABlueBlendType;
			float4 _BlueColor;
			float _BlueColorThemeIndex;
			float _RGBABlueEmissionStrength;
			
			#if defined(PROP_RGBNORMALB) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RgbNormalB;
			#endif
			float4 _RgbNormalB_ST;
			float2 _RgbNormalBPan;
			float _RgbNormalBUV;
			float _RgbNormalBScale;
			float _RgbNormalBStochastic;
			float _RgbNormalBMaskChannel;
			float _RgbNormalBGlobalMaskChannel;
			float _RgbNormalBGlobalMaskBlendType;
			float _RgbNormalBlueBlendMode;
			
			float _RGBAAlphaEnable;
			#if defined(PROP_ALPHATEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AlphaTexture;
			#endif
			float4 _AlphaTexture_ST;
			float2 _AlphaTexturePan;
			float _AlphaTextureUV;
			float _AlphaAlphaAdd;
			float _AlphaTextureStochastic;
			float _RgbAlphaMaskChannel;
			float _RgbAlphaGlobalMaskChannel;
			float _RgbAlphaGlobalMaskBlendType;
			float _RGBAAlphaBlendType;
			float4 _AlphaColor;
			float _AlphaColorThemeIndex;
			float _RGBAAlphaEmissionStrength;
			
			#if defined(PROP_RGBNORMALA) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RgbNormalA;
			#endif
			float4 _RgbNormalA_ST;
			float2 _RgbNormalAPan;
			float _RgbNormalAUV;
			float _RgbNormalAScale;
			float _RgbNormalAStochastic;
			float _RgbNormalAMaskChannel;
			float _RgbNormalAGlobalMaskChannel;
			float _RgbNormalAGlobalMaskBlendType;
			float _RgbNormalAlphaBlendMode;
			
			float _RGBMaskType;
			
			#endif
			//endex
			
			//ifex _ShadingEnabled==0
			float _ShadowStrength;
			float _LightingIgnoreAmbientColor;
			float3 _LightingShadowColor;
			
			float _ShadingRampedLightMapApplyGlobalMaskIndex;
			float _ShadingRampedLightMapApplyGlobalMaskBlendType;
			
			float _ShadingRampedLightMapInverseApplyGlobalMaskIndex;
			float _ShadingRampedLightMapInverseApplyGlobalMaskBlendType;
			
			// Toon Lighting
			#ifdef _LIGHTINGMODE_TEXTURERAMP
			UNITY_DECLARE_TEX2D(_ToonRamp);
			float _ShadowOffset;
			int _ToonRampCount;
			int _ToonRampUVSelector;
			#endif
			
			#ifdef _LIGHTINGMODE_WRAPPED
			float4 _LightingWrappedColor;
			float _LightingWrappedWrap;
			float _LightingWrappedNormalization;
			float _LightingGradientStart;
			float _LightingGradientEnd;
			#endif
			
			#ifdef _LIGHTINGMODE_SHADEMAP
			float3 _1st_ShadeColor;
			#if defined(PROP_1ST_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _1st_ShadeMap;
			#endif
			float4 _1st_ShadeMap_ST;
			float2 _1st_ShadeMapPan;
			float _1st_ShadeMapUV;
			float _Use_1stShadeMapAlpha_As_ShadowMask;
			float _1stShadeMapMask_Inverse;
			float _Use_BaseAs1st;
			float3 _2nd_ShadeColor;
			#if defined(PROP_2ND_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _2nd_ShadeMap;
			#endif
			float4 _2nd_ShadeMap_ST;
			float2 _2nd_ShadeMapPan;
			float _2nd_ShadeMapUV;
			float _Use_2ndShadeMapAlpha_As_ShadowMask;
			float _2ndShadeMapMask_Inverse;
			float _Use_1stAs2nd;
			float _BaseColor_Step;
			float _BaseShade_Feather;
			float _ShadeColor_Step;
			float _1st2nd_Shades_Feather;
			float _ShadingShadeMapBlendType;
			#endif
			
			#ifdef _LIGHTINGMODE_SKIN
			sampler2D _SkinLUT;
			float _SssScale;
			#if defined(PROP_SKINTHICKNESS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _SkinThicknessMap;
			#endif
			float4 _SkinThicknessMap_ST;
			float2 _SkinThicknessMapPan;
			float _SkinThicknessMapUV;
			float _SkinThicknessMapInvert;
			float _SkinThicknessPower;
			float _SssBumpBlur;
			float3 _SssTransmissionAbsorption;
			float3 _SssColorBleedAoWeights;
			#endif
			
			#ifdef _LIGHTINGMODE_MULTILAYER_MATH
			float _ShadowBorderMapToggle;
			#if defined(PROP_SHADOWBORDERMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ShadowBorderMask;
			float4 _ShadowBorderMask_ST;
			float2 _ShadowBorderMaskPan;
			float _ShadowBorderMaskUV;
			#endif
			float _ShadowPostAO;
			float _ShadowBorderMaskLOD;
			float4 _ShadowAOShift;
			float4 _ShadowAOShift2;
			
			float4 _ShadowColor;
			float _LightingMulitlayerNonLinear;
			#if defined(PROP_SHADOWCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ShadowColorTex;
			float4 _ShadowColorTex_ST;
			float2 _ShadowColorTexPan;
			float _ShadowColorTexUV;
			#endif
			#if defined(PROP_MULTILAYERMATHBLURMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MultilayerMathBlurMap;
			float4 _MultilayerMathBlurMap_ST;
			float2 _MultilayerMathBlurMapPan;
			float _MultilayerMathBlurMapUV;
			#endif
			float _ShadowBorder;
			float _ShadowBlur;
			float _ShadowReceive;
			float4 _Shadow2ndColor;
			#if defined(PROP_SHADOW2NDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Shadow2ndColorTex;
			float4 _Shadow2ndColorTex_ST;
			float2 _Shadow2ndColorTexPan;
			float _Shadow2ndColorTexUV;
			#endif
			float _Shadow2ndBorder;
			float _Shadow2ndBlur;
			float _Shadow2ndReceive;
			float4 _Shadow3rdColor;
			#if defined(PROP_SHADOW3RDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Shadow3rdColorTex;
			float4 _Shadow3rdColorTex_ST;
			float2 _Shadow3rdColorTexPan;
			float _Shadow3rdColorTexUV;
			#endif
			float _Shadow3rdBorder;
			float _Shadow3rdBlur;
			float _Shadow3rdReceive;
			float4 _ShadowBorderColor;
			float _ShadowBorderRange;
			float _ShadowMainStrength;
			#endif
			
			#ifdef _LIGHTINGMODE_FLAT
			float _ForceFlatRampedLightmap;
			#endif
			
			#ifdef _LIGHTINGMODE_CLOTH
			Texture2D_float _ClothDFG;
			SamplerState sampler_ClothDFG;
			
			#if defined(PROP_CLOTHMETALLICSMOOTHNESSMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ClothMetallicSmoothnessMap;
			#endif
			
			float4 _ClothMetallicSmoothnessMap_ST;
			float2 _ClothMetallicSmoothnessMapPan;
			float _ClothMetallicSmoothnessMapUV;
			float _ClothMetallicSmoothnessMapInvert;
			
			float _ClothLerp;
			float _ClothMetallic;
			float _ClothReflectance;
			float _ClothSmoothness;
			#endif
			
			#ifdef _LIGHTINGMODE_SDF
			#if defined(PROP_SDFSHADINGTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _SDFShadingTexture;
			float _SDFShadingTextureUV;
			float2 _SDFShadingTexturePan;
			float4 _SDFShadingTexture_ST;
			float _SDFBlur;
			float4 _SDFForward;
			float4 _SDFLeft;
			#endif
			#endif
			
			// Additive
			float _LightingAdditiveType;
			float _LightingAdditiveGradientStart;
			float _LightingAdditiveGradientEnd;
			float _LightingAdditiveDetailStrength;
			//endex
			
			//ifex _DecalEnabled==0 && _DecalEnabled1==0 && _DecalEnabled2==0 && _DecalEnabled3==0
			
			#if defined(PROP_DECALMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DecalMask;
			float4 _DecalMask_ST;
			float2 _DecalMaskPan;
			float _DecalMaskUV;
			#endif
			float _DecalTPSDepthMaskEnabled;
			float _Decal0TPSMaskStrength;
			float _Decal1TPSMaskStrength;
			float _Decal2TPSMaskStrength;
			float _Decal3TPSMaskStrength;
			
			sampler2D _Udon_VideoTex;
			float4 _Udon_VideoTex_TexelSize;
			
			#ifdef POI_AUDIOLINK
			//ifex _DecalEnabled==0
			#ifdef GEOM_TYPE_BRANCH
			// Audio Link
			half _AudioLinkDecal0ScaleBand;
			float4 _AudioLinkDecal0Scale;
			half _AudioLinkDecal0RotationBand;
			float2 _AudioLinkDecal0Rotation;
			half _AudioLinkDecal0AlphaBand;
			float2 _AudioLinkDecal0Alpha;
			half _AudioLinkDecal0EmissionBand;
			float2 _AudioLinkDecal0Emission;
			float _DecalRotationCTALBand0;
			float _DecalRotationCTALSpeed0;
			float _DecalRotationCTALType0;
			float _AudioLinkDecalCC0;
			float _AudioLinkDecal0SideBand;
			float4 _AudioLinkDecal0SideMin;
			float4 _AudioLinkDecal0SideMax;
			float2 _AudioLinkDecal0ChannelSeparation;
			float _AudioLinkDecal0ChannelSeparationBand;
			#endif //GEOM_TYPE_BRANCH
			//endex
			//ifex _DecalEnabled1==0
			#ifdef GEOM_TYPE_BRANCH_DETAIL
			half _AudioLinkDecal1ScaleBand;
			float4 _AudioLinkDecal1Scale;
			half _AudioLinkDecal1RotationBand;
			float2 _AudioLinkDecal1Rotation;
			half _AudioLinkDecal1AlphaBand;
			float2 _AudioLinkDecal1Alpha;
			half _AudioLinkDecal1EmissionBand;
			float2 _AudioLinkDecal1Emission;
			float _DecalRotationCTALBand1;
			float _DecalRotationCTALSpeed1;
			float _DecalRotationCTALType1;
			float _AudioLinkDecalCC1;
			float _AudioLinkDecal1SideBand;
			float4 _AudioLinkDecal1SideMin;
			float4 _AudioLinkDecal1SideMax;
			float2 _AudioLinkDecal1ChannelSeparation;
			float _AudioLinkDecal1ChannelSeparationBand;
			#endif //GEOM_TYPE_BRANCH_DETAIL
			//endex
			//ifex _DecalEnabled2==0
			#ifdef GEOM_TYPE_FROND
			half _AudioLinkDecal2ScaleBand;
			float4 _AudioLinkDecal2Scale;
			half _AudioLinkDecal2RotationBand;
			float2 _AudioLinkDecal2Rotation;
			half _AudioLinkDecal2AlphaBand;
			float2 _AudioLinkDecal2Alpha;
			half _AudioLinkDecal2EmissionBand;
			float2 _AudioLinkDecal2Emission;
			float _DecalRotationCTALBand2;
			float _DecalRotationCTALSpeed2;
			float _DecalRotationCTALType2;
			float _AudioLinkDecalCC2;
			float _AudioLinkDecal2SideBand;
			float4 _AudioLinkDecal2SideMin;
			float4 _AudioLinkDecal2SideMax;
			float2 _AudioLinkDecal2ChannelSeparation;
			float _AudioLinkDecal2ChannelSeparationBand;
			#endif //GEOM_TYPE_FROND
			//endex
			//ifex _DecalEnabled3==0
			#ifdef DEPTH_OF_FIELD_COC_VIEW
			half _AudioLinkDecal3ScaleBand;
			float4 _AudioLinkDecal3Scale;
			half _AudioLinkDecal3RotationBand;
			float2 _AudioLinkDecal3Rotation;
			half _AudioLinkDecal3AlphaBand;
			float2 _AudioLinkDecal3Alpha;
			half _AudioLinkDecal3EmissionBand;
			float2 _AudioLinkDecal3Emission;
			float _DecalRotationCTALBand3;
			float _DecalRotationCTALSpeed3;
			float _DecalRotationCTALType3;
			float _AudioLinkDecalCC3;
			float _AudioLinkDecal3SideBand;
			float4 _AudioLinkDecal3SideMin;
			float4 _AudioLinkDecal3SideMax;
			float2 _AudioLinkDecal3ChannelSeparation;
			float _AudioLinkDecal3ChannelSeparationBand;
			#endif //DEPTH_OF_FIELD_COC_VIEW
			//endex
			#endif
			//endex
			//ifex _DecalEnabled==0
			#ifdef GEOM_TYPE_BRANCH
			float _Decal0VideoFitToScale;
			float _Decal0VideoAspectFix;
			float _Decal0VideoEmissionStrength;
			float _Decal0VideoEnabled;
			float _Decal0UseDecalAlpha;
			float _Decal0OnlyVideo;
			sampler2D _DecalTexture;
			float _Decal0FaceMask;
			float _Decal0MaskChannel;
			float _Decal0GlobalMask;
			float _Decal0GlobalMaskBlendType;
			float _Decal0ApplyGlobalMaskIndex;
			float _Decal0ApplyGlobalMaskBlendType;
			float4 _DecalTexture_ST;
			float2 _DecalTexturePan;
			float _DecalTextureUV;
			float4 _DecalColor;
			float _DecalColorThemeIndex;
			float _DecalTiled;
			float _DecalBlendType;
			half _DecalRotation;
			half3 _DecalScale;
			float4 _DecalSideOffset;
			half2 _DecalPosition;
			half _DecalRotationSpeed;
			float _DecalEmissionStrength;
			float _DecalBlendAlpha;
			float _DecalOverrideAlpha;
			float _DecalHueShiftEnabled;
			float _DecalHueShift;
			float _DecalHueShiftSpeed;
			float _Decal0Depth;
			float _Decal0HueAngleStrength;
			float _Decal0ChannelSeparationEnable;
			float _Decal0ChannelSeparation;
			float _Decal0ChannelSeparationPremultiply;
			float _Decal0ChannelSeparationHue;
			float _Decal0ChannelSeparationVertical;
			float _Decal0ChannelSeparationAngleStrength;
			float _Decal0OverrideAlphaMode;
			#endif
			//endex
			
			//ifex _DecalEnabled1==0
			#ifdef GEOM_TYPE_BRANCH_DETAIL
			float _Decal1VideoAspectFix;
			float _Decal1VideoFitToScale;
			float _Decal1VideoEmissionStrength;
			float _Decal1VideoEnabled;
			float _Decal1UseDecalAlpha;
			float _Decal1OnlyVideo;
			float _Decal1TextureToUse;
			sampler2D _DecalTexture1;
			float _Decal1FaceMask;
			float _Decal1MaskChannel;
			float _Decal1GlobalMask;
			float _Decal1GlobalMaskBlendType;
			float _Decal1ApplyGlobalMaskIndex;
			float _Decal1ApplyGlobalMaskBlendType;
			float4 _DecalTexture1_ST;
			float2 _DecalTexture1Pan;
			float _DecalTexture1UV;
			float4 _DecalColor1;
			float _DecalColor1ThemeIndex;
			fixed _DecalTiled1;
			float _DecalBlendType1;
			half _DecalRotation1;
			half3 _DecalScale1;
			float4 _DecalSideOffset1;
			half2 _DecalPosition1;
			half _DecalRotationSpeed1;
			float _DecalEmissionStrength1;
			float _DecalBlendAlpha1;
			float _DecalOverrideAlpha1;
			float _DecalHueShiftEnabled1;
			float _DecalHueShift1;
			float _DecalHueShiftSpeed1;
			float _Decal1Depth;
			float _Decal1HueAngleStrength;
			float _Decal1ChannelSeparationEnable;
			float _Decal1ChannelSeparation;
			float _Decal1ChannelSeparationPremultiply;
			float _Decal1ChannelSeparationHue;
			float _Decal1ChannelSeparationVertical;
			float _Decal1ChannelSeparationAngleStrength;
			float _Decal1OverrideAlphaMode;
			#endif
			//endex
			
			//ifex _DecalEnabled2==0
			#ifdef GEOM_TYPE_FROND
			float _Decal2VideoAspectFix;
			float _Decal2VideoFitToScale;
			float _Decal2VideoEmissionStrength;
			float _Decal2VideoEnabled;
			float _Decal2UseDecalAlpha;
			float _Decal2OnlyVideo;
			float _Decal2TextureToUse;
			sampler2D _DecalTexture2;
			float _Decal2FaceMask;
			float _Decal2MaskChannel;
			float _Decal2GlobalMask;
			float _Decal2GlobalMaskBlendType;
			float _Decal2ApplyGlobalMaskIndex;
			float _Decal2ApplyGlobalMaskBlendType;
			float4 _DecalTexture2_ST;
			float2 _DecalTexture2Pan;
			float _DecalTexture2UV;
			float4 _DecalColor2;
			float _DecalColor2ThemeIndex;
			fixed _DecalTiled2;
			float _DecalBlendType2;
			half _DecalRotation2;
			half3 _DecalScale2;
			float4 _DecalSideOffset2;
			half2 _DecalPosition2;
			half _DecalRotationSpeed2;
			float _DecalEmissionStrength2;
			float _DecalBlendAlpha2;
			float _DecalOverrideAlpha2;
			float _DecalHueShiftEnabled2;
			float _DecalHueShift2;
			float _DecalHueShiftSpeed2;
			float _Decal2Depth;
			float _Decal2HueAngleStrength;
			float _Decal2ChannelSeparationEnable;
			float _Decal2ChannelSeparation;
			float _Decal2ChannelSeparationPremultiply;
			float _Decal2ChannelSeparationHue;
			float _Decal2ChannelSeparationVertical;
			float _Decal2ChannelSeparationAngleStrength;
			float _Decal2OverrideAlphaMode;
			#endif
			//endex
			
			//ifex _DecalEnabled3==0
			#ifdef DEPTH_OF_FIELD_COC_VIEW
			float _Decal3VideoAspectFix;
			float _Decal3VideoFitToScale;
			float _Decal3VideoEmissionStrength;
			float _Decal3VideoEnabled;
			float _Decal3UseDecalAlpha;
			float _Decal3OnlyVideo;
			float _Decal3TextureToUse;
			sampler2D _DecalTexture3;
			float _Decal3FaceMask;
			float _Decal3MaskChannel;
			float _Decal3GlobalMask;
			float _Decal3GlobalMaskBlendType;
			float _Decal3ApplyGlobalMaskIndex;
			float _Decal3ApplyGlobalMaskBlendType;
			float4 _DecalTexture3_ST;
			float2 _DecalTexture3Pan;
			float _DecalTexture3UV;
			float4 _DecalColor3;
			float _DecalColor3ThemeIndex;
			fixed _DecalTiled3;
			float _DecalBlendType3;
			half _DecalRotation3;
			half3 _DecalScale3;
			float4 _DecalSideOffset3;
			half2 _DecalPosition3;
			half _DecalRotationSpeed3;
			float _DecalEmissionStrength3;
			float _DecalBlendAlpha3;
			float _DecalOverrideAlpha3;
			float _DecalHueShiftEnabled3;
			float _DecalHueShift3;
			float _DecalHueShiftSpeed3;
			float _Decal3Depth;
			float _Decal3HueAngleStrength;
			float _Decal3ChannelSeparationEnable;
			float _Decal3ChannelSeparation;
			float _Decal3ChannelSeparationPremultiply;
			float _Decal3ChannelSeparationHue;
			float _Decal3ChannelSeparationVertical;
			float _Decal3ChannelSeparationAngleStrength;
			float _Decal3OverrideAlphaMode;
			#endif
			//endex
			
			//ifex _EnableDissolve==0
			#ifdef DISTORT
			float _DissolveType;
			float _DissolveEdgeWidth;
			float4 _DissolveEdgeColor;
			sampler2D _DissolveEdgeGradient;
			float4 _DissolveEdgeGradient_ST;
			float2 _DissolveEdgeGradientPan;
			float _DissolveEdgeGradientUV;
			float _DissolveEdgeEmission;
			float4 _DissolveTextureColor;
			float _DissolveEdgeColorThemeIndex;
			float _DissolveTextureColorThemeIndex;
			
			#if defined(PROP_DISSOLVETOTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveToTexture;
			#endif
			float4 _DissolveToTexture_ST;
			float2 _DissolveToTexturePan;
			float _DissolveToTextureUV;
			
			#if defined(PROP_DISSOLVENOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveNoiseTexture;
			#endif
			float4 _DissolveNoiseTexture_ST;
			float2 _DissolveNoiseTexturePan;
			float _DissolveNoiseTextureUV;
			
			#if defined(PROP_DISSOLVEDETAILNOISE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveDetailNoise;
			#endif
			float4 _DissolveDetailNoise_ST;
			float2 _DissolveDetailNoisePan;
			float _DissolveDetailNoiseUV;
			
			#if defined(PROP_DISSOLVEMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveMask;
			#endif
			float4 _DissolveMask_ST;
			float2 _DissolveMaskPan;
			float _DissolveMaskUV;
			
			float _DissolveMaskGlobalMask;
			float _DissolveMaskGlobalMaskBlendType;
			float _DissolveApplyGlobalMaskIndex;
			float _DissolveApplyGlobalMaskBlendType;
			float _DissolveInverseApplyGlobalMaskBlendType;
			float _DissolveInverseApplyGlobalMaskIndex;
			float _DissolveMaskInvert;
			float _DissolveAlpha;
			float _ContinuousDissolve;
			float _DissolveDetailStrength;
			float _DissolveDetailEdgeSmoothing;
			float _DissolveEdgeHardness;
			float _DissolveInvertNoise;
			float _DissolveInvertDetailNoise;
			float _DissolveToEmissionStrength;
			
			// Point to Point
			float _DissolveP2PWorldLocal;
			float _DissolveP2PEdgeLength;
			float _DissolveP2PClamp;
			float4 _DissolveStartPoint;
			float4 _DissolveEndPoint;
			
			// Spherical
			float3 _SphericalDissolveCenter;
			float _SphericalDissolveRadius;
			float _SphericalDissolveInvert;
			float _SphericalDissolveClamp;
			
			// CenterOut
			float _CenterOutDissolveMode;
			float3 _CenterOutDissolveDirection;
			float _CenterOutDissolveInvert;
			float _CenterOutDissolveNormals;
			float _CenterOutDissolvePower;
			
			// World Dissolve
			float _DissolveWorldShape;
			float4 _DissolveShapePosition;
			float4 _DissolveShapeRotation;
			float _DissolveShapeScale;
			float _DissolveInvertShape;
			float _DissolveShapeEdgeLength;
			
			// UV Tile Dissolve
			float _UVTileDissolveEnabled;
			float _UVTileDissolveDiscardAtMax;
			float _UVTileDissolveUV;
			
			float _UVTileDissolveAlpha_Row3_0;
			float _UVTileDissolveAlpha_Row3_1;
			float _UVTileDissolveAlpha_Row3_2;
			float _UVTileDissolveAlpha_Row3_3;
			float _UVTileDissolveAlpha_Row2_0;
			float _UVTileDissolveAlpha_Row2_1;
			float _UVTileDissolveAlpha_Row2_2;
			float _UVTileDissolveAlpha_Row2_3;
			float _UVTileDissolveAlpha_Row1_0;
			float _UVTileDissolveAlpha_Row1_1;
			float _UVTileDissolveAlpha_Row1_2;
			float _UVTileDissolveAlpha_Row1_3;
			float _UVTileDissolveAlpha_Row0_0;
			float _UVTileDissolveAlpha_Row0_1;
			float _UVTileDissolveAlpha_Row0_2;
			float _UVTileDissolveAlpha_Row0_3;
			
			float _DissolveAlpha0;
			float _DissolveAlpha1;
			float _DissolveAlpha2;
			float _DissolveAlpha3;
			float _DissolveAlpha4;
			float _DissolveAlpha5;
			float _DissolveAlpha6;
			float _DissolveAlpha7;
			float _DissolveAlpha8;
			float _DissolveAlpha9;
			// Masking
			float _DissolveEmissionSide;
			float _DissolveEmission1Side;
			float _DissolveUseVertexColors;
			
			float4 edgeColor;
			float edgeAlpha;
			float dissolveAlpha;
			float4 dissolveToTexture;
			
			float _DissolveHueShiftEnabled;
			float _DissolveHueShiftSpeed;
			float _DissolveHueShift;
			float _DissolveEdgeHueShiftEnabled;
			float _DissolveEdgeHueShiftSpeed;
			float _DissolveEdgeHueShift;
			
			// Audio Link
			#ifdef POI_AUDIOLINK
			fixed _EnableDissolveAudioLink;
			half _AudioLinkDissolveAlphaBand;
			float2 _AudioLinkDissolveAlpha;
			half _AudioLinkDissolveDetailBand;
			float2 _AudioLinkDissolveDetail;
			#endif
			#endif
			//endex
			
			//ifex _EnableAniso==0
			#ifdef POI_ANISOTROPICS
			
			#if defined(PROP_ANISOCOLORMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AnisoColorMap;
			float4 _AnisoColorMap_ST;
			float2 _AnisoColorMapPan;
			float _AnisoColorMapUV;
			#endif
			/*
			#if defined(PROP_ANISONOISEMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AnisoNoiseMap;
			float4 _AnisoNoiseMap_ST;
			float2 _AnisoNoiseMapPan;
			float _AnisoNoiseMapUV;
			#endif
			*/
			float _AnisoHideInShadow;
			float _AnisoReplace;
			float _AnisoAdd;
			float _AnisoUseBaseColor;
			float _AnisoUseLightColor;
			
			float _AnisoGlobalMask;
			float _AnisoGlobalMaskBlendType;
			
			float _Aniso0Strength;
			float _Aniso0Power;
			float _Aniso0Offset;
			float _Aniso0SwitchDirection;
			float4 _Aniso0Tint;
			float _Aniso0TintIndex;
			float _Aniso0OffsetMapStrength;
			float _Aniso0ToonMode;
			float _Aniso0Edge;
			float _Aniso0Blur;
			
			float _Aniso1Strength;
			float _Aniso1Power;
			float _Aniso1Offset;
			float _Aniso1SwitchDirection;
			float4 _Aniso1Tint;
			float _Aniso1TintIndex;
			float _Aniso1OffsetMapStrength;
			float _Aniso1ToonMode;
			float _Aniso1Edge;
			float _Aniso1Blur;
			#endif
			//endex
			
			//ifex _MatcapEnable==0
			#ifdef POI_MATCAP0
			#if defined(PROP_MATCAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap;
			float4 _Matcap_ST;
			float4 _Matcap_TexelSize;
			float2 _MatcapPan;
			float _MatcapUV;
			#endif
			#if defined(PROP_MATCAPMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MatcapMask;
			float4 _MatcapMask_ST;
			float2 _MatcapMaskPan;
			float _MatcapMaskUV;
			float _MatcapMaskChannel;
			#endif
			#ifdef POI_MATCAP0_CUSTOM_NORMAL
			#if defined(PROP_MATCAP0NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap0NormalMap;
			#endif
			float4 _Matcap0NormalMap_ST;
			float2 _Matcap0NormalMapPan;
			float _Matcap0NormalMapUV;
			float _Matcap0NormalMapScale;
			#endif
			float _MatcapUVToBlend;
			float4 _MatCapBlendUV1;
			float _MatcapUVMode;
			float _MatcapMaskInvert;
			float _MatcapMaskGlobalMask;
			float _MatcapMaskGlobalMaskBlendType;
			float _MatcapBorder;
			float _MatcapRotation;
			float _MatcapSmoothnessEnabled;
			float _MatcapSmoothness;
			float _MatcapMaskSmoothnessChannel;
			float _MatcapMaskSmoothnessApply;
			float4 _MatcapColor;
			float _MatcapBaseColorMix;
			float _MatcapColorThemeIndex;
			float _MatcapIntensity;
			float _MatcapReplace;
			float _MatcapMultiply;
			float _MatcapAdd;
			float _MatcapAddToLight;
			float _MatcapMixed;
			float _MatcapScreen;
			float _MatcapAlphaOverride;
			float _MatcapEnable;
			float _MatcapLightMask;
			float _MatcapEmissionStrength;
			float _MatcapNormal;
			float _MatcapHueShiftEnabled;
			float _MatcapHueShiftSpeed;
			float _MatcapHueShift;
			int _MatcapApplyToAlphaEnabled;
			int _MatcapApplyToAlphaSourceBlend;
			int _MatcapApplyToAlphaBlendType;
			float _MatcapApplyToAlphaBlending;
			float _MatcapTPSDepthEnabled;
			float _MatcapTPSMaskStrength;
			
			float _Matcap0ALEnabled;
			float _Matcap0ALAlphaAddBand;
			float4 _Matcap0ALAlphaAdd;
			float _Matcap0ALEmissionAddBand;
			float4 _Matcap0ALEmissionAdd;
			float _Matcap0ALIntensityAddBand;
			float4 _Matcap0ALIntensityAdd;
			float _Matcap0ALChronoPanType;
			float _Matcap0ALChronoPanBand;
			float _Matcap0ALChronoPanSpeed;
			#endif
			//endex
			//ifex _Matcap2Enable==0
			#ifdef COLOR_GRADING_HDR_3D
			#if defined(PROP_MATCAP2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap2;
			float4 _Matcap2_ST;
			float4 _Matcap2_TexelSize;
			float2 _Matcap2Pan;
			float _Matcap2UV;
			#endif
			#if defined(PROP_MATCAP2MASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap2Mask;
			float4 _Matcap2Mask_ST;
			float2 _Matcap2MaskPan;
			float _Matcap2MaskUV;
			float _Matcap2MaskChannel;
			#endif
			#ifdef POI_MATCAP1_CUSTOM_NORMAL
			#if defined(PROP_MATCAP1NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap1NormalMap;
			#endif
			float4 _Matcap1NormalMap_ST;
			float2 _Matcap1NormalMapPan;
			float _Matcap1NormalMapUV;
			float _Matcap1NormalMapScale;
			#endif
			float _Matcap2UVToBlend;
			float4 _MatCap2ndBlendUV1;
			float _Matcap2UVMode;
			float _Matcap2MaskInvert;
			float _Matcap2MaskGlobalMask;
			float _Matcap2MaskGlobalMaskBlendType;
			float _Matcap2Border;
			float _Matcap2Rotation;
			float _Matcap2SmoothnessEnabled;
			float _Matcap2Smoothness;
			float _Matcap2MaskSmoothnessChannel;
			float _Matcap2MaskSmoothnessApply;
			float4 _Matcap2Color;
			float _Matcap2BaseColorMix;
			float _Matcap2ColorThemeIndex;
			float _Matcap2Intensity;
			float _Matcap2Replace;
			float _Matcap2Multiply;
			float _Matcap2Add;
			float _Matcap2AddToLight;
			float _Matcap2Mixed;
			float _Matcap2Screen;
			float _Matcap2AlphaOverride;
			float _Matcap2Enable;
			float _Matcap2LightMask;
			float _Matcap2EmissionStrength;
			float _Matcap2Normal;
			float _Matcap2HueShiftEnabled;
			float _Matcap2HueShiftSpeed;
			float _Matcap2HueShift;
			int _Matcap2ApplyToAlphaEnabled;
			int _Matcap2ApplyToAlphaSourceBlend;
			int _Matcap2ApplyToAlphaBlendType;
			float _Matcap2ApplyToAlphaBlending;
			float _Matcap2TPSDepthEnabled;
			float _Matcap2TPSMaskStrength;
			
			float _Matcap1ALEnabled;
			float _Matcap1ALAlphaAddBand;
			float4 _Matcap1ALAlphaAdd;
			float _Matcap1ALEmissionAddBand;
			float4 _Matcap1ALEmissionAdd;
			float _Matcap1ALIntensityAddBand;
			float4 _Matcap1ALIntensityAdd;
			float _Matcap1ALChronoPanType;
			float _Matcap1ALChronoPanBand;
			float _Matcap1ALChronoPanSpeed;
			#endif
			//endex
			
			//ifex _Matcap3Enable==0
			#ifdef POI_MATCAP2
			#if defined(PROP_MATCAP3) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap3;
			float4 _Matcap3_ST;
			float4 _Matcap3_TexelSize;
			float2 _Matcap3Pan;
			float _Matcap3UV;
			#endif
			#if defined(PROP_MATCAP3MASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap3Mask;
			float4 _Matcap3Mask_ST;
			float2 _Matcap3MaskPan;
			float _Matcap3MaskUV;
			float _Matcap3MaskChannel;
			#endif
			#ifdef POI_MATCAP2_CUSTOM_NORMAL
			#if defined(PROP_MATCAP2NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap2NormalMap;
			#endif
			float4 _Matcap2NormalMap_ST;
			float2 _Matcap2NormalMapPan;
			float _Matcap2NormalMapUV;
			float _Matcap2NormalMapScale;
			#endif
			float _Matcap3UVToBlend;
			float4 _MatCap3rdBlendUV1;
			float _Matcap3UVMode;
			float _Matcap3MaskInvert;
			float _Matcap3MaskGlobalMask;
			float _Matcap3MaskGlobalMaskBlendType;
			float _Matcap3Border;
			float _Matcap3Rotation;
			float _Matcap3SmoothnessEnabled;
			float _Matcap3Smoothness;
			float _Matcap3MaskSmoothnessChannel;
			float _Matcap3MaskSmoothnessApply;
			float4 _Matcap3Color;
			float _Matcap3BaseColorMix;
			float _Matcap3ColorThemeIndex;
			float _Matcap3Intensity;
			float _Matcap3Replace;
			float _Matcap3Multiply;
			float _Matcap3Add;
			float _Matcap3AddToLight;
			float _Matcap3Mixed;
			float _Matcap3Screen;
			float _Matcap3AlphaOverride;
			float _Matcap3Enable;
			float _Matcap3LightMask;
			float _Matcap3EmissionStrength;
			float _Matcap3Normal;
			float _Matcap3HueShiftEnabled;
			float _Matcap3HueShiftSpeed;
			float _Matcap3HueShift;
			int _Matcap3ApplyToAlphaEnabled;
			int _Matcap3ApplyToAlphaSourceBlend;
			int _Matcap3ApplyToAlphaBlendType;
			float _Matcap3ApplyToAlphaBlending;
			float _Matcap3TPSDepthEnabled;
			float _Matcap3TPSMaskStrength;
			
			float _Matcap2ALEnabled;
			float _Matcap2ALAlphaAddBand;
			float4 _Matcap2ALAlphaAdd;
			float _Matcap2ALEmissionAddBand;
			float4 _Matcap2ALEmissionAdd;
			float _Matcap2ALIntensityAddBand;
			float4 _Matcap2ALIntensityAdd;
			float _Matcap2ALChronoPanType;
			float _Matcap2ALChronoPanBand;
			float _Matcap2ALChronoPanSpeed;
			#endif
			//endex
			
			//ifex _Matcap4Enable==0
			#ifdef POI_MATCAP3
			#if defined(PROP_MATCAP4) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap4;
			float4 _Matcap4_ST;
			float4 _Matcap4_TexelSize;
			float2 _Matcap4Pan;
			float _Matcap4UV;
			#endif
			#if defined(PROP_MATCAP4MASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap4Mask;
			float4 _Matcap4Mask_ST;
			float2 _Matcap4MaskPan;
			float _Matcap4MaskUV;
			float _Matcap4MaskChannel;
			#endif
			#ifdef POI_MATCAP3_CUSTOM_NORMAL
			#if defined(PROP_MATCAP3NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap3NormalMap;
			#endif
			float4 _Matcap3NormalMap_ST;
			float2 _Matcap3NormalMapPan;
			float _Matcap3NormalMapUV;
			float _Matcap3NormalMapScale;
			#endif
			float _Matcap4UVToBlend;
			float4 _MatCap4thBlendUV1;
			float _Matcap4UVMode;
			float _Matcap4MaskInvert;
			float _Matcap4MaskGlobalMask;
			float _Matcap4MaskGlobalMaskBlendType;
			float _Matcap4Border;
			float _Matcap4Rotation;
			float _Matcap4SmoothnessEnabled;
			float _Matcap4Smoothness;
			float _Matcap4MaskSmoothnessChannel;
			float _Matcap4MaskSmoothnessApply;
			float4 _Matcap4Color;
			float _Matcap4BaseColorMix;
			float _Matcap4ColorThemeIndex;
			float _Matcap4Intensity;
			float _Matcap4Replace;
			float _Matcap4Multiply;
			float _Matcap4Add;
			float _Matcap4AddToLight;
			float _Matcap4Mixed;
			float _Matcap4Screen;
			float _Matcap4AlphaOverride;
			float _Matcap4Enable;
			float _Matcap4LightMask;
			float _Matcap4EmissionStrength;
			float _Matcap4Normal;
			float _Matcap4HueShiftEnabled;
			float _Matcap4HueShiftSpeed;
			float _Matcap4HueShift;
			int _Matcap4ApplyToAlphaEnabled;
			int _Matcap4ApplyToAlphaSourceBlend;
			int _Matcap4ApplyToAlphaBlendType;
			float _Matcap4ApplyToAlphaBlending;
			float _Matcap4TPSDepthEnabled;
			float _Matcap4TPSMaskStrength;
			
			float _Matcap3ALEnabled;
			float _Matcap3ALAlphaAddBand;
			float4 _Matcap3ALAlphaAdd;
			float _Matcap3ALEmissionAddBand;
			float4 _Matcap3ALEmissionAdd;
			float _Matcap3ALIntensityAddBand;
			float4 _Matcap3ALIntensityAdd;
			float _Matcap3ALChronoPanType;
			float _Matcap3ALChronoPanBand;
			float _Matcap3ALChronoPanSpeed;
			#endif
			//endex
			struct MatcapAudioLinkData
			{
				float matcapALEnabled;
				float matcapALAlphaAddBand;
				float4 matcapALAlphaAdd;
				float matcapALEmissionAddBand;
				float4 matcapALEmissionAdd;
				float matcapALIntensityAddBand;
				float4 matcapALIntensityAdd;
				float matcapALChronoPanType;
				float matcapALChronoPanBand;
				float matcapALChronoPanSpeed;
			};
			
			//ifex _CubeMapEnabled==0
			#ifdef _CUBEMAP
			#if defined(PROP_CUBEMAP) || !defined(OPTIMIZER_ENABLED)
			samplerCUBE _CubeMap;
			float3 _CubeMapRotation;
			float3 _CubeMapRotationPan;
			#endif
			#if defined(PROP_CUBEMAPMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _CubeMapMask;
			float4 _CubeMapMask_ST;
			float2 _CubeMapMaskPan;
			float _CubeMapMaskUV;
			float _CubeMapMaskChannel;
			#endif
			float _CubeMapUVMode;
			float _CubeMapWorldNormalsStrength;
			float _CubeMapMaskInvert;
			float _CubeMapMaskGlobalMask;
			float _CubeMapMaskGlobalMaskBlendType;
			float4 _CubeMapColor;
			float _CubeMapColorThemeIndex;
			float _CubeMapIntensity;
			float _CubemapBlendType;
			float _CubeMapBlendAmount;
			float _CubeMapEnable;
			float _CubeMapLightMask;
			float _CubeMapEmissionStrength;
			float _CubeMapNormal;
			float _CubeMapHueShiftEnabled;
			float _CubeMapHueShiftSpeed;
			float _CubeMapHueShift;
			float _CubeMapSaturation;
			float _CubeMapBrightness;
			float _CubeMapContrast;
			float _CubeMapSmoothness;
			#endif
			//endex
			
			//ifex _EnableALDecal==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_DECAL
			float _ALDecalUV;
			float4 _ALUVScale;
			float2 _ALUVPosition;
			float _ALUVRotation;
			float _ALUVRotationSpeed;
			float4 _ALDecaldCircleDimensions;
			
			float _ALDecalUVMode;
			
			float _ALDecalVolumeStep;
			float _ALDecalVolumeClipMin;
			float _ALDecalVolumeClipMax;
			
			float _ALDecalBandStep;
			float _ALDecalBandClipMin;
			float _ALDecalBandClipMax;
			
			float _ALDecalShapeClip;
			float _ALDecalShapeClipVolumeWidth;
			float _ALDecalShapeClipBandWidth;
			
			#if defined(PROP_ALDECALCOLORMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ALDecalColorMask;
			float4 _ALDecalColorMask_ST;
			float2 _ALDecalColorMaskPan;
			float _ALDecalColorMaskUV;
			#endif
			
			float _ALDecalVolume;
			float _ALDecalBaseBoost;
			float _ALDecalTrebleBoost;
			float _ALDecalLineWidth;
			float _ALDecalVolumeColorSource;
			float3 _ALDecalVolumeColorLow;
			float _ALDecalVolumeColorLowThemeIndex;
			float3 _ALDecalVolumeColorMid;
			float _ALDecalVolumeColorMidThemeIndex;
			float3 _ALDecalVolumeColorHigh;
			float _ALDecalVolumeColorHighThemeIndex;
			float _ALDecalLowEmission;
			float _ALDecalMidEmission;
			float _ALDecalHighEmission;
			float _ALDecalBlendType;
			float _ALDecalBlendAlpha;
			float _ALDecalControlsAlpha;
			float _ALDecalGlobalMask;
			float _ALDecalGlobalMaskBlendType;
			#endif
			#endif
			//endex
			
			//ifex _EnableVolumeColor==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_VOLUMECOLOR
			float _ALVolumeColorUV;
			float _ALVolumeColorDirection;
			float _ALVolumeColorBlendType;
			float _ALVolumeColorBlendAlpha;
			float3 _ALVolumeColorLow;
			float _ALVolumeColorLowThemeIndex;
			float3 _ALVolumeColorMid;
			float _ALVolumeColorMidThemeIndex;
			float3 _ALVolumeColorHigh;
			float _ALVolumeColorHighThemeIndex;
			float _ALLowEmission;
			float _ALMidEmission;
			float _ALHighEmission;
			#endif
			#endif
			//endex
			
			//ifex _EnableFlipbook==0
			#ifdef _SUNDISK_HIGH_QUALITY
			
			UNITY_DECLARE_TEX2DARRAY(_FlipbookTexArray);
			float4 _FlipbookTexArray_ST;
			
			float4 _FlipbookColor;
			float _FlipbookColorThemeIndex;
			float _FlipbookFPS;
			// float _FlipbookTotalFrames;
			float4 _FlipbookScaleOffset;
			float4 _FlipbookSideOffset;
			float _FlipbookTiled;
			float _FlipbookManualFrameControl;
			float _FlipbookCurrentFrame;
			float _FlipbookStartAndEnd;
			float _FlipbookStartFrame;
			float _FlipbookEndFrame;
			float _FlipbookEmissionStrength;
			float _FlipbookRotation;
			float _EnableFlipbook;
			float _FlipbookTexArrayUV;
			float _FlipbookAlphaControlsFinalAlpha;
			float _FlipbookRotationSpeed;
			float _FlipbookIntensityControlsAlpha;
			float _FlipbookColorReplaces;
			float2 _FlipbookTexArrayPan;
			float _FlipbookFrameOffset;
			// blending
			float _FlipbookReplace;
			float _FlipbookMultiply;
			float _FlipbookAdd;
			float _FlipbookBlendType;
			
			#if defined(PROP_FLIPBOOKMASSK) || !defined(OPTIMIZED_ENABLED)
			Texture2D _FlipbookMask;
			#endif
			float4 _FlipbookMask_ST;
			float2 _FlipbookMaskPan;
			float _FlipbookMaskUV;
			float _FlipbookMaskChannel;
			float _FlipbookMaskGlobalMask;
			float _FlipbookMaskGlobalMaskBlendType;
			
			// anim
			float _FlipbookMovementType;
			float4 _FlipbookStartEndOffset;
			float _FlipbookMovementSpeed;
			
			// Crossfade
			float _FlipbookCrossfadeEnabled;
			float2 _FlipbookCrossfadeRange;
			
			// Hueshift
			float _FlipbookHueShiftEnabled;
			float _FlipbookHueShiftSpeed;
			float _FlipbookHueShift;
			
			#ifdef POI_AUDIOLINK
			float _FlipbookChronotensityEnabled;
			float _FlipbookChronotensityBand;
			float _FlipbookChronotensitySpeed;
			float _FlipbookChronoType;
			half _AudioLinkFlipbookScaleBand;
			half4 _AudioLinkFlipbookScale;
			half _AudioLinkFlipbookAlphaBand;
			half2 _AudioLinkFlipbookAlpha;
			half _AudioLinkFlipbookEmissionBand;
			half2 _AudioLinkFlipbookEmission;
			half _AudioLinkFlipbookFrameBand;
			half2 _AudioLinkFlipbookFrame;
			#endif
			#endif
			//endex
			
			//ifex _EnableRimLighting==0
			#ifdef _GLOSSYREFLECTIONS_OFF
			float _Is_NormalMapToRimLight;
			float4 _RimLightColor;
			float _RimLightColorThemeIndex;
			#ifdef _RIMSTYLE_POIYOMI
			float _RimLightingInvert;
			float _RimWidth;
			float _RimStrength;
			float _RimSharpness;
			float _RimBaseColorMix;
			float _EnableRimLighting;
			float _RimWidthNoiseStrength;
			float4 _RimShadowAlpha;
			float _RimShadowWidth;
			float _RimBlendStrength;
			float _RimPoiBlendMode;
			float _RimShadowToggle;
			float _RimPower;
			float _RimShadowMaskStrength;
			float _RimShadowMaskRampType;
			float _RimShadowMaskInvert;
			float _RimBrightness;
			#if defined(PROP_RIMTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RimTex;
			#endif
			float4 _RimTex_ST;
			float2 _RimTexPan;
			float _RimTexUV;
			#if defined(PROP_RIMMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RimMask;
			#endif
			float4 _RimMask_ST;
			float2 _RimMaskPan;
			float _RimMaskUV;
			float _RimMaskChannel;
			float _RimMaskInvert;
			float _RimBiasIntensity;
			int _RimApplyAlpha;
			float _RimApplyAlphaBlend;
			#ifdef POI_AUDIOLINK
			half _AudioLinkRimWidthBand;
			float2 _AudioLinkRimWidthAdd;
			half _AudioLinkRimEmissionBand;
			float2 _AudioLinkRimEmissionAdd;
			half _AudioLinkRimBrightnessBand;
			float2 _AudioLinkRimBrightnessAdd;
			#endif
			#endif
			
			#ifdef _RIMSTYLE_UTS2
			float _RimLight;
			float _Is_LightColor_RimLight;
			float _RimLight_Power;
			float _RimLight_InsideMask;
			float _RimLight_FeatherOff;
			float _LightDirection_MaskOn;
			float _Tweak_LightDirection_MaskLevel;
			float _Add_Antipodean_RimLight;
			float4 _Ap_RimLightColor;
			float _RimApColorThemeIndex;
			float _Is_LightColor_Ap_RimLight;
			float _Ap_RimLight_Power;
			float _Ap_RimLight_FeatherOff;
			#if defined(PROP_SET_RIMLIGHTMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Set_RimLightMask;
			float4 _Set_RimLightMask_ST;
			float2 _Set_RimLightMaskPan;
			float _Set_RimLightMaskUV;
			float _Set_RimLightMaskChannel;
			#endif
			float _Tweak_RimLightMaskLevel;
			#endif
			
			#ifdef _RIMSTYLE_LILTOON
			float4 _RimColor;
			#if defined(PROP_RIMCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RimColorTex;
			float4 _RimColorTex_ST;
			float2 _RimColorTexPan;
			float _RimColorTexUV;
			#endif
			float _RimMainStrength;
			float _RimNormalStrength;
			float _RimBorder;
			float _RimBlur;
			float _RimFresnelPower;
			float _RimEnableLighting;
			float _RimShadowMask;
			int _RimBackfaceMask;
			float _RimVRParallaxStrength;
			float _RimDirStrength;
			float _RimDirRange;
			float _RimIndirRange;
			float4 _RimIndirColor;
			float _RimIndirBorder;
			float _RimIndirBlur;
			int _RimBlendMode;
			#endif
			
			float _RimGlobalMask;
			float _RimGlobalMaskBlendType;
			float _RimApplyGlobalMaskIndex;
			float _RimApplyGlobalMaskBlendType;
			
			float _RimHueShiftEnabled;
			float _RimHueShiftSpeed;
			float _RimHueShift;
			#endif
			//endex
			//ifex _EnableRim2Lighting==0
			#ifdef POI_RIM2
			float _Is_NormalMapToRim2Light;
			float4 _Rim2LightColor;
			float _Rim2LightColorThemeIndex;
			
			#ifdef _RIM2STYLE_POIYOMI
			float _Rim2LightingInvert;
			float _Rim2Width;
			float _Rim2Strength;
			float _Rim2Sharpness;
			float _Rim2BaseColorMix;
			float _EnableRim2Lighting;
			float _Rim2WidthNoiseStrength;
			float4 _Rim2ShadowAlpha;
			float _Rim2ShadowWidth;
			float _Rim2BlendStrength;
			float _RimPoi2BlendMode;
			float _Rim2ShadowToggle;
			float _Rim2Power;
			float _Rim2ShadowMaskStrength;
			float _Rim2ShadowMaskRampType;
			float _Rim2ShadowMaskInvert;
			float _Rim2Brightness;
			#if defined(PROP_RIM2TEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Rim2Tex;
			#endif
			float4 _Rim2Tex_ST;
			float2 _Rim2TexPan;
			float _Rim2TexUV;
			#if defined(PROP_RIM2MASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Rim2Mask;
			#endif
			float4 _Rim2Mask_ST;
			float2 _Rim2MaskPan;
			float _Rim2MaskUV;
			float _Rim2MaskChannel;
			float _Rim2MaskInvert;
			float _Rim2BiasIntensity;
			int _Rim2ApplyAlpha;
			float _Rim2ApplyAlphaBlend;
			#if defined(PROP_RIM2WIDTHNOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Rim2WidthNoiseTexture;
			#endif
			#ifdef POI_AUDIOLINK
			half _AudioLinkRim2WidthBand;
			float2 _AudioLinkRim2WidthAdd;
			half _AudioLinkRim2EmissionBand;
			float2 _AudioLinkRim2EmissionAdd;
			half _AudioLinkRim2BrightnessBand;
			float2 _AudioLinkRim2BrightnessAdd;
			#endif
			#endif
			
			#ifdef _RIM2STYLE_UTS2
			float _Rim2Light;
			float _Is_LightColor_Rim2Light;
			float _Rim2Light_Power;
			float _Rim2Light_InsideMask;
			float _Rim2Light_FeatherOff;
			float _LightDirection_MaskOn2;
			float _Tweak_LightDirection_MaskLevel2;
			float _Add_Antipodean_Rim2Light;
			float4 _Ap_Rim2LightColor;
			float _Rim2ApColorThemeIndex;
			float _Is_LightColor_Ap_Rim2Light;
			float _Ap_Rim2Light_Power;
			float _Ap_Rim2Light_FeatherOff;
			#if defined(PROP_SET_RIM2LIGHTMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Set_Rim2LightMask;
			float4 _Set_Rim2LightMask_ST;
			float2 _Set_Rim2LightMaskPan;
			float _Set_Rim2LightMaskUV;
			float _Set_Rim2LightMaskChannel;
			#endif
			float _Tweak_Rim2LightMaskLevel;
			#endif
			
			#ifdef _RIM2STYLE_LILTOON
			float4 _Rim2Color;
			#if defined(PROP_RIM2COLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Rim2ColorTex;
			float4 _Rim2ColorTex_ST;
			float2 _Rim2ColorTexPan;
			float _Rim2ColorTexUV;
			#endif
			float _Rim2MainStrength;
			float _Rim2NormalStrength;
			float _Rim2Border;
			float _Rim2Blur;
			float _Rim2FresnelPower;
			float _Rim2EnableLighting;
			float _Rim2ShadowMask;
			int _Rim2BackfaceMask;
			float _Rim2VRParallaxStrength;
			// int _Rim2ApplyTransparency;
			float _Rim2DirStrength;
			float _Rim2DirRange;
			float _Rim2IndirRange;
			float4 _Rim2IndirColor;
			float _Rim2IndirBorder;
			float _Rim2IndirBlur;
			int _Rim2BlendMode;
			#endif
			
			float _Rim2GlobalMask;
			float _Rim2GlobalMaskBlendType;
			float _Rim2ApplyGlobalMaskIndex;
			float _Rim2ApplyGlobalMaskBlendType;
			
			float _Rim2HueShiftEnabled;
			float _Rim2HueShiftSpeed;
			float _Rim2HueShift;
			#endif
			//endex
			
			//ifex _EnableDepthRimLighting==0
			#ifdef _POI_DEPTH_RIMLIGHT
			float _DepthRimNormalToUse;
			float _DepthRimWidth;
			float _DepthRimSharpness;
			float _DepthRimHideInShadow;
			float4 _DepthRimColor;
			float _DepthRimColorThemeIndex;
			float _DepthRimMixBaseColor;
			float _DepthRimEmission;
			float _DepthRimReplace;
			float _DepthRimAdd;
			float _DepthRimMultiply;
			float _DepthRimAdditiveLighting;
			float _DepthRimMixLightColor;
			float _DepthRimType;
			float _DepthRimBrightness;
			
			static float2 sobelSamplePoints[9] = {
				float2(-1, 1), float2(0, 1), float2(1, 1),
				float2(-1, 0), float2(0, 0), float2(1, 01),
				float2(-1, -1), float2(0, -1), float2(1, -1)
			};
			
			static float sobelXMatrix[9] = {
				1, 0, -1,
				2, 0, -2,
				1, 0, -1
			};
			static float sobelYMatrix[9] = {
				1, 2, 1,
				0, 0, 0,
				- 1, -2, -1
			};
			#endif
			//endex
			
			//ifex _GlitterEnable==0
			#ifdef _SUNDISK_SIMPLE
			float4 _GlitterRandomRotationSpeed;
			float _GlitterLayers;
			float _GlitterUseNormals;
			float _GlitterUV;
			float4 _GlitterColor;
			float _GlitterColorThemeIndex;
			float2 _GlitterPan;
			half _GlitterSpeed;
			half _GlitterBrightness;
			float _GlitterFrequency;
			float _GlitterRandomLocation;
			half _GlitterSize;
			half _GlitterContrast;
			half _GlitterAngleRange;
			half _GlitterMinBrightness;
			half _GlitterBias;
			fixed _GlitterUseSurfaceColor;
			float _GlitterBlendType;
			float _GlitterMode;
			float _GlitterShape;
			float _GlitterCenterSize;
			float _GlitterJaggyFix;
			float _GlitterTextureRotation;
			float2 _GlitterUVPanning;
			
			float _GlitterHueShiftEnabled;
			float _GlitterHueShiftSpeed;
			float _GlitterHueShift;
			float _GlitterHideInShadow;
			float _GlitterScaleWithLighting;
			
			float _GlitterRandomColors;
			float2 _GlitterMinMaxSaturation;
			float2 _GlitterMinMaxBrightness;
			float _GlitterRandomSize;
			float4 _GlitterMinMaxSize;
			float _GlitterRandomRotation;
			
			#if defined(PROP_GLITTERMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlitterMask;
			#endif
			float4 _GlitterMask_ST;
			float2 _GlitterMaskPan;
			float _GlitterMaskUV;
			float _GlitterMaskChannel;
			float _GlitterMaskInvert;
			float _GlitterMaskGlobalMask;
			float _GlitterMaskGlobalMaskBlendType;
			#if defined(PROP_GLITTERCOLORMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlitterColorMap;
			#endif
			float4 _GlitterColorMap_ST;
			float2 _GlitterColorMapPan;
			float _GlitterColorMapUV;
			#if defined(PROP_GLITTERTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlitterTexture;
			#endif
			float4 _GlitterTexture_ST;
			float2 _GlitterTexturePan;
			float _GlitterTextureUV;
			
			float _GlitterALEnabled;
			float _GlitterALAlphaAddBand;
			float4 _GlitterALAlphaAdd;
			float _GlitterALMinBrightnessBand;
			float4 _GlitterALMinBrightnessAdd;
			float _GlitterALMaxBrightnessBand;
			float4 _GlitterALMaxBrightnessAdd;
			float _GlitterALSizeAddBand;
			float4 _GlitterALSizeAdd;
			float _GlitterALChronoSparkleSpeedType;
			float _GlitterALChronoSparkleSpeedBand;
			float _GlitterALChronoSparkleSpeed;
			float _GlitterALChronoRotationSpeedType;
			float _GlitterALChronoRotationSpeedBand;
			float _GlitterALChronoRotationSpeed;
			#endif
			//endex
			
			//ifex _SubsurfaceScattering==0
			#ifdef POI_SUBSURFACESCATTERING
			float4 _SSSColor;
			#if defined(PROP_SSSTHICKNESSMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _SSSThicknessMap;
			#endif
			float4 _SSSThicknessMap_ST;
			float2 _SSSThicknessMapPan;
			float _SSSThicknessMapUV;
			float _SSSThicknessMapChannel;
			
			float _SSSThicknessMod;
			float _SSSStrength;
			float _SSSSpread;
			float _SSSDistortion;
			float _SSSBaseColorMix;
			#endif
			//endex
			
			//ifex _MochieBRDF==0
			#ifdef MOCHIE_PBR
			#if defined(PROP_MOCHIEMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MochieMetallicMaps;
			float _PBRMapsStochastic;
			#endif
			float4 _MochieMetallicMaps_ST;
			float2 _MochieMetallicMapsPan;
			float _MochieMetallicMapsUV;
			float _MochieMetallicMapsStochastic;
			float _MochieMetallicMapInvert;
			float _MochieRoughnessMapInvert;
			float _MochieReflectionMaskInvert;
			float _MochieSpecularMaskInvert;
			float _MochieMetallicMapsMetallicChannel;
			float _MochieMetallicMapsRoughnessChannel;
			float _MochieMetallicMapsReflectionMaskChannel;
			float _MochieMetallicMapsSpecularMaskChannel;
			float _PBRNormalSelect;
			
			float _MochieReflectionTintThemeIndex;
			float _MochieSpecularTintThemeIndex;
			
			float _MochieRoughnessMultiplier;
			float _MochieMetallicMultiplier;
			float _MochieReflectionStrength;
			float _MochieSpecularStrength;
			float4 _MochieSpecularTint;
			float4 _MochieReflectionTint;
			float _MochieLitFallback;
			float _IgnoreCastedShadows;
			float _PBRSplitMaskSample;
			float _PBRSplitMaskStochastic;
			float4 _PBRMaskScaleTiling;
			float _MochieMetallicMasksUV;
			float4 _MochieMetallicMasksPan;
			
			float _Specular2ndLayer;
			float _MochieSpecularStrength2;
			float _MochieRoughnessMultiplier2;
			float _RefSpecFresnel;
			float _RefSpecFresnelBack;
			samplerCUBE _MochieReflCube;
			float4 _MochieReflCube_HDR;
			float _MochieForceFallback;
			float _MochieGSAAEnabled;
			float _PoiGSAAVariance;
			float _PoiGSAAThreshold;
			float _BRDFTPSReflectionMaskStrength;
			float _BRDFTPSSpecularMaskStrength;
			float _BRDFTPSDepthEnabled;
			
			float _MochieMetallicGlobalMask;
			float _MochieMetallicGlobalMaskBlendType;
			float _MochieSmoothnessGlobalMask;
			float _MochieSmoothnessGlobalMaskBlendType;
			float _MochieReflectionStrengthGlobalMask;
			float _MochieReflectionStrengthGlobalMaskBlendType;
			float _MochieSpecularStrengthGlobalMask;
			float _MochieSpecularStrengthGlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _ClearCoatBRDF==0
			#ifdef POI_CLEARCOAT
			#if defined(PROP_CLEARCOATMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ClearCoatMaps;
			float4 _ClearCoatMaps_ST;
			float2 _ClearCoatMapsPan;
			float _ClearCoatMapsUV;
			float _ClearCoatMapsStochastic;
			#endif
			float _ClearCoatMapsClearCoatMaskChannel;
			float _ClearCoatMapsRoughnessChannel;
			float _ClearCoatMapsReflectionMaskChannel;
			float _ClearCoatMapsSpecularMaskChannel;
			float _ClearCoatBRDF;
			float _ClearCoatReflectionStrength;
			float _ClearCoatSpecularStrength;
			float _ClearCoatStrength;
			float _ClearCoatSmoothness;
			float4 _ClearCoatReflectionTint;
			float _ClearCoatReflectionTintThemeIndex;
			float4 _ClearCoatSpecularTint;
			float _ClearCoatSpecularTintThemeIndex;
			float _ClearCoatSmoothnessMapInvert;
			float _ClearCoatMaskInvert;
			float _ClearCoatReflectionMaskInvert;
			float _ClearCoatSpecularMaskInvert;
			float _ClearCoatTPSMaskStrength;
			float _ClearCoatTPSDepthMaskEnabled;
			float _ClearCoatNormalSelect;
			
			samplerCUBE _ClearCoatFallback;
			float4 _ClearCoatFallback_HDR;
			float _ClearCoatForceFallback;
			float _ClearCoatLitFallback;
			float _CCIgnoreCastedShadows;
			float _ClearCoatGSAAEnabled;
			float _ClearCoatGSAAVariance;
			float _ClearCoatGSAAThreshold;
			float _ClearcoatFresnel;
			
			float _ClearCoatGlobalMask;
			float _ClearCoatGlobalMaskBlendType;
			float _ClearCoatSmoothnessGlobalMask;
			float _ClearCoatSmoothnessGlobalMaskBlendType;
			float _ClearCoatReflectionStrengthGlobalMask;
			float _ClearCoatReflectionStrengthGlobalMaskBlendType;
			float _ClearCoatSpecularStrengthGlobalMask;
			float _ClearCoatSpecularStrengthGlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _StylizedSpecular==0
			#ifdef POI_STYLIZED_StylizedSpecular
			#if defined(PROP_HIGHCOLOR_TEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _HighColor_Tex;
			#endif
			float4 _HighColor_Tex_ST;
			float2 _HighColor_TexPan;
			float _HighColor_TexUV;
			
			#if defined(PROP_SET_HIGHCOLORMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Set_HighColorMask;
			#endif
			float4 _Set_HighColorMask_ST;
			float2 _Set_HighColorMaskPan;
			float _Set_HighColorMaskUV;
			float _Set_HighColorMaskChannel;
			float _Tweak_HighColorMaskLevel;
			
			/*
			#if defined(PROP_StylizedSpecularOPTMAP1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _StylizedSpecularOptMap1;
			#endif
			float4 _StylizedSpecularOptMap1_ST;
			float2 _StylizedSpecularOptMap1Pan;
			float _StylizedSpecularOptMap1UV;
			
			#if defined(PROP_StylizedSpecularOPTMAP2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _StylizedSpecularOptMap2;
			#endif
			float4 _StylizedSpecularOptMap2_ST;
			float2 _StylizedSpecularOptMap2Pan;
			float _StylizedSpecularOptMap2UV;
			*/
			
			float4 _HighColor;
			float _UseLightColor;
			
			float _HighColor_Power;
			float _StylizedSpecularFeather;
			float _Layer1Strength;
			
			float _StylizedSpecularIgnoreNormal;
			float _StylizedSpecularIgnoreShadow;
			
			float _Layer2Size;
			float _StylizedSpecular2Feather;
			float _Layer2Strength;
			float _SSIgnoreCastedShadows;
			float _StylizedSpecularStrength;
			float _UseSpecularOptMap2;
			float _HighColorThemeIndex;
			float _Is_BlendAddToHiColor;
			float _Is_SpecularToHighColor;
			#endif
			//endex
			
			//ifex _EnablePathing==0
			#ifdef POI_PATHING
			
			#if defined(PROP_PATHINGMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _PathingMap;
			SamplerState SmpRepeatPoint;
			#endif
			float4 _PathingMap_ST;
			float2 _PathingMapPan;
			float _PathingMapUV;
			
			#if defined(PROP_PATHINGCOLORMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _PathingColorMap;
			#endif
			float4 _PathingColorMap_ST;
			float2 _PathingColorMapPan;
			float _PathingColorMapUV;
			float _PathingOverrideAlpha;
			// Fill, 0, Path, 1, Loop, 2
			float _PathTypeR;
			float _PathTypeG;
			float _PathTypeB;
			float _PathTypeA;
			float _PathGradientType;
			half4 _PathWidth;
			float4 _PathTime;
			float4 _PathOffset;
			float4 _PathSpeed;
			float4 _PathColorR;
			float4 _PathColorG;
			float4 _PathColorB;
			float4 _PathColorA;
			float4 _PathEmissionStrength;
			float4 _PathSoftness;
			float4 _PathSegments;
			
			float _PathColorRThemeIndex;
			float _PathColorGThemeIndex;
			float _PathColorBThemeIndex;
			float _PathColorAThemeIndex;
			
			#ifdef POI_AUDIOLINK
			float _PathALAutoCorrelator;
			float _PathALAutoCorrelatorMode;
			float _PathALAutoCorrelatorR;
			float2 _PathALAutoCorrelatorRangeR;
			float _PathALAutoCorrelatorG;
			float2 _PathALAutoCorrelatorRangeG;
			float _PathALAutoCorrelatorB;
			float2 _PathALAutoCorrelatorRangeB;
			float _PathALAutoCorrelatorA;
			float2 _PathALAutoCorrelatorRangeA;
			
			float _PathALHistory;
			float _PathALHistoryMode;
			float _PathALHistoryBandR;
			float2 _PathALHistoryRangeR;
			float _PathALHistoryR;
			float _PathALHistoryBandG;
			float2 _PathALHistoryRangeG;
			float _PathALHistoryG;
			float _PathALHistoryBandB;
			float2 _PathALHistoryRangeB;
			float _PathALHistoryB;
			float _PathALHistoryBandA;
			float2 _PathALHistoryRangeA;
			float _PathALHistoryA;
			
			float _PathALColorChord;
			float _PathALCCR;
			float _PathALCCG;
			float _PathALCCB;
			float _PathALCCA;
			
			// Time Offset
			float _PathALTimeOffset;
			half _AudioLinkPathTimeOffsetBandR;
			half2 _AudioLinkPathTimeOffsetR;
			half _AudioLinkPathTimeOffsetBandG;
			half2 _AudioLinkPathTimeOffsetG;
			half _AudioLinkPathTimeOffsetBandB;
			half2 _AudioLinkPathTimeOffsetB;
			half _AudioLinkPathTimeOffsetBandA;
			half2 _AudioLinkPathTimeOffsetA;
			
			// Emission Offset
			float _PathALEmissionOffset;
			half _AudioLinkPathEmissionAddBandR;
			half2 _AudioLinkPathEmissionAddR;
			half _AudioLinkPathEmissionAddBandG;
			half2 _AudioLinkPathEmissionAddG;
			half _AudioLinkPathEmissionAddBandB;
			half2 _AudioLinkPathEmissionAddB;
			half _AudioLinkPathEmissionAddBandA;
			half2 _AudioLinkPathEmissionAddA;
			
			// Length Offset
			float _PathALWidthOffset;
			half _AudioLinkPathWidthOffsetBandR;
			half2 _AudioLinkPathWidthOffsetR;
			half _AudioLinkPathWidthOffsetBandG;
			half2 _AudioLinkPathWidthOffsetG;
			half _AudioLinkPathWidthOffsetBandB;
			half2 _AudioLinkPathWidthOffsetB;
			half _AudioLinkPathWidthOffsetBandA;
			half2 _AudioLinkPathWidthOffsetA;
			
			// Chrono Time
			float _PathALChrono;
			float _PathChronoBandR;
			float _PathChronoTypeR;
			float _PathChronoSpeedR;
			float _PathChronoBandG;
			float _PathChronoTypeG;
			float _PathChronoSpeedG;
			float _PathChronoBandB;
			float _PathChronoTypeB;
			float _PathChronoSpeedB;
			float _PathChronoBandA;
			float _PathChronoTypeA;
			float _PathChronoSpeedA;
			#endif
			#endif
			//endex
			
			//ifex _EnableMirrorOptions==0
			#ifdef POI_MIRROR
			float _VisibilityMode;
			float _Mirror;
			#if defined(PROP_MIRRORTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MirrorTexture;
			#endif
			float4 _MirrorColor;
			float _MirrorColorThemeIndex;
			float _MirrorTextureBlendType;
			float4 _MirrorTexture_ST;
			float2 _MirrorTexturePan;
			float _MirrorTextureUV;
			float _MirrorTextureEnabled;
			float _MirrorTextureForceEnabled;
			float _VisibilityVRCRegular;
			float _VisibilityVRCMirrorVR;
			float _VisibilityVRCMirrorDesktop;
			float _VisibilityVRCCameraVR;
			float _VisibilityVRCCameraDesktop;
			float _VisibilityVRCCameraScreenshot;
			#endif
			//endex
			
			//ifex _EnableTouchGlow==0
			#ifdef GRAIN
			#if defined(PROP_DEPTHMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DepthMask;
			#endif
			float4 _DepthMask_ST;
			float2 _DepthMaskPan;
			float _DepthMaskUV;
			float _DepthMaskChannel;
			float _DepthMaskGlobalMask;
			float _DepthMaskGlobalMaskBlendType;
			
			// Color
			float _DepthColorToggle;
			float _DepthColorBlendMode;
			#if defined(PROP_DEPTHTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DepthTexture;
			#endif
			float4 _DepthTexture_ST;
			float2 _DepthTexturePan;
			float _DepthTextureUV;
			
			float3 _DepthColor;
			float _DepthColorThemeIndex;
			float _DepthColorMinDepth;
			float _DepthColorMaxDepth;
			float _DepthColorMinValue;
			float _DepthColorMaxValue;
			float _DepthEmissionStrength;
			
			// Emission
			
			// Alpha
			float _DepthAlphaToggle;
			float _DepthAlphaMinValue;
			float _DepthAlphaMaxValue;
			float _DepthAlphaMinDepth;
			float _DepthAlphaMaxDepth;
			#endif
			//endex
			
			//ifex _TextEnabled==0
			#ifdef EFFECT_BUMP
			sampler2D _TextGlyphs;
			float4 _TextGlyphs_ST;
			float4 _TextGlyphs_TexelSize;
			float _TextFPSUV;
			float _TextTimeUV;
			float _TextPositionUV;
			float _TextNumericUV;
			float _TextPixelRange;
			
			float _TextFPSEnabled;
			float _TextPositionEnabled;
			float _TextTimeEnabled;
			float _TextNumericEnabled;
			
			float4 _TextFPSColor;
			float _TextFPSEmissionStrength;
			fixed4 _TextFPSPadding;
			float2 _TextFPSOffset;
			float2 _TextFPSScale;
			float _TextFPSRotation;
			float _TextFPSOutlineColor;
			
			fixed _TextPositionVertical;
			float4 _TextPositionColor;
			float _TextPositionEmissionStrength;
			fixed4 _TextPositionPadding;
			float2 _TextPositionOffset;
			float2 _TextPositionScale;
			float _TextPositionRotation;
			
			float4 _TextTimeColor;
			float _TextTimeEmissionStrength;
			fixed4 _TextTimePadding;
			float2 _TextTimeOffset;
			float2 _TextTimeScale;
			float _TextTimeRotation;
			
			float4 _TextNumericColor;
			float _TextNumericEmissionStrength;
			fixed4 _TextNumericPadding;
			float2 _TextNumericOffset;
			float2 _TextNumericScale;
			float _TextNumericRotation;
			float _TextNumericValue;
			float _TextNumericWholeDigits;
			float _TextNumericDecimalDigits;
			float _TextNumericTrimZeroes;
			
			float _TextFPSColorThemeIndex;
			float _TextPositionColorThemeIndex;
			float _TextTimeColorThemeIndex;
			float _TextNumericColorThemeIndex;
			
			float3 globalTextEmission;
			
			#define ASCII_SPACE 32
			#define ASCII_LEFT_PARENTHESIS 40
			#define ASCII_RIGHT_PARENTHESIS 41
			#define ASCII_POSITIVE 43
			#define ASCII_PERIOD 46
			#define ASCII_NEGATIVE 45
			#define ASCII_COMMA 44
			#define ASCII_E 69
			#define ASCII_F 70
			#define ASCII_I 73
			#define ASCII_M 77
			#define ASCII_O 79
			#define ASCII_P 80
			#define ASCII_R 82
			#define ASCII_S 83
			#define ASCII_T 84
			#define ASCII_SEMICOLON 58
			#define glyphWidth 0.0625
			
			#endif
			//endex
			
			//ifex _FXProximityColor==0
			float _FXProximityColor;
			float _FXProximityColorType;
			float3 _FXProximityColorMinColor;
			float3 _FXProximityColorMaxColor;
			float _FXProximityColorMinColorThemeIndex;
			float _FXProximityColorMaxColorThemeIndex;
			float _FXProximityColorMinDistance;
			float _FXProximityColorMaxDistance;
			float _FXProximityColorBackFace;
			//endex
			
			//ifex _PostProcess==0
			#ifdef POSTPROCESS
			#if defined(PROP_PPMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _PPMask;
			#endif
			float4 _PPMask_ST;
			float2 _PPMaskPan;
			float _PPMaskUV;
			float _PPMaskChannel;
			float _PPMaskInvert;
			
			float3 _PPTint;
			float3 _PPRGB;
			float _PPHue;
			float _PPContrast;
			float _PPSaturation;
			float _PPBrightness;
			float _PPLightness;
			float _PPHDR;
			
			float _PPPosterization;
			float _PPPosterizationAmount;
			const static float COLORS = 32;
			
			#endif
			//endex
			
			//ifex _NormalCorrect==0
			#ifdef POI_NORMALCORRECT
			float _NormalCorrectAmount;
			float3 _NormalCorrectOrigin;
			#endif
			//endex
			
			//ifex _VideoEffectsEnable==0
			#ifdef POI_VIDEO_EFFECTS
			float _VideoEffectsEnable;
			#if defined(PROP_VIDEOPIXELTEXTURE) || !defined(OPTIMIZER_ENABLED)
			sampler2D _VideoPixelTexture;
			float4 _VideoPixelTexture_ST;
			float _VideoPixelTextureUV;
			#endif
			#if defined(PROP_VIDEOMASKTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VideoMaskTexture;
			float4 _VideoMaskTexture_ST;
			float2 _VideoMaskTexturePan;
			float _VideoMaskTextureUV;
			float _VideoMaskTextureChannel;
			#endif
			
			float _VideoType;
			float2 _VideoResolution;
			sampler2D _VideoGameboyRamp;
			float _VideoBacklight;
			float _VideoCRTRefreshRate;
			float _VideoCRTPixelEnergizedTime;
			float _VideoRepeatVideoTexture;
			float _VideoPixelateToResolution;
			float2 _VideoMaskPanning;
			
			float _VideoSaturation;
			float _VideoContrast;
			float _VideoEmissionEnabled;
			#endif
			//endex
			
			//ifex _BacklightEnabled!=1
			#ifdef POI_BACKLIGHT
			float4 _BacklightColor;
			#if defined(PROP_BACKLIGHTCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BacklightColorTex;
			float4 _BacklightColorTex_ST;
			float2 _BacklightColorTexPan;
			float _BacklightColorTexUV;
			#endif
			float _BacklightMainStrength;
			float _BacklightNormalStrength;
			float _BacklightBorder;
			float _BacklightBlur;
			float _BacklightDirectivity;
			float _BacklightViewStrength;
			int _BacklightReceiveShadow;
			int _BacklightBackfaceMask;
			#endif
			//endex
			
			//ifex _BSSEnabled!=1
			#ifdef POIBS_ENABLE
			float _CustomColors;
			//ifex _BSSBloomfog!=1
			#ifdef POIBS_BLOOMFOG
			float _FogStartOffset;
			float _FogScale;
			float _FogHeightOffset;
			float _FogHeightScale;
			
			uniform float2 _CustomFogTextureToScreenRatio;
			uniform float _StereoCameraEyeOffset;
			
			uniform float _CustomFogOffset;
			uniform float _CustomFogAttenuation;
			uniform float _CustomFogHeightFogStartY;
			uniform float _CustomFogHeightFogHeight;
			uniform sampler2D _BloomPrePassTexture;
			#endif
			//endex
			#endif
			//endex
			
			//ifex _VoronoiEnabled!=1
			#ifdef POI_VORONOI
			#if defined(PROP_VORONOIMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VoronoiMask;
			float4 _VoronoiMask_ST;
			float2 _VoronoiMaskPan;
			float _VoronoiMaskUV;
			int _VoronoiMaskChannel;
			#endif
			#if defined(PROP_VORONOINOISE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VoronoiNoise;
			float4 _VoronoiNoise_ST;
			float2 _VoronoiNoisePan;
			float _VoronoiNoiseUV;
			int _VoronoiNoiseChannel;
			#endif
			int _VoronoiSpace;
			int _VoronoiBlend;
			int _VoronoiType;
			float4 _VoronoiOuterColor;
			float _VoronoiOuterEmissionStrength;
			float4 _VoronoiInnerColor;
			float _VoronoiInnerEmissionStrength;
			float _VoronoiPower;
			float2 _VoronoiGradient;
			float _VoronoiScale;
			float3 _VoronoiSpeed;
			float _VoronoiEnableRandomCellColor;
			float2 _VoronoiRandomMinMaxSaturation;
			float2 _VoronoiRandomMinMaxBrightness;
			float _VoronoiNoiseIntensity;
			int _VoronoiAffectsMaterialAlpha;
			float _VoronoiGlobalMask;
			float _VoronoiGlobalMaskBlendType;
			
			// AudioLink
			int _AudioLinkVoronoiInnerEmissionBand;
			float2 _AudioLinkVoronoiInnerEmission;
			int _AudioLinkVoronoiOuterEmissionBand;
			float2 _AudioLinkVoronoiOuterEmission;
			
			int _AudioLinkVoronoiGradientMinAddBand;
			float _AudioLinkVoronoiGradientMinAdd;
			int _AudioLinkVoronoiGradientMaxAddBand;
			float _AudioLinkVoronoiGradientMaxAdd;
			
			int _AudioLinkVoronoiChronoSpeedXType;
			int _AudioLinkVoronoiChronoSpeedXBand;
			float _AudioLinkVoronoiChronoSpeedXSpeed;
			int _AudioLinkVoronoiChronoSpeedYType;
			int _AudioLinkVoronoiChronoSpeedYBand;
			float _AudioLinkVoronoiChronoSpeedYSpeed;
			int _AudioLinkVoronoiChronoSpeedZType;
			int _AudioLinkVoronoiChronoSpeedZBand;
			float _AudioLinkVoronoiChronoSpeedZSpeed;
			#endif
			//endex
			
			struct appdata
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 tangent : TANGENT;
				float4 color : COLOR;
				float2 uv0 : TEXCOORD0;
				float2 uv1 : TEXCOORD1;
				float2 uv2 : TEXCOORD2;
				float2 uv3 : TEXCOORD3;
				uint vertexId : SV_VertexID;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};
			
			struct VertexOut
			{
				float4 pos : SV_POSITION;
				float4 uv[2] : TEXCOORD0;
				float3 normal : TEXCOORD2;
				float4 tangent : TEXCOORD3;
				float4 worldPos : TEXCOORD4;
				float4 localPos : TEXCOORD5;
				float4 vertexColor : TEXCOORD6;
				float4 lightmapUV : TEXCOORD7;
				float2 fogCoord: TEXCOORD10;
				UNITY_SHADOW_COORDS(11)
				
				UNITY_VERTEX_INPUT_INSTANCE_ID
				UNITY_VERTEX_OUTPUT_STEREO
			};
			
			struct PoiMesh
			{
				
				// 0 Vertex normal
				// 1 Fragment normal
				float3 normals[2];
				float3 objNormal;
				float3 tangentSpaceNormal;
				float3 binormal[2];
				float3 tangent[2];
				float3 worldPos;
				float3 localPos;
				float3 objectPosition;
				float isFrontFace;
				float4 vertexColor;
				float4 lightmapUV;
				// 0-3 UV0-UV3
				// 4 Panosphere UV
				// 5 world pos xz
				// 6 Polar UV
				// 7 Distorted UV
				float2 uv[9];
				float2 parallaxUV;
				float2 dx;
				float2 dy;
			};
			
			struct PoiCam
			{
				float3 viewDir;
				float3 forwardDir;
				float3 worldPos;
				float distanceToVert;
				float4 clipPos;
				float4 screenSpacePosition;
				float3 reflectionDir;
				float3 vertexReflectionDir;
				float3 tangentViewDir;
				float4 posScreenSpace;
				float2 posScreenPixels;
				float2 screenUV;
				float vDotN;
				float4 worldDirection;
				
			};
			
			struct PoiMods
			{
				float4 Mask;
				float audioLink[5];
				float audioLinkAvailable;
				float audioLinkVersion;
				float4 audioLinkTexture;
				float2 detailMask;
				float2 backFaceDetailIntensity;
				float globalEmission;
				float4 globalColorTheme[12];
				float globalMask[16];
				float ALTime[8];
			};
			
			struct PoiLight
			{
				
				float3 direction;
				float attenuation;
				float attenuationStrength;
				float3 directColor;
				float3 indirectColor;
				float occlusion;
				float shadowMask;
				float detailShadow;
				float3 halfDir;
				float lightMap;
				float lightMapNoAttenuation;
				float3 rampedLightMap;
				float vertexNDotL;
				float nDotL;
				float nDotV;
				float vertexNDotV;
				float nDotH;
				float vertexNDotH;
				float lDotv;
				float lDotH;
				float nDotLSaturated;
				float nDotLNormalized;
				#ifdef POI_PASS_ADD
				float additiveShadow;
				#endif
				float3 finalLighting;
				float3 finalLightAdd;
				float3 LTCGISpecular;
				float3 LTCGIDiffuse;
				float directLuminance;
				float indirectLuminance;
				float finalLuminance;
				
				#if defined(VERTEXLIGHT_ON)
				// Non Important Lights
				float4 vDotNL;
				float4 vertexVDotNL;
				float3 vColor[4];
				float4 vCorrectedDotNL;
				float4 vAttenuation;
				float4 vSaturatedDotNL;
				float3 vPosition[4];
				float3 vDirection[4];
				float3 vFinalLighting;
				float3 vHalfDir[4];
				half4 vDotNH;
				half4 vertexVDotNH;
				half4 vDotLH;
				#endif
				
			};
			
			struct PoiVertexLights
			{
				
				float3 direction;
				float3 color;
				float attenuation;
			};
			
			struct PoiFragData
			{
				float smoothness;
				float smoothness2;
				float metallic;
				float specularMask;
				float reflectionMask;
				
				float3 baseColor;
				float3 finalColor;
				float alpha;
				float3 emission;
				float toggleVertexLights;
			};
			
			float4 poiTransformClipSpacetoScreenSpaceFrag(float4 clipPos)
			{
				float4 positionSS = float4(clipPos.xyz * clipPos.w, clipPos.w);
				positionSS.xy = positionSS.xy / _ScreenParams.xy;
				return positionSS;
			}
			
			// glsl_mod behaves better on negative numbers, and
			// in some situations actually outperforms HLSL's fmod()
			#ifndef glsl_mod
			#define glsl_mod(x, y) (((x) - (y) * floor((x) / (y))))
			#endif
			
			uniform float random_uniform_float_only_used_to_stop_compiler_warnings = 0.0f;
			
			float2 poiUV(float2 uv, float4 tex_st)
			{
				return uv * tex_st.xy + tex_st.zw;
			}
			
			float2 vertexUV(in VertexOut o, int index)
			{
				switch(index)
				{
					case 0:
					return o.uv[0].xy;
					case 1:
					return o.uv[0].zw;
					case 2:
					return o.uv[1].xy;
					case 3:
					return o.uv[1].zw;
					default:
					return o.uv[0].xy;
				}
			}
			
			float2 vertexUV(in appdata v, int index)
			{
				switch(index)
				{
					case 0:
					return v.uv0.xy;
					case 1:
					return v.uv1.xy;
					case 2:
					return v.uv2.xy;
					case 3:
					return v.uv3.xy;
					default:
					return v.uv0.xy;
				}
			}
			
			//Lighting Helpers
			float calculateluminance(float3 color)
			{
				return color.r * 0.299 + color.g * 0.587 + color.b * 0.114;
			}
			
			// Set by VRChat (as of open beta 1245)
			// _VRChatCameraMode: 0 => Normal, 1 => VR HandCam, 2 => Desktop Handcam, 3 => Screenshot/Photo
			// _VRChatMirrorMode: 0 => Normal, 1 => Mirror (VR), 2 => Mirror (Deskie)
			float _VRChatCameraMode;
			float _VRChatMirrorMode;
			
			float VRCCameraMode()
			{
				return _VRChatCameraMode;
			}
			
			float VRCMirrorMode()
			{
				return _VRChatMirrorMode;
			}
			
			bool IsInMirror()
			{
				return unity_CameraProjection[2][0] != 0.f || unity_CameraProjection[2][1] != 0.f;
			}
			
			bool IsOrthographicCamera()
			{
				return unity_OrthoParams.w == 1 || UNITY_MATRIX_P[3][3] == 1;
			}
			
			float shEvaluateDiffuseL1Geomerics_local(float L0, float3 L1, float3 n)
			{
				// average energy
				float R0 = max(0, L0);
				
				// avg direction of incoming light
				float3 R1 = 0.5f * L1;
				
				// directional brightness
				float lenR1 = length(R1);
				
				// linear angle between normal and direction 0-1
				//float q = 0.5f * (1.0f + dot(R1 / lenR1, n));
				//float q = dot(R1 / lenR1, n) * 0.5 + 0.5;
				float q = dot(normalize(R1), n) * 0.5 + 0.5;
				q = saturate(q); // Thanks to ScruffyRuffles for the bug identity.
				
				// power for q
				// lerps from 1 (linear) to 3 (cubic) based on directionality
				float p = 1.0f + 2.0f * lenR1 / R0;
				
				// dynamic range constant
				// should vary between 4 (highly directional) and 0 (ambient)
				float a = (1.0f - lenR1 / R0) / (1.0f + lenR1 / R0);
				
				return R0 * (a + (1.0f - a) * (p + 1.0f) * pow(q, p));
			}
			
			half3 BetterSH9(half4 normal)
			{
				float3 indirect;
				float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) + float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0;
				indirect.r = shEvaluateDiffuseL1Geomerics_local(L0.r, unity_SHAr.xyz, normal.xyz);
				indirect.g = shEvaluateDiffuseL1Geomerics_local(L0.g, unity_SHAg.xyz, normal.xyz);
				indirect.b = shEvaluateDiffuseL1Geomerics_local(L0.b, unity_SHAb.xyz, normal.xyz);
				indirect = max(0, indirect);
				indirect += SHEvalLinearL2(normal);
				return indirect;
			}
			
			// Silent's code ends here
			
			float3 getCameraForward()
			{
				#if UNITY_SINGLE_PASS_STEREO
				float3 p1 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 1, 1));
				float3 p2 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 0, 1));
				#else
				float3 p1 = mul(unity_CameraToWorld, float4(0, 0, 1, 1)).xyz;
				float3 p2 = mul(unity_CameraToWorld, float4(0, 0, 0, 1)).xyz;
				#endif
				return normalize(p2 - p1);
			}
			
			half3 GetSHLength()
			{
				half3 x, x1;
				x.r = length(unity_SHAr);
				x.g = length(unity_SHAg);
				x.b = length(unity_SHAb);
				x1.r = length(unity_SHBr);
				x1.g = length(unity_SHBg);
				x1.b = length(unity_SHBb);
				return x + x1;
			}
			
			float3 BoxProjection(float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax)
			{
				#if UNITY_SPECCUBE_BOX_PROJECTION
				//UNITY_BRANCH
				if (cubemapPosition.w > 0)
				{
					float3 factors = ((direction > 0 ? boxMax : boxMin) - position) / direction;
					float scalar = min(min(factors.x, factors.y), factors.z);
					direction = direction * scalar + (position - cubemapPosition.xyz);
				}
				#endif
				return direction;
			}
			
			float poiMax(float2 i)
			{
				return max(i.x, i.y);
			}
			
			float poiMax(float3 i)
			{
				return max(max(i.x, i.y), i.z);
			}
			
			float poiMax(float4 i)
			{
				return max(max(max(i.x, i.y), i.z), i.w);
			}
			
			float3 calculateNormal(in float3 baseNormal, in PoiMesh poiMesh, in Texture2D normalTexture, in float4 normal_ST, in float2 normalPan, in float normalUV, in float normalIntensity)
			{
				float3 normal = UnpackScaleNormal(POI2D_SAMPLER_PAN(normalTexture, _MainTex, poiUV(poiMesh.uv[normalUV], normal_ST), normalPan), normalIntensity);
				return normalize(
				normal.x * poiMesh.tangent[0] +
				normal.y * poiMesh.binormal[0] +
				normal.z * baseNormal
				);
			}
			
			float remap(float x, float minOld, float maxOld, float minNew = 0, float maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float2 remap(float2 x, float2 minOld, float2 maxOld, float2 minNew = 0, float2 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float3 remap(float3 x, float3 minOld, float3 maxOld, float3 minNew = 0, float3 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float4 remap(float4 x, float4 minOld, float4 maxOld, float4 minNew = 0, float4 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float remapClamped(float minOld, float maxOld, float x, float minNew = 0, float maxNew = 1)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float2 remapClamped(float2 minOld, float2 maxOld, float2 x, float2 minNew, float2 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float3 remapClamped(float3 minOld, float3 maxOld, float3 x, float3 minNew, float3 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float4 remapClamped(float4 minOld, float4 maxOld, float4 x, float4 minNew, float4 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			float2 calcParallax(in float height, in PoiCam poiCam)
			{
				return ((height * - 1) + 1) * (poiCam.tangentViewDir.xy / poiCam.tangentViewDir.z);
			}
			
			/*
			0: Zero	                float4(0.0, 0.0, 0.0, 0.0),
			1: One	                float4(1.0, 1.0, 1.0, 1.0),
			2: DstColor	            destinationColor,
			3: SrcColor	            sourceColor,
			4: OneMinusDstColor	    float4(1.0, 1.0, 1.0, 1.0) - destinationColor,
			5: SrcAlpha	            sourceColor.aaaa,
			6: OneMinusSrcColor	    float4(1.0, 1.0, 1.0, 1.0) - sourceColor,
			7: DstAlpha	            destinationColor.aaaa,
			8: OneMinusDstAlpha	    float4(1.0, 1.0, 1.0, 1.0) - destinationColor.,
			9: SrcAlphaSaturate     saturate(sourceColor.aaaa),
			10: OneMinusSrcAlpha	float4(1.0, 1.0, 1.0, 1.0) - sourceColor.aaaa,
			*/
			
			float4 poiBlend(const float sourceFactor, const  float4 sourceColor, const  float destinationFactor, const  float4 destinationColor, const float4 blendFactor)
			{
				float4 sA = 1 - blendFactor;
				const float4 blendData[11] = {
					float4(0.0, 0.0, 0.0, 0.0),
					float4(1.0, 1.0, 1.0, 1.0),
					destinationColor,
					sourceColor,
					float4(1.0, 1.0, 1.0, 1.0) - destinationColor,
					sA,
					float4(1.0, 1.0, 1.0, 1.0) - sourceColor,
					sA,
					float4(1.0, 1.0, 1.0, 1.0) - sA,
					saturate(sourceColor.aaaa),
					1 - sA,
				};
				
				return lerp(blendData[sourceFactor] * sourceColor + blendData[destinationFactor] * destinationColor, sourceColor, sA);
			}
			
			// Average
			float blendAverage(float base, float blend)
			{
				return (base + blend) / 2.0;
			}
			float3 blendAverage(float3 base, float3 blend)
			{
				return (base + blend) / 2.0;
			}
			
			// Color burn
			float blendColorBurn(float base, float blend)
			{
				return (blend == 0.0) ? blend : max((1.0 - ((1.0 - base) * rcp(random_uniform_float_only_used_to_stop_compiler_warnings + blend))), 0.0);
			}
			
			float3 blendColorBurn(float3 base, float3 blend)
			{
				return float3(blendColorBurn(base.r, blend.r), blendColorBurn(base.g, blend.g), blendColorBurn(base.b, blend.b));
			}
			
			// Color Dodge
			float blendColorDodge(float base, float blend)
			{
				return (blend == 1.0) ? blend : min(base / (1.0 - blend), 1.0);
			}
			
			float3 blendColorDodge(float3 base, float3 blend)
			{
				return float3(blendColorDodge(base.r, blend.r), blendColorDodge(base.g, blend.g), blendColorDodge(base.b, blend.b));
			}
			
			// Darken
			float blendDarken(float base, float blend)
			{
				return min(blend, base);
			}
			
			float3 blendDarken(float3 base, float3 blend)
			{
				return float3(blendDarken(base.r, blend.r), blendDarken(base.g, blend.g), blendDarken(base.b, blend.b));
			}
			
			// Exclusion
			float blendExclusion(float base, float blend)
			{
				return base + blend - 2.0 * base * blend;
			}
			float3 blendExclusion(float3 base, float3 blend)
			{
				return base + blend - 2.0 * base * blend;
			}
			
			// Reflect
			float blendReflect(float base, float blend)
			{
				return (blend == 1.0) ? blend : min(base * base / (1.0 - blend), 1.0);
			}
			
			float3 blendReflect(float3 base, float3 blend)
			{
				return float3(blendReflect(base.r, blend.r), blendReflect(base.g, blend.g), blendReflect(base.b, blend.b));
			}
			
			// Glow
			float blendGlow(float base, float blend)
			{
				return blendReflect(blend, base);
			}
			float3 blendGlow(float3 base, float3 blend)
			{
				return blendReflect(blend, base);
			}
			
			// Overlay
			float blendOverlay(float base, float blend)
			{
				return base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend));
			}
			
			float3 blendOverlay(float3 base, float3 blend)
			{
				return float3(blendOverlay(base.r, blend.r), blendOverlay(base.g, blend.g), blendOverlay(base.b, blend.b));
			}
			
			// Hard Light
			float blendHardLight(float base, float blend)
			{
				return blendOverlay(blend, base);
			}
			float3 blendHardLight(float3 base, float3 blend)
			{
				return blendOverlay(blend, base);
			}
			
			// Vivid light
			float blendVividLight(float base, float blend)
			{
				return (blend < 0.5) ? blendColorBurn(base, (2.0 * blend)) : blendColorDodge(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendVividLight(float3 base, float3 blend)
			{
				return float3(blendVividLight(base.r, blend.r), blendVividLight(base.g, blend.g), blendVividLight(base.b, blend.b));
			}
			
			// Hard mix
			float blendHardMix(float base, float blend)
			{
				return (blendVividLight(base, blend) < 0.5) ? 0.0 : 1.0;
			}
			
			float3 blendHardMix(float3 base, float3 blend)
			{
				return float3(blendHardMix(base.r, blend.r), blendHardMix(base.g, blend.g), blendHardMix(base.b, blend.b));
			}
			
			// Lighten
			float blendLighten(float base, float blend)
			{
				return max(blend, base);
			}
			
			float3 blendLighten(float3 base, float3 blend)
			{
				return float3(blendLighten(base.r, blend.r), blendLighten(base.g, blend.g), blendLighten(base.b, blend.b));
			}
			
			// Linear Burn
			float blendLinearBurn(float base, float blend)
			{
				// Note : Same implementation as BlendSubtractf
				return max(base + blend - 1.0, 0.0);
			}
			
			float3 blendLinearBurn(float3 base, float3 blend)
			{
				// Note : Same implementation as BlendSubtract
				return max(base + blend - float3(1.0, 1.0, 1.0), float3(0.0, 0.0, 0.0));
			}
			
			// Linear Dodge
			float blendLinearDodge(float base, float blend)
			{
				// Note : Same implementation as BlendAddf
				return min(base + blend, 1.0);
			}
			
			float3 blendLinearDodge(float3 base, float3 blend)
			{
				// Note : Same implementation as BlendAdd
				return base + blend;
			}
			
			// Linear light
			float blendLinearLight(float base, float blend)
			{
				return blend < 0.5 ? blendLinearBurn(base, (2.0 * blend)) : blendLinearDodge(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendLinearLight(float3 base, float3 blend)
			{
				return float3(blendLinearLight(base.r, blend.r), blendLinearLight(base.g, blend.g), blendLinearLight(base.b, blend.b));
			}
			
			// Multiply
			float blendMultiply(float base, float blend)
			{
				return base * blend;
			}
			float3 blendMultiply(float3 base, float3 blend)
			{
				return base * blend;
			}
			
			// Negation
			float blendNegation(float base, float blend)
			{
				return 1.0 - abs(1.0 - base - blend);
			}
			float3 blendNegation(float3 base, float3 blend)
			{
				return float3(1.0, 1.0, 1.0) - abs(float3(1.0, 1.0, 1.0) - base - blend);
			}
			
			// Normal
			float blendNormal(float base, float blend)
			{
				return blend;
			}
			float3 blendNormal(float3 base, float3 blend)
			{
				return blend;
			}
			
			// Phoenix
			float blendPhoenix(float base, float blend)
			{
				return min(base, blend) - max(base, blend) + 1.0;
			}
			float3 blendPhoenix(float3 base, float3 blend)
			{
				return min(base, blend) - max(base, blend) + float3(1.0, 1.0, 1.0);
			}
			
			// Pin light
			float blendPinLight(float base, float blend)
			{
				return (blend < 0.5) ? blendDarken(base, (2.0 * blend)) : blendLighten(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendPinLight(float3 base, float3 blend)
			{
				return float3(blendPinLight(base.r, blend.r), blendPinLight(base.g, blend.g), blendPinLight(base.b, blend.b));
			}
			
			// Screen
			float blendScreen(float base, float blend)
			{
				return 1.0 - ((1.0 - base) * (1.0 - blend));
			}
			
			float3 blendScreen(float3 base, float3 blend)
			{
				return float3(blendScreen(base.r, blend.r), blendScreen(base.g, blend.g), blendScreen(base.b, blend.b));
			}
			
			// Soft Light
			float blendSoftLight(float base, float blend)
			{
				return (blend < 0.5) ? (2.0 * base * blend + base * base * (1.0 - 2.0 * blend)) : (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend));
			}
			
			float3 blendSoftLight(float3 base, float3 blend)
			{
				return float3(blendSoftLight(base.r, blend.r), blendSoftLight(base.g, blend.g), blendSoftLight(base.b, blend.b));
			}
			
			// Subtract
			float blendSubtract(float base, float blend)
			{
				return max(base - blend, 0.0);
			}
			
			float3 blendSubtract(float3 base, float3 blend)
			{
				return max(base - blend, 0.0);
			}
			
			// Difference
			float blendDifference(float base, float blend)
			{
				return abs(base - blend);
			}
			
			float3 blendDifference(float3 base, float3 blend)
			{
				return abs(base - blend);
			}
			
			// Divide
			float blendDivide(float base, float blend)
			{
				return base / max(blend, 0.0001);
			}
			
			float3 blendDivide(float3 base, float3 blend)
			{
				return base / max(blend, 0.0001);
			}
			
			float blendMixed(float base, float blend)
			{
				return base + base * blend;
			}
			
			float3 blendMixed(float3 base, float3 blend)
			{
				return base + base * blend;
			}
			
			float3 customBlend(float3 base, float3 blend, float blendType, float alpha = 1)
			{
				float3 output = base;
				switch(blendType)
				{
					case 0: output = lerp(base, blend, alpha); break;
					case 1: output = lerp(base, blendDarken(base, blend), alpha); break;
					case 2: output = base * lerp(1, blend, alpha); break;
					case 5: output = lerp(base, blendLighten(base, blend), alpha); break;
					case 6: output = lerp(base, blendScreen(base, blend), alpha); break;
					case 7: output = blendSubtract(base, blend * alpha); break;
					case 8: output = lerp(base, blendLinearDodge(base, blend), alpha); break;
					case 9: output = lerp(base, blendOverlay(base, blend), alpha); break;
					case 20: output = lerp(base, blendMixed(base, blend), alpha); break;
					default: output = 0; break;
				}
				return output;
			}
			
			float3 customBlend(float base, float blend, float blendType, float alpha = 1)
			{
				float3 output = base;
				switch(blendType)
				{
					case 0: output = lerp(base, blend, alpha); break;
					case 2: output = base * lerp(1, blend, alpha); break;
					case 5: output = lerp(base, blendLighten(base, blend), alpha); break;
					case 6: output = lerp(base, blendScreen(base, blend), alpha); break;
					case 7: output = blendSubtract(base, blend * alpha); break;
					case 8: output = lerp(base, blendLinearDodge(base, blend), alpha); break;
					case 9: output = lerp(base, blendOverlay(base, blend), alpha); break;
					case 20: output = lerp(base, blendMixed(base, blend), alpha); break;
					default: output = 0; break;
				}
				return output;
			}
			
			#define REPLACE 0
			#define SUBSTRACT 1
			#define MULTIPLY 2
			#define DIVIDE 3
			#define MIN 4
			#define MAX 5
			#define AVERAGE 6
			#define ADD 7
			
			float maskBlend(float baseMask, float blendMask, float blendType)
			{
				float output = 0;
				switch(blendType)
				{
					case REPLACE: output = blendMask; break;
					case SUBSTRACT: output = baseMask - blendMask; break;
					case MULTIPLY: output = baseMask * blendMask; break;
					case DIVIDE: output = baseMask / blendMask; break;
					case MIN: output = min(baseMask, blendMask); break;
					case MAX: output = max(baseMask, blendMask); break;
					case AVERAGE: output = (baseMask + blendMask) * 0.5; break;
					case ADD: output = baseMask + blendMask; break;
				}
				return saturate(output);
			}
			
			float globalMaskBlend(float baseMask, float globalMaskIndex, float blendType, PoiMods poiMods)
			{
				if (globalMaskIndex == 0)
				{
					return baseMask;
				}
				else
				{
					return maskBlend(baseMask, poiMods.globalMask[globalMaskIndex - 1], blendType);
				}
			}
			
			float random(float2 p)
			{
				return frac(sin(dot(p, float2(12.9898, 78.2383))) * 43758.5453123);
			}
			
			float2 random2(float2 p)
			{
				return frac(sin(float2(dot(p, float2(127.1, 311.7)), dot(p, float2(269.5, 183.3)))) * 43758.5453);
			}
			
			float3 random3(float2 p)
			{
				return frac(sin(float3(dot(p, float2(127.1, 311.7)), dot(p, float2(269.5, 183.3)), dot(p, float2(248.3, 315.9)))) * 43758.5453);
			}
			
			float3 random3(float3 p)
			{
				return frac(sin(float3(dot(p, float3(127.1, 311.7, 248.6)), dot(p, float3(269.5, 183.3, 423.3)), dot(p, float3(248.3, 315.9, 184.2)))) * 43758.5453);
			}
			
			float3 randomFloat3(float2 Seed, float maximum)
			{
				return (.5 + float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed), float2(12.9898, 78.233))) * 43758.5453)
				) * .5) * (maximum);
			}
			
			float3 randomFloat3Range(float2 Seed, float Range)
			{
				return (float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed.x * Seed.y, Seed.y + Seed.x), float2(12.9898, 78.233))) * 43758.5453)
				) * 2 - 1) * Range;
			}
			
			float3 randomFloat3WiggleRange(float2 Seed, float Range, float wiggleSpeed, float timeOffset)
			{
				float3 rando = (float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed.x * Seed.y, Seed.y + Seed.x), float2(12.9898, 78.233))) * 43758.5453)
				) * 2 - 1);
				float speed = 1 + wiggleSpeed;
				return float3(sin(((_Time.x + timeOffset) + rando.x * PI) * speed), sin(((_Time.x + timeOffset) + rando.y * PI) * speed), sin(((_Time.x + timeOffset) + rando.z * PI) * speed)) * Range;
			}
			
			void poiDither(float4 In, float4 ScreenPosition, out float4 Out)
			{
				float2 uv = ScreenPosition.xy * _ScreenParams.xy;
				float DITHER_THRESHOLDS[16] = {
					1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0,
					13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0,
					4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0,
					16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0
				};
				uint index = (uint(uv.x) % 4) * 4 + uint(uv.y) % 4;
				Out = In - DITHER_THRESHOLDS[index];
			}
			// The weights of RGB contributions to luminance.
			// Should sum to unity.
			static const float3 HCYwts = float3(0.299, 0.587, 0.114);
			static const float HCLgamma = 3;
			static const float HCLy0 = 100;
			static const float HCLmaxL = 0.530454533953517; // == exp(HCLgamma / HCLy0) - 0.5
			static const float3 wref = float3(1.0, 1.0, 1.0);
			#define TAU 6.28318531
			
			float3 HUEtoRGB(in float H)
			{
				float R = abs(H * 6 - 3) - 1;
				float G = 2 - abs(H * 6 - 2);
				float B = 2 - abs(H * 6 - 4);
				return saturate(float3(R, G, B));
			}
			
			float3 RGBtoHCV(in float3 RGB)
			{
				// Based on work by Sam Hocevar and Emil Persson
				float4 P = (RGB.g < RGB.b) ? float4(RGB.bg, -1.0, 2.0 / 3.0) : float4(RGB.gb, 0.0, -1.0 / 3.0);
				float4 Q = (RGB.r < P.x) ? float4(P.xyw, RGB.r) : float4(RGB.r, P.yzx);
				float C = Q.x - min(Q.w, Q.y);
				float H = abs((Q.w - Q.y) / (6 * C + Epsilon) + Q.z);
				return float3(H, C, Q.x);
			}
			
			float3 HSVtoRGB(in float3 HSV)
			{
				float3 RGB = HUEtoRGB(HSV.x);
				return ((RGB - 1) * HSV.y + 1) * HSV.z;
			}
			
			float3 RGBtoHSV(in float3 RGB)
			{
				float3 HCV = RGBtoHCV(RGB);
				float S = HCV.y / (HCV.z + Epsilon);
				return float3(HCV.x, S, HCV.z);
			}
			
			float3 HSLtoRGB(in float3 HSL)
			{
				float3 RGB = HUEtoRGB(HSL.x);
				float C = (1 - abs(2 * HSL.z - 1)) * HSL.y;
				return (RGB - 0.5) * C + HSL.z;
			}
			
			float3 RGBtoHSL(in float3 RGB)
			{
				float3 HCV = RGBtoHCV(RGB);
				float L = HCV.z - HCV.y * 0.5;
				float S = HCV.y / (1 - abs(L * 2 - 1) + Epsilon);
				return float3(HCV.x, S, L);
			}
			
			void DecomposeHDRColor(in float3 linearColorHDR, out float3 baseLinearColor, out float exposure)
			{
				// Optimization/adaptation of https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/GUI/ColorMutator.cs#L23 but skips weird photoshop stuff
				float maxColorComponent = max(linearColorHDR.r, max(linearColorHDR.g, linearColorHDR.b));
				bool isSDR = maxColorComponent <= 1.0;
				
				float scaleFactor = isSDR ? 1.0 : (1.0 / maxColorComponent);
				exposure = isSDR ? 0.0 : log(maxColorComponent) * 1.44269504089; // ln(2)
				
				baseLinearColor = scaleFactor * linearColorHDR;
			}
			
			float3 ApplyHDRExposure(float3 linearColor, float exposure)
			{
				return linearColor * pow(2, exposure);
			}
			
			// Transforms an RGB color using a matrix. Note that S and V are absolute values here
			float3 ModifyViaHSV(float3 color, float h, float s, float v)
			{
				float3 colorHSV = RGBtoHSV(color);
				colorHSV.x = frac(colorHSV.x + h);
				colorHSV.y = saturate(colorHSV.y + s);
				colorHSV.z = saturate(colorHSV.z + v);
				return HSVtoRGB(colorHSV);
			}
			
			float3 ModifyViaHSV(float3 color, float3 HSVMod)
			{
				return ModifyViaHSV(color, HSVMod.x, HSVMod.y, HSVMod.z);
			}
			
			float4x4 brightnessMatrix(float brightness)
			{
				return float4x4(
				1, 0, 0, 0,
				0, 1, 0, 0,
				0, 0, 1, 0,
				brightness, brightness, brightness, 1
				);
			}
			
			float4x4 contrastMatrix(float contrast)
			{
				float t = (1.0 - contrast) / 2.0;
				
				return float4x4(
				contrast, 0, 0, 0,
				0, contrast, 0, 0,
				0, 0, contrast, 0,
				t, t, t, 1
				);
			}
			
			float4x4 saturationMatrix(float saturation)
			{
				float3 luminance = float3(0.3086, 0.6094, 0.0820);
				
				float oneMinusSat = 1.0 - saturation;
				
				float3 red = luminance.x * oneMinusSat;
				red += float3(saturation, 0, 0);
				
				float3 green = luminance.y * oneMinusSat;
				green += float3(0, saturation, 0);
				
				float3 blue = luminance.z * oneMinusSat;
				blue += float3(0, 0, saturation);
				
				return float4x4(
				red, 0,
				green, 0,
				blue, 0,
				0, 0, 0, 1
				);
			}
			
			float4 PoiColorBCS(float4 color, float brightness, float contrast, float saturation)
			{
				return mul(color, mul(brightnessMatrix(brightness), mul(contrastMatrix(contrast), saturationMatrix(saturation))));
			}
			float3 PoiColorBCS(float3 color, float brightness, float contrast, float saturation)
			{
				return mul(float4(color, 1), mul(brightnessMatrix(brightness), mul(contrastMatrix(contrast), saturationMatrix(saturation)))).rgb;
			}
			
			float3 linear_srgb_to_oklab(float3 c)
			{
				float l = 0.4122214708 * c.x + 0.5363325363 * c.y + 0.0514459929 * c.z;
				float m = 0.2119034982 * c.x + 0.6806995451 * c.y + 0.1073969566 * c.z;
				float s = 0.0883024619 * c.x + 0.2817188376 * c.y + 0.6299787005 * c.z;
				
				float l_ = pow(l, 1.0 / 3.0);
				float m_ = pow(m, 1.0 / 3.0);
				float s_ = pow(s, 1.0 / 3.0);
				
				return float3(
				0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_,
				1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_,
				0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_
				);
			}
			
			float3 oklab_to_linear_srgb(float3 c)
			{
				float l_ = c.x + 0.3963377774 * c.y + 0.2158037573 * c.z;
				float m_ = c.x - 0.1055613458 * c.y - 0.0638541728 * c.z;
				float s_ = c.x - 0.0894841775 * c.y - 1.2914855480 * c.z;
				
				float l = l_ * l_ * l_;
				float m = m_ * m_ * m_;
				float s = s_ * s_ * s_;
				
				return float3(
				+ 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
				- 1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
				- 0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s
				);
			}
			
			float3 hueShift(float3 color, float shift)
			{
				float3 oklab = linear_srgb_to_oklab(max(color, 0.0000000001));
				float hue = atan2(oklab.z, oklab.y);
				hue += shift * PI * 2;  // Add the hue shift
				
				float chroma = length(oklab.yz);
				oklab.y = cos(hue) * chroma;
				oklab.z = sin(hue) * chroma;
				
				return oklab_to_linear_srgb(oklab);
			}
			
			float3 hueShift(float4 color, float shift)
			{
				return hueShift(color.rgb, shift);
			}
			
			/*
			float3 hueShift(float3 color, float hueOffset)
			{
				color = RGBtoHSV(color);
				color.x = frac(hueOffset +color.x);
				return HSVtoRGB(color);
			}
			*/
			
			// LCH
			float xyzF(float t)
			{
				return lerp(pow(t, 1. / 3.), 7.787037 * t + 0.139731, step(t, 0.00885645));
			}
			float xyzR(float t)
			{
				return lerp(t * t * t, 0.1284185 * (t - 0.139731), step(t, 0.20689655));
			}
			
			float4x4 poiRotationMatrixFromAngles(float x, float y, float z)
			{
				float angleX = radians(x);
				float c = cos(angleX);
				float s = sin(angleX);
				float4x4 rotateXMatrix = float4x4(1, 0, 0, 0,
				0, c, -s, 0,
				0, s, c, 0,
				0, 0, 0, 1);
				
				float angleY = radians(y);
				c = cos(angleY);
				s = sin(angleY);
				float4x4 rotateYMatrix = float4x4(c, 0, s, 0,
				0, 1, 0, 0,
				- s, 0, c, 0,
				0, 0, 0, 1);
				
				float angleZ = radians(z);
				c = cos(angleZ);
				s = sin(angleZ);
				float4x4 rotateZMatrix = float4x4(c, -s, 0, 0,
				s, c, 0, 0,
				0, 0, 1, 0,
				0, 0, 0, 1);
				
				return mul(mul(rotateXMatrix, rotateYMatrix), rotateZMatrix);
			}
			
			float4x4 poiRotationMatrixFromAngles(float3 angles)
			{
				float angleX = radians(angles.x);
				float c = cos(angleX);
				float s = sin(angleX);
				float4x4 rotateXMatrix = float4x4(1, 0, 0, 0,
				0, c, -s, 0,
				0, s, c, 0,
				0, 0, 0, 1);
				
				float angleY = radians(angles.y);
				c = cos(angleY);
				s = sin(angleY);
				float4x4 rotateYMatrix = float4x4(c, 0, s, 0,
				0, 1, 0, 0,
				- s, 0, c, 0,
				0, 0, 0, 1);
				
				float angleZ = radians(angles.z);
				c = cos(angleZ);
				s = sin(angleZ);
				float4x4 rotateZMatrix = float4x4(c, -s, 0, 0,
				s, c, 0, 0,
				0, 0, 1, 0,
				0, 0, 0, 1);
				
				return mul(mul(rotateXMatrix, rotateYMatrix), rotateZMatrix);
			}
			
			float3 getCameraPosition()
			{
				#ifdef USING_STEREO_MATRICES
				return lerp(unity_StereoWorldSpaceCameraPos[0], unity_StereoWorldSpaceCameraPos[1], 0.5);
				#endif
				return _WorldSpaceCameraPos;
			}
			
			float2 calcPixelScreenUVs(half4 grabPos)
			{
				half2 uv = grabPos.xy / (grabPos.w + 0.0000000001);
				#if UNITY_SINGLE_PASS_STEREO
				uv.xy *= half2(_ScreenParams.x * 2, _ScreenParams.y);
				#else
				uv.xy *= _ScreenParams.xy;
				#endif
				
				return uv;
			}
			
			float CalcMipLevel(float2 texture_coord)
			{
				float2 dx = ddx(texture_coord);
				float2 dy = ddy(texture_coord);
				float delta_max_sqr = max(dot(dx, dx), dot(dy, dy));
				
				return 0.5 * log2(delta_max_sqr);
			}
			
			float inverseLerp(float A, float B, float T)
			{
				return (T - A) / (B - A);
			}
			
			float inverseLerp2(float2 a, float2 b, float2 value)
			{
				float2 AB = b - a;
				float2 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			float inverseLerp3(float3 a, float3 b, float3 value)
			{
				float3 AB = b - a;
				float3 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			float inverseLerp4(float4 a, float4 b, float4 value)
			{
				float4 AB = b - a;
				float4 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			/*
			MIT License
			
			Copyright (c) 2019 wraikny
			
			Permission is hereby granted, free of charge, to any person obtaining a copy
			of this software and associated documentation files (the "Software"), to deal
			in the Software without restriction, including without limitation the rights
			to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
			copies of the Software, and to permit persons to whom the Software is
			furnished to do so, subject to the following conditions:
			
			The above copyright notice and this permission notice shall be included in all
			copies or substantial portions of the Software.
			
			THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
			IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
			FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
			AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
			LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
			OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
			SOFTWARE.
			
			VertexTransformShader is dependent on:
			*/
			
			float4 quaternion_conjugate(float4 v)
			{
				return float4(
				v.x, -v.yzw
				);
			}
			
			float4 quaternion_mul(float4 v1, float4 v2)
			{
				float4 result1 = (v1.x * v2 + v1 * v2.x);
				
				float4 result2 = float4(
				- dot(v1.yzw, v2.yzw),
				cross(v1.yzw, v2.yzw)
				);
				
				return float4(result1 + result2);
			}
			
			// angle : radians
			float4 get_quaternion_from_angle(float3 axis, float angle)
			{
				float sn = sin(angle * 0.5);
				float cs = cos(angle * 0.5);
				return float4(axis * sn, cs);
			}
			
			float4 quaternion_from_vector(float3 inVec)
			{
				return float4(0.0, inVec);
			}
			
			float degree_to_radius(float degree)
			{
				return (
				degree / 180.0 * PI
				);
			}
			
			float3 rotate_with_quaternion(float3 inVec, float3 rotation)
			{
				float4 qx = get_quaternion_from_angle(float3(1, 0, 0), radians(rotation.x));
				float4 qy = get_quaternion_from_angle(float3(0, 1, 0), radians(rotation.y));
				float4 qz = get_quaternion_from_angle(float3(0, 0, 1), radians(rotation.z));
				
				#define MUL3(A, B, C) quaternion_mul(quaternion_mul((A), (B)), (C))
				float4 quaternion = normalize(MUL3(qx, qy, qz));
				float4 conjugate = quaternion_conjugate(quaternion);
				
				float4 inVecQ = quaternion_from_vector(inVec);
				
				float3 rotated = (
				MUL3(quaternion, inVecQ, conjugate)
				).yzw;
				
				return rotated;
			}
			
			float4 transform(float4 input, float4 pos, float4 rotation, float4 scale)
			{
				input.rgb *= (scale.xyz * scale.w);
				input = float4(rotate_with_quaternion(input.xyz, rotation.xyz * rotation.w) + (pos.xyz * pos.w), input.w);
				return input;
			}
			
			float2 RotateUV(float2 _uv, float _radian, float2 _piv, float _time)
			{
				float RotateUV_ang = _radian;
				float RotateUV_cos = cos(_time * RotateUV_ang);
				float RotateUV_sin = sin(_time * RotateUV_ang);
				return (mul(_uv - _piv, float2x2(RotateUV_cos, -RotateUV_sin, RotateUV_sin, RotateUV_cos)) + _piv);
			}
			
			/*
			MIT END
			*/
			
			float3 RotateAroundAxis(float3 original, float3 axis, float radian)
			{
				float s = sin(radian);
				float c = cos(radian);
				float one_minus_c = 1.0 - c;
				
				axis = normalize(axis);
				float3x3 rot_mat = {
					one_minus_c * axis.x * axis.x + c, one_minus_c * axis.x * axis.y - axis.z * s, one_minus_c * axis.z * axis.x + axis.y * s,
					one_minus_c * axis.x * axis.y + axis.z * s, one_minus_c * axis.y * axis.y + c, one_minus_c * axis.y * axis.z - axis.x * s,
					one_minus_c * axis.z * axis.x - axis.y * s, one_minus_c * axis.y * axis.z + axis.x * s, one_minus_c * axis.z * axis.z + c
				};
				return mul(rot_mat, original);
			}
			
			float3 poiThemeColor(in PoiMods poiMods, in float3 srcColor, in float themeIndex)
			{
				float3 outputColor = srcColor;
				if (themeIndex != 0)
				{
					themeIndex = max(themeIndex - 1, 0);
					
					if (themeIndex <= 3)
					{
						outputColor = poiMods.globalColorTheme[themeIndex];
					}
					else
					{
						#ifdef POI_AUDIOLINK
						if (poiMods.audioLinkAvailable)
						{
							outputColor = poiMods.globalColorTheme[themeIndex];
						}
						#endif
					}
				}
				return outputColor;
			}
			
			float3 lilToneCorrection(float3 c, float4 hsvg)
			{
				// gamma
				c = pow(abs(c), hsvg.w);
				// rgb - > hsv
				float4 p = (c.b > c.g) ? float4(c.bg, -1.0, 2.0 / 3.0) : float4(c.gb, 0.0, -1.0 / 3.0);
				float4 q = (p.x > c.r) ? float4(p.xyw, c.r) : float4(c.r, p.yzx);
				float d = q.x - min(q.w, q.y);
				float e = 1.0e-10;
				float3 hsv = float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
				// shift
				hsv = float3(hsv.x + hsvg.x, saturate(hsv.y * hsvg.y), saturate(hsv.z * hsvg.z));
				// hsv - > rgb
				return hsv.z - hsv.z * hsv.y + hsv.z * hsv.y * saturate(abs(frac(hsv.x + float3(1.0, 2.0 / 3.0, 1.0 / 3.0)) * 6.0 - 3.0) - 1.0);
			}
			
			float3 lilBlendColor(float3 dstCol, float3 srcCol, float3 srcA, int blendMode)
			{
				float3 ad = dstCol + srcCol;
				float3 mu = dstCol * srcCol;
				float3 outCol = float3(0, 0, 0);
				if (blendMode == 0) outCol = srcCol; // Normal
				if (blendMode == 1) outCol = ad; // Add
				if (blendMode == 2) outCol = max(ad - mu, dstCol); // Screen
				if (blendMode == 3) outCol = mu; // Multiply
				return lerp(dstCol, outCol, srcA);
			}
			
			float lilIsIn0to1(float f)
			{
				float value = 0.5 - abs(f - 0.5);
				return saturate(value / clamp(fwidth(value), 0.0001, 1.0));
			}
			
			float lilIsIn0to1(float f, float nv)
			{
				float value = 0.5 - abs(f - 0.5);
				return saturate(value / clamp(fwidth(value), 0.0001, nv));
			}
			
			float poiEdgeLinearNoSaturate(float value, float border)
			{
				return (value - border) / clamp(fwidth(value), 0.0001, 1.0);
			}
			
			float3 poiEdgeLinearNoSaturate(float value, float3 border)
			{
				return float3(
				(value - border.x) / clamp(fwidth(value), 0.0001, 1.0),
				(value - border.y) / clamp(fwidth(value), 0.0001, 1.0),
				(value - border.z) / clamp(fwidth(value), 0.0001, 1.0)
				);
			}
			
			float poiEdgeLinearNoSaturate(float value, float border, float blur)
			{
				float borderMin = saturate(border - blur * 0.5);
				float borderMax = saturate(border + blur * 0.5);
				return (value - borderMin) / saturate(borderMax - borderMin + fwidth(value));
			}
			
			float poiEdgeLinearNoSaturate(float value, float border, float blur, float borderRange)
			{
				float borderMin = saturate(border - blur * 0.5 - borderRange);
				float borderMax = saturate(border + blur * 0.5);
				return (value - borderMin) / saturate(borderMax - borderMin + fwidth(value));
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border)
			{
				// return (value - border) / clamp(fwidth(value), 0.0001, 1.0);
				
				float fwidthValue = fwidth(value);
				return smoothstep(border - fwidthValue, border + fwidthValue, value);
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border, float blur)
			{
				float fwidthValue = fwidth(value);
				float borderMin = saturate(border - blur * 0.5);
				float borderMax = saturate(border + blur * 0.5);
				return smoothstep(borderMin - fwidthValue, borderMax + fwidthValue, value);
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border, float blur, float borderRange)
			{
				float fwidthValue = fwidth(value);
				float borderMin = saturate(border - blur * 0.5 - borderRange);
				float borderMax = saturate(border + blur * 0.5);
				return smoothstep(borderMin - fwidthValue, borderMax + fwidthValue, value);
			}
			
			float poiEdgeNonLinear(float value, float border)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border));
			}
			
			float poiEdgeNonLinear(float value, float border, float blur)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border, blur));
			}
			
			float poiEdgeNonLinear(float value, float border, float blur, float borderRange)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border, blur, borderRange));
			}
			
			float poiEdgeLinear(float value, float border)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border));
			}
			
			float poiEdgeLinear(float value, float border, float blur)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border, blur));
			}
			
			float poiEdgeLinear(float value, float border, float blur, float borderRange)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border, blur, borderRange));
			}
			// From https : // github.com / lilxyzw / OpenLit / blob / main / Assets / OpenLit / core.hlsl
			float3 OpenLitLinearToSRGB(float3 col)
			{
				return LinearToGammaSpace(col);
			}
			
			float3 OpenLitSRGBToLinear(float3 col)
			{
				return GammaToLinearSpace(col);
			}
			
			float OpenLitLuminance(float3 rgb)
			{
				#if defined(UNITY_COLORSPACE_GAMMA)
				return dot(rgb, float3(0.22, 0.707, 0.071));
				#else
				return dot(rgb, float3(0.0396819152, 0.458021790, 0.00609653955));
				#endif
			}
			
			float3 AdjustLitLuminance(float3 rgb, float targetLuminance)
			{
				float currentLuminance;
				#if defined(UNITY_COLORSPACE_GAMMA)
				currentLuminance = dot(rgb, float3(0.22, 0.707, 0.071));
				#else
				currentLuminance = dot(rgb, float3(0.0396819152, 0.458021790, 0.00609653955));
				#endif
				
				float luminanceRatio = targetLuminance / currentLuminance;
				return rgb * luminanceRatio;
			}
			
			float3 ClampLuminance(float3 rgb, float minLuminance, float maxLuminance)
			{
				float currentLuminance = dot(rgb, float3(0.299, 0.587, 0.114));
				float minRatio = (currentLuminance != 0) ? minLuminance / currentLuminance : 1.0;
				float maxRatio = (currentLuminance != 0) ? maxLuminance / currentLuminance : 1.0;
				float luminanceRatio = clamp(min(maxRatio, max(minRatio, 1.0)), 0.0, 1.0);
				return lerp(rgb, rgb * luminanceRatio, luminanceRatio < 1.0);
			}
			
			float3 MaxLuminance(float3 rgb, float maxLuminance)
			{
				float currentLuminance = dot(rgb, float3(0.299, 0.587, 0.114));
				float luminanceRatio = (currentLuminance != 0) ? maxLuminance / max(currentLuminance, 0.00001) : 1.0;
				return lerp(rgb, rgb * luminanceRatio, currentLuminance > maxLuminance);
			}
			
			float OpenLitGray(float3 rgb)
			{
				return dot(rgb, float3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0));
			}
			
			void OpenLitShadeSH9ToonDouble(float3 lightDirection, out float3 shMax, out float3 shMin)
			{
				#if !defined(LIGHTMAP_ON)
				float3 N = lightDirection * 0.666666;
				float4 vB = N.xyzz * N.yzzx;
				// L0 L2
				float3 res = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
				res.r += dot(unity_SHBr, vB);
				res.g += dot(unity_SHBg, vB);
				res.b += dot(unity_SHBb, vB);
				res += unity_SHC.rgb * (N.x * N.x - N.y * N.y);
				// L1
				float3 l1;
				l1.r = dot(unity_SHAr.rgb, N);
				l1.g = dot(unity_SHAg.rgb, N);
				l1.b = dot(unity_SHAb.rgb, N);
				shMax = res + l1;
				shMin = res - l1;
				#if defined(UNITY_COLORSPACE_GAMMA)
				shMax = OpenLitLinearToSRGB(shMax);
				shMin = OpenLitLinearToSRGB(shMin);
				#endif
				#else
				shMax = 0.0;
				shMin = 0.0;
				#endif
			}
			
			float3 OpenLitComputeCustomLightDirection(float4 lightDirectionOverride)
			{
				float3 customDir = length(lightDirectionOverride.xyz) * normalize(mul((float3x3)unity_ObjectToWorld, lightDirectionOverride.xyz));
				return lightDirectionOverride.w ? customDir : lightDirectionOverride.xyz; // .w isn't doc'd anywhere and is always 0 unless end user changes it
			}
			
			float3 OpenLitLightingDirectionForSH9()
			{
				float3 mainDir = _WorldSpaceLightPos0.xyz * OpenLitLuminance(_LightColor0.rgb);
				#if !defined(LIGHTMAP_ON)
				float3 sh9Dir = unity_SHAr.xyz * 0.333333 + unity_SHAg.xyz * 0.333333 + unity_SHAb.xyz * 0.333333;
				float3 sh9DirAbs = float3(sh9Dir.x, abs(sh9Dir.y), sh9Dir.z);
				#else
				float3 sh9Dir = 0;
				float3 sh9DirAbs = 0;
				#endif
				
				float3 lightDirectionForSH9 = sh9Dir + mainDir;
				lightDirectionForSH9 = dot(lightDirectionForSH9, lightDirectionForSH9) < 0.000001 ? 0 : normalize(lightDirectionForSH9);
				return lightDirectionForSH9;
			}
			
			float3 OpenLitLightingDirection(float4 lightDirectionOverride)
			{
				float3 mainDir = _WorldSpaceLightPos0.xyz * OpenLitLuminance(_LightColor0.rgb);
				#if !defined(LIGHTMAP_ON) && UNITY_SHOULD_SAMPLE_SH
				float3 sh9Dir = unity_SHAr.xyz * 0.333333 + unity_SHAg.xyz * 0.333333 + unity_SHAb.xyz * 0.333333;
				float3 sh9DirAbs = float3(sh9Dir.x, abs(sh9Dir.y), sh9Dir.z);
				#else
				float3 sh9Dir = 0;
				float3 sh9DirAbs = 0;
				#endif
				float3 customDir = OpenLitComputeCustomLightDirection(lightDirectionOverride);
				
				return normalize(sh9DirAbs + mainDir + customDir);
			}
			
			float3 OpenLitLightingDirection()
			{
				float4 customDir = float4(0.001, 0.002, 0.001, 0.0);
				return OpenLitLightingDirection(customDir);
			}
			
			inline float4 CalculateFrustumCorrection()
			{
				float x1 = -UNITY_MATRIX_P._31 / (UNITY_MATRIX_P._11 * UNITY_MATRIX_P._34);
				float x2 = -UNITY_MATRIX_P._32 / (UNITY_MATRIX_P._22 * UNITY_MATRIX_P._34);
				return float4(x1, x2, 0, UNITY_MATRIX_P._33 / UNITY_MATRIX_P._34 + x1 * UNITY_MATRIX_P._13 + x2 * UNITY_MATRIX_P._23);
			}
			
			inline float CorrectedLinearEyeDepth(float z, float B)
			{
				return 1.0 / (z / UNITY_MATRIX_P._34 + B);
			}
			
			// Silent's code
			float2 sharpSample(float4 texelSize, float2 p)
			{
				p = p * texelSize.zw;
				float2 c = max(0.0, fwidth(p));
				p = floor(p) + saturate(frac(p) / c);
				p = (p - 0.5) * texelSize.xy;
				return p;
			}
			
			void applyToGlobalMask(inout PoiMods poiMods, int index, int blendType, float val)
			{
				float valBlended = saturate(maskBlend(poiMods.globalMask[index], val, blendType));
				switch(index)
				{
					case 0: poiMods.globalMask[0] = valBlended; break;
					case 1: poiMods.globalMask[1] = valBlended; break;
					case 2: poiMods.globalMask[2] = valBlended; break;
					case 3: poiMods.globalMask[3] = valBlended; break;
					case 4: poiMods.globalMask[4] = valBlended; break;
					case 5: poiMods.globalMask[5] = valBlended; break;
					case 6: poiMods.globalMask[6] = valBlended; break;
					case 7: poiMods.globalMask[7] = valBlended; break;
					case 8: poiMods.globalMask[8] = valBlended; break;
					case 9: poiMods.globalMask[9] = valBlended; break;
					case 10: poiMods.globalMask[10] = valBlended; break;
					case 11: poiMods.globalMask[11] = valBlended; break;
					case 12: poiMods.globalMask[12] = valBlended; break;
					case 13: poiMods.globalMask[13] = valBlended; break;
					case 14: poiMods.globalMask[14] = valBlended; break;
					case 15: poiMods.globalMask[15] = valBlended; break;
				}
			}
			
			void assignValueToVectorFromIndex(inout float4 vec, int index, float value)
			{
				switch(index)
				{
					case 0: vec[0] = value; break;
					case 1: vec[1] = value; break;
					case 2: vec[2] = value; break;
					case 3: vec[3] = value; break;
				}
			}
			
			// SNose
			float3 mod289(float3 x)
			{
				return x - floor(x * (1.0 / 289.0)) * 289.0;
			}
			float2 mod289(float2 x)
			{
				return x - floor(x * (1.0 / 289.0)) * 289.0;
			}
			float3 permute(float3 x)
			{
				return mod289(((x * 34.0) + 1.0) * x);
			}
			
			float snoise(float2 v)
			{
				const float4 C = float4(0.211324865405187, // (3.0 - sqrt(3.0)) / 6.0
				0.366025403784439, // 0.5 * (sqrt(3.0) - 1.0)
				- 0.577350269189626, // - 1.0 + 2.0 * C.x
				0.024390243902439); // 1.0 / 41.0
				float2 i = floor(v + dot(v, C.yy));
				float2 x0 = v - i + dot(i, C.xx);
				float2 i1;
				i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0);
				float4 x12 = x0.xyxy + C.xxzz;
				x12.xy -= i1;
				i = mod289(i); // Avoid truncation effects in permutation
				float3 p = permute(permute(i.y + float3(0.0, i1.y, 1.0))
				+ i.x + float3(0.0, i1.x, 1.0));
				
				float3 m = max(0.5 - float3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);
				m = m * m ;
				m = m * m ;
				float3 x = 2.0 * frac(p * C.www) - 1.0;
				float3 h = abs(x) - 0.5;
				float3 ox = floor(x + 0.5);
				float3 a0 = x - ox;
				m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);
				float3 g;
				g.x = a0.x * x0.x + h.x * x0.y;
				g.yz = a0.yz * x12.xz + h.yz * x12.yw;
				return 130.0 * dot(m, g);
			}
			
			float nsqDistance(float2 a, float2 b)
			{
				return dot(a - b, a - b);
			}
			
			float poiInvertToggle(in float value, in float toggle)
			{
				return (toggle == 0 ? value : 1 - value);
			}
			
			float3 PoiBlendNormal(float3 dstNormal, float3 srcNormal)
			{
				return float3(dstNormal.xy + srcNormal.xy, dstNormal.z * srcNormal.z);
			}
			
			float3 lilTransformDirOStoWS(float3 directionOS, bool doNormalize)
			{
				if (doNormalize) return normalize(mul((float3x3)unity_ObjectToWorld, directionOS));
				else            return mul((float3x3)unity_ObjectToWorld, directionOS);
			}
			
			float2 poiGetWidthAndHeight(Texture2D tex)
			{
				uint width, height;
				tex.GetDimensions(width, height);
				return float2(width, height);
			}
			
			float2 poiGetWidthAndHeight(Texture2DArray tex)
			{
				uint width, height, element;
				tex.GetDimensions(width, height, element);
				return float2(width, height);
			}
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			
			// Convenient mechanism to read from the AudioLink texture that handles reading off the end of one line and onto the next above it.
			float4 AudioLinkDataMultiline(uint2 xycoord)
			{
				return AudioLinkData(uint2(xycoord.x % AUDIOLINK_WIDTH, xycoord.y + xycoord.x / AUDIOLINK_WIDTH));
			}
			
			// Mechanism to sample between two adjacent pixels and lerp between them, like "linear" supesampling
			float4 AudioLinkLerp(float2 xy)
			{
				return lerp(AudioLinkData(xy), AudioLinkData(xy + int2(1, 0)), frac(xy.x));
			}
			
			// Same as AudioLinkLerp but properly handles multiline reading.
			float4 AudioLinkLerpMultiline(float2 xy)
			{
				return lerp(AudioLinkDataMultiline(xy), AudioLinkDataMultiline(xy + float2(1, 0)), frac(xy.x));
			}
			
			//Tests to see if Audio Link texture is available
			bool AudioLinkIsAvailable()
			{
				#if !defined(AUDIOLINK_STANDARD_INDEXING)
				int width, height;
				_AudioTexture.GetDimensions(width, height);
				return width > 16;
				#else
				return _AudioTexture_TexelSize.z > 16;
				#endif
			}
			
			//Get version of audiolink present in the world, 0 if no audiolink is present
			float AudioLinkGetVersion()
			{
				int2 dims;
				#if !defined(AUDIOLINK_STANDARD_INDEXING)
				_AudioTexture.GetDimensions(dims.x, dims.y);
				#else
				dims = _AudioTexture_TexelSize.zw;
				#endif
				
				if (dims.x >= 128)
				return AudioLinkData(ALPASS_GENERALVU).x;
				else if (dims.x > 16)
				return 1;
				else
				return 0;
			}
			
			// This pulls data from this texture.
			#define AudioLinkGetSelfPixelData(xy) _SelfTexture2D[xy]
			
			// Extra utility functions for time.
			uint AudioLinkDecodeDataAsUInt(uint2 indexloc)
			{
				uint4 rpx = AudioLinkData(indexloc);
				return rpx.r + rpx.g * 1024 + rpx.b * 1048576 + rpx.a * 1073741824;
			}
			
			//Note: This will truncate time to every 134,217.728 seconds (~1.5 days of an instance being up) to prevent floating point aliasing.
			// if your code will alias sooner, you will need to use a different function.  It should be safe to use this on all times.
			float AudioLinkDecodeDataAsSeconds(uint2 indexloc)
			{
				uint time = AudioLinkDecodeDataAsUInt(indexloc) & 0x7ffffff;
				//Can't just divide by float.  Bug in Unity's HLSL compiler.
				return float(time / 1000) + float(time % 1000) / 1000.;
			}
			
			#define ALDecodeDataAsSeconds(x) AudioLinkDecodeDataAsSeconds(x)
			#define ALDecodeDataAsUInt(x) AudioLinkDecodeDataAsUInt(x)
			
			float AudioLinkRemap(float t, float a, float b, float u, float v)
			{
				return ((t - a) / (b - a)) * (v - u) + u;
			}
			
			float3 AudioLinkHSVtoRGB(float3 HSV)
			{
				float3 RGB = 0;
				float C = HSV.z * HSV.y;
				float H = HSV.x * 6;
				float X = C * (1 - abs(fmod(H, 2) - 1));
				if (HSV.y != 0)
				{
					float I = floor(H);
					if (I == 0)
					{
						RGB = float3(C, X, 0);
					}
					else if (I == 1)
					{
						RGB = float3(X, C, 0);
					}
					else if (I == 2)
					{
						RGB = float3(0, C, X);
					}
					else if (I == 3)
					{
						RGB = float3(0, X, C);
					}
					else if (I == 4)
					{
						RGB = float3(X, 0, C);
					}
					else
					{
						RGB = float3(C, 0, X);
					}
				}
				float M = HSV.z - C;
				return RGB + M;
			}
			
			float3 AudioLinkCCtoRGB(float bin, float intensity, int rootNote)
			{
				float note = bin / AUDIOLINK_EXPBINS;
				
				float hue = 0.0;
				note *= 12.0;
				note = glsl_mod(4. - note + rootNote, 12.0);
				{
					if (note < 4.0)
					{
						//Needs to be YELLOW->RED
						hue = (note) / 24.0;
					}
					else if (note < 8.0)
					{
						//            [4]  [8]
						//Needs to be RED->BLUE
						hue = (note - 2.0) / 12.0;
					}
					else
					{
						//             [8] [12]
						//Needs to be BLUE->YELLOW
						hue = (note - 4.0) / 8.0;
					}
				}
				float val = intensity - 0.1;
				return AudioLinkHSVtoRGB(float3(fmod(hue, 1.0), 1.0, clamp(val, 0.0, 1.0)));
			}
			
			// Sample the amplitude of a given frequency in the DFT, supports frequencies in [13.75; 14080].
			float4 AudioLinkGetAmplitudeAtFrequency(float hertz)
			{
				float note = AUDIOLINK_EXPBINS * log2(hertz / AUDIOLINK_BOTTOM_FREQUENCY);
				return AudioLinkLerpMultiline(ALPASS_DFT + float2(note, 0));
			}
			
			// Sample the amplitude of a given semitone in an octave. Octave is in [0; 9] while note is [0; 11].
			float AudioLinkGetAmplitudeAtNote(float octave, float note)
			{
				float quarter = note * 2.0;
				return AudioLinkLerpMultiline(ALPASS_DFT + float2(octave * AUDIOLINK_EXPBINS + quarter, 0));
			}
			
			// Get a reasonable drop-in replacement time value for _Time.y with the
			// given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTime(uint index, uint band)
			{
				return (AudioLinkDecodeDataAsUInt(ALPASS_CHRONOTENSITY + uint2(index, band))) / 100000.0;
			}
			
			// Get a chronotensity value in the interval [0; 1], modulated by the speed input,
			// with the given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTimeNormalized(uint index, uint band, float speed)
			{
				return frac(AudioLinkGetChronoTime(index, band) * speed);
			}
			
			// Get a chronotensity value in the interval [0; interval], modulated by the speed input,
			// with the given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTimeInterval(uint index, uint band, float speed, float interval)
			{
				return AudioLinkGetChronoTimeNormalized(index, band, speed) * interval;
			}
			
			float getBandAtTime(float band, float time, float size = 1.0f)
			{
				//return remap(UNITY_SAMPLE_TEX2D(_AudioTexture, float2(time * width, band/128.0)).r, min(size,.9999), 1);
				return remapClamped(min(size, .9999), 1, AudioLinkData(ALPASS_AUDIOBASS + uint2(time * AUDIOLINK_WIDTH, band)).r);
			}
			
			fixed3 maximize(fixed3 c)
			{
				if (c.x == 0 && c.y == 0 && c.z == 0)
				return fixed3(1.0, 1.0, 1.0);
				else
				return c / max(c.r, max(c.g, c.b));
			}
			
			void initPoiAudioLink(inout PoiMods poiMods)
			{
				if (!_AudioLinkAnimToggle) return;
				
				if (AudioLinkIsAvailable())
				{
					poiMods.audioLinkAvailable = true;
					poiMods.audioLinkVersion = AudioLinkGetVersion();
					poiMods.audioLink[0] = _AudioLinkSmoothingBass == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 0))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingBass) * 15.95, 0))[0];
					poiMods.audioLink[1] = _AudioLinkSmoothingLowMid == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 1))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingLowMid) * 15.95, 1))[0];
					poiMods.audioLink[2] = _AudioLinkSmoothingHighMid == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 2))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingHighMid) * 15.95, 2))[0];
					poiMods.audioLink[3] = _AudioLinkSmoothingTreble == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 3))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingTreble) * 15.95, 3))[0];
					poiMods.audioLink[4] = AudioLinkData(ALPASS_GENERALVU + float2(8, 0))[0];
					/*
					poiMods.globalColorTheme[4] = AudioLinkData( ALPASS_CCCOLORS + uint2( 0, 0 ) );
					poiMods.globalColorTheme[5] = AudioLinkData( ALPASS_CCCOLORS + uint2( 1, 0 ) );
					poiMods.globalColorTheme[6] = AudioLinkData( ALPASS_CCCOLORS + uint2( 2, 0 ) );
					poiMods.globalColorTheme[7] = AudioLinkData( ALPASS_CCCOLORS + uint2( 3, 0 ) );
					
					poiMods.globalColorTheme[4] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 0, 0 ) )),1.0);
					poiMods.globalColorTheme[5] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 1, 0 ) )),1.0);
					poiMods.globalColorTheme[6] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 2, 0 ) )),1.0);
					poiMods.globalColorTheme[7] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 3, 0 ) )),1.0);
					*/
					
					poiMods.globalColorTheme[4] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(2, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[5] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(3, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[6] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(4, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[7] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(5, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					
					poiMods.globalColorTheme[8] = AudioLinkData(ALPASS_THEME_COLOR0);
					poiMods.globalColorTheme[9] = AudioLinkData(ALPASS_THEME_COLOR1);
					poiMods.globalColorTheme[10] = AudioLinkData(ALPASS_THEME_COLOR2);
					poiMods.globalColorTheme[11] = AudioLinkData(ALPASS_THEME_COLOR3);
					return;
				}
				
				if (_AudioLinkBandOverridesEnabled)
				{
					poiMods.audioLinkAvailable = true;
					poiMods.audioLink[0] = _AudioLinkBandOverrideSliders.x;
					poiMods.audioLink[1] = _AudioLinkBandOverrideSliders.y;
					poiMods.audioLink[2] = _AudioLinkBandOverrideSliders.z;
					poiMods.audioLink[3] = _AudioLinkBandOverrideSliders.w;
				}
			}
			
			void DebugVisualizer(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				if (_DebugWaveform)
				{
					float waveform = AudioLinkLerpMultiline(ALPASS_WAVEFORM + float2(500. * poiMesh.uv[0].x, 0)).r;
					poiFragData.emission += clamp(1 - 50 * abs(waveform - poiMesh.uv[0].y * 2. + 1), 0, 1);
				}
				if (_DebugDFT)
				{
					poiFragData.emission += AudioLinkLerpMultiline(ALPASS_DFT + uint2(poiMesh.uv[0].x * AUDIOLINK_ETOTALBINS, 0)).rrr;
				}
				if (_DebugBass)
				{
					poiFragData.emission += poiMods.audioLink[0];
				}
				if (_DebugLowMids)
				{
					poiFragData.emission += poiMods.audioLink[1];
				}
				if (_DebugHighMids)
				{
					poiFragData.emission += poiMods.audioLink[2];
				}
				if (_DebugTreble)
				{
					poiFragData.emission += poiMods.audioLink[3];
				}
				if (_DebugCCColors)
				{
					poiFragData.emission += AudioLinkData(ALPASS_CCCOLORS + uint2(3 + 1, 0));
				}
				if (_DebugCCStrip)
				{
					poiFragData.emission += AudioLinkLerp(ALPASS_CCSTRIP + float2(poiMesh.uv[0].x * AUDIOLINK_WIDTH, 0));
				}
				if (_DebugCCLights)
				{
					poiFragData.emission += AudioLinkData(ALPASS_CCLIGHTS + uint2(uint(poiMesh.uv[0].x * 8) + uint(poiMesh.uv[0].y * 16) * 8, 0));
				}
				if (_DebugAutocorrelator)
				{
					poiFragData.emission += saturate(AudioLinkLerp(ALPASS_AUTOCORRELATOR + float2((abs(1. - poiMesh.uv[0].x * 2.)) * AUDIOLINK_WIDTH, 0)).rrr);
				}
				if (_DebugChronotensity)
				{
					poiFragData.emission += (AudioLinkDecodeDataAsUInt(ALPASS_CHRONOTENSITY + uint2(1, 0)) % 1000000) / 1000000.0;
				}
			}
			
			void SetupAudioLink(inout PoiFragData poiFragData, inout PoiMods poiMods, in PoiMesh poiMesh)
			{
				initPoiAudioLink(poiMods);
				DebugVisualizer(poiFragData, poiMesh, poiMods);
				
				if (_AudioLinkCCStripY)
				{
					poiFragData.emission += AudioLinkLerp(ALPASS_CCSTRIP + float2(poiMesh.uv[0].y * AUDIOLINK_WIDTH, 0)).rgb * .5;
				}
			}
			
			#endif
			//endex
			
			//ifex _BSSEnabled!=1
			#ifdef POIBS_ENABLE
			//ifex _BSSBloomfog!=1
			#ifdef POIBS_BLOOMFOG
			inline float4 GetFogCoord(float4 clipPos)
			{
				float4 screenPos = ComputeNonStereoScreenPos(clipPos);
				float2 screenPosNormalized = screenPos.xy / screenPos.w;
				float eyeOffset = (unity_StereoEyeIndex * (_StereoCameraEyeOffset * 2)) + - _StereoCameraEyeOffset;
				return float4(
				((eyeOffset +screenPosNormalized.x) + - 0.5) * _CustomFogTextureToScreenRatio.x + 0.5,
				(screenPosNormalized.y + - 0.5) * _CustomFogTextureToScreenRatio.y + 0.5
				,clipPos.z,clipPos.w);
			}
			
			inline float GetHeightFogIntensity(float3 worldPos, float fogHeightOffset, float fogHeightScale)
			{
				float heightFogIntensity = _CustomFogHeightFogHeight + _CustomFogHeightFogStartY;
				heightFogIntensity = ((worldPos.y * fogHeightScale) + fogHeightOffset) + - heightFogIntensity;
				heightFogIntensity = heightFogIntensity / _CustomFogHeightFogHeight;
				heightFogIntensity = clamp(heightFogIntensity, 0, 1);
				return ((-heightFogIntensity * 2) + 3) * (heightFogIntensity * heightFogIntensity);
			}
			
			inline float GetFogIntensity(float3 distance, float fogStartOffset, float fogScale)
			{
				float fogIntensity = max(dot(distance, distance) + - fogStartOffset, 0);
				fogIntensity = max((fogIntensity * fogScale) + - _CustomFogOffset, 0);
				fogIntensity = 1 / ((fogIntensity * _CustomFogAttenuation) + 1);
				return -fogIntensity;
			}
			#endif
			//endex
			#endif
			//endex
			
			//ifex _EnableDepthBulge==0
			#if defined(POI_DEPTHBULGE)
			void applyDepthBulgeFX(inout VertexOut o)
			{
				float4 pos = UnityObjectToClipPos(o.localPos);
				float4 grabPos = ComputeGrabScreenPos(pos);
				float depth = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(grabPos.xy / grabPos.w, 0, 0));
				
				#if defined(PROP_DEPTHBULGEMASK) || !defined(OPTIMIZER_ENABLED)
				float depthBulgeMask = tex2Dlod(_DepthBulgeMask, float4(poiUV(vertexUV(o, _DepthBulgeMaskUV), _DepthBulgeMask_ST), 0, 0))[_DepthBulgeMaskChannel];
				#else
				float depthBulgeMask = 1.0;
				#endif
				
				depth = Linear01Depth(depth);
				
				float intersect = 0;
				if (depth != 1)
				{
					float diff = distance(depth, Linear01Depth(pos.z / pos.w));
					if (diff > 0)
					{
						intersect = 1 - smoothstep(0, _ProjectionParams.w * _DepthBulgeFadeLength, diff);
					}
				}
				float4 offset = intersect * _DepthBulgeHeight * float4(o.normal, 0);
				
				offset = IsInMirror() ? 0 : offset;
				offset *= depthBulgeMask;
				
				o.worldPos.xyz += offset.xyz;
				o.localPos.xyz += mul(unity_WorldToObject, float4(offset.xyz, 0)).xyz;
			}
			#endif
			//endex
			
			VertexOut vert(
			#ifndef POI_TESSELLATED
			appdata v
			#else
			tessAppData v
			#endif
			)
			{
				UNITY_SETUP_INSTANCE_ID(v);
				VertexOut o;
				PoiInitStruct(VertexOut, o);
				UNITY_TRANSFER_INSTANCE_ID(v, o);
				#ifdef POI_TESSELLATED
				UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v);
				#endif
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
				
				//ifex _EnableUDIMDiscardOptions==0
				#ifdef POI_UDIMDISCARD
				UNITY_BRANCH
				if(_UDIMDiscardMode == 0) // Discard Vertices instead of just pixels
				{
					// Branchless (inspired by s-ilent)
					float2 udim = 0;
					// Select UV
					udim += (v.uv0.xy * (_UDIMDiscardUV == 0));
					udim += (v.uv1.xy * (_UDIMDiscardUV == 1));
					udim += (v.uv2.xy * (_UDIMDiscardUV == 2));
					udim += (v.uv3.xy * (_UDIMDiscardUV == 3));
					
					float isDiscarded = 0;
					float4 xMask = float4(  (udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					isDiscarded += (udim.y >= 0 && udim.y < 1) * dot(float4(_UDIMDiscardRow0_0, _UDIMDiscardRow0_1, _UDIMDiscardRow0_2, _UDIMDiscardRow0_3), xMask);
					isDiscarded += (udim.y >= 1 && udim.y < 2) * dot(float4(_UDIMDiscardRow1_0, _UDIMDiscardRow1_1, _UDIMDiscardRow1_2, _UDIMDiscardRow1_3), xMask);
					isDiscarded += (udim.y >= 2 && udim.y < 3) * dot(float4(_UDIMDiscardRow2_0, _UDIMDiscardRow2_1, _UDIMDiscardRow2_2, _UDIMDiscardRow2_3), xMask);
					isDiscarded += (udim.y >= 3 && udim.y < 4) * dot(float4(_UDIMDiscardRow3_0, _UDIMDiscardRow3_1, _UDIMDiscardRow3_2, _UDIMDiscardRow3_3), xMask);
					
					isDiscarded *= any(float4(udim.y >= 0, udim.y < 4, udim.x >= 0, udim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					// Use a threshold so that there's some room for animations to be close to 0, but not exactly 0
					const float threshold = 0.001;
					if(isDiscarded > threshold) // Early Return skips rest of vertex shader
					{
						return (VertexOut)POI_NAN;
					}
				}
				#endif
				//endex
				
				//ifex _VertexManipulationsEnabled==0
				#ifdef AUTO_EXPOSURE
				float4 audioLinkBands = 0;
				float3 ALrotation = 0;
				float3 ALLocalTranslation = 0;
				float3 CTALRotation = 0;
				float3 ALScale = 0;
				float3 ALWorldTranslation = 0;
				float ALHeight = 0;
				float ALRoundingAmount = 0;
				float4 ALSpectrumLocalOffset = float4(0, 0, 0, 0);
				#ifdef POI_AUDIOLINK
				if (AudioLinkIsAvailable() && _VertexAudioLinkEnabled && _AudioLinkAnimToggle)
				{
					audioLinkBands.x = AudioLinkData(ALPASS_AUDIOBASS).r;
					audioLinkBands.y = AudioLinkData(ALPASS_AUDIOLOWMIDS).r;
					audioLinkBands.z = AudioLinkData(ALPASS_AUDIOHIGHMIDS).r;
					audioLinkBands.w = AudioLinkData(ALPASS_AUDIOTREBLE).r;
					
					if (any(_VertexLocalTranslationALMin) || any(_VertexLocalTranslationALMax))
					{
						ALLocalTranslation = lerp(_VertexLocalTranslationALMin, _VertexLocalTranslationALMax, audioLinkBands[_VertexLocalTranslationALBand]);
					}
					if (any(_VertexLocalRotationAL))
					{
						ALrotation = audioLinkBands[_VertexLocalRotationALBand] * _VertexLocalRotationAL;
					}
					if (any(_VertexLocalRotationCTALSpeed))
					{
						CTALRotation.x = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeX, _VertexLocalRotationCTALBandX) * _VertexLocalRotationCTALSpeed.x * 360;
						CTALRotation.y = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeY, _VertexLocalRotationCTALBandY) * _VertexLocalRotationCTALSpeed.y * 360;
						CTALRotation.z = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeZ, _VertexLocalRotationCTALBandZ) * _VertexLocalRotationCTALSpeed.z * 360;
					}
					if (any(_VertexLocalScaleALMin) || any(_VertexLocalScaleALMax))
					{
						ALScale = lerp(_VertexLocalScaleALMin.xyz + _VertexLocalScaleALMin.w, _VertexLocalScaleALMax.xyz + _VertexLocalScaleALMax.w, audioLinkBands[_VertexLocalScaleALBand]);
					}
					if (any(_VertexWorldTranslationALMin) || any(_VertexWorldTranslationALMax))
					{
						ALWorldTranslation = lerp(_VertexWorldTranslationALMin, _VertexWorldTranslationALMax, audioLinkBands[_VertexWorldTranslationALBand]);
					}
					if (any(_VertexManipulationHeightAL))
					{
						ALHeight = lerp(_VertexManipulationHeightAL.x, _VertexManipulationHeightAL.y, audioLinkBands[_VertexManipulationHeightBand]);
					}
					if (any(_VertexRoundingRangeAL))
					{
						ALRoundingAmount = lerp(_VertexRoundingRangeAL.x, _VertexRoundingRangeAL.y, audioLinkBands[_VertexRoundingRangeBand]);
					}
					if (_VertexSpectrumMotion)
					{
						ALSpectrumLocalOffset.xyz = lerp(_VertexSpectrumOffsetMin.xyz, _VertexSpectrumOffsetMax.xyz, AudioLinkLerpMultiline(ALPASS_DFT + float2(vertexUV(v, _VertexSpectrumUV)[_VertexSpectrumUVDirection] * AUDIOLINK_ETOTALBINS, 0.)));
					}
				}
				#endif
				
				// Local Transformation
				float4 rotation = float4(_VertexManipulationLocalRotation.xyz + float3(180, 0, 0) + _VertexManipulationLocalRotationSpeed * _Time.x + ALrotation + CTALRotation, _VertexManipulationLocalRotation.w);
				v.normal = rotate_with_quaternion(v.normal, rotation.xyz);
				v.tangent.xyz = rotate_with_quaternion(v.tangent.xyz, rotation.xyz);
				v.vertex = transform(v.vertex, _VertexManipulationLocalTranslation + float4(ALLocalTranslation, 0) + ALSpectrumLocalOffset, rotation, _VertexManipulationLocalScale + float4(ALScale, 0));
				o.normal = UnityObjectToWorldNormal(v.normal);
				
				#if defined(PROP_VERTEXMANIPULATIONHEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float3 heightOffset = (tex2Dlod(_VertexManipulationHeightMask, float4(poiUV(vertexUV(v, _VertexManipulationHeightMaskUV), _VertexManipulationHeightMask_ST) + _VertexManipulationHeightMaskPan * _Time.x, 0, 0))[_VertexManipulationHeightMaskChannel] - _VertexManipulationHeightBias) * (_VertexManipulationHeight + ALHeight) * o.normal;
				#else
				float3 heightOffset = (_VertexManipulationHeight + ALHeight) * o.normal;
				#endif
				
				if (_VertexBarrelMode)
				{
					v.vertex.xz = lerp(v.vertex.xz, normalize(v.vertex.xz) * _VertexBarrelWidth + v.vertex.xz * _VertexBarrelHeight, _VertexBarrelAlpha);
				}
				
				if (_VertexSphereMode)
				{
					v.vertex.xyz = lerp(v.vertex.xyz, normalize(v.vertex.xyz + _VertexSphereCenter.xyz) * _VertexSphereRadius + v.vertex.xyz * _VertexSphereHeight, _VertexSphereAlpha);
				}
				
				if (_VertexTornadoMode)
				{
					v.vertex.xz = lerp(v.vertex.xz, float3(v.vertex.xz + float2(cos(_Time.y * _VertexTornadoSpeed + v.vertex.y * _VertexTornadoIntensity) * _VertexTornadoRadius, sin(_Time.y * _VertexTornadoSpeed + v.vertex.y * _VertexTornadoIntensity) * _VertexTornadoRadius), v.vertex.y), smoothstep(_VertexTornadoBaseHeight, _VertexTornadoTopHeight, v.vertex.y));
				}
				
				v.vertex.xyz += mul(unity_WorldToObject, _VertexManipulationWorldTranslation.xyz + ALWorldTranslation + heightOffset).xyz;
				
				// rounding
				UNITY_BRANCH
				if (_VertexRoundingEnabled)
				{
					float divisionAmount = max(_VertexRoundingDivision + ALRoundingAmount, 0.0000001);
					if (_VertexRoundingSpace == 0)
					{
						float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
						float3 worldRoundPosition = (ceil(worldPos.xyz / divisionAmount) * divisionAmount) - divisionAmount * .5;
						v.vertex = mul(unity_WorldToObject, float4(worldRoundPosition, worldPos.w));
					}
					else if (_VertexRoundingSpace == 1)
					{
						v.vertex.xyz = (ceil(v.vertex.xyz / divisionAmount) * divisionAmount) - divisionAmount * .5;
					}
				}
				#endif
				//endex
				
				//ifex _EnableDissolve==0
				#ifdef DISTORT
				UNITY_BRANCH
				if (_UVTileDissolveEnabled && _UVTileDissolveDiscardAtMax)
				{
					// Branchless (inspired by s-ilent)
					float2 dissolveUdim = 0;
					// Select UV
					dissolveUdim += (v.uv0.xy * (_UVTileDissolveUV == 0));
					dissolveUdim += (v.uv1.xy * (_UVTileDissolveUV == 1));
					dissolveUdim += (v.uv2.xy * (_UVTileDissolveUV == 2));
					dissolveUdim += (v.uv3.xy * (_UVTileDissolveUV == 3));
					
					float isDiscardedFromDissolve = 0;
					float4 xMaskDissolve = float4((dissolveUdim.x >= 0 && dissolveUdim.x < 1),
					(dissolveUdim.x >= 1 && dissolveUdim.x < 2),
					(dissolveUdim.x >= 2 && dissolveUdim.x < 3),
					(dissolveUdim.x >= 3 && dissolveUdim.x < 4));
					
					isDiscardedFromDissolve += (dissolveUdim.y >= 0 && dissolveUdim.y < 1) * dot(float4(_UVTileDissolveAlpha_Row0_0, _UVTileDissolveAlpha_Row0_1, _UVTileDissolveAlpha_Row0_2, _UVTileDissolveAlpha_Row0_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 1 && dissolveUdim.y < 2) * dot(float4(_UVTileDissolveAlpha_Row1_0, _UVTileDissolveAlpha_Row1_1, _UVTileDissolveAlpha_Row1_2, _UVTileDissolveAlpha_Row1_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 2 && dissolveUdim.y < 3) * dot(float4(_UVTileDissolveAlpha_Row2_0, _UVTileDissolveAlpha_Row2_1, _UVTileDissolveAlpha_Row2_2, _UVTileDissolveAlpha_Row2_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 3 && dissolveUdim.y < 4) * dot(float4(_UVTileDissolveAlpha_Row3_0, _UVTileDissolveAlpha_Row3_1, _UVTileDissolveAlpha_Row3_2, _UVTileDissolveAlpha_Row3_3), xMaskDissolve);
					
					isDiscardedFromDissolve *= any(float4(dissolveUdim.y >= 0, dissolveUdim.y < 4, dissolveUdim.x >= 0, dissolveUdim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					// Use a threshold so that there's some room for animations to be close to 1, but not exactly 1
					const float threshold = 0.999;
					if (isDiscardedFromDissolve > threshold) // Early Return skips rest of vertex shader
					
					{
						return (VertexOut)POI_NAN;
					}
				}
				#endif
				//endex
				
				//ifex _EnableMirrorOptions==0
				#ifdef POI_MIRROR
				float notVisible = 0;
				
				if (_VisibilityMode == 1) // VRC
				
				{
					float mirrorMode = VRCMirrorMode();
					float cameraMode = VRCCameraMode();
					
					notVisible += (!_VisibilityVRCRegular && ((mirrorMode == 0) && (cameraMode == 0)));
					notVisible += (!_VisibilityVRCMirrorVR && (mirrorMode == 1));
					notVisible += (!_VisibilityVRCMirrorDesktop && (mirrorMode == 2));
					notVisible += (!_VisibilityVRCCameraVR && (cameraMode == 1));
					notVisible += (!_VisibilityVRCCameraDesktop && (cameraMode == 2));
					notVisible += (!_VisibilityVRCCameraScreenshot && (cameraMode == 3));
				}
				else if (_Mirror != 0) // Generic (CVR, etc)
				
				{
					notVisible += (_Mirror == 1) ^ IsInMirror();
				}
				
				if (notVisible) // Early Return skips rest of vertex shader
				
				{
					return (VertexOut)POI_NAN;
				}
				#endif
				//endex
				
				o.normal = UnityObjectToWorldNormal(v.normal);
				o.tangent.xyz = UnityObjectToWorldDir(v.tangent);
				o.tangent.w = v.tangent.w;
				o.vertexColor = v.color;
				
				o.uv[0] = float4(v.uv0.xy, v.uv1.xy);
				o.uv[1] = float4(v.uv2.xy, v.uv3.xy);
				
				#if defined(LIGHTMAP_ON)
				o.lightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
				#endif
				#ifdef DYNAMICLIGHTMAP_ON
				o.lightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
				#endif
				
				o.localPos = v.vertex;
				o.worldPos = mul(unity_ObjectToWorld, o.localPos);
				
				float3 localOffset = float3(0, 0, 0);
				float3 worldOffset = float3(0, 0, 0);
				
				//ifex _EnableOutlines!=1
				#ifdef POI_PASS_OUTLINE
				float outlineMask = tex2Dlod(_OutlineMask, float4(poiUV(vertexUV(v, _OutlineMaskUV), _OutlineMask_ST) + _Time.x * _OutlineMaskPan, 0, 0))[_OutlineMaskChannel];
				
				//UNITY_BRANCH
				if (_OutlineVertexColorMask > 0)
				{
					outlineMask *= lerp(1, v.color[_OutlineVertexColorMask - 1], _OutlineVertexColorMaskStrength);
				}
				
				float3 outlineNormal = _OutlineSpace ? o.normal : v.normal;
				//UNITY_BRANCH
				if (_OutlineUseVertexColorNormals)
				{
					float3 outlineTangent;
					float3 outlineBinormal;
					if (_OutlineSpace) // 0 Local, 1 World
					
					{
						outlineTangent = o.tangent;
						outlineBinormal = cross(o.normal, o.tangent) * (v.tangent.w * unity_WorldTransformParams.w);
					}
					else
					{
						outlineTangent = v.tangent.xyz;
						outlineBinormal = normalize(cross(outlineNormal, outlineTangent)) * (v.tangent.w * length(outlineNormal));
					}
					float3 outlineVectorTS = v.color.rgb * 2.0 - 1.0;
					outlineNormal = outlineVectorTS.x * outlineTangent + outlineVectorTS.y * outlineBinormal + outlineVectorTS.z * outlineNormal;
				}
				
				float offsetMultiplier = 1;
				float distanceOffset = 1;
				//UNITY_BRANCH
				if (_OutlineFixedSize)
				{
					distanceOffset *= lerp(1.0, clamp((distance(_WorldSpaceCameraPos, mul(unity_ObjectToWorld, o.localPos).xyz)), 0.0f, _OutlinesMaxDistance), _OutlineFixWidth);
				}
				
				float lineWidth = _LineWidth;
				#ifdef POI_AUDIOLINK
				// Due to PoiMods.audioLink being frag only I'll just
				// recreate what it does here for this vertex function
				//UNITY_BRANCH
				if (_AudioLinkAnimToggle)
				{
					if (AudioLinkIsAvailable())
					{
						lineWidth += lerp(_AudioLinkOutlineSize.x, _AudioLinkOutlineSize.y, AudioLinkData(uint2(0, _AudioLinkOutlineSizeBand)));
					}
				}
				#endif
				
				float3 offset = outlineNormal * (lineWidth * _EnableOutlines / 100) * outlineMask * distanceOffset;
				
				//UNITY_BRANCH
				if (_OutlineExpansionMode == 2)
				{
					float3 lightDirection = normalize(_WorldSpaceLightPos0 + unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz);
					offsetMultiplier = saturate(dot(lightDirection, outlineNormal));
					offset *= offsetMultiplier;
					offset *= distanceOffset;
				}
				else if (_OutlineExpansionMode == 3)
				{
					float3 viewNormal = mul((float3x3)UNITY_MATRIX_V, outlineNormal);
					offsetMultiplier = saturate(dot(viewNormal.xy, normalize(_OutlinePersonaDirection.xy)));
					
					offset *= offsetMultiplier;
					offset *= distanceOffset;
				}
				else if (_OutlineExpansionMode == 4)
				{
					offset = mul((float3x3)transpose(UNITY_MATRIX_V), _OutlineDropShadowOffset);
					offset *= distanceOffset;
				}
				if (_OutlineSpace == 0)
				{
					localOffset += offset;
					worldOffset += mul(unity_ObjectToWorld, offset);
				}
				else
				{
					localOffset += mul(unity_WorldToObject, offset);
					worldOffset += offset;
				}
				#endif
				//endex
				
				//ifex _VertexGlitchingEnabled==0
				#if defined(POI_VERTEX_GLITCHING)
				
				bool canGlitch = true;
				if (_VertexGlitchMirrorEnable && _VertexGlitchMirror > 0)
				{
					bool inMirror = IsInMirror();
					if (_VertexGlitchMirror == 1 && !inMirror)	canGlitch = false;
					if (_VertexGlitchMirror == 2 && inMirror)	canGlitch = false;
				}
				if (canGlitch)
				{
					float3 forward = getCameraPosition() - mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
					forward.y = 0;
					forward = normalize(forward);
					float3 glitchDirection = normalize(cross(float3(0, 1, 0), forward));
					
					float glitchAmount = 0;
					
					#if defined(POI_VERTEX_GLITCHING_TEXTURE)
					// if(_VertexGlitchingUseTexture)
					// {
					float uvl = o.worldPos.y * _VertexGlitchDensity + _Time.x * _VertexGlitchMapPanSpeed;
					float uvr = o.worldPos.y * _VertexGlitchDensity - _Time.x * _VertexGlitchMapPanSpeed;
					
					float3 glitchTextureL = 1;
					float3 glitchTextureR = 1;
					
					#if defined(POI_VERTEX_GLITCHING_TEXTURE) || !defined(OPTIMIZER_ENABLED)
					glitchTextureL = tex2Dlod(_VertexGlitchMap, float4(uvl, uvl, 0, 0)).rgb;
					glitchTextureR = tex2Dlod(_VertexGlitchMap, float4(uvr, uvr, 0, 0)).rgb;
					#endif
					
					glitchAmount += (glitchTextureL.r - 0.5) * 2;
					glitchAmount += - (glitchTextureR.r - 0.5) * 2;
					
					glitchAmount += (glitchTextureL.g - 0.5) * 2;
					glitchAmount += - (glitchTextureR.b - 0.5) * 2;
					// } else {
					#else
					glitchAmount += frac(sin(dot(_Time.xy + o.worldPos.y, float2(12.9898, 78.233))) * 43758.5453123) * 2 - 1;
					// }
					#endif
					
					float time = _Time.y * _VertexGlitchFrequency;
					
					float randomGlitch = (sin(time) + sin(2.2 * time + 5.52) + sin(2.9 * time + 0.93) + sin(4.6 * time + 8.94)) / 4;
					float3 glitchOffset = 0;
					
					#ifdef POI_AUDIOLINK
					if (AudioLinkIsAvailable() && _VertexGlitchingAudioLinkEnabled)
					{
						// float4 audioLinkData = AudioLinkData(ALPASS_AUDIOBASS);
						
						float audioIntensity =
						AudioLinkData(ALPASS_AUDIOBASS).r 		* (_VertexGlitchingAudioLinkBand == 0) +
						AudioLinkData(ALPASS_AUDIOLOWMIDS).r 	* (_VertexGlitchingAudioLinkBand == 1) +
						AudioLinkData(ALPASS_AUDIOHIGHMIDS).r	* (_VertexGlitchingAudioLinkBand == 2) +
						AudioLinkData(ALPASS_AUDIOTREBLE).r 	* (_VertexGlitchingAudioLinkBand == 3) +
						AudioLinkData(ALPASS_FILTEREDVU_INTENSITY).r * (_VertexGlitchingAudioLinkBand == 4);
						
						if(_VertexGlitchingAudiolinkOverride)
						{
							glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
							// glitchOffset += glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
						} else {
							glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
							glitchOffset += glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
						}
					} else {
						glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
					}
					#else
					glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
					#endif
					
					localOffset += glitchOffset;
					worldOffset += mul(unity_ObjectToWorld, glitchOffset);
				}
				#endif
				//endex
				
				o.localPos.rgb += localOffset;
				o.worldPos.rgb += worldOffset;
				
				//ifex _EnableDepthBulge==0
				#if defined(POI_DEPTHBULGE) && (defined(POI_PASS_BASE) || defined(POI_PASS_ADD))
				applyDepthBulgeFX(o);
				#endif
				//endex
				
				//ifex _BSSEnabled!=1
				#ifdef POIBS_ENABLE
				//ifex _BSSBloomfog!=1
				#ifdef POIBS_BLOOMFOG
				o.fogCoord = GetFogCoord(UnityObjectToClipPos(v.vertex));
				o.worldPos = mul(unity_ObjectToWorld, v.vertex);
				#endif
				//endex
				#endif
				//endex
				
				o.pos = UnityObjectToClipPos(o.localPos);
				
				#ifdef POI_PASS_OUTLINE
				#if defined(UNITY_REVERSED_Z)
				//DX
				o.pos.z += _Offset_Z * - 0.01;
				#else
				//OpenGL
				o.pos.z += _Offset_Z * 0.01;
				#endif
				#endif
				//o.grabPos = ComputeGrabScreenPos(o.pos);
				
				#ifndef FORWARD_META_PASS
				#if !defined(UNITY_PASS_SHADOWCASTER)
				UNITY_TRANSFER_SHADOW(o, o.uv[0].xy);
				#else
				v.vertex.xyz = o.localPos.xyz;
				TRANSFER_SHADOW_CASTER_NOPOS(o, o.pos);
				#endif
				#endif
				
				UNITY_TRANSFER_FOG(o, o.pos);
				
				if (_RenderingReduceClipDistance)
				{
					if (o.pos.w < _ProjectionParams.y * 1.01 && o.pos.w > 0)
					{
						#if defined(UNITY_REVERSED_Z) // DirectX
						o.pos.z = o.pos.z * 0.0001 + o.pos.w * 0.999;
						#else // OpenGL
						o.pos.z = o.pos.z * 0.0001 - o.pos.w * 0.999;
						#endif
					}
				}
				
				#ifdef POI_PASS_META
				o.pos = UnityMetaVertexPosition(v.vertex, v.uv1.xy, v.uv2.xy, unity_LightmapST, unity_DynamicLightmapST);
				#endif
				
				return o;
			}
			
			#if defined(_STOCHASTICMODE_DELIOT_HEITZ)
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, uv) : POI2D_SAMPLER(tex, texSampler, uv))
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan)) : POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), dx, dy) : POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			#if defined(_STOCHASTICMODE_HEXTILE)
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, uv, false) : POI2D_SAMPLER(tex, texSampler, uv))
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), false) : POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), false, dx, dy) : POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			
			#ifndef POI2D_SAMPLER_STOCHASTIC
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (POI2D_SAMPLER(tex, texSampler, uv))
			#endif
			#ifndef POI2D_SAMPLER_PAN_STOCHASTIC
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#endif
			#ifndef POI2D_SAMPLER_PANGRAD_STOCHASTIC
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			
			// When using, properties won't properly lock at optimize time; needs macro evaluation implemented
			// #define POI2D_SAMPLER_STOCHASTIC_INLINED(tex, texSampler) (POI2D_SAMPLER_STOCHASTIC(tex, texSampler, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Stochastic))
			// #define POI2D_SAMPLER_PAN_STOCHASTIC_INLINED(tex, texSampler) (POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan, tex##Stochastic))
			
			// #define POI2D_MAINTEX_SAMPLER_STOCHASTIC_INLINED(tex) (POI2D_SAMPLER_STOCHASTIC(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Stochastic))
			// #define POI2D_MAINTEX_SAMPLER_PAN_STOCHASTIC_INLINED(tex) (POI2D_SAMPLER_PAN_STOCHASTIC(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan, tex##Stochastic))
			
			// Deliot, Heitz 2019 - Fast, but non-histogram-preserving (ends up looking a bit blurry and lower contrast)
			// https://eheitzresearch.wordpress.com/738-2/
			
			// Classic Magic Numbers fracsin
			#if !defined(_STOCHASTICMODE_NONE)
			float2 StochasticHash2D2D (float2 s)
			{
				return frac(sin(glsl_mod(float2(dot(s, float2(127.1,311.7)), dot(s, float2(269.5,183.3))), 3.14159)) * 43758.5453);
			}
			#endif
			
			#if defined(_STOCHASTICMODE_DELIOT_HEITZ)
			// UV Offsets and blend weights
			// UVBW[0...2].xy = UV Offsets
			// UVBW[0...2].z = Blend Weights
			float3x3 DeliotHeitzStochasticUVBW(float2 uv)
			{
				// UV transformed into triangular grid space with UV scaled by approximation of 2*sqrt(3)
				const float2x2 stochasticSkewedGrid = float2x2(1.0, -0.57735027, 0.0, 1.15470054);
				float2 skewUV = mul(stochasticSkewedGrid, uv * 3.4641 * _StochasticDeliotHeitzDensity);
				
				// Vertex IDs and barycentric coords
				float2 vxID = floor(skewUV);
				float3 bary = float3(frac(skewUV), 0);
				bary.z = 1.0 - bary.x - bary.y;
				
				float3x3 pos = float3x3(
				float3(vxID, 				bary.z),
				float3(vxID + float2(0, 1), bary.y),
				float3(vxID + float2(1, 0), bary.x)
				);
				
				float3x3 neg = float3x3(
				float3(vxID + float2(1, 1), 	 -bary.z),
				float3(vxID + float2(1, 0), 1.0 - bary.y),
				float3(vxID + float2(0, 1), 1.0 - bary.x)
				);
				
				return (bary.z > 0) ? pos : neg;
			}
			
			float4 DeliotHeitzSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, float2 dx, float2 dy)
			{
				// UVBW[0...2].xy = UV Offsets
				// UVBW[0...2].z = Blend Weights
				float3x3 UVBW = DeliotHeitzStochasticUVBW(uv);
				
				//blend samples with calculated weights
				return 	mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[0].xy), dx, dy), UVBW[0].z) +
				mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[1].xy), dx, dy), UVBW[1].z) +
				mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[2].xy), dx, dy), UVBW[2].z) ;
			}
			
			float4 DeliotHeitzSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv)
			{
				float2 dx = ddx(uv), dy = ddy(uv);
				return DeliotHeitzSampleTexture(tex, texSampler, uv, dx, dy);
			}
			#endif // defined(_STOCHASTICMODE_DELIOT_HEITZ)
			
			#if defined(_STOCHASTICMODE_HEXTILE)
			// HexTiling: Slower, but histogram-preserving
			// SPDX-License-Idenfitier: MIT
			// Copyright (c) 2022 mmikk
			// https://github.com/mmikk/hextile-demo
			float2 HextileMakeCenUV(float2 vertex)
			{
				// 0.288675 ~= 1/(2*sqrt(3))
				const float2x2 stochasticInverseSkewedGrid = float2x2(1.0, 0.5, 0.0, 1.0/1.15470054);
				return mul(stochasticInverseSkewedGrid, vertex) * 0.288675;
			}
			
			float2x2 HextileLoadRot2x2(float2 idx, float rotStrength)
			{
				float angle = abs(idx.x * idx.y) + abs(idx.x + idx.y) + PI;
				
				// remap to +/-pi
				angle = glsl_mod(angle, 2 * PI);
				if(angle < 0)  angle += 2 * PI;
				if(angle > PI) angle -= 2 * PI;
				
				angle *= rotStrength;
				
				float cs = cos(angle), si = sin(angle);
				return float2x2(cs, -si, si, cs);
			}
			
			// UV Offsets and base blend weights
			// UVBWR[0...2].xy = UV Offsets
			// UVBWR[0...2].zw = rotation costh/sinth -> reconstruct rotation matrix with float2x2(UVBWR[n].z, -UVBWR[n].w, UVBWR[n].w, UVBWR[n].z)
			// UVBWR[3].xyz = Blend Weights (w unused) - needs luminance weighting
			float4x4 HextileUVBWR(float2 uv)
			{
				// Create Triangle Grid
				// Skew input space into simplex triangle grid (3.4641 ~= 2*sqrt(3))
				const float2x2 stochasticSkewedGrid = float2x2(1.0, -0.57735027, 0.0, 1.15470054);
				float2 skewedCoord = mul(stochasticSkewedGrid, uv * 3.4641 * _StochasticHexGridDensity);
				
				float2 baseId = float2(floor(skewedCoord));
				float3 temp = float3(frac(skewedCoord), 0);
				temp.z = 1 - temp.x - temp.y;
				
				float s = step(0.0, -temp.z);
				float s2 = 2 * s - 1;
				
				float3 weights = float3(-temp.z * s2, s - temp.y * s2, s - temp.x * s2);
				
				float2 vertex0 = baseId + float2(s, s);
				float2 vertex1 = baseId + float2(s, 1 - s);
				float2 vertex2 = baseId + float2(1 - s, s);
				
				float2 cen0 = HextileMakeCenUV(vertex0), cen1 = HextileMakeCenUV(vertex1), cen2 = HextileMakeCenUV(vertex2);
				float2x2 rot0 = float2x2(1, 0, 0, 1), rot1 = float2x2(1, 0, 0, 1), rot2 = float2x2(1, 0, 0, 1);
				
				if(_StochasticHexRotationStrength > 0)
				{
					rot0 = HextileLoadRot2x2(vertex0, _StochasticHexRotationStrength);
					rot1 = HextileLoadRot2x2(vertex1, _StochasticHexRotationStrength);
					rot2 = HextileLoadRot2x2(vertex2, _StochasticHexRotationStrength);
				}
				
				return float4x4(
				float4(mul(uv - cen0, rot0) + cen0 + StochasticHash2D2D(vertex0), rot0[0].x, -rot0[0].y),
				float4(mul(uv - cen1, rot1) + cen1 + StochasticHash2D2D(vertex1), rot1[0].x, -rot1[0].y),
				float4(mul(uv - cen2, rot2) + cen2 + StochasticHash2D2D(vertex2), rot2[0].x, -rot2[0].y),
				float4(weights, 0)
				);
			}
			
			float4 HextileSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, bool isNormalMap, float2 dUVdx, float2 dUVdy)
			{
				// For some reason doing this instead of just calculating it directly prevents it from \
				// breaking after a certain number of textures use it. I don't understand why yet
				float4x4 UVBWR = HextileUVBWR(uv);
				
				// 2D Rotation Matrices for dUVdx/dy
				// Not sure if this constant folds during compiling when rot is locked at 0, so force it
				float2x2 rot0 = float2x2(1, 0, 0, 1), rot1 = float2x2(1, 0, 0, 1), rot2 = float2x2(1, 0, 0, 1);
				
				if(_StochasticHexRotationStrength > 0)
				{
					rot0 = float2x2(UVBWR[0].z, -UVBWR[0].w, UVBWR[0].w, UVBWR[0].z);
					rot1 = float2x2(UVBWR[1].z, -UVBWR[1].w, UVBWR[1].w, UVBWR[1].z);
					rot2 = float2x2(UVBWR[2].z, -UVBWR[2].w, UVBWR[2].w, UVBWR[2].z);
				}
				
				// Weights
				float3 W = UVBWR[3].xyz;
				
				// Sample texture
				// float3x4 c = float3x4(
				// 	tex.SampleGrad(texSampler, UVBWR[0].xy, mul(dUVdx, rot0), mul(dUVdy, rot0)),
				// 	tex.SampleGrad(texSampler, UVBWR[1].xy, mul(dUVdx, rot1), mul(dUVdy, rot1)),
				// 	tex.SampleGrad(texSampler, UVBWR[2].xy, mul(dUVdx, rot2), mul(dUVdy, rot2))
				// );
				
				float4 c0 = tex.SampleGrad(texSampler, UVBWR[0].xy, mul(dUVdx, rot0), mul(dUVdy, rot0));
				float4 c1 = tex.SampleGrad(texSampler, UVBWR[1].xy, mul(dUVdx, rot1), mul(dUVdy, rot1));
				float4 c2 = tex.SampleGrad(texSampler, UVBWR[2].xy, mul(dUVdx, rot2), mul(dUVdy, rot2));
				
				// Blend samples using luminance
				// This is technically incorrect for normal maps, but produces very similar
				// results to blending using normal map gradients (steepness)
				const float3 Lw = float3(0.299, 0.587, 0.114);
				float3 Dw = float3(dot(c0.xyz, Lw), dot(c1.xyz, Lw), dot(c2.xyz, Lw));
				
				Dw = lerp(1.0, Dw, _StochasticHexFallOffContrast);
				W = Dw * pow(W, _StochasticHexFallOffPower);
				// In the original hextiling there's a Gain3 step here, but it seems to slow things down \
				// and cause the UVs to break, so I've omitted it. Looks fine without
				
				W /= (W.x + W.y + W.z);
				return W.x * c0 + W.y * c1 + W.z * c2;
			}
			
			float4 HextileSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, bool isNormalMap)
			{
				return HextileSampleTexture(tex, texSampler, uv, isNormalMap, ddx(uv), ddy(uv));
			}
			#endif // defined(_STOCHASTICMODE_HEXTILE)
			
			void applyAlphaOptions(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiMods poiMods)
			{
				poiFragData.alpha = saturate(poiFragData.alpha + _AlphaMod);
				
				if (_AlphaGlobalMask > 0)
				{
					poiFragData.alpha = maskBlend(poiFragData.alpha, poiMods.globalMask[_AlphaGlobalMask - 1], _AlphaGlobalMaskBlendType);
				}
				
				//ifex _AlphaDistanceFade==0 && isNotAnimated(_AlphaDistanceFade)
				if (_AlphaDistanceFade)
				{
					float3 position = _AlphaDistanceFadeType ? poiMesh.worldPos : poiMesh.objectPosition;
					float distanceFadeMultiplier = lerp(_AlphaDistanceFadeMinAlpha, _AlphaDistanceFadeMaxAlpha, smoothstep(_AlphaDistanceFadeMin, _AlphaDistanceFadeMax, distance(position, poiCam.worldPos)));
					if (_AlphaDistanceFadeGlobalMask > 0)
					{
						distanceFadeMultiplier = lerp(1, distanceFadeMultiplier, poiMods.globalMask[_AlphaDistanceFadeGlobalMask - 1]);
					}
					poiFragData.alpha *= distanceFadeMultiplier;
				}
				//endex
				
				//ifex _AlphaFresnel==0 && isNotAnimated(_AlphaFresnel)
				if (_AlphaFresnel)
				{
					float holoRim = saturate(1 - smoothstep(min(_AlphaFresnelSharpness, _AlphaFresnelWidth), _AlphaFresnelWidth, (poiCam.vDotN)));
					holoRim = abs(lerp(1, holoRim, _AlphaFresnelAlpha));
					holoRim = _AlphaFresnelInvert ? 1 - holoRim : holoRim;
					if (_AlphaFresnelGlobalMask > 0)
					{
						holoRim = lerp(1, holoRim, poiMods.globalMask[_AlphaFresnelGlobalMask - 1]);
					}
					poiFragData.alpha *= holoRim;
				}
				//endex
				
				//ifex _AlphaAngular==0 && isNotAnimated(_AlphaAngular)
				if (_AlphaAngular)
				{
					half cameraAngleMin = _CameraAngleMin / 180;
					half cameraAngleMax = _CameraAngleMax / 180;
					half modelAngleMin = _ModelAngleMin / 180;
					half modelAngleMax = _ModelAngleMax / 180;
					float3 pos = _AngleCompareTo == 0 ? poiMesh.objectPosition : poiMesh.worldPos;
					half3 cameraToModelDirection = normalize(pos - getCameraPosition());
					half3 modelForwardDirection = normalize(mul(unity_ObjectToWorld, normalize(_AngleForwardDirection.rgb)));
					half cameraLookAtModel = remapClamped(cameraAngleMax, cameraAngleMin, .5 * dot(cameraToModelDirection, getCameraForward()) + .5);
					half modelLookAtCamera = remapClamped(modelAngleMax, modelAngleMin, .5 * dot(-cameraToModelDirection, modelForwardDirection) + .5);
					float angularAlphaMod = 1;
					if (_AngleType == 0)
					{
						angularAlphaMod = max(cameraLookAtModel, _AngleMinAlpha);
					}
					else if (_AngleType == 1)
					{
						angularAlphaMod = max(modelLookAtCamera, _AngleMinAlpha);
					}
					else if (_AngleType == 2)
					{
						angularAlphaMod = max(cameraLookAtModel * modelLookAtCamera, _AngleMinAlpha);
					}
					if (_AlphaAngularGlobalMask > 0)
					{
						angularAlphaMod = lerp(1, angularAlphaMod, poiMods.globalMask[_AlphaAngularGlobalMask - 1]);
					}
					poiFragData.alpha *= angularAlphaMod;
				}
				//endex
				
				//ifex _AlphaAudioLinkEnabled==0 && isNotAnimated(_AlphaAudioLinkEnabled)
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable && _AlphaAudioLinkEnabled)
				{
					poiFragData.alpha = saturate(poiFragData.alpha + lerp(_AlphaAudioLinkAddRange.x, _AlphaAudioLinkAddRange.y, poiMods.audioLink[_AlphaAudioLinkAddBand]));
				}
				#endif
				//endex
				
			}
			
			//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
			inline half Dither8x8Bayer(int x, int y)
			{
				// Premultiplied by 1/64
				const half dither[ 64 ] = {
					0.015625, 0.765625, 0.203125, 0.953125, 0.06250, 0.81250, 0.25000, 1.00000,
					0.515625, 0.265625, 0.703125, 0.453125, 0.56250, 0.31250, 0.75000, 0.50000,
					0.140625, 0.890625, 0.078125, 0.828125, 0.18750, 0.93750, 0.12500, 0.87500,
					0.640625, 0.390625, 0.578125, 0.328125, 0.68750, 0.43750, 0.62500, 0.37500,
					0.046875, 0.796875, 0.234375, 0.984375, 0.03125, 0.78125, 0.21875, 0.96875,
					0.546875, 0.296875, 0.734375, 0.484375, 0.53125, 0.28125, 0.71875, 0.46875,
					0.171875, 0.921875, 0.109375, 0.859375, 0.15625, 0.90625, 0.09375, 0.84375,
					0.671875, 0.421875, 0.609375, 0.359375, 0.65625, 0.40625, 0.59375, 0.34375
				};
				int r = y * 8 + x;
				return dither[r];
			}
			
			half calcDither(half2 grabPos)
			{
				return Dither8x8Bayer(glsl_mod(grabPos.x, 8), glsl_mod(grabPos.y, 8));
			}
			
			void applyDithering(inout PoiFragData poiFragData, in PoiCam poiCam)
			{
				if (_AlphaDithering)
				{
					float dither = calcDither(poiCam.posScreenPixels) - _AlphaDitherBias;
					poiFragData.alpha = saturate(poiFragData.alpha - (dither * (1 - poiFragData.alpha) * _AlphaDitherGradient));
				}
			}
			//endex
			
			//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
			void ApplyAlphaToCoverage(inout PoiFragData poiFragData, in PoiMesh poiMesh)
			{
				// Force Model Opacity to 1 if desired
				UNITY_BRANCH
				if (_Mode == 1)
				{
					UNITY_BRANCH
					if (_AlphaSharpenedA2C && _AlphaToCoverage)
					{
						// rescale alpha by mip level
						poiFragData.alpha *= 1 + max(0, CalcMipLevel(poiMesh.uv[0] * _MainTex_TexelSize.zw)) * _AlphaMipScale;
						// rescale alpha by partial derivative
						poiFragData.alpha = (poiFragData.alpha - _Cutoff) / max(fwidth(poiFragData.alpha), 0.0001) + _Cutoff;
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
				}
			}
			//endex
			
			void calculateGlobalThemes(inout PoiMods poiMods)
			{
				// Theme colors are defined as HDR; convert to SDR and do the HSV adjustment, then re-apply exposure
				float4 themeColorExposures = 0;
				float4 themeColor0, themeColor1, themeColor2, themeColor3 = 0;
				
				DecomposeHDRColor(_GlobalThemeColor0.rgb, themeColor0.rgb, themeColorExposures.x);
				DecomposeHDRColor(_GlobalThemeColor1.rgb, themeColor1.rgb, themeColorExposures.y);
				DecomposeHDRColor(_GlobalThemeColor2.rgb, themeColor2.rgb, themeColorExposures.z);
				DecomposeHDRColor(_GlobalThemeColor3.rgb, themeColor3.rgb, themeColorExposures.w);
				
				poiMods.globalColorTheme[0] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor0.rgb, frac(_GlobalThemeHue0 + _GlobalThemeHueSpeed0 * _Time.x), _GlobalThemeSaturation0, _GlobalThemeValue0), themeColorExposures.x), _GlobalThemeColor0.a);
				poiMods.globalColorTheme[1] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor1.rgb, frac(_GlobalThemeHue1 + _GlobalThemeHueSpeed1 * _Time.x), _GlobalThemeSaturation1, _GlobalThemeValue1), themeColorExposures.y), _GlobalThemeColor1.a);
				poiMods.globalColorTheme[2] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor2.rgb, frac(_GlobalThemeHue2 + _GlobalThemeHueSpeed2 * _Time.x), _GlobalThemeSaturation2, _GlobalThemeValue2), themeColorExposures.z), _GlobalThemeColor2.a);
				poiMods.globalColorTheme[3] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor3.rgb, frac(_GlobalThemeHue3 + _GlobalThemeHueSpeed3 * _Time.x), _GlobalThemeSaturation3, _GlobalThemeValue3), themeColorExposures.w), _GlobalThemeColor3.a);
			}
			
			//ifex _GlobalMaskTexturesEnable==0
			#ifdef POI_GLOBALMASK_TEXTURES
			void ApplyGlobalMaskTextures(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				#if defined(PROP_GLOBALMASKTEXTURE0) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol0 = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0_ST), _GlobalMaskTexture0Pan);
				if (_GlobalMaskTexture0Split)
				{
					poiMods.globalMask[0] = gmcol0.r;
					poiMods.globalMask[1] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_G), _GlobalMaskTexture0SplitPan_G).g;
					poiMods.globalMask[2] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_B), _GlobalMaskTexture0SplitPan_B).b;
					poiMods.globalMask[3] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_A), _GlobalMaskTexture0SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[0] = gmcol0[0];
					poiMods.globalMask[1] = gmcol0[1];
					poiMods.globalMask[2] = gmcol0[2];
					poiMods.globalMask[3] = gmcol0[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE1) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol1 = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1_ST), _GlobalMaskTexture1Pan);
				if (_GlobalMaskTexture1Split)
				{
					poiMods.globalMask[4] = gmcol1.r;
					poiMods.globalMask[5] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_G), _GlobalMaskTexture1SplitPan_G).g;
					poiMods.globalMask[6] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_B), _GlobalMaskTexture1SplitPan_B).b;
					poiMods.globalMask[7] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_A), _GlobalMaskTexture1SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[4] = gmcol1[0];
					poiMods.globalMask[5] = gmcol1[1];
					poiMods.globalMask[6] = gmcol1[2];
					poiMods.globalMask[7] = gmcol1[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE2) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol2 = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2_ST), _GlobalMaskTexture2Pan);
				if (_GlobalMaskTexture2Split)
				{
					poiMods.globalMask[8] = gmcol2.r;
					poiMods.globalMask[9] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_G), _GlobalMaskTexture2SplitPan_G).g;
					poiMods.globalMask[10] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_B), _GlobalMaskTexture2SplitPan_B).b;
					poiMods.globalMask[11] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_A), _GlobalMaskTexture2SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[8] = gmcol2[0];
					poiMods.globalMask[9] = gmcol2[1];
					poiMods.globalMask[10] = gmcol2[2];
					poiMods.globalMask[11] = gmcol2[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE3) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol3 = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3_ST), _GlobalMaskTexture3Pan);
				if (_GlobalMaskTexture3Split)
				{
					poiMods.globalMask[12] = gmcol3.r;
					poiMods.globalMask[13] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_G), _GlobalMaskTexture3SplitPan_G).g;
					poiMods.globalMask[14] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_B), _GlobalMaskTexture3SplitPan_B).b;
					poiMods.globalMask[15] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_A), _GlobalMaskTexture3SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[12] = gmcol3[0];
					poiMods.globalMask[13] = gmcol3[1];
					poiMods.globalMask[14] = gmcol3[2];
					poiMods.globalMask[15] = gmcol3[3];
				}
				#endif
			}
			#endif
			//endex
			//ifex _GlobalMaskOptionsEnable==0
			void ApplyGlobalMaskOptions(inout PoiMods poiMods)
			{
				//ifex _GlobalMaskOptionsType!=0
				if (_GlobalMaskOptionsType == 0)
				{
					poiMods.globalMask[0] = saturate(poiMods.globalMask[0] + _GlobalMaskSlider_0);
					poiMods.globalMask[1] = saturate(poiMods.globalMask[1] + _GlobalMaskSlider_1);
					poiMods.globalMask[2] = saturate(poiMods.globalMask[2] + _GlobalMaskSlider_2);
					poiMods.globalMask[3] = saturate(poiMods.globalMask[3] + _GlobalMaskSlider_3);
					poiMods.globalMask[4] = saturate(poiMods.globalMask[4] + _GlobalMaskSlider_4);
					poiMods.globalMask[5] = saturate(poiMods.globalMask[5] + _GlobalMaskSlider_5);
					poiMods.globalMask[6] = saturate(poiMods.globalMask[6] + _GlobalMaskSlider_6);
					poiMods.globalMask[7] = saturate(poiMods.globalMask[7] + _GlobalMaskSlider_7);
					poiMods.globalMask[8] = saturate(poiMods.globalMask[8] + _GlobalMaskSlider_8);
					poiMods.globalMask[9] = saturate(poiMods.globalMask[9] + _GlobalMaskSlider_9);
					poiMods.globalMask[10] = saturate(poiMods.globalMask[10] + _GlobalMaskSlider_10);
					poiMods.globalMask[11] = saturate(poiMods.globalMask[11] + _GlobalMaskSlider_11);
					poiMods.globalMask[12] = saturate(poiMods.globalMask[12] + _GlobalMaskSlider_12);
					poiMods.globalMask[13] = saturate(poiMods.globalMask[13] + _GlobalMaskSlider_13);
					poiMods.globalMask[14] = saturate(poiMods.globalMask[14] + _GlobalMaskSlider_14);
					poiMods.globalMask[15] = saturate(poiMods.globalMask[15] + _GlobalMaskSlider_15);
				}
				//endex
				//ifex _GlobalMaskOptionsType!=1
				if (_GlobalMaskOptionsType == 1)
				{
					poiMods.globalMask[0] = lerp(_GlobalMaskMinMaxSlider_0.x, _GlobalMaskMinMaxSlider_0.y, poiMods.globalMask[0]);
					poiMods.globalMask[1] = lerp(_GlobalMaskMinMaxSlider_1.x, _GlobalMaskMinMaxSlider_1.y, poiMods.globalMask[1]);
					poiMods.globalMask[2] = lerp(_GlobalMaskMinMaxSlider_2.x, _GlobalMaskMinMaxSlider_2.y, poiMods.globalMask[2]);
					poiMods.globalMask[3] = lerp(_GlobalMaskMinMaxSlider_3.x, _GlobalMaskMinMaxSlider_3.y, poiMods.globalMask[3]);
					poiMods.globalMask[4] = lerp(_GlobalMaskMinMaxSlider_4.x, _GlobalMaskMinMaxSlider_4.y, poiMods.globalMask[4]);
					poiMods.globalMask[5] = lerp(_GlobalMaskMinMaxSlider_5.x, _GlobalMaskMinMaxSlider_5.y, poiMods.globalMask[5]);
					poiMods.globalMask[6] = lerp(_GlobalMaskMinMaxSlider_6.x, _GlobalMaskMinMaxSlider_6.y, poiMods.globalMask[6]);
					poiMods.globalMask[7] = lerp(_GlobalMaskMinMaxSlider_7.x, _GlobalMaskMinMaxSlider_7.y, poiMods.globalMask[7]);
					poiMods.globalMask[8] = lerp(_GlobalMaskMinMaxSlider_8.x, _GlobalMaskMinMaxSlider_8.y, poiMods.globalMask[8]);
					poiMods.globalMask[9] = lerp(_GlobalMaskMinMaxSlider_9.x, _GlobalMaskMinMaxSlider_9.y, poiMods.globalMask[9]);
					poiMods.globalMask[10] = lerp(_GlobalMaskMinMaxSlider_10.x, _GlobalMaskMinMaxSlider_10.y, poiMods.globalMask[10]);
					poiMods.globalMask[11] = lerp(_GlobalMaskMinMaxSlider_11.x, _GlobalMaskMinMaxSlider_11.y, poiMods.globalMask[11]);
					poiMods.globalMask[12] = lerp(_GlobalMaskMinMaxSlider_12.x, _GlobalMaskMinMaxSlider_12.y, poiMods.globalMask[12]);
					poiMods.globalMask[13] = lerp(_GlobalMaskMinMaxSlider_13.x, _GlobalMaskMinMaxSlider_13.y, poiMods.globalMask[13]);
					poiMods.globalMask[14] = lerp(_GlobalMaskMinMaxSlider_14.x, _GlobalMaskMinMaxSlider_14.y, poiMods.globalMask[14]);
					poiMods.globalMask[15] = lerp(_GlobalMaskMinMaxSlider_15.x, _GlobalMaskMinMaxSlider_15.y, poiMods.globalMask[15]);
				}
				//endex
				//ifex _GlobalMaskOptionsType!=2
				if (_GlobalMaskOptionsType == 2)
				{
					if (_GlobalMaskToggleOn_0)  poiMods.globalMask[0] = 1;
					if (_GlobalMaskToggleOn_1)  poiMods.globalMask[1] = 1;
					if (_GlobalMaskToggleOn_2)  poiMods.globalMask[2] = 1;
					if (_GlobalMaskToggleOn_3)  poiMods.globalMask[3] = 1;
					if (_GlobalMaskToggleOn_4)  poiMods.globalMask[4] = 1;
					if (_GlobalMaskToggleOn_5)  poiMods.globalMask[5] = 1;
					if (_GlobalMaskToggleOn_6)  poiMods.globalMask[6] = 1;
					if (_GlobalMaskToggleOn_7)  poiMods.globalMask[7] = 1;
					if (_GlobalMaskToggleOn_8)  poiMods.globalMask[8] = 1;
					if (_GlobalMaskToggleOn_9)  poiMods.globalMask[9] = 1;
					if (_GlobalMaskToggleOn_10) poiMods.globalMask[10] = 1;
					if (_GlobalMaskToggleOn_11) poiMods.globalMask[11] = 1;
					if (_GlobalMaskToggleOn_12) poiMods.globalMask[12] = 1;
					if (_GlobalMaskToggleOn_13) poiMods.globalMask[13] = 1;
					if (_GlobalMaskToggleOn_14) poiMods.globalMask[14] = 1;
					if (_GlobalMaskToggleOn_15) poiMods.globalMask[15] = 1;
					
					poiMods.globalMask[0] *= (1 - _GlobalMaskToggleOff_0);
					poiMods.globalMask[1] *= (1 - _GlobalMaskToggleOff_1);
					poiMods.globalMask[2] *= (1 - _GlobalMaskToggleOff_2);
					poiMods.globalMask[3] *= (1 - _GlobalMaskToggleOff_3);
					poiMods.globalMask[4] *= (1 - _GlobalMaskToggleOff_4);
					poiMods.globalMask[5] *= (1 - _GlobalMaskToggleOff_5);
					poiMods.globalMask[6] *= (1 - _GlobalMaskToggleOff_6);
					poiMods.globalMask[7] *= (1 - _GlobalMaskToggleOff_7);
					poiMods.globalMask[8] *= (1 - _GlobalMaskToggleOff_8);
					poiMods.globalMask[9] *= (1 - _GlobalMaskToggleOff_9);
					poiMods.globalMask[10] *= (1 - _GlobalMaskToggleOff_10);
					poiMods.globalMask[11] *= (1 - _GlobalMaskToggleOff_11);
					poiMods.globalMask[12] *= (1 - _GlobalMaskToggleOff_12);
					poiMods.globalMask[13] *= (1 - _GlobalMaskToggleOff_13);
					poiMods.globalMask[14] *= (1 - _GlobalMaskToggleOff_14);
					poiMods.globalMask[15] *= (1 - _GlobalMaskToggleOff_15);
				}
				//endex
				
			}
			//endex
			
			float customDistanceBlend(float base, float blend, float blendType)
			{
				switch(blendType)
				{
					case 0: return blendNormal(base, blend); break;
					case 2: return blendMultiply(base, blend); break;
					default: return 0; break;
				}
			}
			
			void handleGlobalMaskDistance(int index, bool enable, bool type, float minAlpha, float maxAlpha, float min, float max, int blendType, in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				if (enable)
				{
					float3 position = type ? poiMesh.worldPos : poiMesh.objectPosition;
					float val = lerp(minAlpha, maxAlpha, smoothstep(min, max, distance(position, _WorldSpaceCameraPos)));
					poiMods.globalMask[index] = saturate(customDistanceBlend(poiMods.globalMask[index], val, blendType));
				}
			}
			
			void ApplyGlobalMaskModifiers(in PoiMesh poiMesh, inout PoiMods poiMods, in PoiCam poiCam)
			{
				//ifex _GlobalMaskModifiersBackfaceEnable==0
				if (_GlobalMaskModifiersBackfaceEnable)
				{
					float facingMode = saturate(poiMesh.isFrontFace) + 1;
					// _GlobalMaskBackface is 0 for ignore, 1 for back only, 2 for front only
					poiMods.globalMask[0] *= _GlobalMaskBackface_0 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_0));
					poiMods.globalMask[1] *= _GlobalMaskBackface_1 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_1));
					poiMods.globalMask[2] *= _GlobalMaskBackface_2 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_2));
					poiMods.globalMask[3] *= _GlobalMaskBackface_3 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_3));
					poiMods.globalMask[4] *= _GlobalMaskBackface_4 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_4));
					poiMods.globalMask[5] *= _GlobalMaskBackface_5 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_5));
					poiMods.globalMask[6] *= _GlobalMaskBackface_6 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_6));
					poiMods.globalMask[7] *= _GlobalMaskBackface_7 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_7));
					poiMods.globalMask[8] *= _GlobalMaskBackface_8 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_8));
					poiMods.globalMask[9] *= _GlobalMaskBackface_9 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_9));
					poiMods.globalMask[10] *= _GlobalMaskBackface_10 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_10));
					poiMods.globalMask[11] *= _GlobalMaskBackface_11 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_11));
					poiMods.globalMask[12] *= _GlobalMaskBackface_12 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_12));
					poiMods.globalMask[13] *= _GlobalMaskBackface_13 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_13));
					poiMods.globalMask[14] *= _GlobalMaskBackface_14 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_14));
					poiMods.globalMask[15] *= _GlobalMaskBackface_15 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_15));
				}
				//endex
				
				//ifex _GlobalMaskModifiersMirrorEnable==0
				if (_GlobalMaskModifiersMirrorEnable)
				{
					float mirrorMode = 0;
					if (_GlobalMaskMirrorVisibilityMode == 1) // VRC
					mirrorMode = VRCMirrorMode() > 0;
					else // Generic (CVR, etc)
					mirrorMode = IsInMirror();
					
					mirrorMode += 1;
					// _GlobalMaskMirror is 0 for ignore, 1 for outside mirror only, 2 for in mirror only
					poiMods.globalMask[0] *= _GlobalMaskMirror_0 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_0));
					poiMods.globalMask[1] *= _GlobalMaskMirror_1 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_1));
					poiMods.globalMask[2] *= _GlobalMaskMirror_2 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_2));
					poiMods.globalMask[3] *= _GlobalMaskMirror_3 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_3));
					poiMods.globalMask[4] *= _GlobalMaskMirror_4 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_4));
					poiMods.globalMask[5] *= _GlobalMaskMirror_5 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_5));
					poiMods.globalMask[6] *= _GlobalMaskMirror_6 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_6));
					poiMods.globalMask[7] *= _GlobalMaskMirror_7 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_7));
					poiMods.globalMask[8] *= _GlobalMaskMirror_8 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_8));
					poiMods.globalMask[9] *= _GlobalMaskMirror_9 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_9));
					poiMods.globalMask[10] *= _GlobalMaskMirror_10 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_10));
					poiMods.globalMask[11] *= _GlobalMaskMirror_11 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_11));
					poiMods.globalMask[12] *= _GlobalMaskMirror_12 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_12));
					poiMods.globalMask[13] *= _GlobalMaskMirror_13 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_13));
					poiMods.globalMask[14] *= _GlobalMaskMirror_14 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_14));
					poiMods.globalMask[15] *= _GlobalMaskMirror_15 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_15));
				}
				//endex
				
				//ifex _GlobalMaskModifiersCameraEnable==0
				if (_GlobalMaskModifiersCameraEnable)
				{
					float isCamera = VRCCameraMode() > 0;
					isCamera += 1;
					// _GlobalMaskCamera is 0 for ignore, 1 for outside camera only, 2 for in camera only
					poiMods.globalMask[0] *= _GlobalMaskCamera_0 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_0));
					poiMods.globalMask[1] *= _GlobalMaskCamera_1 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_1));
					poiMods.globalMask[2] *= _GlobalMaskCamera_2 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_2));
					poiMods.globalMask[3] *= _GlobalMaskCamera_3 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_3));
					poiMods.globalMask[4] *= _GlobalMaskCamera_4 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_4));
					poiMods.globalMask[5] *= _GlobalMaskCamera_5 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_5));
					poiMods.globalMask[6] *= _GlobalMaskCamera_6 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_6));
					poiMods.globalMask[7] *= _GlobalMaskCamera_7 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_7));
					poiMods.globalMask[8] *= _GlobalMaskCamera_8 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_8));
					poiMods.globalMask[9] *= _GlobalMaskCamera_9 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_9));
					poiMods.globalMask[10] *= _GlobalMaskCamera_10 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_10));
					poiMods.globalMask[11] *= _GlobalMaskCamera_11 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_11));
					poiMods.globalMask[12] *= _GlobalMaskCamera_12 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_12));
					poiMods.globalMask[13] *= _GlobalMaskCamera_13 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_13));
					poiMods.globalMask[14] *= _GlobalMaskCamera_14 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_14));
					poiMods.globalMask[15] *= _GlobalMaskCamera_15 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_15));
				}
				//endex
				//ifex _GlobalMaskModifiersDistanceEnable==0
				if (_GlobalMaskModifiersDistanceEnable)
				{
					//ifex _GlobalMaskDistanceEnable_0==0
					handleGlobalMaskDistance(0, _GlobalMaskDistanceEnable_0, _GlobalMaskDistanceType_0, _GlobalMaskDistanceMinAlpha_0, _GlobalMaskDistanceMaxAlpha_0, _GlobalMaskDistanceMin_0, _GlobalMaskDistanceMax_0, _GlobalMaskDistanceBlendType_0, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_1==0
					handleGlobalMaskDistance(1, _GlobalMaskDistanceEnable_1, _GlobalMaskDistanceType_1, _GlobalMaskDistanceMinAlpha_1, _GlobalMaskDistanceMaxAlpha_1, _GlobalMaskDistanceMin_1, _GlobalMaskDistanceMax_1, _GlobalMaskDistanceBlendType_1, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_2==0
					handleGlobalMaskDistance(2, _GlobalMaskDistanceEnable_2, _GlobalMaskDistanceType_2, _GlobalMaskDistanceMinAlpha_2, _GlobalMaskDistanceMaxAlpha_2, _GlobalMaskDistanceMin_2, _GlobalMaskDistanceMax_2, _GlobalMaskDistanceBlendType_2, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_3==0
					handleGlobalMaskDistance(3, _GlobalMaskDistanceEnable_3, _GlobalMaskDistanceType_3, _GlobalMaskDistanceMinAlpha_3, _GlobalMaskDistanceMaxAlpha_3, _GlobalMaskDistanceMin_3, _GlobalMaskDistanceMax_3, _GlobalMaskDistanceBlendType_3, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_4==0
					handleGlobalMaskDistance(4, _GlobalMaskDistanceEnable_4, _GlobalMaskDistanceType_4, _GlobalMaskDistanceMinAlpha_4, _GlobalMaskDistanceMaxAlpha_4, _GlobalMaskDistanceMin_4, _GlobalMaskDistanceMax_4, _GlobalMaskDistanceBlendType_4, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_5==0
					handleGlobalMaskDistance(5, _GlobalMaskDistanceEnable_5, _GlobalMaskDistanceType_5, _GlobalMaskDistanceMinAlpha_5, _GlobalMaskDistanceMaxAlpha_5, _GlobalMaskDistanceMin_5, _GlobalMaskDistanceMax_5, _GlobalMaskDistanceBlendType_5, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_6==0
					handleGlobalMaskDistance(6, _GlobalMaskDistanceEnable_6, _GlobalMaskDistanceType_6, _GlobalMaskDistanceMinAlpha_6, _GlobalMaskDistanceMaxAlpha_6, _GlobalMaskDistanceMin_6, _GlobalMaskDistanceMax_6, _GlobalMaskDistanceBlendType_6, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_7==0
					handleGlobalMaskDistance(7, _GlobalMaskDistanceEnable_7, _GlobalMaskDistanceType_7, _GlobalMaskDistanceMinAlpha_7, _GlobalMaskDistanceMaxAlpha_7, _GlobalMaskDistanceMin_7, _GlobalMaskDistanceMax_7, _GlobalMaskDistanceBlendType_7, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_8==0
					handleGlobalMaskDistance(8, _GlobalMaskDistanceEnable_8, _GlobalMaskDistanceType_8, _GlobalMaskDistanceMinAlpha_8, _GlobalMaskDistanceMaxAlpha_8, _GlobalMaskDistanceMin_8, _GlobalMaskDistanceMax_8, _GlobalMaskDistanceBlendType_8, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_9==0
					handleGlobalMaskDistance(9, _GlobalMaskDistanceEnable_9, _GlobalMaskDistanceType_9, _GlobalMaskDistanceMinAlpha_9, _GlobalMaskDistanceMaxAlpha_9, _GlobalMaskDistanceMin_9, _GlobalMaskDistanceMax_9, _GlobalMaskDistanceBlendType_9, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_10==0
					handleGlobalMaskDistance(10, _GlobalMaskDistanceEnable_10, _GlobalMaskDistanceType_10, _GlobalMaskDistanceMinAlpha_10, _GlobalMaskDistanceMaxAlpha_10, _GlobalMaskDistanceMin_10, _GlobalMaskDistanceMax_10, _GlobalMaskDistanceBlendType_10, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_11==0
					handleGlobalMaskDistance(11, _GlobalMaskDistanceEnable_11, _GlobalMaskDistanceType_11, _GlobalMaskDistanceMinAlpha_11, _GlobalMaskDistanceMaxAlpha_11, _GlobalMaskDistanceMin_11, _GlobalMaskDistanceMax_11, _GlobalMaskDistanceBlendType_11, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_12==0
					handleGlobalMaskDistance(12, _GlobalMaskDistanceEnable_12, _GlobalMaskDistanceType_12, _GlobalMaskDistanceMinAlpha_12, _GlobalMaskDistanceMaxAlpha_12, _GlobalMaskDistanceMin_12, _GlobalMaskDistanceMax_12, _GlobalMaskDistanceBlendType_12, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_13==0
					handleGlobalMaskDistance(13, _GlobalMaskDistanceEnable_13, _GlobalMaskDistanceType_13, _GlobalMaskDistanceMinAlpha_13, _GlobalMaskDistanceMaxAlpha_13, _GlobalMaskDistanceMin_13, _GlobalMaskDistanceMax_13, _GlobalMaskDistanceBlendType_13, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_14==0
					handleGlobalMaskDistance(14, _GlobalMaskDistanceEnable_14, _GlobalMaskDistanceType_14, _GlobalMaskDistanceMinAlpha_14, _GlobalMaskDistanceMaxAlpha_14, _GlobalMaskDistanceMin_14, _GlobalMaskDistanceMax_14, _GlobalMaskDistanceBlendType_14, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_15==0
					handleGlobalMaskDistance(15, _GlobalMaskDistanceEnable_15, _GlobalMaskDistanceType_15, _GlobalMaskDistanceMinAlpha_15, _GlobalMaskDistanceMaxAlpha_15, _GlobalMaskDistanceMin_15, _GlobalMaskDistanceMax_15, _GlobalMaskDistanceBlendType_15, poiMesh, poiMods);
					//endex
					
				}
				//endex
				
			}
			
			//ifex _GlobalMaskVertexColorRed==0 && _GlobalMaskVertexColorGreen==0 && _GlobalMaskVertexColorBlue==0 && _GlobalMaskVertexColorAlpha==0
			void ApplyGlobalMaskVertexColors(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				float4 vcol = poiMesh.vertexColor;
				if (_GlobalMaskVertexColorLinearSpace)
				{
					vcol.rgb = GammaToLinearSpace(vcol.rgb);
				}
				if (_GlobalMaskVertexColorRed > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorRed - 1, _GlobalMaskVertexColorRedBlendType, vcol.r);
				}
				if (_GlobalMaskVertexColorGreen > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorGreen - 1, _GlobalMaskVertexColorGreenBlendType, vcol.g);
				}
				if (_GlobalMaskVertexColorBlue > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorBlue - 1, _GlobalMaskVertexColorBlueBlendType, vcol.b);
				}
				if (_GlobalMaskVertexColorAlpha > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorAlpha - 1, _GlobalMaskVertexColorAlphaBlendType, vcol.a);
				}
			}
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#ifdef POI_UDIMDISCARD
			void applyUDIMDiscard(in VertexOut i)
			{
				if(_UDIMDiscardMode == 1) // Don't run if in vertex mode
				{
					float2 udim = floor(vertexUV(i, _UDIMDiscardUV));
					
					float isDiscarded = 0;
					float4 xMask = float4(  (udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					isDiscarded += (udim.y >= 0 && udim.y < 1) * dot(float4(_UDIMDiscardRow0_0, _UDIMDiscardRow0_1, _UDIMDiscardRow0_2, _UDIMDiscardRow0_3), xMask);
					isDiscarded += (udim.y >= 1 && udim.y < 2) * dot(float4(_UDIMDiscardRow1_0, _UDIMDiscardRow1_1, _UDIMDiscardRow1_2, _UDIMDiscardRow1_3), xMask);
					isDiscarded += (udim.y >= 2 && udim.y < 3) * dot(float4(_UDIMDiscardRow2_0, _UDIMDiscardRow2_1, _UDIMDiscardRow2_2, _UDIMDiscardRow2_3), xMask);
					isDiscarded += (udim.y >= 3 && udim.y < 4) * dot(float4(_UDIMDiscardRow3_0, _UDIMDiscardRow3_1, _UDIMDiscardRow3_2, _UDIMDiscardRow3_3), xMask);
					
					isDiscarded *= any(float4(udim.y >= 0, udim.y < 4, udim.x >= 0, udim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					const float threshold = 0.001;
					clip(threshold - isDiscarded); // Clip if discarded
				}
				
				return;
			}
			#endif
			//endex
			
			float2 calculatePolarCoordinate(in PoiMesh poiMesh)
			{
				float2 delta = poiMesh.uv[_PolarUV] - _PolarCenter;
				float radius = length(delta) * 2 * _PolarRadialScale;
				float angle = atan2(delta.x, delta.y);
				float phi = angle / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				angle = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				angle *= _PolarLengthScale;
				
				return float2(radius, angle + distance(poiMesh.uv[_PolarUV], _PolarCenter) * _PolarSpiralPower);
			}
			
			float2 MonoPanoProjection(float3 coords)
			{
				float3 normalizedCoords = normalize(coords);
				float latitude = acos(normalizedCoords.y);
				float longitude = atan2(normalizedCoords.z, normalizedCoords.x);
				float phi = longitude / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				longitude = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				longitude *= 2;
				float2 sphereCoords = float2(longitude, latitude) * float2(1.0, 1.0 / UNITY_PI);
				sphereCoords = float2(1.0, 1.0) - sphereCoords;
				return (sphereCoords + float4(0, 1 - unity_StereoEyeIndex, 1, 1.0).xy) * float4(0, 1 - unity_StereoEyeIndex, 1, 1.0).zw;
			}
			
			float2 StereoPanoProjection(float3 coords)
			{
				float3 normalizedCoords = normalize(coords);
				float latitude = acos(normalizedCoords.y);
				float longitude = atan2(normalizedCoords.z, normalizedCoords.x);
				float phi = longitude / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				longitude = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				longitude *= 2;
				float2 sphereCoords = float2(longitude, latitude) * float2(0.5, 1.0 / UNITY_PI);
				sphereCoords = float2(0.5, 1.0) - sphereCoords;
				return (sphereCoords + float4(0, 1 - unity_StereoEyeIndex, 1, 0.5).xy) * float4(0, 1 - unity_StereoEyeIndex, 1, 0.5).zw;
			}
			
			float2 calculateWorldUV(in PoiMesh poiMesh)
			{
				return float2(_UVModWorldPos0 != 3 ? poiMesh.worldPos[ _UVModWorldPos0] : 0.0f, _UVModWorldPos1 != 3 ? poiMesh.worldPos[_UVModWorldPos1] : 0.0f);
			}
			
			float2 calculatelocalUV(in PoiMesh poiMesh)
			{
				float localUVs[8];
				localUVs[0] = poiMesh.localPos.x;
				localUVs[1] = poiMesh.localPos.y;
				localUVs[2] = poiMesh.localPos.z;
				localUVs[3] = 0;
				localUVs[4] = poiMesh.vertexColor.r;
				localUVs[5] = poiMesh.vertexColor.g;
				localUVs[6] = poiMesh.vertexColor.b;
				localUVs[7] = poiMesh.vertexColor.a;
				
				return float2(localUVs[_UVModLocalPos0],localUVs[_UVModLocalPos1]);
			}
			
			float2 calculatePanosphereUV(in PoiMesh poiMesh)
			{
				float3 viewDirection = normalize(lerp(getCameraPosition().xyz, _WorldSpaceCameraPos.xyz, _PanoUseBothEyes) - poiMesh.worldPos.xyz) * - 1;
				return lerp(MonoPanoProjection(viewDirection), StereoPanoProjection(viewDirection), _StereoEnabled);
			}
			//ifex _EnableDistortion==0
			#ifdef USER_LUT
			float2 distortedUV(in PoiMesh poiMesh)
			{
				#if defined(PROP_DISTORTIONFLOWTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 flowVector = POI2D_SAMPLER_PAN(_DistortionFlowTexture, _MainTex, poiUV(poiMesh.uv[_DistortionFlowTextureUV], _DistortionFlowTexture_ST), _DistortionFlowTexturePan) * 2 - 1;
				#else
				float4 flowVector = -1;
				#endif
				
				#if defined(PROP_DISTORTIONFLOWTEXTURE1) || !defined(OPTIMIZER_ENABLED)
				float4 flowVector1 = POI2D_SAMPLER_PAN(_DistortionFlowTexture1, _MainTex, poiUV(poiMesh.uv[_DistortionFlowTexture1UV], _DistortionFlowTexture1_ST), _DistortionFlowTexture1Pan) * 2 - 1;
				#else
				float4 flowVector1 = -1;
				#endif
				
				#if defined(PROP_DISTORTIONMASK) || !defined(OPTIMIZER_ENABLED)
				half distortionMask = POI2D_SAMPLER_PAN(_DistortionMask, _MainTex, poiMesh.uv[_DistortionMaskUV], _DistortionMaskPan)[_DistortionMaskChannel];
				#else
				half distortionMask = 1;
				#endif
				
				half distortionStrength = _DistortionStrength;
				half distortionStrength1 = _DistortionStrength1;
				
				#ifdef POI_AUDIOLINK
				UNITY_BRANCH
				if (AudioLinkIsAvailable() && _EnableDistortionAudioLink && _AudioLinkAnimToggle)
				{
					distortionStrength += lerp(_DistortionStrengthAudioLink.x, _DistortionStrengthAudioLink.y, AudioLinkData(uint2(0, uint(_DistortionStrengthAudioLinkBand))).r);
					distortionStrength1 += lerp(_DistortionStrength1AudioLink.x, _DistortionStrength1AudioLink.y, AudioLinkData(uint2(0, uint(_DistortionStrength1AudioLinkBand))).r);
				}
				#endif
				
				flowVector *= distortionStrength;
				flowVector1 *= distortionStrength1;
				return poiMesh.uv[_DistortionUvToDistort] + ((flowVector.xy + flowVector1.xy) / 2) * distortionMask;
			}
			#endif
			//endex
			
			//ifex _PoiParallax==0
			#ifdef POI_PARALLAX
			inline float2 POM(in PoiLight poiLight, sampler2D heightMap, in PoiMesh poiMesh, float3 worldViewDir, float3 viewDirTan, int minSamples, int maxSamples, float parallax, float refPlane, float2 tilling, float2 curv)
			{
				#if defined(PROP_HEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float heightMask = POI2D_SAMPLER_PAN(_Heightmask, _linear_repeat, poiUV(poiMesh.uv[_HeightmaskUV], _Heightmask_ST), _HeightmaskPan)[_HeightmaskChannel];
				if (_HeightmaskInvert)
				{
					heightMask = 1 - heightMask;
				}
				#else
				float heightMask = 1;
				#endif
				
				float2 uvs = poiUV(poiMesh.uv[_HeightMapUV], _HeightMap_ST);
				float2 dx = ddx(uvs);
				float2 dy = ddy(uvs);
				float3 result = 0;
				int stepIndex = 0;
				int numSteps = (int)lerp(maxSamples, minSamples, saturate(dot(poiMesh.normals[0], worldViewDir)));
				float layerHeight = 1.0 / numSteps;
				float2 plane = parallax * heightMask * (viewDirTan.xy / viewDirTan.z);
				uvs += refPlane * plane;
				float2 deltaTex = -plane * layerHeight;
				float2 prevTexOffset = 0;
				float prevRayZ = 1.0f;
				float prevHeight = 0.0f;
				float2 currTexOffset = deltaTex;
				float currRayZ = 1.0f - layerHeight;
				float currHeight = 0.0f;
				float intersection = 0;
				float2 finalTexOffset = 0;
				while (stepIndex < numSteps + 1)
				{
					result.z = dot(curv, currTexOffset * currTexOffset);
					currHeight = tex2Dgrad(heightMap, uvs + currTexOffset, dx, dy).r * (1 - result.z);
					if (currHeight > currRayZ)
					{
						stepIndex = numSteps + 1;
					}
					else
					{
						stepIndex++;
						prevTexOffset = currTexOffset;
						prevRayZ = currRayZ;
						prevHeight = currHeight;
						currTexOffset += deltaTex;
						currRayZ -= layerHeight * (1 - result.z) * (1 + _CurvFix);
					}
				}
				int sectionSteps = 10;
				int sectionIndex = 0;
				float newZ = 0;
				float newHeight = 0;
				while (sectionIndex < sectionSteps)
				{
					intersection = (prevHeight - prevRayZ) / (prevHeight - currHeight + currRayZ - prevRayZ);
					finalTexOffset = prevTexOffset +intersection * deltaTex;
					newZ = prevRayZ - intersection * layerHeight;
					newHeight = tex2Dgrad(heightMap, uvs + finalTexOffset, dx, dy).r;
					if (newHeight > newZ)
					{
						currTexOffset = finalTexOffset;
						currHeight = newHeight;
						currRayZ = newZ;
						deltaTex = intersection * deltaTex;
						layerHeight = intersection * layerHeight;
					}
					else
					{
						prevTexOffset = finalTexOffset;
						prevHeight = newHeight;
						prevRayZ = newZ;
						deltaTex = (1 - intersection) * deltaTex;
						layerHeight = (1 - intersection) * layerHeight;
					}
					sectionIndex++;
				}
				#ifdef UNITY_PASS_SHADOWCASTER
				if (unity_LightShadowBias.z == 0.0)
				{
					#endif
					if (result.z > 1)
					clip(-1);
					#ifdef UNITY_PASS_SHADOWCASTER
				}
				#endif
				
				return uvs + finalTexOffset;
			}
			/*
			float2 ParallaxOffsetMultiStep(float surfaceHeight, float strength, float2 uv, float3 tangentViewDir)
			{
				float2 uvOffset = 0;
				float2 prevUVOffset = 0;
				float stepSize = 1.0 / _HeightSteps;
				float stepHeight = 1;
				float2 uvDelta = tangentViewDir.xy * (stepSize * strength);
				float prevStepHeight = stepHeight;
				float prevSurfaceHeight = surfaceHeight;
				
				[unroll(20)]
				for (int j = 1; j <= _HeightSteps && stepHeight > surfaceHeight; j++)
				{
					prevUVOffset = uvOffset;
					prevStepHeight = stepHeight;
					prevSurfaceHeight = surfaceHeight;
					uvOffset -= uvDelta;
					stepHeight -= stepSize;
					surfaceHeight = POI2D_SAMPLER_PAN(_Heightmap, _MainTex, poiUV(uv + uvOffset, _Heightmap_ST), _HeightmapPan) + _HeightOffset;
				}
				
				[unroll(3)]
				for (int k = 0; k < 3; k++)
				{
					uvDelta *= 0.5;
					stepSize *= 0.5;
					
					if (stepHeight < surfaceHeight)
					{
						uvOffset += uvDelta;
						stepHeight += stepSize;
					}
					else
					{
						uvOffset -= uvDelta;
						stepHeight -= stepSize;
					}
					surfaceHeight = POI2D_SAMPLER_PAN(_Heightmap, _MainTex, poiUV(uv + uvOffset, _Heightmap_ST), _HeightmapPan) + _HeightOffset;
				}
				return uvOffset;
			}
			*/
			void applyParallax(inout PoiMesh poiMesh, in PoiLight poiLight, in PoiCam poiCam)
			{
				/*
				half h = POI2D_SAMPLER_PAN(_Heightmap, _linear_repeat, poiUV(poiMesh.uv[_HeightmaskUV], _Heightmap_ST), _HeightmapPan).r + _HeightOffset;
				#if defined(PROP_HEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				half m = POI2D_SAMPLER_PAN(_Heightmask, _linear_repeat, poiUV(poiMesh.uv[_HeightmaskUV], _Heightmask_ST), _HeightmaskPan).r + _HeightOffset;
				#else
				half m = 1 + _HeightOffset;
				#endif
				h = clamp(h, 0, 0.999);
				m = lerp(m, 1 - m, _HeightmaskInvert);
				#if defined(OPTIMIZER_ENABLED)das
				poiMesh.uv[_ParallaxUV] += ParallaxOffsetMultiStep(h, _HeightStrength * m, poiMesh.uv[_HeightmapUV], tangentViewDir / tangentViewDir.z);
				#else
				float2 offset = ParallaxOffsetMultiStep(h, _HeightStrength * m, poiMesh.uv[_HeightmapUV], tangentViewDir / tangentViewDir.z);
				if (_ParallaxUV == 0)       poiMesh.uv[0] += offset;
				if (_ParallaxUV == 1)       poiMesh.uv[1] += offset;
				if (_ParallaxUV == 2)       poiMesh.uv[2] += offset;
				if (_ParallaxUV == 3)       poiMesh.uv[3] += offset;
				if (_ParallaxUV == 4)       poiMesh.uv[4] += offset;
				if (_ParallaxUV == 5)       poiMesh.uv[5] += offset;
				if (_ParallaxUV == 6)       poiMesh.uv[6] += offset;
				if (_ParallaxUV == 7)       poiMesh.uv[7] += offset;
				#endif
				*/
				
				#if defined(OPTIMIZER_ENABLED)
				poiMesh.uv[_ParallaxUV] = POM(poiLight, _HeightMap, poiMesh, poiCam.viewDir, poiCam.tangentViewDir, _HeightStepsMin, _HeightStepsMax, _HeightStrength, 0, _HeightMap_ST.xy, float2(_CurvatureU, _CurvatureV));
				#else
				float2 offset = POM(poiLight, _HeightMap, poiMesh, poiCam.viewDir, poiCam.tangentViewDir, _HeightStepsMin, _HeightStepsMax, _HeightStrength, 0, _HeightMap_ST.xy, float2(_CurvatureU, _CurvatureV));
				if (_ParallaxUV == 0)       poiMesh.uv[0] = offset;
				if (_ParallaxUV == 1)       poiMesh.uv[1] = offset;
				if (_ParallaxUV == 2)       poiMesh.uv[2] = offset;
				if (_ParallaxUV == 3)       poiMesh.uv[3] = offset;
				if (_ParallaxUV == 4)       poiMesh.uv[4] = offset;
				if (_ParallaxUV == 5)       poiMesh.uv[5] = offset;
				if (_ParallaxUV == 6)       poiMesh.uv[6] = offset;
				if (_ParallaxUV == 7)       poiMesh.uv[7] = offset;
				#endif
			}
			#endif
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#ifdef POI_BLACKLIGHTMASKING
			void calculateBlackLightMasks(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				#ifdef VERTEXLIGHT_ON
				for (int lightIndex = 0; lightIndex < 4; lightIndex++)
				{
					float3 lightPos = float3(unity_4LightPosX0[lightIndex], unity_4LightPosY0[lightIndex], unity_4LightPosZ0[lightIndex]);
					if (!distance(unity_LightColor[lightIndex].rgb, float3(0, 0, 0)))
					{
						if (_BlackLightMasking0GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking0Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking0GlobalMaskIndex - 1, _BlackLightMasking0GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking1GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking1Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking1GlobalMaskIndex - 1, _BlackLightMasking1GlobalMaskBlendType, smoothstep(_BlackLightMasking1Range.y, _BlackLightMasking1Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking2GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking2Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking2GlobalMaskIndex - 1, _BlackLightMasking2GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking3GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking3Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking3GlobalMaskIndex - 1, _BlackLightMasking3GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
					}
				}
				#else
				if (_BlackLightMasking0GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking0GlobalMaskIndex - 1, _BlackLightMasking0GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking1GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking1GlobalMaskIndex - 1, _BlackLightMasking1GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking2GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking2GlobalMaskIndex - 1, _BlackLightMasking2GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking3GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking3GlobalMaskIndex - 1, _BlackLightMasking3GlobalMaskBlendType, 0);
				}
				#endif
			}
			#endif
			//endex
			
			//ifex _DetailEnabled==0
			#ifdef FINALPASS
			void ApplyDetailColor(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				#if defined(PROP_DETAILTEX) || !defined(OPTIMIZER_ENABLED)
				half3 detailTexture = POI2D_SAMPLER_PAN_STOCHASTIC(_DetailTex, _MainTex, poiUV(poiMesh.uv[_DetailTexUV], _DetailTex_ST), _DetailTexPan, _DetailTexStochastic).rgb * poiThemeColor(poiMods, _DetailTint, _DetailTintThemeIndex);
				#else
				half3 detailTexture = 0.21763764082 * poiThemeColor(poiMods, _DetailTint, _DetailTintThemeIndex);
				#endif
				
				poiFragData.baseColor.rgb *= LerpWhiteTo(detailTexture * _DetailBrightness * unity_ColorSpaceDouble.rgb, poiMods.detailMask.r * _DetailTexIntensity);
			}
			
			void ApplyDetailNormal(inout PoiMods poiMods, inout PoiMesh poiMesh)
			{
				#if defined(PROP_DETAILMASK) || !defined(OPTIMIZER_ENABLED)
				poiMods.detailMask = POI2D_SAMPLER_PAN_STOCHASTIC(_DetailMask, _MainTex, poiUV(poiMesh.uv[_DetailMaskUV], _DetailMask_ST), _DetailMaskPan, _DetailMaskStochastic).rg;
				#else
				poiMods.detailMask = 1;
				#endif
				
				#ifdef POI_BACKFACE
				if (!poiMesh.isFrontFace)
				{
					poiMods.detailMask.rg *= _BackFaceDetailIntensity;
				}
				#endif
				
				if (_DetailTexGlobalMask > 0)
				{
					poiMods.detailMask.r = maskBlend(poiMods.detailMask.r, poiMods.globalMask[_DetailTexGlobalMask-1], _DetailTexGlobalMaskBlendType);
				}
				if (_DetailNormalGlobalMask > 0)
				{
					poiMods.detailMask.g = maskBlend(poiMods.detailMask.g, poiMods.globalMask[_DetailNormalGlobalMask-1], _DetailNormalGlobalMaskBlendType);
				}
				
				#if defined(PROP_DETAILNORMALMAP) || !defined(OPTIMIZER_ENABLED)
				half3 detailNormal = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_DetailNormalMap, _MainTex, poiUV(poiMesh.uv[_DetailNormalMapUV], _DetailNormalMap_ST), _DetailNormalMapPan, _DetailNormalMapStochastic), _DetailNormalMapScale * poiMods.detailMask.g);
				poiMesh.tangentSpaceNormal = BlendNormals(detailNormal, poiMesh.tangentSpaceNormal);
				#endif
			}
			#endif
			//endex
			
			//ifex _MainVertexColoringEnabled==0
			void applyVertexColor(inout PoiFragData poiFragData, PoiMesh poiMesh)
			{
				if (_MainVertexColoringEnabled)
				{
					#ifndef POI_PASS_OUTLINE
					float3 vertCol = lerp(poiMesh.vertexColor.rgb, GammaToLinearSpace(poiMesh.vertexColor.rgb), _MainVertexColoringLinearSpace);
					poiFragData.baseColor *= lerp(1, vertCol, _MainVertexColoring);
					#endif
					poiFragData.alpha *= lerp(1, poiMesh.vertexColor.a, _MainUseVertexColorAlpha);
				}
			}
			//endex
			
			//ifex _BackFaceEnabled!=1
			#ifdef POI_BACKFACE
			void ApplyBackFaceColor(inout PoiFragData poiFragData, in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				if (!poiMesh.isFrontFace)
				{
					float4 backFaceColor = _BackFaceColor;
					backFaceColor.rgb = poiThemeColor(poiMods, backFaceColor.rgb, _BackFaceColorThemeIndex);
					#if defined(PROP_BACKFACETEXTURE) || !defined(OPTIMIZER_ENABLED)
					backFaceColor *= POI2D_SAMPLER_PAN(_BackFaceTexture, _MainTex, poiUV(poiMesh.uv[_BackFaceTextureUV], _BackFaceTexture_ST), _BackFaceTexturePan);
					#endif
					backFaceColor.rgb = hueShift(backFaceColor.rgb, frac(_BackFaceHueShift + _BackFaceHueShiftSpeed * _Time.x) * _BackFaceHueShiftEnabled);
					
					float backFaceMask = 1;
					#if defined(PROP_BACKFACEMASK) || !defined(OPTIMIZER_ENABLED)
					backFaceMask *= POI2D_SAMPLER_PAN(_BackFaceMask, _MainTex, poiUV(poiMesh.uv[_BackFaceMaskUV], _BackFaceMask_ST), _BackFaceMaskPan)[_BackFaceMaskChannel];
					#endif
					if (!_BackFaceReplaceAlpha)
					{
						backFaceMask *= backFaceColor.a;
					}
					
					poiFragData.baseColor = lerp(poiFragData.baseColor, backFaceColor.rgb, backFaceMask);
					
					UNITY_BRANCH
					if (_BackFaceReplaceAlpha)
					{
						poiFragData.alpha = backFaceColor.a;
					}
					
					poiFragData.emission += backFaceColor.rgb * _BackFaceEmissionStrength * backFaceMask;
					poiMods.globalEmission = poiMods.globalEmission * _BackFaceEmissionLimiter;
				}
			}
			#endif
			//endex
			
			//ifex _RGBMaskEnabled==0
			
			void RGBABlendColor(inout PoiFragData poiFragData, in float mask, in float4 color, float emissionStrength, in float blendType, in float blendAdd, in float enabled)
			{
				if (!enabled) return;
				float alpha = mask * saturate(color.a + blendAdd);
				poiFragData.baseColor = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, color.rgb, blendType), alpha);
				poiFragData.emission += color.rgb * emissionStrength * alpha;
			}
			
			void RGBABlendNormals(inout float3 tangentSpaceNormal, float3 normalToBlendWith, float maskValue, int blendMode)
			{
				if (blendMode == 0)
				{
					tangentSpaceNormal = lerp(tangentSpaceNormal, normalToBlendWith, maskValue);
				}
				else
				{
					tangentSpaceNormal = BlendNormals(tangentSpaceNormal, normalToBlendWith);
				}
			}
			
			#ifdef VIGNETTE
			#if !defined(UNITY_PASS_SHADOWCASTER) && !defined(POI_PASS_OUTLINE)
			void calculateRGBNormals(inout PoiMesh poiMesh, inout PoiMods poiMods)
			{
				// Only define this if we actually have any normal map textures. Can't do the same in color textures because users can tint
				#if defined(PROP_RGBNORMALR) || defined(PROP_RGBNORMALG) || defined(PROP_RGBNORMALB) || defined(PROP_RGBNORMALA) || !defined(OPTIMIZER_ENABLED)
				float4 rgbMask = 1;
				
				#if defined(PROP_RGBMASK) || !defined(OPTIMIZER_ENABLED)
				if (_RGBMaskType == 0)
				{
					rgbMask = POI2D_SAMPLER_PAN(_RGBMask, _trilinear_repeat, poiUV(poiMesh.uv[_RGBMaskUV], _RGBMask_ST), _RGBMaskPan);
				}
				#endif
				
				if (_RGBMaskType == 1)
				{
					rgbMask = poiMesh.vertexColor;
				}
				
				float4 maskFinal = 1;
				maskFinal.r = rgbMask[_RgbNormalRMaskChannel];
				maskFinal.g = rgbMask[_RgbNormalGMaskChannel];
				maskFinal.b = rgbMask[_RgbNormalBMaskChannel];
				maskFinal.a = rgbMask[_RgbNormalAMaskChannel];
				
				if (_RgbNormalRGlobalMaskChannel > 0) maskFinal.r = customBlend(maskFinal.r, poiMods.globalMask[_RgbNormalRGlobalMaskChannel - 1], _RgbNormalRGlobalMaskBlendType);
				if (_RgbNormalGGlobalMaskChannel > 0) maskFinal.g = customBlend(maskFinal.g, poiMods.globalMask[_RgbNormalGGlobalMaskChannel - 1], _RgbNormalGGlobalMaskBlendType);
				if (_RgbNormalBGlobalMaskChannel > 0) maskFinal.b = customBlend(maskFinal.b, poiMods.globalMask[_RgbNormalBGlobalMaskChannel - 1], _RgbNormalBGlobalMaskBlendType);
				if (_RgbNormalAGlobalMaskChannel > 0) maskFinal.a = customBlend(maskFinal.a, poiMods.globalMask[_RgbNormalAGlobalMaskChannel - 1], _RgbNormalAGlobalMaskBlendType);
				
				#if defined(PROP_RGBNORMALR) || !defined(OPTIMIZER_ENABLED)
				if (_RgbNormalRScale > 0 && _RGBARedEnable)
				{
					float3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_RgbNormalR, _trilinear_repeat, poiUV(poiMesh.uv[_RgbNormalRUV], _RgbNormalR_ST), _RgbNormalRPan, _RgbNormalRStochastic), _RgbNormalRedBlendMode == 0 ? _RgbNormalRScale : _RgbNormalRScale * maskFinal.r);
					RGBABlendNormals(poiMesh.tangentSpaceNormal, normalToBlendWith, maskFinal.r, _RgbNormalRedBlendMode);
				}
				#endif
				#if defined(PROP_RGBNORMALG) || !defined(OPTIMIZER_ENABLED)
				if (_RgbNormalGScale > 0 && _RGBAGreenEnable)
				{
					float3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_RgbNormalG, _trilinear_repeat, poiUV(poiMesh.uv[_RgbNormalGUV], _RgbNormalG_ST), _RgbNormalGPan, _RgbNormalGStochastic), _RgbNormalGreenBlendMode == 0 ? _RgbNormalGScale : _RgbNormalGScale * maskFinal.g);
					RGBABlendNormals(poiMesh.tangentSpaceNormal, normalToBlendWith, maskFinal.g, _RgbNormalGreenBlendMode);
				}
				#endif
				#if defined(PROP_RGBNORMALB) || !defined(OPTIMIZER_ENABLED)
				if (_RgbNormalBScale > 0 && _RGBABlueEnable)
				{
					float3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_RgbNormalB, _trilinear_repeat, poiUV(poiMesh.uv[_RgbNormalBUV], _RgbNormalB_ST), _RgbNormalBPan, _RgbNormalBStochastic), _RgbNormalBlueBlendMode == 0 ? _RgbNormalBScale : _RgbNormalBScale * maskFinal.b);
					RGBABlendNormals(poiMesh.tangentSpaceNormal, normalToBlendWith, maskFinal.b, _RgbNormalBlueBlendMode);
				}
				#endif
				#if defined(PROP_RGBNORMALA) || !defined(OPTIMIZER_ENABLED)
				if (_RgbNormalAScale > 0 && _RGBAAlphaEnable)
				{
					float3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_RgbNormalA, _trilinear_repeat, poiUV(poiMesh.uv[_RgbNormalAUV], _RgbNormalA_ST), _RgbNormalAPan, _RgbNormalAStochastic), _RgbNormalAlphaBlendMode == 0 ? _RgbNormalAScale : _RgbNormalAScale * maskFinal.a);
					RGBABlendNormals(poiMesh.tangentSpaceNormal, normalToBlendWith, maskFinal.a, _RgbNormalAlphaBlendMode);
				}
				#endif
				#endif
			}
			#endif
			
			void calculateRGBMask(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float4 rgbMask = float4(1, 1, 1, 1);
				float4 red = float4(poiThemeColor(poiMods, _RedColor.rgb, _RedColorThemeIndex), _RedColor.a);
				float4 green = float4(poiThemeColor(poiMods, _GreenColor.rgb, _GreenColorThemeIndex), _GreenColor.a);
				float4 blue = float4(poiThemeColor(poiMods, _BlueColor.rgb, _BlueColorThemeIndex), _BlueColor.a);
				float4 alpha = float4(poiThemeColor(poiMods, _AlphaColor.rgb, _AlphaColorThemeIndex), _AlphaColor.a);
				
				#if defined(PROP_RGBMASK) || !defined(OPTIMIZER_ENABLED)
				if (_RGBMaskType == 0)
				{
					rgbMask = POI2D_SAMPLER_PAN(_RGBMask, _trilinear_repeat, poiUV(poiMesh.uv[_RGBMaskUV], _RGBMask_ST), _RGBMaskPan);
				}
				#endif
				
				if (_RGBMaskType == 1)
				{
					rgbMask = poiMesh.vertexColor;
				}
				
				#if defined(PROP_REDTEXTURE) || !defined(OPTIMIZER_ENABLED)
				red *= POI2D_SAMPLER_PAN_STOCHASTIC(_RedTexture, _trilinear_repeat, poiUV(poiMesh.uv[_RedTextureUV], _RedTexture_ST), _RedTexturePan.xy, _RedTextureStochastic);
				#endif
				#if defined(PROP_GREENTEXTURE) || !defined(OPTIMIZER_ENABLED)
				green *= POI2D_SAMPLER_PAN_STOCHASTIC(_GreenTexture, _trilinear_repeat, poiUV(poiMesh.uv[_GreenTextureUV], _GreenTexture_ST), _GreenTexturePan.xy, _GreenTextureStochastic);
				#endif
				#if defined(PROP_BLUETEXTURE) || !defined(OPTIMIZER_ENABLED)
				blue *= POI2D_SAMPLER_PAN_STOCHASTIC(_BlueTexture, _trilinear_repeat, poiUV(poiMesh.uv[_BlueTextureUV], _BlueTexture_ST), _BlueTexturePan.xy, _BlueTextureStochastic);
				#endif
				#if defined(PROP_ALPHATEXTURE) || !defined(OPTIMIZER_ENABLED)
				alpha *= POI2D_SAMPLER_PAN_STOCHASTIC(_AlphaTexture, _trilinear_repeat, poiUV(poiMesh.uv[_AlphaTextureUV], _AlphaTexture_ST), _AlphaTexturePan.xy, _AlphaTextureStochastic);
				#endif
				
				RGBABlendColor(poiFragData, globalMaskBlend(rgbMask[_RgbRedMaskChannel], _RgbRedGlobalMaskChannel, _RgbRedGlobalMaskBlendType, poiMods), red, _RGBARedEmissionStrength, _RGBARedBlendType, _RedAlphaAdd, _RGBARedEnable);
				RGBABlendColor(poiFragData, globalMaskBlend(rgbMask[_RgbGreenMaskChannel], _RgbGreenGlobalMaskChannel, _RgbGreenGlobalMaskBlendType, poiMods), green, _RGBAGreenEmissionStrength, _RGBAGreenBlendType, _GreenAlphaAdd, _RGBAGreenEnable);
				RGBABlendColor(poiFragData, globalMaskBlend(rgbMask[_RgbBlueMaskChannel], _RgbBlueGlobalMaskChannel, _RgbBlueGlobalMaskBlendType, poiMods), blue, _RGBABlueEmissionStrength, _RGBABlueBlendType, _BlueAlphaAdd, _RGBABlueEnable);
				RGBABlendColor(poiFragData, globalMaskBlend(rgbMask[_RgbAlphaMaskChannel], _RgbAlphaGlobalMaskChannel, _RgbAlphaGlobalMaskBlendType, poiMods), alpha, _RGBAAlphaEmissionStrength, _RGBAAlphaBlendType, _AlphaAlphaAdd, _RGBAAlphaEnable);
				
				if (_RGBAPBRRedEnabled || _RGBAPBRGreenEnabled || _RGBAPBRBlueEnabled || _RGBAPBRAlphaEnabled)
				{
					#if defined(PROP_RGBASMOOTHNESSMAPS) || !defined(OPTIMIZER_ENABLED)
					float4 smoothnessMaps = 1;
					if (!_RGBARedPBRSplitMaskSample || !_RGBAGreenPBRSplitMaskSample || !_RGBABluePBRSplitMaskSample || !_RGBAAlphaPBRSplitMaskSample)
					{
						smoothnessMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBASmoothnessMapsUV], _RGBASmoothnessMaps_ST), _RGBASmoothnessMapsPan.xy, _RGBASmoothnessMapsStochastic);
					}
					
					if (_RGBARedPBRSplitMaskSample && _RGBAPBRRedEnabled && _RGBARedEnable)
					{
						smoothnessMaps.r = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBARedPBRUV], _RGBARedPBRMaskScaleTiling), _RGBARedPBRMasksPan.xy, _RGBARedPBRSplitMaskStochastic).r;
					}
					if (_RGBAGreenPBRSplitMaskSample && _RGBAPBRGreenEnabled && _RGBAGreenEnable)
					{
						smoothnessMaps.g = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAGreenPBRUV], _RGBAGreenPBRMaskScaleTiling), _RGBAGreenPBRMasksPan.xy, _RGBAGreenPBRSplitMaskStochastic).g;
					}
					if (_RGBABluePBRSplitMaskSample && _RGBAPBRBlueEnabled && _RGBABlueEnable)
					{
						smoothnessMaps.b = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBABluePBRUV], _RGBABluePBRMaskScaleTiling), _RGBABluePBRMasksPan.xy, _RGBABluePBRSplitMaskStochastic).b;
					}
					if (_RGBAAlphaPBRSplitMaskSample && _RGBAPBRAlphaEnabled && _RGBAAlphaEnable)
					{
						smoothnessMaps.a = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAAlphaPBRUV], _RGBAAlphaPBRMaskScaleTiling), _RGBAAlphaPBRMasksPan.xy, _RGBAAlphaPBRSplitMaskStochastic).a;
					}
					
					poiFragData.smoothness = lerp(poiFragData.smoothness, poiInvertToggle(smoothnessMaps.r, _RGBARedSmoothnessInvert), rgbMask[_RgbRedMaskChannel] * (_RGBAPBRRedEnabled && _RGBARedEnable));
					poiFragData.smoothness = lerp(poiFragData.smoothness, poiInvertToggle(smoothnessMaps.g, _RGBAGreenSmoothnessInvert), rgbMask[_RgbGreenMaskChannel] * (_RGBAPBRGreenEnabled && _RGBAGreenEnable));
					poiFragData.smoothness = lerp(poiFragData.smoothness, poiInvertToggle(smoothnessMaps.b, _RGBABlueSmoothnessInvert), rgbMask[_RgbBlueMaskChannel] * (_RGBAPBRBlueEnabled && _RGBABlueEnable));
					poiFragData.smoothness = lerp(poiFragData.smoothness, poiInvertToggle(smoothnessMaps.a, _RGBAAlphaSmoothnessInvert), rgbMask[_RgbAlphaMaskChannel] * (_RGBAPBRAlphaEnabled && _RGBAAlphaEnable));
					#endif
					
					#if defined(PROP_RGBAMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
					float4 metallicMaps = 1;
					if (!_RGBARedPBRSplitMaskSample || !_RGBAGreenPBRSplitMaskSample || !_RGBABluePBRSplitMaskSample || !_RGBAAlphaPBRSplitMaskSample)
					{
						metallicMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAMetallicMapsUV], _RGBAMetallicMaps_ST), _RGBAMetallicMapsPan.xy, _RGBAMetallicMapsStochastic);
					}
					
					if (_RGBARedPBRSplitMaskSample && _RGBAPBRRedEnabled && _RGBARedEnable)
					{
						metallicMaps.r = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBARedPBRUV], _RGBARedPBRMaskScaleTiling), _RGBARedPBRMasksPan.xy, _RGBARedPBRSplitMaskStochastic).r;
					}
					if (_RGBAGreenPBRSplitMaskSample && _RGBAPBRGreenEnabled && _RGBAGreenEnable)
					{
						metallicMaps.g = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAGreenPBRUV], _RGBAGreenPBRMaskScaleTiling), _RGBAGreenPBRMasksPan.xy, _RGBAGreenPBRSplitMaskStochastic).g;
					}
					if (_RGBABluePBRSplitMaskSample && _RGBAPBRBlueEnabled && _RGBABlueEnable)
					{
						metallicMaps.b = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBABluePBRUV], _RGBABluePBRMaskScaleTiling), _RGBABluePBRMasksPan.xy, _RGBABluePBRSplitMaskStochastic).b;
					}
					if (_RGBAAlphaPBRSplitMaskSample && _RGBAPBRAlphaEnabled && _RGBAAlphaEnable)
					{
						metallicMaps.a = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAAlphaPBRUV], _RGBAAlphaPBRMaskScaleTiling), _RGBAAlphaPBRMasksPan.xy, _RGBAAlphaPBRSplitMaskStochastic).a;
					}
					
					poiFragData.metallic = lerp(poiFragData.metallic, poiInvertToggle(metallicMaps.r, _RGBARedMetallicInvert), rgbMask[_RgbRedMaskChannel] * (_RGBAPBRRedEnabled && _RGBARedEnable));
					poiFragData.metallic = lerp(poiFragData.metallic, poiInvertToggle(metallicMaps.g, _RGBAGreenMetallicInvert), rgbMask[_RgbGreenMaskChannel] * (_RGBAPBRGreenEnabled && _RGBAGreenEnable));
					poiFragData.metallic = lerp(poiFragData.metallic, poiInvertToggle(metallicMaps.b, _RGBABlueMetallicInvert), rgbMask[_RgbBlueMaskChannel] * (_RGBAPBRBlueEnabled && _RGBABlueEnable));
					poiFragData.metallic = lerp(poiFragData.metallic, poiInvertToggle(metallicMaps.a, _RGBAAlphaMetallicInvert), rgbMask[_RgbAlphaMaskChannel] * (_RGBAPBRAlphaEnabled && _RGBAAlphaEnable));
					#endif
				}
			}
			#endif
			//endex
			
			//ifex _ShadingEnabled==0
			#ifdef VIGNETTE_MASKED
			
			#ifdef _LIGHTINGMODE_CLOTH
			float V_SmithGGXCorrelated(float roughness, float NoV, float NoL)
			{
				// Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"
				float a2 = roughness * roughness;
				// TODO: lambdaV can be pre-computed for all the lights, it should be moved out of this function
				float lambdaV = NoL * sqrt((NoV - a2 * NoV) * NoV + a2);
				float lambdaL = NoV * sqrt((NoL - a2 * NoL) * NoL + a2);
				float v = 0.5 / (lambdaV + lambdaL);
				// a2=0 => v = 1 / 4*NoL*NoV   => min=1/4, max=+inf
				// a2=1 => v = 1 / 2*(NoL+NoV) => min=1/4, max=+inf
				// clamp to the maximum value representable in mediump
				return v;
			}
			
			float D_GGX(float roughness, float NoH)
			{
				// Walter et al. 2007, "Microfacet Models for Refraction through Rough Surfaces"
				
				// In mediump, there are two problems computing 1.0 - NoH^2
				// 1) 1.0 - NoH^2 suffers floating point cancellation when NoH^2 is close to 1 (highlights)
				// 2) NoH doesn't have enough precision around 1.0
				// Both problem can be fixed by computing 1-NoH^2 in highp and providing NoH in highp as well
				
				// However, we can do better using Lagrange's identity:
				//      ||a x b||^2 = ||a||^2 ||b||^2 - (a . b)^2
				// since N and H are unit vectors: ||N x H||^2 = 1.0 - NoH^2
				// This computes 1.0 - NoH^2 directly (which is close to zero in the highlights and has
				// enough precision).
				// Overall this yields better performance, keeping all computations in mediump
				float oneMinusNoHSquared = 1.0 - NoH * NoH;
				
				float a = NoH * roughness;
				float k = roughness / (oneMinusNoHSquared + a * a);
				float d = k * k * (1.0 / UNITY_PI);
				return d;
			}
			
			// https://github.com/google/filament/blob/main/shaders/src/brdf.fs#L94-L100
			float D_Charlie(float roughness, float NoH)
			{
				// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF"
				float invAlpha = 1.0 / roughness;
				float cos2h = NoH * NoH;
				float sin2h = max(1.0 - cos2h, 0.0078125); // 0.0078125 = 2^(-14/2), so sin2h^2 > 0 in fp16
				return (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * UNITY_PI);
			}
			
			// https://github.com/google/filament/blob/main/shaders/src/brdf.fs#L136-L139
			float V_Neubelt(float NoV, float NoL)
			{
				// Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886"
				return 1.0 / (4.0 * (NoL + NoV - NoL * NoV));
			}
			
			float Distribution(float roughness, float NoH, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(GGXTerm(roughness, NoH), D_Charlie(roughness, NoH), cloth);
				}
				//endex
				return cloth <= 0.5 ? GGXTerm(roughness, NoH) : D_Charlie(roughness, NoH);
			}
			
			float Visibility(float roughness, float NoV, float NoL, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(V_SmithGGXCorrelated(roughness, NoV, NoL), V_Neubelt(NoV, NoL), cloth);
				}
				//endex
				return cloth <= 0.5 ? V_SmithGGXCorrelated(roughness, NoV, NoL) : V_Neubelt(NoV, NoL);
			}
			
			float F_Schlick(float3 f0, float f90, float VoH)
			{
				// Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"
				return f0 + (f90 - f0) * pow(1.0 - VoH, 5);
			}
			
			float F_Schlick(float3 f0, float VoH)
			{
				float f = pow(1.0 - VoH, 5.0);
				return f + f0 * (1.0 - f);
			}
			
			float Fresnel(float3 f0, float LoH)
			{
				float f90 = saturate(dot(f0, float(50.0 * 0.33).xxx));
				return F_Schlick(f0, f90, LoH);
			}
			
			float Fd_Burley(float roughness, float NoV, float NoL, float LoH)
			{
				// Burley 2012, "Physically-Based Shading at Disney"
				float f90 = 0.5 + 2.0 * roughness * LoH * LoH;
				float lightScatter = F_Schlick(1.0, f90, NoL);
				float viewScatter = F_Schlick(1.0, f90, NoV);
				return lightScatter * viewScatter;
			}
			
			// Energy conserving wrap diffuse term, does *not* include the divide by PI
			float Fd_Wrap(float NoL, float w)
			{
				return saturate((NoL + w) / pow(1.0 + w, 2));
			}
			
			float4 SampleDFG(float NoV, float perceptualRoughness)
			{
				return _ClothDFG.Sample(sampler_ClothDFG, float3(NoV, perceptualRoughness, 0));
			}
			
			float3 EnvBRDF(float2 dfg, float3 f0)
			{
				return f0 * dfg.x + dfg.y;
			}
			
			float3 EnvBRDFMultiscatter(float3 dfg, float3 f0, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(lerp(dfg.xxx, dfg.yyy, f0), f0 * dfg.z, cloth);
				}
				//endex
				return cloth <= 0.5 ? lerp(dfg.xxx, dfg.yyy, f0) : f0 * dfg.z;
			}
			
			float3 EnvBRDFEnergyCompensation(float3 dfg, float3 f0, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(1.0 + f0 * (1.0 / dfg.y - 1.0), 1, cloth);
				}
				//endex
				return cloth <= 0.5 ? 1.0 + f0 * (1.0 / dfg.y - 1.0) : 1;
			}
			
			//
			float ClothMetallic(float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return cloth;
				}
				//endex
				return cloth <= 0.5 ? 1 : 0;
			}
			
			float3 Specular(float roughness, PoiLight poiLight, float f0, float3 normal, float cloth)
			{
				float NoL = poiLight.nDotLSaturated;
				float NoH = poiLight.nDotH;
				float LoH = poiLight.lDotH;
				float NoV = poiLight.nDotV;
				
				float D = Distribution(roughness, NoH, cloth);
				float V = Visibility(roughness, NoV, NoL, cloth);
				float3 F = Fresnel(f0, LoH);
				
				return (D * V) * F;
			}
			
			float3 getBoxProjection(float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax)
			{
				#if UNITY_SPECCUBE_BOX_PROJECTION
				if (cubemapPosition.w > 0)
				{
					float3 factors = ((direction > 0 ? boxMax : boxMin) - position) / direction;
					float scalar = min(min(factors.x, factors.y), factors.z);
					direction = direction * scalar + (position - cubemapPosition.xyz);
				}
				#endif
				
				return direction;
			}
			
			float SpecularAO(float NoV, float ao, float roughness)
			{
				return clamp(pow(NoV + ao, exp2(-16.0 * roughness - 1.0)) - 1.0 + ao, 0.0, 1.0);
			}
			
			float3 IndirectSpecular(float3 dfg, float roughness, float occlusion, float energyCompensation, float cloth, float3 indirectDiffuse, float f0, PoiLight poiLight, PoiFragData poiFragData, PoiCam poiCam, PoiMesh poiMesh)
			{
				float3 normal = poiMesh.normals[1];
				
				float3 reflDir = reflect(-poiCam.viewDir, normal);
				
				Unity_GlossyEnvironmentData envData;
				envData.roughness = roughness;
				envData.reflUVW = getBoxProjection(reflDir, poiMesh.worldPos, unity_SpecCube0_ProbePosition,
				unity_SpecCube0_BoxMin.xyz, unity_SpecCube0_BoxMax.xyz);
				
				float3 probe0 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE(unity_SpecCube0), unity_SpecCube0_HDR, envData);
				float3 indirectSpecular = probe0;
				
				#if UNITY_SPECCUBE_BLENDING
				UNITY_BRANCH
				if (unity_SpecCube0_BoxMin.w < 0.99999)
				{
					envData.reflUVW = getBoxProjection(reflDir, poiMesh.worldPos, unity_SpecCube1_ProbePosition, unity_SpecCube1_BoxMin.xyz, unity_SpecCube1_BoxMax.xyz);
					float3 probe1 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1, unity_SpecCube0), unity_SpecCube1_HDR, envData);
					indirectSpecular = lerp(probe1, probe0, unity_SpecCube0_BoxMin.w);
				}
				#endif
				
				float horizon = min(1 + dot(reflDir, normal), 1);
				indirectSpecular = indirectSpecular * horizon * horizon * energyCompensation * EnvBRDFMultiscatter(dfg, f0, cloth);
				
				indirectSpecular *= SpecularAO(poiLight.nDotV, occlusion, roughness);
				return indirectSpecular;
			};
			#endif
			
			#ifdef _LIGHTINGMODE_WRAPPED
			// Wrapped
			// Green’s model with adjustable energy
			// http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/
			// Modified for adjustable conservation ratio and over-wrap to directionless
			float RTWrapFunc(in float dt, in float w, in float norm)
			{
				float cw = saturate(w);
				
				float o = (dt + cw) / ((1.0 + cw) * (1.0 + cw * norm));
				float flt = 1.0 - 0.85 * norm;
				if (w > 1.0)
				{
					o = lerp(o, flt, w - 1.0);
				}
				return o;
			}
			
			float3 GreenWrapSH(float fA) // Greens unoptimized and non-normalized
			
			{
				float fAs = saturate(fA);
				float4 t = float4(fA + 1, fAs - 1, fA - 2, fAs + 1); // DJL edit: allow wrapping to L0-only at w=2
				return float3(t.x, -t.z * t.x / 3, 0.25 * t.y * t.y * t.w);
			}
			float3 GreenWrapSHOpt(float fW) // optimised and normalized https://blog.selfshadow.com/2012/01/07/righting-wrap-part-2/
			
			{
				const float4 t0 = float4(0.0, 1.0 / 4.0, -1.0 / 3.0, -1.0 / 2.0);
				const float4 t1 = float4(1.0, 2.0 / 3.0, 1.0 / 4.0, 0.0);
				float3 fWs = float3(fW, fW, saturate(fW)); // DJL edit: allow wrapping to L0-only at w=2
				
				float3 r;
				r.xyz = t0.xxy * fWs + t0.xzw;
				r.xyz = r.xyz * fWs + t1.xyz;
				return r;
			}
			float3 ShadeSH9_wrapped(float3 normal, float wrap)
			{
				float3 x0, x1, x2;
				float3 conv = lerp(GreenWrapSH(wrap), GreenWrapSHOpt(wrap), _LightingWrappedNormalization); // Should try optimizing this...
				conv *= float3(1, 1.5, 4); // Undo pre-applied cosine convolution by using the inverse
				
				// Constant (L0)
				x0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
				// Remove pre-applied constant part from L(2,0) to apply correct convolution
				float3 L2_0 = float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / - 3.0;
				x0 -= L2_0;
				
				// Linear (L1) polynomial terms
				x1.r = dot(unity_SHAr.xyz, normal);
				x1.g = dot(unity_SHAg.xyz, normal);
				x1.b = dot(unity_SHAb.xyz, normal);
				
				// 4 of the quadratic (L2) polynomials
				float4 vB = normal.xyzz * normal.yzzx;
				x2.r = dot(unity_SHBr, vB);
				x2.g = dot(unity_SHBg, vB);
				x2.b = dot(unity_SHBb, vB);
				
				// Final (5th) quadratic (L2) polynomial
				float vC = normal.x * normal.x - normal.y * normal.y;
				x2 += unity_SHC.rgb * vC;
				// Move back the constant part of L(2,0)
				x2 += L2_0;
				
				return x0 * conv.x + x1 * conv.y + x2 * conv.z;
			}
			
			float3 GetSHDirectionL1()
			{
				// For efficiency, we only get the direction from L1.
				// Because getting it from L2 would be too hard!
				return Unity_SafeNormalize((unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz));
			}
			// Returns the value from SH in the lighting direction with the
			// brightest intensity.
			half3 GetSHMaxL1()
			{
				float3 maxDirection = GetSHDirectionL1();
				return ShadeSH9_wrapped(maxDirection, 0);
			}
			#endif
			
			#ifdef _LIGHTINGMODE_SHADEMAP
			void applyShadeMapping(inout PoiFragData poiFragData, PoiMesh poiMesh, inout PoiLight poiLight)
			{
				float shadowAttenuation = lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				float attenuation = 1;
				#if defined(POINT) || defined(SPOT)
				shadowAttenuation = lerp(1, poiLight.additiveShadow, poiLight.attenuationStrength);
				//attenuation = poiLight.attenuation;
				#endif
				
				float MainColorFeatherStep = _BaseColor_Step - _BaseShade_Feather;
				float firstColorFeatherStep = _ShadeColor_Step - _1st2nd_Shades_Feather;
				
				#if defined(PROP_1ST_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
				float4 firstShadeMap = POI2D_SAMPLER_PAN(_1st_ShadeMap, _MainTex, poiUV(poiMesh.uv[_1st_ShadeMapUV], _1st_ShadeMap_ST), _1st_ShadeMapPan);
				#else
				float4 firstShadeMap = float4(1, 1, 1, 1);
				#endif
				firstShadeMap = lerp(firstShadeMap, float4(poiFragData.baseColor, 1), _Use_BaseAs1st);
				
				#if defined(PROP_2ND_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
				float4 secondShadeMap = POI2D_SAMPLER_PAN(_2nd_ShadeMap, _MainTex, poiUV(poiMesh.uv[_2nd_ShadeMapUV], _2nd_ShadeMap_ST), _2nd_ShadeMapPan);
				#else
				float4 secondShadeMap = float4(1, 1, 1, 1);
				#endif
				secondShadeMap = lerp(secondShadeMap, firstShadeMap, _Use_1stAs2nd);
				
				firstShadeMap.rgb *= _1st_ShadeColor.rgb; //* lighColor
				secondShadeMap.rgb *= _2nd_ShadeColor.rgb; //* LightColor;
				
				float shadowMask = 1;
				shadowMask *= _Use_1stShadeMapAlpha_As_ShadowMask ? (_1stShadeMapMask_Inverse ? (1.0 - firstShadeMap.a) : firstShadeMap.a) : 1;
				shadowMask *= _Use_2ndShadeMapAlpha_As_ShadowMask ? (_2ndShadeMapMask_Inverse ? (1.0 - secondShadeMap.a) : secondShadeMap.a) : 1;
				
				float mainShadowMask = saturate(1 - ((poiLight.lightMap) - MainColorFeatherStep) / (_BaseColor_Step - MainColorFeatherStep) * (shadowMask));
				float firstSecondShadowMask = saturate(1 - ((poiLight.lightMap) - firstColorFeatherStep) / (_ShadeColor_Step - firstColorFeatherStep) * (shadowMask));
				
				mainShadowMask *= poiLight.shadowMask * _ShadowStrength;
				firstSecondShadowMask *= poiLight.shadowMask * _ShadowStrength;
				
				// 0 lerp | 1 multiply
				if (_ShadingShadeMapBlendType == 0)
				{
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, lerp(firstShadeMap.rgb, secondShadeMap.rgb, firstSecondShadowMask), mainShadowMask) * attenuation;
				}
				else
				{
					poiFragData.baseColor.rgb *= lerp(1, lerp(firstShadeMap.rgb, secondShadeMap.rgb, firstSecondShadowMask), mainShadowMask) * attenuation;
				}
				poiLight.rampedLightMap = 1 - mainShadowMask;
			}
			#endif
			
			#ifdef _LIGHTINGMODE_REALISTIC
			// For https://docs.unity3d.com/Manual/LightMode-Mixed-Subtractive.html
			#if defined(LIGHTMAP_ON) && defined(SHADOWS_SCREEN)
			#if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK)
			#define SUBTRACTIVE_LIGHTING 1
			#endif
			#endif
			
			void ApplySubtractiveLighting(inout UnityIndirect indirectLight)
			{
				#if SUBTRACTIVE_LIGHTING
				poiLight.attenuation = FadeShadows(lerp(1, poiLight.attenuation, _AttenuationMultiplier));
				
				float ndotl = saturate(dot(i.normal, _WorldSpaceLightPos0.xyz));
				float3 shadowedLightEstimate = ndotl * (1 - poiLight.attenuation) * _LightColor0.rgb;
				float3 subtractedLight = indirectLight.diffuse - shadowedLightEstimate;
				subtractedLight = max(subtractedLight, unity_ShadowColor.rgb);
				subtractedLight = lerp(subtractedLight, indirectLight.diffuse, _LightShadowData.x);
				indirectLight.diffuse = min(subtractedLight, indirectLight.diffuse);
				#endif
			}
			
			UnityIndirect CreateIndirectLight(in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight)
			{
				UnityIndirect indirectLight;
				indirectLight.diffuse = 0;
				indirectLight.specular = 0;
				
				#if defined(LIGHTMAP_ON)
				indirectLight.diffuse = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, poiMesh.lightmapUV.xy));
				
				#if defined(DIRLIGHTMAP_COMBINED)
				float4 lightmapDirection = UNITY_SAMPLE_TEX2D_SAMPLER(
				unity_LightmapInd, unity_Lightmap, poiMesh.lightmapUV.xy
				);
				indirectLight.diffuse = DecodeDirectionalLightmap(
				indirectLight.diffuse, lightmapDirection, poiMesh.normals[1]
				);
				#endif
				ApplySubtractiveLighting(indirectLight);
				#endif
				
				#if defined(DYNAMICLIGHTMAP_ON)
				float3 dynamicLightDiffuse = DecodeRealtimeLightmap(
				UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, poiMesh.lightmapUV.zw)
				);
				
				#if defined(DIRLIGHTMAP_COMBINED)
				float4 dynamicLightmapDirection = UNITY_SAMPLE_TEX2D_SAMPLER(
				unity_DynamicDirectionality, unity_DynamicLightmap,
				poiMesh.lightmapUV.zw
				);
				indirectLight.diffuse += DecodeDirectionalLightmap(
				dynamicLightDiffuse, dynamicLightmapDirection, poiMesh.normals[1]
				);
				#else
				indirectLight.diffuse += dynamicLightDiffuse;
				#endif
				#endif
				
				#if !defined(LIGHTMAP_ON) && !defined(DYNAMICLIGHTMAP_ON)
				#if UNITY_LIGHT_PROBE_PROXY_VOLUME
				if (unity_ProbeVolumeParams.x == 1)
				{
					indirectLight.diffuse = SHEvalLinearL0L1_SampleProbeVolume(
					float4(poiMesh.normals[1], 1), poiMesh.worldPos
					);
					indirectLight.diffuse = max(0, indirectLight.diffuse);
					#if defined(UNITY_COLORSPACE_GAMMA)
					indirectLight.diffuse = LinearToGammaSpace(indirectLight.diffuse);
					#endif
				}
				else
				{
					indirectLight.diffuse += max(0, ShadeSH9(float4(poiMesh.normals[1], 1)));
				}
				#else
				indirectLight.diffuse += max(0, ShadeSH9(float4(poiMesh.normals[1], 1)));
				#endif
				#endif
				
				indirectLight.diffuse *= poiLight.occlusion;
				
				return indirectLight;
			}
			#endif
			
			float GetRemapMinValue(float scale, float offset)
			{
				return clamp(-offset / scale, -0.01f, 1.01f); // Remap min
				
			}
			float GetRemapMaxValue(float scale, float offset)
			{
				return clamp((1.0f - offset) / scale, -0.01f, 1.01f); // Remap Max
				
			}
			
			void calculateShading(inout PoiLight poiLight, inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam)
			{
				float shadowAttenuation = lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				float attenuation = 1;
				#if defined(POINT) || defined(SPOT)
				shadowAttenuation = lerp(1, poiLight.additiveShadow, poiLight.attenuationStrength);
				//attenuation = poiLight.attenuation;
				#endif
				
				#ifdef POI_PASS_ADD
				if (_LightingAdditiveType == 3)
				{
					#if defined(POINT) || defined(SPOT)
					#if defined(_LIGHTINGMODE_REALISTIC) || defined(_LIGHTINGMODE_CLOTH) || defined(_LIGHTINGMODE_WRAPPED)
					poiLight.rampedLightMap = max(0, poiLight.nDotL);
					poiLight.finalLighting = poiLight.directColor * attenuation * max(0, poiLight.nDotL) * poiLight.detailShadow * shadowAttenuation;
					return;
					#endif
					#endif
				}
				// Realistic
				if (_LightingAdditiveType == 0)
				{
					poiLight.rampedLightMap = max(0, poiLight.nDotL);
					poiLight.finalLighting = poiLight.directColor * attenuation * max(0, poiLight.nDotL) * poiLight.detailShadow * shadowAttenuation;
					return;
				}
				// Toon
				if (_LightingAdditiveType == 1)
				{
					#if defined(POINT_COOKIE) || defined(DIRECTIONAL_COOKIE)
					float passthrough = 0;
					#else
					float passthrough = _LightingAdditivePassthrough;
					#endif
					
					float2 ToonAddGradient = float2(_LightingAdditiveGradientStart, _LightingAdditiveGradientEnd);
					
					if (ToonAddGradient.x == ToonAddGradient.y) ToonAddGradient.y += 0.0001;
					
					poiLight.rampedLightMap = smoothstep(ToonAddGradient.y, ToonAddGradient.x, 1 - (.5 * poiLight.nDotL + .5));
					#if defined(POINT) || defined(SPOT)
					poiLight.finalLighting = lerp(poiLight.directColor * max(min(poiLight.additiveShadow, poiLight.detailShadow), passthrough), poiLight.indirectColor, smoothstep(ToonAddGradient.x, ToonAddGradient.y, 1 - (.5 * poiLight.nDotL + .5)));
					#else
					poiLight.finalLighting = lerp(poiLight.directColor * max(min(poiLight.attenuation, poiLight.detailShadow), passthrough), poiLight.indirectColor, smoothstep(ToonAddGradient.x, ToonAddGradient.y, 1 - (.5 * poiLight.nDotL + .5)));
					#endif
					return;
				}
				#endif
				
				float shadowStrength = _ShadowStrength * poiLight.shadowMask;
				
				#ifdef POI_PASS_OUTLINE
				shadowStrength = lerp(0, shadowStrength, _OutlineShadowStrength);
				#endif
				
				// These blocks shouldn't need ifex, they should be removed on lock when their keywords aren't present
				
				#ifdef _LIGHTINGMODE_FLAT
				poiLight.finalLighting = poiLight.directColor * attenuation * shadowAttenuation;
				if (_ForceFlatRampedLightmap)
				{
					poiLight.rampedLightMap = smoothstep(0.4, 0.6, poiLight.nDotLNormalized);
				}
				else
				{
					poiLight.rampedLightMap = 1;
				}
				#endif
				
				#ifdef _LIGHTINGMODE_TEXTURERAMP
				float2 rampUVs = poiLight.lightMap + _ShadowOffset;
				if (_ToonRampCount > 1)
				{
					rampUVs.y = (floor(poiMesh.uv[_ToonRampUVSelector].y * _ToonRampCount) + 0.5) / _ToonRampCount;
				}
				poiLight.rampedLightMap = lerp(1, UNITY_SAMPLE_TEX2D_SAMPLER(_ToonRamp, _linear_clamp, rampUVs).rgb, shadowStrength);
				poiLight.finalLighting = lerp(_LightingShadowColor * lerp(poiLight.indirectColor, poiLight.rampedLightMap * poiLight.directColor, _LightingIgnoreAmbientColor) * poiLight.occlusion, poiLight.directColor, poiLight.rampedLightMap) * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_MULTILAYER_MATH
				#if defined(PROP_MULTILAYERMATHBLURMAP) || !defined(OPTIMIZER_ENABLED)
				float4 blurMap = POI2D_SAMPLER_PAN(_MultilayerMathBlurMap, _MainTex, poiUV(poiMesh.uv[_MultilayerMathBlurMapUV], _MultilayerMathBlurMap_ST), _MultilayerMathBlurMapPan);
				#else
				float4 blurMap = 1;
				#endif
				
				float4 lns = float4(1, 1, 1, 1);
				
				float shadowAttenuationNoStrength = poiLight.attenuation;
				#if defined(POINT) || defined(SPOT)
				shadowAttenuationNoStrength = poiLight.additiveShadow;
				#endif
				
				float3 lightMap = poiLight.lightMapNoAttenuation.xxx;
				lightMap.x *= lerp(1.0, shadowAttenuationNoStrength, _ShadowReceive);
				lightMap.y *= lerp(1.0, shadowAttenuationNoStrength, _Shadow2ndReceive);
				lightMap.z *= lerp(1.0, shadowAttenuationNoStrength, _Shadow3rdReceive);
				
				float4 shadowBorderMask = 1;
				if (_ShadowBorderMapToggle)
				{
					// This should be moved to ui but honestly if these are locked in the compiler should be able to resolve it at compile time
					float2 shadowShift0 = float2(_ShadowAOShift.x, _ShadowAOShift.y);
					float2 shadowShift1 = float2(_ShadowAOShift.z, _ShadowAOShift.w);
					float2 shadowShift2 = float2(_ShadowAOShift2.x, _ShadowAOShift2.y);
					
					//float2 shadowShift0 = float2(GetRemapMinValue(_ShadowAOShift.x, _ShadowAOShift.y), GetRemapMaxValue(_ShadowAOShift.x, _ShadowAOShift.y));
					//float2 shadowShift1 = float2(GetRemapMinValue(_ShadowAOShift.z, _ShadowAOShift.w), GetRemapMaxValue(_ShadowAOShift.z, _ShadowAOShift.w));
					//float2 shadowShift2 = float2(GetRemapMinValue(_ShadowAOShift2.x, _ShadowAOShift2.y), GetRemapMaxValue(_ShadowAOShift2.x, _ShadowAOShift2.y));
					
					shadowShift0.y = (shadowShift0.x == shadowShift0.y) ? (shadowShift0.y + 0.001f) : shadowShift0.y;
					shadowShift1.y = (shadowShift1.x == shadowShift1.y) ? (shadowShift1.y + 0.001f) : shadowShift1.y;
					shadowShift2.y = (shadowShift2.x == shadowShift2.y) ? (shadowShift2.y + 0.001f) : shadowShift2.y;
					
					shadowShift0 = float2(1.0f / (shadowShift0.y - shadowShift0.x), shadowShift0.x / (shadowShift0.x - shadowShift0.y));
					shadowShift1 = float2(1.0f / (shadowShift1.y - shadowShift1.x), shadowShift1.x / (shadowShift1.x - shadowShift1.y));
					shadowShift2 = float2(1.0f / (shadowShift2.y - shadowShift2.x), shadowShift2.x / (shadowShift2.x - shadowShift2.y));
					
					#if defined(PROP_SHADOWBORDERMASK) || !defined(OPTIMIZER_ENABLED)
					float2 shadowBorderMaskUV = poiUV(poiMesh.uv[_ShadowBorderMaskUV], _ShadowBorderMask_ST);
					if (_ShadowBorderMaskLOD)
					{
						shadowBorderMask = POI2D_SAMPLE_TEX2D_SAMPLERGRADD(_ShadowBorderMask, sampler_trilinear_repeat, shadowBorderMaskUV, _ShadowBorderMaskPan, max(abs(ddx(shadowBorderMaskUV)), pow(_ShadowBorderMaskLOD, 4)), max(abs(ddy(shadowBorderMaskUV)), pow(_ShadowBorderMaskLOD, 4)));
					}
					else
					{
						shadowBorderMask = POI2D_SAMPLER_PAN(_ShadowBorderMask, _linear_repeat, shadowBorderMaskUV, _ShadowBorderMaskPan);
					}
					#endif
					
					shadowBorderMask.r = saturate(shadowBorderMask.r * shadowShift0.x + shadowShift0.y);
					shadowBorderMask.g = saturate(shadowBorderMask.g * shadowShift1.x + shadowShift1.y);
					shadowBorderMask.b = saturate(shadowBorderMask.b * shadowShift2.x + shadowShift2.y);
					
					lightMap.xyz = _ShadowPostAO ? lightMap.xyz : lightMap.xyz * shadowBorderMask.rgb;
				}
				
				if (_LightingMulitlayerNonLinear)
				{
					lns.x = poiEdgeNonLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r);
					lns.y = poiEdgeNonLinearNoSaturate(lightMap.y, _Shadow2ndBorder, _Shadow2ndBlur * blurMap.g);
					lns.z = poiEdgeNonLinearNoSaturate(lightMap.z, _Shadow3rdBorder, _Shadow3rdBlur * blurMap.b);
					lns.w = poiEdgeNonLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r, _ShadowBorderRange);
				}
				else
				{
					lns.x = poiEdgeLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r);
					lns.y = poiEdgeLinearNoSaturate(lightMap.y, _Shadow2ndBorder, _Shadow2ndBlur * blurMap.g);
					lns.z = poiEdgeLinearNoSaturate(lightMap.z, _Shadow3rdBorder, _Shadow3rdBlur * blurMap.b);
					lns.w = poiEdgeLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r, _ShadowBorderRange);
				}
				#if defined(PROP_SHADOWBORDERMASK) || !defined(OPTIMIZER_ENABLED)
				lns = _ShadowPostAO ? lns * shadowBorderMask.rgbr : lns;
				#endif
				lns = saturate(lns);
				//poiLight.finalLighting = lns.rgb;
				//return;
				float3 indirectColor = 1;
				
				if (_ShadowColor.a > 0)
				{
					#if defined(PROP_SHADOWCOLORTEX) || !defined(OPTIMIZER_ENABLED)
					float4 shadowColorTex = POI2D_SAMPLER_PAN(_ShadowColorTex, _MainTex, poiUV(poiMesh.uv[_ShadowColorTexUV], _ShadowColorTex_ST), _ShadowColorTexPan);
					#else
					float4 shadowColorTex = float4(1, 1, 1, 1);
					#endif
					indirectColor = lerp(float3(1, 1, 1), shadowColorTex.rgb, shadowColorTex.a) * _ShadowColor.rgb;
				}
				if (_Shadow2ndColor.a > 0)
				{
					#if defined(PROP_SHADOW2NDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
					float4 shadow2ndColorTex = POI2D_SAMPLER_PAN(_Shadow2ndColorTex, _MainTex, poiUV(poiMesh.uv[_Shadow2ndColorTexUV], _Shadow2ndColorTex_ST), _Shadow2ndColorTexPan);
					#else
					float4 shadow2ndColorTex = float4(1, 1, 1, 1);
					#endif
					shadow2ndColorTex.rgb = lerp(float3(1, 1, 1), shadow2ndColorTex.rgb, shadow2ndColorTex.a) * _Shadow2ndColor.rgb;
					lns.y = _Shadow2ndColor.a - lns.y * _Shadow2ndColor.a;
					indirectColor = lerp(indirectColor, shadow2ndColorTex.rgb, lns.y);
				}
				if (_Shadow3rdColor.a > 0)
				{
					#if defined(PROP_SHADOW3RDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
					float4 shadow3rdColorTex = POI2D_SAMPLER_PAN(_Shadow3rdColorTex, _MainTex, poiUV(poiMesh.uv[_Shadow3rdColorTexUV], _Shadow3rdColorTex_ST), _Shadow3rdColorTexPan);
					#else
					float4 shadow3rdColorTex = float4(1, 1, 1, 1);
					#endif
					shadow3rdColorTex.rgb = lerp(float3(1, 1, 1), shadow3rdColorTex.rgb, shadow3rdColorTex.a) * _Shadow3rdColor.rgb;
					lns.z = _Shadow3rdColor.a - lns.z * _Shadow3rdColor.a;
					indirectColor = lerp(indirectColor, shadow3rdColorTex.rgb, lns.z);
				}
				
				indirectColor = lerp(indirectColor, indirectColor * poiFragData.baseColor, _ShadowMainStrength);
				poiLight.rampedLightMap = lns.x;
				indirectColor = lerp(indirectColor, 1, lns.w * _ShadowBorderColor.rgb * _ShadowBorderColor.a);
				indirectColor = indirectColor * lerp(poiLight.indirectColor, poiLight.directColor, _LightingIgnoreAmbientColor);
				indirectColor = lerp(poiLight.directColor, indirectColor, shadowStrength * poiLight.shadowMask);
				poiLight.finalLighting = lerp(indirectColor, poiLight.directColor, lns.x) * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_SHADEMAP
				poiLight.finalLighting = poiLight.directColor * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_REALISTIC
				UnityLight light;
				light.dir = poiLight.direction;
				light.color = max(0, _LightColor0.rgb) * saturate(shadowAttenuation * attenuation * poiLight.detailShadow);
				light.ndotl = poiLight.nDotLSaturated;
				UnityIndirect indirectLight = (UnityIndirect)0;
				#ifdef UNITY_PASS_FORWARDBASE
				indirectLight = CreateIndirectLight(poiMesh, poiCam, poiLight);
				#endif
				#ifdef UNITY_PASS_FORWARDBASE
				light.color = max(light.color * _PPLightingMultiplier, 0);
				light.color = max(light.color + _PPLightingAddition, 0);
				indirectLight.diffuse = max(indirectLight.diffuse * _PPLightingMultiplier, 0);
				indirectLight.diffuse = max(indirectLight.diffuse + _PPLightingAddition, 0);
				#endif
				
				poiLight.rampedLightMap = poiLight.nDotLSaturated;
				poiLight.finalLighting = max(UNITY_BRDF_PBS(1, 0, 0, 0, poiMesh.normals[1], poiCam.viewDir, light, indirectLight).xyz, _LightingMinLightBrightness);
				#endif
				
				#ifdef _LIGHTINGMODE_CLOTH
				#if defined(PROP_CLOTHMETALLICSMOOTHNESSMAP) || !defined(OPTIMIZER_ENABLED)
				float4 clothmapsample = POI2D_SAMPLER_PAN(_ClothMetallicSmoothnessMap, _MainTex, poiUV(poiMesh.uv[_ClothMetallicSmoothnessMapUV], _ClothMetallicSmoothnessMap_ST), _ClothMetallicSmoothnessMapPan);
				float roughness = 1 - (clothmapsample.a * _ClothSmoothness);
				float reflectance = _ClothReflectance * clothmapsample.b;
				float clothmask = clothmapsample.g;
				float metallic = pow(clothmapsample.r * _ClothMetallic, 2) * ClothMetallic(clothmask);
				roughness = _ClothMetallicSmoothnessMapInvert == 1 ? 1 - roughness : roughness;
				#else
				float roughness = 1 - (_ClothSmoothness);
				float metallic = pow(_ClothMetallic, 2);
				float reflectance = _ClothReflectance;
				float clothmask = 1;
				#endif
				
				float perceptualRoughness = pow(roughness, 2);
				float clampedRoughness = max(0.002, perceptualRoughness);
				
				float f0 = 0.16 * reflectance * reflectance * (1 - metallic) + poiFragData.baseColor * metallic;
				float3 fresnel = Fresnel(f0, poiLight.nDotV);
				
				float3 dfg = SampleDFG(poiLight.nDotV, perceptualRoughness);
				
				float energyCompensation = EnvBRDFEnergyCompensation(dfg, f0, clothmask);
				
				poiLight.finalLighting = Fd_Burley(perceptualRoughness, poiLight.nDotV, poiLight.nDotLSaturated, poiLight.lDotH);
				poiLight.finalLighting *= _LightColor0 * attenuation * shadowAttenuation * poiLight.nDotLSaturated;
				poiLight.rampedLightMap = poiLight.nDotLSaturated;
				float3 specular = max(0, Specular(clampedRoughness, poiLight, f0, poiMesh.normals[1], clothmask) * poiLight.finalLighting * energyCompensation * UNITY_PI); // (D * V) * F
				
				#ifdef UNITY_PASS_FORWARDBASE
				float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
				float3 indirectDiffuse;
				indirectDiffuse.r = shEvaluateDiffuseL1Geomerics_local(L0.r, unity_SHAr.xyz, poiMesh.normals[1]);
				indirectDiffuse.g = shEvaluateDiffuseL1Geomerics_local(L0.g, unity_SHAg.xyz, poiMesh.normals[1]);
				indirectDiffuse.b = shEvaluateDiffuseL1Geomerics_local(L0.b, unity_SHAb.xyz, poiMesh.normals[1]);
				indirectDiffuse = max(0, indirectDiffuse);
				
				float3 indirectSpecular = IndirectSpecular(dfg, roughness, poiLight.occlusion, energyCompensation, clothmask, indirectDiffuse, f0, poiLight, poiFragData, poiCam, poiMesh);
				poiLight.finalLightAdd += max(0, specular + indirectSpecular);
				poiLight.finalLighting += indirectDiffuse * poiLight.occlusion;
				#endif
				
				poiFragData.baseColor.xyz *= (1 - metallic);
				#endif
				
				#ifdef _LIGHTINGMODE_WRAPPED
				#define GREYSCALE_VECTOR float3(.33333, .33333, .33333)
				float3 directColor = _LightColor0.rgb * saturate(RTWrapFunc(poiLight.nDotL, _LightingWrappedWrap, _LightingWrappedNormalization));
				float3 indirectColor = 0;
				#ifdef UNITY_PASS_FORWARDBASE
				indirectColor = ShadeSH9_wrapped(poiMesh.normals[_LightingIndirectUsesNormals], _LightingWrappedWrap) * poiLight.occlusion;
				#endif
				directColor = lerp(directColor, dot(directColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic); // Duplicated from Lightdata due to recreating the light colour
				indirectColor = lerp(indirectColor, dot(indirectColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic); // Ditto^
				
				float3 ShadeSH9Plus_2 = GetSHMaxL1();
				float bw_topDirectLighting_2 = dot(_LightColor0.rgb, GREYSCALE_VECTOR);
				float bw_directLighting = dot(directColor, GREYSCALE_VECTOR);
				float bw_indirectLighting = dot(indirectColor, GREYSCALE_VECTOR);
				float bw_topIndirectLighting = dot(ShadeSH9Plus_2, GREYSCALE_VECTOR);
				
				poiLight.lightMap = smoothstep(0, bw_topIndirectLighting + bw_topDirectLighting_2, bw_indirectLighting + bw_directLighting) * min(poiLight.detailShadow, shadowAttenuation);
				poiLight.rampedLightMap = saturate((poiLight.lightMap - (1 - _LightingGradientEnd)) / saturate((1 - _LightingGradientStart) - (1 - _LightingGradientEnd) + fwidth(poiLight.lightMap)));
				float3 mathRamp = lerp(float3(1, 1, 1), saturate(lerp((_LightingShadowColor * lerp(indirectColor, 1, _LightingIgnoreAmbientColor)), float3(1, 1, 1), saturate(poiLight.rampedLightMap))), _ShadowStrength);
				
				directColor *= saturate(poiLight.rampedLightMap + 1 - _ShadowStrength) * _LightingWrappedColor;
				
				float3 finalWrap = directColor + indirectColor;
				if (_LightingCapEnabled)
				{
					finalWrap = clamp(finalWrap, _LightingMinLightBrightness, _LightingCap);
				}
				else
				{
					finalWrap = max(finalWrap, _LightingMinLightBrightness);
				}
				//finalWrap *= attenuation;
				poiLight.finalLighting = finalWrap * saturate(mathRamp + 1 - _ShadowStrength);
				#endif
				
				#ifdef _LIGHTINGMODE_SKIN
				float3 ambientNormalWorld = poiMesh.normals[1];//aTangentToWorld(s, s.blurredNormalTangent);
				poiLight.rampedLightMap = poiLight.nDotLSaturated;
				
				// Scattering mask.
				#if defined(PROP_SKINTHICKNESS) || !defined(OPTIMIZER_ENABLED)
				float subsurface = 1 - POI2D_SAMPLER_PAN(_SkinThicknessMap, _MainTex, poiUV(poiMesh.uv[_SkinThicknessMapUV], _SkinThicknessMap_ST), _SkinThicknessMapPan).r;
				#else
				float subsurface = 1;
				#endif
				if (_SkinThicknessMapInvert)
				{
					subsurface = 1 - subsurface;
				}
				if (_SkinThicknessPower != 1)
				{
					subsurface = pow(subsurface, _SkinThicknessPower);
				}
				float skinScattering = saturate(subsurface * _SssScale * 2);
				
				// Skin subsurface depth absorption tint.
				// cf http://www.crytek.com/download/2014_03_25_CRYENGINE_GDC_Schultz.pdf pg 35
				// link dead, https://ia600902.us.archive.org/25/items/crytek_presentations/2014_03_25_CRYENGINE_GDC_Schultz.pdf
				half3 absorption = exp((1.0h - subsurface) * _SssTransmissionAbsorption.rgb);
				
				// Albedo scale for absorption assumes ~0.5 luminance for Caucasian skin.
				absorption *= saturate(poiFragData.baseColor * unity_ColorSpaceDouble.rgb);
				
				// Blurred normals for indirect diffuse and direct scattering.
				ambientNormalWorld = normalize(lerp(poiMesh.normals[1], ambientNormalWorld, _SssBumpBlur));
				
				float ndlBlur = dot(poiMesh.normals[1], poiLight.direction) * 0.5h + 0.5h;
				float lumi = dot(poiLight.directColor, half3(0.2126h, 0.7152h, 0.0722h));
				float4 sssLookupUv = float4(ndlBlur, skinScattering * lumi, 0.0f, 0.0f);
				half3 sss = poiLight.lightMap * tex2Dlod(_SkinLUT, sssLookupUv).rgb;
				poiLight.finalLighting = lerp(poiLight.directColor, min(lerp(poiLight.indirectColor * _LightingShadowColor, _LightingShadowColor, _LightingIgnoreAmbientColor) * poiLight.occlusion + (sss * poiLight.directColor), poiLight.directColor), _ShadowStrength * poiLight.shadowMask) * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_SDF
				float3 forward = normalize(UnityObjectToWorldDir(float4(_SDFForward.xyz, 1)));
				float3 left = normalize(UnityObjectToWorldDir(float4(_SDFLeft.xyz, 1)));
				float3 lightDirHorizontal = normalize(float3(poiLight.direction.x, 0, poiLight.direction.z));
				
				float lightAtten = 1 - (dot(lightDirHorizontal, forward) * 0.5 + 0.5);
				float filpU = sign(dot(lightDirHorizontal, left));
				
				#if defined(PROP_SDFSHADINGTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float shadowSDF = POI2D_SAMPLER_PAN(_SDFShadingTexture, _MainTex, poiUV(poiMesh.uv[_SDFShadingTextureUV], _SDFShadingTexture_ST) * float2(filpU, 1), _SDFShadingTexturePan).r;
				#else
				float shadowSDF = float2(1, 1);
				#endif
				float blur = _SDFBlur * 0.1;
				float faceShadow = smoothstep(lightAtten - blur, lightAtten + blur, shadowSDF) * poiLight.detailShadow;
				
				float3 indirectColor = _LightingShadowColor.rgb;
				indirectColor = indirectColor * lerp(poiLight.indirectColor, poiLight.directColor, _LightingIgnoreAmbientColor);
				indirectColor = lerp(poiLight.directColor, indirectColor, _ShadowStrength * poiLight.shadowMask);
				
				poiLight.finalLighting = lerp(indirectColor, poiLight.directColor, faceShadow) * attenuation;
				#endif
				
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					float3 vertexLighting = float3(0, 0, 0);
					for (int index = 0; index < 4; index++)
					{
						float lightingMode = _LightingAdditiveType;
						if (lightingMode == 3)
						{
							//This is a temporary bandaid fix
							#if defined(_LIGHTINGMODE_REALISTIC)
							lightingMode = 0;
							#else
							lightingMode = 1;
							#endif
						}
						//UNITY_BRANCH
						if (lightingMode == 0)
						{
							vertexLighting = max(vertexLighting, poiLight.vColor[index] * poiLight.vSaturatedDotNL[index] * poiLight.detailShadow); // Realistic
							
						}
						//UNITY_BRANCH
						// Toon
						if (lightingMode == 1)
						{
							float2 ToonAddGradient = float2(_LightingAdditiveGradientStart, _LightingAdditiveGradientEnd);
							if (ToonAddGradient.x == ToonAddGradient.y) ToonAddGradient.y += 0.0001;
							vertexLighting = max(vertexLighting, lerp(poiLight.vColor[index], poiLight.vColor[index] * _LightingAdditivePassthrough, smoothstep(ToonAddGradient.x, ToonAddGradient.y, 1 - (.5 * poiLight.vDotNL[index] + .5))) * poiLight.detailShadow);
						}
					}
					float3 mixedLight = poiLight.finalLighting;
					poiLight.finalLighting = max(vertexLighting, poiLight.finalLighting);
					#endif
				}
			}
			#endif
			//endex
			
			#if defined(GEOM_TYPE_BRANCH) || defined(GEOM_TYPE_BRANCH_DETAIL) || defined(GEOM_TYPE_FROND) || defined(DEPTH_OF_FIELD_COC_VIEW)
			float2 decalUV(float uvNumber, float2 position, half rotation, half rotationSpeed, half2 scale, float4 scaleOffset, float depth, in PoiMesh poiMesh, in PoiCam poiCam)
			{
				scaleOffset = float4(-scaleOffset.x, scaleOffset.y, -scaleOffset.z, scaleOffset.w);
				float2 centerOffset = float2((scaleOffset.x + scaleOffset.y) / 2, (scaleOffset.z + scaleOffset.w) / 2);
				float2 uv = poiMesh.uv[uvNumber] + calcParallax(depth + 1, poiCam);
				float2 decalCenter = position + centerOffset;
				float theta = radians(rotation + _Time.z * rotationSpeed);
				float cs = cos(theta);
				float sn = sin(theta);
				uv = float2((uv.x - decalCenter.x) * cs - (uv.y - decalCenter.y) * sn + decalCenter.x, (uv.x - decalCenter.x) * sn + (uv.y - decalCenter.y) * cs + decalCenter.y);
				uv = remap(uv, float2(0, 0) - scale / 2 + position + scaleOffset.xz, scale / 2 + position + scaleOffset.yw, float2(0, 0), float2(1, 1));
				return uv;
			}
			
			inline float3 decalHueShift(float enabled, float3 color, float shift, float shiftSpeed)
			{
				//UNITY_BRANCH
				if (enabled)
				{
					color = hueShift(color, shift + _Time.x * shiftSpeed);
				}
				return color;
			}
			
			inline float applyTilingClipping(float enabled, float2 uv)
			{
				float ret = 1;
				//UNITY_BRANCH
				if (!enabled)
				{
					if (uv.x > 1 || uv.y > 1 || uv.x < 0 || uv.y < 0)
					{
						ret = 0;
					}
				}
				return ret;
			}
			
			struct PoiDecal
			{
				float m_DecalFaceMask;
				float m_DecalMaskChannel;
				float m_DecalGlobalMask;
				float m_DecalGlobalMaskBlendType;
				float m_DecalApplyGlobalMaskIndex;
				float m_DecalApplyGlobalMaskBlendType;
				float4 m_DecalTexture_ST;
				float2 m_DecalTexturePan;
				float m_DecalTextureUV;
				float4 m_DecalColor;
				float m_DecalColorThemeIndex;
				fixed m_DecalTiled;
				float m_DecalBlendType;
				half m_DecalRotation;
				half3 m_DecalScale;
				float4 m_DecalSideOffset;
				half2 m_DecalPosition;
				half m_DecalRotationSpeed;
				float m_DecalEmissionStrength;
				float m_DecalBlendAlpha;
				float m_DecalAlphaBlendMode;
				float m_DecalHueShiftEnabled;
				float m_DecalHueShift;
				float m_DecalHueShiftSpeed;
				float m_DecalDepth;
				float m_DecalHueAngleStrength;
				float m_DecalChannelSeparationEnable;
				float m_DecalChannelSeparation;
				float m_DecalChannelSeparationPremultiply;
				float m_DecalChannelSeparationHue;
				float m_DecalChannelSeparationVertical;
				float m_DecalChannelSeparationAngleStrength;
				float m_DecalOverrideAlphaMode;
				float m_DecalOverrideAlpha;
				
				#if defined(POI_AUDIOLINK)
				half m_AudioLinkDecalScaleBand;
				float4 m_AudioLinkDecalScale;
				half m_AudioLinkDecalRotationBand;
				float2 m_AudioLinkDecalRotation;
				half m_AudioLinkDecalAlphaBand;
				float2 m_AudioLinkDecalAlpha;
				half m_AudioLinkDecalEmissionBand;
				float2 m_AudioLinkDecalEmission;
				float m_DecalRotationCTALBand;
				float m_DecalRotationCTALSpeed;
				float m_DecalRotationCTALType;
				float m_AudioLinkDecalColorChord;
				float m_AudioLinkDecalSideBand;
				float4 m_AudioLinkDecalSideMin;
				float4 m_AudioLinkDecalSideMax;
				float2 m_AudioLinkDecalChannelSeparation;
				float m_AudioLinkDecalChannelSeparationBand;
				#endif
				
				float4 decalColor;
				float2 decalScale;
				float decalRotation;
				float2 uv;
				float4 dduv;
				float4 sideMod;
				float decalChannelOffset;
				float4 decalMask;
				
				void Init(in float4 DecalMask)
				{
					decalMask = DecalMask;
					decalScale = m_DecalScale.xy;// * m_DecalScale.z;
					
				}
				
				void InitAudiolink(in PoiMods poiMods)
				{
					#ifdef POI_AUDIOLINK
					if (poiMods.audioLinkAvailable)
					{
						decalScale += lerp(m_AudioLinkDecalScale.xy, m_AudioLinkDecalScale.zw, poiMods.audioLink[m_AudioLinkDecalScaleBand]);
						sideMod += lerp(m_AudioLinkDecalSideMin, m_AudioLinkDecalSideMax, poiMods.audioLink[m_AudioLinkDecalSideBand]);
						decalRotation += lerp(m_AudioLinkDecalRotation.x, m_AudioLinkDecalRotation.y, poiMods.audioLink[m_AudioLinkDecalRotationBand]);
						decalRotation += AudioLinkGetChronoTime(m_DecalRotationCTALType, m_DecalRotationCTALBand) * m_DecalRotationCTALSpeed * 360;
						decalChannelOffset += lerp(m_AudioLinkDecalChannelSeparation[0], m_AudioLinkDecalChannelSeparation[1], poiMods.audioLink[m_AudioLinkDecalChannelSeparationBand]);
					}
					#endif
				}
				
				void SampleDecalNoTexture(in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam)
				{
					uv = decalUV(m_DecalTextureUV, m_DecalPosition, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					decalColor = float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					decalColor.rgb = decalHueShift(m_DecalHueShiftEnabled, decalColor.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					decalColor.a *= decalMask[m_DecalMaskChannel] * applyTilingClipping(m_DecalTiled, uv);
				}
				
				void SampleDecal(sampler2D decalTexture, in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam, float2 scaleMultiplier = float2(1, 1))
				{
					uv = decalUV(m_DecalTextureUV, m_DecalPosition, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale * scaleMultiplier, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					// Adjust derivatives for _ST of decal texture
					float4 dduv = any(fwidth(uv) > .5) ? 0.001 : float4(ddx(uv) * m_DecalTexture_ST.x, ddy(uv) * m_DecalTexture_ST.y);
					decalColor = tex2D(decalTexture, poiUV(uv, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduv.xy, dduv.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					decalColor.rgb = decalHueShift(m_DecalHueShiftEnabled, decalColor.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					decalColor.a *= decalMask[m_DecalMaskChannel] * applyTilingClipping(m_DecalTiled, uv);
				}
				
				void SampleDecalNoAlpha(sampler2D decalTexture, in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam, float2 scaleMultiplier = float2(1, 1))
				{
					uv = decalUV(m_DecalTextureUV, m_DecalPosition, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale * scaleMultiplier, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					// Adjust derivatives for _ST of decal texture
					float4 dduv = any(fwidth(uv) > .5) ? 0.001 : float4(ddx(uv) * m_DecalTexture_ST.x, ddy(uv) * m_DecalTexture_ST.y);
					decalColor.rgb = tex2D(decalTexture, poiUV(uv, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduv.xy, dduv.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a).rgb;
					decalColor.rgb = decalHueShift(m_DecalHueShiftEnabled, decalColor.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					decalColor.a *= decalMask[m_DecalMaskChannel] * applyTilingClipping(m_DecalTiled, uv);
				}
				
				void SampleDecalAlphaOnly(sampler2D decalTexture, in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam, float2 scaleMultiplier = float2(1, 1))
				{
					uv = decalUV(m_DecalTextureUV, m_DecalPosition, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale * scaleMultiplier, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					// Adjust derivatives for _ST of decal texture
					float4 dduv = any(fwidth(uv) > .5) ? 0.001 : float4(ddx(uv) * m_DecalTexture_ST.x, ddy(uv) * m_DecalTexture_ST.y);
					decalColor = tex2D(decalTexture, poiUV(uv, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduv.xy, dduv.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					decalColor.a *= decalMask[m_DecalMaskChannel] * applyTilingClipping(m_DecalTiled, uv);
				}
				
				void SampleDecalChannelSeparation(sampler2D decalTexture, in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam)
				{
					decalColor = float4(0, 0, 0, 1);
					decalChannelOffset += m_DecalChannelSeparation + m_DecalChannelSeparationAngleStrength * (m_DecalChannelSeparationAngleStrength > 0 ? (1 - poiLight.nDotV) : poiLight.nDotV);
					float2 positionOffset = decalChannelOffset * 0.01 * (decalScale.x + decalScale.y) * float2(cos(m_DecalChannelSeparationVertical), sin(m_DecalChannelSeparationVertical));
					float2 uvSample0 = decalUV(m_DecalTextureUV, m_DecalPosition + positionOffset, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					float2 uvSample1 = decalUV(m_DecalTextureUV, m_DecalPosition - positionOffset, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					
					float4 dduvSample0 = any(fwidth(uvSample0) > .5) ? 0.001 : float4(ddx(uvSample0) * m_DecalTexture_ST.x, ddy(uvSample0) * m_DecalTexture_ST.y);
					float4 dduvSample1 = any(fwidth(uvSample1) > .5) ? 0.001 : float4(ddx(uvSample1) * m_DecalTexture_ST.x, ddy(uvSample1) * m_DecalTexture_ST.y);
					
					float4 sample0 = tex2D(decalTexture, poiUV(uvSample0, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduvSample0.xy, dduvSample0.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					float4 sample1 = tex2D(decalTexture, poiUV(uvSample1, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduvSample1.xy, dduvSample1.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					
					sample0.rgb = decalHueShift(m_DecalHueShiftEnabled, sample0.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					sample1.rgb = decalHueShift(m_DecalHueShiftEnabled, sample1.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					
					float3 channelSeparationColor = HUEtoRGB(frac(m_DecalChannelSeparationHue));
					
					if (m_DecalChannelSeparationPremultiply)
					{
						decalColor.rgb = lerp(sample0 * sample0.a, sample1 * sample1.a, channelSeparationColor);
					}
					else
					{
						decalColor.rgb = lerp(sample0, sample1, channelSeparationColor);
					}
					decalColor.a = 0.5 * (sample0.a + sample1.a);
					decalColor.a *= decalMask[m_DecalMaskChannel] * max(applyTilingClipping(m_DecalTiled, uvSample0), applyTilingClipping(m_DecalTiled, uvSample1));
				}
				
				void Apply(inout float alphaOverride, inout float decalAlpha, inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, inout PoiMods poiMods, in PoiLight poiLight)
				{
					if (m_DecalGlobalMask > 0)
					{
						decalColor.a = maskBlend(decalColor.a, poiMods.globalMask[m_DecalGlobalMask - 1], m_DecalGlobalMaskBlendType);
					}
					
					float audioLinkDecalAlpha = 0;
					float audioLinkDecalEmission = 0;
					#ifdef POI_AUDIOLINK
					audioLinkDecalEmission = lerp(m_AudioLinkDecalEmission.x, m_AudioLinkDecalEmission.y, poiMods.audioLink[m_AudioLinkDecalEmissionBand]) * poiMods.audioLinkAvailable;
					
					if (m_AudioLinkDecalColorChord)
					{
						if (poiMods.audioLinkAvailable)
						{
							decalColor.rgb *= AudioLinkLerp(ALPASS_CCSTRIP + float2(uv.x * AUDIOLINK_WIDTH, 0)).rgb;
						}
						else
						{
							decalAlpha = 0;
						}
					}
					audioLinkDecalAlpha = lerp(m_AudioLinkDecalAlpha.x, m_AudioLinkDecalAlpha.y, poiMods.audioLink[m_AudioLinkDecalAlphaBand]) * poiMods.audioLinkAvailable;
					#endif
					
					if (m_DecalOverrideAlpha)
					{
						float finalAlpha = lerp(1, min(decalAlpha, decalColor.a), decalMask[m_DecalMaskChannel]);
						if (m_DecalOverrideAlphaMode != 0 && !m_DecalTiled)
						{
							if (uv.x > 0 && uv.x < 1 && uv.y > 0 && uv.y < 1)
							{
								//decalAlpha = lerp(decalAlpha, min(decalAlpha, decalColor.a), decalMask[m_DecalMaskChannel]);
								//poiFragData.alpha = saturate(poiFragData.alpha + lerp(1, min(decalAlpha, decalColor.a), decalMask[m_DecalMaskChannel]));
								if (m_DecalOverrideAlpha == 1) poiFragData.alpha = finalAlpha;
								if (m_DecalOverrideAlpha == 2) poiFragData.alpha = saturate(poiFragData.alpha * finalAlpha);
								if (m_DecalOverrideAlpha == 3) poiFragData.alpha = saturate(poiFragData.alpha + finalAlpha);
								if (m_DecalOverrideAlpha == 4) poiFragData.alpha = saturate(poiFragData.alpha - finalAlpha);
								if (m_DecalOverrideAlpha == 5) poiFragData.alpha = min(poiFragData.alpha, finalAlpha);
								if (m_DecalOverrideAlpha == 6) poiFragData.alpha = max(poiFragData.alpha, finalAlpha);
							}
						}
						else
						{
							if (m_DecalOverrideAlpha == 1) poiFragData.alpha = finalAlpha;
							if (m_DecalOverrideAlpha == 2) poiFragData.alpha = saturate(poiFragData.alpha * finalAlpha);
							if (m_DecalOverrideAlpha == 3) poiFragData.alpha = saturate(poiFragData.alpha + finalAlpha);
							if (m_DecalOverrideAlpha == 4) poiFragData.alpha = saturate(poiFragData.alpha - finalAlpha);
							if (m_DecalOverrideAlpha == 5) poiFragData.alpha = min(poiFragData.alpha, finalAlpha);
							if (m_DecalOverrideAlpha == 6) poiFragData.alpha = max(poiFragData.alpha, finalAlpha);
						}
					}
					
					if (m_DecalFaceMask > 0)
					{
						if (m_DecalFaceMask == 1 && !poiMesh.isFrontFace)
						{
							decalColor.a *= 0;
						}
						else if (m_DecalFaceMask == 2 && poiMesh.isFrontFace)
						{
							decalColor.a *= 0;
						}
					}
					
					float decalAlphaMixed = decalColor.a * saturate(m_DecalBlendAlpha + audioLinkDecalAlpha);
					
					if (m_DecalApplyGlobalMaskIndex > 0)
					{
						applyToGlobalMask(poiMods, m_DecalApplyGlobalMaskIndex - 1, m_DecalApplyGlobalMaskBlendType, decalAlphaMixed);
					}
					
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, decalColor.rgb, m_DecalBlendType), decalAlphaMixed);
					poiFragData.emission += decalColor.rgb * decalColor.a * max(m_DecalEmissionStrength + audioLinkDecalEmission, 0);
				}
				float2 GetVideoAspectRatio(float2 videoDimensions, float CorrectionType, float fitToScale)
				{
					float2 AspectRatioMultiplier = float2(1, 1);
					if (fitToScale)
					{
						float2 decalScale = m_DecalScale.xy + float2(m_DecalSideOffset.x + m_DecalSideOffset.y, m_DecalSideOffset.z + m_DecalSideOffset.w);
						if (decalScale.x > decalScale.y)
						{
							videoDimensions.xy *= float2((decalScale.y / decalScale.x), 1);
						}
						else
						{
							videoDimensions.xy *= float2(1, (decalScale.x / decalScale.y));
						}
					}
					
					if (CorrectionType != 2)
					{
						if (CorrectionType == 0)
						{
							if (videoDimensions.x > videoDimensions.y)
							{
								AspectRatioMultiplier = float2(1, videoDimensions.y / videoDimensions.x);
							}
							else
							{
								AspectRatioMultiplier = float2(videoDimensions.x / videoDimensions.y, 1);
							}
						}
						else if (CorrectionType == 1)
						{
							if (videoDimensions.x > videoDimensions.y)
							{
								AspectRatioMultiplier = float2(1 / (videoDimensions.y / videoDimensions.x), 1);
							}
							else
							{
								AspectRatioMultiplier = float2(1, 1 / (videoDimensions.x / videoDimensions.y));
							}
						}
					}
					return AspectRatioMultiplier;
				}
			};
			
			void applyDecals(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, inout PoiMods poiMods, in PoiLight poiLight)
			{
				// check if _Udon_VideoTex is greater than 16 pixels in width
				float udonVideoTexAvailable = 0;
				float2 udonVideoAspectRatio = 1;
				if (_Udon_VideoTex_TexelSize.z > 16)
				{
					udonVideoTexAvailable = 1;
				}
				
				float decalAlpha = 1;
				float alphaOverride = 0;
				#if defined(PROP_DECALMASK) || !defined(OPTIMIZER_ENABLED)
				float4 decalMask = POI2D_SAMPLER_PAN(_DecalMask, _MainTex, poiUV(poiMesh.uv[_DecalMaskUV], _DecalMask_ST), _DecalMaskPan);
				#else
				float4 decalMask = 1;
				#endif
				
				#ifdef TPS_Penetrator
				if (_DecalTPSDepthMaskEnabled)
				{
					decalMask.r = lerp(0, decalMask.r * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Decal0TPSMaskStrength);
					decalMask.g = lerp(0, decalMask.g * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Decal1TPSMaskStrength);
					decalMask.b = lerp(0, decalMask.b * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Decal2TPSMaskStrength);
					decalMask.a = lerp(0, decalMask.a * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Decal3TPSMaskStrength);
				}
				#endif
				
				float4 decalColor = 1;
				float2 uv = 0;
				// yaes
				
				//ifex _DecalEnabled==0
				#ifdef GEOM_TYPE_BRANCH
				PoiDecal Decal0;
				PoiInitStruct(PoiDecal, Decal0)
				Decal0.m_DecalFaceMask = _Decal0FaceMask;
				Decal0.m_DecalMaskChannel = _Decal0MaskChannel;
				Decal0.m_DecalGlobalMask = _Decal0GlobalMask;
				Decal0.m_DecalGlobalMaskBlendType = _Decal0GlobalMaskBlendType;
				Decal0.m_DecalApplyGlobalMaskIndex = _Decal0ApplyGlobalMaskIndex;
				Decal0.m_DecalApplyGlobalMaskBlendType = _Decal0ApplyGlobalMaskBlendType;
				Decal0.m_DecalTexture_ST = _DecalTexture_ST;
				Decal0.m_DecalTexturePan = _DecalTexturePan;
				Decal0.m_DecalTextureUV = _DecalTextureUV;
				Decal0.m_DecalColor = _DecalColor;
				Decal0.m_DecalColorThemeIndex = _DecalColorThemeIndex;
				Decal0.m_DecalTiled = _DecalTiled;
				Decal0.m_DecalBlendType = _DecalBlendType;
				Decal0.m_DecalRotation = _DecalRotation;
				Decal0.m_DecalScale = _DecalScale;
				Decal0.m_DecalSideOffset = _DecalSideOffset;
				Decal0.m_DecalPosition = _DecalPosition;
				Decal0.m_DecalRotationSpeed = _DecalRotationSpeed;
				Decal0.m_DecalEmissionStrength = _DecalEmissionStrength;
				Decal0.m_DecalBlendAlpha = _DecalBlendAlpha;
				Decal0.m_DecalOverrideAlpha = _DecalOverrideAlpha;
				Decal0.m_DecalHueShiftEnabled = _DecalHueShiftEnabled;
				Decal0.m_DecalHueShift = _DecalHueShift;
				Decal0.m_DecalHueShiftSpeed = _DecalHueShiftSpeed;
				Decal0.m_DecalDepth = _Decal0Depth;
				Decal0.m_DecalHueAngleStrength = _Decal0HueAngleStrength;
				Decal0.m_DecalChannelSeparationEnable = _Decal0ChannelSeparationEnable;
				Decal0.m_DecalChannelSeparation = _Decal0ChannelSeparation;
				Decal0.m_DecalChannelSeparationPremultiply = _Decal0ChannelSeparationPremultiply;
				Decal0.m_DecalChannelSeparationHue = _Decal0ChannelSeparationHue;
				Decal0.m_DecalChannelSeparationVertical = _Decal0ChannelSeparationVertical;
				Decal0.m_DecalChannelSeparationAngleStrength = _Decal0ChannelSeparationAngleStrength;
				Decal0.m_DecalOverrideAlphaMode = _Decal0OverrideAlphaMode;
				
				Decal0.Init(decalMask);
				
				#if defined(POI_AUDIOLINK)
				Decal0.m_AudioLinkDecalScaleBand = _AudioLinkDecal0ScaleBand;
				Decal0.m_AudioLinkDecalScale = _AudioLinkDecal0Scale;
				Decal0.m_AudioLinkDecalRotationBand = _AudioLinkDecal0RotationBand;
				Decal0.m_AudioLinkDecalRotation = _AudioLinkDecal0Rotation;
				Decal0.m_AudioLinkDecalAlphaBand = _AudioLinkDecal0AlphaBand;
				Decal0.m_AudioLinkDecalAlpha = _AudioLinkDecal0Alpha;
				Decal0.m_AudioLinkDecalEmissionBand = _AudioLinkDecal0EmissionBand;
				Decal0.m_AudioLinkDecalEmission = _AudioLinkDecal0Emission;
				Decal0.m_DecalRotationCTALBand = _DecalRotationCTALBand0;
				Decal0.m_DecalRotationCTALSpeed = _DecalRotationCTALSpeed0;
				Decal0.m_DecalRotationCTALType = _DecalRotationCTALType0;
				Decal0.m_AudioLinkDecalColorChord = _AudioLinkDecalCC0;
				Decal0.m_AudioLinkDecalSideBand = _AudioLinkDecal0SideBand;
				Decal0.m_AudioLinkDecalSideMin = _AudioLinkDecal0SideMin;
				Decal0.m_AudioLinkDecalSideMax = _AudioLinkDecal0SideMax;
				Decal0.m_AudioLinkDecalChannelSeparation = _AudioLinkDecal0ChannelSeparation;
				Decal0.m_AudioLinkDecalChannelSeparationBand = _AudioLinkDecal0ChannelSeparationBand;
				
				Decal0.InitAudiolink(poiMods);
				#endif
				
				if (!_Decal0VideoEnabled)
				{
					
					#if defined(PROP_DECALTEXTURE) || !defined(OPTIMIZER_ENABLED)
					//ifex _Decal0ChannelSeparationEnable==0
					if (_Decal0ChannelSeparationEnable)
					{
						Decal0.SampleDecalChannelSeparation(_DecalTexture, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					//ifex _Decal0ChannelSeparationEnable==1
					if (!_Decal0ChannelSeparationEnable)
					{
						Decal0.SampleDecal(_DecalTexture, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					#else
					Decal0.SampleDecalNoTexture(poiMods, poiLight, poiMesh, poiCam);
					#endif
					Decal0.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
				}
				else
				{
					udonVideoAspectRatio = Decal0.GetVideoAspectRatio(_Udon_VideoTex_TexelSize.zw, _Decal0VideoAspectFix, _Decal0VideoFitToScale);
					
					if (_Decal0OnlyVideo)
					{
						if (udonVideoTexAvailable)
						{
							Decal0.m_DecalEmissionStrength += _Decal0VideoEmissionStrength;
							if (_Decal0UseDecalAlpha)
							{
								Decal0.SampleDecal(_DecalTexture, poiMods, poiLight, poiMesh, poiCam);
								Decal0.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal0.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							Decal0.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
						}
					}
					else
					{
						Decal0.SampleDecal(_DecalTexture, poiMods, poiLight, poiMesh, poiCam);
						if (udonVideoTexAvailable)
						{
							Decal0.m_DecalEmissionStrength += _Decal0VideoEmissionStrength;
							if (_Decal0UseDecalAlpha)
							{
								Decal0.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal0.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
						}
						Decal0.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
					}
				}
				#endif
				//endex
				
				//ifex _DecalEnabled1==0
				#ifdef GEOM_TYPE_BRANCH_DETAIL
				PoiDecal Decal1;
				PoiInitStruct(PoiDecal, Decal1)
				Decal1.m_DecalFaceMask = _Decal1FaceMask;
				Decal1.m_DecalMaskChannel = _Decal1MaskChannel;
				Decal1.m_DecalGlobalMask = _Decal1GlobalMask;
				Decal1.m_DecalGlobalMaskBlendType = _Decal1GlobalMaskBlendType;
				Decal1.m_DecalApplyGlobalMaskIndex = _Decal1ApplyGlobalMaskIndex;
				Decal1.m_DecalApplyGlobalMaskBlendType = _Decal1ApplyGlobalMaskBlendType;
				Decal1.m_DecalTexture_ST = _DecalTexture1_ST;
				Decal1.m_DecalTexturePan = _DecalTexture1Pan;
				Decal1.m_DecalTextureUV = _DecalTexture1UV;
				Decal1.m_DecalColor = _DecalColor1;
				Decal1.m_DecalColorThemeIndex = _DecalColor1ThemeIndex;
				Decal1.m_DecalTiled = _DecalTiled1;
				Decal1.m_DecalBlendType = _DecalBlendType1;
				Decal1.m_DecalRotation = _DecalRotation1;
				Decal1.m_DecalScale = _DecalScale1;
				Decal1.m_DecalSideOffset = _DecalSideOffset1;
				Decal1.m_DecalPosition = _DecalPosition1;
				Decal1.m_DecalRotationSpeed = _DecalRotationSpeed1;
				Decal1.m_DecalEmissionStrength = _DecalEmissionStrength1;
				Decal1.m_DecalBlendAlpha = _DecalBlendAlpha1;
				Decal1.m_DecalOverrideAlpha = _DecalOverrideAlpha1;
				Decal1.m_DecalHueShiftEnabled = _DecalHueShiftEnabled1;
				Decal1.m_DecalHueShift = _DecalHueShift1;
				Decal1.m_DecalHueShiftSpeed = _DecalHueShiftSpeed1;
				Decal1.m_DecalDepth = _Decal1Depth;
				Decal1.m_DecalHueAngleStrength = _Decal1HueAngleStrength;
				Decal1.m_DecalChannelSeparationEnable = _Decal1ChannelSeparationEnable;
				Decal1.m_DecalChannelSeparation = _Decal1ChannelSeparation;
				Decal1.m_DecalChannelSeparationPremultiply = _Decal1ChannelSeparationPremultiply;
				Decal1.m_DecalChannelSeparationHue = _Decal1ChannelSeparationHue;
				Decal1.m_DecalChannelSeparationVertical = _Decal1ChannelSeparationVertical;
				Decal1.m_DecalChannelSeparationAngleStrength = _Decal1ChannelSeparationAngleStrength;
				Decal1.m_DecalOverrideAlphaMode = _Decal1OverrideAlphaMode;
				Decal1.Init(decalMask);
				
				#if defined(POI_AUDIOLINK)
				Decal1.m_AudioLinkDecalScaleBand = _AudioLinkDecal1ScaleBand;
				Decal1.m_AudioLinkDecalScale = _AudioLinkDecal1Scale;
				Decal1.m_AudioLinkDecalRotationBand = _AudioLinkDecal1RotationBand;
				Decal1.m_AudioLinkDecalRotation = _AudioLinkDecal1Rotation;
				Decal1.m_AudioLinkDecalAlphaBand = _AudioLinkDecal1AlphaBand;
				Decal1.m_AudioLinkDecalAlpha = _AudioLinkDecal1Alpha;
				Decal1.m_AudioLinkDecalEmissionBand = _AudioLinkDecal1EmissionBand;
				Decal1.m_AudioLinkDecalEmission = _AudioLinkDecal1Emission;
				Decal1.m_DecalRotationCTALBand = _DecalRotationCTALBand1;
				Decal1.m_DecalRotationCTALSpeed = _DecalRotationCTALSpeed1;
				Decal1.m_DecalRotationCTALType = _DecalRotationCTALType1;
				Decal1.m_AudioLinkDecalColorChord = _AudioLinkDecalCC1;
				Decal1.m_AudioLinkDecalSideBand = _AudioLinkDecal1SideBand;
				Decal1.m_AudioLinkDecalSideMin = _AudioLinkDecal1SideMin;
				Decal1.m_AudioLinkDecalSideMax = _AudioLinkDecal1SideMax;
				Decal1.m_AudioLinkDecalChannelSeparation = _AudioLinkDecal1ChannelSeparation;
				Decal1.m_AudioLinkDecalChannelSeparationBand = _AudioLinkDecal1ChannelSeparationBand;
				
				Decal1.InitAudiolink(poiMods);
				#endif
				
				if (!_Decal1VideoEnabled)
				{
					#if defined(PROP_DECALTEXTURE1) || !defined(OPTIMIZER_ENABLED)
					//ifex _Decal1ChannelSeparationEnable==0
					if (_Decal1ChannelSeparationEnable)
					{
						Decal1.SampleDecalChannelSeparation(_DecalTexture1, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					//ifex _Decal1ChannelSeparationEnable==1
					if (!_Decal1ChannelSeparationEnable)
					{
						Decal1.SampleDecal(_DecalTexture1, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					#else
					Decal1.SampleDecalNoTexture(poiMods, poiLight, poiMesh, poiCam);
					#endif
					Decal1.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
				}
				else
				{
					udonVideoAspectRatio = Decal1.GetVideoAspectRatio(_Udon_VideoTex_TexelSize.zw, _Decal1VideoAspectFix, _Decal1VideoFitToScale);
					if (_Decal1OnlyVideo)
					{
						if (udonVideoTexAvailable)
						{
							Decal1.m_DecalEmissionStrength += _Decal1VideoEmissionStrength;
							if (_Decal1UseDecalAlpha)
							{
								Decal1.SampleDecal(_DecalTexture1, poiMods, poiLight, poiMesh, poiCam);
								Decal1.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal1.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							Decal1.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
						}
					}
					else
					{
						Decal1.SampleDecal(_DecalTexture1, poiMods, poiLight, poiMesh, poiCam);
						if (udonVideoTexAvailable)
						{
							Decal1.m_DecalEmissionStrength += _Decal1VideoEmissionStrength;
							if (_Decal1UseDecalAlpha)
							{
								Decal1.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal1.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
						}
						Decal1.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
					}
				}
				#endif
				//endex
				
				//ifex _DecalEnabled2==0
				#ifdef GEOM_TYPE_FROND
				PoiDecal Decal2;
				PoiInitStruct(PoiDecal, Decal2)
				Decal2.m_DecalFaceMask = _Decal2FaceMask;
				Decal2.m_DecalMaskChannel = _Decal2MaskChannel;
				Decal2.m_DecalGlobalMask = _Decal2GlobalMask;
				Decal2.m_DecalGlobalMaskBlendType = _Decal2GlobalMaskBlendType;
				Decal2.m_DecalApplyGlobalMaskIndex = _Decal2ApplyGlobalMaskIndex;
				Decal2.m_DecalApplyGlobalMaskBlendType = _Decal2ApplyGlobalMaskBlendType;
				Decal2.m_DecalTexture_ST = _DecalTexture2_ST;
				Decal2.m_DecalTexturePan = _DecalTexture2Pan;
				Decal2.m_DecalTextureUV = _DecalTexture2UV;
				Decal2.m_DecalColor = _DecalColor2;
				Decal2.m_DecalColorThemeIndex = _DecalColor2ThemeIndex;
				Decal2.m_DecalTiled = _DecalTiled2;
				Decal2.m_DecalBlendType = _DecalBlendType2;
				Decal2.m_DecalRotation = _DecalRotation2;
				Decal2.m_DecalScale = _DecalScale2;
				Decal2.m_DecalSideOffset = _DecalSideOffset2;
				Decal2.m_DecalPosition = _DecalPosition2;
				Decal2.m_DecalRotationSpeed = _DecalRotationSpeed2;
				Decal2.m_DecalEmissionStrength = _DecalEmissionStrength2;
				Decal2.m_DecalBlendAlpha = _DecalBlendAlpha2;
				Decal2.m_DecalOverrideAlpha = _DecalOverrideAlpha2;
				Decal2.m_DecalHueShiftEnabled = _DecalHueShiftEnabled2;
				Decal2.m_DecalHueShift = _DecalHueShift2;
				Decal2.m_DecalHueShiftSpeed = _DecalHueShiftSpeed2;
				Decal2.m_DecalDepth = _Decal2Depth;
				Decal2.m_DecalHueAngleStrength = _Decal2HueAngleStrength;
				Decal2.m_DecalChannelSeparationEnable = _Decal2ChannelSeparationEnable;
				Decal2.m_DecalChannelSeparation = _Decal2ChannelSeparation;
				Decal2.m_DecalChannelSeparationPremultiply = _Decal2ChannelSeparationPremultiply;
				Decal2.m_DecalChannelSeparationHue = _Decal2ChannelSeparationHue;
				Decal2.m_DecalChannelSeparationVertical = _Decal2ChannelSeparationVertical;
				Decal2.m_DecalChannelSeparationAngleStrength = _Decal2ChannelSeparationAngleStrength;
				Decal2.m_DecalOverrideAlphaMode = _Decal2OverrideAlphaMode;
				Decal2.Init(decalMask);
				
				#if defined(POI_AUDIOLINK)
				Decal2.m_AudioLinkDecalScaleBand = _AudioLinkDecal2ScaleBand;
				Decal2.m_AudioLinkDecalScale = _AudioLinkDecal2Scale;
				Decal2.m_AudioLinkDecalRotationBand = _AudioLinkDecal2RotationBand;
				Decal2.m_AudioLinkDecalRotation = _AudioLinkDecal2Rotation;
				Decal2.m_AudioLinkDecalAlphaBand = _AudioLinkDecal2AlphaBand;
				Decal2.m_AudioLinkDecalAlpha = _AudioLinkDecal2Alpha;
				Decal2.m_AudioLinkDecalEmissionBand = _AudioLinkDecal2EmissionBand;
				Decal2.m_AudioLinkDecalEmission = _AudioLinkDecal2Emission;
				Decal2.m_DecalRotationCTALBand = _DecalRotationCTALBand2;
				Decal2.m_DecalRotationCTALSpeed = _DecalRotationCTALSpeed2;
				Decal2.m_DecalRotationCTALType = _DecalRotationCTALType2;
				Decal2.m_AudioLinkDecalColorChord = _AudioLinkDecalCC2;
				Decal2.m_AudioLinkDecalSideBand = _AudioLinkDecal2SideBand;
				Decal2.m_AudioLinkDecalSideMin = _AudioLinkDecal2SideMin;
				Decal2.m_AudioLinkDecalSideMax = _AudioLinkDecal2SideMax;
				Decal2.m_AudioLinkDecalChannelSeparation = _AudioLinkDecal2ChannelSeparation;
				Decal2.m_AudioLinkDecalChannelSeparationBand = _AudioLinkDecal2ChannelSeparationBand;
				
				Decal2.InitAudiolink(poiMods);
				#endif
				if (!_Decal2VideoEnabled)
				{
					#if defined(PROP_DECALTEXTURE2) || !defined(OPTIMIZER_ENABLED)
					//ifex _Decal2ChannelSeparationEnable==0
					if (_Decal2ChannelSeparationEnable)
					{
						Decal2.SampleDecalChannelSeparation(_DecalTexture2, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					//ifex _Decal2ChannelSeparationEnable==1
					if (!_Decal2ChannelSeparationEnable)
					{
						Decal2.SampleDecal(_DecalTexture2, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					#else
					Decal2.SampleDecalNoTexture(poiMods, poiLight, poiMesh, poiCam);
					#endif
					Decal2.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
				}
				else
				{
					udonVideoAspectRatio = Decal2.GetVideoAspectRatio(_Udon_VideoTex_TexelSize.zw, _Decal2VideoAspectFix, _Decal2VideoFitToScale);
					if (_Decal2OnlyVideo)
					{
						if (udonVideoTexAvailable)
						{
							Decal2.m_DecalEmissionStrength += _Decal2VideoEmissionStrength;
							if (_Decal2UseDecalAlpha)
							{
								Decal2.SampleDecal(_DecalTexture2, poiMods, poiLight, poiMesh, poiCam);
								Decal2.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal2.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							Decal2.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
						}
					}
					else
					{
						Decal2.SampleDecal(_DecalTexture2, poiMods, poiLight, poiMesh, poiCam);
						if (udonVideoTexAvailable)
						{
							Decal2.m_DecalEmissionStrength += _Decal2VideoEmissionStrength;
							if (_Decal2UseDecalAlpha)
							{
								Decal2.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal2.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
						}
						Decal2.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
					}
				}
				#endif
				//endex
				
				//ifex _DecalEnabled3==0
				#ifdef DEPTH_OF_FIELD_COC_VIEW
				PoiDecal Decal3;
				PoiInitStruct(PoiDecal, Decal3)
				Decal3.m_DecalFaceMask = _Decal3FaceMask;
				Decal3.m_DecalMaskChannel = _Decal3MaskChannel;
				Decal3.m_DecalGlobalMask = _Decal3GlobalMask;
				Decal3.m_DecalGlobalMaskBlendType = _Decal3GlobalMaskBlendType;
				Decal3.m_DecalApplyGlobalMaskIndex = _Decal3ApplyGlobalMaskIndex;
				Decal3.m_DecalApplyGlobalMaskBlendType = _Decal3ApplyGlobalMaskBlendType;
				Decal3.m_DecalTexture_ST = _DecalTexture3_ST;
				Decal3.m_DecalTexturePan = _DecalTexture3Pan;
				Decal3.m_DecalTextureUV = _DecalTexture3UV;
				Decal3.m_DecalColor = _DecalColor3;
				Decal3.m_DecalColorThemeIndex = _DecalColor3ThemeIndex;
				Decal3.m_DecalTiled = _DecalTiled3;
				Decal3.m_DecalBlendType = _DecalBlendType3;
				Decal3.m_DecalRotation = _DecalRotation3;
				Decal3.m_DecalScale = _DecalScale3;
				Decal3.m_DecalSideOffset = _DecalSideOffset3;
				Decal3.m_DecalPosition = _DecalPosition3;
				Decal3.m_DecalRotationSpeed = _DecalRotationSpeed3;
				Decal3.m_DecalEmissionStrength = _DecalEmissionStrength3;
				Decal3.m_DecalBlendAlpha = _DecalBlendAlpha3;
				Decal3.m_DecalOverrideAlpha = _DecalOverrideAlpha3;
				Decal3.m_DecalHueShiftEnabled = _DecalHueShiftEnabled3;
				Decal3.m_DecalHueShift = _DecalHueShift3;
				Decal3.m_DecalHueShiftSpeed = _DecalHueShiftSpeed3;
				Decal3.m_DecalDepth = _Decal3Depth;
				Decal3.m_DecalHueAngleStrength = _Decal3HueAngleStrength;
				Decal3.m_DecalChannelSeparationEnable = _Decal3ChannelSeparationEnable;
				Decal3.m_DecalChannelSeparation = _Decal3ChannelSeparation;
				Decal3.m_DecalChannelSeparationPremultiply = _Decal3ChannelSeparationPremultiply;
				Decal3.m_DecalChannelSeparationHue = _Decal3ChannelSeparationHue;
				Decal3.m_DecalChannelSeparationVertical = _Decal3ChannelSeparationVertical;
				Decal3.m_DecalChannelSeparationAngleStrength = _Decal3ChannelSeparationAngleStrength;
				Decal3.m_DecalOverrideAlphaMode = _Decal3OverrideAlphaMode;
				Decal3.Init(decalMask);
				
				#if defined(POI_AUDIOLINK)
				Decal3.m_AudioLinkDecalScaleBand = _AudioLinkDecal3ScaleBand;
				Decal3.m_AudioLinkDecalScale = _AudioLinkDecal3Scale;
				Decal3.m_AudioLinkDecalRotationBand = _AudioLinkDecal3RotationBand;
				Decal3.m_AudioLinkDecalRotation = _AudioLinkDecal3Rotation;
				Decal3.m_AudioLinkDecalAlphaBand = _AudioLinkDecal3AlphaBand;
				Decal3.m_AudioLinkDecalAlpha = _AudioLinkDecal3Alpha;
				Decal3.m_AudioLinkDecalEmissionBand = _AudioLinkDecal3EmissionBand;
				Decal3.m_AudioLinkDecalEmission = _AudioLinkDecal3Emission;
				Decal3.m_DecalRotationCTALBand = _DecalRotationCTALBand3;
				Decal3.m_DecalRotationCTALSpeed = _DecalRotationCTALSpeed3;
				Decal3.m_DecalRotationCTALType = _DecalRotationCTALType3;
				Decal3.m_AudioLinkDecalColorChord = _AudioLinkDecalCC3;
				Decal3.m_AudioLinkDecalSideBand = _AudioLinkDecal3SideBand;
				Decal3.m_AudioLinkDecalSideMin = _AudioLinkDecal3SideMin;
				Decal3.m_AudioLinkDecalSideMax = _AudioLinkDecal3SideMax;
				Decal3.m_AudioLinkDecalChannelSeparation = _AudioLinkDecal3ChannelSeparation;
				Decal3.m_AudioLinkDecalChannelSeparationBand = _AudioLinkDecal3ChannelSeparationBand;
				
				Decal3.InitAudiolink(poiMods);
				#endif
				if (!_Decal3VideoEnabled)
				{
					#if defined(PROP_DECALTEXTURE3) || !defined(OPTIMIZER_ENABLED)
					//ifex _Decal3ChannelSeparationEnable==0
					if (_Decal3ChannelSeparationEnable)
					{
						Decal3.SampleDecalChannelSeparation(_DecalTexture3, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					//ifex _Decal3ChannelSeparationEnable==1
					if (!_Decal3ChannelSeparationEnable)
					{
						Decal3.SampleDecal(_DecalTexture3, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					#else
					Decal3.SampleDecalNoTexture(poiMods, poiLight, poiMesh, poiCam);
					#endif
					Decal3.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
				}
				else
				{
					udonVideoAspectRatio = Decal3.GetVideoAspectRatio(_Udon_VideoTex_TexelSize.zw, _Decal3VideoAspectFix, _Decal3VideoFitToScale);
					if (_Decal3OnlyVideo)
					{
						if (udonVideoTexAvailable)
						{
							Decal3.m_DecalEmissionStrength += _Decal3VideoEmissionStrength;
							if (_Decal3UseDecalAlpha)
							{
								Decal3.SampleDecal(_DecalTexture3, poiMods, poiLight, poiMesh, poiCam);
								Decal3.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal3.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							Decal3.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
						}
					}
					else
					{
						Decal3.SampleDecal(_DecalTexture3, poiMods, poiLight, poiMesh, poiCam);
						if (udonVideoTexAvailable)
						{
							Decal3.m_DecalEmissionStrength += _Decal3VideoEmissionStrength;
							if (_Decal3UseDecalAlpha)
							{
								Decal3.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal3.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
						}
						Decal3.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
					}
				}
				#endif
				//endex
				//if (alphaOverride)
				//{
				
				//poiFragData.baseColor = decalAlpha;
				//poiFragData.alpha *= decalAlpha;
				
				//}
				//poiFragData.baseColor = saturate(poiFragData.baseColor);
				
			}
			#endif
			
			//ifex _EnableDissolve==0
			#ifdef DISTORT
			void applyDissolve(inout PoiFragData poiFragData, in PoiMesh poiMesh, inout PoiMods poiMods, in PoiCam poiCam, in PoiLight poiLight)
			{
				#if defined(PROP_DISSOLVEMASK) || !defined(OPTIMIZER_ENABLED)
				float dissolveMask = POI2D_SAMPLER_PAN(_DissolveMask, _MainTex, poiUV(poiMesh.uv[_DissolveMaskUV], _DissolveMask_ST), _DissolveMaskPan).r;
				#else
				float dissolveMask = 1;
				#endif
				UNITY_BRANCH
				if (_DissolveUseVertexColors > 0)
				{
					// Vertex Color Imprecision hype
					dissolveMask = ceil(poiMesh.vertexColor[_DissolveUseVertexColors] * 100000) / 100000;
				}
				if (_DissolveMaskGlobalMask > 0)
				{
					dissolveMask = maskBlend(dissolveMask, poiMods.globalMask[_DissolveMaskGlobalMask - 1], _DissolveMaskGlobalMaskBlendType);
				}
				
				#if defined(PROP_DISSOLVETOTEXTURE) || !defined(OPTIMIZER_ENABLED)
				dissolveToTexture = POI2D_SAMPLER_PAN(_DissolveToTexture, _MainTex, poiUV(poiMesh.uv[_DissolveToTextureUV], _DissolveToTexture_ST), _DissolveToTexturePan) * float4(poiThemeColor(poiMods, _DissolveTextureColor.rgb, _DissolveTextureColorThemeIndex), _DissolveTextureColor.a);
				#else
				dissolveToTexture = _DissolveTextureColor;
				#endif
				
				#if defined(PROP_DISSOLVENOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
				float dissolveNoiseTexture = POI2D_SAMPLER_PAN(_DissolveNoiseTexture, _MainTex, poiUV(poiMesh.uv[_DissolveNoiseTextureUV], _DissolveNoiseTexture_ST), _DissolveNoiseTexturePan).r;
				#else
				float dissolveNoiseTexture = 1;
				#endif
				
				float da = _DissolveAlpha
				+ _DissolveAlpha0
				+ _DissolveAlpha1
				+ _DissolveAlpha2
				+ _DissolveAlpha3
				+ _DissolveAlpha4
				+ _DissolveAlpha5
				+ _DissolveAlpha6
				+ _DissolveAlpha7
				+ _DissolveAlpha8
				+ _DissolveAlpha9;
				float dds = _DissolveDetailStrength;
				
				if (_UVTileDissolveEnabled)
				{
					float2 udim = floor(poiMesh.uv[(int)_UVTileDissolveUV]);
					
					float4 xMask = float4((udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					da += (udim.y >= 0 && udim.y < 1) * dot(float4(_UVTileDissolveAlpha_Row0_0, _UVTileDissolveAlpha_Row0_1, _UVTileDissolveAlpha_Row0_2, _UVTileDissolveAlpha_Row0_3), xMask);
					da += (udim.y >= 1 && udim.y < 2) * dot(float4(_UVTileDissolveAlpha_Row1_0, _UVTileDissolveAlpha_Row1_1, _UVTileDissolveAlpha_Row1_2, _UVTileDissolveAlpha_Row1_3), xMask);
					da += (udim.y >= 2 && udim.y < 3) * dot(float4(_UVTileDissolveAlpha_Row2_0, _UVTileDissolveAlpha_Row2_1, _UVTileDissolveAlpha_Row2_2, _UVTileDissolveAlpha_Row2_3), xMask);
					da += (udim.y >= 3 && udim.y < 4) * dot(float4(_UVTileDissolveAlpha_Row3_0, _UVTileDissolveAlpha_Row3_1, _UVTileDissolveAlpha_Row3_2, _UVTileDissolveAlpha_Row3_3), xMask);
				}
				
				#ifdef POI_AUDIOLINK
				UNITY_BRANCH
				if (_EnableDissolveAudioLink && poiMods.audioLinkAvailable)
				{
					da += lerp(_AudioLinkDissolveAlpha.x, _AudioLinkDissolveAlpha.y, poiMods.audioLink[_AudioLinkDissolveAlphaBand]);
					dds += lerp(_AudioLinkDissolveDetail.x, _AudioLinkDissolveDetail.y, poiMods.audioLink[_AudioLinkDissolveDetailBand]);
				}
				#endif
				
				da = saturate(da);
				dds = saturate(dds);
				
				if (_DissolveMaskInvert)
				{
					dissolveMask = 1 - dissolveMask;
				}
				#if defined(PROP_DISSOLVEDETAILNOISE) || !defined(OPTIMIZER_ENABLED)
				float dissolveDetailNoise = POI2D_SAMPLER_PAN(_DissolveDetailNoise, _MainTex, poiUV(poiMesh.uv[_DissolveDetailNoiseUV], _DissolveDetailNoise_ST), _DissolveDetailNoisePan);
				#else
				float dissolveDetailNoise = 0;
				#endif
				if (_DissolveInvertNoise)
				{
					dissolveNoiseTexture = 1 - dissolveNoiseTexture;
				}
				if (_DissolveInvertDetailNoise)
				{
					dissolveDetailNoise = 1 - dissolveDetailNoise;
				}
				if (_ContinuousDissolve != 0)
				{
					da = sin(_Time.x * _ContinuousDissolve) * .5 + .5;
				}
				da *= dissolveMask;
				dissolveAlpha = da;
				edgeAlpha = 0;
				
				[flatten]
				switch(_DissolveType)
				{
					default: // Basic (case 1)
					
					{
						da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						dissolveAlpha = da;
						//Adjust detail strength to avoid artifacts
						dds *= smoothstep(1, 0.99, da) * lerp(1, smoothstep(0, lerp(0.01, 0.1, dds), da), _DissolveDetailEdgeSmoothing);
						float noise = saturate(dissolveNoiseTexture - dissolveDetailNoise * dds);
						
						noise = saturate(noise * 0.998 + 0.001);
						dissolveAlpha = dissolveAlpha >= noise;
						edgeAlpha = remapClamped(da + _DissolveEdgeWidth, da, noise) * (1 - dissolveAlpha);
						break;
					}
					case 2: // Point to Point
					
					{
						float3 direction;
						float3 currentPos;
						float distanceTo = 0;
						direction = normalize(_DissolveEndPoint - _DissolveStartPoint);
						currentPos = lerp(_DissolveStartPoint, _DissolveEndPoint, dissolveAlpha);
						
						UNITY_BRANCH
						if (_DissolveP2PWorldLocal != 1)
						{
							float3 pos = _DissolveP2PWorldLocal == 0 ? poiMesh.localPos.rgb : poiMesh.vertexColor.rgb;
							distanceTo = dot(pos - currentPos, direction) - dissolveDetailNoise * dds;
							edgeAlpha = smoothstep(_DissolveP2PEdgeLength + .00001, 0, distanceTo);
							dissolveAlpha = step(distanceTo, 0);
							edgeAlpha *= 1 - dissolveAlpha;
						}
						else
						{
							distanceTo = dot(poiMesh.worldPos - currentPos, direction) - dissolveDetailNoise * dds;
							edgeAlpha = smoothstep(_DissolveP2PEdgeLength + .00001, 0, distanceTo);
							dissolveAlpha = (distanceTo < 0) ? 1 : 0;
							edgeAlpha *= 1 - dissolveAlpha;
						}
						
						if (_DissolveP2PClamp)
						{
							dissolveAlpha = saturate(dissolveAlpha * smoothstep(0, 0.01, da) + smoothstep(0.99, 1, da));
							edgeAlpha *= smoothstep(0, 0.01, da);
						}
						
						break;
					}
					case 3: // Spherical
					
					{
						if (_SphericalDissolveInvert)
						{
							da = remap(da, 1, 0, -_DissolveEdgeWidth, 1);
						}
						else
						{
							da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						}
						
						dissolveAlpha = da;
						dds *= smoothstep(0, 0.2 * dds + 0.01, dissolveAlpha) * lerp(1, smoothstep(1, 1 - 0.2 * dds - 0.01, dissolveAlpha), _DissolveDetailEdgeSmoothing);
						float currentDistance = lerp(0, _SphericalDissolveRadius, dissolveAlpha);
						float fragDistance = distance(_SphericalDissolveCenter, poiMesh.localPos.xyz);
						float normalizedDistance;
						normalizedDistance = (fragDistance - currentDistance) / (_SphericalDissolveRadius + 0.0001) - dissolveDetailNoise * dds;
						
						if (_SphericalDissolveInvert)
						{
							dissolveAlpha = (normalizedDistance > 0) ? 1 : 0;
							edgeAlpha = smoothstep(_DissolveEdgeWidth + .00001, 0, -normalizedDistance);
						}
						else
						{
							dissolveAlpha = (normalizedDistance < 0) ? 1 : 0;
							edgeAlpha = smoothstep(_DissolveEdgeWidth + .00001, 0, normalizedDistance);
						}
						
						if (_SphericalDissolveClamp)
						{
							da = lerp(da, 1 - da, _SphericalDissolveInvert);
							dissolveAlpha = saturate(dissolveAlpha * smoothstep(0, 0.01, da) + smoothstep(0.99, 1, da));
							edgeAlpha *= smoothstep(0, 0.01, da);
						}
						
						break;
					}
					case 4: // CenterOut
					
					{
						float ramp = 0.5;
						float noise;
						
						[flatten]
						switch(_CenterOutDissolveMode)
						{
							case 1: // View Direction
							
							{
								ramp = saturate(lerp(poiLight.vertexNDotV, poiLight.nDotV, _CenterOutDissolveNormals));
								break;
							}
							case 2: // Custom Direction
							
							{
								ramp = dot(normalize(_CenterOutDissolveDirection), lerp(poiMesh.normals[0], poiMesh.normals[1], _CenterOutDissolveNormals));
								ramp = saturate(ramp * .5 + 0.5);
								break;
							}
							case 3: // Light Direction
							
							{
								ramp = lerp(poiLight.vertexNDotL, poiLight.nDotL, _CenterOutDissolveNormals);
								ramp = saturate(ramp * .5 + 0.5);
								break;
							}
						}
						
						if (_CenterOutDissolvePower != 1)
						{
							ramp = pow(ramp, _CenterOutDissolvePower);
						}
						
						if (!_CenterOutDissolveInvert)
						{
							ramp = 1 - ramp;
						}
						
						da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						dissolveAlpha = da;
						//Adjust detail strength to avoid artifacts
						dds *= smoothstep(1, 0.99, da) * lerp(1, smoothstep(0, lerp(0.01, 0.1, dds), da), _DissolveDetailEdgeSmoothing);
						
						noise = saturate(ramp - dissolveDetailNoise * dds);
						noise = saturate(noise * 0.998 + 0.001);
						dissolveAlpha = dissolveAlpha >= noise;
						edgeAlpha = remapClamped(da + _DissolveEdgeWidth, da, noise) * (1 - dissolveAlpha);
						break;
					}
				}
				
				#ifndef POI_SHADOW
				UNITY_BRANCH
				if (_DissolveHueShiftEnabled)
				{
					dissolveToTexture.rgb = hueShift(dissolveToTexture.rgb, _DissolveHueShift + _Time.x * _DissolveHueShiftSpeed);
				}
				#endif
				
				poiFragData.alpha = lerp(poiFragData.alpha, dissolveToTexture.a, dissolveAlpha * .999999);
				
				#if !defined(POI_PASS_OUTLINE) && !defined(UNITY_PASS_SHADOWCASTER)
				poiFragData.baseColor = lerp(poiFragData.baseColor, dissolveToTexture.rgb, dissolveAlpha * .999999);
				
				if (_DissolveApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _DissolveApplyGlobalMaskIndex - 1, _DissolveApplyGlobalMaskBlendType, dissolveAlpha * .999999);
				}
				if (_DissolveInverseApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _DissolveInverseApplyGlobalMaskIndex - 1, _DissolveInverseApplyGlobalMaskBlendType, 1-(dissolveAlpha * .999999));
				}
				UNITY_BRANCH
				if (_DissolveEdgeWidth || (_DissolveType == 2 && _DissolveP2PEdgeLength != 0))
				{
					edgeColor = tex2D(_DissolveEdgeGradient, poiUV(float2(edgeAlpha, edgeAlpha), _DissolveEdgeGradient_ST)) * float4(poiThemeColor(poiMods, _DissolveEdgeColor.rgb, _DissolveEdgeColorThemeIndex), _DissolveEdgeColor.a);
					#ifndef POI_SHADOW
					UNITY_BRANCH
					if (_DissolveEdgeHueShiftEnabled)
					{
						edgeColor.rgb = hueShift(edgeColor.rgb, _DissolveEdgeHueShift + _Time.x * _DissolveEdgeHueShiftSpeed);
					}
					#endif
					poiFragData.baseColor = lerp(poiFragData.baseColor, edgeColor.rgb, smoothstep(0, 1 - _DissolveEdgeHardness * .99999999999, edgeAlpha));
				}
				
				poiFragData.emission += lerp(0, dissolveToTexture * _DissolveToEmissionStrength, dissolveAlpha) + lerp(0, edgeColor.rgb * _DissolveEdgeEmission, smoothstep(0, 1 - _DissolveEdgeHardness * .99999999999, edgeAlpha));
				#endif
			}
			#endif
			//endex
			
			//ifex _EnableAniso==0
			#ifdef POI_ANISOTROPICS
			/*
			float D_GGX_Anisotropic(float at, float ab, float TdotH, float BdotH, float NdotH)
			{
				// Burley 2012, "Physically-Based Shading at Disney"
				
				// The values at and ab are perceptualRoughness^2, a2 is therefore perceptualRoughness^4
				// The dot product below computes perceptualRoughness^8. We cannot fit in fp16 without clamping
				// the roughness to too high values so we perform the dot product and the division in fp32
				float a2 = at * ab;
				float3 d = float3(ab * TdotH, at * BdotH, a2 * NdotH);
				float d2 = dot(d, d);
				float b2 = a2 / d2;
				return a2 * b2 * b2 * (1.0 / UNITY_PI);
			}
			
			//-------------------------------------GGX Anisotropic visibility function
			float V_SmithGGXCorrelated_Anisotropic(float at, float ab, float TdotV, float BdotV, float TdotL, float BdotL, float NdotV, float NdotL)
			{
				// Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"
				float lambdaV = NdotL * length(float3(at * TdotV, ab * BdotV, NdotV));
				float lambdaL = NdotV * length(float3(at * TdotL, ab * BdotL, NdotL));
				return 0.5 / (lambdaV + lambdaL);
			}
			*/
			
			float calculateAnisotropics(float3 binormal, float offset, float3 normal, float3 viewDir, float3 LightDirection, float exponent, float strength, float shadowMask)
			{
				float3 ShiftedTangent = normalize(binormal + offset * normal);
				float3 H = normalize(LightDirection + viewDir);
				float dotTH = dot(ShiftedTangent, H);
				float sinTH = sqrt(1.0 - dotTH * dotTH);
				float dirAtten = smoothstep(-1.0, 0.0, dotTH);
				return saturate(dirAtten * pow(sinTH, exponent) * strength) * shadowMask;
			}
			
			float aaEdgeFeather(float value, float edge, float feather)
			{
				float edgeMin = saturate(edge - feather * 0.5);
				float edgeMax = saturate(edge + feather * 0.5);
				return saturate((value - edgeMin) / saturate(edgeMax - edgeMin + fwidth(value)));
			}
			
			void applyAnisotropics(inout PoiFragData poiFragData, inout PoiLight poiLight, in PoiCam poiCam, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				#if defined(PROP_ANISOCOLORMAP) || !defined(OPTIMIZER_ENABLED)
				float4 specMap = POI2D_SAMPLER_PAN(_AnisoColorMap, _MainTex, poiUV(poiMesh.uv[_AnisoColorMapUV], _AnisoColorMap_ST), _AnisoColorMapPan);
				#else
				float4 specMap = float4(1, 1, 1, 0);
				#endif
				
				float shadowMask = lerp(1, poiMax(poiLight.rampedLightMap), _AnisoHideInShadow);
				#ifdef POI_PASS_ADD
				shadowMask *= poiLight.additiveShadow;
				#endif
				
				if (_AnisoGlobalMask > 0)
				{
					shadowMask = customBlend(shadowMask, poiMods.globalMask[_AnisoGlobalMask-1], _AnisoGlobalMaskBlendType);
				}
				
				float spec0 = calculateAnisotropics(lerp(poiMesh.binormal[1], poiMesh.tangent[1], _Aniso0SwitchDirection), _Aniso0Offset +_Aniso0OffsetMapStrength * specMap.a, poiMesh.normals[1], poiCam.viewDir, poiLight.direction, _Aniso0Power * 1000, _Aniso0Strength, shadowMask);
				float spec1 = calculateAnisotropics(lerp(poiMesh.binormal[1], poiMesh.tangent[1], _Aniso1SwitchDirection), _Aniso1Offset +_Aniso1OffsetMapStrength * specMap.a, poiMesh.normals[1], poiCam.viewDir, poiLight.direction, _Aniso1Power * 1000, _Aniso1Strength, shadowMask);
				
				spec0 = lerp(spec0, aaEdgeFeather(spec0, _Aniso0Edge, _Aniso0Blur), _Aniso0ToonMode);
				spec1 = lerp(spec1, aaEdgeFeather(spec1, _Aniso1Edge, _Aniso1Blur), _Aniso1ToonMode);
				
				float3 spec0Color = specMap.rgb * poiThemeColor(poiMods, _Aniso0Tint.rgb, _Aniso0TintIndex);
				float3 spec1Color = specMap.rgb * poiThemeColor(poiMods, _Aniso1Tint.rgb, _Aniso1TintIndex);
				
				float3 finalSpec = saturate(saturate(spec0 * spec0Color) + saturate(spec1 * spec1Color)) * lerp(1, poiFragData.baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), poiLight.directColor, _AnisoUseLightColor);
				float3 baseColor = poiFragData.baseColor;
				
				poiFragData.baseColor = lerp(poiFragData.baseColor, spec1Color * lerp(1, baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), poiLight.directColor, _AnisoUseLightColor), _AnisoReplace * spec1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, spec0Color * lerp(1, baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), poiLight.directColor, _AnisoUseLightColor), _AnisoReplace * spec0);
				poiLight.finalLightAdd += max(0, finalSpec * _AnisoAdd);
				
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					for (int index = 0; index < 4; index++)
					{
						float vSpec0 = calculateAnisotropics(lerp(poiMesh.binormal[1], poiMesh.tangent[1], _Aniso0SwitchDirection), _Aniso0Offset +_Aniso0OffsetMapStrength * specMap.a, poiMesh.normals[1], poiCam.viewDir, poiLight.vDirection[index], _Aniso0Power * 1000, _Aniso0Strength, poiLight.vSaturatedDotNL[index]);
						float vSpec1 = calculateAnisotropics(lerp(poiMesh.binormal[1], poiMesh.tangent[1], _Aniso1SwitchDirection), _Aniso1Offset +_Aniso1OffsetMapStrength * specMap.a, poiMesh.normals[1], poiCam.viewDir, poiLight.vDirection[index], _Aniso1Power * 1000, _Aniso1Strength, poiLight.vSaturatedDotNL[index]);
						
						vSpec0 = lerp(vSpec0, aaEdgeFeather(vSpec0, _Aniso0Edge, _Aniso0Blur), _Aniso0ToonMode);
						vSpec1 = lerp(vSpec1, aaEdgeFeather(vSpec1, _Aniso1Edge, _Aniso1Blur), _Aniso1ToonMode);
						
						float3 vSpec0Color = spec0Color;
						float3 vSpec1Color = spec1Color;
						
						poiLight.finalLightAdd += max(0, saturate(saturate(vSpec0 * vSpec0Color) + saturate(vSpec1 * vSpec1Color)) * lerp(1, poiFragData.baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.vColor[index], float3(0.299, 0.587, 0.114)), poiLight.vColor[index], _AnisoUseLightColor) * _AnisoAdd);
						
						poiFragData.baseColor = lerp(poiFragData.baseColor, vSpec1Color * lerp(1, baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.vColor[index], float3(0.299, 0.587, 0.114)), poiLight.vColor[index], _AnisoUseLightColor), _AnisoReplace * vSpec1);
						poiFragData.baseColor = lerp(poiFragData.baseColor, vSpec0Color * lerp(1, baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.vColor[index], float3(0.299, 0.587, 0.114)), poiLight.vColor[index], _AnisoUseLightColor), _AnisoReplace * vSpec0);
					}
					#endif
				}
			}
			#endif
			//endex
			
			//ifex _MatcapEnable==0 && _Matcap2Enable==0 && _Matcap3Enable==0 && _Matcap4Enable==0
			void blendMatcap(inout PoiLight poiLight, inout PoiFragData poiFragData, in PoiMods poiMods, float add, float lightAdd, float multiply, float replace, float mixed, float screen, float4 matcapColor, float matcapMask, float emissionStrength, float matcapLightMask, uint globalMaskIndex, float globalMaskBlendType, in MatcapAudioLinkData matcapALD)
			{
				if (matcapLightMask)
				{
					matcapMask *= lerp(1, poiLight.rampedLightMap, matcapLightMask);
				}
				if (globalMaskIndex > 0)
				{
					matcapMask = maskBlend(matcapMask, poiMods.globalMask[globalMaskIndex - 1], globalMaskBlendType);
				}
				
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapColor.a = saturate(matcapColor.a + lerp(matcapALD.matcapALAlphaAdd.x, matcapALD.matcapALAlphaAdd.y, poiMods.audioLink[matcapALD.matcapALAlphaAddBand]));
					emissionStrength += lerp(matcapALD.matcapALEmissionAdd.x, matcapALD.matcapALEmissionAdd.y, poiMods.audioLink[matcapALD.matcapALEmissionAddBand]);
				}
				#endif
				
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, matcapColor.rgb, replace * matcapMask * matcapColor.a * .999999);
				poiFragData.baseColor.rgb *= lerp(1, matcapColor.rgb, multiply * matcapMask * matcapColor.a);
				poiFragData.baseColor.rgb += matcapColor.rgb * add * matcapMask * matcapColor.a;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, blendScreen(poiFragData.baseColor.rgb, matcapColor.rgb), screen * matcapMask * matcapColor.a);
				#ifdef POI_PASS_BASE
				poiLight.finalLightAdd += matcapColor.rgb * lightAdd * matcapMask * matcapColor.a;
				#endif
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, poiFragData.baseColor.rgb + poiFragData.baseColor.rgb * matcapColor.rgb, mixed * matcapMask * matcapColor.a);
				poiFragData.emission += matcapColor.rgb * emissionStrength * matcapMask * matcapColor.a;
			}
			
			void getMatcapUV(inout float2 matcapUV, in float2 matcapPan, in float matcapUVMode, in float matcapUVToBlend, in float2 matCapBlendUV, in float matcapRotation, in float matcapBorder, in float3 normal, in PoiCam poiCam, in PoiLight poiLight, in PoiMesh poiMesh, in float matcapNormalStrength, in MatcapAudioLinkData matcapALD)
			{
				switch(matcapUVMode)
				{
					// Normal / UTS
					case 0:
					{
						float3 viewNormal = (mul(UNITY_MATRIX_V, float4(normal, 0))).rgb;
						float3 NormalBlend_MatCapUV_Detail = viewNormal.rgb * float3(-1, -1, 1);
						float3 NormalBlend_MatCapUV_Base = (mul(UNITY_MATRIX_V, float4(poiCam.viewDir, 0)).rgb * float3(-1, -1, 1)) + float3(0, 0, 1);
						float3 noSknewViewNormal = NormalBlend_MatCapUV_Base * dot(NormalBlend_MatCapUV_Base, NormalBlend_MatCapUV_Detail) / NormalBlend_MatCapUV_Base.b - NormalBlend_MatCapUV_Detail;
						
						matcapUV = noSknewViewNormal.rg * matcapBorder + 0.5;
						break;
					}
					// Top Pinch
					case 1:
					{
						float3 worldViewUp = normalize(float3(0, 1, 0) - poiCam.viewDir * dot(poiCam.viewDir, float3(0, 1, 0)));
						float3 worldViewRight = normalize(cross(poiCam.viewDir, worldViewUp));
						matcapUV = float2(dot(worldViewRight, normal), dot(worldViewUp, normal)) * matcapBorder + 0.5;
						break;
					}
					// Custom Double Sided
					case 2:
					{
						float3 reflection = reflect(-poiCam.viewDir, normal);
						float2 uv = float2(dot(reflection, float3(1, 0, 0)), dot(reflection, float3(0, 1, 0)));
						matcapUV = uv * matcapBorder + 0.5;
						break;
					}
					// Gradient
					case 3:
					{
						matcapUV = 1 - abs(dot(normal, poiCam.viewDir));
						#ifdef POI_AUDIOLINK
						if (matcapALD.matcapALEnabled)
						{
							matcapUV += AudioLinkGetChronoTime(matcapALD.matcapALChronoPanType, matcapALD.matcapALChronoPanBand) * matcapALD.matcapALChronoPanSpeed;
						}
						#endif
						break;
					}
				}
				matcapUV = lerp(matcapUV, poiMesh.uv[matcapUVToBlend], matCapBlendUV);
				matcapUV += matcapPan * _Time.x;
				matcapUV = RotateUV(matcapUV, matcapRotation * PI, float2(.5, .5), 1.0f);
				
				if (IsInMirror() && matcapUVMode != 3)
				{
					matcapUV.x = 1 - matcapUV.x;
				}
			}
			
			//endex
			//ifex _MatcapEnable==0 && _Matcap2Enable==0 && _Matcap3Enable==0 && _Matcap4Enable==0
			#if defined(POI_MATCAP0) || defined(COLOR_GRADING_HDR_3D) || defined(POI_MATCAP2) || defined(POI_MATCAP3)
			void applyMatcap(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, inout PoiLight poiLight, in PoiMods poiMods)
			{
				float4 matcap = 0;
				float matcapMask = 0;
				float4 matcap2 = 0;
				float matcap2Mask = 0;
				float4 matcap3 = 0;
				float matcap3Mask = 0;
				float4 matcap4 = 0;
				float matcap4Mask = 0;
				float2 matcapUV = 0;
				float matcapIntensity;
				struct MatcapAudioLinkData matcapALD;
				//endex
				
				//ifex _MatcapEnable==0
				// Matcap 1
				#ifdef POI_MATCAP0
				matcapALD.matcapALEnabled = _Matcap0ALEnabled;
				matcapALD.matcapALAlphaAddBand = _Matcap0ALAlphaAddBand;
				matcapALD.matcapALAlphaAdd = _Matcap0ALAlphaAdd;
				matcapALD.matcapALEmissionAddBand = _Matcap0ALEmissionAddBand;
				matcapALD.matcapALEmissionAdd = _Matcap0ALEmissionAdd;
				matcapALD.matcapALIntensityAddBand = _Matcap0ALIntensityAddBand;
				matcapALD.matcapALIntensityAdd = _Matcap0ALIntensityAdd;
				matcapALD.matcapALChronoPanType = _Matcap0ALChronoPanType;
				matcapALD.matcapALChronoPanBand = _Matcap0ALChronoPanBand;
				matcapALD.matcapALChronoPanSpeed = _Matcap0ALChronoPanSpeed;
				
				float3 normal0 = lerp(poiMesh.normals[0], poiMesh.normals[1], _MatcapNormal);
				#ifdef POI_MATCAP0_CUSTOM_NORMAL
				#if defined(PROP_MATCAP0NORMALMAP) || !defined(OPTIMIZER_ENABLED)
				normal0 = calculateNormal(poiMesh.normals[_MatcapNormal], poiMesh, _Matcap0NormalMap, _Matcap0NormalMap_ST, _Matcap0NormalMapPan, _Matcap0NormalMapUV, _Matcap0NormalMapScale);
				#endif
				#endif
				
				#if defined(PROP_MATCAP) || !defined(OPTIMIZER_ENABLED)
				getMatcapUV(matcapUV, _MatcapPan.xy, _MatcapUVMode, _MatcapUVToBlend, _MatCapBlendUV1.xy, _MatcapRotation, _MatcapBorder, normal0, poiCam, poiLight, poiMesh, _MatcapNormal, matcapALD);
				if (_MatcapSmoothnessEnabled)
				{
					float mipCount0 = 9;
					if (_Matcap_TexelSize.z == 8192) mipCount0 = 13;
					if (_Matcap_TexelSize.z == 4096) mipCount0 = 12;
					if (_Matcap_TexelSize.z == 2048) mipCount0 = 11;
					if (_Matcap_TexelSize.z == 1024) mipCount0 = 10;
					if (_Matcap_TexelSize.z == 512) mipCount0 = 9;
					if (_Matcap_TexelSize.z == 256) mipCount0 = 8;
					if (_Matcap_TexelSize.z == 128) mipCount0 = 7;
					if (_Matcap_TexelSize.z == 64) mipCount0 = 6;
					if (_Matcap_TexelSize.z == 32) mipCount0 = 5;
					
					float matcapSmoothness = _MatcapSmoothness;
					
					if (_MatcapMaskSmoothnessApply)
					{
						#if defined(PROP_MATCAPMASK) || !defined(OPTIMIZER_ENABLED)
						matcapSmoothness *= POI2D_SAMPLER_PAN(_MatcapMask, _MainTex, poiUV(poiMesh.uv[_MatcapMaskUV], _MatcapMask_ST), _MatcapMaskPan)[_MatcapMaskSmoothnessChannel];
						#endif
					}
					matcapSmoothness = (1 - matcapSmoothness) * mipCount0;
					matcap = UNITY_SAMPLE_TEX2D_SAMPLER_LOD(_Matcap, _trilinear_repeat, TRANSFORM_TEX(matcapUV, _Matcap), matcapSmoothness) * float4(poiThemeColor(poiMods, _MatcapColor.rgb, _MatcapColorThemeIndex), _MatcapColor.a);
				}
				else
				{
					matcap = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap)) * float4(poiThemeColor(poiMods, _MatcapColor.rgb, _MatcapColorThemeIndex), _MatcapColor.a);
				}
				#else
				matcap = float4(poiThemeColor(poiMods, _MatcapColor.rgb, _MatcapColorThemeIndex), _MatcapColor.a);
				#endif
				
				matcapIntensity = _MatcapIntensity;
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapIntensity += lerp(matcapALD.matcapALIntensityAdd.x, matcapALD.matcapALIntensityAdd.y, poiMods.audioLink[matcapALD.matcapALIntensityAddBand]);
					matcapIntensity = max(0, matcapIntensity);
				}
				#endif
				matcap.rgb *= matcapIntensity;
				matcap.rgb = lerp(matcap.rgb, matcap.rgb * poiFragData.baseColor.rgb, _MatcapBaseColorMix);
				
				#if defined(PROP_MATCAPMASK) || !defined(OPTIMIZER_ENABLED)
				matcapMask = POI2D_SAMPLER_PAN(_MatcapMask, _MainTex, poiUV(poiMesh.uv[_MatcapMaskUV], _MatcapMask_ST), _MatcapMaskPan)[_MatcapMaskChannel];
				#else
				matcapMask = 1;
				#endif
				
				if (_MatcapMaskInvert)
				{
					matcapMask = 1 - matcapMask;
				}
				
				#ifdef TPS_Penetrator
				if (_MatcapTPSDepthEnabled)
				{
					matcapMask = lerp(0, matcapMask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _MatcapTPSMaskStrength);
				}
				#endif
				
				poiFragData.alpha *= lerp(1, matcap.a, matcapMask * _MatcapAlphaOverride);
				
				//UNITY_BRANCH
				if (_MatcapHueShiftEnabled)
				{
					matcap.rgb = hueShift(matcap.rgb, _MatcapHueShift + _Time.x * _MatcapHueShiftSpeed);
				}
				
				if (_MatcapApplyToAlphaEnabled)
				{
					float matcapAlphaApplyValue = dot(matcap.rgb, float3(0.299, 0.587, 0.114)); // Greyscale
					if (_MatcapApplyToAlphaSourceBlend == 1) // Max
					
					{
						matcapAlphaApplyValue = poiMax(matcap.rgb);
					}
					if (_MatcapApplyToAlphaBlendType == 0) // Add
					
					{
						poiFragData.alpha += lerp(0, matcapAlphaApplyValue, _MatcapApplyToAlphaBlending);
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
					if (_MatcapApplyToAlphaBlendType == 1) // Multiply
					
					{
						poiFragData.alpha *= lerp(1, matcapAlphaApplyValue, _MatcapApplyToAlphaBlending);
					}
				}
				
				blendMatcap(poiLight, poiFragData, poiMods, _MatcapAdd, _MatcapAddToLight, _MatcapMultiply, _MatcapReplace, _MatcapMixed, _MatcapScreen, matcap, matcapMask, _MatcapEmissionStrength, _MatcapLightMask, _MatcapMaskGlobalMask, _MatcapMaskGlobalMaskBlendType, matcapALD);
				#endif
				//endex
				//ifex _Matcap2Enable==0
				// Matcap 2
				#ifdef COLOR_GRADING_HDR_3D
				matcapALD.matcapALEnabled = _Matcap1ALEnabled;
				matcapALD.matcapALAlphaAddBand = _Matcap1ALAlphaAddBand;
				matcapALD.matcapALAlphaAdd = _Matcap1ALAlphaAdd;
				matcapALD.matcapALEmissionAddBand = _Matcap1ALEmissionAddBand;
				matcapALD.matcapALEmissionAdd = _Matcap1ALEmissionAdd;
				matcapALD.matcapALIntensityAddBand = _Matcap1ALIntensityAddBand;
				matcapALD.matcapALIntensityAdd = _Matcap1ALIntensityAdd;
				matcapALD.matcapALChronoPanType = _Matcap1ALChronoPanType;
				matcapALD.matcapALChronoPanBand = _Matcap1ALChronoPanBand;
				matcapALD.matcapALChronoPanSpeed = _Matcap1ALChronoPanSpeed;
				
				float3 normal1 = lerp(poiMesh.normals[0], poiMesh.normals[1], _Matcap2Normal);
				#ifdef POI_MATCAP1_CUSTOM_NORMAL
				#if defined(PROP_MATCAP1NORMALMAP) || !defined(OPTIMIZER_ENABLED)
				normal1 = calculateNormal(poiMesh.normals[_Matcap2Normal], poiMesh, _Matcap1NormalMap, _Matcap1NormalMap_ST, _Matcap1NormalMapPan, _Matcap1NormalMapUV, _Matcap1NormalMapScale);
				#endif
				#endif
				
				#if defined(PROP_MATCAP2) || !defined(OPTIMIZER_ENABLED)
				getMatcapUV(matcapUV, _Matcap2Pan.xy, _Matcap2UVMode, _Matcap2UVToBlend, _MatCap2ndBlendUV1.xy, _Matcap2Rotation, _Matcap2Border, normal1, poiCam, poiLight, poiMesh, _Matcap2Normal, matcapALD);
				if (_Matcap2SmoothnessEnabled)
				{
					float mipCount2 = 9;
					if (_Matcap2_TexelSize.z == 8192) mipCount2 = 13;
					if (_Matcap2_TexelSize.z == 4096) mipCount2 = 12;
					if (_Matcap2_TexelSize.z == 2048) mipCount2 = 11;
					if (_Matcap2_TexelSize.z == 1024) mipCount2 = 10;
					if (_Matcap2_TexelSize.z == 512) mipCount2 = 9;
					if (_Matcap2_TexelSize.z == 256) mipCount2 = 8;
					if (_Matcap2_TexelSize.z == 128) mipCount2 = 7;
					if (_Matcap2_TexelSize.z == 64) mipCount2 = 6;
					if (_Matcap2_TexelSize.z == 32) mipCount2 = 5;
					
					float matcap2Smoothness = _Matcap2Smoothness;
					
					if (_Matcap2MaskSmoothnessApply)
					{
						#if defined(PROP_MATCAP2MASK) || !defined(OPTIMIZER_ENABLED)
						matcap2Smoothness *= POI2D_SAMPLER_PAN(_Matcap2Mask, _MainTex, poiUV(poiMesh.uv[_Matcap2MaskUV], _Matcap2Mask_ST), _Matcap2MaskPan)[_Matcap2MaskSmoothnessChannel];
						#endif
					}
					matcap2Smoothness = (1 - matcap2Smoothness) * mipCount2;
					matcap2 = UNITY_SAMPLE_TEX2D_SAMPLER_LOD(_Matcap2, _trilinear_repeat, TRANSFORM_TEX(matcapUV, _Matcap2), matcap2Smoothness) * float4(poiThemeColor(poiMods, _Matcap2Color.rgb, _Matcap2ColorThemeIndex), _Matcap2Color.a);
				}
				else
				{
					matcap2 = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap2, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap2)) * float4(poiThemeColor(poiMods, _Matcap2Color.rgb, _Matcap2ColorThemeIndex), _Matcap2Color.a);
				}
				#else
				matcap2 = float4(poiThemeColor(poiMods, _Matcap2Color.rgb, _Matcap2ColorThemeIndex), _Matcap2Color.a);
				#endif
				
				matcapIntensity = _Matcap2Intensity;
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapIntensity += lerp(matcapALD.matcapALIntensityAdd.x, matcapALD.matcapALIntensityAdd.y, poiMods.audioLink[matcapALD.matcapALIntensityAddBand]);
					matcapIntensity = max(0, matcapIntensity);
				}
				#endif
				matcap2.rgb *= matcapIntensity;
				matcap2.rgb = lerp(matcap2.rgb, matcap2.rgb * poiFragData.baseColor.rgb, _Matcap2BaseColorMix);
				
				#if defined(PROP_MATCAP2MASK) || !defined(OPTIMIZER_ENABLED)
				matcap2Mask = POI2D_SAMPLER_PAN(_Matcap2Mask, _MainTex, poiUV(poiMesh.uv[_Matcap2MaskUV], _Matcap2Mask_ST), _Matcap2MaskPan)[_Matcap2MaskChannel];
				#else
				matcap2Mask = 1;
				#endif
				if (_Matcap2MaskInvert)
				{
					matcap2Mask = 1 - matcap2Mask;
				}
				
				#ifdef TPS_Penetrator
				if (_Matcap2TPSDepthEnabled)
				{
					matcap2Mask = lerp(0, matcap2Mask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Matcap2TPSMaskStrength);
				}
				#endif
				
				poiFragData.alpha *= lerp(1, matcap2.a, matcap2Mask * _Matcap2AlphaOverride);
				
				//UNITY_BRANCH
				if (_Matcap2HueShiftEnabled)
				{
					matcap2.rgb = hueShift(matcap2.rgb, _Matcap2HueShift + _Time.x * _Matcap2HueShiftSpeed);
				}
				
				if (_Matcap2ApplyToAlphaEnabled)
				{
					float matcap2AlphaApplyValue = dot(matcap2.rgb, float3(0.299, 0.587, 0.114)); // Greyscale
					if (_Matcap2ApplyToAlphaSourceBlend == 1) // Max
					
					{
						matcap2AlphaApplyValue = poiMax(matcap2.rgb);
					}
					if (_Matcap2ApplyToAlphaBlendType == 0) // Add
					
					{
						poiFragData.alpha += lerp(0, matcap2AlphaApplyValue, _Matcap2ApplyToAlphaBlending);
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
					if (_Matcap2ApplyToAlphaBlendType == 1) // Multiply
					
					{
						poiFragData.alpha *= lerp(1, matcap2AlphaApplyValue, _Matcap2ApplyToAlphaBlending);
					}
				}
				
				blendMatcap(poiLight, poiFragData, poiMods, _Matcap2Add, _Matcap2AddToLight, _Matcap2Multiply, _Matcap2Replace, _Matcap2Mixed, _Matcap2Screen, matcap2, matcap2Mask, _Matcap2EmissionStrength, _Matcap2LightMask, _Matcap2MaskGlobalMask, _Matcap2MaskGlobalMaskBlendType, matcapALD);
				#endif
				//endex
				//ifex _Matcap3Enable==0
				// Matcap 3
				#ifdef POI_MATCAP2
				
				matcapALD.matcapALEnabled = _Matcap2ALEnabled;
				matcapALD.matcapALAlphaAddBand = _Matcap2ALAlphaAddBand;
				matcapALD.matcapALAlphaAdd = _Matcap2ALAlphaAdd;
				matcapALD.matcapALEmissionAddBand = _Matcap2ALEmissionAddBand;
				matcapALD.matcapALEmissionAdd = _Matcap2ALEmissionAdd;
				matcapALD.matcapALIntensityAddBand = _Matcap2ALIntensityAddBand;
				matcapALD.matcapALIntensityAdd = _Matcap2ALIntensityAdd;
				matcapALD.matcapALChronoPanType = _Matcap2ALChronoPanType;
				matcapALD.matcapALChronoPanBand = _Matcap2ALChronoPanBand;
				matcapALD.matcapALChronoPanSpeed = _Matcap2ALChronoPanSpeed;
				
				float3 normal2 = lerp(poiMesh.normals[0], poiMesh.normals[1], _Matcap3Normal);
				#ifdef POI_MATCAP2_CUSTOM_NORMAL
				#if defined(PROP_MATCAP2NORMALMAP) || !defined(OPTIMIZER_ENABLED)
				normal2 = calculateNormal(poiMesh.normals[_Matcap3Normal], poiMesh, _Matcap2NormalMap, _Matcap2NormalMap_ST, _Matcap2NormalMapPan, _Matcap2NormalMapUV, _Matcap2NormalMapScale);
				#endif
				#endif
				
				#if defined(PROP_MATCAP3) || !defined(OPTIMIZER_ENABLED)
				getMatcapUV(matcapUV, _Matcap3Pan.xy, _Matcap3UVMode, _Matcap3UVToBlend, _MatCap3rdBlendUV1.xy, _Matcap3Rotation, _Matcap3Border, normal2, poiCam, poiLight, poiMesh, _Matcap3Normal, matcapALD);
				if (_Matcap3SmoothnessEnabled)
				{
					float mipCount3 = 9;
					if (_Matcap3_TexelSize.z == 8192) mipCount3 = 13;
					if (_Matcap3_TexelSize.z == 4096) mipCount3 = 12;
					if (_Matcap3_TexelSize.z == 2048) mipCount3 = 11;
					if (_Matcap3_TexelSize.z == 1024) mipCount3 = 10;
					if (_Matcap3_TexelSize.z == 512) mipCount3 = 9;
					if (_Matcap3_TexelSize.z == 256) mipCount3 = 8;
					if (_Matcap3_TexelSize.z == 128) mipCount3 = 7;
					if (_Matcap3_TexelSize.z == 64) mipCount3 = 6;
					if (_Matcap3_TexelSize.z == 32) mipCount3 = 5;
					
					float matcap3Smoothness = _Matcap3Smoothness;
					
					if (_Matcap3MaskSmoothnessApply)
					{
						#if defined(PROP_MATCAP3MASK) || !defined(OPTIMIZER_ENABLED)
						matcap3Smoothness *= POI2D_SAMPLER_PAN(_Matcap3Mask, _MainTex, poiUV(poiMesh.uv[_Matcap3MaskUV], _Matcap3Mask_ST), _Matcap3MaskPan)[_Matcap3MaskSmoothnessChannel];
						#endif
					}
					matcap3Smoothness = (1 - matcap3Smoothness) * mipCount3;
					matcap3 = UNITY_SAMPLE_TEX2D_SAMPLER_LOD(_Matcap3, _trilinear_repeat, TRANSFORM_TEX(matcapUV, _Matcap3), matcap3Smoothness) * float4(poiThemeColor(poiMods, _Matcap3Color.rgb, _Matcap3ColorThemeIndex), _Matcap3Color.a);
				}
				else
				{
					matcap3 = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap3, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap3)) * float4(poiThemeColor(poiMods, _Matcap3Color.rgb, _Matcap3ColorThemeIndex), _Matcap3Color.a);
				}
				#else
				matcap3 = float4(poiThemeColor(poiMods, _Matcap3Color.rgb, _Matcap3ColorThemeIndex), _Matcap3Color.a);
				#endif
				
				matcapIntensity = _Matcap3Intensity;
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapIntensity += lerp(matcapALD.matcapALIntensityAdd.x, matcapALD.matcapALIntensityAdd.y, poiMods.audioLink[matcapALD.matcapALIntensityAddBand]);
					matcapIntensity = max(0, matcapIntensity);
				}
				#endif
				matcap3.rgb *= matcapIntensity;
				matcap3.rgb = lerp(matcap3.rgb, matcap3.rgb * poiFragData.baseColor.rgb, _Matcap3BaseColorMix);
				
				#if defined(PROP_MATCAP3MASK) || !defined(OPTIMIZER_ENABLED)
				matcap3Mask = POI2D_SAMPLER_PAN(_Matcap3Mask, _MainTex, poiUV(poiMesh.uv[_Matcap3MaskUV], _Matcap3Mask_ST), _Matcap3MaskPan)[_Matcap3MaskChannel];
				#else
				matcap3Mask = 1;
				#endif
				if (_Matcap3MaskInvert)
				{
					matcap3Mask = 1 - matcap3Mask;
				}
				
				#ifdef TPS_Penetrator
				if (_Matcap3TPSDepthEnabled)
				{
					matcap3Mask = lerp(0, matcap3Mask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Matcap3TPSMaskStrength);
				}
				#endif
				
				poiFragData.alpha *= lerp(1, matcap3.a, matcap3Mask * _Matcap3AlphaOverride);
				
				//UNITY_BRANCH
				if (_Matcap3HueShiftEnabled)
				{
					matcap3.rgb = hueShift(matcap3.rgb, _Matcap3HueShift + _Time.x * _Matcap3HueShiftSpeed);
				}
				
				if (_Matcap3ApplyToAlphaEnabled)
				{
					float matcap3AlphaApplyValue = dot(matcap3.rgb, float3(0.299, 0.587, 0.114)); // Greyscale
					if (_Matcap3ApplyToAlphaSourceBlend == 1) // Max
					
					{
						matcap3AlphaApplyValue = poiMax(matcap3.rgb);
					}
					if (_Matcap3ApplyToAlphaBlendType == 0) // Add
					
					{
						poiFragData.alpha += lerp(0, matcap3AlphaApplyValue, _Matcap3ApplyToAlphaBlending);
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
					if (_Matcap3ApplyToAlphaBlendType == 1) // Multiply
					
					{
						poiFragData.alpha *= lerp(1, matcap3AlphaApplyValue, _Matcap3ApplyToAlphaBlending);
					}
				}
				
				blendMatcap(poiLight, poiFragData, poiMods, _Matcap3Add, _Matcap3AddToLight, _Matcap3Multiply, _Matcap3Replace, _Matcap3Mixed, _Matcap3Screen, matcap3, matcap3Mask, _Matcap3EmissionStrength, _Matcap3LightMask, _Matcap3MaskGlobalMask, _Matcap3MaskGlobalMaskBlendType, matcapALD);
				#endif
				//endex
				//ifex _Matcap4Enable==0
				// Matcap 4
				#ifdef POI_MATCAP3
				
				matcapALD.matcapALEnabled = _Matcap3ALEnabled;
				matcapALD.matcapALAlphaAddBand = _Matcap3ALAlphaAddBand;
				matcapALD.matcapALAlphaAdd = _Matcap3ALAlphaAdd;
				matcapALD.matcapALEmissionAddBand = _Matcap3ALEmissionAddBand;
				matcapALD.matcapALEmissionAdd = _Matcap3ALEmissionAdd;
				matcapALD.matcapALIntensityAddBand = _Matcap3ALIntensityAddBand;
				matcapALD.matcapALIntensityAdd = _Matcap3ALIntensityAdd;
				matcapALD.matcapALChronoPanType = _Matcap3ALChronoPanType;
				matcapALD.matcapALChronoPanBand = _Matcap3ALChronoPanBand;
				matcapALD.matcapALChronoPanSpeed = _Matcap3ALChronoPanSpeed;
				
				float3 normal3 = lerp(poiMesh.normals[0], poiMesh.normals[1], _Matcap4Normal);
				#ifdef POI_MATCAP3_CUSTOM_NORMAL
				#if defined(PROP_MATCAP3NORMALMAP) || !defined(OPTIMIZER_ENABLED)
				normal3 = calculateNormal(poiMesh.normals[_Matcap4Normal], poiMesh, _Matcap3NormalMap, _Matcap3NormalMap_ST, _Matcap3NormalMapPan, _Matcap3NormalMapUV, _Matcap3NormalMapScale);
				#endif
				#endif
				
				#if defined(PROP_MATCAP4) || !defined(OPTIMIZER_ENABLED)
				getMatcapUV(matcapUV, _Matcap4Pan.xy, _Matcap4UVMode, _Matcap4UVToBlend, _MatCap4thBlendUV1.xy, _Matcap4Rotation, _Matcap4Border, normal3, poiCam, poiLight, poiMesh, _Matcap4Normal, matcapALD);
				if (_Matcap4SmoothnessEnabled)
				{
					float mipCount4 = 9;
					if (_Matcap4_TexelSize.z == 8192) mipCount4 = 13;
					if (_Matcap4_TexelSize.z == 4096) mipCount4 = 12;
					if (_Matcap4_TexelSize.z == 2048) mipCount4 = 11;
					if (_Matcap4_TexelSize.z == 1024) mipCount4 = 10;
					if (_Matcap4_TexelSize.z == 512) mipCount4 = 9;
					if (_Matcap4_TexelSize.z == 256) mipCount4 = 8;
					if (_Matcap4_TexelSize.z == 128) mipCount4 = 7;
					if (_Matcap4_TexelSize.z == 64) mipCount4 = 6;
					if (_Matcap4_TexelSize.z == 32) mipCount4 = 5;
					
					float matcap4Smoothness = _Matcap4Smoothness;
					
					if (_Matcap4MaskSmoothnessApply)
					{
						#if defined(PROP_MATCAP4MASK) || !defined(OPTIMIZER_ENABLED)
						matcap4Smoothness *= POI2D_SAMPLER_PAN(_Matcap4Mask, _MainTex, poiUV(poiMesh.uv[_Matcap4MaskUV], _Matcap4Mask_ST), _Matcap4MaskPan)[_Matcap4MaskSmoothnessChannel];
						#endif
					}
					matcap4Smoothness = (1 - matcap4Smoothness) * mipCount4;
					matcap4 = UNITY_SAMPLE_TEX2D_SAMPLER_LOD(_Matcap4, _trilinear_repeat, TRANSFORM_TEX(matcapUV, _Matcap4), matcap4Smoothness) * float4(poiThemeColor(poiMods, _Matcap4Color.rgb, _Matcap4ColorThemeIndex), _Matcap4Color.a);
				}
				else
				{
					matcap4 = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap4, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap4)) * float4(poiThemeColor(poiMods, _Matcap4Color.rgb, _Matcap4ColorThemeIndex), _Matcap4Color.a);
				}
				#else
				matcap4 = float4(poiThemeColor(poiMods, _Matcap4Color.rgb, _Matcap4ColorThemeIndex), _Matcap4Color.a);
				#endif
				
				matcapIntensity = _Matcap4Intensity;
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapIntensity += lerp(matcapALD.matcapALIntensityAdd.x, matcapALD.matcapALIntensityAdd.y, poiMods.audioLink[matcapALD.matcapALIntensityAddBand]);
					matcapIntensity = max(0, matcapIntensity);
				}
				#endif
				matcap4.rgb *= matcapIntensity;
				matcap4.rgb = lerp(matcap4.rgb, matcap4.rgb * poiFragData.baseColor.rgb, _Matcap4BaseColorMix);
				
				#if defined(PROP_MATCAP4MASK) || !defined(OPTIMIZER_ENABLED)
				matcap4Mask = POI2D_SAMPLER_PAN(_Matcap4Mask, _MainTex, poiUV(poiMesh.uv[_Matcap4MaskUV], _Matcap4Mask_ST), _Matcap4MaskPan)[_Matcap4MaskChannel];
				#else
				matcap4Mask = 1;
				#endif
				if (_Matcap4MaskInvert)
				{
					matcap4Mask = 1 - matcap4Mask;
				}
				
				#ifdef TPS_Penetrator
				if (_Matcap4TPSDepthEnabled)
				{
					matcap4Mask = lerp(0, matcap4Mask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Matcap4TPSMaskStrength);
				}
				#endif
				
				poiFragData.alpha *= lerp(1, matcap4.a, matcap4Mask * _Matcap4AlphaOverride);
				
				//UNITY_BRANCH
				if (_Matcap4HueShiftEnabled)
				{
					matcap4.rgb = hueShift(matcap4.rgb, _Matcap4HueShift + _Time.x * _Matcap4HueShiftSpeed);
				}
				
				if (_Matcap4ApplyToAlphaEnabled)
				{
					float matcap4AlphaApplyValue = dot(matcap4.rgb, float3(0.299, 0.587, 0.114)); // Greyscale
					if (_Matcap4ApplyToAlphaSourceBlend == 1) // Max
					
					{
						matcap4AlphaApplyValue = poiMax(matcap4.rgb);
					}
					if (_Matcap4ApplyToAlphaBlendType == 0) // Add
					
					{
						poiFragData.alpha += lerp(0, matcap4AlphaApplyValue, _Matcap4ApplyToAlphaBlending);
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
					if (_Matcap4ApplyToAlphaBlendType == 1) // Multiply
					
					{
						poiFragData.alpha *= lerp(1, matcap4AlphaApplyValue, _Matcap4ApplyToAlphaBlending);
					}
				}
				
				blendMatcap(poiLight, poiFragData, poiMods, _Matcap4Add, _Matcap4AddToLight, _Matcap4Multiply, _Matcap4Replace, _Matcap4Mixed, _Matcap4Screen, matcap4, matcap4Mask, _Matcap4EmissionStrength, _Matcap4LightMask, _Matcap4MaskGlobalMask, _Matcap4MaskGlobalMaskBlendType, matcapALD);
				#endif
				//endex
				//ifex _MatcapEnable==0 && _Matcap2Enable==0 && _Matcap3Enable==0 && _Matcap4Enable==0
				
			}
			#endif
			//endex
			
			//ifex _CubeMapEnabled==0
			#ifdef _CUBEMAP
			#if defined(PROP_CUBEMAP) || !defined(OPTIMIZER_ENABLED)
			// From Unity's MIT'd Skybox-Cubed.shader
			float3 RotateAroundYInDegrees(float3 dir, float degrees)
			{
				float alpha = degrees * UNITY_PI / 180.0;
				float sina, cosa;
				sincos(alpha, sina, cosa);
				float2x2 m = float2x2(cosa, -sina, sina, cosa);
				return float3(mul(m, dir.xz), dir.y).xzy;
			}
			#endif
			void applyCubemap(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, in PoiLight poiLight, in PoiMods poiMods)
			{
				float3 CubeMapUV = 0;
				
				switch(_CubeMapUVMode)
				{
					case 0: // Skybox
					CubeMapUV = -poiCam.viewDir;
					break;
					case 1: // Reflection
					CubeMapUV = poiCam.reflectionDir;
					break;
					case 2: // World Normal Direction
					CubeMapUV = lerp(poiMesh.normals[0], poiMesh.normals[1], _CubeMapWorldNormalsStrength);
					break;
					case 3: // Local Normal Direction
					CubeMapUV = poiMesh.objNormal;
					break;
				}
				
				#if defined(PROP_CUBEMAP) || !defined(OPTIMIZER_ENABLED)
				if (any(_CubeMapRotation.xyz) || any(_CubeMapRotationPan.xyz))
				{
					// Do funny swizzle so we don't have to make a new function for every direction
					CubeMapUV = RotateAroundYInDegrees(CubeMapUV.yxz, _CubeMapRotation.x + (_CubeMapRotationPan.x * _Time.y)).yxz;
					CubeMapUV = RotateAroundYInDegrees(CubeMapUV.xyz, _CubeMapRotation.y + (_CubeMapRotationPan.y * _Time.y)).xyz;
					CubeMapUV = RotateAroundYInDegrees(CubeMapUV.xzy, _CubeMapRotation.z + (_CubeMapRotationPan.z * _Time.y)).xzy;
				}
				float4 cubeMap = texCUBElod(_CubeMap, float4(CubeMapUV, (1 - _CubeMapSmoothness) * (1 - _CubeMapSmoothness) * 8));
				
				cubeMap.rgb *= poiThemeColor(poiMods, _CubeMapColor, _CubeMapColorThemeIndex);
				#else
				float4 cubeMap = float4(0.21763764082, 0.21763764082, 0.21763764082, .5) * float4(poiThemeColor(poiMods, _CubeMapColor, _CubeMapColorThemeIndex), 1);
				#endif
				
				cubeMap.rgb *= _CubeMapIntensity;
				#if defined(PROP_CUBEMAPMASK) || !defined(OPTIMIZER_ENABLED)
				float CubeMapMask = POI2D_SAMPLER_PAN(_CubeMapMask, _MainTex, poiUV(poiMesh.uv[_CubeMapMaskUV], _CubeMapMask_ST), _CubeMapMaskPan)[_CubeMapMaskChannel];
				#else
				float CubeMapMask = 1;
				#endif
				
				if (_CubeMapMaskGlobalMask > 0)
				{
					CubeMapMask = maskBlend(CubeMapMask, poiMods.globalMask[_CubeMapMaskGlobalMask - 1], _CubeMapMaskGlobalMaskBlendType);
				}
				
				if (_CubeMapMaskInvert)
				{
					CubeMapMask = 1 - CubeMapMask;
				}
				
				//UNITY_BRANCH
				if (_CubeMapHueShiftEnabled)
				{
					cubeMap.rgb = hueShift(cubeMap.rgb, _CubeMapHueShift + _Time.x * _CubeMapHueShiftSpeed);
					cubeMap = PoiColorBCS(cubeMap, _CubeMapBrightness, _CubeMapContrast, _CubeMapSaturation);
					//cubeMap.rgb = ModifyViaHSV(cubeMap.rgb, _CubeMapHueShift + _Time.x * _CubeMapHueShiftSpeed, _CubeMapSaturation, _CubeMapValue);
					
				}
				CubeMapMask = min(CubeMapMask, lerp(1, poiLight.rampedLightMap, _CubeMapLightMask));
				float cubeMapAlpha = CubeMapMask * cubeMap.a * _CubeMapBlendAmount;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, cubeMap.rgb, cubeMapAlpha * (_CubemapBlendType == 0));
				poiFragData.baseColor.rgb *= lerp(1, cubeMap.rgb, cubeMapAlpha * (_CubemapBlendType == 1));
				poiFragData.baseColor.rgb += cubeMap.rgb * cubeMapAlpha * (_CubemapBlendType == 2);
				poiFragData.emission += cubeMap.rgb * _CubeMapEmissionStrength * CubeMapMask * cubeMap.a;
			}
			#endif
			//endex
			
			//ifex _EnableALDecal==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_DECAL
			void ApplyAudioLinkDecal(in PoiMesh poiMesh, inout PoiFragData poiFragData, in PoiMods poiMods)
			{
				float4 colorAndMask = float4(1, 1, 1, 1);
				#if defined(PROP_ALDECALCOLORMASK) || !defined(OPTIMIZER_ENABLED)
				colorAndMask = POI2D_SAMPLER_PAN(_ALDecalColorMask, _MainTex, poiUV(poiMesh.uv[_ALDecalColorMaskUV], _ALDecalColorMask_ST), _ALDecalColorMaskPan);
				#endif
				if (_ALDecalGlobalMask > 0)
				{
					colorAndMask.a = customBlend(colorAndMask.a, poiMods.globalMask[_ALDecalGlobalMask-1], _ALDecalGlobalMaskBlendType);
				}
				
				float2 uv = poiMesh.uv[_ALDecalUV];
				float2 decalCenter = _ALUVPosition;
				float theta = radians(_ALUVRotation + _Time.z * _ALUVRotationSpeed);
				float cs = cos(theta);
				float sn = sin(theta);
				uv = float2((uv.x - decalCenter.x) * cs - (uv.y - decalCenter.y) * sn + decalCenter.x, (uv.x - decalCenter.x) * sn + (uv.y - decalCenter.y) * cs + decalCenter.y);
				uv = remap(uv, float2(0, 0) - _ALUVScale.xz / 2 + _ALUVPosition, _ALUVScale.yw / 2 + _ALUVPosition, float2(0, 0), float2(1, 1));
				
				// Mask
				float4 audioLinkMask = 1.0;
				
				// UV
				float2 aluv = uv;
				if (_ALDecalUVMode == 1)
				{
					float2 uvdir = uv * 2 - 1;
					aluv.x = frac(atan2(uvdir.y, uvdir.x) * UNITY_INV_TWO_PI);
					aluv.y = length(uvdir);
				}
				
				// Scale / Offset / Step
				float maskY = aluv.y;
				if (_ALDecalUVMode == 1)
				{
					maskY = remap(maskY, _ALDecaldCircleDimensions.x, _ALDecaldCircleDimensions.y, 0, 1);
				}
				float maskX = aluv.x;
				if (_ALDecalUVMode == 1)
				{
					maskX = remap(maskX, _ALDecaldCircleDimensions.z, _ALDecaldCircleDimensions.w, 0, 1);
				}
				
				float maskVolume = _ALDecalVolumeStep != 0.0 ? floor(maskY * _ALDecalVolumeStep) / _ALDecalVolumeStep : maskY;
				float maskBand = _ALDecalBandStep != 0.0 ? floor(maskX * _ALDecalBandStep) / _ALDecalBandStep : maskX;
				
				// Copy
				audioLinkMask.r = maskVolume;
				audioLinkMask.g = maskBand;
				
				// Clip
				audioLinkMask.b = maskVolume < _ALDecalVolumeClipMin || maskVolume > _ALDecalVolumeClipMax ? 0.0 : audioLinkMask.b;
				audioLinkMask.b = maskBand < _ALDecalBandClipMin || maskBand > _ALDecalBandClipMax ? 0.0 : audioLinkMask.b;
				
				// Shape Clip
				if (_ALDecalShapeClip)
				{
					float volumeth = _ALDecalShapeClipVolumeWidth;
					if (_ALDecalVolumeStep != 0.0) audioLinkMask.b = frac(maskY * _ALDecalVolumeStep) > volumeth ? 0.0 : audioLinkMask.b;
					
					float bandwidth = _ALDecalUVMode == 1 ? _ALDecalShapeClipBandWidth / aluv.y : _ALDecalShapeClipBandWidth;
					float bandth = 1.0 - bandwidth;
					if (_ALDecalBandStep != 0.0) audioLinkMask.b = frac(maskX * _ALDecalBandStep + bandth * 0.5) < bandth ? 0.0 : audioLinkMask.b;
				}
				
				// AudioLink
				float2 audioLinkUV = float2(frac(audioLinkMask.g * 2.0), 4.5 / 4.0 + floor(audioLinkMask.g * 2.0) / 4.0);
				audioLinkUV.y *= 0.0625;
				float4 audioTexture = _AudioTexture.Sample(sampler_linear_clamp, audioLinkUV);
				float audioVal = audioTexture.b * _ALDecalVolume * lerp(_ALDecalBaseBoost, _ALDecalTrebleBoost, audioLinkMask.g);
				float audioLinkValue = _ALDecalLineWidth < 1.0 ? abs(audioVal - audioLinkMask.r) < _ALDecalLineWidth : audioVal > audioLinkMask.r * 2.0;
				audioLinkValue = saturate(audioLinkValue) * audioLinkMask.b;
				//clip(audioLinkValue - .5);
				audioLinkValue *= colorAndMask.a;
				
				if (!poiMods.audioLinkAvailable)
				{
					audioLinkValue = 0;
				}
				
				float3 alColorChord = _AudioTexture.Sample(sampler_linear_clamp, float2(maskX, 24.5 / 64.0)).rgb;
				float volumeColorSrc = audioLinkMask.g;
				if (_ALDecalVolumeColorSource == 1) volumeColorSrc = audioLinkMask.r;
				if (_ALDecalVolumeColorSource == 2) volumeColorSrc = audioVal;
				
				float3 lowColor = _ALDecalVolumeColorLow.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorLow.rgb, _ALDecalVolumeColorLowThemeIndex);
				float3 midColor = _ALDecalVolumeColorMid.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorMid.rgb, _ALDecalVolumeColorMidThemeIndex);
				float3 highColor = _ALDecalVolumeColorHigh.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorHigh.rgb, _ALDecalVolumeColorHighThemeIndex);
				
				float3 volumeColor = lerp(lowColor, midColor, saturate(volumeColorSrc * 2));
				volumeColor = lerp(volumeColor, highColor, saturate(volumeColorSrc * 2 - 1));
				
				float3 emissionColor = lerp(lowColor * _ALDecalLowEmission, midColor * _ALDecalMidEmission, saturate(volumeColorSrc * 2));
				emissionColor = lerp(emissionColor, highColor * _ALDecalHighEmission, saturate(volumeColorSrc * 2 - 1));
				
				//poiFragData.baseColor = lerp(poiFragData.baseColor, volumeColor, audioLinkValue);
				#if defined(POI_PASS_BASE) || defined(POI_PASS_ADD)
				poiFragData.emission += emissionColor * audioLinkValue;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor, customBlend(poiFragData.baseColor, volumeColor * colorAndMask.rgb, _ALDecalBlendType), saturate(_ALDecalBlendAlpha * audioLinkValue));
				#endif
				poiFragData.alpha = lerp(poiFragData.alpha, poiFragData.alpha * audioLinkValue, _ALDecalControlsAlpha);
			}
			#endif
			#endif
			//endex
			
			//ifex _EnableVolumeColor==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_VOLUMECOLOR
			void ApplyAudioLinkVolumeColor(in PoiMesh poiMesh, inout PoiFragData poiFragData, in PoiMods poiMods)
			{
				float volume = AudioLinkLerpMultiline(ALPASS_DFT + float2(poiMesh.uv[_ALVolumeColorUV][_ALVolumeColorDirection] * AUDIOLINK_ETOTALBINS, 0.0)).b;
				
				float3 lowColor = _ALVolumeColorLow.rgb * poiThemeColor(poiMods, _ALVolumeColorLow.rgb, _ALVolumeColorLowThemeIndex);
				float3 midColor = _ALVolumeColorMid.rgb * poiThemeColor(poiMods, _ALVolumeColorMid.rgb, _ALVolumeColorMidThemeIndex);
				float3 highColor = _ALVolumeColorHigh.rgb * poiThemeColor(poiMods, _ALVolumeColorHigh.rgb, _ALVolumeColorHighThemeIndex);
				
				float3 volumeColor = lerp(lowColor, midColor, saturate(volume * 2));
				volumeColor = lerp(volumeColor, highColor, saturate(volume * 2 - 1));
				
				float3 emissionColor = lerp(lowColor * _ALLowEmission, midColor * _ALMidEmission, saturate(volume * 2));
				emissionColor = lerp(emissionColor, highColor * _ALHighEmission, saturate(volume * 2 - 1));
				
				#if defined(POI_PASS_BASE) || defined(POI_PASS_ADD)
				poiFragData.emission += emissionColor * poiMods.audioLinkAvailable;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor, customBlend(poiFragData.baseColor, volumeColor, _ALVolumeColorBlendType), saturate(_ALVolumeColorBlendAlpha * poiMods.audioLinkAvailable));
				#endif
			}
			#endif
			#endif
			//endex
			
			//ifex _EnableFlipbook==0
			#ifdef _SUNDISK_HIGH_QUALITY
			
			void applyFlipbook(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				#if defined(PROP_FLIPBOOKTEXARRAY) || !defined(OPTIMIZER_ENABLED)
				float4 flipBookPixel = float4(0, 0, 0, 0);
				#if defined(PROP_FLIPBOOKMASK) || !defined(OPTIMIZER_ENABLED)
				float flipBookMask = POI2D_SAMPLER_PAN(_FlipbookMask, _MainTex, poiUV(poiMesh.uv[_FlipbookMaskUV], _FlipbookMask_ST), _FlipbookMaskPan)[_FlipbookMaskChannel];
				#else
				float flipBookMask = 1;
				#endif
				if (_FlipbookMaskGlobalMask > 0)
				{
					flipBookMask = maskBlend(flipBookMask, poiMods.globalMask[_FlipbookMaskGlobalMask-1], _FlipbookMaskGlobalMaskBlendType);
				}
				float4 flipbookScaleOffset = _FlipbookScaleOffset;
				
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookScaleOffset.xy += lerp(_AudioLinkFlipbookScale.xy, _AudioLinkFlipbookScale.zw, poiMods.audioLink[_AudioLinkFlipbookScaleBand]);
				}
				#endif
				
				flipbookScaleOffset.xy = 1 - flipbookScaleOffset.xy;
				float2 uv = frac(poiMesh.uv[_FlipbookTexArrayUV]);
				float theta = radians(_FlipbookRotation + _Time.z * _FlipbookRotationSpeed);
				float cs = cos(theta);
				float sn = sin(theta);
				float2 spriteCenter = flipbookScaleOffset.zw + .5;
				// 2d rotation
				uv = float2((uv.x - spriteCenter.x) * cs - (uv.y - spriteCenter.y) * sn + spriteCenter.x, (uv.x - spriteCenter.x) * sn + (uv.y - spriteCenter.y) * cs + spriteCenter.y);
				float4 sideOffset = float4(-(_FlipbookSideOffset.x), _FlipbookSideOffset.y, -(_FlipbookSideOffset.z), _FlipbookSideOffset.w);
				float2 newUV = remap(uv, float2(0, 0) + flipbookScaleOffset.xy / 2 + flipbookScaleOffset.zw + sideOffset.xz, float2(1, 1) - flipbookScaleOffset.xy / 2 + flipbookScaleOffset.zw + sideOffset.yw, float2(0, 0), float2(1, 1));
				
				UNITY_BRANCH
				if (_FlipbookTiled == 0)
				{
					if (max(newUV.x, newUV.y) > 1 || min(newUV.x, newUV.y) < 0)
					{
						return;
					}
				}
				float currentFrame = 0;
				float width;
				float height;
				float totalFrames;
				_FlipbookTexArray.GetDimensions(width, height, totalFrames);
				
				if (_FlipbookStartAndEnd)
				{
					totalFrames -= (totalFrames - min(max(_FlipbookStartFrame, _FlipbookEndFrame), totalFrames));
					totalFrames -= max(0, _FlipbookStartFrame);
				}
				if (!_FlipbookManualFrameControl)
				{
					if (_FlipbookFPS != 0)
					{
						currentFrame = ((_Time.y / (1 / _FlipbookFPS)) + _FlipbookFrameOffset) % totalFrames;
						if (_FlipbookStartAndEnd)
						{
							currentFrame += _FlipbookStartFrame;
						}
					}
				}
				else
				{
					currentFrame = fmod(_FlipbookCurrentFrame, totalFrames);
				}
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					if (_FlipbookChronotensityEnabled)
					{
						currentFrame += AudioLinkGetChronoTime(_FlipbookChronoType, _FlipbookChronotensityBand) * _FlipbookChronotensitySpeed;
					}
					currentFrame += lerp(_AudioLinkFlipbookFrame.x, _AudioLinkFlipbookFrame.y, poiMods.audioLink[_AudioLinkFlipbookFrameBand]);
					float totalFramesAL = totalFrames;
					if (_FlipbookStartAndEnd)
					{
						totalFramesAL += max(0, _FlipbookStartFrame);
					}
					currentFrame %= totalFramesAL;
				}
				#endif
				flipBookPixel = UNITY_SAMPLE_TEX2DARRAY(_FlipbookTexArray, float3(TRANSFORM_TEX(newUV, _FlipbookTexArray) + _Time.x * _FlipbookTexArrayPan, floor(currentFrame)));
				UNITY_BRANCH
				if (_FlipbookCrossfadeEnabled)
				{
					float totalFramesCF = totalFrames;
					if (_FlipbookStartAndEnd)
					{
						totalFramesCF += max(0, _FlipbookStartFrame);
					}
					float4 flipbookNextPixel = UNITY_SAMPLE_TEX2DARRAY(_FlipbookTexArray, float3(TRANSFORM_TEX(newUV, _FlipbookTexArray) + _Time.x * _FlipbookTexArrayPan, floor((currentFrame + 1) % totalFramesCF)));
					flipBookPixel = lerp(flipBookPixel, flipbookNextPixel, smoothstep(_FlipbookCrossfadeRange.x, _FlipbookCrossfadeRange.y, frac(currentFrame)));
				}
				
				UNITY_BRANCH
				if (_FlipbookIntensityControlsAlpha)
				{
					flipBookPixel.a = poiMax(flipBookPixel.rgb);
				}
				UNITY_BRANCH
				if (_FlipbookColorReplaces)
				{
					flipBookPixel.rgb = poiThemeColor(poiMods, _FlipbookColor.rgb, _FlipbookColorThemeIndex);
				}
				else
				{
					flipBookPixel.rgb *= poiThemeColor(poiMods, _FlipbookColor.rgb, _FlipbookColorThemeIndex);
				}
				
				UNITY_BRANCH
				if (_FlipbookHueShiftEnabled)
				{
					flipBookPixel.rgb = hueShift(flipBookPixel.rgb, _FlipbookHueShift + _Time.x * _FlipbookHueShiftSpeed);
				}
				half flipbookAlpha = 1;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookAlpha += saturate(lerp(_AudioLinkFlipbookAlpha.x, _AudioLinkFlipbookAlpha.y, poiMods.audioLink[_AudioLinkFlipbookAlphaBand]));
				}
				#endif
				
				#if !defined(POI_PASS_OUTLINE) && !defined(UNITY_PASS_SHADOWCASTER)
				
				poiFragData.baseColor = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, flipBookPixel.rgb, _FlipbookBlendType), flipBookPixel.a * _FlipbookColor.a * _FlipbookReplace * flipBookMask * flipbookAlpha);
				
				float flipbookEmissionStrength = _FlipbookEmissionStrength;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookEmissionStrength += max(lerp(_AudioLinkFlipbookEmission.x, _AudioLinkFlipbookEmission.y, poiMods.audioLink[_AudioLinkFlipbookEmissionBand]), 0);
				}
				#endif
				
				poiFragData.emission += lerp(0, flipBookPixel.rgb * flipbookEmissionStrength, flipBookPixel.a * _FlipbookColor.a * flipBookMask * flipbookAlpha);
				
				#endif
				
				UNITY_BRANCH
				if (_FlipbookAlphaControlsFinalAlpha)
				{
					poiFragData.alpha = lerp(poiFragData.alpha, flipBookPixel.a * _FlipbookColor.a, flipBookMask);
				}
				#endif
			}
			
			#endif
			//endex
			
			//ifex _EnableRimLighting==0 && _EnableRim2Lighting==0
			#if defined(_GLOSSYREFLECTIONS_OFF) || defined(POI_RIM2)
			#if defined(_RIMSTYLE_POIYOMI) || defined(_RIM2STYLE_POIYOMI)
			void ApplyPoiyomiRimLighting(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight, inout PoiMods poiMods, float Is_NormalMapToRimLight, float RimInvert, float RimPower, float RimStrength, float RimShadowWidth, float RimShadowToggle, float RimWidth, float RimBlendStrength, float RimMask, float RimGlobalMask, float RimGlobalMaskBlendType, float4 RimTex, float4 RimLightColor, float RimLightColorThemeIndex, float RimHueShiftEnabled, float RimHueShift, float RimHueShiftSpeed, float RimSharpness, float RimShadowMaskRampType, float RimShadowMaskInvert, float RimShadowMaskStrength, float2 RimShadowAlpha, float RimApplyGlobalMaskIndex, float RimApplyGlobalMaskBlendType, float RimBaseColorMix, float RimBrightness, float RimBlendMode, half AudioLinkRimWidthBand, float2 AudioLinkRimWidthAdd, half AudioLinkRimEmissionBand, float2 AudioLinkRimEmissionAdd, half AudioLinkRimBrightnessBand, float2 AudioLinkRimBrightnessAdd, float rimBias, float rimBiasIntensity, int RimApplyAlpha, float RimApplyAlphaBlend)
			{
				float viewDotNormal = abs(dot(poiCam.viewDir, lerp(poiMesh.normals[0], poiMesh.normals[1], Is_NormalMapToRimLight)));
				
				UNITY_BRANCH
				if (RimInvert)
				{
					viewDotNormal = 1 - viewDotNormal;
				}
				
				viewDotNormal = pow(viewDotNormal, RimPower);
				
				if (RimShadowWidth && RimShadowToggle)
				{
					viewDotNormal += lerp(0, (1 - poiLight.nDotLNormalized) * 3, RimShadowWidth);
				}
				
				viewDotNormal *= lerp(1, rimBias, rimBiasIntensity);
				
				float rimStrength = RimStrength;
				
				float rimWidth = lerp( - .05, 1, RimWidth);
				
				float blendStrength = RimBlendStrength;
				#ifdef POI_AUDIOLINK
				UNITY_BRANCH
				if (poiMods.audioLinkAvailable)
				{
					rimWidth = clamp(rimWidth + lerp(AudioLinkRimWidthAdd.x, AudioLinkRimWidthAdd.y, poiMods.audioLink[AudioLinkRimWidthBand]), - .05, 1);
					rimStrength += lerp(AudioLinkRimEmissionAdd.x, AudioLinkRimEmissionAdd.y, poiMods.audioLink[AudioLinkRimEmissionBand]);
					RimBrightness += lerp(AudioLinkRimBrightnessAdd.x, AudioLinkRimBrightnessAdd.y, poiMods.audioLink[AudioLinkRimBrightnessBand]);
				}
				#endif
				float rimMask = RimMask;
				
				if (RimGlobalMask > 0)
				{
					rimMask = maskBlend(rimMask, poiMods.globalMask[RimGlobalMask - 1], RimGlobalMaskBlendType);
				}
				
				float4 rimColor = RimTex;
				rimColor *= float4(poiThemeColor(poiMods, RimLightColor.rgb, RimLightColorThemeIndex), RimLightColor.a);
				
				UNITY_BRANCH
				if (RimHueShiftEnabled)
				{
					rimColor.rgb = hueShift(rimColor.rgb, RimHueShift + _Time.x * RimHueShiftSpeed);
				}
				
				float rim = 1 - smoothstep(min(RimSharpness, rimWidth), rimWidth, viewDotNormal);
				rim *= RimLightColor.a * rimColor.a * rimMask;
				
				if (RimShadowToggle)
				{
					switch(RimShadowMaskRampType)
					{
						case 0:
						float rampedLightMap = poiLight.rampedLightMap;
						if (RimShadowMaskInvert) rampedLightMap = 1 - rampedLightMap;
						rim = lerp(rim, rim * rampedLightMap, RimShadowMaskStrength);
						break;
						case 1:
						float nDotLNormalized = poiLight.nDotLNormalized;
						if (RimShadowMaskInvert) nDotLNormalized = 1 - nDotLNormalized;
						rim = lerp(rim, rim * smoothstep(RimShadowAlpha.x, RimShadowAlpha.y, nDotLNormalized), RimShadowMaskStrength);
						break;
					}
				}
				
				if (RimApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, RimApplyGlobalMaskIndex - 1, RimApplyGlobalMaskBlendType, rim * blendStrength);
				}
				
				if (RimApplyAlpha == 1) // Add
				
				{
					poiFragData.alpha += lerp(0, saturate(rim), RimApplyAlphaBlend);
					poiFragData.alpha = saturate(poiFragData.alpha);
				}
				if (RimApplyAlpha == 2) // Multiply
				
				{
					poiFragData.alpha *= lerp(1, saturate(rim), RimApplyAlphaBlend);
				}
				
				float3 finalRimColor = rimColor.rgb * lerp(1, poiFragData.baseColor, RimBaseColorMix);
				finalRimColor *= RimBrightness;
				// Add 0, Replace 1, Multiply 2, Mixed 3
				switch(RimBlendMode)
				{
					case 0: poiFragData.baseColor += finalRimColor * rim * blendStrength; break;
					case 1: poiFragData.baseColor = lerp(poiFragData.baseColor, finalRimColor, rim * blendStrength); break;
					case 2: poiFragData.baseColor = lerp(poiFragData.baseColor, poiFragData.baseColor * finalRimColor, rim * blendStrength); break;
					case 3: poiFragData.baseColor = lerp(poiFragData.baseColor.rgb, poiFragData.baseColor.rgb + poiFragData.baseColor.rgb * finalRimColor, rim * blendStrength); break;
					case 4: poiFragData.baseColor = lerp(poiFragData.baseColor, 1 - (1 - poiFragData.baseColor) * (1 - finalRimColor), rim * blendStrength); break;
				}
				poiFragData.emission += finalRimColor * rim * rimStrength;
			}
			#endif
			#if defined(_RIMSTYLE_UTS2) || defined(_RIM2STYLE_UTS2)
			void ApplyUTS2RimLighting(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight, in PoiMods poiMods, float Set_RimLightMask_var, float RimGlobalMask, float RimGlobalMaskBlendType, float4 RimLightColor, float RimLightColorThemeIndex, float Is_LightColor_RimLight, float Is_NormalMapToRimLight, float RimLight_Power, float RimLight_InsideMask, float RimLight_FeatherOff, float LightDirection_MaskOn, float Tweak_LightDirection_MaskLevel, float Add_Antipodean_RimLight, float4 Ap_RimLightColor, float RimApColorThemeIndex, float Is_LightColor_Ap_RimLight, float Ap_RimLight_Power, float Ap_RimLight_FeatherOff, float Tweak_RimLightMaskLevel, float RimHueShiftEnabled, float RimHueShift, float RimHueShiftSpeed)
			{
				if (RimGlobalMask > 0)
				{
					Set_RimLightMask_var = maskBlend(Set_RimLightMask_var, poiMods.globalMask[RimGlobalMask - 1], RimGlobalMaskBlendType);
				}
				
				float3 rimColor = float3(poiThemeColor(poiMods, RimLightColor.rgb, RimLightColorThemeIndex));
				float3 _Is_LightColor_RimLight_var = lerp(rimColor, (rimColor * poiLight.directColor), Is_LightColor_RimLight);
				float _RimArea_var = (1.0 - dot(lerp(poiMesh.normals[0], poiMesh.normals[1], Is_NormalMapToRimLight), poiCam.viewDir));
				float _RimLightPower_var = pow(_RimArea_var, exp2(lerp(3, 0, RimLight_Power)));
				float _Rimlight_InsideMask_var = saturate(lerp((0.0 + ((_RimLightPower_var - RimLight_InsideMask) * (1.0 - 0.0)) / (1.0 - RimLight_InsideMask)), step(RimLight_InsideMask, _RimLightPower_var), RimLight_FeatherOff));
				float _VertHalfLambert_var = 0.5 * dot(poiMesh.normals[0], poiLight.direction) + 0.5;
				float3 _LightDirection_MaskOn_var = lerp((_Is_LightColor_RimLight_var * _Rimlight_InsideMask_var), (_Is_LightColor_RimLight_var * saturate((_Rimlight_InsideMask_var - ((1.0 - _VertHalfLambert_var) + Tweak_LightDirection_MaskLevel)))), LightDirection_MaskOn);
				float _ApRimLightPower_var = pow(_RimArea_var, exp2(lerp(3, 0, Ap_RimLight_Power)));
				float3 ApRimColor = float3(poiThemeColor(poiMods, Ap_RimLightColor.rgb, RimApColorThemeIndex));
				float3 _RimLight_var = (saturate((Set_RimLightMask_var + Tweak_RimLightMaskLevel)) * lerp(_LightDirection_MaskOn_var, (_LightDirection_MaskOn_var + (lerp(ApRimColor, (ApRimColor * poiLight.directColor), Is_LightColor_Ap_RimLight) * saturate((lerp((0.0 + ((_ApRimLightPower_var - RimLight_InsideMask) * (1.0 - 0.0)) / (1.0 - RimLight_InsideMask)), step(RimLight_InsideMask, _ApRimLightPower_var), Ap_RimLight_FeatherOff) - (saturate(_VertHalfLambert_var) + Tweak_LightDirection_MaskLevel))))), Add_Antipodean_RimLight));
				UNITY_BRANCH
				if (RimHueShiftEnabled)
				{
					_RimLight_var = hueShift(_RimLight_var, RimHueShift + _Time.x * RimHueShiftSpeed);
				}
				poiFragData.baseColor += _RimLight_var;
			}
			#endif
			#if defined(_RIMSTYLE_LILTOON) || defined(_RIM2STYLE_LILTOON)
			void ApplyLiltoonRimLighting(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight, in PoiMods poiMods, float4 RimColor, float4 RimIndirColor, float4 RimColorTex, float RimMainStrength, float RimNormalStrength, float RimDirRange, float RimIndirRange, float RimFresnelPower, float RimBackfaceMask, float RimDirStrength, float RimBorder, float RimBlur, float RimIndirBorder, float RimIndirBlur, float RimShadowMask, float RimEnableLighting, float RimVRParallaxStrength, float RimGlobalMask, float RimGlobalMaskBlendType, float RimHueShiftEnabled, float RimHueShift, float RimHueShiftSpeed, int RimBlendMode)
			{
				if (RimGlobalMask > 0)
				{
					RimColorTex.a = maskBlend(RimColorTex.a, poiMods.globalMask[RimGlobalMask - 1], RimGlobalMaskBlendType);
				}
				float4 rimColor = RimColor;
				float4 rimIndirColor = RimIndirColor;
				rimColor *= RimColorTex;
				rimIndirColor *= RimColorTex;
				
				if (RimHueShiftEnabled)
				{
					rimColor.rgb = hueShift(rimColor.rgb, RimHueShift + _Time.x * RimHueShiftSpeed);
					rimIndirColor.rgb = hueShift(rimIndirColor.rgb, RimHueShift + _Time.x * RimHueShiftSpeed);
				}
				
				rimColor.rgb = lerp(rimColor.rgb, rimColor.rgb * poiFragData.baseColor, RimMainStrength);
				
				// View direction
				float3 centerViewDir = !IsOrthographicCamera() ? normalize(getCameraPosition() - poiMesh.worldPos.xyz) : normalize(UNITY_MATRIX_I_V._m02_m12_m22);
				float3 viewDir = lerp(centerViewDir, poiCam.viewDir, RimVRParallaxStrength);
				
				// Normal
				float3 normal = lerp(poiMesh.normals[0], poiMesh.normals[1], RimNormalStrength);
				float nvabs = abs(dot(normal, viewDir));
				
				// Factor
				float lnRaw = dot(poiLight.direction, normal) * 0.5 + 0.5;
				float lnDir = saturate((lnRaw + RimDirRange) / (1.0 + RimDirRange));
				float lnIndir = saturate((1.0 - lnRaw + RimIndirRange) / (1.0 + RimIndirRange));
				float rim = pow(saturate(1.0 - nvabs), RimFresnelPower);
				rim = !poiMesh.isFrontFace && RimBackfaceMask ? 0.0 : rim;
				float rimDir = lerp(rim, rim * lnDir, RimDirStrength);
				float rimIndir = rim * lnIndir * RimDirStrength;
				
				rimDir = poiEdgeLinear(rimDir, RimBorder, RimBlur);
				rimIndir = poiEdgeLinear(rimIndir, RimIndirBorder, RimIndirBlur);
				
				rimDir = lerp(rimDir, rimDir * poiLight.rampedLightMap, RimShadowMask);
				rimIndir = lerp(rimIndir, rimIndir * poiLight.rampedLightMap, RimShadowMask);
				
				float3 lightCol = poiLight.finalLighting;
				/*
				#if !defined(POI_PASS_ADD)
				rimColor.rgb = lerp(rimColor.rgb, rimColor.rgb * lightCol, RimEnableLighting);
				#else
				if (RimBlendMode < 3) rimColor.rgb *= lightCol * RimEnableLighting;
				#endif
				// Blend
				*/
				#if !defined(POI_PASS_ADD)
				float3 rimLightMul = 1 - RimEnableLighting + lightCol * RimEnableLighting;
				#else
				float3 rimLightMul = RimBlendMode < 3 ? lightCol * RimEnableLighting : 1;
				#endif
				
				poiFragData.finalColor = lilBlendColor(poiFragData.finalColor, rimColor.rgb * rimLightMul, rimDir * rimColor.a, RimBlendMode);
				poiFragData.finalColor = lilBlendColor(poiFragData.finalColor, rimIndirColor.rgb * rimLightMul, rimIndir * rimIndirColor.a, RimBlendMode);
			}
			#endif
			#endif
			//endex
			
			//ifex _EnableDepthRimLighting==0
			#ifdef _POI_DEPTH_RIMLIGHT
			
			float PositivePow(float base, float power)
			{
				return pow(max(abs(base), Epsilon), power);
			}
			
			float GetScaleWithHight()
			{
				return _ScreenParams.y / 1080;
			}
			
			float GetSSRimScale(float z)
			{
				float w = (1.0 / (PositivePow(z + saturate(UNITY_MATRIX_P._m00), 1.5) + 0.75)) * GetScaleWithHight();
				w *= lerp(1, UNITY_MATRIX_P._m00, 0.60 * saturate(0.25 * z * z));
				return w < 0.01 ? 0 : w;
			}
			
			void ApplyDepthRimLighting(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, inout PoiLight poiLight, in PoiMods poiMods)
			{
				float rim = 0;
				float perspectiveDivide = 1.0f / poiCam.clipPos.w;
				float4 direction = poiCam.worldDirection * perspectiveDivide;
				float2 screenPos = poiCam.posScreenSpace.xy * perspectiveDivide;
				float z = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, screenPos);
				
				#if UNITY_REVERSED_Z
				if (z == 0) return;
				#else
				if (z == 1) return;
				#endif
				
				float depth = CorrectedLinearEyeDepth(z, direction.w);
				
				switch(_DepthRimType)
				{
					case 0:
					{
						float3 viewPos = UnityObjectToViewPos(poiMesh.localPos);
						float3 viewDir = normalize(viewPos);
						
						float3 viewNorm = mul((float3x3)UNITY_MATRIX_V, poiMesh.normals[_DepthRimNormalToUse]);
						float3 viewCrossNorm = cross(viewDir, viewNorm);
						float2 N_View = normalize(float2(-viewCrossNorm.y, viewCrossNorm.x));
						
						float3 viewLight = mul((float3x3)UNITY_MATRIX_V, poiLight.direction);
						float3 viewCrossLight = cross(viewDir, viewLight);
						float2 L_View = normalize(float2(-viewCrossLight.y, viewCrossLight.x));
						
						//float lDotN = saturate(poiLight.nDotL + _RimLightLength);
						float scale = _DepthRimWidth * GetSSRimScale(depth);
						float2 ssUV1 = clamp(screenPos + N_View * .1 * scale, 0, _ScreenParams.xy - 1);
						float depthDiff = z - SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, ssUV1) ;
						
						rim = smoothstep(0.24 * _DepthRimSharpness * z, 0.25 * z, depthDiff);
						rim *= lerp(1, (dot(L_View, N_View) > 0), _DepthRimHideInShadow);
					}
					break;
					case 1:
					{
						//float lDotN = saturate(poiLight.nDotL + _RimLightLength);
						float scale = _DepthRimWidth * GetSSRimScale(depth);
						float depthDiff = 0;
						[unroll(9)]
						for (int i = 0; i < 9; i++)
						{
							float2 ssUV1 = clamp(screenPos + sobelSamplePoints[i] * .1 * scale, 0, _ScreenParams.xy - 1);
							depthDiff = max(depthDiff, z - SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, ssUV1));
						}
						rim = smoothstep(0.24 * _DepthRimSharpness * z, 0.25 * z, depthDiff);
						rim *= lerp(1, lerp(poiLight.vertexNDotL > 0, poiLight.nDotL > 0, _DepthRimNormalToUse), _DepthRimHideInShadow);
					}
					break;
				}
				
				float3 rimColor = poiThemeColor(poiMods, _DepthRimColor.rgb, _DepthRimColorThemeIndex).rgb * lerp(1, poiLight.directColor, _DepthRimMixLightColor) * lerp(1, poiFragData.baseColor, _DepthRimMixBaseColor) * _DepthRimBrightness;
				
				#ifdef POI_PASS_BASE
				poiLight.finalLightAdd += rim * rimColor * _DepthRimAdditiveLighting;
				#endif
				poiFragData.emission += rim * rimColor * _DepthRimEmission;
				poiFragData.baseColor = lerp(poiFragData.baseColor, rimColor, rim * _DepthRimReplace);
				poiFragData.baseColor += rim * rimColor * _DepthRimAdd;
				poiFragData.baseColor *= lerp(1, rimColor, rim * _DepthRimMultiply);
			}
			#endif
			//endex
			
			//ifex _GlitterEnable==0
			#ifdef _SUNDISK_SIMPLE
			
			float3 RandomColorFromPoint(float2 rando, PoiMods poiMods)
			{
				fixed hue = random2(rando.x + rando.y).x;
				fixed saturation = lerp(_GlitterMinMaxSaturation.x, _GlitterMinMaxSaturation.y, rando.x);
				fixed value = lerp(_GlitterMinMaxBrightness.x, _GlitterMinMaxBrightness.y, rando.y);
				float3 hsv = float3(hue, saturation, value);
				return HSVtoRGB(hsv);
			}
			
			void applyGlitter(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight, in PoiMods poiMods)
			{
				float glitterRotationTimeOffset = 0;
				#ifdef POI_AUDIOLINK
				if (_GlitterALEnabled)
				{
					glitterRotationTimeOffset += AudioLinkGetChronoTime(_GlitterALChronoRotationSpeedType, _GlitterALChronoRotationSpeedBand) * _GlitterALChronoRotationSpeed;
				}
				#endif
				
				for (int glitterLayer = 0; glitterLayer < _GlitterLayers; glitterLayer++)
				{
					// Scale
					
					float2 st = (poiMesh.uv[_GlitterUV] + _GlitterUVPanning.xy * _Time.x) * _GlitterFrequency;
					
					// Tile the space
					float2 i_st = floor(st);
					float2 f_st = frac(st);
					
					float m_dist = 10.;  // minimun distance
					float2 m_point = 0;        // minimum point
					float2 randoPoint = 0;
					float2 dank = 0;
					for (int j = -1; j <= 1; j++)
					{
						for (int i = -1; i <= 1; i++)
						{
							float2 neighbor = float2(i, j);
							float2 pos = random2(i_st + neighbor + glitterLayer * 0.5141);
							float2 rando = pos;
							pos = pos * _GlitterRandomLocation;
							float2 diff = neighbor + pos - f_st;
							float dist = length(diff);
							
							if (dist < m_dist)
							{
								dank = diff;
								m_dist = dist;
								m_point = pos;
								randoPoint = rando;
							}
						}
					}
					
					float randomFromPoint = random(randoPoint);
					
					float size = _GlitterSize;
					UNITY_BRANCH
					if (_GlitterRandomSize)
					{
						size = lerp(_GlitterMinMaxSize.x, _GlitterMinMaxSize.y, randomFromPoint);
					}
					#ifdef POI_AUDIOLINK
					if (_GlitterALEnabled)
					{
						size = saturate(size + lerp(_GlitterALSizeAdd.x, _GlitterALSizeAdd.y, poiMods.audioLink[_GlitterALSizeAddBand]));
					}
					#endif
					
					// Assign a color using the closest point position
					//color += dot(m_point, float2(.3, .6));
					
					// Add distance field to closest point center
					// color.g = m_dist;
					
					// Show isolines
					//color -= abs(sin(40.0 * m_dist)) * 0.07;
					
					// Draw cell center
					half glitterAlpha = 1;
					switch(_GlitterShape)
					{
						case 0: //circle
						glitterAlpha = saturate((size - m_dist) / clamp(fwidth(m_dist), 0.0001, 1.0));
						break;
						case 1: //sqaure
						float jaggyFix = pow(poiCam.distanceToVert, 2) * _GlitterJaggyFix;
						UNITY_BRANCH
						if (_GlitterRandomRotation == 1 || _GlitterTextureRotation != 0 || _GlitterRandomRotationSpeed.x != 0 || _GlitterRandomRotationSpeed.y != 0 || glitterRotationTimeOffset != 0)
						{
							float2 center = float2(0, 0);
							float2 glitterRandomRotationSpeed = 0;
							float randomBoy = 0;
							UNITY_BRANCH
							if (_GlitterRandomRotation || _GlitterRandomRotationSpeed.x != 0 || _GlitterRandomRotationSpeed.y != 0)
							{
								randomBoy = random(m_point * 200);
								glitterRandomRotationSpeed = lerp(_GlitterRandomRotationSpeed.x, _GlitterRandomRotationSpeed.y, randomBoy);
							}
							if (glitterRandomRotationSpeed.x + glitterRandomRotationSpeed.y + _GlitterTextureRotation == 0 && glitterRotationTimeOffset != 0)
							{
								glitterRandomRotationSpeed = 1;
							}
							float theta = radians((randomBoy + (_Time.x + glitterRotationTimeOffset) * (_GlitterTextureRotation + glitterRandomRotationSpeed)) * 360);
							float cs = cos(theta);
							float sn = sin(theta);
							dank = float2((dank.x - center.x) * cs - (dank.y - center.y) * sn + center.x, (dank.x - center.x) * sn + (dank.y - center.y) * cs + center.y);
							glitterAlpha = (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.x))) * (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.y)));
						}
						else
						{
							glitterAlpha = (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.x))) * (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.y)));
						}
						break;
					}
					
					float3 finalGlitter = 0;
					
					half3 glitterColor = poiThemeColor(poiMods, _GlitterColor.rgb, _GlitterColorThemeIndex);
					
					float3 norm = lerp(poiMesh.normals[0], poiMesh.normals[1], _GlitterUseNormals);
					float3 randomRotation = 0;
					float glitterSpeedOffset = 0;
					#ifdef POI_AUDIOLINK
					if (_GlitterALEnabled)
					{
						glitterSpeedOffset += AudioLinkGetChronoTime(_GlitterALChronoSparkleSpeedType, _GlitterALChronoSparkleSpeedBand) * _GlitterALChronoSparkleSpeed;
					}
					#endif
					switch(_GlitterMode)
					{
						case 0:
						UNITY_BRANCH
						if (_GlitterSpeed + glitterSpeedOffset > 0)
						{
							randomRotation = randomFloat3WiggleRange(randoPoint, _GlitterAngleRange, _GlitterSpeed, glitterSpeedOffset);
						}
						else
						{
							randomRotation = randomFloat3Range(randoPoint, _GlitterAngleRange);
						}
						
						float3 glitterReflectionDirection = normalize(mul(poiRotationMatrixFromAngles(randomRotation), norm));
						finalGlitter = lerp(0, _GlitterMinBrightness * glitterAlpha, glitterAlpha) + max(pow(saturate(dot(lerp(glitterReflectionDirection, poiCam.viewDir, _GlitterBias), poiCam.viewDir)), _GlitterContrast), 0);
						finalGlitter *= glitterAlpha;
						break;
						case 1:
						float randomOffset = random(randoPoint);
						float brightness = (sin((_Time.x * 10 + randomOffset +glitterSpeedOffset) * _GlitterSpeed) * .5 + .5);
						finalGlitter = max(_GlitterMinBrightness * glitterAlpha, brightness * glitterAlpha * smoothstep(0, 1, 1 - m_dist * _GlitterCenterSize * 10));
						break;
						case 2:
						if (_GlitterSpeed + glitterSpeedOffset > 0)
						{
							randomRotation = randomFloat3WiggleRange(randoPoint, _GlitterAngleRange, _GlitterSpeed, glitterSpeedOffset);
						}
						else
						{
							randomRotation = randomFloat3Range(randoPoint, _GlitterAngleRange);
						}
						
						float3 glitterLightReflectionDirection = normalize(mul(poiRotationMatrixFromAngles(randomRotation), norm));
						
						glitterAlpha *= poiLight.nDotLSaturated;
						
						float3 halfDir = normalize(poiLight.direction + poiCam.viewDir);
						float specAngle = max(dot(halfDir, glitterLightReflectionDirection), 0.0);
						
						finalGlitter = lerp(0, _GlitterMinBrightness * glitterAlpha, glitterAlpha) + max(pow(specAngle, _GlitterContrast), 0);
						
						glitterColor *= poiLight.directColor;
						finalGlitter *= glitterAlpha;
						
						break;
					}
					
					glitterColor *= lerp(1, poiFragData.baseColor, _GlitterUseSurfaceColor);
					#if defined(PROP_GLITTERCOLORMAP) || !defined(OPTIMIZER_ENABLED)
					glitterColor *= POI2D_SAMPLER_PAN(_GlitterColorMap, _MainTex, poiUV(poiMesh.uv[_GlitterColorMapUV], _GlitterColorMap_ST), _GlitterColorMapPan).rgb;
					#endif
					float2 uv = remapClamped(-size, size, dank, 0, 1);
					UNITY_BRANCH
					
					if (_GlitterRandomRotation == 1 || _GlitterTextureRotation != 0 || _GlitterRandomRotationSpeed.x != 0 || _GlitterRandomRotationSpeed.y && !_GlitterShape || glitterRotationTimeOffset != 0)
					{
						float2 fakeUVCenter = float2(.5, .5);
						float randomBoy = 0;
						float2 glitterRandomRotationSpeed = 0;
						UNITY_BRANCH
						if (_GlitterRandomRotation || _GlitterRandomRotationSpeed.x != 0 || _GlitterRandomRotationSpeed.y != 0)
						{
							randomBoy = random(randoPoint * 20);
							glitterRandomRotationSpeed = lerp(_GlitterRandomRotationSpeed.x, _GlitterRandomRotationSpeed.y, randomBoy);
						}
						if (glitterRandomRotationSpeed.x + glitterRandomRotationSpeed.y + _GlitterTextureRotation == 0 && glitterRotationTimeOffset != 0)
						{
							glitterRandomRotationSpeed = 1;
						}
						float theta = radians((randomBoy + (_Time.x + glitterRotationTimeOffset) * (_GlitterTextureRotation + glitterRandomRotationSpeed)) * 360);
						float cs = cos(theta);
						float sn = sin(theta);
						uv = float2((uv.x - fakeUVCenter.x) * cs - (uv.y - fakeUVCenter.y) * sn + fakeUVCenter.x, (uv.x - fakeUVCenter.x) * sn + (uv.y - fakeUVCenter.y) * cs + fakeUVCenter.y);
					}
					
					#if defined(PROP_GLITTERTEXTURE) || !defined(OPTIMIZER_ENABLED)
					float4 glitterTexture = POI2D_SAMPLER_PANGRAD(_GlitterTexture, _linear_clamp, poiUV(uv, _GlitterTexture_ST), _GlitterTexturePan, poiMesh.dx, poiMesh.dy);
					#else
					float4 glitterTexture = 1;
					#endif
					//float4 glitterTexture = _GlitterTexture.SampleGrad(sampler_MainTex, frac(uv), ddx(uv), ddy(uv));
					glitterColor *= glitterTexture.rgb;
					#if defined(PROP_GLITTERMASK) || !defined(OPTIMIZER_ENABLED)
					float glitterMask = POI2D_SAMPLER_PAN(_GlitterMask, _MainTex, poiUV(poiMesh.uv[_GlitterMaskUV], _GlitterMask_ST), _GlitterMaskPan)[_GlitterMaskChannel];
					#else
					float glitterMask = 1;
					#endif
					
					#ifdef POI_AUDIOLINK
					if (_GlitterALEnabled)
					{
						glitterMask = clamp(glitterMask + lerp(_GlitterALAlphaAdd.x, _GlitterALAlphaAdd.y, poiMods.audioLink[_GlitterALAlphaAddBand]), 0, glitterMask);
					}
					#endif
					
					if (_GlitterMaskInvert)
					{
						glitterMask = 1 - glitterMask;
					}
					
					glitterMask *= lerp(1, poiLight.rampedLightMap, _GlitterHideInShadow);
					glitterMask *= lerp(1, poiLight.directLuminance, _GlitterScaleWithLighting);
					glitterMask *= _GlitterColor.a;
					
					if (_GlitterMaskGlobalMask > 0)
					{
						glitterMask = maskBlend(glitterMask, poiMods.globalMask[_GlitterMaskGlobalMask - 1], _GlitterMaskGlobalMaskBlendType);
					}
					
					if (_GlitterRandomColors)
					{
						glitterColor *= RandomColorFromPoint(random2(randoPoint.x + randoPoint.y), poiMods);
					}
					
					UNITY_BRANCH
					if (_GlitterHueShiftEnabled)
					{
						glitterColor.rgb = hueShift(glitterColor.rgb, _GlitterHueShift + _Time.x * _GlitterHueShiftSpeed);
					}
					float GlitterbrightnessOffset = 0;
					#ifdef POI_AUDIOLINK
					if (_GlitterALEnabled)
					{
						GlitterbrightnessOffset = max(GlitterbrightnessOffset +lerp(_GlitterALMaxBrightnessAdd.x, _GlitterALMaxBrightnessAdd.y, poiMods.audioLink[_GlitterALMaxBrightnessBand]), 0);
					}
					#endif
					
					UNITY_BRANCH
					if (_GlitterBlendType == 1)
					{
						poiFragData.baseColor = lerp(poiFragData.baseColor, finalGlitter * glitterColor * (_GlitterBrightness + GlitterbrightnessOffset), finalGlitter * glitterTexture.a * glitterMask);
						poiFragData.emission += finalGlitter * glitterColor * max(0, ((_GlitterBrightness + GlitterbrightnessOffset) - 1) * glitterTexture.a) * glitterMask;
					}
					else
					{
						poiFragData.emission += finalGlitter * glitterColor * (_GlitterBrightness + GlitterbrightnessOffset) * glitterTexture.a * glitterMask;
					}
				}
			}
			#endif
			//endex
			
			//ifex _SubsurfaceScattering==0
			#ifdef POI_SUBSURFACESCATTERING
			void applySubsurfaceScattering(in PoiCam poiCam, inout PoiLight poiLight, in PoiMesh poiMesh, in PoiFragData poiFragData)
			{
				float4 SSS = 1;
				#if defined(PROP_SSSTHICKNESSMAP) || !defined(OPTIMIZER_ENABLED)
				SSS = POI2D_SAMPLER_PAN(_SSSThicknessMap, _MainTex, poiUV(poiMesh.uv[_SSSThicknessMapUV], _SSSThicknessMap_ST), _SSSThicknessMapPan);
				SSS.a = 1 - SSS.a;
				#endif
				
				float3 vLTLight = poiLight.direction + poiMesh.normals[0] * _SSSDistortion;
				float flTDot = pow(saturate(dot(poiCam.viewDir, -vLTLight)), _SSSSpread) * _SSSStrength;
				#ifdef UNITY_PASS_FORWARDBASE
				float3 fLT = (flTDot) * saturate(SSS.a + - 1 * _SSSThicknessMod);
				#else
				float3 fLT = poiLight.additiveShadow * (flTDot) * saturate(SSS.a + - 1 * _SSSThicknessMod);
				#endif
				
				#if defined(POINT) || defined(SPOT)
				poiLight.finalLightAdd += fLT * poiLight.directColor * _SSSColor * SSS.rgb * lerp(1, poiFragData.baseColor, _SSSBaseColorMix);
				#endif
				poiLight.finalLightAdd += fLT * poiLight.directColor * _SSSColor * SSS.rgb * poiLight.attenuation * lerp(1, poiFragData.baseColor, _SSSBaseColorMix);
			}
			#endif
			//endex
			
			//ifex _MochieBRDF==0 && _ClearCoatBRDF==0
			#if defined(MOCHIE_PBR) || defined(POI_CLEARCOAT)
			
			/*
			* Copyright 2022 orels1
			*
			* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
			*
			* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
			*
			* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
			*/
			
			// https://github.com/orels1/orels-Unity-Shaders
			
			float GSAA_Filament(float3 worldNormal, float perceptualRoughness, float gsaaVariance, float gsaaThreshold)
			{
				// Kaplanyan 2016, "Stable specular highlights"
				// Tokuyoshi 2017, "Error Reduction and Simplification for Shading Anti-Aliasing"
				// Tokuyoshi and Kaplanyan 2019, "Improved Geometric Specular Antialiasing"
				
				// This implementation is meant for deferred rendering in the original paper but
				// we use it in forward rendering as well (as discussed in Tokuyoshi and Kaplanyan
				// 2019). The main reason is that the forward version requires an expensive transform
				// of the float vector by the tangent frame for every light. This is therefore an
				// approximation but it works well enough for our needs and provides an improvement
				// over our original implementation based on Vlachos 2015, "Advanced VR Rendering".
				
				float3 du = ddx(worldNormal);
				float3 dv = ddy(worldNormal);
				
				float variance = gsaaVariance * (dot(du, du) + dot(dv, dv));
				
				float roughness = perceptualRoughness * perceptualRoughness;
				float kernelRoughness = min(2.0 * variance, gsaaThreshold);
				float squareRoughness = saturate(roughness * roughness + kernelRoughness);
				
				return sqrt(sqrt(squareRoughness));
			}
			
			/*
			MIT END
			*/
			
			bool SceneHasReflections()
			{
				float width, height;
				unity_SpecCube0.GetDimensions(width, height);
				return !(width * height < 2);
			}
			
			float3 GetWorldReflections(float3 reflDir, float3 worldPos, float roughness)
			{
				float3 baseReflDir = reflDir;
				reflDir = BoxProjection(reflDir, worldPos, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax);
				float4 envSample0 = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, reflDir, roughness * UNITY_SPECCUBE_LOD_STEPS);
				float3 p0 = DecodeHDR(envSample0, unity_SpecCube0_HDR);
				float interpolator = unity_SpecCube0_BoxMin.w;
				UNITY_BRANCH
				if (interpolator < 0.99999)
				{
					float3 refDirBlend = BoxProjection(baseReflDir, worldPos, unity_SpecCube1_ProbePosition, unity_SpecCube1_BoxMin, unity_SpecCube1_BoxMax);
					float4 envSample1 = UNITY_SAMPLE_TEXCUBE_SAMPLER_LOD(unity_SpecCube1, unity_SpecCube0, refDirBlend, roughness * UNITY_SPECCUBE_LOD_STEPS);
					float3 p1 = DecodeHDR(envSample1, unity_SpecCube1_HDR);
					p0 = lerp(p1, p0, interpolator);
				}
				return p0;
			}
			
			float3 GetReflections(in PoiCam poiCam, in PoiLight pl, in PoiMesh poiMesh, float roughness, float ForceFallback, float LightFallback, samplerCUBE reflectionCube, float4 hdrData, float3 reflectionDir)
			{
				float3 reflections = 0;
				float3 lighting = pl.finalLighting;
				// This is a separate conditional so it can optimize out when ForceFallback isn't animated
				if (ForceFallback == 0)
				{
					UNITY_BRANCH
					if (SceneHasReflections())
					{
						#ifdef UNITY_PASS_FORWARDBASE
						reflections = GetWorldReflections(reflectionDir, poiMesh.worldPos.xyz, roughness);
						#endif
					}
					else
					{
						#ifdef UNITY_PASS_FORWARDBASE
						reflections = texCUBElod(reflectionCube, float4(reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
						reflections = DecodeHDR(float4(reflections, 1), hdrData) * lerp(1, pl.finalLighting, LightFallback);
						#endif
						#ifdef POI_PASS_ADD
						if (LightFallback)
						{
							reflections = texCUBElod(reflectionCube, float4(reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
							reflections = DecodeHDR(float4(reflections, 1), hdrData) * pl.finalLighting;
						}
						#endif
					}
				}
				else
				{
					#ifdef UNITY_PASS_FORWARDBASE
					reflections = texCUBElod(reflectionCube, float4(reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
					reflections = DecodeHDR(float4(reflections, 1), hdrData) * lerp(1, pl.finalLighting, LightFallback);
					#endif
					#ifdef POI_PASS_ADD
					if (LightFallback)
					{
						reflections = texCUBElod(reflectionCube, float4(reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
						reflections = DecodeHDR(float4(reflections, 1), hdrData) * pl.finalLighting;
					}
					#endif
				}
				reflections *= pl.occlusion;
				return reflections;
			}
			
			float GetGGXTerm(float nDotL, float nDotV, float nDotH, float roughness)
			{
				float visibilityTerm = 0;
				if (nDotL > 0)
				{
					float rough = roughness;
					float rough2 = roughness * roughness;
					
					float lambdaV = nDotL * (nDotV * (1 - rough) + rough);
					float lambdaL = nDotV * (nDotL * (1 - rough) + rough);
					
					visibilityTerm = 0.5f / (lambdaV + lambdaL + 1e-5f);
					float d = (nDotH * rough2 - nDotH) * nDotH + 1.0f;
					float dotTerm = UNITY_INV_PI * rough2 / (d * d + 1e-7f);
					
					visibilityTerm *= dotTerm * UNITY_PI;
				}
				return visibilityTerm;
			}
			
			void GetSpecFresTerm(float nDotL, float nDotV, float nDotH, float lDotH, inout float3 specularTerm, inout float3 fresnelTerm, float3 specCol, float roughness)
			{
				specularTerm = GetGGXTerm(nDotL, nDotV, nDotH, roughness);
				fresnelTerm = FresnelTerm(specCol, lDotH);
				specularTerm = max(0, specularTerm * max(0.00001, nDotL));
			}
			
			float GetRoughness(float smoothness)
			{
				float rough = 1 - smoothness;
				rough *= 1.7 - 0.7 * rough;
				return rough;
			}
			#endif
			//endex
			
			//ifex _MochieBRDF==0
			#ifdef MOCHIE_PBR
			void MetallicAndSpecularFragDataInit(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float smoothness = _MochieRoughnessMultiplier;
				float smoothness2 = _MochieRoughnessMultiplier2;
				float metallic = _MochieMetallicMultiplier;
				float specularMask = 1;
				float reflectionMask = 1;
				
				smoothness *= poiFragData.smoothness;
				smoothness2 *= poiFragData.smoothness2;
				metallic *= poiFragData.metallic;
				specularMask *= poiFragData.specularMask;
				reflectionMask *= poiFragData.reflectionMask;
				
				#if defined(PROP_MOCHIEMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 PBRMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_MochieMetallicMaps, _MainTex, poiUV(poiMesh.uv[_MochieMetallicMapsUV], _MochieMetallicMaps_ST), _MochieMetallicMapsPan, _MochieMetallicMapsStochastic);
				UNITY_BRANCH
				if (_PBRSplitMaskSample)
				{
					float4 PBRSplitMask = POI2D_SAMPLER_PAN_STOCHASTIC(_MochieMetallicMaps, _MainTex, poiUV(poiMesh.uv[_MochieMetallicMasksUV], _PBRMaskScaleTiling), _MochieMetallicMasksPan.xy, _PBRSplitMaskStochastic);
					assignValueToVectorFromIndex(PBRMaps, _MochieMetallicMapsReflectionMaskChannel, PBRSplitMask[_MochieMetallicMapsReflectionMaskChannel]);
					assignValueToVectorFromIndex(PBRMaps, _MochieMetallicMapsSpecularMaskChannel, PBRSplitMask[_MochieMetallicMapsSpecularMaskChannel]);
				}
				
				if (_MochieMetallicMapsMetallicChannel < 4)
				{
					metallic *= PBRMaps[_MochieMetallicMapsMetallicChannel];
				}
				if (_MochieMetallicMapsRoughnessChannel < 4)
				{
					smoothness *= PBRMaps[_MochieMetallicMapsRoughnessChannel];
					smoothness2 *= PBRMaps[_MochieMetallicMapsRoughnessChannel];
				}
				if (_MochieMetallicMapsReflectionMaskChannel < 4)
				{
					reflectionMask *= PBRMaps[_MochieMetallicMapsReflectionMaskChannel];
				}
				if (_MochieMetallicMapsSpecularMaskChannel < 4)
				{
					specularMask *= PBRMaps[_MochieMetallicMapsSpecularMaskChannel];
				}
				#endif
				
				reflectionMask *= _MochieReflectionStrength;
				specularMask *= _MochieSpecularStrength;
				
				if (_MochieMetallicMapInvert)
				{
					metallic = 1 - metallic;
				}
				if (_MochieRoughnessMapInvert)
				{
					smoothness = 1 - smoothness;
					smoothness2 = 1 - smoothness2;
				}
				if (_MochieReflectionMaskInvert)
				{
					reflectionMask = 1 - reflectionMask;
				}
				if (_MochieSpecularMaskInvert)
				{
					specularMask = 1 - specularMask;
				}
				
				poiFragData.smoothness *= smoothness;
				poiFragData.smoothness2 *= smoothness2;
				poiFragData.metallic *= metallic;
				poiFragData.specularMask *= specularMask;
				poiFragData.reflectionMask *= reflectionMask;
			}
			
			void MochieBRDF(inout PoiFragData poiFragData, in PoiCam poiCam, inout PoiLight poiLight, in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				float smoothness = poiFragData.smoothness;
				float smoothness2 = poiFragData.smoothness2;
				float metallic = poiFragData.metallic;
				float specularMask = poiFragData.specularMask;
				float reflectionMask = poiFragData.reflectionMask;
				
				if (_MochieMetallicGlobalMask > 0)
				{
					metallic = customBlend(metallic, poiMods.globalMask[_MochieMetallicGlobalMask - 1], _MochieMetallicGlobalMaskBlendType);
				}
				if (_MochieSmoothnessGlobalMask > 0)
				{
					smoothness = customBlend(smoothness, poiMods.globalMask[_MochieSmoothnessGlobalMask - 1], _MochieSmoothnessGlobalMaskBlendType);
					smoothness2 = customBlend(smoothness2, poiMods.globalMask[_MochieSmoothnessGlobalMask - 1], _MochieSmoothnessGlobalMaskBlendType);
				}
				if (_MochieReflectionStrengthGlobalMask > 0)
				{
					reflectionMask = customBlend(reflectionMask, poiMods.globalMask[_MochieReflectionStrengthGlobalMask - 1], _MochieReflectionStrengthGlobalMaskBlendType);
				}
				if (_MochieSpecularStrengthGlobalMask > 0)
				{
					specularMask = customBlend(specularMask, poiMods.globalMask[_MochieSpecularStrengthGlobalMask - 1], _MochieSpecularStrengthGlobalMaskBlendType);
				}
				
				#ifdef TPS_Penetrator
				if (_BRDFTPSDepthEnabled)
				{
					reflectionMask = lerp(0, reflectionMask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _BRDFTPSReflectionMaskStrength);
					specularMask = lerp(0, specularMask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _BRDFTPSSpecularMaskStrength);
				}
				#endif
				
				float roughness = GetRoughness(smoothness);
				float roughness2 = GetRoughness(smoothness2);
				float3 specCol = lerp(unity_ColorSpaceDielectricSpec.rgb, poiFragData.baseColor, metallic);
				float omr = unity_ColorSpaceDielectricSpec.a - metallic * unity_ColorSpaceDielectricSpec.a;
				float percepRough = 1 - smoothness;
				float percepRough2 = 1 - smoothness2;
				UNITY_BRANCH
				if (_MochieGSAAEnabled)
				{
					percepRough = GSAA_Filament(poiMesh.normals[_PBRNormalSelect], percepRough, _PoiGSAAVariance, _PoiGSAAThreshold);
					if (_Specular2ndLayer == 1 && _MochieSpecularStrength2 > 0)
					{
						percepRough2 = GSAA_Filament(poiMesh.normals[_PBRNormalSelect], percepRough2, _PoiGSAAVariance, _PoiGSAAThreshold);
					}
				}
				float brdfRoughness = percepRough * percepRough;
				brdfRoughness = max(brdfRoughness, 0.002);
				
				float brdfRoughness2 = percepRough2 * percepRough2;
				brdfRoughness2 = max(brdfRoughness2, 0.002);
				
				float3 diffuse = poiFragData.baseColor;
				float3 specular = 0;
				float3 specular2 = 0;
				float3 vSpecular = 0;
				float3 vSpecular2 = 0;
				float3 reflections = 0;
				float3 environment = 0;
				
				#if defined(POINT) || defined(SPOT)
				float attenuation = lerp(poiLight.additiveShadow, 1, _IgnoreCastedShadows);
				#else
				float attenuation = min(poiLight.nDotLSaturated, lerp(poiLight.attenuation, 1, _IgnoreCastedShadows));
				#endif
				
				float3 fresnelTerm = 1;
				float3 specularTerm = 1;
				
				float pbrNDotL = lerp(poiLight.vertexNDotL, poiLight.nDotL, _PBRNormalSelect);
				float pbrNDotV = lerp(poiLight.vertexNDotV, poiLight.nDotV, _PBRNormalSelect);
				float pbrNDotH = lerp(poiLight.vertexNDotH, poiLight.nDotH, _PBRNormalSelect);
				float3 pbrReflectionDir = lerp(poiCam.vertexReflectionDir, poiCam.reflectionDir, _PBRNormalSelect);
				
				GetSpecFresTerm(pbrNDotL, pbrNDotV, pbrNDotH, poiLight.lDotH, specularTerm, fresnelTerm, specCol, brdfRoughness);
				specular = poiLight.directColor * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _MochieSpecularTint, _MochieSpecularTintThemeIndex) * poiLight.occlusion * attenuation;
				
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					for (int index = 0; index < 4; index++)
					{
						fresnelTerm = 1;
						specularTerm = 1;
						float pbrVDotNL = lerp(poiLight.vertexVDotNL[index], poiLight.vDotNL[index], _PBRNormalSelect);
						float pbrVDotNH = lerp(poiLight.vertexVDotNH[index], poiLight.vDotNH[index], _PBRNormalSelect);
						GetSpecFresTerm(pbrVDotNL, pbrNDotV, pbrVDotNH, poiLight.vDotLH[index], specularTerm, fresnelTerm, specCol, brdfRoughness);
						vSpecular += poiLight.vColor[index] * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _MochieSpecularTint, _MochieSpecularTintThemeIndex) * poiLight.occlusion;
					}
					#endif
				}
				
				if (_Specular2ndLayer == 1)
				{
					float3 fresnelTerm = 1;
					float3 specularTerm = 1;
					GetSpecFresTerm(pbrNDotL, pbrNDotV, pbrNDotH, poiLight.lDotH, specularTerm, fresnelTerm, specCol, brdfRoughness2);
					specular2 = poiLight.directColor * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _MochieSpecularTint, _MochieSpecularTintThemeIndex) * poiLight.occlusion * attenuation * _MochieSpecularStrength2;
					
					if (poiFragData.toggleVertexLights)
					{
						#if defined(VERTEXLIGHT_ON)
						for (int index = 0; index < 4; index++)
						{
							fresnelTerm = 1;
							specularTerm = 1;
							float pbrVDotNL = lerp(poiLight.vertexVDotNL[index], poiLight.vDotNL[index], _PBRNormalSelect);
							float pbrVDotNH = lerp(poiLight.vertexVDotNH[index], poiLight.vDotNH[index], _PBRNormalSelect);
							GetSpecFresTerm(pbrVDotNL, pbrNDotV, pbrVDotNH, poiLight.vDotLH[index], specularTerm, fresnelTerm, specCol, brdfRoughness2);
							vSpecular2 += poiLight.vColor[index] * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _MochieSpecularTint, _MochieSpecularTintThemeIndex) * poiLight.occlusion * _MochieSpecularStrength2;
						}
						#endif
					}
				}
				
				float surfaceReduction = (1.0 / (brdfRoughness * brdfRoughness + 1.0));
				float grazingTerm = saturate(smoothness + (1 - omr));
				float3 reflCol = GetReflections(poiCam, poiLight, poiMesh, roughness, _MochieForceFallback, _MochieLitFallback, _MochieReflCube, _MochieReflCube_HDR, pbrReflectionDir);
				if (poiMesh.isFrontFace)
				{
					reflections = surfaceReduction * reflCol * lerp(1, FresnelLerp(specCol, grazingTerm, pbrNDotV), _RefSpecFresnel);
				}
				else
				{
					reflections = surfaceReduction * reflCol * lerp(1, FresnelLerp(specCol, grazingTerm, pbrNDotV), _RefSpecFresnelBack);
				}
				
				reflections *= poiThemeColor(poiMods, _MochieReflectionTint, _MochieReflectionTintThemeIndex);
				reflections *= reflectionMask;
				diffuse = lerp(diffuse, diffuse * omr, reflectionMask);
				
				environment = max(specular + vSpecular, specular2 + vSpecular2);
				environment += reflections;
				diffuse *= poiLight.finalLighting;
				poiFragData.finalColor = diffuse;
				poiLight.finalLightAdd += environment;
			}
			#endif
			//endex
			//ifex _ClearCoatBRDF==0
			#ifdef POI_CLEARCOAT
			void poiClearCoat(inout PoiFragData poiFragData, in PoiCam poiCam, inout PoiLight poiLight, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float clearCoatMask = _ClearCoatStrength;
				float smoothness = _ClearCoatSmoothness;
				float reflectionMask = _ClearCoatReflectionStrength;
				float specularMask = _ClearCoatSpecularStrength;
				
				#if defined(PROP_CLEARCOATMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 PBRMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_ClearCoatMaps, _MainTex, poiUV(poiMesh.uv[_ClearCoatMapsUV], _ClearCoatMaps_ST), _ClearCoatMapsPan, _ClearCoatMapsStochastic);
				
				if (_ClearCoatMapsClearCoatMaskChannel < 4)
				{
					clearCoatMask *= PBRMaps[_ClearCoatMapsClearCoatMaskChannel];
				}
				if (_ClearCoatMapsRoughnessChannel < 4)
				{
					smoothness *= PBRMaps[_ClearCoatMapsRoughnessChannel];
				}
				if (_ClearCoatMapsReflectionMaskChannel < 4)
				{
					reflectionMask *= PBRMaps[_ClearCoatMapsReflectionMaskChannel];
				}
				if (_ClearCoatMapsSpecularMaskChannel < 4)
				{
					specularMask *= PBRMaps[_ClearCoatMapsSpecularMaskChannel];
				}
				#endif
				
				if (_ClearCoatGlobalMask > 0)
				{
					clearCoatMask = customBlend(clearCoatMask, poiMods.globalMask[_ClearCoatGlobalMask - 1], _ClearCoatGlobalMaskBlendType);
				}
				if (_ClearCoatSmoothnessGlobalMask > 0)
				{
					smoothness = customBlend(smoothness, poiMods.globalMask[_ClearCoatSmoothnessGlobalMask - 1], _ClearCoatSmoothnessGlobalMaskBlendType);
				}
				if (_ClearCoatReflectionStrengthGlobalMask > 0)
				{
					reflectionMask = customBlend(reflectionMask, poiMods.globalMask[_ClearCoatReflectionStrengthGlobalMask - 1], _ClearCoatReflectionStrengthGlobalMaskBlendType);
				}
				if (_ClearCoatSpecularStrengthGlobalMask > 0)
				{
					specularMask = customBlend(specularMask, poiMods.globalMask[_ClearCoatSpecularStrengthGlobalMask - 1], _ClearCoatSpecularStrengthGlobalMaskBlendType);
				}
				
				if (_ClearCoatMaskInvert)
				{
					clearCoatMask = 1 - clearCoatMask;
				}
				if (_ClearCoatSmoothnessMapInvert)
				{
					smoothness = 1 - smoothness;
				}
				if (_ClearCoatReflectionMaskInvert)
				{
					reflectionMask = 1 - reflectionMask;
				}
				if (_ClearCoatSpecularMaskInvert)
				{
					specularMask = 1 - specularMask;
				}
				#ifdef TPS_Penetrator
				if (_ClearCoatTPSDepthMaskEnabled)
				{
					clearCoatMask = lerp(0, clearCoatMask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _ClearCoatTPSMaskStrength);
				}
				#endif
				
				float roughness = GetRoughness(smoothness);
				float3 specCol = 0.220916301;
				float omr = unity_ColorSpaceDielectricSpec.a;
				float percepRough = 1 - smoothness;
				UNITY_BRANCH
				if (_ClearCoatGSAAEnabled)
				{
					percepRough = GSAA_Filament(poiMesh.normals[_ClearCoatNormalSelect], percepRough, _ClearCoatGSAAVariance, _ClearCoatGSAAThreshold);
				}
				float brdfRoughness = percepRough * percepRough;
				brdfRoughness = max(brdfRoughness, 0.002);
				
				float3 diffuse = 0;
				float3 specular = 0;
				float3 vSpecular = 0;
				float3 reflections = 0;
				float3 environment = 0;
				float attenuation = min(poiLight.nDotLSaturated, lerp(poiLight.attenuation, 1, _CCIgnoreCastedShadows));
				
				float3 fresnelTerm = 1;
				float3 specularTerm = 1;
				
				float clearcoatNDotL = lerp(poiLight.vertexNDotL, poiLight.nDotL, _ClearCoatNormalSelect);
				float clearcoatNDotV = lerp(poiLight.vertexNDotV, poiLight.nDotV, _ClearCoatNormalSelect);
				float clearcoatNDotH = lerp(poiLight.vertexNDotH, poiLight.nDotH, _ClearCoatNormalSelect);
				float3 clearcoatReflectionDir = lerp(poiCam.vertexReflectionDir, poiCam.reflectionDir, _ClearCoatNormalSelect);
				
				GetSpecFresTerm(clearcoatNDotL, clearcoatNDotV, clearcoatNDotH, poiLight.lDotH, specularTerm, fresnelTerm, specCol, brdfRoughness);
				specular = poiLight.directColor * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _ClearCoatSpecularTint, _ClearCoatSpecularTintThemeIndex) * poiLight.occlusion * attenuation;
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					for (int index = 0; index < 4; index++)
					{
						fresnelTerm = 1;
						specularTerm = 1;
						float clearcoatVDotNL = lerp(poiLight.vertexVDotNL[index], poiLight.vDotNL[index], _ClearCoatNormalSelect);
						float clearcoatVDotNH = lerp(poiLight.vertexVDotNH[index], poiLight.vDotNH[index], _ClearCoatNormalSelect);
						GetSpecFresTerm(clearcoatVDotNL, clearcoatNDotV, clearcoatVDotNH, poiLight.vDotLH[index], specularTerm, fresnelTerm, specCol, brdfRoughness);
						vSpecular += poiLight.vColor[index] * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _ClearCoatSpecularTint, _ClearCoatSpecularTintThemeIndex) * poiLight.occlusion;
					}
					#endif
				}
				
				float surfaceReduction = (1.0 / (brdfRoughness * brdfRoughness + 1.0));
				float grazingTerm = saturate(smoothness + (1 - omr));
				float3 reflCol = GetReflections(poiCam, poiLight, poiMesh, roughness, _ClearCoatForceFallback, _ClearCoatLitFallback, _ClearCoatFallback, _ClearCoatFallback_HDR, clearcoatReflectionDir);
				reflections = surfaceReduction * reflCol * lerp(1, FresnelLerp(specCol, grazingTerm, clearcoatNDotV), _ClearcoatFresnel);
				reflections *= poiThemeColor(poiMods, _ClearCoatReflectionTint, _ClearCoatReflectionTintThemeIndex) * reflectionMask;
				diffuse = lerp(diffuse, diffuse * omr, reflectionMask);
				
				environment = specular + vSpecular;
				#ifdef UNITY_PASS_FORWARDBASE
				environment += reflections;
				#endif
				//diffuse *= poiLight.finalLighting;
				diffuse += environment;
				poiLight.finalLightAdd += saturate(diffuse * clearCoatMask);
			}
			#endif
			//endex
			
			//ifex _StylizedSpecular==0
			#ifdef POI_STYLIZED_StylizedSpecular
			void stylizedSpecular(inout PoiFragData poiFragData, in PoiCam poiCam, inout PoiLight poiLight, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float specArea = 0.5 * poiLight.nDotH + 0.5;
				#if defined(PROP_HIGHCOLOR_TEX) || !defined(OPTIMIZER_ENABLED)
				float3 specularMap = POI2D_SAMPLER_PAN(_HighColor_Tex, _MainTex, poiUV(poiMesh.uv[_HighColor_TexUV], _HighColor_Tex_ST), _HighColor_TexPan);
				#else
				float3 specularMap = 1;
				#endif
				
				// Spec 1
				float specMask1 = 0;
				float specMask2 = 0;
				if (_Is_SpecularToHighColor)
				{
					specMask1 += pow(specArea, exp2(lerp(11, 1, _HighColor_Power))) * _Layer1Strength;
					specMask2 += pow(specArea, exp2(lerp(11, 1, _Layer2Size))) * _Layer2Strength;
				}
				else
				{
					specMask1 += poiEdgeNonLinear(specArea, (1.0 - pow(_HighColor_Power, 5)), _StylizedSpecularFeather) * _Layer1Strength;
					specMask2 += poiEdgeNonLinear(specArea, (1.0 - pow(_Layer2Size, 5)), _StylizedSpecular2Feather) * _Layer2Strength;
				}
				
				#if defined(PROP_SET_HIGHCOLORMASK) || !defined(OPTIMIZER_ENABLED)
				float specularMask = POI2D_SAMPLER_PAN(_Set_HighColorMask, _MainTex, poiUV(poiMesh.uv[_Set_HighColorMaskUV], _Set_HighColorMask_ST), _Set_HighColorMaskPan)[_Set_HighColorMaskChannel];
				#else
				float specularMask = 1;
				#endif
				
				specularMask = saturate(specularMask + _Tweak_HighColorMaskLevel);
				
				float specMask = saturate(specMask1 + specMask2) * specularMask * lerp(poiLight.rampedLightMap, 1, _StylizedSpecularIgnoreShadow);
				float attenuation = min(lerp(poiLight.nDotLSaturated, 1, _StylizedSpecularIgnoreNormal), lerp(lerp(poiLight.attenuation, 1, _SSIgnoreCastedShadows), 1, _StylizedSpecularIgnoreShadow));
				#ifdef POI_PASS_ADD
				attenuation *= lerp(poiLight.additiveShadow, 1, _SSIgnoreCastedShadows);
				#endif
				
				float finalSpecMask = min(min(specMask, poiLight.occlusion), attenuation) * _StylizedSpecularStrength;
				switch(_Is_BlendAddToHiColor)
				{
					case 0:
					// Replace
					poiFragData.baseColor = lerp(poiFragData.baseColor, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.directColor, _UseLightColor), finalSpecMask);
					break;
					case 1:
					// Add
					poiLight.finalLightAdd += max(0, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.directColor, _UseLightColor) * finalSpecMask);
					break;
					case 2:
					// Screen
					poiFragData.baseColor = lerp(poiFragData.baseColor, blendScreen(poiFragData.baseColor, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.directColor, _UseLightColor)), finalSpecMask);
					break;
					case 3:
					// Multiply
					poiFragData.baseColor = lerp(poiFragData.baseColor, poiFragData.baseColor * specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.directColor, _UseLightColor), finalSpecMask);
					break;
				}
				
				//poiFragData.baseColor = _StylizedSpecularStrength;
				
				float3 vSpecMask = 0;
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					for (int index = 0; index < 4; index++)
					{
						if (!any(poiLight.vPosition[index])) continue;
						specArea = 0.5 * poiLight.vDotNH[index] + 0.5;
						if (_Is_SpecularToHighColor)
						{
							vSpecMask = pow(specArea, exp2(lerp(11, 1, _HighColor_Power))) * _Layer1Strength * poiLight.vAttenuation[index];
							vSpecMask = max(vSpecMask, pow(specArea, exp2(lerp(11, 1, _Layer2Size))) * _Layer2Strength * poiLight.vAttenuation[index]);
						}
						else
						{
							vSpecMask = poiEdgeNonLinear(specArea, (1.0 - pow(_HighColor_Power, 5)), _StylizedSpecularFeather) * _Layer1Strength * poiLight.vAttenuation[index];
							vSpecMask = max(vSpecMask, poiEdgeNonLinear(specArea, (1.0 - pow(_Layer2Size, 5)), _StylizedSpecular2Feather) * _Layer2Strength * poiLight.vAttenuation[index]);
						}
						
						vSpecMask *= specularMask;
						float finalSpecMask = min(min(vSpecMask, poiLight.occlusion), attenuation) * _StylizedSpecularStrength;
						switch(_Is_BlendAddToHiColor)
						{
							case 0:
							// Replace
							poiFragData.baseColor = lerp(poiFragData.baseColor, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.vColor[index], _UseLightColor), finalSpecMask);
							break;
							case 1:
							// Add
							poiLight.finalLightAdd += max(0, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.vColor[index], _UseLightColor) * finalSpecMask);
							break;
							case 2:
							// Screen
							poiFragData.baseColor = lerp(poiFragData.baseColor, blendScreen(poiFragData.baseColor, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.vColor[index], _UseLightColor)), finalSpecMask);
							break;
							case 3:
							// Multiply
							poiFragData.baseColor = lerp(poiFragData.baseColor, poiFragData.baseColor * specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.vColor[index], _UseLightColor), finalSpecMask);
							break;
						}
					}
					#endif
				}
			}
			#endif
			//endex
			
			//ifex _EnablePathing==0
			#ifdef POI_PATHING
			void applyPathing(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float3 albedo = poiFragData.baseColor;
				float3 pathEmission;
				#if defined(PROP_PATHINGMAP) || !defined(OPTIMIZER_ENABLED)
				float4 path = _PathingMap.Sample(SmpRepeatPoint, poiUV(poiMesh.uv[_PathingMapUV], _PathingMap_ST) + _PathingMapPan.xy * _Time.x);
				#else
				float4 path = float4(1, 1, 1, 1);
				#endif
				float4 PathColor[4];
				half pathAudioLinkPathTimeOffsetBand[4] = {
					0, 0, 0, 0
				};
				half2 pathAudioLinkTimeOffset[4] = {
					half2(0, 0), half2(0, 0), half2(0, 0), half2(0, 0)
				};
				half pathAudioLinkPathWidthOffsetBand[4] = {
					0, 0, 0, 0
				};
				half2 pathAudioLinkWidthOffset[4] = {
					half2(0, 0), half2(0, 0), half2(0, 0), half2(0, 0)
				};
				PathColor[0] = _PathColorR;
				PathColor[1] = _PathColorG;
				PathColor[2] = _PathColorB;
				PathColor[3] = _PathColorA;
				
				// Combined data
				if (_PathGradientType == 1)
				{
					path = (path.r + path.g + path.b + path.a) * .25;
				}
				
				#if defined(PROP_PATHINGCOLORMAP) || !defined(OPTIMIZER_ENABLED)
				float4 pathColorMap = POI2D_SAMPLER_PAN(_PathingColorMap, _MainTex, poiUV(poiMesh.uv[_PathingColorMapUV], _PathingColorMap_ST), _PathingColorMapPan);
				#else
				float4 pathColorMap = float4(1, 1, 1, 1);
				#endif
				
				float4 pathAudioLinkEmission = 0;
				float4 pathTime = 0;
				float3 pathAlpha[4] = {
					float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0)
				};
				
				#ifdef POI_AUDIOLINK
				float4 chronoType = float4(_PathChronoTypeR, _PathChronoTypeG, _PathChronoTypeB, _PathChronoTypeA);
				float4 chronoBand = float4(_PathChronoBandR, _PathChronoBandG, _PathChronoBandB, _PathChronoBandA);
				float4 chronoSpeed = float4(_PathChronoSpeedR, _PathChronoSpeedG, _PathChronoSpeedB, _PathChronoSpeedA);
				float3 autoCorrelator[4] = {
					float3(_PathALAutoCorrelatorR, _PathALAutoCorrelatorRangeR[0], _PathALAutoCorrelatorRangeR[1]), float3(_PathALAutoCorrelatorG, _PathALAutoCorrelatorRangeG[0], _PathALAutoCorrelatorRangeG[1]),
					float3(_PathALAutoCorrelatorB, _PathALAutoCorrelatorRangeB[0], _PathALAutoCorrelatorRangeB[1]), float3(_PathALAutoCorrelatorA, _PathALAutoCorrelatorRangeA[0], _PathALAutoCorrelatorRangeA[1])
				};
				float4 history[4] = {
					float4(_PathALHistoryR, _PathALHistoryBandR, _PathALHistoryRangeR[0], _PathALHistoryRangeR[1]), float4(_PathALHistoryG, _PathALHistoryBandG, _PathALHistoryRangeG[0], _PathALHistoryRangeG[1]),
					float4(_PathALHistoryB, _PathALHistoryBandB, _PathALHistoryRangeB[0], _PathALHistoryRangeB[1]), float4(_PathALHistoryA, _PathALHistoryBandA, _PathALHistoryRangeA[0], _PathALHistoryRangeA[1])
				};
				
				if (poiMods.audioLinkAvailable)
				{
					if (_PathALTimeOffset)
					{
						pathAudioLinkPathTimeOffsetBand[0] = _AudioLinkPathTimeOffsetBandR;
						pathAudioLinkPathTimeOffsetBand[1] = _AudioLinkPathTimeOffsetBandG;
						pathAudioLinkPathTimeOffsetBand[2] = _AudioLinkPathTimeOffsetBandB;
						pathAudioLinkPathTimeOffsetBand[3] = _AudioLinkPathTimeOffsetBandA;
						pathAudioLinkTimeOffset[0] = _AudioLinkPathTimeOffsetR.xy;
						pathAudioLinkTimeOffset[1] = _AudioLinkPathTimeOffsetG.xy;
						pathAudioLinkTimeOffset[2] = _AudioLinkPathTimeOffsetB.xy;
						pathAudioLinkTimeOffset[3] = _AudioLinkPathTimeOffsetA.xy;
					}
					
					if (_PathALWidthOffset)
					{
						pathAudioLinkPathWidthOffsetBand[0] = _AudioLinkPathWidthOffsetBandR;
						pathAudioLinkPathWidthOffsetBand[1] = _AudioLinkPathWidthOffsetBandG;
						pathAudioLinkPathWidthOffsetBand[2] = _AudioLinkPathWidthOffsetBandB;
						pathAudioLinkPathWidthOffsetBand[3] = _AudioLinkPathWidthOffsetBandA;
						pathAudioLinkWidthOffset[0] = _AudioLinkPathWidthOffsetR.xy;
						pathAudioLinkWidthOffset[1] = _AudioLinkPathWidthOffsetG.xy;
						pathAudioLinkWidthOffset[2] = _AudioLinkPathWidthOffsetB.xy;
						pathAudioLinkWidthOffset[3] = _AudioLinkPathWidthOffsetA.xy;
					}
					// Emission Offset
					if (_PathALEmissionOffset)
					{
						pathAudioLinkEmission.r += lerp(_AudioLinkPathEmissionAddR.x, _AudioLinkPathEmissionAddR.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandR]);
						pathAudioLinkEmission.g += lerp(_AudioLinkPathEmissionAddG.x, _AudioLinkPathEmissionAddG.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandG]);
						pathAudioLinkEmission.b += lerp(_AudioLinkPathEmissionAddB.x, _AudioLinkPathEmissionAddB.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandB]);
						pathAudioLinkEmission.a += lerp(_AudioLinkPathEmissionAddA.x, _AudioLinkPathEmissionAddA.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandA]);
					}
					
					if(_PathALColorChord)
					{
						if (_PathALCCR)
						{
							PathColor[0] *= AudioLinkLerp(ALPASS_CCSTRIP + float2(path[0] * AUDIOLINK_WIDTH, 0));
						}
						if (_PathALCCG)
						{
							PathColor[1] *= AudioLinkLerp(ALPASS_CCSTRIP + float2(path[1] * AUDIOLINK_WIDTH, 0));
						}
						if (_PathALCCB)
						{
							PathColor[2] *= AudioLinkLerp(ALPASS_CCSTRIP + float2(path[2] * AUDIOLINK_WIDTH, 0));
						}
						if (_PathALCCA)
						{
							PathColor[3] *= AudioLinkLerp(ALPASS_CCSTRIP + float2(path[3] * AUDIOLINK_WIDTH, 0));
						}
					}
				}
				#endif
				
				[unroll]
				for (int index = 0; index < 4; index++)
				{
					float timeOffset = 0;
					#ifdef POI_AUDIOLINK
					UNITY_BRANCH
					if (poiMods.audioLinkAvailable)
					{
						if (_PathALTimeOffset)
						{
							timeOffset += lerp(pathAudioLinkTimeOffset[index].x, pathAudioLinkTimeOffset[index].y, poiMods.audioLink[pathAudioLinkPathTimeOffsetBand[index]]);
						}
						
						if (_PathALChrono)
						{
							timeOffset += AudioLinkGetChronoTime(chronoType[index], chronoBand[index]) * chronoSpeed[index];
						}
					}
					#endif
					pathTime[index] = _PathTime[index] != -999.0f ? frac(_PathTime[index] + _PathOffset[index] + timeOffset) : frac(_Time.x * _PathSpeed[index] + _PathOffset[index] + timeOffset);
					
					if (_PathSegments[index])
					{
						float pathSegments = abs(_PathSegments[index]);
						pathTime = (ceil(pathTime * pathSegments) - .5) / pathSegments;
					}
					
					if (path[index])
					{
						// Cutting it in half because it goes out in both directions for now
						half pathWidth = _PathWidth[index] * .5;
						#ifdef POI_AUDIOLINK
						UNITY_BRANCH
						if (poiMods.audioLinkAvailable)
						{
							if (_PathALWidthOffset)
							{
								pathWidth += lerp(pathAudioLinkWidthOffset[index].x, pathAudioLinkWidthOffset[index].y, poiMods.audioLink[pathAudioLinkPathWidthOffsetBand[index]]);
							}
						}
						#endif
						
						//fill
						pathAlpha[index].x = pathTime[index] > path[index];
						//path
						pathAlpha[index].y = saturate((1 - abs(lerp(-pathWidth, 1 + pathWidth, pathTime[index]) - path[index])) - (1 - pathWidth)) * (1 / pathWidth);
						//loop
						pathAlpha[index].z = saturate((1 - distance(pathTime[index], path[index])) - (1 - pathWidth)) * (1 / pathWidth);
						pathAlpha[index].z += saturate(distance(pathTime[index], path[index]) - (1 - pathWidth)) * (1 / pathWidth);
						pathAlpha[index] = smoothstep(0, _PathSoftness[index] + .00001, pathAlpha[index]);
						
						#ifdef POI_AUDIOLINK
						if (poiMods.audioLinkAvailable)
						{
							if (_PathALHistory && history[index][0])
							{
								// history[index]: [0]: on/off, [1]: band, [2]/[3] min/max
								float historyUV = lerp(history[index][2], history[index][3], path[index]);
								
								if (_PathSegments[index])
								{
									float pathSegments = abs(_PathSegments[index]);
									historyUV = (ceil(historyUV * pathSegments) - .5) / pathSegments;
								}
								
								historyUV *= AUDIOLINK_WIDTH;
								
								float historyValue = AudioLinkLerp(ALPASS_AUDIOLINK + float2(historyUV, history[index][1]))[0];
								
								if(_PathALHistoryMode == 0) // Mask
								pathAlpha[index] *= historyValue;
								else // Override
								pathAlpha[index] = historyValue;
							}
							
							if (_PathALAutoCorrelator && autoCorrelator[index][0] != 0)
							{
								// autoCorrelator[index]: [0]: on/off, [1]/[2]: min/max
								// Choose from only part of the autocorrelator
								float autoCorrelatorUV = lerp(autoCorrelator[index][1], autoCorrelator[index][2], path[index]);
								if (autoCorrelator[index][0] == 2) // Mirror
								{
									autoCorrelatorUV = abs(1. - autoCorrelatorUV * 2.);
								}
								
								if (_PathSegments[index])
								{
									float pathSegments = abs(_PathSegments[index]);
									autoCorrelatorUV = (ceil(autoCorrelatorUV * pathSegments) - .5) / pathSegments;
								}
								
								// Normalize Autocorrelator Value
								float autoCorrelatorValue = AudioLinkLerp(ALPASS_AUTOCORRELATOR + float2(autoCorrelatorUV * AUDIOLINK_WIDTH, 0))[0];
								float autoCorrelatorMax = AudioLinkLerp(ALPASS_AUTOCORRELATOR);
								autoCorrelatorValue = saturate(abs(autoCorrelatorValue) * rcp(autoCorrelatorMax));
								
								// Autocorrelator is normalized, so can look weird at lower volume levels. use Filtered VU intensity to make it smoothly fall off at low volume levels.
								float4 vu = AudioLinkData(ALPASS_FILTEREDVU_INTENSITY + uint2(0, 0));
								autoCorrelatorValue *= smoothstep(0.01, 0.2, vu);
								
								if(_PathALAutoCorrelatorMode == 0) // Mask
								pathAlpha[index] *= autoCorrelatorValue;
								else // Override
								pathAlpha[index] = autoCorrelatorValue;
								
							}
						}
						#endif
					}
				}
				
				// Emission
				pathEmission = 0;
				pathEmission += pathAlpha[0][_PathTypeR] * poiThemeColor(poiMods, PathColor[0].rgb, _PathColorRThemeIndex) * (_PathEmissionStrength[0] + pathAudioLinkEmission.r);
				pathEmission += pathAlpha[1][_PathTypeG] * poiThemeColor(poiMods, PathColor[1].rgb, _PathColorGThemeIndex) * (_PathEmissionStrength[1] + pathAudioLinkEmission.g);
				pathEmission += pathAlpha[2][_PathTypeB] * poiThemeColor(poiMods, PathColor[2].rgb, _PathColorBThemeIndex) * (_PathEmissionStrength[2] + pathAudioLinkEmission.b);
				pathEmission += pathAlpha[3][_PathTypeA] * poiThemeColor(poiMods, PathColor[3].rgb, _PathColorAThemeIndex) * (_PathEmissionStrength[3] + pathAudioLinkEmission.a);
				pathEmission *= pathColorMap.rgb * pathColorMap.a;
				
				float3 colorReplace = 0;
				colorReplace = pathAlpha[0][_PathTypeR] * poiThemeColor(poiMods, PathColor[0].rgb, _PathColorRThemeIndex) * pathColorMap.rgb;
				albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * PathColor[0].a * pathAlpha[0][_PathTypeR]);
				colorReplace = pathAlpha[1][_PathTypeG] * poiThemeColor(poiMods, PathColor[1].rgb, _PathColorGThemeIndex) * pathColorMap.rgb;
				albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * PathColor[1].a * pathAlpha[1][_PathTypeG]);
				colorReplace = pathAlpha[2][_PathTypeB] * poiThemeColor(poiMods, PathColor[2].rgb, _PathColorBThemeIndex) * pathColorMap.rgb;
				albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * PathColor[2].a * pathAlpha[2][_PathTypeB]);
				colorReplace = pathAlpha[3][_PathTypeA] * poiThemeColor(poiMods, PathColor[3].rgb, _PathColorAThemeIndex) * pathColorMap.rgb;
				albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * PathColor[3].a * pathAlpha[3][_PathTypeA]);
				
				float alpha = max(max(max(pathAlpha[0][_PathTypeR], pathAlpha[1][_PathTypeG]), pathAlpha[2][_PathTypeB]), pathAlpha[3][_PathTypeA]);
				
				poiFragData.alpha *= lerp(1, alpha, _PathingOverrideAlpha);
				poiFragData.baseColor = albedo.rgb;
				poiFragData.emission += pathEmission;
			}
			#endif
			//endex
			
			//ifex _EnableMirrorOptions==0
			#ifdef POI_MIRROR
			void applyMirror(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float inMirror = 0;
				// VRC
				if (_VisibilityMode == 1)
				{
					inMirror = VRCMirrorMode() > 0;
				}
				// Generic (CVR, etc)
				else
				{
					inMirror = IsInMirror();
				}
				
				#if (defined(POI_PASS_BASE) || defined(POI_PASS_ADD))
				#if defined(PROP_MIRRORTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 mirrorTexture = POI2D_SAMPLER_PAN(_MirrorTexture, _MainTex, poiUV(poiMesh.uv[_MirrorTextureUV], _MirrorTexture_ST), _MirrorTexturePan);
				if (inMirror && _MirrorTextureEnabled || _MirrorTextureForceEnabled)
				{
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, mirrorTexture.rgb, _MirrorTextureBlendType), mirrorTexture.a * _MirrorColor.a);
					poiFragData.baseColor.rgb *= lerp(1, poiThemeColor(poiMods, _MirrorColor.rgb, _MirrorColorThemeIndex), _MirrorColor.a);
				}
				#else
				if (inMirror && _MirrorTextureEnabled || _MirrorTextureForceEnabled)
				{
					poiFragData.baseColor.rgb *= lerp(1, poiThemeColor(poiMods, _MirrorColor.rgb, _MirrorColorThemeIndex), _MirrorColor.a);
				}
				#endif
				#endif
			}
			#endif
			//endex
			
			//ifex _EnableTouchGlow==0
			#ifdef GRAIN
			void applyDepthFX(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float3 touchEmission = 0;
				
				float perspectiveDivide = 1.0f / poiCam.clipPos.w;
				float4 direction = poiCam.worldDirection * perspectiveDivide;
				float2 screenPos = poiCam.posScreenSpace * perspectiveDivide;
				float z = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, screenPos);
				
				#if UNITY_REVERSED_Z
				if (z == 0)
				#else
				if (z == 1)
				#endif
				return;
				
				float depth = CorrectedLinearEyeDepth(z, direction.w);
				float3 worldpos = direction * depth + _WorldSpaceCameraPos.xyz;
				/*
				finalColor.rgb = frac(worldpos);
				return;
				*/
				
				float diff = distance(worldpos, poiMesh.worldPos);
				//poiFragData.finalColor = diff;
				
				#if defined(PROP_DEPTHMASK) || !defined(OPTIMIZER_ENABLED)
				float depthMask = POI2D_SAMPLER_PAN(_DepthMask, _MainTex, poiUV(poiMesh.uv[_DepthMaskUV], _DepthMask_ST), _DepthMaskPan)[_DepthMaskChannel];
				#else
				float depthMask = 1;
				#endif
				
				if (_DepthMaskGlobalMask > 0)
				{
					depthMask = maskBlend(depthMask, poiMods.globalMask[_DepthMaskGlobalMask - 1], _DepthMaskGlobalMaskBlendType);
				}
				
				if (_DepthColorToggle)
				{
					float colorBlendAlpha = lerp(_DepthColorMinValue, _DepthColorMaxValue, remapClamped(_DepthColorMinDepth, _DepthColorMaxDepth, diff));
					
					#if defined(PROP_DEPTHTEXTURE) || !defined(OPTIMIZER_ENABLED)
					float2 depthTextureUV = float2(0, 0);
					if (_DepthTextureUV == 8)
					{
						depthTextureUV = lerp(0, 1, remapClamped(_DepthColorMinDepth, _DepthColorMaxDepth, diff));
					}
					else
					{
						depthTextureUV = poiMesh.uv[_DepthTextureUV];
					}
					float3 depthColor = POI2D_SAMPLER_PAN(_DepthTexture, _MainTex, poiUV(depthTextureUV, _DepthTexture_ST), _DepthTexturePan).rgb * poiThemeColor(poiMods, _DepthColor, _DepthColorThemeIndex);
					#else
					float3 depthColor = poiThemeColor(poiMods, _DepthColor, _DepthColorThemeIndex);
					#endif
					
					switch(_DepthColorBlendMode)
					{
						case 0:
						{
							poiFragData.baseColor = lerp(poiFragData.baseColor, depthColor, colorBlendAlpha * depthMask);
							break;
						}
						case 1:
						{
							poiFragData.baseColor *= lerp(1, depthColor, colorBlendAlpha * depthMask);
							break;
						}
						case 2:
						{
							poiFragData.baseColor = saturate(poiFragData.baseColor + lerp(0, depthColor, colorBlendAlpha * depthMask));
							break;
						}
					}
					poiFragData.emission += depthColor * colorBlendAlpha * _DepthEmissionStrength * depthMask;
				}
				
				if (_DepthAlphaToggle)
				{
					poiFragData.alpha *= lerp(poiFragData.alpha, saturate(lerp(_DepthAlphaMinValue, _DepthAlphaMaxValue, remapClamped(_DepthAlphaMinDepth, _DepthAlphaMaxDepth, diff))), depthMask);
				}
			}
			#endif
			//endex
			
			//ifex _TextEnabled==0
			#ifdef EFFECT_BUMP
			
			float2 TransformUV(float2 offset, float rotation, float2 scale, float2 uv)
			{
				float theta = radians(rotation);
				scale = 1 - scale;
				float cs = cos(theta);
				float sn = sin(theta);
				float2 centerPoint = offset + .5;
				uv = float2((uv.x - centerPoint.x) * cs - (uv.y - centerPoint.y) * sn + centerPoint.x, (uv.x - centerPoint.x) * sn + (uv.y - centerPoint.y) * cs + centerPoint.y);
				
				return remap(uv, float2(0, 0) + offset + (scale * .5), float2(1, 1) + offset - (scale * .5), float2(0, 0), float2(1, 1));
			}
			
			float2 getAsciiCoordinate(float index)
			{
				return float2((index - 1) / 16, 1 - ((floor(index / 16 - glyphWidth)) / 16));
			}
			
			float median(float r, float g, float b)
			{
				return max(min(r, g), min(max(r, g), b));
			}
			
			void ApplyPositionText(inout PoiFragData poiFragData, float2 uv, in PoiMods poiMods)
			{
				float3 cameraPos = clamp(getCameraPosition(), -999, 999);
				float3 absCameraPos = abs(cameraPos);
				float totalCharacters = 20;
				float positionArray[20];
				positionArray[0] = cameraPos.x >= 0 ? ASCII_NEGATIVE : ASCII_POSITIVE;
				positionArray[1] = floor((absCameraPos.x * .01) % 10) + 48;
				positionArray[2] = floor((absCameraPos.x * .1) % 10) + 48;
				positionArray[3] = floor(absCameraPos.x % 10) + 48;
				positionArray[4] = ASCII_PERIOD;
				positionArray[5] = floor((absCameraPos.x * 10) % 10) + 48;
				positionArray[6] = ASCII_COMMA;
				positionArray[7] = cameraPos.y >= 0 ? ASCII_NEGATIVE : ASCII_POSITIVE;
				positionArray[8] = floor((absCameraPos.y * .01) % 10) + 48;
				positionArray[9] = floor((absCameraPos.y * .1) % 10) + 48;
				positionArray[10] = floor(absCameraPos.y % 10) + 48;
				positionArray[11] = ASCII_PERIOD;
				positionArray[12] = floor((absCameraPos.y * 10) % 10) + 48;
				positionArray[13] = ASCII_COMMA;
				positionArray[14] = cameraPos.z >= 0 ? ASCII_NEGATIVE : ASCII_POSITIVE;
				positionArray[15] = floor((absCameraPos.z * .01) % 10) + 48;
				positionArray[16] = floor((absCameraPos.z * .1) % 10) + 48;
				positionArray[17] = floor(absCameraPos.z % 10) + 48;
				positionArray[18] = ASCII_PERIOD;
				positionArray[19] = floor((absCameraPos.z * 10) % 10) + 48;
				
				uv = TransformUV(_TextPositionOffset, _TextPositionRotation, _TextPositionScale, uv);
				
				if (uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
				{
					return;
				}
				
				float currentCharacter = floor(uv.x * totalCharacters);
				float2 glyphPos = getAsciiCoordinate(positionArray[currentCharacter]);
				
				float2 startUV = float2(1 / totalCharacters * currentCharacter, 0);
				float2 endUV = float2(1 / totalCharacters * (currentCharacter + 1), 1);
				
				fixed4 textPositionPadding = _TextPositionPadding;
				textPositionPadding *= 1 / totalCharacters;
				
				uv = remapClamped(startUV, endUV, uv, float2(glyphPos.x + textPositionPadding.x, glyphPos.y - glyphWidth + textPositionPadding.y), float2(glyphPos.x + glyphWidth - textPositionPadding.z, glyphPos.y - textPositionPadding.w));
				
				if (uv.x > glyphPos.x + glyphWidth - textPositionPadding.z - .001 || uv.x < glyphPos.x + textPositionPadding.x + .001 || uv.y > glyphPos.y - textPositionPadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textPositionPadding.y + .001)
				{
					return;
				}
				
				float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
				float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
				float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
				sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
				float opacity = clamp(sigDist + 0.5, 0, 1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, poiThemeColor(poiMods, _TextPositionColor.rgb, _TextPositionColorThemeIndex), opacity * _TextPositionColor.a);
				globalTextEmission += poiThemeColor(poiMods, _TextPositionColor.rgb, _TextPositionColorThemeIndex) * opacity * _TextPositionEmissionStrength;
			}
			
			void ApplyTimeText(inout PoiFragData poiFragData, float2 uv, in PoiMods poiMods)
			{
				float instanceTime = _Time.y;
				float hours = instanceTime / 3600;
				float minutes = (instanceTime / 60) % 60;
				float seconds = instanceTime % 60;
				float totalCharacters = 8;
				float timeArray[8];
				timeArray[0] = floor((hours * .1) % 10) + 48;
				timeArray[1] = floor(hours % 10) + 48;
				timeArray[2] = ASCII_SEMICOLON;
				timeArray[3] = floor((minutes * .1) % 10) + 48;
				timeArray[4] = floor(minutes % 10) + 48;
				timeArray[5] = ASCII_SEMICOLON;
				timeArray[6] = floor((seconds * .1) % 10) + 48;
				timeArray[7] = floor(seconds % 10) + 48;
				
				uv = TransformUV(_TextTimeOffset, _TextTimeRotation, _TextTimeScale, uv);
				
				if (uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
				{
					return;
				}
				
				float currentCharacter = floor(uv.x * totalCharacters);
				float2 glyphPos = getAsciiCoordinate(timeArray[currentCharacter]);
				// 0.1428571 = 1/7 = 1 / totalCharacters
				float startUV = 1 / totalCharacters * currentCharacter;
				float endUV = 1 / totalCharacters * (currentCharacter + 1);
				
				fixed4 textTimePadding = _TextTimePadding;
				textTimePadding *= 1 / totalCharacters;
				
				uv = remapClamped(float2(startUV, 0), float2(endUV, 1), uv, float2(glyphPos.x + textTimePadding.x, glyphPos.y - glyphWidth + textTimePadding.y), float2(glyphPos.x + glyphWidth - textTimePadding.z, glyphPos.y - textTimePadding.w));
				
				if (uv.x > glyphPos.x + glyphWidth - textTimePadding.z - .001 || uv.x < glyphPos.x + textTimePadding.x + .001 || uv.y > glyphPos.y - textTimePadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textTimePadding.y + .001)
				{
					return;
				}
				
				float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
				float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
				float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
				sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
				float opacity = clamp(sigDist + 0.5, 0, 1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, poiThemeColor(poiMods, _TextTimeColor.rgb, _TextTimeColorThemeIndex), opacity * _TextTimeColor.a);
				globalTextEmission += poiThemeColor(poiMods, _TextTimeColor.rgb, _TextTimeColorThemeIndex) * opacity * _TextTimeEmissionStrength;
			}
			
			void ApplyFPSText(inout PoiFragData poiFragData, float2 uv, in PoiMods poiMods)
			{
				float smoothDeltaTime = clamp(unity_DeltaTime.w, 0, 999);
				float totalCharacters = 7;
				float fpsArray[7];
				fpsArray[0] = ASCII_F;
				fpsArray[1] = ASCII_P;
				fpsArray[2] = ASCII_S;
				fpsArray[3] = ASCII_SEMICOLON;
				fpsArray[4] = floor((smoothDeltaTime * .01) % 10) + 48;
				fpsArray[5] = floor((smoothDeltaTime * .1) % 10) + 48;
				fpsArray[6] = floor(smoothDeltaTime % 10) + 48;
				
				uv = TransformUV(_TextFPSOffset, _TextFPSRotation, _TextFPSScale, uv);
				
				if (uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
				{
					return;
				}
				
				float currentCharacter = floor(uv.x * totalCharacters);
				float2 glyphPos = getAsciiCoordinate(fpsArray[currentCharacter]);
				// 0.1428571 = 1/7 = 1 / totalCharacters
				float startUV = 1 / totalCharacters * currentCharacter;
				float endUV = 1 / totalCharacters * (currentCharacter + 1);
				
				float4 textFPSPadding = _TextFPSPadding;
				textFPSPadding *= 1 / totalCharacters;
				
				uv = remapClamped(float2(startUV, 0), float2(endUV, 1), uv, float2(glyphPos.x + textFPSPadding.x, glyphPos.y - glyphWidth + textFPSPadding.y), float2(glyphPos.x + glyphWidth - textFPSPadding.z, glyphPos.y - textFPSPadding.w));
				
				if (uv.x > glyphPos.x + glyphWidth - textFPSPadding.z - .001 || uv.x < glyphPos.x + textFPSPadding.x + .001 || uv.y > glyphPos.y - textFPSPadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textFPSPadding.y + .001)
				{
					return;
				}
				
				float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
				float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
				float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
				sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
				float opacity = clamp(sigDist + 0.5, 0, 1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, poiThemeColor(poiMods, _TextFPSColor.rgb, _TextFPSColorThemeIndex), opacity * _TextFPSColor.a);
				globalTextEmission += poiThemeColor(poiMods, _TextFPSColor.rgb, _TextFPSColorThemeIndex) * opacity * _TextFPSEmissionStrength;
			}
			
			void ApplyNumericText(inout PoiFragData poiFragData, float2 uv, in PoiMods poiMods)
			{
				// If both digits are set to zero: exit.
				if (_TextNumericWholeDigits == 0 && _TextNumericDecimalDigits == 0)
				{
					return;
				}
				
				uint wholeNumber = 0;
				uint decimalNumber = 0;
				uint wholeDigits = _TextNumericWholeDigits;
				uint decimalDigits = _TextNumericDecimalDigits;
				float NumericArray[10];										// 10 is the max amount of characters = 1 sign + 4 max whole digits + 1 decimal mark + 4 max decimal digits
				uint arrayIndex = 0;
				float totalCharacters = 1 + wholeDigits + decimalDigits; 	// Sign Character + Whole Digits + Decimal Digits
				
				//Determine Sign (_TextNumericValue is usually animated)
				float charSign = _TextNumericValue >= 0 ? ASCII_SPACE : ASCII_NEGATIVE;
				
				NumericArray[arrayIndex] = charSign;						//First character is always the sign
				arrayIndex++;
				
				//Isolate whole number and fill array
				if (wholeDigits > 0)
				{
					wholeNumber = uint(glsl_mod(abs(_TextNumericValue), pow(10, wholeDigits)));
					
					int expIndex = -1 * (wholeDigits - 1);  // Exponent Index
					bool leadingZero = true;
					// Pouplate the Array
					while (arrayIndex <= wholeDigits)
					{
						// Grab the corresponding digit from the whole number going from left to right.
						int digit = floor(glsl_mod(wholeNumber * pow(10, expIndex), 10));
						// Take the resulting value and add 48 to get the corresponding location in the font array.
						NumericArray[arrayIndex] = digit + 48;
						
						//Trim Leading Zeroes, but leave at least one.
						if (_TextNumericTrimZeroes == true)
						{
							//If the digit is zero and there hasn't been any digits greater than 0 previously.
							if (digit == 0 && leadingZero == true && arrayIndex != wholeDigits)
							{
								//Overwrite the leading zero.
								NumericArray[arrayIndex] = ASCII_SPACE;
							}
							else
							{
								leadingZero = false;
							}
						}
						expIndex++;
						arrayIndex++;
					}
				}
				
				// Isolate decimal number and fill array
				if (decimalDigits > 0)
				{
					// Add a decimal point
					NumericArray[arrayIndex] = ASCII_PERIOD;
					int decimalPointer = arrayIndex;
					arrayIndex++;
					totalCharacters++;
					
					decimalNumber = uint(frac(abs(_TextNumericValue)) * pow(10.00001, decimalDigits));    // Isolate the decimal number
					
					int expIndex = -1 * (decimalDigits - 1);                                          // Exponent Index
					//Populate the Array with the remaining digits
					while (arrayIndex < (uint)(totalCharacters))
					{
						// Grab the corresponding digit from the whole number going from left to right.
						int digit = floor(glsl_mod(decimalNumber * pow(10, expIndex), 10));
						// Take the resulting value and add 48 to get the corresponding location in the font array.
						NumericArray[arrayIndex] = digit + 48;
						
						expIndex++;
						arrayIndex++;
					}
				}
				
				uv = TransformUV(_TextNumericOffset, _TextNumericRotation, _TextNumericScale, uv);
				
				if (uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
				{
					return;
				}
				
				float currentCharacter = floor(uv.x * totalCharacters);
				float2 glyphPos = getAsciiCoordinate(NumericArray[currentCharacter]);
				float startUV = 1 / totalCharacters * currentCharacter;
				float endUV = 1 / totalCharacters * (currentCharacter + 1);
				
				float4 textNumericPadding = _TextNumericPadding;
				textNumericPadding *= 1 / totalCharacters;
				
				uv = remapClamped(float2(startUV, 0), float2(endUV, 1), uv, float2(glyphPos.x + textNumericPadding.x, glyphPos.y - glyphWidth + textNumericPadding.y), float2(glyphPos.x + glyphWidth - textNumericPadding.z, glyphPos.y - textNumericPadding.w));
				
				if (uv.x > glyphPos.x + glyphWidth - textNumericPadding.z - .001 || uv.x < glyphPos.x + textNumericPadding.x + .001 || uv.y > glyphPos.y - textNumericPadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textNumericPadding.y + .001)
				{
					return;
				}
				
				float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
				float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
				float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
				sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
				float opacity = clamp(sigDist + 0.5, 0, 1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, poiThemeColor(poiMods, _TextNumericColor.rgb, _TextNumericColorThemeIndex), opacity * _TextNumericColor.a);
				globalTextEmission += poiThemeColor(poiMods, _TextNumericColor.rgb, _TextNumericColorThemeIndex) * opacity * _TextNumericEmissionStrength;
			}
			
			void ApplyTextOverlayColor(inout PoiFragData poiFragData, PoiMesh poiMesh, in PoiMods poiMods)
			{
				globalTextEmission = 0;
				float positionalOpacity = 0;
				
				if (_TextFPSEnabled == 1)
				ApplyFPSText(poiFragData, poiMesh.uv[_TextFPSUV], poiMods);
				if (_TextPositionEnabled == 1)
				ApplyPositionText(poiFragData, poiMesh.uv[_TextPositionUV], poiMods);
				if (_TextTimeEnabled == 1)
				ApplyTimeText(poiFragData, poiMesh.uv[_TextTimeUV], poiMods);
				if (_TextNumericEnabled == 1)
				ApplyNumericText(poiFragData, poiMesh.uv[_TextNumericUV], poiMods);
				
				poiFragData.emission += globalTextEmission;
			}
			#endif
			//endex
			
			//ifex _PostProcess==0
			#ifdef POSTPROCESS
			float3 poiPosterize(float3 color, float steps)
			{
				float3 newColor = RGBtoHSV(color);
				steps = floor(steps);
				newColor.r = floor(newColor.r * steps) / steps;
				newColor.g = floor(newColor.g * steps) / steps;
				newColor.b = floor(newColor.b * steps) / steps;
				return HSVtoRGB(newColor);
			}
			
			float oetf_sRGB_scalar(float L)
			{
				float V = 1.055 * (pow(L, 1.0 / 2.4)) - 0.055;
				if (L <= 0.0031308)
				V = L * 12.92;
				return V;
			}
			
			float3 oetf_sRGB(float3 L)
			{
				return float3(oetf_sRGB_scalar(L.r), oetf_sRGB_scalar(L.g), oetf_sRGB_scalar(L.b));
			}
			
			float eotf_sRGB_scalar(float V)
			{
				float L = pow((V + 0.055) / 1.055, 2.4);
				if (V <= oetf_sRGB_scalar(0.0031308))
				L = V / 12.92;
				return L;
			}
			
			float3 GetHDR(float3 rgb)
			{
				return float3(eotf_sRGB_scalar(rgb.r), eotf_sRGB_scalar(rgb.g), eotf_sRGB_scalar(rgb.b));
			}
			
			float3 GetContrast(float3 col, float contrast)
			{
				return lerp(float3(0.5, 0.5, 0.5), col, contrast);
			}
			
			float3 GetSaturation(float3 col, float interpolator)
			{
				return lerp(dot(col, float3(0.3, 0.59, 0.11)), col, interpolator);
			}
			
			void applyPostProcessing(inout PoiFragData poiFragData, in PoiMesh poiMesh)
			{
				float3 col = poiFragData.finalColor;
				col = hueShift(col, _PPHue);
				col *= _PPTint;
				col *= _PPRGB;
				col = GetSaturation(col, _PPSaturation);
				col = lerp(col, GetHDR(col), _PPHDR);
				col = GetContrast(col, _PPContrast);
				col *= _PPBrightness;
				col += _PPLightness;
				
				float ppMask = 1;
				#if defined(PROP_PPMASK) || !defined(OPTIMIZER_ENABLED)
				ppMask = POI2D_SAMPLER_PAN(_PPMask, _MainTex, poiUV(poiMesh.uv[_PPMaskUV], _PPMask_ST), _PPMaskPan)[_PPMaskChannel];
				ppMask = lerp(ppMask, 1 - ppMask, _PPMaskInvert);
				col = lerp(poiFragData.finalColor, col, ppMask);
				#endif
				
				if (_PPPosterization)
				{
					col = lerp(col, poiPosterize(col, _PPPosterizationAmount), ppMask);
				}
				
				poiFragData.finalColor = col;
			}
			#endif
			//endex
			
			// normal correct code from https://github.com/yoship1639/UniToon (MIT)
			//ifex _NormalCorrect==0
			#ifdef POI_NORMALCORRECT
			void applyNormalCorrect(inout VertexOut i)
			{
				float3 normalCorrectObject = i.localPos.xyz - _NormalCorrectOrigin;
				normalCorrectObject.y = 0;
				normalCorrectObject = normalize(normalCorrectObject);
				float3 normalCorrectWorld = UnityObjectToWorldDir(normalCorrectObject);
				i.normal.xyz = normalize(lerp(i.normal.xyz, normalCorrectWorld, _NormalCorrectAmount));
				//i.objNormal.xyz = normalize(lerp(i.objNormal.xyz, normalCorrectObject, _NormalCorrectAmount));
			}
			#endif
			//endex
			
			//ifex _VideoEffectsEnable==0
			#ifdef POI_VIDEO_EFFECTS
			float3 applyBacklight(float3 videoTexture, half backlightStrength)
			{
				return max(backlightStrength, videoTexture.rgb);
			}
			
			float3 applyViewAngleTN(float3 videoTexture, PoiCam poiCam, PoiMesh poiMesh)
			{
				float3 reflectionVector = normalize(reflect(poiCam.viewDir.rgb, poiMesh.normals[1].rgb));
				float upwardShift = dot(reflectionVector, poiMesh.binormal[0]);
				upwardShift = pow(upwardShift, 1);
				float sideShift = dot(reflectionVector, poiMesh.tangent[0]);
				sideShift *= pow(sideShift, 3);
				#if !UNITY_COLORSPACE_GAMMA
				videoTexture = LinearToGammaSpace(videoTexture);
				#endif
				videoTexture = saturate(lerp(half3(0.5, 0.5, 0.5), videoTexture, upwardShift + 1));
				#if !UNITY_COLORSPACE_GAMMA
				videoTexture = GammaToLinearSpace(videoTexture);
				#endif
				videoTexture = (lerp(videoTexture, videoTexture.gbr, sideShift));
				return videoTexture;
			}
			
			float calculateCRTPixelBrightness(float2 uv)
			{
				float totalPixels = _VideoResolution.x * _VideoResolution.y;
				float2 uvPixel = float2((floor((1 - uv.y) * _VideoResolution.y)) / _VideoResolution.y, (floor(uv.x * _VideoResolution.x)) / _VideoResolution.x);
				float currentPixelNumber = _VideoResolution.x * (_VideoResolution.y * uvPixel.x) + _VideoResolution.y * uvPixel.y;
				float currentPixelAlpha = currentPixelNumber / totalPixels;
				half electronBeamAlpha = frac(_Time.y * _VideoCRTRefreshRate);
				float electronBeamPixelNumber = totalPixels * electronBeamAlpha;
				
				float DistanceInPixelsFromCurrentElectronBeamPixel = 0;
				if (electronBeamPixelNumber >= currentPixelNumber)
				{
					DistanceInPixelsFromCurrentElectronBeamPixel = electronBeamPixelNumber - currentPixelNumber;
				}
				else
				{
					DistanceInPixelsFromCurrentElectronBeamPixel = electronBeamPixelNumber + (totalPixels - currentPixelNumber);
				}
				float CRTFrameTime = 1 / _VideoCRTRefreshRate;
				float timeSincecurrentPixelWasHitByElectronBeam = (DistanceInPixelsFromCurrentElectronBeamPixel / totalPixels);
				
				return saturate(_VideoCRTPixelEnergizedTime - timeSincecurrentPixelWasHitByElectronBeam);
			}
			
			void applyContrastSettings(inout float3 pixel)
			{
				#if !UNITY_COLORSPACE_GAMMA
				pixel = LinearToGammaSpace(pixel);
				#endif
				pixel = saturate(lerp(half3(0.5, 0.5, 0.5), pixel, _VideoContrast + 1));
				#if !UNITY_COLORSPACE_GAMMA
				pixel = GammaToLinearSpace(pixel);
				#endif
			}
			
			void applySaturationSettings(inout float3 pixel)
			{
				pixel = lerp(pixel.rgb, dot(pixel.rgb, float3(0.3, 0.59, 0.11)), - (_VideoSaturation));
			}
			
			void applyVideoSettings(inout float3 pixel)
			{
				applySaturationSettings(pixel);
				applyContrastSettings(pixel);
			}
			
			void calculateLCD(inout float4 videoTexture, float3 pixels)
			{
				videoTexture.rgb = applyBacklight(videoTexture, _VideoBacklight * .01);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateTN(inout float4 videoTexture, float3 pixels, PoiCam poiCam, PoiMesh poiMesh)
			{
				videoTexture.rgb = applyBacklight(videoTexture, _VideoBacklight * .01);
				videoTexture.rgb = applyViewAngleTN(videoTexture, poiCam, poiMesh);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateCRT(inout float4 videoTexture, float3 pixels, float2 uv)
			{
				float brightness = calculateCRTPixelBrightness(uv);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * brightness * _VideoBacklight;
			}
			void calculateOLED(inout float4 videoTexture, float3 pixels)
			{
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateGameboy(inout float4 videoTexture)
			{
				applyVideoSettings(videoTexture.rgb);
				// half brightness = saturate((videoTexture.r + videoTexture.g + videoTexture.b) * .3333333);
				half brightness = LinearRgbToLuminance(LinearToGammaSpace(videoTexture.rgb));
				#if defined(PROP_VIDEOGAMEBOYRAMP) || !defined(OPTIMIZER_ENABLED)
				videoTexture.rgb = tex2Dlod(_VideoGameboyRamp, float4(brightness.xx, 0, 0));
				#else
				float3 dg = float3(0.00392156863, 0.0392156863, 0.00392156863);
				float3 lg = float3(0.333333333, 0.5, 0.00392156863);
				videoTexture.rgb = lerp(dg, lg, brightness);
				#endif
			}
			void calculateProjector(inout float4 videoTexture)
			{
				applyVideoSettings(videoTexture.rgb);
				
				float3 projectorColor = videoTexture * _VideoBacklight;
				videoTexture.r = clamp(projectorColor.r, videoTexture.r, 1000);
				videoTexture.g = clamp(projectorColor.g, videoTexture.g, 1000);
				videoTexture.b = clamp(projectorColor.b, videoTexture.b, 1000);
			}
			
			void applyVideoEffectsMainTex(inout float4 mainTexture, in PoiMesh poiMesh)
			{
				float2 uvs = poiMesh.uv[_MainTexUV];
				if (_VideoPixelateToResolution)
				{
					float2 originalUVs = uvs;
					uvs = sharpSample(float4(1 / _VideoResolution.xy, _VideoResolution.xy), uvs);
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
					mainTexture = _MainTex.SampleGrad(sampler_MainTex, uvs, ddx(originalUVs), ddy(originalUVs));
				}
			}
			void applyVideoEffects(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, in PoiLight poiLight, in PoiMods poiMods)
			{
				#if defined(PROP_VIDEOPIXELTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float3 pixels = tex2D(_VideoPixelTexture, poiUV(poiMesh.uv[_VideoPixelTextureUV], _VideoPixelTexture_ST) * _VideoResolution);
				#else
				float3 pixels = 1;
				#endif
				float2 uvs = poiMesh.uv[_MainTexUV];
				if (_VideoPixelateToResolution)
				{
					uvs = sharpSample(float4(1 / _VideoResolution.xy, _VideoResolution.xy), uvs);
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
				}
				else
				{
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
				}
				float4 modifiedVideoTexture = 0;
				modifiedVideoTexture.rgb = poiFragData.baseColor;
				modifiedVideoTexture.a = poiFragData.alpha;
				
				// UNITY_BRANCH
				// if(_VideoRepeatVideoTexture == 1)
				// {
				// 	if(poiMesh.uv[_VideoUVNumber].x > 1 || poiMesh.uv[_VideoUVNumber].x < 0 || poiMesh.uv[_VideoUVNumber].y > 1 || poiMesh.uv[_VideoUVNumber].y < 0)
				// 	{
				// 		return;
				// 	}
				// }
				
				switch(_VideoType)
				{
					case 0: // LCD
					
					{
						calculateLCD(modifiedVideoTexture, pixels);
						break;
					}
					case 1: // TN
					
					{
						calculateTN(modifiedVideoTexture, pixels, poiCam, poiMesh);
						break;
					}
					case 2: // CRT
					
					{
						calculateCRT(modifiedVideoTexture, pixels, uvs);
						break;
					}
					case 3: // OLED
					
					{
						calculateOLED(modifiedVideoTexture, pixels);
						break;
					}
					case 4: // Gameboy
					
					{
						calculateGameboy(modifiedVideoTexture);
						break;
					}
					case 5: // Projector
					
					{
						calculateProjector(modifiedVideoTexture);
						break;
					}
				}
				#if defined(PROP_VIDEOMASKTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float screenMask = POI2D_SAMPLER_PAN(_VideoMaskTexture, _MainTex, poiUV(poiMesh.uv[_VideoMaskTextureUV], _VideoMaskTexture_ST), _VideoMaskTexturePan)[_VideoMaskTextureChannel];
				#else
				float screenMask = 1;
				#endif
				
				poiFragData.baseColor = lerp(poiFragData.baseColor, modifiedVideoTexture, screenMask);
				// UNITY_BRANCH
				if (_VideoEmissionEnabled)
				{
					poiFragData.emission += modifiedVideoTexture.rgb * screenMask;
				}
			}
			#endif
			//endex
			
			//ifex _BacklightEnabled!=1
			#ifdef POI_BACKLIGHT
			void ApplyBacklight(inout PoiFragData poiFragData, in PoiMesh poiMesh, inout PoiLight poiLight, in PoiCam poiCam, inout PoiMods poiMods)
			{
				
				// Color
				float3 backlightColor = _BacklightColor.rgb;
				#if defined(PROP_BACKLIGHTCOLORTEX) || !defined(OPTIMIZER_ENABLED)
				backlightColor *= POI2D_SAMPLER_PAN(_BacklightColorTex, _MainTex, poiUV(poiMesh.uv[_BacklightColorTexUV], _BacklightColorTex_ST), _BacklightColorTexPan).rgb;
				#endif
				
				float3 normal = lerp(poiMesh.normals[0], poiMesh.normals[1], _BacklightNormalStrength);
				// Factor
				float3 headDir = normalize(getCameraPosition() - poiMesh.worldPos.xyz);
				float headDotLight = dot(headDir, poiLight.direction);
				float backlightFactor = pow(saturate(-headDotLight * 0.5 + 0.5), max(0, _BacklightDirectivity));
				float backlightLN = dot(normalize(-headDir * _BacklightViewStrength + poiLight.direction), normal) * 0.5 + 0.5;
				#if defined(POINT) || defined(SPOT)
				if (_BacklightReceiveShadow) backlightLN *= saturate(poiLight.additiveShadow);
				#else
				if (_BacklightReceiveShadow) backlightLN *= saturate(poiLight.attenuation);
				#endif
				backlightLN = poiEdgeLinear(backlightLN, _BacklightBorder, _BacklightBlur);
				float backlight = saturate(backlightFactor * backlightLN);
				backlight = !poiMesh.isFrontFace && _BacklightBackfaceMask ? 0.0 : backlight;
				
				// Blend
				backlightColor = lerp(backlightColor, backlightColor * poiFragData.baseColor, _BacklightMainStrength);
				poiLight.finalLightAdd += backlight * backlightColor * poiLight.directColor;
			}
			#endif
			//endex
			
			//ifex _VoronoiEnabled!=1
			#ifdef POI_VORONOI
			//1/7
			#define VoronoiK 0.142857142857
			//3/7
			#define VoronoiKo 0.428571428571
			// Permutation polynomial: (34x^2 + x) mod 289
			float3 Permutation(float3 x)
			{
				return glsl_mod((34.0 * x + 1.0) * x, 289.0);
			}
			
			float3 inoise(float3 P, float jitter, out float3 randomPoint)
			{
				P *= 0.7f; // Scale adjustment
				float3 Pi = glsl_mod(floor(P), 289.0);
				float3 Pf = frac(P);
				float3 oi = float3(-1.0, 0.0, 1.0);
				float3 of = float3(-0.5, 0.5, 1.5);
				float3 px = Permutation(Pi.x + oi);
				float3 py = Permutation(Pi.y + oi);
				float3 pz = Permutation(Pi.z + oi);
				
				float3 p, ox, oy, oz, dx, dy, dz;
				float3 F = 1e6;
				
				[unroll(3)]
				for (int i = 0; i < 3; i++)
				{
					[unroll(3)]
					for (int j = 0; j < 3; j++)
					{
						[unroll(3)]
						for (int k = 0; k < 3; k++)
						{
							p = Permutation(px[i] + py[j] + pz[k] + oi); // pij1, pij2, pij3
							float3 ogp = p;
							
							ox = frac(p * VoronoiK) - VoronoiKo;
							oy = glsl_mod(floor(p * VoronoiK), 7.0) * VoronoiK - VoronoiKo;
							
							p = Permutation(p);
							oz = frac(p * VoronoiK) - VoronoiKo;
							
							dx = Pf.x - of[i] + jitter * ox;
							dy = Pf.y - of[j] + jitter * oy;
							dz = Pf.z - of[k] + jitter * oz;
							
							float3 d = dx * dx + dy * dy + dz * dz; // dij1, dij2 and dij3, squared
							
							//Find lowest and second lowest distances
							for (int n = 0; n < 3; n++)
							{
								if (d[n] < F[0])
								{
									F[1] = F[0];
									F[0] = d[n];
									randomPoint = p;
								}
								else if (d[n] < F[1])
								{
									F[1] = d[n];
								}
							}
						}
					}
				}
				
				return F;
			}
			
			float voronoi2D(in float2 x, float scale, float2 speed, out float2 randomPoint)
			{
				x *= scale;
				x += speed * _Time.x;
				float2 n = floor(x);
				float2 f = frac(x);
				
				// first pass: regular voronoi
				float2 mg, mr;
				float md = 8.0;
				for (int j = -1; j <= 1; j++)
				{
					for (int i = -1; i <= 1; i++)
					{
						float2 g = float2(float(i), float(j));
						float2 o = random2(n + g);
						float2 currentPoint = o;
						
						float2 r = g + o - f;
						float d = dot(r, r);
						
						if (d < md)
						{
							md = d;
							mr = r;
							mg = g;
							randomPoint.xy = currentPoint;
						}
					}
				}
				
				// second pass: distance to borders
				md = 8.0;
				for (int r = -2; r <= 2; r++)
				{
					for (int q = -2; q <= 2; q++)
					{
						float2 g = mg + float2(float(q), float(r));
						float2 o = random2(n + g);
						
						float2 r = g + o - f;
						
						if (dot(mr - r, mr - r) > 0.00001)
						{
							md = min(md, dot(0.5 * (mr + r), normalize(r - mr)));
						}
					}
				}
				return md;
			}
			
			float voronoi3D(in float3 x, float scale, float3 speed, out float3 randomPoint)
			{
				x *= scale;
				x += speed * _Time.x;
				float3 n = floor(x);
				float3 f = frac(x);
				
				// first pass: regular voronoi
				float3 mg, mr;
				float md = 8.0;
				for (int j = -1; j <= 1; j++)
				{
					for (int i = -1; i <= 1; i++)
					{
						for (int h = -1; h <= 1; h++)
						{
							float3 g = float3(float(h), float(i), float(j));
							float3 o = random3(n + g);
							float3 currentPoint = o;
							
							float3 r = g + o - f;
							float d = dot(r, r);
							
							if (d < md)
							{
								md = d;
								mr = r;
								mg = g;
								randomPoint = currentPoint;
							}
						}
					}
				}
				
				// second pass: distance to borders
				md = 8.0;
				for (int r = -2; r <= 2; r++)
				{
					for (int q = -2; q <= 2; q++)
					{
						for (int p = -2; p <= 2; p++)
						{
							float3 g = mg + float3(float(p), float(q), float(r));
							float3 o = random3(n + g);
							
							float3 r = g + o - f;
							
							if (dot(mr - r, mr - r) > 0.00001)
							{
								md = min(md, dot(0.5 * (mr + r), normalize(r - mr)));
							}
						}
					}
				}
				return md;
			}
			
			// fracal sum, range -1.0 - 1.0
			float VoronoiNoise_Octaves(float3 p, float scale, float3 speed, int octaveNumber, float octaveScale, float octaveAttenuation, float jitter, float time, out float3 randomPoint)
			{
				float freq = scale;
				float weight = 1.0f;
				float sum = 0;
				// Uncomment when the octave stuff is actually used
				// for (int i = 0; i < octaveNumber; i ++)
				// {
				float3 F = inoise(p * freq + time * speed, jitter, randomPoint) * weight;
				
				sum += sqrt(F[0]);
				
				// 	freq *= octaveScale;
				// 	weight *= 1.0f - octaveAttenuation;
				// }
				return sum;
			}
			
			float VoronoiNoiseDiff_Octaves(float3 p, float scale, float3 speed, int octaveNumber, float octaveScale, float octaveAttenuation, float jitter, float time, out float3 randomPoint)
			{
				float freq = scale;
				float weight = 1.0f;
				float sum = 0;
				// Uncomment when the octave stuff is actually used
				// for (int i = 0; i < octaveNumber; i ++)
				// {
				float3 F = inoise(p * freq + time * speed, jitter, randomPoint) * weight;
				
				sum += sqrt(F[1]) - sqrt(F[0]);
				
				// freq *= octaveScale;
				// weight *= 1.0f - octaveAttenuation;
				// }
				return sum;
			}
			
			void ApplyVoronoi(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float voronoiOctaveNumber = 1;
				float voronoiOctaveScale = 1;
				float voronoiOctaveAttenuation = 1;
				float3 randomPoint = 0;
				
				float voronoi = 0;
				
				float3 position = 0;
				
				UNITY_BRANCH
				if (_VoronoiSpace == 0)
				{
					position = poiMesh.localPos;
				}
				UNITY_BRANCH
				if (_VoronoiSpace == 1)
				{
					position = poiMesh.worldPos;
				}
				UNITY_BRANCH
				if (_VoronoiSpace == 2)
				{
					position = float3(poiMesh.uv[0].x, poiMesh.uv[0].y, 0);
				}
				#if defined(PROP_VORONOIMASK) || !defined(OPTIMIZER_ENABLED)
				float mask = POI2D_SAMPLER_PAN(_VoronoiMask, _MainTex, poiUV(poiMesh.uv[_VoronoiMaskUV], _VoronoiMask_ST), _VoronoiMaskPan)[_VoronoiMaskChannel];
				#else
				float mask = 1;
				#endif
				
				if (_VoronoiGlobalMask > 0)
				{
					mask = maskBlend(mask, poiMods.globalMask[_VoronoiGlobalMask - 1], _VoronoiGlobalMaskBlendType);
				}
				
				#if defined(PROP_VORONOINOISE) || !defined(OPTIMIZER_ENABLED)
				float edgeNoise = POI2D_SAMPLER_PAN(_VoronoiNoise, _MainTex, poiUV(poiMesh.uv[_VoronoiNoiseUV], _VoronoiNoise_ST), _VoronoiNoisePan)[_VoronoiNoiseChannel];
				#else
				float edgeNoise = 0;
				#endif
				edgeNoise *= _VoronoiNoiseIntensity;
				
				float3 voronoiSpeed = _VoronoiSpeed * 10;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					position.x += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedXType, _AudioLinkVoronoiChronoSpeedXBand) * _AudioLinkVoronoiChronoSpeedXSpeed * 0.01;
					position.y += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedYType, _AudioLinkVoronoiChronoSpeedYBand) * _AudioLinkVoronoiChronoSpeedYSpeed * 0.01;
					position.z += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedZType, _AudioLinkVoronoiChronoSpeedZBand) * _AudioLinkVoronoiChronoSpeedZSpeed * 0.01;
				}
				#endif
				
				if (_VoronoiType == 0) // Basic
				
				{
					voronoi = voronoi2D(position.xy, _VoronoiScale, voronoiSpeed, randomPoint.xy);
					voronoi *= 1.55; // Range adjustment
					
				}
				if (_VoronoiType == 1) // Diff
				
				{
					voronoi = VoronoiNoiseDiff_Octaves(position, _VoronoiScale, voronoiSpeed, voronoiOctaveNumber, voronoiOctaveScale, voronoiOctaveAttenuation, 1, _Time.x, randomPoint);
				}
				if (_VoronoiType == 2) // Fixed Border
				
				{
					voronoi = voronoi3D(position, _VoronoiScale, voronoiSpeed, randomPoint);
					voronoi *= 1.8; // Range adjustment
					
				}
				
				float4 outerColor = _VoronoiOuterColor;
				float4 innerColor = _VoronoiInnerColor;
				
				if (_VoronoiEnableRandomCellColor == 1)
				{
					float3 rando = random3(randomPoint);
					fixed hue = rando.x;
					fixed saturation = lerp(_VoronoiRandomMinMaxSaturation.x, _VoronoiRandomMinMaxSaturation.y, rando.y);
					fixed value = lerp(_VoronoiRandomMinMaxBrightness.x, _VoronoiRandomMinMaxBrightness.y, rando.z);
					float3 hsv = float3(hue, saturation, value);
					innerColor.rgb = HSVtoRGB(hsv);
				}
				voronoi = pow(voronoi, _VoronoiPower);
				float2 voronoiGradient = _VoronoiGradient.xy + edgeNoise;
				#ifdef POI_AUDIOLINK
				voronoiGradient.x += _AudioLinkVoronoiGradientMinAdd * poiMods.audioLink[_AudioLinkVoronoiGradientMinAddBand];
				voronoiGradient.y -= _AudioLinkVoronoiGradientMaxAdd * poiMods.audioLink[_AudioLinkVoronoiGradientMaxAddBand];
				#endif
				float ramp = smoothstep(voronoiGradient.x, voronoiGradient.y, voronoi);
				
				if (_VoronoiBlend == 0)
				{
					float4 voronoiColor = lerp(outerColor, innerColor, ramp);
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, voronoiColor, min(mask * voronoiColor.a, 0.99999));
					if (_VoronoiAffectsMaterialAlpha)
					{
						poiFragData.alpha = lerp(poiFragData.alpha, voronoiColor.a, min(mask, 0.99999));
					}
				}
				float outerEmissionStrength = _VoronoiOuterEmissionStrength;
				float innerEmissionStrength = _VoronoiInnerEmissionStrength;
				#ifdef POI_AUDIOLINK
				outerEmissionStrength += lerp(_AudioLinkVoronoiOuterEmission.x, _AudioLinkVoronoiOuterEmission.y, poiMods.audioLink[_AudioLinkVoronoiOuterEmissionBand]);
				innerEmissionStrength += lerp(_AudioLinkVoronoiInnerEmission.x, _AudioLinkVoronoiInnerEmission.y, poiMods.audioLink[_AudioLinkVoronoiInnerEmissionBand]);
				#endif
				float4 voronoiEmissionColor = lerp(outerColor, innerColor, ramp);
				voronoiEmissionColor.rgb *= lerp(outerEmissionStrength, innerEmissionStrength, ramp);
				poiFragData.emission += voronoiEmissionColor.rgb * mask * voronoiEmissionColor.a;
			}
			#endif
			//endex
			
			float4 frag(VertexOut i, uint facing : SV_IsFrontFace) : SV_Target
			{
				UNITY_SETUP_INSTANCE_ID(i);
				UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
				
				PoiMesh poiMesh;
				PoiInitStruct(PoiMesh, poiMesh);
				
				PoiLight poiLight;
				PoiInitStruct(PoiLight, poiLight);
				
				PoiVertexLights poiVertexLights;
				PoiInitStruct(PoiVertexLights, poiVertexLights);
				
				PoiCam poiCam;
				PoiInitStruct(PoiCam, poiCam);
				
				PoiMods poiMods;
				PoiInitStruct(PoiMods, poiMods);
				poiMods.globalEmission = 1;
				
				PoiFragData poiFragData;
				poiFragData.smoothness = 1;
				poiFragData.smoothness2 = 1;
				poiFragData.metallic = 1;
				poiFragData.specularMask = 1;
				poiFragData.reflectionMask = 1;
				poiFragData.emission = 0;
				poiFragData.baseColor = float3(0, 0, 0);
				poiFragData.finalColor = float3(0, 0, 0);
				poiFragData.alpha = 1;
				poiFragData.toggleVertexLights = 0;
				
				#ifdef POI_UDIMDISCARD
				applyUDIMDiscard(i);
				#endif
				
				//ifex _NormalCorrect==0
				#ifdef POI_NORMALCORRECT
				applyNormalCorrect(i);
				#endif
				//endex
				
				// Mesh Data
				//poiMesh.objectPosition = mul(unity_ObjectToWorld, float3(0, 0, 0)).xyz;
				poiMesh.objectPosition = mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
				poiMesh.objNormal = mul(unity_WorldToObject, i.normal);
				poiMesh.normals[0] = i.normal;
				poiMesh.tangent[0] = i.tangent.xyz;
				poiMesh.binormal[0] = cross(i.normal, i.tangent.xyz) * (i.tangent.w * unity_WorldTransformParams.w);
				poiMesh.worldPos = i.worldPos.xyz;
				poiMesh.localPos = i.localPos.xyz;
				poiMesh.vertexColor = i.vertexColor;
				poiMesh.isFrontFace = facing;
				poiMesh.dx = ddx(poiMesh.uv[0]);
				poiMesh.dy = ddy(poiMesh.uv[0]);
				
				#ifndef POI_PASS_OUTLINE
				if (!poiMesh.isFrontFace && _FlipBackfaceNormals)
				{
					poiMesh.normals[0] *= -1;
					poiMesh.tangent[0] *= -1;
					poiMesh.binormal[0] *= -1;
				}
				#endif
				
				poiCam.viewDir = !IsOrthographicCamera() ? normalize(_WorldSpaceCameraPos - i.worldPos.xyz) : normalize(UNITY_MATRIX_I_V._m02_m12_m22);
				float3 tanToWorld0 = float3(poiMesh.tangent[0].x, poiMesh.binormal[0].x, poiMesh.normals[0].x);
				float3 tanToWorld1 = float3(poiMesh.tangent[0].y, poiMesh.binormal[0].y, poiMesh.normals[0].y);
				float3 tanToWorld2 = float3(poiMesh.tangent[0].z, poiMesh.binormal[0].z, poiMesh.normals[0].z);
				float3 ase_tanViewDir = tanToWorld0 * poiCam.viewDir.x + tanToWorld1 * poiCam.viewDir.y + tanToWorld2 * poiCam.viewDir.z;
				poiCam.tangentViewDir = normalize(ase_tanViewDir);
				
				// 0-3 UV0-UV3
				// 4 Panosphere UV
				// 5 world pos xz
				// 6 Polar UV
				// 6 Distorted UV
				#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
				poiMesh.lightmapUV = i.lightmapUV;
				#endif
				poiMesh.parallaxUV = poiCam.tangentViewDir.xy / max(poiCam.tangentViewDir.z, 0.0001);
				poiMesh.uv[0] = i.uv[0].xy;
				poiMesh.uv[1] = i.uv[0].zw;
				poiMesh.uv[2] = i.uv[1].xy;
				poiMesh.uv[3] = i.uv[1].zw;
				poiMesh.uv[4] = poiMesh.uv[0];
				poiMesh.uv[5] = poiMesh.uv[0];
				poiMesh.uv[6] = poiMesh.uv[0];
				poiMesh.uv[7] = poiMesh.uv[0];
				poiMesh.uv[8] = poiMesh.uv[0];
				
				poiMesh.uv[4] = calculatePanosphereUV(poiMesh);
				poiMesh.uv[5] = calculateWorldUV(poiMesh);
				poiMesh.uv[6] = calculatePolarCoordinate(poiMesh);
				poiMesh.uv[8] = calculatelocalUV(poiMesh);
				//ifex _EnableDistortion==0
				#ifdef USER_LUT
				poiMesh.uv[7] = distortedUV(poiMesh);
				#endif
				//endex
				/*
				half3 worldViewUp = normalize(half3(0, 1, 0) - poiCam.viewDir * dot(poiCam.viewDir, half3(0, 1, 0)));
				half3 worldViewRight = normalize(cross(poiCam.viewDir, worldViewUp));
				poiMesh[8] = half2(dot(worldViewRight, poiMesh.normals[_MatcapNormal]), dot(worldViewUp, poiMesh.normals[_MatcapNormal])) * _MatcapBorder + 0.5;
				*/
				
				//ifex _PoiParallax==0
				#ifdef POI_PARALLAX
				#ifndef POI_PASS_OUTLINE
				//return frac(i.tangentViewDir.x);
				//return float4(i.binormal.xyz,1);
				applyParallax(poiMesh, poiLight, poiCam);
				#endif
				#endif
				//endex
				
				poiMods.globalMask[0] = 1;
				poiMods.globalMask[1] = 1;
				poiMods.globalMask[2] = 1;
				poiMods.globalMask[3] = 1;
				poiMods.globalMask[4] = 1;
				poiMods.globalMask[5] = 1;
				poiMods.globalMask[6] = 1;
				poiMods.globalMask[7] = 1;
				poiMods.globalMask[8] = 1;
				poiMods.globalMask[9] = 1;
				poiMods.globalMask[10] = 1;
				poiMods.globalMask[11] = 1;
				poiMods.globalMask[12] = 1;
				poiMods.globalMask[13] = 1;
				poiMods.globalMask[14] = 1;
				poiMods.globalMask[15] = 1;
				//ifex _GlobalMaskTexturesEnable==0
				#ifdef POI_GLOBALMASK_TEXTURES
				ApplyGlobalMaskTextures(poiMesh, poiMods);
				#endif
				//endex
				//ifex _GlobalMaskVertexColorRed==0 && _GlobalMaskVertexColorGreen==0 && _GlobalMaskVertexColorBlue==0 && _GlobalMaskVertexColorAlpha==0
				ApplyGlobalMaskVertexColors(poiMesh, poiMods);
				//endex
				ApplyGlobalMaskModifiers(poiMesh, poiMods, poiCam);
				//ifex _GlobalMaskOptionsEnable==0
				if (_GlobalMaskOptionsEnable)
				{
					ApplyGlobalMaskOptions(poiMods);
				}
				//endex
				
				float2 mainUV = poiUV(poiMesh.uv[_MainTexUV].xy, _MainTex_ST);
				
				if (_MainPixelMode)
				{
					mainUV = sharpSample(_MainTex_TexelSize, mainUV);
				}
				
				float4 mainTexture = POI2D_SAMPLER_PAN_STOCHASTIC(_MainTex, _MainTex, mainUV, _MainTexPan, _MainTexStochastic);
				
				//ifex _VideoEffectsEnable==0
				#ifdef POI_VIDEO_EFFECTS
				if (_VideoEffectsEnable)
				{
					applyVideoEffectsMainTex(mainTexture, poiMesh);
				}
				#endif
				//endex
				
				#if defined(PROP_BUMPMAP) || !defined(OPTIMIZER_ENABLED)
				poiMesh.tangentSpaceNormal = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_BumpMap, _MainTex, poiUV(poiMesh.uv[_BumpMapUV].xy, _BumpMap_ST), _BumpMapPan, _BumpMapStochastic), _BumpScale);
				#else
				poiMesh.tangentSpaceNormal = UnpackNormal(float4(0.5, 0.5, 1, 1));
				#endif
				
				//ifex _DetailEnabled==0
				#if defined(FINALPASS) && !defined(UNITY_PASS_SHADOWCASTER) && !defined(POI_PASS_OUTLINE)
				ApplyDetailNormal(poiMods, poiMesh);
				#endif
				//endex
				
				//ifex _RGBMaskEnabled==0
				#if defined(VIGNETTE) && !defined(UNITY_PASS_SHADOWCASTER) && !defined(POI_PASS_OUTLINE)
				calculateRGBNormals(poiMesh, poiMods);
				#endif
				
				//endex
				
				float3 tangentSpaceNormal = UnpackNormal(float4(0.5, 0.5, 1, 1));
				poiMesh.normals[0] = normalize(
				tangentSpaceNormal.x * poiMesh.tangent[0] +
				tangentSpaceNormal.y * poiMesh.binormal[0] +
				tangentSpaceNormal.z * poiMesh.normals[0]
				);
				
				poiMesh.normals[1] = normalize(
				poiMesh.tangentSpaceNormal.x * poiMesh.tangent[0] +
				poiMesh.tangentSpaceNormal.y * poiMesh.binormal[0] +
				poiMesh.tangentSpaceNormal.z * poiMesh.normals[0]
				);
				
				poiMesh.tangent[1] = cross(poiMesh.binormal[0], -poiMesh.normals[1]);
				poiMesh.binormal[1] = cross(-poiMesh.normals[1], poiMesh.tangent[0]);
				
				//ifex _EnableOutlines!=1
				#ifdef POI_PASS_OUTLINE
				poiMesh.normals[1] = poiMesh.normals[0];
				#endif
				//endex
				
				// Camera data
				poiCam.forwardDir = getCameraForward();
				poiCam.worldPos = _WorldSpaceCameraPos;
				poiCam.reflectionDir = reflect(-poiCam.viewDir, poiMesh.normals[1]);
				poiCam.vertexReflectionDir = reflect(-poiCam.viewDir, poiMesh.normals[0]);
				//poiCam.distanceToModel = distance(poiMesh.modelPos, poiCam.worldPos);
				poiCam.clipPos = i.pos;
				poiCam.distanceToVert = distance(poiMesh.worldPos, poiCam.worldPos);
				poiCam.posScreenSpace = poiTransformClipSpacetoScreenSpaceFrag(poiCam.clipPos);
				#if defined(POI_GRABPASS) && defined(POI_PASS_BASE)
				poiCam.screenUV = poiCam.clipPos.xy / poiGetWidthAndHeight(_PoiGrab2);
				#else
				poiCam.screenUV = poiCam.clipPos.xy / _ScreenParams.xy;
				#endif
				#ifdef UNITY_SINGLE_PASS_STEREO
				poiCam.posScreenSpace.x = poiCam.posScreenSpace.x * 0.5;
				#endif
				poiCam.posScreenPixels = calcPixelScreenUVs(poiCam.posScreenSpace);
				poiCam.vDotN = abs(dot(poiCam.viewDir, poiMesh.normals[1]));
				
				poiCam.worldDirection.xyz = poiMesh.worldPos.xyz - poiCam.worldPos;
				poiCam.worldDirection.w = dot(poiCam.clipPos, CalculateFrustumCorrection());
				
				calculateGlobalThemes(poiMods);
				
				poiLight.finalLightAdd = 0;
				
				// Ambient Occlusion
				#if defined(PROP_LIGHTINGAOMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 AOMaps = POI2D_SAMPLER_PAN(_LightingAOMaps, _MainTex, poiUV(poiMesh.uv[_LightingAOMapsUV], _LightingAOMaps_ST), _LightingAOMapsPan);
				poiLight.occlusion = min(min(min(lerp(1, AOMaps.r, _LightDataAOStrengthR), lerp(1, AOMaps.g, _LightDataAOStrengthG)), lerp(1, AOMaps.b, _LightDataAOStrengthB)), lerp(1, AOMaps.a, _LightDataAOStrengthA));
				#else
				poiLight.occlusion = 1;
				#endif
				
				if (_LightDataAOGlobalMaskR > 0)
				{
					poiLight.occlusion = maskBlend(poiLight.occlusion, poiMods.globalMask[_LightDataAOGlobalMaskR - 1], _LightDataAOGlobalMaskBlendTypeR);
				}
				
				// Detail Shadows
				#if defined(PROP_LIGHTINGDETAILSHADOWMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 DetailShadows = POI2D_SAMPLER_PAN(_LightingDetailShadowMaps, _MainTex, poiUV(poiMesh.uv[_LightingDetailShadowMapsUV], _LightingDetailShadowMaps_ST), _LightingDetailShadowMapsPan);
				#ifndef POI_PASS_ADD
				poiLight.detailShadow = lerp(1, DetailShadows.r, _LightingDetailShadowStrengthR) * lerp(1, DetailShadows.g, _LightingDetailShadowStrengthG) * lerp(1, DetailShadows.b, _LightingDetailShadowStrengthB) * lerp(1, DetailShadows.a, _LightingDetailShadowStrengthA);
				#else
				poiLight.detailShadow = lerp(1, DetailShadows.r, _LightingAddDetailShadowStrengthR) * lerp(1, DetailShadows.g, _LightingAddDetailShadowStrengthG) * lerp(1, DetailShadows.b, _LightingAddDetailShadowStrengthB) * lerp(1, DetailShadows.a, _LightingAddDetailShadowStrengthA);
				#endif
				#else
				poiLight.detailShadow = 1;
				#endif
				
				if (_LightDataDetailShadowGlobalMaskR > 0)
				{
					poiLight.detailShadow = maskBlend(poiLight.detailShadow, poiMods.globalMask[_LightDataDetailShadowGlobalMaskR - 1], _LightDataDetailShadowGlobalMaskBlendTypeR);
				}
				
				// Shadow Masks
				#if defined(PROP_LIGHTINGSHADOWMASKS) || !defined(OPTIMIZER_ENABLED)
				float4 ShadowMasks = POI2D_SAMPLER_PAN(_LightingShadowMasks, _MainTex, poiUV(poiMesh.uv[_LightingShadowMasksUV], _LightingShadowMasks_ST), _LightingShadowMasksPan);
				poiLight.shadowMask = lerp(1, ShadowMasks.r, _LightingShadowMaskStrengthR) * lerp(1, ShadowMasks.g, _LightingShadowMaskStrengthG) * lerp(1, ShadowMasks.b, _LightingShadowMaskStrengthB) * lerp(1, ShadowMasks.a, _LightingShadowMaskStrengthA);
				#else
				poiLight.shadowMask = 1;
				#endif
				if (_LightDataShadowMaskGlobalMaskR > 0)
				{
					poiLight.shadowMask = maskBlend(poiLight.shadowMask, poiMods.globalMask[_LightDataShadowMaskGlobalMaskR - 1], _LightDataShadowMaskGlobalMaskBlendTypeR);
				}
				
				#ifdef UNITY_PASS_FORWARDBASE
				
				bool lightExists = false;
				if (any(_LightColor0.rgb >= 0.002))
				{
					lightExists = true;
				}
				
				if (_LightingVertexLightingEnabled)
				{
					poiFragData.toggleVertexLights = 1;
				}
				if (IsInMirror() && _LightingMirrorVertexLightingEnabled == 0)
				{
					poiFragData.toggleVertexLights = 0;
				}
				
				if (_LightingVertexLightingEnabled)
				{
					#if defined(VERTEXLIGHT_ON)
					float4 toLightX = unity_4LightPosX0 - i.worldPos.x;
					float4 toLightY = unity_4LightPosY0 - i.worldPos.y;
					float4 toLightZ = unity_4LightPosZ0 - i.worldPos.z;
					float4 lengthSq = 0;
					lengthSq += toLightX * toLightX;
					lengthSq += toLightY * toLightY;
					lengthSq += toLightZ * toLightZ;
					
					float4 lightAttenSq = unity_4LightAtten0;
					float4 atten = 1.0 / (1.0 + lengthSq * lightAttenSq);
					float4 vLightWeight = saturate(1 - (lengthSq * lightAttenSq / 25));
					poiLight.vAttenuation = min(atten, vLightWeight * vLightWeight);
					
					poiLight.vDotNL = 0;
					poiLight.vDotNL += toLightX * poiMesh.normals[1].x;
					poiLight.vDotNL += toLightY * poiMesh.normals[1].y;
					poiLight.vDotNL += toLightZ * poiMesh.normals[1].z;
					
					float4 corr = rsqrt(lengthSq);
					poiLight.vertexVDotNL = max(0, poiLight.vDotNL * corr);
					
					poiLight.vertexVDotNL = 0;
					poiLight.vertexVDotNL += toLightX * poiMesh.normals[0].x;
					poiLight.vertexVDotNL += toLightY * poiMesh.normals[0].y;
					poiLight.vertexVDotNL += toLightZ * poiMesh.normals[0].z;
					
					poiLight.vertexVDotNL = max(0, poiLight.vDotNL * corr);
					
					poiLight.vSaturatedDotNL = saturate(poiLight.vDotNL);
					
					[unroll]
					for (int index = 0; index < 4; index++)
					{
						poiLight.vPosition[index] = float3(unity_4LightPosX0[index], unity_4LightPosY0[index], unity_4LightPosZ0[index]);
						
						float3 vertexToLightSource = poiLight.vPosition[index] - poiMesh.worldPos;
						poiLight.vDirection[index] = normalize(vertexToLightSource);
						poiLight.vColor[index] = _LightingAdditiveLimited ? MaxLuminance(unity_LightColor[index].rgb * poiLight.vAttenuation[index], _LightingAdditiveLimit) : unity_LightColor[index].rgb * poiLight.vAttenuation[index];
						poiLight.vColor[index] = lerp(poiLight.vColor[index], dot(poiLight.vColor[index], float3(0.299, 0.587, 0.114)), _LightingAdditiveMonochromatic);
						poiLight.vHalfDir[index] = Unity_SafeNormalize(poiLight.vDirection[index] + poiCam.viewDir);
						poiLight.vDotNL[index] = dot(poiMesh.normals[1], poiLight.vDirection[index]);
						poiLight.vCorrectedDotNL[index] = .5 * (poiLight.vDotNL[index] + 1);
						poiLight.vDotLH[index] = saturate(dot(poiLight.vDirection[index], poiLight.vHalfDir[index]));
						
						poiLight.vDotNH[index] = dot(poiMesh.normals[1], poiLight.vHalfDir[index]);
						poiLight.vertexVDotNH[index] = saturate(dot(poiMesh.normals[0], poiLight.vHalfDir[index]));
					}
					#endif
				}
				
				//UNITY_BRANCH
				if (_LightingColorMode == 0) // Poi Custom Light Color
				
				{
					float3 magic = max(BetterSH9(normalize(unity_SHAr + unity_SHAg + unity_SHAb)), 0);
					float3 normalLight = _LightColor0.rgb + BetterSH9(float4(0, 0, 0, 1));
					
					float magiLumi = calculateluminance(magic);
					float normaLumi = calculateluminance(normalLight);
					float maginormalumi = magiLumi + normaLumi;
					
					float magiratio = magiLumi / maginormalumi;
					float normaRatio = normaLumi / maginormalumi;
					
					float target = calculateluminance(magic * magiratio + normalLight * normaRatio);
					float3 properLightColor = magic + normalLight;
					float properLuminance = calculateluminance(magic + normalLight);
					poiLight.directColor = properLightColor * max(0.0001, (target / properLuminance));
					
					poiLight.indirectColor = BetterSH9(float4(lerp(0, poiMesh.normals[1], _LightingIndirectUsesNormals), 1));
				}
				
				//UNITY_BRANCH
				if (_LightingColorMode == 1) // More standard approach to light color
				
				{
					float3 indirectColor = BetterSH9(float4(poiMesh.normals[1], 1));
					if (lightExists)
					{
						poiLight.directColor = _LightColor0.rgb;
						poiLight.indirectColor = indirectColor;
					}
					else
					{
						poiLight.directColor = indirectColor * 0.6;
						poiLight.indirectColor = indirectColor * 0.5;
					}
				}
				
				if (_LightingColorMode == 2) // UTS style
				
				{
					poiLight.indirectColor = saturate(max(half3(0.05, 0.05, 0.05) * _Unlit_Intensity, max(ShadeSH9(half4(0.0, 0.0, 0.0, 1.0)), ShadeSH9(half4(0.0, -1.0, 0.0, 1.0)).rgb) * _Unlit_Intensity));
					poiLight.directColor = max(poiLight.indirectColor, _LightColor0.rgb);
				}
				
				if (_LightingColorMode == 3) // OpenLit
				
				{
					float3 lightDirectionForSH9 = OpenLitLightingDirectionForSH9();
					OpenLitShadeSH9ToonDouble(lightDirectionForSH9, poiLight.directColor, poiLight.indirectColor);
					poiLight.directColor += _LightColor0.rgb;
					// OpenLit does a few other things by default like clamp direct colour
					// see https://github.com/lilxyzw/OpenLit/blob/main/Assets/OpenLit/core.hlsl#L174
				}
				
				float lightMapMode = _LightingMapMode;
				//UNITY_BRANCH
				if (_LightingDirectionMode == 0)
				{
					poiLight.direction = _WorldSpaceLightPos0.xyz + unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz;
				}
				if (_LightingDirectionMode == 1 || _LightingDirectionMode == 2)
				{
					//UNITY_BRANCH
					if (_LightingDirectionMode == 1)
					{
						poiLight.direction = mul(unity_ObjectToWorld, _LightngForcedDirection).xyz;;
					}
					//UNITY_BRANCH
					if (_LightingDirectionMode == 2)
					{
						poiLight.direction = _LightngForcedDirection;
					}
					if (lightMapMode == 0)
					{
						lightMapMode == 1;
					}
				}
				
				if (_LightingDirectionMode == 3) // UTS
				
				{
					float3 defaultLightDirection = normalize(UNITY_MATRIX_V[2].xyz + UNITY_MATRIX_V[1].xyz);
					float3 lightDirection = normalize(lerp(defaultLightDirection, _WorldSpaceLightPos0.xyz, any(_WorldSpaceLightPos0.xyz)));
					poiLight.direction = lightDirection;
				}
				if (_LightingDirectionMode == 4) // OpenLit
				
				{
					poiLight.direction = OpenLitLightingDirection(); // float4 customDir = 0; // Do we want to give users to alter this (OpenLit always does!)?
					
				}
				
				if (_LightingDirectionMode == 5) // View Direction
				
				{
					float3 upViewDir = normalize(UNITY_MATRIX_V[1].xyz);
					float3 rightViewDir = normalize(UNITY_MATRIX_V[0].xyz);
					float yawOffset_Rads = radians(!IsInMirror() ? - _LightingViewDirOffsetYaw : _LightingViewDirOffsetYaw);
					float3 rotatedViewYaw = normalize(RotateAroundAxis(rightViewDir, upViewDir, yawOffset_Rads));
					float3 rotatedViewCameraMeshOffset = RotateAroundAxis((getCameraPosition() - (poiMesh.worldPos)), upViewDir, yawOffset_Rads);
					float pitchOffset_Rads = radians(!IsInMirror() ? _LightingViewDirOffsetPitch : - _LightingViewDirOffsetPitch);
					float3 rotatedViewPitch = RotateAroundAxis(rotatedViewCameraMeshOffset, rotatedViewYaw, pitchOffset_Rads);
					poiLight.direction = normalize(rotatedViewPitch);
				}
				
				if (!any(poiLight.direction))
				{
					poiLight.direction = float3(.4, 1, .4);
				}
				
				poiLight.direction = normalize(poiLight.direction);
				poiLight.attenuationStrength = _LightingCastedShadows;
				poiLight.attenuation = 1;
				if (!all(_LightColor0.rgb == 0.0))
				{
					UNITY_LIGHT_ATTENUATION(attenuation, i, poiMesh.worldPos)
					poiLight.attenuation *= attenuation;
				}
				
				if (!any(poiLight.directColor) && !any(poiLight.indirectColor) && lightMapMode == 0)
				{
					lightMapMode = 1;
					if (_LightingDirectionMode == 0)
					{
						poiLight.direction = normalize(float3(.4, 1, .4));
					}
				}
				
				poiLight.halfDir = normalize(poiLight.direction + poiCam.viewDir);
				poiLight.vertexNDotL = dot(poiMesh.normals[0], poiLight.direction);
				poiLight.nDotL = dot(poiMesh.normals[1], poiLight.direction);
				poiLight.nDotLSaturated = saturate(poiLight.nDotL);
				poiLight.nDotLNormalized = (poiLight.nDotL + 1) * 0.5;
				poiLight.nDotV = abs(dot(poiMesh.normals[1], poiCam.viewDir));
				poiLight.vertexNDotV = abs(dot(poiMesh.normals[0], poiCam.viewDir));
				poiLight.nDotH = dot(poiMesh.normals[1], poiLight.halfDir);
				poiLight.vertexNDotH = max(0.00001, dot(poiMesh.normals[0], poiLight.halfDir));
				poiLight.lDotv = dot(poiLight.direction, poiCam.viewDir);
				poiLight.lDotH = max(0.00001, dot(poiLight.direction, poiLight.halfDir));
				
				// Poi special light map
				if (lightMapMode == 0)
				{
					float3 ShadeSH9Plus = GetSHLength();
					float3 ShadeSH9Minus = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) + float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0;
					
					float3 greyScaleVector = float3(.33333, .33333, .33333);
					float bw_lightColor = dot(poiLight.directColor, greyScaleVector);
					float bw_directLighting = (((poiLight.nDotL * 0.5 + 0.5) * bw_lightColor * lerp(1, poiLight.attenuation, poiLight.attenuationStrength)) + dot(ShadeSH9(float4(poiMesh.normals[1], 1)), greyScaleVector));
					float bw_directLightingNoAtten = (((poiLight.nDotL * 0.5 + 0.5) * bw_lightColor) + dot(ShadeSH9(float4(poiMesh.normals[1], 1)), greyScaleVector));
					float bw_bottomIndirectLighting = dot(ShadeSH9Minus, greyScaleVector);
					float bw_topIndirectLighting = dot(ShadeSH9Plus, greyScaleVector);
					float lightDifference = ((bw_topIndirectLighting + bw_lightColor) - bw_bottomIndirectLighting);
					
					poiLight.lightMap = smoothstep(0, lightDifference, bw_directLighting - bw_bottomIndirectLighting);
					poiLight.lightMapNoAttenuation = smoothstep(0, lightDifference, bw_directLightingNoAtten - bw_bottomIndirectLighting);
				}
				// Normalized nDotL
				if (lightMapMode == 1)
				{
					poiLight.lightMapNoAttenuation = poiLight.nDotLNormalized;
					poiLight.lightMap = poiLight.nDotLNormalized * lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				}
				// Saturated nDotL
				if (lightMapMode == 2)
				{
					poiLight.lightMapNoAttenuation = poiLight.nDotLSaturated;
					poiLight.lightMap = poiLight.nDotLSaturated * lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				}
				if (lightMapMode == 3)
				{
					poiLight.lightMapNoAttenuation = 1;
					poiLight.lightMap = lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				}
				poiLight.lightMapNoAttenuation *= poiLight.detailShadow;
				poiLight.lightMap *= poiLight.detailShadow;
				
				poiLight.directColor = max(poiLight.directColor, 0.0001);
				poiLight.indirectColor = max(poiLight.indirectColor, 0.0001);
				
				if (_LightingColorMode == 3)
				{
					// OpenLit
					poiLight.directColor = max(poiLight.directColor, _LightingMinLightBrightness);
				}
				else
				{
					poiLight.directColor = max(poiLight.directColor, poiLight.directColor * min(10000, (_LightingMinLightBrightness * rcp(calculateluminance(poiLight.directColor)))));
					poiLight.indirectColor = max(poiLight.indirectColor, poiLight.indirectColor * min(10000, (_LightingMinLightBrightness * rcp(calculateluminance(poiLight.indirectColor)))));
				}
				
				poiLight.directColor = lerp(poiLight.directColor, dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic);
				poiLight.indirectColor = lerp(poiLight.indirectColor, dot(poiLight.indirectColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic);
				
				if (_LightingCapEnabled)
				{
					poiLight.directColor = min(poiLight.directColor, _LightingCap);
					poiLight.indirectColor = min(poiLight.indirectColor, _LightingCap);
				}
				
				if (_LightingForceColorEnabled)
				{
					poiLight.directColor = poiThemeColor(poiMods, _LightingForcedColor, _LightingForcedColorThemeIndex);
				}
				
				#ifdef UNITY_PASS_FORWARDBASE
				poiLight.directColor = max(poiLight.directColor * _PPLightingMultiplier, 0);
				poiLight.directColor = max(poiLight.directColor + _PPLightingAddition, 0);
				poiLight.indirectColor = max(poiLight.indirectColor * _PPLightingMultiplier, 0);
				poiLight.indirectColor = max(poiLight.indirectColor + _PPLightingAddition, 0);
				#endif
				
				#endif
				
				#ifdef POI_PASS_ADD
				if (!_LightingAdditiveEnable)
				{
					return float4(mainTexture.rgb * .0001, 1);
				}
				
				#if defined(DIRECTIONAL)
				if (_DisableDirectionalInAdd)
				{
					return float4(mainTexture.rgb * .0001, 1);
				}
				#endif
				
				poiLight.direction = normalize(_WorldSpaceLightPos0.xyz - i.worldPos.xyz * _WorldSpaceLightPos0.w);
				#if defined(POINT) || defined(SPOT)
				#ifdef POINT
				unityShadowCoord3 lightCoord = mul(unity_WorldToLight, unityShadowCoord4(poiMesh.worldPos, 1)).xyz;
				poiLight.attenuation = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).r;
				#endif
				
				#ifdef SPOT
				unityShadowCoord4 lightCoord = mul(unity_WorldToLight, unityShadowCoord4(poiMesh.worldPos, 1));
				poiLight.attenuation = (lightCoord.z > 0) * UnitySpotCookie(lightCoord) * UnitySpotAttenuate(lightCoord.xyz);
				#endif
				#else
				UNITY_LIGHT_ATTENUATION(attenuation, i, poiMesh.worldPos)
				poiLight.attenuation = attenuation;
				#endif
				poiLight.additiveShadow = UNITY_SHADOW_ATTENUATION(i, poiMesh.worldPos);
				poiLight.attenuationStrength = _LightingAdditiveCastedShadows;
				poiLight.directColor = _LightingAdditiveLimited ? MaxLuminance(_LightColor0.rgb * poiLight.attenuation, _LightingAdditiveLimit) : _LightColor0.rgb  * poiLight.attenuation;
				
				#if defined(POINT_COOKIE) || defined(DIRECTIONAL_COOKIE)
				poiLight.indirectColor = 0;
				#else
				poiLight.indirectColor = lerp(0, poiLight.directColor, _LightingAdditivePassthrough);
				poiLight.indirectColor = _LightingAdditiveLimited ? MaxLuminance(poiLight.indirectColor, _LightingAdditiveLimit) : poiLight.indirectColor;
				#endif
				
				poiLight.directColor = lerp(poiLight.directColor, dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), _LightingAdditiveMonochromatic);
				poiLight.indirectColor = lerp(poiLight.indirectColor, dot(poiLight.indirectColor, float3(0.299, 0.587, 0.114)), _LightingAdditiveMonochromatic);
				
				poiLight.halfDir = normalize(poiLight.direction + poiCam.viewDir);
				poiLight.nDotL = dot(poiMesh.normals[1], poiLight.direction);
				poiLight.nDotLSaturated = saturate(poiLight.nDotL);
				poiLight.nDotLNormalized = (poiLight.nDotL + 1) * 0.5;
				poiLight.nDotV = abs(dot(poiMesh.normals[1], poiCam.viewDir));
				poiLight.nDotH = dot(poiMesh.normals[1], poiLight.halfDir);
				poiLight.lDotv = dot(poiLight.direction, poiCam.viewDir);
				poiLight.lDotH = dot(poiLight.direction, poiLight.halfDir);
				poiLight.vertexNDotL = dot(poiMesh.normals[0], poiLight.direction);
				poiLight.vertexNDotV = abs(dot(poiMesh.normals[0], poiCam.viewDir));
				poiLight.vertexNDotH = max(0.00001, dot(poiMesh.normals[0], poiLight.halfDir));
				
				// Normalized nDotL
				if (_LightingMapMode == 0 || _LightingMapMode == 1 || _LightingMapMode == 2)
				{
					poiLight.lightMap = poiLight.nDotLNormalized;
				}
				if (_LightingMapMode == 3)
				{
					poiLight.lightMap = 1;
				}
				poiLight.lightMap *= poiLight.detailShadow;
				poiLight.lightMapNoAttenuation = poiLight.lightMap;
				poiLight.lightMap *= lerp(1, poiLight.additiveShadow, poiLight.attenuationStrength);
				#endif
				
				//ifex _LightDataDebugEnabled==0
				if (_LightDataDebugEnabled)
				{
					#ifdef UNITY_PASS_FORWARDBASE
					//UNITY_BRANCH
					if (_LightingDebugVisualize <= 6)
					{
						switch(_LightingDebugVisualize)
						{
							case 0: // Direct Light Color
							return float4(poiLight.directColor + mainTexture.rgb * .0001, 1);
							break;
							case 1: // Indirect Light Color
							return float4(poiLight.indirectColor + mainTexture.rgb * .0001, 1);
							break;
							case 2: // Light Map
							return float4(poiLight.lightMap + mainTexture.rgb * .0001, 1);
							break;
							case 3: // Attenuation
							return float4(poiLight.attenuation + mainTexture.rgb * .0001, 1);
							break;
							case 4: // N Dot L
							return float4(poiLight.nDotLNormalized, poiLight.nDotLNormalized, poiLight.nDotLNormalized, 1) + mainTexture * .0001;
							break;
							case 5:
							return float4(poiLight.halfDir, 1) + mainTexture * .0001;
							break;
							case 6:
							return float4(poiLight.direction, 1) + mainTexture * .0001;
							break;
						}
					}
					else
					{
						return POI_SAFE_RGB1;
					}
					#endif
					#ifdef POI_PASS_ADD
					//UNITY_BRANCH
					if (_LightingDebugVisualize < 6)
					{
						return POI_SAFE_RGB1;
					}
					else
					{
						switch(_LightingDebugVisualize)
						{
							case 7:
							return float4(poiLight.directColor * poiLight.attenuation + mainTexture.rgb * .0001, 1);
							break;
							case 8:
							return float4(poiLight.attenuation + mainTexture.rgb * .0001, 1);
							break;
							case 9:
							return float4(poiLight.additiveShadow + mainTexture.rgb * .0001, 1);
							break;
							case 10:
							return float4(poiLight.nDotLNormalized + mainTexture.rgb * .0001, 1);
							break;
							case 11:
							return float4(poiLight.halfDir, 1) + mainTexture * .0001;
							break;
						}
					}
					#endif
				}
				//endex
				
				//ifex _EnableAudioLink==0
				#ifdef POI_AUDIOLINK
				SetupAudioLink(poiFragData, poiMods, poiMesh);
				#endif
				//endex
				
				//ifex _MochieBRDF==0
				#if defined(MOCHIE_PBR)
				MetallicAndSpecularFragDataInit(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _BlackLightMaskingEnabled==0
				#ifdef POI_BLACKLIGHTMASKING
				calculateBlackLightMasks(poiMesh, poiMods);
				#endif
				//endex
				
				poiFragData.baseColor = mainTexture.rgb * poiThemeColor(poiMods, _Color.rgb, _ColorThemeIndex);
				poiFragData.alpha = mainTexture.a * _Color.a;
				
				//ifex _MainColorAdjustToggle==0
				#ifdef COLOR_GRADING_HDR
				#if defined(PROP_MAINCOLORADJUSTTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 hueShiftAlpha = POI2D_SAMPLER_PAN(_MainColorAdjustTexture, _MainTex, poiUV(poiMesh.uv[_MainColorAdjustTextureUV], _MainColorAdjustTexture_ST), _MainColorAdjustTexturePan);
				#else
				float4 hueShiftAlpha = 1;
				#endif
				
				if (_MainHueGlobalMask > 0)
				{
					hueShiftAlpha.r = maskBlend(hueShiftAlpha.r, poiMods.globalMask[_MainHueGlobalMask - 1], _MainHueGlobalMaskBlendType);
				}
				if (_MainSaturationGlobalMask > 0)
				{
					hueShiftAlpha.b = maskBlend(hueShiftAlpha.b, poiMods.globalMask[_MainSaturationGlobalMask - 1], _MainSaturationGlobalMaskBlendType);
				}
				if (_MainBrightnessGlobalMask > 0)
				{
					hueShiftAlpha.g = maskBlend(hueShiftAlpha.g, poiMods.globalMask[_MainBrightnessGlobalMask - 1], _MainBrightnessGlobalMaskBlendType);
				}
				
				if (_MainHueShiftToggle)
				{
					float shift = _MainHueShift;
					#ifdef POI_AUDIOLINK
					//UNITY_BRANCH
					if (poiMods.audioLinkAvailable && _MainHueALCTEnabled)
					{
						shift += AudioLinkGetChronoTime(_MainALHueShiftCTIndex, _MainALHueShiftBand) * _MainHueALMotionSpeed;
					}
					#endif
					if (_MainHueShiftReplace)
					{
						poiFragData.baseColor = lerp(poiFragData.baseColor, hueShift(poiFragData.baseColor, shift + _MainHueShiftSpeed * _Time.x), hueShiftAlpha.r);
					}
					else
					{
						poiFragData.baseColor = hueShift(poiFragData.baseColor, frac((shift - (1 - hueShiftAlpha.r) + _MainHueShiftSpeed * _Time.x)));
					}
				}
				
				if (_MainGradationStrength && _ColorGradingToggle)
				{
					#if !defined(UNITY_COLORSPACE_GAMMA)
					float3 tempColor = OpenLitLinearToSRGB(poiFragData.baseColor);
					#else
					float3 tempColor = poiFragData.baseColor;
					#endif
					#if defined(PROP_MAINGRADATIONTEX) || !defined(OPTIMIZER_ENABLED)
					tempColor.r = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.r).r;
					tempColor.g = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.g).g;
					tempColor.b = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.b).b;
					#else
					tempColor = float3(1, 1, 1);
					#endif
					#if !defined(UNITY_COLORSPACE_GAMMA)
					tempColor = OpenLitSRGBToLinear(tempColor);
					#endif
					poiFragData.baseColor = lerp(poiFragData.baseColor, tempColor, _MainGradationStrength);
				}
				
				poiFragData.baseColor = lerp(poiFragData.baseColor, dot(poiFragData.baseColor, float3(0.3, 0.59, 0.11)), - (_Saturation) * hueShiftAlpha.b);
				poiFragData.baseColor = saturate(lerp(poiFragData.baseColor, poiFragData.baseColor * (_MainBrightness + 1), hueShiftAlpha.g));
				#endif
				//endex
				
				#if defined(PROP_ALPHAMASK) || !defined(OPTIMIZER_ENABLED)
				
				if (_MainAlphaMaskMode)
				{
					float alphaMask = POI2D_SAMPLER_PAN(_AlphaMask, _MainTex, poiUV(poiMesh.uv[_AlphaMaskUV], _AlphaMask_ST), _AlphaMaskPan.xy).r;
					alphaMask = saturate(alphaMask * _AlphaMaskScale + _AlphaMaskValue);
					if (_AlphaMaskInvert) alphaMask = 1 - alphaMask;
					if (_MainAlphaMaskMode == 1) poiFragData.alpha = alphaMask;
					if (_MainAlphaMaskMode == 2) poiFragData.alpha = poiFragData.alpha * alphaMask;
					if (_MainAlphaMaskMode == 3) poiFragData.alpha = saturate(poiFragData.alpha + alphaMask);
					if (_MainAlphaMaskMode == 4) poiFragData.alpha = saturate(poiFragData.alpha - alphaMask);
				}
				#endif
				
				//ifex _VideoEffectsEnable==0
				#ifdef POI_VIDEO_EFFECTS
				if (_VideoEffectsEnable)
				{
					applyVideoEffects(poiFragData, poiCam, poiMesh, poiLight, poiMods);
				}
				#endif
				//endex
				
				applyAlphaOptions(poiFragData, poiMesh, poiCam, poiMods);
				
				//ifex _EnableTouchGlow==0
				#ifdef GRAIN
				applyDepthFX(poiFragData, poiCam, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _DetailEnabled==0
				#ifdef FINALPASS
				ApplyDetailColor(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _MainVertexColoringEnabled==0
				applyVertexColor(poiFragData, poiMesh);
				//endex
				
				//ifex _BackFaceEnabled!=1
				#ifdef POI_BACKFACE
				ApplyBackFaceColor(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _RGBMaskEnabled==0
				#ifdef VIGNETTE
				calculateRGBMask(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _EnableDissolve==0
				#ifdef DISTORT
				applyDissolve(poiFragData, poiMesh, poiMods, poiCam, poiLight);
				#endif
				//endex
				
				//ifex _ShadingEnabled==0
				#if defined(_LIGHTINGMODE_SHADEMAP) && defined(VIGNETTE_MASKED)
				#ifndef POI_PASS_OUTLINE
				#ifdef _LIGHTINGMODE_SHADEMAP
				applyShadeMapping(poiFragData, poiMesh, poiLight);
				#endif
				#endif
				#endif
				//endex
				
				//ifex _ShadingEnabled==0
				#ifdef VIGNETTE_MASKED
				#ifdef POI_PASS_OUTLINE
				//UNITY_BRANCH
				if (_OutlineLit)
				{
					calculateShading(poiLight, poiFragData, poiMesh, poiCam);
				}
				else
				{
					poiLight.finalLighting = 1;
				}
				#else
				calculateShading(poiLight, poiFragData, poiMesh, poiCam);
				#endif
				#else
				//endex
				poiLight.finalLighting = 1;
				poiLight.rampedLightMap = poiEdgeNonLinear(poiLight.nDotL, 0.1, .1);
				//ifex _ShadingEnabled==0
				#endif
				if (_ShadingRampedLightMapApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _ShadingRampedLightMapApplyGlobalMaskIndex - 1, _ShadingRampedLightMapApplyGlobalMaskBlendType, poiLight.rampedLightMap);
				}
				if (_ShadingRampedLightMapInverseApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _ShadingRampedLightMapInverseApplyGlobalMaskIndex - 1, _ShadingRampedLightMapInverseApplyGlobalMaskBlendType, 1 - poiLight.rampedLightMap);
				}
				
				poiLight.directLuminance = dot(poiLight.directColor, float3(0.299, 0.587, 0.114));
				poiLight.indirectLuminance = dot(poiLight.directColor, float3(0.299, 0.587, 0.114));
				poiLight.finalLuminance = dot(poiLight.finalLighting, float3(0.299, 0.587, 0.114));
				//endex
				
				#if defined(GEOM_TYPE_BRANCH) || defined(GEOM_TYPE_BRANCH_DETAIL) || defined(GEOM_TYPE_FROND) || defined(DEPTH_OF_FIELD_COC_VIEW)
				applyDecals(poiFragData, poiMesh, poiCam, poiMods, poiLight);
				#endif
				
				//ifex _EnableAniso==0
				#ifdef POI_ANISOTROPICS
				applyAnisotropics(poiFragData, poiLight, poiCam, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _MatcapEnable==0 && _Matcap2Enable==0 && _Matcap3Enable==0 && _Matcap4Enable==0
				#if defined(POI_MATCAP0) || defined(COLOR_GRADING_HDR_3D) || defined(POI_MATCAP2) || defined(POI_MATCAP3)
				applyMatcap(poiFragData, poiCam, poiMesh, poiLight, poiMods);
				#endif
				//endex
				
				//ifex _CubeMapEnabled==0
				#ifdef _CUBEMAP
				applyCubemap(poiFragData, poiCam, poiMesh, poiLight, poiMods);
				#endif
				//endex
				
				//ifex _EnableALDecal==0
				#ifdef POI_AUDIOLINK
				#ifdef POI_AL_DECAL
				ApplyAudioLinkDecal(poiMesh, poiFragData, poiMods);
				#endif
				#endif
				//endex
				
				//ifex _EnableVolumeColor==0
				#ifdef POI_AUDIOLINK
				#ifdef POI_AL_VOLUMECOLOR
				ApplyAudioLinkVolumeColor(poiMesh, poiFragData, poiMods);
				#endif
				#endif
				//endex
				
				//ifex _EnableFlipbook==0
				#ifdef _SUNDISK_HIGH_QUALITY
				applyFlipbook(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _EnableRimLighting==0
				#ifdef _GLOSSYREFLECTIONS_OFF
				#ifdef _RIMSTYLE_POIYOMI
				#if defined(PROP_RIMMASK) || !defined(OPTIMIZER_ENABLED)
				float4 rimMaskAndBias = POI2D_SAMPLER_PAN(_RimMask, _MainTex, poiUV(poiMesh.uv[_RimMaskUV], _RimMask_ST), _RimMaskPan);
				float rimMask = rimMaskAndBias[_RimMaskChannel];
				float rimBias = rimMaskAndBias.a;
				#else
				float rimMask = 1;
				float rimBias = 0;
				#endif
				
				if (_RimMaskInvert)
				{
					rimMask = 1 - rimMask;
				}
				
				#if defined(PROP_RIMTEX) || !defined(OPTIMIZER_ENABLED)
				float4 rimColor = POI2D_SAMPLER_PAN(_RimTex, _MainTex, poiUV(poiMesh.uv[_RimTexUV], _RimTex_ST), _RimTexPan);
				#else
				float4 rimColor = 1;
				#endif
				half AudioLinkRimWidthBand = 0;
				float2 AudioLinkRimWidthAdd = 0;
				half AudioLinkRimEmissionBand = 0;
				float2 AudioLinkRimEmissionAdd = 0;
				half AudioLinkRimBrightnessBand = 0;
				float2 AudioLinkRimBrightnessAdd = 0;
				#ifdef POI_AUDIOLINK
				AudioLinkRimWidthBand = _AudioLinkRimWidthBand;
				AudioLinkRimWidthAdd = _AudioLinkRimWidthAdd;
				AudioLinkRimEmissionBand = _AudioLinkRimEmissionBand;
				AudioLinkRimEmissionAdd = _AudioLinkRimEmissionAdd;
				AudioLinkRimBrightnessBand = _AudioLinkRimBrightnessBand;
				AudioLinkRimBrightnessAdd = _AudioLinkRimBrightnessAdd;
				#endif
				
				ApplyPoiyomiRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, _Is_NormalMapToRimLight, _RimLightingInvert, _RimPower, _RimStrength, _RimShadowWidth, _RimShadowToggle, _RimWidth, _RimBlendStrength, rimMask, _RimGlobalMask, _RimGlobalMaskBlendType, rimColor, _RimLightColor, _RimLightColorThemeIndex, _RimHueShiftEnabled, _RimHueShift, _RimHueShiftSpeed, _RimSharpness, _RimShadowMaskRampType, _RimShadowMaskInvert, _RimShadowMaskStrength, _RimShadowAlpha, _RimApplyGlobalMaskIndex, _RimApplyGlobalMaskBlendType, _RimBaseColorMix, _RimBrightness, _RimPoiBlendMode, AudioLinkRimWidthBand, AudioLinkRimWidthAdd, AudioLinkRimEmissionBand, AudioLinkRimEmissionAdd, AudioLinkRimBrightnessBand, AudioLinkRimBrightnessAdd, rimBias, _RimBiasIntensity, _RimApplyAlpha, _RimApplyAlphaBlend);
				#endif
				#ifdef _RIMSTYLE_UTS2
				#if defined(PROP_SET_RIMLIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float Set_RimLightMask_var = POI2D_SAMPLER_PAN(_Set_RimLightMask, _MainTex, poiUV(poiMesh.uv[_Set_RimLightMaskUV], _Set_RimLightMask_ST), _Set_RimLightMaskPan)[_Set_RimLightMaskChannel];
				#else
				float Set_RimLightMask_var = 1;
				#endif
				ApplyUTS2RimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, Set_RimLightMask_var, _RimGlobalMask, _RimGlobalMaskBlendType, _RimLightColor, _RimLightColorThemeIndex, _Is_LightColor_RimLight, _Is_NormalMapToRimLight, _RimLight_Power, _RimLight_InsideMask, _RimLight_FeatherOff, _LightDirection_MaskOn, _Tweak_LightDirection_MaskLevel, _Add_Antipodean_RimLight, _Ap_RimLightColor, _RimApColorThemeIndex, _Is_LightColor_Ap_RimLight, _Ap_RimLight_Power, _Ap_RimLight_FeatherOff, _Tweak_RimLightMaskLevel, _RimHueShiftEnabled, _RimHueShift, _RimHueShiftSpeed);
				#endif
				
				#endif
				//endex
				//ifex _EnableRim2Lighting==0
				#ifdef POI_RIM2
				#ifdef _RIM2STYLE_POIYOMI
				#if defined(PROP_RIM2MASK) || !defined(OPTIMIZER_ENABLED)
				float4 rim2MaskAndBias = POI2D_SAMPLER_PAN(_Rim2Mask, _MainTex, poiUV(poiMesh.uv[_Rim2MaskUV], _Rim2Mask_ST), _Rim2MaskPan);
				float rim2Mask = rim2MaskAndBias[_Rim2MaskChannel];
				float rim2Bias = rim2MaskAndBias.a;
				#else
				float rim2Mask = 1;
				float rim2Bias = 0;
				#endif
				
				if (_Rim2MaskInvert)
				{
					rim2Mask = 1 - rim2Mask;
				}
				
				#if defined(PROP_RIM2TEX) || !defined(OPTIMIZER_ENABLED)
				float4 rim2Color = POI2D_SAMPLER_PAN(_Rim2Tex, _MainTex, poiUV(poiMesh.uv[_Rim2TexUV], _Rim2Tex_ST), _Rim2TexPan);
				#else
				float4 rim2Color = 1;
				#endif
				half AudioLinkRim2WidthBand = 0;
				float2 AudioLinkRim2WidthAdd = 0;
				half AudioLinkRim2EmissionBand = 0;
				float2 AudioLinkRim2EmissionAdd = 0;
				half AudioLinkRim2BrightnessBand = 0;
				float2 AudioLinkRim2BrightnessAdd = 0;
				#ifdef POI_AUDIOLINK
				AudioLinkRim2WidthBand = _AudioLinkRim2WidthBand;
				AudioLinkRim2WidthAdd = _AudioLinkRim2WidthAdd;
				AudioLinkRim2EmissionBand = _AudioLinkRim2EmissionBand;
				AudioLinkRim2EmissionAdd = _AudioLinkRim2EmissionAdd;
				AudioLinkRim2BrightnessBand = _AudioLinkRim2BrightnessBand;
				AudioLinkRim2BrightnessAdd = _AudioLinkRim2BrightnessAdd;
				#endif
				ApplyPoiyomiRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, _Is_NormalMapToRim2Light, _Rim2LightingInvert, _Rim2Power, _Rim2Strength, _Rim2ShadowWidth, _Rim2ShadowToggle, _Rim2Width, _Rim2BlendStrength, rim2Mask, _Rim2GlobalMask, _Rim2GlobalMaskBlendType, rim2Color, _Rim2LightColor, _Rim2LightColorThemeIndex, _Rim2HueShiftEnabled, _Rim2HueShift, _Rim2HueShiftSpeed, _Rim2Sharpness, _Rim2ShadowMaskRampType, _Rim2ShadowMaskInvert, _Rim2ShadowMaskStrength, _Rim2ShadowAlpha, _Rim2ApplyGlobalMaskIndex, _Rim2ApplyGlobalMaskBlendType, _Rim2BaseColorMix, _Rim2Brightness, _RimPoi2BlendMode, AudioLinkRim2WidthBand, AudioLinkRim2WidthAdd, AudioLinkRim2EmissionBand, AudioLinkRim2EmissionAdd, AudioLinkRim2BrightnessBand, AudioLinkRim2BrightnessAdd, rim2Bias, _Rim2BiasIntensity, _Rim2ApplyAlpha, _Rim2ApplyAlphaBlend);
				#endif
				#ifdef _RIM2STYLE_UTS2
				#if defined(PROP_SET_RIM2LIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float Set_Rim2LightMask_var = POI2D_SAMPLER_PAN(_Set_Rim2LightMask, _MainTex, poiUV(poiMesh.uv[_Set_Rim2LightMaskUV], _Set_Rim2LightMask_ST), _Set_Rim2LightMaskPan)[_Set_Rim2LightMaskChannel];
				#else
				float Set_Rim2LightMask_var = 1;
				#endif
				ApplyUTS2RimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, Set_Rim2LightMask_var, _Rim2GlobalMask, _Rim2GlobalMaskBlendType, _Rim2LightColor, _Rim2LightColorThemeIndex, _Is_LightColor_Rim2Light, _Is_NormalMapToRim2Light, _Rim2Light_Power, _Rim2Light_InsideMask, _Rim2Light_FeatherOff, _LightDirection_MaskOn2, _Tweak_LightDirection_MaskLevel2, _Add_Antipodean_Rim2Light, _Ap_Rim2LightColor, _Rim2ApColorThemeIndex, _Is_LightColor_Ap_Rim2Light, _Ap_Rim2Light_Power, _Ap_Rim2Light_FeatherOff, _Tweak_Rim2LightMaskLevel, _Rim2HueShiftEnabled, _Rim2HueShift, _Rim2HueShiftSpeed);
				#endif
				
				#endif
				//endex
				
				//ifex _EnableDepthRimLighting==0
				#ifdef _POI_DEPTH_RIMLIGHT
				if (!IsInMirror())
				{
					ApplyDepthRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods);
				}
				#endif
				//endex
				
				//ifex _GlitterEnable==0
				#ifdef _SUNDISK_SIMPLE
				applyGlitter(poiFragData, poiMesh, poiCam, poiLight, poiMods);
				#endif
				//endex
				
				//ifex _StylizedSpecular==0
				#ifdef POI_STYLIZED_StylizedSpecular
				stylizedSpecular(poiFragData, poiCam, poiLight, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _EnablePathing==0
				#ifdef POI_PATHING
				// Only run pathing if a map exists.
				#if defined(PROP_PATHINGMAP) || !defined(OPTIMIZER_ENABLED)
				applyPathing(poiFragData, poiMesh, poiMods);
				#endif
				#endif
				//endex
				
				//ifex _EnableMirrorOptions==0
				#ifdef POI_MIRROR
				applyMirror(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _TextEnabled==0
				#ifdef EFFECT_BUMP
				ApplyTextOverlayColor(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _VoronoiEnabled!=1
				#ifdef POI_VORONOI
				ApplyVoronoi(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				if (_AlphaPremultiply)
				{
					poiFragData.baseColor *= saturate(poiFragData.alpha);
				}
				poiFragData.finalColor = poiFragData.baseColor;
				
				poiFragData.finalColor = poiFragData.baseColor * poiLight.finalLighting;
				
				//ifex _SubsurfaceScattering==0
				#ifdef POI_SUBSURFACESCATTERING
				applySubsurfaceScattering(poiCam, poiLight, poiMesh, poiFragData);
				#endif
				//endex
				
				//ifex _MochieBRDF==0
				#ifdef MOCHIE_PBR
				MochieBRDF(poiFragData, poiCam, poiLight, poiMesh, poiMods);
				#endif
				//endex
				//ifex _ClearCoatBRDF==0
				#ifdef POI_CLEARCOAT
				poiClearCoat(poiFragData, poiCam, poiLight, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _BacklightEnabled!=1
				#ifdef POI_BACKLIGHT
				ApplyBacklight(poiFragData, poiMesh, poiLight, poiCam, poiMods);
				#endif
				//endex
				
				//ifex _EnableRimLighting==0
				#ifdef _GLOSSYREFLECTIONS_OFF
				#ifdef _RIMSTYLE_LILTOON
				#if defined(PROP_RIMCOLORTEX) || !defined(OPTIMIZER_ENABLED)
				float4 rimColorTex = POI2D_SAMPLER_PAN(_RimColorTex, _MainTex, poiUV(poiMesh.uv[_RimColorTexUV], _RimColorTex_ST), _RimColorTexPan);
				#else
				float4 rimColorTex = 1;
				#endif
				ApplyLiltoonRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, _RimColor, _RimIndirColor, rimColorTex, _RimMainStrength, _RimNormalStrength, _RimDirRange, _RimIndirRange, _RimFresnelPower, _RimBackfaceMask, _RimDirStrength, _RimBorder, _RimBlur, _RimIndirBorder, _RimIndirBlur, _RimShadowMask, _RimEnableLighting, _RimVRParallaxStrength, _RimGlobalMask, _RimGlobalMaskBlendType, _RimHueShiftEnabled, _RimHueShift, _RimHueShiftSpeed, _RimBlendMode);
				#endif
				#endif
				//endex
				//ifex _EnableRim2Lighting==0
				#ifdef POI_RIM2
				#ifdef _RIM2STYLE_LILTOON
				#if defined(PROP_RIM2COLORTEX) || !defined(OPTIMIZER_ENABLED)
				float4 rim2ColorTex = POI2D_SAMPLER_PAN(_Rim2ColorTex, _MainTex, poiUV(poiMesh.uv[_Rim2ColorTexUV], _Rim2ColorTex_ST), _Rim2ColorTexPan);
				#else
				float4 rim2ColorTex = 1;
				#endif
				ApplyLiltoonRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, _Rim2Color, _Rim2IndirColor, rim2ColorTex, _Rim2MainStrength, _Rim2NormalStrength, _Rim2DirRange, _Rim2IndirRange, _Rim2FresnelPower, _Rim2BackfaceMask, _Rim2DirStrength, _Rim2Border, _Rim2Blur, _Rim2IndirBorder, _Rim2IndirBlur, _Rim2ShadowMask, _Rim2EnableLighting, _Rim2VRParallaxStrength, _Rim2GlobalMask, _Rim2GlobalMaskBlendType, _Rim2HueShiftEnabled, _Rim2HueShift, _Rim2HueShiftSpeed, _Rim2BlendMode);
				#endif
				#endif
				//endex
				
				//ifex _FXProximityColor==0
				if (_FXProximityColor)
				{
					float3 position = _FXProximityColorType ? poiMesh.worldPos : poiMesh.objectPosition;
					poiFragData.finalColor *= lerp(poiThemeColor(poiMods, _FXProximityColorMinColor.rgb, _FXProximityColorMinColorThemeIndex), poiThemeColor(poiMods, _FXProximityColorMaxColor.rgb, _FXProximityColorMaxColorThemeIndex), smoothstep(_FXProximityColorMinDistance, _FXProximityColorMaxDistance, distance(position, poiCam.worldPos)));
					
					if (_FXProximityColorBackFace)
					{
						poiFragData.finalColor = lerp(poiFragData.finalColor * _FXProximityColorMinColor.rgb, poiFragData.finalColor, saturate(poiMesh.isFrontFace));
					}
				}
				//endex
				
				//UNITY_BRANCH
				if (_IgnoreFog == 0)
				{
					UNITY_APPLY_FOG(i.fogCoord, poiFragData.finalColor);
				}
				
				poiFragData.alpha = _AlphaForceOpaque ? 1 : poiFragData.alpha;
				
				//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
				ApplyAlphaToCoverage(poiFragData, poiMesh);
				//endex
				
				//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
				applyDithering(poiFragData, poiCam);
				//endex
				
				poiFragData.finalColor += poiLight.finalLightAdd;
				
				if (_Mode == POI_MODE_OPAQUE)
				{
					poiFragData.alpha = 1;
				}
				
				clip(poiFragData.alpha - _Cutoff);
				
				if (_Mode == POI_MODE_CUTOUT && !_AlphaToCoverage)
				{
					poiFragData.alpha = 1;
				}
				
				if (_AddBlendOp == 4)
				{
					poiFragData.alpha = saturate(poiFragData.alpha * _AlphaBoostFA);
				}
				
				if (_Mode != POI_MODE_TRANSPARENT)
				{
					poiFragData.finalColor *= poiFragData.alpha;
				}
				
				//ifex _BSSEnabled!=1
				#ifdef POIBS_ENABLE
				poiFragData.finalColor += poiFragData.emission * poiMods.globalEmission;
				poiFragData.alpha = poiFragData.alpha * poiFragData.emission.z;
				poiFragData.emission = 0;
				
				//ifex _BSSBloomfog!=1
				#ifdef POIBS_BLOOMFOG
				float3 fogDistance = i.worldPos + - _WorldSpaceCameraPos;
				float4 fogCol = -float4(poiFragData.finalColor, 1) + tex2D(_BloomPrePassTexture, i.fogCoord.xy);
				fogCol.a = -poiFragData.alpha;
				
				#ifdef BSSBLOOMFOGTYPE_HEIGHT
				poiFragData.finalColor = poiFragData.finalColor + (((GetHeightFogIntensity(i.worldPos, _FogHeightOffset, _FogHeightScale) * GetFogIntensity(fogDistance, _FogStartOffset, _FogScale)) + 1) * fogCol.rgb);
				poiFragData.alpha = poiFragData.alpha + (((GetHeightFogIntensity(i.worldPos, _FogHeightOffset, _FogHeightScale) * GetFogIntensity(fogDistance, _FogStartOffset, _FogScale)) + 1) * fogCol.a);
				#else
				poiFragData.finalColor = poiFragData.finalColor + ((GetFogIntensity(fogDistance, _FogStartOffset, _FogScale) + 1) * fogCol.rgb);
				poiFragData.alpha = poiFragData.alpha + ((GetFogIntensity(fogDistance, _FogStartOffset, _FogScale) + 1) * fogCol.a);
				#endif
				#endif
				//endex
				#endif
				//endex
				
				return float4(poiFragData.finalColor, poiFragData.alpha) + POI_SAFE_RGB0;
			}
			
			ENDCG
		}
		
		//ifex _EnableOutlines!=1
		
		Pass
		{
			Name "Outline"
			Tags { "LightMode" = "ForwardBase" }
			
			Stencil
			{
				Ref [_OutlineStencilRef]
				ReadMask [_OutlineStencilReadMask]
				WriteMask [_OutlineStencilWriteMask]
				//ifex _OutlineStencilType==1
				Comp [_OutlineStencilCompareFunction]
				Pass [_OutlineStencilPassOp]
				Fail [_OutlineStencilFailOp]
				ZFail [_OutlineStencilZFailOp]
				//endex
				
				//ifex _OutlineStencilType==0
				CompBack [_OutlineStencilBackCompareFunction]
				PassBack [_OutlineStencilBackPassOp]
				FailBack [_OutlineStencilBackFailOp]
				ZFailBack [_OutlineStencilBackZFailOp]
				
				CompFront [_OutlineStencilFrontCompareFunction]
				PassFront [_OutlineStencilFrontPassOp]
				FailFront [_OutlineStencilFrontFailOp]
				ZFailFront [_OutlineStencilFrontZFailOp]
				//endex
			}
			
			/*
			ColorMask [_ColorMask]
			BlendOp [_BlendOp], [_BlendOpAlpha]
			Blend [_SrcBlend] [_DstBlend]
			ZWrite [_ZWrite]
			AlphaToMask [_AlphaToCoverage]
			Cull [_OutlineCull]
			*/
			AlphaToMask [_AlphaToCoverage]
			ZTest [_OutlineZTest]
			Cull [_OutlineCull]
			BlendOp [_OutlineBlendOp], [_OutlineBlendOpAlpha]
			Blend [_OutlineSrcBlend] [_OutlineDstBlend], [_OutlineSrcBlendAlpha] [_OutlineDstBlendAlpha]
			
			CGPROGRAM
			/*
			// Disable warnings we aren't interested in
			#if defined(UNITY_COMPILER_HLSL)
			#pragma warning(disable : 3205) // conversion of larger type to smaller
			#pragma warning(disable : 3568) // unknown pragma ignored
			#pragma warning(disable : 3571) // "pow(f,e) will not work for negative f"; however in majority of our calls to pow we know f is not negative
			#pragma warning(disable : 3206) // implicit truncation of vector type
			#endif
			*/
			#pragma target 5.0
			//ifex 0==0
			#pragma skip_optimizations d3d11
			//endex
			
			#pragma shader_feature_local _STOCHASTICMODE_DELIOT_HEITZ _STOCHASTICMODE_HEXTILE _STOCHASTICMODE_NONE
			
			//ifex _MainColorAdjustToggle==0
			#pragma shader_feature COLOR_GRADING_HDR
			//endex
			
			//#pragma shader_feature KEYWORD
			
			#pragma skip_variants LIGHTMAP_ON DYNAMICLIGHTMAP_ON LIGHTMAP_SHADOW_MIXING SHADOWS_SHADOWMASK DIRLIGHTMAP_COMBINED _MIXED_LIGHTING_SUBTRACTIVE
			#pragma skip_variants DECALS_OFF DECALS_3RT DECALS_4RT DECAL_SURFACE_GRADIENT _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3
			#pragma skip_variants _ADDITIONAL_LIGHT_SHADOWS
			#pragma skip_variants PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2
			#pragma skip_variants _SCREEN_SPACE_OCCLUSION
			
			//ifex _GlobalMaskTexturesEnable==0
			#pragma shader_feature_local POI_GLOBALMASK_TEXTURES
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#pragma shader_feature_local POI_UDIMDISCARD
			//endex
			
			//ifex _EnableDistortion==0
			#pragma shader_feature USER_LUT
			//endex
			
			//ifex _PoiParallax==0
			#pragma shader_feature_local POI_PARALLAX
			//endex
			
			//ifex _EnableAudioLink==0
			#pragma shader_feature_local POI_AUDIOLINK
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#pragma shader_feature_local POI_BLACKLIGHTMASKING
			//endex
			
			//ifex _DetailEnabled==0
			#pragma shader_feature FINALPASS
			//endex
			
			//ifex _VertexManipulationsEnabled==0
			#pragma shader_feature AUTO_EXPOSURE
			//endex
			
			//ifex _VertexGlitchingEnabled==0
			#pragma shader_feature_local POI_VERTEX_GLITCHING
			#pragma shader_feature_local POI_VERTEX_GLITCHING_TEXTURE
			//endex
			
			//ifex _EnableDepthBulge==0
			#pragma shader_feature_local POI_DEPTHBULGE
			//endex
			
			//ifex _BackFaceEnabled!=1
			#pragma shader_feature_local POI_BACKFACE
			//endex
			
			//ifex _RGBMaskEnabled==0
			#pragma shader_feature VIGNETTE
			#pragma shader_feature GEOM_TYPE_MESH
			//endex
			
			//ifex _LTCGIEnabled!=1
			#pragma shader_feature_local POI_LTCGI
			//endex
			
			//ifex _ShadingEnabled==0
			#pragma shader_feature_local VIGNETTE_MASKED
			#pragma shader_feature_local _LIGHTINGMODE_TEXTURERAMP _LIGHTINGMODE_MULTILAYER_MATH _LIGHTINGMODE_SHADEMAP _LIGHTINGMODE_REALISTIC _LIGHTINGMODE_WRAPPED _LIGHTINGMODE_SKIN _LIGHTINGMODE_FLAT _LIGHTINGMODE_CLOTH _LIGHTINGMODE_SDF
			//endex
			
			//ifex _DecalEnabled==0
			#pragma shader_feature GEOM_TYPE_BRANCH
			//endex
			//ifex _DecalEnabled1==0
			#pragma shader_feature GEOM_TYPE_BRANCH_DETAIL
			//endex
			//ifex _DecalEnabled2==0
			#pragma shader_feature GEOM_TYPE_FROND
			//endex
			//ifex _DecalEnabled3==0
			#pragma shader_feature DEPTH_OF_FIELD_COC_VIEW
			//endex
			
			//ifex _EnableDissolve==0
			#pragma shader_feature DISTORT
			//endex
			
			//ifex _EnableAniso==0
			#pragma shader_feature_local POI_ANISOTROPICS
			//endex
			
			//ifex _MatcapEnable==0
			#pragma shader_feature_local POI_MATCAP0
			#pragma shader_feature_local POI_MATCAP0_CUSTOM_NORMAL
			//endex
			//ifex _Matcap2Enable==0
			#pragma shader_feature COLOR_GRADING_HDR_3D
			#pragma shader_feature_local POI_MATCAP1_CUSTOM_NORMAL
			//endex
			//ifex _Matcap3Enable==0
			#pragma shader_feature_local POI_MATCAP2
			#pragma shader_feature_local POI_MATCAP2_CUSTOM_NORMAL
			//endex
			//ifex _Matcap4Enable==0
			#pragma shader_feature_local POI_MATCAP3
			#pragma shader_feature_local POI_MATCAP3_CUSTOM_NORMAL
			//endex
			
			//ifex _CubeMapEnabled==0
			#pragma shader_feature_local _CUBEMAP
			//endex
			
			//ifex _EnableALDecal==0
			#pragma shader_feature_local POI_AL_DECAL
			//endex
			
			//ifex _EnableVolumeColor==0
			#pragma shader_feature_local POI_AL_VOLUMECOLOR
			//endex
			
			//ifex _EnableFlipbook==0
			#pragma shader_feature _SUNDISK_HIGH_QUALITY
			//endex
			
			//ifex _EnableEmission==0
			#pragma shader_feature _EMISSION
			//endex
			//ifex _EnableEmission1==0
			#pragma shader_feature_local POI_EMISSION_1
			//endex
			//ifex _EnableEmission2==0
			#pragma shader_feature_local POI_EMISSION_2
			//endex
			//ifex _EnableEmission3==0
			#pragma shader_feature_local POI_EMISSION_3
			//endex
			
			//ifex _EnableRimLighting==0
			#pragma shader_feature_local _GLOSSYREFLECTIONS_OFF
			#pragma shader_feature_local _RIMSTYLE_POIYOMI _RIMSTYLE_UTS2 _RIMSTYLE_LILTOON
			//endex
			//ifex _EnableRim2Lighting==0
			#pragma shader_feature_local POI_RIM2
			#pragma shader_feature_local _RIM2STYLE_POIYOMI _RIM2STYLE_UTS2 _RIM2STYLE_LILTOON
			//endex
			
			//ifex _EnableDepthRimLighting==0
			#pragma shader_feature_local _POI_DEPTH_RIMLIGHT
			//endex
			
			//ifex _GlitterEnable==0
			#pragma shader_feature _SUNDISK_SIMPLE
			//endex
			
			//ifex _SubsurfaceScattering==0
			#pragma shader_feature_local POI_SUBSURFACESCATTERING
			//endex
			
			//ifex _MochieBRDF==0
			#pragma shader_feature_local MOCHIE_PBR
			//endex
			//ifex _ClearCoatBRDF==0
			#pragma shader_feature_local POI_CLEARCOAT
			//endex
			
			//ifex _EnableEnvironmentalRim==0
			#pragma shader_feature_local POI_ENVIRORIM
			//endex
			
			//ifex _StylizedSpecular==0
			#pragma shader_feature_local POI_STYLIZED_StylizedSpecular
			//endex
			
			//ifex _EnablePathing==0
			#pragma shader_feature_local POI_PATHING
			//endex
			
			//ifex _EnableMirrorOptions==0
			#pragma shader_feature_local POI_MIRROR
			//endex
			
			//ifex _EnableTouchGlow==0
			#pragma shader_feature GRAIN
			//endex
			
			//ifex _TextEnabled==0
			#pragma shader_feature EFFECT_BUMP
			//endex
			
			//ifex _PostProcess==0
			#pragma shader_feature_local POSTPROCESS
			//endex
			
			//ifex _PoiInternalParallax==0
			#pragma shader_feature_local POI_INTERNALPARALLAX
			//endex
			
			//ifex _NormalCorrect==0
			#pragma shader_feature_local POI_NORMALCORRECT
			//endex
			
			//ifex _VideoEffectsEnable==0
			#pragma shader_feature_local POI_VIDEO_EFFECTS
			//endex
			
			//ifex _BacklightEnabled!=1
			#pragma shader_feature_local POI_BACKLIGHT
			//endex
			
			//ifex _BSSEnabled!=1
			#pragma shader_feature_local POIBS_ENABLE
			//ifex _BSSBloomfog!=1
			#pragma shader_feature_local POIBS_BLOOMFOG
			#pragma shader_feature_local BSSBLOOMFOGTYPE_HEIGHT
			//endex
			//endex
			
			//ifex _VoronoiEnabled!=1
			#pragma shader_feature_local POI_VORONOI
			//endex
			
			#pragma multi_compile_fwdbase
			#pragma multi_compile_instancing
			#pragma multi_compile_fog
			#pragma multi_compile _ VERTEXLIGHT_ON
			#define POI_PASS_OUTLINE
			
			// UNITY Includes
			#include "UnityCG.cginc"
			#include "UnityStandardUtils.cginc"
			#include "AutoLight.cginc"
			#include "UnityLightingCommon.cginc"
			#include "UnityPBSLighting.cginc"
			#ifdef POI_PASS_META
			#include "UnityMetaPass.cginc"
			#endif
			#pragma vertex vert
			
			#pragma fragment frag
			
			#define DielectricSpec float4(0.04, 0.04, 0.04, 1.0 - 0.04)
			#define PI float(3.14159265359)
			#define Epsilon float(1e-10)
			
			#define POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, samplertex, coord, dx, dy) tex.SampleGrad(sampler##samplertex, coord, dx, dy)
			#define POI2D_SAMPLE_TEX2D_SAMPLERGRADD(tex, samp, uv, pan, dx, dy) tex.SampleGrad(samp, POI_PAN_UV(uv, pan), dx, dy)
			
			#define POI_PAN_UV(uv, pan) (uv + _Time.x * pan)
			#define POI2D_SAMPLER_PAN(tex, texSampler, uv, pan) (UNITY_SAMPLE_TEX2D_SAMPLER(tex, texSampler, POI_PAN_UV(uv, pan)))
			#define POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy) (POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, texSampler, POI_PAN_UV(uv, pan), dx, dy))
			#define POI2D_SAMPLER(tex, texSampler, uv) (UNITY_SAMPLE_TEX2D_SAMPLER(tex, texSampler, uv))
			#define POI_SAMPLE_1D_X(tex, samp, uv) tex.Sample(samp, float2(uv, 0.5))
			#define POI2D_SAMPLER_GRAD(tex, texSampler, uv, dx, dy) (POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, texSampler, uv, dx, dy))
			#define POI2D_SAMPLER_GRADD(tex, texSampler, uv, dx, dy) tex.SampleGrad(texSampler, uv, dx, dy)
			#define POI2D_PAN(tex, uv, pan) (tex2D(tex, POI_PAN_UV(uv, pan)))
			#define POI2D(tex, uv) (tex2D(tex, uv))
			#define POI_SAMPLE_TEX2D(tex, uv) (UNITY_SAMPLE_TEX2D(tex, uv))
			#define POI_SAMPLE_TEX2D_PAN(tex, uv, pan) (UNITY_SAMPLE_TEX2D(tex, POI_PAN_UV(uv, pan)))
			#define POI_SAMPLE_CUBE_LOD(tex, samp, uv, lod) texCUBElod(tex, float4(uv, 0, lod))
			
			#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
			#define POI_SAMPLE_SCREEN(tex, samp, uv)          tex.Sample(samp, float3(uv, unity_StereoEyeIndex))
			#else
			#define POI_SAMPLE_SCREEN(tex, samp, uv)          tex.Sample(samp, uv)
			#endif
			
			// When using, properties won't properly lock at optimize time; needs macro evaluation implemented
			// #define POI2D_MAINTEX_SAMPLER_PAN_INLINED(tex, poiMesh) (POI2D_SAMPLER_PAN(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan))
			
			#define POI_SAFE_RGB0 float4(mainTexture.rgb * .0001, 0)
			#define POI_SAFE_RGB1 float4(mainTexture.rgb * .0001, 1)
			#define POI_SAFE_RGBA mainTexture
			
			#if defined(UNITY_COMPILER_HLSL)
			#define PoiInitStruct(type, name) name = (type)0;
			#else
			#define PoiInitStruct(type, name)
			#endif
			
			#define POI_ERROR(poiMesh, gridSize) lerp(float3(1, 0, 1), float3(0, 0, 0), fmod(floor((poiMesh.worldPos.x) * gridSize) + floor((poiMesh.worldPos.y) * gridSize) + floor((poiMesh.worldPos.z) * gridSize), 2) == 0)
			#define POI_NAN (asfloat(-1))
			
			#define POI_MODE_OPAQUE 0
			#define POI_MODE_CUTOUT 1
			#define POI_MODE_FADE 2
			#define POI_MODE_TRANSPARENT 3
			#define POI_MODE_ADDITIVE 4
			#define POI_MODE_SOFTADDITIVE 5
			#define POI_MODE_MULTIPLICATIVE 6
			#define POI_MODE_2XMULTIPLICATIVE 7
			#define POI_MODE_TRANSCLIPPING 9
			
			/*
			Texture2D ;
			float4 _ST;
			float2 Pan;
			float UV;
			float Stochastic;
			
			[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos XZ, 5, Polar UV, 6, Distorted UV, 7 )]
			*/
			
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			// Map of where features in AudioLink are.
			#define ALPASS_DFT                      uint2(0, 4)   //Size: 128, 2
			#define ALPASS_WAVEFORM                 uint2(0, 6)   //Size: 128, 16
			#define ALPASS_AUDIOLINK                uint2(0, 0)   //Size: 128, 4
			#define ALPASS_AUDIOBASS                uint2(0, 0)   //Size: 128, 1
			#define ALPASS_AUDIOLOWMIDS             uint2(0, 1)   //Size: 128, 1
			#define ALPASS_AUDIOHIGHMIDS            uint2(0, 2)   //Size: 128, 1
			#define ALPASS_AUDIOTREBLE              uint2(0, 3)   //Size: 128, 1
			#define ALPASS_AUDIOLINKHISTORY         uint2(1, 0)   //Size: 127, 4
			#define ALPASS_GENERALVU                uint2(0, 22)  //Size: 12, 1
			#define ALPASS_CCINTERNAL               uint2(12, 22) //Size: 12, 2
			#define ALPASS_CCCOLORS                 uint2(25, 22) //Size: 11, 1
			#define ALPASS_CCSTRIP                  uint2(0, 24)  //Size: 128, 1
			#define ALPASS_CCLIGHTS                 uint2(0, 25)  //Size: 128, 2
			#define ALPASS_AUTOCORRELATOR           uint2(0, 27)  //Size: 128, 1
			#define ALPASS_GENERALVU_INSTANCE_TIME  uint2(2, 22)
			#define ALPASS_GENERALVU_LOCAL_TIME     uint2(3, 22)
			#define ALPASS_GENERALVU_NETWORK_TIME   uint2(4, 22)
			#define ALPASS_GENERALVU_PLAYERINFO     uint2(6, 22)
			// Added in version 2.5
			#define ALPASS_FILTEREDAUDIOLINK        uint2(0, 28)  //Size: 16, 4
			// Added in version 2.6
			#define ALPASS_CHRONOTENSITY            uint2(16, 28) //Size: 8, 4
			#define ALPASS_THEME_COLOR0             uint2(0, 23)
			#define ALPASS_THEME_COLOR1             uint2(1, 23)
			#define ALPASS_THEME_COLOR2             uint2(2, 23)
			#define ALPASS_THEME_COLOR3             uint2(3, 23)
			#define ALPASS_FILTEREDVU               uint2(24, 28) //Size: 4, 4
			#define ALPASS_FILTEREDVU_INTENSITY     uint2(24, 28) //Size: 4, 1
			#define ALPASS_FILTEREDVU_MARKER        uint2(24, 29) //Size: 4, 1
			
			// Some basic constants to use (Note, these should be compatible with
			// future version of AudioLink, but may change.
			#define AUDIOLINK_SAMPHIST              3069        // Internal use for algos, do not change.
			#define AUDIOLINK_SAMPLEDATA24          2046
			#define AUDIOLINK_EXPBINS               24
			#define AUDIOLINK_EXPOCT                10
			#define AUDIOLINK_ETOTALBINS (AUDIOLINK_EXPBINS * AUDIOLINK_EXPOCT)
			#define AUDIOLINK_WIDTH                 128
			#define AUDIOLINK_SPS                   48000       // Samples per second
			#define AUDIOLINK_ROOTNOTE              0
			#define AUDIOLINK_4BAND_FREQFLOOR       0.123
			#define AUDIOLINK_4BAND_FREQCEILING     1
			#define AUDIOLINK_BOTTOM_FREQUENCY      13.75
			#define AUDIOLINK_BASE_AMPLITUDE        2.5
			#define AUDIOLINK_DELAY_COEFFICIENT_MIN 0.3
			#define AUDIOLINK_DELAY_COEFFICIENT_MAX 0.9
			#define AUDIOLINK_DFT_Q                 4.0
			#define AUDIOLINK_TREBLE_CORRECTION     5.0
			
			// ColorChord constants
			#define COLORCHORD_EMAXBIN              192
			#define COLORCHORD_IIR_DECAY_1          0.90
			#define COLORCHORD_IIR_DECAY_2          0.85
			#define COLORCHORD_CONSTANT_DECAY_1     0.01
			#define COLORCHORD_CONSTANT_DECAY_2     0.0
			#define COLORCHORD_NOTE_CLOSEST         3.0
			#define COLORCHORD_NEW_NOTE_GAIN        8.0
			#define COLORCHORD_MAX_NOTES            10
			
			uniform float4               _AudioTexture_TexelSize;
			
			#ifdef SHADER_TARGET_SURFACE_ANALYSIS
			#define AUDIOLINK_STANDARD_INDEXING
			#endif
			
			// Mechanism to index into texture.
			#ifdef AUDIOLINK_STANDARD_INDEXING
			sampler2D _AudioTexture;
			#define AudioLinkData(xycoord) tex2Dlod(_AudioTexture, float4(uint2(xycoord) * _AudioTexture_TexelSize.xy, 0, 0))
			#else
			uniform Texture2D<float4> _AudioTexture;
			SamplerState sampler_AudioTexture;
			#define AudioLinkData(xycoord) _AudioTexture[uint2(xycoord)]
			#endif
			uniform sampler2D _Stored;
			uniform float4 _Stored_TexelSize;
			#endif
			//endex
			
			float _GrabMode;
			float _Mode;
			
			float _StochasticDeliotHeitzDensity;
			float _StochasticHexGridDensity;
			float _StochasticHexRotationStrength;
			float _StochasticHexFallOffContrast;
			float _StochasticHexFallOffPower;
			
			#if defined(PROP_LIGHTINGAOMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _LightingAOMaps;
			#endif
			float4 _LightingAOMaps_ST;
			float2 _LightingAOMapsPan;
			float _LightingAOMapsUV;
			float _LightDataAOStrengthR;
			float _LightDataAOStrengthG;
			float _LightDataAOStrengthB;
			float _LightDataAOStrengthA;
			float _LightDataAOGlobalMaskR;
			float _LightDataAOGlobalMaskBlendTypeR;
			
			#if defined(PROP_LIGHTINGDETAILSHADOWMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _LightingDetailShadowMaps;
			#endif
			float4 _LightingDetailShadowMaps_ST;
			float2 _LightingDetailShadowMapsPan;
			float _LightingDetailShadowMapsUV;
			float _LightingDetailShadowStrengthR;
			float _LightingDetailShadowStrengthG;
			float _LightingDetailShadowStrengthB;
			float _LightingDetailShadowStrengthA;
			float _LightingAddDetailShadowStrengthR;
			float _LightingAddDetailShadowStrengthG;
			float _LightingAddDetailShadowStrengthB;
			float _LightingAddDetailShadowStrengthA;
			float _LightDataDetailShadowGlobalMaskR;
			float _LightDataDetailShadowGlobalMaskBlendTypeR;
			
			#if defined(PROP_LIGHTINGSHADOWMASKS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _LightingShadowMasks;
			#endif
			float4 _LightingShadowMasks_ST;
			float2 _LightingShadowMasksPan;
			float _LightingShadowMasksUV;
			float _LightingShadowMaskStrengthR;
			float _LightingShadowMaskStrengthG;
			float _LightingShadowMaskStrengthB;
			float _LightingShadowMaskStrengthA;
			float _LightDataShadowMaskGlobalMaskR;
			float _LightDataShadowMaskGlobalMaskBlendTypeR;
			
			// Lighting Data
			float _Unlit_Intensity;
			float _LightingColorMode;
			float _LightingMapMode;
			float _LightingDirectionMode;
			float3 _LightngForcedDirection;
			float _LightingViewDirOffsetPitch;
			float _LightingViewDirOffsetYaw;
			float _LightingIndirectUsesNormals;
			float _LightingCapEnabled;
			float _LightingCap;
			float _LightingForceColorEnabled;
			float3 _LightingForcedColor;
			float _LightingForcedColorThemeIndex;
			float _LightingCastedShadows;
			float _LightingMonochromatic;
			float _LightingMinLightBrightness;
			// Additive Lighting Data
			float _LightingAdditiveEnable;
			float _LightingAdditiveLimited;
			float _LightingAdditiveLimit;
			float _LightingAdditiveCastedShadows;
			float _LightingAdditiveMonochromatic;
			float _LightingAdditivePassthrough;
			float _DisableDirectionalInAdd;
			float _LightingVertexLightingEnabled;
			float _LightingMirrorVertexLightingEnabled;
			// Lighting Data Debug
			float _LightDataDebugEnabled;
			float _LightingDebugVisualize;
			
			float _IgnoreFog;
			float _RenderingReduceClipDistance;
			int _FlipBackfaceNormals;
			float _AddBlendOp;
			float _Cull;
			
			float4 _Color;
			float _ColorThemeIndex;
			UNITY_DECLARE_TEX2D(_MainTex);
			UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
			float _MainPixelMode;
			float4 _MainTex_ST;
			float2 _MainTexPan;
			float _MainTexUV;
			float4 _MainTex_TexelSize;
			float _MainTexStochastic;
			#if defined(PROP_BUMPMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BumpMap;
			#endif
			float4 _BumpMap_ST;
			float2 _BumpMapPan;
			float _BumpMapUV;
			float _BumpScale;
			float _BumpMapStochastic;
			#if defined(PROP_ALPHAMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AlphaMask;
			float4 _AlphaMask_ST;
			float2 _AlphaMaskPan;
			float _AlphaMaskUV;
			float _AlphaMaskInvert;
			float _MainAlphaMaskMode;
			float _AlphaMaskScale;
			float _AlphaMaskValue;
			#endif
			float _Cutoff;
			//ifex _MainColorAdjustToggle==0
			#ifdef COLOR_GRADING_HDR
			float _MainColorAdjustToggle;
			#if defined(PROP_MAINCOLORADJUSTTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MainColorAdjustTexture;
			#endif
			float4 _MainColorAdjustTexture_ST;
			float2 _MainColorAdjustTexturePan;
			float _MainColorAdjustTextureUV;
			float _MainHueShiftToggle;
			float _MainHueShiftReplace;
			float _MainHueShift;
			float _MainHueShiftSpeed;
			float _Saturation;
			float _MainBrightness;
			
			float _MainHueALCTEnabled;
			float _MainALHueShiftBand;
			float _MainALHueShiftCTIndex;
			float _MainHueALMotionSpeed;
			
			float _MainHueGlobalMask;
			float _MainHueGlobalMaskBlendType;
			float _MainSaturationGlobalMask;
			float _MainSaturationGlobalMaskBlendType;
			float _MainBrightnessGlobalMask;
			float _MainBrightnessGlobalMaskBlendType;
			
			#if defined(PROP_MAINGRADATIONTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MainGradationTex;
			#endif
			float _ColorGradingToggle;
			float _MainGradationStrength;
			#endif
			//endex
			
			SamplerState sampler_linear_clamp;
			SamplerState sampler_linear_repeat;
			SamplerState sampler_trilinear_repeat;
			
			float _AlphaForceOpaque;
			float _AlphaMod;
			float _AlphaPremultiply;
			float _AlphaBoostFA;
			//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
			float _AlphaToCoverage;
			float _AlphaSharpenedA2C;
			float _AlphaMipScale;
			//endex
			
			//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
			float _AlphaDithering;
			float _AlphaDitherGradient;
			float _AlphaDitherBias;
			//endex
			
			//ifex _AlphaDistanceFade==0 && isNotAnimated(_AlphaDistanceFade)
			float _AlphaDistanceFade;
			float _AlphaDistanceFadeType;
			float _AlphaDistanceFadeMinAlpha;
			float _AlphaDistanceFadeMaxAlpha;
			float _AlphaDistanceFadeMin;
			float _AlphaDistanceFadeMax;
			float _AlphaDistanceFadeGlobalMask;
			float _AlphaDistanceFadeGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaFresnel==0 && isNotAnimated(_AlphaFresnel)
			float _AlphaFresnel;
			float _AlphaFresnelAlpha;
			float _AlphaFresnelSharpness;
			float _AlphaFresnelWidth;
			float _AlphaFresnelInvert;
			float _AlphaFresnelGlobalMask;
			float _AlphaFresnelGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaAngular==0 && isNotAnimated(_AlphaAngular)
			float _AlphaAngular;
			float _AngleType;
			float _AngleCompareTo;
			float3 _AngleForwardDirection;
			float _CameraAngleMin;
			float _CameraAngleMax;
			float _ModelAngleMin;
			float _ModelAngleMax;
			float _AngleMinAlpha;
			float _AlphaAngularGlobalMask;
			float _AlphaAngularGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaAudioLinkEnabled==0 && isNotAnimated(_AlphaAudioLinkEnabled)
			float _AlphaAudioLinkEnabled;
			float2 _AlphaAudioLinkAddRange;
			float _AlphaAudioLinkAddBand;
			//endex
			
			float _AlphaGlobalMask;
			float _AlphaGlobalMaskBlendType;
			
			//ifex _EnableOutlines!=1
			#ifdef POI_PASS_OUTLINE
			// outline Vertex Options
			float _OutlineExpansionMode;
			float4 _OutlinePersonaDirection;
			float4 _OutlineDropShadowOffset;
			float _OutlineUseVertexColorNormals;
			float _OutlineVertexColorMask;
			float _OutlineVertexColorMaskStrength;
			float _OutlineFixedSize;
			float _OutlineFixWidth;
			float _EnableOutlines;
			float _OutlinesMaxDistance;
			float _LineWidth;
			float _OutlineEmission;
			float4 _LineColor;
			float _OutlineOverrideAlpha;
			float _OutlineSpace;
			texture2D _OutlineTexture; //TODO make this dynamically not read for lock in
			float4 _OutlineTexture_ST;
			float2 _OutlineTexturePan;
			float _OutlineTextureUV;
			float4 _OutlineFadeDistance;
			float4 _OutlineGlobalPan;
			sampler2D _OutlineMask;
			float4 _OutlineMask_ST;
			float2 _OutlineMaskPan;
			float _OutlineMaskUV;
			float _OutlineMaskChannel;
			float _OutlineRimLightBlend;
			float _OutlineLit;
			float _OutlineTintMix;
			float4 _OutlineTexHSVG;
			float _OutlineHueShift;
			float _OutlineHueOffset;
			float _OutlineHueOffsetSpeed;
			float _PoiUTSStyleOutlineBlend;
			float _OutlineAlphaDistanceFade;
			float _OutlineAlphaDistanceFadeType;
			float _OutlineAlphaDistanceFadeMinAlpha;
			float _OutlineAlphaDistanceFadeMaxAlpha;
			float _OutlineAlphaDistanceFadeMin;
			float _OutlineAlphaDistanceFadeMax;
			
			float _OutlineShadowStrength;
			float _LineColorThemeIndex;
			float _Offset_Z;
			float _OutlineClipAtZeroWidth;
			#ifdef POI_AUDIOLINK
			float _AudioLinkOutlineSizeBand;
			float2 _AudioLinkOutlineSize;
			float _AudioLinkOutlineEmissionBand;
			float2 _AudioLinkOutlineEmission;
			float _AudioLinkOutlineColorBand;
			float4 _AudioLinkOutlineColor;
			float _OutlineALColorEnabled;
			float4 _AudioLinkOutlineColorMod;
			#endif
			#endif
			//endex
			
			float4 _GlobalThemeColor0;
			float4 _GlobalThemeColor1;
			float4 _GlobalThemeColor2;
			float4 _GlobalThemeColor3;
			float _GlobalThemeHue0;
			float _GlobalThemeHue1;
			float _GlobalThemeHue2;
			float _GlobalThemeHue3;
			float _GlobalThemeHueSpeed0;
			float _GlobalThemeHueSpeed1;
			float _GlobalThemeHueSpeed2;
			float _GlobalThemeHueSpeed3;
			float _GlobalThemeSaturation0;
			float _GlobalThemeSaturation1;
			float _GlobalThemeSaturation2;
			float _GlobalThemeSaturation3;
			float _GlobalThemeValue0;
			float _GlobalThemeValue1;
			float _GlobalThemeValue2;
			float _GlobalThemeValue3;
			
			//ifex _GlobalMaskTexturesEnable==0
			#ifdef POI_GLOBALMASK_TEXTURES
			#if defined(PROP_GLOBALMASKTEXTURE0) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture0;
			#endif
			float4 _GlobalMaskTexture0_ST;
			float2 _GlobalMaskTexture0Pan;
			float _GlobalMaskTexture0UV;
			int _GlobalMaskTexture0Split;
			float4 _GlobalMaskTexture0SplitTilingOffset_G;
			float4 _GlobalMaskTexture0SplitPan_G;
			float4 _GlobalMaskTexture0SplitTilingOffset_B;
			float4 _GlobalMaskTexture0SplitPan_B;
			float4 _GlobalMaskTexture0SplitTilingOffset_A;
			float4 _GlobalMaskTexture0SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture1;
			#endif
			float4 _GlobalMaskTexture1_ST;
			float2 _GlobalMaskTexture1Pan;
			float _GlobalMaskTexture1UV;
			int _GlobalMaskTexture1Split;
			float4 _GlobalMaskTexture1SplitTilingOffset_G;
			float4 _GlobalMaskTexture1SplitPan_G;
			float4 _GlobalMaskTexture1SplitTilingOffset_B;
			float4 _GlobalMaskTexture1SplitPan_B;
			float4 _GlobalMaskTexture1SplitTilingOffset_A;
			float4 _GlobalMaskTexture1SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture2;
			#endif
			float4 _GlobalMaskTexture2_ST;
			float2 _GlobalMaskTexture2Pan;
			float _GlobalMaskTexture2UV;
			int _GlobalMaskTexture2Split;
			float4 _GlobalMaskTexture2SplitTilingOffset_G;
			float4 _GlobalMaskTexture2SplitPan_G;
			float4 _GlobalMaskTexture2SplitTilingOffset_B;
			float4 _GlobalMaskTexture2SplitPan_B;
			float4 _GlobalMaskTexture2SplitTilingOffset_A;
			float4 _GlobalMaskTexture2SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE3) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture3;
			#endif
			float4 _GlobalMaskTexture3_ST;
			float2 _GlobalMaskTexture3Pan;
			float _GlobalMaskTexture3UV;
			int _GlobalMaskTexture3Split;
			float4 _GlobalMaskTexture3SplitTilingOffset_G;
			float4 _GlobalMaskTexture3SplitPan_G;
			float4 _GlobalMaskTexture3SplitTilingOffset_B;
			float4 _GlobalMaskTexture3SplitPan_B;
			float4 _GlobalMaskTexture3SplitTilingOffset_A;
			float4 _GlobalMaskTexture3SplitPan_A;
			#endif
			//endex
			//ifex _GlobalMaskOptionsEnable==0
			float _GlobalMaskOptionsEnable;
			int _GlobalMaskOptionsType;
			
			//ifex _GlobalMaskOptionsType!=0
			float _GlobalMaskSlider_0;
			float _GlobalMaskSlider_1;
			float _GlobalMaskSlider_2;
			float _GlobalMaskSlider_3;
			float _GlobalMaskSlider_4;
			float _GlobalMaskSlider_5;
			float _GlobalMaskSlider_6;
			float _GlobalMaskSlider_7;
			float _GlobalMaskSlider_8;
			float _GlobalMaskSlider_9;
			float _GlobalMaskSlider_10;
			float _GlobalMaskSlider_11;
			float _GlobalMaskSlider_12;
			float _GlobalMaskSlider_13;
			float _GlobalMaskSlider_14;
			float _GlobalMaskSlider_15;
			//endex
			
			//ifex _GlobalMaskOptionsType!=1
			float2 _GlobalMaskMinMaxSlider_0;
			float2 _GlobalMaskMinMaxSlider_1;
			float2 _GlobalMaskMinMaxSlider_2;
			float2 _GlobalMaskMinMaxSlider_3;
			float2 _GlobalMaskMinMaxSlider_4;
			float2 _GlobalMaskMinMaxSlider_5;
			float2 _GlobalMaskMinMaxSlider_6;
			float2 _GlobalMaskMinMaxSlider_7;
			float2 _GlobalMaskMinMaxSlider_8;
			float2 _GlobalMaskMinMaxSlider_9;
			float2 _GlobalMaskMinMaxSlider_10;
			float2 _GlobalMaskMinMaxSlider_11;
			float2 _GlobalMaskMinMaxSlider_12;
			float2 _GlobalMaskMinMaxSlider_13;
			float2 _GlobalMaskMinMaxSlider_14;
			float2 _GlobalMaskMinMaxSlider_15;
			//endex
			
			//ifex _GlobalMaskOptionsType!=2
			int _GlobalMaskToggleOn_0;
			int _GlobalMaskToggleOff_0;
			int _GlobalMaskToggleOn_1;
			int _GlobalMaskToggleOff_1;
			int _GlobalMaskToggleOn_2;
			int _GlobalMaskToggleOff_2;
			int _GlobalMaskToggleOn_3;
			int _GlobalMaskToggleOff_3;
			int _GlobalMaskToggleOn_4;
			int _GlobalMaskToggleOff_4;
			int _GlobalMaskToggleOn_5;
			int _GlobalMaskToggleOff_5;
			int _GlobalMaskToggleOn_6;
			int _GlobalMaskToggleOff_6;
			int _GlobalMaskToggleOn_7;
			int _GlobalMaskToggleOff_7;
			int _GlobalMaskToggleOn_8;
			int _GlobalMaskToggleOff_8;
			int _GlobalMaskToggleOn_9;
			int _GlobalMaskToggleOff_9;
			int _GlobalMaskToggleOn_10;
			int _GlobalMaskToggleOff_10;
			int _GlobalMaskToggleOn_11;
			int _GlobalMaskToggleOff_11;
			int _GlobalMaskToggleOn_12;
			int _GlobalMaskToggleOff_12;
			int _GlobalMaskToggleOn_13;
			int _GlobalMaskToggleOff_13;
			int _GlobalMaskToggleOn_14;
			int _GlobalMaskToggleOff_14;
			int _GlobalMaskToggleOn_15;
			int _GlobalMaskToggleOff_15;
			//endex
			//endex
			//ifex _GlobalMaskModifiersBackfaceEnable==0
			float _GlobalMaskModifiersBackfaceEnable;
			float _GlobalMaskBackface_0;
			float _GlobalMaskBackface_1;
			float _GlobalMaskBackface_2;
			float _GlobalMaskBackface_3;
			float _GlobalMaskBackface_4;
			float _GlobalMaskBackface_5;
			float _GlobalMaskBackface_6;
			float _GlobalMaskBackface_7;
			float _GlobalMaskBackface_8;
			float _GlobalMaskBackface_9;
			float _GlobalMaskBackface_10;
			float _GlobalMaskBackface_11;
			float _GlobalMaskBackface_12;
			float _GlobalMaskBackface_13;
			float _GlobalMaskBackface_14;
			float _GlobalMaskBackface_15;
			//endex
			
			//ifex _GlobalMaskModifiersMirrorEnable==0
			float _GlobalMaskModifiersMirrorEnable;
			float _GlobalMaskMirrorVisibilityMode;
			float _GlobalMaskMirror_0;
			float _GlobalMaskMirror_1;
			float _GlobalMaskMirror_2;
			float _GlobalMaskMirror_3;
			float _GlobalMaskMirror_4;
			float _GlobalMaskMirror_5;
			float _GlobalMaskMirror_6;
			float _GlobalMaskMirror_7;
			float _GlobalMaskMirror_8;
			float _GlobalMaskMirror_9;
			float _GlobalMaskMirror_10;
			float _GlobalMaskMirror_11;
			float _GlobalMaskMirror_12;
			float _GlobalMaskMirror_13;
			float _GlobalMaskMirror_14;
			float _GlobalMaskMirror_15;
			//endex
			
			//ifex _GlobalMaskModifiersCameraEnable==0
			float _GlobalMaskModifiersCameraEnable;
			float _GlobalMaskCamera_0;
			float _GlobalMaskCamera_1;
			float _GlobalMaskCamera_2;
			float _GlobalMaskCamera_3;
			float _GlobalMaskCamera_4;
			float _GlobalMaskCamera_5;
			float _GlobalMaskCamera_6;
			float _GlobalMaskCamera_7;
			float _GlobalMaskCamera_8;
			float _GlobalMaskCamera_9;
			float _GlobalMaskCamera_10;
			float _GlobalMaskCamera_11;
			float _GlobalMaskCamera_12;
			float _GlobalMaskCamera_13;
			float _GlobalMaskCamera_14;
			float _GlobalMaskCamera_15;
			//endex
			
			//ifex _GlobalMaskModifiersDistanceEnable==0
			int _GlobalMaskModifiersDistanceEnable;
			
			//ifex _GlobalMaskDistanceEnable_0==0
			int _GlobalMaskDistanceEnable_0;
			int _GlobalMaskDistanceType_0;
			float _GlobalMaskDistanceMin_0;
			float _GlobalMaskDistanceMax_0;
			float _GlobalMaskDistanceMinAlpha_0;
			float _GlobalMaskDistanceMaxAlpha_0;
			int _GlobalMaskDistanceBlendType_0;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_1==0
			int _GlobalMaskDistanceEnable_1;
			int _GlobalMaskDistanceType_1;
			float _GlobalMaskDistanceMin_1;
			float _GlobalMaskDistanceMax_1;
			float _GlobalMaskDistanceMinAlpha_1;
			float _GlobalMaskDistanceMaxAlpha_1;
			int _GlobalMaskDistanceBlendType_1;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_2==0
			int _GlobalMaskDistanceEnable_2;
			int _GlobalMaskDistanceType_2;
			float _GlobalMaskDistanceMin_2;
			float _GlobalMaskDistanceMax_2;
			float _GlobalMaskDistanceMinAlpha_2;
			float _GlobalMaskDistanceMaxAlpha_2;
			int _GlobalMaskDistanceBlendType_2;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_3==0
			int _GlobalMaskDistanceEnable_3;
			int _GlobalMaskDistanceType_3;
			float _GlobalMaskDistanceMin_3;
			float _GlobalMaskDistanceMax_3;
			float _GlobalMaskDistanceMinAlpha_3;
			float _GlobalMaskDistanceMaxAlpha_3;
			int _GlobalMaskDistanceBlendType_3;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_4==0
			int _GlobalMaskDistanceEnable_4;
			int _GlobalMaskDistanceType_4;
			float _GlobalMaskDistanceMin_4;
			float _GlobalMaskDistanceMax_4;
			float _GlobalMaskDistanceMinAlpha_4;
			float _GlobalMaskDistanceMaxAlpha_4;
			int _GlobalMaskDistanceBlendType_4;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_5==0
			int _GlobalMaskDistanceEnable_5;
			int _GlobalMaskDistanceType_5;
			float _GlobalMaskDistanceMin_5;
			float _GlobalMaskDistanceMax_5;
			float _GlobalMaskDistanceMinAlpha_5;
			float _GlobalMaskDistanceMaxAlpha_5;
			int _GlobalMaskDistanceBlendType_5;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_6==0
			int _GlobalMaskDistanceEnable_6;
			int _GlobalMaskDistanceType_6;
			float _GlobalMaskDistanceMin_6;
			float _GlobalMaskDistanceMax_6;
			float _GlobalMaskDistanceMinAlpha_6;
			float _GlobalMaskDistanceMaxAlpha_6;
			int _GlobalMaskDistanceBlendType_6;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_7==0
			int _GlobalMaskDistanceEnable_7;
			int _GlobalMaskDistanceType_7;
			float _GlobalMaskDistanceMin_7;
			float _GlobalMaskDistanceMax_7;
			float _GlobalMaskDistanceMinAlpha_7;
			float _GlobalMaskDistanceMaxAlpha_7;
			int _GlobalMaskDistanceBlendType_7;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_8==0
			int _GlobalMaskDistanceEnable_8;
			int _GlobalMaskDistanceType_8;
			float _GlobalMaskDistanceMin_8;
			float _GlobalMaskDistanceMax_8;
			float _GlobalMaskDistanceMinAlpha_8;
			float _GlobalMaskDistanceMaxAlpha_8;
			int _GlobalMaskDistanceBlendType_8;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_9==0
			int _GlobalMaskDistanceEnable_9;
			int _GlobalMaskDistanceType_9;
			float _GlobalMaskDistanceMin_9;
			float _GlobalMaskDistanceMax_9;
			float _GlobalMaskDistanceMinAlpha_9;
			float _GlobalMaskDistanceMaxAlpha_9;
			int _GlobalMaskDistanceBlendType_9;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_10==0
			int _GlobalMaskDistanceEnable_10;
			int _GlobalMaskDistanceType_10;
			float _GlobalMaskDistanceMin_10;
			float _GlobalMaskDistanceMax_10;
			float _GlobalMaskDistanceMinAlpha_10;
			float _GlobalMaskDistanceMaxAlpha_10;
			int _GlobalMaskDistanceBlendType_10;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_11==0
			int _GlobalMaskDistanceEnable_11;
			int _GlobalMaskDistanceType_11;
			float _GlobalMaskDistanceMin_11;
			float _GlobalMaskDistanceMax_11;
			float _GlobalMaskDistanceMinAlpha_11;
			float _GlobalMaskDistanceMaxAlpha_11;
			int _GlobalMaskDistanceBlendType_11;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_12==0
			int _GlobalMaskDistanceEnable_12;
			int _GlobalMaskDistanceType_12;
			float _GlobalMaskDistanceMin_12;
			float _GlobalMaskDistanceMax_12;
			float _GlobalMaskDistanceMinAlpha_12;
			float _GlobalMaskDistanceMaxAlpha_12;
			int _GlobalMaskDistanceBlendType_12;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_13==0
			int _GlobalMaskDistanceEnable_13;
			int _GlobalMaskDistanceType_13;
			float _GlobalMaskDistanceMin_13;
			float _GlobalMaskDistanceMax_13;
			float _GlobalMaskDistanceMinAlpha_13;
			float _GlobalMaskDistanceMaxAlpha_13;
			int _GlobalMaskDistanceBlendType_13;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_14==0
			int _GlobalMaskDistanceEnable_14;
			int _GlobalMaskDistanceType_14;
			float _GlobalMaskDistanceMin_14;
			float _GlobalMaskDistanceMax_14;
			float _GlobalMaskDistanceMinAlpha_14;
			float _GlobalMaskDistanceMaxAlpha_14;
			int _GlobalMaskDistanceBlendType_14;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_15==0
			int _GlobalMaskDistanceEnable_15;
			int _GlobalMaskDistanceType_15;
			float _GlobalMaskDistanceMin_15;
			float _GlobalMaskDistanceMax_15;
			float _GlobalMaskDistanceMinAlpha_15;
			float _GlobalMaskDistanceMaxAlpha_15;
			int _GlobalMaskDistanceBlendType_15;
			//endex
			//endex
			
			int _GlobalMaskVertexColorLinearSpace;
			//ifex _GlobalMaskVertexColorRed==0
			int _GlobalMaskVertexColorRed;
			int _GlobalMaskVertexColorRedBlendType;
			//endex
			//ifex _GlobalMaskVertexColorGreen==0
			int _GlobalMaskVertexColorGreen;
			int _GlobalMaskVertexColorGreenBlendType;
			//endex
			//ifex _GlobalMaskVertexColorBlue==0
			int _GlobalMaskVertexColorBlue;
			int _GlobalMaskVertexColorBlueBlendType;
			//endex
			//ifex _GlobalMaskVertexColorAlpha==0
			int _GlobalMaskVertexColorAlpha;
			int _GlobalMaskVertexColorAlphaBlendType;
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#ifdef POI_UDIMDISCARD
			float _UDIMDiscardMode;
			float _UDIMDiscardUV;
			float _UDIMDiscardRow3_0;
			float _UDIMDiscardRow3_1;
			float _UDIMDiscardRow3_2;
			float _UDIMDiscardRow3_3;
			float _UDIMDiscardRow2_0;
			float _UDIMDiscardRow2_1;
			float _UDIMDiscardRow2_2;
			float _UDIMDiscardRow2_3;
			float _UDIMDiscardRow1_0;
			float _UDIMDiscardRow1_1;
			float _UDIMDiscardRow1_2;
			float _UDIMDiscardRow1_3;
			float _UDIMDiscardRow0_0;
			float _UDIMDiscardRow0_1;
			float _UDIMDiscardRow0_2;
			float _UDIMDiscardRow0_3;
			#endif
			//endex
			
			//ifex _EnableDistortion==0
			#ifdef USER_LUT
			#if defined(PROP_DISTORTIONFLOWTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionFlowTexture;
			float4 _DistortionFlowTexture_ST;
			float2 _DistortionFlowTexturePan;
			float _DistortionFlowTextureUV;
			#endif
			
			#if defined(PROP_DISTORTIONFLOWTEXTURE1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionFlowTexture1;
			float4 _DistortionFlowTexture1_ST;
			float2 _DistortionFlowTexture1Pan;
			float _DistortionFlowTexture1UV;
			#endif
			
			#if defined(PROP_DISTORTIONMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionMask;
			float4 _DistortionMask_ST;
			float2 _DistortionMaskPan;
			float _DistortionMaskUV;
			float _DistortionMaskChannel;
			#endif
			
			float _DistortionUvToDistort;
			float _DistortionStrength;
			float _DistortionStrength1;
			
			#ifdef POI_AUDIOLINK
			half _EnableDistortionAudioLink;
			half2 _DistortionStrengthAudioLink;
			half _DistortionStrengthAudioLinkBand;
			half2 _DistortionStrength1AudioLink;
			half _DistortionStrength1AudioLinkBand;
			#endif
			#endif
			//endex
			float _StereoEnabled;
			float _PolarUV;
			float2 _PolarCenter;
			float _PolarRadialScale;
			float _PolarLengthScale;
			float _PolarSpiralPower;
			float _PanoUseBothEyes;
			
			float _UVModWorldPos0;
			float _UVModWorldPos1;
			float _UVModLocalPos0;
			float _UVModLocalPos1;
			
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			float _AudioLinkDelay;
			float _AudioLinkAnimToggle;
			
			float _AudioLinkSmoothingBass;
			float _AudioLinkSmoothingLowMid;
			float _AudioLinkSmoothingHighMid;
			float _AudioLinkSmoothingTreble;
			
			float _DebugWaveform;
			float _DebugDFT;
			float _DebugBass;
			float _DebugLowMids;
			float _DebugHighMids;
			float _DebugTreble;
			float _DebugCCColors;
			float _DebugCCStrip;
			float _DebugCCLights;
			float _DebugAutocorrelator;
			float _DebugChronotensity;
			float _AudioLinkCCStripY;
			
			float _AudioLinkBandOverridesEnabled;
			float4 _AudioLinkBandOverrideSliders;
			#endif
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#ifdef POI_BLACKLIGHTMASKING
			float _BlackLightMasking0Key;
			float2 _BlackLightMasking0Range;
			float _BlackLightMasking0GlobalMaskIndex;
			float _BlackLightMasking0GlobalMaskBlendType;
			
			float _BlackLightMasking1Key;
			float2 _BlackLightMasking1Range;
			float _BlackLightMasking1GlobalMaskIndex;
			float _BlackLightMasking1GlobalMaskBlendType;
			
			float _BlackLightMasking2Key;
			float2 _BlackLightMasking2Range;
			float _BlackLightMasking2GlobalMaskIndex;
			float _BlackLightMasking2GlobalMaskBlendType;
			
			float _BlackLightMasking3Key;
			float2 _BlackLightMasking3Range;
			float _BlackLightMasking3GlobalMaskIndex;
			float _BlackLightMasking3GlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _VertexManipulationsEnabled==0
			#ifdef AUTO_EXPOSURE
			float4 _VertexManipulationLocalTranslation;
			float4 _VertexManipulationLocalRotation;
			float3 _VertexManipulationLocalRotationSpeed;
			float4 _VertexManipulationLocalScale;
			float4 _VertexManipulationWorldTranslation;
			float _VertexManipulationHeight;
			sampler2D _VertexManipulationHeightMask;
			float4 _VertexManipulationHeightMask_ST;
			float2 _VertexManipulationHeightMaskPan;
			float _VertexManipulationHeightMaskUV;
			float _VertexManipulationHeightMaskChannel;
			float _VertexManipulationHeightBias;
			float _VertexRoundingEnabled;
			int _VertexRoundingSpace;
			float _VertexRoundingDivision;
			
			//AL
			float _VertexAudioLinkEnabled;
			float3 _VertexLocalTranslationALMin;
			float3 _VertexLocalTranslationALMax;
			float _VertexLocalTranslationALBand;
			
			float3 _VertexLocalRotationAL;
			float _VertexLocalRotationALBand;
			
			float3 _VertexLocalRotationCTALSpeed;
			float _VertexLocalRotationCTALBandX;
			float _VertexLocalRotationCTALBandY;
			float _VertexLocalRotationCTALBandZ;
			float _VertexLocalRotationCTALTypeX;
			float _VertexLocalRotationCTALTypeY;
			float _VertexLocalRotationCTALTypeZ;
			
			float4 _VertexLocalScaleALMin;
			float4 _VertexLocalScaleALMax;
			float _VertexLocalScaleALBand;
			
			float3 _VertexWorldTranslationALMin;
			float3 _VertexWorldTranslationALMax;
			float _VertexWorldTranslationALBand;
			
			float2 _VertexManipulationHeightAL;
			float _VertexManipulationHeightBand;
			
			float2 _VertexRoundingRangeAL;
			float _VertexRoundingRangeBand;
			
			float _VertexBarrelMode;
			float _VertexBarrelWidth;
			float _VertexBarrelAlpha;
			float _VertexBarrelHeight;
			
			float _VertexSphereMode;
			float _VertexSphereRadius;
			float _VertexSphereHeight;
			float _VertexSphereAlpha;
			float4 _VertexSphereCenter;
			
			float _VertexTornadoMode;
			float _VertexTornadoRadius;
			float _VertexTornadoSpeed;
			float _VertexTornadoIntensity;
			float _VertexTornadoBaseHeight;
			float _VertexTornadoTopHeight;
			
			float _VertexSpectrumMotion;
			float3 _VertexSpectrumOffsetMin;
			float3 _VertexSpectrumOffsetMax;
			float _VertexSpectrumUV;
			float _VertexSpectrumUVDirection;
			#endif
			//endex
			
			//ifex _VertexGlitchingEnabled==0
			#ifdef POI_VERTEX_GLITCHING
			//Vertex Glitching
			#if defined(POI_VERTEX_GLITCHING_TEXTURE)
			float _VertexGlitchingUseTexture;
			sampler2D _VertexGlitchMap;
			float4 _VertexGlitchMap_ST;
			#endif
			float _VertexGlitchThreshold;
			float _VertexGlitchFrequency;
			float _VertexGlitchStrength;
			float _VertexGlitchDensity;
			
			float _VertexGlitchMirrorEnable;
			float _VertexGlitchMirror;
			
			float _VertexGlitchMapPanSpeed;
			float _VertexGlitchingAudioLinkEnabled;
			float _VertexGlitchingAudioLinkBand;
			float _VertexGlitchingAudiolinkOverride;
			#endif
			//endex
			
			//ifex _MainVertexColoringEnabled==0
			float _MainVertexColoringEnabled;
			float _MainVertexColoringLinearSpace;
			float _MainVertexColoring;
			float _MainUseVertexColorAlpha;
			//endex
			
			//ifex _ShadingEnabled==0
			float _ShadowStrength;
			float _LightingIgnoreAmbientColor;
			float3 _LightingShadowColor;
			
			float _ShadingRampedLightMapApplyGlobalMaskIndex;
			float _ShadingRampedLightMapApplyGlobalMaskBlendType;
			
			float _ShadingRampedLightMapInverseApplyGlobalMaskIndex;
			float _ShadingRampedLightMapInverseApplyGlobalMaskBlendType;
			
			// Toon Lighting
			#ifdef _LIGHTINGMODE_TEXTURERAMP
			UNITY_DECLARE_TEX2D(_ToonRamp);
			float _ShadowOffset;
			int _ToonRampCount;
			int _ToonRampUVSelector;
			#endif
			
			#ifdef _LIGHTINGMODE_WRAPPED
			float4 _LightingWrappedColor;
			float _LightingWrappedWrap;
			float _LightingWrappedNormalization;
			float _LightingGradientStart;
			float _LightingGradientEnd;
			#endif
			
			#ifdef _LIGHTINGMODE_SHADEMAP
			float3 _1st_ShadeColor;
			#if defined(PROP_1ST_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _1st_ShadeMap;
			#endif
			float4 _1st_ShadeMap_ST;
			float2 _1st_ShadeMapPan;
			float _1st_ShadeMapUV;
			float _Use_1stShadeMapAlpha_As_ShadowMask;
			float _1stShadeMapMask_Inverse;
			float _Use_BaseAs1st;
			float3 _2nd_ShadeColor;
			#if defined(PROP_2ND_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _2nd_ShadeMap;
			#endif
			float4 _2nd_ShadeMap_ST;
			float2 _2nd_ShadeMapPan;
			float _2nd_ShadeMapUV;
			float _Use_2ndShadeMapAlpha_As_ShadowMask;
			float _2ndShadeMapMask_Inverse;
			float _Use_1stAs2nd;
			float _BaseColor_Step;
			float _BaseShade_Feather;
			float _ShadeColor_Step;
			float _1st2nd_Shades_Feather;
			float _ShadingShadeMapBlendType;
			#endif
			
			#ifdef _LIGHTINGMODE_SKIN
			sampler2D _SkinLUT;
			float _SssScale;
			#if defined(PROP_SKINTHICKNESS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _SkinThicknessMap;
			#endif
			float4 _SkinThicknessMap_ST;
			float2 _SkinThicknessMapPan;
			float _SkinThicknessMapUV;
			float _SkinThicknessMapInvert;
			float _SkinThicknessPower;
			float _SssBumpBlur;
			float3 _SssTransmissionAbsorption;
			float3 _SssColorBleedAoWeights;
			#endif
			
			#ifdef _LIGHTINGMODE_MULTILAYER_MATH
			float _ShadowBorderMapToggle;
			#if defined(PROP_SHADOWBORDERMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ShadowBorderMask;
			float4 _ShadowBorderMask_ST;
			float2 _ShadowBorderMaskPan;
			float _ShadowBorderMaskUV;
			#endif
			float _ShadowPostAO;
			float _ShadowBorderMaskLOD;
			float4 _ShadowAOShift;
			float4 _ShadowAOShift2;
			
			float4 _ShadowColor;
			float _LightingMulitlayerNonLinear;
			#if defined(PROP_SHADOWCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ShadowColorTex;
			float4 _ShadowColorTex_ST;
			float2 _ShadowColorTexPan;
			float _ShadowColorTexUV;
			#endif
			#if defined(PROP_MULTILAYERMATHBLURMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MultilayerMathBlurMap;
			float4 _MultilayerMathBlurMap_ST;
			float2 _MultilayerMathBlurMapPan;
			float _MultilayerMathBlurMapUV;
			#endif
			float _ShadowBorder;
			float _ShadowBlur;
			float _ShadowReceive;
			float4 _Shadow2ndColor;
			#if defined(PROP_SHADOW2NDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Shadow2ndColorTex;
			float4 _Shadow2ndColorTex_ST;
			float2 _Shadow2ndColorTexPan;
			float _Shadow2ndColorTexUV;
			#endif
			float _Shadow2ndBorder;
			float _Shadow2ndBlur;
			float _Shadow2ndReceive;
			float4 _Shadow3rdColor;
			#if defined(PROP_SHADOW3RDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Shadow3rdColorTex;
			float4 _Shadow3rdColorTex_ST;
			float2 _Shadow3rdColorTexPan;
			float _Shadow3rdColorTexUV;
			#endif
			float _Shadow3rdBorder;
			float _Shadow3rdBlur;
			float _Shadow3rdReceive;
			float4 _ShadowBorderColor;
			float _ShadowBorderRange;
			float _ShadowMainStrength;
			#endif
			
			#ifdef _LIGHTINGMODE_FLAT
			float _ForceFlatRampedLightmap;
			#endif
			
			#ifdef _LIGHTINGMODE_CLOTH
			Texture2D_float _ClothDFG;
			SamplerState sampler_ClothDFG;
			
			#if defined(PROP_CLOTHMETALLICSMOOTHNESSMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ClothMetallicSmoothnessMap;
			#endif
			
			float4 _ClothMetallicSmoothnessMap_ST;
			float2 _ClothMetallicSmoothnessMapPan;
			float _ClothMetallicSmoothnessMapUV;
			float _ClothMetallicSmoothnessMapInvert;
			
			float _ClothLerp;
			float _ClothMetallic;
			float _ClothReflectance;
			float _ClothSmoothness;
			#endif
			
			#ifdef _LIGHTINGMODE_SDF
			#if defined(PROP_SDFSHADINGTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _SDFShadingTexture;
			float _SDFShadingTextureUV;
			float2 _SDFShadingTexturePan;
			float4 _SDFShadingTexture_ST;
			float _SDFBlur;
			float4 _SDFForward;
			float4 _SDFLeft;
			#endif
			#endif
			
			// Additive
			float _LightingAdditiveType;
			float _LightingAdditiveGradientStart;
			float _LightingAdditiveGradientEnd;
			float _LightingAdditiveDetailStrength;
			//endex
			
			//ifex _EnableDissolve==0
			#ifdef DISTORT
			float _DissolveType;
			float _DissolveEdgeWidth;
			float4 _DissolveEdgeColor;
			sampler2D _DissolveEdgeGradient;
			float4 _DissolveEdgeGradient_ST;
			float2 _DissolveEdgeGradientPan;
			float _DissolveEdgeGradientUV;
			float _DissolveEdgeEmission;
			float4 _DissolveTextureColor;
			float _DissolveEdgeColorThemeIndex;
			float _DissolveTextureColorThemeIndex;
			
			#if defined(PROP_DISSOLVETOTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveToTexture;
			#endif
			float4 _DissolveToTexture_ST;
			float2 _DissolveToTexturePan;
			float _DissolveToTextureUV;
			
			#if defined(PROP_DISSOLVENOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveNoiseTexture;
			#endif
			float4 _DissolveNoiseTexture_ST;
			float2 _DissolveNoiseTexturePan;
			float _DissolveNoiseTextureUV;
			
			#if defined(PROP_DISSOLVEDETAILNOISE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveDetailNoise;
			#endif
			float4 _DissolveDetailNoise_ST;
			float2 _DissolveDetailNoisePan;
			float _DissolveDetailNoiseUV;
			
			#if defined(PROP_DISSOLVEMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveMask;
			#endif
			float4 _DissolveMask_ST;
			float2 _DissolveMaskPan;
			float _DissolveMaskUV;
			
			float _DissolveMaskGlobalMask;
			float _DissolveMaskGlobalMaskBlendType;
			float _DissolveApplyGlobalMaskIndex;
			float _DissolveApplyGlobalMaskBlendType;
			float _DissolveInverseApplyGlobalMaskBlendType;
			float _DissolveInverseApplyGlobalMaskIndex;
			float _DissolveMaskInvert;
			float _DissolveAlpha;
			float _ContinuousDissolve;
			float _DissolveDetailStrength;
			float _DissolveDetailEdgeSmoothing;
			float _DissolveEdgeHardness;
			float _DissolveInvertNoise;
			float _DissolveInvertDetailNoise;
			float _DissolveToEmissionStrength;
			
			// Point to Point
			float _DissolveP2PWorldLocal;
			float _DissolveP2PEdgeLength;
			float _DissolveP2PClamp;
			float4 _DissolveStartPoint;
			float4 _DissolveEndPoint;
			
			// Spherical
			float3 _SphericalDissolveCenter;
			float _SphericalDissolveRadius;
			float _SphericalDissolveInvert;
			float _SphericalDissolveClamp;
			
			// CenterOut
			float _CenterOutDissolveMode;
			float3 _CenterOutDissolveDirection;
			float _CenterOutDissolveInvert;
			float _CenterOutDissolveNormals;
			float _CenterOutDissolvePower;
			
			// World Dissolve
			float _DissolveWorldShape;
			float4 _DissolveShapePosition;
			float4 _DissolveShapeRotation;
			float _DissolveShapeScale;
			float _DissolveInvertShape;
			float _DissolveShapeEdgeLength;
			
			// UV Tile Dissolve
			float _UVTileDissolveEnabled;
			float _UVTileDissolveDiscardAtMax;
			float _UVTileDissolveUV;
			
			float _UVTileDissolveAlpha_Row3_0;
			float _UVTileDissolveAlpha_Row3_1;
			float _UVTileDissolveAlpha_Row3_2;
			float _UVTileDissolveAlpha_Row3_3;
			float _UVTileDissolveAlpha_Row2_0;
			float _UVTileDissolveAlpha_Row2_1;
			float _UVTileDissolveAlpha_Row2_2;
			float _UVTileDissolveAlpha_Row2_3;
			float _UVTileDissolveAlpha_Row1_0;
			float _UVTileDissolveAlpha_Row1_1;
			float _UVTileDissolveAlpha_Row1_2;
			float _UVTileDissolveAlpha_Row1_3;
			float _UVTileDissolveAlpha_Row0_0;
			float _UVTileDissolveAlpha_Row0_1;
			float _UVTileDissolveAlpha_Row0_2;
			float _UVTileDissolveAlpha_Row0_3;
			
			float _DissolveAlpha0;
			float _DissolveAlpha1;
			float _DissolveAlpha2;
			float _DissolveAlpha3;
			float _DissolveAlpha4;
			float _DissolveAlpha5;
			float _DissolveAlpha6;
			float _DissolveAlpha7;
			float _DissolveAlpha8;
			float _DissolveAlpha9;
			// Masking
			float _DissolveEmissionSide;
			float _DissolveEmission1Side;
			float _DissolveUseVertexColors;
			
			float4 edgeColor;
			float edgeAlpha;
			float dissolveAlpha;
			float4 dissolveToTexture;
			
			float _DissolveHueShiftEnabled;
			float _DissolveHueShiftSpeed;
			float _DissolveHueShift;
			float _DissolveEdgeHueShiftEnabled;
			float _DissolveEdgeHueShiftSpeed;
			float _DissolveEdgeHueShift;
			
			// Audio Link
			#ifdef POI_AUDIOLINK
			fixed _EnableDissolveAudioLink;
			half _AudioLinkDissolveAlphaBand;
			float2 _AudioLinkDissolveAlpha;
			half _AudioLinkDissolveDetailBand;
			float2 _AudioLinkDissolveDetail;
			#endif
			#endif
			//endex
			
			//ifex _EnableALDecal==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_DECAL
			float _ALDecalUV;
			float4 _ALUVScale;
			float2 _ALUVPosition;
			float _ALUVRotation;
			float _ALUVRotationSpeed;
			float4 _ALDecaldCircleDimensions;
			
			float _ALDecalUVMode;
			
			float _ALDecalVolumeStep;
			float _ALDecalVolumeClipMin;
			float _ALDecalVolumeClipMax;
			
			float _ALDecalBandStep;
			float _ALDecalBandClipMin;
			float _ALDecalBandClipMax;
			
			float _ALDecalShapeClip;
			float _ALDecalShapeClipVolumeWidth;
			float _ALDecalShapeClipBandWidth;
			
			#if defined(PROP_ALDECALCOLORMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ALDecalColorMask;
			float4 _ALDecalColorMask_ST;
			float2 _ALDecalColorMaskPan;
			float _ALDecalColorMaskUV;
			#endif
			
			float _ALDecalVolume;
			float _ALDecalBaseBoost;
			float _ALDecalTrebleBoost;
			float _ALDecalLineWidth;
			float _ALDecalVolumeColorSource;
			float3 _ALDecalVolumeColorLow;
			float _ALDecalVolumeColorLowThemeIndex;
			float3 _ALDecalVolumeColorMid;
			float _ALDecalVolumeColorMidThemeIndex;
			float3 _ALDecalVolumeColorHigh;
			float _ALDecalVolumeColorHighThemeIndex;
			float _ALDecalLowEmission;
			float _ALDecalMidEmission;
			float _ALDecalHighEmission;
			float _ALDecalBlendType;
			float _ALDecalBlendAlpha;
			float _ALDecalControlsAlpha;
			float _ALDecalGlobalMask;
			float _ALDecalGlobalMaskBlendType;
			#endif
			#endif
			//endex
			
			//ifex _EnableFlipbook==0
			#ifdef _SUNDISK_HIGH_QUALITY
			
			UNITY_DECLARE_TEX2DARRAY(_FlipbookTexArray);
			float4 _FlipbookTexArray_ST;
			
			float4 _FlipbookColor;
			float _FlipbookColorThemeIndex;
			float _FlipbookFPS;
			// float _FlipbookTotalFrames;
			float4 _FlipbookScaleOffset;
			float4 _FlipbookSideOffset;
			float _FlipbookTiled;
			float _FlipbookManualFrameControl;
			float _FlipbookCurrentFrame;
			float _FlipbookStartAndEnd;
			float _FlipbookStartFrame;
			float _FlipbookEndFrame;
			float _FlipbookEmissionStrength;
			float _FlipbookRotation;
			float _EnableFlipbook;
			float _FlipbookTexArrayUV;
			float _FlipbookAlphaControlsFinalAlpha;
			float _FlipbookRotationSpeed;
			float _FlipbookIntensityControlsAlpha;
			float _FlipbookColorReplaces;
			float2 _FlipbookTexArrayPan;
			float _FlipbookFrameOffset;
			// blending
			float _FlipbookReplace;
			float _FlipbookMultiply;
			float _FlipbookAdd;
			float _FlipbookBlendType;
			
			#if defined(PROP_FLIPBOOKMASSK) || !defined(OPTIMIZED_ENABLED)
			Texture2D _FlipbookMask;
			#endif
			float4 _FlipbookMask_ST;
			float2 _FlipbookMaskPan;
			float _FlipbookMaskUV;
			float _FlipbookMaskChannel;
			float _FlipbookMaskGlobalMask;
			float _FlipbookMaskGlobalMaskBlendType;
			
			// anim
			float _FlipbookMovementType;
			float4 _FlipbookStartEndOffset;
			float _FlipbookMovementSpeed;
			
			// Crossfade
			float _FlipbookCrossfadeEnabled;
			float2 _FlipbookCrossfadeRange;
			
			// Hueshift
			float _FlipbookHueShiftEnabled;
			float _FlipbookHueShiftSpeed;
			float _FlipbookHueShift;
			
			#ifdef POI_AUDIOLINK
			float _FlipbookChronotensityEnabled;
			float _FlipbookChronotensityBand;
			float _FlipbookChronotensitySpeed;
			float _FlipbookChronoType;
			half _AudioLinkFlipbookScaleBand;
			half4 _AudioLinkFlipbookScale;
			half _AudioLinkFlipbookAlphaBand;
			half2 _AudioLinkFlipbookAlpha;
			half _AudioLinkFlipbookEmissionBand;
			half2 _AudioLinkFlipbookEmission;
			half _AudioLinkFlipbookFrameBand;
			half2 _AudioLinkFlipbookFrame;
			#endif
			#endif
			//endex
			
			//ifex _EnableMirrorOptions==0
			#ifdef POI_MIRROR
			float _VisibilityMode;
			float _Mirror;
			#if defined(PROP_MIRRORTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MirrorTexture;
			#endif
			float4 _MirrorColor;
			float _MirrorColorThemeIndex;
			float _MirrorTextureBlendType;
			float4 _MirrorTexture_ST;
			float2 _MirrorTexturePan;
			float _MirrorTextureUV;
			float _MirrorTextureEnabled;
			float _MirrorTextureForceEnabled;
			float _VisibilityVRCRegular;
			float _VisibilityVRCMirrorVR;
			float _VisibilityVRCMirrorDesktop;
			float _VisibilityVRCCameraVR;
			float _VisibilityVRCCameraDesktop;
			float _VisibilityVRCCameraScreenshot;
			#endif
			//endex
			
			float _PPLightingMultiplier;
			float _PPLightingAddition;
			float _PPEmissionMultiplier;
			float _PPFinalColorMultiplier;
			
			//ifex _NormalCorrect==0
			#ifdef POI_NORMALCORRECT
			float _NormalCorrectAmount;
			float3 _NormalCorrectOrigin;
			#endif
			//endex
			
			//ifex _VideoEffectsEnable==0
			#ifdef POI_VIDEO_EFFECTS
			float _VideoEffectsEnable;
			#if defined(PROP_VIDEOPIXELTEXTURE) || !defined(OPTIMIZER_ENABLED)
			sampler2D _VideoPixelTexture;
			float4 _VideoPixelTexture_ST;
			float _VideoPixelTextureUV;
			#endif
			#if defined(PROP_VIDEOMASKTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VideoMaskTexture;
			float4 _VideoMaskTexture_ST;
			float2 _VideoMaskTexturePan;
			float _VideoMaskTextureUV;
			float _VideoMaskTextureChannel;
			#endif
			
			float _VideoType;
			float2 _VideoResolution;
			sampler2D _VideoGameboyRamp;
			float _VideoBacklight;
			float _VideoCRTRefreshRate;
			float _VideoCRTPixelEnergizedTime;
			float _VideoRepeatVideoTexture;
			float _VideoPixelateToResolution;
			float2 _VideoMaskPanning;
			
			float _VideoSaturation;
			float _VideoContrast;
			float _VideoEmissionEnabled;
			#endif
			//endex
			
			//ifex _BacklightEnabled!=1
			#ifdef POI_BACKLIGHT
			float4 _BacklightColor;
			#if defined(PROP_BACKLIGHTCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BacklightColorTex;
			float4 _BacklightColorTex_ST;
			float2 _BacklightColorTexPan;
			float _BacklightColorTexUV;
			#endif
			float _BacklightMainStrength;
			float _BacklightNormalStrength;
			float _BacklightBorder;
			float _BacklightBlur;
			float _BacklightDirectivity;
			float _BacklightViewStrength;
			int _BacklightReceiveShadow;
			int _BacklightBackfaceMask;
			#endif
			//endex
			
			//ifex _BSSEnabled!=1
			#ifdef POIBS_ENABLE
			float _CustomColors;
			//ifex _BSSBloomfog!=1
			#ifdef POIBS_BLOOMFOG
			float _FogStartOffset;
			float _FogScale;
			float _FogHeightOffset;
			float _FogHeightScale;
			
			uniform float2 _CustomFogTextureToScreenRatio;
			uniform float _StereoCameraEyeOffset;
			
			uniform float _CustomFogOffset;
			uniform float _CustomFogAttenuation;
			uniform float _CustomFogHeightFogStartY;
			uniform float _CustomFogHeightFogHeight;
			uniform sampler2D _BloomPrePassTexture;
			#endif
			//endex
			#endif
			//endex
			
			//ifex _VoronoiEnabled!=1
			#ifdef POI_VORONOI
			#if defined(PROP_VORONOIMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VoronoiMask;
			float4 _VoronoiMask_ST;
			float2 _VoronoiMaskPan;
			float _VoronoiMaskUV;
			int _VoronoiMaskChannel;
			#endif
			#if defined(PROP_VORONOINOISE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VoronoiNoise;
			float4 _VoronoiNoise_ST;
			float2 _VoronoiNoisePan;
			float _VoronoiNoiseUV;
			int _VoronoiNoiseChannel;
			#endif
			int _VoronoiSpace;
			int _VoronoiBlend;
			int _VoronoiType;
			float4 _VoronoiOuterColor;
			float _VoronoiOuterEmissionStrength;
			float4 _VoronoiInnerColor;
			float _VoronoiInnerEmissionStrength;
			float _VoronoiPower;
			float2 _VoronoiGradient;
			float _VoronoiScale;
			float3 _VoronoiSpeed;
			float _VoronoiEnableRandomCellColor;
			float2 _VoronoiRandomMinMaxSaturation;
			float2 _VoronoiRandomMinMaxBrightness;
			float _VoronoiNoiseIntensity;
			int _VoronoiAffectsMaterialAlpha;
			float _VoronoiGlobalMask;
			float _VoronoiGlobalMaskBlendType;
			
			// AudioLink
			int _AudioLinkVoronoiInnerEmissionBand;
			float2 _AudioLinkVoronoiInnerEmission;
			int _AudioLinkVoronoiOuterEmissionBand;
			float2 _AudioLinkVoronoiOuterEmission;
			
			int _AudioLinkVoronoiGradientMinAddBand;
			float _AudioLinkVoronoiGradientMinAdd;
			int _AudioLinkVoronoiGradientMaxAddBand;
			float _AudioLinkVoronoiGradientMaxAdd;
			
			int _AudioLinkVoronoiChronoSpeedXType;
			int _AudioLinkVoronoiChronoSpeedXBand;
			float _AudioLinkVoronoiChronoSpeedXSpeed;
			int _AudioLinkVoronoiChronoSpeedYType;
			int _AudioLinkVoronoiChronoSpeedYBand;
			float _AudioLinkVoronoiChronoSpeedYSpeed;
			int _AudioLinkVoronoiChronoSpeedZType;
			int _AudioLinkVoronoiChronoSpeedZBand;
			float _AudioLinkVoronoiChronoSpeedZSpeed;
			#endif
			//endex
			
			struct appdata
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 tangent : TANGENT;
				float4 color : COLOR;
				float2 uv0 : TEXCOORD0;
				float2 uv1 : TEXCOORD1;
				float2 uv2 : TEXCOORD2;
				float2 uv3 : TEXCOORD3;
				uint vertexId : SV_VertexID;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};
			
			struct VertexOut
			{
				float4 pos : SV_POSITION;
				float4 uv[2] : TEXCOORD0;
				float3 normal : TEXCOORD2;
				float4 tangent : TEXCOORD3;
				float4 worldPos : TEXCOORD4;
				float4 localPos : TEXCOORD5;
				float4 vertexColor : TEXCOORD6;
				float4 lightmapUV : TEXCOORD7;
				float2 fogCoord: TEXCOORD10;
				UNITY_SHADOW_COORDS(11)
				
				UNITY_VERTEX_INPUT_INSTANCE_ID
				UNITY_VERTEX_OUTPUT_STEREO
			};
			
			struct PoiMesh
			{
				
				// 0 Vertex normal
				// 1 Fragment normal
				float3 normals[2];
				float3 objNormal;
				float3 tangentSpaceNormal;
				float3 binormal[2];
				float3 tangent[2];
				float3 worldPos;
				float3 localPos;
				float3 objectPosition;
				float isFrontFace;
				float4 vertexColor;
				float4 lightmapUV;
				// 0-3 UV0-UV3
				// 4 Panosphere UV
				// 5 world pos xz
				// 6 Polar UV
				// 7 Distorted UV
				float2 uv[9];
				float2 parallaxUV;
				float2 dx;
				float2 dy;
			};
			
			struct PoiCam
			{
				float3 viewDir;
				float3 forwardDir;
				float3 worldPos;
				float distanceToVert;
				float4 clipPos;
				float4 screenSpacePosition;
				float3 reflectionDir;
				float3 vertexReflectionDir;
				float3 tangentViewDir;
				float4 posScreenSpace;
				float2 posScreenPixels;
				float2 screenUV;
				float vDotN;
				float4 worldDirection;
				
			};
			
			struct PoiMods
			{
				float4 Mask;
				float audioLink[5];
				float audioLinkAvailable;
				float audioLinkVersion;
				float4 audioLinkTexture;
				float2 detailMask;
				float2 backFaceDetailIntensity;
				float globalEmission;
				float4 globalColorTheme[12];
				float globalMask[16];
				float ALTime[8];
			};
			
			struct PoiLight
			{
				
				float3 direction;
				float attenuation;
				float attenuationStrength;
				float3 directColor;
				float3 indirectColor;
				float occlusion;
				float shadowMask;
				float detailShadow;
				float3 halfDir;
				float lightMap;
				float lightMapNoAttenuation;
				float3 rampedLightMap;
				float vertexNDotL;
				float nDotL;
				float nDotV;
				float vertexNDotV;
				float nDotH;
				float vertexNDotH;
				float lDotv;
				float lDotH;
				float nDotLSaturated;
				float nDotLNormalized;
				#ifdef POI_PASS_ADD
				float additiveShadow;
				#endif
				float3 finalLighting;
				float3 finalLightAdd;
				float3 LTCGISpecular;
				float3 LTCGIDiffuse;
				float directLuminance;
				float indirectLuminance;
				float finalLuminance;
				
				#if defined(VERTEXLIGHT_ON)
				// Non Important Lights
				float4 vDotNL;
				float4 vertexVDotNL;
				float3 vColor[4];
				float4 vCorrectedDotNL;
				float4 vAttenuation;
				float4 vSaturatedDotNL;
				float3 vPosition[4];
				float3 vDirection[4];
				float3 vFinalLighting;
				float3 vHalfDir[4];
				half4 vDotNH;
				half4 vertexVDotNH;
				half4 vDotLH;
				#endif
				
			};
			
			struct PoiVertexLights
			{
				
				float3 direction;
				float3 color;
				float attenuation;
			};
			
			struct PoiFragData
			{
				float smoothness;
				float smoothness2;
				float metallic;
				float specularMask;
				float reflectionMask;
				
				float3 baseColor;
				float3 finalColor;
				float alpha;
				float3 emission;
				float toggleVertexLights;
			};
			
			float4 poiTransformClipSpacetoScreenSpaceFrag(float4 clipPos)
			{
				float4 positionSS = float4(clipPos.xyz * clipPos.w, clipPos.w);
				positionSS.xy = positionSS.xy / _ScreenParams.xy;
				return positionSS;
			}
			
			// glsl_mod behaves better on negative numbers, and
			// in some situations actually outperforms HLSL's fmod()
			#ifndef glsl_mod
			#define glsl_mod(x, y) (((x) - (y) * floor((x) / (y))))
			#endif
			
			uniform float random_uniform_float_only_used_to_stop_compiler_warnings = 0.0f;
			
			float2 poiUV(float2 uv, float4 tex_st)
			{
				return uv * tex_st.xy + tex_st.zw;
			}
			
			float2 vertexUV(in VertexOut o, int index)
			{
				switch(index)
				{
					case 0:
					return o.uv[0].xy;
					case 1:
					return o.uv[0].zw;
					case 2:
					return o.uv[1].xy;
					case 3:
					return o.uv[1].zw;
					default:
					return o.uv[0].xy;
				}
			}
			
			float2 vertexUV(in appdata v, int index)
			{
				switch(index)
				{
					case 0:
					return v.uv0.xy;
					case 1:
					return v.uv1.xy;
					case 2:
					return v.uv2.xy;
					case 3:
					return v.uv3.xy;
					default:
					return v.uv0.xy;
				}
			}
			
			//Lighting Helpers
			float calculateluminance(float3 color)
			{
				return color.r * 0.299 + color.g * 0.587 + color.b * 0.114;
			}
			
			// Set by VRChat (as of open beta 1245)
			// _VRChatCameraMode: 0 => Normal, 1 => VR HandCam, 2 => Desktop Handcam, 3 => Screenshot/Photo
			// _VRChatMirrorMode: 0 => Normal, 1 => Mirror (VR), 2 => Mirror (Deskie)
			float _VRChatCameraMode;
			float _VRChatMirrorMode;
			
			float VRCCameraMode()
			{
				return _VRChatCameraMode;
			}
			
			float VRCMirrorMode()
			{
				return _VRChatMirrorMode;
			}
			
			bool IsInMirror()
			{
				return unity_CameraProjection[2][0] != 0.f || unity_CameraProjection[2][1] != 0.f;
			}
			
			bool IsOrthographicCamera()
			{
				return unity_OrthoParams.w == 1 || UNITY_MATRIX_P[3][3] == 1;
			}
			
			float shEvaluateDiffuseL1Geomerics_local(float L0, float3 L1, float3 n)
			{
				// average energy
				float R0 = max(0, L0);
				
				// avg direction of incoming light
				float3 R1 = 0.5f * L1;
				
				// directional brightness
				float lenR1 = length(R1);
				
				// linear angle between normal and direction 0-1
				//float q = 0.5f * (1.0f + dot(R1 / lenR1, n));
				//float q = dot(R1 / lenR1, n) * 0.5 + 0.5;
				float q = dot(normalize(R1), n) * 0.5 + 0.5;
				q = saturate(q); // Thanks to ScruffyRuffles for the bug identity.
				
				// power for q
				// lerps from 1 (linear) to 3 (cubic) based on directionality
				float p = 1.0f + 2.0f * lenR1 / R0;
				
				// dynamic range constant
				// should vary between 4 (highly directional) and 0 (ambient)
				float a = (1.0f - lenR1 / R0) / (1.0f + lenR1 / R0);
				
				return R0 * (a + (1.0f - a) * (p + 1.0f) * pow(q, p));
			}
			
			half3 BetterSH9(half4 normal)
			{
				float3 indirect;
				float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) + float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0;
				indirect.r = shEvaluateDiffuseL1Geomerics_local(L0.r, unity_SHAr.xyz, normal.xyz);
				indirect.g = shEvaluateDiffuseL1Geomerics_local(L0.g, unity_SHAg.xyz, normal.xyz);
				indirect.b = shEvaluateDiffuseL1Geomerics_local(L0.b, unity_SHAb.xyz, normal.xyz);
				indirect = max(0, indirect);
				indirect += SHEvalLinearL2(normal);
				return indirect;
			}
			
			// Silent's code ends here
			
			float3 getCameraForward()
			{
				#if UNITY_SINGLE_PASS_STEREO
				float3 p1 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 1, 1));
				float3 p2 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 0, 1));
				#else
				float3 p1 = mul(unity_CameraToWorld, float4(0, 0, 1, 1)).xyz;
				float3 p2 = mul(unity_CameraToWorld, float4(0, 0, 0, 1)).xyz;
				#endif
				return normalize(p2 - p1);
			}
			
			half3 GetSHLength()
			{
				half3 x, x1;
				x.r = length(unity_SHAr);
				x.g = length(unity_SHAg);
				x.b = length(unity_SHAb);
				x1.r = length(unity_SHBr);
				x1.g = length(unity_SHBg);
				x1.b = length(unity_SHBb);
				return x + x1;
			}
			
			float3 BoxProjection(float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax)
			{
				#if UNITY_SPECCUBE_BOX_PROJECTION
				//UNITY_BRANCH
				if (cubemapPosition.w > 0)
				{
					float3 factors = ((direction > 0 ? boxMax : boxMin) - position) / direction;
					float scalar = min(min(factors.x, factors.y), factors.z);
					direction = direction * scalar + (position - cubemapPosition.xyz);
				}
				#endif
				return direction;
			}
			
			float poiMax(float2 i)
			{
				return max(i.x, i.y);
			}
			
			float poiMax(float3 i)
			{
				return max(max(i.x, i.y), i.z);
			}
			
			float poiMax(float4 i)
			{
				return max(max(max(i.x, i.y), i.z), i.w);
			}
			
			float3 calculateNormal(in float3 baseNormal, in PoiMesh poiMesh, in Texture2D normalTexture, in float4 normal_ST, in float2 normalPan, in float normalUV, in float normalIntensity)
			{
				float3 normal = UnpackScaleNormal(POI2D_SAMPLER_PAN(normalTexture, _MainTex, poiUV(poiMesh.uv[normalUV], normal_ST), normalPan), normalIntensity);
				return normalize(
				normal.x * poiMesh.tangent[0] +
				normal.y * poiMesh.binormal[0] +
				normal.z * baseNormal
				);
			}
			
			float remap(float x, float minOld, float maxOld, float minNew = 0, float maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float2 remap(float2 x, float2 minOld, float2 maxOld, float2 minNew = 0, float2 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float3 remap(float3 x, float3 minOld, float3 maxOld, float3 minNew = 0, float3 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float4 remap(float4 x, float4 minOld, float4 maxOld, float4 minNew = 0, float4 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float remapClamped(float minOld, float maxOld, float x, float minNew = 0, float maxNew = 1)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float2 remapClamped(float2 minOld, float2 maxOld, float2 x, float2 minNew, float2 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float3 remapClamped(float3 minOld, float3 maxOld, float3 x, float3 minNew, float3 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float4 remapClamped(float4 minOld, float4 maxOld, float4 x, float4 minNew, float4 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			float2 calcParallax(in float height, in PoiCam poiCam)
			{
				return ((height * - 1) + 1) * (poiCam.tangentViewDir.xy / poiCam.tangentViewDir.z);
			}
			
			/*
			0: Zero	                float4(0.0, 0.0, 0.0, 0.0),
			1: One	                float4(1.0, 1.0, 1.0, 1.0),
			2: DstColor	            destinationColor,
			3: SrcColor	            sourceColor,
			4: OneMinusDstColor	    float4(1.0, 1.0, 1.0, 1.0) - destinationColor,
			5: SrcAlpha	            sourceColor.aaaa,
			6: OneMinusSrcColor	    float4(1.0, 1.0, 1.0, 1.0) - sourceColor,
			7: DstAlpha	            destinationColor.aaaa,
			8: OneMinusDstAlpha	    float4(1.0, 1.0, 1.0, 1.0) - destinationColor.,
			9: SrcAlphaSaturate     saturate(sourceColor.aaaa),
			10: OneMinusSrcAlpha	float4(1.0, 1.0, 1.0, 1.0) - sourceColor.aaaa,
			*/
			
			float4 poiBlend(const float sourceFactor, const  float4 sourceColor, const  float destinationFactor, const  float4 destinationColor, const float4 blendFactor)
			{
				float4 sA = 1 - blendFactor;
				const float4 blendData[11] = {
					float4(0.0, 0.0, 0.0, 0.0),
					float4(1.0, 1.0, 1.0, 1.0),
					destinationColor,
					sourceColor,
					float4(1.0, 1.0, 1.0, 1.0) - destinationColor,
					sA,
					float4(1.0, 1.0, 1.0, 1.0) - sourceColor,
					sA,
					float4(1.0, 1.0, 1.0, 1.0) - sA,
					saturate(sourceColor.aaaa),
					1 - sA,
				};
				
				return lerp(blendData[sourceFactor] * sourceColor + blendData[destinationFactor] * destinationColor, sourceColor, sA);
			}
			
			// Average
			float blendAverage(float base, float blend)
			{
				return (base + blend) / 2.0;
			}
			float3 blendAverage(float3 base, float3 blend)
			{
				return (base + blend) / 2.0;
			}
			
			// Color burn
			float blendColorBurn(float base, float blend)
			{
				return (blend == 0.0) ? blend : max((1.0 - ((1.0 - base) * rcp(random_uniform_float_only_used_to_stop_compiler_warnings + blend))), 0.0);
			}
			
			float3 blendColorBurn(float3 base, float3 blend)
			{
				return float3(blendColorBurn(base.r, blend.r), blendColorBurn(base.g, blend.g), blendColorBurn(base.b, blend.b));
			}
			
			// Color Dodge
			float blendColorDodge(float base, float blend)
			{
				return (blend == 1.0) ? blend : min(base / (1.0 - blend), 1.0);
			}
			
			float3 blendColorDodge(float3 base, float3 blend)
			{
				return float3(blendColorDodge(base.r, blend.r), blendColorDodge(base.g, blend.g), blendColorDodge(base.b, blend.b));
			}
			
			// Darken
			float blendDarken(float base, float blend)
			{
				return min(blend, base);
			}
			
			float3 blendDarken(float3 base, float3 blend)
			{
				return float3(blendDarken(base.r, blend.r), blendDarken(base.g, blend.g), blendDarken(base.b, blend.b));
			}
			
			// Exclusion
			float blendExclusion(float base, float blend)
			{
				return base + blend - 2.0 * base * blend;
			}
			float3 blendExclusion(float3 base, float3 blend)
			{
				return base + blend - 2.0 * base * blend;
			}
			
			// Reflect
			float blendReflect(float base, float blend)
			{
				return (blend == 1.0) ? blend : min(base * base / (1.0 - blend), 1.0);
			}
			
			float3 blendReflect(float3 base, float3 blend)
			{
				return float3(blendReflect(base.r, blend.r), blendReflect(base.g, blend.g), blendReflect(base.b, blend.b));
			}
			
			// Glow
			float blendGlow(float base, float blend)
			{
				return blendReflect(blend, base);
			}
			float3 blendGlow(float3 base, float3 blend)
			{
				return blendReflect(blend, base);
			}
			
			// Overlay
			float blendOverlay(float base, float blend)
			{
				return base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend));
			}
			
			float3 blendOverlay(float3 base, float3 blend)
			{
				return float3(blendOverlay(base.r, blend.r), blendOverlay(base.g, blend.g), blendOverlay(base.b, blend.b));
			}
			
			// Hard Light
			float blendHardLight(float base, float blend)
			{
				return blendOverlay(blend, base);
			}
			float3 blendHardLight(float3 base, float3 blend)
			{
				return blendOverlay(blend, base);
			}
			
			// Vivid light
			float blendVividLight(float base, float blend)
			{
				return (blend < 0.5) ? blendColorBurn(base, (2.0 * blend)) : blendColorDodge(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendVividLight(float3 base, float3 blend)
			{
				return float3(blendVividLight(base.r, blend.r), blendVividLight(base.g, blend.g), blendVividLight(base.b, blend.b));
			}
			
			// Hard mix
			float blendHardMix(float base, float blend)
			{
				return (blendVividLight(base, blend) < 0.5) ? 0.0 : 1.0;
			}
			
			float3 blendHardMix(float3 base, float3 blend)
			{
				return float3(blendHardMix(base.r, blend.r), blendHardMix(base.g, blend.g), blendHardMix(base.b, blend.b));
			}
			
			// Lighten
			float blendLighten(float base, float blend)
			{
				return max(blend, base);
			}
			
			float3 blendLighten(float3 base, float3 blend)
			{
				return float3(blendLighten(base.r, blend.r), blendLighten(base.g, blend.g), blendLighten(base.b, blend.b));
			}
			
			// Linear Burn
			float blendLinearBurn(float base, float blend)
			{
				// Note : Same implementation as BlendSubtractf
				return max(base + blend - 1.0, 0.0);
			}
			
			float3 blendLinearBurn(float3 base, float3 blend)
			{
				// Note : Same implementation as BlendSubtract
				return max(base + blend - float3(1.0, 1.0, 1.0), float3(0.0, 0.0, 0.0));
			}
			
			// Linear Dodge
			float blendLinearDodge(float base, float blend)
			{
				// Note : Same implementation as BlendAddf
				return min(base + blend, 1.0);
			}
			
			float3 blendLinearDodge(float3 base, float3 blend)
			{
				// Note : Same implementation as BlendAdd
				return base + blend;
			}
			
			// Linear light
			float blendLinearLight(float base, float blend)
			{
				return blend < 0.5 ? blendLinearBurn(base, (2.0 * blend)) : blendLinearDodge(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendLinearLight(float3 base, float3 blend)
			{
				return float3(blendLinearLight(base.r, blend.r), blendLinearLight(base.g, blend.g), blendLinearLight(base.b, blend.b));
			}
			
			// Multiply
			float blendMultiply(float base, float blend)
			{
				return base * blend;
			}
			float3 blendMultiply(float3 base, float3 blend)
			{
				return base * blend;
			}
			
			// Negation
			float blendNegation(float base, float blend)
			{
				return 1.0 - abs(1.0 - base - blend);
			}
			float3 blendNegation(float3 base, float3 blend)
			{
				return float3(1.0, 1.0, 1.0) - abs(float3(1.0, 1.0, 1.0) - base - blend);
			}
			
			// Normal
			float blendNormal(float base, float blend)
			{
				return blend;
			}
			float3 blendNormal(float3 base, float3 blend)
			{
				return blend;
			}
			
			// Phoenix
			float blendPhoenix(float base, float blend)
			{
				return min(base, blend) - max(base, blend) + 1.0;
			}
			float3 blendPhoenix(float3 base, float3 blend)
			{
				return min(base, blend) - max(base, blend) + float3(1.0, 1.0, 1.0);
			}
			
			// Pin light
			float blendPinLight(float base, float blend)
			{
				return (blend < 0.5) ? blendDarken(base, (2.0 * blend)) : blendLighten(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendPinLight(float3 base, float3 blend)
			{
				return float3(blendPinLight(base.r, blend.r), blendPinLight(base.g, blend.g), blendPinLight(base.b, blend.b));
			}
			
			// Screen
			float blendScreen(float base, float blend)
			{
				return 1.0 - ((1.0 - base) * (1.0 - blend));
			}
			
			float3 blendScreen(float3 base, float3 blend)
			{
				return float3(blendScreen(base.r, blend.r), blendScreen(base.g, blend.g), blendScreen(base.b, blend.b));
			}
			
			// Soft Light
			float blendSoftLight(float base, float blend)
			{
				return (blend < 0.5) ? (2.0 * base * blend + base * base * (1.0 - 2.0 * blend)) : (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend));
			}
			
			float3 blendSoftLight(float3 base, float3 blend)
			{
				return float3(blendSoftLight(base.r, blend.r), blendSoftLight(base.g, blend.g), blendSoftLight(base.b, blend.b));
			}
			
			// Subtract
			float blendSubtract(float base, float blend)
			{
				return max(base - blend, 0.0);
			}
			
			float3 blendSubtract(float3 base, float3 blend)
			{
				return max(base - blend, 0.0);
			}
			
			// Difference
			float blendDifference(float base, float blend)
			{
				return abs(base - blend);
			}
			
			float3 blendDifference(float3 base, float3 blend)
			{
				return abs(base - blend);
			}
			
			// Divide
			float blendDivide(float base, float blend)
			{
				return base / max(blend, 0.0001);
			}
			
			float3 blendDivide(float3 base, float3 blend)
			{
				return base / max(blend, 0.0001);
			}
			
			float blendMixed(float base, float blend)
			{
				return base + base * blend;
			}
			
			float3 blendMixed(float3 base, float3 blend)
			{
				return base + base * blend;
			}
			
			float3 customBlend(float3 base, float3 blend, float blendType, float alpha = 1)
			{
				float3 output = base;
				switch(blendType)
				{
					case 0: output = lerp(base, blend, alpha); break;
					case 1: output = lerp(base, blendDarken(base, blend), alpha); break;
					case 2: output = base * lerp(1, blend, alpha); break;
					case 5: output = lerp(base, blendLighten(base, blend), alpha); break;
					case 6: output = lerp(base, blendScreen(base, blend), alpha); break;
					case 7: output = blendSubtract(base, blend * alpha); break;
					case 8: output = lerp(base, blendLinearDodge(base, blend), alpha); break;
					case 9: output = lerp(base, blendOverlay(base, blend), alpha); break;
					case 20: output = lerp(base, blendMixed(base, blend), alpha); break;
					default: output = 0; break;
				}
				return output;
			}
			
			float3 customBlend(float base, float blend, float blendType, float alpha = 1)
			{
				float3 output = base;
				switch(blendType)
				{
					case 0: output = lerp(base, blend, alpha); break;
					case 2: output = base * lerp(1, blend, alpha); break;
					case 5: output = lerp(base, blendLighten(base, blend), alpha); break;
					case 6: output = lerp(base, blendScreen(base, blend), alpha); break;
					case 7: output = blendSubtract(base, blend * alpha); break;
					case 8: output = lerp(base, blendLinearDodge(base, blend), alpha); break;
					case 9: output = lerp(base, blendOverlay(base, blend), alpha); break;
					case 20: output = lerp(base, blendMixed(base, blend), alpha); break;
					default: output = 0; break;
				}
				return output;
			}
			
			#define REPLACE 0
			#define SUBSTRACT 1
			#define MULTIPLY 2
			#define DIVIDE 3
			#define MIN 4
			#define MAX 5
			#define AVERAGE 6
			#define ADD 7
			
			float maskBlend(float baseMask, float blendMask, float blendType)
			{
				float output = 0;
				switch(blendType)
				{
					case REPLACE: output = blendMask; break;
					case SUBSTRACT: output = baseMask - blendMask; break;
					case MULTIPLY: output = baseMask * blendMask; break;
					case DIVIDE: output = baseMask / blendMask; break;
					case MIN: output = min(baseMask, blendMask); break;
					case MAX: output = max(baseMask, blendMask); break;
					case AVERAGE: output = (baseMask + blendMask) * 0.5; break;
					case ADD: output = baseMask + blendMask; break;
				}
				return saturate(output);
			}
			
			float globalMaskBlend(float baseMask, float globalMaskIndex, float blendType, PoiMods poiMods)
			{
				if (globalMaskIndex == 0)
				{
					return baseMask;
				}
				else
				{
					return maskBlend(baseMask, poiMods.globalMask[globalMaskIndex - 1], blendType);
				}
			}
			
			float random(float2 p)
			{
				return frac(sin(dot(p, float2(12.9898, 78.2383))) * 43758.5453123);
			}
			
			float2 random2(float2 p)
			{
				return frac(sin(float2(dot(p, float2(127.1, 311.7)), dot(p, float2(269.5, 183.3)))) * 43758.5453);
			}
			
			float3 random3(float2 p)
			{
				return frac(sin(float3(dot(p, float2(127.1, 311.7)), dot(p, float2(269.5, 183.3)), dot(p, float2(248.3, 315.9)))) * 43758.5453);
			}
			
			float3 random3(float3 p)
			{
				return frac(sin(float3(dot(p, float3(127.1, 311.7, 248.6)), dot(p, float3(269.5, 183.3, 423.3)), dot(p, float3(248.3, 315.9, 184.2)))) * 43758.5453);
			}
			
			float3 randomFloat3(float2 Seed, float maximum)
			{
				return (.5 + float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed), float2(12.9898, 78.233))) * 43758.5453)
				) * .5) * (maximum);
			}
			
			float3 randomFloat3Range(float2 Seed, float Range)
			{
				return (float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed.x * Seed.y, Seed.y + Seed.x), float2(12.9898, 78.233))) * 43758.5453)
				) * 2 - 1) * Range;
			}
			
			float3 randomFloat3WiggleRange(float2 Seed, float Range, float wiggleSpeed, float timeOffset)
			{
				float3 rando = (float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed.x * Seed.y, Seed.y + Seed.x), float2(12.9898, 78.233))) * 43758.5453)
				) * 2 - 1);
				float speed = 1 + wiggleSpeed;
				return float3(sin(((_Time.x + timeOffset) + rando.x * PI) * speed), sin(((_Time.x + timeOffset) + rando.y * PI) * speed), sin(((_Time.x + timeOffset) + rando.z * PI) * speed)) * Range;
			}
			
			void poiDither(float4 In, float4 ScreenPosition, out float4 Out)
			{
				float2 uv = ScreenPosition.xy * _ScreenParams.xy;
				float DITHER_THRESHOLDS[16] = {
					1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0,
					13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0,
					4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0,
					16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0
				};
				uint index = (uint(uv.x) % 4) * 4 + uint(uv.y) % 4;
				Out = In - DITHER_THRESHOLDS[index];
			}
			// The weights of RGB contributions to luminance.
			// Should sum to unity.
			static const float3 HCYwts = float3(0.299, 0.587, 0.114);
			static const float HCLgamma = 3;
			static const float HCLy0 = 100;
			static const float HCLmaxL = 0.530454533953517; // == exp(HCLgamma / HCLy0) - 0.5
			static const float3 wref = float3(1.0, 1.0, 1.0);
			#define TAU 6.28318531
			
			float3 HUEtoRGB(in float H)
			{
				float R = abs(H * 6 - 3) - 1;
				float G = 2 - abs(H * 6 - 2);
				float B = 2 - abs(H * 6 - 4);
				return saturate(float3(R, G, B));
			}
			
			float3 RGBtoHCV(in float3 RGB)
			{
				// Based on work by Sam Hocevar and Emil Persson
				float4 P = (RGB.g < RGB.b) ? float4(RGB.bg, -1.0, 2.0 / 3.0) : float4(RGB.gb, 0.0, -1.0 / 3.0);
				float4 Q = (RGB.r < P.x) ? float4(P.xyw, RGB.r) : float4(RGB.r, P.yzx);
				float C = Q.x - min(Q.w, Q.y);
				float H = abs((Q.w - Q.y) / (6 * C + Epsilon) + Q.z);
				return float3(H, C, Q.x);
			}
			
			float3 HSVtoRGB(in float3 HSV)
			{
				float3 RGB = HUEtoRGB(HSV.x);
				return ((RGB - 1) * HSV.y + 1) * HSV.z;
			}
			
			float3 RGBtoHSV(in float3 RGB)
			{
				float3 HCV = RGBtoHCV(RGB);
				float S = HCV.y / (HCV.z + Epsilon);
				return float3(HCV.x, S, HCV.z);
			}
			
			float3 HSLtoRGB(in float3 HSL)
			{
				float3 RGB = HUEtoRGB(HSL.x);
				float C = (1 - abs(2 * HSL.z - 1)) * HSL.y;
				return (RGB - 0.5) * C + HSL.z;
			}
			
			float3 RGBtoHSL(in float3 RGB)
			{
				float3 HCV = RGBtoHCV(RGB);
				float L = HCV.z - HCV.y * 0.5;
				float S = HCV.y / (1 - abs(L * 2 - 1) + Epsilon);
				return float3(HCV.x, S, L);
			}
			
			void DecomposeHDRColor(in float3 linearColorHDR, out float3 baseLinearColor, out float exposure)
			{
				// Optimization/adaptation of https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/GUI/ColorMutator.cs#L23 but skips weird photoshop stuff
				float maxColorComponent = max(linearColorHDR.r, max(linearColorHDR.g, linearColorHDR.b));
				bool isSDR = maxColorComponent <= 1.0;
				
				float scaleFactor = isSDR ? 1.0 : (1.0 / maxColorComponent);
				exposure = isSDR ? 0.0 : log(maxColorComponent) * 1.44269504089; // ln(2)
				
				baseLinearColor = scaleFactor * linearColorHDR;
			}
			
			float3 ApplyHDRExposure(float3 linearColor, float exposure)
			{
				return linearColor * pow(2, exposure);
			}
			
			// Transforms an RGB color using a matrix. Note that S and V are absolute values here
			float3 ModifyViaHSV(float3 color, float h, float s, float v)
			{
				float3 colorHSV = RGBtoHSV(color);
				colorHSV.x = frac(colorHSV.x + h);
				colorHSV.y = saturate(colorHSV.y + s);
				colorHSV.z = saturate(colorHSV.z + v);
				return HSVtoRGB(colorHSV);
			}
			
			float3 ModifyViaHSV(float3 color, float3 HSVMod)
			{
				return ModifyViaHSV(color, HSVMod.x, HSVMod.y, HSVMod.z);
			}
			
			float4x4 brightnessMatrix(float brightness)
			{
				return float4x4(
				1, 0, 0, 0,
				0, 1, 0, 0,
				0, 0, 1, 0,
				brightness, brightness, brightness, 1
				);
			}
			
			float4x4 contrastMatrix(float contrast)
			{
				float t = (1.0 - contrast) / 2.0;
				
				return float4x4(
				contrast, 0, 0, 0,
				0, contrast, 0, 0,
				0, 0, contrast, 0,
				t, t, t, 1
				);
			}
			
			float4x4 saturationMatrix(float saturation)
			{
				float3 luminance = float3(0.3086, 0.6094, 0.0820);
				
				float oneMinusSat = 1.0 - saturation;
				
				float3 red = luminance.x * oneMinusSat;
				red += float3(saturation, 0, 0);
				
				float3 green = luminance.y * oneMinusSat;
				green += float3(0, saturation, 0);
				
				float3 blue = luminance.z * oneMinusSat;
				blue += float3(0, 0, saturation);
				
				return float4x4(
				red, 0,
				green, 0,
				blue, 0,
				0, 0, 0, 1
				);
			}
			
			float4 PoiColorBCS(float4 color, float brightness, float contrast, float saturation)
			{
				return mul(color, mul(brightnessMatrix(brightness), mul(contrastMatrix(contrast), saturationMatrix(saturation))));
			}
			float3 PoiColorBCS(float3 color, float brightness, float contrast, float saturation)
			{
				return mul(float4(color, 1), mul(brightnessMatrix(brightness), mul(contrastMatrix(contrast), saturationMatrix(saturation)))).rgb;
			}
			
			float3 linear_srgb_to_oklab(float3 c)
			{
				float l = 0.4122214708 * c.x + 0.5363325363 * c.y + 0.0514459929 * c.z;
				float m = 0.2119034982 * c.x + 0.6806995451 * c.y + 0.1073969566 * c.z;
				float s = 0.0883024619 * c.x + 0.2817188376 * c.y + 0.6299787005 * c.z;
				
				float l_ = pow(l, 1.0 / 3.0);
				float m_ = pow(m, 1.0 / 3.0);
				float s_ = pow(s, 1.0 / 3.0);
				
				return float3(
				0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_,
				1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_,
				0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_
				);
			}
			
			float3 oklab_to_linear_srgb(float3 c)
			{
				float l_ = c.x + 0.3963377774 * c.y + 0.2158037573 * c.z;
				float m_ = c.x - 0.1055613458 * c.y - 0.0638541728 * c.z;
				float s_ = c.x - 0.0894841775 * c.y - 1.2914855480 * c.z;
				
				float l = l_ * l_ * l_;
				float m = m_ * m_ * m_;
				float s = s_ * s_ * s_;
				
				return float3(
				+ 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
				- 1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
				- 0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s
				);
			}
			
			float3 hueShift(float3 color, float shift)
			{
				float3 oklab = linear_srgb_to_oklab(max(color, 0.0000000001));
				float hue = atan2(oklab.z, oklab.y);
				hue += shift * PI * 2;  // Add the hue shift
				
				float chroma = length(oklab.yz);
				oklab.y = cos(hue) * chroma;
				oklab.z = sin(hue) * chroma;
				
				return oklab_to_linear_srgb(oklab);
			}
			
			float3 hueShift(float4 color, float shift)
			{
				return hueShift(color.rgb, shift);
			}
			
			/*
			float3 hueShift(float3 color, float hueOffset)
			{
				color = RGBtoHSV(color);
				color.x = frac(hueOffset +color.x);
				return HSVtoRGB(color);
			}
			*/
			
			// LCH
			float xyzF(float t)
			{
				return lerp(pow(t, 1. / 3.), 7.787037 * t + 0.139731, step(t, 0.00885645));
			}
			float xyzR(float t)
			{
				return lerp(t * t * t, 0.1284185 * (t - 0.139731), step(t, 0.20689655));
			}
			
			float4x4 poiRotationMatrixFromAngles(float x, float y, float z)
			{
				float angleX = radians(x);
				float c = cos(angleX);
				float s = sin(angleX);
				float4x4 rotateXMatrix = float4x4(1, 0, 0, 0,
				0, c, -s, 0,
				0, s, c, 0,
				0, 0, 0, 1);
				
				float angleY = radians(y);
				c = cos(angleY);
				s = sin(angleY);
				float4x4 rotateYMatrix = float4x4(c, 0, s, 0,
				0, 1, 0, 0,
				- s, 0, c, 0,
				0, 0, 0, 1);
				
				float angleZ = radians(z);
				c = cos(angleZ);
				s = sin(angleZ);
				float4x4 rotateZMatrix = float4x4(c, -s, 0, 0,
				s, c, 0, 0,
				0, 0, 1, 0,
				0, 0, 0, 1);
				
				return mul(mul(rotateXMatrix, rotateYMatrix), rotateZMatrix);
			}
			
			float4x4 poiRotationMatrixFromAngles(float3 angles)
			{
				float angleX = radians(angles.x);
				float c = cos(angleX);
				float s = sin(angleX);
				float4x4 rotateXMatrix = float4x4(1, 0, 0, 0,
				0, c, -s, 0,
				0, s, c, 0,
				0, 0, 0, 1);
				
				float angleY = radians(angles.y);
				c = cos(angleY);
				s = sin(angleY);
				float4x4 rotateYMatrix = float4x4(c, 0, s, 0,
				0, 1, 0, 0,
				- s, 0, c, 0,
				0, 0, 0, 1);
				
				float angleZ = radians(angles.z);
				c = cos(angleZ);
				s = sin(angleZ);
				float4x4 rotateZMatrix = float4x4(c, -s, 0, 0,
				s, c, 0, 0,
				0, 0, 1, 0,
				0, 0, 0, 1);
				
				return mul(mul(rotateXMatrix, rotateYMatrix), rotateZMatrix);
			}
			
			float3 getCameraPosition()
			{
				#ifdef USING_STEREO_MATRICES
				return lerp(unity_StereoWorldSpaceCameraPos[0], unity_StereoWorldSpaceCameraPos[1], 0.5);
				#endif
				return _WorldSpaceCameraPos;
			}
			
			float2 calcPixelScreenUVs(half4 grabPos)
			{
				half2 uv = grabPos.xy / (grabPos.w + 0.0000000001);
				#if UNITY_SINGLE_PASS_STEREO
				uv.xy *= half2(_ScreenParams.x * 2, _ScreenParams.y);
				#else
				uv.xy *= _ScreenParams.xy;
				#endif
				
				return uv;
			}
			
			float CalcMipLevel(float2 texture_coord)
			{
				float2 dx = ddx(texture_coord);
				float2 dy = ddy(texture_coord);
				float delta_max_sqr = max(dot(dx, dx), dot(dy, dy));
				
				return 0.5 * log2(delta_max_sqr);
			}
			
			float inverseLerp(float A, float B, float T)
			{
				return (T - A) / (B - A);
			}
			
			float inverseLerp2(float2 a, float2 b, float2 value)
			{
				float2 AB = b - a;
				float2 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			float inverseLerp3(float3 a, float3 b, float3 value)
			{
				float3 AB = b - a;
				float3 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			float inverseLerp4(float4 a, float4 b, float4 value)
			{
				float4 AB = b - a;
				float4 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			/*
			MIT License
			
			Copyright (c) 2019 wraikny
			
			Permission is hereby granted, free of charge, to any person obtaining a copy
			of this software and associated documentation files (the "Software"), to deal
			in the Software without restriction, including without limitation the rights
			to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
			copies of the Software, and to permit persons to whom the Software is
			furnished to do so, subject to the following conditions:
			
			The above copyright notice and this permission notice shall be included in all
			copies or substantial portions of the Software.
			
			THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
			IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
			FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
			AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
			LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
			OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
			SOFTWARE.
			
			VertexTransformShader is dependent on:
			*/
			
			float4 quaternion_conjugate(float4 v)
			{
				return float4(
				v.x, -v.yzw
				);
			}
			
			float4 quaternion_mul(float4 v1, float4 v2)
			{
				float4 result1 = (v1.x * v2 + v1 * v2.x);
				
				float4 result2 = float4(
				- dot(v1.yzw, v2.yzw),
				cross(v1.yzw, v2.yzw)
				);
				
				return float4(result1 + result2);
			}
			
			// angle : radians
			float4 get_quaternion_from_angle(float3 axis, float angle)
			{
				float sn = sin(angle * 0.5);
				float cs = cos(angle * 0.5);
				return float4(axis * sn, cs);
			}
			
			float4 quaternion_from_vector(float3 inVec)
			{
				return float4(0.0, inVec);
			}
			
			float degree_to_radius(float degree)
			{
				return (
				degree / 180.0 * PI
				);
			}
			
			float3 rotate_with_quaternion(float3 inVec, float3 rotation)
			{
				float4 qx = get_quaternion_from_angle(float3(1, 0, 0), radians(rotation.x));
				float4 qy = get_quaternion_from_angle(float3(0, 1, 0), radians(rotation.y));
				float4 qz = get_quaternion_from_angle(float3(0, 0, 1), radians(rotation.z));
				
				#define MUL3(A, B, C) quaternion_mul(quaternion_mul((A), (B)), (C))
				float4 quaternion = normalize(MUL3(qx, qy, qz));
				float4 conjugate = quaternion_conjugate(quaternion);
				
				float4 inVecQ = quaternion_from_vector(inVec);
				
				float3 rotated = (
				MUL3(quaternion, inVecQ, conjugate)
				).yzw;
				
				return rotated;
			}
			
			float4 transform(float4 input, float4 pos, float4 rotation, float4 scale)
			{
				input.rgb *= (scale.xyz * scale.w);
				input = float4(rotate_with_quaternion(input.xyz, rotation.xyz * rotation.w) + (pos.xyz * pos.w), input.w);
				return input;
			}
			
			float2 RotateUV(float2 _uv, float _radian, float2 _piv, float _time)
			{
				float RotateUV_ang = _radian;
				float RotateUV_cos = cos(_time * RotateUV_ang);
				float RotateUV_sin = sin(_time * RotateUV_ang);
				return (mul(_uv - _piv, float2x2(RotateUV_cos, -RotateUV_sin, RotateUV_sin, RotateUV_cos)) + _piv);
			}
			
			/*
			MIT END
			*/
			
			float3 RotateAroundAxis(float3 original, float3 axis, float radian)
			{
				float s = sin(radian);
				float c = cos(radian);
				float one_minus_c = 1.0 - c;
				
				axis = normalize(axis);
				float3x3 rot_mat = {
					one_minus_c * axis.x * axis.x + c, one_minus_c * axis.x * axis.y - axis.z * s, one_minus_c * axis.z * axis.x + axis.y * s,
					one_minus_c * axis.x * axis.y + axis.z * s, one_minus_c * axis.y * axis.y + c, one_minus_c * axis.y * axis.z - axis.x * s,
					one_minus_c * axis.z * axis.x - axis.y * s, one_minus_c * axis.y * axis.z + axis.x * s, one_minus_c * axis.z * axis.z + c
				};
				return mul(rot_mat, original);
			}
			
			float3 poiThemeColor(in PoiMods poiMods, in float3 srcColor, in float themeIndex)
			{
				float3 outputColor = srcColor;
				if (themeIndex != 0)
				{
					themeIndex = max(themeIndex - 1, 0);
					
					if (themeIndex <= 3)
					{
						outputColor = poiMods.globalColorTheme[themeIndex];
					}
					else
					{
						#ifdef POI_AUDIOLINK
						if (poiMods.audioLinkAvailable)
						{
							outputColor = poiMods.globalColorTheme[themeIndex];
						}
						#endif
					}
				}
				return outputColor;
			}
			
			float3 lilToneCorrection(float3 c, float4 hsvg)
			{
				// gamma
				c = pow(abs(c), hsvg.w);
				// rgb - > hsv
				float4 p = (c.b > c.g) ? float4(c.bg, -1.0, 2.0 / 3.0) : float4(c.gb, 0.0, -1.0 / 3.0);
				float4 q = (p.x > c.r) ? float4(p.xyw, c.r) : float4(c.r, p.yzx);
				float d = q.x - min(q.w, q.y);
				float e = 1.0e-10;
				float3 hsv = float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
				// shift
				hsv = float3(hsv.x + hsvg.x, saturate(hsv.y * hsvg.y), saturate(hsv.z * hsvg.z));
				// hsv - > rgb
				return hsv.z - hsv.z * hsv.y + hsv.z * hsv.y * saturate(abs(frac(hsv.x + float3(1.0, 2.0 / 3.0, 1.0 / 3.0)) * 6.0 - 3.0) - 1.0);
			}
			
			float3 lilBlendColor(float3 dstCol, float3 srcCol, float3 srcA, int blendMode)
			{
				float3 ad = dstCol + srcCol;
				float3 mu = dstCol * srcCol;
				float3 outCol = float3(0, 0, 0);
				if (blendMode == 0) outCol = srcCol; // Normal
				if (blendMode == 1) outCol = ad; // Add
				if (blendMode == 2) outCol = max(ad - mu, dstCol); // Screen
				if (blendMode == 3) outCol = mu; // Multiply
				return lerp(dstCol, outCol, srcA);
			}
			
			float lilIsIn0to1(float f)
			{
				float value = 0.5 - abs(f - 0.5);
				return saturate(value / clamp(fwidth(value), 0.0001, 1.0));
			}
			
			float lilIsIn0to1(float f, float nv)
			{
				float value = 0.5 - abs(f - 0.5);
				return saturate(value / clamp(fwidth(value), 0.0001, nv));
			}
			
			float poiEdgeLinearNoSaturate(float value, float border)
			{
				return (value - border) / clamp(fwidth(value), 0.0001, 1.0);
			}
			
			float3 poiEdgeLinearNoSaturate(float value, float3 border)
			{
				return float3(
				(value - border.x) / clamp(fwidth(value), 0.0001, 1.0),
				(value - border.y) / clamp(fwidth(value), 0.0001, 1.0),
				(value - border.z) / clamp(fwidth(value), 0.0001, 1.0)
				);
			}
			
			float poiEdgeLinearNoSaturate(float value, float border, float blur)
			{
				float borderMin = saturate(border - blur * 0.5);
				float borderMax = saturate(border + blur * 0.5);
				return (value - borderMin) / saturate(borderMax - borderMin + fwidth(value));
			}
			
			float poiEdgeLinearNoSaturate(float value, float border, float blur, float borderRange)
			{
				float borderMin = saturate(border - blur * 0.5 - borderRange);
				float borderMax = saturate(border + blur * 0.5);
				return (value - borderMin) / saturate(borderMax - borderMin + fwidth(value));
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border)
			{
				// return (value - border) / clamp(fwidth(value), 0.0001, 1.0);
				
				float fwidthValue = fwidth(value);
				return smoothstep(border - fwidthValue, border + fwidthValue, value);
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border, float blur)
			{
				float fwidthValue = fwidth(value);
				float borderMin = saturate(border - blur * 0.5);
				float borderMax = saturate(border + blur * 0.5);
				return smoothstep(borderMin - fwidthValue, borderMax + fwidthValue, value);
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border, float blur, float borderRange)
			{
				float fwidthValue = fwidth(value);
				float borderMin = saturate(border - blur * 0.5 - borderRange);
				float borderMax = saturate(border + blur * 0.5);
				return smoothstep(borderMin - fwidthValue, borderMax + fwidthValue, value);
			}
			
			float poiEdgeNonLinear(float value, float border)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border));
			}
			
			float poiEdgeNonLinear(float value, float border, float blur)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border, blur));
			}
			
			float poiEdgeNonLinear(float value, float border, float blur, float borderRange)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border, blur, borderRange));
			}
			
			float poiEdgeLinear(float value, float border)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border));
			}
			
			float poiEdgeLinear(float value, float border, float blur)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border, blur));
			}
			
			float poiEdgeLinear(float value, float border, float blur, float borderRange)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border, blur, borderRange));
			}
			// From https : // github.com / lilxyzw / OpenLit / blob / main / Assets / OpenLit / core.hlsl
			float3 OpenLitLinearToSRGB(float3 col)
			{
				return LinearToGammaSpace(col);
			}
			
			float3 OpenLitSRGBToLinear(float3 col)
			{
				return GammaToLinearSpace(col);
			}
			
			float OpenLitLuminance(float3 rgb)
			{
				#if defined(UNITY_COLORSPACE_GAMMA)
				return dot(rgb, float3(0.22, 0.707, 0.071));
				#else
				return dot(rgb, float3(0.0396819152, 0.458021790, 0.00609653955));
				#endif
			}
			
			float3 AdjustLitLuminance(float3 rgb, float targetLuminance)
			{
				float currentLuminance;
				#if defined(UNITY_COLORSPACE_GAMMA)
				currentLuminance = dot(rgb, float3(0.22, 0.707, 0.071));
				#else
				currentLuminance = dot(rgb, float3(0.0396819152, 0.458021790, 0.00609653955));
				#endif
				
				float luminanceRatio = targetLuminance / currentLuminance;
				return rgb * luminanceRatio;
			}
			
			float3 ClampLuminance(float3 rgb, float minLuminance, float maxLuminance)
			{
				float currentLuminance = dot(rgb, float3(0.299, 0.587, 0.114));
				float minRatio = (currentLuminance != 0) ? minLuminance / currentLuminance : 1.0;
				float maxRatio = (currentLuminance != 0) ? maxLuminance / currentLuminance : 1.0;
				float luminanceRatio = clamp(min(maxRatio, max(minRatio, 1.0)), 0.0, 1.0);
				return lerp(rgb, rgb * luminanceRatio, luminanceRatio < 1.0);
			}
			
			float3 MaxLuminance(float3 rgb, float maxLuminance)
			{
				float currentLuminance = dot(rgb, float3(0.299, 0.587, 0.114));
				float luminanceRatio = (currentLuminance != 0) ? maxLuminance / max(currentLuminance, 0.00001) : 1.0;
				return lerp(rgb, rgb * luminanceRatio, currentLuminance > maxLuminance);
			}
			
			float OpenLitGray(float3 rgb)
			{
				return dot(rgb, float3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0));
			}
			
			void OpenLitShadeSH9ToonDouble(float3 lightDirection, out float3 shMax, out float3 shMin)
			{
				#if !defined(LIGHTMAP_ON)
				float3 N = lightDirection * 0.666666;
				float4 vB = N.xyzz * N.yzzx;
				// L0 L2
				float3 res = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
				res.r += dot(unity_SHBr, vB);
				res.g += dot(unity_SHBg, vB);
				res.b += dot(unity_SHBb, vB);
				res += unity_SHC.rgb * (N.x * N.x - N.y * N.y);
				// L1
				float3 l1;
				l1.r = dot(unity_SHAr.rgb, N);
				l1.g = dot(unity_SHAg.rgb, N);
				l1.b = dot(unity_SHAb.rgb, N);
				shMax = res + l1;
				shMin = res - l1;
				#if defined(UNITY_COLORSPACE_GAMMA)
				shMax = OpenLitLinearToSRGB(shMax);
				shMin = OpenLitLinearToSRGB(shMin);
				#endif
				#else
				shMax = 0.0;
				shMin = 0.0;
				#endif
			}
			
			float3 OpenLitComputeCustomLightDirection(float4 lightDirectionOverride)
			{
				float3 customDir = length(lightDirectionOverride.xyz) * normalize(mul((float3x3)unity_ObjectToWorld, lightDirectionOverride.xyz));
				return lightDirectionOverride.w ? customDir : lightDirectionOverride.xyz; // .w isn't doc'd anywhere and is always 0 unless end user changes it
			}
			
			float3 OpenLitLightingDirectionForSH9()
			{
				float3 mainDir = _WorldSpaceLightPos0.xyz * OpenLitLuminance(_LightColor0.rgb);
				#if !defined(LIGHTMAP_ON)
				float3 sh9Dir = unity_SHAr.xyz * 0.333333 + unity_SHAg.xyz * 0.333333 + unity_SHAb.xyz * 0.333333;
				float3 sh9DirAbs = float3(sh9Dir.x, abs(sh9Dir.y), sh9Dir.z);
				#else
				float3 sh9Dir = 0;
				float3 sh9DirAbs = 0;
				#endif
				
				float3 lightDirectionForSH9 = sh9Dir + mainDir;
				lightDirectionForSH9 = dot(lightDirectionForSH9, lightDirectionForSH9) < 0.000001 ? 0 : normalize(lightDirectionForSH9);
				return lightDirectionForSH9;
			}
			
			float3 OpenLitLightingDirection(float4 lightDirectionOverride)
			{
				float3 mainDir = _WorldSpaceLightPos0.xyz * OpenLitLuminance(_LightColor0.rgb);
				#if !defined(LIGHTMAP_ON) && UNITY_SHOULD_SAMPLE_SH
				float3 sh9Dir = unity_SHAr.xyz * 0.333333 + unity_SHAg.xyz * 0.333333 + unity_SHAb.xyz * 0.333333;
				float3 sh9DirAbs = float3(sh9Dir.x, abs(sh9Dir.y), sh9Dir.z);
				#else
				float3 sh9Dir = 0;
				float3 sh9DirAbs = 0;
				#endif
				float3 customDir = OpenLitComputeCustomLightDirection(lightDirectionOverride);
				
				return normalize(sh9DirAbs + mainDir + customDir);
			}
			
			float3 OpenLitLightingDirection()
			{
				float4 customDir = float4(0.001, 0.002, 0.001, 0.0);
				return OpenLitLightingDirection(customDir);
			}
			
			inline float4 CalculateFrustumCorrection()
			{
				float x1 = -UNITY_MATRIX_P._31 / (UNITY_MATRIX_P._11 * UNITY_MATRIX_P._34);
				float x2 = -UNITY_MATRIX_P._32 / (UNITY_MATRIX_P._22 * UNITY_MATRIX_P._34);
				return float4(x1, x2, 0, UNITY_MATRIX_P._33 / UNITY_MATRIX_P._34 + x1 * UNITY_MATRIX_P._13 + x2 * UNITY_MATRIX_P._23);
			}
			
			inline float CorrectedLinearEyeDepth(float z, float B)
			{
				return 1.0 / (z / UNITY_MATRIX_P._34 + B);
			}
			
			// Silent's code
			float2 sharpSample(float4 texelSize, float2 p)
			{
				p = p * texelSize.zw;
				float2 c = max(0.0, fwidth(p));
				p = floor(p) + saturate(frac(p) / c);
				p = (p - 0.5) * texelSize.xy;
				return p;
			}
			
			void applyToGlobalMask(inout PoiMods poiMods, int index, int blendType, float val)
			{
				float valBlended = saturate(maskBlend(poiMods.globalMask[index], val, blendType));
				switch(index)
				{
					case 0: poiMods.globalMask[0] = valBlended; break;
					case 1: poiMods.globalMask[1] = valBlended; break;
					case 2: poiMods.globalMask[2] = valBlended; break;
					case 3: poiMods.globalMask[3] = valBlended; break;
					case 4: poiMods.globalMask[4] = valBlended; break;
					case 5: poiMods.globalMask[5] = valBlended; break;
					case 6: poiMods.globalMask[6] = valBlended; break;
					case 7: poiMods.globalMask[7] = valBlended; break;
					case 8: poiMods.globalMask[8] = valBlended; break;
					case 9: poiMods.globalMask[9] = valBlended; break;
					case 10: poiMods.globalMask[10] = valBlended; break;
					case 11: poiMods.globalMask[11] = valBlended; break;
					case 12: poiMods.globalMask[12] = valBlended; break;
					case 13: poiMods.globalMask[13] = valBlended; break;
					case 14: poiMods.globalMask[14] = valBlended; break;
					case 15: poiMods.globalMask[15] = valBlended; break;
				}
			}
			
			void assignValueToVectorFromIndex(inout float4 vec, int index, float value)
			{
				switch(index)
				{
					case 0: vec[0] = value; break;
					case 1: vec[1] = value; break;
					case 2: vec[2] = value; break;
					case 3: vec[3] = value; break;
				}
			}
			
			// SNose
			float3 mod289(float3 x)
			{
				return x - floor(x * (1.0 / 289.0)) * 289.0;
			}
			float2 mod289(float2 x)
			{
				return x - floor(x * (1.0 / 289.0)) * 289.0;
			}
			float3 permute(float3 x)
			{
				return mod289(((x * 34.0) + 1.0) * x);
			}
			
			float snoise(float2 v)
			{
				const float4 C = float4(0.211324865405187, // (3.0 - sqrt(3.0)) / 6.0
				0.366025403784439, // 0.5 * (sqrt(3.0) - 1.0)
				- 0.577350269189626, // - 1.0 + 2.0 * C.x
				0.024390243902439); // 1.0 / 41.0
				float2 i = floor(v + dot(v, C.yy));
				float2 x0 = v - i + dot(i, C.xx);
				float2 i1;
				i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0);
				float4 x12 = x0.xyxy + C.xxzz;
				x12.xy -= i1;
				i = mod289(i); // Avoid truncation effects in permutation
				float3 p = permute(permute(i.y + float3(0.0, i1.y, 1.0))
				+ i.x + float3(0.0, i1.x, 1.0));
				
				float3 m = max(0.5 - float3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);
				m = m * m ;
				m = m * m ;
				float3 x = 2.0 * frac(p * C.www) - 1.0;
				float3 h = abs(x) - 0.5;
				float3 ox = floor(x + 0.5);
				float3 a0 = x - ox;
				m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);
				float3 g;
				g.x = a0.x * x0.x + h.x * x0.y;
				g.yz = a0.yz * x12.xz + h.yz * x12.yw;
				return 130.0 * dot(m, g);
			}
			
			float nsqDistance(float2 a, float2 b)
			{
				return dot(a - b, a - b);
			}
			
			float poiInvertToggle(in float value, in float toggle)
			{
				return (toggle == 0 ? value : 1 - value);
			}
			
			float3 PoiBlendNormal(float3 dstNormal, float3 srcNormal)
			{
				return float3(dstNormal.xy + srcNormal.xy, dstNormal.z * srcNormal.z);
			}
			
			float3 lilTransformDirOStoWS(float3 directionOS, bool doNormalize)
			{
				if (doNormalize) return normalize(mul((float3x3)unity_ObjectToWorld, directionOS));
				else            return mul((float3x3)unity_ObjectToWorld, directionOS);
			}
			
			float2 poiGetWidthAndHeight(Texture2D tex)
			{
				uint width, height;
				tex.GetDimensions(width, height);
				return float2(width, height);
			}
			
			float2 poiGetWidthAndHeight(Texture2DArray tex)
			{
				uint width, height, element;
				tex.GetDimensions(width, height, element);
				return float2(width, height);
			}
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			
			// Convenient mechanism to read from the AudioLink texture that handles reading off the end of one line and onto the next above it.
			float4 AudioLinkDataMultiline(uint2 xycoord)
			{
				return AudioLinkData(uint2(xycoord.x % AUDIOLINK_WIDTH, xycoord.y + xycoord.x / AUDIOLINK_WIDTH));
			}
			
			// Mechanism to sample between two adjacent pixels and lerp between them, like "linear" supesampling
			float4 AudioLinkLerp(float2 xy)
			{
				return lerp(AudioLinkData(xy), AudioLinkData(xy + int2(1, 0)), frac(xy.x));
			}
			
			// Same as AudioLinkLerp but properly handles multiline reading.
			float4 AudioLinkLerpMultiline(float2 xy)
			{
				return lerp(AudioLinkDataMultiline(xy), AudioLinkDataMultiline(xy + float2(1, 0)), frac(xy.x));
			}
			
			//Tests to see if Audio Link texture is available
			bool AudioLinkIsAvailable()
			{
				#if !defined(AUDIOLINK_STANDARD_INDEXING)
				int width, height;
				_AudioTexture.GetDimensions(width, height);
				return width > 16;
				#else
				return _AudioTexture_TexelSize.z > 16;
				#endif
			}
			
			//Get version of audiolink present in the world, 0 if no audiolink is present
			float AudioLinkGetVersion()
			{
				int2 dims;
				#if !defined(AUDIOLINK_STANDARD_INDEXING)
				_AudioTexture.GetDimensions(dims.x, dims.y);
				#else
				dims = _AudioTexture_TexelSize.zw;
				#endif
				
				if (dims.x >= 128)
				return AudioLinkData(ALPASS_GENERALVU).x;
				else if (dims.x > 16)
				return 1;
				else
				return 0;
			}
			
			// This pulls data from this texture.
			#define AudioLinkGetSelfPixelData(xy) _SelfTexture2D[xy]
			
			// Extra utility functions for time.
			uint AudioLinkDecodeDataAsUInt(uint2 indexloc)
			{
				uint4 rpx = AudioLinkData(indexloc);
				return rpx.r + rpx.g * 1024 + rpx.b * 1048576 + rpx.a * 1073741824;
			}
			
			//Note: This will truncate time to every 134,217.728 seconds (~1.5 days of an instance being up) to prevent floating point aliasing.
			// if your code will alias sooner, you will need to use a different function.  It should be safe to use this on all times.
			float AudioLinkDecodeDataAsSeconds(uint2 indexloc)
			{
				uint time = AudioLinkDecodeDataAsUInt(indexloc) & 0x7ffffff;
				//Can't just divide by float.  Bug in Unity's HLSL compiler.
				return float(time / 1000) + float(time % 1000) / 1000.;
			}
			
			#define ALDecodeDataAsSeconds(x) AudioLinkDecodeDataAsSeconds(x)
			#define ALDecodeDataAsUInt(x) AudioLinkDecodeDataAsUInt(x)
			
			float AudioLinkRemap(float t, float a, float b, float u, float v)
			{
				return ((t - a) / (b - a)) * (v - u) + u;
			}
			
			float3 AudioLinkHSVtoRGB(float3 HSV)
			{
				float3 RGB = 0;
				float C = HSV.z * HSV.y;
				float H = HSV.x * 6;
				float X = C * (1 - abs(fmod(H, 2) - 1));
				if (HSV.y != 0)
				{
					float I = floor(H);
					if (I == 0)
					{
						RGB = float3(C, X, 0);
					}
					else if (I == 1)
					{
						RGB = float3(X, C, 0);
					}
					else if (I == 2)
					{
						RGB = float3(0, C, X);
					}
					else if (I == 3)
					{
						RGB = float3(0, X, C);
					}
					else if (I == 4)
					{
						RGB = float3(X, 0, C);
					}
					else
					{
						RGB = float3(C, 0, X);
					}
				}
				float M = HSV.z - C;
				return RGB + M;
			}
			
			float3 AudioLinkCCtoRGB(float bin, float intensity, int rootNote)
			{
				float note = bin / AUDIOLINK_EXPBINS;
				
				float hue = 0.0;
				note *= 12.0;
				note = glsl_mod(4. - note + rootNote, 12.0);
				{
					if (note < 4.0)
					{
						//Needs to be YELLOW->RED
						hue = (note) / 24.0;
					}
					else if (note < 8.0)
					{
						//            [4]  [8]
						//Needs to be RED->BLUE
						hue = (note - 2.0) / 12.0;
					}
					else
					{
						//             [8] [12]
						//Needs to be BLUE->YELLOW
						hue = (note - 4.0) / 8.0;
					}
				}
				float val = intensity - 0.1;
				return AudioLinkHSVtoRGB(float3(fmod(hue, 1.0), 1.0, clamp(val, 0.0, 1.0)));
			}
			
			// Sample the amplitude of a given frequency in the DFT, supports frequencies in [13.75; 14080].
			float4 AudioLinkGetAmplitudeAtFrequency(float hertz)
			{
				float note = AUDIOLINK_EXPBINS * log2(hertz / AUDIOLINK_BOTTOM_FREQUENCY);
				return AudioLinkLerpMultiline(ALPASS_DFT + float2(note, 0));
			}
			
			// Sample the amplitude of a given semitone in an octave. Octave is in [0; 9] while note is [0; 11].
			float AudioLinkGetAmplitudeAtNote(float octave, float note)
			{
				float quarter = note * 2.0;
				return AudioLinkLerpMultiline(ALPASS_DFT + float2(octave * AUDIOLINK_EXPBINS + quarter, 0));
			}
			
			// Get a reasonable drop-in replacement time value for _Time.y with the
			// given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTime(uint index, uint band)
			{
				return (AudioLinkDecodeDataAsUInt(ALPASS_CHRONOTENSITY + uint2(index, band))) / 100000.0;
			}
			
			// Get a chronotensity value in the interval [0; 1], modulated by the speed input,
			// with the given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTimeNormalized(uint index, uint band, float speed)
			{
				return frac(AudioLinkGetChronoTime(index, band) * speed);
			}
			
			// Get a chronotensity value in the interval [0; interval], modulated by the speed input,
			// with the given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTimeInterval(uint index, uint band, float speed, float interval)
			{
				return AudioLinkGetChronoTimeNormalized(index, band, speed) * interval;
			}
			
			float getBandAtTime(float band, float time, float size = 1.0f)
			{
				//return remap(UNITY_SAMPLE_TEX2D(_AudioTexture, float2(time * width, band/128.0)).r, min(size,.9999), 1);
				return remapClamped(min(size, .9999), 1, AudioLinkData(ALPASS_AUDIOBASS + uint2(time * AUDIOLINK_WIDTH, band)).r);
			}
			
			fixed3 maximize(fixed3 c)
			{
				if (c.x == 0 && c.y == 0 && c.z == 0)
				return fixed3(1.0, 1.0, 1.0);
				else
				return c / max(c.r, max(c.g, c.b));
			}
			
			void initPoiAudioLink(inout PoiMods poiMods)
			{
				if (!_AudioLinkAnimToggle) return;
				
				if (AudioLinkIsAvailable())
				{
					poiMods.audioLinkAvailable = true;
					poiMods.audioLinkVersion = AudioLinkGetVersion();
					poiMods.audioLink[0] = _AudioLinkSmoothingBass == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 0))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingBass) * 15.95, 0))[0];
					poiMods.audioLink[1] = _AudioLinkSmoothingLowMid == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 1))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingLowMid) * 15.95, 1))[0];
					poiMods.audioLink[2] = _AudioLinkSmoothingHighMid == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 2))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingHighMid) * 15.95, 2))[0];
					poiMods.audioLink[3] = _AudioLinkSmoothingTreble == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 3))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingTreble) * 15.95, 3))[0];
					poiMods.audioLink[4] = AudioLinkData(ALPASS_GENERALVU + float2(8, 0))[0];
					/*
					poiMods.globalColorTheme[4] = AudioLinkData( ALPASS_CCCOLORS + uint2( 0, 0 ) );
					poiMods.globalColorTheme[5] = AudioLinkData( ALPASS_CCCOLORS + uint2( 1, 0 ) );
					poiMods.globalColorTheme[6] = AudioLinkData( ALPASS_CCCOLORS + uint2( 2, 0 ) );
					poiMods.globalColorTheme[7] = AudioLinkData( ALPASS_CCCOLORS + uint2( 3, 0 ) );
					
					poiMods.globalColorTheme[4] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 0, 0 ) )),1.0);
					poiMods.globalColorTheme[5] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 1, 0 ) )),1.0);
					poiMods.globalColorTheme[6] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 2, 0 ) )),1.0);
					poiMods.globalColorTheme[7] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 3, 0 ) )),1.0);
					*/
					
					poiMods.globalColorTheme[4] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(2, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[5] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(3, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[6] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(4, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[7] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(5, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					
					poiMods.globalColorTheme[8] = AudioLinkData(ALPASS_THEME_COLOR0);
					poiMods.globalColorTheme[9] = AudioLinkData(ALPASS_THEME_COLOR1);
					poiMods.globalColorTheme[10] = AudioLinkData(ALPASS_THEME_COLOR2);
					poiMods.globalColorTheme[11] = AudioLinkData(ALPASS_THEME_COLOR3);
					return;
				}
				
				if (_AudioLinkBandOverridesEnabled)
				{
					poiMods.audioLinkAvailable = true;
					poiMods.audioLink[0] = _AudioLinkBandOverrideSliders.x;
					poiMods.audioLink[1] = _AudioLinkBandOverrideSliders.y;
					poiMods.audioLink[2] = _AudioLinkBandOverrideSliders.z;
					poiMods.audioLink[3] = _AudioLinkBandOverrideSliders.w;
				}
			}
			
			void DebugVisualizer(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				if (_DebugWaveform)
				{
					float waveform = AudioLinkLerpMultiline(ALPASS_WAVEFORM + float2(500. * poiMesh.uv[0].x, 0)).r;
					poiFragData.emission += clamp(1 - 50 * abs(waveform - poiMesh.uv[0].y * 2. + 1), 0, 1);
				}
				if (_DebugDFT)
				{
					poiFragData.emission += AudioLinkLerpMultiline(ALPASS_DFT + uint2(poiMesh.uv[0].x * AUDIOLINK_ETOTALBINS, 0)).rrr;
				}
				if (_DebugBass)
				{
					poiFragData.emission += poiMods.audioLink[0];
				}
				if (_DebugLowMids)
				{
					poiFragData.emission += poiMods.audioLink[1];
				}
				if (_DebugHighMids)
				{
					poiFragData.emission += poiMods.audioLink[2];
				}
				if (_DebugTreble)
				{
					poiFragData.emission += poiMods.audioLink[3];
				}
				if (_DebugCCColors)
				{
					poiFragData.emission += AudioLinkData(ALPASS_CCCOLORS + uint2(3 + 1, 0));
				}
				if (_DebugCCStrip)
				{
					poiFragData.emission += AudioLinkLerp(ALPASS_CCSTRIP + float2(poiMesh.uv[0].x * AUDIOLINK_WIDTH, 0));
				}
				if (_DebugCCLights)
				{
					poiFragData.emission += AudioLinkData(ALPASS_CCLIGHTS + uint2(uint(poiMesh.uv[0].x * 8) + uint(poiMesh.uv[0].y * 16) * 8, 0));
				}
				if (_DebugAutocorrelator)
				{
					poiFragData.emission += saturate(AudioLinkLerp(ALPASS_AUTOCORRELATOR + float2((abs(1. - poiMesh.uv[0].x * 2.)) * AUDIOLINK_WIDTH, 0)).rrr);
				}
				if (_DebugChronotensity)
				{
					poiFragData.emission += (AudioLinkDecodeDataAsUInt(ALPASS_CHRONOTENSITY + uint2(1, 0)) % 1000000) / 1000000.0;
				}
			}
			
			void SetupAudioLink(inout PoiFragData poiFragData, inout PoiMods poiMods, in PoiMesh poiMesh)
			{
				initPoiAudioLink(poiMods);
				DebugVisualizer(poiFragData, poiMesh, poiMods);
				
				if (_AudioLinkCCStripY)
				{
					poiFragData.emission += AudioLinkLerp(ALPASS_CCSTRIP + float2(poiMesh.uv[0].y * AUDIOLINK_WIDTH, 0)).rgb * .5;
				}
			}
			
			#endif
			//endex
			
			//ifex _BSSEnabled!=1
			#ifdef POIBS_ENABLE
			//ifex _BSSBloomfog!=1
			#ifdef POIBS_BLOOMFOG
			inline float4 GetFogCoord(float4 clipPos)
			{
				float4 screenPos = ComputeNonStereoScreenPos(clipPos);
				float2 screenPosNormalized = screenPos.xy / screenPos.w;
				float eyeOffset = (unity_StereoEyeIndex * (_StereoCameraEyeOffset * 2)) + - _StereoCameraEyeOffset;
				return float4(
				((eyeOffset +screenPosNormalized.x) + - 0.5) * _CustomFogTextureToScreenRatio.x + 0.5,
				(screenPosNormalized.y + - 0.5) * _CustomFogTextureToScreenRatio.y + 0.5
				,clipPos.z,clipPos.w);
			}
			
			inline float GetHeightFogIntensity(float3 worldPos, float fogHeightOffset, float fogHeightScale)
			{
				float heightFogIntensity = _CustomFogHeightFogHeight + _CustomFogHeightFogStartY;
				heightFogIntensity = ((worldPos.y * fogHeightScale) + fogHeightOffset) + - heightFogIntensity;
				heightFogIntensity = heightFogIntensity / _CustomFogHeightFogHeight;
				heightFogIntensity = clamp(heightFogIntensity, 0, 1);
				return ((-heightFogIntensity * 2) + 3) * (heightFogIntensity * heightFogIntensity);
			}
			
			inline float GetFogIntensity(float3 distance, float fogStartOffset, float fogScale)
			{
				float fogIntensity = max(dot(distance, distance) + - fogStartOffset, 0);
				fogIntensity = max((fogIntensity * fogScale) + - _CustomFogOffset, 0);
				fogIntensity = 1 / ((fogIntensity * _CustomFogAttenuation) + 1);
				return -fogIntensity;
			}
			#endif
			//endex
			#endif
			//endex
			
			VertexOut vert(
			#ifndef POI_TESSELLATED
			appdata v
			#else
			tessAppData v
			#endif
			)
			{
				UNITY_SETUP_INSTANCE_ID(v);
				VertexOut o;
				PoiInitStruct(VertexOut, o);
				UNITY_TRANSFER_INSTANCE_ID(v, o);
				#ifdef POI_TESSELLATED
				UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v);
				#endif
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
				
				//ifex _EnableUDIMDiscardOptions==0
				#ifdef POI_UDIMDISCARD
				UNITY_BRANCH
				if(_UDIMDiscardMode == 0) // Discard Vertices instead of just pixels
				{
					// Branchless (inspired by s-ilent)
					float2 udim = 0;
					// Select UV
					udim += (v.uv0.xy * (_UDIMDiscardUV == 0));
					udim += (v.uv1.xy * (_UDIMDiscardUV == 1));
					udim += (v.uv2.xy * (_UDIMDiscardUV == 2));
					udim += (v.uv3.xy * (_UDIMDiscardUV == 3));
					
					float isDiscarded = 0;
					float4 xMask = float4(  (udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					isDiscarded += (udim.y >= 0 && udim.y < 1) * dot(float4(_UDIMDiscardRow0_0, _UDIMDiscardRow0_1, _UDIMDiscardRow0_2, _UDIMDiscardRow0_3), xMask);
					isDiscarded += (udim.y >= 1 && udim.y < 2) * dot(float4(_UDIMDiscardRow1_0, _UDIMDiscardRow1_1, _UDIMDiscardRow1_2, _UDIMDiscardRow1_3), xMask);
					isDiscarded += (udim.y >= 2 && udim.y < 3) * dot(float4(_UDIMDiscardRow2_0, _UDIMDiscardRow2_1, _UDIMDiscardRow2_2, _UDIMDiscardRow2_3), xMask);
					isDiscarded += (udim.y >= 3 && udim.y < 4) * dot(float4(_UDIMDiscardRow3_0, _UDIMDiscardRow3_1, _UDIMDiscardRow3_2, _UDIMDiscardRow3_3), xMask);
					
					isDiscarded *= any(float4(udim.y >= 0, udim.y < 4, udim.x >= 0, udim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					// Use a threshold so that there's some room for animations to be close to 0, but not exactly 0
					const float threshold = 0.001;
					if(isDiscarded > threshold) // Early Return skips rest of vertex shader
					{
						return (VertexOut)POI_NAN;
					}
				}
				#endif
				//endex
				
				//ifex _VertexManipulationsEnabled==0
				#ifdef AUTO_EXPOSURE
				float4 audioLinkBands = 0;
				float3 ALrotation = 0;
				float3 ALLocalTranslation = 0;
				float3 CTALRotation = 0;
				float3 ALScale = 0;
				float3 ALWorldTranslation = 0;
				float ALHeight = 0;
				float ALRoundingAmount = 0;
				float4 ALSpectrumLocalOffset = float4(0, 0, 0, 0);
				#ifdef POI_AUDIOLINK
				if (AudioLinkIsAvailable() && _VertexAudioLinkEnabled && _AudioLinkAnimToggle)
				{
					audioLinkBands.x = AudioLinkData(ALPASS_AUDIOBASS).r;
					audioLinkBands.y = AudioLinkData(ALPASS_AUDIOLOWMIDS).r;
					audioLinkBands.z = AudioLinkData(ALPASS_AUDIOHIGHMIDS).r;
					audioLinkBands.w = AudioLinkData(ALPASS_AUDIOTREBLE).r;
					
					if (any(_VertexLocalTranslationALMin) || any(_VertexLocalTranslationALMax))
					{
						ALLocalTranslation = lerp(_VertexLocalTranslationALMin, _VertexLocalTranslationALMax, audioLinkBands[_VertexLocalTranslationALBand]);
					}
					if (any(_VertexLocalRotationAL))
					{
						ALrotation = audioLinkBands[_VertexLocalRotationALBand] * _VertexLocalRotationAL;
					}
					if (any(_VertexLocalRotationCTALSpeed))
					{
						CTALRotation.x = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeX, _VertexLocalRotationCTALBandX) * _VertexLocalRotationCTALSpeed.x * 360;
						CTALRotation.y = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeY, _VertexLocalRotationCTALBandY) * _VertexLocalRotationCTALSpeed.y * 360;
						CTALRotation.z = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeZ, _VertexLocalRotationCTALBandZ) * _VertexLocalRotationCTALSpeed.z * 360;
					}
					if (any(_VertexLocalScaleALMin) || any(_VertexLocalScaleALMax))
					{
						ALScale = lerp(_VertexLocalScaleALMin.xyz + _VertexLocalScaleALMin.w, _VertexLocalScaleALMax.xyz + _VertexLocalScaleALMax.w, audioLinkBands[_VertexLocalScaleALBand]);
					}
					if (any(_VertexWorldTranslationALMin) || any(_VertexWorldTranslationALMax))
					{
						ALWorldTranslation = lerp(_VertexWorldTranslationALMin, _VertexWorldTranslationALMax, audioLinkBands[_VertexWorldTranslationALBand]);
					}
					if (any(_VertexManipulationHeightAL))
					{
						ALHeight = lerp(_VertexManipulationHeightAL.x, _VertexManipulationHeightAL.y, audioLinkBands[_VertexManipulationHeightBand]);
					}
					if (any(_VertexRoundingRangeAL))
					{
						ALRoundingAmount = lerp(_VertexRoundingRangeAL.x, _VertexRoundingRangeAL.y, audioLinkBands[_VertexRoundingRangeBand]);
					}
					if (_VertexSpectrumMotion)
					{
						ALSpectrumLocalOffset.xyz = lerp(_VertexSpectrumOffsetMin.xyz, _VertexSpectrumOffsetMax.xyz, AudioLinkLerpMultiline(ALPASS_DFT + float2(vertexUV(v, _VertexSpectrumUV)[_VertexSpectrumUVDirection] * AUDIOLINK_ETOTALBINS, 0.)));
					}
				}
				#endif
				
				// Local Transformation
				float4 rotation = float4(_VertexManipulationLocalRotation.xyz + float3(180, 0, 0) + _VertexManipulationLocalRotationSpeed * _Time.x + ALrotation + CTALRotation, _VertexManipulationLocalRotation.w);
				v.normal = rotate_with_quaternion(v.normal, rotation.xyz);
				v.tangent.xyz = rotate_with_quaternion(v.tangent.xyz, rotation.xyz);
				v.vertex = transform(v.vertex, _VertexManipulationLocalTranslation + float4(ALLocalTranslation, 0) + ALSpectrumLocalOffset, rotation, _VertexManipulationLocalScale + float4(ALScale, 0));
				o.normal = UnityObjectToWorldNormal(v.normal);
				
				#if defined(PROP_VERTEXMANIPULATIONHEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float3 heightOffset = (tex2Dlod(_VertexManipulationHeightMask, float4(poiUV(vertexUV(v, _VertexManipulationHeightMaskUV), _VertexManipulationHeightMask_ST) + _VertexManipulationHeightMaskPan * _Time.x, 0, 0))[_VertexManipulationHeightMaskChannel] - _VertexManipulationHeightBias) * (_VertexManipulationHeight + ALHeight) * o.normal;
				#else
				float3 heightOffset = (_VertexManipulationHeight + ALHeight) * o.normal;
				#endif
				
				if (_VertexBarrelMode)
				{
					v.vertex.xz = lerp(v.vertex.xz, normalize(v.vertex.xz) * _VertexBarrelWidth + v.vertex.xz * _VertexBarrelHeight, _VertexBarrelAlpha);
				}
				
				if (_VertexSphereMode)
				{
					v.vertex.xyz = lerp(v.vertex.xyz, normalize(v.vertex.xyz + _VertexSphereCenter.xyz) * _VertexSphereRadius + v.vertex.xyz * _VertexSphereHeight, _VertexSphereAlpha);
				}
				
				if (_VertexTornadoMode)
				{
					v.vertex.xz = lerp(v.vertex.xz, float3(v.vertex.xz + float2(cos(_Time.y * _VertexTornadoSpeed + v.vertex.y * _VertexTornadoIntensity) * _VertexTornadoRadius, sin(_Time.y * _VertexTornadoSpeed + v.vertex.y * _VertexTornadoIntensity) * _VertexTornadoRadius), v.vertex.y), smoothstep(_VertexTornadoBaseHeight, _VertexTornadoTopHeight, v.vertex.y));
				}
				
				v.vertex.xyz += mul(unity_WorldToObject, _VertexManipulationWorldTranslation.xyz + ALWorldTranslation + heightOffset).xyz;
				
				// rounding
				UNITY_BRANCH
				if (_VertexRoundingEnabled)
				{
					float divisionAmount = max(_VertexRoundingDivision + ALRoundingAmount, 0.0000001);
					if (_VertexRoundingSpace == 0)
					{
						float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
						float3 worldRoundPosition = (ceil(worldPos.xyz / divisionAmount) * divisionAmount) - divisionAmount * .5;
						v.vertex = mul(unity_WorldToObject, float4(worldRoundPosition, worldPos.w));
					}
					else if (_VertexRoundingSpace == 1)
					{
						v.vertex.xyz = (ceil(v.vertex.xyz / divisionAmount) * divisionAmount) - divisionAmount * .5;
					}
				}
				#endif
				//endex
				
				//ifex _EnableDissolve==0
				#ifdef DISTORT
				UNITY_BRANCH
				if (_UVTileDissolveEnabled && _UVTileDissolveDiscardAtMax)
				{
					// Branchless (inspired by s-ilent)
					float2 dissolveUdim = 0;
					// Select UV
					dissolveUdim += (v.uv0.xy * (_UVTileDissolveUV == 0));
					dissolveUdim += (v.uv1.xy * (_UVTileDissolveUV == 1));
					dissolveUdim += (v.uv2.xy * (_UVTileDissolveUV == 2));
					dissolveUdim += (v.uv3.xy * (_UVTileDissolveUV == 3));
					
					float isDiscardedFromDissolve = 0;
					float4 xMaskDissolve = float4((dissolveUdim.x >= 0 && dissolveUdim.x < 1),
					(dissolveUdim.x >= 1 && dissolveUdim.x < 2),
					(dissolveUdim.x >= 2 && dissolveUdim.x < 3),
					(dissolveUdim.x >= 3 && dissolveUdim.x < 4));
					
					isDiscardedFromDissolve += (dissolveUdim.y >= 0 && dissolveUdim.y < 1) * dot(float4(_UVTileDissolveAlpha_Row0_0, _UVTileDissolveAlpha_Row0_1, _UVTileDissolveAlpha_Row0_2, _UVTileDissolveAlpha_Row0_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 1 && dissolveUdim.y < 2) * dot(float4(_UVTileDissolveAlpha_Row1_0, _UVTileDissolveAlpha_Row1_1, _UVTileDissolveAlpha_Row1_2, _UVTileDissolveAlpha_Row1_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 2 && dissolveUdim.y < 3) * dot(float4(_UVTileDissolveAlpha_Row2_0, _UVTileDissolveAlpha_Row2_1, _UVTileDissolveAlpha_Row2_2, _UVTileDissolveAlpha_Row2_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 3 && dissolveUdim.y < 4) * dot(float4(_UVTileDissolveAlpha_Row3_0, _UVTileDissolveAlpha_Row3_1, _UVTileDissolveAlpha_Row3_2, _UVTileDissolveAlpha_Row3_3), xMaskDissolve);
					
					isDiscardedFromDissolve *= any(float4(dissolveUdim.y >= 0, dissolveUdim.y < 4, dissolveUdim.x >= 0, dissolveUdim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					// Use a threshold so that there's some room for animations to be close to 1, but not exactly 1
					const float threshold = 0.999;
					if (isDiscardedFromDissolve > threshold) // Early Return skips rest of vertex shader
					
					{
						return (VertexOut)POI_NAN;
					}
				}
				#endif
				//endex
				
				//ifex _EnableMirrorOptions==0
				#ifdef POI_MIRROR
				float notVisible = 0;
				
				if (_VisibilityMode == 1) // VRC
				
				{
					float mirrorMode = VRCMirrorMode();
					float cameraMode = VRCCameraMode();
					
					notVisible += (!_VisibilityVRCRegular && ((mirrorMode == 0) && (cameraMode == 0)));
					notVisible += (!_VisibilityVRCMirrorVR && (mirrorMode == 1));
					notVisible += (!_VisibilityVRCMirrorDesktop && (mirrorMode == 2));
					notVisible += (!_VisibilityVRCCameraVR && (cameraMode == 1));
					notVisible += (!_VisibilityVRCCameraDesktop && (cameraMode == 2));
					notVisible += (!_VisibilityVRCCameraScreenshot && (cameraMode == 3));
				}
				else if (_Mirror != 0) // Generic (CVR, etc)
				
				{
					notVisible += (_Mirror == 1) ^ IsInMirror();
				}
				
				if (notVisible) // Early Return skips rest of vertex shader
				
				{
					return (VertexOut)POI_NAN;
				}
				#endif
				//endex
				
				o.normal = UnityObjectToWorldNormal(v.normal);
				o.tangent.xyz = UnityObjectToWorldDir(v.tangent);
				o.tangent.w = v.tangent.w;
				o.vertexColor = v.color;
				
				o.uv[0] = float4(v.uv0.xy, v.uv1.xy);
				o.uv[1] = float4(v.uv2.xy, v.uv3.xy);
				
				#if defined(LIGHTMAP_ON)
				o.lightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
				#endif
				#ifdef DYNAMICLIGHTMAP_ON
				o.lightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
				#endif
				
				o.localPos = v.vertex;
				o.worldPos = mul(unity_ObjectToWorld, o.localPos);
				
				float3 localOffset = float3(0, 0, 0);
				float3 worldOffset = float3(0, 0, 0);
				
				//ifex _EnableOutlines!=1
				#ifdef POI_PASS_OUTLINE
				float outlineMask = tex2Dlod(_OutlineMask, float4(poiUV(vertexUV(v, _OutlineMaskUV), _OutlineMask_ST) + _Time.x * _OutlineMaskPan, 0, 0))[_OutlineMaskChannel];
				
				//UNITY_BRANCH
				if (_OutlineVertexColorMask > 0)
				{
					outlineMask *= lerp(1, v.color[_OutlineVertexColorMask - 1], _OutlineVertexColorMaskStrength);
				}
				
				float3 outlineNormal = _OutlineSpace ? o.normal : v.normal;
				//UNITY_BRANCH
				if (_OutlineUseVertexColorNormals)
				{
					float3 outlineTangent;
					float3 outlineBinormal;
					if (_OutlineSpace) // 0 Local, 1 World
					
					{
						outlineTangent = o.tangent;
						outlineBinormal = cross(o.normal, o.tangent) * (v.tangent.w * unity_WorldTransformParams.w);
					}
					else
					{
						outlineTangent = v.tangent.xyz;
						outlineBinormal = normalize(cross(outlineNormal, outlineTangent)) * (v.tangent.w * length(outlineNormal));
					}
					float3 outlineVectorTS = v.color.rgb * 2.0 - 1.0;
					outlineNormal = outlineVectorTS.x * outlineTangent + outlineVectorTS.y * outlineBinormal + outlineVectorTS.z * outlineNormal;
				}
				
				float offsetMultiplier = 1;
				float distanceOffset = 1;
				//UNITY_BRANCH
				if (_OutlineFixedSize)
				{
					distanceOffset *= lerp(1.0, clamp((distance(_WorldSpaceCameraPos, mul(unity_ObjectToWorld, o.localPos).xyz)), 0.0f, _OutlinesMaxDistance), _OutlineFixWidth);
				}
				
				float lineWidth = _LineWidth;
				#ifdef POI_AUDIOLINK
				// Due to PoiMods.audioLink being frag only I'll just
				// recreate what it does here for this vertex function
				//UNITY_BRANCH
				if (_AudioLinkAnimToggle)
				{
					if (AudioLinkIsAvailable())
					{
						lineWidth += lerp(_AudioLinkOutlineSize.x, _AudioLinkOutlineSize.y, AudioLinkData(uint2(0, _AudioLinkOutlineSizeBand)));
					}
				}
				#endif
				
				float3 offset = outlineNormal * (lineWidth * _EnableOutlines / 100) * outlineMask * distanceOffset;
				
				//UNITY_BRANCH
				if (_OutlineExpansionMode == 2)
				{
					float3 lightDirection = normalize(_WorldSpaceLightPos0 + unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz);
					offsetMultiplier = saturate(dot(lightDirection, outlineNormal));
					offset *= offsetMultiplier;
					offset *= distanceOffset;
				}
				else if (_OutlineExpansionMode == 3)
				{
					float3 viewNormal = mul((float3x3)UNITY_MATRIX_V, outlineNormal);
					offsetMultiplier = saturate(dot(viewNormal.xy, normalize(_OutlinePersonaDirection.xy)));
					
					offset *= offsetMultiplier;
					offset *= distanceOffset;
				}
				else if (_OutlineExpansionMode == 4)
				{
					offset = mul((float3x3)transpose(UNITY_MATRIX_V), _OutlineDropShadowOffset);
					offset *= distanceOffset;
				}
				if (_OutlineSpace == 0)
				{
					localOffset += offset;
					worldOffset += mul(unity_ObjectToWorld, offset);
				}
				else
				{
					localOffset += mul(unity_WorldToObject, offset);
					worldOffset += offset;
				}
				#endif
				//endex
				
				//ifex _VertexGlitchingEnabled==0
				#if defined(POI_VERTEX_GLITCHING)
				
				bool canGlitch = true;
				if (_VertexGlitchMirrorEnable && _VertexGlitchMirror > 0)
				{
					bool inMirror = IsInMirror();
					if (_VertexGlitchMirror == 1 && !inMirror)	canGlitch = false;
					if (_VertexGlitchMirror == 2 && inMirror)	canGlitch = false;
				}
				if (canGlitch)
				{
					float3 forward = getCameraPosition() - mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
					forward.y = 0;
					forward = normalize(forward);
					float3 glitchDirection = normalize(cross(float3(0, 1, 0), forward));
					
					float glitchAmount = 0;
					
					#if defined(POI_VERTEX_GLITCHING_TEXTURE)
					// if(_VertexGlitchingUseTexture)
					// {
					float uvl = o.worldPos.y * _VertexGlitchDensity + _Time.x * _VertexGlitchMapPanSpeed;
					float uvr = o.worldPos.y * _VertexGlitchDensity - _Time.x * _VertexGlitchMapPanSpeed;
					
					float3 glitchTextureL = 1;
					float3 glitchTextureR = 1;
					
					#if defined(POI_VERTEX_GLITCHING_TEXTURE) || !defined(OPTIMIZER_ENABLED)
					glitchTextureL = tex2Dlod(_VertexGlitchMap, float4(uvl, uvl, 0, 0)).rgb;
					glitchTextureR = tex2Dlod(_VertexGlitchMap, float4(uvr, uvr, 0, 0)).rgb;
					#endif
					
					glitchAmount += (glitchTextureL.r - 0.5) * 2;
					glitchAmount += - (glitchTextureR.r - 0.5) * 2;
					
					glitchAmount += (glitchTextureL.g - 0.5) * 2;
					glitchAmount += - (glitchTextureR.b - 0.5) * 2;
					// } else {
					#else
					glitchAmount += frac(sin(dot(_Time.xy + o.worldPos.y, float2(12.9898, 78.233))) * 43758.5453123) * 2 - 1;
					// }
					#endif
					
					float time = _Time.y * _VertexGlitchFrequency;
					
					float randomGlitch = (sin(time) + sin(2.2 * time + 5.52) + sin(2.9 * time + 0.93) + sin(4.6 * time + 8.94)) / 4;
					float3 glitchOffset = 0;
					
					#ifdef POI_AUDIOLINK
					if (AudioLinkIsAvailable() && _VertexGlitchingAudioLinkEnabled)
					{
						// float4 audioLinkData = AudioLinkData(ALPASS_AUDIOBASS);
						
						float audioIntensity =
						AudioLinkData(ALPASS_AUDIOBASS).r 		* (_VertexGlitchingAudioLinkBand == 0) +
						AudioLinkData(ALPASS_AUDIOLOWMIDS).r 	* (_VertexGlitchingAudioLinkBand == 1) +
						AudioLinkData(ALPASS_AUDIOHIGHMIDS).r	* (_VertexGlitchingAudioLinkBand == 2) +
						AudioLinkData(ALPASS_AUDIOTREBLE).r 	* (_VertexGlitchingAudioLinkBand == 3) +
						AudioLinkData(ALPASS_FILTEREDVU_INTENSITY).r * (_VertexGlitchingAudioLinkBand == 4);
						
						if(_VertexGlitchingAudiolinkOverride)
						{
							glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
							// glitchOffset += glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
						} else {
							glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
							glitchOffset += glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
						}
					} else {
						glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
					}
					#else
					glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
					#endif
					
					localOffset += glitchOffset;
					worldOffset += mul(unity_ObjectToWorld, glitchOffset);
				}
				#endif
				//endex
				
				o.localPos.rgb += localOffset;
				o.worldPos.rgb += worldOffset;
				
				//ifex _EnableDepthBulge==0
				#if defined(POI_DEPTHBULGE) && (defined(POI_PASS_BASE) || defined(POI_PASS_ADD))
				applyDepthBulgeFX(o);
				#endif
				//endex
				
				//ifex _BSSEnabled!=1
				#ifdef POIBS_ENABLE
				//ifex _BSSBloomfog!=1
				#ifdef POIBS_BLOOMFOG
				o.fogCoord = GetFogCoord(UnityObjectToClipPos(v.vertex));
				o.worldPos = mul(unity_ObjectToWorld, v.vertex);
				#endif
				//endex
				#endif
				//endex
				
				o.pos = UnityObjectToClipPos(o.localPos);
				
				#ifdef POI_PASS_OUTLINE
				#if defined(UNITY_REVERSED_Z)
				//DX
				o.pos.z += _Offset_Z * - 0.01;
				#else
				//OpenGL
				o.pos.z += _Offset_Z * 0.01;
				#endif
				#endif
				//o.grabPos = ComputeGrabScreenPos(o.pos);
				
				#ifndef FORWARD_META_PASS
				#if !defined(UNITY_PASS_SHADOWCASTER)
				UNITY_TRANSFER_SHADOW(o, o.uv[0].xy);
				#else
				v.vertex.xyz = o.localPos.xyz;
				TRANSFER_SHADOW_CASTER_NOPOS(o, o.pos);
				#endif
				#endif
				
				UNITY_TRANSFER_FOG(o, o.pos);
				
				if (_RenderingReduceClipDistance)
				{
					if (o.pos.w < _ProjectionParams.y * 1.01 && o.pos.w > 0)
					{
						#if defined(UNITY_REVERSED_Z) // DirectX
						o.pos.z = o.pos.z * 0.0001 + o.pos.w * 0.999;
						#else // OpenGL
						o.pos.z = o.pos.z * 0.0001 - o.pos.w * 0.999;
						#endif
					}
				}
				
				#ifdef POI_PASS_META
				o.pos = UnityMetaVertexPosition(v.vertex, v.uv1.xy, v.uv2.xy, unity_LightmapST, unity_DynamicLightmapST);
				#endif
				
				return o;
			}
			
			#if defined(_STOCHASTICMODE_DELIOT_HEITZ)
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, uv) : POI2D_SAMPLER(tex, texSampler, uv))
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan)) : POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), dx, dy) : POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			#if defined(_STOCHASTICMODE_HEXTILE)
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, uv, false) : POI2D_SAMPLER(tex, texSampler, uv))
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), false) : POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), false, dx, dy) : POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			
			#ifndef POI2D_SAMPLER_STOCHASTIC
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (POI2D_SAMPLER(tex, texSampler, uv))
			#endif
			#ifndef POI2D_SAMPLER_PAN_STOCHASTIC
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#endif
			#ifndef POI2D_SAMPLER_PANGRAD_STOCHASTIC
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			
			// When using, properties won't properly lock at optimize time; needs macro evaluation implemented
			// #define POI2D_SAMPLER_STOCHASTIC_INLINED(tex, texSampler) (POI2D_SAMPLER_STOCHASTIC(tex, texSampler, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Stochastic))
			// #define POI2D_SAMPLER_PAN_STOCHASTIC_INLINED(tex, texSampler) (POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan, tex##Stochastic))
			
			// #define POI2D_MAINTEX_SAMPLER_STOCHASTIC_INLINED(tex) (POI2D_SAMPLER_STOCHASTIC(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Stochastic))
			// #define POI2D_MAINTEX_SAMPLER_PAN_STOCHASTIC_INLINED(tex) (POI2D_SAMPLER_PAN_STOCHASTIC(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan, tex##Stochastic))
			
			// Deliot, Heitz 2019 - Fast, but non-histogram-preserving (ends up looking a bit blurry and lower contrast)
			// https://eheitzresearch.wordpress.com/738-2/
			
			// Classic Magic Numbers fracsin
			#if !defined(_STOCHASTICMODE_NONE)
			float2 StochasticHash2D2D (float2 s)
			{
				return frac(sin(glsl_mod(float2(dot(s, float2(127.1,311.7)), dot(s, float2(269.5,183.3))), 3.14159)) * 43758.5453);
			}
			#endif
			
			#if defined(_STOCHASTICMODE_DELIOT_HEITZ)
			// UV Offsets and blend weights
			// UVBW[0...2].xy = UV Offsets
			// UVBW[0...2].z = Blend Weights
			float3x3 DeliotHeitzStochasticUVBW(float2 uv)
			{
				// UV transformed into triangular grid space with UV scaled by approximation of 2*sqrt(3)
				const float2x2 stochasticSkewedGrid = float2x2(1.0, -0.57735027, 0.0, 1.15470054);
				float2 skewUV = mul(stochasticSkewedGrid, uv * 3.4641 * _StochasticDeliotHeitzDensity);
				
				// Vertex IDs and barycentric coords
				float2 vxID = floor(skewUV);
				float3 bary = float3(frac(skewUV), 0);
				bary.z = 1.0 - bary.x - bary.y;
				
				float3x3 pos = float3x3(
				float3(vxID, 				bary.z),
				float3(vxID + float2(0, 1), bary.y),
				float3(vxID + float2(1, 0), bary.x)
				);
				
				float3x3 neg = float3x3(
				float3(vxID + float2(1, 1), 	 -bary.z),
				float3(vxID + float2(1, 0), 1.0 - bary.y),
				float3(vxID + float2(0, 1), 1.0 - bary.x)
				);
				
				return (bary.z > 0) ? pos : neg;
			}
			
			float4 DeliotHeitzSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, float2 dx, float2 dy)
			{
				// UVBW[0...2].xy = UV Offsets
				// UVBW[0...2].z = Blend Weights
				float3x3 UVBW = DeliotHeitzStochasticUVBW(uv);
				
				//blend samples with calculated weights
				return 	mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[0].xy), dx, dy), UVBW[0].z) +
				mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[1].xy), dx, dy), UVBW[1].z) +
				mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[2].xy), dx, dy), UVBW[2].z) ;
			}
			
			float4 DeliotHeitzSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv)
			{
				float2 dx = ddx(uv), dy = ddy(uv);
				return DeliotHeitzSampleTexture(tex, texSampler, uv, dx, dy);
			}
			#endif // defined(_STOCHASTICMODE_DELIOT_HEITZ)
			
			#if defined(_STOCHASTICMODE_HEXTILE)
			// HexTiling: Slower, but histogram-preserving
			// SPDX-License-Idenfitier: MIT
			// Copyright (c) 2022 mmikk
			// https://github.com/mmikk/hextile-demo
			float2 HextileMakeCenUV(float2 vertex)
			{
				// 0.288675 ~= 1/(2*sqrt(3))
				const float2x2 stochasticInverseSkewedGrid = float2x2(1.0, 0.5, 0.0, 1.0/1.15470054);
				return mul(stochasticInverseSkewedGrid, vertex) * 0.288675;
			}
			
			float2x2 HextileLoadRot2x2(float2 idx, float rotStrength)
			{
				float angle = abs(idx.x * idx.y) + abs(idx.x + idx.y) + PI;
				
				// remap to +/-pi
				angle = glsl_mod(angle, 2 * PI);
				if(angle < 0)  angle += 2 * PI;
				if(angle > PI) angle -= 2 * PI;
				
				angle *= rotStrength;
				
				float cs = cos(angle), si = sin(angle);
				return float2x2(cs, -si, si, cs);
			}
			
			// UV Offsets and base blend weights
			// UVBWR[0...2].xy = UV Offsets
			// UVBWR[0...2].zw = rotation costh/sinth -> reconstruct rotation matrix with float2x2(UVBWR[n].z, -UVBWR[n].w, UVBWR[n].w, UVBWR[n].z)
			// UVBWR[3].xyz = Blend Weights (w unused) - needs luminance weighting
			float4x4 HextileUVBWR(float2 uv)
			{
				// Create Triangle Grid
				// Skew input space into simplex triangle grid (3.4641 ~= 2*sqrt(3))
				const float2x2 stochasticSkewedGrid = float2x2(1.0, -0.57735027, 0.0, 1.15470054);
				float2 skewedCoord = mul(stochasticSkewedGrid, uv * 3.4641 * _StochasticHexGridDensity);
				
				float2 baseId = float2(floor(skewedCoord));
				float3 temp = float3(frac(skewedCoord), 0);
				temp.z = 1 - temp.x - temp.y;
				
				float s = step(0.0, -temp.z);
				float s2 = 2 * s - 1;
				
				float3 weights = float3(-temp.z * s2, s - temp.y * s2, s - temp.x * s2);
				
				float2 vertex0 = baseId + float2(s, s);
				float2 vertex1 = baseId + float2(s, 1 - s);
				float2 vertex2 = baseId + float2(1 - s, s);
				
				float2 cen0 = HextileMakeCenUV(vertex0), cen1 = HextileMakeCenUV(vertex1), cen2 = HextileMakeCenUV(vertex2);
				float2x2 rot0 = float2x2(1, 0, 0, 1), rot1 = float2x2(1, 0, 0, 1), rot2 = float2x2(1, 0, 0, 1);
				
				if(_StochasticHexRotationStrength > 0)
				{
					rot0 = HextileLoadRot2x2(vertex0, _StochasticHexRotationStrength);
					rot1 = HextileLoadRot2x2(vertex1, _StochasticHexRotationStrength);
					rot2 = HextileLoadRot2x2(vertex2, _StochasticHexRotationStrength);
				}
				
				return float4x4(
				float4(mul(uv - cen0, rot0) + cen0 + StochasticHash2D2D(vertex0), rot0[0].x, -rot0[0].y),
				float4(mul(uv - cen1, rot1) + cen1 + StochasticHash2D2D(vertex1), rot1[0].x, -rot1[0].y),
				float4(mul(uv - cen2, rot2) + cen2 + StochasticHash2D2D(vertex2), rot2[0].x, -rot2[0].y),
				float4(weights, 0)
				);
			}
			
			float4 HextileSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, bool isNormalMap, float2 dUVdx, float2 dUVdy)
			{
				// For some reason doing this instead of just calculating it directly prevents it from \
				// breaking after a certain number of textures use it. I don't understand why yet
				float4x4 UVBWR = HextileUVBWR(uv);
				
				// 2D Rotation Matrices for dUVdx/dy
				// Not sure if this constant folds during compiling when rot is locked at 0, so force it
				float2x2 rot0 = float2x2(1, 0, 0, 1), rot1 = float2x2(1, 0, 0, 1), rot2 = float2x2(1, 0, 0, 1);
				
				if(_StochasticHexRotationStrength > 0)
				{
					rot0 = float2x2(UVBWR[0].z, -UVBWR[0].w, UVBWR[0].w, UVBWR[0].z);
					rot1 = float2x2(UVBWR[1].z, -UVBWR[1].w, UVBWR[1].w, UVBWR[1].z);
					rot2 = float2x2(UVBWR[2].z, -UVBWR[2].w, UVBWR[2].w, UVBWR[2].z);
				}
				
				// Weights
				float3 W = UVBWR[3].xyz;
				
				// Sample texture
				// float3x4 c = float3x4(
				// 	tex.SampleGrad(texSampler, UVBWR[0].xy, mul(dUVdx, rot0), mul(dUVdy, rot0)),
				// 	tex.SampleGrad(texSampler, UVBWR[1].xy, mul(dUVdx, rot1), mul(dUVdy, rot1)),
				// 	tex.SampleGrad(texSampler, UVBWR[2].xy, mul(dUVdx, rot2), mul(dUVdy, rot2))
				// );
				
				float4 c0 = tex.SampleGrad(texSampler, UVBWR[0].xy, mul(dUVdx, rot0), mul(dUVdy, rot0));
				float4 c1 = tex.SampleGrad(texSampler, UVBWR[1].xy, mul(dUVdx, rot1), mul(dUVdy, rot1));
				float4 c2 = tex.SampleGrad(texSampler, UVBWR[2].xy, mul(dUVdx, rot2), mul(dUVdy, rot2));
				
				// Blend samples using luminance
				// This is technically incorrect for normal maps, but produces very similar
				// results to blending using normal map gradients (steepness)
				const float3 Lw = float3(0.299, 0.587, 0.114);
				float3 Dw = float3(dot(c0.xyz, Lw), dot(c1.xyz, Lw), dot(c2.xyz, Lw));
				
				Dw = lerp(1.0, Dw, _StochasticHexFallOffContrast);
				W = Dw * pow(W, _StochasticHexFallOffPower);
				// In the original hextiling there's a Gain3 step here, but it seems to slow things down \
				// and cause the UVs to break, so I've omitted it. Looks fine without
				
				W /= (W.x + W.y + W.z);
				return W.x * c0 + W.y * c1 + W.z * c2;
			}
			
			float4 HextileSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, bool isNormalMap)
			{
				return HextileSampleTexture(tex, texSampler, uv, isNormalMap, ddx(uv), ddy(uv));
			}
			#endif // defined(_STOCHASTICMODE_HEXTILE)
			
			void applyAlphaOptions(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiMods poiMods)
			{
				poiFragData.alpha = saturate(poiFragData.alpha + _AlphaMod);
				
				if (_AlphaGlobalMask > 0)
				{
					poiFragData.alpha = maskBlend(poiFragData.alpha, poiMods.globalMask[_AlphaGlobalMask - 1], _AlphaGlobalMaskBlendType);
				}
				
				//ifex _AlphaDistanceFade==0 && isNotAnimated(_AlphaDistanceFade)
				if (_AlphaDistanceFade)
				{
					float3 position = _AlphaDistanceFadeType ? poiMesh.worldPos : poiMesh.objectPosition;
					float distanceFadeMultiplier = lerp(_AlphaDistanceFadeMinAlpha, _AlphaDistanceFadeMaxAlpha, smoothstep(_AlphaDistanceFadeMin, _AlphaDistanceFadeMax, distance(position, poiCam.worldPos)));
					if (_AlphaDistanceFadeGlobalMask > 0)
					{
						distanceFadeMultiplier = lerp(1, distanceFadeMultiplier, poiMods.globalMask[_AlphaDistanceFadeGlobalMask - 1]);
					}
					poiFragData.alpha *= distanceFadeMultiplier;
				}
				//endex
				
				//ifex _AlphaFresnel==0 && isNotAnimated(_AlphaFresnel)
				if (_AlphaFresnel)
				{
					float holoRim = saturate(1 - smoothstep(min(_AlphaFresnelSharpness, _AlphaFresnelWidth), _AlphaFresnelWidth, (poiCam.vDotN)));
					holoRim = abs(lerp(1, holoRim, _AlphaFresnelAlpha));
					holoRim = _AlphaFresnelInvert ? 1 - holoRim : holoRim;
					if (_AlphaFresnelGlobalMask > 0)
					{
						holoRim = lerp(1, holoRim, poiMods.globalMask[_AlphaFresnelGlobalMask - 1]);
					}
					poiFragData.alpha *= holoRim;
				}
				//endex
				
				//ifex _AlphaAngular==0 && isNotAnimated(_AlphaAngular)
				if (_AlphaAngular)
				{
					half cameraAngleMin = _CameraAngleMin / 180;
					half cameraAngleMax = _CameraAngleMax / 180;
					half modelAngleMin = _ModelAngleMin / 180;
					half modelAngleMax = _ModelAngleMax / 180;
					float3 pos = _AngleCompareTo == 0 ? poiMesh.objectPosition : poiMesh.worldPos;
					half3 cameraToModelDirection = normalize(pos - getCameraPosition());
					half3 modelForwardDirection = normalize(mul(unity_ObjectToWorld, normalize(_AngleForwardDirection.rgb)));
					half cameraLookAtModel = remapClamped(cameraAngleMax, cameraAngleMin, .5 * dot(cameraToModelDirection, getCameraForward()) + .5);
					half modelLookAtCamera = remapClamped(modelAngleMax, modelAngleMin, .5 * dot(-cameraToModelDirection, modelForwardDirection) + .5);
					float angularAlphaMod = 1;
					if (_AngleType == 0)
					{
						angularAlphaMod = max(cameraLookAtModel, _AngleMinAlpha);
					}
					else if (_AngleType == 1)
					{
						angularAlphaMod = max(modelLookAtCamera, _AngleMinAlpha);
					}
					else if (_AngleType == 2)
					{
						angularAlphaMod = max(cameraLookAtModel * modelLookAtCamera, _AngleMinAlpha);
					}
					if (_AlphaAngularGlobalMask > 0)
					{
						angularAlphaMod = lerp(1, angularAlphaMod, poiMods.globalMask[_AlphaAngularGlobalMask - 1]);
					}
					poiFragData.alpha *= angularAlphaMod;
				}
				//endex
				
				//ifex _AlphaAudioLinkEnabled==0 && isNotAnimated(_AlphaAudioLinkEnabled)
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable && _AlphaAudioLinkEnabled)
				{
					poiFragData.alpha = saturate(poiFragData.alpha + lerp(_AlphaAudioLinkAddRange.x, _AlphaAudioLinkAddRange.y, poiMods.audioLink[_AlphaAudioLinkAddBand]));
				}
				#endif
				//endex
				
			}
			
			//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
			inline half Dither8x8Bayer(int x, int y)
			{
				// Premultiplied by 1/64
				const half dither[ 64 ] = {
					0.015625, 0.765625, 0.203125, 0.953125, 0.06250, 0.81250, 0.25000, 1.00000,
					0.515625, 0.265625, 0.703125, 0.453125, 0.56250, 0.31250, 0.75000, 0.50000,
					0.140625, 0.890625, 0.078125, 0.828125, 0.18750, 0.93750, 0.12500, 0.87500,
					0.640625, 0.390625, 0.578125, 0.328125, 0.68750, 0.43750, 0.62500, 0.37500,
					0.046875, 0.796875, 0.234375, 0.984375, 0.03125, 0.78125, 0.21875, 0.96875,
					0.546875, 0.296875, 0.734375, 0.484375, 0.53125, 0.28125, 0.71875, 0.46875,
					0.171875, 0.921875, 0.109375, 0.859375, 0.15625, 0.90625, 0.09375, 0.84375,
					0.671875, 0.421875, 0.609375, 0.359375, 0.65625, 0.40625, 0.59375, 0.34375
				};
				int r = y * 8 + x;
				return dither[r];
			}
			
			half calcDither(half2 grabPos)
			{
				return Dither8x8Bayer(glsl_mod(grabPos.x, 8), glsl_mod(grabPos.y, 8));
			}
			
			void applyDithering(inout PoiFragData poiFragData, in PoiCam poiCam)
			{
				if (_AlphaDithering)
				{
					float dither = calcDither(poiCam.posScreenPixels) - _AlphaDitherBias;
					poiFragData.alpha = saturate(poiFragData.alpha - (dither * (1 - poiFragData.alpha) * _AlphaDitherGradient));
				}
			}
			//endex
			
			//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
			void ApplyAlphaToCoverage(inout PoiFragData poiFragData, in PoiMesh poiMesh)
			{
				// Force Model Opacity to 1 if desired
				UNITY_BRANCH
				if (_Mode == 1)
				{
					UNITY_BRANCH
					if (_AlphaSharpenedA2C && _AlphaToCoverage)
					{
						// rescale alpha by mip level
						poiFragData.alpha *= 1 + max(0, CalcMipLevel(poiMesh.uv[0] * _MainTex_TexelSize.zw)) * _AlphaMipScale;
						// rescale alpha by partial derivative
						poiFragData.alpha = (poiFragData.alpha - _Cutoff) / max(fwidth(poiFragData.alpha), 0.0001) + _Cutoff;
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
				}
			}
			//endex
			
			//ifex _EnableOutlines!=1
			#ifdef POI_PASS_OUTLINE
			void applyOutlineColor(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiLight poiLight, in PoiMods poiMods, in PoiCam poiCam)
			{
				clip(_EnableOutlines - 0.01);
				float OutlineMask = tex2D(_OutlineMask, TRANSFORM_TEX(poiMesh.uv[_OutlineMaskUV], _OutlineMask) + _Time.x * _OutlineMaskPan)[_OutlineMaskChannel];
				if (_OutlineVertexColorMask > 0)
				{
					OutlineMask *= lerp(1, poiMesh.vertexColor[_OutlineVertexColorMask - 1], _OutlineVertexColorMaskStrength);
				}
				if (_OutlineClipAtZeroWidth)
				{
					float lineWidth = _LineWidth;
					#ifdef POI_AUDIOLINK
					//UNITY_BRANCH
					if (poiMods.audioLinkAvailable)
					{
						lineWidth += lerp(_AudioLinkOutlineSize.x, _AudioLinkOutlineSize.y, poiMods.audioLink[_AudioLinkOutlineSizeBand]);
					}
					#endif
					clip(OutlineMask * lineWidth - 0.001);
				}
				float4 col = POI2D_SAMPLER_PAN(_OutlineTexture, _MainTex, poiUV(poiMesh.uv[_OutlineTextureUV], _OutlineTexture_ST), _OutlineTexturePan);
				poiFragData.baseColor = lerp(col, col * poiFragData.baseColor * lerp(1, poiFragData.baseColor, _PoiUTSStyleOutlineBlend), _OutlineTintMix);
				float4 outlineColor = _LineColor;
				#ifdef POI_AUDIOLINK
				if (_OutlineALColorEnabled && poiMods.audioLinkAvailable)
				{
					outlineColor = lerp(outlineColor, _AudioLinkOutlineColor, smoothstep(_AudioLinkOutlineColorMod.x, _AudioLinkOutlineColorMod.y, poiMods.audioLink[_AudioLinkOutlineColorBand]));
				}
				#endif
				
				poiFragData.baseColor *= poiThemeColor(poiMods, outlineColor.rgb, _LineColorThemeIndex);
				col.a *= outlineColor.a;
				if (_OutlineHueShift)
				{
					//poiFragData.baseColor = hueShift(poiFragData.baseColor, _OutlineHueOffset +_OutlineHueOffsetSpeed * _Time.x);
					float4 hsvg = _OutlineTexHSVG;
					hsvg.r += _OutlineHueOffsetSpeed * _Time.x;
					poiFragData.baseColor.rgb = lilToneCorrection(poiFragData.baseColor.rgb, hsvg);
				}
				
				if (_OutlineExpansionMode == 2)
				{
					poiFragData.baseColor = lerp(poiFragData.baseColor, poiLight.directColor, _OutlineRimLightBlend);
				}
				
				if (_OutlineOverrideAlpha)
				{
					poiFragData.alpha = col.a;
				}
				else
				{
					poiFragData.alpha *= col.a;
				}
				
				if (_OutlineAlphaDistanceFade)
				{
					float3 position = _OutlineAlphaDistanceFadeType ? poiMesh.worldPos : poiMesh.objectPosition;
					poiFragData.alpha *= lerp(_OutlineAlphaDistanceFadeMinAlpha, _OutlineAlphaDistanceFadeMaxAlpha, smoothstep(_OutlineAlphaDistanceFadeMin, _OutlineAlphaDistanceFadeMax, distance(position, poiCam.worldPos)));
				}
				
				float emission = _OutlineEmission;
				#ifdef POI_AUDIOLINK
				//UNITY_BRANCH
				if (poiMods.audioLinkAvailable)
				{
					emission += lerp(_AudioLinkOutlineEmission.x, _AudioLinkOutlineEmission.y, poiMods.audioLink[_AudioLinkOutlineEmissionBand]);
				}
				#endif
				
				poiFragData.emission += poiFragData.baseColor * emission;
			}
			#endif
			//endex
			
			void calculateGlobalThemes(inout PoiMods poiMods)
			{
				// Theme colors are defined as HDR; convert to SDR and do the HSV adjustment, then re-apply exposure
				float4 themeColorExposures = 0;
				float4 themeColor0, themeColor1, themeColor2, themeColor3 = 0;
				
				DecomposeHDRColor(_GlobalThemeColor0.rgb, themeColor0.rgb, themeColorExposures.x);
				DecomposeHDRColor(_GlobalThemeColor1.rgb, themeColor1.rgb, themeColorExposures.y);
				DecomposeHDRColor(_GlobalThemeColor2.rgb, themeColor2.rgb, themeColorExposures.z);
				DecomposeHDRColor(_GlobalThemeColor3.rgb, themeColor3.rgb, themeColorExposures.w);
				
				poiMods.globalColorTheme[0] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor0.rgb, frac(_GlobalThemeHue0 + _GlobalThemeHueSpeed0 * _Time.x), _GlobalThemeSaturation0, _GlobalThemeValue0), themeColorExposures.x), _GlobalThemeColor0.a);
				poiMods.globalColorTheme[1] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor1.rgb, frac(_GlobalThemeHue1 + _GlobalThemeHueSpeed1 * _Time.x), _GlobalThemeSaturation1, _GlobalThemeValue1), themeColorExposures.y), _GlobalThemeColor1.a);
				poiMods.globalColorTheme[2] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor2.rgb, frac(_GlobalThemeHue2 + _GlobalThemeHueSpeed2 * _Time.x), _GlobalThemeSaturation2, _GlobalThemeValue2), themeColorExposures.z), _GlobalThemeColor2.a);
				poiMods.globalColorTheme[3] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor3.rgb, frac(_GlobalThemeHue3 + _GlobalThemeHueSpeed3 * _Time.x), _GlobalThemeSaturation3, _GlobalThemeValue3), themeColorExposures.w), _GlobalThemeColor3.a);
			}
			
			//ifex _GlobalMaskTexturesEnable==0
			#ifdef POI_GLOBALMASK_TEXTURES
			void ApplyGlobalMaskTextures(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				#if defined(PROP_GLOBALMASKTEXTURE0) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol0 = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0_ST), _GlobalMaskTexture0Pan);
				if (_GlobalMaskTexture0Split)
				{
					poiMods.globalMask[0] = gmcol0.r;
					poiMods.globalMask[1] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_G), _GlobalMaskTexture0SplitPan_G).g;
					poiMods.globalMask[2] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_B), _GlobalMaskTexture0SplitPan_B).b;
					poiMods.globalMask[3] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_A), _GlobalMaskTexture0SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[0] = gmcol0[0];
					poiMods.globalMask[1] = gmcol0[1];
					poiMods.globalMask[2] = gmcol0[2];
					poiMods.globalMask[3] = gmcol0[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE1) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol1 = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1_ST), _GlobalMaskTexture1Pan);
				if (_GlobalMaskTexture1Split)
				{
					poiMods.globalMask[4] = gmcol1.r;
					poiMods.globalMask[5] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_G), _GlobalMaskTexture1SplitPan_G).g;
					poiMods.globalMask[6] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_B), _GlobalMaskTexture1SplitPan_B).b;
					poiMods.globalMask[7] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_A), _GlobalMaskTexture1SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[4] = gmcol1[0];
					poiMods.globalMask[5] = gmcol1[1];
					poiMods.globalMask[6] = gmcol1[2];
					poiMods.globalMask[7] = gmcol1[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE2) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol2 = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2_ST), _GlobalMaskTexture2Pan);
				if (_GlobalMaskTexture2Split)
				{
					poiMods.globalMask[8] = gmcol2.r;
					poiMods.globalMask[9] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_G), _GlobalMaskTexture2SplitPan_G).g;
					poiMods.globalMask[10] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_B), _GlobalMaskTexture2SplitPan_B).b;
					poiMods.globalMask[11] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_A), _GlobalMaskTexture2SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[8] = gmcol2[0];
					poiMods.globalMask[9] = gmcol2[1];
					poiMods.globalMask[10] = gmcol2[2];
					poiMods.globalMask[11] = gmcol2[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE3) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol3 = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3_ST), _GlobalMaskTexture3Pan);
				if (_GlobalMaskTexture3Split)
				{
					poiMods.globalMask[12] = gmcol3.r;
					poiMods.globalMask[13] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_G), _GlobalMaskTexture3SplitPan_G).g;
					poiMods.globalMask[14] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_B), _GlobalMaskTexture3SplitPan_B).b;
					poiMods.globalMask[15] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_A), _GlobalMaskTexture3SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[12] = gmcol3[0];
					poiMods.globalMask[13] = gmcol3[1];
					poiMods.globalMask[14] = gmcol3[2];
					poiMods.globalMask[15] = gmcol3[3];
				}
				#endif
			}
			#endif
			//endex
			//ifex _GlobalMaskOptionsEnable==0
			void ApplyGlobalMaskOptions(inout PoiMods poiMods)
			{
				//ifex _GlobalMaskOptionsType!=0
				if (_GlobalMaskOptionsType == 0)
				{
					poiMods.globalMask[0] = saturate(poiMods.globalMask[0] + _GlobalMaskSlider_0);
					poiMods.globalMask[1] = saturate(poiMods.globalMask[1] + _GlobalMaskSlider_1);
					poiMods.globalMask[2] = saturate(poiMods.globalMask[2] + _GlobalMaskSlider_2);
					poiMods.globalMask[3] = saturate(poiMods.globalMask[3] + _GlobalMaskSlider_3);
					poiMods.globalMask[4] = saturate(poiMods.globalMask[4] + _GlobalMaskSlider_4);
					poiMods.globalMask[5] = saturate(poiMods.globalMask[5] + _GlobalMaskSlider_5);
					poiMods.globalMask[6] = saturate(poiMods.globalMask[6] + _GlobalMaskSlider_6);
					poiMods.globalMask[7] = saturate(poiMods.globalMask[7] + _GlobalMaskSlider_7);
					poiMods.globalMask[8] = saturate(poiMods.globalMask[8] + _GlobalMaskSlider_8);
					poiMods.globalMask[9] = saturate(poiMods.globalMask[9] + _GlobalMaskSlider_9);
					poiMods.globalMask[10] = saturate(poiMods.globalMask[10] + _GlobalMaskSlider_10);
					poiMods.globalMask[11] = saturate(poiMods.globalMask[11] + _GlobalMaskSlider_11);
					poiMods.globalMask[12] = saturate(poiMods.globalMask[12] + _GlobalMaskSlider_12);
					poiMods.globalMask[13] = saturate(poiMods.globalMask[13] + _GlobalMaskSlider_13);
					poiMods.globalMask[14] = saturate(poiMods.globalMask[14] + _GlobalMaskSlider_14);
					poiMods.globalMask[15] = saturate(poiMods.globalMask[15] + _GlobalMaskSlider_15);
				}
				//endex
				//ifex _GlobalMaskOptionsType!=1
				if (_GlobalMaskOptionsType == 1)
				{
					poiMods.globalMask[0] = lerp(_GlobalMaskMinMaxSlider_0.x, _GlobalMaskMinMaxSlider_0.y, poiMods.globalMask[0]);
					poiMods.globalMask[1] = lerp(_GlobalMaskMinMaxSlider_1.x, _GlobalMaskMinMaxSlider_1.y, poiMods.globalMask[1]);
					poiMods.globalMask[2] = lerp(_GlobalMaskMinMaxSlider_2.x, _GlobalMaskMinMaxSlider_2.y, poiMods.globalMask[2]);
					poiMods.globalMask[3] = lerp(_GlobalMaskMinMaxSlider_3.x, _GlobalMaskMinMaxSlider_3.y, poiMods.globalMask[3]);
					poiMods.globalMask[4] = lerp(_GlobalMaskMinMaxSlider_4.x, _GlobalMaskMinMaxSlider_4.y, poiMods.globalMask[4]);
					poiMods.globalMask[5] = lerp(_GlobalMaskMinMaxSlider_5.x, _GlobalMaskMinMaxSlider_5.y, poiMods.globalMask[5]);
					poiMods.globalMask[6] = lerp(_GlobalMaskMinMaxSlider_6.x, _GlobalMaskMinMaxSlider_6.y, poiMods.globalMask[6]);
					poiMods.globalMask[7] = lerp(_GlobalMaskMinMaxSlider_7.x, _GlobalMaskMinMaxSlider_7.y, poiMods.globalMask[7]);
					poiMods.globalMask[8] = lerp(_GlobalMaskMinMaxSlider_8.x, _GlobalMaskMinMaxSlider_8.y, poiMods.globalMask[8]);
					poiMods.globalMask[9] = lerp(_GlobalMaskMinMaxSlider_9.x, _GlobalMaskMinMaxSlider_9.y, poiMods.globalMask[9]);
					poiMods.globalMask[10] = lerp(_GlobalMaskMinMaxSlider_10.x, _GlobalMaskMinMaxSlider_10.y, poiMods.globalMask[10]);
					poiMods.globalMask[11] = lerp(_GlobalMaskMinMaxSlider_11.x, _GlobalMaskMinMaxSlider_11.y, poiMods.globalMask[11]);
					poiMods.globalMask[12] = lerp(_GlobalMaskMinMaxSlider_12.x, _GlobalMaskMinMaxSlider_12.y, poiMods.globalMask[12]);
					poiMods.globalMask[13] = lerp(_GlobalMaskMinMaxSlider_13.x, _GlobalMaskMinMaxSlider_13.y, poiMods.globalMask[13]);
					poiMods.globalMask[14] = lerp(_GlobalMaskMinMaxSlider_14.x, _GlobalMaskMinMaxSlider_14.y, poiMods.globalMask[14]);
					poiMods.globalMask[15] = lerp(_GlobalMaskMinMaxSlider_15.x, _GlobalMaskMinMaxSlider_15.y, poiMods.globalMask[15]);
				}
				//endex
				//ifex _GlobalMaskOptionsType!=2
				if (_GlobalMaskOptionsType == 2)
				{
					if (_GlobalMaskToggleOn_0)  poiMods.globalMask[0] = 1;
					if (_GlobalMaskToggleOn_1)  poiMods.globalMask[1] = 1;
					if (_GlobalMaskToggleOn_2)  poiMods.globalMask[2] = 1;
					if (_GlobalMaskToggleOn_3)  poiMods.globalMask[3] = 1;
					if (_GlobalMaskToggleOn_4)  poiMods.globalMask[4] = 1;
					if (_GlobalMaskToggleOn_5)  poiMods.globalMask[5] = 1;
					if (_GlobalMaskToggleOn_6)  poiMods.globalMask[6] = 1;
					if (_GlobalMaskToggleOn_7)  poiMods.globalMask[7] = 1;
					if (_GlobalMaskToggleOn_8)  poiMods.globalMask[8] = 1;
					if (_GlobalMaskToggleOn_9)  poiMods.globalMask[9] = 1;
					if (_GlobalMaskToggleOn_10) poiMods.globalMask[10] = 1;
					if (_GlobalMaskToggleOn_11) poiMods.globalMask[11] = 1;
					if (_GlobalMaskToggleOn_12) poiMods.globalMask[12] = 1;
					if (_GlobalMaskToggleOn_13) poiMods.globalMask[13] = 1;
					if (_GlobalMaskToggleOn_14) poiMods.globalMask[14] = 1;
					if (_GlobalMaskToggleOn_15) poiMods.globalMask[15] = 1;
					
					poiMods.globalMask[0] *= (1 - _GlobalMaskToggleOff_0);
					poiMods.globalMask[1] *= (1 - _GlobalMaskToggleOff_1);
					poiMods.globalMask[2] *= (1 - _GlobalMaskToggleOff_2);
					poiMods.globalMask[3] *= (1 - _GlobalMaskToggleOff_3);
					poiMods.globalMask[4] *= (1 - _GlobalMaskToggleOff_4);
					poiMods.globalMask[5] *= (1 - _GlobalMaskToggleOff_5);
					poiMods.globalMask[6] *= (1 - _GlobalMaskToggleOff_6);
					poiMods.globalMask[7] *= (1 - _GlobalMaskToggleOff_7);
					poiMods.globalMask[8] *= (1 - _GlobalMaskToggleOff_8);
					poiMods.globalMask[9] *= (1 - _GlobalMaskToggleOff_9);
					poiMods.globalMask[10] *= (1 - _GlobalMaskToggleOff_10);
					poiMods.globalMask[11] *= (1 - _GlobalMaskToggleOff_11);
					poiMods.globalMask[12] *= (1 - _GlobalMaskToggleOff_12);
					poiMods.globalMask[13] *= (1 - _GlobalMaskToggleOff_13);
					poiMods.globalMask[14] *= (1 - _GlobalMaskToggleOff_14);
					poiMods.globalMask[15] *= (1 - _GlobalMaskToggleOff_15);
				}
				//endex
				
			}
			//endex
			
			float customDistanceBlend(float base, float blend, float blendType)
			{
				switch(blendType)
				{
					case 0: return blendNormal(base, blend); break;
					case 2: return blendMultiply(base, blend); break;
					default: return 0; break;
				}
			}
			
			void handleGlobalMaskDistance(int index, bool enable, bool type, float minAlpha, float maxAlpha, float min, float max, int blendType, in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				if (enable)
				{
					float3 position = type ? poiMesh.worldPos : poiMesh.objectPosition;
					float val = lerp(minAlpha, maxAlpha, smoothstep(min, max, distance(position, _WorldSpaceCameraPos)));
					poiMods.globalMask[index] = saturate(customDistanceBlend(poiMods.globalMask[index], val, blendType));
				}
			}
			
			void ApplyGlobalMaskModifiers(in PoiMesh poiMesh, inout PoiMods poiMods, in PoiCam poiCam)
			{
				//ifex _GlobalMaskModifiersBackfaceEnable==0
				if (_GlobalMaskModifiersBackfaceEnable)
				{
					float facingMode = saturate(poiMesh.isFrontFace) + 1;
					// _GlobalMaskBackface is 0 for ignore, 1 for back only, 2 for front only
					poiMods.globalMask[0] *= _GlobalMaskBackface_0 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_0));
					poiMods.globalMask[1] *= _GlobalMaskBackface_1 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_1));
					poiMods.globalMask[2] *= _GlobalMaskBackface_2 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_2));
					poiMods.globalMask[3] *= _GlobalMaskBackface_3 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_3));
					poiMods.globalMask[4] *= _GlobalMaskBackface_4 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_4));
					poiMods.globalMask[5] *= _GlobalMaskBackface_5 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_5));
					poiMods.globalMask[6] *= _GlobalMaskBackface_6 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_6));
					poiMods.globalMask[7] *= _GlobalMaskBackface_7 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_7));
					poiMods.globalMask[8] *= _GlobalMaskBackface_8 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_8));
					poiMods.globalMask[9] *= _GlobalMaskBackface_9 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_9));
					poiMods.globalMask[10] *= _GlobalMaskBackface_10 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_10));
					poiMods.globalMask[11] *= _GlobalMaskBackface_11 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_11));
					poiMods.globalMask[12] *= _GlobalMaskBackface_12 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_12));
					poiMods.globalMask[13] *= _GlobalMaskBackface_13 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_13));
					poiMods.globalMask[14] *= _GlobalMaskBackface_14 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_14));
					poiMods.globalMask[15] *= _GlobalMaskBackface_15 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_15));
				}
				//endex
				
				//ifex _GlobalMaskModifiersMirrorEnable==0
				if (_GlobalMaskModifiersMirrorEnable)
				{
					float mirrorMode = 0;
					if (_GlobalMaskMirrorVisibilityMode == 1) // VRC
					mirrorMode = VRCMirrorMode() > 0;
					else // Generic (CVR, etc)
					mirrorMode = IsInMirror();
					
					mirrorMode += 1;
					// _GlobalMaskMirror is 0 for ignore, 1 for outside mirror only, 2 for in mirror only
					poiMods.globalMask[0] *= _GlobalMaskMirror_0 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_0));
					poiMods.globalMask[1] *= _GlobalMaskMirror_1 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_1));
					poiMods.globalMask[2] *= _GlobalMaskMirror_2 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_2));
					poiMods.globalMask[3] *= _GlobalMaskMirror_3 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_3));
					poiMods.globalMask[4] *= _GlobalMaskMirror_4 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_4));
					poiMods.globalMask[5] *= _GlobalMaskMirror_5 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_5));
					poiMods.globalMask[6] *= _GlobalMaskMirror_6 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_6));
					poiMods.globalMask[7] *= _GlobalMaskMirror_7 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_7));
					poiMods.globalMask[8] *= _GlobalMaskMirror_8 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_8));
					poiMods.globalMask[9] *= _GlobalMaskMirror_9 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_9));
					poiMods.globalMask[10] *= _GlobalMaskMirror_10 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_10));
					poiMods.globalMask[11] *= _GlobalMaskMirror_11 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_11));
					poiMods.globalMask[12] *= _GlobalMaskMirror_12 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_12));
					poiMods.globalMask[13] *= _GlobalMaskMirror_13 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_13));
					poiMods.globalMask[14] *= _GlobalMaskMirror_14 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_14));
					poiMods.globalMask[15] *= _GlobalMaskMirror_15 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_15));
				}
				//endex
				
				//ifex _GlobalMaskModifiersCameraEnable==0
				if (_GlobalMaskModifiersCameraEnable)
				{
					float isCamera = VRCCameraMode() > 0;
					isCamera += 1;
					// _GlobalMaskCamera is 0 for ignore, 1 for outside camera only, 2 for in camera only
					poiMods.globalMask[0] *= _GlobalMaskCamera_0 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_0));
					poiMods.globalMask[1] *= _GlobalMaskCamera_1 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_1));
					poiMods.globalMask[2] *= _GlobalMaskCamera_2 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_2));
					poiMods.globalMask[3] *= _GlobalMaskCamera_3 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_3));
					poiMods.globalMask[4] *= _GlobalMaskCamera_4 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_4));
					poiMods.globalMask[5] *= _GlobalMaskCamera_5 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_5));
					poiMods.globalMask[6] *= _GlobalMaskCamera_6 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_6));
					poiMods.globalMask[7] *= _GlobalMaskCamera_7 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_7));
					poiMods.globalMask[8] *= _GlobalMaskCamera_8 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_8));
					poiMods.globalMask[9] *= _GlobalMaskCamera_9 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_9));
					poiMods.globalMask[10] *= _GlobalMaskCamera_10 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_10));
					poiMods.globalMask[11] *= _GlobalMaskCamera_11 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_11));
					poiMods.globalMask[12] *= _GlobalMaskCamera_12 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_12));
					poiMods.globalMask[13] *= _GlobalMaskCamera_13 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_13));
					poiMods.globalMask[14] *= _GlobalMaskCamera_14 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_14));
					poiMods.globalMask[15] *= _GlobalMaskCamera_15 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_15));
				}
				//endex
				//ifex _GlobalMaskModifiersDistanceEnable==0
				if (_GlobalMaskModifiersDistanceEnable)
				{
					//ifex _GlobalMaskDistanceEnable_0==0
					handleGlobalMaskDistance(0, _GlobalMaskDistanceEnable_0, _GlobalMaskDistanceType_0, _GlobalMaskDistanceMinAlpha_0, _GlobalMaskDistanceMaxAlpha_0, _GlobalMaskDistanceMin_0, _GlobalMaskDistanceMax_0, _GlobalMaskDistanceBlendType_0, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_1==0
					handleGlobalMaskDistance(1, _GlobalMaskDistanceEnable_1, _GlobalMaskDistanceType_1, _GlobalMaskDistanceMinAlpha_1, _GlobalMaskDistanceMaxAlpha_1, _GlobalMaskDistanceMin_1, _GlobalMaskDistanceMax_1, _GlobalMaskDistanceBlendType_1, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_2==0
					handleGlobalMaskDistance(2, _GlobalMaskDistanceEnable_2, _GlobalMaskDistanceType_2, _GlobalMaskDistanceMinAlpha_2, _GlobalMaskDistanceMaxAlpha_2, _GlobalMaskDistanceMin_2, _GlobalMaskDistanceMax_2, _GlobalMaskDistanceBlendType_2, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_3==0
					handleGlobalMaskDistance(3, _GlobalMaskDistanceEnable_3, _GlobalMaskDistanceType_3, _GlobalMaskDistanceMinAlpha_3, _GlobalMaskDistanceMaxAlpha_3, _GlobalMaskDistanceMin_3, _GlobalMaskDistanceMax_3, _GlobalMaskDistanceBlendType_3, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_4==0
					handleGlobalMaskDistance(4, _GlobalMaskDistanceEnable_4, _GlobalMaskDistanceType_4, _GlobalMaskDistanceMinAlpha_4, _GlobalMaskDistanceMaxAlpha_4, _GlobalMaskDistanceMin_4, _GlobalMaskDistanceMax_4, _GlobalMaskDistanceBlendType_4, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_5==0
					handleGlobalMaskDistance(5, _GlobalMaskDistanceEnable_5, _GlobalMaskDistanceType_5, _GlobalMaskDistanceMinAlpha_5, _GlobalMaskDistanceMaxAlpha_5, _GlobalMaskDistanceMin_5, _GlobalMaskDistanceMax_5, _GlobalMaskDistanceBlendType_5, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_6==0
					handleGlobalMaskDistance(6, _GlobalMaskDistanceEnable_6, _GlobalMaskDistanceType_6, _GlobalMaskDistanceMinAlpha_6, _GlobalMaskDistanceMaxAlpha_6, _GlobalMaskDistanceMin_6, _GlobalMaskDistanceMax_6, _GlobalMaskDistanceBlendType_6, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_7==0
					handleGlobalMaskDistance(7, _GlobalMaskDistanceEnable_7, _GlobalMaskDistanceType_7, _GlobalMaskDistanceMinAlpha_7, _GlobalMaskDistanceMaxAlpha_7, _GlobalMaskDistanceMin_7, _GlobalMaskDistanceMax_7, _GlobalMaskDistanceBlendType_7, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_8==0
					handleGlobalMaskDistance(8, _GlobalMaskDistanceEnable_8, _GlobalMaskDistanceType_8, _GlobalMaskDistanceMinAlpha_8, _GlobalMaskDistanceMaxAlpha_8, _GlobalMaskDistanceMin_8, _GlobalMaskDistanceMax_8, _GlobalMaskDistanceBlendType_8, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_9==0
					handleGlobalMaskDistance(9, _GlobalMaskDistanceEnable_9, _GlobalMaskDistanceType_9, _GlobalMaskDistanceMinAlpha_9, _GlobalMaskDistanceMaxAlpha_9, _GlobalMaskDistanceMin_9, _GlobalMaskDistanceMax_9, _GlobalMaskDistanceBlendType_9, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_10==0
					handleGlobalMaskDistance(10, _GlobalMaskDistanceEnable_10, _GlobalMaskDistanceType_10, _GlobalMaskDistanceMinAlpha_10, _GlobalMaskDistanceMaxAlpha_10, _GlobalMaskDistanceMin_10, _GlobalMaskDistanceMax_10, _GlobalMaskDistanceBlendType_10, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_11==0
					handleGlobalMaskDistance(11, _GlobalMaskDistanceEnable_11, _GlobalMaskDistanceType_11, _GlobalMaskDistanceMinAlpha_11, _GlobalMaskDistanceMaxAlpha_11, _GlobalMaskDistanceMin_11, _GlobalMaskDistanceMax_11, _GlobalMaskDistanceBlendType_11, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_12==0
					handleGlobalMaskDistance(12, _GlobalMaskDistanceEnable_12, _GlobalMaskDistanceType_12, _GlobalMaskDistanceMinAlpha_12, _GlobalMaskDistanceMaxAlpha_12, _GlobalMaskDistanceMin_12, _GlobalMaskDistanceMax_12, _GlobalMaskDistanceBlendType_12, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_13==0
					handleGlobalMaskDistance(13, _GlobalMaskDistanceEnable_13, _GlobalMaskDistanceType_13, _GlobalMaskDistanceMinAlpha_13, _GlobalMaskDistanceMaxAlpha_13, _GlobalMaskDistanceMin_13, _GlobalMaskDistanceMax_13, _GlobalMaskDistanceBlendType_13, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_14==0
					handleGlobalMaskDistance(14, _GlobalMaskDistanceEnable_14, _GlobalMaskDistanceType_14, _GlobalMaskDistanceMinAlpha_14, _GlobalMaskDistanceMaxAlpha_14, _GlobalMaskDistanceMin_14, _GlobalMaskDistanceMax_14, _GlobalMaskDistanceBlendType_14, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_15==0
					handleGlobalMaskDistance(15, _GlobalMaskDistanceEnable_15, _GlobalMaskDistanceType_15, _GlobalMaskDistanceMinAlpha_15, _GlobalMaskDistanceMaxAlpha_15, _GlobalMaskDistanceMin_15, _GlobalMaskDistanceMax_15, _GlobalMaskDistanceBlendType_15, poiMesh, poiMods);
					//endex
					
				}
				//endex
				
			}
			
			//ifex _GlobalMaskVertexColorRed==0 && _GlobalMaskVertexColorGreen==0 && _GlobalMaskVertexColorBlue==0 && _GlobalMaskVertexColorAlpha==0
			void ApplyGlobalMaskVertexColors(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				float4 vcol = poiMesh.vertexColor;
				if (_GlobalMaskVertexColorLinearSpace)
				{
					vcol.rgb = GammaToLinearSpace(vcol.rgb);
				}
				if (_GlobalMaskVertexColorRed > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorRed - 1, _GlobalMaskVertexColorRedBlendType, vcol.r);
				}
				if (_GlobalMaskVertexColorGreen > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorGreen - 1, _GlobalMaskVertexColorGreenBlendType, vcol.g);
				}
				if (_GlobalMaskVertexColorBlue > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorBlue - 1, _GlobalMaskVertexColorBlueBlendType, vcol.b);
				}
				if (_GlobalMaskVertexColorAlpha > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorAlpha - 1, _GlobalMaskVertexColorAlphaBlendType, vcol.a);
				}
			}
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#ifdef POI_UDIMDISCARD
			void applyUDIMDiscard(in VertexOut i)
			{
				if(_UDIMDiscardMode == 1) // Don't run if in vertex mode
				{
					float2 udim = floor(vertexUV(i, _UDIMDiscardUV));
					
					float isDiscarded = 0;
					float4 xMask = float4(  (udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					isDiscarded += (udim.y >= 0 && udim.y < 1) * dot(float4(_UDIMDiscardRow0_0, _UDIMDiscardRow0_1, _UDIMDiscardRow0_2, _UDIMDiscardRow0_3), xMask);
					isDiscarded += (udim.y >= 1 && udim.y < 2) * dot(float4(_UDIMDiscardRow1_0, _UDIMDiscardRow1_1, _UDIMDiscardRow1_2, _UDIMDiscardRow1_3), xMask);
					isDiscarded += (udim.y >= 2 && udim.y < 3) * dot(float4(_UDIMDiscardRow2_0, _UDIMDiscardRow2_1, _UDIMDiscardRow2_2, _UDIMDiscardRow2_3), xMask);
					isDiscarded += (udim.y >= 3 && udim.y < 4) * dot(float4(_UDIMDiscardRow3_0, _UDIMDiscardRow3_1, _UDIMDiscardRow3_2, _UDIMDiscardRow3_3), xMask);
					
					isDiscarded *= any(float4(udim.y >= 0, udim.y < 4, udim.x >= 0, udim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					const float threshold = 0.001;
					clip(threshold - isDiscarded); // Clip if discarded
				}
				
				return;
			}
			#endif
			//endex
			
			float2 calculatePolarCoordinate(in PoiMesh poiMesh)
			{
				float2 delta = poiMesh.uv[_PolarUV] - _PolarCenter;
				float radius = length(delta) * 2 * _PolarRadialScale;
				float angle = atan2(delta.x, delta.y);
				float phi = angle / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				angle = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				angle *= _PolarLengthScale;
				
				return float2(radius, angle + distance(poiMesh.uv[_PolarUV], _PolarCenter) * _PolarSpiralPower);
			}
			
			float2 MonoPanoProjection(float3 coords)
			{
				float3 normalizedCoords = normalize(coords);
				float latitude = acos(normalizedCoords.y);
				float longitude = atan2(normalizedCoords.z, normalizedCoords.x);
				float phi = longitude / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				longitude = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				longitude *= 2;
				float2 sphereCoords = float2(longitude, latitude) * float2(1.0, 1.0 / UNITY_PI);
				sphereCoords = float2(1.0, 1.0) - sphereCoords;
				return (sphereCoords + float4(0, 1 - unity_StereoEyeIndex, 1, 1.0).xy) * float4(0, 1 - unity_StereoEyeIndex, 1, 1.0).zw;
			}
			
			float2 StereoPanoProjection(float3 coords)
			{
				float3 normalizedCoords = normalize(coords);
				float latitude = acos(normalizedCoords.y);
				float longitude = atan2(normalizedCoords.z, normalizedCoords.x);
				float phi = longitude / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				longitude = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				longitude *= 2;
				float2 sphereCoords = float2(longitude, latitude) * float2(0.5, 1.0 / UNITY_PI);
				sphereCoords = float2(0.5, 1.0) - sphereCoords;
				return (sphereCoords + float4(0, 1 - unity_StereoEyeIndex, 1, 0.5).xy) * float4(0, 1 - unity_StereoEyeIndex, 1, 0.5).zw;
			}
			
			float2 calculateWorldUV(in PoiMesh poiMesh)
			{
				return float2(_UVModWorldPos0 != 3 ? poiMesh.worldPos[ _UVModWorldPos0] : 0.0f, _UVModWorldPos1 != 3 ? poiMesh.worldPos[_UVModWorldPos1] : 0.0f);
			}
			
			float2 calculatelocalUV(in PoiMesh poiMesh)
			{
				float localUVs[8];
				localUVs[0] = poiMesh.localPos.x;
				localUVs[1] = poiMesh.localPos.y;
				localUVs[2] = poiMesh.localPos.z;
				localUVs[3] = 0;
				localUVs[4] = poiMesh.vertexColor.r;
				localUVs[5] = poiMesh.vertexColor.g;
				localUVs[6] = poiMesh.vertexColor.b;
				localUVs[7] = poiMesh.vertexColor.a;
				
				return float2(localUVs[_UVModLocalPos0],localUVs[_UVModLocalPos1]);
			}
			
			float2 calculatePanosphereUV(in PoiMesh poiMesh)
			{
				float3 viewDirection = normalize(lerp(getCameraPosition().xyz, _WorldSpaceCameraPos.xyz, _PanoUseBothEyes) - poiMesh.worldPos.xyz) * - 1;
				return lerp(MonoPanoProjection(viewDirection), StereoPanoProjection(viewDirection), _StereoEnabled);
			}
			//ifex _EnableDistortion==0
			#ifdef USER_LUT
			float2 distortedUV(in PoiMesh poiMesh)
			{
				#if defined(PROP_DISTORTIONFLOWTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 flowVector = POI2D_SAMPLER_PAN(_DistortionFlowTexture, _MainTex, poiUV(poiMesh.uv[_DistortionFlowTextureUV], _DistortionFlowTexture_ST), _DistortionFlowTexturePan) * 2 - 1;
				#else
				float4 flowVector = -1;
				#endif
				
				#if defined(PROP_DISTORTIONFLOWTEXTURE1) || !defined(OPTIMIZER_ENABLED)
				float4 flowVector1 = POI2D_SAMPLER_PAN(_DistortionFlowTexture1, _MainTex, poiUV(poiMesh.uv[_DistortionFlowTexture1UV], _DistortionFlowTexture1_ST), _DistortionFlowTexture1Pan) * 2 - 1;
				#else
				float4 flowVector1 = -1;
				#endif
				
				#if defined(PROP_DISTORTIONMASK) || !defined(OPTIMIZER_ENABLED)
				half distortionMask = POI2D_SAMPLER_PAN(_DistortionMask, _MainTex, poiMesh.uv[_DistortionMaskUV], _DistortionMaskPan)[_DistortionMaskChannel];
				#else
				half distortionMask = 1;
				#endif
				
				half distortionStrength = _DistortionStrength;
				half distortionStrength1 = _DistortionStrength1;
				
				#ifdef POI_AUDIOLINK
				UNITY_BRANCH
				if (AudioLinkIsAvailable() && _EnableDistortionAudioLink && _AudioLinkAnimToggle)
				{
					distortionStrength += lerp(_DistortionStrengthAudioLink.x, _DistortionStrengthAudioLink.y, AudioLinkData(uint2(0, uint(_DistortionStrengthAudioLinkBand))).r);
					distortionStrength1 += lerp(_DistortionStrength1AudioLink.x, _DistortionStrength1AudioLink.y, AudioLinkData(uint2(0, uint(_DistortionStrength1AudioLinkBand))).r);
				}
				#endif
				
				flowVector *= distortionStrength;
				flowVector1 *= distortionStrength1;
				return poiMesh.uv[_DistortionUvToDistort] + ((flowVector.xy + flowVector1.xy) / 2) * distortionMask;
			}
			#endif
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#ifdef POI_BLACKLIGHTMASKING
			void calculateBlackLightMasks(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				#ifdef VERTEXLIGHT_ON
				for (int lightIndex = 0; lightIndex < 4; lightIndex++)
				{
					float3 lightPos = float3(unity_4LightPosX0[lightIndex], unity_4LightPosY0[lightIndex], unity_4LightPosZ0[lightIndex]);
					if (!distance(unity_LightColor[lightIndex].rgb, float3(0, 0, 0)))
					{
						if (_BlackLightMasking0GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking0Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking0GlobalMaskIndex - 1, _BlackLightMasking0GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking1GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking1Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking1GlobalMaskIndex - 1, _BlackLightMasking1GlobalMaskBlendType, smoothstep(_BlackLightMasking1Range.y, _BlackLightMasking1Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking2GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking2Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking2GlobalMaskIndex - 1, _BlackLightMasking2GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking3GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking3Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking3GlobalMaskIndex - 1, _BlackLightMasking3GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
					}
				}
				#else
				if (_BlackLightMasking0GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking0GlobalMaskIndex - 1, _BlackLightMasking0GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking1GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking1GlobalMaskIndex - 1, _BlackLightMasking1GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking2GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking2GlobalMaskIndex - 1, _BlackLightMasking2GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking3GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking3GlobalMaskIndex - 1, _BlackLightMasking3GlobalMaskBlendType, 0);
				}
				#endif
			}
			#endif
			//endex
			
			//ifex _MainVertexColoringEnabled==0
			void applyVertexColor(inout PoiFragData poiFragData, PoiMesh poiMesh)
			{
				if (_MainVertexColoringEnabled)
				{
					#ifndef POI_PASS_OUTLINE
					float3 vertCol = lerp(poiMesh.vertexColor.rgb, GammaToLinearSpace(poiMesh.vertexColor.rgb), _MainVertexColoringLinearSpace);
					poiFragData.baseColor *= lerp(1, vertCol, _MainVertexColoring);
					#endif
					poiFragData.alpha *= lerp(1, poiMesh.vertexColor.a, _MainUseVertexColorAlpha);
				}
			}
			//endex
			
			//ifex _ShadingEnabled==0
			#ifdef VIGNETTE_MASKED
			
			#ifdef _LIGHTINGMODE_CLOTH
			float V_SmithGGXCorrelated(float roughness, float NoV, float NoL)
			{
				// Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"
				float a2 = roughness * roughness;
				// TODO: lambdaV can be pre-computed for all the lights, it should be moved out of this function
				float lambdaV = NoL * sqrt((NoV - a2 * NoV) * NoV + a2);
				float lambdaL = NoV * sqrt((NoL - a2 * NoL) * NoL + a2);
				float v = 0.5 / (lambdaV + lambdaL);
				// a2=0 => v = 1 / 4*NoL*NoV   => min=1/4, max=+inf
				// a2=1 => v = 1 / 2*(NoL+NoV) => min=1/4, max=+inf
				// clamp to the maximum value representable in mediump
				return v;
			}
			
			float D_GGX(float roughness, float NoH)
			{
				// Walter et al. 2007, "Microfacet Models for Refraction through Rough Surfaces"
				
				// In mediump, there are two problems computing 1.0 - NoH^2
				// 1) 1.0 - NoH^2 suffers floating point cancellation when NoH^2 is close to 1 (highlights)
				// 2) NoH doesn't have enough precision around 1.0
				// Both problem can be fixed by computing 1-NoH^2 in highp and providing NoH in highp as well
				
				// However, we can do better using Lagrange's identity:
				//      ||a x b||^2 = ||a||^2 ||b||^2 - (a . b)^2
				// since N and H are unit vectors: ||N x H||^2 = 1.0 - NoH^2
				// This computes 1.0 - NoH^2 directly (which is close to zero in the highlights and has
				// enough precision).
				// Overall this yields better performance, keeping all computations in mediump
				float oneMinusNoHSquared = 1.0 - NoH * NoH;
				
				float a = NoH * roughness;
				float k = roughness / (oneMinusNoHSquared + a * a);
				float d = k * k * (1.0 / UNITY_PI);
				return d;
			}
			
			// https://github.com/google/filament/blob/main/shaders/src/brdf.fs#L94-L100
			float D_Charlie(float roughness, float NoH)
			{
				// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF"
				float invAlpha = 1.0 / roughness;
				float cos2h = NoH * NoH;
				float sin2h = max(1.0 - cos2h, 0.0078125); // 0.0078125 = 2^(-14/2), so sin2h^2 > 0 in fp16
				return (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * UNITY_PI);
			}
			
			// https://github.com/google/filament/blob/main/shaders/src/brdf.fs#L136-L139
			float V_Neubelt(float NoV, float NoL)
			{
				// Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886"
				return 1.0 / (4.0 * (NoL + NoV - NoL * NoV));
			}
			
			float Distribution(float roughness, float NoH, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(GGXTerm(roughness, NoH), D_Charlie(roughness, NoH), cloth);
				}
				//endex
				return cloth <= 0.5 ? GGXTerm(roughness, NoH) : D_Charlie(roughness, NoH);
			}
			
			float Visibility(float roughness, float NoV, float NoL, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(V_SmithGGXCorrelated(roughness, NoV, NoL), V_Neubelt(NoV, NoL), cloth);
				}
				//endex
				return cloth <= 0.5 ? V_SmithGGXCorrelated(roughness, NoV, NoL) : V_Neubelt(NoV, NoL);
			}
			
			float F_Schlick(float3 f0, float f90, float VoH)
			{
				// Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"
				return f0 + (f90 - f0) * pow(1.0 - VoH, 5);
			}
			
			float F_Schlick(float3 f0, float VoH)
			{
				float f = pow(1.0 - VoH, 5.0);
				return f + f0 * (1.0 - f);
			}
			
			float Fresnel(float3 f0, float LoH)
			{
				float f90 = saturate(dot(f0, float(50.0 * 0.33).xxx));
				return F_Schlick(f0, f90, LoH);
			}
			
			float Fd_Burley(float roughness, float NoV, float NoL, float LoH)
			{
				// Burley 2012, "Physically-Based Shading at Disney"
				float f90 = 0.5 + 2.0 * roughness * LoH * LoH;
				float lightScatter = F_Schlick(1.0, f90, NoL);
				float viewScatter = F_Schlick(1.0, f90, NoV);
				return lightScatter * viewScatter;
			}
			
			// Energy conserving wrap diffuse term, does *not* include the divide by PI
			float Fd_Wrap(float NoL, float w)
			{
				return saturate((NoL + w) / pow(1.0 + w, 2));
			}
			
			float4 SampleDFG(float NoV, float perceptualRoughness)
			{
				return _ClothDFG.Sample(sampler_ClothDFG, float3(NoV, perceptualRoughness, 0));
			}
			
			float3 EnvBRDF(float2 dfg, float3 f0)
			{
				return f0 * dfg.x + dfg.y;
			}
			
			float3 EnvBRDFMultiscatter(float3 dfg, float3 f0, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(lerp(dfg.xxx, dfg.yyy, f0), f0 * dfg.z, cloth);
				}
				//endex
				return cloth <= 0.5 ? lerp(dfg.xxx, dfg.yyy, f0) : f0 * dfg.z;
			}
			
			float3 EnvBRDFEnergyCompensation(float3 dfg, float3 f0, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(1.0 + f0 * (1.0 / dfg.y - 1.0), 1, cloth);
				}
				//endex
				return cloth <= 0.5 ? 1.0 + f0 * (1.0 / dfg.y - 1.0) : 1;
			}
			
			//
			float ClothMetallic(float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return cloth;
				}
				//endex
				return cloth <= 0.5 ? 1 : 0;
			}
			
			float3 Specular(float roughness, PoiLight poiLight, float f0, float3 normal, float cloth)
			{
				float NoL = poiLight.nDotLSaturated;
				float NoH = poiLight.nDotH;
				float LoH = poiLight.lDotH;
				float NoV = poiLight.nDotV;
				
				float D = Distribution(roughness, NoH, cloth);
				float V = Visibility(roughness, NoV, NoL, cloth);
				float3 F = Fresnel(f0, LoH);
				
				return (D * V) * F;
			}
			
			float3 getBoxProjection(float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax)
			{
				#if UNITY_SPECCUBE_BOX_PROJECTION
				if (cubemapPosition.w > 0)
				{
					float3 factors = ((direction > 0 ? boxMax : boxMin) - position) / direction;
					float scalar = min(min(factors.x, factors.y), factors.z);
					direction = direction * scalar + (position - cubemapPosition.xyz);
				}
				#endif
				
				return direction;
			}
			
			float SpecularAO(float NoV, float ao, float roughness)
			{
				return clamp(pow(NoV + ao, exp2(-16.0 * roughness - 1.0)) - 1.0 + ao, 0.0, 1.0);
			}
			
			float3 IndirectSpecular(float3 dfg, float roughness, float occlusion, float energyCompensation, float cloth, float3 indirectDiffuse, float f0, PoiLight poiLight, PoiFragData poiFragData, PoiCam poiCam, PoiMesh poiMesh)
			{
				float3 normal = poiMesh.normals[1];
				
				float3 reflDir = reflect(-poiCam.viewDir, normal);
				
				Unity_GlossyEnvironmentData envData;
				envData.roughness = roughness;
				envData.reflUVW = getBoxProjection(reflDir, poiMesh.worldPos, unity_SpecCube0_ProbePosition,
				unity_SpecCube0_BoxMin.xyz, unity_SpecCube0_BoxMax.xyz);
				
				float3 probe0 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE(unity_SpecCube0), unity_SpecCube0_HDR, envData);
				float3 indirectSpecular = probe0;
				
				#if UNITY_SPECCUBE_BLENDING
				UNITY_BRANCH
				if (unity_SpecCube0_BoxMin.w < 0.99999)
				{
					envData.reflUVW = getBoxProjection(reflDir, poiMesh.worldPos, unity_SpecCube1_ProbePosition, unity_SpecCube1_BoxMin.xyz, unity_SpecCube1_BoxMax.xyz);
					float3 probe1 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1, unity_SpecCube0), unity_SpecCube1_HDR, envData);
					indirectSpecular = lerp(probe1, probe0, unity_SpecCube0_BoxMin.w);
				}
				#endif
				
				float horizon = min(1 + dot(reflDir, normal), 1);
				indirectSpecular = indirectSpecular * horizon * horizon * energyCompensation * EnvBRDFMultiscatter(dfg, f0, cloth);
				
				indirectSpecular *= SpecularAO(poiLight.nDotV, occlusion, roughness);
				return indirectSpecular;
			};
			#endif
			
			#ifdef _LIGHTINGMODE_WRAPPED
			// Wrapped
			// Green’s model with adjustable energy
			// http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/
			// Modified for adjustable conservation ratio and over-wrap to directionless
			float RTWrapFunc(in float dt, in float w, in float norm)
			{
				float cw = saturate(w);
				
				float o = (dt + cw) / ((1.0 + cw) * (1.0 + cw * norm));
				float flt = 1.0 - 0.85 * norm;
				if (w > 1.0)
				{
					o = lerp(o, flt, w - 1.0);
				}
				return o;
			}
			
			float3 GreenWrapSH(float fA) // Greens unoptimized and non-normalized
			
			{
				float fAs = saturate(fA);
				float4 t = float4(fA + 1, fAs - 1, fA - 2, fAs + 1); // DJL edit: allow wrapping to L0-only at w=2
				return float3(t.x, -t.z * t.x / 3, 0.25 * t.y * t.y * t.w);
			}
			float3 GreenWrapSHOpt(float fW) // optimised and normalized https://blog.selfshadow.com/2012/01/07/righting-wrap-part-2/
			
			{
				const float4 t0 = float4(0.0, 1.0 / 4.0, -1.0 / 3.0, -1.0 / 2.0);
				const float4 t1 = float4(1.0, 2.0 / 3.0, 1.0 / 4.0, 0.0);
				float3 fWs = float3(fW, fW, saturate(fW)); // DJL edit: allow wrapping to L0-only at w=2
				
				float3 r;
				r.xyz = t0.xxy * fWs + t0.xzw;
				r.xyz = r.xyz * fWs + t1.xyz;
				return r;
			}
			float3 ShadeSH9_wrapped(float3 normal, float wrap)
			{
				float3 x0, x1, x2;
				float3 conv = lerp(GreenWrapSH(wrap), GreenWrapSHOpt(wrap), _LightingWrappedNormalization); // Should try optimizing this...
				conv *= float3(1, 1.5, 4); // Undo pre-applied cosine convolution by using the inverse
				
				// Constant (L0)
				x0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
				// Remove pre-applied constant part from L(2,0) to apply correct convolution
				float3 L2_0 = float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / - 3.0;
				x0 -= L2_0;
				
				// Linear (L1) polynomial terms
				x1.r = dot(unity_SHAr.xyz, normal);
				x1.g = dot(unity_SHAg.xyz, normal);
				x1.b = dot(unity_SHAb.xyz, normal);
				
				// 4 of the quadratic (L2) polynomials
				float4 vB = normal.xyzz * normal.yzzx;
				x2.r = dot(unity_SHBr, vB);
				x2.g = dot(unity_SHBg, vB);
				x2.b = dot(unity_SHBb, vB);
				
				// Final (5th) quadratic (L2) polynomial
				float vC = normal.x * normal.x - normal.y * normal.y;
				x2 += unity_SHC.rgb * vC;
				// Move back the constant part of L(2,0)
				x2 += L2_0;
				
				return x0 * conv.x + x1 * conv.y + x2 * conv.z;
			}
			
			float3 GetSHDirectionL1()
			{
				// For efficiency, we only get the direction from L1.
				// Because getting it from L2 would be too hard!
				return Unity_SafeNormalize((unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz));
			}
			// Returns the value from SH in the lighting direction with the
			// brightest intensity.
			half3 GetSHMaxL1()
			{
				float3 maxDirection = GetSHDirectionL1();
				return ShadeSH9_wrapped(maxDirection, 0);
			}
			#endif
			
			#ifdef _LIGHTINGMODE_SHADEMAP
			void applyShadeMapping(inout PoiFragData poiFragData, PoiMesh poiMesh, inout PoiLight poiLight)
			{
				float shadowAttenuation = lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				float attenuation = 1;
				#if defined(POINT) || defined(SPOT)
				shadowAttenuation = lerp(1, poiLight.additiveShadow, poiLight.attenuationStrength);
				//attenuation = poiLight.attenuation;
				#endif
				
				float MainColorFeatherStep = _BaseColor_Step - _BaseShade_Feather;
				float firstColorFeatherStep = _ShadeColor_Step - _1st2nd_Shades_Feather;
				
				#if defined(PROP_1ST_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
				float4 firstShadeMap = POI2D_SAMPLER_PAN(_1st_ShadeMap, _MainTex, poiUV(poiMesh.uv[_1st_ShadeMapUV], _1st_ShadeMap_ST), _1st_ShadeMapPan);
				#else
				float4 firstShadeMap = float4(1, 1, 1, 1);
				#endif
				firstShadeMap = lerp(firstShadeMap, float4(poiFragData.baseColor, 1), _Use_BaseAs1st);
				
				#if defined(PROP_2ND_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
				float4 secondShadeMap = POI2D_SAMPLER_PAN(_2nd_ShadeMap, _MainTex, poiUV(poiMesh.uv[_2nd_ShadeMapUV], _2nd_ShadeMap_ST), _2nd_ShadeMapPan);
				#else
				float4 secondShadeMap = float4(1, 1, 1, 1);
				#endif
				secondShadeMap = lerp(secondShadeMap, firstShadeMap, _Use_1stAs2nd);
				
				firstShadeMap.rgb *= _1st_ShadeColor.rgb; //* lighColor
				secondShadeMap.rgb *= _2nd_ShadeColor.rgb; //* LightColor;
				
				float shadowMask = 1;
				shadowMask *= _Use_1stShadeMapAlpha_As_ShadowMask ? (_1stShadeMapMask_Inverse ? (1.0 - firstShadeMap.a) : firstShadeMap.a) : 1;
				shadowMask *= _Use_2ndShadeMapAlpha_As_ShadowMask ? (_2ndShadeMapMask_Inverse ? (1.0 - secondShadeMap.a) : secondShadeMap.a) : 1;
				
				float mainShadowMask = saturate(1 - ((poiLight.lightMap) - MainColorFeatherStep) / (_BaseColor_Step - MainColorFeatherStep) * (shadowMask));
				float firstSecondShadowMask = saturate(1 - ((poiLight.lightMap) - firstColorFeatherStep) / (_ShadeColor_Step - firstColorFeatherStep) * (shadowMask));
				
				mainShadowMask *= poiLight.shadowMask * _ShadowStrength;
				firstSecondShadowMask *= poiLight.shadowMask * _ShadowStrength;
				
				// 0 lerp | 1 multiply
				if (_ShadingShadeMapBlendType == 0)
				{
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, lerp(firstShadeMap.rgb, secondShadeMap.rgb, firstSecondShadowMask), mainShadowMask) * attenuation;
				}
				else
				{
					poiFragData.baseColor.rgb *= lerp(1, lerp(firstShadeMap.rgb, secondShadeMap.rgb, firstSecondShadowMask), mainShadowMask) * attenuation;
				}
				poiLight.rampedLightMap = 1 - mainShadowMask;
			}
			#endif
			
			#ifdef _LIGHTINGMODE_REALISTIC
			// For https://docs.unity3d.com/Manual/LightMode-Mixed-Subtractive.html
			#if defined(LIGHTMAP_ON) && defined(SHADOWS_SCREEN)
			#if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK)
			#define SUBTRACTIVE_LIGHTING 1
			#endif
			#endif
			
			void ApplySubtractiveLighting(inout UnityIndirect indirectLight)
			{
				#if SUBTRACTIVE_LIGHTING
				poiLight.attenuation = FadeShadows(lerp(1, poiLight.attenuation, _AttenuationMultiplier));
				
				float ndotl = saturate(dot(i.normal, _WorldSpaceLightPos0.xyz));
				float3 shadowedLightEstimate = ndotl * (1 - poiLight.attenuation) * _LightColor0.rgb;
				float3 subtractedLight = indirectLight.diffuse - shadowedLightEstimate;
				subtractedLight = max(subtractedLight, unity_ShadowColor.rgb);
				subtractedLight = lerp(subtractedLight, indirectLight.diffuse, _LightShadowData.x);
				indirectLight.diffuse = min(subtractedLight, indirectLight.diffuse);
				#endif
			}
			
			UnityIndirect CreateIndirectLight(in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight)
			{
				UnityIndirect indirectLight;
				indirectLight.diffuse = 0;
				indirectLight.specular = 0;
				
				#if defined(LIGHTMAP_ON)
				indirectLight.diffuse = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, poiMesh.lightmapUV.xy));
				
				#if defined(DIRLIGHTMAP_COMBINED)
				float4 lightmapDirection = UNITY_SAMPLE_TEX2D_SAMPLER(
				unity_LightmapInd, unity_Lightmap, poiMesh.lightmapUV.xy
				);
				indirectLight.diffuse = DecodeDirectionalLightmap(
				indirectLight.diffuse, lightmapDirection, poiMesh.normals[1]
				);
				#endif
				ApplySubtractiveLighting(indirectLight);
				#endif
				
				#if defined(DYNAMICLIGHTMAP_ON)
				float3 dynamicLightDiffuse = DecodeRealtimeLightmap(
				UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, poiMesh.lightmapUV.zw)
				);
				
				#if defined(DIRLIGHTMAP_COMBINED)
				float4 dynamicLightmapDirection = UNITY_SAMPLE_TEX2D_SAMPLER(
				unity_DynamicDirectionality, unity_DynamicLightmap,
				poiMesh.lightmapUV.zw
				);
				indirectLight.diffuse += DecodeDirectionalLightmap(
				dynamicLightDiffuse, dynamicLightmapDirection, poiMesh.normals[1]
				);
				#else
				indirectLight.diffuse += dynamicLightDiffuse;
				#endif
				#endif
				
				#if !defined(LIGHTMAP_ON) && !defined(DYNAMICLIGHTMAP_ON)
				#if UNITY_LIGHT_PROBE_PROXY_VOLUME
				if (unity_ProbeVolumeParams.x == 1)
				{
					indirectLight.diffuse = SHEvalLinearL0L1_SampleProbeVolume(
					float4(poiMesh.normals[1], 1), poiMesh.worldPos
					);
					indirectLight.diffuse = max(0, indirectLight.diffuse);
					#if defined(UNITY_COLORSPACE_GAMMA)
					indirectLight.diffuse = LinearToGammaSpace(indirectLight.diffuse);
					#endif
				}
				else
				{
					indirectLight.diffuse += max(0, ShadeSH9(float4(poiMesh.normals[1], 1)));
				}
				#else
				indirectLight.diffuse += max(0, ShadeSH9(float4(poiMesh.normals[1], 1)));
				#endif
				#endif
				
				indirectLight.diffuse *= poiLight.occlusion;
				
				return indirectLight;
			}
			#endif
			
			float GetRemapMinValue(float scale, float offset)
			{
				return clamp(-offset / scale, -0.01f, 1.01f); // Remap min
				
			}
			float GetRemapMaxValue(float scale, float offset)
			{
				return clamp((1.0f - offset) / scale, -0.01f, 1.01f); // Remap Max
				
			}
			
			void calculateShading(inout PoiLight poiLight, inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam)
			{
				float shadowAttenuation = lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				float attenuation = 1;
				#if defined(POINT) || defined(SPOT)
				shadowAttenuation = lerp(1, poiLight.additiveShadow, poiLight.attenuationStrength);
				//attenuation = poiLight.attenuation;
				#endif
				
				#ifdef POI_PASS_ADD
				if (_LightingAdditiveType == 3)
				{
					#if defined(POINT) || defined(SPOT)
					#if defined(_LIGHTINGMODE_REALISTIC) || defined(_LIGHTINGMODE_CLOTH) || defined(_LIGHTINGMODE_WRAPPED)
					poiLight.rampedLightMap = max(0, poiLight.nDotL);
					poiLight.finalLighting = poiLight.directColor * attenuation * max(0, poiLight.nDotL) * poiLight.detailShadow * shadowAttenuation;
					return;
					#endif
					#endif
				}
				// Realistic
				if (_LightingAdditiveType == 0)
				{
					poiLight.rampedLightMap = max(0, poiLight.nDotL);
					poiLight.finalLighting = poiLight.directColor * attenuation * max(0, poiLight.nDotL) * poiLight.detailShadow * shadowAttenuation;
					return;
				}
				// Toon
				if (_LightingAdditiveType == 1)
				{
					#if defined(POINT_COOKIE) || defined(DIRECTIONAL_COOKIE)
					float passthrough = 0;
					#else
					float passthrough = _LightingAdditivePassthrough;
					#endif
					
					float2 ToonAddGradient = float2(_LightingAdditiveGradientStart, _LightingAdditiveGradientEnd);
					
					if (ToonAddGradient.x == ToonAddGradient.y) ToonAddGradient.y += 0.0001;
					
					poiLight.rampedLightMap = smoothstep(ToonAddGradient.y, ToonAddGradient.x, 1 - (.5 * poiLight.nDotL + .5));
					#if defined(POINT) || defined(SPOT)
					poiLight.finalLighting = lerp(poiLight.directColor * max(min(poiLight.additiveShadow, poiLight.detailShadow), passthrough), poiLight.indirectColor, smoothstep(ToonAddGradient.x, ToonAddGradient.y, 1 - (.5 * poiLight.nDotL + .5)));
					#else
					poiLight.finalLighting = lerp(poiLight.directColor * max(min(poiLight.attenuation, poiLight.detailShadow), passthrough), poiLight.indirectColor, smoothstep(ToonAddGradient.x, ToonAddGradient.y, 1 - (.5 * poiLight.nDotL + .5)));
					#endif
					return;
				}
				#endif
				
				float shadowStrength = _ShadowStrength * poiLight.shadowMask;
				
				#ifdef POI_PASS_OUTLINE
				shadowStrength = lerp(0, shadowStrength, _OutlineShadowStrength);
				#endif
				
				// These blocks shouldn't need ifex, they should be removed on lock when their keywords aren't present
				
				#ifdef _LIGHTINGMODE_FLAT
				poiLight.finalLighting = poiLight.directColor * attenuation * shadowAttenuation;
				if (_ForceFlatRampedLightmap)
				{
					poiLight.rampedLightMap = smoothstep(0.4, 0.6, poiLight.nDotLNormalized);
				}
				else
				{
					poiLight.rampedLightMap = 1;
				}
				#endif
				
				#ifdef _LIGHTINGMODE_TEXTURERAMP
				float2 rampUVs = poiLight.lightMap + _ShadowOffset;
				if (_ToonRampCount > 1)
				{
					rampUVs.y = (floor(poiMesh.uv[_ToonRampUVSelector].y * _ToonRampCount) + 0.5) / _ToonRampCount;
				}
				poiLight.rampedLightMap = lerp(1, UNITY_SAMPLE_TEX2D_SAMPLER(_ToonRamp, _linear_clamp, rampUVs).rgb, shadowStrength);
				poiLight.finalLighting = lerp(_LightingShadowColor * lerp(poiLight.indirectColor, poiLight.rampedLightMap * poiLight.directColor, _LightingIgnoreAmbientColor) * poiLight.occlusion, poiLight.directColor, poiLight.rampedLightMap) * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_MULTILAYER_MATH
				#if defined(PROP_MULTILAYERMATHBLURMAP) || !defined(OPTIMIZER_ENABLED)
				float4 blurMap = POI2D_SAMPLER_PAN(_MultilayerMathBlurMap, _MainTex, poiUV(poiMesh.uv[_MultilayerMathBlurMapUV], _MultilayerMathBlurMap_ST), _MultilayerMathBlurMapPan);
				#else
				float4 blurMap = 1;
				#endif
				
				float4 lns = float4(1, 1, 1, 1);
				
				float shadowAttenuationNoStrength = poiLight.attenuation;
				#if defined(POINT) || defined(SPOT)
				shadowAttenuationNoStrength = poiLight.additiveShadow;
				#endif
				
				float3 lightMap = poiLight.lightMapNoAttenuation.xxx;
				lightMap.x *= lerp(1.0, shadowAttenuationNoStrength, _ShadowReceive);
				lightMap.y *= lerp(1.0, shadowAttenuationNoStrength, _Shadow2ndReceive);
				lightMap.z *= lerp(1.0, shadowAttenuationNoStrength, _Shadow3rdReceive);
				
				float4 shadowBorderMask = 1;
				if (_ShadowBorderMapToggle)
				{
					// This should be moved to ui but honestly if these are locked in the compiler should be able to resolve it at compile time
					float2 shadowShift0 = float2(_ShadowAOShift.x, _ShadowAOShift.y);
					float2 shadowShift1 = float2(_ShadowAOShift.z, _ShadowAOShift.w);
					float2 shadowShift2 = float2(_ShadowAOShift2.x, _ShadowAOShift2.y);
					
					//float2 shadowShift0 = float2(GetRemapMinValue(_ShadowAOShift.x, _ShadowAOShift.y), GetRemapMaxValue(_ShadowAOShift.x, _ShadowAOShift.y));
					//float2 shadowShift1 = float2(GetRemapMinValue(_ShadowAOShift.z, _ShadowAOShift.w), GetRemapMaxValue(_ShadowAOShift.z, _ShadowAOShift.w));
					//float2 shadowShift2 = float2(GetRemapMinValue(_ShadowAOShift2.x, _ShadowAOShift2.y), GetRemapMaxValue(_ShadowAOShift2.x, _ShadowAOShift2.y));
					
					shadowShift0.y = (shadowShift0.x == shadowShift0.y) ? (shadowShift0.y + 0.001f) : shadowShift0.y;
					shadowShift1.y = (shadowShift1.x == shadowShift1.y) ? (shadowShift1.y + 0.001f) : shadowShift1.y;
					shadowShift2.y = (shadowShift2.x == shadowShift2.y) ? (shadowShift2.y + 0.001f) : shadowShift2.y;
					
					shadowShift0 = float2(1.0f / (shadowShift0.y - shadowShift0.x), shadowShift0.x / (shadowShift0.x - shadowShift0.y));
					shadowShift1 = float2(1.0f / (shadowShift1.y - shadowShift1.x), shadowShift1.x / (shadowShift1.x - shadowShift1.y));
					shadowShift2 = float2(1.0f / (shadowShift2.y - shadowShift2.x), shadowShift2.x / (shadowShift2.x - shadowShift2.y));
					
					#if defined(PROP_SHADOWBORDERMASK) || !defined(OPTIMIZER_ENABLED)
					float2 shadowBorderMaskUV = poiUV(poiMesh.uv[_ShadowBorderMaskUV], _ShadowBorderMask_ST);
					if (_ShadowBorderMaskLOD)
					{
						shadowBorderMask = POI2D_SAMPLE_TEX2D_SAMPLERGRADD(_ShadowBorderMask, sampler_trilinear_repeat, shadowBorderMaskUV, _ShadowBorderMaskPan, max(abs(ddx(shadowBorderMaskUV)), pow(_ShadowBorderMaskLOD, 4)), max(abs(ddy(shadowBorderMaskUV)), pow(_ShadowBorderMaskLOD, 4)));
					}
					else
					{
						shadowBorderMask = POI2D_SAMPLER_PAN(_ShadowBorderMask, _linear_repeat, shadowBorderMaskUV, _ShadowBorderMaskPan);
					}
					#endif
					
					shadowBorderMask.r = saturate(shadowBorderMask.r * shadowShift0.x + shadowShift0.y);
					shadowBorderMask.g = saturate(shadowBorderMask.g * shadowShift1.x + shadowShift1.y);
					shadowBorderMask.b = saturate(shadowBorderMask.b * shadowShift2.x + shadowShift2.y);
					
					lightMap.xyz = _ShadowPostAO ? lightMap.xyz : lightMap.xyz * shadowBorderMask.rgb;
				}
				
				if (_LightingMulitlayerNonLinear)
				{
					lns.x = poiEdgeNonLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r);
					lns.y = poiEdgeNonLinearNoSaturate(lightMap.y, _Shadow2ndBorder, _Shadow2ndBlur * blurMap.g);
					lns.z = poiEdgeNonLinearNoSaturate(lightMap.z, _Shadow3rdBorder, _Shadow3rdBlur * blurMap.b);
					lns.w = poiEdgeNonLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r, _ShadowBorderRange);
				}
				else
				{
					lns.x = poiEdgeLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r);
					lns.y = poiEdgeLinearNoSaturate(lightMap.y, _Shadow2ndBorder, _Shadow2ndBlur * blurMap.g);
					lns.z = poiEdgeLinearNoSaturate(lightMap.z, _Shadow3rdBorder, _Shadow3rdBlur * blurMap.b);
					lns.w = poiEdgeLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r, _ShadowBorderRange);
				}
				#if defined(PROP_SHADOWBORDERMASK) || !defined(OPTIMIZER_ENABLED)
				lns = _ShadowPostAO ? lns * shadowBorderMask.rgbr : lns;
				#endif
				lns = saturate(lns);
				//poiLight.finalLighting = lns.rgb;
				//return;
				float3 indirectColor = 1;
				
				if (_ShadowColor.a > 0)
				{
					#if defined(PROP_SHADOWCOLORTEX) || !defined(OPTIMIZER_ENABLED)
					float4 shadowColorTex = POI2D_SAMPLER_PAN(_ShadowColorTex, _MainTex, poiUV(poiMesh.uv[_ShadowColorTexUV], _ShadowColorTex_ST), _ShadowColorTexPan);
					#else
					float4 shadowColorTex = float4(1, 1, 1, 1);
					#endif
					indirectColor = lerp(float3(1, 1, 1), shadowColorTex.rgb, shadowColorTex.a) * _ShadowColor.rgb;
				}
				if (_Shadow2ndColor.a > 0)
				{
					#if defined(PROP_SHADOW2NDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
					float4 shadow2ndColorTex = POI2D_SAMPLER_PAN(_Shadow2ndColorTex, _MainTex, poiUV(poiMesh.uv[_Shadow2ndColorTexUV], _Shadow2ndColorTex_ST), _Shadow2ndColorTexPan);
					#else
					float4 shadow2ndColorTex = float4(1, 1, 1, 1);
					#endif
					shadow2ndColorTex.rgb = lerp(float3(1, 1, 1), shadow2ndColorTex.rgb, shadow2ndColorTex.a) * _Shadow2ndColor.rgb;
					lns.y = _Shadow2ndColor.a - lns.y * _Shadow2ndColor.a;
					indirectColor = lerp(indirectColor, shadow2ndColorTex.rgb, lns.y);
				}
				if (_Shadow3rdColor.a > 0)
				{
					#if defined(PROP_SHADOW3RDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
					float4 shadow3rdColorTex = POI2D_SAMPLER_PAN(_Shadow3rdColorTex, _MainTex, poiUV(poiMesh.uv[_Shadow3rdColorTexUV], _Shadow3rdColorTex_ST), _Shadow3rdColorTexPan);
					#else
					float4 shadow3rdColorTex = float4(1, 1, 1, 1);
					#endif
					shadow3rdColorTex.rgb = lerp(float3(1, 1, 1), shadow3rdColorTex.rgb, shadow3rdColorTex.a) * _Shadow3rdColor.rgb;
					lns.z = _Shadow3rdColor.a - lns.z * _Shadow3rdColor.a;
					indirectColor = lerp(indirectColor, shadow3rdColorTex.rgb, lns.z);
				}
				
				indirectColor = lerp(indirectColor, indirectColor * poiFragData.baseColor, _ShadowMainStrength);
				poiLight.rampedLightMap = lns.x;
				indirectColor = lerp(indirectColor, 1, lns.w * _ShadowBorderColor.rgb * _ShadowBorderColor.a);
				indirectColor = indirectColor * lerp(poiLight.indirectColor, poiLight.directColor, _LightingIgnoreAmbientColor);
				indirectColor = lerp(poiLight.directColor, indirectColor, shadowStrength * poiLight.shadowMask);
				poiLight.finalLighting = lerp(indirectColor, poiLight.directColor, lns.x) * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_SHADEMAP
				poiLight.finalLighting = poiLight.directColor * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_REALISTIC
				UnityLight light;
				light.dir = poiLight.direction;
				light.color = max(0, _LightColor0.rgb) * saturate(shadowAttenuation * attenuation * poiLight.detailShadow);
				light.ndotl = poiLight.nDotLSaturated;
				UnityIndirect indirectLight = (UnityIndirect)0;
				#ifdef UNITY_PASS_FORWARDBASE
				indirectLight = CreateIndirectLight(poiMesh, poiCam, poiLight);
				#endif
				#ifdef UNITY_PASS_FORWARDBASE
				light.color = max(light.color * _PPLightingMultiplier, 0);
				light.color = max(light.color + _PPLightingAddition, 0);
				indirectLight.diffuse = max(indirectLight.diffuse * _PPLightingMultiplier, 0);
				indirectLight.diffuse = max(indirectLight.diffuse + _PPLightingAddition, 0);
				#endif
				
				poiLight.rampedLightMap = poiLight.nDotLSaturated;
				poiLight.finalLighting = max(UNITY_BRDF_PBS(1, 0, 0, 0, poiMesh.normals[1], poiCam.viewDir, light, indirectLight).xyz, _LightingMinLightBrightness);
				#endif
				
				#ifdef _LIGHTINGMODE_CLOTH
				#if defined(PROP_CLOTHMETALLICSMOOTHNESSMAP) || !defined(OPTIMIZER_ENABLED)
				float4 clothmapsample = POI2D_SAMPLER_PAN(_ClothMetallicSmoothnessMap, _MainTex, poiUV(poiMesh.uv[_ClothMetallicSmoothnessMapUV], _ClothMetallicSmoothnessMap_ST), _ClothMetallicSmoothnessMapPan);
				float roughness = 1 - (clothmapsample.a * _ClothSmoothness);
				float reflectance = _ClothReflectance * clothmapsample.b;
				float clothmask = clothmapsample.g;
				float metallic = pow(clothmapsample.r * _ClothMetallic, 2) * ClothMetallic(clothmask);
				roughness = _ClothMetallicSmoothnessMapInvert == 1 ? 1 - roughness : roughness;
				#else
				float roughness = 1 - (_ClothSmoothness);
				float metallic = pow(_ClothMetallic, 2);
				float reflectance = _ClothReflectance;
				float clothmask = 1;
				#endif
				
				float perceptualRoughness = pow(roughness, 2);
				float clampedRoughness = max(0.002, perceptualRoughness);
				
				float f0 = 0.16 * reflectance * reflectance * (1 - metallic) + poiFragData.baseColor * metallic;
				float3 fresnel = Fresnel(f0, poiLight.nDotV);
				
				float3 dfg = SampleDFG(poiLight.nDotV, perceptualRoughness);
				
				float energyCompensation = EnvBRDFEnergyCompensation(dfg, f0, clothmask);
				
				poiLight.finalLighting = Fd_Burley(perceptualRoughness, poiLight.nDotV, poiLight.nDotLSaturated, poiLight.lDotH);
				poiLight.finalLighting *= _LightColor0 * attenuation * shadowAttenuation * poiLight.nDotLSaturated;
				poiLight.rampedLightMap = poiLight.nDotLSaturated;
				float3 specular = max(0, Specular(clampedRoughness, poiLight, f0, poiMesh.normals[1], clothmask) * poiLight.finalLighting * energyCompensation * UNITY_PI); // (D * V) * F
				
				#ifdef UNITY_PASS_FORWARDBASE
				float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
				float3 indirectDiffuse;
				indirectDiffuse.r = shEvaluateDiffuseL1Geomerics_local(L0.r, unity_SHAr.xyz, poiMesh.normals[1]);
				indirectDiffuse.g = shEvaluateDiffuseL1Geomerics_local(L0.g, unity_SHAg.xyz, poiMesh.normals[1]);
				indirectDiffuse.b = shEvaluateDiffuseL1Geomerics_local(L0.b, unity_SHAb.xyz, poiMesh.normals[1]);
				indirectDiffuse = max(0, indirectDiffuse);
				
				float3 indirectSpecular = IndirectSpecular(dfg, roughness, poiLight.occlusion, energyCompensation, clothmask, indirectDiffuse, f0, poiLight, poiFragData, poiCam, poiMesh);
				poiLight.finalLightAdd += max(0, specular + indirectSpecular);
				poiLight.finalLighting += indirectDiffuse * poiLight.occlusion;
				#endif
				
				poiFragData.baseColor.xyz *= (1 - metallic);
				#endif
				
				#ifdef _LIGHTINGMODE_WRAPPED
				#define GREYSCALE_VECTOR float3(.33333, .33333, .33333)
				float3 directColor = _LightColor0.rgb * saturate(RTWrapFunc(poiLight.nDotL, _LightingWrappedWrap, _LightingWrappedNormalization));
				float3 indirectColor = 0;
				#ifdef UNITY_PASS_FORWARDBASE
				indirectColor = ShadeSH9_wrapped(poiMesh.normals[_LightingIndirectUsesNormals], _LightingWrappedWrap) * poiLight.occlusion;
				#endif
				directColor = lerp(directColor, dot(directColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic); // Duplicated from Lightdata due to recreating the light colour
				indirectColor = lerp(indirectColor, dot(indirectColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic); // Ditto^
				
				float3 ShadeSH9Plus_2 = GetSHMaxL1();
				float bw_topDirectLighting_2 = dot(_LightColor0.rgb, GREYSCALE_VECTOR);
				float bw_directLighting = dot(directColor, GREYSCALE_VECTOR);
				float bw_indirectLighting = dot(indirectColor, GREYSCALE_VECTOR);
				float bw_topIndirectLighting = dot(ShadeSH9Plus_2, GREYSCALE_VECTOR);
				
				poiLight.lightMap = smoothstep(0, bw_topIndirectLighting + bw_topDirectLighting_2, bw_indirectLighting + bw_directLighting) * min(poiLight.detailShadow, shadowAttenuation);
				poiLight.rampedLightMap = saturate((poiLight.lightMap - (1 - _LightingGradientEnd)) / saturate((1 - _LightingGradientStart) - (1 - _LightingGradientEnd) + fwidth(poiLight.lightMap)));
				float3 mathRamp = lerp(float3(1, 1, 1), saturate(lerp((_LightingShadowColor * lerp(indirectColor, 1, _LightingIgnoreAmbientColor)), float3(1, 1, 1), saturate(poiLight.rampedLightMap))), _ShadowStrength);
				
				directColor *= saturate(poiLight.rampedLightMap + 1 - _ShadowStrength) * _LightingWrappedColor;
				
				float3 finalWrap = directColor + indirectColor;
				if (_LightingCapEnabled)
				{
					finalWrap = clamp(finalWrap, _LightingMinLightBrightness, _LightingCap);
				}
				else
				{
					finalWrap = max(finalWrap, _LightingMinLightBrightness);
				}
				//finalWrap *= attenuation;
				poiLight.finalLighting = finalWrap * saturate(mathRamp + 1 - _ShadowStrength);
				#endif
				
				#ifdef _LIGHTINGMODE_SKIN
				float3 ambientNormalWorld = poiMesh.normals[1];//aTangentToWorld(s, s.blurredNormalTangent);
				poiLight.rampedLightMap = poiLight.nDotLSaturated;
				
				// Scattering mask.
				#if defined(PROP_SKINTHICKNESS) || !defined(OPTIMIZER_ENABLED)
				float subsurface = 1 - POI2D_SAMPLER_PAN(_SkinThicknessMap, _MainTex, poiUV(poiMesh.uv[_SkinThicknessMapUV], _SkinThicknessMap_ST), _SkinThicknessMapPan).r;
				#else
				float subsurface = 1;
				#endif
				if (_SkinThicknessMapInvert)
				{
					subsurface = 1 - subsurface;
				}
				if (_SkinThicknessPower != 1)
				{
					subsurface = pow(subsurface, _SkinThicknessPower);
				}
				float skinScattering = saturate(subsurface * _SssScale * 2);
				
				// Skin subsurface depth absorption tint.
				// cf http://www.crytek.com/download/2014_03_25_CRYENGINE_GDC_Schultz.pdf pg 35
				// link dead, https://ia600902.us.archive.org/25/items/crytek_presentations/2014_03_25_CRYENGINE_GDC_Schultz.pdf
				half3 absorption = exp((1.0h - subsurface) * _SssTransmissionAbsorption.rgb);
				
				// Albedo scale for absorption assumes ~0.5 luminance for Caucasian skin.
				absorption *= saturate(poiFragData.baseColor * unity_ColorSpaceDouble.rgb);
				
				// Blurred normals for indirect diffuse and direct scattering.
				ambientNormalWorld = normalize(lerp(poiMesh.normals[1], ambientNormalWorld, _SssBumpBlur));
				
				float ndlBlur = dot(poiMesh.normals[1], poiLight.direction) * 0.5h + 0.5h;
				float lumi = dot(poiLight.directColor, half3(0.2126h, 0.7152h, 0.0722h));
				float4 sssLookupUv = float4(ndlBlur, skinScattering * lumi, 0.0f, 0.0f);
				half3 sss = poiLight.lightMap * tex2Dlod(_SkinLUT, sssLookupUv).rgb;
				poiLight.finalLighting = lerp(poiLight.directColor, min(lerp(poiLight.indirectColor * _LightingShadowColor, _LightingShadowColor, _LightingIgnoreAmbientColor) * poiLight.occlusion + (sss * poiLight.directColor), poiLight.directColor), _ShadowStrength * poiLight.shadowMask) * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_SDF
				float3 forward = normalize(UnityObjectToWorldDir(float4(_SDFForward.xyz, 1)));
				float3 left = normalize(UnityObjectToWorldDir(float4(_SDFLeft.xyz, 1)));
				float3 lightDirHorizontal = normalize(float3(poiLight.direction.x, 0, poiLight.direction.z));
				
				float lightAtten = 1 - (dot(lightDirHorizontal, forward) * 0.5 + 0.5);
				float filpU = sign(dot(lightDirHorizontal, left));
				
				#if defined(PROP_SDFSHADINGTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float shadowSDF = POI2D_SAMPLER_PAN(_SDFShadingTexture, _MainTex, poiUV(poiMesh.uv[_SDFShadingTextureUV], _SDFShadingTexture_ST) * float2(filpU, 1), _SDFShadingTexturePan).r;
				#else
				float shadowSDF = float2(1, 1);
				#endif
				float blur = _SDFBlur * 0.1;
				float faceShadow = smoothstep(lightAtten - blur, lightAtten + blur, shadowSDF) * poiLight.detailShadow;
				
				float3 indirectColor = _LightingShadowColor.rgb;
				indirectColor = indirectColor * lerp(poiLight.indirectColor, poiLight.directColor, _LightingIgnoreAmbientColor);
				indirectColor = lerp(poiLight.directColor, indirectColor, _ShadowStrength * poiLight.shadowMask);
				
				poiLight.finalLighting = lerp(indirectColor, poiLight.directColor, faceShadow) * attenuation;
				#endif
				
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					float3 vertexLighting = float3(0, 0, 0);
					for (int index = 0; index < 4; index++)
					{
						float lightingMode = _LightingAdditiveType;
						if (lightingMode == 3)
						{
							//This is a temporary bandaid fix
							#if defined(_LIGHTINGMODE_REALISTIC)
							lightingMode = 0;
							#else
							lightingMode = 1;
							#endif
						}
						//UNITY_BRANCH
						if (lightingMode == 0)
						{
							vertexLighting = max(vertexLighting, poiLight.vColor[index] * poiLight.vSaturatedDotNL[index] * poiLight.detailShadow); // Realistic
							
						}
						//UNITY_BRANCH
						// Toon
						if (lightingMode == 1)
						{
							float2 ToonAddGradient = float2(_LightingAdditiveGradientStart, _LightingAdditiveGradientEnd);
							if (ToonAddGradient.x == ToonAddGradient.y) ToonAddGradient.y += 0.0001;
							vertexLighting = max(vertexLighting, lerp(poiLight.vColor[index], poiLight.vColor[index] * _LightingAdditivePassthrough, smoothstep(ToonAddGradient.x, ToonAddGradient.y, 1 - (.5 * poiLight.vDotNL[index] + .5))) * poiLight.detailShadow);
						}
					}
					float3 mixedLight = poiLight.finalLighting;
					poiLight.finalLighting = max(vertexLighting, poiLight.finalLighting);
					#endif
				}
			}
			#endif
			//endex
			
			//ifex _EnableDissolve==0
			#ifdef DISTORT
			void applyDissolve(inout PoiFragData poiFragData, in PoiMesh poiMesh, inout PoiMods poiMods, in PoiCam poiCam, in PoiLight poiLight)
			{
				#if defined(PROP_DISSOLVEMASK) || !defined(OPTIMIZER_ENABLED)
				float dissolveMask = POI2D_SAMPLER_PAN(_DissolveMask, _MainTex, poiUV(poiMesh.uv[_DissolveMaskUV], _DissolveMask_ST), _DissolveMaskPan).r;
				#else
				float dissolveMask = 1;
				#endif
				UNITY_BRANCH
				if (_DissolveUseVertexColors > 0)
				{
					// Vertex Color Imprecision hype
					dissolveMask = ceil(poiMesh.vertexColor[_DissolveUseVertexColors] * 100000) / 100000;
				}
				if (_DissolveMaskGlobalMask > 0)
				{
					dissolveMask = maskBlend(dissolveMask, poiMods.globalMask[_DissolveMaskGlobalMask - 1], _DissolveMaskGlobalMaskBlendType);
				}
				
				#if defined(PROP_DISSOLVETOTEXTURE) || !defined(OPTIMIZER_ENABLED)
				dissolveToTexture = POI2D_SAMPLER_PAN(_DissolveToTexture, _MainTex, poiUV(poiMesh.uv[_DissolveToTextureUV], _DissolveToTexture_ST), _DissolveToTexturePan) * float4(poiThemeColor(poiMods, _DissolveTextureColor.rgb, _DissolveTextureColorThemeIndex), _DissolveTextureColor.a);
				#else
				dissolveToTexture = _DissolveTextureColor;
				#endif
				
				#if defined(PROP_DISSOLVENOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
				float dissolveNoiseTexture = POI2D_SAMPLER_PAN(_DissolveNoiseTexture, _MainTex, poiUV(poiMesh.uv[_DissolveNoiseTextureUV], _DissolveNoiseTexture_ST), _DissolveNoiseTexturePan).r;
				#else
				float dissolveNoiseTexture = 1;
				#endif
				
				float da = _DissolveAlpha
				+ _DissolveAlpha0
				+ _DissolveAlpha1
				+ _DissolveAlpha2
				+ _DissolveAlpha3
				+ _DissolveAlpha4
				+ _DissolveAlpha5
				+ _DissolveAlpha6
				+ _DissolveAlpha7
				+ _DissolveAlpha8
				+ _DissolveAlpha9;
				float dds = _DissolveDetailStrength;
				
				if (_UVTileDissolveEnabled)
				{
					float2 udim = floor(poiMesh.uv[(int)_UVTileDissolveUV]);
					
					float4 xMask = float4((udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					da += (udim.y >= 0 && udim.y < 1) * dot(float4(_UVTileDissolveAlpha_Row0_0, _UVTileDissolveAlpha_Row0_1, _UVTileDissolveAlpha_Row0_2, _UVTileDissolveAlpha_Row0_3), xMask);
					da += (udim.y >= 1 && udim.y < 2) * dot(float4(_UVTileDissolveAlpha_Row1_0, _UVTileDissolveAlpha_Row1_1, _UVTileDissolveAlpha_Row1_2, _UVTileDissolveAlpha_Row1_3), xMask);
					da += (udim.y >= 2 && udim.y < 3) * dot(float4(_UVTileDissolveAlpha_Row2_0, _UVTileDissolveAlpha_Row2_1, _UVTileDissolveAlpha_Row2_2, _UVTileDissolveAlpha_Row2_3), xMask);
					da += (udim.y >= 3 && udim.y < 4) * dot(float4(_UVTileDissolveAlpha_Row3_0, _UVTileDissolveAlpha_Row3_1, _UVTileDissolveAlpha_Row3_2, _UVTileDissolveAlpha_Row3_3), xMask);
				}
				
				#ifdef POI_AUDIOLINK
				UNITY_BRANCH
				if (_EnableDissolveAudioLink && poiMods.audioLinkAvailable)
				{
					da += lerp(_AudioLinkDissolveAlpha.x, _AudioLinkDissolveAlpha.y, poiMods.audioLink[_AudioLinkDissolveAlphaBand]);
					dds += lerp(_AudioLinkDissolveDetail.x, _AudioLinkDissolveDetail.y, poiMods.audioLink[_AudioLinkDissolveDetailBand]);
				}
				#endif
				
				da = saturate(da);
				dds = saturate(dds);
				
				if (_DissolveMaskInvert)
				{
					dissolveMask = 1 - dissolveMask;
				}
				#if defined(PROP_DISSOLVEDETAILNOISE) || !defined(OPTIMIZER_ENABLED)
				float dissolveDetailNoise = POI2D_SAMPLER_PAN(_DissolveDetailNoise, _MainTex, poiUV(poiMesh.uv[_DissolveDetailNoiseUV], _DissolveDetailNoise_ST), _DissolveDetailNoisePan);
				#else
				float dissolveDetailNoise = 0;
				#endif
				if (_DissolveInvertNoise)
				{
					dissolveNoiseTexture = 1 - dissolveNoiseTexture;
				}
				if (_DissolveInvertDetailNoise)
				{
					dissolveDetailNoise = 1 - dissolveDetailNoise;
				}
				if (_ContinuousDissolve != 0)
				{
					da = sin(_Time.x * _ContinuousDissolve) * .5 + .5;
				}
				da *= dissolveMask;
				dissolveAlpha = da;
				edgeAlpha = 0;
				
				[flatten]
				switch(_DissolveType)
				{
					default: // Basic (case 1)
					
					{
						da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						dissolveAlpha = da;
						//Adjust detail strength to avoid artifacts
						dds *= smoothstep(1, 0.99, da) * lerp(1, smoothstep(0, lerp(0.01, 0.1, dds), da), _DissolveDetailEdgeSmoothing);
						float noise = saturate(dissolveNoiseTexture - dissolveDetailNoise * dds);
						
						noise = saturate(noise * 0.998 + 0.001);
						dissolveAlpha = dissolveAlpha >= noise;
						edgeAlpha = remapClamped(da + _DissolveEdgeWidth, da, noise) * (1 - dissolveAlpha);
						break;
					}
					case 2: // Point to Point
					
					{
						float3 direction;
						float3 currentPos;
						float distanceTo = 0;
						direction = normalize(_DissolveEndPoint - _DissolveStartPoint);
						currentPos = lerp(_DissolveStartPoint, _DissolveEndPoint, dissolveAlpha);
						
						UNITY_BRANCH
						if (_DissolveP2PWorldLocal != 1)
						{
							float3 pos = _DissolveP2PWorldLocal == 0 ? poiMesh.localPos.rgb : poiMesh.vertexColor.rgb;
							distanceTo = dot(pos - currentPos, direction) - dissolveDetailNoise * dds;
							edgeAlpha = smoothstep(_DissolveP2PEdgeLength + .00001, 0, distanceTo);
							dissolveAlpha = step(distanceTo, 0);
							edgeAlpha *= 1 - dissolveAlpha;
						}
						else
						{
							distanceTo = dot(poiMesh.worldPos - currentPos, direction) - dissolveDetailNoise * dds;
							edgeAlpha = smoothstep(_DissolveP2PEdgeLength + .00001, 0, distanceTo);
							dissolveAlpha = (distanceTo < 0) ? 1 : 0;
							edgeAlpha *= 1 - dissolveAlpha;
						}
						
						if (_DissolveP2PClamp)
						{
							dissolveAlpha = saturate(dissolveAlpha * smoothstep(0, 0.01, da) + smoothstep(0.99, 1, da));
							edgeAlpha *= smoothstep(0, 0.01, da);
						}
						
						break;
					}
					case 3: // Spherical
					
					{
						if (_SphericalDissolveInvert)
						{
							da = remap(da, 1, 0, -_DissolveEdgeWidth, 1);
						}
						else
						{
							da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						}
						
						dissolveAlpha = da;
						dds *= smoothstep(0, 0.2 * dds + 0.01, dissolveAlpha) * lerp(1, smoothstep(1, 1 - 0.2 * dds - 0.01, dissolveAlpha), _DissolveDetailEdgeSmoothing);
						float currentDistance = lerp(0, _SphericalDissolveRadius, dissolveAlpha);
						float fragDistance = distance(_SphericalDissolveCenter, poiMesh.localPos.xyz);
						float normalizedDistance;
						normalizedDistance = (fragDistance - currentDistance) / (_SphericalDissolveRadius + 0.0001) - dissolveDetailNoise * dds;
						
						if (_SphericalDissolveInvert)
						{
							dissolveAlpha = (normalizedDistance > 0) ? 1 : 0;
							edgeAlpha = smoothstep(_DissolveEdgeWidth + .00001, 0, -normalizedDistance);
						}
						else
						{
							dissolveAlpha = (normalizedDistance < 0) ? 1 : 0;
							edgeAlpha = smoothstep(_DissolveEdgeWidth + .00001, 0, normalizedDistance);
						}
						
						if (_SphericalDissolveClamp)
						{
							da = lerp(da, 1 - da, _SphericalDissolveInvert);
							dissolveAlpha = saturate(dissolveAlpha * smoothstep(0, 0.01, da) + smoothstep(0.99, 1, da));
							edgeAlpha *= smoothstep(0, 0.01, da);
						}
						
						break;
					}
					case 4: // CenterOut
					
					{
						float ramp = 0.5;
						float noise;
						
						[flatten]
						switch(_CenterOutDissolveMode)
						{
							case 1: // View Direction
							
							{
								ramp = saturate(lerp(poiLight.vertexNDotV, poiLight.nDotV, _CenterOutDissolveNormals));
								break;
							}
							case 2: // Custom Direction
							
							{
								ramp = dot(normalize(_CenterOutDissolveDirection), lerp(poiMesh.normals[0], poiMesh.normals[1], _CenterOutDissolveNormals));
								ramp = saturate(ramp * .5 + 0.5);
								break;
							}
							case 3: // Light Direction
							
							{
								ramp = lerp(poiLight.vertexNDotL, poiLight.nDotL, _CenterOutDissolveNormals);
								ramp = saturate(ramp * .5 + 0.5);
								break;
							}
						}
						
						if (_CenterOutDissolvePower != 1)
						{
							ramp = pow(ramp, _CenterOutDissolvePower);
						}
						
						if (!_CenterOutDissolveInvert)
						{
							ramp = 1 - ramp;
						}
						
						da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						dissolveAlpha = da;
						//Adjust detail strength to avoid artifacts
						dds *= smoothstep(1, 0.99, da) * lerp(1, smoothstep(0, lerp(0.01, 0.1, dds), da), _DissolveDetailEdgeSmoothing);
						
						noise = saturate(ramp - dissolveDetailNoise * dds);
						noise = saturate(noise * 0.998 + 0.001);
						dissolveAlpha = dissolveAlpha >= noise;
						edgeAlpha = remapClamped(da + _DissolveEdgeWidth, da, noise) * (1 - dissolveAlpha);
						break;
					}
				}
				
				#ifndef POI_SHADOW
				UNITY_BRANCH
				if (_DissolveHueShiftEnabled)
				{
					dissolveToTexture.rgb = hueShift(dissolveToTexture.rgb, _DissolveHueShift + _Time.x * _DissolveHueShiftSpeed);
				}
				#endif
				
				poiFragData.alpha = lerp(poiFragData.alpha, dissolveToTexture.a, dissolveAlpha * .999999);
				
				#if !defined(POI_PASS_OUTLINE) && !defined(UNITY_PASS_SHADOWCASTER)
				poiFragData.baseColor = lerp(poiFragData.baseColor, dissolveToTexture.rgb, dissolveAlpha * .999999);
				
				if (_DissolveApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _DissolveApplyGlobalMaskIndex - 1, _DissolveApplyGlobalMaskBlendType, dissolveAlpha * .999999);
				}
				if (_DissolveInverseApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _DissolveInverseApplyGlobalMaskIndex - 1, _DissolveInverseApplyGlobalMaskBlendType, 1-(dissolveAlpha * .999999));
				}
				UNITY_BRANCH
				if (_DissolveEdgeWidth || (_DissolveType == 2 && _DissolveP2PEdgeLength != 0))
				{
					edgeColor = tex2D(_DissolveEdgeGradient, poiUV(float2(edgeAlpha, edgeAlpha), _DissolveEdgeGradient_ST)) * float4(poiThemeColor(poiMods, _DissolveEdgeColor.rgb, _DissolveEdgeColorThemeIndex), _DissolveEdgeColor.a);
					#ifndef POI_SHADOW
					UNITY_BRANCH
					if (_DissolveEdgeHueShiftEnabled)
					{
						edgeColor.rgb = hueShift(edgeColor.rgb, _DissolveEdgeHueShift + _Time.x * _DissolveEdgeHueShiftSpeed);
					}
					#endif
					poiFragData.baseColor = lerp(poiFragData.baseColor, edgeColor.rgb, smoothstep(0, 1 - _DissolveEdgeHardness * .99999999999, edgeAlpha));
				}
				
				poiFragData.emission += lerp(0, dissolveToTexture * _DissolveToEmissionStrength, dissolveAlpha) + lerp(0, edgeColor.rgb * _DissolveEdgeEmission, smoothstep(0, 1 - _DissolveEdgeHardness * .99999999999, edgeAlpha));
				#endif
			}
			#endif
			//endex
			
			//ifex _EnableALDecal==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_DECAL
			void ApplyAudioLinkDecal(in PoiMesh poiMesh, inout PoiFragData poiFragData, in PoiMods poiMods)
			{
				float4 colorAndMask = float4(1, 1, 1, 1);
				#if defined(PROP_ALDECALCOLORMASK) || !defined(OPTIMIZER_ENABLED)
				colorAndMask = POI2D_SAMPLER_PAN(_ALDecalColorMask, _MainTex, poiUV(poiMesh.uv[_ALDecalColorMaskUV], _ALDecalColorMask_ST), _ALDecalColorMaskPan);
				#endif
				if (_ALDecalGlobalMask > 0)
				{
					colorAndMask.a = customBlend(colorAndMask.a, poiMods.globalMask[_ALDecalGlobalMask-1], _ALDecalGlobalMaskBlendType);
				}
				
				float2 uv = poiMesh.uv[_ALDecalUV];
				float2 decalCenter = _ALUVPosition;
				float theta = radians(_ALUVRotation + _Time.z * _ALUVRotationSpeed);
				float cs = cos(theta);
				float sn = sin(theta);
				uv = float2((uv.x - decalCenter.x) * cs - (uv.y - decalCenter.y) * sn + decalCenter.x, (uv.x - decalCenter.x) * sn + (uv.y - decalCenter.y) * cs + decalCenter.y);
				uv = remap(uv, float2(0, 0) - _ALUVScale.xz / 2 + _ALUVPosition, _ALUVScale.yw / 2 + _ALUVPosition, float2(0, 0), float2(1, 1));
				
				// Mask
				float4 audioLinkMask = 1.0;
				
				// UV
				float2 aluv = uv;
				if (_ALDecalUVMode == 1)
				{
					float2 uvdir = uv * 2 - 1;
					aluv.x = frac(atan2(uvdir.y, uvdir.x) * UNITY_INV_TWO_PI);
					aluv.y = length(uvdir);
				}
				
				// Scale / Offset / Step
				float maskY = aluv.y;
				if (_ALDecalUVMode == 1)
				{
					maskY = remap(maskY, _ALDecaldCircleDimensions.x, _ALDecaldCircleDimensions.y, 0, 1);
				}
				float maskX = aluv.x;
				if (_ALDecalUVMode == 1)
				{
					maskX = remap(maskX, _ALDecaldCircleDimensions.z, _ALDecaldCircleDimensions.w, 0, 1);
				}
				
				float maskVolume = _ALDecalVolumeStep != 0.0 ? floor(maskY * _ALDecalVolumeStep) / _ALDecalVolumeStep : maskY;
				float maskBand = _ALDecalBandStep != 0.0 ? floor(maskX * _ALDecalBandStep) / _ALDecalBandStep : maskX;
				
				// Copy
				audioLinkMask.r = maskVolume;
				audioLinkMask.g = maskBand;
				
				// Clip
				audioLinkMask.b = maskVolume < _ALDecalVolumeClipMin || maskVolume > _ALDecalVolumeClipMax ? 0.0 : audioLinkMask.b;
				audioLinkMask.b = maskBand < _ALDecalBandClipMin || maskBand > _ALDecalBandClipMax ? 0.0 : audioLinkMask.b;
				
				// Shape Clip
				if (_ALDecalShapeClip)
				{
					float volumeth = _ALDecalShapeClipVolumeWidth;
					if (_ALDecalVolumeStep != 0.0) audioLinkMask.b = frac(maskY * _ALDecalVolumeStep) > volumeth ? 0.0 : audioLinkMask.b;
					
					float bandwidth = _ALDecalUVMode == 1 ? _ALDecalShapeClipBandWidth / aluv.y : _ALDecalShapeClipBandWidth;
					float bandth = 1.0 - bandwidth;
					if (_ALDecalBandStep != 0.0) audioLinkMask.b = frac(maskX * _ALDecalBandStep + bandth * 0.5) < bandth ? 0.0 : audioLinkMask.b;
				}
				
				// AudioLink
				float2 audioLinkUV = float2(frac(audioLinkMask.g * 2.0), 4.5 / 4.0 + floor(audioLinkMask.g * 2.0) / 4.0);
				audioLinkUV.y *= 0.0625;
				float4 audioTexture = _AudioTexture.Sample(sampler_linear_clamp, audioLinkUV);
				float audioVal = audioTexture.b * _ALDecalVolume * lerp(_ALDecalBaseBoost, _ALDecalTrebleBoost, audioLinkMask.g);
				float audioLinkValue = _ALDecalLineWidth < 1.0 ? abs(audioVal - audioLinkMask.r) < _ALDecalLineWidth : audioVal > audioLinkMask.r * 2.0;
				audioLinkValue = saturate(audioLinkValue) * audioLinkMask.b;
				//clip(audioLinkValue - .5);
				audioLinkValue *= colorAndMask.a;
				
				if (!poiMods.audioLinkAvailable)
				{
					audioLinkValue = 0;
				}
				
				float3 alColorChord = _AudioTexture.Sample(sampler_linear_clamp, float2(maskX, 24.5 / 64.0)).rgb;
				float volumeColorSrc = audioLinkMask.g;
				if (_ALDecalVolumeColorSource == 1) volumeColorSrc = audioLinkMask.r;
				if (_ALDecalVolumeColorSource == 2) volumeColorSrc = audioVal;
				
				float3 lowColor = _ALDecalVolumeColorLow.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorLow.rgb, _ALDecalVolumeColorLowThemeIndex);
				float3 midColor = _ALDecalVolumeColorMid.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorMid.rgb, _ALDecalVolumeColorMidThemeIndex);
				float3 highColor = _ALDecalVolumeColorHigh.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorHigh.rgb, _ALDecalVolumeColorHighThemeIndex);
				
				float3 volumeColor = lerp(lowColor, midColor, saturate(volumeColorSrc * 2));
				volumeColor = lerp(volumeColor, highColor, saturate(volumeColorSrc * 2 - 1));
				
				float3 emissionColor = lerp(lowColor * _ALDecalLowEmission, midColor * _ALDecalMidEmission, saturate(volumeColorSrc * 2));
				emissionColor = lerp(emissionColor, highColor * _ALDecalHighEmission, saturate(volumeColorSrc * 2 - 1));
				
				//poiFragData.baseColor = lerp(poiFragData.baseColor, volumeColor, audioLinkValue);
				#if defined(POI_PASS_BASE) || defined(POI_PASS_ADD)
				poiFragData.emission += emissionColor * audioLinkValue;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor, customBlend(poiFragData.baseColor, volumeColor * colorAndMask.rgb, _ALDecalBlendType), saturate(_ALDecalBlendAlpha * audioLinkValue));
				#endif
				poiFragData.alpha = lerp(poiFragData.alpha, poiFragData.alpha * audioLinkValue, _ALDecalControlsAlpha);
			}
			#endif
			#endif
			//endex
			
			//ifex _EnableFlipbook==0
			#ifdef _SUNDISK_HIGH_QUALITY
			
			void applyFlipbook(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				#if defined(PROP_FLIPBOOKTEXARRAY) || !defined(OPTIMIZER_ENABLED)
				float4 flipBookPixel = float4(0, 0, 0, 0);
				#if defined(PROP_FLIPBOOKMASK) || !defined(OPTIMIZER_ENABLED)
				float flipBookMask = POI2D_SAMPLER_PAN(_FlipbookMask, _MainTex, poiUV(poiMesh.uv[_FlipbookMaskUV], _FlipbookMask_ST), _FlipbookMaskPan)[_FlipbookMaskChannel];
				#else
				float flipBookMask = 1;
				#endif
				if (_FlipbookMaskGlobalMask > 0)
				{
					flipBookMask = maskBlend(flipBookMask, poiMods.globalMask[_FlipbookMaskGlobalMask-1], _FlipbookMaskGlobalMaskBlendType);
				}
				float4 flipbookScaleOffset = _FlipbookScaleOffset;
				
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookScaleOffset.xy += lerp(_AudioLinkFlipbookScale.xy, _AudioLinkFlipbookScale.zw, poiMods.audioLink[_AudioLinkFlipbookScaleBand]);
				}
				#endif
				
				flipbookScaleOffset.xy = 1 - flipbookScaleOffset.xy;
				float2 uv = frac(poiMesh.uv[_FlipbookTexArrayUV]);
				float theta = radians(_FlipbookRotation + _Time.z * _FlipbookRotationSpeed);
				float cs = cos(theta);
				float sn = sin(theta);
				float2 spriteCenter = flipbookScaleOffset.zw + .5;
				// 2d rotation
				uv = float2((uv.x - spriteCenter.x) * cs - (uv.y - spriteCenter.y) * sn + spriteCenter.x, (uv.x - spriteCenter.x) * sn + (uv.y - spriteCenter.y) * cs + spriteCenter.y);
				float4 sideOffset = float4(-(_FlipbookSideOffset.x), _FlipbookSideOffset.y, -(_FlipbookSideOffset.z), _FlipbookSideOffset.w);
				float2 newUV = remap(uv, float2(0, 0) + flipbookScaleOffset.xy / 2 + flipbookScaleOffset.zw + sideOffset.xz, float2(1, 1) - flipbookScaleOffset.xy / 2 + flipbookScaleOffset.zw + sideOffset.yw, float2(0, 0), float2(1, 1));
				
				UNITY_BRANCH
				if (_FlipbookTiled == 0)
				{
					if (max(newUV.x, newUV.y) > 1 || min(newUV.x, newUV.y) < 0)
					{
						return;
					}
				}
				float currentFrame = 0;
				float width;
				float height;
				float totalFrames;
				_FlipbookTexArray.GetDimensions(width, height, totalFrames);
				
				if (_FlipbookStartAndEnd)
				{
					totalFrames -= (totalFrames - min(max(_FlipbookStartFrame, _FlipbookEndFrame), totalFrames));
					totalFrames -= max(0, _FlipbookStartFrame);
				}
				if (!_FlipbookManualFrameControl)
				{
					if (_FlipbookFPS != 0)
					{
						currentFrame = ((_Time.y / (1 / _FlipbookFPS)) + _FlipbookFrameOffset) % totalFrames;
						if (_FlipbookStartAndEnd)
						{
							currentFrame += _FlipbookStartFrame;
						}
					}
				}
				else
				{
					currentFrame = fmod(_FlipbookCurrentFrame, totalFrames);
				}
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					if (_FlipbookChronotensityEnabled)
					{
						currentFrame += AudioLinkGetChronoTime(_FlipbookChronoType, _FlipbookChronotensityBand) * _FlipbookChronotensitySpeed;
					}
					currentFrame += lerp(_AudioLinkFlipbookFrame.x, _AudioLinkFlipbookFrame.y, poiMods.audioLink[_AudioLinkFlipbookFrameBand]);
					float totalFramesAL = totalFrames;
					if (_FlipbookStartAndEnd)
					{
						totalFramesAL += max(0, _FlipbookStartFrame);
					}
					currentFrame %= totalFramesAL;
				}
				#endif
				flipBookPixel = UNITY_SAMPLE_TEX2DARRAY(_FlipbookTexArray, float3(TRANSFORM_TEX(newUV, _FlipbookTexArray) + _Time.x * _FlipbookTexArrayPan, floor(currentFrame)));
				UNITY_BRANCH
				if (_FlipbookCrossfadeEnabled)
				{
					float totalFramesCF = totalFrames;
					if (_FlipbookStartAndEnd)
					{
						totalFramesCF += max(0, _FlipbookStartFrame);
					}
					float4 flipbookNextPixel = UNITY_SAMPLE_TEX2DARRAY(_FlipbookTexArray, float3(TRANSFORM_TEX(newUV, _FlipbookTexArray) + _Time.x * _FlipbookTexArrayPan, floor((currentFrame + 1) % totalFramesCF)));
					flipBookPixel = lerp(flipBookPixel, flipbookNextPixel, smoothstep(_FlipbookCrossfadeRange.x, _FlipbookCrossfadeRange.y, frac(currentFrame)));
				}
				
				UNITY_BRANCH
				if (_FlipbookIntensityControlsAlpha)
				{
					flipBookPixel.a = poiMax(flipBookPixel.rgb);
				}
				UNITY_BRANCH
				if (_FlipbookColorReplaces)
				{
					flipBookPixel.rgb = poiThemeColor(poiMods, _FlipbookColor.rgb, _FlipbookColorThemeIndex);
				}
				else
				{
					flipBookPixel.rgb *= poiThemeColor(poiMods, _FlipbookColor.rgb, _FlipbookColorThemeIndex);
				}
				
				UNITY_BRANCH
				if (_FlipbookHueShiftEnabled)
				{
					flipBookPixel.rgb = hueShift(flipBookPixel.rgb, _FlipbookHueShift + _Time.x * _FlipbookHueShiftSpeed);
				}
				half flipbookAlpha = 1;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookAlpha += saturate(lerp(_AudioLinkFlipbookAlpha.x, _AudioLinkFlipbookAlpha.y, poiMods.audioLink[_AudioLinkFlipbookAlphaBand]));
				}
				#endif
				
				#if !defined(POI_PASS_OUTLINE) && !defined(UNITY_PASS_SHADOWCASTER)
				
				poiFragData.baseColor = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, flipBookPixel.rgb, _FlipbookBlendType), flipBookPixel.a * _FlipbookColor.a * _FlipbookReplace * flipBookMask * flipbookAlpha);
				
				float flipbookEmissionStrength = _FlipbookEmissionStrength;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookEmissionStrength += max(lerp(_AudioLinkFlipbookEmission.x, _AudioLinkFlipbookEmission.y, poiMods.audioLink[_AudioLinkFlipbookEmissionBand]), 0);
				}
				#endif
				
				poiFragData.emission += lerp(0, flipBookPixel.rgb * flipbookEmissionStrength, flipBookPixel.a * _FlipbookColor.a * flipBookMask * flipbookAlpha);
				
				#endif
				
				UNITY_BRANCH
				if (_FlipbookAlphaControlsFinalAlpha)
				{
					poiFragData.alpha = lerp(poiFragData.alpha, flipBookPixel.a * _FlipbookColor.a, flipBookMask);
				}
				#endif
			}
			
			#endif
			//endex
			
			//ifex _EnableMirrorOptions==0
			#ifdef POI_MIRROR
			void applyMirror(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float inMirror = 0;
				// VRC
				if (_VisibilityMode == 1)
				{
					inMirror = VRCMirrorMode() > 0;
				}
				// Generic (CVR, etc)
				else
				{
					inMirror = IsInMirror();
				}
				
				#if (defined(POI_PASS_BASE) || defined(POI_PASS_ADD))
				#if defined(PROP_MIRRORTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 mirrorTexture = POI2D_SAMPLER_PAN(_MirrorTexture, _MainTex, poiUV(poiMesh.uv[_MirrorTextureUV], _MirrorTexture_ST), _MirrorTexturePan);
				if (inMirror && _MirrorTextureEnabled || _MirrorTextureForceEnabled)
				{
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, mirrorTexture.rgb, _MirrorTextureBlendType), mirrorTexture.a * _MirrorColor.a);
					poiFragData.baseColor.rgb *= lerp(1, poiThemeColor(poiMods, _MirrorColor.rgb, _MirrorColorThemeIndex), _MirrorColor.a);
				}
				#else
				if (inMirror && _MirrorTextureEnabled || _MirrorTextureForceEnabled)
				{
					poiFragData.baseColor.rgb *= lerp(1, poiThemeColor(poiMods, _MirrorColor.rgb, _MirrorColorThemeIndex), _MirrorColor.a);
				}
				#endif
				#endif
			}
			#endif
			//endex
			
			// normal correct code from https://github.com/yoship1639/UniToon (MIT)
			//ifex _NormalCorrect==0
			#ifdef POI_NORMALCORRECT
			void applyNormalCorrect(inout VertexOut i)
			{
				float3 normalCorrectObject = i.localPos.xyz - _NormalCorrectOrigin;
				normalCorrectObject.y = 0;
				normalCorrectObject = normalize(normalCorrectObject);
				float3 normalCorrectWorld = UnityObjectToWorldDir(normalCorrectObject);
				i.normal.xyz = normalize(lerp(i.normal.xyz, normalCorrectWorld, _NormalCorrectAmount));
				//i.objNormal.xyz = normalize(lerp(i.objNormal.xyz, normalCorrectObject, _NormalCorrectAmount));
			}
			#endif
			//endex
			
			//ifex _VideoEffectsEnable==0
			#ifdef POI_VIDEO_EFFECTS
			float3 applyBacklight(float3 videoTexture, half backlightStrength)
			{
				return max(backlightStrength, videoTexture.rgb);
			}
			
			float3 applyViewAngleTN(float3 videoTexture, PoiCam poiCam, PoiMesh poiMesh)
			{
				float3 reflectionVector = normalize(reflect(poiCam.viewDir.rgb, poiMesh.normals[1].rgb));
				float upwardShift = dot(reflectionVector, poiMesh.binormal[0]);
				upwardShift = pow(upwardShift, 1);
				float sideShift = dot(reflectionVector, poiMesh.tangent[0]);
				sideShift *= pow(sideShift, 3);
				#if !UNITY_COLORSPACE_GAMMA
				videoTexture = LinearToGammaSpace(videoTexture);
				#endif
				videoTexture = saturate(lerp(half3(0.5, 0.5, 0.5), videoTexture, upwardShift + 1));
				#if !UNITY_COLORSPACE_GAMMA
				videoTexture = GammaToLinearSpace(videoTexture);
				#endif
				videoTexture = (lerp(videoTexture, videoTexture.gbr, sideShift));
				return videoTexture;
			}
			
			float calculateCRTPixelBrightness(float2 uv)
			{
				float totalPixels = _VideoResolution.x * _VideoResolution.y;
				float2 uvPixel = float2((floor((1 - uv.y) * _VideoResolution.y)) / _VideoResolution.y, (floor(uv.x * _VideoResolution.x)) / _VideoResolution.x);
				float currentPixelNumber = _VideoResolution.x * (_VideoResolution.y * uvPixel.x) + _VideoResolution.y * uvPixel.y;
				float currentPixelAlpha = currentPixelNumber / totalPixels;
				half electronBeamAlpha = frac(_Time.y * _VideoCRTRefreshRate);
				float electronBeamPixelNumber = totalPixels * electronBeamAlpha;
				
				float DistanceInPixelsFromCurrentElectronBeamPixel = 0;
				if (electronBeamPixelNumber >= currentPixelNumber)
				{
					DistanceInPixelsFromCurrentElectronBeamPixel = electronBeamPixelNumber - currentPixelNumber;
				}
				else
				{
					DistanceInPixelsFromCurrentElectronBeamPixel = electronBeamPixelNumber + (totalPixels - currentPixelNumber);
				}
				float CRTFrameTime = 1 / _VideoCRTRefreshRate;
				float timeSincecurrentPixelWasHitByElectronBeam = (DistanceInPixelsFromCurrentElectronBeamPixel / totalPixels);
				
				return saturate(_VideoCRTPixelEnergizedTime - timeSincecurrentPixelWasHitByElectronBeam);
			}
			
			void applyContrastSettings(inout float3 pixel)
			{
				#if !UNITY_COLORSPACE_GAMMA
				pixel = LinearToGammaSpace(pixel);
				#endif
				pixel = saturate(lerp(half3(0.5, 0.5, 0.5), pixel, _VideoContrast + 1));
				#if !UNITY_COLORSPACE_GAMMA
				pixel = GammaToLinearSpace(pixel);
				#endif
			}
			
			void applySaturationSettings(inout float3 pixel)
			{
				pixel = lerp(pixel.rgb, dot(pixel.rgb, float3(0.3, 0.59, 0.11)), - (_VideoSaturation));
			}
			
			void applyVideoSettings(inout float3 pixel)
			{
				applySaturationSettings(pixel);
				applyContrastSettings(pixel);
			}
			
			void calculateLCD(inout float4 videoTexture, float3 pixels)
			{
				videoTexture.rgb = applyBacklight(videoTexture, _VideoBacklight * .01);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateTN(inout float4 videoTexture, float3 pixels, PoiCam poiCam, PoiMesh poiMesh)
			{
				videoTexture.rgb = applyBacklight(videoTexture, _VideoBacklight * .01);
				videoTexture.rgb = applyViewAngleTN(videoTexture, poiCam, poiMesh);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateCRT(inout float4 videoTexture, float3 pixels, float2 uv)
			{
				float brightness = calculateCRTPixelBrightness(uv);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * brightness * _VideoBacklight;
			}
			void calculateOLED(inout float4 videoTexture, float3 pixels)
			{
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateGameboy(inout float4 videoTexture)
			{
				applyVideoSettings(videoTexture.rgb);
				// half brightness = saturate((videoTexture.r + videoTexture.g + videoTexture.b) * .3333333);
				half brightness = LinearRgbToLuminance(LinearToGammaSpace(videoTexture.rgb));
				#if defined(PROP_VIDEOGAMEBOYRAMP) || !defined(OPTIMIZER_ENABLED)
				videoTexture.rgb = tex2Dlod(_VideoGameboyRamp, float4(brightness.xx, 0, 0));
				#else
				float3 dg = float3(0.00392156863, 0.0392156863, 0.00392156863);
				float3 lg = float3(0.333333333, 0.5, 0.00392156863);
				videoTexture.rgb = lerp(dg, lg, brightness);
				#endif
			}
			void calculateProjector(inout float4 videoTexture)
			{
				applyVideoSettings(videoTexture.rgb);
				
				float3 projectorColor = videoTexture * _VideoBacklight;
				videoTexture.r = clamp(projectorColor.r, videoTexture.r, 1000);
				videoTexture.g = clamp(projectorColor.g, videoTexture.g, 1000);
				videoTexture.b = clamp(projectorColor.b, videoTexture.b, 1000);
			}
			
			void applyVideoEffectsMainTex(inout float4 mainTexture, in PoiMesh poiMesh)
			{
				float2 uvs = poiMesh.uv[_MainTexUV];
				if (_VideoPixelateToResolution)
				{
					float2 originalUVs = uvs;
					uvs = sharpSample(float4(1 / _VideoResolution.xy, _VideoResolution.xy), uvs);
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
					mainTexture = _MainTex.SampleGrad(sampler_MainTex, uvs, ddx(originalUVs), ddy(originalUVs));
				}
			}
			void applyVideoEffects(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, in PoiLight poiLight, in PoiMods poiMods)
			{
				#if defined(PROP_VIDEOPIXELTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float3 pixels = tex2D(_VideoPixelTexture, poiUV(poiMesh.uv[_VideoPixelTextureUV], _VideoPixelTexture_ST) * _VideoResolution);
				#else
				float3 pixels = 1;
				#endif
				float2 uvs = poiMesh.uv[_MainTexUV];
				if (_VideoPixelateToResolution)
				{
					uvs = sharpSample(float4(1 / _VideoResolution.xy, _VideoResolution.xy), uvs);
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
				}
				else
				{
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
				}
				float4 modifiedVideoTexture = 0;
				modifiedVideoTexture.rgb = poiFragData.baseColor;
				modifiedVideoTexture.a = poiFragData.alpha;
				
				// UNITY_BRANCH
				// if(_VideoRepeatVideoTexture == 1)
				// {
				// 	if(poiMesh.uv[_VideoUVNumber].x > 1 || poiMesh.uv[_VideoUVNumber].x < 0 || poiMesh.uv[_VideoUVNumber].y > 1 || poiMesh.uv[_VideoUVNumber].y < 0)
				// 	{
				// 		return;
				// 	}
				// }
				
				switch(_VideoType)
				{
					case 0: // LCD
					
					{
						calculateLCD(modifiedVideoTexture, pixels);
						break;
					}
					case 1: // TN
					
					{
						calculateTN(modifiedVideoTexture, pixels, poiCam, poiMesh);
						break;
					}
					case 2: // CRT
					
					{
						calculateCRT(modifiedVideoTexture, pixels, uvs);
						break;
					}
					case 3: // OLED
					
					{
						calculateOLED(modifiedVideoTexture, pixels);
						break;
					}
					case 4: // Gameboy
					
					{
						calculateGameboy(modifiedVideoTexture);
						break;
					}
					case 5: // Projector
					
					{
						calculateProjector(modifiedVideoTexture);
						break;
					}
				}
				#if defined(PROP_VIDEOMASKTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float screenMask = POI2D_SAMPLER_PAN(_VideoMaskTexture, _MainTex, poiUV(poiMesh.uv[_VideoMaskTextureUV], _VideoMaskTexture_ST), _VideoMaskTexturePan)[_VideoMaskTextureChannel];
				#else
				float screenMask = 1;
				#endif
				
				poiFragData.baseColor = lerp(poiFragData.baseColor, modifiedVideoTexture, screenMask);
				// UNITY_BRANCH
				if (_VideoEmissionEnabled)
				{
					poiFragData.emission += modifiedVideoTexture.rgb * screenMask;
				}
			}
			#endif
			//endex
			
			//ifex _BacklightEnabled!=1
			#ifdef POI_BACKLIGHT
			void ApplyBacklight(inout PoiFragData poiFragData, in PoiMesh poiMesh, inout PoiLight poiLight, in PoiCam poiCam, inout PoiMods poiMods)
			{
				
				// Color
				float3 backlightColor = _BacklightColor.rgb;
				#if defined(PROP_BACKLIGHTCOLORTEX) || !defined(OPTIMIZER_ENABLED)
				backlightColor *= POI2D_SAMPLER_PAN(_BacklightColorTex, _MainTex, poiUV(poiMesh.uv[_BacklightColorTexUV], _BacklightColorTex_ST), _BacklightColorTexPan).rgb;
				#endif
				
				float3 normal = lerp(poiMesh.normals[0], poiMesh.normals[1], _BacklightNormalStrength);
				// Factor
				float3 headDir = normalize(getCameraPosition() - poiMesh.worldPos.xyz);
				float headDotLight = dot(headDir, poiLight.direction);
				float backlightFactor = pow(saturate(-headDotLight * 0.5 + 0.5), max(0, _BacklightDirectivity));
				float backlightLN = dot(normalize(-headDir * _BacklightViewStrength + poiLight.direction), normal) * 0.5 + 0.5;
				#if defined(POINT) || defined(SPOT)
				if (_BacklightReceiveShadow) backlightLN *= saturate(poiLight.additiveShadow);
				#else
				if (_BacklightReceiveShadow) backlightLN *= saturate(poiLight.attenuation);
				#endif
				backlightLN = poiEdgeLinear(backlightLN, _BacklightBorder, _BacklightBlur);
				float backlight = saturate(backlightFactor * backlightLN);
				backlight = !poiMesh.isFrontFace && _BacklightBackfaceMask ? 0.0 : backlight;
				
				// Blend
				backlightColor = lerp(backlightColor, backlightColor * poiFragData.baseColor, _BacklightMainStrength);
				poiLight.finalLightAdd += backlight * backlightColor * poiLight.directColor;
			}
			#endif
			//endex
			
			//ifex _VoronoiEnabled!=1
			#ifdef POI_VORONOI
			//1/7
			#define VoronoiK 0.142857142857
			//3/7
			#define VoronoiKo 0.428571428571
			// Permutation polynomial: (34x^2 + x) mod 289
			float3 Permutation(float3 x)
			{
				return glsl_mod((34.0 * x + 1.0) * x, 289.0);
			}
			
			float3 inoise(float3 P, float jitter, out float3 randomPoint)
			{
				P *= 0.7f; // Scale adjustment
				float3 Pi = glsl_mod(floor(P), 289.0);
				float3 Pf = frac(P);
				float3 oi = float3(-1.0, 0.0, 1.0);
				float3 of = float3(-0.5, 0.5, 1.5);
				float3 px = Permutation(Pi.x + oi);
				float3 py = Permutation(Pi.y + oi);
				float3 pz = Permutation(Pi.z + oi);
				
				float3 p, ox, oy, oz, dx, dy, dz;
				float3 F = 1e6;
				
				[unroll(3)]
				for (int i = 0; i < 3; i++)
				{
					[unroll(3)]
					for (int j = 0; j < 3; j++)
					{
						[unroll(3)]
						for (int k = 0; k < 3; k++)
						{
							p = Permutation(px[i] + py[j] + pz[k] + oi); // pij1, pij2, pij3
							float3 ogp = p;
							
							ox = frac(p * VoronoiK) - VoronoiKo;
							oy = glsl_mod(floor(p * VoronoiK), 7.0) * VoronoiK - VoronoiKo;
							
							p = Permutation(p);
							oz = frac(p * VoronoiK) - VoronoiKo;
							
							dx = Pf.x - of[i] + jitter * ox;
							dy = Pf.y - of[j] + jitter * oy;
							dz = Pf.z - of[k] + jitter * oz;
							
							float3 d = dx * dx + dy * dy + dz * dz; // dij1, dij2 and dij3, squared
							
							//Find lowest and second lowest distances
							for (int n = 0; n < 3; n++)
							{
								if (d[n] < F[0])
								{
									F[1] = F[0];
									F[0] = d[n];
									randomPoint = p;
								}
								else if (d[n] < F[1])
								{
									F[1] = d[n];
								}
							}
						}
					}
				}
				
				return F;
			}
			
			float voronoi2D(in float2 x, float scale, float2 speed, out float2 randomPoint)
			{
				x *= scale;
				x += speed * _Time.x;
				float2 n = floor(x);
				float2 f = frac(x);
				
				// first pass: regular voronoi
				float2 mg, mr;
				float md = 8.0;
				for (int j = -1; j <= 1; j++)
				{
					for (int i = -1; i <= 1; i++)
					{
						float2 g = float2(float(i), float(j));
						float2 o = random2(n + g);
						float2 currentPoint = o;
						
						float2 r = g + o - f;
						float d = dot(r, r);
						
						if (d < md)
						{
							md = d;
							mr = r;
							mg = g;
							randomPoint.xy = currentPoint;
						}
					}
				}
				
				// second pass: distance to borders
				md = 8.0;
				for (int r = -2; r <= 2; r++)
				{
					for (int q = -2; q <= 2; q++)
					{
						float2 g = mg + float2(float(q), float(r));
						float2 o = random2(n + g);
						
						float2 r = g + o - f;
						
						if (dot(mr - r, mr - r) > 0.00001)
						{
							md = min(md, dot(0.5 * (mr + r), normalize(r - mr)));
						}
					}
				}
				return md;
			}
			
			float voronoi3D(in float3 x, float scale, float3 speed, out float3 randomPoint)
			{
				x *= scale;
				x += speed * _Time.x;
				float3 n = floor(x);
				float3 f = frac(x);
				
				// first pass: regular voronoi
				float3 mg, mr;
				float md = 8.0;
				for (int j = -1; j <= 1; j++)
				{
					for (int i = -1; i <= 1; i++)
					{
						for (int h = -1; h <= 1; h++)
						{
							float3 g = float3(float(h), float(i), float(j));
							float3 o = random3(n + g);
							float3 currentPoint = o;
							
							float3 r = g + o - f;
							float d = dot(r, r);
							
							if (d < md)
							{
								md = d;
								mr = r;
								mg = g;
								randomPoint = currentPoint;
							}
						}
					}
				}
				
				// second pass: distance to borders
				md = 8.0;
				for (int r = -2; r <= 2; r++)
				{
					for (int q = -2; q <= 2; q++)
					{
						for (int p = -2; p <= 2; p++)
						{
							float3 g = mg + float3(float(p), float(q), float(r));
							float3 o = random3(n + g);
							
							float3 r = g + o - f;
							
							if (dot(mr - r, mr - r) > 0.00001)
							{
								md = min(md, dot(0.5 * (mr + r), normalize(r - mr)));
							}
						}
					}
				}
				return md;
			}
			
			// fracal sum, range -1.0 - 1.0
			float VoronoiNoise_Octaves(float3 p, float scale, float3 speed, int octaveNumber, float octaveScale, float octaveAttenuation, float jitter, float time, out float3 randomPoint)
			{
				float freq = scale;
				float weight = 1.0f;
				float sum = 0;
				// Uncomment when the octave stuff is actually used
				// for (int i = 0; i < octaveNumber; i ++)
				// {
				float3 F = inoise(p * freq + time * speed, jitter, randomPoint) * weight;
				
				sum += sqrt(F[0]);
				
				// 	freq *= octaveScale;
				// 	weight *= 1.0f - octaveAttenuation;
				// }
				return sum;
			}
			
			float VoronoiNoiseDiff_Octaves(float3 p, float scale, float3 speed, int octaveNumber, float octaveScale, float octaveAttenuation, float jitter, float time, out float3 randomPoint)
			{
				float freq = scale;
				float weight = 1.0f;
				float sum = 0;
				// Uncomment when the octave stuff is actually used
				// for (int i = 0; i < octaveNumber; i ++)
				// {
				float3 F = inoise(p * freq + time * speed, jitter, randomPoint) * weight;
				
				sum += sqrt(F[1]) - sqrt(F[0]);
				
				// freq *= octaveScale;
				// weight *= 1.0f - octaveAttenuation;
				// }
				return sum;
			}
			
			void ApplyVoronoi(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float voronoiOctaveNumber = 1;
				float voronoiOctaveScale = 1;
				float voronoiOctaveAttenuation = 1;
				float3 randomPoint = 0;
				
				float voronoi = 0;
				
				float3 position = 0;
				
				UNITY_BRANCH
				if (_VoronoiSpace == 0)
				{
					position = poiMesh.localPos;
				}
				UNITY_BRANCH
				if (_VoronoiSpace == 1)
				{
					position = poiMesh.worldPos;
				}
				UNITY_BRANCH
				if (_VoronoiSpace == 2)
				{
					position = float3(poiMesh.uv[0].x, poiMesh.uv[0].y, 0);
				}
				#if defined(PROP_VORONOIMASK) || !defined(OPTIMIZER_ENABLED)
				float mask = POI2D_SAMPLER_PAN(_VoronoiMask, _MainTex, poiUV(poiMesh.uv[_VoronoiMaskUV], _VoronoiMask_ST), _VoronoiMaskPan)[_VoronoiMaskChannel];
				#else
				float mask = 1;
				#endif
				
				if (_VoronoiGlobalMask > 0)
				{
					mask = maskBlend(mask, poiMods.globalMask[_VoronoiGlobalMask - 1], _VoronoiGlobalMaskBlendType);
				}
				
				#if defined(PROP_VORONOINOISE) || !defined(OPTIMIZER_ENABLED)
				float edgeNoise = POI2D_SAMPLER_PAN(_VoronoiNoise, _MainTex, poiUV(poiMesh.uv[_VoronoiNoiseUV], _VoronoiNoise_ST), _VoronoiNoisePan)[_VoronoiNoiseChannel];
				#else
				float edgeNoise = 0;
				#endif
				edgeNoise *= _VoronoiNoiseIntensity;
				
				float3 voronoiSpeed = _VoronoiSpeed * 10;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					position.x += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedXType, _AudioLinkVoronoiChronoSpeedXBand) * _AudioLinkVoronoiChronoSpeedXSpeed * 0.01;
					position.y += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedYType, _AudioLinkVoronoiChronoSpeedYBand) * _AudioLinkVoronoiChronoSpeedYSpeed * 0.01;
					position.z += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedZType, _AudioLinkVoronoiChronoSpeedZBand) * _AudioLinkVoronoiChronoSpeedZSpeed * 0.01;
				}
				#endif
				
				if (_VoronoiType == 0) // Basic
				
				{
					voronoi = voronoi2D(position.xy, _VoronoiScale, voronoiSpeed, randomPoint.xy);
					voronoi *= 1.55; // Range adjustment
					
				}
				if (_VoronoiType == 1) // Diff
				
				{
					voronoi = VoronoiNoiseDiff_Octaves(position, _VoronoiScale, voronoiSpeed, voronoiOctaveNumber, voronoiOctaveScale, voronoiOctaveAttenuation, 1, _Time.x, randomPoint);
				}
				if (_VoronoiType == 2) // Fixed Border
				
				{
					voronoi = voronoi3D(position, _VoronoiScale, voronoiSpeed, randomPoint);
					voronoi *= 1.8; // Range adjustment
					
				}
				
				float4 outerColor = _VoronoiOuterColor;
				float4 innerColor = _VoronoiInnerColor;
				
				if (_VoronoiEnableRandomCellColor == 1)
				{
					float3 rando = random3(randomPoint);
					fixed hue = rando.x;
					fixed saturation = lerp(_VoronoiRandomMinMaxSaturation.x, _VoronoiRandomMinMaxSaturation.y, rando.y);
					fixed value = lerp(_VoronoiRandomMinMaxBrightness.x, _VoronoiRandomMinMaxBrightness.y, rando.z);
					float3 hsv = float3(hue, saturation, value);
					innerColor.rgb = HSVtoRGB(hsv);
				}
				voronoi = pow(voronoi, _VoronoiPower);
				float2 voronoiGradient = _VoronoiGradient.xy + edgeNoise;
				#ifdef POI_AUDIOLINK
				voronoiGradient.x += _AudioLinkVoronoiGradientMinAdd * poiMods.audioLink[_AudioLinkVoronoiGradientMinAddBand];
				voronoiGradient.y -= _AudioLinkVoronoiGradientMaxAdd * poiMods.audioLink[_AudioLinkVoronoiGradientMaxAddBand];
				#endif
				float ramp = smoothstep(voronoiGradient.x, voronoiGradient.y, voronoi);
				
				if (_VoronoiBlend == 0)
				{
					float4 voronoiColor = lerp(outerColor, innerColor, ramp);
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, voronoiColor, min(mask * voronoiColor.a, 0.99999));
					if (_VoronoiAffectsMaterialAlpha)
					{
						poiFragData.alpha = lerp(poiFragData.alpha, voronoiColor.a, min(mask, 0.99999));
					}
				}
				float outerEmissionStrength = _VoronoiOuterEmissionStrength;
				float innerEmissionStrength = _VoronoiInnerEmissionStrength;
				#ifdef POI_AUDIOLINK
				outerEmissionStrength += lerp(_AudioLinkVoronoiOuterEmission.x, _AudioLinkVoronoiOuterEmission.y, poiMods.audioLink[_AudioLinkVoronoiOuterEmissionBand]);
				innerEmissionStrength += lerp(_AudioLinkVoronoiInnerEmission.x, _AudioLinkVoronoiInnerEmission.y, poiMods.audioLink[_AudioLinkVoronoiInnerEmissionBand]);
				#endif
				float4 voronoiEmissionColor = lerp(outerColor, innerColor, ramp);
				voronoiEmissionColor.rgb *= lerp(outerEmissionStrength, innerEmissionStrength, ramp);
				poiFragData.emission += voronoiEmissionColor.rgb * mask * voronoiEmissionColor.a;
			}
			#endif
			//endex
			
			float4 frag(VertexOut i, uint facing : SV_IsFrontFace) : SV_Target
			{
				UNITY_SETUP_INSTANCE_ID(i);
				UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
				
				PoiMesh poiMesh;
				PoiInitStruct(PoiMesh, poiMesh);
				
				PoiLight poiLight;
				PoiInitStruct(PoiLight, poiLight);
				
				PoiVertexLights poiVertexLights;
				PoiInitStruct(PoiVertexLights, poiVertexLights);
				
				PoiCam poiCam;
				PoiInitStruct(PoiCam, poiCam);
				
				PoiMods poiMods;
				PoiInitStruct(PoiMods, poiMods);
				poiMods.globalEmission = 1;
				
				PoiFragData poiFragData;
				poiFragData.smoothness = 1;
				poiFragData.smoothness2 = 1;
				poiFragData.metallic = 1;
				poiFragData.specularMask = 1;
				poiFragData.reflectionMask = 1;
				poiFragData.emission = 0;
				poiFragData.baseColor = float3(0, 0, 0);
				poiFragData.finalColor = float3(0, 0, 0);
				poiFragData.alpha = 1;
				poiFragData.toggleVertexLights = 0;
				
				#ifdef POI_UDIMDISCARD
				applyUDIMDiscard(i);
				#endif
				
				//ifex _NormalCorrect==0
				#ifdef POI_NORMALCORRECT
				applyNormalCorrect(i);
				#endif
				//endex
				
				// Mesh Data
				//poiMesh.objectPosition = mul(unity_ObjectToWorld, float3(0, 0, 0)).xyz;
				poiMesh.objectPosition = mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
				poiMesh.objNormal = mul(unity_WorldToObject, i.normal);
				poiMesh.normals[0] = i.normal;
				poiMesh.tangent[0] = i.tangent.xyz;
				poiMesh.binormal[0] = cross(i.normal, i.tangent.xyz) * (i.tangent.w * unity_WorldTransformParams.w);
				poiMesh.worldPos = i.worldPos.xyz;
				poiMesh.localPos = i.localPos.xyz;
				poiMesh.vertexColor = i.vertexColor;
				poiMesh.isFrontFace = facing;
				poiMesh.dx = ddx(poiMesh.uv[0]);
				poiMesh.dy = ddy(poiMesh.uv[0]);
				
				#ifndef POI_PASS_OUTLINE
				if (!poiMesh.isFrontFace && _FlipBackfaceNormals)
				{
					poiMesh.normals[0] *= -1;
					poiMesh.tangent[0] *= -1;
					poiMesh.binormal[0] *= -1;
				}
				#endif
				
				poiCam.viewDir = !IsOrthographicCamera() ? normalize(_WorldSpaceCameraPos - i.worldPos.xyz) : normalize(UNITY_MATRIX_I_V._m02_m12_m22);
				float3 tanToWorld0 = float3(poiMesh.tangent[0].x, poiMesh.binormal[0].x, poiMesh.normals[0].x);
				float3 tanToWorld1 = float3(poiMesh.tangent[0].y, poiMesh.binormal[0].y, poiMesh.normals[0].y);
				float3 tanToWorld2 = float3(poiMesh.tangent[0].z, poiMesh.binormal[0].z, poiMesh.normals[0].z);
				float3 ase_tanViewDir = tanToWorld0 * poiCam.viewDir.x + tanToWorld1 * poiCam.viewDir.y + tanToWorld2 * poiCam.viewDir.z;
				poiCam.tangentViewDir = normalize(ase_tanViewDir);
				
				// 0-3 UV0-UV3
				// 4 Panosphere UV
				// 5 world pos xz
				// 6 Polar UV
				// 6 Distorted UV
				#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
				poiMesh.lightmapUV = i.lightmapUV;
				#endif
				poiMesh.parallaxUV = poiCam.tangentViewDir.xy / max(poiCam.tangentViewDir.z, 0.0001);
				poiMesh.uv[0] = i.uv[0].xy;
				poiMesh.uv[1] = i.uv[0].zw;
				poiMesh.uv[2] = i.uv[1].xy;
				poiMesh.uv[3] = i.uv[1].zw;
				poiMesh.uv[4] = poiMesh.uv[0];
				poiMesh.uv[5] = poiMesh.uv[0];
				poiMesh.uv[6] = poiMesh.uv[0];
				poiMesh.uv[7] = poiMesh.uv[0];
				poiMesh.uv[8] = poiMesh.uv[0];
				
				poiMesh.uv[4] = calculatePanosphereUV(poiMesh);
				poiMesh.uv[5] = calculateWorldUV(poiMesh);
				poiMesh.uv[6] = calculatePolarCoordinate(poiMesh);
				poiMesh.uv[8] = calculatelocalUV(poiMesh);
				//ifex _EnableDistortion==0
				#ifdef USER_LUT
				poiMesh.uv[7] = distortedUV(poiMesh);
				#endif
				//endex
				/*
				half3 worldViewUp = normalize(half3(0, 1, 0) - poiCam.viewDir * dot(poiCam.viewDir, half3(0, 1, 0)));
				half3 worldViewRight = normalize(cross(poiCam.viewDir, worldViewUp));
				poiMesh[8] = half2(dot(worldViewRight, poiMesh.normals[_MatcapNormal]), dot(worldViewUp, poiMesh.normals[_MatcapNormal])) * _MatcapBorder + 0.5;
				*/
				
				//ifex _PoiParallax==0
				#ifdef POI_PARALLAX
				#ifndef POI_PASS_OUTLINE
				//return frac(i.tangentViewDir.x);
				//return float4(i.binormal.xyz,1);
				applyParallax(poiMesh, poiLight, poiCam);
				#endif
				#endif
				//endex
				
				poiMods.globalMask[0] = 1;
				poiMods.globalMask[1] = 1;
				poiMods.globalMask[2] = 1;
				poiMods.globalMask[3] = 1;
				poiMods.globalMask[4] = 1;
				poiMods.globalMask[5] = 1;
				poiMods.globalMask[6] = 1;
				poiMods.globalMask[7] = 1;
				poiMods.globalMask[8] = 1;
				poiMods.globalMask[9] = 1;
				poiMods.globalMask[10] = 1;
				poiMods.globalMask[11] = 1;
				poiMods.globalMask[12] = 1;
				poiMods.globalMask[13] = 1;
				poiMods.globalMask[14] = 1;
				poiMods.globalMask[15] = 1;
				//ifex _GlobalMaskTexturesEnable==0
				#ifdef POI_GLOBALMASK_TEXTURES
				ApplyGlobalMaskTextures(poiMesh, poiMods);
				#endif
				//endex
				//ifex _GlobalMaskVertexColorRed==0 && _GlobalMaskVertexColorGreen==0 && _GlobalMaskVertexColorBlue==0 && _GlobalMaskVertexColorAlpha==0
				ApplyGlobalMaskVertexColors(poiMesh, poiMods);
				//endex
				ApplyGlobalMaskModifiers(poiMesh, poiMods, poiCam);
				//ifex _GlobalMaskOptionsEnable==0
				if (_GlobalMaskOptionsEnable)
				{
					ApplyGlobalMaskOptions(poiMods);
				}
				//endex
				
				float2 mainUV = poiUV(poiMesh.uv[_MainTexUV].xy, _MainTex_ST);
				
				if (_MainPixelMode)
				{
					mainUV = sharpSample(_MainTex_TexelSize, mainUV);
				}
				
				float4 mainTexture = POI2D_SAMPLER_PAN_STOCHASTIC(_MainTex, _MainTex, mainUV, _MainTexPan, _MainTexStochastic);
				
				//ifex _VideoEffectsEnable==0
				#ifdef POI_VIDEO_EFFECTS
				if (_VideoEffectsEnable)
				{
					applyVideoEffectsMainTex(mainTexture, poiMesh);
				}
				#endif
				//endex
				
				#if defined(PROP_BUMPMAP) || !defined(OPTIMIZER_ENABLED)
				poiMesh.tangentSpaceNormal = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_BumpMap, _MainTex, poiUV(poiMesh.uv[_BumpMapUV].xy, _BumpMap_ST), _BumpMapPan, _BumpMapStochastic), _BumpScale);
				#else
				poiMesh.tangentSpaceNormal = UnpackNormal(float4(0.5, 0.5, 1, 1));
				#endif
				
				//ifex _DetailEnabled==0
				#if defined(FINALPASS) && !defined(UNITY_PASS_SHADOWCASTER) && !defined(POI_PASS_OUTLINE)
				ApplyDetailNormal(poiMods, poiMesh);
				#endif
				//endex
				
				//ifex _RGBMaskEnabled==0
				#if defined(VIGNETTE) && !defined(UNITY_PASS_SHADOWCASTER) && !defined(POI_PASS_OUTLINE)
				calculateRGBNormals(poiMesh, poiMods);
				#endif
				
				//endex
				
				float3 tangentSpaceNormal = UnpackNormal(float4(0.5, 0.5, 1, 1));
				poiMesh.normals[0] = normalize(
				tangentSpaceNormal.x * poiMesh.tangent[0] +
				tangentSpaceNormal.y * poiMesh.binormal[0] +
				tangentSpaceNormal.z * poiMesh.normals[0]
				);
				
				poiMesh.normals[1] = normalize(
				poiMesh.tangentSpaceNormal.x * poiMesh.tangent[0] +
				poiMesh.tangentSpaceNormal.y * poiMesh.binormal[0] +
				poiMesh.tangentSpaceNormal.z * poiMesh.normals[0]
				);
				
				poiMesh.tangent[1] = cross(poiMesh.binormal[0], -poiMesh.normals[1]);
				poiMesh.binormal[1] = cross(-poiMesh.normals[1], poiMesh.tangent[0]);
				
				//ifex _EnableOutlines!=1
				#ifdef POI_PASS_OUTLINE
				poiMesh.normals[1] = poiMesh.normals[0];
				#endif
				//endex
				
				// Camera data
				poiCam.forwardDir = getCameraForward();
				poiCam.worldPos = _WorldSpaceCameraPos;
				poiCam.reflectionDir = reflect(-poiCam.viewDir, poiMesh.normals[1]);
				poiCam.vertexReflectionDir = reflect(-poiCam.viewDir, poiMesh.normals[0]);
				//poiCam.distanceToModel = distance(poiMesh.modelPos, poiCam.worldPos);
				poiCam.clipPos = i.pos;
				poiCam.distanceToVert = distance(poiMesh.worldPos, poiCam.worldPos);
				poiCam.posScreenSpace = poiTransformClipSpacetoScreenSpaceFrag(poiCam.clipPos);
				#if defined(POI_GRABPASS) && defined(POI_PASS_BASE)
				poiCam.screenUV = poiCam.clipPos.xy / poiGetWidthAndHeight(_PoiGrab2);
				#else
				poiCam.screenUV = poiCam.clipPos.xy / _ScreenParams.xy;
				#endif
				#ifdef UNITY_SINGLE_PASS_STEREO
				poiCam.posScreenSpace.x = poiCam.posScreenSpace.x * 0.5;
				#endif
				poiCam.posScreenPixels = calcPixelScreenUVs(poiCam.posScreenSpace);
				poiCam.vDotN = abs(dot(poiCam.viewDir, poiMesh.normals[1]));
				
				poiCam.worldDirection.xyz = poiMesh.worldPos.xyz - poiCam.worldPos;
				poiCam.worldDirection.w = dot(poiCam.clipPos, CalculateFrustumCorrection());
				
				calculateGlobalThemes(poiMods);
				
				poiLight.finalLightAdd = 0;
				
				// Ambient Occlusion
				#if defined(PROP_LIGHTINGAOMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 AOMaps = POI2D_SAMPLER_PAN(_LightingAOMaps, _MainTex, poiUV(poiMesh.uv[_LightingAOMapsUV], _LightingAOMaps_ST), _LightingAOMapsPan);
				poiLight.occlusion = min(min(min(lerp(1, AOMaps.r, _LightDataAOStrengthR), lerp(1, AOMaps.g, _LightDataAOStrengthG)), lerp(1, AOMaps.b, _LightDataAOStrengthB)), lerp(1, AOMaps.a, _LightDataAOStrengthA));
				#else
				poiLight.occlusion = 1;
				#endif
				
				if (_LightDataAOGlobalMaskR > 0)
				{
					poiLight.occlusion = maskBlend(poiLight.occlusion, poiMods.globalMask[_LightDataAOGlobalMaskR - 1], _LightDataAOGlobalMaskBlendTypeR);
				}
				
				// Detail Shadows
				#if defined(PROP_LIGHTINGDETAILSHADOWMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 DetailShadows = POI2D_SAMPLER_PAN(_LightingDetailShadowMaps, _MainTex, poiUV(poiMesh.uv[_LightingDetailShadowMapsUV], _LightingDetailShadowMaps_ST), _LightingDetailShadowMapsPan);
				#ifndef POI_PASS_ADD
				poiLight.detailShadow = lerp(1, DetailShadows.r, _LightingDetailShadowStrengthR) * lerp(1, DetailShadows.g, _LightingDetailShadowStrengthG) * lerp(1, DetailShadows.b, _LightingDetailShadowStrengthB) * lerp(1, DetailShadows.a, _LightingDetailShadowStrengthA);
				#else
				poiLight.detailShadow = lerp(1, DetailShadows.r, _LightingAddDetailShadowStrengthR) * lerp(1, DetailShadows.g, _LightingAddDetailShadowStrengthG) * lerp(1, DetailShadows.b, _LightingAddDetailShadowStrengthB) * lerp(1, DetailShadows.a, _LightingAddDetailShadowStrengthA);
				#endif
				#else
				poiLight.detailShadow = 1;
				#endif
				
				if (_LightDataDetailShadowGlobalMaskR > 0)
				{
					poiLight.detailShadow = maskBlend(poiLight.detailShadow, poiMods.globalMask[_LightDataDetailShadowGlobalMaskR - 1], _LightDataDetailShadowGlobalMaskBlendTypeR);
				}
				
				// Shadow Masks
				#if defined(PROP_LIGHTINGSHADOWMASKS) || !defined(OPTIMIZER_ENABLED)
				float4 ShadowMasks = POI2D_SAMPLER_PAN(_LightingShadowMasks, _MainTex, poiUV(poiMesh.uv[_LightingShadowMasksUV], _LightingShadowMasks_ST), _LightingShadowMasksPan);
				poiLight.shadowMask = lerp(1, ShadowMasks.r, _LightingShadowMaskStrengthR) * lerp(1, ShadowMasks.g, _LightingShadowMaskStrengthG) * lerp(1, ShadowMasks.b, _LightingShadowMaskStrengthB) * lerp(1, ShadowMasks.a, _LightingShadowMaskStrengthA);
				#else
				poiLight.shadowMask = 1;
				#endif
				if (_LightDataShadowMaskGlobalMaskR > 0)
				{
					poiLight.shadowMask = maskBlend(poiLight.shadowMask, poiMods.globalMask[_LightDataShadowMaskGlobalMaskR - 1], _LightDataShadowMaskGlobalMaskBlendTypeR);
				}
				
				#ifdef UNITY_PASS_FORWARDBASE
				
				bool lightExists = false;
				if (any(_LightColor0.rgb >= 0.002))
				{
					lightExists = true;
				}
				
				if (_LightingVertexLightingEnabled)
				{
					poiFragData.toggleVertexLights = 1;
				}
				if (IsInMirror() && _LightingMirrorVertexLightingEnabled == 0)
				{
					poiFragData.toggleVertexLights = 0;
				}
				
				if (_LightingVertexLightingEnabled)
				{
					#if defined(VERTEXLIGHT_ON)
					float4 toLightX = unity_4LightPosX0 - i.worldPos.x;
					float4 toLightY = unity_4LightPosY0 - i.worldPos.y;
					float4 toLightZ = unity_4LightPosZ0 - i.worldPos.z;
					float4 lengthSq = 0;
					lengthSq += toLightX * toLightX;
					lengthSq += toLightY * toLightY;
					lengthSq += toLightZ * toLightZ;
					
					float4 lightAttenSq = unity_4LightAtten0;
					float4 atten = 1.0 / (1.0 + lengthSq * lightAttenSq);
					float4 vLightWeight = saturate(1 - (lengthSq * lightAttenSq / 25));
					poiLight.vAttenuation = min(atten, vLightWeight * vLightWeight);
					
					poiLight.vDotNL = 0;
					poiLight.vDotNL += toLightX * poiMesh.normals[1].x;
					poiLight.vDotNL += toLightY * poiMesh.normals[1].y;
					poiLight.vDotNL += toLightZ * poiMesh.normals[1].z;
					
					float4 corr = rsqrt(lengthSq);
					poiLight.vertexVDotNL = max(0, poiLight.vDotNL * corr);
					
					poiLight.vertexVDotNL = 0;
					poiLight.vertexVDotNL += toLightX * poiMesh.normals[0].x;
					poiLight.vertexVDotNL += toLightY * poiMesh.normals[0].y;
					poiLight.vertexVDotNL += toLightZ * poiMesh.normals[0].z;
					
					poiLight.vertexVDotNL = max(0, poiLight.vDotNL * corr);
					
					poiLight.vSaturatedDotNL = saturate(poiLight.vDotNL);
					
					[unroll]
					for (int index = 0; index < 4; index++)
					{
						poiLight.vPosition[index] = float3(unity_4LightPosX0[index], unity_4LightPosY0[index], unity_4LightPosZ0[index]);
						
						float3 vertexToLightSource = poiLight.vPosition[index] - poiMesh.worldPos;
						poiLight.vDirection[index] = normalize(vertexToLightSource);
						poiLight.vColor[index] = _LightingAdditiveLimited ? MaxLuminance(unity_LightColor[index].rgb * poiLight.vAttenuation[index], _LightingAdditiveLimit) : unity_LightColor[index].rgb * poiLight.vAttenuation[index];
						poiLight.vColor[index] = lerp(poiLight.vColor[index], dot(poiLight.vColor[index], float3(0.299, 0.587, 0.114)), _LightingAdditiveMonochromatic);
						poiLight.vHalfDir[index] = Unity_SafeNormalize(poiLight.vDirection[index] + poiCam.viewDir);
						poiLight.vDotNL[index] = dot(poiMesh.normals[1], poiLight.vDirection[index]);
						poiLight.vCorrectedDotNL[index] = .5 * (poiLight.vDotNL[index] + 1);
						poiLight.vDotLH[index] = saturate(dot(poiLight.vDirection[index], poiLight.vHalfDir[index]));
						
						poiLight.vDotNH[index] = dot(poiMesh.normals[1], poiLight.vHalfDir[index]);
						poiLight.vertexVDotNH[index] = saturate(dot(poiMesh.normals[0], poiLight.vHalfDir[index]));
					}
					#endif
				}
				
				//UNITY_BRANCH
				if (_LightingColorMode == 0) // Poi Custom Light Color
				
				{
					float3 magic = max(BetterSH9(normalize(unity_SHAr + unity_SHAg + unity_SHAb)), 0);
					float3 normalLight = _LightColor0.rgb + BetterSH9(float4(0, 0, 0, 1));
					
					float magiLumi = calculateluminance(magic);
					float normaLumi = calculateluminance(normalLight);
					float maginormalumi = magiLumi + normaLumi;
					
					float magiratio = magiLumi / maginormalumi;
					float normaRatio = normaLumi / maginormalumi;
					
					float target = calculateluminance(magic * magiratio + normalLight * normaRatio);
					float3 properLightColor = magic + normalLight;
					float properLuminance = calculateluminance(magic + normalLight);
					poiLight.directColor = properLightColor * max(0.0001, (target / properLuminance));
					
					poiLight.indirectColor = BetterSH9(float4(lerp(0, poiMesh.normals[1], _LightingIndirectUsesNormals), 1));
				}
				
				//UNITY_BRANCH
				if (_LightingColorMode == 1) // More standard approach to light color
				
				{
					float3 indirectColor = BetterSH9(float4(poiMesh.normals[1], 1));
					if (lightExists)
					{
						poiLight.directColor = _LightColor0.rgb;
						poiLight.indirectColor = indirectColor;
					}
					else
					{
						poiLight.directColor = indirectColor * 0.6;
						poiLight.indirectColor = indirectColor * 0.5;
					}
				}
				
				if (_LightingColorMode == 2) // UTS style
				
				{
					poiLight.indirectColor = saturate(max(half3(0.05, 0.05, 0.05) * _Unlit_Intensity, max(ShadeSH9(half4(0.0, 0.0, 0.0, 1.0)), ShadeSH9(half4(0.0, -1.0, 0.0, 1.0)).rgb) * _Unlit_Intensity));
					poiLight.directColor = max(poiLight.indirectColor, _LightColor0.rgb);
				}
				
				if (_LightingColorMode == 3) // OpenLit
				
				{
					float3 lightDirectionForSH9 = OpenLitLightingDirectionForSH9();
					OpenLitShadeSH9ToonDouble(lightDirectionForSH9, poiLight.directColor, poiLight.indirectColor);
					poiLight.directColor += _LightColor0.rgb;
					// OpenLit does a few other things by default like clamp direct colour
					// see https://github.com/lilxyzw/OpenLit/blob/main/Assets/OpenLit/core.hlsl#L174
				}
				
				float lightMapMode = _LightingMapMode;
				//UNITY_BRANCH
				if (_LightingDirectionMode == 0)
				{
					poiLight.direction = _WorldSpaceLightPos0.xyz + unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz;
				}
				if (_LightingDirectionMode == 1 || _LightingDirectionMode == 2)
				{
					//UNITY_BRANCH
					if (_LightingDirectionMode == 1)
					{
						poiLight.direction = mul(unity_ObjectToWorld, _LightngForcedDirection).xyz;;
					}
					//UNITY_BRANCH
					if (_LightingDirectionMode == 2)
					{
						poiLight.direction = _LightngForcedDirection;
					}
					if (lightMapMode == 0)
					{
						lightMapMode == 1;
					}
				}
				
				if (_LightingDirectionMode == 3) // UTS
				
				{
					float3 defaultLightDirection = normalize(UNITY_MATRIX_V[2].xyz + UNITY_MATRIX_V[1].xyz);
					float3 lightDirection = normalize(lerp(defaultLightDirection, _WorldSpaceLightPos0.xyz, any(_WorldSpaceLightPos0.xyz)));
					poiLight.direction = lightDirection;
				}
				if (_LightingDirectionMode == 4) // OpenLit
				
				{
					poiLight.direction = OpenLitLightingDirection(); // float4 customDir = 0; // Do we want to give users to alter this (OpenLit always does!)?
					
				}
				
				if (_LightingDirectionMode == 5) // View Direction
				
				{
					float3 upViewDir = normalize(UNITY_MATRIX_V[1].xyz);
					float3 rightViewDir = normalize(UNITY_MATRIX_V[0].xyz);
					float yawOffset_Rads = radians(!IsInMirror() ? - _LightingViewDirOffsetYaw : _LightingViewDirOffsetYaw);
					float3 rotatedViewYaw = normalize(RotateAroundAxis(rightViewDir, upViewDir, yawOffset_Rads));
					float3 rotatedViewCameraMeshOffset = RotateAroundAxis((getCameraPosition() - (poiMesh.worldPos)), upViewDir, yawOffset_Rads);
					float pitchOffset_Rads = radians(!IsInMirror() ? _LightingViewDirOffsetPitch : - _LightingViewDirOffsetPitch);
					float3 rotatedViewPitch = RotateAroundAxis(rotatedViewCameraMeshOffset, rotatedViewYaw, pitchOffset_Rads);
					poiLight.direction = normalize(rotatedViewPitch);
				}
				
				if (!any(poiLight.direction))
				{
					poiLight.direction = float3(.4, 1, .4);
				}
				
				poiLight.direction = normalize(poiLight.direction);
				poiLight.attenuationStrength = _LightingCastedShadows;
				poiLight.attenuation = 1;
				if (!all(_LightColor0.rgb == 0.0))
				{
					UNITY_LIGHT_ATTENUATION(attenuation, i, poiMesh.worldPos)
					poiLight.attenuation *= attenuation;
				}
				
				if (!any(poiLight.directColor) && !any(poiLight.indirectColor) && lightMapMode == 0)
				{
					lightMapMode = 1;
					if (_LightingDirectionMode == 0)
					{
						poiLight.direction = normalize(float3(.4, 1, .4));
					}
				}
				
				poiLight.halfDir = normalize(poiLight.direction + poiCam.viewDir);
				poiLight.vertexNDotL = dot(poiMesh.normals[0], poiLight.direction);
				poiLight.nDotL = dot(poiMesh.normals[1], poiLight.direction);
				poiLight.nDotLSaturated = saturate(poiLight.nDotL);
				poiLight.nDotLNormalized = (poiLight.nDotL + 1) * 0.5;
				poiLight.nDotV = abs(dot(poiMesh.normals[1], poiCam.viewDir));
				poiLight.vertexNDotV = abs(dot(poiMesh.normals[0], poiCam.viewDir));
				poiLight.nDotH = dot(poiMesh.normals[1], poiLight.halfDir);
				poiLight.vertexNDotH = max(0.00001, dot(poiMesh.normals[0], poiLight.halfDir));
				poiLight.lDotv = dot(poiLight.direction, poiCam.viewDir);
				poiLight.lDotH = max(0.00001, dot(poiLight.direction, poiLight.halfDir));
				
				// Poi special light map
				if (lightMapMode == 0)
				{
					float3 ShadeSH9Plus = GetSHLength();
					float3 ShadeSH9Minus = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) + float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0;
					
					float3 greyScaleVector = float3(.33333, .33333, .33333);
					float bw_lightColor = dot(poiLight.directColor, greyScaleVector);
					float bw_directLighting = (((poiLight.nDotL * 0.5 + 0.5) * bw_lightColor * lerp(1, poiLight.attenuation, poiLight.attenuationStrength)) + dot(ShadeSH9(float4(poiMesh.normals[1], 1)), greyScaleVector));
					float bw_directLightingNoAtten = (((poiLight.nDotL * 0.5 + 0.5) * bw_lightColor) + dot(ShadeSH9(float4(poiMesh.normals[1], 1)), greyScaleVector));
					float bw_bottomIndirectLighting = dot(ShadeSH9Minus, greyScaleVector);
					float bw_topIndirectLighting = dot(ShadeSH9Plus, greyScaleVector);
					float lightDifference = ((bw_topIndirectLighting + bw_lightColor) - bw_bottomIndirectLighting);
					
					poiLight.lightMap = smoothstep(0, lightDifference, bw_directLighting - bw_bottomIndirectLighting);
					poiLight.lightMapNoAttenuation = smoothstep(0, lightDifference, bw_directLightingNoAtten - bw_bottomIndirectLighting);
				}
				// Normalized nDotL
				if (lightMapMode == 1)
				{
					poiLight.lightMapNoAttenuation = poiLight.nDotLNormalized;
					poiLight.lightMap = poiLight.nDotLNormalized * lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				}
				// Saturated nDotL
				if (lightMapMode == 2)
				{
					poiLight.lightMapNoAttenuation = poiLight.nDotLSaturated;
					poiLight.lightMap = poiLight.nDotLSaturated * lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				}
				if (lightMapMode == 3)
				{
					poiLight.lightMapNoAttenuation = 1;
					poiLight.lightMap = lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				}
				poiLight.lightMapNoAttenuation *= poiLight.detailShadow;
				poiLight.lightMap *= poiLight.detailShadow;
				
				poiLight.directColor = max(poiLight.directColor, 0.0001);
				poiLight.indirectColor = max(poiLight.indirectColor, 0.0001);
				
				if (_LightingColorMode == 3)
				{
					// OpenLit
					poiLight.directColor = max(poiLight.directColor, _LightingMinLightBrightness);
				}
				else
				{
					poiLight.directColor = max(poiLight.directColor, poiLight.directColor * min(10000, (_LightingMinLightBrightness * rcp(calculateluminance(poiLight.directColor)))));
					poiLight.indirectColor = max(poiLight.indirectColor, poiLight.indirectColor * min(10000, (_LightingMinLightBrightness * rcp(calculateluminance(poiLight.indirectColor)))));
				}
				
				poiLight.directColor = lerp(poiLight.directColor, dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic);
				poiLight.indirectColor = lerp(poiLight.indirectColor, dot(poiLight.indirectColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic);
				
				if (_LightingCapEnabled)
				{
					poiLight.directColor = min(poiLight.directColor, _LightingCap);
					poiLight.indirectColor = min(poiLight.indirectColor, _LightingCap);
				}
				
				if (_LightingForceColorEnabled)
				{
					poiLight.directColor = poiThemeColor(poiMods, _LightingForcedColor, _LightingForcedColorThemeIndex);
				}
				
				#ifdef UNITY_PASS_FORWARDBASE
				poiLight.directColor = max(poiLight.directColor * _PPLightingMultiplier, 0);
				poiLight.directColor = max(poiLight.directColor + _PPLightingAddition, 0);
				poiLight.indirectColor = max(poiLight.indirectColor * _PPLightingMultiplier, 0);
				poiLight.indirectColor = max(poiLight.indirectColor + _PPLightingAddition, 0);
				#endif
				
				#endif
				
				#ifdef POI_PASS_ADD
				if (!_LightingAdditiveEnable)
				{
					return float4(mainTexture.rgb * .0001, 1);
				}
				
				#if defined(DIRECTIONAL)
				if (_DisableDirectionalInAdd)
				{
					return float4(mainTexture.rgb * .0001, 1);
				}
				#endif
				
				poiLight.direction = normalize(_WorldSpaceLightPos0.xyz - i.worldPos.xyz * _WorldSpaceLightPos0.w);
				#if defined(POINT) || defined(SPOT)
				#ifdef POINT
				unityShadowCoord3 lightCoord = mul(unity_WorldToLight, unityShadowCoord4(poiMesh.worldPos, 1)).xyz;
				poiLight.attenuation = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).r;
				#endif
				
				#ifdef SPOT
				unityShadowCoord4 lightCoord = mul(unity_WorldToLight, unityShadowCoord4(poiMesh.worldPos, 1));
				poiLight.attenuation = (lightCoord.z > 0) * UnitySpotCookie(lightCoord) * UnitySpotAttenuate(lightCoord.xyz);
				#endif
				#else
				UNITY_LIGHT_ATTENUATION(attenuation, i, poiMesh.worldPos)
				poiLight.attenuation = attenuation;
				#endif
				poiLight.additiveShadow = UNITY_SHADOW_ATTENUATION(i, poiMesh.worldPos);
				poiLight.attenuationStrength = _LightingAdditiveCastedShadows;
				poiLight.directColor = _LightingAdditiveLimited ? MaxLuminance(_LightColor0.rgb * poiLight.attenuation, _LightingAdditiveLimit) : _LightColor0.rgb  * poiLight.attenuation;
				
				#if defined(POINT_COOKIE) || defined(DIRECTIONAL_COOKIE)
				poiLight.indirectColor = 0;
				#else
				poiLight.indirectColor = lerp(0, poiLight.directColor, _LightingAdditivePassthrough);
				poiLight.indirectColor = _LightingAdditiveLimited ? MaxLuminance(poiLight.indirectColor, _LightingAdditiveLimit) : poiLight.indirectColor;
				#endif
				
				poiLight.directColor = lerp(poiLight.directColor, dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), _LightingAdditiveMonochromatic);
				poiLight.indirectColor = lerp(poiLight.indirectColor, dot(poiLight.indirectColor, float3(0.299, 0.587, 0.114)), _LightingAdditiveMonochromatic);
				
				poiLight.halfDir = normalize(poiLight.direction + poiCam.viewDir);
				poiLight.nDotL = dot(poiMesh.normals[1], poiLight.direction);
				poiLight.nDotLSaturated = saturate(poiLight.nDotL);
				poiLight.nDotLNormalized = (poiLight.nDotL + 1) * 0.5;
				poiLight.nDotV = abs(dot(poiMesh.normals[1], poiCam.viewDir));
				poiLight.nDotH = dot(poiMesh.normals[1], poiLight.halfDir);
				poiLight.lDotv = dot(poiLight.direction, poiCam.viewDir);
				poiLight.lDotH = dot(poiLight.direction, poiLight.halfDir);
				poiLight.vertexNDotL = dot(poiMesh.normals[0], poiLight.direction);
				poiLight.vertexNDotV = abs(dot(poiMesh.normals[0], poiCam.viewDir));
				poiLight.vertexNDotH = max(0.00001, dot(poiMesh.normals[0], poiLight.halfDir));
				
				// Normalized nDotL
				if (_LightingMapMode == 0 || _LightingMapMode == 1 || _LightingMapMode == 2)
				{
					poiLight.lightMap = poiLight.nDotLNormalized;
				}
				if (_LightingMapMode == 3)
				{
					poiLight.lightMap = 1;
				}
				poiLight.lightMap *= poiLight.detailShadow;
				poiLight.lightMapNoAttenuation = poiLight.lightMap;
				poiLight.lightMap *= lerp(1, poiLight.additiveShadow, poiLight.attenuationStrength);
				#endif
				
				//ifex _LightDataDebugEnabled==0
				if (_LightDataDebugEnabled)
				{
					#ifdef UNITY_PASS_FORWARDBASE
					//UNITY_BRANCH
					if (_LightingDebugVisualize <= 6)
					{
						switch(_LightingDebugVisualize)
						{
							case 0: // Direct Light Color
							return float4(poiLight.directColor + mainTexture.rgb * .0001, 1);
							break;
							case 1: // Indirect Light Color
							return float4(poiLight.indirectColor + mainTexture.rgb * .0001, 1);
							break;
							case 2: // Light Map
							return float4(poiLight.lightMap + mainTexture.rgb * .0001, 1);
							break;
							case 3: // Attenuation
							return float4(poiLight.attenuation + mainTexture.rgb * .0001, 1);
							break;
							case 4: // N Dot L
							return float4(poiLight.nDotLNormalized, poiLight.nDotLNormalized, poiLight.nDotLNormalized, 1) + mainTexture * .0001;
							break;
							case 5:
							return float4(poiLight.halfDir, 1) + mainTexture * .0001;
							break;
							case 6:
							return float4(poiLight.direction, 1) + mainTexture * .0001;
							break;
						}
					}
					else
					{
						return POI_SAFE_RGB1;
					}
					#endif
					#ifdef POI_PASS_ADD
					//UNITY_BRANCH
					if (_LightingDebugVisualize < 6)
					{
						return POI_SAFE_RGB1;
					}
					else
					{
						switch(_LightingDebugVisualize)
						{
							case 7:
							return float4(poiLight.directColor * poiLight.attenuation + mainTexture.rgb * .0001, 1);
							break;
							case 8:
							return float4(poiLight.attenuation + mainTexture.rgb * .0001, 1);
							break;
							case 9:
							return float4(poiLight.additiveShadow + mainTexture.rgb * .0001, 1);
							break;
							case 10:
							return float4(poiLight.nDotLNormalized + mainTexture.rgb * .0001, 1);
							break;
							case 11:
							return float4(poiLight.halfDir, 1) + mainTexture * .0001;
							break;
						}
					}
					#endif
				}
				//endex
				
				//ifex _EnableAudioLink==0
				#ifdef POI_AUDIOLINK
				SetupAudioLink(poiFragData, poiMods, poiMesh);
				#endif
				//endex
				
				//ifex _BlackLightMaskingEnabled==0
				#ifdef POI_BLACKLIGHTMASKING
				calculateBlackLightMasks(poiMesh, poiMods);
				#endif
				//endex
				
				poiFragData.baseColor = mainTexture.rgb * poiThemeColor(poiMods, _Color.rgb, _ColorThemeIndex);
				poiFragData.alpha = mainTexture.a * _Color.a;
				
				//ifex _MainColorAdjustToggle==0
				#ifdef COLOR_GRADING_HDR
				#if defined(PROP_MAINCOLORADJUSTTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 hueShiftAlpha = POI2D_SAMPLER_PAN(_MainColorAdjustTexture, _MainTex, poiUV(poiMesh.uv[_MainColorAdjustTextureUV], _MainColorAdjustTexture_ST), _MainColorAdjustTexturePan);
				#else
				float4 hueShiftAlpha = 1;
				#endif
				
				if (_MainHueGlobalMask > 0)
				{
					hueShiftAlpha.r = maskBlend(hueShiftAlpha.r, poiMods.globalMask[_MainHueGlobalMask - 1], _MainHueGlobalMaskBlendType);
				}
				if (_MainSaturationGlobalMask > 0)
				{
					hueShiftAlpha.b = maskBlend(hueShiftAlpha.b, poiMods.globalMask[_MainSaturationGlobalMask - 1], _MainSaturationGlobalMaskBlendType);
				}
				if (_MainBrightnessGlobalMask > 0)
				{
					hueShiftAlpha.g = maskBlend(hueShiftAlpha.g, poiMods.globalMask[_MainBrightnessGlobalMask - 1], _MainBrightnessGlobalMaskBlendType);
				}
				
				if (_MainHueShiftToggle)
				{
					float shift = _MainHueShift;
					#ifdef POI_AUDIOLINK
					//UNITY_BRANCH
					if (poiMods.audioLinkAvailable && _MainHueALCTEnabled)
					{
						shift += AudioLinkGetChronoTime(_MainALHueShiftCTIndex, _MainALHueShiftBand) * _MainHueALMotionSpeed;
					}
					#endif
					if (_MainHueShiftReplace)
					{
						poiFragData.baseColor = lerp(poiFragData.baseColor, hueShift(poiFragData.baseColor, shift + _MainHueShiftSpeed * _Time.x), hueShiftAlpha.r);
					}
					else
					{
						poiFragData.baseColor = hueShift(poiFragData.baseColor, frac((shift - (1 - hueShiftAlpha.r) + _MainHueShiftSpeed * _Time.x)));
					}
				}
				
				if (_MainGradationStrength && _ColorGradingToggle)
				{
					#if !defined(UNITY_COLORSPACE_GAMMA)
					float3 tempColor = OpenLitLinearToSRGB(poiFragData.baseColor);
					#else
					float3 tempColor = poiFragData.baseColor;
					#endif
					#if defined(PROP_MAINGRADATIONTEX) || !defined(OPTIMIZER_ENABLED)
					tempColor.r = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.r).r;
					tempColor.g = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.g).g;
					tempColor.b = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.b).b;
					#else
					tempColor = float3(1, 1, 1);
					#endif
					#if !defined(UNITY_COLORSPACE_GAMMA)
					tempColor = OpenLitSRGBToLinear(tempColor);
					#endif
					poiFragData.baseColor = lerp(poiFragData.baseColor, tempColor, _MainGradationStrength);
				}
				
				poiFragData.baseColor = lerp(poiFragData.baseColor, dot(poiFragData.baseColor, float3(0.3, 0.59, 0.11)), - (_Saturation) * hueShiftAlpha.b);
				poiFragData.baseColor = saturate(lerp(poiFragData.baseColor, poiFragData.baseColor * (_MainBrightness + 1), hueShiftAlpha.g));
				#endif
				//endex
				
				#if defined(PROP_ALPHAMASK) || !defined(OPTIMIZER_ENABLED)
				
				if (_MainAlphaMaskMode)
				{
					float alphaMask = POI2D_SAMPLER_PAN(_AlphaMask, _MainTex, poiUV(poiMesh.uv[_AlphaMaskUV], _AlphaMask_ST), _AlphaMaskPan.xy).r;
					alphaMask = saturate(alphaMask * _AlphaMaskScale + _AlphaMaskValue);
					if (_AlphaMaskInvert) alphaMask = 1 - alphaMask;
					if (_MainAlphaMaskMode == 1) poiFragData.alpha = alphaMask;
					if (_MainAlphaMaskMode == 2) poiFragData.alpha = poiFragData.alpha * alphaMask;
					if (_MainAlphaMaskMode == 3) poiFragData.alpha = saturate(poiFragData.alpha + alphaMask);
					if (_MainAlphaMaskMode == 4) poiFragData.alpha = saturate(poiFragData.alpha - alphaMask);
				}
				#endif
				
				//ifex _VideoEffectsEnable==0
				#ifdef POI_VIDEO_EFFECTS
				if (_VideoEffectsEnable)
				{
					applyVideoEffects(poiFragData, poiCam, poiMesh, poiLight, poiMods);
				}
				#endif
				//endex
				
				applyAlphaOptions(poiFragData, poiMesh, poiCam, poiMods);
				
				//ifex _MainVertexColoringEnabled==0
				applyVertexColor(poiFragData, poiMesh);
				//endex
				
				//ifex _EnableDissolve==0
				#ifdef DISTORT
				applyDissolve(poiFragData, poiMesh, poiMods, poiCam, poiLight);
				#endif
				//endex
				
				//ifex _ShadingEnabled==0
				#if defined(_LIGHTINGMODE_SHADEMAP) && defined(VIGNETTE_MASKED)
				#ifndef POI_PASS_OUTLINE
				#ifdef _LIGHTINGMODE_SHADEMAP
				applyShadeMapping(poiFragData, poiMesh, poiLight);
				#endif
				#endif
				#endif
				//endex
				
				//ifex _ShadingEnabled==0
				#ifdef VIGNETTE_MASKED
				#ifdef POI_PASS_OUTLINE
				//UNITY_BRANCH
				if (_OutlineLit)
				{
					calculateShading(poiLight, poiFragData, poiMesh, poiCam);
				}
				else
				{
					poiLight.finalLighting = 1;
				}
				#else
				calculateShading(poiLight, poiFragData, poiMesh, poiCam);
				#endif
				#else
				//endex
				poiLight.finalLighting = 1;
				poiLight.rampedLightMap = poiEdgeNonLinear(poiLight.nDotL, 0.1, .1);
				//ifex _ShadingEnabled==0
				#endif
				if (_ShadingRampedLightMapApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _ShadingRampedLightMapApplyGlobalMaskIndex - 1, _ShadingRampedLightMapApplyGlobalMaskBlendType, poiLight.rampedLightMap);
				}
				if (_ShadingRampedLightMapInverseApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _ShadingRampedLightMapInverseApplyGlobalMaskIndex - 1, _ShadingRampedLightMapInverseApplyGlobalMaskBlendType, 1 - poiLight.rampedLightMap);
				}
				
				poiLight.directLuminance = dot(poiLight.directColor, float3(0.299, 0.587, 0.114));
				poiLight.indirectLuminance = dot(poiLight.directColor, float3(0.299, 0.587, 0.114));
				poiLight.finalLuminance = dot(poiLight.finalLighting, float3(0.299, 0.587, 0.114));
				//endex
				
				//ifex _EnableOutlines!=1
				#ifdef POI_PASS_OUTLINE
				applyOutlineColor(poiFragData, poiMesh, poiLight, poiMods, poiCam);
				#endif
				//endex
				
				//ifex _EnableALDecal==0
				#ifdef POI_AUDIOLINK
				#ifdef POI_AL_DECAL
				ApplyAudioLinkDecal(poiMesh, poiFragData, poiMods);
				#endif
				#endif
				//endex
				
				//ifex _EnableFlipbook==0
				#ifdef _SUNDISK_HIGH_QUALITY
				applyFlipbook(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _EnableMirrorOptions==0
				#ifdef POI_MIRROR
				applyMirror(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _VoronoiEnabled!=1
				#ifdef POI_VORONOI
				ApplyVoronoi(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				UNITY_BRANCH
				if (_AlphaPremultiply)
				{
					poiFragData.baseColor *= saturate(poiFragData.alpha);
				}
				poiFragData.finalColor = poiFragData.baseColor;
				
				poiFragData.finalColor = poiFragData.baseColor * poiLight.finalLighting;
				
				//ifex _BacklightEnabled!=1
				#ifdef POI_BACKLIGHT
				ApplyBacklight(poiFragData, poiMesh, poiLight, poiCam, poiMods);
				#endif
				//endex
				
				//UNITY_BRANCH
				if (_IgnoreFog == 0)
				{
					UNITY_APPLY_FOG(i.fogCoord, poiFragData.finalColor);
				}
				
				poiFragData.alpha = _AlphaForceOpaque ? 1 : poiFragData.alpha;
				
				//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
				ApplyAlphaToCoverage(poiFragData, poiMesh);
				//endex
				
				//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
				applyDithering(poiFragData, poiCam);
				//endex
				
				if (_Mode == POI_MODE_OPAQUE)
				{
					poiFragData.alpha = 1;
				}
				
				//ifex _BSSEnabled!=1
				#ifdef POIBS_ENABLE
				poiFragData.finalColor += poiFragData.emission * poiMods.globalEmission;
				poiFragData.alpha = poiFragData.alpha * poiFragData.emission.z;
				poiFragData.emission = 0;
				
				//ifex _BSSBloomfog!=1
				#ifdef POIBS_BLOOMFOG
				float3 fogDistance = i.worldPos + - _WorldSpaceCameraPos;
				float4 fogCol = -float4(poiFragData.finalColor, 1) + tex2D(_BloomPrePassTexture, i.fogCoord.xy);
				fogCol.a = -poiFragData.alpha;
				
				#ifdef BSSBLOOMFOGTYPE_HEIGHT
				poiFragData.finalColor = poiFragData.finalColor + (((GetHeightFogIntensity(i.worldPos, _FogHeightOffset, _FogHeightScale) * GetFogIntensity(fogDistance, _FogStartOffset, _FogScale)) + 1) * fogCol.rgb);
				poiFragData.alpha = poiFragData.alpha + (((GetHeightFogIntensity(i.worldPos, _FogHeightOffset, _FogHeightScale) * GetFogIntensity(fogDistance, _FogStartOffset, _FogScale)) + 1) * fogCol.a);
				#else
				poiFragData.finalColor = poiFragData.finalColor + ((GetFogIntensity(fogDistance, _FogStartOffset, _FogScale) + 1) * fogCol.rgb);
				poiFragData.alpha = poiFragData.alpha + ((GetFogIntensity(fogDistance, _FogStartOffset, _FogScale) + 1) * fogCol.a);
				#endif
				#endif
				//endex
				#endif
				//endex
				
				clip(poiFragData.alpha - _Cutoff);
				
				return float4(poiFragData.finalColor + poiFragData.emission * poiMods.globalEmission, poiFragData.alpha) + POI_SAFE_RGB0;
			}
			
			ENDCG
		}
		//endex
		
		Pass
		{
			Name "Base"
			Tags { "LightMode" = "ForwardBase" }
			
			Stencil
			{
				Ref [_StencilRef]
				ReadMask [_StencilReadMask]
				WriteMask [_StencilWriteMask]
				//ifex _StencilType==1
				Comp [_StencilCompareFunction]
				Pass [_StencilPassOp]
				Fail [_StencilFailOp]
				ZFail [_StencilZFailOp]
				//endex
				
				//ifex _StencilType==0
				CompBack [_StencilBackCompareFunction]
				PassBack [_StencilBackPassOp]
				FailBack [_StencilBackFailOp]
				ZFailBack [_StencilBackZFailOp]
				
				CompFront [_StencilFrontCompareFunction]
				PassFront [_StencilFrontPassOp]
				FailFront [_StencilFrontFailOp]
				ZFailFront [_StencilFrontZFailOp]
				//endex
			}
			
			ZWrite [_ZWrite]
			Cull [_Cull]
			Cull Front
			
			Cull Back
			
			AlphaToMask [_AlphaToCoverage]
			ZTest [_ZTest]
			ColorMask [_ColorMask]
			Offset [_OffsetFactor], [_OffsetUnits]
			
			BlendOp [_BlendOp], [_BlendOpAlpha]
			Blend [_SrcBlend] [_DstBlend], [_SrcBlendAlpha] [_DstBlendAlpha]
			
			CGPROGRAM
			/*
			// Disable warnings we aren't interested in
			#if defined(UNITY_COMPILER_HLSL)
			#pragma warning(disable : 3205) // conversion of larger type to smaller
			#pragma warning(disable : 3568) // unknown pragma ignored
			#pragma warning(disable : 3571) // "pow(f,e) will not work for negative f"; however in majority of our calls to pow we know f is not negative
			#pragma warning(disable : 3206) // implicit truncation of vector type
			#endif
			*/
			#pragma target 5.0
			//ifex 0==0
			#pragma skip_optimizations d3d11
			//endex
			
			#pragma shader_feature_local _STOCHASTICMODE_DELIOT_HEITZ _STOCHASTICMODE_HEXTILE _STOCHASTICMODE_NONE
			
			//ifex _MainColorAdjustToggle==0
			#pragma shader_feature COLOR_GRADING_HDR
			//endex
			
			//#pragma shader_feature KEYWORD
			
			#pragma skip_variants LIGHTMAP_ON DYNAMICLIGHTMAP_ON LIGHTMAP_SHADOW_MIXING SHADOWS_SHADOWMASK DIRLIGHTMAP_COMBINED _MIXED_LIGHTING_SUBTRACTIVE
			#pragma skip_variants DECALS_OFF DECALS_3RT DECALS_4RT DECAL_SURFACE_GRADIENT _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3
			#pragma skip_variants _ADDITIONAL_LIGHT_SHADOWS
			#pragma skip_variants PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2
			#pragma skip_variants _SCREEN_SPACE_OCCLUSION
			
			//ifex _GlobalMaskTexturesEnable==0
			#pragma shader_feature_local POI_GLOBALMASK_TEXTURES
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#pragma shader_feature_local POI_UDIMDISCARD
			//endex
			
			//ifex _EnableDistortion==0
			#pragma shader_feature USER_LUT
			//endex
			
			//ifex _PoiParallax==0
			#pragma shader_feature_local POI_PARALLAX
			//endex
			
			//ifex _EnableAudioLink==0
			#pragma shader_feature_local POI_AUDIOLINK
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#pragma shader_feature_local POI_BLACKLIGHTMASKING
			//endex
			
			//ifex _DetailEnabled==0
			#pragma shader_feature FINALPASS
			//endex
			
			//ifex _VertexManipulationsEnabled==0
			#pragma shader_feature AUTO_EXPOSURE
			//endex
			
			//ifex _VertexGlitchingEnabled==0
			#pragma shader_feature_local POI_VERTEX_GLITCHING
			#pragma shader_feature_local POI_VERTEX_GLITCHING_TEXTURE
			//endex
			
			//ifex _EnableDepthBulge==0
			#pragma shader_feature_local POI_DEPTHBULGE
			//endex
			
			//ifex _BackFaceEnabled!=1
			#pragma shader_feature_local POI_BACKFACE
			//endex
			
			//ifex _RGBMaskEnabled==0
			#pragma shader_feature VIGNETTE
			#pragma shader_feature GEOM_TYPE_MESH
			//endex
			
			//ifex _LTCGIEnabled!=1
			#pragma shader_feature_local POI_LTCGI
			//endex
			
			//ifex _ShadingEnabled==0
			#pragma shader_feature_local VIGNETTE_MASKED
			#pragma shader_feature_local _LIGHTINGMODE_TEXTURERAMP _LIGHTINGMODE_MULTILAYER_MATH _LIGHTINGMODE_SHADEMAP _LIGHTINGMODE_REALISTIC _LIGHTINGMODE_WRAPPED _LIGHTINGMODE_SKIN _LIGHTINGMODE_FLAT _LIGHTINGMODE_CLOTH _LIGHTINGMODE_SDF
			//endex
			
			//ifex _DecalEnabled==0
			#pragma shader_feature GEOM_TYPE_BRANCH
			//endex
			//ifex _DecalEnabled1==0
			#pragma shader_feature GEOM_TYPE_BRANCH_DETAIL
			//endex
			//ifex _DecalEnabled2==0
			#pragma shader_feature GEOM_TYPE_FROND
			//endex
			//ifex _DecalEnabled3==0
			#pragma shader_feature DEPTH_OF_FIELD_COC_VIEW
			//endex
			
			//ifex _EnableDissolve==0
			#pragma shader_feature DISTORT
			//endex
			
			//ifex _EnableAniso==0
			#pragma shader_feature_local POI_ANISOTROPICS
			//endex
			
			//ifex _MatcapEnable==0
			#pragma shader_feature_local POI_MATCAP0
			#pragma shader_feature_local POI_MATCAP0_CUSTOM_NORMAL
			//endex
			//ifex _Matcap2Enable==0
			#pragma shader_feature COLOR_GRADING_HDR_3D
			#pragma shader_feature_local POI_MATCAP1_CUSTOM_NORMAL
			//endex
			//ifex _Matcap3Enable==0
			#pragma shader_feature_local POI_MATCAP2
			#pragma shader_feature_local POI_MATCAP2_CUSTOM_NORMAL
			//endex
			//ifex _Matcap4Enable==0
			#pragma shader_feature_local POI_MATCAP3
			#pragma shader_feature_local POI_MATCAP3_CUSTOM_NORMAL
			//endex
			
			//ifex _CubeMapEnabled==0
			#pragma shader_feature_local _CUBEMAP
			//endex
			
			//ifex _EnableALDecal==0
			#pragma shader_feature_local POI_AL_DECAL
			//endex
			
			//ifex _EnableVolumeColor==0
			#pragma shader_feature_local POI_AL_VOLUMECOLOR
			//endex
			
			//ifex _EnableFlipbook==0
			#pragma shader_feature _SUNDISK_HIGH_QUALITY
			//endex
			
			//ifex _EnableEmission==0
			#pragma shader_feature _EMISSION
			//endex
			//ifex _EnableEmission1==0
			#pragma shader_feature_local POI_EMISSION_1
			//endex
			//ifex _EnableEmission2==0
			#pragma shader_feature_local POI_EMISSION_2
			//endex
			//ifex _EnableEmission3==0
			#pragma shader_feature_local POI_EMISSION_3
			//endex
			
			//ifex _EnableRimLighting==0
			#pragma shader_feature_local _GLOSSYREFLECTIONS_OFF
			#pragma shader_feature_local _RIMSTYLE_POIYOMI _RIMSTYLE_UTS2 _RIMSTYLE_LILTOON
			//endex
			//ifex _EnableRim2Lighting==0
			#pragma shader_feature_local POI_RIM2
			#pragma shader_feature_local _RIM2STYLE_POIYOMI _RIM2STYLE_UTS2 _RIM2STYLE_LILTOON
			//endex
			
			//ifex _EnableDepthRimLighting==0
			#pragma shader_feature_local _POI_DEPTH_RIMLIGHT
			//endex
			
			//ifex _GlitterEnable==0
			#pragma shader_feature _SUNDISK_SIMPLE
			//endex
			
			//ifex _SubsurfaceScattering==0
			#pragma shader_feature_local POI_SUBSURFACESCATTERING
			//endex
			
			//ifex _MochieBRDF==0
			#pragma shader_feature_local MOCHIE_PBR
			//endex
			//ifex _ClearCoatBRDF==0
			#pragma shader_feature_local POI_CLEARCOAT
			//endex
			
			//ifex _EnableEnvironmentalRim==0
			#pragma shader_feature_local POI_ENVIRORIM
			//endex
			
			//ifex _StylizedSpecular==0
			#pragma shader_feature_local POI_STYLIZED_StylizedSpecular
			//endex
			
			//ifex _EnablePathing==0
			#pragma shader_feature_local POI_PATHING
			//endex
			
			//ifex _EnableMirrorOptions==0
			#pragma shader_feature_local POI_MIRROR
			//endex
			
			//ifex _EnableTouchGlow==0
			#pragma shader_feature GRAIN
			//endex
			
			//ifex _TextEnabled==0
			#pragma shader_feature EFFECT_BUMP
			//endex
			
			//ifex _PostProcess==0
			#pragma shader_feature_local POSTPROCESS
			//endex
			
			//ifex _PoiInternalParallax==0
			#pragma shader_feature_local POI_INTERNALPARALLAX
			//endex
			
			//ifex _NormalCorrect==0
			#pragma shader_feature_local POI_NORMALCORRECT
			//endex
			
			//ifex _VideoEffectsEnable==0
			#pragma shader_feature_local POI_VIDEO_EFFECTS
			//endex
			
			//ifex _BacklightEnabled!=1
			#pragma shader_feature_local POI_BACKLIGHT
			//endex
			
			//ifex _BSSEnabled!=1
			#pragma shader_feature_local POIBS_ENABLE
			//ifex _BSSBloomfog!=1
			#pragma shader_feature_local POIBS_BLOOMFOG
			#pragma shader_feature_local BSSBLOOMFOGTYPE_HEIGHT
			//endex
			//endex
			
			//ifex _VoronoiEnabled!=1
			#pragma shader_feature_local POI_VORONOI
			//endex
			
			// UNITY Includes
			#include "UnityCG.cginc"
			#include "UnityStandardUtils.cginc"
			#include "AutoLight.cginc"
			#include "UnityLightingCommon.cginc"
			#include "UnityPBSLighting.cginc"
			#ifdef POI_PASS_META
			#include "UnityMetaPass.cginc"
			#endif
			#pragma vertex vert
			
			#pragma fragment frag
			
			#define DielectricSpec float4(0.04, 0.04, 0.04, 1.0 - 0.04)
			#define PI float(3.14159265359)
			#define Epsilon float(1e-10)
			
			#define POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, samplertex, coord, dx, dy) tex.SampleGrad(sampler##samplertex, coord, dx, dy)
			#define POI2D_SAMPLE_TEX2D_SAMPLERGRADD(tex, samp, uv, pan, dx, dy) tex.SampleGrad(samp, POI_PAN_UV(uv, pan), dx, dy)
			
			#define POI_PAN_UV(uv, pan) (uv + _Time.x * pan)
			#define POI2D_SAMPLER_PAN(tex, texSampler, uv, pan) (UNITY_SAMPLE_TEX2D_SAMPLER(tex, texSampler, POI_PAN_UV(uv, pan)))
			#define POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy) (POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, texSampler, POI_PAN_UV(uv, pan), dx, dy))
			#define POI2D_SAMPLER(tex, texSampler, uv) (UNITY_SAMPLE_TEX2D_SAMPLER(tex, texSampler, uv))
			#define POI_SAMPLE_1D_X(tex, samp, uv) tex.Sample(samp, float2(uv, 0.5))
			#define POI2D_SAMPLER_GRAD(tex, texSampler, uv, dx, dy) (POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, texSampler, uv, dx, dy))
			#define POI2D_SAMPLER_GRADD(tex, texSampler, uv, dx, dy) tex.SampleGrad(texSampler, uv, dx, dy)
			#define POI2D_PAN(tex, uv, pan) (tex2D(tex, POI_PAN_UV(uv, pan)))
			#define POI2D(tex, uv) (tex2D(tex, uv))
			#define POI_SAMPLE_TEX2D(tex, uv) (UNITY_SAMPLE_TEX2D(tex, uv))
			#define POI_SAMPLE_TEX2D_PAN(tex, uv, pan) (UNITY_SAMPLE_TEX2D(tex, POI_PAN_UV(uv, pan)))
			#define POI_SAMPLE_CUBE_LOD(tex, samp, uv, lod) texCUBElod(tex, float4(uv, 0, lod))
			
			#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
			#define POI_SAMPLE_SCREEN(tex, samp, uv)          tex.Sample(samp, float3(uv, unity_StereoEyeIndex))
			#else
			#define POI_SAMPLE_SCREEN(tex, samp, uv)          tex.Sample(samp, uv)
			#endif
			
			// When using, properties won't properly lock at optimize time; needs macro evaluation implemented
			// #define POI2D_MAINTEX_SAMPLER_PAN_INLINED(tex, poiMesh) (POI2D_SAMPLER_PAN(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan))
			
			#define POI_SAFE_RGB0 float4(mainTexture.rgb * .0001, 0)
			#define POI_SAFE_RGB1 float4(mainTexture.rgb * .0001, 1)
			#define POI_SAFE_RGBA mainTexture
			
			#if defined(UNITY_COMPILER_HLSL)
			#define PoiInitStruct(type, name) name = (type)0;
			#else
			#define PoiInitStruct(type, name)
			#endif
			
			#define POI_ERROR(poiMesh, gridSize) lerp(float3(1, 0, 1), float3(0, 0, 0), fmod(floor((poiMesh.worldPos.x) * gridSize) + floor((poiMesh.worldPos.y) * gridSize) + floor((poiMesh.worldPos.z) * gridSize), 2) == 0)
			#define POI_NAN (asfloat(-1))
			
			#define POI_MODE_OPAQUE 0
			#define POI_MODE_CUTOUT 1
			#define POI_MODE_FADE 2
			#define POI_MODE_TRANSPARENT 3
			#define POI_MODE_ADDITIVE 4
			#define POI_MODE_SOFTADDITIVE 5
			#define POI_MODE_MULTIPLICATIVE 6
			#define POI_MODE_2XMULTIPLICATIVE 7
			#define POI_MODE_TRANSCLIPPING 9
			
			/*
			Texture2D ;
			float4 _ST;
			float2 Pan;
			float UV;
			float Stochastic;
			
			[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos XZ, 5, Polar UV, 6, Distorted UV, 7 )]
			*/
			
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			// Map of where features in AudioLink are.
			#define ALPASS_DFT                      uint2(0, 4)   //Size: 128, 2
			#define ALPASS_WAVEFORM                 uint2(0, 6)   //Size: 128, 16
			#define ALPASS_AUDIOLINK                uint2(0, 0)   //Size: 128, 4
			#define ALPASS_AUDIOBASS                uint2(0, 0)   //Size: 128, 1
			#define ALPASS_AUDIOLOWMIDS             uint2(0, 1)   //Size: 128, 1
			#define ALPASS_AUDIOHIGHMIDS            uint2(0, 2)   //Size: 128, 1
			#define ALPASS_AUDIOTREBLE              uint2(0, 3)   //Size: 128, 1
			#define ALPASS_AUDIOLINKHISTORY         uint2(1, 0)   //Size: 127, 4
			#define ALPASS_GENERALVU                uint2(0, 22)  //Size: 12, 1
			#define ALPASS_CCINTERNAL               uint2(12, 22) //Size: 12, 2
			#define ALPASS_CCCOLORS                 uint2(25, 22) //Size: 11, 1
			#define ALPASS_CCSTRIP                  uint2(0, 24)  //Size: 128, 1
			#define ALPASS_CCLIGHTS                 uint2(0, 25)  //Size: 128, 2
			#define ALPASS_AUTOCORRELATOR           uint2(0, 27)  //Size: 128, 1
			#define ALPASS_GENERALVU_INSTANCE_TIME  uint2(2, 22)
			#define ALPASS_GENERALVU_LOCAL_TIME     uint2(3, 22)
			#define ALPASS_GENERALVU_NETWORK_TIME   uint2(4, 22)
			#define ALPASS_GENERALVU_PLAYERINFO     uint2(6, 22)
			// Added in version 2.5
			#define ALPASS_FILTEREDAUDIOLINK        uint2(0, 28)  //Size: 16, 4
			// Added in version 2.6
			#define ALPASS_CHRONOTENSITY            uint2(16, 28) //Size: 8, 4
			#define ALPASS_THEME_COLOR0             uint2(0, 23)
			#define ALPASS_THEME_COLOR1             uint2(1, 23)
			#define ALPASS_THEME_COLOR2             uint2(2, 23)
			#define ALPASS_THEME_COLOR3             uint2(3, 23)
			#define ALPASS_FILTEREDVU               uint2(24, 28) //Size: 4, 4
			#define ALPASS_FILTEREDVU_INTENSITY     uint2(24, 28) //Size: 4, 1
			#define ALPASS_FILTEREDVU_MARKER        uint2(24, 29) //Size: 4, 1
			
			// Some basic constants to use (Note, these should be compatible with
			// future version of AudioLink, but may change.
			#define AUDIOLINK_SAMPHIST              3069        // Internal use for algos, do not change.
			#define AUDIOLINK_SAMPLEDATA24          2046
			#define AUDIOLINK_EXPBINS               24
			#define AUDIOLINK_EXPOCT                10
			#define AUDIOLINK_ETOTALBINS (AUDIOLINK_EXPBINS * AUDIOLINK_EXPOCT)
			#define AUDIOLINK_WIDTH                 128
			#define AUDIOLINK_SPS                   48000       // Samples per second
			#define AUDIOLINK_ROOTNOTE              0
			#define AUDIOLINK_4BAND_FREQFLOOR       0.123
			#define AUDIOLINK_4BAND_FREQCEILING     1
			#define AUDIOLINK_BOTTOM_FREQUENCY      13.75
			#define AUDIOLINK_BASE_AMPLITUDE        2.5
			#define AUDIOLINK_DELAY_COEFFICIENT_MIN 0.3
			#define AUDIOLINK_DELAY_COEFFICIENT_MAX 0.9
			#define AUDIOLINK_DFT_Q                 4.0
			#define AUDIOLINK_TREBLE_CORRECTION     5.0
			
			// ColorChord constants
			#define COLORCHORD_EMAXBIN              192
			#define COLORCHORD_IIR_DECAY_1          0.90
			#define COLORCHORD_IIR_DECAY_2          0.85
			#define COLORCHORD_CONSTANT_DECAY_1     0.01
			#define COLORCHORD_CONSTANT_DECAY_2     0.0
			#define COLORCHORD_NOTE_CLOSEST         3.0
			#define COLORCHORD_NEW_NOTE_GAIN        8.0
			#define COLORCHORD_MAX_NOTES            10
			
			uniform float4               _AudioTexture_TexelSize;
			
			#ifdef SHADER_TARGET_SURFACE_ANALYSIS
			#define AUDIOLINK_STANDARD_INDEXING
			#endif
			
			// Mechanism to index into texture.
			#ifdef AUDIOLINK_STANDARD_INDEXING
			sampler2D _AudioTexture;
			#define AudioLinkData(xycoord) tex2Dlod(_AudioTexture, float4(uint2(xycoord) * _AudioTexture_TexelSize.xy, 0, 0))
			#else
			uniform Texture2D<float4> _AudioTexture;
			SamplerState sampler_AudioTexture;
			#define AudioLinkData(xycoord) _AudioTexture[uint2(xycoord)]
			#endif
			uniform sampler2D _Stored;
			uniform float4 _Stored_TexelSize;
			#endif
			//endex
			
			float _GrabMode;
			float _Mode;
			
			float _StochasticDeliotHeitzDensity;
			float _StochasticHexGridDensity;
			float _StochasticHexRotationStrength;
			float _StochasticHexFallOffContrast;
			float _StochasticHexFallOffPower;
			
			#if defined(PROP_LIGHTINGAOMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _LightingAOMaps;
			#endif
			float4 _LightingAOMaps_ST;
			float2 _LightingAOMapsPan;
			float _LightingAOMapsUV;
			float _LightDataAOStrengthR;
			float _LightDataAOStrengthG;
			float _LightDataAOStrengthB;
			float _LightDataAOStrengthA;
			float _LightDataAOGlobalMaskR;
			float _LightDataAOGlobalMaskBlendTypeR;
			
			#if defined(PROP_LIGHTINGDETAILSHADOWMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _LightingDetailShadowMaps;
			#endif
			float4 _LightingDetailShadowMaps_ST;
			float2 _LightingDetailShadowMapsPan;
			float _LightingDetailShadowMapsUV;
			float _LightingDetailShadowStrengthR;
			float _LightingDetailShadowStrengthG;
			float _LightingDetailShadowStrengthB;
			float _LightingDetailShadowStrengthA;
			float _LightingAddDetailShadowStrengthR;
			float _LightingAddDetailShadowStrengthG;
			float _LightingAddDetailShadowStrengthB;
			float _LightingAddDetailShadowStrengthA;
			float _LightDataDetailShadowGlobalMaskR;
			float _LightDataDetailShadowGlobalMaskBlendTypeR;
			
			#if defined(PROP_LIGHTINGSHADOWMASKS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _LightingShadowMasks;
			#endif
			float4 _LightingShadowMasks_ST;
			float2 _LightingShadowMasksPan;
			float _LightingShadowMasksUV;
			float _LightingShadowMaskStrengthR;
			float _LightingShadowMaskStrengthG;
			float _LightingShadowMaskStrengthB;
			float _LightingShadowMaskStrengthA;
			float _LightDataShadowMaskGlobalMaskR;
			float _LightDataShadowMaskGlobalMaskBlendTypeR;
			
			// Lighting Data
			float _Unlit_Intensity;
			float _LightingColorMode;
			float _LightingMapMode;
			float _LightingDirectionMode;
			float3 _LightngForcedDirection;
			float _LightingViewDirOffsetPitch;
			float _LightingViewDirOffsetYaw;
			float _LightingIndirectUsesNormals;
			float _LightingCapEnabled;
			float _LightingCap;
			float _LightingForceColorEnabled;
			float3 _LightingForcedColor;
			float _LightingForcedColorThemeIndex;
			float _LightingCastedShadows;
			float _LightingMonochromatic;
			float _LightingMinLightBrightness;
			// Additive Lighting Data
			float _LightingAdditiveEnable;
			float _LightingAdditiveLimited;
			float _LightingAdditiveLimit;
			float _LightingAdditiveCastedShadows;
			float _LightingAdditiveMonochromatic;
			float _LightingAdditivePassthrough;
			float _DisableDirectionalInAdd;
			float _LightingVertexLightingEnabled;
			float _LightingMirrorVertexLightingEnabled;
			// Lighting Data Debug
			float _LightDataDebugEnabled;
			float _LightingDebugVisualize;
			
			float _IgnoreFog;
			float _RenderingReduceClipDistance;
			int _FlipBackfaceNormals;
			float _AddBlendOp;
			float _Cull;
			
			float4 _Color;
			float _ColorThemeIndex;
			UNITY_DECLARE_TEX2D(_MainTex);
			UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
			float _MainPixelMode;
			float4 _MainTex_ST;
			float2 _MainTexPan;
			float _MainTexUV;
			float4 _MainTex_TexelSize;
			float _MainTexStochastic;
			#if defined(PROP_BUMPMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BumpMap;
			#endif
			float4 _BumpMap_ST;
			float2 _BumpMapPan;
			float _BumpMapUV;
			float _BumpScale;
			float _BumpMapStochastic;
			#if defined(PROP_ALPHAMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AlphaMask;
			float4 _AlphaMask_ST;
			float2 _AlphaMaskPan;
			float _AlphaMaskUV;
			float _AlphaMaskInvert;
			float _MainAlphaMaskMode;
			float _AlphaMaskScale;
			float _AlphaMaskValue;
			#endif
			float _Cutoff;
			//ifex _MainColorAdjustToggle==0
			#ifdef COLOR_GRADING_HDR
			float _MainColorAdjustToggle;
			#if defined(PROP_MAINCOLORADJUSTTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MainColorAdjustTexture;
			#endif
			float4 _MainColorAdjustTexture_ST;
			float2 _MainColorAdjustTexturePan;
			float _MainColorAdjustTextureUV;
			float _MainHueShiftToggle;
			float _MainHueShiftReplace;
			float _MainHueShift;
			float _MainHueShiftSpeed;
			float _Saturation;
			float _MainBrightness;
			
			float _MainHueALCTEnabled;
			float _MainALHueShiftBand;
			float _MainALHueShiftCTIndex;
			float _MainHueALMotionSpeed;
			
			float _MainHueGlobalMask;
			float _MainHueGlobalMaskBlendType;
			float _MainSaturationGlobalMask;
			float _MainSaturationGlobalMaskBlendType;
			float _MainBrightnessGlobalMask;
			float _MainBrightnessGlobalMaskBlendType;
			
			#if defined(PROP_MAINGRADATIONTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MainGradationTex;
			#endif
			float _ColorGradingToggle;
			float _MainGradationStrength;
			#endif
			//endex
			
			SamplerState sampler_linear_clamp;
			SamplerState sampler_linear_repeat;
			SamplerState sampler_trilinear_repeat;
			
			float _AlphaForceOpaque;
			float _AlphaMod;
			float _AlphaPremultiply;
			float _AlphaBoostFA;
			//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
			float _AlphaToCoverage;
			float _AlphaSharpenedA2C;
			float _AlphaMipScale;
			//endex
			
			//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
			float _AlphaDithering;
			float _AlphaDitherGradient;
			float _AlphaDitherBias;
			//endex
			
			//ifex _AlphaDistanceFade==0 && isNotAnimated(_AlphaDistanceFade)
			float _AlphaDistanceFade;
			float _AlphaDistanceFadeType;
			float _AlphaDistanceFadeMinAlpha;
			float _AlphaDistanceFadeMaxAlpha;
			float _AlphaDistanceFadeMin;
			float _AlphaDistanceFadeMax;
			float _AlphaDistanceFadeGlobalMask;
			float _AlphaDistanceFadeGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaFresnel==0 && isNotAnimated(_AlphaFresnel)
			float _AlphaFresnel;
			float _AlphaFresnelAlpha;
			float _AlphaFresnelSharpness;
			float _AlphaFresnelWidth;
			float _AlphaFresnelInvert;
			float _AlphaFresnelGlobalMask;
			float _AlphaFresnelGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaAngular==0 && isNotAnimated(_AlphaAngular)
			float _AlphaAngular;
			float _AngleType;
			float _AngleCompareTo;
			float3 _AngleForwardDirection;
			float _CameraAngleMin;
			float _CameraAngleMax;
			float _ModelAngleMin;
			float _ModelAngleMax;
			float _AngleMinAlpha;
			float _AlphaAngularGlobalMask;
			float _AlphaAngularGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaAudioLinkEnabled==0 && isNotAnimated(_AlphaAudioLinkEnabled)
			float _AlphaAudioLinkEnabled;
			float2 _AlphaAudioLinkAddRange;
			float _AlphaAudioLinkAddBand;
			//endex
			
			float _AlphaGlobalMask;
			float _AlphaGlobalMaskBlendType;
			
			float4 _GlobalThemeColor0;
			float4 _GlobalThemeColor1;
			float4 _GlobalThemeColor2;
			float4 _GlobalThemeColor3;
			float _GlobalThemeHue0;
			float _GlobalThemeHue1;
			float _GlobalThemeHue2;
			float _GlobalThemeHue3;
			float _GlobalThemeHueSpeed0;
			float _GlobalThemeHueSpeed1;
			float _GlobalThemeHueSpeed2;
			float _GlobalThemeHueSpeed3;
			float _GlobalThemeSaturation0;
			float _GlobalThemeSaturation1;
			float _GlobalThemeSaturation2;
			float _GlobalThemeSaturation3;
			float _GlobalThemeValue0;
			float _GlobalThemeValue1;
			float _GlobalThemeValue2;
			float _GlobalThemeValue3;
			
			//ifex _GlobalMaskTexturesEnable==0
			#ifdef POI_GLOBALMASK_TEXTURES
			#if defined(PROP_GLOBALMASKTEXTURE0) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture0;
			#endif
			float4 _GlobalMaskTexture0_ST;
			float2 _GlobalMaskTexture0Pan;
			float _GlobalMaskTexture0UV;
			int _GlobalMaskTexture0Split;
			float4 _GlobalMaskTexture0SplitTilingOffset_G;
			float4 _GlobalMaskTexture0SplitPan_G;
			float4 _GlobalMaskTexture0SplitTilingOffset_B;
			float4 _GlobalMaskTexture0SplitPan_B;
			float4 _GlobalMaskTexture0SplitTilingOffset_A;
			float4 _GlobalMaskTexture0SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture1;
			#endif
			float4 _GlobalMaskTexture1_ST;
			float2 _GlobalMaskTexture1Pan;
			float _GlobalMaskTexture1UV;
			int _GlobalMaskTexture1Split;
			float4 _GlobalMaskTexture1SplitTilingOffset_G;
			float4 _GlobalMaskTexture1SplitPan_G;
			float4 _GlobalMaskTexture1SplitTilingOffset_B;
			float4 _GlobalMaskTexture1SplitPan_B;
			float4 _GlobalMaskTexture1SplitTilingOffset_A;
			float4 _GlobalMaskTexture1SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture2;
			#endif
			float4 _GlobalMaskTexture2_ST;
			float2 _GlobalMaskTexture2Pan;
			float _GlobalMaskTexture2UV;
			int _GlobalMaskTexture2Split;
			float4 _GlobalMaskTexture2SplitTilingOffset_G;
			float4 _GlobalMaskTexture2SplitPan_G;
			float4 _GlobalMaskTexture2SplitTilingOffset_B;
			float4 _GlobalMaskTexture2SplitPan_B;
			float4 _GlobalMaskTexture2SplitTilingOffset_A;
			float4 _GlobalMaskTexture2SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE3) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture3;
			#endif
			float4 _GlobalMaskTexture3_ST;
			float2 _GlobalMaskTexture3Pan;
			float _GlobalMaskTexture3UV;
			int _GlobalMaskTexture3Split;
			float4 _GlobalMaskTexture3SplitTilingOffset_G;
			float4 _GlobalMaskTexture3SplitPan_G;
			float4 _GlobalMaskTexture3SplitTilingOffset_B;
			float4 _GlobalMaskTexture3SplitPan_B;
			float4 _GlobalMaskTexture3SplitTilingOffset_A;
			float4 _GlobalMaskTexture3SplitPan_A;
			#endif
			//endex
			//ifex _GlobalMaskOptionsEnable==0
			float _GlobalMaskOptionsEnable;
			int _GlobalMaskOptionsType;
			
			//ifex _GlobalMaskOptionsType!=0
			float _GlobalMaskSlider_0;
			float _GlobalMaskSlider_1;
			float _GlobalMaskSlider_2;
			float _GlobalMaskSlider_3;
			float _GlobalMaskSlider_4;
			float _GlobalMaskSlider_5;
			float _GlobalMaskSlider_6;
			float _GlobalMaskSlider_7;
			float _GlobalMaskSlider_8;
			float _GlobalMaskSlider_9;
			float _GlobalMaskSlider_10;
			float _GlobalMaskSlider_11;
			float _GlobalMaskSlider_12;
			float _GlobalMaskSlider_13;
			float _GlobalMaskSlider_14;
			float _GlobalMaskSlider_15;
			//endex
			
			//ifex _GlobalMaskOptionsType!=1
			float2 _GlobalMaskMinMaxSlider_0;
			float2 _GlobalMaskMinMaxSlider_1;
			float2 _GlobalMaskMinMaxSlider_2;
			float2 _GlobalMaskMinMaxSlider_3;
			float2 _GlobalMaskMinMaxSlider_4;
			float2 _GlobalMaskMinMaxSlider_5;
			float2 _GlobalMaskMinMaxSlider_6;
			float2 _GlobalMaskMinMaxSlider_7;
			float2 _GlobalMaskMinMaxSlider_8;
			float2 _GlobalMaskMinMaxSlider_9;
			float2 _GlobalMaskMinMaxSlider_10;
			float2 _GlobalMaskMinMaxSlider_11;
			float2 _GlobalMaskMinMaxSlider_12;
			float2 _GlobalMaskMinMaxSlider_13;
			float2 _GlobalMaskMinMaxSlider_14;
			float2 _GlobalMaskMinMaxSlider_15;
			//endex
			
			//ifex _GlobalMaskOptionsType!=2
			int _GlobalMaskToggleOn_0;
			int _GlobalMaskToggleOff_0;
			int _GlobalMaskToggleOn_1;
			int _GlobalMaskToggleOff_1;
			int _GlobalMaskToggleOn_2;
			int _GlobalMaskToggleOff_2;
			int _GlobalMaskToggleOn_3;
			int _GlobalMaskToggleOff_3;
			int _GlobalMaskToggleOn_4;
			int _GlobalMaskToggleOff_4;
			int _GlobalMaskToggleOn_5;
			int _GlobalMaskToggleOff_5;
			int _GlobalMaskToggleOn_6;
			int _GlobalMaskToggleOff_6;
			int _GlobalMaskToggleOn_7;
			int _GlobalMaskToggleOff_7;
			int _GlobalMaskToggleOn_8;
			int _GlobalMaskToggleOff_8;
			int _GlobalMaskToggleOn_9;
			int _GlobalMaskToggleOff_9;
			int _GlobalMaskToggleOn_10;
			int _GlobalMaskToggleOff_10;
			int _GlobalMaskToggleOn_11;
			int _GlobalMaskToggleOff_11;
			int _GlobalMaskToggleOn_12;
			int _GlobalMaskToggleOff_12;
			int _GlobalMaskToggleOn_13;
			int _GlobalMaskToggleOff_13;
			int _GlobalMaskToggleOn_14;
			int _GlobalMaskToggleOff_14;
			int _GlobalMaskToggleOn_15;
			int _GlobalMaskToggleOff_15;
			//endex
			//endex
			//ifex _GlobalMaskModifiersBackfaceEnable==0
			float _GlobalMaskModifiersBackfaceEnable;
			float _GlobalMaskBackface_0;
			float _GlobalMaskBackface_1;
			float _GlobalMaskBackface_2;
			float _GlobalMaskBackface_3;
			float _GlobalMaskBackface_4;
			float _GlobalMaskBackface_5;
			float _GlobalMaskBackface_6;
			float _GlobalMaskBackface_7;
			float _GlobalMaskBackface_8;
			float _GlobalMaskBackface_9;
			float _GlobalMaskBackface_10;
			float _GlobalMaskBackface_11;
			float _GlobalMaskBackface_12;
			float _GlobalMaskBackface_13;
			float _GlobalMaskBackface_14;
			float _GlobalMaskBackface_15;
			//endex
			
			//ifex _GlobalMaskModifiersMirrorEnable==0
			float _GlobalMaskModifiersMirrorEnable;
			float _GlobalMaskMirrorVisibilityMode;
			float _GlobalMaskMirror_0;
			float _GlobalMaskMirror_1;
			float _GlobalMaskMirror_2;
			float _GlobalMaskMirror_3;
			float _GlobalMaskMirror_4;
			float _GlobalMaskMirror_5;
			float _GlobalMaskMirror_6;
			float _GlobalMaskMirror_7;
			float _GlobalMaskMirror_8;
			float _GlobalMaskMirror_9;
			float _GlobalMaskMirror_10;
			float _GlobalMaskMirror_11;
			float _GlobalMaskMirror_12;
			float _GlobalMaskMirror_13;
			float _GlobalMaskMirror_14;
			float _GlobalMaskMirror_15;
			//endex
			
			//ifex _GlobalMaskModifiersCameraEnable==0
			float _GlobalMaskModifiersCameraEnable;
			float _GlobalMaskCamera_0;
			float _GlobalMaskCamera_1;
			float _GlobalMaskCamera_2;
			float _GlobalMaskCamera_3;
			float _GlobalMaskCamera_4;
			float _GlobalMaskCamera_5;
			float _GlobalMaskCamera_6;
			float _GlobalMaskCamera_7;
			float _GlobalMaskCamera_8;
			float _GlobalMaskCamera_9;
			float _GlobalMaskCamera_10;
			float _GlobalMaskCamera_11;
			float _GlobalMaskCamera_12;
			float _GlobalMaskCamera_13;
			float _GlobalMaskCamera_14;
			float _GlobalMaskCamera_15;
			//endex
			
			//ifex _GlobalMaskModifiersDistanceEnable==0
			int _GlobalMaskModifiersDistanceEnable;
			
			//ifex _GlobalMaskDistanceEnable_0==0
			int _GlobalMaskDistanceEnable_0;
			int _GlobalMaskDistanceType_0;
			float _GlobalMaskDistanceMin_0;
			float _GlobalMaskDistanceMax_0;
			float _GlobalMaskDistanceMinAlpha_0;
			float _GlobalMaskDistanceMaxAlpha_0;
			int _GlobalMaskDistanceBlendType_0;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_1==0
			int _GlobalMaskDistanceEnable_1;
			int _GlobalMaskDistanceType_1;
			float _GlobalMaskDistanceMin_1;
			float _GlobalMaskDistanceMax_1;
			float _GlobalMaskDistanceMinAlpha_1;
			float _GlobalMaskDistanceMaxAlpha_1;
			int _GlobalMaskDistanceBlendType_1;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_2==0
			int _GlobalMaskDistanceEnable_2;
			int _GlobalMaskDistanceType_2;
			float _GlobalMaskDistanceMin_2;
			float _GlobalMaskDistanceMax_2;
			float _GlobalMaskDistanceMinAlpha_2;
			float _GlobalMaskDistanceMaxAlpha_2;
			int _GlobalMaskDistanceBlendType_2;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_3==0
			int _GlobalMaskDistanceEnable_3;
			int _GlobalMaskDistanceType_3;
			float _GlobalMaskDistanceMin_3;
			float _GlobalMaskDistanceMax_3;
			float _GlobalMaskDistanceMinAlpha_3;
			float _GlobalMaskDistanceMaxAlpha_3;
			int _GlobalMaskDistanceBlendType_3;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_4==0
			int _GlobalMaskDistanceEnable_4;
			int _GlobalMaskDistanceType_4;
			float _GlobalMaskDistanceMin_4;
			float _GlobalMaskDistanceMax_4;
			float _GlobalMaskDistanceMinAlpha_4;
			float _GlobalMaskDistanceMaxAlpha_4;
			int _GlobalMaskDistanceBlendType_4;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_5==0
			int _GlobalMaskDistanceEnable_5;
			int _GlobalMaskDistanceType_5;
			float _GlobalMaskDistanceMin_5;
			float _GlobalMaskDistanceMax_5;
			float _GlobalMaskDistanceMinAlpha_5;
			float _GlobalMaskDistanceMaxAlpha_5;
			int _GlobalMaskDistanceBlendType_5;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_6==0
			int _GlobalMaskDistanceEnable_6;
			int _GlobalMaskDistanceType_6;
			float _GlobalMaskDistanceMin_6;
			float _GlobalMaskDistanceMax_6;
			float _GlobalMaskDistanceMinAlpha_6;
			float _GlobalMaskDistanceMaxAlpha_6;
			int _GlobalMaskDistanceBlendType_6;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_7==0
			int _GlobalMaskDistanceEnable_7;
			int _GlobalMaskDistanceType_7;
			float _GlobalMaskDistanceMin_7;
			float _GlobalMaskDistanceMax_7;
			float _GlobalMaskDistanceMinAlpha_7;
			float _GlobalMaskDistanceMaxAlpha_7;
			int _GlobalMaskDistanceBlendType_7;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_8==0
			int _GlobalMaskDistanceEnable_8;
			int _GlobalMaskDistanceType_8;
			float _GlobalMaskDistanceMin_8;
			float _GlobalMaskDistanceMax_8;
			float _GlobalMaskDistanceMinAlpha_8;
			float _GlobalMaskDistanceMaxAlpha_8;
			int _GlobalMaskDistanceBlendType_8;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_9==0
			int _GlobalMaskDistanceEnable_9;
			int _GlobalMaskDistanceType_9;
			float _GlobalMaskDistanceMin_9;
			float _GlobalMaskDistanceMax_9;
			float _GlobalMaskDistanceMinAlpha_9;
			float _GlobalMaskDistanceMaxAlpha_9;
			int _GlobalMaskDistanceBlendType_9;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_10==0
			int _GlobalMaskDistanceEnable_10;
			int _GlobalMaskDistanceType_10;
			float _GlobalMaskDistanceMin_10;
			float _GlobalMaskDistanceMax_10;
			float _GlobalMaskDistanceMinAlpha_10;
			float _GlobalMaskDistanceMaxAlpha_10;
			int _GlobalMaskDistanceBlendType_10;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_11==0
			int _GlobalMaskDistanceEnable_11;
			int _GlobalMaskDistanceType_11;
			float _GlobalMaskDistanceMin_11;
			float _GlobalMaskDistanceMax_11;
			float _GlobalMaskDistanceMinAlpha_11;
			float _GlobalMaskDistanceMaxAlpha_11;
			int _GlobalMaskDistanceBlendType_11;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_12==0
			int _GlobalMaskDistanceEnable_12;
			int _GlobalMaskDistanceType_12;
			float _GlobalMaskDistanceMin_12;
			float _GlobalMaskDistanceMax_12;
			float _GlobalMaskDistanceMinAlpha_12;
			float _GlobalMaskDistanceMaxAlpha_12;
			int _GlobalMaskDistanceBlendType_12;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_13==0
			int _GlobalMaskDistanceEnable_13;
			int _GlobalMaskDistanceType_13;
			float _GlobalMaskDistanceMin_13;
			float _GlobalMaskDistanceMax_13;
			float _GlobalMaskDistanceMinAlpha_13;
			float _GlobalMaskDistanceMaxAlpha_13;
			int _GlobalMaskDistanceBlendType_13;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_14==0
			int _GlobalMaskDistanceEnable_14;
			int _GlobalMaskDistanceType_14;
			float _GlobalMaskDistanceMin_14;
			float _GlobalMaskDistanceMax_14;
			float _GlobalMaskDistanceMinAlpha_14;
			float _GlobalMaskDistanceMaxAlpha_14;
			int _GlobalMaskDistanceBlendType_14;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_15==0
			int _GlobalMaskDistanceEnable_15;
			int _GlobalMaskDistanceType_15;
			float _GlobalMaskDistanceMin_15;
			float _GlobalMaskDistanceMax_15;
			float _GlobalMaskDistanceMinAlpha_15;
			float _GlobalMaskDistanceMaxAlpha_15;
			int _GlobalMaskDistanceBlendType_15;
			//endex
			//endex
			
			int _GlobalMaskVertexColorLinearSpace;
			//ifex _GlobalMaskVertexColorRed==0
			int _GlobalMaskVertexColorRed;
			int _GlobalMaskVertexColorRedBlendType;
			//endex
			//ifex _GlobalMaskVertexColorGreen==0
			int _GlobalMaskVertexColorGreen;
			int _GlobalMaskVertexColorGreenBlendType;
			//endex
			//ifex _GlobalMaskVertexColorBlue==0
			int _GlobalMaskVertexColorBlue;
			int _GlobalMaskVertexColorBlueBlendType;
			//endex
			//ifex _GlobalMaskVertexColorAlpha==0
			int _GlobalMaskVertexColorAlpha;
			int _GlobalMaskVertexColorAlphaBlendType;
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#ifdef POI_UDIMDISCARD
			float _UDIMDiscardMode;
			float _UDIMDiscardUV;
			float _UDIMDiscardRow3_0;
			float _UDIMDiscardRow3_1;
			float _UDIMDiscardRow3_2;
			float _UDIMDiscardRow3_3;
			float _UDIMDiscardRow2_0;
			float _UDIMDiscardRow2_1;
			float _UDIMDiscardRow2_2;
			float _UDIMDiscardRow2_3;
			float _UDIMDiscardRow1_0;
			float _UDIMDiscardRow1_1;
			float _UDIMDiscardRow1_2;
			float _UDIMDiscardRow1_3;
			float _UDIMDiscardRow0_0;
			float _UDIMDiscardRow0_1;
			float _UDIMDiscardRow0_2;
			float _UDIMDiscardRow0_3;
			#endif
			//endex
			
			//ifex _EnableDistortion==0
			#ifdef USER_LUT
			#if defined(PROP_DISTORTIONFLOWTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionFlowTexture;
			float4 _DistortionFlowTexture_ST;
			float2 _DistortionFlowTexturePan;
			float _DistortionFlowTextureUV;
			#endif
			
			#if defined(PROP_DISTORTIONFLOWTEXTURE1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionFlowTexture1;
			float4 _DistortionFlowTexture1_ST;
			float2 _DistortionFlowTexture1Pan;
			float _DistortionFlowTexture1UV;
			#endif
			
			#if defined(PROP_DISTORTIONMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionMask;
			float4 _DistortionMask_ST;
			float2 _DistortionMaskPan;
			float _DistortionMaskUV;
			float _DistortionMaskChannel;
			#endif
			
			float _DistortionUvToDistort;
			float _DistortionStrength;
			float _DistortionStrength1;
			
			#ifdef POI_AUDIOLINK
			half _EnableDistortionAudioLink;
			half2 _DistortionStrengthAudioLink;
			half _DistortionStrengthAudioLinkBand;
			half2 _DistortionStrength1AudioLink;
			half _DistortionStrength1AudioLinkBand;
			#endif
			#endif
			//endex
			float _StereoEnabled;
			float _PolarUV;
			float2 _PolarCenter;
			float _PolarRadialScale;
			float _PolarLengthScale;
			float _PolarSpiralPower;
			float _PanoUseBothEyes;
			
			float _UVModWorldPos0;
			float _UVModWorldPos1;
			float _UVModLocalPos0;
			float _UVModLocalPos1;
			
			//ifex _PoiParallax==0
			#ifdef POI_PARALLAX
			
			sampler2D _HeightMap;
			float4 _HeightMap_ST;
			float2 _HeightMapPan;
			float _HeightMapUV;
			
			#if defined(PROP_HEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Heightmask;
			float4 _Heightmask_ST;
			float2 _HeightmaskPan;
			float _HeightmaskUV;
			float _HeightmaskChannel;
			float _HeightmaskInvert;
			SamplerState _linear_repeat;
			#endif
			
			float _ParallaxUV;
			float _HeightStrength;
			float _HeightOffset;
			float _HeightStepsMin;
			float _HeightStepsMax;
			
			float _CurvatureU;
			float _CurvatureV;
			float _CurvFix;
			#endif
			//endex
			
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			float _AudioLinkDelay;
			float _AudioLinkAnimToggle;
			
			float _AudioLinkSmoothingBass;
			float _AudioLinkSmoothingLowMid;
			float _AudioLinkSmoothingHighMid;
			float _AudioLinkSmoothingTreble;
			
			float _DebugWaveform;
			float _DebugDFT;
			float _DebugBass;
			float _DebugLowMids;
			float _DebugHighMids;
			float _DebugTreble;
			float _DebugCCColors;
			float _DebugCCStrip;
			float _DebugCCLights;
			float _DebugAutocorrelator;
			float _DebugChronotensity;
			float _AudioLinkCCStripY;
			
			float _AudioLinkBandOverridesEnabled;
			float4 _AudioLinkBandOverrideSliders;
			#endif
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#ifdef POI_BLACKLIGHTMASKING
			float _BlackLightMasking0Key;
			float2 _BlackLightMasking0Range;
			float _BlackLightMasking0GlobalMaskIndex;
			float _BlackLightMasking0GlobalMaskBlendType;
			
			float _BlackLightMasking1Key;
			float2 _BlackLightMasking1Range;
			float _BlackLightMasking1GlobalMaskIndex;
			float _BlackLightMasking1GlobalMaskBlendType;
			
			float _BlackLightMasking2Key;
			float2 _BlackLightMasking2Range;
			float _BlackLightMasking2GlobalMaskIndex;
			float _BlackLightMasking2GlobalMaskBlendType;
			
			float _BlackLightMasking3Key;
			float2 _BlackLightMasking3Range;
			float _BlackLightMasking3GlobalMaskIndex;
			float _BlackLightMasking3GlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _DetailEnabled==0
			#ifdef FINALPASS
			#if defined(PROP_DETAILMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DetailMask;
			#endif
			float4 _DetailMask_ST;
			float2 _DetailMaskPan;
			float _DetailMaskUV;
			float _DetailMaskStochastic;
			
			#if defined(PROP_DETAILNORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DetailNormalMap;
			#endif
			float4 _DetailNormalMap_ST;
			float2 _DetailNormalMapPan;
			float _DetailNormalMapUV;
			float _DetailNormalMapScale;
			float _DetailNormalMapStochastic;
			float _DetailNormalGlobalMask;
			float _DetailNormalGlobalMaskBlendType;
			
			#if defined(PROP_DETAILTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DetailTex;
			#endif
			float4 _DetailTex_ST;
			float2 _DetailTexPan;
			float _DetailTexUV;
			float _DetailTexStochastic;
			
			float3 _DetailTint;
			float _DetailTintThemeIndex;
			float _DetailTexIntensity;
			float _DetailBrightness;
			float _DetailTexGlobalMask;
			float _DetailTexGlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _VertexManipulationsEnabled==0
			#ifdef AUTO_EXPOSURE
			float4 _VertexManipulationLocalTranslation;
			float4 _VertexManipulationLocalRotation;
			float3 _VertexManipulationLocalRotationSpeed;
			float4 _VertexManipulationLocalScale;
			float4 _VertexManipulationWorldTranslation;
			float _VertexManipulationHeight;
			sampler2D _VertexManipulationHeightMask;
			float4 _VertexManipulationHeightMask_ST;
			float2 _VertexManipulationHeightMaskPan;
			float _VertexManipulationHeightMaskUV;
			float _VertexManipulationHeightMaskChannel;
			float _VertexManipulationHeightBias;
			float _VertexRoundingEnabled;
			int _VertexRoundingSpace;
			float _VertexRoundingDivision;
			
			//AL
			float _VertexAudioLinkEnabled;
			float3 _VertexLocalTranslationALMin;
			float3 _VertexLocalTranslationALMax;
			float _VertexLocalTranslationALBand;
			
			float3 _VertexLocalRotationAL;
			float _VertexLocalRotationALBand;
			
			float3 _VertexLocalRotationCTALSpeed;
			float _VertexLocalRotationCTALBandX;
			float _VertexLocalRotationCTALBandY;
			float _VertexLocalRotationCTALBandZ;
			float _VertexLocalRotationCTALTypeX;
			float _VertexLocalRotationCTALTypeY;
			float _VertexLocalRotationCTALTypeZ;
			
			float4 _VertexLocalScaleALMin;
			float4 _VertexLocalScaleALMax;
			float _VertexLocalScaleALBand;
			
			float3 _VertexWorldTranslationALMin;
			float3 _VertexWorldTranslationALMax;
			float _VertexWorldTranslationALBand;
			
			float2 _VertexManipulationHeightAL;
			float _VertexManipulationHeightBand;
			
			float2 _VertexRoundingRangeAL;
			float _VertexRoundingRangeBand;
			
			float _VertexBarrelMode;
			float _VertexBarrelWidth;
			float _VertexBarrelAlpha;
			float _VertexBarrelHeight;
			
			float _VertexSphereMode;
			float _VertexSphereRadius;
			float _VertexSphereHeight;
			float _VertexSphereAlpha;
			float4 _VertexSphereCenter;
			
			float _VertexTornadoMode;
			float _VertexTornadoRadius;
			float _VertexTornadoSpeed;
			float _VertexTornadoIntensity;
			float _VertexTornadoBaseHeight;
			float _VertexTornadoTopHeight;
			
			float _VertexSpectrumMotion;
			float3 _VertexSpectrumOffsetMin;
			float3 _VertexSpectrumOffsetMax;
			float _VertexSpectrumUV;
			float _VertexSpectrumUVDirection;
			#endif
			//endex
			
			//ifex _VertexGlitchingEnabled==0
			#ifdef POI_VERTEX_GLITCHING
			//Vertex Glitching
			#if defined(POI_VERTEX_GLITCHING_TEXTURE)
			float _VertexGlitchingUseTexture;
			sampler2D _VertexGlitchMap;
			float4 _VertexGlitchMap_ST;
			#endif
			float _VertexGlitchThreshold;
			float _VertexGlitchFrequency;
			float _VertexGlitchStrength;
			float _VertexGlitchDensity;
			
			float _VertexGlitchMirrorEnable;
			float _VertexGlitchMirror;
			
			float _VertexGlitchMapPanSpeed;
			float _VertexGlitchingAudioLinkEnabled;
			float _VertexGlitchingAudioLinkBand;
			float _VertexGlitchingAudiolinkOverride;
			#endif
			//endex
			
			//ifex _EnableDepthBulge==0
			#ifdef POI_DEPTHBULGE
			float _DepthBulgeFadeLength;
			float _DepthBulgeHeight;
			
			#if defined(PROP_DEPTHBULGEMASK) || !defined(OPTIMIZER_ENABLED)
			sampler2D _DepthBulgeMask;
			#endif
			float _DepthBulgeMaskUV;
			float4 _DepthBulgeMask_ST;
			float _DepthBulgeMaskChannel;
			#endif
			//endex
			
			//ifex _MainVertexColoringEnabled==0
			float _MainVertexColoringEnabled;
			float _MainVertexColoringLinearSpace;
			float _MainVertexColoring;
			float _MainUseVertexColorAlpha;
			//endex
			
			//ifex _BackFaceEnabled!=1
			#ifdef POI_BACKFACE
			float _BackFaceEnabled;
			float _BackFaceDetailIntensity;
			float _BackFaceEmissionStrength;
			float2 _BackFacePanning;
			float4 _BackFaceColor;
			float _BackFaceColorThemeIndex;
			float _BackFaceReplaceAlpha;
			
			#if defined(PROP_BACKFACETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BackFaceTexture;
			#endif
			float4 _BackFaceTexture_ST;
			float2 _BackFaceTexturePan;
			float _BackFaceTextureUV;
			
			#if defined(PROP_BACKFACEMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BackFaceMask;
			#endif
			float4 _BackFaceMask_ST;
			float2 _BackFaceMaskPan;
			float _BackFaceMaskUV;
			float _BackFaceMaskChannel;
			
			float _BackFaceHueShiftEnabled;
			float _BackFaceHueShift;
			float _BackFaceHueShiftSpeed;
			float _BackFaceEmissionLimiter;
			#endif
			
			//TODO detail strength stuff
			//endex
			
			//ifex _RGBMaskEnabled==0
			#ifdef VIGNETTE
			#if defined(PROP_RGBMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RGBMask;
			#endif
			float4 _RGBMask_ST;
			float2 _RGBMaskPan;
			float _RGBMaskUV;
			
			#if defined(PROP_RGBAMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RGBAMetallicMaps;
			float4 _RGBAMetallicMaps_ST;
			float2 _RGBAMetallicMapsPan;
			float _RGBAMetallicMapsUV;
			float _RGBAMetallicMapsStochastic;
			#endif
			float _RGBARedMetallicInvert;
			float _RGBAGreenMetallicInvert;
			float _RGBABlueMetallicInvert;
			float _RGBAAlphaMetallicInvert;
			float _RGBAMetallicRedEnabled;
			float _RGBAMetallicGreenEnabled;
			float _RGBAMetallicBlueEnabled;
			float _RGBAMetallicAlphaEnabled;
			
			float _RGBARedPBRSplitMaskSample;
			float4 _RGBARedPBRMaskScaleTiling;
			float2 _RGBARedPBRMasksPan;
			float _RGBARedPBRUV;
			float _RGBARedPBRSplitMaskStochastic;
			
			float _RGBAGreenPBRSplitMaskSample;
			float4 _RGBAGreenPBRMaskScaleTiling;
			float2 _RGBAGreenPBRMasksPan;
			float _RGBAGreenPBRUV;
			float _RGBAGreenPBRSplitMaskStochastic;
			
			float _RGBABluePBRSplitMaskSample;
			float4 _RGBABluePBRMaskScaleTiling;
			float2 _RGBABluePBRMasksPan;
			float _RGBABluePBRUV;
			float _RGBABluePBRSplitMaskStochastic;
			
			float _RGBAAlphaPBRSplitMaskSample;
			float4 _RGBAAlphaPBRMaskScaleTiling;
			float2 _RGBAAlphaPBRMasksPan;
			float _RGBAAlphaPBRUV;
			float _RGBAAlphaPBRSplitMaskStochastic;
			
			float _RGBAPBRRedEnabled;
			float _RGBAPBRGreenEnabled;
			float _RGBAPBRBlueEnabled;
			float _RGBAPBRAlphaEnabled;
			
			#if defined(PROP_RGBASMOOTHNESSMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RGBASmoothnessMaps;
			float4 _RGBASmoothnessMaps_ST;
			float4 _RGBASmoothnessMapsPan;
			float _RGBASmoothnessMapsUV;
			float _RGBASmoothnessMapsStochastic;
			#endif
			float _RGBARedSmoothnessInvert;
			float _RGBAGreenSmoothnessInvert;
			float _RGBABlueSmoothnessInvert;
			float _RGBAAlphaSmoothnessInvert;
			
			float _RGBARedEnable;
			#if defined(PROP_REDTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RedTexture;
			#endif
			float4 _RedTexture_ST;
			float2 _RedTexturePan;
			float _RedTextureUV;
			float _RedAlphaAdd;
			float _RedTextureStochastic;
			float _RgbRedMaskChannel;
			float _RgbRedGlobalMaskChannel;
			float _RgbRedGlobalMaskBlendType;
			float _RGBARedBlendType;
			float4 _RedColor;
			float _RedColorThemeIndex;
			float _RGBARedEmissionStrength;
			
			#if defined(PROP_RGBNORMALR) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RgbNormalR;
			#endif
			float4 _RgbNormalR_ST;
			float2 _RgbNormalRPan;
			float _RgbNormalRUV;
			float _RgbNormalRScale;
			float _RgbNormalRStochastic;
			float _RgbNormalRMaskChannel;
			float _RgbNormalRGlobalMaskChannel;
			float _RgbNormalRGlobalMaskBlendType;
			float _RgbNormalRedBlendMode;
			
			float _RGBAGreenEnable;
			#if defined(PROP_GREENTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GreenTexture;
			#endif
			float4 _GreenTexture_ST;
			float2 _GreenTexturePan;
			float _GreenTextureUV;
			float _GreenAlphaAdd;
			float _GreenTextureStochastic;
			float _RgbGreenMaskChannel;
			float _RgbGreenGlobalMaskChannel;
			float _RgbGreenGlobalMaskBlendType;
			float _RGBAGreenBlendType;
			float4 _GreenColor;
			float _GreenColorThemeIndex;
			float _RGBAGreenEmissionStrength;
			
			#if defined(PROP_RGBNORMALG) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RgbNormalG;
			#endif
			float4 _RgbNormalG_ST;
			float2 _RgbNormalGPan;
			float _RgbNormalGUV;
			float _RgbNormalGScale;
			float _RgbNormalGStochastic;
			float _RgbNormalGMaskChannel;
			float _RgbNormalGGlobalMaskChannel;
			float _RgbNormalGGlobalMaskBlendType;
			float _RgbNormalGreenBlendMode;
			
			float _RGBABlueEnable;
			#if defined(PROP_BLUETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BlueTexture;
			#endif
			float4 _BlueTexture_ST;
			float2 _BlueTexturePan;
			float _BlueTextureUV;
			float _BlueAlphaAdd;
			float _BlueTextureStochastic;
			float _RgbBlueMaskChannel;
			float _RgbBlueGlobalMaskChannel;
			float _RgbBlueGlobalMaskBlendType;
			float _RGBABlueBlendType;
			float4 _BlueColor;
			float _BlueColorThemeIndex;
			float _RGBABlueEmissionStrength;
			
			#if defined(PROP_RGBNORMALB) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RgbNormalB;
			#endif
			float4 _RgbNormalB_ST;
			float2 _RgbNormalBPan;
			float _RgbNormalBUV;
			float _RgbNormalBScale;
			float _RgbNormalBStochastic;
			float _RgbNormalBMaskChannel;
			float _RgbNormalBGlobalMaskChannel;
			float _RgbNormalBGlobalMaskBlendType;
			float _RgbNormalBlueBlendMode;
			
			float _RGBAAlphaEnable;
			#if defined(PROP_ALPHATEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AlphaTexture;
			#endif
			float4 _AlphaTexture_ST;
			float2 _AlphaTexturePan;
			float _AlphaTextureUV;
			float _AlphaAlphaAdd;
			float _AlphaTextureStochastic;
			float _RgbAlphaMaskChannel;
			float _RgbAlphaGlobalMaskChannel;
			float _RgbAlphaGlobalMaskBlendType;
			float _RGBAAlphaBlendType;
			float4 _AlphaColor;
			float _AlphaColorThemeIndex;
			float _RGBAAlphaEmissionStrength;
			
			#if defined(PROP_RGBNORMALA) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RgbNormalA;
			#endif
			float4 _RgbNormalA_ST;
			float2 _RgbNormalAPan;
			float _RgbNormalAUV;
			float _RgbNormalAScale;
			float _RgbNormalAStochastic;
			float _RgbNormalAMaskChannel;
			float _RgbNormalAGlobalMaskChannel;
			float _RgbNormalAGlobalMaskBlendType;
			float _RgbNormalAlphaBlendMode;
			
			float _RGBMaskType;
			
			#endif
			//endex
			
			//ifex _LTCGIEnabled!=1
			#ifdef POI_LTCGI
			float4 _LTCGI_DiffuseColor;
			int _LTCGI_DiffuseColorThemeIndex;
			float4 _LTCGI_SpecularColor;
			int _LTCGI_SpecularColorThemeIndex;
			float _LTCGI_Smoothness;
			float _LTCGI_Metallic;
			int _LTCGI_UsePBR;
			int _LTCGI_AnimToggle;
			#endif
			//endex
			
			//ifex _ShadingEnabled==0
			float _ShadowStrength;
			float _LightingIgnoreAmbientColor;
			float3 _LightingShadowColor;
			
			float _ShadingRampedLightMapApplyGlobalMaskIndex;
			float _ShadingRampedLightMapApplyGlobalMaskBlendType;
			
			float _ShadingRampedLightMapInverseApplyGlobalMaskIndex;
			float _ShadingRampedLightMapInverseApplyGlobalMaskBlendType;
			
			// Toon Lighting
			#ifdef _LIGHTINGMODE_TEXTURERAMP
			UNITY_DECLARE_TEX2D(_ToonRamp);
			float _ShadowOffset;
			int _ToonRampCount;
			int _ToonRampUVSelector;
			#endif
			
			#ifdef _LIGHTINGMODE_WRAPPED
			float4 _LightingWrappedColor;
			float _LightingWrappedWrap;
			float _LightingWrappedNormalization;
			float _LightingGradientStart;
			float _LightingGradientEnd;
			#endif
			
			#ifdef _LIGHTINGMODE_SHADEMAP
			float3 _1st_ShadeColor;
			#if defined(PROP_1ST_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _1st_ShadeMap;
			#endif
			float4 _1st_ShadeMap_ST;
			float2 _1st_ShadeMapPan;
			float _1st_ShadeMapUV;
			float _Use_1stShadeMapAlpha_As_ShadowMask;
			float _1stShadeMapMask_Inverse;
			float _Use_BaseAs1st;
			float3 _2nd_ShadeColor;
			#if defined(PROP_2ND_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _2nd_ShadeMap;
			#endif
			float4 _2nd_ShadeMap_ST;
			float2 _2nd_ShadeMapPan;
			float _2nd_ShadeMapUV;
			float _Use_2ndShadeMapAlpha_As_ShadowMask;
			float _2ndShadeMapMask_Inverse;
			float _Use_1stAs2nd;
			float _BaseColor_Step;
			float _BaseShade_Feather;
			float _ShadeColor_Step;
			float _1st2nd_Shades_Feather;
			float _ShadingShadeMapBlendType;
			#endif
			
			#ifdef _LIGHTINGMODE_SKIN
			sampler2D _SkinLUT;
			float _SssScale;
			#if defined(PROP_SKINTHICKNESS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _SkinThicknessMap;
			#endif
			float4 _SkinThicknessMap_ST;
			float2 _SkinThicknessMapPan;
			float _SkinThicknessMapUV;
			float _SkinThicknessMapInvert;
			float _SkinThicknessPower;
			float _SssBumpBlur;
			float3 _SssTransmissionAbsorption;
			float3 _SssColorBleedAoWeights;
			#endif
			
			#ifdef _LIGHTINGMODE_MULTILAYER_MATH
			float _ShadowBorderMapToggle;
			#if defined(PROP_SHADOWBORDERMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ShadowBorderMask;
			float4 _ShadowBorderMask_ST;
			float2 _ShadowBorderMaskPan;
			float _ShadowBorderMaskUV;
			#endif
			float _ShadowPostAO;
			float _ShadowBorderMaskLOD;
			float4 _ShadowAOShift;
			float4 _ShadowAOShift2;
			
			float4 _ShadowColor;
			float _LightingMulitlayerNonLinear;
			#if defined(PROP_SHADOWCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ShadowColorTex;
			float4 _ShadowColorTex_ST;
			float2 _ShadowColorTexPan;
			float _ShadowColorTexUV;
			#endif
			#if defined(PROP_MULTILAYERMATHBLURMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MultilayerMathBlurMap;
			float4 _MultilayerMathBlurMap_ST;
			float2 _MultilayerMathBlurMapPan;
			float _MultilayerMathBlurMapUV;
			#endif
			float _ShadowBorder;
			float _ShadowBlur;
			float _ShadowReceive;
			float4 _Shadow2ndColor;
			#if defined(PROP_SHADOW2NDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Shadow2ndColorTex;
			float4 _Shadow2ndColorTex_ST;
			float2 _Shadow2ndColorTexPan;
			float _Shadow2ndColorTexUV;
			#endif
			float _Shadow2ndBorder;
			float _Shadow2ndBlur;
			float _Shadow2ndReceive;
			float4 _Shadow3rdColor;
			#if defined(PROP_SHADOW3RDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Shadow3rdColorTex;
			float4 _Shadow3rdColorTex_ST;
			float2 _Shadow3rdColorTexPan;
			float _Shadow3rdColorTexUV;
			#endif
			float _Shadow3rdBorder;
			float _Shadow3rdBlur;
			float _Shadow3rdReceive;
			float4 _ShadowBorderColor;
			float _ShadowBorderRange;
			float _ShadowMainStrength;
			#endif
			
			#ifdef _LIGHTINGMODE_FLAT
			float _ForceFlatRampedLightmap;
			#endif
			
			#ifdef _LIGHTINGMODE_CLOTH
			Texture2D_float _ClothDFG;
			SamplerState sampler_ClothDFG;
			
			#if defined(PROP_CLOTHMETALLICSMOOTHNESSMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ClothMetallicSmoothnessMap;
			#endif
			
			float4 _ClothMetallicSmoothnessMap_ST;
			float2 _ClothMetallicSmoothnessMapPan;
			float _ClothMetallicSmoothnessMapUV;
			float _ClothMetallicSmoothnessMapInvert;
			
			float _ClothLerp;
			float _ClothMetallic;
			float _ClothReflectance;
			float _ClothSmoothness;
			#endif
			
			#ifdef _LIGHTINGMODE_SDF
			#if defined(PROP_SDFSHADINGTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _SDFShadingTexture;
			float _SDFShadingTextureUV;
			float2 _SDFShadingTexturePan;
			float4 _SDFShadingTexture_ST;
			float _SDFBlur;
			float4 _SDFForward;
			float4 _SDFLeft;
			#endif
			#endif
			
			// Additive
			float _LightingAdditiveType;
			float _LightingAdditiveGradientStart;
			float _LightingAdditiveGradientEnd;
			float _LightingAdditiveDetailStrength;
			//endex
			
			//ifex _DecalEnabled==0 && _DecalEnabled1==0 && _DecalEnabled2==0 && _DecalEnabled3==0
			
			#if defined(PROP_DECALMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DecalMask;
			float4 _DecalMask_ST;
			float2 _DecalMaskPan;
			float _DecalMaskUV;
			#endif
			float _DecalTPSDepthMaskEnabled;
			float _Decal0TPSMaskStrength;
			float _Decal1TPSMaskStrength;
			float _Decal2TPSMaskStrength;
			float _Decal3TPSMaskStrength;
			
			sampler2D _Udon_VideoTex;
			float4 _Udon_VideoTex_TexelSize;
			
			#ifdef POI_AUDIOLINK
			//ifex _DecalEnabled==0
			#ifdef GEOM_TYPE_BRANCH
			// Audio Link
			half _AudioLinkDecal0ScaleBand;
			float4 _AudioLinkDecal0Scale;
			half _AudioLinkDecal0RotationBand;
			float2 _AudioLinkDecal0Rotation;
			half _AudioLinkDecal0AlphaBand;
			float2 _AudioLinkDecal0Alpha;
			half _AudioLinkDecal0EmissionBand;
			float2 _AudioLinkDecal0Emission;
			float _DecalRotationCTALBand0;
			float _DecalRotationCTALSpeed0;
			float _DecalRotationCTALType0;
			float _AudioLinkDecalCC0;
			float _AudioLinkDecal0SideBand;
			float4 _AudioLinkDecal0SideMin;
			float4 _AudioLinkDecal0SideMax;
			float2 _AudioLinkDecal0ChannelSeparation;
			float _AudioLinkDecal0ChannelSeparationBand;
			#endif //GEOM_TYPE_BRANCH
			//endex
			//ifex _DecalEnabled1==0
			#ifdef GEOM_TYPE_BRANCH_DETAIL
			half _AudioLinkDecal1ScaleBand;
			float4 _AudioLinkDecal1Scale;
			half _AudioLinkDecal1RotationBand;
			float2 _AudioLinkDecal1Rotation;
			half _AudioLinkDecal1AlphaBand;
			float2 _AudioLinkDecal1Alpha;
			half _AudioLinkDecal1EmissionBand;
			float2 _AudioLinkDecal1Emission;
			float _DecalRotationCTALBand1;
			float _DecalRotationCTALSpeed1;
			float _DecalRotationCTALType1;
			float _AudioLinkDecalCC1;
			float _AudioLinkDecal1SideBand;
			float4 _AudioLinkDecal1SideMin;
			float4 _AudioLinkDecal1SideMax;
			float2 _AudioLinkDecal1ChannelSeparation;
			float _AudioLinkDecal1ChannelSeparationBand;
			#endif //GEOM_TYPE_BRANCH_DETAIL
			//endex
			//ifex _DecalEnabled2==0
			#ifdef GEOM_TYPE_FROND
			half _AudioLinkDecal2ScaleBand;
			float4 _AudioLinkDecal2Scale;
			half _AudioLinkDecal2RotationBand;
			float2 _AudioLinkDecal2Rotation;
			half _AudioLinkDecal2AlphaBand;
			float2 _AudioLinkDecal2Alpha;
			half _AudioLinkDecal2EmissionBand;
			float2 _AudioLinkDecal2Emission;
			float _DecalRotationCTALBand2;
			float _DecalRotationCTALSpeed2;
			float _DecalRotationCTALType2;
			float _AudioLinkDecalCC2;
			float _AudioLinkDecal2SideBand;
			float4 _AudioLinkDecal2SideMin;
			float4 _AudioLinkDecal2SideMax;
			float2 _AudioLinkDecal2ChannelSeparation;
			float _AudioLinkDecal2ChannelSeparationBand;
			#endif //GEOM_TYPE_FROND
			//endex
			//ifex _DecalEnabled3==0
			#ifdef DEPTH_OF_FIELD_COC_VIEW
			half _AudioLinkDecal3ScaleBand;
			float4 _AudioLinkDecal3Scale;
			half _AudioLinkDecal3RotationBand;
			float2 _AudioLinkDecal3Rotation;
			half _AudioLinkDecal3AlphaBand;
			float2 _AudioLinkDecal3Alpha;
			half _AudioLinkDecal3EmissionBand;
			float2 _AudioLinkDecal3Emission;
			float _DecalRotationCTALBand3;
			float _DecalRotationCTALSpeed3;
			float _DecalRotationCTALType3;
			float _AudioLinkDecalCC3;
			float _AudioLinkDecal3SideBand;
			float4 _AudioLinkDecal3SideMin;
			float4 _AudioLinkDecal3SideMax;
			float2 _AudioLinkDecal3ChannelSeparation;
			float _AudioLinkDecal3ChannelSeparationBand;
			#endif //DEPTH_OF_FIELD_COC_VIEW
			//endex
			#endif
			//endex
			//ifex _DecalEnabled==0
			#ifdef GEOM_TYPE_BRANCH
			float _Decal0VideoFitToScale;
			float _Decal0VideoAspectFix;
			float _Decal0VideoEmissionStrength;
			float _Decal0VideoEnabled;
			float _Decal0UseDecalAlpha;
			float _Decal0OnlyVideo;
			sampler2D _DecalTexture;
			float _Decal0FaceMask;
			float _Decal0MaskChannel;
			float _Decal0GlobalMask;
			float _Decal0GlobalMaskBlendType;
			float _Decal0ApplyGlobalMaskIndex;
			float _Decal0ApplyGlobalMaskBlendType;
			float4 _DecalTexture_ST;
			float2 _DecalTexturePan;
			float _DecalTextureUV;
			float4 _DecalColor;
			float _DecalColorThemeIndex;
			float _DecalTiled;
			float _DecalBlendType;
			half _DecalRotation;
			half3 _DecalScale;
			float4 _DecalSideOffset;
			half2 _DecalPosition;
			half _DecalRotationSpeed;
			float _DecalEmissionStrength;
			float _DecalBlendAlpha;
			float _DecalOverrideAlpha;
			float _DecalHueShiftEnabled;
			float _DecalHueShift;
			float _DecalHueShiftSpeed;
			float _Decal0Depth;
			float _Decal0HueAngleStrength;
			float _Decal0ChannelSeparationEnable;
			float _Decal0ChannelSeparation;
			float _Decal0ChannelSeparationPremultiply;
			float _Decal0ChannelSeparationHue;
			float _Decal0ChannelSeparationVertical;
			float _Decal0ChannelSeparationAngleStrength;
			float _Decal0OverrideAlphaMode;
			#endif
			//endex
			
			//ifex _DecalEnabled1==0
			#ifdef GEOM_TYPE_BRANCH_DETAIL
			float _Decal1VideoAspectFix;
			float _Decal1VideoFitToScale;
			float _Decal1VideoEmissionStrength;
			float _Decal1VideoEnabled;
			float _Decal1UseDecalAlpha;
			float _Decal1OnlyVideo;
			float _Decal1TextureToUse;
			sampler2D _DecalTexture1;
			float _Decal1FaceMask;
			float _Decal1MaskChannel;
			float _Decal1GlobalMask;
			float _Decal1GlobalMaskBlendType;
			float _Decal1ApplyGlobalMaskIndex;
			float _Decal1ApplyGlobalMaskBlendType;
			float4 _DecalTexture1_ST;
			float2 _DecalTexture1Pan;
			float _DecalTexture1UV;
			float4 _DecalColor1;
			float _DecalColor1ThemeIndex;
			fixed _DecalTiled1;
			float _DecalBlendType1;
			half _DecalRotation1;
			half3 _DecalScale1;
			float4 _DecalSideOffset1;
			half2 _DecalPosition1;
			half _DecalRotationSpeed1;
			float _DecalEmissionStrength1;
			float _DecalBlendAlpha1;
			float _DecalOverrideAlpha1;
			float _DecalHueShiftEnabled1;
			float _DecalHueShift1;
			float _DecalHueShiftSpeed1;
			float _Decal1Depth;
			float _Decal1HueAngleStrength;
			float _Decal1ChannelSeparationEnable;
			float _Decal1ChannelSeparation;
			float _Decal1ChannelSeparationPremultiply;
			float _Decal1ChannelSeparationHue;
			float _Decal1ChannelSeparationVertical;
			float _Decal1ChannelSeparationAngleStrength;
			float _Decal1OverrideAlphaMode;
			#endif
			//endex
			
			//ifex _DecalEnabled2==0
			#ifdef GEOM_TYPE_FROND
			float _Decal2VideoAspectFix;
			float _Decal2VideoFitToScale;
			float _Decal2VideoEmissionStrength;
			float _Decal2VideoEnabled;
			float _Decal2UseDecalAlpha;
			float _Decal2OnlyVideo;
			float _Decal2TextureToUse;
			sampler2D _DecalTexture2;
			float _Decal2FaceMask;
			float _Decal2MaskChannel;
			float _Decal2GlobalMask;
			float _Decal2GlobalMaskBlendType;
			float _Decal2ApplyGlobalMaskIndex;
			float _Decal2ApplyGlobalMaskBlendType;
			float4 _DecalTexture2_ST;
			float2 _DecalTexture2Pan;
			float _DecalTexture2UV;
			float4 _DecalColor2;
			float _DecalColor2ThemeIndex;
			fixed _DecalTiled2;
			float _DecalBlendType2;
			half _DecalRotation2;
			half3 _DecalScale2;
			float4 _DecalSideOffset2;
			half2 _DecalPosition2;
			half _DecalRotationSpeed2;
			float _DecalEmissionStrength2;
			float _DecalBlendAlpha2;
			float _DecalOverrideAlpha2;
			float _DecalHueShiftEnabled2;
			float _DecalHueShift2;
			float _DecalHueShiftSpeed2;
			float _Decal2Depth;
			float _Decal2HueAngleStrength;
			float _Decal2ChannelSeparationEnable;
			float _Decal2ChannelSeparation;
			float _Decal2ChannelSeparationPremultiply;
			float _Decal2ChannelSeparationHue;
			float _Decal2ChannelSeparationVertical;
			float _Decal2ChannelSeparationAngleStrength;
			float _Decal2OverrideAlphaMode;
			#endif
			//endex
			
			//ifex _DecalEnabled3==0
			#ifdef DEPTH_OF_FIELD_COC_VIEW
			float _Decal3VideoAspectFix;
			float _Decal3VideoFitToScale;
			float _Decal3VideoEmissionStrength;
			float _Decal3VideoEnabled;
			float _Decal3UseDecalAlpha;
			float _Decal3OnlyVideo;
			float _Decal3TextureToUse;
			sampler2D _DecalTexture3;
			float _Decal3FaceMask;
			float _Decal3MaskChannel;
			float _Decal3GlobalMask;
			float _Decal3GlobalMaskBlendType;
			float _Decal3ApplyGlobalMaskIndex;
			float _Decal3ApplyGlobalMaskBlendType;
			float4 _DecalTexture3_ST;
			float2 _DecalTexture3Pan;
			float _DecalTexture3UV;
			float4 _DecalColor3;
			float _DecalColor3ThemeIndex;
			fixed _DecalTiled3;
			float _DecalBlendType3;
			half _DecalRotation3;
			half3 _DecalScale3;
			float4 _DecalSideOffset3;
			half2 _DecalPosition3;
			half _DecalRotationSpeed3;
			float _DecalEmissionStrength3;
			float _DecalBlendAlpha3;
			float _DecalOverrideAlpha3;
			float _DecalHueShiftEnabled3;
			float _DecalHueShift3;
			float _DecalHueShiftSpeed3;
			float _Decal3Depth;
			float _Decal3HueAngleStrength;
			float _Decal3ChannelSeparationEnable;
			float _Decal3ChannelSeparation;
			float _Decal3ChannelSeparationPremultiply;
			float _Decal3ChannelSeparationHue;
			float _Decal3ChannelSeparationVertical;
			float _Decal3ChannelSeparationAngleStrength;
			float _Decal3OverrideAlphaMode;
			#endif
			//endex
			
			//ifex _EnableDissolve==0
			#ifdef DISTORT
			float _DissolveType;
			float _DissolveEdgeWidth;
			float4 _DissolveEdgeColor;
			sampler2D _DissolveEdgeGradient;
			float4 _DissolveEdgeGradient_ST;
			float2 _DissolveEdgeGradientPan;
			float _DissolveEdgeGradientUV;
			float _DissolveEdgeEmission;
			float4 _DissolveTextureColor;
			float _DissolveEdgeColorThemeIndex;
			float _DissolveTextureColorThemeIndex;
			
			#if defined(PROP_DISSOLVETOTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveToTexture;
			#endif
			float4 _DissolveToTexture_ST;
			float2 _DissolveToTexturePan;
			float _DissolveToTextureUV;
			
			#if defined(PROP_DISSOLVENOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveNoiseTexture;
			#endif
			float4 _DissolveNoiseTexture_ST;
			float2 _DissolveNoiseTexturePan;
			float _DissolveNoiseTextureUV;
			
			#if defined(PROP_DISSOLVEDETAILNOISE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveDetailNoise;
			#endif
			float4 _DissolveDetailNoise_ST;
			float2 _DissolveDetailNoisePan;
			float _DissolveDetailNoiseUV;
			
			#if defined(PROP_DISSOLVEMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveMask;
			#endif
			float4 _DissolveMask_ST;
			float2 _DissolveMaskPan;
			float _DissolveMaskUV;
			
			float _DissolveMaskGlobalMask;
			float _DissolveMaskGlobalMaskBlendType;
			float _DissolveApplyGlobalMaskIndex;
			float _DissolveApplyGlobalMaskBlendType;
			float _DissolveInverseApplyGlobalMaskBlendType;
			float _DissolveInverseApplyGlobalMaskIndex;
			float _DissolveMaskInvert;
			float _DissolveAlpha;
			float _ContinuousDissolve;
			float _DissolveDetailStrength;
			float _DissolveDetailEdgeSmoothing;
			float _DissolveEdgeHardness;
			float _DissolveInvertNoise;
			float _DissolveInvertDetailNoise;
			float _DissolveToEmissionStrength;
			
			// Point to Point
			float _DissolveP2PWorldLocal;
			float _DissolveP2PEdgeLength;
			float _DissolveP2PClamp;
			float4 _DissolveStartPoint;
			float4 _DissolveEndPoint;
			
			// Spherical
			float3 _SphericalDissolveCenter;
			float _SphericalDissolveRadius;
			float _SphericalDissolveInvert;
			float _SphericalDissolveClamp;
			
			// CenterOut
			float _CenterOutDissolveMode;
			float3 _CenterOutDissolveDirection;
			float _CenterOutDissolveInvert;
			float _CenterOutDissolveNormals;
			float _CenterOutDissolvePower;
			
			// World Dissolve
			float _DissolveWorldShape;
			float4 _DissolveShapePosition;
			float4 _DissolveShapeRotation;
			float _DissolveShapeScale;
			float _DissolveInvertShape;
			float _DissolveShapeEdgeLength;
			
			// UV Tile Dissolve
			float _UVTileDissolveEnabled;
			float _UVTileDissolveDiscardAtMax;
			float _UVTileDissolveUV;
			
			float _UVTileDissolveAlpha_Row3_0;
			float _UVTileDissolveAlpha_Row3_1;
			float _UVTileDissolveAlpha_Row3_2;
			float _UVTileDissolveAlpha_Row3_3;
			float _UVTileDissolveAlpha_Row2_0;
			float _UVTileDissolveAlpha_Row2_1;
			float _UVTileDissolveAlpha_Row2_2;
			float _UVTileDissolveAlpha_Row2_3;
			float _UVTileDissolveAlpha_Row1_0;
			float _UVTileDissolveAlpha_Row1_1;
			float _UVTileDissolveAlpha_Row1_2;
			float _UVTileDissolveAlpha_Row1_3;
			float _UVTileDissolveAlpha_Row0_0;
			float _UVTileDissolveAlpha_Row0_1;
			float _UVTileDissolveAlpha_Row0_2;
			float _UVTileDissolveAlpha_Row0_3;
			
			float _DissolveAlpha0;
			float _DissolveAlpha1;
			float _DissolveAlpha2;
			float _DissolveAlpha3;
			float _DissolveAlpha4;
			float _DissolveAlpha5;
			float _DissolveAlpha6;
			float _DissolveAlpha7;
			float _DissolveAlpha8;
			float _DissolveAlpha9;
			// Masking
			float _DissolveEmissionSide;
			float _DissolveEmission1Side;
			float _DissolveUseVertexColors;
			
			float4 edgeColor;
			float edgeAlpha;
			float dissolveAlpha;
			float4 dissolveToTexture;
			
			float _DissolveHueShiftEnabled;
			float _DissolveHueShiftSpeed;
			float _DissolveHueShift;
			float _DissolveEdgeHueShiftEnabled;
			float _DissolveEdgeHueShiftSpeed;
			float _DissolveEdgeHueShift;
			
			// Audio Link
			#ifdef POI_AUDIOLINK
			fixed _EnableDissolveAudioLink;
			half _AudioLinkDissolveAlphaBand;
			float2 _AudioLinkDissolveAlpha;
			half _AudioLinkDissolveDetailBand;
			float2 _AudioLinkDissolveDetail;
			#endif
			#endif
			//endex
			
			//ifex _EnableAniso==0
			#ifdef POI_ANISOTROPICS
			
			#if defined(PROP_ANISOCOLORMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AnisoColorMap;
			float4 _AnisoColorMap_ST;
			float2 _AnisoColorMapPan;
			float _AnisoColorMapUV;
			#endif
			/*
			#if defined(PROP_ANISONOISEMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AnisoNoiseMap;
			float4 _AnisoNoiseMap_ST;
			float2 _AnisoNoiseMapPan;
			float _AnisoNoiseMapUV;
			#endif
			*/
			float _AnisoHideInShadow;
			float _AnisoReplace;
			float _AnisoAdd;
			float _AnisoUseBaseColor;
			float _AnisoUseLightColor;
			
			float _AnisoGlobalMask;
			float _AnisoGlobalMaskBlendType;
			
			float _Aniso0Strength;
			float _Aniso0Power;
			float _Aniso0Offset;
			float _Aniso0SwitchDirection;
			float4 _Aniso0Tint;
			float _Aniso0TintIndex;
			float _Aniso0OffsetMapStrength;
			float _Aniso0ToonMode;
			float _Aniso0Edge;
			float _Aniso0Blur;
			
			float _Aniso1Strength;
			float _Aniso1Power;
			float _Aniso1Offset;
			float _Aniso1SwitchDirection;
			float4 _Aniso1Tint;
			float _Aniso1TintIndex;
			float _Aniso1OffsetMapStrength;
			float _Aniso1ToonMode;
			float _Aniso1Edge;
			float _Aniso1Blur;
			#endif
			//endex
			
			//ifex _MatcapEnable==0
			#ifdef POI_MATCAP0
			#if defined(PROP_MATCAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap;
			float4 _Matcap_ST;
			float4 _Matcap_TexelSize;
			float2 _MatcapPan;
			float _MatcapUV;
			#endif
			#if defined(PROP_MATCAPMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MatcapMask;
			float4 _MatcapMask_ST;
			float2 _MatcapMaskPan;
			float _MatcapMaskUV;
			float _MatcapMaskChannel;
			#endif
			#ifdef POI_MATCAP0_CUSTOM_NORMAL
			#if defined(PROP_MATCAP0NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap0NormalMap;
			#endif
			float4 _Matcap0NormalMap_ST;
			float2 _Matcap0NormalMapPan;
			float _Matcap0NormalMapUV;
			float _Matcap0NormalMapScale;
			#endif
			float _MatcapUVToBlend;
			float4 _MatCapBlendUV1;
			float _MatcapUVMode;
			float _MatcapMaskInvert;
			float _MatcapMaskGlobalMask;
			float _MatcapMaskGlobalMaskBlendType;
			float _MatcapBorder;
			float _MatcapRotation;
			float _MatcapSmoothnessEnabled;
			float _MatcapSmoothness;
			float _MatcapMaskSmoothnessChannel;
			float _MatcapMaskSmoothnessApply;
			float4 _MatcapColor;
			float _MatcapBaseColorMix;
			float _MatcapColorThemeIndex;
			float _MatcapIntensity;
			float _MatcapReplace;
			float _MatcapMultiply;
			float _MatcapAdd;
			float _MatcapAddToLight;
			float _MatcapMixed;
			float _MatcapScreen;
			float _MatcapAlphaOverride;
			float _MatcapEnable;
			float _MatcapLightMask;
			float _MatcapEmissionStrength;
			float _MatcapNormal;
			float _MatcapHueShiftEnabled;
			float _MatcapHueShiftSpeed;
			float _MatcapHueShift;
			int _MatcapApplyToAlphaEnabled;
			int _MatcapApplyToAlphaSourceBlend;
			int _MatcapApplyToAlphaBlendType;
			float _MatcapApplyToAlphaBlending;
			float _MatcapTPSDepthEnabled;
			float _MatcapTPSMaskStrength;
			
			float _Matcap0ALEnabled;
			float _Matcap0ALAlphaAddBand;
			float4 _Matcap0ALAlphaAdd;
			float _Matcap0ALEmissionAddBand;
			float4 _Matcap0ALEmissionAdd;
			float _Matcap0ALIntensityAddBand;
			float4 _Matcap0ALIntensityAdd;
			float _Matcap0ALChronoPanType;
			float _Matcap0ALChronoPanBand;
			float _Matcap0ALChronoPanSpeed;
			#endif
			//endex
			//ifex _Matcap2Enable==0
			#ifdef COLOR_GRADING_HDR_3D
			#if defined(PROP_MATCAP2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap2;
			float4 _Matcap2_ST;
			float4 _Matcap2_TexelSize;
			float2 _Matcap2Pan;
			float _Matcap2UV;
			#endif
			#if defined(PROP_MATCAP2MASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap2Mask;
			float4 _Matcap2Mask_ST;
			float2 _Matcap2MaskPan;
			float _Matcap2MaskUV;
			float _Matcap2MaskChannel;
			#endif
			#ifdef POI_MATCAP1_CUSTOM_NORMAL
			#if defined(PROP_MATCAP1NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap1NormalMap;
			#endif
			float4 _Matcap1NormalMap_ST;
			float2 _Matcap1NormalMapPan;
			float _Matcap1NormalMapUV;
			float _Matcap1NormalMapScale;
			#endif
			float _Matcap2UVToBlend;
			float4 _MatCap2ndBlendUV1;
			float _Matcap2UVMode;
			float _Matcap2MaskInvert;
			float _Matcap2MaskGlobalMask;
			float _Matcap2MaskGlobalMaskBlendType;
			float _Matcap2Border;
			float _Matcap2Rotation;
			float _Matcap2SmoothnessEnabled;
			float _Matcap2Smoothness;
			float _Matcap2MaskSmoothnessChannel;
			float _Matcap2MaskSmoothnessApply;
			float4 _Matcap2Color;
			float _Matcap2BaseColorMix;
			float _Matcap2ColorThemeIndex;
			float _Matcap2Intensity;
			float _Matcap2Replace;
			float _Matcap2Multiply;
			float _Matcap2Add;
			float _Matcap2AddToLight;
			float _Matcap2Mixed;
			float _Matcap2Screen;
			float _Matcap2AlphaOverride;
			float _Matcap2Enable;
			float _Matcap2LightMask;
			float _Matcap2EmissionStrength;
			float _Matcap2Normal;
			float _Matcap2HueShiftEnabled;
			float _Matcap2HueShiftSpeed;
			float _Matcap2HueShift;
			int _Matcap2ApplyToAlphaEnabled;
			int _Matcap2ApplyToAlphaSourceBlend;
			int _Matcap2ApplyToAlphaBlendType;
			float _Matcap2ApplyToAlphaBlending;
			float _Matcap2TPSDepthEnabled;
			float _Matcap2TPSMaskStrength;
			
			float _Matcap1ALEnabled;
			float _Matcap1ALAlphaAddBand;
			float4 _Matcap1ALAlphaAdd;
			float _Matcap1ALEmissionAddBand;
			float4 _Matcap1ALEmissionAdd;
			float _Matcap1ALIntensityAddBand;
			float4 _Matcap1ALIntensityAdd;
			float _Matcap1ALChronoPanType;
			float _Matcap1ALChronoPanBand;
			float _Matcap1ALChronoPanSpeed;
			#endif
			//endex
			
			//ifex _Matcap3Enable==0
			#ifdef POI_MATCAP2
			#if defined(PROP_MATCAP3) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap3;
			float4 _Matcap3_ST;
			float4 _Matcap3_TexelSize;
			float2 _Matcap3Pan;
			float _Matcap3UV;
			#endif
			#if defined(PROP_MATCAP3MASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap3Mask;
			float4 _Matcap3Mask_ST;
			float2 _Matcap3MaskPan;
			float _Matcap3MaskUV;
			float _Matcap3MaskChannel;
			#endif
			#ifdef POI_MATCAP2_CUSTOM_NORMAL
			#if defined(PROP_MATCAP2NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap2NormalMap;
			#endif
			float4 _Matcap2NormalMap_ST;
			float2 _Matcap2NormalMapPan;
			float _Matcap2NormalMapUV;
			float _Matcap2NormalMapScale;
			#endif
			float _Matcap3UVToBlend;
			float4 _MatCap3rdBlendUV1;
			float _Matcap3UVMode;
			float _Matcap3MaskInvert;
			float _Matcap3MaskGlobalMask;
			float _Matcap3MaskGlobalMaskBlendType;
			float _Matcap3Border;
			float _Matcap3Rotation;
			float _Matcap3SmoothnessEnabled;
			float _Matcap3Smoothness;
			float _Matcap3MaskSmoothnessChannel;
			float _Matcap3MaskSmoothnessApply;
			float4 _Matcap3Color;
			float _Matcap3BaseColorMix;
			float _Matcap3ColorThemeIndex;
			float _Matcap3Intensity;
			float _Matcap3Replace;
			float _Matcap3Multiply;
			float _Matcap3Add;
			float _Matcap3AddToLight;
			float _Matcap3Mixed;
			float _Matcap3Screen;
			float _Matcap3AlphaOverride;
			float _Matcap3Enable;
			float _Matcap3LightMask;
			float _Matcap3EmissionStrength;
			float _Matcap3Normal;
			float _Matcap3HueShiftEnabled;
			float _Matcap3HueShiftSpeed;
			float _Matcap3HueShift;
			int _Matcap3ApplyToAlphaEnabled;
			int _Matcap3ApplyToAlphaSourceBlend;
			int _Matcap3ApplyToAlphaBlendType;
			float _Matcap3ApplyToAlphaBlending;
			float _Matcap3TPSDepthEnabled;
			float _Matcap3TPSMaskStrength;
			
			float _Matcap2ALEnabled;
			float _Matcap2ALAlphaAddBand;
			float4 _Matcap2ALAlphaAdd;
			float _Matcap2ALEmissionAddBand;
			float4 _Matcap2ALEmissionAdd;
			float _Matcap2ALIntensityAddBand;
			float4 _Matcap2ALIntensityAdd;
			float _Matcap2ALChronoPanType;
			float _Matcap2ALChronoPanBand;
			float _Matcap2ALChronoPanSpeed;
			#endif
			//endex
			
			//ifex _Matcap4Enable==0
			#ifdef POI_MATCAP3
			#if defined(PROP_MATCAP4) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap4;
			float4 _Matcap4_ST;
			float4 _Matcap4_TexelSize;
			float2 _Matcap4Pan;
			float _Matcap4UV;
			#endif
			#if defined(PROP_MATCAP4MASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap4Mask;
			float4 _Matcap4Mask_ST;
			float2 _Matcap4MaskPan;
			float _Matcap4MaskUV;
			float _Matcap4MaskChannel;
			#endif
			#ifdef POI_MATCAP3_CUSTOM_NORMAL
			#if defined(PROP_MATCAP3NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap3NormalMap;
			#endif
			float4 _Matcap3NormalMap_ST;
			float2 _Matcap3NormalMapPan;
			float _Matcap3NormalMapUV;
			float _Matcap3NormalMapScale;
			#endif
			float _Matcap4UVToBlend;
			float4 _MatCap4thBlendUV1;
			float _Matcap4UVMode;
			float _Matcap4MaskInvert;
			float _Matcap4MaskGlobalMask;
			float _Matcap4MaskGlobalMaskBlendType;
			float _Matcap4Border;
			float _Matcap4Rotation;
			float _Matcap4SmoothnessEnabled;
			float _Matcap4Smoothness;
			float _Matcap4MaskSmoothnessChannel;
			float _Matcap4MaskSmoothnessApply;
			float4 _Matcap4Color;
			float _Matcap4BaseColorMix;
			float _Matcap4ColorThemeIndex;
			float _Matcap4Intensity;
			float _Matcap4Replace;
			float _Matcap4Multiply;
			float _Matcap4Add;
			float _Matcap4AddToLight;
			float _Matcap4Mixed;
			float _Matcap4Screen;
			float _Matcap4AlphaOverride;
			float _Matcap4Enable;
			float _Matcap4LightMask;
			float _Matcap4EmissionStrength;
			float _Matcap4Normal;
			float _Matcap4HueShiftEnabled;
			float _Matcap4HueShiftSpeed;
			float _Matcap4HueShift;
			int _Matcap4ApplyToAlphaEnabled;
			int _Matcap4ApplyToAlphaSourceBlend;
			int _Matcap4ApplyToAlphaBlendType;
			float _Matcap4ApplyToAlphaBlending;
			float _Matcap4TPSDepthEnabled;
			float _Matcap4TPSMaskStrength;
			
			float _Matcap3ALEnabled;
			float _Matcap3ALAlphaAddBand;
			float4 _Matcap3ALAlphaAdd;
			float _Matcap3ALEmissionAddBand;
			float4 _Matcap3ALEmissionAdd;
			float _Matcap3ALIntensityAddBand;
			float4 _Matcap3ALIntensityAdd;
			float _Matcap3ALChronoPanType;
			float _Matcap3ALChronoPanBand;
			float _Matcap3ALChronoPanSpeed;
			#endif
			//endex
			struct MatcapAudioLinkData
			{
				float matcapALEnabled;
				float matcapALAlphaAddBand;
				float4 matcapALAlphaAdd;
				float matcapALEmissionAddBand;
				float4 matcapALEmissionAdd;
				float matcapALIntensityAddBand;
				float4 matcapALIntensityAdd;
				float matcapALChronoPanType;
				float matcapALChronoPanBand;
				float matcapALChronoPanSpeed;
			};
			
			//ifex _CubeMapEnabled==0
			#ifdef _CUBEMAP
			#if defined(PROP_CUBEMAP) || !defined(OPTIMIZER_ENABLED)
			samplerCUBE _CubeMap;
			float3 _CubeMapRotation;
			float3 _CubeMapRotationPan;
			#endif
			#if defined(PROP_CUBEMAPMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _CubeMapMask;
			float4 _CubeMapMask_ST;
			float2 _CubeMapMaskPan;
			float _CubeMapMaskUV;
			float _CubeMapMaskChannel;
			#endif
			float _CubeMapUVMode;
			float _CubeMapWorldNormalsStrength;
			float _CubeMapMaskInvert;
			float _CubeMapMaskGlobalMask;
			float _CubeMapMaskGlobalMaskBlendType;
			float4 _CubeMapColor;
			float _CubeMapColorThemeIndex;
			float _CubeMapIntensity;
			float _CubemapBlendType;
			float _CubeMapBlendAmount;
			float _CubeMapEnable;
			float _CubeMapLightMask;
			float _CubeMapEmissionStrength;
			float _CubeMapNormal;
			float _CubeMapHueShiftEnabled;
			float _CubeMapHueShiftSpeed;
			float _CubeMapHueShift;
			float _CubeMapSaturation;
			float _CubeMapBrightness;
			float _CubeMapContrast;
			float _CubeMapSmoothness;
			#endif
			//endex
			
			//ifex _EnableALDecal==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_DECAL
			float _ALDecalUV;
			float4 _ALUVScale;
			float2 _ALUVPosition;
			float _ALUVRotation;
			float _ALUVRotationSpeed;
			float4 _ALDecaldCircleDimensions;
			
			float _ALDecalUVMode;
			
			float _ALDecalVolumeStep;
			float _ALDecalVolumeClipMin;
			float _ALDecalVolumeClipMax;
			
			float _ALDecalBandStep;
			float _ALDecalBandClipMin;
			float _ALDecalBandClipMax;
			
			float _ALDecalShapeClip;
			float _ALDecalShapeClipVolumeWidth;
			float _ALDecalShapeClipBandWidth;
			
			#if defined(PROP_ALDECALCOLORMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ALDecalColorMask;
			float4 _ALDecalColorMask_ST;
			float2 _ALDecalColorMaskPan;
			float _ALDecalColorMaskUV;
			#endif
			
			float _ALDecalVolume;
			float _ALDecalBaseBoost;
			float _ALDecalTrebleBoost;
			float _ALDecalLineWidth;
			float _ALDecalVolumeColorSource;
			float3 _ALDecalVolumeColorLow;
			float _ALDecalVolumeColorLowThemeIndex;
			float3 _ALDecalVolumeColorMid;
			float _ALDecalVolumeColorMidThemeIndex;
			float3 _ALDecalVolumeColorHigh;
			float _ALDecalVolumeColorHighThemeIndex;
			float _ALDecalLowEmission;
			float _ALDecalMidEmission;
			float _ALDecalHighEmission;
			float _ALDecalBlendType;
			float _ALDecalBlendAlpha;
			float _ALDecalControlsAlpha;
			float _ALDecalGlobalMask;
			float _ALDecalGlobalMaskBlendType;
			#endif
			#endif
			//endex
			
			//ifex _EnableVolumeColor==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_VOLUMECOLOR
			float _ALVolumeColorUV;
			float _ALVolumeColorDirection;
			float _ALVolumeColorBlendType;
			float _ALVolumeColorBlendAlpha;
			float3 _ALVolumeColorLow;
			float _ALVolumeColorLowThemeIndex;
			float3 _ALVolumeColorMid;
			float _ALVolumeColorMidThemeIndex;
			float3 _ALVolumeColorHigh;
			float _ALVolumeColorHighThemeIndex;
			float _ALLowEmission;
			float _ALMidEmission;
			float _ALHighEmission;
			#endif
			#endif
			//endex
			
			//ifex _EnableFlipbook==0
			#ifdef _SUNDISK_HIGH_QUALITY
			
			UNITY_DECLARE_TEX2DARRAY(_FlipbookTexArray);
			float4 _FlipbookTexArray_ST;
			
			float4 _FlipbookColor;
			float _FlipbookColorThemeIndex;
			float _FlipbookFPS;
			// float _FlipbookTotalFrames;
			float4 _FlipbookScaleOffset;
			float4 _FlipbookSideOffset;
			float _FlipbookTiled;
			float _FlipbookManualFrameControl;
			float _FlipbookCurrentFrame;
			float _FlipbookStartAndEnd;
			float _FlipbookStartFrame;
			float _FlipbookEndFrame;
			float _FlipbookEmissionStrength;
			float _FlipbookRotation;
			float _EnableFlipbook;
			float _FlipbookTexArrayUV;
			float _FlipbookAlphaControlsFinalAlpha;
			float _FlipbookRotationSpeed;
			float _FlipbookIntensityControlsAlpha;
			float _FlipbookColorReplaces;
			float2 _FlipbookTexArrayPan;
			float _FlipbookFrameOffset;
			// blending
			float _FlipbookReplace;
			float _FlipbookMultiply;
			float _FlipbookAdd;
			float _FlipbookBlendType;
			
			#if defined(PROP_FLIPBOOKMASSK) || !defined(OPTIMIZED_ENABLED)
			Texture2D _FlipbookMask;
			#endif
			float4 _FlipbookMask_ST;
			float2 _FlipbookMaskPan;
			float _FlipbookMaskUV;
			float _FlipbookMaskChannel;
			float _FlipbookMaskGlobalMask;
			float _FlipbookMaskGlobalMaskBlendType;
			
			// anim
			float _FlipbookMovementType;
			float4 _FlipbookStartEndOffset;
			float _FlipbookMovementSpeed;
			
			// Crossfade
			float _FlipbookCrossfadeEnabled;
			float2 _FlipbookCrossfadeRange;
			
			// Hueshift
			float _FlipbookHueShiftEnabled;
			float _FlipbookHueShiftSpeed;
			float _FlipbookHueShift;
			
			#ifdef POI_AUDIOLINK
			float _FlipbookChronotensityEnabled;
			float _FlipbookChronotensityBand;
			float _FlipbookChronotensitySpeed;
			float _FlipbookChronoType;
			half _AudioLinkFlipbookScaleBand;
			half4 _AudioLinkFlipbookScale;
			half _AudioLinkFlipbookAlphaBand;
			half2 _AudioLinkFlipbookAlpha;
			half _AudioLinkFlipbookEmissionBand;
			half2 _AudioLinkFlipbookEmission;
			half _AudioLinkFlipbookFrameBand;
			half2 _AudioLinkFlipbookFrame;
			#endif
			#endif
			//endex
			
			//ifex _EnableEmission==0
			#ifdef _EMISSION
			#if defined(PROP_EMISSIONMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionMap;
			#endif
			float4 _EmissionMap_ST;
			float2 _EmissionMapPan;
			float _EmissionMapUV;
			#if defined(PROP_EMISSIONMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionMask;
			#endif
			float4 _EmissionMask_ST;
			float2 _EmissionMaskPan;
			float _EmissionMaskUV;
			float _EmissionMaskInvert;
			float _EmissionMaskChannel;
			float _EmissionMask0GlobalMask;
			float _EmissionMask0GlobalMaskBlendType;
			#if defined(PROP_EMISSIONSCROLLINGCURVE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionScrollingCurve;
			#endif
			float4 _EmissionScrollingCurve_ST;
			
			float4 _EmissionColor;
			float _EmissionBaseColorAsMap;
			float _EmissionStrength;
			float _EmissionHueShiftEnabled;
			float _EmissionSaturation;
			float _EmissionHueShift;
			float _EmissionHueShiftSpeed;
			float _EmissionCenterOutEnabled;
			float _EmissionCenterOutSpeed;
			float _EnableGITDEmission;
			float _GITDEWorldOrMesh;
			float _GITDEMinEmissionMultiplier;
			float _GITDEMaxEmissionMultiplier;
			float _GITDEMinLight;
			float _GITDEMaxLight;
			float _EmissionBlinkingEnabled;
			float _EmissiveBlink_Min;
			float _EmissiveBlink_Max;
			float _EmissiveBlink_Velocity;
			float _EmissionBlinkingOffset;
			float _ScrollingEmission;
			float4 _EmissiveScroll_Direction;
			float _EmissiveScroll_Width;
			float _EmissiveScroll_Velocity;
			float _EmissiveScroll_Interval;
			float _EmissionScrollingOffset;
			
			float _EmissionReplace0;
			float _EmissionScrollingVertexColor;
			float _EmissionScrollingUseCurve;
			float _EmissionColorThemeIndex;
			
			// Audio Link
			float _EmissionAL0Enabled;
			float2 _EmissionAL0StrengthMod;
			float _EmissionAL0StrengthBand;
			float _EmissionAL0StrengthBandSmoothing;
			float2 _AudioLinkEmission0CenterOut;
			float _AudioLinkEmission0CenterOutSize;
			float _AudioLinkEmission0CenterOutBand;
			float _AudioLinkEmission0CenterOutDuration;
			float2 _EmissionAL0Multipliers;
			float _EmissionAL0MultipliersBand;
			#endif
			//endex
			//ifex _EnableEmission1==0
			#ifdef POI_EMISSION_1
			
			#if defined(PROP_EMISSIONMAP1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionMap1;
			#endif
			float4 _EmissionMap1_ST;
			float2 _EmissionMap1Pan;
			float _EmissionMap1UV;
			#if defined(PROP_EMISSIONMASK1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionMask1;
			#endif
			float4 _EmissionMask1_ST;
			float2 _EmissionMask1Pan;
			float _EmissionMask1UV;
			float _EmissionMask1Channel;
			float _EmissionMaskInvert1;
			float _EmissionMask1GlobalMask;
			float _EmissionMask1GlobalMaskBlendType;
			#if defined(PROP_EMISSIONSCROLLINGCURVE1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionScrollingCurve1;
			#endif
			float4 _EmissionScrollingCurve1_ST;
			
			float4 _EmissionColor1;
			float _EmissionBaseColorAsMap1;
			float _EmissionStrength1;
			float _EnableEmission1;
			float _EmissionHueShift1;
			float _EmissionHueShiftSpeed1;
			float4 _EmissiveScroll_Direction1;
			float _EmissiveScroll_Width1;
			float _EmissiveScroll_Velocity1;
			float _EmissiveScroll_Interval1;
			float _EmissionBlinkingEnabled1;
			float _EmissiveBlink_Min1;
			float _EmissiveBlink_Max1;
			float _EmissiveBlink_Velocity1;
			float _ScrollingEmission1;
			float _EnableGITDEmission1;
			float _GITDEMinEmissionMultiplier1;
			float _GITDEMaxEmissionMultiplier1;
			float _GITDEMinLight1;
			float _GITDEMaxLight1;
			float _GITDEWorldOrMesh1;
			float _EmissionCenterOutEnabled1;
			float _EmissionCenterOutSpeed1;
			float _EmissionHueShiftEnabled1;
			float _EmissionSaturation1;
			float _EmissionBlinkingOffset1;
			float _EmissionScrollingOffset1;
			float _EmissionScrollingVertexColor1;
			float _EmissionScrollingUseCurve1;
			float _EmissionReplace1;
			float _EmissionColor1ThemeIndex;
			
			// Audio Link
			float _EmissionAL1Enabled;
			float2 _EmissionAL1StrengthMod;
			float _EmissionAL1StrengthBand;
			float2 _AudioLinkEmission1CenterOut;
			float _AudioLinkEmission1CenterOutSize;
			float _AudioLinkEmission1CenterOutBand;
			float _AudioLinkEmission1CenterOutDuration;
			float2 _EmissionAL1Multipliers;
			float _EmissionAL1MultipliersBand;
			#endif
			//endex
			//ifex _EnableEmission2==0
			#ifdef POI_EMISSION_2
			
			#if defined(PROP_EMISSIONMAP2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionMap2;
			#endif
			float4 _EmissionMap2_ST;
			float2 _EmissionMap2Pan;
			float _EmissionMap2UV;
			#if defined(PROP_EMISSIONMASK2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionMask2;
			#endif
			float4 _EmissionMask2_ST;
			float2 _EmissionMask2Pan;
			float _EmissionMask2UV;
			float _EmissionMask2Channel;
			float _EmissionMaskInvert2;
			float _EmissionMask2GlobalMask;
			float _EmissionMask2GlobalMaskBlendType;
			#if defined(PROP_EMISSIONSCROLLINGCURVE2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionScrollingCurve2;
			#endif
			float4 _EmissionScrollingCurve2_ST;
			
			float4 _EmissionColor2;
			float _EmissionBaseColorAsMap2;
			float _EmissionStrength2;
			float _EnableEmission2;
			float _EmissionHueShift2;
			float _EmissionHueShiftSpeed2;
			float4 _EmissiveScroll_Direction2;
			float _EmissiveScroll_Width2;
			float _EmissiveScroll_Velocity2;
			float _EmissiveScroll_Interval2;
			float _EmissionBlinkingEnabled2;
			float _EmissiveBlink_Min2;
			float _EmissiveBlink_Max2;
			float _EmissiveBlink_Velocity2;
			float _ScrollingEmission2;
			float _EnableGITDEmission2;
			float _GITDEMinEmissionMultiplier2;
			float _GITDEMaxEmissionMultiplier2;
			float _GITDEMinLight2;
			float _GITDEMaxLight2;
			float _GITDEWorldOrMesh2;
			float _EmissionCenterOutEnabled2;
			float _EmissionCenterOutSpeed2;
			float _EmissionHueShiftEnabled2;
			float _EmissionSaturation2;
			float _EmissionBlinkingOffset2;
			float _EmissionScrollingOffset2;
			float _EmissionScrollingVertexColor2;
			float _EmissionScrollingUseCurve2;
			float _EmissionReplace2;
			float _EmissionColor2ThemeIndex;
			
			// Audio Link
			float _EmissionAL2Enabled;
			float2 _EmissionAL2StrengthMod;
			float _EmissionAL2StrengthBand;
			float2 _AudioLinkEmission2CenterOut;
			float _AudioLinkEmission2CenterOutSize;
			float _AudioLinkEmission2CenterOutBand;
			float _AudioLinkEmission2CenterOutDuration;
			float2 _EmissionAL2Multipliers;
			float _EmissionAL2MultipliersBand;
			#endif
			//endex
			//ifex _EnableEmission3==0
			#ifdef POI_EMISSION_3
			#if defined(PROP_EMISSIONMAP3) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionMap3;
			#endif
			float4 _EmissionMap3_ST;
			float2 _EmissionMap3Pan;
			float _EmissionMap3UV;
			#if defined(PROP_EMISSIONMASK3) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionMask3;
			#endif
			float4 _EmissionMask3_ST;
			float2 _EmissionMask3Pan;
			float _EmissionMask3UV;
			float _EmissionMask3Channel;
			float _EmissionMaskInvert3;
			float _EmissionMask3GlobalMask;
			float _EmissionMask3GlobalMaskBlendType;
			#if defined(PROP_EMISSIONSCROLLINGCURVE3) || !defined(OPTIMIZER_ENABLED)
			Texture2D _EmissionScrollingCurve3;
			#endif
			float4 _EmissionScrollingCurve3_ST;
			
			float4 _EmissionColor3;
			float _EmissionBaseColorAsMap3;
			float _EmissionStrength3;
			float _EnableEmission3;
			float _EmissionHueShift3;
			float _EmissionHueShiftSpeed3;
			float4 _EmissiveScroll_Direction3;
			float _EmissiveScroll_Width3;
			float _EmissiveScroll_Velocity3;
			float _EmissiveScroll_Interval3;
			float _EmissionBlinkingEnabled3;
			float _EmissiveBlink_Min3;
			float _EmissiveBlink_Max3;
			float _EmissiveBlink_Velocity3;
			float _ScrollingEmission3;
			float _EnableGITDEmission3;
			float _GITDEMinEmissionMultiplier3;
			float _GITDEMaxEmissionMultiplier3;
			float _GITDEMinLight3;
			float _GITDEMaxLight3;
			float _GITDEWorldOrMesh3;
			float _EmissionCenterOutEnabled3;
			float _EmissionCenterOutSpeed3;
			float _EmissionHueShiftEnabled3;
			float _EmissionSaturation3;
			float _EmissionBlinkingOffset3;
			float _EmissionScrollingOffset3;
			float _EmissionScrollingVertexColor3;
			float _EmissionScrollingUseCurve3;
			float _EmissionReplace3;
			float _EmissionColor3ThemeIndex;
			
			// Audio Link
			float _EmissionAL3Enabled;
			float2 _EmissionAL3StrengthMod;
			float _EmissionAL3StrengthBand;
			float2 _AudioLinkEmission3CenterOut;
			float _AudioLinkEmission3CenterOutSize;
			float _AudioLinkEmission3CenterOutBand;
			float _AudioLinkEmission3CenterOutDuration;
			float2 _EmissionAL3Multipliers;
			float _EmissionAL3MultipliersBand;
			#endif
			//endex
			
			//ifex _EnableRimLighting==0
			#ifdef _GLOSSYREFLECTIONS_OFF
			float _Is_NormalMapToRimLight;
			float4 _RimLightColor;
			float _RimLightColorThemeIndex;
			#ifdef _RIMSTYLE_POIYOMI
			float _RimLightingInvert;
			float _RimWidth;
			float _RimStrength;
			float _RimSharpness;
			float _RimBaseColorMix;
			float _EnableRimLighting;
			float _RimWidthNoiseStrength;
			float4 _RimShadowAlpha;
			float _RimShadowWidth;
			float _RimBlendStrength;
			float _RimPoiBlendMode;
			float _RimShadowToggle;
			float _RimPower;
			float _RimShadowMaskStrength;
			float _RimShadowMaskRampType;
			float _RimShadowMaskInvert;
			float _RimBrightness;
			#if defined(PROP_RIMTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RimTex;
			#endif
			float4 _RimTex_ST;
			float2 _RimTexPan;
			float _RimTexUV;
			#if defined(PROP_RIMMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RimMask;
			#endif
			float4 _RimMask_ST;
			float2 _RimMaskPan;
			float _RimMaskUV;
			float _RimMaskChannel;
			float _RimMaskInvert;
			float _RimBiasIntensity;
			int _RimApplyAlpha;
			float _RimApplyAlphaBlend;
			#ifdef POI_AUDIOLINK
			half _AudioLinkRimWidthBand;
			float2 _AudioLinkRimWidthAdd;
			half _AudioLinkRimEmissionBand;
			float2 _AudioLinkRimEmissionAdd;
			half _AudioLinkRimBrightnessBand;
			float2 _AudioLinkRimBrightnessAdd;
			#endif
			#endif
			
			#ifdef _RIMSTYLE_UTS2
			float _RimLight;
			float _Is_LightColor_RimLight;
			float _RimLight_Power;
			float _RimLight_InsideMask;
			float _RimLight_FeatherOff;
			float _LightDirection_MaskOn;
			float _Tweak_LightDirection_MaskLevel;
			float _Add_Antipodean_RimLight;
			float4 _Ap_RimLightColor;
			float _RimApColorThemeIndex;
			float _Is_LightColor_Ap_RimLight;
			float _Ap_RimLight_Power;
			float _Ap_RimLight_FeatherOff;
			#if defined(PROP_SET_RIMLIGHTMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Set_RimLightMask;
			float4 _Set_RimLightMask_ST;
			float2 _Set_RimLightMaskPan;
			float _Set_RimLightMaskUV;
			float _Set_RimLightMaskChannel;
			#endif
			float _Tweak_RimLightMaskLevel;
			#endif
			
			#ifdef _RIMSTYLE_LILTOON
			float4 _RimColor;
			#if defined(PROP_RIMCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RimColorTex;
			float4 _RimColorTex_ST;
			float2 _RimColorTexPan;
			float _RimColorTexUV;
			#endif
			float _RimMainStrength;
			float _RimNormalStrength;
			float _RimBorder;
			float _RimBlur;
			float _RimFresnelPower;
			float _RimEnableLighting;
			float _RimShadowMask;
			int _RimBackfaceMask;
			float _RimVRParallaxStrength;
			float _RimDirStrength;
			float _RimDirRange;
			float _RimIndirRange;
			float4 _RimIndirColor;
			float _RimIndirBorder;
			float _RimIndirBlur;
			int _RimBlendMode;
			#endif
			
			float _RimGlobalMask;
			float _RimGlobalMaskBlendType;
			float _RimApplyGlobalMaskIndex;
			float _RimApplyGlobalMaskBlendType;
			
			float _RimHueShiftEnabled;
			float _RimHueShiftSpeed;
			float _RimHueShift;
			#endif
			//endex
			//ifex _EnableRim2Lighting==0
			#ifdef POI_RIM2
			float _Is_NormalMapToRim2Light;
			float4 _Rim2LightColor;
			float _Rim2LightColorThemeIndex;
			
			#ifdef _RIM2STYLE_POIYOMI
			float _Rim2LightingInvert;
			float _Rim2Width;
			float _Rim2Strength;
			float _Rim2Sharpness;
			float _Rim2BaseColorMix;
			float _EnableRim2Lighting;
			float _Rim2WidthNoiseStrength;
			float4 _Rim2ShadowAlpha;
			float _Rim2ShadowWidth;
			float _Rim2BlendStrength;
			float _RimPoi2BlendMode;
			float _Rim2ShadowToggle;
			float _Rim2Power;
			float _Rim2ShadowMaskStrength;
			float _Rim2ShadowMaskRampType;
			float _Rim2ShadowMaskInvert;
			float _Rim2Brightness;
			#if defined(PROP_RIM2TEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Rim2Tex;
			#endif
			float4 _Rim2Tex_ST;
			float2 _Rim2TexPan;
			float _Rim2TexUV;
			#if defined(PROP_RIM2MASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Rim2Mask;
			#endif
			float4 _Rim2Mask_ST;
			float2 _Rim2MaskPan;
			float _Rim2MaskUV;
			float _Rim2MaskChannel;
			float _Rim2MaskInvert;
			float _Rim2BiasIntensity;
			int _Rim2ApplyAlpha;
			float _Rim2ApplyAlphaBlend;
			#if defined(PROP_RIM2WIDTHNOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Rim2WidthNoiseTexture;
			#endif
			#ifdef POI_AUDIOLINK
			half _AudioLinkRim2WidthBand;
			float2 _AudioLinkRim2WidthAdd;
			half _AudioLinkRim2EmissionBand;
			float2 _AudioLinkRim2EmissionAdd;
			half _AudioLinkRim2BrightnessBand;
			float2 _AudioLinkRim2BrightnessAdd;
			#endif
			#endif
			
			#ifdef _RIM2STYLE_UTS2
			float _Rim2Light;
			float _Is_LightColor_Rim2Light;
			float _Rim2Light_Power;
			float _Rim2Light_InsideMask;
			float _Rim2Light_FeatherOff;
			float _LightDirection_MaskOn2;
			float _Tweak_LightDirection_MaskLevel2;
			float _Add_Antipodean_Rim2Light;
			float4 _Ap_Rim2LightColor;
			float _Rim2ApColorThemeIndex;
			float _Is_LightColor_Ap_Rim2Light;
			float _Ap_Rim2Light_Power;
			float _Ap_Rim2Light_FeatherOff;
			#if defined(PROP_SET_RIM2LIGHTMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Set_Rim2LightMask;
			float4 _Set_Rim2LightMask_ST;
			float2 _Set_Rim2LightMaskPan;
			float _Set_Rim2LightMaskUV;
			float _Set_Rim2LightMaskChannel;
			#endif
			float _Tweak_Rim2LightMaskLevel;
			#endif
			
			#ifdef _RIM2STYLE_LILTOON
			float4 _Rim2Color;
			#if defined(PROP_RIM2COLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Rim2ColorTex;
			float4 _Rim2ColorTex_ST;
			float2 _Rim2ColorTexPan;
			float _Rim2ColorTexUV;
			#endif
			float _Rim2MainStrength;
			float _Rim2NormalStrength;
			float _Rim2Border;
			float _Rim2Blur;
			float _Rim2FresnelPower;
			float _Rim2EnableLighting;
			float _Rim2ShadowMask;
			int _Rim2BackfaceMask;
			float _Rim2VRParallaxStrength;
			// int _Rim2ApplyTransparency;
			float _Rim2DirStrength;
			float _Rim2DirRange;
			float _Rim2IndirRange;
			float4 _Rim2IndirColor;
			float _Rim2IndirBorder;
			float _Rim2IndirBlur;
			int _Rim2BlendMode;
			#endif
			
			float _Rim2GlobalMask;
			float _Rim2GlobalMaskBlendType;
			float _Rim2ApplyGlobalMaskIndex;
			float _Rim2ApplyGlobalMaskBlendType;
			
			float _Rim2HueShiftEnabled;
			float _Rim2HueShiftSpeed;
			float _Rim2HueShift;
			#endif
			//endex
			
			//ifex _EnableDepthRimLighting==0
			#ifdef _POI_DEPTH_RIMLIGHT
			float _DepthRimNormalToUse;
			float _DepthRimWidth;
			float _DepthRimSharpness;
			float _DepthRimHideInShadow;
			float4 _DepthRimColor;
			float _DepthRimColorThemeIndex;
			float _DepthRimMixBaseColor;
			float _DepthRimEmission;
			float _DepthRimReplace;
			float _DepthRimAdd;
			float _DepthRimMultiply;
			float _DepthRimAdditiveLighting;
			float _DepthRimMixLightColor;
			float _DepthRimType;
			float _DepthRimBrightness;
			
			static float2 sobelSamplePoints[9] = {
				float2(-1, 1), float2(0, 1), float2(1, 1),
				float2(-1, 0), float2(0, 0), float2(1, 01),
				float2(-1, -1), float2(0, -1), float2(1, -1)
			};
			
			static float sobelXMatrix[9] = {
				1, 0, -1,
				2, 0, -2,
				1, 0, -1
			};
			static float sobelYMatrix[9] = {
				1, 2, 1,
				0, 0, 0,
				- 1, -2, -1
			};
			#endif
			//endex
			
			//ifex _GlitterEnable==0
			#ifdef _SUNDISK_SIMPLE
			float4 _GlitterRandomRotationSpeed;
			float _GlitterLayers;
			float _GlitterUseNormals;
			float _GlitterUV;
			float4 _GlitterColor;
			float _GlitterColorThemeIndex;
			float2 _GlitterPan;
			half _GlitterSpeed;
			half _GlitterBrightness;
			float _GlitterFrequency;
			float _GlitterRandomLocation;
			half _GlitterSize;
			half _GlitterContrast;
			half _GlitterAngleRange;
			half _GlitterMinBrightness;
			half _GlitterBias;
			fixed _GlitterUseSurfaceColor;
			float _GlitterBlendType;
			float _GlitterMode;
			float _GlitterShape;
			float _GlitterCenterSize;
			float _GlitterJaggyFix;
			float _GlitterTextureRotation;
			float2 _GlitterUVPanning;
			
			float _GlitterHueShiftEnabled;
			float _GlitterHueShiftSpeed;
			float _GlitterHueShift;
			float _GlitterHideInShadow;
			float _GlitterScaleWithLighting;
			
			float _GlitterRandomColors;
			float2 _GlitterMinMaxSaturation;
			float2 _GlitterMinMaxBrightness;
			float _GlitterRandomSize;
			float4 _GlitterMinMaxSize;
			float _GlitterRandomRotation;
			
			#if defined(PROP_GLITTERMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlitterMask;
			#endif
			float4 _GlitterMask_ST;
			float2 _GlitterMaskPan;
			float _GlitterMaskUV;
			float _GlitterMaskChannel;
			float _GlitterMaskInvert;
			float _GlitterMaskGlobalMask;
			float _GlitterMaskGlobalMaskBlendType;
			#if defined(PROP_GLITTERCOLORMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlitterColorMap;
			#endif
			float4 _GlitterColorMap_ST;
			float2 _GlitterColorMapPan;
			float _GlitterColorMapUV;
			#if defined(PROP_GLITTERTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlitterTexture;
			#endif
			float4 _GlitterTexture_ST;
			float2 _GlitterTexturePan;
			float _GlitterTextureUV;
			
			float _GlitterALEnabled;
			float _GlitterALAlphaAddBand;
			float4 _GlitterALAlphaAdd;
			float _GlitterALMinBrightnessBand;
			float4 _GlitterALMinBrightnessAdd;
			float _GlitterALMaxBrightnessBand;
			float4 _GlitterALMaxBrightnessAdd;
			float _GlitterALSizeAddBand;
			float4 _GlitterALSizeAdd;
			float _GlitterALChronoSparkleSpeedType;
			float _GlitterALChronoSparkleSpeedBand;
			float _GlitterALChronoSparkleSpeed;
			float _GlitterALChronoRotationSpeedType;
			float _GlitterALChronoRotationSpeedBand;
			float _GlitterALChronoRotationSpeed;
			#endif
			//endex
			
			//ifex _SubsurfaceScattering==0
			#ifdef POI_SUBSURFACESCATTERING
			float4 _SSSColor;
			#if defined(PROP_SSSTHICKNESSMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _SSSThicknessMap;
			#endif
			float4 _SSSThicknessMap_ST;
			float2 _SSSThicknessMapPan;
			float _SSSThicknessMapUV;
			float _SSSThicknessMapChannel;
			
			float _SSSThicknessMod;
			float _SSSStrength;
			float _SSSSpread;
			float _SSSDistortion;
			float _SSSBaseColorMix;
			#endif
			//endex
			
			//ifex _MochieBRDF==0
			#ifdef MOCHIE_PBR
			#if defined(PROP_MOCHIEMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MochieMetallicMaps;
			float _PBRMapsStochastic;
			#endif
			float4 _MochieMetallicMaps_ST;
			float2 _MochieMetallicMapsPan;
			float _MochieMetallicMapsUV;
			float _MochieMetallicMapsStochastic;
			float _MochieMetallicMapInvert;
			float _MochieRoughnessMapInvert;
			float _MochieReflectionMaskInvert;
			float _MochieSpecularMaskInvert;
			float _MochieMetallicMapsMetallicChannel;
			float _MochieMetallicMapsRoughnessChannel;
			float _MochieMetallicMapsReflectionMaskChannel;
			float _MochieMetallicMapsSpecularMaskChannel;
			float _PBRNormalSelect;
			
			float _MochieReflectionTintThemeIndex;
			float _MochieSpecularTintThemeIndex;
			
			float _MochieRoughnessMultiplier;
			float _MochieMetallicMultiplier;
			float _MochieReflectionStrength;
			float _MochieSpecularStrength;
			float4 _MochieSpecularTint;
			float4 _MochieReflectionTint;
			float _MochieLitFallback;
			float _IgnoreCastedShadows;
			float _PBRSplitMaskSample;
			float _PBRSplitMaskStochastic;
			float4 _PBRMaskScaleTiling;
			float _MochieMetallicMasksUV;
			float4 _MochieMetallicMasksPan;
			
			float _Specular2ndLayer;
			float _MochieSpecularStrength2;
			float _MochieRoughnessMultiplier2;
			float _RefSpecFresnel;
			float _RefSpecFresnelBack;
			samplerCUBE _MochieReflCube;
			float4 _MochieReflCube_HDR;
			float _MochieForceFallback;
			float _MochieGSAAEnabled;
			float _PoiGSAAVariance;
			float _PoiGSAAThreshold;
			float _BRDFTPSReflectionMaskStrength;
			float _BRDFTPSSpecularMaskStrength;
			float _BRDFTPSDepthEnabled;
			
			float _MochieMetallicGlobalMask;
			float _MochieMetallicGlobalMaskBlendType;
			float _MochieSmoothnessGlobalMask;
			float _MochieSmoothnessGlobalMaskBlendType;
			float _MochieReflectionStrengthGlobalMask;
			float _MochieReflectionStrengthGlobalMaskBlendType;
			float _MochieSpecularStrengthGlobalMask;
			float _MochieSpecularStrengthGlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _ClearCoatBRDF==0
			#ifdef POI_CLEARCOAT
			#if defined(PROP_CLEARCOATMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ClearCoatMaps;
			float4 _ClearCoatMaps_ST;
			float2 _ClearCoatMapsPan;
			float _ClearCoatMapsUV;
			float _ClearCoatMapsStochastic;
			#endif
			float _ClearCoatMapsClearCoatMaskChannel;
			float _ClearCoatMapsRoughnessChannel;
			float _ClearCoatMapsReflectionMaskChannel;
			float _ClearCoatMapsSpecularMaskChannel;
			float _ClearCoatBRDF;
			float _ClearCoatReflectionStrength;
			float _ClearCoatSpecularStrength;
			float _ClearCoatStrength;
			float _ClearCoatSmoothness;
			float4 _ClearCoatReflectionTint;
			float _ClearCoatReflectionTintThemeIndex;
			float4 _ClearCoatSpecularTint;
			float _ClearCoatSpecularTintThemeIndex;
			float _ClearCoatSmoothnessMapInvert;
			float _ClearCoatMaskInvert;
			float _ClearCoatReflectionMaskInvert;
			float _ClearCoatSpecularMaskInvert;
			float _ClearCoatTPSMaskStrength;
			float _ClearCoatTPSDepthMaskEnabled;
			float _ClearCoatNormalSelect;
			
			samplerCUBE _ClearCoatFallback;
			float4 _ClearCoatFallback_HDR;
			float _ClearCoatForceFallback;
			float _ClearCoatLitFallback;
			float _CCIgnoreCastedShadows;
			float _ClearCoatGSAAEnabled;
			float _ClearCoatGSAAVariance;
			float _ClearCoatGSAAThreshold;
			float _ClearcoatFresnel;
			
			float _ClearCoatGlobalMask;
			float _ClearCoatGlobalMaskBlendType;
			float _ClearCoatSmoothnessGlobalMask;
			float _ClearCoatSmoothnessGlobalMaskBlendType;
			float _ClearCoatReflectionStrengthGlobalMask;
			float _ClearCoatReflectionStrengthGlobalMaskBlendType;
			float _ClearCoatSpecularStrengthGlobalMask;
			float _ClearCoatSpecularStrengthGlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _EnableEnvironmentalRim==0
			#ifdef POI_ENVIRORIM
			#if defined(PROP_RIMENVIROMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RimEnviroMask;
			#endif
			float4 _RimEnviroMask_ST;
			float2 _RimEnviroMaskPan;
			float _RimEnviroMaskUV;
			float _RimEnviroChannel;
			
			float _RimEnviroBlur;
			float _RimEnviroMinBrightness;
			float _RimEnviroWidth;
			float _RimEnviroSharpness;
			float _RimEnviroIntensity;
			#endif
			//endex
			
			//ifex _StylizedSpecular==0
			#ifdef POI_STYLIZED_StylizedSpecular
			#if defined(PROP_HIGHCOLOR_TEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _HighColor_Tex;
			#endif
			float4 _HighColor_Tex_ST;
			float2 _HighColor_TexPan;
			float _HighColor_TexUV;
			
			#if defined(PROP_SET_HIGHCOLORMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Set_HighColorMask;
			#endif
			float4 _Set_HighColorMask_ST;
			float2 _Set_HighColorMaskPan;
			float _Set_HighColorMaskUV;
			float _Set_HighColorMaskChannel;
			float _Tweak_HighColorMaskLevel;
			
			/*
			#if defined(PROP_StylizedSpecularOPTMAP1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _StylizedSpecularOptMap1;
			#endif
			float4 _StylizedSpecularOptMap1_ST;
			float2 _StylizedSpecularOptMap1Pan;
			float _StylizedSpecularOptMap1UV;
			
			#if defined(PROP_StylizedSpecularOPTMAP2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _StylizedSpecularOptMap2;
			#endif
			float4 _StylizedSpecularOptMap2_ST;
			float2 _StylizedSpecularOptMap2Pan;
			float _StylizedSpecularOptMap2UV;
			*/
			
			float4 _HighColor;
			float _UseLightColor;
			
			float _HighColor_Power;
			float _StylizedSpecularFeather;
			float _Layer1Strength;
			
			float _StylizedSpecularIgnoreNormal;
			float _StylizedSpecularIgnoreShadow;
			
			float _Layer2Size;
			float _StylizedSpecular2Feather;
			float _Layer2Strength;
			float _SSIgnoreCastedShadows;
			float _StylizedSpecularStrength;
			float _UseSpecularOptMap2;
			float _HighColorThemeIndex;
			float _Is_BlendAddToHiColor;
			float _Is_SpecularToHighColor;
			#endif
			//endex
			
			//ifex _EnablePathing==0
			#ifdef POI_PATHING
			
			#if defined(PROP_PATHINGMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _PathingMap;
			SamplerState SmpRepeatPoint;
			#endif
			float4 _PathingMap_ST;
			float2 _PathingMapPan;
			float _PathingMapUV;
			
			#if defined(PROP_PATHINGCOLORMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _PathingColorMap;
			#endif
			float4 _PathingColorMap_ST;
			float2 _PathingColorMapPan;
			float _PathingColorMapUV;
			float _PathingOverrideAlpha;
			// Fill, 0, Path, 1, Loop, 2
			float _PathTypeR;
			float _PathTypeG;
			float _PathTypeB;
			float _PathTypeA;
			float _PathGradientType;
			half4 _PathWidth;
			float4 _PathTime;
			float4 _PathOffset;
			float4 _PathSpeed;
			float4 _PathColorR;
			float4 _PathColorG;
			float4 _PathColorB;
			float4 _PathColorA;
			float4 _PathEmissionStrength;
			float4 _PathSoftness;
			float4 _PathSegments;
			
			float _PathColorRThemeIndex;
			float _PathColorGThemeIndex;
			float _PathColorBThemeIndex;
			float _PathColorAThemeIndex;
			
			#ifdef POI_AUDIOLINK
			float _PathALAutoCorrelator;
			float _PathALAutoCorrelatorMode;
			float _PathALAutoCorrelatorR;
			float2 _PathALAutoCorrelatorRangeR;
			float _PathALAutoCorrelatorG;
			float2 _PathALAutoCorrelatorRangeG;
			float _PathALAutoCorrelatorB;
			float2 _PathALAutoCorrelatorRangeB;
			float _PathALAutoCorrelatorA;
			float2 _PathALAutoCorrelatorRangeA;
			
			float _PathALHistory;
			float _PathALHistoryMode;
			float _PathALHistoryBandR;
			float2 _PathALHistoryRangeR;
			float _PathALHistoryR;
			float _PathALHistoryBandG;
			float2 _PathALHistoryRangeG;
			float _PathALHistoryG;
			float _PathALHistoryBandB;
			float2 _PathALHistoryRangeB;
			float _PathALHistoryB;
			float _PathALHistoryBandA;
			float2 _PathALHistoryRangeA;
			float _PathALHistoryA;
			
			float _PathALColorChord;
			float _PathALCCR;
			float _PathALCCG;
			float _PathALCCB;
			float _PathALCCA;
			
			// Time Offset
			float _PathALTimeOffset;
			half _AudioLinkPathTimeOffsetBandR;
			half2 _AudioLinkPathTimeOffsetR;
			half _AudioLinkPathTimeOffsetBandG;
			half2 _AudioLinkPathTimeOffsetG;
			half _AudioLinkPathTimeOffsetBandB;
			half2 _AudioLinkPathTimeOffsetB;
			half _AudioLinkPathTimeOffsetBandA;
			half2 _AudioLinkPathTimeOffsetA;
			
			// Emission Offset
			float _PathALEmissionOffset;
			half _AudioLinkPathEmissionAddBandR;
			half2 _AudioLinkPathEmissionAddR;
			half _AudioLinkPathEmissionAddBandG;
			half2 _AudioLinkPathEmissionAddG;
			half _AudioLinkPathEmissionAddBandB;
			half2 _AudioLinkPathEmissionAddB;
			half _AudioLinkPathEmissionAddBandA;
			half2 _AudioLinkPathEmissionAddA;
			
			// Length Offset
			float _PathALWidthOffset;
			half _AudioLinkPathWidthOffsetBandR;
			half2 _AudioLinkPathWidthOffsetR;
			half _AudioLinkPathWidthOffsetBandG;
			half2 _AudioLinkPathWidthOffsetG;
			half _AudioLinkPathWidthOffsetBandB;
			half2 _AudioLinkPathWidthOffsetB;
			half _AudioLinkPathWidthOffsetBandA;
			half2 _AudioLinkPathWidthOffsetA;
			
			// Chrono Time
			float _PathALChrono;
			float _PathChronoBandR;
			float _PathChronoTypeR;
			float _PathChronoSpeedR;
			float _PathChronoBandG;
			float _PathChronoTypeG;
			float _PathChronoSpeedG;
			float _PathChronoBandB;
			float _PathChronoTypeB;
			float _PathChronoSpeedB;
			float _PathChronoBandA;
			float _PathChronoTypeA;
			float _PathChronoSpeedA;
			#endif
			#endif
			//endex
			
			//ifex _EnableMirrorOptions==0
			#ifdef POI_MIRROR
			float _VisibilityMode;
			float _Mirror;
			#if defined(PROP_MIRRORTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MirrorTexture;
			#endif
			float4 _MirrorColor;
			float _MirrorColorThemeIndex;
			float _MirrorTextureBlendType;
			float4 _MirrorTexture_ST;
			float2 _MirrorTexturePan;
			float _MirrorTextureUV;
			float _MirrorTextureEnabled;
			float _MirrorTextureForceEnabled;
			float _VisibilityVRCRegular;
			float _VisibilityVRCMirrorVR;
			float _VisibilityVRCMirrorDesktop;
			float _VisibilityVRCCameraVR;
			float _VisibilityVRCCameraDesktop;
			float _VisibilityVRCCameraScreenshot;
			#endif
			//endex
			
			//ifex _EnableTouchGlow==0
			#ifdef GRAIN
			#if defined(PROP_DEPTHMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DepthMask;
			#endif
			float4 _DepthMask_ST;
			float2 _DepthMaskPan;
			float _DepthMaskUV;
			float _DepthMaskChannel;
			float _DepthMaskGlobalMask;
			float _DepthMaskGlobalMaskBlendType;
			
			// Color
			float _DepthColorToggle;
			float _DepthColorBlendMode;
			#if defined(PROP_DEPTHTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DepthTexture;
			#endif
			float4 _DepthTexture_ST;
			float2 _DepthTexturePan;
			float _DepthTextureUV;
			
			float3 _DepthColor;
			float _DepthColorThemeIndex;
			float _DepthColorMinDepth;
			float _DepthColorMaxDepth;
			float _DepthColorMinValue;
			float _DepthColorMaxValue;
			float _DepthEmissionStrength;
			
			// Emission
			
			// Alpha
			float _DepthAlphaToggle;
			float _DepthAlphaMinValue;
			float _DepthAlphaMaxValue;
			float _DepthAlphaMinDepth;
			float _DepthAlphaMaxDepth;
			#endif
			//endex
			
			float _PPLightingMultiplier;
			float _PPLightingAddition;
			float _PPEmissionMultiplier;
			float _PPFinalColorMultiplier;
			
			//ifex _TextEnabled==0
			#ifdef EFFECT_BUMP
			sampler2D _TextGlyphs;
			float4 _TextGlyphs_ST;
			float4 _TextGlyphs_TexelSize;
			float _TextFPSUV;
			float _TextTimeUV;
			float _TextPositionUV;
			float _TextNumericUV;
			float _TextPixelRange;
			
			float _TextFPSEnabled;
			float _TextPositionEnabled;
			float _TextTimeEnabled;
			float _TextNumericEnabled;
			
			float4 _TextFPSColor;
			float _TextFPSEmissionStrength;
			fixed4 _TextFPSPadding;
			float2 _TextFPSOffset;
			float2 _TextFPSScale;
			float _TextFPSRotation;
			float _TextFPSOutlineColor;
			
			fixed _TextPositionVertical;
			float4 _TextPositionColor;
			float _TextPositionEmissionStrength;
			fixed4 _TextPositionPadding;
			float2 _TextPositionOffset;
			float2 _TextPositionScale;
			float _TextPositionRotation;
			
			float4 _TextTimeColor;
			float _TextTimeEmissionStrength;
			fixed4 _TextTimePadding;
			float2 _TextTimeOffset;
			float2 _TextTimeScale;
			float _TextTimeRotation;
			
			float4 _TextNumericColor;
			float _TextNumericEmissionStrength;
			fixed4 _TextNumericPadding;
			float2 _TextNumericOffset;
			float2 _TextNumericScale;
			float _TextNumericRotation;
			float _TextNumericValue;
			float _TextNumericWholeDigits;
			float _TextNumericDecimalDigits;
			float _TextNumericTrimZeroes;
			
			float _TextFPSColorThemeIndex;
			float _TextPositionColorThemeIndex;
			float _TextTimeColorThemeIndex;
			float _TextNumericColorThemeIndex;
			
			float3 globalTextEmission;
			
			#define ASCII_SPACE 32
			#define ASCII_LEFT_PARENTHESIS 40
			#define ASCII_RIGHT_PARENTHESIS 41
			#define ASCII_POSITIVE 43
			#define ASCII_PERIOD 46
			#define ASCII_NEGATIVE 45
			#define ASCII_COMMA 44
			#define ASCII_E 69
			#define ASCII_F 70
			#define ASCII_I 73
			#define ASCII_M 77
			#define ASCII_O 79
			#define ASCII_P 80
			#define ASCII_R 82
			#define ASCII_S 83
			#define ASCII_T 84
			#define ASCII_SEMICOLON 58
			#define glyphWidth 0.0625
			
			#endif
			//endex
			
			//ifex _FXProximityColor==0
			float _FXProximityColor;
			float _FXProximityColorType;
			float3 _FXProximityColorMinColor;
			float3 _FXProximityColorMaxColor;
			float _FXProximityColorMinColorThemeIndex;
			float _FXProximityColorMaxColorThemeIndex;
			float _FXProximityColorMinDistance;
			float _FXProximityColorMaxDistance;
			float _FXProximityColorBackFace;
			//endex
			
			//ifex _PostProcess==0
			#ifdef POSTPROCESS
			#if defined(PROP_PPMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _PPMask;
			#endif
			float4 _PPMask_ST;
			float2 _PPMaskPan;
			float _PPMaskUV;
			float _PPMaskChannel;
			float _PPMaskInvert;
			
			float3 _PPTint;
			float3 _PPRGB;
			float _PPHue;
			float _PPContrast;
			float _PPSaturation;
			float _PPBrightness;
			float _PPLightness;
			float _PPHDR;
			
			float _PPPosterization;
			float _PPPosterizationAmount;
			const static float COLORS = 32;
			
			#endif
			//endex
			
			//ifex _PoiInternalParallax==0
			#ifdef POI_INTERNALPARALLAX
			#if defined(PROP_PARALLAXINTERNALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ParallaxInternalMap;
			#endif
			float4 _ParallaxInternalMap_ST;
			float2 _ParallaxInternalMapPan;
			
			#if defined(PROP_PARALLAXINTERNALMAPMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ParallaxInternalMapMask;
			#endif
			float4 _ParallaxInternalMapMask_ST;
			float2 _ParallaxInternalMapMaskPan;
			float _ParallaxInternalMapMaskUV;
			float _ParallaxInternalMapMaskChannel;
			
			float _ParallaxInternalIterations;
			float _ParallaxInternalMinDepth;
			float _ParallaxInternalMaxDepth;
			float _ParallaxInternalMinFade;
			float _ParallaxInternalMaxFade;
			float4 _ParallaxInternalMinColor;
			float4 _ParallaxInternalMaxColor;
			float _ParallaxInternalMinColorThemeIndex;
			float _ParallaxInternalMaxColorThemeIndex;
			// float4 _ParallaxInternalPanSpeed;
			float4 _ParallaxInternalPanDepthSpeed;
			float _ParallaxInternalHeightmapMode;
			float _ParallaxInternalHeightFromAlpha;
			
			float _ParallaxInternalHueShiftEnabled;
			float _ParallaxInternalHueShift;
			float _ParallaxInternalHueShiftSpeed;
			float _ParallaxInternalHueShiftPerLevel;
			float _ParallaxInternalSurfaceBlendMode;
			float _ParallaxInternalBlendMode;
			// float _ParallaxInternalHueShiftPerLevelSpeed;
			#endif
			//endex
			
			//ifex _NormalCorrect==0
			#ifdef POI_NORMALCORRECT
			float _NormalCorrectAmount;
			float3 _NormalCorrectOrigin;
			#endif
			//endex
			
			//ifex _VideoEffectsEnable==0
			#ifdef POI_VIDEO_EFFECTS
			float _VideoEffectsEnable;
			#if defined(PROP_VIDEOPIXELTEXTURE) || !defined(OPTIMIZER_ENABLED)
			sampler2D _VideoPixelTexture;
			float4 _VideoPixelTexture_ST;
			float _VideoPixelTextureUV;
			#endif
			#if defined(PROP_VIDEOMASKTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VideoMaskTexture;
			float4 _VideoMaskTexture_ST;
			float2 _VideoMaskTexturePan;
			float _VideoMaskTextureUV;
			float _VideoMaskTextureChannel;
			#endif
			
			float _VideoType;
			float2 _VideoResolution;
			sampler2D _VideoGameboyRamp;
			float _VideoBacklight;
			float _VideoCRTRefreshRate;
			float _VideoCRTPixelEnergizedTime;
			float _VideoRepeatVideoTexture;
			float _VideoPixelateToResolution;
			float2 _VideoMaskPanning;
			
			float _VideoSaturation;
			float _VideoContrast;
			float _VideoEmissionEnabled;
			#endif
			//endex
			
			//ifex _BacklightEnabled!=1
			#ifdef POI_BACKLIGHT
			float4 _BacklightColor;
			#if defined(PROP_BACKLIGHTCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BacklightColorTex;
			float4 _BacklightColorTex_ST;
			float2 _BacklightColorTexPan;
			float _BacklightColorTexUV;
			#endif
			float _BacklightMainStrength;
			float _BacklightNormalStrength;
			float _BacklightBorder;
			float _BacklightBlur;
			float _BacklightDirectivity;
			float _BacklightViewStrength;
			int _BacklightReceiveShadow;
			int _BacklightBackfaceMask;
			#endif
			//endex
			
			//ifex _BSSEnabled!=1
			#ifdef POIBS_ENABLE
			float _CustomColors;
			//ifex _BSSBloomfog!=1
			#ifdef POIBS_BLOOMFOG
			float _FogStartOffset;
			float _FogScale;
			float _FogHeightOffset;
			float _FogHeightScale;
			
			uniform float2 _CustomFogTextureToScreenRatio;
			uniform float _StereoCameraEyeOffset;
			
			uniform float _CustomFogOffset;
			uniform float _CustomFogAttenuation;
			uniform float _CustomFogHeightFogStartY;
			uniform float _CustomFogHeightFogHeight;
			uniform sampler2D _BloomPrePassTexture;
			#endif
			//endex
			#endif
			//endex
			
			//ifex _VoronoiEnabled!=1
			#ifdef POI_VORONOI
			#if defined(PROP_VORONOIMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VoronoiMask;
			float4 _VoronoiMask_ST;
			float2 _VoronoiMaskPan;
			float _VoronoiMaskUV;
			int _VoronoiMaskChannel;
			#endif
			#if defined(PROP_VORONOINOISE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VoronoiNoise;
			float4 _VoronoiNoise_ST;
			float2 _VoronoiNoisePan;
			float _VoronoiNoiseUV;
			int _VoronoiNoiseChannel;
			#endif
			int _VoronoiSpace;
			int _VoronoiBlend;
			int _VoronoiType;
			float4 _VoronoiOuterColor;
			float _VoronoiOuterEmissionStrength;
			float4 _VoronoiInnerColor;
			float _VoronoiInnerEmissionStrength;
			float _VoronoiPower;
			float2 _VoronoiGradient;
			float _VoronoiScale;
			float3 _VoronoiSpeed;
			float _VoronoiEnableRandomCellColor;
			float2 _VoronoiRandomMinMaxSaturation;
			float2 _VoronoiRandomMinMaxBrightness;
			float _VoronoiNoiseIntensity;
			int _VoronoiAffectsMaterialAlpha;
			float _VoronoiGlobalMask;
			float _VoronoiGlobalMaskBlendType;
			
			// AudioLink
			int _AudioLinkVoronoiInnerEmissionBand;
			float2 _AudioLinkVoronoiInnerEmission;
			int _AudioLinkVoronoiOuterEmissionBand;
			float2 _AudioLinkVoronoiOuterEmission;
			
			int _AudioLinkVoronoiGradientMinAddBand;
			float _AudioLinkVoronoiGradientMinAdd;
			int _AudioLinkVoronoiGradientMaxAddBand;
			float _AudioLinkVoronoiGradientMaxAdd;
			
			int _AudioLinkVoronoiChronoSpeedXType;
			int _AudioLinkVoronoiChronoSpeedXBand;
			float _AudioLinkVoronoiChronoSpeedXSpeed;
			int _AudioLinkVoronoiChronoSpeedYType;
			int _AudioLinkVoronoiChronoSpeedYBand;
			float _AudioLinkVoronoiChronoSpeedYSpeed;
			int _AudioLinkVoronoiChronoSpeedZType;
			int _AudioLinkVoronoiChronoSpeedZBand;
			float _AudioLinkVoronoiChronoSpeedZSpeed;
			#endif
			//endex
			
			struct appdata
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 tangent : TANGENT;
				float4 color : COLOR;
				float2 uv0 : TEXCOORD0;
				float2 uv1 : TEXCOORD1;
				float2 uv2 : TEXCOORD2;
				float2 uv3 : TEXCOORD3;
				uint vertexId : SV_VertexID;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};
			
			struct VertexOut
			{
				float4 pos : SV_POSITION;
				float4 uv[2] : TEXCOORD0;
				float3 normal : TEXCOORD2;
				float4 tangent : TEXCOORD3;
				float4 worldPos : TEXCOORD4;
				float4 localPos : TEXCOORD5;
				float4 vertexColor : TEXCOORD6;
				float4 lightmapUV : TEXCOORD7;
				float2 fogCoord: TEXCOORD10;
				UNITY_SHADOW_COORDS(11)
				
				UNITY_VERTEX_INPUT_INSTANCE_ID
				UNITY_VERTEX_OUTPUT_STEREO
			};
			
			struct PoiMesh
			{
				
				// 0 Vertex normal
				// 1 Fragment normal
				float3 normals[2];
				float3 objNormal;
				float3 tangentSpaceNormal;
				float3 binormal[2];
				float3 tangent[2];
				float3 worldPos;
				float3 localPos;
				float3 objectPosition;
				float isFrontFace;
				float4 vertexColor;
				float4 lightmapUV;
				// 0-3 UV0-UV3
				// 4 Panosphere UV
				// 5 world pos xz
				// 6 Polar UV
				// 7 Distorted UV
				float2 uv[9];
				float2 parallaxUV;
				float2 dx;
				float2 dy;
			};
			
			struct PoiCam
			{
				float3 viewDir;
				float3 forwardDir;
				float3 worldPos;
				float distanceToVert;
				float4 clipPos;
				float4 screenSpacePosition;
				float3 reflectionDir;
				float3 vertexReflectionDir;
				float3 tangentViewDir;
				float4 posScreenSpace;
				float2 posScreenPixels;
				float2 screenUV;
				float vDotN;
				float4 worldDirection;
				
			};
			
			struct PoiMods
			{
				float4 Mask;
				float audioLink[5];
				float audioLinkAvailable;
				float audioLinkVersion;
				float4 audioLinkTexture;
				float2 detailMask;
				float2 backFaceDetailIntensity;
				float globalEmission;
				float4 globalColorTheme[12];
				float globalMask[16];
				float ALTime[8];
			};
			
			struct PoiLight
			{
				
				float3 direction;
				float attenuation;
				float attenuationStrength;
				float3 directColor;
				float3 indirectColor;
				float occlusion;
				float shadowMask;
				float detailShadow;
				float3 halfDir;
				float lightMap;
				float lightMapNoAttenuation;
				float3 rampedLightMap;
				float vertexNDotL;
				float nDotL;
				float nDotV;
				float vertexNDotV;
				float nDotH;
				float vertexNDotH;
				float lDotv;
				float lDotH;
				float nDotLSaturated;
				float nDotLNormalized;
				#ifdef POI_PASS_ADD
				float additiveShadow;
				#endif
				float3 finalLighting;
				float3 finalLightAdd;
				float3 LTCGISpecular;
				float3 LTCGIDiffuse;
				float directLuminance;
				float indirectLuminance;
				float finalLuminance;
				
				#if defined(VERTEXLIGHT_ON)
				// Non Important Lights
				float4 vDotNL;
				float4 vertexVDotNL;
				float3 vColor[4];
				float4 vCorrectedDotNL;
				float4 vAttenuation;
				float4 vSaturatedDotNL;
				float3 vPosition[4];
				float3 vDirection[4];
				float3 vFinalLighting;
				float3 vHalfDir[4];
				half4 vDotNH;
				half4 vertexVDotNH;
				half4 vDotLH;
				#endif
				
			};
			
			struct PoiVertexLights
			{
				
				float3 direction;
				float3 color;
				float attenuation;
			};
			
			struct PoiFragData
			{
				float smoothness;
				float smoothness2;
				float metallic;
				float specularMask;
				float reflectionMask;
				
				float3 baseColor;
				float3 finalColor;
				float alpha;
				float3 emission;
				float toggleVertexLights;
			};
			
			float4 poiTransformClipSpacetoScreenSpaceFrag(float4 clipPos)
			{
				float4 positionSS = float4(clipPos.xyz * clipPos.w, clipPos.w);
				positionSS.xy = positionSS.xy / _ScreenParams.xy;
				return positionSS;
			}
			
			// glsl_mod behaves better on negative numbers, and
			// in some situations actually outperforms HLSL's fmod()
			#ifndef glsl_mod
			#define glsl_mod(x, y) (((x) - (y) * floor((x) / (y))))
			#endif
			
			uniform float random_uniform_float_only_used_to_stop_compiler_warnings = 0.0f;
			
			float2 poiUV(float2 uv, float4 tex_st)
			{
				return uv * tex_st.xy + tex_st.zw;
			}
			
			float2 vertexUV(in VertexOut o, int index)
			{
				switch(index)
				{
					case 0:
					return o.uv[0].xy;
					case 1:
					return o.uv[0].zw;
					case 2:
					return o.uv[1].xy;
					case 3:
					return o.uv[1].zw;
					default:
					return o.uv[0].xy;
				}
			}
			
			float2 vertexUV(in appdata v, int index)
			{
				switch(index)
				{
					case 0:
					return v.uv0.xy;
					case 1:
					return v.uv1.xy;
					case 2:
					return v.uv2.xy;
					case 3:
					return v.uv3.xy;
					default:
					return v.uv0.xy;
				}
			}
			
			//Lighting Helpers
			float calculateluminance(float3 color)
			{
				return color.r * 0.299 + color.g * 0.587 + color.b * 0.114;
			}
			
			// Set by VRChat (as of open beta 1245)
			// _VRChatCameraMode: 0 => Normal, 1 => VR HandCam, 2 => Desktop Handcam, 3 => Screenshot/Photo
			// _VRChatMirrorMode: 0 => Normal, 1 => Mirror (VR), 2 => Mirror (Deskie)
			float _VRChatCameraMode;
			float _VRChatMirrorMode;
			
			float VRCCameraMode()
			{
				return _VRChatCameraMode;
			}
			
			float VRCMirrorMode()
			{
				return _VRChatMirrorMode;
			}
			
			bool IsInMirror()
			{
				return unity_CameraProjection[2][0] != 0.f || unity_CameraProjection[2][1] != 0.f;
			}
			
			bool IsOrthographicCamera()
			{
				return unity_OrthoParams.w == 1 || UNITY_MATRIX_P[3][3] == 1;
			}
			
			float shEvaluateDiffuseL1Geomerics_local(float L0, float3 L1, float3 n)
			{
				// average energy
				float R0 = max(0, L0);
				
				// avg direction of incoming light
				float3 R1 = 0.5f * L1;
				
				// directional brightness
				float lenR1 = length(R1);
				
				// linear angle between normal and direction 0-1
				//float q = 0.5f * (1.0f + dot(R1 / lenR1, n));
				//float q = dot(R1 / lenR1, n) * 0.5 + 0.5;
				float q = dot(normalize(R1), n) * 0.5 + 0.5;
				q = saturate(q); // Thanks to ScruffyRuffles for the bug identity.
				
				// power for q
				// lerps from 1 (linear) to 3 (cubic) based on directionality
				float p = 1.0f + 2.0f * lenR1 / R0;
				
				// dynamic range constant
				// should vary between 4 (highly directional) and 0 (ambient)
				float a = (1.0f - lenR1 / R0) / (1.0f + lenR1 / R0);
				
				return R0 * (a + (1.0f - a) * (p + 1.0f) * pow(q, p));
			}
			
			half3 BetterSH9(half4 normal)
			{
				float3 indirect;
				float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) + float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0;
				indirect.r = shEvaluateDiffuseL1Geomerics_local(L0.r, unity_SHAr.xyz, normal.xyz);
				indirect.g = shEvaluateDiffuseL1Geomerics_local(L0.g, unity_SHAg.xyz, normal.xyz);
				indirect.b = shEvaluateDiffuseL1Geomerics_local(L0.b, unity_SHAb.xyz, normal.xyz);
				indirect = max(0, indirect);
				indirect += SHEvalLinearL2(normal);
				return indirect;
			}
			
			// Silent's code ends here
			
			float3 getCameraForward()
			{
				#if UNITY_SINGLE_PASS_STEREO
				float3 p1 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 1, 1));
				float3 p2 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 0, 1));
				#else
				float3 p1 = mul(unity_CameraToWorld, float4(0, 0, 1, 1)).xyz;
				float3 p2 = mul(unity_CameraToWorld, float4(0, 0, 0, 1)).xyz;
				#endif
				return normalize(p2 - p1);
			}
			
			half3 GetSHLength()
			{
				half3 x, x1;
				x.r = length(unity_SHAr);
				x.g = length(unity_SHAg);
				x.b = length(unity_SHAb);
				x1.r = length(unity_SHBr);
				x1.g = length(unity_SHBg);
				x1.b = length(unity_SHBb);
				return x + x1;
			}
			
			float3 BoxProjection(float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax)
			{
				#if UNITY_SPECCUBE_BOX_PROJECTION
				//UNITY_BRANCH
				if (cubemapPosition.w > 0)
				{
					float3 factors = ((direction > 0 ? boxMax : boxMin) - position) / direction;
					float scalar = min(min(factors.x, factors.y), factors.z);
					direction = direction * scalar + (position - cubemapPosition.xyz);
				}
				#endif
				return direction;
			}
			
			float poiMax(float2 i)
			{
				return max(i.x, i.y);
			}
			
			float poiMax(float3 i)
			{
				return max(max(i.x, i.y), i.z);
			}
			
			float poiMax(float4 i)
			{
				return max(max(max(i.x, i.y), i.z), i.w);
			}
			
			float3 calculateNormal(in float3 baseNormal, in PoiMesh poiMesh, in Texture2D normalTexture, in float4 normal_ST, in float2 normalPan, in float normalUV, in float normalIntensity)
			{
				float3 normal = UnpackScaleNormal(POI2D_SAMPLER_PAN(normalTexture, _MainTex, poiUV(poiMesh.uv[normalUV], normal_ST), normalPan), normalIntensity);
				return normalize(
				normal.x * poiMesh.tangent[0] +
				normal.y * poiMesh.binormal[0] +
				normal.z * baseNormal
				);
			}
			
			float remap(float x, float minOld, float maxOld, float minNew = 0, float maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float2 remap(float2 x, float2 minOld, float2 maxOld, float2 minNew = 0, float2 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float3 remap(float3 x, float3 minOld, float3 maxOld, float3 minNew = 0, float3 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float4 remap(float4 x, float4 minOld, float4 maxOld, float4 minNew = 0, float4 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float remapClamped(float minOld, float maxOld, float x, float minNew = 0, float maxNew = 1)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float2 remapClamped(float2 minOld, float2 maxOld, float2 x, float2 minNew, float2 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float3 remapClamped(float3 minOld, float3 maxOld, float3 x, float3 minNew, float3 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float4 remapClamped(float4 minOld, float4 maxOld, float4 x, float4 minNew, float4 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			float2 calcParallax(in float height, in PoiCam poiCam)
			{
				return ((height * - 1) + 1) * (poiCam.tangentViewDir.xy / poiCam.tangentViewDir.z);
			}
			
			/*
			0: Zero	                float4(0.0, 0.0, 0.0, 0.0),
			1: One	                float4(1.0, 1.0, 1.0, 1.0),
			2: DstColor	            destinationColor,
			3: SrcColor	            sourceColor,
			4: OneMinusDstColor	    float4(1.0, 1.0, 1.0, 1.0) - destinationColor,
			5: SrcAlpha	            sourceColor.aaaa,
			6: OneMinusSrcColor	    float4(1.0, 1.0, 1.0, 1.0) - sourceColor,
			7: DstAlpha	            destinationColor.aaaa,
			8: OneMinusDstAlpha	    float4(1.0, 1.0, 1.0, 1.0) - destinationColor.,
			9: SrcAlphaSaturate     saturate(sourceColor.aaaa),
			10: OneMinusSrcAlpha	float4(1.0, 1.0, 1.0, 1.0) - sourceColor.aaaa,
			*/
			
			float4 poiBlend(const float sourceFactor, const  float4 sourceColor, const  float destinationFactor, const  float4 destinationColor, const float4 blendFactor)
			{
				float4 sA = 1 - blendFactor;
				const float4 blendData[11] = {
					float4(0.0, 0.0, 0.0, 0.0),
					float4(1.0, 1.0, 1.0, 1.0),
					destinationColor,
					sourceColor,
					float4(1.0, 1.0, 1.0, 1.0) - destinationColor,
					sA,
					float4(1.0, 1.0, 1.0, 1.0) - sourceColor,
					sA,
					float4(1.0, 1.0, 1.0, 1.0) - sA,
					saturate(sourceColor.aaaa),
					1 - sA,
				};
				
				return lerp(blendData[sourceFactor] * sourceColor + blendData[destinationFactor] * destinationColor, sourceColor, sA);
			}
			
			// Average
			float blendAverage(float base, float blend)
			{
				return (base + blend) / 2.0;
			}
			float3 blendAverage(float3 base, float3 blend)
			{
				return (base + blend) / 2.0;
			}
			
			// Color burn
			float blendColorBurn(float base, float blend)
			{
				return (blend == 0.0) ? blend : max((1.0 - ((1.0 - base) * rcp(random_uniform_float_only_used_to_stop_compiler_warnings + blend))), 0.0);
			}
			
			float3 blendColorBurn(float3 base, float3 blend)
			{
				return float3(blendColorBurn(base.r, blend.r), blendColorBurn(base.g, blend.g), blendColorBurn(base.b, blend.b));
			}
			
			// Color Dodge
			float blendColorDodge(float base, float blend)
			{
				return (blend == 1.0) ? blend : min(base / (1.0 - blend), 1.0);
			}
			
			float3 blendColorDodge(float3 base, float3 blend)
			{
				return float3(blendColorDodge(base.r, blend.r), blendColorDodge(base.g, blend.g), blendColorDodge(base.b, blend.b));
			}
			
			// Darken
			float blendDarken(float base, float blend)
			{
				return min(blend, base);
			}
			
			float3 blendDarken(float3 base, float3 blend)
			{
				return float3(blendDarken(base.r, blend.r), blendDarken(base.g, blend.g), blendDarken(base.b, blend.b));
			}
			
			// Exclusion
			float blendExclusion(float base, float blend)
			{
				return base + blend - 2.0 * base * blend;
			}
			float3 blendExclusion(float3 base, float3 blend)
			{
				return base + blend - 2.0 * base * blend;
			}
			
			// Reflect
			float blendReflect(float base, float blend)
			{
				return (blend == 1.0) ? blend : min(base * base / (1.0 - blend), 1.0);
			}
			
			float3 blendReflect(float3 base, float3 blend)
			{
				return float3(blendReflect(base.r, blend.r), blendReflect(base.g, blend.g), blendReflect(base.b, blend.b));
			}
			
			// Glow
			float blendGlow(float base, float blend)
			{
				return blendReflect(blend, base);
			}
			float3 blendGlow(float3 base, float3 blend)
			{
				return blendReflect(blend, base);
			}
			
			// Overlay
			float blendOverlay(float base, float blend)
			{
				return base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend));
			}
			
			float3 blendOverlay(float3 base, float3 blend)
			{
				return float3(blendOverlay(base.r, blend.r), blendOverlay(base.g, blend.g), blendOverlay(base.b, blend.b));
			}
			
			// Hard Light
			float blendHardLight(float base, float blend)
			{
				return blendOverlay(blend, base);
			}
			float3 blendHardLight(float3 base, float3 blend)
			{
				return blendOverlay(blend, base);
			}
			
			// Vivid light
			float blendVividLight(float base, float blend)
			{
				return (blend < 0.5) ? blendColorBurn(base, (2.0 * blend)) : blendColorDodge(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendVividLight(float3 base, float3 blend)
			{
				return float3(blendVividLight(base.r, blend.r), blendVividLight(base.g, blend.g), blendVividLight(base.b, blend.b));
			}
			
			// Hard mix
			float blendHardMix(float base, float blend)
			{
				return (blendVividLight(base, blend) < 0.5) ? 0.0 : 1.0;
			}
			
			float3 blendHardMix(float3 base, float3 blend)
			{
				return float3(blendHardMix(base.r, blend.r), blendHardMix(base.g, blend.g), blendHardMix(base.b, blend.b));
			}
			
			// Lighten
			float blendLighten(float base, float blend)
			{
				return max(blend, base);
			}
			
			float3 blendLighten(float3 base, float3 blend)
			{
				return float3(blendLighten(base.r, blend.r), blendLighten(base.g, blend.g), blendLighten(base.b, blend.b));
			}
			
			// Linear Burn
			float blendLinearBurn(float base, float blend)
			{
				// Note : Same implementation as BlendSubtractf
				return max(base + blend - 1.0, 0.0);
			}
			
			float3 blendLinearBurn(float3 base, float3 blend)
			{
				// Note : Same implementation as BlendSubtract
				return max(base + blend - float3(1.0, 1.0, 1.0), float3(0.0, 0.0, 0.0));
			}
			
			// Linear Dodge
			float blendLinearDodge(float base, float blend)
			{
				// Note : Same implementation as BlendAddf
				return min(base + blend, 1.0);
			}
			
			float3 blendLinearDodge(float3 base, float3 blend)
			{
				// Note : Same implementation as BlendAdd
				return base + blend;
			}
			
			// Linear light
			float blendLinearLight(float base, float blend)
			{
				return blend < 0.5 ? blendLinearBurn(base, (2.0 * blend)) : blendLinearDodge(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendLinearLight(float3 base, float3 blend)
			{
				return float3(blendLinearLight(base.r, blend.r), blendLinearLight(base.g, blend.g), blendLinearLight(base.b, blend.b));
			}
			
			// Multiply
			float blendMultiply(float base, float blend)
			{
				return base * blend;
			}
			float3 blendMultiply(float3 base, float3 blend)
			{
				return base * blend;
			}
			
			// Negation
			float blendNegation(float base, float blend)
			{
				return 1.0 - abs(1.0 - base - blend);
			}
			float3 blendNegation(float3 base, float3 blend)
			{
				return float3(1.0, 1.0, 1.0) - abs(float3(1.0, 1.0, 1.0) - base - blend);
			}
			
			// Normal
			float blendNormal(float base, float blend)
			{
				return blend;
			}
			float3 blendNormal(float3 base, float3 blend)
			{
				return blend;
			}
			
			// Phoenix
			float blendPhoenix(float base, float blend)
			{
				return min(base, blend) - max(base, blend) + 1.0;
			}
			float3 blendPhoenix(float3 base, float3 blend)
			{
				return min(base, blend) - max(base, blend) + float3(1.0, 1.0, 1.0);
			}
			
			// Pin light
			float blendPinLight(float base, float blend)
			{
				return (blend < 0.5) ? blendDarken(base, (2.0 * blend)) : blendLighten(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendPinLight(float3 base, float3 blend)
			{
				return float3(blendPinLight(base.r, blend.r), blendPinLight(base.g, blend.g), blendPinLight(base.b, blend.b));
			}
			
			// Screen
			float blendScreen(float base, float blend)
			{
				return 1.0 - ((1.0 - base) * (1.0 - blend));
			}
			
			float3 blendScreen(float3 base, float3 blend)
			{
				return float3(blendScreen(base.r, blend.r), blendScreen(base.g, blend.g), blendScreen(base.b, blend.b));
			}
			
			// Soft Light
			float blendSoftLight(float base, float blend)
			{
				return (blend < 0.5) ? (2.0 * base * blend + base * base * (1.0 - 2.0 * blend)) : (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend));
			}
			
			float3 blendSoftLight(float3 base, float3 blend)
			{
				return float3(blendSoftLight(base.r, blend.r), blendSoftLight(base.g, blend.g), blendSoftLight(base.b, blend.b));
			}
			
			// Subtract
			float blendSubtract(float base, float blend)
			{
				return max(base - blend, 0.0);
			}
			
			float3 blendSubtract(float3 base, float3 blend)
			{
				return max(base - blend, 0.0);
			}
			
			// Difference
			float blendDifference(float base, float blend)
			{
				return abs(base - blend);
			}
			
			float3 blendDifference(float3 base, float3 blend)
			{
				return abs(base - blend);
			}
			
			// Divide
			float blendDivide(float base, float blend)
			{
				return base / max(blend, 0.0001);
			}
			
			float3 blendDivide(float3 base, float3 blend)
			{
				return base / max(blend, 0.0001);
			}
			
			float blendMixed(float base, float blend)
			{
				return base + base * blend;
			}
			
			float3 blendMixed(float3 base, float3 blend)
			{
				return base + base * blend;
			}
			
			float3 customBlend(float3 base, float3 blend, float blendType, float alpha = 1)
			{
				float3 output = base;
				switch(blendType)
				{
					case 0: output = lerp(base, blend, alpha); break;
					case 1: output = lerp(base, blendDarken(base, blend), alpha); break;
					case 2: output = base * lerp(1, blend, alpha); break;
					case 5: output = lerp(base, blendLighten(base, blend), alpha); break;
					case 6: output = lerp(base, blendScreen(base, blend), alpha); break;
					case 7: output = blendSubtract(base, blend * alpha); break;
					case 8: output = lerp(base, blendLinearDodge(base, blend), alpha); break;
					case 9: output = lerp(base, blendOverlay(base, blend), alpha); break;
					case 20: output = lerp(base, blendMixed(base, blend), alpha); break;
					default: output = 0; break;
				}
				return output;
			}
			
			float3 customBlend(float base, float blend, float blendType, float alpha = 1)
			{
				float3 output = base;
				switch(blendType)
				{
					case 0: output = lerp(base, blend, alpha); break;
					case 2: output = base * lerp(1, blend, alpha); break;
					case 5: output = lerp(base, blendLighten(base, blend), alpha); break;
					case 6: output = lerp(base, blendScreen(base, blend), alpha); break;
					case 7: output = blendSubtract(base, blend * alpha); break;
					case 8: output = lerp(base, blendLinearDodge(base, blend), alpha); break;
					case 9: output = lerp(base, blendOverlay(base, blend), alpha); break;
					case 20: output = lerp(base, blendMixed(base, blend), alpha); break;
					default: output = 0; break;
				}
				return output;
			}
			
			#define REPLACE 0
			#define SUBSTRACT 1
			#define MULTIPLY 2
			#define DIVIDE 3
			#define MIN 4
			#define MAX 5
			#define AVERAGE 6
			#define ADD 7
			
			float maskBlend(float baseMask, float blendMask, float blendType)
			{
				float output = 0;
				switch(blendType)
				{
					case REPLACE: output = blendMask; break;
					case SUBSTRACT: output = baseMask - blendMask; break;
					case MULTIPLY: output = baseMask * blendMask; break;
					case DIVIDE: output = baseMask / blendMask; break;
					case MIN: output = min(baseMask, blendMask); break;
					case MAX: output = max(baseMask, blendMask); break;
					case AVERAGE: output = (baseMask + blendMask) * 0.5; break;
					case ADD: output = baseMask + blendMask; break;
				}
				return saturate(output);
			}
			
			float globalMaskBlend(float baseMask, float globalMaskIndex, float blendType, PoiMods poiMods)
			{
				if (globalMaskIndex == 0)
				{
					return baseMask;
				}
				else
				{
					return maskBlend(baseMask, poiMods.globalMask[globalMaskIndex - 1], blendType);
				}
			}
			
			float random(float2 p)
			{
				return frac(sin(dot(p, float2(12.9898, 78.2383))) * 43758.5453123);
			}
			
			float2 random2(float2 p)
			{
				return frac(sin(float2(dot(p, float2(127.1, 311.7)), dot(p, float2(269.5, 183.3)))) * 43758.5453);
			}
			
			float3 random3(float2 p)
			{
				return frac(sin(float3(dot(p, float2(127.1, 311.7)), dot(p, float2(269.5, 183.3)), dot(p, float2(248.3, 315.9)))) * 43758.5453);
			}
			
			float3 random3(float3 p)
			{
				return frac(sin(float3(dot(p, float3(127.1, 311.7, 248.6)), dot(p, float3(269.5, 183.3, 423.3)), dot(p, float3(248.3, 315.9, 184.2)))) * 43758.5453);
			}
			
			float3 randomFloat3(float2 Seed, float maximum)
			{
				return (.5 + float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed), float2(12.9898, 78.233))) * 43758.5453)
				) * .5) * (maximum);
			}
			
			float3 randomFloat3Range(float2 Seed, float Range)
			{
				return (float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed.x * Seed.y, Seed.y + Seed.x), float2(12.9898, 78.233))) * 43758.5453)
				) * 2 - 1) * Range;
			}
			
			float3 randomFloat3WiggleRange(float2 Seed, float Range, float wiggleSpeed, float timeOffset)
			{
				float3 rando = (float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed.x * Seed.y, Seed.y + Seed.x), float2(12.9898, 78.233))) * 43758.5453)
				) * 2 - 1);
				float speed = 1 + wiggleSpeed;
				return float3(sin(((_Time.x + timeOffset) + rando.x * PI) * speed), sin(((_Time.x + timeOffset) + rando.y * PI) * speed), sin(((_Time.x + timeOffset) + rando.z * PI) * speed)) * Range;
			}
			
			void poiDither(float4 In, float4 ScreenPosition, out float4 Out)
			{
				float2 uv = ScreenPosition.xy * _ScreenParams.xy;
				float DITHER_THRESHOLDS[16] = {
					1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0,
					13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0,
					4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0,
					16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0
				};
				uint index = (uint(uv.x) % 4) * 4 + uint(uv.y) % 4;
				Out = In - DITHER_THRESHOLDS[index];
			}
			// The weights of RGB contributions to luminance.
			// Should sum to unity.
			static const float3 HCYwts = float3(0.299, 0.587, 0.114);
			static const float HCLgamma = 3;
			static const float HCLy0 = 100;
			static const float HCLmaxL = 0.530454533953517; // == exp(HCLgamma / HCLy0) - 0.5
			static const float3 wref = float3(1.0, 1.0, 1.0);
			#define TAU 6.28318531
			
			float3 HUEtoRGB(in float H)
			{
				float R = abs(H * 6 - 3) - 1;
				float G = 2 - abs(H * 6 - 2);
				float B = 2 - abs(H * 6 - 4);
				return saturate(float3(R, G, B));
			}
			
			float3 RGBtoHCV(in float3 RGB)
			{
				// Based on work by Sam Hocevar and Emil Persson
				float4 P = (RGB.g < RGB.b) ? float4(RGB.bg, -1.0, 2.0 / 3.0) : float4(RGB.gb, 0.0, -1.0 / 3.0);
				float4 Q = (RGB.r < P.x) ? float4(P.xyw, RGB.r) : float4(RGB.r, P.yzx);
				float C = Q.x - min(Q.w, Q.y);
				float H = abs((Q.w - Q.y) / (6 * C + Epsilon) + Q.z);
				return float3(H, C, Q.x);
			}
			
			float3 HSVtoRGB(in float3 HSV)
			{
				float3 RGB = HUEtoRGB(HSV.x);
				return ((RGB - 1) * HSV.y + 1) * HSV.z;
			}
			
			float3 RGBtoHSV(in float3 RGB)
			{
				float3 HCV = RGBtoHCV(RGB);
				float S = HCV.y / (HCV.z + Epsilon);
				return float3(HCV.x, S, HCV.z);
			}
			
			float3 HSLtoRGB(in float3 HSL)
			{
				float3 RGB = HUEtoRGB(HSL.x);
				float C = (1 - abs(2 * HSL.z - 1)) * HSL.y;
				return (RGB - 0.5) * C + HSL.z;
			}
			
			float3 RGBtoHSL(in float3 RGB)
			{
				float3 HCV = RGBtoHCV(RGB);
				float L = HCV.z - HCV.y * 0.5;
				float S = HCV.y / (1 - abs(L * 2 - 1) + Epsilon);
				return float3(HCV.x, S, L);
			}
			
			void DecomposeHDRColor(in float3 linearColorHDR, out float3 baseLinearColor, out float exposure)
			{
				// Optimization/adaptation of https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/GUI/ColorMutator.cs#L23 but skips weird photoshop stuff
				float maxColorComponent = max(linearColorHDR.r, max(linearColorHDR.g, linearColorHDR.b));
				bool isSDR = maxColorComponent <= 1.0;
				
				float scaleFactor = isSDR ? 1.0 : (1.0 / maxColorComponent);
				exposure = isSDR ? 0.0 : log(maxColorComponent) * 1.44269504089; // ln(2)
				
				baseLinearColor = scaleFactor * linearColorHDR;
			}
			
			float3 ApplyHDRExposure(float3 linearColor, float exposure)
			{
				return linearColor * pow(2, exposure);
			}
			
			// Transforms an RGB color using a matrix. Note that S and V are absolute values here
			float3 ModifyViaHSV(float3 color, float h, float s, float v)
			{
				float3 colorHSV = RGBtoHSV(color);
				colorHSV.x = frac(colorHSV.x + h);
				colorHSV.y = saturate(colorHSV.y + s);
				colorHSV.z = saturate(colorHSV.z + v);
				return HSVtoRGB(colorHSV);
			}
			
			float3 ModifyViaHSV(float3 color, float3 HSVMod)
			{
				return ModifyViaHSV(color, HSVMod.x, HSVMod.y, HSVMod.z);
			}
			
			float4x4 brightnessMatrix(float brightness)
			{
				return float4x4(
				1, 0, 0, 0,
				0, 1, 0, 0,
				0, 0, 1, 0,
				brightness, brightness, brightness, 1
				);
			}
			
			float4x4 contrastMatrix(float contrast)
			{
				float t = (1.0 - contrast) / 2.0;
				
				return float4x4(
				contrast, 0, 0, 0,
				0, contrast, 0, 0,
				0, 0, contrast, 0,
				t, t, t, 1
				);
			}
			
			float4x4 saturationMatrix(float saturation)
			{
				float3 luminance = float3(0.3086, 0.6094, 0.0820);
				
				float oneMinusSat = 1.0 - saturation;
				
				float3 red = luminance.x * oneMinusSat;
				red += float3(saturation, 0, 0);
				
				float3 green = luminance.y * oneMinusSat;
				green += float3(0, saturation, 0);
				
				float3 blue = luminance.z * oneMinusSat;
				blue += float3(0, 0, saturation);
				
				return float4x4(
				red, 0,
				green, 0,
				blue, 0,
				0, 0, 0, 1
				);
			}
			
			float4 PoiColorBCS(float4 color, float brightness, float contrast, float saturation)
			{
				return mul(color, mul(brightnessMatrix(brightness), mul(contrastMatrix(contrast), saturationMatrix(saturation))));
			}
			float3 PoiColorBCS(float3 color, float brightness, float contrast, float saturation)
			{
				return mul(float4(color, 1), mul(brightnessMatrix(brightness), mul(contrastMatrix(contrast), saturationMatrix(saturation)))).rgb;
			}
			
			float3 linear_srgb_to_oklab(float3 c)
			{
				float l = 0.4122214708 * c.x + 0.5363325363 * c.y + 0.0514459929 * c.z;
				float m = 0.2119034982 * c.x + 0.6806995451 * c.y + 0.1073969566 * c.z;
				float s = 0.0883024619 * c.x + 0.2817188376 * c.y + 0.6299787005 * c.z;
				
				float l_ = pow(l, 1.0 / 3.0);
				float m_ = pow(m, 1.0 / 3.0);
				float s_ = pow(s, 1.0 / 3.0);
				
				return float3(
				0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_,
				1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_,
				0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_
				);
			}
			
			float3 oklab_to_linear_srgb(float3 c)
			{
				float l_ = c.x + 0.3963377774 * c.y + 0.2158037573 * c.z;
				float m_ = c.x - 0.1055613458 * c.y - 0.0638541728 * c.z;
				float s_ = c.x - 0.0894841775 * c.y - 1.2914855480 * c.z;
				
				float l = l_ * l_ * l_;
				float m = m_ * m_ * m_;
				float s = s_ * s_ * s_;
				
				return float3(
				+ 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
				- 1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
				- 0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s
				);
			}
			
			float3 hueShift(float3 color, float shift)
			{
				float3 oklab = linear_srgb_to_oklab(max(color, 0.0000000001));
				float hue = atan2(oklab.z, oklab.y);
				hue += shift * PI * 2;  // Add the hue shift
				
				float chroma = length(oklab.yz);
				oklab.y = cos(hue) * chroma;
				oklab.z = sin(hue) * chroma;
				
				return oklab_to_linear_srgb(oklab);
			}
			
			float3 hueShift(float4 color, float shift)
			{
				return hueShift(color.rgb, shift);
			}
			
			/*
			float3 hueShift(float3 color, float hueOffset)
			{
				color = RGBtoHSV(color);
				color.x = frac(hueOffset +color.x);
				return HSVtoRGB(color);
			}
			*/
			
			// LCH
			float xyzF(float t)
			{
				return lerp(pow(t, 1. / 3.), 7.787037 * t + 0.139731, step(t, 0.00885645));
			}
			float xyzR(float t)
			{
				return lerp(t * t * t, 0.1284185 * (t - 0.139731), step(t, 0.20689655));
			}
			
			float4x4 poiRotationMatrixFromAngles(float x, float y, float z)
			{
				float angleX = radians(x);
				float c = cos(angleX);
				float s = sin(angleX);
				float4x4 rotateXMatrix = float4x4(1, 0, 0, 0,
				0, c, -s, 0,
				0, s, c, 0,
				0, 0, 0, 1);
				
				float angleY = radians(y);
				c = cos(angleY);
				s = sin(angleY);
				float4x4 rotateYMatrix = float4x4(c, 0, s, 0,
				0, 1, 0, 0,
				- s, 0, c, 0,
				0, 0, 0, 1);
				
				float angleZ = radians(z);
				c = cos(angleZ);
				s = sin(angleZ);
				float4x4 rotateZMatrix = float4x4(c, -s, 0, 0,
				s, c, 0, 0,
				0, 0, 1, 0,
				0, 0, 0, 1);
				
				return mul(mul(rotateXMatrix, rotateYMatrix), rotateZMatrix);
			}
			
			float4x4 poiRotationMatrixFromAngles(float3 angles)
			{
				float angleX = radians(angles.x);
				float c = cos(angleX);
				float s = sin(angleX);
				float4x4 rotateXMatrix = float4x4(1, 0, 0, 0,
				0, c, -s, 0,
				0, s, c, 0,
				0, 0, 0, 1);
				
				float angleY = radians(angles.y);
				c = cos(angleY);
				s = sin(angleY);
				float4x4 rotateYMatrix = float4x4(c, 0, s, 0,
				0, 1, 0, 0,
				- s, 0, c, 0,
				0, 0, 0, 1);
				
				float angleZ = radians(angles.z);
				c = cos(angleZ);
				s = sin(angleZ);
				float4x4 rotateZMatrix = float4x4(c, -s, 0, 0,
				s, c, 0, 0,
				0, 0, 1, 0,
				0, 0, 0, 1);
				
				return mul(mul(rotateXMatrix, rotateYMatrix), rotateZMatrix);
			}
			
			float3 getCameraPosition()
			{
				#ifdef USING_STEREO_MATRICES
				return lerp(unity_StereoWorldSpaceCameraPos[0], unity_StereoWorldSpaceCameraPos[1], 0.5);
				#endif
				return _WorldSpaceCameraPos;
			}
			
			float2 calcPixelScreenUVs(half4 grabPos)
			{
				half2 uv = grabPos.xy / (grabPos.w + 0.0000000001);
				#if UNITY_SINGLE_PASS_STEREO
				uv.xy *= half2(_ScreenParams.x * 2, _ScreenParams.y);
				#else
				uv.xy *= _ScreenParams.xy;
				#endif
				
				return uv;
			}
			
			float CalcMipLevel(float2 texture_coord)
			{
				float2 dx = ddx(texture_coord);
				float2 dy = ddy(texture_coord);
				float delta_max_sqr = max(dot(dx, dx), dot(dy, dy));
				
				return 0.5 * log2(delta_max_sqr);
			}
			
			float inverseLerp(float A, float B, float T)
			{
				return (T - A) / (B - A);
			}
			
			float inverseLerp2(float2 a, float2 b, float2 value)
			{
				float2 AB = b - a;
				float2 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			float inverseLerp3(float3 a, float3 b, float3 value)
			{
				float3 AB = b - a;
				float3 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			float inverseLerp4(float4 a, float4 b, float4 value)
			{
				float4 AB = b - a;
				float4 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			/*
			MIT License
			
			Copyright (c) 2019 wraikny
			
			Permission is hereby granted, free of charge, to any person obtaining a copy
			of this software and associated documentation files (the "Software"), to deal
			in the Software without restriction, including without limitation the rights
			to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
			copies of the Software, and to permit persons to whom the Software is
			furnished to do so, subject to the following conditions:
			
			The above copyright notice and this permission notice shall be included in all
			copies or substantial portions of the Software.
			
			THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
			IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
			FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
			AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
			LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
			OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
			SOFTWARE.
			
			VertexTransformShader is dependent on:
			*/
			
			float4 quaternion_conjugate(float4 v)
			{
				return float4(
				v.x, -v.yzw
				);
			}
			
			float4 quaternion_mul(float4 v1, float4 v2)
			{
				float4 result1 = (v1.x * v2 + v1 * v2.x);
				
				float4 result2 = float4(
				- dot(v1.yzw, v2.yzw),
				cross(v1.yzw, v2.yzw)
				);
				
				return float4(result1 + result2);
			}
			
			// angle : radians
			float4 get_quaternion_from_angle(float3 axis, float angle)
			{
				float sn = sin(angle * 0.5);
				float cs = cos(angle * 0.5);
				return float4(axis * sn, cs);
			}
			
			float4 quaternion_from_vector(float3 inVec)
			{
				return float4(0.0, inVec);
			}
			
			float degree_to_radius(float degree)
			{
				return (
				degree / 180.0 * PI
				);
			}
			
			float3 rotate_with_quaternion(float3 inVec, float3 rotation)
			{
				float4 qx = get_quaternion_from_angle(float3(1, 0, 0), radians(rotation.x));
				float4 qy = get_quaternion_from_angle(float3(0, 1, 0), radians(rotation.y));
				float4 qz = get_quaternion_from_angle(float3(0, 0, 1), radians(rotation.z));
				
				#define MUL3(A, B, C) quaternion_mul(quaternion_mul((A), (B)), (C))
				float4 quaternion = normalize(MUL3(qx, qy, qz));
				float4 conjugate = quaternion_conjugate(quaternion);
				
				float4 inVecQ = quaternion_from_vector(inVec);
				
				float3 rotated = (
				MUL3(quaternion, inVecQ, conjugate)
				).yzw;
				
				return rotated;
			}
			
			float4 transform(float4 input, float4 pos, float4 rotation, float4 scale)
			{
				input.rgb *= (scale.xyz * scale.w);
				input = float4(rotate_with_quaternion(input.xyz, rotation.xyz * rotation.w) + (pos.xyz * pos.w), input.w);
				return input;
			}
			
			float2 RotateUV(float2 _uv, float _radian, float2 _piv, float _time)
			{
				float RotateUV_ang = _radian;
				float RotateUV_cos = cos(_time * RotateUV_ang);
				float RotateUV_sin = sin(_time * RotateUV_ang);
				return (mul(_uv - _piv, float2x2(RotateUV_cos, -RotateUV_sin, RotateUV_sin, RotateUV_cos)) + _piv);
			}
			
			/*
			MIT END
			*/
			
			float3 RotateAroundAxis(float3 original, float3 axis, float radian)
			{
				float s = sin(radian);
				float c = cos(radian);
				float one_minus_c = 1.0 - c;
				
				axis = normalize(axis);
				float3x3 rot_mat = {
					one_minus_c * axis.x * axis.x + c, one_minus_c * axis.x * axis.y - axis.z * s, one_minus_c * axis.z * axis.x + axis.y * s,
					one_minus_c * axis.x * axis.y + axis.z * s, one_minus_c * axis.y * axis.y + c, one_minus_c * axis.y * axis.z - axis.x * s,
					one_minus_c * axis.z * axis.x - axis.y * s, one_minus_c * axis.y * axis.z + axis.x * s, one_minus_c * axis.z * axis.z + c
				};
				return mul(rot_mat, original);
			}
			
			float3 poiThemeColor(in PoiMods poiMods, in float3 srcColor, in float themeIndex)
			{
				float3 outputColor = srcColor;
				if (themeIndex != 0)
				{
					themeIndex = max(themeIndex - 1, 0);
					
					if (themeIndex <= 3)
					{
						outputColor = poiMods.globalColorTheme[themeIndex];
					}
					else
					{
						#ifdef POI_AUDIOLINK
						if (poiMods.audioLinkAvailable)
						{
							outputColor = poiMods.globalColorTheme[themeIndex];
						}
						#endif
					}
				}
				return outputColor;
			}
			
			float3 lilToneCorrection(float3 c, float4 hsvg)
			{
				// gamma
				c = pow(abs(c), hsvg.w);
				// rgb - > hsv
				float4 p = (c.b > c.g) ? float4(c.bg, -1.0, 2.0 / 3.0) : float4(c.gb, 0.0, -1.0 / 3.0);
				float4 q = (p.x > c.r) ? float4(p.xyw, c.r) : float4(c.r, p.yzx);
				float d = q.x - min(q.w, q.y);
				float e = 1.0e-10;
				float3 hsv = float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
				// shift
				hsv = float3(hsv.x + hsvg.x, saturate(hsv.y * hsvg.y), saturate(hsv.z * hsvg.z));
				// hsv - > rgb
				return hsv.z - hsv.z * hsv.y + hsv.z * hsv.y * saturate(abs(frac(hsv.x + float3(1.0, 2.0 / 3.0, 1.0 / 3.0)) * 6.0 - 3.0) - 1.0);
			}
			
			float3 lilBlendColor(float3 dstCol, float3 srcCol, float3 srcA, int blendMode)
			{
				float3 ad = dstCol + srcCol;
				float3 mu = dstCol * srcCol;
				float3 outCol = float3(0, 0, 0);
				if (blendMode == 0) outCol = srcCol; // Normal
				if (blendMode == 1) outCol = ad; // Add
				if (blendMode == 2) outCol = max(ad - mu, dstCol); // Screen
				if (blendMode == 3) outCol = mu; // Multiply
				return lerp(dstCol, outCol, srcA);
			}
			
			float lilIsIn0to1(float f)
			{
				float value = 0.5 - abs(f - 0.5);
				return saturate(value / clamp(fwidth(value), 0.0001, 1.0));
			}
			
			float lilIsIn0to1(float f, float nv)
			{
				float value = 0.5 - abs(f - 0.5);
				return saturate(value / clamp(fwidth(value), 0.0001, nv));
			}
			
			float poiEdgeLinearNoSaturate(float value, float border)
			{
				return (value - border) / clamp(fwidth(value), 0.0001, 1.0);
			}
			
			float3 poiEdgeLinearNoSaturate(float value, float3 border)
			{
				return float3(
				(value - border.x) / clamp(fwidth(value), 0.0001, 1.0),
				(value - border.y) / clamp(fwidth(value), 0.0001, 1.0),
				(value - border.z) / clamp(fwidth(value), 0.0001, 1.0)
				);
			}
			
			float poiEdgeLinearNoSaturate(float value, float border, float blur)
			{
				float borderMin = saturate(border - blur * 0.5);
				float borderMax = saturate(border + blur * 0.5);
				return (value - borderMin) / saturate(borderMax - borderMin + fwidth(value));
			}
			
			float poiEdgeLinearNoSaturate(float value, float border, float blur, float borderRange)
			{
				float borderMin = saturate(border - blur * 0.5 - borderRange);
				float borderMax = saturate(border + blur * 0.5);
				return (value - borderMin) / saturate(borderMax - borderMin + fwidth(value));
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border)
			{
				// return (value - border) / clamp(fwidth(value), 0.0001, 1.0);
				
				float fwidthValue = fwidth(value);
				return smoothstep(border - fwidthValue, border + fwidthValue, value);
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border, float blur)
			{
				float fwidthValue = fwidth(value);
				float borderMin = saturate(border - blur * 0.5);
				float borderMax = saturate(border + blur * 0.5);
				return smoothstep(borderMin - fwidthValue, borderMax + fwidthValue, value);
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border, float blur, float borderRange)
			{
				float fwidthValue = fwidth(value);
				float borderMin = saturate(border - blur * 0.5 - borderRange);
				float borderMax = saturate(border + blur * 0.5);
				return smoothstep(borderMin - fwidthValue, borderMax + fwidthValue, value);
			}
			
			float poiEdgeNonLinear(float value, float border)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border));
			}
			
			float poiEdgeNonLinear(float value, float border, float blur)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border, blur));
			}
			
			float poiEdgeNonLinear(float value, float border, float blur, float borderRange)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border, blur, borderRange));
			}
			
			float poiEdgeLinear(float value, float border)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border));
			}
			
			float poiEdgeLinear(float value, float border, float blur)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border, blur));
			}
			
			float poiEdgeLinear(float value, float border, float blur, float borderRange)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border, blur, borderRange));
			}
			// From https : // github.com / lilxyzw / OpenLit / blob / main / Assets / OpenLit / core.hlsl
			float3 OpenLitLinearToSRGB(float3 col)
			{
				return LinearToGammaSpace(col);
			}
			
			float3 OpenLitSRGBToLinear(float3 col)
			{
				return GammaToLinearSpace(col);
			}
			
			float OpenLitLuminance(float3 rgb)
			{
				#if defined(UNITY_COLORSPACE_GAMMA)
				return dot(rgb, float3(0.22, 0.707, 0.071));
				#else
				return dot(rgb, float3(0.0396819152, 0.458021790, 0.00609653955));
				#endif
			}
			
			float3 AdjustLitLuminance(float3 rgb, float targetLuminance)
			{
				float currentLuminance;
				#if defined(UNITY_COLORSPACE_GAMMA)
				currentLuminance = dot(rgb, float3(0.22, 0.707, 0.071));
				#else
				currentLuminance = dot(rgb, float3(0.0396819152, 0.458021790, 0.00609653955));
				#endif
				
				float luminanceRatio = targetLuminance / currentLuminance;
				return rgb * luminanceRatio;
			}
			
			float3 ClampLuminance(float3 rgb, float minLuminance, float maxLuminance)
			{
				float currentLuminance = dot(rgb, float3(0.299, 0.587, 0.114));
				float minRatio = (currentLuminance != 0) ? minLuminance / currentLuminance : 1.0;
				float maxRatio = (currentLuminance != 0) ? maxLuminance / currentLuminance : 1.0;
				float luminanceRatio = clamp(min(maxRatio, max(minRatio, 1.0)), 0.0, 1.0);
				return lerp(rgb, rgb * luminanceRatio, luminanceRatio < 1.0);
			}
			
			float3 MaxLuminance(float3 rgb, float maxLuminance)
			{
				float currentLuminance = dot(rgb, float3(0.299, 0.587, 0.114));
				float luminanceRatio = (currentLuminance != 0) ? maxLuminance / max(currentLuminance, 0.00001) : 1.0;
				return lerp(rgb, rgb * luminanceRatio, currentLuminance > maxLuminance);
			}
			
			float OpenLitGray(float3 rgb)
			{
				return dot(rgb, float3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0));
			}
			
			void OpenLitShadeSH9ToonDouble(float3 lightDirection, out float3 shMax, out float3 shMin)
			{
				#if !defined(LIGHTMAP_ON)
				float3 N = lightDirection * 0.666666;
				float4 vB = N.xyzz * N.yzzx;
				// L0 L2
				float3 res = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
				res.r += dot(unity_SHBr, vB);
				res.g += dot(unity_SHBg, vB);
				res.b += dot(unity_SHBb, vB);
				res += unity_SHC.rgb * (N.x * N.x - N.y * N.y);
				// L1
				float3 l1;
				l1.r = dot(unity_SHAr.rgb, N);
				l1.g = dot(unity_SHAg.rgb, N);
				l1.b = dot(unity_SHAb.rgb, N);
				shMax = res + l1;
				shMin = res - l1;
				#if defined(UNITY_COLORSPACE_GAMMA)
				shMax = OpenLitLinearToSRGB(shMax);
				shMin = OpenLitLinearToSRGB(shMin);
				#endif
				#else
				shMax = 0.0;
				shMin = 0.0;
				#endif
			}
			
			float3 OpenLitComputeCustomLightDirection(float4 lightDirectionOverride)
			{
				float3 customDir = length(lightDirectionOverride.xyz) * normalize(mul((float3x3)unity_ObjectToWorld, lightDirectionOverride.xyz));
				return lightDirectionOverride.w ? customDir : lightDirectionOverride.xyz; // .w isn't doc'd anywhere and is always 0 unless end user changes it
			}
			
			float3 OpenLitLightingDirectionForSH9()
			{
				float3 mainDir = _WorldSpaceLightPos0.xyz * OpenLitLuminance(_LightColor0.rgb);
				#if !defined(LIGHTMAP_ON)
				float3 sh9Dir = unity_SHAr.xyz * 0.333333 + unity_SHAg.xyz * 0.333333 + unity_SHAb.xyz * 0.333333;
				float3 sh9DirAbs = float3(sh9Dir.x, abs(sh9Dir.y), sh9Dir.z);
				#else
				float3 sh9Dir = 0;
				float3 sh9DirAbs = 0;
				#endif
				
				float3 lightDirectionForSH9 = sh9Dir + mainDir;
				lightDirectionForSH9 = dot(lightDirectionForSH9, lightDirectionForSH9) < 0.000001 ? 0 : normalize(lightDirectionForSH9);
				return lightDirectionForSH9;
			}
			
			float3 OpenLitLightingDirection(float4 lightDirectionOverride)
			{
				float3 mainDir = _WorldSpaceLightPos0.xyz * OpenLitLuminance(_LightColor0.rgb);
				#if !defined(LIGHTMAP_ON) && UNITY_SHOULD_SAMPLE_SH
				float3 sh9Dir = unity_SHAr.xyz * 0.333333 + unity_SHAg.xyz * 0.333333 + unity_SHAb.xyz * 0.333333;
				float3 sh9DirAbs = float3(sh9Dir.x, abs(sh9Dir.y), sh9Dir.z);
				#else
				float3 sh9Dir = 0;
				float3 sh9DirAbs = 0;
				#endif
				float3 customDir = OpenLitComputeCustomLightDirection(lightDirectionOverride);
				
				return normalize(sh9DirAbs + mainDir + customDir);
			}
			
			float3 OpenLitLightingDirection()
			{
				float4 customDir = float4(0.001, 0.002, 0.001, 0.0);
				return OpenLitLightingDirection(customDir);
			}
			
			inline float4 CalculateFrustumCorrection()
			{
				float x1 = -UNITY_MATRIX_P._31 / (UNITY_MATRIX_P._11 * UNITY_MATRIX_P._34);
				float x2 = -UNITY_MATRIX_P._32 / (UNITY_MATRIX_P._22 * UNITY_MATRIX_P._34);
				return float4(x1, x2, 0, UNITY_MATRIX_P._33 / UNITY_MATRIX_P._34 + x1 * UNITY_MATRIX_P._13 + x2 * UNITY_MATRIX_P._23);
			}
			
			inline float CorrectedLinearEyeDepth(float z, float B)
			{
				return 1.0 / (z / UNITY_MATRIX_P._34 + B);
			}
			
			// Silent's code
			float2 sharpSample(float4 texelSize, float2 p)
			{
				p = p * texelSize.zw;
				float2 c = max(0.0, fwidth(p));
				p = floor(p) + saturate(frac(p) / c);
				p = (p - 0.5) * texelSize.xy;
				return p;
			}
			
			void applyToGlobalMask(inout PoiMods poiMods, int index, int blendType, float val)
			{
				float valBlended = saturate(maskBlend(poiMods.globalMask[index], val, blendType));
				switch(index)
				{
					case 0: poiMods.globalMask[0] = valBlended; break;
					case 1: poiMods.globalMask[1] = valBlended; break;
					case 2: poiMods.globalMask[2] = valBlended; break;
					case 3: poiMods.globalMask[3] = valBlended; break;
					case 4: poiMods.globalMask[4] = valBlended; break;
					case 5: poiMods.globalMask[5] = valBlended; break;
					case 6: poiMods.globalMask[6] = valBlended; break;
					case 7: poiMods.globalMask[7] = valBlended; break;
					case 8: poiMods.globalMask[8] = valBlended; break;
					case 9: poiMods.globalMask[9] = valBlended; break;
					case 10: poiMods.globalMask[10] = valBlended; break;
					case 11: poiMods.globalMask[11] = valBlended; break;
					case 12: poiMods.globalMask[12] = valBlended; break;
					case 13: poiMods.globalMask[13] = valBlended; break;
					case 14: poiMods.globalMask[14] = valBlended; break;
					case 15: poiMods.globalMask[15] = valBlended; break;
				}
			}
			
			void assignValueToVectorFromIndex(inout float4 vec, int index, float value)
			{
				switch(index)
				{
					case 0: vec[0] = value; break;
					case 1: vec[1] = value; break;
					case 2: vec[2] = value; break;
					case 3: vec[3] = value; break;
				}
			}
			
			// SNose
			float3 mod289(float3 x)
			{
				return x - floor(x * (1.0 / 289.0)) * 289.0;
			}
			float2 mod289(float2 x)
			{
				return x - floor(x * (1.0 / 289.0)) * 289.0;
			}
			float3 permute(float3 x)
			{
				return mod289(((x * 34.0) + 1.0) * x);
			}
			
			float snoise(float2 v)
			{
				const float4 C = float4(0.211324865405187, // (3.0 - sqrt(3.0)) / 6.0
				0.366025403784439, // 0.5 * (sqrt(3.0) - 1.0)
				- 0.577350269189626, // - 1.0 + 2.0 * C.x
				0.024390243902439); // 1.0 / 41.0
				float2 i = floor(v + dot(v, C.yy));
				float2 x0 = v - i + dot(i, C.xx);
				float2 i1;
				i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0);
				float4 x12 = x0.xyxy + C.xxzz;
				x12.xy -= i1;
				i = mod289(i); // Avoid truncation effects in permutation
				float3 p = permute(permute(i.y + float3(0.0, i1.y, 1.0))
				+ i.x + float3(0.0, i1.x, 1.0));
				
				float3 m = max(0.5 - float3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);
				m = m * m ;
				m = m * m ;
				float3 x = 2.0 * frac(p * C.www) - 1.0;
				float3 h = abs(x) - 0.5;
				float3 ox = floor(x + 0.5);
				float3 a0 = x - ox;
				m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);
				float3 g;
				g.x = a0.x * x0.x + h.x * x0.y;
				g.yz = a0.yz * x12.xz + h.yz * x12.yw;
				return 130.0 * dot(m, g);
			}
			
			float nsqDistance(float2 a, float2 b)
			{
				return dot(a - b, a - b);
			}
			
			float poiInvertToggle(in float value, in float toggle)
			{
				return (toggle == 0 ? value : 1 - value);
			}
			
			float3 PoiBlendNormal(float3 dstNormal, float3 srcNormal)
			{
				return float3(dstNormal.xy + srcNormal.xy, dstNormal.z * srcNormal.z);
			}
			
			float3 lilTransformDirOStoWS(float3 directionOS, bool doNormalize)
			{
				if (doNormalize) return normalize(mul((float3x3)unity_ObjectToWorld, directionOS));
				else            return mul((float3x3)unity_ObjectToWorld, directionOS);
			}
			
			float2 poiGetWidthAndHeight(Texture2D tex)
			{
				uint width, height;
				tex.GetDimensions(width, height);
				return float2(width, height);
			}
			
			float2 poiGetWidthAndHeight(Texture2DArray tex)
			{
				uint width, height, element;
				tex.GetDimensions(width, height, element);
				return float2(width, height);
			}
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			
			// Convenient mechanism to read from the AudioLink texture that handles reading off the end of one line and onto the next above it.
			float4 AudioLinkDataMultiline(uint2 xycoord)
			{
				return AudioLinkData(uint2(xycoord.x % AUDIOLINK_WIDTH, xycoord.y + xycoord.x / AUDIOLINK_WIDTH));
			}
			
			// Mechanism to sample between two adjacent pixels and lerp between them, like "linear" supesampling
			float4 AudioLinkLerp(float2 xy)
			{
				return lerp(AudioLinkData(xy), AudioLinkData(xy + int2(1, 0)), frac(xy.x));
			}
			
			// Same as AudioLinkLerp but properly handles multiline reading.
			float4 AudioLinkLerpMultiline(float2 xy)
			{
				return lerp(AudioLinkDataMultiline(xy), AudioLinkDataMultiline(xy + float2(1, 0)), frac(xy.x));
			}
			
			//Tests to see if Audio Link texture is available
			bool AudioLinkIsAvailable()
			{
				#if !defined(AUDIOLINK_STANDARD_INDEXING)
				int width, height;
				_AudioTexture.GetDimensions(width, height);
				return width > 16;
				#else
				return _AudioTexture_TexelSize.z > 16;
				#endif
			}
			
			//Get version of audiolink present in the world, 0 if no audiolink is present
			float AudioLinkGetVersion()
			{
				int2 dims;
				#if !defined(AUDIOLINK_STANDARD_INDEXING)
				_AudioTexture.GetDimensions(dims.x, dims.y);
				#else
				dims = _AudioTexture_TexelSize.zw;
				#endif
				
				if (dims.x >= 128)
				return AudioLinkData(ALPASS_GENERALVU).x;
				else if (dims.x > 16)
				return 1;
				else
				return 0;
			}
			
			// This pulls data from this texture.
			#define AudioLinkGetSelfPixelData(xy) _SelfTexture2D[xy]
			
			// Extra utility functions for time.
			uint AudioLinkDecodeDataAsUInt(uint2 indexloc)
			{
				uint4 rpx = AudioLinkData(indexloc);
				return rpx.r + rpx.g * 1024 + rpx.b * 1048576 + rpx.a * 1073741824;
			}
			
			//Note: This will truncate time to every 134,217.728 seconds (~1.5 days of an instance being up) to prevent floating point aliasing.
			// if your code will alias sooner, you will need to use a different function.  It should be safe to use this on all times.
			float AudioLinkDecodeDataAsSeconds(uint2 indexloc)
			{
				uint time = AudioLinkDecodeDataAsUInt(indexloc) & 0x7ffffff;
				//Can't just divide by float.  Bug in Unity's HLSL compiler.
				return float(time / 1000) + float(time % 1000) / 1000.;
			}
			
			#define ALDecodeDataAsSeconds(x) AudioLinkDecodeDataAsSeconds(x)
			#define ALDecodeDataAsUInt(x) AudioLinkDecodeDataAsUInt(x)
			
			float AudioLinkRemap(float t, float a, float b, float u, float v)
			{
				return ((t - a) / (b - a)) * (v - u) + u;
			}
			
			float3 AudioLinkHSVtoRGB(float3 HSV)
			{
				float3 RGB = 0;
				float C = HSV.z * HSV.y;
				float H = HSV.x * 6;
				float X = C * (1 - abs(fmod(H, 2) - 1));
				if (HSV.y != 0)
				{
					float I = floor(H);
					if (I == 0)
					{
						RGB = float3(C, X, 0);
					}
					else if (I == 1)
					{
						RGB = float3(X, C, 0);
					}
					else if (I == 2)
					{
						RGB = float3(0, C, X);
					}
					else if (I == 3)
					{
						RGB = float3(0, X, C);
					}
					else if (I == 4)
					{
						RGB = float3(X, 0, C);
					}
					else
					{
						RGB = float3(C, 0, X);
					}
				}
				float M = HSV.z - C;
				return RGB + M;
			}
			
			float3 AudioLinkCCtoRGB(float bin, float intensity, int rootNote)
			{
				float note = bin / AUDIOLINK_EXPBINS;
				
				float hue = 0.0;
				note *= 12.0;
				note = glsl_mod(4. - note + rootNote, 12.0);
				{
					if (note < 4.0)
					{
						//Needs to be YELLOW->RED
						hue = (note) / 24.0;
					}
					else if (note < 8.0)
					{
						//            [4]  [8]
						//Needs to be RED->BLUE
						hue = (note - 2.0) / 12.0;
					}
					else
					{
						//             [8] [12]
						//Needs to be BLUE->YELLOW
						hue = (note - 4.0) / 8.0;
					}
				}
				float val = intensity - 0.1;
				return AudioLinkHSVtoRGB(float3(fmod(hue, 1.0), 1.0, clamp(val, 0.0, 1.0)));
			}
			
			// Sample the amplitude of a given frequency in the DFT, supports frequencies in [13.75; 14080].
			float4 AudioLinkGetAmplitudeAtFrequency(float hertz)
			{
				float note = AUDIOLINK_EXPBINS * log2(hertz / AUDIOLINK_BOTTOM_FREQUENCY);
				return AudioLinkLerpMultiline(ALPASS_DFT + float2(note, 0));
			}
			
			// Sample the amplitude of a given semitone in an octave. Octave is in [0; 9] while note is [0; 11].
			float AudioLinkGetAmplitudeAtNote(float octave, float note)
			{
				float quarter = note * 2.0;
				return AudioLinkLerpMultiline(ALPASS_DFT + float2(octave * AUDIOLINK_EXPBINS + quarter, 0));
			}
			
			// Get a reasonable drop-in replacement time value for _Time.y with the
			// given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTime(uint index, uint band)
			{
				return (AudioLinkDecodeDataAsUInt(ALPASS_CHRONOTENSITY + uint2(index, band))) / 100000.0;
			}
			
			// Get a chronotensity value in the interval [0; 1], modulated by the speed input,
			// with the given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTimeNormalized(uint index, uint band, float speed)
			{
				return frac(AudioLinkGetChronoTime(index, band) * speed);
			}
			
			// Get a chronotensity value in the interval [0; interval], modulated by the speed input,
			// with the given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTimeInterval(uint index, uint band, float speed, float interval)
			{
				return AudioLinkGetChronoTimeNormalized(index, band, speed) * interval;
			}
			
			float getBandAtTime(float band, float time, float size = 1.0f)
			{
				//return remap(UNITY_SAMPLE_TEX2D(_AudioTexture, float2(time * width, band/128.0)).r, min(size,.9999), 1);
				return remapClamped(min(size, .9999), 1, AudioLinkData(ALPASS_AUDIOBASS + uint2(time * AUDIOLINK_WIDTH, band)).r);
			}
			
			fixed3 maximize(fixed3 c)
			{
				if (c.x == 0 && c.y == 0 && c.z == 0)
				return fixed3(1.0, 1.0, 1.0);
				else
				return c / max(c.r, max(c.g, c.b));
			}
			
			void initPoiAudioLink(inout PoiMods poiMods)
			{
				if (!_AudioLinkAnimToggle) return;
				
				if (AudioLinkIsAvailable())
				{
					poiMods.audioLinkAvailable = true;
					poiMods.audioLinkVersion = AudioLinkGetVersion();
					poiMods.audioLink[0] = _AudioLinkSmoothingBass == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 0))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingBass) * 15.95, 0))[0];
					poiMods.audioLink[1] = _AudioLinkSmoothingLowMid == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 1))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingLowMid) * 15.95, 1))[0];
					poiMods.audioLink[2] = _AudioLinkSmoothingHighMid == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 2))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingHighMid) * 15.95, 2))[0];
					poiMods.audioLink[3] = _AudioLinkSmoothingTreble == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 3))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingTreble) * 15.95, 3))[0];
					poiMods.audioLink[4] = AudioLinkData(ALPASS_GENERALVU + float2(8, 0))[0];
					/*
					poiMods.globalColorTheme[4] = AudioLinkData( ALPASS_CCCOLORS + uint2( 0, 0 ) );
					poiMods.globalColorTheme[5] = AudioLinkData( ALPASS_CCCOLORS + uint2( 1, 0 ) );
					poiMods.globalColorTheme[6] = AudioLinkData( ALPASS_CCCOLORS + uint2( 2, 0 ) );
					poiMods.globalColorTheme[7] = AudioLinkData( ALPASS_CCCOLORS + uint2( 3, 0 ) );
					
					poiMods.globalColorTheme[4] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 0, 0 ) )),1.0);
					poiMods.globalColorTheme[5] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 1, 0 ) )),1.0);
					poiMods.globalColorTheme[6] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 2, 0 ) )),1.0);
					poiMods.globalColorTheme[7] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 3, 0 ) )),1.0);
					*/
					
					poiMods.globalColorTheme[4] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(2, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[5] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(3, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[6] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(4, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[7] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(5, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					
					poiMods.globalColorTheme[8] = AudioLinkData(ALPASS_THEME_COLOR0);
					poiMods.globalColorTheme[9] = AudioLinkData(ALPASS_THEME_COLOR1);
					poiMods.globalColorTheme[10] = AudioLinkData(ALPASS_THEME_COLOR2);
					poiMods.globalColorTheme[11] = AudioLinkData(ALPASS_THEME_COLOR3);
					return;
				}
				
				if (_AudioLinkBandOverridesEnabled)
				{
					poiMods.audioLinkAvailable = true;
					poiMods.audioLink[0] = _AudioLinkBandOverrideSliders.x;
					poiMods.audioLink[1] = _AudioLinkBandOverrideSliders.y;
					poiMods.audioLink[2] = _AudioLinkBandOverrideSliders.z;
					poiMods.audioLink[3] = _AudioLinkBandOverrideSliders.w;
				}
			}
			
			void DebugVisualizer(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				if (_DebugWaveform)
				{
					float waveform = AudioLinkLerpMultiline(ALPASS_WAVEFORM + float2(500. * poiMesh.uv[0].x, 0)).r;
					poiFragData.emission += clamp(1 - 50 * abs(waveform - poiMesh.uv[0].y * 2. + 1), 0, 1);
				}
				if (_DebugDFT)
				{
					poiFragData.emission += AudioLinkLerpMultiline(ALPASS_DFT + uint2(poiMesh.uv[0].x * AUDIOLINK_ETOTALBINS, 0)).rrr;
				}
				if (_DebugBass)
				{
					poiFragData.emission += poiMods.audioLink[0];
				}
				if (_DebugLowMids)
				{
					poiFragData.emission += poiMods.audioLink[1];
				}
				if (_DebugHighMids)
				{
					poiFragData.emission += poiMods.audioLink[2];
				}
				if (_DebugTreble)
				{
					poiFragData.emission += poiMods.audioLink[3];
				}
				if (_DebugCCColors)
				{
					poiFragData.emission += AudioLinkData(ALPASS_CCCOLORS + uint2(3 + 1, 0));
				}
				if (_DebugCCStrip)
				{
					poiFragData.emission += AudioLinkLerp(ALPASS_CCSTRIP + float2(poiMesh.uv[0].x * AUDIOLINK_WIDTH, 0));
				}
				if (_DebugCCLights)
				{
					poiFragData.emission += AudioLinkData(ALPASS_CCLIGHTS + uint2(uint(poiMesh.uv[0].x * 8) + uint(poiMesh.uv[0].y * 16) * 8, 0));
				}
				if (_DebugAutocorrelator)
				{
					poiFragData.emission += saturate(AudioLinkLerp(ALPASS_AUTOCORRELATOR + float2((abs(1. - poiMesh.uv[0].x * 2.)) * AUDIOLINK_WIDTH, 0)).rrr);
				}
				if (_DebugChronotensity)
				{
					poiFragData.emission += (AudioLinkDecodeDataAsUInt(ALPASS_CHRONOTENSITY + uint2(1, 0)) % 1000000) / 1000000.0;
				}
			}
			
			void SetupAudioLink(inout PoiFragData poiFragData, inout PoiMods poiMods, in PoiMesh poiMesh)
			{
				initPoiAudioLink(poiMods);
				DebugVisualizer(poiFragData, poiMesh, poiMods);
				
				if (_AudioLinkCCStripY)
				{
					poiFragData.emission += AudioLinkLerp(ALPASS_CCSTRIP + float2(poiMesh.uv[0].y * AUDIOLINK_WIDTH, 0)).rgb * .5;
				}
			}
			
			#endif
			//endex
			
			//ifex _BSSEnabled!=1
			#ifdef POIBS_ENABLE
			//ifex _BSSBloomfog!=1
			#ifdef POIBS_BLOOMFOG
			inline float4 GetFogCoord(float4 clipPos)
			{
				float4 screenPos = ComputeNonStereoScreenPos(clipPos);
				float2 screenPosNormalized = screenPos.xy / screenPos.w;
				float eyeOffset = (unity_StereoEyeIndex * (_StereoCameraEyeOffset * 2)) + - _StereoCameraEyeOffset;
				return float4(
				((eyeOffset +screenPosNormalized.x) + - 0.5) * _CustomFogTextureToScreenRatio.x + 0.5,
				(screenPosNormalized.y + - 0.5) * _CustomFogTextureToScreenRatio.y + 0.5
				,clipPos.z,clipPos.w);
			}
			
			inline float GetHeightFogIntensity(float3 worldPos, float fogHeightOffset, float fogHeightScale)
			{
				float heightFogIntensity = _CustomFogHeightFogHeight + _CustomFogHeightFogStartY;
				heightFogIntensity = ((worldPos.y * fogHeightScale) + fogHeightOffset) + - heightFogIntensity;
				heightFogIntensity = heightFogIntensity / _CustomFogHeightFogHeight;
				heightFogIntensity = clamp(heightFogIntensity, 0, 1);
				return ((-heightFogIntensity * 2) + 3) * (heightFogIntensity * heightFogIntensity);
			}
			
			inline float GetFogIntensity(float3 distance, float fogStartOffset, float fogScale)
			{
				float fogIntensity = max(dot(distance, distance) + - fogStartOffset, 0);
				fogIntensity = max((fogIntensity * fogScale) + - _CustomFogOffset, 0);
				fogIntensity = 1 / ((fogIntensity * _CustomFogAttenuation) + 1);
				return -fogIntensity;
			}
			#endif
			//endex
			#endif
			//endex
			
			//ifex _EnableDepthBulge==0
			#if defined(POI_DEPTHBULGE)
			void applyDepthBulgeFX(inout VertexOut o)
			{
				float4 pos = UnityObjectToClipPos(o.localPos);
				float4 grabPos = ComputeGrabScreenPos(pos);
				float depth = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(grabPos.xy / grabPos.w, 0, 0));
				
				#if defined(PROP_DEPTHBULGEMASK) || !defined(OPTIMIZER_ENABLED)
				float depthBulgeMask = tex2Dlod(_DepthBulgeMask, float4(poiUV(vertexUV(o, _DepthBulgeMaskUV), _DepthBulgeMask_ST), 0, 0))[_DepthBulgeMaskChannel];
				#else
				float depthBulgeMask = 1.0;
				#endif
				
				depth = Linear01Depth(depth);
				
				float intersect = 0;
				if (depth != 1)
				{
					float diff = distance(depth, Linear01Depth(pos.z / pos.w));
					if (diff > 0)
					{
						intersect = 1 - smoothstep(0, _ProjectionParams.w * _DepthBulgeFadeLength, diff);
					}
				}
				float4 offset = intersect * _DepthBulgeHeight * float4(o.normal, 0);
				
				offset = IsInMirror() ? 0 : offset;
				offset *= depthBulgeMask;
				
				o.worldPos.xyz += offset.xyz;
				o.localPos.xyz += mul(unity_WorldToObject, float4(offset.xyz, 0)).xyz;
			}
			#endif
			//endex
			
			VertexOut vert(
			#ifndef POI_TESSELLATED
			appdata v
			#else
			tessAppData v
			#endif
			)
			{
				UNITY_SETUP_INSTANCE_ID(v);
				VertexOut o;
				PoiInitStruct(VertexOut, o);
				UNITY_TRANSFER_INSTANCE_ID(v, o);
				#ifdef POI_TESSELLATED
				UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v);
				#endif
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
				
				//ifex _EnableUDIMDiscardOptions==0
				#ifdef POI_UDIMDISCARD
				UNITY_BRANCH
				if(_UDIMDiscardMode == 0) // Discard Vertices instead of just pixels
				{
					// Branchless (inspired by s-ilent)
					float2 udim = 0;
					// Select UV
					udim += (v.uv0.xy * (_UDIMDiscardUV == 0));
					udim += (v.uv1.xy * (_UDIMDiscardUV == 1));
					udim += (v.uv2.xy * (_UDIMDiscardUV == 2));
					udim += (v.uv3.xy * (_UDIMDiscardUV == 3));
					
					float isDiscarded = 0;
					float4 xMask = float4(  (udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					isDiscarded += (udim.y >= 0 && udim.y < 1) * dot(float4(_UDIMDiscardRow0_0, _UDIMDiscardRow0_1, _UDIMDiscardRow0_2, _UDIMDiscardRow0_3), xMask);
					isDiscarded += (udim.y >= 1 && udim.y < 2) * dot(float4(_UDIMDiscardRow1_0, _UDIMDiscardRow1_1, _UDIMDiscardRow1_2, _UDIMDiscardRow1_3), xMask);
					isDiscarded += (udim.y >= 2 && udim.y < 3) * dot(float4(_UDIMDiscardRow2_0, _UDIMDiscardRow2_1, _UDIMDiscardRow2_2, _UDIMDiscardRow2_3), xMask);
					isDiscarded += (udim.y >= 3 && udim.y < 4) * dot(float4(_UDIMDiscardRow3_0, _UDIMDiscardRow3_1, _UDIMDiscardRow3_2, _UDIMDiscardRow3_3), xMask);
					
					isDiscarded *= any(float4(udim.y >= 0, udim.y < 4, udim.x >= 0, udim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					// Use a threshold so that there's some room for animations to be close to 0, but not exactly 0
					const float threshold = 0.001;
					if(isDiscarded > threshold) // Early Return skips rest of vertex shader
					{
						return (VertexOut)POI_NAN;
					}
				}
				#endif
				//endex
				
				//ifex _VertexManipulationsEnabled==0
				#ifdef AUTO_EXPOSURE
				float4 audioLinkBands = 0;
				float3 ALrotation = 0;
				float3 ALLocalTranslation = 0;
				float3 CTALRotation = 0;
				float3 ALScale = 0;
				float3 ALWorldTranslation = 0;
				float ALHeight = 0;
				float ALRoundingAmount = 0;
				float4 ALSpectrumLocalOffset = float4(0, 0, 0, 0);
				#ifdef POI_AUDIOLINK
				if (AudioLinkIsAvailable() && _VertexAudioLinkEnabled && _AudioLinkAnimToggle)
				{
					audioLinkBands.x = AudioLinkData(ALPASS_AUDIOBASS).r;
					audioLinkBands.y = AudioLinkData(ALPASS_AUDIOLOWMIDS).r;
					audioLinkBands.z = AudioLinkData(ALPASS_AUDIOHIGHMIDS).r;
					audioLinkBands.w = AudioLinkData(ALPASS_AUDIOTREBLE).r;
					
					if (any(_VertexLocalTranslationALMin) || any(_VertexLocalTranslationALMax))
					{
						ALLocalTranslation = lerp(_VertexLocalTranslationALMin, _VertexLocalTranslationALMax, audioLinkBands[_VertexLocalTranslationALBand]);
					}
					if (any(_VertexLocalRotationAL))
					{
						ALrotation = audioLinkBands[_VertexLocalRotationALBand] * _VertexLocalRotationAL;
					}
					if (any(_VertexLocalRotationCTALSpeed))
					{
						CTALRotation.x = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeX, _VertexLocalRotationCTALBandX) * _VertexLocalRotationCTALSpeed.x * 360;
						CTALRotation.y = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeY, _VertexLocalRotationCTALBandY) * _VertexLocalRotationCTALSpeed.y * 360;
						CTALRotation.z = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeZ, _VertexLocalRotationCTALBandZ) * _VertexLocalRotationCTALSpeed.z * 360;
					}
					if (any(_VertexLocalScaleALMin) || any(_VertexLocalScaleALMax))
					{
						ALScale = lerp(_VertexLocalScaleALMin.xyz + _VertexLocalScaleALMin.w, _VertexLocalScaleALMax.xyz + _VertexLocalScaleALMax.w, audioLinkBands[_VertexLocalScaleALBand]);
					}
					if (any(_VertexWorldTranslationALMin) || any(_VertexWorldTranslationALMax))
					{
						ALWorldTranslation = lerp(_VertexWorldTranslationALMin, _VertexWorldTranslationALMax, audioLinkBands[_VertexWorldTranslationALBand]);
					}
					if (any(_VertexManipulationHeightAL))
					{
						ALHeight = lerp(_VertexManipulationHeightAL.x, _VertexManipulationHeightAL.y, audioLinkBands[_VertexManipulationHeightBand]);
					}
					if (any(_VertexRoundingRangeAL))
					{
						ALRoundingAmount = lerp(_VertexRoundingRangeAL.x, _VertexRoundingRangeAL.y, audioLinkBands[_VertexRoundingRangeBand]);
					}
					if (_VertexSpectrumMotion)
					{
						ALSpectrumLocalOffset.xyz = lerp(_VertexSpectrumOffsetMin.xyz, _VertexSpectrumOffsetMax.xyz, AudioLinkLerpMultiline(ALPASS_DFT + float2(vertexUV(v, _VertexSpectrumUV)[_VertexSpectrumUVDirection] * AUDIOLINK_ETOTALBINS, 0.)));
					}
				}
				#endif
				
				// Local Transformation
				float4 rotation = float4(_VertexManipulationLocalRotation.xyz + float3(180, 0, 0) + _VertexManipulationLocalRotationSpeed * _Time.x + ALrotation + CTALRotation, _VertexManipulationLocalRotation.w);
				v.normal = rotate_with_quaternion(v.normal, rotation.xyz);
				v.tangent.xyz = rotate_with_quaternion(v.tangent.xyz, rotation.xyz);
				v.vertex = transform(v.vertex, _VertexManipulationLocalTranslation + float4(ALLocalTranslation, 0) + ALSpectrumLocalOffset, rotation, _VertexManipulationLocalScale + float4(ALScale, 0));
				o.normal = UnityObjectToWorldNormal(v.normal);
				
				#if defined(PROP_VERTEXMANIPULATIONHEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float3 heightOffset = (tex2Dlod(_VertexManipulationHeightMask, float4(poiUV(vertexUV(v, _VertexManipulationHeightMaskUV), _VertexManipulationHeightMask_ST) + _VertexManipulationHeightMaskPan * _Time.x, 0, 0))[_VertexManipulationHeightMaskChannel] - _VertexManipulationHeightBias) * (_VertexManipulationHeight + ALHeight) * o.normal;
				#else
				float3 heightOffset = (_VertexManipulationHeight + ALHeight) * o.normal;
				#endif
				
				if (_VertexBarrelMode)
				{
					v.vertex.xz = lerp(v.vertex.xz, normalize(v.vertex.xz) * _VertexBarrelWidth + v.vertex.xz * _VertexBarrelHeight, _VertexBarrelAlpha);
				}
				
				if (_VertexSphereMode)
				{
					v.vertex.xyz = lerp(v.vertex.xyz, normalize(v.vertex.xyz + _VertexSphereCenter.xyz) * _VertexSphereRadius + v.vertex.xyz * _VertexSphereHeight, _VertexSphereAlpha);
				}
				
				if (_VertexTornadoMode)
				{
					v.vertex.xz = lerp(v.vertex.xz, float3(v.vertex.xz + float2(cos(_Time.y * _VertexTornadoSpeed + v.vertex.y * _VertexTornadoIntensity) * _VertexTornadoRadius, sin(_Time.y * _VertexTornadoSpeed + v.vertex.y * _VertexTornadoIntensity) * _VertexTornadoRadius), v.vertex.y), smoothstep(_VertexTornadoBaseHeight, _VertexTornadoTopHeight, v.vertex.y));
				}
				
				v.vertex.xyz += mul(unity_WorldToObject, _VertexManipulationWorldTranslation.xyz + ALWorldTranslation + heightOffset).xyz;
				
				// rounding
				UNITY_BRANCH
				if (_VertexRoundingEnabled)
				{
					float divisionAmount = max(_VertexRoundingDivision + ALRoundingAmount, 0.0000001);
					if (_VertexRoundingSpace == 0)
					{
						float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
						float3 worldRoundPosition = (ceil(worldPos.xyz / divisionAmount) * divisionAmount) - divisionAmount * .5;
						v.vertex = mul(unity_WorldToObject, float4(worldRoundPosition, worldPos.w));
					}
					else if (_VertexRoundingSpace == 1)
					{
						v.vertex.xyz = (ceil(v.vertex.xyz / divisionAmount) * divisionAmount) - divisionAmount * .5;
					}
				}
				#endif
				//endex
				
				//ifex _EnableDissolve==0
				#ifdef DISTORT
				UNITY_BRANCH
				if (_UVTileDissolveEnabled && _UVTileDissolveDiscardAtMax)
				{
					// Branchless (inspired by s-ilent)
					float2 dissolveUdim = 0;
					// Select UV
					dissolveUdim += (v.uv0.xy * (_UVTileDissolveUV == 0));
					dissolveUdim += (v.uv1.xy * (_UVTileDissolveUV == 1));
					dissolveUdim += (v.uv2.xy * (_UVTileDissolveUV == 2));
					dissolveUdim += (v.uv3.xy * (_UVTileDissolveUV == 3));
					
					float isDiscardedFromDissolve = 0;
					float4 xMaskDissolve = float4((dissolveUdim.x >= 0 && dissolveUdim.x < 1),
					(dissolveUdim.x >= 1 && dissolveUdim.x < 2),
					(dissolveUdim.x >= 2 && dissolveUdim.x < 3),
					(dissolveUdim.x >= 3 && dissolveUdim.x < 4));
					
					isDiscardedFromDissolve += (dissolveUdim.y >= 0 && dissolveUdim.y < 1) * dot(float4(_UVTileDissolveAlpha_Row0_0, _UVTileDissolveAlpha_Row0_1, _UVTileDissolveAlpha_Row0_2, _UVTileDissolveAlpha_Row0_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 1 && dissolveUdim.y < 2) * dot(float4(_UVTileDissolveAlpha_Row1_0, _UVTileDissolveAlpha_Row1_1, _UVTileDissolveAlpha_Row1_2, _UVTileDissolveAlpha_Row1_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 2 && dissolveUdim.y < 3) * dot(float4(_UVTileDissolveAlpha_Row2_0, _UVTileDissolveAlpha_Row2_1, _UVTileDissolveAlpha_Row2_2, _UVTileDissolveAlpha_Row2_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 3 && dissolveUdim.y < 4) * dot(float4(_UVTileDissolveAlpha_Row3_0, _UVTileDissolveAlpha_Row3_1, _UVTileDissolveAlpha_Row3_2, _UVTileDissolveAlpha_Row3_3), xMaskDissolve);
					
					isDiscardedFromDissolve *= any(float4(dissolveUdim.y >= 0, dissolveUdim.y < 4, dissolveUdim.x >= 0, dissolveUdim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					// Use a threshold so that there's some room for animations to be close to 1, but not exactly 1
					const float threshold = 0.999;
					if (isDiscardedFromDissolve > threshold) // Early Return skips rest of vertex shader
					
					{
						return (VertexOut)POI_NAN;
					}
				}
				#endif
				//endex
				
				//ifex _EnableMirrorOptions==0
				#ifdef POI_MIRROR
				float notVisible = 0;
				
				if (_VisibilityMode == 1) // VRC
				
				{
					float mirrorMode = VRCMirrorMode();
					float cameraMode = VRCCameraMode();
					
					notVisible += (!_VisibilityVRCRegular && ((mirrorMode == 0) && (cameraMode == 0)));
					notVisible += (!_VisibilityVRCMirrorVR && (mirrorMode == 1));
					notVisible += (!_VisibilityVRCMirrorDesktop && (mirrorMode == 2));
					notVisible += (!_VisibilityVRCCameraVR && (cameraMode == 1));
					notVisible += (!_VisibilityVRCCameraDesktop && (cameraMode == 2));
					notVisible += (!_VisibilityVRCCameraScreenshot && (cameraMode == 3));
				}
				else if (_Mirror != 0) // Generic (CVR, etc)
				
				{
					notVisible += (_Mirror == 1) ^ IsInMirror();
				}
				
				if (notVisible) // Early Return skips rest of vertex shader
				
				{
					return (VertexOut)POI_NAN;
				}
				#endif
				//endex
				
				o.normal = UnityObjectToWorldNormal(v.normal);
				o.tangent.xyz = UnityObjectToWorldDir(v.tangent);
				o.tangent.w = v.tangent.w;
				o.vertexColor = v.color;
				
				o.uv[0] = float4(v.uv0.xy, v.uv1.xy);
				o.uv[1] = float4(v.uv2.xy, v.uv3.xy);
				
				#if defined(LIGHTMAP_ON)
				o.lightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
				#endif
				#ifdef DYNAMICLIGHTMAP_ON
				o.lightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
				#endif
				
				o.localPos = v.vertex;
				o.worldPos = mul(unity_ObjectToWorld, o.localPos);
				
				float3 localOffset = float3(0, 0, 0);
				float3 worldOffset = float3(0, 0, 0);
				
				//ifex _EnableOutlines!=1
				#ifdef POI_PASS_OUTLINE
				float outlineMask = tex2Dlod(_OutlineMask, float4(poiUV(vertexUV(v, _OutlineMaskUV), _OutlineMask_ST) + _Time.x * _OutlineMaskPan, 0, 0))[_OutlineMaskChannel];
				
				//UNITY_BRANCH
				if (_OutlineVertexColorMask > 0)
				{
					outlineMask *= lerp(1, v.color[_OutlineVertexColorMask - 1], _OutlineVertexColorMaskStrength);
				}
				
				float3 outlineNormal = _OutlineSpace ? o.normal : v.normal;
				//UNITY_BRANCH
				if (_OutlineUseVertexColorNormals)
				{
					float3 outlineTangent;
					float3 outlineBinormal;
					if (_OutlineSpace) // 0 Local, 1 World
					
					{
						outlineTangent = o.tangent;
						outlineBinormal = cross(o.normal, o.tangent) * (v.tangent.w * unity_WorldTransformParams.w);
					}
					else
					{
						outlineTangent = v.tangent.xyz;
						outlineBinormal = normalize(cross(outlineNormal, outlineTangent)) * (v.tangent.w * length(outlineNormal));
					}
					float3 outlineVectorTS = v.color.rgb * 2.0 - 1.0;
					outlineNormal = outlineVectorTS.x * outlineTangent + outlineVectorTS.y * outlineBinormal + outlineVectorTS.z * outlineNormal;
				}
				
				float offsetMultiplier = 1;
				float distanceOffset = 1;
				//UNITY_BRANCH
				if (_OutlineFixedSize)
				{
					distanceOffset *= lerp(1.0, clamp((distance(_WorldSpaceCameraPos, mul(unity_ObjectToWorld, o.localPos).xyz)), 0.0f, _OutlinesMaxDistance), _OutlineFixWidth);
				}
				
				float lineWidth = _LineWidth;
				#ifdef POI_AUDIOLINK
				// Due to PoiMods.audioLink being frag only I'll just
				// recreate what it does here for this vertex function
				//UNITY_BRANCH
				if (_AudioLinkAnimToggle)
				{
					if (AudioLinkIsAvailable())
					{
						lineWidth += lerp(_AudioLinkOutlineSize.x, _AudioLinkOutlineSize.y, AudioLinkData(uint2(0, _AudioLinkOutlineSizeBand)));
					}
				}
				#endif
				
				float3 offset = outlineNormal * (lineWidth * _EnableOutlines / 100) * outlineMask * distanceOffset;
				
				//UNITY_BRANCH
				if (_OutlineExpansionMode == 2)
				{
					float3 lightDirection = normalize(_WorldSpaceLightPos0 + unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz);
					offsetMultiplier = saturate(dot(lightDirection, outlineNormal));
					offset *= offsetMultiplier;
					offset *= distanceOffset;
				}
				else if (_OutlineExpansionMode == 3)
				{
					float3 viewNormal = mul((float3x3)UNITY_MATRIX_V, outlineNormal);
					offsetMultiplier = saturate(dot(viewNormal.xy, normalize(_OutlinePersonaDirection.xy)));
					
					offset *= offsetMultiplier;
					offset *= distanceOffset;
				}
				else if (_OutlineExpansionMode == 4)
				{
					offset = mul((float3x3)transpose(UNITY_MATRIX_V), _OutlineDropShadowOffset);
					offset *= distanceOffset;
				}
				if (_OutlineSpace == 0)
				{
					localOffset += offset;
					worldOffset += mul(unity_ObjectToWorld, offset);
				}
				else
				{
					localOffset += mul(unity_WorldToObject, offset);
					worldOffset += offset;
				}
				#endif
				//endex
				
				//ifex _VertexGlitchingEnabled==0
				#if defined(POI_VERTEX_GLITCHING)
				
				bool canGlitch = true;
				if (_VertexGlitchMirrorEnable && _VertexGlitchMirror > 0)
				{
					bool inMirror = IsInMirror();
					if (_VertexGlitchMirror == 1 && !inMirror)	canGlitch = false;
					if (_VertexGlitchMirror == 2 && inMirror)	canGlitch = false;
				}
				if (canGlitch)
				{
					float3 forward = getCameraPosition() - mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
					forward.y = 0;
					forward = normalize(forward);
					float3 glitchDirection = normalize(cross(float3(0, 1, 0), forward));
					
					float glitchAmount = 0;
					
					#if defined(POI_VERTEX_GLITCHING_TEXTURE)
					// if(_VertexGlitchingUseTexture)
					// {
					float uvl = o.worldPos.y * _VertexGlitchDensity + _Time.x * _VertexGlitchMapPanSpeed;
					float uvr = o.worldPos.y * _VertexGlitchDensity - _Time.x * _VertexGlitchMapPanSpeed;
					
					float3 glitchTextureL = 1;
					float3 glitchTextureR = 1;
					
					#if defined(POI_VERTEX_GLITCHING_TEXTURE) || !defined(OPTIMIZER_ENABLED)
					glitchTextureL = tex2Dlod(_VertexGlitchMap, float4(uvl, uvl, 0, 0)).rgb;
					glitchTextureR = tex2Dlod(_VertexGlitchMap, float4(uvr, uvr, 0, 0)).rgb;
					#endif
					
					glitchAmount += (glitchTextureL.r - 0.5) * 2;
					glitchAmount += - (glitchTextureR.r - 0.5) * 2;
					
					glitchAmount += (glitchTextureL.g - 0.5) * 2;
					glitchAmount += - (glitchTextureR.b - 0.5) * 2;
					// } else {
					#else
					glitchAmount += frac(sin(dot(_Time.xy + o.worldPos.y, float2(12.9898, 78.233))) * 43758.5453123) * 2 - 1;
					// }
					#endif
					
					float time = _Time.y * _VertexGlitchFrequency;
					
					float randomGlitch = (sin(time) + sin(2.2 * time + 5.52) + sin(2.9 * time + 0.93) + sin(4.6 * time + 8.94)) / 4;
					float3 glitchOffset = 0;
					
					#ifdef POI_AUDIOLINK
					if (AudioLinkIsAvailable() && _VertexGlitchingAudioLinkEnabled)
					{
						// float4 audioLinkData = AudioLinkData(ALPASS_AUDIOBASS);
						
						float audioIntensity =
						AudioLinkData(ALPASS_AUDIOBASS).r 		* (_VertexGlitchingAudioLinkBand == 0) +
						AudioLinkData(ALPASS_AUDIOLOWMIDS).r 	* (_VertexGlitchingAudioLinkBand == 1) +
						AudioLinkData(ALPASS_AUDIOHIGHMIDS).r	* (_VertexGlitchingAudioLinkBand == 2) +
						AudioLinkData(ALPASS_AUDIOTREBLE).r 	* (_VertexGlitchingAudioLinkBand == 3) +
						AudioLinkData(ALPASS_FILTEREDVU_INTENSITY).r * (_VertexGlitchingAudioLinkBand == 4);
						
						if(_VertexGlitchingAudiolinkOverride)
						{
							glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
							// glitchOffset += glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
						} else {
							glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
							glitchOffset += glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
						}
					} else {
						glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
					}
					#else
					glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
					#endif
					
					localOffset += glitchOffset;
					worldOffset += mul(unity_ObjectToWorld, glitchOffset);
				}
				#endif
				//endex
				
				o.localPos.rgb += localOffset;
				o.worldPos.rgb += worldOffset;
				
				//ifex _EnableDepthBulge==0
				#if defined(POI_DEPTHBULGE) && (defined(POI_PASS_BASE) || defined(POI_PASS_ADD))
				applyDepthBulgeFX(o);
				#endif
				//endex
				
				//ifex _BSSEnabled!=1
				#ifdef POIBS_ENABLE
				//ifex _BSSBloomfog!=1
				#ifdef POIBS_BLOOMFOG
				o.fogCoord = GetFogCoord(UnityObjectToClipPos(v.vertex));
				o.worldPos = mul(unity_ObjectToWorld, v.vertex);
				#endif
				//endex
				#endif
				//endex
				
				o.pos = UnityObjectToClipPos(o.localPos);
				
				#ifdef POI_PASS_OUTLINE
				#if defined(UNITY_REVERSED_Z)
				//DX
				o.pos.z += _Offset_Z * - 0.01;
				#else
				//OpenGL
				o.pos.z += _Offset_Z * 0.01;
				#endif
				#endif
				//o.grabPos = ComputeGrabScreenPos(o.pos);
				
				#ifndef FORWARD_META_PASS
				#if !defined(UNITY_PASS_SHADOWCASTER)
				UNITY_TRANSFER_SHADOW(o, o.uv[0].xy);
				#else
				v.vertex.xyz = o.localPos.xyz;
				TRANSFER_SHADOW_CASTER_NOPOS(o, o.pos);
				#endif
				#endif
				
				UNITY_TRANSFER_FOG(o, o.pos);
				
				if (_RenderingReduceClipDistance)
				{
					if (o.pos.w < _ProjectionParams.y * 1.01 && o.pos.w > 0)
					{
						#if defined(UNITY_REVERSED_Z) // DirectX
						o.pos.z = o.pos.z * 0.0001 + o.pos.w * 0.999;
						#else // OpenGL
						o.pos.z = o.pos.z * 0.0001 - o.pos.w * 0.999;
						#endif
					}
				}
				
				#ifdef POI_PASS_META
				o.pos = UnityMetaVertexPosition(v.vertex, v.uv1.xy, v.uv2.xy, unity_LightmapST, unity_DynamicLightmapST);
				#endif
				
				return o;
			}
			
			#if defined(_STOCHASTICMODE_DELIOT_HEITZ)
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, uv) : POI2D_SAMPLER(tex, texSampler, uv))
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan)) : POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), dx, dy) : POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			#if defined(_STOCHASTICMODE_HEXTILE)
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, uv, false) : POI2D_SAMPLER(tex, texSampler, uv))
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), false) : POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), false, dx, dy) : POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			
			#ifndef POI2D_SAMPLER_STOCHASTIC
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (POI2D_SAMPLER(tex, texSampler, uv))
			#endif
			#ifndef POI2D_SAMPLER_PAN_STOCHASTIC
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#endif
			#ifndef POI2D_SAMPLER_PANGRAD_STOCHASTIC
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			
			// When using, properties won't properly lock at optimize time; needs macro evaluation implemented
			// #define POI2D_SAMPLER_STOCHASTIC_INLINED(tex, texSampler) (POI2D_SAMPLER_STOCHASTIC(tex, texSampler, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Stochastic))
			// #define POI2D_SAMPLER_PAN_STOCHASTIC_INLINED(tex, texSampler) (POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan, tex##Stochastic))
			
			// #define POI2D_MAINTEX_SAMPLER_STOCHASTIC_INLINED(tex) (POI2D_SAMPLER_STOCHASTIC(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Stochastic))
			// #define POI2D_MAINTEX_SAMPLER_PAN_STOCHASTIC_INLINED(tex) (POI2D_SAMPLER_PAN_STOCHASTIC(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan, tex##Stochastic))
			
			// Deliot, Heitz 2019 - Fast, but non-histogram-preserving (ends up looking a bit blurry and lower contrast)
			// https://eheitzresearch.wordpress.com/738-2/
			
			// Classic Magic Numbers fracsin
			#if !defined(_STOCHASTICMODE_NONE)
			float2 StochasticHash2D2D (float2 s)
			{
				return frac(sin(glsl_mod(float2(dot(s, float2(127.1,311.7)), dot(s, float2(269.5,183.3))), 3.14159)) * 43758.5453);
			}
			#endif
			
			#if defined(_STOCHASTICMODE_DELIOT_HEITZ)
			// UV Offsets and blend weights
			// UVBW[0...2].xy = UV Offsets
			// UVBW[0...2].z = Blend Weights
			float3x3 DeliotHeitzStochasticUVBW(float2 uv)
			{
				// UV transformed into triangular grid space with UV scaled by approximation of 2*sqrt(3)
				const float2x2 stochasticSkewedGrid = float2x2(1.0, -0.57735027, 0.0, 1.15470054);
				float2 skewUV = mul(stochasticSkewedGrid, uv * 3.4641 * _StochasticDeliotHeitzDensity);
				
				// Vertex IDs and barycentric coords
				float2 vxID = floor(skewUV);
				float3 bary = float3(frac(skewUV), 0);
				bary.z = 1.0 - bary.x - bary.y;
				
				float3x3 pos = float3x3(
				float3(vxID, 				bary.z),
				float3(vxID + float2(0, 1), bary.y),
				float3(vxID + float2(1, 0), bary.x)
				);
				
				float3x3 neg = float3x3(
				float3(vxID + float2(1, 1), 	 -bary.z),
				float3(vxID + float2(1, 0), 1.0 - bary.y),
				float3(vxID + float2(0, 1), 1.0 - bary.x)
				);
				
				return (bary.z > 0) ? pos : neg;
			}
			
			float4 DeliotHeitzSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, float2 dx, float2 dy)
			{
				// UVBW[0...2].xy = UV Offsets
				// UVBW[0...2].z = Blend Weights
				float3x3 UVBW = DeliotHeitzStochasticUVBW(uv);
				
				//blend samples with calculated weights
				return 	mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[0].xy), dx, dy), UVBW[0].z) +
				mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[1].xy), dx, dy), UVBW[1].z) +
				mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[2].xy), dx, dy), UVBW[2].z) ;
			}
			
			float4 DeliotHeitzSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv)
			{
				float2 dx = ddx(uv), dy = ddy(uv);
				return DeliotHeitzSampleTexture(tex, texSampler, uv, dx, dy);
			}
			#endif // defined(_STOCHASTICMODE_DELIOT_HEITZ)
			
			#if defined(_STOCHASTICMODE_HEXTILE)
			// HexTiling: Slower, but histogram-preserving
			// SPDX-License-Idenfitier: MIT
			// Copyright (c) 2022 mmikk
			// https://github.com/mmikk/hextile-demo
			float2 HextileMakeCenUV(float2 vertex)
			{
				// 0.288675 ~= 1/(2*sqrt(3))
				const float2x2 stochasticInverseSkewedGrid = float2x2(1.0, 0.5, 0.0, 1.0/1.15470054);
				return mul(stochasticInverseSkewedGrid, vertex) * 0.288675;
			}
			
			float2x2 HextileLoadRot2x2(float2 idx, float rotStrength)
			{
				float angle = abs(idx.x * idx.y) + abs(idx.x + idx.y) + PI;
				
				// remap to +/-pi
				angle = glsl_mod(angle, 2 * PI);
				if(angle < 0)  angle += 2 * PI;
				if(angle > PI) angle -= 2 * PI;
				
				angle *= rotStrength;
				
				float cs = cos(angle), si = sin(angle);
				return float2x2(cs, -si, si, cs);
			}
			
			// UV Offsets and base blend weights
			// UVBWR[0...2].xy = UV Offsets
			// UVBWR[0...2].zw = rotation costh/sinth -> reconstruct rotation matrix with float2x2(UVBWR[n].z, -UVBWR[n].w, UVBWR[n].w, UVBWR[n].z)
			// UVBWR[3].xyz = Blend Weights (w unused) - needs luminance weighting
			float4x4 HextileUVBWR(float2 uv)
			{
				// Create Triangle Grid
				// Skew input space into simplex triangle grid (3.4641 ~= 2*sqrt(3))
				const float2x2 stochasticSkewedGrid = float2x2(1.0, -0.57735027, 0.0, 1.15470054);
				float2 skewedCoord = mul(stochasticSkewedGrid, uv * 3.4641 * _StochasticHexGridDensity);
				
				float2 baseId = float2(floor(skewedCoord));
				float3 temp = float3(frac(skewedCoord), 0);
				temp.z = 1 - temp.x - temp.y;
				
				float s = step(0.0, -temp.z);
				float s2 = 2 * s - 1;
				
				float3 weights = float3(-temp.z * s2, s - temp.y * s2, s - temp.x * s2);
				
				float2 vertex0 = baseId + float2(s, s);
				float2 vertex1 = baseId + float2(s, 1 - s);
				float2 vertex2 = baseId + float2(1 - s, s);
				
				float2 cen0 = HextileMakeCenUV(vertex0), cen1 = HextileMakeCenUV(vertex1), cen2 = HextileMakeCenUV(vertex2);
				float2x2 rot0 = float2x2(1, 0, 0, 1), rot1 = float2x2(1, 0, 0, 1), rot2 = float2x2(1, 0, 0, 1);
				
				if(_StochasticHexRotationStrength > 0)
				{
					rot0 = HextileLoadRot2x2(vertex0, _StochasticHexRotationStrength);
					rot1 = HextileLoadRot2x2(vertex1, _StochasticHexRotationStrength);
					rot2 = HextileLoadRot2x2(vertex2, _StochasticHexRotationStrength);
				}
				
				return float4x4(
				float4(mul(uv - cen0, rot0) + cen0 + StochasticHash2D2D(vertex0), rot0[0].x, -rot0[0].y),
				float4(mul(uv - cen1, rot1) + cen1 + StochasticHash2D2D(vertex1), rot1[0].x, -rot1[0].y),
				float4(mul(uv - cen2, rot2) + cen2 + StochasticHash2D2D(vertex2), rot2[0].x, -rot2[0].y),
				float4(weights, 0)
				);
			}
			
			float4 HextileSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, bool isNormalMap, float2 dUVdx, float2 dUVdy)
			{
				// For some reason doing this instead of just calculating it directly prevents it from \
				// breaking after a certain number of textures use it. I don't understand why yet
				float4x4 UVBWR = HextileUVBWR(uv);
				
				// 2D Rotation Matrices for dUVdx/dy
				// Not sure if this constant folds during compiling when rot is locked at 0, so force it
				float2x2 rot0 = float2x2(1, 0, 0, 1), rot1 = float2x2(1, 0, 0, 1), rot2 = float2x2(1, 0, 0, 1);
				
				if(_StochasticHexRotationStrength > 0)
				{
					rot0 = float2x2(UVBWR[0].z, -UVBWR[0].w, UVBWR[0].w, UVBWR[0].z);
					rot1 = float2x2(UVBWR[1].z, -UVBWR[1].w, UVBWR[1].w, UVBWR[1].z);
					rot2 = float2x2(UVBWR[2].z, -UVBWR[2].w, UVBWR[2].w, UVBWR[2].z);
				}
				
				// Weights
				float3 W = UVBWR[3].xyz;
				
				// Sample texture
				// float3x4 c = float3x4(
				// 	tex.SampleGrad(texSampler, UVBWR[0].xy, mul(dUVdx, rot0), mul(dUVdy, rot0)),
				// 	tex.SampleGrad(texSampler, UVBWR[1].xy, mul(dUVdx, rot1), mul(dUVdy, rot1)),
				// 	tex.SampleGrad(texSampler, UVBWR[2].xy, mul(dUVdx, rot2), mul(dUVdy, rot2))
				// );
				
				float4 c0 = tex.SampleGrad(texSampler, UVBWR[0].xy, mul(dUVdx, rot0), mul(dUVdy, rot0));
				float4 c1 = tex.SampleGrad(texSampler, UVBWR[1].xy, mul(dUVdx, rot1), mul(dUVdy, rot1));
				float4 c2 = tex.SampleGrad(texSampler, UVBWR[2].xy, mul(dUVdx, rot2), mul(dUVdy, rot2));
				
				// Blend samples using luminance
				// This is technically incorrect for normal maps, but produces very similar
				// results to blending using normal map gradients (steepness)
				const float3 Lw = float3(0.299, 0.587, 0.114);
				float3 Dw = float3(dot(c0.xyz, Lw), dot(c1.xyz, Lw), dot(c2.xyz, Lw));
				
				Dw = lerp(1.0, Dw, _StochasticHexFallOffContrast);
				W = Dw * pow(W, _StochasticHexFallOffPower);
				// In the original hextiling there's a Gain3 step here, but it seems to slow things down \
				// and cause the UVs to break, so I've omitted it. Looks fine without
				
				W /= (W.x + W.y + W.z);
				return W.x * c0 + W.y * c1 + W.z * c2;
			}
			
			float4 HextileSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, bool isNormalMap)
			{
				return HextileSampleTexture(tex, texSampler, uv, isNormalMap, ddx(uv), ddy(uv));
			}
			#endif // defined(_STOCHASTICMODE_HEXTILE)
			
			void applyAlphaOptions(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiMods poiMods)
			{
				poiFragData.alpha = saturate(poiFragData.alpha + _AlphaMod);
				
				if (_AlphaGlobalMask > 0)
				{
					poiFragData.alpha = maskBlend(poiFragData.alpha, poiMods.globalMask[_AlphaGlobalMask - 1], _AlphaGlobalMaskBlendType);
				}
				
				//ifex _AlphaDistanceFade==0 && isNotAnimated(_AlphaDistanceFade)
				if (_AlphaDistanceFade)
				{
					float3 position = _AlphaDistanceFadeType ? poiMesh.worldPos : poiMesh.objectPosition;
					float distanceFadeMultiplier = lerp(_AlphaDistanceFadeMinAlpha, _AlphaDistanceFadeMaxAlpha, smoothstep(_AlphaDistanceFadeMin, _AlphaDistanceFadeMax, distance(position, poiCam.worldPos)));
					if (_AlphaDistanceFadeGlobalMask > 0)
					{
						distanceFadeMultiplier = lerp(1, distanceFadeMultiplier, poiMods.globalMask[_AlphaDistanceFadeGlobalMask - 1]);
					}
					poiFragData.alpha *= distanceFadeMultiplier;
				}
				//endex
				
				//ifex _AlphaFresnel==0 && isNotAnimated(_AlphaFresnel)
				if (_AlphaFresnel)
				{
					float holoRim = saturate(1 - smoothstep(min(_AlphaFresnelSharpness, _AlphaFresnelWidth), _AlphaFresnelWidth, (poiCam.vDotN)));
					holoRim = abs(lerp(1, holoRim, _AlphaFresnelAlpha));
					holoRim = _AlphaFresnelInvert ? 1 - holoRim : holoRim;
					if (_AlphaFresnelGlobalMask > 0)
					{
						holoRim = lerp(1, holoRim, poiMods.globalMask[_AlphaFresnelGlobalMask - 1]);
					}
					poiFragData.alpha *= holoRim;
				}
				//endex
				
				//ifex _AlphaAngular==0 && isNotAnimated(_AlphaAngular)
				if (_AlphaAngular)
				{
					half cameraAngleMin = _CameraAngleMin / 180;
					half cameraAngleMax = _CameraAngleMax / 180;
					half modelAngleMin = _ModelAngleMin / 180;
					half modelAngleMax = _ModelAngleMax / 180;
					float3 pos = _AngleCompareTo == 0 ? poiMesh.objectPosition : poiMesh.worldPos;
					half3 cameraToModelDirection = normalize(pos - getCameraPosition());
					half3 modelForwardDirection = normalize(mul(unity_ObjectToWorld, normalize(_AngleForwardDirection.rgb)));
					half cameraLookAtModel = remapClamped(cameraAngleMax, cameraAngleMin, .5 * dot(cameraToModelDirection, getCameraForward()) + .5);
					half modelLookAtCamera = remapClamped(modelAngleMax, modelAngleMin, .5 * dot(-cameraToModelDirection, modelForwardDirection) + .5);
					float angularAlphaMod = 1;
					if (_AngleType == 0)
					{
						angularAlphaMod = max(cameraLookAtModel, _AngleMinAlpha);
					}
					else if (_AngleType == 1)
					{
						angularAlphaMod = max(modelLookAtCamera, _AngleMinAlpha);
					}
					else if (_AngleType == 2)
					{
						angularAlphaMod = max(cameraLookAtModel * modelLookAtCamera, _AngleMinAlpha);
					}
					if (_AlphaAngularGlobalMask > 0)
					{
						angularAlphaMod = lerp(1, angularAlphaMod, poiMods.globalMask[_AlphaAngularGlobalMask - 1]);
					}
					poiFragData.alpha *= angularAlphaMod;
				}
				//endex
				
				//ifex _AlphaAudioLinkEnabled==0 && isNotAnimated(_AlphaAudioLinkEnabled)
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable && _AlphaAudioLinkEnabled)
				{
					poiFragData.alpha = saturate(poiFragData.alpha + lerp(_AlphaAudioLinkAddRange.x, _AlphaAudioLinkAddRange.y, poiMods.audioLink[_AlphaAudioLinkAddBand]));
				}
				#endif
				//endex
				
			}
			
			//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
			inline half Dither8x8Bayer(int x, int y)
			{
				// Premultiplied by 1/64
				const half dither[ 64 ] = {
					0.015625, 0.765625, 0.203125, 0.953125, 0.06250, 0.81250, 0.25000, 1.00000,
					0.515625, 0.265625, 0.703125, 0.453125, 0.56250, 0.31250, 0.75000, 0.50000,
					0.140625, 0.890625, 0.078125, 0.828125, 0.18750, 0.93750, 0.12500, 0.87500,
					0.640625, 0.390625, 0.578125, 0.328125, 0.68750, 0.43750, 0.62500, 0.37500,
					0.046875, 0.796875, 0.234375, 0.984375, 0.03125, 0.78125, 0.21875, 0.96875,
					0.546875, 0.296875, 0.734375, 0.484375, 0.53125, 0.28125, 0.71875, 0.46875,
					0.171875, 0.921875, 0.109375, 0.859375, 0.15625, 0.90625, 0.09375, 0.84375,
					0.671875, 0.421875, 0.609375, 0.359375, 0.65625, 0.40625, 0.59375, 0.34375
				};
				int r = y * 8 + x;
				return dither[r];
			}
			
			half calcDither(half2 grabPos)
			{
				return Dither8x8Bayer(glsl_mod(grabPos.x, 8), glsl_mod(grabPos.y, 8));
			}
			
			void applyDithering(inout PoiFragData poiFragData, in PoiCam poiCam)
			{
				if (_AlphaDithering)
				{
					float dither = calcDither(poiCam.posScreenPixels) - _AlphaDitherBias;
					poiFragData.alpha = saturate(poiFragData.alpha - (dither * (1 - poiFragData.alpha) * _AlphaDitherGradient));
				}
			}
			//endex
			
			//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
			void ApplyAlphaToCoverage(inout PoiFragData poiFragData, in PoiMesh poiMesh)
			{
				// Force Model Opacity to 1 if desired
				UNITY_BRANCH
				if (_Mode == 1)
				{
					UNITY_BRANCH
					if (_AlphaSharpenedA2C && _AlphaToCoverage)
					{
						// rescale alpha by mip level
						poiFragData.alpha *= 1 + max(0, CalcMipLevel(poiMesh.uv[0] * _MainTex_TexelSize.zw)) * _AlphaMipScale;
						// rescale alpha by partial derivative
						poiFragData.alpha = (poiFragData.alpha - _Cutoff) / max(fwidth(poiFragData.alpha), 0.0001) + _Cutoff;
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
				}
			}
			//endex
			
			void calculateGlobalThemes(inout PoiMods poiMods)
			{
				// Theme colors are defined as HDR; convert to SDR and do the HSV adjustment, then re-apply exposure
				float4 themeColorExposures = 0;
				float4 themeColor0, themeColor1, themeColor2, themeColor3 = 0;
				
				DecomposeHDRColor(_GlobalThemeColor0.rgb, themeColor0.rgb, themeColorExposures.x);
				DecomposeHDRColor(_GlobalThemeColor1.rgb, themeColor1.rgb, themeColorExposures.y);
				DecomposeHDRColor(_GlobalThemeColor2.rgb, themeColor2.rgb, themeColorExposures.z);
				DecomposeHDRColor(_GlobalThemeColor3.rgb, themeColor3.rgb, themeColorExposures.w);
				
				poiMods.globalColorTheme[0] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor0.rgb, frac(_GlobalThemeHue0 + _GlobalThemeHueSpeed0 * _Time.x), _GlobalThemeSaturation0, _GlobalThemeValue0), themeColorExposures.x), _GlobalThemeColor0.a);
				poiMods.globalColorTheme[1] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor1.rgb, frac(_GlobalThemeHue1 + _GlobalThemeHueSpeed1 * _Time.x), _GlobalThemeSaturation1, _GlobalThemeValue1), themeColorExposures.y), _GlobalThemeColor1.a);
				poiMods.globalColorTheme[2] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor2.rgb, frac(_GlobalThemeHue2 + _GlobalThemeHueSpeed2 * _Time.x), _GlobalThemeSaturation2, _GlobalThemeValue2), themeColorExposures.z), _GlobalThemeColor2.a);
				poiMods.globalColorTheme[3] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor3.rgb, frac(_GlobalThemeHue3 + _GlobalThemeHueSpeed3 * _Time.x), _GlobalThemeSaturation3, _GlobalThemeValue3), themeColorExposures.w), _GlobalThemeColor3.a);
			}
			
			//ifex _GlobalMaskTexturesEnable==0
			#ifdef POI_GLOBALMASK_TEXTURES
			void ApplyGlobalMaskTextures(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				#if defined(PROP_GLOBALMASKTEXTURE0) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol0 = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0_ST), _GlobalMaskTexture0Pan);
				if (_GlobalMaskTexture0Split)
				{
					poiMods.globalMask[0] = gmcol0.r;
					poiMods.globalMask[1] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_G), _GlobalMaskTexture0SplitPan_G).g;
					poiMods.globalMask[2] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_B), _GlobalMaskTexture0SplitPan_B).b;
					poiMods.globalMask[3] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_A), _GlobalMaskTexture0SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[0] = gmcol0[0];
					poiMods.globalMask[1] = gmcol0[1];
					poiMods.globalMask[2] = gmcol0[2];
					poiMods.globalMask[3] = gmcol0[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE1) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol1 = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1_ST), _GlobalMaskTexture1Pan);
				if (_GlobalMaskTexture1Split)
				{
					poiMods.globalMask[4] = gmcol1.r;
					poiMods.globalMask[5] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_G), _GlobalMaskTexture1SplitPan_G).g;
					poiMods.globalMask[6] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_B), _GlobalMaskTexture1SplitPan_B).b;
					poiMods.globalMask[7] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_A), _GlobalMaskTexture1SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[4] = gmcol1[0];
					poiMods.globalMask[5] = gmcol1[1];
					poiMods.globalMask[6] = gmcol1[2];
					poiMods.globalMask[7] = gmcol1[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE2) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol2 = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2_ST), _GlobalMaskTexture2Pan);
				if (_GlobalMaskTexture2Split)
				{
					poiMods.globalMask[8] = gmcol2.r;
					poiMods.globalMask[9] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_G), _GlobalMaskTexture2SplitPan_G).g;
					poiMods.globalMask[10] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_B), _GlobalMaskTexture2SplitPan_B).b;
					poiMods.globalMask[11] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_A), _GlobalMaskTexture2SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[8] = gmcol2[0];
					poiMods.globalMask[9] = gmcol2[1];
					poiMods.globalMask[10] = gmcol2[2];
					poiMods.globalMask[11] = gmcol2[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE3) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol3 = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3_ST), _GlobalMaskTexture3Pan);
				if (_GlobalMaskTexture3Split)
				{
					poiMods.globalMask[12] = gmcol3.r;
					poiMods.globalMask[13] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_G), _GlobalMaskTexture3SplitPan_G).g;
					poiMods.globalMask[14] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_B), _GlobalMaskTexture3SplitPan_B).b;
					poiMods.globalMask[15] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_A), _GlobalMaskTexture3SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[12] = gmcol3[0];
					poiMods.globalMask[13] = gmcol3[1];
					poiMods.globalMask[14] = gmcol3[2];
					poiMods.globalMask[15] = gmcol3[3];
				}
				#endif
			}
			#endif
			//endex
			//ifex _GlobalMaskOptionsEnable==0
			void ApplyGlobalMaskOptions(inout PoiMods poiMods)
			{
				//ifex _GlobalMaskOptionsType!=0
				if (_GlobalMaskOptionsType == 0)
				{
					poiMods.globalMask[0] = saturate(poiMods.globalMask[0] + _GlobalMaskSlider_0);
					poiMods.globalMask[1] = saturate(poiMods.globalMask[1] + _GlobalMaskSlider_1);
					poiMods.globalMask[2] = saturate(poiMods.globalMask[2] + _GlobalMaskSlider_2);
					poiMods.globalMask[3] = saturate(poiMods.globalMask[3] + _GlobalMaskSlider_3);
					poiMods.globalMask[4] = saturate(poiMods.globalMask[4] + _GlobalMaskSlider_4);
					poiMods.globalMask[5] = saturate(poiMods.globalMask[5] + _GlobalMaskSlider_5);
					poiMods.globalMask[6] = saturate(poiMods.globalMask[6] + _GlobalMaskSlider_6);
					poiMods.globalMask[7] = saturate(poiMods.globalMask[7] + _GlobalMaskSlider_7);
					poiMods.globalMask[8] = saturate(poiMods.globalMask[8] + _GlobalMaskSlider_8);
					poiMods.globalMask[9] = saturate(poiMods.globalMask[9] + _GlobalMaskSlider_9);
					poiMods.globalMask[10] = saturate(poiMods.globalMask[10] + _GlobalMaskSlider_10);
					poiMods.globalMask[11] = saturate(poiMods.globalMask[11] + _GlobalMaskSlider_11);
					poiMods.globalMask[12] = saturate(poiMods.globalMask[12] + _GlobalMaskSlider_12);
					poiMods.globalMask[13] = saturate(poiMods.globalMask[13] + _GlobalMaskSlider_13);
					poiMods.globalMask[14] = saturate(poiMods.globalMask[14] + _GlobalMaskSlider_14);
					poiMods.globalMask[15] = saturate(poiMods.globalMask[15] + _GlobalMaskSlider_15);
				}
				//endex
				//ifex _GlobalMaskOptionsType!=1
				if (_GlobalMaskOptionsType == 1)
				{
					poiMods.globalMask[0] = lerp(_GlobalMaskMinMaxSlider_0.x, _GlobalMaskMinMaxSlider_0.y, poiMods.globalMask[0]);
					poiMods.globalMask[1] = lerp(_GlobalMaskMinMaxSlider_1.x, _GlobalMaskMinMaxSlider_1.y, poiMods.globalMask[1]);
					poiMods.globalMask[2] = lerp(_GlobalMaskMinMaxSlider_2.x, _GlobalMaskMinMaxSlider_2.y, poiMods.globalMask[2]);
					poiMods.globalMask[3] = lerp(_GlobalMaskMinMaxSlider_3.x, _GlobalMaskMinMaxSlider_3.y, poiMods.globalMask[3]);
					poiMods.globalMask[4] = lerp(_GlobalMaskMinMaxSlider_4.x, _GlobalMaskMinMaxSlider_4.y, poiMods.globalMask[4]);
					poiMods.globalMask[5] = lerp(_GlobalMaskMinMaxSlider_5.x, _GlobalMaskMinMaxSlider_5.y, poiMods.globalMask[5]);
					poiMods.globalMask[6] = lerp(_GlobalMaskMinMaxSlider_6.x, _GlobalMaskMinMaxSlider_6.y, poiMods.globalMask[6]);
					poiMods.globalMask[7] = lerp(_GlobalMaskMinMaxSlider_7.x, _GlobalMaskMinMaxSlider_7.y, poiMods.globalMask[7]);
					poiMods.globalMask[8] = lerp(_GlobalMaskMinMaxSlider_8.x, _GlobalMaskMinMaxSlider_8.y, poiMods.globalMask[8]);
					poiMods.globalMask[9] = lerp(_GlobalMaskMinMaxSlider_9.x, _GlobalMaskMinMaxSlider_9.y, poiMods.globalMask[9]);
					poiMods.globalMask[10] = lerp(_GlobalMaskMinMaxSlider_10.x, _GlobalMaskMinMaxSlider_10.y, poiMods.globalMask[10]);
					poiMods.globalMask[11] = lerp(_GlobalMaskMinMaxSlider_11.x, _GlobalMaskMinMaxSlider_11.y, poiMods.globalMask[11]);
					poiMods.globalMask[12] = lerp(_GlobalMaskMinMaxSlider_12.x, _GlobalMaskMinMaxSlider_12.y, poiMods.globalMask[12]);
					poiMods.globalMask[13] = lerp(_GlobalMaskMinMaxSlider_13.x, _GlobalMaskMinMaxSlider_13.y, poiMods.globalMask[13]);
					poiMods.globalMask[14] = lerp(_GlobalMaskMinMaxSlider_14.x, _GlobalMaskMinMaxSlider_14.y, poiMods.globalMask[14]);
					poiMods.globalMask[15] = lerp(_GlobalMaskMinMaxSlider_15.x, _GlobalMaskMinMaxSlider_15.y, poiMods.globalMask[15]);
				}
				//endex
				//ifex _GlobalMaskOptionsType!=2
				if (_GlobalMaskOptionsType == 2)
				{
					if (_GlobalMaskToggleOn_0)  poiMods.globalMask[0] = 1;
					if (_GlobalMaskToggleOn_1)  poiMods.globalMask[1] = 1;
					if (_GlobalMaskToggleOn_2)  poiMods.globalMask[2] = 1;
					if (_GlobalMaskToggleOn_3)  poiMods.globalMask[3] = 1;
					if (_GlobalMaskToggleOn_4)  poiMods.globalMask[4] = 1;
					if (_GlobalMaskToggleOn_5)  poiMods.globalMask[5] = 1;
					if (_GlobalMaskToggleOn_6)  poiMods.globalMask[6] = 1;
					if (_GlobalMaskToggleOn_7)  poiMods.globalMask[7] = 1;
					if (_GlobalMaskToggleOn_8)  poiMods.globalMask[8] = 1;
					if (_GlobalMaskToggleOn_9)  poiMods.globalMask[9] = 1;
					if (_GlobalMaskToggleOn_10) poiMods.globalMask[10] = 1;
					if (_GlobalMaskToggleOn_11) poiMods.globalMask[11] = 1;
					if (_GlobalMaskToggleOn_12) poiMods.globalMask[12] = 1;
					if (_GlobalMaskToggleOn_13) poiMods.globalMask[13] = 1;
					if (_GlobalMaskToggleOn_14) poiMods.globalMask[14] = 1;
					if (_GlobalMaskToggleOn_15) poiMods.globalMask[15] = 1;
					
					poiMods.globalMask[0] *= (1 - _GlobalMaskToggleOff_0);
					poiMods.globalMask[1] *= (1 - _GlobalMaskToggleOff_1);
					poiMods.globalMask[2] *= (1 - _GlobalMaskToggleOff_2);
					poiMods.globalMask[3] *= (1 - _GlobalMaskToggleOff_3);
					poiMods.globalMask[4] *= (1 - _GlobalMaskToggleOff_4);
					poiMods.globalMask[5] *= (1 - _GlobalMaskToggleOff_5);
					poiMods.globalMask[6] *= (1 - _GlobalMaskToggleOff_6);
					poiMods.globalMask[7] *= (1 - _GlobalMaskToggleOff_7);
					poiMods.globalMask[8] *= (1 - _GlobalMaskToggleOff_8);
					poiMods.globalMask[9] *= (1 - _GlobalMaskToggleOff_9);
					poiMods.globalMask[10] *= (1 - _GlobalMaskToggleOff_10);
					poiMods.globalMask[11] *= (1 - _GlobalMaskToggleOff_11);
					poiMods.globalMask[12] *= (1 - _GlobalMaskToggleOff_12);
					poiMods.globalMask[13] *= (1 - _GlobalMaskToggleOff_13);
					poiMods.globalMask[14] *= (1 - _GlobalMaskToggleOff_14);
					poiMods.globalMask[15] *= (1 - _GlobalMaskToggleOff_15);
				}
				//endex
				
			}
			//endex
			
			float customDistanceBlend(float base, float blend, float blendType)
			{
				switch(blendType)
				{
					case 0: return blendNormal(base, blend); break;
					case 2: return blendMultiply(base, blend); break;
					default: return 0; break;
				}
			}
			
			void handleGlobalMaskDistance(int index, bool enable, bool type, float minAlpha, float maxAlpha, float min, float max, int blendType, in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				if (enable)
				{
					float3 position = type ? poiMesh.worldPos : poiMesh.objectPosition;
					float val = lerp(minAlpha, maxAlpha, smoothstep(min, max, distance(position, _WorldSpaceCameraPos)));
					poiMods.globalMask[index] = saturate(customDistanceBlend(poiMods.globalMask[index], val, blendType));
				}
			}
			
			void ApplyGlobalMaskModifiers(in PoiMesh poiMesh, inout PoiMods poiMods, in PoiCam poiCam)
			{
				//ifex _GlobalMaskModifiersBackfaceEnable==0
				if (_GlobalMaskModifiersBackfaceEnable)
				{
					float facingMode = saturate(poiMesh.isFrontFace) + 1;
					// _GlobalMaskBackface is 0 for ignore, 1 for back only, 2 for front only
					poiMods.globalMask[0] *= _GlobalMaskBackface_0 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_0));
					poiMods.globalMask[1] *= _GlobalMaskBackface_1 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_1));
					poiMods.globalMask[2] *= _GlobalMaskBackface_2 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_2));
					poiMods.globalMask[3] *= _GlobalMaskBackface_3 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_3));
					poiMods.globalMask[4] *= _GlobalMaskBackface_4 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_4));
					poiMods.globalMask[5] *= _GlobalMaskBackface_5 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_5));
					poiMods.globalMask[6] *= _GlobalMaskBackface_6 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_6));
					poiMods.globalMask[7] *= _GlobalMaskBackface_7 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_7));
					poiMods.globalMask[8] *= _GlobalMaskBackface_8 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_8));
					poiMods.globalMask[9] *= _GlobalMaskBackface_9 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_9));
					poiMods.globalMask[10] *= _GlobalMaskBackface_10 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_10));
					poiMods.globalMask[11] *= _GlobalMaskBackface_11 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_11));
					poiMods.globalMask[12] *= _GlobalMaskBackface_12 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_12));
					poiMods.globalMask[13] *= _GlobalMaskBackface_13 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_13));
					poiMods.globalMask[14] *= _GlobalMaskBackface_14 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_14));
					poiMods.globalMask[15] *= _GlobalMaskBackface_15 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_15));
				}
				//endex
				
				//ifex _GlobalMaskModifiersMirrorEnable==0
				if (_GlobalMaskModifiersMirrorEnable)
				{
					float mirrorMode = 0;
					if (_GlobalMaskMirrorVisibilityMode == 1) // VRC
					mirrorMode = VRCMirrorMode() > 0;
					else // Generic (CVR, etc)
					mirrorMode = IsInMirror();
					
					mirrorMode += 1;
					// _GlobalMaskMirror is 0 for ignore, 1 for outside mirror only, 2 for in mirror only
					poiMods.globalMask[0] *= _GlobalMaskMirror_0 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_0));
					poiMods.globalMask[1] *= _GlobalMaskMirror_1 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_1));
					poiMods.globalMask[2] *= _GlobalMaskMirror_2 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_2));
					poiMods.globalMask[3] *= _GlobalMaskMirror_3 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_3));
					poiMods.globalMask[4] *= _GlobalMaskMirror_4 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_4));
					poiMods.globalMask[5] *= _GlobalMaskMirror_5 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_5));
					poiMods.globalMask[6] *= _GlobalMaskMirror_6 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_6));
					poiMods.globalMask[7] *= _GlobalMaskMirror_7 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_7));
					poiMods.globalMask[8] *= _GlobalMaskMirror_8 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_8));
					poiMods.globalMask[9] *= _GlobalMaskMirror_9 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_9));
					poiMods.globalMask[10] *= _GlobalMaskMirror_10 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_10));
					poiMods.globalMask[11] *= _GlobalMaskMirror_11 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_11));
					poiMods.globalMask[12] *= _GlobalMaskMirror_12 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_12));
					poiMods.globalMask[13] *= _GlobalMaskMirror_13 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_13));
					poiMods.globalMask[14] *= _GlobalMaskMirror_14 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_14));
					poiMods.globalMask[15] *= _GlobalMaskMirror_15 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_15));
				}
				//endex
				
				//ifex _GlobalMaskModifiersCameraEnable==0
				if (_GlobalMaskModifiersCameraEnable)
				{
					float isCamera = VRCCameraMode() > 0;
					isCamera += 1;
					// _GlobalMaskCamera is 0 for ignore, 1 for outside camera only, 2 for in camera only
					poiMods.globalMask[0] *= _GlobalMaskCamera_0 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_0));
					poiMods.globalMask[1] *= _GlobalMaskCamera_1 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_1));
					poiMods.globalMask[2] *= _GlobalMaskCamera_2 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_2));
					poiMods.globalMask[3] *= _GlobalMaskCamera_3 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_3));
					poiMods.globalMask[4] *= _GlobalMaskCamera_4 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_4));
					poiMods.globalMask[5] *= _GlobalMaskCamera_5 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_5));
					poiMods.globalMask[6] *= _GlobalMaskCamera_6 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_6));
					poiMods.globalMask[7] *= _GlobalMaskCamera_7 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_7));
					poiMods.globalMask[8] *= _GlobalMaskCamera_8 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_8));
					poiMods.globalMask[9] *= _GlobalMaskCamera_9 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_9));
					poiMods.globalMask[10] *= _GlobalMaskCamera_10 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_10));
					poiMods.globalMask[11] *= _GlobalMaskCamera_11 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_11));
					poiMods.globalMask[12] *= _GlobalMaskCamera_12 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_12));
					poiMods.globalMask[13] *= _GlobalMaskCamera_13 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_13));
					poiMods.globalMask[14] *= _GlobalMaskCamera_14 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_14));
					poiMods.globalMask[15] *= _GlobalMaskCamera_15 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_15));
				}
				//endex
				//ifex _GlobalMaskModifiersDistanceEnable==0
				if (_GlobalMaskModifiersDistanceEnable)
				{
					//ifex _GlobalMaskDistanceEnable_0==0
					handleGlobalMaskDistance(0, _GlobalMaskDistanceEnable_0, _GlobalMaskDistanceType_0, _GlobalMaskDistanceMinAlpha_0, _GlobalMaskDistanceMaxAlpha_0, _GlobalMaskDistanceMin_0, _GlobalMaskDistanceMax_0, _GlobalMaskDistanceBlendType_0, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_1==0
					handleGlobalMaskDistance(1, _GlobalMaskDistanceEnable_1, _GlobalMaskDistanceType_1, _GlobalMaskDistanceMinAlpha_1, _GlobalMaskDistanceMaxAlpha_1, _GlobalMaskDistanceMin_1, _GlobalMaskDistanceMax_1, _GlobalMaskDistanceBlendType_1, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_2==0
					handleGlobalMaskDistance(2, _GlobalMaskDistanceEnable_2, _GlobalMaskDistanceType_2, _GlobalMaskDistanceMinAlpha_2, _GlobalMaskDistanceMaxAlpha_2, _GlobalMaskDistanceMin_2, _GlobalMaskDistanceMax_2, _GlobalMaskDistanceBlendType_2, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_3==0
					handleGlobalMaskDistance(3, _GlobalMaskDistanceEnable_3, _GlobalMaskDistanceType_3, _GlobalMaskDistanceMinAlpha_3, _GlobalMaskDistanceMaxAlpha_3, _GlobalMaskDistanceMin_3, _GlobalMaskDistanceMax_3, _GlobalMaskDistanceBlendType_3, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_4==0
					handleGlobalMaskDistance(4, _GlobalMaskDistanceEnable_4, _GlobalMaskDistanceType_4, _GlobalMaskDistanceMinAlpha_4, _GlobalMaskDistanceMaxAlpha_4, _GlobalMaskDistanceMin_4, _GlobalMaskDistanceMax_4, _GlobalMaskDistanceBlendType_4, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_5==0
					handleGlobalMaskDistance(5, _GlobalMaskDistanceEnable_5, _GlobalMaskDistanceType_5, _GlobalMaskDistanceMinAlpha_5, _GlobalMaskDistanceMaxAlpha_5, _GlobalMaskDistanceMin_5, _GlobalMaskDistanceMax_5, _GlobalMaskDistanceBlendType_5, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_6==0
					handleGlobalMaskDistance(6, _GlobalMaskDistanceEnable_6, _GlobalMaskDistanceType_6, _GlobalMaskDistanceMinAlpha_6, _GlobalMaskDistanceMaxAlpha_6, _GlobalMaskDistanceMin_6, _GlobalMaskDistanceMax_6, _GlobalMaskDistanceBlendType_6, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_7==0
					handleGlobalMaskDistance(7, _GlobalMaskDistanceEnable_7, _GlobalMaskDistanceType_7, _GlobalMaskDistanceMinAlpha_7, _GlobalMaskDistanceMaxAlpha_7, _GlobalMaskDistanceMin_7, _GlobalMaskDistanceMax_7, _GlobalMaskDistanceBlendType_7, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_8==0
					handleGlobalMaskDistance(8, _GlobalMaskDistanceEnable_8, _GlobalMaskDistanceType_8, _GlobalMaskDistanceMinAlpha_8, _GlobalMaskDistanceMaxAlpha_8, _GlobalMaskDistanceMin_8, _GlobalMaskDistanceMax_8, _GlobalMaskDistanceBlendType_8, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_9==0
					handleGlobalMaskDistance(9, _GlobalMaskDistanceEnable_9, _GlobalMaskDistanceType_9, _GlobalMaskDistanceMinAlpha_9, _GlobalMaskDistanceMaxAlpha_9, _GlobalMaskDistanceMin_9, _GlobalMaskDistanceMax_9, _GlobalMaskDistanceBlendType_9, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_10==0
					handleGlobalMaskDistance(10, _GlobalMaskDistanceEnable_10, _GlobalMaskDistanceType_10, _GlobalMaskDistanceMinAlpha_10, _GlobalMaskDistanceMaxAlpha_10, _GlobalMaskDistanceMin_10, _GlobalMaskDistanceMax_10, _GlobalMaskDistanceBlendType_10, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_11==0
					handleGlobalMaskDistance(11, _GlobalMaskDistanceEnable_11, _GlobalMaskDistanceType_11, _GlobalMaskDistanceMinAlpha_11, _GlobalMaskDistanceMaxAlpha_11, _GlobalMaskDistanceMin_11, _GlobalMaskDistanceMax_11, _GlobalMaskDistanceBlendType_11, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_12==0
					handleGlobalMaskDistance(12, _GlobalMaskDistanceEnable_12, _GlobalMaskDistanceType_12, _GlobalMaskDistanceMinAlpha_12, _GlobalMaskDistanceMaxAlpha_12, _GlobalMaskDistanceMin_12, _GlobalMaskDistanceMax_12, _GlobalMaskDistanceBlendType_12, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_13==0
					handleGlobalMaskDistance(13, _GlobalMaskDistanceEnable_13, _GlobalMaskDistanceType_13, _GlobalMaskDistanceMinAlpha_13, _GlobalMaskDistanceMaxAlpha_13, _GlobalMaskDistanceMin_13, _GlobalMaskDistanceMax_13, _GlobalMaskDistanceBlendType_13, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_14==0
					handleGlobalMaskDistance(14, _GlobalMaskDistanceEnable_14, _GlobalMaskDistanceType_14, _GlobalMaskDistanceMinAlpha_14, _GlobalMaskDistanceMaxAlpha_14, _GlobalMaskDistanceMin_14, _GlobalMaskDistanceMax_14, _GlobalMaskDistanceBlendType_14, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_15==0
					handleGlobalMaskDistance(15, _GlobalMaskDistanceEnable_15, _GlobalMaskDistanceType_15, _GlobalMaskDistanceMinAlpha_15, _GlobalMaskDistanceMaxAlpha_15, _GlobalMaskDistanceMin_15, _GlobalMaskDistanceMax_15, _GlobalMaskDistanceBlendType_15, poiMesh, poiMods);
					//endex
					
				}
				//endex
				
			}
			
			//ifex _GlobalMaskVertexColorRed==0 && _GlobalMaskVertexColorGreen==0 && _GlobalMaskVertexColorBlue==0 && _GlobalMaskVertexColorAlpha==0
			void ApplyGlobalMaskVertexColors(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				float4 vcol = poiMesh.vertexColor;
				if (_GlobalMaskVertexColorLinearSpace)
				{
					vcol.rgb = GammaToLinearSpace(vcol.rgb);
				}
				if (_GlobalMaskVertexColorRed > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorRed - 1, _GlobalMaskVertexColorRedBlendType, vcol.r);
				}
				if (_GlobalMaskVertexColorGreen > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorGreen - 1, _GlobalMaskVertexColorGreenBlendType, vcol.g);
				}
				if (_GlobalMaskVertexColorBlue > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorBlue - 1, _GlobalMaskVertexColorBlueBlendType, vcol.b);
				}
				if (_GlobalMaskVertexColorAlpha > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorAlpha - 1, _GlobalMaskVertexColorAlphaBlendType, vcol.a);
				}
			}
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#ifdef POI_UDIMDISCARD
			void applyUDIMDiscard(in VertexOut i)
			{
				if(_UDIMDiscardMode == 1) // Don't run if in vertex mode
				{
					float2 udim = floor(vertexUV(i, _UDIMDiscardUV));
					
					float isDiscarded = 0;
					float4 xMask = float4(  (udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					isDiscarded += (udim.y >= 0 && udim.y < 1) * dot(float4(_UDIMDiscardRow0_0, _UDIMDiscardRow0_1, _UDIMDiscardRow0_2, _UDIMDiscardRow0_3), xMask);
					isDiscarded += (udim.y >= 1 && udim.y < 2) * dot(float4(_UDIMDiscardRow1_0, _UDIMDiscardRow1_1, _UDIMDiscardRow1_2, _UDIMDiscardRow1_3), xMask);
					isDiscarded += (udim.y >= 2 && udim.y < 3) * dot(float4(_UDIMDiscardRow2_0, _UDIMDiscardRow2_1, _UDIMDiscardRow2_2, _UDIMDiscardRow2_3), xMask);
					isDiscarded += (udim.y >= 3 && udim.y < 4) * dot(float4(_UDIMDiscardRow3_0, _UDIMDiscardRow3_1, _UDIMDiscardRow3_2, _UDIMDiscardRow3_3), xMask);
					
					isDiscarded *= any(float4(udim.y >= 0, udim.y < 4, udim.x >= 0, udim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					const float threshold = 0.001;
					clip(threshold - isDiscarded); // Clip if discarded
				}
				
				return;
			}
			#endif
			//endex
			
			float2 calculatePolarCoordinate(in PoiMesh poiMesh)
			{
				float2 delta = poiMesh.uv[_PolarUV] - _PolarCenter;
				float radius = length(delta) * 2 * _PolarRadialScale;
				float angle = atan2(delta.x, delta.y);
				float phi = angle / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				angle = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				angle *= _PolarLengthScale;
				
				return float2(radius, angle + distance(poiMesh.uv[_PolarUV], _PolarCenter) * _PolarSpiralPower);
			}
			
			float2 MonoPanoProjection(float3 coords)
			{
				float3 normalizedCoords = normalize(coords);
				float latitude = acos(normalizedCoords.y);
				float longitude = atan2(normalizedCoords.z, normalizedCoords.x);
				float phi = longitude / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				longitude = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				longitude *= 2;
				float2 sphereCoords = float2(longitude, latitude) * float2(1.0, 1.0 / UNITY_PI);
				sphereCoords = float2(1.0, 1.0) - sphereCoords;
				return (sphereCoords + float4(0, 1 - unity_StereoEyeIndex, 1, 1.0).xy) * float4(0, 1 - unity_StereoEyeIndex, 1, 1.0).zw;
			}
			
			float2 StereoPanoProjection(float3 coords)
			{
				float3 normalizedCoords = normalize(coords);
				float latitude = acos(normalizedCoords.y);
				float longitude = atan2(normalizedCoords.z, normalizedCoords.x);
				float phi = longitude / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				longitude = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				longitude *= 2;
				float2 sphereCoords = float2(longitude, latitude) * float2(0.5, 1.0 / UNITY_PI);
				sphereCoords = float2(0.5, 1.0) - sphereCoords;
				return (sphereCoords + float4(0, 1 - unity_StereoEyeIndex, 1, 0.5).xy) * float4(0, 1 - unity_StereoEyeIndex, 1, 0.5).zw;
			}
			
			float2 calculateWorldUV(in PoiMesh poiMesh)
			{
				return float2(_UVModWorldPos0 != 3 ? poiMesh.worldPos[ _UVModWorldPos0] : 0.0f, _UVModWorldPos1 != 3 ? poiMesh.worldPos[_UVModWorldPos1] : 0.0f);
			}
			
			float2 calculatelocalUV(in PoiMesh poiMesh)
			{
				float localUVs[8];
				localUVs[0] = poiMesh.localPos.x;
				localUVs[1] = poiMesh.localPos.y;
				localUVs[2] = poiMesh.localPos.z;
				localUVs[3] = 0;
				localUVs[4] = poiMesh.vertexColor.r;
				localUVs[5] = poiMesh.vertexColor.g;
				localUVs[6] = poiMesh.vertexColor.b;
				localUVs[7] = poiMesh.vertexColor.a;
				
				return float2(localUVs[_UVModLocalPos0],localUVs[_UVModLocalPos1]);
			}
			
			float2 calculatePanosphereUV(in PoiMesh poiMesh)
			{
				float3 viewDirection = normalize(lerp(getCameraPosition().xyz, _WorldSpaceCameraPos.xyz, _PanoUseBothEyes) - poiMesh.worldPos.xyz) * - 1;
				return lerp(MonoPanoProjection(viewDirection), StereoPanoProjection(viewDirection), _StereoEnabled);
			}
			//ifex _EnableDistortion==0
			#ifdef USER_LUT
			float2 distortedUV(in PoiMesh poiMesh)
			{
				#if defined(PROP_DISTORTIONFLOWTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 flowVector = POI2D_SAMPLER_PAN(_DistortionFlowTexture, _MainTex, poiUV(poiMesh.uv[_DistortionFlowTextureUV], _DistortionFlowTexture_ST), _DistortionFlowTexturePan) * 2 - 1;
				#else
				float4 flowVector = -1;
				#endif
				
				#if defined(PROP_DISTORTIONFLOWTEXTURE1) || !defined(OPTIMIZER_ENABLED)
				float4 flowVector1 = POI2D_SAMPLER_PAN(_DistortionFlowTexture1, _MainTex, poiUV(poiMesh.uv[_DistortionFlowTexture1UV], _DistortionFlowTexture1_ST), _DistortionFlowTexture1Pan) * 2 - 1;
				#else
				float4 flowVector1 = -1;
				#endif
				
				#if defined(PROP_DISTORTIONMASK) || !defined(OPTIMIZER_ENABLED)
				half distortionMask = POI2D_SAMPLER_PAN(_DistortionMask, _MainTex, poiMesh.uv[_DistortionMaskUV], _DistortionMaskPan)[_DistortionMaskChannel];
				#else
				half distortionMask = 1;
				#endif
				
				half distortionStrength = _DistortionStrength;
				half distortionStrength1 = _DistortionStrength1;
				
				#ifdef POI_AUDIOLINK
				UNITY_BRANCH
				if (AudioLinkIsAvailable() && _EnableDistortionAudioLink && _AudioLinkAnimToggle)
				{
					distortionStrength += lerp(_DistortionStrengthAudioLink.x, _DistortionStrengthAudioLink.y, AudioLinkData(uint2(0, uint(_DistortionStrengthAudioLinkBand))).r);
					distortionStrength1 += lerp(_DistortionStrength1AudioLink.x, _DistortionStrength1AudioLink.y, AudioLinkData(uint2(0, uint(_DistortionStrength1AudioLinkBand))).r);
				}
				#endif
				
				flowVector *= distortionStrength;
				flowVector1 *= distortionStrength1;
				return poiMesh.uv[_DistortionUvToDistort] + ((flowVector.xy + flowVector1.xy) / 2) * distortionMask;
			}
			#endif
			//endex
			
			//ifex _PoiParallax==0
			#ifdef POI_PARALLAX
			inline float2 POM(in PoiLight poiLight, sampler2D heightMap, in PoiMesh poiMesh, float3 worldViewDir, float3 viewDirTan, int minSamples, int maxSamples, float parallax, float refPlane, float2 tilling, float2 curv)
			{
				#if defined(PROP_HEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float heightMask = POI2D_SAMPLER_PAN(_Heightmask, _linear_repeat, poiUV(poiMesh.uv[_HeightmaskUV], _Heightmask_ST), _HeightmaskPan)[_HeightmaskChannel];
				if (_HeightmaskInvert)
				{
					heightMask = 1 - heightMask;
				}
				#else
				float heightMask = 1;
				#endif
				
				float2 uvs = poiUV(poiMesh.uv[_HeightMapUV], _HeightMap_ST);
				float2 dx = ddx(uvs);
				float2 dy = ddy(uvs);
				float3 result = 0;
				int stepIndex = 0;
				int numSteps = (int)lerp(maxSamples, minSamples, saturate(dot(poiMesh.normals[0], worldViewDir)));
				float layerHeight = 1.0 / numSteps;
				float2 plane = parallax * heightMask * (viewDirTan.xy / viewDirTan.z);
				uvs += refPlane * plane;
				float2 deltaTex = -plane * layerHeight;
				float2 prevTexOffset = 0;
				float prevRayZ = 1.0f;
				float prevHeight = 0.0f;
				float2 currTexOffset = deltaTex;
				float currRayZ = 1.0f - layerHeight;
				float currHeight = 0.0f;
				float intersection = 0;
				float2 finalTexOffset = 0;
				while (stepIndex < numSteps + 1)
				{
					result.z = dot(curv, currTexOffset * currTexOffset);
					currHeight = tex2Dgrad(heightMap, uvs + currTexOffset, dx, dy).r * (1 - result.z);
					if (currHeight > currRayZ)
					{
						stepIndex = numSteps + 1;
					}
					else
					{
						stepIndex++;
						prevTexOffset = currTexOffset;
						prevRayZ = currRayZ;
						prevHeight = currHeight;
						currTexOffset += deltaTex;
						currRayZ -= layerHeight * (1 - result.z) * (1 + _CurvFix);
					}
				}
				int sectionSteps = 10;
				int sectionIndex = 0;
				float newZ = 0;
				float newHeight = 0;
				while (sectionIndex < sectionSteps)
				{
					intersection = (prevHeight - prevRayZ) / (prevHeight - currHeight + currRayZ - prevRayZ);
					finalTexOffset = prevTexOffset +intersection * deltaTex;
					newZ = prevRayZ - intersection * layerHeight;
					newHeight = tex2Dgrad(heightMap, uvs + finalTexOffset, dx, dy).r;
					if (newHeight > newZ)
					{
						currTexOffset = finalTexOffset;
						currHeight = newHeight;
						currRayZ = newZ;
						deltaTex = intersection * deltaTex;
						layerHeight = intersection * layerHeight;
					}
					else
					{
						prevTexOffset = finalTexOffset;
						prevHeight = newHeight;
						prevRayZ = newZ;
						deltaTex = (1 - intersection) * deltaTex;
						layerHeight = (1 - intersection) * layerHeight;
					}
					sectionIndex++;
				}
				#ifdef UNITY_PASS_SHADOWCASTER
				if (unity_LightShadowBias.z == 0.0)
				{
					#endif
					if (result.z > 1)
					clip(-1);
					#ifdef UNITY_PASS_SHADOWCASTER
				}
				#endif
				
				return uvs + finalTexOffset;
			}
			/*
			float2 ParallaxOffsetMultiStep(float surfaceHeight, float strength, float2 uv, float3 tangentViewDir)
			{
				float2 uvOffset = 0;
				float2 prevUVOffset = 0;
				float stepSize = 1.0 / _HeightSteps;
				float stepHeight = 1;
				float2 uvDelta = tangentViewDir.xy * (stepSize * strength);
				float prevStepHeight = stepHeight;
				float prevSurfaceHeight = surfaceHeight;
				
				[unroll(20)]
				for (int j = 1; j <= _HeightSteps && stepHeight > surfaceHeight; j++)
				{
					prevUVOffset = uvOffset;
					prevStepHeight = stepHeight;
					prevSurfaceHeight = surfaceHeight;
					uvOffset -= uvDelta;
					stepHeight -= stepSize;
					surfaceHeight = POI2D_SAMPLER_PAN(_Heightmap, _MainTex, poiUV(uv + uvOffset, _Heightmap_ST), _HeightmapPan) + _HeightOffset;
				}
				
				[unroll(3)]
				for (int k = 0; k < 3; k++)
				{
					uvDelta *= 0.5;
					stepSize *= 0.5;
					
					if (stepHeight < surfaceHeight)
					{
						uvOffset += uvDelta;
						stepHeight += stepSize;
					}
					else
					{
						uvOffset -= uvDelta;
						stepHeight -= stepSize;
					}
					surfaceHeight = POI2D_SAMPLER_PAN(_Heightmap, _MainTex, poiUV(uv + uvOffset, _Heightmap_ST), _HeightmapPan) + _HeightOffset;
				}
				return uvOffset;
			}
			*/
			void applyParallax(inout PoiMesh poiMesh, in PoiLight poiLight, in PoiCam poiCam)
			{
				/*
				half h = POI2D_SAMPLER_PAN(_Heightmap, _linear_repeat, poiUV(poiMesh.uv[_HeightmaskUV], _Heightmap_ST), _HeightmapPan).r + _HeightOffset;
				#if defined(PROP_HEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				half m = POI2D_SAMPLER_PAN(_Heightmask, _linear_repeat, poiUV(poiMesh.uv[_HeightmaskUV], _Heightmask_ST), _HeightmaskPan).r + _HeightOffset;
				#else
				half m = 1 + _HeightOffset;
				#endif
				h = clamp(h, 0, 0.999);
				m = lerp(m, 1 - m, _HeightmaskInvert);
				#if defined(OPTIMIZER_ENABLED)das
				poiMesh.uv[_ParallaxUV] += ParallaxOffsetMultiStep(h, _HeightStrength * m, poiMesh.uv[_HeightmapUV], tangentViewDir / tangentViewDir.z);
				#else
				float2 offset = ParallaxOffsetMultiStep(h, _HeightStrength * m, poiMesh.uv[_HeightmapUV], tangentViewDir / tangentViewDir.z);
				if (_ParallaxUV == 0)       poiMesh.uv[0] += offset;
				if (_ParallaxUV == 1)       poiMesh.uv[1] += offset;
				if (_ParallaxUV == 2)       poiMesh.uv[2] += offset;
				if (_ParallaxUV == 3)       poiMesh.uv[3] += offset;
				if (_ParallaxUV == 4)       poiMesh.uv[4] += offset;
				if (_ParallaxUV == 5)       poiMesh.uv[5] += offset;
				if (_ParallaxUV == 6)       poiMesh.uv[6] += offset;
				if (_ParallaxUV == 7)       poiMesh.uv[7] += offset;
				#endif
				*/
				
				#if defined(OPTIMIZER_ENABLED)
				poiMesh.uv[_ParallaxUV] = POM(poiLight, _HeightMap, poiMesh, poiCam.viewDir, poiCam.tangentViewDir, _HeightStepsMin, _HeightStepsMax, _HeightStrength, 0, _HeightMap_ST.xy, float2(_CurvatureU, _CurvatureV));
				#else
				float2 offset = POM(poiLight, _HeightMap, poiMesh, poiCam.viewDir, poiCam.tangentViewDir, _HeightStepsMin, _HeightStepsMax, _HeightStrength, 0, _HeightMap_ST.xy, float2(_CurvatureU, _CurvatureV));
				if (_ParallaxUV == 0)       poiMesh.uv[0] = offset;
				if (_ParallaxUV == 1)       poiMesh.uv[1] = offset;
				if (_ParallaxUV == 2)       poiMesh.uv[2] = offset;
				if (_ParallaxUV == 3)       poiMesh.uv[3] = offset;
				if (_ParallaxUV == 4)       poiMesh.uv[4] = offset;
				if (_ParallaxUV == 5)       poiMesh.uv[5] = offset;
				if (_ParallaxUV == 6)       poiMesh.uv[6] = offset;
				if (_ParallaxUV == 7)       poiMesh.uv[7] = offset;
				#endif
			}
			#endif
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#ifdef POI_BLACKLIGHTMASKING
			void calculateBlackLightMasks(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				#ifdef VERTEXLIGHT_ON
				for (int lightIndex = 0; lightIndex < 4; lightIndex++)
				{
					float3 lightPos = float3(unity_4LightPosX0[lightIndex], unity_4LightPosY0[lightIndex], unity_4LightPosZ0[lightIndex]);
					if (!distance(unity_LightColor[lightIndex].rgb, float3(0, 0, 0)))
					{
						if (_BlackLightMasking0GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking0Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking0GlobalMaskIndex - 1, _BlackLightMasking0GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking1GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking1Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking1GlobalMaskIndex - 1, _BlackLightMasking1GlobalMaskBlendType, smoothstep(_BlackLightMasking1Range.y, _BlackLightMasking1Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking2GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking2Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking2GlobalMaskIndex - 1, _BlackLightMasking2GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking3GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking3Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking3GlobalMaskIndex - 1, _BlackLightMasking3GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
					}
				}
				#else
				if (_BlackLightMasking0GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking0GlobalMaskIndex - 1, _BlackLightMasking0GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking1GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking1GlobalMaskIndex - 1, _BlackLightMasking1GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking2GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking2GlobalMaskIndex - 1, _BlackLightMasking2GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking3GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking3GlobalMaskIndex - 1, _BlackLightMasking3GlobalMaskBlendType, 0);
				}
				#endif
			}
			#endif
			//endex
			
			//ifex _DetailEnabled==0
			#ifdef FINALPASS
			void ApplyDetailColor(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				#if defined(PROP_DETAILTEX) || !defined(OPTIMIZER_ENABLED)
				half3 detailTexture = POI2D_SAMPLER_PAN_STOCHASTIC(_DetailTex, _MainTex, poiUV(poiMesh.uv[_DetailTexUV], _DetailTex_ST), _DetailTexPan, _DetailTexStochastic).rgb * poiThemeColor(poiMods, _DetailTint, _DetailTintThemeIndex);
				#else
				half3 detailTexture = 0.21763764082 * poiThemeColor(poiMods, _DetailTint, _DetailTintThemeIndex);
				#endif
				
				poiFragData.baseColor.rgb *= LerpWhiteTo(detailTexture * _DetailBrightness * unity_ColorSpaceDouble.rgb, poiMods.detailMask.r * _DetailTexIntensity);
			}
			
			void ApplyDetailNormal(inout PoiMods poiMods, inout PoiMesh poiMesh)
			{
				#if defined(PROP_DETAILMASK) || !defined(OPTIMIZER_ENABLED)
				poiMods.detailMask = POI2D_SAMPLER_PAN_STOCHASTIC(_DetailMask, _MainTex, poiUV(poiMesh.uv[_DetailMaskUV], _DetailMask_ST), _DetailMaskPan, _DetailMaskStochastic).rg;
				#else
				poiMods.detailMask = 1;
				#endif
				
				#ifdef POI_BACKFACE
				if (!poiMesh.isFrontFace)
				{
					poiMods.detailMask.rg *= _BackFaceDetailIntensity;
				}
				#endif
				
				if (_DetailTexGlobalMask > 0)
				{
					poiMods.detailMask.r = maskBlend(poiMods.detailMask.r, poiMods.globalMask[_DetailTexGlobalMask-1], _DetailTexGlobalMaskBlendType);
				}
				if (_DetailNormalGlobalMask > 0)
				{
					poiMods.detailMask.g = maskBlend(poiMods.detailMask.g, poiMods.globalMask[_DetailNormalGlobalMask-1], _DetailNormalGlobalMaskBlendType);
				}
				
				#if defined(PROP_DETAILNORMALMAP) || !defined(OPTIMIZER_ENABLED)
				half3 detailNormal = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_DetailNormalMap, _MainTex, poiUV(poiMesh.uv[_DetailNormalMapUV], _DetailNormalMap_ST), _DetailNormalMapPan, _DetailNormalMapStochastic), _DetailNormalMapScale * poiMods.detailMask.g);
				poiMesh.tangentSpaceNormal = BlendNormals(detailNormal, poiMesh.tangentSpaceNormal);
				#endif
			}
			#endif
			//endex
			
			//ifex _MainVertexColoringEnabled==0
			void applyVertexColor(inout PoiFragData poiFragData, PoiMesh poiMesh)
			{
				if (_MainVertexColoringEnabled)
				{
					#ifndef POI_PASS_OUTLINE
					float3 vertCol = lerp(poiMesh.vertexColor.rgb, GammaToLinearSpace(poiMesh.vertexColor.rgb), _MainVertexColoringLinearSpace);
					poiFragData.baseColor *= lerp(1, vertCol, _MainVertexColoring);
					#endif
					poiFragData.alpha *= lerp(1, poiMesh.vertexColor.a, _MainUseVertexColorAlpha);
				}
			}
			//endex
			
			//ifex _BackFaceEnabled!=1
			#ifdef POI_BACKFACE
			void ApplyBackFaceColor(inout PoiFragData poiFragData, in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				if (!poiMesh.isFrontFace)
				{
					float4 backFaceColor = _BackFaceColor;
					backFaceColor.rgb = poiThemeColor(poiMods, backFaceColor.rgb, _BackFaceColorThemeIndex);
					#if defined(PROP_BACKFACETEXTURE) || !defined(OPTIMIZER_ENABLED)
					backFaceColor *= POI2D_SAMPLER_PAN(_BackFaceTexture, _MainTex, poiUV(poiMesh.uv[_BackFaceTextureUV], _BackFaceTexture_ST), _BackFaceTexturePan);
					#endif
					backFaceColor.rgb = hueShift(backFaceColor.rgb, frac(_BackFaceHueShift + _BackFaceHueShiftSpeed * _Time.x) * _BackFaceHueShiftEnabled);
					
					float backFaceMask = 1;
					#if defined(PROP_BACKFACEMASK) || !defined(OPTIMIZER_ENABLED)
					backFaceMask *= POI2D_SAMPLER_PAN(_BackFaceMask, _MainTex, poiUV(poiMesh.uv[_BackFaceMaskUV], _BackFaceMask_ST), _BackFaceMaskPan)[_BackFaceMaskChannel];
					#endif
					if (!_BackFaceReplaceAlpha)
					{
						backFaceMask *= backFaceColor.a;
					}
					
					poiFragData.baseColor = lerp(poiFragData.baseColor, backFaceColor.rgb, backFaceMask);
					
					UNITY_BRANCH
					if (_BackFaceReplaceAlpha)
					{
						poiFragData.alpha = backFaceColor.a;
					}
					
					poiFragData.emission += backFaceColor.rgb * _BackFaceEmissionStrength * backFaceMask;
					poiMods.globalEmission = poiMods.globalEmission * _BackFaceEmissionLimiter;
				}
			}
			#endif
			//endex
			
			//ifex _RGBMaskEnabled==0
			
			void RGBABlendColor(inout PoiFragData poiFragData, in float mask, in float4 color, float emissionStrength, in float blendType, in float blendAdd, in float enabled)
			{
				if (!enabled) return;
				float alpha = mask * saturate(color.a + blendAdd);
				poiFragData.baseColor = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, color.rgb, blendType), alpha);
				poiFragData.emission += color.rgb * emissionStrength * alpha;
			}
			
			void RGBABlendNormals(inout float3 tangentSpaceNormal, float3 normalToBlendWith, float maskValue, int blendMode)
			{
				if (blendMode == 0)
				{
					tangentSpaceNormal = lerp(tangentSpaceNormal, normalToBlendWith, maskValue);
				}
				else
				{
					tangentSpaceNormal = BlendNormals(tangentSpaceNormal, normalToBlendWith);
				}
			}
			
			#ifdef VIGNETTE
			#if !defined(UNITY_PASS_SHADOWCASTER) && !defined(POI_PASS_OUTLINE)
			void calculateRGBNormals(inout PoiMesh poiMesh, inout PoiMods poiMods)
			{
				// Only define this if we actually have any normal map textures. Can't do the same in color textures because users can tint
				#if defined(PROP_RGBNORMALR) || defined(PROP_RGBNORMALG) || defined(PROP_RGBNORMALB) || defined(PROP_RGBNORMALA) || !defined(OPTIMIZER_ENABLED)
				float4 rgbMask = 1;
				
				#if defined(PROP_RGBMASK) || !defined(OPTIMIZER_ENABLED)
				if (_RGBMaskType == 0)
				{
					rgbMask = POI2D_SAMPLER_PAN(_RGBMask, _trilinear_repeat, poiUV(poiMesh.uv[_RGBMaskUV], _RGBMask_ST), _RGBMaskPan);
				}
				#endif
				
				if (_RGBMaskType == 1)
				{
					rgbMask = poiMesh.vertexColor;
				}
				
				float4 maskFinal = 1;
				maskFinal.r = rgbMask[_RgbNormalRMaskChannel];
				maskFinal.g = rgbMask[_RgbNormalGMaskChannel];
				maskFinal.b = rgbMask[_RgbNormalBMaskChannel];
				maskFinal.a = rgbMask[_RgbNormalAMaskChannel];
				
				if (_RgbNormalRGlobalMaskChannel > 0) maskFinal.r = customBlend(maskFinal.r, poiMods.globalMask[_RgbNormalRGlobalMaskChannel - 1], _RgbNormalRGlobalMaskBlendType);
				if (_RgbNormalGGlobalMaskChannel > 0) maskFinal.g = customBlend(maskFinal.g, poiMods.globalMask[_RgbNormalGGlobalMaskChannel - 1], _RgbNormalGGlobalMaskBlendType);
				if (_RgbNormalBGlobalMaskChannel > 0) maskFinal.b = customBlend(maskFinal.b, poiMods.globalMask[_RgbNormalBGlobalMaskChannel - 1], _RgbNormalBGlobalMaskBlendType);
				if (_RgbNormalAGlobalMaskChannel > 0) maskFinal.a = customBlend(maskFinal.a, poiMods.globalMask[_RgbNormalAGlobalMaskChannel - 1], _RgbNormalAGlobalMaskBlendType);
				
				#if defined(PROP_RGBNORMALR) || !defined(OPTIMIZER_ENABLED)
				if (_RgbNormalRScale > 0 && _RGBARedEnable)
				{
					float3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_RgbNormalR, _trilinear_repeat, poiUV(poiMesh.uv[_RgbNormalRUV], _RgbNormalR_ST), _RgbNormalRPan, _RgbNormalRStochastic), _RgbNormalRedBlendMode == 0 ? _RgbNormalRScale : _RgbNormalRScale * maskFinal.r);
					RGBABlendNormals(poiMesh.tangentSpaceNormal, normalToBlendWith, maskFinal.r, _RgbNormalRedBlendMode);
				}
				#endif
				#if defined(PROP_RGBNORMALG) || !defined(OPTIMIZER_ENABLED)
				if (_RgbNormalGScale > 0 && _RGBAGreenEnable)
				{
					float3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_RgbNormalG, _trilinear_repeat, poiUV(poiMesh.uv[_RgbNormalGUV], _RgbNormalG_ST), _RgbNormalGPan, _RgbNormalGStochastic), _RgbNormalGreenBlendMode == 0 ? _RgbNormalGScale : _RgbNormalGScale * maskFinal.g);
					RGBABlendNormals(poiMesh.tangentSpaceNormal, normalToBlendWith, maskFinal.g, _RgbNormalGreenBlendMode);
				}
				#endif
				#if defined(PROP_RGBNORMALB) || !defined(OPTIMIZER_ENABLED)
				if (_RgbNormalBScale > 0 && _RGBABlueEnable)
				{
					float3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_RgbNormalB, _trilinear_repeat, poiUV(poiMesh.uv[_RgbNormalBUV], _RgbNormalB_ST), _RgbNormalBPan, _RgbNormalBStochastic), _RgbNormalBlueBlendMode == 0 ? _RgbNormalBScale : _RgbNormalBScale * maskFinal.b);
					RGBABlendNormals(poiMesh.tangentSpaceNormal, normalToBlendWith, maskFinal.b, _RgbNormalBlueBlendMode);
				}
				#endif
				#if defined(PROP_RGBNORMALA) || !defined(OPTIMIZER_ENABLED)
				if (_RgbNormalAScale > 0 && _RGBAAlphaEnable)
				{
					float3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_RgbNormalA, _trilinear_repeat, poiUV(poiMesh.uv[_RgbNormalAUV], _RgbNormalA_ST), _RgbNormalAPan, _RgbNormalAStochastic), _RgbNormalAlphaBlendMode == 0 ? _RgbNormalAScale : _RgbNormalAScale * maskFinal.a);
					RGBABlendNormals(poiMesh.tangentSpaceNormal, normalToBlendWith, maskFinal.a, _RgbNormalAlphaBlendMode);
				}
				#endif
				#endif
			}
			#endif
			
			void calculateRGBMask(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float4 rgbMask = float4(1, 1, 1, 1);
				float4 red = float4(poiThemeColor(poiMods, _RedColor.rgb, _RedColorThemeIndex), _RedColor.a);
				float4 green = float4(poiThemeColor(poiMods, _GreenColor.rgb, _GreenColorThemeIndex), _GreenColor.a);
				float4 blue = float4(poiThemeColor(poiMods, _BlueColor.rgb, _BlueColorThemeIndex), _BlueColor.a);
				float4 alpha = float4(poiThemeColor(poiMods, _AlphaColor.rgb, _AlphaColorThemeIndex), _AlphaColor.a);
				
				#if defined(PROP_RGBMASK) || !defined(OPTIMIZER_ENABLED)
				if (_RGBMaskType == 0)
				{
					rgbMask = POI2D_SAMPLER_PAN(_RGBMask, _trilinear_repeat, poiUV(poiMesh.uv[_RGBMaskUV], _RGBMask_ST), _RGBMaskPan);
				}
				#endif
				
				if (_RGBMaskType == 1)
				{
					rgbMask = poiMesh.vertexColor;
				}
				
				#if defined(PROP_REDTEXTURE) || !defined(OPTIMIZER_ENABLED)
				red *= POI2D_SAMPLER_PAN_STOCHASTIC(_RedTexture, _trilinear_repeat, poiUV(poiMesh.uv[_RedTextureUV], _RedTexture_ST), _RedTexturePan.xy, _RedTextureStochastic);
				#endif
				#if defined(PROP_GREENTEXTURE) || !defined(OPTIMIZER_ENABLED)
				green *= POI2D_SAMPLER_PAN_STOCHASTIC(_GreenTexture, _trilinear_repeat, poiUV(poiMesh.uv[_GreenTextureUV], _GreenTexture_ST), _GreenTexturePan.xy, _GreenTextureStochastic);
				#endif
				#if defined(PROP_BLUETEXTURE) || !defined(OPTIMIZER_ENABLED)
				blue *= POI2D_SAMPLER_PAN_STOCHASTIC(_BlueTexture, _trilinear_repeat, poiUV(poiMesh.uv[_BlueTextureUV], _BlueTexture_ST), _BlueTexturePan.xy, _BlueTextureStochastic);
				#endif
				#if defined(PROP_ALPHATEXTURE) || !defined(OPTIMIZER_ENABLED)
				alpha *= POI2D_SAMPLER_PAN_STOCHASTIC(_AlphaTexture, _trilinear_repeat, poiUV(poiMesh.uv[_AlphaTextureUV], _AlphaTexture_ST), _AlphaTexturePan.xy, _AlphaTextureStochastic);
				#endif
				
				RGBABlendColor(poiFragData, globalMaskBlend(rgbMask[_RgbRedMaskChannel], _RgbRedGlobalMaskChannel, _RgbRedGlobalMaskBlendType, poiMods), red, _RGBARedEmissionStrength, _RGBARedBlendType, _RedAlphaAdd, _RGBARedEnable);
				RGBABlendColor(poiFragData, globalMaskBlend(rgbMask[_RgbGreenMaskChannel], _RgbGreenGlobalMaskChannel, _RgbGreenGlobalMaskBlendType, poiMods), green, _RGBAGreenEmissionStrength, _RGBAGreenBlendType, _GreenAlphaAdd, _RGBAGreenEnable);
				RGBABlendColor(poiFragData, globalMaskBlend(rgbMask[_RgbBlueMaskChannel], _RgbBlueGlobalMaskChannel, _RgbBlueGlobalMaskBlendType, poiMods), blue, _RGBABlueEmissionStrength, _RGBABlueBlendType, _BlueAlphaAdd, _RGBABlueEnable);
				RGBABlendColor(poiFragData, globalMaskBlend(rgbMask[_RgbAlphaMaskChannel], _RgbAlphaGlobalMaskChannel, _RgbAlphaGlobalMaskBlendType, poiMods), alpha, _RGBAAlphaEmissionStrength, _RGBAAlphaBlendType, _AlphaAlphaAdd, _RGBAAlphaEnable);
				
				if (_RGBAPBRRedEnabled || _RGBAPBRGreenEnabled || _RGBAPBRBlueEnabled || _RGBAPBRAlphaEnabled)
				{
					#if defined(PROP_RGBASMOOTHNESSMAPS) || !defined(OPTIMIZER_ENABLED)
					float4 smoothnessMaps = 1;
					if (!_RGBARedPBRSplitMaskSample || !_RGBAGreenPBRSplitMaskSample || !_RGBABluePBRSplitMaskSample || !_RGBAAlphaPBRSplitMaskSample)
					{
						smoothnessMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBASmoothnessMapsUV], _RGBASmoothnessMaps_ST), _RGBASmoothnessMapsPan.xy, _RGBASmoothnessMapsStochastic);
					}
					
					if (_RGBARedPBRSplitMaskSample && _RGBAPBRRedEnabled && _RGBARedEnable)
					{
						smoothnessMaps.r = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBARedPBRUV], _RGBARedPBRMaskScaleTiling), _RGBARedPBRMasksPan.xy, _RGBARedPBRSplitMaskStochastic).r;
					}
					if (_RGBAGreenPBRSplitMaskSample && _RGBAPBRGreenEnabled && _RGBAGreenEnable)
					{
						smoothnessMaps.g = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAGreenPBRUV], _RGBAGreenPBRMaskScaleTiling), _RGBAGreenPBRMasksPan.xy, _RGBAGreenPBRSplitMaskStochastic).g;
					}
					if (_RGBABluePBRSplitMaskSample && _RGBAPBRBlueEnabled && _RGBABlueEnable)
					{
						smoothnessMaps.b = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBABluePBRUV], _RGBABluePBRMaskScaleTiling), _RGBABluePBRMasksPan.xy, _RGBABluePBRSplitMaskStochastic).b;
					}
					if (_RGBAAlphaPBRSplitMaskSample && _RGBAPBRAlphaEnabled && _RGBAAlphaEnable)
					{
						smoothnessMaps.a = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAAlphaPBRUV], _RGBAAlphaPBRMaskScaleTiling), _RGBAAlphaPBRMasksPan.xy, _RGBAAlphaPBRSplitMaskStochastic).a;
					}
					
					poiFragData.smoothness = lerp(poiFragData.smoothness, poiInvertToggle(smoothnessMaps.r, _RGBARedSmoothnessInvert), rgbMask[_RgbRedMaskChannel] * (_RGBAPBRRedEnabled && _RGBARedEnable));
					poiFragData.smoothness = lerp(poiFragData.smoothness, poiInvertToggle(smoothnessMaps.g, _RGBAGreenSmoothnessInvert), rgbMask[_RgbGreenMaskChannel] * (_RGBAPBRGreenEnabled && _RGBAGreenEnable));
					poiFragData.smoothness = lerp(poiFragData.smoothness, poiInvertToggle(smoothnessMaps.b, _RGBABlueSmoothnessInvert), rgbMask[_RgbBlueMaskChannel] * (_RGBAPBRBlueEnabled && _RGBABlueEnable));
					poiFragData.smoothness = lerp(poiFragData.smoothness, poiInvertToggle(smoothnessMaps.a, _RGBAAlphaSmoothnessInvert), rgbMask[_RgbAlphaMaskChannel] * (_RGBAPBRAlphaEnabled && _RGBAAlphaEnable));
					#endif
					
					#if defined(PROP_RGBAMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
					float4 metallicMaps = 1;
					if (!_RGBARedPBRSplitMaskSample || !_RGBAGreenPBRSplitMaskSample || !_RGBABluePBRSplitMaskSample || !_RGBAAlphaPBRSplitMaskSample)
					{
						metallicMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAMetallicMapsUV], _RGBAMetallicMaps_ST), _RGBAMetallicMapsPan.xy, _RGBAMetallicMapsStochastic);
					}
					
					if (_RGBARedPBRSplitMaskSample && _RGBAPBRRedEnabled && _RGBARedEnable)
					{
						metallicMaps.r = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBARedPBRUV], _RGBARedPBRMaskScaleTiling), _RGBARedPBRMasksPan.xy, _RGBARedPBRSplitMaskStochastic).r;
					}
					if (_RGBAGreenPBRSplitMaskSample && _RGBAPBRGreenEnabled && _RGBAGreenEnable)
					{
						metallicMaps.g = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAGreenPBRUV], _RGBAGreenPBRMaskScaleTiling), _RGBAGreenPBRMasksPan.xy, _RGBAGreenPBRSplitMaskStochastic).g;
					}
					if (_RGBABluePBRSplitMaskSample && _RGBAPBRBlueEnabled && _RGBABlueEnable)
					{
						metallicMaps.b = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBABluePBRUV], _RGBABluePBRMaskScaleTiling), _RGBABluePBRMasksPan.xy, _RGBABluePBRSplitMaskStochastic).b;
					}
					if (_RGBAAlphaPBRSplitMaskSample && _RGBAPBRAlphaEnabled && _RGBAAlphaEnable)
					{
						metallicMaps.a = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAAlphaPBRUV], _RGBAAlphaPBRMaskScaleTiling), _RGBAAlphaPBRMasksPan.xy, _RGBAAlphaPBRSplitMaskStochastic).a;
					}
					
					poiFragData.metallic = lerp(poiFragData.metallic, poiInvertToggle(metallicMaps.r, _RGBARedMetallicInvert), rgbMask[_RgbRedMaskChannel] * (_RGBAPBRRedEnabled && _RGBARedEnable));
					poiFragData.metallic = lerp(poiFragData.metallic, poiInvertToggle(metallicMaps.g, _RGBAGreenMetallicInvert), rgbMask[_RgbGreenMaskChannel] * (_RGBAPBRGreenEnabled && _RGBAGreenEnable));
					poiFragData.metallic = lerp(poiFragData.metallic, poiInvertToggle(metallicMaps.b, _RGBABlueMetallicInvert), rgbMask[_RgbBlueMaskChannel] * (_RGBAPBRBlueEnabled && _RGBABlueEnable));
					poiFragData.metallic = lerp(poiFragData.metallic, poiInvertToggle(metallicMaps.a, _RGBAAlphaMetallicInvert), rgbMask[_RgbAlphaMaskChannel] * (_RGBAPBRAlphaEnabled && _RGBAAlphaEnable));
					#endif
				}
			}
			#endif
			//endex
			
			//ifex _LTCGIEnabled!=1
			#ifdef POI_LTCGI
			// #include "../../ThirdParty/LTCGI/LTCGI_structs.cginc"
			// LTCGI_structs.cginc
			#define LTCGI_COLORMODE_STATIC 0
			#define LTCGI_COLORMODE_TEXTURE 1
			#define LTCGI_COLORMODE_SINGLEUV 2
			#define LTCGI_COLORMODE_AUDIOLINK 3
			
			struct ltcgi_flags
			{
				bool doublesided; // if the light is doublesided or only illuminates the front face
				bool diffFromLm; // diffuse lighting intensity will not be calculated via LTC but taken directly from the lightmap
				bool specular; // if the light has a specular component
				bool diffuse; // if the light has a diffuse component
				uint colormode; // colormode, see above
				uint texindex; // index of the texture to shade with, if colormode == LTCGI_COLORMODE_TEXTURE
				uint lmch, lmidx; // lightmap channel and index
				bool cylinder; // is this light a cylinder
				uint alBand; // audiolink band if colormode == LTCGI_COLORMODE_AUDIOLINK
				bool lmdOnly; // if this light is lightmap-diffuse _only_, that is, no LTC will be run (Lw will be all 0 in that case) - this will never be true on avatars (with LTCGI_ALWAYS_LTC_DIFFUSE)
				
			};
			
			struct ltcgi_input
			{
				uint i; // light number
				float3 Lw[4]; // world space area light vertices, Lw[1] == Lw[3] for triangle lights, shifted by input worldPos (i.e. world space position as seen from (0, 0, 0))
				bool isTri; // if this is a triangle light, quad if false
				float2 uvStart; //
				float2 uvEnd; // defines the UV layout of the area, top left to bottom right
				float3 rawColor; // the raw light color, unaffected by any colormode calculations (i.e. exactly what's given as "color" in editor)
				float3 screenNormal; // world space normal direction of area light
				ltcgi_flags flags; // flags, see above
				
			};
			
			struct ltcgi_output
			{
				ltcgi_input input; // input data that resulted in this output
				
				float intensity; // intensity output by LTC calculation
				float3 color; // color output by LTCGI colormode calculation
				
			};
			// LTCGI_structs.cginc END
			
			struct accumulator_struct
			{
				float3 diffuse;
				float3 specular;
			};
			
			void callback_diffuse(inout accumulator_struct acc, in ltcgi_output output);
			void callback_specular(inout accumulator_struct acc, in ltcgi_output output);
			
			#define LTCGI_V2_CUSTOM_INPUT accumulator_struct
			#define LTCGI_V2_DIFFUSE_CALLBACK callback_diffuse
			#define LTCGI_V2_SPECULAR_CALLBACK callback_specular
			
			// #include "../../ThirdParty/LTCGI/LTCGI.cginc"
			// LTCGI.cginc
			// #include "LTCGI_config.cginc"
			// LTCGI_config.cginc
			
			// Feel free to enable or disable (//) the options here.
			// They will apply to all LTCGI materials in the project.
			// Most of these can be changed in the LTCGI_Controller editor as well.
			
			/// No specular at all.
			//#define LTCGI_SPECULAR_OFF
			/// No diffuse at all.
			//#define LTCGI_DIFFUSE_OFF
			/// Disable the ability to toggle specular/diffuse on or off per screen.
			//#define LTCGI_TOGGLEABLE_SPEC_DIFF_OFF
			
			/// Only use LTC diffuse mode, never lightmapped diffuse.
			/// This disables lightmaps entirely.
			//#define LTCGI_ALWAYS_LTC_DIFFUSE
			
			/// Use bicubic filtering for LTCGI lightmap. Recommended on.
			#define LTCGI_BICUBIC_LIGHTMAP
			
			/// Lightmap values below this will be treated as black for specular/LTC diffuse.
			#define LTCGI_LIGHTMAP_CUTOFF 0.1
			/// Lightmap values above this (plus cutoff) will be treated as white.
			#define LTCGI_SPECULAR_LIGHTMAP_STEP 0.3
			
			/// Distance multiplier for calculating blur amount.
			/// Increase to make reflections blurrier faster as distance increases.
			#define LTCGI_UV_BLUR_DISTANCE 333
			
			/// Fall back to LTC diffuse (from LM diffuse) on objects that are not marked static.
			#define LTCGI_LTC_DIFFUSE_FALLBACK
			
			/// Approximation to ignore diffuse light for far away
			/// lights, increase MULT or disable if you notice artifacting
			#define LTCGI_DISTANCE_FADE_APPROX
			/// Distance at which diffuse from screens will be ignored.
			#define LTCGI_DISTANCE_FADE_APPROX_MULT 50
			
			// disabled editor from here on out
			///
			
			// Allow statically textured lights.
			// (deprecated: doesn't really cause any improvement when disabled...)
			#define LTCGI_STATIC_TEXTURES
			
			// keep in sync with LTCGI_Controller.cs
			#define MAX_SOURCES 16
			
			// set according to the LUT specified on CONTROLLER
			#define LUT_SIZE 256
			static float LUT_SCALE = (LUT_SIZE - 1.0) / LUT_SIZE;
			const float LUT_BIAS = 0.5 / LUT_SIZE;
			
			// will be set automatically if audiolink is available
			#ifdef POI_AUDIOLINK
			#define LTCGI_AUDIOLINK
			#endif
			
			// #ifdef LTCGI_AUDIOLINK
			// #ifndef AUDIOLINK_WIDTH
			// #ifndef AUDIOLINK_CGINC_INCLUDED
			// #include "Packages/com.llealloo.audiolink/Runtime/Shaders/AudioLink.cginc"
			// #define AUDIOLINK_CGINC_INCLUDED
			// #endif
			// #endif
			// #endif
			
			// Bake screen data into texture for better performance. Disables moveable screens.
			#define LTCGI_STATIC_UNIFORMS
			
			// Enable support for cylindrical screens.
			#define LTCGI_CYLINDER
			
			// Activate avatar mode, which overrides certain configs from above.
			#define LTCGI_AVATAR_MODE
			
			// LTCGI_config.cginc END
			
			#ifdef LTCGI_AVATAR_MODE
			#undef LTCGI_STATIC_UNIFORMS
			#undef LTCGI_BICUBIC_LIGHTMAP
			#define LTCGI_ALWAYS_LTC_DIFFUSE
			#endif
			
			#ifdef LTCGI_TOGGLEABLE_SPEC_DIFF_OFF
			#undef LTCGI_DIFFUSE_OFF
			#undef LTCGI_SPECULAR_OFF
			#endif
			
			#if defined(LTCGI_V2_CUSTOM_INPUT) || defined(LTCGI_V2_DIFFUSE_CALLBACK) || defined(LTCGI_V2_SPECULAR_CALLBACK)
			#define LTCGI_API_V2
			#endif
			
			// #include "LTCGI_uniform.cginc"
			// global sampler (trilinear)
			#ifndef LTCGI_SAMPLER
			SamplerState sampler_LTCGI_trilinear_clamp_sampler;
			#define LTCGI_SAMPLER sampler_LTCGI_trilinear_clamp_sampler
			#endif
			
			// LUTs
			#ifndef SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER
			uniform Texture2D<float4> _Udon_LTCGI_lut2;
			uniform Texture2D<float4> _Udon_LTCGI_lut1;
			#endif
			
			#ifndef SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER
			uniform Texture2D<float4> _Udon_LTCGI_static_uniforms;
			#endif
			
			#ifdef LTCGI_STATIC_UNIFORMS
			
			float4 _Udon_LTCGI_Vertices_0_get(uint i)
			{
				return _Udon_LTCGI_static_uniforms[uint2(0, i)];
			}
			float4 _Udon_LTCGI_Vertices_1_get(uint i)
			{
				return _Udon_LTCGI_static_uniforms[uint2(1, i)];
			}
			float4 _Udon_LTCGI_Vertices_2_get(uint i)
			{
				return _Udon_LTCGI_static_uniforms[uint2(2, i)];
			}
			float4 _Udon_LTCGI_Vertices_3_get(uint i)
			{
				return _Udon_LTCGI_static_uniforms[uint2(3, i)];
			}
			
			#else
			
			// vertices in object space; w component is UV (legacy)
			uniform float4 _Udon_LTCGI_Vertices_0[MAX_SOURCES];
			uniform float4 _Udon_LTCGI_Vertices_1[MAX_SOURCES];
			uniform float4 _Udon_LTCGI_Vertices_2[MAX_SOURCES];
			uniform float4 _Udon_LTCGI_Vertices_3[MAX_SOURCES];
			
			float4 _Udon_LTCGI_Vertices_0_get(uint i)
			{
				return _Udon_LTCGI_Vertices_0[i];
			}
			float4 _Udon_LTCGI_Vertices_1_get(uint i)
			{
				return _Udon_LTCGI_Vertices_1[i];
			}
			float4 _Udon_LTCGI_Vertices_2_get(uint i)
			{
				return _Udon_LTCGI_Vertices_2[i];
			}
			float4 _Udon_LTCGI_Vertices_3_get(uint i)
			{
				return _Udon_LTCGI_Vertices_3[i];
			}
			
			#endif
			
			// light source count, maximum is MAX_SOURCES
			uniform uint _Udon_LTCGI_ScreenCount;
			
			// per-renderer mask to select sources,
			// for max perf update _Udon_LTCGI_ScreenCount too
			uniform bool _Udon_LTCGI_Mask[MAX_SOURCES];
			
			// extra data per light source, layout:
			//  color.r   color.g   color.b   flags*
			// * b0=double-sided, b1=diffuse-from-lightmap, b2=specular, b3=diffuse,
			//   b4-b7=texture index (0=video, (n>0)=n-1)
			//   b8-b9=color mode
			//   b10-b11=lightmap channel (0=disabled, 1=r, 2=g, 3=b)
			//   b12=cylinder
			//   b13-14=audio link band
			//   b15=lightmap diffuse only
			// (color black = fully disabled)
			uniform float4 _Udon_LTCGI_ExtraData[MAX_SOURCES];
			
			ltcgi_flags ltcgi_parse_flags(uint val, bool noLmDiff)
			{
				ltcgi_flags ret = (ltcgi_flags)0;
				ret.doublesided = (val & 1) == 1;
				
				#ifdef LTCGI_ALWAYS_LTC_DIFFUSE
				ret.diffFromLm = false;
				#else
				ret.diffFromLm = !noLmDiff && (val & 2) == 2;
				#endif
				
				ret.diffuse = (val & 8) == 8;
				
				ret.specular = (val & 4) == 4;
				ret.texindex = (val & 0xf0) >> 4;
				ret.colormode = (val & 0x300) >> 8;
				
				#ifdef LTCGI_ALWAYS_LTC_DIFFUSE
				ret.lmch = 0;
				#else
				ret.lmch = (val & 0xC00) >> 10;
				#endif
				
				ret.cylinder = (val & (1 << 12)) == (1 << 12);
				
				#ifdef LTCGI_AUDIOLINK
				ret.alBand = (val & 0x6000) >> 13;
				#endif
				
				ret.lmdOnly = (val & (1 << 15)) == (1 << 15);
				
				return ret;
			}
			
			// video input
			#ifndef SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER
			uniform Texture2D<float4> _Udon_LTCGI_Texture_LOD0;
			uniform Texture2D<float4> _Udon_LTCGI_Texture_LOD1;
			uniform Texture2D<float4> _Udon_LTCGI_Texture_LOD2;
			uniform Texture2D<float4> _Udon_LTCGI_Texture_LOD3;
			#endif
			
			// static textures
			UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(_Udon_LTCGI_Texture_LOD0_arr);
			UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(_Udon_LTCGI_Texture_LOD1_arr);
			UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(_Udon_LTCGI_Texture_LOD2_arr);
			UNITY_DECLARE_TEX2DARRAY_NOSAMPLER(_Udon_LTCGI_Texture_LOD3_arr);
			
			// lightmap
			#ifndef SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER
			#ifndef LTCGI_ALWAYS_LTC_DIFFUSE
			uniform Texture2D<float4> _Udon_LTCGI_Lightmap;
			#endif
			#endif
			uniform float3 _Udon_LTCGI_LightmapMult;
			uniform float4 _Udon_LTCGI_LightmapST;
			
			// global toggle
			uniform float _Udon_LTCGI_GlobalEnable;
			
			// #include "LTCGI_uniform.cginc" END
			// #include "LTCGI_functions.cginc"
			
			/*
			LTC HELPERS
			*/
			
			float3 LTCGI_IntegrateEdge(float3 v1, float3 v2)
			{
				float x = dot(v1, v2);
				float y = abs(x);
				
				float a = 0.8543985 + (0.4965155 + 0.0145206 * y) * y;
				float b = 3.4175940 + (4.1616724 + y) * y;
				float v = a / b;
				float theta_sintheta = (x > 0.0) ? v : 0.5 * rsqrt(max(1.0 - x * x, 1e-7)) - v;
				
				return cross(v1, v2) * theta_sintheta;
			}
			
			void LTCGI_ClipQuadToHorizon(inout float3 L[5], out int n)
			{
				// detect clipping config
				uint config = 0;
				if (L[0].z > 0.0) config += 1;
				if (L[1].z > 0.0) config += 2;
				if (L[2].z > 0.0) config += 4;
				if (L[3].z > 0.0) config += 8;
				
				n = 0;
				
				// This [forcecase] only works when the cases are ordered in a specific manner.
				// It gives like 10%-20% performance boost, so *make sure to leave it on*!
				// If it breaks however, see if [branch] fixes it, and if it does, start
				// reordering cases at random until it works again.
				// It seems the compiler somehow optimizes away anything but setting 'n' in
				// some orderings, including the ascending and descending ones.
				// I wish I was joking.
				[forcecase]
				switch(config)
				{
					case 13: // V1 V3 V4 clip V2 <- tl;dr: this fecker has to be first or shader go boom
					n = 5;
					L[4] = L[3];
					L[3] = L[2];
					L[2] = -L[1].z * L[2] + L[2].z * L[1];
					L[1] = -L[1].z * L[0] + L[0].z * L[1];
					break;
					case 15: // V1 V2 V3 V4 - most common
					n = 4;
					break;
					case 9: // V1 V4 clip V2 V3
					n = 4;
					L[1] = -L[1].z * L[0] + L[0].z * L[1];
					L[2] = -L[2].z * L[3] + L[3].z * L[2];
					break;
					case 0: // clip all
					break;
					case 1: // V1 clip V2 V3 V4
					n = 3;
					L[1] = -L[1].z * L[0] + L[0].z * L[1];
					L[2] = -L[3].z * L[0] + L[0].z * L[3];
					L[3] = L[0];
					break;
					case 2: // V2 clip V1 V3 V4
					n = 3;
					L[0] = -L[0].z * L[1] + L[1].z * L[0];
					L[2] = -L[2].z * L[1] + L[1].z * L[2];
					L[3] = L[0];
					break;
					case 3: // V1 V2 clip V3 V4
					n = 4;
					L[2] = -L[2].z * L[1] + L[1].z * L[2];
					L[3] = -L[3].z * L[0] + L[0].z * L[3];
					break;
					case 4: // V3 clip V1 V2 V4
					n = 3;
					L[0] = -L[3].z * L[2] + L[2].z * L[3];
					L[1] = -L[1].z * L[2] + L[2].z * L[1];
					L[3] = L[0];
					break;
					case 5: // V1 V3 clip V2 V4) impossible
					break;
					case 6: // V2 V3 clip V1 V4
					n = 4;
					L[0] = -L[0].z * L[1] + L[1].z * L[0];
					L[3] = -L[3].z * L[2] + L[2].z * L[3];
					break;
					case 7: // V1 V2 V3 clip V4
					n = 5;
					L[4] = -L[3].z * L[0] + L[0].z * L[3];
					L[3] = -L[3].z * L[2] + L[2].z * L[3];
					break;
					case 8: // V4 clip V1 V2 V3
					n = 3;
					L[0] = -L[0].z * L[3] + L[3].z * L[0];
					L[1] = -L[2].z * L[3] + L[3].z * L[2];
					L[2] = L[3];
					break;
					case 10: // V2 V4 clip V1 V3) impossible
					break;
					case 11: // V1 V2 V4 clip V3
					n = 5;
					L[4] = L[3];
					L[3] = -L[2].z * L[3] + L[3].z * L[2];
					L[2] = -L[2].z * L[1] + L[1].z * L[2];
					break;
					case 12: // V3 V4 clip V1 V2
					n = 4;
					L[1] = -L[1].z * L[2] + L[2].z * L[1];
					L[0] = -L[0].z * L[3] + L[3].z * L[0];
					break;
					case 14: // V2 V3 V4 clip V1
					n = 5;
					L[4] = -L[0].z * L[3] + L[3].z * L[0];
					L[0] = -L[0].z * L[1] + L[1].z * L[0];
					break;
				}
				
				// inlining these branches *unconditionally* breaks the [forcecase] above
				// ...yeah I know
				if (n == 3)
				L[3] = L[0];
				if (n == 4)
				L[4] = L[0];
			}
			
			/*
			TEXTURE SAMPLING
			*/
			
			float2 LTCGI_inset_uv(float2 uv)
			{
				return uv * 0.75 + float2(0.125, 0.125);
			}
			
			half3 premul_alpha(half4 i)
			{
				return i.rgb * i.a;
			}
			
			void LTCGI_sample(float2 uv, uint lod, uint idx, float blend, out float3 result)
			{
				result = 0;
				#ifndef LTCGI_STATIC_TEXTURES
				idx = 0; // optimize away the branches below
				#endif
				
				[branch]
				if (lod == 0)
				{
					// if we're outside of the 0-1 UV space we must sample a prefiltered texture
					[branch]
					if (any(saturate(abs(uv - 0.5) - 0.5)))
					{
						lod = 1;
					}
					else
					{
						// LOD0 is the original texture itself, so not prefiltered, but we can
						// approximate it a bit with trilinear lod
						float lod = (1 - blend) * 1.5;
						[branch]
						if (idx == 0)
						{
							#ifndef SHADER_TARGET_SURFACE_ANALYSIS
							result = premul_alpha(_Udon_LTCGI_Texture_LOD0.SampleLevel(LTCGI_SAMPLER, uv, lod));
							return;
							#else
							result = 0;
							return;
							#endif
						}
						else
						{
							result = premul_alpha(UNITY_SAMPLE_TEX2DARRAY_SAMPLER_LOD(
							_Udon_LTCGI_Texture_LOD0_arr,
							_LTCGI_trilinear_clamp_sampler,
							float3(uv, idx - 1),
							lod
							));
							return;
						}
					}
				}
				
				float2 ruv = LTCGI_inset_uv(uv);
				
				[branch]
				if (idx == 0)
				{
					#ifndef SHADER_TARGET_SURFACE_ANALYSIS
					switch(lod)
					{
						case 1:
						result = _Udon_LTCGI_Texture_LOD1.SampleLevel(LTCGI_SAMPLER, ruv, 0).rgb;
						return;
						case 2:
						result = _Udon_LTCGI_Texture_LOD2.SampleLevel(LTCGI_SAMPLER, ruv, 0).rgb;
						return;
						default:
						result = _Udon_LTCGI_Texture_LOD3.SampleLevel(LTCGI_SAMPLER, ruv, blend * 0.72).rgb;
						return;
					}
					#else
					result = 0;
					return;
					#endif
				}
				else
				{
					[forcecase]
					switch(lod)
					{
						case 1:
						result = UNITY_SAMPLE_TEX2DARRAY_SAMPLER_LOD(
						_Udon_LTCGI_Texture_LOD1_arr,
						_LTCGI_trilinear_clamp_sampler,
						float3(ruv, idx - 1),
						0
						).rgb;
						return;
						case 2:
						result = UNITY_SAMPLE_TEX2DARRAY_SAMPLER_LOD(
						_Udon_LTCGI_Texture_LOD2_arr,
						_LTCGI_trilinear_clamp_sampler,
						float3(ruv, idx - 1),
						0
						).rgb;
						return;
						default:
						result = UNITY_SAMPLE_TEX2DARRAY_SAMPLER_LOD(
						_Udon_LTCGI_Texture_LOD3_arr,
						_LTCGI_trilinear_clamp_sampler,
						float3(ruv, idx - 1),
						blend
						).rgb;
						return;
					}
				}
			}
			
			void LTCGI_trilinear(float2 uv, float d, uint idx, out float3 result)
			{
				uint low = (uint)d;
				uint high = low + 1;
				
				// DEBUG: colorize d/lod
				//return float3(low == 0, low == 1, low == 2);
				
				if (low >= 3)
				{
					LTCGI_sample(uv, 3, idx, d - 3, result);
				}
				else
				{
					float amount = saturate(high - d);
					float3 low_sample;
					LTCGI_sample(uv, low, idx, amount, low_sample);
					float3 high_sample;
					LTCGI_sample(uv, high, idx, 0, high_sample);
					
					result = lerp(high_sample, low_sample, amount);
				}
			}
			
			/*
			GENERIC HELPERS
			*/
			
			bool LTCGI_tri_ray(float3 orig, float3 dir, float3 v0, float3 v1, float3 v2, out float2 bary)
			{
				float3 v0v1 = v1 - v0;
				float3 v0v2 = v2 - v0;
				float3 pvec = cross(dir, v0v2);
				float det = dot(v0v1, pvec);
				float invDet = 1 / det;
				
				float3 tvec = orig - v0;
				bary.x = dot(tvec, pvec) * invDet;
				
				float3 qvec = cross(tvec, v0v1);
				bary.y = dot(dir, qvec) * invDet;
				
				// return false when other triangle of quad should be sampled,
				// i.e. we went over the diagonal line
				return bary.x >= 0;
			}
			
			float2 LTCGI_rotateVector(float2 x, float angle)
			{
				float c = cos(angle);
				float s = sin(angle);
				return mul(float2x2(c, s, -s, c), x);
			}
			
			float2 LTCGI_calculateUV(uint i, ltcgi_flags flags, float3 L[5], bool isTri, float2 uvStart, float2 uvEnd, out float3 ray)
			{
				// calculate perpendicular vector to plane defined by area light
				float3 E1 = L[1] - L[0];
				float3 E2 = L[3] - L[0];
				ray = cross(E1, E2);
				
				// raycast it against the two triangles formed by the quad
				float2 bary;
				bool hit0 = LTCGI_tri_ray(0, ray, L[0], L[2], L[3], bary) || isTri;
				if (!hit0)
				{
					LTCGI_tri_ray(0, ray, L[0], L[1], L[2], bary);
				}
				
				float2 uvs[4];
				#ifdef LTCGI_CYLINDER
				if (flags.cylinder)
				{
					uvs[0] = uvStart;
					uvs[1] = float2(uvStart.x, uvEnd.y);
					uvs[2] = float2(uvEnd.x, uvStart.y);
					uvs[3] = uvEnd;
				}
				else
				#endif
				{
					uvs[0] = uvStart; // == _Udon_LTCGI_static_uniforms[uint2(4, i)].xy;
					uvs[1] = _Udon_LTCGI_static_uniforms[uint2(4, i)].zw;
					uvs[2] = _Udon_LTCGI_static_uniforms[uint2(5, i)].xy;
					uvs[3] = uvEnd; // == _Udon_LTCGI_static_uniforms[uint2(5, i)].zw;
					
				}
				
				// map barycentric triangle coordinates to the according object UVs
				float3 bary3 = float3(bary, 1 - bary.x - bary.y);
				float2 uv = uvs[1 + hit0 * 2] * bary3.x + uvs[3 - hit0] * bary3.y + uvs[0] * bary3.z;
				
				return uv;
			}
			
			/*
			EXPERIMENTAL: CYLINDER HELPER
			*/
			
			void LTCGI_GetLw(uint i, ltcgi_flags flags, float3 worldPos, out float3 Lw[4], out float2 uvStart, out float2 uvEnd, out bool isTri)
			{
				bool cylinder = false;
				#ifdef LTCGI_CYLINDER
				// statically optimize out branch below in case disabled
				cylinder = flags.cylinder;
				#endif
				
				float4 v0 = _Udon_LTCGI_Vertices_0_get(i);
				float4 v1 = _Udon_LTCGI_Vertices_1_get(i);
				float4 v2 = _Udon_LTCGI_Vertices_2_get(i);
				float4 v3 = _Udon_LTCGI_Vertices_3_get(i);
				
				[branch]
				if (cylinder)
				{
					// construct data according to worldPos to create aligned
					// rectangle tangent to the cylinder
					
					float3 in_base = v0.xyz;
					float in_height = v0.w;
					float in_radius = v1.w;
					float in_size = v2.w;
					float in_angle = v3.w;
					
					// get angle between 2D unit plane and vector pointing from cylinder to shade point
					float2 towardsCylinder = LTCGI_rotateVector((in_base - worldPos).xz, -in_angle);
					float angle = atan2(towardsCylinder.x, towardsCylinder.y);
					// clamp angle to size parameter, i.e. "width" of lit surface area
					float angleClamped = clamp(angle, -in_size, in_size) + in_angle;
					// construct vector that *most* faces shade point
					float2 facing = float2(sin(angleClamped), cos(angleClamped));
					// tangent of rectangular screen on cylinder surface used for calculating lighting for shade point
					float2 tangent = float2(facing.y, -facing.x);
					float2 onCylinderFacing = facing * in_radius;
					
					// clip ends, approximately
					float rclip = saturate(lerp(1, 0, (angleClamped - in_angle) - (in_size - UNITY_HALF_PI * 0.5f)));
					float lclip = saturate(lerp(1, 0, - (angleClamped - in_angle) - (in_size - UNITY_HALF_PI * 0.5f)));
					
					float2 p1 = in_base.xz - onCylinderFacing + tangent * in_radius * lclip;
					float2 p2 = in_base.xz - onCylinderFacing - tangent * in_radius * rclip;
					
					Lw[0] = float3(p1.x, in_base.y, p1.y) - worldPos;
					Lw[1] = float3(p1.x, in_base.y + in_height, p1.y) - worldPos;
					Lw[2] = float3(p2.x, in_base.y, p2.y) - worldPos;
					Lw[3] = float3(p2.x, in_base.y + in_height, p2.y) - worldPos;
					
					isTri = false;
					
					// UV depends on "viewing" angle of the shade point towards the cylinder
					float2 viewDir = normalize((in_base - worldPos).xz);
					// forwardAngle == atan2(cos(in_angle), sin(in_angle)); but only negative
					float forwardAngle = -in_angle + UNITY_HALF_PI;
					// offset from center of screen forward to the side ends, positive goes left/ccw fpv top,
					// sine to account for the fact we're rotating around a cylinder which has depth
					float viewAngle = forwardAngle - atan2(viewDir.y, viewDir.x);
					// prevent rollover, since we need to clamp we must stay withing [-pi, pi]
					if (viewAngle < - UNITY_PI)
					viewAngle += UNITY_TWO_PI;
					if (viewAngle > UNITY_PI)
					viewAngle -= UNITY_TWO_PI;
					viewAngle = clamp(viewAngle * 0.5f, -in_size, in_size);
					viewAngle = sin(viewAngle);
					// full view UVs, but shifted left/right depending on view angle
					uvStart = float2(1 - saturate(viewAngle), 0);
					uvEnd = float2(1 - saturate(viewAngle + 1), 1);
				}
				else
				{
					// use passed in data, offset around worldPos
					Lw[0] = v0.xyz - worldPos;
					Lw[1] = v1.xyz - worldPos;
					Lw[2] = v2.xyz - worldPos;
					Lw[3] = v3.xyz - worldPos;
					#ifndef SHADER_TARGET_SURFACE_ANALYSIS
					uvStart = _Udon_LTCGI_static_uniforms[uint2(4, i)].xy;
					uvEnd = _Udon_LTCGI_static_uniforms[uint2(5, i)].zw;
					#else
					uvStart = float2(0, 0);
					uvEnd = float2(1, 1);
					#endif
					
					// we only detect triangles for "blender" import configuration, as those are the only
					// ones that can actually be triangles (I think?)
					isTri = /*distance(Lw[2], Lw[3]) < 0.001 || */distance(Lw[1], Lw[3]) < 0.001;
				}
			}
			
			/*
			
			Parts of the code in this file are adapted from the example code found here:
			
			https://github.com/selfshadow/ltc_code
			
			Modifications by _pi_ (@pimaker on GitHub), licensed under the terms of the
			MIT license as far as applicable.
			
			Original copyright notice:
			
			Copyright (c) 2017, Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt.
			All rights reserved.
			
			Redistribution and use in source and binary forms, with or without
			modification, are permitted provided that the following conditions are met:
			
			* If you use (or adapt) the source code in your own work, please include a
			reference to the paper:
			
			Real-Time Polygonal-Light Shading with Linearly Transformed Cosines.
			Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt.
			ACM Transactions on Graphics (Proceedings of ACM SIGGRAPH 2016) 35(4), 2016.
			Project page: https://eheitzresearch.wordpress.com/415-2/
			
			* Redistributions of source code must retain the above copyright notice, this
			list of conditions and the following disclaimer.
			
			* Redistributions in binary form must reproduce the above copyright notice,
			this list of conditions and the following disclaimer in the documentation
			and/or other materials provided with the distribution.
			
			THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
			AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
			IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
			DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
			FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
			DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
			SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
			CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
			OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
			OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
			
			*/
			// #include "LTCGI_functions.cginc" END
			// #include "LTCGI_shadowmap.cginc"
			
			// Adapted from: https://gitlab.com/s-ilent/filamented
			// Licensed under the terms of the Apache License 2.0
			// Full text: https://gitlab.com/s-ilent/filamented/-/blob/master/LICENSE
			//
			// Conforming to the terms of the above license, this file is redistributed
			// under the terms of the MIT license as part of the LTCGI shader package,
			// provided this notice is kept.
			
			#ifndef SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER
			
			float4 LTCGI_cubic(float v)
			{
				float4 n = float4(1.0, 2.0, 3.0, 4.0) - v;
				float4 s = n * n * n;
				float x = s.x;
				float y = s.y - 4.0 * s.x;
				float z = s.z - 4.0 * s.y + 6.0 * s.x;
				float w = 6.0 - x - y - z;
				return float4(x, y, z, w);
			}
			
			// Unity's SampleTexture2DBicubic doesn't exist in 2018, which is our target here.
			// So this is a similar function with tweaks to have similar semantics.
			
			float4 LTCGI_SampleTexture2DBicubicFilter(Texture2D tex, SamplerState smp, float2 coord, float4 texSize)
			{
				coord = coord * texSize.xy - 0.5;
				float fx = frac(coord.x);
				float fy = frac(coord.y);
				coord.x -= fx;
				coord.y -= fy;
				
				float4 xcubic = LTCGI_cubic(fx);
				float4 ycubic = LTCGI_cubic(fy);
				
				float4 c = float4(coord.x - 0.5, coord.x + 1.5, coord.y - 0.5, coord.y + 1.5);
				float4 s = float4(xcubic.x + xcubic.y, xcubic.z + xcubic.w, ycubic.x + ycubic.y, ycubic.z + ycubic.w);
				float4 offset = c + float4(xcubic.y, xcubic.w, ycubic.y, ycubic.w) / s;
				
				float4 sample0 = tex.Sample(smp, float2(offset.x, offset.z) * texSize.zw);
				float4 sample1 = tex.Sample(smp, float2(offset.y, offset.z) * texSize.zw);
				float4 sample2 = tex.Sample(smp, float2(offset.x, offset.w) * texSize.zw);
				float4 sample3 = tex.Sample(smp, float2(offset.y, offset.w) * texSize.zw);
				
				float sx = s.x / (s.x + s.y);
				float sy = s.z / (s.z + s.w);
				
				return lerp(
				lerp(sample3, sample2, sx),
				lerp(sample1, sample0, sx), sy);
			}
			
			float4 LTCGI_SampleShadowmap(float2 lmuv)
			{
				#ifdef LTCGI_ALWAYS_LTC_DIFFUSE
				return 1;
				#else
				lmuv = lmuv * _Udon_LTCGI_LightmapST.xy + _Udon_LTCGI_LightmapST.zw;
				
				#ifdef LTCGI_BICUBIC_LIGHTMAP
				float width, height;
				_Udon_LTCGI_Lightmap.GetDimensions(width, height);
				
				float4 _Udon_LTCGI_Lightmap_TexelSize = float4(width, height, 1.0 / width, 1.0 / height);
				
				return LTCGI_SampleTexture2DBicubicFilter(
				_Udon_LTCGI_Lightmap, LTCGI_SAMPLER,
				lmuv, _Udon_LTCGI_Lightmap_TexelSize
				);
				#else
				return _Udon_LTCGI_Lightmap.Sample(LTCGI_SAMPLER, lmuv);
				#endif
				#endif
			}
			
			#else
			// surface shader analysis stub
			float4 LTCGI_SampleShadowmap(float2 lmuv)
			{
				return 1;
			}
			#endif
			
			// #include "LTCGI_shadowmap.cginc" END
			
			#ifdef SHADER_TARGET_SURFACE_ANALYSIS
			#define const
			#endif
			
			// Main function - this calculates the approximated model for one pixel and one light
			void LTCGI_Evaluate(ltcgi_input input, float3 worldNorm, float3 viewDir, float3x3 Minv, float roughness, const bool diffuse, out ltcgi_output output)
			{
				output.input = input;
				output.color = input.rawColor; // copy for colormode static
				output.intensity = 0;
				
				// diffuse distance fade
				#ifdef LTCGI_DISTANCE_FADE_APPROX
				if (diffuse) // static branch, specular does not directly fade with distance
				
				{
					if (!input.flags.lmdOnly)
					{
						// very approximate lol
						float3 ctr = (input.Lw[0] + input.Lw[1]) / 2;
						float dist = length(ctr);
						if (dist > LTCGI_DISTANCE_FADE_APPROX_MULT)
						{
							return;
						}
					}
				}
				#endif
				
				#define RET1_IF_LMDIFF [branch] if (/*const*/ diffuse && input.flags.diffFromLm) \
				{ \
					output.intensity = 1.0f; return; \
				}
				
				if (input.flags.colormode == LTCGI_COLORMODE_SINGLEUV)
				{
					float2 uv = input.uvStart;
					if (uv.x < 0) uv.xy = uv.yx;
					// TODO: make more configurable?
					#ifdef LTCGI_VISUALIZE_SAMPLE_UV
					output.color = float3(uv.xy, 0);
					#else
					float3 sampled;
					LTCGI_sample(LTCGI_inset_uv(uv), 1, input.flags.texindex, 0, sampled);
					output.color *= sampled;
					#endif
					
					RET1_IF_LMDIFF
				}
				
				#ifdef LTCGI_AUDIOLINK
				if (input.flags.colormode == LTCGI_COLORMODE_AUDIOLINK)
				{
					float al = AudioLinkData(ALPASS_AUDIOLINK + uint2(0, input.flags.alBand)).r;
					output.color *= al;
					
					RET1_IF_LMDIFF
				}
				#endif
				
				// create LTC polygon array
				// note the order of source verts (keyword: winding order)
				float3 L[5];
				L[0] = mul(Minv, input.Lw[0]);
				L[1] = mul(Minv, input.Lw[1]);
				L[2] = input.isTri ? L[1] : mul(Minv, input.Lw[3]);
				L[3] = mul(Minv, input.Lw[2]);
				L[4] = 0;
				
				// get texture coords (before clipping!)
				[branch]
				if (input.flags.colormode == LTCGI_COLORMODE_TEXTURE)
				{
					float3 RN;
					float2 uv = LTCGI_calculateUV(input.i, input.flags, L, input.isTri, input.uvStart, input.uvEnd, RN);
					float planeAreaSquared = dot(RN, RN);
					float planeDistxPlaneArea = dot(RN, L[0]);
					
					float3 sampled;
					[branch]
					if (diffuse)
					{
						// static branch
						float3 sampled1;
						LTCGI_sample(uv, 3, input.flags.texindex, 10, sampled1);
						float3 sampled2;
						LTCGI_sample(uv, 3, input.flags.texindex, 100, sampled2);
						sampled =
						sampled1 * 0.75 +
						sampled2 * 0.25;
					}
					else
					{
						float d = abs(planeDistxPlaneArea) / planeAreaSquared;
						d *= LTCGI_UV_BLUR_DISTANCE;
						d = log(d) / log(3.0);
						
						// a rough material must never show a perfect reflection,
						// since our LOD0 texture is not prefiltered (and thus cannot
						// depict any blur correctly) - without this there is artifacting
						// on the border of LOD0 and LOD1
						d = clamp(d, saturate(roughness * 5.75), 1000);
						
						LTCGI_trilinear(uv, d, input.flags.texindex, sampled);
					}
					
					// colorize output
					output.color *= sampled;
				}
				
				RET1_IF_LMDIFF
				#undef RET1_IF_LMDIFF
				
				int n;
				LTCGI_ClipQuadToHorizon(L, n);
				
				// early out if everything was clipped below horizon
				if (n == 0)
				return;
				
				L[0] = normalize(L[0]);
				L[1] = normalize(L[1]);
				L[2] = normalize(L[2]);
				L[3] = normalize(L[3]);
				L[4] = normalize(L[4]);
				
				// integrate (and pray that constant folding works well)
				float sum = 0;
				[unroll(5)]
				for (uint v = 0; v < max(3, (uint)n); v++)
				{
					float3 a = L[v];
					float3 b = L[(v + 1) % 5];
					sum += LTCGI_IntegrateEdge(a, b).z;
				}
				
				// doublesided is accounted for with optimization at the start, so return abs
				output.intensity = abs(sum);
				return;
			}
			
			// Calculate light contribution for all lights,
			// call this from your shader and use the "diffuse" and "specular" outputs
			// lmuv is the raw lightmap UV coordinate (e.g. UV1)
			void LTCGI_Contribution(
			#ifdef LTCGI_API_V2
			inout LTCGI_V2_CUSTOM_INPUT data,
			#endif
			float3 worldPos, float3 worldNorm, float3 viewDir, float roughness, float2 lmuv
			#ifndef LTCGI_API_V2
			, inout half3 diffuse, inout half3 specular, out float totalSpecularIntensity, out float totalDiffuseIntensity
			#endif
			)
			{
				#ifndef LTCGI_API_V2
				totalSpecularIntensity = 0;
				#endif
				if (_Udon_LTCGI_GlobalEnable == 0.0f)
				{
					return;
				}
				
				// sample lookup tables
				float theta = acos(dot(worldNorm, viewDir));
				float2 uv = float2(roughness, theta / (0.5 * UNITY_PI));
				uv = uv * LUT_SCALE + LUT_BIAS;
				
				#ifndef UNITY_UV_STARTS_AT_TOP
				uv.y = 1 - uv.y;
				#endif
				
				// calculate LTCGI custom lightmap UV and sample
				float3 lms = LTCGI_SampleShadowmap(lmuv);
				
				#ifndef SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER
				// sample BDRF approximation from lookup texture
				float4 t = _Udon_LTCGI_lut1.SampleLevel(LTCGI_SAMPLER, uv, 0);
				#endif
				float3x3 Minv = float3x3(
				float3(1, 0, t.w),
				float3(0, t.z, 0),
				float3(t.y, 0, t.x)
				);
				
				// construct orthonormal basis around N
				float3 T1, T2;
				T1 = normalize(viewDir - worldNorm * dot(viewDir, worldNorm));
				T2 = cross(worldNorm, T1);
				
				// for diffuse lighting we assume the identity matrix as BDRF, so the
				// LTC approximation is directly equivalent to the orthonormal rotation matrix
				float3x3 identityBrdf = float3x3(float3(T1), float3(T2), float3(worldNorm));
				// rotate area light in (T1, T2, N) basis for actual BRDF matrix as well
				Minv = mul(Minv, identityBrdf);
				
				// specular brightness
				#ifndef LTCGI_SPECULAR_OFF
				#ifndef SHADER_TARGET_SURFACE_ANALYSIS_MOJOSHADER
				float spec_amp = _Udon_LTCGI_lut2.SampleLevel(LTCGI_SAMPLER, uv, 0).x;
				#endif
				#endif
				
				bool noLm = false;
				#ifdef LTCGI_LTC_DIFFUSE_FALLBACK
				#ifndef LTCGI_ALWAYS_LTC_DIFFUSE
				#ifndef SHADER_TARGET_SURFACE_ANALYSIS
				float2 lmSize;
				_Udon_LTCGI_Lightmap.GetDimensions(lmSize.x, lmSize.y);
				noLm = lmSize.x == 1;
				#endif
				#endif
				#endif
				#ifdef LTCGI_ALWAYS_LTC_DIFFUSE
				noLm = true;
				#endif
				
				// loop through all lights and add them to the output
				uint count = min(_Udon_LTCGI_ScreenCount, MAX_SOURCES);
				[loop]
				for (uint i = 0; i < count; i++)
				{
					// skip masked and black lights
					if (_Udon_LTCGI_Mask[i]) continue;
					float4 extra = _Udon_LTCGI_ExtraData[i];
					float3 color = extra.rgb;
					if (!any(color)) continue;
					
					ltcgi_flags flags = ltcgi_parse_flags(asuint(extra.w), noLm);
					
					#ifdef LTCGI_ALWAYS_LTC_DIFFUSE
					// can't honor a lightmap-only light in this mode
					if (flags.lmdOnly) continue;
					#endif
					
					#ifdef LTCGI_TOGGLEABLE_SPEC_DIFF_OFF
					// compile branches below away statically
					flags.diffuse = flags.specular = true;
					#endif
					
					// calculate (shifted) world space positions
					float3 Lw[4];
					float2 uvStart = (float2)0, uvEnd = (float2)0;
					bool isTri = false;
					if (flags.lmdOnly)
					{
						Lw[0] = Lw[1] = Lw[2] = Lw[3] = (float3)0;
					}
					else
					{
						LTCGI_GetLw(i, flags, worldPos, Lw, uvStart, uvEnd, isTri);
					}
					
					// skip single-sided lights that face the other way
					float3 screenNorm = cross(Lw[1] - Lw[0], Lw[2] - Lw[0]);
					if (!flags.doublesided)
					{
						if (dot(screenNorm, Lw[0]) < 0)
						continue;
					}
					
					float lm = 1;
					if (flags.lmch)
					{
						lm = lms[flags.lmch - 1];
						if (lm < 0.001) continue;
					}
					
					ltcgi_input input;
					input.i = i;
					input.Lw = Lw;
					input.isTri = isTri;
					input.uvStart = uvStart;
					input.uvEnd = uvEnd;
					input.rawColor = color;
					input.flags = flags;
					input.screenNormal = screenNorm;
					
					// diffuse lighting
					#ifndef LTCGI_DIFFUSE_OFF
					[branch]
					if (flags.diffuse)
					{
						float lmd = lm;
						if (flags.lmch)
						{
							if (flags.diffFromLm)
							lmd *= _Udon_LTCGI_LightmapMult[flags.lmch - 1];
							else
							lmd = smoothstep(0.0, LTCGI_SPECULAR_LIGHTMAP_STEP, saturate(lm - LTCGI_LIGHTMAP_CUTOFF));
						}
						ltcgi_output diff;
						LTCGI_Evaluate(input, worldNorm, viewDir, identityBrdf, roughness, true, diff);
						diff.intensity *= lmd;
						
						#ifdef LTCGI_API_V2
						LTCGI_V2_DIFFUSE_CALLBACK(data, diff);
						#else
						// simply accumulate all lights
						diffuse += (diff.intensity * diff.color);
						totalDiffuseIntensity += diff.intensity;
						#endif
					}
					#endif
					
					// specular lighting
					#ifndef LTCGI_SPECULAR_OFF
					[branch]
					if (flags.specular)
					{
						ltcgi_output spec;
						LTCGI_Evaluate(input, worldNorm, viewDir, Minv, roughness, false, spec);
						spec.intensity *= spec_amp * smoothstep(0.0, LTCGI_SPECULAR_LIGHTMAP_STEP, saturate(lm - LTCGI_LIGHTMAP_CUTOFF));
						
						#ifdef LTCGI_API_V2
						LTCGI_V2_SPECULAR_CALLBACK(data, spec);
						#else
						// simply accumulate all lights
						specular += spec.intensity * spec.color;
						totalSpecularIntensity += spec.intensity;
						#endif
					}
					#endif
				}
			}
			
			// COMPATIBILITY FALLBACKS
			
			#ifndef LTCGI_API_V2
			
			void LTCGI_Contribution(
			float3 worldPos, float3 worldNorm, float3 viewDir, float roughness, float2 lmuv, inout half3 diffuse
			)
			{
				half3 _u1;
				float _u2, _u3;
				LTCGI_Contribution(worldPos, worldNorm, viewDir, roughness, lmuv, diffuse, _u1, _u2, _u3);
			}
			
			void LTCGI_Contribution(
			float3 worldPos, float3 worldNorm, float3 viewDir, float roughness, float2 lmuv, inout half3 diffuse, inout half3 specular
			)
			{
				float _u1, _u2;
				LTCGI_Contribution(worldPos, worldNorm, viewDir, roughness, lmuv, diffuse, specular, _u1, _u2);
			}
			
			void LTCGI_Contribution(
			float3 worldPos, float3 worldNorm, float3 viewDir, float roughness, float2 lmuv, inout half3 diffuse, inout half3 specular, out float totalSpecularIntensity
			)
			{
				float _u1;
				LTCGI_Contribution(worldPos, worldNorm, viewDir, roughness, lmuv, diffuse, specular, totalSpecularIntensity, _u1);
			}
			
			#endif
			
			/*
			
			Parts of the code in this file are adapted from the example code found here:
			
			https://github.com/selfshadow/ltc_code
			
			Modifications by _pi_ (@pimaker on GitHub), licensed under the terms of the
			MIT license as far as applicable.
			
			Original copyright notice:
			
			Copyright (c) 2017, Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt.
			All rights reserved.
			
			Redistribution and use in source and binary forms, with or without
			modification, are permitted provided that the following conditions are met:
			
			* If you use (or adapt) the source code in your own work, please include a
			reference to the paper:
			
			Real-Time Polygonal-Light Shading with Linearly Transformed Cosines.
			Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt.
			ACM Transactions on Graphics (Proceedings of ACM SIGGRAPH 2016) 35(4), 2016.
			Project page: https://eheitzresearch.wordpress.com/415-2/
			
			* Redistributions of source code must retain the above copyright notice, this
			list of conditions and the following disclaimer.
			
			* Redistributions in binary form must reproduce the above copyright notice,
			this list of conditions and the following disclaimer in the documentation
			and/or other materials provided with the distribution.
			
			THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
			AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
			IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
			DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
			FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
			DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
			SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
			CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
			OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
			OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
			
			*/
			
			// LTCGI.cginc END
			
			void callback_diffuse(inout accumulator_struct acc, in ltcgi_output output)
			{
				// you can do whatever here! check out the ltcgi_output struct in
				// "LTCGI_structs.cginc" to see what data you have available
				acc.diffuse += output.intensity * output.color;
			}
			void callback_specular(inout accumulator_struct acc, in ltcgi_output output)
			{
				// same here, this example one is pretty boring though.
				// you could accumulate intensity separately for example,
				// to emulate total{Specular,Diffuse}Intensity from APIv1
				acc.specular += output.intensity * output.color;
			}
			
			#endif
			//endex
			
			//ifex _ShadingEnabled==0
			#ifdef VIGNETTE_MASKED
			
			#ifdef _LIGHTINGMODE_CLOTH
			float V_SmithGGXCorrelated(float roughness, float NoV, float NoL)
			{
				// Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"
				float a2 = roughness * roughness;
				// TODO: lambdaV can be pre-computed for all the lights, it should be moved out of this function
				float lambdaV = NoL * sqrt((NoV - a2 * NoV) * NoV + a2);
				float lambdaL = NoV * sqrt((NoL - a2 * NoL) * NoL + a2);
				float v = 0.5 / (lambdaV + lambdaL);
				// a2=0 => v = 1 / 4*NoL*NoV   => min=1/4, max=+inf
				// a2=1 => v = 1 / 2*(NoL+NoV) => min=1/4, max=+inf
				// clamp to the maximum value representable in mediump
				return v;
			}
			
			float D_GGX(float roughness, float NoH)
			{
				// Walter et al. 2007, "Microfacet Models for Refraction through Rough Surfaces"
				
				// In mediump, there are two problems computing 1.0 - NoH^2
				// 1) 1.0 - NoH^2 suffers floating point cancellation when NoH^2 is close to 1 (highlights)
				// 2) NoH doesn't have enough precision around 1.0
				// Both problem can be fixed by computing 1-NoH^2 in highp and providing NoH in highp as well
				
				// However, we can do better using Lagrange's identity:
				//      ||a x b||^2 = ||a||^2 ||b||^2 - (a . b)^2
				// since N and H are unit vectors: ||N x H||^2 = 1.0 - NoH^2
				// This computes 1.0 - NoH^2 directly (which is close to zero in the highlights and has
				// enough precision).
				// Overall this yields better performance, keeping all computations in mediump
				float oneMinusNoHSquared = 1.0 - NoH * NoH;
				
				float a = NoH * roughness;
				float k = roughness / (oneMinusNoHSquared + a * a);
				float d = k * k * (1.0 / UNITY_PI);
				return d;
			}
			
			// https://github.com/google/filament/blob/main/shaders/src/brdf.fs#L94-L100
			float D_Charlie(float roughness, float NoH)
			{
				// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF"
				float invAlpha = 1.0 / roughness;
				float cos2h = NoH * NoH;
				float sin2h = max(1.0 - cos2h, 0.0078125); // 0.0078125 = 2^(-14/2), so sin2h^2 > 0 in fp16
				return (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * UNITY_PI);
			}
			
			// https://github.com/google/filament/blob/main/shaders/src/brdf.fs#L136-L139
			float V_Neubelt(float NoV, float NoL)
			{
				// Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886"
				return 1.0 / (4.0 * (NoL + NoV - NoL * NoV));
			}
			
			float Distribution(float roughness, float NoH, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(GGXTerm(roughness, NoH), D_Charlie(roughness, NoH), cloth);
				}
				//endex
				return cloth <= 0.5 ? GGXTerm(roughness, NoH) : D_Charlie(roughness, NoH);
			}
			
			float Visibility(float roughness, float NoV, float NoL, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(V_SmithGGXCorrelated(roughness, NoV, NoL), V_Neubelt(NoV, NoL), cloth);
				}
				//endex
				return cloth <= 0.5 ? V_SmithGGXCorrelated(roughness, NoV, NoL) : V_Neubelt(NoV, NoL);
			}
			
			float F_Schlick(float3 f0, float f90, float VoH)
			{
				// Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"
				return f0 + (f90 - f0) * pow(1.0 - VoH, 5);
			}
			
			float F_Schlick(float3 f0, float VoH)
			{
				float f = pow(1.0 - VoH, 5.0);
				return f + f0 * (1.0 - f);
			}
			
			float Fresnel(float3 f0, float LoH)
			{
				float f90 = saturate(dot(f0, float(50.0 * 0.33).xxx));
				return F_Schlick(f0, f90, LoH);
			}
			
			float Fd_Burley(float roughness, float NoV, float NoL, float LoH)
			{
				// Burley 2012, "Physically-Based Shading at Disney"
				float f90 = 0.5 + 2.0 * roughness * LoH * LoH;
				float lightScatter = F_Schlick(1.0, f90, NoL);
				float viewScatter = F_Schlick(1.0, f90, NoV);
				return lightScatter * viewScatter;
			}
			
			// Energy conserving wrap diffuse term, does *not* include the divide by PI
			float Fd_Wrap(float NoL, float w)
			{
				return saturate((NoL + w) / pow(1.0 + w, 2));
			}
			
			float4 SampleDFG(float NoV, float perceptualRoughness)
			{
				return _ClothDFG.Sample(sampler_ClothDFG, float3(NoV, perceptualRoughness, 0));
			}
			
			float3 EnvBRDF(float2 dfg, float3 f0)
			{
				return f0 * dfg.x + dfg.y;
			}
			
			float3 EnvBRDFMultiscatter(float3 dfg, float3 f0, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(lerp(dfg.xxx, dfg.yyy, f0), f0 * dfg.z, cloth);
				}
				//endex
				return cloth <= 0.5 ? lerp(dfg.xxx, dfg.yyy, f0) : f0 * dfg.z;
			}
			
			float3 EnvBRDFEnergyCompensation(float3 dfg, float3 f0, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(1.0 + f0 * (1.0 / dfg.y - 1.0), 1, cloth);
				}
				//endex
				return cloth <= 0.5 ? 1.0 + f0 * (1.0 / dfg.y - 1.0) : 1;
			}
			
			//
			float ClothMetallic(float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return cloth;
				}
				//endex
				return cloth <= 0.5 ? 1 : 0;
			}
			
			float3 Specular(float roughness, PoiLight poiLight, float f0, float3 normal, float cloth)
			{
				float NoL = poiLight.nDotLSaturated;
				float NoH = poiLight.nDotH;
				float LoH = poiLight.lDotH;
				float NoV = poiLight.nDotV;
				
				float D = Distribution(roughness, NoH, cloth);
				float V = Visibility(roughness, NoV, NoL, cloth);
				float3 F = Fresnel(f0, LoH);
				
				return (D * V) * F;
			}
			
			float3 getBoxProjection(float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax)
			{
				#if UNITY_SPECCUBE_BOX_PROJECTION
				if (cubemapPosition.w > 0)
				{
					float3 factors = ((direction > 0 ? boxMax : boxMin) - position) / direction;
					float scalar = min(min(factors.x, factors.y), factors.z);
					direction = direction * scalar + (position - cubemapPosition.xyz);
				}
				#endif
				
				return direction;
			}
			
			float SpecularAO(float NoV, float ao, float roughness)
			{
				return clamp(pow(NoV + ao, exp2(-16.0 * roughness - 1.0)) - 1.0 + ao, 0.0, 1.0);
			}
			
			float3 IndirectSpecular(float3 dfg, float roughness, float occlusion, float energyCompensation, float cloth, float3 indirectDiffuse, float f0, PoiLight poiLight, PoiFragData poiFragData, PoiCam poiCam, PoiMesh poiMesh)
			{
				float3 normal = poiMesh.normals[1];
				
				float3 reflDir = reflect(-poiCam.viewDir, normal);
				
				Unity_GlossyEnvironmentData envData;
				envData.roughness = roughness;
				envData.reflUVW = getBoxProjection(reflDir, poiMesh.worldPos, unity_SpecCube0_ProbePosition,
				unity_SpecCube0_BoxMin.xyz, unity_SpecCube0_BoxMax.xyz);
				
				float3 probe0 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE(unity_SpecCube0), unity_SpecCube0_HDR, envData);
				float3 indirectSpecular = probe0;
				
				#if UNITY_SPECCUBE_BLENDING
				UNITY_BRANCH
				if (unity_SpecCube0_BoxMin.w < 0.99999)
				{
					envData.reflUVW = getBoxProjection(reflDir, poiMesh.worldPos, unity_SpecCube1_ProbePosition, unity_SpecCube1_BoxMin.xyz, unity_SpecCube1_BoxMax.xyz);
					float3 probe1 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1, unity_SpecCube0), unity_SpecCube1_HDR, envData);
					indirectSpecular = lerp(probe1, probe0, unity_SpecCube0_BoxMin.w);
				}
				#endif
				
				float horizon = min(1 + dot(reflDir, normal), 1);
				indirectSpecular = indirectSpecular * horizon * horizon * energyCompensation * EnvBRDFMultiscatter(dfg, f0, cloth);
				
				indirectSpecular *= SpecularAO(poiLight.nDotV, occlusion, roughness);
				return indirectSpecular;
			};
			#endif
			
			#ifdef _LIGHTINGMODE_WRAPPED
			// Wrapped
			// Green’s model with adjustable energy
			// http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/
			// Modified for adjustable conservation ratio and over-wrap to directionless
			float RTWrapFunc(in float dt, in float w, in float norm)
			{
				float cw = saturate(w);
				
				float o = (dt + cw) / ((1.0 + cw) * (1.0 + cw * norm));
				float flt = 1.0 - 0.85 * norm;
				if (w > 1.0)
				{
					o = lerp(o, flt, w - 1.0);
				}
				return o;
			}
			
			float3 GreenWrapSH(float fA) // Greens unoptimized and non-normalized
			
			{
				float fAs = saturate(fA);
				float4 t = float4(fA + 1, fAs - 1, fA - 2, fAs + 1); // DJL edit: allow wrapping to L0-only at w=2
				return float3(t.x, -t.z * t.x / 3, 0.25 * t.y * t.y * t.w);
			}
			float3 GreenWrapSHOpt(float fW) // optimised and normalized https://blog.selfshadow.com/2012/01/07/righting-wrap-part-2/
			
			{
				const float4 t0 = float4(0.0, 1.0 / 4.0, -1.0 / 3.0, -1.0 / 2.0);
				const float4 t1 = float4(1.0, 2.0 / 3.0, 1.0 / 4.0, 0.0);
				float3 fWs = float3(fW, fW, saturate(fW)); // DJL edit: allow wrapping to L0-only at w=2
				
				float3 r;
				r.xyz = t0.xxy * fWs + t0.xzw;
				r.xyz = r.xyz * fWs + t1.xyz;
				return r;
			}
			float3 ShadeSH9_wrapped(float3 normal, float wrap)
			{
				float3 x0, x1, x2;
				float3 conv = lerp(GreenWrapSH(wrap), GreenWrapSHOpt(wrap), _LightingWrappedNormalization); // Should try optimizing this...
				conv *= float3(1, 1.5, 4); // Undo pre-applied cosine convolution by using the inverse
				
				// Constant (L0)
				x0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
				// Remove pre-applied constant part from L(2,0) to apply correct convolution
				float3 L2_0 = float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / - 3.0;
				x0 -= L2_0;
				
				// Linear (L1) polynomial terms
				x1.r = dot(unity_SHAr.xyz, normal);
				x1.g = dot(unity_SHAg.xyz, normal);
				x1.b = dot(unity_SHAb.xyz, normal);
				
				// 4 of the quadratic (L2) polynomials
				float4 vB = normal.xyzz * normal.yzzx;
				x2.r = dot(unity_SHBr, vB);
				x2.g = dot(unity_SHBg, vB);
				x2.b = dot(unity_SHBb, vB);
				
				// Final (5th) quadratic (L2) polynomial
				float vC = normal.x * normal.x - normal.y * normal.y;
				x2 += unity_SHC.rgb * vC;
				// Move back the constant part of L(2,0)
				x2 += L2_0;
				
				return x0 * conv.x + x1 * conv.y + x2 * conv.z;
			}
			
			float3 GetSHDirectionL1()
			{
				// For efficiency, we only get the direction from L1.
				// Because getting it from L2 would be too hard!
				return Unity_SafeNormalize((unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz));
			}
			// Returns the value from SH in the lighting direction with the
			// brightest intensity.
			half3 GetSHMaxL1()
			{
				float3 maxDirection = GetSHDirectionL1();
				return ShadeSH9_wrapped(maxDirection, 0);
			}
			#endif
			
			#ifdef _LIGHTINGMODE_SHADEMAP
			void applyShadeMapping(inout PoiFragData poiFragData, PoiMesh poiMesh, inout PoiLight poiLight)
			{
				float shadowAttenuation = lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				float attenuation = 1;
				#if defined(POINT) || defined(SPOT)
				shadowAttenuation = lerp(1, poiLight.additiveShadow, poiLight.attenuationStrength);
				//attenuation = poiLight.attenuation;
				#endif
				
				float MainColorFeatherStep = _BaseColor_Step - _BaseShade_Feather;
				float firstColorFeatherStep = _ShadeColor_Step - _1st2nd_Shades_Feather;
				
				#if defined(PROP_1ST_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
				float4 firstShadeMap = POI2D_SAMPLER_PAN(_1st_ShadeMap, _MainTex, poiUV(poiMesh.uv[_1st_ShadeMapUV], _1st_ShadeMap_ST), _1st_ShadeMapPan);
				#else
				float4 firstShadeMap = float4(1, 1, 1, 1);
				#endif
				firstShadeMap = lerp(firstShadeMap, float4(poiFragData.baseColor, 1), _Use_BaseAs1st);
				
				#if defined(PROP_2ND_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
				float4 secondShadeMap = POI2D_SAMPLER_PAN(_2nd_ShadeMap, _MainTex, poiUV(poiMesh.uv[_2nd_ShadeMapUV], _2nd_ShadeMap_ST), _2nd_ShadeMapPan);
				#else
				float4 secondShadeMap = float4(1, 1, 1, 1);
				#endif
				secondShadeMap = lerp(secondShadeMap, firstShadeMap, _Use_1stAs2nd);
				
				firstShadeMap.rgb *= _1st_ShadeColor.rgb; //* lighColor
				secondShadeMap.rgb *= _2nd_ShadeColor.rgb; //* LightColor;
				
				float shadowMask = 1;
				shadowMask *= _Use_1stShadeMapAlpha_As_ShadowMask ? (_1stShadeMapMask_Inverse ? (1.0 - firstShadeMap.a) : firstShadeMap.a) : 1;
				shadowMask *= _Use_2ndShadeMapAlpha_As_ShadowMask ? (_2ndShadeMapMask_Inverse ? (1.0 - secondShadeMap.a) : secondShadeMap.a) : 1;
				
				float mainShadowMask = saturate(1 - ((poiLight.lightMap) - MainColorFeatherStep) / (_BaseColor_Step - MainColorFeatherStep) * (shadowMask));
				float firstSecondShadowMask = saturate(1 - ((poiLight.lightMap) - firstColorFeatherStep) / (_ShadeColor_Step - firstColorFeatherStep) * (shadowMask));
				
				mainShadowMask *= poiLight.shadowMask * _ShadowStrength;
				firstSecondShadowMask *= poiLight.shadowMask * _ShadowStrength;
				
				// 0 lerp | 1 multiply
				if (_ShadingShadeMapBlendType == 0)
				{
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, lerp(firstShadeMap.rgb, secondShadeMap.rgb, firstSecondShadowMask), mainShadowMask) * attenuation;
				}
				else
				{
					poiFragData.baseColor.rgb *= lerp(1, lerp(firstShadeMap.rgb, secondShadeMap.rgb, firstSecondShadowMask), mainShadowMask) * attenuation;
				}
				poiLight.rampedLightMap = 1 - mainShadowMask;
			}
			#endif
			
			#ifdef _LIGHTINGMODE_REALISTIC
			// For https://docs.unity3d.com/Manual/LightMode-Mixed-Subtractive.html
			#if defined(LIGHTMAP_ON) && defined(SHADOWS_SCREEN)
			#if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK)
			#define SUBTRACTIVE_LIGHTING 1
			#endif
			#endif
			
			void ApplySubtractiveLighting(inout UnityIndirect indirectLight)
			{
				#if SUBTRACTIVE_LIGHTING
				poiLight.attenuation = FadeShadows(lerp(1, poiLight.attenuation, _AttenuationMultiplier));
				
				float ndotl = saturate(dot(i.normal, _WorldSpaceLightPos0.xyz));
				float3 shadowedLightEstimate = ndotl * (1 - poiLight.attenuation) * _LightColor0.rgb;
				float3 subtractedLight = indirectLight.diffuse - shadowedLightEstimate;
				subtractedLight = max(subtractedLight, unity_ShadowColor.rgb);
				subtractedLight = lerp(subtractedLight, indirectLight.diffuse, _LightShadowData.x);
				indirectLight.diffuse = min(subtractedLight, indirectLight.diffuse);
				#endif
			}
			
			UnityIndirect CreateIndirectLight(in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight)
			{
				UnityIndirect indirectLight;
				indirectLight.diffuse = 0;
				indirectLight.specular = 0;
				
				#if defined(LIGHTMAP_ON)
				indirectLight.diffuse = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, poiMesh.lightmapUV.xy));
				
				#if defined(DIRLIGHTMAP_COMBINED)
				float4 lightmapDirection = UNITY_SAMPLE_TEX2D_SAMPLER(
				unity_LightmapInd, unity_Lightmap, poiMesh.lightmapUV.xy
				);
				indirectLight.diffuse = DecodeDirectionalLightmap(
				indirectLight.diffuse, lightmapDirection, poiMesh.normals[1]
				);
				#endif
				ApplySubtractiveLighting(indirectLight);
				#endif
				
				#if defined(DYNAMICLIGHTMAP_ON)
				float3 dynamicLightDiffuse = DecodeRealtimeLightmap(
				UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, poiMesh.lightmapUV.zw)
				);
				
				#if defined(DIRLIGHTMAP_COMBINED)
				float4 dynamicLightmapDirection = UNITY_SAMPLE_TEX2D_SAMPLER(
				unity_DynamicDirectionality, unity_DynamicLightmap,
				poiMesh.lightmapUV.zw
				);
				indirectLight.diffuse += DecodeDirectionalLightmap(
				dynamicLightDiffuse, dynamicLightmapDirection, poiMesh.normals[1]
				);
				#else
				indirectLight.diffuse += dynamicLightDiffuse;
				#endif
				#endif
				
				#if !defined(LIGHTMAP_ON) && !defined(DYNAMICLIGHTMAP_ON)
				#if UNITY_LIGHT_PROBE_PROXY_VOLUME
				if (unity_ProbeVolumeParams.x == 1)
				{
					indirectLight.diffuse = SHEvalLinearL0L1_SampleProbeVolume(
					float4(poiMesh.normals[1], 1), poiMesh.worldPos
					);
					indirectLight.diffuse = max(0, indirectLight.diffuse);
					#if defined(UNITY_COLORSPACE_GAMMA)
					indirectLight.diffuse = LinearToGammaSpace(indirectLight.diffuse);
					#endif
				}
				else
				{
					indirectLight.diffuse += max(0, ShadeSH9(float4(poiMesh.normals[1], 1)));
				}
				#else
				indirectLight.diffuse += max(0, ShadeSH9(float4(poiMesh.normals[1], 1)));
				#endif
				#endif
				
				indirectLight.diffuse *= poiLight.occlusion;
				
				return indirectLight;
			}
			#endif
			
			float GetRemapMinValue(float scale, float offset)
			{
				return clamp(-offset / scale, -0.01f, 1.01f); // Remap min
				
			}
			float GetRemapMaxValue(float scale, float offset)
			{
				return clamp((1.0f - offset) / scale, -0.01f, 1.01f); // Remap Max
				
			}
			
			void calculateShading(inout PoiLight poiLight, inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam)
			{
				float shadowAttenuation = lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				float attenuation = 1;
				#if defined(POINT) || defined(SPOT)
				shadowAttenuation = lerp(1, poiLight.additiveShadow, poiLight.attenuationStrength);
				//attenuation = poiLight.attenuation;
				#endif
				
				#ifdef POI_PASS_ADD
				if (_LightingAdditiveType == 3)
				{
					#if defined(POINT) || defined(SPOT)
					#if defined(_LIGHTINGMODE_REALISTIC) || defined(_LIGHTINGMODE_CLOTH) || defined(_LIGHTINGMODE_WRAPPED)
					poiLight.rampedLightMap = max(0, poiLight.nDotL);
					poiLight.finalLighting = poiLight.directColor * attenuation * max(0, poiLight.nDotL) * poiLight.detailShadow * shadowAttenuation;
					return;
					#endif
					#endif
				}
				// Realistic
				if (_LightingAdditiveType == 0)
				{
					poiLight.rampedLightMap = max(0, poiLight.nDotL);
					poiLight.finalLighting = poiLight.directColor * attenuation * max(0, poiLight.nDotL) * poiLight.detailShadow * shadowAttenuation;
					return;
				}
				// Toon
				if (_LightingAdditiveType == 1)
				{
					#if defined(POINT_COOKIE) || defined(DIRECTIONAL_COOKIE)
					float passthrough = 0;
					#else
					float passthrough = _LightingAdditivePassthrough;
					#endif
					
					float2 ToonAddGradient = float2(_LightingAdditiveGradientStart, _LightingAdditiveGradientEnd);
					
					if (ToonAddGradient.x == ToonAddGradient.y) ToonAddGradient.y += 0.0001;
					
					poiLight.rampedLightMap = smoothstep(ToonAddGradient.y, ToonAddGradient.x, 1 - (.5 * poiLight.nDotL + .5));
					#if defined(POINT) || defined(SPOT)
					poiLight.finalLighting = lerp(poiLight.directColor * max(min(poiLight.additiveShadow, poiLight.detailShadow), passthrough), poiLight.indirectColor, smoothstep(ToonAddGradient.x, ToonAddGradient.y, 1 - (.5 * poiLight.nDotL + .5)));
					#else
					poiLight.finalLighting = lerp(poiLight.directColor * max(min(poiLight.attenuation, poiLight.detailShadow), passthrough), poiLight.indirectColor, smoothstep(ToonAddGradient.x, ToonAddGradient.y, 1 - (.5 * poiLight.nDotL + .5)));
					#endif
					return;
				}
				#endif
				
				float shadowStrength = _ShadowStrength * poiLight.shadowMask;
				
				#ifdef POI_PASS_OUTLINE
				shadowStrength = lerp(0, shadowStrength, _OutlineShadowStrength);
				#endif
				
				// These blocks shouldn't need ifex, they should be removed on lock when their keywords aren't present
				
				#ifdef _LIGHTINGMODE_FLAT
				poiLight.finalLighting = poiLight.directColor * attenuation * shadowAttenuation;
				if (_ForceFlatRampedLightmap)
				{
					poiLight.rampedLightMap = smoothstep(0.4, 0.6, poiLight.nDotLNormalized);
				}
				else
				{
					poiLight.rampedLightMap = 1;
				}
				#endif
				
				#ifdef _LIGHTINGMODE_TEXTURERAMP
				float2 rampUVs = poiLight.lightMap + _ShadowOffset;
				if (_ToonRampCount > 1)
				{
					rampUVs.y = (floor(poiMesh.uv[_ToonRampUVSelector].y * _ToonRampCount) + 0.5) / _ToonRampCount;
				}
				poiLight.rampedLightMap = lerp(1, UNITY_SAMPLE_TEX2D_SAMPLER(_ToonRamp, _linear_clamp, rampUVs).rgb, shadowStrength);
				poiLight.finalLighting = lerp(_LightingShadowColor * lerp(poiLight.indirectColor, poiLight.rampedLightMap * poiLight.directColor, _LightingIgnoreAmbientColor) * poiLight.occlusion, poiLight.directColor, poiLight.rampedLightMap) * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_MULTILAYER_MATH
				#if defined(PROP_MULTILAYERMATHBLURMAP) || !defined(OPTIMIZER_ENABLED)
				float4 blurMap = POI2D_SAMPLER_PAN(_MultilayerMathBlurMap, _MainTex, poiUV(poiMesh.uv[_MultilayerMathBlurMapUV], _MultilayerMathBlurMap_ST), _MultilayerMathBlurMapPan);
				#else
				float4 blurMap = 1;
				#endif
				
				float4 lns = float4(1, 1, 1, 1);
				
				float shadowAttenuationNoStrength = poiLight.attenuation;
				#if defined(POINT) || defined(SPOT)
				shadowAttenuationNoStrength = poiLight.additiveShadow;
				#endif
				
				float3 lightMap = poiLight.lightMapNoAttenuation.xxx;
				lightMap.x *= lerp(1.0, shadowAttenuationNoStrength, _ShadowReceive);
				lightMap.y *= lerp(1.0, shadowAttenuationNoStrength, _Shadow2ndReceive);
				lightMap.z *= lerp(1.0, shadowAttenuationNoStrength, _Shadow3rdReceive);
				
				float4 shadowBorderMask = 1;
				if (_ShadowBorderMapToggle)
				{
					// This should be moved to ui but honestly if these are locked in the compiler should be able to resolve it at compile time
					float2 shadowShift0 = float2(_ShadowAOShift.x, _ShadowAOShift.y);
					float2 shadowShift1 = float2(_ShadowAOShift.z, _ShadowAOShift.w);
					float2 shadowShift2 = float2(_ShadowAOShift2.x, _ShadowAOShift2.y);
					
					//float2 shadowShift0 = float2(GetRemapMinValue(_ShadowAOShift.x, _ShadowAOShift.y), GetRemapMaxValue(_ShadowAOShift.x, _ShadowAOShift.y));
					//float2 shadowShift1 = float2(GetRemapMinValue(_ShadowAOShift.z, _ShadowAOShift.w), GetRemapMaxValue(_ShadowAOShift.z, _ShadowAOShift.w));
					//float2 shadowShift2 = float2(GetRemapMinValue(_ShadowAOShift2.x, _ShadowAOShift2.y), GetRemapMaxValue(_ShadowAOShift2.x, _ShadowAOShift2.y));
					
					shadowShift0.y = (shadowShift0.x == shadowShift0.y) ? (shadowShift0.y + 0.001f) : shadowShift0.y;
					shadowShift1.y = (shadowShift1.x == shadowShift1.y) ? (shadowShift1.y + 0.001f) : shadowShift1.y;
					shadowShift2.y = (shadowShift2.x == shadowShift2.y) ? (shadowShift2.y + 0.001f) : shadowShift2.y;
					
					shadowShift0 = float2(1.0f / (shadowShift0.y - shadowShift0.x), shadowShift0.x / (shadowShift0.x - shadowShift0.y));
					shadowShift1 = float2(1.0f / (shadowShift1.y - shadowShift1.x), shadowShift1.x / (shadowShift1.x - shadowShift1.y));
					shadowShift2 = float2(1.0f / (shadowShift2.y - shadowShift2.x), shadowShift2.x / (shadowShift2.x - shadowShift2.y));
					
					#if defined(PROP_SHADOWBORDERMASK) || !defined(OPTIMIZER_ENABLED)
					float2 shadowBorderMaskUV = poiUV(poiMesh.uv[_ShadowBorderMaskUV], _ShadowBorderMask_ST);
					if (_ShadowBorderMaskLOD)
					{
						shadowBorderMask = POI2D_SAMPLE_TEX2D_SAMPLERGRADD(_ShadowBorderMask, sampler_trilinear_repeat, shadowBorderMaskUV, _ShadowBorderMaskPan, max(abs(ddx(shadowBorderMaskUV)), pow(_ShadowBorderMaskLOD, 4)), max(abs(ddy(shadowBorderMaskUV)), pow(_ShadowBorderMaskLOD, 4)));
					}
					else
					{
						shadowBorderMask = POI2D_SAMPLER_PAN(_ShadowBorderMask, _linear_repeat, shadowBorderMaskUV, _ShadowBorderMaskPan);
					}
					#endif
					
					shadowBorderMask.r = saturate(shadowBorderMask.r * shadowShift0.x + shadowShift0.y);
					shadowBorderMask.g = saturate(shadowBorderMask.g * shadowShift1.x + shadowShift1.y);
					shadowBorderMask.b = saturate(shadowBorderMask.b * shadowShift2.x + shadowShift2.y);
					
					lightMap.xyz = _ShadowPostAO ? lightMap.xyz : lightMap.xyz * shadowBorderMask.rgb;
				}
				
				if (_LightingMulitlayerNonLinear)
				{
					lns.x = poiEdgeNonLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r);
					lns.y = poiEdgeNonLinearNoSaturate(lightMap.y, _Shadow2ndBorder, _Shadow2ndBlur * blurMap.g);
					lns.z = poiEdgeNonLinearNoSaturate(lightMap.z, _Shadow3rdBorder, _Shadow3rdBlur * blurMap.b);
					lns.w = poiEdgeNonLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r, _ShadowBorderRange);
				}
				else
				{
					lns.x = poiEdgeLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r);
					lns.y = poiEdgeLinearNoSaturate(lightMap.y, _Shadow2ndBorder, _Shadow2ndBlur * blurMap.g);
					lns.z = poiEdgeLinearNoSaturate(lightMap.z, _Shadow3rdBorder, _Shadow3rdBlur * blurMap.b);
					lns.w = poiEdgeLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r, _ShadowBorderRange);
				}
				#if defined(PROP_SHADOWBORDERMASK) || !defined(OPTIMIZER_ENABLED)
				lns = _ShadowPostAO ? lns * shadowBorderMask.rgbr : lns;
				#endif
				lns = saturate(lns);
				//poiLight.finalLighting = lns.rgb;
				//return;
				float3 indirectColor = 1;
				
				if (_ShadowColor.a > 0)
				{
					#if defined(PROP_SHADOWCOLORTEX) || !defined(OPTIMIZER_ENABLED)
					float4 shadowColorTex = POI2D_SAMPLER_PAN(_ShadowColorTex, _MainTex, poiUV(poiMesh.uv[_ShadowColorTexUV], _ShadowColorTex_ST), _ShadowColorTexPan);
					#else
					float4 shadowColorTex = float4(1, 1, 1, 1);
					#endif
					indirectColor = lerp(float3(1, 1, 1), shadowColorTex.rgb, shadowColorTex.a) * _ShadowColor.rgb;
				}
				if (_Shadow2ndColor.a > 0)
				{
					#if defined(PROP_SHADOW2NDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
					float4 shadow2ndColorTex = POI2D_SAMPLER_PAN(_Shadow2ndColorTex, _MainTex, poiUV(poiMesh.uv[_Shadow2ndColorTexUV], _Shadow2ndColorTex_ST), _Shadow2ndColorTexPan);
					#else
					float4 shadow2ndColorTex = float4(1, 1, 1, 1);
					#endif
					shadow2ndColorTex.rgb = lerp(float3(1, 1, 1), shadow2ndColorTex.rgb, shadow2ndColorTex.a) * _Shadow2ndColor.rgb;
					lns.y = _Shadow2ndColor.a - lns.y * _Shadow2ndColor.a;
					indirectColor = lerp(indirectColor, shadow2ndColorTex.rgb, lns.y);
				}
				if (_Shadow3rdColor.a > 0)
				{
					#if defined(PROP_SHADOW3RDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
					float4 shadow3rdColorTex = POI2D_SAMPLER_PAN(_Shadow3rdColorTex, _MainTex, poiUV(poiMesh.uv[_Shadow3rdColorTexUV], _Shadow3rdColorTex_ST), _Shadow3rdColorTexPan);
					#else
					float4 shadow3rdColorTex = float4(1, 1, 1, 1);
					#endif
					shadow3rdColorTex.rgb = lerp(float3(1, 1, 1), shadow3rdColorTex.rgb, shadow3rdColorTex.a) * _Shadow3rdColor.rgb;
					lns.z = _Shadow3rdColor.a - lns.z * _Shadow3rdColor.a;
					indirectColor = lerp(indirectColor, shadow3rdColorTex.rgb, lns.z);
				}
				
				indirectColor = lerp(indirectColor, indirectColor * poiFragData.baseColor, _ShadowMainStrength);
				poiLight.rampedLightMap = lns.x;
				indirectColor = lerp(indirectColor, 1, lns.w * _ShadowBorderColor.rgb * _ShadowBorderColor.a);
				indirectColor = indirectColor * lerp(poiLight.indirectColor, poiLight.directColor, _LightingIgnoreAmbientColor);
				indirectColor = lerp(poiLight.directColor, indirectColor, shadowStrength * poiLight.shadowMask);
				poiLight.finalLighting = lerp(indirectColor, poiLight.directColor, lns.x) * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_SHADEMAP
				poiLight.finalLighting = poiLight.directColor * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_REALISTIC
				UnityLight light;
				light.dir = poiLight.direction;
				light.color = max(0, _LightColor0.rgb) * saturate(shadowAttenuation * attenuation * poiLight.detailShadow);
				light.ndotl = poiLight.nDotLSaturated;
				UnityIndirect indirectLight = (UnityIndirect)0;
				#ifdef UNITY_PASS_FORWARDBASE
				indirectLight = CreateIndirectLight(poiMesh, poiCam, poiLight);
				#endif
				#ifdef UNITY_PASS_FORWARDBASE
				light.color = max(light.color * _PPLightingMultiplier, 0);
				light.color = max(light.color + _PPLightingAddition, 0);
				indirectLight.diffuse = max(indirectLight.diffuse * _PPLightingMultiplier, 0);
				indirectLight.diffuse = max(indirectLight.diffuse + _PPLightingAddition, 0);
				#endif
				
				poiLight.rampedLightMap = poiLight.nDotLSaturated;
				poiLight.finalLighting = max(UNITY_BRDF_PBS(1, 0, 0, 0, poiMesh.normals[1], poiCam.viewDir, light, indirectLight).xyz, _LightingMinLightBrightness);
				#endif
				
				#ifdef _LIGHTINGMODE_CLOTH
				#if defined(PROP_CLOTHMETALLICSMOOTHNESSMAP) || !defined(OPTIMIZER_ENABLED)
				float4 clothmapsample = POI2D_SAMPLER_PAN(_ClothMetallicSmoothnessMap, _MainTex, poiUV(poiMesh.uv[_ClothMetallicSmoothnessMapUV], _ClothMetallicSmoothnessMap_ST), _ClothMetallicSmoothnessMapPan);
				float roughness = 1 - (clothmapsample.a * _ClothSmoothness);
				float reflectance = _ClothReflectance * clothmapsample.b;
				float clothmask = clothmapsample.g;
				float metallic = pow(clothmapsample.r * _ClothMetallic, 2) * ClothMetallic(clothmask);
				roughness = _ClothMetallicSmoothnessMapInvert == 1 ? 1 - roughness : roughness;
				#else
				float roughness = 1 - (_ClothSmoothness);
				float metallic = pow(_ClothMetallic, 2);
				float reflectance = _ClothReflectance;
				float clothmask = 1;
				#endif
				
				float perceptualRoughness = pow(roughness, 2);
				float clampedRoughness = max(0.002, perceptualRoughness);
				
				float f0 = 0.16 * reflectance * reflectance * (1 - metallic) + poiFragData.baseColor * metallic;
				float3 fresnel = Fresnel(f0, poiLight.nDotV);
				
				float3 dfg = SampleDFG(poiLight.nDotV, perceptualRoughness);
				
				float energyCompensation = EnvBRDFEnergyCompensation(dfg, f0, clothmask);
				
				poiLight.finalLighting = Fd_Burley(perceptualRoughness, poiLight.nDotV, poiLight.nDotLSaturated, poiLight.lDotH);
				poiLight.finalLighting *= _LightColor0 * attenuation * shadowAttenuation * poiLight.nDotLSaturated;
				poiLight.rampedLightMap = poiLight.nDotLSaturated;
				float3 specular = max(0, Specular(clampedRoughness, poiLight, f0, poiMesh.normals[1], clothmask) * poiLight.finalLighting * energyCompensation * UNITY_PI); // (D * V) * F
				
				#ifdef UNITY_PASS_FORWARDBASE
				float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
				float3 indirectDiffuse;
				indirectDiffuse.r = shEvaluateDiffuseL1Geomerics_local(L0.r, unity_SHAr.xyz, poiMesh.normals[1]);
				indirectDiffuse.g = shEvaluateDiffuseL1Geomerics_local(L0.g, unity_SHAg.xyz, poiMesh.normals[1]);
				indirectDiffuse.b = shEvaluateDiffuseL1Geomerics_local(L0.b, unity_SHAb.xyz, poiMesh.normals[1]);
				indirectDiffuse = max(0, indirectDiffuse);
				
				float3 indirectSpecular = IndirectSpecular(dfg, roughness, poiLight.occlusion, energyCompensation, clothmask, indirectDiffuse, f0, poiLight, poiFragData, poiCam, poiMesh);
				poiLight.finalLightAdd += max(0, specular + indirectSpecular);
				poiLight.finalLighting += indirectDiffuse * poiLight.occlusion;
				#endif
				
				poiFragData.baseColor.xyz *= (1 - metallic);
				#endif
				
				#ifdef _LIGHTINGMODE_WRAPPED
				#define GREYSCALE_VECTOR float3(.33333, .33333, .33333)
				float3 directColor = _LightColor0.rgb * saturate(RTWrapFunc(poiLight.nDotL, _LightingWrappedWrap, _LightingWrappedNormalization));
				float3 indirectColor = 0;
				#ifdef UNITY_PASS_FORWARDBASE
				indirectColor = ShadeSH9_wrapped(poiMesh.normals[_LightingIndirectUsesNormals], _LightingWrappedWrap) * poiLight.occlusion;
				#endif
				directColor = lerp(directColor, dot(directColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic); // Duplicated from Lightdata due to recreating the light colour
				indirectColor = lerp(indirectColor, dot(indirectColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic); // Ditto^
				
				float3 ShadeSH9Plus_2 = GetSHMaxL1();
				float bw_topDirectLighting_2 = dot(_LightColor0.rgb, GREYSCALE_VECTOR);
				float bw_directLighting = dot(directColor, GREYSCALE_VECTOR);
				float bw_indirectLighting = dot(indirectColor, GREYSCALE_VECTOR);
				float bw_topIndirectLighting = dot(ShadeSH9Plus_2, GREYSCALE_VECTOR);
				
				poiLight.lightMap = smoothstep(0, bw_topIndirectLighting + bw_topDirectLighting_2, bw_indirectLighting + bw_directLighting) * min(poiLight.detailShadow, shadowAttenuation);
				poiLight.rampedLightMap = saturate((poiLight.lightMap - (1 - _LightingGradientEnd)) / saturate((1 - _LightingGradientStart) - (1 - _LightingGradientEnd) + fwidth(poiLight.lightMap)));
				float3 mathRamp = lerp(float3(1, 1, 1), saturate(lerp((_LightingShadowColor * lerp(indirectColor, 1, _LightingIgnoreAmbientColor)), float3(1, 1, 1), saturate(poiLight.rampedLightMap))), _ShadowStrength);
				
				directColor *= saturate(poiLight.rampedLightMap + 1 - _ShadowStrength) * _LightingWrappedColor;
				
				float3 finalWrap = directColor + indirectColor;
				if (_LightingCapEnabled)
				{
					finalWrap = clamp(finalWrap, _LightingMinLightBrightness, _LightingCap);
				}
				else
				{
					finalWrap = max(finalWrap, _LightingMinLightBrightness);
				}
				//finalWrap *= attenuation;
				poiLight.finalLighting = finalWrap * saturate(mathRamp + 1 - _ShadowStrength);
				#endif
				
				#ifdef _LIGHTINGMODE_SKIN
				float3 ambientNormalWorld = poiMesh.normals[1];//aTangentToWorld(s, s.blurredNormalTangent);
				poiLight.rampedLightMap = poiLight.nDotLSaturated;
				
				// Scattering mask.
				#if defined(PROP_SKINTHICKNESS) || !defined(OPTIMIZER_ENABLED)
				float subsurface = 1 - POI2D_SAMPLER_PAN(_SkinThicknessMap, _MainTex, poiUV(poiMesh.uv[_SkinThicknessMapUV], _SkinThicknessMap_ST), _SkinThicknessMapPan).r;
				#else
				float subsurface = 1;
				#endif
				if (_SkinThicknessMapInvert)
				{
					subsurface = 1 - subsurface;
				}
				if (_SkinThicknessPower != 1)
				{
					subsurface = pow(subsurface, _SkinThicknessPower);
				}
				float skinScattering = saturate(subsurface * _SssScale * 2);
				
				// Skin subsurface depth absorption tint.
				// cf http://www.crytek.com/download/2014_03_25_CRYENGINE_GDC_Schultz.pdf pg 35
				// link dead, https://ia600902.us.archive.org/25/items/crytek_presentations/2014_03_25_CRYENGINE_GDC_Schultz.pdf
				half3 absorption = exp((1.0h - subsurface) * _SssTransmissionAbsorption.rgb);
				
				// Albedo scale for absorption assumes ~0.5 luminance for Caucasian skin.
				absorption *= saturate(poiFragData.baseColor * unity_ColorSpaceDouble.rgb);
				
				// Blurred normals for indirect diffuse and direct scattering.
				ambientNormalWorld = normalize(lerp(poiMesh.normals[1], ambientNormalWorld, _SssBumpBlur));
				
				float ndlBlur = dot(poiMesh.normals[1], poiLight.direction) * 0.5h + 0.5h;
				float lumi = dot(poiLight.directColor, half3(0.2126h, 0.7152h, 0.0722h));
				float4 sssLookupUv = float4(ndlBlur, skinScattering * lumi, 0.0f, 0.0f);
				half3 sss = poiLight.lightMap * tex2Dlod(_SkinLUT, sssLookupUv).rgb;
				poiLight.finalLighting = lerp(poiLight.directColor, min(lerp(poiLight.indirectColor * _LightingShadowColor, _LightingShadowColor, _LightingIgnoreAmbientColor) * poiLight.occlusion + (sss * poiLight.directColor), poiLight.directColor), _ShadowStrength * poiLight.shadowMask) * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_SDF
				float3 forward = normalize(UnityObjectToWorldDir(float4(_SDFForward.xyz, 1)));
				float3 left = normalize(UnityObjectToWorldDir(float4(_SDFLeft.xyz, 1)));
				float3 lightDirHorizontal = normalize(float3(poiLight.direction.x, 0, poiLight.direction.z));
				
				float lightAtten = 1 - (dot(lightDirHorizontal, forward) * 0.5 + 0.5);
				float filpU = sign(dot(lightDirHorizontal, left));
				
				#if defined(PROP_SDFSHADINGTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float shadowSDF = POI2D_SAMPLER_PAN(_SDFShadingTexture, _MainTex, poiUV(poiMesh.uv[_SDFShadingTextureUV], _SDFShadingTexture_ST) * float2(filpU, 1), _SDFShadingTexturePan).r;
				#else
				float shadowSDF = float2(1, 1);
				#endif
				float blur = _SDFBlur * 0.1;
				float faceShadow = smoothstep(lightAtten - blur, lightAtten + blur, shadowSDF) * poiLight.detailShadow;
				
				float3 indirectColor = _LightingShadowColor.rgb;
				indirectColor = indirectColor * lerp(poiLight.indirectColor, poiLight.directColor, _LightingIgnoreAmbientColor);
				indirectColor = lerp(poiLight.directColor, indirectColor, _ShadowStrength * poiLight.shadowMask);
				
				poiLight.finalLighting = lerp(indirectColor, poiLight.directColor, faceShadow) * attenuation;
				#endif
				
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					float3 vertexLighting = float3(0, 0, 0);
					for (int index = 0; index < 4; index++)
					{
						float lightingMode = _LightingAdditiveType;
						if (lightingMode == 3)
						{
							//This is a temporary bandaid fix
							#if defined(_LIGHTINGMODE_REALISTIC)
							lightingMode = 0;
							#else
							lightingMode = 1;
							#endif
						}
						//UNITY_BRANCH
						if (lightingMode == 0)
						{
							vertexLighting = max(vertexLighting, poiLight.vColor[index] * poiLight.vSaturatedDotNL[index] * poiLight.detailShadow); // Realistic
							
						}
						//UNITY_BRANCH
						// Toon
						if (lightingMode == 1)
						{
							float2 ToonAddGradient = float2(_LightingAdditiveGradientStart, _LightingAdditiveGradientEnd);
							if (ToonAddGradient.x == ToonAddGradient.y) ToonAddGradient.y += 0.0001;
							vertexLighting = max(vertexLighting, lerp(poiLight.vColor[index], poiLight.vColor[index] * _LightingAdditivePassthrough, smoothstep(ToonAddGradient.x, ToonAddGradient.y, 1 - (.5 * poiLight.vDotNL[index] + .5))) * poiLight.detailShadow);
						}
					}
					float3 mixedLight = poiLight.finalLighting;
					poiLight.finalLighting = max(vertexLighting, poiLight.finalLighting);
					#endif
				}
			}
			#endif
			//endex
			
			#if defined(GEOM_TYPE_BRANCH) || defined(GEOM_TYPE_BRANCH_DETAIL) || defined(GEOM_TYPE_FROND) || defined(DEPTH_OF_FIELD_COC_VIEW)
			float2 decalUV(float uvNumber, float2 position, half rotation, half rotationSpeed, half2 scale, float4 scaleOffset, float depth, in PoiMesh poiMesh, in PoiCam poiCam)
			{
				scaleOffset = float4(-scaleOffset.x, scaleOffset.y, -scaleOffset.z, scaleOffset.w);
				float2 centerOffset = float2((scaleOffset.x + scaleOffset.y) / 2, (scaleOffset.z + scaleOffset.w) / 2);
				float2 uv = poiMesh.uv[uvNumber] + calcParallax(depth + 1, poiCam);
				float2 decalCenter = position + centerOffset;
				float theta = radians(rotation + _Time.z * rotationSpeed);
				float cs = cos(theta);
				float sn = sin(theta);
				uv = float2((uv.x - decalCenter.x) * cs - (uv.y - decalCenter.y) * sn + decalCenter.x, (uv.x - decalCenter.x) * sn + (uv.y - decalCenter.y) * cs + decalCenter.y);
				uv = remap(uv, float2(0, 0) - scale / 2 + position + scaleOffset.xz, scale / 2 + position + scaleOffset.yw, float2(0, 0), float2(1, 1));
				return uv;
			}
			
			inline float3 decalHueShift(float enabled, float3 color, float shift, float shiftSpeed)
			{
				//UNITY_BRANCH
				if (enabled)
				{
					color = hueShift(color, shift + _Time.x * shiftSpeed);
				}
				return color;
			}
			
			inline float applyTilingClipping(float enabled, float2 uv)
			{
				float ret = 1;
				//UNITY_BRANCH
				if (!enabled)
				{
					if (uv.x > 1 || uv.y > 1 || uv.x < 0 || uv.y < 0)
					{
						ret = 0;
					}
				}
				return ret;
			}
			
			struct PoiDecal
			{
				float m_DecalFaceMask;
				float m_DecalMaskChannel;
				float m_DecalGlobalMask;
				float m_DecalGlobalMaskBlendType;
				float m_DecalApplyGlobalMaskIndex;
				float m_DecalApplyGlobalMaskBlendType;
				float4 m_DecalTexture_ST;
				float2 m_DecalTexturePan;
				float m_DecalTextureUV;
				float4 m_DecalColor;
				float m_DecalColorThemeIndex;
				fixed m_DecalTiled;
				float m_DecalBlendType;
				half m_DecalRotation;
				half3 m_DecalScale;
				float4 m_DecalSideOffset;
				half2 m_DecalPosition;
				half m_DecalRotationSpeed;
				float m_DecalEmissionStrength;
				float m_DecalBlendAlpha;
				float m_DecalAlphaBlendMode;
				float m_DecalHueShiftEnabled;
				float m_DecalHueShift;
				float m_DecalHueShiftSpeed;
				float m_DecalDepth;
				float m_DecalHueAngleStrength;
				float m_DecalChannelSeparationEnable;
				float m_DecalChannelSeparation;
				float m_DecalChannelSeparationPremultiply;
				float m_DecalChannelSeparationHue;
				float m_DecalChannelSeparationVertical;
				float m_DecalChannelSeparationAngleStrength;
				float m_DecalOverrideAlphaMode;
				float m_DecalOverrideAlpha;
				
				#if defined(POI_AUDIOLINK)
				half m_AudioLinkDecalScaleBand;
				float4 m_AudioLinkDecalScale;
				half m_AudioLinkDecalRotationBand;
				float2 m_AudioLinkDecalRotation;
				half m_AudioLinkDecalAlphaBand;
				float2 m_AudioLinkDecalAlpha;
				half m_AudioLinkDecalEmissionBand;
				float2 m_AudioLinkDecalEmission;
				float m_DecalRotationCTALBand;
				float m_DecalRotationCTALSpeed;
				float m_DecalRotationCTALType;
				float m_AudioLinkDecalColorChord;
				float m_AudioLinkDecalSideBand;
				float4 m_AudioLinkDecalSideMin;
				float4 m_AudioLinkDecalSideMax;
				float2 m_AudioLinkDecalChannelSeparation;
				float m_AudioLinkDecalChannelSeparationBand;
				#endif
				
				float4 decalColor;
				float2 decalScale;
				float decalRotation;
				float2 uv;
				float4 dduv;
				float4 sideMod;
				float decalChannelOffset;
				float4 decalMask;
				
				void Init(in float4 DecalMask)
				{
					decalMask = DecalMask;
					decalScale = m_DecalScale.xy;// * m_DecalScale.z;
					
				}
				
				void InitAudiolink(in PoiMods poiMods)
				{
					#ifdef POI_AUDIOLINK
					if (poiMods.audioLinkAvailable)
					{
						decalScale += lerp(m_AudioLinkDecalScale.xy, m_AudioLinkDecalScale.zw, poiMods.audioLink[m_AudioLinkDecalScaleBand]);
						sideMod += lerp(m_AudioLinkDecalSideMin, m_AudioLinkDecalSideMax, poiMods.audioLink[m_AudioLinkDecalSideBand]);
						decalRotation += lerp(m_AudioLinkDecalRotation.x, m_AudioLinkDecalRotation.y, poiMods.audioLink[m_AudioLinkDecalRotationBand]);
						decalRotation += AudioLinkGetChronoTime(m_DecalRotationCTALType, m_DecalRotationCTALBand) * m_DecalRotationCTALSpeed * 360;
						decalChannelOffset += lerp(m_AudioLinkDecalChannelSeparation[0], m_AudioLinkDecalChannelSeparation[1], poiMods.audioLink[m_AudioLinkDecalChannelSeparationBand]);
					}
					#endif
				}
				
				void SampleDecalNoTexture(in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam)
				{
					uv = decalUV(m_DecalTextureUV, m_DecalPosition, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					decalColor = float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					decalColor.rgb = decalHueShift(m_DecalHueShiftEnabled, decalColor.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					decalColor.a *= decalMask[m_DecalMaskChannel] * applyTilingClipping(m_DecalTiled, uv);
				}
				
				void SampleDecal(sampler2D decalTexture, in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam, float2 scaleMultiplier = float2(1, 1))
				{
					uv = decalUV(m_DecalTextureUV, m_DecalPosition, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale * scaleMultiplier, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					// Adjust derivatives for _ST of decal texture
					float4 dduv = any(fwidth(uv) > .5) ? 0.001 : float4(ddx(uv) * m_DecalTexture_ST.x, ddy(uv) * m_DecalTexture_ST.y);
					decalColor = tex2D(decalTexture, poiUV(uv, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduv.xy, dduv.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					decalColor.rgb = decalHueShift(m_DecalHueShiftEnabled, decalColor.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					decalColor.a *= decalMask[m_DecalMaskChannel] * applyTilingClipping(m_DecalTiled, uv);
				}
				
				void SampleDecalNoAlpha(sampler2D decalTexture, in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam, float2 scaleMultiplier = float2(1, 1))
				{
					uv = decalUV(m_DecalTextureUV, m_DecalPosition, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale * scaleMultiplier, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					// Adjust derivatives for _ST of decal texture
					float4 dduv = any(fwidth(uv) > .5) ? 0.001 : float4(ddx(uv) * m_DecalTexture_ST.x, ddy(uv) * m_DecalTexture_ST.y);
					decalColor.rgb = tex2D(decalTexture, poiUV(uv, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduv.xy, dduv.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a).rgb;
					decalColor.rgb = decalHueShift(m_DecalHueShiftEnabled, decalColor.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					decalColor.a *= decalMask[m_DecalMaskChannel] * applyTilingClipping(m_DecalTiled, uv);
				}
				
				void SampleDecalAlphaOnly(sampler2D decalTexture, in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam, float2 scaleMultiplier = float2(1, 1))
				{
					uv = decalUV(m_DecalTextureUV, m_DecalPosition, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale * scaleMultiplier, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					// Adjust derivatives for _ST of decal texture
					float4 dduv = any(fwidth(uv) > .5) ? 0.001 : float4(ddx(uv) * m_DecalTexture_ST.x, ddy(uv) * m_DecalTexture_ST.y);
					decalColor = tex2D(decalTexture, poiUV(uv, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduv.xy, dduv.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					decalColor.a *= decalMask[m_DecalMaskChannel] * applyTilingClipping(m_DecalTiled, uv);
				}
				
				void SampleDecalChannelSeparation(sampler2D decalTexture, in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam)
				{
					decalColor = float4(0, 0, 0, 1);
					decalChannelOffset += m_DecalChannelSeparation + m_DecalChannelSeparationAngleStrength * (m_DecalChannelSeparationAngleStrength > 0 ? (1 - poiLight.nDotV) : poiLight.nDotV);
					float2 positionOffset = decalChannelOffset * 0.01 * (decalScale.x + decalScale.y) * float2(cos(m_DecalChannelSeparationVertical), sin(m_DecalChannelSeparationVertical));
					float2 uvSample0 = decalUV(m_DecalTextureUV, m_DecalPosition + positionOffset, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					float2 uvSample1 = decalUV(m_DecalTextureUV, m_DecalPosition - positionOffset, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					
					float4 dduvSample0 = any(fwidth(uvSample0) > .5) ? 0.001 : float4(ddx(uvSample0) * m_DecalTexture_ST.x, ddy(uvSample0) * m_DecalTexture_ST.y);
					float4 dduvSample1 = any(fwidth(uvSample1) > .5) ? 0.001 : float4(ddx(uvSample1) * m_DecalTexture_ST.x, ddy(uvSample1) * m_DecalTexture_ST.y);
					
					float4 sample0 = tex2D(decalTexture, poiUV(uvSample0, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduvSample0.xy, dduvSample0.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					float4 sample1 = tex2D(decalTexture, poiUV(uvSample1, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduvSample1.xy, dduvSample1.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					
					sample0.rgb = decalHueShift(m_DecalHueShiftEnabled, sample0.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					sample1.rgb = decalHueShift(m_DecalHueShiftEnabled, sample1.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					
					float3 channelSeparationColor = HUEtoRGB(frac(m_DecalChannelSeparationHue));
					
					if (m_DecalChannelSeparationPremultiply)
					{
						decalColor.rgb = lerp(sample0 * sample0.a, sample1 * sample1.a, channelSeparationColor);
					}
					else
					{
						decalColor.rgb = lerp(sample0, sample1, channelSeparationColor);
					}
					decalColor.a = 0.5 * (sample0.a + sample1.a);
					decalColor.a *= decalMask[m_DecalMaskChannel] * max(applyTilingClipping(m_DecalTiled, uvSample0), applyTilingClipping(m_DecalTiled, uvSample1));
				}
				
				void Apply(inout float alphaOverride, inout float decalAlpha, inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, inout PoiMods poiMods, in PoiLight poiLight)
				{
					if (m_DecalGlobalMask > 0)
					{
						decalColor.a = maskBlend(decalColor.a, poiMods.globalMask[m_DecalGlobalMask - 1], m_DecalGlobalMaskBlendType);
					}
					
					float audioLinkDecalAlpha = 0;
					float audioLinkDecalEmission = 0;
					#ifdef POI_AUDIOLINK
					audioLinkDecalEmission = lerp(m_AudioLinkDecalEmission.x, m_AudioLinkDecalEmission.y, poiMods.audioLink[m_AudioLinkDecalEmissionBand]) * poiMods.audioLinkAvailable;
					
					if (m_AudioLinkDecalColorChord)
					{
						if (poiMods.audioLinkAvailable)
						{
							decalColor.rgb *= AudioLinkLerp(ALPASS_CCSTRIP + float2(uv.x * AUDIOLINK_WIDTH, 0)).rgb;
						}
						else
						{
							decalAlpha = 0;
						}
					}
					audioLinkDecalAlpha = lerp(m_AudioLinkDecalAlpha.x, m_AudioLinkDecalAlpha.y, poiMods.audioLink[m_AudioLinkDecalAlphaBand]) * poiMods.audioLinkAvailable;
					#endif
					
					if (m_DecalOverrideAlpha)
					{
						float finalAlpha = lerp(1, min(decalAlpha, decalColor.a), decalMask[m_DecalMaskChannel]);
						if (m_DecalOverrideAlphaMode != 0 && !m_DecalTiled)
						{
							if (uv.x > 0 && uv.x < 1 && uv.y > 0 && uv.y < 1)
							{
								//decalAlpha = lerp(decalAlpha, min(decalAlpha, decalColor.a), decalMask[m_DecalMaskChannel]);
								//poiFragData.alpha = saturate(poiFragData.alpha + lerp(1, min(decalAlpha, decalColor.a), decalMask[m_DecalMaskChannel]));
								if (m_DecalOverrideAlpha == 1) poiFragData.alpha = finalAlpha;
								if (m_DecalOverrideAlpha == 2) poiFragData.alpha = saturate(poiFragData.alpha * finalAlpha);
								if (m_DecalOverrideAlpha == 3) poiFragData.alpha = saturate(poiFragData.alpha + finalAlpha);
								if (m_DecalOverrideAlpha == 4) poiFragData.alpha = saturate(poiFragData.alpha - finalAlpha);
								if (m_DecalOverrideAlpha == 5) poiFragData.alpha = min(poiFragData.alpha, finalAlpha);
								if (m_DecalOverrideAlpha == 6) poiFragData.alpha = max(poiFragData.alpha, finalAlpha);
							}
						}
						else
						{
							if (m_DecalOverrideAlpha == 1) poiFragData.alpha = finalAlpha;
							if (m_DecalOverrideAlpha == 2) poiFragData.alpha = saturate(poiFragData.alpha * finalAlpha);
							if (m_DecalOverrideAlpha == 3) poiFragData.alpha = saturate(poiFragData.alpha + finalAlpha);
							if (m_DecalOverrideAlpha == 4) poiFragData.alpha = saturate(poiFragData.alpha - finalAlpha);
							if (m_DecalOverrideAlpha == 5) poiFragData.alpha = min(poiFragData.alpha, finalAlpha);
							if (m_DecalOverrideAlpha == 6) poiFragData.alpha = max(poiFragData.alpha, finalAlpha);
						}
					}
					
					if (m_DecalFaceMask > 0)
					{
						if (m_DecalFaceMask == 1 && !poiMesh.isFrontFace)
						{
							decalColor.a *= 0;
						}
						else if (m_DecalFaceMask == 2 && poiMesh.isFrontFace)
						{
							decalColor.a *= 0;
						}
					}
					
					float decalAlphaMixed = decalColor.a * saturate(m_DecalBlendAlpha + audioLinkDecalAlpha);
					
					if (m_DecalApplyGlobalMaskIndex > 0)
					{
						applyToGlobalMask(poiMods, m_DecalApplyGlobalMaskIndex - 1, m_DecalApplyGlobalMaskBlendType, decalAlphaMixed);
					}
					
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, decalColor.rgb, m_DecalBlendType), decalAlphaMixed);
					poiFragData.emission += decalColor.rgb * decalColor.a * max(m_DecalEmissionStrength + audioLinkDecalEmission, 0);
				}
				float2 GetVideoAspectRatio(float2 videoDimensions, float CorrectionType, float fitToScale)
				{
					float2 AspectRatioMultiplier = float2(1, 1);
					if (fitToScale)
					{
						float2 decalScale = m_DecalScale.xy + float2(m_DecalSideOffset.x + m_DecalSideOffset.y, m_DecalSideOffset.z + m_DecalSideOffset.w);
						if (decalScale.x > decalScale.y)
						{
							videoDimensions.xy *= float2((decalScale.y / decalScale.x), 1);
						}
						else
						{
							videoDimensions.xy *= float2(1, (decalScale.x / decalScale.y));
						}
					}
					
					if (CorrectionType != 2)
					{
						if (CorrectionType == 0)
						{
							if (videoDimensions.x > videoDimensions.y)
							{
								AspectRatioMultiplier = float2(1, videoDimensions.y / videoDimensions.x);
							}
							else
							{
								AspectRatioMultiplier = float2(videoDimensions.x / videoDimensions.y, 1);
							}
						}
						else if (CorrectionType == 1)
						{
							if (videoDimensions.x > videoDimensions.y)
							{
								AspectRatioMultiplier = float2(1 / (videoDimensions.y / videoDimensions.x), 1);
							}
							else
							{
								AspectRatioMultiplier = float2(1, 1 / (videoDimensions.x / videoDimensions.y));
							}
						}
					}
					return AspectRatioMultiplier;
				}
			};
			
			void applyDecals(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, inout PoiMods poiMods, in PoiLight poiLight)
			{
				// check if _Udon_VideoTex is greater than 16 pixels in width
				float udonVideoTexAvailable = 0;
				float2 udonVideoAspectRatio = 1;
				if (_Udon_VideoTex_TexelSize.z > 16)
				{
					udonVideoTexAvailable = 1;
				}
				
				float decalAlpha = 1;
				float alphaOverride = 0;
				#if defined(PROP_DECALMASK) || !defined(OPTIMIZER_ENABLED)
				float4 decalMask = POI2D_SAMPLER_PAN(_DecalMask, _MainTex, poiUV(poiMesh.uv[_DecalMaskUV], _DecalMask_ST), _DecalMaskPan);
				#else
				float4 decalMask = 1;
				#endif
				
				#ifdef TPS_Penetrator
				if (_DecalTPSDepthMaskEnabled)
				{
					decalMask.r = lerp(0, decalMask.r * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Decal0TPSMaskStrength);
					decalMask.g = lerp(0, decalMask.g * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Decal1TPSMaskStrength);
					decalMask.b = lerp(0, decalMask.b * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Decal2TPSMaskStrength);
					decalMask.a = lerp(0, decalMask.a * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Decal3TPSMaskStrength);
				}
				#endif
				
				float4 decalColor = 1;
				float2 uv = 0;
				// yaes
				
				//ifex _DecalEnabled==0
				#ifdef GEOM_TYPE_BRANCH
				PoiDecal Decal0;
				PoiInitStruct(PoiDecal, Decal0)
				Decal0.m_DecalFaceMask = _Decal0FaceMask;
				Decal0.m_DecalMaskChannel = _Decal0MaskChannel;
				Decal0.m_DecalGlobalMask = _Decal0GlobalMask;
				Decal0.m_DecalGlobalMaskBlendType = _Decal0GlobalMaskBlendType;
				Decal0.m_DecalApplyGlobalMaskIndex = _Decal0ApplyGlobalMaskIndex;
				Decal0.m_DecalApplyGlobalMaskBlendType = _Decal0ApplyGlobalMaskBlendType;
				Decal0.m_DecalTexture_ST = _DecalTexture_ST;
				Decal0.m_DecalTexturePan = _DecalTexturePan;
				Decal0.m_DecalTextureUV = _DecalTextureUV;
				Decal0.m_DecalColor = _DecalColor;
				Decal0.m_DecalColorThemeIndex = _DecalColorThemeIndex;
				Decal0.m_DecalTiled = _DecalTiled;
				Decal0.m_DecalBlendType = _DecalBlendType;
				Decal0.m_DecalRotation = _DecalRotation;
				Decal0.m_DecalScale = _DecalScale;
				Decal0.m_DecalSideOffset = _DecalSideOffset;
				Decal0.m_DecalPosition = _DecalPosition;
				Decal0.m_DecalRotationSpeed = _DecalRotationSpeed;
				Decal0.m_DecalEmissionStrength = _DecalEmissionStrength;
				Decal0.m_DecalBlendAlpha = _DecalBlendAlpha;
				Decal0.m_DecalOverrideAlpha = _DecalOverrideAlpha;
				Decal0.m_DecalHueShiftEnabled = _DecalHueShiftEnabled;
				Decal0.m_DecalHueShift = _DecalHueShift;
				Decal0.m_DecalHueShiftSpeed = _DecalHueShiftSpeed;
				Decal0.m_DecalDepth = _Decal0Depth;
				Decal0.m_DecalHueAngleStrength = _Decal0HueAngleStrength;
				Decal0.m_DecalChannelSeparationEnable = _Decal0ChannelSeparationEnable;
				Decal0.m_DecalChannelSeparation = _Decal0ChannelSeparation;
				Decal0.m_DecalChannelSeparationPremultiply = _Decal0ChannelSeparationPremultiply;
				Decal0.m_DecalChannelSeparationHue = _Decal0ChannelSeparationHue;
				Decal0.m_DecalChannelSeparationVertical = _Decal0ChannelSeparationVertical;
				Decal0.m_DecalChannelSeparationAngleStrength = _Decal0ChannelSeparationAngleStrength;
				Decal0.m_DecalOverrideAlphaMode = _Decal0OverrideAlphaMode;
				
				Decal0.Init(decalMask);
				
				#if defined(POI_AUDIOLINK)
				Decal0.m_AudioLinkDecalScaleBand = _AudioLinkDecal0ScaleBand;
				Decal0.m_AudioLinkDecalScale = _AudioLinkDecal0Scale;
				Decal0.m_AudioLinkDecalRotationBand = _AudioLinkDecal0RotationBand;
				Decal0.m_AudioLinkDecalRotation = _AudioLinkDecal0Rotation;
				Decal0.m_AudioLinkDecalAlphaBand = _AudioLinkDecal0AlphaBand;
				Decal0.m_AudioLinkDecalAlpha = _AudioLinkDecal0Alpha;
				Decal0.m_AudioLinkDecalEmissionBand = _AudioLinkDecal0EmissionBand;
				Decal0.m_AudioLinkDecalEmission = _AudioLinkDecal0Emission;
				Decal0.m_DecalRotationCTALBand = _DecalRotationCTALBand0;
				Decal0.m_DecalRotationCTALSpeed = _DecalRotationCTALSpeed0;
				Decal0.m_DecalRotationCTALType = _DecalRotationCTALType0;
				Decal0.m_AudioLinkDecalColorChord = _AudioLinkDecalCC0;
				Decal0.m_AudioLinkDecalSideBand = _AudioLinkDecal0SideBand;
				Decal0.m_AudioLinkDecalSideMin = _AudioLinkDecal0SideMin;
				Decal0.m_AudioLinkDecalSideMax = _AudioLinkDecal0SideMax;
				Decal0.m_AudioLinkDecalChannelSeparation = _AudioLinkDecal0ChannelSeparation;
				Decal0.m_AudioLinkDecalChannelSeparationBand = _AudioLinkDecal0ChannelSeparationBand;
				
				Decal0.InitAudiolink(poiMods);
				#endif
				
				if (!_Decal0VideoEnabled)
				{
					
					#if defined(PROP_DECALTEXTURE) || !defined(OPTIMIZER_ENABLED)
					//ifex _Decal0ChannelSeparationEnable==0
					if (_Decal0ChannelSeparationEnable)
					{
						Decal0.SampleDecalChannelSeparation(_DecalTexture, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					//ifex _Decal0ChannelSeparationEnable==1
					if (!_Decal0ChannelSeparationEnable)
					{
						Decal0.SampleDecal(_DecalTexture, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					#else
					Decal0.SampleDecalNoTexture(poiMods, poiLight, poiMesh, poiCam);
					#endif
					Decal0.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
				}
				else
				{
					udonVideoAspectRatio = Decal0.GetVideoAspectRatio(_Udon_VideoTex_TexelSize.zw, _Decal0VideoAspectFix, _Decal0VideoFitToScale);
					
					if (_Decal0OnlyVideo)
					{
						if (udonVideoTexAvailable)
						{
							Decal0.m_DecalEmissionStrength += _Decal0VideoEmissionStrength;
							if (_Decal0UseDecalAlpha)
							{
								Decal0.SampleDecal(_DecalTexture, poiMods, poiLight, poiMesh, poiCam);
								Decal0.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal0.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							Decal0.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
						}
					}
					else
					{
						Decal0.SampleDecal(_DecalTexture, poiMods, poiLight, poiMesh, poiCam);
						if (udonVideoTexAvailable)
						{
							Decal0.m_DecalEmissionStrength += _Decal0VideoEmissionStrength;
							if (_Decal0UseDecalAlpha)
							{
								Decal0.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal0.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
						}
						Decal0.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
					}
				}
				#endif
				//endex
				
				//ifex _DecalEnabled1==0
				#ifdef GEOM_TYPE_BRANCH_DETAIL
				PoiDecal Decal1;
				PoiInitStruct(PoiDecal, Decal1)
				Decal1.m_DecalFaceMask = _Decal1FaceMask;
				Decal1.m_DecalMaskChannel = _Decal1MaskChannel;
				Decal1.m_DecalGlobalMask = _Decal1GlobalMask;
				Decal1.m_DecalGlobalMaskBlendType = _Decal1GlobalMaskBlendType;
				Decal1.m_DecalApplyGlobalMaskIndex = _Decal1ApplyGlobalMaskIndex;
				Decal1.m_DecalApplyGlobalMaskBlendType = _Decal1ApplyGlobalMaskBlendType;
				Decal1.m_DecalTexture_ST = _DecalTexture1_ST;
				Decal1.m_DecalTexturePan = _DecalTexture1Pan;
				Decal1.m_DecalTextureUV = _DecalTexture1UV;
				Decal1.m_DecalColor = _DecalColor1;
				Decal1.m_DecalColorThemeIndex = _DecalColor1ThemeIndex;
				Decal1.m_DecalTiled = _DecalTiled1;
				Decal1.m_DecalBlendType = _DecalBlendType1;
				Decal1.m_DecalRotation = _DecalRotation1;
				Decal1.m_DecalScale = _DecalScale1;
				Decal1.m_DecalSideOffset = _DecalSideOffset1;
				Decal1.m_DecalPosition = _DecalPosition1;
				Decal1.m_DecalRotationSpeed = _DecalRotationSpeed1;
				Decal1.m_DecalEmissionStrength = _DecalEmissionStrength1;
				Decal1.m_DecalBlendAlpha = _DecalBlendAlpha1;
				Decal1.m_DecalOverrideAlpha = _DecalOverrideAlpha1;
				Decal1.m_DecalHueShiftEnabled = _DecalHueShiftEnabled1;
				Decal1.m_DecalHueShift = _DecalHueShift1;
				Decal1.m_DecalHueShiftSpeed = _DecalHueShiftSpeed1;
				Decal1.m_DecalDepth = _Decal1Depth;
				Decal1.m_DecalHueAngleStrength = _Decal1HueAngleStrength;
				Decal1.m_DecalChannelSeparationEnable = _Decal1ChannelSeparationEnable;
				Decal1.m_DecalChannelSeparation = _Decal1ChannelSeparation;
				Decal1.m_DecalChannelSeparationPremultiply = _Decal1ChannelSeparationPremultiply;
				Decal1.m_DecalChannelSeparationHue = _Decal1ChannelSeparationHue;
				Decal1.m_DecalChannelSeparationVertical = _Decal1ChannelSeparationVertical;
				Decal1.m_DecalChannelSeparationAngleStrength = _Decal1ChannelSeparationAngleStrength;
				Decal1.m_DecalOverrideAlphaMode = _Decal1OverrideAlphaMode;
				Decal1.Init(decalMask);
				
				#if defined(POI_AUDIOLINK)
				Decal1.m_AudioLinkDecalScaleBand = _AudioLinkDecal1ScaleBand;
				Decal1.m_AudioLinkDecalScale = _AudioLinkDecal1Scale;
				Decal1.m_AudioLinkDecalRotationBand = _AudioLinkDecal1RotationBand;
				Decal1.m_AudioLinkDecalRotation = _AudioLinkDecal1Rotation;
				Decal1.m_AudioLinkDecalAlphaBand = _AudioLinkDecal1AlphaBand;
				Decal1.m_AudioLinkDecalAlpha = _AudioLinkDecal1Alpha;
				Decal1.m_AudioLinkDecalEmissionBand = _AudioLinkDecal1EmissionBand;
				Decal1.m_AudioLinkDecalEmission = _AudioLinkDecal1Emission;
				Decal1.m_DecalRotationCTALBand = _DecalRotationCTALBand1;
				Decal1.m_DecalRotationCTALSpeed = _DecalRotationCTALSpeed1;
				Decal1.m_DecalRotationCTALType = _DecalRotationCTALType1;
				Decal1.m_AudioLinkDecalColorChord = _AudioLinkDecalCC1;
				Decal1.m_AudioLinkDecalSideBand = _AudioLinkDecal1SideBand;
				Decal1.m_AudioLinkDecalSideMin = _AudioLinkDecal1SideMin;
				Decal1.m_AudioLinkDecalSideMax = _AudioLinkDecal1SideMax;
				Decal1.m_AudioLinkDecalChannelSeparation = _AudioLinkDecal1ChannelSeparation;
				Decal1.m_AudioLinkDecalChannelSeparationBand = _AudioLinkDecal1ChannelSeparationBand;
				
				Decal1.InitAudiolink(poiMods);
				#endif
				
				if (!_Decal1VideoEnabled)
				{
					#if defined(PROP_DECALTEXTURE1) || !defined(OPTIMIZER_ENABLED)
					//ifex _Decal1ChannelSeparationEnable==0
					if (_Decal1ChannelSeparationEnable)
					{
						Decal1.SampleDecalChannelSeparation(_DecalTexture1, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					//ifex _Decal1ChannelSeparationEnable==1
					if (!_Decal1ChannelSeparationEnable)
					{
						Decal1.SampleDecal(_DecalTexture1, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					#else
					Decal1.SampleDecalNoTexture(poiMods, poiLight, poiMesh, poiCam);
					#endif
					Decal1.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
				}
				else
				{
					udonVideoAspectRatio = Decal1.GetVideoAspectRatio(_Udon_VideoTex_TexelSize.zw, _Decal1VideoAspectFix, _Decal1VideoFitToScale);
					if (_Decal1OnlyVideo)
					{
						if (udonVideoTexAvailable)
						{
							Decal1.m_DecalEmissionStrength += _Decal1VideoEmissionStrength;
							if (_Decal1UseDecalAlpha)
							{
								Decal1.SampleDecal(_DecalTexture1, poiMods, poiLight, poiMesh, poiCam);
								Decal1.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal1.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							Decal1.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
						}
					}
					else
					{
						Decal1.SampleDecal(_DecalTexture1, poiMods, poiLight, poiMesh, poiCam);
						if (udonVideoTexAvailable)
						{
							Decal1.m_DecalEmissionStrength += _Decal1VideoEmissionStrength;
							if (_Decal1UseDecalAlpha)
							{
								Decal1.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal1.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
						}
						Decal1.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
					}
				}
				#endif
				//endex
				
				//ifex _DecalEnabled2==0
				#ifdef GEOM_TYPE_FROND
				PoiDecal Decal2;
				PoiInitStruct(PoiDecal, Decal2)
				Decal2.m_DecalFaceMask = _Decal2FaceMask;
				Decal2.m_DecalMaskChannel = _Decal2MaskChannel;
				Decal2.m_DecalGlobalMask = _Decal2GlobalMask;
				Decal2.m_DecalGlobalMaskBlendType = _Decal2GlobalMaskBlendType;
				Decal2.m_DecalApplyGlobalMaskIndex = _Decal2ApplyGlobalMaskIndex;
				Decal2.m_DecalApplyGlobalMaskBlendType = _Decal2ApplyGlobalMaskBlendType;
				Decal2.m_DecalTexture_ST = _DecalTexture2_ST;
				Decal2.m_DecalTexturePan = _DecalTexture2Pan;
				Decal2.m_DecalTextureUV = _DecalTexture2UV;
				Decal2.m_DecalColor = _DecalColor2;
				Decal2.m_DecalColorThemeIndex = _DecalColor2ThemeIndex;
				Decal2.m_DecalTiled = _DecalTiled2;
				Decal2.m_DecalBlendType = _DecalBlendType2;
				Decal2.m_DecalRotation = _DecalRotation2;
				Decal2.m_DecalScale = _DecalScale2;
				Decal2.m_DecalSideOffset = _DecalSideOffset2;
				Decal2.m_DecalPosition = _DecalPosition2;
				Decal2.m_DecalRotationSpeed = _DecalRotationSpeed2;
				Decal2.m_DecalEmissionStrength = _DecalEmissionStrength2;
				Decal2.m_DecalBlendAlpha = _DecalBlendAlpha2;
				Decal2.m_DecalOverrideAlpha = _DecalOverrideAlpha2;
				Decal2.m_DecalHueShiftEnabled = _DecalHueShiftEnabled2;
				Decal2.m_DecalHueShift = _DecalHueShift2;
				Decal2.m_DecalHueShiftSpeed = _DecalHueShiftSpeed2;
				Decal2.m_DecalDepth = _Decal2Depth;
				Decal2.m_DecalHueAngleStrength = _Decal2HueAngleStrength;
				Decal2.m_DecalChannelSeparationEnable = _Decal2ChannelSeparationEnable;
				Decal2.m_DecalChannelSeparation = _Decal2ChannelSeparation;
				Decal2.m_DecalChannelSeparationPremultiply = _Decal2ChannelSeparationPremultiply;
				Decal2.m_DecalChannelSeparationHue = _Decal2ChannelSeparationHue;
				Decal2.m_DecalChannelSeparationVertical = _Decal2ChannelSeparationVertical;
				Decal2.m_DecalChannelSeparationAngleStrength = _Decal2ChannelSeparationAngleStrength;
				Decal2.m_DecalOverrideAlphaMode = _Decal2OverrideAlphaMode;
				Decal2.Init(decalMask);
				
				#if defined(POI_AUDIOLINK)
				Decal2.m_AudioLinkDecalScaleBand = _AudioLinkDecal2ScaleBand;
				Decal2.m_AudioLinkDecalScale = _AudioLinkDecal2Scale;
				Decal2.m_AudioLinkDecalRotationBand = _AudioLinkDecal2RotationBand;
				Decal2.m_AudioLinkDecalRotation = _AudioLinkDecal2Rotation;
				Decal2.m_AudioLinkDecalAlphaBand = _AudioLinkDecal2AlphaBand;
				Decal2.m_AudioLinkDecalAlpha = _AudioLinkDecal2Alpha;
				Decal2.m_AudioLinkDecalEmissionBand = _AudioLinkDecal2EmissionBand;
				Decal2.m_AudioLinkDecalEmission = _AudioLinkDecal2Emission;
				Decal2.m_DecalRotationCTALBand = _DecalRotationCTALBand2;
				Decal2.m_DecalRotationCTALSpeed = _DecalRotationCTALSpeed2;
				Decal2.m_DecalRotationCTALType = _DecalRotationCTALType2;
				Decal2.m_AudioLinkDecalColorChord = _AudioLinkDecalCC2;
				Decal2.m_AudioLinkDecalSideBand = _AudioLinkDecal2SideBand;
				Decal2.m_AudioLinkDecalSideMin = _AudioLinkDecal2SideMin;
				Decal2.m_AudioLinkDecalSideMax = _AudioLinkDecal2SideMax;
				Decal2.m_AudioLinkDecalChannelSeparation = _AudioLinkDecal2ChannelSeparation;
				Decal2.m_AudioLinkDecalChannelSeparationBand = _AudioLinkDecal2ChannelSeparationBand;
				
				Decal2.InitAudiolink(poiMods);
				#endif
				if (!_Decal2VideoEnabled)
				{
					#if defined(PROP_DECALTEXTURE2) || !defined(OPTIMIZER_ENABLED)
					//ifex _Decal2ChannelSeparationEnable==0
					if (_Decal2ChannelSeparationEnable)
					{
						Decal2.SampleDecalChannelSeparation(_DecalTexture2, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					//ifex _Decal2ChannelSeparationEnable==1
					if (!_Decal2ChannelSeparationEnable)
					{
						Decal2.SampleDecal(_DecalTexture2, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					#else
					Decal2.SampleDecalNoTexture(poiMods, poiLight, poiMesh, poiCam);
					#endif
					Decal2.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
				}
				else
				{
					udonVideoAspectRatio = Decal2.GetVideoAspectRatio(_Udon_VideoTex_TexelSize.zw, _Decal2VideoAspectFix, _Decal2VideoFitToScale);
					if (_Decal2OnlyVideo)
					{
						if (udonVideoTexAvailable)
						{
							Decal2.m_DecalEmissionStrength += _Decal2VideoEmissionStrength;
							if (_Decal2UseDecalAlpha)
							{
								Decal2.SampleDecal(_DecalTexture2, poiMods, poiLight, poiMesh, poiCam);
								Decal2.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal2.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							Decal2.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
						}
					}
					else
					{
						Decal2.SampleDecal(_DecalTexture2, poiMods, poiLight, poiMesh, poiCam);
						if (udonVideoTexAvailable)
						{
							Decal2.m_DecalEmissionStrength += _Decal2VideoEmissionStrength;
							if (_Decal2UseDecalAlpha)
							{
								Decal2.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal2.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
						}
						Decal2.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
					}
				}
				#endif
				//endex
				
				//ifex _DecalEnabled3==0
				#ifdef DEPTH_OF_FIELD_COC_VIEW
				PoiDecal Decal3;
				PoiInitStruct(PoiDecal, Decal3)
				Decal3.m_DecalFaceMask = _Decal3FaceMask;
				Decal3.m_DecalMaskChannel = _Decal3MaskChannel;
				Decal3.m_DecalGlobalMask = _Decal3GlobalMask;
				Decal3.m_DecalGlobalMaskBlendType = _Decal3GlobalMaskBlendType;
				Decal3.m_DecalApplyGlobalMaskIndex = _Decal3ApplyGlobalMaskIndex;
				Decal3.m_DecalApplyGlobalMaskBlendType = _Decal3ApplyGlobalMaskBlendType;
				Decal3.m_DecalTexture_ST = _DecalTexture3_ST;
				Decal3.m_DecalTexturePan = _DecalTexture3Pan;
				Decal3.m_DecalTextureUV = _DecalTexture3UV;
				Decal3.m_DecalColor = _DecalColor3;
				Decal3.m_DecalColorThemeIndex = _DecalColor3ThemeIndex;
				Decal3.m_DecalTiled = _DecalTiled3;
				Decal3.m_DecalBlendType = _DecalBlendType3;
				Decal3.m_DecalRotation = _DecalRotation3;
				Decal3.m_DecalScale = _DecalScale3;
				Decal3.m_DecalSideOffset = _DecalSideOffset3;
				Decal3.m_DecalPosition = _DecalPosition3;
				Decal3.m_DecalRotationSpeed = _DecalRotationSpeed3;
				Decal3.m_DecalEmissionStrength = _DecalEmissionStrength3;
				Decal3.m_DecalBlendAlpha = _DecalBlendAlpha3;
				Decal3.m_DecalOverrideAlpha = _DecalOverrideAlpha3;
				Decal3.m_DecalHueShiftEnabled = _DecalHueShiftEnabled3;
				Decal3.m_DecalHueShift = _DecalHueShift3;
				Decal3.m_DecalHueShiftSpeed = _DecalHueShiftSpeed3;
				Decal3.m_DecalDepth = _Decal3Depth;
				Decal3.m_DecalHueAngleStrength = _Decal3HueAngleStrength;
				Decal3.m_DecalChannelSeparationEnable = _Decal3ChannelSeparationEnable;
				Decal3.m_DecalChannelSeparation = _Decal3ChannelSeparation;
				Decal3.m_DecalChannelSeparationPremultiply = _Decal3ChannelSeparationPremultiply;
				Decal3.m_DecalChannelSeparationHue = _Decal3ChannelSeparationHue;
				Decal3.m_DecalChannelSeparationVertical = _Decal3ChannelSeparationVertical;
				Decal3.m_DecalChannelSeparationAngleStrength = _Decal3ChannelSeparationAngleStrength;
				Decal3.m_DecalOverrideAlphaMode = _Decal3OverrideAlphaMode;
				Decal3.Init(decalMask);
				
				#if defined(POI_AUDIOLINK)
				Decal3.m_AudioLinkDecalScaleBand = _AudioLinkDecal3ScaleBand;
				Decal3.m_AudioLinkDecalScale = _AudioLinkDecal3Scale;
				Decal3.m_AudioLinkDecalRotationBand = _AudioLinkDecal3RotationBand;
				Decal3.m_AudioLinkDecalRotation = _AudioLinkDecal3Rotation;
				Decal3.m_AudioLinkDecalAlphaBand = _AudioLinkDecal3AlphaBand;
				Decal3.m_AudioLinkDecalAlpha = _AudioLinkDecal3Alpha;
				Decal3.m_AudioLinkDecalEmissionBand = _AudioLinkDecal3EmissionBand;
				Decal3.m_AudioLinkDecalEmission = _AudioLinkDecal3Emission;
				Decal3.m_DecalRotationCTALBand = _DecalRotationCTALBand3;
				Decal3.m_DecalRotationCTALSpeed = _DecalRotationCTALSpeed3;
				Decal3.m_DecalRotationCTALType = _DecalRotationCTALType3;
				Decal3.m_AudioLinkDecalColorChord = _AudioLinkDecalCC3;
				Decal3.m_AudioLinkDecalSideBand = _AudioLinkDecal3SideBand;
				Decal3.m_AudioLinkDecalSideMin = _AudioLinkDecal3SideMin;
				Decal3.m_AudioLinkDecalSideMax = _AudioLinkDecal3SideMax;
				Decal3.m_AudioLinkDecalChannelSeparation = _AudioLinkDecal3ChannelSeparation;
				Decal3.m_AudioLinkDecalChannelSeparationBand = _AudioLinkDecal3ChannelSeparationBand;
				
				Decal3.InitAudiolink(poiMods);
				#endif
				if (!_Decal3VideoEnabled)
				{
					#if defined(PROP_DECALTEXTURE3) || !defined(OPTIMIZER_ENABLED)
					//ifex _Decal3ChannelSeparationEnable==0
					if (_Decal3ChannelSeparationEnable)
					{
						Decal3.SampleDecalChannelSeparation(_DecalTexture3, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					//ifex _Decal3ChannelSeparationEnable==1
					if (!_Decal3ChannelSeparationEnable)
					{
						Decal3.SampleDecal(_DecalTexture3, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					#else
					Decal3.SampleDecalNoTexture(poiMods, poiLight, poiMesh, poiCam);
					#endif
					Decal3.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
				}
				else
				{
					udonVideoAspectRatio = Decal3.GetVideoAspectRatio(_Udon_VideoTex_TexelSize.zw, _Decal3VideoAspectFix, _Decal3VideoFitToScale);
					if (_Decal3OnlyVideo)
					{
						if (udonVideoTexAvailable)
						{
							Decal3.m_DecalEmissionStrength += _Decal3VideoEmissionStrength;
							if (_Decal3UseDecalAlpha)
							{
								Decal3.SampleDecal(_DecalTexture3, poiMods, poiLight, poiMesh, poiCam);
								Decal3.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal3.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							Decal3.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
						}
					}
					else
					{
						Decal3.SampleDecal(_DecalTexture3, poiMods, poiLight, poiMesh, poiCam);
						if (udonVideoTexAvailable)
						{
							Decal3.m_DecalEmissionStrength += _Decal3VideoEmissionStrength;
							if (_Decal3UseDecalAlpha)
							{
								Decal3.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal3.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
						}
						Decal3.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
					}
				}
				#endif
				//endex
				//if (alphaOverride)
				//{
				
				//poiFragData.baseColor = decalAlpha;
				//poiFragData.alpha *= decalAlpha;
				
				//}
				//poiFragData.baseColor = saturate(poiFragData.baseColor);
				
			}
			#endif
			
			//ifex _EnableDissolve==0
			#ifdef DISTORT
			void applyDissolve(inout PoiFragData poiFragData, in PoiMesh poiMesh, inout PoiMods poiMods, in PoiCam poiCam, in PoiLight poiLight)
			{
				#if defined(PROP_DISSOLVEMASK) || !defined(OPTIMIZER_ENABLED)
				float dissolveMask = POI2D_SAMPLER_PAN(_DissolveMask, _MainTex, poiUV(poiMesh.uv[_DissolveMaskUV], _DissolveMask_ST), _DissolveMaskPan).r;
				#else
				float dissolveMask = 1;
				#endif
				UNITY_BRANCH
				if (_DissolveUseVertexColors > 0)
				{
					// Vertex Color Imprecision hype
					dissolveMask = ceil(poiMesh.vertexColor[_DissolveUseVertexColors] * 100000) / 100000;
				}
				if (_DissolveMaskGlobalMask > 0)
				{
					dissolveMask = maskBlend(dissolveMask, poiMods.globalMask[_DissolveMaskGlobalMask - 1], _DissolveMaskGlobalMaskBlendType);
				}
				
				#if defined(PROP_DISSOLVETOTEXTURE) || !defined(OPTIMIZER_ENABLED)
				dissolveToTexture = POI2D_SAMPLER_PAN(_DissolveToTexture, _MainTex, poiUV(poiMesh.uv[_DissolveToTextureUV], _DissolveToTexture_ST), _DissolveToTexturePan) * float4(poiThemeColor(poiMods, _DissolveTextureColor.rgb, _DissolveTextureColorThemeIndex), _DissolveTextureColor.a);
				#else
				dissolveToTexture = _DissolveTextureColor;
				#endif
				
				#if defined(PROP_DISSOLVENOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
				float dissolveNoiseTexture = POI2D_SAMPLER_PAN(_DissolveNoiseTexture, _MainTex, poiUV(poiMesh.uv[_DissolveNoiseTextureUV], _DissolveNoiseTexture_ST), _DissolveNoiseTexturePan).r;
				#else
				float dissolveNoiseTexture = 1;
				#endif
				
				float da = _DissolveAlpha
				+ _DissolveAlpha0
				+ _DissolveAlpha1
				+ _DissolveAlpha2
				+ _DissolveAlpha3
				+ _DissolveAlpha4
				+ _DissolveAlpha5
				+ _DissolveAlpha6
				+ _DissolveAlpha7
				+ _DissolveAlpha8
				+ _DissolveAlpha9;
				float dds = _DissolveDetailStrength;
				
				if (_UVTileDissolveEnabled)
				{
					float2 udim = floor(poiMesh.uv[(int)_UVTileDissolveUV]);
					
					float4 xMask = float4((udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					da += (udim.y >= 0 && udim.y < 1) * dot(float4(_UVTileDissolveAlpha_Row0_0, _UVTileDissolveAlpha_Row0_1, _UVTileDissolveAlpha_Row0_2, _UVTileDissolveAlpha_Row0_3), xMask);
					da += (udim.y >= 1 && udim.y < 2) * dot(float4(_UVTileDissolveAlpha_Row1_0, _UVTileDissolveAlpha_Row1_1, _UVTileDissolveAlpha_Row1_2, _UVTileDissolveAlpha_Row1_3), xMask);
					da += (udim.y >= 2 && udim.y < 3) * dot(float4(_UVTileDissolveAlpha_Row2_0, _UVTileDissolveAlpha_Row2_1, _UVTileDissolveAlpha_Row2_2, _UVTileDissolveAlpha_Row2_3), xMask);
					da += (udim.y >= 3 && udim.y < 4) * dot(float4(_UVTileDissolveAlpha_Row3_0, _UVTileDissolveAlpha_Row3_1, _UVTileDissolveAlpha_Row3_2, _UVTileDissolveAlpha_Row3_3), xMask);
				}
				
				#ifdef POI_AUDIOLINK
				UNITY_BRANCH
				if (_EnableDissolveAudioLink && poiMods.audioLinkAvailable)
				{
					da += lerp(_AudioLinkDissolveAlpha.x, _AudioLinkDissolveAlpha.y, poiMods.audioLink[_AudioLinkDissolveAlphaBand]);
					dds += lerp(_AudioLinkDissolveDetail.x, _AudioLinkDissolveDetail.y, poiMods.audioLink[_AudioLinkDissolveDetailBand]);
				}
				#endif
				
				da = saturate(da);
				dds = saturate(dds);
				
				if (_DissolveMaskInvert)
				{
					dissolveMask = 1 - dissolveMask;
				}
				#if defined(PROP_DISSOLVEDETAILNOISE) || !defined(OPTIMIZER_ENABLED)
				float dissolveDetailNoise = POI2D_SAMPLER_PAN(_DissolveDetailNoise, _MainTex, poiUV(poiMesh.uv[_DissolveDetailNoiseUV], _DissolveDetailNoise_ST), _DissolveDetailNoisePan);
				#else
				float dissolveDetailNoise = 0;
				#endif
				if (_DissolveInvertNoise)
				{
					dissolveNoiseTexture = 1 - dissolveNoiseTexture;
				}
				if (_DissolveInvertDetailNoise)
				{
					dissolveDetailNoise = 1 - dissolveDetailNoise;
				}
				if (_ContinuousDissolve != 0)
				{
					da = sin(_Time.x * _ContinuousDissolve) * .5 + .5;
				}
				da *= dissolveMask;
				dissolveAlpha = da;
				edgeAlpha = 0;
				
				[flatten]
				switch(_DissolveType)
				{
					default: // Basic (case 1)
					
					{
						da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						dissolveAlpha = da;
						//Adjust detail strength to avoid artifacts
						dds *= smoothstep(1, 0.99, da) * lerp(1, smoothstep(0, lerp(0.01, 0.1, dds), da), _DissolveDetailEdgeSmoothing);
						float noise = saturate(dissolveNoiseTexture - dissolveDetailNoise * dds);
						
						noise = saturate(noise * 0.998 + 0.001);
						dissolveAlpha = dissolveAlpha >= noise;
						edgeAlpha = remapClamped(da + _DissolveEdgeWidth, da, noise) * (1 - dissolveAlpha);
						break;
					}
					case 2: // Point to Point
					
					{
						float3 direction;
						float3 currentPos;
						float distanceTo = 0;
						direction = normalize(_DissolveEndPoint - _DissolveStartPoint);
						currentPos = lerp(_DissolveStartPoint, _DissolveEndPoint, dissolveAlpha);
						
						UNITY_BRANCH
						if (_DissolveP2PWorldLocal != 1)
						{
							float3 pos = _DissolveP2PWorldLocal == 0 ? poiMesh.localPos.rgb : poiMesh.vertexColor.rgb;
							distanceTo = dot(pos - currentPos, direction) - dissolveDetailNoise * dds;
							edgeAlpha = smoothstep(_DissolveP2PEdgeLength + .00001, 0, distanceTo);
							dissolveAlpha = step(distanceTo, 0);
							edgeAlpha *= 1 - dissolveAlpha;
						}
						else
						{
							distanceTo = dot(poiMesh.worldPos - currentPos, direction) - dissolveDetailNoise * dds;
							edgeAlpha = smoothstep(_DissolveP2PEdgeLength + .00001, 0, distanceTo);
							dissolveAlpha = (distanceTo < 0) ? 1 : 0;
							edgeAlpha *= 1 - dissolveAlpha;
						}
						
						if (_DissolveP2PClamp)
						{
							dissolveAlpha = saturate(dissolveAlpha * smoothstep(0, 0.01, da) + smoothstep(0.99, 1, da));
							edgeAlpha *= smoothstep(0, 0.01, da);
						}
						
						break;
					}
					case 3: // Spherical
					
					{
						if (_SphericalDissolveInvert)
						{
							da = remap(da, 1, 0, -_DissolveEdgeWidth, 1);
						}
						else
						{
							da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						}
						
						dissolveAlpha = da;
						dds *= smoothstep(0, 0.2 * dds + 0.01, dissolveAlpha) * lerp(1, smoothstep(1, 1 - 0.2 * dds - 0.01, dissolveAlpha), _DissolveDetailEdgeSmoothing);
						float currentDistance = lerp(0, _SphericalDissolveRadius, dissolveAlpha);
						float fragDistance = distance(_SphericalDissolveCenter, poiMesh.localPos.xyz);
						float normalizedDistance;
						normalizedDistance = (fragDistance - currentDistance) / (_SphericalDissolveRadius + 0.0001) - dissolveDetailNoise * dds;
						
						if (_SphericalDissolveInvert)
						{
							dissolveAlpha = (normalizedDistance > 0) ? 1 : 0;
							edgeAlpha = smoothstep(_DissolveEdgeWidth + .00001, 0, -normalizedDistance);
						}
						else
						{
							dissolveAlpha = (normalizedDistance < 0) ? 1 : 0;
							edgeAlpha = smoothstep(_DissolveEdgeWidth + .00001, 0, normalizedDistance);
						}
						
						if (_SphericalDissolveClamp)
						{
							da = lerp(da, 1 - da, _SphericalDissolveInvert);
							dissolveAlpha = saturate(dissolveAlpha * smoothstep(0, 0.01, da) + smoothstep(0.99, 1, da));
							edgeAlpha *= smoothstep(0, 0.01, da);
						}
						
						break;
					}
					case 4: // CenterOut
					
					{
						float ramp = 0.5;
						float noise;
						
						[flatten]
						switch(_CenterOutDissolveMode)
						{
							case 1: // View Direction
							
							{
								ramp = saturate(lerp(poiLight.vertexNDotV, poiLight.nDotV, _CenterOutDissolveNormals));
								break;
							}
							case 2: // Custom Direction
							
							{
								ramp = dot(normalize(_CenterOutDissolveDirection), lerp(poiMesh.normals[0], poiMesh.normals[1], _CenterOutDissolveNormals));
								ramp = saturate(ramp * .5 + 0.5);
								break;
							}
							case 3: // Light Direction
							
							{
								ramp = lerp(poiLight.vertexNDotL, poiLight.nDotL, _CenterOutDissolveNormals);
								ramp = saturate(ramp * .5 + 0.5);
								break;
							}
						}
						
						if (_CenterOutDissolvePower != 1)
						{
							ramp = pow(ramp, _CenterOutDissolvePower);
						}
						
						if (!_CenterOutDissolveInvert)
						{
							ramp = 1 - ramp;
						}
						
						da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						dissolveAlpha = da;
						//Adjust detail strength to avoid artifacts
						dds *= smoothstep(1, 0.99, da) * lerp(1, smoothstep(0, lerp(0.01, 0.1, dds), da), _DissolveDetailEdgeSmoothing);
						
						noise = saturate(ramp - dissolveDetailNoise * dds);
						noise = saturate(noise * 0.998 + 0.001);
						dissolveAlpha = dissolveAlpha >= noise;
						edgeAlpha = remapClamped(da + _DissolveEdgeWidth, da, noise) * (1 - dissolveAlpha);
						break;
					}
				}
				
				#ifndef POI_SHADOW
				UNITY_BRANCH
				if (_DissolveHueShiftEnabled)
				{
					dissolveToTexture.rgb = hueShift(dissolveToTexture.rgb, _DissolveHueShift + _Time.x * _DissolveHueShiftSpeed);
				}
				#endif
				
				poiFragData.alpha = lerp(poiFragData.alpha, dissolveToTexture.a, dissolveAlpha * .999999);
				
				#if !defined(POI_PASS_OUTLINE) && !defined(UNITY_PASS_SHADOWCASTER)
				poiFragData.baseColor = lerp(poiFragData.baseColor, dissolveToTexture.rgb, dissolveAlpha * .999999);
				
				if (_DissolveApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _DissolveApplyGlobalMaskIndex - 1, _DissolveApplyGlobalMaskBlendType, dissolveAlpha * .999999);
				}
				if (_DissolveInverseApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _DissolveInverseApplyGlobalMaskIndex - 1, _DissolveInverseApplyGlobalMaskBlendType, 1-(dissolveAlpha * .999999));
				}
				UNITY_BRANCH
				if (_DissolveEdgeWidth || (_DissolveType == 2 && _DissolveP2PEdgeLength != 0))
				{
					edgeColor = tex2D(_DissolveEdgeGradient, poiUV(float2(edgeAlpha, edgeAlpha), _DissolveEdgeGradient_ST)) * float4(poiThemeColor(poiMods, _DissolveEdgeColor.rgb, _DissolveEdgeColorThemeIndex), _DissolveEdgeColor.a);
					#ifndef POI_SHADOW
					UNITY_BRANCH
					if (_DissolveEdgeHueShiftEnabled)
					{
						edgeColor.rgb = hueShift(edgeColor.rgb, _DissolveEdgeHueShift + _Time.x * _DissolveEdgeHueShiftSpeed);
					}
					#endif
					poiFragData.baseColor = lerp(poiFragData.baseColor, edgeColor.rgb, smoothstep(0, 1 - _DissolveEdgeHardness * .99999999999, edgeAlpha));
				}
				
				poiFragData.emission += lerp(0, dissolveToTexture * _DissolveToEmissionStrength, dissolveAlpha) + lerp(0, edgeColor.rgb * _DissolveEdgeEmission, smoothstep(0, 1 - _DissolveEdgeHardness * .99999999999, edgeAlpha));
				#endif
			}
			#endif
			//endex
			
			//ifex _EnableAniso==0
			#ifdef POI_ANISOTROPICS
			/*
			float D_GGX_Anisotropic(float at, float ab, float TdotH, float BdotH, float NdotH)
			{
				// Burley 2012, "Physically-Based Shading at Disney"
				
				// The values at and ab are perceptualRoughness^2, a2 is therefore perceptualRoughness^4
				// The dot product below computes perceptualRoughness^8. We cannot fit in fp16 without clamping
				// the roughness to too high values so we perform the dot product and the division in fp32
				float a2 = at * ab;
				float3 d = float3(ab * TdotH, at * BdotH, a2 * NdotH);
				float d2 = dot(d, d);
				float b2 = a2 / d2;
				return a2 * b2 * b2 * (1.0 / UNITY_PI);
			}
			
			//-------------------------------------GGX Anisotropic visibility function
			float V_SmithGGXCorrelated_Anisotropic(float at, float ab, float TdotV, float BdotV, float TdotL, float BdotL, float NdotV, float NdotL)
			{
				// Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"
				float lambdaV = NdotL * length(float3(at * TdotV, ab * BdotV, NdotV));
				float lambdaL = NdotV * length(float3(at * TdotL, ab * BdotL, NdotL));
				return 0.5 / (lambdaV + lambdaL);
			}
			*/
			
			float calculateAnisotropics(float3 binormal, float offset, float3 normal, float3 viewDir, float3 LightDirection, float exponent, float strength, float shadowMask)
			{
				float3 ShiftedTangent = normalize(binormal + offset * normal);
				float3 H = normalize(LightDirection + viewDir);
				float dotTH = dot(ShiftedTangent, H);
				float sinTH = sqrt(1.0 - dotTH * dotTH);
				float dirAtten = smoothstep(-1.0, 0.0, dotTH);
				return saturate(dirAtten * pow(sinTH, exponent) * strength) * shadowMask;
			}
			
			float aaEdgeFeather(float value, float edge, float feather)
			{
				float edgeMin = saturate(edge - feather * 0.5);
				float edgeMax = saturate(edge + feather * 0.5);
				return saturate((value - edgeMin) / saturate(edgeMax - edgeMin + fwidth(value)));
			}
			
			void applyAnisotropics(inout PoiFragData poiFragData, inout PoiLight poiLight, in PoiCam poiCam, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				#if defined(PROP_ANISOCOLORMAP) || !defined(OPTIMIZER_ENABLED)
				float4 specMap = POI2D_SAMPLER_PAN(_AnisoColorMap, _MainTex, poiUV(poiMesh.uv[_AnisoColorMapUV], _AnisoColorMap_ST), _AnisoColorMapPan);
				#else
				float4 specMap = float4(1, 1, 1, 0);
				#endif
				
				float shadowMask = lerp(1, poiMax(poiLight.rampedLightMap), _AnisoHideInShadow);
				#ifdef POI_PASS_ADD
				shadowMask *= poiLight.additiveShadow;
				#endif
				
				if (_AnisoGlobalMask > 0)
				{
					shadowMask = customBlend(shadowMask, poiMods.globalMask[_AnisoGlobalMask-1], _AnisoGlobalMaskBlendType);
				}
				
				float spec0 = calculateAnisotropics(lerp(poiMesh.binormal[1], poiMesh.tangent[1], _Aniso0SwitchDirection), _Aniso0Offset +_Aniso0OffsetMapStrength * specMap.a, poiMesh.normals[1], poiCam.viewDir, poiLight.direction, _Aniso0Power * 1000, _Aniso0Strength, shadowMask);
				float spec1 = calculateAnisotropics(lerp(poiMesh.binormal[1], poiMesh.tangent[1], _Aniso1SwitchDirection), _Aniso1Offset +_Aniso1OffsetMapStrength * specMap.a, poiMesh.normals[1], poiCam.viewDir, poiLight.direction, _Aniso1Power * 1000, _Aniso1Strength, shadowMask);
				
				spec0 = lerp(spec0, aaEdgeFeather(spec0, _Aniso0Edge, _Aniso0Blur), _Aniso0ToonMode);
				spec1 = lerp(spec1, aaEdgeFeather(spec1, _Aniso1Edge, _Aniso1Blur), _Aniso1ToonMode);
				
				float3 spec0Color = specMap.rgb * poiThemeColor(poiMods, _Aniso0Tint.rgb, _Aniso0TintIndex);
				float3 spec1Color = specMap.rgb * poiThemeColor(poiMods, _Aniso1Tint.rgb, _Aniso1TintIndex);
				
				float3 finalSpec = saturate(saturate(spec0 * spec0Color) + saturate(spec1 * spec1Color)) * lerp(1, poiFragData.baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), poiLight.directColor, _AnisoUseLightColor);
				float3 baseColor = poiFragData.baseColor;
				
				poiFragData.baseColor = lerp(poiFragData.baseColor, spec1Color * lerp(1, baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), poiLight.directColor, _AnisoUseLightColor), _AnisoReplace * spec1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, spec0Color * lerp(1, baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), poiLight.directColor, _AnisoUseLightColor), _AnisoReplace * spec0);
				poiLight.finalLightAdd += max(0, finalSpec * _AnisoAdd);
				
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					for (int index = 0; index < 4; index++)
					{
						float vSpec0 = calculateAnisotropics(lerp(poiMesh.binormal[1], poiMesh.tangent[1], _Aniso0SwitchDirection), _Aniso0Offset +_Aniso0OffsetMapStrength * specMap.a, poiMesh.normals[1], poiCam.viewDir, poiLight.vDirection[index], _Aniso0Power * 1000, _Aniso0Strength, poiLight.vSaturatedDotNL[index]);
						float vSpec1 = calculateAnisotropics(lerp(poiMesh.binormal[1], poiMesh.tangent[1], _Aniso1SwitchDirection), _Aniso1Offset +_Aniso1OffsetMapStrength * specMap.a, poiMesh.normals[1], poiCam.viewDir, poiLight.vDirection[index], _Aniso1Power * 1000, _Aniso1Strength, poiLight.vSaturatedDotNL[index]);
						
						vSpec0 = lerp(vSpec0, aaEdgeFeather(vSpec0, _Aniso0Edge, _Aniso0Blur), _Aniso0ToonMode);
						vSpec1 = lerp(vSpec1, aaEdgeFeather(vSpec1, _Aniso1Edge, _Aniso1Blur), _Aniso1ToonMode);
						
						float3 vSpec0Color = spec0Color;
						float3 vSpec1Color = spec1Color;
						
						poiLight.finalLightAdd += max(0, saturate(saturate(vSpec0 * vSpec0Color) + saturate(vSpec1 * vSpec1Color)) * lerp(1, poiFragData.baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.vColor[index], float3(0.299, 0.587, 0.114)), poiLight.vColor[index], _AnisoUseLightColor) * _AnisoAdd);
						
						poiFragData.baseColor = lerp(poiFragData.baseColor, vSpec1Color * lerp(1, baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.vColor[index], float3(0.299, 0.587, 0.114)), poiLight.vColor[index], _AnisoUseLightColor), _AnisoReplace * vSpec1);
						poiFragData.baseColor = lerp(poiFragData.baseColor, vSpec0Color * lerp(1, baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.vColor[index], float3(0.299, 0.587, 0.114)), poiLight.vColor[index], _AnisoUseLightColor), _AnisoReplace * vSpec0);
					}
					#endif
				}
			}
			#endif
			//endex
			
			//ifex _MatcapEnable==0 && _Matcap2Enable==0 && _Matcap3Enable==0 && _Matcap4Enable==0
			void blendMatcap(inout PoiLight poiLight, inout PoiFragData poiFragData, in PoiMods poiMods, float add, float lightAdd, float multiply, float replace, float mixed, float screen, float4 matcapColor, float matcapMask, float emissionStrength, float matcapLightMask, uint globalMaskIndex, float globalMaskBlendType, in MatcapAudioLinkData matcapALD)
			{
				if (matcapLightMask)
				{
					matcapMask *= lerp(1, poiLight.rampedLightMap, matcapLightMask);
				}
				if (globalMaskIndex > 0)
				{
					matcapMask = maskBlend(matcapMask, poiMods.globalMask[globalMaskIndex - 1], globalMaskBlendType);
				}
				
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapColor.a = saturate(matcapColor.a + lerp(matcapALD.matcapALAlphaAdd.x, matcapALD.matcapALAlphaAdd.y, poiMods.audioLink[matcapALD.matcapALAlphaAddBand]));
					emissionStrength += lerp(matcapALD.matcapALEmissionAdd.x, matcapALD.matcapALEmissionAdd.y, poiMods.audioLink[matcapALD.matcapALEmissionAddBand]);
				}
				#endif
				
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, matcapColor.rgb, replace * matcapMask * matcapColor.a * .999999);
				poiFragData.baseColor.rgb *= lerp(1, matcapColor.rgb, multiply * matcapMask * matcapColor.a);
				poiFragData.baseColor.rgb += matcapColor.rgb * add * matcapMask * matcapColor.a;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, blendScreen(poiFragData.baseColor.rgb, matcapColor.rgb), screen * matcapMask * matcapColor.a);
				#ifdef POI_PASS_BASE
				poiLight.finalLightAdd += matcapColor.rgb * lightAdd * matcapMask * matcapColor.a;
				#endif
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, poiFragData.baseColor.rgb + poiFragData.baseColor.rgb * matcapColor.rgb, mixed * matcapMask * matcapColor.a);
				poiFragData.emission += matcapColor.rgb * emissionStrength * matcapMask * matcapColor.a;
			}
			
			void getMatcapUV(inout float2 matcapUV, in float2 matcapPan, in float matcapUVMode, in float matcapUVToBlend, in float2 matCapBlendUV, in float matcapRotation, in float matcapBorder, in float3 normal, in PoiCam poiCam, in PoiLight poiLight, in PoiMesh poiMesh, in float matcapNormalStrength, in MatcapAudioLinkData matcapALD)
			{
				switch(matcapUVMode)
				{
					// Normal / UTS
					case 0:
					{
						float3 viewNormal = (mul(UNITY_MATRIX_V, float4(normal, 0))).rgb;
						float3 NormalBlend_MatCapUV_Detail = viewNormal.rgb * float3(-1, -1, 1);
						float3 NormalBlend_MatCapUV_Base = (mul(UNITY_MATRIX_V, float4(poiCam.viewDir, 0)).rgb * float3(-1, -1, 1)) + float3(0, 0, 1);
						float3 noSknewViewNormal = NormalBlend_MatCapUV_Base * dot(NormalBlend_MatCapUV_Base, NormalBlend_MatCapUV_Detail) / NormalBlend_MatCapUV_Base.b - NormalBlend_MatCapUV_Detail;
						
						matcapUV = noSknewViewNormal.rg * matcapBorder + 0.5;
						break;
					}
					// Top Pinch
					case 1:
					{
						float3 worldViewUp = normalize(float3(0, 1, 0) - poiCam.viewDir * dot(poiCam.viewDir, float3(0, 1, 0)));
						float3 worldViewRight = normalize(cross(poiCam.viewDir, worldViewUp));
						matcapUV = float2(dot(worldViewRight, normal), dot(worldViewUp, normal)) * matcapBorder + 0.5;
						break;
					}
					// Custom Double Sided
					case 2:
					{
						float3 reflection = reflect(-poiCam.viewDir, normal);
						float2 uv = float2(dot(reflection, float3(1, 0, 0)), dot(reflection, float3(0, 1, 0)));
						matcapUV = uv * matcapBorder + 0.5;
						break;
					}
					// Gradient
					case 3:
					{
						matcapUV = 1 - abs(dot(normal, poiCam.viewDir));
						#ifdef POI_AUDIOLINK
						if (matcapALD.matcapALEnabled)
						{
							matcapUV += AudioLinkGetChronoTime(matcapALD.matcapALChronoPanType, matcapALD.matcapALChronoPanBand) * matcapALD.matcapALChronoPanSpeed;
						}
						#endif
						break;
					}
				}
				matcapUV = lerp(matcapUV, poiMesh.uv[matcapUVToBlend], matCapBlendUV);
				matcapUV += matcapPan * _Time.x;
				matcapUV = RotateUV(matcapUV, matcapRotation * PI, float2(.5, .5), 1.0f);
				
				if (IsInMirror() && matcapUVMode != 3)
				{
					matcapUV.x = 1 - matcapUV.x;
				}
			}
			
			//endex
			//ifex _MatcapEnable==0 && _Matcap2Enable==0 && _Matcap3Enable==0 && _Matcap4Enable==0
			#if defined(POI_MATCAP0) || defined(COLOR_GRADING_HDR_3D) || defined(POI_MATCAP2) || defined(POI_MATCAP3)
			void applyMatcap(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, inout PoiLight poiLight, in PoiMods poiMods)
			{
				float4 matcap = 0;
				float matcapMask = 0;
				float4 matcap2 = 0;
				float matcap2Mask = 0;
				float4 matcap3 = 0;
				float matcap3Mask = 0;
				float4 matcap4 = 0;
				float matcap4Mask = 0;
				float2 matcapUV = 0;
				float matcapIntensity;
				struct MatcapAudioLinkData matcapALD;
				//endex
				
				//ifex _MatcapEnable==0
				// Matcap 1
				#ifdef POI_MATCAP0
				matcapALD.matcapALEnabled = _Matcap0ALEnabled;
				matcapALD.matcapALAlphaAddBand = _Matcap0ALAlphaAddBand;
				matcapALD.matcapALAlphaAdd = _Matcap0ALAlphaAdd;
				matcapALD.matcapALEmissionAddBand = _Matcap0ALEmissionAddBand;
				matcapALD.matcapALEmissionAdd = _Matcap0ALEmissionAdd;
				matcapALD.matcapALIntensityAddBand = _Matcap0ALIntensityAddBand;
				matcapALD.matcapALIntensityAdd = _Matcap0ALIntensityAdd;
				matcapALD.matcapALChronoPanType = _Matcap0ALChronoPanType;
				matcapALD.matcapALChronoPanBand = _Matcap0ALChronoPanBand;
				matcapALD.matcapALChronoPanSpeed = _Matcap0ALChronoPanSpeed;
				
				float3 normal0 = lerp(poiMesh.normals[0], poiMesh.normals[1], _MatcapNormal);
				#ifdef POI_MATCAP0_CUSTOM_NORMAL
				#if defined(PROP_MATCAP0NORMALMAP) || !defined(OPTIMIZER_ENABLED)
				normal0 = calculateNormal(poiMesh.normals[_MatcapNormal], poiMesh, _Matcap0NormalMap, _Matcap0NormalMap_ST, _Matcap0NormalMapPan, _Matcap0NormalMapUV, _Matcap0NormalMapScale);
				#endif
				#endif
				
				#if defined(PROP_MATCAP) || !defined(OPTIMIZER_ENABLED)
				getMatcapUV(matcapUV, _MatcapPan.xy, _MatcapUVMode, _MatcapUVToBlend, _MatCapBlendUV1.xy, _MatcapRotation, _MatcapBorder, normal0, poiCam, poiLight, poiMesh, _MatcapNormal, matcapALD);
				if (_MatcapSmoothnessEnabled)
				{
					float mipCount0 = 9;
					if (_Matcap_TexelSize.z == 8192) mipCount0 = 13;
					if (_Matcap_TexelSize.z == 4096) mipCount0 = 12;
					if (_Matcap_TexelSize.z == 2048) mipCount0 = 11;
					if (_Matcap_TexelSize.z == 1024) mipCount0 = 10;
					if (_Matcap_TexelSize.z == 512) mipCount0 = 9;
					if (_Matcap_TexelSize.z == 256) mipCount0 = 8;
					if (_Matcap_TexelSize.z == 128) mipCount0 = 7;
					if (_Matcap_TexelSize.z == 64) mipCount0 = 6;
					if (_Matcap_TexelSize.z == 32) mipCount0 = 5;
					
					float matcapSmoothness = _MatcapSmoothness;
					
					if (_MatcapMaskSmoothnessApply)
					{
						#if defined(PROP_MATCAPMASK) || !defined(OPTIMIZER_ENABLED)
						matcapSmoothness *= POI2D_SAMPLER_PAN(_MatcapMask, _MainTex, poiUV(poiMesh.uv[_MatcapMaskUV], _MatcapMask_ST), _MatcapMaskPan)[_MatcapMaskSmoothnessChannel];
						#endif
					}
					matcapSmoothness = (1 - matcapSmoothness) * mipCount0;
					matcap = UNITY_SAMPLE_TEX2D_SAMPLER_LOD(_Matcap, _trilinear_repeat, TRANSFORM_TEX(matcapUV, _Matcap), matcapSmoothness) * float4(poiThemeColor(poiMods, _MatcapColor.rgb, _MatcapColorThemeIndex), _MatcapColor.a);
				}
				else
				{
					matcap = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap)) * float4(poiThemeColor(poiMods, _MatcapColor.rgb, _MatcapColorThemeIndex), _MatcapColor.a);
				}
				#else
				matcap = float4(poiThemeColor(poiMods, _MatcapColor.rgb, _MatcapColorThemeIndex), _MatcapColor.a);
				#endif
				
				matcapIntensity = _MatcapIntensity;
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapIntensity += lerp(matcapALD.matcapALIntensityAdd.x, matcapALD.matcapALIntensityAdd.y, poiMods.audioLink[matcapALD.matcapALIntensityAddBand]);
					matcapIntensity = max(0, matcapIntensity);
				}
				#endif
				matcap.rgb *= matcapIntensity;
				matcap.rgb = lerp(matcap.rgb, matcap.rgb * poiFragData.baseColor.rgb, _MatcapBaseColorMix);
				
				#if defined(PROP_MATCAPMASK) || !defined(OPTIMIZER_ENABLED)
				matcapMask = POI2D_SAMPLER_PAN(_MatcapMask, _MainTex, poiUV(poiMesh.uv[_MatcapMaskUV], _MatcapMask_ST), _MatcapMaskPan)[_MatcapMaskChannel];
				#else
				matcapMask = 1;
				#endif
				
				if (_MatcapMaskInvert)
				{
					matcapMask = 1 - matcapMask;
				}
				
				#ifdef TPS_Penetrator
				if (_MatcapTPSDepthEnabled)
				{
					matcapMask = lerp(0, matcapMask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _MatcapTPSMaskStrength);
				}
				#endif
				
				poiFragData.alpha *= lerp(1, matcap.a, matcapMask * _MatcapAlphaOverride);
				
				//UNITY_BRANCH
				if (_MatcapHueShiftEnabled)
				{
					matcap.rgb = hueShift(matcap.rgb, _MatcapHueShift + _Time.x * _MatcapHueShiftSpeed);
				}
				
				if (_MatcapApplyToAlphaEnabled)
				{
					float matcapAlphaApplyValue = dot(matcap.rgb, float3(0.299, 0.587, 0.114)); // Greyscale
					if (_MatcapApplyToAlphaSourceBlend == 1) // Max
					
					{
						matcapAlphaApplyValue = poiMax(matcap.rgb);
					}
					if (_MatcapApplyToAlphaBlendType == 0) // Add
					
					{
						poiFragData.alpha += lerp(0, matcapAlphaApplyValue, _MatcapApplyToAlphaBlending);
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
					if (_MatcapApplyToAlphaBlendType == 1) // Multiply
					
					{
						poiFragData.alpha *= lerp(1, matcapAlphaApplyValue, _MatcapApplyToAlphaBlending);
					}
				}
				
				blendMatcap(poiLight, poiFragData, poiMods, _MatcapAdd, _MatcapAddToLight, _MatcapMultiply, _MatcapReplace, _MatcapMixed, _MatcapScreen, matcap, matcapMask, _MatcapEmissionStrength, _MatcapLightMask, _MatcapMaskGlobalMask, _MatcapMaskGlobalMaskBlendType, matcapALD);
				#endif
				//endex
				//ifex _Matcap2Enable==0
				// Matcap 2
				#ifdef COLOR_GRADING_HDR_3D
				matcapALD.matcapALEnabled = _Matcap1ALEnabled;
				matcapALD.matcapALAlphaAddBand = _Matcap1ALAlphaAddBand;
				matcapALD.matcapALAlphaAdd = _Matcap1ALAlphaAdd;
				matcapALD.matcapALEmissionAddBand = _Matcap1ALEmissionAddBand;
				matcapALD.matcapALEmissionAdd = _Matcap1ALEmissionAdd;
				matcapALD.matcapALIntensityAddBand = _Matcap1ALIntensityAddBand;
				matcapALD.matcapALIntensityAdd = _Matcap1ALIntensityAdd;
				matcapALD.matcapALChronoPanType = _Matcap1ALChronoPanType;
				matcapALD.matcapALChronoPanBand = _Matcap1ALChronoPanBand;
				matcapALD.matcapALChronoPanSpeed = _Matcap1ALChronoPanSpeed;
				
				float3 normal1 = lerp(poiMesh.normals[0], poiMesh.normals[1], _Matcap2Normal);
				#ifdef POI_MATCAP1_CUSTOM_NORMAL
				#if defined(PROP_MATCAP1NORMALMAP) || !defined(OPTIMIZER_ENABLED)
				normal1 = calculateNormal(poiMesh.normals[_Matcap2Normal], poiMesh, _Matcap1NormalMap, _Matcap1NormalMap_ST, _Matcap1NormalMapPan, _Matcap1NormalMapUV, _Matcap1NormalMapScale);
				#endif
				#endif
				
				#if defined(PROP_MATCAP2) || !defined(OPTIMIZER_ENABLED)
				getMatcapUV(matcapUV, _Matcap2Pan.xy, _Matcap2UVMode, _Matcap2UVToBlend, _MatCap2ndBlendUV1.xy, _Matcap2Rotation, _Matcap2Border, normal1, poiCam, poiLight, poiMesh, _Matcap2Normal, matcapALD);
				if (_Matcap2SmoothnessEnabled)
				{
					float mipCount2 = 9;
					if (_Matcap2_TexelSize.z == 8192) mipCount2 = 13;
					if (_Matcap2_TexelSize.z == 4096) mipCount2 = 12;
					if (_Matcap2_TexelSize.z == 2048) mipCount2 = 11;
					if (_Matcap2_TexelSize.z == 1024) mipCount2 = 10;
					if (_Matcap2_TexelSize.z == 512) mipCount2 = 9;
					if (_Matcap2_TexelSize.z == 256) mipCount2 = 8;
					if (_Matcap2_TexelSize.z == 128) mipCount2 = 7;
					if (_Matcap2_TexelSize.z == 64) mipCount2 = 6;
					if (_Matcap2_TexelSize.z == 32) mipCount2 = 5;
					
					float matcap2Smoothness = _Matcap2Smoothness;
					
					if (_Matcap2MaskSmoothnessApply)
					{
						#if defined(PROP_MATCAP2MASK) || !defined(OPTIMIZER_ENABLED)
						matcap2Smoothness *= POI2D_SAMPLER_PAN(_Matcap2Mask, _MainTex, poiUV(poiMesh.uv[_Matcap2MaskUV], _Matcap2Mask_ST), _Matcap2MaskPan)[_Matcap2MaskSmoothnessChannel];
						#endif
					}
					matcap2Smoothness = (1 - matcap2Smoothness) * mipCount2;
					matcap2 = UNITY_SAMPLE_TEX2D_SAMPLER_LOD(_Matcap2, _trilinear_repeat, TRANSFORM_TEX(matcapUV, _Matcap2), matcap2Smoothness) * float4(poiThemeColor(poiMods, _Matcap2Color.rgb, _Matcap2ColorThemeIndex), _Matcap2Color.a);
				}
				else
				{
					matcap2 = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap2, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap2)) * float4(poiThemeColor(poiMods, _Matcap2Color.rgb, _Matcap2ColorThemeIndex), _Matcap2Color.a);
				}
				#else
				matcap2 = float4(poiThemeColor(poiMods, _Matcap2Color.rgb, _Matcap2ColorThemeIndex), _Matcap2Color.a);
				#endif
				
				matcapIntensity = _Matcap2Intensity;
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapIntensity += lerp(matcapALD.matcapALIntensityAdd.x, matcapALD.matcapALIntensityAdd.y, poiMods.audioLink[matcapALD.matcapALIntensityAddBand]);
					matcapIntensity = max(0, matcapIntensity);
				}
				#endif
				matcap2.rgb *= matcapIntensity;
				matcap2.rgb = lerp(matcap2.rgb, matcap2.rgb * poiFragData.baseColor.rgb, _Matcap2BaseColorMix);
				
				#if defined(PROP_MATCAP2MASK) || !defined(OPTIMIZER_ENABLED)
				matcap2Mask = POI2D_SAMPLER_PAN(_Matcap2Mask, _MainTex, poiUV(poiMesh.uv[_Matcap2MaskUV], _Matcap2Mask_ST), _Matcap2MaskPan)[_Matcap2MaskChannel];
				#else
				matcap2Mask = 1;
				#endif
				if (_Matcap2MaskInvert)
				{
					matcap2Mask = 1 - matcap2Mask;
				}
				
				#ifdef TPS_Penetrator
				if (_Matcap2TPSDepthEnabled)
				{
					matcap2Mask = lerp(0, matcap2Mask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Matcap2TPSMaskStrength);
				}
				#endif
				
				poiFragData.alpha *= lerp(1, matcap2.a, matcap2Mask * _Matcap2AlphaOverride);
				
				//UNITY_BRANCH
				if (_Matcap2HueShiftEnabled)
				{
					matcap2.rgb = hueShift(matcap2.rgb, _Matcap2HueShift + _Time.x * _Matcap2HueShiftSpeed);
				}
				
				if (_Matcap2ApplyToAlphaEnabled)
				{
					float matcap2AlphaApplyValue = dot(matcap2.rgb, float3(0.299, 0.587, 0.114)); // Greyscale
					if (_Matcap2ApplyToAlphaSourceBlend == 1) // Max
					
					{
						matcap2AlphaApplyValue = poiMax(matcap2.rgb);
					}
					if (_Matcap2ApplyToAlphaBlendType == 0) // Add
					
					{
						poiFragData.alpha += lerp(0, matcap2AlphaApplyValue, _Matcap2ApplyToAlphaBlending);
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
					if (_Matcap2ApplyToAlphaBlendType == 1) // Multiply
					
					{
						poiFragData.alpha *= lerp(1, matcap2AlphaApplyValue, _Matcap2ApplyToAlphaBlending);
					}
				}
				
				blendMatcap(poiLight, poiFragData, poiMods, _Matcap2Add, _Matcap2AddToLight, _Matcap2Multiply, _Matcap2Replace, _Matcap2Mixed, _Matcap2Screen, matcap2, matcap2Mask, _Matcap2EmissionStrength, _Matcap2LightMask, _Matcap2MaskGlobalMask, _Matcap2MaskGlobalMaskBlendType, matcapALD);
				#endif
				//endex
				//ifex _Matcap3Enable==0
				// Matcap 3
				#ifdef POI_MATCAP2
				
				matcapALD.matcapALEnabled = _Matcap2ALEnabled;
				matcapALD.matcapALAlphaAddBand = _Matcap2ALAlphaAddBand;
				matcapALD.matcapALAlphaAdd = _Matcap2ALAlphaAdd;
				matcapALD.matcapALEmissionAddBand = _Matcap2ALEmissionAddBand;
				matcapALD.matcapALEmissionAdd = _Matcap2ALEmissionAdd;
				matcapALD.matcapALIntensityAddBand = _Matcap2ALIntensityAddBand;
				matcapALD.matcapALIntensityAdd = _Matcap2ALIntensityAdd;
				matcapALD.matcapALChronoPanType = _Matcap2ALChronoPanType;
				matcapALD.matcapALChronoPanBand = _Matcap2ALChronoPanBand;
				matcapALD.matcapALChronoPanSpeed = _Matcap2ALChronoPanSpeed;
				
				float3 normal2 = lerp(poiMesh.normals[0], poiMesh.normals[1], _Matcap3Normal);
				#ifdef POI_MATCAP2_CUSTOM_NORMAL
				#if defined(PROP_MATCAP2NORMALMAP) || !defined(OPTIMIZER_ENABLED)
				normal2 = calculateNormal(poiMesh.normals[_Matcap3Normal], poiMesh, _Matcap2NormalMap, _Matcap2NormalMap_ST, _Matcap2NormalMapPan, _Matcap2NormalMapUV, _Matcap2NormalMapScale);
				#endif
				#endif
				
				#if defined(PROP_MATCAP3) || !defined(OPTIMIZER_ENABLED)
				getMatcapUV(matcapUV, _Matcap3Pan.xy, _Matcap3UVMode, _Matcap3UVToBlend, _MatCap3rdBlendUV1.xy, _Matcap3Rotation, _Matcap3Border, normal2, poiCam, poiLight, poiMesh, _Matcap3Normal, matcapALD);
				if (_Matcap3SmoothnessEnabled)
				{
					float mipCount3 = 9;
					if (_Matcap3_TexelSize.z == 8192) mipCount3 = 13;
					if (_Matcap3_TexelSize.z == 4096) mipCount3 = 12;
					if (_Matcap3_TexelSize.z == 2048) mipCount3 = 11;
					if (_Matcap3_TexelSize.z == 1024) mipCount3 = 10;
					if (_Matcap3_TexelSize.z == 512) mipCount3 = 9;
					if (_Matcap3_TexelSize.z == 256) mipCount3 = 8;
					if (_Matcap3_TexelSize.z == 128) mipCount3 = 7;
					if (_Matcap3_TexelSize.z == 64) mipCount3 = 6;
					if (_Matcap3_TexelSize.z == 32) mipCount3 = 5;
					
					float matcap3Smoothness = _Matcap3Smoothness;
					
					if (_Matcap3MaskSmoothnessApply)
					{
						#if defined(PROP_MATCAP3MASK) || !defined(OPTIMIZER_ENABLED)
						matcap3Smoothness *= POI2D_SAMPLER_PAN(_Matcap3Mask, _MainTex, poiUV(poiMesh.uv[_Matcap3MaskUV], _Matcap3Mask_ST), _Matcap3MaskPan)[_Matcap3MaskSmoothnessChannel];
						#endif
					}
					matcap3Smoothness = (1 - matcap3Smoothness) * mipCount3;
					matcap3 = UNITY_SAMPLE_TEX2D_SAMPLER_LOD(_Matcap3, _trilinear_repeat, TRANSFORM_TEX(matcapUV, _Matcap3), matcap3Smoothness) * float4(poiThemeColor(poiMods, _Matcap3Color.rgb, _Matcap3ColorThemeIndex), _Matcap3Color.a);
				}
				else
				{
					matcap3 = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap3, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap3)) * float4(poiThemeColor(poiMods, _Matcap3Color.rgb, _Matcap3ColorThemeIndex), _Matcap3Color.a);
				}
				#else
				matcap3 = float4(poiThemeColor(poiMods, _Matcap3Color.rgb, _Matcap3ColorThemeIndex), _Matcap3Color.a);
				#endif
				
				matcapIntensity = _Matcap3Intensity;
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapIntensity += lerp(matcapALD.matcapALIntensityAdd.x, matcapALD.matcapALIntensityAdd.y, poiMods.audioLink[matcapALD.matcapALIntensityAddBand]);
					matcapIntensity = max(0, matcapIntensity);
				}
				#endif
				matcap3.rgb *= matcapIntensity;
				matcap3.rgb = lerp(matcap3.rgb, matcap3.rgb * poiFragData.baseColor.rgb, _Matcap3BaseColorMix);
				
				#if defined(PROP_MATCAP3MASK) || !defined(OPTIMIZER_ENABLED)
				matcap3Mask = POI2D_SAMPLER_PAN(_Matcap3Mask, _MainTex, poiUV(poiMesh.uv[_Matcap3MaskUV], _Matcap3Mask_ST), _Matcap3MaskPan)[_Matcap3MaskChannel];
				#else
				matcap3Mask = 1;
				#endif
				if (_Matcap3MaskInvert)
				{
					matcap3Mask = 1 - matcap3Mask;
				}
				
				#ifdef TPS_Penetrator
				if (_Matcap3TPSDepthEnabled)
				{
					matcap3Mask = lerp(0, matcap3Mask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Matcap3TPSMaskStrength);
				}
				#endif
				
				poiFragData.alpha *= lerp(1, matcap3.a, matcap3Mask * _Matcap3AlphaOverride);
				
				//UNITY_BRANCH
				if (_Matcap3HueShiftEnabled)
				{
					matcap3.rgb = hueShift(matcap3.rgb, _Matcap3HueShift + _Time.x * _Matcap3HueShiftSpeed);
				}
				
				if (_Matcap3ApplyToAlphaEnabled)
				{
					float matcap3AlphaApplyValue = dot(matcap3.rgb, float3(0.299, 0.587, 0.114)); // Greyscale
					if (_Matcap3ApplyToAlphaSourceBlend == 1) // Max
					
					{
						matcap3AlphaApplyValue = poiMax(matcap3.rgb);
					}
					if (_Matcap3ApplyToAlphaBlendType == 0) // Add
					
					{
						poiFragData.alpha += lerp(0, matcap3AlphaApplyValue, _Matcap3ApplyToAlphaBlending);
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
					if (_Matcap3ApplyToAlphaBlendType == 1) // Multiply
					
					{
						poiFragData.alpha *= lerp(1, matcap3AlphaApplyValue, _Matcap3ApplyToAlphaBlending);
					}
				}
				
				blendMatcap(poiLight, poiFragData, poiMods, _Matcap3Add, _Matcap3AddToLight, _Matcap3Multiply, _Matcap3Replace, _Matcap3Mixed, _Matcap3Screen, matcap3, matcap3Mask, _Matcap3EmissionStrength, _Matcap3LightMask, _Matcap3MaskGlobalMask, _Matcap3MaskGlobalMaskBlendType, matcapALD);
				#endif
				//endex
				//ifex _Matcap4Enable==0
				// Matcap 4
				#ifdef POI_MATCAP3
				
				matcapALD.matcapALEnabled = _Matcap3ALEnabled;
				matcapALD.matcapALAlphaAddBand = _Matcap3ALAlphaAddBand;
				matcapALD.matcapALAlphaAdd = _Matcap3ALAlphaAdd;
				matcapALD.matcapALEmissionAddBand = _Matcap3ALEmissionAddBand;
				matcapALD.matcapALEmissionAdd = _Matcap3ALEmissionAdd;
				matcapALD.matcapALIntensityAddBand = _Matcap3ALIntensityAddBand;
				matcapALD.matcapALIntensityAdd = _Matcap3ALIntensityAdd;
				matcapALD.matcapALChronoPanType = _Matcap3ALChronoPanType;
				matcapALD.matcapALChronoPanBand = _Matcap3ALChronoPanBand;
				matcapALD.matcapALChronoPanSpeed = _Matcap3ALChronoPanSpeed;
				
				float3 normal3 = lerp(poiMesh.normals[0], poiMesh.normals[1], _Matcap4Normal);
				#ifdef POI_MATCAP3_CUSTOM_NORMAL
				#if defined(PROP_MATCAP3NORMALMAP) || !defined(OPTIMIZER_ENABLED)
				normal3 = calculateNormal(poiMesh.normals[_Matcap4Normal], poiMesh, _Matcap3NormalMap, _Matcap3NormalMap_ST, _Matcap3NormalMapPan, _Matcap3NormalMapUV, _Matcap3NormalMapScale);
				#endif
				#endif
				
				#if defined(PROP_MATCAP4) || !defined(OPTIMIZER_ENABLED)
				getMatcapUV(matcapUV, _Matcap4Pan.xy, _Matcap4UVMode, _Matcap4UVToBlend, _MatCap4thBlendUV1.xy, _Matcap4Rotation, _Matcap4Border, normal3, poiCam, poiLight, poiMesh, _Matcap4Normal, matcapALD);
				if (_Matcap4SmoothnessEnabled)
				{
					float mipCount4 = 9;
					if (_Matcap4_TexelSize.z == 8192) mipCount4 = 13;
					if (_Matcap4_TexelSize.z == 4096) mipCount4 = 12;
					if (_Matcap4_TexelSize.z == 2048) mipCount4 = 11;
					if (_Matcap4_TexelSize.z == 1024) mipCount4 = 10;
					if (_Matcap4_TexelSize.z == 512) mipCount4 = 9;
					if (_Matcap4_TexelSize.z == 256) mipCount4 = 8;
					if (_Matcap4_TexelSize.z == 128) mipCount4 = 7;
					if (_Matcap4_TexelSize.z == 64) mipCount4 = 6;
					if (_Matcap4_TexelSize.z == 32) mipCount4 = 5;
					
					float matcap4Smoothness = _Matcap4Smoothness;
					
					if (_Matcap4MaskSmoothnessApply)
					{
						#if defined(PROP_MATCAP4MASK) || !defined(OPTIMIZER_ENABLED)
						matcap4Smoothness *= POI2D_SAMPLER_PAN(_Matcap4Mask, _MainTex, poiUV(poiMesh.uv[_Matcap4MaskUV], _Matcap4Mask_ST), _Matcap4MaskPan)[_Matcap4MaskSmoothnessChannel];
						#endif
					}
					matcap4Smoothness = (1 - matcap4Smoothness) * mipCount4;
					matcap4 = UNITY_SAMPLE_TEX2D_SAMPLER_LOD(_Matcap4, _trilinear_repeat, TRANSFORM_TEX(matcapUV, _Matcap4), matcap4Smoothness) * float4(poiThemeColor(poiMods, _Matcap4Color.rgb, _Matcap4ColorThemeIndex), _Matcap4Color.a);
				}
				else
				{
					matcap4 = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap4, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap4)) * float4(poiThemeColor(poiMods, _Matcap4Color.rgb, _Matcap4ColorThemeIndex), _Matcap4Color.a);
				}
				#else
				matcap4 = float4(poiThemeColor(poiMods, _Matcap4Color.rgb, _Matcap4ColorThemeIndex), _Matcap4Color.a);
				#endif
				
				matcapIntensity = _Matcap4Intensity;
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapIntensity += lerp(matcapALD.matcapALIntensityAdd.x, matcapALD.matcapALIntensityAdd.y, poiMods.audioLink[matcapALD.matcapALIntensityAddBand]);
					matcapIntensity = max(0, matcapIntensity);
				}
				#endif
				matcap4.rgb *= matcapIntensity;
				matcap4.rgb = lerp(matcap4.rgb, matcap4.rgb * poiFragData.baseColor.rgb, _Matcap4BaseColorMix);
				
				#if defined(PROP_MATCAP4MASK) || !defined(OPTIMIZER_ENABLED)
				matcap4Mask = POI2D_SAMPLER_PAN(_Matcap4Mask, _MainTex, poiUV(poiMesh.uv[_Matcap4MaskUV], _Matcap4Mask_ST), _Matcap4MaskPan)[_Matcap4MaskChannel];
				#else
				matcap4Mask = 1;
				#endif
				if (_Matcap4MaskInvert)
				{
					matcap4Mask = 1 - matcap4Mask;
				}
				
				#ifdef TPS_Penetrator
				if (_Matcap4TPSDepthEnabled)
				{
					matcap4Mask = lerp(0, matcap4Mask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Matcap4TPSMaskStrength);
				}
				#endif
				
				poiFragData.alpha *= lerp(1, matcap4.a, matcap4Mask * _Matcap4AlphaOverride);
				
				//UNITY_BRANCH
				if (_Matcap4HueShiftEnabled)
				{
					matcap4.rgb = hueShift(matcap4.rgb, _Matcap4HueShift + _Time.x * _Matcap4HueShiftSpeed);
				}
				
				if (_Matcap4ApplyToAlphaEnabled)
				{
					float matcap4AlphaApplyValue = dot(matcap4.rgb, float3(0.299, 0.587, 0.114)); // Greyscale
					if (_Matcap4ApplyToAlphaSourceBlend == 1) // Max
					
					{
						matcap4AlphaApplyValue = poiMax(matcap4.rgb);
					}
					if (_Matcap4ApplyToAlphaBlendType == 0) // Add
					
					{
						poiFragData.alpha += lerp(0, matcap4AlphaApplyValue, _Matcap4ApplyToAlphaBlending);
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
					if (_Matcap4ApplyToAlphaBlendType == 1) // Multiply
					
					{
						poiFragData.alpha *= lerp(1, matcap4AlphaApplyValue, _Matcap4ApplyToAlphaBlending);
					}
				}
				
				blendMatcap(poiLight, poiFragData, poiMods, _Matcap4Add, _Matcap4AddToLight, _Matcap4Multiply, _Matcap4Replace, _Matcap4Mixed, _Matcap4Screen, matcap4, matcap4Mask, _Matcap4EmissionStrength, _Matcap4LightMask, _Matcap4MaskGlobalMask, _Matcap4MaskGlobalMaskBlendType, matcapALD);
				#endif
				//endex
				//ifex _MatcapEnable==0 && _Matcap2Enable==0 && _Matcap3Enable==0 && _Matcap4Enable==0
				
			}
			#endif
			//endex
			
			//ifex _CubeMapEnabled==0
			#ifdef _CUBEMAP
			#if defined(PROP_CUBEMAP) || !defined(OPTIMIZER_ENABLED)
			// From Unity's MIT'd Skybox-Cubed.shader
			float3 RotateAroundYInDegrees(float3 dir, float degrees)
			{
				float alpha = degrees * UNITY_PI / 180.0;
				float sina, cosa;
				sincos(alpha, sina, cosa);
				float2x2 m = float2x2(cosa, -sina, sina, cosa);
				return float3(mul(m, dir.xz), dir.y).xzy;
			}
			#endif
			void applyCubemap(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, in PoiLight poiLight, in PoiMods poiMods)
			{
				float3 CubeMapUV = 0;
				
				switch(_CubeMapUVMode)
				{
					case 0: // Skybox
					CubeMapUV = -poiCam.viewDir;
					break;
					case 1: // Reflection
					CubeMapUV = poiCam.reflectionDir;
					break;
					case 2: // World Normal Direction
					CubeMapUV = lerp(poiMesh.normals[0], poiMesh.normals[1], _CubeMapWorldNormalsStrength);
					break;
					case 3: // Local Normal Direction
					CubeMapUV = poiMesh.objNormal;
					break;
				}
				
				#if defined(PROP_CUBEMAP) || !defined(OPTIMIZER_ENABLED)
				if (any(_CubeMapRotation.xyz) || any(_CubeMapRotationPan.xyz))
				{
					// Do funny swizzle so we don't have to make a new function for every direction
					CubeMapUV = RotateAroundYInDegrees(CubeMapUV.yxz, _CubeMapRotation.x + (_CubeMapRotationPan.x * _Time.y)).yxz;
					CubeMapUV = RotateAroundYInDegrees(CubeMapUV.xyz, _CubeMapRotation.y + (_CubeMapRotationPan.y * _Time.y)).xyz;
					CubeMapUV = RotateAroundYInDegrees(CubeMapUV.xzy, _CubeMapRotation.z + (_CubeMapRotationPan.z * _Time.y)).xzy;
				}
				float4 cubeMap = texCUBElod(_CubeMap, float4(CubeMapUV, (1 - _CubeMapSmoothness) * (1 - _CubeMapSmoothness) * 8));
				
				cubeMap.rgb *= poiThemeColor(poiMods, _CubeMapColor, _CubeMapColorThemeIndex);
				#else
				float4 cubeMap = float4(0.21763764082, 0.21763764082, 0.21763764082, .5) * float4(poiThemeColor(poiMods, _CubeMapColor, _CubeMapColorThemeIndex), 1);
				#endif
				
				cubeMap.rgb *= _CubeMapIntensity;
				#if defined(PROP_CUBEMAPMASK) || !defined(OPTIMIZER_ENABLED)
				float CubeMapMask = POI2D_SAMPLER_PAN(_CubeMapMask, _MainTex, poiUV(poiMesh.uv[_CubeMapMaskUV], _CubeMapMask_ST), _CubeMapMaskPan)[_CubeMapMaskChannel];
				#else
				float CubeMapMask = 1;
				#endif
				
				if (_CubeMapMaskGlobalMask > 0)
				{
					CubeMapMask = maskBlend(CubeMapMask, poiMods.globalMask[_CubeMapMaskGlobalMask - 1], _CubeMapMaskGlobalMaskBlendType);
				}
				
				if (_CubeMapMaskInvert)
				{
					CubeMapMask = 1 - CubeMapMask;
				}
				
				//UNITY_BRANCH
				if (_CubeMapHueShiftEnabled)
				{
					cubeMap.rgb = hueShift(cubeMap.rgb, _CubeMapHueShift + _Time.x * _CubeMapHueShiftSpeed);
					cubeMap = PoiColorBCS(cubeMap, _CubeMapBrightness, _CubeMapContrast, _CubeMapSaturation);
					//cubeMap.rgb = ModifyViaHSV(cubeMap.rgb, _CubeMapHueShift + _Time.x * _CubeMapHueShiftSpeed, _CubeMapSaturation, _CubeMapValue);
					
				}
				CubeMapMask = min(CubeMapMask, lerp(1, poiLight.rampedLightMap, _CubeMapLightMask));
				float cubeMapAlpha = CubeMapMask * cubeMap.a * _CubeMapBlendAmount;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, cubeMap.rgb, cubeMapAlpha * (_CubemapBlendType == 0));
				poiFragData.baseColor.rgb *= lerp(1, cubeMap.rgb, cubeMapAlpha * (_CubemapBlendType == 1));
				poiFragData.baseColor.rgb += cubeMap.rgb * cubeMapAlpha * (_CubemapBlendType == 2);
				poiFragData.emission += cubeMap.rgb * _CubeMapEmissionStrength * CubeMapMask * cubeMap.a;
			}
			#endif
			//endex
			
			//ifex _EnableALDecal==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_DECAL
			void ApplyAudioLinkDecal(in PoiMesh poiMesh, inout PoiFragData poiFragData, in PoiMods poiMods)
			{
				float4 colorAndMask = float4(1, 1, 1, 1);
				#if defined(PROP_ALDECALCOLORMASK) || !defined(OPTIMIZER_ENABLED)
				colorAndMask = POI2D_SAMPLER_PAN(_ALDecalColorMask, _MainTex, poiUV(poiMesh.uv[_ALDecalColorMaskUV], _ALDecalColorMask_ST), _ALDecalColorMaskPan);
				#endif
				if (_ALDecalGlobalMask > 0)
				{
					colorAndMask.a = customBlend(colorAndMask.a, poiMods.globalMask[_ALDecalGlobalMask-1], _ALDecalGlobalMaskBlendType);
				}
				
				float2 uv = poiMesh.uv[_ALDecalUV];
				float2 decalCenter = _ALUVPosition;
				float theta = radians(_ALUVRotation + _Time.z * _ALUVRotationSpeed);
				float cs = cos(theta);
				float sn = sin(theta);
				uv = float2((uv.x - decalCenter.x) * cs - (uv.y - decalCenter.y) * sn + decalCenter.x, (uv.x - decalCenter.x) * sn + (uv.y - decalCenter.y) * cs + decalCenter.y);
				uv = remap(uv, float2(0, 0) - _ALUVScale.xz / 2 + _ALUVPosition, _ALUVScale.yw / 2 + _ALUVPosition, float2(0, 0), float2(1, 1));
				
				// Mask
				float4 audioLinkMask = 1.0;
				
				// UV
				float2 aluv = uv;
				if (_ALDecalUVMode == 1)
				{
					float2 uvdir = uv * 2 - 1;
					aluv.x = frac(atan2(uvdir.y, uvdir.x) * UNITY_INV_TWO_PI);
					aluv.y = length(uvdir);
				}
				
				// Scale / Offset / Step
				float maskY = aluv.y;
				if (_ALDecalUVMode == 1)
				{
					maskY = remap(maskY, _ALDecaldCircleDimensions.x, _ALDecaldCircleDimensions.y, 0, 1);
				}
				float maskX = aluv.x;
				if (_ALDecalUVMode == 1)
				{
					maskX = remap(maskX, _ALDecaldCircleDimensions.z, _ALDecaldCircleDimensions.w, 0, 1);
				}
				
				float maskVolume = _ALDecalVolumeStep != 0.0 ? floor(maskY * _ALDecalVolumeStep) / _ALDecalVolumeStep : maskY;
				float maskBand = _ALDecalBandStep != 0.0 ? floor(maskX * _ALDecalBandStep) / _ALDecalBandStep : maskX;
				
				// Copy
				audioLinkMask.r = maskVolume;
				audioLinkMask.g = maskBand;
				
				// Clip
				audioLinkMask.b = maskVolume < _ALDecalVolumeClipMin || maskVolume > _ALDecalVolumeClipMax ? 0.0 : audioLinkMask.b;
				audioLinkMask.b = maskBand < _ALDecalBandClipMin || maskBand > _ALDecalBandClipMax ? 0.0 : audioLinkMask.b;
				
				// Shape Clip
				if (_ALDecalShapeClip)
				{
					float volumeth = _ALDecalShapeClipVolumeWidth;
					if (_ALDecalVolumeStep != 0.0) audioLinkMask.b = frac(maskY * _ALDecalVolumeStep) > volumeth ? 0.0 : audioLinkMask.b;
					
					float bandwidth = _ALDecalUVMode == 1 ? _ALDecalShapeClipBandWidth / aluv.y : _ALDecalShapeClipBandWidth;
					float bandth = 1.0 - bandwidth;
					if (_ALDecalBandStep != 0.0) audioLinkMask.b = frac(maskX * _ALDecalBandStep + bandth * 0.5) < bandth ? 0.0 : audioLinkMask.b;
				}
				
				// AudioLink
				float2 audioLinkUV = float2(frac(audioLinkMask.g * 2.0), 4.5 / 4.0 + floor(audioLinkMask.g * 2.0) / 4.0);
				audioLinkUV.y *= 0.0625;
				float4 audioTexture = _AudioTexture.Sample(sampler_linear_clamp, audioLinkUV);
				float audioVal = audioTexture.b * _ALDecalVolume * lerp(_ALDecalBaseBoost, _ALDecalTrebleBoost, audioLinkMask.g);
				float audioLinkValue = _ALDecalLineWidth < 1.0 ? abs(audioVal - audioLinkMask.r) < _ALDecalLineWidth : audioVal > audioLinkMask.r * 2.0;
				audioLinkValue = saturate(audioLinkValue) * audioLinkMask.b;
				//clip(audioLinkValue - .5);
				audioLinkValue *= colorAndMask.a;
				
				if (!poiMods.audioLinkAvailable)
				{
					audioLinkValue = 0;
				}
				
				float3 alColorChord = _AudioTexture.Sample(sampler_linear_clamp, float2(maskX, 24.5 / 64.0)).rgb;
				float volumeColorSrc = audioLinkMask.g;
				if (_ALDecalVolumeColorSource == 1) volumeColorSrc = audioLinkMask.r;
				if (_ALDecalVolumeColorSource == 2) volumeColorSrc = audioVal;
				
				float3 lowColor = _ALDecalVolumeColorLow.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorLow.rgb, _ALDecalVolumeColorLowThemeIndex);
				float3 midColor = _ALDecalVolumeColorMid.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorMid.rgb, _ALDecalVolumeColorMidThemeIndex);
				float3 highColor = _ALDecalVolumeColorHigh.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorHigh.rgb, _ALDecalVolumeColorHighThemeIndex);
				
				float3 volumeColor = lerp(lowColor, midColor, saturate(volumeColorSrc * 2));
				volumeColor = lerp(volumeColor, highColor, saturate(volumeColorSrc * 2 - 1));
				
				float3 emissionColor = lerp(lowColor * _ALDecalLowEmission, midColor * _ALDecalMidEmission, saturate(volumeColorSrc * 2));
				emissionColor = lerp(emissionColor, highColor * _ALDecalHighEmission, saturate(volumeColorSrc * 2 - 1));
				
				//poiFragData.baseColor = lerp(poiFragData.baseColor, volumeColor, audioLinkValue);
				#if defined(POI_PASS_BASE) || defined(POI_PASS_ADD)
				poiFragData.emission += emissionColor * audioLinkValue;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor, customBlend(poiFragData.baseColor, volumeColor * colorAndMask.rgb, _ALDecalBlendType), saturate(_ALDecalBlendAlpha * audioLinkValue));
				#endif
				poiFragData.alpha = lerp(poiFragData.alpha, poiFragData.alpha * audioLinkValue, _ALDecalControlsAlpha);
			}
			#endif
			#endif
			//endex
			
			//ifex _EnableVolumeColor==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_VOLUMECOLOR
			void ApplyAudioLinkVolumeColor(in PoiMesh poiMesh, inout PoiFragData poiFragData, in PoiMods poiMods)
			{
				float volume = AudioLinkLerpMultiline(ALPASS_DFT + float2(poiMesh.uv[_ALVolumeColorUV][_ALVolumeColorDirection] * AUDIOLINK_ETOTALBINS, 0.0)).b;
				
				float3 lowColor = _ALVolumeColorLow.rgb * poiThemeColor(poiMods, _ALVolumeColorLow.rgb, _ALVolumeColorLowThemeIndex);
				float3 midColor = _ALVolumeColorMid.rgb * poiThemeColor(poiMods, _ALVolumeColorMid.rgb, _ALVolumeColorMidThemeIndex);
				float3 highColor = _ALVolumeColorHigh.rgb * poiThemeColor(poiMods, _ALVolumeColorHigh.rgb, _ALVolumeColorHighThemeIndex);
				
				float3 volumeColor = lerp(lowColor, midColor, saturate(volume * 2));
				volumeColor = lerp(volumeColor, highColor, saturate(volume * 2 - 1));
				
				float3 emissionColor = lerp(lowColor * _ALLowEmission, midColor * _ALMidEmission, saturate(volume * 2));
				emissionColor = lerp(emissionColor, highColor * _ALHighEmission, saturate(volume * 2 - 1));
				
				#if defined(POI_PASS_BASE) || defined(POI_PASS_ADD)
				poiFragData.emission += emissionColor * poiMods.audioLinkAvailable;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor, customBlend(poiFragData.baseColor, volumeColor, _ALVolumeColorBlendType), saturate(_ALVolumeColorBlendAlpha * poiMods.audioLinkAvailable));
				#endif
			}
			#endif
			#endif
			//endex
			
			//ifex _EnableFlipbook==0
			#ifdef _SUNDISK_HIGH_QUALITY
			
			void applyFlipbook(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				#if defined(PROP_FLIPBOOKTEXARRAY) || !defined(OPTIMIZER_ENABLED)
				float4 flipBookPixel = float4(0, 0, 0, 0);
				#if defined(PROP_FLIPBOOKMASK) || !defined(OPTIMIZER_ENABLED)
				float flipBookMask = POI2D_SAMPLER_PAN(_FlipbookMask, _MainTex, poiUV(poiMesh.uv[_FlipbookMaskUV], _FlipbookMask_ST), _FlipbookMaskPan)[_FlipbookMaskChannel];
				#else
				float flipBookMask = 1;
				#endif
				if (_FlipbookMaskGlobalMask > 0)
				{
					flipBookMask = maskBlend(flipBookMask, poiMods.globalMask[_FlipbookMaskGlobalMask-1], _FlipbookMaskGlobalMaskBlendType);
				}
				float4 flipbookScaleOffset = _FlipbookScaleOffset;
				
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookScaleOffset.xy += lerp(_AudioLinkFlipbookScale.xy, _AudioLinkFlipbookScale.zw, poiMods.audioLink[_AudioLinkFlipbookScaleBand]);
				}
				#endif
				
				flipbookScaleOffset.xy = 1 - flipbookScaleOffset.xy;
				float2 uv = frac(poiMesh.uv[_FlipbookTexArrayUV]);
				float theta = radians(_FlipbookRotation + _Time.z * _FlipbookRotationSpeed);
				float cs = cos(theta);
				float sn = sin(theta);
				float2 spriteCenter = flipbookScaleOffset.zw + .5;
				// 2d rotation
				uv = float2((uv.x - spriteCenter.x) * cs - (uv.y - spriteCenter.y) * sn + spriteCenter.x, (uv.x - spriteCenter.x) * sn + (uv.y - spriteCenter.y) * cs + spriteCenter.y);
				float4 sideOffset = float4(-(_FlipbookSideOffset.x), _FlipbookSideOffset.y, -(_FlipbookSideOffset.z), _FlipbookSideOffset.w);
				float2 newUV = remap(uv, float2(0, 0) + flipbookScaleOffset.xy / 2 + flipbookScaleOffset.zw + sideOffset.xz, float2(1, 1) - flipbookScaleOffset.xy / 2 + flipbookScaleOffset.zw + sideOffset.yw, float2(0, 0), float2(1, 1));
				
				UNITY_BRANCH
				if (_FlipbookTiled == 0)
				{
					if (max(newUV.x, newUV.y) > 1 || min(newUV.x, newUV.y) < 0)
					{
						return;
					}
				}
				float currentFrame = 0;
				float width;
				float height;
				float totalFrames;
				_FlipbookTexArray.GetDimensions(width, height, totalFrames);
				
				if (_FlipbookStartAndEnd)
				{
					totalFrames -= (totalFrames - min(max(_FlipbookStartFrame, _FlipbookEndFrame), totalFrames));
					totalFrames -= max(0, _FlipbookStartFrame);
				}
				if (!_FlipbookManualFrameControl)
				{
					if (_FlipbookFPS != 0)
					{
						currentFrame = ((_Time.y / (1 / _FlipbookFPS)) + _FlipbookFrameOffset) % totalFrames;
						if (_FlipbookStartAndEnd)
						{
							currentFrame += _FlipbookStartFrame;
						}
					}
				}
				else
				{
					currentFrame = fmod(_FlipbookCurrentFrame, totalFrames);
				}
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					if (_FlipbookChronotensityEnabled)
					{
						currentFrame += AudioLinkGetChronoTime(_FlipbookChronoType, _FlipbookChronotensityBand) * _FlipbookChronotensitySpeed;
					}
					currentFrame += lerp(_AudioLinkFlipbookFrame.x, _AudioLinkFlipbookFrame.y, poiMods.audioLink[_AudioLinkFlipbookFrameBand]);
					float totalFramesAL = totalFrames;
					if (_FlipbookStartAndEnd)
					{
						totalFramesAL += max(0, _FlipbookStartFrame);
					}
					currentFrame %= totalFramesAL;
				}
				#endif
				flipBookPixel = UNITY_SAMPLE_TEX2DARRAY(_FlipbookTexArray, float3(TRANSFORM_TEX(newUV, _FlipbookTexArray) + _Time.x * _FlipbookTexArrayPan, floor(currentFrame)));
				UNITY_BRANCH
				if (_FlipbookCrossfadeEnabled)
				{
					float totalFramesCF = totalFrames;
					if (_FlipbookStartAndEnd)
					{
						totalFramesCF += max(0, _FlipbookStartFrame);
					}
					float4 flipbookNextPixel = UNITY_SAMPLE_TEX2DARRAY(_FlipbookTexArray, float3(TRANSFORM_TEX(newUV, _FlipbookTexArray) + _Time.x * _FlipbookTexArrayPan, floor((currentFrame + 1) % totalFramesCF)));
					flipBookPixel = lerp(flipBookPixel, flipbookNextPixel, smoothstep(_FlipbookCrossfadeRange.x, _FlipbookCrossfadeRange.y, frac(currentFrame)));
				}
				
				UNITY_BRANCH
				if (_FlipbookIntensityControlsAlpha)
				{
					flipBookPixel.a = poiMax(flipBookPixel.rgb);
				}
				UNITY_BRANCH
				if (_FlipbookColorReplaces)
				{
					flipBookPixel.rgb = poiThemeColor(poiMods, _FlipbookColor.rgb, _FlipbookColorThemeIndex);
				}
				else
				{
					flipBookPixel.rgb *= poiThemeColor(poiMods, _FlipbookColor.rgb, _FlipbookColorThemeIndex);
				}
				
				UNITY_BRANCH
				if (_FlipbookHueShiftEnabled)
				{
					flipBookPixel.rgb = hueShift(flipBookPixel.rgb, _FlipbookHueShift + _Time.x * _FlipbookHueShiftSpeed);
				}
				half flipbookAlpha = 1;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookAlpha += saturate(lerp(_AudioLinkFlipbookAlpha.x, _AudioLinkFlipbookAlpha.y, poiMods.audioLink[_AudioLinkFlipbookAlphaBand]));
				}
				#endif
				
				#if !defined(POI_PASS_OUTLINE) && !defined(UNITY_PASS_SHADOWCASTER)
				
				poiFragData.baseColor = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, flipBookPixel.rgb, _FlipbookBlendType), flipBookPixel.a * _FlipbookColor.a * _FlipbookReplace * flipBookMask * flipbookAlpha);
				
				float flipbookEmissionStrength = _FlipbookEmissionStrength;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookEmissionStrength += max(lerp(_AudioLinkFlipbookEmission.x, _AudioLinkFlipbookEmission.y, poiMods.audioLink[_AudioLinkFlipbookEmissionBand]), 0);
				}
				#endif
				
				poiFragData.emission += lerp(0, flipBookPixel.rgb * flipbookEmissionStrength, flipBookPixel.a * _FlipbookColor.a * flipBookMask * flipbookAlpha);
				
				#endif
				
				UNITY_BRANCH
				if (_FlipbookAlphaControlsFinalAlpha)
				{
					poiFragData.alpha = lerp(poiFragData.alpha, flipBookPixel.a * _FlipbookColor.a, flipBookMask);
				}
				#endif
			}
			
			#endif
			//endex
			
			//ifex _EnableEmission==0 && _EnableEmission1==0 && _EnableEmission2==0 && _EnableEmission3==0
			float calculateGlowInTheDark(in float minLight, in float maxLight, in float minEmissionMultiplier, in float maxEmissionMultiplier, in float enabled, in float worldOrMesh, in PoiLight poiLight)
			{
				float glowInTheDarkMultiplier = 1;
				//UNITY_BRANCH
				if (enabled)
				{
					float3 lightValue = worldOrMesh ? calculateluminance(poiLight.finalLighting.rgb) : calculateluminance(poiLight.directColor.rgb);
					float gitdeAlpha = saturate(inverseLerp(minLight, maxLight, lightValue));
					glowInTheDarkMultiplier = lerp(minEmissionMultiplier, maxEmissionMultiplier, gitdeAlpha);
				}
				return glowInTheDarkMultiplier;
			}
			
			float calculateScrollingEmission(in float3 direction, in float velocity, in float interval, in float scrollWidth, float offset, float3 position)
			{
				scrollWidth = max(scrollWidth, 0);
				float phase = 0;
				phase = dot(position, direction);
				phase -= (_Time.y + offset) * velocity;
				phase /= interval;
				phase -= floor(phase);
				phase = saturate(phase);
				return (pow(phase, scrollWidth) + pow(1 - phase, scrollWidth * 4)) * 0.5;
			}
			
			float calculateBlinkingEmission(in float blinkMin, in float blinkMax, in float blinkVelocity, float offset)
			{
				float amplitude = (blinkMax - blinkMin) * 0.5f;
				float base = blinkMin + amplitude;
				return sin((_Time.y + offset) * blinkVelocity) * amplitude + base;
			}
			
			void applyALEmmissionStrength(in PoiMods poiMods, inout float emissionStrength, in float2 emissionStrengthMod, in float emissionStrengthBand, in float2 _EmissionALMultipliers, in float _EmissionALMultipliersBand, in float enabled)
			{
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable && enabled)
				{
					emissionStrength += lerp(emissionStrengthMod.x, emissionStrengthMod.y, poiMods.audioLink[emissionStrengthBand]);
					emissionStrength *= lerp(_EmissionALMultipliers.x, _EmissionALMultipliers.y, poiMods.audioLink[_EmissionALMultipliersBand]);
				}
				#endif
			}
			
			void applyALCenterOutEmission(in PoiMods poiMods, in float nDotV, inout float emissionStrength, in float size, in float band, in float2 emissionToAdd, in float enabled, in float duration)
			{
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable && enabled)
				{
					float intensity;
					[flatten]
					if (duration >= 0)
					{
						intensity = getBandAtTime(band, saturate(remap(nDotV, 1, 0, 0, duration)), size);
					}
					else
					{
						duration *= -1;
						intensity = getBandAtTime(band, saturate(remap(pow(nDotV, 2), 0, 1 + duration, 0, duration)), size);
					}
					emissionStrength += lerp(emissionToAdd[0], emissionToAdd[1], intensity);
				}
				#endif
			}
			//endex
			
			//ifex _EnableEmission==0
			#ifdef _EMISSION
			float3 applyEmission(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiLight poiLight, in PoiCam poiCam, in PoiMods poiMods)
			{
				
				// First Emission
				float3 emission0 = 0;
				float emissionStrength0 = _EmissionStrength;
				float3 emissionColor0 = 0;
				applyALEmmissionStrength(poiMods, emissionStrength0, _EmissionAL0StrengthMod, _EmissionAL0StrengthBand, _EmissionAL0Multipliers, _EmissionAL0MultipliersBand, _EmissionAL0Enabled);
				applyALCenterOutEmission(poiMods, poiLight.nDotV, emissionStrength0, _AudioLinkEmission0CenterOutSize, _AudioLinkEmission0CenterOutBand, _AudioLinkEmission0CenterOut, _EmissionAL0Enabled, _AudioLinkEmission0CenterOutDuration);
				
				float glowInTheDarkMultiplier0 = calculateGlowInTheDark(_GITDEMinLight, _GITDEMaxLight, _GITDEMinEmissionMultiplier, _GITDEMaxEmissionMultiplier, _EnableGITDEmission, _GITDEWorldOrMesh, poiLight);
				
				#if defined(PROP_EMISSIONMAP) || !defined(OPTIMIZER_ENABLED)
				//UNITY_BRANCH
				if (!_EmissionCenterOutEnabled)
				{
					emissionColor0 = POI2D_SAMPLER_PAN(_EmissionMap, _MainTex, poiUV(poiMesh.uv[_EmissionMapUV], _EmissionMap_ST), _EmissionMapPan).rgb * lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap).rgb * poiThemeColor(poiMods, _EmissionColor.rgb, _EmissionColorThemeIndex);
				}
				else
				{
					emissionColor0 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMap, _MainTex, ((.5 + poiLight.nDotV * .5) * _EmissionMap_ST.xy) + _Time.x * _EmissionCenterOutSpeed).rgb * lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap).rgb * poiThemeColor(poiMods, _EmissionColor.rgb, _EmissionColorThemeIndex);
				}
				#else
				emissionColor0 = lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap).rgb * poiThemeColor(poiMods, _EmissionColor.rgb, _EmissionColorThemeIndex);
				#endif
				
				//UNITY_BRANCH
				if (_ScrollingEmission)
				{
					float3 pos = poiMesh.localPos;
					//UNITY_BRANCH
					if (_EmissionScrollingVertexColor)
					{
						pos = poiMesh.vertexColor.rgb;
					}
					
					//UNITY_BRANCH
					if (_EmissionScrollingUseCurve)
					{
						#if defined(PROP_EMISSIONSCROLLINGCURVE) || !defined(OPTIMIZER_ENABLED)
						emissionStrength0 *= UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionScrollingCurve, _MainTex, poiUV(poiMesh.uv[_EmissionMapUV], _EmissionScrollingCurve_ST) + (dot(pos, _EmissiveScroll_Direction.xyz) * _EmissiveScroll_Interval) + _Time.x * _EmissiveScroll_Velocity).r;
						#endif
					}
					else
					{
						emissionStrength0 *= calculateScrollingEmission(_EmissiveScroll_Direction.xyz, _EmissiveScroll_Velocity, _EmissiveScroll_Interval, _EmissiveScroll_Width, _EmissionScrollingOffset, pos);
					}
				}
				
				//UNITY_BRANCH
				if (_EmissionBlinkingEnabled)
				{
					emissionStrength0 *= calculateBlinkingEmission(_EmissiveBlink_Min, _EmissiveBlink_Max, _EmissiveBlink_Velocity, _EmissionBlinkingOffset);
				}
				emissionColor0 = hueShift(emissionColor0, frac(_EmissionHueShift + _EmissionHueShiftSpeed * _Time.x) * _EmissionHueShiftEnabled);
				emissionColor0 = lerp(emissionColor0, dot(emissionColor0, float3(0.3, 0.59, 0.11)), - (_EmissionSaturation) * _EmissionHueShiftEnabled);
				
				#if defined(PROP_EMISSIONMASK) || !defined(OPTIMIZER_ENABLED)
				float emissionMask0 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMask, _MainTex, poiUV(poiMesh.uv[_EmissionMaskUV], _EmissionMask_ST) + _Time.x * _EmissionMaskPan)[_EmissionMaskChannel];
				#else
				float emissionMask0 = 1;
				#endif
				
				if (_EmissionMaskInvert)
				{
					emissionMask0 = 1 - emissionMask0;
				}
				
				if (_EmissionMask0GlobalMask > 0)
				{
					emissionMask0 = maskBlend(emissionMask0, poiMods.globalMask[_EmissionMask0GlobalMask - 1], _EmissionMask0GlobalMaskBlendType);
				}
				
				emissionStrength0 *= glowInTheDarkMultiplier0 * emissionMask0;
				emission0 = max(emissionStrength0 * emissionColor0, 0);
				
				#ifdef POI_DISSOLVE
				//UNITY_BRANCH
				if (_DissolveEmissionSide != 2)
				{
					emission0 *= lerp(1 - dissolveAlpha, dissolveAlpha, _DissolveEmissionSide);
				}
				#endif
				
				// poiFragData.finalColor.rgb = lerp(poiFragData.finalColor.rgb, saturate(emission0 + emission1), _EmissionReplace * poiMax(emission0 + emission1));
				
				poiFragData.emission += emission0;
				return emission0 * _EmissionReplace0;
			}
			#endif
			//endex
			//ifex _EnableEmission1==0
			#ifdef POI_EMISSION_1
			float3 applyEmission1(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiLight poiLight, in PoiCam poiCam, in PoiMods poiMods)
			{
				
				// Second Emission
				float3 emission1 = 0;
				float emissionStrength1 = 0;
				float3 emissionColor1 = 0;
				
				emissionStrength1 = _EmissionStrength1;
				applyALEmmissionStrength(poiMods, emissionStrength1, _EmissionAL1StrengthMod, _EmissionAL1StrengthBand, _EmissionAL1Multipliers, _EmissionAL1MultipliersBand, _EmissionAL1Enabled);
				applyALCenterOutEmission(poiMods, poiLight.nDotV, emissionStrength1, _AudioLinkEmission1CenterOutSize, _AudioLinkEmission1CenterOutBand, _AudioLinkEmission1CenterOut, _EmissionAL1Enabled, _AudioLinkEmission1CenterOutDuration);
				
				float glowInTheDarkMultiplier1 = calculateGlowInTheDark(_GITDEMinLight1, _GITDEMaxLight1, _GITDEMinEmissionMultiplier1, _GITDEMaxEmissionMultiplier1, _EnableGITDEmission1, _GITDEWorldOrMesh1, poiLight);
				#if defined(PROP_EMISSIONMAP1) || !defined(OPTIMIZER_ENABLED)
				
				//UNITY_BRANCH
				if (!_EmissionCenterOutEnabled1)
				{
					emissionColor1 = POI2D_SAMPLER_PAN(_EmissionMap1, _MainTex, poiUV(poiMesh.uv[_EmissionMap1UV], _EmissionMap1_ST), _EmissionMap1Pan) * lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap1).rgb * poiThemeColor(poiMods, _EmissionColor1.rgb, _EmissionColor1ThemeIndex);
				}
				else
				{
					emissionColor1 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMap1, _MainTex, ((.5 + poiLight.nDotV * .5) * _EmissionMap1_ST.xy) + _Time.x * _EmissionCenterOutSpeed1).rgb * lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap1).rgb * poiThemeColor(poiMods, _EmissionColor1.rgb, _EmissionColor1ThemeIndex);
				}
				#else
				emissionColor1 = lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap1).rgb * poiThemeColor(poiMods, _EmissionColor1.rgb, _EmissionColor1ThemeIndex);
				#endif
				//UNITY_BRANCH
				if (_ScrollingEmission1)
				{
					float3 pos1 = poiMesh.localPos;
					//UNITY_BRANCH
					if (_EmissionScrollingVertexColor1)
					{
						pos1 = poiMesh.vertexColor.rgb;
					}
					
					//UNITY_BRANCH
					if (_EmissionScrollingUseCurve1)
					{
						#if defined(PROP_EMISSIONSCROLLINGCURVE1) || !defined(OPTIMIZER_ENABLED)
						emissionStrength1 *= UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionScrollingCurve1, _MainTex, poiUV(poiMesh.uv[_EmissionMap1UV], _EmissionScrollingCurve1_ST) + (dot(pos1, _EmissiveScroll_Direction1) * _EmissiveScroll_Interval1) + _Time.x * _EmissiveScroll_Velocity1);
						#endif
					}
					else
					{
						emissionStrength1 *= calculateScrollingEmission(_EmissiveScroll_Direction1, _EmissiveScroll_Velocity1, _EmissiveScroll_Interval1, _EmissiveScroll_Width1, _EmissionScrollingOffset1, pos1);
					}
				}
				//UNITY_BRANCH
				if (_EmissionBlinkingEnabled1)
				{
					emissionStrength1 *= calculateBlinkingEmission(_EmissiveBlink_Min1, _EmissiveBlink_Max1, _EmissiveBlink_Velocity1, _EmissionBlinkingOffset1);
				}
				emissionColor1 = hueShift(emissionColor1, frac(_EmissionHueShift1 + _EmissionHueShiftSpeed1 * _Time.x) * _EmissionHueShiftEnabled1);
				emissionColor1 = lerp(emissionColor1, dot(emissionColor1, float3(0.3, 0.59, 0.11)), - (_EmissionSaturation1) * _EmissionHueShiftEnabled1);
				
				#if defined(PROP_EMISSIONMASK1) || !defined(OPTIMIZER_ENABLED)
				float emissionMask1 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMask1, _MainTex, poiUV(poiMesh.uv[_EmissionMask1UV], _EmissionMask1_ST) + _Time.x * _EmissionMask1Pan)[_EmissionMask1Channel];
				#else
				float emissionMask1 = 1;
				#endif
				
				if (_EmissionMaskInvert1)
				{
					emissionMask1 = 1 - emissionMask1;
				}
				
				if (_EmissionMask1GlobalMask > 0)
				{
					emissionMask1 = maskBlend(emissionMask1, poiMods.globalMask[_EmissionMask1GlobalMask - 1], _EmissionMask1GlobalMaskBlendType);
				}
				
				emissionStrength1 *= glowInTheDarkMultiplier1 * emissionMask1;
				emission1 = max(emissionStrength1 * emissionColor1, 0);
				
				poiFragData.emission += emission1;
				return emission1 * _EmissionReplace1;
			}
			#endif
			//endex
			//ifex _EnableEmission2==0
			#ifdef POI_EMISSION_2
			float3 applyEmission2(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiLight poiLight, in PoiCam poiCam, in PoiMods poiMods)
			{
				
				// Second Emission
				float3 emission2 = 0;
				float emissionStrength2 = 0;
				float3 emissionColor2 = 0;
				
				emissionStrength2 = _EmissionStrength2;
				applyALEmmissionStrength(poiMods, emissionStrength2, _EmissionAL2StrengthMod, _EmissionAL2StrengthBand, _EmissionAL2Multipliers, _EmissionAL2MultipliersBand, _EmissionAL2Enabled);
				applyALCenterOutEmission(poiMods, poiLight.nDotV, emissionStrength2, _AudioLinkEmission2CenterOutSize, _AudioLinkEmission2CenterOutBand, _AudioLinkEmission2CenterOut, _EmissionAL2Enabled, _AudioLinkEmission2CenterOutDuration);
				
				float glowInTheDarkMultiplier2 = calculateGlowInTheDark(_GITDEMinLight2, _GITDEMaxLight2, _GITDEMinEmissionMultiplier2, _GITDEMaxEmissionMultiplier2, _EnableGITDEmission2, _GITDEWorldOrMesh2, poiLight);
				#if defined(PROP_EMISSIONMAP2) || !defined(OPTIMIZER_ENABLED)
				
				//UNITY_BRANCH
				if (!_EmissionCenterOutEnabled2)
				{
					emissionColor2 = POI2D_SAMPLER_PAN(_EmissionMap2, _MainTex, poiUV(poiMesh.uv[_EmissionMap2UV], _EmissionMap2_ST), _EmissionMap2Pan) * lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap2).rgb * poiThemeColor(poiMods, _EmissionColor2.rgb, _EmissionColor2ThemeIndex);
				}
				else
				{
					emissionColor2 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMap2, _MainTex, ((.5 + poiLight.nDotV * .5) * _EmissionMap2_ST.xy) + _Time.x * _EmissionCenterOutSpeed2).rgb * lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap2).rgb * poiThemeColor(poiMods, _EmissionColor2.rgb, _EmissionColor2ThemeIndex);
				}
				#else
				emissionColor2 = lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap2).rgb * poiThemeColor(poiMods, _EmissionColor2.rgb, _EmissionColor2ThemeIndex);
				#endif
				//UNITY_BRANCH
				if (_ScrollingEmission2)
				{
					float3 pos2 = poiMesh.localPos;
					//UNITY_BRANCH
					if (_EmissionScrollingVertexColor2)
					{
						pos2 = poiMesh.vertexColor.rgb;
					}
					
					//UNITY_BRANCH
					if (_EmissionScrollingUseCurve2)
					{
						#if defined(PROP_EMISSIONSCROLLINGCURVE2) || !defined(OPTIMIZER_ENABLED)
						emissionStrength2 *= UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionScrollingCurve2, _MainTex, poiUV(poiMesh.uv[_EmissionMap2UV], _EmissionScrollingCurve2_ST) + (dot(pos2, _EmissiveScroll_Direction2) * _EmissiveScroll_Interval2) + _Time.x * _EmissiveScroll_Velocity2);
						#endif
					}
					else
					{
						emissionStrength2 *= calculateScrollingEmission(_EmissiveScroll_Direction2, _EmissiveScroll_Velocity2, _EmissiveScroll_Interval2, _EmissiveScroll_Width2, _EmissionScrollingOffset2, pos2);
					}
				}
				//UNITY_BRANCH
				if (_EmissionBlinkingEnabled2)
				{
					emissionStrength2 *= calculateBlinkingEmission(_EmissiveBlink_Min2, _EmissiveBlink_Max2, _EmissiveBlink_Velocity2, _EmissionBlinkingOffset2);
				}
				emissionColor2 = hueShift(emissionColor2, frac(_EmissionHueShift2 + _EmissionHueShiftSpeed2 * _Time.x) * _EmissionHueShiftEnabled2);
				emissionColor2 = lerp(emissionColor2, dot(emissionColor2, float3(0.3, 0.59, 0.11)), - (_EmissionSaturation2) * _EmissionHueShiftEnabled2);
				
				#if defined(PROP_EMISSIONMASK2) || !defined(OPTIMIZER_ENABLED)
				float emissionMask2 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMask2, _MainTex, poiUV(poiMesh.uv[_EmissionMask2UV], _EmissionMask2_ST) + _Time.x * _EmissionMask2Pan)[_EmissionMask2Channel];
				#else
				float emissionMask2 = 1;
				#endif
				if (_EmissionMaskInvert2)
				{
					emissionMask2 = 1 - emissionMask2;
				}
				
				if (_EmissionMask2GlobalMask > 0)
				{
					emissionMask2 = maskBlend(emissionMask2, poiMods.globalMask[_EmissionMask2GlobalMask - 1], _EmissionMask2GlobalMaskBlendType);
				}
				emissionStrength2 *= glowInTheDarkMultiplier2 * emissionMask2;
				emission2 = max(emissionStrength2 * emissionColor2, 0);
				
				poiFragData.emission += emission2;
				return emission2 * _EmissionReplace2;
			}
			#endif
			//endex
			//ifex _EnableEmission3==0
			#ifdef POI_EMISSION_3
			float3 applyEmission3(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiLight poiLight, in PoiCam poiCam, in PoiMods poiMods)
			{
				
				// Second Emission
				float3 emission3 = 0;
				float emissionStrength3 = 0;
				float3 emissionColor3 = 0;
				
				emissionStrength3 = _EmissionStrength3;
				applyALEmmissionStrength(poiMods, emissionStrength3, _EmissionAL3StrengthMod, _EmissionAL3StrengthBand, _EmissionAL3Multipliers, _EmissionAL3MultipliersBand, _EmissionAL3Enabled);
				applyALCenterOutEmission(poiMods, poiLight.nDotV, emissionStrength3, _AudioLinkEmission3CenterOutSize, _AudioLinkEmission3CenterOutBand, _AudioLinkEmission3CenterOut, _EmissionAL3Enabled, _AudioLinkEmission3CenterOutDuration);
				
				float glowInTheDarkMultiplier3 = calculateGlowInTheDark(_GITDEMinLight3, _GITDEMaxLight3, _GITDEMinEmissionMultiplier3, _GITDEMaxEmissionMultiplier3, _EnableGITDEmission3, _GITDEWorldOrMesh3, poiLight);
				#if defined(PROP_EMISSIONMAP3) || !defined(OPTIMIZER_ENABLED)
				
				//UNITY_BRANCH
				if (!_EmissionCenterOutEnabled3)
				{
					emissionColor3 = POI2D_SAMPLER_PAN(_EmissionMap3, _MainTex, poiUV(poiMesh.uv[_EmissionMap3UV], _EmissionMap3_ST), _EmissionMap3Pan) * lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap3).rgb * poiThemeColor(poiMods, _EmissionColor3.rgb, _EmissionColor3ThemeIndex);
				}
				else
				{
					emissionColor3 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMap3, _MainTex, ((.5 + poiLight.nDotV * .5) * _EmissionMap3_ST.xy) + _Time.x * _EmissionCenterOutSpeed3).rgb * lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap3).rgb * poiThemeColor(poiMods, _EmissionColor3.rgb, _EmissionColor3ThemeIndex);
				}
				#else
				emissionColor3 = lerp(1, poiFragData.baseColor, _EmissionBaseColorAsMap3).rgb * poiThemeColor(poiMods, _EmissionColor3.rgb, _EmissionColor3ThemeIndex);
				#endif
				//UNITY_BRANCH
				if (_ScrollingEmission3)
				{
					float3 pos3 = poiMesh.localPos;
					//UNITY_BRANCH
					if (_EmissionScrollingVertexColor3)
					{
						pos3 = poiMesh.vertexColor.rgb;
					}
					
					//UNITY_BRANCH
					if (_EmissionScrollingUseCurve3)
					{
						#if defined(PROP_EMISSIONSCROLLINGCURVE3) || !defined(OPTIMIZER_ENABLED)
						emissionStrength3 *= UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionScrollingCurve3, _MainTex, poiUV(poiMesh.uv[_EmissionMap3UV], _EmissionScrollingCurve3_ST) + (dot(pos3, _EmissiveScroll_Direction3) * _EmissiveScroll_Interval3) + _Time.x * _EmissiveScroll_Velocity3);
						#endif
					}
					else
					{
						emissionStrength3 *= calculateScrollingEmission(_EmissiveScroll_Direction3, _EmissiveScroll_Velocity3, _EmissiveScroll_Interval3, _EmissiveScroll_Width3, _EmissionScrollingOffset3, pos3);
					}
				}
				//UNITY_BRANCH
				if (_EmissionBlinkingEnabled3)
				{
					emissionStrength3 *= calculateBlinkingEmission(_EmissiveBlink_Min3, _EmissiveBlink_Max3, _EmissiveBlink_Velocity3, _EmissionBlinkingOffset3);
				}
				emissionColor3 = hueShift(emissionColor3, frac(_EmissionHueShift3 + _EmissionHueShiftSpeed3 * _Time.x) * _EmissionHueShiftEnabled3);
				emissionColor3 = lerp(emissionColor3, dot(emissionColor3, float3(0.3, 0.59, 0.11)), - (_EmissionSaturation3) * _EmissionHueShiftEnabled3);
				
				#if defined(PROP_EMISSIONMASK3) || !defined(OPTIMIZER_ENABLED)
				float emissionMask3 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMask3, _MainTex, poiUV(poiMesh.uv[_EmissionMask3UV], _EmissionMask3_ST) + _Time.x * _EmissionMask3Pan)[_EmissionMask3Channel];
				#else
				float emissionMask3 = 1;
				#endif
				
				if (_EmissionMaskInvert3)
				{
					emissionMask3 = 1 - emissionMask3;
				}
				
				if (_EmissionMask3GlobalMask > 0)
				{
					emissionMask3 = maskBlend(emissionMask3, poiMods.globalMask[_EmissionMask3GlobalMask - 1], _EmissionMask3GlobalMaskBlendType);
				}
				emissionStrength3 *= glowInTheDarkMultiplier3 * emissionMask3;
				emission3 = max(emissionStrength3 * emissionColor3, 0);
				
				poiFragData.emission += emission3;
				return emission3 * _EmissionReplace3;
			}
			#endif
			//endex
			
			//ifex _EnableRimLighting==0 && _EnableRim2Lighting==0
			#if defined(_GLOSSYREFLECTIONS_OFF) || defined(POI_RIM2)
			#if defined(_RIMSTYLE_POIYOMI) || defined(_RIM2STYLE_POIYOMI)
			void ApplyPoiyomiRimLighting(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight, inout PoiMods poiMods, float Is_NormalMapToRimLight, float RimInvert, float RimPower, float RimStrength, float RimShadowWidth, float RimShadowToggle, float RimWidth, float RimBlendStrength, float RimMask, float RimGlobalMask, float RimGlobalMaskBlendType, float4 RimTex, float4 RimLightColor, float RimLightColorThemeIndex, float RimHueShiftEnabled, float RimHueShift, float RimHueShiftSpeed, float RimSharpness, float RimShadowMaskRampType, float RimShadowMaskInvert, float RimShadowMaskStrength, float2 RimShadowAlpha, float RimApplyGlobalMaskIndex, float RimApplyGlobalMaskBlendType, float RimBaseColorMix, float RimBrightness, float RimBlendMode, half AudioLinkRimWidthBand, float2 AudioLinkRimWidthAdd, half AudioLinkRimEmissionBand, float2 AudioLinkRimEmissionAdd, half AudioLinkRimBrightnessBand, float2 AudioLinkRimBrightnessAdd, float rimBias, float rimBiasIntensity, int RimApplyAlpha, float RimApplyAlphaBlend)
			{
				float viewDotNormal = abs(dot(poiCam.viewDir, lerp(poiMesh.normals[0], poiMesh.normals[1], Is_NormalMapToRimLight)));
				
				UNITY_BRANCH
				if (RimInvert)
				{
					viewDotNormal = 1 - viewDotNormal;
				}
				
				viewDotNormal = pow(viewDotNormal, RimPower);
				
				if (RimShadowWidth && RimShadowToggle)
				{
					viewDotNormal += lerp(0, (1 - poiLight.nDotLNormalized) * 3, RimShadowWidth);
				}
				
				viewDotNormal *= lerp(1, rimBias, rimBiasIntensity);
				
				float rimStrength = RimStrength;
				
				float rimWidth = lerp( - .05, 1, RimWidth);
				
				float blendStrength = RimBlendStrength;
				#ifdef POI_AUDIOLINK
				UNITY_BRANCH
				if (poiMods.audioLinkAvailable)
				{
					rimWidth = clamp(rimWidth + lerp(AudioLinkRimWidthAdd.x, AudioLinkRimWidthAdd.y, poiMods.audioLink[AudioLinkRimWidthBand]), - .05, 1);
					rimStrength += lerp(AudioLinkRimEmissionAdd.x, AudioLinkRimEmissionAdd.y, poiMods.audioLink[AudioLinkRimEmissionBand]);
					RimBrightness += lerp(AudioLinkRimBrightnessAdd.x, AudioLinkRimBrightnessAdd.y, poiMods.audioLink[AudioLinkRimBrightnessBand]);
				}
				#endif
				float rimMask = RimMask;
				
				if (RimGlobalMask > 0)
				{
					rimMask = maskBlend(rimMask, poiMods.globalMask[RimGlobalMask - 1], RimGlobalMaskBlendType);
				}
				
				float4 rimColor = RimTex;
				rimColor *= float4(poiThemeColor(poiMods, RimLightColor.rgb, RimLightColorThemeIndex), RimLightColor.a);
				
				UNITY_BRANCH
				if (RimHueShiftEnabled)
				{
					rimColor.rgb = hueShift(rimColor.rgb, RimHueShift + _Time.x * RimHueShiftSpeed);
				}
				
				float rim = 1 - smoothstep(min(RimSharpness, rimWidth), rimWidth, viewDotNormal);
				rim *= RimLightColor.a * rimColor.a * rimMask;
				
				if (RimShadowToggle)
				{
					switch(RimShadowMaskRampType)
					{
						case 0:
						float rampedLightMap = poiLight.rampedLightMap;
						if (RimShadowMaskInvert) rampedLightMap = 1 - rampedLightMap;
						rim = lerp(rim, rim * rampedLightMap, RimShadowMaskStrength);
						break;
						case 1:
						float nDotLNormalized = poiLight.nDotLNormalized;
						if (RimShadowMaskInvert) nDotLNormalized = 1 - nDotLNormalized;
						rim = lerp(rim, rim * smoothstep(RimShadowAlpha.x, RimShadowAlpha.y, nDotLNormalized), RimShadowMaskStrength);
						break;
					}
				}
				
				if (RimApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, RimApplyGlobalMaskIndex - 1, RimApplyGlobalMaskBlendType, rim * blendStrength);
				}
				
				if (RimApplyAlpha == 1) // Add
				
				{
					poiFragData.alpha += lerp(0, saturate(rim), RimApplyAlphaBlend);
					poiFragData.alpha = saturate(poiFragData.alpha);
				}
				if (RimApplyAlpha == 2) // Multiply
				
				{
					poiFragData.alpha *= lerp(1, saturate(rim), RimApplyAlphaBlend);
				}
				
				float3 finalRimColor = rimColor.rgb * lerp(1, poiFragData.baseColor, RimBaseColorMix);
				finalRimColor *= RimBrightness;
				// Add 0, Replace 1, Multiply 2, Mixed 3
				switch(RimBlendMode)
				{
					case 0: poiFragData.baseColor += finalRimColor * rim * blendStrength; break;
					case 1: poiFragData.baseColor = lerp(poiFragData.baseColor, finalRimColor, rim * blendStrength); break;
					case 2: poiFragData.baseColor = lerp(poiFragData.baseColor, poiFragData.baseColor * finalRimColor, rim * blendStrength); break;
					case 3: poiFragData.baseColor = lerp(poiFragData.baseColor.rgb, poiFragData.baseColor.rgb + poiFragData.baseColor.rgb * finalRimColor, rim * blendStrength); break;
					case 4: poiFragData.baseColor = lerp(poiFragData.baseColor, 1 - (1 - poiFragData.baseColor) * (1 - finalRimColor), rim * blendStrength); break;
				}
				poiFragData.emission += finalRimColor * rim * rimStrength;
			}
			#endif
			#if defined(_RIMSTYLE_UTS2) || defined(_RIM2STYLE_UTS2)
			void ApplyUTS2RimLighting(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight, in PoiMods poiMods, float Set_RimLightMask_var, float RimGlobalMask, float RimGlobalMaskBlendType, float4 RimLightColor, float RimLightColorThemeIndex, float Is_LightColor_RimLight, float Is_NormalMapToRimLight, float RimLight_Power, float RimLight_InsideMask, float RimLight_FeatherOff, float LightDirection_MaskOn, float Tweak_LightDirection_MaskLevel, float Add_Antipodean_RimLight, float4 Ap_RimLightColor, float RimApColorThemeIndex, float Is_LightColor_Ap_RimLight, float Ap_RimLight_Power, float Ap_RimLight_FeatherOff, float Tweak_RimLightMaskLevel, float RimHueShiftEnabled, float RimHueShift, float RimHueShiftSpeed)
			{
				if (RimGlobalMask > 0)
				{
					Set_RimLightMask_var = maskBlend(Set_RimLightMask_var, poiMods.globalMask[RimGlobalMask - 1], RimGlobalMaskBlendType);
				}
				
				float3 rimColor = float3(poiThemeColor(poiMods, RimLightColor.rgb, RimLightColorThemeIndex));
				float3 _Is_LightColor_RimLight_var = lerp(rimColor, (rimColor * poiLight.directColor), Is_LightColor_RimLight);
				float _RimArea_var = (1.0 - dot(lerp(poiMesh.normals[0], poiMesh.normals[1], Is_NormalMapToRimLight), poiCam.viewDir));
				float _RimLightPower_var = pow(_RimArea_var, exp2(lerp(3, 0, RimLight_Power)));
				float _Rimlight_InsideMask_var = saturate(lerp((0.0 + ((_RimLightPower_var - RimLight_InsideMask) * (1.0 - 0.0)) / (1.0 - RimLight_InsideMask)), step(RimLight_InsideMask, _RimLightPower_var), RimLight_FeatherOff));
				float _VertHalfLambert_var = 0.5 * dot(poiMesh.normals[0], poiLight.direction) + 0.5;
				float3 _LightDirection_MaskOn_var = lerp((_Is_LightColor_RimLight_var * _Rimlight_InsideMask_var), (_Is_LightColor_RimLight_var * saturate((_Rimlight_InsideMask_var - ((1.0 - _VertHalfLambert_var) + Tweak_LightDirection_MaskLevel)))), LightDirection_MaskOn);
				float _ApRimLightPower_var = pow(_RimArea_var, exp2(lerp(3, 0, Ap_RimLight_Power)));
				float3 ApRimColor = float3(poiThemeColor(poiMods, Ap_RimLightColor.rgb, RimApColorThemeIndex));
				float3 _RimLight_var = (saturate((Set_RimLightMask_var + Tweak_RimLightMaskLevel)) * lerp(_LightDirection_MaskOn_var, (_LightDirection_MaskOn_var + (lerp(ApRimColor, (ApRimColor * poiLight.directColor), Is_LightColor_Ap_RimLight) * saturate((lerp((0.0 + ((_ApRimLightPower_var - RimLight_InsideMask) * (1.0 - 0.0)) / (1.0 - RimLight_InsideMask)), step(RimLight_InsideMask, _ApRimLightPower_var), Ap_RimLight_FeatherOff) - (saturate(_VertHalfLambert_var) + Tweak_LightDirection_MaskLevel))))), Add_Antipodean_RimLight));
				UNITY_BRANCH
				if (RimHueShiftEnabled)
				{
					_RimLight_var = hueShift(_RimLight_var, RimHueShift + _Time.x * RimHueShiftSpeed);
				}
				poiFragData.baseColor += _RimLight_var;
			}
			#endif
			#if defined(_RIMSTYLE_LILTOON) || defined(_RIM2STYLE_LILTOON)
			void ApplyLiltoonRimLighting(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight, in PoiMods poiMods, float4 RimColor, float4 RimIndirColor, float4 RimColorTex, float RimMainStrength, float RimNormalStrength, float RimDirRange, float RimIndirRange, float RimFresnelPower, float RimBackfaceMask, float RimDirStrength, float RimBorder, float RimBlur, float RimIndirBorder, float RimIndirBlur, float RimShadowMask, float RimEnableLighting, float RimVRParallaxStrength, float RimGlobalMask, float RimGlobalMaskBlendType, float RimHueShiftEnabled, float RimHueShift, float RimHueShiftSpeed, int RimBlendMode)
			{
				if (RimGlobalMask > 0)
				{
					RimColorTex.a = maskBlend(RimColorTex.a, poiMods.globalMask[RimGlobalMask - 1], RimGlobalMaskBlendType);
				}
				float4 rimColor = RimColor;
				float4 rimIndirColor = RimIndirColor;
				rimColor *= RimColorTex;
				rimIndirColor *= RimColorTex;
				
				if (RimHueShiftEnabled)
				{
					rimColor.rgb = hueShift(rimColor.rgb, RimHueShift + _Time.x * RimHueShiftSpeed);
					rimIndirColor.rgb = hueShift(rimIndirColor.rgb, RimHueShift + _Time.x * RimHueShiftSpeed);
				}
				
				rimColor.rgb = lerp(rimColor.rgb, rimColor.rgb * poiFragData.baseColor, RimMainStrength);
				
				// View direction
				float3 centerViewDir = !IsOrthographicCamera() ? normalize(getCameraPosition() - poiMesh.worldPos.xyz) : normalize(UNITY_MATRIX_I_V._m02_m12_m22);
				float3 viewDir = lerp(centerViewDir, poiCam.viewDir, RimVRParallaxStrength);
				
				// Normal
				float3 normal = lerp(poiMesh.normals[0], poiMesh.normals[1], RimNormalStrength);
				float nvabs = abs(dot(normal, viewDir));
				
				// Factor
				float lnRaw = dot(poiLight.direction, normal) * 0.5 + 0.5;
				float lnDir = saturate((lnRaw + RimDirRange) / (1.0 + RimDirRange));
				float lnIndir = saturate((1.0 - lnRaw + RimIndirRange) / (1.0 + RimIndirRange));
				float rim = pow(saturate(1.0 - nvabs), RimFresnelPower);
				rim = !poiMesh.isFrontFace && RimBackfaceMask ? 0.0 : rim;
				float rimDir = lerp(rim, rim * lnDir, RimDirStrength);
				float rimIndir = rim * lnIndir * RimDirStrength;
				
				rimDir = poiEdgeLinear(rimDir, RimBorder, RimBlur);
				rimIndir = poiEdgeLinear(rimIndir, RimIndirBorder, RimIndirBlur);
				
				rimDir = lerp(rimDir, rimDir * poiLight.rampedLightMap, RimShadowMask);
				rimIndir = lerp(rimIndir, rimIndir * poiLight.rampedLightMap, RimShadowMask);
				
				float3 lightCol = poiLight.finalLighting;
				/*
				#if !defined(POI_PASS_ADD)
				rimColor.rgb = lerp(rimColor.rgb, rimColor.rgb * lightCol, RimEnableLighting);
				#else
				if (RimBlendMode < 3) rimColor.rgb *= lightCol * RimEnableLighting;
				#endif
				// Blend
				*/
				#if !defined(POI_PASS_ADD)
				float3 rimLightMul = 1 - RimEnableLighting + lightCol * RimEnableLighting;
				#else
				float3 rimLightMul = RimBlendMode < 3 ? lightCol * RimEnableLighting : 1;
				#endif
				
				poiFragData.finalColor = lilBlendColor(poiFragData.finalColor, rimColor.rgb * rimLightMul, rimDir * rimColor.a, RimBlendMode);
				poiFragData.finalColor = lilBlendColor(poiFragData.finalColor, rimIndirColor.rgb * rimLightMul, rimIndir * rimIndirColor.a, RimBlendMode);
			}
			#endif
			#endif
			//endex
			
			//ifex _EnableDepthRimLighting==0
			#ifdef _POI_DEPTH_RIMLIGHT
			
			float PositivePow(float base, float power)
			{
				return pow(max(abs(base), Epsilon), power);
			}
			
			float GetScaleWithHight()
			{
				return _ScreenParams.y / 1080;
			}
			
			float GetSSRimScale(float z)
			{
				float w = (1.0 / (PositivePow(z + saturate(UNITY_MATRIX_P._m00), 1.5) + 0.75)) * GetScaleWithHight();
				w *= lerp(1, UNITY_MATRIX_P._m00, 0.60 * saturate(0.25 * z * z));
				return w < 0.01 ? 0 : w;
			}
			
			void ApplyDepthRimLighting(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, inout PoiLight poiLight, in PoiMods poiMods)
			{
				float rim = 0;
				float perspectiveDivide = 1.0f / poiCam.clipPos.w;
				float4 direction = poiCam.worldDirection * perspectiveDivide;
				float2 screenPos = poiCam.posScreenSpace.xy * perspectiveDivide;
				float z = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, screenPos);
				
				#if UNITY_REVERSED_Z
				if (z == 0) return;
				#else
				if (z == 1) return;
				#endif
				
				float depth = CorrectedLinearEyeDepth(z, direction.w);
				
				switch(_DepthRimType)
				{
					case 0:
					{
						float3 viewPos = UnityObjectToViewPos(poiMesh.localPos);
						float3 viewDir = normalize(viewPos);
						
						float3 viewNorm = mul((float3x3)UNITY_MATRIX_V, poiMesh.normals[_DepthRimNormalToUse]);
						float3 viewCrossNorm = cross(viewDir, viewNorm);
						float2 N_View = normalize(float2(-viewCrossNorm.y, viewCrossNorm.x));
						
						float3 viewLight = mul((float3x3)UNITY_MATRIX_V, poiLight.direction);
						float3 viewCrossLight = cross(viewDir, viewLight);
						float2 L_View = normalize(float2(-viewCrossLight.y, viewCrossLight.x));
						
						//float lDotN = saturate(poiLight.nDotL + _RimLightLength);
						float scale = _DepthRimWidth * GetSSRimScale(depth);
						float2 ssUV1 = clamp(screenPos + N_View * .1 * scale, 0, _ScreenParams.xy - 1);
						float depthDiff = z - SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, ssUV1) ;
						
						rim = smoothstep(0.24 * _DepthRimSharpness * z, 0.25 * z, depthDiff);
						rim *= lerp(1, (dot(L_View, N_View) > 0), _DepthRimHideInShadow);
					}
					break;
					case 1:
					{
						//float lDotN = saturate(poiLight.nDotL + _RimLightLength);
						float scale = _DepthRimWidth * GetSSRimScale(depth);
						float depthDiff = 0;
						[unroll(9)]
						for (int i = 0; i < 9; i++)
						{
							float2 ssUV1 = clamp(screenPos + sobelSamplePoints[i] * .1 * scale, 0, _ScreenParams.xy - 1);
							depthDiff = max(depthDiff, z - SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, ssUV1));
						}
						rim = smoothstep(0.24 * _DepthRimSharpness * z, 0.25 * z, depthDiff);
						rim *= lerp(1, lerp(poiLight.vertexNDotL > 0, poiLight.nDotL > 0, _DepthRimNormalToUse), _DepthRimHideInShadow);
					}
					break;
				}
				
				float3 rimColor = poiThemeColor(poiMods, _DepthRimColor.rgb, _DepthRimColorThemeIndex).rgb * lerp(1, poiLight.directColor, _DepthRimMixLightColor) * lerp(1, poiFragData.baseColor, _DepthRimMixBaseColor) * _DepthRimBrightness;
				
				#ifdef POI_PASS_BASE
				poiLight.finalLightAdd += rim * rimColor * _DepthRimAdditiveLighting;
				#endif
				poiFragData.emission += rim * rimColor * _DepthRimEmission;
				poiFragData.baseColor = lerp(poiFragData.baseColor, rimColor, rim * _DepthRimReplace);
				poiFragData.baseColor += rim * rimColor * _DepthRimAdd;
				poiFragData.baseColor *= lerp(1, rimColor, rim * _DepthRimMultiply);
			}
			#endif
			//endex
			
			//ifex _GlitterEnable==0
			#ifdef _SUNDISK_SIMPLE
			
			float3 RandomColorFromPoint(float2 rando, PoiMods poiMods)
			{
				fixed hue = random2(rando.x + rando.y).x;
				fixed saturation = lerp(_GlitterMinMaxSaturation.x, _GlitterMinMaxSaturation.y, rando.x);
				fixed value = lerp(_GlitterMinMaxBrightness.x, _GlitterMinMaxBrightness.y, rando.y);
				float3 hsv = float3(hue, saturation, value);
				return HSVtoRGB(hsv);
			}
			
			void applyGlitter(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight, in PoiMods poiMods)
			{
				float glitterRotationTimeOffset = 0;
				#ifdef POI_AUDIOLINK
				if (_GlitterALEnabled)
				{
					glitterRotationTimeOffset += AudioLinkGetChronoTime(_GlitterALChronoRotationSpeedType, _GlitterALChronoRotationSpeedBand) * _GlitterALChronoRotationSpeed;
				}
				#endif
				
				for (int glitterLayer = 0; glitterLayer < _GlitterLayers; glitterLayer++)
				{
					// Scale
					
					float2 st = (poiMesh.uv[_GlitterUV] + _GlitterUVPanning.xy * _Time.x) * _GlitterFrequency;
					
					// Tile the space
					float2 i_st = floor(st);
					float2 f_st = frac(st);
					
					float m_dist = 10.;  // minimun distance
					float2 m_point = 0;        // minimum point
					float2 randoPoint = 0;
					float2 dank = 0;
					for (int j = -1; j <= 1; j++)
					{
						for (int i = -1; i <= 1; i++)
						{
							float2 neighbor = float2(i, j);
							float2 pos = random2(i_st + neighbor + glitterLayer * 0.5141);
							float2 rando = pos;
							pos = pos * _GlitterRandomLocation;
							float2 diff = neighbor + pos - f_st;
							float dist = length(diff);
							
							if (dist < m_dist)
							{
								dank = diff;
								m_dist = dist;
								m_point = pos;
								randoPoint = rando;
							}
						}
					}
					
					float randomFromPoint = random(randoPoint);
					
					float size = _GlitterSize;
					UNITY_BRANCH
					if (_GlitterRandomSize)
					{
						size = lerp(_GlitterMinMaxSize.x, _GlitterMinMaxSize.y, randomFromPoint);
					}
					#ifdef POI_AUDIOLINK
					if (_GlitterALEnabled)
					{
						size = saturate(size + lerp(_GlitterALSizeAdd.x, _GlitterALSizeAdd.y, poiMods.audioLink[_GlitterALSizeAddBand]));
					}
					#endif
					
					// Assign a color using the closest point position
					//color += dot(m_point, float2(.3, .6));
					
					// Add distance field to closest point center
					// color.g = m_dist;
					
					// Show isolines
					//color -= abs(sin(40.0 * m_dist)) * 0.07;
					
					// Draw cell center
					half glitterAlpha = 1;
					switch(_GlitterShape)
					{
						case 0: //circle
						glitterAlpha = saturate((size - m_dist) / clamp(fwidth(m_dist), 0.0001, 1.0));
						break;
						case 1: //sqaure
						float jaggyFix = pow(poiCam.distanceToVert, 2) * _GlitterJaggyFix;
						UNITY_BRANCH
						if (_GlitterRandomRotation == 1 || _GlitterTextureRotation != 0 || _GlitterRandomRotationSpeed.x != 0 || _GlitterRandomRotationSpeed.y != 0 || glitterRotationTimeOffset != 0)
						{
							float2 center = float2(0, 0);
							float2 glitterRandomRotationSpeed = 0;
							float randomBoy = 0;
							UNITY_BRANCH
							if (_GlitterRandomRotation || _GlitterRandomRotationSpeed.x != 0 || _GlitterRandomRotationSpeed.y != 0)
							{
								randomBoy = random(m_point * 200);
								glitterRandomRotationSpeed = lerp(_GlitterRandomRotationSpeed.x, _GlitterRandomRotationSpeed.y, randomBoy);
							}
							if (glitterRandomRotationSpeed.x + glitterRandomRotationSpeed.y + _GlitterTextureRotation == 0 && glitterRotationTimeOffset != 0)
							{
								glitterRandomRotationSpeed = 1;
							}
							float theta = radians((randomBoy + (_Time.x + glitterRotationTimeOffset) * (_GlitterTextureRotation + glitterRandomRotationSpeed)) * 360);
							float cs = cos(theta);
							float sn = sin(theta);
							dank = float2((dank.x - center.x) * cs - (dank.y - center.y) * sn + center.x, (dank.x - center.x) * sn + (dank.y - center.y) * cs + center.y);
							glitterAlpha = (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.x))) * (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.y)));
						}
						else
						{
							glitterAlpha = (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.x))) * (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.y)));
						}
						break;
					}
					
					float3 finalGlitter = 0;
					
					half3 glitterColor = poiThemeColor(poiMods, _GlitterColor.rgb, _GlitterColorThemeIndex);
					
					float3 norm = lerp(poiMesh.normals[0], poiMesh.normals[1], _GlitterUseNormals);
					float3 randomRotation = 0;
					float glitterSpeedOffset = 0;
					#ifdef POI_AUDIOLINK
					if (_GlitterALEnabled)
					{
						glitterSpeedOffset += AudioLinkGetChronoTime(_GlitterALChronoSparkleSpeedType, _GlitterALChronoSparkleSpeedBand) * _GlitterALChronoSparkleSpeed;
					}
					#endif
					switch(_GlitterMode)
					{
						case 0:
						UNITY_BRANCH
						if (_GlitterSpeed + glitterSpeedOffset > 0)
						{
							randomRotation = randomFloat3WiggleRange(randoPoint, _GlitterAngleRange, _GlitterSpeed, glitterSpeedOffset);
						}
						else
						{
							randomRotation = randomFloat3Range(randoPoint, _GlitterAngleRange);
						}
						
						float3 glitterReflectionDirection = normalize(mul(poiRotationMatrixFromAngles(randomRotation), norm));
						finalGlitter = lerp(0, _GlitterMinBrightness * glitterAlpha, glitterAlpha) + max(pow(saturate(dot(lerp(glitterReflectionDirection, poiCam.viewDir, _GlitterBias), poiCam.viewDir)), _GlitterContrast), 0);
						finalGlitter *= glitterAlpha;
						break;
						case 1:
						float randomOffset = random(randoPoint);
						float brightness = (sin((_Time.x * 10 + randomOffset +glitterSpeedOffset) * _GlitterSpeed) * .5 + .5);
						finalGlitter = max(_GlitterMinBrightness * glitterAlpha, brightness * glitterAlpha * smoothstep(0, 1, 1 - m_dist * _GlitterCenterSize * 10));
						break;
						case 2:
						if (_GlitterSpeed + glitterSpeedOffset > 0)
						{
							randomRotation = randomFloat3WiggleRange(randoPoint, _GlitterAngleRange, _GlitterSpeed, glitterSpeedOffset);
						}
						else
						{
							randomRotation = randomFloat3Range(randoPoint, _GlitterAngleRange);
						}
						
						float3 glitterLightReflectionDirection = normalize(mul(poiRotationMatrixFromAngles(randomRotation), norm));
						
						glitterAlpha *= poiLight.nDotLSaturated;
						
						float3 halfDir = normalize(poiLight.direction + poiCam.viewDir);
						float specAngle = max(dot(halfDir, glitterLightReflectionDirection), 0.0);
						
						finalGlitter = lerp(0, _GlitterMinBrightness * glitterAlpha, glitterAlpha) + max(pow(specAngle, _GlitterContrast), 0);
						
						glitterColor *= poiLight.directColor;
						finalGlitter *= glitterAlpha;
						
						break;
					}
					
					glitterColor *= lerp(1, poiFragData.baseColor, _GlitterUseSurfaceColor);
					#if defined(PROP_GLITTERCOLORMAP) || !defined(OPTIMIZER_ENABLED)
					glitterColor *= POI2D_SAMPLER_PAN(_GlitterColorMap, _MainTex, poiUV(poiMesh.uv[_GlitterColorMapUV], _GlitterColorMap_ST), _GlitterColorMapPan).rgb;
					#endif
					float2 uv = remapClamped(-size, size, dank, 0, 1);
					UNITY_BRANCH
					
					if (_GlitterRandomRotation == 1 || _GlitterTextureRotation != 0 || _GlitterRandomRotationSpeed.x != 0 || _GlitterRandomRotationSpeed.y && !_GlitterShape || glitterRotationTimeOffset != 0)
					{
						float2 fakeUVCenter = float2(.5, .5);
						float randomBoy = 0;
						float2 glitterRandomRotationSpeed = 0;
						UNITY_BRANCH
						if (_GlitterRandomRotation || _GlitterRandomRotationSpeed.x != 0 || _GlitterRandomRotationSpeed.y != 0)
						{
							randomBoy = random(randoPoint * 20);
							glitterRandomRotationSpeed = lerp(_GlitterRandomRotationSpeed.x, _GlitterRandomRotationSpeed.y, randomBoy);
						}
						if (glitterRandomRotationSpeed.x + glitterRandomRotationSpeed.y + _GlitterTextureRotation == 0 && glitterRotationTimeOffset != 0)
						{
							glitterRandomRotationSpeed = 1;
						}
						float theta = radians((randomBoy + (_Time.x + glitterRotationTimeOffset) * (_GlitterTextureRotation + glitterRandomRotationSpeed)) * 360);
						float cs = cos(theta);
						float sn = sin(theta);
						uv = float2((uv.x - fakeUVCenter.x) * cs - (uv.y - fakeUVCenter.y) * sn + fakeUVCenter.x, (uv.x - fakeUVCenter.x) * sn + (uv.y - fakeUVCenter.y) * cs + fakeUVCenter.y);
					}
					
					#if defined(PROP_GLITTERTEXTURE) || !defined(OPTIMIZER_ENABLED)
					float4 glitterTexture = POI2D_SAMPLER_PANGRAD(_GlitterTexture, _linear_clamp, poiUV(uv, _GlitterTexture_ST), _GlitterTexturePan, poiMesh.dx, poiMesh.dy);
					#else
					float4 glitterTexture = 1;
					#endif
					//float4 glitterTexture = _GlitterTexture.SampleGrad(sampler_MainTex, frac(uv), ddx(uv), ddy(uv));
					glitterColor *= glitterTexture.rgb;
					#if defined(PROP_GLITTERMASK) || !defined(OPTIMIZER_ENABLED)
					float glitterMask = POI2D_SAMPLER_PAN(_GlitterMask, _MainTex, poiUV(poiMesh.uv[_GlitterMaskUV], _GlitterMask_ST), _GlitterMaskPan)[_GlitterMaskChannel];
					#else
					float glitterMask = 1;
					#endif
					
					#ifdef POI_AUDIOLINK
					if (_GlitterALEnabled)
					{
						glitterMask = clamp(glitterMask + lerp(_GlitterALAlphaAdd.x, _GlitterALAlphaAdd.y, poiMods.audioLink[_GlitterALAlphaAddBand]), 0, glitterMask);
					}
					#endif
					
					if (_GlitterMaskInvert)
					{
						glitterMask = 1 - glitterMask;
					}
					
					glitterMask *= lerp(1, poiLight.rampedLightMap, _GlitterHideInShadow);
					glitterMask *= lerp(1, poiLight.directLuminance, _GlitterScaleWithLighting);
					glitterMask *= _GlitterColor.a;
					
					if (_GlitterMaskGlobalMask > 0)
					{
						glitterMask = maskBlend(glitterMask, poiMods.globalMask[_GlitterMaskGlobalMask - 1], _GlitterMaskGlobalMaskBlendType);
					}
					
					if (_GlitterRandomColors)
					{
						glitterColor *= RandomColorFromPoint(random2(randoPoint.x + randoPoint.y), poiMods);
					}
					
					UNITY_BRANCH
					if (_GlitterHueShiftEnabled)
					{
						glitterColor.rgb = hueShift(glitterColor.rgb, _GlitterHueShift + _Time.x * _GlitterHueShiftSpeed);
					}
					float GlitterbrightnessOffset = 0;
					#ifdef POI_AUDIOLINK
					if (_GlitterALEnabled)
					{
						GlitterbrightnessOffset = max(GlitterbrightnessOffset +lerp(_GlitterALMaxBrightnessAdd.x, _GlitterALMaxBrightnessAdd.y, poiMods.audioLink[_GlitterALMaxBrightnessBand]), 0);
					}
					#endif
					
					UNITY_BRANCH
					if (_GlitterBlendType == 1)
					{
						poiFragData.baseColor = lerp(poiFragData.baseColor, finalGlitter * glitterColor * (_GlitterBrightness + GlitterbrightnessOffset), finalGlitter * glitterTexture.a * glitterMask);
						poiFragData.emission += finalGlitter * glitterColor * max(0, ((_GlitterBrightness + GlitterbrightnessOffset) - 1) * glitterTexture.a) * glitterMask;
					}
					else
					{
						poiFragData.emission += finalGlitter * glitterColor * (_GlitterBrightness + GlitterbrightnessOffset) * glitterTexture.a * glitterMask;
					}
				}
			}
			#endif
			//endex
			
			//ifex _SubsurfaceScattering==0
			#ifdef POI_SUBSURFACESCATTERING
			void applySubsurfaceScattering(in PoiCam poiCam, inout PoiLight poiLight, in PoiMesh poiMesh, in PoiFragData poiFragData)
			{
				float4 SSS = 1;
				#if defined(PROP_SSSTHICKNESSMAP) || !defined(OPTIMIZER_ENABLED)
				SSS = POI2D_SAMPLER_PAN(_SSSThicknessMap, _MainTex, poiUV(poiMesh.uv[_SSSThicknessMapUV], _SSSThicknessMap_ST), _SSSThicknessMapPan);
				SSS.a = 1 - SSS.a;
				#endif
				
				float3 vLTLight = poiLight.direction + poiMesh.normals[0] * _SSSDistortion;
				float flTDot = pow(saturate(dot(poiCam.viewDir, -vLTLight)), _SSSSpread) * _SSSStrength;
				#ifdef UNITY_PASS_FORWARDBASE
				float3 fLT = (flTDot) * saturate(SSS.a + - 1 * _SSSThicknessMod);
				#else
				float3 fLT = poiLight.additiveShadow * (flTDot) * saturate(SSS.a + - 1 * _SSSThicknessMod);
				#endif
				
				#if defined(POINT) || defined(SPOT)
				poiLight.finalLightAdd += fLT * poiLight.directColor * _SSSColor * SSS.rgb * lerp(1, poiFragData.baseColor, _SSSBaseColorMix);
				#endif
				poiLight.finalLightAdd += fLT * poiLight.directColor * _SSSColor * SSS.rgb * poiLight.attenuation * lerp(1, poiFragData.baseColor, _SSSBaseColorMix);
			}
			#endif
			//endex
			
			//ifex _MochieBRDF==0 && _ClearCoatBRDF==0
			#if defined(MOCHIE_PBR) || defined(POI_CLEARCOAT)
			
			/*
			* Copyright 2022 orels1
			*
			* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
			*
			* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
			*
			* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
			*/
			
			// https://github.com/orels1/orels-Unity-Shaders
			
			float GSAA_Filament(float3 worldNormal, float perceptualRoughness, float gsaaVariance, float gsaaThreshold)
			{
				// Kaplanyan 2016, "Stable specular highlights"
				// Tokuyoshi 2017, "Error Reduction and Simplification for Shading Anti-Aliasing"
				// Tokuyoshi and Kaplanyan 2019, "Improved Geometric Specular Antialiasing"
				
				// This implementation is meant for deferred rendering in the original paper but
				// we use it in forward rendering as well (as discussed in Tokuyoshi and Kaplanyan
				// 2019). The main reason is that the forward version requires an expensive transform
				// of the float vector by the tangent frame for every light. This is therefore an
				// approximation but it works well enough for our needs and provides an improvement
				// over our original implementation based on Vlachos 2015, "Advanced VR Rendering".
				
				float3 du = ddx(worldNormal);
				float3 dv = ddy(worldNormal);
				
				float variance = gsaaVariance * (dot(du, du) + dot(dv, dv));
				
				float roughness = perceptualRoughness * perceptualRoughness;
				float kernelRoughness = min(2.0 * variance, gsaaThreshold);
				float squareRoughness = saturate(roughness * roughness + kernelRoughness);
				
				return sqrt(sqrt(squareRoughness));
			}
			
			/*
			MIT END
			*/
			
			bool SceneHasReflections()
			{
				float width, height;
				unity_SpecCube0.GetDimensions(width, height);
				return !(width * height < 2);
			}
			
			float3 GetWorldReflections(float3 reflDir, float3 worldPos, float roughness)
			{
				float3 baseReflDir = reflDir;
				reflDir = BoxProjection(reflDir, worldPos, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax);
				float4 envSample0 = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, reflDir, roughness * UNITY_SPECCUBE_LOD_STEPS);
				float3 p0 = DecodeHDR(envSample0, unity_SpecCube0_HDR);
				float interpolator = unity_SpecCube0_BoxMin.w;
				UNITY_BRANCH
				if (interpolator < 0.99999)
				{
					float3 refDirBlend = BoxProjection(baseReflDir, worldPos, unity_SpecCube1_ProbePosition, unity_SpecCube1_BoxMin, unity_SpecCube1_BoxMax);
					float4 envSample1 = UNITY_SAMPLE_TEXCUBE_SAMPLER_LOD(unity_SpecCube1, unity_SpecCube0, refDirBlend, roughness * UNITY_SPECCUBE_LOD_STEPS);
					float3 p1 = DecodeHDR(envSample1, unity_SpecCube1_HDR);
					p0 = lerp(p1, p0, interpolator);
				}
				return p0;
			}
			
			float3 GetReflections(in PoiCam poiCam, in PoiLight pl, in PoiMesh poiMesh, float roughness, float ForceFallback, float LightFallback, samplerCUBE reflectionCube, float4 hdrData, float3 reflectionDir)
			{
				float3 reflections = 0;
				float3 lighting = pl.finalLighting;
				// This is a separate conditional so it can optimize out when ForceFallback isn't animated
				if (ForceFallback == 0)
				{
					UNITY_BRANCH
					if (SceneHasReflections())
					{
						#ifdef UNITY_PASS_FORWARDBASE
						reflections = GetWorldReflections(reflectionDir, poiMesh.worldPos.xyz, roughness);
						#endif
					}
					else
					{
						#ifdef UNITY_PASS_FORWARDBASE
						reflections = texCUBElod(reflectionCube, float4(reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
						reflections = DecodeHDR(float4(reflections, 1), hdrData) * lerp(1, pl.finalLighting, LightFallback);
						#endif
						#ifdef POI_PASS_ADD
						if (LightFallback)
						{
							reflections = texCUBElod(reflectionCube, float4(reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
							reflections = DecodeHDR(float4(reflections, 1), hdrData) * pl.finalLighting;
						}
						#endif
					}
				}
				else
				{
					#ifdef UNITY_PASS_FORWARDBASE
					reflections = texCUBElod(reflectionCube, float4(reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
					reflections = DecodeHDR(float4(reflections, 1), hdrData) * lerp(1, pl.finalLighting, LightFallback);
					#endif
					#ifdef POI_PASS_ADD
					if (LightFallback)
					{
						reflections = texCUBElod(reflectionCube, float4(reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
						reflections = DecodeHDR(float4(reflections, 1), hdrData) * pl.finalLighting;
					}
					#endif
				}
				reflections *= pl.occlusion;
				return reflections;
			}
			
			float GetGGXTerm(float nDotL, float nDotV, float nDotH, float roughness)
			{
				float visibilityTerm = 0;
				if (nDotL > 0)
				{
					float rough = roughness;
					float rough2 = roughness * roughness;
					
					float lambdaV = nDotL * (nDotV * (1 - rough) + rough);
					float lambdaL = nDotV * (nDotL * (1 - rough) + rough);
					
					visibilityTerm = 0.5f / (lambdaV + lambdaL + 1e-5f);
					float d = (nDotH * rough2 - nDotH) * nDotH + 1.0f;
					float dotTerm = UNITY_INV_PI * rough2 / (d * d + 1e-7f);
					
					visibilityTerm *= dotTerm * UNITY_PI;
				}
				return visibilityTerm;
			}
			
			void GetSpecFresTerm(float nDotL, float nDotV, float nDotH, float lDotH, inout float3 specularTerm, inout float3 fresnelTerm, float3 specCol, float roughness)
			{
				specularTerm = GetGGXTerm(nDotL, nDotV, nDotH, roughness);
				fresnelTerm = FresnelTerm(specCol, lDotH);
				specularTerm = max(0, specularTerm * max(0.00001, nDotL));
			}
			
			float GetRoughness(float smoothness)
			{
				float rough = 1 - smoothness;
				rough *= 1.7 - 0.7 * rough;
				return rough;
			}
			#endif
			//endex
			
			//ifex _MochieBRDF==0
			#ifdef MOCHIE_PBR
			void MetallicAndSpecularFragDataInit(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float smoothness = _MochieRoughnessMultiplier;
				float smoothness2 = _MochieRoughnessMultiplier2;
				float metallic = _MochieMetallicMultiplier;
				float specularMask = 1;
				float reflectionMask = 1;
				
				smoothness *= poiFragData.smoothness;
				smoothness2 *= poiFragData.smoothness2;
				metallic *= poiFragData.metallic;
				specularMask *= poiFragData.specularMask;
				reflectionMask *= poiFragData.reflectionMask;
				
				#if defined(PROP_MOCHIEMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 PBRMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_MochieMetallicMaps, _MainTex, poiUV(poiMesh.uv[_MochieMetallicMapsUV], _MochieMetallicMaps_ST), _MochieMetallicMapsPan, _MochieMetallicMapsStochastic);
				UNITY_BRANCH
				if (_PBRSplitMaskSample)
				{
					float4 PBRSplitMask = POI2D_SAMPLER_PAN_STOCHASTIC(_MochieMetallicMaps, _MainTex, poiUV(poiMesh.uv[_MochieMetallicMasksUV], _PBRMaskScaleTiling), _MochieMetallicMasksPan.xy, _PBRSplitMaskStochastic);
					assignValueToVectorFromIndex(PBRMaps, _MochieMetallicMapsReflectionMaskChannel, PBRSplitMask[_MochieMetallicMapsReflectionMaskChannel]);
					assignValueToVectorFromIndex(PBRMaps, _MochieMetallicMapsSpecularMaskChannel, PBRSplitMask[_MochieMetallicMapsSpecularMaskChannel]);
				}
				
				if (_MochieMetallicMapsMetallicChannel < 4)
				{
					metallic *= PBRMaps[_MochieMetallicMapsMetallicChannel];
				}
				if (_MochieMetallicMapsRoughnessChannel < 4)
				{
					smoothness *= PBRMaps[_MochieMetallicMapsRoughnessChannel];
					smoothness2 *= PBRMaps[_MochieMetallicMapsRoughnessChannel];
				}
				if (_MochieMetallicMapsReflectionMaskChannel < 4)
				{
					reflectionMask *= PBRMaps[_MochieMetallicMapsReflectionMaskChannel];
				}
				if (_MochieMetallicMapsSpecularMaskChannel < 4)
				{
					specularMask *= PBRMaps[_MochieMetallicMapsSpecularMaskChannel];
				}
				#endif
				
				reflectionMask *= _MochieReflectionStrength;
				specularMask *= _MochieSpecularStrength;
				
				if (_MochieMetallicMapInvert)
				{
					metallic = 1 - metallic;
				}
				if (_MochieRoughnessMapInvert)
				{
					smoothness = 1 - smoothness;
					smoothness2 = 1 - smoothness2;
				}
				if (_MochieReflectionMaskInvert)
				{
					reflectionMask = 1 - reflectionMask;
				}
				if (_MochieSpecularMaskInvert)
				{
					specularMask = 1 - specularMask;
				}
				
				poiFragData.smoothness *= smoothness;
				poiFragData.smoothness2 *= smoothness2;
				poiFragData.metallic *= metallic;
				poiFragData.specularMask *= specularMask;
				poiFragData.reflectionMask *= reflectionMask;
			}
			
			void MochieBRDF(inout PoiFragData poiFragData, in PoiCam poiCam, inout PoiLight poiLight, in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				float smoothness = poiFragData.smoothness;
				float smoothness2 = poiFragData.smoothness2;
				float metallic = poiFragData.metallic;
				float specularMask = poiFragData.specularMask;
				float reflectionMask = poiFragData.reflectionMask;
				
				if (_MochieMetallicGlobalMask > 0)
				{
					metallic = customBlend(metallic, poiMods.globalMask[_MochieMetallicGlobalMask - 1], _MochieMetallicGlobalMaskBlendType);
				}
				if (_MochieSmoothnessGlobalMask > 0)
				{
					smoothness = customBlend(smoothness, poiMods.globalMask[_MochieSmoothnessGlobalMask - 1], _MochieSmoothnessGlobalMaskBlendType);
					smoothness2 = customBlend(smoothness2, poiMods.globalMask[_MochieSmoothnessGlobalMask - 1], _MochieSmoothnessGlobalMaskBlendType);
				}
				if (_MochieReflectionStrengthGlobalMask > 0)
				{
					reflectionMask = customBlend(reflectionMask, poiMods.globalMask[_MochieReflectionStrengthGlobalMask - 1], _MochieReflectionStrengthGlobalMaskBlendType);
				}
				if (_MochieSpecularStrengthGlobalMask > 0)
				{
					specularMask = customBlend(specularMask, poiMods.globalMask[_MochieSpecularStrengthGlobalMask - 1], _MochieSpecularStrengthGlobalMaskBlendType);
				}
				
				#ifdef TPS_Penetrator
				if (_BRDFTPSDepthEnabled)
				{
					reflectionMask = lerp(0, reflectionMask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _BRDFTPSReflectionMaskStrength);
					specularMask = lerp(0, specularMask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _BRDFTPSSpecularMaskStrength);
				}
				#endif
				
				float roughness = GetRoughness(smoothness);
				float roughness2 = GetRoughness(smoothness2);
				float3 specCol = lerp(unity_ColorSpaceDielectricSpec.rgb, poiFragData.baseColor, metallic);
				float omr = unity_ColorSpaceDielectricSpec.a - metallic * unity_ColorSpaceDielectricSpec.a;
				float percepRough = 1 - smoothness;
				float percepRough2 = 1 - smoothness2;
				UNITY_BRANCH
				if (_MochieGSAAEnabled)
				{
					percepRough = GSAA_Filament(poiMesh.normals[_PBRNormalSelect], percepRough, _PoiGSAAVariance, _PoiGSAAThreshold);
					if (_Specular2ndLayer == 1 && _MochieSpecularStrength2 > 0)
					{
						percepRough2 = GSAA_Filament(poiMesh.normals[_PBRNormalSelect], percepRough2, _PoiGSAAVariance, _PoiGSAAThreshold);
					}
				}
				float brdfRoughness = percepRough * percepRough;
				brdfRoughness = max(brdfRoughness, 0.002);
				
				float brdfRoughness2 = percepRough2 * percepRough2;
				brdfRoughness2 = max(brdfRoughness2, 0.002);
				
				float3 diffuse = poiFragData.baseColor;
				float3 specular = 0;
				float3 specular2 = 0;
				float3 vSpecular = 0;
				float3 vSpecular2 = 0;
				float3 reflections = 0;
				float3 environment = 0;
				
				#if defined(POINT) || defined(SPOT)
				float attenuation = lerp(poiLight.additiveShadow, 1, _IgnoreCastedShadows);
				#else
				float attenuation = min(poiLight.nDotLSaturated, lerp(poiLight.attenuation, 1, _IgnoreCastedShadows));
				#endif
				
				float3 fresnelTerm = 1;
				float3 specularTerm = 1;
				
				float pbrNDotL = lerp(poiLight.vertexNDotL, poiLight.nDotL, _PBRNormalSelect);
				float pbrNDotV = lerp(poiLight.vertexNDotV, poiLight.nDotV, _PBRNormalSelect);
				float pbrNDotH = lerp(poiLight.vertexNDotH, poiLight.nDotH, _PBRNormalSelect);
				float3 pbrReflectionDir = lerp(poiCam.vertexReflectionDir, poiCam.reflectionDir, _PBRNormalSelect);
				
				GetSpecFresTerm(pbrNDotL, pbrNDotV, pbrNDotH, poiLight.lDotH, specularTerm, fresnelTerm, specCol, brdfRoughness);
				specular = poiLight.directColor * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _MochieSpecularTint, _MochieSpecularTintThemeIndex) * poiLight.occlusion * attenuation;
				
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					for (int index = 0; index < 4; index++)
					{
						fresnelTerm = 1;
						specularTerm = 1;
						float pbrVDotNL = lerp(poiLight.vertexVDotNL[index], poiLight.vDotNL[index], _PBRNormalSelect);
						float pbrVDotNH = lerp(poiLight.vertexVDotNH[index], poiLight.vDotNH[index], _PBRNormalSelect);
						GetSpecFresTerm(pbrVDotNL, pbrNDotV, pbrVDotNH, poiLight.vDotLH[index], specularTerm, fresnelTerm, specCol, brdfRoughness);
						vSpecular += poiLight.vColor[index] * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _MochieSpecularTint, _MochieSpecularTintThemeIndex) * poiLight.occlusion;
					}
					#endif
				}
				
				if (_Specular2ndLayer == 1)
				{
					float3 fresnelTerm = 1;
					float3 specularTerm = 1;
					GetSpecFresTerm(pbrNDotL, pbrNDotV, pbrNDotH, poiLight.lDotH, specularTerm, fresnelTerm, specCol, brdfRoughness2);
					specular2 = poiLight.directColor * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _MochieSpecularTint, _MochieSpecularTintThemeIndex) * poiLight.occlusion * attenuation * _MochieSpecularStrength2;
					
					if (poiFragData.toggleVertexLights)
					{
						#if defined(VERTEXLIGHT_ON)
						for (int index = 0; index < 4; index++)
						{
							fresnelTerm = 1;
							specularTerm = 1;
							float pbrVDotNL = lerp(poiLight.vertexVDotNL[index], poiLight.vDotNL[index], _PBRNormalSelect);
							float pbrVDotNH = lerp(poiLight.vertexVDotNH[index], poiLight.vDotNH[index], _PBRNormalSelect);
							GetSpecFresTerm(pbrVDotNL, pbrNDotV, pbrVDotNH, poiLight.vDotLH[index], specularTerm, fresnelTerm, specCol, brdfRoughness2);
							vSpecular2 += poiLight.vColor[index] * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _MochieSpecularTint, _MochieSpecularTintThemeIndex) * poiLight.occlusion * _MochieSpecularStrength2;
						}
						#endif
					}
				}
				
				float surfaceReduction = (1.0 / (brdfRoughness * brdfRoughness + 1.0));
				float grazingTerm = saturate(smoothness + (1 - omr));
				float3 reflCol = GetReflections(poiCam, poiLight, poiMesh, roughness, _MochieForceFallback, _MochieLitFallback, _MochieReflCube, _MochieReflCube_HDR, pbrReflectionDir);
				if (poiMesh.isFrontFace)
				{
					reflections = surfaceReduction * reflCol * lerp(1, FresnelLerp(specCol, grazingTerm, pbrNDotV), _RefSpecFresnel);
				}
				else
				{
					reflections = surfaceReduction * reflCol * lerp(1, FresnelLerp(specCol, grazingTerm, pbrNDotV), _RefSpecFresnelBack);
				}
				
				reflections *= poiThemeColor(poiMods, _MochieReflectionTint, _MochieReflectionTintThemeIndex);
				reflections *= reflectionMask;
				diffuse = lerp(diffuse, diffuse * omr, reflectionMask);
				
				environment = max(specular + vSpecular, specular2 + vSpecular2);
				environment += reflections;
				diffuse *= poiLight.finalLighting;
				poiFragData.finalColor = diffuse;
				poiLight.finalLightAdd += environment;
			}
			#endif
			//endex
			//ifex _ClearCoatBRDF==0
			#ifdef POI_CLEARCOAT
			void poiClearCoat(inout PoiFragData poiFragData, in PoiCam poiCam, inout PoiLight poiLight, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float clearCoatMask = _ClearCoatStrength;
				float smoothness = _ClearCoatSmoothness;
				float reflectionMask = _ClearCoatReflectionStrength;
				float specularMask = _ClearCoatSpecularStrength;
				
				#if defined(PROP_CLEARCOATMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 PBRMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_ClearCoatMaps, _MainTex, poiUV(poiMesh.uv[_ClearCoatMapsUV], _ClearCoatMaps_ST), _ClearCoatMapsPan, _ClearCoatMapsStochastic);
				
				if (_ClearCoatMapsClearCoatMaskChannel < 4)
				{
					clearCoatMask *= PBRMaps[_ClearCoatMapsClearCoatMaskChannel];
				}
				if (_ClearCoatMapsRoughnessChannel < 4)
				{
					smoothness *= PBRMaps[_ClearCoatMapsRoughnessChannel];
				}
				if (_ClearCoatMapsReflectionMaskChannel < 4)
				{
					reflectionMask *= PBRMaps[_ClearCoatMapsReflectionMaskChannel];
				}
				if (_ClearCoatMapsSpecularMaskChannel < 4)
				{
					specularMask *= PBRMaps[_ClearCoatMapsSpecularMaskChannel];
				}
				#endif
				
				if (_ClearCoatGlobalMask > 0)
				{
					clearCoatMask = customBlend(clearCoatMask, poiMods.globalMask[_ClearCoatGlobalMask - 1], _ClearCoatGlobalMaskBlendType);
				}
				if (_ClearCoatSmoothnessGlobalMask > 0)
				{
					smoothness = customBlend(smoothness, poiMods.globalMask[_ClearCoatSmoothnessGlobalMask - 1], _ClearCoatSmoothnessGlobalMaskBlendType);
				}
				if (_ClearCoatReflectionStrengthGlobalMask > 0)
				{
					reflectionMask = customBlend(reflectionMask, poiMods.globalMask[_ClearCoatReflectionStrengthGlobalMask - 1], _ClearCoatReflectionStrengthGlobalMaskBlendType);
				}
				if (_ClearCoatSpecularStrengthGlobalMask > 0)
				{
					specularMask = customBlend(specularMask, poiMods.globalMask[_ClearCoatSpecularStrengthGlobalMask - 1], _ClearCoatSpecularStrengthGlobalMaskBlendType);
				}
				
				if (_ClearCoatMaskInvert)
				{
					clearCoatMask = 1 - clearCoatMask;
				}
				if (_ClearCoatSmoothnessMapInvert)
				{
					smoothness = 1 - smoothness;
				}
				if (_ClearCoatReflectionMaskInvert)
				{
					reflectionMask = 1 - reflectionMask;
				}
				if (_ClearCoatSpecularMaskInvert)
				{
					specularMask = 1 - specularMask;
				}
				#ifdef TPS_Penetrator
				if (_ClearCoatTPSDepthMaskEnabled)
				{
					clearCoatMask = lerp(0, clearCoatMask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _ClearCoatTPSMaskStrength);
				}
				#endif
				
				float roughness = GetRoughness(smoothness);
				float3 specCol = 0.220916301;
				float omr = unity_ColorSpaceDielectricSpec.a;
				float percepRough = 1 - smoothness;
				UNITY_BRANCH
				if (_ClearCoatGSAAEnabled)
				{
					percepRough = GSAA_Filament(poiMesh.normals[_ClearCoatNormalSelect], percepRough, _ClearCoatGSAAVariance, _ClearCoatGSAAThreshold);
				}
				float brdfRoughness = percepRough * percepRough;
				brdfRoughness = max(brdfRoughness, 0.002);
				
				float3 diffuse = 0;
				float3 specular = 0;
				float3 vSpecular = 0;
				float3 reflections = 0;
				float3 environment = 0;
				float attenuation = min(poiLight.nDotLSaturated, lerp(poiLight.attenuation, 1, _CCIgnoreCastedShadows));
				
				float3 fresnelTerm = 1;
				float3 specularTerm = 1;
				
				float clearcoatNDotL = lerp(poiLight.vertexNDotL, poiLight.nDotL, _ClearCoatNormalSelect);
				float clearcoatNDotV = lerp(poiLight.vertexNDotV, poiLight.nDotV, _ClearCoatNormalSelect);
				float clearcoatNDotH = lerp(poiLight.vertexNDotH, poiLight.nDotH, _ClearCoatNormalSelect);
				float3 clearcoatReflectionDir = lerp(poiCam.vertexReflectionDir, poiCam.reflectionDir, _ClearCoatNormalSelect);
				
				GetSpecFresTerm(clearcoatNDotL, clearcoatNDotV, clearcoatNDotH, poiLight.lDotH, specularTerm, fresnelTerm, specCol, brdfRoughness);
				specular = poiLight.directColor * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _ClearCoatSpecularTint, _ClearCoatSpecularTintThemeIndex) * poiLight.occlusion * attenuation;
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					for (int index = 0; index < 4; index++)
					{
						fresnelTerm = 1;
						specularTerm = 1;
						float clearcoatVDotNL = lerp(poiLight.vertexVDotNL[index], poiLight.vDotNL[index], _ClearCoatNormalSelect);
						float clearcoatVDotNH = lerp(poiLight.vertexVDotNH[index], poiLight.vDotNH[index], _ClearCoatNormalSelect);
						GetSpecFresTerm(clearcoatVDotNL, clearcoatNDotV, clearcoatVDotNH, poiLight.vDotLH[index], specularTerm, fresnelTerm, specCol, brdfRoughness);
						vSpecular += poiLight.vColor[index] * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _ClearCoatSpecularTint, _ClearCoatSpecularTintThemeIndex) * poiLight.occlusion;
					}
					#endif
				}
				
				float surfaceReduction = (1.0 / (brdfRoughness * brdfRoughness + 1.0));
				float grazingTerm = saturate(smoothness + (1 - omr));
				float3 reflCol = GetReflections(poiCam, poiLight, poiMesh, roughness, _ClearCoatForceFallback, _ClearCoatLitFallback, _ClearCoatFallback, _ClearCoatFallback_HDR, clearcoatReflectionDir);
				reflections = surfaceReduction * reflCol * lerp(1, FresnelLerp(specCol, grazingTerm, clearcoatNDotV), _ClearcoatFresnel);
				reflections *= poiThemeColor(poiMods, _ClearCoatReflectionTint, _ClearCoatReflectionTintThemeIndex) * reflectionMask;
				diffuse = lerp(diffuse, diffuse * omr, reflectionMask);
				
				environment = specular + vSpecular;
				#ifdef UNITY_PASS_FORWARDBASE
				environment += reflections;
				#endif
				//diffuse *= poiLight.finalLighting;
				diffuse += environment;
				poiLight.finalLightAdd += saturate(diffuse * clearCoatMask);
			}
			#endif
			//endex
			
			//ifex _EnableEnvironmentalRim==0
			#ifdef POI_ENVIRORIM
			void applyEnvironmentRim(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam)
			{
				float enviroRimAlpha = saturate(1 - smoothstep(min(_RimEnviroSharpness, _RimEnviroWidth), _RimEnviroWidth, poiCam.vDotN));
				_RimEnviroBlur *= 1.7 - 0.7 * _RimEnviroBlur;
				
				float3 enviroRimColor = 0;
				float interpolator = unity_SpecCube0_BoxMin.w;
				UNITY_BRANCH
				if (interpolator < 0.99999)
				{
					//Probe 1
					float4 reflectionData0 = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, poiMesh.normals[1], _RimEnviroBlur * UNITY_SPECCUBE_LOD_STEPS);
					float3 reflectionColor0 = DecodeHDR(reflectionData0, unity_SpecCube0_HDR);
					
					//Probe 2
					float4 reflectionData1 = UNITY_SAMPLE_TEXCUBE_SAMPLER_LOD(unity_SpecCube1, unity_SpecCube0, poiMesh.normals[1], _RimEnviroBlur * UNITY_SPECCUBE_LOD_STEPS);
					float3 reflectionColor1 = DecodeHDR(reflectionData1, unity_SpecCube1_HDR);
					
					enviroRimColor = lerp(reflectionColor1, reflectionColor0, interpolator);
				}
				else
				{
					float4 reflectionData = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, poiMesh.normals[1], _RimEnviroBlur * UNITY_SPECCUBE_LOD_STEPS);
					enviroRimColor = DecodeHDR(reflectionData, unity_SpecCube0_HDR);
				}
				
				half enviroMask = 1;
				#if defined(PROP_RIMENVIROMASK) || !defined(OPTIMIZER_ENABLED)
				enviroMask = POI2D_SAMPLER_PAN(_RimEnviroMask, _MainTex, poiMesh.uv[_RimEnviroMaskUV], _RimEnviroMaskPan)[_RimEnviroChannel];
				#endif
				float3 envRimCol = lerp(0, max(0, (enviroRimColor - _RimEnviroMinBrightness) * poiFragData.baseColor), enviroRimAlpha).rgb * enviroMask * _RimEnviroIntensity;
				poiFragData.finalColor += envRimCol;
			}
			#endif
			//endex
			
			//ifex _StylizedSpecular==0
			#ifdef POI_STYLIZED_StylizedSpecular
			void stylizedSpecular(inout PoiFragData poiFragData, in PoiCam poiCam, inout PoiLight poiLight, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float specArea = 0.5 * poiLight.nDotH + 0.5;
				#if defined(PROP_HIGHCOLOR_TEX) || !defined(OPTIMIZER_ENABLED)
				float3 specularMap = POI2D_SAMPLER_PAN(_HighColor_Tex, _MainTex, poiUV(poiMesh.uv[_HighColor_TexUV], _HighColor_Tex_ST), _HighColor_TexPan);
				#else
				float3 specularMap = 1;
				#endif
				
				// Spec 1
				float specMask1 = 0;
				float specMask2 = 0;
				if (_Is_SpecularToHighColor)
				{
					specMask1 += pow(specArea, exp2(lerp(11, 1, _HighColor_Power))) * _Layer1Strength;
					specMask2 += pow(specArea, exp2(lerp(11, 1, _Layer2Size))) * _Layer2Strength;
				}
				else
				{
					specMask1 += poiEdgeNonLinear(specArea, (1.0 - pow(_HighColor_Power, 5)), _StylizedSpecularFeather) * _Layer1Strength;
					specMask2 += poiEdgeNonLinear(specArea, (1.0 - pow(_Layer2Size, 5)), _StylizedSpecular2Feather) * _Layer2Strength;
				}
				
				#if defined(PROP_SET_HIGHCOLORMASK) || !defined(OPTIMIZER_ENABLED)
				float specularMask = POI2D_SAMPLER_PAN(_Set_HighColorMask, _MainTex, poiUV(poiMesh.uv[_Set_HighColorMaskUV], _Set_HighColorMask_ST), _Set_HighColorMaskPan)[_Set_HighColorMaskChannel];
				#else
				float specularMask = 1;
				#endif
				
				specularMask = saturate(specularMask + _Tweak_HighColorMaskLevel);
				
				float specMask = saturate(specMask1 + specMask2) * specularMask * lerp(poiLight.rampedLightMap, 1, _StylizedSpecularIgnoreShadow);
				float attenuation = min(lerp(poiLight.nDotLSaturated, 1, _StylizedSpecularIgnoreNormal), lerp(lerp(poiLight.attenuation, 1, _SSIgnoreCastedShadows), 1, _StylizedSpecularIgnoreShadow));
				#ifdef POI_PASS_ADD
				attenuation *= lerp(poiLight.additiveShadow, 1, _SSIgnoreCastedShadows);
				#endif
				
				float finalSpecMask = min(min(specMask, poiLight.occlusion), attenuation) * _StylizedSpecularStrength;
				switch(_Is_BlendAddToHiColor)
				{
					case 0:
					// Replace
					poiFragData.baseColor = lerp(poiFragData.baseColor, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.directColor, _UseLightColor), finalSpecMask);
					break;
					case 1:
					// Add
					poiLight.finalLightAdd += max(0, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.directColor, _UseLightColor) * finalSpecMask);
					break;
					case 2:
					// Screen
					poiFragData.baseColor = lerp(poiFragData.baseColor, blendScreen(poiFragData.baseColor, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.directColor, _UseLightColor)), finalSpecMask);
					break;
					case 3:
					// Multiply
					poiFragData.baseColor = lerp(poiFragData.baseColor, poiFragData.baseColor * specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.directColor, _UseLightColor), finalSpecMask);
					break;
				}
				
				//poiFragData.baseColor = _StylizedSpecularStrength;
				
				float3 vSpecMask = 0;
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					for (int index = 0; index < 4; index++)
					{
						if (!any(poiLight.vPosition[index])) continue;
						specArea = 0.5 * poiLight.vDotNH[index] + 0.5;
						if (_Is_SpecularToHighColor)
						{
							vSpecMask = pow(specArea, exp2(lerp(11, 1, _HighColor_Power))) * _Layer1Strength * poiLight.vAttenuation[index];
							vSpecMask = max(vSpecMask, pow(specArea, exp2(lerp(11, 1, _Layer2Size))) * _Layer2Strength * poiLight.vAttenuation[index]);
						}
						else
						{
							vSpecMask = poiEdgeNonLinear(specArea, (1.0 - pow(_HighColor_Power, 5)), _StylizedSpecularFeather) * _Layer1Strength * poiLight.vAttenuation[index];
							vSpecMask = max(vSpecMask, poiEdgeNonLinear(specArea, (1.0 - pow(_Layer2Size, 5)), _StylizedSpecular2Feather) * _Layer2Strength * poiLight.vAttenuation[index]);
						}
						
						vSpecMask *= specularMask;
						float finalSpecMask = min(min(vSpecMask, poiLight.occlusion), attenuation) * _StylizedSpecularStrength;
						switch(_Is_BlendAddToHiColor)
						{
							case 0:
							// Replace
							poiFragData.baseColor = lerp(poiFragData.baseColor, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.vColor[index], _UseLightColor), finalSpecMask);
							break;
							case 1:
							// Add
							poiLight.finalLightAdd += max(0, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.vColor[index], _UseLightColor) * finalSpecMask);
							break;
							case 2:
							// Screen
							poiFragData.baseColor = lerp(poiFragData.baseColor, blendScreen(poiFragData.baseColor, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.vColor[index], _UseLightColor)), finalSpecMask);
							break;
							case 3:
							// Multiply
							poiFragData.baseColor = lerp(poiFragData.baseColor, poiFragData.baseColor * specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.vColor[index], _UseLightColor), finalSpecMask);
							break;
						}
					}
					#endif
				}
			}
			#endif
			//endex
			
			//ifex _EnablePathing==0
			#ifdef POI_PATHING
			void applyPathing(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float3 albedo = poiFragData.baseColor;
				float3 pathEmission;
				#if defined(PROP_PATHINGMAP) || !defined(OPTIMIZER_ENABLED)
				float4 path = _PathingMap.Sample(SmpRepeatPoint, poiUV(poiMesh.uv[_PathingMapUV], _PathingMap_ST) + _PathingMapPan.xy * _Time.x);
				#else
				float4 path = float4(1, 1, 1, 1);
				#endif
				float4 PathColor[4];
				half pathAudioLinkPathTimeOffsetBand[4] = {
					0, 0, 0, 0
				};
				half2 pathAudioLinkTimeOffset[4] = {
					half2(0, 0), half2(0, 0), half2(0, 0), half2(0, 0)
				};
				half pathAudioLinkPathWidthOffsetBand[4] = {
					0, 0, 0, 0
				};
				half2 pathAudioLinkWidthOffset[4] = {
					half2(0, 0), half2(0, 0), half2(0, 0), half2(0, 0)
				};
				PathColor[0] = _PathColorR;
				PathColor[1] = _PathColorG;
				PathColor[2] = _PathColorB;
				PathColor[3] = _PathColorA;
				
				// Combined data
				if (_PathGradientType == 1)
				{
					path = (path.r + path.g + path.b + path.a) * .25;
				}
				
				#if defined(PROP_PATHINGCOLORMAP) || !defined(OPTIMIZER_ENABLED)
				float4 pathColorMap = POI2D_SAMPLER_PAN(_PathingColorMap, _MainTex, poiUV(poiMesh.uv[_PathingColorMapUV], _PathingColorMap_ST), _PathingColorMapPan);
				#else
				float4 pathColorMap = float4(1, 1, 1, 1);
				#endif
				
				float4 pathAudioLinkEmission = 0;
				float4 pathTime = 0;
				float3 pathAlpha[4] = {
					float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0)
				};
				
				#ifdef POI_AUDIOLINK
				float4 chronoType = float4(_PathChronoTypeR, _PathChronoTypeG, _PathChronoTypeB, _PathChronoTypeA);
				float4 chronoBand = float4(_PathChronoBandR, _PathChronoBandG, _PathChronoBandB, _PathChronoBandA);
				float4 chronoSpeed = float4(_PathChronoSpeedR, _PathChronoSpeedG, _PathChronoSpeedB, _PathChronoSpeedA);
				float3 autoCorrelator[4] = {
					float3(_PathALAutoCorrelatorR, _PathALAutoCorrelatorRangeR[0], _PathALAutoCorrelatorRangeR[1]), float3(_PathALAutoCorrelatorG, _PathALAutoCorrelatorRangeG[0], _PathALAutoCorrelatorRangeG[1]),
					float3(_PathALAutoCorrelatorB, _PathALAutoCorrelatorRangeB[0], _PathALAutoCorrelatorRangeB[1]), float3(_PathALAutoCorrelatorA, _PathALAutoCorrelatorRangeA[0], _PathALAutoCorrelatorRangeA[1])
				};
				float4 history[4] = {
					float4(_PathALHistoryR, _PathALHistoryBandR, _PathALHistoryRangeR[0], _PathALHistoryRangeR[1]), float4(_PathALHistoryG, _PathALHistoryBandG, _PathALHistoryRangeG[0], _PathALHistoryRangeG[1]),
					float4(_PathALHistoryB, _PathALHistoryBandB, _PathALHistoryRangeB[0], _PathALHistoryRangeB[1]), float4(_PathALHistoryA, _PathALHistoryBandA, _PathALHistoryRangeA[0], _PathALHistoryRangeA[1])
				};
				
				if (poiMods.audioLinkAvailable)
				{
					if (_PathALTimeOffset)
					{
						pathAudioLinkPathTimeOffsetBand[0] = _AudioLinkPathTimeOffsetBandR;
						pathAudioLinkPathTimeOffsetBand[1] = _AudioLinkPathTimeOffsetBandG;
						pathAudioLinkPathTimeOffsetBand[2] = _AudioLinkPathTimeOffsetBandB;
						pathAudioLinkPathTimeOffsetBand[3] = _AudioLinkPathTimeOffsetBandA;
						pathAudioLinkTimeOffset[0] = _AudioLinkPathTimeOffsetR.xy;
						pathAudioLinkTimeOffset[1] = _AudioLinkPathTimeOffsetG.xy;
						pathAudioLinkTimeOffset[2] = _AudioLinkPathTimeOffsetB.xy;
						pathAudioLinkTimeOffset[3] = _AudioLinkPathTimeOffsetA.xy;
					}
					
					if (_PathALWidthOffset)
					{
						pathAudioLinkPathWidthOffsetBand[0] = _AudioLinkPathWidthOffsetBandR;
						pathAudioLinkPathWidthOffsetBand[1] = _AudioLinkPathWidthOffsetBandG;
						pathAudioLinkPathWidthOffsetBand[2] = _AudioLinkPathWidthOffsetBandB;
						pathAudioLinkPathWidthOffsetBand[3] = _AudioLinkPathWidthOffsetBandA;
						pathAudioLinkWidthOffset[0] = _AudioLinkPathWidthOffsetR.xy;
						pathAudioLinkWidthOffset[1] = _AudioLinkPathWidthOffsetG.xy;
						pathAudioLinkWidthOffset[2] = _AudioLinkPathWidthOffsetB.xy;
						pathAudioLinkWidthOffset[3] = _AudioLinkPathWidthOffsetA.xy;
					}
					// Emission Offset
					if (_PathALEmissionOffset)
					{
						pathAudioLinkEmission.r += lerp(_AudioLinkPathEmissionAddR.x, _AudioLinkPathEmissionAddR.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandR]);
						pathAudioLinkEmission.g += lerp(_AudioLinkPathEmissionAddG.x, _AudioLinkPathEmissionAddG.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandG]);
						pathAudioLinkEmission.b += lerp(_AudioLinkPathEmissionAddB.x, _AudioLinkPathEmissionAddB.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandB]);
						pathAudioLinkEmission.a += lerp(_AudioLinkPathEmissionAddA.x, _AudioLinkPathEmissionAddA.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandA]);
					}
					
					if(_PathALColorChord)
					{
						if (_PathALCCR)
						{
							PathColor[0] *= AudioLinkLerp(ALPASS_CCSTRIP + float2(path[0] * AUDIOLINK_WIDTH, 0));
						}
						if (_PathALCCG)
						{
							PathColor[1] *= AudioLinkLerp(ALPASS_CCSTRIP + float2(path[1] * AUDIOLINK_WIDTH, 0));
						}
						if (_PathALCCB)
						{
							PathColor[2] *= AudioLinkLerp(ALPASS_CCSTRIP + float2(path[2] * AUDIOLINK_WIDTH, 0));
						}
						if (_PathALCCA)
						{
							PathColor[3] *= AudioLinkLerp(ALPASS_CCSTRIP + float2(path[3] * AUDIOLINK_WIDTH, 0));
						}
					}
				}
				#endif
				
				[unroll]
				for (int index = 0; index < 4; index++)
				{
					float timeOffset = 0;
					#ifdef POI_AUDIOLINK
					UNITY_BRANCH
					if (poiMods.audioLinkAvailable)
					{
						if (_PathALTimeOffset)
						{
							timeOffset += lerp(pathAudioLinkTimeOffset[index].x, pathAudioLinkTimeOffset[index].y, poiMods.audioLink[pathAudioLinkPathTimeOffsetBand[index]]);
						}
						
						if (_PathALChrono)
						{
							timeOffset += AudioLinkGetChronoTime(chronoType[index], chronoBand[index]) * chronoSpeed[index];
						}
					}
					#endif
					pathTime[index] = _PathTime[index] != -999.0f ? frac(_PathTime[index] + _PathOffset[index] + timeOffset) : frac(_Time.x * _PathSpeed[index] + _PathOffset[index] + timeOffset);
					
					if (_PathSegments[index])
					{
						float pathSegments = abs(_PathSegments[index]);
						pathTime = (ceil(pathTime * pathSegments) - .5) / pathSegments;
					}
					
					if (path[index])
					{
						// Cutting it in half because it goes out in both directions for now
						half pathWidth = _PathWidth[index] * .5;
						#ifdef POI_AUDIOLINK
						UNITY_BRANCH
						if (poiMods.audioLinkAvailable)
						{
							if (_PathALWidthOffset)
							{
								pathWidth += lerp(pathAudioLinkWidthOffset[index].x, pathAudioLinkWidthOffset[index].y, poiMods.audioLink[pathAudioLinkPathWidthOffsetBand[index]]);
							}
						}
						#endif
						
						//fill
						pathAlpha[index].x = pathTime[index] > path[index];
						//path
						pathAlpha[index].y = saturate((1 - abs(lerp(-pathWidth, 1 + pathWidth, pathTime[index]) - path[index])) - (1 - pathWidth)) * (1 / pathWidth);
						//loop
						pathAlpha[index].z = saturate((1 - distance(pathTime[index], path[index])) - (1 - pathWidth)) * (1 / pathWidth);
						pathAlpha[index].z += saturate(distance(pathTime[index], path[index]) - (1 - pathWidth)) * (1 / pathWidth);
						pathAlpha[index] = smoothstep(0, _PathSoftness[index] + .00001, pathAlpha[index]);
						
						#ifdef POI_AUDIOLINK
						if (poiMods.audioLinkAvailable)
						{
							if (_PathALHistory && history[index][0])
							{
								// history[index]: [0]: on/off, [1]: band, [2]/[3] min/max
								float historyUV = lerp(history[index][2], history[index][3], path[index]);
								
								if (_PathSegments[index])
								{
									float pathSegments = abs(_PathSegments[index]);
									historyUV = (ceil(historyUV * pathSegments) - .5) / pathSegments;
								}
								
								historyUV *= AUDIOLINK_WIDTH;
								
								float historyValue = AudioLinkLerp(ALPASS_AUDIOLINK + float2(historyUV, history[index][1]))[0];
								
								if(_PathALHistoryMode == 0) // Mask
								pathAlpha[index] *= historyValue;
								else // Override
								pathAlpha[index] = historyValue;
							}
							
							if (_PathALAutoCorrelator && autoCorrelator[index][0] != 0)
							{
								// autoCorrelator[index]: [0]: on/off, [1]/[2]: min/max
								// Choose from only part of the autocorrelator
								float autoCorrelatorUV = lerp(autoCorrelator[index][1], autoCorrelator[index][2], path[index]);
								if (autoCorrelator[index][0] == 2) // Mirror
								{
									autoCorrelatorUV = abs(1. - autoCorrelatorUV * 2.);
								}
								
								if (_PathSegments[index])
								{
									float pathSegments = abs(_PathSegments[index]);
									autoCorrelatorUV = (ceil(autoCorrelatorUV * pathSegments) - .5) / pathSegments;
								}
								
								// Normalize Autocorrelator Value
								float autoCorrelatorValue = AudioLinkLerp(ALPASS_AUTOCORRELATOR + float2(autoCorrelatorUV * AUDIOLINK_WIDTH, 0))[0];
								float autoCorrelatorMax = AudioLinkLerp(ALPASS_AUTOCORRELATOR);
								autoCorrelatorValue = saturate(abs(autoCorrelatorValue) * rcp(autoCorrelatorMax));
								
								// Autocorrelator is normalized, so can look weird at lower volume levels. use Filtered VU intensity to make it smoothly fall off at low volume levels.
								float4 vu = AudioLinkData(ALPASS_FILTEREDVU_INTENSITY + uint2(0, 0));
								autoCorrelatorValue *= smoothstep(0.01, 0.2, vu);
								
								if(_PathALAutoCorrelatorMode == 0) // Mask
								pathAlpha[index] *= autoCorrelatorValue;
								else // Override
								pathAlpha[index] = autoCorrelatorValue;
								
							}
						}
						#endif
					}
				}
				
				// Emission
				pathEmission = 0;
				pathEmission += pathAlpha[0][_PathTypeR] * poiThemeColor(poiMods, PathColor[0].rgb, _PathColorRThemeIndex) * (_PathEmissionStrength[0] + pathAudioLinkEmission.r);
				pathEmission += pathAlpha[1][_PathTypeG] * poiThemeColor(poiMods, PathColor[1].rgb, _PathColorGThemeIndex) * (_PathEmissionStrength[1] + pathAudioLinkEmission.g);
				pathEmission += pathAlpha[2][_PathTypeB] * poiThemeColor(poiMods, PathColor[2].rgb, _PathColorBThemeIndex) * (_PathEmissionStrength[2] + pathAudioLinkEmission.b);
				pathEmission += pathAlpha[3][_PathTypeA] * poiThemeColor(poiMods, PathColor[3].rgb, _PathColorAThemeIndex) * (_PathEmissionStrength[3] + pathAudioLinkEmission.a);
				pathEmission *= pathColorMap.rgb * pathColorMap.a;
				
				float3 colorReplace = 0;
				colorReplace = pathAlpha[0][_PathTypeR] * poiThemeColor(poiMods, PathColor[0].rgb, _PathColorRThemeIndex) * pathColorMap.rgb;
				albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * PathColor[0].a * pathAlpha[0][_PathTypeR]);
				colorReplace = pathAlpha[1][_PathTypeG] * poiThemeColor(poiMods, PathColor[1].rgb, _PathColorGThemeIndex) * pathColorMap.rgb;
				albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * PathColor[1].a * pathAlpha[1][_PathTypeG]);
				colorReplace = pathAlpha[2][_PathTypeB] * poiThemeColor(poiMods, PathColor[2].rgb, _PathColorBThemeIndex) * pathColorMap.rgb;
				albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * PathColor[2].a * pathAlpha[2][_PathTypeB]);
				colorReplace = pathAlpha[3][_PathTypeA] * poiThemeColor(poiMods, PathColor[3].rgb, _PathColorAThemeIndex) * pathColorMap.rgb;
				albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * PathColor[3].a * pathAlpha[3][_PathTypeA]);
				
				float alpha = max(max(max(pathAlpha[0][_PathTypeR], pathAlpha[1][_PathTypeG]), pathAlpha[2][_PathTypeB]), pathAlpha[3][_PathTypeA]);
				
				poiFragData.alpha *= lerp(1, alpha, _PathingOverrideAlpha);
				poiFragData.baseColor = albedo.rgb;
				poiFragData.emission += pathEmission;
			}
			#endif
			//endex
			
			//ifex _EnableMirrorOptions==0
			#ifdef POI_MIRROR
			void applyMirror(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float inMirror = 0;
				// VRC
				if (_VisibilityMode == 1)
				{
					inMirror = VRCMirrorMode() > 0;
				}
				// Generic (CVR, etc)
				else
				{
					inMirror = IsInMirror();
				}
				
				#if (defined(POI_PASS_BASE) || defined(POI_PASS_ADD))
				#if defined(PROP_MIRRORTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 mirrorTexture = POI2D_SAMPLER_PAN(_MirrorTexture, _MainTex, poiUV(poiMesh.uv[_MirrorTextureUV], _MirrorTexture_ST), _MirrorTexturePan);
				if (inMirror && _MirrorTextureEnabled || _MirrorTextureForceEnabled)
				{
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, mirrorTexture.rgb, _MirrorTextureBlendType), mirrorTexture.a * _MirrorColor.a);
					poiFragData.baseColor.rgb *= lerp(1, poiThemeColor(poiMods, _MirrorColor.rgb, _MirrorColorThemeIndex), _MirrorColor.a);
				}
				#else
				if (inMirror && _MirrorTextureEnabled || _MirrorTextureForceEnabled)
				{
					poiFragData.baseColor.rgb *= lerp(1, poiThemeColor(poiMods, _MirrorColor.rgb, _MirrorColorThemeIndex), _MirrorColor.a);
				}
				#endif
				#endif
			}
			#endif
			//endex
			
			//ifex _EnableTouchGlow==0
			#ifdef GRAIN
			void applyDepthFX(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float3 touchEmission = 0;
				
				float perspectiveDivide = 1.0f / poiCam.clipPos.w;
				float4 direction = poiCam.worldDirection * perspectiveDivide;
				float2 screenPos = poiCam.posScreenSpace * perspectiveDivide;
				float z = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, screenPos);
				
				#if UNITY_REVERSED_Z
				if (z == 0)
				#else
				if (z == 1)
				#endif
				return;
				
				float depth = CorrectedLinearEyeDepth(z, direction.w);
				float3 worldpos = direction * depth + _WorldSpaceCameraPos.xyz;
				/*
				finalColor.rgb = frac(worldpos);
				return;
				*/
				
				float diff = distance(worldpos, poiMesh.worldPos);
				//poiFragData.finalColor = diff;
				
				#if defined(PROP_DEPTHMASK) || !defined(OPTIMIZER_ENABLED)
				float depthMask = POI2D_SAMPLER_PAN(_DepthMask, _MainTex, poiUV(poiMesh.uv[_DepthMaskUV], _DepthMask_ST), _DepthMaskPan)[_DepthMaskChannel];
				#else
				float depthMask = 1;
				#endif
				
				if (_DepthMaskGlobalMask > 0)
				{
					depthMask = maskBlend(depthMask, poiMods.globalMask[_DepthMaskGlobalMask - 1], _DepthMaskGlobalMaskBlendType);
				}
				
				if (_DepthColorToggle)
				{
					float colorBlendAlpha = lerp(_DepthColorMinValue, _DepthColorMaxValue, remapClamped(_DepthColorMinDepth, _DepthColorMaxDepth, diff));
					
					#if defined(PROP_DEPTHTEXTURE) || !defined(OPTIMIZER_ENABLED)
					float2 depthTextureUV = float2(0, 0);
					if (_DepthTextureUV == 8)
					{
						depthTextureUV = lerp(0, 1, remapClamped(_DepthColorMinDepth, _DepthColorMaxDepth, diff));
					}
					else
					{
						depthTextureUV = poiMesh.uv[_DepthTextureUV];
					}
					float3 depthColor = POI2D_SAMPLER_PAN(_DepthTexture, _MainTex, poiUV(depthTextureUV, _DepthTexture_ST), _DepthTexturePan).rgb * poiThemeColor(poiMods, _DepthColor, _DepthColorThemeIndex);
					#else
					float3 depthColor = poiThemeColor(poiMods, _DepthColor, _DepthColorThemeIndex);
					#endif
					
					switch(_DepthColorBlendMode)
					{
						case 0:
						{
							poiFragData.baseColor = lerp(poiFragData.baseColor, depthColor, colorBlendAlpha * depthMask);
							break;
						}
						case 1:
						{
							poiFragData.baseColor *= lerp(1, depthColor, colorBlendAlpha * depthMask);
							break;
						}
						case 2:
						{
							poiFragData.baseColor = saturate(poiFragData.baseColor + lerp(0, depthColor, colorBlendAlpha * depthMask));
							break;
						}
					}
					poiFragData.emission += depthColor * colorBlendAlpha * _DepthEmissionStrength * depthMask;
				}
				
				if (_DepthAlphaToggle)
				{
					poiFragData.alpha *= lerp(poiFragData.alpha, saturate(lerp(_DepthAlphaMinValue, _DepthAlphaMaxValue, remapClamped(_DepthAlphaMinDepth, _DepthAlphaMaxDepth, diff))), depthMask);
				}
			}
			#endif
			//endex
			
			//ifex _TextEnabled==0
			#ifdef EFFECT_BUMP
			
			float2 TransformUV(float2 offset, float rotation, float2 scale, float2 uv)
			{
				float theta = radians(rotation);
				scale = 1 - scale;
				float cs = cos(theta);
				float sn = sin(theta);
				float2 centerPoint = offset + .5;
				uv = float2((uv.x - centerPoint.x) * cs - (uv.y - centerPoint.y) * sn + centerPoint.x, (uv.x - centerPoint.x) * sn + (uv.y - centerPoint.y) * cs + centerPoint.y);
				
				return remap(uv, float2(0, 0) + offset + (scale * .5), float2(1, 1) + offset - (scale * .5), float2(0, 0), float2(1, 1));
			}
			
			float2 getAsciiCoordinate(float index)
			{
				return float2((index - 1) / 16, 1 - ((floor(index / 16 - glyphWidth)) / 16));
			}
			
			float median(float r, float g, float b)
			{
				return max(min(r, g), min(max(r, g), b));
			}
			
			void ApplyPositionText(inout PoiFragData poiFragData, float2 uv, in PoiMods poiMods)
			{
				float3 cameraPos = clamp(getCameraPosition(), -999, 999);
				float3 absCameraPos = abs(cameraPos);
				float totalCharacters = 20;
				float positionArray[20];
				positionArray[0] = cameraPos.x >= 0 ? ASCII_NEGATIVE : ASCII_POSITIVE;
				positionArray[1] = floor((absCameraPos.x * .01) % 10) + 48;
				positionArray[2] = floor((absCameraPos.x * .1) % 10) + 48;
				positionArray[3] = floor(absCameraPos.x % 10) + 48;
				positionArray[4] = ASCII_PERIOD;
				positionArray[5] = floor((absCameraPos.x * 10) % 10) + 48;
				positionArray[6] = ASCII_COMMA;
				positionArray[7] = cameraPos.y >= 0 ? ASCII_NEGATIVE : ASCII_POSITIVE;
				positionArray[8] = floor((absCameraPos.y * .01) % 10) + 48;
				positionArray[9] = floor((absCameraPos.y * .1) % 10) + 48;
				positionArray[10] = floor(absCameraPos.y % 10) + 48;
				positionArray[11] = ASCII_PERIOD;
				positionArray[12] = floor((absCameraPos.y * 10) % 10) + 48;
				positionArray[13] = ASCII_COMMA;
				positionArray[14] = cameraPos.z >= 0 ? ASCII_NEGATIVE : ASCII_POSITIVE;
				positionArray[15] = floor((absCameraPos.z * .01) % 10) + 48;
				positionArray[16] = floor((absCameraPos.z * .1) % 10) + 48;
				positionArray[17] = floor(absCameraPos.z % 10) + 48;
				positionArray[18] = ASCII_PERIOD;
				positionArray[19] = floor((absCameraPos.z * 10) % 10) + 48;
				
				uv = TransformUV(_TextPositionOffset, _TextPositionRotation, _TextPositionScale, uv);
				
				if (uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
				{
					return;
				}
				
				float currentCharacter = floor(uv.x * totalCharacters);
				float2 glyphPos = getAsciiCoordinate(positionArray[currentCharacter]);
				
				float2 startUV = float2(1 / totalCharacters * currentCharacter, 0);
				float2 endUV = float2(1 / totalCharacters * (currentCharacter + 1), 1);
				
				fixed4 textPositionPadding = _TextPositionPadding;
				textPositionPadding *= 1 / totalCharacters;
				
				uv = remapClamped(startUV, endUV, uv, float2(glyphPos.x + textPositionPadding.x, glyphPos.y - glyphWidth + textPositionPadding.y), float2(glyphPos.x + glyphWidth - textPositionPadding.z, glyphPos.y - textPositionPadding.w));
				
				if (uv.x > glyphPos.x + glyphWidth - textPositionPadding.z - .001 || uv.x < glyphPos.x + textPositionPadding.x + .001 || uv.y > glyphPos.y - textPositionPadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textPositionPadding.y + .001)
				{
					return;
				}
				
				float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
				float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
				float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
				sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
				float opacity = clamp(sigDist + 0.5, 0, 1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, poiThemeColor(poiMods, _TextPositionColor.rgb, _TextPositionColorThemeIndex), opacity * _TextPositionColor.a);
				globalTextEmission += poiThemeColor(poiMods, _TextPositionColor.rgb, _TextPositionColorThemeIndex) * opacity * _TextPositionEmissionStrength;
			}
			
			void ApplyTimeText(inout PoiFragData poiFragData, float2 uv, in PoiMods poiMods)
			{
				float instanceTime = _Time.y;
				float hours = instanceTime / 3600;
				float minutes = (instanceTime / 60) % 60;
				float seconds = instanceTime % 60;
				float totalCharacters = 8;
				float timeArray[8];
				timeArray[0] = floor((hours * .1) % 10) + 48;
				timeArray[1] = floor(hours % 10) + 48;
				timeArray[2] = ASCII_SEMICOLON;
				timeArray[3] = floor((minutes * .1) % 10) + 48;
				timeArray[4] = floor(minutes % 10) + 48;
				timeArray[5] = ASCII_SEMICOLON;
				timeArray[6] = floor((seconds * .1) % 10) + 48;
				timeArray[7] = floor(seconds % 10) + 48;
				
				uv = TransformUV(_TextTimeOffset, _TextTimeRotation, _TextTimeScale, uv);
				
				if (uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
				{
					return;
				}
				
				float currentCharacter = floor(uv.x * totalCharacters);
				float2 glyphPos = getAsciiCoordinate(timeArray[currentCharacter]);
				// 0.1428571 = 1/7 = 1 / totalCharacters
				float startUV = 1 / totalCharacters * currentCharacter;
				float endUV = 1 / totalCharacters * (currentCharacter + 1);
				
				fixed4 textTimePadding = _TextTimePadding;
				textTimePadding *= 1 / totalCharacters;
				
				uv = remapClamped(float2(startUV, 0), float2(endUV, 1), uv, float2(glyphPos.x + textTimePadding.x, glyphPos.y - glyphWidth + textTimePadding.y), float2(glyphPos.x + glyphWidth - textTimePadding.z, glyphPos.y - textTimePadding.w));
				
				if (uv.x > glyphPos.x + glyphWidth - textTimePadding.z - .001 || uv.x < glyphPos.x + textTimePadding.x + .001 || uv.y > glyphPos.y - textTimePadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textTimePadding.y + .001)
				{
					return;
				}
				
				float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
				float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
				float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
				sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
				float opacity = clamp(sigDist + 0.5, 0, 1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, poiThemeColor(poiMods, _TextTimeColor.rgb, _TextTimeColorThemeIndex), opacity * _TextTimeColor.a);
				globalTextEmission += poiThemeColor(poiMods, _TextTimeColor.rgb, _TextTimeColorThemeIndex) * opacity * _TextTimeEmissionStrength;
			}
			
			void ApplyFPSText(inout PoiFragData poiFragData, float2 uv, in PoiMods poiMods)
			{
				float smoothDeltaTime = clamp(unity_DeltaTime.w, 0, 999);
				float totalCharacters = 7;
				float fpsArray[7];
				fpsArray[0] = ASCII_F;
				fpsArray[1] = ASCII_P;
				fpsArray[2] = ASCII_S;
				fpsArray[3] = ASCII_SEMICOLON;
				fpsArray[4] = floor((smoothDeltaTime * .01) % 10) + 48;
				fpsArray[5] = floor((smoothDeltaTime * .1) % 10) + 48;
				fpsArray[6] = floor(smoothDeltaTime % 10) + 48;
				
				uv = TransformUV(_TextFPSOffset, _TextFPSRotation, _TextFPSScale, uv);
				
				if (uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
				{
					return;
				}
				
				float currentCharacter = floor(uv.x * totalCharacters);
				float2 glyphPos = getAsciiCoordinate(fpsArray[currentCharacter]);
				// 0.1428571 = 1/7 = 1 / totalCharacters
				float startUV = 1 / totalCharacters * currentCharacter;
				float endUV = 1 / totalCharacters * (currentCharacter + 1);
				
				float4 textFPSPadding = _TextFPSPadding;
				textFPSPadding *= 1 / totalCharacters;
				
				uv = remapClamped(float2(startUV, 0), float2(endUV, 1), uv, float2(glyphPos.x + textFPSPadding.x, glyphPos.y - glyphWidth + textFPSPadding.y), float2(glyphPos.x + glyphWidth - textFPSPadding.z, glyphPos.y - textFPSPadding.w));
				
				if (uv.x > glyphPos.x + glyphWidth - textFPSPadding.z - .001 || uv.x < glyphPos.x + textFPSPadding.x + .001 || uv.y > glyphPos.y - textFPSPadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textFPSPadding.y + .001)
				{
					return;
				}
				
				float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
				float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
				float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
				sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
				float opacity = clamp(sigDist + 0.5, 0, 1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, poiThemeColor(poiMods, _TextFPSColor.rgb, _TextFPSColorThemeIndex), opacity * _TextFPSColor.a);
				globalTextEmission += poiThemeColor(poiMods, _TextFPSColor.rgb, _TextFPSColorThemeIndex) * opacity * _TextFPSEmissionStrength;
			}
			
			void ApplyNumericText(inout PoiFragData poiFragData, float2 uv, in PoiMods poiMods)
			{
				// If both digits are set to zero: exit.
				if (_TextNumericWholeDigits == 0 && _TextNumericDecimalDigits == 0)
				{
					return;
				}
				
				uint wholeNumber = 0;
				uint decimalNumber = 0;
				uint wholeDigits = _TextNumericWholeDigits;
				uint decimalDigits = _TextNumericDecimalDigits;
				float NumericArray[10];										// 10 is the max amount of characters = 1 sign + 4 max whole digits + 1 decimal mark + 4 max decimal digits
				uint arrayIndex = 0;
				float totalCharacters = 1 + wholeDigits + decimalDigits; 	// Sign Character + Whole Digits + Decimal Digits
				
				//Determine Sign (_TextNumericValue is usually animated)
				float charSign = _TextNumericValue >= 0 ? ASCII_SPACE : ASCII_NEGATIVE;
				
				NumericArray[arrayIndex] = charSign;						//First character is always the sign
				arrayIndex++;
				
				//Isolate whole number and fill array
				if (wholeDigits > 0)
				{
					wholeNumber = uint(glsl_mod(abs(_TextNumericValue), pow(10, wholeDigits)));
					
					int expIndex = -1 * (wholeDigits - 1);  // Exponent Index
					bool leadingZero = true;
					// Pouplate the Array
					while (arrayIndex <= wholeDigits)
					{
						// Grab the corresponding digit from the whole number going from left to right.
						int digit = floor(glsl_mod(wholeNumber * pow(10, expIndex), 10));
						// Take the resulting value and add 48 to get the corresponding location in the font array.
						NumericArray[arrayIndex] = digit + 48;
						
						//Trim Leading Zeroes, but leave at least one.
						if (_TextNumericTrimZeroes == true)
						{
							//If the digit is zero and there hasn't been any digits greater than 0 previously.
							if (digit == 0 && leadingZero == true && arrayIndex != wholeDigits)
							{
								//Overwrite the leading zero.
								NumericArray[arrayIndex] = ASCII_SPACE;
							}
							else
							{
								leadingZero = false;
							}
						}
						expIndex++;
						arrayIndex++;
					}
				}
				
				// Isolate decimal number and fill array
				if (decimalDigits > 0)
				{
					// Add a decimal point
					NumericArray[arrayIndex] = ASCII_PERIOD;
					int decimalPointer = arrayIndex;
					arrayIndex++;
					totalCharacters++;
					
					decimalNumber = uint(frac(abs(_TextNumericValue)) * pow(10.00001, decimalDigits));    // Isolate the decimal number
					
					int expIndex = -1 * (decimalDigits - 1);                                          // Exponent Index
					//Populate the Array with the remaining digits
					while (arrayIndex < (uint)(totalCharacters))
					{
						// Grab the corresponding digit from the whole number going from left to right.
						int digit = floor(glsl_mod(decimalNumber * pow(10, expIndex), 10));
						// Take the resulting value and add 48 to get the corresponding location in the font array.
						NumericArray[arrayIndex] = digit + 48;
						
						expIndex++;
						arrayIndex++;
					}
				}
				
				uv = TransformUV(_TextNumericOffset, _TextNumericRotation, _TextNumericScale, uv);
				
				if (uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
				{
					return;
				}
				
				float currentCharacter = floor(uv.x * totalCharacters);
				float2 glyphPos = getAsciiCoordinate(NumericArray[currentCharacter]);
				float startUV = 1 / totalCharacters * currentCharacter;
				float endUV = 1 / totalCharacters * (currentCharacter + 1);
				
				float4 textNumericPadding = _TextNumericPadding;
				textNumericPadding *= 1 / totalCharacters;
				
				uv = remapClamped(float2(startUV, 0), float2(endUV, 1), uv, float2(glyphPos.x + textNumericPadding.x, glyphPos.y - glyphWidth + textNumericPadding.y), float2(glyphPos.x + glyphWidth - textNumericPadding.z, glyphPos.y - textNumericPadding.w));
				
				if (uv.x > glyphPos.x + glyphWidth - textNumericPadding.z - .001 || uv.x < glyphPos.x + textNumericPadding.x + .001 || uv.y > glyphPos.y - textNumericPadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textNumericPadding.y + .001)
				{
					return;
				}
				
				float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
				float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
				float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
				sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
				float opacity = clamp(sigDist + 0.5, 0, 1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, poiThemeColor(poiMods, _TextNumericColor.rgb, _TextNumericColorThemeIndex), opacity * _TextNumericColor.a);
				globalTextEmission += poiThemeColor(poiMods, _TextNumericColor.rgb, _TextNumericColorThemeIndex) * opacity * _TextNumericEmissionStrength;
			}
			
			void ApplyTextOverlayColor(inout PoiFragData poiFragData, PoiMesh poiMesh, in PoiMods poiMods)
			{
				globalTextEmission = 0;
				float positionalOpacity = 0;
				
				if (_TextFPSEnabled == 1)
				ApplyFPSText(poiFragData, poiMesh.uv[_TextFPSUV], poiMods);
				if (_TextPositionEnabled == 1)
				ApplyPositionText(poiFragData, poiMesh.uv[_TextPositionUV], poiMods);
				if (_TextTimeEnabled == 1)
				ApplyTimeText(poiFragData, poiMesh.uv[_TextTimeUV], poiMods);
				if (_TextNumericEnabled == 1)
				ApplyNumericText(poiFragData, poiMesh.uv[_TextNumericUV], poiMods);
				
				poiFragData.emission += globalTextEmission;
			}
			#endif
			//endex
			
			//ifex _PostProcess==0
			#ifdef POSTPROCESS
			float3 poiPosterize(float3 color, float steps)
			{
				float3 newColor = RGBtoHSV(color);
				steps = floor(steps);
				newColor.r = floor(newColor.r * steps) / steps;
				newColor.g = floor(newColor.g * steps) / steps;
				newColor.b = floor(newColor.b * steps) / steps;
				return HSVtoRGB(newColor);
			}
			
			float oetf_sRGB_scalar(float L)
			{
				float V = 1.055 * (pow(L, 1.0 / 2.4)) - 0.055;
				if (L <= 0.0031308)
				V = L * 12.92;
				return V;
			}
			
			float3 oetf_sRGB(float3 L)
			{
				return float3(oetf_sRGB_scalar(L.r), oetf_sRGB_scalar(L.g), oetf_sRGB_scalar(L.b));
			}
			
			float eotf_sRGB_scalar(float V)
			{
				float L = pow((V + 0.055) / 1.055, 2.4);
				if (V <= oetf_sRGB_scalar(0.0031308))
				L = V / 12.92;
				return L;
			}
			
			float3 GetHDR(float3 rgb)
			{
				return float3(eotf_sRGB_scalar(rgb.r), eotf_sRGB_scalar(rgb.g), eotf_sRGB_scalar(rgb.b));
			}
			
			float3 GetContrast(float3 col, float contrast)
			{
				return lerp(float3(0.5, 0.5, 0.5), col, contrast);
			}
			
			float3 GetSaturation(float3 col, float interpolator)
			{
				return lerp(dot(col, float3(0.3, 0.59, 0.11)), col, interpolator);
			}
			
			void applyPostProcessing(inout PoiFragData poiFragData, in PoiMesh poiMesh)
			{
				float3 col = poiFragData.finalColor;
				col = hueShift(col, _PPHue);
				col *= _PPTint;
				col *= _PPRGB;
				col = GetSaturation(col, _PPSaturation);
				col = lerp(col, GetHDR(col), _PPHDR);
				col = GetContrast(col, _PPContrast);
				col *= _PPBrightness;
				col += _PPLightness;
				
				float ppMask = 1;
				#if defined(PROP_PPMASK) || !defined(OPTIMIZER_ENABLED)
				ppMask = POI2D_SAMPLER_PAN(_PPMask, _MainTex, poiUV(poiMesh.uv[_PPMaskUV], _PPMask_ST), _PPMaskPan)[_PPMaskChannel];
				ppMask = lerp(ppMask, 1 - ppMask, _PPMaskInvert);
				col = lerp(poiFragData.finalColor, col, ppMask);
				#endif
				
				if (_PPPosterization)
				{
					col = lerp(col, poiPosterize(col, _PPPosterizationAmount), ppMask);
				}
				
				poiFragData.finalColor = col;
			}
			#endif
			//endex
			
			//ifex _PoiInternalParallax==0
			#ifdef POI_INTERNALPARALLAX
			void applyInternalParallax(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiMods poiMods)
			{
				float3 parallax = 0;
				
				for (int j = _ParallaxInternalIterations - 1; j >= 0; j--)
				{
					float ratio = saturate((float)j / max(_ParallaxInternalIterations - 1, 1));
					float2 parallaxOffset = _Time.y * (_ParallaxInternalMapPan + ratio * _ParallaxInternalPanDepthSpeed);
					float fade = lerp(_ParallaxInternalMinFade, _ParallaxInternalMaxFade, ratio);
					fade = pow(fade, 2.2);
					#if defined(PROP_PARALLAXINTERNALMAP) || !defined(OPTIMIZER_ENABLED)
					float4 parallaxColor = UNITY_SAMPLE_TEX2D_SAMPLER(_ParallaxInternalMap, _MainTex, TRANSFORM_TEX(poiMesh.uv[0], _ParallaxInternalMap) + (lerp(_ParallaxInternalMinDepth, _ParallaxInternalMaxDepth, ratio)) * - (poiCam.tangentViewDir.xy / (poiCam.tangentViewDir.z)) + parallaxOffset);
					#else
					float4 parallaxColor = 0;
					#endif
					float3 minColor = poiThemeColor(poiMods, _ParallaxInternalMinColor.rgb, _ParallaxInternalMinColorThemeIndex);
					float3 maxColor = poiThemeColor(poiMods, _ParallaxInternalMaxColor.rgb, _ParallaxInternalMaxColorThemeIndex);
					float3 parallaxTint = lerp(minColor, maxColor, ratio);
					float parallaxHeight;
					if (_ParallaxInternalHeightFromAlpha)
					{
						parallaxTint *= parallaxColor.rgb;
						parallaxHeight = parallaxColor.a;
					}
					else
					{
						parallaxHeight = parallaxColor.r;
					}
					// parallaxTint = hueShift(parallaxTint, frac((ratio * _ParallaxInternalHueShiftPerLevel) + (ratio * _ParallaxInternalHueShiftPerLevelSpeed * _Time.x)) * _ParallaxInternalHueShiftEnabled);
					parallaxTint = hueShift(parallaxTint, frac(ratio * _ParallaxInternalHueShiftPerLevel) * _ParallaxInternalHueShiftEnabled);
					//float parallaxColor *= lerp(_ParallaxInternalMinColor, _ParallaxInternalMaxColor, 1 - ratio);
					UNITY_BRANCH
					if (_ParallaxInternalHeightmapMode == 1)
					{
						parallax = lerp(parallax, parallaxTint * fade, parallaxHeight >= 1 - ratio);
					}
					else
					{
						if (_ParallaxInternalBlendMode == 0) parallax += parallaxTint * parallaxHeight * fade;
						if (_ParallaxInternalBlendMode == 1) parallax = max(parallax, parallaxTint * parallaxHeight * fade);
					}
				}
				parallax = hueShift(parallax, frac(_ParallaxInternalHueShift + _ParallaxInternalHueShiftSpeed * _Time.x) * _ParallaxInternalHueShiftEnabled);
				//parallax /= _ParallaxInternalIterations;
				#if defined(PROP_PARALLAXINTERNALMAPMASK) || !defined(OPTIMIZER_ENABLED)
				poiFragData.baseColor.rgb = customBlend(poiFragData.baseColor.rgb, parallax.rgb, _ParallaxInternalSurfaceBlendMode, POI2D_SAMPLER_PAN(_ParallaxInternalMapMask, _MainTex, poiUV(poiMesh.uv[_ParallaxInternalMapMaskUV], _ParallaxInternalMapMask_ST), _ParallaxInternalMapMaskPan)[_ParallaxInternalMapMaskChannel]);
				#else
				poiFragData.baseColor.rgb = customBlend(poiFragData.baseColor.rgb, parallax.rgb, _ParallaxInternalSurfaceBlendMode);
				#endif
			}
			#endif
			//endex
			
			// normal correct code from https://github.com/yoship1639/UniToon (MIT)
			//ifex _NormalCorrect==0
			#ifdef POI_NORMALCORRECT
			void applyNormalCorrect(inout VertexOut i)
			{
				float3 normalCorrectObject = i.localPos.xyz - _NormalCorrectOrigin;
				normalCorrectObject.y = 0;
				normalCorrectObject = normalize(normalCorrectObject);
				float3 normalCorrectWorld = UnityObjectToWorldDir(normalCorrectObject);
				i.normal.xyz = normalize(lerp(i.normal.xyz, normalCorrectWorld, _NormalCorrectAmount));
				//i.objNormal.xyz = normalize(lerp(i.objNormal.xyz, normalCorrectObject, _NormalCorrectAmount));
			}
			#endif
			//endex
			
			//ifex _VideoEffectsEnable==0
			#ifdef POI_VIDEO_EFFECTS
			float3 applyBacklight(float3 videoTexture, half backlightStrength)
			{
				return max(backlightStrength, videoTexture.rgb);
			}
			
			float3 applyViewAngleTN(float3 videoTexture, PoiCam poiCam, PoiMesh poiMesh)
			{
				float3 reflectionVector = normalize(reflect(poiCam.viewDir.rgb, poiMesh.normals[1].rgb));
				float upwardShift = dot(reflectionVector, poiMesh.binormal[0]);
				upwardShift = pow(upwardShift, 1);
				float sideShift = dot(reflectionVector, poiMesh.tangent[0]);
				sideShift *= pow(sideShift, 3);
				#if !UNITY_COLORSPACE_GAMMA
				videoTexture = LinearToGammaSpace(videoTexture);
				#endif
				videoTexture = saturate(lerp(half3(0.5, 0.5, 0.5), videoTexture, upwardShift + 1));
				#if !UNITY_COLORSPACE_GAMMA
				videoTexture = GammaToLinearSpace(videoTexture);
				#endif
				videoTexture = (lerp(videoTexture, videoTexture.gbr, sideShift));
				return videoTexture;
			}
			
			float calculateCRTPixelBrightness(float2 uv)
			{
				float totalPixels = _VideoResolution.x * _VideoResolution.y;
				float2 uvPixel = float2((floor((1 - uv.y) * _VideoResolution.y)) / _VideoResolution.y, (floor(uv.x * _VideoResolution.x)) / _VideoResolution.x);
				float currentPixelNumber = _VideoResolution.x * (_VideoResolution.y * uvPixel.x) + _VideoResolution.y * uvPixel.y;
				float currentPixelAlpha = currentPixelNumber / totalPixels;
				half electronBeamAlpha = frac(_Time.y * _VideoCRTRefreshRate);
				float electronBeamPixelNumber = totalPixels * electronBeamAlpha;
				
				float DistanceInPixelsFromCurrentElectronBeamPixel = 0;
				if (electronBeamPixelNumber >= currentPixelNumber)
				{
					DistanceInPixelsFromCurrentElectronBeamPixel = electronBeamPixelNumber - currentPixelNumber;
				}
				else
				{
					DistanceInPixelsFromCurrentElectronBeamPixel = electronBeamPixelNumber + (totalPixels - currentPixelNumber);
				}
				float CRTFrameTime = 1 / _VideoCRTRefreshRate;
				float timeSincecurrentPixelWasHitByElectronBeam = (DistanceInPixelsFromCurrentElectronBeamPixel / totalPixels);
				
				return saturate(_VideoCRTPixelEnergizedTime - timeSincecurrentPixelWasHitByElectronBeam);
			}
			
			void applyContrastSettings(inout float3 pixel)
			{
				#if !UNITY_COLORSPACE_GAMMA
				pixel = LinearToGammaSpace(pixel);
				#endif
				pixel = saturate(lerp(half3(0.5, 0.5, 0.5), pixel, _VideoContrast + 1));
				#if !UNITY_COLORSPACE_GAMMA
				pixel = GammaToLinearSpace(pixel);
				#endif
			}
			
			void applySaturationSettings(inout float3 pixel)
			{
				pixel = lerp(pixel.rgb, dot(pixel.rgb, float3(0.3, 0.59, 0.11)), - (_VideoSaturation));
			}
			
			void applyVideoSettings(inout float3 pixel)
			{
				applySaturationSettings(pixel);
				applyContrastSettings(pixel);
			}
			
			void calculateLCD(inout float4 videoTexture, float3 pixels)
			{
				videoTexture.rgb = applyBacklight(videoTexture, _VideoBacklight * .01);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateTN(inout float4 videoTexture, float3 pixels, PoiCam poiCam, PoiMesh poiMesh)
			{
				videoTexture.rgb = applyBacklight(videoTexture, _VideoBacklight * .01);
				videoTexture.rgb = applyViewAngleTN(videoTexture, poiCam, poiMesh);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateCRT(inout float4 videoTexture, float3 pixels, float2 uv)
			{
				float brightness = calculateCRTPixelBrightness(uv);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * brightness * _VideoBacklight;
			}
			void calculateOLED(inout float4 videoTexture, float3 pixels)
			{
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateGameboy(inout float4 videoTexture)
			{
				applyVideoSettings(videoTexture.rgb);
				// half brightness = saturate((videoTexture.r + videoTexture.g + videoTexture.b) * .3333333);
				half brightness = LinearRgbToLuminance(LinearToGammaSpace(videoTexture.rgb));
				#if defined(PROP_VIDEOGAMEBOYRAMP) || !defined(OPTIMIZER_ENABLED)
				videoTexture.rgb = tex2Dlod(_VideoGameboyRamp, float4(brightness.xx, 0, 0));
				#else
				float3 dg = float3(0.00392156863, 0.0392156863, 0.00392156863);
				float3 lg = float3(0.333333333, 0.5, 0.00392156863);
				videoTexture.rgb = lerp(dg, lg, brightness);
				#endif
			}
			void calculateProjector(inout float4 videoTexture)
			{
				applyVideoSettings(videoTexture.rgb);
				
				float3 projectorColor = videoTexture * _VideoBacklight;
				videoTexture.r = clamp(projectorColor.r, videoTexture.r, 1000);
				videoTexture.g = clamp(projectorColor.g, videoTexture.g, 1000);
				videoTexture.b = clamp(projectorColor.b, videoTexture.b, 1000);
			}
			
			void applyVideoEffectsMainTex(inout float4 mainTexture, in PoiMesh poiMesh)
			{
				float2 uvs = poiMesh.uv[_MainTexUV];
				if (_VideoPixelateToResolution)
				{
					float2 originalUVs = uvs;
					uvs = sharpSample(float4(1 / _VideoResolution.xy, _VideoResolution.xy), uvs);
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
					mainTexture = _MainTex.SampleGrad(sampler_MainTex, uvs, ddx(originalUVs), ddy(originalUVs));
				}
			}
			void applyVideoEffects(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, in PoiLight poiLight, in PoiMods poiMods)
			{
				#if defined(PROP_VIDEOPIXELTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float3 pixels = tex2D(_VideoPixelTexture, poiUV(poiMesh.uv[_VideoPixelTextureUV], _VideoPixelTexture_ST) * _VideoResolution);
				#else
				float3 pixels = 1;
				#endif
				float2 uvs = poiMesh.uv[_MainTexUV];
				if (_VideoPixelateToResolution)
				{
					uvs = sharpSample(float4(1 / _VideoResolution.xy, _VideoResolution.xy), uvs);
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
				}
				else
				{
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
				}
				float4 modifiedVideoTexture = 0;
				modifiedVideoTexture.rgb = poiFragData.baseColor;
				modifiedVideoTexture.a = poiFragData.alpha;
				
				// UNITY_BRANCH
				// if(_VideoRepeatVideoTexture == 1)
				// {
				// 	if(poiMesh.uv[_VideoUVNumber].x > 1 || poiMesh.uv[_VideoUVNumber].x < 0 || poiMesh.uv[_VideoUVNumber].y > 1 || poiMesh.uv[_VideoUVNumber].y < 0)
				// 	{
				// 		return;
				// 	}
				// }
				
				switch(_VideoType)
				{
					case 0: // LCD
					
					{
						calculateLCD(modifiedVideoTexture, pixels);
						break;
					}
					case 1: // TN
					
					{
						calculateTN(modifiedVideoTexture, pixels, poiCam, poiMesh);
						break;
					}
					case 2: // CRT
					
					{
						calculateCRT(modifiedVideoTexture, pixels, uvs);
						break;
					}
					case 3: // OLED
					
					{
						calculateOLED(modifiedVideoTexture, pixels);
						break;
					}
					case 4: // Gameboy
					
					{
						calculateGameboy(modifiedVideoTexture);
						break;
					}
					case 5: // Projector
					
					{
						calculateProjector(modifiedVideoTexture);
						break;
					}
				}
				#if defined(PROP_VIDEOMASKTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float screenMask = POI2D_SAMPLER_PAN(_VideoMaskTexture, _MainTex, poiUV(poiMesh.uv[_VideoMaskTextureUV], _VideoMaskTexture_ST), _VideoMaskTexturePan)[_VideoMaskTextureChannel];
				#else
				float screenMask = 1;
				#endif
				
				poiFragData.baseColor = lerp(poiFragData.baseColor, modifiedVideoTexture, screenMask);
				// UNITY_BRANCH
				if (_VideoEmissionEnabled)
				{
					poiFragData.emission += modifiedVideoTexture.rgb * screenMask;
				}
			}
			#endif
			//endex
			
			//ifex _BacklightEnabled!=1
			#ifdef POI_BACKLIGHT
			void ApplyBacklight(inout PoiFragData poiFragData, in PoiMesh poiMesh, inout PoiLight poiLight, in PoiCam poiCam, inout PoiMods poiMods)
			{
				
				// Color
				float3 backlightColor = _BacklightColor.rgb;
				#if defined(PROP_BACKLIGHTCOLORTEX) || !defined(OPTIMIZER_ENABLED)
				backlightColor *= POI2D_SAMPLER_PAN(_BacklightColorTex, _MainTex, poiUV(poiMesh.uv[_BacklightColorTexUV], _BacklightColorTex_ST), _BacklightColorTexPan).rgb;
				#endif
				
				float3 normal = lerp(poiMesh.normals[0], poiMesh.normals[1], _BacklightNormalStrength);
				// Factor
				float3 headDir = normalize(getCameraPosition() - poiMesh.worldPos.xyz);
				float headDotLight = dot(headDir, poiLight.direction);
				float backlightFactor = pow(saturate(-headDotLight * 0.5 + 0.5), max(0, _BacklightDirectivity));
				float backlightLN = dot(normalize(-headDir * _BacklightViewStrength + poiLight.direction), normal) * 0.5 + 0.5;
				#if defined(POINT) || defined(SPOT)
				if (_BacklightReceiveShadow) backlightLN *= saturate(poiLight.additiveShadow);
				#else
				if (_BacklightReceiveShadow) backlightLN *= saturate(poiLight.attenuation);
				#endif
				backlightLN = poiEdgeLinear(backlightLN, _BacklightBorder, _BacklightBlur);
				float backlight = saturate(backlightFactor * backlightLN);
				backlight = !poiMesh.isFrontFace && _BacklightBackfaceMask ? 0.0 : backlight;
				
				// Blend
				backlightColor = lerp(backlightColor, backlightColor * poiFragData.baseColor, _BacklightMainStrength);
				poiLight.finalLightAdd += backlight * backlightColor * poiLight.directColor;
			}
			#endif
			//endex
			
			//ifex _VoronoiEnabled!=1
			#ifdef POI_VORONOI
			//1/7
			#define VoronoiK 0.142857142857
			//3/7
			#define VoronoiKo 0.428571428571
			// Permutation polynomial: (34x^2 + x) mod 289
			float3 Permutation(float3 x)
			{
				return glsl_mod((34.0 * x + 1.0) * x, 289.0);
			}
			
			float3 inoise(float3 P, float jitter, out float3 randomPoint)
			{
				P *= 0.7f; // Scale adjustment
				float3 Pi = glsl_mod(floor(P), 289.0);
				float3 Pf = frac(P);
				float3 oi = float3(-1.0, 0.0, 1.0);
				float3 of = float3(-0.5, 0.5, 1.5);
				float3 px = Permutation(Pi.x + oi);
				float3 py = Permutation(Pi.y + oi);
				float3 pz = Permutation(Pi.z + oi);
				
				float3 p, ox, oy, oz, dx, dy, dz;
				float3 F = 1e6;
				
				[unroll(3)]
				for (int i = 0; i < 3; i++)
				{
					[unroll(3)]
					for (int j = 0; j < 3; j++)
					{
						[unroll(3)]
						for (int k = 0; k < 3; k++)
						{
							p = Permutation(px[i] + py[j] + pz[k] + oi); // pij1, pij2, pij3
							float3 ogp = p;
							
							ox = frac(p * VoronoiK) - VoronoiKo;
							oy = glsl_mod(floor(p * VoronoiK), 7.0) * VoronoiK - VoronoiKo;
							
							p = Permutation(p);
							oz = frac(p * VoronoiK) - VoronoiKo;
							
							dx = Pf.x - of[i] + jitter * ox;
							dy = Pf.y - of[j] + jitter * oy;
							dz = Pf.z - of[k] + jitter * oz;
							
							float3 d = dx * dx + dy * dy + dz * dz; // dij1, dij2 and dij3, squared
							
							//Find lowest and second lowest distances
							for (int n = 0; n < 3; n++)
							{
								if (d[n] < F[0])
								{
									F[1] = F[0];
									F[0] = d[n];
									randomPoint = p;
								}
								else if (d[n] < F[1])
								{
									F[1] = d[n];
								}
							}
						}
					}
				}
				
				return F;
			}
			
			float voronoi2D(in float2 x, float scale, float2 speed, out float2 randomPoint)
			{
				x *= scale;
				x += speed * _Time.x;
				float2 n = floor(x);
				float2 f = frac(x);
				
				// first pass: regular voronoi
				float2 mg, mr;
				float md = 8.0;
				for (int j = -1; j <= 1; j++)
				{
					for (int i = -1; i <= 1; i++)
					{
						float2 g = float2(float(i), float(j));
						float2 o = random2(n + g);
						float2 currentPoint = o;
						
						float2 r = g + o - f;
						float d = dot(r, r);
						
						if (d < md)
						{
							md = d;
							mr = r;
							mg = g;
							randomPoint.xy = currentPoint;
						}
					}
				}
				
				// second pass: distance to borders
				md = 8.0;
				for (int r = -2; r <= 2; r++)
				{
					for (int q = -2; q <= 2; q++)
					{
						float2 g = mg + float2(float(q), float(r));
						float2 o = random2(n + g);
						
						float2 r = g + o - f;
						
						if (dot(mr - r, mr - r) > 0.00001)
						{
							md = min(md, dot(0.5 * (mr + r), normalize(r - mr)));
						}
					}
				}
				return md;
			}
			
			float voronoi3D(in float3 x, float scale, float3 speed, out float3 randomPoint)
			{
				x *= scale;
				x += speed * _Time.x;
				float3 n = floor(x);
				float3 f = frac(x);
				
				// first pass: regular voronoi
				float3 mg, mr;
				float md = 8.0;
				for (int j = -1; j <= 1; j++)
				{
					for (int i = -1; i <= 1; i++)
					{
						for (int h = -1; h <= 1; h++)
						{
							float3 g = float3(float(h), float(i), float(j));
							float3 o = random3(n + g);
							float3 currentPoint = o;
							
							float3 r = g + o - f;
							float d = dot(r, r);
							
							if (d < md)
							{
								md = d;
								mr = r;
								mg = g;
								randomPoint = currentPoint;
							}
						}
					}
				}
				
				// second pass: distance to borders
				md = 8.0;
				for (int r = -2; r <= 2; r++)
				{
					for (int q = -2; q <= 2; q++)
					{
						for (int p = -2; p <= 2; p++)
						{
							float3 g = mg + float3(float(p), float(q), float(r));
							float3 o = random3(n + g);
							
							float3 r = g + o - f;
							
							if (dot(mr - r, mr - r) > 0.00001)
							{
								md = min(md, dot(0.5 * (mr + r), normalize(r - mr)));
							}
						}
					}
				}
				return md;
			}
			
			// fracal sum, range -1.0 - 1.0
			float VoronoiNoise_Octaves(float3 p, float scale, float3 speed, int octaveNumber, float octaveScale, float octaveAttenuation, float jitter, float time, out float3 randomPoint)
			{
				float freq = scale;
				float weight = 1.0f;
				float sum = 0;
				// Uncomment when the octave stuff is actually used
				// for (int i = 0; i < octaveNumber; i ++)
				// {
				float3 F = inoise(p * freq + time * speed, jitter, randomPoint) * weight;
				
				sum += sqrt(F[0]);
				
				// 	freq *= octaveScale;
				// 	weight *= 1.0f - octaveAttenuation;
				// }
				return sum;
			}
			
			float VoronoiNoiseDiff_Octaves(float3 p, float scale, float3 speed, int octaveNumber, float octaveScale, float octaveAttenuation, float jitter, float time, out float3 randomPoint)
			{
				float freq = scale;
				float weight = 1.0f;
				float sum = 0;
				// Uncomment when the octave stuff is actually used
				// for (int i = 0; i < octaveNumber; i ++)
				// {
				float3 F = inoise(p * freq + time * speed, jitter, randomPoint) * weight;
				
				sum += sqrt(F[1]) - sqrt(F[0]);
				
				// freq *= octaveScale;
				// weight *= 1.0f - octaveAttenuation;
				// }
				return sum;
			}
			
			void ApplyVoronoi(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float voronoiOctaveNumber = 1;
				float voronoiOctaveScale = 1;
				float voronoiOctaveAttenuation = 1;
				float3 randomPoint = 0;
				
				float voronoi = 0;
				
				float3 position = 0;
				
				UNITY_BRANCH
				if (_VoronoiSpace == 0)
				{
					position = poiMesh.localPos;
				}
				UNITY_BRANCH
				if (_VoronoiSpace == 1)
				{
					position = poiMesh.worldPos;
				}
				UNITY_BRANCH
				if (_VoronoiSpace == 2)
				{
					position = float3(poiMesh.uv[0].x, poiMesh.uv[0].y, 0);
				}
				#if defined(PROP_VORONOIMASK) || !defined(OPTIMIZER_ENABLED)
				float mask = POI2D_SAMPLER_PAN(_VoronoiMask, _MainTex, poiUV(poiMesh.uv[_VoronoiMaskUV], _VoronoiMask_ST), _VoronoiMaskPan)[_VoronoiMaskChannel];
				#else
				float mask = 1;
				#endif
				
				if (_VoronoiGlobalMask > 0)
				{
					mask = maskBlend(mask, poiMods.globalMask[_VoronoiGlobalMask - 1], _VoronoiGlobalMaskBlendType);
				}
				
				#if defined(PROP_VORONOINOISE) || !defined(OPTIMIZER_ENABLED)
				float edgeNoise = POI2D_SAMPLER_PAN(_VoronoiNoise, _MainTex, poiUV(poiMesh.uv[_VoronoiNoiseUV], _VoronoiNoise_ST), _VoronoiNoisePan)[_VoronoiNoiseChannel];
				#else
				float edgeNoise = 0;
				#endif
				edgeNoise *= _VoronoiNoiseIntensity;
				
				float3 voronoiSpeed = _VoronoiSpeed * 10;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					position.x += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedXType, _AudioLinkVoronoiChronoSpeedXBand) * _AudioLinkVoronoiChronoSpeedXSpeed * 0.01;
					position.y += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedYType, _AudioLinkVoronoiChronoSpeedYBand) * _AudioLinkVoronoiChronoSpeedYSpeed * 0.01;
					position.z += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedZType, _AudioLinkVoronoiChronoSpeedZBand) * _AudioLinkVoronoiChronoSpeedZSpeed * 0.01;
				}
				#endif
				
				if (_VoronoiType == 0) // Basic
				
				{
					voronoi = voronoi2D(position.xy, _VoronoiScale, voronoiSpeed, randomPoint.xy);
					voronoi *= 1.55; // Range adjustment
					
				}
				if (_VoronoiType == 1) // Diff
				
				{
					voronoi = VoronoiNoiseDiff_Octaves(position, _VoronoiScale, voronoiSpeed, voronoiOctaveNumber, voronoiOctaveScale, voronoiOctaveAttenuation, 1, _Time.x, randomPoint);
				}
				if (_VoronoiType == 2) // Fixed Border
				
				{
					voronoi = voronoi3D(position, _VoronoiScale, voronoiSpeed, randomPoint);
					voronoi *= 1.8; // Range adjustment
					
				}
				
				float4 outerColor = _VoronoiOuterColor;
				float4 innerColor = _VoronoiInnerColor;
				
				if (_VoronoiEnableRandomCellColor == 1)
				{
					float3 rando = random3(randomPoint);
					fixed hue = rando.x;
					fixed saturation = lerp(_VoronoiRandomMinMaxSaturation.x, _VoronoiRandomMinMaxSaturation.y, rando.y);
					fixed value = lerp(_VoronoiRandomMinMaxBrightness.x, _VoronoiRandomMinMaxBrightness.y, rando.z);
					float3 hsv = float3(hue, saturation, value);
					innerColor.rgb = HSVtoRGB(hsv);
				}
				voronoi = pow(voronoi, _VoronoiPower);
				float2 voronoiGradient = _VoronoiGradient.xy + edgeNoise;
				#ifdef POI_AUDIOLINK
				voronoiGradient.x += _AudioLinkVoronoiGradientMinAdd * poiMods.audioLink[_AudioLinkVoronoiGradientMinAddBand];
				voronoiGradient.y -= _AudioLinkVoronoiGradientMaxAdd * poiMods.audioLink[_AudioLinkVoronoiGradientMaxAddBand];
				#endif
				float ramp = smoothstep(voronoiGradient.x, voronoiGradient.y, voronoi);
				
				if (_VoronoiBlend == 0)
				{
					float4 voronoiColor = lerp(outerColor, innerColor, ramp);
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, voronoiColor, min(mask * voronoiColor.a, 0.99999));
					if (_VoronoiAffectsMaterialAlpha)
					{
						poiFragData.alpha = lerp(poiFragData.alpha, voronoiColor.a, min(mask, 0.99999));
					}
				}
				float outerEmissionStrength = _VoronoiOuterEmissionStrength;
				float innerEmissionStrength = _VoronoiInnerEmissionStrength;
				#ifdef POI_AUDIOLINK
				outerEmissionStrength += lerp(_AudioLinkVoronoiOuterEmission.x, _AudioLinkVoronoiOuterEmission.y, poiMods.audioLink[_AudioLinkVoronoiOuterEmissionBand]);
				innerEmissionStrength += lerp(_AudioLinkVoronoiInnerEmission.x, _AudioLinkVoronoiInnerEmission.y, poiMods.audioLink[_AudioLinkVoronoiInnerEmissionBand]);
				#endif
				float4 voronoiEmissionColor = lerp(outerColor, innerColor, ramp);
				voronoiEmissionColor.rgb *= lerp(outerEmissionStrength, innerEmissionStrength, ramp);
				poiFragData.emission += voronoiEmissionColor.rgb * mask * voronoiEmissionColor.a;
			}
			#endif
			//endex
			
			float4 frag(VertexOut i, uint facing : SV_IsFrontFace) : SV_Target
			/*
			#ifdef
			, out float depth : SV_DEPTH
			#endif
			*/
			{
				UNITY_SETUP_INSTANCE_ID(i);
				UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
				
				PoiMesh poiMesh;
				PoiInitStruct(PoiMesh, poiMesh);
				
				PoiLight poiLight;
				PoiInitStruct(PoiLight, poiLight);
				
				PoiVertexLights poiVertexLights;
				PoiInitStruct(PoiVertexLights, poiVertexLights);
				
				PoiCam poiCam;
				PoiInitStruct(PoiCam, poiCam);
				
				PoiMods poiMods;
				PoiInitStruct(PoiMods, poiMods);
				poiMods.globalEmission = 1;
				
				PoiFragData poiFragData;
				poiFragData.smoothness = 1;
				poiFragData.smoothness2 = 1;
				poiFragData.metallic = 1;
				poiFragData.specularMask = 1;
				poiFragData.reflectionMask = 1;
				poiFragData.emission = 0;
				poiFragData.baseColor = float3(0, 0, 0);
				poiFragData.finalColor = float3(0, 0, 0);
				poiFragData.alpha = 1;
				poiFragData.toggleVertexLights = 0;
				
				#ifdef POI_UDIMDISCARD
				applyUDIMDiscard(i);
				#endif
				
				//ifex _NormalCorrect==0
				#ifdef POI_NORMALCORRECT
				applyNormalCorrect(i);
				#endif
				//endex
				
				// Mesh Data
				//poiMesh.objectPosition = mul(unity_ObjectToWorld, float3(0, 0, 0)).xyz;
				poiMesh.objectPosition = mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
				poiMesh.objNormal = mul(unity_WorldToObject, i.normal);
				poiMesh.normals[0] = i.normal;
				poiMesh.tangent[0] = i.tangent.xyz;
				poiMesh.binormal[0] = cross(i.normal, i.tangent.xyz) * (i.tangent.w * unity_WorldTransformParams.w);
				poiMesh.worldPos = i.worldPos.xyz;
				poiMesh.localPos = i.localPos.xyz;
				poiMesh.vertexColor = i.vertexColor;
				poiMesh.isFrontFace = facing;
				poiMesh.dx = ddx(poiMesh.uv[0]);
				poiMesh.dy = ddy(poiMesh.uv[0]);
				
				#ifndef POI_PASS_OUTLINE
				if (!poiMesh.isFrontFace && _FlipBackfaceNormals)
				{
					poiMesh.normals[0] *= -1;
					poiMesh.tangent[0] *= -1;
					poiMesh.binormal[0] *= -1;
				}
				#endif
				
				poiCam.viewDir = !IsOrthographicCamera() ? normalize(_WorldSpaceCameraPos - i.worldPos.xyz) : normalize(UNITY_MATRIX_I_V._m02_m12_m22);
				float3 tanToWorld0 = float3(poiMesh.tangent[0].x, poiMesh.binormal[0].x, poiMesh.normals[0].x);
				float3 tanToWorld1 = float3(poiMesh.tangent[0].y, poiMesh.binormal[0].y, poiMesh.normals[0].y);
				float3 tanToWorld2 = float3(poiMesh.tangent[0].z, poiMesh.binormal[0].z, poiMesh.normals[0].z);
				float3 ase_tanViewDir = tanToWorld0 * poiCam.viewDir.x + tanToWorld1 * poiCam.viewDir.y + tanToWorld2 * poiCam.viewDir.z;
				poiCam.tangentViewDir = normalize(ase_tanViewDir);
				
				// 0-3 UV0-UV3
				// 4 Panosphere UV
				// 5 world pos xz
				// 6 Polar UV
				// 6 Distorted UV
				#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
				poiMesh.lightmapUV = i.lightmapUV;
				#endif
				poiMesh.parallaxUV = poiCam.tangentViewDir.xy / max(poiCam.tangentViewDir.z, 0.0001);
				poiMesh.uv[0] = i.uv[0].xy;
				poiMesh.uv[1] = i.uv[0].zw;
				poiMesh.uv[2] = i.uv[1].xy;
				poiMesh.uv[3] = i.uv[1].zw;
				poiMesh.uv[4] = poiMesh.uv[0];
				poiMesh.uv[5] = poiMesh.uv[0];
				poiMesh.uv[6] = poiMesh.uv[0];
				poiMesh.uv[7] = poiMesh.uv[0];
				poiMesh.uv[8] = poiMesh.uv[0];
				
				poiMesh.uv[4] = calculatePanosphereUV(poiMesh);
				poiMesh.uv[5] = calculateWorldUV(poiMesh);
				poiMesh.uv[6] = calculatePolarCoordinate(poiMesh);
				poiMesh.uv[8] = calculatelocalUV(poiMesh);
				//ifex _EnableDistortion==0
				#ifdef USER_LUT
				poiMesh.uv[7] = distortedUV(poiMesh);
				#endif
				//endex
				/*
				half3 worldViewUp = normalize(half3(0, 1, 0) - poiCam.viewDir * dot(poiCam.viewDir, half3(0, 1, 0)));
				half3 worldViewRight = normalize(cross(poiCam.viewDir, worldViewUp));
				poiMesh[8] = half2(dot(worldViewRight, poiMesh.normals[_MatcapNormal]), dot(worldViewUp, poiMesh.normals[_MatcapNormal])) * _MatcapBorder + 0.5;
				*/
				
				//ifex _PoiParallax==0
				#ifdef POI_PARALLAX
				#ifndef POI_PASS_OUTLINE
				//return frac(i.tangentViewDir.x);
				//return float4(i.binormal.xyz,1);
				applyParallax(poiMesh, poiLight, poiCam);
				#endif
				#endif
				//endex
				
				poiMods.globalMask[0] = 1;
				poiMods.globalMask[1] = 1;
				poiMods.globalMask[2] = 1;
				poiMods.globalMask[3] = 1;
				poiMods.globalMask[4] = 1;
				poiMods.globalMask[5] = 1;
				poiMods.globalMask[6] = 1;
				poiMods.globalMask[7] = 1;
				poiMods.globalMask[8] = 1;
				poiMods.globalMask[9] = 1;
				poiMods.globalMask[10] = 1;
				poiMods.globalMask[11] = 1;
				poiMods.globalMask[12] = 1;
				poiMods.globalMask[13] = 1;
				poiMods.globalMask[14] = 1;
				poiMods.globalMask[15] = 1;
				//ifex _GlobalMaskTexturesEnable==0
				#ifdef POI_GLOBALMASK_TEXTURES
				ApplyGlobalMaskTextures(poiMesh, poiMods);
				#endif
				//endex
				//ifex _GlobalMaskVertexColorRed==0 && _GlobalMaskVertexColorGreen==0 && _GlobalMaskVertexColorBlue==0 && _GlobalMaskVertexColorAlpha==0
				ApplyGlobalMaskVertexColors(poiMesh, poiMods);
				//endex
				ApplyGlobalMaskModifiers(poiMesh, poiMods, poiCam);
				//ifex _GlobalMaskOptionsEnable==0
				if (_GlobalMaskOptionsEnable)
				{
					ApplyGlobalMaskOptions(poiMods);
				}
				//endex
				
				float2 mainUV = poiUV(poiMesh.uv[_MainTexUV].xy, _MainTex_ST);
				
				if (_MainPixelMode)
				{
					mainUV = sharpSample(_MainTex_TexelSize, mainUV);
				}
				
				float4 mainTexture = POI2D_SAMPLER_PAN_STOCHASTIC(_MainTex, _MainTex, mainUV, _MainTexPan, _MainTexStochastic);
				
				//ifex _VideoEffectsEnable==0
				#ifdef POI_VIDEO_EFFECTS
				if (_VideoEffectsEnable)
				{
					applyVideoEffectsMainTex(mainTexture, poiMesh);
				}
				#endif
				//endex
				
				#if defined(PROP_BUMPMAP) || !defined(OPTIMIZER_ENABLED)
				poiMesh.tangentSpaceNormal = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_BumpMap, _MainTex, poiUV(poiMesh.uv[_BumpMapUV].xy, _BumpMap_ST), _BumpMapPan, _BumpMapStochastic), _BumpScale);
				#else
				poiMesh.tangentSpaceNormal = UnpackNormal(float4(0.5, 0.5, 1, 1));
				#endif
				
				//ifex _DetailEnabled==0
				#if defined(FINALPASS) && !defined(UNITY_PASS_SHADOWCASTER) && !defined(POI_PASS_OUTLINE)
				ApplyDetailNormal(poiMods, poiMesh);
				#endif
				//endex
				
				//ifex _RGBMaskEnabled==0
				#if defined(VIGNETTE) && !defined(UNITY_PASS_SHADOWCASTER) && !defined(POI_PASS_OUTLINE)
				calculateRGBNormals(poiMesh, poiMods);
				#endif
				
				//endex
				
				float3 tangentSpaceNormal = UnpackNormal(float4(0.5, 0.5, 1, 1));
				poiMesh.normals[0] = normalize(
				tangentSpaceNormal.x * poiMesh.tangent[0] +
				tangentSpaceNormal.y * poiMesh.binormal[0] +
				tangentSpaceNormal.z * poiMesh.normals[0]
				);
				
				poiMesh.normals[1] = normalize(
				poiMesh.tangentSpaceNormal.x * poiMesh.tangent[0] +
				poiMesh.tangentSpaceNormal.y * poiMesh.binormal[0] +
				poiMesh.tangentSpaceNormal.z * poiMesh.normals[0]
				);
				
				poiMesh.tangent[1] = cross(poiMesh.binormal[0], -poiMesh.normals[1]);
				poiMesh.binormal[1] = cross(-poiMesh.normals[1], poiMesh.tangent[0]);
				
				//ifex _EnableOutlines!=1
				#ifdef POI_PASS_OUTLINE
				poiMesh.normals[1] = poiMesh.normals[0];
				#endif
				//endex
				
				// Camera data
				poiCam.forwardDir = getCameraForward();
				poiCam.worldPos = _WorldSpaceCameraPos;
				poiCam.reflectionDir = reflect(-poiCam.viewDir, poiMesh.normals[1]);
				poiCam.vertexReflectionDir = reflect(-poiCam.viewDir, poiMesh.normals[0]);
				//poiCam.distanceToModel = distance(poiMesh.modelPos, poiCam.worldPos);
				poiCam.clipPos = i.pos;
				poiCam.distanceToVert = distance(poiMesh.worldPos, poiCam.worldPos);
				poiCam.posScreenSpace = poiTransformClipSpacetoScreenSpaceFrag(poiCam.clipPos);
				#if defined(POI_GRABPASS) && defined(POI_PASS_BASE)
				poiCam.screenUV = poiCam.clipPos.xy / poiGetWidthAndHeight(_PoiGrab2);
				#else
				poiCam.screenUV = poiCam.clipPos.xy / _ScreenParams.xy;
				#endif
				#ifdef UNITY_SINGLE_PASS_STEREO
				poiCam.posScreenSpace.x = poiCam.posScreenSpace.x * 0.5;
				#endif
				poiCam.posScreenPixels = calcPixelScreenUVs(poiCam.posScreenSpace);
				poiCam.vDotN = abs(dot(poiCam.viewDir, poiMesh.normals[1]));
				
				poiCam.worldDirection.xyz = poiMesh.worldPos.xyz - poiCam.worldPos;
				poiCam.worldDirection.w = dot(poiCam.clipPos, CalculateFrustumCorrection());
				
				calculateGlobalThemes(poiMods);
				
				poiLight.finalLightAdd = 0;
				
				// Ambient Occlusion
				#if defined(PROP_LIGHTINGAOMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 AOMaps = POI2D_SAMPLER_PAN(_LightingAOMaps, _MainTex, poiUV(poiMesh.uv[_LightingAOMapsUV], _LightingAOMaps_ST), _LightingAOMapsPan);
				poiLight.occlusion = min(min(min(lerp(1, AOMaps.r, _LightDataAOStrengthR), lerp(1, AOMaps.g, _LightDataAOStrengthG)), lerp(1, AOMaps.b, _LightDataAOStrengthB)), lerp(1, AOMaps.a, _LightDataAOStrengthA));
				#else
				poiLight.occlusion = 1;
				#endif
				
				if (_LightDataAOGlobalMaskR > 0)
				{
					poiLight.occlusion = maskBlend(poiLight.occlusion, poiMods.globalMask[_LightDataAOGlobalMaskR - 1], _LightDataAOGlobalMaskBlendTypeR);
				}
				
				// Detail Shadows
				#if defined(PROP_LIGHTINGDETAILSHADOWMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 DetailShadows = POI2D_SAMPLER_PAN(_LightingDetailShadowMaps, _MainTex, poiUV(poiMesh.uv[_LightingDetailShadowMapsUV], _LightingDetailShadowMaps_ST), _LightingDetailShadowMapsPan);
				#ifndef POI_PASS_ADD
				poiLight.detailShadow = lerp(1, DetailShadows.r, _LightingDetailShadowStrengthR) * lerp(1, DetailShadows.g, _LightingDetailShadowStrengthG) * lerp(1, DetailShadows.b, _LightingDetailShadowStrengthB) * lerp(1, DetailShadows.a, _LightingDetailShadowStrengthA);
				#else
				poiLight.detailShadow = lerp(1, DetailShadows.r, _LightingAddDetailShadowStrengthR) * lerp(1, DetailShadows.g, _LightingAddDetailShadowStrengthG) * lerp(1, DetailShadows.b, _LightingAddDetailShadowStrengthB) * lerp(1, DetailShadows.a, _LightingAddDetailShadowStrengthA);
				#endif
				#else
				poiLight.detailShadow = 1;
				#endif
				
				if (_LightDataDetailShadowGlobalMaskR > 0)
				{
					poiLight.detailShadow = maskBlend(poiLight.detailShadow, poiMods.globalMask[_LightDataDetailShadowGlobalMaskR - 1], _LightDataDetailShadowGlobalMaskBlendTypeR);
				}
				
				// Shadow Masks
				#if defined(PROP_LIGHTINGSHADOWMASKS) || !defined(OPTIMIZER_ENABLED)
				float4 ShadowMasks = POI2D_SAMPLER_PAN(_LightingShadowMasks, _MainTex, poiUV(poiMesh.uv[_LightingShadowMasksUV], _LightingShadowMasks_ST), _LightingShadowMasksPan);
				poiLight.shadowMask = lerp(1, ShadowMasks.r, _LightingShadowMaskStrengthR) * lerp(1, ShadowMasks.g, _LightingShadowMaskStrengthG) * lerp(1, ShadowMasks.b, _LightingShadowMaskStrengthB) * lerp(1, ShadowMasks.a, _LightingShadowMaskStrengthA);
				#else
				poiLight.shadowMask = 1;
				#endif
				if (_LightDataShadowMaskGlobalMaskR > 0)
				{
					poiLight.shadowMask = maskBlend(poiLight.shadowMask, poiMods.globalMask[_LightDataShadowMaskGlobalMaskR - 1], _LightDataShadowMaskGlobalMaskBlendTypeR);
				}
				
				#ifdef UNITY_PASS_FORWARDBASE
				
				bool lightExists = false;
				if (any(_LightColor0.rgb >= 0.002))
				{
					lightExists = true;
				}
				
				if (_LightingVertexLightingEnabled)
				{
					poiFragData.toggleVertexLights = 1;
				}
				if (IsInMirror() && _LightingMirrorVertexLightingEnabled == 0)
				{
					poiFragData.toggleVertexLights = 0;
				}
				
				if (_LightingVertexLightingEnabled)
				{
					#if defined(VERTEXLIGHT_ON)
					float4 toLightX = unity_4LightPosX0 - i.worldPos.x;
					float4 toLightY = unity_4LightPosY0 - i.worldPos.y;
					float4 toLightZ = unity_4LightPosZ0 - i.worldPos.z;
					float4 lengthSq = 0;
					lengthSq += toLightX * toLightX;
					lengthSq += toLightY * toLightY;
					lengthSq += toLightZ * toLightZ;
					
					float4 lightAttenSq = unity_4LightAtten0;
					float4 atten = 1.0 / (1.0 + lengthSq * lightAttenSq);
					float4 vLightWeight = saturate(1 - (lengthSq * lightAttenSq / 25));
					poiLight.vAttenuation = min(atten, vLightWeight * vLightWeight);
					
					poiLight.vDotNL = 0;
					poiLight.vDotNL += toLightX * poiMesh.normals[1].x;
					poiLight.vDotNL += toLightY * poiMesh.normals[1].y;
					poiLight.vDotNL += toLightZ * poiMesh.normals[1].z;
					
					float4 corr = rsqrt(lengthSq);
					poiLight.vertexVDotNL = max(0, poiLight.vDotNL * corr);
					
					poiLight.vertexVDotNL = 0;
					poiLight.vertexVDotNL += toLightX * poiMesh.normals[0].x;
					poiLight.vertexVDotNL += toLightY * poiMesh.normals[0].y;
					poiLight.vertexVDotNL += toLightZ * poiMesh.normals[0].z;
					
					poiLight.vertexVDotNL = max(0, poiLight.vDotNL * corr);
					
					poiLight.vSaturatedDotNL = saturate(poiLight.vDotNL);
					
					[unroll]
					for (int index = 0; index < 4; index++)
					{
						poiLight.vPosition[index] = float3(unity_4LightPosX0[index], unity_4LightPosY0[index], unity_4LightPosZ0[index]);
						
						float3 vertexToLightSource = poiLight.vPosition[index] - poiMesh.worldPos;
						poiLight.vDirection[index] = normalize(vertexToLightSource);
						poiLight.vColor[index] = _LightingAdditiveLimited ? MaxLuminance(unity_LightColor[index].rgb * poiLight.vAttenuation[index], _LightingAdditiveLimit) : unity_LightColor[index].rgb * poiLight.vAttenuation[index];
						poiLight.vColor[index] = lerp(poiLight.vColor[index], dot(poiLight.vColor[index], float3(0.299, 0.587, 0.114)), _LightingAdditiveMonochromatic);
						poiLight.vHalfDir[index] = Unity_SafeNormalize(poiLight.vDirection[index] + poiCam.viewDir);
						poiLight.vDotNL[index] = dot(poiMesh.normals[1], poiLight.vDirection[index]);
						poiLight.vCorrectedDotNL[index] = .5 * (poiLight.vDotNL[index] + 1);
						poiLight.vDotLH[index] = saturate(dot(poiLight.vDirection[index], poiLight.vHalfDir[index]));
						
						poiLight.vDotNH[index] = dot(poiMesh.normals[1], poiLight.vHalfDir[index]);
						poiLight.vertexVDotNH[index] = saturate(dot(poiMesh.normals[0], poiLight.vHalfDir[index]));
					}
					#endif
				}
				
				//UNITY_BRANCH
				if (_LightingColorMode == 0) // Poi Custom Light Color
				
				{
					float3 magic = max(BetterSH9(normalize(unity_SHAr + unity_SHAg + unity_SHAb)), 0);
					float3 normalLight = _LightColor0.rgb + BetterSH9(float4(0, 0, 0, 1));
					
					float magiLumi = calculateluminance(magic);
					float normaLumi = calculateluminance(normalLight);
					float maginormalumi = magiLumi + normaLumi;
					
					float magiratio = magiLumi / maginormalumi;
					float normaRatio = normaLumi / maginormalumi;
					
					float target = calculateluminance(magic * magiratio + normalLight * normaRatio);
					float3 properLightColor = magic + normalLight;
					float properLuminance = calculateluminance(magic + normalLight);
					poiLight.directColor = properLightColor * max(0.0001, (target / properLuminance));
					
					poiLight.indirectColor = BetterSH9(float4(lerp(0, poiMesh.normals[1], _LightingIndirectUsesNormals), 1));
				}
				
				//UNITY_BRANCH
				if (_LightingColorMode == 1) // More standard approach to light color
				
				{
					float3 indirectColor = BetterSH9(float4(poiMesh.normals[1], 1));
					if (lightExists)
					{
						poiLight.directColor = _LightColor0.rgb;
						poiLight.indirectColor = indirectColor;
					}
					else
					{
						poiLight.directColor = indirectColor * 0.6;
						poiLight.indirectColor = indirectColor * 0.5;
					}
				}
				
				if (_LightingColorMode == 2) // UTS style
				
				{
					poiLight.indirectColor = saturate(max(half3(0.05, 0.05, 0.05) * _Unlit_Intensity, max(ShadeSH9(half4(0.0, 0.0, 0.0, 1.0)), ShadeSH9(half4(0.0, -1.0, 0.0, 1.0)).rgb) * _Unlit_Intensity));
					poiLight.directColor = max(poiLight.indirectColor, _LightColor0.rgb);
				}
				
				if (_LightingColorMode == 3) // OpenLit
				
				{
					float3 lightDirectionForSH9 = OpenLitLightingDirectionForSH9();
					OpenLitShadeSH9ToonDouble(lightDirectionForSH9, poiLight.directColor, poiLight.indirectColor);
					poiLight.directColor += _LightColor0.rgb;
					// OpenLit does a few other things by default like clamp direct colour
					// see https://github.com/lilxyzw/OpenLit/blob/main/Assets/OpenLit/core.hlsl#L174
				}
				
				float lightMapMode = _LightingMapMode;
				//UNITY_BRANCH
				if (_LightingDirectionMode == 0)
				{
					poiLight.direction = _WorldSpaceLightPos0.xyz + unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz;
				}
				if (_LightingDirectionMode == 1 || _LightingDirectionMode == 2)
				{
					//UNITY_BRANCH
					if (_LightingDirectionMode == 1)
					{
						poiLight.direction = mul(unity_ObjectToWorld, _LightngForcedDirection).xyz;;
					}
					//UNITY_BRANCH
					if (_LightingDirectionMode == 2)
					{
						poiLight.direction = _LightngForcedDirection;
					}
					if (lightMapMode == 0)
					{
						lightMapMode == 1;
					}
				}
				
				if (_LightingDirectionMode == 3) // UTS
				
				{
					float3 defaultLightDirection = normalize(UNITY_MATRIX_V[2].xyz + UNITY_MATRIX_V[1].xyz);
					float3 lightDirection = normalize(lerp(defaultLightDirection, _WorldSpaceLightPos0.xyz, any(_WorldSpaceLightPos0.xyz)));
					poiLight.direction = lightDirection;
				}
				if (_LightingDirectionMode == 4) // OpenLit
				
				{
					poiLight.direction = OpenLitLightingDirection(); // float4 customDir = 0; // Do we want to give users to alter this (OpenLit always does!)?
					
				}
				
				if (_LightingDirectionMode == 5) // View Direction
				
				{
					float3 upViewDir = normalize(UNITY_MATRIX_V[1].xyz);
					float3 rightViewDir = normalize(UNITY_MATRIX_V[0].xyz);
					float yawOffset_Rads = radians(!IsInMirror() ? - _LightingViewDirOffsetYaw : _LightingViewDirOffsetYaw);
					float3 rotatedViewYaw = normalize(RotateAroundAxis(rightViewDir, upViewDir, yawOffset_Rads));
					float3 rotatedViewCameraMeshOffset = RotateAroundAxis((getCameraPosition() - (poiMesh.worldPos)), upViewDir, yawOffset_Rads);
					float pitchOffset_Rads = radians(!IsInMirror() ? _LightingViewDirOffsetPitch : - _LightingViewDirOffsetPitch);
					float3 rotatedViewPitch = RotateAroundAxis(rotatedViewCameraMeshOffset, rotatedViewYaw, pitchOffset_Rads);
					poiLight.direction = normalize(rotatedViewPitch);
				}
				
				if (!any(poiLight.direction))
				{
					poiLight.direction = float3(.4, 1, .4);
				}
				
				poiLight.direction = normalize(poiLight.direction);
				poiLight.attenuationStrength = _LightingCastedShadows;
				poiLight.attenuation = 1;
				if (!all(_LightColor0.rgb == 0.0))
				{
					UNITY_LIGHT_ATTENUATION(attenuation, i, poiMesh.worldPos)
					poiLight.attenuation *= attenuation;
				}
				
				if (!any(poiLight.directColor) && !any(poiLight.indirectColor) && lightMapMode == 0)
				{
					lightMapMode = 1;
					if (_LightingDirectionMode == 0)
					{
						poiLight.direction = normalize(float3(.4, 1, .4));
					}
				}
				
				poiLight.halfDir = normalize(poiLight.direction + poiCam.viewDir);
				poiLight.vertexNDotL = dot(poiMesh.normals[0], poiLight.direction);
				poiLight.nDotL = dot(poiMesh.normals[1], poiLight.direction);
				poiLight.nDotLSaturated = saturate(poiLight.nDotL);
				poiLight.nDotLNormalized = (poiLight.nDotL + 1) * 0.5;
				poiLight.nDotV = abs(dot(poiMesh.normals[1], poiCam.viewDir));
				poiLight.vertexNDotV = abs(dot(poiMesh.normals[0], poiCam.viewDir));
				poiLight.nDotH = dot(poiMesh.normals[1], poiLight.halfDir);
				poiLight.vertexNDotH = max(0.00001, dot(poiMesh.normals[0], poiLight.halfDir));
				poiLight.lDotv = dot(poiLight.direction, poiCam.viewDir);
				poiLight.lDotH = max(0.00001, dot(poiLight.direction, poiLight.halfDir));
				
				// Poi special light map
				if (lightMapMode == 0)
				{
					float3 ShadeSH9Plus = GetSHLength();
					float3 ShadeSH9Minus = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) + float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0;
					
					float3 greyScaleVector = float3(.33333, .33333, .33333);
					float bw_lightColor = dot(poiLight.directColor, greyScaleVector);
					float bw_directLighting = (((poiLight.nDotL * 0.5 + 0.5) * bw_lightColor * lerp(1, poiLight.attenuation, poiLight.attenuationStrength)) + dot(ShadeSH9(float4(poiMesh.normals[1], 1)), greyScaleVector));
					float bw_directLightingNoAtten = (((poiLight.nDotL * 0.5 + 0.5) * bw_lightColor) + dot(ShadeSH9(float4(poiMesh.normals[1], 1)), greyScaleVector));
					float bw_bottomIndirectLighting = dot(ShadeSH9Minus, greyScaleVector);
					float bw_topIndirectLighting = dot(ShadeSH9Plus, greyScaleVector);
					float lightDifference = ((bw_topIndirectLighting + bw_lightColor) - bw_bottomIndirectLighting);
					
					poiLight.lightMap = smoothstep(0, lightDifference, bw_directLighting - bw_bottomIndirectLighting);
					poiLight.lightMapNoAttenuation = smoothstep(0, lightDifference, bw_directLightingNoAtten - bw_bottomIndirectLighting);
				}
				// Normalized nDotL
				if (lightMapMode == 1)
				{
					poiLight.lightMapNoAttenuation = poiLight.nDotLNormalized;
					poiLight.lightMap = poiLight.nDotLNormalized * lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				}
				// Saturated nDotL
				if (lightMapMode == 2)
				{
					poiLight.lightMapNoAttenuation = poiLight.nDotLSaturated;
					poiLight.lightMap = poiLight.nDotLSaturated * lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				}
				if (lightMapMode == 3)
				{
					poiLight.lightMapNoAttenuation = 1;
					poiLight.lightMap = lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				}
				poiLight.lightMapNoAttenuation *= poiLight.detailShadow;
				poiLight.lightMap *= poiLight.detailShadow;
				
				poiLight.directColor = max(poiLight.directColor, 0.0001);
				poiLight.indirectColor = max(poiLight.indirectColor, 0.0001);
				
				if (_LightingColorMode == 3)
				{
					// OpenLit
					poiLight.directColor = max(poiLight.directColor, _LightingMinLightBrightness);
				}
				else
				{
					poiLight.directColor = max(poiLight.directColor, poiLight.directColor * min(10000, (_LightingMinLightBrightness * rcp(calculateluminance(poiLight.directColor)))));
					poiLight.indirectColor = max(poiLight.indirectColor, poiLight.indirectColor * min(10000, (_LightingMinLightBrightness * rcp(calculateluminance(poiLight.indirectColor)))));
				}
				
				poiLight.directColor = lerp(poiLight.directColor, dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic);
				poiLight.indirectColor = lerp(poiLight.indirectColor, dot(poiLight.indirectColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic);
				
				if (_LightingCapEnabled)
				{
					poiLight.directColor = min(poiLight.directColor, _LightingCap);
					poiLight.indirectColor = min(poiLight.indirectColor, _LightingCap);
				}
				
				if (_LightingForceColorEnabled)
				{
					poiLight.directColor = poiThemeColor(poiMods, _LightingForcedColor, _LightingForcedColorThemeIndex);
				}
				
				#ifdef UNITY_PASS_FORWARDBASE
				poiLight.directColor = max(poiLight.directColor * _PPLightingMultiplier, 0);
				poiLight.directColor = max(poiLight.directColor + _PPLightingAddition, 0);
				poiLight.indirectColor = max(poiLight.indirectColor * _PPLightingMultiplier, 0);
				poiLight.indirectColor = max(poiLight.indirectColor + _PPLightingAddition, 0);
				#endif
				
				#endif
				
				#ifdef POI_PASS_ADD
				if (!_LightingAdditiveEnable)
				{
					return float4(mainTexture.rgb * .0001, 1);
				}
				
				#if defined(DIRECTIONAL)
				if (_DisableDirectionalInAdd)
				{
					return float4(mainTexture.rgb * .0001, 1);
				}
				#endif
				
				poiLight.direction = normalize(_WorldSpaceLightPos0.xyz - i.worldPos.xyz * _WorldSpaceLightPos0.w);
				#if defined(POINT) || defined(SPOT)
				#ifdef POINT
				unityShadowCoord3 lightCoord = mul(unity_WorldToLight, unityShadowCoord4(poiMesh.worldPos, 1)).xyz;
				poiLight.attenuation = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).r;
				#endif
				
				#ifdef SPOT
				unityShadowCoord4 lightCoord = mul(unity_WorldToLight, unityShadowCoord4(poiMesh.worldPos, 1));
				poiLight.attenuation = (lightCoord.z > 0) * UnitySpotCookie(lightCoord) * UnitySpotAttenuate(lightCoord.xyz);
				#endif
				#else
				UNITY_LIGHT_ATTENUATION(attenuation, i, poiMesh.worldPos)
				poiLight.attenuation = attenuation;
				#endif
				poiLight.additiveShadow = UNITY_SHADOW_ATTENUATION(i, poiMesh.worldPos);
				poiLight.attenuationStrength = _LightingAdditiveCastedShadows;
				poiLight.directColor = _LightingAdditiveLimited ? MaxLuminance(_LightColor0.rgb * poiLight.attenuation, _LightingAdditiveLimit) : _LightColor0.rgb  * poiLight.attenuation;
				
				#if defined(POINT_COOKIE) || defined(DIRECTIONAL_COOKIE)
				poiLight.indirectColor = 0;
				#else
				poiLight.indirectColor = lerp(0, poiLight.directColor, _LightingAdditivePassthrough);
				poiLight.indirectColor = _LightingAdditiveLimited ? MaxLuminance(poiLight.indirectColor, _LightingAdditiveLimit) : poiLight.indirectColor;
				#endif
				
				poiLight.directColor = lerp(poiLight.directColor, dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), _LightingAdditiveMonochromatic);
				poiLight.indirectColor = lerp(poiLight.indirectColor, dot(poiLight.indirectColor, float3(0.299, 0.587, 0.114)), _LightingAdditiveMonochromatic);
				
				poiLight.halfDir = normalize(poiLight.direction + poiCam.viewDir);
				poiLight.nDotL = dot(poiMesh.normals[1], poiLight.direction);
				poiLight.nDotLSaturated = saturate(poiLight.nDotL);
				poiLight.nDotLNormalized = (poiLight.nDotL + 1) * 0.5;
				poiLight.nDotV = abs(dot(poiMesh.normals[1], poiCam.viewDir));
				poiLight.nDotH = dot(poiMesh.normals[1], poiLight.halfDir);
				poiLight.lDotv = dot(poiLight.direction, poiCam.viewDir);
				poiLight.lDotH = dot(poiLight.direction, poiLight.halfDir);
				poiLight.vertexNDotL = dot(poiMesh.normals[0], poiLight.direction);
				poiLight.vertexNDotV = abs(dot(poiMesh.normals[0], poiCam.viewDir));
				poiLight.vertexNDotH = max(0.00001, dot(poiMesh.normals[0], poiLight.halfDir));
				
				// Normalized nDotL
				if (_LightingMapMode == 0 || _LightingMapMode == 1 || _LightingMapMode == 2)
				{
					poiLight.lightMap = poiLight.nDotLNormalized;
				}
				if (_LightingMapMode == 3)
				{
					poiLight.lightMap = 1;
				}
				poiLight.lightMap *= poiLight.detailShadow;
				poiLight.lightMapNoAttenuation = poiLight.lightMap;
				poiLight.lightMap *= lerp(1, poiLight.additiveShadow, poiLight.attenuationStrength);
				#endif
				
				//ifex _LightDataDebugEnabled==0
				if (_LightDataDebugEnabled)
				{
					#ifdef UNITY_PASS_FORWARDBASE
					//UNITY_BRANCH
					if (_LightingDebugVisualize <= 6)
					{
						switch(_LightingDebugVisualize)
						{
							case 0: // Direct Light Color
							return float4(poiLight.directColor + mainTexture.rgb * .0001, 1);
							break;
							case 1: // Indirect Light Color
							return float4(poiLight.indirectColor + mainTexture.rgb * .0001, 1);
							break;
							case 2: // Light Map
							return float4(poiLight.lightMap + mainTexture.rgb * .0001, 1);
							break;
							case 3: // Attenuation
							return float4(poiLight.attenuation + mainTexture.rgb * .0001, 1);
							break;
							case 4: // N Dot L
							return float4(poiLight.nDotLNormalized, poiLight.nDotLNormalized, poiLight.nDotLNormalized, 1) + mainTexture * .0001;
							break;
							case 5:
							return float4(poiLight.halfDir, 1) + mainTexture * .0001;
							break;
							case 6:
							return float4(poiLight.direction, 1) + mainTexture * .0001;
							break;
						}
					}
					else
					{
						return POI_SAFE_RGB1;
					}
					#endif
					#ifdef POI_PASS_ADD
					//UNITY_BRANCH
					if (_LightingDebugVisualize < 6)
					{
						return POI_SAFE_RGB1;
					}
					else
					{
						switch(_LightingDebugVisualize)
						{
							case 7:
							return float4(poiLight.directColor * poiLight.attenuation + mainTexture.rgb * .0001, 1);
							break;
							case 8:
							return float4(poiLight.attenuation + mainTexture.rgb * .0001, 1);
							break;
							case 9:
							return float4(poiLight.additiveShadow + mainTexture.rgb * .0001, 1);
							break;
							case 10:
							return float4(poiLight.nDotLNormalized + mainTexture.rgb * .0001, 1);
							break;
							case 11:
							return float4(poiLight.halfDir, 1) + mainTexture * .0001;
							break;
						}
					}
					#endif
				}
				//endex
				
				//ifex _EnableAudioLink==0
				#ifdef POI_AUDIOLINK
				SetupAudioLink(poiFragData, poiMods, poiMesh);
				#endif
				//endex
				
				//ifex _MochieBRDF==0
				#if defined(MOCHIE_PBR)
				MetallicAndSpecularFragDataInit(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _BlackLightMaskingEnabled==0
				#ifdef POI_BLACKLIGHTMASKING
				calculateBlackLightMasks(poiMesh, poiMods);
				#endif
				//endex
				
				poiFragData.baseColor = mainTexture.rgb * poiThemeColor(poiMods, _Color.rgb, _ColorThemeIndex);
				poiFragData.alpha = mainTexture.a * _Color.a;
				
				//ifex _MainColorAdjustToggle==0
				#ifdef COLOR_GRADING_HDR
				#if defined(PROP_MAINCOLORADJUSTTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 hueShiftAlpha = POI2D_SAMPLER_PAN(_MainColorAdjustTexture, _MainTex, poiUV(poiMesh.uv[_MainColorAdjustTextureUV], _MainColorAdjustTexture_ST), _MainColorAdjustTexturePan);
				#else
				float4 hueShiftAlpha = 1;
				#endif
				
				if (_MainHueGlobalMask > 0)
				{
					hueShiftAlpha.r = maskBlend(hueShiftAlpha.r, poiMods.globalMask[_MainHueGlobalMask - 1], _MainHueGlobalMaskBlendType);
				}
				if (_MainSaturationGlobalMask > 0)
				{
					hueShiftAlpha.b = maskBlend(hueShiftAlpha.b, poiMods.globalMask[_MainSaturationGlobalMask - 1], _MainSaturationGlobalMaskBlendType);
				}
				if (_MainBrightnessGlobalMask > 0)
				{
					hueShiftAlpha.g = maskBlend(hueShiftAlpha.g, poiMods.globalMask[_MainBrightnessGlobalMask - 1], _MainBrightnessGlobalMaskBlendType);
				}
				
				if (_MainHueShiftToggle)
				{
					float shift = _MainHueShift;
					#ifdef POI_AUDIOLINK
					//UNITY_BRANCH
					if (poiMods.audioLinkAvailable && _MainHueALCTEnabled)
					{
						shift += AudioLinkGetChronoTime(_MainALHueShiftCTIndex, _MainALHueShiftBand) * _MainHueALMotionSpeed;
					}
					#endif
					if (_MainHueShiftReplace)
					{
						poiFragData.baseColor = lerp(poiFragData.baseColor, hueShift(poiFragData.baseColor, shift + _MainHueShiftSpeed * _Time.x), hueShiftAlpha.r);
					}
					else
					{
						poiFragData.baseColor = hueShift(poiFragData.baseColor, frac((shift - (1 - hueShiftAlpha.r) + _MainHueShiftSpeed * _Time.x)));
					}
				}
				
				if (_MainGradationStrength && _ColorGradingToggle)
				{
					#if !defined(UNITY_COLORSPACE_GAMMA)
					float3 tempColor = OpenLitLinearToSRGB(poiFragData.baseColor);
					#else
					float3 tempColor = poiFragData.baseColor;
					#endif
					#if defined(PROP_MAINGRADATIONTEX) || !defined(OPTIMIZER_ENABLED)
					tempColor.r = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.r).r;
					tempColor.g = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.g).g;
					tempColor.b = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.b).b;
					#else
					tempColor = float3(1, 1, 1);
					#endif
					#if !defined(UNITY_COLORSPACE_GAMMA)
					tempColor = OpenLitSRGBToLinear(tempColor);
					#endif
					poiFragData.baseColor = lerp(poiFragData.baseColor, tempColor, _MainGradationStrength);
				}
				
				poiFragData.baseColor = lerp(poiFragData.baseColor, dot(poiFragData.baseColor, float3(0.3, 0.59, 0.11)), - (_Saturation) * hueShiftAlpha.b);
				poiFragData.baseColor = saturate(lerp(poiFragData.baseColor, poiFragData.baseColor * (_MainBrightness + 1), hueShiftAlpha.g));
				#endif
				//endex
				
				#if defined(PROP_ALPHAMASK) || !defined(OPTIMIZER_ENABLED)
				
				if (_MainAlphaMaskMode)
				{
					float alphaMask = POI2D_SAMPLER_PAN(_AlphaMask, _MainTex, poiUV(poiMesh.uv[_AlphaMaskUV], _AlphaMask_ST), _AlphaMaskPan.xy).r;
					alphaMask = saturate(alphaMask * _AlphaMaskScale + _AlphaMaskValue);
					if (_AlphaMaskInvert) alphaMask = 1 - alphaMask;
					if (_MainAlphaMaskMode == 1) poiFragData.alpha = alphaMask;
					if (_MainAlphaMaskMode == 2) poiFragData.alpha = poiFragData.alpha * alphaMask;
					if (_MainAlphaMaskMode == 3) poiFragData.alpha = saturate(poiFragData.alpha + alphaMask);
					if (_MainAlphaMaskMode == 4) poiFragData.alpha = saturate(poiFragData.alpha - alphaMask);
				}
				#endif
				
				//ifex _VideoEffectsEnable==0
				#ifdef POI_VIDEO_EFFECTS
				if (_VideoEffectsEnable)
				{
					applyVideoEffects(poiFragData, poiCam, poiMesh, poiLight, poiMods);
				}
				#endif
				//endex
				
				applyAlphaOptions(poiFragData, poiMesh, poiCam, poiMods);
				
				//ifex _EnableTouchGlow==0
				#ifdef GRAIN
				applyDepthFX(poiFragData, poiCam, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _DetailEnabled==0
				#ifdef FINALPASS
				ApplyDetailColor(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _MainVertexColoringEnabled==0
				applyVertexColor(poiFragData, poiMesh);
				//endex
				
				//ifex _BackFaceEnabled!=1
				#ifdef POI_BACKFACE
				ApplyBackFaceColor(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _RGBMaskEnabled==0
				#ifdef VIGNETTE
				calculateRGBMask(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _EnableDissolve==0
				#ifdef DISTORT
				applyDissolve(poiFragData, poiMesh, poiMods, poiCam, poiLight);
				#endif
				//endex
				
				//ifex _ShadingEnabled==0
				#if defined(_LIGHTINGMODE_SHADEMAP) && defined(VIGNETTE_MASKED)
				#ifndef POI_PASS_OUTLINE
				#ifdef _LIGHTINGMODE_SHADEMAP
				applyShadeMapping(poiFragData, poiMesh, poiLight);
				#endif
				#endif
				#endif
				//endex
				
				//ifex _ShadingEnabled==0
				#ifdef VIGNETTE_MASKED
				#ifdef POI_PASS_OUTLINE
				//UNITY_BRANCH
				if (_OutlineLit)
				{
					calculateShading(poiLight, poiFragData, poiMesh, poiCam);
				}
				else
				{
					poiLight.finalLighting = 1;
				}
				#else
				calculateShading(poiLight, poiFragData, poiMesh, poiCam);
				#endif
				#else
				//endex
				poiLight.finalLighting = 1;
				poiLight.rampedLightMap = poiEdgeNonLinear(poiLight.nDotL, 0.1, .1);
				//ifex _ShadingEnabled==0
				#endif
				if (_ShadingRampedLightMapApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _ShadingRampedLightMapApplyGlobalMaskIndex - 1, _ShadingRampedLightMapApplyGlobalMaskBlendType, poiLight.rampedLightMap);
				}
				if (_ShadingRampedLightMapInverseApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _ShadingRampedLightMapInverseApplyGlobalMaskIndex - 1, _ShadingRampedLightMapInverseApplyGlobalMaskBlendType, 1 - poiLight.rampedLightMap);
				}
				
				poiLight.directLuminance = dot(poiLight.directColor, float3(0.299, 0.587, 0.114));
				poiLight.indirectLuminance = dot(poiLight.directColor, float3(0.299, 0.587, 0.114));
				poiLight.finalLuminance = dot(poiLight.finalLighting, float3(0.299, 0.587, 0.114));
				//endex
				
				#if defined(GEOM_TYPE_BRANCH) || defined(GEOM_TYPE_BRANCH_DETAIL) || defined(GEOM_TYPE_FROND) || defined(DEPTH_OF_FIELD_COC_VIEW)
				applyDecals(poiFragData, poiMesh, poiCam, poiMods, poiLight);
				#endif
				
				//ifex _EnableAniso==0
				#ifdef POI_ANISOTROPICS
				applyAnisotropics(poiFragData, poiLight, poiCam, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _MatcapEnable==0 && _Matcap2Enable==0 && _Matcap3Enable==0 && _Matcap4Enable==0
				#if defined(POI_MATCAP0) || defined(COLOR_GRADING_HDR_3D) || defined(POI_MATCAP2) || defined(POI_MATCAP3)
				applyMatcap(poiFragData, poiCam, poiMesh, poiLight, poiMods);
				#endif
				//endex
				
				//ifex _CubeMapEnabled==0
				#ifdef _CUBEMAP
				applyCubemap(poiFragData, poiCam, poiMesh, poiLight, poiMods);
				#endif
				//endex
				
				//ifex _EnableALDecal==0
				#ifdef POI_AUDIOLINK
				#ifdef POI_AL_DECAL
				ApplyAudioLinkDecal(poiMesh, poiFragData, poiMods);
				#endif
				#endif
				//endex
				
				//ifex _EnableVolumeColor==0
				#ifdef POI_AUDIOLINK
				#ifdef POI_AL_VOLUMECOLOR
				ApplyAudioLinkVolumeColor(poiMesh, poiFragData, poiMods);
				#endif
				#endif
				//endex
				
				//ifex _EnableFlipbook==0
				#ifdef _SUNDISK_HIGH_QUALITY
				applyFlipbook(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _EnableRimLighting==0
				#ifdef _GLOSSYREFLECTIONS_OFF
				#ifdef _RIMSTYLE_POIYOMI
				#if defined(PROP_RIMMASK) || !defined(OPTIMIZER_ENABLED)
				float4 rimMaskAndBias = POI2D_SAMPLER_PAN(_RimMask, _MainTex, poiUV(poiMesh.uv[_RimMaskUV], _RimMask_ST), _RimMaskPan);
				float rimMask = rimMaskAndBias[_RimMaskChannel];
				float rimBias = rimMaskAndBias.a;
				#else
				float rimMask = 1;
				float rimBias = 0;
				#endif
				
				if (_RimMaskInvert)
				{
					rimMask = 1 - rimMask;
				}
				
				#if defined(PROP_RIMTEX) || !defined(OPTIMIZER_ENABLED)
				float4 rimColor = POI2D_SAMPLER_PAN(_RimTex, _MainTex, poiUV(poiMesh.uv[_RimTexUV], _RimTex_ST), _RimTexPan);
				#else
				float4 rimColor = 1;
				#endif
				half AudioLinkRimWidthBand = 0;
				float2 AudioLinkRimWidthAdd = 0;
				half AudioLinkRimEmissionBand = 0;
				float2 AudioLinkRimEmissionAdd = 0;
				half AudioLinkRimBrightnessBand = 0;
				float2 AudioLinkRimBrightnessAdd = 0;
				#ifdef POI_AUDIOLINK
				AudioLinkRimWidthBand = _AudioLinkRimWidthBand;
				AudioLinkRimWidthAdd = _AudioLinkRimWidthAdd;
				AudioLinkRimEmissionBand = _AudioLinkRimEmissionBand;
				AudioLinkRimEmissionAdd = _AudioLinkRimEmissionAdd;
				AudioLinkRimBrightnessBand = _AudioLinkRimBrightnessBand;
				AudioLinkRimBrightnessAdd = _AudioLinkRimBrightnessAdd;
				#endif
				
				ApplyPoiyomiRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, _Is_NormalMapToRimLight, _RimLightingInvert, _RimPower, _RimStrength, _RimShadowWidth, _RimShadowToggle, _RimWidth, _RimBlendStrength, rimMask, _RimGlobalMask, _RimGlobalMaskBlendType, rimColor, _RimLightColor, _RimLightColorThemeIndex, _RimHueShiftEnabled, _RimHueShift, _RimHueShiftSpeed, _RimSharpness, _RimShadowMaskRampType, _RimShadowMaskInvert, _RimShadowMaskStrength, _RimShadowAlpha, _RimApplyGlobalMaskIndex, _RimApplyGlobalMaskBlendType, _RimBaseColorMix, _RimBrightness, _RimPoiBlendMode, AudioLinkRimWidthBand, AudioLinkRimWidthAdd, AudioLinkRimEmissionBand, AudioLinkRimEmissionAdd, AudioLinkRimBrightnessBand, AudioLinkRimBrightnessAdd, rimBias, _RimBiasIntensity, _RimApplyAlpha, _RimApplyAlphaBlend);
				#endif
				#ifdef _RIMSTYLE_UTS2
				#if defined(PROP_SET_RIMLIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float Set_RimLightMask_var = POI2D_SAMPLER_PAN(_Set_RimLightMask, _MainTex, poiUV(poiMesh.uv[_Set_RimLightMaskUV], _Set_RimLightMask_ST), _Set_RimLightMaskPan)[_Set_RimLightMaskChannel];
				#else
				float Set_RimLightMask_var = 1;
				#endif
				ApplyUTS2RimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, Set_RimLightMask_var, _RimGlobalMask, _RimGlobalMaskBlendType, _RimLightColor, _RimLightColorThemeIndex, _Is_LightColor_RimLight, _Is_NormalMapToRimLight, _RimLight_Power, _RimLight_InsideMask, _RimLight_FeatherOff, _LightDirection_MaskOn, _Tweak_LightDirection_MaskLevel, _Add_Antipodean_RimLight, _Ap_RimLightColor, _RimApColorThemeIndex, _Is_LightColor_Ap_RimLight, _Ap_RimLight_Power, _Ap_RimLight_FeatherOff, _Tweak_RimLightMaskLevel, _RimHueShiftEnabled, _RimHueShift, _RimHueShiftSpeed);
				#endif
				
				#endif
				//endex
				//ifex _EnableRim2Lighting==0
				#ifdef POI_RIM2
				#ifdef _RIM2STYLE_POIYOMI
				#if defined(PROP_RIM2MASK) || !defined(OPTIMIZER_ENABLED)
				float4 rim2MaskAndBias = POI2D_SAMPLER_PAN(_Rim2Mask, _MainTex, poiUV(poiMesh.uv[_Rim2MaskUV], _Rim2Mask_ST), _Rim2MaskPan);
				float rim2Mask = rim2MaskAndBias[_Rim2MaskChannel];
				float rim2Bias = rim2MaskAndBias.a;
				#else
				float rim2Mask = 1;
				float rim2Bias = 0;
				#endif
				
				if (_Rim2MaskInvert)
				{
					rim2Mask = 1 - rim2Mask;
				}
				
				#if defined(PROP_RIM2TEX) || !defined(OPTIMIZER_ENABLED)
				float4 rim2Color = POI2D_SAMPLER_PAN(_Rim2Tex, _MainTex, poiUV(poiMesh.uv[_Rim2TexUV], _Rim2Tex_ST), _Rim2TexPan);
				#else
				float4 rim2Color = 1;
				#endif
				half AudioLinkRim2WidthBand = 0;
				float2 AudioLinkRim2WidthAdd = 0;
				half AudioLinkRim2EmissionBand = 0;
				float2 AudioLinkRim2EmissionAdd = 0;
				half AudioLinkRim2BrightnessBand = 0;
				float2 AudioLinkRim2BrightnessAdd = 0;
				#ifdef POI_AUDIOLINK
				AudioLinkRim2WidthBand = _AudioLinkRim2WidthBand;
				AudioLinkRim2WidthAdd = _AudioLinkRim2WidthAdd;
				AudioLinkRim2EmissionBand = _AudioLinkRim2EmissionBand;
				AudioLinkRim2EmissionAdd = _AudioLinkRim2EmissionAdd;
				AudioLinkRim2BrightnessBand = _AudioLinkRim2BrightnessBand;
				AudioLinkRim2BrightnessAdd = _AudioLinkRim2BrightnessAdd;
				#endif
				ApplyPoiyomiRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, _Is_NormalMapToRim2Light, _Rim2LightingInvert, _Rim2Power, _Rim2Strength, _Rim2ShadowWidth, _Rim2ShadowToggle, _Rim2Width, _Rim2BlendStrength, rim2Mask, _Rim2GlobalMask, _Rim2GlobalMaskBlendType, rim2Color, _Rim2LightColor, _Rim2LightColorThemeIndex, _Rim2HueShiftEnabled, _Rim2HueShift, _Rim2HueShiftSpeed, _Rim2Sharpness, _Rim2ShadowMaskRampType, _Rim2ShadowMaskInvert, _Rim2ShadowMaskStrength, _Rim2ShadowAlpha, _Rim2ApplyGlobalMaskIndex, _Rim2ApplyGlobalMaskBlendType, _Rim2BaseColorMix, _Rim2Brightness, _RimPoi2BlendMode, AudioLinkRim2WidthBand, AudioLinkRim2WidthAdd, AudioLinkRim2EmissionBand, AudioLinkRim2EmissionAdd, AudioLinkRim2BrightnessBand, AudioLinkRim2BrightnessAdd, rim2Bias, _Rim2BiasIntensity, _Rim2ApplyAlpha, _Rim2ApplyAlphaBlend);
				#endif
				#ifdef _RIM2STYLE_UTS2
				#if defined(PROP_SET_RIM2LIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float Set_Rim2LightMask_var = POI2D_SAMPLER_PAN(_Set_Rim2LightMask, _MainTex, poiUV(poiMesh.uv[_Set_Rim2LightMaskUV], _Set_Rim2LightMask_ST), _Set_Rim2LightMaskPan)[_Set_Rim2LightMaskChannel];
				#else
				float Set_Rim2LightMask_var = 1;
				#endif
				ApplyUTS2RimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, Set_Rim2LightMask_var, _Rim2GlobalMask, _Rim2GlobalMaskBlendType, _Rim2LightColor, _Rim2LightColorThemeIndex, _Is_LightColor_Rim2Light, _Is_NormalMapToRim2Light, _Rim2Light_Power, _Rim2Light_InsideMask, _Rim2Light_FeatherOff, _LightDirection_MaskOn2, _Tweak_LightDirection_MaskLevel2, _Add_Antipodean_Rim2Light, _Ap_Rim2LightColor, _Rim2ApColorThemeIndex, _Is_LightColor_Ap_Rim2Light, _Ap_Rim2Light_Power, _Ap_Rim2Light_FeatherOff, _Tweak_Rim2LightMaskLevel, _Rim2HueShiftEnabled, _Rim2HueShift, _Rim2HueShiftSpeed);
				#endif
				
				#endif
				//endex
				
				//ifex _EnableDepthRimLighting==0
				#ifdef _POI_DEPTH_RIMLIGHT
				if (!IsInMirror())
				{
					ApplyDepthRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods);
				}
				#endif
				//endex
				
				//ifex _GlitterEnable==0
				#ifdef _SUNDISK_SIMPLE
				applyGlitter(poiFragData, poiMesh, poiCam, poiLight, poiMods);
				#endif
				//endex
				
				//ifex _StylizedSpecular==0
				#ifdef POI_STYLIZED_StylizedSpecular
				stylizedSpecular(poiFragData, poiCam, poiLight, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _EnablePathing==0
				#ifdef POI_PATHING
				// Only run pathing if a map exists.
				#if defined(PROP_PATHINGMAP) || !defined(OPTIMIZER_ENABLED)
				applyPathing(poiFragData, poiMesh, poiMods);
				#endif
				#endif
				//endex
				
				//ifex _EnableMirrorOptions==0
				#ifdef POI_MIRROR
				applyMirror(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _TextEnabled==0
				#ifdef EFFECT_BUMP
				ApplyTextOverlayColor(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _PoiInternalParallax==0
				#ifdef POI_INTERNALPARALLAX
				applyInternalParallax(poiFragData, poiMesh, poiCam, poiMods);
				#endif
				//endex
				
				//ifex _VoronoiEnabled!=1
				#ifdef POI_VORONOI
				ApplyVoronoi(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				UNITY_BRANCH
				if (_AlphaPremultiply)
				{
					poiFragData.baseColor *= saturate(poiFragData.alpha);
				}
				poiFragData.finalColor = poiFragData.baseColor;
				
				//ifex _LTCGIEnabled!=1
				#ifdef POI_LTCGI
				if (_LTCGI_AnimToggle)
				{
					float LTCGIsmoothness = _LTCGI_Smoothness;
					float LTCGImetalness = _LTCGI_Metallic;
					float LTCGISpecMask = 1;
					
					if (_LTCGI_UsePBR)
					{
						#ifdef MOCHIE_PBR
						float smoothness = _MochieRoughnessMultiplier;
						float metallic = _MochieMetallicMultiplier;
						float specularMask = 1;
						float reflectionMask = 1;
						
						#if defined(PROP_MOCHIEMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
						float4 PBRMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_MochieMetallicMaps, _MainTex, poiUV(poiMesh.uv[_MochieMetallicMapsUV], _MochieMetallicMaps_ST), _MochieMetallicMapsPan, _MochieMetallicMapsStochastic);
						UNITY_BRANCH
						if (_PBRSplitMaskSample)
						{
							float4 PBRSplitMask = POI2D_SAMPLER_PAN_STOCHASTIC(_MochieMetallicMaps, _MainTex, poiUV(poiMesh.uv[_MochieMetallicMasksUV], _PBRMaskScaleTiling), _MochieMetallicMasksPan.xy, _PBRSplitMaskStochastic);
							assignValueToVectorFromIndex(PBRMaps, _MochieMetallicMapsReflectionMaskChannel, PBRSplitMask[_MochieMetallicMapsReflectionMaskChannel]);
							assignValueToVectorFromIndex(PBRMaps, _MochieMetallicMapsSpecularMaskChannel, PBRSplitMask[_MochieMetallicMapsSpecularMaskChannel]);
						}
						
						if (_MochieMetallicMapsMetallicChannel < 4)
						{
							metallic *= PBRMaps[_MochieMetallicMapsMetallicChannel];
						}
						if (_MochieMetallicMapsRoughnessChannel < 4)
						{
							smoothness *= PBRMaps[_MochieMetallicMapsRoughnessChannel];
						}
						if (_MochieMetallicMapsReflectionMaskChannel < 4)
						{
							reflectionMask *= PBRMaps[_MochieMetallicMapsReflectionMaskChannel];
						}
						if (_MochieMetallicMapsSpecularMaskChannel < 4)
						{
							specularMask *= PBRMaps[_MochieMetallicMapsSpecularMaskChannel];
						}
						#endif
						LTCGIsmoothness = smoothness;
						LTCGImetalness = metallic;
						#endif
					}
					accumulator_struct acc = (accumulator_struct)0;
					
					// then we make the LTCGI_Contribution call as usual, but with slightly different params
					LTCGI_Contribution(
					acc, // our accumulator
					poiMesh.worldPos, // world position of the shaded point
					poiMesh.normals[1], // world space normal
					normalize(poiCam.worldPos - poiMesh.worldPos), // view vector to shaded point, normalized
					1.0f - LTCGIsmoothness, // roughness
					poiMesh.uv[1] // shadowmap coordinates (the normal Unity ones, they should be in sync with LTCGI maps)
					);
					acc.specular *= poiThemeColor(poiMods, _LTCGI_SpecularColor.rgb, _LTCGI_SpecularColorThemeIndex);
					acc.diffuse *= poiThemeColor(poiMods, _LTCGI_DiffuseColor.rgb, _LTCGI_DiffuseColorThemeIndex);
					
					poiLight.finalLightAdd += (acc.specular * lerp(unity_ColorSpaceDielectricSpec, poiFragData.baseColor, LTCGImetalness)) * LTCGISpecMask;
					
					poiLight.finalLighting += acc.diffuse;
					if (_LightingCapEnabled)
					{
						poiLight.finalLighting = min(poiLight.finalLighting, _LightingCap);
					}
				}
				#endif
				//endex
				
				poiFragData.finalColor = poiFragData.baseColor * poiLight.finalLighting;
				
				//ifex _SubsurfaceScattering==0
				#ifdef POI_SUBSURFACESCATTERING
				applySubsurfaceScattering(poiCam, poiLight, poiMesh, poiFragData);
				#endif
				//endex
				
				//ifex _MochieBRDF==0
				#ifdef MOCHIE_PBR
				MochieBRDF(poiFragData, poiCam, poiLight, poiMesh, poiMods);
				#endif
				//endex
				//ifex _ClearCoatBRDF==0
				#ifdef POI_CLEARCOAT
				poiClearCoat(poiFragData, poiCam, poiLight, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _EnableEnvironmentalRim==0
				#ifdef POI_ENVIRORIM
				applyEnvironmentRim(poiFragData, poiMesh, poiCam);
				#endif
				//endex
				
				//ifex _BacklightEnabled!=1
				#ifdef POI_BACKLIGHT
				ApplyBacklight(poiFragData, poiMesh, poiLight, poiCam, poiMods);
				#endif
				//endex
				
				//ifex _EnableRimLighting==0
				#ifdef _GLOSSYREFLECTIONS_OFF
				#ifdef _RIMSTYLE_LILTOON
				#if defined(PROP_RIMCOLORTEX) || !defined(OPTIMIZER_ENABLED)
				float4 rimColorTex = POI2D_SAMPLER_PAN(_RimColorTex, _MainTex, poiUV(poiMesh.uv[_RimColorTexUV], _RimColorTex_ST), _RimColorTexPan);
				#else
				float4 rimColorTex = 1;
				#endif
				ApplyLiltoonRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, _RimColor, _RimIndirColor, rimColorTex, _RimMainStrength, _RimNormalStrength, _RimDirRange, _RimIndirRange, _RimFresnelPower, _RimBackfaceMask, _RimDirStrength, _RimBorder, _RimBlur, _RimIndirBorder, _RimIndirBlur, _RimShadowMask, _RimEnableLighting, _RimVRParallaxStrength, _RimGlobalMask, _RimGlobalMaskBlendType, _RimHueShiftEnabled, _RimHueShift, _RimHueShiftSpeed, _RimBlendMode);
				#endif
				#endif
				//endex
				//ifex _EnableRim2Lighting==0
				#ifdef POI_RIM2
				#ifdef _RIM2STYLE_LILTOON
				#if defined(PROP_RIM2COLORTEX) || !defined(OPTIMIZER_ENABLED)
				float4 rim2ColorTex = POI2D_SAMPLER_PAN(_Rim2ColorTex, _MainTex, poiUV(poiMesh.uv[_Rim2ColorTexUV], _Rim2ColorTex_ST), _Rim2ColorTexPan);
				#else
				float4 rim2ColorTex = 1;
				#endif
				ApplyLiltoonRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, _Rim2Color, _Rim2IndirColor, rim2ColorTex, _Rim2MainStrength, _Rim2NormalStrength, _Rim2DirRange, _Rim2IndirRange, _Rim2FresnelPower, _Rim2BackfaceMask, _Rim2DirStrength, _Rim2Border, _Rim2Blur, _Rim2IndirBorder, _Rim2IndirBlur, _Rim2ShadowMask, _Rim2EnableLighting, _Rim2VRParallaxStrength, _Rim2GlobalMask, _Rim2GlobalMaskBlendType, _Rim2HueShiftEnabled, _Rim2HueShift, _Rim2HueShiftSpeed, _Rim2BlendMode);
				#endif
				#endif
				//endex
				
				//ifex _FXProximityColor==0
				if (_FXProximityColor)
				{
					float3 position = _FXProximityColorType ? poiMesh.worldPos : poiMesh.objectPosition;
					poiFragData.finalColor *= lerp(poiThemeColor(poiMods, _FXProximityColorMinColor.rgb, _FXProximityColorMinColorThemeIndex), poiThemeColor(poiMods, _FXProximityColorMaxColor.rgb, _FXProximityColorMaxColorThemeIndex), smoothstep(_FXProximityColorMinDistance, _FXProximityColorMaxDistance, distance(position, poiCam.worldPos)));
					
					if (_FXProximityColorBackFace)
					{
						poiFragData.finalColor = lerp(poiFragData.finalColor * _FXProximityColorMinColor.rgb, poiFragData.finalColor, saturate(poiMesh.isFrontFace));
					}
				}
				//endex
				
				//ifex _EnableEmission==0 && _EnableEmission1==0 && _EnableEmission2==0 && _EnableEmission3==0
				#if defined(_EMISSION) || defined(POI_EMISSION_1) || defined(POI_EMISSION_2) || defined(POI_EMISSION_3)
				float3 emissionBaseReplace = 0;
				#endif
				//endex
				
				//ifex _EnableEmission==0
				#ifdef _EMISSION
				emissionBaseReplace += applyEmission(poiFragData, poiMesh, poiLight, poiCam, poiMods);
				#endif
				//endex
				//ifex _EnableEmission1==0
				#ifdef POI_EMISSION_1
				emissionBaseReplace += applyEmission1(poiFragData, poiMesh, poiLight, poiCam, poiMods);
				#endif
				//endex
				//ifex _EnableEmission2==0
				#ifdef POI_EMISSION_2
				emissionBaseReplace += applyEmission2(poiFragData, poiMesh, poiLight, poiCam, poiMods);
				#endif
				//endex
				//ifex _EnableEmission3==0
				#ifdef POI_EMISSION_3
				emissionBaseReplace += applyEmission3(poiFragData, poiMesh, poiLight, poiCam, poiMods);
				#endif
				//endex
				
				//ifex _EnableEmission==0 && _EnableEmission1==0 && _EnableEmission2==0 && _EnableEmission3==0
				#if defined(_EMISSION) || defined(POI_EMISSION_1) || defined(POI_EMISSION_2) || defined(POI_EMISSION_3)
				poiFragData.finalColor.rgb = lerp(poiFragData.finalColor.rgb, saturate(emissionBaseReplace), poiMax(emissionBaseReplace));
				#endif
				//endex
				
				//UNITY_BRANCH
				if (_IgnoreFog == 0)
				{
					UNITY_APPLY_FOG(i.fogCoord, poiFragData.finalColor);
				}
				
				poiFragData.alpha = _AlphaForceOpaque ? 1 : poiFragData.alpha;
				
				//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
				ApplyAlphaToCoverage(poiFragData, poiMesh);
				//endex
				
				//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
				applyDithering(poiFragData, poiCam);
				//endex
				
				poiFragData.finalColor += poiLight.finalLightAdd;
				
				#ifdef UNITY_PASS_FORWARDBASE
				poiFragData.emission = max(poiFragData.emission * _PPEmissionMultiplier, 0);
				poiFragData.finalColor = max(poiFragData.finalColor * _PPFinalColorMultiplier, 0);
				#endif
				
				//ifex _PostProcess==0
				#ifdef POSTPROCESS
				applyPostProcessing(poiFragData, poiMesh);
				#endif
				//endex
				
				if (_Mode == POI_MODE_OPAQUE)
				{
					//poiFragData.alpha = 1;
				}
				
				clip(poiFragData.alpha - _Cutoff);
				
				if (_Mode == POI_MODE_CUTOUT && !_AlphaToCoverage)
				{
					poiFragData.alpha = 1;
				}
				
				//ifex _BSSEnabled!=1
				#ifdef POIBS_ENABLE
				poiFragData.finalColor += poiFragData.emission * poiMods.globalEmission;
				poiFragData.alpha = poiFragData.alpha * poiFragData.emission.z;
				poiFragData.emission = 0;
				
				//ifex _BSSBloomfog!=1
				#ifdef POIBS_BLOOMFOG
				float3 fogDistance = i.worldPos + - _WorldSpaceCameraPos;
				float4 fogCol = -float4(poiFragData.finalColor, 1) + tex2D(_BloomPrePassTexture, i.fogCoord.xy);
				fogCol.a = -poiFragData.alpha;
				
				#ifdef BSSBLOOMFOGTYPE_HEIGHT
				poiFragData.finalColor = poiFragData.finalColor + (((GetHeightFogIntensity(i.worldPos, _FogHeightOffset, _FogHeightScale) * GetFogIntensity(fogDistance, _FogStartOffset, _FogScale)) + 1) * fogCol.rgb);
				poiFragData.alpha = poiFragData.alpha + (((GetHeightFogIntensity(i.worldPos, _FogHeightOffset, _FogHeightScale) * GetFogIntensity(fogDistance, _FogStartOffset, _FogScale)) + 1) * fogCol.a);
				#else
				poiFragData.finalColor = poiFragData.finalColor + ((GetFogIntensity(fogDistance, _FogStartOffset, _FogScale) + 1) * fogCol.rgb);
				poiFragData.alpha = poiFragData.alpha + ((GetFogIntensity(fogDistance, _FogStartOffset, _FogScale) + 1) * fogCol.a);
				#endif
				#endif
				//endex
				#endif
				//endex
				
				return float4(poiFragData.finalColor + poiFragData.emission * poiMods.globalEmission, poiFragData.alpha) + POI_SAFE_RGB0;
			}
			
			ENDCG
		}
		
		Pass
		{
			Name "Add"
			Tags { "LightMode" = "ForwardAdd" }
			
			Stencil
			{
				Ref [_StencilRef]
				ReadMask [_StencilReadMask]
				WriteMask [_StencilWriteMask]
				//ifex _StencilType==1
				Comp [_StencilCompareFunction]
				Pass [_StencilPassOp]
				Fail [_StencilFailOp]
				ZFail [_StencilZFailOp]
				//endex
				
				//ifex _StencilType==0
				CompBack [_StencilBackCompareFunction]
				PassBack [_StencilBackPassOp]
				FailBack [_StencilBackFailOp]
				ZFailBack [_StencilBackZFailOp]
				
				CompFront [_StencilFrontCompareFunction]
				PassFront [_StencilFrontPassOp]
				FailFront [_StencilFrontFailOp]
				ZFailFront [_StencilFrontZFailOp]
				//endex
			}
			
			ZWrite Off
			Cull [_Cull]
			Cull Front
			
			Cull Back
			
			AlphaToMask [_AlphaToCoverage]
			ZTest [_ZTest]
			ColorMask [_ColorMask]
			Offset [_OffsetFactor], [_OffsetUnits]
			
			BlendOp [_AddBlendOp], [_AddBlendOpAlpha]
			Blend [_AddSrcBlend] [_AddDstBlend], [_AddSrcBlendAlpha] [_AddDstBlendAlpha]
			
			CGPROGRAM
			/*
			// Disable warnings we aren't interested in
			#if defined(UNITY_COMPILER_HLSL)
			#pragma warning(disable : 3205) // conversion of larger type to smaller
			#pragma warning(disable : 3568) // unknown pragma ignored
			#pragma warning(disable : 3571) // "pow(f,e) will not work for negative f"; however in majority of our calls to pow we know f is not negative
			#pragma warning(disable : 3206) // implicit truncation of vector type
			#endif
			*/
			#pragma target 5.0
			//ifex 0==0
			#pragma skip_optimizations d3d11
			//endex
			
			#pragma shader_feature_local _STOCHASTICMODE_DELIOT_HEITZ _STOCHASTICMODE_HEXTILE _STOCHASTICMODE_NONE
			
			//ifex _MainColorAdjustToggle==0
			#pragma shader_feature COLOR_GRADING_HDR
			//endex
			
			//#pragma shader_feature KEYWORD
			
			#pragma skip_variants LIGHTMAP_ON DYNAMICLIGHTMAP_ON LIGHTMAP_SHADOW_MIXING SHADOWS_SHADOWMASK DIRLIGHTMAP_COMBINED _MIXED_LIGHTING_SUBTRACTIVE
			#pragma skip_variants DECALS_OFF DECALS_3RT DECALS_4RT DECAL_SURFACE_GRADIENT _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3
			#pragma skip_variants _ADDITIONAL_LIGHT_SHADOWS
			#pragma skip_variants PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2
			#pragma skip_variants _SCREEN_SPACE_OCCLUSION
			
			//ifex _GlobalMaskTexturesEnable==0
			#pragma shader_feature_local POI_GLOBALMASK_TEXTURES
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#pragma shader_feature_local POI_UDIMDISCARD
			//endex
			
			//ifex _EnableDistortion==0
			#pragma shader_feature USER_LUT
			//endex
			
			//ifex _PoiParallax==0
			#pragma shader_feature_local POI_PARALLAX
			//endex
			
			//ifex _EnableAudioLink==0
			#pragma shader_feature_local POI_AUDIOLINK
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#pragma shader_feature_local POI_BLACKLIGHTMASKING
			//endex
			
			//ifex _DetailEnabled==0
			#pragma shader_feature FINALPASS
			//endex
			
			//ifex _VertexManipulationsEnabled==0
			#pragma shader_feature AUTO_EXPOSURE
			//endex
			
			//ifex _VertexGlitchingEnabled==0
			#pragma shader_feature_local POI_VERTEX_GLITCHING
			#pragma shader_feature_local POI_VERTEX_GLITCHING_TEXTURE
			//endex
			
			//ifex _EnableDepthBulge==0
			#pragma shader_feature_local POI_DEPTHBULGE
			//endex
			
			//ifex _BackFaceEnabled!=1
			#pragma shader_feature_local POI_BACKFACE
			//endex
			
			//ifex _RGBMaskEnabled==0
			#pragma shader_feature VIGNETTE
			#pragma shader_feature GEOM_TYPE_MESH
			//endex
			
			//ifex _LTCGIEnabled!=1
			#pragma shader_feature_local POI_LTCGI
			//endex
			
			//ifex _ShadingEnabled==0
			#pragma shader_feature_local VIGNETTE_MASKED
			#pragma shader_feature_local _LIGHTINGMODE_TEXTURERAMP _LIGHTINGMODE_MULTILAYER_MATH _LIGHTINGMODE_SHADEMAP _LIGHTINGMODE_REALISTIC _LIGHTINGMODE_WRAPPED _LIGHTINGMODE_SKIN _LIGHTINGMODE_FLAT _LIGHTINGMODE_CLOTH _LIGHTINGMODE_SDF
			//endex
			
			//ifex _DecalEnabled==0
			#pragma shader_feature GEOM_TYPE_BRANCH
			//endex
			//ifex _DecalEnabled1==0
			#pragma shader_feature GEOM_TYPE_BRANCH_DETAIL
			//endex
			//ifex _DecalEnabled2==0
			#pragma shader_feature GEOM_TYPE_FROND
			//endex
			//ifex _DecalEnabled3==0
			#pragma shader_feature DEPTH_OF_FIELD_COC_VIEW
			//endex
			
			//ifex _EnableDissolve==0
			#pragma shader_feature DISTORT
			//endex
			
			//ifex _EnableAniso==0
			#pragma shader_feature_local POI_ANISOTROPICS
			//endex
			
			//ifex _MatcapEnable==0
			#pragma shader_feature_local POI_MATCAP0
			#pragma shader_feature_local POI_MATCAP0_CUSTOM_NORMAL
			//endex
			//ifex _Matcap2Enable==0
			#pragma shader_feature COLOR_GRADING_HDR_3D
			#pragma shader_feature_local POI_MATCAP1_CUSTOM_NORMAL
			//endex
			//ifex _Matcap3Enable==0
			#pragma shader_feature_local POI_MATCAP2
			#pragma shader_feature_local POI_MATCAP2_CUSTOM_NORMAL
			//endex
			//ifex _Matcap4Enable==0
			#pragma shader_feature_local POI_MATCAP3
			#pragma shader_feature_local POI_MATCAP3_CUSTOM_NORMAL
			//endex
			
			//ifex _CubeMapEnabled==0
			#pragma shader_feature_local _CUBEMAP
			//endex
			
			//ifex _EnableALDecal==0
			#pragma shader_feature_local POI_AL_DECAL
			//endex
			
			//ifex _EnableVolumeColor==0
			#pragma shader_feature_local POI_AL_VOLUMECOLOR
			//endex
			
			//ifex _EnableFlipbook==0
			#pragma shader_feature _SUNDISK_HIGH_QUALITY
			//endex
			
			//ifex _EnableEmission==0
			#pragma shader_feature _EMISSION
			//endex
			//ifex _EnableEmission1==0
			#pragma shader_feature_local POI_EMISSION_1
			//endex
			//ifex _EnableEmission2==0
			#pragma shader_feature_local POI_EMISSION_2
			//endex
			//ifex _EnableEmission3==0
			#pragma shader_feature_local POI_EMISSION_3
			//endex
			
			//ifex _EnableRimLighting==0
			#pragma shader_feature_local _GLOSSYREFLECTIONS_OFF
			#pragma shader_feature_local _RIMSTYLE_POIYOMI _RIMSTYLE_UTS2 _RIMSTYLE_LILTOON
			//endex
			//ifex _EnableRim2Lighting==0
			#pragma shader_feature_local POI_RIM2
			#pragma shader_feature_local _RIM2STYLE_POIYOMI _RIM2STYLE_UTS2 _RIM2STYLE_LILTOON
			//endex
			
			//ifex _EnableDepthRimLighting==0
			#pragma shader_feature_local _POI_DEPTH_RIMLIGHT
			//endex
			
			//ifex _GlitterEnable==0
			#pragma shader_feature _SUNDISK_SIMPLE
			//endex
			
			//ifex _SubsurfaceScattering==0
			#pragma shader_feature_local POI_SUBSURFACESCATTERING
			//endex
			
			//ifex _MochieBRDF==0
			#pragma shader_feature_local MOCHIE_PBR
			//endex
			//ifex _ClearCoatBRDF==0
			#pragma shader_feature_local POI_CLEARCOAT
			//endex
			
			//ifex _EnableEnvironmentalRim==0
			#pragma shader_feature_local POI_ENVIRORIM
			//endex
			
			//ifex _StylizedSpecular==0
			#pragma shader_feature_local POI_STYLIZED_StylizedSpecular
			//endex
			
			//ifex _EnablePathing==0
			#pragma shader_feature_local POI_PATHING
			//endex
			
			//ifex _EnableMirrorOptions==0
			#pragma shader_feature_local POI_MIRROR
			//endex
			
			//ifex _EnableTouchGlow==0
			#pragma shader_feature GRAIN
			//endex
			
			//ifex _TextEnabled==0
			#pragma shader_feature EFFECT_BUMP
			//endex
			
			//ifex _PostProcess==0
			#pragma shader_feature_local POSTPROCESS
			//endex
			
			//ifex _PoiInternalParallax==0
			#pragma shader_feature_local POI_INTERNALPARALLAX
			//endex
			
			//ifex _NormalCorrect==0
			#pragma shader_feature_local POI_NORMALCORRECT
			//endex
			
			//ifex _VideoEffectsEnable==0
			#pragma shader_feature_local POI_VIDEO_EFFECTS
			//endex
			
			//ifex _BacklightEnabled!=1
			#pragma shader_feature_local POI_BACKLIGHT
			//endex
			
			//ifex _BSSEnabled!=1
			#pragma shader_feature_local POIBS_ENABLE
			//ifex _BSSBloomfog!=1
			#pragma shader_feature_local POIBS_BLOOMFOG
			#pragma shader_feature_local BSSBLOOMFOGTYPE_HEIGHT
			//endex
			//endex
			
			//ifex _VoronoiEnabled!=1
			#pragma shader_feature_local POI_VORONOI
			//endex
			
			#pragma multi_compile_fwdadd_fullshadows
			#pragma multi_compile_instancing
			#pragma multi_compile_fog
			#define POI_PASS_ADD
			
			// UNITY Includes
			#include "UnityCG.cginc"
			#include "UnityStandardUtils.cginc"
			#include "AutoLight.cginc"
			#include "UnityLightingCommon.cginc"
			#include "UnityPBSLighting.cginc"
			#ifdef POI_PASS_META
			#include "UnityMetaPass.cginc"
			#endif
			#pragma vertex vert
			
			#pragma fragment frag
			
			#define DielectricSpec float4(0.04, 0.04, 0.04, 1.0 - 0.04)
			#define PI float(3.14159265359)
			#define Epsilon float(1e-10)
			
			#define POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, samplertex, coord, dx, dy) tex.SampleGrad(sampler##samplertex, coord, dx, dy)
			#define POI2D_SAMPLE_TEX2D_SAMPLERGRADD(tex, samp, uv, pan, dx, dy) tex.SampleGrad(samp, POI_PAN_UV(uv, pan), dx, dy)
			
			#define POI_PAN_UV(uv, pan) (uv + _Time.x * pan)
			#define POI2D_SAMPLER_PAN(tex, texSampler, uv, pan) (UNITY_SAMPLE_TEX2D_SAMPLER(tex, texSampler, POI_PAN_UV(uv, pan)))
			#define POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy) (POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, texSampler, POI_PAN_UV(uv, pan), dx, dy))
			#define POI2D_SAMPLER(tex, texSampler, uv) (UNITY_SAMPLE_TEX2D_SAMPLER(tex, texSampler, uv))
			#define POI_SAMPLE_1D_X(tex, samp, uv) tex.Sample(samp, float2(uv, 0.5))
			#define POI2D_SAMPLER_GRAD(tex, texSampler, uv, dx, dy) (POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, texSampler, uv, dx, dy))
			#define POI2D_SAMPLER_GRADD(tex, texSampler, uv, dx, dy) tex.SampleGrad(texSampler, uv, dx, dy)
			#define POI2D_PAN(tex, uv, pan) (tex2D(tex, POI_PAN_UV(uv, pan)))
			#define POI2D(tex, uv) (tex2D(tex, uv))
			#define POI_SAMPLE_TEX2D(tex, uv) (UNITY_SAMPLE_TEX2D(tex, uv))
			#define POI_SAMPLE_TEX2D_PAN(tex, uv, pan) (UNITY_SAMPLE_TEX2D(tex, POI_PAN_UV(uv, pan)))
			#define POI_SAMPLE_CUBE_LOD(tex, samp, uv, lod) texCUBElod(tex, float4(uv, 0, lod))
			
			#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
			#define POI_SAMPLE_SCREEN(tex, samp, uv)          tex.Sample(samp, float3(uv, unity_StereoEyeIndex))
			#else
			#define POI_SAMPLE_SCREEN(tex, samp, uv)          tex.Sample(samp, uv)
			#endif
			
			// When using, properties won't properly lock at optimize time; needs macro evaluation implemented
			// #define POI2D_MAINTEX_SAMPLER_PAN_INLINED(tex, poiMesh) (POI2D_SAMPLER_PAN(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan))
			
			#define POI_SAFE_RGB0 float4(mainTexture.rgb * .0001, 0)
			#define POI_SAFE_RGB1 float4(mainTexture.rgb * .0001, 1)
			#define POI_SAFE_RGBA mainTexture
			
			#if defined(UNITY_COMPILER_HLSL)
			#define PoiInitStruct(type, name) name = (type)0;
			#else
			#define PoiInitStruct(type, name)
			#endif
			
			#define POI_ERROR(poiMesh, gridSize) lerp(float3(1, 0, 1), float3(0, 0, 0), fmod(floor((poiMesh.worldPos.x) * gridSize) + floor((poiMesh.worldPos.y) * gridSize) + floor((poiMesh.worldPos.z) * gridSize), 2) == 0)
			#define POI_NAN (asfloat(-1))
			
			#define POI_MODE_OPAQUE 0
			#define POI_MODE_CUTOUT 1
			#define POI_MODE_FADE 2
			#define POI_MODE_TRANSPARENT 3
			#define POI_MODE_ADDITIVE 4
			#define POI_MODE_SOFTADDITIVE 5
			#define POI_MODE_MULTIPLICATIVE 6
			#define POI_MODE_2XMULTIPLICATIVE 7
			#define POI_MODE_TRANSCLIPPING 9
			
			/*
			Texture2D ;
			float4 _ST;
			float2 Pan;
			float UV;
			float Stochastic;
			
			[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos XZ, 5, Polar UV, 6, Distorted UV, 7 )]
			*/
			
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			// Map of where features in AudioLink are.
			#define ALPASS_DFT                      uint2(0, 4)   //Size: 128, 2
			#define ALPASS_WAVEFORM                 uint2(0, 6)   //Size: 128, 16
			#define ALPASS_AUDIOLINK                uint2(0, 0)   //Size: 128, 4
			#define ALPASS_AUDIOBASS                uint2(0, 0)   //Size: 128, 1
			#define ALPASS_AUDIOLOWMIDS             uint2(0, 1)   //Size: 128, 1
			#define ALPASS_AUDIOHIGHMIDS            uint2(0, 2)   //Size: 128, 1
			#define ALPASS_AUDIOTREBLE              uint2(0, 3)   //Size: 128, 1
			#define ALPASS_AUDIOLINKHISTORY         uint2(1, 0)   //Size: 127, 4
			#define ALPASS_GENERALVU                uint2(0, 22)  //Size: 12, 1
			#define ALPASS_CCINTERNAL               uint2(12, 22) //Size: 12, 2
			#define ALPASS_CCCOLORS                 uint2(25, 22) //Size: 11, 1
			#define ALPASS_CCSTRIP                  uint2(0, 24)  //Size: 128, 1
			#define ALPASS_CCLIGHTS                 uint2(0, 25)  //Size: 128, 2
			#define ALPASS_AUTOCORRELATOR           uint2(0, 27)  //Size: 128, 1
			#define ALPASS_GENERALVU_INSTANCE_TIME  uint2(2, 22)
			#define ALPASS_GENERALVU_LOCAL_TIME     uint2(3, 22)
			#define ALPASS_GENERALVU_NETWORK_TIME   uint2(4, 22)
			#define ALPASS_GENERALVU_PLAYERINFO     uint2(6, 22)
			// Added in version 2.5
			#define ALPASS_FILTEREDAUDIOLINK        uint2(0, 28)  //Size: 16, 4
			// Added in version 2.6
			#define ALPASS_CHRONOTENSITY            uint2(16, 28) //Size: 8, 4
			#define ALPASS_THEME_COLOR0             uint2(0, 23)
			#define ALPASS_THEME_COLOR1             uint2(1, 23)
			#define ALPASS_THEME_COLOR2             uint2(2, 23)
			#define ALPASS_THEME_COLOR3             uint2(3, 23)
			#define ALPASS_FILTEREDVU               uint2(24, 28) //Size: 4, 4
			#define ALPASS_FILTEREDVU_INTENSITY     uint2(24, 28) //Size: 4, 1
			#define ALPASS_FILTEREDVU_MARKER        uint2(24, 29) //Size: 4, 1
			
			// Some basic constants to use (Note, these should be compatible with
			// future version of AudioLink, but may change.
			#define AUDIOLINK_SAMPHIST              3069        // Internal use for algos, do not change.
			#define AUDIOLINK_SAMPLEDATA24          2046
			#define AUDIOLINK_EXPBINS               24
			#define AUDIOLINK_EXPOCT                10
			#define AUDIOLINK_ETOTALBINS (AUDIOLINK_EXPBINS * AUDIOLINK_EXPOCT)
			#define AUDIOLINK_WIDTH                 128
			#define AUDIOLINK_SPS                   48000       // Samples per second
			#define AUDIOLINK_ROOTNOTE              0
			#define AUDIOLINK_4BAND_FREQFLOOR       0.123
			#define AUDIOLINK_4BAND_FREQCEILING     1
			#define AUDIOLINK_BOTTOM_FREQUENCY      13.75
			#define AUDIOLINK_BASE_AMPLITUDE        2.5
			#define AUDIOLINK_DELAY_COEFFICIENT_MIN 0.3
			#define AUDIOLINK_DELAY_COEFFICIENT_MAX 0.9
			#define AUDIOLINK_DFT_Q                 4.0
			#define AUDIOLINK_TREBLE_CORRECTION     5.0
			
			// ColorChord constants
			#define COLORCHORD_EMAXBIN              192
			#define COLORCHORD_IIR_DECAY_1          0.90
			#define COLORCHORD_IIR_DECAY_2          0.85
			#define COLORCHORD_CONSTANT_DECAY_1     0.01
			#define COLORCHORD_CONSTANT_DECAY_2     0.0
			#define COLORCHORD_NOTE_CLOSEST         3.0
			#define COLORCHORD_NEW_NOTE_GAIN        8.0
			#define COLORCHORD_MAX_NOTES            10
			
			uniform float4               _AudioTexture_TexelSize;
			
			#ifdef SHADER_TARGET_SURFACE_ANALYSIS
			#define AUDIOLINK_STANDARD_INDEXING
			#endif
			
			// Mechanism to index into texture.
			#ifdef AUDIOLINK_STANDARD_INDEXING
			sampler2D _AudioTexture;
			#define AudioLinkData(xycoord) tex2Dlod(_AudioTexture, float4(uint2(xycoord) * _AudioTexture_TexelSize.xy, 0, 0))
			#else
			uniform Texture2D<float4> _AudioTexture;
			SamplerState sampler_AudioTexture;
			#define AudioLinkData(xycoord) _AudioTexture[uint2(xycoord)]
			#endif
			uniform sampler2D _Stored;
			uniform float4 _Stored_TexelSize;
			#endif
			//endex
			
			float _GrabMode;
			float _Mode;
			
			float _StochasticDeliotHeitzDensity;
			float _StochasticHexGridDensity;
			float _StochasticHexRotationStrength;
			float _StochasticHexFallOffContrast;
			float _StochasticHexFallOffPower;
			
			#if defined(PROP_LIGHTINGAOMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _LightingAOMaps;
			#endif
			float4 _LightingAOMaps_ST;
			float2 _LightingAOMapsPan;
			float _LightingAOMapsUV;
			float _LightDataAOStrengthR;
			float _LightDataAOStrengthG;
			float _LightDataAOStrengthB;
			float _LightDataAOStrengthA;
			float _LightDataAOGlobalMaskR;
			float _LightDataAOGlobalMaskBlendTypeR;
			
			#if defined(PROP_LIGHTINGDETAILSHADOWMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _LightingDetailShadowMaps;
			#endif
			float4 _LightingDetailShadowMaps_ST;
			float2 _LightingDetailShadowMapsPan;
			float _LightingDetailShadowMapsUV;
			float _LightingDetailShadowStrengthR;
			float _LightingDetailShadowStrengthG;
			float _LightingDetailShadowStrengthB;
			float _LightingDetailShadowStrengthA;
			float _LightingAddDetailShadowStrengthR;
			float _LightingAddDetailShadowStrengthG;
			float _LightingAddDetailShadowStrengthB;
			float _LightingAddDetailShadowStrengthA;
			float _LightDataDetailShadowGlobalMaskR;
			float _LightDataDetailShadowGlobalMaskBlendTypeR;
			
			#if defined(PROP_LIGHTINGSHADOWMASKS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _LightingShadowMasks;
			#endif
			float4 _LightingShadowMasks_ST;
			float2 _LightingShadowMasksPan;
			float _LightingShadowMasksUV;
			float _LightingShadowMaskStrengthR;
			float _LightingShadowMaskStrengthG;
			float _LightingShadowMaskStrengthB;
			float _LightingShadowMaskStrengthA;
			float _LightDataShadowMaskGlobalMaskR;
			float _LightDataShadowMaskGlobalMaskBlendTypeR;
			
			// Lighting Data
			float _Unlit_Intensity;
			float _LightingColorMode;
			float _LightingMapMode;
			float _LightingDirectionMode;
			float3 _LightngForcedDirection;
			float _LightingViewDirOffsetPitch;
			float _LightingViewDirOffsetYaw;
			float _LightingIndirectUsesNormals;
			float _LightingCapEnabled;
			float _LightingCap;
			float _LightingForceColorEnabled;
			float3 _LightingForcedColor;
			float _LightingForcedColorThemeIndex;
			float _LightingCastedShadows;
			float _LightingMonochromatic;
			float _LightingMinLightBrightness;
			// Additive Lighting Data
			float _LightingAdditiveEnable;
			float _LightingAdditiveLimited;
			float _LightingAdditiveLimit;
			float _LightingAdditiveCastedShadows;
			float _LightingAdditiveMonochromatic;
			float _LightingAdditivePassthrough;
			float _DisableDirectionalInAdd;
			float _LightingVertexLightingEnabled;
			float _LightingMirrorVertexLightingEnabled;
			// Lighting Data Debug
			float _LightDataDebugEnabled;
			float _LightingDebugVisualize;
			
			float _IgnoreFog;
			float _RenderingReduceClipDistance;
			int _FlipBackfaceNormals;
			float _AddBlendOp;
			float _Cull;
			
			float4 _Color;
			float _ColorThemeIndex;
			UNITY_DECLARE_TEX2D(_MainTex);
			UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
			float _MainPixelMode;
			float4 _MainTex_ST;
			float2 _MainTexPan;
			float _MainTexUV;
			float4 _MainTex_TexelSize;
			float _MainTexStochastic;
			#if defined(PROP_BUMPMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BumpMap;
			#endif
			float4 _BumpMap_ST;
			float2 _BumpMapPan;
			float _BumpMapUV;
			float _BumpScale;
			float _BumpMapStochastic;
			#if defined(PROP_ALPHAMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AlphaMask;
			float4 _AlphaMask_ST;
			float2 _AlphaMaskPan;
			float _AlphaMaskUV;
			float _AlphaMaskInvert;
			float _MainAlphaMaskMode;
			float _AlphaMaskScale;
			float _AlphaMaskValue;
			#endif
			float _Cutoff;
			//ifex _MainColorAdjustToggle==0
			#ifdef COLOR_GRADING_HDR
			float _MainColorAdjustToggle;
			#if defined(PROP_MAINCOLORADJUSTTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MainColorAdjustTexture;
			#endif
			float4 _MainColorAdjustTexture_ST;
			float2 _MainColorAdjustTexturePan;
			float _MainColorAdjustTextureUV;
			float _MainHueShiftToggle;
			float _MainHueShiftReplace;
			float _MainHueShift;
			float _MainHueShiftSpeed;
			float _Saturation;
			float _MainBrightness;
			
			float _MainHueALCTEnabled;
			float _MainALHueShiftBand;
			float _MainALHueShiftCTIndex;
			float _MainHueALMotionSpeed;
			
			float _MainHueGlobalMask;
			float _MainHueGlobalMaskBlendType;
			float _MainSaturationGlobalMask;
			float _MainSaturationGlobalMaskBlendType;
			float _MainBrightnessGlobalMask;
			float _MainBrightnessGlobalMaskBlendType;
			
			#if defined(PROP_MAINGRADATIONTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MainGradationTex;
			#endif
			float _ColorGradingToggle;
			float _MainGradationStrength;
			#endif
			//endex
			
			SamplerState sampler_linear_clamp;
			SamplerState sampler_linear_repeat;
			SamplerState sampler_trilinear_repeat;
			
			float _AlphaForceOpaque;
			float _AlphaMod;
			float _AlphaPremultiply;
			float _AlphaBoostFA;
			//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
			float _AlphaToCoverage;
			float _AlphaSharpenedA2C;
			float _AlphaMipScale;
			//endex
			
			//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
			float _AlphaDithering;
			float _AlphaDitherGradient;
			float _AlphaDitherBias;
			//endex
			
			//ifex _AlphaDistanceFade==0 && isNotAnimated(_AlphaDistanceFade)
			float _AlphaDistanceFade;
			float _AlphaDistanceFadeType;
			float _AlphaDistanceFadeMinAlpha;
			float _AlphaDistanceFadeMaxAlpha;
			float _AlphaDistanceFadeMin;
			float _AlphaDistanceFadeMax;
			float _AlphaDistanceFadeGlobalMask;
			float _AlphaDistanceFadeGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaFresnel==0 && isNotAnimated(_AlphaFresnel)
			float _AlphaFresnel;
			float _AlphaFresnelAlpha;
			float _AlphaFresnelSharpness;
			float _AlphaFresnelWidth;
			float _AlphaFresnelInvert;
			float _AlphaFresnelGlobalMask;
			float _AlphaFresnelGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaAngular==0 && isNotAnimated(_AlphaAngular)
			float _AlphaAngular;
			float _AngleType;
			float _AngleCompareTo;
			float3 _AngleForwardDirection;
			float _CameraAngleMin;
			float _CameraAngleMax;
			float _ModelAngleMin;
			float _ModelAngleMax;
			float _AngleMinAlpha;
			float _AlphaAngularGlobalMask;
			float _AlphaAngularGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaAudioLinkEnabled==0 && isNotAnimated(_AlphaAudioLinkEnabled)
			float _AlphaAudioLinkEnabled;
			float2 _AlphaAudioLinkAddRange;
			float _AlphaAudioLinkAddBand;
			//endex
			
			float _AlphaGlobalMask;
			float _AlphaGlobalMaskBlendType;
			
			float4 _GlobalThemeColor0;
			float4 _GlobalThemeColor1;
			float4 _GlobalThemeColor2;
			float4 _GlobalThemeColor3;
			float _GlobalThemeHue0;
			float _GlobalThemeHue1;
			float _GlobalThemeHue2;
			float _GlobalThemeHue3;
			float _GlobalThemeHueSpeed0;
			float _GlobalThemeHueSpeed1;
			float _GlobalThemeHueSpeed2;
			float _GlobalThemeHueSpeed3;
			float _GlobalThemeSaturation0;
			float _GlobalThemeSaturation1;
			float _GlobalThemeSaturation2;
			float _GlobalThemeSaturation3;
			float _GlobalThemeValue0;
			float _GlobalThemeValue1;
			float _GlobalThemeValue2;
			float _GlobalThemeValue3;
			
			//ifex _GlobalMaskTexturesEnable==0
			#ifdef POI_GLOBALMASK_TEXTURES
			#if defined(PROP_GLOBALMASKTEXTURE0) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture0;
			#endif
			float4 _GlobalMaskTexture0_ST;
			float2 _GlobalMaskTexture0Pan;
			float _GlobalMaskTexture0UV;
			int _GlobalMaskTexture0Split;
			float4 _GlobalMaskTexture0SplitTilingOffset_G;
			float4 _GlobalMaskTexture0SplitPan_G;
			float4 _GlobalMaskTexture0SplitTilingOffset_B;
			float4 _GlobalMaskTexture0SplitPan_B;
			float4 _GlobalMaskTexture0SplitTilingOffset_A;
			float4 _GlobalMaskTexture0SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture1;
			#endif
			float4 _GlobalMaskTexture1_ST;
			float2 _GlobalMaskTexture1Pan;
			float _GlobalMaskTexture1UV;
			int _GlobalMaskTexture1Split;
			float4 _GlobalMaskTexture1SplitTilingOffset_G;
			float4 _GlobalMaskTexture1SplitPan_G;
			float4 _GlobalMaskTexture1SplitTilingOffset_B;
			float4 _GlobalMaskTexture1SplitPan_B;
			float4 _GlobalMaskTexture1SplitTilingOffset_A;
			float4 _GlobalMaskTexture1SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture2;
			#endif
			float4 _GlobalMaskTexture2_ST;
			float2 _GlobalMaskTexture2Pan;
			float _GlobalMaskTexture2UV;
			int _GlobalMaskTexture2Split;
			float4 _GlobalMaskTexture2SplitTilingOffset_G;
			float4 _GlobalMaskTexture2SplitPan_G;
			float4 _GlobalMaskTexture2SplitTilingOffset_B;
			float4 _GlobalMaskTexture2SplitPan_B;
			float4 _GlobalMaskTexture2SplitTilingOffset_A;
			float4 _GlobalMaskTexture2SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE3) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture3;
			#endif
			float4 _GlobalMaskTexture3_ST;
			float2 _GlobalMaskTexture3Pan;
			float _GlobalMaskTexture3UV;
			int _GlobalMaskTexture3Split;
			float4 _GlobalMaskTexture3SplitTilingOffset_G;
			float4 _GlobalMaskTexture3SplitPan_G;
			float4 _GlobalMaskTexture3SplitTilingOffset_B;
			float4 _GlobalMaskTexture3SplitPan_B;
			float4 _GlobalMaskTexture3SplitTilingOffset_A;
			float4 _GlobalMaskTexture3SplitPan_A;
			#endif
			//endex
			//ifex _GlobalMaskOptionsEnable==0
			float _GlobalMaskOptionsEnable;
			int _GlobalMaskOptionsType;
			
			//ifex _GlobalMaskOptionsType!=0
			float _GlobalMaskSlider_0;
			float _GlobalMaskSlider_1;
			float _GlobalMaskSlider_2;
			float _GlobalMaskSlider_3;
			float _GlobalMaskSlider_4;
			float _GlobalMaskSlider_5;
			float _GlobalMaskSlider_6;
			float _GlobalMaskSlider_7;
			float _GlobalMaskSlider_8;
			float _GlobalMaskSlider_9;
			float _GlobalMaskSlider_10;
			float _GlobalMaskSlider_11;
			float _GlobalMaskSlider_12;
			float _GlobalMaskSlider_13;
			float _GlobalMaskSlider_14;
			float _GlobalMaskSlider_15;
			//endex
			
			//ifex _GlobalMaskOptionsType!=1
			float2 _GlobalMaskMinMaxSlider_0;
			float2 _GlobalMaskMinMaxSlider_1;
			float2 _GlobalMaskMinMaxSlider_2;
			float2 _GlobalMaskMinMaxSlider_3;
			float2 _GlobalMaskMinMaxSlider_4;
			float2 _GlobalMaskMinMaxSlider_5;
			float2 _GlobalMaskMinMaxSlider_6;
			float2 _GlobalMaskMinMaxSlider_7;
			float2 _GlobalMaskMinMaxSlider_8;
			float2 _GlobalMaskMinMaxSlider_9;
			float2 _GlobalMaskMinMaxSlider_10;
			float2 _GlobalMaskMinMaxSlider_11;
			float2 _GlobalMaskMinMaxSlider_12;
			float2 _GlobalMaskMinMaxSlider_13;
			float2 _GlobalMaskMinMaxSlider_14;
			float2 _GlobalMaskMinMaxSlider_15;
			//endex
			
			//ifex _GlobalMaskOptionsType!=2
			int _GlobalMaskToggleOn_0;
			int _GlobalMaskToggleOff_0;
			int _GlobalMaskToggleOn_1;
			int _GlobalMaskToggleOff_1;
			int _GlobalMaskToggleOn_2;
			int _GlobalMaskToggleOff_2;
			int _GlobalMaskToggleOn_3;
			int _GlobalMaskToggleOff_3;
			int _GlobalMaskToggleOn_4;
			int _GlobalMaskToggleOff_4;
			int _GlobalMaskToggleOn_5;
			int _GlobalMaskToggleOff_5;
			int _GlobalMaskToggleOn_6;
			int _GlobalMaskToggleOff_6;
			int _GlobalMaskToggleOn_7;
			int _GlobalMaskToggleOff_7;
			int _GlobalMaskToggleOn_8;
			int _GlobalMaskToggleOff_8;
			int _GlobalMaskToggleOn_9;
			int _GlobalMaskToggleOff_9;
			int _GlobalMaskToggleOn_10;
			int _GlobalMaskToggleOff_10;
			int _GlobalMaskToggleOn_11;
			int _GlobalMaskToggleOff_11;
			int _GlobalMaskToggleOn_12;
			int _GlobalMaskToggleOff_12;
			int _GlobalMaskToggleOn_13;
			int _GlobalMaskToggleOff_13;
			int _GlobalMaskToggleOn_14;
			int _GlobalMaskToggleOff_14;
			int _GlobalMaskToggleOn_15;
			int _GlobalMaskToggleOff_15;
			//endex
			//endex
			//ifex _GlobalMaskModifiersBackfaceEnable==0
			float _GlobalMaskModifiersBackfaceEnable;
			float _GlobalMaskBackface_0;
			float _GlobalMaskBackface_1;
			float _GlobalMaskBackface_2;
			float _GlobalMaskBackface_3;
			float _GlobalMaskBackface_4;
			float _GlobalMaskBackface_5;
			float _GlobalMaskBackface_6;
			float _GlobalMaskBackface_7;
			float _GlobalMaskBackface_8;
			float _GlobalMaskBackface_9;
			float _GlobalMaskBackface_10;
			float _GlobalMaskBackface_11;
			float _GlobalMaskBackface_12;
			float _GlobalMaskBackface_13;
			float _GlobalMaskBackface_14;
			float _GlobalMaskBackface_15;
			//endex
			
			//ifex _GlobalMaskModifiersMirrorEnable==0
			float _GlobalMaskModifiersMirrorEnable;
			float _GlobalMaskMirrorVisibilityMode;
			float _GlobalMaskMirror_0;
			float _GlobalMaskMirror_1;
			float _GlobalMaskMirror_2;
			float _GlobalMaskMirror_3;
			float _GlobalMaskMirror_4;
			float _GlobalMaskMirror_5;
			float _GlobalMaskMirror_6;
			float _GlobalMaskMirror_7;
			float _GlobalMaskMirror_8;
			float _GlobalMaskMirror_9;
			float _GlobalMaskMirror_10;
			float _GlobalMaskMirror_11;
			float _GlobalMaskMirror_12;
			float _GlobalMaskMirror_13;
			float _GlobalMaskMirror_14;
			float _GlobalMaskMirror_15;
			//endex
			
			//ifex _GlobalMaskModifiersCameraEnable==0
			float _GlobalMaskModifiersCameraEnable;
			float _GlobalMaskCamera_0;
			float _GlobalMaskCamera_1;
			float _GlobalMaskCamera_2;
			float _GlobalMaskCamera_3;
			float _GlobalMaskCamera_4;
			float _GlobalMaskCamera_5;
			float _GlobalMaskCamera_6;
			float _GlobalMaskCamera_7;
			float _GlobalMaskCamera_8;
			float _GlobalMaskCamera_9;
			float _GlobalMaskCamera_10;
			float _GlobalMaskCamera_11;
			float _GlobalMaskCamera_12;
			float _GlobalMaskCamera_13;
			float _GlobalMaskCamera_14;
			float _GlobalMaskCamera_15;
			//endex
			
			//ifex _GlobalMaskModifiersDistanceEnable==0
			int _GlobalMaskModifiersDistanceEnable;
			
			//ifex _GlobalMaskDistanceEnable_0==0
			int _GlobalMaskDistanceEnable_0;
			int _GlobalMaskDistanceType_0;
			float _GlobalMaskDistanceMin_0;
			float _GlobalMaskDistanceMax_0;
			float _GlobalMaskDistanceMinAlpha_0;
			float _GlobalMaskDistanceMaxAlpha_0;
			int _GlobalMaskDistanceBlendType_0;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_1==0
			int _GlobalMaskDistanceEnable_1;
			int _GlobalMaskDistanceType_1;
			float _GlobalMaskDistanceMin_1;
			float _GlobalMaskDistanceMax_1;
			float _GlobalMaskDistanceMinAlpha_1;
			float _GlobalMaskDistanceMaxAlpha_1;
			int _GlobalMaskDistanceBlendType_1;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_2==0
			int _GlobalMaskDistanceEnable_2;
			int _GlobalMaskDistanceType_2;
			float _GlobalMaskDistanceMin_2;
			float _GlobalMaskDistanceMax_2;
			float _GlobalMaskDistanceMinAlpha_2;
			float _GlobalMaskDistanceMaxAlpha_2;
			int _GlobalMaskDistanceBlendType_2;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_3==0
			int _GlobalMaskDistanceEnable_3;
			int _GlobalMaskDistanceType_3;
			float _GlobalMaskDistanceMin_3;
			float _GlobalMaskDistanceMax_3;
			float _GlobalMaskDistanceMinAlpha_3;
			float _GlobalMaskDistanceMaxAlpha_3;
			int _GlobalMaskDistanceBlendType_3;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_4==0
			int _GlobalMaskDistanceEnable_4;
			int _GlobalMaskDistanceType_4;
			float _GlobalMaskDistanceMin_4;
			float _GlobalMaskDistanceMax_4;
			float _GlobalMaskDistanceMinAlpha_4;
			float _GlobalMaskDistanceMaxAlpha_4;
			int _GlobalMaskDistanceBlendType_4;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_5==0
			int _GlobalMaskDistanceEnable_5;
			int _GlobalMaskDistanceType_5;
			float _GlobalMaskDistanceMin_5;
			float _GlobalMaskDistanceMax_5;
			float _GlobalMaskDistanceMinAlpha_5;
			float _GlobalMaskDistanceMaxAlpha_5;
			int _GlobalMaskDistanceBlendType_5;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_6==0
			int _GlobalMaskDistanceEnable_6;
			int _GlobalMaskDistanceType_6;
			float _GlobalMaskDistanceMin_6;
			float _GlobalMaskDistanceMax_6;
			float _GlobalMaskDistanceMinAlpha_6;
			float _GlobalMaskDistanceMaxAlpha_6;
			int _GlobalMaskDistanceBlendType_6;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_7==0
			int _GlobalMaskDistanceEnable_7;
			int _GlobalMaskDistanceType_7;
			float _GlobalMaskDistanceMin_7;
			float _GlobalMaskDistanceMax_7;
			float _GlobalMaskDistanceMinAlpha_7;
			float _GlobalMaskDistanceMaxAlpha_7;
			int _GlobalMaskDistanceBlendType_7;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_8==0
			int _GlobalMaskDistanceEnable_8;
			int _GlobalMaskDistanceType_8;
			float _GlobalMaskDistanceMin_8;
			float _GlobalMaskDistanceMax_8;
			float _GlobalMaskDistanceMinAlpha_8;
			float _GlobalMaskDistanceMaxAlpha_8;
			int _GlobalMaskDistanceBlendType_8;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_9==0
			int _GlobalMaskDistanceEnable_9;
			int _GlobalMaskDistanceType_9;
			float _GlobalMaskDistanceMin_9;
			float _GlobalMaskDistanceMax_9;
			float _GlobalMaskDistanceMinAlpha_9;
			float _GlobalMaskDistanceMaxAlpha_9;
			int _GlobalMaskDistanceBlendType_9;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_10==0
			int _GlobalMaskDistanceEnable_10;
			int _GlobalMaskDistanceType_10;
			float _GlobalMaskDistanceMin_10;
			float _GlobalMaskDistanceMax_10;
			float _GlobalMaskDistanceMinAlpha_10;
			float _GlobalMaskDistanceMaxAlpha_10;
			int _GlobalMaskDistanceBlendType_10;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_11==0
			int _GlobalMaskDistanceEnable_11;
			int _GlobalMaskDistanceType_11;
			float _GlobalMaskDistanceMin_11;
			float _GlobalMaskDistanceMax_11;
			float _GlobalMaskDistanceMinAlpha_11;
			float _GlobalMaskDistanceMaxAlpha_11;
			int _GlobalMaskDistanceBlendType_11;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_12==0
			int _GlobalMaskDistanceEnable_12;
			int _GlobalMaskDistanceType_12;
			float _GlobalMaskDistanceMin_12;
			float _GlobalMaskDistanceMax_12;
			float _GlobalMaskDistanceMinAlpha_12;
			float _GlobalMaskDistanceMaxAlpha_12;
			int _GlobalMaskDistanceBlendType_12;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_13==0
			int _GlobalMaskDistanceEnable_13;
			int _GlobalMaskDistanceType_13;
			float _GlobalMaskDistanceMin_13;
			float _GlobalMaskDistanceMax_13;
			float _GlobalMaskDistanceMinAlpha_13;
			float _GlobalMaskDistanceMaxAlpha_13;
			int _GlobalMaskDistanceBlendType_13;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_14==0
			int _GlobalMaskDistanceEnable_14;
			int _GlobalMaskDistanceType_14;
			float _GlobalMaskDistanceMin_14;
			float _GlobalMaskDistanceMax_14;
			float _GlobalMaskDistanceMinAlpha_14;
			float _GlobalMaskDistanceMaxAlpha_14;
			int _GlobalMaskDistanceBlendType_14;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_15==0
			int _GlobalMaskDistanceEnable_15;
			int _GlobalMaskDistanceType_15;
			float _GlobalMaskDistanceMin_15;
			float _GlobalMaskDistanceMax_15;
			float _GlobalMaskDistanceMinAlpha_15;
			float _GlobalMaskDistanceMaxAlpha_15;
			int _GlobalMaskDistanceBlendType_15;
			//endex
			//endex
			
			int _GlobalMaskVertexColorLinearSpace;
			//ifex _GlobalMaskVertexColorRed==0
			int _GlobalMaskVertexColorRed;
			int _GlobalMaskVertexColorRedBlendType;
			//endex
			//ifex _GlobalMaskVertexColorGreen==0
			int _GlobalMaskVertexColorGreen;
			int _GlobalMaskVertexColorGreenBlendType;
			//endex
			//ifex _GlobalMaskVertexColorBlue==0
			int _GlobalMaskVertexColorBlue;
			int _GlobalMaskVertexColorBlueBlendType;
			//endex
			//ifex _GlobalMaskVertexColorAlpha==0
			int _GlobalMaskVertexColorAlpha;
			int _GlobalMaskVertexColorAlphaBlendType;
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#ifdef POI_UDIMDISCARD
			float _UDIMDiscardMode;
			float _UDIMDiscardUV;
			float _UDIMDiscardRow3_0;
			float _UDIMDiscardRow3_1;
			float _UDIMDiscardRow3_2;
			float _UDIMDiscardRow3_3;
			float _UDIMDiscardRow2_0;
			float _UDIMDiscardRow2_1;
			float _UDIMDiscardRow2_2;
			float _UDIMDiscardRow2_3;
			float _UDIMDiscardRow1_0;
			float _UDIMDiscardRow1_1;
			float _UDIMDiscardRow1_2;
			float _UDIMDiscardRow1_3;
			float _UDIMDiscardRow0_0;
			float _UDIMDiscardRow0_1;
			float _UDIMDiscardRow0_2;
			float _UDIMDiscardRow0_3;
			#endif
			//endex
			
			//ifex _EnableDistortion==0
			#ifdef USER_LUT
			#if defined(PROP_DISTORTIONFLOWTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionFlowTexture;
			float4 _DistortionFlowTexture_ST;
			float2 _DistortionFlowTexturePan;
			float _DistortionFlowTextureUV;
			#endif
			
			#if defined(PROP_DISTORTIONFLOWTEXTURE1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionFlowTexture1;
			float4 _DistortionFlowTexture1_ST;
			float2 _DistortionFlowTexture1Pan;
			float _DistortionFlowTexture1UV;
			#endif
			
			#if defined(PROP_DISTORTIONMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionMask;
			float4 _DistortionMask_ST;
			float2 _DistortionMaskPan;
			float _DistortionMaskUV;
			float _DistortionMaskChannel;
			#endif
			
			float _DistortionUvToDistort;
			float _DistortionStrength;
			float _DistortionStrength1;
			
			#ifdef POI_AUDIOLINK
			half _EnableDistortionAudioLink;
			half2 _DistortionStrengthAudioLink;
			half _DistortionStrengthAudioLinkBand;
			half2 _DistortionStrength1AudioLink;
			half _DistortionStrength1AudioLinkBand;
			#endif
			#endif
			//endex
			float _StereoEnabled;
			float _PolarUV;
			float2 _PolarCenter;
			float _PolarRadialScale;
			float _PolarLengthScale;
			float _PolarSpiralPower;
			float _PanoUseBothEyes;
			
			float _UVModWorldPos0;
			float _UVModWorldPos1;
			float _UVModLocalPos0;
			float _UVModLocalPos1;
			
			//ifex _PoiParallax==0
			#ifdef POI_PARALLAX
			
			sampler2D _HeightMap;
			float4 _HeightMap_ST;
			float2 _HeightMapPan;
			float _HeightMapUV;
			
			#if defined(PROP_HEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Heightmask;
			float4 _Heightmask_ST;
			float2 _HeightmaskPan;
			float _HeightmaskUV;
			float _HeightmaskChannel;
			float _HeightmaskInvert;
			SamplerState _linear_repeat;
			#endif
			
			float _ParallaxUV;
			float _HeightStrength;
			float _HeightOffset;
			float _HeightStepsMin;
			float _HeightStepsMax;
			
			float _CurvatureU;
			float _CurvatureV;
			float _CurvFix;
			#endif
			//endex
			
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			float _AudioLinkDelay;
			float _AudioLinkAnimToggle;
			
			float _AudioLinkSmoothingBass;
			float _AudioLinkSmoothingLowMid;
			float _AudioLinkSmoothingHighMid;
			float _AudioLinkSmoothingTreble;
			
			float _DebugWaveform;
			float _DebugDFT;
			float _DebugBass;
			float _DebugLowMids;
			float _DebugHighMids;
			float _DebugTreble;
			float _DebugCCColors;
			float _DebugCCStrip;
			float _DebugCCLights;
			float _DebugAutocorrelator;
			float _DebugChronotensity;
			float _AudioLinkCCStripY;
			
			float _AudioLinkBandOverridesEnabled;
			float4 _AudioLinkBandOverrideSliders;
			#endif
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#ifdef POI_BLACKLIGHTMASKING
			float _BlackLightMasking0Key;
			float2 _BlackLightMasking0Range;
			float _BlackLightMasking0GlobalMaskIndex;
			float _BlackLightMasking0GlobalMaskBlendType;
			
			float _BlackLightMasking1Key;
			float2 _BlackLightMasking1Range;
			float _BlackLightMasking1GlobalMaskIndex;
			float _BlackLightMasking1GlobalMaskBlendType;
			
			float _BlackLightMasking2Key;
			float2 _BlackLightMasking2Range;
			float _BlackLightMasking2GlobalMaskIndex;
			float _BlackLightMasking2GlobalMaskBlendType;
			
			float _BlackLightMasking3Key;
			float2 _BlackLightMasking3Range;
			float _BlackLightMasking3GlobalMaskIndex;
			float _BlackLightMasking3GlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _DetailEnabled==0
			#ifdef FINALPASS
			#if defined(PROP_DETAILMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DetailMask;
			#endif
			float4 _DetailMask_ST;
			float2 _DetailMaskPan;
			float _DetailMaskUV;
			float _DetailMaskStochastic;
			
			#if defined(PROP_DETAILNORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DetailNormalMap;
			#endif
			float4 _DetailNormalMap_ST;
			float2 _DetailNormalMapPan;
			float _DetailNormalMapUV;
			float _DetailNormalMapScale;
			float _DetailNormalMapStochastic;
			float _DetailNormalGlobalMask;
			float _DetailNormalGlobalMaskBlendType;
			
			#if defined(PROP_DETAILTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DetailTex;
			#endif
			float4 _DetailTex_ST;
			float2 _DetailTexPan;
			float _DetailTexUV;
			float _DetailTexStochastic;
			
			float3 _DetailTint;
			float _DetailTintThemeIndex;
			float _DetailTexIntensity;
			float _DetailBrightness;
			float _DetailTexGlobalMask;
			float _DetailTexGlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _VertexManipulationsEnabled==0
			#ifdef AUTO_EXPOSURE
			float4 _VertexManipulationLocalTranslation;
			float4 _VertexManipulationLocalRotation;
			float3 _VertexManipulationLocalRotationSpeed;
			float4 _VertexManipulationLocalScale;
			float4 _VertexManipulationWorldTranslation;
			float _VertexManipulationHeight;
			sampler2D _VertexManipulationHeightMask;
			float4 _VertexManipulationHeightMask_ST;
			float2 _VertexManipulationHeightMaskPan;
			float _VertexManipulationHeightMaskUV;
			float _VertexManipulationHeightMaskChannel;
			float _VertexManipulationHeightBias;
			float _VertexRoundingEnabled;
			int _VertexRoundingSpace;
			float _VertexRoundingDivision;
			
			//AL
			float _VertexAudioLinkEnabled;
			float3 _VertexLocalTranslationALMin;
			float3 _VertexLocalTranslationALMax;
			float _VertexLocalTranslationALBand;
			
			float3 _VertexLocalRotationAL;
			float _VertexLocalRotationALBand;
			
			float3 _VertexLocalRotationCTALSpeed;
			float _VertexLocalRotationCTALBandX;
			float _VertexLocalRotationCTALBandY;
			float _VertexLocalRotationCTALBandZ;
			float _VertexLocalRotationCTALTypeX;
			float _VertexLocalRotationCTALTypeY;
			float _VertexLocalRotationCTALTypeZ;
			
			float4 _VertexLocalScaleALMin;
			float4 _VertexLocalScaleALMax;
			float _VertexLocalScaleALBand;
			
			float3 _VertexWorldTranslationALMin;
			float3 _VertexWorldTranslationALMax;
			float _VertexWorldTranslationALBand;
			
			float2 _VertexManipulationHeightAL;
			float _VertexManipulationHeightBand;
			
			float2 _VertexRoundingRangeAL;
			float _VertexRoundingRangeBand;
			
			float _VertexBarrelMode;
			float _VertexBarrelWidth;
			float _VertexBarrelAlpha;
			float _VertexBarrelHeight;
			
			float _VertexSphereMode;
			float _VertexSphereRadius;
			float _VertexSphereHeight;
			float _VertexSphereAlpha;
			float4 _VertexSphereCenter;
			
			float _VertexTornadoMode;
			float _VertexTornadoRadius;
			float _VertexTornadoSpeed;
			float _VertexTornadoIntensity;
			float _VertexTornadoBaseHeight;
			float _VertexTornadoTopHeight;
			
			float _VertexSpectrumMotion;
			float3 _VertexSpectrumOffsetMin;
			float3 _VertexSpectrumOffsetMax;
			float _VertexSpectrumUV;
			float _VertexSpectrumUVDirection;
			#endif
			//endex
			
			//ifex _VertexGlitchingEnabled==0
			#ifdef POI_VERTEX_GLITCHING
			//Vertex Glitching
			#if defined(POI_VERTEX_GLITCHING_TEXTURE)
			float _VertexGlitchingUseTexture;
			sampler2D _VertexGlitchMap;
			float4 _VertexGlitchMap_ST;
			#endif
			float _VertexGlitchThreshold;
			float _VertexGlitchFrequency;
			float _VertexGlitchStrength;
			float _VertexGlitchDensity;
			
			float _VertexGlitchMirrorEnable;
			float _VertexGlitchMirror;
			
			float _VertexGlitchMapPanSpeed;
			float _VertexGlitchingAudioLinkEnabled;
			float _VertexGlitchingAudioLinkBand;
			float _VertexGlitchingAudiolinkOverride;
			#endif
			//endex
			
			//ifex _EnableDepthBulge==0
			#ifdef POI_DEPTHBULGE
			float _DepthBulgeFadeLength;
			float _DepthBulgeHeight;
			
			#if defined(PROP_DEPTHBULGEMASK) || !defined(OPTIMIZER_ENABLED)
			sampler2D _DepthBulgeMask;
			#endif
			float _DepthBulgeMaskUV;
			float4 _DepthBulgeMask_ST;
			float _DepthBulgeMaskChannel;
			#endif
			//endex
			
			//ifex _MainVertexColoringEnabled==0
			float _MainVertexColoringEnabled;
			float _MainVertexColoringLinearSpace;
			float _MainVertexColoring;
			float _MainUseVertexColorAlpha;
			//endex
			
			//ifex _BackFaceEnabled!=1
			#ifdef POI_BACKFACE
			float _BackFaceEnabled;
			float _BackFaceDetailIntensity;
			float _BackFaceEmissionStrength;
			float2 _BackFacePanning;
			float4 _BackFaceColor;
			float _BackFaceColorThemeIndex;
			float _BackFaceReplaceAlpha;
			
			#if defined(PROP_BACKFACETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BackFaceTexture;
			#endif
			float4 _BackFaceTexture_ST;
			float2 _BackFaceTexturePan;
			float _BackFaceTextureUV;
			
			#if defined(PROP_BACKFACEMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BackFaceMask;
			#endif
			float4 _BackFaceMask_ST;
			float2 _BackFaceMaskPan;
			float _BackFaceMaskUV;
			float _BackFaceMaskChannel;
			
			float _BackFaceHueShiftEnabled;
			float _BackFaceHueShift;
			float _BackFaceHueShiftSpeed;
			float _BackFaceEmissionLimiter;
			#endif
			
			//TODO detail strength stuff
			//endex
			
			//ifex _RGBMaskEnabled==0
			#ifdef VIGNETTE
			#if defined(PROP_RGBMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RGBMask;
			#endif
			float4 _RGBMask_ST;
			float2 _RGBMaskPan;
			float _RGBMaskUV;
			
			#if defined(PROP_RGBAMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RGBAMetallicMaps;
			float4 _RGBAMetallicMaps_ST;
			float2 _RGBAMetallicMapsPan;
			float _RGBAMetallicMapsUV;
			float _RGBAMetallicMapsStochastic;
			#endif
			float _RGBARedMetallicInvert;
			float _RGBAGreenMetallicInvert;
			float _RGBABlueMetallicInvert;
			float _RGBAAlphaMetallicInvert;
			float _RGBAMetallicRedEnabled;
			float _RGBAMetallicGreenEnabled;
			float _RGBAMetallicBlueEnabled;
			float _RGBAMetallicAlphaEnabled;
			
			float _RGBARedPBRSplitMaskSample;
			float4 _RGBARedPBRMaskScaleTiling;
			float2 _RGBARedPBRMasksPan;
			float _RGBARedPBRUV;
			float _RGBARedPBRSplitMaskStochastic;
			
			float _RGBAGreenPBRSplitMaskSample;
			float4 _RGBAGreenPBRMaskScaleTiling;
			float2 _RGBAGreenPBRMasksPan;
			float _RGBAGreenPBRUV;
			float _RGBAGreenPBRSplitMaskStochastic;
			
			float _RGBABluePBRSplitMaskSample;
			float4 _RGBABluePBRMaskScaleTiling;
			float2 _RGBABluePBRMasksPan;
			float _RGBABluePBRUV;
			float _RGBABluePBRSplitMaskStochastic;
			
			float _RGBAAlphaPBRSplitMaskSample;
			float4 _RGBAAlphaPBRMaskScaleTiling;
			float2 _RGBAAlphaPBRMasksPan;
			float _RGBAAlphaPBRUV;
			float _RGBAAlphaPBRSplitMaskStochastic;
			
			float _RGBAPBRRedEnabled;
			float _RGBAPBRGreenEnabled;
			float _RGBAPBRBlueEnabled;
			float _RGBAPBRAlphaEnabled;
			
			#if defined(PROP_RGBASMOOTHNESSMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RGBASmoothnessMaps;
			float4 _RGBASmoothnessMaps_ST;
			float4 _RGBASmoothnessMapsPan;
			float _RGBASmoothnessMapsUV;
			float _RGBASmoothnessMapsStochastic;
			#endif
			float _RGBARedSmoothnessInvert;
			float _RGBAGreenSmoothnessInvert;
			float _RGBABlueSmoothnessInvert;
			float _RGBAAlphaSmoothnessInvert;
			
			float _RGBARedEnable;
			#if defined(PROP_REDTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RedTexture;
			#endif
			float4 _RedTexture_ST;
			float2 _RedTexturePan;
			float _RedTextureUV;
			float _RedAlphaAdd;
			float _RedTextureStochastic;
			float _RgbRedMaskChannel;
			float _RgbRedGlobalMaskChannel;
			float _RgbRedGlobalMaskBlendType;
			float _RGBARedBlendType;
			float4 _RedColor;
			float _RedColorThemeIndex;
			float _RGBARedEmissionStrength;
			
			#if defined(PROP_RGBNORMALR) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RgbNormalR;
			#endif
			float4 _RgbNormalR_ST;
			float2 _RgbNormalRPan;
			float _RgbNormalRUV;
			float _RgbNormalRScale;
			float _RgbNormalRStochastic;
			float _RgbNormalRMaskChannel;
			float _RgbNormalRGlobalMaskChannel;
			float _RgbNormalRGlobalMaskBlendType;
			float _RgbNormalRedBlendMode;
			
			float _RGBAGreenEnable;
			#if defined(PROP_GREENTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GreenTexture;
			#endif
			float4 _GreenTexture_ST;
			float2 _GreenTexturePan;
			float _GreenTextureUV;
			float _GreenAlphaAdd;
			float _GreenTextureStochastic;
			float _RgbGreenMaskChannel;
			float _RgbGreenGlobalMaskChannel;
			float _RgbGreenGlobalMaskBlendType;
			float _RGBAGreenBlendType;
			float4 _GreenColor;
			float _GreenColorThemeIndex;
			float _RGBAGreenEmissionStrength;
			
			#if defined(PROP_RGBNORMALG) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RgbNormalG;
			#endif
			float4 _RgbNormalG_ST;
			float2 _RgbNormalGPan;
			float _RgbNormalGUV;
			float _RgbNormalGScale;
			float _RgbNormalGStochastic;
			float _RgbNormalGMaskChannel;
			float _RgbNormalGGlobalMaskChannel;
			float _RgbNormalGGlobalMaskBlendType;
			float _RgbNormalGreenBlendMode;
			
			float _RGBABlueEnable;
			#if defined(PROP_BLUETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BlueTexture;
			#endif
			float4 _BlueTexture_ST;
			float2 _BlueTexturePan;
			float _BlueTextureUV;
			float _BlueAlphaAdd;
			float _BlueTextureStochastic;
			float _RgbBlueMaskChannel;
			float _RgbBlueGlobalMaskChannel;
			float _RgbBlueGlobalMaskBlendType;
			float _RGBABlueBlendType;
			float4 _BlueColor;
			float _BlueColorThemeIndex;
			float _RGBABlueEmissionStrength;
			
			#if defined(PROP_RGBNORMALB) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RgbNormalB;
			#endif
			float4 _RgbNormalB_ST;
			float2 _RgbNormalBPan;
			float _RgbNormalBUV;
			float _RgbNormalBScale;
			float _RgbNormalBStochastic;
			float _RgbNormalBMaskChannel;
			float _RgbNormalBGlobalMaskChannel;
			float _RgbNormalBGlobalMaskBlendType;
			float _RgbNormalBlueBlendMode;
			
			float _RGBAAlphaEnable;
			#if defined(PROP_ALPHATEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AlphaTexture;
			#endif
			float4 _AlphaTexture_ST;
			float2 _AlphaTexturePan;
			float _AlphaTextureUV;
			float _AlphaAlphaAdd;
			float _AlphaTextureStochastic;
			float _RgbAlphaMaskChannel;
			float _RgbAlphaGlobalMaskChannel;
			float _RgbAlphaGlobalMaskBlendType;
			float _RGBAAlphaBlendType;
			float4 _AlphaColor;
			float _AlphaColorThemeIndex;
			float _RGBAAlphaEmissionStrength;
			
			#if defined(PROP_RGBNORMALA) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RgbNormalA;
			#endif
			float4 _RgbNormalA_ST;
			float2 _RgbNormalAPan;
			float _RgbNormalAUV;
			float _RgbNormalAScale;
			float _RgbNormalAStochastic;
			float _RgbNormalAMaskChannel;
			float _RgbNormalAGlobalMaskChannel;
			float _RgbNormalAGlobalMaskBlendType;
			float _RgbNormalAlphaBlendMode;
			
			float _RGBMaskType;
			
			#endif
			//endex
			
			//ifex _ShadingEnabled==0
			float _ShadowStrength;
			float _LightingIgnoreAmbientColor;
			float3 _LightingShadowColor;
			
			float _ShadingRampedLightMapApplyGlobalMaskIndex;
			float _ShadingRampedLightMapApplyGlobalMaskBlendType;
			
			float _ShadingRampedLightMapInverseApplyGlobalMaskIndex;
			float _ShadingRampedLightMapInverseApplyGlobalMaskBlendType;
			
			// Toon Lighting
			#ifdef _LIGHTINGMODE_TEXTURERAMP
			UNITY_DECLARE_TEX2D(_ToonRamp);
			float _ShadowOffset;
			int _ToonRampCount;
			int _ToonRampUVSelector;
			#endif
			
			#ifdef _LIGHTINGMODE_WRAPPED
			float4 _LightingWrappedColor;
			float _LightingWrappedWrap;
			float _LightingWrappedNormalization;
			float _LightingGradientStart;
			float _LightingGradientEnd;
			#endif
			
			#ifdef _LIGHTINGMODE_SHADEMAP
			float3 _1st_ShadeColor;
			#if defined(PROP_1ST_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _1st_ShadeMap;
			#endif
			float4 _1st_ShadeMap_ST;
			float2 _1st_ShadeMapPan;
			float _1st_ShadeMapUV;
			float _Use_1stShadeMapAlpha_As_ShadowMask;
			float _1stShadeMapMask_Inverse;
			float _Use_BaseAs1st;
			float3 _2nd_ShadeColor;
			#if defined(PROP_2ND_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _2nd_ShadeMap;
			#endif
			float4 _2nd_ShadeMap_ST;
			float2 _2nd_ShadeMapPan;
			float _2nd_ShadeMapUV;
			float _Use_2ndShadeMapAlpha_As_ShadowMask;
			float _2ndShadeMapMask_Inverse;
			float _Use_1stAs2nd;
			float _BaseColor_Step;
			float _BaseShade_Feather;
			float _ShadeColor_Step;
			float _1st2nd_Shades_Feather;
			float _ShadingShadeMapBlendType;
			#endif
			
			#ifdef _LIGHTINGMODE_SKIN
			sampler2D _SkinLUT;
			float _SssScale;
			#if defined(PROP_SKINTHICKNESS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _SkinThicknessMap;
			#endif
			float4 _SkinThicknessMap_ST;
			float2 _SkinThicknessMapPan;
			float _SkinThicknessMapUV;
			float _SkinThicknessMapInvert;
			float _SkinThicknessPower;
			float _SssBumpBlur;
			float3 _SssTransmissionAbsorption;
			float3 _SssColorBleedAoWeights;
			#endif
			
			#ifdef _LIGHTINGMODE_MULTILAYER_MATH
			float _ShadowBorderMapToggle;
			#if defined(PROP_SHADOWBORDERMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ShadowBorderMask;
			float4 _ShadowBorderMask_ST;
			float2 _ShadowBorderMaskPan;
			float _ShadowBorderMaskUV;
			#endif
			float _ShadowPostAO;
			float _ShadowBorderMaskLOD;
			float4 _ShadowAOShift;
			float4 _ShadowAOShift2;
			
			float4 _ShadowColor;
			float _LightingMulitlayerNonLinear;
			#if defined(PROP_SHADOWCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ShadowColorTex;
			float4 _ShadowColorTex_ST;
			float2 _ShadowColorTexPan;
			float _ShadowColorTexUV;
			#endif
			#if defined(PROP_MULTILAYERMATHBLURMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MultilayerMathBlurMap;
			float4 _MultilayerMathBlurMap_ST;
			float2 _MultilayerMathBlurMapPan;
			float _MultilayerMathBlurMapUV;
			#endif
			float _ShadowBorder;
			float _ShadowBlur;
			float _ShadowReceive;
			float4 _Shadow2ndColor;
			#if defined(PROP_SHADOW2NDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Shadow2ndColorTex;
			float4 _Shadow2ndColorTex_ST;
			float2 _Shadow2ndColorTexPan;
			float _Shadow2ndColorTexUV;
			#endif
			float _Shadow2ndBorder;
			float _Shadow2ndBlur;
			float _Shadow2ndReceive;
			float4 _Shadow3rdColor;
			#if defined(PROP_SHADOW3RDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Shadow3rdColorTex;
			float4 _Shadow3rdColorTex_ST;
			float2 _Shadow3rdColorTexPan;
			float _Shadow3rdColorTexUV;
			#endif
			float _Shadow3rdBorder;
			float _Shadow3rdBlur;
			float _Shadow3rdReceive;
			float4 _ShadowBorderColor;
			float _ShadowBorderRange;
			float _ShadowMainStrength;
			#endif
			
			#ifdef _LIGHTINGMODE_FLAT
			float _ForceFlatRampedLightmap;
			#endif
			
			#ifdef _LIGHTINGMODE_CLOTH
			Texture2D_float _ClothDFG;
			SamplerState sampler_ClothDFG;
			
			#if defined(PROP_CLOTHMETALLICSMOOTHNESSMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ClothMetallicSmoothnessMap;
			#endif
			
			float4 _ClothMetallicSmoothnessMap_ST;
			float2 _ClothMetallicSmoothnessMapPan;
			float _ClothMetallicSmoothnessMapUV;
			float _ClothMetallicSmoothnessMapInvert;
			
			float _ClothLerp;
			float _ClothMetallic;
			float _ClothReflectance;
			float _ClothSmoothness;
			#endif
			
			#ifdef _LIGHTINGMODE_SDF
			#if defined(PROP_SDFSHADINGTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _SDFShadingTexture;
			float _SDFShadingTextureUV;
			float2 _SDFShadingTexturePan;
			float4 _SDFShadingTexture_ST;
			float _SDFBlur;
			float4 _SDFForward;
			float4 _SDFLeft;
			#endif
			#endif
			
			// Additive
			float _LightingAdditiveType;
			float _LightingAdditiveGradientStart;
			float _LightingAdditiveGradientEnd;
			float _LightingAdditiveDetailStrength;
			//endex
			
			//ifex _DecalEnabled==0 && _DecalEnabled1==0 && _DecalEnabled2==0 && _DecalEnabled3==0
			
			#if defined(PROP_DECALMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DecalMask;
			float4 _DecalMask_ST;
			float2 _DecalMaskPan;
			float _DecalMaskUV;
			#endif
			float _DecalTPSDepthMaskEnabled;
			float _Decal0TPSMaskStrength;
			float _Decal1TPSMaskStrength;
			float _Decal2TPSMaskStrength;
			float _Decal3TPSMaskStrength;
			
			sampler2D _Udon_VideoTex;
			float4 _Udon_VideoTex_TexelSize;
			
			#ifdef POI_AUDIOLINK
			//ifex _DecalEnabled==0
			#ifdef GEOM_TYPE_BRANCH
			// Audio Link
			half _AudioLinkDecal0ScaleBand;
			float4 _AudioLinkDecal0Scale;
			half _AudioLinkDecal0RotationBand;
			float2 _AudioLinkDecal0Rotation;
			half _AudioLinkDecal0AlphaBand;
			float2 _AudioLinkDecal0Alpha;
			half _AudioLinkDecal0EmissionBand;
			float2 _AudioLinkDecal0Emission;
			float _DecalRotationCTALBand0;
			float _DecalRotationCTALSpeed0;
			float _DecalRotationCTALType0;
			float _AudioLinkDecalCC0;
			float _AudioLinkDecal0SideBand;
			float4 _AudioLinkDecal0SideMin;
			float4 _AudioLinkDecal0SideMax;
			float2 _AudioLinkDecal0ChannelSeparation;
			float _AudioLinkDecal0ChannelSeparationBand;
			#endif //GEOM_TYPE_BRANCH
			//endex
			//ifex _DecalEnabled1==0
			#ifdef GEOM_TYPE_BRANCH_DETAIL
			half _AudioLinkDecal1ScaleBand;
			float4 _AudioLinkDecal1Scale;
			half _AudioLinkDecal1RotationBand;
			float2 _AudioLinkDecal1Rotation;
			half _AudioLinkDecal1AlphaBand;
			float2 _AudioLinkDecal1Alpha;
			half _AudioLinkDecal1EmissionBand;
			float2 _AudioLinkDecal1Emission;
			float _DecalRotationCTALBand1;
			float _DecalRotationCTALSpeed1;
			float _DecalRotationCTALType1;
			float _AudioLinkDecalCC1;
			float _AudioLinkDecal1SideBand;
			float4 _AudioLinkDecal1SideMin;
			float4 _AudioLinkDecal1SideMax;
			float2 _AudioLinkDecal1ChannelSeparation;
			float _AudioLinkDecal1ChannelSeparationBand;
			#endif //GEOM_TYPE_BRANCH_DETAIL
			//endex
			//ifex _DecalEnabled2==0
			#ifdef GEOM_TYPE_FROND
			half _AudioLinkDecal2ScaleBand;
			float4 _AudioLinkDecal2Scale;
			half _AudioLinkDecal2RotationBand;
			float2 _AudioLinkDecal2Rotation;
			half _AudioLinkDecal2AlphaBand;
			float2 _AudioLinkDecal2Alpha;
			half _AudioLinkDecal2EmissionBand;
			float2 _AudioLinkDecal2Emission;
			float _DecalRotationCTALBand2;
			float _DecalRotationCTALSpeed2;
			float _DecalRotationCTALType2;
			float _AudioLinkDecalCC2;
			float _AudioLinkDecal2SideBand;
			float4 _AudioLinkDecal2SideMin;
			float4 _AudioLinkDecal2SideMax;
			float2 _AudioLinkDecal2ChannelSeparation;
			float _AudioLinkDecal2ChannelSeparationBand;
			#endif //GEOM_TYPE_FROND
			//endex
			//ifex _DecalEnabled3==0
			#ifdef DEPTH_OF_FIELD_COC_VIEW
			half _AudioLinkDecal3ScaleBand;
			float4 _AudioLinkDecal3Scale;
			half _AudioLinkDecal3RotationBand;
			float2 _AudioLinkDecal3Rotation;
			half _AudioLinkDecal3AlphaBand;
			float2 _AudioLinkDecal3Alpha;
			half _AudioLinkDecal3EmissionBand;
			float2 _AudioLinkDecal3Emission;
			float _DecalRotationCTALBand3;
			float _DecalRotationCTALSpeed3;
			float _DecalRotationCTALType3;
			float _AudioLinkDecalCC3;
			float _AudioLinkDecal3SideBand;
			float4 _AudioLinkDecal3SideMin;
			float4 _AudioLinkDecal3SideMax;
			float2 _AudioLinkDecal3ChannelSeparation;
			float _AudioLinkDecal3ChannelSeparationBand;
			#endif //DEPTH_OF_FIELD_COC_VIEW
			//endex
			#endif
			//endex
			//ifex _DecalEnabled==0
			#ifdef GEOM_TYPE_BRANCH
			float _Decal0VideoFitToScale;
			float _Decal0VideoAspectFix;
			float _Decal0VideoEmissionStrength;
			float _Decal0VideoEnabled;
			float _Decal0UseDecalAlpha;
			float _Decal0OnlyVideo;
			sampler2D _DecalTexture;
			float _Decal0FaceMask;
			float _Decal0MaskChannel;
			float _Decal0GlobalMask;
			float _Decal0GlobalMaskBlendType;
			float _Decal0ApplyGlobalMaskIndex;
			float _Decal0ApplyGlobalMaskBlendType;
			float4 _DecalTexture_ST;
			float2 _DecalTexturePan;
			float _DecalTextureUV;
			float4 _DecalColor;
			float _DecalColorThemeIndex;
			float _DecalTiled;
			float _DecalBlendType;
			half _DecalRotation;
			half3 _DecalScale;
			float4 _DecalSideOffset;
			half2 _DecalPosition;
			half _DecalRotationSpeed;
			float _DecalEmissionStrength;
			float _DecalBlendAlpha;
			float _DecalOverrideAlpha;
			float _DecalHueShiftEnabled;
			float _DecalHueShift;
			float _DecalHueShiftSpeed;
			float _Decal0Depth;
			float _Decal0HueAngleStrength;
			float _Decal0ChannelSeparationEnable;
			float _Decal0ChannelSeparation;
			float _Decal0ChannelSeparationPremultiply;
			float _Decal0ChannelSeparationHue;
			float _Decal0ChannelSeparationVertical;
			float _Decal0ChannelSeparationAngleStrength;
			float _Decal0OverrideAlphaMode;
			#endif
			//endex
			
			//ifex _DecalEnabled1==0
			#ifdef GEOM_TYPE_BRANCH_DETAIL
			float _Decal1VideoAspectFix;
			float _Decal1VideoFitToScale;
			float _Decal1VideoEmissionStrength;
			float _Decal1VideoEnabled;
			float _Decal1UseDecalAlpha;
			float _Decal1OnlyVideo;
			float _Decal1TextureToUse;
			sampler2D _DecalTexture1;
			float _Decal1FaceMask;
			float _Decal1MaskChannel;
			float _Decal1GlobalMask;
			float _Decal1GlobalMaskBlendType;
			float _Decal1ApplyGlobalMaskIndex;
			float _Decal1ApplyGlobalMaskBlendType;
			float4 _DecalTexture1_ST;
			float2 _DecalTexture1Pan;
			float _DecalTexture1UV;
			float4 _DecalColor1;
			float _DecalColor1ThemeIndex;
			fixed _DecalTiled1;
			float _DecalBlendType1;
			half _DecalRotation1;
			half3 _DecalScale1;
			float4 _DecalSideOffset1;
			half2 _DecalPosition1;
			half _DecalRotationSpeed1;
			float _DecalEmissionStrength1;
			float _DecalBlendAlpha1;
			float _DecalOverrideAlpha1;
			float _DecalHueShiftEnabled1;
			float _DecalHueShift1;
			float _DecalHueShiftSpeed1;
			float _Decal1Depth;
			float _Decal1HueAngleStrength;
			float _Decal1ChannelSeparationEnable;
			float _Decal1ChannelSeparation;
			float _Decal1ChannelSeparationPremultiply;
			float _Decal1ChannelSeparationHue;
			float _Decal1ChannelSeparationVertical;
			float _Decal1ChannelSeparationAngleStrength;
			float _Decal1OverrideAlphaMode;
			#endif
			//endex
			
			//ifex _DecalEnabled2==0
			#ifdef GEOM_TYPE_FROND
			float _Decal2VideoAspectFix;
			float _Decal2VideoFitToScale;
			float _Decal2VideoEmissionStrength;
			float _Decal2VideoEnabled;
			float _Decal2UseDecalAlpha;
			float _Decal2OnlyVideo;
			float _Decal2TextureToUse;
			sampler2D _DecalTexture2;
			float _Decal2FaceMask;
			float _Decal2MaskChannel;
			float _Decal2GlobalMask;
			float _Decal2GlobalMaskBlendType;
			float _Decal2ApplyGlobalMaskIndex;
			float _Decal2ApplyGlobalMaskBlendType;
			float4 _DecalTexture2_ST;
			float2 _DecalTexture2Pan;
			float _DecalTexture2UV;
			float4 _DecalColor2;
			float _DecalColor2ThemeIndex;
			fixed _DecalTiled2;
			float _DecalBlendType2;
			half _DecalRotation2;
			half3 _DecalScale2;
			float4 _DecalSideOffset2;
			half2 _DecalPosition2;
			half _DecalRotationSpeed2;
			float _DecalEmissionStrength2;
			float _DecalBlendAlpha2;
			float _DecalOverrideAlpha2;
			float _DecalHueShiftEnabled2;
			float _DecalHueShift2;
			float _DecalHueShiftSpeed2;
			float _Decal2Depth;
			float _Decal2HueAngleStrength;
			float _Decal2ChannelSeparationEnable;
			float _Decal2ChannelSeparation;
			float _Decal2ChannelSeparationPremultiply;
			float _Decal2ChannelSeparationHue;
			float _Decal2ChannelSeparationVertical;
			float _Decal2ChannelSeparationAngleStrength;
			float _Decal2OverrideAlphaMode;
			#endif
			//endex
			
			//ifex _DecalEnabled3==0
			#ifdef DEPTH_OF_FIELD_COC_VIEW
			float _Decal3VideoAspectFix;
			float _Decal3VideoFitToScale;
			float _Decal3VideoEmissionStrength;
			float _Decal3VideoEnabled;
			float _Decal3UseDecalAlpha;
			float _Decal3OnlyVideo;
			float _Decal3TextureToUse;
			sampler2D _DecalTexture3;
			float _Decal3FaceMask;
			float _Decal3MaskChannel;
			float _Decal3GlobalMask;
			float _Decal3GlobalMaskBlendType;
			float _Decal3ApplyGlobalMaskIndex;
			float _Decal3ApplyGlobalMaskBlendType;
			float4 _DecalTexture3_ST;
			float2 _DecalTexture3Pan;
			float _DecalTexture3UV;
			float4 _DecalColor3;
			float _DecalColor3ThemeIndex;
			fixed _DecalTiled3;
			float _DecalBlendType3;
			half _DecalRotation3;
			half3 _DecalScale3;
			float4 _DecalSideOffset3;
			half2 _DecalPosition3;
			half _DecalRotationSpeed3;
			float _DecalEmissionStrength3;
			float _DecalBlendAlpha3;
			float _DecalOverrideAlpha3;
			float _DecalHueShiftEnabled3;
			float _DecalHueShift3;
			float _DecalHueShiftSpeed3;
			float _Decal3Depth;
			float _Decal3HueAngleStrength;
			float _Decal3ChannelSeparationEnable;
			float _Decal3ChannelSeparation;
			float _Decal3ChannelSeparationPremultiply;
			float _Decal3ChannelSeparationHue;
			float _Decal3ChannelSeparationVertical;
			float _Decal3ChannelSeparationAngleStrength;
			float _Decal3OverrideAlphaMode;
			#endif
			//endex
			
			//ifex _EnableDissolve==0
			#ifdef DISTORT
			float _DissolveType;
			float _DissolveEdgeWidth;
			float4 _DissolveEdgeColor;
			sampler2D _DissolveEdgeGradient;
			float4 _DissolveEdgeGradient_ST;
			float2 _DissolveEdgeGradientPan;
			float _DissolveEdgeGradientUV;
			float _DissolveEdgeEmission;
			float4 _DissolveTextureColor;
			float _DissolveEdgeColorThemeIndex;
			float _DissolveTextureColorThemeIndex;
			
			#if defined(PROP_DISSOLVETOTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveToTexture;
			#endif
			float4 _DissolveToTexture_ST;
			float2 _DissolveToTexturePan;
			float _DissolveToTextureUV;
			
			#if defined(PROP_DISSOLVENOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveNoiseTexture;
			#endif
			float4 _DissolveNoiseTexture_ST;
			float2 _DissolveNoiseTexturePan;
			float _DissolveNoiseTextureUV;
			
			#if defined(PROP_DISSOLVEDETAILNOISE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveDetailNoise;
			#endif
			float4 _DissolveDetailNoise_ST;
			float2 _DissolveDetailNoisePan;
			float _DissolveDetailNoiseUV;
			
			#if defined(PROP_DISSOLVEMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveMask;
			#endif
			float4 _DissolveMask_ST;
			float2 _DissolveMaskPan;
			float _DissolveMaskUV;
			
			float _DissolveMaskGlobalMask;
			float _DissolveMaskGlobalMaskBlendType;
			float _DissolveApplyGlobalMaskIndex;
			float _DissolveApplyGlobalMaskBlendType;
			float _DissolveInverseApplyGlobalMaskBlendType;
			float _DissolveInverseApplyGlobalMaskIndex;
			float _DissolveMaskInvert;
			float _DissolveAlpha;
			float _ContinuousDissolve;
			float _DissolveDetailStrength;
			float _DissolveDetailEdgeSmoothing;
			float _DissolveEdgeHardness;
			float _DissolveInvertNoise;
			float _DissolveInvertDetailNoise;
			float _DissolveToEmissionStrength;
			
			// Point to Point
			float _DissolveP2PWorldLocal;
			float _DissolveP2PEdgeLength;
			float _DissolveP2PClamp;
			float4 _DissolveStartPoint;
			float4 _DissolveEndPoint;
			
			// Spherical
			float3 _SphericalDissolveCenter;
			float _SphericalDissolveRadius;
			float _SphericalDissolveInvert;
			float _SphericalDissolveClamp;
			
			// CenterOut
			float _CenterOutDissolveMode;
			float3 _CenterOutDissolveDirection;
			float _CenterOutDissolveInvert;
			float _CenterOutDissolveNormals;
			float _CenterOutDissolvePower;
			
			// World Dissolve
			float _DissolveWorldShape;
			float4 _DissolveShapePosition;
			float4 _DissolveShapeRotation;
			float _DissolveShapeScale;
			float _DissolveInvertShape;
			float _DissolveShapeEdgeLength;
			
			// UV Tile Dissolve
			float _UVTileDissolveEnabled;
			float _UVTileDissolveDiscardAtMax;
			float _UVTileDissolveUV;
			
			float _UVTileDissolveAlpha_Row3_0;
			float _UVTileDissolveAlpha_Row3_1;
			float _UVTileDissolveAlpha_Row3_2;
			float _UVTileDissolveAlpha_Row3_3;
			float _UVTileDissolveAlpha_Row2_0;
			float _UVTileDissolveAlpha_Row2_1;
			float _UVTileDissolveAlpha_Row2_2;
			float _UVTileDissolveAlpha_Row2_3;
			float _UVTileDissolveAlpha_Row1_0;
			float _UVTileDissolveAlpha_Row1_1;
			float _UVTileDissolveAlpha_Row1_2;
			float _UVTileDissolveAlpha_Row1_3;
			float _UVTileDissolveAlpha_Row0_0;
			float _UVTileDissolveAlpha_Row0_1;
			float _UVTileDissolveAlpha_Row0_2;
			float _UVTileDissolveAlpha_Row0_3;
			
			float _DissolveAlpha0;
			float _DissolveAlpha1;
			float _DissolveAlpha2;
			float _DissolveAlpha3;
			float _DissolveAlpha4;
			float _DissolveAlpha5;
			float _DissolveAlpha6;
			float _DissolveAlpha7;
			float _DissolveAlpha8;
			float _DissolveAlpha9;
			// Masking
			float _DissolveEmissionSide;
			float _DissolveEmission1Side;
			float _DissolveUseVertexColors;
			
			float4 edgeColor;
			float edgeAlpha;
			float dissolveAlpha;
			float4 dissolveToTexture;
			
			float _DissolveHueShiftEnabled;
			float _DissolveHueShiftSpeed;
			float _DissolveHueShift;
			float _DissolveEdgeHueShiftEnabled;
			float _DissolveEdgeHueShiftSpeed;
			float _DissolveEdgeHueShift;
			
			// Audio Link
			#ifdef POI_AUDIOLINK
			fixed _EnableDissolveAudioLink;
			half _AudioLinkDissolveAlphaBand;
			float2 _AudioLinkDissolveAlpha;
			half _AudioLinkDissolveDetailBand;
			float2 _AudioLinkDissolveDetail;
			#endif
			#endif
			//endex
			
			//ifex _EnableAniso==0
			#ifdef POI_ANISOTROPICS
			
			#if defined(PROP_ANISOCOLORMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AnisoColorMap;
			float4 _AnisoColorMap_ST;
			float2 _AnisoColorMapPan;
			float _AnisoColorMapUV;
			#endif
			/*
			#if defined(PROP_ANISONOISEMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AnisoNoiseMap;
			float4 _AnisoNoiseMap_ST;
			float2 _AnisoNoiseMapPan;
			float _AnisoNoiseMapUV;
			#endif
			*/
			float _AnisoHideInShadow;
			float _AnisoReplace;
			float _AnisoAdd;
			float _AnisoUseBaseColor;
			float _AnisoUseLightColor;
			
			float _AnisoGlobalMask;
			float _AnisoGlobalMaskBlendType;
			
			float _Aniso0Strength;
			float _Aniso0Power;
			float _Aniso0Offset;
			float _Aniso0SwitchDirection;
			float4 _Aniso0Tint;
			float _Aniso0TintIndex;
			float _Aniso0OffsetMapStrength;
			float _Aniso0ToonMode;
			float _Aniso0Edge;
			float _Aniso0Blur;
			
			float _Aniso1Strength;
			float _Aniso1Power;
			float _Aniso1Offset;
			float _Aniso1SwitchDirection;
			float4 _Aniso1Tint;
			float _Aniso1TintIndex;
			float _Aniso1OffsetMapStrength;
			float _Aniso1ToonMode;
			float _Aniso1Edge;
			float _Aniso1Blur;
			#endif
			//endex
			
			//ifex _MatcapEnable==0
			#ifdef POI_MATCAP0
			#if defined(PROP_MATCAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap;
			float4 _Matcap_ST;
			float4 _Matcap_TexelSize;
			float2 _MatcapPan;
			float _MatcapUV;
			#endif
			#if defined(PROP_MATCAPMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MatcapMask;
			float4 _MatcapMask_ST;
			float2 _MatcapMaskPan;
			float _MatcapMaskUV;
			float _MatcapMaskChannel;
			#endif
			#ifdef POI_MATCAP0_CUSTOM_NORMAL
			#if defined(PROP_MATCAP0NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap0NormalMap;
			#endif
			float4 _Matcap0NormalMap_ST;
			float2 _Matcap0NormalMapPan;
			float _Matcap0NormalMapUV;
			float _Matcap0NormalMapScale;
			#endif
			float _MatcapUVToBlend;
			float4 _MatCapBlendUV1;
			float _MatcapUVMode;
			float _MatcapMaskInvert;
			float _MatcapMaskGlobalMask;
			float _MatcapMaskGlobalMaskBlendType;
			float _MatcapBorder;
			float _MatcapRotation;
			float _MatcapSmoothnessEnabled;
			float _MatcapSmoothness;
			float _MatcapMaskSmoothnessChannel;
			float _MatcapMaskSmoothnessApply;
			float4 _MatcapColor;
			float _MatcapBaseColorMix;
			float _MatcapColorThemeIndex;
			float _MatcapIntensity;
			float _MatcapReplace;
			float _MatcapMultiply;
			float _MatcapAdd;
			float _MatcapAddToLight;
			float _MatcapMixed;
			float _MatcapScreen;
			float _MatcapAlphaOverride;
			float _MatcapEnable;
			float _MatcapLightMask;
			float _MatcapEmissionStrength;
			float _MatcapNormal;
			float _MatcapHueShiftEnabled;
			float _MatcapHueShiftSpeed;
			float _MatcapHueShift;
			int _MatcapApplyToAlphaEnabled;
			int _MatcapApplyToAlphaSourceBlend;
			int _MatcapApplyToAlphaBlendType;
			float _MatcapApplyToAlphaBlending;
			float _MatcapTPSDepthEnabled;
			float _MatcapTPSMaskStrength;
			
			float _Matcap0ALEnabled;
			float _Matcap0ALAlphaAddBand;
			float4 _Matcap0ALAlphaAdd;
			float _Matcap0ALEmissionAddBand;
			float4 _Matcap0ALEmissionAdd;
			float _Matcap0ALIntensityAddBand;
			float4 _Matcap0ALIntensityAdd;
			float _Matcap0ALChronoPanType;
			float _Matcap0ALChronoPanBand;
			float _Matcap0ALChronoPanSpeed;
			#endif
			//endex
			//ifex _Matcap2Enable==0
			#ifdef COLOR_GRADING_HDR_3D
			#if defined(PROP_MATCAP2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap2;
			float4 _Matcap2_ST;
			float4 _Matcap2_TexelSize;
			float2 _Matcap2Pan;
			float _Matcap2UV;
			#endif
			#if defined(PROP_MATCAP2MASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap2Mask;
			float4 _Matcap2Mask_ST;
			float2 _Matcap2MaskPan;
			float _Matcap2MaskUV;
			float _Matcap2MaskChannel;
			#endif
			#ifdef POI_MATCAP1_CUSTOM_NORMAL
			#if defined(PROP_MATCAP1NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap1NormalMap;
			#endif
			float4 _Matcap1NormalMap_ST;
			float2 _Matcap1NormalMapPan;
			float _Matcap1NormalMapUV;
			float _Matcap1NormalMapScale;
			#endif
			float _Matcap2UVToBlend;
			float4 _MatCap2ndBlendUV1;
			float _Matcap2UVMode;
			float _Matcap2MaskInvert;
			float _Matcap2MaskGlobalMask;
			float _Matcap2MaskGlobalMaskBlendType;
			float _Matcap2Border;
			float _Matcap2Rotation;
			float _Matcap2SmoothnessEnabled;
			float _Matcap2Smoothness;
			float _Matcap2MaskSmoothnessChannel;
			float _Matcap2MaskSmoothnessApply;
			float4 _Matcap2Color;
			float _Matcap2BaseColorMix;
			float _Matcap2ColorThemeIndex;
			float _Matcap2Intensity;
			float _Matcap2Replace;
			float _Matcap2Multiply;
			float _Matcap2Add;
			float _Matcap2AddToLight;
			float _Matcap2Mixed;
			float _Matcap2Screen;
			float _Matcap2AlphaOverride;
			float _Matcap2Enable;
			float _Matcap2LightMask;
			float _Matcap2EmissionStrength;
			float _Matcap2Normal;
			float _Matcap2HueShiftEnabled;
			float _Matcap2HueShiftSpeed;
			float _Matcap2HueShift;
			int _Matcap2ApplyToAlphaEnabled;
			int _Matcap2ApplyToAlphaSourceBlend;
			int _Matcap2ApplyToAlphaBlendType;
			float _Matcap2ApplyToAlphaBlending;
			float _Matcap2TPSDepthEnabled;
			float _Matcap2TPSMaskStrength;
			
			float _Matcap1ALEnabled;
			float _Matcap1ALAlphaAddBand;
			float4 _Matcap1ALAlphaAdd;
			float _Matcap1ALEmissionAddBand;
			float4 _Matcap1ALEmissionAdd;
			float _Matcap1ALIntensityAddBand;
			float4 _Matcap1ALIntensityAdd;
			float _Matcap1ALChronoPanType;
			float _Matcap1ALChronoPanBand;
			float _Matcap1ALChronoPanSpeed;
			#endif
			//endex
			
			//ifex _Matcap3Enable==0
			#ifdef POI_MATCAP2
			#if defined(PROP_MATCAP3) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap3;
			float4 _Matcap3_ST;
			float4 _Matcap3_TexelSize;
			float2 _Matcap3Pan;
			float _Matcap3UV;
			#endif
			#if defined(PROP_MATCAP3MASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap3Mask;
			float4 _Matcap3Mask_ST;
			float2 _Matcap3MaskPan;
			float _Matcap3MaskUV;
			float _Matcap3MaskChannel;
			#endif
			#ifdef POI_MATCAP2_CUSTOM_NORMAL
			#if defined(PROP_MATCAP2NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap2NormalMap;
			#endif
			float4 _Matcap2NormalMap_ST;
			float2 _Matcap2NormalMapPan;
			float _Matcap2NormalMapUV;
			float _Matcap2NormalMapScale;
			#endif
			float _Matcap3UVToBlend;
			float4 _MatCap3rdBlendUV1;
			float _Matcap3UVMode;
			float _Matcap3MaskInvert;
			float _Matcap3MaskGlobalMask;
			float _Matcap3MaskGlobalMaskBlendType;
			float _Matcap3Border;
			float _Matcap3Rotation;
			float _Matcap3SmoothnessEnabled;
			float _Matcap3Smoothness;
			float _Matcap3MaskSmoothnessChannel;
			float _Matcap3MaskSmoothnessApply;
			float4 _Matcap3Color;
			float _Matcap3BaseColorMix;
			float _Matcap3ColorThemeIndex;
			float _Matcap3Intensity;
			float _Matcap3Replace;
			float _Matcap3Multiply;
			float _Matcap3Add;
			float _Matcap3AddToLight;
			float _Matcap3Mixed;
			float _Matcap3Screen;
			float _Matcap3AlphaOverride;
			float _Matcap3Enable;
			float _Matcap3LightMask;
			float _Matcap3EmissionStrength;
			float _Matcap3Normal;
			float _Matcap3HueShiftEnabled;
			float _Matcap3HueShiftSpeed;
			float _Matcap3HueShift;
			int _Matcap3ApplyToAlphaEnabled;
			int _Matcap3ApplyToAlphaSourceBlend;
			int _Matcap3ApplyToAlphaBlendType;
			float _Matcap3ApplyToAlphaBlending;
			float _Matcap3TPSDepthEnabled;
			float _Matcap3TPSMaskStrength;
			
			float _Matcap2ALEnabled;
			float _Matcap2ALAlphaAddBand;
			float4 _Matcap2ALAlphaAdd;
			float _Matcap2ALEmissionAddBand;
			float4 _Matcap2ALEmissionAdd;
			float _Matcap2ALIntensityAddBand;
			float4 _Matcap2ALIntensityAdd;
			float _Matcap2ALChronoPanType;
			float _Matcap2ALChronoPanBand;
			float _Matcap2ALChronoPanSpeed;
			#endif
			//endex
			
			//ifex _Matcap4Enable==0
			#ifdef POI_MATCAP3
			#if defined(PROP_MATCAP4) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap4;
			float4 _Matcap4_ST;
			float4 _Matcap4_TexelSize;
			float2 _Matcap4Pan;
			float _Matcap4UV;
			#endif
			#if defined(PROP_MATCAP4MASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap4Mask;
			float4 _Matcap4Mask_ST;
			float2 _Matcap4MaskPan;
			float _Matcap4MaskUV;
			float _Matcap4MaskChannel;
			#endif
			#ifdef POI_MATCAP3_CUSTOM_NORMAL
			#if defined(PROP_MATCAP3NORMALMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Matcap3NormalMap;
			#endif
			float4 _Matcap3NormalMap_ST;
			float2 _Matcap3NormalMapPan;
			float _Matcap3NormalMapUV;
			float _Matcap3NormalMapScale;
			#endif
			float _Matcap4UVToBlend;
			float4 _MatCap4thBlendUV1;
			float _Matcap4UVMode;
			float _Matcap4MaskInvert;
			float _Matcap4MaskGlobalMask;
			float _Matcap4MaskGlobalMaskBlendType;
			float _Matcap4Border;
			float _Matcap4Rotation;
			float _Matcap4SmoothnessEnabled;
			float _Matcap4Smoothness;
			float _Matcap4MaskSmoothnessChannel;
			float _Matcap4MaskSmoothnessApply;
			float4 _Matcap4Color;
			float _Matcap4BaseColorMix;
			float _Matcap4ColorThemeIndex;
			float _Matcap4Intensity;
			float _Matcap4Replace;
			float _Matcap4Multiply;
			float _Matcap4Add;
			float _Matcap4AddToLight;
			float _Matcap4Mixed;
			float _Matcap4Screen;
			float _Matcap4AlphaOverride;
			float _Matcap4Enable;
			float _Matcap4LightMask;
			float _Matcap4EmissionStrength;
			float _Matcap4Normal;
			float _Matcap4HueShiftEnabled;
			float _Matcap4HueShiftSpeed;
			float _Matcap4HueShift;
			int _Matcap4ApplyToAlphaEnabled;
			int _Matcap4ApplyToAlphaSourceBlend;
			int _Matcap4ApplyToAlphaBlendType;
			float _Matcap4ApplyToAlphaBlending;
			float _Matcap4TPSDepthEnabled;
			float _Matcap4TPSMaskStrength;
			
			float _Matcap3ALEnabled;
			float _Matcap3ALAlphaAddBand;
			float4 _Matcap3ALAlphaAdd;
			float _Matcap3ALEmissionAddBand;
			float4 _Matcap3ALEmissionAdd;
			float _Matcap3ALIntensityAddBand;
			float4 _Matcap3ALIntensityAdd;
			float _Matcap3ALChronoPanType;
			float _Matcap3ALChronoPanBand;
			float _Matcap3ALChronoPanSpeed;
			#endif
			//endex
			struct MatcapAudioLinkData
			{
				float matcapALEnabled;
				float matcapALAlphaAddBand;
				float4 matcapALAlphaAdd;
				float matcapALEmissionAddBand;
				float4 matcapALEmissionAdd;
				float matcapALIntensityAddBand;
				float4 matcapALIntensityAdd;
				float matcapALChronoPanType;
				float matcapALChronoPanBand;
				float matcapALChronoPanSpeed;
			};
			
			//ifex _CubeMapEnabled==0
			#ifdef _CUBEMAP
			#if defined(PROP_CUBEMAP) || !defined(OPTIMIZER_ENABLED)
			samplerCUBE _CubeMap;
			float3 _CubeMapRotation;
			float3 _CubeMapRotationPan;
			#endif
			#if defined(PROP_CUBEMAPMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _CubeMapMask;
			float4 _CubeMapMask_ST;
			float2 _CubeMapMaskPan;
			float _CubeMapMaskUV;
			float _CubeMapMaskChannel;
			#endif
			float _CubeMapUVMode;
			float _CubeMapWorldNormalsStrength;
			float _CubeMapMaskInvert;
			float _CubeMapMaskGlobalMask;
			float _CubeMapMaskGlobalMaskBlendType;
			float4 _CubeMapColor;
			float _CubeMapColorThemeIndex;
			float _CubeMapIntensity;
			float _CubemapBlendType;
			float _CubeMapBlendAmount;
			float _CubeMapEnable;
			float _CubeMapLightMask;
			float _CubeMapEmissionStrength;
			float _CubeMapNormal;
			float _CubeMapHueShiftEnabled;
			float _CubeMapHueShiftSpeed;
			float _CubeMapHueShift;
			float _CubeMapSaturation;
			float _CubeMapBrightness;
			float _CubeMapContrast;
			float _CubeMapSmoothness;
			#endif
			//endex
			
			//ifex _EnableALDecal==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_DECAL
			float _ALDecalUV;
			float4 _ALUVScale;
			float2 _ALUVPosition;
			float _ALUVRotation;
			float _ALUVRotationSpeed;
			float4 _ALDecaldCircleDimensions;
			
			float _ALDecalUVMode;
			
			float _ALDecalVolumeStep;
			float _ALDecalVolumeClipMin;
			float _ALDecalVolumeClipMax;
			
			float _ALDecalBandStep;
			float _ALDecalBandClipMin;
			float _ALDecalBandClipMax;
			
			float _ALDecalShapeClip;
			float _ALDecalShapeClipVolumeWidth;
			float _ALDecalShapeClipBandWidth;
			
			#if defined(PROP_ALDECALCOLORMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ALDecalColorMask;
			float4 _ALDecalColorMask_ST;
			float2 _ALDecalColorMaskPan;
			float _ALDecalColorMaskUV;
			#endif
			
			float _ALDecalVolume;
			float _ALDecalBaseBoost;
			float _ALDecalTrebleBoost;
			float _ALDecalLineWidth;
			float _ALDecalVolumeColorSource;
			float3 _ALDecalVolumeColorLow;
			float _ALDecalVolumeColorLowThemeIndex;
			float3 _ALDecalVolumeColorMid;
			float _ALDecalVolumeColorMidThemeIndex;
			float3 _ALDecalVolumeColorHigh;
			float _ALDecalVolumeColorHighThemeIndex;
			float _ALDecalLowEmission;
			float _ALDecalMidEmission;
			float _ALDecalHighEmission;
			float _ALDecalBlendType;
			float _ALDecalBlendAlpha;
			float _ALDecalControlsAlpha;
			float _ALDecalGlobalMask;
			float _ALDecalGlobalMaskBlendType;
			#endif
			#endif
			//endex
			
			//ifex _EnableVolumeColor==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_VOLUMECOLOR
			float _ALVolumeColorUV;
			float _ALVolumeColorDirection;
			float _ALVolumeColorBlendType;
			float _ALVolumeColorBlendAlpha;
			float3 _ALVolumeColorLow;
			float _ALVolumeColorLowThemeIndex;
			float3 _ALVolumeColorMid;
			float _ALVolumeColorMidThemeIndex;
			float3 _ALVolumeColorHigh;
			float _ALVolumeColorHighThemeIndex;
			float _ALLowEmission;
			float _ALMidEmission;
			float _ALHighEmission;
			#endif
			#endif
			//endex
			
			//ifex _EnableFlipbook==0
			#ifdef _SUNDISK_HIGH_QUALITY
			
			UNITY_DECLARE_TEX2DARRAY(_FlipbookTexArray);
			float4 _FlipbookTexArray_ST;
			
			float4 _FlipbookColor;
			float _FlipbookColorThemeIndex;
			float _FlipbookFPS;
			// float _FlipbookTotalFrames;
			float4 _FlipbookScaleOffset;
			float4 _FlipbookSideOffset;
			float _FlipbookTiled;
			float _FlipbookManualFrameControl;
			float _FlipbookCurrentFrame;
			float _FlipbookStartAndEnd;
			float _FlipbookStartFrame;
			float _FlipbookEndFrame;
			float _FlipbookEmissionStrength;
			float _FlipbookRotation;
			float _EnableFlipbook;
			float _FlipbookTexArrayUV;
			float _FlipbookAlphaControlsFinalAlpha;
			float _FlipbookRotationSpeed;
			float _FlipbookIntensityControlsAlpha;
			float _FlipbookColorReplaces;
			float2 _FlipbookTexArrayPan;
			float _FlipbookFrameOffset;
			// blending
			float _FlipbookReplace;
			float _FlipbookMultiply;
			float _FlipbookAdd;
			float _FlipbookBlendType;
			
			#if defined(PROP_FLIPBOOKMASSK) || !defined(OPTIMIZED_ENABLED)
			Texture2D _FlipbookMask;
			#endif
			float4 _FlipbookMask_ST;
			float2 _FlipbookMaskPan;
			float _FlipbookMaskUV;
			float _FlipbookMaskChannel;
			float _FlipbookMaskGlobalMask;
			float _FlipbookMaskGlobalMaskBlendType;
			
			// anim
			float _FlipbookMovementType;
			float4 _FlipbookStartEndOffset;
			float _FlipbookMovementSpeed;
			
			// Crossfade
			float _FlipbookCrossfadeEnabled;
			float2 _FlipbookCrossfadeRange;
			
			// Hueshift
			float _FlipbookHueShiftEnabled;
			float _FlipbookHueShiftSpeed;
			float _FlipbookHueShift;
			
			#ifdef POI_AUDIOLINK
			float _FlipbookChronotensityEnabled;
			float _FlipbookChronotensityBand;
			float _FlipbookChronotensitySpeed;
			float _FlipbookChronoType;
			half _AudioLinkFlipbookScaleBand;
			half4 _AudioLinkFlipbookScale;
			half _AudioLinkFlipbookAlphaBand;
			half2 _AudioLinkFlipbookAlpha;
			half _AudioLinkFlipbookEmissionBand;
			half2 _AudioLinkFlipbookEmission;
			half _AudioLinkFlipbookFrameBand;
			half2 _AudioLinkFlipbookFrame;
			#endif
			#endif
			//endex
			
			//ifex _EnableRimLighting==0
			#ifdef _GLOSSYREFLECTIONS_OFF
			float _Is_NormalMapToRimLight;
			float4 _RimLightColor;
			float _RimLightColorThemeIndex;
			#ifdef _RIMSTYLE_POIYOMI
			float _RimLightingInvert;
			float _RimWidth;
			float _RimStrength;
			float _RimSharpness;
			float _RimBaseColorMix;
			float _EnableRimLighting;
			float _RimWidthNoiseStrength;
			float4 _RimShadowAlpha;
			float _RimShadowWidth;
			float _RimBlendStrength;
			float _RimPoiBlendMode;
			float _RimShadowToggle;
			float _RimPower;
			float _RimShadowMaskStrength;
			float _RimShadowMaskRampType;
			float _RimShadowMaskInvert;
			float _RimBrightness;
			#if defined(PROP_RIMTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RimTex;
			#endif
			float4 _RimTex_ST;
			float2 _RimTexPan;
			float _RimTexUV;
			#if defined(PROP_RIMMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RimMask;
			#endif
			float4 _RimMask_ST;
			float2 _RimMaskPan;
			float _RimMaskUV;
			float _RimMaskChannel;
			float _RimMaskInvert;
			float _RimBiasIntensity;
			int _RimApplyAlpha;
			float _RimApplyAlphaBlend;
			#ifdef POI_AUDIOLINK
			half _AudioLinkRimWidthBand;
			float2 _AudioLinkRimWidthAdd;
			half _AudioLinkRimEmissionBand;
			float2 _AudioLinkRimEmissionAdd;
			half _AudioLinkRimBrightnessBand;
			float2 _AudioLinkRimBrightnessAdd;
			#endif
			#endif
			
			#ifdef _RIMSTYLE_UTS2
			float _RimLight;
			float _Is_LightColor_RimLight;
			float _RimLight_Power;
			float _RimLight_InsideMask;
			float _RimLight_FeatherOff;
			float _LightDirection_MaskOn;
			float _Tweak_LightDirection_MaskLevel;
			float _Add_Antipodean_RimLight;
			float4 _Ap_RimLightColor;
			float _RimApColorThemeIndex;
			float _Is_LightColor_Ap_RimLight;
			float _Ap_RimLight_Power;
			float _Ap_RimLight_FeatherOff;
			#if defined(PROP_SET_RIMLIGHTMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Set_RimLightMask;
			float4 _Set_RimLightMask_ST;
			float2 _Set_RimLightMaskPan;
			float _Set_RimLightMaskUV;
			float _Set_RimLightMaskChannel;
			#endif
			float _Tweak_RimLightMaskLevel;
			#endif
			
			#ifdef _RIMSTYLE_LILTOON
			float4 _RimColor;
			#if defined(PROP_RIMCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _RimColorTex;
			float4 _RimColorTex_ST;
			float2 _RimColorTexPan;
			float _RimColorTexUV;
			#endif
			float _RimMainStrength;
			float _RimNormalStrength;
			float _RimBorder;
			float _RimBlur;
			float _RimFresnelPower;
			float _RimEnableLighting;
			float _RimShadowMask;
			int _RimBackfaceMask;
			float _RimVRParallaxStrength;
			float _RimDirStrength;
			float _RimDirRange;
			float _RimIndirRange;
			float4 _RimIndirColor;
			float _RimIndirBorder;
			float _RimIndirBlur;
			int _RimBlendMode;
			#endif
			
			float _RimGlobalMask;
			float _RimGlobalMaskBlendType;
			float _RimApplyGlobalMaskIndex;
			float _RimApplyGlobalMaskBlendType;
			
			float _RimHueShiftEnabled;
			float _RimHueShiftSpeed;
			float _RimHueShift;
			#endif
			//endex
			//ifex _EnableRim2Lighting==0
			#ifdef POI_RIM2
			float _Is_NormalMapToRim2Light;
			float4 _Rim2LightColor;
			float _Rim2LightColorThemeIndex;
			
			#ifdef _RIM2STYLE_POIYOMI
			float _Rim2LightingInvert;
			float _Rim2Width;
			float _Rim2Strength;
			float _Rim2Sharpness;
			float _Rim2BaseColorMix;
			float _EnableRim2Lighting;
			float _Rim2WidthNoiseStrength;
			float4 _Rim2ShadowAlpha;
			float _Rim2ShadowWidth;
			float _Rim2BlendStrength;
			float _RimPoi2BlendMode;
			float _Rim2ShadowToggle;
			float _Rim2Power;
			float _Rim2ShadowMaskStrength;
			float _Rim2ShadowMaskRampType;
			float _Rim2ShadowMaskInvert;
			float _Rim2Brightness;
			#if defined(PROP_RIM2TEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Rim2Tex;
			#endif
			float4 _Rim2Tex_ST;
			float2 _Rim2TexPan;
			float _Rim2TexUV;
			#if defined(PROP_RIM2MASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Rim2Mask;
			#endif
			float4 _Rim2Mask_ST;
			float2 _Rim2MaskPan;
			float _Rim2MaskUV;
			float _Rim2MaskChannel;
			float _Rim2MaskInvert;
			float _Rim2BiasIntensity;
			int _Rim2ApplyAlpha;
			float _Rim2ApplyAlphaBlend;
			#if defined(PROP_RIM2WIDTHNOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Rim2WidthNoiseTexture;
			#endif
			#ifdef POI_AUDIOLINK
			half _AudioLinkRim2WidthBand;
			float2 _AudioLinkRim2WidthAdd;
			half _AudioLinkRim2EmissionBand;
			float2 _AudioLinkRim2EmissionAdd;
			half _AudioLinkRim2BrightnessBand;
			float2 _AudioLinkRim2BrightnessAdd;
			#endif
			#endif
			
			#ifdef _RIM2STYLE_UTS2
			float _Rim2Light;
			float _Is_LightColor_Rim2Light;
			float _Rim2Light_Power;
			float _Rim2Light_InsideMask;
			float _Rim2Light_FeatherOff;
			float _LightDirection_MaskOn2;
			float _Tweak_LightDirection_MaskLevel2;
			float _Add_Antipodean_Rim2Light;
			float4 _Ap_Rim2LightColor;
			float _Rim2ApColorThemeIndex;
			float _Is_LightColor_Ap_Rim2Light;
			float _Ap_Rim2Light_Power;
			float _Ap_Rim2Light_FeatherOff;
			#if defined(PROP_SET_RIM2LIGHTMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Set_Rim2LightMask;
			float4 _Set_Rim2LightMask_ST;
			float2 _Set_Rim2LightMaskPan;
			float _Set_Rim2LightMaskUV;
			float _Set_Rim2LightMaskChannel;
			#endif
			float _Tweak_Rim2LightMaskLevel;
			#endif
			
			#ifdef _RIM2STYLE_LILTOON
			float4 _Rim2Color;
			#if defined(PROP_RIM2COLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Rim2ColorTex;
			float4 _Rim2ColorTex_ST;
			float2 _Rim2ColorTexPan;
			float _Rim2ColorTexUV;
			#endif
			float _Rim2MainStrength;
			float _Rim2NormalStrength;
			float _Rim2Border;
			float _Rim2Blur;
			float _Rim2FresnelPower;
			float _Rim2EnableLighting;
			float _Rim2ShadowMask;
			int _Rim2BackfaceMask;
			float _Rim2VRParallaxStrength;
			// int _Rim2ApplyTransparency;
			float _Rim2DirStrength;
			float _Rim2DirRange;
			float _Rim2IndirRange;
			float4 _Rim2IndirColor;
			float _Rim2IndirBorder;
			float _Rim2IndirBlur;
			int _Rim2BlendMode;
			#endif
			
			float _Rim2GlobalMask;
			float _Rim2GlobalMaskBlendType;
			float _Rim2ApplyGlobalMaskIndex;
			float _Rim2ApplyGlobalMaskBlendType;
			
			float _Rim2HueShiftEnabled;
			float _Rim2HueShiftSpeed;
			float _Rim2HueShift;
			#endif
			//endex
			
			//ifex _EnableDepthRimLighting==0
			#ifdef _POI_DEPTH_RIMLIGHT
			float _DepthRimNormalToUse;
			float _DepthRimWidth;
			float _DepthRimSharpness;
			float _DepthRimHideInShadow;
			float4 _DepthRimColor;
			float _DepthRimColorThemeIndex;
			float _DepthRimMixBaseColor;
			float _DepthRimEmission;
			float _DepthRimReplace;
			float _DepthRimAdd;
			float _DepthRimMultiply;
			float _DepthRimAdditiveLighting;
			float _DepthRimMixLightColor;
			float _DepthRimType;
			float _DepthRimBrightness;
			
			static float2 sobelSamplePoints[9] = {
				float2(-1, 1), float2(0, 1), float2(1, 1),
				float2(-1, 0), float2(0, 0), float2(1, 01),
				float2(-1, -1), float2(0, -1), float2(1, -1)
			};
			
			static float sobelXMatrix[9] = {
				1, 0, -1,
				2, 0, -2,
				1, 0, -1
			};
			static float sobelYMatrix[9] = {
				1, 2, 1,
				0, 0, 0,
				- 1, -2, -1
			};
			#endif
			//endex
			
			//ifex _GlitterEnable==0
			#ifdef _SUNDISK_SIMPLE
			float4 _GlitterRandomRotationSpeed;
			float _GlitterLayers;
			float _GlitterUseNormals;
			float _GlitterUV;
			float4 _GlitterColor;
			float _GlitterColorThemeIndex;
			float2 _GlitterPan;
			half _GlitterSpeed;
			half _GlitterBrightness;
			float _GlitterFrequency;
			float _GlitterRandomLocation;
			half _GlitterSize;
			half _GlitterContrast;
			half _GlitterAngleRange;
			half _GlitterMinBrightness;
			half _GlitterBias;
			fixed _GlitterUseSurfaceColor;
			float _GlitterBlendType;
			float _GlitterMode;
			float _GlitterShape;
			float _GlitterCenterSize;
			float _GlitterJaggyFix;
			float _GlitterTextureRotation;
			float2 _GlitterUVPanning;
			
			float _GlitterHueShiftEnabled;
			float _GlitterHueShiftSpeed;
			float _GlitterHueShift;
			float _GlitterHideInShadow;
			float _GlitterScaleWithLighting;
			
			float _GlitterRandomColors;
			float2 _GlitterMinMaxSaturation;
			float2 _GlitterMinMaxBrightness;
			float _GlitterRandomSize;
			float4 _GlitterMinMaxSize;
			float _GlitterRandomRotation;
			
			#if defined(PROP_GLITTERMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlitterMask;
			#endif
			float4 _GlitterMask_ST;
			float2 _GlitterMaskPan;
			float _GlitterMaskUV;
			float _GlitterMaskChannel;
			float _GlitterMaskInvert;
			float _GlitterMaskGlobalMask;
			float _GlitterMaskGlobalMaskBlendType;
			#if defined(PROP_GLITTERCOLORMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlitterColorMap;
			#endif
			float4 _GlitterColorMap_ST;
			float2 _GlitterColorMapPan;
			float _GlitterColorMapUV;
			#if defined(PROP_GLITTERTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlitterTexture;
			#endif
			float4 _GlitterTexture_ST;
			float2 _GlitterTexturePan;
			float _GlitterTextureUV;
			
			float _GlitterALEnabled;
			float _GlitterALAlphaAddBand;
			float4 _GlitterALAlphaAdd;
			float _GlitterALMinBrightnessBand;
			float4 _GlitterALMinBrightnessAdd;
			float _GlitterALMaxBrightnessBand;
			float4 _GlitterALMaxBrightnessAdd;
			float _GlitterALSizeAddBand;
			float4 _GlitterALSizeAdd;
			float _GlitterALChronoSparkleSpeedType;
			float _GlitterALChronoSparkleSpeedBand;
			float _GlitterALChronoSparkleSpeed;
			float _GlitterALChronoRotationSpeedType;
			float _GlitterALChronoRotationSpeedBand;
			float _GlitterALChronoRotationSpeed;
			#endif
			//endex
			
			//ifex _SubsurfaceScattering==0
			#ifdef POI_SUBSURFACESCATTERING
			float4 _SSSColor;
			#if defined(PROP_SSSTHICKNESSMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _SSSThicknessMap;
			#endif
			float4 _SSSThicknessMap_ST;
			float2 _SSSThicknessMapPan;
			float _SSSThicknessMapUV;
			float _SSSThicknessMapChannel;
			
			float _SSSThicknessMod;
			float _SSSStrength;
			float _SSSSpread;
			float _SSSDistortion;
			float _SSSBaseColorMix;
			#endif
			//endex
			
			//ifex _MochieBRDF==0
			#ifdef MOCHIE_PBR
			#if defined(PROP_MOCHIEMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MochieMetallicMaps;
			float _PBRMapsStochastic;
			#endif
			float4 _MochieMetallicMaps_ST;
			float2 _MochieMetallicMapsPan;
			float _MochieMetallicMapsUV;
			float _MochieMetallicMapsStochastic;
			float _MochieMetallicMapInvert;
			float _MochieRoughnessMapInvert;
			float _MochieReflectionMaskInvert;
			float _MochieSpecularMaskInvert;
			float _MochieMetallicMapsMetallicChannel;
			float _MochieMetallicMapsRoughnessChannel;
			float _MochieMetallicMapsReflectionMaskChannel;
			float _MochieMetallicMapsSpecularMaskChannel;
			float _PBRNormalSelect;
			
			float _MochieReflectionTintThemeIndex;
			float _MochieSpecularTintThemeIndex;
			
			float _MochieRoughnessMultiplier;
			float _MochieMetallicMultiplier;
			float _MochieReflectionStrength;
			float _MochieSpecularStrength;
			float4 _MochieSpecularTint;
			float4 _MochieReflectionTint;
			float _MochieLitFallback;
			float _IgnoreCastedShadows;
			float _PBRSplitMaskSample;
			float _PBRSplitMaskStochastic;
			float4 _PBRMaskScaleTiling;
			float _MochieMetallicMasksUV;
			float4 _MochieMetallicMasksPan;
			
			float _Specular2ndLayer;
			float _MochieSpecularStrength2;
			float _MochieRoughnessMultiplier2;
			float _RefSpecFresnel;
			float _RefSpecFresnelBack;
			samplerCUBE _MochieReflCube;
			float4 _MochieReflCube_HDR;
			float _MochieForceFallback;
			float _MochieGSAAEnabled;
			float _PoiGSAAVariance;
			float _PoiGSAAThreshold;
			float _BRDFTPSReflectionMaskStrength;
			float _BRDFTPSSpecularMaskStrength;
			float _BRDFTPSDepthEnabled;
			
			float _MochieMetallicGlobalMask;
			float _MochieMetallicGlobalMaskBlendType;
			float _MochieSmoothnessGlobalMask;
			float _MochieSmoothnessGlobalMaskBlendType;
			float _MochieReflectionStrengthGlobalMask;
			float _MochieReflectionStrengthGlobalMaskBlendType;
			float _MochieSpecularStrengthGlobalMask;
			float _MochieSpecularStrengthGlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _ClearCoatBRDF==0
			#ifdef POI_CLEARCOAT
			#if defined(PROP_CLEARCOATMAPS) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ClearCoatMaps;
			float4 _ClearCoatMaps_ST;
			float2 _ClearCoatMapsPan;
			float _ClearCoatMapsUV;
			float _ClearCoatMapsStochastic;
			#endif
			float _ClearCoatMapsClearCoatMaskChannel;
			float _ClearCoatMapsRoughnessChannel;
			float _ClearCoatMapsReflectionMaskChannel;
			float _ClearCoatMapsSpecularMaskChannel;
			float _ClearCoatBRDF;
			float _ClearCoatReflectionStrength;
			float _ClearCoatSpecularStrength;
			float _ClearCoatStrength;
			float _ClearCoatSmoothness;
			float4 _ClearCoatReflectionTint;
			float _ClearCoatReflectionTintThemeIndex;
			float4 _ClearCoatSpecularTint;
			float _ClearCoatSpecularTintThemeIndex;
			float _ClearCoatSmoothnessMapInvert;
			float _ClearCoatMaskInvert;
			float _ClearCoatReflectionMaskInvert;
			float _ClearCoatSpecularMaskInvert;
			float _ClearCoatTPSMaskStrength;
			float _ClearCoatTPSDepthMaskEnabled;
			float _ClearCoatNormalSelect;
			
			samplerCUBE _ClearCoatFallback;
			float4 _ClearCoatFallback_HDR;
			float _ClearCoatForceFallback;
			float _ClearCoatLitFallback;
			float _CCIgnoreCastedShadows;
			float _ClearCoatGSAAEnabled;
			float _ClearCoatGSAAVariance;
			float _ClearCoatGSAAThreshold;
			float _ClearcoatFresnel;
			
			float _ClearCoatGlobalMask;
			float _ClearCoatGlobalMaskBlendType;
			float _ClearCoatSmoothnessGlobalMask;
			float _ClearCoatSmoothnessGlobalMaskBlendType;
			float _ClearCoatReflectionStrengthGlobalMask;
			float _ClearCoatReflectionStrengthGlobalMaskBlendType;
			float _ClearCoatSpecularStrengthGlobalMask;
			float _ClearCoatSpecularStrengthGlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _StylizedSpecular==0
			#ifdef POI_STYLIZED_StylizedSpecular
			#if defined(PROP_HIGHCOLOR_TEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _HighColor_Tex;
			#endif
			float4 _HighColor_Tex_ST;
			float2 _HighColor_TexPan;
			float _HighColor_TexUV;
			
			#if defined(PROP_SET_HIGHCOLORMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Set_HighColorMask;
			#endif
			float4 _Set_HighColorMask_ST;
			float2 _Set_HighColorMaskPan;
			float _Set_HighColorMaskUV;
			float _Set_HighColorMaskChannel;
			float _Tweak_HighColorMaskLevel;
			
			/*
			#if defined(PROP_StylizedSpecularOPTMAP1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _StylizedSpecularOptMap1;
			#endif
			float4 _StylizedSpecularOptMap1_ST;
			float2 _StylizedSpecularOptMap1Pan;
			float _StylizedSpecularOptMap1UV;
			
			#if defined(PROP_StylizedSpecularOPTMAP2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _StylizedSpecularOptMap2;
			#endif
			float4 _StylizedSpecularOptMap2_ST;
			float2 _StylizedSpecularOptMap2Pan;
			float _StylizedSpecularOptMap2UV;
			*/
			
			float4 _HighColor;
			float _UseLightColor;
			
			float _HighColor_Power;
			float _StylizedSpecularFeather;
			float _Layer1Strength;
			
			float _StylizedSpecularIgnoreNormal;
			float _StylizedSpecularIgnoreShadow;
			
			float _Layer2Size;
			float _StylizedSpecular2Feather;
			float _Layer2Strength;
			float _SSIgnoreCastedShadows;
			float _StylizedSpecularStrength;
			float _UseSpecularOptMap2;
			float _HighColorThemeIndex;
			float _Is_BlendAddToHiColor;
			float _Is_SpecularToHighColor;
			#endif
			//endex
			
			//ifex _EnablePathing==0
			#ifdef POI_PATHING
			
			#if defined(PROP_PATHINGMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _PathingMap;
			SamplerState SmpRepeatPoint;
			#endif
			float4 _PathingMap_ST;
			float2 _PathingMapPan;
			float _PathingMapUV;
			
			#if defined(PROP_PATHINGCOLORMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _PathingColorMap;
			#endif
			float4 _PathingColorMap_ST;
			float2 _PathingColorMapPan;
			float _PathingColorMapUV;
			float _PathingOverrideAlpha;
			// Fill, 0, Path, 1, Loop, 2
			float _PathTypeR;
			float _PathTypeG;
			float _PathTypeB;
			float _PathTypeA;
			float _PathGradientType;
			half4 _PathWidth;
			float4 _PathTime;
			float4 _PathOffset;
			float4 _PathSpeed;
			float4 _PathColorR;
			float4 _PathColorG;
			float4 _PathColorB;
			float4 _PathColorA;
			float4 _PathEmissionStrength;
			float4 _PathSoftness;
			float4 _PathSegments;
			
			float _PathColorRThemeIndex;
			float _PathColorGThemeIndex;
			float _PathColorBThemeIndex;
			float _PathColorAThemeIndex;
			
			#ifdef POI_AUDIOLINK
			float _PathALAutoCorrelator;
			float _PathALAutoCorrelatorMode;
			float _PathALAutoCorrelatorR;
			float2 _PathALAutoCorrelatorRangeR;
			float _PathALAutoCorrelatorG;
			float2 _PathALAutoCorrelatorRangeG;
			float _PathALAutoCorrelatorB;
			float2 _PathALAutoCorrelatorRangeB;
			float _PathALAutoCorrelatorA;
			float2 _PathALAutoCorrelatorRangeA;
			
			float _PathALHistory;
			float _PathALHistoryMode;
			float _PathALHistoryBandR;
			float2 _PathALHistoryRangeR;
			float _PathALHistoryR;
			float _PathALHistoryBandG;
			float2 _PathALHistoryRangeG;
			float _PathALHistoryG;
			float _PathALHistoryBandB;
			float2 _PathALHistoryRangeB;
			float _PathALHistoryB;
			float _PathALHistoryBandA;
			float2 _PathALHistoryRangeA;
			float _PathALHistoryA;
			
			float _PathALColorChord;
			float _PathALCCR;
			float _PathALCCG;
			float _PathALCCB;
			float _PathALCCA;
			
			// Time Offset
			float _PathALTimeOffset;
			half _AudioLinkPathTimeOffsetBandR;
			half2 _AudioLinkPathTimeOffsetR;
			half _AudioLinkPathTimeOffsetBandG;
			half2 _AudioLinkPathTimeOffsetG;
			half _AudioLinkPathTimeOffsetBandB;
			half2 _AudioLinkPathTimeOffsetB;
			half _AudioLinkPathTimeOffsetBandA;
			half2 _AudioLinkPathTimeOffsetA;
			
			// Emission Offset
			float _PathALEmissionOffset;
			half _AudioLinkPathEmissionAddBandR;
			half2 _AudioLinkPathEmissionAddR;
			half _AudioLinkPathEmissionAddBandG;
			half2 _AudioLinkPathEmissionAddG;
			half _AudioLinkPathEmissionAddBandB;
			half2 _AudioLinkPathEmissionAddB;
			half _AudioLinkPathEmissionAddBandA;
			half2 _AudioLinkPathEmissionAddA;
			
			// Length Offset
			float _PathALWidthOffset;
			half _AudioLinkPathWidthOffsetBandR;
			half2 _AudioLinkPathWidthOffsetR;
			half _AudioLinkPathWidthOffsetBandG;
			half2 _AudioLinkPathWidthOffsetG;
			half _AudioLinkPathWidthOffsetBandB;
			half2 _AudioLinkPathWidthOffsetB;
			half _AudioLinkPathWidthOffsetBandA;
			half2 _AudioLinkPathWidthOffsetA;
			
			// Chrono Time
			float _PathALChrono;
			float _PathChronoBandR;
			float _PathChronoTypeR;
			float _PathChronoSpeedR;
			float _PathChronoBandG;
			float _PathChronoTypeG;
			float _PathChronoSpeedG;
			float _PathChronoBandB;
			float _PathChronoTypeB;
			float _PathChronoSpeedB;
			float _PathChronoBandA;
			float _PathChronoTypeA;
			float _PathChronoSpeedA;
			#endif
			#endif
			//endex
			
			//ifex _EnableMirrorOptions==0
			#ifdef POI_MIRROR
			float _VisibilityMode;
			float _Mirror;
			#if defined(PROP_MIRRORTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MirrorTexture;
			#endif
			float4 _MirrorColor;
			float _MirrorColorThemeIndex;
			float _MirrorTextureBlendType;
			float4 _MirrorTexture_ST;
			float2 _MirrorTexturePan;
			float _MirrorTextureUV;
			float _MirrorTextureEnabled;
			float _MirrorTextureForceEnabled;
			float _VisibilityVRCRegular;
			float _VisibilityVRCMirrorVR;
			float _VisibilityVRCMirrorDesktop;
			float _VisibilityVRCCameraVR;
			float _VisibilityVRCCameraDesktop;
			float _VisibilityVRCCameraScreenshot;
			#endif
			//endex
			
			//ifex _EnableTouchGlow==0
			#ifdef GRAIN
			#if defined(PROP_DEPTHMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DepthMask;
			#endif
			float4 _DepthMask_ST;
			float2 _DepthMaskPan;
			float _DepthMaskUV;
			float _DepthMaskChannel;
			float _DepthMaskGlobalMask;
			float _DepthMaskGlobalMaskBlendType;
			
			// Color
			float _DepthColorToggle;
			float _DepthColorBlendMode;
			#if defined(PROP_DEPTHTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DepthTexture;
			#endif
			float4 _DepthTexture_ST;
			float2 _DepthTexturePan;
			float _DepthTextureUV;
			
			float3 _DepthColor;
			float _DepthColorThemeIndex;
			float _DepthColorMinDepth;
			float _DepthColorMaxDepth;
			float _DepthColorMinValue;
			float _DepthColorMaxValue;
			float _DepthEmissionStrength;
			
			// Emission
			
			// Alpha
			float _DepthAlphaToggle;
			float _DepthAlphaMinValue;
			float _DepthAlphaMaxValue;
			float _DepthAlphaMinDepth;
			float _DepthAlphaMaxDepth;
			#endif
			//endex
			
			//ifex _TextEnabled==0
			#ifdef EFFECT_BUMP
			sampler2D _TextGlyphs;
			float4 _TextGlyphs_ST;
			float4 _TextGlyphs_TexelSize;
			float _TextFPSUV;
			float _TextTimeUV;
			float _TextPositionUV;
			float _TextNumericUV;
			float _TextPixelRange;
			
			float _TextFPSEnabled;
			float _TextPositionEnabled;
			float _TextTimeEnabled;
			float _TextNumericEnabled;
			
			float4 _TextFPSColor;
			float _TextFPSEmissionStrength;
			fixed4 _TextFPSPadding;
			float2 _TextFPSOffset;
			float2 _TextFPSScale;
			float _TextFPSRotation;
			float _TextFPSOutlineColor;
			
			fixed _TextPositionVertical;
			float4 _TextPositionColor;
			float _TextPositionEmissionStrength;
			fixed4 _TextPositionPadding;
			float2 _TextPositionOffset;
			float2 _TextPositionScale;
			float _TextPositionRotation;
			
			float4 _TextTimeColor;
			float _TextTimeEmissionStrength;
			fixed4 _TextTimePadding;
			float2 _TextTimeOffset;
			float2 _TextTimeScale;
			float _TextTimeRotation;
			
			float4 _TextNumericColor;
			float _TextNumericEmissionStrength;
			fixed4 _TextNumericPadding;
			float2 _TextNumericOffset;
			float2 _TextNumericScale;
			float _TextNumericRotation;
			float _TextNumericValue;
			float _TextNumericWholeDigits;
			float _TextNumericDecimalDigits;
			float _TextNumericTrimZeroes;
			
			float _TextFPSColorThemeIndex;
			float _TextPositionColorThemeIndex;
			float _TextTimeColorThemeIndex;
			float _TextNumericColorThemeIndex;
			
			float3 globalTextEmission;
			
			#define ASCII_SPACE 32
			#define ASCII_LEFT_PARENTHESIS 40
			#define ASCII_RIGHT_PARENTHESIS 41
			#define ASCII_POSITIVE 43
			#define ASCII_PERIOD 46
			#define ASCII_NEGATIVE 45
			#define ASCII_COMMA 44
			#define ASCII_E 69
			#define ASCII_F 70
			#define ASCII_I 73
			#define ASCII_M 77
			#define ASCII_O 79
			#define ASCII_P 80
			#define ASCII_R 82
			#define ASCII_S 83
			#define ASCII_T 84
			#define ASCII_SEMICOLON 58
			#define glyphWidth 0.0625
			
			#endif
			//endex
			
			//ifex _FXProximityColor==0
			float _FXProximityColor;
			float _FXProximityColorType;
			float3 _FXProximityColorMinColor;
			float3 _FXProximityColorMaxColor;
			float _FXProximityColorMinColorThemeIndex;
			float _FXProximityColorMaxColorThemeIndex;
			float _FXProximityColorMinDistance;
			float _FXProximityColorMaxDistance;
			float _FXProximityColorBackFace;
			//endex
			
			//ifex _PostProcess==0
			#ifdef POSTPROCESS
			#if defined(PROP_PPMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _PPMask;
			#endif
			float4 _PPMask_ST;
			float2 _PPMaskPan;
			float _PPMaskUV;
			float _PPMaskChannel;
			float _PPMaskInvert;
			
			float3 _PPTint;
			float3 _PPRGB;
			float _PPHue;
			float _PPContrast;
			float _PPSaturation;
			float _PPBrightness;
			float _PPLightness;
			float _PPHDR;
			
			float _PPPosterization;
			float _PPPosterizationAmount;
			const static float COLORS = 32;
			
			#endif
			//endex
			
			//ifex _NormalCorrect==0
			#ifdef POI_NORMALCORRECT
			float _NormalCorrectAmount;
			float3 _NormalCorrectOrigin;
			#endif
			//endex
			
			//ifex _VideoEffectsEnable==0
			#ifdef POI_VIDEO_EFFECTS
			float _VideoEffectsEnable;
			#if defined(PROP_VIDEOPIXELTEXTURE) || !defined(OPTIMIZER_ENABLED)
			sampler2D _VideoPixelTexture;
			float4 _VideoPixelTexture_ST;
			float _VideoPixelTextureUV;
			#endif
			#if defined(PROP_VIDEOMASKTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VideoMaskTexture;
			float4 _VideoMaskTexture_ST;
			float2 _VideoMaskTexturePan;
			float _VideoMaskTextureUV;
			float _VideoMaskTextureChannel;
			#endif
			
			float _VideoType;
			float2 _VideoResolution;
			sampler2D _VideoGameboyRamp;
			float _VideoBacklight;
			float _VideoCRTRefreshRate;
			float _VideoCRTPixelEnergizedTime;
			float _VideoRepeatVideoTexture;
			float _VideoPixelateToResolution;
			float2 _VideoMaskPanning;
			
			float _VideoSaturation;
			float _VideoContrast;
			float _VideoEmissionEnabled;
			#endif
			//endex
			
			//ifex _BacklightEnabled!=1
			#ifdef POI_BACKLIGHT
			float4 _BacklightColor;
			#if defined(PROP_BACKLIGHTCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BacklightColorTex;
			float4 _BacklightColorTex_ST;
			float2 _BacklightColorTexPan;
			float _BacklightColorTexUV;
			#endif
			float _BacklightMainStrength;
			float _BacklightNormalStrength;
			float _BacklightBorder;
			float _BacklightBlur;
			float _BacklightDirectivity;
			float _BacklightViewStrength;
			int _BacklightReceiveShadow;
			int _BacklightBackfaceMask;
			#endif
			//endex
			
			//ifex _BSSEnabled!=1
			#ifdef POIBS_ENABLE
			float _CustomColors;
			//ifex _BSSBloomfog!=1
			#ifdef POIBS_BLOOMFOG
			float _FogStartOffset;
			float _FogScale;
			float _FogHeightOffset;
			float _FogHeightScale;
			
			uniform float2 _CustomFogTextureToScreenRatio;
			uniform float _StereoCameraEyeOffset;
			
			uniform float _CustomFogOffset;
			uniform float _CustomFogAttenuation;
			uniform float _CustomFogHeightFogStartY;
			uniform float _CustomFogHeightFogHeight;
			uniform sampler2D _BloomPrePassTexture;
			#endif
			//endex
			#endif
			//endex
			
			//ifex _VoronoiEnabled!=1
			#ifdef POI_VORONOI
			#if defined(PROP_VORONOIMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VoronoiMask;
			float4 _VoronoiMask_ST;
			float2 _VoronoiMaskPan;
			float _VoronoiMaskUV;
			int _VoronoiMaskChannel;
			#endif
			#if defined(PROP_VORONOINOISE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VoronoiNoise;
			float4 _VoronoiNoise_ST;
			float2 _VoronoiNoisePan;
			float _VoronoiNoiseUV;
			int _VoronoiNoiseChannel;
			#endif
			int _VoronoiSpace;
			int _VoronoiBlend;
			int _VoronoiType;
			float4 _VoronoiOuterColor;
			float _VoronoiOuterEmissionStrength;
			float4 _VoronoiInnerColor;
			float _VoronoiInnerEmissionStrength;
			float _VoronoiPower;
			float2 _VoronoiGradient;
			float _VoronoiScale;
			float3 _VoronoiSpeed;
			float _VoronoiEnableRandomCellColor;
			float2 _VoronoiRandomMinMaxSaturation;
			float2 _VoronoiRandomMinMaxBrightness;
			float _VoronoiNoiseIntensity;
			int _VoronoiAffectsMaterialAlpha;
			float _VoronoiGlobalMask;
			float _VoronoiGlobalMaskBlendType;
			
			// AudioLink
			int _AudioLinkVoronoiInnerEmissionBand;
			float2 _AudioLinkVoronoiInnerEmission;
			int _AudioLinkVoronoiOuterEmissionBand;
			float2 _AudioLinkVoronoiOuterEmission;
			
			int _AudioLinkVoronoiGradientMinAddBand;
			float _AudioLinkVoronoiGradientMinAdd;
			int _AudioLinkVoronoiGradientMaxAddBand;
			float _AudioLinkVoronoiGradientMaxAdd;
			
			int _AudioLinkVoronoiChronoSpeedXType;
			int _AudioLinkVoronoiChronoSpeedXBand;
			float _AudioLinkVoronoiChronoSpeedXSpeed;
			int _AudioLinkVoronoiChronoSpeedYType;
			int _AudioLinkVoronoiChronoSpeedYBand;
			float _AudioLinkVoronoiChronoSpeedYSpeed;
			int _AudioLinkVoronoiChronoSpeedZType;
			int _AudioLinkVoronoiChronoSpeedZBand;
			float _AudioLinkVoronoiChronoSpeedZSpeed;
			#endif
			//endex
			
			struct appdata
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 tangent : TANGENT;
				float4 color : COLOR;
				float2 uv0 : TEXCOORD0;
				float2 uv1 : TEXCOORD1;
				float2 uv2 : TEXCOORD2;
				float2 uv3 : TEXCOORD3;
				uint vertexId : SV_VertexID;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};
			
			struct VertexOut
			{
				float4 pos : SV_POSITION;
				float4 uv[2] : TEXCOORD0;
				float3 normal : TEXCOORD2;
				float4 tangent : TEXCOORD3;
				float4 worldPos : TEXCOORD4;
				float4 localPos : TEXCOORD5;
				float4 vertexColor : TEXCOORD6;
				float4 lightmapUV : TEXCOORD7;
				float2 fogCoord: TEXCOORD10;
				UNITY_SHADOW_COORDS(11)
				
				UNITY_VERTEX_INPUT_INSTANCE_ID
				UNITY_VERTEX_OUTPUT_STEREO
			};
			
			struct PoiMesh
			{
				
				// 0 Vertex normal
				// 1 Fragment normal
				float3 normals[2];
				float3 objNormal;
				float3 tangentSpaceNormal;
				float3 binormal[2];
				float3 tangent[2];
				float3 worldPos;
				float3 localPos;
				float3 objectPosition;
				float isFrontFace;
				float4 vertexColor;
				float4 lightmapUV;
				// 0-3 UV0-UV3
				// 4 Panosphere UV
				// 5 world pos xz
				// 6 Polar UV
				// 7 Distorted UV
				float2 uv[9];
				float2 parallaxUV;
				float2 dx;
				float2 dy;
			};
			
			struct PoiCam
			{
				float3 viewDir;
				float3 forwardDir;
				float3 worldPos;
				float distanceToVert;
				float4 clipPos;
				float4 screenSpacePosition;
				float3 reflectionDir;
				float3 vertexReflectionDir;
				float3 tangentViewDir;
				float4 posScreenSpace;
				float2 posScreenPixels;
				float2 screenUV;
				float vDotN;
				float4 worldDirection;
				
			};
			
			struct PoiMods
			{
				float4 Mask;
				float audioLink[5];
				float audioLinkAvailable;
				float audioLinkVersion;
				float4 audioLinkTexture;
				float2 detailMask;
				float2 backFaceDetailIntensity;
				float globalEmission;
				float4 globalColorTheme[12];
				float globalMask[16];
				float ALTime[8];
			};
			
			struct PoiLight
			{
				
				float3 direction;
				float attenuation;
				float attenuationStrength;
				float3 directColor;
				float3 indirectColor;
				float occlusion;
				float shadowMask;
				float detailShadow;
				float3 halfDir;
				float lightMap;
				float lightMapNoAttenuation;
				float3 rampedLightMap;
				float vertexNDotL;
				float nDotL;
				float nDotV;
				float vertexNDotV;
				float nDotH;
				float vertexNDotH;
				float lDotv;
				float lDotH;
				float nDotLSaturated;
				float nDotLNormalized;
				#ifdef POI_PASS_ADD
				float additiveShadow;
				#endif
				float3 finalLighting;
				float3 finalLightAdd;
				float3 LTCGISpecular;
				float3 LTCGIDiffuse;
				float directLuminance;
				float indirectLuminance;
				float finalLuminance;
				
				#if defined(VERTEXLIGHT_ON)
				// Non Important Lights
				float4 vDotNL;
				float4 vertexVDotNL;
				float3 vColor[4];
				float4 vCorrectedDotNL;
				float4 vAttenuation;
				float4 vSaturatedDotNL;
				float3 vPosition[4];
				float3 vDirection[4];
				float3 vFinalLighting;
				float3 vHalfDir[4];
				half4 vDotNH;
				half4 vertexVDotNH;
				half4 vDotLH;
				#endif
				
			};
			
			struct PoiVertexLights
			{
				
				float3 direction;
				float3 color;
				float attenuation;
			};
			
			struct PoiFragData
			{
				float smoothness;
				float smoothness2;
				float metallic;
				float specularMask;
				float reflectionMask;
				
				float3 baseColor;
				float3 finalColor;
				float alpha;
				float3 emission;
				float toggleVertexLights;
			};
			
			float4 poiTransformClipSpacetoScreenSpaceFrag(float4 clipPos)
			{
				float4 positionSS = float4(clipPos.xyz * clipPos.w, clipPos.w);
				positionSS.xy = positionSS.xy / _ScreenParams.xy;
				return positionSS;
			}
			
			// glsl_mod behaves better on negative numbers, and
			// in some situations actually outperforms HLSL's fmod()
			#ifndef glsl_mod
			#define glsl_mod(x, y) (((x) - (y) * floor((x) / (y))))
			#endif
			
			uniform float random_uniform_float_only_used_to_stop_compiler_warnings = 0.0f;
			
			float2 poiUV(float2 uv, float4 tex_st)
			{
				return uv * tex_st.xy + tex_st.zw;
			}
			
			float2 vertexUV(in VertexOut o, int index)
			{
				switch(index)
				{
					case 0:
					return o.uv[0].xy;
					case 1:
					return o.uv[0].zw;
					case 2:
					return o.uv[1].xy;
					case 3:
					return o.uv[1].zw;
					default:
					return o.uv[0].xy;
				}
			}
			
			float2 vertexUV(in appdata v, int index)
			{
				switch(index)
				{
					case 0:
					return v.uv0.xy;
					case 1:
					return v.uv1.xy;
					case 2:
					return v.uv2.xy;
					case 3:
					return v.uv3.xy;
					default:
					return v.uv0.xy;
				}
			}
			
			//Lighting Helpers
			float calculateluminance(float3 color)
			{
				return color.r * 0.299 + color.g * 0.587 + color.b * 0.114;
			}
			
			// Set by VRChat (as of open beta 1245)
			// _VRChatCameraMode: 0 => Normal, 1 => VR HandCam, 2 => Desktop Handcam, 3 => Screenshot/Photo
			// _VRChatMirrorMode: 0 => Normal, 1 => Mirror (VR), 2 => Mirror (Deskie)
			float _VRChatCameraMode;
			float _VRChatMirrorMode;
			
			float VRCCameraMode()
			{
				return _VRChatCameraMode;
			}
			
			float VRCMirrorMode()
			{
				return _VRChatMirrorMode;
			}
			
			bool IsInMirror()
			{
				return unity_CameraProjection[2][0] != 0.f || unity_CameraProjection[2][1] != 0.f;
			}
			
			bool IsOrthographicCamera()
			{
				return unity_OrthoParams.w == 1 || UNITY_MATRIX_P[3][3] == 1;
			}
			
			float shEvaluateDiffuseL1Geomerics_local(float L0, float3 L1, float3 n)
			{
				// average energy
				float R0 = max(0, L0);
				
				// avg direction of incoming light
				float3 R1 = 0.5f * L1;
				
				// directional brightness
				float lenR1 = length(R1);
				
				// linear angle between normal and direction 0-1
				//float q = 0.5f * (1.0f + dot(R1 / lenR1, n));
				//float q = dot(R1 / lenR1, n) * 0.5 + 0.5;
				float q = dot(normalize(R1), n) * 0.5 + 0.5;
				q = saturate(q); // Thanks to ScruffyRuffles for the bug identity.
				
				// power for q
				// lerps from 1 (linear) to 3 (cubic) based on directionality
				float p = 1.0f + 2.0f * lenR1 / R0;
				
				// dynamic range constant
				// should vary between 4 (highly directional) and 0 (ambient)
				float a = (1.0f - lenR1 / R0) / (1.0f + lenR1 / R0);
				
				return R0 * (a + (1.0f - a) * (p + 1.0f) * pow(q, p));
			}
			
			half3 BetterSH9(half4 normal)
			{
				float3 indirect;
				float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) + float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0;
				indirect.r = shEvaluateDiffuseL1Geomerics_local(L0.r, unity_SHAr.xyz, normal.xyz);
				indirect.g = shEvaluateDiffuseL1Geomerics_local(L0.g, unity_SHAg.xyz, normal.xyz);
				indirect.b = shEvaluateDiffuseL1Geomerics_local(L0.b, unity_SHAb.xyz, normal.xyz);
				indirect = max(0, indirect);
				indirect += SHEvalLinearL2(normal);
				return indirect;
			}
			
			// Silent's code ends here
			
			float3 getCameraForward()
			{
				#if UNITY_SINGLE_PASS_STEREO
				float3 p1 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 1, 1));
				float3 p2 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 0, 1));
				#else
				float3 p1 = mul(unity_CameraToWorld, float4(0, 0, 1, 1)).xyz;
				float3 p2 = mul(unity_CameraToWorld, float4(0, 0, 0, 1)).xyz;
				#endif
				return normalize(p2 - p1);
			}
			
			half3 GetSHLength()
			{
				half3 x, x1;
				x.r = length(unity_SHAr);
				x.g = length(unity_SHAg);
				x.b = length(unity_SHAb);
				x1.r = length(unity_SHBr);
				x1.g = length(unity_SHBg);
				x1.b = length(unity_SHBb);
				return x + x1;
			}
			
			float3 BoxProjection(float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax)
			{
				#if UNITY_SPECCUBE_BOX_PROJECTION
				//UNITY_BRANCH
				if (cubemapPosition.w > 0)
				{
					float3 factors = ((direction > 0 ? boxMax : boxMin) - position) / direction;
					float scalar = min(min(factors.x, factors.y), factors.z);
					direction = direction * scalar + (position - cubemapPosition.xyz);
				}
				#endif
				return direction;
			}
			
			float poiMax(float2 i)
			{
				return max(i.x, i.y);
			}
			
			float poiMax(float3 i)
			{
				return max(max(i.x, i.y), i.z);
			}
			
			float poiMax(float4 i)
			{
				return max(max(max(i.x, i.y), i.z), i.w);
			}
			
			float3 calculateNormal(in float3 baseNormal, in PoiMesh poiMesh, in Texture2D normalTexture, in float4 normal_ST, in float2 normalPan, in float normalUV, in float normalIntensity)
			{
				float3 normal = UnpackScaleNormal(POI2D_SAMPLER_PAN(normalTexture, _MainTex, poiUV(poiMesh.uv[normalUV], normal_ST), normalPan), normalIntensity);
				return normalize(
				normal.x * poiMesh.tangent[0] +
				normal.y * poiMesh.binormal[0] +
				normal.z * baseNormal
				);
			}
			
			float remap(float x, float minOld, float maxOld, float minNew = 0, float maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float2 remap(float2 x, float2 minOld, float2 maxOld, float2 minNew = 0, float2 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float3 remap(float3 x, float3 minOld, float3 maxOld, float3 minNew = 0, float3 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float4 remap(float4 x, float4 minOld, float4 maxOld, float4 minNew = 0, float4 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float remapClamped(float minOld, float maxOld, float x, float minNew = 0, float maxNew = 1)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float2 remapClamped(float2 minOld, float2 maxOld, float2 x, float2 minNew, float2 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float3 remapClamped(float3 minOld, float3 maxOld, float3 x, float3 minNew, float3 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float4 remapClamped(float4 minOld, float4 maxOld, float4 x, float4 minNew, float4 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			float2 calcParallax(in float height, in PoiCam poiCam)
			{
				return ((height * - 1) + 1) * (poiCam.tangentViewDir.xy / poiCam.tangentViewDir.z);
			}
			
			/*
			0: Zero	                float4(0.0, 0.0, 0.0, 0.0),
			1: One	                float4(1.0, 1.0, 1.0, 1.0),
			2: DstColor	            destinationColor,
			3: SrcColor	            sourceColor,
			4: OneMinusDstColor	    float4(1.0, 1.0, 1.0, 1.0) - destinationColor,
			5: SrcAlpha	            sourceColor.aaaa,
			6: OneMinusSrcColor	    float4(1.0, 1.0, 1.0, 1.0) - sourceColor,
			7: DstAlpha	            destinationColor.aaaa,
			8: OneMinusDstAlpha	    float4(1.0, 1.0, 1.0, 1.0) - destinationColor.,
			9: SrcAlphaSaturate     saturate(sourceColor.aaaa),
			10: OneMinusSrcAlpha	float4(1.0, 1.0, 1.0, 1.0) - sourceColor.aaaa,
			*/
			
			float4 poiBlend(const float sourceFactor, const  float4 sourceColor, const  float destinationFactor, const  float4 destinationColor, const float4 blendFactor)
			{
				float4 sA = 1 - blendFactor;
				const float4 blendData[11] = {
					float4(0.0, 0.0, 0.0, 0.0),
					float4(1.0, 1.0, 1.0, 1.0),
					destinationColor,
					sourceColor,
					float4(1.0, 1.0, 1.0, 1.0) - destinationColor,
					sA,
					float4(1.0, 1.0, 1.0, 1.0) - sourceColor,
					sA,
					float4(1.0, 1.0, 1.0, 1.0) - sA,
					saturate(sourceColor.aaaa),
					1 - sA,
				};
				
				return lerp(blendData[sourceFactor] * sourceColor + blendData[destinationFactor] * destinationColor, sourceColor, sA);
			}
			
			// Average
			float blendAverage(float base, float blend)
			{
				return (base + blend) / 2.0;
			}
			float3 blendAverage(float3 base, float3 blend)
			{
				return (base + blend) / 2.0;
			}
			
			// Color burn
			float blendColorBurn(float base, float blend)
			{
				return (blend == 0.0) ? blend : max((1.0 - ((1.0 - base) * rcp(random_uniform_float_only_used_to_stop_compiler_warnings + blend))), 0.0);
			}
			
			float3 blendColorBurn(float3 base, float3 blend)
			{
				return float3(blendColorBurn(base.r, blend.r), blendColorBurn(base.g, blend.g), blendColorBurn(base.b, blend.b));
			}
			
			// Color Dodge
			float blendColorDodge(float base, float blend)
			{
				return (blend == 1.0) ? blend : min(base / (1.0 - blend), 1.0);
			}
			
			float3 blendColorDodge(float3 base, float3 blend)
			{
				return float3(blendColorDodge(base.r, blend.r), blendColorDodge(base.g, blend.g), blendColorDodge(base.b, blend.b));
			}
			
			// Darken
			float blendDarken(float base, float blend)
			{
				return min(blend, base);
			}
			
			float3 blendDarken(float3 base, float3 blend)
			{
				return float3(blendDarken(base.r, blend.r), blendDarken(base.g, blend.g), blendDarken(base.b, blend.b));
			}
			
			// Exclusion
			float blendExclusion(float base, float blend)
			{
				return base + blend - 2.0 * base * blend;
			}
			float3 blendExclusion(float3 base, float3 blend)
			{
				return base + blend - 2.0 * base * blend;
			}
			
			// Reflect
			float blendReflect(float base, float blend)
			{
				return (blend == 1.0) ? blend : min(base * base / (1.0 - blend), 1.0);
			}
			
			float3 blendReflect(float3 base, float3 blend)
			{
				return float3(blendReflect(base.r, blend.r), blendReflect(base.g, blend.g), blendReflect(base.b, blend.b));
			}
			
			// Glow
			float blendGlow(float base, float blend)
			{
				return blendReflect(blend, base);
			}
			float3 blendGlow(float3 base, float3 blend)
			{
				return blendReflect(blend, base);
			}
			
			// Overlay
			float blendOverlay(float base, float blend)
			{
				return base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend));
			}
			
			float3 blendOverlay(float3 base, float3 blend)
			{
				return float3(blendOverlay(base.r, blend.r), blendOverlay(base.g, blend.g), blendOverlay(base.b, blend.b));
			}
			
			// Hard Light
			float blendHardLight(float base, float blend)
			{
				return blendOverlay(blend, base);
			}
			float3 blendHardLight(float3 base, float3 blend)
			{
				return blendOverlay(blend, base);
			}
			
			// Vivid light
			float blendVividLight(float base, float blend)
			{
				return (blend < 0.5) ? blendColorBurn(base, (2.0 * blend)) : blendColorDodge(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendVividLight(float3 base, float3 blend)
			{
				return float3(blendVividLight(base.r, blend.r), blendVividLight(base.g, blend.g), blendVividLight(base.b, blend.b));
			}
			
			// Hard mix
			float blendHardMix(float base, float blend)
			{
				return (blendVividLight(base, blend) < 0.5) ? 0.0 : 1.0;
			}
			
			float3 blendHardMix(float3 base, float3 blend)
			{
				return float3(blendHardMix(base.r, blend.r), blendHardMix(base.g, blend.g), blendHardMix(base.b, blend.b));
			}
			
			// Lighten
			float blendLighten(float base, float blend)
			{
				return max(blend, base);
			}
			
			float3 blendLighten(float3 base, float3 blend)
			{
				return float3(blendLighten(base.r, blend.r), blendLighten(base.g, blend.g), blendLighten(base.b, blend.b));
			}
			
			// Linear Burn
			float blendLinearBurn(float base, float blend)
			{
				// Note : Same implementation as BlendSubtractf
				return max(base + blend - 1.0, 0.0);
			}
			
			float3 blendLinearBurn(float3 base, float3 blend)
			{
				// Note : Same implementation as BlendSubtract
				return max(base + blend - float3(1.0, 1.0, 1.0), float3(0.0, 0.0, 0.0));
			}
			
			// Linear Dodge
			float blendLinearDodge(float base, float blend)
			{
				// Note : Same implementation as BlendAddf
				return min(base + blend, 1.0);
			}
			
			float3 blendLinearDodge(float3 base, float3 blend)
			{
				// Note : Same implementation as BlendAdd
				return base + blend;
			}
			
			// Linear light
			float blendLinearLight(float base, float blend)
			{
				return blend < 0.5 ? blendLinearBurn(base, (2.0 * blend)) : blendLinearDodge(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendLinearLight(float3 base, float3 blend)
			{
				return float3(blendLinearLight(base.r, blend.r), blendLinearLight(base.g, blend.g), blendLinearLight(base.b, blend.b));
			}
			
			// Multiply
			float blendMultiply(float base, float blend)
			{
				return base * blend;
			}
			float3 blendMultiply(float3 base, float3 blend)
			{
				return base * blend;
			}
			
			// Negation
			float blendNegation(float base, float blend)
			{
				return 1.0 - abs(1.0 - base - blend);
			}
			float3 blendNegation(float3 base, float3 blend)
			{
				return float3(1.0, 1.0, 1.0) - abs(float3(1.0, 1.0, 1.0) - base - blend);
			}
			
			// Normal
			float blendNormal(float base, float blend)
			{
				return blend;
			}
			float3 blendNormal(float3 base, float3 blend)
			{
				return blend;
			}
			
			// Phoenix
			float blendPhoenix(float base, float blend)
			{
				return min(base, blend) - max(base, blend) + 1.0;
			}
			float3 blendPhoenix(float3 base, float3 blend)
			{
				return min(base, blend) - max(base, blend) + float3(1.0, 1.0, 1.0);
			}
			
			// Pin light
			float blendPinLight(float base, float blend)
			{
				return (blend < 0.5) ? blendDarken(base, (2.0 * blend)) : blendLighten(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendPinLight(float3 base, float3 blend)
			{
				return float3(blendPinLight(base.r, blend.r), blendPinLight(base.g, blend.g), blendPinLight(base.b, blend.b));
			}
			
			// Screen
			float blendScreen(float base, float blend)
			{
				return 1.0 - ((1.0 - base) * (1.0 - blend));
			}
			
			float3 blendScreen(float3 base, float3 blend)
			{
				return float3(blendScreen(base.r, blend.r), blendScreen(base.g, blend.g), blendScreen(base.b, blend.b));
			}
			
			// Soft Light
			float blendSoftLight(float base, float blend)
			{
				return (blend < 0.5) ? (2.0 * base * blend + base * base * (1.0 - 2.0 * blend)) : (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend));
			}
			
			float3 blendSoftLight(float3 base, float3 blend)
			{
				return float3(blendSoftLight(base.r, blend.r), blendSoftLight(base.g, blend.g), blendSoftLight(base.b, blend.b));
			}
			
			// Subtract
			float blendSubtract(float base, float blend)
			{
				return max(base - blend, 0.0);
			}
			
			float3 blendSubtract(float3 base, float3 blend)
			{
				return max(base - blend, 0.0);
			}
			
			// Difference
			float blendDifference(float base, float blend)
			{
				return abs(base - blend);
			}
			
			float3 blendDifference(float3 base, float3 blend)
			{
				return abs(base - blend);
			}
			
			// Divide
			float blendDivide(float base, float blend)
			{
				return base / max(blend, 0.0001);
			}
			
			float3 blendDivide(float3 base, float3 blend)
			{
				return base / max(blend, 0.0001);
			}
			
			float blendMixed(float base, float blend)
			{
				return base + base * blend;
			}
			
			float3 blendMixed(float3 base, float3 blend)
			{
				return base + base * blend;
			}
			
			float3 customBlend(float3 base, float3 blend, float blendType, float alpha = 1)
			{
				float3 output = base;
				switch(blendType)
				{
					case 0: output = lerp(base, blend, alpha); break;
					case 1: output = lerp(base, blendDarken(base, blend), alpha); break;
					case 2: output = base * lerp(1, blend, alpha); break;
					case 5: output = lerp(base, blendLighten(base, blend), alpha); break;
					case 6: output = lerp(base, blendScreen(base, blend), alpha); break;
					case 7: output = blendSubtract(base, blend * alpha); break;
					case 8: output = lerp(base, blendLinearDodge(base, blend), alpha); break;
					case 9: output = lerp(base, blendOverlay(base, blend), alpha); break;
					case 20: output = lerp(base, blendMixed(base, blend), alpha); break;
					default: output = 0; break;
				}
				return output;
			}
			
			float3 customBlend(float base, float blend, float blendType, float alpha = 1)
			{
				float3 output = base;
				switch(blendType)
				{
					case 0: output = lerp(base, blend, alpha); break;
					case 2: output = base * lerp(1, blend, alpha); break;
					case 5: output = lerp(base, blendLighten(base, blend), alpha); break;
					case 6: output = lerp(base, blendScreen(base, blend), alpha); break;
					case 7: output = blendSubtract(base, blend * alpha); break;
					case 8: output = lerp(base, blendLinearDodge(base, blend), alpha); break;
					case 9: output = lerp(base, blendOverlay(base, blend), alpha); break;
					case 20: output = lerp(base, blendMixed(base, blend), alpha); break;
					default: output = 0; break;
				}
				return output;
			}
			
			#define REPLACE 0
			#define SUBSTRACT 1
			#define MULTIPLY 2
			#define DIVIDE 3
			#define MIN 4
			#define MAX 5
			#define AVERAGE 6
			#define ADD 7
			
			float maskBlend(float baseMask, float blendMask, float blendType)
			{
				float output = 0;
				switch(blendType)
				{
					case REPLACE: output = blendMask; break;
					case SUBSTRACT: output = baseMask - blendMask; break;
					case MULTIPLY: output = baseMask * blendMask; break;
					case DIVIDE: output = baseMask / blendMask; break;
					case MIN: output = min(baseMask, blendMask); break;
					case MAX: output = max(baseMask, blendMask); break;
					case AVERAGE: output = (baseMask + blendMask) * 0.5; break;
					case ADD: output = baseMask + blendMask; break;
				}
				return saturate(output);
			}
			
			float globalMaskBlend(float baseMask, float globalMaskIndex, float blendType, PoiMods poiMods)
			{
				if (globalMaskIndex == 0)
				{
					return baseMask;
				}
				else
				{
					return maskBlend(baseMask, poiMods.globalMask[globalMaskIndex - 1], blendType);
				}
			}
			
			float random(float2 p)
			{
				return frac(sin(dot(p, float2(12.9898, 78.2383))) * 43758.5453123);
			}
			
			float2 random2(float2 p)
			{
				return frac(sin(float2(dot(p, float2(127.1, 311.7)), dot(p, float2(269.5, 183.3)))) * 43758.5453);
			}
			
			float3 random3(float2 p)
			{
				return frac(sin(float3(dot(p, float2(127.1, 311.7)), dot(p, float2(269.5, 183.3)), dot(p, float2(248.3, 315.9)))) * 43758.5453);
			}
			
			float3 random3(float3 p)
			{
				return frac(sin(float3(dot(p, float3(127.1, 311.7, 248.6)), dot(p, float3(269.5, 183.3, 423.3)), dot(p, float3(248.3, 315.9, 184.2)))) * 43758.5453);
			}
			
			float3 randomFloat3(float2 Seed, float maximum)
			{
				return (.5 + float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed), float2(12.9898, 78.233))) * 43758.5453)
				) * .5) * (maximum);
			}
			
			float3 randomFloat3Range(float2 Seed, float Range)
			{
				return (float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed.x * Seed.y, Seed.y + Seed.x), float2(12.9898, 78.233))) * 43758.5453)
				) * 2 - 1) * Range;
			}
			
			float3 randomFloat3WiggleRange(float2 Seed, float Range, float wiggleSpeed, float timeOffset)
			{
				float3 rando = (float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed.x * Seed.y, Seed.y + Seed.x), float2(12.9898, 78.233))) * 43758.5453)
				) * 2 - 1);
				float speed = 1 + wiggleSpeed;
				return float3(sin(((_Time.x + timeOffset) + rando.x * PI) * speed), sin(((_Time.x + timeOffset) + rando.y * PI) * speed), sin(((_Time.x + timeOffset) + rando.z * PI) * speed)) * Range;
			}
			
			void poiDither(float4 In, float4 ScreenPosition, out float4 Out)
			{
				float2 uv = ScreenPosition.xy * _ScreenParams.xy;
				float DITHER_THRESHOLDS[16] = {
					1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0,
					13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0,
					4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0,
					16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0
				};
				uint index = (uint(uv.x) % 4) * 4 + uint(uv.y) % 4;
				Out = In - DITHER_THRESHOLDS[index];
			}
			// The weights of RGB contributions to luminance.
			// Should sum to unity.
			static const float3 HCYwts = float3(0.299, 0.587, 0.114);
			static const float HCLgamma = 3;
			static const float HCLy0 = 100;
			static const float HCLmaxL = 0.530454533953517; // == exp(HCLgamma / HCLy0) - 0.5
			static const float3 wref = float3(1.0, 1.0, 1.0);
			#define TAU 6.28318531
			
			float3 HUEtoRGB(in float H)
			{
				float R = abs(H * 6 - 3) - 1;
				float G = 2 - abs(H * 6 - 2);
				float B = 2 - abs(H * 6 - 4);
				return saturate(float3(R, G, B));
			}
			
			float3 RGBtoHCV(in float3 RGB)
			{
				// Based on work by Sam Hocevar and Emil Persson
				float4 P = (RGB.g < RGB.b) ? float4(RGB.bg, -1.0, 2.0 / 3.0) : float4(RGB.gb, 0.0, -1.0 / 3.0);
				float4 Q = (RGB.r < P.x) ? float4(P.xyw, RGB.r) : float4(RGB.r, P.yzx);
				float C = Q.x - min(Q.w, Q.y);
				float H = abs((Q.w - Q.y) / (6 * C + Epsilon) + Q.z);
				return float3(H, C, Q.x);
			}
			
			float3 HSVtoRGB(in float3 HSV)
			{
				float3 RGB = HUEtoRGB(HSV.x);
				return ((RGB - 1) * HSV.y + 1) * HSV.z;
			}
			
			float3 RGBtoHSV(in float3 RGB)
			{
				float3 HCV = RGBtoHCV(RGB);
				float S = HCV.y / (HCV.z + Epsilon);
				return float3(HCV.x, S, HCV.z);
			}
			
			float3 HSLtoRGB(in float3 HSL)
			{
				float3 RGB = HUEtoRGB(HSL.x);
				float C = (1 - abs(2 * HSL.z - 1)) * HSL.y;
				return (RGB - 0.5) * C + HSL.z;
			}
			
			float3 RGBtoHSL(in float3 RGB)
			{
				float3 HCV = RGBtoHCV(RGB);
				float L = HCV.z - HCV.y * 0.5;
				float S = HCV.y / (1 - abs(L * 2 - 1) + Epsilon);
				return float3(HCV.x, S, L);
			}
			
			void DecomposeHDRColor(in float3 linearColorHDR, out float3 baseLinearColor, out float exposure)
			{
				// Optimization/adaptation of https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/GUI/ColorMutator.cs#L23 but skips weird photoshop stuff
				float maxColorComponent = max(linearColorHDR.r, max(linearColorHDR.g, linearColorHDR.b));
				bool isSDR = maxColorComponent <= 1.0;
				
				float scaleFactor = isSDR ? 1.0 : (1.0 / maxColorComponent);
				exposure = isSDR ? 0.0 : log(maxColorComponent) * 1.44269504089; // ln(2)
				
				baseLinearColor = scaleFactor * linearColorHDR;
			}
			
			float3 ApplyHDRExposure(float3 linearColor, float exposure)
			{
				return linearColor * pow(2, exposure);
			}
			
			// Transforms an RGB color using a matrix. Note that S and V are absolute values here
			float3 ModifyViaHSV(float3 color, float h, float s, float v)
			{
				float3 colorHSV = RGBtoHSV(color);
				colorHSV.x = frac(colorHSV.x + h);
				colorHSV.y = saturate(colorHSV.y + s);
				colorHSV.z = saturate(colorHSV.z + v);
				return HSVtoRGB(colorHSV);
			}
			
			float3 ModifyViaHSV(float3 color, float3 HSVMod)
			{
				return ModifyViaHSV(color, HSVMod.x, HSVMod.y, HSVMod.z);
			}
			
			float4x4 brightnessMatrix(float brightness)
			{
				return float4x4(
				1, 0, 0, 0,
				0, 1, 0, 0,
				0, 0, 1, 0,
				brightness, brightness, brightness, 1
				);
			}
			
			float4x4 contrastMatrix(float contrast)
			{
				float t = (1.0 - contrast) / 2.0;
				
				return float4x4(
				contrast, 0, 0, 0,
				0, contrast, 0, 0,
				0, 0, contrast, 0,
				t, t, t, 1
				);
			}
			
			float4x4 saturationMatrix(float saturation)
			{
				float3 luminance = float3(0.3086, 0.6094, 0.0820);
				
				float oneMinusSat = 1.0 - saturation;
				
				float3 red = luminance.x * oneMinusSat;
				red += float3(saturation, 0, 0);
				
				float3 green = luminance.y * oneMinusSat;
				green += float3(0, saturation, 0);
				
				float3 blue = luminance.z * oneMinusSat;
				blue += float3(0, 0, saturation);
				
				return float4x4(
				red, 0,
				green, 0,
				blue, 0,
				0, 0, 0, 1
				);
			}
			
			float4 PoiColorBCS(float4 color, float brightness, float contrast, float saturation)
			{
				return mul(color, mul(brightnessMatrix(brightness), mul(contrastMatrix(contrast), saturationMatrix(saturation))));
			}
			float3 PoiColorBCS(float3 color, float brightness, float contrast, float saturation)
			{
				return mul(float4(color, 1), mul(brightnessMatrix(brightness), mul(contrastMatrix(contrast), saturationMatrix(saturation)))).rgb;
			}
			
			float3 linear_srgb_to_oklab(float3 c)
			{
				float l = 0.4122214708 * c.x + 0.5363325363 * c.y + 0.0514459929 * c.z;
				float m = 0.2119034982 * c.x + 0.6806995451 * c.y + 0.1073969566 * c.z;
				float s = 0.0883024619 * c.x + 0.2817188376 * c.y + 0.6299787005 * c.z;
				
				float l_ = pow(l, 1.0 / 3.0);
				float m_ = pow(m, 1.0 / 3.0);
				float s_ = pow(s, 1.0 / 3.0);
				
				return float3(
				0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_,
				1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_,
				0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_
				);
			}
			
			float3 oklab_to_linear_srgb(float3 c)
			{
				float l_ = c.x + 0.3963377774 * c.y + 0.2158037573 * c.z;
				float m_ = c.x - 0.1055613458 * c.y - 0.0638541728 * c.z;
				float s_ = c.x - 0.0894841775 * c.y - 1.2914855480 * c.z;
				
				float l = l_ * l_ * l_;
				float m = m_ * m_ * m_;
				float s = s_ * s_ * s_;
				
				return float3(
				+ 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
				- 1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
				- 0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s
				);
			}
			
			float3 hueShift(float3 color, float shift)
			{
				float3 oklab = linear_srgb_to_oklab(max(color, 0.0000000001));
				float hue = atan2(oklab.z, oklab.y);
				hue += shift * PI * 2;  // Add the hue shift
				
				float chroma = length(oklab.yz);
				oklab.y = cos(hue) * chroma;
				oklab.z = sin(hue) * chroma;
				
				return oklab_to_linear_srgb(oklab);
			}
			
			float3 hueShift(float4 color, float shift)
			{
				return hueShift(color.rgb, shift);
			}
			
			/*
			float3 hueShift(float3 color, float hueOffset)
			{
				color = RGBtoHSV(color);
				color.x = frac(hueOffset +color.x);
				return HSVtoRGB(color);
			}
			*/
			
			// LCH
			float xyzF(float t)
			{
				return lerp(pow(t, 1. / 3.), 7.787037 * t + 0.139731, step(t, 0.00885645));
			}
			float xyzR(float t)
			{
				return lerp(t * t * t, 0.1284185 * (t - 0.139731), step(t, 0.20689655));
			}
			
			float4x4 poiRotationMatrixFromAngles(float x, float y, float z)
			{
				float angleX = radians(x);
				float c = cos(angleX);
				float s = sin(angleX);
				float4x4 rotateXMatrix = float4x4(1, 0, 0, 0,
				0, c, -s, 0,
				0, s, c, 0,
				0, 0, 0, 1);
				
				float angleY = radians(y);
				c = cos(angleY);
				s = sin(angleY);
				float4x4 rotateYMatrix = float4x4(c, 0, s, 0,
				0, 1, 0, 0,
				- s, 0, c, 0,
				0, 0, 0, 1);
				
				float angleZ = radians(z);
				c = cos(angleZ);
				s = sin(angleZ);
				float4x4 rotateZMatrix = float4x4(c, -s, 0, 0,
				s, c, 0, 0,
				0, 0, 1, 0,
				0, 0, 0, 1);
				
				return mul(mul(rotateXMatrix, rotateYMatrix), rotateZMatrix);
			}
			
			float4x4 poiRotationMatrixFromAngles(float3 angles)
			{
				float angleX = radians(angles.x);
				float c = cos(angleX);
				float s = sin(angleX);
				float4x4 rotateXMatrix = float4x4(1, 0, 0, 0,
				0, c, -s, 0,
				0, s, c, 0,
				0, 0, 0, 1);
				
				float angleY = radians(angles.y);
				c = cos(angleY);
				s = sin(angleY);
				float4x4 rotateYMatrix = float4x4(c, 0, s, 0,
				0, 1, 0, 0,
				- s, 0, c, 0,
				0, 0, 0, 1);
				
				float angleZ = radians(angles.z);
				c = cos(angleZ);
				s = sin(angleZ);
				float4x4 rotateZMatrix = float4x4(c, -s, 0, 0,
				s, c, 0, 0,
				0, 0, 1, 0,
				0, 0, 0, 1);
				
				return mul(mul(rotateXMatrix, rotateYMatrix), rotateZMatrix);
			}
			
			float3 getCameraPosition()
			{
				#ifdef USING_STEREO_MATRICES
				return lerp(unity_StereoWorldSpaceCameraPos[0], unity_StereoWorldSpaceCameraPos[1], 0.5);
				#endif
				return _WorldSpaceCameraPos;
			}
			
			float2 calcPixelScreenUVs(half4 grabPos)
			{
				half2 uv = grabPos.xy / (grabPos.w + 0.0000000001);
				#if UNITY_SINGLE_PASS_STEREO
				uv.xy *= half2(_ScreenParams.x * 2, _ScreenParams.y);
				#else
				uv.xy *= _ScreenParams.xy;
				#endif
				
				return uv;
			}
			
			float CalcMipLevel(float2 texture_coord)
			{
				float2 dx = ddx(texture_coord);
				float2 dy = ddy(texture_coord);
				float delta_max_sqr = max(dot(dx, dx), dot(dy, dy));
				
				return 0.5 * log2(delta_max_sqr);
			}
			
			float inverseLerp(float A, float B, float T)
			{
				return (T - A) / (B - A);
			}
			
			float inverseLerp2(float2 a, float2 b, float2 value)
			{
				float2 AB = b - a;
				float2 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			float inverseLerp3(float3 a, float3 b, float3 value)
			{
				float3 AB = b - a;
				float3 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			float inverseLerp4(float4 a, float4 b, float4 value)
			{
				float4 AB = b - a;
				float4 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			/*
			MIT License
			
			Copyright (c) 2019 wraikny
			
			Permission is hereby granted, free of charge, to any person obtaining a copy
			of this software and associated documentation files (the "Software"), to deal
			in the Software without restriction, including without limitation the rights
			to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
			copies of the Software, and to permit persons to whom the Software is
			furnished to do so, subject to the following conditions:
			
			The above copyright notice and this permission notice shall be included in all
			copies or substantial portions of the Software.
			
			THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
			IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
			FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
			AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
			LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
			OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
			SOFTWARE.
			
			VertexTransformShader is dependent on:
			*/
			
			float4 quaternion_conjugate(float4 v)
			{
				return float4(
				v.x, -v.yzw
				);
			}
			
			float4 quaternion_mul(float4 v1, float4 v2)
			{
				float4 result1 = (v1.x * v2 + v1 * v2.x);
				
				float4 result2 = float4(
				- dot(v1.yzw, v2.yzw),
				cross(v1.yzw, v2.yzw)
				);
				
				return float4(result1 + result2);
			}
			
			// angle : radians
			float4 get_quaternion_from_angle(float3 axis, float angle)
			{
				float sn = sin(angle * 0.5);
				float cs = cos(angle * 0.5);
				return float4(axis * sn, cs);
			}
			
			float4 quaternion_from_vector(float3 inVec)
			{
				return float4(0.0, inVec);
			}
			
			float degree_to_radius(float degree)
			{
				return (
				degree / 180.0 * PI
				);
			}
			
			float3 rotate_with_quaternion(float3 inVec, float3 rotation)
			{
				float4 qx = get_quaternion_from_angle(float3(1, 0, 0), radians(rotation.x));
				float4 qy = get_quaternion_from_angle(float3(0, 1, 0), radians(rotation.y));
				float4 qz = get_quaternion_from_angle(float3(0, 0, 1), radians(rotation.z));
				
				#define MUL3(A, B, C) quaternion_mul(quaternion_mul((A), (B)), (C))
				float4 quaternion = normalize(MUL3(qx, qy, qz));
				float4 conjugate = quaternion_conjugate(quaternion);
				
				float4 inVecQ = quaternion_from_vector(inVec);
				
				float3 rotated = (
				MUL3(quaternion, inVecQ, conjugate)
				).yzw;
				
				return rotated;
			}
			
			float4 transform(float4 input, float4 pos, float4 rotation, float4 scale)
			{
				input.rgb *= (scale.xyz * scale.w);
				input = float4(rotate_with_quaternion(input.xyz, rotation.xyz * rotation.w) + (pos.xyz * pos.w), input.w);
				return input;
			}
			
			float2 RotateUV(float2 _uv, float _radian, float2 _piv, float _time)
			{
				float RotateUV_ang = _radian;
				float RotateUV_cos = cos(_time * RotateUV_ang);
				float RotateUV_sin = sin(_time * RotateUV_ang);
				return (mul(_uv - _piv, float2x2(RotateUV_cos, -RotateUV_sin, RotateUV_sin, RotateUV_cos)) + _piv);
			}
			
			/*
			MIT END
			*/
			
			float3 RotateAroundAxis(float3 original, float3 axis, float radian)
			{
				float s = sin(radian);
				float c = cos(radian);
				float one_minus_c = 1.0 - c;
				
				axis = normalize(axis);
				float3x3 rot_mat = {
					one_minus_c * axis.x * axis.x + c, one_minus_c * axis.x * axis.y - axis.z * s, one_minus_c * axis.z * axis.x + axis.y * s,
					one_minus_c * axis.x * axis.y + axis.z * s, one_minus_c * axis.y * axis.y + c, one_minus_c * axis.y * axis.z - axis.x * s,
					one_minus_c * axis.z * axis.x - axis.y * s, one_minus_c * axis.y * axis.z + axis.x * s, one_minus_c * axis.z * axis.z + c
				};
				return mul(rot_mat, original);
			}
			
			float3 poiThemeColor(in PoiMods poiMods, in float3 srcColor, in float themeIndex)
			{
				float3 outputColor = srcColor;
				if (themeIndex != 0)
				{
					themeIndex = max(themeIndex - 1, 0);
					
					if (themeIndex <= 3)
					{
						outputColor = poiMods.globalColorTheme[themeIndex];
					}
					else
					{
						#ifdef POI_AUDIOLINK
						if (poiMods.audioLinkAvailable)
						{
							outputColor = poiMods.globalColorTheme[themeIndex];
						}
						#endif
					}
				}
				return outputColor;
			}
			
			float3 lilToneCorrection(float3 c, float4 hsvg)
			{
				// gamma
				c = pow(abs(c), hsvg.w);
				// rgb - > hsv
				float4 p = (c.b > c.g) ? float4(c.bg, -1.0, 2.0 / 3.0) : float4(c.gb, 0.0, -1.0 / 3.0);
				float4 q = (p.x > c.r) ? float4(p.xyw, c.r) : float4(c.r, p.yzx);
				float d = q.x - min(q.w, q.y);
				float e = 1.0e-10;
				float3 hsv = float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
				// shift
				hsv = float3(hsv.x + hsvg.x, saturate(hsv.y * hsvg.y), saturate(hsv.z * hsvg.z));
				// hsv - > rgb
				return hsv.z - hsv.z * hsv.y + hsv.z * hsv.y * saturate(abs(frac(hsv.x + float3(1.0, 2.0 / 3.0, 1.0 / 3.0)) * 6.0 - 3.0) - 1.0);
			}
			
			float3 lilBlendColor(float3 dstCol, float3 srcCol, float3 srcA, int blendMode)
			{
				float3 ad = dstCol + srcCol;
				float3 mu = dstCol * srcCol;
				float3 outCol = float3(0, 0, 0);
				if (blendMode == 0) outCol = srcCol; // Normal
				if (blendMode == 1) outCol = ad; // Add
				if (blendMode == 2) outCol = max(ad - mu, dstCol); // Screen
				if (blendMode == 3) outCol = mu; // Multiply
				return lerp(dstCol, outCol, srcA);
			}
			
			float lilIsIn0to1(float f)
			{
				float value = 0.5 - abs(f - 0.5);
				return saturate(value / clamp(fwidth(value), 0.0001, 1.0));
			}
			
			float lilIsIn0to1(float f, float nv)
			{
				float value = 0.5 - abs(f - 0.5);
				return saturate(value / clamp(fwidth(value), 0.0001, nv));
			}
			
			float poiEdgeLinearNoSaturate(float value, float border)
			{
				return (value - border) / clamp(fwidth(value), 0.0001, 1.0);
			}
			
			float3 poiEdgeLinearNoSaturate(float value, float3 border)
			{
				return float3(
				(value - border.x) / clamp(fwidth(value), 0.0001, 1.0),
				(value - border.y) / clamp(fwidth(value), 0.0001, 1.0),
				(value - border.z) / clamp(fwidth(value), 0.0001, 1.0)
				);
			}
			
			float poiEdgeLinearNoSaturate(float value, float border, float blur)
			{
				float borderMin = saturate(border - blur * 0.5);
				float borderMax = saturate(border + blur * 0.5);
				return (value - borderMin) / saturate(borderMax - borderMin + fwidth(value));
			}
			
			float poiEdgeLinearNoSaturate(float value, float border, float blur, float borderRange)
			{
				float borderMin = saturate(border - blur * 0.5 - borderRange);
				float borderMax = saturate(border + blur * 0.5);
				return (value - borderMin) / saturate(borderMax - borderMin + fwidth(value));
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border)
			{
				// return (value - border) / clamp(fwidth(value), 0.0001, 1.0);
				
				float fwidthValue = fwidth(value);
				return smoothstep(border - fwidthValue, border + fwidthValue, value);
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border, float blur)
			{
				float fwidthValue = fwidth(value);
				float borderMin = saturate(border - blur * 0.5);
				float borderMax = saturate(border + blur * 0.5);
				return smoothstep(borderMin - fwidthValue, borderMax + fwidthValue, value);
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border, float blur, float borderRange)
			{
				float fwidthValue = fwidth(value);
				float borderMin = saturate(border - blur * 0.5 - borderRange);
				float borderMax = saturate(border + blur * 0.5);
				return smoothstep(borderMin - fwidthValue, borderMax + fwidthValue, value);
			}
			
			float poiEdgeNonLinear(float value, float border)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border));
			}
			
			float poiEdgeNonLinear(float value, float border, float blur)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border, blur));
			}
			
			float poiEdgeNonLinear(float value, float border, float blur, float borderRange)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border, blur, borderRange));
			}
			
			float poiEdgeLinear(float value, float border)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border));
			}
			
			float poiEdgeLinear(float value, float border, float blur)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border, blur));
			}
			
			float poiEdgeLinear(float value, float border, float blur, float borderRange)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border, blur, borderRange));
			}
			// From https : // github.com / lilxyzw / OpenLit / blob / main / Assets / OpenLit / core.hlsl
			float3 OpenLitLinearToSRGB(float3 col)
			{
				return LinearToGammaSpace(col);
			}
			
			float3 OpenLitSRGBToLinear(float3 col)
			{
				return GammaToLinearSpace(col);
			}
			
			float OpenLitLuminance(float3 rgb)
			{
				#if defined(UNITY_COLORSPACE_GAMMA)
				return dot(rgb, float3(0.22, 0.707, 0.071));
				#else
				return dot(rgb, float3(0.0396819152, 0.458021790, 0.00609653955));
				#endif
			}
			
			float3 AdjustLitLuminance(float3 rgb, float targetLuminance)
			{
				float currentLuminance;
				#if defined(UNITY_COLORSPACE_GAMMA)
				currentLuminance = dot(rgb, float3(0.22, 0.707, 0.071));
				#else
				currentLuminance = dot(rgb, float3(0.0396819152, 0.458021790, 0.00609653955));
				#endif
				
				float luminanceRatio = targetLuminance / currentLuminance;
				return rgb * luminanceRatio;
			}
			
			float3 ClampLuminance(float3 rgb, float minLuminance, float maxLuminance)
			{
				float currentLuminance = dot(rgb, float3(0.299, 0.587, 0.114));
				float minRatio = (currentLuminance != 0) ? minLuminance / currentLuminance : 1.0;
				float maxRatio = (currentLuminance != 0) ? maxLuminance / currentLuminance : 1.0;
				float luminanceRatio = clamp(min(maxRatio, max(minRatio, 1.0)), 0.0, 1.0);
				return lerp(rgb, rgb * luminanceRatio, luminanceRatio < 1.0);
			}
			
			float3 MaxLuminance(float3 rgb, float maxLuminance)
			{
				float currentLuminance = dot(rgb, float3(0.299, 0.587, 0.114));
				float luminanceRatio = (currentLuminance != 0) ? maxLuminance / max(currentLuminance, 0.00001) : 1.0;
				return lerp(rgb, rgb * luminanceRatio, currentLuminance > maxLuminance);
			}
			
			float OpenLitGray(float3 rgb)
			{
				return dot(rgb, float3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0));
			}
			
			void OpenLitShadeSH9ToonDouble(float3 lightDirection, out float3 shMax, out float3 shMin)
			{
				#if !defined(LIGHTMAP_ON)
				float3 N = lightDirection * 0.666666;
				float4 vB = N.xyzz * N.yzzx;
				// L0 L2
				float3 res = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
				res.r += dot(unity_SHBr, vB);
				res.g += dot(unity_SHBg, vB);
				res.b += dot(unity_SHBb, vB);
				res += unity_SHC.rgb * (N.x * N.x - N.y * N.y);
				// L1
				float3 l1;
				l1.r = dot(unity_SHAr.rgb, N);
				l1.g = dot(unity_SHAg.rgb, N);
				l1.b = dot(unity_SHAb.rgb, N);
				shMax = res + l1;
				shMin = res - l1;
				#if defined(UNITY_COLORSPACE_GAMMA)
				shMax = OpenLitLinearToSRGB(shMax);
				shMin = OpenLitLinearToSRGB(shMin);
				#endif
				#else
				shMax = 0.0;
				shMin = 0.0;
				#endif
			}
			
			float3 OpenLitComputeCustomLightDirection(float4 lightDirectionOverride)
			{
				float3 customDir = length(lightDirectionOverride.xyz) * normalize(mul((float3x3)unity_ObjectToWorld, lightDirectionOverride.xyz));
				return lightDirectionOverride.w ? customDir : lightDirectionOverride.xyz; // .w isn't doc'd anywhere and is always 0 unless end user changes it
			}
			
			float3 OpenLitLightingDirectionForSH9()
			{
				float3 mainDir = _WorldSpaceLightPos0.xyz * OpenLitLuminance(_LightColor0.rgb);
				#if !defined(LIGHTMAP_ON)
				float3 sh9Dir = unity_SHAr.xyz * 0.333333 + unity_SHAg.xyz * 0.333333 + unity_SHAb.xyz * 0.333333;
				float3 sh9DirAbs = float3(sh9Dir.x, abs(sh9Dir.y), sh9Dir.z);
				#else
				float3 sh9Dir = 0;
				float3 sh9DirAbs = 0;
				#endif
				
				float3 lightDirectionForSH9 = sh9Dir + mainDir;
				lightDirectionForSH9 = dot(lightDirectionForSH9, lightDirectionForSH9) < 0.000001 ? 0 : normalize(lightDirectionForSH9);
				return lightDirectionForSH9;
			}
			
			float3 OpenLitLightingDirection(float4 lightDirectionOverride)
			{
				float3 mainDir = _WorldSpaceLightPos0.xyz * OpenLitLuminance(_LightColor0.rgb);
				#if !defined(LIGHTMAP_ON) && UNITY_SHOULD_SAMPLE_SH
				float3 sh9Dir = unity_SHAr.xyz * 0.333333 + unity_SHAg.xyz * 0.333333 + unity_SHAb.xyz * 0.333333;
				float3 sh9DirAbs = float3(sh9Dir.x, abs(sh9Dir.y), sh9Dir.z);
				#else
				float3 sh9Dir = 0;
				float3 sh9DirAbs = 0;
				#endif
				float3 customDir = OpenLitComputeCustomLightDirection(lightDirectionOverride);
				
				return normalize(sh9DirAbs + mainDir + customDir);
			}
			
			float3 OpenLitLightingDirection()
			{
				float4 customDir = float4(0.001, 0.002, 0.001, 0.0);
				return OpenLitLightingDirection(customDir);
			}
			
			inline float4 CalculateFrustumCorrection()
			{
				float x1 = -UNITY_MATRIX_P._31 / (UNITY_MATRIX_P._11 * UNITY_MATRIX_P._34);
				float x2 = -UNITY_MATRIX_P._32 / (UNITY_MATRIX_P._22 * UNITY_MATRIX_P._34);
				return float4(x1, x2, 0, UNITY_MATRIX_P._33 / UNITY_MATRIX_P._34 + x1 * UNITY_MATRIX_P._13 + x2 * UNITY_MATRIX_P._23);
			}
			
			inline float CorrectedLinearEyeDepth(float z, float B)
			{
				return 1.0 / (z / UNITY_MATRIX_P._34 + B);
			}
			
			// Silent's code
			float2 sharpSample(float4 texelSize, float2 p)
			{
				p = p * texelSize.zw;
				float2 c = max(0.0, fwidth(p));
				p = floor(p) + saturate(frac(p) / c);
				p = (p - 0.5) * texelSize.xy;
				return p;
			}
			
			void applyToGlobalMask(inout PoiMods poiMods, int index, int blendType, float val)
			{
				float valBlended = saturate(maskBlend(poiMods.globalMask[index], val, blendType));
				switch(index)
				{
					case 0: poiMods.globalMask[0] = valBlended; break;
					case 1: poiMods.globalMask[1] = valBlended; break;
					case 2: poiMods.globalMask[2] = valBlended; break;
					case 3: poiMods.globalMask[3] = valBlended; break;
					case 4: poiMods.globalMask[4] = valBlended; break;
					case 5: poiMods.globalMask[5] = valBlended; break;
					case 6: poiMods.globalMask[6] = valBlended; break;
					case 7: poiMods.globalMask[7] = valBlended; break;
					case 8: poiMods.globalMask[8] = valBlended; break;
					case 9: poiMods.globalMask[9] = valBlended; break;
					case 10: poiMods.globalMask[10] = valBlended; break;
					case 11: poiMods.globalMask[11] = valBlended; break;
					case 12: poiMods.globalMask[12] = valBlended; break;
					case 13: poiMods.globalMask[13] = valBlended; break;
					case 14: poiMods.globalMask[14] = valBlended; break;
					case 15: poiMods.globalMask[15] = valBlended; break;
				}
			}
			
			void assignValueToVectorFromIndex(inout float4 vec, int index, float value)
			{
				switch(index)
				{
					case 0: vec[0] = value; break;
					case 1: vec[1] = value; break;
					case 2: vec[2] = value; break;
					case 3: vec[3] = value; break;
				}
			}
			
			// SNose
			float3 mod289(float3 x)
			{
				return x - floor(x * (1.0 / 289.0)) * 289.0;
			}
			float2 mod289(float2 x)
			{
				return x - floor(x * (1.0 / 289.0)) * 289.0;
			}
			float3 permute(float3 x)
			{
				return mod289(((x * 34.0) + 1.0) * x);
			}
			
			float snoise(float2 v)
			{
				const float4 C = float4(0.211324865405187, // (3.0 - sqrt(3.0)) / 6.0
				0.366025403784439, // 0.5 * (sqrt(3.0) - 1.0)
				- 0.577350269189626, // - 1.0 + 2.0 * C.x
				0.024390243902439); // 1.0 / 41.0
				float2 i = floor(v + dot(v, C.yy));
				float2 x0 = v - i + dot(i, C.xx);
				float2 i1;
				i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0);
				float4 x12 = x0.xyxy + C.xxzz;
				x12.xy -= i1;
				i = mod289(i); // Avoid truncation effects in permutation
				float3 p = permute(permute(i.y + float3(0.0, i1.y, 1.0))
				+ i.x + float3(0.0, i1.x, 1.0));
				
				float3 m = max(0.5 - float3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);
				m = m * m ;
				m = m * m ;
				float3 x = 2.0 * frac(p * C.www) - 1.0;
				float3 h = abs(x) - 0.5;
				float3 ox = floor(x + 0.5);
				float3 a0 = x - ox;
				m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);
				float3 g;
				g.x = a0.x * x0.x + h.x * x0.y;
				g.yz = a0.yz * x12.xz + h.yz * x12.yw;
				return 130.0 * dot(m, g);
			}
			
			float nsqDistance(float2 a, float2 b)
			{
				return dot(a - b, a - b);
			}
			
			float poiInvertToggle(in float value, in float toggle)
			{
				return (toggle == 0 ? value : 1 - value);
			}
			
			float3 PoiBlendNormal(float3 dstNormal, float3 srcNormal)
			{
				return float3(dstNormal.xy + srcNormal.xy, dstNormal.z * srcNormal.z);
			}
			
			float3 lilTransformDirOStoWS(float3 directionOS, bool doNormalize)
			{
				if (doNormalize) return normalize(mul((float3x3)unity_ObjectToWorld, directionOS));
				else            return mul((float3x3)unity_ObjectToWorld, directionOS);
			}
			
			float2 poiGetWidthAndHeight(Texture2D tex)
			{
				uint width, height;
				tex.GetDimensions(width, height);
				return float2(width, height);
			}
			
			float2 poiGetWidthAndHeight(Texture2DArray tex)
			{
				uint width, height, element;
				tex.GetDimensions(width, height, element);
				return float2(width, height);
			}
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			
			// Convenient mechanism to read from the AudioLink texture that handles reading off the end of one line and onto the next above it.
			float4 AudioLinkDataMultiline(uint2 xycoord)
			{
				return AudioLinkData(uint2(xycoord.x % AUDIOLINK_WIDTH, xycoord.y + xycoord.x / AUDIOLINK_WIDTH));
			}
			
			// Mechanism to sample between two adjacent pixels and lerp between them, like "linear" supesampling
			float4 AudioLinkLerp(float2 xy)
			{
				return lerp(AudioLinkData(xy), AudioLinkData(xy + int2(1, 0)), frac(xy.x));
			}
			
			// Same as AudioLinkLerp but properly handles multiline reading.
			float4 AudioLinkLerpMultiline(float2 xy)
			{
				return lerp(AudioLinkDataMultiline(xy), AudioLinkDataMultiline(xy + float2(1, 0)), frac(xy.x));
			}
			
			//Tests to see if Audio Link texture is available
			bool AudioLinkIsAvailable()
			{
				#if !defined(AUDIOLINK_STANDARD_INDEXING)
				int width, height;
				_AudioTexture.GetDimensions(width, height);
				return width > 16;
				#else
				return _AudioTexture_TexelSize.z > 16;
				#endif
			}
			
			//Get version of audiolink present in the world, 0 if no audiolink is present
			float AudioLinkGetVersion()
			{
				int2 dims;
				#if !defined(AUDIOLINK_STANDARD_INDEXING)
				_AudioTexture.GetDimensions(dims.x, dims.y);
				#else
				dims = _AudioTexture_TexelSize.zw;
				#endif
				
				if (dims.x >= 128)
				return AudioLinkData(ALPASS_GENERALVU).x;
				else if (dims.x > 16)
				return 1;
				else
				return 0;
			}
			
			// This pulls data from this texture.
			#define AudioLinkGetSelfPixelData(xy) _SelfTexture2D[xy]
			
			// Extra utility functions for time.
			uint AudioLinkDecodeDataAsUInt(uint2 indexloc)
			{
				uint4 rpx = AudioLinkData(indexloc);
				return rpx.r + rpx.g * 1024 + rpx.b * 1048576 + rpx.a * 1073741824;
			}
			
			//Note: This will truncate time to every 134,217.728 seconds (~1.5 days of an instance being up) to prevent floating point aliasing.
			// if your code will alias sooner, you will need to use a different function.  It should be safe to use this on all times.
			float AudioLinkDecodeDataAsSeconds(uint2 indexloc)
			{
				uint time = AudioLinkDecodeDataAsUInt(indexloc) & 0x7ffffff;
				//Can't just divide by float.  Bug in Unity's HLSL compiler.
				return float(time / 1000) + float(time % 1000) / 1000.;
			}
			
			#define ALDecodeDataAsSeconds(x) AudioLinkDecodeDataAsSeconds(x)
			#define ALDecodeDataAsUInt(x) AudioLinkDecodeDataAsUInt(x)
			
			float AudioLinkRemap(float t, float a, float b, float u, float v)
			{
				return ((t - a) / (b - a)) * (v - u) + u;
			}
			
			float3 AudioLinkHSVtoRGB(float3 HSV)
			{
				float3 RGB = 0;
				float C = HSV.z * HSV.y;
				float H = HSV.x * 6;
				float X = C * (1 - abs(fmod(H, 2) - 1));
				if (HSV.y != 0)
				{
					float I = floor(H);
					if (I == 0)
					{
						RGB = float3(C, X, 0);
					}
					else if (I == 1)
					{
						RGB = float3(X, C, 0);
					}
					else if (I == 2)
					{
						RGB = float3(0, C, X);
					}
					else if (I == 3)
					{
						RGB = float3(0, X, C);
					}
					else if (I == 4)
					{
						RGB = float3(X, 0, C);
					}
					else
					{
						RGB = float3(C, 0, X);
					}
				}
				float M = HSV.z - C;
				return RGB + M;
			}
			
			float3 AudioLinkCCtoRGB(float bin, float intensity, int rootNote)
			{
				float note = bin / AUDIOLINK_EXPBINS;
				
				float hue = 0.0;
				note *= 12.0;
				note = glsl_mod(4. - note + rootNote, 12.0);
				{
					if (note < 4.0)
					{
						//Needs to be YELLOW->RED
						hue = (note) / 24.0;
					}
					else if (note < 8.0)
					{
						//            [4]  [8]
						//Needs to be RED->BLUE
						hue = (note - 2.0) / 12.0;
					}
					else
					{
						//             [8] [12]
						//Needs to be BLUE->YELLOW
						hue = (note - 4.0) / 8.0;
					}
				}
				float val = intensity - 0.1;
				return AudioLinkHSVtoRGB(float3(fmod(hue, 1.0), 1.0, clamp(val, 0.0, 1.0)));
			}
			
			// Sample the amplitude of a given frequency in the DFT, supports frequencies in [13.75; 14080].
			float4 AudioLinkGetAmplitudeAtFrequency(float hertz)
			{
				float note = AUDIOLINK_EXPBINS * log2(hertz / AUDIOLINK_BOTTOM_FREQUENCY);
				return AudioLinkLerpMultiline(ALPASS_DFT + float2(note, 0));
			}
			
			// Sample the amplitude of a given semitone in an octave. Octave is in [0; 9] while note is [0; 11].
			float AudioLinkGetAmplitudeAtNote(float octave, float note)
			{
				float quarter = note * 2.0;
				return AudioLinkLerpMultiline(ALPASS_DFT + float2(octave * AUDIOLINK_EXPBINS + quarter, 0));
			}
			
			// Get a reasonable drop-in replacement time value for _Time.y with the
			// given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTime(uint index, uint band)
			{
				return (AudioLinkDecodeDataAsUInt(ALPASS_CHRONOTENSITY + uint2(index, band))) / 100000.0;
			}
			
			// Get a chronotensity value in the interval [0; 1], modulated by the speed input,
			// with the given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTimeNormalized(uint index, uint band, float speed)
			{
				return frac(AudioLinkGetChronoTime(index, band) * speed);
			}
			
			// Get a chronotensity value in the interval [0; interval], modulated by the speed input,
			// with the given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTimeInterval(uint index, uint band, float speed, float interval)
			{
				return AudioLinkGetChronoTimeNormalized(index, band, speed) * interval;
			}
			
			float getBandAtTime(float band, float time, float size = 1.0f)
			{
				//return remap(UNITY_SAMPLE_TEX2D(_AudioTexture, float2(time * width, band/128.0)).r, min(size,.9999), 1);
				return remapClamped(min(size, .9999), 1, AudioLinkData(ALPASS_AUDIOBASS + uint2(time * AUDIOLINK_WIDTH, band)).r);
			}
			
			fixed3 maximize(fixed3 c)
			{
				if (c.x == 0 && c.y == 0 && c.z == 0)
				return fixed3(1.0, 1.0, 1.0);
				else
				return c / max(c.r, max(c.g, c.b));
			}
			
			void initPoiAudioLink(inout PoiMods poiMods)
			{
				if (!_AudioLinkAnimToggle) return;
				
				if (AudioLinkIsAvailable())
				{
					poiMods.audioLinkAvailable = true;
					poiMods.audioLinkVersion = AudioLinkGetVersion();
					poiMods.audioLink[0] = _AudioLinkSmoothingBass == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 0))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingBass) * 15.95, 0))[0];
					poiMods.audioLink[1] = _AudioLinkSmoothingLowMid == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 1))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingLowMid) * 15.95, 1))[0];
					poiMods.audioLink[2] = _AudioLinkSmoothingHighMid == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 2))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingHighMid) * 15.95, 2))[0];
					poiMods.audioLink[3] = _AudioLinkSmoothingTreble == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 3))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingTreble) * 15.95, 3))[0];
					poiMods.audioLink[4] = AudioLinkData(ALPASS_GENERALVU + float2(8, 0))[0];
					/*
					poiMods.globalColorTheme[4] = AudioLinkData( ALPASS_CCCOLORS + uint2( 0, 0 ) );
					poiMods.globalColorTheme[5] = AudioLinkData( ALPASS_CCCOLORS + uint2( 1, 0 ) );
					poiMods.globalColorTheme[6] = AudioLinkData( ALPASS_CCCOLORS + uint2( 2, 0 ) );
					poiMods.globalColorTheme[7] = AudioLinkData( ALPASS_CCCOLORS + uint2( 3, 0 ) );
					
					poiMods.globalColorTheme[4] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 0, 0 ) )),1.0);
					poiMods.globalColorTheme[5] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 1, 0 ) )),1.0);
					poiMods.globalColorTheme[6] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 2, 0 ) )),1.0);
					poiMods.globalColorTheme[7] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 3, 0 ) )),1.0);
					*/
					
					poiMods.globalColorTheme[4] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(2, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[5] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(3, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[6] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(4, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[7] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(5, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					
					poiMods.globalColorTheme[8] = AudioLinkData(ALPASS_THEME_COLOR0);
					poiMods.globalColorTheme[9] = AudioLinkData(ALPASS_THEME_COLOR1);
					poiMods.globalColorTheme[10] = AudioLinkData(ALPASS_THEME_COLOR2);
					poiMods.globalColorTheme[11] = AudioLinkData(ALPASS_THEME_COLOR3);
					return;
				}
				
				if (_AudioLinkBandOverridesEnabled)
				{
					poiMods.audioLinkAvailable = true;
					poiMods.audioLink[0] = _AudioLinkBandOverrideSliders.x;
					poiMods.audioLink[1] = _AudioLinkBandOverrideSliders.y;
					poiMods.audioLink[2] = _AudioLinkBandOverrideSliders.z;
					poiMods.audioLink[3] = _AudioLinkBandOverrideSliders.w;
				}
			}
			
			void DebugVisualizer(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				if (_DebugWaveform)
				{
					float waveform = AudioLinkLerpMultiline(ALPASS_WAVEFORM + float2(500. * poiMesh.uv[0].x, 0)).r;
					poiFragData.emission += clamp(1 - 50 * abs(waveform - poiMesh.uv[0].y * 2. + 1), 0, 1);
				}
				if (_DebugDFT)
				{
					poiFragData.emission += AudioLinkLerpMultiline(ALPASS_DFT + uint2(poiMesh.uv[0].x * AUDIOLINK_ETOTALBINS, 0)).rrr;
				}
				if (_DebugBass)
				{
					poiFragData.emission += poiMods.audioLink[0];
				}
				if (_DebugLowMids)
				{
					poiFragData.emission += poiMods.audioLink[1];
				}
				if (_DebugHighMids)
				{
					poiFragData.emission += poiMods.audioLink[2];
				}
				if (_DebugTreble)
				{
					poiFragData.emission += poiMods.audioLink[3];
				}
				if (_DebugCCColors)
				{
					poiFragData.emission += AudioLinkData(ALPASS_CCCOLORS + uint2(3 + 1, 0));
				}
				if (_DebugCCStrip)
				{
					poiFragData.emission += AudioLinkLerp(ALPASS_CCSTRIP + float2(poiMesh.uv[0].x * AUDIOLINK_WIDTH, 0));
				}
				if (_DebugCCLights)
				{
					poiFragData.emission += AudioLinkData(ALPASS_CCLIGHTS + uint2(uint(poiMesh.uv[0].x * 8) + uint(poiMesh.uv[0].y * 16) * 8, 0));
				}
				if (_DebugAutocorrelator)
				{
					poiFragData.emission += saturate(AudioLinkLerp(ALPASS_AUTOCORRELATOR + float2((abs(1. - poiMesh.uv[0].x * 2.)) * AUDIOLINK_WIDTH, 0)).rrr);
				}
				if (_DebugChronotensity)
				{
					poiFragData.emission += (AudioLinkDecodeDataAsUInt(ALPASS_CHRONOTENSITY + uint2(1, 0)) % 1000000) / 1000000.0;
				}
			}
			
			void SetupAudioLink(inout PoiFragData poiFragData, inout PoiMods poiMods, in PoiMesh poiMesh)
			{
				initPoiAudioLink(poiMods);
				DebugVisualizer(poiFragData, poiMesh, poiMods);
				
				if (_AudioLinkCCStripY)
				{
					poiFragData.emission += AudioLinkLerp(ALPASS_CCSTRIP + float2(poiMesh.uv[0].y * AUDIOLINK_WIDTH, 0)).rgb * .5;
				}
			}
			
			#endif
			//endex
			
			//ifex _BSSEnabled!=1
			#ifdef POIBS_ENABLE
			//ifex _BSSBloomfog!=1
			#ifdef POIBS_BLOOMFOG
			inline float4 GetFogCoord(float4 clipPos)
			{
				float4 screenPos = ComputeNonStereoScreenPos(clipPos);
				float2 screenPosNormalized = screenPos.xy / screenPos.w;
				float eyeOffset = (unity_StereoEyeIndex * (_StereoCameraEyeOffset * 2)) + - _StereoCameraEyeOffset;
				return float4(
				((eyeOffset +screenPosNormalized.x) + - 0.5) * _CustomFogTextureToScreenRatio.x + 0.5,
				(screenPosNormalized.y + - 0.5) * _CustomFogTextureToScreenRatio.y + 0.5
				,clipPos.z,clipPos.w);
			}
			
			inline float GetHeightFogIntensity(float3 worldPos, float fogHeightOffset, float fogHeightScale)
			{
				float heightFogIntensity = _CustomFogHeightFogHeight + _CustomFogHeightFogStartY;
				heightFogIntensity = ((worldPos.y * fogHeightScale) + fogHeightOffset) + - heightFogIntensity;
				heightFogIntensity = heightFogIntensity / _CustomFogHeightFogHeight;
				heightFogIntensity = clamp(heightFogIntensity, 0, 1);
				return ((-heightFogIntensity * 2) + 3) * (heightFogIntensity * heightFogIntensity);
			}
			
			inline float GetFogIntensity(float3 distance, float fogStartOffset, float fogScale)
			{
				float fogIntensity = max(dot(distance, distance) + - fogStartOffset, 0);
				fogIntensity = max((fogIntensity * fogScale) + - _CustomFogOffset, 0);
				fogIntensity = 1 / ((fogIntensity * _CustomFogAttenuation) + 1);
				return -fogIntensity;
			}
			#endif
			//endex
			#endif
			//endex
			
			//ifex _EnableDepthBulge==0
			#if defined(POI_DEPTHBULGE)
			void applyDepthBulgeFX(inout VertexOut o)
			{
				float4 pos = UnityObjectToClipPos(o.localPos);
				float4 grabPos = ComputeGrabScreenPos(pos);
				float depth = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(grabPos.xy / grabPos.w, 0, 0));
				
				#if defined(PROP_DEPTHBULGEMASK) || !defined(OPTIMIZER_ENABLED)
				float depthBulgeMask = tex2Dlod(_DepthBulgeMask, float4(poiUV(vertexUV(o, _DepthBulgeMaskUV), _DepthBulgeMask_ST), 0, 0))[_DepthBulgeMaskChannel];
				#else
				float depthBulgeMask = 1.0;
				#endif
				
				depth = Linear01Depth(depth);
				
				float intersect = 0;
				if (depth != 1)
				{
					float diff = distance(depth, Linear01Depth(pos.z / pos.w));
					if (diff > 0)
					{
						intersect = 1 - smoothstep(0, _ProjectionParams.w * _DepthBulgeFadeLength, diff);
					}
				}
				float4 offset = intersect * _DepthBulgeHeight * float4(o.normal, 0);
				
				offset = IsInMirror() ? 0 : offset;
				offset *= depthBulgeMask;
				
				o.worldPos.xyz += offset.xyz;
				o.localPos.xyz += mul(unity_WorldToObject, float4(offset.xyz, 0)).xyz;
			}
			#endif
			//endex
			
			VertexOut vert(
			#ifndef POI_TESSELLATED
			appdata v
			#else
			tessAppData v
			#endif
			)
			{
				UNITY_SETUP_INSTANCE_ID(v);
				VertexOut o;
				PoiInitStruct(VertexOut, o);
				UNITY_TRANSFER_INSTANCE_ID(v, o);
				#ifdef POI_TESSELLATED
				UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v);
				#endif
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
				
				//ifex _EnableUDIMDiscardOptions==0
				#ifdef POI_UDIMDISCARD
				UNITY_BRANCH
				if(_UDIMDiscardMode == 0) // Discard Vertices instead of just pixels
				{
					// Branchless (inspired by s-ilent)
					float2 udim = 0;
					// Select UV
					udim += (v.uv0.xy * (_UDIMDiscardUV == 0));
					udim += (v.uv1.xy * (_UDIMDiscardUV == 1));
					udim += (v.uv2.xy * (_UDIMDiscardUV == 2));
					udim += (v.uv3.xy * (_UDIMDiscardUV == 3));
					
					float isDiscarded = 0;
					float4 xMask = float4(  (udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					isDiscarded += (udim.y >= 0 && udim.y < 1) * dot(float4(_UDIMDiscardRow0_0, _UDIMDiscardRow0_1, _UDIMDiscardRow0_2, _UDIMDiscardRow0_3), xMask);
					isDiscarded += (udim.y >= 1 && udim.y < 2) * dot(float4(_UDIMDiscardRow1_0, _UDIMDiscardRow1_1, _UDIMDiscardRow1_2, _UDIMDiscardRow1_3), xMask);
					isDiscarded += (udim.y >= 2 && udim.y < 3) * dot(float4(_UDIMDiscardRow2_0, _UDIMDiscardRow2_1, _UDIMDiscardRow2_2, _UDIMDiscardRow2_3), xMask);
					isDiscarded += (udim.y >= 3 && udim.y < 4) * dot(float4(_UDIMDiscardRow3_0, _UDIMDiscardRow3_1, _UDIMDiscardRow3_2, _UDIMDiscardRow3_3), xMask);
					
					isDiscarded *= any(float4(udim.y >= 0, udim.y < 4, udim.x >= 0, udim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					// Use a threshold so that there's some room for animations to be close to 0, but not exactly 0
					const float threshold = 0.001;
					if(isDiscarded > threshold) // Early Return skips rest of vertex shader
					{
						return (VertexOut)POI_NAN;
					}
				}
				#endif
				//endex
				
				//ifex _VertexManipulationsEnabled==0
				#ifdef AUTO_EXPOSURE
				float4 audioLinkBands = 0;
				float3 ALrotation = 0;
				float3 ALLocalTranslation = 0;
				float3 CTALRotation = 0;
				float3 ALScale = 0;
				float3 ALWorldTranslation = 0;
				float ALHeight = 0;
				float ALRoundingAmount = 0;
				float4 ALSpectrumLocalOffset = float4(0, 0, 0, 0);
				#ifdef POI_AUDIOLINK
				if (AudioLinkIsAvailable() && _VertexAudioLinkEnabled && _AudioLinkAnimToggle)
				{
					audioLinkBands.x = AudioLinkData(ALPASS_AUDIOBASS).r;
					audioLinkBands.y = AudioLinkData(ALPASS_AUDIOLOWMIDS).r;
					audioLinkBands.z = AudioLinkData(ALPASS_AUDIOHIGHMIDS).r;
					audioLinkBands.w = AudioLinkData(ALPASS_AUDIOTREBLE).r;
					
					if (any(_VertexLocalTranslationALMin) || any(_VertexLocalTranslationALMax))
					{
						ALLocalTranslation = lerp(_VertexLocalTranslationALMin, _VertexLocalTranslationALMax, audioLinkBands[_VertexLocalTranslationALBand]);
					}
					if (any(_VertexLocalRotationAL))
					{
						ALrotation = audioLinkBands[_VertexLocalRotationALBand] * _VertexLocalRotationAL;
					}
					if (any(_VertexLocalRotationCTALSpeed))
					{
						CTALRotation.x = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeX, _VertexLocalRotationCTALBandX) * _VertexLocalRotationCTALSpeed.x * 360;
						CTALRotation.y = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeY, _VertexLocalRotationCTALBandY) * _VertexLocalRotationCTALSpeed.y * 360;
						CTALRotation.z = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeZ, _VertexLocalRotationCTALBandZ) * _VertexLocalRotationCTALSpeed.z * 360;
					}
					if (any(_VertexLocalScaleALMin) || any(_VertexLocalScaleALMax))
					{
						ALScale = lerp(_VertexLocalScaleALMin.xyz + _VertexLocalScaleALMin.w, _VertexLocalScaleALMax.xyz + _VertexLocalScaleALMax.w, audioLinkBands[_VertexLocalScaleALBand]);
					}
					if (any(_VertexWorldTranslationALMin) || any(_VertexWorldTranslationALMax))
					{
						ALWorldTranslation = lerp(_VertexWorldTranslationALMin, _VertexWorldTranslationALMax, audioLinkBands[_VertexWorldTranslationALBand]);
					}
					if (any(_VertexManipulationHeightAL))
					{
						ALHeight = lerp(_VertexManipulationHeightAL.x, _VertexManipulationHeightAL.y, audioLinkBands[_VertexManipulationHeightBand]);
					}
					if (any(_VertexRoundingRangeAL))
					{
						ALRoundingAmount = lerp(_VertexRoundingRangeAL.x, _VertexRoundingRangeAL.y, audioLinkBands[_VertexRoundingRangeBand]);
					}
					if (_VertexSpectrumMotion)
					{
						ALSpectrumLocalOffset.xyz = lerp(_VertexSpectrumOffsetMin.xyz, _VertexSpectrumOffsetMax.xyz, AudioLinkLerpMultiline(ALPASS_DFT + float2(vertexUV(v, _VertexSpectrumUV)[_VertexSpectrumUVDirection] * AUDIOLINK_ETOTALBINS, 0.)));
					}
				}
				#endif
				
				// Local Transformation
				float4 rotation = float4(_VertexManipulationLocalRotation.xyz + float3(180, 0, 0) + _VertexManipulationLocalRotationSpeed * _Time.x + ALrotation + CTALRotation, _VertexManipulationLocalRotation.w);
				v.normal = rotate_with_quaternion(v.normal, rotation.xyz);
				v.tangent.xyz = rotate_with_quaternion(v.tangent.xyz, rotation.xyz);
				v.vertex = transform(v.vertex, _VertexManipulationLocalTranslation + float4(ALLocalTranslation, 0) + ALSpectrumLocalOffset, rotation, _VertexManipulationLocalScale + float4(ALScale, 0));
				o.normal = UnityObjectToWorldNormal(v.normal);
				
				#if defined(PROP_VERTEXMANIPULATIONHEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float3 heightOffset = (tex2Dlod(_VertexManipulationHeightMask, float4(poiUV(vertexUV(v, _VertexManipulationHeightMaskUV), _VertexManipulationHeightMask_ST) + _VertexManipulationHeightMaskPan * _Time.x, 0, 0))[_VertexManipulationHeightMaskChannel] - _VertexManipulationHeightBias) * (_VertexManipulationHeight + ALHeight) * o.normal;
				#else
				float3 heightOffset = (_VertexManipulationHeight + ALHeight) * o.normal;
				#endif
				
				if (_VertexBarrelMode)
				{
					v.vertex.xz = lerp(v.vertex.xz, normalize(v.vertex.xz) * _VertexBarrelWidth + v.vertex.xz * _VertexBarrelHeight, _VertexBarrelAlpha);
				}
				
				if (_VertexSphereMode)
				{
					v.vertex.xyz = lerp(v.vertex.xyz, normalize(v.vertex.xyz + _VertexSphereCenter.xyz) * _VertexSphereRadius + v.vertex.xyz * _VertexSphereHeight, _VertexSphereAlpha);
				}
				
				if (_VertexTornadoMode)
				{
					v.vertex.xz = lerp(v.vertex.xz, float3(v.vertex.xz + float2(cos(_Time.y * _VertexTornadoSpeed + v.vertex.y * _VertexTornadoIntensity) * _VertexTornadoRadius, sin(_Time.y * _VertexTornadoSpeed + v.vertex.y * _VertexTornadoIntensity) * _VertexTornadoRadius), v.vertex.y), smoothstep(_VertexTornadoBaseHeight, _VertexTornadoTopHeight, v.vertex.y));
				}
				
				v.vertex.xyz += mul(unity_WorldToObject, _VertexManipulationWorldTranslation.xyz + ALWorldTranslation + heightOffset).xyz;
				
				// rounding
				UNITY_BRANCH
				if (_VertexRoundingEnabled)
				{
					float divisionAmount = max(_VertexRoundingDivision + ALRoundingAmount, 0.0000001);
					if (_VertexRoundingSpace == 0)
					{
						float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
						float3 worldRoundPosition = (ceil(worldPos.xyz / divisionAmount) * divisionAmount) - divisionAmount * .5;
						v.vertex = mul(unity_WorldToObject, float4(worldRoundPosition, worldPos.w));
					}
					else if (_VertexRoundingSpace == 1)
					{
						v.vertex.xyz = (ceil(v.vertex.xyz / divisionAmount) * divisionAmount) - divisionAmount * .5;
					}
				}
				#endif
				//endex
				
				//ifex _EnableDissolve==0
				#ifdef DISTORT
				UNITY_BRANCH
				if (_UVTileDissolveEnabled && _UVTileDissolveDiscardAtMax)
				{
					// Branchless (inspired by s-ilent)
					float2 dissolveUdim = 0;
					// Select UV
					dissolveUdim += (v.uv0.xy * (_UVTileDissolveUV == 0));
					dissolveUdim += (v.uv1.xy * (_UVTileDissolveUV == 1));
					dissolveUdim += (v.uv2.xy * (_UVTileDissolveUV == 2));
					dissolveUdim += (v.uv3.xy * (_UVTileDissolveUV == 3));
					
					float isDiscardedFromDissolve = 0;
					float4 xMaskDissolve = float4((dissolveUdim.x >= 0 && dissolveUdim.x < 1),
					(dissolveUdim.x >= 1 && dissolveUdim.x < 2),
					(dissolveUdim.x >= 2 && dissolveUdim.x < 3),
					(dissolveUdim.x >= 3 && dissolveUdim.x < 4));
					
					isDiscardedFromDissolve += (dissolveUdim.y >= 0 && dissolveUdim.y < 1) * dot(float4(_UVTileDissolveAlpha_Row0_0, _UVTileDissolveAlpha_Row0_1, _UVTileDissolveAlpha_Row0_2, _UVTileDissolveAlpha_Row0_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 1 && dissolveUdim.y < 2) * dot(float4(_UVTileDissolveAlpha_Row1_0, _UVTileDissolveAlpha_Row1_1, _UVTileDissolveAlpha_Row1_2, _UVTileDissolveAlpha_Row1_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 2 && dissolveUdim.y < 3) * dot(float4(_UVTileDissolveAlpha_Row2_0, _UVTileDissolveAlpha_Row2_1, _UVTileDissolveAlpha_Row2_2, _UVTileDissolveAlpha_Row2_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 3 && dissolveUdim.y < 4) * dot(float4(_UVTileDissolveAlpha_Row3_0, _UVTileDissolveAlpha_Row3_1, _UVTileDissolveAlpha_Row3_2, _UVTileDissolveAlpha_Row3_3), xMaskDissolve);
					
					isDiscardedFromDissolve *= any(float4(dissolveUdim.y >= 0, dissolveUdim.y < 4, dissolveUdim.x >= 0, dissolveUdim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					// Use a threshold so that there's some room for animations to be close to 1, but not exactly 1
					const float threshold = 0.999;
					if (isDiscardedFromDissolve > threshold) // Early Return skips rest of vertex shader
					
					{
						return (VertexOut)POI_NAN;
					}
				}
				#endif
				//endex
				
				//ifex _EnableMirrorOptions==0
				#ifdef POI_MIRROR
				float notVisible = 0;
				
				if (_VisibilityMode == 1) // VRC
				
				{
					float mirrorMode = VRCMirrorMode();
					float cameraMode = VRCCameraMode();
					
					notVisible += (!_VisibilityVRCRegular && ((mirrorMode == 0) && (cameraMode == 0)));
					notVisible += (!_VisibilityVRCMirrorVR && (mirrorMode == 1));
					notVisible += (!_VisibilityVRCMirrorDesktop && (mirrorMode == 2));
					notVisible += (!_VisibilityVRCCameraVR && (cameraMode == 1));
					notVisible += (!_VisibilityVRCCameraDesktop && (cameraMode == 2));
					notVisible += (!_VisibilityVRCCameraScreenshot && (cameraMode == 3));
				}
				else if (_Mirror != 0) // Generic (CVR, etc)
				
				{
					notVisible += (_Mirror == 1) ^ IsInMirror();
				}
				
				if (notVisible) // Early Return skips rest of vertex shader
				
				{
					return (VertexOut)POI_NAN;
				}
				#endif
				//endex
				
				o.normal = UnityObjectToWorldNormal(v.normal);
				o.tangent.xyz = UnityObjectToWorldDir(v.tangent);
				o.tangent.w = v.tangent.w;
				o.vertexColor = v.color;
				
				o.uv[0] = float4(v.uv0.xy, v.uv1.xy);
				o.uv[1] = float4(v.uv2.xy, v.uv3.xy);
				
				#if defined(LIGHTMAP_ON)
				o.lightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
				#endif
				#ifdef DYNAMICLIGHTMAP_ON
				o.lightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
				#endif
				
				o.localPos = v.vertex;
				o.worldPos = mul(unity_ObjectToWorld, o.localPos);
				
				float3 localOffset = float3(0, 0, 0);
				float3 worldOffset = float3(0, 0, 0);
				
				//ifex _EnableOutlines!=1
				#ifdef POI_PASS_OUTLINE
				float outlineMask = tex2Dlod(_OutlineMask, float4(poiUV(vertexUV(v, _OutlineMaskUV), _OutlineMask_ST) + _Time.x * _OutlineMaskPan, 0, 0))[_OutlineMaskChannel];
				
				//UNITY_BRANCH
				if (_OutlineVertexColorMask > 0)
				{
					outlineMask *= lerp(1, v.color[_OutlineVertexColorMask - 1], _OutlineVertexColorMaskStrength);
				}
				
				float3 outlineNormal = _OutlineSpace ? o.normal : v.normal;
				//UNITY_BRANCH
				if (_OutlineUseVertexColorNormals)
				{
					float3 outlineTangent;
					float3 outlineBinormal;
					if (_OutlineSpace) // 0 Local, 1 World
					
					{
						outlineTangent = o.tangent;
						outlineBinormal = cross(o.normal, o.tangent) * (v.tangent.w * unity_WorldTransformParams.w);
					}
					else
					{
						outlineTangent = v.tangent.xyz;
						outlineBinormal = normalize(cross(outlineNormal, outlineTangent)) * (v.tangent.w * length(outlineNormal));
					}
					float3 outlineVectorTS = v.color.rgb * 2.0 - 1.0;
					outlineNormal = outlineVectorTS.x * outlineTangent + outlineVectorTS.y * outlineBinormal + outlineVectorTS.z * outlineNormal;
				}
				
				float offsetMultiplier = 1;
				float distanceOffset = 1;
				//UNITY_BRANCH
				if (_OutlineFixedSize)
				{
					distanceOffset *= lerp(1.0, clamp((distance(_WorldSpaceCameraPos, mul(unity_ObjectToWorld, o.localPos).xyz)), 0.0f, _OutlinesMaxDistance), _OutlineFixWidth);
				}
				
				float lineWidth = _LineWidth;
				#ifdef POI_AUDIOLINK
				// Due to PoiMods.audioLink being frag only I'll just
				// recreate what it does here for this vertex function
				//UNITY_BRANCH
				if (_AudioLinkAnimToggle)
				{
					if (AudioLinkIsAvailable())
					{
						lineWidth += lerp(_AudioLinkOutlineSize.x, _AudioLinkOutlineSize.y, AudioLinkData(uint2(0, _AudioLinkOutlineSizeBand)));
					}
				}
				#endif
				
				float3 offset = outlineNormal * (lineWidth * _EnableOutlines / 100) * outlineMask * distanceOffset;
				
				//UNITY_BRANCH
				if (_OutlineExpansionMode == 2)
				{
					float3 lightDirection = normalize(_WorldSpaceLightPos0 + unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz);
					offsetMultiplier = saturate(dot(lightDirection, outlineNormal));
					offset *= offsetMultiplier;
					offset *= distanceOffset;
				}
				else if (_OutlineExpansionMode == 3)
				{
					float3 viewNormal = mul((float3x3)UNITY_MATRIX_V, outlineNormal);
					offsetMultiplier = saturate(dot(viewNormal.xy, normalize(_OutlinePersonaDirection.xy)));
					
					offset *= offsetMultiplier;
					offset *= distanceOffset;
				}
				else if (_OutlineExpansionMode == 4)
				{
					offset = mul((float3x3)transpose(UNITY_MATRIX_V), _OutlineDropShadowOffset);
					offset *= distanceOffset;
				}
				if (_OutlineSpace == 0)
				{
					localOffset += offset;
					worldOffset += mul(unity_ObjectToWorld, offset);
				}
				else
				{
					localOffset += mul(unity_WorldToObject, offset);
					worldOffset += offset;
				}
				#endif
				//endex
				
				//ifex _VertexGlitchingEnabled==0
				#if defined(POI_VERTEX_GLITCHING)
				
				bool canGlitch = true;
				if (_VertexGlitchMirrorEnable && _VertexGlitchMirror > 0)
				{
					bool inMirror = IsInMirror();
					if (_VertexGlitchMirror == 1 && !inMirror)	canGlitch = false;
					if (_VertexGlitchMirror == 2 && inMirror)	canGlitch = false;
				}
				if (canGlitch)
				{
					float3 forward = getCameraPosition() - mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
					forward.y = 0;
					forward = normalize(forward);
					float3 glitchDirection = normalize(cross(float3(0, 1, 0), forward));
					
					float glitchAmount = 0;
					
					#if defined(POI_VERTEX_GLITCHING_TEXTURE)
					// if(_VertexGlitchingUseTexture)
					// {
					float uvl = o.worldPos.y * _VertexGlitchDensity + _Time.x * _VertexGlitchMapPanSpeed;
					float uvr = o.worldPos.y * _VertexGlitchDensity - _Time.x * _VertexGlitchMapPanSpeed;
					
					float3 glitchTextureL = 1;
					float3 glitchTextureR = 1;
					
					#if defined(POI_VERTEX_GLITCHING_TEXTURE) || !defined(OPTIMIZER_ENABLED)
					glitchTextureL = tex2Dlod(_VertexGlitchMap, float4(uvl, uvl, 0, 0)).rgb;
					glitchTextureR = tex2Dlod(_VertexGlitchMap, float4(uvr, uvr, 0, 0)).rgb;
					#endif
					
					glitchAmount += (glitchTextureL.r - 0.5) * 2;
					glitchAmount += - (glitchTextureR.r - 0.5) * 2;
					
					glitchAmount += (glitchTextureL.g - 0.5) * 2;
					glitchAmount += - (glitchTextureR.b - 0.5) * 2;
					// } else {
					#else
					glitchAmount += frac(sin(dot(_Time.xy + o.worldPos.y, float2(12.9898, 78.233))) * 43758.5453123) * 2 - 1;
					// }
					#endif
					
					float time = _Time.y * _VertexGlitchFrequency;
					
					float randomGlitch = (sin(time) + sin(2.2 * time + 5.52) + sin(2.9 * time + 0.93) + sin(4.6 * time + 8.94)) / 4;
					float3 glitchOffset = 0;
					
					#ifdef POI_AUDIOLINK
					if (AudioLinkIsAvailable() && _VertexGlitchingAudioLinkEnabled)
					{
						// float4 audioLinkData = AudioLinkData(ALPASS_AUDIOBASS);
						
						float audioIntensity =
						AudioLinkData(ALPASS_AUDIOBASS).r 		* (_VertexGlitchingAudioLinkBand == 0) +
						AudioLinkData(ALPASS_AUDIOLOWMIDS).r 	* (_VertexGlitchingAudioLinkBand == 1) +
						AudioLinkData(ALPASS_AUDIOHIGHMIDS).r	* (_VertexGlitchingAudioLinkBand == 2) +
						AudioLinkData(ALPASS_AUDIOTREBLE).r 	* (_VertexGlitchingAudioLinkBand == 3) +
						AudioLinkData(ALPASS_FILTEREDVU_INTENSITY).r * (_VertexGlitchingAudioLinkBand == 4);
						
						if(_VertexGlitchingAudiolinkOverride)
						{
							glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
							// glitchOffset += glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
						} else {
							glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
							glitchOffset += glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
						}
					} else {
						glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
					}
					#else
					glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
					#endif
					
					localOffset += glitchOffset;
					worldOffset += mul(unity_ObjectToWorld, glitchOffset);
				}
				#endif
				//endex
				
				o.localPos.rgb += localOffset;
				o.worldPos.rgb += worldOffset;
				
				//ifex _EnableDepthBulge==0
				#if defined(POI_DEPTHBULGE) && (defined(POI_PASS_BASE) || defined(POI_PASS_ADD))
				applyDepthBulgeFX(o);
				#endif
				//endex
				
				//ifex _BSSEnabled!=1
				#ifdef POIBS_ENABLE
				//ifex _BSSBloomfog!=1
				#ifdef POIBS_BLOOMFOG
				o.fogCoord = GetFogCoord(UnityObjectToClipPos(v.vertex));
				o.worldPos = mul(unity_ObjectToWorld, v.vertex);
				#endif
				//endex
				#endif
				//endex
				
				o.pos = UnityObjectToClipPos(o.localPos);
				
				#ifdef POI_PASS_OUTLINE
				#if defined(UNITY_REVERSED_Z)
				//DX
				o.pos.z += _Offset_Z * - 0.01;
				#else
				//OpenGL
				o.pos.z += _Offset_Z * 0.01;
				#endif
				#endif
				//o.grabPos = ComputeGrabScreenPos(o.pos);
				
				#ifndef FORWARD_META_PASS
				#if !defined(UNITY_PASS_SHADOWCASTER)
				UNITY_TRANSFER_SHADOW(o, o.uv[0].xy);
				#else
				v.vertex.xyz = o.localPos.xyz;
				TRANSFER_SHADOW_CASTER_NOPOS(o, o.pos);
				#endif
				#endif
				
				UNITY_TRANSFER_FOG(o, o.pos);
				
				if (_RenderingReduceClipDistance)
				{
					if (o.pos.w < _ProjectionParams.y * 1.01 && o.pos.w > 0)
					{
						#if defined(UNITY_REVERSED_Z) // DirectX
						o.pos.z = o.pos.z * 0.0001 + o.pos.w * 0.999;
						#else // OpenGL
						o.pos.z = o.pos.z * 0.0001 - o.pos.w * 0.999;
						#endif
					}
				}
				
				#ifdef POI_PASS_META
				o.pos = UnityMetaVertexPosition(v.vertex, v.uv1.xy, v.uv2.xy, unity_LightmapST, unity_DynamicLightmapST);
				#endif
				
				return o;
			}
			
			#if defined(_STOCHASTICMODE_DELIOT_HEITZ)
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, uv) : POI2D_SAMPLER(tex, texSampler, uv))
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan)) : POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), dx, dy) : POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			#if defined(_STOCHASTICMODE_HEXTILE)
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, uv, false) : POI2D_SAMPLER(tex, texSampler, uv))
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), false) : POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), false, dx, dy) : POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			
			#ifndef POI2D_SAMPLER_STOCHASTIC
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (POI2D_SAMPLER(tex, texSampler, uv))
			#endif
			#ifndef POI2D_SAMPLER_PAN_STOCHASTIC
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#endif
			#ifndef POI2D_SAMPLER_PANGRAD_STOCHASTIC
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			
			// When using, properties won't properly lock at optimize time; needs macro evaluation implemented
			// #define POI2D_SAMPLER_STOCHASTIC_INLINED(tex, texSampler) (POI2D_SAMPLER_STOCHASTIC(tex, texSampler, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Stochastic))
			// #define POI2D_SAMPLER_PAN_STOCHASTIC_INLINED(tex, texSampler) (POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan, tex##Stochastic))
			
			// #define POI2D_MAINTEX_SAMPLER_STOCHASTIC_INLINED(tex) (POI2D_SAMPLER_STOCHASTIC(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Stochastic))
			// #define POI2D_MAINTEX_SAMPLER_PAN_STOCHASTIC_INLINED(tex) (POI2D_SAMPLER_PAN_STOCHASTIC(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan, tex##Stochastic))
			
			// Deliot, Heitz 2019 - Fast, but non-histogram-preserving (ends up looking a bit blurry and lower contrast)
			// https://eheitzresearch.wordpress.com/738-2/
			
			// Classic Magic Numbers fracsin
			#if !defined(_STOCHASTICMODE_NONE)
			float2 StochasticHash2D2D (float2 s)
			{
				return frac(sin(glsl_mod(float2(dot(s, float2(127.1,311.7)), dot(s, float2(269.5,183.3))), 3.14159)) * 43758.5453);
			}
			#endif
			
			#if defined(_STOCHASTICMODE_DELIOT_HEITZ)
			// UV Offsets and blend weights
			// UVBW[0...2].xy = UV Offsets
			// UVBW[0...2].z = Blend Weights
			float3x3 DeliotHeitzStochasticUVBW(float2 uv)
			{
				// UV transformed into triangular grid space with UV scaled by approximation of 2*sqrt(3)
				const float2x2 stochasticSkewedGrid = float2x2(1.0, -0.57735027, 0.0, 1.15470054);
				float2 skewUV = mul(stochasticSkewedGrid, uv * 3.4641 * _StochasticDeliotHeitzDensity);
				
				// Vertex IDs and barycentric coords
				float2 vxID = floor(skewUV);
				float3 bary = float3(frac(skewUV), 0);
				bary.z = 1.0 - bary.x - bary.y;
				
				float3x3 pos = float3x3(
				float3(vxID, 				bary.z),
				float3(vxID + float2(0, 1), bary.y),
				float3(vxID + float2(1, 0), bary.x)
				);
				
				float3x3 neg = float3x3(
				float3(vxID + float2(1, 1), 	 -bary.z),
				float3(vxID + float2(1, 0), 1.0 - bary.y),
				float3(vxID + float2(0, 1), 1.0 - bary.x)
				);
				
				return (bary.z > 0) ? pos : neg;
			}
			
			float4 DeliotHeitzSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, float2 dx, float2 dy)
			{
				// UVBW[0...2].xy = UV Offsets
				// UVBW[0...2].z = Blend Weights
				float3x3 UVBW = DeliotHeitzStochasticUVBW(uv);
				
				//blend samples with calculated weights
				return 	mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[0].xy), dx, dy), UVBW[0].z) +
				mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[1].xy), dx, dy), UVBW[1].z) +
				mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[2].xy), dx, dy), UVBW[2].z) ;
			}
			
			float4 DeliotHeitzSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv)
			{
				float2 dx = ddx(uv), dy = ddy(uv);
				return DeliotHeitzSampleTexture(tex, texSampler, uv, dx, dy);
			}
			#endif // defined(_STOCHASTICMODE_DELIOT_HEITZ)
			
			#if defined(_STOCHASTICMODE_HEXTILE)
			// HexTiling: Slower, but histogram-preserving
			// SPDX-License-Idenfitier: MIT
			// Copyright (c) 2022 mmikk
			// https://github.com/mmikk/hextile-demo
			float2 HextileMakeCenUV(float2 vertex)
			{
				// 0.288675 ~= 1/(2*sqrt(3))
				const float2x2 stochasticInverseSkewedGrid = float2x2(1.0, 0.5, 0.0, 1.0/1.15470054);
				return mul(stochasticInverseSkewedGrid, vertex) * 0.288675;
			}
			
			float2x2 HextileLoadRot2x2(float2 idx, float rotStrength)
			{
				float angle = abs(idx.x * idx.y) + abs(idx.x + idx.y) + PI;
				
				// remap to +/-pi
				angle = glsl_mod(angle, 2 * PI);
				if(angle < 0)  angle += 2 * PI;
				if(angle > PI) angle -= 2 * PI;
				
				angle *= rotStrength;
				
				float cs = cos(angle), si = sin(angle);
				return float2x2(cs, -si, si, cs);
			}
			
			// UV Offsets and base blend weights
			// UVBWR[0...2].xy = UV Offsets
			// UVBWR[0...2].zw = rotation costh/sinth -> reconstruct rotation matrix with float2x2(UVBWR[n].z, -UVBWR[n].w, UVBWR[n].w, UVBWR[n].z)
			// UVBWR[3].xyz = Blend Weights (w unused) - needs luminance weighting
			float4x4 HextileUVBWR(float2 uv)
			{
				// Create Triangle Grid
				// Skew input space into simplex triangle grid (3.4641 ~= 2*sqrt(3))
				const float2x2 stochasticSkewedGrid = float2x2(1.0, -0.57735027, 0.0, 1.15470054);
				float2 skewedCoord = mul(stochasticSkewedGrid, uv * 3.4641 * _StochasticHexGridDensity);
				
				float2 baseId = float2(floor(skewedCoord));
				float3 temp = float3(frac(skewedCoord), 0);
				temp.z = 1 - temp.x - temp.y;
				
				float s = step(0.0, -temp.z);
				float s2 = 2 * s - 1;
				
				float3 weights = float3(-temp.z * s2, s - temp.y * s2, s - temp.x * s2);
				
				float2 vertex0 = baseId + float2(s, s);
				float2 vertex1 = baseId + float2(s, 1 - s);
				float2 vertex2 = baseId + float2(1 - s, s);
				
				float2 cen0 = HextileMakeCenUV(vertex0), cen1 = HextileMakeCenUV(vertex1), cen2 = HextileMakeCenUV(vertex2);
				float2x2 rot0 = float2x2(1, 0, 0, 1), rot1 = float2x2(1, 0, 0, 1), rot2 = float2x2(1, 0, 0, 1);
				
				if(_StochasticHexRotationStrength > 0)
				{
					rot0 = HextileLoadRot2x2(vertex0, _StochasticHexRotationStrength);
					rot1 = HextileLoadRot2x2(vertex1, _StochasticHexRotationStrength);
					rot2 = HextileLoadRot2x2(vertex2, _StochasticHexRotationStrength);
				}
				
				return float4x4(
				float4(mul(uv - cen0, rot0) + cen0 + StochasticHash2D2D(vertex0), rot0[0].x, -rot0[0].y),
				float4(mul(uv - cen1, rot1) + cen1 + StochasticHash2D2D(vertex1), rot1[0].x, -rot1[0].y),
				float4(mul(uv - cen2, rot2) + cen2 + StochasticHash2D2D(vertex2), rot2[0].x, -rot2[0].y),
				float4(weights, 0)
				);
			}
			
			float4 HextileSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, bool isNormalMap, float2 dUVdx, float2 dUVdy)
			{
				// For some reason doing this instead of just calculating it directly prevents it from \
				// breaking after a certain number of textures use it. I don't understand why yet
				float4x4 UVBWR = HextileUVBWR(uv);
				
				// 2D Rotation Matrices for dUVdx/dy
				// Not sure if this constant folds during compiling when rot is locked at 0, so force it
				float2x2 rot0 = float2x2(1, 0, 0, 1), rot1 = float2x2(1, 0, 0, 1), rot2 = float2x2(1, 0, 0, 1);
				
				if(_StochasticHexRotationStrength > 0)
				{
					rot0 = float2x2(UVBWR[0].z, -UVBWR[0].w, UVBWR[0].w, UVBWR[0].z);
					rot1 = float2x2(UVBWR[1].z, -UVBWR[1].w, UVBWR[1].w, UVBWR[1].z);
					rot2 = float2x2(UVBWR[2].z, -UVBWR[2].w, UVBWR[2].w, UVBWR[2].z);
				}
				
				// Weights
				float3 W = UVBWR[3].xyz;
				
				// Sample texture
				// float3x4 c = float3x4(
				// 	tex.SampleGrad(texSampler, UVBWR[0].xy, mul(dUVdx, rot0), mul(dUVdy, rot0)),
				// 	tex.SampleGrad(texSampler, UVBWR[1].xy, mul(dUVdx, rot1), mul(dUVdy, rot1)),
				// 	tex.SampleGrad(texSampler, UVBWR[2].xy, mul(dUVdx, rot2), mul(dUVdy, rot2))
				// );
				
				float4 c0 = tex.SampleGrad(texSampler, UVBWR[0].xy, mul(dUVdx, rot0), mul(dUVdy, rot0));
				float4 c1 = tex.SampleGrad(texSampler, UVBWR[1].xy, mul(dUVdx, rot1), mul(dUVdy, rot1));
				float4 c2 = tex.SampleGrad(texSampler, UVBWR[2].xy, mul(dUVdx, rot2), mul(dUVdy, rot2));
				
				// Blend samples using luminance
				// This is technically incorrect for normal maps, but produces very similar
				// results to blending using normal map gradients (steepness)
				const float3 Lw = float3(0.299, 0.587, 0.114);
				float3 Dw = float3(dot(c0.xyz, Lw), dot(c1.xyz, Lw), dot(c2.xyz, Lw));
				
				Dw = lerp(1.0, Dw, _StochasticHexFallOffContrast);
				W = Dw * pow(W, _StochasticHexFallOffPower);
				// In the original hextiling there's a Gain3 step here, but it seems to slow things down \
				// and cause the UVs to break, so I've omitted it. Looks fine without
				
				W /= (W.x + W.y + W.z);
				return W.x * c0 + W.y * c1 + W.z * c2;
			}
			
			float4 HextileSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, bool isNormalMap)
			{
				return HextileSampleTexture(tex, texSampler, uv, isNormalMap, ddx(uv), ddy(uv));
			}
			#endif // defined(_STOCHASTICMODE_HEXTILE)
			
			void applyAlphaOptions(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiMods poiMods)
			{
				poiFragData.alpha = saturate(poiFragData.alpha + _AlphaMod);
				
				if (_AlphaGlobalMask > 0)
				{
					poiFragData.alpha = maskBlend(poiFragData.alpha, poiMods.globalMask[_AlphaGlobalMask - 1], _AlphaGlobalMaskBlendType);
				}
				
				//ifex _AlphaDistanceFade==0 && isNotAnimated(_AlphaDistanceFade)
				if (_AlphaDistanceFade)
				{
					float3 position = _AlphaDistanceFadeType ? poiMesh.worldPos : poiMesh.objectPosition;
					float distanceFadeMultiplier = lerp(_AlphaDistanceFadeMinAlpha, _AlphaDistanceFadeMaxAlpha, smoothstep(_AlphaDistanceFadeMin, _AlphaDistanceFadeMax, distance(position, poiCam.worldPos)));
					if (_AlphaDistanceFadeGlobalMask > 0)
					{
						distanceFadeMultiplier = lerp(1, distanceFadeMultiplier, poiMods.globalMask[_AlphaDistanceFadeGlobalMask - 1]);
					}
					poiFragData.alpha *= distanceFadeMultiplier;
				}
				//endex
				
				//ifex _AlphaFresnel==0 && isNotAnimated(_AlphaFresnel)
				if (_AlphaFresnel)
				{
					float holoRim = saturate(1 - smoothstep(min(_AlphaFresnelSharpness, _AlphaFresnelWidth), _AlphaFresnelWidth, (poiCam.vDotN)));
					holoRim = abs(lerp(1, holoRim, _AlphaFresnelAlpha));
					holoRim = _AlphaFresnelInvert ? 1 - holoRim : holoRim;
					if (_AlphaFresnelGlobalMask > 0)
					{
						holoRim = lerp(1, holoRim, poiMods.globalMask[_AlphaFresnelGlobalMask - 1]);
					}
					poiFragData.alpha *= holoRim;
				}
				//endex
				
				//ifex _AlphaAngular==0 && isNotAnimated(_AlphaAngular)
				if (_AlphaAngular)
				{
					half cameraAngleMin = _CameraAngleMin / 180;
					half cameraAngleMax = _CameraAngleMax / 180;
					half modelAngleMin = _ModelAngleMin / 180;
					half modelAngleMax = _ModelAngleMax / 180;
					float3 pos = _AngleCompareTo == 0 ? poiMesh.objectPosition : poiMesh.worldPos;
					half3 cameraToModelDirection = normalize(pos - getCameraPosition());
					half3 modelForwardDirection = normalize(mul(unity_ObjectToWorld, normalize(_AngleForwardDirection.rgb)));
					half cameraLookAtModel = remapClamped(cameraAngleMax, cameraAngleMin, .5 * dot(cameraToModelDirection, getCameraForward()) + .5);
					half modelLookAtCamera = remapClamped(modelAngleMax, modelAngleMin, .5 * dot(-cameraToModelDirection, modelForwardDirection) + .5);
					float angularAlphaMod = 1;
					if (_AngleType == 0)
					{
						angularAlphaMod = max(cameraLookAtModel, _AngleMinAlpha);
					}
					else if (_AngleType == 1)
					{
						angularAlphaMod = max(modelLookAtCamera, _AngleMinAlpha);
					}
					else if (_AngleType == 2)
					{
						angularAlphaMod = max(cameraLookAtModel * modelLookAtCamera, _AngleMinAlpha);
					}
					if (_AlphaAngularGlobalMask > 0)
					{
						angularAlphaMod = lerp(1, angularAlphaMod, poiMods.globalMask[_AlphaAngularGlobalMask - 1]);
					}
					poiFragData.alpha *= angularAlphaMod;
				}
				//endex
				
				//ifex _AlphaAudioLinkEnabled==0 && isNotAnimated(_AlphaAudioLinkEnabled)
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable && _AlphaAudioLinkEnabled)
				{
					poiFragData.alpha = saturate(poiFragData.alpha + lerp(_AlphaAudioLinkAddRange.x, _AlphaAudioLinkAddRange.y, poiMods.audioLink[_AlphaAudioLinkAddBand]));
				}
				#endif
				//endex
				
			}
			
			//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
			inline half Dither8x8Bayer(int x, int y)
			{
				// Premultiplied by 1/64
				const half dither[ 64 ] = {
					0.015625, 0.765625, 0.203125, 0.953125, 0.06250, 0.81250, 0.25000, 1.00000,
					0.515625, 0.265625, 0.703125, 0.453125, 0.56250, 0.31250, 0.75000, 0.50000,
					0.140625, 0.890625, 0.078125, 0.828125, 0.18750, 0.93750, 0.12500, 0.87500,
					0.640625, 0.390625, 0.578125, 0.328125, 0.68750, 0.43750, 0.62500, 0.37500,
					0.046875, 0.796875, 0.234375, 0.984375, 0.03125, 0.78125, 0.21875, 0.96875,
					0.546875, 0.296875, 0.734375, 0.484375, 0.53125, 0.28125, 0.71875, 0.46875,
					0.171875, 0.921875, 0.109375, 0.859375, 0.15625, 0.90625, 0.09375, 0.84375,
					0.671875, 0.421875, 0.609375, 0.359375, 0.65625, 0.40625, 0.59375, 0.34375
				};
				int r = y * 8 + x;
				return dither[r];
			}
			
			half calcDither(half2 grabPos)
			{
				return Dither8x8Bayer(glsl_mod(grabPos.x, 8), glsl_mod(grabPos.y, 8));
			}
			
			void applyDithering(inout PoiFragData poiFragData, in PoiCam poiCam)
			{
				if (_AlphaDithering)
				{
					float dither = calcDither(poiCam.posScreenPixels) - _AlphaDitherBias;
					poiFragData.alpha = saturate(poiFragData.alpha - (dither * (1 - poiFragData.alpha) * _AlphaDitherGradient));
				}
			}
			//endex
			
			//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
			void ApplyAlphaToCoverage(inout PoiFragData poiFragData, in PoiMesh poiMesh)
			{
				// Force Model Opacity to 1 if desired
				UNITY_BRANCH
				if (_Mode == 1)
				{
					UNITY_BRANCH
					if (_AlphaSharpenedA2C && _AlphaToCoverage)
					{
						// rescale alpha by mip level
						poiFragData.alpha *= 1 + max(0, CalcMipLevel(poiMesh.uv[0] * _MainTex_TexelSize.zw)) * _AlphaMipScale;
						// rescale alpha by partial derivative
						poiFragData.alpha = (poiFragData.alpha - _Cutoff) / max(fwidth(poiFragData.alpha), 0.0001) + _Cutoff;
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
				}
			}
			//endex
			
			void calculateGlobalThemes(inout PoiMods poiMods)
			{
				// Theme colors are defined as HDR; convert to SDR and do the HSV adjustment, then re-apply exposure
				float4 themeColorExposures = 0;
				float4 themeColor0, themeColor1, themeColor2, themeColor3 = 0;
				
				DecomposeHDRColor(_GlobalThemeColor0.rgb, themeColor0.rgb, themeColorExposures.x);
				DecomposeHDRColor(_GlobalThemeColor1.rgb, themeColor1.rgb, themeColorExposures.y);
				DecomposeHDRColor(_GlobalThemeColor2.rgb, themeColor2.rgb, themeColorExposures.z);
				DecomposeHDRColor(_GlobalThemeColor3.rgb, themeColor3.rgb, themeColorExposures.w);
				
				poiMods.globalColorTheme[0] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor0.rgb, frac(_GlobalThemeHue0 + _GlobalThemeHueSpeed0 * _Time.x), _GlobalThemeSaturation0, _GlobalThemeValue0), themeColorExposures.x), _GlobalThemeColor0.a);
				poiMods.globalColorTheme[1] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor1.rgb, frac(_GlobalThemeHue1 + _GlobalThemeHueSpeed1 * _Time.x), _GlobalThemeSaturation1, _GlobalThemeValue1), themeColorExposures.y), _GlobalThemeColor1.a);
				poiMods.globalColorTheme[2] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor2.rgb, frac(_GlobalThemeHue2 + _GlobalThemeHueSpeed2 * _Time.x), _GlobalThemeSaturation2, _GlobalThemeValue2), themeColorExposures.z), _GlobalThemeColor2.a);
				poiMods.globalColorTheme[3] = float4(ApplyHDRExposure(ModifyViaHSV(themeColor3.rgb, frac(_GlobalThemeHue3 + _GlobalThemeHueSpeed3 * _Time.x), _GlobalThemeSaturation3, _GlobalThemeValue3), themeColorExposures.w), _GlobalThemeColor3.a);
			}
			
			//ifex _GlobalMaskTexturesEnable==0
			#ifdef POI_GLOBALMASK_TEXTURES
			void ApplyGlobalMaskTextures(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				#if defined(PROP_GLOBALMASKTEXTURE0) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol0 = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0_ST), _GlobalMaskTexture0Pan);
				if (_GlobalMaskTexture0Split)
				{
					poiMods.globalMask[0] = gmcol0.r;
					poiMods.globalMask[1] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_G), _GlobalMaskTexture0SplitPan_G).g;
					poiMods.globalMask[2] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_B), _GlobalMaskTexture0SplitPan_B).b;
					poiMods.globalMask[3] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_A), _GlobalMaskTexture0SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[0] = gmcol0[0];
					poiMods.globalMask[1] = gmcol0[1];
					poiMods.globalMask[2] = gmcol0[2];
					poiMods.globalMask[3] = gmcol0[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE1) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol1 = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1_ST), _GlobalMaskTexture1Pan);
				if (_GlobalMaskTexture1Split)
				{
					poiMods.globalMask[4] = gmcol1.r;
					poiMods.globalMask[5] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_G), _GlobalMaskTexture1SplitPan_G).g;
					poiMods.globalMask[6] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_B), _GlobalMaskTexture1SplitPan_B).b;
					poiMods.globalMask[7] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_A), _GlobalMaskTexture1SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[4] = gmcol1[0];
					poiMods.globalMask[5] = gmcol1[1];
					poiMods.globalMask[6] = gmcol1[2];
					poiMods.globalMask[7] = gmcol1[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE2) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol2 = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2_ST), _GlobalMaskTexture2Pan);
				if (_GlobalMaskTexture2Split)
				{
					poiMods.globalMask[8] = gmcol2.r;
					poiMods.globalMask[9] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_G), _GlobalMaskTexture2SplitPan_G).g;
					poiMods.globalMask[10] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_B), _GlobalMaskTexture2SplitPan_B).b;
					poiMods.globalMask[11] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_A), _GlobalMaskTexture2SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[8] = gmcol2[0];
					poiMods.globalMask[9] = gmcol2[1];
					poiMods.globalMask[10] = gmcol2[2];
					poiMods.globalMask[11] = gmcol2[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE3) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol3 = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3_ST), _GlobalMaskTexture3Pan);
				if (_GlobalMaskTexture3Split)
				{
					poiMods.globalMask[12] = gmcol3.r;
					poiMods.globalMask[13] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_G), _GlobalMaskTexture3SplitPan_G).g;
					poiMods.globalMask[14] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_B), _GlobalMaskTexture3SplitPan_B).b;
					poiMods.globalMask[15] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_A), _GlobalMaskTexture3SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[12] = gmcol3[0];
					poiMods.globalMask[13] = gmcol3[1];
					poiMods.globalMask[14] = gmcol3[2];
					poiMods.globalMask[15] = gmcol3[3];
				}
				#endif
			}
			#endif
			//endex
			//ifex _GlobalMaskOptionsEnable==0
			void ApplyGlobalMaskOptions(inout PoiMods poiMods)
			{
				//ifex _GlobalMaskOptionsType!=0
				if (_GlobalMaskOptionsType == 0)
				{
					poiMods.globalMask[0] = saturate(poiMods.globalMask[0] + _GlobalMaskSlider_0);
					poiMods.globalMask[1] = saturate(poiMods.globalMask[1] + _GlobalMaskSlider_1);
					poiMods.globalMask[2] = saturate(poiMods.globalMask[2] + _GlobalMaskSlider_2);
					poiMods.globalMask[3] = saturate(poiMods.globalMask[3] + _GlobalMaskSlider_3);
					poiMods.globalMask[4] = saturate(poiMods.globalMask[4] + _GlobalMaskSlider_4);
					poiMods.globalMask[5] = saturate(poiMods.globalMask[5] + _GlobalMaskSlider_5);
					poiMods.globalMask[6] = saturate(poiMods.globalMask[6] + _GlobalMaskSlider_6);
					poiMods.globalMask[7] = saturate(poiMods.globalMask[7] + _GlobalMaskSlider_7);
					poiMods.globalMask[8] = saturate(poiMods.globalMask[8] + _GlobalMaskSlider_8);
					poiMods.globalMask[9] = saturate(poiMods.globalMask[9] + _GlobalMaskSlider_9);
					poiMods.globalMask[10] = saturate(poiMods.globalMask[10] + _GlobalMaskSlider_10);
					poiMods.globalMask[11] = saturate(poiMods.globalMask[11] + _GlobalMaskSlider_11);
					poiMods.globalMask[12] = saturate(poiMods.globalMask[12] + _GlobalMaskSlider_12);
					poiMods.globalMask[13] = saturate(poiMods.globalMask[13] + _GlobalMaskSlider_13);
					poiMods.globalMask[14] = saturate(poiMods.globalMask[14] + _GlobalMaskSlider_14);
					poiMods.globalMask[15] = saturate(poiMods.globalMask[15] + _GlobalMaskSlider_15);
				}
				//endex
				//ifex _GlobalMaskOptionsType!=1
				if (_GlobalMaskOptionsType == 1)
				{
					poiMods.globalMask[0] = lerp(_GlobalMaskMinMaxSlider_0.x, _GlobalMaskMinMaxSlider_0.y, poiMods.globalMask[0]);
					poiMods.globalMask[1] = lerp(_GlobalMaskMinMaxSlider_1.x, _GlobalMaskMinMaxSlider_1.y, poiMods.globalMask[1]);
					poiMods.globalMask[2] = lerp(_GlobalMaskMinMaxSlider_2.x, _GlobalMaskMinMaxSlider_2.y, poiMods.globalMask[2]);
					poiMods.globalMask[3] = lerp(_GlobalMaskMinMaxSlider_3.x, _GlobalMaskMinMaxSlider_3.y, poiMods.globalMask[3]);
					poiMods.globalMask[4] = lerp(_GlobalMaskMinMaxSlider_4.x, _GlobalMaskMinMaxSlider_4.y, poiMods.globalMask[4]);
					poiMods.globalMask[5] = lerp(_GlobalMaskMinMaxSlider_5.x, _GlobalMaskMinMaxSlider_5.y, poiMods.globalMask[5]);
					poiMods.globalMask[6] = lerp(_GlobalMaskMinMaxSlider_6.x, _GlobalMaskMinMaxSlider_6.y, poiMods.globalMask[6]);
					poiMods.globalMask[7] = lerp(_GlobalMaskMinMaxSlider_7.x, _GlobalMaskMinMaxSlider_7.y, poiMods.globalMask[7]);
					poiMods.globalMask[8] = lerp(_GlobalMaskMinMaxSlider_8.x, _GlobalMaskMinMaxSlider_8.y, poiMods.globalMask[8]);
					poiMods.globalMask[9] = lerp(_GlobalMaskMinMaxSlider_9.x, _GlobalMaskMinMaxSlider_9.y, poiMods.globalMask[9]);
					poiMods.globalMask[10] = lerp(_GlobalMaskMinMaxSlider_10.x, _GlobalMaskMinMaxSlider_10.y, poiMods.globalMask[10]);
					poiMods.globalMask[11] = lerp(_GlobalMaskMinMaxSlider_11.x, _GlobalMaskMinMaxSlider_11.y, poiMods.globalMask[11]);
					poiMods.globalMask[12] = lerp(_GlobalMaskMinMaxSlider_12.x, _GlobalMaskMinMaxSlider_12.y, poiMods.globalMask[12]);
					poiMods.globalMask[13] = lerp(_GlobalMaskMinMaxSlider_13.x, _GlobalMaskMinMaxSlider_13.y, poiMods.globalMask[13]);
					poiMods.globalMask[14] = lerp(_GlobalMaskMinMaxSlider_14.x, _GlobalMaskMinMaxSlider_14.y, poiMods.globalMask[14]);
					poiMods.globalMask[15] = lerp(_GlobalMaskMinMaxSlider_15.x, _GlobalMaskMinMaxSlider_15.y, poiMods.globalMask[15]);
				}
				//endex
				//ifex _GlobalMaskOptionsType!=2
				if (_GlobalMaskOptionsType == 2)
				{
					if (_GlobalMaskToggleOn_0)  poiMods.globalMask[0] = 1;
					if (_GlobalMaskToggleOn_1)  poiMods.globalMask[1] = 1;
					if (_GlobalMaskToggleOn_2)  poiMods.globalMask[2] = 1;
					if (_GlobalMaskToggleOn_3)  poiMods.globalMask[3] = 1;
					if (_GlobalMaskToggleOn_4)  poiMods.globalMask[4] = 1;
					if (_GlobalMaskToggleOn_5)  poiMods.globalMask[5] = 1;
					if (_GlobalMaskToggleOn_6)  poiMods.globalMask[6] = 1;
					if (_GlobalMaskToggleOn_7)  poiMods.globalMask[7] = 1;
					if (_GlobalMaskToggleOn_8)  poiMods.globalMask[8] = 1;
					if (_GlobalMaskToggleOn_9)  poiMods.globalMask[9] = 1;
					if (_GlobalMaskToggleOn_10) poiMods.globalMask[10] = 1;
					if (_GlobalMaskToggleOn_11) poiMods.globalMask[11] = 1;
					if (_GlobalMaskToggleOn_12) poiMods.globalMask[12] = 1;
					if (_GlobalMaskToggleOn_13) poiMods.globalMask[13] = 1;
					if (_GlobalMaskToggleOn_14) poiMods.globalMask[14] = 1;
					if (_GlobalMaskToggleOn_15) poiMods.globalMask[15] = 1;
					
					poiMods.globalMask[0] *= (1 - _GlobalMaskToggleOff_0);
					poiMods.globalMask[1] *= (1 - _GlobalMaskToggleOff_1);
					poiMods.globalMask[2] *= (1 - _GlobalMaskToggleOff_2);
					poiMods.globalMask[3] *= (1 - _GlobalMaskToggleOff_3);
					poiMods.globalMask[4] *= (1 - _GlobalMaskToggleOff_4);
					poiMods.globalMask[5] *= (1 - _GlobalMaskToggleOff_5);
					poiMods.globalMask[6] *= (1 - _GlobalMaskToggleOff_6);
					poiMods.globalMask[7] *= (1 - _GlobalMaskToggleOff_7);
					poiMods.globalMask[8] *= (1 - _GlobalMaskToggleOff_8);
					poiMods.globalMask[9] *= (1 - _GlobalMaskToggleOff_9);
					poiMods.globalMask[10] *= (1 - _GlobalMaskToggleOff_10);
					poiMods.globalMask[11] *= (1 - _GlobalMaskToggleOff_11);
					poiMods.globalMask[12] *= (1 - _GlobalMaskToggleOff_12);
					poiMods.globalMask[13] *= (1 - _GlobalMaskToggleOff_13);
					poiMods.globalMask[14] *= (1 - _GlobalMaskToggleOff_14);
					poiMods.globalMask[15] *= (1 - _GlobalMaskToggleOff_15);
				}
				//endex
				
			}
			//endex
			
			float customDistanceBlend(float base, float blend, float blendType)
			{
				switch(blendType)
				{
					case 0: return blendNormal(base, blend); break;
					case 2: return blendMultiply(base, blend); break;
					default: return 0; break;
				}
			}
			
			void handleGlobalMaskDistance(int index, bool enable, bool type, float minAlpha, float maxAlpha, float min, float max, int blendType, in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				if (enable)
				{
					float3 position = type ? poiMesh.worldPos : poiMesh.objectPosition;
					float val = lerp(minAlpha, maxAlpha, smoothstep(min, max, distance(position, _WorldSpaceCameraPos)));
					poiMods.globalMask[index] = saturate(customDistanceBlend(poiMods.globalMask[index], val, blendType));
				}
			}
			
			void ApplyGlobalMaskModifiers(in PoiMesh poiMesh, inout PoiMods poiMods, in PoiCam poiCam)
			{
				//ifex _GlobalMaskModifiersBackfaceEnable==0
				if (_GlobalMaskModifiersBackfaceEnable)
				{
					float facingMode = saturate(poiMesh.isFrontFace) + 1;
					// _GlobalMaskBackface is 0 for ignore, 1 for back only, 2 for front only
					poiMods.globalMask[0] *= _GlobalMaskBackface_0 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_0));
					poiMods.globalMask[1] *= _GlobalMaskBackface_1 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_1));
					poiMods.globalMask[2] *= _GlobalMaskBackface_2 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_2));
					poiMods.globalMask[3] *= _GlobalMaskBackface_3 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_3));
					poiMods.globalMask[4] *= _GlobalMaskBackface_4 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_4));
					poiMods.globalMask[5] *= _GlobalMaskBackface_5 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_5));
					poiMods.globalMask[6] *= _GlobalMaskBackface_6 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_6));
					poiMods.globalMask[7] *= _GlobalMaskBackface_7 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_7));
					poiMods.globalMask[8] *= _GlobalMaskBackface_8 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_8));
					poiMods.globalMask[9] *= _GlobalMaskBackface_9 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_9));
					poiMods.globalMask[10] *= _GlobalMaskBackface_10 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_10));
					poiMods.globalMask[11] *= _GlobalMaskBackface_11 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_11));
					poiMods.globalMask[12] *= _GlobalMaskBackface_12 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_12));
					poiMods.globalMask[13] *= _GlobalMaskBackface_13 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_13));
					poiMods.globalMask[14] *= _GlobalMaskBackface_14 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_14));
					poiMods.globalMask[15] *= _GlobalMaskBackface_15 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_15));
				}
				//endex
				
				//ifex _GlobalMaskModifiersMirrorEnable==0
				if (_GlobalMaskModifiersMirrorEnable)
				{
					float mirrorMode = 0;
					if (_GlobalMaskMirrorVisibilityMode == 1) // VRC
					mirrorMode = VRCMirrorMode() > 0;
					else // Generic (CVR, etc)
					mirrorMode = IsInMirror();
					
					mirrorMode += 1;
					// _GlobalMaskMirror is 0 for ignore, 1 for outside mirror only, 2 for in mirror only
					poiMods.globalMask[0] *= _GlobalMaskMirror_0 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_0));
					poiMods.globalMask[1] *= _GlobalMaskMirror_1 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_1));
					poiMods.globalMask[2] *= _GlobalMaskMirror_2 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_2));
					poiMods.globalMask[3] *= _GlobalMaskMirror_3 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_3));
					poiMods.globalMask[4] *= _GlobalMaskMirror_4 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_4));
					poiMods.globalMask[5] *= _GlobalMaskMirror_5 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_5));
					poiMods.globalMask[6] *= _GlobalMaskMirror_6 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_6));
					poiMods.globalMask[7] *= _GlobalMaskMirror_7 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_7));
					poiMods.globalMask[8] *= _GlobalMaskMirror_8 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_8));
					poiMods.globalMask[9] *= _GlobalMaskMirror_9 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_9));
					poiMods.globalMask[10] *= _GlobalMaskMirror_10 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_10));
					poiMods.globalMask[11] *= _GlobalMaskMirror_11 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_11));
					poiMods.globalMask[12] *= _GlobalMaskMirror_12 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_12));
					poiMods.globalMask[13] *= _GlobalMaskMirror_13 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_13));
					poiMods.globalMask[14] *= _GlobalMaskMirror_14 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_14));
					poiMods.globalMask[15] *= _GlobalMaskMirror_15 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_15));
				}
				//endex
				
				//ifex _GlobalMaskModifiersCameraEnable==0
				if (_GlobalMaskModifiersCameraEnable)
				{
					float isCamera = VRCCameraMode() > 0;
					isCamera += 1;
					// _GlobalMaskCamera is 0 for ignore, 1 for outside camera only, 2 for in camera only
					poiMods.globalMask[0] *= _GlobalMaskCamera_0 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_0));
					poiMods.globalMask[1] *= _GlobalMaskCamera_1 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_1));
					poiMods.globalMask[2] *= _GlobalMaskCamera_2 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_2));
					poiMods.globalMask[3] *= _GlobalMaskCamera_3 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_3));
					poiMods.globalMask[4] *= _GlobalMaskCamera_4 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_4));
					poiMods.globalMask[5] *= _GlobalMaskCamera_5 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_5));
					poiMods.globalMask[6] *= _GlobalMaskCamera_6 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_6));
					poiMods.globalMask[7] *= _GlobalMaskCamera_7 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_7));
					poiMods.globalMask[8] *= _GlobalMaskCamera_8 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_8));
					poiMods.globalMask[9] *= _GlobalMaskCamera_9 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_9));
					poiMods.globalMask[10] *= _GlobalMaskCamera_10 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_10));
					poiMods.globalMask[11] *= _GlobalMaskCamera_11 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_11));
					poiMods.globalMask[12] *= _GlobalMaskCamera_12 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_12));
					poiMods.globalMask[13] *= _GlobalMaskCamera_13 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_13));
					poiMods.globalMask[14] *= _GlobalMaskCamera_14 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_14));
					poiMods.globalMask[15] *= _GlobalMaskCamera_15 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_15));
				}
				//endex
				//ifex _GlobalMaskModifiersDistanceEnable==0
				if (_GlobalMaskModifiersDistanceEnable)
				{
					//ifex _GlobalMaskDistanceEnable_0==0
					handleGlobalMaskDistance(0, _GlobalMaskDistanceEnable_0, _GlobalMaskDistanceType_0, _GlobalMaskDistanceMinAlpha_0, _GlobalMaskDistanceMaxAlpha_0, _GlobalMaskDistanceMin_0, _GlobalMaskDistanceMax_0, _GlobalMaskDistanceBlendType_0, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_1==0
					handleGlobalMaskDistance(1, _GlobalMaskDistanceEnable_1, _GlobalMaskDistanceType_1, _GlobalMaskDistanceMinAlpha_1, _GlobalMaskDistanceMaxAlpha_1, _GlobalMaskDistanceMin_1, _GlobalMaskDistanceMax_1, _GlobalMaskDistanceBlendType_1, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_2==0
					handleGlobalMaskDistance(2, _GlobalMaskDistanceEnable_2, _GlobalMaskDistanceType_2, _GlobalMaskDistanceMinAlpha_2, _GlobalMaskDistanceMaxAlpha_2, _GlobalMaskDistanceMin_2, _GlobalMaskDistanceMax_2, _GlobalMaskDistanceBlendType_2, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_3==0
					handleGlobalMaskDistance(3, _GlobalMaskDistanceEnable_3, _GlobalMaskDistanceType_3, _GlobalMaskDistanceMinAlpha_3, _GlobalMaskDistanceMaxAlpha_3, _GlobalMaskDistanceMin_3, _GlobalMaskDistanceMax_3, _GlobalMaskDistanceBlendType_3, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_4==0
					handleGlobalMaskDistance(4, _GlobalMaskDistanceEnable_4, _GlobalMaskDistanceType_4, _GlobalMaskDistanceMinAlpha_4, _GlobalMaskDistanceMaxAlpha_4, _GlobalMaskDistanceMin_4, _GlobalMaskDistanceMax_4, _GlobalMaskDistanceBlendType_4, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_5==0
					handleGlobalMaskDistance(5, _GlobalMaskDistanceEnable_5, _GlobalMaskDistanceType_5, _GlobalMaskDistanceMinAlpha_5, _GlobalMaskDistanceMaxAlpha_5, _GlobalMaskDistanceMin_5, _GlobalMaskDistanceMax_5, _GlobalMaskDistanceBlendType_5, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_6==0
					handleGlobalMaskDistance(6, _GlobalMaskDistanceEnable_6, _GlobalMaskDistanceType_6, _GlobalMaskDistanceMinAlpha_6, _GlobalMaskDistanceMaxAlpha_6, _GlobalMaskDistanceMin_6, _GlobalMaskDistanceMax_6, _GlobalMaskDistanceBlendType_6, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_7==0
					handleGlobalMaskDistance(7, _GlobalMaskDistanceEnable_7, _GlobalMaskDistanceType_7, _GlobalMaskDistanceMinAlpha_7, _GlobalMaskDistanceMaxAlpha_7, _GlobalMaskDistanceMin_7, _GlobalMaskDistanceMax_7, _GlobalMaskDistanceBlendType_7, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_8==0
					handleGlobalMaskDistance(8, _GlobalMaskDistanceEnable_8, _GlobalMaskDistanceType_8, _GlobalMaskDistanceMinAlpha_8, _GlobalMaskDistanceMaxAlpha_8, _GlobalMaskDistanceMin_8, _GlobalMaskDistanceMax_8, _GlobalMaskDistanceBlendType_8, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_9==0
					handleGlobalMaskDistance(9, _GlobalMaskDistanceEnable_9, _GlobalMaskDistanceType_9, _GlobalMaskDistanceMinAlpha_9, _GlobalMaskDistanceMaxAlpha_9, _GlobalMaskDistanceMin_9, _GlobalMaskDistanceMax_9, _GlobalMaskDistanceBlendType_9, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_10==0
					handleGlobalMaskDistance(10, _GlobalMaskDistanceEnable_10, _GlobalMaskDistanceType_10, _GlobalMaskDistanceMinAlpha_10, _GlobalMaskDistanceMaxAlpha_10, _GlobalMaskDistanceMin_10, _GlobalMaskDistanceMax_10, _GlobalMaskDistanceBlendType_10, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_11==0
					handleGlobalMaskDistance(11, _GlobalMaskDistanceEnable_11, _GlobalMaskDistanceType_11, _GlobalMaskDistanceMinAlpha_11, _GlobalMaskDistanceMaxAlpha_11, _GlobalMaskDistanceMin_11, _GlobalMaskDistanceMax_11, _GlobalMaskDistanceBlendType_11, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_12==0
					handleGlobalMaskDistance(12, _GlobalMaskDistanceEnable_12, _GlobalMaskDistanceType_12, _GlobalMaskDistanceMinAlpha_12, _GlobalMaskDistanceMaxAlpha_12, _GlobalMaskDistanceMin_12, _GlobalMaskDistanceMax_12, _GlobalMaskDistanceBlendType_12, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_13==0
					handleGlobalMaskDistance(13, _GlobalMaskDistanceEnable_13, _GlobalMaskDistanceType_13, _GlobalMaskDistanceMinAlpha_13, _GlobalMaskDistanceMaxAlpha_13, _GlobalMaskDistanceMin_13, _GlobalMaskDistanceMax_13, _GlobalMaskDistanceBlendType_13, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_14==0
					handleGlobalMaskDistance(14, _GlobalMaskDistanceEnable_14, _GlobalMaskDistanceType_14, _GlobalMaskDistanceMinAlpha_14, _GlobalMaskDistanceMaxAlpha_14, _GlobalMaskDistanceMin_14, _GlobalMaskDistanceMax_14, _GlobalMaskDistanceBlendType_14, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_15==0
					handleGlobalMaskDistance(15, _GlobalMaskDistanceEnable_15, _GlobalMaskDistanceType_15, _GlobalMaskDistanceMinAlpha_15, _GlobalMaskDistanceMaxAlpha_15, _GlobalMaskDistanceMin_15, _GlobalMaskDistanceMax_15, _GlobalMaskDistanceBlendType_15, poiMesh, poiMods);
					//endex
					
				}
				//endex
				
			}
			
			//ifex _GlobalMaskVertexColorRed==0 && _GlobalMaskVertexColorGreen==0 && _GlobalMaskVertexColorBlue==0 && _GlobalMaskVertexColorAlpha==0
			void ApplyGlobalMaskVertexColors(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				float4 vcol = poiMesh.vertexColor;
				if (_GlobalMaskVertexColorLinearSpace)
				{
					vcol.rgb = GammaToLinearSpace(vcol.rgb);
				}
				if (_GlobalMaskVertexColorRed > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorRed - 1, _GlobalMaskVertexColorRedBlendType, vcol.r);
				}
				if (_GlobalMaskVertexColorGreen > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorGreen - 1, _GlobalMaskVertexColorGreenBlendType, vcol.g);
				}
				if (_GlobalMaskVertexColorBlue > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorBlue - 1, _GlobalMaskVertexColorBlueBlendType, vcol.b);
				}
				if (_GlobalMaskVertexColorAlpha > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorAlpha - 1, _GlobalMaskVertexColorAlphaBlendType, vcol.a);
				}
			}
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#ifdef POI_UDIMDISCARD
			void applyUDIMDiscard(in VertexOut i)
			{
				if(_UDIMDiscardMode == 1) // Don't run if in vertex mode
				{
					float2 udim = floor(vertexUV(i, _UDIMDiscardUV));
					
					float isDiscarded = 0;
					float4 xMask = float4(  (udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					isDiscarded += (udim.y >= 0 && udim.y < 1) * dot(float4(_UDIMDiscardRow0_0, _UDIMDiscardRow0_1, _UDIMDiscardRow0_2, _UDIMDiscardRow0_3), xMask);
					isDiscarded += (udim.y >= 1 && udim.y < 2) * dot(float4(_UDIMDiscardRow1_0, _UDIMDiscardRow1_1, _UDIMDiscardRow1_2, _UDIMDiscardRow1_3), xMask);
					isDiscarded += (udim.y >= 2 && udim.y < 3) * dot(float4(_UDIMDiscardRow2_0, _UDIMDiscardRow2_1, _UDIMDiscardRow2_2, _UDIMDiscardRow2_3), xMask);
					isDiscarded += (udim.y >= 3 && udim.y < 4) * dot(float4(_UDIMDiscardRow3_0, _UDIMDiscardRow3_1, _UDIMDiscardRow3_2, _UDIMDiscardRow3_3), xMask);
					
					isDiscarded *= any(float4(udim.y >= 0, udim.y < 4, udim.x >= 0, udim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					const float threshold = 0.001;
					clip(threshold - isDiscarded); // Clip if discarded
				}
				
				return;
			}
			#endif
			//endex
			
			float2 calculatePolarCoordinate(in PoiMesh poiMesh)
			{
				float2 delta = poiMesh.uv[_PolarUV] - _PolarCenter;
				float radius = length(delta) * 2 * _PolarRadialScale;
				float angle = atan2(delta.x, delta.y);
				float phi = angle / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				angle = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				angle *= _PolarLengthScale;
				
				return float2(radius, angle + distance(poiMesh.uv[_PolarUV], _PolarCenter) * _PolarSpiralPower);
			}
			
			float2 MonoPanoProjection(float3 coords)
			{
				float3 normalizedCoords = normalize(coords);
				float latitude = acos(normalizedCoords.y);
				float longitude = atan2(normalizedCoords.z, normalizedCoords.x);
				float phi = longitude / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				longitude = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				longitude *= 2;
				float2 sphereCoords = float2(longitude, latitude) * float2(1.0, 1.0 / UNITY_PI);
				sphereCoords = float2(1.0, 1.0) - sphereCoords;
				return (sphereCoords + float4(0, 1 - unity_StereoEyeIndex, 1, 1.0).xy) * float4(0, 1 - unity_StereoEyeIndex, 1, 1.0).zw;
			}
			
			float2 StereoPanoProjection(float3 coords)
			{
				float3 normalizedCoords = normalize(coords);
				float latitude = acos(normalizedCoords.y);
				float longitude = atan2(normalizedCoords.z, normalizedCoords.x);
				float phi = longitude / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				longitude = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				longitude *= 2;
				float2 sphereCoords = float2(longitude, latitude) * float2(0.5, 1.0 / UNITY_PI);
				sphereCoords = float2(0.5, 1.0) - sphereCoords;
				return (sphereCoords + float4(0, 1 - unity_StereoEyeIndex, 1, 0.5).xy) * float4(0, 1 - unity_StereoEyeIndex, 1, 0.5).zw;
			}
			
			float2 calculateWorldUV(in PoiMesh poiMesh)
			{
				return float2(_UVModWorldPos0 != 3 ? poiMesh.worldPos[ _UVModWorldPos0] : 0.0f, _UVModWorldPos1 != 3 ? poiMesh.worldPos[_UVModWorldPos1] : 0.0f);
			}
			
			float2 calculatelocalUV(in PoiMesh poiMesh)
			{
				float localUVs[8];
				localUVs[0] = poiMesh.localPos.x;
				localUVs[1] = poiMesh.localPos.y;
				localUVs[2] = poiMesh.localPos.z;
				localUVs[3] = 0;
				localUVs[4] = poiMesh.vertexColor.r;
				localUVs[5] = poiMesh.vertexColor.g;
				localUVs[6] = poiMesh.vertexColor.b;
				localUVs[7] = poiMesh.vertexColor.a;
				
				return float2(localUVs[_UVModLocalPos0],localUVs[_UVModLocalPos1]);
			}
			
			float2 calculatePanosphereUV(in PoiMesh poiMesh)
			{
				float3 viewDirection = normalize(lerp(getCameraPosition().xyz, _WorldSpaceCameraPos.xyz, _PanoUseBothEyes) - poiMesh.worldPos.xyz) * - 1;
				return lerp(MonoPanoProjection(viewDirection), StereoPanoProjection(viewDirection), _StereoEnabled);
			}
			//ifex _EnableDistortion==0
			#ifdef USER_LUT
			float2 distortedUV(in PoiMesh poiMesh)
			{
				#if defined(PROP_DISTORTIONFLOWTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 flowVector = POI2D_SAMPLER_PAN(_DistortionFlowTexture, _MainTex, poiUV(poiMesh.uv[_DistortionFlowTextureUV], _DistortionFlowTexture_ST), _DistortionFlowTexturePan) * 2 - 1;
				#else
				float4 flowVector = -1;
				#endif
				
				#if defined(PROP_DISTORTIONFLOWTEXTURE1) || !defined(OPTIMIZER_ENABLED)
				float4 flowVector1 = POI2D_SAMPLER_PAN(_DistortionFlowTexture1, _MainTex, poiUV(poiMesh.uv[_DistortionFlowTexture1UV], _DistortionFlowTexture1_ST), _DistortionFlowTexture1Pan) * 2 - 1;
				#else
				float4 flowVector1 = -1;
				#endif
				
				#if defined(PROP_DISTORTIONMASK) || !defined(OPTIMIZER_ENABLED)
				half distortionMask = POI2D_SAMPLER_PAN(_DistortionMask, _MainTex, poiMesh.uv[_DistortionMaskUV], _DistortionMaskPan)[_DistortionMaskChannel];
				#else
				half distortionMask = 1;
				#endif
				
				half distortionStrength = _DistortionStrength;
				half distortionStrength1 = _DistortionStrength1;
				
				#ifdef POI_AUDIOLINK
				UNITY_BRANCH
				if (AudioLinkIsAvailable() && _EnableDistortionAudioLink && _AudioLinkAnimToggle)
				{
					distortionStrength += lerp(_DistortionStrengthAudioLink.x, _DistortionStrengthAudioLink.y, AudioLinkData(uint2(0, uint(_DistortionStrengthAudioLinkBand))).r);
					distortionStrength1 += lerp(_DistortionStrength1AudioLink.x, _DistortionStrength1AudioLink.y, AudioLinkData(uint2(0, uint(_DistortionStrength1AudioLinkBand))).r);
				}
				#endif
				
				flowVector *= distortionStrength;
				flowVector1 *= distortionStrength1;
				return poiMesh.uv[_DistortionUvToDistort] + ((flowVector.xy + flowVector1.xy) / 2) * distortionMask;
			}
			#endif
			//endex
			
			//ifex _PoiParallax==0
			#ifdef POI_PARALLAX
			inline float2 POM(in PoiLight poiLight, sampler2D heightMap, in PoiMesh poiMesh, float3 worldViewDir, float3 viewDirTan, int minSamples, int maxSamples, float parallax, float refPlane, float2 tilling, float2 curv)
			{
				#if defined(PROP_HEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float heightMask = POI2D_SAMPLER_PAN(_Heightmask, _linear_repeat, poiUV(poiMesh.uv[_HeightmaskUV], _Heightmask_ST), _HeightmaskPan)[_HeightmaskChannel];
				if (_HeightmaskInvert)
				{
					heightMask = 1 - heightMask;
				}
				#else
				float heightMask = 1;
				#endif
				
				float2 uvs = poiUV(poiMesh.uv[_HeightMapUV], _HeightMap_ST);
				float2 dx = ddx(uvs);
				float2 dy = ddy(uvs);
				float3 result = 0;
				int stepIndex = 0;
				int numSteps = (int)lerp(maxSamples, minSamples, saturate(dot(poiMesh.normals[0], worldViewDir)));
				float layerHeight = 1.0 / numSteps;
				float2 plane = parallax * heightMask * (viewDirTan.xy / viewDirTan.z);
				uvs += refPlane * plane;
				float2 deltaTex = -plane * layerHeight;
				float2 prevTexOffset = 0;
				float prevRayZ = 1.0f;
				float prevHeight = 0.0f;
				float2 currTexOffset = deltaTex;
				float currRayZ = 1.0f - layerHeight;
				float currHeight = 0.0f;
				float intersection = 0;
				float2 finalTexOffset = 0;
				while (stepIndex < numSteps + 1)
				{
					result.z = dot(curv, currTexOffset * currTexOffset);
					currHeight = tex2Dgrad(heightMap, uvs + currTexOffset, dx, dy).r * (1 - result.z);
					if (currHeight > currRayZ)
					{
						stepIndex = numSteps + 1;
					}
					else
					{
						stepIndex++;
						prevTexOffset = currTexOffset;
						prevRayZ = currRayZ;
						prevHeight = currHeight;
						currTexOffset += deltaTex;
						currRayZ -= layerHeight * (1 - result.z) * (1 + _CurvFix);
					}
				}
				int sectionSteps = 10;
				int sectionIndex = 0;
				float newZ = 0;
				float newHeight = 0;
				while (sectionIndex < sectionSteps)
				{
					intersection = (prevHeight - prevRayZ) / (prevHeight - currHeight + currRayZ - prevRayZ);
					finalTexOffset = prevTexOffset +intersection * deltaTex;
					newZ = prevRayZ - intersection * layerHeight;
					newHeight = tex2Dgrad(heightMap, uvs + finalTexOffset, dx, dy).r;
					if (newHeight > newZ)
					{
						currTexOffset = finalTexOffset;
						currHeight = newHeight;
						currRayZ = newZ;
						deltaTex = intersection * deltaTex;
						layerHeight = intersection * layerHeight;
					}
					else
					{
						prevTexOffset = finalTexOffset;
						prevHeight = newHeight;
						prevRayZ = newZ;
						deltaTex = (1 - intersection) * deltaTex;
						layerHeight = (1 - intersection) * layerHeight;
					}
					sectionIndex++;
				}
				#ifdef UNITY_PASS_SHADOWCASTER
				if (unity_LightShadowBias.z == 0.0)
				{
					#endif
					if (result.z > 1)
					clip(-1);
					#ifdef UNITY_PASS_SHADOWCASTER
				}
				#endif
				
				return uvs + finalTexOffset;
			}
			/*
			float2 ParallaxOffsetMultiStep(float surfaceHeight, float strength, float2 uv, float3 tangentViewDir)
			{
				float2 uvOffset = 0;
				float2 prevUVOffset = 0;
				float stepSize = 1.0 / _HeightSteps;
				float stepHeight = 1;
				float2 uvDelta = tangentViewDir.xy * (stepSize * strength);
				float prevStepHeight = stepHeight;
				float prevSurfaceHeight = surfaceHeight;
				
				[unroll(20)]
				for (int j = 1; j <= _HeightSteps && stepHeight > surfaceHeight; j++)
				{
					prevUVOffset = uvOffset;
					prevStepHeight = stepHeight;
					prevSurfaceHeight = surfaceHeight;
					uvOffset -= uvDelta;
					stepHeight -= stepSize;
					surfaceHeight = POI2D_SAMPLER_PAN(_Heightmap, _MainTex, poiUV(uv + uvOffset, _Heightmap_ST), _HeightmapPan) + _HeightOffset;
				}
				
				[unroll(3)]
				for (int k = 0; k < 3; k++)
				{
					uvDelta *= 0.5;
					stepSize *= 0.5;
					
					if (stepHeight < surfaceHeight)
					{
						uvOffset += uvDelta;
						stepHeight += stepSize;
					}
					else
					{
						uvOffset -= uvDelta;
						stepHeight -= stepSize;
					}
					surfaceHeight = POI2D_SAMPLER_PAN(_Heightmap, _MainTex, poiUV(uv + uvOffset, _Heightmap_ST), _HeightmapPan) + _HeightOffset;
				}
				return uvOffset;
			}
			*/
			void applyParallax(inout PoiMesh poiMesh, in PoiLight poiLight, in PoiCam poiCam)
			{
				/*
				half h = POI2D_SAMPLER_PAN(_Heightmap, _linear_repeat, poiUV(poiMesh.uv[_HeightmaskUV], _Heightmap_ST), _HeightmapPan).r + _HeightOffset;
				#if defined(PROP_HEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				half m = POI2D_SAMPLER_PAN(_Heightmask, _linear_repeat, poiUV(poiMesh.uv[_HeightmaskUV], _Heightmask_ST), _HeightmaskPan).r + _HeightOffset;
				#else
				half m = 1 + _HeightOffset;
				#endif
				h = clamp(h, 0, 0.999);
				m = lerp(m, 1 - m, _HeightmaskInvert);
				#if defined(OPTIMIZER_ENABLED)das
				poiMesh.uv[_ParallaxUV] += ParallaxOffsetMultiStep(h, _HeightStrength * m, poiMesh.uv[_HeightmapUV], tangentViewDir / tangentViewDir.z);
				#else
				float2 offset = ParallaxOffsetMultiStep(h, _HeightStrength * m, poiMesh.uv[_HeightmapUV], tangentViewDir / tangentViewDir.z);
				if (_ParallaxUV == 0)       poiMesh.uv[0] += offset;
				if (_ParallaxUV == 1)       poiMesh.uv[1] += offset;
				if (_ParallaxUV == 2)       poiMesh.uv[2] += offset;
				if (_ParallaxUV == 3)       poiMesh.uv[3] += offset;
				if (_ParallaxUV == 4)       poiMesh.uv[4] += offset;
				if (_ParallaxUV == 5)       poiMesh.uv[5] += offset;
				if (_ParallaxUV == 6)       poiMesh.uv[6] += offset;
				if (_ParallaxUV == 7)       poiMesh.uv[7] += offset;
				#endif
				*/
				
				#if defined(OPTIMIZER_ENABLED)
				poiMesh.uv[_ParallaxUV] = POM(poiLight, _HeightMap, poiMesh, poiCam.viewDir, poiCam.tangentViewDir, _HeightStepsMin, _HeightStepsMax, _HeightStrength, 0, _HeightMap_ST.xy, float2(_CurvatureU, _CurvatureV));
				#else
				float2 offset = POM(poiLight, _HeightMap, poiMesh, poiCam.viewDir, poiCam.tangentViewDir, _HeightStepsMin, _HeightStepsMax, _HeightStrength, 0, _HeightMap_ST.xy, float2(_CurvatureU, _CurvatureV));
				if (_ParallaxUV == 0)       poiMesh.uv[0] = offset;
				if (_ParallaxUV == 1)       poiMesh.uv[1] = offset;
				if (_ParallaxUV == 2)       poiMesh.uv[2] = offset;
				if (_ParallaxUV == 3)       poiMesh.uv[3] = offset;
				if (_ParallaxUV == 4)       poiMesh.uv[4] = offset;
				if (_ParallaxUV == 5)       poiMesh.uv[5] = offset;
				if (_ParallaxUV == 6)       poiMesh.uv[6] = offset;
				if (_ParallaxUV == 7)       poiMesh.uv[7] = offset;
				#endif
			}
			#endif
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#ifdef POI_BLACKLIGHTMASKING
			void calculateBlackLightMasks(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				#ifdef VERTEXLIGHT_ON
				for (int lightIndex = 0; lightIndex < 4; lightIndex++)
				{
					float3 lightPos = float3(unity_4LightPosX0[lightIndex], unity_4LightPosY0[lightIndex], unity_4LightPosZ0[lightIndex]);
					if (!distance(unity_LightColor[lightIndex].rgb, float3(0, 0, 0)))
					{
						if (_BlackLightMasking0GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking0Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking0GlobalMaskIndex - 1, _BlackLightMasking0GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking1GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking1Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking1GlobalMaskIndex - 1, _BlackLightMasking1GlobalMaskBlendType, smoothstep(_BlackLightMasking1Range.y, _BlackLightMasking1Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking2GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking2Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking2GlobalMaskIndex - 1, _BlackLightMasking2GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking3GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking3Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking3GlobalMaskIndex - 1, _BlackLightMasking3GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
					}
				}
				#else
				if (_BlackLightMasking0GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking0GlobalMaskIndex - 1, _BlackLightMasking0GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking1GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking1GlobalMaskIndex - 1, _BlackLightMasking1GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking2GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking2GlobalMaskIndex - 1, _BlackLightMasking2GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking3GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking3GlobalMaskIndex - 1, _BlackLightMasking3GlobalMaskBlendType, 0);
				}
				#endif
			}
			#endif
			//endex
			
			//ifex _DetailEnabled==0
			#ifdef FINALPASS
			void ApplyDetailColor(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				#if defined(PROP_DETAILTEX) || !defined(OPTIMIZER_ENABLED)
				half3 detailTexture = POI2D_SAMPLER_PAN_STOCHASTIC(_DetailTex, _MainTex, poiUV(poiMesh.uv[_DetailTexUV], _DetailTex_ST), _DetailTexPan, _DetailTexStochastic).rgb * poiThemeColor(poiMods, _DetailTint, _DetailTintThemeIndex);
				#else
				half3 detailTexture = 0.21763764082 * poiThemeColor(poiMods, _DetailTint, _DetailTintThemeIndex);
				#endif
				
				poiFragData.baseColor.rgb *= LerpWhiteTo(detailTexture * _DetailBrightness * unity_ColorSpaceDouble.rgb, poiMods.detailMask.r * _DetailTexIntensity);
			}
			
			void ApplyDetailNormal(inout PoiMods poiMods, inout PoiMesh poiMesh)
			{
				#if defined(PROP_DETAILMASK) || !defined(OPTIMIZER_ENABLED)
				poiMods.detailMask = POI2D_SAMPLER_PAN_STOCHASTIC(_DetailMask, _MainTex, poiUV(poiMesh.uv[_DetailMaskUV], _DetailMask_ST), _DetailMaskPan, _DetailMaskStochastic).rg;
				#else
				poiMods.detailMask = 1;
				#endif
				
				#ifdef POI_BACKFACE
				if (!poiMesh.isFrontFace)
				{
					poiMods.detailMask.rg *= _BackFaceDetailIntensity;
				}
				#endif
				
				if (_DetailTexGlobalMask > 0)
				{
					poiMods.detailMask.r = maskBlend(poiMods.detailMask.r, poiMods.globalMask[_DetailTexGlobalMask-1], _DetailTexGlobalMaskBlendType);
				}
				if (_DetailNormalGlobalMask > 0)
				{
					poiMods.detailMask.g = maskBlend(poiMods.detailMask.g, poiMods.globalMask[_DetailNormalGlobalMask-1], _DetailNormalGlobalMaskBlendType);
				}
				
				#if defined(PROP_DETAILNORMALMAP) || !defined(OPTIMIZER_ENABLED)
				half3 detailNormal = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_DetailNormalMap, _MainTex, poiUV(poiMesh.uv[_DetailNormalMapUV], _DetailNormalMap_ST), _DetailNormalMapPan, _DetailNormalMapStochastic), _DetailNormalMapScale * poiMods.detailMask.g);
				poiMesh.tangentSpaceNormal = BlendNormals(detailNormal, poiMesh.tangentSpaceNormal);
				#endif
			}
			#endif
			//endex
			
			//ifex _MainVertexColoringEnabled==0
			void applyVertexColor(inout PoiFragData poiFragData, PoiMesh poiMesh)
			{
				if (_MainVertexColoringEnabled)
				{
					#ifndef POI_PASS_OUTLINE
					float3 vertCol = lerp(poiMesh.vertexColor.rgb, GammaToLinearSpace(poiMesh.vertexColor.rgb), _MainVertexColoringLinearSpace);
					poiFragData.baseColor *= lerp(1, vertCol, _MainVertexColoring);
					#endif
					poiFragData.alpha *= lerp(1, poiMesh.vertexColor.a, _MainUseVertexColorAlpha);
				}
			}
			//endex
			
			//ifex _BackFaceEnabled!=1
			#ifdef POI_BACKFACE
			void ApplyBackFaceColor(inout PoiFragData poiFragData, in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				if (!poiMesh.isFrontFace)
				{
					float4 backFaceColor = _BackFaceColor;
					backFaceColor.rgb = poiThemeColor(poiMods, backFaceColor.rgb, _BackFaceColorThemeIndex);
					#if defined(PROP_BACKFACETEXTURE) || !defined(OPTIMIZER_ENABLED)
					backFaceColor *= POI2D_SAMPLER_PAN(_BackFaceTexture, _MainTex, poiUV(poiMesh.uv[_BackFaceTextureUV], _BackFaceTexture_ST), _BackFaceTexturePan);
					#endif
					backFaceColor.rgb = hueShift(backFaceColor.rgb, frac(_BackFaceHueShift + _BackFaceHueShiftSpeed * _Time.x) * _BackFaceHueShiftEnabled);
					
					float backFaceMask = 1;
					#if defined(PROP_BACKFACEMASK) || !defined(OPTIMIZER_ENABLED)
					backFaceMask *= POI2D_SAMPLER_PAN(_BackFaceMask, _MainTex, poiUV(poiMesh.uv[_BackFaceMaskUV], _BackFaceMask_ST), _BackFaceMaskPan)[_BackFaceMaskChannel];
					#endif
					if (!_BackFaceReplaceAlpha)
					{
						backFaceMask *= backFaceColor.a;
					}
					
					poiFragData.baseColor = lerp(poiFragData.baseColor, backFaceColor.rgb, backFaceMask);
					
					UNITY_BRANCH
					if (_BackFaceReplaceAlpha)
					{
						poiFragData.alpha = backFaceColor.a;
					}
					
					poiFragData.emission += backFaceColor.rgb * _BackFaceEmissionStrength * backFaceMask;
					poiMods.globalEmission = poiMods.globalEmission * _BackFaceEmissionLimiter;
				}
			}
			#endif
			//endex
			
			//ifex _RGBMaskEnabled==0
			
			void RGBABlendColor(inout PoiFragData poiFragData, in float mask, in float4 color, float emissionStrength, in float blendType, in float blendAdd, in float enabled)
			{
				if (!enabled) return;
				float alpha = mask * saturate(color.a + blendAdd);
				poiFragData.baseColor = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, color.rgb, blendType), alpha);
				poiFragData.emission += color.rgb * emissionStrength * alpha;
			}
			
			void RGBABlendNormals(inout float3 tangentSpaceNormal, float3 normalToBlendWith, float maskValue, int blendMode)
			{
				if (blendMode == 0)
				{
					tangentSpaceNormal = lerp(tangentSpaceNormal, normalToBlendWith, maskValue);
				}
				else
				{
					tangentSpaceNormal = BlendNormals(tangentSpaceNormal, normalToBlendWith);
				}
			}
			
			#ifdef VIGNETTE
			#if !defined(UNITY_PASS_SHADOWCASTER) && !defined(POI_PASS_OUTLINE)
			void calculateRGBNormals(inout PoiMesh poiMesh, inout PoiMods poiMods)
			{
				// Only define this if we actually have any normal map textures. Can't do the same in color textures because users can tint
				#if defined(PROP_RGBNORMALR) || defined(PROP_RGBNORMALG) || defined(PROP_RGBNORMALB) || defined(PROP_RGBNORMALA) || !defined(OPTIMIZER_ENABLED)
				float4 rgbMask = 1;
				
				#if defined(PROP_RGBMASK) || !defined(OPTIMIZER_ENABLED)
				if (_RGBMaskType == 0)
				{
					rgbMask = POI2D_SAMPLER_PAN(_RGBMask, _trilinear_repeat, poiUV(poiMesh.uv[_RGBMaskUV], _RGBMask_ST), _RGBMaskPan);
				}
				#endif
				
				if (_RGBMaskType == 1)
				{
					rgbMask = poiMesh.vertexColor;
				}
				
				float4 maskFinal = 1;
				maskFinal.r = rgbMask[_RgbNormalRMaskChannel];
				maskFinal.g = rgbMask[_RgbNormalGMaskChannel];
				maskFinal.b = rgbMask[_RgbNormalBMaskChannel];
				maskFinal.a = rgbMask[_RgbNormalAMaskChannel];
				
				if (_RgbNormalRGlobalMaskChannel > 0) maskFinal.r = customBlend(maskFinal.r, poiMods.globalMask[_RgbNormalRGlobalMaskChannel - 1], _RgbNormalRGlobalMaskBlendType);
				if (_RgbNormalGGlobalMaskChannel > 0) maskFinal.g = customBlend(maskFinal.g, poiMods.globalMask[_RgbNormalGGlobalMaskChannel - 1], _RgbNormalGGlobalMaskBlendType);
				if (_RgbNormalBGlobalMaskChannel > 0) maskFinal.b = customBlend(maskFinal.b, poiMods.globalMask[_RgbNormalBGlobalMaskChannel - 1], _RgbNormalBGlobalMaskBlendType);
				if (_RgbNormalAGlobalMaskChannel > 0) maskFinal.a = customBlend(maskFinal.a, poiMods.globalMask[_RgbNormalAGlobalMaskChannel - 1], _RgbNormalAGlobalMaskBlendType);
				
				#if defined(PROP_RGBNORMALR) || !defined(OPTIMIZER_ENABLED)
				if (_RgbNormalRScale > 0 && _RGBARedEnable)
				{
					float3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_RgbNormalR, _trilinear_repeat, poiUV(poiMesh.uv[_RgbNormalRUV], _RgbNormalR_ST), _RgbNormalRPan, _RgbNormalRStochastic), _RgbNormalRedBlendMode == 0 ? _RgbNormalRScale : _RgbNormalRScale * maskFinal.r);
					RGBABlendNormals(poiMesh.tangentSpaceNormal, normalToBlendWith, maskFinal.r, _RgbNormalRedBlendMode);
				}
				#endif
				#if defined(PROP_RGBNORMALG) || !defined(OPTIMIZER_ENABLED)
				if (_RgbNormalGScale > 0 && _RGBAGreenEnable)
				{
					float3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_RgbNormalG, _trilinear_repeat, poiUV(poiMesh.uv[_RgbNormalGUV], _RgbNormalG_ST), _RgbNormalGPan, _RgbNormalGStochastic), _RgbNormalGreenBlendMode == 0 ? _RgbNormalGScale : _RgbNormalGScale * maskFinal.g);
					RGBABlendNormals(poiMesh.tangentSpaceNormal, normalToBlendWith, maskFinal.g, _RgbNormalGreenBlendMode);
				}
				#endif
				#if defined(PROP_RGBNORMALB) || !defined(OPTIMIZER_ENABLED)
				if (_RgbNormalBScale > 0 && _RGBABlueEnable)
				{
					float3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_RgbNormalB, _trilinear_repeat, poiUV(poiMesh.uv[_RgbNormalBUV], _RgbNormalB_ST), _RgbNormalBPan, _RgbNormalBStochastic), _RgbNormalBlueBlendMode == 0 ? _RgbNormalBScale : _RgbNormalBScale * maskFinal.b);
					RGBABlendNormals(poiMesh.tangentSpaceNormal, normalToBlendWith, maskFinal.b, _RgbNormalBlueBlendMode);
				}
				#endif
				#if defined(PROP_RGBNORMALA) || !defined(OPTIMIZER_ENABLED)
				if (_RgbNormalAScale > 0 && _RGBAAlphaEnable)
				{
					float3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_RgbNormalA, _trilinear_repeat, poiUV(poiMesh.uv[_RgbNormalAUV], _RgbNormalA_ST), _RgbNormalAPan, _RgbNormalAStochastic), _RgbNormalAlphaBlendMode == 0 ? _RgbNormalAScale : _RgbNormalAScale * maskFinal.a);
					RGBABlendNormals(poiMesh.tangentSpaceNormal, normalToBlendWith, maskFinal.a, _RgbNormalAlphaBlendMode);
				}
				#endif
				#endif
			}
			#endif
			
			void calculateRGBMask(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float4 rgbMask = float4(1, 1, 1, 1);
				float4 red = float4(poiThemeColor(poiMods, _RedColor.rgb, _RedColorThemeIndex), _RedColor.a);
				float4 green = float4(poiThemeColor(poiMods, _GreenColor.rgb, _GreenColorThemeIndex), _GreenColor.a);
				float4 blue = float4(poiThemeColor(poiMods, _BlueColor.rgb, _BlueColorThemeIndex), _BlueColor.a);
				float4 alpha = float4(poiThemeColor(poiMods, _AlphaColor.rgb, _AlphaColorThemeIndex), _AlphaColor.a);
				
				#if defined(PROP_RGBMASK) || !defined(OPTIMIZER_ENABLED)
				if (_RGBMaskType == 0)
				{
					rgbMask = POI2D_SAMPLER_PAN(_RGBMask, _trilinear_repeat, poiUV(poiMesh.uv[_RGBMaskUV], _RGBMask_ST), _RGBMaskPan);
				}
				#endif
				
				if (_RGBMaskType == 1)
				{
					rgbMask = poiMesh.vertexColor;
				}
				
				#if defined(PROP_REDTEXTURE) || !defined(OPTIMIZER_ENABLED)
				red *= POI2D_SAMPLER_PAN_STOCHASTIC(_RedTexture, _trilinear_repeat, poiUV(poiMesh.uv[_RedTextureUV], _RedTexture_ST), _RedTexturePan.xy, _RedTextureStochastic);
				#endif
				#if defined(PROP_GREENTEXTURE) || !defined(OPTIMIZER_ENABLED)
				green *= POI2D_SAMPLER_PAN_STOCHASTIC(_GreenTexture, _trilinear_repeat, poiUV(poiMesh.uv[_GreenTextureUV], _GreenTexture_ST), _GreenTexturePan.xy, _GreenTextureStochastic);
				#endif
				#if defined(PROP_BLUETEXTURE) || !defined(OPTIMIZER_ENABLED)
				blue *= POI2D_SAMPLER_PAN_STOCHASTIC(_BlueTexture, _trilinear_repeat, poiUV(poiMesh.uv[_BlueTextureUV], _BlueTexture_ST), _BlueTexturePan.xy, _BlueTextureStochastic);
				#endif
				#if defined(PROP_ALPHATEXTURE) || !defined(OPTIMIZER_ENABLED)
				alpha *= POI2D_SAMPLER_PAN_STOCHASTIC(_AlphaTexture, _trilinear_repeat, poiUV(poiMesh.uv[_AlphaTextureUV], _AlphaTexture_ST), _AlphaTexturePan.xy, _AlphaTextureStochastic);
				#endif
				
				RGBABlendColor(poiFragData, globalMaskBlend(rgbMask[_RgbRedMaskChannel], _RgbRedGlobalMaskChannel, _RgbRedGlobalMaskBlendType, poiMods), red, _RGBARedEmissionStrength, _RGBARedBlendType, _RedAlphaAdd, _RGBARedEnable);
				RGBABlendColor(poiFragData, globalMaskBlend(rgbMask[_RgbGreenMaskChannel], _RgbGreenGlobalMaskChannel, _RgbGreenGlobalMaskBlendType, poiMods), green, _RGBAGreenEmissionStrength, _RGBAGreenBlendType, _GreenAlphaAdd, _RGBAGreenEnable);
				RGBABlendColor(poiFragData, globalMaskBlend(rgbMask[_RgbBlueMaskChannel], _RgbBlueGlobalMaskChannel, _RgbBlueGlobalMaskBlendType, poiMods), blue, _RGBABlueEmissionStrength, _RGBABlueBlendType, _BlueAlphaAdd, _RGBABlueEnable);
				RGBABlendColor(poiFragData, globalMaskBlend(rgbMask[_RgbAlphaMaskChannel], _RgbAlphaGlobalMaskChannel, _RgbAlphaGlobalMaskBlendType, poiMods), alpha, _RGBAAlphaEmissionStrength, _RGBAAlphaBlendType, _AlphaAlphaAdd, _RGBAAlphaEnable);
				
				if (_RGBAPBRRedEnabled || _RGBAPBRGreenEnabled || _RGBAPBRBlueEnabled || _RGBAPBRAlphaEnabled)
				{
					#if defined(PROP_RGBASMOOTHNESSMAPS) || !defined(OPTIMIZER_ENABLED)
					float4 smoothnessMaps = 1;
					if (!_RGBARedPBRSplitMaskSample || !_RGBAGreenPBRSplitMaskSample || !_RGBABluePBRSplitMaskSample || !_RGBAAlphaPBRSplitMaskSample)
					{
						smoothnessMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBASmoothnessMapsUV], _RGBASmoothnessMaps_ST), _RGBASmoothnessMapsPan.xy, _RGBASmoothnessMapsStochastic);
					}
					
					if (_RGBARedPBRSplitMaskSample && _RGBAPBRRedEnabled && _RGBARedEnable)
					{
						smoothnessMaps.r = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBARedPBRUV], _RGBARedPBRMaskScaleTiling), _RGBARedPBRMasksPan.xy, _RGBARedPBRSplitMaskStochastic).r;
					}
					if (_RGBAGreenPBRSplitMaskSample && _RGBAPBRGreenEnabled && _RGBAGreenEnable)
					{
						smoothnessMaps.g = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAGreenPBRUV], _RGBAGreenPBRMaskScaleTiling), _RGBAGreenPBRMasksPan.xy, _RGBAGreenPBRSplitMaskStochastic).g;
					}
					if (_RGBABluePBRSplitMaskSample && _RGBAPBRBlueEnabled && _RGBABlueEnable)
					{
						smoothnessMaps.b = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBABluePBRUV], _RGBABluePBRMaskScaleTiling), _RGBABluePBRMasksPan.xy, _RGBABluePBRSplitMaskStochastic).b;
					}
					if (_RGBAAlphaPBRSplitMaskSample && _RGBAPBRAlphaEnabled && _RGBAAlphaEnable)
					{
						smoothnessMaps.a = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBASmoothnessMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAAlphaPBRUV], _RGBAAlphaPBRMaskScaleTiling), _RGBAAlphaPBRMasksPan.xy, _RGBAAlphaPBRSplitMaskStochastic).a;
					}
					
					poiFragData.smoothness = lerp(poiFragData.smoothness, poiInvertToggle(smoothnessMaps.r, _RGBARedSmoothnessInvert), rgbMask[_RgbRedMaskChannel] * (_RGBAPBRRedEnabled && _RGBARedEnable));
					poiFragData.smoothness = lerp(poiFragData.smoothness, poiInvertToggle(smoothnessMaps.g, _RGBAGreenSmoothnessInvert), rgbMask[_RgbGreenMaskChannel] * (_RGBAPBRGreenEnabled && _RGBAGreenEnable));
					poiFragData.smoothness = lerp(poiFragData.smoothness, poiInvertToggle(smoothnessMaps.b, _RGBABlueSmoothnessInvert), rgbMask[_RgbBlueMaskChannel] * (_RGBAPBRBlueEnabled && _RGBABlueEnable));
					poiFragData.smoothness = lerp(poiFragData.smoothness, poiInvertToggle(smoothnessMaps.a, _RGBAAlphaSmoothnessInvert), rgbMask[_RgbAlphaMaskChannel] * (_RGBAPBRAlphaEnabled && _RGBAAlphaEnable));
					#endif
					
					#if defined(PROP_RGBAMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
					float4 metallicMaps = 1;
					if (!_RGBARedPBRSplitMaskSample || !_RGBAGreenPBRSplitMaskSample || !_RGBABluePBRSplitMaskSample || !_RGBAAlphaPBRSplitMaskSample)
					{
						metallicMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAMetallicMapsUV], _RGBAMetallicMaps_ST), _RGBAMetallicMapsPan.xy, _RGBAMetallicMapsStochastic);
					}
					
					if (_RGBARedPBRSplitMaskSample && _RGBAPBRRedEnabled && _RGBARedEnable)
					{
						metallicMaps.r = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBARedPBRUV], _RGBARedPBRMaskScaleTiling), _RGBARedPBRMasksPan.xy, _RGBARedPBRSplitMaskStochastic).r;
					}
					if (_RGBAGreenPBRSplitMaskSample && _RGBAPBRGreenEnabled && _RGBAGreenEnable)
					{
						metallicMaps.g = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAGreenPBRUV], _RGBAGreenPBRMaskScaleTiling), _RGBAGreenPBRMasksPan.xy, _RGBAGreenPBRSplitMaskStochastic).g;
					}
					if (_RGBABluePBRSplitMaskSample && _RGBAPBRBlueEnabled && _RGBABlueEnable)
					{
						metallicMaps.b = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBABluePBRUV], _RGBABluePBRMaskScaleTiling), _RGBABluePBRMasksPan.xy, _RGBABluePBRSplitMaskStochastic).b;
					}
					if (_RGBAAlphaPBRSplitMaskSample && _RGBAPBRAlphaEnabled && _RGBAAlphaEnable)
					{
						metallicMaps.a = POI2D_SAMPLER_PAN_STOCHASTIC(_RGBAMetallicMaps, _trilinear_repeat, poiUV(poiMesh.uv[_RGBAAlphaPBRUV], _RGBAAlphaPBRMaskScaleTiling), _RGBAAlphaPBRMasksPan.xy, _RGBAAlphaPBRSplitMaskStochastic).a;
					}
					
					poiFragData.metallic = lerp(poiFragData.metallic, poiInvertToggle(metallicMaps.r, _RGBARedMetallicInvert), rgbMask[_RgbRedMaskChannel] * (_RGBAPBRRedEnabled && _RGBARedEnable));
					poiFragData.metallic = lerp(poiFragData.metallic, poiInvertToggle(metallicMaps.g, _RGBAGreenMetallicInvert), rgbMask[_RgbGreenMaskChannel] * (_RGBAPBRGreenEnabled && _RGBAGreenEnable));
					poiFragData.metallic = lerp(poiFragData.metallic, poiInvertToggle(metallicMaps.b, _RGBABlueMetallicInvert), rgbMask[_RgbBlueMaskChannel] * (_RGBAPBRBlueEnabled && _RGBABlueEnable));
					poiFragData.metallic = lerp(poiFragData.metallic, poiInvertToggle(metallicMaps.a, _RGBAAlphaMetallicInvert), rgbMask[_RgbAlphaMaskChannel] * (_RGBAPBRAlphaEnabled && _RGBAAlphaEnable));
					#endif
				}
			}
			#endif
			//endex
			
			//ifex _ShadingEnabled==0
			#ifdef VIGNETTE_MASKED
			
			#ifdef _LIGHTINGMODE_CLOTH
			float V_SmithGGXCorrelated(float roughness, float NoV, float NoL)
			{
				// Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"
				float a2 = roughness * roughness;
				// TODO: lambdaV can be pre-computed for all the lights, it should be moved out of this function
				float lambdaV = NoL * sqrt((NoV - a2 * NoV) * NoV + a2);
				float lambdaL = NoV * sqrt((NoL - a2 * NoL) * NoL + a2);
				float v = 0.5 / (lambdaV + lambdaL);
				// a2=0 => v = 1 / 4*NoL*NoV   => min=1/4, max=+inf
				// a2=1 => v = 1 / 2*(NoL+NoV) => min=1/4, max=+inf
				// clamp to the maximum value representable in mediump
				return v;
			}
			
			float D_GGX(float roughness, float NoH)
			{
				// Walter et al. 2007, "Microfacet Models for Refraction through Rough Surfaces"
				
				// In mediump, there are two problems computing 1.0 - NoH^2
				// 1) 1.0 - NoH^2 suffers floating point cancellation when NoH^2 is close to 1 (highlights)
				// 2) NoH doesn't have enough precision around 1.0
				// Both problem can be fixed by computing 1-NoH^2 in highp and providing NoH in highp as well
				
				// However, we can do better using Lagrange's identity:
				//      ||a x b||^2 = ||a||^2 ||b||^2 - (a . b)^2
				// since N and H are unit vectors: ||N x H||^2 = 1.0 - NoH^2
				// This computes 1.0 - NoH^2 directly (which is close to zero in the highlights and has
				// enough precision).
				// Overall this yields better performance, keeping all computations in mediump
				float oneMinusNoHSquared = 1.0 - NoH * NoH;
				
				float a = NoH * roughness;
				float k = roughness / (oneMinusNoHSquared + a * a);
				float d = k * k * (1.0 / UNITY_PI);
				return d;
			}
			
			// https://github.com/google/filament/blob/main/shaders/src/brdf.fs#L94-L100
			float D_Charlie(float roughness, float NoH)
			{
				// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF"
				float invAlpha = 1.0 / roughness;
				float cos2h = NoH * NoH;
				float sin2h = max(1.0 - cos2h, 0.0078125); // 0.0078125 = 2^(-14/2), so sin2h^2 > 0 in fp16
				return (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * UNITY_PI);
			}
			
			// https://github.com/google/filament/blob/main/shaders/src/brdf.fs#L136-L139
			float V_Neubelt(float NoV, float NoL)
			{
				// Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886"
				return 1.0 / (4.0 * (NoL + NoV - NoL * NoV));
			}
			
			float Distribution(float roughness, float NoH, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(GGXTerm(roughness, NoH), D_Charlie(roughness, NoH), cloth);
				}
				//endex
				return cloth <= 0.5 ? GGXTerm(roughness, NoH) : D_Charlie(roughness, NoH);
			}
			
			float Visibility(float roughness, float NoV, float NoL, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(V_SmithGGXCorrelated(roughness, NoV, NoL), V_Neubelt(NoV, NoL), cloth);
				}
				//endex
				return cloth <= 0.5 ? V_SmithGGXCorrelated(roughness, NoV, NoL) : V_Neubelt(NoV, NoL);
			}
			
			float F_Schlick(float3 f0, float f90, float VoH)
			{
				// Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"
				return f0 + (f90 - f0) * pow(1.0 - VoH, 5);
			}
			
			float F_Schlick(float3 f0, float VoH)
			{
				float f = pow(1.0 - VoH, 5.0);
				return f + f0 * (1.0 - f);
			}
			
			float Fresnel(float3 f0, float LoH)
			{
				float f90 = saturate(dot(f0, float(50.0 * 0.33).xxx));
				return F_Schlick(f0, f90, LoH);
			}
			
			float Fd_Burley(float roughness, float NoV, float NoL, float LoH)
			{
				// Burley 2012, "Physically-Based Shading at Disney"
				float f90 = 0.5 + 2.0 * roughness * LoH * LoH;
				float lightScatter = F_Schlick(1.0, f90, NoL);
				float viewScatter = F_Schlick(1.0, f90, NoV);
				return lightScatter * viewScatter;
			}
			
			// Energy conserving wrap diffuse term, does *not* include the divide by PI
			float Fd_Wrap(float NoL, float w)
			{
				return saturate((NoL + w) / pow(1.0 + w, 2));
			}
			
			float4 SampleDFG(float NoV, float perceptualRoughness)
			{
				return _ClothDFG.Sample(sampler_ClothDFG, float3(NoV, perceptualRoughness, 0));
			}
			
			float3 EnvBRDF(float2 dfg, float3 f0)
			{
				return f0 * dfg.x + dfg.y;
			}
			
			float3 EnvBRDFMultiscatter(float3 dfg, float3 f0, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(lerp(dfg.xxx, dfg.yyy, f0), f0 * dfg.z, cloth);
				}
				//endex
				return cloth <= 0.5 ? lerp(dfg.xxx, dfg.yyy, f0) : f0 * dfg.z;
			}
			
			float3 EnvBRDFEnergyCompensation(float3 dfg, float3 f0, float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return lerp(1.0 + f0 * (1.0 / dfg.y - 1.0), 1, cloth);
				}
				//endex
				return cloth <= 0.5 ? 1.0 + f0 * (1.0 / dfg.y - 1.0) : 1;
			}
			
			//
			float ClothMetallic(float cloth)
			{
				//ifex _ClothLerp==0
				if (_ClothLerp)
				{
					return cloth;
				}
				//endex
				return cloth <= 0.5 ? 1 : 0;
			}
			
			float3 Specular(float roughness, PoiLight poiLight, float f0, float3 normal, float cloth)
			{
				float NoL = poiLight.nDotLSaturated;
				float NoH = poiLight.nDotH;
				float LoH = poiLight.lDotH;
				float NoV = poiLight.nDotV;
				
				float D = Distribution(roughness, NoH, cloth);
				float V = Visibility(roughness, NoV, NoL, cloth);
				float3 F = Fresnel(f0, LoH);
				
				return (D * V) * F;
			}
			
			float3 getBoxProjection(float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax)
			{
				#if UNITY_SPECCUBE_BOX_PROJECTION
				if (cubemapPosition.w > 0)
				{
					float3 factors = ((direction > 0 ? boxMax : boxMin) - position) / direction;
					float scalar = min(min(factors.x, factors.y), factors.z);
					direction = direction * scalar + (position - cubemapPosition.xyz);
				}
				#endif
				
				return direction;
			}
			
			float SpecularAO(float NoV, float ao, float roughness)
			{
				return clamp(pow(NoV + ao, exp2(-16.0 * roughness - 1.0)) - 1.0 + ao, 0.0, 1.0);
			}
			
			float3 IndirectSpecular(float3 dfg, float roughness, float occlusion, float energyCompensation, float cloth, float3 indirectDiffuse, float f0, PoiLight poiLight, PoiFragData poiFragData, PoiCam poiCam, PoiMesh poiMesh)
			{
				float3 normal = poiMesh.normals[1];
				
				float3 reflDir = reflect(-poiCam.viewDir, normal);
				
				Unity_GlossyEnvironmentData envData;
				envData.roughness = roughness;
				envData.reflUVW = getBoxProjection(reflDir, poiMesh.worldPos, unity_SpecCube0_ProbePosition,
				unity_SpecCube0_BoxMin.xyz, unity_SpecCube0_BoxMax.xyz);
				
				float3 probe0 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE(unity_SpecCube0), unity_SpecCube0_HDR, envData);
				float3 indirectSpecular = probe0;
				
				#if UNITY_SPECCUBE_BLENDING
				UNITY_BRANCH
				if (unity_SpecCube0_BoxMin.w < 0.99999)
				{
					envData.reflUVW = getBoxProjection(reflDir, poiMesh.worldPos, unity_SpecCube1_ProbePosition, unity_SpecCube1_BoxMin.xyz, unity_SpecCube1_BoxMax.xyz);
					float3 probe1 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1, unity_SpecCube0), unity_SpecCube1_HDR, envData);
					indirectSpecular = lerp(probe1, probe0, unity_SpecCube0_BoxMin.w);
				}
				#endif
				
				float horizon = min(1 + dot(reflDir, normal), 1);
				indirectSpecular = indirectSpecular * horizon * horizon * energyCompensation * EnvBRDFMultiscatter(dfg, f0, cloth);
				
				indirectSpecular *= SpecularAO(poiLight.nDotV, occlusion, roughness);
				return indirectSpecular;
			};
			#endif
			
			#ifdef _LIGHTINGMODE_WRAPPED
			// Wrapped
			// Green’s model with adjustable energy
			// http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/
			// Modified for adjustable conservation ratio and over-wrap to directionless
			float RTWrapFunc(in float dt, in float w, in float norm)
			{
				float cw = saturate(w);
				
				float o = (dt + cw) / ((1.0 + cw) * (1.0 + cw * norm));
				float flt = 1.0 - 0.85 * norm;
				if (w > 1.0)
				{
					o = lerp(o, flt, w - 1.0);
				}
				return o;
			}
			
			float3 GreenWrapSH(float fA) // Greens unoptimized and non-normalized
			
			{
				float fAs = saturate(fA);
				float4 t = float4(fA + 1, fAs - 1, fA - 2, fAs + 1); // DJL edit: allow wrapping to L0-only at w=2
				return float3(t.x, -t.z * t.x / 3, 0.25 * t.y * t.y * t.w);
			}
			float3 GreenWrapSHOpt(float fW) // optimised and normalized https://blog.selfshadow.com/2012/01/07/righting-wrap-part-2/
			
			{
				const float4 t0 = float4(0.0, 1.0 / 4.0, -1.0 / 3.0, -1.0 / 2.0);
				const float4 t1 = float4(1.0, 2.0 / 3.0, 1.0 / 4.0, 0.0);
				float3 fWs = float3(fW, fW, saturate(fW)); // DJL edit: allow wrapping to L0-only at w=2
				
				float3 r;
				r.xyz = t0.xxy * fWs + t0.xzw;
				r.xyz = r.xyz * fWs + t1.xyz;
				return r;
			}
			float3 ShadeSH9_wrapped(float3 normal, float wrap)
			{
				float3 x0, x1, x2;
				float3 conv = lerp(GreenWrapSH(wrap), GreenWrapSHOpt(wrap), _LightingWrappedNormalization); // Should try optimizing this...
				conv *= float3(1, 1.5, 4); // Undo pre-applied cosine convolution by using the inverse
				
				// Constant (L0)
				x0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
				// Remove pre-applied constant part from L(2,0) to apply correct convolution
				float3 L2_0 = float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / - 3.0;
				x0 -= L2_0;
				
				// Linear (L1) polynomial terms
				x1.r = dot(unity_SHAr.xyz, normal);
				x1.g = dot(unity_SHAg.xyz, normal);
				x1.b = dot(unity_SHAb.xyz, normal);
				
				// 4 of the quadratic (L2) polynomials
				float4 vB = normal.xyzz * normal.yzzx;
				x2.r = dot(unity_SHBr, vB);
				x2.g = dot(unity_SHBg, vB);
				x2.b = dot(unity_SHBb, vB);
				
				// Final (5th) quadratic (L2) polynomial
				float vC = normal.x * normal.x - normal.y * normal.y;
				x2 += unity_SHC.rgb * vC;
				// Move back the constant part of L(2,0)
				x2 += L2_0;
				
				return x0 * conv.x + x1 * conv.y + x2 * conv.z;
			}
			
			float3 GetSHDirectionL1()
			{
				// For efficiency, we only get the direction from L1.
				// Because getting it from L2 would be too hard!
				return Unity_SafeNormalize((unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz));
			}
			// Returns the value from SH in the lighting direction with the
			// brightest intensity.
			half3 GetSHMaxL1()
			{
				float3 maxDirection = GetSHDirectionL1();
				return ShadeSH9_wrapped(maxDirection, 0);
			}
			#endif
			
			#ifdef _LIGHTINGMODE_SHADEMAP
			void applyShadeMapping(inout PoiFragData poiFragData, PoiMesh poiMesh, inout PoiLight poiLight)
			{
				float shadowAttenuation = lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				float attenuation = 1;
				#if defined(POINT) || defined(SPOT)
				shadowAttenuation = lerp(1, poiLight.additiveShadow, poiLight.attenuationStrength);
				//attenuation = poiLight.attenuation;
				#endif
				
				float MainColorFeatherStep = _BaseColor_Step - _BaseShade_Feather;
				float firstColorFeatherStep = _ShadeColor_Step - _1st2nd_Shades_Feather;
				
				#if defined(PROP_1ST_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
				float4 firstShadeMap = POI2D_SAMPLER_PAN(_1st_ShadeMap, _MainTex, poiUV(poiMesh.uv[_1st_ShadeMapUV], _1st_ShadeMap_ST), _1st_ShadeMapPan);
				#else
				float4 firstShadeMap = float4(1, 1, 1, 1);
				#endif
				firstShadeMap = lerp(firstShadeMap, float4(poiFragData.baseColor, 1), _Use_BaseAs1st);
				
				#if defined(PROP_2ND_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
				float4 secondShadeMap = POI2D_SAMPLER_PAN(_2nd_ShadeMap, _MainTex, poiUV(poiMesh.uv[_2nd_ShadeMapUV], _2nd_ShadeMap_ST), _2nd_ShadeMapPan);
				#else
				float4 secondShadeMap = float4(1, 1, 1, 1);
				#endif
				secondShadeMap = lerp(secondShadeMap, firstShadeMap, _Use_1stAs2nd);
				
				firstShadeMap.rgb *= _1st_ShadeColor.rgb; //* lighColor
				secondShadeMap.rgb *= _2nd_ShadeColor.rgb; //* LightColor;
				
				float shadowMask = 1;
				shadowMask *= _Use_1stShadeMapAlpha_As_ShadowMask ? (_1stShadeMapMask_Inverse ? (1.0 - firstShadeMap.a) : firstShadeMap.a) : 1;
				shadowMask *= _Use_2ndShadeMapAlpha_As_ShadowMask ? (_2ndShadeMapMask_Inverse ? (1.0 - secondShadeMap.a) : secondShadeMap.a) : 1;
				
				float mainShadowMask = saturate(1 - ((poiLight.lightMap) - MainColorFeatherStep) / (_BaseColor_Step - MainColorFeatherStep) * (shadowMask));
				float firstSecondShadowMask = saturate(1 - ((poiLight.lightMap) - firstColorFeatherStep) / (_ShadeColor_Step - firstColorFeatherStep) * (shadowMask));
				
				mainShadowMask *= poiLight.shadowMask * _ShadowStrength;
				firstSecondShadowMask *= poiLight.shadowMask * _ShadowStrength;
				
				// 0 lerp | 1 multiply
				if (_ShadingShadeMapBlendType == 0)
				{
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, lerp(firstShadeMap.rgb, secondShadeMap.rgb, firstSecondShadowMask), mainShadowMask) * attenuation;
				}
				else
				{
					poiFragData.baseColor.rgb *= lerp(1, lerp(firstShadeMap.rgb, secondShadeMap.rgb, firstSecondShadowMask), mainShadowMask) * attenuation;
				}
				poiLight.rampedLightMap = 1 - mainShadowMask;
			}
			#endif
			
			#ifdef _LIGHTINGMODE_REALISTIC
			// For https://docs.unity3d.com/Manual/LightMode-Mixed-Subtractive.html
			#if defined(LIGHTMAP_ON) && defined(SHADOWS_SCREEN)
			#if defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK)
			#define SUBTRACTIVE_LIGHTING 1
			#endif
			#endif
			
			void ApplySubtractiveLighting(inout UnityIndirect indirectLight)
			{
				#if SUBTRACTIVE_LIGHTING
				poiLight.attenuation = FadeShadows(lerp(1, poiLight.attenuation, _AttenuationMultiplier));
				
				float ndotl = saturate(dot(i.normal, _WorldSpaceLightPos0.xyz));
				float3 shadowedLightEstimate = ndotl * (1 - poiLight.attenuation) * _LightColor0.rgb;
				float3 subtractedLight = indirectLight.diffuse - shadowedLightEstimate;
				subtractedLight = max(subtractedLight, unity_ShadowColor.rgb);
				subtractedLight = lerp(subtractedLight, indirectLight.diffuse, _LightShadowData.x);
				indirectLight.diffuse = min(subtractedLight, indirectLight.diffuse);
				#endif
			}
			
			UnityIndirect CreateIndirectLight(in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight)
			{
				UnityIndirect indirectLight;
				indirectLight.diffuse = 0;
				indirectLight.specular = 0;
				
				#if defined(LIGHTMAP_ON)
				indirectLight.diffuse = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, poiMesh.lightmapUV.xy));
				
				#if defined(DIRLIGHTMAP_COMBINED)
				float4 lightmapDirection = UNITY_SAMPLE_TEX2D_SAMPLER(
				unity_LightmapInd, unity_Lightmap, poiMesh.lightmapUV.xy
				);
				indirectLight.diffuse = DecodeDirectionalLightmap(
				indirectLight.diffuse, lightmapDirection, poiMesh.normals[1]
				);
				#endif
				ApplySubtractiveLighting(indirectLight);
				#endif
				
				#if defined(DYNAMICLIGHTMAP_ON)
				float3 dynamicLightDiffuse = DecodeRealtimeLightmap(
				UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, poiMesh.lightmapUV.zw)
				);
				
				#if defined(DIRLIGHTMAP_COMBINED)
				float4 dynamicLightmapDirection = UNITY_SAMPLE_TEX2D_SAMPLER(
				unity_DynamicDirectionality, unity_DynamicLightmap,
				poiMesh.lightmapUV.zw
				);
				indirectLight.diffuse += DecodeDirectionalLightmap(
				dynamicLightDiffuse, dynamicLightmapDirection, poiMesh.normals[1]
				);
				#else
				indirectLight.diffuse += dynamicLightDiffuse;
				#endif
				#endif
				
				#if !defined(LIGHTMAP_ON) && !defined(DYNAMICLIGHTMAP_ON)
				#if UNITY_LIGHT_PROBE_PROXY_VOLUME
				if (unity_ProbeVolumeParams.x == 1)
				{
					indirectLight.diffuse = SHEvalLinearL0L1_SampleProbeVolume(
					float4(poiMesh.normals[1], 1), poiMesh.worldPos
					);
					indirectLight.diffuse = max(0, indirectLight.diffuse);
					#if defined(UNITY_COLORSPACE_GAMMA)
					indirectLight.diffuse = LinearToGammaSpace(indirectLight.diffuse);
					#endif
				}
				else
				{
					indirectLight.diffuse += max(0, ShadeSH9(float4(poiMesh.normals[1], 1)));
				}
				#else
				indirectLight.diffuse += max(0, ShadeSH9(float4(poiMesh.normals[1], 1)));
				#endif
				#endif
				
				indirectLight.diffuse *= poiLight.occlusion;
				
				return indirectLight;
			}
			#endif
			
			float GetRemapMinValue(float scale, float offset)
			{
				return clamp(-offset / scale, -0.01f, 1.01f); // Remap min
				
			}
			float GetRemapMaxValue(float scale, float offset)
			{
				return clamp((1.0f - offset) / scale, -0.01f, 1.01f); // Remap Max
				
			}
			
			void calculateShading(inout PoiLight poiLight, inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam)
			{
				float shadowAttenuation = lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				float attenuation = 1;
				#if defined(POINT) || defined(SPOT)
				shadowAttenuation = lerp(1, poiLight.additiveShadow, poiLight.attenuationStrength);
				//attenuation = poiLight.attenuation;
				#endif
				
				#ifdef POI_PASS_ADD
				if (_LightingAdditiveType == 3)
				{
					#if defined(POINT) || defined(SPOT)
					#if defined(_LIGHTINGMODE_REALISTIC) || defined(_LIGHTINGMODE_CLOTH) || defined(_LIGHTINGMODE_WRAPPED)
					poiLight.rampedLightMap = max(0, poiLight.nDotL);
					poiLight.finalLighting = poiLight.directColor * attenuation * max(0, poiLight.nDotL) * poiLight.detailShadow * shadowAttenuation;
					return;
					#endif
					#endif
				}
				// Realistic
				if (_LightingAdditiveType == 0)
				{
					poiLight.rampedLightMap = max(0, poiLight.nDotL);
					poiLight.finalLighting = poiLight.directColor * attenuation * max(0, poiLight.nDotL) * poiLight.detailShadow * shadowAttenuation;
					return;
				}
				// Toon
				if (_LightingAdditiveType == 1)
				{
					#if defined(POINT_COOKIE) || defined(DIRECTIONAL_COOKIE)
					float passthrough = 0;
					#else
					float passthrough = _LightingAdditivePassthrough;
					#endif
					
					float2 ToonAddGradient = float2(_LightingAdditiveGradientStart, _LightingAdditiveGradientEnd);
					
					if (ToonAddGradient.x == ToonAddGradient.y) ToonAddGradient.y += 0.0001;
					
					poiLight.rampedLightMap = smoothstep(ToonAddGradient.y, ToonAddGradient.x, 1 - (.5 * poiLight.nDotL + .5));
					#if defined(POINT) || defined(SPOT)
					poiLight.finalLighting = lerp(poiLight.directColor * max(min(poiLight.additiveShadow, poiLight.detailShadow), passthrough), poiLight.indirectColor, smoothstep(ToonAddGradient.x, ToonAddGradient.y, 1 - (.5 * poiLight.nDotL + .5)));
					#else
					poiLight.finalLighting = lerp(poiLight.directColor * max(min(poiLight.attenuation, poiLight.detailShadow), passthrough), poiLight.indirectColor, smoothstep(ToonAddGradient.x, ToonAddGradient.y, 1 - (.5 * poiLight.nDotL + .5)));
					#endif
					return;
				}
				#endif
				
				float shadowStrength = _ShadowStrength * poiLight.shadowMask;
				
				#ifdef POI_PASS_OUTLINE
				shadowStrength = lerp(0, shadowStrength, _OutlineShadowStrength);
				#endif
				
				// These blocks shouldn't need ifex, they should be removed on lock when their keywords aren't present
				
				#ifdef _LIGHTINGMODE_FLAT
				poiLight.finalLighting = poiLight.directColor * attenuation * shadowAttenuation;
				if (_ForceFlatRampedLightmap)
				{
					poiLight.rampedLightMap = smoothstep(0.4, 0.6, poiLight.nDotLNormalized);
				}
				else
				{
					poiLight.rampedLightMap = 1;
				}
				#endif
				
				#ifdef _LIGHTINGMODE_TEXTURERAMP
				float2 rampUVs = poiLight.lightMap + _ShadowOffset;
				if (_ToonRampCount > 1)
				{
					rampUVs.y = (floor(poiMesh.uv[_ToonRampUVSelector].y * _ToonRampCount) + 0.5) / _ToonRampCount;
				}
				poiLight.rampedLightMap = lerp(1, UNITY_SAMPLE_TEX2D_SAMPLER(_ToonRamp, _linear_clamp, rampUVs).rgb, shadowStrength);
				poiLight.finalLighting = lerp(_LightingShadowColor * lerp(poiLight.indirectColor, poiLight.rampedLightMap * poiLight.directColor, _LightingIgnoreAmbientColor) * poiLight.occlusion, poiLight.directColor, poiLight.rampedLightMap) * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_MULTILAYER_MATH
				#if defined(PROP_MULTILAYERMATHBLURMAP) || !defined(OPTIMIZER_ENABLED)
				float4 blurMap = POI2D_SAMPLER_PAN(_MultilayerMathBlurMap, _MainTex, poiUV(poiMesh.uv[_MultilayerMathBlurMapUV], _MultilayerMathBlurMap_ST), _MultilayerMathBlurMapPan);
				#else
				float4 blurMap = 1;
				#endif
				
				float4 lns = float4(1, 1, 1, 1);
				
				float shadowAttenuationNoStrength = poiLight.attenuation;
				#if defined(POINT) || defined(SPOT)
				shadowAttenuationNoStrength = poiLight.additiveShadow;
				#endif
				
				float3 lightMap = poiLight.lightMapNoAttenuation.xxx;
				lightMap.x *= lerp(1.0, shadowAttenuationNoStrength, _ShadowReceive);
				lightMap.y *= lerp(1.0, shadowAttenuationNoStrength, _Shadow2ndReceive);
				lightMap.z *= lerp(1.0, shadowAttenuationNoStrength, _Shadow3rdReceive);
				
				float4 shadowBorderMask = 1;
				if (_ShadowBorderMapToggle)
				{
					// This should be moved to ui but honestly if these are locked in the compiler should be able to resolve it at compile time
					float2 shadowShift0 = float2(_ShadowAOShift.x, _ShadowAOShift.y);
					float2 shadowShift1 = float2(_ShadowAOShift.z, _ShadowAOShift.w);
					float2 shadowShift2 = float2(_ShadowAOShift2.x, _ShadowAOShift2.y);
					
					//float2 shadowShift0 = float2(GetRemapMinValue(_ShadowAOShift.x, _ShadowAOShift.y), GetRemapMaxValue(_ShadowAOShift.x, _ShadowAOShift.y));
					//float2 shadowShift1 = float2(GetRemapMinValue(_ShadowAOShift.z, _ShadowAOShift.w), GetRemapMaxValue(_ShadowAOShift.z, _ShadowAOShift.w));
					//float2 shadowShift2 = float2(GetRemapMinValue(_ShadowAOShift2.x, _ShadowAOShift2.y), GetRemapMaxValue(_ShadowAOShift2.x, _ShadowAOShift2.y));
					
					shadowShift0.y = (shadowShift0.x == shadowShift0.y) ? (shadowShift0.y + 0.001f) : shadowShift0.y;
					shadowShift1.y = (shadowShift1.x == shadowShift1.y) ? (shadowShift1.y + 0.001f) : shadowShift1.y;
					shadowShift2.y = (shadowShift2.x == shadowShift2.y) ? (shadowShift2.y + 0.001f) : shadowShift2.y;
					
					shadowShift0 = float2(1.0f / (shadowShift0.y - shadowShift0.x), shadowShift0.x / (shadowShift0.x - shadowShift0.y));
					shadowShift1 = float2(1.0f / (shadowShift1.y - shadowShift1.x), shadowShift1.x / (shadowShift1.x - shadowShift1.y));
					shadowShift2 = float2(1.0f / (shadowShift2.y - shadowShift2.x), shadowShift2.x / (shadowShift2.x - shadowShift2.y));
					
					#if defined(PROP_SHADOWBORDERMASK) || !defined(OPTIMIZER_ENABLED)
					float2 shadowBorderMaskUV = poiUV(poiMesh.uv[_ShadowBorderMaskUV], _ShadowBorderMask_ST);
					if (_ShadowBorderMaskLOD)
					{
						shadowBorderMask = POI2D_SAMPLE_TEX2D_SAMPLERGRADD(_ShadowBorderMask, sampler_trilinear_repeat, shadowBorderMaskUV, _ShadowBorderMaskPan, max(abs(ddx(shadowBorderMaskUV)), pow(_ShadowBorderMaskLOD, 4)), max(abs(ddy(shadowBorderMaskUV)), pow(_ShadowBorderMaskLOD, 4)));
					}
					else
					{
						shadowBorderMask = POI2D_SAMPLER_PAN(_ShadowBorderMask, _linear_repeat, shadowBorderMaskUV, _ShadowBorderMaskPan);
					}
					#endif
					
					shadowBorderMask.r = saturate(shadowBorderMask.r * shadowShift0.x + shadowShift0.y);
					shadowBorderMask.g = saturate(shadowBorderMask.g * shadowShift1.x + shadowShift1.y);
					shadowBorderMask.b = saturate(shadowBorderMask.b * shadowShift2.x + shadowShift2.y);
					
					lightMap.xyz = _ShadowPostAO ? lightMap.xyz : lightMap.xyz * shadowBorderMask.rgb;
				}
				
				if (_LightingMulitlayerNonLinear)
				{
					lns.x = poiEdgeNonLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r);
					lns.y = poiEdgeNonLinearNoSaturate(lightMap.y, _Shadow2ndBorder, _Shadow2ndBlur * blurMap.g);
					lns.z = poiEdgeNonLinearNoSaturate(lightMap.z, _Shadow3rdBorder, _Shadow3rdBlur * blurMap.b);
					lns.w = poiEdgeNonLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r, _ShadowBorderRange);
				}
				else
				{
					lns.x = poiEdgeLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r);
					lns.y = poiEdgeLinearNoSaturate(lightMap.y, _Shadow2ndBorder, _Shadow2ndBlur * blurMap.g);
					lns.z = poiEdgeLinearNoSaturate(lightMap.z, _Shadow3rdBorder, _Shadow3rdBlur * blurMap.b);
					lns.w = poiEdgeLinearNoSaturate(lightMap.x, _ShadowBorder, _ShadowBlur * blurMap.r, _ShadowBorderRange);
				}
				#if defined(PROP_SHADOWBORDERMASK) || !defined(OPTIMIZER_ENABLED)
				lns = _ShadowPostAO ? lns * shadowBorderMask.rgbr : lns;
				#endif
				lns = saturate(lns);
				//poiLight.finalLighting = lns.rgb;
				//return;
				float3 indirectColor = 1;
				
				if (_ShadowColor.a > 0)
				{
					#if defined(PROP_SHADOWCOLORTEX) || !defined(OPTIMIZER_ENABLED)
					float4 shadowColorTex = POI2D_SAMPLER_PAN(_ShadowColorTex, _MainTex, poiUV(poiMesh.uv[_ShadowColorTexUV], _ShadowColorTex_ST), _ShadowColorTexPan);
					#else
					float4 shadowColorTex = float4(1, 1, 1, 1);
					#endif
					indirectColor = lerp(float3(1, 1, 1), shadowColorTex.rgb, shadowColorTex.a) * _ShadowColor.rgb;
				}
				if (_Shadow2ndColor.a > 0)
				{
					#if defined(PROP_SHADOW2NDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
					float4 shadow2ndColorTex = POI2D_SAMPLER_PAN(_Shadow2ndColorTex, _MainTex, poiUV(poiMesh.uv[_Shadow2ndColorTexUV], _Shadow2ndColorTex_ST), _Shadow2ndColorTexPan);
					#else
					float4 shadow2ndColorTex = float4(1, 1, 1, 1);
					#endif
					shadow2ndColorTex.rgb = lerp(float3(1, 1, 1), shadow2ndColorTex.rgb, shadow2ndColorTex.a) * _Shadow2ndColor.rgb;
					lns.y = _Shadow2ndColor.a - lns.y * _Shadow2ndColor.a;
					indirectColor = lerp(indirectColor, shadow2ndColorTex.rgb, lns.y);
				}
				if (_Shadow3rdColor.a > 0)
				{
					#if defined(PROP_SHADOW3RDCOLORTEX) || !defined(OPTIMIZER_ENABLED)
					float4 shadow3rdColorTex = POI2D_SAMPLER_PAN(_Shadow3rdColorTex, _MainTex, poiUV(poiMesh.uv[_Shadow3rdColorTexUV], _Shadow3rdColorTex_ST), _Shadow3rdColorTexPan);
					#else
					float4 shadow3rdColorTex = float4(1, 1, 1, 1);
					#endif
					shadow3rdColorTex.rgb = lerp(float3(1, 1, 1), shadow3rdColorTex.rgb, shadow3rdColorTex.a) * _Shadow3rdColor.rgb;
					lns.z = _Shadow3rdColor.a - lns.z * _Shadow3rdColor.a;
					indirectColor = lerp(indirectColor, shadow3rdColorTex.rgb, lns.z);
				}
				
				indirectColor = lerp(indirectColor, indirectColor * poiFragData.baseColor, _ShadowMainStrength);
				poiLight.rampedLightMap = lns.x;
				indirectColor = lerp(indirectColor, 1, lns.w * _ShadowBorderColor.rgb * _ShadowBorderColor.a);
				indirectColor = indirectColor * lerp(poiLight.indirectColor, poiLight.directColor, _LightingIgnoreAmbientColor);
				indirectColor = lerp(poiLight.directColor, indirectColor, shadowStrength * poiLight.shadowMask);
				poiLight.finalLighting = lerp(indirectColor, poiLight.directColor, lns.x) * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_SHADEMAP
				poiLight.finalLighting = poiLight.directColor * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_REALISTIC
				UnityLight light;
				light.dir = poiLight.direction;
				light.color = max(0, _LightColor0.rgb) * saturate(shadowAttenuation * attenuation * poiLight.detailShadow);
				light.ndotl = poiLight.nDotLSaturated;
				UnityIndirect indirectLight = (UnityIndirect)0;
				#ifdef UNITY_PASS_FORWARDBASE
				indirectLight = CreateIndirectLight(poiMesh, poiCam, poiLight);
				#endif
				#ifdef UNITY_PASS_FORWARDBASE
				light.color = max(light.color * _PPLightingMultiplier, 0);
				light.color = max(light.color + _PPLightingAddition, 0);
				indirectLight.diffuse = max(indirectLight.diffuse * _PPLightingMultiplier, 0);
				indirectLight.diffuse = max(indirectLight.diffuse + _PPLightingAddition, 0);
				#endif
				
				poiLight.rampedLightMap = poiLight.nDotLSaturated;
				poiLight.finalLighting = max(UNITY_BRDF_PBS(1, 0, 0, 0, poiMesh.normals[1], poiCam.viewDir, light, indirectLight).xyz, _LightingMinLightBrightness);
				#endif
				
				#ifdef _LIGHTINGMODE_CLOTH
				#if defined(PROP_CLOTHMETALLICSMOOTHNESSMAP) || !defined(OPTIMIZER_ENABLED)
				float4 clothmapsample = POI2D_SAMPLER_PAN(_ClothMetallicSmoothnessMap, _MainTex, poiUV(poiMesh.uv[_ClothMetallicSmoothnessMapUV], _ClothMetallicSmoothnessMap_ST), _ClothMetallicSmoothnessMapPan);
				float roughness = 1 - (clothmapsample.a * _ClothSmoothness);
				float reflectance = _ClothReflectance * clothmapsample.b;
				float clothmask = clothmapsample.g;
				float metallic = pow(clothmapsample.r * _ClothMetallic, 2) * ClothMetallic(clothmask);
				roughness = _ClothMetallicSmoothnessMapInvert == 1 ? 1 - roughness : roughness;
				#else
				float roughness = 1 - (_ClothSmoothness);
				float metallic = pow(_ClothMetallic, 2);
				float reflectance = _ClothReflectance;
				float clothmask = 1;
				#endif
				
				float perceptualRoughness = pow(roughness, 2);
				float clampedRoughness = max(0.002, perceptualRoughness);
				
				float f0 = 0.16 * reflectance * reflectance * (1 - metallic) + poiFragData.baseColor * metallic;
				float3 fresnel = Fresnel(f0, poiLight.nDotV);
				
				float3 dfg = SampleDFG(poiLight.nDotV, perceptualRoughness);
				
				float energyCompensation = EnvBRDFEnergyCompensation(dfg, f0, clothmask);
				
				poiLight.finalLighting = Fd_Burley(perceptualRoughness, poiLight.nDotV, poiLight.nDotLSaturated, poiLight.lDotH);
				poiLight.finalLighting *= _LightColor0 * attenuation * shadowAttenuation * poiLight.nDotLSaturated;
				poiLight.rampedLightMap = poiLight.nDotLSaturated;
				float3 specular = max(0, Specular(clampedRoughness, poiLight, f0, poiMesh.normals[1], clothmask) * poiLight.finalLighting * energyCompensation * UNITY_PI); // (D * V) * F
				
				#ifdef UNITY_PASS_FORWARDBASE
				float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
				float3 indirectDiffuse;
				indirectDiffuse.r = shEvaluateDiffuseL1Geomerics_local(L0.r, unity_SHAr.xyz, poiMesh.normals[1]);
				indirectDiffuse.g = shEvaluateDiffuseL1Geomerics_local(L0.g, unity_SHAg.xyz, poiMesh.normals[1]);
				indirectDiffuse.b = shEvaluateDiffuseL1Geomerics_local(L0.b, unity_SHAb.xyz, poiMesh.normals[1]);
				indirectDiffuse = max(0, indirectDiffuse);
				
				float3 indirectSpecular = IndirectSpecular(dfg, roughness, poiLight.occlusion, energyCompensation, clothmask, indirectDiffuse, f0, poiLight, poiFragData, poiCam, poiMesh);
				poiLight.finalLightAdd += max(0, specular + indirectSpecular);
				poiLight.finalLighting += indirectDiffuse * poiLight.occlusion;
				#endif
				
				poiFragData.baseColor.xyz *= (1 - metallic);
				#endif
				
				#ifdef _LIGHTINGMODE_WRAPPED
				#define GREYSCALE_VECTOR float3(.33333, .33333, .33333)
				float3 directColor = _LightColor0.rgb * saturate(RTWrapFunc(poiLight.nDotL, _LightingWrappedWrap, _LightingWrappedNormalization));
				float3 indirectColor = 0;
				#ifdef UNITY_PASS_FORWARDBASE
				indirectColor = ShadeSH9_wrapped(poiMesh.normals[_LightingIndirectUsesNormals], _LightingWrappedWrap) * poiLight.occlusion;
				#endif
				directColor = lerp(directColor, dot(directColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic); // Duplicated from Lightdata due to recreating the light colour
				indirectColor = lerp(indirectColor, dot(indirectColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic); // Ditto^
				
				float3 ShadeSH9Plus_2 = GetSHMaxL1();
				float bw_topDirectLighting_2 = dot(_LightColor0.rgb, GREYSCALE_VECTOR);
				float bw_directLighting = dot(directColor, GREYSCALE_VECTOR);
				float bw_indirectLighting = dot(indirectColor, GREYSCALE_VECTOR);
				float bw_topIndirectLighting = dot(ShadeSH9Plus_2, GREYSCALE_VECTOR);
				
				poiLight.lightMap = smoothstep(0, bw_topIndirectLighting + bw_topDirectLighting_2, bw_indirectLighting + bw_directLighting) * min(poiLight.detailShadow, shadowAttenuation);
				poiLight.rampedLightMap = saturate((poiLight.lightMap - (1 - _LightingGradientEnd)) / saturate((1 - _LightingGradientStart) - (1 - _LightingGradientEnd) + fwidth(poiLight.lightMap)));
				float3 mathRamp = lerp(float3(1, 1, 1), saturate(lerp((_LightingShadowColor * lerp(indirectColor, 1, _LightingIgnoreAmbientColor)), float3(1, 1, 1), saturate(poiLight.rampedLightMap))), _ShadowStrength);
				
				directColor *= saturate(poiLight.rampedLightMap + 1 - _ShadowStrength) * _LightingWrappedColor;
				
				float3 finalWrap = directColor + indirectColor;
				if (_LightingCapEnabled)
				{
					finalWrap = clamp(finalWrap, _LightingMinLightBrightness, _LightingCap);
				}
				else
				{
					finalWrap = max(finalWrap, _LightingMinLightBrightness);
				}
				//finalWrap *= attenuation;
				poiLight.finalLighting = finalWrap * saturate(mathRamp + 1 - _ShadowStrength);
				#endif
				
				#ifdef _LIGHTINGMODE_SKIN
				float3 ambientNormalWorld = poiMesh.normals[1];//aTangentToWorld(s, s.blurredNormalTangent);
				poiLight.rampedLightMap = poiLight.nDotLSaturated;
				
				// Scattering mask.
				#if defined(PROP_SKINTHICKNESS) || !defined(OPTIMIZER_ENABLED)
				float subsurface = 1 - POI2D_SAMPLER_PAN(_SkinThicknessMap, _MainTex, poiUV(poiMesh.uv[_SkinThicknessMapUV], _SkinThicknessMap_ST), _SkinThicknessMapPan).r;
				#else
				float subsurface = 1;
				#endif
				if (_SkinThicknessMapInvert)
				{
					subsurface = 1 - subsurface;
				}
				if (_SkinThicknessPower != 1)
				{
					subsurface = pow(subsurface, _SkinThicknessPower);
				}
				float skinScattering = saturate(subsurface * _SssScale * 2);
				
				// Skin subsurface depth absorption tint.
				// cf http://www.crytek.com/download/2014_03_25_CRYENGINE_GDC_Schultz.pdf pg 35
				// link dead, https://ia600902.us.archive.org/25/items/crytek_presentations/2014_03_25_CRYENGINE_GDC_Schultz.pdf
				half3 absorption = exp((1.0h - subsurface) * _SssTransmissionAbsorption.rgb);
				
				// Albedo scale for absorption assumes ~0.5 luminance for Caucasian skin.
				absorption *= saturate(poiFragData.baseColor * unity_ColorSpaceDouble.rgb);
				
				// Blurred normals for indirect diffuse and direct scattering.
				ambientNormalWorld = normalize(lerp(poiMesh.normals[1], ambientNormalWorld, _SssBumpBlur));
				
				float ndlBlur = dot(poiMesh.normals[1], poiLight.direction) * 0.5h + 0.5h;
				float lumi = dot(poiLight.directColor, half3(0.2126h, 0.7152h, 0.0722h));
				float4 sssLookupUv = float4(ndlBlur, skinScattering * lumi, 0.0f, 0.0f);
				half3 sss = poiLight.lightMap * tex2Dlod(_SkinLUT, sssLookupUv).rgb;
				poiLight.finalLighting = lerp(poiLight.directColor, min(lerp(poiLight.indirectColor * _LightingShadowColor, _LightingShadowColor, _LightingIgnoreAmbientColor) * poiLight.occlusion + (sss * poiLight.directColor), poiLight.directColor), _ShadowStrength * poiLight.shadowMask) * attenuation;
				#endif
				
				#ifdef _LIGHTINGMODE_SDF
				float3 forward = normalize(UnityObjectToWorldDir(float4(_SDFForward.xyz, 1)));
				float3 left = normalize(UnityObjectToWorldDir(float4(_SDFLeft.xyz, 1)));
				float3 lightDirHorizontal = normalize(float3(poiLight.direction.x, 0, poiLight.direction.z));
				
				float lightAtten = 1 - (dot(lightDirHorizontal, forward) * 0.5 + 0.5);
				float filpU = sign(dot(lightDirHorizontal, left));
				
				#if defined(PROP_SDFSHADINGTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float shadowSDF = POI2D_SAMPLER_PAN(_SDFShadingTexture, _MainTex, poiUV(poiMesh.uv[_SDFShadingTextureUV], _SDFShadingTexture_ST) * float2(filpU, 1), _SDFShadingTexturePan).r;
				#else
				float shadowSDF = float2(1, 1);
				#endif
				float blur = _SDFBlur * 0.1;
				float faceShadow = smoothstep(lightAtten - blur, lightAtten + blur, shadowSDF) * poiLight.detailShadow;
				
				float3 indirectColor = _LightingShadowColor.rgb;
				indirectColor = indirectColor * lerp(poiLight.indirectColor, poiLight.directColor, _LightingIgnoreAmbientColor);
				indirectColor = lerp(poiLight.directColor, indirectColor, _ShadowStrength * poiLight.shadowMask);
				
				poiLight.finalLighting = lerp(indirectColor, poiLight.directColor, faceShadow) * attenuation;
				#endif
				
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					float3 vertexLighting = float3(0, 0, 0);
					for (int index = 0; index < 4; index++)
					{
						float lightingMode = _LightingAdditiveType;
						if (lightingMode == 3)
						{
							//This is a temporary bandaid fix
							#if defined(_LIGHTINGMODE_REALISTIC)
							lightingMode = 0;
							#else
							lightingMode = 1;
							#endif
						}
						//UNITY_BRANCH
						if (lightingMode == 0)
						{
							vertexLighting = max(vertexLighting, poiLight.vColor[index] * poiLight.vSaturatedDotNL[index] * poiLight.detailShadow); // Realistic
							
						}
						//UNITY_BRANCH
						// Toon
						if (lightingMode == 1)
						{
							float2 ToonAddGradient = float2(_LightingAdditiveGradientStart, _LightingAdditiveGradientEnd);
							if (ToonAddGradient.x == ToonAddGradient.y) ToonAddGradient.y += 0.0001;
							vertexLighting = max(vertexLighting, lerp(poiLight.vColor[index], poiLight.vColor[index] * _LightingAdditivePassthrough, smoothstep(ToonAddGradient.x, ToonAddGradient.y, 1 - (.5 * poiLight.vDotNL[index] + .5))) * poiLight.detailShadow);
						}
					}
					float3 mixedLight = poiLight.finalLighting;
					poiLight.finalLighting = max(vertexLighting, poiLight.finalLighting);
					#endif
				}
			}
			#endif
			//endex
			
			#if defined(GEOM_TYPE_BRANCH) || defined(GEOM_TYPE_BRANCH_DETAIL) || defined(GEOM_TYPE_FROND) || defined(DEPTH_OF_FIELD_COC_VIEW)
			float2 decalUV(float uvNumber, float2 position, half rotation, half rotationSpeed, half2 scale, float4 scaleOffset, float depth, in PoiMesh poiMesh, in PoiCam poiCam)
			{
				scaleOffset = float4(-scaleOffset.x, scaleOffset.y, -scaleOffset.z, scaleOffset.w);
				float2 centerOffset = float2((scaleOffset.x + scaleOffset.y) / 2, (scaleOffset.z + scaleOffset.w) / 2);
				float2 uv = poiMesh.uv[uvNumber] + calcParallax(depth + 1, poiCam);
				float2 decalCenter = position + centerOffset;
				float theta = radians(rotation + _Time.z * rotationSpeed);
				float cs = cos(theta);
				float sn = sin(theta);
				uv = float2((uv.x - decalCenter.x) * cs - (uv.y - decalCenter.y) * sn + decalCenter.x, (uv.x - decalCenter.x) * sn + (uv.y - decalCenter.y) * cs + decalCenter.y);
				uv = remap(uv, float2(0, 0) - scale / 2 + position + scaleOffset.xz, scale / 2 + position + scaleOffset.yw, float2(0, 0), float2(1, 1));
				return uv;
			}
			
			inline float3 decalHueShift(float enabled, float3 color, float shift, float shiftSpeed)
			{
				//UNITY_BRANCH
				if (enabled)
				{
					color = hueShift(color, shift + _Time.x * shiftSpeed);
				}
				return color;
			}
			
			inline float applyTilingClipping(float enabled, float2 uv)
			{
				float ret = 1;
				//UNITY_BRANCH
				if (!enabled)
				{
					if (uv.x > 1 || uv.y > 1 || uv.x < 0 || uv.y < 0)
					{
						ret = 0;
					}
				}
				return ret;
			}
			
			struct PoiDecal
			{
				float m_DecalFaceMask;
				float m_DecalMaskChannel;
				float m_DecalGlobalMask;
				float m_DecalGlobalMaskBlendType;
				float m_DecalApplyGlobalMaskIndex;
				float m_DecalApplyGlobalMaskBlendType;
				float4 m_DecalTexture_ST;
				float2 m_DecalTexturePan;
				float m_DecalTextureUV;
				float4 m_DecalColor;
				float m_DecalColorThemeIndex;
				fixed m_DecalTiled;
				float m_DecalBlendType;
				half m_DecalRotation;
				half3 m_DecalScale;
				float4 m_DecalSideOffset;
				half2 m_DecalPosition;
				half m_DecalRotationSpeed;
				float m_DecalEmissionStrength;
				float m_DecalBlendAlpha;
				float m_DecalAlphaBlendMode;
				float m_DecalHueShiftEnabled;
				float m_DecalHueShift;
				float m_DecalHueShiftSpeed;
				float m_DecalDepth;
				float m_DecalHueAngleStrength;
				float m_DecalChannelSeparationEnable;
				float m_DecalChannelSeparation;
				float m_DecalChannelSeparationPremultiply;
				float m_DecalChannelSeparationHue;
				float m_DecalChannelSeparationVertical;
				float m_DecalChannelSeparationAngleStrength;
				float m_DecalOverrideAlphaMode;
				float m_DecalOverrideAlpha;
				
				#if defined(POI_AUDIOLINK)
				half m_AudioLinkDecalScaleBand;
				float4 m_AudioLinkDecalScale;
				half m_AudioLinkDecalRotationBand;
				float2 m_AudioLinkDecalRotation;
				half m_AudioLinkDecalAlphaBand;
				float2 m_AudioLinkDecalAlpha;
				half m_AudioLinkDecalEmissionBand;
				float2 m_AudioLinkDecalEmission;
				float m_DecalRotationCTALBand;
				float m_DecalRotationCTALSpeed;
				float m_DecalRotationCTALType;
				float m_AudioLinkDecalColorChord;
				float m_AudioLinkDecalSideBand;
				float4 m_AudioLinkDecalSideMin;
				float4 m_AudioLinkDecalSideMax;
				float2 m_AudioLinkDecalChannelSeparation;
				float m_AudioLinkDecalChannelSeparationBand;
				#endif
				
				float4 decalColor;
				float2 decalScale;
				float decalRotation;
				float2 uv;
				float4 dduv;
				float4 sideMod;
				float decalChannelOffset;
				float4 decalMask;
				
				void Init(in float4 DecalMask)
				{
					decalMask = DecalMask;
					decalScale = m_DecalScale.xy;// * m_DecalScale.z;
					
				}
				
				void InitAudiolink(in PoiMods poiMods)
				{
					#ifdef POI_AUDIOLINK
					if (poiMods.audioLinkAvailable)
					{
						decalScale += lerp(m_AudioLinkDecalScale.xy, m_AudioLinkDecalScale.zw, poiMods.audioLink[m_AudioLinkDecalScaleBand]);
						sideMod += lerp(m_AudioLinkDecalSideMin, m_AudioLinkDecalSideMax, poiMods.audioLink[m_AudioLinkDecalSideBand]);
						decalRotation += lerp(m_AudioLinkDecalRotation.x, m_AudioLinkDecalRotation.y, poiMods.audioLink[m_AudioLinkDecalRotationBand]);
						decalRotation += AudioLinkGetChronoTime(m_DecalRotationCTALType, m_DecalRotationCTALBand) * m_DecalRotationCTALSpeed * 360;
						decalChannelOffset += lerp(m_AudioLinkDecalChannelSeparation[0], m_AudioLinkDecalChannelSeparation[1], poiMods.audioLink[m_AudioLinkDecalChannelSeparationBand]);
					}
					#endif
				}
				
				void SampleDecalNoTexture(in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam)
				{
					uv = decalUV(m_DecalTextureUV, m_DecalPosition, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					decalColor = float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					decalColor.rgb = decalHueShift(m_DecalHueShiftEnabled, decalColor.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					decalColor.a *= decalMask[m_DecalMaskChannel] * applyTilingClipping(m_DecalTiled, uv);
				}
				
				void SampleDecal(sampler2D decalTexture, in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam, float2 scaleMultiplier = float2(1, 1))
				{
					uv = decalUV(m_DecalTextureUV, m_DecalPosition, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale * scaleMultiplier, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					// Adjust derivatives for _ST of decal texture
					float4 dduv = any(fwidth(uv) > .5) ? 0.001 : float4(ddx(uv) * m_DecalTexture_ST.x, ddy(uv) * m_DecalTexture_ST.y);
					decalColor = tex2D(decalTexture, poiUV(uv, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduv.xy, dduv.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					decalColor.rgb = decalHueShift(m_DecalHueShiftEnabled, decalColor.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					decalColor.a *= decalMask[m_DecalMaskChannel] * applyTilingClipping(m_DecalTiled, uv);
				}
				
				void SampleDecalNoAlpha(sampler2D decalTexture, in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam, float2 scaleMultiplier = float2(1, 1))
				{
					uv = decalUV(m_DecalTextureUV, m_DecalPosition, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale * scaleMultiplier, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					// Adjust derivatives for _ST of decal texture
					float4 dduv = any(fwidth(uv) > .5) ? 0.001 : float4(ddx(uv) * m_DecalTexture_ST.x, ddy(uv) * m_DecalTexture_ST.y);
					decalColor.rgb = tex2D(decalTexture, poiUV(uv, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduv.xy, dduv.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a).rgb;
					decalColor.rgb = decalHueShift(m_DecalHueShiftEnabled, decalColor.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					decalColor.a *= decalMask[m_DecalMaskChannel] * applyTilingClipping(m_DecalTiled, uv);
				}
				
				void SampleDecalAlphaOnly(sampler2D decalTexture, in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam, float2 scaleMultiplier = float2(1, 1))
				{
					uv = decalUV(m_DecalTextureUV, m_DecalPosition, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale * scaleMultiplier, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					// Adjust derivatives for _ST of decal texture
					float4 dduv = any(fwidth(uv) > .5) ? 0.001 : float4(ddx(uv) * m_DecalTexture_ST.x, ddy(uv) * m_DecalTexture_ST.y);
					decalColor = tex2D(decalTexture, poiUV(uv, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduv.xy, dduv.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					decalColor.a *= decalMask[m_DecalMaskChannel] * applyTilingClipping(m_DecalTiled, uv);
				}
				
				void SampleDecalChannelSeparation(sampler2D decalTexture, in PoiMods poiMods, in PoiLight poiLight, in PoiMesh poiMesh, in PoiCam poiCam)
				{
					decalColor = float4(0, 0, 0, 1);
					decalChannelOffset += m_DecalChannelSeparation + m_DecalChannelSeparationAngleStrength * (m_DecalChannelSeparationAngleStrength > 0 ? (1 - poiLight.nDotV) : poiLight.nDotV);
					float2 positionOffset = decalChannelOffset * 0.01 * (decalScale.x + decalScale.y) * float2(cos(m_DecalChannelSeparationVertical), sin(m_DecalChannelSeparationVertical));
					float2 uvSample0 = decalUV(m_DecalTextureUV, m_DecalPosition + positionOffset, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					float2 uvSample1 = decalUV(m_DecalTextureUV, m_DecalPosition - positionOffset, m_DecalRotation + decalRotation, m_DecalRotationSpeed, decalScale, m_DecalSideOffset +sideMod, m_DecalDepth, poiMesh, poiCam);
					
					float4 dduvSample0 = any(fwidth(uvSample0) > .5) ? 0.001 : float4(ddx(uvSample0) * m_DecalTexture_ST.x, ddy(uvSample0) * m_DecalTexture_ST.y);
					float4 dduvSample1 = any(fwidth(uvSample1) > .5) ? 0.001 : float4(ddx(uvSample1) * m_DecalTexture_ST.x, ddy(uvSample1) * m_DecalTexture_ST.y);
					
					float4 sample0 = tex2D(decalTexture, poiUV(uvSample0, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduvSample0.xy, dduvSample0.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					float4 sample1 = tex2D(decalTexture, poiUV(uvSample1, m_DecalTexture_ST) + m_DecalTexturePan * _Time.x, dduvSample1.xy, dduvSample1.zw) * float4(poiThemeColor(poiMods, m_DecalColor.rgb, m_DecalColorThemeIndex), m_DecalColor.a);
					
					sample0.rgb = decalHueShift(m_DecalHueShiftEnabled, sample0.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					sample1.rgb = decalHueShift(m_DecalHueShiftEnabled, sample1.rgb, m_DecalHueShift + poiLight.nDotV * m_DecalHueAngleStrength, m_DecalHueShiftSpeed);
					
					float3 channelSeparationColor = HUEtoRGB(frac(m_DecalChannelSeparationHue));
					
					if (m_DecalChannelSeparationPremultiply)
					{
						decalColor.rgb = lerp(sample0 * sample0.a, sample1 * sample1.a, channelSeparationColor);
					}
					else
					{
						decalColor.rgb = lerp(sample0, sample1, channelSeparationColor);
					}
					decalColor.a = 0.5 * (sample0.a + sample1.a);
					decalColor.a *= decalMask[m_DecalMaskChannel] * max(applyTilingClipping(m_DecalTiled, uvSample0), applyTilingClipping(m_DecalTiled, uvSample1));
				}
				
				void Apply(inout float alphaOverride, inout float decalAlpha, inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, inout PoiMods poiMods, in PoiLight poiLight)
				{
					if (m_DecalGlobalMask > 0)
					{
						decalColor.a = maskBlend(decalColor.a, poiMods.globalMask[m_DecalGlobalMask - 1], m_DecalGlobalMaskBlendType);
					}
					
					float audioLinkDecalAlpha = 0;
					float audioLinkDecalEmission = 0;
					#ifdef POI_AUDIOLINK
					audioLinkDecalEmission = lerp(m_AudioLinkDecalEmission.x, m_AudioLinkDecalEmission.y, poiMods.audioLink[m_AudioLinkDecalEmissionBand]) * poiMods.audioLinkAvailable;
					
					if (m_AudioLinkDecalColorChord)
					{
						if (poiMods.audioLinkAvailable)
						{
							decalColor.rgb *= AudioLinkLerp(ALPASS_CCSTRIP + float2(uv.x * AUDIOLINK_WIDTH, 0)).rgb;
						}
						else
						{
							decalAlpha = 0;
						}
					}
					audioLinkDecalAlpha = lerp(m_AudioLinkDecalAlpha.x, m_AudioLinkDecalAlpha.y, poiMods.audioLink[m_AudioLinkDecalAlphaBand]) * poiMods.audioLinkAvailable;
					#endif
					
					if (m_DecalOverrideAlpha)
					{
						float finalAlpha = lerp(1, min(decalAlpha, decalColor.a), decalMask[m_DecalMaskChannel]);
						if (m_DecalOverrideAlphaMode != 0 && !m_DecalTiled)
						{
							if (uv.x > 0 && uv.x < 1 && uv.y > 0 && uv.y < 1)
							{
								//decalAlpha = lerp(decalAlpha, min(decalAlpha, decalColor.a), decalMask[m_DecalMaskChannel]);
								//poiFragData.alpha = saturate(poiFragData.alpha + lerp(1, min(decalAlpha, decalColor.a), decalMask[m_DecalMaskChannel]));
								if (m_DecalOverrideAlpha == 1) poiFragData.alpha = finalAlpha;
								if (m_DecalOverrideAlpha == 2) poiFragData.alpha = saturate(poiFragData.alpha * finalAlpha);
								if (m_DecalOverrideAlpha == 3) poiFragData.alpha = saturate(poiFragData.alpha + finalAlpha);
								if (m_DecalOverrideAlpha == 4) poiFragData.alpha = saturate(poiFragData.alpha - finalAlpha);
								if (m_DecalOverrideAlpha == 5) poiFragData.alpha = min(poiFragData.alpha, finalAlpha);
								if (m_DecalOverrideAlpha == 6) poiFragData.alpha = max(poiFragData.alpha, finalAlpha);
							}
						}
						else
						{
							if (m_DecalOverrideAlpha == 1) poiFragData.alpha = finalAlpha;
							if (m_DecalOverrideAlpha == 2) poiFragData.alpha = saturate(poiFragData.alpha * finalAlpha);
							if (m_DecalOverrideAlpha == 3) poiFragData.alpha = saturate(poiFragData.alpha + finalAlpha);
							if (m_DecalOverrideAlpha == 4) poiFragData.alpha = saturate(poiFragData.alpha - finalAlpha);
							if (m_DecalOverrideAlpha == 5) poiFragData.alpha = min(poiFragData.alpha, finalAlpha);
							if (m_DecalOverrideAlpha == 6) poiFragData.alpha = max(poiFragData.alpha, finalAlpha);
						}
					}
					
					if (m_DecalFaceMask > 0)
					{
						if (m_DecalFaceMask == 1 && !poiMesh.isFrontFace)
						{
							decalColor.a *= 0;
						}
						else if (m_DecalFaceMask == 2 && poiMesh.isFrontFace)
						{
							decalColor.a *= 0;
						}
					}
					
					float decalAlphaMixed = decalColor.a * saturate(m_DecalBlendAlpha + audioLinkDecalAlpha);
					
					if (m_DecalApplyGlobalMaskIndex > 0)
					{
						applyToGlobalMask(poiMods, m_DecalApplyGlobalMaskIndex - 1, m_DecalApplyGlobalMaskBlendType, decalAlphaMixed);
					}
					
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, decalColor.rgb, m_DecalBlendType), decalAlphaMixed);
					poiFragData.emission += decalColor.rgb * decalColor.a * max(m_DecalEmissionStrength + audioLinkDecalEmission, 0);
				}
				float2 GetVideoAspectRatio(float2 videoDimensions, float CorrectionType, float fitToScale)
				{
					float2 AspectRatioMultiplier = float2(1, 1);
					if (fitToScale)
					{
						float2 decalScale = m_DecalScale.xy + float2(m_DecalSideOffset.x + m_DecalSideOffset.y, m_DecalSideOffset.z + m_DecalSideOffset.w);
						if (decalScale.x > decalScale.y)
						{
							videoDimensions.xy *= float2((decalScale.y / decalScale.x), 1);
						}
						else
						{
							videoDimensions.xy *= float2(1, (decalScale.x / decalScale.y));
						}
					}
					
					if (CorrectionType != 2)
					{
						if (CorrectionType == 0)
						{
							if (videoDimensions.x > videoDimensions.y)
							{
								AspectRatioMultiplier = float2(1, videoDimensions.y / videoDimensions.x);
							}
							else
							{
								AspectRatioMultiplier = float2(videoDimensions.x / videoDimensions.y, 1);
							}
						}
						else if (CorrectionType == 1)
						{
							if (videoDimensions.x > videoDimensions.y)
							{
								AspectRatioMultiplier = float2(1 / (videoDimensions.y / videoDimensions.x), 1);
							}
							else
							{
								AspectRatioMultiplier = float2(1, 1 / (videoDimensions.x / videoDimensions.y));
							}
						}
					}
					return AspectRatioMultiplier;
				}
			};
			
			void applyDecals(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, inout PoiMods poiMods, in PoiLight poiLight)
			{
				// check if _Udon_VideoTex is greater than 16 pixels in width
				float udonVideoTexAvailable = 0;
				float2 udonVideoAspectRatio = 1;
				if (_Udon_VideoTex_TexelSize.z > 16)
				{
					udonVideoTexAvailable = 1;
				}
				
				float decalAlpha = 1;
				float alphaOverride = 0;
				#if defined(PROP_DECALMASK) || !defined(OPTIMIZER_ENABLED)
				float4 decalMask = POI2D_SAMPLER_PAN(_DecalMask, _MainTex, poiUV(poiMesh.uv[_DecalMaskUV], _DecalMask_ST), _DecalMaskPan);
				#else
				float4 decalMask = 1;
				#endif
				
				#ifdef TPS_Penetrator
				if (_DecalTPSDepthMaskEnabled)
				{
					decalMask.r = lerp(0, decalMask.r * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Decal0TPSMaskStrength);
					decalMask.g = lerp(0, decalMask.g * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Decal1TPSMaskStrength);
					decalMask.b = lerp(0, decalMask.b * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Decal2TPSMaskStrength);
					decalMask.a = lerp(0, decalMask.a * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Decal3TPSMaskStrength);
				}
				#endif
				
				float4 decalColor = 1;
				float2 uv = 0;
				// yaes
				
				//ifex _DecalEnabled==0
				#ifdef GEOM_TYPE_BRANCH
				PoiDecal Decal0;
				PoiInitStruct(PoiDecal, Decal0)
				Decal0.m_DecalFaceMask = _Decal0FaceMask;
				Decal0.m_DecalMaskChannel = _Decal0MaskChannel;
				Decal0.m_DecalGlobalMask = _Decal0GlobalMask;
				Decal0.m_DecalGlobalMaskBlendType = _Decal0GlobalMaskBlendType;
				Decal0.m_DecalApplyGlobalMaskIndex = _Decal0ApplyGlobalMaskIndex;
				Decal0.m_DecalApplyGlobalMaskBlendType = _Decal0ApplyGlobalMaskBlendType;
				Decal0.m_DecalTexture_ST = _DecalTexture_ST;
				Decal0.m_DecalTexturePan = _DecalTexturePan;
				Decal0.m_DecalTextureUV = _DecalTextureUV;
				Decal0.m_DecalColor = _DecalColor;
				Decal0.m_DecalColorThemeIndex = _DecalColorThemeIndex;
				Decal0.m_DecalTiled = _DecalTiled;
				Decal0.m_DecalBlendType = _DecalBlendType;
				Decal0.m_DecalRotation = _DecalRotation;
				Decal0.m_DecalScale = _DecalScale;
				Decal0.m_DecalSideOffset = _DecalSideOffset;
				Decal0.m_DecalPosition = _DecalPosition;
				Decal0.m_DecalRotationSpeed = _DecalRotationSpeed;
				Decal0.m_DecalEmissionStrength = _DecalEmissionStrength;
				Decal0.m_DecalBlendAlpha = _DecalBlendAlpha;
				Decal0.m_DecalOverrideAlpha = _DecalOverrideAlpha;
				Decal0.m_DecalHueShiftEnabled = _DecalHueShiftEnabled;
				Decal0.m_DecalHueShift = _DecalHueShift;
				Decal0.m_DecalHueShiftSpeed = _DecalHueShiftSpeed;
				Decal0.m_DecalDepth = _Decal0Depth;
				Decal0.m_DecalHueAngleStrength = _Decal0HueAngleStrength;
				Decal0.m_DecalChannelSeparationEnable = _Decal0ChannelSeparationEnable;
				Decal0.m_DecalChannelSeparation = _Decal0ChannelSeparation;
				Decal0.m_DecalChannelSeparationPremultiply = _Decal0ChannelSeparationPremultiply;
				Decal0.m_DecalChannelSeparationHue = _Decal0ChannelSeparationHue;
				Decal0.m_DecalChannelSeparationVertical = _Decal0ChannelSeparationVertical;
				Decal0.m_DecalChannelSeparationAngleStrength = _Decal0ChannelSeparationAngleStrength;
				Decal0.m_DecalOverrideAlphaMode = _Decal0OverrideAlphaMode;
				
				Decal0.Init(decalMask);
				
				#if defined(POI_AUDIOLINK)
				Decal0.m_AudioLinkDecalScaleBand = _AudioLinkDecal0ScaleBand;
				Decal0.m_AudioLinkDecalScale = _AudioLinkDecal0Scale;
				Decal0.m_AudioLinkDecalRotationBand = _AudioLinkDecal0RotationBand;
				Decal0.m_AudioLinkDecalRotation = _AudioLinkDecal0Rotation;
				Decal0.m_AudioLinkDecalAlphaBand = _AudioLinkDecal0AlphaBand;
				Decal0.m_AudioLinkDecalAlpha = _AudioLinkDecal0Alpha;
				Decal0.m_AudioLinkDecalEmissionBand = _AudioLinkDecal0EmissionBand;
				Decal0.m_AudioLinkDecalEmission = _AudioLinkDecal0Emission;
				Decal0.m_DecalRotationCTALBand = _DecalRotationCTALBand0;
				Decal0.m_DecalRotationCTALSpeed = _DecalRotationCTALSpeed0;
				Decal0.m_DecalRotationCTALType = _DecalRotationCTALType0;
				Decal0.m_AudioLinkDecalColorChord = _AudioLinkDecalCC0;
				Decal0.m_AudioLinkDecalSideBand = _AudioLinkDecal0SideBand;
				Decal0.m_AudioLinkDecalSideMin = _AudioLinkDecal0SideMin;
				Decal0.m_AudioLinkDecalSideMax = _AudioLinkDecal0SideMax;
				Decal0.m_AudioLinkDecalChannelSeparation = _AudioLinkDecal0ChannelSeparation;
				Decal0.m_AudioLinkDecalChannelSeparationBand = _AudioLinkDecal0ChannelSeparationBand;
				
				Decal0.InitAudiolink(poiMods);
				#endif
				
				if (!_Decal0VideoEnabled)
				{
					
					#if defined(PROP_DECALTEXTURE) || !defined(OPTIMIZER_ENABLED)
					//ifex _Decal0ChannelSeparationEnable==0
					if (_Decal0ChannelSeparationEnable)
					{
						Decal0.SampleDecalChannelSeparation(_DecalTexture, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					//ifex _Decal0ChannelSeparationEnable==1
					if (!_Decal0ChannelSeparationEnable)
					{
						Decal0.SampleDecal(_DecalTexture, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					#else
					Decal0.SampleDecalNoTexture(poiMods, poiLight, poiMesh, poiCam);
					#endif
					Decal0.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
				}
				else
				{
					udonVideoAspectRatio = Decal0.GetVideoAspectRatio(_Udon_VideoTex_TexelSize.zw, _Decal0VideoAspectFix, _Decal0VideoFitToScale);
					
					if (_Decal0OnlyVideo)
					{
						if (udonVideoTexAvailable)
						{
							Decal0.m_DecalEmissionStrength += _Decal0VideoEmissionStrength;
							if (_Decal0UseDecalAlpha)
							{
								Decal0.SampleDecal(_DecalTexture, poiMods, poiLight, poiMesh, poiCam);
								Decal0.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal0.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							Decal0.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
						}
					}
					else
					{
						Decal0.SampleDecal(_DecalTexture, poiMods, poiLight, poiMesh, poiCam);
						if (udonVideoTexAvailable)
						{
							Decal0.m_DecalEmissionStrength += _Decal0VideoEmissionStrength;
							if (_Decal0UseDecalAlpha)
							{
								Decal0.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal0.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
						}
						Decal0.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
					}
				}
				#endif
				//endex
				
				//ifex _DecalEnabled1==0
				#ifdef GEOM_TYPE_BRANCH_DETAIL
				PoiDecal Decal1;
				PoiInitStruct(PoiDecal, Decal1)
				Decal1.m_DecalFaceMask = _Decal1FaceMask;
				Decal1.m_DecalMaskChannel = _Decal1MaskChannel;
				Decal1.m_DecalGlobalMask = _Decal1GlobalMask;
				Decal1.m_DecalGlobalMaskBlendType = _Decal1GlobalMaskBlendType;
				Decal1.m_DecalApplyGlobalMaskIndex = _Decal1ApplyGlobalMaskIndex;
				Decal1.m_DecalApplyGlobalMaskBlendType = _Decal1ApplyGlobalMaskBlendType;
				Decal1.m_DecalTexture_ST = _DecalTexture1_ST;
				Decal1.m_DecalTexturePan = _DecalTexture1Pan;
				Decal1.m_DecalTextureUV = _DecalTexture1UV;
				Decal1.m_DecalColor = _DecalColor1;
				Decal1.m_DecalColorThemeIndex = _DecalColor1ThemeIndex;
				Decal1.m_DecalTiled = _DecalTiled1;
				Decal1.m_DecalBlendType = _DecalBlendType1;
				Decal1.m_DecalRotation = _DecalRotation1;
				Decal1.m_DecalScale = _DecalScale1;
				Decal1.m_DecalSideOffset = _DecalSideOffset1;
				Decal1.m_DecalPosition = _DecalPosition1;
				Decal1.m_DecalRotationSpeed = _DecalRotationSpeed1;
				Decal1.m_DecalEmissionStrength = _DecalEmissionStrength1;
				Decal1.m_DecalBlendAlpha = _DecalBlendAlpha1;
				Decal1.m_DecalOverrideAlpha = _DecalOverrideAlpha1;
				Decal1.m_DecalHueShiftEnabled = _DecalHueShiftEnabled1;
				Decal1.m_DecalHueShift = _DecalHueShift1;
				Decal1.m_DecalHueShiftSpeed = _DecalHueShiftSpeed1;
				Decal1.m_DecalDepth = _Decal1Depth;
				Decal1.m_DecalHueAngleStrength = _Decal1HueAngleStrength;
				Decal1.m_DecalChannelSeparationEnable = _Decal1ChannelSeparationEnable;
				Decal1.m_DecalChannelSeparation = _Decal1ChannelSeparation;
				Decal1.m_DecalChannelSeparationPremultiply = _Decal1ChannelSeparationPremultiply;
				Decal1.m_DecalChannelSeparationHue = _Decal1ChannelSeparationHue;
				Decal1.m_DecalChannelSeparationVertical = _Decal1ChannelSeparationVertical;
				Decal1.m_DecalChannelSeparationAngleStrength = _Decal1ChannelSeparationAngleStrength;
				Decal1.m_DecalOverrideAlphaMode = _Decal1OverrideAlphaMode;
				Decal1.Init(decalMask);
				
				#if defined(POI_AUDIOLINK)
				Decal1.m_AudioLinkDecalScaleBand = _AudioLinkDecal1ScaleBand;
				Decal1.m_AudioLinkDecalScale = _AudioLinkDecal1Scale;
				Decal1.m_AudioLinkDecalRotationBand = _AudioLinkDecal1RotationBand;
				Decal1.m_AudioLinkDecalRotation = _AudioLinkDecal1Rotation;
				Decal1.m_AudioLinkDecalAlphaBand = _AudioLinkDecal1AlphaBand;
				Decal1.m_AudioLinkDecalAlpha = _AudioLinkDecal1Alpha;
				Decal1.m_AudioLinkDecalEmissionBand = _AudioLinkDecal1EmissionBand;
				Decal1.m_AudioLinkDecalEmission = _AudioLinkDecal1Emission;
				Decal1.m_DecalRotationCTALBand = _DecalRotationCTALBand1;
				Decal1.m_DecalRotationCTALSpeed = _DecalRotationCTALSpeed1;
				Decal1.m_DecalRotationCTALType = _DecalRotationCTALType1;
				Decal1.m_AudioLinkDecalColorChord = _AudioLinkDecalCC1;
				Decal1.m_AudioLinkDecalSideBand = _AudioLinkDecal1SideBand;
				Decal1.m_AudioLinkDecalSideMin = _AudioLinkDecal1SideMin;
				Decal1.m_AudioLinkDecalSideMax = _AudioLinkDecal1SideMax;
				Decal1.m_AudioLinkDecalChannelSeparation = _AudioLinkDecal1ChannelSeparation;
				Decal1.m_AudioLinkDecalChannelSeparationBand = _AudioLinkDecal1ChannelSeparationBand;
				
				Decal1.InitAudiolink(poiMods);
				#endif
				
				if (!_Decal1VideoEnabled)
				{
					#if defined(PROP_DECALTEXTURE1) || !defined(OPTIMIZER_ENABLED)
					//ifex _Decal1ChannelSeparationEnable==0
					if (_Decal1ChannelSeparationEnable)
					{
						Decal1.SampleDecalChannelSeparation(_DecalTexture1, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					//ifex _Decal1ChannelSeparationEnable==1
					if (!_Decal1ChannelSeparationEnable)
					{
						Decal1.SampleDecal(_DecalTexture1, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					#else
					Decal1.SampleDecalNoTexture(poiMods, poiLight, poiMesh, poiCam);
					#endif
					Decal1.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
				}
				else
				{
					udonVideoAspectRatio = Decal1.GetVideoAspectRatio(_Udon_VideoTex_TexelSize.zw, _Decal1VideoAspectFix, _Decal1VideoFitToScale);
					if (_Decal1OnlyVideo)
					{
						if (udonVideoTexAvailable)
						{
							Decal1.m_DecalEmissionStrength += _Decal1VideoEmissionStrength;
							if (_Decal1UseDecalAlpha)
							{
								Decal1.SampleDecal(_DecalTexture1, poiMods, poiLight, poiMesh, poiCam);
								Decal1.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal1.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							Decal1.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
						}
					}
					else
					{
						Decal1.SampleDecal(_DecalTexture1, poiMods, poiLight, poiMesh, poiCam);
						if (udonVideoTexAvailable)
						{
							Decal1.m_DecalEmissionStrength += _Decal1VideoEmissionStrength;
							if (_Decal1UseDecalAlpha)
							{
								Decal1.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal1.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
						}
						Decal1.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
					}
				}
				#endif
				//endex
				
				//ifex _DecalEnabled2==0
				#ifdef GEOM_TYPE_FROND
				PoiDecal Decal2;
				PoiInitStruct(PoiDecal, Decal2)
				Decal2.m_DecalFaceMask = _Decal2FaceMask;
				Decal2.m_DecalMaskChannel = _Decal2MaskChannel;
				Decal2.m_DecalGlobalMask = _Decal2GlobalMask;
				Decal2.m_DecalGlobalMaskBlendType = _Decal2GlobalMaskBlendType;
				Decal2.m_DecalApplyGlobalMaskIndex = _Decal2ApplyGlobalMaskIndex;
				Decal2.m_DecalApplyGlobalMaskBlendType = _Decal2ApplyGlobalMaskBlendType;
				Decal2.m_DecalTexture_ST = _DecalTexture2_ST;
				Decal2.m_DecalTexturePan = _DecalTexture2Pan;
				Decal2.m_DecalTextureUV = _DecalTexture2UV;
				Decal2.m_DecalColor = _DecalColor2;
				Decal2.m_DecalColorThemeIndex = _DecalColor2ThemeIndex;
				Decal2.m_DecalTiled = _DecalTiled2;
				Decal2.m_DecalBlendType = _DecalBlendType2;
				Decal2.m_DecalRotation = _DecalRotation2;
				Decal2.m_DecalScale = _DecalScale2;
				Decal2.m_DecalSideOffset = _DecalSideOffset2;
				Decal2.m_DecalPosition = _DecalPosition2;
				Decal2.m_DecalRotationSpeed = _DecalRotationSpeed2;
				Decal2.m_DecalEmissionStrength = _DecalEmissionStrength2;
				Decal2.m_DecalBlendAlpha = _DecalBlendAlpha2;
				Decal2.m_DecalOverrideAlpha = _DecalOverrideAlpha2;
				Decal2.m_DecalHueShiftEnabled = _DecalHueShiftEnabled2;
				Decal2.m_DecalHueShift = _DecalHueShift2;
				Decal2.m_DecalHueShiftSpeed = _DecalHueShiftSpeed2;
				Decal2.m_DecalDepth = _Decal2Depth;
				Decal2.m_DecalHueAngleStrength = _Decal2HueAngleStrength;
				Decal2.m_DecalChannelSeparationEnable = _Decal2ChannelSeparationEnable;
				Decal2.m_DecalChannelSeparation = _Decal2ChannelSeparation;
				Decal2.m_DecalChannelSeparationPremultiply = _Decal2ChannelSeparationPremultiply;
				Decal2.m_DecalChannelSeparationHue = _Decal2ChannelSeparationHue;
				Decal2.m_DecalChannelSeparationVertical = _Decal2ChannelSeparationVertical;
				Decal2.m_DecalChannelSeparationAngleStrength = _Decal2ChannelSeparationAngleStrength;
				Decal2.m_DecalOverrideAlphaMode = _Decal2OverrideAlphaMode;
				Decal2.Init(decalMask);
				
				#if defined(POI_AUDIOLINK)
				Decal2.m_AudioLinkDecalScaleBand = _AudioLinkDecal2ScaleBand;
				Decal2.m_AudioLinkDecalScale = _AudioLinkDecal2Scale;
				Decal2.m_AudioLinkDecalRotationBand = _AudioLinkDecal2RotationBand;
				Decal2.m_AudioLinkDecalRotation = _AudioLinkDecal2Rotation;
				Decal2.m_AudioLinkDecalAlphaBand = _AudioLinkDecal2AlphaBand;
				Decal2.m_AudioLinkDecalAlpha = _AudioLinkDecal2Alpha;
				Decal2.m_AudioLinkDecalEmissionBand = _AudioLinkDecal2EmissionBand;
				Decal2.m_AudioLinkDecalEmission = _AudioLinkDecal2Emission;
				Decal2.m_DecalRotationCTALBand = _DecalRotationCTALBand2;
				Decal2.m_DecalRotationCTALSpeed = _DecalRotationCTALSpeed2;
				Decal2.m_DecalRotationCTALType = _DecalRotationCTALType2;
				Decal2.m_AudioLinkDecalColorChord = _AudioLinkDecalCC2;
				Decal2.m_AudioLinkDecalSideBand = _AudioLinkDecal2SideBand;
				Decal2.m_AudioLinkDecalSideMin = _AudioLinkDecal2SideMin;
				Decal2.m_AudioLinkDecalSideMax = _AudioLinkDecal2SideMax;
				Decal2.m_AudioLinkDecalChannelSeparation = _AudioLinkDecal2ChannelSeparation;
				Decal2.m_AudioLinkDecalChannelSeparationBand = _AudioLinkDecal2ChannelSeparationBand;
				
				Decal2.InitAudiolink(poiMods);
				#endif
				if (!_Decal2VideoEnabled)
				{
					#if defined(PROP_DECALTEXTURE2) || !defined(OPTIMIZER_ENABLED)
					//ifex _Decal2ChannelSeparationEnable==0
					if (_Decal2ChannelSeparationEnable)
					{
						Decal2.SampleDecalChannelSeparation(_DecalTexture2, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					//ifex _Decal2ChannelSeparationEnable==1
					if (!_Decal2ChannelSeparationEnable)
					{
						Decal2.SampleDecal(_DecalTexture2, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					#else
					Decal2.SampleDecalNoTexture(poiMods, poiLight, poiMesh, poiCam);
					#endif
					Decal2.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
				}
				else
				{
					udonVideoAspectRatio = Decal2.GetVideoAspectRatio(_Udon_VideoTex_TexelSize.zw, _Decal2VideoAspectFix, _Decal2VideoFitToScale);
					if (_Decal2OnlyVideo)
					{
						if (udonVideoTexAvailable)
						{
							Decal2.m_DecalEmissionStrength += _Decal2VideoEmissionStrength;
							if (_Decal2UseDecalAlpha)
							{
								Decal2.SampleDecal(_DecalTexture2, poiMods, poiLight, poiMesh, poiCam);
								Decal2.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal2.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							Decal2.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
						}
					}
					else
					{
						Decal2.SampleDecal(_DecalTexture2, poiMods, poiLight, poiMesh, poiCam);
						if (udonVideoTexAvailable)
						{
							Decal2.m_DecalEmissionStrength += _Decal2VideoEmissionStrength;
							if (_Decal2UseDecalAlpha)
							{
								Decal2.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal2.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
						}
						Decal2.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
					}
				}
				#endif
				//endex
				
				//ifex _DecalEnabled3==0
				#ifdef DEPTH_OF_FIELD_COC_VIEW
				PoiDecal Decal3;
				PoiInitStruct(PoiDecal, Decal3)
				Decal3.m_DecalFaceMask = _Decal3FaceMask;
				Decal3.m_DecalMaskChannel = _Decal3MaskChannel;
				Decal3.m_DecalGlobalMask = _Decal3GlobalMask;
				Decal3.m_DecalGlobalMaskBlendType = _Decal3GlobalMaskBlendType;
				Decal3.m_DecalApplyGlobalMaskIndex = _Decal3ApplyGlobalMaskIndex;
				Decal3.m_DecalApplyGlobalMaskBlendType = _Decal3ApplyGlobalMaskBlendType;
				Decal3.m_DecalTexture_ST = _DecalTexture3_ST;
				Decal3.m_DecalTexturePan = _DecalTexture3Pan;
				Decal3.m_DecalTextureUV = _DecalTexture3UV;
				Decal3.m_DecalColor = _DecalColor3;
				Decal3.m_DecalColorThemeIndex = _DecalColor3ThemeIndex;
				Decal3.m_DecalTiled = _DecalTiled3;
				Decal3.m_DecalBlendType = _DecalBlendType3;
				Decal3.m_DecalRotation = _DecalRotation3;
				Decal3.m_DecalScale = _DecalScale3;
				Decal3.m_DecalSideOffset = _DecalSideOffset3;
				Decal3.m_DecalPosition = _DecalPosition3;
				Decal3.m_DecalRotationSpeed = _DecalRotationSpeed3;
				Decal3.m_DecalEmissionStrength = _DecalEmissionStrength3;
				Decal3.m_DecalBlendAlpha = _DecalBlendAlpha3;
				Decal3.m_DecalOverrideAlpha = _DecalOverrideAlpha3;
				Decal3.m_DecalHueShiftEnabled = _DecalHueShiftEnabled3;
				Decal3.m_DecalHueShift = _DecalHueShift3;
				Decal3.m_DecalHueShiftSpeed = _DecalHueShiftSpeed3;
				Decal3.m_DecalDepth = _Decal3Depth;
				Decal3.m_DecalHueAngleStrength = _Decal3HueAngleStrength;
				Decal3.m_DecalChannelSeparationEnable = _Decal3ChannelSeparationEnable;
				Decal3.m_DecalChannelSeparation = _Decal3ChannelSeparation;
				Decal3.m_DecalChannelSeparationPremultiply = _Decal3ChannelSeparationPremultiply;
				Decal3.m_DecalChannelSeparationHue = _Decal3ChannelSeparationHue;
				Decal3.m_DecalChannelSeparationVertical = _Decal3ChannelSeparationVertical;
				Decal3.m_DecalChannelSeparationAngleStrength = _Decal3ChannelSeparationAngleStrength;
				Decal3.m_DecalOverrideAlphaMode = _Decal3OverrideAlphaMode;
				Decal3.Init(decalMask);
				
				#if defined(POI_AUDIOLINK)
				Decal3.m_AudioLinkDecalScaleBand = _AudioLinkDecal3ScaleBand;
				Decal3.m_AudioLinkDecalScale = _AudioLinkDecal3Scale;
				Decal3.m_AudioLinkDecalRotationBand = _AudioLinkDecal3RotationBand;
				Decal3.m_AudioLinkDecalRotation = _AudioLinkDecal3Rotation;
				Decal3.m_AudioLinkDecalAlphaBand = _AudioLinkDecal3AlphaBand;
				Decal3.m_AudioLinkDecalAlpha = _AudioLinkDecal3Alpha;
				Decal3.m_AudioLinkDecalEmissionBand = _AudioLinkDecal3EmissionBand;
				Decal3.m_AudioLinkDecalEmission = _AudioLinkDecal3Emission;
				Decal3.m_DecalRotationCTALBand = _DecalRotationCTALBand3;
				Decal3.m_DecalRotationCTALSpeed = _DecalRotationCTALSpeed3;
				Decal3.m_DecalRotationCTALType = _DecalRotationCTALType3;
				Decal3.m_AudioLinkDecalColorChord = _AudioLinkDecalCC3;
				Decal3.m_AudioLinkDecalSideBand = _AudioLinkDecal3SideBand;
				Decal3.m_AudioLinkDecalSideMin = _AudioLinkDecal3SideMin;
				Decal3.m_AudioLinkDecalSideMax = _AudioLinkDecal3SideMax;
				Decal3.m_AudioLinkDecalChannelSeparation = _AudioLinkDecal3ChannelSeparation;
				Decal3.m_AudioLinkDecalChannelSeparationBand = _AudioLinkDecal3ChannelSeparationBand;
				
				Decal3.InitAudiolink(poiMods);
				#endif
				if (!_Decal3VideoEnabled)
				{
					#if defined(PROP_DECALTEXTURE3) || !defined(OPTIMIZER_ENABLED)
					//ifex _Decal3ChannelSeparationEnable==0
					if (_Decal3ChannelSeparationEnable)
					{
						Decal3.SampleDecalChannelSeparation(_DecalTexture3, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					//ifex _Decal3ChannelSeparationEnable==1
					if (!_Decal3ChannelSeparationEnable)
					{
						Decal3.SampleDecal(_DecalTexture3, poiMods, poiLight, poiMesh, poiCam);
					}
					//endex
					#else
					Decal3.SampleDecalNoTexture(poiMods, poiLight, poiMesh, poiCam);
					#endif
					Decal3.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
				}
				else
				{
					udonVideoAspectRatio = Decal3.GetVideoAspectRatio(_Udon_VideoTex_TexelSize.zw, _Decal3VideoAspectFix, _Decal3VideoFitToScale);
					if (_Decal3OnlyVideo)
					{
						if (udonVideoTexAvailable)
						{
							Decal3.m_DecalEmissionStrength += _Decal3VideoEmissionStrength;
							if (_Decal3UseDecalAlpha)
							{
								Decal3.SampleDecal(_DecalTexture3, poiMods, poiLight, poiMesh, poiCam);
								Decal3.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal3.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							Decal3.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
						}
					}
					else
					{
						Decal3.SampleDecal(_DecalTexture3, poiMods, poiLight, poiMesh, poiCam);
						if (udonVideoTexAvailable)
						{
							Decal3.m_DecalEmissionStrength += _Decal3VideoEmissionStrength;
							if (_Decal3UseDecalAlpha)
							{
								Decal3.SampleDecalNoAlpha(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
							else
							{
								Decal3.SampleDecal(_Udon_VideoTex, poiMods, poiLight, poiMesh, poiCam, udonVideoAspectRatio);
							}
						}
						Decal3.Apply(alphaOverride, decalAlpha, poiFragData, poiMesh, poiCam, poiMods, poiLight);
					}
				}
				#endif
				//endex
				//if (alphaOverride)
				//{
				
				//poiFragData.baseColor = decalAlpha;
				//poiFragData.alpha *= decalAlpha;
				
				//}
				//poiFragData.baseColor = saturate(poiFragData.baseColor);
				
			}
			#endif
			
			//ifex _EnableDissolve==0
			#ifdef DISTORT
			void applyDissolve(inout PoiFragData poiFragData, in PoiMesh poiMesh, inout PoiMods poiMods, in PoiCam poiCam, in PoiLight poiLight)
			{
				#if defined(PROP_DISSOLVEMASK) || !defined(OPTIMIZER_ENABLED)
				float dissolveMask = POI2D_SAMPLER_PAN(_DissolveMask, _MainTex, poiUV(poiMesh.uv[_DissolveMaskUV], _DissolveMask_ST), _DissolveMaskPan).r;
				#else
				float dissolveMask = 1;
				#endif
				UNITY_BRANCH
				if (_DissolveUseVertexColors > 0)
				{
					// Vertex Color Imprecision hype
					dissolveMask = ceil(poiMesh.vertexColor[_DissolveUseVertexColors] * 100000) / 100000;
				}
				if (_DissolveMaskGlobalMask > 0)
				{
					dissolveMask = maskBlend(dissolveMask, poiMods.globalMask[_DissolveMaskGlobalMask - 1], _DissolveMaskGlobalMaskBlendType);
				}
				
				#if defined(PROP_DISSOLVETOTEXTURE) || !defined(OPTIMIZER_ENABLED)
				dissolveToTexture = POI2D_SAMPLER_PAN(_DissolveToTexture, _MainTex, poiUV(poiMesh.uv[_DissolveToTextureUV], _DissolveToTexture_ST), _DissolveToTexturePan) * float4(poiThemeColor(poiMods, _DissolveTextureColor.rgb, _DissolveTextureColorThemeIndex), _DissolveTextureColor.a);
				#else
				dissolveToTexture = _DissolveTextureColor;
				#endif
				
				#if defined(PROP_DISSOLVENOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
				float dissolveNoiseTexture = POI2D_SAMPLER_PAN(_DissolveNoiseTexture, _MainTex, poiUV(poiMesh.uv[_DissolveNoiseTextureUV], _DissolveNoiseTexture_ST), _DissolveNoiseTexturePan).r;
				#else
				float dissolveNoiseTexture = 1;
				#endif
				
				float da = _DissolveAlpha
				+ _DissolveAlpha0
				+ _DissolveAlpha1
				+ _DissolveAlpha2
				+ _DissolveAlpha3
				+ _DissolveAlpha4
				+ _DissolveAlpha5
				+ _DissolveAlpha6
				+ _DissolveAlpha7
				+ _DissolveAlpha8
				+ _DissolveAlpha9;
				float dds = _DissolveDetailStrength;
				
				if (_UVTileDissolveEnabled)
				{
					float2 udim = floor(poiMesh.uv[(int)_UVTileDissolveUV]);
					
					float4 xMask = float4((udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					da += (udim.y >= 0 && udim.y < 1) * dot(float4(_UVTileDissolveAlpha_Row0_0, _UVTileDissolveAlpha_Row0_1, _UVTileDissolveAlpha_Row0_2, _UVTileDissolveAlpha_Row0_3), xMask);
					da += (udim.y >= 1 && udim.y < 2) * dot(float4(_UVTileDissolveAlpha_Row1_0, _UVTileDissolveAlpha_Row1_1, _UVTileDissolveAlpha_Row1_2, _UVTileDissolveAlpha_Row1_3), xMask);
					da += (udim.y >= 2 && udim.y < 3) * dot(float4(_UVTileDissolveAlpha_Row2_0, _UVTileDissolveAlpha_Row2_1, _UVTileDissolveAlpha_Row2_2, _UVTileDissolveAlpha_Row2_3), xMask);
					da += (udim.y >= 3 && udim.y < 4) * dot(float4(_UVTileDissolveAlpha_Row3_0, _UVTileDissolveAlpha_Row3_1, _UVTileDissolveAlpha_Row3_2, _UVTileDissolveAlpha_Row3_3), xMask);
				}
				
				#ifdef POI_AUDIOLINK
				UNITY_BRANCH
				if (_EnableDissolveAudioLink && poiMods.audioLinkAvailable)
				{
					da += lerp(_AudioLinkDissolveAlpha.x, _AudioLinkDissolveAlpha.y, poiMods.audioLink[_AudioLinkDissolveAlphaBand]);
					dds += lerp(_AudioLinkDissolveDetail.x, _AudioLinkDissolveDetail.y, poiMods.audioLink[_AudioLinkDissolveDetailBand]);
				}
				#endif
				
				da = saturate(da);
				dds = saturate(dds);
				
				if (_DissolveMaskInvert)
				{
					dissolveMask = 1 - dissolveMask;
				}
				#if defined(PROP_DISSOLVEDETAILNOISE) || !defined(OPTIMIZER_ENABLED)
				float dissolveDetailNoise = POI2D_SAMPLER_PAN(_DissolveDetailNoise, _MainTex, poiUV(poiMesh.uv[_DissolveDetailNoiseUV], _DissolveDetailNoise_ST), _DissolveDetailNoisePan);
				#else
				float dissolveDetailNoise = 0;
				#endif
				if (_DissolveInvertNoise)
				{
					dissolveNoiseTexture = 1 - dissolveNoiseTexture;
				}
				if (_DissolveInvertDetailNoise)
				{
					dissolveDetailNoise = 1 - dissolveDetailNoise;
				}
				if (_ContinuousDissolve != 0)
				{
					da = sin(_Time.x * _ContinuousDissolve) * .5 + .5;
				}
				da *= dissolveMask;
				dissolveAlpha = da;
				edgeAlpha = 0;
				
				[flatten]
				switch(_DissolveType)
				{
					default: // Basic (case 1)
					
					{
						da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						dissolveAlpha = da;
						//Adjust detail strength to avoid artifacts
						dds *= smoothstep(1, 0.99, da) * lerp(1, smoothstep(0, lerp(0.01, 0.1, dds), da), _DissolveDetailEdgeSmoothing);
						float noise = saturate(dissolveNoiseTexture - dissolveDetailNoise * dds);
						
						noise = saturate(noise * 0.998 + 0.001);
						dissolveAlpha = dissolveAlpha >= noise;
						edgeAlpha = remapClamped(da + _DissolveEdgeWidth, da, noise) * (1 - dissolveAlpha);
						break;
					}
					case 2: // Point to Point
					
					{
						float3 direction;
						float3 currentPos;
						float distanceTo = 0;
						direction = normalize(_DissolveEndPoint - _DissolveStartPoint);
						currentPos = lerp(_DissolveStartPoint, _DissolveEndPoint, dissolveAlpha);
						
						UNITY_BRANCH
						if (_DissolveP2PWorldLocal != 1)
						{
							float3 pos = _DissolveP2PWorldLocal == 0 ? poiMesh.localPos.rgb : poiMesh.vertexColor.rgb;
							distanceTo = dot(pos - currentPos, direction) - dissolveDetailNoise * dds;
							edgeAlpha = smoothstep(_DissolveP2PEdgeLength + .00001, 0, distanceTo);
							dissolveAlpha = step(distanceTo, 0);
							edgeAlpha *= 1 - dissolveAlpha;
						}
						else
						{
							distanceTo = dot(poiMesh.worldPos - currentPos, direction) - dissolveDetailNoise * dds;
							edgeAlpha = smoothstep(_DissolveP2PEdgeLength + .00001, 0, distanceTo);
							dissolveAlpha = (distanceTo < 0) ? 1 : 0;
							edgeAlpha *= 1 - dissolveAlpha;
						}
						
						if (_DissolveP2PClamp)
						{
							dissolveAlpha = saturate(dissolveAlpha * smoothstep(0, 0.01, da) + smoothstep(0.99, 1, da));
							edgeAlpha *= smoothstep(0, 0.01, da);
						}
						
						break;
					}
					case 3: // Spherical
					
					{
						if (_SphericalDissolveInvert)
						{
							da = remap(da, 1, 0, -_DissolveEdgeWidth, 1);
						}
						else
						{
							da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						}
						
						dissolveAlpha = da;
						dds *= smoothstep(0, 0.2 * dds + 0.01, dissolveAlpha) * lerp(1, smoothstep(1, 1 - 0.2 * dds - 0.01, dissolveAlpha), _DissolveDetailEdgeSmoothing);
						float currentDistance = lerp(0, _SphericalDissolveRadius, dissolveAlpha);
						float fragDistance = distance(_SphericalDissolveCenter, poiMesh.localPos.xyz);
						float normalizedDistance;
						normalizedDistance = (fragDistance - currentDistance) / (_SphericalDissolveRadius + 0.0001) - dissolveDetailNoise * dds;
						
						if (_SphericalDissolveInvert)
						{
							dissolveAlpha = (normalizedDistance > 0) ? 1 : 0;
							edgeAlpha = smoothstep(_DissolveEdgeWidth + .00001, 0, -normalizedDistance);
						}
						else
						{
							dissolveAlpha = (normalizedDistance < 0) ? 1 : 0;
							edgeAlpha = smoothstep(_DissolveEdgeWidth + .00001, 0, normalizedDistance);
						}
						
						if (_SphericalDissolveClamp)
						{
							da = lerp(da, 1 - da, _SphericalDissolveInvert);
							dissolveAlpha = saturate(dissolveAlpha * smoothstep(0, 0.01, da) + smoothstep(0.99, 1, da));
							edgeAlpha *= smoothstep(0, 0.01, da);
						}
						
						break;
					}
					case 4: // CenterOut
					
					{
						float ramp = 0.5;
						float noise;
						
						[flatten]
						switch(_CenterOutDissolveMode)
						{
							case 1: // View Direction
							
							{
								ramp = saturate(lerp(poiLight.vertexNDotV, poiLight.nDotV, _CenterOutDissolveNormals));
								break;
							}
							case 2: // Custom Direction
							
							{
								ramp = dot(normalize(_CenterOutDissolveDirection), lerp(poiMesh.normals[0], poiMesh.normals[1], _CenterOutDissolveNormals));
								ramp = saturate(ramp * .5 + 0.5);
								break;
							}
							case 3: // Light Direction
							
							{
								ramp = lerp(poiLight.vertexNDotL, poiLight.nDotL, _CenterOutDissolveNormals);
								ramp = saturate(ramp * .5 + 0.5);
								break;
							}
						}
						
						if (_CenterOutDissolvePower != 1)
						{
							ramp = pow(ramp, _CenterOutDissolvePower);
						}
						
						if (!_CenterOutDissolveInvert)
						{
							ramp = 1 - ramp;
						}
						
						da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						dissolveAlpha = da;
						//Adjust detail strength to avoid artifacts
						dds *= smoothstep(1, 0.99, da) * lerp(1, smoothstep(0, lerp(0.01, 0.1, dds), da), _DissolveDetailEdgeSmoothing);
						
						noise = saturate(ramp - dissolveDetailNoise * dds);
						noise = saturate(noise * 0.998 + 0.001);
						dissolveAlpha = dissolveAlpha >= noise;
						edgeAlpha = remapClamped(da + _DissolveEdgeWidth, da, noise) * (1 - dissolveAlpha);
						break;
					}
				}
				
				#ifndef POI_SHADOW
				UNITY_BRANCH
				if (_DissolveHueShiftEnabled)
				{
					dissolveToTexture.rgb = hueShift(dissolveToTexture.rgb, _DissolveHueShift + _Time.x * _DissolveHueShiftSpeed);
				}
				#endif
				
				poiFragData.alpha = lerp(poiFragData.alpha, dissolveToTexture.a, dissolveAlpha * .999999);
				
				#if !defined(POI_PASS_OUTLINE) && !defined(UNITY_PASS_SHADOWCASTER)
				poiFragData.baseColor = lerp(poiFragData.baseColor, dissolveToTexture.rgb, dissolveAlpha * .999999);
				
				if (_DissolveApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _DissolveApplyGlobalMaskIndex - 1, _DissolveApplyGlobalMaskBlendType, dissolveAlpha * .999999);
				}
				if (_DissolveInverseApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _DissolveInverseApplyGlobalMaskIndex - 1, _DissolveInverseApplyGlobalMaskBlendType, 1-(dissolveAlpha * .999999));
				}
				UNITY_BRANCH
				if (_DissolveEdgeWidth || (_DissolveType == 2 && _DissolveP2PEdgeLength != 0))
				{
					edgeColor = tex2D(_DissolveEdgeGradient, poiUV(float2(edgeAlpha, edgeAlpha), _DissolveEdgeGradient_ST)) * float4(poiThemeColor(poiMods, _DissolveEdgeColor.rgb, _DissolveEdgeColorThemeIndex), _DissolveEdgeColor.a);
					#ifndef POI_SHADOW
					UNITY_BRANCH
					if (_DissolveEdgeHueShiftEnabled)
					{
						edgeColor.rgb = hueShift(edgeColor.rgb, _DissolveEdgeHueShift + _Time.x * _DissolveEdgeHueShiftSpeed);
					}
					#endif
					poiFragData.baseColor = lerp(poiFragData.baseColor, edgeColor.rgb, smoothstep(0, 1 - _DissolveEdgeHardness * .99999999999, edgeAlpha));
				}
				
				poiFragData.emission += lerp(0, dissolveToTexture * _DissolveToEmissionStrength, dissolveAlpha) + lerp(0, edgeColor.rgb * _DissolveEdgeEmission, smoothstep(0, 1 - _DissolveEdgeHardness * .99999999999, edgeAlpha));
				#endif
			}
			#endif
			//endex
			
			//ifex _EnableAniso==0
			#ifdef POI_ANISOTROPICS
			/*
			float D_GGX_Anisotropic(float at, float ab, float TdotH, float BdotH, float NdotH)
			{
				// Burley 2012, "Physically-Based Shading at Disney"
				
				// The values at and ab are perceptualRoughness^2, a2 is therefore perceptualRoughness^4
				// The dot product below computes perceptualRoughness^8. We cannot fit in fp16 without clamping
				// the roughness to too high values so we perform the dot product and the division in fp32
				float a2 = at * ab;
				float3 d = float3(ab * TdotH, at * BdotH, a2 * NdotH);
				float d2 = dot(d, d);
				float b2 = a2 / d2;
				return a2 * b2 * b2 * (1.0 / UNITY_PI);
			}
			
			//-------------------------------------GGX Anisotropic visibility function
			float V_SmithGGXCorrelated_Anisotropic(float at, float ab, float TdotV, float BdotV, float TdotL, float BdotL, float NdotV, float NdotL)
			{
				// Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"
				float lambdaV = NdotL * length(float3(at * TdotV, ab * BdotV, NdotV));
				float lambdaL = NdotV * length(float3(at * TdotL, ab * BdotL, NdotL));
				return 0.5 / (lambdaV + lambdaL);
			}
			*/
			
			float calculateAnisotropics(float3 binormal, float offset, float3 normal, float3 viewDir, float3 LightDirection, float exponent, float strength, float shadowMask)
			{
				float3 ShiftedTangent = normalize(binormal + offset * normal);
				float3 H = normalize(LightDirection + viewDir);
				float dotTH = dot(ShiftedTangent, H);
				float sinTH = sqrt(1.0 - dotTH * dotTH);
				float dirAtten = smoothstep(-1.0, 0.0, dotTH);
				return saturate(dirAtten * pow(sinTH, exponent) * strength) * shadowMask;
			}
			
			float aaEdgeFeather(float value, float edge, float feather)
			{
				float edgeMin = saturate(edge - feather * 0.5);
				float edgeMax = saturate(edge + feather * 0.5);
				return saturate((value - edgeMin) / saturate(edgeMax - edgeMin + fwidth(value)));
			}
			
			void applyAnisotropics(inout PoiFragData poiFragData, inout PoiLight poiLight, in PoiCam poiCam, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				#if defined(PROP_ANISOCOLORMAP) || !defined(OPTIMIZER_ENABLED)
				float4 specMap = POI2D_SAMPLER_PAN(_AnisoColorMap, _MainTex, poiUV(poiMesh.uv[_AnisoColorMapUV], _AnisoColorMap_ST), _AnisoColorMapPan);
				#else
				float4 specMap = float4(1, 1, 1, 0);
				#endif
				
				float shadowMask = lerp(1, poiMax(poiLight.rampedLightMap), _AnisoHideInShadow);
				#ifdef POI_PASS_ADD
				shadowMask *= poiLight.additiveShadow;
				#endif
				
				if (_AnisoGlobalMask > 0)
				{
					shadowMask = customBlend(shadowMask, poiMods.globalMask[_AnisoGlobalMask-1], _AnisoGlobalMaskBlendType);
				}
				
				float spec0 = calculateAnisotropics(lerp(poiMesh.binormal[1], poiMesh.tangent[1], _Aniso0SwitchDirection), _Aniso0Offset +_Aniso0OffsetMapStrength * specMap.a, poiMesh.normals[1], poiCam.viewDir, poiLight.direction, _Aniso0Power * 1000, _Aniso0Strength, shadowMask);
				float spec1 = calculateAnisotropics(lerp(poiMesh.binormal[1], poiMesh.tangent[1], _Aniso1SwitchDirection), _Aniso1Offset +_Aniso1OffsetMapStrength * specMap.a, poiMesh.normals[1], poiCam.viewDir, poiLight.direction, _Aniso1Power * 1000, _Aniso1Strength, shadowMask);
				
				spec0 = lerp(spec0, aaEdgeFeather(spec0, _Aniso0Edge, _Aniso0Blur), _Aniso0ToonMode);
				spec1 = lerp(spec1, aaEdgeFeather(spec1, _Aniso1Edge, _Aniso1Blur), _Aniso1ToonMode);
				
				float3 spec0Color = specMap.rgb * poiThemeColor(poiMods, _Aniso0Tint.rgb, _Aniso0TintIndex);
				float3 spec1Color = specMap.rgb * poiThemeColor(poiMods, _Aniso1Tint.rgb, _Aniso1TintIndex);
				
				float3 finalSpec = saturate(saturate(spec0 * spec0Color) + saturate(spec1 * spec1Color)) * lerp(1, poiFragData.baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), poiLight.directColor, _AnisoUseLightColor);
				float3 baseColor = poiFragData.baseColor;
				
				poiFragData.baseColor = lerp(poiFragData.baseColor, spec1Color * lerp(1, baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), poiLight.directColor, _AnisoUseLightColor), _AnisoReplace * spec1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, spec0Color * lerp(1, baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), poiLight.directColor, _AnisoUseLightColor), _AnisoReplace * spec0);
				poiLight.finalLightAdd += max(0, finalSpec * _AnisoAdd);
				
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					for (int index = 0; index < 4; index++)
					{
						float vSpec0 = calculateAnisotropics(lerp(poiMesh.binormal[1], poiMesh.tangent[1], _Aniso0SwitchDirection), _Aniso0Offset +_Aniso0OffsetMapStrength * specMap.a, poiMesh.normals[1], poiCam.viewDir, poiLight.vDirection[index], _Aniso0Power * 1000, _Aniso0Strength, poiLight.vSaturatedDotNL[index]);
						float vSpec1 = calculateAnisotropics(lerp(poiMesh.binormal[1], poiMesh.tangent[1], _Aniso1SwitchDirection), _Aniso1Offset +_Aniso1OffsetMapStrength * specMap.a, poiMesh.normals[1], poiCam.viewDir, poiLight.vDirection[index], _Aniso1Power * 1000, _Aniso1Strength, poiLight.vSaturatedDotNL[index]);
						
						vSpec0 = lerp(vSpec0, aaEdgeFeather(vSpec0, _Aniso0Edge, _Aniso0Blur), _Aniso0ToonMode);
						vSpec1 = lerp(vSpec1, aaEdgeFeather(vSpec1, _Aniso1Edge, _Aniso1Blur), _Aniso1ToonMode);
						
						float3 vSpec0Color = spec0Color;
						float3 vSpec1Color = spec1Color;
						
						poiLight.finalLightAdd += max(0, saturate(saturate(vSpec0 * vSpec0Color) + saturate(vSpec1 * vSpec1Color)) * lerp(1, poiFragData.baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.vColor[index], float3(0.299, 0.587, 0.114)), poiLight.vColor[index], _AnisoUseLightColor) * _AnisoAdd);
						
						poiFragData.baseColor = lerp(poiFragData.baseColor, vSpec1Color * lerp(1, baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.vColor[index], float3(0.299, 0.587, 0.114)), poiLight.vColor[index], _AnisoUseLightColor), _AnisoReplace * vSpec1);
						poiFragData.baseColor = lerp(poiFragData.baseColor, vSpec0Color * lerp(1, baseColor, _AnisoUseBaseColor) * lerp(dot(poiLight.vColor[index], float3(0.299, 0.587, 0.114)), poiLight.vColor[index], _AnisoUseLightColor), _AnisoReplace * vSpec0);
					}
					#endif
				}
			}
			#endif
			//endex
			
			//ifex _MatcapEnable==0 && _Matcap2Enable==0 && _Matcap3Enable==0 && _Matcap4Enable==0
			void blendMatcap(inout PoiLight poiLight, inout PoiFragData poiFragData, in PoiMods poiMods, float add, float lightAdd, float multiply, float replace, float mixed, float screen, float4 matcapColor, float matcapMask, float emissionStrength, float matcapLightMask, uint globalMaskIndex, float globalMaskBlendType, in MatcapAudioLinkData matcapALD)
			{
				if (matcapLightMask)
				{
					matcapMask *= lerp(1, poiLight.rampedLightMap, matcapLightMask);
				}
				if (globalMaskIndex > 0)
				{
					matcapMask = maskBlend(matcapMask, poiMods.globalMask[globalMaskIndex - 1], globalMaskBlendType);
				}
				
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapColor.a = saturate(matcapColor.a + lerp(matcapALD.matcapALAlphaAdd.x, matcapALD.matcapALAlphaAdd.y, poiMods.audioLink[matcapALD.matcapALAlphaAddBand]));
					emissionStrength += lerp(matcapALD.matcapALEmissionAdd.x, matcapALD.matcapALEmissionAdd.y, poiMods.audioLink[matcapALD.matcapALEmissionAddBand]);
				}
				#endif
				
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, matcapColor.rgb, replace * matcapMask * matcapColor.a * .999999);
				poiFragData.baseColor.rgb *= lerp(1, matcapColor.rgb, multiply * matcapMask * matcapColor.a);
				poiFragData.baseColor.rgb += matcapColor.rgb * add * matcapMask * matcapColor.a;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, blendScreen(poiFragData.baseColor.rgb, matcapColor.rgb), screen * matcapMask * matcapColor.a);
				#ifdef POI_PASS_BASE
				poiLight.finalLightAdd += matcapColor.rgb * lightAdd * matcapMask * matcapColor.a;
				#endif
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, poiFragData.baseColor.rgb + poiFragData.baseColor.rgb * matcapColor.rgb, mixed * matcapMask * matcapColor.a);
				poiFragData.emission += matcapColor.rgb * emissionStrength * matcapMask * matcapColor.a;
			}
			
			void getMatcapUV(inout float2 matcapUV, in float2 matcapPan, in float matcapUVMode, in float matcapUVToBlend, in float2 matCapBlendUV, in float matcapRotation, in float matcapBorder, in float3 normal, in PoiCam poiCam, in PoiLight poiLight, in PoiMesh poiMesh, in float matcapNormalStrength, in MatcapAudioLinkData matcapALD)
			{
				switch(matcapUVMode)
				{
					// Normal / UTS
					case 0:
					{
						float3 viewNormal = (mul(UNITY_MATRIX_V, float4(normal, 0))).rgb;
						float3 NormalBlend_MatCapUV_Detail = viewNormal.rgb * float3(-1, -1, 1);
						float3 NormalBlend_MatCapUV_Base = (mul(UNITY_MATRIX_V, float4(poiCam.viewDir, 0)).rgb * float3(-1, -1, 1)) + float3(0, 0, 1);
						float3 noSknewViewNormal = NormalBlend_MatCapUV_Base * dot(NormalBlend_MatCapUV_Base, NormalBlend_MatCapUV_Detail) / NormalBlend_MatCapUV_Base.b - NormalBlend_MatCapUV_Detail;
						
						matcapUV = noSknewViewNormal.rg * matcapBorder + 0.5;
						break;
					}
					// Top Pinch
					case 1:
					{
						float3 worldViewUp = normalize(float3(0, 1, 0) - poiCam.viewDir * dot(poiCam.viewDir, float3(0, 1, 0)));
						float3 worldViewRight = normalize(cross(poiCam.viewDir, worldViewUp));
						matcapUV = float2(dot(worldViewRight, normal), dot(worldViewUp, normal)) * matcapBorder + 0.5;
						break;
					}
					// Custom Double Sided
					case 2:
					{
						float3 reflection = reflect(-poiCam.viewDir, normal);
						float2 uv = float2(dot(reflection, float3(1, 0, 0)), dot(reflection, float3(0, 1, 0)));
						matcapUV = uv * matcapBorder + 0.5;
						break;
					}
					// Gradient
					case 3:
					{
						matcapUV = 1 - abs(dot(normal, poiCam.viewDir));
						#ifdef POI_AUDIOLINK
						if (matcapALD.matcapALEnabled)
						{
							matcapUV += AudioLinkGetChronoTime(matcapALD.matcapALChronoPanType, matcapALD.matcapALChronoPanBand) * matcapALD.matcapALChronoPanSpeed;
						}
						#endif
						break;
					}
				}
				matcapUV = lerp(matcapUV, poiMesh.uv[matcapUVToBlend], matCapBlendUV);
				matcapUV += matcapPan * _Time.x;
				matcapUV = RotateUV(matcapUV, matcapRotation * PI, float2(.5, .5), 1.0f);
				
				if (IsInMirror() && matcapUVMode != 3)
				{
					matcapUV.x = 1 - matcapUV.x;
				}
			}
			
			//endex
			//ifex _MatcapEnable==0 && _Matcap2Enable==0 && _Matcap3Enable==0 && _Matcap4Enable==0
			#if defined(POI_MATCAP0) || defined(COLOR_GRADING_HDR_3D) || defined(POI_MATCAP2) || defined(POI_MATCAP3)
			void applyMatcap(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, inout PoiLight poiLight, in PoiMods poiMods)
			{
				float4 matcap = 0;
				float matcapMask = 0;
				float4 matcap2 = 0;
				float matcap2Mask = 0;
				float4 matcap3 = 0;
				float matcap3Mask = 0;
				float4 matcap4 = 0;
				float matcap4Mask = 0;
				float2 matcapUV = 0;
				float matcapIntensity;
				struct MatcapAudioLinkData matcapALD;
				//endex
				
				//ifex _MatcapEnable==0
				// Matcap 1
				#ifdef POI_MATCAP0
				matcapALD.matcapALEnabled = _Matcap0ALEnabled;
				matcapALD.matcapALAlphaAddBand = _Matcap0ALAlphaAddBand;
				matcapALD.matcapALAlphaAdd = _Matcap0ALAlphaAdd;
				matcapALD.matcapALEmissionAddBand = _Matcap0ALEmissionAddBand;
				matcapALD.matcapALEmissionAdd = _Matcap0ALEmissionAdd;
				matcapALD.matcapALIntensityAddBand = _Matcap0ALIntensityAddBand;
				matcapALD.matcapALIntensityAdd = _Matcap0ALIntensityAdd;
				matcapALD.matcapALChronoPanType = _Matcap0ALChronoPanType;
				matcapALD.matcapALChronoPanBand = _Matcap0ALChronoPanBand;
				matcapALD.matcapALChronoPanSpeed = _Matcap0ALChronoPanSpeed;
				
				float3 normal0 = lerp(poiMesh.normals[0], poiMesh.normals[1], _MatcapNormal);
				#ifdef POI_MATCAP0_CUSTOM_NORMAL
				#if defined(PROP_MATCAP0NORMALMAP) || !defined(OPTIMIZER_ENABLED)
				normal0 = calculateNormal(poiMesh.normals[_MatcapNormal], poiMesh, _Matcap0NormalMap, _Matcap0NormalMap_ST, _Matcap0NormalMapPan, _Matcap0NormalMapUV, _Matcap0NormalMapScale);
				#endif
				#endif
				
				#if defined(PROP_MATCAP) || !defined(OPTIMIZER_ENABLED)
				getMatcapUV(matcapUV, _MatcapPan.xy, _MatcapUVMode, _MatcapUVToBlend, _MatCapBlendUV1.xy, _MatcapRotation, _MatcapBorder, normal0, poiCam, poiLight, poiMesh, _MatcapNormal, matcapALD);
				if (_MatcapSmoothnessEnabled)
				{
					float mipCount0 = 9;
					if (_Matcap_TexelSize.z == 8192) mipCount0 = 13;
					if (_Matcap_TexelSize.z == 4096) mipCount0 = 12;
					if (_Matcap_TexelSize.z == 2048) mipCount0 = 11;
					if (_Matcap_TexelSize.z == 1024) mipCount0 = 10;
					if (_Matcap_TexelSize.z == 512) mipCount0 = 9;
					if (_Matcap_TexelSize.z == 256) mipCount0 = 8;
					if (_Matcap_TexelSize.z == 128) mipCount0 = 7;
					if (_Matcap_TexelSize.z == 64) mipCount0 = 6;
					if (_Matcap_TexelSize.z == 32) mipCount0 = 5;
					
					float matcapSmoothness = _MatcapSmoothness;
					
					if (_MatcapMaskSmoothnessApply)
					{
						#if defined(PROP_MATCAPMASK) || !defined(OPTIMIZER_ENABLED)
						matcapSmoothness *= POI2D_SAMPLER_PAN(_MatcapMask, _MainTex, poiUV(poiMesh.uv[_MatcapMaskUV], _MatcapMask_ST), _MatcapMaskPan)[_MatcapMaskSmoothnessChannel];
						#endif
					}
					matcapSmoothness = (1 - matcapSmoothness) * mipCount0;
					matcap = UNITY_SAMPLE_TEX2D_SAMPLER_LOD(_Matcap, _trilinear_repeat, TRANSFORM_TEX(matcapUV, _Matcap), matcapSmoothness) * float4(poiThemeColor(poiMods, _MatcapColor.rgb, _MatcapColorThemeIndex), _MatcapColor.a);
				}
				else
				{
					matcap = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap)) * float4(poiThemeColor(poiMods, _MatcapColor.rgb, _MatcapColorThemeIndex), _MatcapColor.a);
				}
				#else
				matcap = float4(poiThemeColor(poiMods, _MatcapColor.rgb, _MatcapColorThemeIndex), _MatcapColor.a);
				#endif
				
				matcapIntensity = _MatcapIntensity;
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapIntensity += lerp(matcapALD.matcapALIntensityAdd.x, matcapALD.matcapALIntensityAdd.y, poiMods.audioLink[matcapALD.matcapALIntensityAddBand]);
					matcapIntensity = max(0, matcapIntensity);
				}
				#endif
				matcap.rgb *= matcapIntensity;
				matcap.rgb = lerp(matcap.rgb, matcap.rgb * poiFragData.baseColor.rgb, _MatcapBaseColorMix);
				
				#if defined(PROP_MATCAPMASK) || !defined(OPTIMIZER_ENABLED)
				matcapMask = POI2D_SAMPLER_PAN(_MatcapMask, _MainTex, poiUV(poiMesh.uv[_MatcapMaskUV], _MatcapMask_ST), _MatcapMaskPan)[_MatcapMaskChannel];
				#else
				matcapMask = 1;
				#endif
				
				if (_MatcapMaskInvert)
				{
					matcapMask = 1 - matcapMask;
				}
				
				#ifdef TPS_Penetrator
				if (_MatcapTPSDepthEnabled)
				{
					matcapMask = lerp(0, matcapMask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _MatcapTPSMaskStrength);
				}
				#endif
				
				poiFragData.alpha *= lerp(1, matcap.a, matcapMask * _MatcapAlphaOverride);
				
				//UNITY_BRANCH
				if (_MatcapHueShiftEnabled)
				{
					matcap.rgb = hueShift(matcap.rgb, _MatcapHueShift + _Time.x * _MatcapHueShiftSpeed);
				}
				
				if (_MatcapApplyToAlphaEnabled)
				{
					float matcapAlphaApplyValue = dot(matcap.rgb, float3(0.299, 0.587, 0.114)); // Greyscale
					if (_MatcapApplyToAlphaSourceBlend == 1) // Max
					
					{
						matcapAlphaApplyValue = poiMax(matcap.rgb);
					}
					if (_MatcapApplyToAlphaBlendType == 0) // Add
					
					{
						poiFragData.alpha += lerp(0, matcapAlphaApplyValue, _MatcapApplyToAlphaBlending);
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
					if (_MatcapApplyToAlphaBlendType == 1) // Multiply
					
					{
						poiFragData.alpha *= lerp(1, matcapAlphaApplyValue, _MatcapApplyToAlphaBlending);
					}
				}
				
				blendMatcap(poiLight, poiFragData, poiMods, _MatcapAdd, _MatcapAddToLight, _MatcapMultiply, _MatcapReplace, _MatcapMixed, _MatcapScreen, matcap, matcapMask, _MatcapEmissionStrength, _MatcapLightMask, _MatcapMaskGlobalMask, _MatcapMaskGlobalMaskBlendType, matcapALD);
				#endif
				//endex
				//ifex _Matcap2Enable==0
				// Matcap 2
				#ifdef COLOR_GRADING_HDR_3D
				matcapALD.matcapALEnabled = _Matcap1ALEnabled;
				matcapALD.matcapALAlphaAddBand = _Matcap1ALAlphaAddBand;
				matcapALD.matcapALAlphaAdd = _Matcap1ALAlphaAdd;
				matcapALD.matcapALEmissionAddBand = _Matcap1ALEmissionAddBand;
				matcapALD.matcapALEmissionAdd = _Matcap1ALEmissionAdd;
				matcapALD.matcapALIntensityAddBand = _Matcap1ALIntensityAddBand;
				matcapALD.matcapALIntensityAdd = _Matcap1ALIntensityAdd;
				matcapALD.matcapALChronoPanType = _Matcap1ALChronoPanType;
				matcapALD.matcapALChronoPanBand = _Matcap1ALChronoPanBand;
				matcapALD.matcapALChronoPanSpeed = _Matcap1ALChronoPanSpeed;
				
				float3 normal1 = lerp(poiMesh.normals[0], poiMesh.normals[1], _Matcap2Normal);
				#ifdef POI_MATCAP1_CUSTOM_NORMAL
				#if defined(PROP_MATCAP1NORMALMAP) || !defined(OPTIMIZER_ENABLED)
				normal1 = calculateNormal(poiMesh.normals[_Matcap2Normal], poiMesh, _Matcap1NormalMap, _Matcap1NormalMap_ST, _Matcap1NormalMapPan, _Matcap1NormalMapUV, _Matcap1NormalMapScale);
				#endif
				#endif
				
				#if defined(PROP_MATCAP2) || !defined(OPTIMIZER_ENABLED)
				getMatcapUV(matcapUV, _Matcap2Pan.xy, _Matcap2UVMode, _Matcap2UVToBlend, _MatCap2ndBlendUV1.xy, _Matcap2Rotation, _Matcap2Border, normal1, poiCam, poiLight, poiMesh, _Matcap2Normal, matcapALD);
				if (_Matcap2SmoothnessEnabled)
				{
					float mipCount2 = 9;
					if (_Matcap2_TexelSize.z == 8192) mipCount2 = 13;
					if (_Matcap2_TexelSize.z == 4096) mipCount2 = 12;
					if (_Matcap2_TexelSize.z == 2048) mipCount2 = 11;
					if (_Matcap2_TexelSize.z == 1024) mipCount2 = 10;
					if (_Matcap2_TexelSize.z == 512) mipCount2 = 9;
					if (_Matcap2_TexelSize.z == 256) mipCount2 = 8;
					if (_Matcap2_TexelSize.z == 128) mipCount2 = 7;
					if (_Matcap2_TexelSize.z == 64) mipCount2 = 6;
					if (_Matcap2_TexelSize.z == 32) mipCount2 = 5;
					
					float matcap2Smoothness = _Matcap2Smoothness;
					
					if (_Matcap2MaskSmoothnessApply)
					{
						#if defined(PROP_MATCAP2MASK) || !defined(OPTIMIZER_ENABLED)
						matcap2Smoothness *= POI2D_SAMPLER_PAN(_Matcap2Mask, _MainTex, poiUV(poiMesh.uv[_Matcap2MaskUV], _Matcap2Mask_ST), _Matcap2MaskPan)[_Matcap2MaskSmoothnessChannel];
						#endif
					}
					matcap2Smoothness = (1 - matcap2Smoothness) * mipCount2;
					matcap2 = UNITY_SAMPLE_TEX2D_SAMPLER_LOD(_Matcap2, _trilinear_repeat, TRANSFORM_TEX(matcapUV, _Matcap2), matcap2Smoothness) * float4(poiThemeColor(poiMods, _Matcap2Color.rgb, _Matcap2ColorThemeIndex), _Matcap2Color.a);
				}
				else
				{
					matcap2 = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap2, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap2)) * float4(poiThemeColor(poiMods, _Matcap2Color.rgb, _Matcap2ColorThemeIndex), _Matcap2Color.a);
				}
				#else
				matcap2 = float4(poiThemeColor(poiMods, _Matcap2Color.rgb, _Matcap2ColorThemeIndex), _Matcap2Color.a);
				#endif
				
				matcapIntensity = _Matcap2Intensity;
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapIntensity += lerp(matcapALD.matcapALIntensityAdd.x, matcapALD.matcapALIntensityAdd.y, poiMods.audioLink[matcapALD.matcapALIntensityAddBand]);
					matcapIntensity = max(0, matcapIntensity);
				}
				#endif
				matcap2.rgb *= matcapIntensity;
				matcap2.rgb = lerp(matcap2.rgb, matcap2.rgb * poiFragData.baseColor.rgb, _Matcap2BaseColorMix);
				
				#if defined(PROP_MATCAP2MASK) || !defined(OPTIMIZER_ENABLED)
				matcap2Mask = POI2D_SAMPLER_PAN(_Matcap2Mask, _MainTex, poiUV(poiMesh.uv[_Matcap2MaskUV], _Matcap2Mask_ST), _Matcap2MaskPan)[_Matcap2MaskChannel];
				#else
				matcap2Mask = 1;
				#endif
				if (_Matcap2MaskInvert)
				{
					matcap2Mask = 1 - matcap2Mask;
				}
				
				#ifdef TPS_Penetrator
				if (_Matcap2TPSDepthEnabled)
				{
					matcap2Mask = lerp(0, matcap2Mask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Matcap2TPSMaskStrength);
				}
				#endif
				
				poiFragData.alpha *= lerp(1, matcap2.a, matcap2Mask * _Matcap2AlphaOverride);
				
				//UNITY_BRANCH
				if (_Matcap2HueShiftEnabled)
				{
					matcap2.rgb = hueShift(matcap2.rgb, _Matcap2HueShift + _Time.x * _Matcap2HueShiftSpeed);
				}
				
				if (_Matcap2ApplyToAlphaEnabled)
				{
					float matcap2AlphaApplyValue = dot(matcap2.rgb, float3(0.299, 0.587, 0.114)); // Greyscale
					if (_Matcap2ApplyToAlphaSourceBlend == 1) // Max
					
					{
						matcap2AlphaApplyValue = poiMax(matcap2.rgb);
					}
					if (_Matcap2ApplyToAlphaBlendType == 0) // Add
					
					{
						poiFragData.alpha += lerp(0, matcap2AlphaApplyValue, _Matcap2ApplyToAlphaBlending);
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
					if (_Matcap2ApplyToAlphaBlendType == 1) // Multiply
					
					{
						poiFragData.alpha *= lerp(1, matcap2AlphaApplyValue, _Matcap2ApplyToAlphaBlending);
					}
				}
				
				blendMatcap(poiLight, poiFragData, poiMods, _Matcap2Add, _Matcap2AddToLight, _Matcap2Multiply, _Matcap2Replace, _Matcap2Mixed, _Matcap2Screen, matcap2, matcap2Mask, _Matcap2EmissionStrength, _Matcap2LightMask, _Matcap2MaskGlobalMask, _Matcap2MaskGlobalMaskBlendType, matcapALD);
				#endif
				//endex
				//ifex _Matcap3Enable==0
				// Matcap 3
				#ifdef POI_MATCAP2
				
				matcapALD.matcapALEnabled = _Matcap2ALEnabled;
				matcapALD.matcapALAlphaAddBand = _Matcap2ALAlphaAddBand;
				matcapALD.matcapALAlphaAdd = _Matcap2ALAlphaAdd;
				matcapALD.matcapALEmissionAddBand = _Matcap2ALEmissionAddBand;
				matcapALD.matcapALEmissionAdd = _Matcap2ALEmissionAdd;
				matcapALD.matcapALIntensityAddBand = _Matcap2ALIntensityAddBand;
				matcapALD.matcapALIntensityAdd = _Matcap2ALIntensityAdd;
				matcapALD.matcapALChronoPanType = _Matcap2ALChronoPanType;
				matcapALD.matcapALChronoPanBand = _Matcap2ALChronoPanBand;
				matcapALD.matcapALChronoPanSpeed = _Matcap2ALChronoPanSpeed;
				
				float3 normal2 = lerp(poiMesh.normals[0], poiMesh.normals[1], _Matcap3Normal);
				#ifdef POI_MATCAP2_CUSTOM_NORMAL
				#if defined(PROP_MATCAP2NORMALMAP) || !defined(OPTIMIZER_ENABLED)
				normal2 = calculateNormal(poiMesh.normals[_Matcap3Normal], poiMesh, _Matcap2NormalMap, _Matcap2NormalMap_ST, _Matcap2NormalMapPan, _Matcap2NormalMapUV, _Matcap2NormalMapScale);
				#endif
				#endif
				
				#if defined(PROP_MATCAP3) || !defined(OPTIMIZER_ENABLED)
				getMatcapUV(matcapUV, _Matcap3Pan.xy, _Matcap3UVMode, _Matcap3UVToBlend, _MatCap3rdBlendUV1.xy, _Matcap3Rotation, _Matcap3Border, normal2, poiCam, poiLight, poiMesh, _Matcap3Normal, matcapALD);
				if (_Matcap3SmoothnessEnabled)
				{
					float mipCount3 = 9;
					if (_Matcap3_TexelSize.z == 8192) mipCount3 = 13;
					if (_Matcap3_TexelSize.z == 4096) mipCount3 = 12;
					if (_Matcap3_TexelSize.z == 2048) mipCount3 = 11;
					if (_Matcap3_TexelSize.z == 1024) mipCount3 = 10;
					if (_Matcap3_TexelSize.z == 512) mipCount3 = 9;
					if (_Matcap3_TexelSize.z == 256) mipCount3 = 8;
					if (_Matcap3_TexelSize.z == 128) mipCount3 = 7;
					if (_Matcap3_TexelSize.z == 64) mipCount3 = 6;
					if (_Matcap3_TexelSize.z == 32) mipCount3 = 5;
					
					float matcap3Smoothness = _Matcap3Smoothness;
					
					if (_Matcap3MaskSmoothnessApply)
					{
						#if defined(PROP_MATCAP3MASK) || !defined(OPTIMIZER_ENABLED)
						matcap3Smoothness *= POI2D_SAMPLER_PAN(_Matcap3Mask, _MainTex, poiUV(poiMesh.uv[_Matcap3MaskUV], _Matcap3Mask_ST), _Matcap3MaskPan)[_Matcap3MaskSmoothnessChannel];
						#endif
					}
					matcap3Smoothness = (1 - matcap3Smoothness) * mipCount3;
					matcap3 = UNITY_SAMPLE_TEX2D_SAMPLER_LOD(_Matcap3, _trilinear_repeat, TRANSFORM_TEX(matcapUV, _Matcap3), matcap3Smoothness) * float4(poiThemeColor(poiMods, _Matcap3Color.rgb, _Matcap3ColorThemeIndex), _Matcap3Color.a);
				}
				else
				{
					matcap3 = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap3, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap3)) * float4(poiThemeColor(poiMods, _Matcap3Color.rgb, _Matcap3ColorThemeIndex), _Matcap3Color.a);
				}
				#else
				matcap3 = float4(poiThemeColor(poiMods, _Matcap3Color.rgb, _Matcap3ColorThemeIndex), _Matcap3Color.a);
				#endif
				
				matcapIntensity = _Matcap3Intensity;
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapIntensity += lerp(matcapALD.matcapALIntensityAdd.x, matcapALD.matcapALIntensityAdd.y, poiMods.audioLink[matcapALD.matcapALIntensityAddBand]);
					matcapIntensity = max(0, matcapIntensity);
				}
				#endif
				matcap3.rgb *= matcapIntensity;
				matcap3.rgb = lerp(matcap3.rgb, matcap3.rgb * poiFragData.baseColor.rgb, _Matcap3BaseColorMix);
				
				#if defined(PROP_MATCAP3MASK) || !defined(OPTIMIZER_ENABLED)
				matcap3Mask = POI2D_SAMPLER_PAN(_Matcap3Mask, _MainTex, poiUV(poiMesh.uv[_Matcap3MaskUV], _Matcap3Mask_ST), _Matcap3MaskPan)[_Matcap3MaskChannel];
				#else
				matcap3Mask = 1;
				#endif
				if (_Matcap3MaskInvert)
				{
					matcap3Mask = 1 - matcap3Mask;
				}
				
				#ifdef TPS_Penetrator
				if (_Matcap3TPSDepthEnabled)
				{
					matcap3Mask = lerp(0, matcap3Mask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Matcap3TPSMaskStrength);
				}
				#endif
				
				poiFragData.alpha *= lerp(1, matcap3.a, matcap3Mask * _Matcap3AlphaOverride);
				
				//UNITY_BRANCH
				if (_Matcap3HueShiftEnabled)
				{
					matcap3.rgb = hueShift(matcap3.rgb, _Matcap3HueShift + _Time.x * _Matcap3HueShiftSpeed);
				}
				
				if (_Matcap3ApplyToAlphaEnabled)
				{
					float matcap3AlphaApplyValue = dot(matcap3.rgb, float3(0.299, 0.587, 0.114)); // Greyscale
					if (_Matcap3ApplyToAlphaSourceBlend == 1) // Max
					
					{
						matcap3AlphaApplyValue = poiMax(matcap3.rgb);
					}
					if (_Matcap3ApplyToAlphaBlendType == 0) // Add
					
					{
						poiFragData.alpha += lerp(0, matcap3AlphaApplyValue, _Matcap3ApplyToAlphaBlending);
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
					if (_Matcap3ApplyToAlphaBlendType == 1) // Multiply
					
					{
						poiFragData.alpha *= lerp(1, matcap3AlphaApplyValue, _Matcap3ApplyToAlphaBlending);
					}
				}
				
				blendMatcap(poiLight, poiFragData, poiMods, _Matcap3Add, _Matcap3AddToLight, _Matcap3Multiply, _Matcap3Replace, _Matcap3Mixed, _Matcap3Screen, matcap3, matcap3Mask, _Matcap3EmissionStrength, _Matcap3LightMask, _Matcap3MaskGlobalMask, _Matcap3MaskGlobalMaskBlendType, matcapALD);
				#endif
				//endex
				//ifex _Matcap4Enable==0
				// Matcap 4
				#ifdef POI_MATCAP3
				
				matcapALD.matcapALEnabled = _Matcap3ALEnabled;
				matcapALD.matcapALAlphaAddBand = _Matcap3ALAlphaAddBand;
				matcapALD.matcapALAlphaAdd = _Matcap3ALAlphaAdd;
				matcapALD.matcapALEmissionAddBand = _Matcap3ALEmissionAddBand;
				matcapALD.matcapALEmissionAdd = _Matcap3ALEmissionAdd;
				matcapALD.matcapALIntensityAddBand = _Matcap3ALIntensityAddBand;
				matcapALD.matcapALIntensityAdd = _Matcap3ALIntensityAdd;
				matcapALD.matcapALChronoPanType = _Matcap3ALChronoPanType;
				matcapALD.matcapALChronoPanBand = _Matcap3ALChronoPanBand;
				matcapALD.matcapALChronoPanSpeed = _Matcap3ALChronoPanSpeed;
				
				float3 normal3 = lerp(poiMesh.normals[0], poiMesh.normals[1], _Matcap4Normal);
				#ifdef POI_MATCAP3_CUSTOM_NORMAL
				#if defined(PROP_MATCAP3NORMALMAP) || !defined(OPTIMIZER_ENABLED)
				normal3 = calculateNormal(poiMesh.normals[_Matcap4Normal], poiMesh, _Matcap3NormalMap, _Matcap3NormalMap_ST, _Matcap3NormalMapPan, _Matcap3NormalMapUV, _Matcap3NormalMapScale);
				#endif
				#endif
				
				#if defined(PROP_MATCAP4) || !defined(OPTIMIZER_ENABLED)
				getMatcapUV(matcapUV, _Matcap4Pan.xy, _Matcap4UVMode, _Matcap4UVToBlend, _MatCap4thBlendUV1.xy, _Matcap4Rotation, _Matcap4Border, normal3, poiCam, poiLight, poiMesh, _Matcap4Normal, matcapALD);
				if (_Matcap4SmoothnessEnabled)
				{
					float mipCount4 = 9;
					if (_Matcap4_TexelSize.z == 8192) mipCount4 = 13;
					if (_Matcap4_TexelSize.z == 4096) mipCount4 = 12;
					if (_Matcap4_TexelSize.z == 2048) mipCount4 = 11;
					if (_Matcap4_TexelSize.z == 1024) mipCount4 = 10;
					if (_Matcap4_TexelSize.z == 512) mipCount4 = 9;
					if (_Matcap4_TexelSize.z == 256) mipCount4 = 8;
					if (_Matcap4_TexelSize.z == 128) mipCount4 = 7;
					if (_Matcap4_TexelSize.z == 64) mipCount4 = 6;
					if (_Matcap4_TexelSize.z == 32) mipCount4 = 5;
					
					float matcap4Smoothness = _Matcap4Smoothness;
					
					if (_Matcap4MaskSmoothnessApply)
					{
						#if defined(PROP_MATCAP4MASK) || !defined(OPTIMIZER_ENABLED)
						matcap4Smoothness *= POI2D_SAMPLER_PAN(_Matcap4Mask, _MainTex, poiUV(poiMesh.uv[_Matcap4MaskUV], _Matcap4Mask_ST), _Matcap4MaskPan)[_Matcap4MaskSmoothnessChannel];
						#endif
					}
					matcap4Smoothness = (1 - matcap4Smoothness) * mipCount4;
					matcap4 = UNITY_SAMPLE_TEX2D_SAMPLER_LOD(_Matcap4, _trilinear_repeat, TRANSFORM_TEX(matcapUV, _Matcap4), matcap4Smoothness) * float4(poiThemeColor(poiMods, _Matcap4Color.rgb, _Matcap4ColorThemeIndex), _Matcap4Color.a);
				}
				else
				{
					matcap4 = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap4, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap4)) * float4(poiThemeColor(poiMods, _Matcap4Color.rgb, _Matcap4ColorThemeIndex), _Matcap4Color.a);
				}
				#else
				matcap4 = float4(poiThemeColor(poiMods, _Matcap4Color.rgb, _Matcap4ColorThemeIndex), _Matcap4Color.a);
				#endif
				
				matcapIntensity = _Matcap4Intensity;
				#ifdef POI_AUDIOLINK
				if (matcapALD.matcapALEnabled > 0)
				{
					matcapIntensity += lerp(matcapALD.matcapALIntensityAdd.x, matcapALD.matcapALIntensityAdd.y, poiMods.audioLink[matcapALD.matcapALIntensityAddBand]);
					matcapIntensity = max(0, matcapIntensity);
				}
				#endif
				matcap4.rgb *= matcapIntensity;
				matcap4.rgb = lerp(matcap4.rgb, matcap4.rgb * poiFragData.baseColor.rgb, _Matcap4BaseColorMix);
				
				#if defined(PROP_MATCAP4MASK) || !defined(OPTIMIZER_ENABLED)
				matcap4Mask = POI2D_SAMPLER_PAN(_Matcap4Mask, _MainTex, poiUV(poiMesh.uv[_Matcap4MaskUV], _Matcap4Mask_ST), _Matcap4MaskPan)[_Matcap4MaskChannel];
				#else
				matcap4Mask = 1;
				#endif
				if (_Matcap4MaskInvert)
				{
					matcap4Mask = 1 - matcap4Mask;
				}
				
				#ifdef TPS_Penetrator
				if (_Matcap4TPSDepthEnabled)
				{
					matcap4Mask = lerp(0, matcap4Mask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _Matcap4TPSMaskStrength);
				}
				#endif
				
				poiFragData.alpha *= lerp(1, matcap4.a, matcap4Mask * _Matcap4AlphaOverride);
				
				//UNITY_BRANCH
				if (_Matcap4HueShiftEnabled)
				{
					matcap4.rgb = hueShift(matcap4.rgb, _Matcap4HueShift + _Time.x * _Matcap4HueShiftSpeed);
				}
				
				if (_Matcap4ApplyToAlphaEnabled)
				{
					float matcap4AlphaApplyValue = dot(matcap4.rgb, float3(0.299, 0.587, 0.114)); // Greyscale
					if (_Matcap4ApplyToAlphaSourceBlend == 1) // Max
					
					{
						matcap4AlphaApplyValue = poiMax(matcap4.rgb);
					}
					if (_Matcap4ApplyToAlphaBlendType == 0) // Add
					
					{
						poiFragData.alpha += lerp(0, matcap4AlphaApplyValue, _Matcap4ApplyToAlphaBlending);
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
					if (_Matcap4ApplyToAlphaBlendType == 1) // Multiply
					
					{
						poiFragData.alpha *= lerp(1, matcap4AlphaApplyValue, _Matcap4ApplyToAlphaBlending);
					}
				}
				
				blendMatcap(poiLight, poiFragData, poiMods, _Matcap4Add, _Matcap4AddToLight, _Matcap4Multiply, _Matcap4Replace, _Matcap4Mixed, _Matcap4Screen, matcap4, matcap4Mask, _Matcap4EmissionStrength, _Matcap4LightMask, _Matcap4MaskGlobalMask, _Matcap4MaskGlobalMaskBlendType, matcapALD);
				#endif
				//endex
				//ifex _MatcapEnable==0 && _Matcap2Enable==0 && _Matcap3Enable==0 && _Matcap4Enable==0
				
			}
			#endif
			//endex
			
			//ifex _CubeMapEnabled==0
			#ifdef _CUBEMAP
			#if defined(PROP_CUBEMAP) || !defined(OPTIMIZER_ENABLED)
			// From Unity's MIT'd Skybox-Cubed.shader
			float3 RotateAroundYInDegrees(float3 dir, float degrees)
			{
				float alpha = degrees * UNITY_PI / 180.0;
				float sina, cosa;
				sincos(alpha, sina, cosa);
				float2x2 m = float2x2(cosa, -sina, sina, cosa);
				return float3(mul(m, dir.xz), dir.y).xzy;
			}
			#endif
			void applyCubemap(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, in PoiLight poiLight, in PoiMods poiMods)
			{
				float3 CubeMapUV = 0;
				
				switch(_CubeMapUVMode)
				{
					case 0: // Skybox
					CubeMapUV = -poiCam.viewDir;
					break;
					case 1: // Reflection
					CubeMapUV = poiCam.reflectionDir;
					break;
					case 2: // World Normal Direction
					CubeMapUV = lerp(poiMesh.normals[0], poiMesh.normals[1], _CubeMapWorldNormalsStrength);
					break;
					case 3: // Local Normal Direction
					CubeMapUV = poiMesh.objNormal;
					break;
				}
				
				#if defined(PROP_CUBEMAP) || !defined(OPTIMIZER_ENABLED)
				if (any(_CubeMapRotation.xyz) || any(_CubeMapRotationPan.xyz))
				{
					// Do funny swizzle so we don't have to make a new function for every direction
					CubeMapUV = RotateAroundYInDegrees(CubeMapUV.yxz, _CubeMapRotation.x + (_CubeMapRotationPan.x * _Time.y)).yxz;
					CubeMapUV = RotateAroundYInDegrees(CubeMapUV.xyz, _CubeMapRotation.y + (_CubeMapRotationPan.y * _Time.y)).xyz;
					CubeMapUV = RotateAroundYInDegrees(CubeMapUV.xzy, _CubeMapRotation.z + (_CubeMapRotationPan.z * _Time.y)).xzy;
				}
				float4 cubeMap = texCUBElod(_CubeMap, float4(CubeMapUV, (1 - _CubeMapSmoothness) * (1 - _CubeMapSmoothness) * 8));
				
				cubeMap.rgb *= poiThemeColor(poiMods, _CubeMapColor, _CubeMapColorThemeIndex);
				#else
				float4 cubeMap = float4(0.21763764082, 0.21763764082, 0.21763764082, .5) * float4(poiThemeColor(poiMods, _CubeMapColor, _CubeMapColorThemeIndex), 1);
				#endif
				
				cubeMap.rgb *= _CubeMapIntensity;
				#if defined(PROP_CUBEMAPMASK) || !defined(OPTIMIZER_ENABLED)
				float CubeMapMask = POI2D_SAMPLER_PAN(_CubeMapMask, _MainTex, poiUV(poiMesh.uv[_CubeMapMaskUV], _CubeMapMask_ST), _CubeMapMaskPan)[_CubeMapMaskChannel];
				#else
				float CubeMapMask = 1;
				#endif
				
				if (_CubeMapMaskGlobalMask > 0)
				{
					CubeMapMask = maskBlend(CubeMapMask, poiMods.globalMask[_CubeMapMaskGlobalMask - 1], _CubeMapMaskGlobalMaskBlendType);
				}
				
				if (_CubeMapMaskInvert)
				{
					CubeMapMask = 1 - CubeMapMask;
				}
				
				//UNITY_BRANCH
				if (_CubeMapHueShiftEnabled)
				{
					cubeMap.rgb = hueShift(cubeMap.rgb, _CubeMapHueShift + _Time.x * _CubeMapHueShiftSpeed);
					cubeMap = PoiColorBCS(cubeMap, _CubeMapBrightness, _CubeMapContrast, _CubeMapSaturation);
					//cubeMap.rgb = ModifyViaHSV(cubeMap.rgb, _CubeMapHueShift + _Time.x * _CubeMapHueShiftSpeed, _CubeMapSaturation, _CubeMapValue);
					
				}
				CubeMapMask = min(CubeMapMask, lerp(1, poiLight.rampedLightMap, _CubeMapLightMask));
				float cubeMapAlpha = CubeMapMask * cubeMap.a * _CubeMapBlendAmount;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, cubeMap.rgb, cubeMapAlpha * (_CubemapBlendType == 0));
				poiFragData.baseColor.rgb *= lerp(1, cubeMap.rgb, cubeMapAlpha * (_CubemapBlendType == 1));
				poiFragData.baseColor.rgb += cubeMap.rgb * cubeMapAlpha * (_CubemapBlendType == 2);
				poiFragData.emission += cubeMap.rgb * _CubeMapEmissionStrength * CubeMapMask * cubeMap.a;
			}
			#endif
			//endex
			
			//ifex _EnableALDecal==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_DECAL
			void ApplyAudioLinkDecal(in PoiMesh poiMesh, inout PoiFragData poiFragData, in PoiMods poiMods)
			{
				float4 colorAndMask = float4(1, 1, 1, 1);
				#if defined(PROP_ALDECALCOLORMASK) || !defined(OPTIMIZER_ENABLED)
				colorAndMask = POI2D_SAMPLER_PAN(_ALDecalColorMask, _MainTex, poiUV(poiMesh.uv[_ALDecalColorMaskUV], _ALDecalColorMask_ST), _ALDecalColorMaskPan);
				#endif
				if (_ALDecalGlobalMask > 0)
				{
					colorAndMask.a = customBlend(colorAndMask.a, poiMods.globalMask[_ALDecalGlobalMask-1], _ALDecalGlobalMaskBlendType);
				}
				
				float2 uv = poiMesh.uv[_ALDecalUV];
				float2 decalCenter = _ALUVPosition;
				float theta = radians(_ALUVRotation + _Time.z * _ALUVRotationSpeed);
				float cs = cos(theta);
				float sn = sin(theta);
				uv = float2((uv.x - decalCenter.x) * cs - (uv.y - decalCenter.y) * sn + decalCenter.x, (uv.x - decalCenter.x) * sn + (uv.y - decalCenter.y) * cs + decalCenter.y);
				uv = remap(uv, float2(0, 0) - _ALUVScale.xz / 2 + _ALUVPosition, _ALUVScale.yw / 2 + _ALUVPosition, float2(0, 0), float2(1, 1));
				
				// Mask
				float4 audioLinkMask = 1.0;
				
				// UV
				float2 aluv = uv;
				if (_ALDecalUVMode == 1)
				{
					float2 uvdir = uv * 2 - 1;
					aluv.x = frac(atan2(uvdir.y, uvdir.x) * UNITY_INV_TWO_PI);
					aluv.y = length(uvdir);
				}
				
				// Scale / Offset / Step
				float maskY = aluv.y;
				if (_ALDecalUVMode == 1)
				{
					maskY = remap(maskY, _ALDecaldCircleDimensions.x, _ALDecaldCircleDimensions.y, 0, 1);
				}
				float maskX = aluv.x;
				if (_ALDecalUVMode == 1)
				{
					maskX = remap(maskX, _ALDecaldCircleDimensions.z, _ALDecaldCircleDimensions.w, 0, 1);
				}
				
				float maskVolume = _ALDecalVolumeStep != 0.0 ? floor(maskY * _ALDecalVolumeStep) / _ALDecalVolumeStep : maskY;
				float maskBand = _ALDecalBandStep != 0.0 ? floor(maskX * _ALDecalBandStep) / _ALDecalBandStep : maskX;
				
				// Copy
				audioLinkMask.r = maskVolume;
				audioLinkMask.g = maskBand;
				
				// Clip
				audioLinkMask.b = maskVolume < _ALDecalVolumeClipMin || maskVolume > _ALDecalVolumeClipMax ? 0.0 : audioLinkMask.b;
				audioLinkMask.b = maskBand < _ALDecalBandClipMin || maskBand > _ALDecalBandClipMax ? 0.0 : audioLinkMask.b;
				
				// Shape Clip
				if (_ALDecalShapeClip)
				{
					float volumeth = _ALDecalShapeClipVolumeWidth;
					if (_ALDecalVolumeStep != 0.0) audioLinkMask.b = frac(maskY * _ALDecalVolumeStep) > volumeth ? 0.0 : audioLinkMask.b;
					
					float bandwidth = _ALDecalUVMode == 1 ? _ALDecalShapeClipBandWidth / aluv.y : _ALDecalShapeClipBandWidth;
					float bandth = 1.0 - bandwidth;
					if (_ALDecalBandStep != 0.0) audioLinkMask.b = frac(maskX * _ALDecalBandStep + bandth * 0.5) < bandth ? 0.0 : audioLinkMask.b;
				}
				
				// AudioLink
				float2 audioLinkUV = float2(frac(audioLinkMask.g * 2.0), 4.5 / 4.0 + floor(audioLinkMask.g * 2.0) / 4.0);
				audioLinkUV.y *= 0.0625;
				float4 audioTexture = _AudioTexture.Sample(sampler_linear_clamp, audioLinkUV);
				float audioVal = audioTexture.b * _ALDecalVolume * lerp(_ALDecalBaseBoost, _ALDecalTrebleBoost, audioLinkMask.g);
				float audioLinkValue = _ALDecalLineWidth < 1.0 ? abs(audioVal - audioLinkMask.r) < _ALDecalLineWidth : audioVal > audioLinkMask.r * 2.0;
				audioLinkValue = saturate(audioLinkValue) * audioLinkMask.b;
				//clip(audioLinkValue - .5);
				audioLinkValue *= colorAndMask.a;
				
				if (!poiMods.audioLinkAvailable)
				{
					audioLinkValue = 0;
				}
				
				float3 alColorChord = _AudioTexture.Sample(sampler_linear_clamp, float2(maskX, 24.5 / 64.0)).rgb;
				float volumeColorSrc = audioLinkMask.g;
				if (_ALDecalVolumeColorSource == 1) volumeColorSrc = audioLinkMask.r;
				if (_ALDecalVolumeColorSource == 2) volumeColorSrc = audioVal;
				
				float3 lowColor = _ALDecalVolumeColorLow.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorLow.rgb, _ALDecalVolumeColorLowThemeIndex);
				float3 midColor = _ALDecalVolumeColorMid.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorMid.rgb, _ALDecalVolumeColorMidThemeIndex);
				float3 highColor = _ALDecalVolumeColorHigh.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorHigh.rgb, _ALDecalVolumeColorHighThemeIndex);
				
				float3 volumeColor = lerp(lowColor, midColor, saturate(volumeColorSrc * 2));
				volumeColor = lerp(volumeColor, highColor, saturate(volumeColorSrc * 2 - 1));
				
				float3 emissionColor = lerp(lowColor * _ALDecalLowEmission, midColor * _ALDecalMidEmission, saturate(volumeColorSrc * 2));
				emissionColor = lerp(emissionColor, highColor * _ALDecalHighEmission, saturate(volumeColorSrc * 2 - 1));
				
				//poiFragData.baseColor = lerp(poiFragData.baseColor, volumeColor, audioLinkValue);
				#if defined(POI_PASS_BASE) || defined(POI_PASS_ADD)
				poiFragData.emission += emissionColor * audioLinkValue;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor, customBlend(poiFragData.baseColor, volumeColor * colorAndMask.rgb, _ALDecalBlendType), saturate(_ALDecalBlendAlpha * audioLinkValue));
				#endif
				poiFragData.alpha = lerp(poiFragData.alpha, poiFragData.alpha * audioLinkValue, _ALDecalControlsAlpha);
			}
			#endif
			#endif
			//endex
			
			//ifex _EnableVolumeColor==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_VOLUMECOLOR
			void ApplyAudioLinkVolumeColor(in PoiMesh poiMesh, inout PoiFragData poiFragData, in PoiMods poiMods)
			{
				float volume = AudioLinkLerpMultiline(ALPASS_DFT + float2(poiMesh.uv[_ALVolumeColorUV][_ALVolumeColorDirection] * AUDIOLINK_ETOTALBINS, 0.0)).b;
				
				float3 lowColor = _ALVolumeColorLow.rgb * poiThemeColor(poiMods, _ALVolumeColorLow.rgb, _ALVolumeColorLowThemeIndex);
				float3 midColor = _ALVolumeColorMid.rgb * poiThemeColor(poiMods, _ALVolumeColorMid.rgb, _ALVolumeColorMidThemeIndex);
				float3 highColor = _ALVolumeColorHigh.rgb * poiThemeColor(poiMods, _ALVolumeColorHigh.rgb, _ALVolumeColorHighThemeIndex);
				
				float3 volumeColor = lerp(lowColor, midColor, saturate(volume * 2));
				volumeColor = lerp(volumeColor, highColor, saturate(volume * 2 - 1));
				
				float3 emissionColor = lerp(lowColor * _ALLowEmission, midColor * _ALMidEmission, saturate(volume * 2));
				emissionColor = lerp(emissionColor, highColor * _ALHighEmission, saturate(volume * 2 - 1));
				
				#if defined(POI_PASS_BASE) || defined(POI_PASS_ADD)
				poiFragData.emission += emissionColor * poiMods.audioLinkAvailable;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor, customBlend(poiFragData.baseColor, volumeColor, _ALVolumeColorBlendType), saturate(_ALVolumeColorBlendAlpha * poiMods.audioLinkAvailable));
				#endif
			}
			#endif
			#endif
			//endex
			
			//ifex _EnableFlipbook==0
			#ifdef _SUNDISK_HIGH_QUALITY
			
			void applyFlipbook(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				#if defined(PROP_FLIPBOOKTEXARRAY) || !defined(OPTIMIZER_ENABLED)
				float4 flipBookPixel = float4(0, 0, 0, 0);
				#if defined(PROP_FLIPBOOKMASK) || !defined(OPTIMIZER_ENABLED)
				float flipBookMask = POI2D_SAMPLER_PAN(_FlipbookMask, _MainTex, poiUV(poiMesh.uv[_FlipbookMaskUV], _FlipbookMask_ST), _FlipbookMaskPan)[_FlipbookMaskChannel];
				#else
				float flipBookMask = 1;
				#endif
				if (_FlipbookMaskGlobalMask > 0)
				{
					flipBookMask = maskBlend(flipBookMask, poiMods.globalMask[_FlipbookMaskGlobalMask-1], _FlipbookMaskGlobalMaskBlendType);
				}
				float4 flipbookScaleOffset = _FlipbookScaleOffset;
				
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookScaleOffset.xy += lerp(_AudioLinkFlipbookScale.xy, _AudioLinkFlipbookScale.zw, poiMods.audioLink[_AudioLinkFlipbookScaleBand]);
				}
				#endif
				
				flipbookScaleOffset.xy = 1 - flipbookScaleOffset.xy;
				float2 uv = frac(poiMesh.uv[_FlipbookTexArrayUV]);
				float theta = radians(_FlipbookRotation + _Time.z * _FlipbookRotationSpeed);
				float cs = cos(theta);
				float sn = sin(theta);
				float2 spriteCenter = flipbookScaleOffset.zw + .5;
				// 2d rotation
				uv = float2((uv.x - spriteCenter.x) * cs - (uv.y - spriteCenter.y) * sn + spriteCenter.x, (uv.x - spriteCenter.x) * sn + (uv.y - spriteCenter.y) * cs + spriteCenter.y);
				float4 sideOffset = float4(-(_FlipbookSideOffset.x), _FlipbookSideOffset.y, -(_FlipbookSideOffset.z), _FlipbookSideOffset.w);
				float2 newUV = remap(uv, float2(0, 0) + flipbookScaleOffset.xy / 2 + flipbookScaleOffset.zw + sideOffset.xz, float2(1, 1) - flipbookScaleOffset.xy / 2 + flipbookScaleOffset.zw + sideOffset.yw, float2(0, 0), float2(1, 1));
				
				UNITY_BRANCH
				if (_FlipbookTiled == 0)
				{
					if (max(newUV.x, newUV.y) > 1 || min(newUV.x, newUV.y) < 0)
					{
						return;
					}
				}
				float currentFrame = 0;
				float width;
				float height;
				float totalFrames;
				_FlipbookTexArray.GetDimensions(width, height, totalFrames);
				
				if (_FlipbookStartAndEnd)
				{
					totalFrames -= (totalFrames - min(max(_FlipbookStartFrame, _FlipbookEndFrame), totalFrames));
					totalFrames -= max(0, _FlipbookStartFrame);
				}
				if (!_FlipbookManualFrameControl)
				{
					if (_FlipbookFPS != 0)
					{
						currentFrame = ((_Time.y / (1 / _FlipbookFPS)) + _FlipbookFrameOffset) % totalFrames;
						if (_FlipbookStartAndEnd)
						{
							currentFrame += _FlipbookStartFrame;
						}
					}
				}
				else
				{
					currentFrame = fmod(_FlipbookCurrentFrame, totalFrames);
				}
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					if (_FlipbookChronotensityEnabled)
					{
						currentFrame += AudioLinkGetChronoTime(_FlipbookChronoType, _FlipbookChronotensityBand) * _FlipbookChronotensitySpeed;
					}
					currentFrame += lerp(_AudioLinkFlipbookFrame.x, _AudioLinkFlipbookFrame.y, poiMods.audioLink[_AudioLinkFlipbookFrameBand]);
					float totalFramesAL = totalFrames;
					if (_FlipbookStartAndEnd)
					{
						totalFramesAL += max(0, _FlipbookStartFrame);
					}
					currentFrame %= totalFramesAL;
				}
				#endif
				flipBookPixel = UNITY_SAMPLE_TEX2DARRAY(_FlipbookTexArray, float3(TRANSFORM_TEX(newUV, _FlipbookTexArray) + _Time.x * _FlipbookTexArrayPan, floor(currentFrame)));
				UNITY_BRANCH
				if (_FlipbookCrossfadeEnabled)
				{
					float totalFramesCF = totalFrames;
					if (_FlipbookStartAndEnd)
					{
						totalFramesCF += max(0, _FlipbookStartFrame);
					}
					float4 flipbookNextPixel = UNITY_SAMPLE_TEX2DARRAY(_FlipbookTexArray, float3(TRANSFORM_TEX(newUV, _FlipbookTexArray) + _Time.x * _FlipbookTexArrayPan, floor((currentFrame + 1) % totalFramesCF)));
					flipBookPixel = lerp(flipBookPixel, flipbookNextPixel, smoothstep(_FlipbookCrossfadeRange.x, _FlipbookCrossfadeRange.y, frac(currentFrame)));
				}
				
				UNITY_BRANCH
				if (_FlipbookIntensityControlsAlpha)
				{
					flipBookPixel.a = poiMax(flipBookPixel.rgb);
				}
				UNITY_BRANCH
				if (_FlipbookColorReplaces)
				{
					flipBookPixel.rgb = poiThemeColor(poiMods, _FlipbookColor.rgb, _FlipbookColorThemeIndex);
				}
				else
				{
					flipBookPixel.rgb *= poiThemeColor(poiMods, _FlipbookColor.rgb, _FlipbookColorThemeIndex);
				}
				
				UNITY_BRANCH
				if (_FlipbookHueShiftEnabled)
				{
					flipBookPixel.rgb = hueShift(flipBookPixel.rgb, _FlipbookHueShift + _Time.x * _FlipbookHueShiftSpeed);
				}
				half flipbookAlpha = 1;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookAlpha += saturate(lerp(_AudioLinkFlipbookAlpha.x, _AudioLinkFlipbookAlpha.y, poiMods.audioLink[_AudioLinkFlipbookAlphaBand]));
				}
				#endif
				
				#if !defined(POI_PASS_OUTLINE) && !defined(UNITY_PASS_SHADOWCASTER)
				
				poiFragData.baseColor = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, flipBookPixel.rgb, _FlipbookBlendType), flipBookPixel.a * _FlipbookColor.a * _FlipbookReplace * flipBookMask * flipbookAlpha);
				
				float flipbookEmissionStrength = _FlipbookEmissionStrength;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookEmissionStrength += max(lerp(_AudioLinkFlipbookEmission.x, _AudioLinkFlipbookEmission.y, poiMods.audioLink[_AudioLinkFlipbookEmissionBand]), 0);
				}
				#endif
				
				poiFragData.emission += lerp(0, flipBookPixel.rgb * flipbookEmissionStrength, flipBookPixel.a * _FlipbookColor.a * flipBookMask * flipbookAlpha);
				
				#endif
				
				UNITY_BRANCH
				if (_FlipbookAlphaControlsFinalAlpha)
				{
					poiFragData.alpha = lerp(poiFragData.alpha, flipBookPixel.a * _FlipbookColor.a, flipBookMask);
				}
				#endif
			}
			
			#endif
			//endex
			
			//ifex _EnableRimLighting==0 && _EnableRim2Lighting==0
			#if defined(_GLOSSYREFLECTIONS_OFF) || defined(POI_RIM2)
			#if defined(_RIMSTYLE_POIYOMI) || defined(_RIM2STYLE_POIYOMI)
			void ApplyPoiyomiRimLighting(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight, inout PoiMods poiMods, float Is_NormalMapToRimLight, float RimInvert, float RimPower, float RimStrength, float RimShadowWidth, float RimShadowToggle, float RimWidth, float RimBlendStrength, float RimMask, float RimGlobalMask, float RimGlobalMaskBlendType, float4 RimTex, float4 RimLightColor, float RimLightColorThemeIndex, float RimHueShiftEnabled, float RimHueShift, float RimHueShiftSpeed, float RimSharpness, float RimShadowMaskRampType, float RimShadowMaskInvert, float RimShadowMaskStrength, float2 RimShadowAlpha, float RimApplyGlobalMaskIndex, float RimApplyGlobalMaskBlendType, float RimBaseColorMix, float RimBrightness, float RimBlendMode, half AudioLinkRimWidthBand, float2 AudioLinkRimWidthAdd, half AudioLinkRimEmissionBand, float2 AudioLinkRimEmissionAdd, half AudioLinkRimBrightnessBand, float2 AudioLinkRimBrightnessAdd, float rimBias, float rimBiasIntensity, int RimApplyAlpha, float RimApplyAlphaBlend)
			{
				float viewDotNormal = abs(dot(poiCam.viewDir, lerp(poiMesh.normals[0], poiMesh.normals[1], Is_NormalMapToRimLight)));
				
				UNITY_BRANCH
				if (RimInvert)
				{
					viewDotNormal = 1 - viewDotNormal;
				}
				
				viewDotNormal = pow(viewDotNormal, RimPower);
				
				if (RimShadowWidth && RimShadowToggle)
				{
					viewDotNormal += lerp(0, (1 - poiLight.nDotLNormalized) * 3, RimShadowWidth);
				}
				
				viewDotNormal *= lerp(1, rimBias, rimBiasIntensity);
				
				float rimStrength = RimStrength;
				
				float rimWidth = lerp( - .05, 1, RimWidth);
				
				float blendStrength = RimBlendStrength;
				#ifdef POI_AUDIOLINK
				UNITY_BRANCH
				if (poiMods.audioLinkAvailable)
				{
					rimWidth = clamp(rimWidth + lerp(AudioLinkRimWidthAdd.x, AudioLinkRimWidthAdd.y, poiMods.audioLink[AudioLinkRimWidthBand]), - .05, 1);
					rimStrength += lerp(AudioLinkRimEmissionAdd.x, AudioLinkRimEmissionAdd.y, poiMods.audioLink[AudioLinkRimEmissionBand]);
					RimBrightness += lerp(AudioLinkRimBrightnessAdd.x, AudioLinkRimBrightnessAdd.y, poiMods.audioLink[AudioLinkRimBrightnessBand]);
				}
				#endif
				float rimMask = RimMask;
				
				if (RimGlobalMask > 0)
				{
					rimMask = maskBlend(rimMask, poiMods.globalMask[RimGlobalMask - 1], RimGlobalMaskBlendType);
				}
				
				float4 rimColor = RimTex;
				rimColor *= float4(poiThemeColor(poiMods, RimLightColor.rgb, RimLightColorThemeIndex), RimLightColor.a);
				
				UNITY_BRANCH
				if (RimHueShiftEnabled)
				{
					rimColor.rgb = hueShift(rimColor.rgb, RimHueShift + _Time.x * RimHueShiftSpeed);
				}
				
				float rim = 1 - smoothstep(min(RimSharpness, rimWidth), rimWidth, viewDotNormal);
				rim *= RimLightColor.a * rimColor.a * rimMask;
				
				if (RimShadowToggle)
				{
					switch(RimShadowMaskRampType)
					{
						case 0:
						float rampedLightMap = poiLight.rampedLightMap;
						if (RimShadowMaskInvert) rampedLightMap = 1 - rampedLightMap;
						rim = lerp(rim, rim * rampedLightMap, RimShadowMaskStrength);
						break;
						case 1:
						float nDotLNormalized = poiLight.nDotLNormalized;
						if (RimShadowMaskInvert) nDotLNormalized = 1 - nDotLNormalized;
						rim = lerp(rim, rim * smoothstep(RimShadowAlpha.x, RimShadowAlpha.y, nDotLNormalized), RimShadowMaskStrength);
						break;
					}
				}
				
				if (RimApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, RimApplyGlobalMaskIndex - 1, RimApplyGlobalMaskBlendType, rim * blendStrength);
				}
				
				if (RimApplyAlpha == 1) // Add
				
				{
					poiFragData.alpha += lerp(0, saturate(rim), RimApplyAlphaBlend);
					poiFragData.alpha = saturate(poiFragData.alpha);
				}
				if (RimApplyAlpha == 2) // Multiply
				
				{
					poiFragData.alpha *= lerp(1, saturate(rim), RimApplyAlphaBlend);
				}
				
				float3 finalRimColor = rimColor.rgb * lerp(1, poiFragData.baseColor, RimBaseColorMix);
				finalRimColor *= RimBrightness;
				// Add 0, Replace 1, Multiply 2, Mixed 3
				switch(RimBlendMode)
				{
					case 0: poiFragData.baseColor += finalRimColor * rim * blendStrength; break;
					case 1: poiFragData.baseColor = lerp(poiFragData.baseColor, finalRimColor, rim * blendStrength); break;
					case 2: poiFragData.baseColor = lerp(poiFragData.baseColor, poiFragData.baseColor * finalRimColor, rim * blendStrength); break;
					case 3: poiFragData.baseColor = lerp(poiFragData.baseColor.rgb, poiFragData.baseColor.rgb + poiFragData.baseColor.rgb * finalRimColor, rim * blendStrength); break;
					case 4: poiFragData.baseColor = lerp(poiFragData.baseColor, 1 - (1 - poiFragData.baseColor) * (1 - finalRimColor), rim * blendStrength); break;
				}
				poiFragData.emission += finalRimColor * rim * rimStrength;
			}
			#endif
			#if defined(_RIMSTYLE_UTS2) || defined(_RIM2STYLE_UTS2)
			void ApplyUTS2RimLighting(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight, in PoiMods poiMods, float Set_RimLightMask_var, float RimGlobalMask, float RimGlobalMaskBlendType, float4 RimLightColor, float RimLightColorThemeIndex, float Is_LightColor_RimLight, float Is_NormalMapToRimLight, float RimLight_Power, float RimLight_InsideMask, float RimLight_FeatherOff, float LightDirection_MaskOn, float Tweak_LightDirection_MaskLevel, float Add_Antipodean_RimLight, float4 Ap_RimLightColor, float RimApColorThemeIndex, float Is_LightColor_Ap_RimLight, float Ap_RimLight_Power, float Ap_RimLight_FeatherOff, float Tweak_RimLightMaskLevel, float RimHueShiftEnabled, float RimHueShift, float RimHueShiftSpeed)
			{
				if (RimGlobalMask > 0)
				{
					Set_RimLightMask_var = maskBlend(Set_RimLightMask_var, poiMods.globalMask[RimGlobalMask - 1], RimGlobalMaskBlendType);
				}
				
				float3 rimColor = float3(poiThemeColor(poiMods, RimLightColor.rgb, RimLightColorThemeIndex));
				float3 _Is_LightColor_RimLight_var = lerp(rimColor, (rimColor * poiLight.directColor), Is_LightColor_RimLight);
				float _RimArea_var = (1.0 - dot(lerp(poiMesh.normals[0], poiMesh.normals[1], Is_NormalMapToRimLight), poiCam.viewDir));
				float _RimLightPower_var = pow(_RimArea_var, exp2(lerp(3, 0, RimLight_Power)));
				float _Rimlight_InsideMask_var = saturate(lerp((0.0 + ((_RimLightPower_var - RimLight_InsideMask) * (1.0 - 0.0)) / (1.0 - RimLight_InsideMask)), step(RimLight_InsideMask, _RimLightPower_var), RimLight_FeatherOff));
				float _VertHalfLambert_var = 0.5 * dot(poiMesh.normals[0], poiLight.direction) + 0.5;
				float3 _LightDirection_MaskOn_var = lerp((_Is_LightColor_RimLight_var * _Rimlight_InsideMask_var), (_Is_LightColor_RimLight_var * saturate((_Rimlight_InsideMask_var - ((1.0 - _VertHalfLambert_var) + Tweak_LightDirection_MaskLevel)))), LightDirection_MaskOn);
				float _ApRimLightPower_var = pow(_RimArea_var, exp2(lerp(3, 0, Ap_RimLight_Power)));
				float3 ApRimColor = float3(poiThemeColor(poiMods, Ap_RimLightColor.rgb, RimApColorThemeIndex));
				float3 _RimLight_var = (saturate((Set_RimLightMask_var + Tweak_RimLightMaskLevel)) * lerp(_LightDirection_MaskOn_var, (_LightDirection_MaskOn_var + (lerp(ApRimColor, (ApRimColor * poiLight.directColor), Is_LightColor_Ap_RimLight) * saturate((lerp((0.0 + ((_ApRimLightPower_var - RimLight_InsideMask) * (1.0 - 0.0)) / (1.0 - RimLight_InsideMask)), step(RimLight_InsideMask, _ApRimLightPower_var), Ap_RimLight_FeatherOff) - (saturate(_VertHalfLambert_var) + Tweak_LightDirection_MaskLevel))))), Add_Antipodean_RimLight));
				UNITY_BRANCH
				if (RimHueShiftEnabled)
				{
					_RimLight_var = hueShift(_RimLight_var, RimHueShift + _Time.x * RimHueShiftSpeed);
				}
				poiFragData.baseColor += _RimLight_var;
			}
			#endif
			#if defined(_RIMSTYLE_LILTOON) || defined(_RIM2STYLE_LILTOON)
			void ApplyLiltoonRimLighting(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight, in PoiMods poiMods, float4 RimColor, float4 RimIndirColor, float4 RimColorTex, float RimMainStrength, float RimNormalStrength, float RimDirRange, float RimIndirRange, float RimFresnelPower, float RimBackfaceMask, float RimDirStrength, float RimBorder, float RimBlur, float RimIndirBorder, float RimIndirBlur, float RimShadowMask, float RimEnableLighting, float RimVRParallaxStrength, float RimGlobalMask, float RimGlobalMaskBlendType, float RimHueShiftEnabled, float RimHueShift, float RimHueShiftSpeed, int RimBlendMode)
			{
				if (RimGlobalMask > 0)
				{
					RimColorTex.a = maskBlend(RimColorTex.a, poiMods.globalMask[RimGlobalMask - 1], RimGlobalMaskBlendType);
				}
				float4 rimColor = RimColor;
				float4 rimIndirColor = RimIndirColor;
				rimColor *= RimColorTex;
				rimIndirColor *= RimColorTex;
				
				if (RimHueShiftEnabled)
				{
					rimColor.rgb = hueShift(rimColor.rgb, RimHueShift + _Time.x * RimHueShiftSpeed);
					rimIndirColor.rgb = hueShift(rimIndirColor.rgb, RimHueShift + _Time.x * RimHueShiftSpeed);
				}
				
				rimColor.rgb = lerp(rimColor.rgb, rimColor.rgb * poiFragData.baseColor, RimMainStrength);
				
				// View direction
				float3 centerViewDir = !IsOrthographicCamera() ? normalize(getCameraPosition() - poiMesh.worldPos.xyz) : normalize(UNITY_MATRIX_I_V._m02_m12_m22);
				float3 viewDir = lerp(centerViewDir, poiCam.viewDir, RimVRParallaxStrength);
				
				// Normal
				float3 normal = lerp(poiMesh.normals[0], poiMesh.normals[1], RimNormalStrength);
				float nvabs = abs(dot(normal, viewDir));
				
				// Factor
				float lnRaw = dot(poiLight.direction, normal) * 0.5 + 0.5;
				float lnDir = saturate((lnRaw + RimDirRange) / (1.0 + RimDirRange));
				float lnIndir = saturate((1.0 - lnRaw + RimIndirRange) / (1.0 + RimIndirRange));
				float rim = pow(saturate(1.0 - nvabs), RimFresnelPower);
				rim = !poiMesh.isFrontFace && RimBackfaceMask ? 0.0 : rim;
				float rimDir = lerp(rim, rim * lnDir, RimDirStrength);
				float rimIndir = rim * lnIndir * RimDirStrength;
				
				rimDir = poiEdgeLinear(rimDir, RimBorder, RimBlur);
				rimIndir = poiEdgeLinear(rimIndir, RimIndirBorder, RimIndirBlur);
				
				rimDir = lerp(rimDir, rimDir * poiLight.rampedLightMap, RimShadowMask);
				rimIndir = lerp(rimIndir, rimIndir * poiLight.rampedLightMap, RimShadowMask);
				
				float3 lightCol = poiLight.finalLighting;
				/*
				#if !defined(POI_PASS_ADD)
				rimColor.rgb = lerp(rimColor.rgb, rimColor.rgb * lightCol, RimEnableLighting);
				#else
				if (RimBlendMode < 3) rimColor.rgb *= lightCol * RimEnableLighting;
				#endif
				// Blend
				*/
				#if !defined(POI_PASS_ADD)
				float3 rimLightMul = 1 - RimEnableLighting + lightCol * RimEnableLighting;
				#else
				float3 rimLightMul = RimBlendMode < 3 ? lightCol * RimEnableLighting : 1;
				#endif
				
				poiFragData.finalColor = lilBlendColor(poiFragData.finalColor, rimColor.rgb * rimLightMul, rimDir * rimColor.a, RimBlendMode);
				poiFragData.finalColor = lilBlendColor(poiFragData.finalColor, rimIndirColor.rgb * rimLightMul, rimIndir * rimIndirColor.a, RimBlendMode);
			}
			#endif
			#endif
			//endex
			
			//ifex _EnableDepthRimLighting==0
			#ifdef _POI_DEPTH_RIMLIGHT
			
			float PositivePow(float base, float power)
			{
				return pow(max(abs(base), Epsilon), power);
			}
			
			float GetScaleWithHight()
			{
				return _ScreenParams.y / 1080;
			}
			
			float GetSSRimScale(float z)
			{
				float w = (1.0 / (PositivePow(z + saturate(UNITY_MATRIX_P._m00), 1.5) + 0.75)) * GetScaleWithHight();
				w *= lerp(1, UNITY_MATRIX_P._m00, 0.60 * saturate(0.25 * z * z));
				return w < 0.01 ? 0 : w;
			}
			
			void ApplyDepthRimLighting(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, inout PoiLight poiLight, in PoiMods poiMods)
			{
				float rim = 0;
				float perspectiveDivide = 1.0f / poiCam.clipPos.w;
				float4 direction = poiCam.worldDirection * perspectiveDivide;
				float2 screenPos = poiCam.posScreenSpace.xy * perspectiveDivide;
				float z = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, screenPos);
				
				#if UNITY_REVERSED_Z
				if (z == 0) return;
				#else
				if (z == 1) return;
				#endif
				
				float depth = CorrectedLinearEyeDepth(z, direction.w);
				
				switch(_DepthRimType)
				{
					case 0:
					{
						float3 viewPos = UnityObjectToViewPos(poiMesh.localPos);
						float3 viewDir = normalize(viewPos);
						
						float3 viewNorm = mul((float3x3)UNITY_MATRIX_V, poiMesh.normals[_DepthRimNormalToUse]);
						float3 viewCrossNorm = cross(viewDir, viewNorm);
						float2 N_View = normalize(float2(-viewCrossNorm.y, viewCrossNorm.x));
						
						float3 viewLight = mul((float3x3)UNITY_MATRIX_V, poiLight.direction);
						float3 viewCrossLight = cross(viewDir, viewLight);
						float2 L_View = normalize(float2(-viewCrossLight.y, viewCrossLight.x));
						
						//float lDotN = saturate(poiLight.nDotL + _RimLightLength);
						float scale = _DepthRimWidth * GetSSRimScale(depth);
						float2 ssUV1 = clamp(screenPos + N_View * .1 * scale, 0, _ScreenParams.xy - 1);
						float depthDiff = z - SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, ssUV1) ;
						
						rim = smoothstep(0.24 * _DepthRimSharpness * z, 0.25 * z, depthDiff);
						rim *= lerp(1, (dot(L_View, N_View) > 0), _DepthRimHideInShadow);
					}
					break;
					case 1:
					{
						//float lDotN = saturate(poiLight.nDotL + _RimLightLength);
						float scale = _DepthRimWidth * GetSSRimScale(depth);
						float depthDiff = 0;
						[unroll(9)]
						for (int i = 0; i < 9; i++)
						{
							float2 ssUV1 = clamp(screenPos + sobelSamplePoints[i] * .1 * scale, 0, _ScreenParams.xy - 1);
							depthDiff = max(depthDiff, z - SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, ssUV1));
						}
						rim = smoothstep(0.24 * _DepthRimSharpness * z, 0.25 * z, depthDiff);
						rim *= lerp(1, lerp(poiLight.vertexNDotL > 0, poiLight.nDotL > 0, _DepthRimNormalToUse), _DepthRimHideInShadow);
					}
					break;
				}
				
				float3 rimColor = poiThemeColor(poiMods, _DepthRimColor.rgb, _DepthRimColorThemeIndex).rgb * lerp(1, poiLight.directColor, _DepthRimMixLightColor) * lerp(1, poiFragData.baseColor, _DepthRimMixBaseColor) * _DepthRimBrightness;
				
				#ifdef POI_PASS_BASE
				poiLight.finalLightAdd += rim * rimColor * _DepthRimAdditiveLighting;
				#endif
				poiFragData.emission += rim * rimColor * _DepthRimEmission;
				poiFragData.baseColor = lerp(poiFragData.baseColor, rimColor, rim * _DepthRimReplace);
				poiFragData.baseColor += rim * rimColor * _DepthRimAdd;
				poiFragData.baseColor *= lerp(1, rimColor, rim * _DepthRimMultiply);
			}
			#endif
			//endex
			
			//ifex _GlitterEnable==0
			#ifdef _SUNDISK_SIMPLE
			
			float3 RandomColorFromPoint(float2 rando, PoiMods poiMods)
			{
				fixed hue = random2(rando.x + rando.y).x;
				fixed saturation = lerp(_GlitterMinMaxSaturation.x, _GlitterMinMaxSaturation.y, rando.x);
				fixed value = lerp(_GlitterMinMaxBrightness.x, _GlitterMinMaxBrightness.y, rando.y);
				float3 hsv = float3(hue, saturation, value);
				return HSVtoRGB(hsv);
			}
			
			void applyGlitter(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiLight poiLight, in PoiMods poiMods)
			{
				float glitterRotationTimeOffset = 0;
				#ifdef POI_AUDIOLINK
				if (_GlitterALEnabled)
				{
					glitterRotationTimeOffset += AudioLinkGetChronoTime(_GlitterALChronoRotationSpeedType, _GlitterALChronoRotationSpeedBand) * _GlitterALChronoRotationSpeed;
				}
				#endif
				
				for (int glitterLayer = 0; glitterLayer < _GlitterLayers; glitterLayer++)
				{
					// Scale
					
					float2 st = (poiMesh.uv[_GlitterUV] + _GlitterUVPanning.xy * _Time.x) * _GlitterFrequency;
					
					// Tile the space
					float2 i_st = floor(st);
					float2 f_st = frac(st);
					
					float m_dist = 10.;  // minimun distance
					float2 m_point = 0;        // minimum point
					float2 randoPoint = 0;
					float2 dank = 0;
					for (int j = -1; j <= 1; j++)
					{
						for (int i = -1; i <= 1; i++)
						{
							float2 neighbor = float2(i, j);
							float2 pos = random2(i_st + neighbor + glitterLayer * 0.5141);
							float2 rando = pos;
							pos = pos * _GlitterRandomLocation;
							float2 diff = neighbor + pos - f_st;
							float dist = length(diff);
							
							if (dist < m_dist)
							{
								dank = diff;
								m_dist = dist;
								m_point = pos;
								randoPoint = rando;
							}
						}
					}
					
					float randomFromPoint = random(randoPoint);
					
					float size = _GlitterSize;
					UNITY_BRANCH
					if (_GlitterRandomSize)
					{
						size = lerp(_GlitterMinMaxSize.x, _GlitterMinMaxSize.y, randomFromPoint);
					}
					#ifdef POI_AUDIOLINK
					if (_GlitterALEnabled)
					{
						size = saturate(size + lerp(_GlitterALSizeAdd.x, _GlitterALSizeAdd.y, poiMods.audioLink[_GlitterALSizeAddBand]));
					}
					#endif
					
					// Assign a color using the closest point position
					//color += dot(m_point, float2(.3, .6));
					
					// Add distance field to closest point center
					// color.g = m_dist;
					
					// Show isolines
					//color -= abs(sin(40.0 * m_dist)) * 0.07;
					
					// Draw cell center
					half glitterAlpha = 1;
					switch(_GlitterShape)
					{
						case 0: //circle
						glitterAlpha = saturate((size - m_dist) / clamp(fwidth(m_dist), 0.0001, 1.0));
						break;
						case 1: //sqaure
						float jaggyFix = pow(poiCam.distanceToVert, 2) * _GlitterJaggyFix;
						UNITY_BRANCH
						if (_GlitterRandomRotation == 1 || _GlitterTextureRotation != 0 || _GlitterRandomRotationSpeed.x != 0 || _GlitterRandomRotationSpeed.y != 0 || glitterRotationTimeOffset != 0)
						{
							float2 center = float2(0, 0);
							float2 glitterRandomRotationSpeed = 0;
							float randomBoy = 0;
							UNITY_BRANCH
							if (_GlitterRandomRotation || _GlitterRandomRotationSpeed.x != 0 || _GlitterRandomRotationSpeed.y != 0)
							{
								randomBoy = random(m_point * 200);
								glitterRandomRotationSpeed = lerp(_GlitterRandomRotationSpeed.x, _GlitterRandomRotationSpeed.y, randomBoy);
							}
							if (glitterRandomRotationSpeed.x + glitterRandomRotationSpeed.y + _GlitterTextureRotation == 0 && glitterRotationTimeOffset != 0)
							{
								glitterRandomRotationSpeed = 1;
							}
							float theta = radians((randomBoy + (_Time.x + glitterRotationTimeOffset) * (_GlitterTextureRotation + glitterRandomRotationSpeed)) * 360);
							float cs = cos(theta);
							float sn = sin(theta);
							dank = float2((dank.x - center.x) * cs - (dank.y - center.y) * sn + center.x, (dank.x - center.x) * sn + (dank.y - center.y) * cs + center.y);
							glitterAlpha = (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.x))) * (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.y)));
						}
						else
						{
							glitterAlpha = (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.x))) * (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.y)));
						}
						break;
					}
					
					float3 finalGlitter = 0;
					
					half3 glitterColor = poiThemeColor(poiMods, _GlitterColor.rgb, _GlitterColorThemeIndex);
					
					float3 norm = lerp(poiMesh.normals[0], poiMesh.normals[1], _GlitterUseNormals);
					float3 randomRotation = 0;
					float glitterSpeedOffset = 0;
					#ifdef POI_AUDIOLINK
					if (_GlitterALEnabled)
					{
						glitterSpeedOffset += AudioLinkGetChronoTime(_GlitterALChronoSparkleSpeedType, _GlitterALChronoSparkleSpeedBand) * _GlitterALChronoSparkleSpeed;
					}
					#endif
					switch(_GlitterMode)
					{
						case 0:
						UNITY_BRANCH
						if (_GlitterSpeed + glitterSpeedOffset > 0)
						{
							randomRotation = randomFloat3WiggleRange(randoPoint, _GlitterAngleRange, _GlitterSpeed, glitterSpeedOffset);
						}
						else
						{
							randomRotation = randomFloat3Range(randoPoint, _GlitterAngleRange);
						}
						
						float3 glitterReflectionDirection = normalize(mul(poiRotationMatrixFromAngles(randomRotation), norm));
						finalGlitter = lerp(0, _GlitterMinBrightness * glitterAlpha, glitterAlpha) + max(pow(saturate(dot(lerp(glitterReflectionDirection, poiCam.viewDir, _GlitterBias), poiCam.viewDir)), _GlitterContrast), 0);
						finalGlitter *= glitterAlpha;
						break;
						case 1:
						float randomOffset = random(randoPoint);
						float brightness = (sin((_Time.x * 10 + randomOffset +glitterSpeedOffset) * _GlitterSpeed) * .5 + .5);
						finalGlitter = max(_GlitterMinBrightness * glitterAlpha, brightness * glitterAlpha * smoothstep(0, 1, 1 - m_dist * _GlitterCenterSize * 10));
						break;
						case 2:
						if (_GlitterSpeed + glitterSpeedOffset > 0)
						{
							randomRotation = randomFloat3WiggleRange(randoPoint, _GlitterAngleRange, _GlitterSpeed, glitterSpeedOffset);
						}
						else
						{
							randomRotation = randomFloat3Range(randoPoint, _GlitterAngleRange);
						}
						
						float3 glitterLightReflectionDirection = normalize(mul(poiRotationMatrixFromAngles(randomRotation), norm));
						
						glitterAlpha *= poiLight.nDotLSaturated;
						
						float3 halfDir = normalize(poiLight.direction + poiCam.viewDir);
						float specAngle = max(dot(halfDir, glitterLightReflectionDirection), 0.0);
						
						finalGlitter = lerp(0, _GlitterMinBrightness * glitterAlpha, glitterAlpha) + max(pow(specAngle, _GlitterContrast), 0);
						
						glitterColor *= poiLight.directColor;
						finalGlitter *= glitterAlpha;
						
						break;
					}
					
					glitterColor *= lerp(1, poiFragData.baseColor, _GlitterUseSurfaceColor);
					#if defined(PROP_GLITTERCOLORMAP) || !defined(OPTIMIZER_ENABLED)
					glitterColor *= POI2D_SAMPLER_PAN(_GlitterColorMap, _MainTex, poiUV(poiMesh.uv[_GlitterColorMapUV], _GlitterColorMap_ST), _GlitterColorMapPan).rgb;
					#endif
					float2 uv = remapClamped(-size, size, dank, 0, 1);
					UNITY_BRANCH
					
					if (_GlitterRandomRotation == 1 || _GlitterTextureRotation != 0 || _GlitterRandomRotationSpeed.x != 0 || _GlitterRandomRotationSpeed.y && !_GlitterShape || glitterRotationTimeOffset != 0)
					{
						float2 fakeUVCenter = float2(.5, .5);
						float randomBoy = 0;
						float2 glitterRandomRotationSpeed = 0;
						UNITY_BRANCH
						if (_GlitterRandomRotation || _GlitterRandomRotationSpeed.x != 0 || _GlitterRandomRotationSpeed.y != 0)
						{
							randomBoy = random(randoPoint * 20);
							glitterRandomRotationSpeed = lerp(_GlitterRandomRotationSpeed.x, _GlitterRandomRotationSpeed.y, randomBoy);
						}
						if (glitterRandomRotationSpeed.x + glitterRandomRotationSpeed.y + _GlitterTextureRotation == 0 && glitterRotationTimeOffset != 0)
						{
							glitterRandomRotationSpeed = 1;
						}
						float theta = radians((randomBoy + (_Time.x + glitterRotationTimeOffset) * (_GlitterTextureRotation + glitterRandomRotationSpeed)) * 360);
						float cs = cos(theta);
						float sn = sin(theta);
						uv = float2((uv.x - fakeUVCenter.x) * cs - (uv.y - fakeUVCenter.y) * sn + fakeUVCenter.x, (uv.x - fakeUVCenter.x) * sn + (uv.y - fakeUVCenter.y) * cs + fakeUVCenter.y);
					}
					
					#if defined(PROP_GLITTERTEXTURE) || !defined(OPTIMIZER_ENABLED)
					float4 glitterTexture = POI2D_SAMPLER_PANGRAD(_GlitterTexture, _linear_clamp, poiUV(uv, _GlitterTexture_ST), _GlitterTexturePan, poiMesh.dx, poiMesh.dy);
					#else
					float4 glitterTexture = 1;
					#endif
					//float4 glitterTexture = _GlitterTexture.SampleGrad(sampler_MainTex, frac(uv), ddx(uv), ddy(uv));
					glitterColor *= glitterTexture.rgb;
					#if defined(PROP_GLITTERMASK) || !defined(OPTIMIZER_ENABLED)
					float glitterMask = POI2D_SAMPLER_PAN(_GlitterMask, _MainTex, poiUV(poiMesh.uv[_GlitterMaskUV], _GlitterMask_ST), _GlitterMaskPan)[_GlitterMaskChannel];
					#else
					float glitterMask = 1;
					#endif
					
					#ifdef POI_AUDIOLINK
					if (_GlitterALEnabled)
					{
						glitterMask = clamp(glitterMask + lerp(_GlitterALAlphaAdd.x, _GlitterALAlphaAdd.y, poiMods.audioLink[_GlitterALAlphaAddBand]), 0, glitterMask);
					}
					#endif
					
					if (_GlitterMaskInvert)
					{
						glitterMask = 1 - glitterMask;
					}
					
					glitterMask *= lerp(1, poiLight.rampedLightMap, _GlitterHideInShadow);
					glitterMask *= lerp(1, poiLight.directLuminance, _GlitterScaleWithLighting);
					glitterMask *= _GlitterColor.a;
					
					if (_GlitterMaskGlobalMask > 0)
					{
						glitterMask = maskBlend(glitterMask, poiMods.globalMask[_GlitterMaskGlobalMask - 1], _GlitterMaskGlobalMaskBlendType);
					}
					
					if (_GlitterRandomColors)
					{
						glitterColor *= RandomColorFromPoint(random2(randoPoint.x + randoPoint.y), poiMods);
					}
					
					UNITY_BRANCH
					if (_GlitterHueShiftEnabled)
					{
						glitterColor.rgb = hueShift(glitterColor.rgb, _GlitterHueShift + _Time.x * _GlitterHueShiftSpeed);
					}
					float GlitterbrightnessOffset = 0;
					#ifdef POI_AUDIOLINK
					if (_GlitterALEnabled)
					{
						GlitterbrightnessOffset = max(GlitterbrightnessOffset +lerp(_GlitterALMaxBrightnessAdd.x, _GlitterALMaxBrightnessAdd.y, poiMods.audioLink[_GlitterALMaxBrightnessBand]), 0);
					}
					#endif
					
					UNITY_BRANCH
					if (_GlitterBlendType == 1)
					{
						poiFragData.baseColor = lerp(poiFragData.baseColor, finalGlitter * glitterColor * (_GlitterBrightness + GlitterbrightnessOffset), finalGlitter * glitterTexture.a * glitterMask);
						poiFragData.emission += finalGlitter * glitterColor * max(0, ((_GlitterBrightness + GlitterbrightnessOffset) - 1) * glitterTexture.a) * glitterMask;
					}
					else
					{
						poiFragData.emission += finalGlitter * glitterColor * (_GlitterBrightness + GlitterbrightnessOffset) * glitterTexture.a * glitterMask;
					}
				}
			}
			#endif
			//endex
			
			//ifex _SubsurfaceScattering==0
			#ifdef POI_SUBSURFACESCATTERING
			void applySubsurfaceScattering(in PoiCam poiCam, inout PoiLight poiLight, in PoiMesh poiMesh, in PoiFragData poiFragData)
			{
				float4 SSS = 1;
				#if defined(PROP_SSSTHICKNESSMAP) || !defined(OPTIMIZER_ENABLED)
				SSS = POI2D_SAMPLER_PAN(_SSSThicknessMap, _MainTex, poiUV(poiMesh.uv[_SSSThicknessMapUV], _SSSThicknessMap_ST), _SSSThicknessMapPan);
				SSS.a = 1 - SSS.a;
				#endif
				
				float3 vLTLight = poiLight.direction + poiMesh.normals[0] * _SSSDistortion;
				float flTDot = pow(saturate(dot(poiCam.viewDir, -vLTLight)), _SSSSpread) * _SSSStrength;
				#ifdef UNITY_PASS_FORWARDBASE
				float3 fLT = (flTDot) * saturate(SSS.a + - 1 * _SSSThicknessMod);
				#else
				float3 fLT = poiLight.additiveShadow * (flTDot) * saturate(SSS.a + - 1 * _SSSThicknessMod);
				#endif
				
				#if defined(POINT) || defined(SPOT)
				poiLight.finalLightAdd += fLT * poiLight.directColor * _SSSColor * SSS.rgb * lerp(1, poiFragData.baseColor, _SSSBaseColorMix);
				#endif
				poiLight.finalLightAdd += fLT * poiLight.directColor * _SSSColor * SSS.rgb * poiLight.attenuation * lerp(1, poiFragData.baseColor, _SSSBaseColorMix);
			}
			#endif
			//endex
			
			//ifex _MochieBRDF==0 && _ClearCoatBRDF==0
			#if defined(MOCHIE_PBR) || defined(POI_CLEARCOAT)
			
			/*
			* Copyright 2022 orels1
			*
			* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
			*
			* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
			*
			* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
			*/
			
			// https://github.com/orels1/orels-Unity-Shaders
			
			float GSAA_Filament(float3 worldNormal, float perceptualRoughness, float gsaaVariance, float gsaaThreshold)
			{
				// Kaplanyan 2016, "Stable specular highlights"
				// Tokuyoshi 2017, "Error Reduction and Simplification for Shading Anti-Aliasing"
				// Tokuyoshi and Kaplanyan 2019, "Improved Geometric Specular Antialiasing"
				
				// This implementation is meant for deferred rendering in the original paper but
				// we use it in forward rendering as well (as discussed in Tokuyoshi and Kaplanyan
				// 2019). The main reason is that the forward version requires an expensive transform
				// of the float vector by the tangent frame for every light. This is therefore an
				// approximation but it works well enough for our needs and provides an improvement
				// over our original implementation based on Vlachos 2015, "Advanced VR Rendering".
				
				float3 du = ddx(worldNormal);
				float3 dv = ddy(worldNormal);
				
				float variance = gsaaVariance * (dot(du, du) + dot(dv, dv));
				
				float roughness = perceptualRoughness * perceptualRoughness;
				float kernelRoughness = min(2.0 * variance, gsaaThreshold);
				float squareRoughness = saturate(roughness * roughness + kernelRoughness);
				
				return sqrt(sqrt(squareRoughness));
			}
			
			/*
			MIT END
			*/
			
			bool SceneHasReflections()
			{
				float width, height;
				unity_SpecCube0.GetDimensions(width, height);
				return !(width * height < 2);
			}
			
			float3 GetWorldReflections(float3 reflDir, float3 worldPos, float roughness)
			{
				float3 baseReflDir = reflDir;
				reflDir = BoxProjection(reflDir, worldPos, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax);
				float4 envSample0 = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, reflDir, roughness * UNITY_SPECCUBE_LOD_STEPS);
				float3 p0 = DecodeHDR(envSample0, unity_SpecCube0_HDR);
				float interpolator = unity_SpecCube0_BoxMin.w;
				UNITY_BRANCH
				if (interpolator < 0.99999)
				{
					float3 refDirBlend = BoxProjection(baseReflDir, worldPos, unity_SpecCube1_ProbePosition, unity_SpecCube1_BoxMin, unity_SpecCube1_BoxMax);
					float4 envSample1 = UNITY_SAMPLE_TEXCUBE_SAMPLER_LOD(unity_SpecCube1, unity_SpecCube0, refDirBlend, roughness * UNITY_SPECCUBE_LOD_STEPS);
					float3 p1 = DecodeHDR(envSample1, unity_SpecCube1_HDR);
					p0 = lerp(p1, p0, interpolator);
				}
				return p0;
			}
			
			float3 GetReflections(in PoiCam poiCam, in PoiLight pl, in PoiMesh poiMesh, float roughness, float ForceFallback, float LightFallback, samplerCUBE reflectionCube, float4 hdrData, float3 reflectionDir)
			{
				float3 reflections = 0;
				float3 lighting = pl.finalLighting;
				// This is a separate conditional so it can optimize out when ForceFallback isn't animated
				if (ForceFallback == 0)
				{
					UNITY_BRANCH
					if (SceneHasReflections())
					{
						#ifdef UNITY_PASS_FORWARDBASE
						reflections = GetWorldReflections(reflectionDir, poiMesh.worldPos.xyz, roughness);
						#endif
					}
					else
					{
						#ifdef UNITY_PASS_FORWARDBASE
						reflections = texCUBElod(reflectionCube, float4(reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
						reflections = DecodeHDR(float4(reflections, 1), hdrData) * lerp(1, pl.finalLighting, LightFallback);
						#endif
						#ifdef POI_PASS_ADD
						if (LightFallback)
						{
							reflections = texCUBElod(reflectionCube, float4(reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
							reflections = DecodeHDR(float4(reflections, 1), hdrData) * pl.finalLighting;
						}
						#endif
					}
				}
				else
				{
					#ifdef UNITY_PASS_FORWARDBASE
					reflections = texCUBElod(reflectionCube, float4(reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
					reflections = DecodeHDR(float4(reflections, 1), hdrData) * lerp(1, pl.finalLighting, LightFallback);
					#endif
					#ifdef POI_PASS_ADD
					if (LightFallback)
					{
						reflections = texCUBElod(reflectionCube, float4(reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
						reflections = DecodeHDR(float4(reflections, 1), hdrData) * pl.finalLighting;
					}
					#endif
				}
				reflections *= pl.occlusion;
				return reflections;
			}
			
			float GetGGXTerm(float nDotL, float nDotV, float nDotH, float roughness)
			{
				float visibilityTerm = 0;
				if (nDotL > 0)
				{
					float rough = roughness;
					float rough2 = roughness * roughness;
					
					float lambdaV = nDotL * (nDotV * (1 - rough) + rough);
					float lambdaL = nDotV * (nDotL * (1 - rough) + rough);
					
					visibilityTerm = 0.5f / (lambdaV + lambdaL + 1e-5f);
					float d = (nDotH * rough2 - nDotH) * nDotH + 1.0f;
					float dotTerm = UNITY_INV_PI * rough2 / (d * d + 1e-7f);
					
					visibilityTerm *= dotTerm * UNITY_PI;
				}
				return visibilityTerm;
			}
			
			void GetSpecFresTerm(float nDotL, float nDotV, float nDotH, float lDotH, inout float3 specularTerm, inout float3 fresnelTerm, float3 specCol, float roughness)
			{
				specularTerm = GetGGXTerm(nDotL, nDotV, nDotH, roughness);
				fresnelTerm = FresnelTerm(specCol, lDotH);
				specularTerm = max(0, specularTerm * max(0.00001, nDotL));
			}
			
			float GetRoughness(float smoothness)
			{
				float rough = 1 - smoothness;
				rough *= 1.7 - 0.7 * rough;
				return rough;
			}
			#endif
			//endex
			
			//ifex _MochieBRDF==0
			#ifdef MOCHIE_PBR
			void MetallicAndSpecularFragDataInit(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float smoothness = _MochieRoughnessMultiplier;
				float smoothness2 = _MochieRoughnessMultiplier2;
				float metallic = _MochieMetallicMultiplier;
				float specularMask = 1;
				float reflectionMask = 1;
				
				smoothness *= poiFragData.smoothness;
				smoothness2 *= poiFragData.smoothness2;
				metallic *= poiFragData.metallic;
				specularMask *= poiFragData.specularMask;
				reflectionMask *= poiFragData.reflectionMask;
				
				#if defined(PROP_MOCHIEMETALLICMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 PBRMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_MochieMetallicMaps, _MainTex, poiUV(poiMesh.uv[_MochieMetallicMapsUV], _MochieMetallicMaps_ST), _MochieMetallicMapsPan, _MochieMetallicMapsStochastic);
				UNITY_BRANCH
				if (_PBRSplitMaskSample)
				{
					float4 PBRSplitMask = POI2D_SAMPLER_PAN_STOCHASTIC(_MochieMetallicMaps, _MainTex, poiUV(poiMesh.uv[_MochieMetallicMasksUV], _PBRMaskScaleTiling), _MochieMetallicMasksPan.xy, _PBRSplitMaskStochastic);
					assignValueToVectorFromIndex(PBRMaps, _MochieMetallicMapsReflectionMaskChannel, PBRSplitMask[_MochieMetallicMapsReflectionMaskChannel]);
					assignValueToVectorFromIndex(PBRMaps, _MochieMetallicMapsSpecularMaskChannel, PBRSplitMask[_MochieMetallicMapsSpecularMaskChannel]);
				}
				
				if (_MochieMetallicMapsMetallicChannel < 4)
				{
					metallic *= PBRMaps[_MochieMetallicMapsMetallicChannel];
				}
				if (_MochieMetallicMapsRoughnessChannel < 4)
				{
					smoothness *= PBRMaps[_MochieMetallicMapsRoughnessChannel];
					smoothness2 *= PBRMaps[_MochieMetallicMapsRoughnessChannel];
				}
				if (_MochieMetallicMapsReflectionMaskChannel < 4)
				{
					reflectionMask *= PBRMaps[_MochieMetallicMapsReflectionMaskChannel];
				}
				if (_MochieMetallicMapsSpecularMaskChannel < 4)
				{
					specularMask *= PBRMaps[_MochieMetallicMapsSpecularMaskChannel];
				}
				#endif
				
				reflectionMask *= _MochieReflectionStrength;
				specularMask *= _MochieSpecularStrength;
				
				if (_MochieMetallicMapInvert)
				{
					metallic = 1 - metallic;
				}
				if (_MochieRoughnessMapInvert)
				{
					smoothness = 1 - smoothness;
					smoothness2 = 1 - smoothness2;
				}
				if (_MochieReflectionMaskInvert)
				{
					reflectionMask = 1 - reflectionMask;
				}
				if (_MochieSpecularMaskInvert)
				{
					specularMask = 1 - specularMask;
				}
				
				poiFragData.smoothness *= smoothness;
				poiFragData.smoothness2 *= smoothness2;
				poiFragData.metallic *= metallic;
				poiFragData.specularMask *= specularMask;
				poiFragData.reflectionMask *= reflectionMask;
			}
			
			void MochieBRDF(inout PoiFragData poiFragData, in PoiCam poiCam, inout PoiLight poiLight, in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				float smoothness = poiFragData.smoothness;
				float smoothness2 = poiFragData.smoothness2;
				float metallic = poiFragData.metallic;
				float specularMask = poiFragData.specularMask;
				float reflectionMask = poiFragData.reflectionMask;
				
				if (_MochieMetallicGlobalMask > 0)
				{
					metallic = customBlend(metallic, poiMods.globalMask[_MochieMetallicGlobalMask - 1], _MochieMetallicGlobalMaskBlendType);
				}
				if (_MochieSmoothnessGlobalMask > 0)
				{
					smoothness = customBlend(smoothness, poiMods.globalMask[_MochieSmoothnessGlobalMask - 1], _MochieSmoothnessGlobalMaskBlendType);
					smoothness2 = customBlend(smoothness2, poiMods.globalMask[_MochieSmoothnessGlobalMask - 1], _MochieSmoothnessGlobalMaskBlendType);
				}
				if (_MochieReflectionStrengthGlobalMask > 0)
				{
					reflectionMask = customBlend(reflectionMask, poiMods.globalMask[_MochieReflectionStrengthGlobalMask - 1], _MochieReflectionStrengthGlobalMaskBlendType);
				}
				if (_MochieSpecularStrengthGlobalMask > 0)
				{
					specularMask = customBlend(specularMask, poiMods.globalMask[_MochieSpecularStrengthGlobalMask - 1], _MochieSpecularStrengthGlobalMaskBlendType);
				}
				
				#ifdef TPS_Penetrator
				if (_BRDFTPSDepthEnabled)
				{
					reflectionMask = lerp(0, reflectionMask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _BRDFTPSReflectionMaskStrength);
					specularMask = lerp(0, specularMask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _BRDFTPSSpecularMaskStrength);
				}
				#endif
				
				float roughness = GetRoughness(smoothness);
				float roughness2 = GetRoughness(smoothness2);
				float3 specCol = lerp(unity_ColorSpaceDielectricSpec.rgb, poiFragData.baseColor, metallic);
				float omr = unity_ColorSpaceDielectricSpec.a - metallic * unity_ColorSpaceDielectricSpec.a;
				float percepRough = 1 - smoothness;
				float percepRough2 = 1 - smoothness2;
				UNITY_BRANCH
				if (_MochieGSAAEnabled)
				{
					percepRough = GSAA_Filament(poiMesh.normals[_PBRNormalSelect], percepRough, _PoiGSAAVariance, _PoiGSAAThreshold);
					if (_Specular2ndLayer == 1 && _MochieSpecularStrength2 > 0)
					{
						percepRough2 = GSAA_Filament(poiMesh.normals[_PBRNormalSelect], percepRough2, _PoiGSAAVariance, _PoiGSAAThreshold);
					}
				}
				float brdfRoughness = percepRough * percepRough;
				brdfRoughness = max(brdfRoughness, 0.002);
				
				float brdfRoughness2 = percepRough2 * percepRough2;
				brdfRoughness2 = max(brdfRoughness2, 0.002);
				
				float3 diffuse = poiFragData.baseColor;
				float3 specular = 0;
				float3 specular2 = 0;
				float3 vSpecular = 0;
				float3 vSpecular2 = 0;
				float3 reflections = 0;
				float3 environment = 0;
				
				#if defined(POINT) || defined(SPOT)
				float attenuation = lerp(poiLight.additiveShadow, 1, _IgnoreCastedShadows);
				#else
				float attenuation = min(poiLight.nDotLSaturated, lerp(poiLight.attenuation, 1, _IgnoreCastedShadows));
				#endif
				
				float3 fresnelTerm = 1;
				float3 specularTerm = 1;
				
				float pbrNDotL = lerp(poiLight.vertexNDotL, poiLight.nDotL, _PBRNormalSelect);
				float pbrNDotV = lerp(poiLight.vertexNDotV, poiLight.nDotV, _PBRNormalSelect);
				float pbrNDotH = lerp(poiLight.vertexNDotH, poiLight.nDotH, _PBRNormalSelect);
				float3 pbrReflectionDir = lerp(poiCam.vertexReflectionDir, poiCam.reflectionDir, _PBRNormalSelect);
				
				GetSpecFresTerm(pbrNDotL, pbrNDotV, pbrNDotH, poiLight.lDotH, specularTerm, fresnelTerm, specCol, brdfRoughness);
				specular = poiLight.directColor * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _MochieSpecularTint, _MochieSpecularTintThemeIndex) * poiLight.occlusion * attenuation;
				
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					for (int index = 0; index < 4; index++)
					{
						fresnelTerm = 1;
						specularTerm = 1;
						float pbrVDotNL = lerp(poiLight.vertexVDotNL[index], poiLight.vDotNL[index], _PBRNormalSelect);
						float pbrVDotNH = lerp(poiLight.vertexVDotNH[index], poiLight.vDotNH[index], _PBRNormalSelect);
						GetSpecFresTerm(pbrVDotNL, pbrNDotV, pbrVDotNH, poiLight.vDotLH[index], specularTerm, fresnelTerm, specCol, brdfRoughness);
						vSpecular += poiLight.vColor[index] * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _MochieSpecularTint, _MochieSpecularTintThemeIndex) * poiLight.occlusion;
					}
					#endif
				}
				
				if (_Specular2ndLayer == 1)
				{
					float3 fresnelTerm = 1;
					float3 specularTerm = 1;
					GetSpecFresTerm(pbrNDotL, pbrNDotV, pbrNDotH, poiLight.lDotH, specularTerm, fresnelTerm, specCol, brdfRoughness2);
					specular2 = poiLight.directColor * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _MochieSpecularTint, _MochieSpecularTintThemeIndex) * poiLight.occlusion * attenuation * _MochieSpecularStrength2;
					
					if (poiFragData.toggleVertexLights)
					{
						#if defined(VERTEXLIGHT_ON)
						for (int index = 0; index < 4; index++)
						{
							fresnelTerm = 1;
							specularTerm = 1;
							float pbrVDotNL = lerp(poiLight.vertexVDotNL[index], poiLight.vDotNL[index], _PBRNormalSelect);
							float pbrVDotNH = lerp(poiLight.vertexVDotNH[index], poiLight.vDotNH[index], _PBRNormalSelect);
							GetSpecFresTerm(pbrVDotNL, pbrNDotV, pbrVDotNH, poiLight.vDotLH[index], specularTerm, fresnelTerm, specCol, brdfRoughness2);
							vSpecular2 += poiLight.vColor[index] * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _MochieSpecularTint, _MochieSpecularTintThemeIndex) * poiLight.occlusion * _MochieSpecularStrength2;
						}
						#endif
					}
				}
				
				float surfaceReduction = (1.0 / (brdfRoughness * brdfRoughness + 1.0));
				float grazingTerm = saturate(smoothness + (1 - omr));
				float3 reflCol = GetReflections(poiCam, poiLight, poiMesh, roughness, _MochieForceFallback, _MochieLitFallback, _MochieReflCube, _MochieReflCube_HDR, pbrReflectionDir);
				if (poiMesh.isFrontFace)
				{
					reflections = surfaceReduction * reflCol * lerp(1, FresnelLerp(specCol, grazingTerm, pbrNDotV), _RefSpecFresnel);
				}
				else
				{
					reflections = surfaceReduction * reflCol * lerp(1, FresnelLerp(specCol, grazingTerm, pbrNDotV), _RefSpecFresnelBack);
				}
				
				reflections *= poiThemeColor(poiMods, _MochieReflectionTint, _MochieReflectionTintThemeIndex);
				reflections *= reflectionMask;
				diffuse = lerp(diffuse, diffuse * omr, reflectionMask);
				
				environment = max(specular + vSpecular, specular2 + vSpecular2);
				environment += reflections;
				diffuse *= poiLight.finalLighting;
				poiFragData.finalColor = diffuse;
				poiLight.finalLightAdd += environment;
			}
			#endif
			//endex
			//ifex _ClearCoatBRDF==0
			#ifdef POI_CLEARCOAT
			void poiClearCoat(inout PoiFragData poiFragData, in PoiCam poiCam, inout PoiLight poiLight, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float clearCoatMask = _ClearCoatStrength;
				float smoothness = _ClearCoatSmoothness;
				float reflectionMask = _ClearCoatReflectionStrength;
				float specularMask = _ClearCoatSpecularStrength;
				
				#if defined(PROP_CLEARCOATMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 PBRMaps = POI2D_SAMPLER_PAN_STOCHASTIC(_ClearCoatMaps, _MainTex, poiUV(poiMesh.uv[_ClearCoatMapsUV], _ClearCoatMaps_ST), _ClearCoatMapsPan, _ClearCoatMapsStochastic);
				
				if (_ClearCoatMapsClearCoatMaskChannel < 4)
				{
					clearCoatMask *= PBRMaps[_ClearCoatMapsClearCoatMaskChannel];
				}
				if (_ClearCoatMapsRoughnessChannel < 4)
				{
					smoothness *= PBRMaps[_ClearCoatMapsRoughnessChannel];
				}
				if (_ClearCoatMapsReflectionMaskChannel < 4)
				{
					reflectionMask *= PBRMaps[_ClearCoatMapsReflectionMaskChannel];
				}
				if (_ClearCoatMapsSpecularMaskChannel < 4)
				{
					specularMask *= PBRMaps[_ClearCoatMapsSpecularMaskChannel];
				}
				#endif
				
				if (_ClearCoatGlobalMask > 0)
				{
					clearCoatMask = customBlend(clearCoatMask, poiMods.globalMask[_ClearCoatGlobalMask - 1], _ClearCoatGlobalMaskBlendType);
				}
				if (_ClearCoatSmoothnessGlobalMask > 0)
				{
					smoothness = customBlend(smoothness, poiMods.globalMask[_ClearCoatSmoothnessGlobalMask - 1], _ClearCoatSmoothnessGlobalMaskBlendType);
				}
				if (_ClearCoatReflectionStrengthGlobalMask > 0)
				{
					reflectionMask = customBlend(reflectionMask, poiMods.globalMask[_ClearCoatReflectionStrengthGlobalMask - 1], _ClearCoatReflectionStrengthGlobalMaskBlendType);
				}
				if (_ClearCoatSpecularStrengthGlobalMask > 0)
				{
					specularMask = customBlend(specularMask, poiMods.globalMask[_ClearCoatSpecularStrengthGlobalMask - 1], _ClearCoatSpecularStrengthGlobalMaskBlendType);
				}
				
				if (_ClearCoatMaskInvert)
				{
					clearCoatMask = 1 - clearCoatMask;
				}
				if (_ClearCoatSmoothnessMapInvert)
				{
					smoothness = 1 - smoothness;
				}
				if (_ClearCoatReflectionMaskInvert)
				{
					reflectionMask = 1 - reflectionMask;
				}
				if (_ClearCoatSpecularMaskInvert)
				{
					specularMask = 1 - specularMask;
				}
				#ifdef TPS_Penetrator
				if (_ClearCoatTPSDepthMaskEnabled)
				{
					clearCoatMask = lerp(0, clearCoatMask * TPSBufferedDepth(poiMesh.localPos, poiMesh.vertexColor), _ClearCoatTPSMaskStrength);
				}
				#endif
				
				float roughness = GetRoughness(smoothness);
				float3 specCol = 0.220916301;
				float omr = unity_ColorSpaceDielectricSpec.a;
				float percepRough = 1 - smoothness;
				UNITY_BRANCH
				if (_ClearCoatGSAAEnabled)
				{
					percepRough = GSAA_Filament(poiMesh.normals[_ClearCoatNormalSelect], percepRough, _ClearCoatGSAAVariance, _ClearCoatGSAAThreshold);
				}
				float brdfRoughness = percepRough * percepRough;
				brdfRoughness = max(brdfRoughness, 0.002);
				
				float3 diffuse = 0;
				float3 specular = 0;
				float3 vSpecular = 0;
				float3 reflections = 0;
				float3 environment = 0;
				float attenuation = min(poiLight.nDotLSaturated, lerp(poiLight.attenuation, 1, _CCIgnoreCastedShadows));
				
				float3 fresnelTerm = 1;
				float3 specularTerm = 1;
				
				float clearcoatNDotL = lerp(poiLight.vertexNDotL, poiLight.nDotL, _ClearCoatNormalSelect);
				float clearcoatNDotV = lerp(poiLight.vertexNDotV, poiLight.nDotV, _ClearCoatNormalSelect);
				float clearcoatNDotH = lerp(poiLight.vertexNDotH, poiLight.nDotH, _ClearCoatNormalSelect);
				float3 clearcoatReflectionDir = lerp(poiCam.vertexReflectionDir, poiCam.reflectionDir, _ClearCoatNormalSelect);
				
				GetSpecFresTerm(clearcoatNDotL, clearcoatNDotV, clearcoatNDotH, poiLight.lDotH, specularTerm, fresnelTerm, specCol, brdfRoughness);
				specular = poiLight.directColor * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _ClearCoatSpecularTint, _ClearCoatSpecularTintThemeIndex) * poiLight.occlusion * attenuation;
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					for (int index = 0; index < 4; index++)
					{
						fresnelTerm = 1;
						specularTerm = 1;
						float clearcoatVDotNL = lerp(poiLight.vertexVDotNL[index], poiLight.vDotNL[index], _ClearCoatNormalSelect);
						float clearcoatVDotNH = lerp(poiLight.vertexVDotNH[index], poiLight.vDotNH[index], _ClearCoatNormalSelect);
						GetSpecFresTerm(clearcoatVDotNL, clearcoatNDotV, clearcoatVDotNH, poiLight.vDotLH[index], specularTerm, fresnelTerm, specCol, brdfRoughness);
						vSpecular += poiLight.vColor[index] * specularTerm * fresnelTerm * specularMask * poiThemeColor(poiMods, _ClearCoatSpecularTint, _ClearCoatSpecularTintThemeIndex) * poiLight.occlusion;
					}
					#endif
				}
				
				float surfaceReduction = (1.0 / (brdfRoughness * brdfRoughness + 1.0));
				float grazingTerm = saturate(smoothness + (1 - omr));
				float3 reflCol = GetReflections(poiCam, poiLight, poiMesh, roughness, _ClearCoatForceFallback, _ClearCoatLitFallback, _ClearCoatFallback, _ClearCoatFallback_HDR, clearcoatReflectionDir);
				reflections = surfaceReduction * reflCol * lerp(1, FresnelLerp(specCol, grazingTerm, clearcoatNDotV), _ClearcoatFresnel);
				reflections *= poiThemeColor(poiMods, _ClearCoatReflectionTint, _ClearCoatReflectionTintThemeIndex) * reflectionMask;
				diffuse = lerp(diffuse, diffuse * omr, reflectionMask);
				
				environment = specular + vSpecular;
				#ifdef UNITY_PASS_FORWARDBASE
				environment += reflections;
				#endif
				//diffuse *= poiLight.finalLighting;
				diffuse += environment;
				poiLight.finalLightAdd += saturate(diffuse * clearCoatMask);
			}
			#endif
			//endex
			
			//ifex _StylizedSpecular==0
			#ifdef POI_STYLIZED_StylizedSpecular
			void stylizedSpecular(inout PoiFragData poiFragData, in PoiCam poiCam, inout PoiLight poiLight, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float specArea = 0.5 * poiLight.nDotH + 0.5;
				#if defined(PROP_HIGHCOLOR_TEX) || !defined(OPTIMIZER_ENABLED)
				float3 specularMap = POI2D_SAMPLER_PAN(_HighColor_Tex, _MainTex, poiUV(poiMesh.uv[_HighColor_TexUV], _HighColor_Tex_ST), _HighColor_TexPan);
				#else
				float3 specularMap = 1;
				#endif
				
				// Spec 1
				float specMask1 = 0;
				float specMask2 = 0;
				if (_Is_SpecularToHighColor)
				{
					specMask1 += pow(specArea, exp2(lerp(11, 1, _HighColor_Power))) * _Layer1Strength;
					specMask2 += pow(specArea, exp2(lerp(11, 1, _Layer2Size))) * _Layer2Strength;
				}
				else
				{
					specMask1 += poiEdgeNonLinear(specArea, (1.0 - pow(_HighColor_Power, 5)), _StylizedSpecularFeather) * _Layer1Strength;
					specMask2 += poiEdgeNonLinear(specArea, (1.0 - pow(_Layer2Size, 5)), _StylizedSpecular2Feather) * _Layer2Strength;
				}
				
				#if defined(PROP_SET_HIGHCOLORMASK) || !defined(OPTIMIZER_ENABLED)
				float specularMask = POI2D_SAMPLER_PAN(_Set_HighColorMask, _MainTex, poiUV(poiMesh.uv[_Set_HighColorMaskUV], _Set_HighColorMask_ST), _Set_HighColorMaskPan)[_Set_HighColorMaskChannel];
				#else
				float specularMask = 1;
				#endif
				
				specularMask = saturate(specularMask + _Tweak_HighColorMaskLevel);
				
				float specMask = saturate(specMask1 + specMask2) * specularMask * lerp(poiLight.rampedLightMap, 1, _StylizedSpecularIgnoreShadow);
				float attenuation = min(lerp(poiLight.nDotLSaturated, 1, _StylizedSpecularIgnoreNormal), lerp(lerp(poiLight.attenuation, 1, _SSIgnoreCastedShadows), 1, _StylizedSpecularIgnoreShadow));
				#ifdef POI_PASS_ADD
				attenuation *= lerp(poiLight.additiveShadow, 1, _SSIgnoreCastedShadows);
				#endif
				
				float finalSpecMask = min(min(specMask, poiLight.occlusion), attenuation) * _StylizedSpecularStrength;
				switch(_Is_BlendAddToHiColor)
				{
					case 0:
					// Replace
					poiFragData.baseColor = lerp(poiFragData.baseColor, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.directColor, _UseLightColor), finalSpecMask);
					break;
					case 1:
					// Add
					poiLight.finalLightAdd += max(0, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.directColor, _UseLightColor) * finalSpecMask);
					break;
					case 2:
					// Screen
					poiFragData.baseColor = lerp(poiFragData.baseColor, blendScreen(poiFragData.baseColor, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.directColor, _UseLightColor)), finalSpecMask);
					break;
					case 3:
					// Multiply
					poiFragData.baseColor = lerp(poiFragData.baseColor, poiFragData.baseColor * specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.directColor, _UseLightColor), finalSpecMask);
					break;
				}
				
				//poiFragData.baseColor = _StylizedSpecularStrength;
				
				float3 vSpecMask = 0;
				if (poiFragData.toggleVertexLights)
				{
					#if defined(VERTEXLIGHT_ON)
					for (int index = 0; index < 4; index++)
					{
						if (!any(poiLight.vPosition[index])) continue;
						specArea = 0.5 * poiLight.vDotNH[index] + 0.5;
						if (_Is_SpecularToHighColor)
						{
							vSpecMask = pow(specArea, exp2(lerp(11, 1, _HighColor_Power))) * _Layer1Strength * poiLight.vAttenuation[index];
							vSpecMask = max(vSpecMask, pow(specArea, exp2(lerp(11, 1, _Layer2Size))) * _Layer2Strength * poiLight.vAttenuation[index]);
						}
						else
						{
							vSpecMask = poiEdgeNonLinear(specArea, (1.0 - pow(_HighColor_Power, 5)), _StylizedSpecularFeather) * _Layer1Strength * poiLight.vAttenuation[index];
							vSpecMask = max(vSpecMask, poiEdgeNonLinear(specArea, (1.0 - pow(_Layer2Size, 5)), _StylizedSpecular2Feather) * _Layer2Strength * poiLight.vAttenuation[index]);
						}
						
						vSpecMask *= specularMask;
						float finalSpecMask = min(min(vSpecMask, poiLight.occlusion), attenuation) * _StylizedSpecularStrength;
						switch(_Is_BlendAddToHiColor)
						{
							case 0:
							// Replace
							poiFragData.baseColor = lerp(poiFragData.baseColor, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.vColor[index], _UseLightColor), finalSpecMask);
							break;
							case 1:
							// Add
							poiLight.finalLightAdd += max(0, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.vColor[index], _UseLightColor) * finalSpecMask);
							break;
							case 2:
							// Screen
							poiFragData.baseColor = lerp(poiFragData.baseColor, blendScreen(poiFragData.baseColor, specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.vColor[index], _UseLightColor)), finalSpecMask);
							break;
							case 3:
							// Multiply
							poiFragData.baseColor = lerp(poiFragData.baseColor, poiFragData.baseColor * specularMap * poiThemeColor(poiMods, _HighColor, _HighColorThemeIndex) * lerp(1, poiLight.vColor[index], _UseLightColor), finalSpecMask);
							break;
						}
					}
					#endif
				}
			}
			#endif
			//endex
			
			//ifex _EnablePathing==0
			#ifdef POI_PATHING
			void applyPathing(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float3 albedo = poiFragData.baseColor;
				float3 pathEmission;
				#if defined(PROP_PATHINGMAP) || !defined(OPTIMIZER_ENABLED)
				float4 path = _PathingMap.Sample(SmpRepeatPoint, poiUV(poiMesh.uv[_PathingMapUV], _PathingMap_ST) + _PathingMapPan.xy * _Time.x);
				#else
				float4 path = float4(1, 1, 1, 1);
				#endif
				float4 PathColor[4];
				half pathAudioLinkPathTimeOffsetBand[4] = {
					0, 0, 0, 0
				};
				half2 pathAudioLinkTimeOffset[4] = {
					half2(0, 0), half2(0, 0), half2(0, 0), half2(0, 0)
				};
				half pathAudioLinkPathWidthOffsetBand[4] = {
					0, 0, 0, 0
				};
				half2 pathAudioLinkWidthOffset[4] = {
					half2(0, 0), half2(0, 0), half2(0, 0), half2(0, 0)
				};
				PathColor[0] = _PathColorR;
				PathColor[1] = _PathColorG;
				PathColor[2] = _PathColorB;
				PathColor[3] = _PathColorA;
				
				// Combined data
				if (_PathGradientType == 1)
				{
					path = (path.r + path.g + path.b + path.a) * .25;
				}
				
				#if defined(PROP_PATHINGCOLORMAP) || !defined(OPTIMIZER_ENABLED)
				float4 pathColorMap = POI2D_SAMPLER_PAN(_PathingColorMap, _MainTex, poiUV(poiMesh.uv[_PathingColorMapUV], _PathingColorMap_ST), _PathingColorMapPan);
				#else
				float4 pathColorMap = float4(1, 1, 1, 1);
				#endif
				
				float4 pathAudioLinkEmission = 0;
				float4 pathTime = 0;
				float3 pathAlpha[4] = {
					float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0)
				};
				
				#ifdef POI_AUDIOLINK
				float4 chronoType = float4(_PathChronoTypeR, _PathChronoTypeG, _PathChronoTypeB, _PathChronoTypeA);
				float4 chronoBand = float4(_PathChronoBandR, _PathChronoBandG, _PathChronoBandB, _PathChronoBandA);
				float4 chronoSpeed = float4(_PathChronoSpeedR, _PathChronoSpeedG, _PathChronoSpeedB, _PathChronoSpeedA);
				float3 autoCorrelator[4] = {
					float3(_PathALAutoCorrelatorR, _PathALAutoCorrelatorRangeR[0], _PathALAutoCorrelatorRangeR[1]), float3(_PathALAutoCorrelatorG, _PathALAutoCorrelatorRangeG[0], _PathALAutoCorrelatorRangeG[1]),
					float3(_PathALAutoCorrelatorB, _PathALAutoCorrelatorRangeB[0], _PathALAutoCorrelatorRangeB[1]), float3(_PathALAutoCorrelatorA, _PathALAutoCorrelatorRangeA[0], _PathALAutoCorrelatorRangeA[1])
				};
				float4 history[4] = {
					float4(_PathALHistoryR, _PathALHistoryBandR, _PathALHistoryRangeR[0], _PathALHistoryRangeR[1]), float4(_PathALHistoryG, _PathALHistoryBandG, _PathALHistoryRangeG[0], _PathALHistoryRangeG[1]),
					float4(_PathALHistoryB, _PathALHistoryBandB, _PathALHistoryRangeB[0], _PathALHistoryRangeB[1]), float4(_PathALHistoryA, _PathALHistoryBandA, _PathALHistoryRangeA[0], _PathALHistoryRangeA[1])
				};
				
				if (poiMods.audioLinkAvailable)
				{
					if (_PathALTimeOffset)
					{
						pathAudioLinkPathTimeOffsetBand[0] = _AudioLinkPathTimeOffsetBandR;
						pathAudioLinkPathTimeOffsetBand[1] = _AudioLinkPathTimeOffsetBandG;
						pathAudioLinkPathTimeOffsetBand[2] = _AudioLinkPathTimeOffsetBandB;
						pathAudioLinkPathTimeOffsetBand[3] = _AudioLinkPathTimeOffsetBandA;
						pathAudioLinkTimeOffset[0] = _AudioLinkPathTimeOffsetR.xy;
						pathAudioLinkTimeOffset[1] = _AudioLinkPathTimeOffsetG.xy;
						pathAudioLinkTimeOffset[2] = _AudioLinkPathTimeOffsetB.xy;
						pathAudioLinkTimeOffset[3] = _AudioLinkPathTimeOffsetA.xy;
					}
					
					if (_PathALWidthOffset)
					{
						pathAudioLinkPathWidthOffsetBand[0] = _AudioLinkPathWidthOffsetBandR;
						pathAudioLinkPathWidthOffsetBand[1] = _AudioLinkPathWidthOffsetBandG;
						pathAudioLinkPathWidthOffsetBand[2] = _AudioLinkPathWidthOffsetBandB;
						pathAudioLinkPathWidthOffsetBand[3] = _AudioLinkPathWidthOffsetBandA;
						pathAudioLinkWidthOffset[0] = _AudioLinkPathWidthOffsetR.xy;
						pathAudioLinkWidthOffset[1] = _AudioLinkPathWidthOffsetG.xy;
						pathAudioLinkWidthOffset[2] = _AudioLinkPathWidthOffsetB.xy;
						pathAudioLinkWidthOffset[3] = _AudioLinkPathWidthOffsetA.xy;
					}
					// Emission Offset
					if (_PathALEmissionOffset)
					{
						pathAudioLinkEmission.r += lerp(_AudioLinkPathEmissionAddR.x, _AudioLinkPathEmissionAddR.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandR]);
						pathAudioLinkEmission.g += lerp(_AudioLinkPathEmissionAddG.x, _AudioLinkPathEmissionAddG.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandG]);
						pathAudioLinkEmission.b += lerp(_AudioLinkPathEmissionAddB.x, _AudioLinkPathEmissionAddB.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandB]);
						pathAudioLinkEmission.a += lerp(_AudioLinkPathEmissionAddA.x, _AudioLinkPathEmissionAddA.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandA]);
					}
					
					if(_PathALColorChord)
					{
						if (_PathALCCR)
						{
							PathColor[0] *= AudioLinkLerp(ALPASS_CCSTRIP + float2(path[0] * AUDIOLINK_WIDTH, 0));
						}
						if (_PathALCCG)
						{
							PathColor[1] *= AudioLinkLerp(ALPASS_CCSTRIP + float2(path[1] * AUDIOLINK_WIDTH, 0));
						}
						if (_PathALCCB)
						{
							PathColor[2] *= AudioLinkLerp(ALPASS_CCSTRIP + float2(path[2] * AUDIOLINK_WIDTH, 0));
						}
						if (_PathALCCA)
						{
							PathColor[3] *= AudioLinkLerp(ALPASS_CCSTRIP + float2(path[3] * AUDIOLINK_WIDTH, 0));
						}
					}
				}
				#endif
				
				[unroll]
				for (int index = 0; index < 4; index++)
				{
					float timeOffset = 0;
					#ifdef POI_AUDIOLINK
					UNITY_BRANCH
					if (poiMods.audioLinkAvailable)
					{
						if (_PathALTimeOffset)
						{
							timeOffset += lerp(pathAudioLinkTimeOffset[index].x, pathAudioLinkTimeOffset[index].y, poiMods.audioLink[pathAudioLinkPathTimeOffsetBand[index]]);
						}
						
						if (_PathALChrono)
						{
							timeOffset += AudioLinkGetChronoTime(chronoType[index], chronoBand[index]) * chronoSpeed[index];
						}
					}
					#endif
					pathTime[index] = _PathTime[index] != -999.0f ? frac(_PathTime[index] + _PathOffset[index] + timeOffset) : frac(_Time.x * _PathSpeed[index] + _PathOffset[index] + timeOffset);
					
					if (_PathSegments[index])
					{
						float pathSegments = abs(_PathSegments[index]);
						pathTime = (ceil(pathTime * pathSegments) - .5) / pathSegments;
					}
					
					if (path[index])
					{
						// Cutting it in half because it goes out in both directions for now
						half pathWidth = _PathWidth[index] * .5;
						#ifdef POI_AUDIOLINK
						UNITY_BRANCH
						if (poiMods.audioLinkAvailable)
						{
							if (_PathALWidthOffset)
							{
								pathWidth += lerp(pathAudioLinkWidthOffset[index].x, pathAudioLinkWidthOffset[index].y, poiMods.audioLink[pathAudioLinkPathWidthOffsetBand[index]]);
							}
						}
						#endif
						
						//fill
						pathAlpha[index].x = pathTime[index] > path[index];
						//path
						pathAlpha[index].y = saturate((1 - abs(lerp(-pathWidth, 1 + pathWidth, pathTime[index]) - path[index])) - (1 - pathWidth)) * (1 / pathWidth);
						//loop
						pathAlpha[index].z = saturate((1 - distance(pathTime[index], path[index])) - (1 - pathWidth)) * (1 / pathWidth);
						pathAlpha[index].z += saturate(distance(pathTime[index], path[index]) - (1 - pathWidth)) * (1 / pathWidth);
						pathAlpha[index] = smoothstep(0, _PathSoftness[index] + .00001, pathAlpha[index]);
						
						#ifdef POI_AUDIOLINK
						if (poiMods.audioLinkAvailable)
						{
							if (_PathALHistory && history[index][0])
							{
								// history[index]: [0]: on/off, [1]: band, [2]/[3] min/max
								float historyUV = lerp(history[index][2], history[index][3], path[index]);
								
								if (_PathSegments[index])
								{
									float pathSegments = abs(_PathSegments[index]);
									historyUV = (ceil(historyUV * pathSegments) - .5) / pathSegments;
								}
								
								historyUV *= AUDIOLINK_WIDTH;
								
								float historyValue = AudioLinkLerp(ALPASS_AUDIOLINK + float2(historyUV, history[index][1]))[0];
								
								if(_PathALHistoryMode == 0) // Mask
								pathAlpha[index] *= historyValue;
								else // Override
								pathAlpha[index] = historyValue;
							}
							
							if (_PathALAutoCorrelator && autoCorrelator[index][0] != 0)
							{
								// autoCorrelator[index]: [0]: on/off, [1]/[2]: min/max
								// Choose from only part of the autocorrelator
								float autoCorrelatorUV = lerp(autoCorrelator[index][1], autoCorrelator[index][2], path[index]);
								if (autoCorrelator[index][0] == 2) // Mirror
								{
									autoCorrelatorUV = abs(1. - autoCorrelatorUV * 2.);
								}
								
								if (_PathSegments[index])
								{
									float pathSegments = abs(_PathSegments[index]);
									autoCorrelatorUV = (ceil(autoCorrelatorUV * pathSegments) - .5) / pathSegments;
								}
								
								// Normalize Autocorrelator Value
								float autoCorrelatorValue = AudioLinkLerp(ALPASS_AUTOCORRELATOR + float2(autoCorrelatorUV * AUDIOLINK_WIDTH, 0))[0];
								float autoCorrelatorMax = AudioLinkLerp(ALPASS_AUTOCORRELATOR);
								autoCorrelatorValue = saturate(abs(autoCorrelatorValue) * rcp(autoCorrelatorMax));
								
								// Autocorrelator is normalized, so can look weird at lower volume levels. use Filtered VU intensity to make it smoothly fall off at low volume levels.
								float4 vu = AudioLinkData(ALPASS_FILTEREDVU_INTENSITY + uint2(0, 0));
								autoCorrelatorValue *= smoothstep(0.01, 0.2, vu);
								
								if(_PathALAutoCorrelatorMode == 0) // Mask
								pathAlpha[index] *= autoCorrelatorValue;
								else // Override
								pathAlpha[index] = autoCorrelatorValue;
								
							}
						}
						#endif
					}
				}
				
				// Emission
				pathEmission = 0;
				pathEmission += pathAlpha[0][_PathTypeR] * poiThemeColor(poiMods, PathColor[0].rgb, _PathColorRThemeIndex) * (_PathEmissionStrength[0] + pathAudioLinkEmission.r);
				pathEmission += pathAlpha[1][_PathTypeG] * poiThemeColor(poiMods, PathColor[1].rgb, _PathColorGThemeIndex) * (_PathEmissionStrength[1] + pathAudioLinkEmission.g);
				pathEmission += pathAlpha[2][_PathTypeB] * poiThemeColor(poiMods, PathColor[2].rgb, _PathColorBThemeIndex) * (_PathEmissionStrength[2] + pathAudioLinkEmission.b);
				pathEmission += pathAlpha[3][_PathTypeA] * poiThemeColor(poiMods, PathColor[3].rgb, _PathColorAThemeIndex) * (_PathEmissionStrength[3] + pathAudioLinkEmission.a);
				pathEmission *= pathColorMap.rgb * pathColorMap.a;
				
				float3 colorReplace = 0;
				colorReplace = pathAlpha[0][_PathTypeR] * poiThemeColor(poiMods, PathColor[0].rgb, _PathColorRThemeIndex) * pathColorMap.rgb;
				albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * PathColor[0].a * pathAlpha[0][_PathTypeR]);
				colorReplace = pathAlpha[1][_PathTypeG] * poiThemeColor(poiMods, PathColor[1].rgb, _PathColorGThemeIndex) * pathColorMap.rgb;
				albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * PathColor[1].a * pathAlpha[1][_PathTypeG]);
				colorReplace = pathAlpha[2][_PathTypeB] * poiThemeColor(poiMods, PathColor[2].rgb, _PathColorBThemeIndex) * pathColorMap.rgb;
				albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * PathColor[2].a * pathAlpha[2][_PathTypeB]);
				colorReplace = pathAlpha[3][_PathTypeA] * poiThemeColor(poiMods, PathColor[3].rgb, _PathColorAThemeIndex) * pathColorMap.rgb;
				albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * PathColor[3].a * pathAlpha[3][_PathTypeA]);
				
				float alpha = max(max(max(pathAlpha[0][_PathTypeR], pathAlpha[1][_PathTypeG]), pathAlpha[2][_PathTypeB]), pathAlpha[3][_PathTypeA]);
				
				poiFragData.alpha *= lerp(1, alpha, _PathingOverrideAlpha);
				poiFragData.baseColor = albedo.rgb;
				poiFragData.emission += pathEmission;
			}
			#endif
			//endex
			
			//ifex _EnableMirrorOptions==0
			#ifdef POI_MIRROR
			void applyMirror(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float inMirror = 0;
				// VRC
				if (_VisibilityMode == 1)
				{
					inMirror = VRCMirrorMode() > 0;
				}
				// Generic (CVR, etc)
				else
				{
					inMirror = IsInMirror();
				}
				
				#if (defined(POI_PASS_BASE) || defined(POI_PASS_ADD))
				#if defined(PROP_MIRRORTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 mirrorTexture = POI2D_SAMPLER_PAN(_MirrorTexture, _MainTex, poiUV(poiMesh.uv[_MirrorTextureUV], _MirrorTexture_ST), _MirrorTexturePan);
				if (inMirror && _MirrorTextureEnabled || _MirrorTextureForceEnabled)
				{
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, mirrorTexture.rgb, _MirrorTextureBlendType), mirrorTexture.a * _MirrorColor.a);
					poiFragData.baseColor.rgb *= lerp(1, poiThemeColor(poiMods, _MirrorColor.rgb, _MirrorColorThemeIndex), _MirrorColor.a);
				}
				#else
				if (inMirror && _MirrorTextureEnabled || _MirrorTextureForceEnabled)
				{
					poiFragData.baseColor.rgb *= lerp(1, poiThemeColor(poiMods, _MirrorColor.rgb, _MirrorColorThemeIndex), _MirrorColor.a);
				}
				#endif
				#endif
			}
			#endif
			//endex
			
			//ifex _EnableTouchGlow==0
			#ifdef GRAIN
			void applyDepthFX(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float3 touchEmission = 0;
				
				float perspectiveDivide = 1.0f / poiCam.clipPos.w;
				float4 direction = poiCam.worldDirection * perspectiveDivide;
				float2 screenPos = poiCam.posScreenSpace * perspectiveDivide;
				float z = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, screenPos);
				
				#if UNITY_REVERSED_Z
				if (z == 0)
				#else
				if (z == 1)
				#endif
				return;
				
				float depth = CorrectedLinearEyeDepth(z, direction.w);
				float3 worldpos = direction * depth + _WorldSpaceCameraPos.xyz;
				/*
				finalColor.rgb = frac(worldpos);
				return;
				*/
				
				float diff = distance(worldpos, poiMesh.worldPos);
				//poiFragData.finalColor = diff;
				
				#if defined(PROP_DEPTHMASK) || !defined(OPTIMIZER_ENABLED)
				float depthMask = POI2D_SAMPLER_PAN(_DepthMask, _MainTex, poiUV(poiMesh.uv[_DepthMaskUV], _DepthMask_ST), _DepthMaskPan)[_DepthMaskChannel];
				#else
				float depthMask = 1;
				#endif
				
				if (_DepthMaskGlobalMask > 0)
				{
					depthMask = maskBlend(depthMask, poiMods.globalMask[_DepthMaskGlobalMask - 1], _DepthMaskGlobalMaskBlendType);
				}
				
				if (_DepthColorToggle)
				{
					float colorBlendAlpha = lerp(_DepthColorMinValue, _DepthColorMaxValue, remapClamped(_DepthColorMinDepth, _DepthColorMaxDepth, diff));
					
					#if defined(PROP_DEPTHTEXTURE) || !defined(OPTIMIZER_ENABLED)
					float2 depthTextureUV = float2(0, 0);
					if (_DepthTextureUV == 8)
					{
						depthTextureUV = lerp(0, 1, remapClamped(_DepthColorMinDepth, _DepthColorMaxDepth, diff));
					}
					else
					{
						depthTextureUV = poiMesh.uv[_DepthTextureUV];
					}
					float3 depthColor = POI2D_SAMPLER_PAN(_DepthTexture, _MainTex, poiUV(depthTextureUV, _DepthTexture_ST), _DepthTexturePan).rgb * poiThemeColor(poiMods, _DepthColor, _DepthColorThemeIndex);
					#else
					float3 depthColor = poiThemeColor(poiMods, _DepthColor, _DepthColorThemeIndex);
					#endif
					
					switch(_DepthColorBlendMode)
					{
						case 0:
						{
							poiFragData.baseColor = lerp(poiFragData.baseColor, depthColor, colorBlendAlpha * depthMask);
							break;
						}
						case 1:
						{
							poiFragData.baseColor *= lerp(1, depthColor, colorBlendAlpha * depthMask);
							break;
						}
						case 2:
						{
							poiFragData.baseColor = saturate(poiFragData.baseColor + lerp(0, depthColor, colorBlendAlpha * depthMask));
							break;
						}
					}
					poiFragData.emission += depthColor * colorBlendAlpha * _DepthEmissionStrength * depthMask;
				}
				
				if (_DepthAlphaToggle)
				{
					poiFragData.alpha *= lerp(poiFragData.alpha, saturate(lerp(_DepthAlphaMinValue, _DepthAlphaMaxValue, remapClamped(_DepthAlphaMinDepth, _DepthAlphaMaxDepth, diff))), depthMask);
				}
			}
			#endif
			//endex
			
			//ifex _TextEnabled==0
			#ifdef EFFECT_BUMP
			
			float2 TransformUV(float2 offset, float rotation, float2 scale, float2 uv)
			{
				float theta = radians(rotation);
				scale = 1 - scale;
				float cs = cos(theta);
				float sn = sin(theta);
				float2 centerPoint = offset + .5;
				uv = float2((uv.x - centerPoint.x) * cs - (uv.y - centerPoint.y) * sn + centerPoint.x, (uv.x - centerPoint.x) * sn + (uv.y - centerPoint.y) * cs + centerPoint.y);
				
				return remap(uv, float2(0, 0) + offset + (scale * .5), float2(1, 1) + offset - (scale * .5), float2(0, 0), float2(1, 1));
			}
			
			float2 getAsciiCoordinate(float index)
			{
				return float2((index - 1) / 16, 1 - ((floor(index / 16 - glyphWidth)) / 16));
			}
			
			float median(float r, float g, float b)
			{
				return max(min(r, g), min(max(r, g), b));
			}
			
			void ApplyPositionText(inout PoiFragData poiFragData, float2 uv, in PoiMods poiMods)
			{
				float3 cameraPos = clamp(getCameraPosition(), -999, 999);
				float3 absCameraPos = abs(cameraPos);
				float totalCharacters = 20;
				float positionArray[20];
				positionArray[0] = cameraPos.x >= 0 ? ASCII_NEGATIVE : ASCII_POSITIVE;
				positionArray[1] = floor((absCameraPos.x * .01) % 10) + 48;
				positionArray[2] = floor((absCameraPos.x * .1) % 10) + 48;
				positionArray[3] = floor(absCameraPos.x % 10) + 48;
				positionArray[4] = ASCII_PERIOD;
				positionArray[5] = floor((absCameraPos.x * 10) % 10) + 48;
				positionArray[6] = ASCII_COMMA;
				positionArray[7] = cameraPos.y >= 0 ? ASCII_NEGATIVE : ASCII_POSITIVE;
				positionArray[8] = floor((absCameraPos.y * .01) % 10) + 48;
				positionArray[9] = floor((absCameraPos.y * .1) % 10) + 48;
				positionArray[10] = floor(absCameraPos.y % 10) + 48;
				positionArray[11] = ASCII_PERIOD;
				positionArray[12] = floor((absCameraPos.y * 10) % 10) + 48;
				positionArray[13] = ASCII_COMMA;
				positionArray[14] = cameraPos.z >= 0 ? ASCII_NEGATIVE : ASCII_POSITIVE;
				positionArray[15] = floor((absCameraPos.z * .01) % 10) + 48;
				positionArray[16] = floor((absCameraPos.z * .1) % 10) + 48;
				positionArray[17] = floor(absCameraPos.z % 10) + 48;
				positionArray[18] = ASCII_PERIOD;
				positionArray[19] = floor((absCameraPos.z * 10) % 10) + 48;
				
				uv = TransformUV(_TextPositionOffset, _TextPositionRotation, _TextPositionScale, uv);
				
				if (uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
				{
					return;
				}
				
				float currentCharacter = floor(uv.x * totalCharacters);
				float2 glyphPos = getAsciiCoordinate(positionArray[currentCharacter]);
				
				float2 startUV = float2(1 / totalCharacters * currentCharacter, 0);
				float2 endUV = float2(1 / totalCharacters * (currentCharacter + 1), 1);
				
				fixed4 textPositionPadding = _TextPositionPadding;
				textPositionPadding *= 1 / totalCharacters;
				
				uv = remapClamped(startUV, endUV, uv, float2(glyphPos.x + textPositionPadding.x, glyphPos.y - glyphWidth + textPositionPadding.y), float2(glyphPos.x + glyphWidth - textPositionPadding.z, glyphPos.y - textPositionPadding.w));
				
				if (uv.x > glyphPos.x + glyphWidth - textPositionPadding.z - .001 || uv.x < glyphPos.x + textPositionPadding.x + .001 || uv.y > glyphPos.y - textPositionPadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textPositionPadding.y + .001)
				{
					return;
				}
				
				float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
				float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
				float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
				sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
				float opacity = clamp(sigDist + 0.5, 0, 1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, poiThemeColor(poiMods, _TextPositionColor.rgb, _TextPositionColorThemeIndex), opacity * _TextPositionColor.a);
				globalTextEmission += poiThemeColor(poiMods, _TextPositionColor.rgb, _TextPositionColorThemeIndex) * opacity * _TextPositionEmissionStrength;
			}
			
			void ApplyTimeText(inout PoiFragData poiFragData, float2 uv, in PoiMods poiMods)
			{
				float instanceTime = _Time.y;
				float hours = instanceTime / 3600;
				float minutes = (instanceTime / 60) % 60;
				float seconds = instanceTime % 60;
				float totalCharacters = 8;
				float timeArray[8];
				timeArray[0] = floor((hours * .1) % 10) + 48;
				timeArray[1] = floor(hours % 10) + 48;
				timeArray[2] = ASCII_SEMICOLON;
				timeArray[3] = floor((minutes * .1) % 10) + 48;
				timeArray[4] = floor(minutes % 10) + 48;
				timeArray[5] = ASCII_SEMICOLON;
				timeArray[6] = floor((seconds * .1) % 10) + 48;
				timeArray[7] = floor(seconds % 10) + 48;
				
				uv = TransformUV(_TextTimeOffset, _TextTimeRotation, _TextTimeScale, uv);
				
				if (uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
				{
					return;
				}
				
				float currentCharacter = floor(uv.x * totalCharacters);
				float2 glyphPos = getAsciiCoordinate(timeArray[currentCharacter]);
				// 0.1428571 = 1/7 = 1 / totalCharacters
				float startUV = 1 / totalCharacters * currentCharacter;
				float endUV = 1 / totalCharacters * (currentCharacter + 1);
				
				fixed4 textTimePadding = _TextTimePadding;
				textTimePadding *= 1 / totalCharacters;
				
				uv = remapClamped(float2(startUV, 0), float2(endUV, 1), uv, float2(glyphPos.x + textTimePadding.x, glyphPos.y - glyphWidth + textTimePadding.y), float2(glyphPos.x + glyphWidth - textTimePadding.z, glyphPos.y - textTimePadding.w));
				
				if (uv.x > glyphPos.x + glyphWidth - textTimePadding.z - .001 || uv.x < glyphPos.x + textTimePadding.x + .001 || uv.y > glyphPos.y - textTimePadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textTimePadding.y + .001)
				{
					return;
				}
				
				float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
				float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
				float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
				sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
				float opacity = clamp(sigDist + 0.5, 0, 1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, poiThemeColor(poiMods, _TextTimeColor.rgb, _TextTimeColorThemeIndex), opacity * _TextTimeColor.a);
				globalTextEmission += poiThemeColor(poiMods, _TextTimeColor.rgb, _TextTimeColorThemeIndex) * opacity * _TextTimeEmissionStrength;
			}
			
			void ApplyFPSText(inout PoiFragData poiFragData, float2 uv, in PoiMods poiMods)
			{
				float smoothDeltaTime = clamp(unity_DeltaTime.w, 0, 999);
				float totalCharacters = 7;
				float fpsArray[7];
				fpsArray[0] = ASCII_F;
				fpsArray[1] = ASCII_P;
				fpsArray[2] = ASCII_S;
				fpsArray[3] = ASCII_SEMICOLON;
				fpsArray[4] = floor((smoothDeltaTime * .01) % 10) + 48;
				fpsArray[5] = floor((smoothDeltaTime * .1) % 10) + 48;
				fpsArray[6] = floor(smoothDeltaTime % 10) + 48;
				
				uv = TransformUV(_TextFPSOffset, _TextFPSRotation, _TextFPSScale, uv);
				
				if (uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
				{
					return;
				}
				
				float currentCharacter = floor(uv.x * totalCharacters);
				float2 glyphPos = getAsciiCoordinate(fpsArray[currentCharacter]);
				// 0.1428571 = 1/7 = 1 / totalCharacters
				float startUV = 1 / totalCharacters * currentCharacter;
				float endUV = 1 / totalCharacters * (currentCharacter + 1);
				
				float4 textFPSPadding = _TextFPSPadding;
				textFPSPadding *= 1 / totalCharacters;
				
				uv = remapClamped(float2(startUV, 0), float2(endUV, 1), uv, float2(glyphPos.x + textFPSPadding.x, glyphPos.y - glyphWidth + textFPSPadding.y), float2(glyphPos.x + glyphWidth - textFPSPadding.z, glyphPos.y - textFPSPadding.w));
				
				if (uv.x > glyphPos.x + glyphWidth - textFPSPadding.z - .001 || uv.x < glyphPos.x + textFPSPadding.x + .001 || uv.y > glyphPos.y - textFPSPadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textFPSPadding.y + .001)
				{
					return;
				}
				
				float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
				float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
				float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
				sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
				float opacity = clamp(sigDist + 0.5, 0, 1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, poiThemeColor(poiMods, _TextFPSColor.rgb, _TextFPSColorThemeIndex), opacity * _TextFPSColor.a);
				globalTextEmission += poiThemeColor(poiMods, _TextFPSColor.rgb, _TextFPSColorThemeIndex) * opacity * _TextFPSEmissionStrength;
			}
			
			void ApplyNumericText(inout PoiFragData poiFragData, float2 uv, in PoiMods poiMods)
			{
				// If both digits are set to zero: exit.
				if (_TextNumericWholeDigits == 0 && _TextNumericDecimalDigits == 0)
				{
					return;
				}
				
				uint wholeNumber = 0;
				uint decimalNumber = 0;
				uint wholeDigits = _TextNumericWholeDigits;
				uint decimalDigits = _TextNumericDecimalDigits;
				float NumericArray[10];										// 10 is the max amount of characters = 1 sign + 4 max whole digits + 1 decimal mark + 4 max decimal digits
				uint arrayIndex = 0;
				float totalCharacters = 1 + wholeDigits + decimalDigits; 	// Sign Character + Whole Digits + Decimal Digits
				
				//Determine Sign (_TextNumericValue is usually animated)
				float charSign = _TextNumericValue >= 0 ? ASCII_SPACE : ASCII_NEGATIVE;
				
				NumericArray[arrayIndex] = charSign;						//First character is always the sign
				arrayIndex++;
				
				//Isolate whole number and fill array
				if (wholeDigits > 0)
				{
					wholeNumber = uint(glsl_mod(abs(_TextNumericValue), pow(10, wholeDigits)));
					
					int expIndex = -1 * (wholeDigits - 1);  // Exponent Index
					bool leadingZero = true;
					// Pouplate the Array
					while (arrayIndex <= wholeDigits)
					{
						// Grab the corresponding digit from the whole number going from left to right.
						int digit = floor(glsl_mod(wholeNumber * pow(10, expIndex), 10));
						// Take the resulting value and add 48 to get the corresponding location in the font array.
						NumericArray[arrayIndex] = digit + 48;
						
						//Trim Leading Zeroes, but leave at least one.
						if (_TextNumericTrimZeroes == true)
						{
							//If the digit is zero and there hasn't been any digits greater than 0 previously.
							if (digit == 0 && leadingZero == true && arrayIndex != wholeDigits)
							{
								//Overwrite the leading zero.
								NumericArray[arrayIndex] = ASCII_SPACE;
							}
							else
							{
								leadingZero = false;
							}
						}
						expIndex++;
						arrayIndex++;
					}
				}
				
				// Isolate decimal number and fill array
				if (decimalDigits > 0)
				{
					// Add a decimal point
					NumericArray[arrayIndex] = ASCII_PERIOD;
					int decimalPointer = arrayIndex;
					arrayIndex++;
					totalCharacters++;
					
					decimalNumber = uint(frac(abs(_TextNumericValue)) * pow(10.00001, decimalDigits));    // Isolate the decimal number
					
					int expIndex = -1 * (decimalDigits - 1);                                          // Exponent Index
					//Populate the Array with the remaining digits
					while (arrayIndex < (uint)(totalCharacters))
					{
						// Grab the corresponding digit from the whole number going from left to right.
						int digit = floor(glsl_mod(decimalNumber * pow(10, expIndex), 10));
						// Take the resulting value and add 48 to get the corresponding location in the font array.
						NumericArray[arrayIndex] = digit + 48;
						
						expIndex++;
						arrayIndex++;
					}
				}
				
				uv = TransformUV(_TextNumericOffset, _TextNumericRotation, _TextNumericScale, uv);
				
				if (uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
				{
					return;
				}
				
				float currentCharacter = floor(uv.x * totalCharacters);
				float2 glyphPos = getAsciiCoordinate(NumericArray[currentCharacter]);
				float startUV = 1 / totalCharacters * currentCharacter;
				float endUV = 1 / totalCharacters * (currentCharacter + 1);
				
				float4 textNumericPadding = _TextNumericPadding;
				textNumericPadding *= 1 / totalCharacters;
				
				uv = remapClamped(float2(startUV, 0), float2(endUV, 1), uv, float2(glyphPos.x + textNumericPadding.x, glyphPos.y - glyphWidth + textNumericPadding.y), float2(glyphPos.x + glyphWidth - textNumericPadding.z, glyphPos.y - textNumericPadding.w));
				
				if (uv.x > glyphPos.x + glyphWidth - textNumericPadding.z - .001 || uv.x < glyphPos.x + textNumericPadding.x + .001 || uv.y > glyphPos.y - textNumericPadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textNumericPadding.y + .001)
				{
					return;
				}
				
				float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
				float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
				float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
				sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
				float opacity = clamp(sigDist + 0.5, 0, 1);
				poiFragData.baseColor = lerp(poiFragData.baseColor, poiThemeColor(poiMods, _TextNumericColor.rgb, _TextNumericColorThemeIndex), opacity * _TextNumericColor.a);
				globalTextEmission += poiThemeColor(poiMods, _TextNumericColor.rgb, _TextNumericColorThemeIndex) * opacity * _TextNumericEmissionStrength;
			}
			
			void ApplyTextOverlayColor(inout PoiFragData poiFragData, PoiMesh poiMesh, in PoiMods poiMods)
			{
				globalTextEmission = 0;
				float positionalOpacity = 0;
				
				if (_TextFPSEnabled == 1)
				ApplyFPSText(poiFragData, poiMesh.uv[_TextFPSUV], poiMods);
				if (_TextPositionEnabled == 1)
				ApplyPositionText(poiFragData, poiMesh.uv[_TextPositionUV], poiMods);
				if (_TextTimeEnabled == 1)
				ApplyTimeText(poiFragData, poiMesh.uv[_TextTimeUV], poiMods);
				if (_TextNumericEnabled == 1)
				ApplyNumericText(poiFragData, poiMesh.uv[_TextNumericUV], poiMods);
				
				poiFragData.emission += globalTextEmission;
			}
			#endif
			//endex
			
			//ifex _PostProcess==0
			#ifdef POSTPROCESS
			float3 poiPosterize(float3 color, float steps)
			{
				float3 newColor = RGBtoHSV(color);
				steps = floor(steps);
				newColor.r = floor(newColor.r * steps) / steps;
				newColor.g = floor(newColor.g * steps) / steps;
				newColor.b = floor(newColor.b * steps) / steps;
				return HSVtoRGB(newColor);
			}
			
			float oetf_sRGB_scalar(float L)
			{
				float V = 1.055 * (pow(L, 1.0 / 2.4)) - 0.055;
				if (L <= 0.0031308)
				V = L * 12.92;
				return V;
			}
			
			float3 oetf_sRGB(float3 L)
			{
				return float3(oetf_sRGB_scalar(L.r), oetf_sRGB_scalar(L.g), oetf_sRGB_scalar(L.b));
			}
			
			float eotf_sRGB_scalar(float V)
			{
				float L = pow((V + 0.055) / 1.055, 2.4);
				if (V <= oetf_sRGB_scalar(0.0031308))
				L = V / 12.92;
				return L;
			}
			
			float3 GetHDR(float3 rgb)
			{
				return float3(eotf_sRGB_scalar(rgb.r), eotf_sRGB_scalar(rgb.g), eotf_sRGB_scalar(rgb.b));
			}
			
			float3 GetContrast(float3 col, float contrast)
			{
				return lerp(float3(0.5, 0.5, 0.5), col, contrast);
			}
			
			float3 GetSaturation(float3 col, float interpolator)
			{
				return lerp(dot(col, float3(0.3, 0.59, 0.11)), col, interpolator);
			}
			
			void applyPostProcessing(inout PoiFragData poiFragData, in PoiMesh poiMesh)
			{
				float3 col = poiFragData.finalColor;
				col = hueShift(col, _PPHue);
				col *= _PPTint;
				col *= _PPRGB;
				col = GetSaturation(col, _PPSaturation);
				col = lerp(col, GetHDR(col), _PPHDR);
				col = GetContrast(col, _PPContrast);
				col *= _PPBrightness;
				col += _PPLightness;
				
				float ppMask = 1;
				#if defined(PROP_PPMASK) || !defined(OPTIMIZER_ENABLED)
				ppMask = POI2D_SAMPLER_PAN(_PPMask, _MainTex, poiUV(poiMesh.uv[_PPMaskUV], _PPMask_ST), _PPMaskPan)[_PPMaskChannel];
				ppMask = lerp(ppMask, 1 - ppMask, _PPMaskInvert);
				col = lerp(poiFragData.finalColor, col, ppMask);
				#endif
				
				if (_PPPosterization)
				{
					col = lerp(col, poiPosterize(col, _PPPosterizationAmount), ppMask);
				}
				
				poiFragData.finalColor = col;
			}
			#endif
			//endex
			
			// normal correct code from https://github.com/yoship1639/UniToon (MIT)
			//ifex _NormalCorrect==0
			#ifdef POI_NORMALCORRECT
			void applyNormalCorrect(inout VertexOut i)
			{
				float3 normalCorrectObject = i.localPos.xyz - _NormalCorrectOrigin;
				normalCorrectObject.y = 0;
				normalCorrectObject = normalize(normalCorrectObject);
				float3 normalCorrectWorld = UnityObjectToWorldDir(normalCorrectObject);
				i.normal.xyz = normalize(lerp(i.normal.xyz, normalCorrectWorld, _NormalCorrectAmount));
				//i.objNormal.xyz = normalize(lerp(i.objNormal.xyz, normalCorrectObject, _NormalCorrectAmount));
			}
			#endif
			//endex
			
			//ifex _VideoEffectsEnable==0
			#ifdef POI_VIDEO_EFFECTS
			float3 applyBacklight(float3 videoTexture, half backlightStrength)
			{
				return max(backlightStrength, videoTexture.rgb);
			}
			
			float3 applyViewAngleTN(float3 videoTexture, PoiCam poiCam, PoiMesh poiMesh)
			{
				float3 reflectionVector = normalize(reflect(poiCam.viewDir.rgb, poiMesh.normals[1].rgb));
				float upwardShift = dot(reflectionVector, poiMesh.binormal[0]);
				upwardShift = pow(upwardShift, 1);
				float sideShift = dot(reflectionVector, poiMesh.tangent[0]);
				sideShift *= pow(sideShift, 3);
				#if !UNITY_COLORSPACE_GAMMA
				videoTexture = LinearToGammaSpace(videoTexture);
				#endif
				videoTexture = saturate(lerp(half3(0.5, 0.5, 0.5), videoTexture, upwardShift + 1));
				#if !UNITY_COLORSPACE_GAMMA
				videoTexture = GammaToLinearSpace(videoTexture);
				#endif
				videoTexture = (lerp(videoTexture, videoTexture.gbr, sideShift));
				return videoTexture;
			}
			
			float calculateCRTPixelBrightness(float2 uv)
			{
				float totalPixels = _VideoResolution.x * _VideoResolution.y;
				float2 uvPixel = float2((floor((1 - uv.y) * _VideoResolution.y)) / _VideoResolution.y, (floor(uv.x * _VideoResolution.x)) / _VideoResolution.x);
				float currentPixelNumber = _VideoResolution.x * (_VideoResolution.y * uvPixel.x) + _VideoResolution.y * uvPixel.y;
				float currentPixelAlpha = currentPixelNumber / totalPixels;
				half electronBeamAlpha = frac(_Time.y * _VideoCRTRefreshRate);
				float electronBeamPixelNumber = totalPixels * electronBeamAlpha;
				
				float DistanceInPixelsFromCurrentElectronBeamPixel = 0;
				if (electronBeamPixelNumber >= currentPixelNumber)
				{
					DistanceInPixelsFromCurrentElectronBeamPixel = electronBeamPixelNumber - currentPixelNumber;
				}
				else
				{
					DistanceInPixelsFromCurrentElectronBeamPixel = electronBeamPixelNumber + (totalPixels - currentPixelNumber);
				}
				float CRTFrameTime = 1 / _VideoCRTRefreshRate;
				float timeSincecurrentPixelWasHitByElectronBeam = (DistanceInPixelsFromCurrentElectronBeamPixel / totalPixels);
				
				return saturate(_VideoCRTPixelEnergizedTime - timeSincecurrentPixelWasHitByElectronBeam);
			}
			
			void applyContrastSettings(inout float3 pixel)
			{
				#if !UNITY_COLORSPACE_GAMMA
				pixel = LinearToGammaSpace(pixel);
				#endif
				pixel = saturate(lerp(half3(0.5, 0.5, 0.5), pixel, _VideoContrast + 1));
				#if !UNITY_COLORSPACE_GAMMA
				pixel = GammaToLinearSpace(pixel);
				#endif
			}
			
			void applySaturationSettings(inout float3 pixel)
			{
				pixel = lerp(pixel.rgb, dot(pixel.rgb, float3(0.3, 0.59, 0.11)), - (_VideoSaturation));
			}
			
			void applyVideoSettings(inout float3 pixel)
			{
				applySaturationSettings(pixel);
				applyContrastSettings(pixel);
			}
			
			void calculateLCD(inout float4 videoTexture, float3 pixels)
			{
				videoTexture.rgb = applyBacklight(videoTexture, _VideoBacklight * .01);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateTN(inout float4 videoTexture, float3 pixels, PoiCam poiCam, PoiMesh poiMesh)
			{
				videoTexture.rgb = applyBacklight(videoTexture, _VideoBacklight * .01);
				videoTexture.rgb = applyViewAngleTN(videoTexture, poiCam, poiMesh);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateCRT(inout float4 videoTexture, float3 pixels, float2 uv)
			{
				float brightness = calculateCRTPixelBrightness(uv);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * brightness * _VideoBacklight;
			}
			void calculateOLED(inout float4 videoTexture, float3 pixels)
			{
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateGameboy(inout float4 videoTexture)
			{
				applyVideoSettings(videoTexture.rgb);
				// half brightness = saturate((videoTexture.r + videoTexture.g + videoTexture.b) * .3333333);
				half brightness = LinearRgbToLuminance(LinearToGammaSpace(videoTexture.rgb));
				#if defined(PROP_VIDEOGAMEBOYRAMP) || !defined(OPTIMIZER_ENABLED)
				videoTexture.rgb = tex2Dlod(_VideoGameboyRamp, float4(brightness.xx, 0, 0));
				#else
				float3 dg = float3(0.00392156863, 0.0392156863, 0.00392156863);
				float3 lg = float3(0.333333333, 0.5, 0.00392156863);
				videoTexture.rgb = lerp(dg, lg, brightness);
				#endif
			}
			void calculateProjector(inout float4 videoTexture)
			{
				applyVideoSettings(videoTexture.rgb);
				
				float3 projectorColor = videoTexture * _VideoBacklight;
				videoTexture.r = clamp(projectorColor.r, videoTexture.r, 1000);
				videoTexture.g = clamp(projectorColor.g, videoTexture.g, 1000);
				videoTexture.b = clamp(projectorColor.b, videoTexture.b, 1000);
			}
			
			void applyVideoEffectsMainTex(inout float4 mainTexture, in PoiMesh poiMesh)
			{
				float2 uvs = poiMesh.uv[_MainTexUV];
				if (_VideoPixelateToResolution)
				{
					float2 originalUVs = uvs;
					uvs = sharpSample(float4(1 / _VideoResolution.xy, _VideoResolution.xy), uvs);
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
					mainTexture = _MainTex.SampleGrad(sampler_MainTex, uvs, ddx(originalUVs), ddy(originalUVs));
				}
			}
			void applyVideoEffects(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, in PoiLight poiLight, in PoiMods poiMods)
			{
				#if defined(PROP_VIDEOPIXELTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float3 pixels = tex2D(_VideoPixelTexture, poiUV(poiMesh.uv[_VideoPixelTextureUV], _VideoPixelTexture_ST) * _VideoResolution);
				#else
				float3 pixels = 1;
				#endif
				float2 uvs = poiMesh.uv[_MainTexUV];
				if (_VideoPixelateToResolution)
				{
					uvs = sharpSample(float4(1 / _VideoResolution.xy, _VideoResolution.xy), uvs);
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
				}
				else
				{
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
				}
				float4 modifiedVideoTexture = 0;
				modifiedVideoTexture.rgb = poiFragData.baseColor;
				modifiedVideoTexture.a = poiFragData.alpha;
				
				// UNITY_BRANCH
				// if(_VideoRepeatVideoTexture == 1)
				// {
				// 	if(poiMesh.uv[_VideoUVNumber].x > 1 || poiMesh.uv[_VideoUVNumber].x < 0 || poiMesh.uv[_VideoUVNumber].y > 1 || poiMesh.uv[_VideoUVNumber].y < 0)
				// 	{
				// 		return;
				// 	}
				// }
				
				switch(_VideoType)
				{
					case 0: // LCD
					
					{
						calculateLCD(modifiedVideoTexture, pixels);
						break;
					}
					case 1: // TN
					
					{
						calculateTN(modifiedVideoTexture, pixels, poiCam, poiMesh);
						break;
					}
					case 2: // CRT
					
					{
						calculateCRT(modifiedVideoTexture, pixels, uvs);
						break;
					}
					case 3: // OLED
					
					{
						calculateOLED(modifiedVideoTexture, pixels);
						break;
					}
					case 4: // Gameboy
					
					{
						calculateGameboy(modifiedVideoTexture);
						break;
					}
					case 5: // Projector
					
					{
						calculateProjector(modifiedVideoTexture);
						break;
					}
				}
				#if defined(PROP_VIDEOMASKTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float screenMask = POI2D_SAMPLER_PAN(_VideoMaskTexture, _MainTex, poiUV(poiMesh.uv[_VideoMaskTextureUV], _VideoMaskTexture_ST), _VideoMaskTexturePan)[_VideoMaskTextureChannel];
				#else
				float screenMask = 1;
				#endif
				
				poiFragData.baseColor = lerp(poiFragData.baseColor, modifiedVideoTexture, screenMask);
				// UNITY_BRANCH
				if (_VideoEmissionEnabled)
				{
					poiFragData.emission += modifiedVideoTexture.rgb * screenMask;
				}
			}
			#endif
			//endex
			
			//ifex _BacklightEnabled!=1
			#ifdef POI_BACKLIGHT
			void ApplyBacklight(inout PoiFragData poiFragData, in PoiMesh poiMesh, inout PoiLight poiLight, in PoiCam poiCam, inout PoiMods poiMods)
			{
				
				// Color
				float3 backlightColor = _BacklightColor.rgb;
				#if defined(PROP_BACKLIGHTCOLORTEX) || !defined(OPTIMIZER_ENABLED)
				backlightColor *= POI2D_SAMPLER_PAN(_BacklightColorTex, _MainTex, poiUV(poiMesh.uv[_BacklightColorTexUV], _BacklightColorTex_ST), _BacklightColorTexPan).rgb;
				#endif
				
				float3 normal = lerp(poiMesh.normals[0], poiMesh.normals[1], _BacklightNormalStrength);
				// Factor
				float3 headDir = normalize(getCameraPosition() - poiMesh.worldPos.xyz);
				float headDotLight = dot(headDir, poiLight.direction);
				float backlightFactor = pow(saturate(-headDotLight * 0.5 + 0.5), max(0, _BacklightDirectivity));
				float backlightLN = dot(normalize(-headDir * _BacklightViewStrength + poiLight.direction), normal) * 0.5 + 0.5;
				#if defined(POINT) || defined(SPOT)
				if (_BacklightReceiveShadow) backlightLN *= saturate(poiLight.additiveShadow);
				#else
				if (_BacklightReceiveShadow) backlightLN *= saturate(poiLight.attenuation);
				#endif
				backlightLN = poiEdgeLinear(backlightLN, _BacklightBorder, _BacklightBlur);
				float backlight = saturate(backlightFactor * backlightLN);
				backlight = !poiMesh.isFrontFace && _BacklightBackfaceMask ? 0.0 : backlight;
				
				// Blend
				backlightColor = lerp(backlightColor, backlightColor * poiFragData.baseColor, _BacklightMainStrength);
				poiLight.finalLightAdd += backlight * backlightColor * poiLight.directColor;
			}
			#endif
			//endex
			
			//ifex _VoronoiEnabled!=1
			#ifdef POI_VORONOI
			//1/7
			#define VoronoiK 0.142857142857
			//3/7
			#define VoronoiKo 0.428571428571
			// Permutation polynomial: (34x^2 + x) mod 289
			float3 Permutation(float3 x)
			{
				return glsl_mod((34.0 * x + 1.0) * x, 289.0);
			}
			
			float3 inoise(float3 P, float jitter, out float3 randomPoint)
			{
				P *= 0.7f; // Scale adjustment
				float3 Pi = glsl_mod(floor(P), 289.0);
				float3 Pf = frac(P);
				float3 oi = float3(-1.0, 0.0, 1.0);
				float3 of = float3(-0.5, 0.5, 1.5);
				float3 px = Permutation(Pi.x + oi);
				float3 py = Permutation(Pi.y + oi);
				float3 pz = Permutation(Pi.z + oi);
				
				float3 p, ox, oy, oz, dx, dy, dz;
				float3 F = 1e6;
				
				[unroll(3)]
				for (int i = 0; i < 3; i++)
				{
					[unroll(3)]
					for (int j = 0; j < 3; j++)
					{
						[unroll(3)]
						for (int k = 0; k < 3; k++)
						{
							p = Permutation(px[i] + py[j] + pz[k] + oi); // pij1, pij2, pij3
							float3 ogp = p;
							
							ox = frac(p * VoronoiK) - VoronoiKo;
							oy = glsl_mod(floor(p * VoronoiK), 7.0) * VoronoiK - VoronoiKo;
							
							p = Permutation(p);
							oz = frac(p * VoronoiK) - VoronoiKo;
							
							dx = Pf.x - of[i] + jitter * ox;
							dy = Pf.y - of[j] + jitter * oy;
							dz = Pf.z - of[k] + jitter * oz;
							
							float3 d = dx * dx + dy * dy + dz * dz; // dij1, dij2 and dij3, squared
							
							//Find lowest and second lowest distances
							for (int n = 0; n < 3; n++)
							{
								if (d[n] < F[0])
								{
									F[1] = F[0];
									F[0] = d[n];
									randomPoint = p;
								}
								else if (d[n] < F[1])
								{
									F[1] = d[n];
								}
							}
						}
					}
				}
				
				return F;
			}
			
			float voronoi2D(in float2 x, float scale, float2 speed, out float2 randomPoint)
			{
				x *= scale;
				x += speed * _Time.x;
				float2 n = floor(x);
				float2 f = frac(x);
				
				// first pass: regular voronoi
				float2 mg, mr;
				float md = 8.0;
				for (int j = -1; j <= 1; j++)
				{
					for (int i = -1; i <= 1; i++)
					{
						float2 g = float2(float(i), float(j));
						float2 o = random2(n + g);
						float2 currentPoint = o;
						
						float2 r = g + o - f;
						float d = dot(r, r);
						
						if (d < md)
						{
							md = d;
							mr = r;
							mg = g;
							randomPoint.xy = currentPoint;
						}
					}
				}
				
				// second pass: distance to borders
				md = 8.0;
				for (int r = -2; r <= 2; r++)
				{
					for (int q = -2; q <= 2; q++)
					{
						float2 g = mg + float2(float(q), float(r));
						float2 o = random2(n + g);
						
						float2 r = g + o - f;
						
						if (dot(mr - r, mr - r) > 0.00001)
						{
							md = min(md, dot(0.5 * (mr + r), normalize(r - mr)));
						}
					}
				}
				return md;
			}
			
			float voronoi3D(in float3 x, float scale, float3 speed, out float3 randomPoint)
			{
				x *= scale;
				x += speed * _Time.x;
				float3 n = floor(x);
				float3 f = frac(x);
				
				// first pass: regular voronoi
				float3 mg, mr;
				float md = 8.0;
				for (int j = -1; j <= 1; j++)
				{
					for (int i = -1; i <= 1; i++)
					{
						for (int h = -1; h <= 1; h++)
						{
							float3 g = float3(float(h), float(i), float(j));
							float3 o = random3(n + g);
							float3 currentPoint = o;
							
							float3 r = g + o - f;
							float d = dot(r, r);
							
							if (d < md)
							{
								md = d;
								mr = r;
								mg = g;
								randomPoint = currentPoint;
							}
						}
					}
				}
				
				// second pass: distance to borders
				md = 8.0;
				for (int r = -2; r <= 2; r++)
				{
					for (int q = -2; q <= 2; q++)
					{
						for (int p = -2; p <= 2; p++)
						{
							float3 g = mg + float3(float(p), float(q), float(r));
							float3 o = random3(n + g);
							
							float3 r = g + o - f;
							
							if (dot(mr - r, mr - r) > 0.00001)
							{
								md = min(md, dot(0.5 * (mr + r), normalize(r - mr)));
							}
						}
					}
				}
				return md;
			}
			
			// fracal sum, range -1.0 - 1.0
			float VoronoiNoise_Octaves(float3 p, float scale, float3 speed, int octaveNumber, float octaveScale, float octaveAttenuation, float jitter, float time, out float3 randomPoint)
			{
				float freq = scale;
				float weight = 1.0f;
				float sum = 0;
				// Uncomment when the octave stuff is actually used
				// for (int i = 0; i < octaveNumber; i ++)
				// {
				float3 F = inoise(p * freq + time * speed, jitter, randomPoint) * weight;
				
				sum += sqrt(F[0]);
				
				// 	freq *= octaveScale;
				// 	weight *= 1.0f - octaveAttenuation;
				// }
				return sum;
			}
			
			float VoronoiNoiseDiff_Octaves(float3 p, float scale, float3 speed, int octaveNumber, float octaveScale, float octaveAttenuation, float jitter, float time, out float3 randomPoint)
			{
				float freq = scale;
				float weight = 1.0f;
				float sum = 0;
				// Uncomment when the octave stuff is actually used
				// for (int i = 0; i < octaveNumber; i ++)
				// {
				float3 F = inoise(p * freq + time * speed, jitter, randomPoint) * weight;
				
				sum += sqrt(F[1]) - sqrt(F[0]);
				
				// freq *= octaveScale;
				// weight *= 1.0f - octaveAttenuation;
				// }
				return sum;
			}
			
			void ApplyVoronoi(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float voronoiOctaveNumber = 1;
				float voronoiOctaveScale = 1;
				float voronoiOctaveAttenuation = 1;
				float3 randomPoint = 0;
				
				float voronoi = 0;
				
				float3 position = 0;
				
				UNITY_BRANCH
				if (_VoronoiSpace == 0)
				{
					position = poiMesh.localPos;
				}
				UNITY_BRANCH
				if (_VoronoiSpace == 1)
				{
					position = poiMesh.worldPos;
				}
				UNITY_BRANCH
				if (_VoronoiSpace == 2)
				{
					position = float3(poiMesh.uv[0].x, poiMesh.uv[0].y, 0);
				}
				#if defined(PROP_VORONOIMASK) || !defined(OPTIMIZER_ENABLED)
				float mask = POI2D_SAMPLER_PAN(_VoronoiMask, _MainTex, poiUV(poiMesh.uv[_VoronoiMaskUV], _VoronoiMask_ST), _VoronoiMaskPan)[_VoronoiMaskChannel];
				#else
				float mask = 1;
				#endif
				
				if (_VoronoiGlobalMask > 0)
				{
					mask = maskBlend(mask, poiMods.globalMask[_VoronoiGlobalMask - 1], _VoronoiGlobalMaskBlendType);
				}
				
				#if defined(PROP_VORONOINOISE) || !defined(OPTIMIZER_ENABLED)
				float edgeNoise = POI2D_SAMPLER_PAN(_VoronoiNoise, _MainTex, poiUV(poiMesh.uv[_VoronoiNoiseUV], _VoronoiNoise_ST), _VoronoiNoisePan)[_VoronoiNoiseChannel];
				#else
				float edgeNoise = 0;
				#endif
				edgeNoise *= _VoronoiNoiseIntensity;
				
				float3 voronoiSpeed = _VoronoiSpeed * 10;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					position.x += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedXType, _AudioLinkVoronoiChronoSpeedXBand) * _AudioLinkVoronoiChronoSpeedXSpeed * 0.01;
					position.y += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedYType, _AudioLinkVoronoiChronoSpeedYBand) * _AudioLinkVoronoiChronoSpeedYSpeed * 0.01;
					position.z += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedZType, _AudioLinkVoronoiChronoSpeedZBand) * _AudioLinkVoronoiChronoSpeedZSpeed * 0.01;
				}
				#endif
				
				if (_VoronoiType == 0) // Basic
				
				{
					voronoi = voronoi2D(position.xy, _VoronoiScale, voronoiSpeed, randomPoint.xy);
					voronoi *= 1.55; // Range adjustment
					
				}
				if (_VoronoiType == 1) // Diff
				
				{
					voronoi = VoronoiNoiseDiff_Octaves(position, _VoronoiScale, voronoiSpeed, voronoiOctaveNumber, voronoiOctaveScale, voronoiOctaveAttenuation, 1, _Time.x, randomPoint);
				}
				if (_VoronoiType == 2) // Fixed Border
				
				{
					voronoi = voronoi3D(position, _VoronoiScale, voronoiSpeed, randomPoint);
					voronoi *= 1.8; // Range adjustment
					
				}
				
				float4 outerColor = _VoronoiOuterColor;
				float4 innerColor = _VoronoiInnerColor;
				
				if (_VoronoiEnableRandomCellColor == 1)
				{
					float3 rando = random3(randomPoint);
					fixed hue = rando.x;
					fixed saturation = lerp(_VoronoiRandomMinMaxSaturation.x, _VoronoiRandomMinMaxSaturation.y, rando.y);
					fixed value = lerp(_VoronoiRandomMinMaxBrightness.x, _VoronoiRandomMinMaxBrightness.y, rando.z);
					float3 hsv = float3(hue, saturation, value);
					innerColor.rgb = HSVtoRGB(hsv);
				}
				voronoi = pow(voronoi, _VoronoiPower);
				float2 voronoiGradient = _VoronoiGradient.xy + edgeNoise;
				#ifdef POI_AUDIOLINK
				voronoiGradient.x += _AudioLinkVoronoiGradientMinAdd * poiMods.audioLink[_AudioLinkVoronoiGradientMinAddBand];
				voronoiGradient.y -= _AudioLinkVoronoiGradientMaxAdd * poiMods.audioLink[_AudioLinkVoronoiGradientMaxAddBand];
				#endif
				float ramp = smoothstep(voronoiGradient.x, voronoiGradient.y, voronoi);
				
				if (_VoronoiBlend == 0)
				{
					float4 voronoiColor = lerp(outerColor, innerColor, ramp);
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, voronoiColor, min(mask * voronoiColor.a, 0.99999));
					if (_VoronoiAffectsMaterialAlpha)
					{
						poiFragData.alpha = lerp(poiFragData.alpha, voronoiColor.a, min(mask, 0.99999));
					}
				}
				float outerEmissionStrength = _VoronoiOuterEmissionStrength;
				float innerEmissionStrength = _VoronoiInnerEmissionStrength;
				#ifdef POI_AUDIOLINK
				outerEmissionStrength += lerp(_AudioLinkVoronoiOuterEmission.x, _AudioLinkVoronoiOuterEmission.y, poiMods.audioLink[_AudioLinkVoronoiOuterEmissionBand]);
				innerEmissionStrength += lerp(_AudioLinkVoronoiInnerEmission.x, _AudioLinkVoronoiInnerEmission.y, poiMods.audioLink[_AudioLinkVoronoiInnerEmissionBand]);
				#endif
				float4 voronoiEmissionColor = lerp(outerColor, innerColor, ramp);
				voronoiEmissionColor.rgb *= lerp(outerEmissionStrength, innerEmissionStrength, ramp);
				poiFragData.emission += voronoiEmissionColor.rgb * mask * voronoiEmissionColor.a;
			}
			#endif
			//endex
			
			float4 frag(VertexOut i, uint facing : SV_IsFrontFace) : SV_Target
			{
				UNITY_SETUP_INSTANCE_ID(i);
				UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
				
				PoiMesh poiMesh;
				PoiInitStruct(PoiMesh, poiMesh);
				
				PoiLight poiLight;
				PoiInitStruct(PoiLight, poiLight);
				
				PoiVertexLights poiVertexLights;
				PoiInitStruct(PoiVertexLights, poiVertexLights);
				
				PoiCam poiCam;
				PoiInitStruct(PoiCam, poiCam);
				
				PoiMods poiMods;
				PoiInitStruct(PoiMods, poiMods);
				poiMods.globalEmission = 1;
				
				PoiFragData poiFragData;
				poiFragData.smoothness = 1;
				poiFragData.smoothness2 = 1;
				poiFragData.metallic = 1;
				poiFragData.specularMask = 1;
				poiFragData.reflectionMask = 1;
				poiFragData.emission = 0;
				poiFragData.baseColor = float3(0, 0, 0);
				poiFragData.finalColor = float3(0, 0, 0);
				poiFragData.alpha = 1;
				poiFragData.toggleVertexLights = 0;
				
				#ifdef POI_UDIMDISCARD
				applyUDIMDiscard(i);
				#endif
				
				//ifex _NormalCorrect==0
				#ifdef POI_NORMALCORRECT
				applyNormalCorrect(i);
				#endif
				//endex
				
				// Mesh Data
				//poiMesh.objectPosition = mul(unity_ObjectToWorld, float3(0, 0, 0)).xyz;
				poiMesh.objectPosition = mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
				poiMesh.objNormal = mul(unity_WorldToObject, i.normal);
				poiMesh.normals[0] = i.normal;
				poiMesh.tangent[0] = i.tangent.xyz;
				poiMesh.binormal[0] = cross(i.normal, i.tangent.xyz) * (i.tangent.w * unity_WorldTransformParams.w);
				poiMesh.worldPos = i.worldPos.xyz;
				poiMesh.localPos = i.localPos.xyz;
				poiMesh.vertexColor = i.vertexColor;
				poiMesh.isFrontFace = facing;
				poiMesh.dx = ddx(poiMesh.uv[0]);
				poiMesh.dy = ddy(poiMesh.uv[0]);
				
				#ifndef POI_PASS_OUTLINE
				if (!poiMesh.isFrontFace && _FlipBackfaceNormals)
				{
					poiMesh.normals[0] *= -1;
					poiMesh.tangent[0] *= -1;
					poiMesh.binormal[0] *= -1;
				}
				#endif
				
				poiCam.viewDir = !IsOrthographicCamera() ? normalize(_WorldSpaceCameraPos - i.worldPos.xyz) : normalize(UNITY_MATRIX_I_V._m02_m12_m22);
				float3 tanToWorld0 = float3(poiMesh.tangent[0].x, poiMesh.binormal[0].x, poiMesh.normals[0].x);
				float3 tanToWorld1 = float3(poiMesh.tangent[0].y, poiMesh.binormal[0].y, poiMesh.normals[0].y);
				float3 tanToWorld2 = float3(poiMesh.tangent[0].z, poiMesh.binormal[0].z, poiMesh.normals[0].z);
				float3 ase_tanViewDir = tanToWorld0 * poiCam.viewDir.x + tanToWorld1 * poiCam.viewDir.y + tanToWorld2 * poiCam.viewDir.z;
				poiCam.tangentViewDir = normalize(ase_tanViewDir);
				
				// 0-3 UV0-UV3
				// 4 Panosphere UV
				// 5 world pos xz
				// 6 Polar UV
				// 6 Distorted UV
				#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
				poiMesh.lightmapUV = i.lightmapUV;
				#endif
				poiMesh.parallaxUV = poiCam.tangentViewDir.xy / max(poiCam.tangentViewDir.z, 0.0001);
				poiMesh.uv[0] = i.uv[0].xy;
				poiMesh.uv[1] = i.uv[0].zw;
				poiMesh.uv[2] = i.uv[1].xy;
				poiMesh.uv[3] = i.uv[1].zw;
				poiMesh.uv[4] = poiMesh.uv[0];
				poiMesh.uv[5] = poiMesh.uv[0];
				poiMesh.uv[6] = poiMesh.uv[0];
				poiMesh.uv[7] = poiMesh.uv[0];
				poiMesh.uv[8] = poiMesh.uv[0];
				
				poiMesh.uv[4] = calculatePanosphereUV(poiMesh);
				poiMesh.uv[5] = calculateWorldUV(poiMesh);
				poiMesh.uv[6] = calculatePolarCoordinate(poiMesh);
				poiMesh.uv[8] = calculatelocalUV(poiMesh);
				//ifex _EnableDistortion==0
				#ifdef USER_LUT
				poiMesh.uv[7] = distortedUV(poiMesh);
				#endif
				//endex
				/*
				half3 worldViewUp = normalize(half3(0, 1, 0) - poiCam.viewDir * dot(poiCam.viewDir, half3(0, 1, 0)));
				half3 worldViewRight = normalize(cross(poiCam.viewDir, worldViewUp));
				poiMesh[8] = half2(dot(worldViewRight, poiMesh.normals[_MatcapNormal]), dot(worldViewUp, poiMesh.normals[_MatcapNormal])) * _MatcapBorder + 0.5;
				*/
				
				//ifex _PoiParallax==0
				#ifdef POI_PARALLAX
				#ifndef POI_PASS_OUTLINE
				//return frac(i.tangentViewDir.x);
				//return float4(i.binormal.xyz,1);
				applyParallax(poiMesh, poiLight, poiCam);
				#endif
				#endif
				//endex
				
				poiMods.globalMask[0] = 1;
				poiMods.globalMask[1] = 1;
				poiMods.globalMask[2] = 1;
				poiMods.globalMask[3] = 1;
				poiMods.globalMask[4] = 1;
				poiMods.globalMask[5] = 1;
				poiMods.globalMask[6] = 1;
				poiMods.globalMask[7] = 1;
				poiMods.globalMask[8] = 1;
				poiMods.globalMask[9] = 1;
				poiMods.globalMask[10] = 1;
				poiMods.globalMask[11] = 1;
				poiMods.globalMask[12] = 1;
				poiMods.globalMask[13] = 1;
				poiMods.globalMask[14] = 1;
				poiMods.globalMask[15] = 1;
				//ifex _GlobalMaskTexturesEnable==0
				#ifdef POI_GLOBALMASK_TEXTURES
				ApplyGlobalMaskTextures(poiMesh, poiMods);
				#endif
				//endex
				//ifex _GlobalMaskVertexColorRed==0 && _GlobalMaskVertexColorGreen==0 && _GlobalMaskVertexColorBlue==0 && _GlobalMaskVertexColorAlpha==0
				ApplyGlobalMaskVertexColors(poiMesh, poiMods);
				//endex
				ApplyGlobalMaskModifiers(poiMesh, poiMods, poiCam);
				//ifex _GlobalMaskOptionsEnable==0
				if (_GlobalMaskOptionsEnable)
				{
					ApplyGlobalMaskOptions(poiMods);
				}
				//endex
				
				float2 mainUV = poiUV(poiMesh.uv[_MainTexUV].xy, _MainTex_ST);
				
				if (_MainPixelMode)
				{
					mainUV = sharpSample(_MainTex_TexelSize, mainUV);
				}
				
				float4 mainTexture = POI2D_SAMPLER_PAN_STOCHASTIC(_MainTex, _MainTex, mainUV, _MainTexPan, _MainTexStochastic);
				
				//ifex _VideoEffectsEnable==0
				#ifdef POI_VIDEO_EFFECTS
				if (_VideoEffectsEnable)
				{
					applyVideoEffectsMainTex(mainTexture, poiMesh);
				}
				#endif
				//endex
				
				#if defined(PROP_BUMPMAP) || !defined(OPTIMIZER_ENABLED)
				poiMesh.tangentSpaceNormal = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_BumpMap, _MainTex, poiUV(poiMesh.uv[_BumpMapUV].xy, _BumpMap_ST), _BumpMapPan, _BumpMapStochastic), _BumpScale);
				#else
				poiMesh.tangentSpaceNormal = UnpackNormal(float4(0.5, 0.5, 1, 1));
				#endif
				
				//ifex _DetailEnabled==0
				#if defined(FINALPASS) && !defined(UNITY_PASS_SHADOWCASTER) && !defined(POI_PASS_OUTLINE)
				ApplyDetailNormal(poiMods, poiMesh);
				#endif
				//endex
				
				//ifex _RGBMaskEnabled==0
				#if defined(VIGNETTE) && !defined(UNITY_PASS_SHADOWCASTER) && !defined(POI_PASS_OUTLINE)
				calculateRGBNormals(poiMesh, poiMods);
				#endif
				
				//endex
				
				float3 tangentSpaceNormal = UnpackNormal(float4(0.5, 0.5, 1, 1));
				poiMesh.normals[0] = normalize(
				tangentSpaceNormal.x * poiMesh.tangent[0] +
				tangentSpaceNormal.y * poiMesh.binormal[0] +
				tangentSpaceNormal.z * poiMesh.normals[0]
				);
				
				poiMesh.normals[1] = normalize(
				poiMesh.tangentSpaceNormal.x * poiMesh.tangent[0] +
				poiMesh.tangentSpaceNormal.y * poiMesh.binormal[0] +
				poiMesh.tangentSpaceNormal.z * poiMesh.normals[0]
				);
				
				poiMesh.tangent[1] = cross(poiMesh.binormal[0], -poiMesh.normals[1]);
				poiMesh.binormal[1] = cross(-poiMesh.normals[1], poiMesh.tangent[0]);
				
				//ifex _EnableOutlines!=1
				#ifdef POI_PASS_OUTLINE
				poiMesh.normals[1] = poiMesh.normals[0];
				#endif
				//endex
				
				// Camera data
				poiCam.forwardDir = getCameraForward();
				poiCam.worldPos = _WorldSpaceCameraPos;
				poiCam.reflectionDir = reflect(-poiCam.viewDir, poiMesh.normals[1]);
				poiCam.vertexReflectionDir = reflect(-poiCam.viewDir, poiMesh.normals[0]);
				//poiCam.distanceToModel = distance(poiMesh.modelPos, poiCam.worldPos);
				poiCam.clipPos = i.pos;
				poiCam.distanceToVert = distance(poiMesh.worldPos, poiCam.worldPos);
				poiCam.posScreenSpace = poiTransformClipSpacetoScreenSpaceFrag(poiCam.clipPos);
				#if defined(POI_GRABPASS) && defined(POI_PASS_BASE)
				poiCam.screenUV = poiCam.clipPos.xy / poiGetWidthAndHeight(_PoiGrab2);
				#else
				poiCam.screenUV = poiCam.clipPos.xy / _ScreenParams.xy;
				#endif
				#ifdef UNITY_SINGLE_PASS_STEREO
				poiCam.posScreenSpace.x = poiCam.posScreenSpace.x * 0.5;
				#endif
				poiCam.posScreenPixels = calcPixelScreenUVs(poiCam.posScreenSpace);
				poiCam.vDotN = abs(dot(poiCam.viewDir, poiMesh.normals[1]));
				
				poiCam.worldDirection.xyz = poiMesh.worldPos.xyz - poiCam.worldPos;
				poiCam.worldDirection.w = dot(poiCam.clipPos, CalculateFrustumCorrection());
				
				calculateGlobalThemes(poiMods);
				
				poiLight.finalLightAdd = 0;
				
				// Ambient Occlusion
				#if defined(PROP_LIGHTINGAOMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 AOMaps = POI2D_SAMPLER_PAN(_LightingAOMaps, _MainTex, poiUV(poiMesh.uv[_LightingAOMapsUV], _LightingAOMaps_ST), _LightingAOMapsPan);
				poiLight.occlusion = min(min(min(lerp(1, AOMaps.r, _LightDataAOStrengthR), lerp(1, AOMaps.g, _LightDataAOStrengthG)), lerp(1, AOMaps.b, _LightDataAOStrengthB)), lerp(1, AOMaps.a, _LightDataAOStrengthA));
				#else
				poiLight.occlusion = 1;
				#endif
				
				if (_LightDataAOGlobalMaskR > 0)
				{
					poiLight.occlusion = maskBlend(poiLight.occlusion, poiMods.globalMask[_LightDataAOGlobalMaskR - 1], _LightDataAOGlobalMaskBlendTypeR);
				}
				
				// Detail Shadows
				#if defined(PROP_LIGHTINGDETAILSHADOWMAPS) || !defined(OPTIMIZER_ENABLED)
				float4 DetailShadows = POI2D_SAMPLER_PAN(_LightingDetailShadowMaps, _MainTex, poiUV(poiMesh.uv[_LightingDetailShadowMapsUV], _LightingDetailShadowMaps_ST), _LightingDetailShadowMapsPan);
				#ifndef POI_PASS_ADD
				poiLight.detailShadow = lerp(1, DetailShadows.r, _LightingDetailShadowStrengthR) * lerp(1, DetailShadows.g, _LightingDetailShadowStrengthG) * lerp(1, DetailShadows.b, _LightingDetailShadowStrengthB) * lerp(1, DetailShadows.a, _LightingDetailShadowStrengthA);
				#else
				poiLight.detailShadow = lerp(1, DetailShadows.r, _LightingAddDetailShadowStrengthR) * lerp(1, DetailShadows.g, _LightingAddDetailShadowStrengthG) * lerp(1, DetailShadows.b, _LightingAddDetailShadowStrengthB) * lerp(1, DetailShadows.a, _LightingAddDetailShadowStrengthA);
				#endif
				#else
				poiLight.detailShadow = 1;
				#endif
				
				if (_LightDataDetailShadowGlobalMaskR > 0)
				{
					poiLight.detailShadow = maskBlend(poiLight.detailShadow, poiMods.globalMask[_LightDataDetailShadowGlobalMaskR - 1], _LightDataDetailShadowGlobalMaskBlendTypeR);
				}
				
				// Shadow Masks
				#if defined(PROP_LIGHTINGSHADOWMASKS) || !defined(OPTIMIZER_ENABLED)
				float4 ShadowMasks = POI2D_SAMPLER_PAN(_LightingShadowMasks, _MainTex, poiUV(poiMesh.uv[_LightingShadowMasksUV], _LightingShadowMasks_ST), _LightingShadowMasksPan);
				poiLight.shadowMask = lerp(1, ShadowMasks.r, _LightingShadowMaskStrengthR) * lerp(1, ShadowMasks.g, _LightingShadowMaskStrengthG) * lerp(1, ShadowMasks.b, _LightingShadowMaskStrengthB) * lerp(1, ShadowMasks.a, _LightingShadowMaskStrengthA);
				#else
				poiLight.shadowMask = 1;
				#endif
				if (_LightDataShadowMaskGlobalMaskR > 0)
				{
					poiLight.shadowMask = maskBlend(poiLight.shadowMask, poiMods.globalMask[_LightDataShadowMaskGlobalMaskR - 1], _LightDataShadowMaskGlobalMaskBlendTypeR);
				}
				
				#ifdef UNITY_PASS_FORWARDBASE
				
				bool lightExists = false;
				if (any(_LightColor0.rgb >= 0.002))
				{
					lightExists = true;
				}
				
				if (_LightingVertexLightingEnabled)
				{
					poiFragData.toggleVertexLights = 1;
				}
				if (IsInMirror() && _LightingMirrorVertexLightingEnabled == 0)
				{
					poiFragData.toggleVertexLights = 0;
				}
				
				if (_LightingVertexLightingEnabled)
				{
					#if defined(VERTEXLIGHT_ON)
					float4 toLightX = unity_4LightPosX0 - i.worldPos.x;
					float4 toLightY = unity_4LightPosY0 - i.worldPos.y;
					float4 toLightZ = unity_4LightPosZ0 - i.worldPos.z;
					float4 lengthSq = 0;
					lengthSq += toLightX * toLightX;
					lengthSq += toLightY * toLightY;
					lengthSq += toLightZ * toLightZ;
					
					float4 lightAttenSq = unity_4LightAtten0;
					float4 atten = 1.0 / (1.0 + lengthSq * lightAttenSq);
					float4 vLightWeight = saturate(1 - (lengthSq * lightAttenSq / 25));
					poiLight.vAttenuation = min(atten, vLightWeight * vLightWeight);
					
					poiLight.vDotNL = 0;
					poiLight.vDotNL += toLightX * poiMesh.normals[1].x;
					poiLight.vDotNL += toLightY * poiMesh.normals[1].y;
					poiLight.vDotNL += toLightZ * poiMesh.normals[1].z;
					
					float4 corr = rsqrt(lengthSq);
					poiLight.vertexVDotNL = max(0, poiLight.vDotNL * corr);
					
					poiLight.vertexVDotNL = 0;
					poiLight.vertexVDotNL += toLightX * poiMesh.normals[0].x;
					poiLight.vertexVDotNL += toLightY * poiMesh.normals[0].y;
					poiLight.vertexVDotNL += toLightZ * poiMesh.normals[0].z;
					
					poiLight.vertexVDotNL = max(0, poiLight.vDotNL * corr);
					
					poiLight.vSaturatedDotNL = saturate(poiLight.vDotNL);
					
					[unroll]
					for (int index = 0; index < 4; index++)
					{
						poiLight.vPosition[index] = float3(unity_4LightPosX0[index], unity_4LightPosY0[index], unity_4LightPosZ0[index]);
						
						float3 vertexToLightSource = poiLight.vPosition[index] - poiMesh.worldPos;
						poiLight.vDirection[index] = normalize(vertexToLightSource);
						poiLight.vColor[index] = _LightingAdditiveLimited ? MaxLuminance(unity_LightColor[index].rgb * poiLight.vAttenuation[index], _LightingAdditiveLimit) : unity_LightColor[index].rgb * poiLight.vAttenuation[index];
						poiLight.vColor[index] = lerp(poiLight.vColor[index], dot(poiLight.vColor[index], float3(0.299, 0.587, 0.114)), _LightingAdditiveMonochromatic);
						poiLight.vHalfDir[index] = Unity_SafeNormalize(poiLight.vDirection[index] + poiCam.viewDir);
						poiLight.vDotNL[index] = dot(poiMesh.normals[1], poiLight.vDirection[index]);
						poiLight.vCorrectedDotNL[index] = .5 * (poiLight.vDotNL[index] + 1);
						poiLight.vDotLH[index] = saturate(dot(poiLight.vDirection[index], poiLight.vHalfDir[index]));
						
						poiLight.vDotNH[index] = dot(poiMesh.normals[1], poiLight.vHalfDir[index]);
						poiLight.vertexVDotNH[index] = saturate(dot(poiMesh.normals[0], poiLight.vHalfDir[index]));
					}
					#endif
				}
				
				//UNITY_BRANCH
				if (_LightingColorMode == 0) // Poi Custom Light Color
				
				{
					float3 magic = max(BetterSH9(normalize(unity_SHAr + unity_SHAg + unity_SHAb)), 0);
					float3 normalLight = _LightColor0.rgb + BetterSH9(float4(0, 0, 0, 1));
					
					float magiLumi = calculateluminance(magic);
					float normaLumi = calculateluminance(normalLight);
					float maginormalumi = magiLumi + normaLumi;
					
					float magiratio = magiLumi / maginormalumi;
					float normaRatio = normaLumi / maginormalumi;
					
					float target = calculateluminance(magic * magiratio + normalLight * normaRatio);
					float3 properLightColor = magic + normalLight;
					float properLuminance = calculateluminance(magic + normalLight);
					poiLight.directColor = properLightColor * max(0.0001, (target / properLuminance));
					
					poiLight.indirectColor = BetterSH9(float4(lerp(0, poiMesh.normals[1], _LightingIndirectUsesNormals), 1));
				}
				
				//UNITY_BRANCH
				if (_LightingColorMode == 1) // More standard approach to light color
				
				{
					float3 indirectColor = BetterSH9(float4(poiMesh.normals[1], 1));
					if (lightExists)
					{
						poiLight.directColor = _LightColor0.rgb;
						poiLight.indirectColor = indirectColor;
					}
					else
					{
						poiLight.directColor = indirectColor * 0.6;
						poiLight.indirectColor = indirectColor * 0.5;
					}
				}
				
				if (_LightingColorMode == 2) // UTS style
				
				{
					poiLight.indirectColor = saturate(max(half3(0.05, 0.05, 0.05) * _Unlit_Intensity, max(ShadeSH9(half4(0.0, 0.0, 0.0, 1.0)), ShadeSH9(half4(0.0, -1.0, 0.0, 1.0)).rgb) * _Unlit_Intensity));
					poiLight.directColor = max(poiLight.indirectColor, _LightColor0.rgb);
				}
				
				if (_LightingColorMode == 3) // OpenLit
				
				{
					float3 lightDirectionForSH9 = OpenLitLightingDirectionForSH9();
					OpenLitShadeSH9ToonDouble(lightDirectionForSH9, poiLight.directColor, poiLight.indirectColor);
					poiLight.directColor += _LightColor0.rgb;
					// OpenLit does a few other things by default like clamp direct colour
					// see https://github.com/lilxyzw/OpenLit/blob/main/Assets/OpenLit/core.hlsl#L174
				}
				
				float lightMapMode = _LightingMapMode;
				//UNITY_BRANCH
				if (_LightingDirectionMode == 0)
				{
					poiLight.direction = _WorldSpaceLightPos0.xyz + unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz;
				}
				if (_LightingDirectionMode == 1 || _LightingDirectionMode == 2)
				{
					//UNITY_BRANCH
					if (_LightingDirectionMode == 1)
					{
						poiLight.direction = mul(unity_ObjectToWorld, _LightngForcedDirection).xyz;;
					}
					//UNITY_BRANCH
					if (_LightingDirectionMode == 2)
					{
						poiLight.direction = _LightngForcedDirection;
					}
					if (lightMapMode == 0)
					{
						lightMapMode == 1;
					}
				}
				
				if (_LightingDirectionMode == 3) // UTS
				
				{
					float3 defaultLightDirection = normalize(UNITY_MATRIX_V[2].xyz + UNITY_MATRIX_V[1].xyz);
					float3 lightDirection = normalize(lerp(defaultLightDirection, _WorldSpaceLightPos0.xyz, any(_WorldSpaceLightPos0.xyz)));
					poiLight.direction = lightDirection;
				}
				if (_LightingDirectionMode == 4) // OpenLit
				
				{
					poiLight.direction = OpenLitLightingDirection(); // float4 customDir = 0; // Do we want to give users to alter this (OpenLit always does!)?
					
				}
				
				if (_LightingDirectionMode == 5) // View Direction
				
				{
					float3 upViewDir = normalize(UNITY_MATRIX_V[1].xyz);
					float3 rightViewDir = normalize(UNITY_MATRIX_V[0].xyz);
					float yawOffset_Rads = radians(!IsInMirror() ? - _LightingViewDirOffsetYaw : _LightingViewDirOffsetYaw);
					float3 rotatedViewYaw = normalize(RotateAroundAxis(rightViewDir, upViewDir, yawOffset_Rads));
					float3 rotatedViewCameraMeshOffset = RotateAroundAxis((getCameraPosition() - (poiMesh.worldPos)), upViewDir, yawOffset_Rads);
					float pitchOffset_Rads = radians(!IsInMirror() ? _LightingViewDirOffsetPitch : - _LightingViewDirOffsetPitch);
					float3 rotatedViewPitch = RotateAroundAxis(rotatedViewCameraMeshOffset, rotatedViewYaw, pitchOffset_Rads);
					poiLight.direction = normalize(rotatedViewPitch);
				}
				
				if (!any(poiLight.direction))
				{
					poiLight.direction = float3(.4, 1, .4);
				}
				
				poiLight.direction = normalize(poiLight.direction);
				poiLight.attenuationStrength = _LightingCastedShadows;
				poiLight.attenuation = 1;
				if (!all(_LightColor0.rgb == 0.0))
				{
					UNITY_LIGHT_ATTENUATION(attenuation, i, poiMesh.worldPos)
					poiLight.attenuation *= attenuation;
				}
				
				if (!any(poiLight.directColor) && !any(poiLight.indirectColor) && lightMapMode == 0)
				{
					lightMapMode = 1;
					if (_LightingDirectionMode == 0)
					{
						poiLight.direction = normalize(float3(.4, 1, .4));
					}
				}
				
				poiLight.halfDir = normalize(poiLight.direction + poiCam.viewDir);
				poiLight.vertexNDotL = dot(poiMesh.normals[0], poiLight.direction);
				poiLight.nDotL = dot(poiMesh.normals[1], poiLight.direction);
				poiLight.nDotLSaturated = saturate(poiLight.nDotL);
				poiLight.nDotLNormalized = (poiLight.nDotL + 1) * 0.5;
				poiLight.nDotV = abs(dot(poiMesh.normals[1], poiCam.viewDir));
				poiLight.vertexNDotV = abs(dot(poiMesh.normals[0], poiCam.viewDir));
				poiLight.nDotH = dot(poiMesh.normals[1], poiLight.halfDir);
				poiLight.vertexNDotH = max(0.00001, dot(poiMesh.normals[0], poiLight.halfDir));
				poiLight.lDotv = dot(poiLight.direction, poiCam.viewDir);
				poiLight.lDotH = max(0.00001, dot(poiLight.direction, poiLight.halfDir));
				
				// Poi special light map
				if (lightMapMode == 0)
				{
					float3 ShadeSH9Plus = GetSHLength();
					float3 ShadeSH9Minus = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) + float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0;
					
					float3 greyScaleVector = float3(.33333, .33333, .33333);
					float bw_lightColor = dot(poiLight.directColor, greyScaleVector);
					float bw_directLighting = (((poiLight.nDotL * 0.5 + 0.5) * bw_lightColor * lerp(1, poiLight.attenuation, poiLight.attenuationStrength)) + dot(ShadeSH9(float4(poiMesh.normals[1], 1)), greyScaleVector));
					float bw_directLightingNoAtten = (((poiLight.nDotL * 0.5 + 0.5) * bw_lightColor) + dot(ShadeSH9(float4(poiMesh.normals[1], 1)), greyScaleVector));
					float bw_bottomIndirectLighting = dot(ShadeSH9Minus, greyScaleVector);
					float bw_topIndirectLighting = dot(ShadeSH9Plus, greyScaleVector);
					float lightDifference = ((bw_topIndirectLighting + bw_lightColor) - bw_bottomIndirectLighting);
					
					poiLight.lightMap = smoothstep(0, lightDifference, bw_directLighting - bw_bottomIndirectLighting);
					poiLight.lightMapNoAttenuation = smoothstep(0, lightDifference, bw_directLightingNoAtten - bw_bottomIndirectLighting);
				}
				// Normalized nDotL
				if (lightMapMode == 1)
				{
					poiLight.lightMapNoAttenuation = poiLight.nDotLNormalized;
					poiLight.lightMap = poiLight.nDotLNormalized * lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				}
				// Saturated nDotL
				if (lightMapMode == 2)
				{
					poiLight.lightMapNoAttenuation = poiLight.nDotLSaturated;
					poiLight.lightMap = poiLight.nDotLSaturated * lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				}
				if (lightMapMode == 3)
				{
					poiLight.lightMapNoAttenuation = 1;
					poiLight.lightMap = lerp(1, poiLight.attenuation, poiLight.attenuationStrength);
				}
				poiLight.lightMapNoAttenuation *= poiLight.detailShadow;
				poiLight.lightMap *= poiLight.detailShadow;
				
				poiLight.directColor = max(poiLight.directColor, 0.0001);
				poiLight.indirectColor = max(poiLight.indirectColor, 0.0001);
				
				if (_LightingColorMode == 3)
				{
					// OpenLit
					poiLight.directColor = max(poiLight.directColor, _LightingMinLightBrightness);
				}
				else
				{
					poiLight.directColor = max(poiLight.directColor, poiLight.directColor * min(10000, (_LightingMinLightBrightness * rcp(calculateluminance(poiLight.directColor)))));
					poiLight.indirectColor = max(poiLight.indirectColor, poiLight.indirectColor * min(10000, (_LightingMinLightBrightness * rcp(calculateluminance(poiLight.indirectColor)))));
				}
				
				poiLight.directColor = lerp(poiLight.directColor, dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic);
				poiLight.indirectColor = lerp(poiLight.indirectColor, dot(poiLight.indirectColor, float3(0.299, 0.587, 0.114)), _LightingMonochromatic);
				
				if (_LightingCapEnabled)
				{
					poiLight.directColor = min(poiLight.directColor, _LightingCap);
					poiLight.indirectColor = min(poiLight.indirectColor, _LightingCap);
				}
				
				if (_LightingForceColorEnabled)
				{
					poiLight.directColor = poiThemeColor(poiMods, _LightingForcedColor, _LightingForcedColorThemeIndex);
				}
				
				#ifdef UNITY_PASS_FORWARDBASE
				poiLight.directColor = max(poiLight.directColor * _PPLightingMultiplier, 0);
				poiLight.directColor = max(poiLight.directColor + _PPLightingAddition, 0);
				poiLight.indirectColor = max(poiLight.indirectColor * _PPLightingMultiplier, 0);
				poiLight.indirectColor = max(poiLight.indirectColor + _PPLightingAddition, 0);
				#endif
				
				#endif
				
				#ifdef POI_PASS_ADD
				if (!_LightingAdditiveEnable)
				{
					return float4(mainTexture.rgb * .0001, 1);
				}
				
				#if defined(DIRECTIONAL)
				if (_DisableDirectionalInAdd)
				{
					return float4(mainTexture.rgb * .0001, 1);
				}
				#endif
				
				poiLight.direction = normalize(_WorldSpaceLightPos0.xyz - i.worldPos.xyz * _WorldSpaceLightPos0.w);
				#if defined(POINT) || defined(SPOT)
				#ifdef POINT
				unityShadowCoord3 lightCoord = mul(unity_WorldToLight, unityShadowCoord4(poiMesh.worldPos, 1)).xyz;
				poiLight.attenuation = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).r;
				#endif
				
				#ifdef SPOT
				unityShadowCoord4 lightCoord = mul(unity_WorldToLight, unityShadowCoord4(poiMesh.worldPos, 1));
				poiLight.attenuation = (lightCoord.z > 0) * UnitySpotCookie(lightCoord) * UnitySpotAttenuate(lightCoord.xyz);
				#endif
				#else
				UNITY_LIGHT_ATTENUATION(attenuation, i, poiMesh.worldPos)
				poiLight.attenuation = attenuation;
				#endif
				poiLight.additiveShadow = UNITY_SHADOW_ATTENUATION(i, poiMesh.worldPos);
				poiLight.attenuationStrength = _LightingAdditiveCastedShadows;
				poiLight.directColor = _LightingAdditiveLimited ? MaxLuminance(_LightColor0.rgb * poiLight.attenuation, _LightingAdditiveLimit) : _LightColor0.rgb  * poiLight.attenuation;
				
				#if defined(POINT_COOKIE) || defined(DIRECTIONAL_COOKIE)
				poiLight.indirectColor = 0;
				#else
				poiLight.indirectColor = lerp(0, poiLight.directColor, _LightingAdditivePassthrough);
				poiLight.indirectColor = _LightingAdditiveLimited ? MaxLuminance(poiLight.indirectColor, _LightingAdditiveLimit) : poiLight.indirectColor;
				#endif
				
				poiLight.directColor = lerp(poiLight.directColor, dot(poiLight.directColor, float3(0.299, 0.587, 0.114)), _LightingAdditiveMonochromatic);
				poiLight.indirectColor = lerp(poiLight.indirectColor, dot(poiLight.indirectColor, float3(0.299, 0.587, 0.114)), _LightingAdditiveMonochromatic);
				
				poiLight.halfDir = normalize(poiLight.direction + poiCam.viewDir);
				poiLight.nDotL = dot(poiMesh.normals[1], poiLight.direction);
				poiLight.nDotLSaturated = saturate(poiLight.nDotL);
				poiLight.nDotLNormalized = (poiLight.nDotL + 1) * 0.5;
				poiLight.nDotV = abs(dot(poiMesh.normals[1], poiCam.viewDir));
				poiLight.nDotH = dot(poiMesh.normals[1], poiLight.halfDir);
				poiLight.lDotv = dot(poiLight.direction, poiCam.viewDir);
				poiLight.lDotH = dot(poiLight.direction, poiLight.halfDir);
				poiLight.vertexNDotL = dot(poiMesh.normals[0], poiLight.direction);
				poiLight.vertexNDotV = abs(dot(poiMesh.normals[0], poiCam.viewDir));
				poiLight.vertexNDotH = max(0.00001, dot(poiMesh.normals[0], poiLight.halfDir));
				
				// Normalized nDotL
				if (_LightingMapMode == 0 || _LightingMapMode == 1 || _LightingMapMode == 2)
				{
					poiLight.lightMap = poiLight.nDotLNormalized;
				}
				if (_LightingMapMode == 3)
				{
					poiLight.lightMap = 1;
				}
				poiLight.lightMap *= poiLight.detailShadow;
				poiLight.lightMapNoAttenuation = poiLight.lightMap;
				poiLight.lightMap *= lerp(1, poiLight.additiveShadow, poiLight.attenuationStrength);
				#endif
				
				//ifex _LightDataDebugEnabled==0
				if (_LightDataDebugEnabled)
				{
					#ifdef UNITY_PASS_FORWARDBASE
					//UNITY_BRANCH
					if (_LightingDebugVisualize <= 6)
					{
						switch(_LightingDebugVisualize)
						{
							case 0: // Direct Light Color
							return float4(poiLight.directColor + mainTexture.rgb * .0001, 1);
							break;
							case 1: // Indirect Light Color
							return float4(poiLight.indirectColor + mainTexture.rgb * .0001, 1);
							break;
							case 2: // Light Map
							return float4(poiLight.lightMap + mainTexture.rgb * .0001, 1);
							break;
							case 3: // Attenuation
							return float4(poiLight.attenuation + mainTexture.rgb * .0001, 1);
							break;
							case 4: // N Dot L
							return float4(poiLight.nDotLNormalized, poiLight.nDotLNormalized, poiLight.nDotLNormalized, 1) + mainTexture * .0001;
							break;
							case 5:
							return float4(poiLight.halfDir, 1) + mainTexture * .0001;
							break;
							case 6:
							return float4(poiLight.direction, 1) + mainTexture * .0001;
							break;
						}
					}
					else
					{
						return POI_SAFE_RGB1;
					}
					#endif
					#ifdef POI_PASS_ADD
					//UNITY_BRANCH
					if (_LightingDebugVisualize < 6)
					{
						return POI_SAFE_RGB1;
					}
					else
					{
						switch(_LightingDebugVisualize)
						{
							case 7:
							return float4(poiLight.directColor * poiLight.attenuation + mainTexture.rgb * .0001, 1);
							break;
							case 8:
							return float4(poiLight.attenuation + mainTexture.rgb * .0001, 1);
							break;
							case 9:
							return float4(poiLight.additiveShadow + mainTexture.rgb * .0001, 1);
							break;
							case 10:
							return float4(poiLight.nDotLNormalized + mainTexture.rgb * .0001, 1);
							break;
							case 11:
							return float4(poiLight.halfDir, 1) + mainTexture * .0001;
							break;
						}
					}
					#endif
				}
				//endex
				
				//ifex _EnableAudioLink==0
				#ifdef POI_AUDIOLINK
				SetupAudioLink(poiFragData, poiMods, poiMesh);
				#endif
				//endex
				
				//ifex _MochieBRDF==0
				#if defined(MOCHIE_PBR)
				MetallicAndSpecularFragDataInit(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _BlackLightMaskingEnabled==0
				#ifdef POI_BLACKLIGHTMASKING
				calculateBlackLightMasks(poiMesh, poiMods);
				#endif
				//endex
				
				poiFragData.baseColor = mainTexture.rgb * poiThemeColor(poiMods, _Color.rgb, _ColorThemeIndex);
				poiFragData.alpha = mainTexture.a * _Color.a;
				
				//ifex _MainColorAdjustToggle==0
				#ifdef COLOR_GRADING_HDR
				#if defined(PROP_MAINCOLORADJUSTTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 hueShiftAlpha = POI2D_SAMPLER_PAN(_MainColorAdjustTexture, _MainTex, poiUV(poiMesh.uv[_MainColorAdjustTextureUV], _MainColorAdjustTexture_ST), _MainColorAdjustTexturePan);
				#else
				float4 hueShiftAlpha = 1;
				#endif
				
				if (_MainHueGlobalMask > 0)
				{
					hueShiftAlpha.r = maskBlend(hueShiftAlpha.r, poiMods.globalMask[_MainHueGlobalMask - 1], _MainHueGlobalMaskBlendType);
				}
				if (_MainSaturationGlobalMask > 0)
				{
					hueShiftAlpha.b = maskBlend(hueShiftAlpha.b, poiMods.globalMask[_MainSaturationGlobalMask - 1], _MainSaturationGlobalMaskBlendType);
				}
				if (_MainBrightnessGlobalMask > 0)
				{
					hueShiftAlpha.g = maskBlend(hueShiftAlpha.g, poiMods.globalMask[_MainBrightnessGlobalMask - 1], _MainBrightnessGlobalMaskBlendType);
				}
				
				if (_MainHueShiftToggle)
				{
					float shift = _MainHueShift;
					#ifdef POI_AUDIOLINK
					//UNITY_BRANCH
					if (poiMods.audioLinkAvailable && _MainHueALCTEnabled)
					{
						shift += AudioLinkGetChronoTime(_MainALHueShiftCTIndex, _MainALHueShiftBand) * _MainHueALMotionSpeed;
					}
					#endif
					if (_MainHueShiftReplace)
					{
						poiFragData.baseColor = lerp(poiFragData.baseColor, hueShift(poiFragData.baseColor, shift + _MainHueShiftSpeed * _Time.x), hueShiftAlpha.r);
					}
					else
					{
						poiFragData.baseColor = hueShift(poiFragData.baseColor, frac((shift - (1 - hueShiftAlpha.r) + _MainHueShiftSpeed * _Time.x)));
					}
				}
				
				if (_MainGradationStrength && _ColorGradingToggle)
				{
					#if !defined(UNITY_COLORSPACE_GAMMA)
					float3 tempColor = OpenLitLinearToSRGB(poiFragData.baseColor);
					#else
					float3 tempColor = poiFragData.baseColor;
					#endif
					#if defined(PROP_MAINGRADATIONTEX) || !defined(OPTIMIZER_ENABLED)
					tempColor.r = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.r).r;
					tempColor.g = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.g).g;
					tempColor.b = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.b).b;
					#else
					tempColor = float3(1, 1, 1);
					#endif
					#if !defined(UNITY_COLORSPACE_GAMMA)
					tempColor = OpenLitSRGBToLinear(tempColor);
					#endif
					poiFragData.baseColor = lerp(poiFragData.baseColor, tempColor, _MainGradationStrength);
				}
				
				poiFragData.baseColor = lerp(poiFragData.baseColor, dot(poiFragData.baseColor, float3(0.3, 0.59, 0.11)), - (_Saturation) * hueShiftAlpha.b);
				poiFragData.baseColor = saturate(lerp(poiFragData.baseColor, poiFragData.baseColor * (_MainBrightness + 1), hueShiftAlpha.g));
				#endif
				//endex
				
				#if defined(PROP_ALPHAMASK) || !defined(OPTIMIZER_ENABLED)
				
				if (_MainAlphaMaskMode)
				{
					float alphaMask = POI2D_SAMPLER_PAN(_AlphaMask, _MainTex, poiUV(poiMesh.uv[_AlphaMaskUV], _AlphaMask_ST), _AlphaMaskPan.xy).r;
					alphaMask = saturate(alphaMask * _AlphaMaskScale + _AlphaMaskValue);
					if (_AlphaMaskInvert) alphaMask = 1 - alphaMask;
					if (_MainAlphaMaskMode == 1) poiFragData.alpha = alphaMask;
					if (_MainAlphaMaskMode == 2) poiFragData.alpha = poiFragData.alpha * alphaMask;
					if (_MainAlphaMaskMode == 3) poiFragData.alpha = saturate(poiFragData.alpha + alphaMask);
					if (_MainAlphaMaskMode == 4) poiFragData.alpha = saturate(poiFragData.alpha - alphaMask);
				}
				#endif
				
				//ifex _VideoEffectsEnable==0
				#ifdef POI_VIDEO_EFFECTS
				if (_VideoEffectsEnable)
				{
					applyVideoEffects(poiFragData, poiCam, poiMesh, poiLight, poiMods);
				}
				#endif
				//endex
				
				applyAlphaOptions(poiFragData, poiMesh, poiCam, poiMods);
				
				//ifex _EnableTouchGlow==0
				#ifdef GRAIN
				applyDepthFX(poiFragData, poiCam, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _DetailEnabled==0
				#ifdef FINALPASS
				ApplyDetailColor(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _MainVertexColoringEnabled==0
				applyVertexColor(poiFragData, poiMesh);
				//endex
				
				//ifex _BackFaceEnabled!=1
				#ifdef POI_BACKFACE
				ApplyBackFaceColor(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _RGBMaskEnabled==0
				#ifdef VIGNETTE
				calculateRGBMask(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _EnableDissolve==0
				#ifdef DISTORT
				applyDissolve(poiFragData, poiMesh, poiMods, poiCam, poiLight);
				#endif
				//endex
				
				//ifex _ShadingEnabled==0
				#if defined(_LIGHTINGMODE_SHADEMAP) && defined(VIGNETTE_MASKED)
				#ifndef POI_PASS_OUTLINE
				#ifdef _LIGHTINGMODE_SHADEMAP
				applyShadeMapping(poiFragData, poiMesh, poiLight);
				#endif
				#endif
				#endif
				//endex
				
				//ifex _ShadingEnabled==0
				#ifdef VIGNETTE_MASKED
				#ifdef POI_PASS_OUTLINE
				//UNITY_BRANCH
				if (_OutlineLit)
				{
					calculateShading(poiLight, poiFragData, poiMesh, poiCam);
				}
				else
				{
					poiLight.finalLighting = 1;
				}
				#else
				calculateShading(poiLight, poiFragData, poiMesh, poiCam);
				#endif
				#else
				//endex
				poiLight.finalLighting = 1;
				poiLight.rampedLightMap = poiEdgeNonLinear(poiLight.nDotL, 0.1, .1);
				//ifex _ShadingEnabled==0
				#endif
				if (_ShadingRampedLightMapApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _ShadingRampedLightMapApplyGlobalMaskIndex - 1, _ShadingRampedLightMapApplyGlobalMaskBlendType, poiLight.rampedLightMap);
				}
				if (_ShadingRampedLightMapInverseApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _ShadingRampedLightMapInverseApplyGlobalMaskIndex - 1, _ShadingRampedLightMapInverseApplyGlobalMaskBlendType, 1 - poiLight.rampedLightMap);
				}
				
				poiLight.directLuminance = dot(poiLight.directColor, float3(0.299, 0.587, 0.114));
				poiLight.indirectLuminance = dot(poiLight.directColor, float3(0.299, 0.587, 0.114));
				poiLight.finalLuminance = dot(poiLight.finalLighting, float3(0.299, 0.587, 0.114));
				//endex
				
				#if defined(GEOM_TYPE_BRANCH) || defined(GEOM_TYPE_BRANCH_DETAIL) || defined(GEOM_TYPE_FROND) || defined(DEPTH_OF_FIELD_COC_VIEW)
				applyDecals(poiFragData, poiMesh, poiCam, poiMods, poiLight);
				#endif
				
				//ifex _EnableAniso==0
				#ifdef POI_ANISOTROPICS
				applyAnisotropics(poiFragData, poiLight, poiCam, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _MatcapEnable==0 && _Matcap2Enable==0 && _Matcap3Enable==0 && _Matcap4Enable==0
				#if defined(POI_MATCAP0) || defined(COLOR_GRADING_HDR_3D) || defined(POI_MATCAP2) || defined(POI_MATCAP3)
				applyMatcap(poiFragData, poiCam, poiMesh, poiLight, poiMods);
				#endif
				//endex
				
				//ifex _CubeMapEnabled==0
				#ifdef _CUBEMAP
				applyCubemap(poiFragData, poiCam, poiMesh, poiLight, poiMods);
				#endif
				//endex
				
				//ifex _EnableALDecal==0
				#ifdef POI_AUDIOLINK
				#ifdef POI_AL_DECAL
				ApplyAudioLinkDecal(poiMesh, poiFragData, poiMods);
				#endif
				#endif
				//endex
				
				//ifex _EnableVolumeColor==0
				#ifdef POI_AUDIOLINK
				#ifdef POI_AL_VOLUMECOLOR
				ApplyAudioLinkVolumeColor(poiMesh, poiFragData, poiMods);
				#endif
				#endif
				//endex
				
				//ifex _EnableFlipbook==0
				#ifdef _SUNDISK_HIGH_QUALITY
				applyFlipbook(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _EnableRimLighting==0
				#ifdef _GLOSSYREFLECTIONS_OFF
				#ifdef _RIMSTYLE_POIYOMI
				#if defined(PROP_RIMMASK) || !defined(OPTIMIZER_ENABLED)
				float4 rimMaskAndBias = POI2D_SAMPLER_PAN(_RimMask, _MainTex, poiUV(poiMesh.uv[_RimMaskUV], _RimMask_ST), _RimMaskPan);
				float rimMask = rimMaskAndBias[_RimMaskChannel];
				float rimBias = rimMaskAndBias.a;
				#else
				float rimMask = 1;
				float rimBias = 0;
				#endif
				
				if (_RimMaskInvert)
				{
					rimMask = 1 - rimMask;
				}
				
				#if defined(PROP_RIMTEX) || !defined(OPTIMIZER_ENABLED)
				float4 rimColor = POI2D_SAMPLER_PAN(_RimTex, _MainTex, poiUV(poiMesh.uv[_RimTexUV], _RimTex_ST), _RimTexPan);
				#else
				float4 rimColor = 1;
				#endif
				half AudioLinkRimWidthBand = 0;
				float2 AudioLinkRimWidthAdd = 0;
				half AudioLinkRimEmissionBand = 0;
				float2 AudioLinkRimEmissionAdd = 0;
				half AudioLinkRimBrightnessBand = 0;
				float2 AudioLinkRimBrightnessAdd = 0;
				#ifdef POI_AUDIOLINK
				AudioLinkRimWidthBand = _AudioLinkRimWidthBand;
				AudioLinkRimWidthAdd = _AudioLinkRimWidthAdd;
				AudioLinkRimEmissionBand = _AudioLinkRimEmissionBand;
				AudioLinkRimEmissionAdd = _AudioLinkRimEmissionAdd;
				AudioLinkRimBrightnessBand = _AudioLinkRimBrightnessBand;
				AudioLinkRimBrightnessAdd = _AudioLinkRimBrightnessAdd;
				#endif
				
				ApplyPoiyomiRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, _Is_NormalMapToRimLight, _RimLightingInvert, _RimPower, _RimStrength, _RimShadowWidth, _RimShadowToggle, _RimWidth, _RimBlendStrength, rimMask, _RimGlobalMask, _RimGlobalMaskBlendType, rimColor, _RimLightColor, _RimLightColorThemeIndex, _RimHueShiftEnabled, _RimHueShift, _RimHueShiftSpeed, _RimSharpness, _RimShadowMaskRampType, _RimShadowMaskInvert, _RimShadowMaskStrength, _RimShadowAlpha, _RimApplyGlobalMaskIndex, _RimApplyGlobalMaskBlendType, _RimBaseColorMix, _RimBrightness, _RimPoiBlendMode, AudioLinkRimWidthBand, AudioLinkRimWidthAdd, AudioLinkRimEmissionBand, AudioLinkRimEmissionAdd, AudioLinkRimBrightnessBand, AudioLinkRimBrightnessAdd, rimBias, _RimBiasIntensity, _RimApplyAlpha, _RimApplyAlphaBlend);
				#endif
				#ifdef _RIMSTYLE_UTS2
				#if defined(PROP_SET_RIMLIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float Set_RimLightMask_var = POI2D_SAMPLER_PAN(_Set_RimLightMask, _MainTex, poiUV(poiMesh.uv[_Set_RimLightMaskUV], _Set_RimLightMask_ST), _Set_RimLightMaskPan)[_Set_RimLightMaskChannel];
				#else
				float Set_RimLightMask_var = 1;
				#endif
				ApplyUTS2RimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, Set_RimLightMask_var, _RimGlobalMask, _RimGlobalMaskBlendType, _RimLightColor, _RimLightColorThemeIndex, _Is_LightColor_RimLight, _Is_NormalMapToRimLight, _RimLight_Power, _RimLight_InsideMask, _RimLight_FeatherOff, _LightDirection_MaskOn, _Tweak_LightDirection_MaskLevel, _Add_Antipodean_RimLight, _Ap_RimLightColor, _RimApColorThemeIndex, _Is_LightColor_Ap_RimLight, _Ap_RimLight_Power, _Ap_RimLight_FeatherOff, _Tweak_RimLightMaskLevel, _RimHueShiftEnabled, _RimHueShift, _RimHueShiftSpeed);
				#endif
				
				#endif
				//endex
				//ifex _EnableRim2Lighting==0
				#ifdef POI_RIM2
				#ifdef _RIM2STYLE_POIYOMI
				#if defined(PROP_RIM2MASK) || !defined(OPTIMIZER_ENABLED)
				float4 rim2MaskAndBias = POI2D_SAMPLER_PAN(_Rim2Mask, _MainTex, poiUV(poiMesh.uv[_Rim2MaskUV], _Rim2Mask_ST), _Rim2MaskPan);
				float rim2Mask = rim2MaskAndBias[_Rim2MaskChannel];
				float rim2Bias = rim2MaskAndBias.a;
				#else
				float rim2Mask = 1;
				float rim2Bias = 0;
				#endif
				
				if (_Rim2MaskInvert)
				{
					rim2Mask = 1 - rim2Mask;
				}
				
				#if defined(PROP_RIM2TEX) || !defined(OPTIMIZER_ENABLED)
				float4 rim2Color = POI2D_SAMPLER_PAN(_Rim2Tex, _MainTex, poiUV(poiMesh.uv[_Rim2TexUV], _Rim2Tex_ST), _Rim2TexPan);
				#else
				float4 rim2Color = 1;
				#endif
				half AudioLinkRim2WidthBand = 0;
				float2 AudioLinkRim2WidthAdd = 0;
				half AudioLinkRim2EmissionBand = 0;
				float2 AudioLinkRim2EmissionAdd = 0;
				half AudioLinkRim2BrightnessBand = 0;
				float2 AudioLinkRim2BrightnessAdd = 0;
				#ifdef POI_AUDIOLINK
				AudioLinkRim2WidthBand = _AudioLinkRim2WidthBand;
				AudioLinkRim2WidthAdd = _AudioLinkRim2WidthAdd;
				AudioLinkRim2EmissionBand = _AudioLinkRim2EmissionBand;
				AudioLinkRim2EmissionAdd = _AudioLinkRim2EmissionAdd;
				AudioLinkRim2BrightnessBand = _AudioLinkRim2BrightnessBand;
				AudioLinkRim2BrightnessAdd = _AudioLinkRim2BrightnessAdd;
				#endif
				ApplyPoiyomiRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, _Is_NormalMapToRim2Light, _Rim2LightingInvert, _Rim2Power, _Rim2Strength, _Rim2ShadowWidth, _Rim2ShadowToggle, _Rim2Width, _Rim2BlendStrength, rim2Mask, _Rim2GlobalMask, _Rim2GlobalMaskBlendType, rim2Color, _Rim2LightColor, _Rim2LightColorThemeIndex, _Rim2HueShiftEnabled, _Rim2HueShift, _Rim2HueShiftSpeed, _Rim2Sharpness, _Rim2ShadowMaskRampType, _Rim2ShadowMaskInvert, _Rim2ShadowMaskStrength, _Rim2ShadowAlpha, _Rim2ApplyGlobalMaskIndex, _Rim2ApplyGlobalMaskBlendType, _Rim2BaseColorMix, _Rim2Brightness, _RimPoi2BlendMode, AudioLinkRim2WidthBand, AudioLinkRim2WidthAdd, AudioLinkRim2EmissionBand, AudioLinkRim2EmissionAdd, AudioLinkRim2BrightnessBand, AudioLinkRim2BrightnessAdd, rim2Bias, _Rim2BiasIntensity, _Rim2ApplyAlpha, _Rim2ApplyAlphaBlend);
				#endif
				#ifdef _RIM2STYLE_UTS2
				#if defined(PROP_SET_RIM2LIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float Set_Rim2LightMask_var = POI2D_SAMPLER_PAN(_Set_Rim2LightMask, _MainTex, poiUV(poiMesh.uv[_Set_Rim2LightMaskUV], _Set_Rim2LightMask_ST), _Set_Rim2LightMaskPan)[_Set_Rim2LightMaskChannel];
				#else
				float Set_Rim2LightMask_var = 1;
				#endif
				ApplyUTS2RimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, Set_Rim2LightMask_var, _Rim2GlobalMask, _Rim2GlobalMaskBlendType, _Rim2LightColor, _Rim2LightColorThemeIndex, _Is_LightColor_Rim2Light, _Is_NormalMapToRim2Light, _Rim2Light_Power, _Rim2Light_InsideMask, _Rim2Light_FeatherOff, _LightDirection_MaskOn2, _Tweak_LightDirection_MaskLevel2, _Add_Antipodean_Rim2Light, _Ap_Rim2LightColor, _Rim2ApColorThemeIndex, _Is_LightColor_Ap_Rim2Light, _Ap_Rim2Light_Power, _Ap_Rim2Light_FeatherOff, _Tweak_Rim2LightMaskLevel, _Rim2HueShiftEnabled, _Rim2HueShift, _Rim2HueShiftSpeed);
				#endif
				
				#endif
				//endex
				
				//ifex _EnableDepthRimLighting==0
				#ifdef _POI_DEPTH_RIMLIGHT
				if (!IsInMirror())
				{
					ApplyDepthRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods);
				}
				#endif
				//endex
				
				//ifex _GlitterEnable==0
				#ifdef _SUNDISK_SIMPLE
				applyGlitter(poiFragData, poiMesh, poiCam, poiLight, poiMods);
				#endif
				//endex
				
				//ifex _StylizedSpecular==0
				#ifdef POI_STYLIZED_StylizedSpecular
				stylizedSpecular(poiFragData, poiCam, poiLight, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _EnablePathing==0
				#ifdef POI_PATHING
				// Only run pathing if a map exists.
				#if defined(PROP_PATHINGMAP) || !defined(OPTIMIZER_ENABLED)
				applyPathing(poiFragData, poiMesh, poiMods);
				#endif
				#endif
				//endex
				
				//ifex _EnableMirrorOptions==0
				#ifdef POI_MIRROR
				applyMirror(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _TextEnabled==0
				#ifdef EFFECT_BUMP
				ApplyTextOverlayColor(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _VoronoiEnabled!=1
				#ifdef POI_VORONOI
				ApplyVoronoi(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				if (_AlphaPremultiply)
				{
					poiFragData.baseColor *= saturate(poiFragData.alpha);
				}
				poiFragData.finalColor = poiFragData.baseColor;
				
				poiFragData.finalColor = poiFragData.baseColor * poiLight.finalLighting;
				
				//ifex _SubsurfaceScattering==0
				#ifdef POI_SUBSURFACESCATTERING
				applySubsurfaceScattering(poiCam, poiLight, poiMesh, poiFragData);
				#endif
				//endex
				
				//ifex _MochieBRDF==0
				#ifdef MOCHIE_PBR
				MochieBRDF(poiFragData, poiCam, poiLight, poiMesh, poiMods);
				#endif
				//endex
				//ifex _ClearCoatBRDF==0
				#ifdef POI_CLEARCOAT
				poiClearCoat(poiFragData, poiCam, poiLight, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _BacklightEnabled!=1
				#ifdef POI_BACKLIGHT
				ApplyBacklight(poiFragData, poiMesh, poiLight, poiCam, poiMods);
				#endif
				//endex
				
				//ifex _EnableRimLighting==0
				#ifdef _GLOSSYREFLECTIONS_OFF
				#ifdef _RIMSTYLE_LILTOON
				#if defined(PROP_RIMCOLORTEX) || !defined(OPTIMIZER_ENABLED)
				float4 rimColorTex = POI2D_SAMPLER_PAN(_RimColorTex, _MainTex, poiUV(poiMesh.uv[_RimColorTexUV], _RimColorTex_ST), _RimColorTexPan);
				#else
				float4 rimColorTex = 1;
				#endif
				ApplyLiltoonRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, _RimColor, _RimIndirColor, rimColorTex, _RimMainStrength, _RimNormalStrength, _RimDirRange, _RimIndirRange, _RimFresnelPower, _RimBackfaceMask, _RimDirStrength, _RimBorder, _RimBlur, _RimIndirBorder, _RimIndirBlur, _RimShadowMask, _RimEnableLighting, _RimVRParallaxStrength, _RimGlobalMask, _RimGlobalMaskBlendType, _RimHueShiftEnabled, _RimHueShift, _RimHueShiftSpeed, _RimBlendMode);
				#endif
				#endif
				//endex
				//ifex _EnableRim2Lighting==0
				#ifdef POI_RIM2
				#ifdef _RIM2STYLE_LILTOON
				#if defined(PROP_RIM2COLORTEX) || !defined(OPTIMIZER_ENABLED)
				float4 rim2ColorTex = POI2D_SAMPLER_PAN(_Rim2ColorTex, _MainTex, poiUV(poiMesh.uv[_Rim2ColorTexUV], _Rim2ColorTex_ST), _Rim2ColorTexPan);
				#else
				float4 rim2ColorTex = 1;
				#endif
				ApplyLiltoonRimLighting(poiFragData, poiMesh, poiCam, poiLight, poiMods, _Rim2Color, _Rim2IndirColor, rim2ColorTex, _Rim2MainStrength, _Rim2NormalStrength, _Rim2DirRange, _Rim2IndirRange, _Rim2FresnelPower, _Rim2BackfaceMask, _Rim2DirStrength, _Rim2Border, _Rim2Blur, _Rim2IndirBorder, _Rim2IndirBlur, _Rim2ShadowMask, _Rim2EnableLighting, _Rim2VRParallaxStrength, _Rim2GlobalMask, _Rim2GlobalMaskBlendType, _Rim2HueShiftEnabled, _Rim2HueShift, _Rim2HueShiftSpeed, _Rim2BlendMode);
				#endif
				#endif
				//endex
				
				//ifex _FXProximityColor==0
				if (_FXProximityColor)
				{
					float3 position = _FXProximityColorType ? poiMesh.worldPos : poiMesh.objectPosition;
					poiFragData.finalColor *= lerp(poiThemeColor(poiMods, _FXProximityColorMinColor.rgb, _FXProximityColorMinColorThemeIndex), poiThemeColor(poiMods, _FXProximityColorMaxColor.rgb, _FXProximityColorMaxColorThemeIndex), smoothstep(_FXProximityColorMinDistance, _FXProximityColorMaxDistance, distance(position, poiCam.worldPos)));
					
					if (_FXProximityColorBackFace)
					{
						poiFragData.finalColor = lerp(poiFragData.finalColor * _FXProximityColorMinColor.rgb, poiFragData.finalColor, saturate(poiMesh.isFrontFace));
					}
				}
				//endex
				
				//UNITY_BRANCH
				if (_IgnoreFog == 0)
				{
					UNITY_APPLY_FOG(i.fogCoord, poiFragData.finalColor);
				}
				
				poiFragData.alpha = _AlphaForceOpaque ? 1 : poiFragData.alpha;
				
				//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
				ApplyAlphaToCoverage(poiFragData, poiMesh);
				//endex
				
				//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
				applyDithering(poiFragData, poiCam);
				//endex
				
				poiFragData.finalColor += poiLight.finalLightAdd;
				
				if (_Mode == POI_MODE_OPAQUE)
				{
					poiFragData.alpha = 1;
				}
				
				clip(poiFragData.alpha - _Cutoff);
				
				if (_Mode == POI_MODE_CUTOUT && !_AlphaToCoverage)
				{
					poiFragData.alpha = 1;
				}
				
				if (_AddBlendOp == 4)
				{
					poiFragData.alpha = saturate(poiFragData.alpha * _AlphaBoostFA);
				}
				
				if (_Mode != POI_MODE_TRANSPARENT)
				{
					poiFragData.finalColor *= poiFragData.alpha;
				}
				
				//ifex _BSSEnabled!=1
				#ifdef POIBS_ENABLE
				poiFragData.finalColor += poiFragData.emission * poiMods.globalEmission;
				poiFragData.alpha = poiFragData.alpha * poiFragData.emission.z;
				poiFragData.emission = 0;
				
				//ifex _BSSBloomfog!=1
				#ifdef POIBS_BLOOMFOG
				float3 fogDistance = i.worldPos + - _WorldSpaceCameraPos;
				float4 fogCol = -float4(poiFragData.finalColor, 1) + tex2D(_BloomPrePassTexture, i.fogCoord.xy);
				fogCol.a = -poiFragData.alpha;
				
				#ifdef BSSBLOOMFOGTYPE_HEIGHT
				poiFragData.finalColor = poiFragData.finalColor + (((GetHeightFogIntensity(i.worldPos, _FogHeightOffset, _FogHeightScale) * GetFogIntensity(fogDistance, _FogStartOffset, _FogScale)) + 1) * fogCol.rgb);
				poiFragData.alpha = poiFragData.alpha + (((GetHeightFogIntensity(i.worldPos, _FogHeightOffset, _FogHeightScale) * GetFogIntensity(fogDistance, _FogStartOffset, _FogScale)) + 1) * fogCol.a);
				#else
				poiFragData.finalColor = poiFragData.finalColor + ((GetFogIntensity(fogDistance, _FogStartOffset, _FogScale) + 1) * fogCol.rgb);
				poiFragData.alpha = poiFragData.alpha + ((GetFogIntensity(fogDistance, _FogStartOffset, _FogScale) + 1) * fogCol.a);
				#endif
				#endif
				//endex
				#endif
				//endex
				
				return float4(poiFragData.finalColor, poiFragData.alpha) + POI_SAFE_RGB0;
			}
			
			ENDCG
		}
		
		Pass
		{
			Name "ShadowCaster"
			Tags { "LightMode" = "ShadowCaster" }
			
			Stencil
			{
				Ref [_StencilRef]
				ReadMask [_StencilReadMask]
				WriteMask [_StencilWriteMask]
				//ifex _StencilType==1
				Comp [_StencilCompareFunction]
				Pass [_StencilPassOp]
				Fail [_StencilFailOp]
				ZFail [_StencilZFailOp]
				//endex
				
				//ifex _StencilType==0
				CompBack [_StencilBackCompareFunction]
				PassBack [_StencilBackPassOp]
				FailBack [_StencilBackFailOp]
				ZFailBack [_StencilBackZFailOp]
				
				CompFront [_StencilFrontCompareFunction]
				PassFront [_StencilFrontPassOp]
				FailFront [_StencilFrontFailOp]
				ZFailFront [_StencilFrontZFailOp]
				//endex
			}
			
			ZWrite [_ZWrite]
			Cull [_Cull]
			AlphaToMask Off
			ZTest [_ZTest]
			ColorMask [_ColorMask]
			Offset [_OffsetFactor], [_OffsetUnits]
			
			BlendOp [_BlendOp], [_BlendOpAlpha]
			Blend [_SrcBlend] [_DstBlend], [_SrcBlendAlpha] [_DstBlendAlpha]
			
			CGPROGRAM
			/*
			// Disable warnings we aren't interested in
			#if defined(UNITY_COMPILER_HLSL)
			#pragma warning(disable : 3205) // conversion of larger type to smaller
			#pragma warning(disable : 3568) // unknown pragma ignored
			#pragma warning(disable : 3571) // "pow(f,e) will not work for negative f"; however in majority of our calls to pow we know f is not negative
			#pragma warning(disable : 3206) // implicit truncation of vector type
			#endif
			*/
			#pragma target 5.0
			//ifex 0==0
			#pragma skip_optimizations d3d11
			//endex
			
			#pragma shader_feature_local _STOCHASTICMODE_DELIOT_HEITZ _STOCHASTICMODE_HEXTILE _STOCHASTICMODE_NONE
			
			//ifex _MainColorAdjustToggle==0
			#pragma shader_feature COLOR_GRADING_HDR
			//endex
			
			//#pragma shader_feature KEYWORD
			
			#pragma skip_variants LIGHTMAP_ON DYNAMICLIGHTMAP_ON LIGHTMAP_SHADOW_MIXING SHADOWS_SHADOWMASK DIRLIGHTMAP_COMBINED _MIXED_LIGHTING_SUBTRACTIVE
			#pragma skip_variants DECALS_OFF DECALS_3RT DECALS_4RT DECAL_SURFACE_GRADIENT _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3
			#pragma skip_variants _ADDITIONAL_LIGHT_SHADOWS
			#pragma skip_variants PROBE_VOLUMES_OFF PROBE_VOLUMES_L1 PROBE_VOLUMES_L2
			#pragma skip_variants _SCREEN_SPACE_OCCLUSION
			
			//ifex _GlobalMaskTexturesEnable==0
			#pragma shader_feature_local POI_GLOBALMASK_TEXTURES
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#pragma shader_feature_local POI_UDIMDISCARD
			//endex
			
			//ifex _EnableDistortion==0
			#pragma shader_feature USER_LUT
			//endex
			
			//ifex _PoiParallax==0
			#pragma shader_feature_local POI_PARALLAX
			//endex
			
			//ifex _EnableAudioLink==0
			#pragma shader_feature_local POI_AUDIOLINK
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#pragma shader_feature_local POI_BLACKLIGHTMASKING
			//endex
			
			//ifex _DetailEnabled==0
			#pragma shader_feature FINALPASS
			//endex
			
			//ifex _VertexManipulationsEnabled==0
			#pragma shader_feature AUTO_EXPOSURE
			//endex
			
			//ifex _VertexGlitchingEnabled==0
			#pragma shader_feature_local POI_VERTEX_GLITCHING
			#pragma shader_feature_local POI_VERTEX_GLITCHING_TEXTURE
			//endex
			
			//ifex _EnableDepthBulge==0
			#pragma shader_feature_local POI_DEPTHBULGE
			//endex
			
			//ifex _BackFaceEnabled!=1
			#pragma shader_feature_local POI_BACKFACE
			//endex
			
			//ifex _RGBMaskEnabled==0
			#pragma shader_feature VIGNETTE
			#pragma shader_feature GEOM_TYPE_MESH
			//endex
			
			//ifex _LTCGIEnabled!=1
			#pragma shader_feature_local POI_LTCGI
			//endex
			
			//ifex _ShadingEnabled==0
			#pragma shader_feature_local VIGNETTE_MASKED
			#pragma shader_feature_local _LIGHTINGMODE_TEXTURERAMP _LIGHTINGMODE_MULTILAYER_MATH _LIGHTINGMODE_SHADEMAP _LIGHTINGMODE_REALISTIC _LIGHTINGMODE_WRAPPED _LIGHTINGMODE_SKIN _LIGHTINGMODE_FLAT _LIGHTINGMODE_CLOTH _LIGHTINGMODE_SDF
			//endex
			
			//ifex _DecalEnabled==0
			#pragma shader_feature GEOM_TYPE_BRANCH
			//endex
			//ifex _DecalEnabled1==0
			#pragma shader_feature GEOM_TYPE_BRANCH_DETAIL
			//endex
			//ifex _DecalEnabled2==0
			#pragma shader_feature GEOM_TYPE_FROND
			//endex
			//ifex _DecalEnabled3==0
			#pragma shader_feature DEPTH_OF_FIELD_COC_VIEW
			//endex
			
			//ifex _EnableDissolve==0
			#pragma shader_feature DISTORT
			//endex
			
			//ifex _EnableAniso==0
			#pragma shader_feature_local POI_ANISOTROPICS
			//endex
			
			//ifex _MatcapEnable==0
			#pragma shader_feature_local POI_MATCAP0
			#pragma shader_feature_local POI_MATCAP0_CUSTOM_NORMAL
			//endex
			//ifex _Matcap2Enable==0
			#pragma shader_feature COLOR_GRADING_HDR_3D
			#pragma shader_feature_local POI_MATCAP1_CUSTOM_NORMAL
			//endex
			//ifex _Matcap3Enable==0
			#pragma shader_feature_local POI_MATCAP2
			#pragma shader_feature_local POI_MATCAP2_CUSTOM_NORMAL
			//endex
			//ifex _Matcap4Enable==0
			#pragma shader_feature_local POI_MATCAP3
			#pragma shader_feature_local POI_MATCAP3_CUSTOM_NORMAL
			//endex
			
			//ifex _CubeMapEnabled==0
			#pragma shader_feature_local _CUBEMAP
			//endex
			
			//ifex _EnableALDecal==0
			#pragma shader_feature_local POI_AL_DECAL
			//endex
			
			//ifex _EnableVolumeColor==0
			#pragma shader_feature_local POI_AL_VOLUMECOLOR
			//endex
			
			//ifex _EnableFlipbook==0
			#pragma shader_feature _SUNDISK_HIGH_QUALITY
			//endex
			
			//ifex _EnableEmission==0
			#pragma shader_feature _EMISSION
			//endex
			//ifex _EnableEmission1==0
			#pragma shader_feature_local POI_EMISSION_1
			//endex
			//ifex _EnableEmission2==0
			#pragma shader_feature_local POI_EMISSION_2
			//endex
			//ifex _EnableEmission3==0
			#pragma shader_feature_local POI_EMISSION_3
			//endex
			
			//ifex _EnableRimLighting==0
			#pragma shader_feature_local _GLOSSYREFLECTIONS_OFF
			#pragma shader_feature_local _RIMSTYLE_POIYOMI _RIMSTYLE_UTS2 _RIMSTYLE_LILTOON
			//endex
			//ifex _EnableRim2Lighting==0
			#pragma shader_feature_local POI_RIM2
			#pragma shader_feature_local _RIM2STYLE_POIYOMI _RIM2STYLE_UTS2 _RIM2STYLE_LILTOON
			//endex
			
			//ifex _EnableDepthRimLighting==0
			#pragma shader_feature_local _POI_DEPTH_RIMLIGHT
			//endex
			
			//ifex _GlitterEnable==0
			#pragma shader_feature _SUNDISK_SIMPLE
			//endex
			
			//ifex _SubsurfaceScattering==0
			#pragma shader_feature_local POI_SUBSURFACESCATTERING
			//endex
			
			//ifex _MochieBRDF==0
			#pragma shader_feature_local MOCHIE_PBR
			//endex
			//ifex _ClearCoatBRDF==0
			#pragma shader_feature_local POI_CLEARCOAT
			//endex
			
			//ifex _EnableEnvironmentalRim==0
			#pragma shader_feature_local POI_ENVIRORIM
			//endex
			
			//ifex _StylizedSpecular==0
			#pragma shader_feature_local POI_STYLIZED_StylizedSpecular
			//endex
			
			//ifex _EnablePathing==0
			#pragma shader_feature_local POI_PATHING
			//endex
			
			//ifex _EnableMirrorOptions==0
			#pragma shader_feature_local POI_MIRROR
			//endex
			
			//ifex _EnableTouchGlow==0
			#pragma shader_feature GRAIN
			//endex
			
			//ifex _TextEnabled==0
			#pragma shader_feature EFFECT_BUMP
			//endex
			
			//ifex _PostProcess==0
			#pragma shader_feature_local POSTPROCESS
			//endex
			
			//ifex _PoiInternalParallax==0
			#pragma shader_feature_local POI_INTERNALPARALLAX
			//endex
			
			//ifex _NormalCorrect==0
			#pragma shader_feature_local POI_NORMALCORRECT
			//endex
			
			//ifex _VideoEffectsEnable==0
			#pragma shader_feature_local POI_VIDEO_EFFECTS
			//endex
			
			//ifex _BacklightEnabled!=1
			#pragma shader_feature_local POI_BACKLIGHT
			//endex
			
			//ifex _BSSEnabled!=1
			#pragma shader_feature_local POIBS_ENABLE
			//ifex _BSSBloomfog!=1
			#pragma shader_feature_local POIBS_BLOOMFOG
			#pragma shader_feature_local BSSBLOOMFOGTYPE_HEIGHT
			//endex
			//endex
			
			//ifex _VoronoiEnabled!=1
			#pragma shader_feature_local POI_VORONOI
			//endex
			
			#pragma skip_variants FOG_LINEAR FOG_EXP FOG_EXP2
			#pragma multi_compile_instancing
			#pragma multi_compile_shadowcaster
			#pragma multi_compile_fog
			#define POI_PASS_SHADOW
			
			// UNITY Includes
			#include "UnityCG.cginc"
			#include "UnityStandardUtils.cginc"
			#include "AutoLight.cginc"
			#include "UnityLightingCommon.cginc"
			#include "UnityPBSLighting.cginc"
			#ifdef POI_PASS_META
			#include "UnityMetaPass.cginc"
			#endif
			#pragma vertex vert
			
			#pragma fragment frag
			
			#define DielectricSpec float4(0.04, 0.04, 0.04, 1.0 - 0.04)
			#define PI float(3.14159265359)
			#define Epsilon float(1e-10)
			
			#define POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, samplertex, coord, dx, dy) tex.SampleGrad(sampler##samplertex, coord, dx, dy)
			#define POI2D_SAMPLE_TEX2D_SAMPLERGRADD(tex, samp, uv, pan, dx, dy) tex.SampleGrad(samp, POI_PAN_UV(uv, pan), dx, dy)
			
			#define POI_PAN_UV(uv, pan) (uv + _Time.x * pan)
			#define POI2D_SAMPLER_PAN(tex, texSampler, uv, pan) (UNITY_SAMPLE_TEX2D_SAMPLER(tex, texSampler, POI_PAN_UV(uv, pan)))
			#define POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy) (POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, texSampler, POI_PAN_UV(uv, pan), dx, dy))
			#define POI2D_SAMPLER(tex, texSampler, uv) (UNITY_SAMPLE_TEX2D_SAMPLER(tex, texSampler, uv))
			#define POI_SAMPLE_1D_X(tex, samp, uv) tex.Sample(samp, float2(uv, 0.5))
			#define POI2D_SAMPLER_GRAD(tex, texSampler, uv, dx, dy) (POI2D_SAMPLE_TEX2D_SAMPLERGRAD(tex, texSampler, uv, dx, dy))
			#define POI2D_SAMPLER_GRADD(tex, texSampler, uv, dx, dy) tex.SampleGrad(texSampler, uv, dx, dy)
			#define POI2D_PAN(tex, uv, pan) (tex2D(tex, POI_PAN_UV(uv, pan)))
			#define POI2D(tex, uv) (tex2D(tex, uv))
			#define POI_SAMPLE_TEX2D(tex, uv) (UNITY_SAMPLE_TEX2D(tex, uv))
			#define POI_SAMPLE_TEX2D_PAN(tex, uv, pan) (UNITY_SAMPLE_TEX2D(tex, POI_PAN_UV(uv, pan)))
			#define POI_SAMPLE_CUBE_LOD(tex, samp, uv, lod) texCUBElod(tex, float4(uv, 0, lod))
			
			#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
			#define POI_SAMPLE_SCREEN(tex, samp, uv)          tex.Sample(samp, float3(uv, unity_StereoEyeIndex))
			#else
			#define POI_SAMPLE_SCREEN(tex, samp, uv)          tex.Sample(samp, uv)
			#endif
			
			// When using, properties won't properly lock at optimize time; needs macro evaluation implemented
			// #define POI2D_MAINTEX_SAMPLER_PAN_INLINED(tex, poiMesh) (POI2D_SAMPLER_PAN(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan))
			
			#define POI_SAFE_RGB0 float4(mainTexture.rgb * .0001, 0)
			#define POI_SAFE_RGB1 float4(mainTexture.rgb * .0001, 1)
			#define POI_SAFE_RGBA mainTexture
			
			#if defined(UNITY_COMPILER_HLSL)
			#define PoiInitStruct(type, name) name = (type)0;
			#else
			#define PoiInitStruct(type, name)
			#endif
			
			#define POI_ERROR(poiMesh, gridSize) lerp(float3(1, 0, 1), float3(0, 0, 0), fmod(floor((poiMesh.worldPos.x) * gridSize) + floor((poiMesh.worldPos.y) * gridSize) + floor((poiMesh.worldPos.z) * gridSize), 2) == 0)
			#define POI_NAN (asfloat(-1))
			
			#define POI_MODE_OPAQUE 0
			#define POI_MODE_CUTOUT 1
			#define POI_MODE_FADE 2
			#define POI_MODE_TRANSPARENT 3
			#define POI_MODE_ADDITIVE 4
			#define POI_MODE_SOFTADDITIVE 5
			#define POI_MODE_MULTIPLICATIVE 6
			#define POI_MODE_2XMULTIPLICATIVE 7
			#define POI_MODE_TRANSCLIPPING 9
			
			/*
			Texture2D ;
			float4 _ST;
			float2 Pan;
			float UV;
			float Stochastic;
			
			[HideInInspector][ThryWideEnum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Panosphere, 4, World Pos XZ, 5, Polar UV, 6, Distorted UV, 7 )]
			*/
			
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			// Map of where features in AudioLink are.
			#define ALPASS_DFT                      uint2(0, 4)   //Size: 128, 2
			#define ALPASS_WAVEFORM                 uint2(0, 6)   //Size: 128, 16
			#define ALPASS_AUDIOLINK                uint2(0, 0)   //Size: 128, 4
			#define ALPASS_AUDIOBASS                uint2(0, 0)   //Size: 128, 1
			#define ALPASS_AUDIOLOWMIDS             uint2(0, 1)   //Size: 128, 1
			#define ALPASS_AUDIOHIGHMIDS            uint2(0, 2)   //Size: 128, 1
			#define ALPASS_AUDIOTREBLE              uint2(0, 3)   //Size: 128, 1
			#define ALPASS_AUDIOLINKHISTORY         uint2(1, 0)   //Size: 127, 4
			#define ALPASS_GENERALVU                uint2(0, 22)  //Size: 12, 1
			#define ALPASS_CCINTERNAL               uint2(12, 22) //Size: 12, 2
			#define ALPASS_CCCOLORS                 uint2(25, 22) //Size: 11, 1
			#define ALPASS_CCSTRIP                  uint2(0, 24)  //Size: 128, 1
			#define ALPASS_CCLIGHTS                 uint2(0, 25)  //Size: 128, 2
			#define ALPASS_AUTOCORRELATOR           uint2(0, 27)  //Size: 128, 1
			#define ALPASS_GENERALVU_INSTANCE_TIME  uint2(2, 22)
			#define ALPASS_GENERALVU_LOCAL_TIME     uint2(3, 22)
			#define ALPASS_GENERALVU_NETWORK_TIME   uint2(4, 22)
			#define ALPASS_GENERALVU_PLAYERINFO     uint2(6, 22)
			// Added in version 2.5
			#define ALPASS_FILTEREDAUDIOLINK        uint2(0, 28)  //Size: 16, 4
			// Added in version 2.6
			#define ALPASS_CHRONOTENSITY            uint2(16, 28) //Size: 8, 4
			#define ALPASS_THEME_COLOR0             uint2(0, 23)
			#define ALPASS_THEME_COLOR1             uint2(1, 23)
			#define ALPASS_THEME_COLOR2             uint2(2, 23)
			#define ALPASS_THEME_COLOR3             uint2(3, 23)
			#define ALPASS_FILTEREDVU               uint2(24, 28) //Size: 4, 4
			#define ALPASS_FILTEREDVU_INTENSITY     uint2(24, 28) //Size: 4, 1
			#define ALPASS_FILTEREDVU_MARKER        uint2(24, 29) //Size: 4, 1
			
			// Some basic constants to use (Note, these should be compatible with
			// future version of AudioLink, but may change.
			#define AUDIOLINK_SAMPHIST              3069        // Internal use for algos, do not change.
			#define AUDIOLINK_SAMPLEDATA24          2046
			#define AUDIOLINK_EXPBINS               24
			#define AUDIOLINK_EXPOCT                10
			#define AUDIOLINK_ETOTALBINS (AUDIOLINK_EXPBINS * AUDIOLINK_EXPOCT)
			#define AUDIOLINK_WIDTH                 128
			#define AUDIOLINK_SPS                   48000       // Samples per second
			#define AUDIOLINK_ROOTNOTE              0
			#define AUDIOLINK_4BAND_FREQFLOOR       0.123
			#define AUDIOLINK_4BAND_FREQCEILING     1
			#define AUDIOLINK_BOTTOM_FREQUENCY      13.75
			#define AUDIOLINK_BASE_AMPLITUDE        2.5
			#define AUDIOLINK_DELAY_COEFFICIENT_MIN 0.3
			#define AUDIOLINK_DELAY_COEFFICIENT_MAX 0.9
			#define AUDIOLINK_DFT_Q                 4.0
			#define AUDIOLINK_TREBLE_CORRECTION     5.0
			
			// ColorChord constants
			#define COLORCHORD_EMAXBIN              192
			#define COLORCHORD_IIR_DECAY_1          0.90
			#define COLORCHORD_IIR_DECAY_2          0.85
			#define COLORCHORD_CONSTANT_DECAY_1     0.01
			#define COLORCHORD_CONSTANT_DECAY_2     0.0
			#define COLORCHORD_NOTE_CLOSEST         3.0
			#define COLORCHORD_NEW_NOTE_GAIN        8.0
			#define COLORCHORD_MAX_NOTES            10
			
			uniform float4               _AudioTexture_TexelSize;
			
			#ifdef SHADER_TARGET_SURFACE_ANALYSIS
			#define AUDIOLINK_STANDARD_INDEXING
			#endif
			
			// Mechanism to index into texture.
			#ifdef AUDIOLINK_STANDARD_INDEXING
			sampler2D _AudioTexture;
			#define AudioLinkData(xycoord) tex2Dlod(_AudioTexture, float4(uint2(xycoord) * _AudioTexture_TexelSize.xy, 0, 0))
			#else
			uniform Texture2D<float4> _AudioTexture;
			SamplerState sampler_AudioTexture;
			#define AudioLinkData(xycoord) _AudioTexture[uint2(xycoord)]
			#endif
			uniform sampler2D _Stored;
			uniform float4 _Stored_TexelSize;
			#endif
			//endex
			
			float _GrabMode;
			float _Mode;
			
			float _StochasticDeliotHeitzDensity;
			float _StochasticHexGridDensity;
			float _StochasticHexRotationStrength;
			float _StochasticHexFallOffContrast;
			float _StochasticHexFallOffPower;
			
			float _IgnoreFog;
			float _RenderingReduceClipDistance;
			int _FlipBackfaceNormals;
			float _AddBlendOp;
			float _Cull;
			
			float4 _Color;
			float _ColorThemeIndex;
			UNITY_DECLARE_TEX2D(_MainTex);
			UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
			float _MainPixelMode;
			float4 _MainTex_ST;
			float2 _MainTexPan;
			float _MainTexUV;
			float4 _MainTex_TexelSize;
			float _MainTexStochastic;
			#if defined(PROP_BUMPMAP) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BumpMap;
			#endif
			float4 _BumpMap_ST;
			float2 _BumpMapPan;
			float _BumpMapUV;
			float _BumpScale;
			float _BumpMapStochastic;
			#if defined(PROP_ALPHAMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _AlphaMask;
			float4 _AlphaMask_ST;
			float2 _AlphaMaskPan;
			float _AlphaMaskUV;
			float _AlphaMaskInvert;
			float _MainAlphaMaskMode;
			float _AlphaMaskScale;
			float _AlphaMaskValue;
			#endif
			float _Cutoff;
			//ifex _MainColorAdjustToggle==0
			#ifdef COLOR_GRADING_HDR
			float _MainColorAdjustToggle;
			#if defined(PROP_MAINCOLORADJUSTTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MainColorAdjustTexture;
			#endif
			float4 _MainColorAdjustTexture_ST;
			float2 _MainColorAdjustTexturePan;
			float _MainColorAdjustTextureUV;
			float _MainHueShiftToggle;
			float _MainHueShiftReplace;
			float _MainHueShift;
			float _MainHueShiftSpeed;
			float _Saturation;
			float _MainBrightness;
			
			float _MainHueALCTEnabled;
			float _MainALHueShiftBand;
			float _MainALHueShiftCTIndex;
			float _MainHueALMotionSpeed;
			
			float _MainHueGlobalMask;
			float _MainHueGlobalMaskBlendType;
			float _MainSaturationGlobalMask;
			float _MainSaturationGlobalMaskBlendType;
			float _MainBrightnessGlobalMask;
			float _MainBrightnessGlobalMaskBlendType;
			
			#if defined(PROP_MAINGRADATIONTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MainGradationTex;
			#endif
			float _ColorGradingToggle;
			float _MainGradationStrength;
			#endif
			//endex
			
			SamplerState sampler_linear_clamp;
			SamplerState sampler_linear_repeat;
			SamplerState sampler_trilinear_repeat;
			
			float _AlphaForceOpaque;
			float _AlphaMod;
			float _AlphaPremultiply;
			float _AlphaBoostFA;
			//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
			float _AlphaToCoverage;
			float _AlphaSharpenedA2C;
			float _AlphaMipScale;
			//endex
			
			//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
			float _AlphaDithering;
			float _AlphaDitherGradient;
			float _AlphaDitherBias;
			//endex
			
			//ifex _AlphaDistanceFade==0 && isNotAnimated(_AlphaDistanceFade)
			float _AlphaDistanceFade;
			float _AlphaDistanceFadeType;
			float _AlphaDistanceFadeMinAlpha;
			float _AlphaDistanceFadeMaxAlpha;
			float _AlphaDistanceFadeMin;
			float _AlphaDistanceFadeMax;
			float _AlphaDistanceFadeGlobalMask;
			float _AlphaDistanceFadeGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaFresnel==0 && isNotAnimated(_AlphaFresnel)
			float _AlphaFresnel;
			float _AlphaFresnelAlpha;
			float _AlphaFresnelSharpness;
			float _AlphaFresnelWidth;
			float _AlphaFresnelInvert;
			float _AlphaFresnelGlobalMask;
			float _AlphaFresnelGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaAngular==0 && isNotAnimated(_AlphaAngular)
			float _AlphaAngular;
			float _AngleType;
			float _AngleCompareTo;
			float3 _AngleForwardDirection;
			float _CameraAngleMin;
			float _CameraAngleMax;
			float _ModelAngleMin;
			float _ModelAngleMax;
			float _AngleMinAlpha;
			float _AlphaAngularGlobalMask;
			float _AlphaAngularGlobalMaskBlendType;
			//endex
			
			//ifex _AlphaAudioLinkEnabled==0 && isNotAnimated(_AlphaAudioLinkEnabled)
			float _AlphaAudioLinkEnabled;
			float2 _AlphaAudioLinkAddRange;
			float _AlphaAudioLinkAddBand;
			//endex
			
			float _AlphaGlobalMask;
			float _AlphaGlobalMaskBlendType;
			
			//ifex _GlobalMaskTexturesEnable==0
			#ifdef POI_GLOBALMASK_TEXTURES
			#if defined(PROP_GLOBALMASKTEXTURE0) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture0;
			#endif
			float4 _GlobalMaskTexture0_ST;
			float2 _GlobalMaskTexture0Pan;
			float _GlobalMaskTexture0UV;
			int _GlobalMaskTexture0Split;
			float4 _GlobalMaskTexture0SplitTilingOffset_G;
			float4 _GlobalMaskTexture0SplitPan_G;
			float4 _GlobalMaskTexture0SplitTilingOffset_B;
			float4 _GlobalMaskTexture0SplitPan_B;
			float4 _GlobalMaskTexture0SplitTilingOffset_A;
			float4 _GlobalMaskTexture0SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture1;
			#endif
			float4 _GlobalMaskTexture1_ST;
			float2 _GlobalMaskTexture1Pan;
			float _GlobalMaskTexture1UV;
			int _GlobalMaskTexture1Split;
			float4 _GlobalMaskTexture1SplitTilingOffset_G;
			float4 _GlobalMaskTexture1SplitPan_G;
			float4 _GlobalMaskTexture1SplitTilingOffset_B;
			float4 _GlobalMaskTexture1SplitPan_B;
			float4 _GlobalMaskTexture1SplitTilingOffset_A;
			float4 _GlobalMaskTexture1SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE2) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture2;
			#endif
			float4 _GlobalMaskTexture2_ST;
			float2 _GlobalMaskTexture2Pan;
			float _GlobalMaskTexture2UV;
			int _GlobalMaskTexture2Split;
			float4 _GlobalMaskTexture2SplitTilingOffset_G;
			float4 _GlobalMaskTexture2SplitPan_G;
			float4 _GlobalMaskTexture2SplitTilingOffset_B;
			float4 _GlobalMaskTexture2SplitPan_B;
			float4 _GlobalMaskTexture2SplitTilingOffset_A;
			float4 _GlobalMaskTexture2SplitPan_A;
			
			#if defined(PROP_GLOBALMASKTEXTURE3) || !defined(OPTIMIZER_ENABLED)
			Texture2D _GlobalMaskTexture3;
			#endif
			float4 _GlobalMaskTexture3_ST;
			float2 _GlobalMaskTexture3Pan;
			float _GlobalMaskTexture3UV;
			int _GlobalMaskTexture3Split;
			float4 _GlobalMaskTexture3SplitTilingOffset_G;
			float4 _GlobalMaskTexture3SplitPan_G;
			float4 _GlobalMaskTexture3SplitTilingOffset_B;
			float4 _GlobalMaskTexture3SplitPan_B;
			float4 _GlobalMaskTexture3SplitTilingOffset_A;
			float4 _GlobalMaskTexture3SplitPan_A;
			#endif
			//endex
			//ifex _GlobalMaskOptionsEnable==0
			float _GlobalMaskOptionsEnable;
			int _GlobalMaskOptionsType;
			
			//ifex _GlobalMaskOptionsType!=0
			float _GlobalMaskSlider_0;
			float _GlobalMaskSlider_1;
			float _GlobalMaskSlider_2;
			float _GlobalMaskSlider_3;
			float _GlobalMaskSlider_4;
			float _GlobalMaskSlider_5;
			float _GlobalMaskSlider_6;
			float _GlobalMaskSlider_7;
			float _GlobalMaskSlider_8;
			float _GlobalMaskSlider_9;
			float _GlobalMaskSlider_10;
			float _GlobalMaskSlider_11;
			float _GlobalMaskSlider_12;
			float _GlobalMaskSlider_13;
			float _GlobalMaskSlider_14;
			float _GlobalMaskSlider_15;
			//endex
			
			//ifex _GlobalMaskOptionsType!=1
			float2 _GlobalMaskMinMaxSlider_0;
			float2 _GlobalMaskMinMaxSlider_1;
			float2 _GlobalMaskMinMaxSlider_2;
			float2 _GlobalMaskMinMaxSlider_3;
			float2 _GlobalMaskMinMaxSlider_4;
			float2 _GlobalMaskMinMaxSlider_5;
			float2 _GlobalMaskMinMaxSlider_6;
			float2 _GlobalMaskMinMaxSlider_7;
			float2 _GlobalMaskMinMaxSlider_8;
			float2 _GlobalMaskMinMaxSlider_9;
			float2 _GlobalMaskMinMaxSlider_10;
			float2 _GlobalMaskMinMaxSlider_11;
			float2 _GlobalMaskMinMaxSlider_12;
			float2 _GlobalMaskMinMaxSlider_13;
			float2 _GlobalMaskMinMaxSlider_14;
			float2 _GlobalMaskMinMaxSlider_15;
			//endex
			
			//ifex _GlobalMaskOptionsType!=2
			int _GlobalMaskToggleOn_0;
			int _GlobalMaskToggleOff_0;
			int _GlobalMaskToggleOn_1;
			int _GlobalMaskToggleOff_1;
			int _GlobalMaskToggleOn_2;
			int _GlobalMaskToggleOff_2;
			int _GlobalMaskToggleOn_3;
			int _GlobalMaskToggleOff_3;
			int _GlobalMaskToggleOn_4;
			int _GlobalMaskToggleOff_4;
			int _GlobalMaskToggleOn_5;
			int _GlobalMaskToggleOff_5;
			int _GlobalMaskToggleOn_6;
			int _GlobalMaskToggleOff_6;
			int _GlobalMaskToggleOn_7;
			int _GlobalMaskToggleOff_7;
			int _GlobalMaskToggleOn_8;
			int _GlobalMaskToggleOff_8;
			int _GlobalMaskToggleOn_9;
			int _GlobalMaskToggleOff_9;
			int _GlobalMaskToggleOn_10;
			int _GlobalMaskToggleOff_10;
			int _GlobalMaskToggleOn_11;
			int _GlobalMaskToggleOff_11;
			int _GlobalMaskToggleOn_12;
			int _GlobalMaskToggleOff_12;
			int _GlobalMaskToggleOn_13;
			int _GlobalMaskToggleOff_13;
			int _GlobalMaskToggleOn_14;
			int _GlobalMaskToggleOff_14;
			int _GlobalMaskToggleOn_15;
			int _GlobalMaskToggleOff_15;
			//endex
			//endex
			//ifex _GlobalMaskModifiersBackfaceEnable==0
			float _GlobalMaskModifiersBackfaceEnable;
			float _GlobalMaskBackface_0;
			float _GlobalMaskBackface_1;
			float _GlobalMaskBackface_2;
			float _GlobalMaskBackface_3;
			float _GlobalMaskBackface_4;
			float _GlobalMaskBackface_5;
			float _GlobalMaskBackface_6;
			float _GlobalMaskBackface_7;
			float _GlobalMaskBackface_8;
			float _GlobalMaskBackface_9;
			float _GlobalMaskBackface_10;
			float _GlobalMaskBackface_11;
			float _GlobalMaskBackface_12;
			float _GlobalMaskBackface_13;
			float _GlobalMaskBackface_14;
			float _GlobalMaskBackface_15;
			//endex
			
			//ifex _GlobalMaskModifiersMirrorEnable==0
			float _GlobalMaskModifiersMirrorEnable;
			float _GlobalMaskMirrorVisibilityMode;
			float _GlobalMaskMirror_0;
			float _GlobalMaskMirror_1;
			float _GlobalMaskMirror_2;
			float _GlobalMaskMirror_3;
			float _GlobalMaskMirror_4;
			float _GlobalMaskMirror_5;
			float _GlobalMaskMirror_6;
			float _GlobalMaskMirror_7;
			float _GlobalMaskMirror_8;
			float _GlobalMaskMirror_9;
			float _GlobalMaskMirror_10;
			float _GlobalMaskMirror_11;
			float _GlobalMaskMirror_12;
			float _GlobalMaskMirror_13;
			float _GlobalMaskMirror_14;
			float _GlobalMaskMirror_15;
			//endex
			
			//ifex _GlobalMaskModifiersCameraEnable==0
			float _GlobalMaskModifiersCameraEnable;
			float _GlobalMaskCamera_0;
			float _GlobalMaskCamera_1;
			float _GlobalMaskCamera_2;
			float _GlobalMaskCamera_3;
			float _GlobalMaskCamera_4;
			float _GlobalMaskCamera_5;
			float _GlobalMaskCamera_6;
			float _GlobalMaskCamera_7;
			float _GlobalMaskCamera_8;
			float _GlobalMaskCamera_9;
			float _GlobalMaskCamera_10;
			float _GlobalMaskCamera_11;
			float _GlobalMaskCamera_12;
			float _GlobalMaskCamera_13;
			float _GlobalMaskCamera_14;
			float _GlobalMaskCamera_15;
			//endex
			
			//ifex _GlobalMaskModifiersDistanceEnable==0
			int _GlobalMaskModifiersDistanceEnable;
			
			//ifex _GlobalMaskDistanceEnable_0==0
			int _GlobalMaskDistanceEnable_0;
			int _GlobalMaskDistanceType_0;
			float _GlobalMaskDistanceMin_0;
			float _GlobalMaskDistanceMax_0;
			float _GlobalMaskDistanceMinAlpha_0;
			float _GlobalMaskDistanceMaxAlpha_0;
			int _GlobalMaskDistanceBlendType_0;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_1==0
			int _GlobalMaskDistanceEnable_1;
			int _GlobalMaskDistanceType_1;
			float _GlobalMaskDistanceMin_1;
			float _GlobalMaskDistanceMax_1;
			float _GlobalMaskDistanceMinAlpha_1;
			float _GlobalMaskDistanceMaxAlpha_1;
			int _GlobalMaskDistanceBlendType_1;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_2==0
			int _GlobalMaskDistanceEnable_2;
			int _GlobalMaskDistanceType_2;
			float _GlobalMaskDistanceMin_2;
			float _GlobalMaskDistanceMax_2;
			float _GlobalMaskDistanceMinAlpha_2;
			float _GlobalMaskDistanceMaxAlpha_2;
			int _GlobalMaskDistanceBlendType_2;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_3==0
			int _GlobalMaskDistanceEnable_3;
			int _GlobalMaskDistanceType_3;
			float _GlobalMaskDistanceMin_3;
			float _GlobalMaskDistanceMax_3;
			float _GlobalMaskDistanceMinAlpha_3;
			float _GlobalMaskDistanceMaxAlpha_3;
			int _GlobalMaskDistanceBlendType_3;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_4==0
			int _GlobalMaskDistanceEnable_4;
			int _GlobalMaskDistanceType_4;
			float _GlobalMaskDistanceMin_4;
			float _GlobalMaskDistanceMax_4;
			float _GlobalMaskDistanceMinAlpha_4;
			float _GlobalMaskDistanceMaxAlpha_4;
			int _GlobalMaskDistanceBlendType_4;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_5==0
			int _GlobalMaskDistanceEnable_5;
			int _GlobalMaskDistanceType_5;
			float _GlobalMaskDistanceMin_5;
			float _GlobalMaskDistanceMax_5;
			float _GlobalMaskDistanceMinAlpha_5;
			float _GlobalMaskDistanceMaxAlpha_5;
			int _GlobalMaskDistanceBlendType_5;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_6==0
			int _GlobalMaskDistanceEnable_6;
			int _GlobalMaskDistanceType_6;
			float _GlobalMaskDistanceMin_6;
			float _GlobalMaskDistanceMax_6;
			float _GlobalMaskDistanceMinAlpha_6;
			float _GlobalMaskDistanceMaxAlpha_6;
			int _GlobalMaskDistanceBlendType_6;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_7==0
			int _GlobalMaskDistanceEnable_7;
			int _GlobalMaskDistanceType_7;
			float _GlobalMaskDistanceMin_7;
			float _GlobalMaskDistanceMax_7;
			float _GlobalMaskDistanceMinAlpha_7;
			float _GlobalMaskDistanceMaxAlpha_7;
			int _GlobalMaskDistanceBlendType_7;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_8==0
			int _GlobalMaskDistanceEnable_8;
			int _GlobalMaskDistanceType_8;
			float _GlobalMaskDistanceMin_8;
			float _GlobalMaskDistanceMax_8;
			float _GlobalMaskDistanceMinAlpha_8;
			float _GlobalMaskDistanceMaxAlpha_8;
			int _GlobalMaskDistanceBlendType_8;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_9==0
			int _GlobalMaskDistanceEnable_9;
			int _GlobalMaskDistanceType_9;
			float _GlobalMaskDistanceMin_9;
			float _GlobalMaskDistanceMax_9;
			float _GlobalMaskDistanceMinAlpha_9;
			float _GlobalMaskDistanceMaxAlpha_9;
			int _GlobalMaskDistanceBlendType_9;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_10==0
			int _GlobalMaskDistanceEnable_10;
			int _GlobalMaskDistanceType_10;
			float _GlobalMaskDistanceMin_10;
			float _GlobalMaskDistanceMax_10;
			float _GlobalMaskDistanceMinAlpha_10;
			float _GlobalMaskDistanceMaxAlpha_10;
			int _GlobalMaskDistanceBlendType_10;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_11==0
			int _GlobalMaskDistanceEnable_11;
			int _GlobalMaskDistanceType_11;
			float _GlobalMaskDistanceMin_11;
			float _GlobalMaskDistanceMax_11;
			float _GlobalMaskDistanceMinAlpha_11;
			float _GlobalMaskDistanceMaxAlpha_11;
			int _GlobalMaskDistanceBlendType_11;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_12==0
			int _GlobalMaskDistanceEnable_12;
			int _GlobalMaskDistanceType_12;
			float _GlobalMaskDistanceMin_12;
			float _GlobalMaskDistanceMax_12;
			float _GlobalMaskDistanceMinAlpha_12;
			float _GlobalMaskDistanceMaxAlpha_12;
			int _GlobalMaskDistanceBlendType_12;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_13==0
			int _GlobalMaskDistanceEnable_13;
			int _GlobalMaskDistanceType_13;
			float _GlobalMaskDistanceMin_13;
			float _GlobalMaskDistanceMax_13;
			float _GlobalMaskDistanceMinAlpha_13;
			float _GlobalMaskDistanceMaxAlpha_13;
			int _GlobalMaskDistanceBlendType_13;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_14==0
			int _GlobalMaskDistanceEnable_14;
			int _GlobalMaskDistanceType_14;
			float _GlobalMaskDistanceMin_14;
			float _GlobalMaskDistanceMax_14;
			float _GlobalMaskDistanceMinAlpha_14;
			float _GlobalMaskDistanceMaxAlpha_14;
			int _GlobalMaskDistanceBlendType_14;
			//endex
			
			//ifex _GlobalMaskDistanceEnable_15==0
			int _GlobalMaskDistanceEnable_15;
			int _GlobalMaskDistanceType_15;
			float _GlobalMaskDistanceMin_15;
			float _GlobalMaskDistanceMax_15;
			float _GlobalMaskDistanceMinAlpha_15;
			float _GlobalMaskDistanceMaxAlpha_15;
			int _GlobalMaskDistanceBlendType_15;
			//endex
			//endex
			
			int _GlobalMaskVertexColorLinearSpace;
			//ifex _GlobalMaskVertexColorRed==0
			int _GlobalMaskVertexColorRed;
			int _GlobalMaskVertexColorRedBlendType;
			//endex
			//ifex _GlobalMaskVertexColorGreen==0
			int _GlobalMaskVertexColorGreen;
			int _GlobalMaskVertexColorGreenBlendType;
			//endex
			//ifex _GlobalMaskVertexColorBlue==0
			int _GlobalMaskVertexColorBlue;
			int _GlobalMaskVertexColorBlueBlendType;
			//endex
			//ifex _GlobalMaskVertexColorAlpha==0
			int _GlobalMaskVertexColorAlpha;
			int _GlobalMaskVertexColorAlphaBlendType;
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#ifdef POI_UDIMDISCARD
			float _UDIMDiscardMode;
			float _UDIMDiscardUV;
			float _UDIMDiscardRow3_0;
			float _UDIMDiscardRow3_1;
			float _UDIMDiscardRow3_2;
			float _UDIMDiscardRow3_3;
			float _UDIMDiscardRow2_0;
			float _UDIMDiscardRow2_1;
			float _UDIMDiscardRow2_2;
			float _UDIMDiscardRow2_3;
			float _UDIMDiscardRow1_0;
			float _UDIMDiscardRow1_1;
			float _UDIMDiscardRow1_2;
			float _UDIMDiscardRow1_3;
			float _UDIMDiscardRow0_0;
			float _UDIMDiscardRow0_1;
			float _UDIMDiscardRow0_2;
			float _UDIMDiscardRow0_3;
			#endif
			//endex
			
			//ifex _EnableDistortion==0
			#ifdef USER_LUT
			#if defined(PROP_DISTORTIONFLOWTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionFlowTexture;
			float4 _DistortionFlowTexture_ST;
			float2 _DistortionFlowTexturePan;
			float _DistortionFlowTextureUV;
			#endif
			
			#if defined(PROP_DISTORTIONFLOWTEXTURE1) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionFlowTexture1;
			float4 _DistortionFlowTexture1_ST;
			float2 _DistortionFlowTexture1Pan;
			float _DistortionFlowTexture1UV;
			#endif
			
			#if defined(PROP_DISTORTIONMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DistortionMask;
			float4 _DistortionMask_ST;
			float2 _DistortionMaskPan;
			float _DistortionMaskUV;
			float _DistortionMaskChannel;
			#endif
			
			float _DistortionUvToDistort;
			float _DistortionStrength;
			float _DistortionStrength1;
			
			#ifdef POI_AUDIOLINK
			half _EnableDistortionAudioLink;
			half2 _DistortionStrengthAudioLink;
			half _DistortionStrengthAudioLinkBand;
			half2 _DistortionStrength1AudioLink;
			half _DistortionStrength1AudioLinkBand;
			#endif
			#endif
			//endex
			float _StereoEnabled;
			float _PolarUV;
			float2 _PolarCenter;
			float _PolarRadialScale;
			float _PolarLengthScale;
			float _PolarSpiralPower;
			float _PanoUseBothEyes;
			
			float _UVModWorldPos0;
			float _UVModWorldPos1;
			float _UVModLocalPos0;
			float _UVModLocalPos1;
			
			//ifex _PoiParallax==0
			#ifdef POI_PARALLAX
			
			sampler2D _HeightMap;
			float4 _HeightMap_ST;
			float2 _HeightMapPan;
			float _HeightMapUV;
			
			#if defined(PROP_HEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _Heightmask;
			float4 _Heightmask_ST;
			float2 _HeightmaskPan;
			float _HeightmaskUV;
			float _HeightmaskChannel;
			float _HeightmaskInvert;
			SamplerState _linear_repeat;
			#endif
			
			float _ParallaxUV;
			float _HeightStrength;
			float _HeightOffset;
			float _HeightStepsMin;
			float _HeightStepsMax;
			
			float _CurvatureU;
			float _CurvatureV;
			float _CurvFix;
			#endif
			//endex
			
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			float _AudioLinkDelay;
			float _AudioLinkAnimToggle;
			
			float _AudioLinkSmoothingBass;
			float _AudioLinkSmoothingLowMid;
			float _AudioLinkSmoothingHighMid;
			float _AudioLinkSmoothingTreble;
			
			float _DebugWaveform;
			float _DebugDFT;
			float _DebugBass;
			float _DebugLowMids;
			float _DebugHighMids;
			float _DebugTreble;
			float _DebugCCColors;
			float _DebugCCStrip;
			float _DebugCCLights;
			float _DebugAutocorrelator;
			float _DebugChronotensity;
			float _AudioLinkCCStripY;
			
			float _AudioLinkBandOverridesEnabled;
			float4 _AudioLinkBandOverrideSliders;
			#endif
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#ifdef POI_BLACKLIGHTMASKING
			float _BlackLightMasking0Key;
			float2 _BlackLightMasking0Range;
			float _BlackLightMasking0GlobalMaskIndex;
			float _BlackLightMasking0GlobalMaskBlendType;
			
			float _BlackLightMasking1Key;
			float2 _BlackLightMasking1Range;
			float _BlackLightMasking1GlobalMaskIndex;
			float _BlackLightMasking1GlobalMaskBlendType;
			
			float _BlackLightMasking2Key;
			float2 _BlackLightMasking2Range;
			float _BlackLightMasking2GlobalMaskIndex;
			float _BlackLightMasking2GlobalMaskBlendType;
			
			float _BlackLightMasking3Key;
			float2 _BlackLightMasking3Range;
			float _BlackLightMasking3GlobalMaskIndex;
			float _BlackLightMasking3GlobalMaskBlendType;
			#endif
			//endex
			
			//ifex _VertexManipulationsEnabled==0
			#ifdef AUTO_EXPOSURE
			float4 _VertexManipulationLocalTranslation;
			float4 _VertexManipulationLocalRotation;
			float3 _VertexManipulationLocalRotationSpeed;
			float4 _VertexManipulationLocalScale;
			float4 _VertexManipulationWorldTranslation;
			float _VertexManipulationHeight;
			sampler2D _VertexManipulationHeightMask;
			float4 _VertexManipulationHeightMask_ST;
			float2 _VertexManipulationHeightMaskPan;
			float _VertexManipulationHeightMaskUV;
			float _VertexManipulationHeightMaskChannel;
			float _VertexManipulationHeightBias;
			float _VertexRoundingEnabled;
			int _VertexRoundingSpace;
			float _VertexRoundingDivision;
			
			//AL
			float _VertexAudioLinkEnabled;
			float3 _VertexLocalTranslationALMin;
			float3 _VertexLocalTranslationALMax;
			float _VertexLocalTranslationALBand;
			
			float3 _VertexLocalRotationAL;
			float _VertexLocalRotationALBand;
			
			float3 _VertexLocalRotationCTALSpeed;
			float _VertexLocalRotationCTALBandX;
			float _VertexLocalRotationCTALBandY;
			float _VertexLocalRotationCTALBandZ;
			float _VertexLocalRotationCTALTypeX;
			float _VertexLocalRotationCTALTypeY;
			float _VertexLocalRotationCTALTypeZ;
			
			float4 _VertexLocalScaleALMin;
			float4 _VertexLocalScaleALMax;
			float _VertexLocalScaleALBand;
			
			float3 _VertexWorldTranslationALMin;
			float3 _VertexWorldTranslationALMax;
			float _VertexWorldTranslationALBand;
			
			float2 _VertexManipulationHeightAL;
			float _VertexManipulationHeightBand;
			
			float2 _VertexRoundingRangeAL;
			float _VertexRoundingRangeBand;
			
			float _VertexBarrelMode;
			float _VertexBarrelWidth;
			float _VertexBarrelAlpha;
			float _VertexBarrelHeight;
			
			float _VertexSphereMode;
			float _VertexSphereRadius;
			float _VertexSphereHeight;
			float _VertexSphereAlpha;
			float4 _VertexSphereCenter;
			
			float _VertexTornadoMode;
			float _VertexTornadoRadius;
			float _VertexTornadoSpeed;
			float _VertexTornadoIntensity;
			float _VertexTornadoBaseHeight;
			float _VertexTornadoTopHeight;
			
			float _VertexSpectrumMotion;
			float3 _VertexSpectrumOffsetMin;
			float3 _VertexSpectrumOffsetMax;
			float _VertexSpectrumUV;
			float _VertexSpectrumUVDirection;
			#endif
			//endex
			
			//ifex _VertexGlitchingEnabled==0
			#ifdef POI_VERTEX_GLITCHING
			//Vertex Glitching
			#if defined(POI_VERTEX_GLITCHING_TEXTURE)
			float _VertexGlitchingUseTexture;
			sampler2D _VertexGlitchMap;
			float4 _VertexGlitchMap_ST;
			#endif
			float _VertexGlitchThreshold;
			float _VertexGlitchFrequency;
			float _VertexGlitchStrength;
			float _VertexGlitchDensity;
			
			float _VertexGlitchMirrorEnable;
			float _VertexGlitchMirror;
			
			float _VertexGlitchMapPanSpeed;
			float _VertexGlitchingAudioLinkEnabled;
			float _VertexGlitchingAudioLinkBand;
			float _VertexGlitchingAudiolinkOverride;
			#endif
			//endex
			
			//ifex _MainVertexColoringEnabled==0
			float _MainVertexColoringEnabled;
			float _MainVertexColoringLinearSpace;
			float _MainVertexColoring;
			float _MainUseVertexColorAlpha;
			//endex
			
			//ifex _BackFaceEnabled!=1
			#ifdef POI_BACKFACE
			float _BackFaceEnabled;
			float _BackFaceDetailIntensity;
			float _BackFaceEmissionStrength;
			float2 _BackFacePanning;
			float4 _BackFaceColor;
			float _BackFaceColorThemeIndex;
			float _BackFaceReplaceAlpha;
			
			#if defined(PROP_BACKFACETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BackFaceTexture;
			#endif
			float4 _BackFaceTexture_ST;
			float2 _BackFaceTexturePan;
			float _BackFaceTextureUV;
			
			#if defined(PROP_BACKFACEMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BackFaceMask;
			#endif
			float4 _BackFaceMask_ST;
			float2 _BackFaceMaskPan;
			float _BackFaceMaskUV;
			float _BackFaceMaskChannel;
			
			float _BackFaceHueShiftEnabled;
			float _BackFaceHueShift;
			float _BackFaceHueShiftSpeed;
			float _BackFaceEmissionLimiter;
			#endif
			
			//TODO detail strength stuff
			//endex
			
			//ifex _EnableDissolve==0
			#ifdef DISTORT
			float _DissolveType;
			float _DissolveEdgeWidth;
			float4 _DissolveEdgeColor;
			sampler2D _DissolveEdgeGradient;
			float4 _DissolveEdgeGradient_ST;
			float2 _DissolveEdgeGradientPan;
			float _DissolveEdgeGradientUV;
			float _DissolveEdgeEmission;
			float4 _DissolveTextureColor;
			float _DissolveEdgeColorThemeIndex;
			float _DissolveTextureColorThemeIndex;
			
			#if defined(PROP_DISSOLVETOTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveToTexture;
			#endif
			float4 _DissolveToTexture_ST;
			float2 _DissolveToTexturePan;
			float _DissolveToTextureUV;
			
			#if defined(PROP_DISSOLVENOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveNoiseTexture;
			#endif
			float4 _DissolveNoiseTexture_ST;
			float2 _DissolveNoiseTexturePan;
			float _DissolveNoiseTextureUV;
			
			#if defined(PROP_DISSOLVEDETAILNOISE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveDetailNoise;
			#endif
			float4 _DissolveDetailNoise_ST;
			float2 _DissolveDetailNoisePan;
			float _DissolveDetailNoiseUV;
			
			#if defined(PROP_DISSOLVEMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DissolveMask;
			#endif
			float4 _DissolveMask_ST;
			float2 _DissolveMaskPan;
			float _DissolveMaskUV;
			
			float _DissolveMaskGlobalMask;
			float _DissolveMaskGlobalMaskBlendType;
			float _DissolveApplyGlobalMaskIndex;
			float _DissolveApplyGlobalMaskBlendType;
			float _DissolveInverseApplyGlobalMaskBlendType;
			float _DissolveInverseApplyGlobalMaskIndex;
			float _DissolveMaskInvert;
			float _DissolveAlpha;
			float _ContinuousDissolve;
			float _DissolveDetailStrength;
			float _DissolveDetailEdgeSmoothing;
			float _DissolveEdgeHardness;
			float _DissolveInvertNoise;
			float _DissolveInvertDetailNoise;
			float _DissolveToEmissionStrength;
			
			// Point to Point
			float _DissolveP2PWorldLocal;
			float _DissolveP2PEdgeLength;
			float _DissolveP2PClamp;
			float4 _DissolveStartPoint;
			float4 _DissolveEndPoint;
			
			// Spherical
			float3 _SphericalDissolveCenter;
			float _SphericalDissolveRadius;
			float _SphericalDissolveInvert;
			float _SphericalDissolveClamp;
			
			// CenterOut
			float _CenterOutDissolveMode;
			float3 _CenterOutDissolveDirection;
			float _CenterOutDissolveInvert;
			float _CenterOutDissolveNormals;
			float _CenterOutDissolvePower;
			
			// World Dissolve
			float _DissolveWorldShape;
			float4 _DissolveShapePosition;
			float4 _DissolveShapeRotation;
			float _DissolveShapeScale;
			float _DissolveInvertShape;
			float _DissolveShapeEdgeLength;
			
			// UV Tile Dissolve
			float _UVTileDissolveEnabled;
			float _UVTileDissolveDiscardAtMax;
			float _UVTileDissolveUV;
			
			float _UVTileDissolveAlpha_Row3_0;
			float _UVTileDissolveAlpha_Row3_1;
			float _UVTileDissolveAlpha_Row3_2;
			float _UVTileDissolveAlpha_Row3_3;
			float _UVTileDissolveAlpha_Row2_0;
			float _UVTileDissolveAlpha_Row2_1;
			float _UVTileDissolveAlpha_Row2_2;
			float _UVTileDissolveAlpha_Row2_3;
			float _UVTileDissolveAlpha_Row1_0;
			float _UVTileDissolveAlpha_Row1_1;
			float _UVTileDissolveAlpha_Row1_2;
			float _UVTileDissolveAlpha_Row1_3;
			float _UVTileDissolveAlpha_Row0_0;
			float _UVTileDissolveAlpha_Row0_1;
			float _UVTileDissolveAlpha_Row0_2;
			float _UVTileDissolveAlpha_Row0_3;
			
			float _DissolveAlpha0;
			float _DissolveAlpha1;
			float _DissolveAlpha2;
			float _DissolveAlpha3;
			float _DissolveAlpha4;
			float _DissolveAlpha5;
			float _DissolveAlpha6;
			float _DissolveAlpha7;
			float _DissolveAlpha8;
			float _DissolveAlpha9;
			// Masking
			float _DissolveEmissionSide;
			float _DissolveEmission1Side;
			float _DissolveUseVertexColors;
			
			float4 edgeColor;
			float edgeAlpha;
			float dissolveAlpha;
			float4 dissolveToTexture;
			
			float _DissolveHueShiftEnabled;
			float _DissolveHueShiftSpeed;
			float _DissolveHueShift;
			float _DissolveEdgeHueShiftEnabled;
			float _DissolveEdgeHueShiftSpeed;
			float _DissolveEdgeHueShift;
			
			// Audio Link
			#ifdef POI_AUDIOLINK
			fixed _EnableDissolveAudioLink;
			half _AudioLinkDissolveAlphaBand;
			float2 _AudioLinkDissolveAlpha;
			half _AudioLinkDissolveDetailBand;
			float2 _AudioLinkDissolveDetail;
			#endif
			#endif
			//endex
			
			//ifex _EnableALDecal==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_DECAL
			float _ALDecalUV;
			float4 _ALUVScale;
			float2 _ALUVPosition;
			float _ALUVRotation;
			float _ALUVRotationSpeed;
			float4 _ALDecaldCircleDimensions;
			
			float _ALDecalUVMode;
			
			float _ALDecalVolumeStep;
			float _ALDecalVolumeClipMin;
			float _ALDecalVolumeClipMax;
			
			float _ALDecalBandStep;
			float _ALDecalBandClipMin;
			float _ALDecalBandClipMax;
			
			float _ALDecalShapeClip;
			float _ALDecalShapeClipVolumeWidth;
			float _ALDecalShapeClipBandWidth;
			
			#if defined(PROP_ALDECALCOLORMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _ALDecalColorMask;
			float4 _ALDecalColorMask_ST;
			float2 _ALDecalColorMaskPan;
			float _ALDecalColorMaskUV;
			#endif
			
			float _ALDecalVolume;
			float _ALDecalBaseBoost;
			float _ALDecalTrebleBoost;
			float _ALDecalLineWidth;
			float _ALDecalVolumeColorSource;
			float3 _ALDecalVolumeColorLow;
			float _ALDecalVolumeColorLowThemeIndex;
			float3 _ALDecalVolumeColorMid;
			float _ALDecalVolumeColorMidThemeIndex;
			float3 _ALDecalVolumeColorHigh;
			float _ALDecalVolumeColorHighThemeIndex;
			float _ALDecalLowEmission;
			float _ALDecalMidEmission;
			float _ALDecalHighEmission;
			float _ALDecalBlendType;
			float _ALDecalBlendAlpha;
			float _ALDecalControlsAlpha;
			float _ALDecalGlobalMask;
			float _ALDecalGlobalMaskBlendType;
			#endif
			#endif
			//endex
			
			//ifex _EnableFlipbook==0
			#ifdef _SUNDISK_HIGH_QUALITY
			
			UNITY_DECLARE_TEX2DARRAY(_FlipbookTexArray);
			float4 _FlipbookTexArray_ST;
			
			float4 _FlipbookColor;
			float _FlipbookColorThemeIndex;
			float _FlipbookFPS;
			// float _FlipbookTotalFrames;
			float4 _FlipbookScaleOffset;
			float4 _FlipbookSideOffset;
			float _FlipbookTiled;
			float _FlipbookManualFrameControl;
			float _FlipbookCurrentFrame;
			float _FlipbookStartAndEnd;
			float _FlipbookStartFrame;
			float _FlipbookEndFrame;
			float _FlipbookEmissionStrength;
			float _FlipbookRotation;
			float _EnableFlipbook;
			float _FlipbookTexArrayUV;
			float _FlipbookAlphaControlsFinalAlpha;
			float _FlipbookRotationSpeed;
			float _FlipbookIntensityControlsAlpha;
			float _FlipbookColorReplaces;
			float2 _FlipbookTexArrayPan;
			float _FlipbookFrameOffset;
			// blending
			float _FlipbookReplace;
			float _FlipbookMultiply;
			float _FlipbookAdd;
			float _FlipbookBlendType;
			
			#if defined(PROP_FLIPBOOKMASSK) || !defined(OPTIMIZED_ENABLED)
			Texture2D _FlipbookMask;
			#endif
			float4 _FlipbookMask_ST;
			float2 _FlipbookMaskPan;
			float _FlipbookMaskUV;
			float _FlipbookMaskChannel;
			float _FlipbookMaskGlobalMask;
			float _FlipbookMaskGlobalMaskBlendType;
			
			// anim
			float _FlipbookMovementType;
			float4 _FlipbookStartEndOffset;
			float _FlipbookMovementSpeed;
			
			// Crossfade
			float _FlipbookCrossfadeEnabled;
			float2 _FlipbookCrossfadeRange;
			
			// Hueshift
			float _FlipbookHueShiftEnabled;
			float _FlipbookHueShiftSpeed;
			float _FlipbookHueShift;
			
			#ifdef POI_AUDIOLINK
			float _FlipbookChronotensityEnabled;
			float _FlipbookChronotensityBand;
			float _FlipbookChronotensitySpeed;
			float _FlipbookChronoType;
			half _AudioLinkFlipbookScaleBand;
			half4 _AudioLinkFlipbookScale;
			half _AudioLinkFlipbookAlphaBand;
			half2 _AudioLinkFlipbookAlpha;
			half _AudioLinkFlipbookEmissionBand;
			half2 _AudioLinkFlipbookEmission;
			half _AudioLinkFlipbookFrameBand;
			half2 _AudioLinkFlipbookFrame;
			#endif
			#endif
			//endex
			
			//ifex _EnableMirrorOptions==0
			#ifdef POI_MIRROR
			float _VisibilityMode;
			float _Mirror;
			#if defined(PROP_MIRRORTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _MirrorTexture;
			#endif
			float4 _MirrorColor;
			float _MirrorColorThemeIndex;
			float _MirrorTextureBlendType;
			float4 _MirrorTexture_ST;
			float2 _MirrorTexturePan;
			float _MirrorTextureUV;
			float _MirrorTextureEnabled;
			float _MirrorTextureForceEnabled;
			float _VisibilityVRCRegular;
			float _VisibilityVRCMirrorVR;
			float _VisibilityVRCMirrorDesktop;
			float _VisibilityVRCCameraVR;
			float _VisibilityVRCCameraDesktop;
			float _VisibilityVRCCameraScreenshot;
			#endif
			//endex
			
			//ifex _EnableTouchGlow==0
			#ifdef GRAIN
			#if defined(PROP_DEPTHMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DepthMask;
			#endif
			float4 _DepthMask_ST;
			float2 _DepthMaskPan;
			float _DepthMaskUV;
			float _DepthMaskChannel;
			float _DepthMaskGlobalMask;
			float _DepthMaskGlobalMaskBlendType;
			
			// Color
			float _DepthColorToggle;
			float _DepthColorBlendMode;
			#if defined(PROP_DEPTHTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _DepthTexture;
			#endif
			float4 _DepthTexture_ST;
			float2 _DepthTexturePan;
			float _DepthTextureUV;
			
			float3 _DepthColor;
			float _DepthColorThemeIndex;
			float _DepthColorMinDepth;
			float _DepthColorMaxDepth;
			float _DepthColorMinValue;
			float _DepthColorMaxValue;
			float _DepthEmissionStrength;
			
			// Emission
			
			// Alpha
			float _DepthAlphaToggle;
			float _DepthAlphaMinValue;
			float _DepthAlphaMaxValue;
			float _DepthAlphaMinDepth;
			float _DepthAlphaMaxDepth;
			#endif
			//endex
			
			//ifex _NormalCorrect==0
			#ifdef POI_NORMALCORRECT
			float _NormalCorrectAmount;
			float3 _NormalCorrectOrigin;
			#endif
			//endex
			
			//ifex _VideoEffectsEnable==0
			#ifdef POI_VIDEO_EFFECTS
			float _VideoEffectsEnable;
			#if defined(PROP_VIDEOPIXELTEXTURE) || !defined(OPTIMIZER_ENABLED)
			sampler2D _VideoPixelTexture;
			float4 _VideoPixelTexture_ST;
			float _VideoPixelTextureUV;
			#endif
			#if defined(PROP_VIDEOMASKTEXTURE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VideoMaskTexture;
			float4 _VideoMaskTexture_ST;
			float2 _VideoMaskTexturePan;
			float _VideoMaskTextureUV;
			float _VideoMaskTextureChannel;
			#endif
			
			float _VideoType;
			float2 _VideoResolution;
			sampler2D _VideoGameboyRamp;
			float _VideoBacklight;
			float _VideoCRTRefreshRate;
			float _VideoCRTPixelEnergizedTime;
			float _VideoRepeatVideoTexture;
			float _VideoPixelateToResolution;
			float2 _VideoMaskPanning;
			
			float _VideoSaturation;
			float _VideoContrast;
			float _VideoEmissionEnabled;
			#endif
			//endex
			
			//ifex _BacklightEnabled!=1
			#ifdef POI_BACKLIGHT
			float4 _BacklightColor;
			#if defined(PROP_BACKLIGHTCOLORTEX) || !defined(OPTIMIZER_ENABLED)
			Texture2D _BacklightColorTex;
			float4 _BacklightColorTex_ST;
			float2 _BacklightColorTexPan;
			float _BacklightColorTexUV;
			#endif
			float _BacklightMainStrength;
			float _BacklightNormalStrength;
			float _BacklightBorder;
			float _BacklightBlur;
			float _BacklightDirectivity;
			float _BacklightViewStrength;
			int _BacklightReceiveShadow;
			int _BacklightBackfaceMask;
			#endif
			//endex
			
			//ifex _BSSEnabled!=1
			#ifdef POIBS_ENABLE
			float _CustomColors;
			//ifex _BSSBloomfog!=1
			#ifdef POIBS_BLOOMFOG
			float _FogStartOffset;
			float _FogScale;
			float _FogHeightOffset;
			float _FogHeightScale;
			
			uniform float2 _CustomFogTextureToScreenRatio;
			uniform float _StereoCameraEyeOffset;
			
			uniform float _CustomFogOffset;
			uniform float _CustomFogAttenuation;
			uniform float _CustomFogHeightFogStartY;
			uniform float _CustomFogHeightFogHeight;
			uniform sampler2D _BloomPrePassTexture;
			#endif
			//endex
			#endif
			//endex
			
			//ifex _VoronoiEnabled!=1
			#ifdef POI_VORONOI
			#if defined(PROP_VORONOIMASK) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VoronoiMask;
			float4 _VoronoiMask_ST;
			float2 _VoronoiMaskPan;
			float _VoronoiMaskUV;
			int _VoronoiMaskChannel;
			#endif
			#if defined(PROP_VORONOINOISE) || !defined(OPTIMIZER_ENABLED)
			Texture2D _VoronoiNoise;
			float4 _VoronoiNoise_ST;
			float2 _VoronoiNoisePan;
			float _VoronoiNoiseUV;
			int _VoronoiNoiseChannel;
			#endif
			int _VoronoiSpace;
			int _VoronoiBlend;
			int _VoronoiType;
			float4 _VoronoiOuterColor;
			float _VoronoiOuterEmissionStrength;
			float4 _VoronoiInnerColor;
			float _VoronoiInnerEmissionStrength;
			float _VoronoiPower;
			float2 _VoronoiGradient;
			float _VoronoiScale;
			float3 _VoronoiSpeed;
			float _VoronoiEnableRandomCellColor;
			float2 _VoronoiRandomMinMaxSaturation;
			float2 _VoronoiRandomMinMaxBrightness;
			float _VoronoiNoiseIntensity;
			int _VoronoiAffectsMaterialAlpha;
			float _VoronoiGlobalMask;
			float _VoronoiGlobalMaskBlendType;
			
			// AudioLink
			int _AudioLinkVoronoiInnerEmissionBand;
			float2 _AudioLinkVoronoiInnerEmission;
			int _AudioLinkVoronoiOuterEmissionBand;
			float2 _AudioLinkVoronoiOuterEmission;
			
			int _AudioLinkVoronoiGradientMinAddBand;
			float _AudioLinkVoronoiGradientMinAdd;
			int _AudioLinkVoronoiGradientMaxAddBand;
			float _AudioLinkVoronoiGradientMaxAdd;
			
			int _AudioLinkVoronoiChronoSpeedXType;
			int _AudioLinkVoronoiChronoSpeedXBand;
			float _AudioLinkVoronoiChronoSpeedXSpeed;
			int _AudioLinkVoronoiChronoSpeedYType;
			int _AudioLinkVoronoiChronoSpeedYBand;
			float _AudioLinkVoronoiChronoSpeedYSpeed;
			int _AudioLinkVoronoiChronoSpeedZType;
			int _AudioLinkVoronoiChronoSpeedZBand;
			float _AudioLinkVoronoiChronoSpeedZSpeed;
			#endif
			//endex
			
			struct appdata
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 tangent : TANGENT;
				float4 color : COLOR;
				float2 uv0 : TEXCOORD0;
				float2 uv1 : TEXCOORD1;
				float2 uv2 : TEXCOORD2;
				float2 uv3 : TEXCOORD3;
				uint vertexId : SV_VertexID;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};
			
			struct VertexOut
			{
				float4 pos : SV_POSITION;
				float4 uv[2] : TEXCOORD0;
				float3 normal : TEXCOORD2;
				float4 tangent : TEXCOORD3;
				float4 worldPos : TEXCOORD4;
				float4 localPos : TEXCOORD5;
				float4 vertexColor : TEXCOORD6;
				float4 lightmapUV : TEXCOORD7;
				float2 fogCoord: TEXCOORD10;
				UNITY_SHADOW_COORDS(11)
				
				UNITY_VERTEX_INPUT_INSTANCE_ID
				UNITY_VERTEX_OUTPUT_STEREO
			};
			
			struct PoiMesh
			{
				
				// 0 Vertex normal
				// 1 Fragment normal
				float3 normals[2];
				float3 objNormal;
				float3 tangentSpaceNormal;
				float3 binormal[2];
				float3 tangent[2];
				float3 worldPos;
				float3 localPos;
				float3 objectPosition;
				float isFrontFace;
				float4 vertexColor;
				float4 lightmapUV;
				// 0-3 UV0-UV3
				// 4 Panosphere UV
				// 5 world pos xz
				// 6 Polar UV
				// 7 Distorted UV
				float2 uv[9];
				float2 parallaxUV;
				float2 dx;
				float2 dy;
			};
			
			struct PoiCam
			{
				float3 viewDir;
				float3 forwardDir;
				float3 worldPos;
				float distanceToVert;
				float4 clipPos;
				float4 screenSpacePosition;
				float3 reflectionDir;
				float3 vertexReflectionDir;
				float3 tangentViewDir;
				float4 posScreenSpace;
				float2 posScreenPixels;
				float2 screenUV;
				float vDotN;
				float4 worldDirection;
				
			};
			
			struct PoiMods
			{
				float4 Mask;
				float audioLink[5];
				float audioLinkAvailable;
				float audioLinkVersion;
				float4 audioLinkTexture;
				float2 detailMask;
				float2 backFaceDetailIntensity;
				float globalEmission;
				float4 globalColorTheme[12];
				float globalMask[16];
				float ALTime[8];
			};
			
			struct PoiLight
			{
				
				float3 direction;
				float attenuation;
				float attenuationStrength;
				float3 directColor;
				float3 indirectColor;
				float occlusion;
				float shadowMask;
				float detailShadow;
				float3 halfDir;
				float lightMap;
				float lightMapNoAttenuation;
				float3 rampedLightMap;
				float vertexNDotL;
				float nDotL;
				float nDotV;
				float vertexNDotV;
				float nDotH;
				float vertexNDotH;
				float lDotv;
				float lDotH;
				float nDotLSaturated;
				float nDotLNormalized;
				#ifdef POI_PASS_ADD
				float additiveShadow;
				#endif
				float3 finalLighting;
				float3 finalLightAdd;
				float3 LTCGISpecular;
				float3 LTCGIDiffuse;
				float directLuminance;
				float indirectLuminance;
				float finalLuminance;
				
				#if defined(VERTEXLIGHT_ON)
				// Non Important Lights
				float4 vDotNL;
				float4 vertexVDotNL;
				float3 vColor[4];
				float4 vCorrectedDotNL;
				float4 vAttenuation;
				float4 vSaturatedDotNL;
				float3 vPosition[4];
				float3 vDirection[4];
				float3 vFinalLighting;
				float3 vHalfDir[4];
				half4 vDotNH;
				half4 vertexVDotNH;
				half4 vDotLH;
				#endif
				
			};
			
			struct PoiVertexLights
			{
				
				float3 direction;
				float3 color;
				float attenuation;
			};
			
			struct PoiFragData
			{
				float smoothness;
				float smoothness2;
				float metallic;
				float specularMask;
				float reflectionMask;
				
				float3 baseColor;
				float3 finalColor;
				float alpha;
				float3 emission;
				float toggleVertexLights;
			};
			
			float4 poiTransformClipSpacetoScreenSpaceFrag(float4 clipPos)
			{
				float4 positionSS = float4(clipPos.xyz * clipPos.w, clipPos.w);
				positionSS.xy = positionSS.xy / _ScreenParams.xy;
				return positionSS;
			}
			
			// glsl_mod behaves better on negative numbers, and
			// in some situations actually outperforms HLSL's fmod()
			#ifndef glsl_mod
			#define glsl_mod(x, y) (((x) - (y) * floor((x) / (y))))
			#endif
			
			uniform float random_uniform_float_only_used_to_stop_compiler_warnings = 0.0f;
			
			float2 poiUV(float2 uv, float4 tex_st)
			{
				return uv * tex_st.xy + tex_st.zw;
			}
			
			float2 vertexUV(in VertexOut o, int index)
			{
				switch(index)
				{
					case 0:
					return o.uv[0].xy;
					case 1:
					return o.uv[0].zw;
					case 2:
					return o.uv[1].xy;
					case 3:
					return o.uv[1].zw;
					default:
					return o.uv[0].xy;
				}
			}
			
			float2 vertexUV(in appdata v, int index)
			{
				switch(index)
				{
					case 0:
					return v.uv0.xy;
					case 1:
					return v.uv1.xy;
					case 2:
					return v.uv2.xy;
					case 3:
					return v.uv3.xy;
					default:
					return v.uv0.xy;
				}
			}
			
			//Lighting Helpers
			float calculateluminance(float3 color)
			{
				return color.r * 0.299 + color.g * 0.587 + color.b * 0.114;
			}
			
			// Set by VRChat (as of open beta 1245)
			// _VRChatCameraMode: 0 => Normal, 1 => VR HandCam, 2 => Desktop Handcam, 3 => Screenshot/Photo
			// _VRChatMirrorMode: 0 => Normal, 1 => Mirror (VR), 2 => Mirror (Deskie)
			float _VRChatCameraMode;
			float _VRChatMirrorMode;
			
			float VRCCameraMode()
			{
				return _VRChatCameraMode;
			}
			
			float VRCMirrorMode()
			{
				return _VRChatMirrorMode;
			}
			
			bool IsInMirror()
			{
				return unity_CameraProjection[2][0] != 0.f || unity_CameraProjection[2][1] != 0.f;
			}
			
			bool IsOrthographicCamera()
			{
				return unity_OrthoParams.w == 1 || UNITY_MATRIX_P[3][3] == 1;
			}
			
			float shEvaluateDiffuseL1Geomerics_local(float L0, float3 L1, float3 n)
			{
				// average energy
				float R0 = max(0, L0);
				
				// avg direction of incoming light
				float3 R1 = 0.5f * L1;
				
				// directional brightness
				float lenR1 = length(R1);
				
				// linear angle between normal and direction 0-1
				//float q = 0.5f * (1.0f + dot(R1 / lenR1, n));
				//float q = dot(R1 / lenR1, n) * 0.5 + 0.5;
				float q = dot(normalize(R1), n) * 0.5 + 0.5;
				q = saturate(q); // Thanks to ScruffyRuffles for the bug identity.
				
				// power for q
				// lerps from 1 (linear) to 3 (cubic) based on directionality
				float p = 1.0f + 2.0f * lenR1 / R0;
				
				// dynamic range constant
				// should vary between 4 (highly directional) and 0 (ambient)
				float a = (1.0f - lenR1 / R0) / (1.0f + lenR1 / R0);
				
				return R0 * (a + (1.0f - a) * (p + 1.0f) * pow(q, p));
			}
			
			half3 BetterSH9(half4 normal)
			{
				float3 indirect;
				float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) + float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0;
				indirect.r = shEvaluateDiffuseL1Geomerics_local(L0.r, unity_SHAr.xyz, normal.xyz);
				indirect.g = shEvaluateDiffuseL1Geomerics_local(L0.g, unity_SHAg.xyz, normal.xyz);
				indirect.b = shEvaluateDiffuseL1Geomerics_local(L0.b, unity_SHAb.xyz, normal.xyz);
				indirect = max(0, indirect);
				indirect += SHEvalLinearL2(normal);
				return indirect;
			}
			
			// Silent's code ends here
			
			float3 getCameraForward()
			{
				#if UNITY_SINGLE_PASS_STEREO
				float3 p1 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 1, 1));
				float3 p2 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 0, 1));
				#else
				float3 p1 = mul(unity_CameraToWorld, float4(0, 0, 1, 1)).xyz;
				float3 p2 = mul(unity_CameraToWorld, float4(0, 0, 0, 1)).xyz;
				#endif
				return normalize(p2 - p1);
			}
			
			half3 GetSHLength()
			{
				half3 x, x1;
				x.r = length(unity_SHAr);
				x.g = length(unity_SHAg);
				x.b = length(unity_SHAb);
				x1.r = length(unity_SHBr);
				x1.g = length(unity_SHBg);
				x1.b = length(unity_SHBb);
				return x + x1;
			}
			
			float3 BoxProjection(float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax)
			{
				#if UNITY_SPECCUBE_BOX_PROJECTION
				//UNITY_BRANCH
				if (cubemapPosition.w > 0)
				{
					float3 factors = ((direction > 0 ? boxMax : boxMin) - position) / direction;
					float scalar = min(min(factors.x, factors.y), factors.z);
					direction = direction * scalar + (position - cubemapPosition.xyz);
				}
				#endif
				return direction;
			}
			
			float poiMax(float2 i)
			{
				return max(i.x, i.y);
			}
			
			float poiMax(float3 i)
			{
				return max(max(i.x, i.y), i.z);
			}
			
			float poiMax(float4 i)
			{
				return max(max(max(i.x, i.y), i.z), i.w);
			}
			
			float3 calculateNormal(in float3 baseNormal, in PoiMesh poiMesh, in Texture2D normalTexture, in float4 normal_ST, in float2 normalPan, in float normalUV, in float normalIntensity)
			{
				float3 normal = UnpackScaleNormal(POI2D_SAMPLER_PAN(normalTexture, _MainTex, poiUV(poiMesh.uv[normalUV], normal_ST), normalPan), normalIntensity);
				return normalize(
				normal.x * poiMesh.tangent[0] +
				normal.y * poiMesh.binormal[0] +
				normal.z * baseNormal
				);
			}
			
			float remap(float x, float minOld, float maxOld, float minNew = 0, float maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float2 remap(float2 x, float2 minOld, float2 maxOld, float2 minNew = 0, float2 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float3 remap(float3 x, float3 minOld, float3 maxOld, float3 minNew = 0, float3 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float4 remap(float4 x, float4 minOld, float4 maxOld, float4 minNew = 0, float4 maxNew = 1)
			{
				return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
			}
			
			float remapClamped(float minOld, float maxOld, float x, float minNew = 0, float maxNew = 1)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float2 remapClamped(float2 minOld, float2 maxOld, float2 x, float2 minNew, float2 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float3 remapClamped(float3 minOld, float3 maxOld, float3 x, float3 minNew, float3 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			
			float4 remapClamped(float4 minOld, float4 maxOld, float4 x, float4 minNew, float4 maxNew)
			{
				return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
			}
			float2 calcParallax(in float height, in PoiCam poiCam)
			{
				return ((height * - 1) + 1) * (poiCam.tangentViewDir.xy / poiCam.tangentViewDir.z);
			}
			
			/*
			0: Zero	                float4(0.0, 0.0, 0.0, 0.0),
			1: One	                float4(1.0, 1.0, 1.0, 1.0),
			2: DstColor	            destinationColor,
			3: SrcColor	            sourceColor,
			4: OneMinusDstColor	    float4(1.0, 1.0, 1.0, 1.0) - destinationColor,
			5: SrcAlpha	            sourceColor.aaaa,
			6: OneMinusSrcColor	    float4(1.0, 1.0, 1.0, 1.0) - sourceColor,
			7: DstAlpha	            destinationColor.aaaa,
			8: OneMinusDstAlpha	    float4(1.0, 1.0, 1.0, 1.0) - destinationColor.,
			9: SrcAlphaSaturate     saturate(sourceColor.aaaa),
			10: OneMinusSrcAlpha	float4(1.0, 1.0, 1.0, 1.0) - sourceColor.aaaa,
			*/
			
			float4 poiBlend(const float sourceFactor, const  float4 sourceColor, const  float destinationFactor, const  float4 destinationColor, const float4 blendFactor)
			{
				float4 sA = 1 - blendFactor;
				const float4 blendData[11] = {
					float4(0.0, 0.0, 0.0, 0.0),
					float4(1.0, 1.0, 1.0, 1.0),
					destinationColor,
					sourceColor,
					float4(1.0, 1.0, 1.0, 1.0) - destinationColor,
					sA,
					float4(1.0, 1.0, 1.0, 1.0) - sourceColor,
					sA,
					float4(1.0, 1.0, 1.0, 1.0) - sA,
					saturate(sourceColor.aaaa),
					1 - sA,
				};
				
				return lerp(blendData[sourceFactor] * sourceColor + blendData[destinationFactor] * destinationColor, sourceColor, sA);
			}
			
			// Average
			float blendAverage(float base, float blend)
			{
				return (base + blend) / 2.0;
			}
			float3 blendAverage(float3 base, float3 blend)
			{
				return (base + blend) / 2.0;
			}
			
			// Color burn
			float blendColorBurn(float base, float blend)
			{
				return (blend == 0.0) ? blend : max((1.0 - ((1.0 - base) * rcp(random_uniform_float_only_used_to_stop_compiler_warnings + blend))), 0.0);
			}
			
			float3 blendColorBurn(float3 base, float3 blend)
			{
				return float3(blendColorBurn(base.r, blend.r), blendColorBurn(base.g, blend.g), blendColorBurn(base.b, blend.b));
			}
			
			// Color Dodge
			float blendColorDodge(float base, float blend)
			{
				return (blend == 1.0) ? blend : min(base / (1.0 - blend), 1.0);
			}
			
			float3 blendColorDodge(float3 base, float3 blend)
			{
				return float3(blendColorDodge(base.r, blend.r), blendColorDodge(base.g, blend.g), blendColorDodge(base.b, blend.b));
			}
			
			// Darken
			float blendDarken(float base, float blend)
			{
				return min(blend, base);
			}
			
			float3 blendDarken(float3 base, float3 blend)
			{
				return float3(blendDarken(base.r, blend.r), blendDarken(base.g, blend.g), blendDarken(base.b, blend.b));
			}
			
			// Exclusion
			float blendExclusion(float base, float blend)
			{
				return base + blend - 2.0 * base * blend;
			}
			float3 blendExclusion(float3 base, float3 blend)
			{
				return base + blend - 2.0 * base * blend;
			}
			
			// Reflect
			float blendReflect(float base, float blend)
			{
				return (blend == 1.0) ? blend : min(base * base / (1.0 - blend), 1.0);
			}
			
			float3 blendReflect(float3 base, float3 blend)
			{
				return float3(blendReflect(base.r, blend.r), blendReflect(base.g, blend.g), blendReflect(base.b, blend.b));
			}
			
			// Glow
			float blendGlow(float base, float blend)
			{
				return blendReflect(blend, base);
			}
			float3 blendGlow(float3 base, float3 blend)
			{
				return blendReflect(blend, base);
			}
			
			// Overlay
			float blendOverlay(float base, float blend)
			{
				return base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend));
			}
			
			float3 blendOverlay(float3 base, float3 blend)
			{
				return float3(blendOverlay(base.r, blend.r), blendOverlay(base.g, blend.g), blendOverlay(base.b, blend.b));
			}
			
			// Hard Light
			float blendHardLight(float base, float blend)
			{
				return blendOverlay(blend, base);
			}
			float3 blendHardLight(float3 base, float3 blend)
			{
				return blendOverlay(blend, base);
			}
			
			// Vivid light
			float blendVividLight(float base, float blend)
			{
				return (blend < 0.5) ? blendColorBurn(base, (2.0 * blend)) : blendColorDodge(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendVividLight(float3 base, float3 blend)
			{
				return float3(blendVividLight(base.r, blend.r), blendVividLight(base.g, blend.g), blendVividLight(base.b, blend.b));
			}
			
			// Hard mix
			float blendHardMix(float base, float blend)
			{
				return (blendVividLight(base, blend) < 0.5) ? 0.0 : 1.0;
			}
			
			float3 blendHardMix(float3 base, float3 blend)
			{
				return float3(blendHardMix(base.r, blend.r), blendHardMix(base.g, blend.g), blendHardMix(base.b, blend.b));
			}
			
			// Lighten
			float blendLighten(float base, float blend)
			{
				return max(blend, base);
			}
			
			float3 blendLighten(float3 base, float3 blend)
			{
				return float3(blendLighten(base.r, blend.r), blendLighten(base.g, blend.g), blendLighten(base.b, blend.b));
			}
			
			// Linear Burn
			float blendLinearBurn(float base, float blend)
			{
				// Note : Same implementation as BlendSubtractf
				return max(base + blend - 1.0, 0.0);
			}
			
			float3 blendLinearBurn(float3 base, float3 blend)
			{
				// Note : Same implementation as BlendSubtract
				return max(base + blend - float3(1.0, 1.0, 1.0), float3(0.0, 0.0, 0.0));
			}
			
			// Linear Dodge
			float blendLinearDodge(float base, float blend)
			{
				// Note : Same implementation as BlendAddf
				return min(base + blend, 1.0);
			}
			
			float3 blendLinearDodge(float3 base, float3 blend)
			{
				// Note : Same implementation as BlendAdd
				return base + blend;
			}
			
			// Linear light
			float blendLinearLight(float base, float blend)
			{
				return blend < 0.5 ? blendLinearBurn(base, (2.0 * blend)) : blendLinearDodge(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendLinearLight(float3 base, float3 blend)
			{
				return float3(blendLinearLight(base.r, blend.r), blendLinearLight(base.g, blend.g), blendLinearLight(base.b, blend.b));
			}
			
			// Multiply
			float blendMultiply(float base, float blend)
			{
				return base * blend;
			}
			float3 blendMultiply(float3 base, float3 blend)
			{
				return base * blend;
			}
			
			// Negation
			float blendNegation(float base, float blend)
			{
				return 1.0 - abs(1.0 - base - blend);
			}
			float3 blendNegation(float3 base, float3 blend)
			{
				return float3(1.0, 1.0, 1.0) - abs(float3(1.0, 1.0, 1.0) - base - blend);
			}
			
			// Normal
			float blendNormal(float base, float blend)
			{
				return blend;
			}
			float3 blendNormal(float3 base, float3 blend)
			{
				return blend;
			}
			
			// Phoenix
			float blendPhoenix(float base, float blend)
			{
				return min(base, blend) - max(base, blend) + 1.0;
			}
			float3 blendPhoenix(float3 base, float3 blend)
			{
				return min(base, blend) - max(base, blend) + float3(1.0, 1.0, 1.0);
			}
			
			// Pin light
			float blendPinLight(float base, float blend)
			{
				return (blend < 0.5) ? blendDarken(base, (2.0 * blend)) : blendLighten(base, (2.0 * (blend - 0.5)));
			}
			
			float3 blendPinLight(float3 base, float3 blend)
			{
				return float3(blendPinLight(base.r, blend.r), blendPinLight(base.g, blend.g), blendPinLight(base.b, blend.b));
			}
			
			// Screen
			float blendScreen(float base, float blend)
			{
				return 1.0 - ((1.0 - base) * (1.0 - blend));
			}
			
			float3 blendScreen(float3 base, float3 blend)
			{
				return float3(blendScreen(base.r, blend.r), blendScreen(base.g, blend.g), blendScreen(base.b, blend.b));
			}
			
			// Soft Light
			float blendSoftLight(float base, float blend)
			{
				return (blend < 0.5) ? (2.0 * base * blend + base * base * (1.0 - 2.0 * blend)) : (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend));
			}
			
			float3 blendSoftLight(float3 base, float3 blend)
			{
				return float3(blendSoftLight(base.r, blend.r), blendSoftLight(base.g, blend.g), blendSoftLight(base.b, blend.b));
			}
			
			// Subtract
			float blendSubtract(float base, float blend)
			{
				return max(base - blend, 0.0);
			}
			
			float3 blendSubtract(float3 base, float3 blend)
			{
				return max(base - blend, 0.0);
			}
			
			// Difference
			float blendDifference(float base, float blend)
			{
				return abs(base - blend);
			}
			
			float3 blendDifference(float3 base, float3 blend)
			{
				return abs(base - blend);
			}
			
			// Divide
			float blendDivide(float base, float blend)
			{
				return base / max(blend, 0.0001);
			}
			
			float3 blendDivide(float3 base, float3 blend)
			{
				return base / max(blend, 0.0001);
			}
			
			float blendMixed(float base, float blend)
			{
				return base + base * blend;
			}
			
			float3 blendMixed(float3 base, float3 blend)
			{
				return base + base * blend;
			}
			
			float3 customBlend(float3 base, float3 blend, float blendType, float alpha = 1)
			{
				float3 output = base;
				switch(blendType)
				{
					case 0: output = lerp(base, blend, alpha); break;
					case 1: output = lerp(base, blendDarken(base, blend), alpha); break;
					case 2: output = base * lerp(1, blend, alpha); break;
					case 5: output = lerp(base, blendLighten(base, blend), alpha); break;
					case 6: output = lerp(base, blendScreen(base, blend), alpha); break;
					case 7: output = blendSubtract(base, blend * alpha); break;
					case 8: output = lerp(base, blendLinearDodge(base, blend), alpha); break;
					case 9: output = lerp(base, blendOverlay(base, blend), alpha); break;
					case 20: output = lerp(base, blendMixed(base, blend), alpha); break;
					default: output = 0; break;
				}
				return output;
			}
			
			float3 customBlend(float base, float blend, float blendType, float alpha = 1)
			{
				float3 output = base;
				switch(blendType)
				{
					case 0: output = lerp(base, blend, alpha); break;
					case 2: output = base * lerp(1, blend, alpha); break;
					case 5: output = lerp(base, blendLighten(base, blend), alpha); break;
					case 6: output = lerp(base, blendScreen(base, blend), alpha); break;
					case 7: output = blendSubtract(base, blend * alpha); break;
					case 8: output = lerp(base, blendLinearDodge(base, blend), alpha); break;
					case 9: output = lerp(base, blendOverlay(base, blend), alpha); break;
					case 20: output = lerp(base, blendMixed(base, blend), alpha); break;
					default: output = 0; break;
				}
				return output;
			}
			
			#define REPLACE 0
			#define SUBSTRACT 1
			#define MULTIPLY 2
			#define DIVIDE 3
			#define MIN 4
			#define MAX 5
			#define AVERAGE 6
			#define ADD 7
			
			float maskBlend(float baseMask, float blendMask, float blendType)
			{
				float output = 0;
				switch(blendType)
				{
					case REPLACE: output = blendMask; break;
					case SUBSTRACT: output = baseMask - blendMask; break;
					case MULTIPLY: output = baseMask * blendMask; break;
					case DIVIDE: output = baseMask / blendMask; break;
					case MIN: output = min(baseMask, blendMask); break;
					case MAX: output = max(baseMask, blendMask); break;
					case AVERAGE: output = (baseMask + blendMask) * 0.5; break;
					case ADD: output = baseMask + blendMask; break;
				}
				return saturate(output);
			}
			
			float globalMaskBlend(float baseMask, float globalMaskIndex, float blendType, PoiMods poiMods)
			{
				if (globalMaskIndex == 0)
				{
					return baseMask;
				}
				else
				{
					return maskBlend(baseMask, poiMods.globalMask[globalMaskIndex - 1], blendType);
				}
			}
			
			float random(float2 p)
			{
				return frac(sin(dot(p, float2(12.9898, 78.2383))) * 43758.5453123);
			}
			
			float2 random2(float2 p)
			{
				return frac(sin(float2(dot(p, float2(127.1, 311.7)), dot(p, float2(269.5, 183.3)))) * 43758.5453);
			}
			
			float3 random3(float2 p)
			{
				return frac(sin(float3(dot(p, float2(127.1, 311.7)), dot(p, float2(269.5, 183.3)), dot(p, float2(248.3, 315.9)))) * 43758.5453);
			}
			
			float3 random3(float3 p)
			{
				return frac(sin(float3(dot(p, float3(127.1, 311.7, 248.6)), dot(p, float3(269.5, 183.3, 423.3)), dot(p, float3(248.3, 315.9, 184.2)))) * 43758.5453);
			}
			
			float3 randomFloat3(float2 Seed, float maximum)
			{
				return (.5 + float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed), float2(12.9898, 78.233))) * 43758.5453)
				) * .5) * (maximum);
			}
			
			float3 randomFloat3Range(float2 Seed, float Range)
			{
				return (float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed.x * Seed.y, Seed.y + Seed.x), float2(12.9898, 78.233))) * 43758.5453)
				) * 2 - 1) * Range;
			}
			
			float3 randomFloat3WiggleRange(float2 Seed, float Range, float wiggleSpeed, float timeOffset)
			{
				float3 rando = (float3(
				frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
				frac(sin(dot(float2(Seed.x * Seed.y, Seed.y + Seed.x), float2(12.9898, 78.233))) * 43758.5453)
				) * 2 - 1);
				float speed = 1 + wiggleSpeed;
				return float3(sin(((_Time.x + timeOffset) + rando.x * PI) * speed), sin(((_Time.x + timeOffset) + rando.y * PI) * speed), sin(((_Time.x + timeOffset) + rando.z * PI) * speed)) * Range;
			}
			
			void poiDither(float4 In, float4 ScreenPosition, out float4 Out)
			{
				float2 uv = ScreenPosition.xy * _ScreenParams.xy;
				float DITHER_THRESHOLDS[16] = {
					1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0,
					13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0,
					4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0,
					16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0
				};
				uint index = (uint(uv.x) % 4) * 4 + uint(uv.y) % 4;
				Out = In - DITHER_THRESHOLDS[index];
			}
			// The weights of RGB contributions to luminance.
			// Should sum to unity.
			static const float3 HCYwts = float3(0.299, 0.587, 0.114);
			static const float HCLgamma = 3;
			static const float HCLy0 = 100;
			static const float HCLmaxL = 0.530454533953517; // == exp(HCLgamma / HCLy0) - 0.5
			static const float3 wref = float3(1.0, 1.0, 1.0);
			#define TAU 6.28318531
			
			float3 HUEtoRGB(in float H)
			{
				float R = abs(H * 6 - 3) - 1;
				float G = 2 - abs(H * 6 - 2);
				float B = 2 - abs(H * 6 - 4);
				return saturate(float3(R, G, B));
			}
			
			float3 RGBtoHCV(in float3 RGB)
			{
				// Based on work by Sam Hocevar and Emil Persson
				float4 P = (RGB.g < RGB.b) ? float4(RGB.bg, -1.0, 2.0 / 3.0) : float4(RGB.gb, 0.0, -1.0 / 3.0);
				float4 Q = (RGB.r < P.x) ? float4(P.xyw, RGB.r) : float4(RGB.r, P.yzx);
				float C = Q.x - min(Q.w, Q.y);
				float H = abs((Q.w - Q.y) / (6 * C + Epsilon) + Q.z);
				return float3(H, C, Q.x);
			}
			
			float3 HSVtoRGB(in float3 HSV)
			{
				float3 RGB = HUEtoRGB(HSV.x);
				return ((RGB - 1) * HSV.y + 1) * HSV.z;
			}
			
			float3 RGBtoHSV(in float3 RGB)
			{
				float3 HCV = RGBtoHCV(RGB);
				float S = HCV.y / (HCV.z + Epsilon);
				return float3(HCV.x, S, HCV.z);
			}
			
			float3 HSLtoRGB(in float3 HSL)
			{
				float3 RGB = HUEtoRGB(HSL.x);
				float C = (1 - abs(2 * HSL.z - 1)) * HSL.y;
				return (RGB - 0.5) * C + HSL.z;
			}
			
			float3 RGBtoHSL(in float3 RGB)
			{
				float3 HCV = RGBtoHCV(RGB);
				float L = HCV.z - HCV.y * 0.5;
				float S = HCV.y / (1 - abs(L * 2 - 1) + Epsilon);
				return float3(HCV.x, S, L);
			}
			
			void DecomposeHDRColor(in float3 linearColorHDR, out float3 baseLinearColor, out float exposure)
			{
				// Optimization/adaptation of https://github.com/Unity-Technologies/UnityCsReference/blob/master/Editor/Mono/GUI/ColorMutator.cs#L23 but skips weird photoshop stuff
				float maxColorComponent = max(linearColorHDR.r, max(linearColorHDR.g, linearColorHDR.b));
				bool isSDR = maxColorComponent <= 1.0;
				
				float scaleFactor = isSDR ? 1.0 : (1.0 / maxColorComponent);
				exposure = isSDR ? 0.0 : log(maxColorComponent) * 1.44269504089; // ln(2)
				
				baseLinearColor = scaleFactor * linearColorHDR;
			}
			
			float3 ApplyHDRExposure(float3 linearColor, float exposure)
			{
				return linearColor * pow(2, exposure);
			}
			
			// Transforms an RGB color using a matrix. Note that S and V are absolute values here
			float3 ModifyViaHSV(float3 color, float h, float s, float v)
			{
				float3 colorHSV = RGBtoHSV(color);
				colorHSV.x = frac(colorHSV.x + h);
				colorHSV.y = saturate(colorHSV.y + s);
				colorHSV.z = saturate(colorHSV.z + v);
				return HSVtoRGB(colorHSV);
			}
			
			float3 ModifyViaHSV(float3 color, float3 HSVMod)
			{
				return ModifyViaHSV(color, HSVMod.x, HSVMod.y, HSVMod.z);
			}
			
			float4x4 brightnessMatrix(float brightness)
			{
				return float4x4(
				1, 0, 0, 0,
				0, 1, 0, 0,
				0, 0, 1, 0,
				brightness, brightness, brightness, 1
				);
			}
			
			float4x4 contrastMatrix(float contrast)
			{
				float t = (1.0 - contrast) / 2.0;
				
				return float4x4(
				contrast, 0, 0, 0,
				0, contrast, 0, 0,
				0, 0, contrast, 0,
				t, t, t, 1
				);
			}
			
			float4x4 saturationMatrix(float saturation)
			{
				float3 luminance = float3(0.3086, 0.6094, 0.0820);
				
				float oneMinusSat = 1.0 - saturation;
				
				float3 red = luminance.x * oneMinusSat;
				red += float3(saturation, 0, 0);
				
				float3 green = luminance.y * oneMinusSat;
				green += float3(0, saturation, 0);
				
				float3 blue = luminance.z * oneMinusSat;
				blue += float3(0, 0, saturation);
				
				return float4x4(
				red, 0,
				green, 0,
				blue, 0,
				0, 0, 0, 1
				);
			}
			
			float4 PoiColorBCS(float4 color, float brightness, float contrast, float saturation)
			{
				return mul(color, mul(brightnessMatrix(brightness), mul(contrastMatrix(contrast), saturationMatrix(saturation))));
			}
			float3 PoiColorBCS(float3 color, float brightness, float contrast, float saturation)
			{
				return mul(float4(color, 1), mul(brightnessMatrix(brightness), mul(contrastMatrix(contrast), saturationMatrix(saturation)))).rgb;
			}
			
			float3 linear_srgb_to_oklab(float3 c)
			{
				float l = 0.4122214708 * c.x + 0.5363325363 * c.y + 0.0514459929 * c.z;
				float m = 0.2119034982 * c.x + 0.6806995451 * c.y + 0.1073969566 * c.z;
				float s = 0.0883024619 * c.x + 0.2817188376 * c.y + 0.6299787005 * c.z;
				
				float l_ = pow(l, 1.0 / 3.0);
				float m_ = pow(m, 1.0 / 3.0);
				float s_ = pow(s, 1.0 / 3.0);
				
				return float3(
				0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_,
				1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_,
				0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_
				);
			}
			
			float3 oklab_to_linear_srgb(float3 c)
			{
				float l_ = c.x + 0.3963377774 * c.y + 0.2158037573 * c.z;
				float m_ = c.x - 0.1055613458 * c.y - 0.0638541728 * c.z;
				float s_ = c.x - 0.0894841775 * c.y - 1.2914855480 * c.z;
				
				float l = l_ * l_ * l_;
				float m = m_ * m_ * m_;
				float s = s_ * s_ * s_;
				
				return float3(
				+ 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
				- 1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
				- 0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s
				);
			}
			
			float3 hueShift(float3 color, float shift)
			{
				float3 oklab = linear_srgb_to_oklab(max(color, 0.0000000001));
				float hue = atan2(oklab.z, oklab.y);
				hue += shift * PI * 2;  // Add the hue shift
				
				float chroma = length(oklab.yz);
				oklab.y = cos(hue) * chroma;
				oklab.z = sin(hue) * chroma;
				
				return oklab_to_linear_srgb(oklab);
			}
			
			float3 hueShift(float4 color, float shift)
			{
				return hueShift(color.rgb, shift);
			}
			
			/*
			float3 hueShift(float3 color, float hueOffset)
			{
				color = RGBtoHSV(color);
				color.x = frac(hueOffset +color.x);
				return HSVtoRGB(color);
			}
			*/
			
			// LCH
			float xyzF(float t)
			{
				return lerp(pow(t, 1. / 3.), 7.787037 * t + 0.139731, step(t, 0.00885645));
			}
			float xyzR(float t)
			{
				return lerp(t * t * t, 0.1284185 * (t - 0.139731), step(t, 0.20689655));
			}
			
			float4x4 poiRotationMatrixFromAngles(float x, float y, float z)
			{
				float angleX = radians(x);
				float c = cos(angleX);
				float s = sin(angleX);
				float4x4 rotateXMatrix = float4x4(1, 0, 0, 0,
				0, c, -s, 0,
				0, s, c, 0,
				0, 0, 0, 1);
				
				float angleY = radians(y);
				c = cos(angleY);
				s = sin(angleY);
				float4x4 rotateYMatrix = float4x4(c, 0, s, 0,
				0, 1, 0, 0,
				- s, 0, c, 0,
				0, 0, 0, 1);
				
				float angleZ = radians(z);
				c = cos(angleZ);
				s = sin(angleZ);
				float4x4 rotateZMatrix = float4x4(c, -s, 0, 0,
				s, c, 0, 0,
				0, 0, 1, 0,
				0, 0, 0, 1);
				
				return mul(mul(rotateXMatrix, rotateYMatrix), rotateZMatrix);
			}
			
			float4x4 poiRotationMatrixFromAngles(float3 angles)
			{
				float angleX = radians(angles.x);
				float c = cos(angleX);
				float s = sin(angleX);
				float4x4 rotateXMatrix = float4x4(1, 0, 0, 0,
				0, c, -s, 0,
				0, s, c, 0,
				0, 0, 0, 1);
				
				float angleY = radians(angles.y);
				c = cos(angleY);
				s = sin(angleY);
				float4x4 rotateYMatrix = float4x4(c, 0, s, 0,
				0, 1, 0, 0,
				- s, 0, c, 0,
				0, 0, 0, 1);
				
				float angleZ = radians(angles.z);
				c = cos(angleZ);
				s = sin(angleZ);
				float4x4 rotateZMatrix = float4x4(c, -s, 0, 0,
				s, c, 0, 0,
				0, 0, 1, 0,
				0, 0, 0, 1);
				
				return mul(mul(rotateXMatrix, rotateYMatrix), rotateZMatrix);
			}
			
			float3 getCameraPosition()
			{
				#ifdef USING_STEREO_MATRICES
				return lerp(unity_StereoWorldSpaceCameraPos[0], unity_StereoWorldSpaceCameraPos[1], 0.5);
				#endif
				return _WorldSpaceCameraPos;
			}
			
			float2 calcPixelScreenUVs(half4 grabPos)
			{
				half2 uv = grabPos.xy / (grabPos.w + 0.0000000001);
				#if UNITY_SINGLE_PASS_STEREO
				uv.xy *= half2(_ScreenParams.x * 2, _ScreenParams.y);
				#else
				uv.xy *= _ScreenParams.xy;
				#endif
				
				return uv;
			}
			
			float CalcMipLevel(float2 texture_coord)
			{
				float2 dx = ddx(texture_coord);
				float2 dy = ddy(texture_coord);
				float delta_max_sqr = max(dot(dx, dx), dot(dy, dy));
				
				return 0.5 * log2(delta_max_sqr);
			}
			
			float inverseLerp(float A, float B, float T)
			{
				return (T - A) / (B - A);
			}
			
			float inverseLerp2(float2 a, float2 b, float2 value)
			{
				float2 AB = b - a;
				float2 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			float inverseLerp3(float3 a, float3 b, float3 value)
			{
				float3 AB = b - a;
				float3 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			float inverseLerp4(float4 a, float4 b, float4 value)
			{
				float4 AB = b - a;
				float4 AV = value - a;
				return dot(AV, AB) / dot(AB, AB);
			}
			
			/*
			MIT License
			
			Copyright (c) 2019 wraikny
			
			Permission is hereby granted, free of charge, to any person obtaining a copy
			of this software and associated documentation files (the "Software"), to deal
			in the Software without restriction, including without limitation the rights
			to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
			copies of the Software, and to permit persons to whom the Software is
			furnished to do so, subject to the following conditions:
			
			The above copyright notice and this permission notice shall be included in all
			copies or substantial portions of the Software.
			
			THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
			IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
			FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
			AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
			LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
			OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
			SOFTWARE.
			
			VertexTransformShader is dependent on:
			*/
			
			float4 quaternion_conjugate(float4 v)
			{
				return float4(
				v.x, -v.yzw
				);
			}
			
			float4 quaternion_mul(float4 v1, float4 v2)
			{
				float4 result1 = (v1.x * v2 + v1 * v2.x);
				
				float4 result2 = float4(
				- dot(v1.yzw, v2.yzw),
				cross(v1.yzw, v2.yzw)
				);
				
				return float4(result1 + result2);
			}
			
			// angle : radians
			float4 get_quaternion_from_angle(float3 axis, float angle)
			{
				float sn = sin(angle * 0.5);
				float cs = cos(angle * 0.5);
				return float4(axis * sn, cs);
			}
			
			float4 quaternion_from_vector(float3 inVec)
			{
				return float4(0.0, inVec);
			}
			
			float degree_to_radius(float degree)
			{
				return (
				degree / 180.0 * PI
				);
			}
			
			float3 rotate_with_quaternion(float3 inVec, float3 rotation)
			{
				float4 qx = get_quaternion_from_angle(float3(1, 0, 0), radians(rotation.x));
				float4 qy = get_quaternion_from_angle(float3(0, 1, 0), radians(rotation.y));
				float4 qz = get_quaternion_from_angle(float3(0, 0, 1), radians(rotation.z));
				
				#define MUL3(A, B, C) quaternion_mul(quaternion_mul((A), (B)), (C))
				float4 quaternion = normalize(MUL3(qx, qy, qz));
				float4 conjugate = quaternion_conjugate(quaternion);
				
				float4 inVecQ = quaternion_from_vector(inVec);
				
				float3 rotated = (
				MUL3(quaternion, inVecQ, conjugate)
				).yzw;
				
				return rotated;
			}
			
			float4 transform(float4 input, float4 pos, float4 rotation, float4 scale)
			{
				input.rgb *= (scale.xyz * scale.w);
				input = float4(rotate_with_quaternion(input.xyz, rotation.xyz * rotation.w) + (pos.xyz * pos.w), input.w);
				return input;
			}
			
			float2 RotateUV(float2 _uv, float _radian, float2 _piv, float _time)
			{
				float RotateUV_ang = _radian;
				float RotateUV_cos = cos(_time * RotateUV_ang);
				float RotateUV_sin = sin(_time * RotateUV_ang);
				return (mul(_uv - _piv, float2x2(RotateUV_cos, -RotateUV_sin, RotateUV_sin, RotateUV_cos)) + _piv);
			}
			
			/*
			MIT END
			*/
			
			float3 RotateAroundAxis(float3 original, float3 axis, float radian)
			{
				float s = sin(radian);
				float c = cos(radian);
				float one_minus_c = 1.0 - c;
				
				axis = normalize(axis);
				float3x3 rot_mat = {
					one_minus_c * axis.x * axis.x + c, one_minus_c * axis.x * axis.y - axis.z * s, one_minus_c * axis.z * axis.x + axis.y * s,
					one_minus_c * axis.x * axis.y + axis.z * s, one_minus_c * axis.y * axis.y + c, one_minus_c * axis.y * axis.z - axis.x * s,
					one_minus_c * axis.z * axis.x - axis.y * s, one_minus_c * axis.y * axis.z + axis.x * s, one_minus_c * axis.z * axis.z + c
				};
				return mul(rot_mat, original);
			}
			
			float3 poiThemeColor(in PoiMods poiMods, in float3 srcColor, in float themeIndex)
			{
				float3 outputColor = srcColor;
				if (themeIndex != 0)
				{
					themeIndex = max(themeIndex - 1, 0);
					
					if (themeIndex <= 3)
					{
						outputColor = poiMods.globalColorTheme[themeIndex];
					}
					else
					{
						#ifdef POI_AUDIOLINK
						if (poiMods.audioLinkAvailable)
						{
							outputColor = poiMods.globalColorTheme[themeIndex];
						}
						#endif
					}
				}
				return outputColor;
			}
			
			float3 lilToneCorrection(float3 c, float4 hsvg)
			{
				// gamma
				c = pow(abs(c), hsvg.w);
				// rgb - > hsv
				float4 p = (c.b > c.g) ? float4(c.bg, -1.0, 2.0 / 3.0) : float4(c.gb, 0.0, -1.0 / 3.0);
				float4 q = (p.x > c.r) ? float4(p.xyw, c.r) : float4(c.r, p.yzx);
				float d = q.x - min(q.w, q.y);
				float e = 1.0e-10;
				float3 hsv = float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
				// shift
				hsv = float3(hsv.x + hsvg.x, saturate(hsv.y * hsvg.y), saturate(hsv.z * hsvg.z));
				// hsv - > rgb
				return hsv.z - hsv.z * hsv.y + hsv.z * hsv.y * saturate(abs(frac(hsv.x + float3(1.0, 2.0 / 3.0, 1.0 / 3.0)) * 6.0 - 3.0) - 1.0);
			}
			
			float3 lilBlendColor(float3 dstCol, float3 srcCol, float3 srcA, int blendMode)
			{
				float3 ad = dstCol + srcCol;
				float3 mu = dstCol * srcCol;
				float3 outCol = float3(0, 0, 0);
				if (blendMode == 0) outCol = srcCol; // Normal
				if (blendMode == 1) outCol = ad; // Add
				if (blendMode == 2) outCol = max(ad - mu, dstCol); // Screen
				if (blendMode == 3) outCol = mu; // Multiply
				return lerp(dstCol, outCol, srcA);
			}
			
			float lilIsIn0to1(float f)
			{
				float value = 0.5 - abs(f - 0.5);
				return saturate(value / clamp(fwidth(value), 0.0001, 1.0));
			}
			
			float lilIsIn0to1(float f, float nv)
			{
				float value = 0.5 - abs(f - 0.5);
				return saturate(value / clamp(fwidth(value), 0.0001, nv));
			}
			
			float poiEdgeLinearNoSaturate(float value, float border)
			{
				return (value - border) / clamp(fwidth(value), 0.0001, 1.0);
			}
			
			float3 poiEdgeLinearNoSaturate(float value, float3 border)
			{
				return float3(
				(value - border.x) / clamp(fwidth(value), 0.0001, 1.0),
				(value - border.y) / clamp(fwidth(value), 0.0001, 1.0),
				(value - border.z) / clamp(fwidth(value), 0.0001, 1.0)
				);
			}
			
			float poiEdgeLinearNoSaturate(float value, float border, float blur)
			{
				float borderMin = saturate(border - blur * 0.5);
				float borderMax = saturate(border + blur * 0.5);
				return (value - borderMin) / saturate(borderMax - borderMin + fwidth(value));
			}
			
			float poiEdgeLinearNoSaturate(float value, float border, float blur, float borderRange)
			{
				float borderMin = saturate(border - blur * 0.5 - borderRange);
				float borderMax = saturate(border + blur * 0.5);
				return (value - borderMin) / saturate(borderMax - borderMin + fwidth(value));
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border)
			{
				// return (value - border) / clamp(fwidth(value), 0.0001, 1.0);
				
				float fwidthValue = fwidth(value);
				return smoothstep(border - fwidthValue, border + fwidthValue, value);
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border, float blur)
			{
				float fwidthValue = fwidth(value);
				float borderMin = saturate(border - blur * 0.5);
				float borderMax = saturate(border + blur * 0.5);
				return smoothstep(borderMin - fwidthValue, borderMax + fwidthValue, value);
			}
			
			float poiEdgeNonLinearNoSaturate(float value, float border, float blur, float borderRange)
			{
				float fwidthValue = fwidth(value);
				float borderMin = saturate(border - blur * 0.5 - borderRange);
				float borderMax = saturate(border + blur * 0.5);
				return smoothstep(borderMin - fwidthValue, borderMax + fwidthValue, value);
			}
			
			float poiEdgeNonLinear(float value, float border)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border));
			}
			
			float poiEdgeNonLinear(float value, float border, float blur)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border, blur));
			}
			
			float poiEdgeNonLinear(float value, float border, float blur, float borderRange)
			{
				return saturate(poiEdgeNonLinearNoSaturate(value, border, blur, borderRange));
			}
			
			float poiEdgeLinear(float value, float border)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border));
			}
			
			float poiEdgeLinear(float value, float border, float blur)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border, blur));
			}
			
			float poiEdgeLinear(float value, float border, float blur, float borderRange)
			{
				return saturate(poiEdgeLinearNoSaturate(value, border, blur, borderRange));
			}
			// From https : // github.com / lilxyzw / OpenLit / blob / main / Assets / OpenLit / core.hlsl
			float3 OpenLitLinearToSRGB(float3 col)
			{
				return LinearToGammaSpace(col);
			}
			
			float3 OpenLitSRGBToLinear(float3 col)
			{
				return GammaToLinearSpace(col);
			}
			
			float OpenLitLuminance(float3 rgb)
			{
				#if defined(UNITY_COLORSPACE_GAMMA)
				return dot(rgb, float3(0.22, 0.707, 0.071));
				#else
				return dot(rgb, float3(0.0396819152, 0.458021790, 0.00609653955));
				#endif
			}
			
			float3 AdjustLitLuminance(float3 rgb, float targetLuminance)
			{
				float currentLuminance;
				#if defined(UNITY_COLORSPACE_GAMMA)
				currentLuminance = dot(rgb, float3(0.22, 0.707, 0.071));
				#else
				currentLuminance = dot(rgb, float3(0.0396819152, 0.458021790, 0.00609653955));
				#endif
				
				float luminanceRatio = targetLuminance / currentLuminance;
				return rgb * luminanceRatio;
			}
			
			float3 ClampLuminance(float3 rgb, float minLuminance, float maxLuminance)
			{
				float currentLuminance = dot(rgb, float3(0.299, 0.587, 0.114));
				float minRatio = (currentLuminance != 0) ? minLuminance / currentLuminance : 1.0;
				float maxRatio = (currentLuminance != 0) ? maxLuminance / currentLuminance : 1.0;
				float luminanceRatio = clamp(min(maxRatio, max(minRatio, 1.0)), 0.0, 1.0);
				return lerp(rgb, rgb * luminanceRatio, luminanceRatio < 1.0);
			}
			
			float3 MaxLuminance(float3 rgb, float maxLuminance)
			{
				float currentLuminance = dot(rgb, float3(0.299, 0.587, 0.114));
				float luminanceRatio = (currentLuminance != 0) ? maxLuminance / max(currentLuminance, 0.00001) : 1.0;
				return lerp(rgb, rgb * luminanceRatio, currentLuminance > maxLuminance);
			}
			
			float OpenLitGray(float3 rgb)
			{
				return dot(rgb, float3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0));
			}
			
			void OpenLitShadeSH9ToonDouble(float3 lightDirection, out float3 shMax, out float3 shMin)
			{
				#if !defined(LIGHTMAP_ON)
				float3 N = lightDirection * 0.666666;
				float4 vB = N.xyzz * N.yzzx;
				// L0 L2
				float3 res = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
				res.r += dot(unity_SHBr, vB);
				res.g += dot(unity_SHBg, vB);
				res.b += dot(unity_SHBb, vB);
				res += unity_SHC.rgb * (N.x * N.x - N.y * N.y);
				// L1
				float3 l1;
				l1.r = dot(unity_SHAr.rgb, N);
				l1.g = dot(unity_SHAg.rgb, N);
				l1.b = dot(unity_SHAb.rgb, N);
				shMax = res + l1;
				shMin = res - l1;
				#if defined(UNITY_COLORSPACE_GAMMA)
				shMax = OpenLitLinearToSRGB(shMax);
				shMin = OpenLitLinearToSRGB(shMin);
				#endif
				#else
				shMax = 0.0;
				shMin = 0.0;
				#endif
			}
			
			float3 OpenLitComputeCustomLightDirection(float4 lightDirectionOverride)
			{
				float3 customDir = length(lightDirectionOverride.xyz) * normalize(mul((float3x3)unity_ObjectToWorld, lightDirectionOverride.xyz));
				return lightDirectionOverride.w ? customDir : lightDirectionOverride.xyz; // .w isn't doc'd anywhere and is always 0 unless end user changes it
			}
			
			float3 OpenLitLightingDirectionForSH9()
			{
				float3 mainDir = _WorldSpaceLightPos0.xyz * OpenLitLuminance(_LightColor0.rgb);
				#if !defined(LIGHTMAP_ON)
				float3 sh9Dir = unity_SHAr.xyz * 0.333333 + unity_SHAg.xyz * 0.333333 + unity_SHAb.xyz * 0.333333;
				float3 sh9DirAbs = float3(sh9Dir.x, abs(sh9Dir.y), sh9Dir.z);
				#else
				float3 sh9Dir = 0;
				float3 sh9DirAbs = 0;
				#endif
				
				float3 lightDirectionForSH9 = sh9Dir + mainDir;
				lightDirectionForSH9 = dot(lightDirectionForSH9, lightDirectionForSH9) < 0.000001 ? 0 : normalize(lightDirectionForSH9);
				return lightDirectionForSH9;
			}
			
			float3 OpenLitLightingDirection(float4 lightDirectionOverride)
			{
				float3 mainDir = _WorldSpaceLightPos0.xyz * OpenLitLuminance(_LightColor0.rgb);
				#if !defined(LIGHTMAP_ON) && UNITY_SHOULD_SAMPLE_SH
				float3 sh9Dir = unity_SHAr.xyz * 0.333333 + unity_SHAg.xyz * 0.333333 + unity_SHAb.xyz * 0.333333;
				float3 sh9DirAbs = float3(sh9Dir.x, abs(sh9Dir.y), sh9Dir.z);
				#else
				float3 sh9Dir = 0;
				float3 sh9DirAbs = 0;
				#endif
				float3 customDir = OpenLitComputeCustomLightDirection(lightDirectionOverride);
				
				return normalize(sh9DirAbs + mainDir + customDir);
			}
			
			float3 OpenLitLightingDirection()
			{
				float4 customDir = float4(0.001, 0.002, 0.001, 0.0);
				return OpenLitLightingDirection(customDir);
			}
			
			inline float4 CalculateFrustumCorrection()
			{
				float x1 = -UNITY_MATRIX_P._31 / (UNITY_MATRIX_P._11 * UNITY_MATRIX_P._34);
				float x2 = -UNITY_MATRIX_P._32 / (UNITY_MATRIX_P._22 * UNITY_MATRIX_P._34);
				return float4(x1, x2, 0, UNITY_MATRIX_P._33 / UNITY_MATRIX_P._34 + x1 * UNITY_MATRIX_P._13 + x2 * UNITY_MATRIX_P._23);
			}
			
			inline float CorrectedLinearEyeDepth(float z, float B)
			{
				return 1.0 / (z / UNITY_MATRIX_P._34 + B);
			}
			
			// Silent's code
			float2 sharpSample(float4 texelSize, float2 p)
			{
				p = p * texelSize.zw;
				float2 c = max(0.0, fwidth(p));
				p = floor(p) + saturate(frac(p) / c);
				p = (p - 0.5) * texelSize.xy;
				return p;
			}
			
			void applyToGlobalMask(inout PoiMods poiMods, int index, int blendType, float val)
			{
				float valBlended = saturate(maskBlend(poiMods.globalMask[index], val, blendType));
				switch(index)
				{
					case 0: poiMods.globalMask[0] = valBlended; break;
					case 1: poiMods.globalMask[1] = valBlended; break;
					case 2: poiMods.globalMask[2] = valBlended; break;
					case 3: poiMods.globalMask[3] = valBlended; break;
					case 4: poiMods.globalMask[4] = valBlended; break;
					case 5: poiMods.globalMask[5] = valBlended; break;
					case 6: poiMods.globalMask[6] = valBlended; break;
					case 7: poiMods.globalMask[7] = valBlended; break;
					case 8: poiMods.globalMask[8] = valBlended; break;
					case 9: poiMods.globalMask[9] = valBlended; break;
					case 10: poiMods.globalMask[10] = valBlended; break;
					case 11: poiMods.globalMask[11] = valBlended; break;
					case 12: poiMods.globalMask[12] = valBlended; break;
					case 13: poiMods.globalMask[13] = valBlended; break;
					case 14: poiMods.globalMask[14] = valBlended; break;
					case 15: poiMods.globalMask[15] = valBlended; break;
				}
			}
			
			void assignValueToVectorFromIndex(inout float4 vec, int index, float value)
			{
				switch(index)
				{
					case 0: vec[0] = value; break;
					case 1: vec[1] = value; break;
					case 2: vec[2] = value; break;
					case 3: vec[3] = value; break;
				}
			}
			
			// SNose
			float3 mod289(float3 x)
			{
				return x - floor(x * (1.0 / 289.0)) * 289.0;
			}
			float2 mod289(float2 x)
			{
				return x - floor(x * (1.0 / 289.0)) * 289.0;
			}
			float3 permute(float3 x)
			{
				return mod289(((x * 34.0) + 1.0) * x);
			}
			
			float snoise(float2 v)
			{
				const float4 C = float4(0.211324865405187, // (3.0 - sqrt(3.0)) / 6.0
				0.366025403784439, // 0.5 * (sqrt(3.0) - 1.0)
				- 0.577350269189626, // - 1.0 + 2.0 * C.x
				0.024390243902439); // 1.0 / 41.0
				float2 i = floor(v + dot(v, C.yy));
				float2 x0 = v - i + dot(i, C.xx);
				float2 i1;
				i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0);
				float4 x12 = x0.xyxy + C.xxzz;
				x12.xy -= i1;
				i = mod289(i); // Avoid truncation effects in permutation
				float3 p = permute(permute(i.y + float3(0.0, i1.y, 1.0))
				+ i.x + float3(0.0, i1.x, 1.0));
				
				float3 m = max(0.5 - float3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);
				m = m * m ;
				m = m * m ;
				float3 x = 2.0 * frac(p * C.www) - 1.0;
				float3 h = abs(x) - 0.5;
				float3 ox = floor(x + 0.5);
				float3 a0 = x - ox;
				m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);
				float3 g;
				g.x = a0.x * x0.x + h.x * x0.y;
				g.yz = a0.yz * x12.xz + h.yz * x12.yw;
				return 130.0 * dot(m, g);
			}
			
			float nsqDistance(float2 a, float2 b)
			{
				return dot(a - b, a - b);
			}
			
			float poiInvertToggle(in float value, in float toggle)
			{
				return (toggle == 0 ? value : 1 - value);
			}
			
			float3 PoiBlendNormal(float3 dstNormal, float3 srcNormal)
			{
				return float3(dstNormal.xy + srcNormal.xy, dstNormal.z * srcNormal.z);
			}
			
			float3 lilTransformDirOStoWS(float3 directionOS, bool doNormalize)
			{
				if (doNormalize) return normalize(mul((float3x3)unity_ObjectToWorld, directionOS));
				else            return mul((float3x3)unity_ObjectToWorld, directionOS);
			}
			
			float2 poiGetWidthAndHeight(Texture2D tex)
			{
				uint width, height;
				tex.GetDimensions(width, height);
				return float2(width, height);
			}
			
			float2 poiGetWidthAndHeight(Texture2DArray tex)
			{
				uint width, height, element;
				tex.GetDimensions(width, height, element);
				return float2(width, height);
			}
			//ifex _EnableAudioLink==0
			#ifdef POI_AUDIOLINK
			
			// Convenient mechanism to read from the AudioLink texture that handles reading off the end of one line and onto the next above it.
			float4 AudioLinkDataMultiline(uint2 xycoord)
			{
				return AudioLinkData(uint2(xycoord.x % AUDIOLINK_WIDTH, xycoord.y + xycoord.x / AUDIOLINK_WIDTH));
			}
			
			// Mechanism to sample between two adjacent pixels and lerp between them, like "linear" supesampling
			float4 AudioLinkLerp(float2 xy)
			{
				return lerp(AudioLinkData(xy), AudioLinkData(xy + int2(1, 0)), frac(xy.x));
			}
			
			// Same as AudioLinkLerp but properly handles multiline reading.
			float4 AudioLinkLerpMultiline(float2 xy)
			{
				return lerp(AudioLinkDataMultiline(xy), AudioLinkDataMultiline(xy + float2(1, 0)), frac(xy.x));
			}
			
			//Tests to see if Audio Link texture is available
			bool AudioLinkIsAvailable()
			{
				#if !defined(AUDIOLINK_STANDARD_INDEXING)
				int width, height;
				_AudioTexture.GetDimensions(width, height);
				return width > 16;
				#else
				return _AudioTexture_TexelSize.z > 16;
				#endif
			}
			
			//Get version of audiolink present in the world, 0 if no audiolink is present
			float AudioLinkGetVersion()
			{
				int2 dims;
				#if !defined(AUDIOLINK_STANDARD_INDEXING)
				_AudioTexture.GetDimensions(dims.x, dims.y);
				#else
				dims = _AudioTexture_TexelSize.zw;
				#endif
				
				if (dims.x >= 128)
				return AudioLinkData(ALPASS_GENERALVU).x;
				else if (dims.x > 16)
				return 1;
				else
				return 0;
			}
			
			// This pulls data from this texture.
			#define AudioLinkGetSelfPixelData(xy) _SelfTexture2D[xy]
			
			// Extra utility functions for time.
			uint AudioLinkDecodeDataAsUInt(uint2 indexloc)
			{
				uint4 rpx = AudioLinkData(indexloc);
				return rpx.r + rpx.g * 1024 + rpx.b * 1048576 + rpx.a * 1073741824;
			}
			
			//Note: This will truncate time to every 134,217.728 seconds (~1.5 days of an instance being up) to prevent floating point aliasing.
			// if your code will alias sooner, you will need to use a different function.  It should be safe to use this on all times.
			float AudioLinkDecodeDataAsSeconds(uint2 indexloc)
			{
				uint time = AudioLinkDecodeDataAsUInt(indexloc) & 0x7ffffff;
				//Can't just divide by float.  Bug in Unity's HLSL compiler.
				return float(time / 1000) + float(time % 1000) / 1000.;
			}
			
			#define ALDecodeDataAsSeconds(x) AudioLinkDecodeDataAsSeconds(x)
			#define ALDecodeDataAsUInt(x) AudioLinkDecodeDataAsUInt(x)
			
			float AudioLinkRemap(float t, float a, float b, float u, float v)
			{
				return ((t - a) / (b - a)) * (v - u) + u;
			}
			
			float3 AudioLinkHSVtoRGB(float3 HSV)
			{
				float3 RGB = 0;
				float C = HSV.z * HSV.y;
				float H = HSV.x * 6;
				float X = C * (1 - abs(fmod(H, 2) - 1));
				if (HSV.y != 0)
				{
					float I = floor(H);
					if (I == 0)
					{
						RGB = float3(C, X, 0);
					}
					else if (I == 1)
					{
						RGB = float3(X, C, 0);
					}
					else if (I == 2)
					{
						RGB = float3(0, C, X);
					}
					else if (I == 3)
					{
						RGB = float3(0, X, C);
					}
					else if (I == 4)
					{
						RGB = float3(X, 0, C);
					}
					else
					{
						RGB = float3(C, 0, X);
					}
				}
				float M = HSV.z - C;
				return RGB + M;
			}
			
			float3 AudioLinkCCtoRGB(float bin, float intensity, int rootNote)
			{
				float note = bin / AUDIOLINK_EXPBINS;
				
				float hue = 0.0;
				note *= 12.0;
				note = glsl_mod(4. - note + rootNote, 12.0);
				{
					if (note < 4.0)
					{
						//Needs to be YELLOW->RED
						hue = (note) / 24.0;
					}
					else if (note < 8.0)
					{
						//            [4]  [8]
						//Needs to be RED->BLUE
						hue = (note - 2.0) / 12.0;
					}
					else
					{
						//             [8] [12]
						//Needs to be BLUE->YELLOW
						hue = (note - 4.0) / 8.0;
					}
				}
				float val = intensity - 0.1;
				return AudioLinkHSVtoRGB(float3(fmod(hue, 1.0), 1.0, clamp(val, 0.0, 1.0)));
			}
			
			// Sample the amplitude of a given frequency in the DFT, supports frequencies in [13.75; 14080].
			float4 AudioLinkGetAmplitudeAtFrequency(float hertz)
			{
				float note = AUDIOLINK_EXPBINS * log2(hertz / AUDIOLINK_BOTTOM_FREQUENCY);
				return AudioLinkLerpMultiline(ALPASS_DFT + float2(note, 0));
			}
			
			// Sample the amplitude of a given semitone in an octave. Octave is in [0; 9] while note is [0; 11].
			float AudioLinkGetAmplitudeAtNote(float octave, float note)
			{
				float quarter = note * 2.0;
				return AudioLinkLerpMultiline(ALPASS_DFT + float2(octave * AUDIOLINK_EXPBINS + quarter, 0));
			}
			
			// Get a reasonable drop-in replacement time value for _Time.y with the
			// given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTime(uint index, uint band)
			{
				return (AudioLinkDecodeDataAsUInt(ALPASS_CHRONOTENSITY + uint2(index, band))) / 100000.0;
			}
			
			// Get a chronotensity value in the interval [0; 1], modulated by the speed input,
			// with the given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTimeNormalized(uint index, uint band, float speed)
			{
				return frac(AudioLinkGetChronoTime(index, band) * speed);
			}
			
			// Get a chronotensity value in the interval [0; interval], modulated by the speed input,
			// with the given chronotensity index [0; 7] and AudioLink band [0; 3].
			float AudioLinkGetChronoTimeInterval(uint index, uint band, float speed, float interval)
			{
				return AudioLinkGetChronoTimeNormalized(index, band, speed) * interval;
			}
			
			float getBandAtTime(float band, float time, float size = 1.0f)
			{
				//return remap(UNITY_SAMPLE_TEX2D(_AudioTexture, float2(time * width, band/128.0)).r, min(size,.9999), 1);
				return remapClamped(min(size, .9999), 1, AudioLinkData(ALPASS_AUDIOBASS + uint2(time * AUDIOLINK_WIDTH, band)).r);
			}
			
			fixed3 maximize(fixed3 c)
			{
				if (c.x == 0 && c.y == 0 && c.z == 0)
				return fixed3(1.0, 1.0, 1.0);
				else
				return c / max(c.r, max(c.g, c.b));
			}
			
			void initPoiAudioLink(inout PoiMods poiMods)
			{
				if (!_AudioLinkAnimToggle) return;
				
				if (AudioLinkIsAvailable())
				{
					poiMods.audioLinkAvailable = true;
					poiMods.audioLinkVersion = AudioLinkGetVersion();
					poiMods.audioLink[0] = _AudioLinkSmoothingBass == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 0))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingBass) * 15.95, 0))[0];
					poiMods.audioLink[1] = _AudioLinkSmoothingLowMid == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 1))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingLowMid) * 15.95, 1))[0];
					poiMods.audioLink[2] = _AudioLinkSmoothingHighMid == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 2))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingHighMid) * 15.95, 2))[0];
					poiMods.audioLink[3] = _AudioLinkSmoothingTreble == 0 ? AudioLinkData(ALPASS_AUDIOLINK + float2(0, 3))[0] : AudioLinkData(ALPASS_FILTEREDAUDIOLINK + float2((1 - _AudioLinkSmoothingTreble) * 15.95, 3))[0];
					poiMods.audioLink[4] = AudioLinkData(ALPASS_GENERALVU + float2(8, 0))[0];
					/*
					poiMods.globalColorTheme[4] = AudioLinkData( ALPASS_CCCOLORS + uint2( 0, 0 ) );
					poiMods.globalColorTheme[5] = AudioLinkData( ALPASS_CCCOLORS + uint2( 1, 0 ) );
					poiMods.globalColorTheme[6] = AudioLinkData( ALPASS_CCCOLORS + uint2( 2, 0 ) );
					poiMods.globalColorTheme[7] = AudioLinkData( ALPASS_CCCOLORS + uint2( 3, 0 ) );
					
					poiMods.globalColorTheme[4] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 0, 0 ) )),1.0);
					poiMods.globalColorTheme[5] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 1, 0 ) )),1.0);
					poiMods.globalColorTheme[6] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 2, 0 ) )),1.0);
					poiMods.globalColorTheme[7] =  float4(maximize(AudioLinkData( ALPASS_CCCOLORS + uint2( 3, 0 ) )),1.0);
					*/
					
					poiMods.globalColorTheme[4] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(2, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[5] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(3, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[6] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(4, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					poiMods.globalColorTheme[7] = float4(AudioLinkCCtoRGB(glsl_mod(AudioLinkData(ALPASS_CCINTERNAL + uint2(5, 0))[0], AUDIOLINK_EXPBINS), 1, AUDIOLINK_ROOTNOTE), 1.0);
					
					poiMods.globalColorTheme[8] = AudioLinkData(ALPASS_THEME_COLOR0);
					poiMods.globalColorTheme[9] = AudioLinkData(ALPASS_THEME_COLOR1);
					poiMods.globalColorTheme[10] = AudioLinkData(ALPASS_THEME_COLOR2);
					poiMods.globalColorTheme[11] = AudioLinkData(ALPASS_THEME_COLOR3);
					return;
				}
				
				if (_AudioLinkBandOverridesEnabled)
				{
					poiMods.audioLinkAvailable = true;
					poiMods.audioLink[0] = _AudioLinkBandOverrideSliders.x;
					poiMods.audioLink[1] = _AudioLinkBandOverrideSliders.y;
					poiMods.audioLink[2] = _AudioLinkBandOverrideSliders.z;
					poiMods.audioLink[3] = _AudioLinkBandOverrideSliders.w;
				}
			}
			
			void DebugVisualizer(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				if (_DebugWaveform)
				{
					float waveform = AudioLinkLerpMultiline(ALPASS_WAVEFORM + float2(500. * poiMesh.uv[0].x, 0)).r;
					poiFragData.emission += clamp(1 - 50 * abs(waveform - poiMesh.uv[0].y * 2. + 1), 0, 1);
				}
				if (_DebugDFT)
				{
					poiFragData.emission += AudioLinkLerpMultiline(ALPASS_DFT + uint2(poiMesh.uv[0].x * AUDIOLINK_ETOTALBINS, 0)).rrr;
				}
				if (_DebugBass)
				{
					poiFragData.emission += poiMods.audioLink[0];
				}
				if (_DebugLowMids)
				{
					poiFragData.emission += poiMods.audioLink[1];
				}
				if (_DebugHighMids)
				{
					poiFragData.emission += poiMods.audioLink[2];
				}
				if (_DebugTreble)
				{
					poiFragData.emission += poiMods.audioLink[3];
				}
				if (_DebugCCColors)
				{
					poiFragData.emission += AudioLinkData(ALPASS_CCCOLORS + uint2(3 + 1, 0));
				}
				if (_DebugCCStrip)
				{
					poiFragData.emission += AudioLinkLerp(ALPASS_CCSTRIP + float2(poiMesh.uv[0].x * AUDIOLINK_WIDTH, 0));
				}
				if (_DebugCCLights)
				{
					poiFragData.emission += AudioLinkData(ALPASS_CCLIGHTS + uint2(uint(poiMesh.uv[0].x * 8) + uint(poiMesh.uv[0].y * 16) * 8, 0));
				}
				if (_DebugAutocorrelator)
				{
					poiFragData.emission += saturate(AudioLinkLerp(ALPASS_AUTOCORRELATOR + float2((abs(1. - poiMesh.uv[0].x * 2.)) * AUDIOLINK_WIDTH, 0)).rrr);
				}
				if (_DebugChronotensity)
				{
					poiFragData.emission += (AudioLinkDecodeDataAsUInt(ALPASS_CHRONOTENSITY + uint2(1, 0)) % 1000000) / 1000000.0;
				}
			}
			
			void SetupAudioLink(inout PoiFragData poiFragData, inout PoiMods poiMods, in PoiMesh poiMesh)
			{
				initPoiAudioLink(poiMods);
				DebugVisualizer(poiFragData, poiMesh, poiMods);
				
				if (_AudioLinkCCStripY)
				{
					poiFragData.emission += AudioLinkLerp(ALPASS_CCSTRIP + float2(poiMesh.uv[0].y * AUDIOLINK_WIDTH, 0)).rgb * .5;
				}
			}
			
			#endif
			//endex
			
			//ifex _BSSEnabled!=1
			#ifdef POIBS_ENABLE
			//ifex _BSSBloomfog!=1
			#ifdef POIBS_BLOOMFOG
			inline float4 GetFogCoord(float4 clipPos)
			{
				float4 screenPos = ComputeNonStereoScreenPos(clipPos);
				float2 screenPosNormalized = screenPos.xy / screenPos.w;
				float eyeOffset = (unity_StereoEyeIndex * (_StereoCameraEyeOffset * 2)) + - _StereoCameraEyeOffset;
				return float4(
				((eyeOffset +screenPosNormalized.x) + - 0.5) * _CustomFogTextureToScreenRatio.x + 0.5,
				(screenPosNormalized.y + - 0.5) * _CustomFogTextureToScreenRatio.y + 0.5
				,clipPos.z,clipPos.w);
			}
			
			inline float GetHeightFogIntensity(float3 worldPos, float fogHeightOffset, float fogHeightScale)
			{
				float heightFogIntensity = _CustomFogHeightFogHeight + _CustomFogHeightFogStartY;
				heightFogIntensity = ((worldPos.y * fogHeightScale) + fogHeightOffset) + - heightFogIntensity;
				heightFogIntensity = heightFogIntensity / _CustomFogHeightFogHeight;
				heightFogIntensity = clamp(heightFogIntensity, 0, 1);
				return ((-heightFogIntensity * 2) + 3) * (heightFogIntensity * heightFogIntensity);
			}
			
			inline float GetFogIntensity(float3 distance, float fogStartOffset, float fogScale)
			{
				float fogIntensity = max(dot(distance, distance) + - fogStartOffset, 0);
				fogIntensity = max((fogIntensity * fogScale) + - _CustomFogOffset, 0);
				fogIntensity = 1 / ((fogIntensity * _CustomFogAttenuation) + 1);
				return -fogIntensity;
			}
			#endif
			//endex
			#endif
			//endex
			
			VertexOut vert(
			#ifndef POI_TESSELLATED
			appdata v
			#else
			tessAppData v
			#endif
			)
			{
				UNITY_SETUP_INSTANCE_ID(v);
				VertexOut o;
				PoiInitStruct(VertexOut, o);
				UNITY_TRANSFER_INSTANCE_ID(v, o);
				#ifdef POI_TESSELLATED
				UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v);
				#endif
				UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
				
				//ifex _EnableUDIMDiscardOptions==0
				#ifdef POI_UDIMDISCARD
				UNITY_BRANCH
				if(_UDIMDiscardMode == 0) // Discard Vertices instead of just pixels
				{
					// Branchless (inspired by s-ilent)
					float2 udim = 0;
					// Select UV
					udim += (v.uv0.xy * (_UDIMDiscardUV == 0));
					udim += (v.uv1.xy * (_UDIMDiscardUV == 1));
					udim += (v.uv2.xy * (_UDIMDiscardUV == 2));
					udim += (v.uv3.xy * (_UDIMDiscardUV == 3));
					
					float isDiscarded = 0;
					float4 xMask = float4(  (udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					isDiscarded += (udim.y >= 0 && udim.y < 1) * dot(float4(_UDIMDiscardRow0_0, _UDIMDiscardRow0_1, _UDIMDiscardRow0_2, _UDIMDiscardRow0_3), xMask);
					isDiscarded += (udim.y >= 1 && udim.y < 2) * dot(float4(_UDIMDiscardRow1_0, _UDIMDiscardRow1_1, _UDIMDiscardRow1_2, _UDIMDiscardRow1_3), xMask);
					isDiscarded += (udim.y >= 2 && udim.y < 3) * dot(float4(_UDIMDiscardRow2_0, _UDIMDiscardRow2_1, _UDIMDiscardRow2_2, _UDIMDiscardRow2_3), xMask);
					isDiscarded += (udim.y >= 3 && udim.y < 4) * dot(float4(_UDIMDiscardRow3_0, _UDIMDiscardRow3_1, _UDIMDiscardRow3_2, _UDIMDiscardRow3_3), xMask);
					
					isDiscarded *= any(float4(udim.y >= 0, udim.y < 4, udim.x >= 0, udim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					// Use a threshold so that there's some room for animations to be close to 0, but not exactly 0
					const float threshold = 0.001;
					if(isDiscarded > threshold) // Early Return skips rest of vertex shader
					{
						return (VertexOut)POI_NAN;
					}
				}
				#endif
				//endex
				
				//ifex _VertexManipulationsEnabled==0
				#ifdef AUTO_EXPOSURE
				float4 audioLinkBands = 0;
				float3 ALrotation = 0;
				float3 ALLocalTranslation = 0;
				float3 CTALRotation = 0;
				float3 ALScale = 0;
				float3 ALWorldTranslation = 0;
				float ALHeight = 0;
				float ALRoundingAmount = 0;
				float4 ALSpectrumLocalOffset = float4(0, 0, 0, 0);
				#ifdef POI_AUDIOLINK
				if (AudioLinkIsAvailable() && _VertexAudioLinkEnabled && _AudioLinkAnimToggle)
				{
					audioLinkBands.x = AudioLinkData(ALPASS_AUDIOBASS).r;
					audioLinkBands.y = AudioLinkData(ALPASS_AUDIOLOWMIDS).r;
					audioLinkBands.z = AudioLinkData(ALPASS_AUDIOHIGHMIDS).r;
					audioLinkBands.w = AudioLinkData(ALPASS_AUDIOTREBLE).r;
					
					if (any(_VertexLocalTranslationALMin) || any(_VertexLocalTranslationALMax))
					{
						ALLocalTranslation = lerp(_VertexLocalTranslationALMin, _VertexLocalTranslationALMax, audioLinkBands[_VertexLocalTranslationALBand]);
					}
					if (any(_VertexLocalRotationAL))
					{
						ALrotation = audioLinkBands[_VertexLocalRotationALBand] * _VertexLocalRotationAL;
					}
					if (any(_VertexLocalRotationCTALSpeed))
					{
						CTALRotation.x = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeX, _VertexLocalRotationCTALBandX) * _VertexLocalRotationCTALSpeed.x * 360;
						CTALRotation.y = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeY, _VertexLocalRotationCTALBandY) * _VertexLocalRotationCTALSpeed.y * 360;
						CTALRotation.z = AudioLinkGetChronoTime(_VertexLocalRotationCTALTypeZ, _VertexLocalRotationCTALBandZ) * _VertexLocalRotationCTALSpeed.z * 360;
					}
					if (any(_VertexLocalScaleALMin) || any(_VertexLocalScaleALMax))
					{
						ALScale = lerp(_VertexLocalScaleALMin.xyz + _VertexLocalScaleALMin.w, _VertexLocalScaleALMax.xyz + _VertexLocalScaleALMax.w, audioLinkBands[_VertexLocalScaleALBand]);
					}
					if (any(_VertexWorldTranslationALMin) || any(_VertexWorldTranslationALMax))
					{
						ALWorldTranslation = lerp(_VertexWorldTranslationALMin, _VertexWorldTranslationALMax, audioLinkBands[_VertexWorldTranslationALBand]);
					}
					if (any(_VertexManipulationHeightAL))
					{
						ALHeight = lerp(_VertexManipulationHeightAL.x, _VertexManipulationHeightAL.y, audioLinkBands[_VertexManipulationHeightBand]);
					}
					if (any(_VertexRoundingRangeAL))
					{
						ALRoundingAmount = lerp(_VertexRoundingRangeAL.x, _VertexRoundingRangeAL.y, audioLinkBands[_VertexRoundingRangeBand]);
					}
					if (_VertexSpectrumMotion)
					{
						ALSpectrumLocalOffset.xyz = lerp(_VertexSpectrumOffsetMin.xyz, _VertexSpectrumOffsetMax.xyz, AudioLinkLerpMultiline(ALPASS_DFT + float2(vertexUV(v, _VertexSpectrumUV)[_VertexSpectrumUVDirection] * AUDIOLINK_ETOTALBINS, 0.)));
					}
				}
				#endif
				
				// Local Transformation
				float4 rotation = float4(_VertexManipulationLocalRotation.xyz + float3(180, 0, 0) + _VertexManipulationLocalRotationSpeed * _Time.x + ALrotation + CTALRotation, _VertexManipulationLocalRotation.w);
				v.normal = rotate_with_quaternion(v.normal, rotation.xyz);
				v.tangent.xyz = rotate_with_quaternion(v.tangent.xyz, rotation.xyz);
				v.vertex = transform(v.vertex, _VertexManipulationLocalTranslation + float4(ALLocalTranslation, 0) + ALSpectrumLocalOffset, rotation, _VertexManipulationLocalScale + float4(ALScale, 0));
				o.normal = UnityObjectToWorldNormal(v.normal);
				
				#if defined(PROP_VERTEXMANIPULATIONHEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float3 heightOffset = (tex2Dlod(_VertexManipulationHeightMask, float4(poiUV(vertexUV(v, _VertexManipulationHeightMaskUV), _VertexManipulationHeightMask_ST) + _VertexManipulationHeightMaskPan * _Time.x, 0, 0))[_VertexManipulationHeightMaskChannel] - _VertexManipulationHeightBias) * (_VertexManipulationHeight + ALHeight) * o.normal;
				#else
				float3 heightOffset = (_VertexManipulationHeight + ALHeight) * o.normal;
				#endif
				
				if (_VertexBarrelMode)
				{
					v.vertex.xz = lerp(v.vertex.xz, normalize(v.vertex.xz) * _VertexBarrelWidth + v.vertex.xz * _VertexBarrelHeight, _VertexBarrelAlpha);
				}
				
				if (_VertexSphereMode)
				{
					v.vertex.xyz = lerp(v.vertex.xyz, normalize(v.vertex.xyz + _VertexSphereCenter.xyz) * _VertexSphereRadius + v.vertex.xyz * _VertexSphereHeight, _VertexSphereAlpha);
				}
				
				if (_VertexTornadoMode)
				{
					v.vertex.xz = lerp(v.vertex.xz, float3(v.vertex.xz + float2(cos(_Time.y * _VertexTornadoSpeed + v.vertex.y * _VertexTornadoIntensity) * _VertexTornadoRadius, sin(_Time.y * _VertexTornadoSpeed + v.vertex.y * _VertexTornadoIntensity) * _VertexTornadoRadius), v.vertex.y), smoothstep(_VertexTornadoBaseHeight, _VertexTornadoTopHeight, v.vertex.y));
				}
				
				v.vertex.xyz += mul(unity_WorldToObject, _VertexManipulationWorldTranslation.xyz + ALWorldTranslation + heightOffset).xyz;
				
				// rounding
				UNITY_BRANCH
				if (_VertexRoundingEnabled)
				{
					float divisionAmount = max(_VertexRoundingDivision + ALRoundingAmount, 0.0000001);
					if (_VertexRoundingSpace == 0)
					{
						float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
						float3 worldRoundPosition = (ceil(worldPos.xyz / divisionAmount) * divisionAmount) - divisionAmount * .5;
						v.vertex = mul(unity_WorldToObject, float4(worldRoundPosition, worldPos.w));
					}
					else if (_VertexRoundingSpace == 1)
					{
						v.vertex.xyz = (ceil(v.vertex.xyz / divisionAmount) * divisionAmount) - divisionAmount * .5;
					}
				}
				#endif
				//endex
				
				//ifex _EnableDissolve==0
				#ifdef DISTORT
				UNITY_BRANCH
				if (_UVTileDissolveEnabled && _UVTileDissolveDiscardAtMax)
				{
					// Branchless (inspired by s-ilent)
					float2 dissolveUdim = 0;
					// Select UV
					dissolveUdim += (v.uv0.xy * (_UVTileDissolveUV == 0));
					dissolveUdim += (v.uv1.xy * (_UVTileDissolveUV == 1));
					dissolveUdim += (v.uv2.xy * (_UVTileDissolveUV == 2));
					dissolveUdim += (v.uv3.xy * (_UVTileDissolveUV == 3));
					
					float isDiscardedFromDissolve = 0;
					float4 xMaskDissolve = float4((dissolveUdim.x >= 0 && dissolveUdim.x < 1),
					(dissolveUdim.x >= 1 && dissolveUdim.x < 2),
					(dissolveUdim.x >= 2 && dissolveUdim.x < 3),
					(dissolveUdim.x >= 3 && dissolveUdim.x < 4));
					
					isDiscardedFromDissolve += (dissolveUdim.y >= 0 && dissolveUdim.y < 1) * dot(float4(_UVTileDissolveAlpha_Row0_0, _UVTileDissolveAlpha_Row0_1, _UVTileDissolveAlpha_Row0_2, _UVTileDissolveAlpha_Row0_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 1 && dissolveUdim.y < 2) * dot(float4(_UVTileDissolveAlpha_Row1_0, _UVTileDissolveAlpha_Row1_1, _UVTileDissolveAlpha_Row1_2, _UVTileDissolveAlpha_Row1_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 2 && dissolveUdim.y < 3) * dot(float4(_UVTileDissolveAlpha_Row2_0, _UVTileDissolveAlpha_Row2_1, _UVTileDissolveAlpha_Row2_2, _UVTileDissolveAlpha_Row2_3), xMaskDissolve);
					isDiscardedFromDissolve += (dissolveUdim.y >= 3 && dissolveUdim.y < 4) * dot(float4(_UVTileDissolveAlpha_Row3_0, _UVTileDissolveAlpha_Row3_1, _UVTileDissolveAlpha_Row3_2, _UVTileDissolveAlpha_Row3_3), xMaskDissolve);
					
					isDiscardedFromDissolve *= any(float4(dissolveUdim.y >= 0, dissolveUdim.y < 4, dissolveUdim.x >= 0, dissolveUdim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					// Use a threshold so that there's some room for animations to be close to 1, but not exactly 1
					const float threshold = 0.999;
					if (isDiscardedFromDissolve > threshold) // Early Return skips rest of vertex shader
					
					{
						return (VertexOut)POI_NAN;
					}
				}
				#endif
				//endex
				
				//ifex _EnableMirrorOptions==0
				#ifdef POI_MIRROR
				float notVisible = 0;
				
				if (_VisibilityMode == 1) // VRC
				
				{
					float mirrorMode = VRCMirrorMode();
					float cameraMode = VRCCameraMode();
					
					notVisible += (!_VisibilityVRCRegular && ((mirrorMode == 0) && (cameraMode == 0)));
					notVisible += (!_VisibilityVRCMirrorVR && (mirrorMode == 1));
					notVisible += (!_VisibilityVRCMirrorDesktop && (mirrorMode == 2));
					notVisible += (!_VisibilityVRCCameraVR && (cameraMode == 1));
					notVisible += (!_VisibilityVRCCameraDesktop && (cameraMode == 2));
					notVisible += (!_VisibilityVRCCameraScreenshot && (cameraMode == 3));
				}
				else if (_Mirror != 0) // Generic (CVR, etc)
				
				{
					notVisible += (_Mirror == 1) ^ IsInMirror();
				}
				
				if (notVisible) // Early Return skips rest of vertex shader
				
				{
					return (VertexOut)POI_NAN;
				}
				#endif
				//endex
				
				o.normal = UnityObjectToWorldNormal(v.normal);
				o.tangent.xyz = UnityObjectToWorldDir(v.tangent);
				o.tangent.w = v.tangent.w;
				o.vertexColor = v.color;
				
				o.uv[0] = float4(v.uv0.xy, v.uv1.xy);
				o.uv[1] = float4(v.uv2.xy, v.uv3.xy);
				
				#if defined(LIGHTMAP_ON)
				o.lightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
				#endif
				#ifdef DYNAMICLIGHTMAP_ON
				o.lightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
				#endif
				
				o.localPos = v.vertex;
				o.worldPos = mul(unity_ObjectToWorld, o.localPos);
				
				float3 localOffset = float3(0, 0, 0);
				float3 worldOffset = float3(0, 0, 0);
				
				//ifex _EnableOutlines!=1
				#ifdef POI_PASS_OUTLINE
				float outlineMask = tex2Dlod(_OutlineMask, float4(poiUV(vertexUV(v, _OutlineMaskUV), _OutlineMask_ST) + _Time.x * _OutlineMaskPan, 0, 0))[_OutlineMaskChannel];
				
				//UNITY_BRANCH
				if (_OutlineVertexColorMask > 0)
				{
					outlineMask *= lerp(1, v.color[_OutlineVertexColorMask - 1], _OutlineVertexColorMaskStrength);
				}
				
				float3 outlineNormal = _OutlineSpace ? o.normal : v.normal;
				//UNITY_BRANCH
				if (_OutlineUseVertexColorNormals)
				{
					float3 outlineTangent;
					float3 outlineBinormal;
					if (_OutlineSpace) // 0 Local, 1 World
					
					{
						outlineTangent = o.tangent;
						outlineBinormal = cross(o.normal, o.tangent) * (v.tangent.w * unity_WorldTransformParams.w);
					}
					else
					{
						outlineTangent = v.tangent.xyz;
						outlineBinormal = normalize(cross(outlineNormal, outlineTangent)) * (v.tangent.w * length(outlineNormal));
					}
					float3 outlineVectorTS = v.color.rgb * 2.0 - 1.0;
					outlineNormal = outlineVectorTS.x * outlineTangent + outlineVectorTS.y * outlineBinormal + outlineVectorTS.z * outlineNormal;
				}
				
				float offsetMultiplier = 1;
				float distanceOffset = 1;
				//UNITY_BRANCH
				if (_OutlineFixedSize)
				{
					distanceOffset *= lerp(1.0, clamp((distance(_WorldSpaceCameraPos, mul(unity_ObjectToWorld, o.localPos).xyz)), 0.0f, _OutlinesMaxDistance), _OutlineFixWidth);
				}
				
				float lineWidth = _LineWidth;
				#ifdef POI_AUDIOLINK
				// Due to PoiMods.audioLink being frag only I'll just
				// recreate what it does here for this vertex function
				//UNITY_BRANCH
				if (_AudioLinkAnimToggle)
				{
					if (AudioLinkIsAvailable())
					{
						lineWidth += lerp(_AudioLinkOutlineSize.x, _AudioLinkOutlineSize.y, AudioLinkData(uint2(0, _AudioLinkOutlineSizeBand)));
					}
				}
				#endif
				
				float3 offset = outlineNormal * (lineWidth * _EnableOutlines / 100) * outlineMask * distanceOffset;
				
				//UNITY_BRANCH
				if (_OutlineExpansionMode == 2)
				{
					float3 lightDirection = normalize(_WorldSpaceLightPos0 + unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz);
					offsetMultiplier = saturate(dot(lightDirection, outlineNormal));
					offset *= offsetMultiplier;
					offset *= distanceOffset;
				}
				else if (_OutlineExpansionMode == 3)
				{
					float3 viewNormal = mul((float3x3)UNITY_MATRIX_V, outlineNormal);
					offsetMultiplier = saturate(dot(viewNormal.xy, normalize(_OutlinePersonaDirection.xy)));
					
					offset *= offsetMultiplier;
					offset *= distanceOffset;
				}
				else if (_OutlineExpansionMode == 4)
				{
					offset = mul((float3x3)transpose(UNITY_MATRIX_V), _OutlineDropShadowOffset);
					offset *= distanceOffset;
				}
				if (_OutlineSpace == 0)
				{
					localOffset += offset;
					worldOffset += mul(unity_ObjectToWorld, offset);
				}
				else
				{
					localOffset += mul(unity_WorldToObject, offset);
					worldOffset += offset;
				}
				#endif
				//endex
				
				//ifex _VertexGlitchingEnabled==0
				#if defined(POI_VERTEX_GLITCHING)
				
				bool canGlitch = true;
				if (_VertexGlitchMirrorEnable && _VertexGlitchMirror > 0)
				{
					bool inMirror = IsInMirror();
					if (_VertexGlitchMirror == 1 && !inMirror)	canGlitch = false;
					if (_VertexGlitchMirror == 2 && inMirror)	canGlitch = false;
				}
				if (canGlitch)
				{
					float3 forward = getCameraPosition() - mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
					forward.y = 0;
					forward = normalize(forward);
					float3 glitchDirection = normalize(cross(float3(0, 1, 0), forward));
					
					float glitchAmount = 0;
					
					#if defined(POI_VERTEX_GLITCHING_TEXTURE)
					// if(_VertexGlitchingUseTexture)
					// {
					float uvl = o.worldPos.y * _VertexGlitchDensity + _Time.x * _VertexGlitchMapPanSpeed;
					float uvr = o.worldPos.y * _VertexGlitchDensity - _Time.x * _VertexGlitchMapPanSpeed;
					
					float3 glitchTextureL = 1;
					float3 glitchTextureR = 1;
					
					#if defined(POI_VERTEX_GLITCHING_TEXTURE) || !defined(OPTIMIZER_ENABLED)
					glitchTextureL = tex2Dlod(_VertexGlitchMap, float4(uvl, uvl, 0, 0)).rgb;
					glitchTextureR = tex2Dlod(_VertexGlitchMap, float4(uvr, uvr, 0, 0)).rgb;
					#endif
					
					glitchAmount += (glitchTextureL.r - 0.5) * 2;
					glitchAmount += - (glitchTextureR.r - 0.5) * 2;
					
					glitchAmount += (glitchTextureL.g - 0.5) * 2;
					glitchAmount += - (glitchTextureR.b - 0.5) * 2;
					// } else {
					#else
					glitchAmount += frac(sin(dot(_Time.xy + o.worldPos.y, float2(12.9898, 78.233))) * 43758.5453123) * 2 - 1;
					// }
					#endif
					
					float time = _Time.y * _VertexGlitchFrequency;
					
					float randomGlitch = (sin(time) + sin(2.2 * time + 5.52) + sin(2.9 * time + 0.93) + sin(4.6 * time + 8.94)) / 4;
					float3 glitchOffset = 0;
					
					#ifdef POI_AUDIOLINK
					if (AudioLinkIsAvailable() && _VertexGlitchingAudioLinkEnabled)
					{
						// float4 audioLinkData = AudioLinkData(ALPASS_AUDIOBASS);
						
						float audioIntensity =
						AudioLinkData(ALPASS_AUDIOBASS).r 		* (_VertexGlitchingAudioLinkBand == 0) +
						AudioLinkData(ALPASS_AUDIOLOWMIDS).r 	* (_VertexGlitchingAudioLinkBand == 1) +
						AudioLinkData(ALPASS_AUDIOHIGHMIDS).r	* (_VertexGlitchingAudioLinkBand == 2) +
						AudioLinkData(ALPASS_AUDIOTREBLE).r 	* (_VertexGlitchingAudioLinkBand == 3) +
						AudioLinkData(ALPASS_FILTEREDVU_INTENSITY).r * (_VertexGlitchingAudioLinkBand == 4);
						
						if(_VertexGlitchingAudiolinkOverride)
						{
							glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
							// glitchOffset += glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
						} else {
							glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
							glitchOffset += glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * audioIntensity;
						}
					} else {
						glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
					}
					#else
					glitchOffset = glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
					#endif
					
					localOffset += glitchOffset;
					worldOffset += mul(unity_ObjectToWorld, glitchOffset);
				}
				#endif
				//endex
				
				o.localPos.rgb += localOffset;
				o.worldPos.rgb += worldOffset;
				
				//ifex _EnableDepthBulge==0
				#if defined(POI_DEPTHBULGE) && (defined(POI_PASS_BASE) || defined(POI_PASS_ADD))
				applyDepthBulgeFX(o);
				#endif
				//endex
				
				//ifex _BSSEnabled!=1
				#ifdef POIBS_ENABLE
				//ifex _BSSBloomfog!=1
				#ifdef POIBS_BLOOMFOG
				o.fogCoord = GetFogCoord(UnityObjectToClipPos(v.vertex));
				o.worldPos = mul(unity_ObjectToWorld, v.vertex);
				#endif
				//endex
				#endif
				//endex
				
				o.pos = UnityObjectToClipPos(o.localPos);
				
				#ifdef POI_PASS_OUTLINE
				#if defined(UNITY_REVERSED_Z)
				//DX
				o.pos.z += _Offset_Z * - 0.01;
				#else
				//OpenGL
				o.pos.z += _Offset_Z * 0.01;
				#endif
				#endif
				//o.grabPos = ComputeGrabScreenPos(o.pos);
				
				#ifndef FORWARD_META_PASS
				#if !defined(UNITY_PASS_SHADOWCASTER)
				UNITY_TRANSFER_SHADOW(o, o.uv[0].xy);
				#else
				v.vertex.xyz = o.localPos.xyz;
				TRANSFER_SHADOW_CASTER_NOPOS(o, o.pos);
				#endif
				#endif
				
				UNITY_TRANSFER_FOG(o, o.pos);
				
				if (_RenderingReduceClipDistance)
				{
					if (o.pos.w < _ProjectionParams.y * 1.01 && o.pos.w > 0)
					{
						#if defined(UNITY_REVERSED_Z) // DirectX
						o.pos.z = o.pos.z * 0.0001 + o.pos.w * 0.999;
						#else // OpenGL
						o.pos.z = o.pos.z * 0.0001 - o.pos.w * 0.999;
						#endif
					}
				}
				
				#ifdef POI_PASS_META
				o.pos = UnityMetaVertexPosition(v.vertex, v.uv1.xy, v.uv2.xy, unity_LightmapST, unity_DynamicLightmapST);
				#endif
				
				return o;
			}
			
			#if defined(_STOCHASTICMODE_DELIOT_HEITZ)
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, uv) : POI2D_SAMPLER(tex, texSampler, uv))
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan)) : POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (useStochastic ? DeliotHeitzSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), dx, dy) : POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			#if defined(_STOCHASTICMODE_HEXTILE)
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, uv, false) : POI2D_SAMPLER(tex, texSampler, uv))
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), false) : POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (useStochastic ? HextileSampleTexture(tex, sampler##texSampler, POI_PAN_UV(uv, pan), false, dx, dy) : POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			
			#ifndef POI2D_SAMPLER_STOCHASTIC
			#define POI2D_SAMPLER_STOCHASTIC(tex, texSampler, uv, useStochastic) (POI2D_SAMPLER(tex, texSampler, uv))
			#endif
			#ifndef POI2D_SAMPLER_PAN_STOCHASTIC
			#define POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, uv, pan, useStochastic) (POI2D_SAMPLER_PAN(tex, texSampler, uv, pan))
			#endif
			#ifndef POI2D_SAMPLER_PANGRAD_STOCHASTIC
			#define POI2D_SAMPLER_PANGRAD_STOCHASTIC(tex, texSampler, uv, pan, dx, dy, useStochastic) (POI2D_SAMPLER_PANGRAD(tex, texSampler, uv, pan, dx, dy))
			#endif
			
			// When using, properties won't properly lock at optimize time; needs macro evaluation implemented
			// #define POI2D_SAMPLER_STOCHASTIC_INLINED(tex, texSampler) (POI2D_SAMPLER_STOCHASTIC(tex, texSampler, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Stochastic))
			// #define POI2D_SAMPLER_PAN_STOCHASTIC_INLINED(tex, texSampler) (POI2D_SAMPLER_PAN_STOCHASTIC(tex, texSampler, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan, tex##Stochastic))
			
			// #define POI2D_MAINTEX_SAMPLER_STOCHASTIC_INLINED(tex) (POI2D_SAMPLER_STOCHASTIC(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Stochastic))
			// #define POI2D_MAINTEX_SAMPLER_PAN_STOCHASTIC_INLINED(tex) (POI2D_SAMPLER_PAN_STOCHASTIC(tex, _MainTex, poiUV(poiMesh.uv[tex##UV], tex##_ST), tex##Pan, tex##Stochastic))
			
			// Deliot, Heitz 2019 - Fast, but non-histogram-preserving (ends up looking a bit blurry and lower contrast)
			// https://eheitzresearch.wordpress.com/738-2/
			
			// Classic Magic Numbers fracsin
			#if !defined(_STOCHASTICMODE_NONE)
			float2 StochasticHash2D2D (float2 s)
			{
				return frac(sin(glsl_mod(float2(dot(s, float2(127.1,311.7)), dot(s, float2(269.5,183.3))), 3.14159)) * 43758.5453);
			}
			#endif
			
			#if defined(_STOCHASTICMODE_DELIOT_HEITZ)
			// UV Offsets and blend weights
			// UVBW[0...2].xy = UV Offsets
			// UVBW[0...2].z = Blend Weights
			float3x3 DeliotHeitzStochasticUVBW(float2 uv)
			{
				// UV transformed into triangular grid space with UV scaled by approximation of 2*sqrt(3)
				const float2x2 stochasticSkewedGrid = float2x2(1.0, -0.57735027, 0.0, 1.15470054);
				float2 skewUV = mul(stochasticSkewedGrid, uv * 3.4641 * _StochasticDeliotHeitzDensity);
				
				// Vertex IDs and barycentric coords
				float2 vxID = floor(skewUV);
				float3 bary = float3(frac(skewUV), 0);
				bary.z = 1.0 - bary.x - bary.y;
				
				float3x3 pos = float3x3(
				float3(vxID, 				bary.z),
				float3(vxID + float2(0, 1), bary.y),
				float3(vxID + float2(1, 0), bary.x)
				);
				
				float3x3 neg = float3x3(
				float3(vxID + float2(1, 1), 	 -bary.z),
				float3(vxID + float2(1, 0), 1.0 - bary.y),
				float3(vxID + float2(0, 1), 1.0 - bary.x)
				);
				
				return (bary.z > 0) ? pos : neg;
			}
			
			float4 DeliotHeitzSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, float2 dx, float2 dy)
			{
				// UVBW[0...2].xy = UV Offsets
				// UVBW[0...2].z = Blend Weights
				float3x3 UVBW = DeliotHeitzStochasticUVBW(uv);
				
				//blend samples with calculated weights
				return 	mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[0].xy), dx, dy), UVBW[0].z) +
				mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[1].xy), dx, dy), UVBW[1].z) +
				mul(tex.SampleGrad(texSampler, uv + StochasticHash2D2D(UVBW[2].xy), dx, dy), UVBW[2].z) ;
			}
			
			float4 DeliotHeitzSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv)
			{
				float2 dx = ddx(uv), dy = ddy(uv);
				return DeliotHeitzSampleTexture(tex, texSampler, uv, dx, dy);
			}
			#endif // defined(_STOCHASTICMODE_DELIOT_HEITZ)
			
			#if defined(_STOCHASTICMODE_HEXTILE)
			// HexTiling: Slower, but histogram-preserving
			// SPDX-License-Idenfitier: MIT
			// Copyright (c) 2022 mmikk
			// https://github.com/mmikk/hextile-demo
			float2 HextileMakeCenUV(float2 vertex)
			{
				// 0.288675 ~= 1/(2*sqrt(3))
				const float2x2 stochasticInverseSkewedGrid = float2x2(1.0, 0.5, 0.0, 1.0/1.15470054);
				return mul(stochasticInverseSkewedGrid, vertex) * 0.288675;
			}
			
			float2x2 HextileLoadRot2x2(float2 idx, float rotStrength)
			{
				float angle = abs(idx.x * idx.y) + abs(idx.x + idx.y) + PI;
				
				// remap to +/-pi
				angle = glsl_mod(angle, 2 * PI);
				if(angle < 0)  angle += 2 * PI;
				if(angle > PI) angle -= 2 * PI;
				
				angle *= rotStrength;
				
				float cs = cos(angle), si = sin(angle);
				return float2x2(cs, -si, si, cs);
			}
			
			// UV Offsets and base blend weights
			// UVBWR[0...2].xy = UV Offsets
			// UVBWR[0...2].zw = rotation costh/sinth -> reconstruct rotation matrix with float2x2(UVBWR[n].z, -UVBWR[n].w, UVBWR[n].w, UVBWR[n].z)
			// UVBWR[3].xyz = Blend Weights (w unused) - needs luminance weighting
			float4x4 HextileUVBWR(float2 uv)
			{
				// Create Triangle Grid
				// Skew input space into simplex triangle grid (3.4641 ~= 2*sqrt(3))
				const float2x2 stochasticSkewedGrid = float2x2(1.0, -0.57735027, 0.0, 1.15470054);
				float2 skewedCoord = mul(stochasticSkewedGrid, uv * 3.4641 * _StochasticHexGridDensity);
				
				float2 baseId = float2(floor(skewedCoord));
				float3 temp = float3(frac(skewedCoord), 0);
				temp.z = 1 - temp.x - temp.y;
				
				float s = step(0.0, -temp.z);
				float s2 = 2 * s - 1;
				
				float3 weights = float3(-temp.z * s2, s - temp.y * s2, s - temp.x * s2);
				
				float2 vertex0 = baseId + float2(s, s);
				float2 vertex1 = baseId + float2(s, 1 - s);
				float2 vertex2 = baseId + float2(1 - s, s);
				
				float2 cen0 = HextileMakeCenUV(vertex0), cen1 = HextileMakeCenUV(vertex1), cen2 = HextileMakeCenUV(vertex2);
				float2x2 rot0 = float2x2(1, 0, 0, 1), rot1 = float2x2(1, 0, 0, 1), rot2 = float2x2(1, 0, 0, 1);
				
				if(_StochasticHexRotationStrength > 0)
				{
					rot0 = HextileLoadRot2x2(vertex0, _StochasticHexRotationStrength);
					rot1 = HextileLoadRot2x2(vertex1, _StochasticHexRotationStrength);
					rot2 = HextileLoadRot2x2(vertex2, _StochasticHexRotationStrength);
				}
				
				return float4x4(
				float4(mul(uv - cen0, rot0) + cen0 + StochasticHash2D2D(vertex0), rot0[0].x, -rot0[0].y),
				float4(mul(uv - cen1, rot1) + cen1 + StochasticHash2D2D(vertex1), rot1[0].x, -rot1[0].y),
				float4(mul(uv - cen2, rot2) + cen2 + StochasticHash2D2D(vertex2), rot2[0].x, -rot2[0].y),
				float4(weights, 0)
				);
			}
			
			float4 HextileSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, bool isNormalMap, float2 dUVdx, float2 dUVdy)
			{
				// For some reason doing this instead of just calculating it directly prevents it from \
				// breaking after a certain number of textures use it. I don't understand why yet
				float4x4 UVBWR = HextileUVBWR(uv);
				
				// 2D Rotation Matrices for dUVdx/dy
				// Not sure if this constant folds during compiling when rot is locked at 0, so force it
				float2x2 rot0 = float2x2(1, 0, 0, 1), rot1 = float2x2(1, 0, 0, 1), rot2 = float2x2(1, 0, 0, 1);
				
				if(_StochasticHexRotationStrength > 0)
				{
					rot0 = float2x2(UVBWR[0].z, -UVBWR[0].w, UVBWR[0].w, UVBWR[0].z);
					rot1 = float2x2(UVBWR[1].z, -UVBWR[1].w, UVBWR[1].w, UVBWR[1].z);
					rot2 = float2x2(UVBWR[2].z, -UVBWR[2].w, UVBWR[2].w, UVBWR[2].z);
				}
				
				// Weights
				float3 W = UVBWR[3].xyz;
				
				// Sample texture
				// float3x4 c = float3x4(
				// 	tex.SampleGrad(texSampler, UVBWR[0].xy, mul(dUVdx, rot0), mul(dUVdy, rot0)),
				// 	tex.SampleGrad(texSampler, UVBWR[1].xy, mul(dUVdx, rot1), mul(dUVdy, rot1)),
				// 	tex.SampleGrad(texSampler, UVBWR[2].xy, mul(dUVdx, rot2), mul(dUVdy, rot2))
				// );
				
				float4 c0 = tex.SampleGrad(texSampler, UVBWR[0].xy, mul(dUVdx, rot0), mul(dUVdy, rot0));
				float4 c1 = tex.SampleGrad(texSampler, UVBWR[1].xy, mul(dUVdx, rot1), mul(dUVdy, rot1));
				float4 c2 = tex.SampleGrad(texSampler, UVBWR[2].xy, mul(dUVdx, rot2), mul(dUVdy, rot2));
				
				// Blend samples using luminance
				// This is technically incorrect for normal maps, but produces very similar
				// results to blending using normal map gradients (steepness)
				const float3 Lw = float3(0.299, 0.587, 0.114);
				float3 Dw = float3(dot(c0.xyz, Lw), dot(c1.xyz, Lw), dot(c2.xyz, Lw));
				
				Dw = lerp(1.0, Dw, _StochasticHexFallOffContrast);
				W = Dw * pow(W, _StochasticHexFallOffPower);
				// In the original hextiling there's a Gain3 step here, but it seems to slow things down \
				// and cause the UVs to break, so I've omitted it. Looks fine without
				
				W /= (W.x + W.y + W.z);
				return W.x * c0 + W.y * c1 + W.z * c2;
			}
			
			float4 HextileSampleTexture(Texture2D tex, SamplerState texSampler, float2 uv, bool isNormalMap)
			{
				return HextileSampleTexture(tex, texSampler, uv, isNormalMap, ddx(uv), ddy(uv));
			}
			#endif // defined(_STOCHASTICMODE_HEXTILE)
			
			void applyAlphaOptions(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiCam poiCam, in PoiMods poiMods)
			{
				poiFragData.alpha = saturate(poiFragData.alpha + _AlphaMod);
				
				if (_AlphaGlobalMask > 0)
				{
					poiFragData.alpha = maskBlend(poiFragData.alpha, poiMods.globalMask[_AlphaGlobalMask - 1], _AlphaGlobalMaskBlendType);
				}
				
				//ifex _AlphaDistanceFade==0 && isNotAnimated(_AlphaDistanceFade)
				if (_AlphaDistanceFade)
				{
					float3 position = _AlphaDistanceFadeType ? poiMesh.worldPos : poiMesh.objectPosition;
					float distanceFadeMultiplier = lerp(_AlphaDistanceFadeMinAlpha, _AlphaDistanceFadeMaxAlpha, smoothstep(_AlphaDistanceFadeMin, _AlphaDistanceFadeMax, distance(position, poiCam.worldPos)));
					if (_AlphaDistanceFadeGlobalMask > 0)
					{
						distanceFadeMultiplier = lerp(1, distanceFadeMultiplier, poiMods.globalMask[_AlphaDistanceFadeGlobalMask - 1]);
					}
					poiFragData.alpha *= distanceFadeMultiplier;
				}
				//endex
				
				//ifex _AlphaFresnel==0 && isNotAnimated(_AlphaFresnel)
				if (_AlphaFresnel)
				{
					float holoRim = saturate(1 - smoothstep(min(_AlphaFresnelSharpness, _AlphaFresnelWidth), _AlphaFresnelWidth, (poiCam.vDotN)));
					holoRim = abs(lerp(1, holoRim, _AlphaFresnelAlpha));
					holoRim = _AlphaFresnelInvert ? 1 - holoRim : holoRim;
					if (_AlphaFresnelGlobalMask > 0)
					{
						holoRim = lerp(1, holoRim, poiMods.globalMask[_AlphaFresnelGlobalMask - 1]);
					}
					poiFragData.alpha *= holoRim;
				}
				//endex
				
				//ifex _AlphaAngular==0 && isNotAnimated(_AlphaAngular)
				if (_AlphaAngular)
				{
					half cameraAngleMin = _CameraAngleMin / 180;
					half cameraAngleMax = _CameraAngleMax / 180;
					half modelAngleMin = _ModelAngleMin / 180;
					half modelAngleMax = _ModelAngleMax / 180;
					float3 pos = _AngleCompareTo == 0 ? poiMesh.objectPosition : poiMesh.worldPos;
					half3 cameraToModelDirection = normalize(pos - getCameraPosition());
					half3 modelForwardDirection = normalize(mul(unity_ObjectToWorld, normalize(_AngleForwardDirection.rgb)));
					half cameraLookAtModel = remapClamped(cameraAngleMax, cameraAngleMin, .5 * dot(cameraToModelDirection, getCameraForward()) + .5);
					half modelLookAtCamera = remapClamped(modelAngleMax, modelAngleMin, .5 * dot(-cameraToModelDirection, modelForwardDirection) + .5);
					float angularAlphaMod = 1;
					if (_AngleType == 0)
					{
						angularAlphaMod = max(cameraLookAtModel, _AngleMinAlpha);
					}
					else if (_AngleType == 1)
					{
						angularAlphaMod = max(modelLookAtCamera, _AngleMinAlpha);
					}
					else if (_AngleType == 2)
					{
						angularAlphaMod = max(cameraLookAtModel * modelLookAtCamera, _AngleMinAlpha);
					}
					if (_AlphaAngularGlobalMask > 0)
					{
						angularAlphaMod = lerp(1, angularAlphaMod, poiMods.globalMask[_AlphaAngularGlobalMask - 1]);
					}
					poiFragData.alpha *= angularAlphaMod;
				}
				//endex
				
				//ifex _AlphaAudioLinkEnabled==0 && isNotAnimated(_AlphaAudioLinkEnabled)
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable && _AlphaAudioLinkEnabled)
				{
					poiFragData.alpha = saturate(poiFragData.alpha + lerp(_AlphaAudioLinkAddRange.x, _AlphaAudioLinkAddRange.y, poiMods.audioLink[_AlphaAudioLinkAddBand]));
				}
				#endif
				//endex
				
			}
			
			//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
			inline half Dither8x8Bayer(int x, int y)
			{
				// Premultiplied by 1/64
				const half dither[ 64 ] = {
					0.015625, 0.765625, 0.203125, 0.953125, 0.06250, 0.81250, 0.25000, 1.00000,
					0.515625, 0.265625, 0.703125, 0.453125, 0.56250, 0.31250, 0.75000, 0.50000,
					0.140625, 0.890625, 0.078125, 0.828125, 0.18750, 0.93750, 0.12500, 0.87500,
					0.640625, 0.390625, 0.578125, 0.328125, 0.68750, 0.43750, 0.62500, 0.37500,
					0.046875, 0.796875, 0.234375, 0.984375, 0.03125, 0.78125, 0.21875, 0.96875,
					0.546875, 0.296875, 0.734375, 0.484375, 0.53125, 0.28125, 0.71875, 0.46875,
					0.171875, 0.921875, 0.109375, 0.859375, 0.15625, 0.90625, 0.09375, 0.84375,
					0.671875, 0.421875, 0.609375, 0.359375, 0.65625, 0.40625, 0.59375, 0.34375
				};
				int r = y * 8 + x;
				return dither[r];
			}
			
			half calcDither(half2 grabPos)
			{
				return Dither8x8Bayer(glsl_mod(grabPos.x, 8), glsl_mod(grabPos.y, 8));
			}
			
			void applyDithering(inout PoiFragData poiFragData, in PoiCam poiCam)
			{
				if (_AlphaDithering)
				{
					float dither = calcDither(poiCam.posScreenPixels) - _AlphaDitherBias;
					poiFragData.alpha = saturate(poiFragData.alpha - (dither * (1 - poiFragData.alpha) * _AlphaDitherGradient));
				}
			}
			//endex
			
			//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
			void ApplyAlphaToCoverage(inout PoiFragData poiFragData, in PoiMesh poiMesh)
			{
				// Force Model Opacity to 1 if desired
				UNITY_BRANCH
				if (_Mode == 1)
				{
					UNITY_BRANCH
					if (_AlphaSharpenedA2C && _AlphaToCoverage)
					{
						// rescale alpha by mip level
						poiFragData.alpha *= 1 + max(0, CalcMipLevel(poiMesh.uv[0] * _MainTex_TexelSize.zw)) * _AlphaMipScale;
						// rescale alpha by partial derivative
						poiFragData.alpha = (poiFragData.alpha - _Cutoff) / max(fwidth(poiFragData.alpha), 0.0001) + _Cutoff;
						poiFragData.alpha = saturate(poiFragData.alpha);
					}
				}
			}
			//endex
			
			//ifex _GlobalMaskTexturesEnable==0
			#ifdef POI_GLOBALMASK_TEXTURES
			void ApplyGlobalMaskTextures(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				#if defined(PROP_GLOBALMASKTEXTURE0) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol0 = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0_ST), _GlobalMaskTexture0Pan);
				if (_GlobalMaskTexture0Split)
				{
					poiMods.globalMask[0] = gmcol0.r;
					poiMods.globalMask[1] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_G), _GlobalMaskTexture0SplitPan_G).g;
					poiMods.globalMask[2] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_B), _GlobalMaskTexture0SplitPan_B).b;
					poiMods.globalMask[3] = POI2D_SAMPLER_PAN(_GlobalMaskTexture0, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture0UV], _GlobalMaskTexture0SplitTilingOffset_A), _GlobalMaskTexture0SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[0] = gmcol0[0];
					poiMods.globalMask[1] = gmcol0[1];
					poiMods.globalMask[2] = gmcol0[2];
					poiMods.globalMask[3] = gmcol0[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE1) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol1 = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1_ST), _GlobalMaskTexture1Pan);
				if (_GlobalMaskTexture1Split)
				{
					poiMods.globalMask[4] = gmcol1.r;
					poiMods.globalMask[5] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_G), _GlobalMaskTexture1SplitPan_G).g;
					poiMods.globalMask[6] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_B), _GlobalMaskTexture1SplitPan_B).b;
					poiMods.globalMask[7] = POI2D_SAMPLER_PAN(_GlobalMaskTexture1, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture1UV], _GlobalMaskTexture1SplitTilingOffset_A), _GlobalMaskTexture1SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[4] = gmcol1[0];
					poiMods.globalMask[5] = gmcol1[1];
					poiMods.globalMask[6] = gmcol1[2];
					poiMods.globalMask[7] = gmcol1[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE2) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol2 = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2_ST), _GlobalMaskTexture2Pan);
				if (_GlobalMaskTexture2Split)
				{
					poiMods.globalMask[8] = gmcol2.r;
					poiMods.globalMask[9] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_G), _GlobalMaskTexture2SplitPan_G).g;
					poiMods.globalMask[10] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_B), _GlobalMaskTexture2SplitPan_B).b;
					poiMods.globalMask[11] = POI2D_SAMPLER_PAN(_GlobalMaskTexture2, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture2UV], _GlobalMaskTexture2SplitTilingOffset_A), _GlobalMaskTexture2SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[8] = gmcol2[0];
					poiMods.globalMask[9] = gmcol2[1];
					poiMods.globalMask[10] = gmcol2[2];
					poiMods.globalMask[11] = gmcol2[3];
				}
				#endif
				
				#if defined(PROP_GLOBALMASKTEXTURE3) || !defined(OPTIMIZER_ENABLED)
				float4 gmcol3 = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3_ST), _GlobalMaskTexture3Pan);
				if (_GlobalMaskTexture3Split)
				{
					poiMods.globalMask[12] = gmcol3.r;
					poiMods.globalMask[13] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_G), _GlobalMaskTexture3SplitPan_G).g;
					poiMods.globalMask[14] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_B), _GlobalMaskTexture3SplitPan_B).b;
					poiMods.globalMask[15] = POI2D_SAMPLER_PAN(_GlobalMaskTexture3, _MainTex, poiUV(poiMesh.uv[_GlobalMaskTexture3UV], _GlobalMaskTexture3SplitTilingOffset_A), _GlobalMaskTexture3SplitPan_A).a;
				}
				else
				{
					poiMods.globalMask[12] = gmcol3[0];
					poiMods.globalMask[13] = gmcol3[1];
					poiMods.globalMask[14] = gmcol3[2];
					poiMods.globalMask[15] = gmcol3[3];
				}
				#endif
			}
			#endif
			//endex
			//ifex _GlobalMaskOptionsEnable==0
			void ApplyGlobalMaskOptions(inout PoiMods poiMods)
			{
				//ifex _GlobalMaskOptionsType!=0
				if (_GlobalMaskOptionsType == 0)
				{
					poiMods.globalMask[0] = saturate(poiMods.globalMask[0] + _GlobalMaskSlider_0);
					poiMods.globalMask[1] = saturate(poiMods.globalMask[1] + _GlobalMaskSlider_1);
					poiMods.globalMask[2] = saturate(poiMods.globalMask[2] + _GlobalMaskSlider_2);
					poiMods.globalMask[3] = saturate(poiMods.globalMask[3] + _GlobalMaskSlider_3);
					poiMods.globalMask[4] = saturate(poiMods.globalMask[4] + _GlobalMaskSlider_4);
					poiMods.globalMask[5] = saturate(poiMods.globalMask[5] + _GlobalMaskSlider_5);
					poiMods.globalMask[6] = saturate(poiMods.globalMask[6] + _GlobalMaskSlider_6);
					poiMods.globalMask[7] = saturate(poiMods.globalMask[7] + _GlobalMaskSlider_7);
					poiMods.globalMask[8] = saturate(poiMods.globalMask[8] + _GlobalMaskSlider_8);
					poiMods.globalMask[9] = saturate(poiMods.globalMask[9] + _GlobalMaskSlider_9);
					poiMods.globalMask[10] = saturate(poiMods.globalMask[10] + _GlobalMaskSlider_10);
					poiMods.globalMask[11] = saturate(poiMods.globalMask[11] + _GlobalMaskSlider_11);
					poiMods.globalMask[12] = saturate(poiMods.globalMask[12] + _GlobalMaskSlider_12);
					poiMods.globalMask[13] = saturate(poiMods.globalMask[13] + _GlobalMaskSlider_13);
					poiMods.globalMask[14] = saturate(poiMods.globalMask[14] + _GlobalMaskSlider_14);
					poiMods.globalMask[15] = saturate(poiMods.globalMask[15] + _GlobalMaskSlider_15);
				}
				//endex
				//ifex _GlobalMaskOptionsType!=1
				if (_GlobalMaskOptionsType == 1)
				{
					poiMods.globalMask[0] = lerp(_GlobalMaskMinMaxSlider_0.x, _GlobalMaskMinMaxSlider_0.y, poiMods.globalMask[0]);
					poiMods.globalMask[1] = lerp(_GlobalMaskMinMaxSlider_1.x, _GlobalMaskMinMaxSlider_1.y, poiMods.globalMask[1]);
					poiMods.globalMask[2] = lerp(_GlobalMaskMinMaxSlider_2.x, _GlobalMaskMinMaxSlider_2.y, poiMods.globalMask[2]);
					poiMods.globalMask[3] = lerp(_GlobalMaskMinMaxSlider_3.x, _GlobalMaskMinMaxSlider_3.y, poiMods.globalMask[3]);
					poiMods.globalMask[4] = lerp(_GlobalMaskMinMaxSlider_4.x, _GlobalMaskMinMaxSlider_4.y, poiMods.globalMask[4]);
					poiMods.globalMask[5] = lerp(_GlobalMaskMinMaxSlider_5.x, _GlobalMaskMinMaxSlider_5.y, poiMods.globalMask[5]);
					poiMods.globalMask[6] = lerp(_GlobalMaskMinMaxSlider_6.x, _GlobalMaskMinMaxSlider_6.y, poiMods.globalMask[6]);
					poiMods.globalMask[7] = lerp(_GlobalMaskMinMaxSlider_7.x, _GlobalMaskMinMaxSlider_7.y, poiMods.globalMask[7]);
					poiMods.globalMask[8] = lerp(_GlobalMaskMinMaxSlider_8.x, _GlobalMaskMinMaxSlider_8.y, poiMods.globalMask[8]);
					poiMods.globalMask[9] = lerp(_GlobalMaskMinMaxSlider_9.x, _GlobalMaskMinMaxSlider_9.y, poiMods.globalMask[9]);
					poiMods.globalMask[10] = lerp(_GlobalMaskMinMaxSlider_10.x, _GlobalMaskMinMaxSlider_10.y, poiMods.globalMask[10]);
					poiMods.globalMask[11] = lerp(_GlobalMaskMinMaxSlider_11.x, _GlobalMaskMinMaxSlider_11.y, poiMods.globalMask[11]);
					poiMods.globalMask[12] = lerp(_GlobalMaskMinMaxSlider_12.x, _GlobalMaskMinMaxSlider_12.y, poiMods.globalMask[12]);
					poiMods.globalMask[13] = lerp(_GlobalMaskMinMaxSlider_13.x, _GlobalMaskMinMaxSlider_13.y, poiMods.globalMask[13]);
					poiMods.globalMask[14] = lerp(_GlobalMaskMinMaxSlider_14.x, _GlobalMaskMinMaxSlider_14.y, poiMods.globalMask[14]);
					poiMods.globalMask[15] = lerp(_GlobalMaskMinMaxSlider_15.x, _GlobalMaskMinMaxSlider_15.y, poiMods.globalMask[15]);
				}
				//endex
				//ifex _GlobalMaskOptionsType!=2
				if (_GlobalMaskOptionsType == 2)
				{
					if (_GlobalMaskToggleOn_0)  poiMods.globalMask[0] = 1;
					if (_GlobalMaskToggleOn_1)  poiMods.globalMask[1] = 1;
					if (_GlobalMaskToggleOn_2)  poiMods.globalMask[2] = 1;
					if (_GlobalMaskToggleOn_3)  poiMods.globalMask[3] = 1;
					if (_GlobalMaskToggleOn_4)  poiMods.globalMask[4] = 1;
					if (_GlobalMaskToggleOn_5)  poiMods.globalMask[5] = 1;
					if (_GlobalMaskToggleOn_6)  poiMods.globalMask[6] = 1;
					if (_GlobalMaskToggleOn_7)  poiMods.globalMask[7] = 1;
					if (_GlobalMaskToggleOn_8)  poiMods.globalMask[8] = 1;
					if (_GlobalMaskToggleOn_9)  poiMods.globalMask[9] = 1;
					if (_GlobalMaskToggleOn_10) poiMods.globalMask[10] = 1;
					if (_GlobalMaskToggleOn_11) poiMods.globalMask[11] = 1;
					if (_GlobalMaskToggleOn_12) poiMods.globalMask[12] = 1;
					if (_GlobalMaskToggleOn_13) poiMods.globalMask[13] = 1;
					if (_GlobalMaskToggleOn_14) poiMods.globalMask[14] = 1;
					if (_GlobalMaskToggleOn_15) poiMods.globalMask[15] = 1;
					
					poiMods.globalMask[0] *= (1 - _GlobalMaskToggleOff_0);
					poiMods.globalMask[1] *= (1 - _GlobalMaskToggleOff_1);
					poiMods.globalMask[2] *= (1 - _GlobalMaskToggleOff_2);
					poiMods.globalMask[3] *= (1 - _GlobalMaskToggleOff_3);
					poiMods.globalMask[4] *= (1 - _GlobalMaskToggleOff_4);
					poiMods.globalMask[5] *= (1 - _GlobalMaskToggleOff_5);
					poiMods.globalMask[6] *= (1 - _GlobalMaskToggleOff_6);
					poiMods.globalMask[7] *= (1 - _GlobalMaskToggleOff_7);
					poiMods.globalMask[8] *= (1 - _GlobalMaskToggleOff_8);
					poiMods.globalMask[9] *= (1 - _GlobalMaskToggleOff_9);
					poiMods.globalMask[10] *= (1 - _GlobalMaskToggleOff_10);
					poiMods.globalMask[11] *= (1 - _GlobalMaskToggleOff_11);
					poiMods.globalMask[12] *= (1 - _GlobalMaskToggleOff_12);
					poiMods.globalMask[13] *= (1 - _GlobalMaskToggleOff_13);
					poiMods.globalMask[14] *= (1 - _GlobalMaskToggleOff_14);
					poiMods.globalMask[15] *= (1 - _GlobalMaskToggleOff_15);
				}
				//endex
				
			}
			//endex
			
			float customDistanceBlend(float base, float blend, float blendType)
			{
				switch(blendType)
				{
					case 0: return blendNormal(base, blend); break;
					case 2: return blendMultiply(base, blend); break;
					default: return 0; break;
				}
			}
			
			void handleGlobalMaskDistance(int index, bool enable, bool type, float minAlpha, float maxAlpha, float min, float max, int blendType, in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				if (enable)
				{
					float3 position = type ? poiMesh.worldPos : poiMesh.objectPosition;
					float val = lerp(minAlpha, maxAlpha, smoothstep(min, max, distance(position, _WorldSpaceCameraPos)));
					poiMods.globalMask[index] = saturate(customDistanceBlend(poiMods.globalMask[index], val, blendType));
				}
			}
			
			void ApplyGlobalMaskModifiers(in PoiMesh poiMesh, inout PoiMods poiMods, in PoiCam poiCam)
			{
				//ifex _GlobalMaskModifiersBackfaceEnable==0
				if (_GlobalMaskModifiersBackfaceEnable)
				{
					float facingMode = saturate(poiMesh.isFrontFace) + 1;
					// _GlobalMaskBackface is 0 for ignore, 1 for back only, 2 for front only
					poiMods.globalMask[0] *= _GlobalMaskBackface_0 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_0));
					poiMods.globalMask[1] *= _GlobalMaskBackface_1 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_1));
					poiMods.globalMask[2] *= _GlobalMaskBackface_2 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_2));
					poiMods.globalMask[3] *= _GlobalMaskBackface_3 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_3));
					poiMods.globalMask[4] *= _GlobalMaskBackface_4 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_4));
					poiMods.globalMask[5] *= _GlobalMaskBackface_5 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_5));
					poiMods.globalMask[6] *= _GlobalMaskBackface_6 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_6));
					poiMods.globalMask[7] *= _GlobalMaskBackface_7 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_7));
					poiMods.globalMask[8] *= _GlobalMaskBackface_8 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_8));
					poiMods.globalMask[9] *= _GlobalMaskBackface_9 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_9));
					poiMods.globalMask[10] *= _GlobalMaskBackface_10 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_10));
					poiMods.globalMask[11] *= _GlobalMaskBackface_11 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_11));
					poiMods.globalMask[12] *= _GlobalMaskBackface_12 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_12));
					poiMods.globalMask[13] *= _GlobalMaskBackface_13 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_13));
					poiMods.globalMask[14] *= _GlobalMaskBackface_14 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_14));
					poiMods.globalMask[15] *= _GlobalMaskBackface_15 == 0 ? 1 : (facingMode == (_GlobalMaskBackface_15));
				}
				//endex
				
				//ifex _GlobalMaskModifiersMirrorEnable==0
				if (_GlobalMaskModifiersMirrorEnable)
				{
					float mirrorMode = 0;
					if (_GlobalMaskMirrorVisibilityMode == 1) // VRC
					mirrorMode = VRCMirrorMode() > 0;
					else // Generic (CVR, etc)
					mirrorMode = IsInMirror();
					
					mirrorMode += 1;
					// _GlobalMaskMirror is 0 for ignore, 1 for outside mirror only, 2 for in mirror only
					poiMods.globalMask[0] *= _GlobalMaskMirror_0 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_0));
					poiMods.globalMask[1] *= _GlobalMaskMirror_1 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_1));
					poiMods.globalMask[2] *= _GlobalMaskMirror_2 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_2));
					poiMods.globalMask[3] *= _GlobalMaskMirror_3 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_3));
					poiMods.globalMask[4] *= _GlobalMaskMirror_4 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_4));
					poiMods.globalMask[5] *= _GlobalMaskMirror_5 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_5));
					poiMods.globalMask[6] *= _GlobalMaskMirror_6 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_6));
					poiMods.globalMask[7] *= _GlobalMaskMirror_7 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_7));
					poiMods.globalMask[8] *= _GlobalMaskMirror_8 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_8));
					poiMods.globalMask[9] *= _GlobalMaskMirror_9 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_9));
					poiMods.globalMask[10] *= _GlobalMaskMirror_10 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_10));
					poiMods.globalMask[11] *= _GlobalMaskMirror_11 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_11));
					poiMods.globalMask[12] *= _GlobalMaskMirror_12 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_12));
					poiMods.globalMask[13] *= _GlobalMaskMirror_13 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_13));
					poiMods.globalMask[14] *= _GlobalMaskMirror_14 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_14));
					poiMods.globalMask[15] *= _GlobalMaskMirror_15 == 0 ? 1 : (mirrorMode == (_GlobalMaskMirror_15));
				}
				//endex
				
				//ifex _GlobalMaskModifiersCameraEnable==0
				if (_GlobalMaskModifiersCameraEnable)
				{
					float isCamera = VRCCameraMode() > 0;
					isCamera += 1;
					// _GlobalMaskCamera is 0 for ignore, 1 for outside camera only, 2 for in camera only
					poiMods.globalMask[0] *= _GlobalMaskCamera_0 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_0));
					poiMods.globalMask[1] *= _GlobalMaskCamera_1 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_1));
					poiMods.globalMask[2] *= _GlobalMaskCamera_2 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_2));
					poiMods.globalMask[3] *= _GlobalMaskCamera_3 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_3));
					poiMods.globalMask[4] *= _GlobalMaskCamera_4 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_4));
					poiMods.globalMask[5] *= _GlobalMaskCamera_5 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_5));
					poiMods.globalMask[6] *= _GlobalMaskCamera_6 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_6));
					poiMods.globalMask[7] *= _GlobalMaskCamera_7 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_7));
					poiMods.globalMask[8] *= _GlobalMaskCamera_8 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_8));
					poiMods.globalMask[9] *= _GlobalMaskCamera_9 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_9));
					poiMods.globalMask[10] *= _GlobalMaskCamera_10 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_10));
					poiMods.globalMask[11] *= _GlobalMaskCamera_11 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_11));
					poiMods.globalMask[12] *= _GlobalMaskCamera_12 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_12));
					poiMods.globalMask[13] *= _GlobalMaskCamera_13 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_13));
					poiMods.globalMask[14] *= _GlobalMaskCamera_14 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_14));
					poiMods.globalMask[15] *= _GlobalMaskCamera_15 == 0 ? 1 : (isCamera == (_GlobalMaskCamera_15));
				}
				//endex
				//ifex _GlobalMaskModifiersDistanceEnable==0
				if (_GlobalMaskModifiersDistanceEnable)
				{
					//ifex _GlobalMaskDistanceEnable_0==0
					handleGlobalMaskDistance(0, _GlobalMaskDistanceEnable_0, _GlobalMaskDistanceType_0, _GlobalMaskDistanceMinAlpha_0, _GlobalMaskDistanceMaxAlpha_0, _GlobalMaskDistanceMin_0, _GlobalMaskDistanceMax_0, _GlobalMaskDistanceBlendType_0, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_1==0
					handleGlobalMaskDistance(1, _GlobalMaskDistanceEnable_1, _GlobalMaskDistanceType_1, _GlobalMaskDistanceMinAlpha_1, _GlobalMaskDistanceMaxAlpha_1, _GlobalMaskDistanceMin_1, _GlobalMaskDistanceMax_1, _GlobalMaskDistanceBlendType_1, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_2==0
					handleGlobalMaskDistance(2, _GlobalMaskDistanceEnable_2, _GlobalMaskDistanceType_2, _GlobalMaskDistanceMinAlpha_2, _GlobalMaskDistanceMaxAlpha_2, _GlobalMaskDistanceMin_2, _GlobalMaskDistanceMax_2, _GlobalMaskDistanceBlendType_2, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_3==0
					handleGlobalMaskDistance(3, _GlobalMaskDistanceEnable_3, _GlobalMaskDistanceType_3, _GlobalMaskDistanceMinAlpha_3, _GlobalMaskDistanceMaxAlpha_3, _GlobalMaskDistanceMin_3, _GlobalMaskDistanceMax_3, _GlobalMaskDistanceBlendType_3, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_4==0
					handleGlobalMaskDistance(4, _GlobalMaskDistanceEnable_4, _GlobalMaskDistanceType_4, _GlobalMaskDistanceMinAlpha_4, _GlobalMaskDistanceMaxAlpha_4, _GlobalMaskDistanceMin_4, _GlobalMaskDistanceMax_4, _GlobalMaskDistanceBlendType_4, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_5==0
					handleGlobalMaskDistance(5, _GlobalMaskDistanceEnable_5, _GlobalMaskDistanceType_5, _GlobalMaskDistanceMinAlpha_5, _GlobalMaskDistanceMaxAlpha_5, _GlobalMaskDistanceMin_5, _GlobalMaskDistanceMax_5, _GlobalMaskDistanceBlendType_5, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_6==0
					handleGlobalMaskDistance(6, _GlobalMaskDistanceEnable_6, _GlobalMaskDistanceType_6, _GlobalMaskDistanceMinAlpha_6, _GlobalMaskDistanceMaxAlpha_6, _GlobalMaskDistanceMin_6, _GlobalMaskDistanceMax_6, _GlobalMaskDistanceBlendType_6, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_7==0
					handleGlobalMaskDistance(7, _GlobalMaskDistanceEnable_7, _GlobalMaskDistanceType_7, _GlobalMaskDistanceMinAlpha_7, _GlobalMaskDistanceMaxAlpha_7, _GlobalMaskDistanceMin_7, _GlobalMaskDistanceMax_7, _GlobalMaskDistanceBlendType_7, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_8==0
					handleGlobalMaskDistance(8, _GlobalMaskDistanceEnable_8, _GlobalMaskDistanceType_8, _GlobalMaskDistanceMinAlpha_8, _GlobalMaskDistanceMaxAlpha_8, _GlobalMaskDistanceMin_8, _GlobalMaskDistanceMax_8, _GlobalMaskDistanceBlendType_8, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_9==0
					handleGlobalMaskDistance(9, _GlobalMaskDistanceEnable_9, _GlobalMaskDistanceType_9, _GlobalMaskDistanceMinAlpha_9, _GlobalMaskDistanceMaxAlpha_9, _GlobalMaskDistanceMin_9, _GlobalMaskDistanceMax_9, _GlobalMaskDistanceBlendType_9, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_10==0
					handleGlobalMaskDistance(10, _GlobalMaskDistanceEnable_10, _GlobalMaskDistanceType_10, _GlobalMaskDistanceMinAlpha_10, _GlobalMaskDistanceMaxAlpha_10, _GlobalMaskDistanceMin_10, _GlobalMaskDistanceMax_10, _GlobalMaskDistanceBlendType_10, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_11==0
					handleGlobalMaskDistance(11, _GlobalMaskDistanceEnable_11, _GlobalMaskDistanceType_11, _GlobalMaskDistanceMinAlpha_11, _GlobalMaskDistanceMaxAlpha_11, _GlobalMaskDistanceMin_11, _GlobalMaskDistanceMax_11, _GlobalMaskDistanceBlendType_11, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_12==0
					handleGlobalMaskDistance(12, _GlobalMaskDistanceEnable_12, _GlobalMaskDistanceType_12, _GlobalMaskDistanceMinAlpha_12, _GlobalMaskDistanceMaxAlpha_12, _GlobalMaskDistanceMin_12, _GlobalMaskDistanceMax_12, _GlobalMaskDistanceBlendType_12, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_13==0
					handleGlobalMaskDistance(13, _GlobalMaskDistanceEnable_13, _GlobalMaskDistanceType_13, _GlobalMaskDistanceMinAlpha_13, _GlobalMaskDistanceMaxAlpha_13, _GlobalMaskDistanceMin_13, _GlobalMaskDistanceMax_13, _GlobalMaskDistanceBlendType_13, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_14==0
					handleGlobalMaskDistance(14, _GlobalMaskDistanceEnable_14, _GlobalMaskDistanceType_14, _GlobalMaskDistanceMinAlpha_14, _GlobalMaskDistanceMaxAlpha_14, _GlobalMaskDistanceMin_14, _GlobalMaskDistanceMax_14, _GlobalMaskDistanceBlendType_14, poiMesh, poiMods);
					//endex
					//ifex _GlobalMaskDistanceEnable_15==0
					handleGlobalMaskDistance(15, _GlobalMaskDistanceEnable_15, _GlobalMaskDistanceType_15, _GlobalMaskDistanceMinAlpha_15, _GlobalMaskDistanceMaxAlpha_15, _GlobalMaskDistanceMin_15, _GlobalMaskDistanceMax_15, _GlobalMaskDistanceBlendType_15, poiMesh, poiMods);
					//endex
					
				}
				//endex
				
			}
			
			//ifex _GlobalMaskVertexColorRed==0 && _GlobalMaskVertexColorGreen==0 && _GlobalMaskVertexColorBlue==0 && _GlobalMaskVertexColorAlpha==0
			void ApplyGlobalMaskVertexColors(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				float4 vcol = poiMesh.vertexColor;
				if (_GlobalMaskVertexColorLinearSpace)
				{
					vcol.rgb = GammaToLinearSpace(vcol.rgb);
				}
				if (_GlobalMaskVertexColorRed > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorRed - 1, _GlobalMaskVertexColorRedBlendType, vcol.r);
				}
				if (_GlobalMaskVertexColorGreen > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorGreen - 1, _GlobalMaskVertexColorGreenBlendType, vcol.g);
				}
				if (_GlobalMaskVertexColorBlue > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorBlue - 1, _GlobalMaskVertexColorBlueBlendType, vcol.b);
				}
				if (_GlobalMaskVertexColorAlpha > 0)
				{
					applyToGlobalMask(poiMods, _GlobalMaskVertexColorAlpha - 1, _GlobalMaskVertexColorAlphaBlendType, vcol.a);
				}
			}
			//endex
			
			//ifex _EnableUDIMDiscardOptions==0
			#ifdef POI_UDIMDISCARD
			void applyUDIMDiscard(in VertexOut i)
			{
				if(_UDIMDiscardMode == 1) // Don't run if in vertex mode
				{
					float2 udim = floor(vertexUV(i, _UDIMDiscardUV));
					
					float isDiscarded = 0;
					float4 xMask = float4(  (udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					isDiscarded += (udim.y >= 0 && udim.y < 1) * dot(float4(_UDIMDiscardRow0_0, _UDIMDiscardRow0_1, _UDIMDiscardRow0_2, _UDIMDiscardRow0_3), xMask);
					isDiscarded += (udim.y >= 1 && udim.y < 2) * dot(float4(_UDIMDiscardRow1_0, _UDIMDiscardRow1_1, _UDIMDiscardRow1_2, _UDIMDiscardRow1_3), xMask);
					isDiscarded += (udim.y >= 2 && udim.y < 3) * dot(float4(_UDIMDiscardRow2_0, _UDIMDiscardRow2_1, _UDIMDiscardRow2_2, _UDIMDiscardRow2_3), xMask);
					isDiscarded += (udim.y >= 3 && udim.y < 4) * dot(float4(_UDIMDiscardRow3_0, _UDIMDiscardRow3_1, _UDIMDiscardRow3_2, _UDIMDiscardRow3_3), xMask);
					
					isDiscarded *= any(float4(udim.y >= 0, udim.y < 4, udim.x >= 0, udim.x < 4)); // never discard outside 4x4 grid in pos coords
					
					const float threshold = 0.001;
					clip(threshold - isDiscarded); // Clip if discarded
				}
				
				return;
			}
			#endif
			//endex
			
			float2 calculatePolarCoordinate(in PoiMesh poiMesh)
			{
				float2 delta = poiMesh.uv[_PolarUV] - _PolarCenter;
				float radius = length(delta) * 2 * _PolarRadialScale;
				float angle = atan2(delta.x, delta.y);
				float phi = angle / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				angle = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				angle *= _PolarLengthScale;
				
				return float2(radius, angle + distance(poiMesh.uv[_PolarUV], _PolarCenter) * _PolarSpiralPower);
			}
			
			float2 MonoPanoProjection(float3 coords)
			{
				float3 normalizedCoords = normalize(coords);
				float latitude = acos(normalizedCoords.y);
				float longitude = atan2(normalizedCoords.z, normalizedCoords.x);
				float phi = longitude / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				longitude = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				longitude *= 2;
				float2 sphereCoords = float2(longitude, latitude) * float2(1.0, 1.0 / UNITY_PI);
				sphereCoords = float2(1.0, 1.0) - sphereCoords;
				return (sphereCoords + float4(0, 1 - unity_StereoEyeIndex, 1, 1.0).xy) * float4(0, 1 - unity_StereoEyeIndex, 1, 1.0).zw;
			}
			
			float2 StereoPanoProjection(float3 coords)
			{
				float3 normalizedCoords = normalize(coords);
				float latitude = acos(normalizedCoords.y);
				float longitude = atan2(normalizedCoords.z, normalizedCoords.x);
				float phi = longitude / (UNITY_PI * 2.0);
				float phi_frac = frac(phi);
				longitude = fwidth(phi) - 0.0001 < fwidth(phi_frac) ? phi : phi_frac;
				longitude *= 2;
				float2 sphereCoords = float2(longitude, latitude) * float2(0.5, 1.0 / UNITY_PI);
				sphereCoords = float2(0.5, 1.0) - sphereCoords;
				return (sphereCoords + float4(0, 1 - unity_StereoEyeIndex, 1, 0.5).xy) * float4(0, 1 - unity_StereoEyeIndex, 1, 0.5).zw;
			}
			
			float2 calculateWorldUV(in PoiMesh poiMesh)
			{
				return float2(_UVModWorldPos0 != 3 ? poiMesh.worldPos[ _UVModWorldPos0] : 0.0f, _UVModWorldPos1 != 3 ? poiMesh.worldPos[_UVModWorldPos1] : 0.0f);
			}
			
			float2 calculatelocalUV(in PoiMesh poiMesh)
			{
				float localUVs[8];
				localUVs[0] = poiMesh.localPos.x;
				localUVs[1] = poiMesh.localPos.y;
				localUVs[2] = poiMesh.localPos.z;
				localUVs[3] = 0;
				localUVs[4] = poiMesh.vertexColor.r;
				localUVs[5] = poiMesh.vertexColor.g;
				localUVs[6] = poiMesh.vertexColor.b;
				localUVs[7] = poiMesh.vertexColor.a;
				
				return float2(localUVs[_UVModLocalPos0],localUVs[_UVModLocalPos1]);
			}
			
			float2 calculatePanosphereUV(in PoiMesh poiMesh)
			{
				float3 viewDirection = normalize(lerp(getCameraPosition().xyz, _WorldSpaceCameraPos.xyz, _PanoUseBothEyes) - poiMesh.worldPos.xyz) * - 1;
				return lerp(MonoPanoProjection(viewDirection), StereoPanoProjection(viewDirection), _StereoEnabled);
			}
			//ifex _EnableDistortion==0
			#ifdef USER_LUT
			float2 distortedUV(in PoiMesh poiMesh)
			{
				#if defined(PROP_DISTORTIONFLOWTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 flowVector = POI2D_SAMPLER_PAN(_DistortionFlowTexture, _MainTex, poiUV(poiMesh.uv[_DistortionFlowTextureUV], _DistortionFlowTexture_ST), _DistortionFlowTexturePan) * 2 - 1;
				#else
				float4 flowVector = -1;
				#endif
				
				#if defined(PROP_DISTORTIONFLOWTEXTURE1) || !defined(OPTIMIZER_ENABLED)
				float4 flowVector1 = POI2D_SAMPLER_PAN(_DistortionFlowTexture1, _MainTex, poiUV(poiMesh.uv[_DistortionFlowTexture1UV], _DistortionFlowTexture1_ST), _DistortionFlowTexture1Pan) * 2 - 1;
				#else
				float4 flowVector1 = -1;
				#endif
				
				#if defined(PROP_DISTORTIONMASK) || !defined(OPTIMIZER_ENABLED)
				half distortionMask = POI2D_SAMPLER_PAN(_DistortionMask, _MainTex, poiMesh.uv[_DistortionMaskUV], _DistortionMaskPan)[_DistortionMaskChannel];
				#else
				half distortionMask = 1;
				#endif
				
				half distortionStrength = _DistortionStrength;
				half distortionStrength1 = _DistortionStrength1;
				
				#ifdef POI_AUDIOLINK
				UNITY_BRANCH
				if (AudioLinkIsAvailable() && _EnableDistortionAudioLink && _AudioLinkAnimToggle)
				{
					distortionStrength += lerp(_DistortionStrengthAudioLink.x, _DistortionStrengthAudioLink.y, AudioLinkData(uint2(0, uint(_DistortionStrengthAudioLinkBand))).r);
					distortionStrength1 += lerp(_DistortionStrength1AudioLink.x, _DistortionStrength1AudioLink.y, AudioLinkData(uint2(0, uint(_DistortionStrength1AudioLinkBand))).r);
				}
				#endif
				
				flowVector *= distortionStrength;
				flowVector1 *= distortionStrength1;
				return poiMesh.uv[_DistortionUvToDistort] + ((flowVector.xy + flowVector1.xy) / 2) * distortionMask;
			}
			#endif
			//endex
			
			//ifex _PoiParallax==0
			#ifdef POI_PARALLAX
			inline float2 POM(in PoiLight poiLight, sampler2D heightMap, in PoiMesh poiMesh, float3 worldViewDir, float3 viewDirTan, int minSamples, int maxSamples, float parallax, float refPlane, float2 tilling, float2 curv)
			{
				#if defined(PROP_HEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				float heightMask = POI2D_SAMPLER_PAN(_Heightmask, _linear_repeat, poiUV(poiMesh.uv[_HeightmaskUV], _Heightmask_ST), _HeightmaskPan)[_HeightmaskChannel];
				if (_HeightmaskInvert)
				{
					heightMask = 1 - heightMask;
				}
				#else
				float heightMask = 1;
				#endif
				
				float2 uvs = poiUV(poiMesh.uv[_HeightMapUV], _HeightMap_ST);
				float2 dx = ddx(uvs);
				float2 dy = ddy(uvs);
				float3 result = 0;
				int stepIndex = 0;
				int numSteps = (int)lerp(maxSamples, minSamples, saturate(dot(poiMesh.normals[0], worldViewDir)));
				float layerHeight = 1.0 / numSteps;
				float2 plane = parallax * heightMask * (viewDirTan.xy / viewDirTan.z);
				uvs += refPlane * plane;
				float2 deltaTex = -plane * layerHeight;
				float2 prevTexOffset = 0;
				float prevRayZ = 1.0f;
				float prevHeight = 0.0f;
				float2 currTexOffset = deltaTex;
				float currRayZ = 1.0f - layerHeight;
				float currHeight = 0.0f;
				float intersection = 0;
				float2 finalTexOffset = 0;
				while (stepIndex < numSteps + 1)
				{
					result.z = dot(curv, currTexOffset * currTexOffset);
					currHeight = tex2Dgrad(heightMap, uvs + currTexOffset, dx, dy).r * (1 - result.z);
					if (currHeight > currRayZ)
					{
						stepIndex = numSteps + 1;
					}
					else
					{
						stepIndex++;
						prevTexOffset = currTexOffset;
						prevRayZ = currRayZ;
						prevHeight = currHeight;
						currTexOffset += deltaTex;
						currRayZ -= layerHeight * (1 - result.z) * (1 + _CurvFix);
					}
				}
				int sectionSteps = 10;
				int sectionIndex = 0;
				float newZ = 0;
				float newHeight = 0;
				while (sectionIndex < sectionSteps)
				{
					intersection = (prevHeight - prevRayZ) / (prevHeight - currHeight + currRayZ - prevRayZ);
					finalTexOffset = prevTexOffset +intersection * deltaTex;
					newZ = prevRayZ - intersection * layerHeight;
					newHeight = tex2Dgrad(heightMap, uvs + finalTexOffset, dx, dy).r;
					if (newHeight > newZ)
					{
						currTexOffset = finalTexOffset;
						currHeight = newHeight;
						currRayZ = newZ;
						deltaTex = intersection * deltaTex;
						layerHeight = intersection * layerHeight;
					}
					else
					{
						prevTexOffset = finalTexOffset;
						prevHeight = newHeight;
						prevRayZ = newZ;
						deltaTex = (1 - intersection) * deltaTex;
						layerHeight = (1 - intersection) * layerHeight;
					}
					sectionIndex++;
				}
				#ifdef UNITY_PASS_SHADOWCASTER
				if (unity_LightShadowBias.z == 0.0)
				{
					#endif
					if (result.z > 1)
					clip(-1);
					#ifdef UNITY_PASS_SHADOWCASTER
				}
				#endif
				
				return uvs + finalTexOffset;
			}
			/*
			float2 ParallaxOffsetMultiStep(float surfaceHeight, float strength, float2 uv, float3 tangentViewDir)
			{
				float2 uvOffset = 0;
				float2 prevUVOffset = 0;
				float stepSize = 1.0 / _HeightSteps;
				float stepHeight = 1;
				float2 uvDelta = tangentViewDir.xy * (stepSize * strength);
				float prevStepHeight = stepHeight;
				float prevSurfaceHeight = surfaceHeight;
				
				[unroll(20)]
				for (int j = 1; j <= _HeightSteps && stepHeight > surfaceHeight; j++)
				{
					prevUVOffset = uvOffset;
					prevStepHeight = stepHeight;
					prevSurfaceHeight = surfaceHeight;
					uvOffset -= uvDelta;
					stepHeight -= stepSize;
					surfaceHeight = POI2D_SAMPLER_PAN(_Heightmap, _MainTex, poiUV(uv + uvOffset, _Heightmap_ST), _HeightmapPan) + _HeightOffset;
				}
				
				[unroll(3)]
				for (int k = 0; k < 3; k++)
				{
					uvDelta *= 0.5;
					stepSize *= 0.5;
					
					if (stepHeight < surfaceHeight)
					{
						uvOffset += uvDelta;
						stepHeight += stepSize;
					}
					else
					{
						uvOffset -= uvDelta;
						stepHeight -= stepSize;
					}
					surfaceHeight = POI2D_SAMPLER_PAN(_Heightmap, _MainTex, poiUV(uv + uvOffset, _Heightmap_ST), _HeightmapPan) + _HeightOffset;
				}
				return uvOffset;
			}
			*/
			void applyParallax(inout PoiMesh poiMesh, in PoiLight poiLight, in PoiCam poiCam)
			{
				/*
				half h = POI2D_SAMPLER_PAN(_Heightmap, _linear_repeat, poiUV(poiMesh.uv[_HeightmaskUV], _Heightmap_ST), _HeightmapPan).r + _HeightOffset;
				#if defined(PROP_HEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
				half m = POI2D_SAMPLER_PAN(_Heightmask, _linear_repeat, poiUV(poiMesh.uv[_HeightmaskUV], _Heightmask_ST), _HeightmaskPan).r + _HeightOffset;
				#else
				half m = 1 + _HeightOffset;
				#endif
				h = clamp(h, 0, 0.999);
				m = lerp(m, 1 - m, _HeightmaskInvert);
				#if defined(OPTIMIZER_ENABLED)das
				poiMesh.uv[_ParallaxUV] += ParallaxOffsetMultiStep(h, _HeightStrength * m, poiMesh.uv[_HeightmapUV], tangentViewDir / tangentViewDir.z);
				#else
				float2 offset = ParallaxOffsetMultiStep(h, _HeightStrength * m, poiMesh.uv[_HeightmapUV], tangentViewDir / tangentViewDir.z);
				if (_ParallaxUV == 0)       poiMesh.uv[0] += offset;
				if (_ParallaxUV == 1)       poiMesh.uv[1] += offset;
				if (_ParallaxUV == 2)       poiMesh.uv[2] += offset;
				if (_ParallaxUV == 3)       poiMesh.uv[3] += offset;
				if (_ParallaxUV == 4)       poiMesh.uv[4] += offset;
				if (_ParallaxUV == 5)       poiMesh.uv[5] += offset;
				if (_ParallaxUV == 6)       poiMesh.uv[6] += offset;
				if (_ParallaxUV == 7)       poiMesh.uv[7] += offset;
				#endif
				*/
				
				#if defined(OPTIMIZER_ENABLED)
				poiMesh.uv[_ParallaxUV] = POM(poiLight, _HeightMap, poiMesh, poiCam.viewDir, poiCam.tangentViewDir, _HeightStepsMin, _HeightStepsMax, _HeightStrength, 0, _HeightMap_ST.xy, float2(_CurvatureU, _CurvatureV));
				#else
				float2 offset = POM(poiLight, _HeightMap, poiMesh, poiCam.viewDir, poiCam.tangentViewDir, _HeightStepsMin, _HeightStepsMax, _HeightStrength, 0, _HeightMap_ST.xy, float2(_CurvatureU, _CurvatureV));
				if (_ParallaxUV == 0)       poiMesh.uv[0] = offset;
				if (_ParallaxUV == 1)       poiMesh.uv[1] = offset;
				if (_ParallaxUV == 2)       poiMesh.uv[2] = offset;
				if (_ParallaxUV == 3)       poiMesh.uv[3] = offset;
				if (_ParallaxUV == 4)       poiMesh.uv[4] = offset;
				if (_ParallaxUV == 5)       poiMesh.uv[5] = offset;
				if (_ParallaxUV == 6)       poiMesh.uv[6] = offset;
				if (_ParallaxUV == 7)       poiMesh.uv[7] = offset;
				#endif
			}
			#endif
			//endex
			
			//ifex _BlackLightMaskingEnabled==0
			#ifdef POI_BLACKLIGHTMASKING
			void calculateBlackLightMasks(in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				#ifdef VERTEXLIGHT_ON
				for (int lightIndex = 0; lightIndex < 4; lightIndex++)
				{
					float3 lightPos = float3(unity_4LightPosX0[lightIndex], unity_4LightPosY0[lightIndex], unity_4LightPosZ0[lightIndex]);
					if (!distance(unity_LightColor[lightIndex].rgb, float3(0, 0, 0)))
					{
						if (_BlackLightMasking0GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking0Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking0GlobalMaskIndex - 1, _BlackLightMasking0GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking1GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking1Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking1GlobalMaskIndex - 1, _BlackLightMasking1GlobalMaskBlendType, smoothstep(_BlackLightMasking1Range.y, _BlackLightMasking1Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking2GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking2Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking2GlobalMaskIndex - 1, _BlackLightMasking2GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
						
						if (_BlackLightMasking3GlobalMaskIndex > 0)
						{
							if (unity_LightColor[lightIndex].a == _BlackLightMasking3Key)
							{
								applyToGlobalMask(poiMods, _BlackLightMasking3GlobalMaskIndex - 1, _BlackLightMasking3GlobalMaskBlendType, smoothstep(_BlackLightMasking0Range.y, _BlackLightMasking0Range.x, distance(poiMesh.worldPos, lightPos)));
							}
						}
					}
				}
				#else
				if (_BlackLightMasking0GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking0GlobalMaskIndex - 1, _BlackLightMasking0GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking1GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking1GlobalMaskIndex - 1, _BlackLightMasking1GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking2GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking2GlobalMaskIndex - 1, _BlackLightMasking2GlobalMaskBlendType, 0);
				}
				
				if (_BlackLightMasking3GlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _BlackLightMasking3GlobalMaskIndex - 1, _BlackLightMasking3GlobalMaskBlendType, 0);
				}
				#endif
			}
			#endif
			//endex
			
			//ifex _MainVertexColoringEnabled==0
			void applyVertexColor(inout PoiFragData poiFragData, PoiMesh poiMesh)
			{
				if (_MainVertexColoringEnabled)
				{
					#ifndef POI_PASS_OUTLINE
					float3 vertCol = lerp(poiMesh.vertexColor.rgb, GammaToLinearSpace(poiMesh.vertexColor.rgb), _MainVertexColoringLinearSpace);
					poiFragData.baseColor *= lerp(1, vertCol, _MainVertexColoring);
					#endif
					poiFragData.alpha *= lerp(1, poiMesh.vertexColor.a, _MainUseVertexColorAlpha);
				}
			}
			//endex
			
			//ifex _BackFaceEnabled!=1
			#ifdef POI_BACKFACE
			void ApplyBackFaceColor(inout PoiFragData poiFragData, in PoiMesh poiMesh, inout PoiMods poiMods)
			{
				if (!poiMesh.isFrontFace)
				{
					float4 backFaceColor = _BackFaceColor;
					backFaceColor.rgb = poiThemeColor(poiMods, backFaceColor.rgb, _BackFaceColorThemeIndex);
					#if defined(PROP_BACKFACETEXTURE) || !defined(OPTIMIZER_ENABLED)
					backFaceColor *= POI2D_SAMPLER_PAN(_BackFaceTexture, _MainTex, poiUV(poiMesh.uv[_BackFaceTextureUV], _BackFaceTexture_ST), _BackFaceTexturePan);
					#endif
					backFaceColor.rgb = hueShift(backFaceColor.rgb, frac(_BackFaceHueShift + _BackFaceHueShiftSpeed * _Time.x) * _BackFaceHueShiftEnabled);
					
					float backFaceMask = 1;
					#if defined(PROP_BACKFACEMASK) || !defined(OPTIMIZER_ENABLED)
					backFaceMask *= POI2D_SAMPLER_PAN(_BackFaceMask, _MainTex, poiUV(poiMesh.uv[_BackFaceMaskUV], _BackFaceMask_ST), _BackFaceMaskPan)[_BackFaceMaskChannel];
					#endif
					if (!_BackFaceReplaceAlpha)
					{
						backFaceMask *= backFaceColor.a;
					}
					
					poiFragData.baseColor = lerp(poiFragData.baseColor, backFaceColor.rgb, backFaceMask);
					
					UNITY_BRANCH
					if (_BackFaceReplaceAlpha)
					{
						poiFragData.alpha = backFaceColor.a;
					}
					
					poiFragData.emission += backFaceColor.rgb * _BackFaceEmissionStrength * backFaceMask;
					poiMods.globalEmission = poiMods.globalEmission * _BackFaceEmissionLimiter;
				}
			}
			#endif
			//endex
			
			//ifex _EnableDissolve==0
			#ifdef DISTORT
			void applyDissolve(inout PoiFragData poiFragData, in PoiMesh poiMesh, inout PoiMods poiMods, in PoiCam poiCam, in PoiLight poiLight)
			{
				#if defined(PROP_DISSOLVEMASK) || !defined(OPTIMIZER_ENABLED)
				float dissolveMask = POI2D_SAMPLER_PAN(_DissolveMask, _MainTex, poiUV(poiMesh.uv[_DissolveMaskUV], _DissolveMask_ST), _DissolveMaskPan).r;
				#else
				float dissolveMask = 1;
				#endif
				UNITY_BRANCH
				if (_DissolveUseVertexColors > 0)
				{
					// Vertex Color Imprecision hype
					dissolveMask = ceil(poiMesh.vertexColor[_DissolveUseVertexColors] * 100000) / 100000;
				}
				if (_DissolveMaskGlobalMask > 0)
				{
					dissolveMask = maskBlend(dissolveMask, poiMods.globalMask[_DissolveMaskGlobalMask - 1], _DissolveMaskGlobalMaskBlendType);
				}
				
				#if defined(PROP_DISSOLVETOTEXTURE) || !defined(OPTIMIZER_ENABLED)
				dissolveToTexture = POI2D_SAMPLER_PAN(_DissolveToTexture, _MainTex, poiUV(poiMesh.uv[_DissolveToTextureUV], _DissolveToTexture_ST), _DissolveToTexturePan) * float4(poiThemeColor(poiMods, _DissolveTextureColor.rgb, _DissolveTextureColorThemeIndex), _DissolveTextureColor.a);
				#else
				dissolveToTexture = _DissolveTextureColor;
				#endif
				
				#if defined(PROP_DISSOLVENOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
				float dissolveNoiseTexture = POI2D_SAMPLER_PAN(_DissolveNoiseTexture, _MainTex, poiUV(poiMesh.uv[_DissolveNoiseTextureUV], _DissolveNoiseTexture_ST), _DissolveNoiseTexturePan).r;
				#else
				float dissolveNoiseTexture = 1;
				#endif
				
				float da = _DissolveAlpha
				+ _DissolveAlpha0
				+ _DissolveAlpha1
				+ _DissolveAlpha2
				+ _DissolveAlpha3
				+ _DissolveAlpha4
				+ _DissolveAlpha5
				+ _DissolveAlpha6
				+ _DissolveAlpha7
				+ _DissolveAlpha8
				+ _DissolveAlpha9;
				float dds = _DissolveDetailStrength;
				
				if (_UVTileDissolveEnabled)
				{
					float2 udim = floor(poiMesh.uv[(int)_UVTileDissolveUV]);
					
					float4 xMask = float4((udim.x >= 0 && udim.x < 1),
					(udim.x >= 1 && udim.x < 2),
					(udim.x >= 2 && udim.x < 3),
					(udim.x >= 3 && udim.x < 4));
					
					da += (udim.y >= 0 && udim.y < 1) * dot(float4(_UVTileDissolveAlpha_Row0_0, _UVTileDissolveAlpha_Row0_1, _UVTileDissolveAlpha_Row0_2, _UVTileDissolveAlpha_Row0_3), xMask);
					da += (udim.y >= 1 && udim.y < 2) * dot(float4(_UVTileDissolveAlpha_Row1_0, _UVTileDissolveAlpha_Row1_1, _UVTileDissolveAlpha_Row1_2, _UVTileDissolveAlpha_Row1_3), xMask);
					da += (udim.y >= 2 && udim.y < 3) * dot(float4(_UVTileDissolveAlpha_Row2_0, _UVTileDissolveAlpha_Row2_1, _UVTileDissolveAlpha_Row2_2, _UVTileDissolveAlpha_Row2_3), xMask);
					da += (udim.y >= 3 && udim.y < 4) * dot(float4(_UVTileDissolveAlpha_Row3_0, _UVTileDissolveAlpha_Row3_1, _UVTileDissolveAlpha_Row3_2, _UVTileDissolveAlpha_Row3_3), xMask);
				}
				
				#ifdef POI_AUDIOLINK
				UNITY_BRANCH
				if (_EnableDissolveAudioLink && poiMods.audioLinkAvailable)
				{
					da += lerp(_AudioLinkDissolveAlpha.x, _AudioLinkDissolveAlpha.y, poiMods.audioLink[_AudioLinkDissolveAlphaBand]);
					dds += lerp(_AudioLinkDissolveDetail.x, _AudioLinkDissolveDetail.y, poiMods.audioLink[_AudioLinkDissolveDetailBand]);
				}
				#endif
				
				da = saturate(da);
				dds = saturate(dds);
				
				if (_DissolveMaskInvert)
				{
					dissolveMask = 1 - dissolveMask;
				}
				#if defined(PROP_DISSOLVEDETAILNOISE) || !defined(OPTIMIZER_ENABLED)
				float dissolveDetailNoise = POI2D_SAMPLER_PAN(_DissolveDetailNoise, _MainTex, poiUV(poiMesh.uv[_DissolveDetailNoiseUV], _DissolveDetailNoise_ST), _DissolveDetailNoisePan);
				#else
				float dissolveDetailNoise = 0;
				#endif
				if (_DissolveInvertNoise)
				{
					dissolveNoiseTexture = 1 - dissolveNoiseTexture;
				}
				if (_DissolveInvertDetailNoise)
				{
					dissolveDetailNoise = 1 - dissolveDetailNoise;
				}
				if (_ContinuousDissolve != 0)
				{
					da = sin(_Time.x * _ContinuousDissolve) * .5 + .5;
				}
				da *= dissolveMask;
				dissolveAlpha = da;
				edgeAlpha = 0;
				
				[flatten]
				switch(_DissolveType)
				{
					default: // Basic (case 1)
					
					{
						da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						dissolveAlpha = da;
						//Adjust detail strength to avoid artifacts
						dds *= smoothstep(1, 0.99, da) * lerp(1, smoothstep(0, lerp(0.01, 0.1, dds), da), _DissolveDetailEdgeSmoothing);
						float noise = saturate(dissolveNoiseTexture - dissolveDetailNoise * dds);
						
						noise = saturate(noise * 0.998 + 0.001);
						dissolveAlpha = dissolveAlpha >= noise;
						edgeAlpha = remapClamped(da + _DissolveEdgeWidth, da, noise) * (1 - dissolveAlpha);
						break;
					}
					case 2: // Point to Point
					
					{
						float3 direction;
						float3 currentPos;
						float distanceTo = 0;
						direction = normalize(_DissolveEndPoint - _DissolveStartPoint);
						currentPos = lerp(_DissolveStartPoint, _DissolveEndPoint, dissolveAlpha);
						
						UNITY_BRANCH
						if (_DissolveP2PWorldLocal != 1)
						{
							float3 pos = _DissolveP2PWorldLocal == 0 ? poiMesh.localPos.rgb : poiMesh.vertexColor.rgb;
							distanceTo = dot(pos - currentPos, direction) - dissolveDetailNoise * dds;
							edgeAlpha = smoothstep(_DissolveP2PEdgeLength + .00001, 0, distanceTo);
							dissolveAlpha = step(distanceTo, 0);
							edgeAlpha *= 1 - dissolveAlpha;
						}
						else
						{
							distanceTo = dot(poiMesh.worldPos - currentPos, direction) - dissolveDetailNoise * dds;
							edgeAlpha = smoothstep(_DissolveP2PEdgeLength + .00001, 0, distanceTo);
							dissolveAlpha = (distanceTo < 0) ? 1 : 0;
							edgeAlpha *= 1 - dissolveAlpha;
						}
						
						if (_DissolveP2PClamp)
						{
							dissolveAlpha = saturate(dissolveAlpha * smoothstep(0, 0.01, da) + smoothstep(0.99, 1, da));
							edgeAlpha *= smoothstep(0, 0.01, da);
						}
						
						break;
					}
					case 3: // Spherical
					
					{
						if (_SphericalDissolveInvert)
						{
							da = remap(da, 1, 0, -_DissolveEdgeWidth, 1);
						}
						else
						{
							da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						}
						
						dissolveAlpha = da;
						dds *= smoothstep(0, 0.2 * dds + 0.01, dissolveAlpha) * lerp(1, smoothstep(1, 1 - 0.2 * dds - 0.01, dissolveAlpha), _DissolveDetailEdgeSmoothing);
						float currentDistance = lerp(0, _SphericalDissolveRadius, dissolveAlpha);
						float fragDistance = distance(_SphericalDissolveCenter, poiMesh.localPos.xyz);
						float normalizedDistance;
						normalizedDistance = (fragDistance - currentDistance) / (_SphericalDissolveRadius + 0.0001) - dissolveDetailNoise * dds;
						
						if (_SphericalDissolveInvert)
						{
							dissolveAlpha = (normalizedDistance > 0) ? 1 : 0;
							edgeAlpha = smoothstep(_DissolveEdgeWidth + .00001, 0, -normalizedDistance);
						}
						else
						{
							dissolveAlpha = (normalizedDistance < 0) ? 1 : 0;
							edgeAlpha = smoothstep(_DissolveEdgeWidth + .00001, 0, normalizedDistance);
						}
						
						if (_SphericalDissolveClamp)
						{
							da = lerp(da, 1 - da, _SphericalDissolveInvert);
							dissolveAlpha = saturate(dissolveAlpha * smoothstep(0, 0.01, da) + smoothstep(0.99, 1, da));
							edgeAlpha *= smoothstep(0, 0.01, da);
						}
						
						break;
					}
					case 4: // CenterOut
					
					{
						float ramp = 0.5;
						float noise;
						
						[flatten]
						switch(_CenterOutDissolveMode)
						{
							case 1: // View Direction
							
							{
								ramp = saturate(lerp(poiLight.vertexNDotV, poiLight.nDotV, _CenterOutDissolveNormals));
								break;
							}
							case 2: // Custom Direction
							
							{
								ramp = dot(normalize(_CenterOutDissolveDirection), lerp(poiMesh.normals[0], poiMesh.normals[1], _CenterOutDissolveNormals));
								ramp = saturate(ramp * .5 + 0.5);
								break;
							}
							case 3: // Light Direction
							
							{
								ramp = lerp(poiLight.vertexNDotL, poiLight.nDotL, _CenterOutDissolveNormals);
								ramp = saturate(ramp * .5 + 0.5);
								break;
							}
						}
						
						if (_CenterOutDissolvePower != 1)
						{
							ramp = pow(ramp, _CenterOutDissolvePower);
						}
						
						if (!_CenterOutDissolveInvert)
						{
							ramp = 1 - ramp;
						}
						
						da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
						dissolveAlpha = da;
						//Adjust detail strength to avoid artifacts
						dds *= smoothstep(1, 0.99, da) * lerp(1, smoothstep(0, lerp(0.01, 0.1, dds), da), _DissolveDetailEdgeSmoothing);
						
						noise = saturate(ramp - dissolveDetailNoise * dds);
						noise = saturate(noise * 0.998 + 0.001);
						dissolveAlpha = dissolveAlpha >= noise;
						edgeAlpha = remapClamped(da + _DissolveEdgeWidth, da, noise) * (1 - dissolveAlpha);
						break;
					}
				}
				
				#ifndef POI_SHADOW
				UNITY_BRANCH
				if (_DissolveHueShiftEnabled)
				{
					dissolveToTexture.rgb = hueShift(dissolveToTexture.rgb, _DissolveHueShift + _Time.x * _DissolveHueShiftSpeed);
				}
				#endif
				
				poiFragData.alpha = lerp(poiFragData.alpha, dissolveToTexture.a, dissolveAlpha * .999999);
				
				#if !defined(POI_PASS_OUTLINE) && !defined(UNITY_PASS_SHADOWCASTER)
				poiFragData.baseColor = lerp(poiFragData.baseColor, dissolveToTexture.rgb, dissolveAlpha * .999999);
				
				if (_DissolveApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _DissolveApplyGlobalMaskIndex - 1, _DissolveApplyGlobalMaskBlendType, dissolveAlpha * .999999);
				}
				if (_DissolveInverseApplyGlobalMaskIndex > 0)
				{
					applyToGlobalMask(poiMods, _DissolveInverseApplyGlobalMaskIndex - 1, _DissolveInverseApplyGlobalMaskBlendType, 1-(dissolveAlpha * .999999));
				}
				UNITY_BRANCH
				if (_DissolveEdgeWidth || (_DissolveType == 2 && _DissolveP2PEdgeLength != 0))
				{
					edgeColor = tex2D(_DissolveEdgeGradient, poiUV(float2(edgeAlpha, edgeAlpha), _DissolveEdgeGradient_ST)) * float4(poiThemeColor(poiMods, _DissolveEdgeColor.rgb, _DissolveEdgeColorThemeIndex), _DissolveEdgeColor.a);
					#ifndef POI_SHADOW
					UNITY_BRANCH
					if (_DissolveEdgeHueShiftEnabled)
					{
						edgeColor.rgb = hueShift(edgeColor.rgb, _DissolveEdgeHueShift + _Time.x * _DissolveEdgeHueShiftSpeed);
					}
					#endif
					poiFragData.baseColor = lerp(poiFragData.baseColor, edgeColor.rgb, smoothstep(0, 1 - _DissolveEdgeHardness * .99999999999, edgeAlpha));
				}
				
				poiFragData.emission += lerp(0, dissolveToTexture * _DissolveToEmissionStrength, dissolveAlpha) + lerp(0, edgeColor.rgb * _DissolveEdgeEmission, smoothstep(0, 1 - _DissolveEdgeHardness * .99999999999, edgeAlpha));
				#endif
			}
			#endif
			//endex
			
			//ifex _EnableALDecal==0
			#ifdef POI_AUDIOLINK
			#ifdef POI_AL_DECAL
			void ApplyAudioLinkDecal(in PoiMesh poiMesh, inout PoiFragData poiFragData, in PoiMods poiMods)
			{
				float4 colorAndMask = float4(1, 1, 1, 1);
				#if defined(PROP_ALDECALCOLORMASK) || !defined(OPTIMIZER_ENABLED)
				colorAndMask = POI2D_SAMPLER_PAN(_ALDecalColorMask, _MainTex, poiUV(poiMesh.uv[_ALDecalColorMaskUV], _ALDecalColorMask_ST), _ALDecalColorMaskPan);
				#endif
				if (_ALDecalGlobalMask > 0)
				{
					colorAndMask.a = customBlend(colorAndMask.a, poiMods.globalMask[_ALDecalGlobalMask-1], _ALDecalGlobalMaskBlendType);
				}
				
				float2 uv = poiMesh.uv[_ALDecalUV];
				float2 decalCenter = _ALUVPosition;
				float theta = radians(_ALUVRotation + _Time.z * _ALUVRotationSpeed);
				float cs = cos(theta);
				float sn = sin(theta);
				uv = float2((uv.x - decalCenter.x) * cs - (uv.y - decalCenter.y) * sn + decalCenter.x, (uv.x - decalCenter.x) * sn + (uv.y - decalCenter.y) * cs + decalCenter.y);
				uv = remap(uv, float2(0, 0) - _ALUVScale.xz / 2 + _ALUVPosition, _ALUVScale.yw / 2 + _ALUVPosition, float2(0, 0), float2(1, 1));
				
				// Mask
				float4 audioLinkMask = 1.0;
				
				// UV
				float2 aluv = uv;
				if (_ALDecalUVMode == 1)
				{
					float2 uvdir = uv * 2 - 1;
					aluv.x = frac(atan2(uvdir.y, uvdir.x) * UNITY_INV_TWO_PI);
					aluv.y = length(uvdir);
				}
				
				// Scale / Offset / Step
				float maskY = aluv.y;
				if (_ALDecalUVMode == 1)
				{
					maskY = remap(maskY, _ALDecaldCircleDimensions.x, _ALDecaldCircleDimensions.y, 0, 1);
				}
				float maskX = aluv.x;
				if (_ALDecalUVMode == 1)
				{
					maskX = remap(maskX, _ALDecaldCircleDimensions.z, _ALDecaldCircleDimensions.w, 0, 1);
				}
				
				float maskVolume = _ALDecalVolumeStep != 0.0 ? floor(maskY * _ALDecalVolumeStep) / _ALDecalVolumeStep : maskY;
				float maskBand = _ALDecalBandStep != 0.0 ? floor(maskX * _ALDecalBandStep) / _ALDecalBandStep : maskX;
				
				// Copy
				audioLinkMask.r = maskVolume;
				audioLinkMask.g = maskBand;
				
				// Clip
				audioLinkMask.b = maskVolume < _ALDecalVolumeClipMin || maskVolume > _ALDecalVolumeClipMax ? 0.0 : audioLinkMask.b;
				audioLinkMask.b = maskBand < _ALDecalBandClipMin || maskBand > _ALDecalBandClipMax ? 0.0 : audioLinkMask.b;
				
				// Shape Clip
				if (_ALDecalShapeClip)
				{
					float volumeth = _ALDecalShapeClipVolumeWidth;
					if (_ALDecalVolumeStep != 0.0) audioLinkMask.b = frac(maskY * _ALDecalVolumeStep) > volumeth ? 0.0 : audioLinkMask.b;
					
					float bandwidth = _ALDecalUVMode == 1 ? _ALDecalShapeClipBandWidth / aluv.y : _ALDecalShapeClipBandWidth;
					float bandth = 1.0 - bandwidth;
					if (_ALDecalBandStep != 0.0) audioLinkMask.b = frac(maskX * _ALDecalBandStep + bandth * 0.5) < bandth ? 0.0 : audioLinkMask.b;
				}
				
				// AudioLink
				float2 audioLinkUV = float2(frac(audioLinkMask.g * 2.0), 4.5 / 4.0 + floor(audioLinkMask.g * 2.0) / 4.0);
				audioLinkUV.y *= 0.0625;
				float4 audioTexture = _AudioTexture.Sample(sampler_linear_clamp, audioLinkUV);
				float audioVal = audioTexture.b * _ALDecalVolume * lerp(_ALDecalBaseBoost, _ALDecalTrebleBoost, audioLinkMask.g);
				float audioLinkValue = _ALDecalLineWidth < 1.0 ? abs(audioVal - audioLinkMask.r) < _ALDecalLineWidth : audioVal > audioLinkMask.r * 2.0;
				audioLinkValue = saturate(audioLinkValue) * audioLinkMask.b;
				//clip(audioLinkValue - .5);
				audioLinkValue *= colorAndMask.a;
				
				if (!poiMods.audioLinkAvailable)
				{
					audioLinkValue = 0;
				}
				
				float3 alColorChord = _AudioTexture.Sample(sampler_linear_clamp, float2(maskX, 24.5 / 64.0)).rgb;
				float volumeColorSrc = audioLinkMask.g;
				if (_ALDecalVolumeColorSource == 1) volumeColorSrc = audioLinkMask.r;
				if (_ALDecalVolumeColorSource == 2) volumeColorSrc = audioVal;
				
				float3 lowColor = _ALDecalVolumeColorLow.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorLow.rgb, _ALDecalVolumeColorLowThemeIndex);
				float3 midColor = _ALDecalVolumeColorMid.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorMid.rgb, _ALDecalVolumeColorMidThemeIndex);
				float3 highColor = _ALDecalVolumeColorHigh.rgb * poiThemeColor(poiMods, _ALDecalVolumeColorHigh.rgb, _ALDecalVolumeColorHighThemeIndex);
				
				float3 volumeColor = lerp(lowColor, midColor, saturate(volumeColorSrc * 2));
				volumeColor = lerp(volumeColor, highColor, saturate(volumeColorSrc * 2 - 1));
				
				float3 emissionColor = lerp(lowColor * _ALDecalLowEmission, midColor * _ALDecalMidEmission, saturate(volumeColorSrc * 2));
				emissionColor = lerp(emissionColor, highColor * _ALDecalHighEmission, saturate(volumeColorSrc * 2 - 1));
				
				//poiFragData.baseColor = lerp(poiFragData.baseColor, volumeColor, audioLinkValue);
				#if defined(POI_PASS_BASE) || defined(POI_PASS_ADD)
				poiFragData.emission += emissionColor * audioLinkValue;
				poiFragData.baseColor.rgb = lerp(poiFragData.baseColor, customBlend(poiFragData.baseColor, volumeColor * colorAndMask.rgb, _ALDecalBlendType), saturate(_ALDecalBlendAlpha * audioLinkValue));
				#endif
				poiFragData.alpha = lerp(poiFragData.alpha, poiFragData.alpha * audioLinkValue, _ALDecalControlsAlpha);
			}
			#endif
			#endif
			//endex
			
			//ifex _EnableFlipbook==0
			#ifdef _SUNDISK_HIGH_QUALITY
			
			void applyFlipbook(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				#if defined(PROP_FLIPBOOKTEXARRAY) || !defined(OPTIMIZER_ENABLED)
				float4 flipBookPixel = float4(0, 0, 0, 0);
				#if defined(PROP_FLIPBOOKMASK) || !defined(OPTIMIZER_ENABLED)
				float flipBookMask = POI2D_SAMPLER_PAN(_FlipbookMask, _MainTex, poiUV(poiMesh.uv[_FlipbookMaskUV], _FlipbookMask_ST), _FlipbookMaskPan)[_FlipbookMaskChannel];
				#else
				float flipBookMask = 1;
				#endif
				if (_FlipbookMaskGlobalMask > 0)
				{
					flipBookMask = maskBlend(flipBookMask, poiMods.globalMask[_FlipbookMaskGlobalMask-1], _FlipbookMaskGlobalMaskBlendType);
				}
				float4 flipbookScaleOffset = _FlipbookScaleOffset;
				
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookScaleOffset.xy += lerp(_AudioLinkFlipbookScale.xy, _AudioLinkFlipbookScale.zw, poiMods.audioLink[_AudioLinkFlipbookScaleBand]);
				}
				#endif
				
				flipbookScaleOffset.xy = 1 - flipbookScaleOffset.xy;
				float2 uv = frac(poiMesh.uv[_FlipbookTexArrayUV]);
				float theta = radians(_FlipbookRotation + _Time.z * _FlipbookRotationSpeed);
				float cs = cos(theta);
				float sn = sin(theta);
				float2 spriteCenter = flipbookScaleOffset.zw + .5;
				// 2d rotation
				uv = float2((uv.x - spriteCenter.x) * cs - (uv.y - spriteCenter.y) * sn + spriteCenter.x, (uv.x - spriteCenter.x) * sn + (uv.y - spriteCenter.y) * cs + spriteCenter.y);
				float4 sideOffset = float4(-(_FlipbookSideOffset.x), _FlipbookSideOffset.y, -(_FlipbookSideOffset.z), _FlipbookSideOffset.w);
				float2 newUV = remap(uv, float2(0, 0) + flipbookScaleOffset.xy / 2 + flipbookScaleOffset.zw + sideOffset.xz, float2(1, 1) - flipbookScaleOffset.xy / 2 + flipbookScaleOffset.zw + sideOffset.yw, float2(0, 0), float2(1, 1));
				
				UNITY_BRANCH
				if (_FlipbookTiled == 0)
				{
					if (max(newUV.x, newUV.y) > 1 || min(newUV.x, newUV.y) < 0)
					{
						return;
					}
				}
				float currentFrame = 0;
				float width;
				float height;
				float totalFrames;
				_FlipbookTexArray.GetDimensions(width, height, totalFrames);
				
				if (_FlipbookStartAndEnd)
				{
					totalFrames -= (totalFrames - min(max(_FlipbookStartFrame, _FlipbookEndFrame), totalFrames));
					totalFrames -= max(0, _FlipbookStartFrame);
				}
				if (!_FlipbookManualFrameControl)
				{
					if (_FlipbookFPS != 0)
					{
						currentFrame = ((_Time.y / (1 / _FlipbookFPS)) + _FlipbookFrameOffset) % totalFrames;
						if (_FlipbookStartAndEnd)
						{
							currentFrame += _FlipbookStartFrame;
						}
					}
				}
				else
				{
					currentFrame = fmod(_FlipbookCurrentFrame, totalFrames);
				}
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					if (_FlipbookChronotensityEnabled)
					{
						currentFrame += AudioLinkGetChronoTime(_FlipbookChronoType, _FlipbookChronotensityBand) * _FlipbookChronotensitySpeed;
					}
					currentFrame += lerp(_AudioLinkFlipbookFrame.x, _AudioLinkFlipbookFrame.y, poiMods.audioLink[_AudioLinkFlipbookFrameBand]);
					float totalFramesAL = totalFrames;
					if (_FlipbookStartAndEnd)
					{
						totalFramesAL += max(0, _FlipbookStartFrame);
					}
					currentFrame %= totalFramesAL;
				}
				#endif
				flipBookPixel = UNITY_SAMPLE_TEX2DARRAY(_FlipbookTexArray, float3(TRANSFORM_TEX(newUV, _FlipbookTexArray) + _Time.x * _FlipbookTexArrayPan, floor(currentFrame)));
				UNITY_BRANCH
				if (_FlipbookCrossfadeEnabled)
				{
					float totalFramesCF = totalFrames;
					if (_FlipbookStartAndEnd)
					{
						totalFramesCF += max(0, _FlipbookStartFrame);
					}
					float4 flipbookNextPixel = UNITY_SAMPLE_TEX2DARRAY(_FlipbookTexArray, float3(TRANSFORM_TEX(newUV, _FlipbookTexArray) + _Time.x * _FlipbookTexArrayPan, floor((currentFrame + 1) % totalFramesCF)));
					flipBookPixel = lerp(flipBookPixel, flipbookNextPixel, smoothstep(_FlipbookCrossfadeRange.x, _FlipbookCrossfadeRange.y, frac(currentFrame)));
				}
				
				UNITY_BRANCH
				if (_FlipbookIntensityControlsAlpha)
				{
					flipBookPixel.a = poiMax(flipBookPixel.rgb);
				}
				UNITY_BRANCH
				if (_FlipbookColorReplaces)
				{
					flipBookPixel.rgb = poiThemeColor(poiMods, _FlipbookColor.rgb, _FlipbookColorThemeIndex);
				}
				else
				{
					flipBookPixel.rgb *= poiThemeColor(poiMods, _FlipbookColor.rgb, _FlipbookColorThemeIndex);
				}
				
				UNITY_BRANCH
				if (_FlipbookHueShiftEnabled)
				{
					flipBookPixel.rgb = hueShift(flipBookPixel.rgb, _FlipbookHueShift + _Time.x * _FlipbookHueShiftSpeed);
				}
				half flipbookAlpha = 1;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookAlpha += saturate(lerp(_AudioLinkFlipbookAlpha.x, _AudioLinkFlipbookAlpha.y, poiMods.audioLink[_AudioLinkFlipbookAlphaBand]));
				}
				#endif
				
				#if !defined(POI_PASS_OUTLINE) && !defined(UNITY_PASS_SHADOWCASTER)
				
				poiFragData.baseColor = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, flipBookPixel.rgb, _FlipbookBlendType), flipBookPixel.a * _FlipbookColor.a * _FlipbookReplace * flipBookMask * flipbookAlpha);
				
				float flipbookEmissionStrength = _FlipbookEmissionStrength;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					flipbookEmissionStrength += max(lerp(_AudioLinkFlipbookEmission.x, _AudioLinkFlipbookEmission.y, poiMods.audioLink[_AudioLinkFlipbookEmissionBand]), 0);
				}
				#endif
				
				poiFragData.emission += lerp(0, flipBookPixel.rgb * flipbookEmissionStrength, flipBookPixel.a * _FlipbookColor.a * flipBookMask * flipbookAlpha);
				
				#endif
				
				UNITY_BRANCH
				if (_FlipbookAlphaControlsFinalAlpha)
				{
					poiFragData.alpha = lerp(poiFragData.alpha, flipBookPixel.a * _FlipbookColor.a, flipBookMask);
				}
				#endif
			}
			
			#endif
			//endex
			
			//ifex _EnableMirrorOptions==0
			#ifdef POI_MIRROR
			void applyMirror(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float inMirror = 0;
				// VRC
				if (_VisibilityMode == 1)
				{
					inMirror = VRCMirrorMode() > 0;
				}
				// Generic (CVR, etc)
				else
				{
					inMirror = IsInMirror();
				}
				
				#if (defined(POI_PASS_BASE) || defined(POI_PASS_ADD))
				#if defined(PROP_MIRRORTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 mirrorTexture = POI2D_SAMPLER_PAN(_MirrorTexture, _MainTex, poiUV(poiMesh.uv[_MirrorTextureUV], _MirrorTexture_ST), _MirrorTexturePan);
				if (inMirror && _MirrorTextureEnabled || _MirrorTextureForceEnabled)
				{
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, customBlend(poiFragData.baseColor.rgb, mirrorTexture.rgb, _MirrorTextureBlendType), mirrorTexture.a * _MirrorColor.a);
					poiFragData.baseColor.rgb *= lerp(1, poiThemeColor(poiMods, _MirrorColor.rgb, _MirrorColorThemeIndex), _MirrorColor.a);
				}
				#else
				if (inMirror && _MirrorTextureEnabled || _MirrorTextureForceEnabled)
				{
					poiFragData.baseColor.rgb *= lerp(1, poiThemeColor(poiMods, _MirrorColor.rgb, _MirrorColorThemeIndex), _MirrorColor.a);
				}
				#endif
				#endif
			}
			#endif
			//endex
			
			//ifex _EnableTouchGlow==0
			#ifdef GRAIN
			void applyDepthFX(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float3 touchEmission = 0;
				
				float perspectiveDivide = 1.0f / poiCam.clipPos.w;
				float4 direction = poiCam.worldDirection * perspectiveDivide;
				float2 screenPos = poiCam.posScreenSpace * perspectiveDivide;
				float z = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, screenPos);
				
				#if UNITY_REVERSED_Z
				if (z == 0)
				#else
				if (z == 1)
				#endif
				return;
				
				float depth = CorrectedLinearEyeDepth(z, direction.w);
				float3 worldpos = direction * depth + _WorldSpaceCameraPos.xyz;
				/*
				finalColor.rgb = frac(worldpos);
				return;
				*/
				
				float diff = distance(worldpos, poiMesh.worldPos);
				//poiFragData.finalColor = diff;
				
				#if defined(PROP_DEPTHMASK) || !defined(OPTIMIZER_ENABLED)
				float depthMask = POI2D_SAMPLER_PAN(_DepthMask, _MainTex, poiUV(poiMesh.uv[_DepthMaskUV], _DepthMask_ST), _DepthMaskPan)[_DepthMaskChannel];
				#else
				float depthMask = 1;
				#endif
				
				if (_DepthMaskGlobalMask > 0)
				{
					depthMask = maskBlend(depthMask, poiMods.globalMask[_DepthMaskGlobalMask - 1], _DepthMaskGlobalMaskBlendType);
				}
				
				if (_DepthColorToggle)
				{
					float colorBlendAlpha = lerp(_DepthColorMinValue, _DepthColorMaxValue, remapClamped(_DepthColorMinDepth, _DepthColorMaxDepth, diff));
					
					#if defined(PROP_DEPTHTEXTURE) || !defined(OPTIMIZER_ENABLED)
					float2 depthTextureUV = float2(0, 0);
					if (_DepthTextureUV == 8)
					{
						depthTextureUV = lerp(0, 1, remapClamped(_DepthColorMinDepth, _DepthColorMaxDepth, diff));
					}
					else
					{
						depthTextureUV = poiMesh.uv[_DepthTextureUV];
					}
					float3 depthColor = POI2D_SAMPLER_PAN(_DepthTexture, _MainTex, poiUV(depthTextureUV, _DepthTexture_ST), _DepthTexturePan).rgb * poiThemeColor(poiMods, _DepthColor, _DepthColorThemeIndex);
					#else
					float3 depthColor = poiThemeColor(poiMods, _DepthColor, _DepthColorThemeIndex);
					#endif
					
					switch(_DepthColorBlendMode)
					{
						case 0:
						{
							poiFragData.baseColor = lerp(poiFragData.baseColor, depthColor, colorBlendAlpha * depthMask);
							break;
						}
						case 1:
						{
							poiFragData.baseColor *= lerp(1, depthColor, colorBlendAlpha * depthMask);
							break;
						}
						case 2:
						{
							poiFragData.baseColor = saturate(poiFragData.baseColor + lerp(0, depthColor, colorBlendAlpha * depthMask));
							break;
						}
					}
					poiFragData.emission += depthColor * colorBlendAlpha * _DepthEmissionStrength * depthMask;
				}
				
				if (_DepthAlphaToggle)
				{
					poiFragData.alpha *= lerp(poiFragData.alpha, saturate(lerp(_DepthAlphaMinValue, _DepthAlphaMaxValue, remapClamped(_DepthAlphaMinDepth, _DepthAlphaMaxDepth, diff))), depthMask);
				}
			}
			#endif
			//endex
			
			// normal correct code from https://github.com/yoship1639/UniToon (MIT)
			//ifex _NormalCorrect==0
			#ifdef POI_NORMALCORRECT
			void applyNormalCorrect(inout VertexOut i)
			{
				float3 normalCorrectObject = i.localPos.xyz - _NormalCorrectOrigin;
				normalCorrectObject.y = 0;
				normalCorrectObject = normalize(normalCorrectObject);
				float3 normalCorrectWorld = UnityObjectToWorldDir(normalCorrectObject);
				i.normal.xyz = normalize(lerp(i.normal.xyz, normalCorrectWorld, _NormalCorrectAmount));
				//i.objNormal.xyz = normalize(lerp(i.objNormal.xyz, normalCorrectObject, _NormalCorrectAmount));
			}
			#endif
			//endex
			
			//ifex _VideoEffectsEnable==0
			#ifdef POI_VIDEO_EFFECTS
			float3 applyBacklight(float3 videoTexture, half backlightStrength)
			{
				return max(backlightStrength, videoTexture.rgb);
			}
			
			float3 applyViewAngleTN(float3 videoTexture, PoiCam poiCam, PoiMesh poiMesh)
			{
				float3 reflectionVector = normalize(reflect(poiCam.viewDir.rgb, poiMesh.normals[1].rgb));
				float upwardShift = dot(reflectionVector, poiMesh.binormal[0]);
				upwardShift = pow(upwardShift, 1);
				float sideShift = dot(reflectionVector, poiMesh.tangent[0]);
				sideShift *= pow(sideShift, 3);
				#if !UNITY_COLORSPACE_GAMMA
				videoTexture = LinearToGammaSpace(videoTexture);
				#endif
				videoTexture = saturate(lerp(half3(0.5, 0.5, 0.5), videoTexture, upwardShift + 1));
				#if !UNITY_COLORSPACE_GAMMA
				videoTexture = GammaToLinearSpace(videoTexture);
				#endif
				videoTexture = (lerp(videoTexture, videoTexture.gbr, sideShift));
				return videoTexture;
			}
			
			float calculateCRTPixelBrightness(float2 uv)
			{
				float totalPixels = _VideoResolution.x * _VideoResolution.y;
				float2 uvPixel = float2((floor((1 - uv.y) * _VideoResolution.y)) / _VideoResolution.y, (floor(uv.x * _VideoResolution.x)) / _VideoResolution.x);
				float currentPixelNumber = _VideoResolution.x * (_VideoResolution.y * uvPixel.x) + _VideoResolution.y * uvPixel.y;
				float currentPixelAlpha = currentPixelNumber / totalPixels;
				half electronBeamAlpha = frac(_Time.y * _VideoCRTRefreshRate);
				float electronBeamPixelNumber = totalPixels * electronBeamAlpha;
				
				float DistanceInPixelsFromCurrentElectronBeamPixel = 0;
				if (electronBeamPixelNumber >= currentPixelNumber)
				{
					DistanceInPixelsFromCurrentElectronBeamPixel = electronBeamPixelNumber - currentPixelNumber;
				}
				else
				{
					DistanceInPixelsFromCurrentElectronBeamPixel = electronBeamPixelNumber + (totalPixels - currentPixelNumber);
				}
				float CRTFrameTime = 1 / _VideoCRTRefreshRate;
				float timeSincecurrentPixelWasHitByElectronBeam = (DistanceInPixelsFromCurrentElectronBeamPixel / totalPixels);
				
				return saturate(_VideoCRTPixelEnergizedTime - timeSincecurrentPixelWasHitByElectronBeam);
			}
			
			void applyContrastSettings(inout float3 pixel)
			{
				#if !UNITY_COLORSPACE_GAMMA
				pixel = LinearToGammaSpace(pixel);
				#endif
				pixel = saturate(lerp(half3(0.5, 0.5, 0.5), pixel, _VideoContrast + 1));
				#if !UNITY_COLORSPACE_GAMMA
				pixel = GammaToLinearSpace(pixel);
				#endif
			}
			
			void applySaturationSettings(inout float3 pixel)
			{
				pixel = lerp(pixel.rgb, dot(pixel.rgb, float3(0.3, 0.59, 0.11)), - (_VideoSaturation));
			}
			
			void applyVideoSettings(inout float3 pixel)
			{
				applySaturationSettings(pixel);
				applyContrastSettings(pixel);
			}
			
			void calculateLCD(inout float4 videoTexture, float3 pixels)
			{
				videoTexture.rgb = applyBacklight(videoTexture, _VideoBacklight * .01);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateTN(inout float4 videoTexture, float3 pixels, PoiCam poiCam, PoiMesh poiMesh)
			{
				videoTexture.rgb = applyBacklight(videoTexture, _VideoBacklight * .01);
				videoTexture.rgb = applyViewAngleTN(videoTexture, poiCam, poiMesh);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateCRT(inout float4 videoTexture, float3 pixels, float2 uv)
			{
				float brightness = calculateCRTPixelBrightness(uv);
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * brightness * _VideoBacklight;
			}
			void calculateOLED(inout float4 videoTexture, float3 pixels)
			{
				applyVideoSettings(videoTexture.rgb);
				videoTexture.rgb = videoTexture * pixels * _VideoBacklight;
			}
			void calculateGameboy(inout float4 videoTexture)
			{
				applyVideoSettings(videoTexture.rgb);
				// half brightness = saturate((videoTexture.r + videoTexture.g + videoTexture.b) * .3333333);
				half brightness = LinearRgbToLuminance(LinearToGammaSpace(videoTexture.rgb));
				#if defined(PROP_VIDEOGAMEBOYRAMP) || !defined(OPTIMIZER_ENABLED)
				videoTexture.rgb = tex2Dlod(_VideoGameboyRamp, float4(brightness.xx, 0, 0));
				#else
				float3 dg = float3(0.00392156863, 0.0392156863, 0.00392156863);
				float3 lg = float3(0.333333333, 0.5, 0.00392156863);
				videoTexture.rgb = lerp(dg, lg, brightness);
				#endif
			}
			void calculateProjector(inout float4 videoTexture)
			{
				applyVideoSettings(videoTexture.rgb);
				
				float3 projectorColor = videoTexture * _VideoBacklight;
				videoTexture.r = clamp(projectorColor.r, videoTexture.r, 1000);
				videoTexture.g = clamp(projectorColor.g, videoTexture.g, 1000);
				videoTexture.b = clamp(projectorColor.b, videoTexture.b, 1000);
			}
			
			void applyVideoEffectsMainTex(inout float4 mainTexture, in PoiMesh poiMesh)
			{
				float2 uvs = poiMesh.uv[_MainTexUV];
				if (_VideoPixelateToResolution)
				{
					float2 originalUVs = uvs;
					uvs = sharpSample(float4(1 / _VideoResolution.xy, _VideoResolution.xy), uvs);
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
					mainTexture = _MainTex.SampleGrad(sampler_MainTex, uvs, ddx(originalUVs), ddy(originalUVs));
				}
			}
			void applyVideoEffects(inout PoiFragData poiFragData, in PoiCam poiCam, in PoiMesh poiMesh, in PoiLight poiLight, in PoiMods poiMods)
			{
				#if defined(PROP_VIDEOPIXELTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float3 pixels = tex2D(_VideoPixelTexture, poiUV(poiMesh.uv[_VideoPixelTextureUV], _VideoPixelTexture_ST) * _VideoResolution);
				#else
				float3 pixels = 1;
				#endif
				float2 uvs = poiMesh.uv[_MainTexUV];
				if (_VideoPixelateToResolution)
				{
					uvs = sharpSample(float4(1 / _VideoResolution.xy, _VideoResolution.xy), uvs);
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
				}
				else
				{
					uvs = poiUV(uvs, _MainTex_ST) + _Time.x * _MainTexPan;
				}
				float4 modifiedVideoTexture = 0;
				modifiedVideoTexture.rgb = poiFragData.baseColor;
				modifiedVideoTexture.a = poiFragData.alpha;
				
				// UNITY_BRANCH
				// if(_VideoRepeatVideoTexture == 1)
				// {
				// 	if(poiMesh.uv[_VideoUVNumber].x > 1 || poiMesh.uv[_VideoUVNumber].x < 0 || poiMesh.uv[_VideoUVNumber].y > 1 || poiMesh.uv[_VideoUVNumber].y < 0)
				// 	{
				// 		return;
				// 	}
				// }
				
				switch(_VideoType)
				{
					case 0: // LCD
					
					{
						calculateLCD(modifiedVideoTexture, pixels);
						break;
					}
					case 1: // TN
					
					{
						calculateTN(modifiedVideoTexture, pixels, poiCam, poiMesh);
						break;
					}
					case 2: // CRT
					
					{
						calculateCRT(modifiedVideoTexture, pixels, uvs);
						break;
					}
					case 3: // OLED
					
					{
						calculateOLED(modifiedVideoTexture, pixels);
						break;
					}
					case 4: // Gameboy
					
					{
						calculateGameboy(modifiedVideoTexture);
						break;
					}
					case 5: // Projector
					
					{
						calculateProjector(modifiedVideoTexture);
						break;
					}
				}
				#if defined(PROP_VIDEOMASKTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float screenMask = POI2D_SAMPLER_PAN(_VideoMaskTexture, _MainTex, poiUV(poiMesh.uv[_VideoMaskTextureUV], _VideoMaskTexture_ST), _VideoMaskTexturePan)[_VideoMaskTextureChannel];
				#else
				float screenMask = 1;
				#endif
				
				poiFragData.baseColor = lerp(poiFragData.baseColor, modifiedVideoTexture, screenMask);
				// UNITY_BRANCH
				if (_VideoEmissionEnabled)
				{
					poiFragData.emission += modifiedVideoTexture.rgb * screenMask;
				}
			}
			#endif
			//endex
			
			//ifex _BacklightEnabled!=1
			#ifdef POI_BACKLIGHT
			void ApplyBacklight(inout PoiFragData poiFragData, in PoiMesh poiMesh, inout PoiLight poiLight, in PoiCam poiCam, inout PoiMods poiMods)
			{
				
				// Color
				float3 backlightColor = _BacklightColor.rgb;
				#if defined(PROP_BACKLIGHTCOLORTEX) || !defined(OPTIMIZER_ENABLED)
				backlightColor *= POI2D_SAMPLER_PAN(_BacklightColorTex, _MainTex, poiUV(poiMesh.uv[_BacklightColorTexUV], _BacklightColorTex_ST), _BacklightColorTexPan).rgb;
				#endif
				
				float3 normal = lerp(poiMesh.normals[0], poiMesh.normals[1], _BacklightNormalStrength);
				// Factor
				float3 headDir = normalize(getCameraPosition() - poiMesh.worldPos.xyz);
				float headDotLight = dot(headDir, poiLight.direction);
				float backlightFactor = pow(saturate(-headDotLight * 0.5 + 0.5), max(0, _BacklightDirectivity));
				float backlightLN = dot(normalize(-headDir * _BacklightViewStrength + poiLight.direction), normal) * 0.5 + 0.5;
				#if defined(POINT) || defined(SPOT)
				if (_BacklightReceiveShadow) backlightLN *= saturate(poiLight.additiveShadow);
				#else
				if (_BacklightReceiveShadow) backlightLN *= saturate(poiLight.attenuation);
				#endif
				backlightLN = poiEdgeLinear(backlightLN, _BacklightBorder, _BacklightBlur);
				float backlight = saturate(backlightFactor * backlightLN);
				backlight = !poiMesh.isFrontFace && _BacklightBackfaceMask ? 0.0 : backlight;
				
				// Blend
				backlightColor = lerp(backlightColor, backlightColor * poiFragData.baseColor, _BacklightMainStrength);
				poiLight.finalLightAdd += backlight * backlightColor * poiLight.directColor;
			}
			#endif
			//endex
			
			//ifex _VoronoiEnabled!=1
			#ifdef POI_VORONOI
			//1/7
			#define VoronoiK 0.142857142857
			//3/7
			#define VoronoiKo 0.428571428571
			// Permutation polynomial: (34x^2 + x) mod 289
			float3 Permutation(float3 x)
			{
				return glsl_mod((34.0 * x + 1.0) * x, 289.0);
			}
			
			float3 inoise(float3 P, float jitter, out float3 randomPoint)
			{
				P *= 0.7f; // Scale adjustment
				float3 Pi = glsl_mod(floor(P), 289.0);
				float3 Pf = frac(P);
				float3 oi = float3(-1.0, 0.0, 1.0);
				float3 of = float3(-0.5, 0.5, 1.5);
				float3 px = Permutation(Pi.x + oi);
				float3 py = Permutation(Pi.y + oi);
				float3 pz = Permutation(Pi.z + oi);
				
				float3 p, ox, oy, oz, dx, dy, dz;
				float3 F = 1e6;
				
				[unroll(3)]
				for (int i = 0; i < 3; i++)
				{
					[unroll(3)]
					for (int j = 0; j < 3; j++)
					{
						[unroll(3)]
						for (int k = 0; k < 3; k++)
						{
							p = Permutation(px[i] + py[j] + pz[k] + oi); // pij1, pij2, pij3
							float3 ogp = p;
							
							ox = frac(p * VoronoiK) - VoronoiKo;
							oy = glsl_mod(floor(p * VoronoiK), 7.0) * VoronoiK - VoronoiKo;
							
							p = Permutation(p);
							oz = frac(p * VoronoiK) - VoronoiKo;
							
							dx = Pf.x - of[i] + jitter * ox;
							dy = Pf.y - of[j] + jitter * oy;
							dz = Pf.z - of[k] + jitter * oz;
							
							float3 d = dx * dx + dy * dy + dz * dz; // dij1, dij2 and dij3, squared
							
							//Find lowest and second lowest distances
							for (int n = 0; n < 3; n++)
							{
								if (d[n] < F[0])
								{
									F[1] = F[0];
									F[0] = d[n];
									randomPoint = p;
								}
								else if (d[n] < F[1])
								{
									F[1] = d[n];
								}
							}
						}
					}
				}
				
				return F;
			}
			
			float voronoi2D(in float2 x, float scale, float2 speed, out float2 randomPoint)
			{
				x *= scale;
				x += speed * _Time.x;
				float2 n = floor(x);
				float2 f = frac(x);
				
				// first pass: regular voronoi
				float2 mg, mr;
				float md = 8.0;
				for (int j = -1; j <= 1; j++)
				{
					for (int i = -1; i <= 1; i++)
					{
						float2 g = float2(float(i), float(j));
						float2 o = random2(n + g);
						float2 currentPoint = o;
						
						float2 r = g + o - f;
						float d = dot(r, r);
						
						if (d < md)
						{
							md = d;
							mr = r;
							mg = g;
							randomPoint.xy = currentPoint;
						}
					}
				}
				
				// second pass: distance to borders
				md = 8.0;
				for (int r = -2; r <= 2; r++)
				{
					for (int q = -2; q <= 2; q++)
					{
						float2 g = mg + float2(float(q), float(r));
						float2 o = random2(n + g);
						
						float2 r = g + o - f;
						
						if (dot(mr - r, mr - r) > 0.00001)
						{
							md = min(md, dot(0.5 * (mr + r), normalize(r - mr)));
						}
					}
				}
				return md;
			}
			
			float voronoi3D(in float3 x, float scale, float3 speed, out float3 randomPoint)
			{
				x *= scale;
				x += speed * _Time.x;
				float3 n = floor(x);
				float3 f = frac(x);
				
				// first pass: regular voronoi
				float3 mg, mr;
				float md = 8.0;
				for (int j = -1; j <= 1; j++)
				{
					for (int i = -1; i <= 1; i++)
					{
						for (int h = -1; h <= 1; h++)
						{
							float3 g = float3(float(h), float(i), float(j));
							float3 o = random3(n + g);
							float3 currentPoint = o;
							
							float3 r = g + o - f;
							float d = dot(r, r);
							
							if (d < md)
							{
								md = d;
								mr = r;
								mg = g;
								randomPoint = currentPoint;
							}
						}
					}
				}
				
				// second pass: distance to borders
				md = 8.0;
				for (int r = -2; r <= 2; r++)
				{
					for (int q = -2; q <= 2; q++)
					{
						for (int p = -2; p <= 2; p++)
						{
							float3 g = mg + float3(float(p), float(q), float(r));
							float3 o = random3(n + g);
							
							float3 r = g + o - f;
							
							if (dot(mr - r, mr - r) > 0.00001)
							{
								md = min(md, dot(0.5 * (mr + r), normalize(r - mr)));
							}
						}
					}
				}
				return md;
			}
			
			// fracal sum, range -1.0 - 1.0
			float VoronoiNoise_Octaves(float3 p, float scale, float3 speed, int octaveNumber, float octaveScale, float octaveAttenuation, float jitter, float time, out float3 randomPoint)
			{
				float freq = scale;
				float weight = 1.0f;
				float sum = 0;
				// Uncomment when the octave stuff is actually used
				// for (int i = 0; i < octaveNumber; i ++)
				// {
				float3 F = inoise(p * freq + time * speed, jitter, randomPoint) * weight;
				
				sum += sqrt(F[0]);
				
				// 	freq *= octaveScale;
				// 	weight *= 1.0f - octaveAttenuation;
				// }
				return sum;
			}
			
			float VoronoiNoiseDiff_Octaves(float3 p, float scale, float3 speed, int octaveNumber, float octaveScale, float octaveAttenuation, float jitter, float time, out float3 randomPoint)
			{
				float freq = scale;
				float weight = 1.0f;
				float sum = 0;
				// Uncomment when the octave stuff is actually used
				// for (int i = 0; i < octaveNumber; i ++)
				// {
				float3 F = inoise(p * freq + time * speed, jitter, randomPoint) * weight;
				
				sum += sqrt(F[1]) - sqrt(F[0]);
				
				// freq *= octaveScale;
				// weight *= 1.0f - octaveAttenuation;
				// }
				return sum;
			}
			
			void ApplyVoronoi(inout PoiFragData poiFragData, in PoiMesh poiMesh, in PoiMods poiMods)
			{
				float voronoiOctaveNumber = 1;
				float voronoiOctaveScale = 1;
				float voronoiOctaveAttenuation = 1;
				float3 randomPoint = 0;
				
				float voronoi = 0;
				
				float3 position = 0;
				
				UNITY_BRANCH
				if (_VoronoiSpace == 0)
				{
					position = poiMesh.localPos;
				}
				UNITY_BRANCH
				if (_VoronoiSpace == 1)
				{
					position = poiMesh.worldPos;
				}
				UNITY_BRANCH
				if (_VoronoiSpace == 2)
				{
					position = float3(poiMesh.uv[0].x, poiMesh.uv[0].y, 0);
				}
				#if defined(PROP_VORONOIMASK) || !defined(OPTIMIZER_ENABLED)
				float mask = POI2D_SAMPLER_PAN(_VoronoiMask, _MainTex, poiUV(poiMesh.uv[_VoronoiMaskUV], _VoronoiMask_ST), _VoronoiMaskPan)[_VoronoiMaskChannel];
				#else
				float mask = 1;
				#endif
				
				if (_VoronoiGlobalMask > 0)
				{
					mask = maskBlend(mask, poiMods.globalMask[_VoronoiGlobalMask - 1], _VoronoiGlobalMaskBlendType);
				}
				
				#if defined(PROP_VORONOINOISE) || !defined(OPTIMIZER_ENABLED)
				float edgeNoise = POI2D_SAMPLER_PAN(_VoronoiNoise, _MainTex, poiUV(poiMesh.uv[_VoronoiNoiseUV], _VoronoiNoise_ST), _VoronoiNoisePan)[_VoronoiNoiseChannel];
				#else
				float edgeNoise = 0;
				#endif
				edgeNoise *= _VoronoiNoiseIntensity;
				
				float3 voronoiSpeed = _VoronoiSpeed * 10;
				#ifdef POI_AUDIOLINK
				if (poiMods.audioLinkAvailable)
				{
					position.x += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedXType, _AudioLinkVoronoiChronoSpeedXBand) * _AudioLinkVoronoiChronoSpeedXSpeed * 0.01;
					position.y += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedYType, _AudioLinkVoronoiChronoSpeedYBand) * _AudioLinkVoronoiChronoSpeedYSpeed * 0.01;
					position.z += AudioLinkGetChronoTime(_AudioLinkVoronoiChronoSpeedZType, _AudioLinkVoronoiChronoSpeedZBand) * _AudioLinkVoronoiChronoSpeedZSpeed * 0.01;
				}
				#endif
				
				if (_VoronoiType == 0) // Basic
				
				{
					voronoi = voronoi2D(position.xy, _VoronoiScale, voronoiSpeed, randomPoint.xy);
					voronoi *= 1.55; // Range adjustment
					
				}
				if (_VoronoiType == 1) // Diff
				
				{
					voronoi = VoronoiNoiseDiff_Octaves(position, _VoronoiScale, voronoiSpeed, voronoiOctaveNumber, voronoiOctaveScale, voronoiOctaveAttenuation, 1, _Time.x, randomPoint);
				}
				if (_VoronoiType == 2) // Fixed Border
				
				{
					voronoi = voronoi3D(position, _VoronoiScale, voronoiSpeed, randomPoint);
					voronoi *= 1.8; // Range adjustment
					
				}
				
				float4 outerColor = _VoronoiOuterColor;
				float4 innerColor = _VoronoiInnerColor;
				
				if (_VoronoiEnableRandomCellColor == 1)
				{
					float3 rando = random3(randomPoint);
					fixed hue = rando.x;
					fixed saturation = lerp(_VoronoiRandomMinMaxSaturation.x, _VoronoiRandomMinMaxSaturation.y, rando.y);
					fixed value = lerp(_VoronoiRandomMinMaxBrightness.x, _VoronoiRandomMinMaxBrightness.y, rando.z);
					float3 hsv = float3(hue, saturation, value);
					innerColor.rgb = HSVtoRGB(hsv);
				}
				voronoi = pow(voronoi, _VoronoiPower);
				float2 voronoiGradient = _VoronoiGradient.xy + edgeNoise;
				#ifdef POI_AUDIOLINK
				voronoiGradient.x += _AudioLinkVoronoiGradientMinAdd * poiMods.audioLink[_AudioLinkVoronoiGradientMinAddBand];
				voronoiGradient.y -= _AudioLinkVoronoiGradientMaxAdd * poiMods.audioLink[_AudioLinkVoronoiGradientMaxAddBand];
				#endif
				float ramp = smoothstep(voronoiGradient.x, voronoiGradient.y, voronoi);
				
				if (_VoronoiBlend == 0)
				{
					float4 voronoiColor = lerp(outerColor, innerColor, ramp);
					poiFragData.baseColor.rgb = lerp(poiFragData.baseColor.rgb, voronoiColor, min(mask * voronoiColor.a, 0.99999));
					if (_VoronoiAffectsMaterialAlpha)
					{
						poiFragData.alpha = lerp(poiFragData.alpha, voronoiColor.a, min(mask, 0.99999));
					}
				}
				float outerEmissionStrength = _VoronoiOuterEmissionStrength;
				float innerEmissionStrength = _VoronoiInnerEmissionStrength;
				#ifdef POI_AUDIOLINK
				outerEmissionStrength += lerp(_AudioLinkVoronoiOuterEmission.x, _AudioLinkVoronoiOuterEmission.y, poiMods.audioLink[_AudioLinkVoronoiOuterEmissionBand]);
				innerEmissionStrength += lerp(_AudioLinkVoronoiInnerEmission.x, _AudioLinkVoronoiInnerEmission.y, poiMods.audioLink[_AudioLinkVoronoiInnerEmissionBand]);
				#endif
				float4 voronoiEmissionColor = lerp(outerColor, innerColor, ramp);
				voronoiEmissionColor.rgb *= lerp(outerEmissionStrength, innerEmissionStrength, ramp);
				poiFragData.emission += voronoiEmissionColor.rgb * mask * voronoiEmissionColor.a;
			}
			#endif
			//endex
			
			float4 frag(VertexOut i, uint facing : SV_IsFrontFace) : SV_Target
			{
				//ifex _EnableDepthBulge==0
				#ifdef POI_DEPTHBULGE
				clip(-1);
				return 0;
				#endif
				//endex
				
				//ifex _EnableTouchGlow==0
				#ifdef GRAIN
				clip(-1);
				return 0;
				#endif
				//endex
				
				UNITY_SETUP_INSTANCE_ID(i);
				UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
				
				PoiMesh poiMesh;
				PoiInitStruct(PoiMesh, poiMesh);
				
				PoiLight poiLight;
				PoiInitStruct(PoiLight, poiLight);
				
				PoiVertexLights poiVertexLights;
				PoiInitStruct(PoiVertexLights, poiVertexLights);
				
				PoiCam poiCam;
				PoiInitStruct(PoiCam, poiCam);
				
				PoiMods poiMods;
				PoiInitStruct(PoiMods, poiMods);
				poiMods.globalEmission = 1;
				
				PoiFragData poiFragData;
				poiFragData.smoothness = 1;
				poiFragData.smoothness2 = 1;
				poiFragData.metallic = 1;
				poiFragData.specularMask = 1;
				poiFragData.reflectionMask = 1;
				poiFragData.emission = 0;
				poiFragData.baseColor = float3(0, 0, 0);
				poiFragData.finalColor = float3(0, 0, 0);
				poiFragData.alpha = 1;
				poiFragData.toggleVertexLights = 0;
				
				#ifdef POI_UDIMDISCARD
				applyUDIMDiscard(i);
				#endif
				
				//ifex _NormalCorrect==0
				#ifdef POI_NORMALCORRECT
				applyNormalCorrect(i);
				#endif
				//endex
				
				// Mesh Data
				//poiMesh.objectPosition = mul(unity_ObjectToWorld, float3(0, 0, 0)).xyz;
				poiMesh.objectPosition = mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
				poiMesh.objNormal = mul(unity_WorldToObject, i.normal);
				poiMesh.normals[0] = i.normal;
				poiMesh.tangent[0] = i.tangent.xyz;
				poiMesh.binormal[0] = cross(i.normal, i.tangent.xyz) * (i.tangent.w * unity_WorldTransformParams.w);
				poiMesh.worldPos = i.worldPos.xyz;
				poiMesh.localPos = i.localPos.xyz;
				poiMesh.vertexColor = i.vertexColor;
				poiMesh.isFrontFace = facing;
				poiMesh.dx = ddx(poiMesh.uv[0]);
				poiMesh.dy = ddy(poiMesh.uv[0]);
				
				#ifndef POI_PASS_OUTLINE
				if (!poiMesh.isFrontFace && _FlipBackfaceNormals)
				{
					poiMesh.normals[0] *= -1;
					poiMesh.tangent[0] *= -1;
					poiMesh.binormal[0] *= -1;
				}
				#endif
				
				poiCam.viewDir = !IsOrthographicCamera() ? normalize(_WorldSpaceCameraPos - i.worldPos.xyz) : normalize(UNITY_MATRIX_I_V._m02_m12_m22);
				float3 tanToWorld0 = float3(poiMesh.tangent[0].x, poiMesh.binormal[0].x, poiMesh.normals[0].x);
				float3 tanToWorld1 = float3(poiMesh.tangent[0].y, poiMesh.binormal[0].y, poiMesh.normals[0].y);
				float3 tanToWorld2 = float3(poiMesh.tangent[0].z, poiMesh.binormal[0].z, poiMesh.normals[0].z);
				float3 ase_tanViewDir = tanToWorld0 * poiCam.viewDir.x + tanToWorld1 * poiCam.viewDir.y + tanToWorld2 * poiCam.viewDir.z;
				poiCam.tangentViewDir = normalize(ase_tanViewDir);
				
				// 0-3 UV0-UV3
				// 4 Panosphere UV
				// 5 world pos xz
				// 6 Polar UV
				// 6 Distorted UV
				#if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
				poiMesh.lightmapUV = i.lightmapUV;
				#endif
				poiMesh.parallaxUV = poiCam.tangentViewDir.xy / max(poiCam.tangentViewDir.z, 0.0001);
				poiMesh.uv[0] = i.uv[0].xy;
				poiMesh.uv[1] = i.uv[0].zw;
				poiMesh.uv[2] = i.uv[1].xy;
				poiMesh.uv[3] = i.uv[1].zw;
				poiMesh.uv[4] = poiMesh.uv[0];
				poiMesh.uv[5] = poiMesh.uv[0];
				poiMesh.uv[6] = poiMesh.uv[0];
				poiMesh.uv[7] = poiMesh.uv[0];
				poiMesh.uv[8] = poiMesh.uv[0];
				
				poiMesh.uv[4] = calculatePanosphereUV(poiMesh);
				poiMesh.uv[5] = calculateWorldUV(poiMesh);
				poiMesh.uv[6] = calculatePolarCoordinate(poiMesh);
				poiMesh.uv[8] = calculatelocalUV(poiMesh);
				//ifex _EnableDistortion==0
				#ifdef USER_LUT
				poiMesh.uv[7] = distortedUV(poiMesh);
				#endif
				//endex
				/*
				half3 worldViewUp = normalize(half3(0, 1, 0) - poiCam.viewDir * dot(poiCam.viewDir, half3(0, 1, 0)));
				half3 worldViewRight = normalize(cross(poiCam.viewDir, worldViewUp));
				poiMesh[8] = half2(dot(worldViewRight, poiMesh.normals[_MatcapNormal]), dot(worldViewUp, poiMesh.normals[_MatcapNormal])) * _MatcapBorder + 0.5;
				*/
				
				//ifex _PoiParallax==0
				#ifdef POI_PARALLAX
				#ifndef POI_PASS_OUTLINE
				//return frac(i.tangentViewDir.x);
				//return float4(i.binormal.xyz,1);
				applyParallax(poiMesh, poiLight, poiCam);
				#endif
				#endif
				//endex
				
				poiMods.globalMask[0] = 1;
				poiMods.globalMask[1] = 1;
				poiMods.globalMask[2] = 1;
				poiMods.globalMask[3] = 1;
				poiMods.globalMask[4] = 1;
				poiMods.globalMask[5] = 1;
				poiMods.globalMask[6] = 1;
				poiMods.globalMask[7] = 1;
				poiMods.globalMask[8] = 1;
				poiMods.globalMask[9] = 1;
				poiMods.globalMask[10] = 1;
				poiMods.globalMask[11] = 1;
				poiMods.globalMask[12] = 1;
				poiMods.globalMask[13] = 1;
				poiMods.globalMask[14] = 1;
				poiMods.globalMask[15] = 1;
				//ifex _GlobalMaskTexturesEnable==0
				#ifdef POI_GLOBALMASK_TEXTURES
				ApplyGlobalMaskTextures(poiMesh, poiMods);
				#endif
				//endex
				//ifex _GlobalMaskVertexColorRed==0 && _GlobalMaskVertexColorGreen==0 && _GlobalMaskVertexColorBlue==0 && _GlobalMaskVertexColorAlpha==0
				ApplyGlobalMaskVertexColors(poiMesh, poiMods);
				//endex
				ApplyGlobalMaskModifiers(poiMesh, poiMods, poiCam);
				//ifex _GlobalMaskOptionsEnable==0
				if (_GlobalMaskOptionsEnable)
				{
					ApplyGlobalMaskOptions(poiMods);
				}
				//endex
				
				float2 mainUV = poiUV(poiMesh.uv[_MainTexUV].xy, _MainTex_ST);
				
				if (_MainPixelMode)
				{
					mainUV = sharpSample(_MainTex_TexelSize, mainUV);
				}
				
				float4 mainTexture = POI2D_SAMPLER_PAN_STOCHASTIC(_MainTex, _MainTex, mainUV, _MainTexPan, _MainTexStochastic);
				
				//ifex _VideoEffectsEnable==0
				#ifdef POI_VIDEO_EFFECTS
				if (_VideoEffectsEnable)
				{
					applyVideoEffectsMainTex(mainTexture, poiMesh);
				}
				#endif
				//endex
				
				#if defined(PROP_BUMPMAP) || !defined(OPTIMIZER_ENABLED)
				poiMesh.tangentSpaceNormal = UnpackScaleNormal(POI2D_SAMPLER_PAN_STOCHASTIC(_BumpMap, _MainTex, poiUV(poiMesh.uv[_BumpMapUV].xy, _BumpMap_ST), _BumpMapPan, _BumpMapStochastic), _BumpScale);
				#else
				poiMesh.tangentSpaceNormal = UnpackNormal(float4(0.5, 0.5, 1, 1));
				#endif
				
				//ifex _DetailEnabled==0
				#if defined(FINALPASS) && !defined(UNITY_PASS_SHADOWCASTER) && !defined(POI_PASS_OUTLINE)
				ApplyDetailNormal(poiMods, poiMesh);
				#endif
				//endex
				
				//ifex _RGBMaskEnabled==0
				#if defined(VIGNETTE) && !defined(UNITY_PASS_SHADOWCASTER) && !defined(POI_PASS_OUTLINE)
				calculateRGBNormals(poiMesh, poiMods);
				#endif
				
				//endex
				
				float3 tangentSpaceNormal = UnpackNormal(float4(0.5, 0.5, 1, 1));
				poiMesh.normals[0] = normalize(
				tangentSpaceNormal.x * poiMesh.tangent[0] +
				tangentSpaceNormal.y * poiMesh.binormal[0] +
				tangentSpaceNormal.z * poiMesh.normals[0]
				);
				
				poiMesh.normals[1] = normalize(
				poiMesh.tangentSpaceNormal.x * poiMesh.tangent[0] +
				poiMesh.tangentSpaceNormal.y * poiMesh.binormal[0] +
				poiMesh.tangentSpaceNormal.z * poiMesh.normals[0]
				);
				
				poiMesh.tangent[1] = cross(poiMesh.binormal[0], -poiMesh.normals[1]);
				poiMesh.binormal[1] = cross(-poiMesh.normals[1], poiMesh.tangent[0]);
				
				//ifex _EnableOutlines!=1
				#ifdef POI_PASS_OUTLINE
				poiMesh.normals[1] = poiMesh.normals[0];
				#endif
				//endex
				
				// Camera data
				poiCam.forwardDir = getCameraForward();
				poiCam.worldPos = _WorldSpaceCameraPos;
				poiCam.reflectionDir = reflect(-poiCam.viewDir, poiMesh.normals[1]);
				poiCam.vertexReflectionDir = reflect(-poiCam.viewDir, poiMesh.normals[0]);
				//poiCam.distanceToModel = distance(poiMesh.modelPos, poiCam.worldPos);
				poiCam.clipPos = i.pos;
				poiCam.distanceToVert = distance(poiMesh.worldPos, poiCam.worldPos);
				poiCam.posScreenSpace = poiTransformClipSpacetoScreenSpaceFrag(poiCam.clipPos);
				#if defined(POI_GRABPASS) && defined(POI_PASS_BASE)
				poiCam.screenUV = poiCam.clipPos.xy / poiGetWidthAndHeight(_PoiGrab2);
				#else
				poiCam.screenUV = poiCam.clipPos.xy / _ScreenParams.xy;
				#endif
				#ifdef UNITY_SINGLE_PASS_STEREO
				poiCam.posScreenSpace.x = poiCam.posScreenSpace.x * 0.5;
				#endif
				poiCam.posScreenPixels = calcPixelScreenUVs(poiCam.posScreenSpace);
				poiCam.vDotN = abs(dot(poiCam.viewDir, poiMesh.normals[1]));
				
				poiCam.worldDirection.xyz = poiMesh.worldPos.xyz - poiCam.worldPos;
				poiCam.worldDirection.w = dot(poiCam.clipPos, CalculateFrustumCorrection());
				
				//ifex _EnableAudioLink==0
				#ifdef POI_AUDIOLINK
				SetupAudioLink(poiFragData, poiMods, poiMesh);
				#endif
				//endex
				
				//ifex _BlackLightMaskingEnabled==0
				#ifdef POI_BLACKLIGHTMASKING
				calculateBlackLightMasks(poiMesh, poiMods);
				#endif
				//endex
				
				poiFragData.baseColor = mainTexture.rgb * poiThemeColor(poiMods, _Color.rgb, _ColorThemeIndex);
				poiFragData.alpha = mainTexture.a * _Color.a;
				
				//ifex _MainColorAdjustToggle==0
				#ifdef COLOR_GRADING_HDR
				#if defined(PROP_MAINCOLORADJUSTTEXTURE) || !defined(OPTIMIZER_ENABLED)
				float4 hueShiftAlpha = POI2D_SAMPLER_PAN(_MainColorAdjustTexture, _MainTex, poiUV(poiMesh.uv[_MainColorAdjustTextureUV], _MainColorAdjustTexture_ST), _MainColorAdjustTexturePan);
				#else
				float4 hueShiftAlpha = 1;
				#endif
				
				if (_MainHueGlobalMask > 0)
				{
					hueShiftAlpha.r = maskBlend(hueShiftAlpha.r, poiMods.globalMask[_MainHueGlobalMask - 1], _MainHueGlobalMaskBlendType);
				}
				if (_MainSaturationGlobalMask > 0)
				{
					hueShiftAlpha.b = maskBlend(hueShiftAlpha.b, poiMods.globalMask[_MainSaturationGlobalMask - 1], _MainSaturationGlobalMaskBlendType);
				}
				if (_MainBrightnessGlobalMask > 0)
				{
					hueShiftAlpha.g = maskBlend(hueShiftAlpha.g, poiMods.globalMask[_MainBrightnessGlobalMask - 1], _MainBrightnessGlobalMaskBlendType);
				}
				
				if (_MainHueShiftToggle)
				{
					float shift = _MainHueShift;
					#ifdef POI_AUDIOLINK
					//UNITY_BRANCH
					if (poiMods.audioLinkAvailable && _MainHueALCTEnabled)
					{
						shift += AudioLinkGetChronoTime(_MainALHueShiftCTIndex, _MainALHueShiftBand) * _MainHueALMotionSpeed;
					}
					#endif
					if (_MainHueShiftReplace)
					{
						poiFragData.baseColor = lerp(poiFragData.baseColor, hueShift(poiFragData.baseColor, shift + _MainHueShiftSpeed * _Time.x), hueShiftAlpha.r);
					}
					else
					{
						poiFragData.baseColor = hueShift(poiFragData.baseColor, frac((shift - (1 - hueShiftAlpha.r) + _MainHueShiftSpeed * _Time.x)));
					}
				}
				
				if (_MainGradationStrength && _ColorGradingToggle)
				{
					#if !defined(UNITY_COLORSPACE_GAMMA)
					float3 tempColor = OpenLitLinearToSRGB(poiFragData.baseColor);
					#else
					float3 tempColor = poiFragData.baseColor;
					#endif
					#if defined(PROP_MAINGRADATIONTEX) || !defined(OPTIMIZER_ENABLED)
					tempColor.r = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.r).r;
					tempColor.g = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.g).g;
					tempColor.b = POI_SAMPLE_1D_X(_MainGradationTex, sampler_linear_clamp, tempColor.b).b;
					#else
					tempColor = float3(1, 1, 1);
					#endif
					#if !defined(UNITY_COLORSPACE_GAMMA)
					tempColor = OpenLitSRGBToLinear(tempColor);
					#endif
					poiFragData.baseColor = lerp(poiFragData.baseColor, tempColor, _MainGradationStrength);
				}
				
				poiFragData.baseColor = lerp(poiFragData.baseColor, dot(poiFragData.baseColor, float3(0.3, 0.59, 0.11)), - (_Saturation) * hueShiftAlpha.b);
				poiFragData.baseColor = saturate(lerp(poiFragData.baseColor, poiFragData.baseColor * (_MainBrightness + 1), hueShiftAlpha.g));
				#endif
				//endex
				
				#if defined(PROP_ALPHAMASK) || !defined(OPTIMIZER_ENABLED)
				
				if (_MainAlphaMaskMode)
				{
					float alphaMask = POI2D_SAMPLER_PAN(_AlphaMask, _MainTex, poiUV(poiMesh.uv[_AlphaMaskUV], _AlphaMask_ST), _AlphaMaskPan.xy).r;
					alphaMask = saturate(alphaMask * _AlphaMaskScale + _AlphaMaskValue);
					if (_AlphaMaskInvert) alphaMask = 1 - alphaMask;
					if (_MainAlphaMaskMode == 1) poiFragData.alpha = alphaMask;
					if (_MainAlphaMaskMode == 2) poiFragData.alpha = poiFragData.alpha * alphaMask;
					if (_MainAlphaMaskMode == 3) poiFragData.alpha = saturate(poiFragData.alpha + alphaMask);
					if (_MainAlphaMaskMode == 4) poiFragData.alpha = saturate(poiFragData.alpha - alphaMask);
				}
				#endif
				
				//ifex _VideoEffectsEnable==0
				#ifdef POI_VIDEO_EFFECTS
				if (_VideoEffectsEnable)
				{
					applyVideoEffects(poiFragData, poiCam, poiMesh, poiLight, poiMods);
				}
				#endif
				//endex
				
				applyAlphaOptions(poiFragData, poiMesh, poiCam, poiMods);
				
				//ifex _EnableTouchGlow==0
				#ifdef GRAIN
				applyDepthFX(poiFragData, poiCam, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _MainVertexColoringEnabled==0
				applyVertexColor(poiFragData, poiMesh);
				//endex
				
				//ifex _BackFaceEnabled!=1
				#ifdef POI_BACKFACE
				ApplyBackFaceColor(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _EnableDissolve==0
				#ifdef DISTORT
				applyDissolve(poiFragData, poiMesh, poiMods, poiCam, poiLight);
				#endif
				//endex
				
				//ifex _EnableALDecal==0
				#ifdef POI_AUDIOLINK
				#ifdef POI_AL_DECAL
				ApplyAudioLinkDecal(poiMesh, poiFragData, poiMods);
				#endif
				#endif
				//endex
				
				//ifex _EnableFlipbook==0
				#ifdef _SUNDISK_HIGH_QUALITY
				applyFlipbook(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _EnableMirrorOptions==0
				#ifdef POI_MIRROR
				applyMirror(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				//ifex _VoronoiEnabled!=1
				#ifdef POI_VORONOI
				ApplyVoronoi(poiFragData, poiMesh, poiMods);
				#endif
				//endex
				
				poiFragData.finalColor = poiFragData.baseColor;
				
				//ifex _BacklightEnabled!=1
				#ifdef POI_BACKLIGHT
				ApplyBacklight(poiFragData, poiMesh, poiLight, poiCam, poiMods);
				#endif
				//endex
				
				//UNITY_BRANCH
				if (_IgnoreFog == 0)
				{
					UNITY_APPLY_FOG(i.fogCoord, poiFragData.finalColor);
				}
				
				poiFragData.alpha = _AlphaForceOpaque ? 1 : poiFragData.alpha;
				
				//ifex _AlphaToCoverage==0 && isNotAnimated(_AlphaToCoverage)
				ApplyAlphaToCoverage(poiFragData, poiMesh);
				//endex
				
				//ifex _AlphaDithering==0 && isNotAnimated(_AlphaDithering)
				applyDithering(poiFragData, poiCam);
				//endex
				
				if (_Mode == POI_MODE_OPAQUE)
				{
					poiFragData.alpha = 1;
				}
				
				clip(poiFragData.alpha - _Cutoff);
				
				return float4(poiFragData.finalColor, poiFragData.alpha) + POI_SAFE_RGB0;
			}
			
			ENDCG
		}
		
	}
	CustomEditor "Thry.ShaderEditor"
}
